Browse Source

Merge "ASoC: wsa883x: update supply and variant configuration" into audio-drivers.lnx.5.0

Linux Build Service Account 5 years ago
parent
commit
6744f565b2
2 changed files with 134 additions and 2 deletions
  1. 10 1
      asoc/codecs/wsa883x/internal.h
  2. 124 1
      asoc/codecs/wsa883x/wsa883x.c

+ 10 - 1
asoc/codecs/wsa883x/internal.h

@@ -26,7 +26,11 @@
 #define WSA883X_DRV_NAME "wsa883x-codec"
 #define WSA883X_NUM_RETRY	5
 
-#define WSA883X_VERSION_ENTRY_SIZE 27
+#define WSA883X_VERSION_ENTRY_SIZE 32
+#define WSA883X_VARIANT_ENTRY_SIZE 32
+
+#define WSA883X_VERSION_1_0 0
+#define WSA883X_VERSION_1_1 1
 
 enum {
 	G_18DB = 0,
@@ -98,10 +102,12 @@ struct wsa883x_priv {
 	struct mutex res_lock;
 	struct snd_info_entry *entry;
 	struct snd_info_entry *version_entry;
+	struct snd_info_entry *variant_entry;
 	struct device_node *wsa_rst_np;
 	int pa_mute;
 	int curr_temp;
 	int variant;
+	int version;
 	u8 pa_gain;
 	struct irq_domain *virq;
 	struct wcd_irq_info irq_info;
@@ -119,6 +125,9 @@ struct wsa883x_priv {
 	int (*register_notifier)(void *handle,
 				struct notifier_block *nblock, bool enable);
 	struct delayed_work vbat_work;
+	struct cdc_regulator *regulator;
+	int num_supplies;
+	struct regulator_bulk_data *supplies;
 };
 
 #endif /* WSA883X_INTERNAL_H */

+ 124 - 1
asoc/codecs/wsa883x/wsa883x.c

@@ -26,6 +26,7 @@
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
 #include <asoc/msm-cdc-pinctrl.h>
+#include <asoc/msm-cdc-supply.h>
 #include "wsa883x.h"
 #include "internal.h"
 
@@ -594,7 +595,17 @@ static ssize_t wsa883x_codec_version_read(struct snd_info_entry *entry,
 		return -EINVAL;
 	}
 
-	len = snprintf(buffer, sizeof(buffer), "WSA883X-SOUNDWIRE_1_0\n");
+	switch (wsa883x->version) {
+	case WSA883X_VERSION_1_0:
+		len = snprintf(buffer, sizeof(buffer), "WSA883X_1_0\n");
+		break;
+	case WSA883X_VERSION_1_1:
+		len = snprintf(buffer, sizeof(buffer), "WSA883X_1_1\n");
+		break;
+	default:
+		len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
+		break;
+	}
 
 	return simple_read_from_buffer(buf, count, &pos, buffer, len);
 }
@@ -603,6 +614,41 @@ static struct snd_info_entry_ops wsa883x_codec_info_ops = {
 	.read = wsa883x_codec_version_read,
 };
 
+static ssize_t wsa883x_variant_read(struct snd_info_entry *entry,
+				    void *file_private_data,
+				    struct file *file,
+				    char __user *buf, size_t count,
+				    loff_t pos)
+{
+	struct wsa883x_priv *wsa883x;
+	char buffer[WSA883X_VARIANT_ENTRY_SIZE];
+	int len = 0;
+
+	wsa883x = (struct wsa883x_priv *) entry->private_data;
+	if (!wsa883x) {
+		pr_err("%s: wsa883x priv is null\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (wsa883x->variant) {
+	case WSA8830:
+		len = snprintf(buffer, sizeof(buffer), "WSA8830\n");
+		break;
+	case WSA8835:
+		len = snprintf(buffer, sizeof(buffer), "WSA8835\n");
+		break;
+	default:
+		len = snprintf(buffer, sizeof(buffer), "UNDEFINED\n");
+		break;
+	}
+
+	return simple_read_from_buffer(buf, count, &pos, buffer, len);
+}
+
+static struct snd_info_entry_ops wsa883x_variant_ops = {
+	.read = wsa883x_variant_read,
+};
+
 /*
  * wsa883x_codec_info_create_codec_entry - creates wsa883x module
  * @codec_root: The parent directory
@@ -617,6 +663,7 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
 					  struct snd_soc_component *component)
 {
 	struct snd_info_entry *version_entry;
+	struct snd_info_entry *variant_entry;
 	struct wsa883x_priv *wsa883x;
 	struct snd_soc_card *card;
 	char name[80];
@@ -625,7 +672,13 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
 		return -EINVAL;
 
 	wsa883x = snd_soc_component_get_drvdata(component);
+	if (wsa883x->entry) {
+		dev_dbg(wsa883x->dev,
+			"%s:wsa883x module already created\n", __func__);
+		return 0;
+	}
 	card = component->card;
+
 	snprintf(name, sizeof(name), "%s.%x", "wsa883x",
 		 (u32)wsa883x->swr_slave->addr);
 
@@ -665,6 +718,31 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
 	}
 	wsa883x->version_entry = version_entry;
 
+	variant_entry = snd_info_create_card_entry(card->snd_card,
+						   "variant",
+						   wsa883x->entry);
+	if (!variant_entry) {
+		dev_dbg(component->dev,
+			"%s: failed to create wsa883x variant entry\n",
+			__func__);
+		snd_info_free_entry(version_entry);
+		snd_info_free_entry(wsa883x->entry);
+		return -ENOMEM;
+	}
+
+	variant_entry->private_data = wsa883x;
+	variant_entry->size = WSA883X_VARIANT_ENTRY_SIZE;
+	variant_entry->content = SNDRV_INFO_CONTENT_DATA;
+	variant_entry->c.ops = &wsa883x_variant_ops;
+
+	if (snd_info_register(variant_entry) < 0) {
+		snd_info_free_entry(variant_entry);
+		snd_info_free_entry(version_entry);
+		snd_info_free_entry(wsa883x->entry);
+		return -ENOMEM;
+	}
+	wsa883x->variant_entry = variant_entry;
+
 	return 0;
 }
 EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry);
@@ -1105,6 +1183,7 @@ static int wsa883x_codec_probe(struct snd_soc_component *component)
 {
 	struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
 	struct swr_device *dev;
+	int variant = 0, version = 0;
 
 	if (!wsa883x)
 		return -EINVAL;
@@ -1112,6 +1191,15 @@ static int wsa883x_codec_probe(struct snd_soc_component *component)
 
 	dev = wsa883x->swr_slave;
 	wsa883x->component = component;
+
+	variant = (snd_soc_component_read32(component, WSA883X_OTP_REG_0)
+					    & 0x0F);
+	wsa883x->variant = variant;
+
+	version = (snd_soc_component_read32(component, WSA883X_CHIP_ID0)
+					    & 0xFF);
+	wsa883x->version = version;
+
 	wsa883x_codec_init(component);
 	wsa883x->global_pa_cnt = 0;
 	INIT_DELAYED_WORK(&wsa883x->vbat_work, wsa883x_vbat_monitor_work);
@@ -1188,6 +1276,37 @@ static int wsa883x_event_notify(struct notifier_block *nb,
 	return 0;
 }
 
+static int wsa883x_enable_supplies(struct device * dev,
+				   struct wsa883x_priv *priv)
+{
+	int ret = 0;
+
+	/* Parse power supplies */
+	msm_cdc_get_power_supplies(dev, &priv->regulator,
+				   &priv->num_supplies);
+	if (!priv->regulator || (priv->num_supplies <= 0)) {
+		dev_err(dev, "%s: no power supplies defined\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = msm_cdc_init_supplies(dev, &priv->supplies,
+				    priv->regulator, priv->num_supplies);
+	if (!priv->supplies) {
+		dev_err(dev, "%s: Cannot init wsa supplies\n",
+			__func__);
+		return ret;
+	}
+
+	ret = msm_cdc_enable_static_supplies(dev, priv->supplies,
+					     priv->regulator,
+					     priv->num_supplies);
+	if (ret)
+		dev_err(dev, "%s: wsa static supply enable failed!\n",
+			__func__);
+
+	return ret;
+}
+
 static int wsa883x_swr_probe(struct swr_device *pdev)
 {
 	int ret = 0, i = 0;
@@ -1201,6 +1320,10 @@ static int wsa883x_swr_probe(struct swr_device *pdev)
 	if (!wsa883x)
 		return -ENOMEM;
 
+	ret = wsa883x_enable_supplies(&pdev->dev, wsa883x);
+	if (ret)
+		return -EINVAL;
+
 	wsa883x->wsa_rst_np = of_parse_phandle(pdev->dev.of_node,
 					     "qcom,spkr-sd-n-node", 0);
 	if (!wsa883x->wsa_rst_np) {