return ret;
}
+static int gbmodule_shutdown_tx(struct gbaudio_module_info *module,
+ struct gbaudio_data_connection *data,
+ int codec_state, struct device *dev)
+{
+ int ret, module_state;
+ __u16 i2s_port, cportid;
+
+ module_state = module->ctrlstate[0];
+ if (module_state == GBAUDIO_CODEC_SHUTDOWN) {
+ dev_dbg(dev, "%s: module already configured\n",
+ module->name);
+ return 0;
+ }
+
+ if (codec_state == GBAUDIO_CODEC_STOP) {
+ ret = gb_audio_apbridgea_shutdown_tx(data->connection, 0);
+ if (ret)
+ return ret;
+ }
+
+ /* deactivate */
+ cportid = data->connection->intf_cport_id;
+ if (module_state >= GBAUDIO_CODEC_PREPARE) {
+ ret = gb_audio_gb_deactivate_tx(module->mgmt_connection,
+ cportid);
+ if (ret)
+ return ret;
+ }
+
+ /* unregister cport */
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_unregister_cport(data->connection, i2s_port,
+ cportid,
+ AUDIO_APBRIDGEA_DIRECTION_TX);
+
+ return ret;
+}
+
+static int gbmodule_shutdown_rx(struct gbaudio_module_info *module,
+ struct gbaudio_data_connection *data,
+ int codec_state, struct device *dev)
+{
+ int ret, module_state;
+ __u16 i2s_port, cportid;
+
+ module_state = module->ctrlstate[1];
+ if (module_state == GBAUDIO_CODEC_SHUTDOWN) {
+ dev_dbg(dev, "%s: module already configured\n",
+ module->name);
+ return 0;
+ }
+
+ if (codec_state == GBAUDIO_CODEC_STOP) {
+ ret = gb_audio_apbridgea_shutdown_rx(data->connection, 0);
+ if (ret)
+ return ret;
+ }
+
+ /* deactivate */
+ cportid = data->connection->intf_cport_id;
+ if (module_state >= GBAUDIO_CODEC_PREPARE) {
+ ret = gb_audio_gb_deactivate_rx(module->mgmt_connection,
+ cportid);
+ if (ret)
+ return ret;
+ }
+
+ /* unregister cport */
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_unregister_cport(data->connection, i2s_port,
+ cportid,
+ AUDIO_APBRIDGEA_DIRECTION_RX);
+
+ return ret;
+}
+
static void gbcodec_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- int ret;
- __u16 i2s_port, cportid;
- int state, module_state;
+ int ret, state;
struct gbaudio_module_info *module;
struct gbaudio_data_connection *data;
struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
mutex_unlock(&module->lock);
continue;
}
- module_state = module->ctrlstate[substream->stream];
- if (module_state == GBAUDIO_CODEC_SHUTDOWN) {
- dev_dbg(codec->dev, "%s: module already configured\n",
- module->name);
- mutex_unlock(&module->lock);
- continue;
- }
-
/* find the dai */
data = find_data(module, dai->name);
if (!data) {
continue;
}
- /* deactivate */
- cportid = data->connection->intf_cport_id;
switch (substream->stream) {
- case SNDRV_PCM_STREAM_CAPTURE:
- ret = gb_audio_gb_deactivate_rx(module->mgmt_connection,
- cportid);
- /* unregister cport */
- i2s_port = 0; /* fixed for now */
- cportid = data->connection->hd_cport_id;
- ret = gb_audio_apbridgea_unregister_cport(
- data->connection, i2s_port, cportid,
- AUDIO_APBRIDGEA_DIRECTION_RX);
- break;
case SNDRV_PCM_STREAM_PLAYBACK:
- ret = gb_audio_gb_deactivate_tx(module->mgmt_connection,
- cportid);
- /* unregister cport */
- i2s_port = 0; /* fixed for now */
- cportid = data->connection->hd_cport_id;
- ret = gb_audio_apbridgea_unregister_cport(
- data->connection, i2s_port, cportid,
- AUDIO_APBRIDGEA_DIRECTION_TX);
+ ret = gbmodule_shutdown_tx(module, data, state,
+ dai->dev);
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ ret = gbmodule_shutdown_rx(module, data, state,
+ dai->dev);
break;
}
- dev_dbg(dai->dev, "Unregister %s:%d DAI, ret:%d\n", dai->name,
- cportid, ret);
+ dev_dbg(dai->dev, "Unregister %s DAI, ret:%d\n", dai->name,
+ ret);
state = GBAUDIO_CODEC_SHUTDOWN;
module->ctrlstate[substream->stream] = state;
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
return ret;
}
+static int gbmodule_prepare_tx(struct gbaudio_module_info *module,
+ struct gbaudio_data_connection *data,
+ int codec_state, struct device *dev)
+{
+ int ret;
+ uint16_t data_cport;
+
+ data_cport = data->connection->intf_cport_id;
+ ret = gb_audio_gb_set_tx_data_size(module->mgmt_connection, data_cport,
+ 192);
+ if (ret) {
+ dev_err(dev, "%d:Error during set_tx_data_size, cport:%d\n",
+ ret, data_cport);
+ return ret;
+ }
+ if (codec_state < GBAUDIO_CODEC_PREPARE) {
+ ret = gb_audio_apbridgea_set_tx_data_size(data->connection, 0,
+ 192);
+ if (ret) {
+ dev_err(dev,
+ "%d:Error during apbridgea set_tx_data_size, cport\n",
+ ret);
+ return ret;
+ }
+ }
+ ret = gb_audio_gb_activate_tx(module->mgmt_connection,
+ data_cport);
+ if (ret)
+ dev_err(dev, "%s:Error during activate stream,%d\n",
+ module->name, ret);
+
+ return ret;
+}
+
+static int gbmodule_prepare_rx(struct gbaudio_module_info *module,
+ struct gbaudio_data_connection *data,
+ int codec_state, struct device *dev)
+{
+ int ret;
+ uint16_t data_cport;
+
+ data_cport = data->connection->intf_cport_id;
+
+ ret = gb_audio_gb_set_rx_data_size(module->mgmt_connection, data_cport,
+ 192);
+ if (ret) {
+ dev_err(dev, "%d:Error during set_rx_data_size, cport:%d\n",
+ ret, data_cport);
+ return ret;
+ }
+ if (codec_state < GBAUDIO_CODEC_PREPARE) {
+ ret = gb_audio_apbridgea_set_rx_data_size(data->connection, 0,
+ 192);
+ if (ret) {
+ dev_err(dev,
+ "%d:Error during apbridgea_set_rx_data_size\n",
+ ret);
+ return ret;
+ }
+ }
+ ret = gb_audio_gb_activate_rx(module->mgmt_connection,
+ data_cport);
+ if (ret)
+ dev_err(dev, "%s:Error during activate stream,%d\n",
+ module->name, ret);
+
+ return ret;
+}
+
static int gbcodec_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
int ret;
- uint16_t data_cport;
- struct gbaudio_data_connection *data;
struct gbaudio_module_info *module;
int state;
+ struct gbaudio_data_connection *data;
struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
mutex_lock(&codec->lock);
mutex_unlock(&module->lock);
continue;
}
- /* deactivate rx/tx */
- data_cport = data->connection->intf_cport_id;
switch (substream->stream) {
- case SNDRV_PCM_STREAM_CAPTURE:
- ret = gb_audio_gb_set_rx_data_size(
- module->mgmt_connection,
- data_cport, 192);
- if (ret) {
- dev_err(dai->dev,
- "%d:Error during set_rx_data_size, cport:%d\n",
- ret, data_cport);
- mutex_unlock(&module->lock);
- goto func_exit;
- }
- if (state < GBAUDIO_CODEC_PREPARE) {
- ret = gb_audio_apbridgea_set_rx_data_size(
- data->connection, 0,
- 192);
- if (ret) {
- dev_err(dai->dev,
- "%d:Error during apbridgea_set_rx_data_size\n",
- ret);
- mutex_unlock(&module->lock);
- goto func_exit;
- }
- }
- ret = gb_audio_gb_activate_rx(module->mgmt_connection,
- data_cport);
- if (ret)
- dev_err(dai->dev,
- "%s:Error during activate stream,%d\n",
- module->name, ret);
- break;
case SNDRV_PCM_STREAM_PLAYBACK:
- ret = gb_audio_gb_set_tx_data_size(
- module->mgmt_connection,
- data_cport, 192);
- if (ret) {
- dev_err(dai->dev,
- "%d:Error during module set_tx_data_size, cport:%d\n",
- ret, data_cport);
- mutex_unlock(&module->lock);
- goto func_exit;
- }
- if (state < GBAUDIO_CODEC_PREPARE) {
- ret = gb_audio_apbridgea_set_tx_data_size(
- data->connection, 0,
- 192);
- if (ret) {
- dev_err(dai->dev,
- "%d:Error during apbridgea set_tx_data_size, cport\n",
- ret);
- mutex_unlock(&module->lock);
- goto func_exit;
- }
- }
- ret = gb_audio_gb_activate_tx(module->mgmt_connection,
- data_cport);
- if (ret)
- dev_err(dai->dev,
- "%s:Error during activate stream,%d\n",
- module->name, ret);
+ ret = gbmodule_prepare_tx(module, data, state,
+ dai->dev);
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ ret = gbmodule_prepare_rx(module, data, state,
+ dai->dev);
break;
}
+ if (ret == -ENODEV)
+ continue;
+ if (ret) {
+ mutex_unlock(&module->lock);
+ goto func_exit;
+ }
+
state = GBAUDIO_CODEC_PREPARE;
module->ctrlstate[substream->stream] = state;
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
func_exit:
mutex_unlock(&codec->lock);
- return 0;
+ return ret;
}
static int gbcodec_trigger(struct snd_pcm_substream *substream, int cmd,