ASoC: codecs: some more improvements for adau1701
Subsystems (4)
v4 cover ASoC: codecs: some more improvements for adau1701
v4:
- added one more patch to move the firmware download, for more clarity.
- postpone the firmware download to the first call of hw_params(), so we don't need to pass a default pll div in DT.
- drop adi,pll-clkdiv entirely
v3:
- fixed documentation for adi,pll-clkdiv
- droped implicit I2C_M_STOP
- moved regcache_sync() to adau1761_reset()
- added regcache_mark_dirty()
- made gpio_pll_mode and array
- dropped ADAU1701_CLKDIV_MCLK_LRCLK
Daniel Mack (4):
ASoC: codecs: adau1701: move firmware download to adau1701_reset()
ASoC: codecs: adau1701: allow configuration of PLL mode pins
ASoC: codecs: adau1701: switch to direct regmap API usage
ASoC: codecs: adau1701: add support for pin muxing
.../devicetree/bindings/sound/adi,adau1701.txt | 12 + sound/soc/codecs/adau1701.c | 277 ++++++++++++++++----- 2 files changed, 232 insertions(+), 57 deletions(-)
Signature · 1 line
1.8.1.4
PATCH v4 1/4 ASoC: codecs: adau1701: move firmware download to adau1701_reset()
The chip needs a new download after each reset, so the code to do that needs to live in adau1701_reset().
--- sound/soc/codecs/adau1701.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-)
sound/soc/codecs/adau1701.c +12 -20
@@ -184,27 +184,20 @@ static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg)return value; } -static void adau1701_reset (struct snd_soc_codec *codec) +static int adau1701_reset (struct snd_soc_codec *codec) {struct adau1701 *adau1701 =snd_soc_codec_get_drvdata (codec); - -if (!gpio_is_valid (adau1701->gpio_nreset)) -return ; - -gpio_set_value (adau1701->gpio_nreset,0 ); -/* minimum reset time is 20ns */ -udelay (1 ); -gpio_set_value (adau1701->gpio_nreset,1 ); -/* power-up time may be as long as 85ms */ -mdelay (85 ); -} - -static int adau1701_init (struct snd_soc_codec *codec) -{ -int ret;struct i2c_client *client =to_i2c_client (codec->dev); +int ret; -adau1701_reset (codec); +if (gpio_is_valid (adau1701->gpio_nreset)) { +gpio_set_value (adau1701->gpio_nreset,0 ); +/* minimum reset time is 20ns */ +udelay (1 ); +gpio_set_value (adau1701->gpio_nreset,1 ); +/* power-up time may be as long as 85ms */ +mdelay (85 ); + } ret =process_sigma_firmware (client,ADAU1701_FIRMWARE );if (ret) {
@@ -213,6 +206,7 @@ static int adau1701_init(struct snd_soc_codec *codec) }snd_soc_write (codec,ADAU1701_DACSET ,ADAU1701_DACSET_DACINIT ); +snd_soc_write (codec,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR );return 0 ; }
@@ -498,12 +492,10 @@ static int adau1701_probe(struct snd_soc_codec *codec) codec->control_data =to_i2c_client (codec->dev); - ret =adau1701_init (codec); + ret =adau1701_reset (codec);if (ret)return ret; -snd_soc_write (codec,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR ); -return 0 ; }
Signature · 1 line
1.8.1.4
PATCH v4 2/4 ASoC: codecs: adau1701: allow configuration of PLL mode pins
In reply to Daniel MackThe ADAU1701 has 2 hardware pins to configure the PLL mode in accordance to the MCLK-to-LRCLK ratio. These pins have to be stable before the chip is released from reset, and a full reset cycle, including a new firmware download is needed whenever they change.
This patch adds GPIO properties to the DT bindings of the Codec, and implements makes the set_sysclk memorize the configured sysclk.
Because the run-time parameters are unknown at probe time, the first firmware download is postponed to the first hw_params call, when the driver can determine the mclk/lrclk divider. Subsequent downloads are only issued when the divider configuration changes.
--- .../devicetree/bindings/sound/adi,adau1701.txt | 6 ++ sound/soc/codecs/adau1701.c | 105 +++++++++++++++++++-- 2 files changed, 104 insertions(+), 7 deletions(-)
Documentation/devicetree/bindings/sound/adi,adau1701.txt +6 -0
@@ -11,6 +11,11 @@ Optional properties: - reset-gpio: A GPIO spec to define which pin is connected to the chip's !RESET pin. If specified, the driver will assert a hardware reset at probe time. + - adi,pll-mode-gpios: An array of two GPIO specs to describe the GPIOs + the ADAU's PLL config pins are connected to. + The state of the pins are set according to the + configured clock divider on ASoC side before the + firmware is loaded. Examples:
@@ -19,5 +24,6 @@ Examples: compatible = "adi,adau1701"; reg = <0x34>; reset-gpio = <&gpio 23 0>; + adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>; }; };
sound/soc/codecs/adau1701.c +98 -7
181 lines not on this page · raw message
Signature · 1 line
1.8.1.4
PATCH v4 3/4 ASoC: codecs: adau1701: switch to direct regmap API usage
In reply to Daniel MackThe hardware I/O has to be open-coded due to registers of unequal sizes. Other than that, the transition is straight forward.
--- sound/soc/codecs/adau1701.c | 118 +++++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 33 deletions(-)
sound/soc/codecs/adau1701.c +85 -33
@@ -16,6 +16,7 @@#include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_device.h> +#include <linux/regmap.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h>
@@ -24,16 +25,16 @@#include "sigmadsp.h" #include "adau1701.h" -#define ADAU1701_DSPCTRL 0x1c -#define ADAU1701_SEROCTL 0x1e -#define ADAU1701_SERICTL 0x1f +#define ADAU1701_DSPCTRL 0x081c +#define ADAU1701_SEROCTL 0x081e +#define ADAU1701_SERICTL 0x081f -#define ADAU1701_AUXNPOW 0x22 +#define ADAU1701_AUXNPOW 0x0822 -#define ADAU1701_OSCIPOW 0x26 -#define ADAU1701_DACSET 0x27 +#define ADAU1701_OSCIPOW 0x0826 +#define ADAU1701_DACSET 0x0827 -#define ADAU1701_NUM_REGS 0x28 +#define ADAU1701_MAX_REGISTER 0x0828#define ADAU1701_DSPCTRL_CR (1 << 2)#define ADAU1701_DSPCTRL_DAM (1 << 3)
@@ -97,6 +98,7 @@ struct adau1701 {unsigned int dai_fmt;unsigned int pll_clkdiv;unsigned int sysclk; +struct regmap *regmap; };static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -128,7 +130,7 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = { { "ADC", NULL, "IN1" }, }; -static unsigned int adau1701_register_size (struct snd_soc_codec *codec, +static unsigned int adau1701_register_size (struct device *dev,unsigned int reg) {switch (reg) {
@@ -142,33 +144,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec,return 1 ; } -dev_err (codec->dev,"Unsupported register address: %d\n" , reg); +dev_err (dev,"Unsupported register address: %d\n" , reg);return 0 ; } -static int adau1701_write (struct snd_soc_codec *codec,unsigned int reg, -unsigned int value) +static bool adau1701_volatile_reg (struct device *dev,unsigned int reg) { +switch (reg) { +case ADAU1701_DACSET : +return true; +default : +return false; + } +} + +static int adau1701_reg_write (void *context,unsigned int reg, +unsigned int value) +{ +struct i2c_client *client = context;unsigned int i;unsigned int size;uint8_t buf[4 ];int ret; - size =adau1701_register_size (codec, reg); + size =adau1701_register_size (&client->dev, reg);if (size ==0 )return -EINVAL ; -snd_soc_cache_write (codec, reg, value); - - buf[0 ] =0x08 ; - buf[1 ] = reg; + buf[0 ] = reg >>8 ; + buf[1 ] = reg &0xff ;for (i = size +1 ; i >=2 ; --i) { buf[i] = value; value >>=8 ; } - ret =i2c_master_send (to_i2c_client (codec->dev), buf, size +2 ); + ret =i2c_master_send (client, buf, size +2 );if (ret == size +2 )return 0 ;else if (ret <0 )
@@ -177,16 +188,45 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,return -EIO ; } -static unsigned int adau1701_read (struct snd_soc_codec *codec,unsigned int reg) +static int adau1701_reg_read (void *context,unsigned int reg, +unsigned int *value) { -unsigned int value; -unsigned int ret; +int ret; +unsigned int i; +unsigned int size; +uint8_t send_buf[2 ], recv_buf[3 ]; +struct i2c_client *client = context; +struct i2c_msg msgs[2 ]; + + size =adau1701_register_size (&client->dev, reg); +if (size ==0 ) +return -EINVAL ; - ret =snd_soc_cache_read (codec, reg, &value); -if (ret) + send_buf[0 ] = reg >>8 ; + send_buf[1 ] = reg &0xff ; + + msgs[0 ].addr = client->addr; + msgs[0 ].len =sizeof (send_buf); + msgs[0 ].buf = send_buf; + msgs[0 ].flags =0 ; + + msgs[1 ].addr = client->addr; + msgs[1 ].len = size; + msgs[1 ].buf = recv_buf; + msgs[1 ].flags =I2C_M_RD ; + + ret =i2c_transfer (client->adapter, msgs,ARRAY_SIZE (msgs)); +if (ret <0 )return ret; +else if (ret !=ARRAY_SIZE (msgs)) +return -EIO ; + + *value =0 ; + +for (i =0 ; i < size; i++) + *value |= recv_buf[i] << (i *8 ); -return value; +return 0 ; }static int adau1701_reset (struct snd_soc_codec *codec,unsigned int clkdiv)
@@ -242,8 +282,11 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) } } -snd_soc_write (codec,ADAU1701_DACSET ,ADAU1701_DACSET_DACINIT ); -snd_soc_write (codec,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR ); +regmap_write (adau1701->regmap,ADAU1701_DACSET ,ADAU1701_DACSET_DACINIT ); +regmap_write (adau1701->regmap,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR ); + +regcache_mark_dirty (adau1701->regmap); +regcache_sync (adau1701->regmap);return 0 ; }
@@ -429,8 +472,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai, adau1701->dai_fmt = fmt &SND_SOC_DAIFMT_FORMAT_MASK ; -snd_soc_write (codec,ADAU1701_SERICTL , serictl); -snd_soc_update_bits (codec,ADAU1701_SEROCTL , +regmap_write (adau1701->regmap,ADAU1701_SERICTL , serictl); +regmap_update_bits (adau1701->regmap,ADAU1701_SEROCTL , ~ADAU1701_SEROCTL_WORD_LEN_MASK , seroctl);return 0 ;
@@ -567,9 +610,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { .set_bias_level = adau1701_set_bias_level, .idle_bias_off = true, - .reg_cache_size = ADAU1701_NUM_REGS, - .reg_word_size = sizeof(u16), - .controls = adau1701_controls, .num_controls = ARRAY_SIZE(adau1701_controls), .dapm_widgets = adau1701_dapm_widgets,
@@ -577,12 +617,19 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { .dapm_routes = adau1701_dapm_routes, .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), - .write = adau1701_write, - .read = adau1701_read, - .set_sysclk = adau1701_set_sysclk, }; +static const struct regmap_config adau1701_regmap = { + .reg_bits =16 , + .val_bits =32 , + .max_register =ADAU1701_MAX_REGISTER , + .cache_type =REGCACHE_RBTREE , + .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) {
@@ -596,6 +643,11 @@ static int adau1701_i2c_probe(struct i2c_client *client,if (!adau1701)return -ENOMEM ; + adau1701->regmap =devm_regmap_init (dev,NULL , client, + &adau1701_regmap); +if (IS_ERR (adau1701->regmap)) +return PTR_ERR (adau1701->regmap); +if (dev->of_node) { gpio_nreset =of_get_named_gpio (dev->of_node,"reset-gpio" ,0 );if (gpio_nreset <0 && gpio_nreset != -ENOENT )
Signature · 1 line
1.8.1.4
PATCH v4 4/4 ASoC: codecs: adau1701: add support for pin muxing
In reply to Daniel MackThe ADAU1701 has 12 pins that can be configured depending on the system configuration. Allow settting the corresponding registers from DT.
--- .../devicetree/bindings/sound/adi,adau1701.txt | 6 ++++ sound/soc/codecs/adau1701.c | 32 ++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/sound/adi,adau1701.txt +6 -0
@@ -16,6 +16,10 @@ Optional properties: The state of the pins are set according to the configured clock divider on ASoC side before the firmware is loaded. + - adi,pin-config: An array of 12 numerical values selecting one of the + pin configurations as described in the datasheet, + table 53. Note that the value of this property has + to be prefixed with '/bits/ 8'. Examples:
@@ -25,5 +29,7 @@ Examples: reg = <0x34>; reset-gpio = <&gpio 23 0>; adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>; + adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4 + 0x4 0x4 0x4 0x4 0x4 0x4>; }; };
sound/soc/codecs/adau1701.c +30 -2
@@ -30,6 +30,9 @@#define ADAU1701_SERICTL 0x081f#define ADAU1701_AUXNPOW 0x0822 +#define ADAU1701_PINCONF_0 0x0820 +#define ADAU1701_PINCONF_1 0x0821 +#define ADAU1701_AUXNPOW 0x0822#define ADAU1701_OSCIPOW 0x0826#define ADAU1701_DACSET 0x0827
@@ -99,6 +102,7 @@ struct adau1701 {unsigned int pll_clkdiv;unsigned int sysclk;struct regmap *regmap; +u8 pin_config[12 ]; };static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -134,6 +138,9 @@ static unsigned int adau1701_register_size(struct device *dev, unsigned int reg) {switch (reg) { +case ADAU1701_PINCONF_0 : +case ADAU1701_PINCONF_1 : +return 3 ;case ADAU1701_DSPCTRL :case ADAU1701_SEROCTL :case ADAU1701_AUXNPOW :
@@ -164,7 +171,7 @@ static int adau1701_reg_write(void *context, unsigned int reg,struct i2c_client *client = context;unsigned int i;unsigned int size; -uint8_t buf[4 ]; +uint8_t buf[5 ];int ret; size =adau1701_register_size (&client->dev, reg);
@@ -584,7 +591,8 @@ MODULE_DEVICE_TABLE(of, adau1701_dt_ids);static int adau1701_probe (struct snd_soc_codec *codec) { -int ret; +int i, ret; +unsigned int val;struct adau1701 *adau1701 =snd_soc_codec_get_drvdata (codec); codec->control_data =to_i2c_client (codec->dev);
@@ -602,6 +610,19 @@ static int adau1701_probe(struct snd_soc_codec *codec)if (ret <0 )return ret; +/* set up pin config */ + val =0 ; +for (i =0 ; i <6 ; i++) + val |= adau1701->pin_config[i] << (i *4 ); + +regmap_write (adau1701->regmap,ADAU1701_PINCONF_0 , val); + + val =0 ; +for (i =0 ; i <6 ; i++) + val |= adau1701->pin_config[i +6 ] << (i *4 ); + +regmap_write (adau1701->regmap,ADAU1701_PINCONF_1 , val); +return 0 ; }
@@ -662,6 +683,13 @@ static int adau1701_i2c_probe(struct i2c_client *client, "adi,pll-mode-gpios", 1);if (gpio_pll_mode[1 ] <0 && gpio_pll_mode[1 ] != -ENOENT )return gpio_pll_mode[1 ]; + +of_property_read_u32 (dev->of_node,"adi,pll-clkdiv" , + &adau1701->pll_clkdiv); + +of_property_read_u8_array (dev->of_node,"adi,pin-config" , + adau1701->pin_config, +ARRAY_SIZE (adau1701->pin_config)); }if (gpio_is_valid (gpio_nreset)) {
Signature · 1 line
1.8.1.4
Re: [PATCH v4 3/4] ASoC: codecs: adau1701: switch to direct regmap API usage
In reply to Daniel MackQuoted 4 lines · Daniel Mack
The hardware I/O has to be open-coded due to registers of unequal sizes. Other than that, the transition is straight forward.
Signed-off-by Daniel Mack <[email protected]>
Quoted 231 lines
--- sound/soc/codecs/adau1701.c | 118 +++++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 33 deletions(-)sound/soc/codecs/adau1701.c +85
-33@@ -16,6 +16,7 @@#include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_device.h> +#include <linux/regmap.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -24,16 +25,16 @@#include "sigmadsp.h" #include "adau1701.h" -#define ADAU1701_DSPCTRL 0x1c -#define ADAU1701_SEROCTL 0x1e -#define ADAU1701_SERICTL 0x1f +#define ADAU1701_DSPCTRL 0x081c +#define ADAU1701_SEROCTL 0x081e +#define ADAU1701_SERICTL 0x081f -#define ADAU1701_AUXNPOW 0x22 +#define ADAU1701_AUXNPOW 0x0822 -#define ADAU1701_OSCIPOW 0x26 -#define ADAU1701_DACSET 0x27 +#define ADAU1701_OSCIPOW 0x0826 +#define ADAU1701_DACSET 0x0827 -#define ADAU1701_NUM_REGS 0x28 +#define ADAU1701_MAX_REGISTER 0x0828#define ADAU1701_DSPCTRL_CR (1 << 2)#define ADAU1701_DSPCTRL_DAM (1 << 3)@@ -97,6 +98,7 @@ struct adau1701 {unsigned int dai_fmt;unsigned int pll_clkdiv;unsigned int sysclk; +struct regmap *regmap; };static const struct snd_kcontrol_new adau1701_controls[] = {@@ -128,7 +130,7 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = { { "ADC", NULL, "IN1" }, }; -static unsigned int adau1701_register_size (struct snd_soc_codec *codec, +static unsigned int adau1701_register_size (struct device *dev,unsigned int reg) {switch (reg) {@@ -142,33 +144,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec,return 1 ; } -dev_err (codec->dev,"Unsupported register address: %d\n" , reg); +dev_err (dev,"Unsupported register address: %d\n" , reg);return 0 ; } -static int adau1701_write (struct snd_soc_codec *codec,unsigned int reg, -unsigned int value) +static bool adau1701_volatile_reg (struct device *dev,unsigned int reg) { +switch (reg) { +case ADAU1701_DACSET : +return true; +default : +return false; + } +} + +static int adau1701_reg_write (void *context,unsigned int reg, +unsigned int value) +{ +struct i2c_client *client = context;unsigned int i;unsigned int size;uint8_t buf[4 ];int ret; - size =adau1701_register_size (codec, reg); + size =adau1701_register_size (&client->dev, reg);if (size ==0 )return -EINVAL ; -snd_soc_cache_write (codec, reg, value); - - buf[0 ] =0x08 ; - buf[1 ] = reg; + buf[0 ] = reg >>8 ; + buf[1 ] = reg &0xff ;for (i = size +1 ; i >=2 ; --i) { buf[i] = value; value >>=8 ; } - ret =i2c_master_send (to_i2c_client (codec->dev), buf, size +2 ); + ret =i2c_master_send (client, buf, size +2 );if (ret == size +2 )return 0 ;else if (ret <0 )@@ -177,16 +188,45 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,return -EIO ; } -static unsigned int adau1701_read (struct snd_soc_codec *codec,unsigned int reg) +static int adau1701_reg_read (void *context,unsigned int reg, +unsigned int *value) { -unsigned int value; -unsigned int ret; +int ret; +unsigned int i; +unsigned int size; +uint8_t send_buf[2 ], recv_buf[3 ]; +struct i2c_client *client = context; +struct i2c_msg msgs[2 ]; + + size =adau1701_register_size (&client->dev, reg); +if (size ==0 ) +return -EINVAL ; - ret =snd_soc_cache_read (codec, reg, &value); -if (ret) + send_buf[0 ] = reg >>8 ; + send_buf[1 ] = reg &0xff ; + + msgs[0 ].addr = client->addr; + msgs[0 ].len =sizeof (send_buf); + msgs[0 ].buf = send_buf; + msgs[0 ].flags =0 ; + + msgs[1 ].addr = client->addr; + msgs[1 ].len = size; + msgs[1 ].buf = recv_buf; + msgs[1 ].flags =I2C_M_RD ; + + ret =i2c_transfer (client->adapter, msgs,ARRAY_SIZE (msgs)); +if (ret <0 )return ret; +else if (ret !=ARRAY_SIZE (msgs)) +return -EIO ; + + *value =0 ; + +for (i =0 ; i < size; i++) + *value |= recv_buf[i] << (i *8 ); -return value; +return 0 ; }static int adau1701_reset (struct snd_soc_codec *codec,unsigned int clkdiv)@@ -242,8 +282,11 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) } } -snd_soc_write (codec,ADAU1701_DACSET ,ADAU1701_DACSET_DACINIT ); -snd_soc_write (codec,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR ); +regmap_write (adau1701->regmap,ADAU1701_DACSET ,ADAU1701_DACSET_DACINIT ); +regmap_write (adau1701->regmap,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR ); + +regcache_mark_dirty (adau1701->regmap); +regcache_sync (adau1701->regmap);return 0 ; }@@ -429,8 +472,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai, adau1701->dai_fmt = fmt &SND_SOC_DAIFMT_FORMAT_MASK ; -snd_soc_write (codec,ADAU1701_SERICTL , serictl); -snd_soc_update_bits (codec,ADAU1701_SEROCTL , +regmap_write (adau1701->regmap,ADAU1701_SERICTL , serictl); +regmap_update_bits (adau1701->regmap,ADAU1701_SEROCTL , ~ADAU1701_SEROCTL_WORD_LEN_MASK , seroctl);return 0 ;@@ -567,9 +610,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { .set_bias_level = adau1701_set_bias_level, .idle_bias_off = true, - .reg_cache_size = ADAU1701_NUM_REGS, - .reg_word_size = sizeof(u16), - .controls = adau1701_controls, .num_controls = ARRAY_SIZE(adau1701_controls), .dapm_widgets = adau1701_dapm_widgets,@@ -577,12 +617,19 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { .dapm_routes = adau1701_dapm_routes, .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), - .write = adau1701_write, - .read = adau1701_read, - .set_sysclk = adau1701_set_sysclk, }; +static const struct regmap_config adau1701_regmap = { + .reg_bits =16 , + .val_bits =32 , + .max_register =ADAU1701_MAX_REGISTER , + .cache_type =REGCACHE_RBTREE , + .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) {@@ -596,6 +643,11 @@ static int adau1701_i2c_probe(struct i2c_client *client,if (!adau1701)return -ENOMEM ; + adau1701->regmap =devm_regmap_init (dev,NULL , client, + &adau1701_regmap); +if (IS_ERR (adau1701->regmap)) +return PTR_ERR (adau1701->regmap); +if (dev->of_node) { gpio_nreset =of_get_named_gpio (dev->of_node,"reset-gpio" ,0 );if (gpio_nreset <0 && gpio_nreset != -ENOENT )
Re: [PATCH v4 1/4] ASoC: codecs: adau1701: move firmware download to adau1701_reset()
In reply to Daniel MackQuoted 4 lines · Daniel Mack
The chip needs a new download after each reset, so the code to do that needs to live in
adau1701_reset().Signed-off-by Daniel Mack <[email protected]>
Quoted 68 lines
--- sound/soc/codecs/adau1701.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-)sound/soc/codecs/adau1701.c +12
-20@@ -184,27 +184,20 @@ static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg)return value; } -static void adau1701_reset (struct snd_soc_codec *codec) +static int adau1701_reset (struct snd_soc_codec *codec) {struct adau1701 *adau1701 =snd_soc_codec_get_drvdata (codec); - -if (!gpio_is_valid (adau1701->gpio_nreset)) -return ; - -gpio_set_value (adau1701->gpio_nreset,0 ); -/* minimum reset time is 20ns */ -udelay (1 ); -gpio_set_value (adau1701->gpio_nreset,1 ); -/* power-up time may be as long as 85ms */ -mdelay (85 ); -} - -static int adau1701_init (struct snd_soc_codec *codec) -{ -int ret;struct i2c_client *client =to_i2c_client (codec->dev); +int ret; -adau1701_reset (codec); +if (gpio_is_valid (adau1701->gpio_nreset)) { +gpio_set_value (adau1701->gpio_nreset,0 ); +/* minimum reset time is 20ns */ +udelay (1 ); +gpio_set_value (adau1701->gpio_nreset,1 ); +/* power-up time may be as long as 85ms */ +mdelay (85 ); + } ret =process_sigma_firmware (client,ADAU1701_FIRMWARE );if (ret) {@@ -213,6 +206,7 @@ static int adau1701_init(struct snd_soc_codec *codec) }snd_soc_write (codec,ADAU1701_DACSET ,ADAU1701_DACSET_DACINIT ); +snd_soc_write (codec,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR );return 0 ; }@@ -498,12 +492,10 @@ static int adau1701_probe(struct snd_soc_codec *codec) codec->control_data =to_i2c_client (codec->dev); - ret =adau1701_init (codec); + ret =adau1701_reset (codec);if (ret)return ret; -snd_soc_write (codec,ADAU1701_DSPCTRL ,ADAU1701_DSPCTRL_CR ); -return 0 ; }