diff mbox

[RFC,19/19] ASoC: Intel: mrfld: add the DSP mixers

Message ID 1402662848-24534-20-git-send-email-vinod.koul@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vinod Koul June 13, 2014, 12:34 p.m. UTC
The is RFC patch for adding the platform mixer controls. This requires the
dapm_set-get to be exported. Or changes required after component series is
merged

Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 sound/soc/intel/sst-atom-controls.c |   67 +++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

Comments

Lars-Peter Clausen June 14, 2014, 3:39 p.m. UTC | #1
On 06/13/2014 02:34 PM, Vinod Koul wrote:
> The is RFC patch for adding the platform mixer controls. This requires the
> dapm_set-get to be exported. Or changes required after component series is
> merged

You are not using dapm_kcontrol_get_value() in this patch and without that 
calling dapm_kcontrol_set_value() is pretty pointless as the value is never 
read again. But it is still a good idea to use the generic controls rather 
than having a custom copy&pasted version.

>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
>   sound/soc/intel/sst-atom-controls.c |   67 +++++++++++++++++++++++++++++++++++
>   1 files changed, 67 insertions(+), 0 deletions(-)
>
> diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c
> index 2e733f8..81a24eb 100644
> --- a/sound/soc/intel/sst-atom-controls.c
> +++ b/sound/soc/intel/sst-atom-controls.c
> @@ -66,6 +66,47 @@ unsigned int sst_reg_write(struct sst_data *drv, unsigned int reg,
>   	return val;
>   }
>
> +int sst_mix_put(struct snd_kcontrol *kcontrol,
> +	struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_dapm_widget_list *wlist;// = dapm_kcontrol_get_wlist(kcontrol);
> +	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
> +	struct soc_mixer_control *mc =
> +		(struct soc_mixer_control *)kcontrol->private_value;
> +	struct sst_data *drv = snd_soc_platform_get_drvdata(widget->platform);
> +	unsigned int mask = (1 << fls(mc->max)) - 1;
> +	unsigned int val;
> +	int connect;
> +	struct snd_soc_dapm_update update;
> +
> +	pr_debug("%s called set %#lx for %s\n", __func__,
> +			ucontrol->value.integer.value[0], widget->name);
> +	val = sst_reg_write(drv, mc->reg, mc->shift, mc->max, ucontrol->value.integer.value[0]);
> +	connect = !!val;
> +
> +	//dapm_kcontrol_set_value(kcontrol, val);
> +	update.kcontrol = kcontrol;
> +	update.reg = mc->reg;
> +	update.mask = mask;
> +	update.val = val;
> +
> +	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, connect, &update);
> +	return 0;
> +}
> +
> +int sst_mix_get(struct snd_kcontrol *kcontrol,
> +		struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_dapm_widget_list *wlist;// = dapm_kcontrol_get_wlist(kcontrol);
> +	struct snd_soc_dapm_widget *w = wlist->widgets[0];
> +	struct soc_mixer_control *mc =
> +		(struct soc_mixer_control *)kcontrol->private_value;
> +	struct sst_data *drv = snd_soc_platform_get_drvdata(w->platform);
> +
> +	ucontrol->value.integer.value[0] = !!sst_reg_read(drv, mc->reg, mc->shift, mc->max);
> +	return 0;
> +}
> +
>   static inline void sst_fill_byte_control(char *param,
>   					 u8 ipc_msg, u8 block,
>   					 u8 task_id, u8 pipe_id,
> @@ -937,6 +978,32 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
>   	SST_PATH_MEDIA_LOOP_OUTPUT("media_loop2_out", SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP2, SST_FMT_STEREO, sst_set_media_loop),
>
>   	/* Media Mixers */
> +	SST_SWM_MIXER("media0_out mix 0", SST_MIX_MEDIA0, SST_TASK_MMX, SST_SWM_OUT_MEDIA0,
> +		      sst_mix_media0_controls, sst_swm_mixer_event),
> +	SST_SWM_MIXER("media1_out mix 0", SST_MIX_MEDIA1, SST_TASK_MMX, SST_SWM_OUT_MEDIA1,
> +		      sst_mix_media1_controls, sst_swm_mixer_event),
> +
> +	/* SBA PCM mixers */
> +	SST_SWM_MIXER("pcm0_out mix 0", SST_MIX_PCM0, SST_TASK_SBA, SST_SWM_OUT_PCM0,
> +		      sst_mix_pcm0_controls, sst_swm_mixer_event),
> +	SST_SWM_MIXER("pcm1_out mix 0", SST_MIX_PCM1, SST_TASK_SBA, SST_SWM_OUT_PCM1,
> +		      sst_mix_pcm1_controls, sst_swm_mixer_event),
> +	SST_SWM_MIXER("pcm2_out mix 0", SST_MIX_PCM2, SST_TASK_SBA, SST_SWM_OUT_PCM2,
> +		      sst_mix_pcm2_controls, sst_swm_mixer_event),
> +
> +	/* SBA Loop mixers */
> +	SST_SWM_MIXER("sprot_loop_out mix 0", SST_MIX_LOOP0, SST_TASK_SBA, SST_SWM_OUT_SPROT_LOOP,
> +		      sst_mix_sprot_l0_controls, sst_swm_mixer_event),
> +	SST_SWM_MIXER("media_loop1_out mix 0", SST_MIX_LOOP1, SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP1,
> +		      sst_mix_media_l1_controls, sst_swm_mixer_event),
> +	SST_SWM_MIXER("media_loop2_out mix 0", SST_MIX_LOOP2, SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP2,
> +		      sst_mix_media_l2_controls, sst_swm_mixer_event),
> +
> +	/* SBA Backend mixers */
> +	SST_SWM_MIXER("codec_out0 mix 0", SST_MIX_CODEC0, SST_TASK_SBA, SST_SWM_OUT_CODEC0,
> +		      sst_mix_codec0_controls, sst_swm_mixer_event),
> +	SST_SWM_MIXER("codec_out1 mix 0", SST_MIX_CODEC1, SST_TASK_SBA, SST_SWM_OUT_CODEC1,
> +		      sst_mix_codec1_controls, sst_swm_mixer_event),
>   };
>
>   static const struct snd_soc_dapm_route intercon[] = {
>
Vinod Koul July 4, 2014, 4:46 a.m. UTC | #2
On Sat, Jun 14, 2014 at 05:39:09PM +0200, Lars-Peter Clausen wrote:
> On 06/13/2014 02:34 PM, Vinod Koul wrote:
> >The is RFC patch for adding the platform mixer controls. This requires the
> >dapm_set-get to be exported. Or changes required after component series is
> >merged
> 
> You are not using dapm_kcontrol_get_value() in this patch and
> without that calling dapm_kcontrol_set_value() is pretty pointless
> as the value is never read again. But it is still a good idea to use
> the generic controls rather than having a custom copy&pasted
> version.

Hey Lars,

Circling back on this one..

We tried implementing based on the feedback. One question though remains.

We were able to remove the get/put widget handlers. Now only the callback is
present. With this when widget is powered up for a mixer, we need to know the value
of the mixer so that we can inform DSP using IPC.

Now potentially looks like we should be able to remove the register file as well,
but only problem would be how to get the mixer control value (how many and which
inputs are on/off and tell DSP). This would need me to export the dapm_get
function, is that approach fine, or do we have any other way to get the value of
this in driver.
Lars-Peter Clausen July 4, 2014, 11:21 a.m. UTC | #3
On 07/04/2014 06:46 AM, Vinod Koul wrote:
> On Sat, Jun 14, 2014 at 05:39:09PM +0200, Lars-Peter Clausen wrote:
>> On 06/13/2014 02:34 PM, Vinod Koul wrote:
>>> The is RFC patch for adding the platform mixer controls. This requires the
>>> dapm_set-get to be exported. Or changes required after component series is
>>> merged
>>
>> You are not using dapm_kcontrol_get_value() in this patch and
>> without that calling dapm_kcontrol_set_value() is pretty pointless
>> as the value is never read again. But it is still a good idea to use
>> the generic controls rather than having a custom copy&pasted
>> version.
>
> Hey Lars,
>
> Circling back on this one..
>
> We tried implementing based on the feedback. One question though remains.
>
> We were able to remove the get/put widget handlers. Now only the callback is
> present. With this when widget is powered up for a mixer, we need to know the value
> of the mixer so that we can inform DSP using IPC.
>
> Now potentially looks like we should be able to remove the register file as well,
> but only problem would be how to get the mixer control value (how many and which
> inputs are on/off and tell DSP). This would need me to export the dapm_get
> function, is that approach fine, or do we have any other way to get the value of
> this in driver.

I think it should be fine, if I correctly understand what you want to do. 
The main issue with all of this is that DAPM internally is very much 
tailored towards registers IO based systems. And using it for IPC is a bit 
bumpy. You can do it but the implementation is not always nice. DAPM could 
probably be adopted to better support non register IO based systems, but 
that would require a bit of effort.

- Lars
Vinod Koul July 7, 2014, 8:45 a.m. UTC | #4
On Fri, Jul 04, 2014 at 01:21:17PM +0200, Lars-Peter Clausen wrote:
> On 07/04/2014 06:46 AM, Vinod Koul wrote:
> >On Sat, Jun 14, 2014 at 05:39:09PM +0200, Lars-Peter Clausen wrote:
> >>On 06/13/2014 02:34 PM, Vinod Koul wrote:
> >>>The is RFC patch for adding the platform mixer controls. This requires the
> >>>dapm_set-get to be exported. Or changes required after component series is
> >>>merged
> >>
> >>You are not using dapm_kcontrol_get_value() in this patch and
> >>without that calling dapm_kcontrol_set_value() is pretty pointless
> >>as the value is never read again. But it is still a good idea to use
> >>the generic controls rather than having a custom copy&pasted
> >>version.
> >
> >Hey Lars,
> >
> >Circling back on this one..
> >
> >We tried implementing based on the feedback. One question though remains.
> >
> >We were able to remove the get/put widget handlers. Now only the callback is
> >present. With this when widget is powered up for a mixer, we need to know the value
> >of the mixer so that we can inform DSP using IPC.
> >
> >Now potentially looks like we should be able to remove the register file as well,
> >but only problem would be how to get the mixer control value (how many and which
> >inputs are on/off and tell DSP). This would need me to export the dapm_get
> >function, is that approach fine, or do we have any other way to get the value of
> >this in driver.
> 
> I think it should be fine, if I correctly understand what you want
> to do. The main issue with all of this is that DAPM internally is
> very much tailored towards registers IO based systems. And using it
> for IPC is a bit bumpy. You can do it but the implementation is not
> always nice. DAPM could probably be adopted to better support non
> register IO based systems, but that would require a bit of effort.

For now with this we are removing most of register code. Am optimistic right now
that we can get it to work... Stay tuned :)
diff mbox

