sound: fix pcm186x driver playback/capture

PD#161075: fix pcm186x driver playback/capture

Change-Id: I04d66ca1987efcaaff2ed897593748cf101db921
Signed-off-by: Renjun Xu <renjun.xu@amlogic.com>
This commit is contained in:
Renjun Xu
2018-03-16 15:25:36 +08:00
committed by Jianxin Pan
parent 69c355d25b
commit a3fb5c97c0
3 changed files with 111 additions and 13 deletions

View File

@@ -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 */

View File

@@ -14389,3 +14389,7 @@ AMLOGIC G12A CVBS DRIVER
M: Nian Jing <nian.jing@amlogic.com>
F: drivers/amlogic/media/vout/cvbs/
F: arch/arm64/boot/dts/amlogic/g12a*.dts
AMLOGIC FIX PCM186X DRIVER
M: Renjun Xu <renjun.xu@amlogic.com>
F: sound/soc/codecs/amlogic/pcm186x.c

View File

@@ -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;