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->ops && 318 component->driver->ops->open) 319 return component->driver->ops->open(substream); 320 321 return 0; 322 } 323 324 int snd_soc_component_close(struct snd_soc_component *component, 325 struct snd_pcm_substream *substream) 326 { 327 if (component->driver->ops && 328 component->driver->ops->close) 329 return component->driver->ops->close(substream); 330 331 return 0; 332 } 333 334 int snd_soc_component_prepare(struct snd_soc_component *component, 335 struct snd_pcm_substream *substream) 336 { 337 if (component->driver->ops && 338 component->driver->ops->prepare) 339 return component->driver->ops->prepare(substream); 340 341 return 0; 342 } 343 344 int snd_soc_component_hw_params(struct snd_soc_component *component, 345 struct snd_pcm_substream *substream, 346 struct snd_pcm_hw_params *params) 347 { 348 if (component->driver->ops && 349 component->driver->ops->hw_params) 350 return component->driver->ops->hw_params(substream, params); 351 352 return 0; 353 } 354 355 int snd_soc_component_hw_free(struct snd_soc_component *component, 356 struct snd_pcm_substream *substream) 357 { 358 if (component->driver->ops && 359 component->driver->ops->hw_free) 360 return component->driver->ops->hw_free(substream); 361 362 return 0; 363 } 364 365 int snd_soc_component_trigger(struct snd_soc_component *component, 366 struct snd_pcm_substream *substream, 367 int cmd) 368 { 369 if (component->driver->ops && 370 component->driver->ops->trigger) 371 return component->driver->ops->trigger(substream, cmd); 372 373 return 0; 374 } 375 376 void snd_soc_component_suspend(struct snd_soc_component *component) 377 { 378 if (component->driver->suspend) 379 component->driver->suspend(component); 380 component->suspended = 1; 381 } 382 383 void snd_soc_component_resume(struct snd_soc_component *component) 384 { 385 if (component->driver->resume) 386 component->driver->resume(component); 387 component->suspended = 0; 388 } 389 390 int snd_soc_component_is_suspended(struct snd_soc_component *component) 391 { 392 return component->suspended; 393 } 394 395 int snd_soc_component_probe(struct snd_soc_component *component) 396 { 397 if (component->driver->probe) 398 return component->driver->probe(component); 399 400 return 0; 401 } 402 403 void snd_soc_component_remove(struct snd_soc_component *component) 404 { 405 if (component->driver->remove) 406 component->driver->remove(component); 407 } 408 409 int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component, 410 struct device_node *ep) 411 { 412 if (component->driver->of_xlate_dai_id) 413 return component->driver->of_xlate_dai_id(component, ep); 414 415 return -ENOTSUPP; 416 } 417 418 int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component, 419 struct of_phandle_args *args, 420 const char **dai_name) 421 { 422 if (component->driver->of_xlate_dai_name) 423 return component->driver->of_xlate_dai_name(component, 424 args, dai_name); 425 return -ENOTSUPP; 426 } 427 428 int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream) 429 { 430 struct snd_soc_pcm_runtime *rtd = substream->private_data; 431 struct snd_soc_component *component; 432 struct snd_soc_rtdcom_list *rtdcom; 433 434 for_each_rtdcom(rtd, rtdcom) { 435 component = rtdcom->component; 436 437 /* FIXME: use 1st pointer */ 438 if (component->driver->ops && 439 component->driver->ops->pointer) 440 return component->driver->ops->pointer(substream); 441 } 442 443 return 0; 444 } 445 446 int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream, 447 unsigned int cmd, void *arg) 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 453 for_each_rtdcom(rtd, rtdcom) { 454 component = rtdcom->component; 455 456 /* FIXME: use 1st ioctl */ 457 if (component->driver->ops && 458 component->driver->ops->ioctl) 459 return component->driver->ops->ioctl(substream, 460 cmd, arg); 461 } 462 463 return snd_pcm_lib_ioctl(substream, cmd, arg); 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 for_each_rtdcom(rtd, rtdcom) { 475 component = rtdcom->component; 476 477 /* FIXME. it returns 1st copy now */ 478 if (component->driver->ops && 479 component->driver->ops->copy_user) 480 return component->driver->ops->copy_user( 481 substream, channel, pos, buf, bytes); 482 } 483 484 return -EINVAL; 485 } 486 487 struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream, 488 unsigned long offset) 489 { 490 struct snd_soc_pcm_runtime *rtd = substream->private_data; 491 struct snd_soc_rtdcom_list *rtdcom; 492 struct snd_soc_component *component; 493 struct page *page; 494 495 for_each_rtdcom(rtd, rtdcom) { 496 component = rtdcom->component; 497 498 /* FIXME. it returns 1st page now */ 499 if (component->driver->ops && 500 component->driver->ops->page) { 501 page = component->driver->ops->page(substream, offset); 502 if (page) 503 return page; 504 } 505 } 506 507 return NULL; 508 } 509 510 int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream, 511 struct vm_area_struct *vma) 512 { 513 struct snd_soc_pcm_runtime *rtd = substream->private_data; 514 struct snd_soc_rtdcom_list *rtdcom; 515 struct snd_soc_component *component; 516 517 for_each_rtdcom(rtd, rtdcom) { 518 component = rtdcom->component; 519 520 /* FIXME. it returns 1st mmap now */ 521 if (component->driver->ops && 522 component->driver->ops->mmap) 523 return component->driver->ops->mmap(substream, vma); 524 } 525 526 return -EINVAL; 527 } 528 529 int snd_soc_pcm_component_new(struct snd_pcm *pcm) 530 { 531 struct snd_soc_pcm_runtime *rtd = pcm->private_data; 532 struct snd_soc_rtdcom_list *rtdcom; 533 struct snd_soc_component *component; 534 int ret; 535 536 for_each_rtdcom(rtd, rtdcom) { 537 component = rtdcom->component; 538 539 if (component->driver->pcm_new) { 540 ret = component->driver->pcm_new(rtd); 541 if (ret < 0) 542 return ret; 543 } 544 } 545 546 return 0; 547 } 548 549 void snd_soc_pcm_component_free(struct snd_pcm *pcm) 550 { 551 struct snd_soc_pcm_runtime *rtd = pcm->private_data; 552 struct snd_soc_rtdcom_list *rtdcom; 553 struct snd_soc_component *component; 554 555 for_each_rtdcom(rtd, rtdcom) { 556 component = rtdcom->component; 557 558 if (component->driver->pcm_free) 559 component->driver->pcm_free(pcm); 560 } 561 } 562