summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/adau1701.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/adau1701.c')
-rw-r--r--sound/soc/codecs/adau1701.c389
1 files changed, 258 insertions, 131 deletions
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index d1124a5b3471..6876462d8bdb 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -1,11 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Driver for ADAU1701 SigmaDSP processor
*
* Copyright 2011 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
* based on an inital version by Cliff Cai <cliff.cai@analog.com>
- *
- * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
@@ -14,17 +13,22 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/of.h>
-#include <linux/of_gpio.h>
-#include <linux/of_device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include <linux/unaligned.h>
+
#include "sigmadsp.h"
#include "adau1701.h"
+#define ADAU1701_SAFELOAD_DATA(i) (0x0810 + (i))
+#define ADAU1701_SAFELOAD_ADDR(i) (0x0815 + (i))
+
#define ADAU1701_DSPCTRL 0x081c
#define ADAU1701_SEROCTL 0x081e
#define ADAU1701_SERICTL 0x081f
@@ -42,6 +46,7 @@
#define ADAU1701_DSPCTRL_CR (1 << 2)
#define ADAU1701_DSPCTRL_DAM (1 << 3)
#define ADAU1701_DSPCTRL_ADM (1 << 4)
+#define ADAU1701_DSPCTRL_IST (1 << 5)
#define ADAU1701_DSPCTRL_SR_48 0x00
#define ADAU1701_DSPCTRL_SR_96 0x01
#define ADAU1701_DSPCTRL_SR_192 0x02
@@ -71,7 +76,7 @@
#define ADAU1701_SEROCTL_WORD_LEN_24 0x0000
#define ADAU1701_SEROCTL_WORD_LEN_20 0x0001
-#define ADAU1701_SEROCTL_WORD_LEN_16 0x0010
+#define ADAU1701_SEROCTL_WORD_LEN_16 0x0002
#define ADAU1701_SEROCTL_WORD_LEN_MASK 0x0003
#define ADAU1701_AUXNPOW_VBPD 0x40
@@ -91,18 +96,26 @@
#define ADAU1701_OSCIPOW_OPD 0x04
#define ADAU1701_DACSET_DACINIT 1
-#define ADAU1707_CLKDIV_UNSET (-1UL)
+#define ADAU1707_CLKDIV_UNSET (-1U)
#define ADAU1701_FIRMWARE "adau1701.bin"
+static const char * const supply_names[] = {
+ "dvdd", "avdd"
+};
+
struct adau1701 {
- int gpio_nreset;
- int gpio_pll_mode[2];
+ struct gpio_desc *gpio_nreset;
+ struct gpio_descs *gpio_pll_mode;
unsigned int dai_fmt;
unsigned int pll_clkdiv;
unsigned int sysclk;
struct regmap *regmap;
+ struct i2c_client *client;
u8 pin_config[12];
+
+ struct sigmadsp *sigmadsp;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
};
static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -159,6 +172,7 @@ static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case ADAU1701_DACSET:
+ case ADAU1701_DSPCTRL:
return true;
default:
return false;
@@ -230,49 +244,97 @@ static int adau1701_reg_read(void *context, unsigned int reg,
*value = 0;
- for (i = 0; i < size; i++)
- *value |= recv_buf[i] << (i * 8);
+ for (i = 0; i < size; i++) {
+ *value <<= 8;
+ *value |= recv_buf[i];
+ }
return 0;
}
-static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
+static int adau1701_safeload(struct sigmadsp *sigmadsp, unsigned int addr,
+ const uint8_t bytes[], size_t len)
+{
+ struct i2c_client *client = to_i2c_client(sigmadsp->dev);
+ struct adau1701 *adau1701 = i2c_get_clientdata(client);
+ unsigned int val;
+ unsigned int i;
+ uint8_t buf[10];
+ int ret;
+
+ ret = regmap_read(adau1701->regmap, ADAU1701_DSPCTRL, &val);
+ if (ret)
+ return ret;
+
+ if (val & ADAU1701_DSPCTRL_IST)
+ msleep(50);
+
+ for (i = 0; i < len / 4; i++) {
+ put_unaligned_le16(ADAU1701_SAFELOAD_DATA(i), buf);
+ buf[2] = 0x00;
+ memcpy(buf + 3, bytes + i * 4, 4);
+ ret = i2c_master_send(client, buf, 7);
+ if (ret < 0)
+ return ret;
+ else if (ret != 7)
+ return -EIO;
+
+ put_unaligned_le16(ADAU1701_SAFELOAD_ADDR(i), buf);
+ put_unaligned_le16(addr + i, buf + 2);
+ ret = i2c_master_send(client, buf, 4);
+ if (ret < 0)
+ return ret;
+ else if (ret != 4)
+ return -EIO;
+ }
+
+ return regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
+ ADAU1701_DSPCTRL_IST, ADAU1701_DSPCTRL_IST);
+}
+
+static const struct sigmadsp_ops adau1701_sigmadsp_ops = {
+ .safeload = adau1701_safeload,
+};
+
+static int adau1701_reset(struct snd_soc_component *component, unsigned int clkdiv,
+ unsigned int rate)
{
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *client = to_i2c_client(codec->dev);
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
int ret;
- if (clkdiv != ADAU1707_CLKDIV_UNSET &&
- gpio_is_valid(adau1701->gpio_pll_mode[0]) &&
- gpio_is_valid(adau1701->gpio_pll_mode[1])) {
+ DECLARE_BITMAP(values, 2);
+ sigmadsp_reset(adau1701->sigmadsp);
+
+ if (clkdiv != ADAU1707_CLKDIV_UNSET && adau1701->gpio_pll_mode) {
switch (clkdiv) {
case 64:
- gpio_set_value(adau1701->gpio_pll_mode[0], 0);
- gpio_set_value(adau1701->gpio_pll_mode[1], 0);
+ __assign_bit(0, values, 0);
+ __assign_bit(1, values, 0);
break;
case 256:
- gpio_set_value(adau1701->gpio_pll_mode[0], 0);
- gpio_set_value(adau1701->gpio_pll_mode[1], 1);
+ __assign_bit(0, values, 0);
+ __assign_bit(1, values, 1);
break;
case 384:
- gpio_set_value(adau1701->gpio_pll_mode[0], 1);
- gpio_set_value(adau1701->gpio_pll_mode[1], 0);
+ __assign_bit(0, values, 1);
+ __assign_bit(1, values, 0);
break;
- case 0: /* fallback */
+ case 0: /* fallback */
case 512:
- gpio_set_value(adau1701->gpio_pll_mode[0], 1);
- gpio_set_value(adau1701->gpio_pll_mode[1], 1);
+ __assign_bit(0, values, 1);
+ __assign_bit(1, values, 1);
break;
}
+ gpiod_multi_set_value_cansleep(adau1701->gpio_pll_mode, values);
}
adau1701->pll_clkdiv = clkdiv;
- if (gpio_is_valid(adau1701->gpio_nreset)) {
- gpio_set_value(adau1701->gpio_nreset, 0);
+ if (adau1701->gpio_nreset) {
+ gpiod_set_value_cansleep(adau1701->gpio_nreset, 0);
/* minimum reset time is 20ns */
udelay(1);
- gpio_set_value(adau1701->gpio_nreset, 1);
+ gpiod_set_value_cansleep(adau1701->gpio_nreset, 1);
/* power-up time may be as long as 85ms */
mdelay(85);
}
@@ -282,9 +344,9 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
* know the correct PLL setup
*/
if (clkdiv != ADAU1707_CLKDIV_UNSET) {
- ret = process_sigma_firmware(client, ADAU1701_FIRMWARE);
+ ret = sigmadsp_setup(adau1701->sigmadsp, rate);
if (ret) {
- dev_warn(codec->dev, "Failed to load firmware\n");
+ dev_warn(component->dev, "Failed to load firmware\n");
return ret;
}
}
@@ -298,21 +360,21 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
return 0;
}
-static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
- snd_pcm_format_t format)
+static int adau1701_set_capture_pcm_format(struct snd_soc_component *component,
+ struct snd_pcm_hw_params *params)
{
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
unsigned int val;
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
+ switch (params_width(params)) {
+ case 16:
val = ADAU1701_SEROCTL_WORD_LEN_16;
break;
- case SNDRV_PCM_FORMAT_S20_3LE:
+ case 20:
val = ADAU1701_SEROCTL_WORD_LEN_20;
break;
- case SNDRV_PCM_FORMAT_S24_LE:
+ case 24:
val = ADAU1701_SEROCTL_WORD_LEN_24;
break;
default:
@@ -320,14 +382,14 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
}
if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) {
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
+ switch (params_width(params)) {
+ case 16:
val |= ADAU1701_SEROCTL_MSB_DEALY16;
break;
- case SNDRV_PCM_FORMAT_S20_3LE:
+ case 20:
val |= ADAU1701_SEROCTL_MSB_DEALY12;
break;
- case SNDRV_PCM_FORMAT_S24_LE:
+ case 24:
val |= ADAU1701_SEROCTL_MSB_DEALY8;
break;
}
@@ -339,23 +401,23 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
return 0;
}
-static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
- snd_pcm_format_t format)
+static int adau1701_set_playback_pcm_format(struct snd_soc_component *component,
+ struct snd_pcm_hw_params *params)
{
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
unsigned int val;
if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
return 0;
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
+ switch (params_width(params)) {
+ case 16:
val = ADAU1701_SERICTL_RIGHTJ_16;
break;
- case SNDRV_PCM_FORMAT_S20_3LE:
+ case 20:
val = ADAU1701_SERICTL_RIGHTJ_20;
break;
- case SNDRV_PCM_FORMAT_S24_LE:
+ case 24:
val = ADAU1701_SERICTL_RIGHTJ_24;
break;
default:
@@ -371,10 +433,9 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
static int adau1701_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
- struct snd_soc_codec *codec = dai->codec;
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_component *component = dai->component;
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
unsigned int clkdiv = adau1701->sysclk / params_rate(params);
- snd_pcm_format_t format;
unsigned int val;
int ret;
@@ -384,7 +445,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
* firmware upload.
*/
if (clkdiv != adau1701->pll_clkdiv) {
- ret = adau1701_reset(codec, clkdiv);
+ ret = adau1701_reset(component, clkdiv, params_rate(params));
if (ret < 0)
return ret;
}
@@ -406,28 +467,27 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
ADAU1701_DSPCTRL_SR_MASK, val);
- format = params_format(params);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return adau1701_set_playback_pcm_format(codec, format);
+ return adau1701_set_playback_pcm_format(component, params);
else
- return adau1701_set_capture_pcm_format(codec, format);
+ return adau1701_set_capture_pcm_format(component, params);
}
static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_component *component = codec_dai->component;
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
unsigned int serictl = 0x00, seroctl = 0x00;
bool invert_lrclk;
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+ case SND_SOC_DAIFMT_CBP_CFP:
/* master, 64-bits per sample, 1 frame per sample */
seroctl |= ADAU1701_SEROCTL_MASTER | ADAU1701_SEROCTL_OBF16
| ADAU1701_SEROCTL_OLF1024;
break;
- case SND_SOC_DAIFMT_CBS_CFS:
+ case SND_SOC_DAIFMT_CBC_CFC:
break;
default:
return -EINVAL;
@@ -486,11 +546,11 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
-static int adau1701_set_bias_level(struct snd_soc_codec *codec,
+static int adau1701_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
switch (level) {
case SND_SOC_BIAS_ON:
@@ -509,15 +569,14 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
break;
}
- codec->dapm.bias_level = level;
return 0;
}
-static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
+static int adau1701_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
{
- struct snd_soc_codec *codec = dai->codec;
+ struct snd_soc_component *component = dai->component;
unsigned int mask = ADAU1701_DSPCTRL_DAM;
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
unsigned int val;
if (mute)
@@ -530,11 +589,11 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
return 0;
}
-static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int adau1701_set_sysclk(struct snd_soc_component *component, int clk_id,
int source, unsigned int freq, int dir)
{
unsigned int val;
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
switch (clk_id) {
case ADAU1701_CLK_SRC_OSC:
@@ -554,6 +613,14 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
return 0;
}
+static int adau1701_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(dai->component);
+
+ return sigmadsp_restrict_params(adau1701->sigmadsp, substream);
+}
+
#define ADAU1701_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
SNDRV_PCM_RATE_192000)
@@ -563,7 +630,9 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
static const struct snd_soc_dai_ops adau1701_dai_ops = {
.set_fmt = adau1701_set_dai_fmt,
.hw_params = adau1701_hw_params,
- .digital_mute = adau1701_digital_mute,
+ .mute_stream = adau1701_mute_stream,
+ .startup = adau1701_startup,
+ .no_capture_mute = 1,
};
static struct snd_soc_dai_driver adau1701_dai = {
@@ -583,7 +652,7 @@ static struct snd_soc_dai_driver adau1701_dai = {
.formats = ADAU1701_FORMATS,
},
.ops = &adau1701_dai_ops,
- .symmetric_rates = 1,
+ .symmetric_rate = 1,
};
#ifdef CONFIG_OF
@@ -594,11 +663,22 @@ static const struct of_device_id adau1701_dt_ids[] = {
MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
#endif
-static int adau1701_probe(struct snd_soc_codec *codec)
+static int adau1701_probe(struct snd_soc_component *component)
{
int i, ret;
unsigned int val;
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
+
+ ret = sigmadsp_attach(adau1701->sigmadsp, component);
+ if (ret)
+ return ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
+ adau1701->supplies);
+ if (ret < 0) {
+ dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
+ return ret;
+ }
/*
* Let the pll_clkdiv variable default to something that won't happen
@@ -609,9 +689,9 @@ static int adau1701_probe(struct snd_soc_codec *codec)
adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
/* initalize with pre-configured pll mode settings */
- ret = adau1701_reset(codec, adau1701->pll_clkdiv);
+ ret = adau1701_reset(component, adau1701->pll_clkdiv, 0);
if (ret < 0)
- return ret;
+ goto exit_regulators_disable;
/* set up pin config */
val = 0;
@@ -627,66 +707,117 @@ static int adau1701_probe(struct snd_soc_codec *codec)
regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
return 0;
+
+exit_regulators_disable:
+
+ regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
+ return ret;
+}
+
+static void adau1701_remove(struct snd_soc_component *component)
+{
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
+
+ if (adau1701->gpio_nreset)
+ gpiod_set_value_cansleep(adau1701->gpio_nreset, 0);
+
+ regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
+}
+
+#ifdef CONFIG_PM
+static int adau1701_suspend(struct snd_soc_component *component)
+{
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
+
+ regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies),
+ adau1701->supplies);
+
+ return 0;
}
-static struct snd_soc_codec_driver adau1701_codec_drv = {
+static int adau1701_resume(struct snd_soc_component *component)
+{
+ struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
+ adau1701->supplies);
+ if (ret < 0) {
+ dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
+ return ret;
+ }
+
+ return adau1701_reset(component, adau1701->pll_clkdiv, 0);
+}
+#else
+#define adau1701_resume NULL
+#define adau1701_suspend NULL
+#endif /* CONFIG_PM */
+
+static const struct snd_soc_component_driver adau1701_component_drv = {
.probe = adau1701_probe,
+ .remove = adau1701_remove,
+ .resume = adau1701_resume,
+ .suspend = adau1701_suspend,
.set_bias_level = adau1701_set_bias_level,
- .idle_bias_off = true,
-
.controls = adau1701_controls,
.num_controls = ARRAY_SIZE(adau1701_controls),
.dapm_widgets = adau1701_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets),
.dapm_routes = adau1701_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
-
.set_sysclk = adau1701_set_sysclk,
+ .use_pmdown_time = 1,
+ .endianness = 1,
};
static const struct regmap_config adau1701_regmap = {
.reg_bits = 16,
.val_bits = 32,
.max_register = ADAU1701_MAX_REGISTER,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_reg = adau1701_volatile_reg,
.reg_write = adau1701_reg_write,
.reg_read = adau1701_reg_read,
};
-static int adau1701_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adau1701_i2c_probe(struct i2c_client *client)
{
struct adau1701 *adau1701;
struct device *dev = &client->dev;
- int gpio_nreset = -EINVAL;
- int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
- int ret;
+ int ret, i;
adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
if (!adau1701)
return -ENOMEM;
- adau1701->regmap = devm_regmap_init(dev, NULL, client,
- &adau1701_regmap);
- if (IS_ERR(adau1701->regmap))
- return PTR_ERR(adau1701->regmap);
+ for (i = 0; i < ARRAY_SIZE(supply_names); i++)
+ adau1701->supplies[i].supply = supply_names[i];
- if (dev->of_node) {
- gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
- if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
- return gpio_nreset;
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(adau1701->supplies),
+ adau1701->supplies);
+ if (ret < 0) {
+ dev_err(dev, "Failed to get regulators: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
+ adau1701->supplies);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable regulators: %d\n", ret);
+ return ret;
+ }
- gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
- "adi,pll-mode-gpios", 0);
- if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT)
- return gpio_pll_mode[0];
+ adau1701->client = client;
+ adau1701->regmap = devm_regmap_init(dev, NULL, client,
+ &adau1701_regmap);
+ if (IS_ERR(adau1701->regmap)) {
+ ret = PTR_ERR(adau1701->regmap);
+ goto exit_regulators_disable;
+ }
- gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
- "adi,pll-mode-gpios", 1);
- if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT)
- return gpio_pll_mode[1];
+ if (dev->of_node) {
of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
&adau1701->pll_clkdiv);
@@ -695,46 +826,44 @@ static int adau1701_i2c_probe(struct i2c_client *client,
ARRAY_SIZE(adau1701->pin_config));
}
- if (gpio_is_valid(gpio_nreset)) {
- ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
- "ADAU1701 Reset");
- if (ret < 0)
- return ret;
+ adau1701->gpio_nreset = devm_gpiod_get_optional(dev, "reset", GPIOD_IN);
+
+ if (IS_ERR(adau1701->gpio_nreset)) {
+ ret = PTR_ERR(adau1701->gpio_nreset);
+ goto exit_regulators_disable;
}
- if (gpio_is_valid(gpio_pll_mode[0]) &&
- gpio_is_valid(gpio_pll_mode[1])) {
- ret = devm_gpio_request_one(dev, gpio_pll_mode[0],
- GPIOF_OUT_INIT_LOW,
- "ADAU1701 PLL mode 0");
- if (ret < 0)
- return ret;
+ adau1701->gpio_pll_mode = devm_gpiod_get_array_optional(dev, "adi,pll-mode", GPIOD_OUT_LOW);
- ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
- GPIOF_OUT_INIT_LOW,
- "ADAU1701 PLL mode 1");
- if (ret < 0)
- return ret;
+ if (IS_ERR(adau1701->gpio_pll_mode)) {
+ ret = PTR_ERR(adau1701->gpio_pll_mode);
+ goto exit_regulators_disable;
}
- adau1701->gpio_nreset = gpio_nreset;
- adau1701->gpio_pll_mode[0] = gpio_pll_mode[0];
- adau1701->gpio_pll_mode[1] = gpio_pll_mode[1];
-
i2c_set_clientdata(client, adau1701);
- ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
+
+ adau1701->sigmadsp = devm_sigmadsp_init_i2c(client,
+ &adau1701_sigmadsp_ops, ADAU1701_FIRMWARE);
+ if (IS_ERR(adau1701->sigmadsp)) {
+ ret = PTR_ERR(adau1701->sigmadsp);
+ goto exit_regulators_disable;
+ }
+
+ ret = devm_snd_soc_register_component(&client->dev,
+ &adau1701_component_drv,
&adau1701_dai, 1);
- return ret;
-}
-static int adau1701_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
+exit_regulators_disable:
+
+ regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
+ return ret;
}
static const struct i2c_device_id adau1701_i2c_id[] = {
- { "adau1701", 0 },
+ { "adau1401" },
+ { "adau1401a" },
+ { "adau1701" },
+ { "adau1702" },
{ }
};
MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id);
@@ -742,11 +871,9 @@ MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id);
static struct i2c_driver adau1701_i2c_driver = {
.driver = {
.name = "adau1701",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(adau1701_dt_ids),
},
.probe = adau1701_i2c_probe,
- .remove = adau1701_i2c_remove,
.id_table = adau1701_i2c_id,
};