aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic23.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320aic23.c')
-rw-r--r--sound/soc/codecs/tlv320aic23.c84
1 files changed, 34 insertions, 50 deletions
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 31762ebdd774..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
@@ -586,9 +594,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
586 594
587 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); 595 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
588 596
589 snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls,
590 ARRAY_SIZE(tlv320aic23_snd_controls));
591
592 return 0; 597 return 0;
593} 598}
594 599
@@ -599,21 +604,19 @@ static int tlv320aic23_remove(struct snd_soc_codec *codec)
599} 604}
600 605
601static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { 606static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
602 .reg_cache_size = ARRAY_SIZE(tlv320aic23_reg),
603 .reg_word_size = sizeof(u16),
604 .reg_cache_default = tlv320aic23_reg,
605 .probe = tlv320aic23_probe, 607 .probe = tlv320aic23_probe,
606 .remove = tlv320aic23_remove, 608 .remove = tlv320aic23_remove,
607 .suspend = tlv320aic23_suspend, 609 .suspend = tlv320aic23_suspend,
608 .resume = tlv320aic23_resume, 610 .resume = tlv320aic23_resume,
609 .set_bias_level = tlv320aic23_set_bias_level, 611 .set_bias_level = tlv320aic23_set_bias_level,
612 .controls = tlv320aic23_snd_controls,
613 .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls),
610 .dapm_widgets = tlv320aic23_dapm_widgets, 614 .dapm_widgets = tlv320aic23_dapm_widgets,
611 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), 615 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
612 .dapm_routes = tlv320aic23_intercon, 616 .dapm_routes = tlv320aic23_intercon,
613 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), 617 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
614}; 618};
615 619
616#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
617/* 620/*
618 * If the i2c layer weren't so broken, we could pass this kind of data 621 * If the i2c layer weren't so broken, we could pass this kind of data
619 * around 622 * around
@@ -631,8 +634,11 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c,
631 if (aic23 == NULL) 634 if (aic23 == NULL)
632 return -ENOMEM; 635 return -ENOMEM;
633 636
637 aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
638 if (IS_ERR(aic23->regmap))
639 return PTR_ERR(aic23->regmap);
640
634 i2c_set_clientdata(i2c, aic23); 641 i2c_set_clientdata(i2c, aic23);
635 aic23->control_type = SND_SOC_I2C;
636 642
637 ret = snd_soc_register_codec(&i2c->dev, 643 ret = snd_soc_register_codec(&i2c->dev,
638 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1); 644 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
@@ -660,29 +666,7 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
660 .id_table = tlv320aic23_id, 666 .id_table = tlv320aic23_id,
661}; 667};
662 668
663#endif 669module_i2c_driver(tlv320aic23_i2c_driver);
664
665static int __init tlv320aic23_modinit(void)
666{
667 int ret;
668#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
669 ret = i2c_add_driver(&tlv320aic23_i2c_driver);
670 if (ret != 0) {
671 printk(KERN_ERR "Failed to register TLV320AIC23 I2C driver: %d\n",
672 ret);
673 }
674#endif
675 return ret;
676}
677module_init(tlv320aic23_modinit);
678
679static void __exit tlv320aic23_exit(void)
680{
681#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
682 i2c_del_driver(&tlv320aic23_i2c_driver);
683#endif
684}
685module_exit(tlv320aic23_exit);
686 670
687MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); 671MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
688MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); 672MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");