Skip to content

Commit 180bc41

Browse files
committed
Merge remote-tracking branches 'asoc/topic/es8328', 'asoc/topic/find-dai', 'asoc/topic/fsl', 'asoc/topic/fsl-sai' and 'asoc/topic/fsl-ssi' into asoc-next
6 parents e449f7a + ca0d879 + fbb88b5 + aeea2fd + 4d24585 + 027db2e commit 180bc41

File tree

9 files changed

+288
-66
lines changed

9 files changed

+288
-66
lines changed

Documentation/devicetree/bindings/sound/fsl-sai.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ codec/DSP interfaces.
77

88
Required properties:
99

10-
- compatible : Compatible list, contains "fsl,vf610-sai" or
11-
"fsl,imx6sx-sai".
10+
- compatible : Compatible list, contains "fsl,vf610-sai",
11+
"fsl,imx6sx-sai" or "fsl,imx6ul-sai"
1212

1313
- reg : Offset and length of the register set for the device.
1414

@@ -48,6 +48,11 @@ Required properties:
4848
receive data by following their own bit clocks and
4949
frame sync clocks separately.
5050

51+
Optional properties (for mx6ul):
52+
53+
- fsl,sai-mclk-direction-output: This is a boolean property. If present,
54+
indicates that SAI will output the SAI MCLK clock.
55+
5156
Note:
5257
- If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the
5358
default synchronous mode (sync Rx with Tx) will be used, which means both

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4661,6 +4661,7 @@ FREESCALE SOC SOUND DRIVERS
46614661
M: Timur Tabi <[email protected]>
46624662
M: Nicolin Chen <[email protected]>
46634663
M: Xiubo Li <[email protected]>
4664+
R: Fabio Estevam <[email protected]>
46644665
L: [email protected] (moderated for non-subscribers)
46654666
46664667
S: Maintained

include/linux/mfd/syscon/imx6q-iomuxc-gpr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,5 +447,11 @@
447447
#define IMX6UL_GPR1_ENET2_CLK_OUTPUT (0x1 << 18)
448448
#define IMX6UL_GPR1_ENET_CLK_DIR (0x3 << 17)
449449
#define IMX6UL_GPR1_ENET_CLK_OUTPUT (0x3 << 17)
450+
#define IMX6UL_GPR1_SAI1_MCLK_DIR (0x1 << 19)
451+
#define IMX6UL_GPR1_SAI2_MCLK_DIR (0x1 << 20)
452+
#define IMX6UL_GPR1_SAI3_MCLK_DIR (0x1 << 21)
453+
#define IMX6UL_GPR1_SAI_MCLK_MASK (0x7 << 19)
454+
#define MCLK_DIR(x) (x == 1 ? IMX6UL_GPR1_SAI1_MCLK_DIR : x == 2 ? \
455+
IMX6UL_GPR1_SAI2_MCLK_DIR : IMX6UL_GPR1_SAI3_MCLK_DIR)
450456

451457
#endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */

include/sound/soc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,9 @@ void snd_soc_remove_dai_link(struct snd_soc_card *card,
16831683
int snd_soc_register_dai(struct snd_soc_component *component,
16841684
struct snd_soc_dai_driver *dai_drv);
16851685

1686+
struct snd_soc_dai *snd_soc_find_dai(
1687+
const struct snd_soc_dai_link_component *dlc);
1688+
16861689
#include <sound/soc-dai.h>
16871690

16881691
#ifdef CONFIG_DEBUG_FS

sound/soc/codecs/es8328.c

Lines changed: 149 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,30 @@
2626
#include <sound/tlv.h>
2727
#include "es8328.h"
2828

29-
#define ES8328_SYSCLK_RATE_1X 11289600
30-
#define ES8328_SYSCLK_RATE_2X 22579200
29+
static const unsigned int rates_12288[] = {
30+
8000, 12000, 16000, 24000, 32000, 48000, 96000,
31+
};
3132

32-
/* Run the codec at 22.5792 or 11.2896 MHz to support these rates */
33-
static struct {
34-
int rate;
35-
u8 ratio;
36-
} mclk_ratios[] = {
37-
{ 8000, 9 },
38-
{11025, 7 },
39-
{22050, 4 },
40-
{44100, 2 },
33+
static const int ratios_12288[] = {
34+
10, 7, 6, 4, 3, 2, 0,
35+
};
36+
37+
static const struct snd_pcm_hw_constraint_list constraints_12288 = {
38+
.count = ARRAY_SIZE(rates_12288),
39+
.list = rates_12288,
40+
};
41+
42+
static const unsigned int rates_11289[] = {
43+
8018, 11025, 22050, 44100, 88200,
44+
};
45+
46+
static const int ratios_11289[] = {
47+
9, 7, 4, 2, 0,
48+
};
49+
50+
static const struct snd_pcm_hw_constraint_list constraints_11289 = {
51+
.count = ARRAY_SIZE(rates_11289),
52+
.list = rates_11289,
4153
};
4254

4355
/* regulator supplies for sgtl5000, VDDD is an optional external supply */
@@ -57,16 +69,28 @@ static const char * const supply_names[ES8328_SUPPLY_NUM] = {
5769
"HPVDD",
5870
};
5971

60-
#define ES8328_RATES (SNDRV_PCM_RATE_44100 | \
72+
#define ES8328_RATES (SNDRV_PCM_RATE_96000 | \
73+
SNDRV_PCM_RATE_48000 | \
74+
SNDRV_PCM_RATE_44100 | \
75+
SNDRV_PCM_RATE_32000 | \
6176
SNDRV_PCM_RATE_22050 | \
62-
SNDRV_PCM_RATE_11025)
63-
#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
77+
SNDRV_PCM_RATE_16000 | \
78+
SNDRV_PCM_RATE_11025 | \
79+
SNDRV_PCM_RATE_8000)
80+
#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
81+
SNDRV_PCM_FMTBIT_S18_3LE | \
82+
SNDRV_PCM_FMTBIT_S20_3LE | \
83+
SNDRV_PCM_FMTBIT_S24_LE | \
84+
SNDRV_PCM_FMTBIT_S32_LE)
6485

