]> Git Repo - linux.git/blob - drivers/staging/greybus/audio_codec.c
Merge tag 'acpi-fix-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[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         uint32_t 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         uint32_t 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         uint32_t 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
591         dev_dbg(dai->dev, "Mute:%d, Direction:%s\n", mute,
592                 stream ? "CAPTURE":"PLAYBACK");
593
594         mutex_lock(&codec->lock);
595
596         params = find_dai_stream_params(codec, dai->id, stream);
597         if (!params) {
598                 dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
599                 mutex_unlock(&codec->lock);
600                 return -EINVAL;
601         }
602
603         if (list_empty(&codec->module_list)) {
604                 dev_err(codec->dev, "No codec module available\n");
605                 if (mute) {
606                         params->state = GBAUDIO_CODEC_STOP;
607                         ret = 0;
608                 } else {
609                         ret = -ENODEV;
610                 }
611                 mutex_unlock(&codec->lock);
612                 return ret;
613         }
614
615         list_for_each_entry(module, &codec->module_list, list) {
616                 /* find the dai */
617                 data = find_data(module, dai->id);
618                 if (data)
619                         break;
620         }
621         if (!data) {
622                 dev_err(dai->dev, "%s:%s DATA connection missing\n",
623                         dai->name, module->name);
624                 mutex_unlock(&codec->lock);
625                 return -ENODEV;
626         }
627
628         bundle = to_gb_bundle(module->dev);
629         ret = gb_pm_runtime_get_sync(bundle);
630         if (ret) {
631                 mutex_unlock(&codec->lock);
632                 return ret;
633         }
634
635         if (!mute && !stream) {/* start playback */
636                 ret = gb_audio_apbridgea_prepare_tx(data->connection,
637                                                     0);
638                 if (!ret)
639                         ret = gb_audio_apbridgea_start_tx(data->connection,
640                                                           0, 0);
641                 params->state = GBAUDIO_CODEC_START;
642         } else if (!mute && stream) {/* start capture */
643                 ret = gb_audio_apbridgea_prepare_rx(data->connection,
644                                                     0);
645                 if (!ret)
646                         ret = gb_audio_apbridgea_start_rx(data->connection,
647                                                           0);
648                 params->state = GBAUDIO_CODEC_START;
649         } else if (mute && !stream) {/* stop playback */
650                 ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
651                 if (!ret)
652                         ret = gb_audio_apbridgea_shutdown_tx(data->connection,
653                                                              0);
654                 params->state = GBAUDIO_CODEC_STOP;
655         } else if (mute && stream) {/* stop capture */
656                 ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
657                 if (!ret)
658                         ret = gb_audio_apbridgea_shutdown_rx(data->connection,
659                                                              0);
660                 params->state = GBAUDIO_CODEC_STOP;
661         } else {
662                 ret = -EINVAL;
663         }
664
665         if (ret)
666                 dev_err_ratelimited(dai->dev,
667                                     "%s:Error during %s %s stream:%d\n",
668                                     module->name, mute ? "Mute" : "Unmute",
669                                     stream ? "Capture" : "Playback", ret);
670
671         gb_pm_runtime_put_noidle(bundle);
672         mutex_unlock(&codec->lock);
673         return ret;
674 }
675
676 static const struct snd_soc_dai_ops gbcodec_dai_ops = {
677         .startup = gbcodec_startup,
678         .shutdown = gbcodec_shutdown,
679         .hw_params = gbcodec_hw_params,
680         .prepare = gbcodec_prepare,
681         .mute_stream = gbcodec_mute_stream,
682 };
683
684 static struct snd_soc_dai_driver gbaudio_dai[] = {
685         {
686                 .name = "apb-i2s0",
687                 .id = 0,
688                 .playback = {
689                         .stream_name = "I2S 0 Playback",
690                         .rates = SNDRV_PCM_RATE_48000,
691                         .formats = SNDRV_PCM_FORMAT_S16_LE,
692                         .rate_max = 48000,
693                         .rate_min = 48000,
694                         .channels_min = 1,
695                         .channels_max = 2,
696                         .sig_bits = 16,
697                 },
698                 .capture = {
699                         .stream_name = "I2S 0 Capture",
700                         .rates = SNDRV_PCM_RATE_48000,
701                         .formats = SNDRV_PCM_FORMAT_S16_LE,
702                         .rate_max = 48000,
703                         .rate_min = 48000,
704                         .channels_min = 1,
705                         .channels_max = 2,
706                         .sig_bits = 16,
707                 },
708                 .ops = &gbcodec_dai_ops,
709         },
710 };
711
712 static int gbaudio_init_jack(struct gbaudio_module_info *module,
713                              struct snd_soc_codec *codec)
714 {
715         int ret;
716
717         if (!module->jack_mask)
718                 return 0;
719
720         snprintf(module->jack_name, NAME_SIZE, "GB %d Headset Jack",
721                  module->dev_id);
722         ret = snd_soc_jack_new(codec, module->jack_name, module->jack_mask,
723                                &module->headset_jack);
724         if (ret) {
725                 dev_err(module->dev, "Failed to create new jack\n");
726                 return ret;
727         }
728
729         if (!module->button_mask)
730                 return 0;
731
732         snprintf(module->button_name, NAME_SIZE, "GB %d Button Jack",
733                  module->dev_id);
734         ret = snd_soc_jack_new(codec, module->button_name, module->button_mask,
735                                &module->button_jack);
736         if (ret) {
737                 dev_err(module->dev, "Failed to create button jack\n");
738                 return ret;
739         }
740
741         /*
742          * Currently, max 4 buttons are supported with following key mapping
743          * BTN_0 = KEY_MEDIA
744          * BTN_1 = KEY_VOICECOMMAND
745          * BTN_2 = KEY_VOLUMEUP
746          * BTN_3 = KEY_VOLUMEDOWN
747          */
748
749         if (module->button_mask & SND_JACK_BTN_0) {
750                 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_0,
751                                        KEY_MEDIA);
752                 if (ret) {
753                         dev_err(module->dev, "Failed to set BTN_0\n");
754                         return ret;
755                 }
756         }
757
758         if (module->button_mask & SND_JACK_BTN_1) {
759                 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_1,
760                                        KEY_VOICECOMMAND);
761                 if (ret) {
762                         dev_err(module->dev, "Failed to set BTN_1\n");
763                         return ret;
764                 }
765         }
766
767         if (module->button_mask & SND_JACK_BTN_2) {
768                 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_2,
769                                        KEY_VOLUMEUP);
770                 if (ret) {
771                         dev_err(module->dev, "Failed to set BTN_2\n");
772                         return ret;
773                 }
774         }
775
776         if (module->button_mask & SND_JACK_BTN_3) {
777                 ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_3,
778                                        KEY_VOLUMEDOWN);
779                 if (ret) {
780                         dev_err(module->dev, "Failed to set BTN_0\n");
781                         return ret;
782                 }
783         }
784
785         /* FIXME
786          * verify if this is really required
787         set_bit(INPUT_PROP_NO_DUMMY_RELEASE,
788                 module->button_jack.jack->input_dev->propbit);
789         */
790
791         return 0;
792 }
793
794 int gbaudio_register_module(struct gbaudio_module_info *module)
795 {
796         int ret;
797         struct snd_soc_codec *codec;
798         struct snd_card *card;
799         struct snd_soc_jack *jack = NULL;
800
801         if (!gbcodec) {
802                 dev_err(module->dev, "GB Codec not yet probed\n");
803                 return -EAGAIN;
804         }
805
806         codec = gbcodec->codec;
807         card = codec->card->snd_card;
808
809         down_write(&card->controls_rwsem);
810
811         if (module->num_dais) {
812                 dev_err(gbcodec->dev,
813                         "%d:DAIs not supported via gbcodec driver\n",
814                         module->num_dais);
815                 up_write(&card->controls_rwsem);
816                 return -EINVAL;
817         }
818
819         ret = gbaudio_init_jack(module, codec);
820         if (ret) {
821                 up_write(&card->controls_rwsem);
822                 return ret;
823         }
824
825         if (module->dapm_widgets)
826                 snd_soc_dapm_new_controls(&codec->dapm, module->dapm_widgets,
827                                           module->num_dapm_widgets);
828         if (module->controls)
829                 snd_soc_add_codec_controls(codec, module->controls,
830                                      module->num_controls);
831         if (module->dapm_routes)
832                 snd_soc_dapm_add_routes(&codec->dapm, module->dapm_routes,
833                                         module->num_dapm_routes);
834
835         /* card already instantiated, create widgets here only */
836         if (codec->card->instantiated) {
837                 snd_soc_dapm_link_component_dai_widgets(codec->card,
838                                                         &codec->dapm);
839 #ifdef CONFIG_SND_JACK
840                 /*
841                  * register jack devices for this module
842                  * from codec->jack_list
843                  */
844                 list_for_each_entry(jack, &codec->jack_list, list) {
845                         if ((jack == &module->headset_jack)
846                             || (jack == &module->button_jack))
847                                 snd_device_register(codec->card->snd_card,
848                                                     jack->jack);
849                 }
850 #endif
851         }
852
853         mutex_lock(&gbcodec->lock);
854         list_add(&module->list, &gbcodec->module_list);
855         mutex_unlock(&gbcodec->lock);
856
857         if (codec->card->instantiated)
858                 ret = snd_soc_dapm_new_widgets(&codec->dapm);
859         dev_dbg(codec->dev, "Registered %s module\n", module->name);
860
861         up_write(&card->controls_rwsem);
862         return ret;
863 }
864 EXPORT_SYMBOL(gbaudio_register_module);
865
866 static void gbaudio_codec_clean_data_tx(struct gbaudio_data_connection *data)
867 {
868         u16 i2s_port, cportid;
869         int ret;
870
871         if (list_is_singular(&gbcodec->module_list)) {
872                 ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
873                 if (ret)
874                         return;
875                 ret = gb_audio_apbridgea_shutdown_tx(data->connection,
876                                                      0);
877                 if (ret)
878                         return;
879         }
880         i2s_port = 0;   /* fixed for now */
881         cportid = data->connection->hd_cport_id;
882         ret = gb_audio_apbridgea_unregister_cport(data->connection,
883                                                   i2s_port, cportid,
884                                                   AUDIO_APBRIDGEA_DIRECTION_TX);
885         data->state[0] = GBAUDIO_CODEC_SHUTDOWN;
886 }
887
888 static void gbaudio_codec_clean_data_rx(struct gbaudio_data_connection *data)
889 {
890         u16 i2s_port, cportid;
891         int ret;
892
893         if (list_is_singular(&gbcodec->module_list)) {
894                 ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
895                 if (ret)
896                         return;
897                 ret = gb_audio_apbridgea_shutdown_rx(data->connection,
898                                                      0);
899                 if (ret)
900                         return;
901         }
902         i2s_port = 0;   /* fixed for now */
903         cportid = data->connection->hd_cport_id;
904         ret = gb_audio_apbridgea_unregister_cport(data->connection,
905                                                   i2s_port, cportid,
906                                                   AUDIO_APBRIDGEA_DIRECTION_RX);
907         data->state[1] = GBAUDIO_CODEC_SHUTDOWN;
908 }
909
910
911 static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
912 {
913         struct gbaudio_data_connection *data;
914         int pb_state, cap_state;
915
916         dev_dbg(gbcodec->dev, "%s: removed, cleanup APBridge\n", module->name);
917         list_for_each_entry(data, &module->data_list, list) {
918                 pb_state = data->state[0];
919                 cap_state = data->state[1];
920
921                 if (pb_state > GBAUDIO_CODEC_SHUTDOWN)
922                         gbaudio_codec_clean_data_tx(data);
923
924                 if (cap_state > GBAUDIO_CODEC_SHUTDOWN)
925                         gbaudio_codec_clean_data_rx(data);
926
927         }
928 }
929
930 void gbaudio_unregister_module(struct gbaudio_module_info *module)
931 {
932         struct snd_soc_codec *codec = gbcodec->codec;
933         struct snd_card *card = codec->card->snd_card;
934         struct snd_soc_jack *jack, *next_j;
935         int mask;
936
937         dev_dbg(codec->dev, "Unregister %s module\n", module->name);
938
939         down_write(&card->controls_rwsem);
940         mutex_lock(&gbcodec->lock);
941         gbaudio_codec_cleanup(module);
942         list_del(&module->list);
943         dev_dbg(codec->dev, "Process Unregister %s module\n", module->name);
944         mutex_unlock(&gbcodec->lock);
945
946 #ifdef CONFIG_SND_JACK
947         /* free jack devices for this module from codec->jack_list */
948         list_for_each_entry_safe(jack, next_j, &codec->jack_list, list) {
949                 if (jack == &module->headset_jack)
950                         mask = GBCODEC_JACK_MASK;
951                 else if (jack == &module->button_jack)
952                         mask = GBCODEC_JACK_BUTTON_MASK;
953                 else
954                         mask = 0;
955                 if (mask) {
956                         dev_dbg(module->dev, "Report %s removal\n",
957                                 jack->jack->id);
958                         snd_soc_jack_report(jack, 0, mask);
959                         snd_device_free(codec->card->snd_card, jack->jack);
960                         list_del(&jack->list);
961                 }
962         }
963 #endif
964
965         if (module->dapm_routes) {
966                 dev_dbg(codec->dev, "Removing %d routes\n",
967                         module->num_dapm_routes);
968                 snd_soc_dapm_del_routes(&codec->dapm, module->dapm_routes,
969                                         module->num_dapm_routes);
970         }
971         if (module->controls) {
972                 dev_dbg(codec->dev, "Removing %d controls\n",
973                         module->num_controls);
974                 snd_soc_remove_codec_controls(codec, module->controls,
975                                           module->num_controls);
976         }
977         if (module->dapm_widgets) {
978                 dev_dbg(codec->dev, "Removing %d widgets\n",
979                         module->num_dapm_widgets);
980                 snd_soc_dapm_free_controls(&codec->dapm, module->dapm_widgets,
981                                            module->num_dapm_widgets);
982         }
983
984         dev_dbg(codec->dev, "Unregistered %s module\n", module->name);
985
986         up_write(&card->controls_rwsem);
987 }
988 EXPORT_SYMBOL(gbaudio_unregister_module);
989
990 /*
991  * codec driver ops
992  */
993 static int gbcodec_probe(struct snd_soc_codec *codec)
994 {
995         int i;
996         struct gbaudio_codec_info *info;
997         struct gbaudio_codec_dai *dai;
998
999         info = devm_kzalloc(codec->dev, sizeof(*info), GFP_KERNEL);
1000         if (!info)
1001                 return -ENOMEM;
1002
1003         info->dev = codec->dev;
1004         INIT_LIST_HEAD(&info->module_list);
1005         mutex_init(&info->lock);
1006         INIT_LIST_HEAD(&info->dai_list);
1007
1008         /* init dai_list used to maintain runtime stream info */
1009         for (i = 0; i < ARRAY_SIZE(gbaudio_dai); i++) {
1010                 dai = devm_kzalloc(codec->dev, sizeof(*dai), GFP_KERNEL);
1011                 if (!dai)
1012                         return -ENOMEM;
1013                 dai->id = gbaudio_dai[i].id;
1014                 list_add(&dai->list, &info->dai_list);
1015         }
1016
1017         info->codec = codec;
1018         snd_soc_codec_set_drvdata(codec, info);
1019         gbcodec = info;
1020
1021         device_init_wakeup(codec->dev, 1);
1022         return 0;
1023 }
1024
1025 static int gbcodec_remove(struct snd_soc_codec *codec)
1026 {
1027         /* Empty function for now */
1028         return 0;
1029 }
1030
1031 static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg,
1032                          unsigned int value)
1033 {
1034         return 0;
1035 }
1036
1037 static unsigned int gbcodec_read(struct snd_soc_codec *codec,
1038                                  unsigned int reg)
1039 {
1040         return 0;
1041 }
1042
1043 static struct snd_soc_codec_driver soc_codec_dev_gbaudio = {
1044         .probe  = gbcodec_probe,
1045         .remove = gbcodec_remove,
1046
1047         .read = gbcodec_read,
1048         .write = gbcodec_write,
1049
1050         .idle_bias_off = true,
1051         .ignore_pmdown_time = 1,
1052 };
1053
1054 #ifdef CONFIG_PM
1055 static int gbaudio_codec_suspend(struct device *dev)
1056 {
1057         dev_dbg(dev, "%s: suspend\n", __func__);
1058         return 0;
1059 }
1060
1061 static int gbaudio_codec_resume(struct device *dev)
1062 {
1063         dev_dbg(dev, "%s: resume\n", __func__);
1064         return 0;
1065 }
1066
1067 static const struct dev_pm_ops gbaudio_codec_pm_ops = {
1068         .suspend        = gbaudio_codec_suspend,
1069         .resume         = gbaudio_codec_resume,
1070 };
1071 #endif
1072
1073 static int gbaudio_codec_probe(struct platform_device *pdev)
1074 {
1075         return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_gbaudio,
1076                         gbaudio_dai, ARRAY_SIZE(gbaudio_dai));
1077 }
1078
1079 static int gbaudio_codec_remove(struct platform_device *pdev)
1080 {
1081         snd_soc_unregister_codec(&pdev->dev);
1082         return 0;
1083 }
1084
1085 static const struct of_device_id greybus_asoc_machine_of_match[]  = {
1086         { .compatible = "toshiba,apb-dummy-codec", },
1087         {},
1088 };
1089
1090 static struct platform_driver gbaudio_codec_driver = {
1091         .driver = {
1092                 .name = "apb-dummy-codec",
1093                 .owner = THIS_MODULE,
1094 #ifdef CONFIG_PM
1095                 .pm = &gbaudio_codec_pm_ops,
1096 #endif
1097                 .of_match_table = greybus_asoc_machine_of_match,
1098         },
1099         .probe = gbaudio_codec_probe,
1100         .remove = gbaudio_codec_remove,
1101 };
1102 module_platform_driver(gbaudio_codec_driver);
1103
1104 MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
1105 MODULE_AUTHOR("Vaibhav Agarwal <[email protected]>");
1106 MODULE_LICENSE("GPL v2");
1107 MODULE_ALIAS("platform:apb-dummy-codec");
This page took 0.109868 seconds and 4 git commands to generate.