File Index
Files and directories
Sign in
FILE

audio_codec.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/greybus/audio_codec.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * APBridge ALSA SoC dummy codec driver
   4 * Copyright 2016 Google Inc.
   5 * Copyright 2016 Linaro Ltd.
   6 */
   7#include <linux/kernel.h>
   8#include <linux/module.h>
   9#include <linux/pm_runtime.h>
  10#include <sound/soc.h>
  11#include <sound/pcm_params.h>
  12#include <uapi/linux/input.h>
  13
  14#include "audio_codec.h"
  15#include "audio_apbridgea.h"
  16#include "audio_manager.h"
  17#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 snd_soc_dapm_context *dapm;
 811	struct gbaudio_jack *jack = NULL;
 812
 813	if (!gbcodec) {
 814		dev_err(module->dev, "GB Codec not yet probed\n");
 815		return -EAGAIN;
 816	}
 817
 818	comp = gbcodec->component;
 819	dapm = snd_soc_component_to_dapm(comp);
 820
 821	mutex_lock(&gbcodec->register_mutex);
 822
 823	if (module->num_dais) {
 824		dev_err(gbcodec->dev,
 825			"%d:DAIs not supported via gbcodec driver\n",
 826			module->num_dais);
 827		mutex_unlock(&gbcodec->register_mutex);
 828		return -EINVAL;
 829	}
 830
 831	ret = gbaudio_init_jack(module, comp->card);
 832	if (ret) {
 833		mutex_unlock(&gbcodec->register_mutex);
 834		return ret;
 835	}
 836
 837	if (module->dapm_widgets)
 838		snd_soc_dapm_new_controls(dapm, module->dapm_widgets,
 839					  module->num_dapm_widgets);
 840	if (module->controls)
 841		snd_soc_add_component_controls(comp, module->controls,
 842					       module->num_controls);
 843	if (module->dapm_routes)
 844		snd_soc_dapm_add_routes(dapm, module->dapm_routes,
 845					module->num_dapm_routes);
 846
 847	/* card already instantiated, create widgets here only */
 848	if (comp->card->instantiated) {
 849		gbaudio_dapm_link_component_dai_widgets(comp->card, dapm);
 850#ifdef CONFIG_SND_JACK
 851		/*
 852		 * register jack devices for this module
 853		 * from codec->jack_list
 854		 */
 855		list_for_each_entry(jack, &module->jack_list, list) {
 856			snd_device_register(comp->card->snd_card,
 857					    jack->jack.jack);
 858		}
 859#endif
 860	}
 861
 862	mutex_lock(&gbcodec->lock);
 863	list_add(&module->list, &gbcodec->module_list);
 864	mutex_unlock(&gbcodec->lock);
 865
 866	if (comp->card->instantiated)
 867		ret = snd_soc_dapm_new_widgets(comp->card);
 868	dev_dbg(comp->dev, "Registered %s module\n", module->name);
 869
 870	mutex_unlock(&gbcodec->register_mutex);
 871	return ret;
 872}
 873EXPORT_SYMBOL(gbaudio_register_module);
 874
 875static void gbaudio_codec_clean_data_tx(struct gbaudio_data_connection *data)
 876{
 877	u16 i2s_port, cportid;
 878	int ret;
 879
 880	if (list_is_singular(&gbcodec->module_list)) {
 881		ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
 882		if (ret)
 883			return;
 884		ret = gb_audio_apbridgea_shutdown_tx(data->connection, 0);
 885		if (ret)
 886			return;
 887	}
 888	i2s_port = 0;	/* fixed for now */
 889	cportid = data->connection->hd_cport_id;
 890	ret = gb_audio_apbridgea_unregister_cport(data->connection,
 891						  i2s_port, cportid,
 892						  AUDIO_APBRIDGEA_DIRECTION_TX);
 893	data->state[0] = GBAUDIO_CODEC_SHUTDOWN;
 894}
 895
 896static void gbaudio_codec_clean_data_rx(struct gbaudio_data_connection *data)
 897{
 898	u16 i2s_port, cportid;
 899	int ret;
 900
 901	if (list_is_singular(&gbcodec->module_list)) {
 902		ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
 903		if (ret)
 904			return;
 905		ret = gb_audio_apbridgea_shutdown_rx(data->connection, 0);
 906		if (ret)
 907			return;
 908	}
 909	i2s_port = 0;	/* fixed for now */
 910	cportid = data->connection->hd_cport_id;
 911	ret = gb_audio_apbridgea_unregister_cport(data->connection,
 912						  i2s_port, cportid,
 913						  AUDIO_APBRIDGEA_DIRECTION_RX);
 914	data->state[1] = GBAUDIO_CODEC_SHUTDOWN;
 915}
 916
 917static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
 918{
 919	struct gbaudio_data_connection *data;
 920	int pb_state, cap_state;
 921
 922	dev_dbg(gbcodec->dev, "%s: removed, cleanup APBridge\n", module->name);
 923	list_for_each_entry(data, &module->data_list, list) {
 924		pb_state = data->state[0];
 925		cap_state = data->state[1];
 926
 927		if (pb_state > GBAUDIO_CODEC_SHUTDOWN)
 928			gbaudio_codec_clean_data_tx(data);
 929
 930		if (cap_state > GBAUDIO_CODEC_SHUTDOWN)
 931			gbaudio_codec_clean_data_rx(data);
 932	}
 933}
 934
 935void gbaudio_unregister_module(struct gbaudio_module_info *module)
 936{
 937	struct snd_soc_component *comp = gbcodec->component;
 938	struct gbaudio_jack *jack, *n;
 939	int mask;
 940
 941	dev_dbg(comp->dev, "Unregister %s module\n", module->name);
 942
 943	mutex_lock(&gbcodec->register_mutex);
 944	mutex_lock(&gbcodec->lock);
 945	gbaudio_codec_cleanup(module);
 946	list_del(&module->list);
 947	dev_dbg(comp->dev, "Process Unregister %s module\n", module->name);
 948	mutex_unlock(&gbcodec->lock);
 949
 950#ifdef CONFIG_SND_JACK
 951	/* free jack devices for this module jack_list */
 952	list_for_each_entry_safe(jack, n, &module->jack_list, list) {
 953		if (jack == &module->headset)
 954			mask = GBCODEC_JACK_MASK;
 955		else if (jack == &module->button)
 956			mask = GBCODEC_JACK_BUTTON_MASK;
 957		else
 958			mask = 0;
 959		if (mask) {
 960			dev_dbg(module->dev, "Report %s removal\n",
 961				jack->jack.jack->id);
 962			snd_soc_jack_report(&jack->jack, 0, mask);
 963			snd_device_free(comp->card->snd_card,
 964					jack->jack.jack);
 965			list_del(&jack->list);
 966		}
 967	}
 968#endif
 969
 970	if (module->dapm_routes) {
 971		struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp);
 972
 973		dev_dbg(comp->dev, "Removing %d routes\n",
 974			module->num_dapm_routes);
 975		snd_soc_dapm_del_routes(dapm, module->dapm_routes,
 976					module->num_dapm_routes);
 977	}
 978	if (module->controls) {
 979		dev_dbg(comp->dev, "Removing %d controls\n",
 980			module->num_controls);
 981		/* release control semaphore */
 982		gbaudio_remove_component_controls(comp, module->controls,
 983						  module->num_controls);
 984	}
 985	if (module->dapm_widgets) {
 986		struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp);
 987
 988		dev_dbg(comp->dev, "Removing %d widgets\n",
 989			module->num_dapm_widgets);
 990		gbaudio_dapm_free_controls(dapm, module->dapm_widgets,
 991					   module->num_dapm_widgets);
 992	}
 993
 994	dev_dbg(comp->dev, "Unregistered %s module\n", module->name);
 995
 996	mutex_unlock(&gbcodec->register_mutex);
 997}
 998EXPORT_SYMBOL(gbaudio_unregister_module);
 999
