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