Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * APBridge ALSA SoC dummy codec driver
0004  * Copyright 2016 Google Inc.
0005  * Copyright 2016 Linaro Ltd.
0006  */
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/pm_runtime.h>
0010 #include <sound/soc.h>
0011 #include <sound/pcm_params.h>
0012 #include <uapi/linux/input.h>
0013 
0014 #include "audio_codec.h"
0015 #include "audio_apbridgea.h"
0016 #include "audio_manager.h"
0017 #include "audio_helper.h"
0018 
0019 static struct gbaudio_codec_info *gbcodec;
0020 
0021 static struct gbaudio_data_connection *
0022 find_data(struct gbaudio_module_info *module, int id)
0023 {
0024     struct gbaudio_data_connection *data;
0025 
0026     list_for_each_entry(data, &module->data_list, list) {
0027         if (id == data->id)
0028             return data;
0029     }
0030     return NULL;
0031 }
0032 
0033 static struct gbaudio_stream_params *
0034 find_dai_stream_params(struct gbaudio_codec_info *codec, int id, int stream)
0035 {
0036     struct gbaudio_codec_dai *dai;
0037 
0038     list_for_each_entry(dai, &codec->dai_list, list) {
0039         if (dai->id == id)
0040             return &dai->params[stream];
0041     }
0042     return NULL;
0043 }
0044 
0045 static int gbaudio_module_enable_tx(struct gbaudio_codec_info *codec,
0046                     struct gbaudio_module_info *module, int id)
0047 {
0048     int module_state, ret = 0;
0049     u16 data_cport, i2s_port, cportid;
0050     u8 sig_bits, channels;
0051     u32 format, rate;
0052     struct gbaudio_data_connection *data;
0053     struct gbaudio_stream_params *params;
0054 
0055     /* find the dai */
0056     data = find_data(module, id);
0057     if (!data) {
0058         dev_err(module->dev, "%d:DATA connection missing\n", id);
0059         return -ENODEV;
0060     }
0061     module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK];
0062 
0063     params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_PLAYBACK);
0064     if (!params) {
0065         dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
0066         return -EINVAL;
0067     }
0068 
0069     /* register cport */
0070     if (module_state < GBAUDIO_CODEC_STARTUP) {
0071         i2s_port = 0;   /* fixed for now */
0072         cportid = data->connection->hd_cport_id;
0073         ret = gb_audio_apbridgea_register_cport(data->connection,
0074                             i2s_port, cportid,
0075                             AUDIO_APBRIDGEA_DIRECTION_TX);
0076         if (ret) {
0077             dev_err_ratelimited(module->dev, "reg_cport failed:%d\n", ret);
0078             return ret;
0079         }
0080         data->state[SNDRV_PCM_STREAM_PLAYBACK] = GBAUDIO_CODEC_STARTUP;
0081         dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid);
0082     }
0083 
0084     /* hw_params */
0085     if (module_state < GBAUDIO_CODEC_HWPARAMS) {
0086         format = params->format;
0087         channels = params->channels;
0088         rate = params->rate;
0089         sig_bits = params->sig_bits;
0090         data_cport = data->connection->intf_cport_id;
0091         ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport,
0092                       format, rate, channels, sig_bits);
0093         if (ret) {
0094             dev_err_ratelimited(module->dev, "set_pcm failed:%d\n", ret);
0095             return ret;
0096         }
0097         data->state[SNDRV_PCM_STREAM_PLAYBACK] = GBAUDIO_CODEC_HWPARAMS;
0098         dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport);
0099     }
0100 
0101     /* prepare */
0102     if (module_state < GBAUDIO_CODEC_PREPARE) {
0103         data_cport = data->connection->intf_cport_id;
0104         ret = gb_audio_gb_set_tx_data_size(module->mgmt_connection,
0105                            data_cport, 192);
0106         if (ret) {
0107             dev_err_ratelimited(module->dev,
0108                         "set_tx_data_size failed:%d\n",
0109                         ret);
0110             return ret;
0111         }
0112         ret = gb_audio_gb_activate_tx(module->mgmt_connection, data_cport);
0113         if (ret) {
0114             dev_err_ratelimited(module->dev,
0115                         "activate_tx failed:%d\n", ret);
0116             return ret;
0117         }
0118         data->state[SNDRV_PCM_STREAM_PLAYBACK] = GBAUDIO_CODEC_PREPARE;
0119         dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport);
0120     }
0121 
0122     return 0;
0123 }
0124 
0125 static int gbaudio_module_disable_tx(struct gbaudio_module_info *module, int id)
0126 {
0127     int ret;
0128     u16 data_cport, cportid, i2s_port;
0129     int module_state;
0130     struct gbaudio_data_connection *data;
0131 
0132     /* find the dai */
0133     data = find_data(module, id);
0134     if (!data) {
0135         dev_err(module->dev, "%d:DATA connection missing\n", id);
0136         return -ENODEV;
0137     }
0138     module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK];
0139 
0140     if (module_state > GBAUDIO_CODEC_HWPARAMS) {
0141         data_cport = data->connection->intf_cport_id;
0142         ret = gb_audio_gb_deactivate_tx(module->mgmt_connection,
0143                         data_cport);
0144         if (ret) {
0145             dev_err_ratelimited(module->dev,
0146                         "deactivate_tx failed:%d\n", ret);
0147             return ret;
0148         }
0149         dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport);
0150         data->state[SNDRV_PCM_STREAM_PLAYBACK] = GBAUDIO_CODEC_HWPARAMS;
0151     }
0152 
0153     if (module_state > GBAUDIO_CODEC_SHUTDOWN) {
0154         i2s_port = 0;   /* fixed for now */
0155         cportid = data->connection->hd_cport_id;
0156         ret = gb_audio_apbridgea_unregister_cport(data->connection,
0157                               i2s_port, cportid,
0158                               AUDIO_APBRIDGEA_DIRECTION_TX);
0159         if (ret) {
0160             dev_err_ratelimited(module->dev,
0161                         "unregister_cport failed:%d\n", ret);
0162             return ret;
0163         }
0164         dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid);
0165         data->state[SNDRV_PCM_STREAM_PLAYBACK] = GBAUDIO_CODEC_SHUTDOWN;
0166     }
0167 
0168     return 0;
0169 }
0170 
0171 static int gbaudio_module_enable_rx(struct gbaudio_codec_info *codec,
0172                     struct gbaudio_module_info *module, int id)
0173 {
0174     int module_state, ret = 0;
0175     u16 data_cport, i2s_port, cportid;
0176     u8 sig_bits, channels;
0177     u32 format, rate;
0178     struct gbaudio_data_connection *data;
0179     struct gbaudio_stream_params *params;
0180 
0181     /* find the dai */
0182     data = find_data(module, id);
0183     if (!data) {
0184         dev_err(module->dev, "%d:DATA connection missing\n", id);
0185         return -ENODEV;
0186     }
0187     module_state = data->state[SNDRV_PCM_STREAM_CAPTURE];
0188 
0189     params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_CAPTURE);
0190     if (!params) {
0191         dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
0192         return -EINVAL;
0193     }
0194 
0195     /* register cport */
0196     if (module_state < GBAUDIO_CODEC_STARTUP) {
0197         i2s_port = 0;   /* fixed for now */
0198         cportid = data->connection->hd_cport_id;
0199         ret = gb_audio_apbridgea_register_cport(data->connection,
0200                             i2s_port, cportid,
0201                             AUDIO_APBRIDGEA_DIRECTION_RX);
0202         if (ret) {
0203             dev_err_ratelimited(module->dev, "reg_cport failed:%d\n", ret);
0204             return ret;
0205         }
0206         data->state[SNDRV_PCM_STREAM_CAPTURE] = GBAUDIO_CODEC_STARTUP;
0207         dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid);
0208     }
0209 
0210     /* hw_params */
0211     if (module_state < GBAUDIO_CODEC_HWPARAMS) {
0212         format = params->format;
0213         channels = params->channels;
0214         rate = params->rate;
0215         sig_bits = params->sig_bits;
0216         data_cport = data->connection->intf_cport_id;
0217         ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport,
0218                       format, rate, channels, sig_bits);
0219         if (ret) {
0220             dev_err_ratelimited(module->dev, "set_pcm failed:%d\n", ret);
0221             return ret;
0222         }
0223         data->state[SNDRV_PCM_STREAM_CAPTURE] = GBAUDIO_CODEC_HWPARAMS;
0224         dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport);
0225     }
0226 
0227     /* prepare */
0228     if (module_state < GBAUDIO_CODEC_PREPARE) {
0229         data_cport = data->connection->intf_cport_id;
0230         ret = gb_audio_gb_set_rx_data_size(module->mgmt_connection,
0231                            data_cport, 192);
0232         if (ret) {
0233             dev_err_ratelimited(module->dev,
0234                         "set_rx_data_size failed:%d\n",
0235                         ret);
0236             return ret;
0237         }
0238         ret = gb_audio_gb_activate_rx(module->mgmt_connection,
0239                           data_cport);
0240         if (ret) {
0241             dev_err_ratelimited(module->dev,
0242                         "activate_rx failed:%d\n", ret);
0243             return ret;
0244         }
0245         data->state[SNDRV_PCM_STREAM_CAPTURE] = GBAUDIO_CODEC_PREPARE;
0246         dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport);
0247     }
0248 
0249     return 0;
0250 }
0251 
0252 static int gbaudio_module_disable_rx(struct gbaudio_module_info *module, int id)
0253 {
0254     int ret;
0255     u16 data_cport, cportid, i2s_port;
0256     int module_state;
0257     struct gbaudio_data_connection *data;
0258 
0259     /* find the dai */
0260     data = find_data(module, id);
0261     if (!data) {
0262         dev_err(module->dev, "%d:DATA connection missing\n", id);
0263         return -ENODEV;
0264     }
0265     module_state = data->state[SNDRV_PCM_STREAM_CAPTURE];
0266 
0267     if (module_state > GBAUDIO_CODEC_HWPARAMS) {
0268         data_cport = data->connection->intf_cport_id;
0269         ret = gb_audio_gb_deactivate_rx(module->mgmt_connection,
0270                         data_cport);
0271         if (ret) {
0272             dev_err_ratelimited(module->dev,
0273                         "deactivate_rx failed:%d\n", ret);
0274             return ret;
0275         }
0276         dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport);
0277         data->state[SNDRV_PCM_STREAM_CAPTURE] = GBAUDIO_CODEC_HWPARAMS;
0278     }
0279 
0280     if (module_state > GBAUDIO_CODEC_SHUTDOWN) {
0281         i2s_port = 0;   /* fixed for now */
0282         cportid = data->connection->hd_cport_id;
0283         ret = gb_audio_apbridgea_unregister_cport(data->connection,
0284                               i2s_port, cportid,
0285                               AUDIO_APBRIDGEA_DIRECTION_RX);
0286         if (ret) {
0287             dev_err_ratelimited(module->dev,
0288                         "unregister_cport failed:%d\n", ret);
0289             return ret;
0290         }
0291         dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid);
0292         data->state[SNDRV_PCM_STREAM_CAPTURE] = GBAUDIO_CODEC_SHUTDOWN;
0293     }
0294 
0295     return 0;
0296 }
0297 
0298 int gbaudio_module_update(struct gbaudio_codec_info *codec,
0299               struct snd_soc_dapm_widget *w,
0300               struct gbaudio_module_info *module, int enable)
0301 {
0302     int dai_id, ret;
0303     char intf_name[NAME_SIZE], dir[NAME_SIZE];
0304 
0305     dev_dbg(module->dev, "%s:Module update %s sequence\n", w->name,
0306         enable ? "Enable" : "Disable");
0307 
0308     if ((w->id != snd_soc_dapm_aif_in) && (w->id != snd_soc_dapm_aif_out)) {
0309         dev_dbg(codec->dev, "No action required for %s\n", w->name);
0310         return 0;
0311     }
0312 
0313     /* parse dai_id from AIF widget's stream_name */
0314     ret = sscanf(w->sname, "%s %d %s", intf_name, &dai_id, dir);
0315     if (ret < 3) {
0316         dev_err(codec->dev, "Error while parsing dai_id for %s\n", w->name);
0317         return -EINVAL;
0318     }
0319 
0320     mutex_lock(&codec->lock);
0321     if (w->id == snd_soc_dapm_aif_in) {
0322         if (enable)
0323             ret = gbaudio_module_enable_tx(codec, module, dai_id);
0324         else
0325             ret = gbaudio_module_disable_tx(module, dai_id);
0326     } else if (w->id == snd_soc_dapm_aif_out) {
0327         if (enable)
0328             ret = gbaudio_module_enable_rx(codec, module, dai_id);
0329         else
0330             ret = gbaudio_module_disable_rx(module, dai_id);
0331     }
0332 
0333     mutex_unlock(&codec->lock);
0334 
0335     return ret;
0336 }
0337 EXPORT_SYMBOL(gbaudio_module_update);
0338 
0339 /*
0340  * codec DAI ops
0341  */
0342 static int gbcodec_startup(struct snd_pcm_substream *substream,
0343                struct snd_soc_dai *dai)
0344 {
0345     struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
0346     struct gbaudio_stream_params *params;
0347 
0348     mutex_lock(&codec->lock);
0349 
0350     if (list_empty(&codec->module_list)) {
0351         dev_err(codec->dev, "No codec module available\n");
0352         mutex_unlock(&codec->lock);
0353         return -ENODEV;
0354     }
0355 
0356     params = find_dai_stream_params(codec, dai->id, substream->stream);
0357     if (!params) {
0358         dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
0359         mutex_unlock(&codec->lock);
0360         return -EINVAL;
0361     }
0362     params->state = GBAUDIO_CODEC_STARTUP;
0363     mutex_unlock(&codec->lock);
0364     /* to prevent suspend in case of active audio */
0365     pm_stay_awake(dai->dev);
0366 
0367     return 0;
0368 }
0369 
0370 static void gbcodec_shutdown(struct snd_pcm_substream *substream,
0371                  struct snd_soc_dai *dai)
0372 {
0373     struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
0374     struct gbaudio_stream_params *params;
0375 
0376     mutex_lock(&codec->lock);
0377 
0378     if (list_empty(&codec->module_list))
0379         dev_info(codec->dev, "No codec module available during shutdown\n");
0380 
0381     params = find_dai_stream_params(codec, dai->id, substream->stream);
0382     if (!params) {
0383         dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
0384         mutex_unlock(&codec->lock);
0385         return;
0386     }
0387     params->state = GBAUDIO_CODEC_SHUTDOWN;
0388     mutex_unlock(&codec->lock);
0389     pm_relax(dai->dev);
0390 }
0391 
0392 static int gbcodec_hw_params(struct snd_pcm_substream *substream,
0393                  struct snd_pcm_hw_params *hwparams,
0394                  struct snd_soc_dai *dai)
0395 {
0396     int ret;
0397     u8 sig_bits, channels;
0398     u32 format, rate;
0399     struct gbaudio_module_info *module;
0400     struct gbaudio_data_connection *data;
0401     struct gb_bundle *bundle;
0402     struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
0403     struct gbaudio_stream_params *params;
0404 
0405     mutex_lock(&codec->lock);
0406 
0407     if (list_empty(&codec->module_list)) {
0408         dev_err(codec->dev, "No codec module available\n");
0409         mutex_unlock(&codec->lock);
0410         return -ENODEV;
0411     }
0412 
0413     /*
0414      * assuming, currently only 48000 Hz, 16BIT_LE, stereo
0415      * is supported, validate params before configuring codec
0416      */
0417     if (params_channels(hwparams) != 2) {
0418         dev_err(dai->dev, "Invalid channel count:%d\n",
0419             params_channels(hwparams));
0420         mutex_unlock(&codec->lock);
0421         return -EINVAL;
0422     }
0423     channels = params_channels(hwparams);
0424 
0425     if (params_rate(hwparams) != 48000) {
0426         dev_err(dai->dev, "Invalid sampling rate:%d\n",
0427             params_rate(hwparams));
0428         mutex_unlock(&codec->lock);
0429         return -EINVAL;
0430     }
0431     rate = GB_AUDIO_PCM_RATE_48000;
0432 
0433     if (params_format(hwparams) != SNDRV_PCM_FORMAT_S16_LE) {
0434         dev_err(dai->dev, "Invalid format:%d\n", params_format(hwparams));
0435         mutex_unlock(&codec->lock);
0436         return -EINVAL;
0437     }
0438     format = GB_AUDIO_PCM_FMT_S16_LE;
0439 
0440     /* find the data connection */
0441     list_for_each_entry(module, &codec->module_list, list) {
0442         data = find_data(module, dai->id);
0443         if (data)
0444             break;
0445     }
0446 
0447     if (!data) {
0448         dev_err(dai->dev, "DATA connection missing\n");
0449         mutex_unlock(&codec->lock);
0450         return -EINVAL;
0451     }
0452 
0453     params = find_dai_stream_params(codec, dai->id, substream->stream);
0454     if (!params) {
0455         dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
0456         mutex_unlock(&codec->lock);
0457         return -EINVAL;
0458     }
0459 
0460     bundle = to_gb_bundle(module->dev);
0461     ret = gb_pm_runtime_get_sync(bundle);
0462     if (ret) {
0463         mutex_unlock(&codec->lock);
0464         return ret;
0465     }
0466 
0467     ret = gb_audio_apbridgea_set_config(data->connection, 0,
0468                         AUDIO_APBRIDGEA_PCM_FMT_16,
0469                         AUDIO_APBRIDGEA_PCM_RATE_48000,
0470                         6144000);
0471     if (ret) {
0472         dev_err_ratelimited(dai->dev, "%d: Error during set_config\n",
0473                     ret);
0474         gb_pm_runtime_put_noidle(bundle);
0475         mutex_unlock(&codec->lock);
0476         return ret;
0477     }
0478 
0479     gb_pm_runtime_put_noidle(bundle);
0480 
0481     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0482         sig_bits = dai->driver->playback.sig_bits;
0483     else
0484         sig_bits = dai->driver->capture.sig_bits;
0485 
0486     params->state = GBAUDIO_CODEC_HWPARAMS;
0487     params->format = format;
0488     params->rate = rate;
0489     params->channels = channels;
0490     params->sig_bits = sig_bits;
0491 
0492     mutex_unlock(&codec->lock);
0493     return 0;
0494 }
0495 
0496 static int gbcodec_prepare(struct snd_pcm_substream *substream,
0497                struct snd_soc_dai *dai)
0498 {
0499     int ret;
0500     struct gbaudio_module_info *module = NULL, *iter;
0501     struct gbaudio_data_connection *data;
0502     struct gb_bundle *bundle;
0503     struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
0504     struct gbaudio_stream_params *params;
0505 
0506     mutex_lock(&codec->lock);
0507 
0508     if (list_empty(&codec->module_list)) {
0509         dev_err(codec->dev, "No codec module available\n");
0510         mutex_unlock(&codec->lock);
0511         return -ENODEV;
0512     }
0513 
0514     list_for_each_entry(iter, &codec->module_list, list) {
0515         /* find the dai */
0516         data = find_data(iter, dai->id);
0517         if (data) {
0518             module = iter;
0519             break;
0520         }
0521     }
0522     if (!data) {
0523         dev_err(dai->dev, "DATA connection missing\n");
0524         mutex_unlock(&codec->lock);
0525         return -ENODEV;
0526     }
0527 
0528     params = find_dai_stream_params(codec, dai->id, substream->stream);
0529     if (!params) {
0530         dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
0531         mutex_unlock(&codec->lock);
0532         return -EINVAL;
0533     }
0534 
0535     bundle = to_gb_bundle(module->dev);
0536     ret = gb_pm_runtime_get_sync(bundle);
0537     if (ret) {
0538         mutex_unlock(&codec->lock);
0539         return ret;
0540     }
0541 
0542     switch (substream->stream) {
0543     case SNDRV_PCM_STREAM_PLAYBACK:
0544         ret = gb_audio_apbridgea_set_tx_data_size(data->connection, 0, 192);
0545         break;
0546     case SNDRV_PCM_STREAM_CAPTURE:
0547         ret = gb_audio_apbridgea_set_rx_data_size(data->connection, 0, 192);
0548         break;
0549     }
0550     if (ret) {
0551         gb_pm_runtime_put_noidle(bundle);
0552         mutex_unlock(&codec->lock);
0553         dev_err_ratelimited(dai->dev, "set_data_size failed:%d\n", ret);
0554         return ret;
0555     }
0556 
0557     gb_pm_runtime_put_noidle(bundle);
0558 
0559     params->state = GBAUDIO_CODEC_PREPARE;
0560     mutex_unlock(&codec->lock);
0561     return 0;
0562 }
0563 
0564 static int gbcodec_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
0565 {
0566     int ret;
0567     struct gbaudio_data_connection *data;
0568     struct gbaudio_module_info *module = NULL, *iter;
0569     struct gb_bundle *bundle;
0570     struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
0571     struct gbaudio_stream_params *params;
0572 
0573     dev_dbg(dai->dev, "Mute:%d, Direction:%s\n", mute,
0574         stream ? "CAPTURE" : "PLAYBACK");
0575 
0576     mutex_lock(&codec->lock);
0577 
0578     params = find_dai_stream_params(codec, dai->id, stream);
0579     if (!params) {
0580         dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
0581         mutex_unlock(&codec->lock);
0582         return -EINVAL;
0583     }
0584 
0585     if (list_empty(&codec->module_list)) {
0586         dev_err(codec->dev, "No codec module available\n");
0587         if (mute) {
0588             params->state = GBAUDIO_CODEC_STOP;
0589             ret = 0;
0590         } else {
0591             ret = -ENODEV;
0592         }
0593         mutex_unlock(&codec->lock);
0594         return ret;
0595     }
0596 
0597     list_for_each_entry(iter, &codec->module_list, list) {
0598         /* find the dai */
0599         data = find_data(iter, dai->id);
0600         if (data) {
0601             module = iter;
0602             break;
0603         }
0604     }
0605     if (!data) {
0606         dev_err(dai->dev, "%s DATA connection missing\n",
0607             dai->name);
0608         mutex_unlock(&codec->lock);
0609         return -ENODEV;
0610     }
0611 
0612     bundle = to_gb_bundle(module->dev);
0613     ret = gb_pm_runtime_get_sync(bundle);
0614     if (ret) {
0615         mutex_unlock(&codec->lock);
0616         return ret;
0617     }
0618 
0619     if (!mute && !stream) {/* start playback */
0620         ret = gb_audio_apbridgea_prepare_tx(data->connection, 0);
0621         if (!ret)
0622             ret = gb_audio_apbridgea_start_tx(data->connection, 0, 0);
0623         params->state = GBAUDIO_CODEC_START;
0624     } else if (!mute && stream) {/* start capture */
0625         ret = gb_audio_apbridgea_prepare_rx(data->connection, 0);
0626         if (!ret)
0627             ret = gb_audio_apbridgea_start_rx(data->connection, 0);
0628         params->state = GBAUDIO_CODEC_START;
0629     } else if (mute && !stream) {/* stop playback */
0630         ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
0631         if (!ret)
0632             ret = gb_audio_apbridgea_shutdown_tx(data->connection, 0);
0633         params->state = GBAUDIO_CODEC_STOP;
0634     } else if (mute && stream) {/* stop capture */
0635         ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
0636         if (!ret)
0637             ret = gb_audio_apbridgea_shutdown_rx(data->connection, 0);
0638         params->state = GBAUDIO_CODEC_STOP;
0639     } else {
0640         ret = -EINVAL;
0641     }
0642 
0643     if (ret)
0644         dev_err_ratelimited(dai->dev,
0645                     "%s:Error during %s %s stream:%d\n",
0646                     module->name, mute ? "Mute" : "Unmute",
0647                     stream ? "Capture" : "Playback", ret);
0648 
0649     gb_pm_runtime_put_noidle(bundle);
0650     mutex_unlock(&codec->lock);
0651     return ret;
0652 }
0653 
0654 static const struct snd_soc_dai_ops gbcodec_dai_ops = {
0655     .startup = gbcodec_startup,
0656     .shutdown = gbcodec_shutdown,
0657     .hw_params = gbcodec_hw_params,
0658     .prepare = gbcodec_prepare,
0659     .mute_stream = gbcodec_mute_stream,
0660 };
0661 
0662 static struct snd_soc_dai_driver gbaudio_dai[] = {
0663     {
0664         .name = "apb-i2s0",
0665         .id = 0,
0666         .playback = {
0667             .stream_name = "I2S 0 Playback",
0668             .rates = SNDRV_PCM_RATE_48000,
0669             .formats = SNDRV_PCM_FMTBIT_S16_LE,
0670             .rate_max = 48000,
0671             .rate_min = 48000,
0672             .channels_min = 1,
0673             .channels_max = 2,
0674             .sig_bits = 16,
0675         },
0676         .capture = {
0677             .stream_name = "I2S 0 Capture",
0678             .rates = SNDRV_PCM_RATE_48000,
0679             .formats = SNDRV_PCM_FMTBIT_S16_LE,
0680             .rate_max = 48000,
0681             .rate_min = 48000,
0682             .channels_min = 1,
0683             .channels_max = 2,
0684             .sig_bits = 16,
0685         },
0686         .ops = &gbcodec_dai_ops,
0687     },
0688 };
0689 
0690 static int gbaudio_init_jack(struct gbaudio_module_info *module,
0691                  struct snd_soc_card *card)
0692 {
0693     int ret;
0694     struct gbaudio_jack *jack, *n;
0695     struct snd_soc_jack_pin *headset, *button;
0696 
0697     if (!module->jack_mask)
0698         return 0;
0699 
0700     snprintf(module->jack_name, NAME_SIZE, "GB %d Headset Jack",
0701          module->dev_id);
0702 
0703     headset = devm_kzalloc(module->dev, sizeof(*headset), GFP_KERNEL);
0704     if (!headset)
0705         return -ENOMEM;
0706 
0707     headset->pin = module->jack_name;
0708     headset->mask = module->jack_mask;
0709     ret = snd_soc_card_jack_new_pins(card, module->jack_name,
0710                      module->jack_mask,
0711                      &module->headset.jack, headset, 1);
0712     if (ret) {
0713         dev_err(module->dev, "Failed to create new jack\n");
0714         return ret;
0715     }
0716 
0717     /* Add to module's jack list */
0718     list_add(&module->headset.list, &module->jack_list);
0719 
0720     if (!module->button_mask)
0721         return 0;
0722 
0723     snprintf(module->button_name, NAME_SIZE, "GB %d Button Jack",
0724          module->dev_id);
0725     button = devm_kzalloc(module->dev, sizeof(*button), GFP_KERNEL);
0726     if (!button) {
0727         ret = -ENOMEM;
0728         goto free_jacks;
0729     }
0730 
0731     button->pin = module->button_name;
0732     button->mask = module->button_mask;
0733     ret = snd_soc_card_jack_new_pins(card, module->button_name,
0734                      module->button_mask,
0735                      &module->button.jack,
0736                      button, 1);
0737     if (ret) {
0738         dev_err(module->dev, "Failed to create button jack\n");
0739         goto free_jacks;
0740     }
0741 
0742     /* Add to module's jack list */
0743     list_add(&module->button.list, &module->jack_list);
0744 
0745     /*
0746      * Currently, max 4 buttons are supported with following key mapping
0747      * BTN_0 = KEY_MEDIA
0748      * BTN_1 = KEY_VOICECOMMAND
0749      * BTN_2 = KEY_VOLUMEUP
0750      * BTN_3 = KEY_VOLUMEDOWN
0751      */
0752 
0753     if (module->button_mask & SND_JACK_BTN_0) {
0754         ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_0,
0755                        KEY_MEDIA);
0756         if (ret) {
0757             dev_err(module->dev, "Failed to set BTN_0\n");
0758             goto free_jacks;
0759         }
0760     }
0761 
0762     if (module->button_mask & SND_JACK_BTN_1) {
0763         ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_1,
0764                        KEY_VOICECOMMAND);
0765         if (ret) {
0766             dev_err(module->dev, "Failed to set BTN_1\n");
0767             goto free_jacks;
0768         }
0769     }
0770 
0771     if (module->button_mask & SND_JACK_BTN_2) {
0772         ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_2,
0773                        KEY_VOLUMEUP);
0774         if (ret) {
0775             dev_err(module->dev, "Failed to set BTN_2\n");
0776             goto free_jacks;
0777         }
0778     }
0779 
0780     if (module->button_mask & SND_JACK_BTN_3) {
0781         ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_3,
0782                        KEY_VOLUMEDOWN);
0783         if (ret) {
0784             dev_err(module->dev, "Failed to set BTN_0\n");
0785             goto free_jacks;
0786         }
0787     }
0788 
0789     /* FIXME
0790      * verify if this is really required
0791     set_bit(INPUT_PROP_NO_DUMMY_RELEASE,
0792         module->button.jack.jack->input_dev->propbit);
0793     */
0794 
0795     return 0;
0796 
0797 free_jacks:
0798     list_for_each_entry_safe(jack, n, &module->jack_list, list) {
0799         snd_device_free(card->snd_card, jack->jack.jack);
0800         list_del(&jack->list);
0801     }
0802 
0803     return ret;
0804 }
0805 
0806 int gbaudio_register_module(struct gbaudio_module_info *module)
0807 {
0808     int ret;
0809     struct snd_soc_component *comp;
0810     struct snd_card *card;
0811     struct gbaudio_jack *jack = NULL;
0812 
0813     if (!gbcodec) {
0814         dev_err(module->dev, "GB Codec not yet probed\n");
0815         return -EAGAIN;
0816     }
0817 
0818     comp = gbcodec->component;
0819     card = comp->card->snd_card;
0820 
0821     down_write(&card->controls_rwsem);
0822 
0823     if (module->num_dais) {
0824         dev_err(gbcodec->dev,
0825             "%d:DAIs not supported via gbcodec driver\n",
0826             module->num_dais);
0827         up_write(&card->controls_rwsem);
0828         return -EINVAL;
0829     }
0830 
0831     ret = gbaudio_init_jack(module, comp->card);
0832     if (ret) {
0833         up_write(&card->controls_rwsem);
0834         return ret;
0835     }
0836 
0837     if (module->dapm_widgets)
0838         snd_soc_dapm_new_controls(&comp->dapm, module->dapm_widgets,
0839                       module->num_dapm_widgets);
0840     if (module->controls)
0841         snd_soc_add_component_controls(comp, module->controls,
0842                            module->num_controls);
0843     if (module->dapm_routes)
0844         snd_soc_dapm_add_routes(&comp->dapm, module->dapm_routes,
0845                     module->num_dapm_routes);
0846 
0847     /* card already instantiated, create widgets here only */
0848     if (comp->card->instantiated) {
0849         gbaudio_dapm_link_component_dai_widgets(comp->card, &comp->dapm);
0850 #ifdef CONFIG_SND_JACK
0851         /*
0852          * register jack devices for this module
0853          * from codec->jack_list
0854          */
0855         list_for_each_entry(jack, &module->jack_list, list) {
0856             snd_device_register(comp->card->snd_card,
0857                         jack->jack.jack);
0858         }
0859 #endif
0860     }
0861 
0862     mutex_lock(&gbcodec->lock);
0863     list_add(&module->list, &gbcodec->module_list);
0864     mutex_unlock(&gbcodec->lock);
0865 
0866     if (comp->card->instantiated)
0867         ret = snd_soc_dapm_new_widgets(comp->card);
0868     dev_dbg(comp->dev, "Registered %s module\n", module->name);
0869 
0870     up_write(&card->controls_rwsem);
0871     return ret;
0872 }
0873 EXPORT_SYMBOL(gbaudio_register_module);
0874 
0875 static void gbaudio_codec_clean_data_tx(struct gbaudio_data_connection *data)
0876 {
0877     u16 i2s_port, cportid;
0878     int ret;
0879 
0880     if (list_is_singular(&gbcodec->module_list)) {
0881         ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
0882         if (ret)
0883             return;
0884         ret = gb_audio_apbridgea_shutdown_tx(data->connection, 0);
0885         if (ret)
0886             return;
0887     }
0888     i2s_port = 0;   /* fixed for now */
0889     cportid = data->connection->hd_cport_id;
0890     ret = gb_audio_apbridgea_unregister_cport(data->connection,
0891                           i2s_port, cportid,
0892                           AUDIO_APBRIDGEA_DIRECTION_TX);
0893     data->state[0] = GBAUDIO_CODEC_SHUTDOWN;
0894 }
0895 
0896 static void gbaudio_codec_clean_data_rx(struct gbaudio_data_connection *data)
0897 {
0898     u16 i2s_port, cportid;
0899     int ret;
0900 
0901     if (list_is_singular(&gbcodec->module_list)) {
0902         ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
0903         if (ret)
0904             return;
0905         ret = gb_audio_apbridgea_shutdown_rx(data->connection, 0);
0906         if (ret)
0907             return;
0908     }
0909     i2s_port = 0;   /* fixed for now */
0910     cportid = data->connection->hd_cport_id;
0911     ret = gb_audio_apbridgea_unregister_cport(data->connection,
0912                           i2s_port, cportid,
0913                           AUDIO_APBRIDGEA_DIRECTION_RX);
0914     data->state[1] = GBAUDIO_CODEC_SHUTDOWN;
0915 }
0916 
0917 static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
0918 {
0919     struct gbaudio_data_connection *data;
0920     int pb_state, cap_state;
0921 
0922     dev_dbg(gbcodec->dev, "%s: removed, cleanup APBridge\n", module->name);
0923     list_for_each_entry(data, &module->data_list, list) {
0924         pb_state = data->state[0];
0925         cap_state = data->state[1];
0926 
0927         if (pb_state > GBAUDIO_CODEC_SHUTDOWN)
0928             gbaudio_codec_clean_data_tx(data);
0929 
0930         if (cap_state > GBAUDIO_CODEC_SHUTDOWN)
0931             gbaudio_codec_clean_data_rx(data);
0932     }
0933 }
0934 
0935 void gbaudio_unregister_module(struct gbaudio_module_info *module)
0936 {
0937     struct snd_soc_component *comp = gbcodec->component;
0938     struct snd_card *card = comp->card->snd_card;
0939     struct gbaudio_jack *jack, *n;
0940     int mask;
0941 
0942     dev_dbg(comp->dev, "Unregister %s module\n", module->name);
0943 
0944     down_write(&card->controls_rwsem);
0945     mutex_lock(&gbcodec->lock);
0946     gbaudio_codec_cleanup(module);
0947     list_del(&module->list);
0948     dev_dbg(comp->dev, "Process Unregister %s module\n", module->name);
0949     mutex_unlock(&gbcodec->lock);
0950 
0951 #ifdef CONFIG_SND_JACK
0952     /* free jack devices for this module jack_list */
0953     list_for_each_entry_safe(jack, n, &module->jack_list, list) {
0954         if (jack == &module->headset)
0955             mask = GBCODEC_JACK_MASK;
0956         else if (jack == &module->button)
0957             mask = GBCODEC_JACK_BUTTON_MASK;
0958         else
0959             mask = 0;
0960         if (mask) {
0961             dev_dbg(module->dev, "Report %s removal\n",
0962                 jack->jack.jack->id);
0963             snd_soc_jack_report(&jack->jack, 0, mask);
0964             snd_device_free(comp->card->snd_card,
0965                     jack->jack.jack);
0966             list_del(&jack->list);
0967         }
0968     }
0969 #endif
0970 
0971     if (module->dapm_routes) {
0972         dev_dbg(comp->dev, "Removing %d routes\n",
0973             module->num_dapm_routes);
0974         snd_soc_dapm_del_routes(&comp->dapm, module->dapm_routes,
0975                     module->num_dapm_routes);
0976     }
0977     if (module->controls) {
0978         dev_dbg(comp->dev, "Removing %d controls\n",
0979             module->num_controls);
0980         /* release control semaphore */
0981         up_write(&card->controls_rwsem);
0982         gbaudio_remove_component_controls(comp, module->controls,
0983                           module->num_controls);
0984         down_write(&card->controls_rwsem);
0985     }
0986     if (module->dapm_widgets) {
0987         dev_dbg(comp->dev, "Removing %d widgets\n",
0988             module->num_dapm_widgets);
0989         gbaudio_dapm_free_controls(&comp->dapm, module->dapm_widgets,
0990                        module->num_dapm_widgets);
0991     }
0992 
0993     dev_dbg(comp->dev, "Unregistered %s module\n", module->name);
0994 
0995     up_write(&card->controls_rwsem);
0996 }
0997 EXPORT_SYMBOL(gbaudio_unregister_module);
0998 
0999 /*
1000  * component driver ops
1001  */
1002 static int gbcodec_probe(struct snd_soc_component *comp)
1003 {
1004     int i;
1005     struct gbaudio_codec_info *info;
1006     struct gbaudio_codec_dai *dai;
1007 
1008     info = devm_kzalloc(comp->dev, sizeof(*info), GFP_KERNEL);
1009     if (!info)
1010         return -ENOMEM;
1011 
1012     info->dev = comp->dev;
1013     INIT_LIST_HEAD(&info->module_list);
1014     mutex_init(&info->lock);
1015     INIT_LIST_HEAD(&info->dai_list);
1016 
1017     /* init dai_list used to maintain runtime stream info */
1018     for (i = 0; i < ARRAY_SIZE(gbaudio_dai); i++) {
1019         dai = devm_kzalloc(comp->dev, sizeof(*dai), GFP_KERNEL);
1020         if (!dai)
1021             return -ENOMEM;
1022         dai->id = gbaudio_dai[i].id;
1023         list_add(&dai->list, &info->dai_list);
1024     }
1025 
1026     info->component = comp;
1027     snd_soc_component_set_drvdata(comp, info);
1028     gbcodec = info;
1029 
1030     device_init_wakeup(comp->dev, 1);
1031     return 0;
1032 }
1033 
1034 static int gbcodec_write(struct snd_soc_component *comp, unsigned int reg,
1035              unsigned int value)
1036 {
1037     return 0;
1038 }
1039 
1040 static unsigned int gbcodec_read(struct snd_soc_component *comp,
1041                  unsigned int reg)
1042 {
1043     return 0;
1044 }
1045 
1046 static const struct snd_soc_component_driver soc_codec_dev_gbaudio = {
1047     .probe  = gbcodec_probe,
1048     .read = gbcodec_read,
1049     .write = gbcodec_write,
1050 };
1051 
1052 #ifdef CONFIG_PM
1053 static int gbaudio_codec_suspend(struct device *dev)
1054 {
1055     dev_dbg(dev, "%s: suspend\n", __func__);
1056     return 0;
1057 }
1058 
1059 static int gbaudio_codec_resume(struct device *dev)
1060 {
1061     dev_dbg(dev, "%s: resume\n", __func__);
1062     return 0;
1063 }
1064 
1065 static const struct dev_pm_ops gbaudio_codec_pm_ops = {
1066     .suspend    = gbaudio_codec_suspend,
1067     .resume     = gbaudio_codec_resume,
1068 };
1069 #endif
1070 
1071 static int gbaudio_codec_probe(struct platform_device *pdev)
1072 {
1073     return devm_snd_soc_register_component(&pdev->dev,
1074             &soc_codec_dev_gbaudio,
1075             gbaudio_dai, ARRAY_SIZE(gbaudio_dai));
1076 }
1077 
1078 static int gbaudio_codec_remove(struct platform_device *pdev)
1079 {
1080     return 0;
1081 }
1082 
1083 static const struct of_device_id greybus_asoc_machine_of_match[]  = {
1084     { .compatible = "toshiba,apb-dummy-codec", },
1085     {},
1086 };
1087 
1088 static struct platform_driver gbaudio_codec_driver = {
1089     .driver = {
1090         .name = "apb-dummy-codec",
1091 #ifdef CONFIG_PM
1092         .pm = &gbaudio_codec_pm_ops,
1093 #endif
1094         .of_match_table = greybus_asoc_machine_of_match,
1095     },
1096     .probe = gbaudio_codec_probe,
1097     .remove = gbaudio_codec_remove,
1098 };
1099 module_platform_driver(gbaudio_codec_driver);
1100 
1101 MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
1102 MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
1103 MODULE_LICENSE("GPL v2");
1104 MODULE_ALIAS("platform:apb-dummy-codec");