6586
struct es8328_priv {
6687
struct regmap *regmap;
6788
struct clk *clk;
6889
int playback_fs;
6990
bool deemph;
91+
int mclkdiv2;
92+
const struct snd_pcm_hw_constraint_list *sysclk_constraints;
93+
const int *mclk_ratios;
7094
struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM];
7195
};
7296

@@ -439,54 +463,131 @@ static int es8328_mute(struct snd_soc_dai *dai, int mute)
439463
mute ? ES8328_DACCONTROL3_DACMUTE : 0);
440464
}
441465

466+
static int es8328_startup(struct snd_pcm_substream *substream,
467+
struct snd_soc_dai *dai)
468+
{
469+
struct snd_soc_codec *codec = dai->codec;
470+
struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
471+
472+
if (es8328->sysclk_constraints)
473+
snd_pcm_hw_constraint_list(substream->runtime, 0,
474+
SNDRV_PCM_HW_PARAM_RATE,
475+
es8328->sysclk_constraints);
476+
477+
return 0;
478+
}
479+
442480
static int es8328_hw_params(struct snd_pcm_substream *substream,
443481
struct snd_pcm_hw_params *params,
444482
struct snd_soc_dai *dai)
445483
{
446484
struct snd_soc_codec *codec = dai->codec;
447485
struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
448-
int clk_rate;
449486
int i;
450487
int reg;
451-
u8 ratio;
488+
int wl;
489+
int ratio;
490+
491+
if (!es8328->sysclk_constraints) {
492+
dev_err(codec->dev, "No MCLK configured\n");
493+
return -EINVAL;
494+
}
452495

453496
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
454497
reg = ES8328_DACCONTROL2;
455498
else
456499
reg = ES8328_ADCCONTROL5;
457500

458-
clk_rate = clk_get_rate(es8328->clk);
501+
for (i = 0; i < es8328->sysclk_constraints->count; i++)
502+
if (es8328->sysclk_constraints->list[i] == params_rate(params))
503+
break;
459504

460-
if ((clk_rate != ES8328_SYSCLK_RATE_1X) &&
461-
(clk_rate != ES8328_SYSCLK_RATE_2X)) {
462-
dev_err(codec->dev,
463-
"%s: clock is running at %d Hz, not %d or %d Hz\n",
464-
__func__, clk_rate,
465-
ES8328_SYSCLK_RATE_1X, ES8328_SYSCLK_RATE_2X);
505+
if (i == es8328->sysclk_constraints->count) {
506+
dev_err(codec->dev, "LRCLK %d unsupported with current clock\n",
507+
params_rate(params));
466508
return -EINVAL;
467509
}
468510

469-
/* find master mode MCLK to sampling frequency ratio */
470-
ratio = mclk_ratios[0].rate;
471-
for (i = 1; i < ARRAY_SIZE(mclk_ratios); i++)
472-
if (params_rate(params) <= mclk_ratios[i].rate)
473-
ratio = mclk_ratios[i].ratio;
511+
ratio = es8328->mclk_ratios[i];
512+
snd_soc_update_bits(codec, ES8328_MASTERMODE,
513+
ES8328_MASTERMODE_MCLKDIV2,
514+
es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0);
515+
516+
switch (params_width(params)) {
517+
case 16:
518+
wl = 3;
519+
break;
520+
case 18:
521+
wl = 2;
522+
break;
523+
case 20:
524+
wl = 1;
525+
break;
526+
case 24:
527+
wl = 0;
528+
break;
529+
case 32:
530+
wl = 4;
531+
break;
532+
default:
533+
return -EINVAL;
534+
}
474535

475536
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
537+
snd_soc_update_bits(codec, ES8328_DACCONTROL1,
538+
ES8328_DACCONTROL1_DACWL_MASK,
539+
wl << ES8328_DACCONTROL1_DACWL_SHIFT);
540+
476541
es8328->playback_fs = params_rate(params);
477542
es8328_set_deemph(codec);
478-
}
543+
} else
544+
snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
545+
ES8328_ADCCONTROL4_ADCWL_MASK,
546+
wl << ES8328_ADCCONTROL4_ADCWL_SHIFT);
479547

