root/drivers/staging/greybus/audio_codec.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_data
  2. find_dai_stream_params
  3. gbaudio_module_enable_tx
  4. gbaudio_module_disable_tx
  5. gbaudio_module_enable_rx
  6. gbaudio_module_disable_rx
  7. gbaudio_module_update
  8. gbcodec_startup
  9. gbcodec_shutdown
  10. gbcodec_hw_params
  11. gbcodec_prepare
  12. gbcodec_mute_stream
  13. gbaudio_init_jack
  14. gbaudio_register_module
  15. gbaudio_codec_clean_data_tx
  16. gbaudio_codec_clean_data_rx
  17. gbaudio_codec_cleanup
  18. gbaudio_unregister_module
  19. gbcodec_probe
  20. gbcodec_remove
  21. gbcodec_write
  22. gbcodec_read
  23. gbaudio_codec_suspend
  24. gbaudio_codec_resume
  25. gbaudio_codec_probe
  26. gbaudio_codec_remove

   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 #ifdef CONFIG_PM
1091                 .pm = &gbaudio_codec_pm_ops,
1092 #endif
1093                 .of_match_table = greybus_asoc_machine_of_match,
1094         },
1095         .probe = gbaudio_codec_probe,
1096         .remove = gbaudio_codec_remove,
1097 };
1098 module_platform_driver(gbaudio_codec_driver);
1099 
1100 MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
1101 MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
1102 MODULE_LICENSE("GPL v2");
1103 MODULE_ALIAS("platform:apb-dummy-codec");

/* [<][>][^][v][top][bottom][index][help] */