Commit 1a946005 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/tas571x',...

Merge remote-tracking branches 'asoc/topic/tas571x', 'asoc/topic/tlv320aic31xx', 'asoc/topic/tpa6130a2', 'asoc/topic/twl6040' and 'asoc/topic/wm8731' into asoc-next
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/tlv.h> #include <sound/tlv.h>
#include <asm/unaligned.h>
#include "tas571x.h" #include "tas571x.h"
...@@ -63,6 +64,10 @@ static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg) ...@@ -63,6 +64,10 @@ static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
case TAS571X_INPUT_MUX_REG: case TAS571X_INPUT_MUX_REG:
case TAS571X_CH4_SRC_SELECT_REG: case TAS571X_CH4_SRC_SELECT_REG:
case TAS571X_PWM_MUX_REG: case TAS571X_PWM_MUX_REG:
case TAS5717_CH1_RIGHT_CH_MIX_REG:
case TAS5717_CH1_LEFT_CH_MIX_REG:
case TAS5717_CH2_LEFT_CH_MIX_REG:
case TAS5717_CH2_RIGHT_CH_MIX_REG:
return 4; return 4;
default: default:
return 1; return 1;
...@@ -135,6 +140,129 @@ static int tas571x_reg_read(void *context, unsigned int reg, ...@@ -135,6 +140,129 @@ static int tas571x_reg_read(void *context, unsigned int reg,
return 0; return 0;
} }
/*
* register write for 8- and 20-byte registers
*/
static int tas571x_reg_write_multiword(struct i2c_client *client,
unsigned int reg, const long values[], size_t len)
{
size_t i;
uint8_t *buf, *p;
int ret;
size_t send_size = 1 + len * sizeof(uint32_t);
buf = kzalloc(send_size, GFP_KERNEL | GFP_DMA);
if (!buf)
return -ENOMEM;
buf[0] = reg;
for (i = 0, p = buf + 1; i < len; i++, p += sizeof(uint32_t))
put_unaligned_be32(values[i], p);
ret = i2c_master_send(client, buf, send_size);
kfree(buf);
if (ret == send_size)
return 0;
else if (ret < 0)
return ret;
else
return -EIO;
}
/*
* register read for 8- and 20-byte registers
*/
static int tas571x_reg_read_multiword(struct i2c_client *client,
unsigned int reg, long values[], size_t len)
{
unsigned int i;
uint8_t send_buf;
uint8_t *recv_buf, *p;
struct i2c_msg msgs[2];
unsigned int recv_size = len * sizeof(uint32_t);
int ret;
recv_buf = kzalloc(recv_size, GFP_KERNEL | GFP_DMA);
if (!recv_buf)
return -ENOMEM;
send_buf = reg;
msgs[0].addr = client->addr;
msgs[0].len = sizeof(send_buf);
msgs[0].buf = &send_buf;
msgs[0].flags = 0;
msgs[1].addr = client->addr;
msgs[1].len = recv_size;
msgs[1].buf = recv_buf;
msgs[1].flags = I2C_M_RD;
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret < 0)
goto err_ret;
else if (ret != ARRAY_SIZE(msgs)) {
ret = -EIO;
goto err_ret;
}
for (i = 0, p = recv_buf; i < len; i++, p += sizeof(uint32_t))
values[i] = get_unaligned_be32(p);
err_ret:
kfree(recv_buf);
return ret;
}
/*
* Integer array controls for setting biquad, mixer, DRC coefficients.
* According to the datasheet each coefficient is effectively 26bits,
* i.e. stored as 32bits, where bits [31:26] are ignored.
* TI's TAS57xx Graphical Development Environment tool however produces
* coefficients with more than 26 bits. For this reason we allow values
* in the full 32-bits reange.
* The coefficients are ordered as given in the TAS571x data sheet:
* b0, b1, b2, a1, a2
*/
static int tas571x_coefficient_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
int numcoef = kcontrol->private_value >> 16;
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = numcoef;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 0xffffffff;
return 0;
}
static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct i2c_client *i2c = to_i2c_client(codec->dev);
int numcoef = kcontrol->private_value >> 16;
int index = kcontrol->private_value & 0xffff;
return tas571x_reg_read_multiword(i2c, index,
ucontrol->value.integer.value, numcoef);
}
static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct i2c_client *i2c = to_i2c_client(codec->dev);
int numcoef = kcontrol->private_value >> 16;
int index = kcontrol->private_value & 0xffff;
return tas571x_reg_write_multiword(i2c, index,
ucontrol->value.integer.value, numcoef);
}
static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format) static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
{ {
struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec); struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
...@@ -241,6 +369,15 @@ static const struct snd_soc_dai_ops tas571x_dai_ops = { ...@@ -241,6 +369,15 @@ static const struct snd_soc_dai_ops tas571x_dai_ops = {
.digital_mute = tas571x_mute, .digital_mute = tas571x_mute,
}; };
#define BIQUAD_COEFS(xname, reg) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = tas571x_coefficient_info, \
.get = tas571x_coefficient_get,\
.put = tas571x_coefficient_put, \
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
.private_value = reg | (5 << 16) }
static const char *const tas5711_supply_names[] = { static const char *const tas5711_supply_names[] = {
"AVDD", "AVDD",
"DVDD", "DVDD",
...@@ -264,6 +401,16 @@ static const struct snd_kcontrol_new tas5711_controls[] = { ...@@ -264,6 +401,16 @@ static const struct snd_kcontrol_new tas5711_controls[] = {
TAS571X_SOFT_MUTE_REG, TAS571X_SOFT_MUTE_REG,
TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
1, 1), 1, 1),
SOC_DOUBLE_R_RANGE("CH1 Mixer Volume",
TAS5717_CH1_LEFT_CH_MIX_REG,
TAS5717_CH1_RIGHT_CH_MIX_REG,
16, 0, 0x80, 0),
SOC_DOUBLE_R_RANGE("CH2 Mixer Volume",
TAS5717_CH2_LEFT_CH_MIX_REG,
TAS5717_CH2_RIGHT_CH_MIX_REG,
16, 0, 0x80, 0),
}; };
static const struct regmap_range tas571x_readonly_regs_range[] = { static const struct regmap_range tas571x_readonly_regs_range[] = {
...@@ -340,6 +487,43 @@ static const struct snd_kcontrol_new tas5717_controls[] = { ...@@ -340,6 +487,43 @@ static const struct snd_kcontrol_new tas5717_controls[] = {
TAS571X_SOFT_MUTE_REG, TAS571X_SOFT_MUTE_REG,
TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
1, 1), 1, 1),
/*
* The biquads are named according to the register names.
* Please note that TI's TAS57xx Graphical Development Environment
* tool names them different.
*/
BIQUAD_COEFS("CH1 - Biquad 0", TAS5717_CH1_BQ0_REG),
BIQUAD_COEFS("CH1 - Biquad 1", TAS5717_CH1_BQ1_REG),
BIQUAD_COEFS("CH1 - Biquad 2", TAS5717_CH1_BQ2_REG),
BIQUAD_COEFS("CH1 - Biquad 3", TAS5717_CH1_BQ3_REG),
BIQUAD_COEFS("CH1 - Biquad 4", TAS5717_CH1_BQ4_REG),
BIQUAD_COEFS("CH1 - Biquad 5", TAS5717_CH1_BQ5_REG),
BIQUAD_COEFS("CH1 - Biquad 6", TAS5717_CH1_BQ6_REG),
BIQUAD_COEFS("CH1 - Biquad 7", TAS5717_CH1_BQ7_REG),
BIQUAD_COEFS("CH1 - Biquad 8", TAS5717_CH1_BQ8_REG),
BIQUAD_COEFS("CH1 - Biquad 9", TAS5717_CH1_BQ9_REG),
BIQUAD_COEFS("CH1 - Biquad 10", TAS5717_CH1_BQ10_REG),
BIQUAD_COEFS("CH1 - Biquad 11", TAS5717_CH1_BQ11_REG),
BIQUAD_COEFS("CH2 - Biquad 0", TAS5717_CH2_BQ0_REG),
BIQUAD_COEFS("CH2 - Biquad 1", TAS5717_CH2_BQ1_REG),
BIQUAD_COEFS("CH2 - Biquad 2", TAS5717_CH2_BQ2_REG),
BIQUAD_COEFS("CH2 - Biquad 3", TAS5717_CH2_BQ3_REG),
BIQUAD_COEFS("CH2 - Biquad 4", TAS5717_CH2_BQ4_REG),
BIQUAD_COEFS("CH2 - Biquad 5", TAS5717_CH2_BQ5_REG),
BIQUAD_COEFS("CH2 - Biquad 6", TAS5717_CH2_BQ6_REG),
BIQUAD_COEFS("CH2 - Biquad 7", TAS5717_CH2_BQ7_REG),
BIQUAD_COEFS("CH2 - Biquad 8", TAS5717_CH2_BQ8_REG),
BIQUAD_COEFS("CH2 - Biquad 9", TAS5717_CH2_BQ9_REG),
BIQUAD_COEFS("CH2 - Biquad 10", TAS5717_CH2_BQ10_REG),
BIQUAD_COEFS("CH2 - Biquad 11", TAS5717_CH2_BQ11_REG),
BIQUAD_COEFS("CH3 - Biquad 0", TAS5717_CH3_BQ0_REG),
BIQUAD_COEFS("CH3 - Biquad 1", TAS5717_CH3_BQ1_REG),
BIQUAD_COEFS("CH4 - Biquad 0", TAS5717_CH4_BQ0_REG),
BIQUAD_COEFS("CH4 - Biquad 1", TAS5717_CH4_BQ1_REG),
}; };
static const struct reg_default tas5717_reg_defaults[] = { static const struct reg_default tas5717_reg_defaults[] = {
...@@ -350,6 +534,10 @@ static const struct reg_default tas5717_reg_defaults[] = { ...@@ -350,6 +534,10 @@ static const struct reg_default tas5717_reg_defaults[] = {
{ 0x08, 0x00c0 }, { 0x08, 0x00c0 },
{ 0x09, 0x00c0 }, { 0x09, 0x00c0 },
{ 0x1b, 0x82 }, { 0x1b, 0x82 },
{ TAS5717_CH1_RIGHT_CH_MIX_REG, 0x0 },
{ TAS5717_CH1_LEFT_CH_MIX_REG, 0x800000},
{ TAS5717_CH2_LEFT_CH_MIX_REG, 0x0 },
{ TAS5717_CH2_RIGHT_CH_MIX_REG, 0x800000},
}; };
static const struct regmap_config tas5717_regmap_config = { static const struct regmap_config tas5717_regmap_config = {
......
...@@ -52,4 +52,44 @@ ...@@ -52,4 +52,44 @@
#define TAS571X_CH4_SRC_SELECT_REG 0x21 #define TAS571X_CH4_SRC_SELECT_REG 0x21
#define TAS571X_PWM_MUX_REG 0x25 #define TAS571X_PWM_MUX_REG 0x25
/* 20-byte biquad registers */
#define TAS5717_CH1_BQ0_REG 0x26
#define TAS5717_CH1_BQ1_REG 0x27
#define TAS5717_CH1_BQ2_REG 0x28
#define TAS5717_CH1_BQ3_REG 0x29
#define TAS5717_CH1_BQ4_REG 0x2a
#define TAS5717_CH1_BQ5_REG 0x2b
#define TAS5717_CH1_BQ6_REG 0x2c
#define TAS5717_CH1_BQ7_REG 0x2d
#define TAS5717_CH1_BQ8_REG 0x2e
#define TAS5717_CH1_BQ9_REG 0x2f
#define TAS5717_CH2_BQ0_REG 0x30
#define TAS5717_CH2_BQ1_REG 0x31
#define TAS5717_CH2_BQ2_REG 0x32
#define TAS5717_CH2_BQ3_REG 0x33
#define TAS5717_CH2_BQ4_REG 0x34
#define TAS5717_CH2_BQ5_REG 0x35
#define TAS5717_CH2_BQ6_REG 0x36
#define TAS5717_CH2_BQ7_REG 0x37
#define TAS5717_CH2_BQ8_REG 0x38
#define TAS5717_CH2_BQ9_REG 0x39
#define TAS5717_CH1_BQ10_REG 0x58
#define TAS5717_CH1_BQ11_REG 0x59
#define TAS5717_CH4_BQ0_REG 0x5a
#define TAS5717_CH4_BQ1_REG 0x5b
#define TAS5717_CH2_BQ10_REG 0x5c
#define TAS5717_CH2_BQ11_REG 0x5d
#define TAS5717_CH3_BQ0_REG 0x5e
#define TAS5717_CH3_BQ1_REG 0x5f
#define TAS5717_CH1_RIGHT_CH_MIX_REG 0x72
#define TAS5717_CH1_LEFT_CH_MIX_REG 0x73
#define TAS5717_CH2_LEFT_CH_MIX_REG 0x76
#define TAS5717_CH2_RIGHT_CH_MIX_REG 0x77
#endif /* _TAS571X_H */ #endif /* _TAS571X_H */
...@@ -38,141 +38,143 @@ struct aic31xx_pdata { ...@@ -38,141 +38,143 @@ struct aic31xx_pdata {
int micbias_vg; int micbias_vg;
}; };
#define AIC31XX_REG(page, reg) ((page * 128) + reg)
/* Page Control Register */ /* Page Control Register */
#define AIC31XX_PAGECTL 0x00 #define AIC31XX_PAGECTL AIC31XX_REG(0, 0)
/* Page 0 Registers */ /* Page 0 Registers */
/* Software reset register */ /* Software reset register */
#define AIC31XX_RESET 0x01 #define AIC31XX_RESET AIC31XX_REG(0, 1)
/* OT FLAG register */ /* OT FLAG register */
#define AIC31XX_OT_FLAG 0x03 #define AIC31XX_OT_FLAG AIC31XX_REG(0, 3)
/* Clock clock Gen muxing, Multiplexers*/ /* Clock clock Gen muxing, Multiplexers*/
#define AIC31XX_CLKMUX 0x04 #define AIC31XX_CLKMUX AIC31XX_REG(0, 4)
/* PLL P and R-VAL register */ /* PLL P and R-VAL register */
#define AIC31XX_PLLPR 0x05 #define AIC31XX_PLLPR AIC31XX_REG(0, 5)
/* PLL J-VAL register */ /* PLL J-VAL register */
#define AIC31XX_PLLJ 0x06 #define AIC31XX_PLLJ AIC31XX_REG(0, 6)
/* PLL D-VAL MSB register */ /* PLL D-VAL MSB register */
#define AIC31XX_PLLDMSB 0x07 #define AIC31XX_PLLDMSB AIC31XX_REG(0, 7)
/* PLL D-VAL LSB register */ /* PLL D-VAL LSB register */
#define AIC31XX_PLLDLSB 0x08 #define AIC31XX_PLLDLSB AIC31XX_REG(0, 8)
/* DAC NDAC_VAL register*/ /* DAC NDAC_VAL register*/
#define AIC31XX_NDAC 0x0B #define AIC31XX_NDAC AIC31XX_REG(0, 11)
/* DAC MDAC_VAL register */ /* DAC MDAC_VAL register */
#define AIC31XX_MDAC 0x0C #define AIC31XX_MDAC AIC31XX_REG(0, 12)
/* DAC OSR setting register 1, MSB value */ /* DAC OSR setting register 1, MSB value */
#define AIC31XX_DOSRMSB 0x0D #define AIC31XX_DOSRMSB AIC31XX_REG(0, 13)
/* DAC OSR setting register 2, LSB value */ /* DAC OSR setting register 2, LSB value */
#define AIC31XX_DOSRLSB 0x0E #define AIC31XX_DOSRLSB AIC31XX_REG(0, 14)
#define AIC31XX_MINI_DSP_INPOL 0x10 #define AIC31XX_MINI_DSP_INPOL AIC31XX_REG(0, 16)
/* Clock setting register 8, PLL */ /* Clock setting register 8, PLL */
#define AIC31XX_NADC 0x12 #define AIC31XX_NADC AIC31XX_REG(0, 18)
/* Clock setting register 9, PLL */ /* Clock setting register 9, PLL */
#define AIC31XX_MADC 0x13 #define AIC31XX_MADC AIC31XX_REG(0, 19)
/* ADC Oversampling (AOSR) Register */ /* ADC Oversampling (AOSR) Register */
#define AIC31XX_AOSR 0x14 #define AIC31XX_AOSR AIC31XX_REG(0, 20)
/* Clock setting register 9, Multiplexers */ /* Clock setting register 9, Multiplexers */
#define AIC31XX_CLKOUTMUX 0x19 #define AIC31XX_CLKOUTMUX AIC31XX_REG(0, 25)
/* Clock setting register 10, CLOCKOUT M divider value */ /* Clock setting register 10, CLOCKOUT M divider value */
#define AIC31XX_CLKOUTMVAL 0x1A #define AIC31XX_CLKOUTMVAL AIC31XX_REG(0, 26)
/* Audio Interface Setting Register 1 */ /* Audio Interface Setting Register 1 */
#define AIC31XX_IFACE1 0x1B #define AIC31XX_IFACE1 AIC31XX_REG(0, 27)
/* Audio Data Slot Offset Programming */ /* Audio Data Slot Offset Programming */
#define AIC31XX_DATA_OFFSET 0x1C #define AIC31XX_DATA_OFFSET AIC31XX_REG(0, 28)
/* Audio Interface Setting Register 2 */ /* Audio Interface Setting Register 2 */
#define AIC31XX_IFACE2 0x1D #define AIC31XX_IFACE2 AIC31XX_REG(0, 29)
/* Clock setting register 11, BCLK N Divider */ /* Clock setting register 11, BCLK N Divider */
#define AIC31XX_BCLKN 0x1E #define AIC31XX_BCLKN AIC31XX_REG(0, 30)
/* Audio Interface Setting Register 3, Secondary Audio Interface */ /* Audio Interface Setting Register 3, Secondary Audio Interface */
#define AIC31XX_IFACESEC1 0x1F #define AIC31XX_IFACESEC1 AIC31XX_REG(0, 31)
/* Audio Interface Setting Register 4 */ /* Audio Interface Setting Register 4 */
#define AIC31XX_IFACESEC2 0x20 #define AIC31XX_IFACESEC2 AIC31XX_REG(0, 32)
/* Audio Interface Setting Register 5 */ /* Audio Interface Setting Register 5 */
#define AIC31XX_IFACESEC3 0x21 #define AIC31XX_IFACESEC3 AIC31XX_REG(0, 33)
/* I2C Bus Condition */ /* I2C Bus Condition */
#define AIC31XX_I2C 0x22 #define AIC31XX_I2C AIC31XX_REG(0, 34)
/* ADC FLAG */ /* ADC FLAG */
#define AIC31XX_ADCFLAG 0x24 #define AIC31XX_ADCFLAG AIC31XX_REG(0, 36)
/* DAC Flag Registers */ /* DAC Flag Registers */
#define AIC31XX_DACFLAG1 0x25 #define AIC31XX_DACFLAG1 AIC31XX_REG(0, 37)
#define AIC31XX_DACFLAG2 0x26 #define AIC31XX_DACFLAG2 AIC31XX_REG(0, 38)
/* Sticky Interrupt flag (overflow) */ /* Sticky Interrupt flag (overflow) */
#define AIC31XX_OFFLAG 0x27 #define AIC31XX_OFFLAG AIC31XX_REG(0, 39)
/* Sticy DAC Interrupt flags */ /* Sticy DAC Interrupt flags */
#define AIC31XX_INTRDACFLAG 0x2C #define AIC31XX_INTRDACFLAG AIC31XX_REG(0, 44)
/* Sticy ADC Interrupt flags */ /* Sticy ADC Interrupt flags */
#define AIC31XX_INTRADCFLAG 0x2D #define AIC31XX_INTRADCFLAG AIC31XX_REG(0, 45)
/* DAC Interrupt flags 2 */ /* DAC Interrupt flags 2 */
#define AIC31XX_INTRDACFLAG2 0x2E #define AIC31XX_INTRDACFLAG2 AIC31XX_REG(0, 46)
/* ADC Interrupt flags 2 */ /* ADC Interrupt flags 2 */
#define AIC31XX_INTRADCFLAG2 0x2F #define AIC31XX_INTRADCFLAG2 AIC31XX_REG(0, 47)
/* INT1 interrupt control */ /* INT1 interrupt control */
#define AIC31XX_INT1CTRL 0x30 #define AIC31XX_INT1CTRL AIC31XX_REG(0, 48)
/* INT2 interrupt control */ /* INT2 interrupt control */
#define AIC31XX_INT2CTRL 0x31 #define AIC31XX_INT2CTRL AIC31XX_REG(0, 49)
/* GPIO1 control */ /* GPIO1 control */
#define AIC31XX_GPIO1 0x33 #define AIC31XX_GPIO1 AIC31XX_REG(0, 50)
#define AIC31XX_DACPRB 0x3C #define AIC31XX_DACPRB AIC31XX_REG(0, 60)
/* ADC Instruction Set Register */ /* ADC Instruction Set Register */
#define AIC31XX_ADCPRB 0x3D #define AIC31XX_ADCPRB AIC31XX_REG(0, 61)
/* DAC channel setup register */ /* DAC channel setup register */
#define AIC31XX_DACSETUP 0x3F #define AIC31XX_DACSETUP AIC31XX_REG(0, 63)
/* DAC Mute and volume control register */ /* DAC Mute and volume control register */
#define AIC31XX_DACMUTE 0x40 #define AIC31XX_DACMUTE AIC31XX_REG(0, 64)
/* Left DAC channel digital volume control */ /* Left DAC channel digital volume control */
#define AIC31XX_LDACVOL 0x41 #define AIC31XX_LDACVOL AIC31XX_REG(0, 65)
/* Right DAC channel digital volume control */ /* Right DAC channel digital volume control */
#define AIC31XX_RDACVOL 0x42 #define AIC31XX_RDACVOL AIC31XX_REG(0, 66)
/* Headset detection */ /* Headset detection */
#define AIC31XX_HSDETECT 0x43 #define AIC31XX_HSDETECT AIC31XX_REG(0, 67)
/* ADC Digital Mic */ /* ADC Digital Mic */
#define AIC31XX_ADCSETUP 0x51 #define AIC31XX_ADCSETUP AIC31XX_REG(0, 81)
/* ADC Digital Volume Control Fine Adjust */ /* ADC Digital Volume Control Fine Adjust */
#define AIC31XX_ADCFGA 0x52 #define AIC31XX_ADCFGA AIC31XX_REG(0, 82)
/* ADC Digital Volume Control Coarse Adjust */ /* ADC Digital Volume Control Coarse Adjust */
#define AIC31XX_ADCVOL 0x53 #define AIC31XX_ADCVOL AIC31XX_REG(0, 83)
/* Page 1 Registers */ /* Page 1 Registers */
/* Headphone drivers */ /* Headphone drivers */
#define AIC31XX_HPDRIVER 0x9F #define AIC31XX_HPDRIVER AIC31XX_REG(1, 31)
/* Class-D Speakear Amplifier */ /* Class-D Speakear Amplifier */
#define AIC31XX_SPKAMP 0xA0 #define AIC31XX_SPKAMP AIC31XX_REG(1, 32)
/* HP Output Drivers POP Removal Settings */ /* HP Output Drivers POP Removal Settings */
#define AIC31XX_HPPOP 0xA1 #define AIC31XX_HPPOP AIC31XX_REG(1, 33)
/* Output Driver PGA Ramp-Down Period Control */ /* Output Driver PGA Ramp-Down Period Control */
#define AIC31XX_SPPGARAMP 0xA2 #define AIC31XX_SPPGARAMP AIC31XX_REG(1, 34)
/* DAC_L and DAC_R Output Mixer Routing */ /* DAC_L and DAC_R Output Mixer Routing */
#define AIC31XX_DACMIXERROUTE 0xA3 #define AIC31XX_DACMIXERROUTE AIC31XX_REG(1, 35)
/* Left Analog Vol to HPL */ /* Left Analog Vol to HPL */
#define AIC31XX_LANALOGHPL 0xA4 #define AIC31XX_LANALOGHPL AIC31XX_REG(1, 36)
/* Right Analog Vol to HPR */ /* Right Analog Vol to HPR */
#define AIC31XX_RANALOGHPR 0xA5 #define AIC31XX_RANALOGHPR AIC31XX_REG(1, 37)
/* Left Analog Vol to SPL */ /* Left Analog Vol to SPL */
#define AIC31XX_LANALOGSPL 0xA6 #define AIC31XX_LANALOGSPL AIC31XX_REG(1, 38)
/* Right Analog Vol to SPR */ /* Right Analog Vol to SPR */
#define AIC31XX_RANALOGSPR 0xA7 #define AIC31XX_RANALOGSPR AIC31XX_REG(1, 39)
/* HPL Driver */ /* HPL Driver */
#define AIC31XX_HPLGAIN 0xA8 #define AIC31XX_HPLGAIN AIC31XX_REG(1, 40)
/* HPR Driver */ /* HPR Driver */
#define AIC31XX_HPRGAIN 0xA9 #define AIC31XX_HPRGAIN AIC31XX_REG(1, 41)
/* SPL Driver */ /* SPL Driver */
#define AIC31XX_SPLGAIN 0xAA #define AIC31XX_SPLGAIN AIC31XX_REG(1, 42)
/* SPR Driver */ /* SPR Driver */
#define AIC31XX_SPRGAIN 0xAB #define AIC31XX_SPRGAIN AIC31XX_REG(1, 43)
/* HP Driver Control */ /* HP Driver Control */
#define AIC31XX_HPCONTROL 0xAC #define AIC31XX_HPCONTROL AIC31XX_REG(1, 44)
/* MIC Bias Control */ /* MIC Bias Control */
#define AIC31XX_MICBIAS 0xAE #define AIC31XX_MICBIAS AIC31XX_REG(1, 46)
/* MIC PGA*/ /* MIC PGA*/
#define AIC31XX_MICPGA 0xAF #define AIC31XX_MICPGA AIC31XX_REG(1, 47)
/* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */ /* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */
#define AIC31XX_MICPGAPI 0xB0 #define AIC31XX_MICPGAPI AIC31XX_REG(1, 48)
/* ADC Input Selection for M-Terminal */ /* ADC Input Selection for M-Terminal */
#define AIC31XX_MICPGAMI 0xB1 #define AIC31XX_MICPGAMI AIC31XX_REG(1, 49)
/* Input CM Settings */ /* Input CM Settings */
#define AIC31XX_MICPGACM 0xB2 #define AIC31XX_MICPGACM AIC31XX_REG(1, 50)
/* Bits, masks and shifts */ /* Bits, masks and shifts */
......
This diff is collapsed.
...@@ -30,19 +30,20 @@ ...@@ -30,19 +30,20 @@
#define TPA6130A2_REG_OUT_IMPEDANCE 0x03 #define TPA6130A2_REG_OUT_IMPEDANCE 0x03
#define TPA6130A2_REG_VERSION 0x04 #define TPA6130A2_REG_VERSION 0x04
#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
/* Register bits */ /* Register bits */
/* TPA6130A2_REG_CONTROL (0x01) */ /* TPA6130A2_REG_CONTROL (0x01) */
#define TPA6130A2_SWS (0x01 << 0) #define TPA6130A2_SWS_SHIFT 0
#define TPA6130A2_SWS (0x01 << TPA6130A2_SWS_SHIFT)
#define TPA6130A2_TERMAL (0x01 << 1) #define TPA6130A2_TERMAL (0x01 << 1)
#define TPA6130A2_MODE(x) (x << 4) #define TPA6130A2_MODE(x) (x << 4)
#define TPA6130A2_MODE_STEREO (0x00) #define TPA6130A2_MODE_STEREO (0x00)
#define TPA6130A2_MODE_DUAL_MONO (0x01) #define TPA6130A2_MODE_DUAL_MONO (0x01)
#define TPA6130A2_MODE_BRIDGE (0x02) #define TPA6130A2_MODE_BRIDGE (0x02)
#define TPA6130A2_MODE_MASK (0x03) #define TPA6130A2_MODE_MASK (0x03)
#define TPA6130A2_HP_EN_R (0x01 << 6) #define TPA6130A2_HP_EN_R_SHIFT 6
#define TPA6130A2_HP_EN_L (0x01 << 7) #define TPA6130A2_HP_EN_R (0x01 << TPA6130A2_HP_EN_R_SHIFT)
#define TPA6130A2_HP_EN_L_SHIFT 7
#define TPA6130A2_HP_EN_L (0x01 << TPA6130A2_HP_EN_L_SHIFT)
/* TPA6130A2_REG_VOL_MUTE (0x02) */ /* TPA6130A2_REG_VOL_MUTE (0x02) */
#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0) #define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
...@@ -56,7 +57,4 @@ ...@@ -56,7 +57,4 @@
/* TPA6130A2_REG_VERSION (0x04) */ /* TPA6130A2_REG_VERSION (0x04) */
#define TPA6130A2_VERSION_MASK (0x0f) #define TPA6130A2_VERSION_MASK (0x0f)
extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
#endif /* __TPA6130A2_H__ */ #endif /* __TPA6130A2_H__ */
...@@ -358,6 +358,9 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, ...@@ -358,6 +358,9 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
case 24: case 24:
iface |= 0x0008; iface |= 0x0008;
break; break;
case 32:
iface |= 0x000c;
break;
} }
wm8731_set_deemph(codec); wm8731_set_deemph(codec);
...@@ -541,7 +544,7 @@ static int wm8731_startup(struct snd_pcm_substream *substream, ...@@ -541,7 +544,7 @@ static int wm8731_startup(struct snd_pcm_substream *substream,
#define WM8731_RATES SNDRV_PCM_RATE_8000_96000 #define WM8731_RATES SNDRV_PCM_RATE_8000_96000
#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE) SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
static const struct snd_soc_dai_ops wm8731_dai_ops = { static const struct snd_soc_dai_ops wm8731_dai_ops = {
.startup = wm8731_startup, .startup = wm8731_startup,
......
...@@ -100,7 +100,7 @@ config SND_OMAP_SOC_OMAP_TWL4030 ...@@ -100,7 +100,7 @@ config SND_OMAP_SOC_OMAP_TWL4030
config SND_OMAP_SOC_OMAP_ABE_TWL6040 config SND_OMAP_SOC_OMAP_ABE_TWL6040
tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
depends on TWL6040_CORE && SND_OMAP_SOC depends on TWL6040_CORE && SND_OMAP_SOC && COMMON_CLK
depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST
select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_DMIC
select SND_OMAP_SOC_MCPDM select SND_OMAP_SOC_MCPDM
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <linux/platform_data/asoc-ti-mcbsp.h> #include <linux/platform_data/asoc-ti-mcbsp.h>
#include "../codecs/tpa6130a2.h"
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w, ...@@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static int rx51_hp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
if (SND_SOC_DAPM_EVENT_ON(event))
tpa6130a2_stereo_enable(codec, 1);
else
tpa6130a2_stereo_enable(codec, 0);
return 0;
}
static int rx51_get_input(struct snd_kcontrol *kcontrol, static int rx51_get_input(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
...@@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = { ...@@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event), SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
SND_SOC_DAPM_MIC("DMic", NULL), SND_SOC_DAPM_MIC("DMic", NULL),
SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event), SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("HS Mic", NULL), SND_SOC_DAPM_MIC("HS Mic", NULL),
SND_SOC_DAPM_LINE("FM Transmitter", NULL), SND_SOC_DAPM_LINE("FM Transmitter", NULL),
SND_SOC_DAPM_SPK("Earphone", NULL), SND_SOC_DAPM_SPK("Earphone", NULL),
...@@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = { ...@@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"Ext Spk", NULL, "HPROUT"}, {"Ext Spk", NULL, "HPROUT"},
{"Ext Spk", NULL, "HPLCOM"}, {"Ext Spk", NULL, "HPLCOM"},
{"Ext Spk", NULL, "HPRCOM"}, {"Ext Spk", NULL, "HPRCOM"},
{"Headphone Jack", NULL, "LLOUT"},
{"Headphone Jack", NULL, "RLOUT"},
{"FM Transmitter", NULL, "LLOUT"}, {"FM Transmitter", NULL, "LLOUT"},
{"FM Transmitter", NULL, "RLOUT"}, {"FM Transmitter", NULL, "RLOUT"},
{"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
{"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
{"TPA6130A2 LEFTIN", NULL, "LLOUT"},
{"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
{"DMic Rate 64", NULL, "DMic"}, {"DMic Rate 64", NULL, "DMic"},
{"DMic", NULL, "Mic Bias"}, {"DMic", NULL, "Mic Bias"},
...@@ -286,16 +275,10 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { ...@@ -286,16 +275,10 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
int err; int err;
err = tpa6130a2_add_controls(codec);
if (err < 0) {
dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
return err;
}
snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42); snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
err = omap_mcbsp_st_add_controls(rtd, 2); err = omap_mcbsp_st_add_controls(rtd, 2);
...@@ -357,6 +340,10 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = { ...@@ -357,6 +340,10 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
.name = "TLV320AIC34b", .name = "TLV320AIC34b",
.codec_name = "tlv320aic3x-codec.2-0019", .codec_name = "tlv320aic3x-codec.2-0019",
}, },
{
.name = "TPA61320A2",
.codec_name = "tpa6130a2.2-0060",
},
}; };
static struct snd_soc_codec_conf rx51_codec_conf[] = { static struct snd_soc_codec_conf rx51_codec_conf[] = {
...@@ -364,6 +351,10 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = { ...@@ -364,6 +351,10 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = {
.dev_name = "tlv320aic3x-codec.2-0019", .dev_name = "tlv320aic3x-codec.2-0019",
.name_prefix = "b", .name_prefix = "b",
}, },
{
.dev_name = "tpa6130a2.2-0060",
.name_prefix = "TPA6130A2",
},
}; };
/* Audio card */ /* Audio card */
...@@ -435,11 +426,10 @@ static int rx51_soc_probe(struct platform_device *pdev) ...@@ -435,11 +426,10 @@ static int rx51_soc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Headphone amplifier node is not provided\n"); dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
return -EINVAL; return -EINVAL;
} }
rx51_aux_dev[1].codec_name = NULL;
/* TODO: tpa6130a2a driver supports only a single instance, so rx51_aux_dev[1].codec_of_node = dai_node;
* this driver ignores the headphone-amplifier node for now. rx51_codec_conf[1].dev_name = NULL;
* It's already mandatory in the DT binding to be future proof. rx51_codec_conf[1].of_node = dai_node;
*/
} }
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
......
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