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