Browse Source

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 <[email protected]>
Signed-off-by: Mangesh Kunchamwar <[email protected]>
Ralf Herz 6 years ago
parent
commit
900bd738dd
1 changed files with 105 additions and 77 deletions
  1. 105 77
      asoc/msm-dai-q6-v2.c

+ 105 - 77
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;