Loading sound/soc/codecs/alc5632.c +159 −58 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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) { Loading @@ -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, Loading Loading @@ -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) { int ret; /* mark cache as needed to sync */ codec->cache_sync = 1; struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); ret = snd_soc_cache_sync(codec); if (ret != 0) { dev_err(codec->dev, "Failed to sync cache: %d\n", ret); return ret; } regcache_sync(alc5632->regmap); alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; Loading @@ -972,14 +1049,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); Loading Loading @@ -1008,11 +1085,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, Loading @@ -1021,13 +1093,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; Loading Loading @@ -1074,20 +1157,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; } Loading sound/soc/codecs/alc5632.h +2 −0 Original line number Diff line number Diff line Loading @@ -246,4 +246,6 @@ #define ALC5632_VENDOR_ID1 0x7C #define ALC5632_VENDOR_ID2 0x7E #define ALC5632_MAX_REGISTER 0x7E #endif Loading
sound/soc/codecs/alc5632.c +159 −58 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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) { Loading @@ -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, Loading Loading @@ -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) { int ret; /* mark cache as needed to sync */ codec->cache_sync = 1; struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); ret = snd_soc_cache_sync(codec); if (ret != 0) { dev_err(codec->dev, "Failed to sync cache: %d\n", ret); return ret; } regcache_sync(alc5632->regmap); alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; Loading @@ -972,14 +1049,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); Loading Loading @@ -1008,11 +1085,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, Loading @@ -1021,13 +1093,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; Loading Loading @@ -1074,20 +1157,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; } Loading
sound/soc/codecs/alc5632.h +2 −0 Original line number Diff line number Diff line Loading @@ -246,4 +246,6 @@ #define ALC5632_VENDOR_ID1 0x7C #define ALC5632_VENDOR_ID2 0x7E #define ALC5632_MAX_REGISTER 0x7E #endif