linux/drivers/staging/greybus/audio_codec.c
<<
>>
Prefs
   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
  18static struct gbaudio_codec_info *gbcodec;
  19
  20static struct gbaudio_data_connection *
  21find_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
  32static struct gbaudio_stream_params *
  33find_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
  44static 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
 130static 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
 179static 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
 265static 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
 314int 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}
 354EXPORT_SYMBOL(gbaudio_module_update);
 355
 356/*
 357 * codec DAI ops
 358 */
 359static 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
 387static 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
 409static 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
 513static 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
 581static 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
 675static 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
 683static 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
 711static 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
 793int 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}
 863EXPORT_SYMBOL(gbaudio_register_module);
 864
 865static 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
 887static 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
 909static 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
 927void 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}
 985EXPORT_SYMBOL(gbaudio_unregister_module);
 986
 987/*
 988 * codec driver ops
 989 */
 990static 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
1022static int gbcodec_remove(struct snd_soc_codec *codec)
1023{
1024        /* Empty function for now */
1025        return 0;
1026}
1027
1028static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg,
1029                         unsigned int value)
1030{
1031        return 0;
1032}
1033
1034static unsigned int gbcodec_read(struct snd_soc_codec *codec,
1035                                 unsigned int reg)
1036{
1037        return 0;
1038}
1039
1040static 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
1052static int gbaudio_codec_suspend(struct device *dev)
1053{
1054        dev_dbg(dev, "%s: suspend\n", __func__);
1055        return 0;
1056}
1057
1058static int gbaudio_codec_resume(struct device *dev)
1059{
1060        dev_dbg(dev, "%s: resume\n", __func__);
1061        return 0;
1062}
1063
1064static const struct dev_pm_ops gbaudio_codec_pm_ops = {
1065        .suspend        = gbaudio_codec_suspend,
1066        .resume         = gbaudio_codec_resume,
1067};
1068#endif
1069
1070static 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
1076static int gbaudio_codec_remove(struct platform_device *pdev)
1077{
1078        snd_soc_unregister_codec(&pdev->dev);
1079        return 0;
1080}
1081
1082static const struct of_device_id greybus_asoc_machine_of_match[]  = {
1083        { .compatible = "toshiba,apb-dummy-codec", },
1084        {},
1085};
1086
1087static 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};
1098module_platform_driver(gbaudio_codec_driver);
1099
1100MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
1101MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
1102MODULE_LICENSE("GPL v2");
1103MODULE_ALIAS("platform:apb-dummy-codec");
1104