@@ -259,6 +259,7 @@ static void uni_player_set_channel_status(struct uniperif *player,
* sampling frequency. If no sample rate is already specified, then
* set one.
*/
+ spin_lock(&player->lock);
if (runtime && (player->stream_settings.iec958.status[3]
== IEC958_AES3_CON_FS_NOTID)) {
switch (runtime->rate) {
@@ -340,6 +341,7 @@ static void uni_player_set_channel_status(struct uniperif *player,
player->stream_settings.iec958.status[3 + (n * 4)] << 24;
SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
}
+ spin_unlock(&player->lock);
/* Update the channel status */
if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
@@ -580,6 +582,59 @@ static int uni_player_prepare_pcm(struct uniperif *player,
}
/*
+ * ALSA uniperipheral iec958 controls
+ */
+static int uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+
+ return 0;
+}
+
+static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct uniperif *player = snd_kcontrol_chip(kcontrol);
+ struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
+
+ spin_lock(&player->lock);
+ ucontrol->value.iec958.status[0] = iec958->status[0];
+ ucontrol->value.iec958.status[1] = iec958->status[1];
+ ucontrol->value.iec958.status[2] = iec958->status[2];
+ ucontrol->value.iec958.status[3] = iec958->status[3];
+ spin_unlock(&player->lock);
+ return 0;
+}
+
+static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct uniperif *player = snd_kcontrol_chip(kcontrol);
+ struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
+
+ spin_lock(&player->lock);
+ iec958->status[0] = ucontrol->value.iec958.status[0];
+ iec958->status[1] = ucontrol->value.iec958.status[1];
+ iec958->status[2] = ucontrol->value.iec958.status[2];
+ iec958->status[3] = ucontrol->value.iec958.status[3];
+ spin_unlock(&player->lock);
+
+ uni_player_set_channel_status(player, NULL);
+
+ return 0;
+}
+
+static struct snd_kcontrol_new uni_player_iec958_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
+ .info = uni_player_ctl_iec958_info,
+ .get = uni_player_ctl_iec958_get,
+ .put = uni_player_ctl_iec958_put,
+};
+
+/*
* uniperif rate adjustement control
*/
static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol,
@@ -599,7 +654,9 @@ static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol,
{
struct uniperif *player = snd_kcontrol_chip(kcontrol);
+ spin_lock(&player->lock);
ucontrol->value.integer.value[0] = player->clk_adj;
+ spin_unlock(&player->lock);
return 0;
}
@@ -633,7 +690,12 @@ static struct snd_kcontrol_new uni_player_clk_adj_ctl = {
.put = snd_sti_clk_adjustment_put,
};
-static struct snd_kcontrol_new *snd_sti_ctl[] = {
+static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = {
+ &uni_player_clk_adj_ctl,
+};
+
+static struct snd_kcontrol_new *snd_sti_iec_ctl[] = {
+ &uni_player_iec958_ctl,
&uni_player_clk_adj_ctl,
};
@@ -1132,10 +1194,13 @@ int uni_player_init(struct platform_device *pdev, struct device_node *node,
player->stream_settings.iec958.status[4] =
IEC958_AES4_CON_MAX_WORDLEN_24 |
IEC958_AES4_CON_WORDLEN_24_20;
- }
- player->num_ctrls = ARRAY_SIZE(snd_sti_ctl);
- player->snd_ctrls = snd_sti_ctl[0];
+ player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl);
+ player->snd_ctrls = snd_sti_iec_ctl[0];
+ } else {
+ player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl);
+ player->snd_ctrls = snd_sti_pcm_ctl[0];
+ }
return 0;
}
Add control to configure IEC60958 settings. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> --- sound/soc/sti/uniperif_player.c | 73 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-)