mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
asoc: Add sysfs attr for SPDIF interfaces
The format change event signaling for SPDIF input interfaces is adapted to provide format information through sysfs nodes. Change-Id: Ifab1074a0e4b13e08813e27f8694023c2c47bfe1 Signed-off-by: Ralf Herz <rherz@codeaurora.org> Signed-off-by: Mangesh Kunchamwar <mangeshk@codeaurora.org>
This commit is contained in:
parent
044e476310
commit
900bd738dd
1 changed files with 105 additions and 77 deletions
|
|
@ -40,6 +40,7 @@
|
|||
#define CHANNEL_STATUS_MASK_INIT 0x0
|
||||
#define CHANNEL_STATUS_MASK 0x4
|
||||
#define AFE_API_VERSION_CLOCK_SET 1
|
||||
#define MSM_DAI_SYSFS_ENTRY_MAX_LEN 64
|
||||
|
||||
#define DAI_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
|
|
@ -218,6 +219,7 @@ struct msm_dai_q6_spdif_dai_data {
|
|||
u16 port_id;
|
||||
struct afe_spdif_port_config spdif_port;
|
||||
struct afe_event_fmt_update fmt_event;
|
||||
struct kobject *kobj;
|
||||
};
|
||||
|
||||
struct msm_dai_q6_spdif_event_msg {
|
||||
|
|
@ -1459,39 +1461,6 @@ static int msm_dai_q6_spdif_source_get(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_spdif_ext_state_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
|
||||
|
||||
ucontrol->value.integer.value[0] =
|
||||
dai_data->fmt_event.status & 0x3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_spdif_ext_format_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
|
||||
|
||||
ucontrol->value.integer.value[0] =
|
||||
dai_data->fmt_event.data_format & 0x1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_spdif_ext_rate_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
|
||||
|
||||
ucontrol->value.integer.value[0] =
|
||||
dai_data->fmt_event.sample_rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const spdif_format[] = {
|
||||
"LPCM",
|
||||
"Compr"
|
||||
|
|
@ -1501,10 +1470,6 @@ static const char * const spdif_source[] = {
|
|||
"Optical", "EXT-ARC", "Coaxial", "VT-ARC"
|
||||
};
|
||||
|
||||
static const char * const spdif_state[] = {
|
||||
"Inactive", "Active", "EOS"
|
||||
};
|
||||
|
||||
static const struct soc_enum spdif_rx_config_enum[] = {
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
|
||||
};
|
||||
|
|
@ -1514,11 +1479,6 @@ static const struct soc_enum spdif_tx_config_enum[] = {
|
|||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
|
||||
};
|
||||
|
||||
static const struct soc_enum spdif_tx_status_enum[] = {
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_state), spdif_state),
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
|
||||
};
|
||||
|
||||
static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
|
@ -1609,21 +1569,6 @@ static const struct snd_kcontrol_new spdif_tx_config_controls[] = {
|
|||
msm_dai_q6_spdif_format_put)
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new spdif_tx_status_controls[] = {
|
||||
SOC_ENUM_EXT("PRI SPDIF TX EXT State", spdif_tx_status_enum[0],
|
||||
msm_dai_q6_spdif_ext_state_get, NULL),
|
||||
SOC_ENUM_EXT("PRI SPDIF TX EXT Format", spdif_tx_status_enum[1],
|
||||
msm_dai_q6_spdif_ext_format_get, NULL),
|
||||
SOC_SINGLE_EXT("PRI SPDIF TX EXT Rate", 0, 0, 192000, 0,
|
||||
msm_dai_q6_spdif_ext_rate_get, NULL),
|
||||
SOC_ENUM_EXT("SEC SPDIF TX EXT State", spdif_tx_status_enum[0],
|
||||
msm_dai_q6_spdif_ext_state_get, NULL),
|
||||
SOC_ENUM_EXT("SEC SPDIF TX EXT Format", spdif_tx_status_enum[1],
|
||||
msm_dai_q6_spdif_ext_format_get, NULL),
|
||||
SOC_SINGLE_EXT("SEC SPDIF TX EXT Rate", 0, 0, 192000, 0,
|
||||
msm_dai_q6_spdif_ext_rate_get, NULL)
|
||||
};
|
||||
|
||||
static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token,
|
||||
uint32_t *payload, void *private_data)
|
||||
{
|
||||
|
|
@ -1734,6 +1679,102 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_state(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev);
|
||||
|
||||
if (!dai_data) {
|
||||
pr_err("%s: invalid input\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n",
|
||||
dai_data->fmt_event.status);
|
||||
pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.status);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_format(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev);
|
||||
|
||||
if (!dai_data) {
|
||||
pr_err("%s: invalid input\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n",
|
||||
dai_data->fmt_event.data_format);
|
||||
pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.data_format);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_rate(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev);
|
||||
|
||||
if (!dai_data) {
|
||||
pr_err("%s: invalid input\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n",
|
||||
dai_data->fmt_event.sample_rate);
|
||||
pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.sample_rate);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(audio_state, 0444, msm_dai_q6_spdif_sysfs_rda_audio_state,
|
||||
NULL);
|
||||
static DEVICE_ATTR(audio_format, 0444, msm_dai_q6_spdif_sysfs_rda_audio_format,
|
||||
NULL);
|
||||
static DEVICE_ATTR(audio_rate, 0444, msm_dai_q6_spdif_sysfs_rda_audio_rate,
|
||||
NULL);
|
||||
|
||||
static struct attribute *msm_dai_q6_spdif_fs_attrs[] = {
|
||||
&dev_attr_audio_state.attr,
|
||||
&dev_attr_audio_format.attr,
|
||||
&dev_attr_audio_rate.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group msm_dai_q6_spdif_fs_attrs_group = {
|
||||
.attrs = msm_dai_q6_spdif_fs_attrs,
|
||||
};
|
||||
|
||||
static int msm_dai_q6_spdif_sysfs_create(struct snd_soc_dai *dai,
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = sysfs_create_group(&dai->dev->kobj,
|
||||
&msm_dai_q6_spdif_fs_attrs_group);
|
||||
if (rc) {
|
||||
pr_err("%s: failed, rc=%d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
dai_data->kobj = &dai->dev->kobj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm_dai_q6_spdif_sysfs_remove(struct snd_soc_dai *dai,
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data)
|
||||
{
|
||||
if (dai_data->kobj)
|
||||
sysfs_remove_group(dai_data->kobj,
|
||||
&msm_dai_q6_spdif_fs_attrs_group);
|
||||
dai_data->kobj = NULL;
|
||||
}
|
||||
|
||||
static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct msm_dai_q6_spdif_dai_data *dai_data;
|
||||
|
|
@ -1773,40 +1814,24 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai)
|
|||
dai_data));
|
||||
break;
|
||||
case AFE_PORT_ID_PRIMARY_SPDIF_TX:
|
||||
rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data);
|
||||
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_config_controls[0],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_config_controls[1],
|
||||
dai_data));
|
||||
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_status_controls[0],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_status_controls[1],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_status_controls[2],
|
||||
dai_data));
|
||||
break;
|
||||
case AFE_PORT_ID_SECONDARY_SPDIF_TX:
|
||||
rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data);
|
||||
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_config_controls[2],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_config_controls[3],
|
||||
dai_data));
|
||||
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_status_controls[3],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_status_controls[4],
|
||||
dai_data));
|
||||
rc = snd_ctl_add(dai->component->card->snd_card,
|
||||
snd_ctl_new1(&spdif_tx_status_controls[5],
|
||||
dai_data));
|
||||
break;
|
||||
}
|
||||
if (rc < 0)
|
||||
|
|
@ -1866,6 +1891,9 @@ static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai)
|
|||
|
||||
clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
|
||||
}
|
||||
|
||||
msm_dai_q6_spdif_sysfs_remove(dai, dai_data);
|
||||
|
||||
kfree(dai_data);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue