/** *snd_soc_dai_set_clkdiv-configureDAIclockdividers. *@dai:DAI *@div_id:DAIspecificclockdividerID *@div:newclockdivisor. * *Configurestheclockdividers.ThisisusedtoderivethebestDAIbitand *frameclocksfromthesystemormasterclock.It'sbesttosettheDAIbit *andframeclocksaslowaspossibletosavesystempower.
*/ int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
{ int ret = -EINVAL;
if (dai->driver->ops &&
dai->driver->ops->set_clkdiv)
ret = dai->driver->ops->set_clkdiv(dai, div_id, div);
/** *snd_soc_dai_set_tdm_slot()-ConfiguresaDAIforTDMoperation *@dai:TheDAItoconfigure *@tx_mask:bitmaskrepresentingactiveTXslots. *@rx_mask:bitmaskrepresentingactiveRXslots. *@slots:Numberofslotsinuse. *@slot_width:Widthinbitsforeachslot. * *ThisfunctionconfiguresthespecifiedDAIforTDMoperation.@slotcontains *thetotalnumberofslotsoftheTDMstreamand@slot_withthewidthofeach *slotinbitclockcycles.@tx_maskand@rx_maskarebitmasksspecifyingthe *activeslotsoftheTDMstreamforthespecifiedDAI,i.e.whichslotsthe *DAIshouldwritetoorreadfrom.Ifabitissetthecorrespondingslotis *active,ifabitisclearedthecorrespondingslotisinactive.Bit0mapsto *thefirstslot,bit1tothesecondslotandsoon.Thefirstactiveslot *mapstothefirstchanneloftheDAI,thesecondactiveslottothesecond *channelandsoon. * *TDMmodecanbedisabledbypassing0for@slots.Inthiscase@tx_mask, *@rx_maskand@slot_widthwillbeignored. * *Returns0onsuccess,anegativeerrorcodeotherwise.
*/ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, unsignedint tx_mask, unsignedint rx_mask, int slots, int slot_width)
{ int ret = -ENOTSUPP; int stream; unsignedint *tdm_mask[] = {
&tx_mask,
&rx_mask,
};
if (slots) { if (dai->driver->ops &&
dai->driver->ops->xlate_tdm_slot_mask)
ret = dai->driver->ops->xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); else
ret = snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); if (ret) goto err;
}
if (dai->driver->ops &&
dai->driver->ops->set_tdm_slot)
ret = dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
slots, slot_width);
err: return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
/** *snd_soc_dai_set_channel_map-configureDAIaudiochannelmap *@dai:DAI *@tx_num:howmanyTXchannels *@tx_slot:pointertoanarraywhichimplytheTXslotnumberchannel *0~num-1uses *@rx_num:howmanyRXchannels *@rx_slot:pointertoanarraywhichimplytheRXslotnumberchannel *0~num-1uses * *configuretherelationshipbetweenchannelnumberandTDMslotnumber.
*/ int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai, unsignedint tx_num, constunsignedint *tx_slot, unsignedint rx_num, constunsignedint *rx_slot)
{ int ret = -ENOTSUPP;
if (dai->driver->ops &&
dai->driver->ops->set_channel_map)
ret = dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
rx_num, rx_slot); return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
/** *snd_soc_dai_get_channel_map-GetDAIaudiochannelmap *@dai:DAI *@tx_num:howmanyTXchannels *@tx_slot:pointertoanarraywhichimplytheTXslotnumberchannel *0~num-1uses *@rx_num:howmanyRXchannels *@rx_slot:pointertoanarraywhichimplytheRXslotnumberchannel *0~num-1uses
*/ int snd_soc_dai_get_channel_map(conststruct snd_soc_dai *dai, unsignedint *tx_num, unsignedint *tx_slot, unsignedint *rx_num, unsignedint *rx_slot)
{ int ret = -ENOTSUPP;
if (dai->driver->ops &&
dai->driver->ops->get_channel_map)
ret = dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
rx_num, rx_slot); return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
/** *snd_soc_dai_set_tristate-configureDAIsystemormasterclock. *@dai:DAI *@tristate:tristateenable * *TristatestheDAIsothatotherscanuseit.
*/ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
{ int ret = -EINVAL;
if (dai->driver->ops &&
dai->driver->ops->set_tristate)
ret = dai->driver->ops->set_tristate(dai, tristate);
int snd_soc_dai_mute_is_ctrled_at_trigger(struct snd_soc_dai *dai)
{ if (dai->driver->ops) return dai->driver->ops->mute_unmute_on_trigger;
return0;
}
/** *snd_soc_dai_digital_mute-configureDAIsystemormasterclock. *@dai:DAI *@mute:muteenable *@direction:streamtomute * *MutestheDAIDAC.
*/ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute, int direction)
{ int ret = -ENOTSUPP;
/* *ignoreifdirectionwasCAPTURE *andithad.no_capture_muteflag
*/ if (dai->driver->ops &&
dai->driver->ops->mute_stream &&
(direction == SNDRV_PCM_STREAM_PLAYBACK ||
!dai->driver->ops->no_capture_mute))
ret = dai->driver->ops->mute_stream(dai, mute, direction);
int snd_soc_dai_compress_new(struct snd_soc_dai *dai, struct snd_soc_pcm_runtime *rtd)
{ int ret = -ENOTSUPP; if (dai->driver->ops &&
dai->driver->ops->compress_new)
ret = dai->driver->ops->compress_new(rtd); return soc_dai_ret(dai, ret);
}
int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order)
{ struct snd_soc_dai *dai; int i, r, ret = 0;
for_each_rtd_dais(rtd, i, dai) { if (!dai->probed) continue;
if (dai->driver->ops) { if (dai->driver->ops->remove_order != order) continue;
if (dai->driver->ops->remove) {
r = dai->driver->ops->remove(dai); if (r < 0)
ret = r; /* use last error */
}
}
dai->probed = 0;
}
return ret;
}
int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd)
{ struct snd_soc_dai *dai; int i;
for_each_rtd_dais(rtd, i, dai) { if (dai->driver->ops &&
dai->driver->ops->pcm_new) { int ret = dai->driver->ops->pcm_new(rtd, dai); if (ret < 0) return soc_dai_ret(dai, ret);
}
}
return0;
}
int snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream)
{ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *dai; int i, ret;
for_each_rtd_dais(rtd, i, dai) {
ret = snd_soc_dai_prepare(dai, substream); if (ret < 0) return ret;
}
return0;
}
staticint soc_dai_trigger(struct snd_soc_dai *dai, struct snd_pcm_substream *substream, int cmd)
{ int ret = 0;
if (!snd_soc_dai_stream_valid(dai, substream->stream)) return0;
if (dai->driver->ops &&
dai->driver->ops->trigger)
ret = dai->driver->ops->trigger(substream, cmd, dai);
return soc_dai_ret(dai, ret);
}
int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd, int rollback)
{ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *dai; int i, r, ret = 0;
switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
for_each_rtd_dais(rtd, i, dai) {
ret = soc_dai_trigger(dai, substream, cmd); if (ret < 0) break;
if (snd_soc_dai_mute_is_ctrled_at_trigger(dai))
snd_soc_dai_digital_mute(dai, 0, substream->stream);
soc_dai_mark_push(dai, substream, trigger);
} break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
for_each_rtd_dais(rtd, i, dai) { if (rollback && !soc_dai_mark_match(dai, substream, trigger)) continue;
if (snd_soc_dai_mute_is_ctrled_at_trigger(dai))
snd_soc_dai_digital_mute(dai, 1, substream->stream);
r = soc_dai_trigger(dai, substream, cmd); if (r < 0)
ret = r; /* use last ret */
soc_dai_mark_pop(dai, trigger);
}
}
/* for CPU */
for_each_rtd_cpu_dais(rtd, i, dai) if (dai->driver->ops &&
dai->driver->ops->delay)
*cpu_delay = max(*cpu_delay, dai->driver->ops->delay(substream, dai));
/* for Codec */
for_each_rtd_codec_dais(rtd, i, dai) if (dai->driver->ops &&
dai->driver->ops->delay)
*codec_delay = max(*codec_delay, dai->driver->ops->delay(substream, dai));
}
int snd_soc_dai_compr_startup(struct snd_soc_dai *dai, struct snd_compr_stream *cstream)
{ int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->startup)
ret = dai->driver->cops->startup(cstream, dai);
/* mark cstream if succeeded */ if (ret == 0)
soc_dai_mark_push(dai, cstream, compr_startup);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.