aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-03-06 05:04:41 -0500
committerMark Brown <broonie@linaro.org>2014-03-06 21:55:33 -0500
commitb3fc5725967cea8b661383742ccce21fdeb3ef72 (patch)
treeea6f1a500c802f76ca247887cf76534c294f0c7d /sound/soc/codecs
parent806057cc75ef641cd9b012b0278c1f179090bab2 (diff)
ASoC: tlv320aic23: add support for SPI control mode
tlv320aic23 chip control interface may work in either I2C or SPI mode depending on the MODE pin state. Functionality and register layout are independent of the control mode. Implement bus-specific parts as separate modules. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig11
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/tlv320aic23-i2c.c59
-rw-r--r--sound/soc/codecs/tlv320aic23-spi.c57
-rw-r--r--sound/soc/codecs/tlv320aic23.c55
-rw-r--r--sound/soc/codecs/tlv320aic23.h6
6 files changed, 147 insertions, 45 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 983d087aa92a..5e4fc048d42a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -71,7 +71,8 @@ config SND_SOC_ALL_CODECS
71 select SND_SOC_STA529 if I2C 71 select SND_SOC_STA529 if I2C
72 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 72 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
73 select SND_SOC_TAS5086 if I2C 73 select SND_SOC_TAS5086 if I2C
74 select SND_SOC_TLV320AIC23 if I2C 74 select SND_SOC_TLV320AIC23_I2C if I2C
75 select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
75 select SND_SOC_TLV320AIC26 if SPI_MASTER 76 select SND_SOC_TLV320AIC26 if SPI_MASTER
76 select SND_SOC_TLV320AIC32X4 if I2C 77 select SND_SOC_TLV320AIC32X4 if I2C
77 select SND_SOC_TLV320AIC3X if I2C 78 select SND_SOC_TLV320AIC3X if I2C
@@ -357,6 +358,14 @@ config SND_SOC_TAS5086
357config SND_SOC_TLV320AIC23 358config SND_SOC_TLV320AIC23
358 tristate 359 tristate
359 360
361config SND_SOC_TLV320AIC23_I2C
362 tristate
363 select SND_SOC_TLV320AIC23
364
365config SND_SOC_TLV320AIC23_SPI
366 tristate
367 select SND_SOC_TLV320AIC23
368
360config SND_SOC_TLV320AIC26 369config SND_SOC_TLV320AIC26
361 tristate 370 tristate
362 depends on SPI 371 depends on SPI
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index bc126764a44d..ed1fd8925e43 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -63,6 +63,8 @@ snd-soc-sta529-objs := sta529.o
63snd-soc-stac9766-objs := stac9766.o 63snd-soc-stac9766-objs := stac9766.o
64snd-soc-tas5086-objs := tas5086.o 64snd-soc-tas5086-objs := tas5086.o
65snd-soc-tlv320aic23-objs := tlv320aic23.o 65snd-soc-tlv320aic23-objs := tlv320aic23.o
66snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
67snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
66snd-soc-tlv320aic26-objs := tlv320aic26.o 68snd-soc-tlv320aic26-objs := tlv320aic26.o
67snd-soc-tlv320aic3x-objs := tlv320aic3x.o 69snd-soc-tlv320aic3x-objs := tlv320aic3x.o
68snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o 70snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
@@ -193,6 +195,8 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
193obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 195obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
194obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o 196obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
195obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 197obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
198obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
199obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
196obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 200obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
197obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 201obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
198obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o 202obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c
new file mode 100644
index 000000000000..20fc46092c2c
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23-i2c.c
@@ -0,0 +1,59 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver I2C interface
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/i2c.h>
15#include <linux/module.h>
16#include <linux/regmap.h>
17#include <sound/soc.h>
18
19#include "tlv320aic23.h"
20
21static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
22 const struct i2c_device_id *i2c_id)
23{
24 struct regmap *regmap;
25
26 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
27 return -EINVAL;
28
29 regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
30 return tlv320aic23_probe(&i2c->dev, regmap);
31}
32
33static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
34{
35 snd_soc_unregister_codec(&i2c->dev);
36 return 0;
37}
38
39static const struct i2c_device_id tlv320aic23_id[] = {
40 {"tlv320aic23", 0},
41 {}
42};
43
44MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
45
46static struct i2c_driver tlv320aic23_i2c_driver = {
47 .driver = {
48 .name = "tlv320aic23-codec",
49 },
50 .probe = tlv320aic23_i2c_probe,
51 .remove = __exit_p(tlv320aic23_i2c_remove),
52 .id_table = tlv320aic23_id,
53};
54
55module_i2c_driver(tlv320aic23_i2c_driver);
56
57MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver I2C");
58MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
59MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23-spi.c b/sound/soc/codecs/tlv320aic23-spi.c
new file mode 100644
index 000000000000..585aea436c6a
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23-spi.c
@@ -0,0 +1,57 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver SPI interface
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/regmap.h>
16#include <linux/spi/spi.h>
17#include <sound/soc.h>
18
19#include "tlv320aic23.h"
20
21static int aic23_spi_probe(struct spi_device *spi)
22{
23 int ret;
24 struct regmap *regmap;
25
26 dev_dbg(&spi->dev, "probing tlv320aic23 spi device\n");
27
28 spi->bits_per_word = 16;
29 spi->mode = SPI_MODE_0;
30 ret = spi_setup(spi);
31 if (ret < 0)
32 return ret;
33
34 regmap = devm_regmap_init_spi(spi, &tlv320aic23_regmap);
35 return tlv320aic23_probe(&spi->dev, regmap);
36}
37
38static int aic23_spi_remove(struct spi_device *spi)
39{
40 snd_soc_unregister_codec(&spi->dev);
41 return 0;
42}
43
44static struct spi_driver aic23_spi = {
45 .driver = {
46 .name = "tlv320aic23",
47 .owner = THIS_MODULE,
48 },
49 .probe = aic23_spi_probe,
50 .remove = aic23_spi_remove,
51};
52
53module_spi_driver(aic23_spi);
54
55MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver SPI");
56MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
57MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 139f11f4dd8b..ab369ae76b8c 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -23,7 +23,6 @@
23#include <linux/init.h> 23#include <linux/init.h>
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>
27#include <linux/regmap.h> 26#include <linux/regmap.h>
28#include <linux/slab.h> 27#include <linux/slab.h>
29#include <sound/core.h> 28#include <sound/core.h>
@@ -51,7 +50,7 @@ static const struct reg_default tlv320aic23_reg[] = {
51 { 9, 0x0000 }, 50 { 9, 0x0000 },
52}; 51};
53 52
54static const struct regmap_config tlv320aic23_regmap = { 53const struct regmap_config tlv320aic23_regmap = {
55 .reg_bits = 7, 54 .reg_bits = 7,
56 .val_bits = 9, 55 .val_bits = 9,
57 56
@@ -557,7 +556,7 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
557 return 0; 556 return 0;
558} 557}
559 558
560static int tlv320aic23_probe(struct snd_soc_codec *codec) 559static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
561{ 560{
562 int ret; 561 int ret;
563 562
@@ -604,7 +603,7 @@ static int tlv320aic23_remove(struct snd_soc_codec *codec)
604} 603}
605 604
606static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { 605static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
607 .probe = tlv320aic23_probe, 606 .probe = tlv320aic23_codec_probe,
608 .remove = tlv320aic23_remove, 607 .remove = tlv320aic23_remove,
609 .suspend = tlv320aic23_suspend, 608 .suspend = tlv320aic23_suspend,
610 .resume = tlv320aic23_resume, 609 .resume = tlv320aic23_resume,
@@ -617,57 +616,25 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
617 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), 616 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
618}; 617};
619 618
620/* 619int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
621 * If the i2c layer weren't so broken, we could pass this kind of data
622 * around
623 */
624static int tlv320aic23_codec_probe(struct i2c_client *i2c,
625 const struct i2c_device_id *i2c_id)
626{ 620{
627 struct aic23 *aic23; 621 struct aic23 *aic23;
628 int ret;
629 622
630 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 623 if (IS_ERR(regmap))
631 return -EINVAL; 624 return PTR_ERR(regmap);
632 625
633 aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL); 626 aic23 = devm_kzalloc(dev, sizeof(struct aic23), GFP_KERNEL);
634 if (aic23 == NULL) 627 if (aic23 == NULL)
635 return -ENOMEM; 628 return -ENOMEM;
636 629
637 aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap); 630 aic23->regmap = regmap;
638 if (IS_ERR(aic23->regmap))
639 return PTR_ERR(aic23->regmap);
640 631
641 i2c_set_clientdata(i2c, aic23); 632 dev_set_drvdata(dev, aic23);
642 633
643 ret = snd_soc_register_codec(&i2c->dev, 634 return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
644 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1); 635 &tlv320aic23_dai, 1);
645 return ret;
646}
647static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
648{
649 snd_soc_unregister_codec(&i2c->dev);
650 return 0;
651} 636}
652 637
653static const struct i2c_device_id tlv320aic23_id[] = {
654 {"tlv320aic23", 0},
655 {}
656};
657
658MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
659
660static struct i2c_driver tlv320aic23_i2c_driver = {
661 .driver = {
662 .name = "tlv320aic23-codec",
663 },
664 .probe = tlv320aic23_codec_probe,
665 .remove = __exit_p(tlv320aic23_i2c_remove),
666 .id_table = tlv320aic23_id,
667};
668
669module_i2c_driver(tlv320aic23_i2c_driver);
670
671MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); 638MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
672MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); 639MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
673MODULE_LICENSE("GPL"); 640MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
index e804120bd3da..3a7235a04a89 100644
--- a/sound/soc/codecs/tlv320aic23.h
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -12,6 +12,12 @@
12#ifndef _TLV320AIC23_H 12#ifndef _TLV320AIC23_H
13#define _TLV320AIC23_H 13#define _TLV320AIC23_H
14 14
15struct device;
16struct regmap_config;
17
18extern const struct regmap_config tlv320aic23_regmap;
19int tlv320aic23_probe(struct device *dev, struct regmap *regmap);
20
15/* Codec TLV320AIC23 */ 21/* Codec TLV320AIC23 */
16#define TLV320AIC23_LINVOL 0x00 22#define TLV320AIC23_LINVOL 0x00
17#define TLV320AIC23_RINVOL 0x01 23#define TLV320AIC23_RINVOL 0x01