summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/wcd9335.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wcd9335.c')
-rw-r--r--sound/soc/codecs/wcd9335.c165
1 files changed, 44 insertions, 121 deletions
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index deb15b95992d..5e19e813748d 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/bitops.h>
@@ -16,7 +17,7 @@
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <sound/soc-dapm.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <sound/tlv.h>
@@ -158,6 +159,8 @@
{"AMIC MUX" #id, "ADC5", "ADC5"}, \
{"AMIC MUX" #id, "ADC6", "ADC6"}
+#define NUM_CODEC_DAIS 7
+
enum {
WCD9335_RX0 = 0,
WCD9335_RX1,
@@ -297,7 +300,6 @@ struct wcd9335_codec {
struct clk *mclk;
struct clk *native_clk;
u32 mclk_rate;
- u8 version;
struct slim_device *slim;
struct slim_device *slim_ifc_dev;
@@ -329,8 +331,7 @@ struct wcd9335_codec {
int comp_enabled[COMPANDER_MAX];
int intr1;
- int reset_gpio;
- struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
+ struct gpio_desc *reset_gpio;
unsigned int rx_port_value[WCD9335_RX_MAX];
unsigned int tx_port_value[WCD9335_TX_MAX];
@@ -345,10 +346,6 @@ struct wcd9335_codec {
int dmic_0_1_clk_cnt;
int dmic_2_3_clk_cnt;
int dmic_4_5_clk_cnt;
- int dmic_sample_rate;
- int mad_dmic_sample_rate;
-
- int native_clk_users;
};
struct wcd9335_irq {
@@ -357,6 +354,10 @@ struct wcd9335_irq {
char *name;
};
+static const char * const wcd9335_supplies[] = {
+ "vdd-buck", "vdd-buck-sido", "vdd-tx", "vdd-rx", "vdd-io",
+};
+
static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = {
WCD9335_SLIM_TX_CH(0),
WCD9335_SLIM_TX_CH(1),
@@ -397,13 +398,13 @@ struct interp_sample_rate {
int rate_val;
};
-static struct interp_sample_rate int_mix_rate_val[] = {
+static const struct interp_sample_rate int_mix_rate_val[] = {
{48000, 0x4}, /* 48K */
{96000, 0x5}, /* 96K */
{192000, 0x6}, /* 192K */
};
-static struct interp_sample_rate int_prim_rate_val[] = {
+static const struct interp_sample_rate int_prim_rate_val[] = {
{8000, 0x0}, /* 8K */
{16000, 0x1}, /* 16K */
{24000, -EINVAL},/* 24K */
@@ -1983,8 +1984,10 @@ static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd,
}
static int wcd9335_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_slot,
- unsigned int rx_num, unsigned int *rx_slot)
+ unsigned int tx_num,
+ const unsigned int *tx_slot,
+ unsigned int rx_num,
+ const unsigned int *rx_slot)
{
struct wcd9335_codec *wcd;
int i;
@@ -2012,7 +2015,7 @@ static int wcd9335_set_channel_map(struct snd_soc_dai *dai,
return 0;
}
-static int wcd9335_get_channel_map(struct snd_soc_dai *dai,
+static int wcd9335_get_channel_map(const struct snd_soc_dai *dai,
unsigned int *tx_num, unsigned int *tx_slot,
unsigned int *rx_num, unsigned int *rx_slot)
{
@@ -2717,25 +2720,23 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
unsigned int decimator;
char *dec_adc_mux_name = NULL;
- char *widget_name = NULL;
- char *wname;
+ char *widget_name;
int ret = 0, amic_n;
u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
u16 tx_gain_ctl_reg;
char *dec;
u8 hpf_coff_freq;
- widget_name = kmemdup_nul(w->name, 15, GFP_KERNEL);
- if (!widget_name)
+ char *wname __free(kfree) = kmemdup_nul(w->name, 15, GFP_KERNEL);
+ if (!wname)
return -ENOMEM;
- wname = widget_name;
+ widget_name = wname;
dec_adc_mux_name = strsep(&widget_name, " ");
if (!dec_adc_mux_name) {
dev_err(comp->dev, "%s: Invalid decimator = %s\n",
__func__, w->name);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
dec_adc_mux_name = widget_name;
@@ -2743,16 +2744,14 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
if (!dec) {
dev_err(comp->dev, "%s: decimator index not found\n",
__func__);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
ret = kstrtouint(dec, 10, &decimator);
if (ret < 0) {
dev_err(comp->dev, "%s: Invalid decimator = %s\n",
__func__, wname);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator;
@@ -2839,62 +2838,20 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x00);
break;
}
-out:
- kfree(wname);
+
return ret;
}
static u8 wcd9335_get_dmic_clk_val(struct snd_soc_component *component,
- u32 mclk_rate, u32 dmic_clk_rate)
+ u32 mclk_rate)
{
- u32 div_factor;
u8 dmic_ctl_val;
- dev_err(component->dev,
- "%s: mclk_rate = %d, dmic_sample_rate = %d\n",
- __func__, mclk_rate, dmic_clk_rate);
-
- /* Default value to return in case of error */
if (mclk_rate == WCD9335_MCLK_CLK_9P6MHZ)
dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
else
dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
- if (dmic_clk_rate == 0) {
- dev_err(component->dev,
- "%s: dmic_sample_rate cannot be 0\n",
- __func__);
- goto done;
- }
-
- div_factor = mclk_rate / dmic_clk_rate;
- switch (div_factor) {
- case 2:
- dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
- break;
- case 3:
- dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
- break;
- case 4:
- dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4;
- break;
- case 6:
- dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6;
- break;
- case 8:
- dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8;
- break;
- case 16:
- dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16;
- break;
- default:
- dev_err(component->dev,
- "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n",
- __func__, div_factor, mclk_rate, dmic_clk_rate);
- break;
- }
-
-done:
return dmic_ctl_val;
}
@@ -2948,11 +2905,7 @@ static int wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- dmic_rate_val =
- wcd9335_get_dmic_clk_val(comp,
- wcd->mclk_rate,
- wcd->dmic_sample_rate);
-
+ dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate);
(*dmic_clk_cnt)++;
if (*dmic_clk_cnt == 1) {
snd_soc_component_update_bits(comp, dmic_clk_reg,
@@ -2964,10 +2917,7 @@ static int wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMD:
- dmic_rate_val =
- wcd9335_get_dmic_clk_val(comp,
- wcd->mclk_rate,
- wcd->mad_dmic_sample_rate);
+ dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate);
(*dmic_clk_cnt)--;
if (*dmic_clk_cnt == 0) {
snd_soc_component_update_bits(comp, dmic_clk_reg,
@@ -4024,7 +3974,7 @@ static irqreturn_t wcd9335_slimbus_irq(int irq, void *data)
return ret;
}
-static struct wcd9335_irq wcd9335_irqs[] = {
+static const struct wcd9335_irq wcd9335_irqs[] = {
{
.irq = WCD9335_IRQ_SLIMBUS,
.handler = wcd9335_slimbus_irq,
@@ -4961,7 +4911,7 @@ static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg)
}
}
-static struct regmap_config wcd9335_regmap_config = {
+static const struct regmap_config wcd9335_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_MAPLE,
@@ -4985,7 +4935,7 @@ static const struct regmap_range_cfg wcd9335_ifc_ranges[] = {
},
};
-static struct regmap_config wcd9335_ifc_regmap_config = {
+static const struct regmap_config wcd9335_ifc_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.can_multi_write = true,
@@ -5028,53 +4978,30 @@ static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = {
static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
{
struct device *dev = wcd->dev;
- struct device_node *np = dev->of_node;
int ret;
- wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
- if (wcd->reset_gpio < 0) {
- dev_err(dev, "Reset GPIO missing from DT\n");
- return wcd->reset_gpio;
- }
+ wcd->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(wcd->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(wcd->reset_gpio), "Reset GPIO missing from DT\n");
wcd->mclk = devm_clk_get(dev, "mclk");
- if (IS_ERR(wcd->mclk)) {
- dev_err(dev, "mclk not found\n");
- return PTR_ERR(wcd->mclk);
- }
+ if (IS_ERR(wcd->mclk))
+ return dev_err_probe(dev, PTR_ERR(wcd->mclk), "mclk not found\n");
wcd->native_clk = devm_clk_get(dev, "slimbus");
- if (IS_ERR(wcd->native_clk)) {
- dev_err(dev, "slimbus clock not found\n");
- return PTR_ERR(wcd->native_clk);
- }
-
- wcd->supplies[0].supply = "vdd-buck";
- wcd->supplies[1].supply = "vdd-buck-sido";
- wcd->supplies[2].supply = "vdd-tx";
- wcd->supplies[3].supply = "vdd-rx";
- wcd->supplies[4].supply = "vdd-io";
+ if (IS_ERR(wcd->native_clk))
+ return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n");
- ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
- if (ret) {
- dev_err(dev, "Failed to get supplies: err = %d\n", ret);
- return ret;
- }
+ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd9335_supplies),
+ wcd9335_supplies);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
return 0;
}
static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
{
- struct device *dev = wcd->dev;
- int ret;
-
- ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies);
- if (ret) {
- dev_err(dev, "Failed to get supplies: err = %d\n", ret);
- return ret;
- }
-
/*
* For WCD9335, it takes about 600us for the Vout_A and
* Vout_D to be ready after BUCK_SIDO is powered up.
@@ -5084,9 +5011,9 @@ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
*/
usleep_range(600, 650);
- gpio_direction_output(wcd->reset_gpio, 0);
+ gpiod_set_value(wcd->reset_gpio, 1);
msleep(20);
- gpio_set_value(wcd->reset_gpio, 1);
+ gpiod_set_value(wcd->reset_gpio, 0);
msleep(20);
return 0;
@@ -5107,7 +5034,6 @@ static int wcd9335_bring_up(struct wcd9335_codec *wcd)
if (byte0 == 0x1) {
dev_info(wcd->dev, "WCD9335 CODEC version is v2.0\n");
- wcd->version = WCD9335_VERSION_2_0;
regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01);
regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00);
regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F);
@@ -5159,10 +5085,8 @@ static int wcd9335_slim_probe(struct slim_device *slim)
wcd->dev = dev;
ret = wcd9335_parse_dt(wcd);
- if (ret) {
- dev_err(dev, "Error parsing DT: %d\n", ret);
+ if (ret)
return ret;
- }
ret = wcd9335_power_on_reset(wcd);
if (ret)
@@ -5243,4 +5167,3 @@ static struct slim_driver wcd9335_slim_driver = {
module_slim_driver(wcd9335_slim_driver);
MODULE_DESCRIPTION("WCD9335 slim driver");
MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("slim:217:1a0:*");