[alsa-devel] [PATCH 0/5] ASoC: Component has suspend/resume support
Hi Mark, Lars-Peter
These patches add suspend/resume support on Component, and current Codec suspend/resume uses it.
Current Card has has aux_comp_list and codec_dev_list. Now, this patch will add component_dev_list. Here, we can simply replace codec_dev_list -> component_dev_list. and we can replace aux_comp_list by component_dev_list and new flags.
1), 2) : prepare for 4) 3) : add component_dev_list 4) : add Component suspend/resume
Kuninori Morimoto (4): 1) ASoC: rt286: rt286_mic_detect() uses component 2) ASoC: rt5670: rt5670_jack_suspend/resume() uses component 3) ASoC: core: add component_dev_list on Card 4) ASoC: add Component level suspend/resume
include/sound/soc.h | 16 +++++++++------- sound/soc/codecs/rt286.c | 6 +++--- sound/soc/codecs/rt286.h | 2 +- sound/soc/codecs/rt5670.c | 53 +++++++++++++++++++++++++++-------------------------- sound/soc/codecs/rt5670.h | 4 ++-- sound/soc/intel/boards/broadwell.c | 22 +++++++++++----------- sound/soc/intel/boards/cht_bsw_rt5672.c | 20 ++++++++++---------- sound/soc/intel/boards/skl_rt286.c | 2 +- sound/soc/soc-core.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------- 9 files changed, 120 insertions(+), 95 deletions(-)
Best regards --- Kuninori Morimoto
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel broadwell is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec". So, rt286_mic_detect() needs to use component instead of codec. This patch replace it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/codecs/rt286.c | 6 +++--- sound/soc/codecs/rt286.h | 2 +- sound/soc/intel/boards/broadwell.c | 6 +++--- sound/soc/intel/boards/skl_rt286.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 9c365a7..b76e978 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -305,10 +305,10 @@ static void rt286_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); }
-int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) +int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
rt286->jack = jack;
diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h index 7130edb..c63d0e7 100644 --- a/sound/soc/codecs/rt286.h +++ b/sound/soc/codecs/rt286.h @@ -199,7 +199,7 @@ enum { RT286_AIFS, };
-int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); +int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
#endif /* __RT286_H__ */
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c index 7486a00..c7ff53c 100644 --- a/sound/soc/intel/boards/broadwell.c +++ b/sound/soc/intel/boards/broadwell.c @@ -86,7 +86,7 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret;
- rt286_mic_detect(codec, &broadwell_headset); + rt286_mic_detect(&codec->component, &broadwell_headset); return 0; }
@@ -225,7 +225,7 @@ static int broadwell_suspend(struct snd_soc_card *card){ list_for_each_entry(codec, &card->codec_dev_list, card_list) { if (!strcmp(codec->component.name, "i2c-INT343A:00")) { dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n"); - rt286_mic_detect(codec, NULL); + rt286_mic_detect(&codec->component, NULL); break; } } @@ -238,7 +238,7 @@ static int broadwell_resume(struct snd_soc_card *card){ list_for_each_entry(codec, &card->codec_dev_list, card_list) { if (!strcmp(codec->component.name, "i2c-INT343A:00")) { dev_dbg(codec->dev, "enabling jack detect for resume.\n"); - rt286_mic_detect(codec, &broadwell_headset); + rt286_mic_detect(&codec->component, &broadwell_headset); break; } } diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index 88c61e8..55b704b 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c @@ -143,7 +143,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret;
- rt286_mic_detect(codec, &skylake_headset); + rt286_mic_detect(&codec->component, &skylake_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
On Fri, 21 Oct 2016 06:29:09 +0200, Kuninori Morimoto wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel broadwell is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec".
Can't it be deduced by a simple container_of()?
Takashi
On 10/24/2016 08:57 AM, Takashi Iwai wrote:
On Fri, 21 Oct 2016 06:29:09 +0200, Kuninori Morimoto wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel broadwell is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec".
Can't it be deduced by a simple container_of()?
There is the snd_soc_component_to_codec() helper for this.
Hi
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel broadwell is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec".
Can't it be deduced by a simple container_of()?
There is the snd_soc_component_to_codec() helper for this.
The points are 1) We would like to remove "codec" related functions 2) We can get "codec" pointer by above function/macro, but "codec" function/macro is using codec->component inside.
On 10/24/2016 09:43 AM, Kuninori Morimoto wrote:
Hi
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel broadwell is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec".
Can't it be deduced by a simple container_of()?
There is the snd_soc_component_to_codec() helper for this.
The points are
- We would like to remove "codec" related functions
The focus at the moment is to remove all special handling of CODECs from the ASoC core. And trying to do this without being too invasive and causing too many changes all over the place.
- We can get "codec" pointer by above function/macro, but "codec" function/macro is using codec->component inside.
That's not a problem though.
This is slightly unrelated to this series, but these drivers should not be poking the internal data structures of snd_soc_card in the first place. The best way to get the pointer to the CODEC is by using the DAI link init callback. This also means that there is no need to run a lookup each time the CODEC is needed. An alternative is to add a helper function in the core that allows to lookup a component by name.
Maybe somebody from the Intel side can look into fixing this. The affected boards are cht_bsw_rt5672 and broadwell, which both access the cards codec_dev_list field.
On Mon, Oct 24, 2016 at 11:19:17AM +0200, Lars-Peter Clausen wrote:
On 10/24/2016 09:43 AM, Kuninori Morimoto wrote:
Hi
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel broadwell is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec".
Can't it be deduced by a simple container_of()?
There is the snd_soc_component_to_codec() helper for this.
The points are
- We would like to remove "codec" related functions
The focus at the moment is to remove all special handling of CODECs from the ASoC core. And trying to do this without being too invasive and causing too many changes all over the place.
- We can get "codec" pointer by above function/macro, but "codec" function/macro is using codec->component inside.
That's not a problem though.
This is slightly unrelated to this series, but these drivers should not be poking the internal data structures of snd_soc_card in the first place. The best way to get the pointer to the CODEC is by using the DAI link init callback. This also means that there is no need to run a lookup each time the CODEC is needed. An alternative is to add a helper function in the core that allows to lookup a component by name.
Maybe somebody from the Intel side can look into fixing this. The affected boards are cht_bsw_rt5672 and broadwell, which both access the cards codec_dev_list field.
This also exists in some customer SKL machines.
I agree that this may not be best implementation so I can send a patch for this.
As Lars suggested we can use DAI link init callback, but then I dont feel it is right to use rtd->codec to get codec pointer, again we will be looking into rtd internals. So would make sense to combine two suggestion and add an API:
struct snd_soc_codec *snd_soc_get_codec(struct snd_soc_pcm_runtime *rtd) { return rtd->codec; }
then we can use this is drivers.
Let me know if all are in agreement, I can test this and send out..
Thanks
Hi Mark, Lars, Vinod
Maybe somebody from the Intel side can look into fixing this. The affected boards are cht_bsw_rt5672 and broadwell, which both access the cards codec_dev_list field.
This also exists in some customer SKL machines.
I agree that this may not be best implementation so I can send a patch for this.
As Lars suggested we can use DAI link init callback, but then I dont feel it is right to use rtd->codec to get codec pointer, again we will be looking into rtd internals. So would make sense to combine two suggestion and add an API:
struct snd_soc_codec *snd_soc_get_codec(struct snd_soc_pcm_runtime *rtd) { return rtd->codec; }
then we can use this is drivers.
Let me know if all are in agreement, I can test this and send out..
I guess my patch series should based on Vinod's new patch which doesn't use codec_dev_list ? Or can I post separately ?
Vinod, can you please Cc to me about your new patch ?
On Wed, Oct 26, 2016 at 04:48:29AM +0000, Kuninori Morimoto wrote:
Hi Mark, Lars, Vinod
Maybe somebody from the Intel side can look into fixing this. The affected boards are cht_bsw_rt5672 and broadwell, which both access the cards codec_dev_list field.
This also exists in some customer SKL machines.
I agree that this may not be best implementation so I can send a patch for this.
As Lars suggested we can use DAI link init callback, but then I dont feel it is right to use rtd->codec to get codec pointer, again we will be looking into rtd internals. So would make sense to combine two suggestion and add an API:
struct snd_soc_codec *snd_soc_get_codec(struct snd_soc_pcm_runtime *rtd) { return rtd->codec; }
then we can use this is drivers.
Let me know if all are in agreement, I can test this and send out..
I guess my patch series should based on Vinod's new patch which doesn't use codec_dev_list ? Or can I post separately ?
Vinod, can you please Cc to me about your new patch ?
Sure thing..
On 10/26/2016 05:50 AM, Vinod Koul wrote:
On Mon, Oct 24, 2016 at 11:19:17AM +0200, Lars-Peter Clausen wrote:
On 10/24/2016 09:43 AM, Kuninori Morimoto wrote:
Hi
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel broadwell is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec".
Can't it be deduced by a simple container_of()?
There is the snd_soc_component_to_codec() helper for this.
The points are
- We would like to remove "codec" related functions
The focus at the moment is to remove all special handling of CODECs from the ASoC core. And trying to do this without being too invasive and causing too many changes all over the place.
- We can get "codec" pointer by above function/macro, but "codec" function/macro is using codec->component inside.
That's not a problem though.
This is slightly unrelated to this series, but these drivers should not be poking the internal data structures of snd_soc_card in the first place. The best way to get the pointer to the CODEC is by using the DAI link init callback. This also means that there is no need to run a lookup each time the CODEC is needed. An alternative is to add a helper function in the core that allows to lookup a component by name.
Maybe somebody from the Intel side can look into fixing this. The affected boards are cht_bsw_rt5672 and broadwell, which both access the cards codec_dev_list field.
This also exists in some customer SKL machines.
I agree that this may not be best implementation so I can send a patch for this.
As Lars suggested we can use DAI link init callback, but then I dont feel it is right to use rtd->codec to get codec pointer, again we will be looking into rtd internals. So would make sense to combine two suggestion and add an API:
struct snd_soc_codec *snd_soc_get_codec(struct snd_soc_pcm_runtime *rtd) { return rtd->codec; }
I've started working on this series[1] a while ago with the intention of eventually removing the CODEC field from the rtd struct. Maybe you can use it as a base.
- Lars
[1] http://git.metafoo.de/?p=linux-2.6;a=shortlog;h=refs/heads/asoc-remove-pcm-c...
On Wed, Oct 26, 2016 at 08:56:15AM +0200, Lars-Peter Clausen wrote:
On 10/26/2016 05:50 AM, Vinod Koul wrote:
Maybe somebody from the Intel side can look into fixing this. The affected boards are cht_bsw_rt5672 and broadwell, which both access the cards codec_dev_list field.
This also exists in some customer SKL machines.
I agree that this may not be best implementation so I can send a patch for this.
As Lars suggested we can use DAI link init callback, but then I dont feel it is right to use rtd->codec to get codec pointer, again we will be looking into rtd internals. So would make sense to combine two suggestion and add an API:
struct snd_soc_codec *snd_soc_get_codec(struct snd_soc_pcm_runtime *rtd) { return rtd->codec; }
I've started working on this series[1] a while ago with the intention of eventually removing the CODEC field from the rtd struct. Maybe you can use it as a base.
Sure thing :)
On Wed, Oct 26, 2016 at 09:20:45AM +0530, Vinod Koul wrote:
into rtd internals. So would make sense to combine two suggestion and add an API:
struct snd_soc_codec *snd_soc_get_codec(struct snd_soc_pcm_runtime *rtd) { return rtd->codec; }
then we can use this is drivers.
That interface does bake in the CPU/CODEC distinction which is something we want to get away from with componentization since it makes things more complicated with situations like CODEC<->CODEC links. OTOH we're looking up a CODEC rather than a component here so it's going to need to change again anyway so it probably doesn't matter.
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Intel cht_bsw_rt5672 is using card->codec_dev_list, but it will be replaced to component list soon. Then, it will not be able to use "codec". So, rt5670_jack_suspend/resume() needs to use component instead of codec. This patch replace it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/codecs/rt5670.c | 53 +++++++++++++++++---------------- sound/soc/codecs/rt5670.h | 4 +-- sound/soc/intel/boards/cht_bsw_rt5672.c | 4 +-- 3 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 49caf13..47e3bac 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -413,46 +413,47 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg) * Returns detect status. */
-static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert) +static int rt5670_headset_detect(struct snd_soc_component *component, int jack_insert) { int val; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
if (jack_insert) { snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power"); snd_soc_dapm_sync(dapm); - snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0); - snd_soc_update_bits(codec, RT5670_CJ_CTRL2, + snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x0); + snd_soc_component_update_bits(component, RT5670_CJ_CTRL2, RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD); - snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004); - snd_soc_update_bits(codec, RT5670_GPIO_CTRL1, + snd_soc_component_write(component, RT5670_GPIO_CTRL2, 0x0004); + snd_soc_component_update_bits(component, RT5670_GPIO_CTRL1, RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ); - snd_soc_update_bits(codec, RT5670_CJ_CTRL1, + snd_soc_component_update_bits(component, RT5670_CJ_CTRL1, RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN); - snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0); - snd_soc_update_bits(codec, RT5670_CJ_CTRL2, + snd_soc_component_write(component, RT5670_JD_CTRL3, 0x00f0); + snd_soc_component_update_bits(component, RT5670_CJ_CTRL2, RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD); - snd_soc_update_bits(codec, RT5670_CJ_CTRL2, + snd_soc_component_update_bits(component, RT5670_CJ_CTRL2, RT5670_CBJ_MN_JD, 0); msleep(300); - val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7; + snd_soc_component_read(component, RT5670_CJ_CTRL3, &val); + val &= 0x7; if (val == 0x1 || val == 0x2) { rt5670->jack_type = SND_JACK_HEADSET; /* for push button */ - snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8); - snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40); - snd_soc_read(codec, RT5670_IL_CMD); + snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x8); + snd_soc_component_update_bits(component, RT5670_IL_CMD, 0x40, 0x40); + snd_soc_component_read(component, RT5670_IL_CMD, &val); } else { - snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4); + snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4); rt5670->jack_type = SND_JACK_HEADPHONE; snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); snd_soc_dapm_sync(dapm); } } else { - snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0); - snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4); + snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x0); + snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4); rt5670->jack_type = 0; snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); snd_soc_dapm_sync(dapm); @@ -461,21 +462,21 @@ static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert) return rt5670->jack_type; }
-void rt5670_jack_suspend(struct snd_soc_codec *codec) +void rt5670_jack_suspend(struct snd_soc_component *component) { - struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); + struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
rt5670->jack_type_saved = rt5670->jack_type; - rt5670_headset_detect(codec, 0); + rt5670_headset_detect(component, 0); } EXPORT_SYMBOL_GPL(rt5670_jack_suspend);
-void rt5670_jack_resume(struct snd_soc_codec *codec) +void rt5670_jack_resume(struct snd_soc_component *component) { - struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); + struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
if (rt5670->jack_type_saved) - rt5670_headset_detect(codec, 1); + rt5670_headset_detect(component, 1); } EXPORT_SYMBOL_GPL(rt5670_jack_resume);
@@ -512,7 +513,7 @@ static int rt5670_irq_detection(void *data) case 0x30: /* 2 port */ case 0x0: /* 1 port or 2 port */ if (rt5670->jack_type == 0) { - report = rt5670_headset_detect(rt5670->codec, 1); + report = rt5670_headset_detect(&rt5670->codec->component, 1); /* for push button and jack out */ gpio->debounce_time = 25; break; @@ -549,7 +550,7 @@ static int rt5670_irq_detection(void *data) case 0x20: /* 1 port */ report = 0; snd_soc_update_bits(rt5670->codec, RT5670_INT_IRQ_ST, 0x1, 0x0); - rt5670_headset_detect(rt5670->codec, 0); + rt5670_headset_detect(&rt5670->codec->component, 0); gpio->debounce_time = 150; /* for jack in */ break; default: diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h index 3f1b0f1..132b151 100644 --- a/sound/soc/codecs/rt5670.h +++ b/sound/soc/codecs/rt5670.h @@ -2007,8 +2007,8 @@ struct rt5670_priv { int jack_type_saved; };
-void rt5670_jack_suspend(struct snd_soc_codec *codec); -void rt5670_jack_resume(struct snd_soc_codec *codec); +void rt5670_jack_suspend(struct snd_soc_component *component); +void rt5670_jack_resume(struct snd_soc_component *component); int rt5670_set_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); #endif /* __RT5670_H__ */ diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index df9d254..5bc8ab4 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -297,7 +297,7 @@ static int cht_suspend_pre(struct snd_soc_card *card) list_for_each_entry(codec, &card->codec_dev_list, card_list) { if (!strcmp(codec->component.name, "i2c-10EC5670:00")) { dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n"); - rt5670_jack_suspend(codec); + rt5670_jack_suspend(&codec->component); break; } } @@ -311,7 +311,7 @@ static int cht_resume_post(struct snd_soc_card *card) list_for_each_entry(codec, &card->codec_dev_list, card_list) { if (!strcmp(codec->component.name, "i2c-10EC5670:00")) { dev_dbg(codec->dev, "enabling jack detect for resume.\n"); - rt5670_jack_resume(codec); + rt5670_jack_resume(&codec->component); break; } }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current Card has Codec list (= codec_dev_list), but Codec will be removed in the future. Because of this reason, this patch adds new Component list in Card. In the same time, current Card has AUX list (= aux_comp_list). This patch replaces it by Component list and new flag (= has_auxliary) too
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 7 ++++--- sound/soc/soc-core.c | 21 ++++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 4f1c784..e96affa 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -807,9 +807,10 @@ struct snd_soc_component {
unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ unsigned int registered_as_component:1; + unsigned int has_auxiliary:1; /* for auxiliary component of the card */
struct list_head list; - struct list_head list_aux; /* for auxiliary component of the card */ + struct list_head card_list;
struct snd_soc_dai_driver *dai_drv; int num_dai; @@ -1148,7 +1149,6 @@ struct snd_soc_card { */ struct snd_soc_aux_dev *aux_dev; int num_aux_devs; - struct list_head aux_comp_list;
const struct snd_kcontrol_new *controls; int num_controls; @@ -1171,6 +1171,7 @@ struct snd_soc_card {
/* lists of probed devices belonging to this card */ struct list_head codec_dev_list; + struct list_head component_dev_list;
struct list_head widgets; struct list_head paths; @@ -1545,7 +1546,7 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) INIT_LIST_HEAD(&card->widgets); INIT_LIST_HEAD(&card->paths); INIT_LIST_HEAD(&card->dapm_list); - INIT_LIST_HEAD(&card->aux_comp_list); + INIT_LIST_HEAD(&card->component_dev_list); }
static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c0bbcd9..2a00b5e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1076,6 +1076,8 @@ static void soc_remove_component(struct snd_soc_component *component) if (component->codec) list_del(&component->codec->card_list);
+ list_del(&component->card_list); + if (component->remove) component->remove(component);
@@ -1448,6 +1450,8 @@ static int soc_probe_component(struct snd_soc_card *card, if (component->codec) list_add(&component->codec->card_list, &card->codec_dev_list);
+ list_add(&component->card_list, &card->component_dev_list); + return 0;
err_probe: @@ -1706,7 +1710,8 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num) }
component->init = aux_dev->init; - list_add(&component->list_aux, &card->aux_comp_list); + component->has_auxiliary = 1; + return 0;
err_defer: @@ -1722,7 +1727,10 @@ static int soc_probe_aux_devices(struct snd_soc_card *card)
for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; order++) { - list_for_each_entry(comp, &card->aux_comp_list, list_aux) { + list_for_each_entry(comp, &card->component_dev_list, card_list) { + if (!comp->has_auxiliary) + continue; + if (comp->driver->probe_order == order) { ret = soc_probe_component(card, comp); if (ret < 0) { @@ -1746,11 +1754,14 @@ static void soc_remove_aux_devices(struct snd_soc_card *card) for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; order++) { list_for_each_entry_safe(comp, _comp, - &card->aux_comp_list, list_aux) { + &card->component_dev_list, card_list) { + + if (!comp->has_auxiliary) + continue; + if (comp->driver->remove_order == order) { soc_remove_component(comp); - /* remove it from the card's aux_comp_list */ - list_del(&comp->list_aux); + comp->has_auxiliary = 0; } } }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
In current ALSA SoC, Codec only has suspend/resume feature. But it should be supported on Component level. This patch adds it. This patch replaces current codec_dev_list to component_dev_list. Current Codec suspend/resume will use Component one now.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 9 ++-- sound/soc/intel/boards/broadwell.c | 20 ++++----- sound/soc/intel/boards/cht_bsw_rt5672.c | 20 ++++----- sound/soc/soc-core.c | 73 +++++++++++++++++++-------------- 4 files changed, 67 insertions(+), 55 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index e96affa..a1b65b2 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -782,6 +782,8 @@ struct snd_soc_component_driver {
int (*probe)(struct snd_soc_component *); void (*remove)(struct snd_soc_component *); + int (*suspend)(struct snd_soc_component *); + int (*resume)(struct snd_soc_component *);
/* DT */ int (*of_xlate_dai_name)(struct snd_soc_component *component, @@ -808,6 +810,7 @@ struct snd_soc_component { unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ unsigned int registered_as_component:1; unsigned int has_auxiliary:1; /* for auxiliary component of the card */ + unsigned int suspended:1; /* is in suspend PM state */
struct list_head list; struct list_head card_list; @@ -853,6 +856,8 @@ struct snd_soc_component {
int (*probe)(struct snd_soc_component *); void (*remove)(struct snd_soc_component *); + int (*suspend)(struct snd_soc_component *); + int (*resume)(struct snd_soc_component *);
/* machine specific init */ int (*init)(struct snd_soc_component *component); @@ -869,11 +874,9 @@ struct snd_soc_codec { const struct snd_soc_codec_driver *driver;
struct list_head list; - struct list_head card_list;
/* runtime */ unsigned int cache_bypass:1; /* Suppress access to the cache */ - unsigned int suspended:1; /* Codec is in suspend PM state */ unsigned int cache_init:1; /* codec cache has been initialized */
/* codec IO */ @@ -1170,7 +1173,6 @@ struct snd_soc_card { struct work_struct deferred_resume_work;
/* lists of probed devices belonging to this card */ - struct list_head codec_dev_list; struct list_head component_dev_list;
struct list_head widgets; @@ -1542,7 +1544,6 @@ static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platfo
static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) { - INIT_LIST_HEAD(&card->codec_dev_list); INIT_LIST_HEAD(&card->widgets); INIT_LIST_HEAD(&card->paths); INIT_LIST_HEAD(&card->dapm_list); diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c index c7ff53c..6f5aedb 100644 --- a/sound/soc/intel/boards/broadwell.c +++ b/sound/soc/intel/boards/broadwell.c @@ -220,12 +220,12 @@ static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) };
static int broadwell_suspend(struct snd_soc_card *card){ - struct snd_soc_codec *codec; + struct snd_soc_component *component;
- list_for_each_entry(codec, &card->codec_dev_list, card_list) { - if (!strcmp(codec->component.name, "i2c-INT343A:00")) { - dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n"); - rt286_mic_detect(&codec->component, NULL); + list_for_each_entry(component, &card->component_dev_list, card_list) { + if (!strcmp(component->name, "i2c-INT343A:00")) { + dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); + rt286_mic_detect(component, NULL); break; } } @@ -233,12 +233,12 @@ static int broadwell_suspend(struct snd_soc_card *card){ }
static int broadwell_resume(struct snd_soc_card *card){ - struct snd_soc_codec *codec; + struct snd_soc_component *component;
- list_for_each_entry(codec, &card->codec_dev_list, card_list) { - if (!strcmp(codec->component.name, "i2c-INT343A:00")) { - dev_dbg(codec->dev, "enabling jack detect for resume.\n"); - rt286_mic_detect(&codec->component, &broadwell_headset); + list_for_each_entry(component, &card->component_dev_list, card_list) { + if (!strcmp(component->name, "i2c-INT343A:00")) { + dev_dbg(component->dev, "enabling jack detect for resume.\n"); + rt286_mic_detect(component, &broadwell_headset); break; } } diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index 5bc8ab4..ec21e58 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -292,12 +292,12 @@ static int cht_aif1_startup(struct snd_pcm_substream *substream)
static int cht_suspend_pre(struct snd_soc_card *card) { - struct snd_soc_codec *codec; + struct snd_soc_component *component;
- list_for_each_entry(codec, &card->codec_dev_list, card_list) { - if (!strcmp(codec->component.name, "i2c-10EC5670:00")) { - dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n"); - rt5670_jack_suspend(&codec->component); + list_for_each_entry(component, &card->component_dev_list, card_list) { + if (!strcmp(component->name, "i2c-10EC5670:00")) { + dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); + rt5670_jack_suspend(component); break; } } @@ -306,12 +306,12 @@ static int cht_suspend_pre(struct snd_soc_card *card)
static int cht_resume_post(struct snd_soc_card *card) { - struct snd_soc_codec *codec; + struct snd_soc_component *component;
- list_for_each_entry(codec, &card->codec_dev_list, card_list) { - if (!strcmp(codec->component.name, "i2c-10EC5670:00")) { - dev_dbg(codec->dev, "enabling jack detect for resume.\n"); - rt5670_jack_resume(&codec->component); + list_for_each_entry(component, &card->component_dev_list, card_list) { + if (!strcmp(component->name, "i2c-10EC5670:00")) { + dev_dbg(component->dev, "enabling jack detect for resume.\n"); + rt5670_jack_resume(component); break; } } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2a00b5e..41e70f1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -626,7 +626,7 @@ static void codec2codec_close_delayed_work(struct work_struct *work) int snd_soc_suspend(struct device *dev) { struct snd_soc_card *card = dev_get_drvdata(dev); - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct snd_soc_pcm_runtime *rtd; int i;
@@ -702,39 +702,39 @@ int snd_soc_suspend(struct device *dev) dapm_mark_endpoints_dirty(card); snd_soc_dapm_sync(&card->dapm);
- /* suspend all CODECs */ - list_for_each_entry(codec, &card->codec_dev_list, card_list) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + /* suspend all COMPONENTs */ + list_for_each_entry(component, &card->component_dev_list, card_list) { + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
- /* If there are paths active then the CODEC will be held with + /* If there are paths active then the COMPONENT will be held with * bias _ON and should not be suspended. */ - if (!codec->suspended) { + if (!component->suspended) { switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_STANDBY: /* - * If the CODEC is capable of idle + * If the COMPONENT is capable of idle * bias off then being in STANDBY * means it's doing something, * otherwise fall through. */ if (dapm->idle_bias_off) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "ASoC: idle_bias_off CODEC on over suspend\n"); break; }
case SND_SOC_BIAS_OFF: - if (codec->driver->suspend) - codec->driver->suspend(codec); - codec->suspended = 1; - if (codec->component.regmap) - regcache_mark_dirty(codec->component.regmap); + if (component->suspend) + component->suspend(component); + component->suspended = 1; + if (component->regmap) + regcache_mark_dirty(component->regmap); /* deactivate pins to sleep state */ - pinctrl_pm_select_sleep_state(codec->dev); + pinctrl_pm_select_sleep_state(component->dev); break; default: - dev_dbg(codec->dev, - "ASoC: CODEC is on over suspend\n"); + dev_dbg(component->dev, + "ASoC: COMPONENT is on over suspend\n"); break; } } @@ -768,7 +768,7 @@ static void soc_resume_deferred(struct work_struct *work) struct snd_soc_card *card = container_of(work, struct snd_soc_card, deferred_resume_work); struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int i;
/* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, @@ -794,11 +794,11 @@ static void soc_resume_deferred(struct work_struct *work) cpu_dai->driver->resume(cpu_dai); }
- list_for_each_entry(codec, &card->codec_dev_list, card_list) { - if (codec->suspended) { - if (codec->driver->resume) - codec->driver->resume(codec); - codec->suspended = 0; + list_for_each_entry(component, &card->component_dev_list, card_list) { + if (component->suspended) { + if (component->resume) + component->resume(component); + component->suspended = 0; } }
@@ -1072,10 +1072,6 @@ static void soc_remove_component(struct snd_soc_component *component) if (!component->card) return;
- /* This is a HACK and will be removed soon */ - if (component->codec) - list_del(&component->codec->card_list); - list_del(&component->card_list);
if (component->remove) @@ -1445,11 +1441,6 @@ static int soc_probe_component(struct snd_soc_card *card, component->num_dapm_routes);
list_add(&dapm->list, &card->dapm_list); - - /* This is a HACK and will be removed soon */ - if (component->codec) - list_add(&component->codec->card_list, &card->codec_dev_list); - list_add(&component->card_list, &card->component_dev_list);
return 0; @@ -2937,6 +2928,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, component->driver = driver; component->probe = component->driver->probe; component->remove = component->driver->remove; + component->suspend = component->driver->suspend; + component->resume = component->driver->resume;
dapm = &component->dapm; dapm->dev = dev; @@ -3286,6 +3279,20 @@ static void snd_soc_codec_drv_remove(struct snd_soc_component *component) codec->driver->remove(codec); }
+static int snd_soc_codec_drv_suspend(struct snd_soc_component *component) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return codec->driver->suspend(codec); +} + +static int snd_soc_codec_drv_resume(struct snd_soc_component *component) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return codec->driver->resume(codec); +} + static int snd_soc_codec_drv_write(struct snd_soc_component *component, unsigned int reg, unsigned int val) { @@ -3347,6 +3354,10 @@ int snd_soc_register_codec(struct device *dev, codec->component.probe = snd_soc_codec_drv_probe; if (codec_drv->remove) codec->component.remove = snd_soc_codec_drv_remove; + if (codec_drv->suspend) + codec->component.suspend = snd_soc_codec_drv_suspend; + if (codec_drv->resume) + codec->component.resume = snd_soc_codec_drv_resume; if (codec_drv->write) codec->component.write = snd_soc_codec_drv_write; if (codec_drv->read)
participants (5)
-
Kuninori Morimoto
-
Lars-Peter Clausen
-
Mark Brown
-
Takashi Iwai
-
Vinod Koul