From 2dbb29cd977fc281f71f8895abce7e382efe77e1 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 23 Nov 2017 21:30:07 +0100 Subject: [PATCH 1/5] ASoC: twl4030: Delete an error message for a failed memory allocation in twl4030_get_pdata() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index cfe72b9d4356..90691701b082 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -240,7 +240,6 @@ static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec) sizeof(struct twl4030_codec_data), GFP_KERNEL); if (!pdata) { - dev_err(codec->dev, "Can not allocate memory\n"); of_node_put(twl4030_codec_node); return NULL; } From 3bd333677d6091d989068b0f7ff7aba975e62dc5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 9 Nov 2017 01:04:37 +0000 Subject: [PATCH 2/5] ASoC: don't use codec hw_write on twl6040 twl6040 driver is using codec hw_write/control_data, but it is redundant code. This patch cleanup these Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/codecs/twl6040.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 1773ff84ee3b..a8e6941a1868 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -106,10 +106,12 @@ static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = { { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, }; +#define to_twl6040(codec) dev_get_drvdata((codec)->dev->parent) + static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg) { struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); - struct twl6040 *twl6040 = codec->control_data; + struct twl6040 *twl6040 = to_twl6040(codec); u8 value; if (reg >= TWL6040_CACHEREGNUM) @@ -171,7 +173,7 @@ static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec, static int twl6040_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - struct twl6040 *twl6040 = codec->control_data; + struct twl6040 *twl6040 = to_twl6040(codec); if (reg >= TWL6040_CACHEREGNUM) return -EIO; @@ -572,7 +574,7 @@ EXPORT_SYMBOL_GPL(twl6040_get_trim_value); int twl6040_get_hs_step_size(struct snd_soc_codec *codec) { - struct twl6040 *twl6040 = codec->control_data; + struct twl6040 *twl6040 = to_twl6040(codec); if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3) /* For ES under ES_1.3 HS step is 2 mV */ @@ -830,7 +832,7 @@ static const struct snd_soc_dapm_route intercon[] = { static int twl6040_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct twl6040 *twl6040 = codec->control_data; + struct twl6040 *twl6040 = to_twl6040(codec); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); int ret = 0; @@ -922,7 +924,7 @@ static int twl6040_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - struct twl6040 *twl6040 = codec->control_data; + struct twl6040 *twl6040 = to_twl6040(codec); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); int ret; @@ -964,7 +966,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id, int mute) { - struct twl6040 *twl6040 = codec->control_data; + struct twl6040 *twl6040 = to_twl6040(codec); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); int hslctl, hsrctl, earctl; int hflctl, hfrctl; @@ -1108,7 +1110,6 @@ static struct snd_soc_dai_driver twl6040_dai[] = { static int twl6040_probe(struct snd_soc_codec *codec) { struct twl6040_data *priv; - struct twl6040 *twl6040 = dev_get_drvdata(codec->dev->parent); struct platform_device *pdev = to_platform_device(codec->dev); int ret = 0; @@ -1119,7 +1120,6 @@ static int twl6040_probe(struct snd_soc_codec *codec) snd_soc_codec_set_drvdata(codec, priv); priv->codec = codec; - codec->control_data = twl6040; priv->plug_irq = platform_get_irq(pdev, 0); if (priv->plug_irq < 0) { From 93a00c467fe998bf5716cbc9cabc127046054782 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 14 Nov 2017 01:04:58 +0000 Subject: [PATCH 3/5] ASoC: don't use snd_soc_write/read on twl6040 twl6040 doesn't use regmap nor reg_cache. Its write/read are done through twl6040_reg_write/read. This driver directly calling these functions, but sometimes using snd_soc_write/read. As part of cleanup, snd_soc_codec_driver::write, read will be removed soon. Then, write/read access through snd_soc_write/read will doesn't work on this driver, since it doesn't use regmap nor reg_cache. This patch replace snd_soc_write/read to twl6040_write/read. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/codecs/twl6040.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index a8e6941a1868..3b895b4b451c 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -543,7 +543,7 @@ int twl6040_get_dl1_gain(struct snd_soc_codec *codec) if (snd_soc_dapm_get_pin_status(dapm, "HSOR") || snd_soc_dapm_get_pin_status(dapm, "HSOL")) { - u8 val = snd_soc_read(codec, TWL6040_REG_HSLCTL); + u8 val = twl6040_read(codec, TWL6040_REG_HSLCTL); if (val & TWL6040_HSDACMODE) /* HSDACL in LP mode */ return -8; /* -8dB */ @@ -1158,8 +1158,6 @@ static int twl6040_remove(struct snd_soc_codec *codec) static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = { .probe = twl6040_probe, .remove = twl6040_remove, - .read = twl6040_read, - .write = twl6040_write, .set_bias_level = twl6040_set_bias_level, .suspend_bias_off = true, .ignore_pmdown_time = true, From 3bb0f7c31b1aedd0f85c675297031281799145d7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 14 Nov 2017 01:05:17 +0000 Subject: [PATCH 4/5] ASoC: don't use snd_soc_write/read on twl4030 twl4030 doesn't use regmap nor reg_cache. Its write/read are done through twl4030_reg_write/read. This driver directly calling these functions, but sometimes using snd_soc_write/read. As part of cleanup, snd_soc_codec_driver::write, read will be removed soon. Then, write/read access through snd_soc_write/read will doesn't work on this driver, since it doesn't use regmap nor reg_cache. This patch replace snd_soc_write/read to twl4030_write/read. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 90691701b082..8798182959c1 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -850,14 +850,14 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, int mask = (1 << fls(max)) - 1; ucontrol->value.integer.value[0] = - (snd_soc_read(codec, reg) >> shift) & mask; + (twl4030_read(codec, reg) >> shift) & mask; if (ucontrol->value.integer.value[0]) ucontrol->value.integer.value[0] = max + 1 - ucontrol->value.integer.value[0]; if (shift != rshift) { ucontrol->value.integer.value[1] = - (snd_soc_read(codec, reg) >> rshift) & mask; + (twl4030_read(codec, reg) >> rshift) & mask; if (ucontrol->value.integer.value[1]) ucontrol->value.integer.value[1] = max + 1 - ucontrol->value.integer.value[1]; @@ -908,9 +908,9 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, int mask = (1<value.integer.value[0] = - (snd_soc_read(codec, reg) >> shift) & mask; + (twl4030_read(codec, reg) >> shift) & mask; ucontrol->value.integer.value[1] = - (snd_soc_read(codec, reg2) >> shift) & mask; + (twl4030_read(codec, reg2) >> shift) & mask; if (ucontrol->value.integer.value[0]) ucontrol->value.integer.value[0] = @@ -2195,8 +2195,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = { .probe = twl4030_soc_probe, .remove = twl4030_soc_remove, - .read = twl4030_read, - .write = twl4030_write, .set_bias_level = twl4030_set_bias_level, .idle_bias_off = true, From 8146acff3b80327f2a23710f2674a79a7fa80de3 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 25 Jan 2018 09:35:05 -0800 Subject: [PATCH 5/5] ASoC: Fix twl4030 and 6040 regression by adding back read and write Commit 3bb0f7c31b1a ("ASoC: don't use snd_soc_write/read on twl4030") caused regressions for both twl4030 and twl6040 as it assumes the ASoC driver is using regmap. As a side effect, this also causes a considerable increase in idle power consumption omap3 boards using twl4030 as the PMIC. This is because the removal of read and write function pointers causes some of the ASoC IO functions to not do anything. For example, snd_soc_register_card() calls snd_soc_dapm_new_widgets() that calls snd_soc_codec_drv_read() that now does nothing. A long term solution suggested by Mark Brown is to make the twl drivers use regmap by adding a call to snd_soc_codec_set_regmap(). This however needs more consideration as currently the driver internal reads do caching and we would have both regmap access and internal read/write access accessing the same hardware registers. So to fix the regression, let's just do a partial revert adding back the read and write function pointers. Note that other non-regmap ASoC drivers may need similar patches. Fixes: 3bb0f7c31b1a ("ASoC: don't use snd_soc_write/read on twl4030") Fixes: 93a00c467fe9 ("ASoC: don't use snd_soc_write/read on twl6040") Acked-by: Kuninori Morimoto Acked-by: Peter Ujfalusi Signed-off-by: Tony Lindgren Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 2 ++ sound/soc/codecs/twl6040.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 8798182959c1..e4d7f397d361 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -2195,6 +2195,8 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = { .probe = twl4030_soc_probe, .remove = twl4030_soc_remove, + .read = twl4030_read, + .write = twl4030_write, .set_bias_level = twl4030_set_bias_level, .idle_bias_off = true, diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 3b895b4b451c..573a523ed0b3 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1158,6 +1158,8 @@ static int twl6040_remove(struct snd_soc_codec *codec) static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = { .probe = twl6040_probe, .remove = twl6040_remove, + .read = twl6040_read, + .write = twl6040_write, .set_bias_level = twl6040_set_bias_level, .suspend_bias_off = true, .ignore_pmdown_time = true,