1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
6 // Copyright(c) 2018 Intel Corporation. All rights reserved.
8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
13 #include <linux/pm_runtime.h>
14 #include <linux/leds.h>
16 #include "sof-audio.h"
18 static void update_mute_led(struct snd_sof_control
*scontrol
,
19 struct snd_kcontrol
*kcontrol
,
20 struct snd_ctl_elem_value
*ucontrol
)
26 mask
= 1U << snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
28 for (i
= 0; i
< scontrol
->num_channels
; i
++) {
29 if (ucontrol
->value
.integer
.value
[i
]) {
35 if (temp
== scontrol
->led_ctl
.led_value
)
38 scontrol
->led_ctl
.led_value
= temp
;
40 #if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
41 if (!scontrol
->led_ctl
.direction
)
42 ledtrig_audio_set(LED_AUDIO_MUTE
, temp
? LED_OFF
: LED_ON
);
44 ledtrig_audio_set(LED_AUDIO_MICMUTE
, temp
? LED_OFF
: LED_ON
);
48 static inline u32
mixer_to_ipc(unsigned int value
, u32
*volume_map
, int size
)
51 return volume_map
[size
- 1];
53 return volume_map
[value
];
56 static inline u32
ipc_to_mixer(u32 value
, u32
*volume_map
, int size
)
60 for (i
= 0; i
< size
; i
++) {
61 if (volume_map
[i
] >= value
)
68 int snd_sof_volume_get(struct snd_kcontrol
*kcontrol
,
69 struct snd_ctl_elem_value
*ucontrol
)
71 struct soc_mixer_control
*sm
=
72 (struct soc_mixer_control
*)kcontrol
->private_value
;
73 struct snd_sof_control
*scontrol
= sm
->dobj
.private;
74 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
75 unsigned int i
, channels
= scontrol
->num_channels
;
77 /* read back each channel */
78 for (i
= 0; i
< channels
; i
++)
79 ucontrol
->value
.integer
.value
[i
] =
80 ipc_to_mixer(cdata
->chanv
[i
].value
,
81 scontrol
->volume_table
, sm
->max
+ 1);
86 int snd_sof_volume_put(struct snd_kcontrol
*kcontrol
,
87 struct snd_ctl_elem_value
*ucontrol
)
89 struct soc_mixer_control
*sm
=
90 (struct soc_mixer_control
*)kcontrol
->private_value
;
91 struct snd_sof_control
*scontrol
= sm
->dobj
.private;
92 struct snd_soc_component
*scomp
= scontrol
->scomp
;
93 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
94 unsigned int i
, channels
= scontrol
->num_channels
;
98 /* update each channel */
99 for (i
= 0; i
< channels
; i
++) {
100 value
= mixer_to_ipc(ucontrol
->value
.integer
.value
[i
],
101 scontrol
->volume_table
, sm
->max
+ 1);
102 change
= change
|| (value
!= cdata
->chanv
[i
].value
);
103 cdata
->chanv
[i
].channel
= i
;
104 cdata
->chanv
[i
].value
= value
;
107 /* notify DSP of mixer updates */
108 if (pm_runtime_active(scomp
->dev
))
109 snd_sof_ipc_set_get_comp_data(scontrol
,
110 SOF_IPC_COMP_SET_VALUE
,
111 SOF_CTRL_TYPE_VALUE_CHAN_GET
,
117 int snd_sof_volume_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
119 struct soc_mixer_control
*sm
= (struct soc_mixer_control
*)kcontrol
->private_value
;
120 struct snd_sof_control
*scontrol
= sm
->dobj
.private;
121 unsigned int channels
= scontrol
->num_channels
;
124 if (!sm
->platform_max
)
125 sm
->platform_max
= sm
->max
;
126 platform_max
= sm
->platform_max
;
128 if (platform_max
== 1 && !strstr(kcontrol
->id
.name
, " Volume"))
129 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
131 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
133 uinfo
->count
= channels
;
134 uinfo
->value
.integer
.min
= 0;
135 uinfo
->value
.integer
.max
= platform_max
- sm
->min
;
139 int snd_sof_switch_get(struct snd_kcontrol
*kcontrol
,
140 struct snd_ctl_elem_value
*ucontrol
)
142 struct soc_mixer_control
*sm
=
143 (struct soc_mixer_control
*)kcontrol
->private_value
;
144 struct snd_sof_control
*scontrol
= sm
->dobj
.private;
145 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
146 unsigned int i
, channels
= scontrol
->num_channels
;
148 /* read back each channel */
149 for (i
= 0; i
< channels
; i
++)
150 ucontrol
->value
.integer
.value
[i
] = cdata
->chanv
[i
].value
;
155 int snd_sof_switch_put(struct snd_kcontrol
*kcontrol
,
156 struct snd_ctl_elem_value
*ucontrol
)
158 struct soc_mixer_control
*sm
=
159 (struct soc_mixer_control
*)kcontrol
->private_value
;
160 struct snd_sof_control
*scontrol
= sm
->dobj
.private;
161 struct snd_soc_component
*scomp
= scontrol
->scomp
;
162 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
163 unsigned int i
, channels
= scontrol
->num_channels
;
167 /* update each channel */
168 for (i
= 0; i
< channels
; i
++) {
169 value
= ucontrol
->value
.integer
.value
[i
];
170 change
= change
|| (value
!= cdata
->chanv
[i
].value
);
171 cdata
->chanv
[i
].channel
= i
;
172 cdata
->chanv
[i
].value
= value
;
175 if (scontrol
->led_ctl
.use_led
)
176 update_mute_led(scontrol
, kcontrol
, ucontrol
);
178 /* notify DSP of mixer updates */
179 if (pm_runtime_active(scomp
->dev
))
180 snd_sof_ipc_set_get_comp_data(scontrol
,
181 SOF_IPC_COMP_SET_VALUE
,
182 SOF_CTRL_TYPE_VALUE_CHAN_GET
,
189 int snd_sof_enum_get(struct snd_kcontrol
*kcontrol
,
190 struct snd_ctl_elem_value
*ucontrol
)
192 struct soc_enum
*se
=
193 (struct soc_enum
*)kcontrol
->private_value
;
194 struct snd_sof_control
*scontrol
= se
->dobj
.private;
195 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
196 unsigned int i
, channels
= scontrol
->num_channels
;
198 /* read back each channel */
199 for (i
= 0; i
< channels
; i
++)
200 ucontrol
->value
.enumerated
.item
[i
] = cdata
->chanv
[i
].value
;
205 int snd_sof_enum_put(struct snd_kcontrol
*kcontrol
,
206 struct snd_ctl_elem_value
*ucontrol
)
208 struct soc_enum
*se
=
209 (struct soc_enum
*)kcontrol
->private_value
;
210 struct snd_sof_control
*scontrol
= se
->dobj
.private;
211 struct snd_soc_component
*scomp
= scontrol
->scomp
;
212 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
213 unsigned int i
, channels
= scontrol
->num_channels
;
217 /* update each channel */
218 for (i
= 0; i
< channels
; i
++) {
219 value
= ucontrol
->value
.enumerated
.item
[i
];
220 change
= change
|| (value
!= cdata
->chanv
[i
].value
);
221 cdata
->chanv
[i
].channel
= i
;
222 cdata
->chanv
[i
].value
= value
;
225 /* notify DSP of enum updates */
226 if (pm_runtime_active(scomp
->dev
))
227 snd_sof_ipc_set_get_comp_data(scontrol
,
228 SOF_IPC_COMP_SET_VALUE
,
229 SOF_CTRL_TYPE_VALUE_CHAN_GET
,
236 int snd_sof_bytes_get(struct snd_kcontrol
*kcontrol
,
237 struct snd_ctl_elem_value
*ucontrol
)
239 struct soc_bytes_ext
*be
=
240 (struct soc_bytes_ext
*)kcontrol
->private_value
;
241 struct snd_sof_control
*scontrol
= be
->dobj
.private;
242 struct snd_soc_component
*scomp
= scontrol
->scomp
;
243 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
244 struct sof_abi_hdr
*data
= cdata
->data
;
247 if (be
->max
> sizeof(ucontrol
->value
.bytes
.data
)) {
248 dev_err_ratelimited(scomp
->dev
,
249 "error: data max %d exceeds ucontrol data array size\n",
254 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
255 if (data
->size
> be
->max
- sizeof(*data
)) {
256 dev_err_ratelimited(scomp
->dev
,
257 "error: %u bytes of control data is invalid, max is %zu\n",
258 data
->size
, be
->max
- sizeof(*data
));
262 size
= data
->size
+ sizeof(*data
);
264 /* copy back to kcontrol */
265 memcpy(ucontrol
->value
.bytes
.data
, data
, size
);
270 int snd_sof_bytes_put(struct snd_kcontrol
*kcontrol
,
271 struct snd_ctl_elem_value
*ucontrol
)
273 struct soc_bytes_ext
*be
=
274 (struct soc_bytes_ext
*)kcontrol
->private_value
;
275 struct snd_sof_control
*scontrol
= be
->dobj
.private;
276 struct snd_soc_component
*scomp
= scontrol
->scomp
;
277 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
278 struct sof_abi_hdr
*data
= cdata
->data
;
281 if (be
->max
> sizeof(ucontrol
->value
.bytes
.data
)) {
282 dev_err_ratelimited(scomp
->dev
,
283 "error: data max %d exceeds ucontrol data array size\n",
288 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
289 if (data
->size
> be
->max
- sizeof(*data
)) {
290 dev_err_ratelimited(scomp
->dev
,
291 "error: data size too big %u bytes max is %zu\n",
292 data
->size
, be
->max
- sizeof(*data
));
296 size
= data
->size
+ sizeof(*data
);
298 /* copy from kcontrol */
299 memcpy(data
, ucontrol
->value
.bytes
.data
, size
);
301 /* notify DSP of byte control updates */
302 if (pm_runtime_active(scomp
->dev
))
303 snd_sof_ipc_set_get_comp_data(scontrol
,
304 SOF_IPC_COMP_SET_DATA
,
305 SOF_CTRL_TYPE_DATA_SET
,
312 int snd_sof_bytes_ext_put(struct snd_kcontrol
*kcontrol
,
313 const unsigned int __user
*binary_data
,
316 struct soc_bytes_ext
*be
=
317 (struct soc_bytes_ext
*)kcontrol
->private_value
;
318 struct snd_sof_control
*scontrol
= be
->dobj
.private;
319 struct snd_soc_component
*scomp
= scontrol
->scomp
;
320 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
321 struct snd_ctl_tlv header
;
322 const struct snd_ctl_tlv __user
*tlvd
=
323 (const struct snd_ctl_tlv __user
*)binary_data
;
325 /* make sure we have at least a header */
326 if (size
< sizeof(struct snd_ctl_tlv
))
330 * The beginning of bytes data contains a header from where
331 * the length (as bytes) is needed to know the correct copy
332 * length of data from tlvd->tlv.
334 if (copy_from_user(&header
, tlvd
, sizeof(struct snd_ctl_tlv
)))
337 /* make sure TLV info is consistent */
338 if (header
.length
+ sizeof(struct snd_ctl_tlv
) > size
) {
339 dev_err_ratelimited(scomp
->dev
, "error: inconsistent TLV, data %d + header %zu > %d\n",
340 header
.length
, sizeof(struct snd_ctl_tlv
), size
);
344 /* be->max is coming from topology */
345 if (header
.length
> be
->max
) {
346 dev_err_ratelimited(scomp
->dev
, "error: Bytes data size %d exceeds max %d.\n",
347 header
.length
, be
->max
);
351 /* Check that header id matches the command */
352 if (header
.numid
!= scontrol
->cmd
) {
353 dev_err_ratelimited(scomp
->dev
,
354 "error: incorrect numid %d\n",
359 if (copy_from_user(cdata
->data
, tlvd
->tlv
, header
.length
))
362 if (cdata
->data
->magic
!= SOF_ABI_MAGIC
) {
363 dev_err_ratelimited(scomp
->dev
,
364 "error: Wrong ABI magic 0x%08x.\n",
369 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION
, cdata
->data
->abi
)) {
370 dev_err_ratelimited(scomp
->dev
, "error: Incompatible ABI version 0x%08x.\n",
375 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
376 if (cdata
->data
->size
> be
->max
- sizeof(struct sof_abi_hdr
)) {
377 dev_err_ratelimited(scomp
->dev
, "error: Mismatch in ABI data size (truncated?).\n");
381 /* notify DSP of byte control updates */
382 if (pm_runtime_active(scomp
->dev
))
383 snd_sof_ipc_set_get_comp_data(scontrol
,
384 SOF_IPC_COMP_SET_DATA
,
385 SOF_CTRL_TYPE_DATA_SET
,
392 int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol
*kcontrol
, unsigned int __user
*binary_data
,
395 struct soc_bytes_ext
*be
= (struct soc_bytes_ext
*)kcontrol
->private_value
;
396 struct snd_sof_control
*scontrol
= be
->dobj
.private;
397 struct snd_soc_component
*scomp
= scontrol
->scomp
;
398 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
399 struct snd_ctl_tlv header
;
400 struct snd_ctl_tlv __user
*tlvd
= (struct snd_ctl_tlv __user
*)binary_data
;
406 * Decrement the limit by ext bytes header size to
407 * ensure the user space buffer is not exceeded.
409 if (size
< sizeof(struct snd_ctl_tlv
))
411 size
-= sizeof(struct snd_ctl_tlv
);
413 ret
= pm_runtime_get_sync(scomp
->dev
);
414 if (ret
< 0 && ret
!= -EACCES
) {
415 dev_err_ratelimited(scomp
->dev
, "error: bytes_ext get failed to resume %d\n", ret
);
416 pm_runtime_put_noidle(scomp
->dev
);
420 /* set the ABI header values */
421 cdata
->data
->magic
= SOF_ABI_MAGIC
;
422 cdata
->data
->abi
= SOF_ABI_VERSION
;
423 /* get all the component data from DSP */
424 ret
= snd_sof_ipc_set_get_comp_data(scontrol
, SOF_IPC_COMP_GET_DATA
, SOF_CTRL_TYPE_DATA_GET
,
425 scontrol
->cmd
, false);
429 /* check data size doesn't exceed max coming from topology */
430 if (cdata
->data
->size
> be
->max
- sizeof(struct sof_abi_hdr
)) {
431 dev_err_ratelimited(scomp
->dev
, "error: user data size %d exceeds max size %zu.\n",
433 be
->max
- sizeof(struct sof_abi_hdr
));
438 data_size
= cdata
->data
->size
+ sizeof(struct sof_abi_hdr
);
440 /* make sure we don't exceed size provided by user space for data */
441 if (data_size
> size
) {
446 header
.numid
= scontrol
->cmd
;
447 header
.length
= data_size
;
448 if (copy_to_user(tlvd
, &header
, sizeof(struct snd_ctl_tlv
))) {
453 if (copy_to_user(tlvd
->tlv
, cdata
->data
, data_size
))
456 pm_runtime_mark_last_busy(scomp
->dev
);
457 err
= pm_runtime_put_autosuspend(scomp
->dev
);
459 dev_err_ratelimited(scomp
->dev
, "error: bytes_ext get failed to idle %d\n", err
);
464 int snd_sof_bytes_ext_get(struct snd_kcontrol
*kcontrol
,
465 unsigned int __user
*binary_data
,
468 struct soc_bytes_ext
*be
=
469 (struct soc_bytes_ext
*)kcontrol
->private_value
;
470 struct snd_sof_control
*scontrol
= be
->dobj
.private;
471 struct snd_soc_component
*scomp
= scontrol
->scomp
;
472 struct sof_ipc_ctrl_data
*cdata
= scontrol
->control_data
;
473 struct snd_ctl_tlv header
;
474 struct snd_ctl_tlv __user
*tlvd
=
475 (struct snd_ctl_tlv __user
*)binary_data
;
479 * Decrement the limit by ext bytes header size to
480 * ensure the user space buffer is not exceeded.
482 if (size
< sizeof(struct snd_ctl_tlv
))
484 size
-= sizeof(struct snd_ctl_tlv
);
486 /* set the ABI header values */
487 cdata
->data
->magic
= SOF_ABI_MAGIC
;
488 cdata
->data
->abi
= SOF_ABI_VERSION
;
490 /* check data size doesn't exceed max coming from topology */
491 if (cdata
->data
->size
> be
->max
- sizeof(struct sof_abi_hdr
)) {
492 dev_err_ratelimited(scomp
->dev
, "error: user data size %d exceeds max size %zu.\n",
494 be
->max
- sizeof(struct sof_abi_hdr
));
498 data_size
= cdata
->data
->size
+ sizeof(struct sof_abi_hdr
);
500 /* make sure we don't exceed size provided by user space for data */
501 if (data_size
> size
)
504 header
.numid
= scontrol
->cmd
;
505 header
.length
= data_size
;
506 if (copy_to_user(tlvd
, &header
, sizeof(struct snd_ctl_tlv
)))
509 if (copy_to_user(tlvd
->tlv
, cdata
->data
, data_size
))