Commit bb39753c authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Mark Brown

ASoC: Convert ALC5632 codec to use regmap API

Signed-off-by: default avatarLeon Romanovsky <leon@leon.nu>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent c9be8427
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/regmap.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
...@@ -34,45 +35,129 @@ ...@@ -34,45 +35,129 @@
/* /*
* ALC5632 register cache * ALC5632 register cache
*/ */
static const u16 alc5632_reg_defaults[] = { static struct reg_default alc5632_reg_defaults[] = {
0x59B4, 0x0000, 0x8080, 0x0000, /* 0 */ { 0, 0x59B4 },
0x8080, 0x0000, 0x8080, 0x0000, /* 4 */ { 1, 0x0000 },
0xC800, 0x0000, 0xE808, 0x0000, /* 8 */ { 2, 0x8080 },
0x1010, 0x0000, 0x0808, 0x0000, /* 12 */ { 3, 0x0000 },
0xEE0F, 0x0000, 0xCBCB, 0x0000, /* 16 */ { 4, 0x8080 },
0x7F7F, 0x0000, 0x0000, 0x0000, /* 20 */ { 5, 0x0000 },
0xE010, 0x0000, 0x0000, 0x0000, /* 24 */ { 6, 0x8080 },
0x8008, 0x0000, 0x0000, 0x0000, /* 28 */ { 7, 0x0000 },
0x0000, 0x0000, 0x0000, 0x0000, /* 32 */ { 8, 0xC800 },
0x00C0, 0x0000, 0xEF00, 0x0000, /* 36 */ { 9, 0x0000 },
0x0000, 0x0000, 0x0000, 0x0000, /* 40 */ { 10, 0xE808 },
0x0000, 0x0000, 0x0000, 0x0000, /* 44 */ { 11, 0x0000 },
0x0000, 0x0000, 0x0000, 0x0000, /* 48 */ { 12, 0x1010 },
0x8000, 0x0000, 0x0000, 0x0000, /* 52 */ { 13, 0x0000 },
0x0000, 0x0000, 0x0000, 0x0000, /* 56 */ { 14, 0x0808 },
0x0000, 0x0000, 0x8000, 0x0000, /* 60 */ { 15, 0x0000 },
0x0C0A, 0x0000, 0x0000, 0x0000, /* 64 */ { 16, 0xEE0F },
0x0000, 0x0000, 0x0000, 0x0000, /* 68 */ { 17, 0x0000 },
0x0000, 0x0000, 0x0000, 0x0000, /* 72 */ { 18, 0xCBCB },
0xBE3E, 0x0000, 0xBE3E, 0x0000, /* 76 */ { 19, 0x0000 },
0x0000, 0x0000, 0x0000, 0x0000, /* 80 */ { 20, 0x7F7F },
0x803A, 0x0000, 0x0000, 0x0000, /* 84 */ { 21, 0x0000 },
0x0000, 0x0000, 0x0009, 0x0000, /* 88 */ { 22, 0x0000 },
0x0000, 0x0000, 0x3000, 0x0000, /* 92 */ { 23, 0x0000 },
0x3075, 0x0000, 0x1010, 0x0000, /* 96 */ { 24, 0xE010 },
0x3110, 0x0000, 0x0000, 0x0000, /* 100 */ { 25, 0x0000 },
0x0553, 0x0000, 0x0000, 0x0000, /* 104 */ { 26, 0x0000 },
0x0000, 0x0000, 0x0000, 0x0000, /* 108 */ { 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 */ /* codec private data */
struct alc5632_priv { struct alc5632_priv {
enum snd_soc_control_type control_type; struct regmap *regmap;
u8 id; u8 id;
unsigned int sysclk; unsigned int sysclk;
}; };
static int alc5632_volatile_register(struct snd_soc_codec *codec, static bool alc5632_volatile_register(struct device *dev,
unsigned int reg) unsigned int reg)
{ {
switch (reg) { switch (reg) {
...@@ -82,19 +167,18 @@ static int alc5632_volatile_register(struct snd_soc_codec *codec, ...@@ -82,19 +167,18 @@ static int alc5632_volatile_register(struct snd_soc_codec *codec,
case ALC5632_OVER_CURR_STATUS: case ALC5632_OVER_CURR_STATUS:
case ALC5632_HID_CTRL_DATA: case ALC5632_HID_CTRL_DATA:
case ALC5632_EQ_CTRL: case ALC5632_EQ_CTRL:
return 1; return true;
default: default:
break; 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 regmap_write(map, ALC5632_RESET, 0x59B4);
return snd_soc_read(codec, ALC5632_RESET);
} }
static int amp_mixer_event(struct snd_soc_dapm_widget *w, static int amp_mixer_event(struct snd_soc_dapm_widget *w,
...@@ -948,16 +1032,9 @@ static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg) ...@@ -948,16 +1032,9 @@ static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
static int alc5632_resume(struct snd_soc_codec *codec) static int alc5632_resume(struct snd_soc_codec *codec)
{ {
int ret; struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
/* mark cache as needed to sync */
codec->cache_sync = 1;
ret = snd_soc_cache_sync(codec); regcache_sync(alc5632->regmap);
if (ret != 0) {
dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
return ret;
}
alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0; return 0;
...@@ -972,14 +1049,14 @@ static int alc5632_probe(struct snd_soc_codec *codec) ...@@ -972,14 +1049,14 @@ static int alc5632_probe(struct snd_soc_codec *codec)
struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
int ret; int ret;
ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5632->control_type); codec->control_data = alc5632->regmap;
if (ret < 0) {
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); dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret; return ret;
} }
alc5632_reset(codec);
/* power on device */ /* power on device */
alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
...@@ -1008,11 +1085,6 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = { ...@@ -1008,11 +1085,6 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
.suspend = alc5632_suspend, .suspend = alc5632_suspend,
.resume = alc5632_resume, .resume = alc5632_resume,
.set_bias_level = alc5632_set_bias_level, .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, .controls = alc5632_snd_controls,
.num_controls = ARRAY_SIZE(alc5632_snd_controls), .num_controls = ARRAY_SIZE(alc5632_snd_controls),
.dapm_widgets = alc5632_dapm_widgets, .dapm_widgets = alc5632_dapm_widgets,
...@@ -1021,13 +1093,24 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = { ...@@ -1021,13 +1093,24 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
.num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), .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 * alc5632 2 wire address is determined by A1 pin
* state during powerup. * state during powerup.
* low = 0x1a * low = 0x1a
* high = 0x1b * 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) const struct i2c_device_id *id)
{ {
struct alc5632_priv *alc5632; struct alc5632_priv *alc5632;
...@@ -1074,20 +1157,38 @@ static int alc5632_i2c_probe(struct i2c_client *client, ...@@ -1074,20 +1157,38 @@ static int alc5632_i2c_probe(struct i2c_client *client,
} }
i2c_set_clientdata(client, alc5632); 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, ret = snd_soc_register_codec(&client->dev,
&soc_codec_device_alc5632, &alc5632_dai, 1); &soc_codec_device_alc5632, &alc5632_dai, 1);
if (ret != 0)
if (ret < 0) {
dev_err(&client->dev, "Failed to register codec: %d\n", ret); dev_err(&client->dev, "Failed to register codec: %d\n", ret);
regmap_exit(alc5632->regmap);
return ret;
}
return ret; return ret;
} }
static int alc5632_i2c_remove(struct i2c_client *client) static int alc5632_i2c_remove(struct i2c_client *client)
{ {
struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev); snd_soc_unregister_codec(&client->dev);
regmap_exit(alc5632->regmap);
return 0; return 0;
} }
......
...@@ -246,4 +246,6 @@ ...@@ -246,4 +246,6 @@
#define ALC5632_VENDOR_ID1 0x7C #define ALC5632_VENDOR_ID1 0x7C
#define ALC5632_VENDOR_ID2 0x7E #define ALC5632_VENDOR_ID2 0x7E
#define ALC5632_MAX_REGISTER 0x7E
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment