aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/alc5632.c
diff options
context:
space:
mode:
authorLeon Romanovsky <leon@leon.nu>2011-11-16 05:06:58 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-11-16 05:41:56 -0500
commitbb39753c2ba69d4d9467a109b03861cf43a6dcf8 (patch)
tree0d3e259a1becaa2df5fd46cd1fa0740d893a0380 /sound/soc/codecs/alc5632.c
parentc9be8427b1dbd5e9d0313762fb80b2633abb694b (diff)
ASoC: Convert ALC5632 codec to use regmap API
Signed-off-by: Leon Romanovsky <leon@leon.nu> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/alc5632.c')
-rw-r--r--sound/soc/codecs/alc5632.c217
1 files changed, 159 insertions, 58 deletions
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index e560a2119b12..c5055c1a2d55 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -22,6 +22,7 @@
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/regmap.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
@@ -34,45 +35,129 @@
34/* 35/*
35 * ALC5632 register cache 36 * ALC5632 register cache
36 */ 37 */
37static const u16 alc5632_reg_defaults[] = { 38static struct reg_default alc5632_reg_defaults[] = {
38 0x59B4, 0x0000, 0x8080, 0x0000, /* 0 */ 39 { 0, 0x59B4 },
39 0x8080, 0x0000, 0x8080, 0x0000, /* 4 */ 40 { 1, 0x0000 },
40 0xC800, 0x0000, 0xE808, 0x0000, /* 8 */ 41 { 2, 0x8080 },
41 0x1010, 0x0000, 0x0808, 0x0000, /* 12 */ 42 { 3, 0x0000 },
42 0xEE0F, 0x0000, 0xCBCB, 0x0000, /* 16 */ 43 { 4, 0x8080 },
43 0x7F7F, 0x0000, 0x0000, 0x0000, /* 20 */ 44 { 5, 0x0000 },
44 0xE010, 0x0000, 0x0000, 0x0000, /* 24 */ 45 { 6, 0x8080 },
45 0x8008, 0x0000, 0x0000, 0x0000, /* 28 */ 46 { 7, 0x0000 },
46 0x0000, 0x0000, 0x0000, 0x0000, /* 32 */ 47 { 8, 0xC800 },
47 0x00C0, 0x0000, 0xEF00, 0x0000, /* 36 */ 48 { 9, 0x0000 },
48 0x0000, 0x0000, 0x0000, 0x0000, /* 40 */ 49 { 10, 0xE808 },
49 0x0000, 0x0000, 0x0000, 0x0000, /* 44 */ 50 { 11, 0x0000 },
50 0x0000, 0x0000, 0x0000, 0x0000, /* 48 */ 51 { 12, 0x1010 },
51 0x8000, 0x0000, 0x0000, 0x0000, /* 52 */ 52 { 13, 0x0000 },
52 0x0000, 0x0000, 0x0000, 0x0000, /* 56 */ 53 { 14, 0x0808 },
53 0x0000, 0x0000, 0x8000, 0x0000, /* 60 */ 54 { 15, 0x0000 },
54 0x0C0A, 0x0000, 0x0000, 0x0000, /* 64 */ 55 { 16, 0xEE0F },
55 0x0000, 0x0000, 0x0000, 0x0000, /* 68 */ 56 { 17, 0x0000 },
56 0x0000, 0x0000, 0x0000, 0x0000, /* 72 */ 57 { 18, 0xCBCB },
57 0xBE3E, 0x0000, 0xBE3E, 0x0000, /* 76 */ 58 { 19, 0x0000 },
58 0x0000, 0x0000, 0x0000, 0x0000, /* 80 */ 59 { 20, 0x7F7F },
59 0x803A, 0x0000, 0x0000, 0x0000, /* 84 */ 60 { 21, 0x0000 },
60 0x0000, 0x0000, 0x0009, 0x0000, /* 88 */ 61 { 22, 0x0000 },
61 0x0000, 0x0000, 0x3000, 0x0000, /* 92 */ 62 { 23, 0x0000 },
62 0x3075, 0x0000, 0x1010, 0x0000, /* 96 */ 63 { 24, 0xE010 },
63 0x3110, 0x0000, 0x0000, 0x0000, /* 100 */ 64 { 25, 0x0000 },
64 0x0553, 0x0000, 0x0000, 0x0000, /* 104 */ 65 { 26, 0x0000 },
65 0x0000, 0x0000, 0x0000, 0x0000, /* 108 */ 66 { 27, 0x0000 },
67 { 28, 0x8008 },
68 { 29, 0x0000 },
69 { 30, 0x0000 },
70 { 31, 0x0000 },
71 { 32, 0x0000 },
72 { 33, 0x0000 },
73 { 34, 0x0000 },
74 { 35, 0x0000 },
75 { 36, 0x00C0 },
76 { 37, 0x0000 },
77 { 38, 0xEF00 },
78 { 39, 0x0000 },
79 { 40, 0x0000 },
80 { 41, 0x0000 },
81 { 42, 0x0000 },
82 { 43, 0x0000 },
83 { 44, 0x0000 },
84 { 45, 0x0000 },
85 { 46, 0x0000 },
86 { 47, 0x0000 },
87 { 48, 0x0000 },
88 { 49, 0x0000 },
89 { 50, 0x0000 },
90 { 51, 0x0000 },
91 { 52, 0x8000 },
92 { 53, 0x0000 },
93 { 54, 0x0000 },
94 { 55, 0x0000 },
95 { 56, 0x0000 },
96 { 57, 0x0000 },
97 { 58, 0x0000 },
98 { 59, 0x0000 },
99 { 60, 0x0000 },
100 { 61, 0x0000 },
101 { 62, 0x8000 },
102 { 63, 0x0000 },
103 { 64, 0x0C0A },
104 { 65, 0x0000 },
105 { 66, 0x0000 },
106 { 67, 0x0000 },
107 { 68, 0x0000 },
108 { 69, 0x0000 },
109 { 70, 0x0000 },
110 { 71, 0x0000 },
111 { 72, 0x0000 },
112 { 73, 0x0000 },
113 { 74, 0x0000 },
114 { 75, 0x0000 },
115 { 76, 0xBE3E },
116 { 77, 0x0000 },
117 { 78, 0xBE3E },
118 { 79, 0x0000 },
119 { 80, 0x0000 },
120 { 81, 0x0000 },
121 { 82, 0x0000 },
122 { 83, 0x0000 },
123 { 84, 0x803A },
124 { 85, 0x0000 },
125 { 86, 0x0000 },
126 { 87, 0x0000 },
127 { 88, 0x0000 },
128 { 89, 0x0000 },
129 { 90, 0x0009 },
130 { 91, 0x0000 },
131 { 92, 0x0000 },
132 { 93, 0x0000 },
133 { 94, 0x3000 },
134 { 95, 0x0000 },
135 { 96, 0x3075 },
136 { 97, 0x0000 },
137 { 98, 0x1010 },
138 { 99, 0x0000 },
139 { 100, 0x3110 },
140 { 101, 0x0000 },
141 { 102, 0x0000 },
142 { 103, 0x0000 },
143 { 104, 0x0553 },
144 { 105, 0x0000 },
145 { 106, 0x0000 },
146 { 107, 0x0000 },
147 { 108, 0x0000 },
148 { 109, 0x0000 },
149 { 110, 0x0000 },
150 { 111, 0x0000 },
66}; 151};
67 152
68/* codec private data */ 153/* codec private data */
69struct alc5632_priv { 154struct alc5632_priv {
70 enum snd_soc_control_type control_type; 155 struct regmap *regmap;
71 u8 id; 156 u8 id;
72 unsigned int sysclk; 157 unsigned int sysclk;
73}; 158};
74 159
75static int alc5632_volatile_register(struct snd_soc_codec *codec, 160static bool alc5632_volatile_register(struct device *dev,
76 unsigned int reg) 161 unsigned int reg)
77{ 162{
78 switch (reg) { 163 switch (reg) {
@@ -82,19 +167,18 @@ static int alc5632_volatile_register(struct snd_soc_codec *codec,
82 case ALC5632_OVER_CURR_STATUS: 167 case ALC5632_OVER_CURR_STATUS:
83 case ALC5632_HID_CTRL_DATA: 168 case ALC5632_HID_CTRL_DATA:
84 case ALC5632_EQ_CTRL: 169 case ALC5632_EQ_CTRL:
85 return 1; 170 return true;
86 171
87 default: 172 default:
88 break; 173 break;
89 } 174 }
90 175
91 return 0; 176 return false;
92} 177}
93 178
94static inline int alc5632_reset(struct snd_soc_codec *codec) 179static inline int alc5632_reset(struct regmap *map)
95{ 180{
96 snd_soc_write(codec, ALC5632_RESET, 0); 181 return regmap_write(map, ALC5632_RESET, 0x59B4);
97 return snd_soc_read(codec, ALC5632_RESET);
98} 182}
99 183
100static int amp_mixer_event(struct snd_soc_dapm_widget *w, 184static 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 1032
949static int alc5632_resume(struct snd_soc_codec *codec) 1033static int alc5632_resume(struct snd_soc_codec *codec)
950{ 1034{
951 int ret; 1035 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
952
953 /* mark cache as needed to sync */
954 codec->cache_sync = 1;
955 1036
956 ret = snd_soc_cache_sync(codec); 1037 regcache_sync(alc5632->regmap);
957 if (ret != 0) {
958 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
959 return ret;
960 }
961 1038
962 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1039 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
963 return 0; 1040 return 0;
@@ -972,14 +1049,14 @@ static int alc5632_probe(struct snd_soc_codec *codec)
972 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); 1049 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
973 int ret; 1050 int ret;
974 1051
975 ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5632->control_type); 1052 codec->control_data = alc5632->regmap;
976 if (ret < 0) { 1053
1054 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1055 if (ret != 0) {
977 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1056 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
978 return ret; 1057 return ret;
979 } 1058 }
980 1059
981 alc5632_reset(codec);
982
983 /* power on device */ 1060 /* power on device */
984 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1061 alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
985 1062
@@ -1008,11 +1085,6 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
1008 .suspend = alc5632_suspend, 1085 .suspend = alc5632_suspend,
1009 .resume = alc5632_resume, 1086 .resume = alc5632_resume,
1010 .set_bias_level = alc5632_set_bias_level, 1087 .set_bias_level = alc5632_set_bias_level,
1011 .reg_word_size = sizeof(u16),
1012 .reg_cache_step = 2,
1013 .reg_cache_default = alc5632_reg_defaults,
1014 .reg_cache_size = ARRAY_SIZE(alc5632_reg_defaults),
1015 .volatile_register = alc5632_volatile_register,
1016 .controls = alc5632_snd_controls, 1088 .controls = alc5632_snd_controls,
1017 .num_controls = ARRAY_SIZE(alc5632_snd_controls), 1089 .num_controls = ARRAY_SIZE(alc5632_snd_controls),
1018 .dapm_widgets = alc5632_dapm_widgets, 1090 .dapm_widgets = alc5632_dapm_widgets,
@@ -1021,13 +1093,24 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
1021 .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), 1093 .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
1022}; 1094};
1023 1095
1096static struct regmap_config alc5632_regmap = {
1097 .reg_bits = 8,
1098 .val_bits = 16,
1099
1100 .max_register = ALC5632_MAX_REGISTER,
1101 .reg_defaults = alc5632_reg_defaults,
1102 .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults),
1103 .volatile_reg = alc5632_volatile_register,
1104 .cache_type = REGCACHE_RBTREE,
1105};
1106
1024/* 1107/*
1025 * alc5632 2 wire address is determined by A1 pin 1108 * alc5632 2 wire address is determined by A1 pin
1026 * state during powerup. 1109 * state during powerup.
1027 * low = 0x1a 1110 * low = 0x1a
1028 * high = 0x1b 1111 * high = 0x1b
1029 */ 1112 */
1030static int alc5632_i2c_probe(struct i2c_client *client, 1113static __devinit int alc5632_i2c_probe(struct i2c_client *client,
1031 const struct i2c_device_id *id) 1114 const struct i2c_device_id *id)
1032{ 1115{
1033 struct alc5632_priv *alc5632; 1116 struct alc5632_priv *alc5632;
@@ -1074,20 +1157,38 @@ static int alc5632_i2c_probe(struct i2c_client *client,
1074 } 1157 }
1075 1158
1076 i2c_set_clientdata(client, alc5632); 1159 i2c_set_clientdata(client, alc5632);
1077 alc5632->control_type = SND_SOC_I2C; 1160
1161 alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap);
1162 if (IS_ERR(alc5632->regmap)) {
1163 ret = PTR_ERR(alc5632->regmap);
1164 dev_err(&client->dev, "regmap_init() failed: %d\n", ret);
1165 return ret;
1166 }
1167
1168 ret = alc5632_reset(alc5632->regmap);
1169 if (ret < 0) {
1170 dev_err(&client->dev, "Failed to issue reset\n");
1171 regmap_exit(alc5632->regmap);
1172 return ret;
1173 }
1078 1174
1079 ret = snd_soc_register_codec(&client->dev, 1175 ret = snd_soc_register_codec(&client->dev,
1080 &soc_codec_device_alc5632, &alc5632_dai, 1); 1176 &soc_codec_device_alc5632, &alc5632_dai, 1);
1081 if (ret != 0) 1177
1178 if (ret < 0) {
1082 dev_err(&client->dev, "Failed to register codec: %d\n", ret); 1179 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1180 regmap_exit(alc5632->regmap);
1181 return ret;
1182 }
1083 1183
1084 return ret; 1184 return ret;
1085} 1185}
1086 1186
1087static int alc5632_i2c_remove(struct i2c_client *client) 1187static int alc5632_i2c_remove(struct i2c_client *client)
1088{ 1188{
1189 struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
1089 snd_soc_unregister_codec(&client->dev); 1190 snd_soc_unregister_codec(&client->dev);
1090 1191 regmap_exit(alc5632->regmap);
1091 return 0; 1192 return 0;
1092} 1193}
1093 1194