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