[alsa-devel] [PATCH RFC 0/7] ASoC: tlv320aic26: Add device tree support and bug fixes
Hi,
This is my first patch so I'm including the RFC to help identify if I've missed something.
The following patches were created to get the tlv320aic26 working on our AM335x SoM.
This patch series relies on commit 93d0ad8f374c "ASoC: tlv320aic26: Convert to params_width()" for proper operation.
Thanks -Jonathan
Cormier, Jonathan (7): ASoC: tlv320aic26: Add device tree binding ASoC: tlv320aic26: Fix module autoload ASoC: tlv320aic26: Make SND_SOC_TLV320AIC26 user-visible ASoC: tlv320aic26: Fix regmap by setting reg_defaults and reg_stride ASoC: tlv320aic26: hw_params was unintentionally clearing AIC26 master mode ASoC: tlv320aic26: Add support for DSP_B data format ASoC: tlv320aic26: Change Capture Mute to Capture Switch to match alsa documentation.
.../devicetree/bindings/sound/tlv320aic26.txt | 65 ++++++++++++++++++++++ sound/soc/codecs/Kconfig | 2 +- sound/soc/codecs/tlv320aic26.c | 60 ++++++++++++++++++-- 3 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic26.txt
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- .../devicetree/bindings/sound/tlv320aic26.txt | 65 ++++++++++++++++++++++ sound/soc/codecs/tlv320aic26.c | 10 ++++ 2 files changed, 75 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic26.txt
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic26.txt b/Documentation/devicetree/bindings/sound/tlv320aic26.txt new file mode 100644 index 000000000000..93aa0f76ec0d --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tlv320aic26.txt @@ -0,0 +1,65 @@ +Texas Instruments - tlv320aic26 Codec module + +The tlv320aic26 serial control bus communicates through I2C protocols + +Required properties: + +- compatible - "string" - One of: + "ti,tlv320aic26" - TLV320AIC26 +- reg - <int> - SPI chip select + +CODEC input pins: + * MICIN + * AUX + +CODEC output pins: + * HPL + * HPR + +The pins can be used in referring sound node's audio-routing property. + +Example: + +tlv320aic26: tlv320aic26@0 { + compatible = "ti,tlv320aic26"; + reg = <0>; +}; + +&spi0 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi0_pins>; + pinctrl-1 = <&spi0_sleep_pins>; + + status = "okay"; + ti,pindir-d0-out-d1-in = <1>; + + tlv320aic26: tlv320aic26@1 { + compatible = "ti,tlv320aic26"; + reg = <0x1>; + status = "okay"; + + spi-max-frequency = <2000000>; + spi-cpha; + }; +}; + +sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "AM335x_SND"; + simple-audio-card,format = "dsp_b"; + /* SND_SOC_DAIFMT_CBM_CFM */ + simple-audio-card,bitclock-master = <&tlv320aic26_codec>; + simple-audio-card,frame-master = <&tlv320aic26_codec>; + /* SND_SOC_DAIFMT_IB_NF */ + simple-audio-card,bitclock-inversion; + + simple-audio-card,cpu { + sound-dai = <&mcasp1>; + system-clock-frequency = <24576000>; + }; + + tlv320aic26_codec: simple-audio-card,codec { + sound-dai = <&tlv320aic26>; + system-clock-frequency = <24576000>; + }; +}; diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 620ab9ea1ef0..91fdd96648bd 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -370,10 +370,20 @@ static int aic26_spi_remove(struct spi_device *spi) return 0; }
+#if defined(CONFIG_OF) +static const struct of_device_id tlv320aic26_of_match[] = { + { .compatible = "ti,tlv320aic26", }, + {}, +}; +#endif + static struct spi_driver aic26_spi = { .driver = { .name = "tlv320aic26-codec", .owner = THIS_MODULE, +#if defined(CONFIG_OF) + .of_match_table = of_match_ptr(tlv320aic26_of_match), +#endif }, .probe = aic26_spi_probe, .remove = aic26_spi_remove,
On 09/18/2015 11:11 PM, Cormier, Jonathan wrote:
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 620ab9ea1ef0..91fdd96648bd 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -370,10 +370,20 @@ static int aic26_spi_remove(struct spi_device *spi) return 0; }
+#if defined(CONFIG_OF)
You don't need the #ifdef here
+static const struct of_device_id tlv320aic26_of_match[] = {
- { .compatible = "ti,tlv320aic26", },
- {},
+}; +#endif
static struct spi_driver aic26_spi = { .driver = { .name = "tlv320aic26-codec", .owner = THIS_MODULE, +#if defined(CONFIG_OF)
neither here.
.of_match_table = of_match_ptr(tlv320aic26_of_match),
+#endif }, .probe = aic26_spi_probe, .remove = aic26_spi_remove,
On Mon, Sep 21, 2015 at 4:38 AM, Peter Ujfalusi peter.ujfalusi@ti.com wrote:
On 09/18/2015 11:11 PM, Cormier, Jonathan wrote:
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 620ab9ea1ef0..91fdd96648bd 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -370,10 +370,20 @@ static int aic26_spi_remove(struct spi_device *spi) return 0; }
+#if defined(CONFIG_OF)
You don't need the #ifdef here
+static const struct of_device_id tlv320aic26_of_match[] = {
{ .compatible = "ti,tlv320aic26", },
{},
+}; +#endif
static struct spi_driver aic26_spi = { .driver = { .name = "tlv320aic26-codec", .owner = THIS_MODULE, +#if defined(CONFIG_OF)
neither here.
.of_match_table = of_match_ptr(tlv320aic26_of_match),
+#endif }, .probe = aic26_spi_probe, .remove = aic26_spi_remove,
-- Péter
Ok thanks.
Add the missing MODULE_DEVICE_TABLE() for OF and SPI to export the information so modules have the correct aliases built-in and autoloading works correctly.
A longer explanation by Javier Canillas can be found here: https://lkml.org/lkml/2015/7/30/519 https://lkml.org/lkml/2014/9/11/458
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 91fdd96648bd..91347727cfae 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -370,11 +370,18 @@ static int aic26_spi_remove(struct spi_device *spi) return 0; }
+static const struct spi_device_id tlv320aic26_id_table[] = { + { "tlv320aic26" }, + {}, +}; +MODULE_DEVICE_TABLE(spi, tlv320aic26_id_table); + #if defined(CONFIG_OF) static const struct of_device_id tlv320aic26_of_match[] = { { .compatible = "ti,tlv320aic26", }, {}, }; +MODULE_DEVICE_TABLE(of, tlv320aic26_of_match); #endif
static struct spi_driver aic26_spi = { @@ -387,6 +394,7 @@ static struct spi_driver aic26_spi = { }, .probe = aic26_spi_probe, .remove = aic26_spi_remove, + .id_table = tlv320aic26_id_table, };
module_spi_driver(aic26_spi);
Allow SND_SOC_TLV320AIC26 to be built.
Based on commit: http://mailman.alsa-project.org/pipermail/alsa-devel/2008-October/011287.htm...
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index efaafce8ba38..a70b5a00dc5e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -640,7 +640,7 @@ config SND_SOC_TLV320AIC23_SPI select SND_SOC_TLV320AIC23
config SND_SOC_TLV320AIC26 - tristate + tristate "Texas Instruments TLV320AIC26 Codec support" depends on SPI
config SND_SOC_TLV320AIC31XX
tlv320aic26 codec wasn't being setup correctly on bootup due to misconfigured regmap cache.
Fixes: b7e9f3973279 "ASoC: tlv320aic26: Convert to direct regmap API usage" Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 91347727cfae..70af361a116c 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -41,6 +41,27 @@ struct aic26 { int keyclick_len; };
+static const struct reg_default aic26_reg[] = { + /* Page 0 */ + { 0x00A0, 0x0000 }, { 0x00C0, 0x0000 }, { 0x00E0, 0x0000 }, + { 0x0120, 0x0000 }, { 0x0140, 0x0000 }, + /* Page 1 */ + { 0x0800, 0x0000 }, { 0x0820, 0x8000 }, { 0x0860, 0x0002 }, + { 0x0880, 0xFFFF }, + /* Page 2 */ + { 0x1000, 0x0000 }, { 0x1020, 0x8000 }, { 0x1040, 0xFFFF }, + { 0x1060, 0xC580 }, { 0x1080, 0x4410 }, { 0x10A0, 0xAFC0 }, + { 0x10C0, 0x0000 }, { 0x10E0, 27619 }, { 0x1100, -27034 }, + { 0x1120, 26461 }, { 0x1140, 27619 }, { 0x1160, -27034 }, + { 0x1180, 26461 }, { 0x11A0, 32131 }, { 0x11C0, -31506 }, + { 0x11E0, 32131 }, { 0x1200, -31506 }, { 0x1220, 27619 }, + { 0x1240, -27034 }, { 0x1260, 26461 }, { 0x1280, 27619 }, + { 0x12A0, -27034 }, { 0x12C0, 26461 }, { 0x12E0, 32131 }, + { 0x1300, -31506 }, { 0x1320, 32131 }, { 0x1340, -31506 }, + { 0x1360, 0x1004 }, { 0x1380, 0x0000 }, { 0x13A0, 0x0000 }, + { 0x13C0, 0xFE00 }, +}; + static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = { SND_SOC_DAPM_INPUT("MICIN"), SND_SOC_DAPM_INPUT("AUX"), @@ -332,6 +353,13 @@ static struct snd_soc_codec_driver aic26_soc_codec_dev = { static const struct regmap_config aic26_regmap = { .reg_bits = 16, .val_bits = 16, + /* AIC26_PAGE_ADDR(0, 0x01) */ + .reg_stride = 0x20, + + .max_register = AIC26_REG_AUDIO_CTRL5, + .reg_defaults = aic26_reg, + .num_reg_defaults = ARRAY_SIZE(aic26_reg), + .cache_type = REGCACHE_RBTREE, };
/* ---------------------------------------------------------------------
Commit: 5b0959d472c2 "ASoC: tlv320aic26: Use snd_soc_update_bits()" broke setting AIC26_REG_AUDIO_CTRL3 in master mode when fsref happens to be 48000. The master mode bit was getting cleared.
Also fix setting AIC26_REG_DAC_GAIN and AIC26_REG_AUDIO_CTRL2 which was broke by same commit.
Fixes: 5b0959d472c2 "ASoC: tlv320aic26: Use snd_soc_update_bits()" Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 70af361a116c..c3b0a698ea66 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -138,11 +138,12 @@ static int aic26_hw_params(struct snd_pcm_substream *substream, snd_soc_write(codec, AIC26_REG_PLL_PROG2, reg);
/* Audio Control 3 (master mode, fsref rate) */ + reg = 0; if (aic26->master) - reg = 0x0800; + reg |= 0x0800; if (fsref == 48000) - reg = 0x2000; - snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL3, 0xf800, reg); + reg |= 0x2000; + snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL3, 0x2800, reg);
/* Audio Control 1 (FSref divisor) */ reg = wlen | aic26->datfm | (divisor << 3) | divisor; @@ -167,7 +168,7 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute) reg = 0x8080; else reg = 0; - snd_soc_update_bits(codec, AIC26_REG_DAC_GAIN, 0x8000, reg); + snd_soc_update_bits(codec, AIC26_REG_DAC_GAIN, 0x8080, reg);
return 0; } @@ -302,7 +303,7 @@ static ssize_t aic26_keyclick_set(struct device *dev, struct aic26 *aic26 = dev_get_drvdata(dev);
snd_soc_update_bits(aic26->codec, AIC26_REG_AUDIO_CTRL2, - 0x8000, 0x800); + 0x8000, 0x8000);
return count; }
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index c3b0a698ea66..5c5641cd28de 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -211,6 +211,7 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break; case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break; + case SND_SOC_DAIFMT_DSP_B: aic26->datfm = AIC26_DATFM_DSP; break; case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break; case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break; default:
On 09/18/2015 11:11 PM, Cormier, Jonathan wrote:
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com
sound/soc/codecs/tlv320aic26.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index c3b0a698ea66..5c5641cd28de 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -211,6 +211,7 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break; case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break;
- case SND_SOC_DAIFMT_DSP_B: aic26->datfm = AIC26_DATFM_DSP; break;
Are you sure about this? According to the datasheet: www.ti.com/litv/slas412 page 18 there is no bit to change the data delay and the format the codec supports is DSP_A.
case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break; case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break; default:
On Mon, Sep 21, 2015 at 2:19 AM, Peter Ujfalusi peter.ujfalusi@ti.com wrote:
On 09/18/2015 11:11 PM, Cormier, Jonathan wrote:
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com
sound/soc/codecs/tlv320aic26.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index c3b0a698ea66..5c5641cd28de 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -211,6 +211,7 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break; case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break;
case SND_SOC_DAIFMT_DSP_B: aic26->datfm = AIC26_DATFM_DSP; break;
Are you sure about this? According to the datasheet: www.ti.com/litv/slas412 page 18 there is no bit to change the data delay and the format the codec supports is DSP_A.
I went with DSP_B because thats what the 335x EVM had set and when comparing the tlv320aic26 datasheet to the tlv320aic32 for the DSP mode it seemed to match. I had been getting garbled audio playback when I tested with DSP_A but I just retested to be sure and now DSP_A appears to work just the same as DSP_B. So I suggest we drop this patch.
case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break; case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break; default:
-- Péter
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 5c5641cd28de..1d60199740f1 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -270,7 +270,7 @@ static const struct snd_kcontrol_new aic26_snd_controls[] = { SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1), SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1), SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0), - SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1), + SOC_SINGLE("PCM Capture Switch", AIC26_REG_ADC_GAIN, 15, 1, 1), SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0), SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0), SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
Hi,
The following patches were created to get the tlv320aic26 working on our AM335x SoM.
This patch series relies on commit 93d0ad8f374c "ASoC: tlv320aic26: Convert to params_width()" for proper operation.
Changes since RFC: - Removed the unecessary "#if defined(CONFIG_OF)" - Dropped the DSP_B patch
Thanks -Jonathan
Cormier, Jonathan (6): ASoC: tlv320aic26: Add device tree binding ASoC: tlv320aic26: Fix module autoload ASoC: tlv320aic26: Make SND_SOC_TLV320AIC26 user-visible ASoC: tlv320aic26: Fix regmap by setting reg_defaults and reg_stride ASoC: tlv320aic26: hw_params was unintentionally clearing AIC26 master mode ASoC: tlv320aic26: Change Capture Mute to Capture Switch to match alsa documentation.
.../devicetree/bindings/sound/tlv320aic26.txt | 65 ++++++++++++++++++++++ sound/soc/codecs/Kconfig | 2 +- sound/soc/codecs/tlv320aic26.c | 55 ++++++++++++++++-- 3 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic26.txt
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- .../devicetree/bindings/sound/tlv320aic26.txt | 65 ++++++++++++++++++++++ sound/soc/codecs/tlv320aic26.c | 6 ++ 2 files changed, 71 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic26.txt
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic26.txt b/Documentation/devicetree/bindings/sound/tlv320aic26.txt new file mode 100644 index 000000000000..93aa0f76ec0d --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tlv320aic26.txt @@ -0,0 +1,65 @@ +Texas Instruments - tlv320aic26 Codec module + +The tlv320aic26 serial control bus communicates through I2C protocols + +Required properties: + +- compatible - "string" - One of: + "ti,tlv320aic26" - TLV320AIC26 +- reg - <int> - SPI chip select + +CODEC input pins: + * MICIN + * AUX + +CODEC output pins: + * HPL + * HPR + +The pins can be used in referring sound node's audio-routing property. + +Example: + +tlv320aic26: tlv320aic26@0 { + compatible = "ti,tlv320aic26"; + reg = <0>; +}; + +&spi0 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi0_pins>; + pinctrl-1 = <&spi0_sleep_pins>; + + status = "okay"; + ti,pindir-d0-out-d1-in = <1>; + + tlv320aic26: tlv320aic26@1 { + compatible = "ti,tlv320aic26"; + reg = <0x1>; + status = "okay"; + + spi-max-frequency = <2000000>; + spi-cpha; + }; +}; + +sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "AM335x_SND"; + simple-audio-card,format = "dsp_b"; + /* SND_SOC_DAIFMT_CBM_CFM */ + simple-audio-card,bitclock-master = <&tlv320aic26_codec>; + simple-audio-card,frame-master = <&tlv320aic26_codec>; + /* SND_SOC_DAIFMT_IB_NF */ + simple-audio-card,bitclock-inversion; + + simple-audio-card,cpu { + sound-dai = <&mcasp1>; + system-clock-frequency = <24576000>; + }; + + tlv320aic26_codec: simple-audio-card,codec { + sound-dai = <&tlv320aic26>; + system-clock-frequency = <24576000>; + }; +}; diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 620ab9ea1ef0..65c2bfb02e76 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -370,10 +370,16 @@ static int aic26_spi_remove(struct spi_device *spi) return 0; }
+static const struct of_device_id tlv320aic26_of_match[] = { + { .compatible = "ti,tlv320aic26", }, + {}, +}; + static struct spi_driver aic26_spi = { .driver = { .name = "tlv320aic26-codec", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(tlv320aic26_of_match), }, .probe = aic26_spi_probe, .remove = aic26_spi_remove,
Add the missing MODULE_DEVICE_TABLE() for OF and SPI to export the information so modules have the correct aliases built-in and autoloading works correctly.
A longer explanation by Javier Canillas can be found here: https://lkml.org/lkml/2015/7/30/519 https://lkml.org/lkml/2014/9/11/458
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 65c2bfb02e76..bf3a9ec40e1e 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -370,10 +370,17 @@ static int aic26_spi_remove(struct spi_device *spi) return 0; }
+static const struct spi_device_id tlv320aic26_id_table[] = { + { "tlv320aic26" }, + {}, +}; +MODULE_DEVICE_TABLE(spi, tlv320aic26_id_table); + static const struct of_device_id tlv320aic26_of_match[] = { { .compatible = "ti,tlv320aic26", }, {}, }; +MODULE_DEVICE_TABLE(of, tlv320aic26_of_match);
static struct spi_driver aic26_spi = { .driver = { @@ -383,6 +390,7 @@ static struct spi_driver aic26_spi = { }, .probe = aic26_spi_probe, .remove = aic26_spi_remove, + .id_table = tlv320aic26_id_table, };
module_spi_driver(aic26_spi);
Allow SND_SOC_TLV320AIC26 to be built.
Based on commit: http://mailman.alsa-project.org/pipermail/alsa-devel/2008-October/011287.htm...
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index efaafce8ba38..a70b5a00dc5e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -640,7 +640,7 @@ config SND_SOC_TLV320AIC23_SPI select SND_SOC_TLV320AIC23
config SND_SOC_TLV320AIC26 - tristate + tristate "Texas Instruments TLV320AIC26 Codec support" depends on SPI
config SND_SOC_TLV320AIC31XX
tlv320aic26 codec wasn't being setup correctly on bootup due to misconfigured regmap cache.
Fixes: b7e9f3973279 "ASoC: tlv320aic26: Convert to direct regmap API usage" Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index bf3a9ec40e1e..8355f379d45d 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -41,6 +41,27 @@ struct aic26 { int keyclick_len; };
+static const struct reg_default aic26_reg[] = { + /* Page 0 */ + { 0x00A0, 0x0000 }, { 0x00C0, 0x0000 }, { 0x00E0, 0x0000 }, + { 0x0120, 0x0000 }, { 0x0140, 0x0000 }, + /* Page 1 */ + { 0x0800, 0x0000 }, { 0x0820, 0x8000 }, { 0x0860, 0x0002 }, + { 0x0880, 0xFFFF }, + /* Page 2 */ + { 0x1000, 0x0000 }, { 0x1020, 0x8000 }, { 0x1040, 0xFFFF }, + { 0x1060, 0xC580 }, { 0x1080, 0x4410 }, { 0x10A0, 0xAFC0 }, + { 0x10C0, 0x0000 }, { 0x10E0, 27619 }, { 0x1100, -27034 }, + { 0x1120, 26461 }, { 0x1140, 27619 }, { 0x1160, -27034 }, + { 0x1180, 26461 }, { 0x11A0, 32131 }, { 0x11C0, -31506 }, + { 0x11E0, 32131 }, { 0x1200, -31506 }, { 0x1220, 27619 }, + { 0x1240, -27034 }, { 0x1260, 26461 }, { 0x1280, 27619 }, + { 0x12A0, -27034 }, { 0x12C0, 26461 }, { 0x12E0, 32131 }, + { 0x1300, -31506 }, { 0x1320, 32131 }, { 0x1340, -31506 }, + { 0x1360, 0x1004 }, { 0x1380, 0x0000 }, { 0x13A0, 0x0000 }, + { 0x13C0, 0xFE00 }, +}; + static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = { SND_SOC_DAPM_INPUT("MICIN"), SND_SOC_DAPM_INPUT("AUX"), @@ -332,6 +353,13 @@ static struct snd_soc_codec_driver aic26_soc_codec_dev = { static const struct regmap_config aic26_regmap = { .reg_bits = 16, .val_bits = 16, + /* AIC26_PAGE_ADDR(0, 0x01) */ + .reg_stride = 0x20, + + .max_register = AIC26_REG_AUDIO_CTRL5, + .reg_defaults = aic26_reg, + .num_reg_defaults = ARRAY_SIZE(aic26_reg), + .cache_type = REGCACHE_RBTREE, };
/* ---------------------------------------------------------------------
Commit: 5b0959d472c2 "ASoC: tlv320aic26: Use snd_soc_update_bits()" broke setting AIC26_REG_AUDIO_CTRL3 in master mode when fsref happens to be 48000. The master mode bit was getting cleared.
Also fix setting AIC26_REG_DAC_GAIN and AIC26_REG_AUDIO_CTRL2 which was broke by same commit.
Fixes: 5b0959d472c2 "ASoC: tlv320aic26: Use snd_soc_update_bits()" Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 8355f379d45d..7d2fbca068d0 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -138,11 +138,12 @@ static int aic26_hw_params(struct snd_pcm_substream *substream, snd_soc_write(codec, AIC26_REG_PLL_PROG2, reg);
/* Audio Control 3 (master mode, fsref rate) */ + reg = 0; if (aic26->master) - reg = 0x0800; + reg |= 0x0800; if (fsref == 48000) - reg = 0x2000; - snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL3, 0xf800, reg); + reg |= 0x2000; + snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL3, 0x2800, reg);
/* Audio Control 1 (FSref divisor) */ reg = wlen | aic26->datfm | (divisor << 3) | divisor; @@ -167,7 +168,7 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute) reg = 0x8080; else reg = 0; - snd_soc_update_bits(codec, AIC26_REG_DAC_GAIN, 0x8000, reg); + snd_soc_update_bits(codec, AIC26_REG_DAC_GAIN, 0x8080, reg);
return 0; } @@ -302,7 +303,7 @@ static ssize_t aic26_keyclick_set(struct device *dev, struct aic26 *aic26 = dev_get_drvdata(dev);
snd_soc_update_bits(aic26->codec, AIC26_REG_AUDIO_CTRL2, - 0x8000, 0x800); + 0x8000, 0x8000);
return count; }
Signed-off-by: Cormier, Jonathan jcormier@criticallink.com --- sound/soc/codecs/tlv320aic26.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 7d2fbca068d0..f7629b17ee5b 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -269,7 +269,7 @@ static const struct snd_kcontrol_new aic26_snd_controls[] = { SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1), SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1), SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0), - SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1), + SOC_SINGLE("PCM Capture Switch", AIC26_REG_ADC_GAIN, 15, 1, 1), SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0), SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0), SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
On 09/25/2015 09:30 PM, Cormier, Jonathan wrote:
Hi,
The following patches were created to get the tlv320aic26 working on our AM335x SoM.
This patch series relies on commit 93d0ad8f374c "ASoC: tlv320aic26: Convert to params_width()" for proper operation.
Changes since RFC:
- Removed the unecessary "#if defined(CONFIG_OF)"
- Dropped the DSP_B patch
All: Reviewed-by: Peter Ujfalusi peter.ujfalusi@ti.com
Thanks -Jonathan
Cormier, Jonathan (6): ASoC: tlv320aic26: Add device tree binding ASoC: tlv320aic26: Fix module autoload ASoC: tlv320aic26: Make SND_SOC_TLV320AIC26 user-visible ASoC: tlv320aic26: Fix regmap by setting reg_defaults and reg_stride ASoC: tlv320aic26: hw_params was unintentionally clearing AIC26 master mode ASoC: tlv320aic26: Change Capture Mute to Capture Switch to match alsa documentation.
.../devicetree/bindings/sound/tlv320aic26.txt | 65 ++++++++++++++++++++++ sound/soc/codecs/Kconfig | 2 +- sound/soc/codecs/tlv320aic26.c | 55 ++++++++++++++++-- 3 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic26.txt
participants (3)
-
Cormier, Jonathan
-
Jon Cormier
-
Peter Ujfalusi