aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/ak4535.c66
-rw-r--r--sound/soc/codecs/ak4535.h2
2 files changed, 55 insertions, 13 deletions
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index e13303a6500f..838ae8b22b50 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -29,20 +30,41 @@
29 30
30/* codec private data */ 31/* codec private data */
31struct ak4535_priv { 32struct ak4535_priv {
33 struct regmap *regmap;
32 unsigned int sysclk; 34 unsigned int sysclk;
33 enum snd_soc_control_type control_type;
34}; 35};
35 36
36/* 37/*
37 * ak4535 register cache 38 * ak4535 register cache
38 */ 39 */
39static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { 40static const struct reg_default ak4535_reg_defaults[] = {
40 0x00, 0x80, 0x00, 0x03, 41 { 0, 0x00 },
41 0x02, 0x00, 0x11, 0x01, 42 { 1, 0x80 },
42 0x00, 0x40, 0x36, 0x10, 43 { 2, 0x00 },
43 0x00, 0x00, 0x57, 0x00, 44 { 3, 0x03 },
45 { 4, 0x02 },
46 { 5, 0x00 },
47 { 6, 0x11 },
48 { 7, 0x01 },
49 { 8, 0x00 },
50 { 9, 0x40 },
51 { 10, 0x36 },
52 { 11, 0x10 },
53 { 12, 0x00 },
54 { 13, 0x00 },
55 { 14, 0x57 },
44}; 56};
45 57
58static bool ak4535_volatile(struct device *dev, unsigned int reg)
59{
60 switch (reg) {
61 case AK4535_STATUS:
62 return true;
63 default:
64 return false;
65 }
66}
67
46static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; 68static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
47static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; 69static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
48static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; 70static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
@@ -370,7 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec)
370 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 392 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
371 int ret; 393 int ret;
372 394
373 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type); 395 codec->control_data = ak4535->regmap;
396 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
374 if (ret < 0) { 397 if (ret < 0) {
375 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 398 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
376 return ret; 399 return ret;
@@ -390,15 +413,24 @@ static int ak4535_remove(struct snd_soc_codec *codec)
390 return 0; 413 return 0;
391} 414}
392 415
416static const struct regmap_config ak4535_regmap = {
417 .reg_bits = 8,
418 .val_bits = 8,
419
420 .max_register = AK4535_STATUS,
421 .volatile_reg = ak4535_volatile,
422
423 .cache_type = REGCACHE_RBTREE,
424 .reg_defaults = ak4535_reg_defaults,
425 .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
426};
427
393static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { 428static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
394 .probe = ak4535_probe, 429 .probe = ak4535_probe,
395 .remove = ak4535_remove, 430 .remove = ak4535_remove,
396 .suspend = ak4535_suspend, 431 .suspend = ak4535_suspend,
397 .resume = ak4535_resume, 432 .resume = ak4535_resume,
398 .set_bias_level = ak4535_set_bias_level, 433 .set_bias_level = ak4535_set_bias_level,
399 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
400 .reg_word_size = sizeof(u8),
401 .reg_cache_default = ak4535_reg,
402 .dapm_widgets = ak4535_dapm_widgets, 434 .dapm_widgets = ak4535_dapm_widgets,
403 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), 435 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
404 .dapm_routes = ak4535_audio_map, 436 .dapm_routes = ak4535_audio_map,
@@ -416,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
416 if (ak4535 == NULL) 448 if (ak4535 == NULL)
417 return -ENOMEM; 449 return -ENOMEM;
418 450
451 ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
452 if (IS_ERR(ak4535->regmap)) {
453 ret = PTR_ERR(ak4535->regmap);
454 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
455 return ret;
456 }
457
419 i2c_set_clientdata(i2c, ak4535); 458 i2c_set_clientdata(i2c, ak4535);
420 ak4535->control_type = SND_SOC_I2C;
421 459
422 ret = snd_soc_register_codec(&i2c->dev, 460 ret = snd_soc_register_codec(&i2c->dev,
423 &soc_codec_dev_ak4535, &ak4535_dai, 1); 461 &soc_codec_dev_ak4535, &ak4535_dai, 1);
462 if (ret != 0)
463 regmap_exit(ak4535->regmap);
464
424 return ret; 465 return ret;
425} 466}
426 467
427static __devexit int ak4535_i2c_remove(struct i2c_client *client) 468static __devexit int ak4535_i2c_remove(struct i2c_client *client)
428{ 469{
470 struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
471
429 snd_soc_unregister_codec(&client->dev); 472 snd_soc_unregister_codec(&client->dev);
473 regmap_exit(ak4535->regmap);
430 return 0; 474 return 0;
431} 475}
432 476
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index 0431e5f634a2..402de1d274bf 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -34,6 +34,4 @@
34#define AK4535_VOL 0xe 34#define AK4535_VOL 0xe
35#define AK4535_STATUS 0xf 35#define AK4535_STATUS 0xf
36 36
37#define AK4535_CACHEREGNUM 0x10
38
39#endif 37#endif