480548
return snd_soc_update_bits(codec, reg, ES8328_RATEMASK, ratio);
481549
}
482550

551+
static int es8328_set_sysclk(struct snd_soc_dai *codec_dai,
552+
int clk_id, unsigned int freq, int dir)
553+
{
554+
struct snd_soc_codec *codec = codec_dai->codec;
555+
struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
556+
int mclkdiv2 = 0;
557+
558+
switch (freq) {
559+
case 0:
560+
es8328->sysclk_constraints = NULL;
561+
es8328->mclk_ratios = NULL;
562+
break;
563+
case 22579200:
564+
mclkdiv2 = 1;
565+
/* fallthru */
566+
case 11289600:
567+
es8328->sysclk_constraints = &constraints_11289;
568+
es8328->mclk_ratios = ratios_11289;
569+
break;
570+
case 24576000:
571+
mclkdiv2 = 1;
572+
/* fallthru */
573+
case 12288000:
574+
es8328->sysclk_constraints = &constraints_12288;
575+
es8328->mclk_ratios = ratios_12288;
576+
break;
577+
default:
578+
return -EINVAL;
579+
}
580+
581+
es8328->mclkdiv2 = mclkdiv2;
582+
return 0;
583+
}
584+
483585
static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
484586
unsigned int fmt)
485587
{
486588
struct snd_soc_codec *codec = codec_dai->codec;
487-
struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
488-
int clk_rate;
489-
u8 mode = ES8328_DACCONTROL1_DACWL_16;
589+
u8 dac_mode = 0;
590+
u8 adc_mode = 0;
490591

491592
/* set master/slave audio interface */
492593
if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM)
@@ -495,13 +596,16 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
495596
/* interface format */
496597
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
497598
case SND_SOC_DAIFMT_I2S:
498-
mode |= ES8328_DACCONTROL1_DACFORMAT_I2S;
599+
dac_mode |= ES8328_DACCONTROL1_DACFORMAT_I2S;
600+
adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_I2S;
499601
break;
500602
case SND_SOC_DAIFMT_RIGHT_J:
501-
mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST;
603+
dac_mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST;
604+
adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_RJUST;
502605
break;
503606
case SND_SOC_DAIFMT_LEFT_J:
504-
mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST;
607+
dac_mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST;
608+
adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_LJUST;
505609
break;
506610
default:
507611
return -EINVAL;
@@ -511,18 +615,14 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
511615
if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF)
512616
return -EINVAL;
513617

514-
snd_soc_write(codec, ES8328_DACCONTROL1, mode);
515-
snd_soc_write(codec, ES8328_ADCCONTROL4, mode);
618+
snd_soc_update_bits(codec, ES8328_DACCONTROL1,
619+
ES8328_DACCONTROL1_DACFORMAT_MASK, dac_mode);
620+
snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
621+
ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);
516622

517623
/* Master serial port mode, with BCLK generated automatically */
518-
clk_rate = clk_get_rate(es8328->clk);
519-
if (clk_rate == ES8328_SYSCLK_RATE_1X)
520-
snd_soc_write(codec, ES8328_MASTERMODE,
521-
ES8328_MASTERMODE_MSC);
522-
else
523-
snd_soc_write(codec, ES8328_MASTERMODE,
524-
ES8328_MASTERMODE_MCLKDIV2 |
525-
ES8328_MASTERMODE_MSC);
624+
snd_soc_update_bits(codec, ES8328_MASTERMODE,
625+
ES8328_MASTERMODE_MSC, ES8328_MASTERMODE_MSC);
526626

527627
return 0;
528628
}
@@ -579,8 +679,10 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
579679
}
580680

581681
static const struct snd_soc_dai_ops es8328_dai_ops = {
682+
.startup = es8328_startup,
582683
.hw_params = es8328_hw_params,
583684
.digital_mute = es8328_mute,
685+
.set_sysclk = es8328_set_sysclk,
584686
.set_fmt = es8328_set_dai_fmt,
585687
};
586688

