From 70ab12578d6ee3c80a02b43bcb26ef2841d6b911 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Thu, 23 May 2019 20:14:19 +0800 Subject: [PATCH] ASoC: rk3308_codec: add support ADC grps and DAC endisable for testing Some times, we need to enable/disable ADC grps or DAC directly to debug. Change-Id: I53b9fa94733d84f7101e299d3fcb6f9160e36112 Signed-off-by: Xing Zheng --- sound/soc/codecs/rk3308_codec.c | 129 ++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c index aadcd7f698fb..815e22fc346c 100644 --- a/sound/soc/codecs/rk3308_codec.c +++ b/sound/soc/codecs/rk3308_codec.c @@ -111,6 +111,7 @@ enum { enum { ADC_TYPE_NORMAL = 0, ADC_TYPE_LOOPBACK, + ADC_TYPE_DBG, ADC_TYPE_ALL, }; @@ -171,6 +172,7 @@ struct rk3308_codec_priv { u32 used_adc_grps; /* The ADC group which is used for loop back */ u32 loopback_grp; + u32 cur_dbg_grp; u32 en_always_grps[ADC_LR_GROUP_MAX]; u32 en_always_grps_num; u32 skip_grps[ADC_LR_GROUP_MAX]; @@ -211,6 +213,8 @@ struct rk3308_codec_priv { unsigned int hpout_l_dgain; unsigned int hpout_r_dgain; + bool adc_grps_endisable[ADC_LR_GROUP_MAX]; + bool dac_endisable; bool enable_all_adcs; bool enable_micbias; bool micbias1; @@ -1341,6 +1345,18 @@ static bool adc_for_each_grp(struct rk3308_codec_priv *rk3308, dev_dbg(rk3308->plat_dev, "ADC_TYPE_ALL, idx: %d, get grp: %d\n", idx, *grp); + } else if (type == ADC_TYPE_DBG) { + if (idx >= ADC_LR_GROUP_MAX) + return false; + + if (idx == (int)rk3308->cur_dbg_grp) + *grp = idx; + else + *grp = ADC_GRP_SKIP_MAGIC; + + dev_dbg(rk3308->plat_dev, + "ADC_TYPE_DBG, idx: %d, get grp: %d\n", + idx, *grp); } else { if (idx >= 1) return false; @@ -2265,6 +2281,8 @@ static int rk3308_codec_dac_enable(struct rk3308_codec_priv *rk3308) rk3308_codec_digital_fadein(rk3308); } + rk3308->dac_endisable = true; + /* TODO: TRY TO TEST DRIVE STRENGTH */ return 0; @@ -2417,6 +2435,8 @@ static int rk3308_codec_dac_disable(struct rk3308_codec_priv *rk3308) * rk3308_codec_adc_ana_disable(rk3308, type); */ + rk3308->dac_endisable = false; + return 0; } @@ -3226,6 +3246,13 @@ static int rk3308_codec_adc_ana_enable(struct rk3308_codec_priv *rk3308, } } + for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { + if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) + continue; + + rk3308->adc_grps_endisable[grp] = true; + } + return 0; } @@ -3352,6 +3379,13 @@ static int rk3308_codec_adc_ana_disable(struct rk3308_codec_priv *rk3308, RK3308_ADC_CH2_MIC_INIT); } + for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) { + if (grp < 0 || grp > ADC_LR_GROUP_MAX - 1) + continue; + + rk3308->adc_grps_endisable[grp] = false; + } + return 0; } @@ -3441,6 +3475,20 @@ static void rk3308_codec_dac_mclk_enable(struct rk3308_codec_priv *rk3308) udelay(20); } +static int rk3308_codec_open_dbg_capture(struct rk3308_codec_priv *rk3308) +{ + rk3308_codec_adc_ana_enable(rk3308, ADC_TYPE_DBG); + + return 0; +} + +static int rk3308_codec_close_dbg_capture(struct rk3308_codec_priv *rk3308) +{ + rk3308_codec_adc_ana_disable(rk3308, ADC_TYPE_DBG); + + return 0; +} + static int rk3308_codec_close_all_capture(struct rk3308_codec_priv *rk3308) { rk3308_codec_adc_ana_disable(rk3308, ADC_TYPE_ALL); @@ -4506,6 +4554,85 @@ static ssize_t adc_zerocross_store(struct device *dev, return count; } +static ssize_t adc_grps_endisable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct rk3308_codec_priv *rk3308 = + container_of(dev, struct rk3308_codec_priv, dev); + int count = 0, i; + + count += sprintf(buf + count, "enabled adc grps:"); + for (i = 0; i < ADC_LR_GROUP_MAX; i++) + count += sprintf(buf + count, "%d ", + rk3308->adc_grps_endisable[i]); + + count += sprintf(buf + count, "\n"); + return count; +} + +static ssize_t adc_grps_endisable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rk3308_codec_priv *rk3308 = + container_of(dev, struct rk3308_codec_priv, dev); + int grp, endisable, ret; + + ret = sscanf(buf, "%d,%d", &grp, &endisable); + if (ret != 2) { + dev_err(rk3308->plat_dev, "%s sscanf failed: %d\n", + __func__, ret); + return -EFAULT; + } + + rk3308->cur_dbg_grp = grp; + + if (endisable) + rk3308_codec_open_dbg_capture(rk3308); + else + rk3308_codec_close_dbg_capture(rk3308); + + dev_info(dev, "ADC grp %d endisable: %d\n", grp, endisable); + + return count; +} + +static ssize_t dac_endisable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct rk3308_codec_priv *rk3308 = + container_of(dev, struct rk3308_codec_priv, dev); + + return sprintf(buf, "%d\n", rk3308->dac_endisable); +} + +static ssize_t dac_endisable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rk3308_codec_priv *rk3308 = + container_of(dev, struct rk3308_codec_priv, dev); + unsigned long endisable; + int ret = kstrtoul(buf, 10, &endisable); + + if (ret < 0) { + dev_err(dev, "Invalid endisable: %ld, ret: %d\n", + endisable, ret); + return -EINVAL; + } + + if (endisable) + rk3308_codec_open_playback(rk3308); + else + rk3308_codec_close_playback(rk3308); + + dev_info(dev, "DAC endisable: %ld\n", endisable); + + return count; +} + static ssize_t dac_output_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -4587,9 +4714,11 @@ static ssize_t enable_all_adcs_store(struct device *dev, static const struct device_attribute acodec_attrs[] = { __ATTR_RW(adc_grps), + __ATTR_RW(adc_grps_endisable), __ATTR_RW(adc_grps_route), __ATTR_RW(adc_grp0_in), __ATTR_RW(adc_zerocross), + __ATTR_RW(dac_endisable), __ATTR_RW(dac_output), __ATTR_RW(enable_all_adcs), __ATTR_RW(pm_state),