1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // soc-component.c 4 // 5 // Copyright (C) 2019 Renesas Electronics Corp. 6 // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 7 // 8 #include <linux/module.h> 9 #include <sound/soc.h> 10 11 /** 12 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock. 13 * @component: COMPONENT 14 * @clk_id: DAI specific clock ID 15 * @source: Source for the clock 16 * @freq: new clock frequency in Hz 17 * @dir: new clock direction - input/output. 18 * 19 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. 20 */ 21 int snd_soc_component_set_sysclk(struct snd_soc_component *component, 22 int clk_id, int source, unsigned int freq, 23 int dir) 24 { 25 if (component->driver->set_sysclk) 26 return component->driver->set_sysclk(component, clk_id, source, 27 freq, dir); 28 29 return -ENOTSUPP; 30 } 31 EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk); 32 33 /* 34 * snd_soc_component_set_pll - configure component PLL. 35 * @component: COMPONENT 36 * @pll_id: DAI specific PLL ID 37 * @source: DAI specific source for the PLL 38 * @freq_in: PLL input clock frequency in Hz 39 * @freq_out: requested PLL output clock frequency in Hz 40 * 41 * Configures and enables PLL to generate output clock based on input clock. 42 */ 43 int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id, 44 int source, unsigned int freq_in, 45 unsigned int freq_out) 46 { 47 if (component->driver->set_pll) 48 return component->driver->set_pll(component, pll_id, source, 49 freq_in, freq_out); 50 51 return -EINVAL; 52 } 53 EXPORT_SYMBOL_GPL(snd_soc_component_set_pll); 54 55 void snd_soc_component_seq_notifier(struct snd_soc_component *component, 56 enum snd_soc_dapm_type type, int subseq) 57 { 58 if (component->driver->seq_notifier) 59 component->driver->seq_notifier(component, type, subseq); 60 } 61 62 int snd_soc_component_stream_event(struct snd_soc_component *component, 63 int event) 64 { 65 if (component->driver->stream_event) 66 return component->driver->stream_event(component, event); 67 68 return 0; 69 } 70 71 int snd_soc_component_set_bias_level(struct snd_soc_component *component, 72 enum snd_soc_bias_level level) 73 { 74 if (component->driver->set_bias_level) 75 return component->driver->set_bias_level(component, level); 76 77 return 0; 78 } 79 80 int snd_soc_component_enable_pin(struct snd_soc_component *component, 81 const char *pin) 82 { 83 struct snd_soc_dapm_context *dapm = 84 snd_soc_component_get_dapm(component); 85 char *full_name; 86 int ret; 87 88 if (!component->name_prefix) 89 return snd_soc_dapm_enable_pin(dapm, pin); 90 91 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 92 if (!full_name) 93 return -ENOMEM; 94 95 ret = snd_soc_dapm_enable_pin(dapm, full_name); 96 kfree(full_name); 97 98 return ret; 99 } 100 EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin); 101 102 int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, 103 const char *pin) 104 { 105 struct snd_soc_dapm_context *dapm = 106 snd_soc_component_get_dapm(component); 107 char *full_name; 108 int ret; 109 110 if (!component->name_prefix) 111 return snd_soc_dapm_enable_pin_unlocked(dapm, pin); 112 113 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 114 if (!full_name) 115 return -ENOMEM; 116 117 ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name); 118 kfree(full_name); 119 120 return ret; 121 } 122 EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked); 123 124 int snd_soc_component_disable_pin(struct snd_soc_component *component, 125 const char *pin) 126 { 127 struct snd_soc_dapm_context *dapm = 128 snd_soc_component_get_dapm(component); 129 char *full_name; 130 int ret; 131 132 if (!component->name_prefix) 133 return snd_soc_dapm_disable_pin(dapm, pin); 134 135 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 136 if (!full_name) 137 return -ENOMEM; 138 139 ret = snd_soc_dapm_disable_pin(dapm, full_name); 140 kfree(full_name); 141 142 return ret; 143 } 144 EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin); 145 146 int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, 147 const char *pin) 148 { 149 struct snd_soc_dapm_context *dapm = 150 snd_soc_component_get_dapm(component); 151 char *full_name; 152 int ret; 153 154 if (!component->name_prefix) 155 return snd_soc_dapm_disable_pin_unlocked(dapm, pin); 156 157 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 158 if (!full_name) 159 return -ENOMEM; 160 161 ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name); 162 kfree(full_name); 163 164 return ret; 165 } 166 EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked); 167 168 int snd_soc_component_nc_pin(struct snd_soc_component *component, 169 const char *pin) 170 { 171 struct snd_soc_dapm_context *dapm = 172 snd_soc_component_get_dapm(component); 173 char *full_name; 174 int ret; 175 176 if (!component->name_prefix) 177 return snd_soc_dapm_nc_pin(dapm, pin); 178 179 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 180 if (!full_name) 181 return -ENOMEM; 182 183 ret = snd_soc_dapm_nc_pin(dapm, full_name); 184 kfree(full_name); 185 186 return ret; 187 } 188 EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin); 189 190 int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, 191 const char *pin) 192 { 193 struct snd_soc_dapm_context *dapm = 194 snd_soc_component_get_dapm(component); 195 char *full_name; 196 int ret; 197 198 if (!component->name_prefix) 199 return snd_soc_dapm_nc_pin_unlocked(dapm, pin); 200 201 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 202 if (!full_name) 203 return -ENOMEM; 204 205 ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name); 206 kfree(full_name); 207 208 return ret; 209 } 210 EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked); 211 212 int snd_soc_component_get_pin_status(struct snd_soc_component *component, 213 const char *pin) 214 { 215 struct snd_soc_dapm_context *dapm = 216 snd_soc_component_get_dapm(component); 217 char *full_name; 218 int ret; 219 220 if (!component->name_prefix) 221 return snd_soc_dapm_get_pin_status(dapm, pin); 222 223 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 224 if (!full_name) 225 return -ENOMEM; 226 227 ret = snd_soc_dapm_get_pin_status(dapm, full_name); 228 kfree(full_name); 229 230 return ret; 231 } 232 EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status); 233 234 int snd_soc_component_force_enable_pin(struct snd_soc_component *component, 235 const char *pin) 236 { 237 struct snd_soc_dapm_context *dapm = 238 snd_soc_component_get_dapm(component); 239 char *full_name; 240 int ret; 241 242 if (!component->name_prefix) 243 return snd_soc_dapm_force_enable_pin(dapm, pin); 244 245 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 246 if (!full_name) 247 return -ENOMEM; 248 249 ret = snd_soc_dapm_force_enable_pin(dapm, full_name); 250 kfree(full_name); 251 252 return ret; 253 } 254 EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin); 255 256 int snd_soc_component_force_enable_pin_unlocked( 257 struct snd_soc_component *component, 258 const char *pin) 259 { 260 struct snd_soc_dapm_context *dapm = 261 snd_soc_component_get_dapm(component); 262 char *full_name; 263 int ret; 264 265 if (!component->name_prefix) 266 return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); 267 268 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 269 if (!full_name) 270 return -ENOMEM; 271 272 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name); 273 kfree(full_name); 274 275 return ret; 276 } 277 EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked); 278 279 /** 280 * snd_soc_component_set_jack - configure component jack. 281 * @component: COMPONENTs 282 * @jack: structure to use for the jack 283 * @data: can be used if codec driver need extra data for configuring jack 284 * 285 * Configures and enables jack detection function. 286 */ 287 int snd_soc_component_set_jack(struct snd_soc_component *component, 288 struct snd_soc_jack *jack, void *data) 289 { 290 if (component->driver->set_jack) 291 return component->driver->set_jack(component, jack, data); 292 293 return -ENOTSUPP; 294 } 295 EXPORT_SYMBOL_GPL(snd_soc_component_set_jack); 296 297 int snd_soc_component_module_get(struct snd_soc_component *component, 298 int upon_open) 299 { 300 if (component->driver->module_get_upon_open == !!upon_open && 301 !try_module_get(component->dev->driver->owner)) 302 return -ENODEV; 303 304 return 0; 305 } 306 307 void snd_soc_component_module_put(struct snd_soc_component *component, 308 int upon_open) 309 { 310 if (component->driver->module_get_upon_open == !!upon_open) 311 module_put(component->dev->driver->owner); 312 } 313 314 int snd_soc_component_open(struct snd_soc_component *component, 315 struct snd_pcm_substream *substream) 316 { 317 if (component->driver->open) 318 return component->driver->open(component, substream); 319 return 0; 320 } 321 322 int snd_soc_component_close(struct snd_soc_component *component, 323 struct snd_pcm_substream *substream) 324 { 325 if (component->driver->close) 326 return component->driver->close(component, substream); 327 return 0; 328 } 329 330 int snd_soc_component_prepare(struct snd_soc_component *component, 331 struct snd_pcm_substream *substream) 332 { 333 if (component->driver->prepare) 334 return component->driver->prepare(component, substream); 335 return 0; 336 } 337 338 int snd_soc_component_hw_params(struct snd_soc_component *component, 339 struct snd_pcm_substream *substream, 340 struct snd_pcm_hw_params *params) 341 { 342 if (component->driver->hw_params) 343 return component->driver->hw_params(component, 344 substream, params); 345 return 0; 346 } 347 348 int snd_soc_component_hw_free(struct snd_soc_component *component, 349 struct snd_pcm_substream *substream) 350 { 351 if (component->driver->hw_free) 352 return component->driver->hw_free(component, substream); 353 return 0; 354 } 355 356 int snd_soc_component_trigger(struct snd_soc_component *component, 357 struct snd_pcm_substream *substream, 358 int cmd) 359 { 360 if (component->driver->trigger) 361 return component->driver->trigger(component, substream, cmd); 362 return 0; 363 } 364 365 void snd_soc_component_suspend(struct snd_soc_component *component) 366 { 367 if (component->driver->suspend) 368 component->driver->suspend(component); 369 component->suspended = 1; 370 } 371 372 void snd_soc_component_resume(struct snd_soc_component *component) 373 { 374 if (component->driver->resume) 375 component->driver->resume(component); 376 component->suspended = 0; 377 } 378 379 int snd_soc_component_is_suspended(struct snd_soc_component *component) 380 { 381 return component->suspended; 382 } 383 384 int snd_soc_component_probe(struct snd_soc_component *component) 385 { 386 if (component->driver->probe) 387 return component->driver->probe(component); 388 389 return 0; 390 } 391 392 void snd_soc_component_remove(struct snd_soc_component *component) 393 { 394 if (component->driver->remove) 395 component->driver->remove(component); 396 } 397 398 int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component, 399 struct device_node *ep) 400 { 401 if (component->driver->of_xlate_dai_id) 402 return component->driver->of_xlate_dai_id(component, ep); 403 404 return -ENOTSUPP; 405 } 406 407 int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component, 408 struct of_phandle_args *args, 409 const char **dai_name) 410 { 411 if (component->driver->of_xlate_dai_name) 412 return component->driver->of_xlate_dai_name(component, 413 args, dai_name); 414 return -ENOTSUPP; 415 } 416 417 int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream) 418 { 419 struct snd_soc_pcm_runtime *rtd = substream->private_data; 420 struct snd_soc_component *component; 421 struct snd_soc_rtdcom_list *rtdcom; 422 423 /* FIXME: use 1st pointer */ 424 for_each_rtd_components(rtd, rtdcom, component) 425 if (component->driver->pointer) 426 return component->driver->pointer(component, substream); 427 428 return 0; 429 } 430 431 int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream, 432 unsigned int cmd, void *arg) 433 { 434 struct snd_soc_pcm_runtime *rtd = substream->private_data; 435 struct snd_soc_component *component; 436 struct snd_soc_rtdcom_list *rtdcom; 437 438 /* FIXME: use 1st ioctl */ 439 for_each_rtd_components(rtd, rtdcom, component) 440 if (component->driver->ioctl) 441 return component->driver->ioctl(component, substream, 442 cmd, arg); 443 444 return snd_pcm_lib_ioctl(substream, cmd, arg); 445 } 446 447 int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream) 448 { 449 struct snd_soc_pcm_runtime *rtd = substream->private_data; 450 struct snd_soc_component *component; 451 struct snd_soc_rtdcom_list *rtdcom; 452 int ret; 453 454 for_each_rtd_components(rtd, rtdcom, component) { 455 if (component->driver->ioctl) { 456 ret = component->driver->sync_stop(component, 457 substream); 458 if (ret < 0) 459 return ret; 460 } 461 } 462 463 return 0; 464 } 465 466 int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream, 467 int channel, unsigned long pos, 468 void __user *buf, unsigned long bytes) 469 { 470 struct snd_soc_pcm_runtime *rtd = substream->private_data; 471 struct snd_soc_rtdcom_list *rtdcom; 472 struct snd_soc_component *component; 473 474 /* FIXME. it returns 1st copy now */ 475 for_each_rtd_components(rtd, rtdcom, component) 476 if (component->driver->copy_user) 477 return component->driver->copy_user( 478 component, substream, channel, pos, buf, bytes); 479 480 return -EINVAL; 481 } 482 483 struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream, 484 unsigned long offset) 485 { 486 struct snd_soc_pcm_runtime *rtd = substream->private_data; 487 struct snd_soc_rtdcom_list *rtdcom; 488 struct snd_soc_component *component; 489 struct page *page; 490 491 /* FIXME. it returns 1st page now */ 492 for_each_rtd_components(rtd, rtdcom, component) { 493 if (component->driver->page) { 494 page = component->driver->page(component, 495 substream, offset); 496 if (page) 497 return page; 498 } 499 } 500 501 return NULL; 502 } 503 504 int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream, 505 struct vm_area_struct *vma) 506 { 507 struct snd_soc_pcm_runtime *rtd = substream->private_data; 508 struct snd_soc_rtdcom_list *rtdcom; 509 struct snd_soc_component *component; 510 511 /* FIXME. it returns 1st mmap now */ 512 for_each_rtd_components(rtd, rtdcom, component) 513 if (component->driver->mmap) 514 return component->driver->mmap(component, 515 substream, vma); 516 517 return -EINVAL; 518 } 519 520 int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd) 521 { 522 struct snd_soc_rtdcom_list *rtdcom; 523 struct snd_soc_component *component; 524 int ret; 525 526 for_each_rtd_components(rtd, rtdcom, component) { 527 if (component->driver->pcm_construct) { 528 ret = component->driver->pcm_construct(component, rtd); 529 if (ret < 0) 530 return ret; 531 } 532 } 533 534 return 0; 535 } 536 537 void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd) 538 { 539 struct snd_soc_rtdcom_list *rtdcom; 540 struct snd_soc_component *component; 541 542 if (!rtd->pcm) 543 return; 544 545 for_each_rtd_components(rtd, rtdcom, component) 546 if (component->driver->pcm_destruct) 547 component->driver->pcm_destruct(component, rtd->pcm); 548 } 549