1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 // 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. 5 // 6 // Copyright(c) 2018 Intel Corporation. All rights reserved. 7 // 8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9 // 10 11 /* Mixer Controls */ 12 13 #include <linux/pm_runtime.h> 14 #include <linux/leds.h> 15 #include "sof-priv.h" 16 17 static void update_mute_led(struct snd_sof_control *scontrol, 18 struct snd_kcontrol *kcontrol, 19 struct snd_ctl_elem_value *ucontrol) 20 { 21 unsigned int temp = 0; 22 unsigned int mask; 23 int i; 24 25 mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 26 27 for (i = 0; i < scontrol->num_channels; i++) { 28 if (ucontrol->value.integer.value[i]) { 29 temp |= mask; 30 break; 31 } 32 } 33 34 if (temp == scontrol->led_ctl.led_value) 35 return; 36 37 scontrol->led_ctl.led_value = temp; 38 39 #if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO) 40 if (!scontrol->led_ctl.direction) 41 ledtrig_audio_set(LED_AUDIO_MUTE, temp ? LED_OFF : LED_ON); 42 else 43 ledtrig_audio_set(LED_AUDIO_MICMUTE, temp ? LED_OFF : LED_ON); 44 #endif 45 } 46 47 static inline u32 mixer_to_ipc(unsigned int value, u32 *volume_map, int size) 48 { 49 if (value >= size) 50 return volume_map[size - 1]; 51 52 return volume_map[value]; 53 } 54 55 static inline u32 ipc_to_mixer(u32 value, u32 *volume_map, int size) 56 { 57 int i; 58 59 for (i = 0; i < size; i++) { 60 if (volume_map[i] >= value) 61 return i; 62 } 63 64 return i - 1; 65 } 66 67 int snd_sof_volume_get(struct snd_kcontrol *kcontrol, 68 struct snd_ctl_elem_value *ucontrol) 69 { 70 struct soc_mixer_control *sm = 71 (struct soc_mixer_control *)kcontrol->private_value; 72 struct snd_sof_control *scontrol = sm->dobj.private; 73 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 74 unsigned int i, channels = scontrol->num_channels; 75 76 /* read back each channel */ 77 for (i = 0; i < channels; i++) 78 ucontrol->value.integer.value[i] = 79 ipc_to_mixer(cdata->chanv[i].value, 80 scontrol->volume_table, sm->max + 1); 81 82 return 0; 83 } 84 85 int snd_sof_volume_put(struct snd_kcontrol *kcontrol, 86 struct snd_ctl_elem_value *ucontrol) 87 { 88 struct soc_mixer_control *sm = 89 (struct soc_mixer_control *)kcontrol->private_value; 90 struct snd_sof_control *scontrol = sm->dobj.private; 91 struct snd_sof_dev *sdev = scontrol->sdev; 92 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 93 unsigned int i, channels = scontrol->num_channels; 94 bool change = false; 95 u32 value; 96 97 /* update each channel */ 98 for (i = 0; i < channels; i++) { 99 value = mixer_to_ipc(ucontrol->value.integer.value[i], 100 scontrol->volume_table, sm->max + 1); 101 change = change || (value != cdata->chanv[i].value); 102 cdata->chanv[i].channel = i; 103 cdata->chanv[i].value = value; 104 } 105 106 /* notify DSP of mixer updates */ 107 if (pm_runtime_active(sdev->dev)) 108 snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol, 109 SOF_IPC_COMP_SET_VALUE, 110 SOF_CTRL_TYPE_VALUE_CHAN_GET, 111 SOF_CTRL_CMD_VOLUME, 112 true); 113 return change; 114 } 115 116 int snd_sof_switch_get(struct snd_kcontrol *kcontrol, 117 struct snd_ctl_elem_value *ucontrol) 118 { 119 struct soc_mixer_control *sm = 120 (struct soc_mixer_control *)kcontrol->private_value; 121 struct snd_sof_control *scontrol = sm->dobj.private; 122 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 123 unsigned int i, channels = scontrol->num_channels; 124 125 /* read back each channel */ 126 for (i = 0; i < channels; i++) 127 ucontrol->value.integer.value[i] = cdata->chanv[i].value; 128 129 return 0; 130 } 131 132 int snd_sof_switch_put(struct snd_kcontrol *kcontrol, 133 struct snd_ctl_elem_value *ucontrol) 134 { 135 struct soc_mixer_control *sm = 136 (struct soc_mixer_control *)kcontrol->private_value; 137 struct snd_sof_control *scontrol = sm->dobj.private; 138 struct snd_sof_dev *sdev = scontrol->sdev; 139 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 140 unsigned int i, channels = scontrol->num_channels; 141 bool change = false; 142 u32 value; 143 144 /* update each channel */ 145 for (i = 0; i < channels; i++) { 146 value = ucontrol->value.integer.value[i]; 147 change = change || (value != cdata->chanv[i].value); 148 cdata->chanv[i].channel = i; 149 cdata->chanv[i].value = value; 150 } 151 152 if (scontrol->led_ctl.use_led) 153 update_mute_led(scontrol, kcontrol, ucontrol); 154 155 /* notify DSP of mixer updates */ 156 if (pm_runtime_active(sdev->dev)) 157 snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol, 158 SOF_IPC_COMP_SET_VALUE, 159 SOF_CTRL_TYPE_VALUE_CHAN_GET, 160 SOF_CTRL_CMD_SWITCH, 161 true); 162 163 return change; 164 } 165 166 int snd_sof_enum_get(struct snd_kcontrol *kcontrol, 167 struct snd_ctl_elem_value *ucontrol) 168 { 169 struct soc_enum *se = 170 (struct soc_enum *)kcontrol->private_value; 171 struct snd_sof_control *scontrol = se->dobj.private; 172 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 173 unsigned int i, channels = scontrol->num_channels; 174 175 /* read back each channel */ 176 for (i = 0; i < channels; i++) 177 ucontrol->value.enumerated.item[i] = cdata->chanv[i].value; 178 179 return 0; 180 } 181 182 int snd_sof_enum_put(struct snd_kcontrol *kcontrol, 183 struct snd_ctl_elem_value *ucontrol) 184 { 185 struct soc_enum *se = 186 (struct soc_enum *)kcontrol->private_value; 187 struct snd_sof_control *scontrol = se->dobj.private; 188 struct snd_sof_dev *sdev = scontrol->sdev; 189 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 190 unsigned int i, channels = scontrol->num_channels; 191 bool change = false; 192 u32 value; 193 194 /* update each channel */ 195 for (i = 0; i < channels; i++) { 196 value = ucontrol->value.enumerated.item[i]; 197 change = change || (value != cdata->chanv[i].value); 198 cdata->chanv[i].channel = i; 199 cdata->chanv[i].value = value; 200 } 201 202 /* notify DSP of enum updates */ 203 if (pm_runtime_active(sdev->dev)) 204 snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol, 205 SOF_IPC_COMP_SET_VALUE, 206 SOF_CTRL_TYPE_VALUE_CHAN_GET, 207 SOF_CTRL_CMD_ENUM, 208 true); 209 210 return change; 211 } 212 213 int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, 214 struct snd_ctl_elem_value *ucontrol) 215 { 216 struct soc_bytes_ext *be = 217 (struct soc_bytes_ext *)kcontrol->private_value; 218 struct snd_sof_control *scontrol = be->dobj.private; 219 struct snd_sof_dev *sdev = scontrol->sdev; 220 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 221 struct sof_abi_hdr *data = cdata->data; 222 size_t size; 223 int ret = 0; 224 225 if (be->max > sizeof(ucontrol->value.bytes.data)) { 226 dev_err_ratelimited(sdev->dev, 227 "error: data max %d exceeds ucontrol data array size\n", 228 be->max); 229 return -EINVAL; 230 } 231 232 size = data->size + sizeof(*data); 233 if (size > be->max) { 234 dev_err_ratelimited(sdev->dev, 235 "error: DSP sent %zu bytes max is %d\n", 236 size, be->max); 237 ret = -EINVAL; 238 goto out; 239 } 240 241 /* copy back to kcontrol */ 242 memcpy(ucontrol->value.bytes.data, data, size); 243 244 out: 245 return ret; 246 } 247 248 int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, 249 struct snd_ctl_elem_value *ucontrol) 250 { 251 struct soc_bytes_ext *be = 252 (struct soc_bytes_ext *)kcontrol->private_value; 253 struct snd_sof_control *scontrol = be->dobj.private; 254 struct snd_sof_dev *sdev = scontrol->sdev; 255 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 256 struct sof_abi_hdr *data = cdata->data; 257 size_t size = data->size + sizeof(*data); 258 259 if (be->max > sizeof(ucontrol->value.bytes.data)) { 260 dev_err_ratelimited(sdev->dev, 261 "error: data max %d exceeds ucontrol data array size\n", 262 be->max); 263 return -EINVAL; 264 } 265 266 if (size > be->max) { 267 dev_err_ratelimited(sdev->dev, 268 "error: size too big %zu bytes max is %d\n", 269 size, be->max); 270 return -EINVAL; 271 } 272 273 /* copy from kcontrol */ 274 memcpy(data, ucontrol->value.bytes.data, size); 275 276 /* notify DSP of byte control updates */ 277 if (pm_runtime_active(sdev->dev)) 278 snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol, 279 SOF_IPC_COMP_SET_DATA, 280 SOF_CTRL_TYPE_DATA_SET, 281 scontrol->cmd, 282 true); 283 284 return 0; 285 } 286 287 int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol, 288 const unsigned int __user *binary_data, 289 unsigned int size) 290 { 291 struct soc_bytes_ext *be = 292 (struct soc_bytes_ext *)kcontrol->private_value; 293 struct snd_sof_control *scontrol = be->dobj.private; 294 struct snd_sof_dev *sdev = scontrol->sdev; 295 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 296 struct snd_ctl_tlv header; 297 const struct snd_ctl_tlv __user *tlvd = 298 (const struct snd_ctl_tlv __user *)binary_data; 299 300 /* 301 * The beginning of bytes data contains a header from where 302 * the length (as bytes) is needed to know the correct copy 303 * length of data from tlvd->tlv. 304 */ 305 if (copy_from_user(&header, tlvd, sizeof(const struct snd_ctl_tlv))) 306 return -EFAULT; 307 308 /* be->max is coming from topology */ 309 if (header.length > be->max) { 310 dev_err_ratelimited(sdev->dev, "error: Bytes data size %d exceeds max %d.\n", 311 header.length, be->max); 312 return -EINVAL; 313 } 314 315 /* Check that header id matches the command */ 316 if (header.numid != scontrol->cmd) { 317 dev_err_ratelimited(sdev->dev, 318 "error: incorrect numid %d\n", 319 header.numid); 320 return -EINVAL; 321 } 322 323 if (copy_from_user(cdata->data, tlvd->tlv, header.length)) 324 return -EFAULT; 325 326 if (cdata->data->magic != SOF_ABI_MAGIC) { 327 dev_err_ratelimited(sdev->dev, 328 "error: Wrong ABI magic 0x%08x.\n", 329 cdata->data->magic); 330 return -EINVAL; 331 } 332 333 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, cdata->data->abi)) { 334 dev_err_ratelimited(sdev->dev, "error: Incompatible ABI version 0x%08x.\n", 335 cdata->data->abi); 336 return -EINVAL; 337 } 338 339 if (cdata->data->size + sizeof(const struct sof_abi_hdr) > be->max) { 340 dev_err_ratelimited(sdev->dev, "error: Mismatch in ABI data size (truncated?).\n"); 341 return -EINVAL; 342 } 343 344 /* notify DSP of byte control updates */ 345 if (pm_runtime_active(sdev->dev)) 346 snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol, 347 SOF_IPC_COMP_SET_DATA, 348 SOF_CTRL_TYPE_DATA_SET, 349 scontrol->cmd, 350 true); 351 352 return 0; 353 } 354 355 int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol, 356 unsigned int __user *binary_data, 357 unsigned int size) 358 { 359 struct soc_bytes_ext *be = 360 (struct soc_bytes_ext *)kcontrol->private_value; 361 struct snd_sof_control *scontrol = be->dobj.private; 362 struct snd_sof_dev *sdev = scontrol->sdev; 363 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 364 struct snd_ctl_tlv header; 365 struct snd_ctl_tlv __user *tlvd = 366 (struct snd_ctl_tlv __user *)binary_data; 367 int data_size; 368 int ret = 0; 369 370 /* 371 * Decrement the limit by ext bytes header size to 372 * ensure the user space buffer is not exceeded. 373 */ 374 size -= sizeof(const struct snd_ctl_tlv); 375 376 /* set the ABI header values */ 377 cdata->data->magic = SOF_ABI_MAGIC; 378 cdata->data->abi = SOF_ABI_VERSION; 379 380 /* Prevent read of other kernel data or possibly corrupt response */ 381 data_size = cdata->data->size + sizeof(const struct sof_abi_hdr); 382 383 /* check data size doesn't exceed max coming from topology */ 384 if (data_size > be->max) { 385 dev_err_ratelimited(sdev->dev, "error: user data size %d exceeds max size %d.\n", 386 data_size, be->max); 387 ret = -EINVAL; 388 goto out; 389 } 390 391 header.numid = scontrol->cmd; 392 header.length = data_size; 393 if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) { 394 ret = -EFAULT; 395 goto out; 396 } 397 398 if (copy_to_user(tlvd->tlv, cdata->data, data_size)) 399 ret = -EFAULT; 400 401 out: 402 return ret; 403 } 404