mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
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:
83
Documentation/devicetree/bindings/sound/pcm186x.txt
Normal file
83
Documentation/devicetree/bindings/sound/pcm186x.txt
Normal 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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user