diff options
author | Leon Romanovsky <leon@leon.nu> | 2011-11-16 05:06:58 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-11-16 05:41:56 -0500 |
commit | bb39753c2ba69d4d9467a109b03861cf43a6dcf8 (patch) | |
tree | 0d3e259a1becaa2df5fd46cd1fa0740d893a0380 /sound/soc/codecs/alc5632.c | |
parent | c9be8427b1dbd5e9d0313762fb80b2633abb694b (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.c | 217 |
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 | */ |
37 | static const u16 alc5632_reg_defaults[] = { | 38 | static 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 */ |
69 | struct alc5632_priv { | 154 | struct 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 | ||
75 | static int alc5632_volatile_register(struct snd_soc_codec *codec, | 160 | static 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 | ||
94 | static inline int alc5632_reset(struct snd_soc_codec *codec) | 179 | static 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 | ||
100 | static int amp_mixer_event(struct snd_soc_dapm_widget *w, | 184 | 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 | 1032 | ||
949 | static int alc5632_resume(struct snd_soc_codec *codec) | 1033 | static 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 | ||
1096 | static 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 | */ |
1030 | static int alc5632_i2c_probe(struct i2c_client *client, | 1113 | static __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 | ||
1087 | static int alc5632_i2c_remove(struct i2c_client *client) | 1187 | static 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 | ||