aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ak4642.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ak4642.c')
-rw-r--r--sound/soc/codecs/ak4642.c105
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[] = {
156struct ak4642_priv { 157struct 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 */
165static const u16 ak4642_reg[AK4642_CACHEREGNUM] = { 165static 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 */
181static 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 */
193static 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 */
206static 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
225static 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
236static int ak4642_dai_startup(struct snd_pcm_substream *substream, 178static 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
463static int ak4642_resume(struct snd_soc_codec *codec) 405static 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)
470static int ak4642_probe(struct snd_soc_codec *codec) 412static 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)
485static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 431static 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,