@@ -601,6 +703,7 @@ static struct snd_soc_dai_driver es8328_dai = {
601703
.formats = ES8328_FORMATS,
602704
},
603705
.ops = &es8328_dai_ops,
706+
.symmetric_rates = 1,
604707
};
605708

606709
static int es8328_suspend(struct snd_soc_codec *codec)
@@ -708,6 +811,7 @@ const struct regmap_config es8328_regmap_config = {
708811
.val_bits = 8,
709812
.max_register = ES8328_REG_MAX,
710813
.cache_type = REGCACHE_RBTREE,
814+
.use_single_rw = true,
711815
};
712816
EXPORT_SYMBOL_GPL(es8328_regmap_config);
713817

sound/soc/codecs/es8328.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ int es8328_probe(struct device *dev, struct regmap *regmap);
2222
#define ES8328_CONTROL1_VMIDSEL_50k (1 << 0)
2323
#define ES8328_CONTROL1_VMIDSEL_500k (2 << 0)
2424
#define ES8328_CONTROL1_VMIDSEL_5k (3 << 0)
25-
#define ES8328_CONTROL1_VMIDSEL_MASK (7 << 0)
25+
#define ES8328_CONTROL1_VMIDSEL_MASK (3 << 0)
2626
#define ES8328_CONTROL1_ENREF (1 << 2)
2727
#define ES8328_CONTROL1_SEQEN (1 << 3)
2828
#define ES8328_CONTROL1_SAMEFS (1 << 4)
@@ -84,7 +84,20 @@ int es8328_probe(struct device *dev, struct regmap *regmap);
8484
#define ES8328_ADCCONTROL1 0x09
8585
#define ES8328_ADCCONTROL2 0x0a
8686
#define ES8328_ADCCONTROL3 0x0b
87+
8788
#define ES8328_ADCCONTROL4 0x0c
89+
#define ES8328_ADCCONTROL4_ADCFORMAT_MASK (3 << 0)
90+
#define ES8328_ADCCONTROL4_ADCFORMAT_I2S (0 << 0)
91+
#define ES8328_ADCCONTROL4_ADCFORMAT_LJUST (1 << 0)
92+
#define ES8328_ADCCONTROL4_ADCFORMAT_RJUST (2 << 0)
93+
#define ES8328_ADCCONTROL4_ADCFORMAT_PCM (3 << 0)
94+
#define ES8328_ADCCONTROL4_ADCWL_SHIFT 2
95+
#define ES8328_ADCCONTROL4_ADCWL_MASK (7 << 2)
96+
#define ES8328_ADCCONTROL4_ADCLRP_I2S_POL_NORMAL (0 << 5)
97+
#define ES8328_ADCCONTROL4_ADCLRP_I2S_POL_INV (1 << 5)
98+
#define ES8328_ADCCONTROL4_ADCLRP_PCM_MSB_CLK2 (0 << 5)
99+
#define ES8328_ADCCONTROL4_ADCLRP_PCM_MSB_CLK1 (1 << 5)
100+
88101
#define ES8328_ADCCONTROL5 0x0d
89102
#define ES8328_ADCCONTROL5_RATEMASK (0x1f << 0)
90103

@@ -109,15 +122,13 @@ int es8328_probe(struct device *dev, struct regmap *regmap);
109122
#define ES8328_ADCCONTROL14 0x16
110123

111124
#define ES8328_DACCONTROL1 0x17
125+
#define ES8328_DACCONTROL1_DACFORMAT_MASK (3 << 1)
112126
#define ES8328_DACCONTROL1_DACFORMAT_I2S (0 << 1)
113127
#define ES8328_DACCONTROL1_DACFORMAT_LJUST (1 << 1)
114128
#define ES8328_DACCONTROL1_DACFORMAT_RJUST (2 << 1)
115129
#define ES8328_DACCONTROL1_DACFORMAT_PCM (3 << 1)
116-
#define ES8328_DACCONTROL1_DACWL_24 (0 << 3)
117-
#define ES8328_DACCONTROL1_DACWL_20 (1 << 3)
118-
#define ES8328_DACCONTROL1_DACWL_18 (2 << 3)
119-
#define ES8328_DACCONTROL1_DACWL_16 (3 << 3)
120-
#define ES8328_DACCONTROL1_DACWL_32 (4 << 3)
130+
#define ES8328_DACCONTROL1_DACWL_SHIFT 3
131+
#define ES8328_DACCONTROL1_DACWL_MASK (7 << 3)
121132
#define ES8328_DACCONTROL1_DACLRP_I2S_POL_NORMAL (0 << 6)
122133
#define ES8328_DACCONTROL1_DACLRP_I2S_POL_INV (1 << 6)
123134
#define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK2 (0 << 6)

0 commit comments

Comments
 (0)