diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 0c9d0b013eb7..6242c58d3b38 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -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;