aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/tlv320aic23.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 3a6be8c3d557..5d430cc56f51 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -24,6 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/regmap.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
@@ -37,11 +38,27 @@
37/* 38/*
38 * AIC23 register cache 39 * AIC23 register cache
39 */ 40 */
40static const u16 tlv320aic23_reg[] = { 41static const struct reg_default tlv320aic23_reg[] = {
41 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */ 42 { 0, 0x0097 },
42 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */ 43 { 1, 0x0097 },
43 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */ 44 { 2, 0x00F9 },
44 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */ 45 { 3, 0x00F9 },
46 { 4, 0x001A },
47 { 5, 0x0004 },
48 { 6, 0x0007 },
49 { 7, 0x0001 },
50 { 8, 0x0020 },
51 { 9, 0x0000 },
52};
53
54static const struct regmap_config tlv320aic23_regmap = {
55 .reg_bits = 7,
56 .val_bits = 9,
57
58 .max_register = TLV320AIC23_RESET,
59 .reg_defaults = tlv320aic23_reg,
60 .num_reg_defaults = ARRAY_SIZE(tlv320aic23_reg),
61 .cache_type = REGCACHE_RBTREE,
45}; 62};
46 63
47static const char *rec_src_text[] = { "Line", "Mic" }; 64static const char *rec_src_text[] = { "Line", "Mic" };
@@ -171,7 +188,7 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
171 188
172/* AIC23 driver data */ 189/* AIC23 driver data */
173struct aic23 { 190struct aic23 {
174 enum snd_soc_control_type control_type; 191 struct regmap *regmap;
175 int mclk; 192 int mclk;
176 int requested_adc; 193 int requested_adc;
177 int requested_dac; 194 int requested_dac;
@@ -532,7 +549,9 @@ static int tlv320aic23_suspend(struct snd_soc_codec *codec)
532 549
533static int tlv320aic23_resume(struct snd_soc_codec *codec) 550static int tlv320aic23_resume(struct snd_soc_codec *codec)
534{ 551{
535 snd_soc_cache_sync(codec); 552 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
553 regcache_mark_dirty(aic23->regmap);
554 regcache_sync(aic23->regmap);
536 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 555 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
537 556
538 return 0; 557 return 0;
@@ -540,10 +559,9 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
540 559
541static int tlv320aic23_probe(struct snd_soc_codec *codec) 560static int tlv320aic23_probe(struct snd_soc_codec *codec)
542{ 561{
543 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
544 int ret; 562 int ret;
545 563
546 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type); 564 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
547 if (ret < 0) { 565 if (ret < 0) {
548 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 566 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
549 return ret; 567 return ret;
@@ -552,16 +570,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
552 /* Reset codec */ 570 /* Reset codec */
553 snd_soc_write(codec, TLV320AIC23_RESET, 0); 571 snd_soc_write(codec, TLV320AIC23_RESET, 0);
554 572
555 /* Write the register default value to cache for reserved registers,
556 * so the write to the these registers are suppressed by the cache
557 * restore code when it skips writes of default registers.
558 */
559 snd_soc_cache_write(codec, 0x0A, 0);
560 snd_soc_cache_write(codec, 0x0B, 0);
561 snd_soc_cache_write(codec, 0x0C, 0);
562 snd_soc_cache_write(codec, 0x0D, 0);
563 snd_soc_cache_write(codec, 0x0E, 0);
564
565 /* power on device */ 573 /* power on device */
566 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 574 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 575
@@ -596,9 +604,6 @@ static int tlv320aic23_remove(struct snd_soc_codec *codec)
596} 604}
597 605
598static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { 606static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
599 .reg_cache_size = ARRAY_SIZE(tlv320aic23_reg),
600 .reg_word_size = sizeof(u16),
601 .reg_cache_default = tlv320aic23_reg,
602 .probe = tlv320aic23_probe, 607 .probe = tlv320aic23_probe,
603 .remove = tlv320aic23_remove, 608 .remove = tlv320aic23_remove,
604 .suspend = tlv320aic23_suspend, 609 .suspend = tlv320aic23_suspend,
@@ -629,8 +634,11 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c,
629 if (aic23 == NULL) 634 if (aic23 == NULL)
630 return -ENOMEM; 635 return -ENOMEM;
631 636
637 aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
638 if (IS_ERR(aic23->regmap))
639 return PTR_ERR(aic23->regmap);
640
632 i2c_set_clientdata(i2c, aic23); 641 i2c_set_clientdata(i2c, aic23);
633 aic23->control_type = SND_SOC_I2C;
634 642
635 ret = snd_soc_register_codec(&i2c->dev, 643 ret = snd_soc_register_codec(&i2c->dev,
636 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1); 644 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);