diff --git a/Documentation/devicetree/bindings/sound/pcm186x.txt b/Documentation/devicetree/bindings/sound/pcm186x.txt new file mode 100644 index 000000000000..b00ce3d98c05 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/pcm186x.txt @@ -0,0 +1,83 @@ +Texas Instruments pcm186x DT bindings + +This driver supports the I2C. + +Required properties on I2C: + - compatible: "ti, pcm1864" + - reg: the I2C address + + +Examples: + +&i2c_c { + status = "okay"; + pinctrl-names="default"; + pinctrl-0=<&c_i2c_master_pin1>; + + pcm1864_4a: pcm1864_4a@4a { + compatible = "ti, pcm1864"; + #sound-dai-cells = <0>; + slots_mask = <0x0f>; + reg = <0x4a>; + status = "okay"; + }; +}; + +Note: + Because pcm1864 need to use a fixed frequency, + So we also need to modify pcm config. +Reference is as follows: + +diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c +index d235a8d..a294e1b 100644 +--- a/sound/soc/amlogic/auge/tdm.c ++++ b/sound/soc/amlogic/auge/tdm.c +@@ -451,11 +451,12 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd, + } + + static int pcm_setting_init(struct pcm_setting *setting, unsigned int rate, +- unsigned int channels) ++ unsigned int channels, unsigned int fixbclk) + { + unsigned int ratio = 0; + setting->lrclk = rate; +- setting->bclk_lrclk_ratio = setting->slots * setting->slot_width; ++ ++ setting->bclk_lrclk_ratio = setting->slots * setting->slot_width * fixbclk; + setting->bclk = setting->lrclk * setting->bclk_lrclk_ratio; + + /* calculate mclk */ +@@ -534,8 +535,13 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream, + unsigned int rate = params_rate(params); + unsigned int channels = params_channels(params); + int ret; +- +- ret = pcm_setting_init(setting, rate, channels); ++ ++ // FOR PCM1864 TDM BCLK NEED 12.288MHz ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ ret = pcm_setting_init(setting, rate, channels, 1); ++ } else { ++ ret = pcm_setting_init(setting, rate, channels, 2); ++ } + if (ret) + return ret; + +diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c +index a294e1b..a756035 100644 +--- a/sound/soc/amlogic/auge/tdm.c ++++ b/sound/soc/amlogic/auge/tdm.c +@@ -455,8 +455,11 @@ static int pcm_setting_init(struct pcm_setting *setting, unsigned int rate, + { + unsigned int ratio = 0; + setting->lrclk = rate; +- +- setting->bclk_lrclk_ratio = setting->slots * setting->slot_width * fixbclk; ++ ++ if (fixbclk == 2) ++ setting->bclk_lrclk_ratio = setting->slots * 32 * fixbclk; ++ else ++ setting->bclk_lrclk_ratio = setting->slots * setting->slot_width * fixbclk; + setting->bclk = setting->lrclk * setting->bclk_lrclk_ratio; + + /* calculate mclk */ diff --git a/MAINTAINERS b/MAINTAINERS index 630133073ea0..2aa9add8686f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14389,3 +14389,7 @@ AMLOGIC G12A CVBS DRIVER M: Nian Jing F: drivers/amlogic/media/vout/cvbs/ F: arch/arm64/boot/dts/amlogic/g12a*.dts + +AMLOGIC FIX PCM186X DRIVER +M: Renjun Xu +F: sound/soc/codecs/amlogic/pcm186x.c diff --git a/sound/soc/codecs/amlogic/pcm186x.c b/sound/soc/codecs/amlogic/pcm186x.c index 2c436c6abc16..98ecd1b8cd1a 100644 --- a/sound/soc/codecs/amlogic/pcm186x.c +++ b/sound/soc/codecs/amlogic/pcm186x.c @@ -302,7 +302,7 @@ static int pcm186x_dsp_coefficients_put(struct snd_kcontrol *kcontrol, return 0; } -static const DECLARE_TLV_DB_SCALE(pcm186x_pga_tlv, -1200, 4000, 50); +static const DECLARE_TLV_DB_SCALE(pcm186x_pga_tlv, -1200, 50, 0); static const struct snd_kcontrol_new pcm1863_snd_controls[] = { SOC_DOUBLE_R_S_TLV("Analog Gain", PCM186X_PGA_VAL_CH1_L, @@ -719,8 +719,8 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format) * We only support the non-inverted clocks. Note that clock polarity * depends on the actual FORMAT. */ - if ((format & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) - return -EINVAL; + //if ((format & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) + // return -EINVAL; priv->dai_format = format; @@ -739,10 +739,10 @@ static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, "%s() tx_mask=0x%x rx_mask=0x%x slots=%d slot_width=%d\n", __func__, tx_mask, rx_mask, slots, slot_width); - if (!tx_mask) { - dev_err(codec->dev, "tdm tx mask must not be 0\n"); - return -EINVAL; - } + //if (!tx_mask) { + // dev_err(codec->dev, "tdm tx mask must not be 0\n"); + // return -EINVAL; + //} tx_mask = priv->slots_mask; first_slot = __ffs(tx_mask); last_slot = __fls(tx_mask); @@ -762,7 +762,7 @@ static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, } priv->tdm_offset = tdm_offset; - tdm_offset += 1; + //tdm_offset += 1; ret = regmap_write(priv->regmap, PCM186X_TDM_TX_OFFSET, tdm_offset); if (ret < 0) dev_err(codec->dev, "failed to write register: %d\n", ret); @@ -1164,25 +1164,36 @@ int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq, goto err_disable_reg; } - /*default ADC1 Input Channel Select*/ - ret = regmap_write(regmap, PCM186X_ADC1_INPUT_SEL_L, 0x50); + ret = regmap_write(regmap, PCM186X_PGA_VAL_CH2_L, 0x0C); if (ret != 0) { dev_err(dev, "failed to write device: %d\n", ret); goto err_disable_reg; } - ret = regmap_write(regmap, PCM186X_ADC1_INPUT_SEL_R, 0x50); + ret = regmap_write(regmap, PCM186X_PGA_VAL_CH2_R, 0x0C); + if (ret != 0) { + dev_err(dev, "failed to write device: %d\n", ret); + goto err_disable_reg; + } + + /*default ADC1 Input Channel Select*/ + ret = regmap_write(regmap, PCM186X_ADC1_INPUT_SEL_L, 0x02); + if (ret != 0) { + dev_err(dev, "failed to write device: %d\n", ret); + goto err_disable_reg; + } + ret = regmap_write(regmap, PCM186X_ADC1_INPUT_SEL_R, 0x02); if (ret != 0) { dev_err(dev, "failed to write device: %d\n", ret); goto err_disable_reg; } /*default ADC2 Input Channel Select*/ - ret = regmap_write(regmap, PCM186X_ADC2_INPUT_SEL_L, 0x40); + ret = regmap_write(regmap, PCM186X_ADC2_INPUT_SEL_L, 0x60); if (ret != 0) { dev_err(dev, "failed to write device: %d\n", ret); goto err_disable_reg; } - ret = regmap_write(regmap, PCM186X_ADC2_INPUT_SEL_R, 0x40); + ret = regmap_write(regmap, PCM186X_ADC2_INPUT_SEL_R, 0x60); if (ret != 0) { dev_err(dev, "failed to write device: %d\n", ret); goto err_disable_reg;