summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c5
-rw-r--r--arch/arm/mach-omap2/common-board-devices.h2
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c1
-rw-r--r--include/sound/tlv320aic3x.h65
-rw-r--r--sound/soc/codecs/simple-mux.c9
-rw-r--r--sound/soc/codecs/tlv320aic3x.c120
-rw-r--r--sound/soc/codecs/tlv320aic3x.h43
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.c2
8 files changed, 97 insertions, 150 deletions
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 5e86145db0e2..8897364e550b 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -22,7 +22,6 @@
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/platform_data/mmc-omap.h>
#include <linux/mfd/menelaus.h>
-#include <sound/tlv320aic3x.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -567,10 +566,6 @@ struct menelaus_platform_data n8x0_menelaus_platform_data = {
.late_init = n8x0_menelaus_late_init,
};
-struct aic3x_pdata n810_aic33_data = {
- .gpio_reset = 118,
-};
-
static int __init n8x0_late_initcall(void)
{
if (!board_caps)
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h
index b23962c38fb2..69694af71475 100644
--- a/arch/arm/mach-omap2/common-board-devices.h
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -2,12 +2,10 @@
#ifndef __OMAP_COMMON_BOARD_DEVICES__
#define __OMAP_COMMON_BOARD_DEVICES__
-#include <sound/tlv320aic3x.h>
#include <linux/mfd/menelaus.h>
void *n8x0_legacy_init(void);
extern struct menelaus_platform_data n8x0_menelaus_platform_data;
-extern struct aic3x_pdata n810_aic33_data;
#endif /* __OMAP_COMMON_BOARD_DEVICES__ */
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 5b99d602c87b..9deba798cc91 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -440,7 +440,6 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
#ifdef CONFIG_MACH_NOKIA_N8X0
OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL),
OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data),
- OF_DEV_AUXDATA("tlv320aic3x", 0x18, "2-0018", &n810_aic33_data),
#endif
#ifdef CONFIG_ARCH_OMAP3
OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu",
diff --git a/include/sound/tlv320aic3x.h b/include/sound/tlv320aic3x.h
deleted file mode 100644
index b660a9ed05ec..000000000000
--- a/include/sound/tlv320aic3x.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Platform data for Texas Instruments TLV320AIC3x codec
- *
- * Author: Jarkko Nikula <jarkko.nikula@bitmer.com>
- */
-#ifndef __TLV320AIC3x_H__
-#define __TLV320AIC3x_H__
-
-/* GPIO API */
-enum {
- AIC3X_GPIO1_FUNC_DISABLED = 0,
- AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
- AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
- AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
- AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
- AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
- AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
- AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
- AIC3X_GPIO1_FUNC_INPUT = 8,
- AIC3X_GPIO1_FUNC_OUTPUT = 9,
- AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
- AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
- AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
- AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
- AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
- AIC3X_GPIO1_FUNC_ALL_IRQ = 16
-};
-
-enum {
- AIC3X_GPIO2_FUNC_DISABLED = 0,
- AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
- AIC3X_GPIO2_FUNC_INPUT = 3,
- AIC3X_GPIO2_FUNC_OUTPUT = 4,
- AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
- AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
- AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
- AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
- AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
- AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
- AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
- AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
- AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
-};
-
-enum aic3x_micbias_voltage {
- AIC3X_MICBIAS_OFF = 0,
- AIC3X_MICBIAS_2_0V = 1,
- AIC3X_MICBIAS_2_5V = 2,
- AIC3X_MICBIAS_AVDDV = 3,
-};
-
-struct aic3x_setup_data {
- unsigned int gpio_func[2];
-};
-
-struct aic3x_pdata {
- int gpio_reset; /* < 0 if not used */
- struct aic3x_setup_data *setup;
-
- /* Selects the micbias voltage */
- enum aic3x_micbias_voltage micbias_vg;
-};
-
-#endif
diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c
index d30c0d24d90a..bf67de12d20b 100644
--- a/sound/soc/codecs/simple-mux.c
+++ b/sound/soc/codecs/simple-mux.c
@@ -55,6 +55,14 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
e, NULL);
}
+static unsigned int simple_mux_read(struct snd_soc_component *component,
+ unsigned int reg)
+{
+ struct simple_mux *priv = snd_soc_component_get_drvdata(component);
+
+ return priv->mux;
+}
+
static const struct snd_kcontrol_new simple_mux_mux =
SOC_DAPM_ENUM_EXT("Muxer", simple_mux_enum, simple_mux_control_get, simple_mux_control_put);
@@ -76,6 +84,7 @@ static const struct snd_soc_component_driver simple_mux_component_driver = {
.num_dapm_widgets = ARRAY_SIZE(simple_mux_dapm_widgets),
.dapm_routes = simple_mux_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(simple_mux_dapm_routes),
+ .read = simple_mux_read,
};
static int simple_mux_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 08938801daec..56e795a00e22 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -32,12 +32,12 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/err.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
-#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -45,7 +45,6 @@
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
-#include <sound/tlv320aic3x.h>
#include "tlv320aic3x.h"
@@ -57,8 +56,6 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
"DRVDD", /* ADC Analog and Output Driver Voltage */
};
-static LIST_HEAD(reset_list);
-
struct aic3x_priv;
struct aic3x_disable_nb {
@@ -66,6 +63,10 @@ struct aic3x_disable_nb {
struct aic3x_priv *aic3x;
};
+struct aic3x_setup_data {
+ unsigned int gpio_func[2];
+};
+
/* codec private data */
struct aic3x_priv {
struct snd_soc_component *component;
@@ -77,9 +78,9 @@ struct aic3x_priv {
unsigned int dai_fmt;
unsigned int tdm_delay;
unsigned int slot_width;
- struct list_head list;
int master;
- int gpio_reset;
+ struct gpio_desc *gpio_reset;
+ bool shared_reset;
int power;
u16 model;
@@ -1366,8 +1367,8 @@ static int aic3x_regulator_event(struct notifier_block *nb,
* Put codec to reset and require cache sync as at least one
* of the supplies was disabled
*/
- if (gpio_is_valid(aic3x->gpio_reset))
- gpio_set_value(aic3x->gpio_reset, 0);
+ if (aic3x->gpio_reset)
+ gpiod_set_value(aic3x->gpio_reset, 1);
regcache_mark_dirty(aic3x->regmap);
}
@@ -1387,9 +1388,9 @@ static int aic3x_set_power(struct snd_soc_component *component, int power)
goto out;
aic3x->power = 1;
- if (gpio_is_valid(aic3x->gpio_reset)) {
+ if (aic3x->gpio_reset) {
udelay(1);
- gpio_set_value(aic3x->gpio_reset, 1);
+ gpiod_set_value(aic3x->gpio_reset, 0);
}
/* Sync reg_cache with the hardware */
@@ -1595,19 +1596,6 @@ static int aic3x_init(struct snd_soc_component *component)
return 0;
}
-static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
-{
- struct aic3x_priv *a;
-
- list_for_each_entry(a, &reset_list, list) {
- if (gpio_is_valid(aic3x->gpio_reset) &&
- aic3x->gpio_reset == a->gpio_reset)
- return true;
- }
-
- return false;
-}
-
static int aic3x_component_probe(struct snd_soc_component *component)
{
struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
@@ -1748,7 +1736,6 @@ static const struct reg_sequence aic3007_class_d[] = {
int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver_data)
{
- struct aic3x_pdata *pdata = dev->platform_data;
struct aic3x_priv *aic3x;
struct aic3x_setup_data *ai3x_setup;
struct device_node *np = dev->of_node;
@@ -1768,28 +1755,11 @@ int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver
regcache_cache_only(aic3x->regmap, true);
dev_set_drvdata(dev, aic3x);
- if (pdata) {
- aic3x->gpio_reset = pdata->gpio_reset;
- aic3x->setup = pdata->setup;
- aic3x->micbias_vg = pdata->micbias_vg;
- } else if (np) {
+ if (np) {
ai3x_setup = devm_kzalloc(dev, sizeof(*ai3x_setup), GFP_KERNEL);
if (!ai3x_setup)
return -ENOMEM;
- ret = of_get_named_gpio(np, "reset-gpios", 0);
- if (ret >= 0) {
- aic3x->gpio_reset = ret;
- } else {
- ret = of_get_named_gpio(np, "gpio-reset", 0);
- if (ret > 0) {
- dev_warn(dev, "Using deprecated property \"gpio-reset\", please update your DT");
- aic3x->gpio_reset = ret;
- } else {
- aic3x->gpio_reset = -1;
- }
- }
-
if (of_property_read_u32_array(np, "ai3x-gpio-func",
ai3x_setup->gpio_func, 2) >= 0) {
aic3x->setup = ai3x_setup;
@@ -1814,29 +1784,43 @@ int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver
} else {
aic3x->micbias_vg = AIC3X_MICBIAS_OFF;
}
-
- } else {
- aic3x->gpio_reset = -1;
}
aic3x->model = driver_data;
- if (gpio_is_valid(aic3x->gpio_reset) &&
- !aic3x_is_shared_reset(aic3x)) {
- ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
- if (ret != 0)
- goto err;
- gpio_direction_output(aic3x->gpio_reset, 0);
+ aic3x->gpio_reset = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_HIGH);
+ ret = PTR_ERR_OR_ZERO(aic3x->gpio_reset);
+ if (ret) {
+ if (ret != -EBUSY)
+ return ret;
+
+ /*
+ * Apparently there are setups where the codec is sharing
+ * its reset line. Try to get it non-exclusively, although
+ * the utility of this is unclear: how do we make sure that
+ * resetting one chip will not disturb the others that share
+ * the same line?
+ */
+ aic3x->gpio_reset = devm_gpiod_get(dev, "reset",
+ GPIOD_ASIS | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+ ret = PTR_ERR_OR_ZERO(aic3x->gpio_reset);
+ if (ret)
+ return ret;
+
+ aic3x->shared_reset = true;
}
+ gpiod_set_consumer_name(aic3x->gpio_reset, "tlv320aic3x reset");
+
for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
aic3x->supplies[i].supply = aic3x_supply_names[i];
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(aic3x->supplies),
aic3x->supplies);
- if (ret != 0) {
+ if (ret) {
dev_err(dev, "Failed to request supplies: %d\n", ret);
- goto err_gpio;
+ return ret;
}
aic3x_configure_ocmv(dev, aic3x);
@@ -1845,26 +1829,14 @@ int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver
ret = regmap_register_patch(aic3x->regmap, aic3007_class_d,
ARRAY_SIZE(aic3007_class_d));
if (ret != 0)
- dev_err(dev, "Failed to init class D: %d\n",
- ret);
+ dev_err(dev, "Failed to init class D: %d\n", ret);
}
ret = devm_snd_soc_register_component(dev, &soc_component_dev_aic3x, &aic3x_dai, 1);
-
- if (ret != 0)
- goto err_gpio;
-
- INIT_LIST_HEAD(&aic3x->list);
- list_add(&aic3x->list, &reset_list);
+ if (ret)
+ return ret;
return 0;
-
-err_gpio:
- if (gpio_is_valid(aic3x->gpio_reset) &&
- !aic3x_is_shared_reset(aic3x))
- gpio_free(aic3x->gpio_reset);
-err:
- return ret;
}
EXPORT_SYMBOL(aic3x_probe);
@@ -1872,13 +1844,9 @@ void aic3x_remove(struct device *dev)
{
struct aic3x_priv *aic3x = dev_get_drvdata(dev);
- list_del(&aic3x->list);
-
- if (gpio_is_valid(aic3x->gpio_reset) &&
- !aic3x_is_shared_reset(aic3x)) {
- gpio_set_value(aic3x->gpio_reset, 0);
- gpio_free(aic3x->gpio_reset);
- }
+ /* Leave the codec in reset state */
+ if (aic3x->gpio_reset && !aic3x->shared_reset)
+ gpiod_set_value(aic3x->gpio_reset, 1);
}
EXPORT_SYMBOL(aic3x_remove);
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 14298f9e6d9b..066e5a6322b8 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -298,4 +298,47 @@ enum {
#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
#define AIC3X_BUTTON_DEBOUNCE_MASK 3
+/* GPIO API */
+enum {
+ AIC3X_GPIO1_FUNC_DISABLED = 0,
+ AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
+ AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
+ AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
+ AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
+ AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
+ AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
+ AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
+ AIC3X_GPIO1_FUNC_INPUT = 8,
+ AIC3X_GPIO1_FUNC_OUTPUT = 9,
+ AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
+ AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
+ AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
+ AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
+ AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
+ AIC3X_GPIO1_FUNC_ALL_IRQ = 16
+};
+
+enum {
+ AIC3X_GPIO2_FUNC_DISABLED = 0,
+ AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
+ AIC3X_GPIO2_FUNC_INPUT = 3,
+ AIC3X_GPIO2_FUNC_OUTPUT = 4,
+ AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
+ AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
+ AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
+ AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
+ AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
+ AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
+ AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
+ AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
+ AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
+};
+
+enum aic3x_micbias_voltage {
+ AIC3X_MICBIAS_OFF = 0,
+ AIC3X_MICBIAS_2_0V = 1,
+ AIC3X_MICBIAS_2_5V = 2,
+ AIC3X_MICBIAS_AVDDV = 3,
+};
+
#endif /* _AIC3X_H */
diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c
index 6e39eda77385..851c516c8f5b 100644
--- a/sound/soc/intel/boards/sof_cirrus_common.c
+++ b/sound/soc/intel/boards/sof_cirrus_common.c
@@ -155,7 +155,7 @@ static const char * const cs35l41_name_prefixes[] = { "WL", "WR", "TL", "TR" };
*/
static int cs35l41_compute_codec_conf(void)
{
- const char * const uid_strings[] = { "0", "1", "2", "3" };
+ static const char * const uid_strings[] = { "0", "1", "2", "3" };
unsigned int uid, sz = 0;
struct acpi_device *adev;
struct device *physdev;