Patch

diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c
index 2e733f8..81a24eb 100644
--- a/sound/soc/intel/sst-atom-controls.c
+++ b/sound/soc/intel/sst-atom-controls.c
@@ -66,6 +66,47 @@  unsigned int sst_reg_write(struct sst_data *drv, unsigned int reg,
 	return val;
 }
 
+int sst_mix_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist;// = dapm_kcontrol_get_wlist(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct sst_data *drv = snd_soc_platform_get_drvdata(widget->platform);
+	unsigned int mask = (1 << fls(mc->max)) - 1;
+	unsigned int val;
+	int connect;
+	struct snd_soc_dapm_update update;
+
+	pr_debug("%s called set %#lx for %s\n", __func__,
+			ucontrol->value.integer.value[0], widget->name);
+	val = sst_reg_write(drv, mc->reg, mc->shift, mc->max, ucontrol->value.integer.value[0]);
+	connect = !!val;
+
+	//dapm_kcontrol_set_value(kcontrol, val);
+	update.kcontrol = kcontrol;
+	update.reg = mc->reg;
+	update.mask = mask;
+	update.val = val;
+
+	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, connect, &update);
+	return 0;
+}
+
+int sst_mix_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist;// = dapm_kcontrol_get_wlist(kcontrol);
+	struct snd_soc_dapm_widget *w = wlist->widgets[0];
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct sst_data *drv = snd_soc_platform_get_drvdata(w->platform);
+
+	ucontrol->value.integer.value[0] = !!sst_reg_read(drv, mc->reg, mc->shift, mc->max);
+	return 0;
+}
+
 static inline void sst_fill_byte_control(char *param,
 					 u8 ipc_msg, u8 block,
 					 u8 task_id, u8 pipe_id,
@@ -937,6 +978,32 @@  static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
 	SST_PATH_MEDIA_LOOP_OUTPUT("media_loop2_out", SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP2, SST_FMT_STEREO, sst_set_media_loop),
 
 	/* Media Mixers */
+	SST_SWM_MIXER("media0_out mix 0", SST_MIX_MEDIA0, SST_TASK_MMX, SST_SWM_OUT_MEDIA0,
+		      sst_mix_media0_controls, sst_swm_mixer_event),
+	SST_SWM_MIXER("media1_out mix 0", SST_MIX_MEDIA1, SST_TASK_MMX, SST_SWM_OUT_MEDIA1,
+		      sst_mix_media1_controls, sst_swm_mixer_event),
+
+	/* SBA PCM mixers */
+	SST_SWM_MIXER("pcm0_out mix 0", SST_MIX_PCM0, SST_TASK_SBA, SST_SWM_OUT_PCM0,
+		      sst_mix_pcm0_controls, sst_swm_mixer_event),
+	SST_SWM_MIXER("pcm1_out mix 0", SST_MIX_PCM1, SST_TASK_SBA, SST_SWM_OUT_PCM1,
+		      sst_mix_pcm1_controls, sst_swm_mixer_event),
+	SST_SWM_MIXER("pcm2_out mix 0", SST_MIX_PCM2, SST_TASK_SBA, SST_SWM_OUT_PCM2,
+		      sst_mix_pcm2_controls, sst_swm_mixer_event),
+
+	/* SBA Loop mixers */
+	SST_SWM_MIXER("sprot_loop_out mix 0", SST_MIX_LOOP0, SST_TASK_SBA, SST_SWM_OUT_SPROT_LOOP,
+		      sst_mix_sprot_l0_controls, sst_swm_mixer_event),
+	SST_SWM_MIXER("media_loop1_out mix 0", SST_MIX_LOOP1, SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP1,
+		      sst_mix_media_l1_controls, sst_swm_mixer_event),
+	SST_SWM_MIXER("media_loop2_out mix 0", SST_MIX_LOOP2, SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP2,
+		      sst_mix_media_l2_controls, sst_swm_mixer_event),
+
+	/* SBA Backend mixers */
+	SST_SWM_MIXER("codec_out0 mix 0", SST_MIX_CODEC0, SST_TASK_SBA, SST_SWM_OUT_CODEC0,
+		      sst_mix_codec0_controls, sst_swm_mixer_event),
+	SST_SWM_MIXER("codec_out1 mix 0", SST_MIX_CODEC1, SST_TASK_SBA, SST_SWM_OUT_CODEC1,
+		      sst_mix_codec1_controls, sst_swm_mixer_event),
 };
 
 static const struct snd_soc_dapm_route intercon[] = {