diff options
Diffstat (limited to 'sound/soc/codecs/ak4642.c')
-rw-r--r-- | sound/soc/codecs/ak4642.c | 105 |
1 files changed, 24 insertions, 81 deletions
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 65f46047b1c..12c1bdef673 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/module.h> | ||
29 | #include <sound/soc.h> | 30 | #include <sound/soc.h> |
30 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
31 | #include <sound/tlv.h> | 32 | #include <sound/tlv.h> |
@@ -156,81 +157,22 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = { | |||
156 | struct ak4642_priv { | 157 | struct ak4642_priv { |
157 | unsigned int sysclk; | 158 | unsigned int sysclk; |
158 | enum snd_soc_control_type control_type; | 159 | enum snd_soc_control_type control_type; |
159 | void *control_data; | ||
160 | }; | 160 | }; |
161 | 161 | ||
162 | /* | 162 | /* |
163 | * ak4642 register cache | 163 | * ak4642 register cache |
164 | */ | 164 | */ |
165 | static const u16 ak4642_reg[AK4642_CACHEREGNUM] = { | 165 | static const u8 ak4642_reg[AK4642_CACHEREGNUM] = { |
166 | 0x0000, 0x0000, 0x0001, 0x0000, | 166 | 0x00, 0x00, 0x01, 0x00, |
167 | 0x0002, 0x0000, 0x0000, 0x0000, | 167 | 0x02, 0x00, 0x00, 0x00, |
168 | 0x00e1, 0x00e1, 0x0018, 0x0000, | 168 | 0xe1, 0xe1, 0x18, 0x00, |
169 | 0x00e1, 0x0018, 0x0011, 0x0008, | 169 | 0xe1, 0x18, 0x11, 0x08, |
170 | 0x0000, 0x0000, 0x0000, 0x0000, | 170 | 0x00, 0x00, 0x00, 0x00, |
171 | 0x0000, 0x0000, 0x0000, 0x0000, | 171 | 0x00, 0x00, 0x00, 0x00, |
172 | 0x0000, 0x0000, 0x0000, 0x0000, | 172 | 0x00, 0x00, 0x00, 0x00, |
173 | 0x0000, 0x0000, 0x0000, 0x0000, | 173 | 0x00, 0x00, 0x00, 0x00, |
174 | 0x0000, 0x0000, 0x0000, 0x0000, | 174 | 0x00, 0x00, 0x00, 0x00, |
175 | 0x0000, | 175 | 0x00, |
176 | }; | ||
177 | |||
178 | /* | ||
179 | * read ak4642 register cache | ||
180 | */ | ||
181 | static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec, | ||
182 | unsigned int reg) | ||
183 | { | ||
184 | u16 *cache = codec->reg_cache; | ||
185 | if (reg >= AK4642_CACHEREGNUM) | ||
186 | return -1; | ||
187 | return cache[reg]; | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * write ak4642 register cache | ||
192 | */ | ||
193 | static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec, | ||
194 | u16 reg, unsigned int value) | ||
195 | { | ||
196 | u16 *cache = codec->reg_cache; | ||
197 | if (reg >= AK4642_CACHEREGNUM) | ||
198 | return; | ||
199 | |||
200 | cache[reg] = value; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * write to the AK4642 register space | ||
205 | */ | ||
206 | static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg, | ||
207 | unsigned int value) | ||
208 | { | ||
209 | u8 data[2]; | ||
210 | |||
211 | /* data is | ||
212 | * D15..D8 AK4642 register offset | ||
213 | * D7...D0 register data | ||
214 | */ | ||
215 | data[0] = reg & 0xff; | ||
216 | data[1] = value & 0xff; | ||
217 | |||
218 | if (codec->hw_write(codec->control_data, data, 2) == 2) { | ||
219 | ak4642_write_reg_cache(codec, reg, value); | ||
220 | return 0; | ||
221 | } else | ||
222 | return -EIO; | ||
223 | } | ||
224 | |||
225 | static int ak4642_sync(struct snd_soc_codec *codec) | ||
226 | { | ||
227 | u16 *cache = codec->reg_cache; | ||
228 | int i, r = 0; | ||
229 | |||
230 | for (i = 0; i < AK4642_CACHEREGNUM; i++) | ||
231 | r |= ak4642_write(codec, i, cache[i]); | ||
232 | |||
233 | return r; | ||
234 | }; | 176 | }; |
235 | 177 | ||
236 | static int ak4642_dai_startup(struct snd_pcm_substream *substream, | 178 | static int ak4642_dai_startup(struct snd_pcm_substream *substream, |
@@ -252,8 +194,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, | |||
252 | */ | 194 | */ |
253 | snd_soc_update_bits(codec, MD_CTL4, DACH, DACH); | 195 | snd_soc_update_bits(codec, MD_CTL4, DACH, DACH); |
254 | snd_soc_update_bits(codec, MD_CTL3, BST1, BST1); | 196 | snd_soc_update_bits(codec, MD_CTL3, BST1, BST1); |
255 | ak4642_write(codec, L_IVC, 0x91); /* volume */ | 197 | snd_soc_write(codec, L_IVC, 0x91); /* volume */ |
256 | ak4642_write(codec, R_IVC, 0x91); /* volume */ | 198 | snd_soc_write(codec, R_IVC, 0x91); /* volume */ |
257 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC, | 199 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC, |
258 | PMVCM | PMMIN | PMDAC); | 200 | PMVCM | PMMIN | PMDAC); |
259 | snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); | 201 | snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); |
@@ -272,9 +214,9 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, | |||
272 | * This operation came from example code of | 214 | * This operation came from example code of |
273 | * "ASAHI KASEI AK4642" (japanese) manual p94. | 215 | * "ASAHI KASEI AK4642" (japanese) manual p94. |
274 | */ | 216 | */ |
275 | ak4642_write(codec, SG_SL1, PMMP | MGAIN0); | 217 | snd_soc_write(codec, SG_SL1, PMMP | MGAIN0); |
276 | ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); | 218 | snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); |
277 | ak4642_write(codec, ALC_CTL1, ALC | LMTH0); | 219 | snd_soc_write(codec, ALC_CTL1, ALC | LMTH0); |
278 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL, | 220 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL, |
279 | PMVCM | PMADL); | 221 | PMVCM | PMADL); |
280 | snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); | 222 | snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); |
@@ -462,7 +404,7 @@ static struct snd_soc_dai_driver ak4642_dai = { | |||
462 | 404 | ||
463 | static int ak4642_resume(struct snd_soc_codec *codec) | 405 | static int ak4642_resume(struct snd_soc_codec *codec) |
464 | { | 406 | { |
465 | ak4642_sync(codec); | 407 | snd_soc_cache_sync(codec); |
466 | return 0; | 408 | return 0; |
467 | } | 409 | } |
468 | 410 | ||
@@ -470,11 +412,15 @@ static int ak4642_resume(struct snd_soc_codec *codec) | |||
470 | static int ak4642_probe(struct snd_soc_codec *codec) | 412 | static int ak4642_probe(struct snd_soc_codec *codec) |
471 | { | 413 | { |
472 | struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); | 414 | struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); |
415 | int ret; | ||
473 | 416 | ||
474 | dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); | 417 | dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); |
475 | 418 | ||
476 | codec->hw_write = (hw_write_t)i2c_master_send; | 419 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type); |
477 | codec->control_data = ak4642->control_data; | 420 | if (ret < 0) { |
421 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
422 | return ret; | ||
423 | } | ||
478 | 424 | ||
479 | snd_soc_add_controls(codec, ak4642_snd_controls, | 425 | snd_soc_add_controls(codec, ak4642_snd_controls, |
480 | ARRAY_SIZE(ak4642_snd_controls)); | 426 | ARRAY_SIZE(ak4642_snd_controls)); |
@@ -485,8 +431,6 @@ static int ak4642_probe(struct snd_soc_codec *codec) | |||
485 | static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { | 431 | static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { |
486 | .probe = ak4642_probe, | 432 | .probe = ak4642_probe, |
487 | .resume = ak4642_resume, | 433 | .resume = ak4642_resume, |
488 | .read = ak4642_read_reg_cache, | ||
489 | .write = ak4642_write, | ||
490 | .reg_cache_size = ARRAY_SIZE(ak4642_reg), | 434 | .reg_cache_size = ARRAY_SIZE(ak4642_reg), |
491 | .reg_word_size = sizeof(u8), | 435 | .reg_word_size = sizeof(u8), |
492 | .reg_cache_default = ak4642_reg, | 436 | .reg_cache_default = ak4642_reg, |
@@ -504,7 +448,6 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, | |||
504 | return -ENOMEM; | 448 | return -ENOMEM; |
505 | 449 | ||
506 | i2c_set_clientdata(i2c, ak4642); | 450 | i2c_set_clientdata(i2c, ak4642); |
507 | ak4642->control_data = i2c; | ||
508 | ak4642->control_type = SND_SOC_I2C; | 451 | ak4642->control_type = SND_SOC_I2C; |
509 | 452 | ||
510 | ret = snd_soc_register_codec(&i2c->dev, | 453 | ret = snd_soc_register_codec(&i2c->dev, |