1000/*
1001 * component driver ops
1002 */
1003static int gbcodec_probe(struct snd_soc_component *comp)
1004{
1005	int i;
1006	struct gbaudio_codec_info *info;
1007	struct gbaudio_codec_dai *dai;
1008
1009	info = devm_kzalloc(comp->dev, sizeof(*info), GFP_KERNEL);
1010	if (!info)
1011		return -ENOMEM;
1012
1013	info->dev = comp->dev;
1014	INIT_LIST_HEAD(&info->module_list);
1015	mutex_init(&info->lock);
1016	mutex_init(&info->register_mutex);
1017	INIT_LIST_HEAD(&info->dai_list);
1018
1019	/* init dai_list used to maintain runtime stream info */
1020	for (i = 0; i < ARRAY_SIZE(gbaudio_dai); i++) {
1021		dai = devm_kzalloc(comp->dev, sizeof(*dai), GFP_KERNEL);
1022		if (!dai)
1023			return -ENOMEM;
1024		dai->id = gbaudio_dai[i].id;
1025		list_add(&dai->list, &info->dai_list);
1026	}
1027
1028	info->component = comp;
1029	snd_soc_component_set_drvdata(comp, info);
1030	gbcodec = info;
1031
1032	device_init_wakeup(comp->dev, 1);
1033	return 0;
1034}
1035
1036static int gbcodec_write(struct snd_soc_component *comp, unsigned int reg,
1037			 unsigned int value)
1038{
1039	return 0;
1040}
1041
1042static unsigned int gbcodec_read(struct snd_soc_component *comp,
1043				 unsigned int reg)
1044{
1045	return 0;
1046}
1047
1048static const struct snd_soc_component_driver soc_codec_dev_gbaudio = {
1049	.probe	= gbcodec_probe,
1050	.read = gbcodec_read,
1051	.write = gbcodec_write,
1052};
1053
1054#ifdef CONFIG_PM
1055static int gbaudio_codec_suspend(struct device *dev)
1056{
1057	dev_dbg(dev, "%s: suspend\n", __func__);
1058	return 0;
1059}
1060
1061static int gbaudio_codec_resume(struct device *dev)
1062{
1063	dev_dbg(dev, "%s: resume\n", __func__);
1064	return 0;
1065}
1066
1067static const struct dev_pm_ops gbaudio_codec_pm_ops = {
1068	.suspend	= gbaudio_codec_suspend,
1069	.resume		= gbaudio_codec_resume,
1070};
1071#endif
1072
1073static int gbaudio_codec_probe(struct platform_device *pdev)
1074{
1075	return devm_snd_soc_register_component(&pdev->dev,
1076			&soc_codec_dev_gbaudio,
1077			gbaudio_dai, ARRAY_SIZE(gbaudio_dai));
1078}
1079
1080static const struct of_device_id greybus_asoc_machine_of_match[]  = {
1081	{ .compatible = "toshiba,apb-dummy-codec", },
1082	{},
1083};
1084
1085static struct platform_driver gbaudio_codec_driver = {
1086	.driver = {
1087		.name = "apb-dummy-codec",
1088#ifdef CONFIG_PM
1089		.pm = &gbaudio_codec_pm_ops,
1090#endif
1091		.of_match_table = greybus_asoc_machine_of_match,
1092	},
1093	.probe = gbaudio_codec_probe,
1094};
1095module_platform_driver(gbaudio_codec_driver);
1096
1097MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
1098MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
1099MODULE_LICENSE("GPL v2");
1100MODULE_ALIAS("platform:apb-dummy-codec");
~/ Read-only file preview.