summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorBinyuan Lan <lby@rock-chips.com>2018-02-09 11:08:07 +0800
committerTao Huang <huangtao@rock-chips.com>2018-02-23 14:37:59 +0800
commitad85bca9e82371fc2e1b03fa337aeaeeabeeb302 (patch)
tree6d5fff828b9596e2eec3ce2b8c0b6ccc02533ae2 /sound
parent7e99010694f5e7b2388903f361c9411daa5d0f41 (diff)
ASoC: rockchip: rk817-codec: add some functions
distinguish MIC input differential or single-ended disable DAC_D_HPF add pdm support Change-Id: Id2befb3f817c9eaf273e1120036cf013db463639 Signed-off-by: Binyuan Lan <lby@rock-chips.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/rk817_codec.c124
-rw-r--r--sound/soc/codecs/rk817_codec.h48
2 files changed, 135 insertions, 37 deletions
diff --git a/sound/soc/codecs/rk817_codec.c b/sound/soc/codecs/rk817_codec.c
index 2ec16c291c5a..915019ad2a76 100644
--- a/sound/soc/codecs/rk817_codec.c
+++ b/sound/soc/codecs/rk817_codec.c
@@ -44,21 +44,21 @@ module_param_named(dbg_level, dbg_enable, int, 0644);
/*
* DDAC L/R volume setting
+ * 0db~-95db,0.375db/step,for example:
* 0: 0dB
- * 0x0a:-3.75dB
+ * 0x0a: -3.75dB
* 0x7d: -46dB
* 0xff: -95dB
- * Step: 0.375dB
*/
#define OUT_VOLUME (0x03)
/*
* DADC L/R volume setting
+ * 0db~-95db,0.375db/step,for example:
* 0: 0dB
- * 0x0a:-3.75dB
+ * 0x0a: -3.75dB
* 0x7d: -46dB
* 0xff: -95dB
- * Step: 0.375dB
*/
#define CAPTURE_VOLUME (0x0)
@@ -75,6 +75,9 @@ struct rk817_codec_priv {
unsigned int hp_volume;
unsigned int capture_volume;
+ bool mic_in_differential;
+ bool pdmdata_out_enable;
+
long int playback_path;
long int capture_path;
};
@@ -227,8 +230,8 @@ static struct rk817_reg_val_typ playback_power_up_list[] = {
{RK817_CODEC_AREF_RTCFG1, 0x40},
{RK817_CODEC_DDAC_POPD_DACST, 0x02},
{RK817_CODEC_DDAC_SR_LMT0, 0x02},
- /*{RK817_CODEC_DTOP_DIGEN_CLKE, 0x0f},*/
- /*APLL*/
+ /* {RK817_CODEC_DTOP_DIGEN_CLKE, 0x0f}, */
+ /* APLL */
{RK817_CODEC_APLL_CFG0, 0x04},
{RK817_CODEC_APLL_CFG1, 0x58},
{RK817_CODEC_APLL_CFG2, 0x2d},
@@ -242,6 +245,7 @@ static struct rk817_reg_val_typ playback_power_up_list[] = {
{RK817_CODEC_DI2S_RXCR1, 0x00},
{RK817_CODEC_DI2S_RXCMD_TSD, 0x20},
{RK817_CODEC_DTOP_VUCTIME, 0xf4},
+ {RK817_CODEC_DDAC_MUTE_MIXCTL, 0x00},
{RK817_CODEC_DDAC_VOLL, 0x0a},
{RK817_CODEC_DDAC_VOLR, 0x0a},
@@ -251,7 +255,7 @@ static struct rk817_reg_val_typ playback_power_up_list[] = {
ARRAY_SIZE(playback_power_up_list)
static struct rk817_reg_val_typ playback_power_down_list[] = {
- {RK817_CODEC_DDAC_MUTE_MIXCTL, 0xa1},
+ {RK817_CODEC_DDAC_MUTE_MIXCTL, 0x01},
{RK817_CODEC_ADAC_CFG1, 0x0f},
/* HP */
{RK817_CODEC_AHP_CFG0, 0xe0},
@@ -267,7 +271,7 @@ static struct rk817_reg_val_typ capture_power_up_list[] = {
{RK817_CODEC_AREF_RTCFG1, 0x40},
{RK817_CODEC_DDAC_SR_LMT0, 0x02},
{RK817_CODEC_DADC_SR_ACL0, 0x02},
- /*{RK817_CODEC_DTOP_DIGEN_CLKE, 0xff},*/
+ /* {RK817_CODEC_DTOP_DIGEN_CLKE, 0xff}, */
{RK817_CODEC_APLL_CFG0, 0x04},
{RK817_CODEC_APLL_CFG1, 0x58},
{RK817_CODEC_APLL_CFG2, 0x2d},
@@ -287,7 +291,7 @@ static struct rk817_reg_val_typ capture_power_up_list[] = {
{RK817_CODEC_AMIC_CFG0, 0x0f},
{RK817_CODEC_DI2S_TXCR3_TXCMD, 0x88},
{RK817_CODEC_DDAC_POPD_DACST, 0x02},
- /* 0x29: -18db to 27db*/
+ /* 0x29: -18db to 27db */
{RK817_CODEC_DMIC_PGA_GAIN, 0xaa},
};
@@ -310,10 +314,10 @@ static int rk817_codec_power_up(int type)
codec = rk817->codec;
- dev_info(codec->dev, "%s : power up %s %s %s\n", __func__,
- type & RK817_CODEC_PLAYBACK ? "playback" : "",
- type & RK817_CODEC_CAPTURE ? "capture" : "",
- type & RK817_CODEC_INCALL ? "incall" : "");
+ DBG("%s : power up %s %s %s\n", __func__,
+ type & RK817_CODEC_PLAYBACK ? "playback" : "",
+ type & RK817_CODEC_CAPTURE ? "capture" : "",
+ type & RK817_CODEC_INCALL ? "incall" : "");
if (type & RK817_CODEC_PLAYBACK) {
snd_soc_update_bits(codec, RK817_CODEC_DTOP_DIGEN_CLKE,
@@ -321,7 +325,6 @@ static int rk817_codec_power_up(int type)
for (i = 0; i < RK817_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) {
snd_soc_write(codec, playback_power_up_list[i].reg,
playback_power_up_list[i].value);
- usleep_range(1000, 1100);
}
}
@@ -331,8 +334,19 @@ static int rk817_codec_power_up(int type)
for (i = 0; i < RK817_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) {
snd_soc_write(codec, capture_power_up_list[i].reg,
capture_power_up_list[i].value);
- usleep_range(1000, 1100);
}
+
+ if (rk817->mic_in_differential)
+ snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
+ MIC_DIFF_MASK, MIC_DIFF_EN);
+ else
+ snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
+ MIC_DIFF_MASK, MIC_DIFF_DIS);
+
+ if (rk817->pdmdata_out_enable)
+ snd_soc_update_bits(codec, RK817_CODEC_DI2S_CKM,
+ PDM_EN_MASK, PDM_EN_ENABLE);
+
snd_soc_write(codec, RK817_CODEC_DADC_VOLL,
rk817->capture_volume);
snd_soc_write(codec, RK817_CODEC_DADC_VOLR,
@@ -350,10 +364,10 @@ static int rk817_codec_power_down(int type)
codec = rk817->codec;
- dev_info(codec->dev, "%s : power down %s %s %s\n", __func__,
- type & RK817_CODEC_PLAYBACK ? "playback" : "",
- type & RK817_CODEC_CAPTURE ? "capture" : "",
- type & RK817_CODEC_INCALL ? "incall" : "");
+ DBG("%s : power down %s %s %s\n", __func__,
+ type & RK817_CODEC_PLAYBACK ? "playback" : "",
+ type & RK817_CODEC_CAPTURE ? "capture" : "",
+ type & RK817_CODEC_INCALL ? "incall" : "");
/* mute output for pop noise */
if ((type & RK817_CODEC_PLAYBACK) ||
@@ -449,7 +463,9 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
switch (rk817->playback_path) {
case OFF:
- if (pre_path != OFF)
+ if (pre_path != OFF && (pre_path != HP_PATH &&
+ pre_path != HP_NO_MIC && pre_path != RING_HP &&
+ pre_path != RING_HP_NO_MIC))
rk817_codec_power_down(RK817_CODEC_PLAYBACK);
break;
case RCV:
@@ -457,15 +473,15 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
case RING_SPK:
if (pre_path == OFF)
rk817_codec_power_up(RK817_CODEC_PLAYBACK);
- /* power on dac ibias/l/r*/
+ /* power on dac ibias/l/r */
snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
PWD_DACBIAS_ON | PWD_DACD_ON |
PWD_DACL_ON | PWD_DACR_ON);
- /* CLASS D mode*/
+ /* CLASS D mode */
snd_soc_write(codec, RK817_CODEC_DDAC_MUTE_MIXCTL, 0x10);
- /* CLASS D enable*/
+ /* CLASS D enable */
snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG1, 0xa5);
- /* restart CLASS D, OCPP/N*/
+ /* restart CLASS D, OCPP/N */
snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG2, 0xc4);
snd_soc_write(codec, RK817_CODEC_DDAC_VOLL, rk817->spk_volume);
@@ -479,9 +495,9 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
rk817_codec_power_up(RK817_CODEC_PLAYBACK);
/* HP_CP_EN , CP 2.3V */
snd_soc_write(codec, RK817_CODEC_AHP_CP, 0x11);
- /* power on HP two stage opamp ,HP amplitude 0db*/
+ /* power on HP two stage opamp ,HP amplitude 0db */
snd_soc_write(codec, RK817_CODEC_AHP_CFG0, 0x80);
- /* power on dac ibias/l/r*/
+ /* power on dac ibias/l/r */
snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
PWD_DACBIAS_ON | PWD_DACD_DOWN |
PWD_DACL_ON | PWD_DACR_ON);
@@ -497,6 +513,21 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
case RING_SPK_HP:
if (pre_path == OFF)
rk817_codec_power_up(RK817_CODEC_PLAYBACK);
+ /* HP_CP_EN , CP 2.3V */
+ snd_soc_write(codec, RK817_CODEC_AHP_CP, 0x11);
+ /* power on HP two stage opamp ,HP amplitude 0db */
+ snd_soc_write(codec, RK817_CODEC_AHP_CFG0, 0x80);
+
+ /* power on dac ibias/l/r */
+ snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
+ PWD_DACBIAS_ON | PWD_DACD_ON |
+ PWD_DACL_ON | PWD_DACR_ON);
+ /* CLASS D mode */
+ snd_soc_write(codec, RK817_CODEC_DDAC_MUTE_MIXCTL, 0x10);
+ /* CLASS D enable */
+ snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG1, 0xa5);
+ /* restart CLASS D, OCPP/N */
+ snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG2, 0xc4);
snd_soc_write(codec, RK817_CODEC_DDAC_VOLL, rk817->hp_volume);
snd_soc_write(codec, RK817_CODEC_DDAC_VOLR, rk817->hp_volume);
@@ -550,10 +581,26 @@ static int rk817_capture_path_put(struct snd_kcontrol *kcontrol,
case MAIN_MIC:
if (pre_path == MIC_OFF)
rk817_codec_power_up(RK817_CODEC_CAPTURE);
+
+ if (!rk817->mic_in_differential) {
+ snd_soc_write(codec, RK817_CODEC_DADC_VOLR, 0xff);
+ snd_soc_update_bits(codec, RK817_CODEC_AADC_CFG0,
+ ADC_R_PWD_MASK, ADC_R_PWD_EN);
+ snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
+ PWD_PGA_R_MASK, PWD_PGA_R_EN);
+ }
break;
case HANDS_FREE_MIC:
if (pre_path == MIC_OFF)
rk817_codec_power_up(RK817_CODEC_CAPTURE);
+
+ if (!rk817->mic_in_differential) {
+ snd_soc_write(codec, RK817_CODEC_DADC_VOLL, 0xff);
+ snd_soc_update_bits(codec, RK817_CODEC_AADC_CFG0,
+ ADC_L_PWD_MASK, ADC_L_PWD_EN);
+ snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
+ PWD_PGA_L_MASK, PWD_PGA_L_EN);
+ }
break;
case BT_SCO_MIC:
break;
@@ -641,7 +688,16 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
static int rk817_digital_mute(struct snd_soc_dai *dai, int mute)
{
- DBG("%s immediately return for mid\n", __func__);
+ struct snd_soc_codec *codec = dai->codec;
+
+ DBG("%s %d\n", __func__, mute);
+ if (mute)
+ snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
+ DACMT_ENABLE, DACMT_ENABLE);
+ else
+ snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
+ DACMT_ENABLE, DACMT_DISABLE);
+
return 0;
}
@@ -766,9 +822,9 @@ static int rk817_codec_parse_dt_property(struct device *dev,
return -ENODEV;
}
- node = of_get_child_by_name(dev->parent->of_node, "rk817-codec");
+ node = of_get_child_by_name(dev->parent->of_node, "codec");
if (!node) {
- dev_err(dev, "%s() Can not get child: rk817-codec\n",
+ dev_err(dev, "%s() Can not get child: codec\n",
__func__);
return -ENODEV;
}
@@ -778,6 +834,8 @@ static int rk817_codec_parse_dt_property(struct device *dev,
DBG("%s() Can not read property skp-volume\n", __func__);
rk817->spk_volume = OUT_VOLUME;
}
+ if (rk817->spk_volume < 3)
+ rk817->spk_volume = 3;
ret = of_property_read_u32(node, "hp-volume",
&rk817->hp_volume);
@@ -786,6 +844,8 @@ static int rk817_codec_parse_dt_property(struct device *dev,
__func__);
rk817->hp_volume = OUT_VOLUME;
}
+ if (rk817->hp_volume < 3)
+ rk817->hp_volume = 3;
ret = of_property_read_u32(node, "capture-volume",
&rk817->capture_volume);
@@ -795,6 +855,12 @@ static int rk817_codec_parse_dt_property(struct device *dev,
rk817->capture_volume = CAPTURE_VOLUME;
}
+ rk817->mic_in_differential =
+ of_property_read_bool(node, "mic-in-differential");
+
+ rk817->pdmdata_out_enable =
+ of_property_read_bool(node, "pdmdata-out-enable");
+
return 0;
}
diff --git a/sound/soc/codecs/rk817_codec.h b/sound/soc/codecs/rk817_codec.h
index cdf56a087308..7f17cd9b7d2b 100644
--- a/sound/soc/codecs/rk817_codec.h
+++ b/sound/soc/codecs/rk817_codec.h
@@ -75,7 +75,7 @@
#define RK817_CODEC_DI2S_TXCR2 (RK817_CODEC_BASE + 0x4e)
#define RK817_CODEC_DI2S_TXCR3_TXCMD (RK817_CODEC_BASE + 0x4f)
-/*RK817_CODEC_DTOP_DIGEN_CLKE*/
+/* RK817_CODEC_DTOP_DIGEN_CLKE */
#define ADC_DIG_CLK_MASK (0xf << 4)
#define ADC_DIG_CLK_SFT 4
#define ADC_DIG_CLK_DIS (0x0 << 4)
@@ -86,11 +86,16 @@
#define DAC_DIG_CLK_DIS (0x0 << 0)
#define DAC_DIG_CLK_EN (0xf << 0)
-/*RK817_CODEC_APLL_CFG5*/
+/* RK817_CODEC_APLL_CFG5 */
#define PLL_PW_DOWN (0x01 << 0)
#define PLL_PW_UP (0x00 << 0)
-/*RK817_CODEC_DI2S_CKM*/
+/* RK817_CODEC_DI2S_CKM */
+#define PDM_EN_MASK (0x1 << 3)
+#define PDM_EN_SFT 3
+#define PDM_EN_DISABLE (0x0 << 3)
+#define PDM_EN_ENABLE (0x1 << 3)
+
#define SCK_EN_ENABLE (0x1 << 2)
#define SCK_EN_DISABLE (0x0 << 2)
@@ -99,22 +104,22 @@
#define RK817_I2S_MODE_MST (0x1 << 0)
#define RK817_I2S_MODE_SLV (0x0 << 0)
-/*RK817_CODEC_DDAC_MUTE_MIXCTL*/
+/* RK817_CODEC_DDAC_MUTE_MIXCTL */
#define DACMT_ENABLE (0x1 << 0)
#define DACMT_DISABLE (0x0 << 0)
-/*RK817_CODEC_DI2S_RXCR2*/
+/* RK817_CODEC_DI2S_RXCR2 */
#define VDW_RX_24BITS (0x17)
#define VDW_RX_16BITS (0x0f)
-/*RK817_CODEC_DI2S_TXCR2*/
+/* RK817_CODEC_DI2S_TXCR2 */
#define VDW_TX_24BITS (0x17)
#define VDW_TX_16BITS (0x0f)
-/*RK817_CODEC_AHP_CFG1*/
+/* RK817_CODEC_AHP_CFG1 */
#define HP_ANTIPOP_ENABLE (0x1 << 4)
#define HP_ANTIPOP_DISABLE (0x0 << 4)
-/*RK817_CODEC_ADAC_CFG1*/
+/* RK817_CODEC_ADAC_CFG1 */
#define PWD_DACBIAS_MASK (0x1 << 3)
#define PWD_DACBIAS_SFT 3
#define PWD_DACBIAS_DOWN (0x1 << 3)
@@ -135,6 +140,33 @@
#define PWD_DACR_DOWN (0x1 << 0)
#define PWD_DACR_ON (0x0 << 0)
+/* RK817_CODEC_AADC_CFG0 */
+#define ADC_L_PWD_MASK (0x1 << 7)
+#define ADC_L_PWD_SFT 7
+#define ADC_L_PWD_DIS (0x0 << 7)
+#define ADC_L_PWD_EN (0x1 << 7)
+
+#define ADC_R_PWD_MASK (0x1 << 6)
+#define ADC_R_PWD_SFT 6
+#define ADC_R_PWD_DIS (0x0 << 6)
+#define ADC_R_PWD_EN (0x1 << 6)
+
+/* RK817_CODEC_AMIC_CFG0 */
+#define MIC_DIFF_MASK (0x1 << 7)
+#define MIC_DIFF_SFT 7
+#define MIC_DIFF_DIS (0x0 << 7)
+#define MIC_DIFF_EN (0x1 << 7)
+
+#define PWD_PGA_L_MASK (0x1 << 5)
+#define PWD_PGA_L_SFT 5
+#define PWD_PGA_L_DIS (0x0 << 5)
+#define PWD_PGA_L_EN (0x1 << 5)
+
+#define PWD_PGA_R_MASK (0x1 << 4)
+#define PWD_PGA_R_SFT 4
+#define PWD_PGA_R_DIS (0x0 << 4)
+#define PWD_PGA_R_EN (0x1 << 4)
+
enum {
RK817_HIFI,
RK817_VOICE,