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