• 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 #include "audio_helper.h"
18 
19 static struct gbaudio_codec_info *gbcodec;
20 
21 static struct gbaudio_data_connection *
find_data(struct gbaudio_module_info * module,int id)22 find_data(struct gbaudio_module_info *module, int id)
23 {
24 	struct gbaudio_data_connection *data;
25 
26 	list_for_each_entry(data, &module->data_list, list) {
27 		if (id == data->id)
28 			return data;
29 	}
30 	return NULL;
31 }
32 
33 static struct gbaudio_stream_params *
find_dai_stream_params(struct gbaudio_codec_info * codec,int id,int stream)34 find_dai_stream_params(struct gbaudio_codec_info *codec, int id, int stream)
35 {
36 	struct gbaudio_codec_dai *dai;
37 
38 	list_for_each_entry(dai, &codec->dai_list, list) {
39 		if (dai->id == id)
40 			return &dai->params[stream];
41 	}
42 	return NULL;
43 }
44 
gbaudio_module_enable_tx(struct gbaudio_codec_info * codec,struct gbaudio_module_info * module,int id)45 static int gbaudio_module_enable_tx(struct gbaudio_codec_info *codec,
46 				    struct gbaudio_module_info *module, int id)
47 {
48 	int module_state, ret = 0;
49 	u16 data_cport, i2s_port, cportid;
50 	u8 sig_bits, channels;
51 	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 
gbaudio_module_disable_tx(struct gbaudio_module_info * module,int id)125 static 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 
gbaudio_module_enable_rx(struct gbaudio_codec_info * codec,struct gbaudio_module_info * module,int id)171 static 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 
gbaudio_module_disable_rx(struct gbaudio_module_info * module,int id)252 static 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 
gbaudio_module_update(struct gbaudio_codec_info * codec,struct snd_soc_dapm_widget * w,struct gbaudio_module_info * module,int enable)298 int 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 }
337 EXPORT_SYMBOL(gbaudio_module_update);
338 
339 /*
340  * codec DAI ops
341  */
gbcodec_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)342 static 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 
gbcodec_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)370 static 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 
gbcodec_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hwparams,struct snd_soc_dai * dai)392 static 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 
gbcodec_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)496 static 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 
gbcodec_mute_stream(struct snd_soc_dai * dai,int mute,int stream)564 static 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 
654 static 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 
662 static 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 
gbaudio_init_jack(struct gbaudio_module_info * module,struct snd_soc_card * card)690 static 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 
797 free_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 
gbaudio_register_module(struct gbaudio_module_info * module)806 int 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 }
871 EXPORT_SYMBOL(gbaudio_register_module);
872 
gbaudio_codec_clean_data_tx(struct gbaudio_data_connection * data)873 static 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 
gbaudio_codec_clean_data_rx(struct gbaudio_data_connection * data)894 static 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 
gbaudio_codec_cleanup(struct gbaudio_module_info * module)915 static 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 
gbaudio_unregister_module(struct gbaudio_module_info * module)933 void 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 }
992 EXPORT_SYMBOL(gbaudio_unregister_module);
993 
994 /*
995  * component driver ops
996  */
gbcodec_probe(struct snd_soc_component * comp)997 static 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 
gbcodec_write(struct snd_soc_component * comp,unsigned int reg,unsigned int value)1030 static int gbcodec_write(struct snd_soc_component *comp, unsigned int reg,
1031 			 unsigned int value)
1032 {
1033 	return 0;
1034 }
1035 
gbcodec_read(struct snd_soc_component * comp,unsigned int reg)1036 static unsigned int gbcodec_read(struct snd_soc_component *comp,
1037 				 unsigned int reg)
1038 {
1039 	return 0;
1040 }
1041 
1042 static 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
gbaudio_codec_suspend(struct device * dev)1049 static int gbaudio_codec_suspend(struct device *dev)
1050 {
1051 	dev_dbg(dev, "%s: suspend\n", __func__);
1052 	return 0;
1053 }
1054 
gbaudio_codec_resume(struct device * dev)1055 static int gbaudio_codec_resume(struct device *dev)
1056 {
1057 	dev_dbg(dev, "%s: resume\n", __func__);
1058 	return 0;
1059 }
1060 
1061 static const struct dev_pm_ops gbaudio_codec_pm_ops = {
1062 	.suspend	= gbaudio_codec_suspend,
1063 	.resume		= gbaudio_codec_resume,
1064 };
1065 #endif
1066 
gbaudio_codec_probe(struct platform_device * pdev)1067 static 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 
1074 static const struct of_device_id greybus_asoc_machine_of_match[]  = {
1075 	{ .compatible = "toshiba,apb-dummy-codec", },
1076 	{},
1077 };
1078 
1079 static 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 };
1089 module_platform_driver(gbaudio_codec_driver);
1090 
1091 MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
1092 MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
1093 MODULE_LICENSE("GPL v2");
1094 MODULE_ALIAS("platform:apb-dummy-codec");
1095