ASoC: rk3308_codec: configure ADC/DAC flexibility on hw_params

We need to know how many channels that are needed
to enable on hw_params for ADC groups, it's more
reasonable and more flexible.

By the way, clean up some coding styles.

Change-Id: Ia13b1667492dd60a63fc17130ff09b6b1b01b8df
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
This commit is contained in:
Xing Zheng
2018-06-01 11:13:44 +08:00
committed by Tao Huang
parent 738f93c0ab
commit 12324e6c5c

View File

@@ -65,6 +65,7 @@
#define GRF_I2S3_4CH_SDI_SFT 8
#define GRF_I2S1_2CH_SDI_SFT 12
#define GRF_I2S2_8CH_SDI_R_MSK(i, v) ((v >> (i * 2 + GRF_I2S2_8CH_SDI_SFT)) & 0x3)
#define GRF_I2S2_8CH_SDI_W_MSK(i) (0x3 << (i * 2 + GRF_I2S2_8CH_SDI_SFT + 16))
#define GRF_I2S2_8CH_SDI(i, v) (((v & 0x3) << (i * 2 + GRF_I2S2_8CH_SDI_SFT)) |\
GRF_I2S2_8CH_SDI_W_MSK(i))
@@ -125,8 +126,7 @@ struct rk3308_codec_priv {
* grp 2 -- select ADC5 / ADC6
* grp 3 -- select ADC7 / ADC8
*/
u32 adc_grps[ADC_LR_GROUP_MAX];
u32 used_grps;
u32 used_adc_grps;
/* The ADC group which is used for loop back */
u32 loopback_grp;
u32 i2s_sdis[ADC_LR_GROUP_MAX];
@@ -137,8 +137,10 @@ struct rk3308_codec_priv {
int adc_zerocross;
/* 0: line out, 1: hp out, 11: lineout and hpout */
int dac_output;
int adc_path_state;
int dac_path_state;
bool enable_all_adcs;
bool hp_plugged;
struct delayed_work hpdet_work;
struct delayed_work loopback_work;
@@ -476,10 +478,17 @@ static bool adc_for_each_grp(struct rk3308_codec_priv *rk3308,
int type, int idx, u32 *grp)
{
if (type == ADC_TYPE_NORMAL) {
if (idx >= rk3308->used_grps)
int max_grps;
if (rk3308->enable_all_adcs)
max_grps = ADC_LR_GROUP_MAX;
else
max_grps = rk3308->used_adc_grps;
if (idx >= max_grps)
return false;
*grp = rk3308->adc_grps[idx];
*grp = rk3308->i2s_sdis[idx];
dev_dbg(rk3308->plat_dev,
"ADC_TYPE_NORMAL, idx: %d, get grp: %d\n",
idx, *grp);
@@ -500,14 +509,13 @@ static bool adc_for_each_grp(struct rk3308_codec_priv *rk3308,
* Maybe there are rk3308_codec_get_adc_path_state() and
* rk3308_codec_set_adc_path_state() in future.
*/
static int rk3308_codec_get_dac_path_state(struct rk3308_codec_priv *rk3308)
{
return rk3308->dac_path_state;
}
static void rk3308_codec_set_dac_path_state(struct rk3308_codec_priv *rk3308,
int state)
int state)
{
rk3308->dac_path_state = state;
}
@@ -545,12 +553,12 @@ static int rk3308_codec_reset(struct snd_soc_codec *codec)
static int rk3308_codec_adc_dig_reset(struct rk3308_codec_priv *rk3308)
{
regmap_update_bits(rk3308->regmap, RK3308_GLB_CON,
RK3308_ADC_DIG_WORK,
RK3308_ADC_DIG_RESET);
RK3308_ADC_DIG_WORK,
RK3308_ADC_DIG_RESET);
udelay(50);
regmap_update_bits(rk3308->regmap, RK3308_GLB_CON,
RK3308_ADC_DIG_WORK,
RK3308_ADC_DIG_WORK);
RK3308_ADC_DIG_WORK,
RK3308_ADC_DIG_WORK);
return 0;
}
@@ -558,12 +566,12 @@ static int rk3308_codec_adc_dig_reset(struct rk3308_codec_priv *rk3308)
static int rk3308_codec_dac_dig_reset(struct rk3308_codec_priv *rk3308)
{
regmap_update_bits(rk3308->regmap, RK3308_GLB_CON,
RK3308_DAC_DIG_WORK,
RK3308_DAC_DIG_RESET);
RK3308_DAC_DIG_WORK,
RK3308_DAC_DIG_RESET);
udelay(50);
regmap_update_bits(rk3308->regmap, RK3308_GLB_CON,
RK3308_DAC_DIG_WORK,
RK3308_DAC_DIG_WORK);
RK3308_DAC_DIG_WORK,
RK3308_DAC_DIG_WORK);
return 0;
}
@@ -721,99 +729,120 @@ static int rk3308_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
static int rk3308_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
static int rk3308_codec_dac_dig_config(struct rk3308_codec_priv *rk3308,
struct snd_pcm_hw_params *params)
{
struct snd_soc_codec *codec = dai->codec;
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
unsigned int dac_aif1 = 0, dac_aif2 = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
unsigned int dac_aif1 = 0, dac_aif2 = 0;
/* Clear the status of DAC DIG Digital reigisters */
rk3308_codec_dac_dig_reset(rk3308);
/* Clear the status of DAC DIG Digital reigisters */
rk3308_codec_dac_dig_reset(rk3308);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS;
break;
case SNDRV_PCM_FORMAT_S24_LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS;
break;
case SNDRV_PCM_FORMAT_S32_LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS;
break;
default:
return -EINVAL;
}
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS;
break;
case SNDRV_PCM_FORMAT_S24_LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS;
break;
case SNDRV_PCM_FORMAT_S32_LE:
dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS;
break;
default:
return -EINVAL;
}
dac_aif1 |= RK3308_DAC_I2S_LR_NORMAL;
dac_aif2 |= RK3308_DAC_I2S_WORK;
dac_aif1 |= RK3308_DAC_I2S_LR_NORMAL;
dac_aif2 |= RK3308_DAC_I2S_WORK;
regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01,
RK3308_DAC_I2S_VALID_LEN_MSK |
RK3308_DAC_I2S_LR_MSK,
dac_aif1);
regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
RK3308_DAC_I2S_MSK,
dac_aif2);
regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01,
RK3308_DAC_I2S_VALID_LEN_MSK |
RK3308_DAC_I2S_LR_MSK,
dac_aif1);
regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
RK3308_DAC_I2S_MSK,
dac_aif2);
} else {
unsigned int adc_aif1 = 0, adc_aif2 = 0;
int grp, cur_grp_max;
return 0;
}
/* Clear the status of ADC DIG Digital reigisters */
rk3308_codec_adc_dig_reset(rk3308);
static int rk3308_codec_adc_dig_config(struct rk3308_codec_priv *rk3308,
struct snd_pcm_hw_params *params)
{
unsigned int adc_aif1 = 0, adc_aif2 = 0;
int type = ADC_TYPE_NORMAL;
int idx, grp;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS;
break;
case SNDRV_PCM_FORMAT_S24_LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS;
break;
case SNDRV_PCM_FORMAT_S32_LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS;
break;
default:
return -EINVAL;
}
/* Clear the status of ADC DIG Digital reigisters */
rk3308_codec_adc_dig_reset(rk3308);
switch (params_channels(params)) {
case 1:
adc_aif1 |= RK3308_ADC_I2S_MONO;
cur_grp_max = 0;
break;
case 2:
case 4:
case 6:
case 8:
adc_aif1 |= RK3308_ADC_I2S_STEREO;
cur_grp_max = (params_channels(params) - 1) / 2;
break;
default:
return -EINVAL;
}
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS;
break;
case SNDRV_PCM_FORMAT_S24_LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS;
break;
case SNDRV_PCM_FORMAT_S32_LE:
adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS;
break;
default:
return -EINVAL;
}
adc_aif1 |= RK3308_ADC_I2S_LR_NORMAL;
adc_aif2 |= RK3308_ADC_I2S_WORK;
switch (params_channels(params)) {
case 1:
adc_aif1 |= RK3308_ADC_I2S_MONO;
break;
case 2:
case 4:
case 6:
case 8:
adc_aif1 |= RK3308_ADC_I2S_STEREO;
break;
default:
return -EINVAL;
}
for (grp = 0; grp <= cur_grp_max; grp++) {
regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp),
RK3308_ADC_I2S_VALID_LEN_MSK |
RK3308_ADC_I2S_LR_MSK |
RK3308_ADC_I2S_TYPE_MSK,
adc_aif1);
regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp),
RK3308_ADC_I2S_MSK,
adc_aif2);
}
adc_aif1 |= RK3308_ADC_I2S_LR_NORMAL;
adc_aif2 |= RK3308_ADC_I2S_WORK;
for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++) {
regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp),
RK3308_ADC_I2S_VALID_LEN_MSK |
RK3308_ADC_I2S_LR_MSK |
RK3308_ADC_I2S_TYPE_MSK,
adc_aif1);
regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp),
RK3308_ADC_I2S_MSK,
adc_aif2);
}
return 0;
}
static int rk3308_codec_update_adc_grps(struct rk3308_codec_priv *rk3308,
struct snd_pcm_hw_params *params)
{
switch (params_channels(params)) {
case 1:
rk3308->used_adc_grps = 1;
break;
case 2:
case 4:
case 6:
case 8:
rk3308->used_adc_grps = params_channels(params) / 2;
break;
default:
dev_err(rk3308->plat_dev, "Invalid channels: %d\n",
params_channels(params));
return -EINVAL;
}
return 0;
@@ -1041,7 +1070,7 @@ static int rk3308_codec_dac_switch(struct rk3308_codec_priv *rk3308,
rk3308->dac_output = dac_output;
out:
dev_dbg(rk3308->plat_dev, "switch dac_output to: %d\n",
rk3308->dac_output);
rk3308->dac_output);
return ret;
}
@@ -1607,60 +1636,11 @@ static int rk3308_codec_headset_detect_disable(struct rk3308_codec_priv *rk3308)
return 0;
}
static int rk3308_codec_check_adc_grps(struct rk3308_codec_priv *rk3308,
struct device_node *np)
{
int idx, num_grps, ret;
num_grps = of_count_phandle_with_args(np, "rockchip,adc-grps", NULL);
if (num_grps < 0) {
if (num_grps == -ENOENT) {
/* Not use 'rockchip,adc-grps' property here */
ret = 0;
} else {
dev_err(rk3308->plat_dev,
"Failed to read 'rockchip,adc-grps' num: %d\n",
num_grps);
ret = num_grps;
}
return ret;
}
ret = of_property_read_u32_array(np, "rockchip,adc-grps",
rk3308->adc_grps, num_grps);
if (ret < 0) {
dev_err(rk3308->plat_dev,
"Failed to read 'rockchip,adc-grps' property: %d\n",
ret);
return ret;
}
dev_info(rk3308->plat_dev, "The ADC %d groups assignment:\n", num_grps);
for (idx = 0; idx < num_grps; idx++) {
if (rk3308->adc_grps[idx] >= ADC_LR_GROUP_MAX) {
dev_err(rk3308->plat_dev,
"Invalid adc_grp[%d]: %d, should be: 0 - %d\n",
idx, rk3308->adc_grps[idx],
ADC_LR_GROUP_MAX - 1);
return -EINVAL;
}
dev_info(rk3308->plat_dev, "adc_grp[%d]: %d\n",
idx, rk3308->adc_grps[idx]);
}
rk3308->used_grps = num_grps;
return 0;
}
static int rk3308_codec_check_i2s_sdis(struct rk3308_codec_priv *rk3308,
int num)
{
int i, j, ret = 0;
dev_err(rk3308->plat_dev, "xing_codec: %s, %d\n", __func__, __LINE__);
switch (num) {
case 1:
rk3308->which_i2s = ACODEC_TO_I2S1_2CH;
@@ -1707,7 +1687,7 @@ err:
static int rk3308_codec_adc_grps_route_config(struct rk3308_codec_priv *rk3308)
{
int idx;
int idx = 0;
if (rk3308->which_i2s == ACODEC_TO_I2S2_8CH) {
for (idx = 0; idx < rk3308->to_i2s_grps; idx++) {
@@ -1727,6 +1707,25 @@ static int rk3308_codec_adc_grps_route_config(struct rk3308_codec_priv *rk3308)
return 0;
}
/* Put default one-to-one mapping */
static int rk3308_codec_adc_grps_route_default(struct rk3308_codec_priv *rk3308)
{
unsigned int v, idx;
rk3308->which_i2s = ACODEC_TO_I2S2_8CH;
rk3308->to_i2s_grps = ADC_LR_GROUP_MAX;
/*
* The GRF values may be kept the previous status after hot reboot,
* we need to update them.
*/
for (idx = 0; idx < rk3308->to_i2s_grps; idx++) {
regmap_read(rk3308->grf, GRF_SOC_CON1, &v);
rk3308->i2s_sdis[idx] = GRF_I2S2_8CH_SDI_R_MSK(idx, v);
}
return 0;
}
static int rk3308_codec_adc_grps_route(struct rk3308_codec_priv *rk3308,
struct device_node *np)
{
@@ -1742,6 +1741,7 @@ static int rk3308_codec_adc_grps_route(struct rk3308_codec_priv *rk3308,
if (num < 0) {
if (num == -ENOENT) {
/* Not use 'rockchip,adc-grps-route' property here */
rk3308_codec_adc_grps_route_default(rk3308);
ret = 0;
} else {
dev_err(rk3308->plat_dev,
@@ -2361,9 +2361,8 @@ static int rk3308_codec_adc_ana_disable(struct rk3308_codec_priv *rk3308,
return 0;
}
static int rk3308_codec_open_capture(struct snd_soc_codec *codec)
static int rk3308_codec_open_capture(struct rk3308_codec_priv *rk3308)
{
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
int idx, grp = 0;
int type = ADC_TYPE_NORMAL;
@@ -2393,36 +2392,54 @@ static int rk3308_codec_open_capture(struct snd_soc_codec *codec)
return 0;
}
static int rk3308_codec_close_capture(struct snd_soc_codec *codec)
static int rk3308_codec_close_capture(struct rk3308_codec_priv *rk3308)
{
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
rk3308_codec_alc_disable(rk3308, ADC_TYPE_NORMAL);
rk3308_codec_adc_ana_disable(rk3308, ADC_TYPE_NORMAL);
return 0;
}
static int rk3308_codec_open_playback(struct snd_soc_codec *codec)
static int rk3308_codec_open_playback(struct rk3308_codec_priv *rk3308)
{
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
rk3308_codec_dac_enable(rk3308);
rk3308_codec_set_dac_path_state(rk3308, PATH_BUSY);
return 0;
}
static int rk3308_codec_close_playback(struct snd_soc_codec *codec)
static int rk3308_codec_close_playback(struct rk3308_codec_priv *rk3308)
{
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
rk3308_codec_set_dac_path_state(rk3308, PATH_IDLE);
rk3308_codec_dac_disable(rk3308);
return 0;
}
static int rk3308_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
int ret;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
/* DAC only supports 2 channels */
rk3308_codec_open_playback(rk3308);
rk3308_codec_dac_dig_config(rk3308, params);
} else {
ret = rk3308_codec_update_adc_grps(rk3308, params);
if (ret < 0)
return ret;
rk3308_codec_open_capture(rk3308);
rk3308_codec_adc_dig_config(rk3308, params);
}
return 0;
}
static int rk3308_pcm_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
@@ -2445,24 +2462,6 @@ static int rk3308_pcm_trigger(struct snd_pcm_substream *substream,
return 0;
}
static int rk3308_pcm_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = rk3308_codec_open_playback(codec);
else
ret = rk3308_codec_open_capture(codec);
regcache_cache_only(rk3308->regmap, false);
regcache_sync(rk3308->regmap);
return ret;
}
static void rk3308_pcm_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -2470,9 +2469,9 @@ static void rk3308_pcm_shutdown(struct snd_pcm_substream *substream,
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rk3308_codec_close_playback(codec);
rk3308_codec_close_playback(rk3308);
else
rk3308_codec_close_capture(codec);
rk3308_codec_close_capture(rk3308);
regcache_cache_only(rk3308->regmap, false);
regcache_sync(rk3308->regmap);
@@ -2483,7 +2482,6 @@ static struct snd_soc_dai_ops rk3308_dai_ops = {
.set_fmt = rk3308_set_dai_fmt,
.mute_stream = rk3308_mute_stream,
.trigger = rk3308_pcm_trigger,
.startup = rk3308_pcm_startup,
.shutdown = rk3308_pcm_shutdown,
};
@@ -2529,11 +2527,11 @@ static int rk3308_resume(struct snd_soc_codec *codec)
return 0;
}
static int rk3308_codec_prepare(struct snd_soc_codec *codec)
static int rk3308_codec_prepare(struct rk3308_codec_priv *rk3308)
{
/* Clear registers for ADC and DAC */
rk3308_codec_close_playback(codec);
rk3308_codec_close_capture(codec);
rk3308_codec_close_playback(rk3308);
rk3308_codec_close_capture(rk3308);
return 0;
}
@@ -2551,7 +2549,7 @@ static int rk3308_probe(struct snd_soc_codec *codec)
/* From vendor recommend */
rk3308_codec_micbias_enable(rk3308, RK3308_ADC_MICBIAS_VOLT_0_85);
rk3308_codec_prepare(codec);
rk3308_codec_prepare(rk3308);
rk3308_codec_headset_detect_enable(rk3308);
regcache_cache_only(rk3308->regmap, false);
@@ -2708,7 +2706,7 @@ static ssize_t adc_grps_show(struct device *dev,
int type = ADC_TYPE_NORMAL, count = 0;
int idx;
count += sprintf(buf + count, "used adc_grps:\n");
count += sprintf(buf + count, "current used adc_grps:\n");
count += sprintf(buf + count, "- normal:");
for (idx = 0; adc_for_each_grp(rk3308, type, idx, &grp); idx++)
count += sprintf(buf + count, " %d", grp);
@@ -2725,27 +2723,21 @@ static ssize_t adc_grps_store(struct device *dev,
{
struct rk3308_codec_priv *rk3308 =
container_of(dev, struct rk3308_codec_priv, dev);
u32 adc_grps[ADC_LR_GROUP_MAX];
char adc_type;
int idx, num_grps;
int grps, ret;
sscanf(buf, "%c,%d,%d,%d,%d,%d", &adc_type, &num_grps,
&adc_grps[0], &adc_grps[1], &adc_grps[2], &adc_grps[3]);
if (adc_type == 'n') {
for (idx = 0; idx < num_grps; idx++) {
sscanf(buf, "%d", &adc_grps[idx]);
rk3308->adc_grps[idx] = adc_grps[idx];
}
rk3308->used_grps = num_grps;
} else if (adc_type == 'l') {
if (num_grps != 1)
pr_warn("loopback type num_grps should be 1\n");
rk3308->loopback_grp = adc_grps[0];
ret = sscanf(buf, "%c,%d", &adc_type, &grps);
if (ret != 2) {
dev_err(rk3308->plat_dev, "%s sscanf failed: %d\n",
__func__, ret);
return -EFAULT;
}
if (adc_type == 'n')
rk3308->used_adc_grps = grps;
else if (adc_type == 'l')
rk3308->loopback_grp = grps;
return count;
}
@@ -2788,9 +2780,15 @@ static ssize_t adc_grps_route_store(struct device *dev,
struct rk3308_codec_priv *rk3308 =
container_of(dev, struct rk3308_codec_priv, dev);
int which_i2s, idx, i2s_sdis[ADC_LR_GROUP_MAX];
int ret;
sscanf(buf, "%d,%d,%d,%d,%d", &which_i2s,
&i2s_sdis[0], &i2s_sdis[1], &i2s_sdis[2], &i2s_sdis[3]);
ret = sscanf(buf, "%d,%d,%d,%d,%d", &which_i2s,
&i2s_sdis[0], &i2s_sdis[1], &i2s_sdis[2], &i2s_sdis[3]);
if (ret != 5) {
dev_err(rk3308->plat_dev, "%s sscanf failed: %d\n",
__func__, ret);
goto err;
}
if (which_i2s < ACODEC_TO_I2S2_8CH ||
which_i2s > ACODEC_TO_I2S1_2CH) {
@@ -2937,12 +2935,43 @@ static ssize_t dac_output_store(struct device *dev,
return count;
}
static const struct device_attribute adc_ch_attrs[] = {
__ATTR(adc_grps, 0644, adc_grps_show, adc_grps_store),
__ATTR(adc_grps_route, 0644, adc_grps_route_show, adc_grps_route_store),
__ATTR(adc_grp0_in, 0644, adc_grp0_in_show, adc_grp0_in_store),
__ATTR(adc_zerocross, 0644, adc_zerocross_show, adc_zerocross_store),
__ATTR(dac_output, 0644, dac_output_show, dac_output_store),
static ssize_t enable_all_adcs_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->enable_all_adcs);
}
static ssize_t enable_all_adcs_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 enable;
int ret = kstrtoul(buf, 10, &enable);
if (ret < 0) {
dev_err(dev, "Invalid enable value: %ld, ret: %d\n",
enable, ret);
return -EINVAL;
}
rk3308->enable_all_adcs = enable;
return count;
}
static const struct device_attribute acodec_attrs[] = {
__ATTR_RW(adc_grps),
__ATTR_RW(adc_grps_route),
__ATTR_RW(adc_grp0_in),
__ATTR_RW(adc_zerocross),
__ATTR_RW(dac_output),
__ATTR_RW(enable_all_adcs),
};
static void rk3308_codec_device_release(struct device *dev)
@@ -2968,8 +2997,8 @@ static int rk3308_codec_sysfs_init(struct platform_device *pdev,
return -ENOMEM;
}
for (i = 0; i < ARRAY_SIZE(adc_ch_attrs); i++) {
if (device_create_file(dev, &adc_ch_attrs[i])) {
for (i = 0; i < ARRAY_SIZE(acodec_attrs); i++) {
if (device_create_file(dev, &acodec_attrs[i])) {
dev_err(&pdev->dev,
"Create 'rk3308-acodec-dev' attr failed\n");
device_unregister(dev);
@@ -3169,6 +3198,9 @@ static int rk3308_platform_probe(struct platform_device *pdev)
return ret;
}
rk3308->enable_all_adcs =
of_property_read_bool(np, "rockchip,enable-all-adcs");
rk3308->loopback_grp = LOOPBACK_NO_USE;
ret = of_property_read_u32(np, "rockchip,loopback-grp",
&rk3308->loopback_grp);
@@ -3182,13 +3214,6 @@ static int rk3308_platform_probe(struct platform_device *pdev)
return ret;
}
ret = rk3308_codec_check_adc_grps(rk3308, np);
if (ret < 0) {
dev_err(&pdev->dev, "Invalid ADC group configuration: %d\n",
ret);
return ret;
}
ret = rk3308_codec_adc_grps_route(rk3308, np);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to route ADC groups: %d\n",