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