Commit 01954a7b authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/cs4265', 'asoc/topic/cs42l56',...

Merge remote-tracking branches 'asoc/topic/cs4265', 'asoc/topic/cs42l56', 'asoc/topic/cs42xx8', 'asoc/topic/cx20442' and 'asoc/topic/davinci' into asoc-next
CS4265 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "cirrus,cs4265"
- reg : the I2C address of the device for I2C. The I2C address depends on
the state of the AD0 pin. If AD0 is high, the i2c address is 0x4f.
If it is low, the i2c address is 0x4e.
Optional properties:
- reset-gpios : a GPIO spec for the reset pin. If specified, it will be
deasserted before communication to the codec starts.
Examples:
codec_ad0_high: cs4265@4f { /* AD0 Pin is high */
compatible = "cirrus,cs4265";
reg = <0x4f>;
};
codec_ad0_low: cs4265@4e { /* AD0 Pin is low */
compatible = "cirrus,cs4265";
reg = <0x4e>;
};
...@@ -47,6 +47,7 @@ config SND_SOC_ALL_CODECS ...@@ -47,6 +47,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS42L52 if I2C && INPUT select SND_SOC_CS42L52 if I2C && INPUT
select SND_SOC_CS42L56 if I2C && INPUT select SND_SOC_CS42L56 if I2C && INPUT
select SND_SOC_CS42L73 if I2C select SND_SOC_CS42L73 if I2C
select SND_SOC_CS4265 if I2C
select SND_SOC_CS4270 if I2C select SND_SOC_CS4270 if I2C
select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
select SND_SOC_CS42XX8_I2C if I2C select SND_SOC_CS42XX8_I2C if I2C
...@@ -338,6 +339,11 @@ config SND_SOC_CS42L73 ...@@ -338,6 +339,11 @@ config SND_SOC_CS42L73
tristate "Cirrus Logic CS42L73 CODEC" tristate "Cirrus Logic CS42L73 CODEC"
depends on I2C depends on I2C
config SND_SOC_CS4265
tristate "Cirrus Logic CS4265 CODEC"
depends on I2C
select REGMAP_I2C
# Cirrus Logic CS4270 Codec # Cirrus Logic CS4270 Codec
config SND_SOC_CS4270 config SND_SOC_CS4270
tristate "Cirrus Logic CS4270 CODEC" tristate "Cirrus Logic CS4270 CODEC"
......
...@@ -37,6 +37,7 @@ snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o ...@@ -37,6 +37,7 @@ snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
snd-soc-cs42l52-objs := cs42l52.o snd-soc-cs42l52-objs := cs42l52.o
snd-soc-cs42l56-objs := cs42l56.o snd-soc-cs42l56-objs := cs42l56.o
snd-soc-cs42l73-objs := cs42l73.o snd-soc-cs42l73-objs := cs42l73.o
snd-soc-cs4265-objs := cs4265.o
snd-soc-cs4270-objs := cs4270.o snd-soc-cs4270-objs := cs4270.o
snd-soc-cs4271-objs := cs4271.o snd-soc-cs4271-objs := cs4271.o
snd-soc-cs42xx8-objs := cs42xx8.o snd-soc-cs42xx8-objs := cs42xx8.o
...@@ -204,6 +205,7 @@ obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o ...@@ -204,6 +205,7 @@ obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
obj-$(CONFIG_SND_SOC_CS42L56) += snd-soc-cs42l56.o obj-$(CONFIG_SND_SOC_CS42L56) += snd-soc-cs42l56.o
obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
obj-$(CONFIG_SND_SOC_CS4265) += snd-soc-cs4265.o
obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
......
This diff is collapsed.
/*
* cs4265.h -- CS4265 ALSA SoC audio driver
*
* Copyright 2014 Cirrus Logic, Inc.
*
* Author: Paul Handrigan <paul.handrigan@cirrus.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#ifndef __CS4265_H__
#define __CS4265_H__
#define CS4265_CHIP_ID 0x1
#define CS4265_CHIP_ID_VAL 0xD0
#define CS4265_CHIP_ID_MASK 0xF0
#define CS4265_REV_ID_MASK 0x0F
#define CS4265_PWRCTL 0x02
#define CS4265_PWRCTL_PDN 1
#define CS4265_DAC_CTL 0x3
#define CS4265_DAC_CTL_MUTE (1 << 2)
#define CS4265_DAC_CTL_DIF (3 << 4)
#define CS4265_ADC_CTL 0x4
#define CS4265_ADC_MASTER 1
#define CS4265_ADC_DIF (1 << 4)
#define CS4265_ADC_FM (3 << 6)
#define CS4265_MCLK_FREQ 0x5
#define CS4265_MCLK_FREQ_MASK (7 << 4)
#define CS4265_SIG_SEL 0x6
#define CS4265_SIG_SEL_LOOP (1 << 1)
#define CS4265_CHB_PGA_CTL 0x7
#define CS4265_CHA_PGA_CTL 0x8
#define CS4265_ADC_CTL2 0x9
#define CS4265_DAC_CHA_VOL 0xA
#define CS4265_DAC_CHB_VOL 0xB
#define CS4265_DAC_CTL2 0xC
#define CS4265_INT_STATUS 0xD
#define CS4265_INT_MASK 0xE
#define CS4265_STATUS_MODE_MSB 0xF
#define CS4265_STATUS_MODE_LSB 0x10
#define CS4265_SPDIF_CTL1 0x11
#define CS4265_SPDIF_CTL2 0x12
#define CS4265_SPDIF_CTL2_MUTE (1 << 4)
#define CS4265_SPDIF_CTL2_DIF (3 << 6)
#define CS4265_C_DATA_BUFF 0x13
#define CS4265_MAX_REGISTER 0x2A
#endif
...@@ -318,24 +318,32 @@ static const struct soc_enum adca_swap_enum = ...@@ -318,24 +318,32 @@ static const struct soc_enum adca_swap_enum =
ARRAY_SIZE(left_swap_text), ARRAY_SIZE(left_swap_text),
left_swap_text, left_swap_text,
swap_values); swap_values);
static const struct snd_kcontrol_new adca_swap_mux =
SOC_DAPM_ENUM("Route", adca_swap_enum);
static const struct soc_enum pcma_swap_enum = static const struct soc_enum pcma_swap_enum =
SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3, SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3,
ARRAY_SIZE(left_swap_text), ARRAY_SIZE(left_swap_text),
left_swap_text, left_swap_text,
swap_values); swap_values);
static const struct snd_kcontrol_new pcma_swap_mux =
SOC_DAPM_ENUM("Route", pcma_swap_enum);
static const struct soc_enum adcb_swap_enum = static const struct soc_enum adcb_swap_enum =
SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3, SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3,
ARRAY_SIZE(right_swap_text), ARRAY_SIZE(right_swap_text),
right_swap_text, right_swap_text,
swap_values); swap_values);
static const struct snd_kcontrol_new adcb_swap_mux =
SOC_DAPM_ENUM("Route", adcb_swap_enum);
static const struct soc_enum pcmb_swap_enum = static const struct soc_enum pcmb_swap_enum =
SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3, SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3,
ARRAY_SIZE(right_swap_text), ARRAY_SIZE(right_swap_text),
right_swap_text, right_swap_text,
swap_values); swap_values);
static const struct snd_kcontrol_new pcmb_swap_mux =
SOC_DAPM_ENUM("Route", pcmb_swap_enum);
static const struct snd_kcontrol_new hpa_switch = static const struct snd_kcontrol_new hpa_switch =
SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1); SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1);
...@@ -467,11 +475,6 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = { ...@@ -467,11 +475,6 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1), SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1),
SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1), SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1),
SOC_ENUM("PCMA Swap", pcma_swap_enum),
SOC_ENUM("PCMB Swap", pcmb_swap_enum),
SOC_ENUM("ADCA Swap", adca_swap_enum),
SOC_ENUM("ADCB Swap", adcb_swap_enum),
SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1), SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1),
SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1), SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1),
SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum), SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum),
...@@ -570,6 +573,16 @@ static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = { ...@@ -570,6 +573,16 @@ static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = {
SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1), SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1),
SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1), SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1),
SND_SOC_DAPM_MUX("ADCA Swap Mux", SND_SOC_NOPM, 0, 0,
&adca_swap_mux),
SND_SOC_DAPM_MUX("ADCB Swap Mux", SND_SOC_NOPM, 0, 0,
&adcb_swap_mux),
SND_SOC_DAPM_MUX("PCMA Swap Mux", SND_SOC_NOPM, 0, 0,
&pcma_swap_mux),
SND_SOC_DAPM_MUX("PCMB Swap Mux", SND_SOC_NOPM, 0, 0,
&pcmb_swap_mux),
SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0),
...@@ -607,8 +620,19 @@ static const struct snd_soc_dapm_route cs42l56_audio_map[] = { ...@@ -607,8 +620,19 @@ static const struct snd_soc_dapm_route cs42l56_audio_map[] = {
{"Digital Output Mux", NULL, "ADCA"}, {"Digital Output Mux", NULL, "ADCA"},
{"Digital Output Mux", NULL, "ADCB"}, {"Digital Output Mux", NULL, "ADCB"},
{"ADCB", NULL, "ADCB Mux"}, {"ADCB", NULL, "ADCB Swap Mux"},
{"ADCA", NULL, "ADCA Mux"}, {"ADCA", NULL, "ADCA Swap Mux"},
{"ADCA Swap Mux", NULL, "ADCA"},
{"ADCB Swap Mux", NULL, "ADCB"},
{"DACA", "Left", "ADCA Swap Mux"},
{"DACA", "LR 2", "ADCA Swap Mux"},
{"DACA", "Right", "ADCA Swap Mux"},
{"DACB", "Left", "ADCB Swap Mux"},
{"DACB", "LR 2", "ADCB Swap Mux"},
{"DACB", "Right", "ADCB Swap Mux"},
{"ADCA Mux", NULL, "AIN3A"}, {"ADCA Mux", NULL, "AIN3A"},
{"ADCA Mux", NULL, "AIN2A"}, {"ADCA Mux", NULL, "AIN2A"},
...@@ -633,30 +657,32 @@ static const struct snd_soc_dapm_route cs42l56_audio_map[] = { ...@@ -633,30 +657,32 @@ static const struct snd_soc_dapm_route cs42l56_audio_map[] = {
{"PGAB Input Mux", NULL, "AIN2B"}, {"PGAB Input Mux", NULL, "AIN2B"},
{"PGAB Input Mux", NULL, "AIN3B"}, {"PGAB Input Mux", NULL, "AIN3B"},
{"LOB", NULL, "Lineout Right"}, {"LOB", "Switch", "LINEOUTB Input Mux"},
{"LOA", NULL, "Lineout Left"}, {"LOA", "Switch", "LINEOUTA Input Mux"},
{"Lineout Right", "Switch", "LINEOUTB Input Mux"},
{"Lineout Left", "Switch", "LINEOUTA Input Mux"},
{"LINEOUTA Input Mux", "PGAA", "PGAA"}, {"LINEOUTA Input Mux", "PGAA", "PGAA"},
{"LINEOUTB Input Mux", "PGAB", "PGAB"}, {"LINEOUTB Input Mux", "PGAB", "PGAB"},
{"LINEOUTA Input Mux", "DACA", "DACA"}, {"LINEOUTA Input Mux", "DACA", "DACA"},
{"LINEOUTB Input Mux", "DACB", "DACB"}, {"LINEOUTB Input Mux", "DACB", "DACB"},
{"HPA", NULL, "Headphone Left"}, {"HPA", "Switch", "HPB Input Mux"},
{"HPB", NULL, "Headphone Right"}, {"HPB", "Switch", "HPA Input Mux"},
{"Headphone Right", "Switch", "HPB Input Mux"},
{"Headphone Left", "Switch", "HPA Input Mux"},
{"HPA Input Mux", "PGAA", "PGAA"}, {"HPA Input Mux", "PGAA", "PGAA"},
{"HPB Input Mux", "PGAB", "PGAB"}, {"HPB Input Mux", "PGAB", "PGAB"},
{"HPA Input Mux", "DACA", "DACA"}, {"HPA Input Mux", "DACA", "DACA"},
{"HPB Input Mux", "DACB", "DACB"}, {"HPB Input Mux", "DACB", "DACB"},
{"DACB", NULL, "HiFi Playback"}, {"DACA", NULL, "PCMA Swap Mux"},
{"DACA", NULL, "HiFi Playback"}, {"DACB", NULL, "PCMB Swap Mux"},
{"PCMB Swap Mux", "Left", "HiFi Playback"},
{"PCMB Swap Mux", "LR 2", "HiFi Playback"},
{"PCMB Swap Mux", "Right", "HiFi Playback"},
{"PCMA Swap Mux", "Left", "HiFi Playback"},
{"PCMA Swap Mux", "LR 2", "HiFi Playback"},
{"PCMA Swap Mux", "Right", "HiFi Playback"},
}; };
......
...@@ -219,6 +219,9 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -219,6 +219,9 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_RIGHT_J: case SND_SOC_DAIFMT_RIGHT_J:
val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ; val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ;
break; break;
case SND_SOC_DAIFMT_DSP_A:
val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM;
break;
default: default:
dev_err(codec->dev, "unsupported dai format\n"); dev_err(codec->dev, "unsupported dai format\n");
return -EINVAL; return -EINVAL;
...@@ -422,7 +425,7 @@ const struct cs42xx8_driver_data cs42888_data = { ...@@ -422,7 +425,7 @@ const struct cs42xx8_driver_data cs42888_data = {
}; };
EXPORT_SYMBOL_GPL(cs42888_data); EXPORT_SYMBOL_GPL(cs42888_data);
const struct of_device_id cs42xx8_of_match[] = { static const struct of_device_id cs42xx8_of_match[] = {
{ .compatible = "cirrus,cs42448", .data = &cs42448_data, }, { .compatible = "cirrus,cs42448", .data = &cs42448_data, },
{ .compatible = "cirrus,cs42888", .data = &cs42888_data, }, { .compatible = "cirrus,cs42888", .data = &cs42888_data, },
{ /* sentinel */ } { /* sentinel */ }
......
...@@ -128,8 +128,8 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap); ...@@ -128,8 +128,8 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap);
#define CS42XX8_INTF_DAC_DIF_RIGHTJ (2 << CS42XX8_INTF_DAC_DIF_SHIFT) #define CS42XX8_INTF_DAC_DIF_RIGHTJ (2 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_DAC_DIF_SHIFT) #define CS42XX8_INTF_DAC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_ONELINE_20 (4 << CS42XX8_INTF_DAC_DIF_SHIFT) #define CS42XX8_INTF_DAC_DIF_ONELINE_20 (4 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_ONELINE_24 (6 << CS42XX8_INTF_DAC_DIF_SHIFT) #define CS42XX8_INTF_DAC_DIF_ONELINE_24 (5 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_TDM (7 << CS42XX8_INTF_DAC_DIF_SHIFT) #define CS42XX8_INTF_DAC_DIF_TDM (6 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_SHIFT 0 #define CS42XX8_INTF_ADC_DIF_SHIFT 0
#define CS42XX8_INTF_ADC_DIF_WIDTH 3 #define CS42XX8_INTF_ADC_DIF_WIDTH 3
#define CS42XX8_INTF_ADC_DIF_MASK (((1 << CS42XX8_INTF_ADC_DIF_WIDTH) - 1) << CS42XX8_INTF_ADC_DIF_SHIFT) #define CS42XX8_INTF_ADC_DIF_MASK (((1 << CS42XX8_INTF_ADC_DIF_WIDTH) - 1) << CS42XX8_INTF_ADC_DIF_SHIFT)
...@@ -138,8 +138,8 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap); ...@@ -138,8 +138,8 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap);
#define CS42XX8_INTF_ADC_DIF_RIGHTJ (2 << CS42XX8_INTF_ADC_DIF_SHIFT) #define CS42XX8_INTF_ADC_DIF_RIGHTJ (2 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_ADC_DIF_SHIFT) #define CS42XX8_INTF_ADC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_ONELINE_20 (4 << CS42XX8_INTF_ADC_DIF_SHIFT) #define CS42XX8_INTF_ADC_DIF_ONELINE_20 (4 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_ONELINE_24 (6 << CS42XX8_INTF_ADC_DIF_SHIFT) #define CS42XX8_INTF_ADC_DIF_ONELINE_24 (5 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_TDM (7 << CS42XX8_INTF_ADC_DIF_SHIFT) #define CS42XX8_INTF_ADC_DIF_TDM (6 << CS42XX8_INTF_ADC_DIF_SHIFT)
/* ADC Control & DAC De-Emphasis (Address 05h) */ /* ADC Control & DAC De-Emphasis (Address 05h) */
#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT 7 #define CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT 7
......
...@@ -383,8 +383,8 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) ...@@ -383,8 +383,8 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
if (cx20442->control_data) { if (cx20442->control_data) {
struct tty_struct *tty = cx20442->control_data; struct tty_struct *tty = cx20442->control_data;
tty_hangup(tty); tty_hangup(tty);
} }
if (!IS_ERR(cx20442->por)) { if (!IS_ERR(cx20442->por)) {
......
config SND_DAVINCI_SOC config SND_DAVINCI_SOC
tristate "SoC Audio for TI DAVINCI or AM33XX/AM43XX chips" tristate "SoC Audio for TI DAVINCI"
depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX depends on ARCH_DAVINCI
config SND_EDMA_SOC
tristate "SoC Audio for Texas Instruments chips using eDMA (AM33XX/43XX)"
depends on SOC_AM33XX || SOC_AM43XX
select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y or M here if you want audio support for TI SoC which uses eDMA.
The following line of SoCs are supported by this platform driver:
- AM335x
- AM437x/AM438x
config SND_DAVINCI_SOC_I2S config SND_DAVINCI_SOC_I2S
tristate tristate
config SND_DAVINCI_SOC_MCASP config SND_DAVINCI_SOC_MCASP
depends on SND_DAVINCI_SOC || SND_OMAP_SOC tristate "Multichannel Audio Serial Port (McASP) support"
tristate depends on SND_DAVINCI_SOC || SND_OMAP_SOC || SND_EDMA_SOC
help
Say Y or M here if you want to have support for McASP IP found in
various Texas Instruments SoCs like:
- daVinci devices
- Sitara line of SoCs (AM335x, AM438x, etc)
- DRA7x devices
config SND_DAVINCI_SOC_VCIF config SND_DAVINCI_SOC_VCIF
tristate tristate
...@@ -19,7 +35,7 @@ config SND_DAVINCI_SOC_GENERIC_EVM ...@@ -19,7 +35,7 @@ config SND_DAVINCI_SOC_GENERIC_EVM
config SND_AM33XX_SOC_EVM config SND_AM33XX_SOC_EVM
tristate "SoC Audio for the AM33XX chip based boards" tristate "SoC Audio for the AM33XX chip based boards"
depends on SND_DAVINCI_SOC && SOC_AM33XX && I2C depends on SND_EDMA_SOC && SOC_AM33XX && I2C
select SND_DAVINCI_SOC_GENERIC_EVM select SND_DAVINCI_SOC_GENERIC_EVM
help help
Say Y or M if you want to add support for SoC audio on AM33XX Say Y or M if you want to add support for SoC audio on AM33XX
......
# DAVINCI Platform Support # DAVINCI Platform Support
snd-soc-davinci-objs := davinci-pcm.o snd-soc-davinci-objs := davinci-pcm.o
snd-soc-edma-objs := edma-pcm.o
snd-soc-davinci-i2s-objs := davinci-i2s.o snd-soc-davinci-i2s-objs := davinci-i2s.o
snd-soc-davinci-mcasp-objs:= davinci-mcasp.o snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
snd-soc-davinci-vcif-objs:= davinci-vcif.o snd-soc-davinci-vcif-objs:= davinci-vcif.o
obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
obj-$(CONFIG_SND_EDMA_SOC) += snd-soc-edma.o
obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <sound/asoundef.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
#include <sound/omap-pcm.h> #include <sound/omap-pcm.h>
#include "davinci-pcm.h" #include "davinci-pcm.h"
#include "edma-pcm.h"
#include "davinci-mcasp.h" #include "davinci-mcasp.h"
#define MCASP_MAX_AFIFO_DEPTH 64 #define MCASP_MAX_AFIFO_DEPTH 64
...@@ -63,6 +65,7 @@ struct davinci_mcasp { ...@@ -63,6 +65,7 @@ struct davinci_mcasp {
u8 num_serializer; u8 num_serializer;
u8 *serial_dir; u8 *serial_dir;
u8 version; u8 version;
u8 bclk_div;
u16 bclk_lrclk_ratio; u16 bclk_lrclk_ratio;
int streams; int streams;
...@@ -417,6 +420,7 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div ...@@ -417,6 +420,7 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div
ACLKXDIV(div - 1), ACLKXDIV_MASK); ACLKXDIV(div - 1), ACLKXDIV_MASK);
mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG,
ACLKRDIV(div - 1), ACLKRDIV_MASK); ACLKRDIV(div - 1), ACLKRDIV_MASK);
mcasp->bclk_div = div;
break; break;
case 2: /* BCLK/LRCLK ratio */ case 2: /* BCLK/LRCLK ratio */
...@@ -637,8 +641,12 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) ...@@ -637,8 +641,12 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
} }
/* S/PDIF */ /* S/PDIF */
static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp) static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
unsigned int rate)
{ {
u32 cs_value = 0;
u8 *cs_bytes = (u8*) &cs_value;
/* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
and LSB first */ and LSB first */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15)); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
...@@ -660,6 +668,46 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp) ...@@ -660,6 +668,46 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
/* Enable the DIT */ /* Enable the DIT */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
/* Set S/PDIF channel status bits */
cs_bytes[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
cs_bytes[1] = IEC958_AES1_CON_PCM_CODER;
switch (rate) {
case 22050:
cs_bytes[3] |= IEC958_AES3_CON_FS_22050;
break;
case 24000:
cs_bytes[3] |= IEC958_AES3_CON_FS_24000;
break;
case 32000:
cs_bytes[3] |= IEC958_AES3_CON_FS_32000;
break;
case 44100:
cs_bytes[3] |= IEC958_AES3_CON_FS_44100;
break;
case 48000:
cs_bytes[3] |= IEC958_AES3_CON_FS_48000;
break;
case 88200:
cs_bytes[3] |= IEC958_AES3_CON_FS_88200;
break;
case 96000:
cs_bytes[3] |= IEC958_AES3_CON_FS_96000;
break;
case 176400:
cs_bytes[3] |= IEC958_AES3_CON_FS_176400;
break;
case 192000:
cs_bytes[3] |= IEC958_AES3_CON_FS_192000;
break;
default:
printk(KERN_WARNING "unsupported sampling rate: %d\n", rate);
return -EINVAL;
}
mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, cs_value);
mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, cs_value);
return 0; return 0;
} }
...@@ -675,15 +723,22 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -675,15 +723,22 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
int period_size = params_period_size(params); int period_size = params_period_size(params);
int ret; int ret;
/* If mcasp is BCLK master we need to set BCLK divider */ /*
if (mcasp->bclk_master) { * If mcasp is BCLK master, and a BCLK divider was not provided by
* the machine driver, we need to calculate the ratio.
*/
if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
unsigned int bclk_freq = snd_soc_params_to_bclk(params); unsigned int bclk_freq = snd_soc_params_to_bclk(params);
unsigned int div = mcasp->sysclk_freq / bclk_freq;
if (mcasp->sysclk_freq % bclk_freq != 0) { if (mcasp->sysclk_freq % bclk_freq != 0) {
dev_err(mcasp->dev, "Can't produce required BCLK\n"); if (((mcasp->sysclk_freq / div) - bclk_freq) >
return -EINVAL; (bclk_freq - (mcasp->sysclk_freq / (div+1))))
div++;
dev_warn(mcasp->dev,
"Inaccurate BCLK: %u Hz / %u != %u Hz\n",
mcasp->sysclk_freq, div, bclk_freq);
} }
davinci_mcasp_set_clkdiv( davinci_mcasp_set_clkdiv(cpu_dai, 1, div);
cpu_dai, 1, mcasp->sysclk_freq / bclk_freq);
} }
ret = mcasp_common_hw_param(mcasp, substream->stream, ret = mcasp_common_hw_param(mcasp, substream->stream,
...@@ -692,7 +747,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -692,7 +747,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
ret = mcasp_dit_hw_param(mcasp); ret = mcasp_dit_hw_param(mcasp, params_rate(params));
else else
ret = mcasp_i2s_hw_param(mcasp, substream->stream); ret = mcasp_i2s_hw_param(mcasp, substream->stream);
...@@ -782,7 +837,7 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) ...@@ -782,7 +837,7 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
{ {
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
if (mcasp->version == MCASP_VERSION_4) { if (mcasp->version >= MCASP_VERSION_3) {
/* Using dmaengine PCM */ /* Using dmaengine PCM */
dai->playback_dma_data = dai->playback_dma_data =
&mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
...@@ -1232,10 +1287,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -1232,10 +1287,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
IS_MODULE(CONFIG_SND_DAVINCI_SOC)) IS_MODULE(CONFIG_SND_DAVINCI_SOC))
case MCASP_VERSION_1: case MCASP_VERSION_1:
case MCASP_VERSION_2: case MCASP_VERSION_2:
case MCASP_VERSION_3:
ret = davinci_soc_platform_register(&pdev->dev); ret = davinci_soc_platform_register(&pdev->dev);
break; break;
#endif #endif
#if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
IS_MODULE(CONFIG_SND_EDMA_SOC))
case MCASP_VERSION_3:
ret = edma_pcm_platform_register(&pdev->dev);
break;
#endif
#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \ #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
IS_MODULE(CONFIG_SND_OMAP_SOC)) IS_MODULE(CONFIG_SND_OMAP_SOC))
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
static const struct snd_pcm_hardware edma_pcm_hardware = { static const struct snd_pcm_hardware edma_pcm_hardware = {
.info = SNDRV_PCM_INFO_MMAP | .info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_BATCH |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
SNDRV_PCM_INFO_INTERLEAVED, SNDRV_PCM_INFO_INTERLEAVED,
.buffer_bytes_max = 128 * 1024, .buffer_bytes_max = 128 * 1024,
.period_bytes_min = 32, .period_bytes_min = 32,
......
...@@ -20,6 +20,13 @@ ...@@ -20,6 +20,13 @@
#ifndef __EDMA_PCM_H__ #ifndef __EDMA_PCM_H__
#define __EDMA_PCM_H__ #define __EDMA_PCM_H__
#if IS_ENABLED(CONFIG_SND_EDMA_SOC)
int edma_pcm_platform_register(struct device *dev); int edma_pcm_platform_register(struct device *dev);
#else
static inline int edma_pcm_platform_register(struct device *dev)
{
return 0;
}
#endif /* CONFIG_SND_EDMA_SOC */
#endif /* __EDMA_PCM_H__ */ #endif /* __EDMA_PCM_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment