[alsa-devel] [PATCH 0/6] ASoC: Convert ALC5632 codec to use regmap API
Leon Romanovsky (6): ASoC: Convert ALC5632 codec to use regmap API ASoC: alc5632: Fix compile without CONFIG_I2C ASoC: alc5632: Fix compile without CONFIG_PM ASoC: alc5632: Remove unrelevant registers and name the relevant ASoC: alc5632: Added support of two undocumented registers ASoC: alc5632: Update of i2c_probe function to use regmap API only
sound/soc/codecs/alc5632.c | 222 ++++++++++++++++++++++++++------------------ sound/soc/codecs/alc5632.h | 2 + 2 files changed, 135 insertions(+), 89 deletions(-)
Signed-off-by: Leon Romanovsky leon@leon.nu --- sound/soc/codecs/alc5632.c | 219 ++++++++++++++++++++++++++++++++------------ sound/soc/codecs/alc5632.h | 2 + 2 files changed, 162 insertions(+), 59 deletions(-)
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 8df1e22..42feae0 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -22,6 +22,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/slab.h> +#include <linux/regmap.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -34,45 +35,129 @@ /* * ALC5632 register cache */ -static const u16 alc5632_reg_defaults[] = { - 0x59B4, 0x0000, 0x8080, 0x0000, /* 0 */ - 0x8080, 0x0000, 0x8080, 0x0000, /* 4 */ - 0xC800, 0x0000, 0xE808, 0x0000, /* 8 */ - 0x1010, 0x0000, 0x0808, 0x0000, /* 12 */ - 0xEE0F, 0x0000, 0xCBCB, 0x0000, /* 16 */ - 0x7F7F, 0x0000, 0x0000, 0x0000, /* 20 */ - 0xE010, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x8008, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 32 */ - 0x00C0, 0x0000, 0xEF00, 0x0000, /* 36 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 40 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 44 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 48 */ - 0x8000, 0x0000, 0x0000, 0x0000, /* 52 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 56 */ - 0x0000, 0x0000, 0x8000, 0x0000, /* 60 */ - 0x0C0A, 0x0000, 0x0000, 0x0000, /* 64 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 68 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 72 */ - 0xBE3E, 0x0000, 0xBE3E, 0x0000, /* 76 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 80 */ - 0x803A, 0x0000, 0x0000, 0x0000, /* 84 */ - 0x0000, 0x0000, 0x0009, 0x0000, /* 88 */ - 0x0000, 0x0000, 0x3000, 0x0000, /* 92 */ - 0x3075, 0x0000, 0x1010, 0x0000, /* 96 */ - 0x3110, 0x0000, 0x0000, 0x0000, /* 100 */ - 0x0553, 0x0000, 0x0000, 0x0000, /* 104 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 108 */ +static struct reg_default alc5632_reg_defaults[] = { + { 0, 0x59B4 }, + { 1, 0x0000 }, + { 2, 0x8080 }, + { 3, 0x0000 }, + { 4, 0x8080 }, + { 5, 0x0000 }, + { 6, 0x8080 }, + { 7, 0x0000 }, + { 8, 0xC800 }, + { 9, 0x0000 }, + { 10, 0xE808 }, + { 11, 0x0000 }, + { 12, 0x1010 }, + { 13, 0x0000 }, + { 14, 0x0808 }, + { 15, 0x0000 }, + { 16, 0xEE0F }, + { 17, 0x0000 }, + { 18, 0xCBCB }, + { 19, 0x0000 }, + { 20, 0x7F7F }, + { 21, 0x0000 }, + { 22, 0x0000 }, + { 23, 0x0000 }, + { 24, 0xE010 }, + { 25, 0x0000 }, + { 26, 0x0000 }, + { 27, 0x0000 }, + { 28, 0x8008 }, + { 29, 0x0000 }, + { 30, 0x0000 }, + { 31, 0x0000 }, + { 32, 0x0000 }, + { 33, 0x0000 }, + { 34, 0x0000 }, + { 35, 0x0000 }, + { 36, 0x00C0 }, + { 37, 0x0000 }, + { 38, 0xEF00 }, + { 39, 0x0000 }, + { 40, 0x0000 }, + { 41, 0x0000 }, + { 42, 0x0000 }, + { 43, 0x0000 }, + { 44, 0x0000 }, + { 45, 0x0000 }, + { 46, 0x0000 }, + { 47, 0x0000 }, + { 48, 0x0000 }, + { 49, 0x0000 }, + { 50, 0x0000 }, + { 51, 0x0000 }, + { 52, 0x8000 }, + { 53, 0x0000 }, + { 54, 0x0000 }, + { 55, 0x0000 }, + { 56, 0x0000 }, + { 57, 0x0000 }, + { 58, 0x0000 }, + { 59, 0x0000 }, + { 60, 0x0000 }, + { 61, 0x0000 }, + { 62, 0x8000 }, + { 63, 0x0000 }, + { 64, 0x0C0A }, + { 65, 0x0000 }, + { 66, 0x0000 }, + { 67, 0x0000 }, + { 68, 0x0000 }, + { 69, 0x0000 }, + { 70, 0x0000 }, + { 71, 0x0000 }, + { 72, 0x0000 }, + { 73, 0x0000 }, + { 74, 0x0000 }, + { 75, 0x0000 }, + { 76, 0xBE3E }, + { 77, 0x0000 }, + { 78, 0xBE3E }, + { 79, 0x0000 }, + { 80, 0x0000 }, + { 81, 0x0000 }, + { 82, 0x0000 }, + { 83, 0x0000 }, + { 84, 0x803A }, + { 85, 0x0000 }, + { 86, 0x0000 }, + { 87, 0x0000 }, + { 88, 0x0000 }, + { 89, 0x0000 }, + { 90, 0x0009 }, + { 91, 0x0000 }, + { 92, 0x0000 }, + { 93, 0x0000 }, + { 94, 0x3000 }, + { 95, 0x0000 }, + { 96, 0x3075 }, + { 97, 0x0000 }, + { 98, 0x1010 }, + { 99, 0x0000 }, + { 100, 0x3110 }, + { 101, 0x0000 }, + { 102, 0x0000 }, + { 103, 0x0000 }, + { 104, 0x0553 }, + { 105, 0x0000 }, + { 106, 0x0000 }, + { 107, 0x0000 }, + { 108, 0x0000 }, + { 109, 0x0000 }, + { 110, 0x0000 }, + { 111, 0x0000 }, };
/* codec private data */ struct alc5632_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; u8 id; unsigned int sysclk; };
-static int alc5632_volatile_register(struct snd_soc_codec *codec, +static bool alc5632_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { @@ -82,19 +167,18 @@ static int alc5632_volatile_register(struct snd_soc_codec *codec, case ALC5632_OVER_CURR_STATUS: case ALC5632_HID_CTRL_DATA: case ALC5632_EQ_CTRL: - return 1; + return true;
default: break; }
- return 0; + return false; }
-static inline int alc5632_reset(struct snd_soc_codec *codec) +static inline int alc5632_reset(struct regmap *map) { - snd_soc_write(codec, ALC5632_RESET, 0); - return snd_soc_read(codec, ALC5632_RESET); + return regmap_write(map, ALC5632_RESET, 0x59B4); }
static int amp_mixer_event(struct snd_soc_dapm_widget *w, @@ -947,17 +1031,10 @@ static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
static int alc5632_resume(struct snd_soc_codec *codec) { - int ret; - - /* mark cache as needed to sync */ - codec->cache_sync = 1; - - ret = snd_soc_cache_sync(codec); - if (ret != 0) { - dev_err(codec->dev, "Failed to sync cache: %d\n", ret); - return ret; - } + struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+ regcache_sync(alc5632->regmap); + alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } @@ -967,14 +1044,14 @@ static int alc5632_probe(struct snd_soc_codec *codec) struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); int ret;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5632->control_type); - if (ret < 0) { + codec->control_data = alc5632->regmap; + + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); + if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; }
- alc5632_reset(codec); - /* power on device */ alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1003,11 +1080,6 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = { .suspend = alc5632_suspend, .resume = alc5632_resume, .set_bias_level = alc5632_set_bias_level, - .reg_word_size = sizeof(u16), - .reg_cache_step = 2, - .reg_cache_default = alc5632_reg_defaults, - .reg_cache_size = ARRAY_SIZE(alc5632_reg_defaults), - .volatile_register = alc5632_volatile_register, .controls = alc5632_snd_controls, .num_controls = ARRAY_SIZE(alc5632_snd_controls), .dapm_widgets = alc5632_dapm_widgets, @@ -1016,13 +1088,24 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = { .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), };
+static struct regmap_config alc5632_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = ALC5632_MAX_REGISTER, + .reg_defaults = alc5632_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults), + .volatile_reg = alc5632_volatile_register, + .cache_type = REGCACHE_RBTREE, +}; + /* * alc5632 2 wire address is determined by A1 pin * state during powerup. * low = 0x1a * high = 0x1b */ -static int alc5632_i2c_probe(struct i2c_client *client, +static __devinit int alc5632_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct alc5632_priv *alc5632; @@ -1069,20 +1152,38 @@ static int alc5632_i2c_probe(struct i2c_client *client, }
i2c_set_clientdata(client, alc5632); - alc5632->control_type = SND_SOC_I2C;
+ alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap); + if (IS_ERR(alc5632->regmap)) { + ret = PTR_ERR(alc5632->regmap); + dev_err(&client->dev, "regmap_init() failed: %d\n", ret); + return ret; + } + + ret = alc5632_reset(alc5632->regmap); + if (ret < 0) { + dev_err(&client->dev, "Failed to issue reset\n"); + regmap_exit(alc5632->regmap); + return ret; + } + ret = snd_soc_register_codec(&client->dev, &soc_codec_device_alc5632, &alc5632_dai, 1); - if (ret != 0) + + if (ret < 0) { dev_err(&client->dev, "Failed to register codec: %d\n", ret); + regmap_exit(alc5632->regmap); + return ret; + }
return ret; }
static int alc5632_i2c_remove(struct i2c_client *client) { + struct alc5632_priv *alc5632 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); - + regmap_exit(alc5632->regmap); return 0; }
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h index ff4c0fd..357651e 100644 --- a/sound/soc/codecs/alc5632.h +++ b/sound/soc/codecs/alc5632.h @@ -246,4 +246,6 @@ #define ALC5632_VENDOR_ID1 0x7C #define ALC5632_VENDOR_ID2 0x7E
+#define ALC5632_MAX_REGISTER 0x7E + #endif
On Wed, Nov 16, 2011 at 12:06:58PM +0200, Leon Romanovsky wrote:
Signed-off-by: Leon Romanovsky leon@leon.nu
Applied, thanks.
Signed-off-by: Leon Romanovsky leon@leon.nu --- sound/soc/codecs/alc5632.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 42feae0..b72d467 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1105,6 +1105,7 @@ static struct regmap_config alc5632_regmap = { * low = 0x1a * high = 0x1b */ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int alc5632_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1203,24 +1204,27 @@ static struct i2c_driver alc5632_i2c_driver = { .remove = __devexit_p(alc5632_i2c_remove), .id_table = alc5632_i2c_table, }; +#endif
static int __init alc5632_modinit(void) { - int ret; - + int ret = 0; +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&alc5632_i2c_driver); if (ret != 0) { printk(KERN_ERR "%s: can't add i2c driver", __func__); return ret; } - +#endif return ret; } module_init(alc5632_modinit);
static void __exit alc5632_modexit(void) { +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&alc5632_i2c_driver); +#endif } module_exit(alc5632_modexit);
On Wed, Nov 16, 2011 at 12:06:59PM +0200, Leon Romanovsky wrote:
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int alc5632_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1203,24 +1204,27 @@ static struct i2c_driver alc5632_i2c_driver = { .remove = __devexit_p(alc5632_i2c_remove), .id_table = alc5632_i2c_table, }; +#endif
This is only needed if the driver supports more than one control interface. If it only supports I2C then this should be sorted out at Kconfig stage.
On Wed, Nov 16, 2011 at 12:35, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Wed, Nov 16, 2011 at 12:06:59PM +0200, Leon Romanovsky wrote:
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int alc5632_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1203,24 +1204,27 @@ static struct i2c_driver alc5632_i2c_driver = { .remove = __devexit_p(alc5632_i2c_remove), .id_table = alc5632_i2c_table, }; +#endif
This is only needed if the driver supports more than one control interface. If it only supports I2C then this should be sorted out at Kconfig stage.
It is the same as your WM9081 codec, you have entry in Kconfig and CONFIG_I2C in the code.
Anyway this codec is not usable without I2C, so we can drop this patch.
On Wed, Nov 16, 2011 at 09:11:00PM +0200, Leon Romanovsky wrote:
On Wed, Nov 16, 2011 at 12:35, Mark Brown
This is only needed if the driver supports more than one control interface. If it only supports I2C then this should be sorted out at Kconfig stage.
It is the same as your WM9081 codec, you have entry in Kconfig and CONFIG_I2C in the code.
Anyway this codec is not usable without I2C, so we can drop this patch.
Some devices do have both I2C and SPI support but didn't get round to adding one bus or the other.
Signed-off-by: Leon Romanovsky leon@leon.nu --- sound/soc/codecs/alc5632.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index b72d467..902f178 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1023,6 +1023,7 @@ static struct snd_soc_dai_driver alc5632_dai = { .symmetric_rates = 1, };
+#ifdef CONFIG_PM static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg) { alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1038,6 +1039,10 @@ static int alc5632_resume(struct snd_soc_codec *codec) alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } +#else +#define alc5632_suspend NULL +#define alc5632_resume NULL +#endif
static int alc5632_probe(struct snd_soc_codec *codec) {
On Wed, Nov 16, 2011 at 12:07:00PM +0200, Leon Romanovsky wrote:
Signed-off-by: Leon Romanovsky leon@leon.nu
Applied, thanks.
Signed-off-by: Leon Romanovsky leon@leon.nu --- sound/soc/codecs/alc5632.c | 177 ++++++++++++++------------------------------ 1 files changed, 57 insertions(+), 120 deletions(-)
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 902f178..ea40f02 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -36,118 +36,55 @@ * ALC5632 register cache */ static struct reg_default alc5632_reg_defaults[] = { - { 0, 0x59B4 }, - { 1, 0x0000 }, - { 2, 0x8080 }, - { 3, 0x0000 }, - { 4, 0x8080 }, - { 5, 0x0000 }, - { 6, 0x8080 }, - { 7, 0x0000 }, - { 8, 0xC800 }, - { 9, 0x0000 }, - { 10, 0xE808 }, - { 11, 0x0000 }, - { 12, 0x1010 }, - { 13, 0x0000 }, - { 14, 0x0808 }, - { 15, 0x0000 }, - { 16, 0xEE0F }, - { 17, 0x0000 }, - { 18, 0xCBCB }, - { 19, 0x0000 }, - { 20, 0x7F7F }, - { 21, 0x0000 }, - { 22, 0x0000 }, - { 23, 0x0000 }, - { 24, 0xE010 }, - { 25, 0x0000 }, - { 26, 0x0000 }, - { 27, 0x0000 }, - { 28, 0x8008 }, - { 29, 0x0000 }, - { 30, 0x0000 }, - { 31, 0x0000 }, - { 32, 0x0000 }, - { 33, 0x0000 }, - { 34, 0x0000 }, - { 35, 0x0000 }, - { 36, 0x00C0 }, - { 37, 0x0000 }, - { 38, 0xEF00 }, - { 39, 0x0000 }, - { 40, 0x0000 }, - { 41, 0x0000 }, - { 42, 0x0000 }, - { 43, 0x0000 }, - { 44, 0x0000 }, - { 45, 0x0000 }, - { 46, 0x0000 }, - { 47, 0x0000 }, - { 48, 0x0000 }, - { 49, 0x0000 }, - { 50, 0x0000 }, - { 51, 0x0000 }, - { 52, 0x8000 }, - { 53, 0x0000 }, - { 54, 0x0000 }, - { 55, 0x0000 }, - { 56, 0x0000 }, - { 57, 0x0000 }, - { 58, 0x0000 }, - { 59, 0x0000 }, - { 60, 0x0000 }, - { 61, 0x0000 }, - { 62, 0x8000 }, - { 63, 0x0000 }, - { 64, 0x0C0A }, - { 65, 0x0000 }, - { 66, 0x0000 }, - { 67, 0x0000 }, - { 68, 0x0000 }, - { 69, 0x0000 }, - { 70, 0x0000 }, - { 71, 0x0000 }, - { 72, 0x0000 }, - { 73, 0x0000 }, - { 74, 0x0000 }, - { 75, 0x0000 }, - { 76, 0xBE3E }, - { 77, 0x0000 }, - { 78, 0xBE3E }, - { 79, 0x0000 }, - { 80, 0x0000 }, - { 81, 0x0000 }, - { 82, 0x0000 }, - { 83, 0x0000 }, - { 84, 0x803A }, - { 85, 0x0000 }, - { 86, 0x0000 }, - { 87, 0x0000 }, - { 88, 0x0000 }, - { 89, 0x0000 }, - { 90, 0x0009 }, - { 91, 0x0000 }, - { 92, 0x0000 }, - { 93, 0x0000 }, - { 94, 0x3000 }, - { 95, 0x0000 }, - { 96, 0x3075 }, - { 97, 0x0000 }, - { 98, 0x1010 }, - { 99, 0x0000 }, - { 100, 0x3110 }, - { 101, 0x0000 }, - { 102, 0x0000 }, - { 103, 0x0000 }, - { 104, 0x0553 }, - { 105, 0x0000 }, - { 106, 0x0000 }, - { 107, 0x0000 }, - { 108, 0x0000 }, - { 109, 0x0000 }, - { 110, 0x0000 }, - { 111, 0x0000 }, + { 0, 0x59B4 }, /* R0 - Reset */ + { 2, 0x8080 }, /* R2 - Speaker Output Volume */ + { 4, 0x8080 }, /* R4 - Headphone Output Volume */ + { 6, 0x8080 }, /* R6 - AUXOUT Volume */ + { 8, 0xC800 }, /* R8 - Phone Input */ + { 10, 0xE808 }, /* R10 - LINE_IN Volume */ + { 12, 0x1010 }, /* R12 - STEREO DAC Input Volume */ + { 14, 0x0808 }, /* R14 - MIC Input Volume */ + { 16, 0xEE0F }, /* R16 - Stereo DAC and MIC Routing Control */ + { 18, 0xCBCB }, /* R18 - ADC Record Gain */ + { 20, 0x7F7F }, /* R20 - ADC Record Mixer Control */ + { 24, 0xE010 }, /* R24 - Voice DAC Volume */ + { 28, 0x8008 }, /* R28 - Output Mixer Control */ + { 34, 0x0000 }, /* R34 - Microphone Control */ + { 36, 0x00C0 }, /* R36 - Codec Digital MIC/Digital Boost + Control */ + { 38, 0xEF00 }, /* R38 - Power Down Control/Status */ + { 46, 0x0000 }, /* R46 - Stereo DAC/Voice DAC/Stereo ADC + Function Select */ + { 52, 0x8000 }, /* R52 - Main Serial Data Port Control + (Stereo I2S) */ + { 54, 0x0000 }, /* R54 - Extend Serial Data Port Control + (VoDAC_I2S/PCM) */ + { 58, 0x0000 }, /* R58 - Power Management Addition 1 */ + { 60, 0x0000 }, /* R60 - Power Management Addition 2 */ + { 62, 0x8000 }, /* R62 - Power Management Addition 3 */ + { 64, 0x0C0A }, /* R64 - General Purpose Control Register 1 */ + { 66, 0x0000 }, /* R66 - General Purpose Control Register 2 */ + { 68, 0x0000 }, /* R68 - PLL1 Control */ + { 70, 0x0000 }, /* R70 - PLL2 Control */ + { 76, 0xBE3E }, /* R76 - GPIO Pin Configuration */ + { 78, 0xBE3E }, /* R78 - GPIO Pin Polarity */ + { 80, 0x0000 }, /* R80 - GPIO Pin Sticky */ + { 82, 0x0000 }, /* R82 - GPIO Pin Wake Up */ + { 84, 0x803A }, /* R84 - GPIO Pin Status */ + { 86, 0x0000 }, /* R86 - Pin Sharing */ + { 88, 0x0000 }, /* R88 - Over-Temp/Current Status */ + { 90, 0x0009 }, /* R90 - Soft Volume Control Setting */ + { 92, 0x0000 }, /* R92 - GPIO_Output Pin Control */ + { 94, 0x3000 }, /* R94 - MISC Control */ + { 96, 0x3075 }, /* R96 - Stereo DAC Clock Control_1 */ + { 98, 0x1010 }, /* R98 - Stereo DAC Clock Control_2 */ + { 100, 0x3110 }, /* R100 - VoDAC_PCM Clock Control_1 */ + { 104, 0x0553 }, /* R104 - Pseudo Stereo and Spatial Effect + Block Control */ + { 106, 0x0000 }, /* R106 - Private Register Address */ + { 108, 0x0000 }, /* R108 - Private Register Data */ + { 110, 0x0000 }, /* R110 - EQ Control and Status/ADC + HPF Control */ };
/* codec private data */ @@ -1023,7 +960,7 @@ static struct snd_soc_dai_driver alc5632_dai = { .symmetric_rates = 1, };
-#ifdef CONFIG_PM +#ifdef CONFIG_PM static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg) { alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1035,7 +972,7 @@ static int alc5632_resume(struct snd_soc_codec *codec) struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
regcache_sync(alc5632->regmap); - + alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } @@ -1097,7 +1034,7 @@ static struct regmap_config alc5632_regmap = { .reg_bits = 8, .val_bits = 16,
- .max_register = ALC5632_MAX_REGISTER, + .max_register = ALC5632_MAX_REGISTER, .reg_defaults = alc5632_reg_defaults, .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults), .volatile_reg = alc5632_volatile_register, @@ -1165,14 +1102,14 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client, dev_err(&client->dev, "regmap_init() failed: %d\n", ret); return ret; } - + ret = alc5632_reset(alc5632->regmap); if (ret < 0) { dev_err(&client->dev, "Failed to issue reset\n"); regmap_exit(alc5632->regmap); return ret; } - + ret = snd_soc_register_codec(&client->dev, &soc_codec_device_alc5632, &alc5632_dai, 1);
@@ -1209,7 +1146,7 @@ static struct i2c_driver alc5632_i2c_driver = { .remove = __devexit_p(alc5632_i2c_remove), .id_table = alc5632_i2c_table, }; -#endif +#endif
static int __init alc5632_modinit(void) { @@ -1227,9 +1164,9 @@ module_init(alc5632_modinit);
static void __exit alc5632_modexit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&alc5632_i2c_driver); -#endif +#endif } module_exit(alc5632_modexit);
On Wed, Nov 16, 2011 at 12:07:01PM +0200, Leon Romanovsky wrote:
-#ifdef CONFIG_PM +#ifdef CONFIG_PM
The actual change is OK but there's a bunch of extra changes that look like whitespace noise - please fix these up and resend.
There are two undocumented registers in use in alc5632_i2c_probe function. It must be added to regmap defaults, in order to support future rewrite of this function to use regmap API completely.
Signed-off-by: Leon Romanovsky leon@leon.nu --- sound/soc/codecs/alc5632.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index ea40f02..5a672a9 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -85,6 +85,8 @@ static struct reg_default alc5632_reg_defaults[] = { { 108, 0x0000 }, /* R108 - Private Register Data */ { 110, 0x0000 }, /* R110 - EQ Control and Status/ADC HPF Control */ + { 124, 0x0000 }, /* R124 - Vendor ID1 (Undocumented) */ + { 125, 0x0000 }, /* R124 - Vendor ID2 (Undocumented) */ };
/* codec private data */ @@ -104,6 +106,8 @@ static bool alc5632_volatile_register(struct device *dev, case ALC5632_OVER_CURR_STATUS: case ALC5632_HID_CTRL_DATA: case ALC5632_EQ_CTRL: + case ALC5632_VENDOR_ID1: + case ALC5632_VENDOR_ID2: return true;
default:
On Wed, Nov 16, 2011 at 12:07:02PM +0200, Leon Romanovsky wrote:
- { 124, 0x0000 }, /* R124 - Vendor ID1 (Undocumented) */
- { 125, 0x0000 }, /* R124 - Vendor ID2 (Undocumented) */
As these are volatile registers you don't need to provide defaults and doing so might cause confusion.
On Wed, Nov 16, 2011 at 12:37, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Wed, Nov 16, 2011 at 12:07:02PM +0200, Leon Romanovsky wrote:
- { 124, 0x0000 }, /* R124 - Vendor ID1 (Undocumented) */
- { 125, 0x0000 }, /* R124 - Vendor ID2 (Undocumented) */
As these are volatile registers you don't need to provide defaults and doing so might cause confusion.
Is it applicable for all volatile registers? Do I provide the patch which remove all volatile registers from the regmap DB?
On Wed, Nov 16, 2011 at 09:43:15PM +0200, Leon Romanovsky wrote:
On Wed, Nov 16, 2011 at 12:37, Mark Brown
As these are volatile registers you don't need to provide defaults and doing so might cause confusion.
Is it applicable for all volatile registers?
Yes.
Do I provide the patch which remove all volatile registers from the regmap DB?
Please.
Signed-off-by: Leon Romanovsky leon@leon.nu --- sound/soc/codecs/alc5632.c | 67 +++++++++++++++++++------------------------ 1 files changed, 30 insertions(+), 37 deletions(-)
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 5a672a9..9ac177d 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1056,48 +1056,14 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct alc5632_priv *alc5632; - int ret, vid1, vid2; - - vid1 = i2c_smbus_read_word_data(client, ALC5632_VENDOR_ID1); - if (vid1 < 0) { - dev_err(&client->dev, "failed to read I2C\n"); - return -EIO; - } else { - dev_info(&client->dev, "got vid1: %x\n", vid1); - } - vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); - - vid2 = i2c_smbus_read_word_data(client, ALC5632_VENDOR_ID2); - if (vid2 < 0) { - dev_err(&client->dev, "failed to read I2C\n"); - return -EIO; - } else { - dev_info(&client->dev, "got vid2: %x\n", vid2); - } - vid2 = (vid2 & 0xff); - - if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { - dev_err(&client->dev, "unknown or wrong codec\n"); - dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n", - 0x10ec, id->driver_data, - vid1, vid2); - return -ENODEV; - } + int ret, ret1, ret2; + unsigned int vid1, vid2;
alc5632 = devm_kzalloc(&client->dev, sizeof(struct alc5632_priv), GFP_KERNEL); if (alc5632 == NULL) return -ENOMEM;
- alc5632->id = vid2; - switch (alc5632->id) { - case 0x5c: - alc5632_dai.name = "alc5632-hifi"; - break; - default: - return -EINVAL; - } - i2c_set_clientdata(client, alc5632);
alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap); @@ -1107,6 +1073,24 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client, return ret; }
+ ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1); + ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2); + if (ret1 != 0 || ret2 != 0) { + dev_err(&client->dev, + "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2); + regmap_exit(alc5632->regmap); + return -EIO; + } + + vid2 >>= 8; + + if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) { + dev_err(&client->dev, + "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2); + regmap_exit(alc5632->regmap); + return -EINVAL; + } + ret = alc5632_reset(alc5632->regmap); if (ret < 0) { dev_err(&client->dev, "Failed to issue reset\n"); @@ -1114,7 +1098,16 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client, return ret; }
- ret = snd_soc_register_codec(&client->dev, + alc5632->id = vid2; + switch (alc5632->id) { + case 0x5c: + alc5632_dai.name = "alc5632-hifi"; + break; + default: + return -EINVAL; + } + + ret = snd_soc_register_codec(&client->dev, &soc_codec_device_alc5632, &alc5632_dai, 1);
if (ret < 0) {
participants (2)
-
Leon Romanovsky
-
Mark Brown