aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic23.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-10-25 05:43:47 -0400
committerTakashi Iwai <tiwai@suse.de>2013-10-25 05:43:47 -0400
commit6913a9dbf18f08e3577695032da15812bda92b66 (patch)
tree05ca8620b11f2898022a7fd8a00f1f8566161428 /sound/soc/codecs/tlv320aic23.c
parent7342017f4a0f129d277f78b8761f2732661ba30a (diff)
parent9645083ca5ef365b7b750cf219bb20b61bb925f8 (diff)
Merge tag 'asoc-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v3.13 - Further work on the dmaengine helpers, including support for configuring the parameters for DMA by reading the capabilities of the DMA controller which removes some guesswork and magic numbers fromm drivers. - A refresh of the documentation. - Conversions of many drivers to direct regmap API usage in order to allow the ASoC level register I/O code to be removed, this will hopefully be completed by v3.14. - Support for using async register I/O in DAPM, reducing the time taken to implement power transitions on systems that support it.
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>");