1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * APBridge ALSA SoC dummy codec driver 4 * Copyright 2016 Google Inc. 5 * Copyright 2016 Linaro Ltd. 6 */ 7 #include <linux/kernel.h> 8 #include <linux/module.h> 9 #include <linux/pm_runtime.h> 10 #include <sound/soc.h> 11 #include <sound/pcm_params.h> 12 #include <uapi/linux/input.h> 13 14 #include "audio_codec.h" 15 #include "audio_apbridgea.h" 16 #include "audio_manager.h" 17 18 static struct gbaudio_codec_info *gbcodec; 19 20 static struct gbaudio_data_connection * 21 find_data(struct gbaudio_module_info *module, int id) 22 { 23 struct gbaudio_data_connection *data; 24 25 list_for_each_entry(data, &module->data_list, list) { 26 if (id == data->id) 27 return data; 28 } 29 return NULL; 30 } 31 32 static struct gbaudio_stream_params * 33 find_dai_stream_params(struct gbaudio_codec_info *codec, int id, int stream) 34 { 35 struct gbaudio_codec_dai *dai; 36 37 list_for_each_entry(dai, &codec->dai_list, list) { 38 if (dai->id == id) 39 return &dai->params[stream]; 40 } 41 return NULL; 42 } 43 44 static int gbaudio_module_enable_tx(struct gbaudio_codec_info *codec, 45 struct gbaudio_module_info *module, int id) 46 { 47 int module_state, ret = 0; 48 u16 data_cport, i2s_port, cportid; 49 u8 sig_bits, channels; 50 u32 format, rate; 51 struct gbaudio_data_connection *data; 52 struct gbaudio_stream_params *params; 53 54 /* find the dai */ 55 data = find_data(module, id); 56 if (!data) { 57 dev_err(module->dev, "%d:DATA connection missing\n", id); 58 return -ENODEV; 59 } 60 module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK]; 61 62 params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_PLAYBACK); 63 if (!params) { 64 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n"); 65 return -EINVAL; 66 } 67 68 /* register cport */ 69 if (module_state < GBAUDIO_CODEC_STARTUP) { 70 i2s_port = 0; /* fixed for now */ 71 cportid = data->connection->hd_cport_id; 72 ret = gb_audio_apbridgea_register_cport(data->connection, 73 i2s_port, cportid, 74 AUDIO_APBRIDGEA_DIRECTION_TX); 75 if (ret) { 76 dev_err_ratelimited(module->dev, 77 "reg_cport failed:%d\n", ret); 78 return ret; 79 } 80 data->state[SNDRV_PCM_STREAM_PLAYBACK] = 81 GBAUDIO_CODEC_STARTUP; 82 dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid); 83 } 84 85 /* hw_params */ 86 if (module_state < GBAUDIO_CODEC_HWPARAMS) { 87 format = params->format; 88 channels = params->channels; 89 rate = params->rate; 90 sig_bits = params->sig_bits; 91 data_cport = data->connection->intf_cport_id; 92 ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport, 93 format, rate, channels, sig_bits); 94 if (ret) { 95 dev_err_ratelimited(module->dev, "set_pcm failed:%d\n", 96 ret); 97 return ret; 98 } 99 data->state[SNDRV_PCM_STREAM_PLAYBACK] = 100 GBAUDIO_CODEC_HWPARAMS; 101 dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport); 102 } 103 104 /* prepare */ 105 if (module_state < GBAUDIO_CODEC_PREPARE) { 106 data_cport = data->connection->intf_cport_id; 107 ret = gb_audio_gb_set_tx_data_size(module->mgmt_connection, 108 data_cport, 192); 109 if (ret) { 110 dev_err_ratelimited(module->dev, 111 "set_tx_data_size failed:%d\n", 112 ret); 113 return ret; 114 } 115 ret = gb_audio_gb_activate_tx(module->mgmt_connection, 116 data_cport); 117 if (ret) { 118 dev_err_ratelimited(module->dev, 119 "activate_tx failed:%d\n", ret); 120 return ret; 121 } 122 data->state[SNDRV_PCM_STREAM_PLAYBACK] = 123 GBAUDIO_CODEC_PREPARE; 124 dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport); 125 } 126 127 return 0; 128 } 129 130 static int gbaudio_module_disable_tx(struct gbaudio_module_info *module, int id) 131 { 132 int ret; 133 u16 data_cport, cportid, i2s_port; 134 int module_state; 135 struct gbaudio_data_connection *data; 136 137 /* find the dai */ 138 data = find_data(module, id); 139 if (!data) { 140 dev_err(module->dev, "%d:DATA connection missing\n", id); 141 return -ENODEV; 142 } 143 module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK]; 144 145 if (module_state > GBAUDIO_CODEC_HWPARAMS) { 146 data_cport = data->connection->intf_cport_id; 147 ret = gb_audio_gb_deactivate_tx(module->mgmt_connection, 148 data_cport); 149 if (ret) { 150 dev_err_ratelimited(module->dev, 151 "deactivate_tx failed:%d\n", ret); 152 return ret; 153 } 154 dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport); 155 data->state[SNDRV_PCM_STREAM_PLAYBACK] = 156 GBAUDIO_CODEC_HWPARAMS; 157 } 158 159 if (module_state > GBAUDIO_CODEC_SHUTDOWN) { 160 i2s_port = 0; /* fixed for now */ 161 cportid = data->connection->hd_cport_id; 162 ret = gb_audio_apbridgea_unregister_cport(data->connection, 163 i2s_port, cportid, 164 AUDIO_APBRIDGEA_DIRECTION_TX); 165 if (ret) { 166 dev_err_ratelimited(module->dev, 167 "unregister_cport failed:%d\n", 168 ret); 169 return ret; 170 } 171 dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid); 172 data->state[SNDRV_PCM_STREAM_PLAYBACK] = 173 GBAUDIO_CODEC_SHUTDOWN; 174 } 175 176 return 0; 177 } 178 179 static int gbaudio_module_enable_rx(struct gbaudio_codec_info *codec, 180 struct gbaudio_module_info *module, int id) 181 { 182 int module_state, ret = 0; 183 u16 data_cport, i2s_port, cportid; 184 u8 sig_bits, channels; 185 u32 format, rate; 186 struct gbaudio_data_connection *data; 187 struct gbaudio_stream_params *params; 188 189 /* find the dai */ 190 data = find_data(module, id); 191 if (!data) { 192 dev_err(module->dev, "%d:DATA connection missing\n", id); 193 return -ENODEV; 194 } 195 module_state = data->state[SNDRV_PCM_STREAM_CAPTURE]; 196 197 params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_CAPTURE); 198 if (!params) { 199 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n"); 200 return -EINVAL; 201 } 202 203 /* register cport */ 204 if (module_state < GBAUDIO_CODEC_STARTUP) { 205 i2s_port = 0; /* fixed for now */ 206 cportid = data->connection->hd_cport_id; 207 ret = gb_audio_apbridgea_register_cport(data->connection, 208 i2s_port, cportid, 209 AUDIO_APBRIDGEA_DIRECTION_RX); 210 if (ret) { 211 dev_err_ratelimited(module->dev, 212 "reg_cport failed:%d\n", ret); 213 return ret; 214 } 215 data->state[SNDRV_PCM_STREAM_CAPTURE] = 216 GBAUDIO_CODEC_STARTUP; 217 dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid); 218 } 219 220 /* hw_params */ 221 if (module_state < GBAUDIO_CODEC_HWPARAMS) { 222 format = params->format; 223 channels = params->channels; 224 rate = params->rate; 225 sig_bits = params->sig_bits; 226 data_cport = data->connection->intf_cport_id; 227 ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport, 228 format, rate, channels, sig_bits); 229 if (ret) { 230 dev_err_ratelimited(module->dev, "set_pcm failed:%d\n", 231 ret); 232 return ret; 233 } 234 data->state[SNDRV_PCM_STREAM_CAPTURE] = 235 GBAUDIO_CODEC_HWPARAMS; 236 dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport); 237 } 238 239 /* prepare */ 240 if (module_state < GBAUDIO_CODEC_PREPARE) { 241 data_cport = data->connection->intf_cport_id; 242 ret = gb_audio_gb_set_rx_data_size(module->mgmt_connection, 243 data_cport, 192); 244 if (ret) { 245 dev_err_ratelimited(module->dev, 246 "set_rx_data_size failed:%d\n", 247 ret); 248 return ret; 249 } 250 ret = gb_audio_gb_activate_rx(module->mgmt_connection, 251 data_cport); 252 if (ret) { 253 dev_err_ratelimited(module->dev, 254 "activate_rx failed:%d\n", ret); 255 return ret; 256 } 257 data->state[SNDRV_PCM_STREAM_CAPTURE] = 258 GBAUDIO_CODEC_PREPARE; 259 dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport); 260 } 261 262 return 0; 263 } 264 265 static int gbaudio_module_disable_rx(struct gbaudio_module_info *module, int id) 266 { 267 int ret; 268 u16 data_cport, cportid, i2s_port; 269 int module_state; 270 struct gbaudio_data_connection *data; 271 272 /* find the dai */ 273 data = find_data(module, id); 274 if (!data) { 275 dev_err(module->dev, "%d:DATA connection missing\n", id); 276 return -ENODEV; 277 } 278 module_state = data->state[SNDRV_PCM_STREAM_CAPTURE]; 279 280 if (module_state > GBAUDIO_CODEC_HWPARAMS) { 281 data_cport = data->connection->intf_cport_id; 282 ret = gb_audio_gb_deactivate_rx(module->mgmt_connection, 283 data_cport); 284 if (ret) { 285 dev_err_ratelimited(module->dev, 286 "deactivate_rx failed:%d\n", ret); 287 return ret; 288 } 289 dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport); 290 data->state[SNDRV_PCM_STREAM_CAPTURE] = 291 GBAUDIO_CODEC_HWPARAMS; 292 } 293 294 if (module_state > GBAUDIO_CODEC_SHUTDOWN) { 295 i2s_port = 0; /* fixed for now */ 296 cportid = data->connection->hd_cport_id; 297 ret = gb_audio_apbridgea_unregister_cport(data->connection, 298 i2s_port, cportid, 299 AUDIO_APBRIDGEA_DIRECTION_RX); 300 if (ret) { 301 dev_err_ratelimited(module->dev, 302 "unregister_cport failed:%d\n", 303 ret); 304 return ret; 305 } 306 dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid); 307 data->state[SNDRV_PCM_STREAM_CAPTURE] = 308 GBAUDIO_CODEC_SHUTDOWN; 309 } 310 311 return 0; 312 } 313 314 int gbaudio_module_update(struct gbaudio_codec_info *codec, 315 struct snd_soc_dapm_widget *w, 316 struct gbaudio_module_info *module, int enable) 317 { 318 int dai_id, ret; 319 char intf_name[NAME_SIZE], dir[NAME_SIZE]; 320 321 dev_dbg(module->dev, "%s:Module update %s sequence\n", w->name, 322 enable ? "Enable" : "Disable"); 323 324 if ((w->id != snd_soc_dapm_aif_in) && (w->id != snd_soc_dapm_aif_out)) { 325 dev_dbg(codec->dev, "No action required for %s\n", w->name); 326 return 0; 327 } 328 329 /* parse dai_id from AIF widget's stream_name */ 330 ret = sscanf(w->sname, "%s %d %s", intf_name, &dai_id, dir); 331 if (ret < 3) { 332 dev_err(codec->dev, "Error while parsing dai_id for %s\n", 333 w->name); 334 return -EINVAL; 335 } 336 337 mutex_lock(&codec->lock); 338 if (w->id == snd_soc_dapm_aif_in) { 339 if (enable) 340 ret = gbaudio_module_enable_tx(codec, module, dai_id); 341 else 342 ret = gbaudio_module_disable_tx(module, dai_id); 343 } else if (w->id == snd_soc_dapm_aif_out) { 344 if (enable) 345 ret = gbaudio_module_enable_rx(codec, module, dai_id); 346 else 347 ret = gbaudio_module_disable_rx(module, dai_id); 348 } 349 350 mutex_unlock(&codec->lock); 351 352 return ret; 353 } 354 EXPORT_SYMBOL(gbaudio_module_update); 355 356 /* 357 * codec DAI ops 358 */ 359 static int gbcodec_startup(struct snd_pcm_substream *substream, 360 struct snd_soc_dai *dai) 361 { 362 struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev); 363 struct gbaudio_stream_params *params; 364 365 mutex_lock(&codec->lock); 366 367 if (list_empty(&codec->module_list)) { 368 dev_err(codec->dev, "No codec module available\n"); 369 mutex_unlock(&codec->lock); 370 return -ENODEV; 371 } 372 373 params = find_dai_stream_params(codec, dai->id, substream->stream); 374 if (!params) { 375 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n"); 376 mutex_unlock(&codec->lock); 377 return -EINVAL; 378 } 379 params->state = GBAUDIO_CODEC_STARTUP; 380 mutex_unlock(&codec->lock); 381 /* to prevent suspend in case of active audio */ 382 pm_stay_awake(dai->dev); 383 384 return 0; 385 } 386 387 static void gbcodec_shutdown(struct snd_pcm_substream *substream, 388 struct snd_soc_dai *dai) 389 { 390 struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev); 391 struct gbaudio_stream_params *params; 392 393 mutex_lock(&codec->lock); 394 395 if (list_empty(&codec->module_list)) 396 dev_info(codec->dev, "No codec module available during shutdown\n"); 397 398 params = find_dai_stream_params(codec, dai->id, substream->stream); 399 if (!params) { 400 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n"); 401 mutex_unlock(&codec->lock); 402 return; 403 } 404 params->state = GBAUDIO_CODEC_SHUTDOWN; 405 mutex_unlock(&codec->lock); 406 pm_relax(dai->dev); 407 } 408 409 static int gbcodec_hw_params(struct snd_pcm_substream *substream, 410 struct snd_pcm_hw_params *hwparams, 411 struct snd_soc_dai *dai) 412 { 413 int ret; 414 u8 sig_bits, channels; 415 u32 format, rate; 416 struct gbaudio_module_info *module; 417 struct gbaudio_data_connection *data; 418 struct gb_bundle *bundle; 419 struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev); 420 struct gbaudio_stream_params *params; 421 422 mutex_lock(&codec->lock); 423 424 if (list_empty(&codec->module_list)) { 425 dev_err(codec->dev, "No codec module available\n"); 426 mutex_unlock(&codec->lock); 427 return -ENODEV; 428 } 429 430 /* 431 * assuming, currently only 48000 Hz, 16BIT_LE, stereo 432 * is supported, validate params before configuring codec 433 */ 434 if (params_channels(hwparams) != 2) { 435 dev_err(dai->dev, "Invalid channel count:%d\n", 436 params_channels(hwparams)); 437 mutex_unlock(&codec->lock); 438 return -EINVAL; 439 } 440 channels = params_channels(hwparams); 441 442 if (params_rate(hwparams) != 48000) { 443 dev_err(dai->dev, "Invalid sampling rate:%d\n", 444 params_rate(hwparams)); 445 mutex_unlock(&codec->lock); 446 return -EINVAL; 447 } 448 rate = GB_AUDIO_PCM_RATE_48000; 449 450 if (params_format(hwparams) != SNDRV_PCM_FORMAT_S16_LE) { 451 dev_err(dai->dev, "Invalid format:%d\n", 452 params_format(hwparams)); 453 mutex_unlock(&codec->lock); 454 return -EINVAL; 455 } 456 format = GB_AUDIO_PCM_FMT_S16_LE; 457 458 /* find the data connection */ 459 list_for_each_entry(module, &codec->module_list, list) { 460 data = find_data(module, dai->id); 461 if (data) 462 break; 463 } 464 465 if (!data) { 466 dev_err(dai->dev, "DATA connection missing\n"); 467 mutex_unlock(&codec->lock); 468 return -EINVAL; 469 } 470 471 params = find_dai_stream_params(codec, dai->id, substream->stream); 472 if (!params) { 473 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n"); 474 mutex_unlock(&codec->lock); 475 return -EINVAL; 476 } 477 478 bundle = to_gb_bundle(module->dev); 479 ret = gb_pm_runtime_get_sync(bundle); 480 if (ret) { 481 mutex_unlock(&codec->lock); 482 return ret; 483 } 484 485 ret = gb_audio_apbridgea_set_config(data->connection, 0, 486 AUDIO_APBRIDGEA_PCM_FMT_16, 487 AUDIO_APBRIDGEA_PCM_RATE_48000, 488 6144000); 489 if (ret) { 490 dev_err_ratelimited(dai->dev, "%d: Error during set_config\n", 491 ret); 492 mutex_unlock(&codec->lock); 493 return ret; 494 } 495 496 gb_pm_runtime_put_noidle(bundle); 497 498 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 499 sig_bits = dai->driver->playback.sig_bits; 500 else 501 sig_bits = dai->driver->capture.sig_bits; 502 503 params->state = GBAUDIO_CODEC_HWPARAMS; 504 params->format = format; 505 params->rate = rate; 506 params->channels = channels; 507 params->sig_bits = sig_bits; 508 509 mutex_unlock(&codec->lock); 510 return 0; 511 } 512 513 static int gbcodec_prepare(struct snd_pcm_substream *substream, 514 struct snd_soc_dai *dai) 515 { 516 int ret; 517 struct gbaudio_module_info *module; 518 struct gbaudio_data_connection *data; 519 struct gb_bundle *bundle; 520 struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev); 521 struct gbaudio_stream_params *params; 522 523 mutex_lock(&codec->lock); 524 525 if (list_empty(&codec->module_list)) { 526 dev_err(codec->dev, "No codec module available\n"); 527 mutex_unlock(&codec->lock); 528 return -ENODEV; 529 } 530 531 list_for_each_entry(module, &codec->module_list, list) { 532 /* find the dai */ 533 data = find_data(module, dai->id); 534 if (data) 535 break; 536 } 537 if (!data) { 538 dev_err(dai->dev, "DATA connection missing\n"); 539 mutex_unlock(&codec->lock); 540 return -ENODEV; 541 } 542 543 params = find_dai_stream_params(codec, dai->id, substream->stream); 544 if (!params) { 545 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n"); 546 mutex_unlock(&codec->lock); 547 return -EINVAL; 548 } 549 550 bundle = to_gb_bundle(module->dev); 551 ret = gb_pm_runtime_get_sync(bundle); 552 if (ret) { 553 mutex_unlock(&codec->lock); 554 return ret; 555 } 556 557 switch (substream->stream) { 558 case SNDRV_PCM_STREAM_PLAYBACK: 559 ret = gb_audio_apbridgea_set_tx_data_size(data->connection, 0, 560 192); 561 break; 562 case SNDRV_PCM_STREAM_CAPTURE: 563 ret = gb_audio_apbridgea_set_rx_data_size(data->connection, 0, 564 192); 565 break; 566 } 567 if (ret) { 568 mutex_unlock(&codec->lock); 569 dev_err_ratelimited(dai->dev, "set_data_size failed:%d\n", 570 ret); 571 return ret; 572 } 573 574 gb_pm_runtime_put_noidle(bundle); 575 576 params->state = GBAUDIO_CODEC_PREPARE; 577 mutex_unlock(&codec->lock); 578 return 0; 579 } 580 581 static int gbcodec_mute_stream(struct snd_soc_dai *dai, int mute, int stream) 582 { 583 int ret; 584 struct gbaudio_data_connection *data; 585 struct gbaudio_module_info *module; 586 struct gb_bundle *bundle; 587 struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev); 588 struct gbaudio_stream_params *params; 589 590 dev_dbg(dai->dev, "Mute:%d, Direction:%s\n", mute, 591 stream ? "CAPTURE" : "PLAYBACK"); 592 593 mutex_lock(&codec->lock); 594 595 params = find_dai_stream_params(codec, dai->id, stream); 596 if (!params) { 597 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n"); 598 mutex_unlock(&codec->lock); 599 return -EINVAL; 600 } 601 602 if (list_empty(&codec->module_list)) { 603 dev_err(codec->dev, "No codec module available\n"); 604 if (mute) { 605 params->state = GBAUDIO_CODEC_STOP; 606 ret = 0; 607 } else { 608 ret = -ENODEV; 609 } 610 mutex_unlock(&codec->lock); 611 return ret; 612 } 613 614 list_for_each_entry(module, &codec->module_list, list) { 615 /* find the dai */ 616 data = find_data(module, dai->id); 617 if (data) 618 break; 619 } 620 if (!data) { 621 dev_err(dai->dev, "%s:%s DATA connection missing\n", 622 dai->name, module->name); 623 mutex_unlock(&codec->lock); 624 return -ENODEV; 625 } 626 627 bundle = to_gb_bundle(module->dev); 628 ret = gb_pm_runtime_get_sync(bundle); 629 if (ret) { 630 mutex_unlock(&codec->lock); 631 return ret; 632 } 633 634 if (!mute && !stream) {/* start playback */ 635 ret = gb_audio_apbridgea_prepare_tx(data->connection, 636 0); 637 if (!ret) 638 ret = gb_audio_apbridgea_start_tx(data->connection, 639 0, 0); 640 params->state = GBAUDIO_CODEC_START; 641 } else if (!mute && stream) {/* start capture */ 642 ret = gb_audio_apbridgea_prepare_rx(data->connection, 643 0); 644 if (!ret) 645 ret = gb_audio_apbridgea_start_rx(data->connection, 646 0); 647 params->state = GBAUDIO_CODEC_START; 648 } else if (mute && !stream) {/* stop playback */ 649 ret = gb_audio_apbridgea_stop_tx(data->connection, 0); 650 if (!ret) 651 ret = gb_audio_apbridgea_shutdown_tx(data->connection, 652 0); 653 params->state = GBAUDIO_CODEC_STOP; 654 } else if (mute && stream) {/* stop capture */ 655 ret = gb_audio_apbridgea_stop_rx(data->connection, 0); 656 if (!ret) 657 ret = gb_audio_apbridgea_shutdown_rx(data->connection, 658 0); 659 params->state = GBAUDIO_CODEC_STOP; 660 } else { 661 ret = -EINVAL; 662 } 663 664 if (ret) 665 dev_err_ratelimited(dai->dev, 666 "%s:Error during %s %s stream:%d\n", 667 module->name, mute ? "Mute" : "Unmute", 668 stream ? "Capture" : "Playback", ret); 669 670 gb_pm_runtime_put_noidle(bundle); 671 mutex_unlock(&codec->lock); 672 return ret; 673 } 674 675 static const struct snd_soc_dai_ops gbcodec_dai_ops = { 676 .startup = gbcodec_startup, 677 .shutdown = gbcodec_shutdown, 678 .hw_params = gbcodec_hw_params, 679 .prepare = gbcodec_prepare, 680 .mute_stream = gbcodec_mute_stream, 681 }; 682 683 static struct snd_soc_dai_driver gbaudio_dai[] = { 684 { 685 .name = "apb-i2s0", 686 .id = 0, 687 .playback = { 688 .stream_name = "I2S 0 Playback", 689 .rates = SNDRV_PCM_RATE_48000, 690 .formats = SNDRV_PCM_FORMAT_S16_LE, 691 .rate_max = 48000, 692 .rate_min = 48000, 693 .channels_min = 1, 694 .channels_max = 2, 695 .sig_bits = 16, 696 }, 697 .capture = { 698 .stream_name = "I2S 0 Capture", 699 .rates = SNDRV_PCM_RATE_48000, 700 .formats = SNDRV_PCM_FORMAT_S16_LE, 701 .rate_max = 48000, 702 .rate_min = 48000, 703 .channels_min = 1, 704 .channels_max = 2, 705 .sig_bits = 16, 706 }, 707 .ops = &gbcodec_dai_ops, 708 }, 709 }; 710 711 static int gbaudio_init_jack(struct gbaudio_module_info *module, 712 struct snd_soc_codec *codec) 713 { 714 int ret; 715 716 if (!module->jack_mask) 717 return 0; 718 719 snprintf(module->jack_name, NAME_SIZE, "GB %d Headset Jack", 720 module->dev_id); 721 ret = snd_soc_jack_new(codec, module->jack_name, module->jack_mask, 722 &module->headset_jack); 723 if (ret) { 724 dev_err(module->dev, "Failed to create new jack\n"); 725 return ret; 726 } 727 728 if (!module->button_mask) 729 return 0; 730 731 snprintf(module->button_name, NAME_SIZE, "GB %d Button Jack", 732 module->dev_id); 733 ret = snd_soc_jack_new(codec, module->button_name, module->button_mask, 734 &module->button_jack); 735 if (ret) { 736 dev_err(module->dev, "Failed to create button jack\n"); 737 return ret; 738 } 739 740 /* 741 * Currently, max 4 buttons are supported with following key mapping 742 * BTN_0 = KEY_MEDIA 743 * BTN_1 = KEY_VOICECOMMAND 744 * BTN_2 = KEY_VOLUMEUP 745 * BTN_3 = KEY_VOLUMEDOWN 746 */ 747 748 if (module->button_mask & SND_JACK_BTN_0) { 749 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_0, 750 KEY_MEDIA); 751 if (ret) { 752 dev_err(module->dev, "Failed to set BTN_0\n"); 753 return ret; 754 } 755 } 756 757 if (module->button_mask & SND_JACK_BTN_1) { 758 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_1, 759 KEY_VOICECOMMAND); 760 if (ret) { 761 dev_err(module->dev, "Failed to set BTN_1\n"); 762 return ret; 763 } 764 } 765 766 if (module->button_mask & SND_JACK_BTN_2) { 767 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_2, 768 KEY_VOLUMEUP); 769 if (ret) { 770 dev_err(module->dev, "Failed to set BTN_2\n"); 771 return ret; 772 } 773 } 774 775 if (module->button_mask & SND_JACK_BTN_3) { 776 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_3, 777 KEY_VOLUMEDOWN); 778 if (ret) { 779 dev_err(module->dev, "Failed to set BTN_0\n"); 780 return ret; 781 } 782 } 783 784 /* FIXME 785 * verify if this is really required 786 set_bit(INPUT_PROP_NO_DUMMY_RELEASE, 787 module->button_jack.jack->input_dev->propbit); 788 */ 789 790 return 0; 791 } 792 793 int gbaudio_register_module(struct gbaudio_module_info *module) 794 { 795 int ret; 796 struct snd_soc_codec *codec; 797 struct snd_card *card; 798 struct snd_soc_jack *jack = NULL; 799 800 if (!gbcodec) { 801 dev_err(module->dev, "GB Codec not yet probed\n"); 802 return -EAGAIN; 803 } 804 805 codec = gbcodec->codec; 806 card = codec->card->snd_card; 807 808 down_write(&card->controls_rwsem); 809 810 if (module->num_dais) { 811 dev_err(gbcodec->dev, 812 "%d:DAIs not supported via gbcodec driver\n", 813 module->num_dais); 814 up_write(&card->controls_rwsem); 815 return -EINVAL; 816 } 817 818 ret = gbaudio_init_jack(module, codec); 819 if (ret) { 820 up_write(&card->controls_rwsem); 821 return ret; 822 } 823 824 if (module->dapm_widgets) 825 snd_soc_dapm_new_controls(&codec->dapm, module->dapm_widgets, 826 module->num_dapm_widgets); 827 if (module->controls) 828 snd_soc_add_codec_controls(codec, module->controls, 829 module->num_controls); 830 if (module->dapm_routes) 831 snd_soc_dapm_add_routes(&codec->dapm, module->dapm_routes, 832 module->num_dapm_routes); 833 834 /* card already instantiated, create widgets here only */ 835 if (codec->card->instantiated) { 836 snd_soc_dapm_link_component_dai_widgets(codec->card, 837 &codec->dapm); 838 #ifdef CONFIG_SND_JACK 839 /* 840 * register jack devices for this module 841 * from codec->jack_list 842 */ 843 list_for_each_entry(jack, &codec->jack_list, list) { 844 if ((jack == &module->headset_jack) || 845 (jack == &module->button_jack)) 846 snd_device_register(codec->card->snd_card, 847 jack->jack); 848 } 849 #endif 850 } 851 852 mutex_lock(&gbcodec->lock); 853 list_add(&module->list, &gbcodec->module_list); 854 mutex_unlock(&gbcodec->lock); 855 856 if (codec->card->instantiated) 857 ret = snd_soc_dapm_new_widgets(&codec->dapm); 858 dev_dbg(codec->dev, "Registered %s module\n", module->name); 859 860 up_write(&card->controls_rwsem); 861 return ret; 862 } 863 EXPORT_SYMBOL(gbaudio_register_module); 864 865 static void gbaudio_codec_clean_data_tx(struct gbaudio_data_connection *data) 866 { 867 u16 i2s_port, cportid; 868 int ret; 869 870 if (list_is_singular(&gbcodec->module_list)) { 871 ret = gb_audio_apbridgea_stop_tx(data->connection, 0); 872 if (ret) 873 return; 874 ret = gb_audio_apbridgea_shutdown_tx(data->connection, 875 0); 876 if (ret) 877 return; 878 } 879 i2s_port = 0; /* fixed for now */ 880 cportid = data->connection->hd_cport_id; 881 ret = gb_audio_apbridgea_unregister_cport(data->connection, 882 i2s_port, cportid, 883 AUDIO_APBRIDGEA_DIRECTION_TX); 884 data->state[0] = GBAUDIO_CODEC_SHUTDOWN; 885 } 886 887 static void gbaudio_codec_clean_data_rx(struct gbaudio_data_connection *data) 888 { 889 u16 i2s_port, cportid; 890 int ret; 891 892 if (list_is_singular(&gbcodec->module_list)) { 893 ret = gb_audio_apbridgea_stop_rx(data->connection, 0); 894 if (ret) 895 return; 896 ret = gb_audio_apbridgea_shutdown_rx(data->connection, 897 0); 898 if (ret) 899 return; 900 } 901 i2s_port = 0; /* fixed for now */ 902 cportid = data->connection->hd_cport_id; 903 ret = gb_audio_apbridgea_unregister_cport(data->connection, 904 i2s_port, cportid, 905 AUDIO_APBRIDGEA_DIRECTION_RX); 906 data->state[1] = GBAUDIO_CODEC_SHUTDOWN; 907 } 908 909 static void gbaudio_codec_cleanup(struct gbaudio_module_info *module) 910 { 911 struct gbaudio_data_connection *data; 912 int pb_state, cap_state; 913 914 dev_dbg(gbcodec->dev, "%s: removed, cleanup APBridge\n", module->name); 915 list_for_each_entry(data, &module->data_list, list) { 916 pb_state = data->state[0]; 917 cap_state = data->state[1]; 918 919 if (pb_state > GBAUDIO_CODEC_SHUTDOWN) 920 gbaudio_codec_clean_data_tx(data); 921 922 if (cap_state > GBAUDIO_CODEC_SHUTDOWN) 923 gbaudio_codec_clean_data_rx(data); 924 } 925 } 926 927 void gbaudio_unregister_module(struct gbaudio_module_info *module) 928 { 929 struct snd_soc_codec *codec = gbcodec->codec; 930 struct snd_card *card = codec->card->snd_card; 931 struct snd_soc_jack *jack, *next_j; 932 int mask; 933 934 dev_dbg(codec->dev, "Unregister %s module\n", module->name); 935 936 down_write(&card->controls_rwsem); 937 mutex_lock(&gbcodec->lock); 938 gbaudio_codec_cleanup(module); 939 list_del(&module->list); 940 dev_dbg(codec->dev, "Process Unregister %s module\n", module->name); 941 mutex_unlock(&gbcodec->lock); 942 943 #ifdef CONFIG_SND_JACK 944 /* free jack devices for this module from codec->jack_list */ 945 list_for_each_entry_safe(jack, next_j, &codec->jack_list, list) { 946 if (jack == &module->headset_jack) 947 mask = GBCODEC_JACK_MASK; 948 else if (jack == &module->button_jack) 949 mask = GBCODEC_JACK_BUTTON_MASK; 950 else 951 mask = 0; 952 if (mask) { 953 dev_dbg(module->dev, "Report %s removal\n", 954 jack->jack->id); 955 snd_soc_jack_report(jack, 0, mask); 956 snd_device_free(codec->card->snd_card, jack->jack); 957 list_del(&jack->list); 958 } 959 } 960 #endif 961 962 if (module->dapm_routes) { 963 dev_dbg(codec->dev, "Removing %d routes\n", 964 module->num_dapm_routes); 965 snd_soc_dapm_del_routes(&codec->dapm, module->dapm_routes, 966 module->num_dapm_routes); 967 } 968 if (module->controls) { 969 dev_dbg(codec->dev, "Removing %d controls\n", 970 module->num_controls); 971 snd_soc_remove_codec_controls(codec, module->controls, 972 module->num_controls); 973 } 974 if (module->dapm_widgets) { 975 dev_dbg(codec->dev, "Removing %d widgets\n", 976 module->num_dapm_widgets); 977 snd_soc_dapm_free_controls(&codec->dapm, module->dapm_widgets, 978 module->num_dapm_widgets); 979 } 980 981 dev_dbg(codec->dev, "Unregistered %s module\n", module->name); 982 983 up_write(&card->controls_rwsem); 984 } 985 EXPORT_SYMBOL(gbaudio_unregister_module); 986 987 /* 988 * codec driver ops 989 */ 990 static int gbcodec_probe(struct snd_soc_codec *codec) 991 { 992 int i; 993 struct gbaudio_codec_info *info; 994 struct gbaudio_codec_dai *dai; 995 996 info = devm_kzalloc(codec->dev, sizeof(*info), GFP_KERNEL); 997 if (!info) 998 return -ENOMEM; 999 1000 info->dev = codec->dev; 1001 INIT_LIST_HEAD(&info->module_list); 1002 mutex_init(&info->lock); 1003 INIT_LIST_HEAD(&info->dai_list); 1004 1005 /* init dai_list used to maintain runtime stream info */ 1006 for (i = 0; i < ARRAY_SIZE(gbaudio_dai); i++) { 1007 dai = devm_kzalloc(codec->dev, sizeof(*dai), GFP_KERNEL); 1008 if (!dai) 1009 return -ENOMEM; 1010 dai->id = gbaudio_dai[i].id; 1011 list_add(&dai->list, &info->dai_list); 1012 } 1013 1014 info->codec = codec; 1015 snd_soc_codec_set_drvdata(codec, info); 1016 gbcodec = info; 1017 1018 device_init_wakeup(codec->dev, 1); 1019 return 0; 1020 } 1021 1022 static int gbcodec_remove(struct snd_soc_codec *codec) 1023 { 1024 /* Empty function for now */ 1025 return 0; 1026 } 1027 1028 static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg, 1029 unsigned int value) 1030 { 1031 return 0; 1032 } 1033 1034 static unsigned int gbcodec_read(struct snd_soc_codec *codec, 1035 unsigned int reg) 1036 { 1037 return 0; 1038 } 1039 1040 static struct snd_soc_codec_driver soc_codec_dev_gbaudio = { 1041 .probe = gbcodec_probe, 1042 .remove = gbcodec_remove, 1043 1044 .read = gbcodec_read, 1045 .write = gbcodec_write, 1046 1047 .idle_bias_off = true, 1048 .ignore_pmdown_time = 1, 1049 }; 1050 1051 #ifdef CONFIG_PM 1052 static int gbaudio_codec_suspend(struct device *dev) 1053 { 1054 dev_dbg(dev, "%s: suspend\n", __func__); 1055 return 0; 1056 } 1057 1058 static int gbaudio_codec_resume(struct device *dev) 1059 { 1060 dev_dbg(dev, "%s: resume\n", __func__); 1061 return 0; 1062 } 1063 1064 static const struct dev_pm_ops gbaudio_codec_pm_ops = { 1065 .suspend = gbaudio_codec_suspend, 1066 .resume = gbaudio_codec_resume, 1067 }; 1068 #endif 1069 1070 static int gbaudio_codec_probe(struct platform_device *pdev) 1071 { 1072 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_gbaudio, 1073 gbaudio_dai, ARRAY_SIZE(gbaudio_dai)); 1074 } 1075 1076 static int gbaudio_codec_remove(struct platform_device *pdev) 1077 { 1078 snd_soc_unregister_codec(&pdev->dev); 1079 return 0; 1080 } 1081 1082 static const struct of_device_id greybus_asoc_machine_of_match[] = { 1083 { .compatible = "toshiba,apb-dummy-codec", }, 1084 {}, 1085 }; 1086 1087 static struct platform_driver gbaudio_codec_driver = { 1088 .driver = { 1089 .name = "apb-dummy-codec", 1090 .owner = THIS_MODULE, 1091 #ifdef CONFIG_PM 1092 .pm = &gbaudio_codec_pm_ops, 1093 #endif 1094 .of_match_table = greybus_asoc_machine_of_match, 1095 }, 1096 .probe = gbaudio_codec_probe, 1097 .remove = gbaudio_codec_remove, 1098 }; 1099 module_platform_driver(gbaudio_codec_driver); 1100 1101 MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver"); 1102 MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>"); 1103 MODULE_LICENSE("GPL v2"); 1104 MODULE_ALIAS("platform:apb-dummy-codec"); 1105