[alsa-devel] [PATCH 0/6] ASoC/MFD: twl6040: PLL handling changes
Hello,
The following series depends on the v6 of twl6040 MFD series.
The aim is to simplify the PLL handling for twl6040: - Move the PLL selection control to the codec driver from machine driver - Sample rate constraint simplification for selected PLL - Avoid multiple, duplicated PLL configuration, which can slow down the audio startup. - Harmonize the PLL ID usage among the drivers, so we avoid redundancy.
I have generated this series on top of l-o/devel-cleanup branch + my previous twl6040 MFD/Input/ASoC v6 series, since it depends on the changes introduced there. Is it OK, if Tony will be taking this as well to avoid cross tree merge issues? I can put the series on top of my previous series, and offer Tony a pull link.
Regards, Peter
--- Peter Ujfalusi (6): ASoC: twl6040: Use neutral name for power mode text/enum ASoC: twl6040: Move PLL selection to codec driver ASoC: twl6040: Simplify sample rate constraint handling ASoC: twl6040: Configure PLL only once MFD: twl6040: Remove enum for PLL tracking ASoC: twl6040: No need to convert the PLL ID
drivers/mfd/twl6040-core.c | 26 +++--- include/linux/mfd/twl6040.h | 17 ++--- sound/soc/codecs/twl6040.c | 182 ++++++++++++++++++++++--------------------- sound/soc/codecs/twl6040.h | 1 + sound/soc/omap/sdp4430.c | 47 +---------- 5 files changed, 118 insertions(+), 155 deletions(-)
Change the variable names to be neutral (not refering to HS). This will ease up the introduction of PLL selection, which going to use the same enum strings.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/twl6040.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 0145041..3b2843c 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1012,13 +1012,13 @@ static const struct snd_kcontrol_new ep_driver_switch_controls = SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
/* Headset power mode */ -static const char *twl6040_headset_power_texts[] = { +static const char *twl6040_power_mode_texts[] = { "Low-Power", "High-Perfomance", };
-static const struct soc_enum twl6040_headset_power_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_headset_power_texts), - twl6040_headset_power_texts); +static const struct soc_enum twl6040_power_mode_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_power_mode_texts), + twl6040_power_mode_texts);
static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1067,7 +1067,7 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { SOC_SINGLE_TLV("Earphone Playback Volume", TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
- SOC_ENUM_EXT("Headset Power Mode", twl6040_headset_power_enum, + SOC_ENUM_EXT("Headset Power Mode", twl6040_power_mode_enum, twl6040_headset_power_get_enum, twl6040_headset_power_put_enum), };
It is better if the selection between the Low power, and High performance PLL is handled within the codec driver, not in machine driver(s) to avoid duplicated code, and also to have consistent tracking of the selected PLL, and the resulting differences in supported sample rates.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/twl6040.c | 110 +++++++++++++++++++++++++++++--------------- sound/soc/codecs/twl6040.h | 1 + sound/soc/omap/sdp4430.c | 47 ++----------------- 3 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 3b2843c..e61f32f 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -79,6 +79,7 @@ struct twl6040_data { int codec_powered; int pll; int non_lp; + int pll_power_mode; int hs_power_mode; int hs_power_mode_locked; unsigned int clk_in; @@ -209,6 +210,37 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = { TWL6040_REG_DLB, };
+/* set of rates for each pll: low-power and high-performance */ +static unsigned int lp_rates[] = { + 8000, + 11250, + 16000, + 22500, + 32000, + 44100, + 48000, + 88200, + 96000, +}; + +static struct snd_pcm_hw_constraint_list lp_constraints = { + .count = ARRAY_SIZE(lp_rates), + .list = lp_rates, +}; + +static unsigned int hp_rates[] = { + 8000, + 16000, + 32000, + 48000, + 96000, +}; + +static struct snd_pcm_hw_constraint_list hp_constraints = { + .count = ARRAY_SIZE(hp_rates), + .list = hp_rates, +}; + /* * read twl6040 register cache */ @@ -1048,6 +1080,43 @@ static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, return ret; }
+static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = priv->pll_power_mode; + + return 0; +} + +static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + + priv->pll_power_mode = ucontrol->value.enumerated.item[0]; + if (priv->pll_power_mode) + priv->sysclk_constraints = &hp_constraints; + else + priv->sysclk_constraints = &lp_constraints; + + return 0; +} + +int twl6040_get_clk_id(struct snd_soc_codec *codec) +{ + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + + if (priv->pll_power_mode) + return TWL6040_SYSCLK_SEL_HPPLL; + else + return TWL6040_SYSCLK_SEL_LPPLL; +} +EXPORT_SYMBOL_GPL(twl6040_get_clk_id); + static const struct snd_kcontrol_new twl6040_snd_controls[] = { /* Capture gains */ SOC_DOUBLE_TLV("Capture Preamplifier Volume", @@ -1070,6 +1139,9 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { SOC_ENUM_EXT("Headset Power Mode", twl6040_power_mode_enum, twl6040_headset_power_get_enum, twl6040_headset_power_put_enum), + + SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum, + twl6040_pll_get_enum, twl6040_pll_put_enum), };
static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { @@ -1288,38 +1360,6 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, return 0; }
-/* set of rates for each pll: low-power and high-performance */ - -static unsigned int lp_rates[] = { - 8000, - 11250, - 16000, - 22500, - 32000, - 44100, - 48000, - 88200, - 96000, -}; - -static struct snd_pcm_hw_constraint_list lp_constraints = { - .count = ARRAY_SIZE(lp_rates), - .list = lp_rates, -}; - -static unsigned int hp_rates[] = { - 8000, - 16000, - 32000, - 48000, - 96000, -}; - -static struct snd_pcm_hw_constraint_list hp_constraints = { - .count = ARRAY_SIZE(hp_rates), - .list = hp_rates, -}; - static int twl6040_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1426,16 +1466,12 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, freq, priv->sysclk); if (ret) return ret; - - priv->sysclk_constraints = &lp_constraints; break; case TWL6040_SYSCLK_SEL_HPPLL: ret = twl6040_set_pll(twl6040, TWL6040_HPPLL_ID, freq, priv->sysclk); if (ret) return ret; - - priv->sysclk_constraints = &hp_constraints; break; default: dev_err(codec->dev, "unknown clk_id %d\n", clk_id); @@ -1553,7 +1589,7 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->hf_right_step = 1; }
- priv->sysclk_constraints = &hp_constraints; + priv->sysclk_constraints = &lp_constraints; priv->workqueue = create_singlethread_workqueue("twl6040-codec"); if (!priv->workqueue) { ret = -ENOMEM; diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index 234bfad..d8de678 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h @@ -24,5 +24,6 @@
void twl6040_hs_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int report); +int twl6040_get_clk_id(struct snd_soc_codec *codec);
#endif /* End of __TWL6040_H__ */ diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 5d67c25..d9172c0 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -36,8 +36,6 @@ #include "omap-pcm.h" #include "../codecs/twl6040.h"
-static int twl6040_power_mode; - static int sdp4430_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -46,13 +44,13 @@ static int sdp4430_hw_params(struct snd_pcm_substream *substream, int clk_id, freq; int ret;
- if (twl6040_power_mode) { - clk_id = TWL6040_SYSCLK_SEL_HPPLL; + clk_id = twl6040_get_clk_id(rtd->codec); + if (clk_id == TWL6040_SYSCLK_SEL_HPPLL) freq = 38400000; - } else { - clk_id = TWL6040_SYSCLK_SEL_LPPLL; + else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL) freq = 32768; - } + else + return -EINVAL;
/* set the codec mclk */ ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq, @@ -83,35 +81,6 @@ static struct snd_soc_jack_pin hs_jack_pins[] = { }, };
-static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = twl6040_power_mode; - return 0; -} - -static int sdp4430_set_power_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (twl6040_power_mode == ucontrol->value.integer.value[0]) - return 0; - - twl6040_power_mode = ucontrol->value.integer.value[0]; - - return 1; -} - -static const char *power_texts[] = {"Low-Power", "High-Performance"}; - -static const struct soc_enum sdp4430_enum[] = { - SOC_ENUM_SINGLE_EXT(2, power_texts), -}; - -static const struct snd_kcontrol_new sdp4430_controls[] = { - SOC_ENUM_EXT("TWL6040 Power Mode", sdp4430_enum[0], - sdp4430_get_power_mode, sdp4430_set_power_mode), -}; - /* SDP4430 machine DAPM */ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { SND_SOC_DAPM_MIC("Ext Mic", NULL), @@ -154,12 +123,6 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; int ret;
- /* Add SDP4430 specific controls */ - ret = snd_soc_add_controls(codec, sdp4430_controls, - ARRAY_SIZE(sdp4430_controls)); - if (ret) - return ret; - /* Add SDP4430 specific widgets */ ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
We can manage the sample rate constraints without the need to maintain a variable and a pointer. This simplifies the handling of the constraint, and makes it more robust.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/twl6040.c | 19 ++++--------------- 1 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index e61f32f..9229049 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -88,7 +88,6 @@ struct twl6040_data { u16 hs_right_step; u16 hf_left_step; u16 hf_right_step; - struct snd_pcm_hw_constraint_list *sysclk_constraints; struct twl6040_jack_data hs_jack; struct snd_soc_codec *codec; struct workqueue_struct *workqueue; @@ -223,11 +222,6 @@ static unsigned int lp_rates[] = { 96000, };
-static struct snd_pcm_hw_constraint_list lp_constraints = { - .count = ARRAY_SIZE(lp_rates), - .list = lp_rates, -}; - static unsigned int hp_rates[] = { 8000, 16000, @@ -236,9 +230,9 @@ static unsigned int hp_rates[] = { 96000, };
-static struct snd_pcm_hw_constraint_list hp_constraints = { - .count = ARRAY_SIZE(hp_rates), - .list = hp_rates, +static struct snd_pcm_hw_constraint_list sysclk_constraints[] = { + { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, }, + { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, };
/* @@ -1098,10 +1092,6 @@ static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
priv->pll_power_mode = ucontrol->value.enumerated.item[0]; - if (priv->pll_power_mode) - priv->sysclk_constraints = &hp_constraints; - else - priv->sysclk_constraints = &lp_constraints;
return 0; } @@ -1369,7 +1359,7 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - priv->sysclk_constraints); + &sysclk_constraints[priv->pll_power_mode]);
return 0; } @@ -1589,7 +1579,6 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->hf_right_step = 1; }
- priv->sysclk_constraints = &lp_constraints; priv->workqueue = create_singlethread_workqueue("twl6040-codec"); if (!priv->workqueue) { ret = -ENOMEM;
Avoid configuring the PLL several times during audio startup. We can configure the PLL at prepare time with parameters collected earlier hw_param, and set_dai_sysclk calls.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/twl6040.c | 72 ++++++++++++++++--------------------------- 1 files changed, 27 insertions(+), 45 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 9229049..407c79e 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1342,9 +1342,6 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, break; }
- /* get PLL and sysclk after power transition */ - priv->pll = twl6040_get_pll(twl6040); - priv->sysclk = twl6040_get_sysclk(twl6040); codec->dapm.bias_level = level;
return 0; @@ -1370,14 +1367,8 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; - struct twl6040 *twl6040 = codec->control_data; struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); - unsigned int sysclk; - int rate, ret; - - /* nothing to do for high-perf pll, it supports only 48 kHz */ - if (priv->pll == TWL6040_HPPLL_ID) - return 0; + int rate;
rate = params_rate(params); switch (rate) { @@ -1385,26 +1376,33 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream, case 22500: case 44100: case 88200: - sysclk = 17640000; + /* These rates are not supported when HPPLL is in use */ + if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) { + dev_err(codec->dev, "HPPLL does not support rate %d\n", + rate); + return -EINVAL; + } + /* Capture is not supported with 17.64MHz sysclk */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + dev_err(codec->dev, + "capture mode is not supported at %dHz\n", + rate); + return -EINVAL; + } + priv->sysclk = 17640000; break; case 8000: case 16000: case 32000: case 48000: case 96000: - sysclk = 19200000; + priv->sysclk = 19200000; break; default: dev_err(codec->dev, "unsupported rate %d\n", rate); return -EINVAL; }
- ret = twl6040_set_pll(twl6040, TWL6040_LPPLL_ID, priv->clk_in, sysclk); - if (ret) - return ret; - - priv->sysclk = twl6040_get_sysclk(twl6040); - return 0; }
@@ -1413,7 +1411,9 @@ static int twl6040_prepare(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; + struct twl6040 *twl6040 = codec->control_data; struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + int ret;
if (!priv->sysclk) { dev_err(codec->dev, @@ -1421,24 +1421,19 @@ static int twl6040_prepare(struct snd_pcm_substream *substream, return -EINVAL; }
- /* - * capture is not supported at 17.64 MHz, - * it's reserved for headset low-power playback scenario - */ - if ((priv->sysclk == 17640000) && - substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - dev_err(codec->dev, - "capture mode is not supported at %dHz\n", - priv->sysclk); - return -EINVAL; - } - if ((priv->sysclk == 17640000) && priv->non_lp) { dev_err(codec->dev, "some enabled paths aren't supported at %dHz\n", priv->sysclk); return -EPERM; } + + ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); + if (ret) { + dev_err(codec->dev, "Can not set PLL (%d)\n", ret); + return -EPERM; + } + return 0; }
@@ -1446,32 +1441,19 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; - struct twl6040 *twl6040 = codec->control_data; struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); - int ret = 0;
switch (clk_id) { case TWL6040_SYSCLK_SEL_LPPLL: - ret = twl6040_set_pll(twl6040, TWL6040_LPPLL_ID, - freq, priv->sysclk); - if (ret) - return ret; - break; case TWL6040_SYSCLK_SEL_HPPLL: - ret = twl6040_set_pll(twl6040, TWL6040_HPPLL_ID, - freq, priv->sysclk); - if (ret) - return ret; + priv->pll = clk_id; + priv->clk_in = freq; break; default: dev_err(codec->dev, "unknown clk_id %d\n", clk_id); return -EINVAL; }
- priv->pll = twl6040_get_pll(twl6040); - priv->clk_in = freq; - priv->sysclk = twl6040_get_sysclk(twl6040); - return 0; }
There is no need to have two different types for tracking the selected PLL. Use only the defines, when dealing with the PLLs.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- drivers/mfd/twl6040-core.c | 26 +++++++++++++------------- include/linux/mfd/twl6040.h | 17 ++++++----------- 2 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b6e5338..50152d7 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c @@ -270,7 +270,8 @@ int twl6040_power(struct twl6040 *twl6040, int on) goto out; } } - twl6040->pll = TWL6040_LPPLL_ID; + /* Default PLL configuration after power up */ + twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; twl6040->sysclk = 19200000; } else { /* already powered-down */ @@ -294,7 +295,6 @@ int twl6040_power(struct twl6040 *twl6040, int on) /* use manual power-down sequence */ twl6040_power_down(twl6040); } - twl6040->pll = TWL6040_NOPLL_ID; twl6040->sysclk = 0; }
@@ -310,7 +310,7 @@ int twl6040_is_powered(struct twl6040 *twl6040) } EXPORT_SYMBOL(twl6040_is_powered);
-int twl6040_set_pll(struct twl6040 *twl6040, enum twl6040_pll_id id, +int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, unsigned int freq_in, unsigned int freq_out) { u8 hppllctl, lppllctl; @@ -321,8 +321,8 @@ int twl6040_set_pll(struct twl6040 *twl6040, enum twl6040_pll_id id, hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL); lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL);
- switch (id) { - case TWL6040_LPPLL_ID: + switch (pll_id) { + case TWL6040_SYSCLK_SEL_LPPLL: /* low-power PLL divider */ switch (freq_out) { case 17640000: @@ -358,10 +358,8 @@ int twl6040_set_pll(struct twl6040 *twl6040, enum twl6040_pll_id id, ret = -EINVAL; goto pll_out; } - - twl6040->pll = TWL6040_LPPLL_ID; break; - case TWL6040_HPPLL_ID: + case TWL6040_SYSCLK_SEL_HPPLL: /* high-performance PLL can provide only 19.2 MHz */ if (freq_out != 19200000) { dev_err(&twl6040_dev->dev, @@ -412,16 +410,15 @@ int twl6040_set_pll(struct twl6040 *twl6040, enum twl6040_pll_id id, twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); lppllctl &= ~TWL6040_LPLLENA; twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); - - twl6040->pll = TWL6040_HPPLL_ID; break; default: - dev_err(&twl6040_dev->dev, "unknown pll id %d\n", id); + dev_err(&twl6040_dev->dev, "unknown pll id %d\n", pll_id); ret = -EINVAL; goto pll_out; }
twl6040->sysclk = freq_out; + twl6040->pll = pll_id;
pll_out: mutex_unlock(&twl6040->mutex); @@ -429,9 +426,12 @@ pll_out: } EXPORT_SYMBOL(twl6040_set_pll);
-enum twl6040_pll_id twl6040_get_pll(struct twl6040 *twl6040) +int twl6040_get_pll(struct twl6040 *twl6040) { - return twl6040->pll; + if (twl6040->power_count) + return twl6040->pll; + else + return -ENODEV; } EXPORT_SYMBOL(twl6040_get_pll);
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index d384a01..2008f2e 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h @@ -165,9 +165,6 @@ #define TWL6040_RESETSPLIT 0x04 #define TWL6040_INTCLRMODE 0x08
-#define TWL6040_SYSCLK_SEL_LPPLL 1 -#define TWL6040_SYSCLK_SEL_HPPLL 2 - /* STATUS (0x2E) fields */
#define TWL6040_PLUGCOMP 0x02 @@ -188,11 +185,9 @@ #define TWL6040_IRQ_VIB 4 #define TWL6040_IRQ_READY 5
-enum twl6040_pll_id { - TWL6040_NOPLL_ID, - TWL6040_LPPLL_ID, - TWL6040_HPPLL_ID, -}; +/* PLL selection */ +#define TWL6040_SYSCLK_SEL_LPPLL 0 +#define TWL6040_SYSCLK_SEL_HPPLL 1
struct twl6040 { struct device *dev; @@ -206,7 +201,7 @@ struct twl6040 { int power_count; int rev;
- enum twl6040_pll_id pll; + int pll; unsigned int sysclk;
unsigned int irq; @@ -251,9 +246,9 @@ int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask); int twl6040_power(struct twl6040 *twl6040, int on); int twl6040_is_powered(struct twl6040 *twl6040); -int twl6040_set_pll(struct twl6040 *twl6040, enum twl6040_pll_id id, +int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, unsigned int freq_in, unsigned int freq_out); -enum twl6040_pll_id twl6040_get_pll(struct twl6040 *twl6040); +int twl6040_get_pll(struct twl6040 *twl6040); unsigned int twl6040_get_sysclk(struct twl6040 *twl6040); int twl6040_irq_init(struct twl6040 *twl6040); void twl6040_irq_exit(struct twl6040 *twl6040);
Since the PLL handling has been simplified, and rebased on 0, there is no longer need for converting the PLL ID.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/twl6040.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 407c79e..a03f57e 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1100,10 +1100,7 @@ int twl6040_get_clk_id(struct snd_soc_codec *codec) { struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- if (priv->pll_power_mode) - return TWL6040_SYSCLK_SEL_HPPLL; - else - return TWL6040_SYSCLK_SEL_LPPLL; + return priv->pll_power_mode; } EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
On Mon, Jul 04, 2011 at 01:05:58PM +0300, Peter Ujfalusi wrote:
Since the PLL handling has been simplified, and rebased on 0, there is no longer need for converting the PLL ID.
These are all
Acked-by: Mark Brown broonie@opensource.wolfsonmicro.com
though I do generally prefer to have the IDs based off 1 as this means that we catch people just shoving 0 in as an ID when it's not appropriate.
Hi Samuel,
On Monday 04 July 2011 12:05:52 Ujfalusi, Peter wrote:
Hello,
The following series depends on the v6 of twl6040 MFD series.
The aim is to simplify the PLL handling for twl6040:
- Move the PLL selection control to the codec driver from machine driver
- Sample rate constraint simplification for selected PLL
- Avoid multiple, duplicated PLL configuration, which can slow down the
audio startup.
- Harmonize the PLL ID usage among the drivers, so we avoid redundancy.
I have generated this series on top of l-o/devel-cleanup branch + my previous twl6040 MFD/Input/ASoC v6 series, since it depends on the changes introduced there. Is it OK, if Tony will be taking this as well to avoid cross tree merge issues? I can put the series on top of my previous series, and offer Tony a pull link.
would you be able to check patch 5 in this series?
Thank you, Péter
Regards, Peter
Peter Ujfalusi (6): ASoC: twl6040: Use neutral name for power mode text/enum ASoC: twl6040: Move PLL selection to codec driver ASoC: twl6040: Simplify sample rate constraint handling ASoC: twl6040: Configure PLL only once MFD: twl6040: Remove enum for PLL tracking ASoC: twl6040: No need to convert the PLL ID
drivers/mfd/twl6040-core.c | 26 +++--- include/linux/mfd/twl6040.h | 17 ++--- sound/soc/codecs/twl6040.c | 182 ++++++++++++++++++++++--------------------- sound/soc/codecs/twl6040.h | 1 + sound/soc/omap/sdp4430.c | 47 +---------- 5 files changed, 118 insertions(+), 155 deletions(-)
participants (2)
-
Mark Brown
-
Peter Ujfalusi