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