Commit d7502f7f authored by Mark Brown's avatar Mark Brown

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

Merge remote-tracking branches 'asoc/topic/tlv320aic31xx', 'asoc/topic/tlv320aic32x4', 'asoc/topic/tlv320aic3x', 'asoc/topic/tlv320dac33' and 'asoc/topic/ts3a227e' into asoc-next
...@@ -22,7 +22,7 @@ Required properties: ...@@ -22,7 +22,7 @@ Required properties:
Optional properties: Optional properties:
- gpio-reset - gpio pin number used for codec reset - reset-gpios - GPIO specification for the active low RESET input.
- ai31xx-micbias-vg - MicBias Voltage setting - ai31xx-micbias-vg - MicBias Voltage setting
1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V 1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V
2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V 2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V
...@@ -30,6 +30,10 @@ Optional properties: ...@@ -30,6 +30,10 @@ Optional properties:
If this node is not mentioned or if the value is unknown, then If this node is not mentioned or if the value is unknown, then
micbias is set to 2.0V. micbias is set to 2.0V.
Deprecated properties:
- gpio-reset - gpio pin number used for codec reset
CODEC output pins: CODEC output pins:
* HPL * HPL
* HPR * HPR
...@@ -48,6 +52,7 @@ CODEC input pins: ...@@ -48,6 +52,7 @@ CODEC input pins:
The pins can be used in referring sound node's audio-routing property. The pins can be used in referring sound node's audio-routing property.
Example: Example:
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/sound/tlv320aic31xx-micbias.h> #include <dt-bindings/sound/tlv320aic31xx-micbias.h>
tlv320aic31xx: tlv320aic31xx@18 { tlv320aic31xx: tlv320aic31xx@18 {
...@@ -56,6 +61,8 @@ tlv320aic31xx: tlv320aic31xx@18 { ...@@ -56,6 +61,8 @@ tlv320aic31xx: tlv320aic31xx@18 {
ai31xx-micbias-vg = <MICBIAS_OFF>; ai31xx-micbias-vg = <MICBIAS_OFF>;
reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
HPVDD-supply = <&regulator>; HPVDD-supply = <&regulator>;
SPRVDD-supply = <&regulator>; SPRVDD-supply = <&regulator>;
SPLVDD-supply = <&regulator>; SPLVDD-supply = <&regulator>;
......
...@@ -17,7 +17,7 @@ Required properties: ...@@ -17,7 +17,7 @@ Required properties:
Optional properties: Optional properties:
- gpio-reset - gpio pin number used for codec reset - reset-gpios - GPIO specification for the active low RESET input.
- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality - ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
- Not supported on tlv320aic3104 - Not supported on tlv320aic3104
- ai3x-micbias-vg - MicBias Voltage required. - ai3x-micbias-vg - MicBias Voltage required.
...@@ -34,6 +34,10 @@ Optional properties: ...@@ -34,6 +34,10 @@ Optional properties:
- AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the
device as covered in Documentation/devicetree/bindings/regulator/regulator.txt device as covered in Documentation/devicetree/bindings/regulator/regulator.txt
Deprecated properties:
- gpio-reset - gpio pin number used for codec reset
CODEC output pins: CODEC output pins:
* LLOUT * LLOUT
* RLOUT * RLOUT
...@@ -61,10 +65,14 @@ The pins can be used in referring sound node's audio-routing property. ...@@ -61,10 +65,14 @@ The pins can be used in referring sound node's audio-routing property.
Example: Example:
#include <dt-bindings/gpio/gpio.h>
tlv320aic3x: tlv320aic3x@1b { tlv320aic3x: tlv320aic3x@1b {
compatible = "ti,tlv320aic3x"; compatible = "ti,tlv320aic3x";
reg = <0x1b>; reg = <0x1b>;
reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
AVDD-supply = <&regulator>; AVDD-supply = <&regulator>;
IOVDD-supply = <&regulator>; IOVDD-supply = <&regulator>;
DRVDD-supply = <&regulator>; DRVDD-supply = <&regulator>;
......
...@@ -939,12 +939,12 @@ config SND_SOC_TLV320AIC32X4 ...@@ -939,12 +939,12 @@ config SND_SOC_TLV320AIC32X4
tristate tristate
config SND_SOC_TLV320AIC32X4_I2C config SND_SOC_TLV320AIC32X4_I2C
tristate tristate "Texas Instruments TLV320AIC32x4 audio CODECs - I2C"
depends on I2C depends on I2C
select SND_SOC_TLV320AIC32X4 select SND_SOC_TLV320AIC32X4
config SND_SOC_TLV320AIC32X4_SPI config SND_SOC_TLV320AIC32X4_SPI
tristate tristate "Texas Instruments TLV320AIC32x4 audio CODECs - SPI"
depends on SPI_MASTER depends on SPI_MASTER
select SND_SOC_TLV320AIC32X4 select SND_SOC_TLV320AIC32X4
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* ALSA SoC TLV320AIC31XX codec driver * ALSA SoC TLV320AIC31xx CODEC Driver
* *
* Copyright (C) 2014 Texas Instruments, Inc. * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
* * Jyri Sarha <jsarha@ti.com>
* Author: Jyri Sarha <jsarha@ti.com>
* *
* Based on ground work by: Ajit Kulkarni <x0175765@ti.com> * Based on ground work by: Ajit Kulkarni <x0175765@ti.com>
* *
* This package is free software; you can redistribute it and/or modify * The TLV320AIC31xx series of audio codecs are low-power, highly integrated
* it under the terms of the GNU General Public License version 2 as * high performance codecs which provides a stereo DAC, a mono ADC,
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* The TLV320AIC31xx series of audio codec is a low-power, highly integrated
* high performance codec which provides a stereo DAC, a mono ADC,
* and mono/stereo Class-D speaker driver. * and mono/stereo Class-D speaker driver.
*/ */
...@@ -26,7 +18,7 @@ ...@@ -26,7 +18,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -144,8 +136,7 @@ static const struct regmap_config aic31xx_i2c_regmap = { ...@@ -144,8 +136,7 @@ static const struct regmap_config aic31xx_i2c_regmap = {
.max_register = 12 * 128, .max_register = 12 * 128,
}; };
#define AIC31XX_NUM_SUPPLIES 6 static const char * const aic31xx_supply_names[] = {
static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = {
"HPVDD", "HPVDD",
"SPRVDD", "SPRVDD",
"SPLVDD", "SPLVDD",
...@@ -154,6 +145,8 @@ static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = { ...@@ -154,6 +145,8 @@ static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = {
"DVDD", "DVDD",
}; };
#define AIC31XX_NUM_SUPPLIES ARRAY_SIZE(aic31xx_supply_names)
struct aic31xx_disable_nb { struct aic31xx_disable_nb {
struct notifier_block nb; struct notifier_block nb;
struct aic31xx_priv *aic31xx; struct aic31xx_priv *aic31xx;
...@@ -164,6 +157,9 @@ struct aic31xx_priv { ...@@ -164,6 +157,9 @@ struct aic31xx_priv {
u8 i2c_regs_status; u8 i2c_regs_status;
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
enum aic31xx_type codec_type;
struct gpio_desc *gpio_reset;
int micbias_vg;
struct aic31xx_pdata pdata; struct aic31xx_pdata pdata;
struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES];
struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES];
...@@ -185,7 +181,7 @@ struct aic31xx_rate_divs { ...@@ -185,7 +181,7 @@ struct aic31xx_rate_divs {
u8 madc; u8 madc;
}; };
/* ADC dividers can be disabled by cofiguring them to 0 */ /* ADC dividers can be disabled by configuring them to 0 */
static const struct aic31xx_rate_divs aic31xx_divs[] = { static const struct aic31xx_rate_divs aic31xx_divs[] = {
/* mclk/p rate pll: j d dosr ndac mdac aors nadc madc */ /* mclk/p rate pll: j d dosr ndac mdac aors nadc madc */
/* 8k rate */ /* 8k rate */
...@@ -456,7 +452,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, ...@@ -456,7 +452,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
/* change mic bias voltage to user defined */ /* change mic bias voltage to user defined */
snd_soc_update_bits(codec, AIC31XX_MICBIAS, snd_soc_update_bits(codec, AIC31XX_MICBIAS,
AIC31XX_MICBIAS_MASK, AIC31XX_MICBIAS_MASK,
aic31xx->pdata.micbias_vg << aic31xx->micbias_vg <<
AIC31XX_MICBIAS_SHIFT); AIC31XX_MICBIAS_SHIFT);
dev_dbg(codec->dev, "%s: turned on\n", __func__); dev_dbg(codec->dev, "%s: turned on\n", __func__);
break; break;
...@@ -679,14 +675,14 @@ static int aic31xx_add_controls(struct snd_soc_codec *codec) ...@@ -679,14 +675,14 @@ static int aic31xx_add_controls(struct snd_soc_codec *codec)
int ret = 0; int ret = 0;
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
if (!(aic31xx->pdata.codec_type & DAC31XX_BIT)) if (!(aic31xx->codec_type & DAC31XX_BIT))
ret = snd_soc_add_codec_controls( ret = snd_soc_add_codec_controls(
codec, aic31xx_snd_controls, codec, aic31xx_snd_controls,
ARRAY_SIZE(aic31xx_snd_controls)); ARRAY_SIZE(aic31xx_snd_controls));
if (ret) if (ret)
return ret; return ret;
if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) if (aic31xx->codec_type & AIC31XX_STEREO_CLASS_D_BIT)
ret = snd_soc_add_codec_controls( ret = snd_soc_add_codec_controls(
codec, aic311x_snd_controls, codec, aic311x_snd_controls,
ARRAY_SIZE(aic311x_snd_controls)); ARRAY_SIZE(aic311x_snd_controls));
...@@ -704,7 +700,7 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec) ...@@ -704,7 +700,7 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec)
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
int ret = 0; int ret = 0;
if (aic31xx->pdata.codec_type & DAC31XX_BIT) { if (aic31xx->codec_type & DAC31XX_BIT) {
ret = snd_soc_dapm_new_controls( ret = snd_soc_dapm_new_controls(
dapm, dac31xx_dapm_widgets, dapm, dac31xx_dapm_widgets,
ARRAY_SIZE(dac31xx_dapm_widgets)); ARRAY_SIZE(dac31xx_dapm_widgets));
...@@ -728,7 +724,7 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec) ...@@ -728,7 +724,7 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec)
return ret; return ret;
} }
if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { if (aic31xx->codec_type & AIC31XX_STEREO_CLASS_D_BIT) {
ret = snd_soc_dapm_new_controls( ret = snd_soc_dapm_new_controls(
dapm, aic311x_dapm_widgets, dapm, aic311x_dapm_widgets,
ARRAY_SIZE(aic311x_dapm_widgets)); ARRAY_SIZE(aic311x_dapm_widgets));
...@@ -760,11 +756,17 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, ...@@ -760,11 +756,17 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
{ {
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
int bclk_score = snd_soc_params_to_frame_size(params); int bclk_score = snd_soc_params_to_frame_size(params);
int mclk_p = aic31xx->sysclk / aic31xx->p_div; int mclk_p;
int bclk_n = 0; int bclk_n = 0;
int match = -1; int match = -1;
int i; int i;
if (!aic31xx->sysclk || !aic31xx->p_div) {
dev_err(codec->dev, "Master clock not supplied\n");
return -EINVAL;
}
mclk_p = aic31xx->sysclk / aic31xx->p_div;
/* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */
snd_soc_update_bits(codec, AIC31XX_CLKMUX, snd_soc_update_bits(codec, AIC31XX_CLKMUX,
AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL); AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL);
...@@ -840,11 +842,17 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, ...@@ -840,11 +842,17 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
dev_dbg(codec->dev, dev_dbg(codec->dev,
"pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n", "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n",
aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d, aic31xx_divs[i].pll_j,
aic31xx->p_div, aic31xx_divs[i].dosr, aic31xx_divs[i].pll_d,
aic31xx_divs[i].ndac, aic31xx_divs[i].mdac, aic31xx->p_div,
aic31xx_divs[i].aosr, aic31xx_divs[i].nadc, aic31xx_divs[i].dosr,
aic31xx_divs[i].madc, bclk_n); aic31xx_divs[i].ndac,
aic31xx_divs[i].mdac,
aic31xx_divs[i].aosr,
aic31xx_divs[i].nadc,
aic31xx_divs[i].madc,
bclk_n
);
return 0; return 0;
} }
...@@ -919,8 +927,28 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -919,8 +927,28 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER; iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER;
break; break;
case SND_SOC_DAIFMT_CBS_CFM:
iface_reg1 |= AIC31XX_WCLK_MASTER;
break;
case SND_SOC_DAIFMT_CBM_CFS:
iface_reg1 |= AIC31XX_BCLK_MASTER;
break;
case SND_SOC_DAIFMT_CBS_CFS:
break;
default:
dev_err(codec->dev, "Invalid DAI master/slave interface\n");
return -EINVAL;
}
/* signal polarity */
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_IB_NF:
iface_reg2 |= AIC31XX_BCLKINV_MASK;
break;
default: default:
dev_alert(codec->dev, "Invalid DAI master/slave interface\n"); dev_err(codec->dev, "Invalid DAI clock signal polarity\n");
return -EINVAL; return -EINVAL;
} }
...@@ -931,16 +959,12 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -931,16 +959,12 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
dsp_a_val = 0x1; /* fall through */ dsp_a_val = 0x1; /* fall through */
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
/* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */ /*
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { * NOTE: This CODEC samples on the falling edge of BCLK in
case SND_SOC_DAIFMT_NB_NF: * DSP mode, this is inverted compared to what most DAIs
iface_reg2 |= AIC31XX_BCLKINV_MASK; * expect, so we invert for this mode
break; */
case SND_SOC_DAIFMT_IB_NF: iface_reg2 ^= AIC31XX_BCLKINV_MASK;
break;
default:
return -EINVAL;
}
iface_reg1 |= (AIC31XX_DSP_MODE << iface_reg1 |= (AIC31XX_DSP_MODE <<
AIC31XX_IFACE1_DATATYPE_SHIFT); AIC31XX_IFACE1_DATATYPE_SHIFT);
break; break;
...@@ -981,8 +1005,9 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, ...@@ -981,8 +1005,9 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n", dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
__func__, clk_id, freq, dir); __func__, clk_id, freq, dir);
for (i = 1; freq/i > 20000000 && i < 8; i++) for (i = 1; i < 8; i++)
; if (freq / i <= 20000000)
break;
if (freq/i > 20000000) { if (freq/i > 20000000) {
dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n", dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n",
__func__, freq); __func__, freq);
...@@ -990,9 +1015,9 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, ...@@ -990,9 +1015,9 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
} }
aic31xx->p_div = i; aic31xx->p_div = i;
for (i = 0; i < ARRAY_SIZE(aic31xx_divs) && for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++)
aic31xx_divs[i].mclk_p != freq/aic31xx->p_div; i++) if (aic31xx_divs[i].mclk_p == freq / aic31xx->p_div)
; break;
if (i == ARRAY_SIZE(aic31xx_divs)) { if (i == ARRAY_SIZE(aic31xx_divs)) {
dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n",
__func__, freq); __func__, freq);
...@@ -1004,6 +1029,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, ...@@ -1004,6 +1029,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
clk_id << AIC31XX_PLL_CLKIN_SHIFT); clk_id << AIC31XX_PLL_CLKIN_SHIFT);
aic31xx->sysclk = freq; aic31xx->sysclk = freq;
return 0; return 0;
} }
...@@ -1019,8 +1045,8 @@ static int aic31xx_regulator_event(struct notifier_block *nb, ...@@ -1019,8 +1045,8 @@ static int aic31xx_regulator_event(struct notifier_block *nb,
* Put codec to reset and as at least one of the * Put codec to reset and as at least one of the
* supplies was disabled. * supplies was disabled.
*/ */
if (gpio_is_valid(aic31xx->pdata.gpio_reset)) if (aic31xx->gpio_reset)
gpio_set_value(aic31xx->pdata.gpio_reset, 0); gpiod_set_value(aic31xx->gpio_reset, 1);
regcache_mark_dirty(aic31xx->regmap); regcache_mark_dirty(aic31xx->regmap);
dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__); dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__);
...@@ -1029,6 +1055,22 @@ static int aic31xx_regulator_event(struct notifier_block *nb, ...@@ -1029,6 +1055,22 @@ static int aic31xx_regulator_event(struct notifier_block *nb,
return 0; return 0;
} }
static int aic31xx_reset(struct aic31xx_priv *aic31xx)
{
int ret = 0;
if (aic31xx->gpio_reset) {
gpiod_set_value(aic31xx->gpio_reset, 1);
ndelay(10); /* At least 10ns */
gpiod_set_value(aic31xx->gpio_reset, 0);
} else {
ret = regmap_write(aic31xx->regmap, AIC31XX_RESET, 1);
}
mdelay(1); /* At least 1ms */
return ret;
}
static void aic31xx_clk_on(struct snd_soc_codec *codec) static void aic31xx_clk_on(struct snd_soc_codec *codec)
{ {
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
...@@ -1065,20 +1107,22 @@ static void aic31xx_clk_off(struct snd_soc_codec *codec) ...@@ -1065,20 +1107,22 @@ static void aic31xx_clk_off(struct snd_soc_codec *codec)
static int aic31xx_power_on(struct snd_soc_codec *codec) static int aic31xx_power_on(struct snd_soc_codec *codec)
{ {
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
int ret = 0; int ret;
ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies), ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies),
aic31xx->supplies); aic31xx->supplies);
if (ret) if (ret)
return ret; return ret;
if (gpio_is_valid(aic31xx->pdata.gpio_reset)) {
gpio_set_value(aic31xx->pdata.gpio_reset, 1);
udelay(100);
}
regcache_cache_only(aic31xx->regmap, false); regcache_cache_only(aic31xx->regmap, false);
/* Reset device registers for a consistent power-on like state */
ret = aic31xx_reset(aic31xx);
if (ret < 0)
dev_err(aic31xx->dev, "Could not reset device: %d\n", ret);
ret = regcache_sync(aic31xx->regmap); ret = regcache_sync(aic31xx->regmap);
if (ret != 0) { if (ret) {
dev_err(codec->dev, dev_err(codec->dev,
"Failed to restore cache: %d\n", ret); "Failed to restore cache: %d\n", ret);
regcache_cache_only(aic31xx->regmap, true); regcache_cache_only(aic31xx->regmap, true);
...@@ -1086,19 +1130,17 @@ static int aic31xx_power_on(struct snd_soc_codec *codec) ...@@ -1086,19 +1130,17 @@ static int aic31xx_power_on(struct snd_soc_codec *codec)
aic31xx->supplies); aic31xx->supplies);
return ret; return ret;
} }
return 0; return 0;
} }
static int aic31xx_power_off(struct snd_soc_codec *codec) static void aic31xx_power_off(struct snd_soc_codec *codec)
{ {
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
int ret = 0;
regcache_cache_only(aic31xx->regmap, true); regcache_cache_only(aic31xx->regmap, true);
ret = regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies), regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
aic31xx->supplies); aic31xx->supplies);
return ret;
} }
static int aic31xx_set_bias_level(struct snd_soc_codec *codec, static int aic31xx_set_bias_level(struct snd_soc_codec *codec,
...@@ -1137,14 +1179,11 @@ static int aic31xx_set_bias_level(struct snd_soc_codec *codec, ...@@ -1137,14 +1179,11 @@ static int aic31xx_set_bias_level(struct snd_soc_codec *codec,
static int aic31xx_codec_probe(struct snd_soc_codec *codec) static int aic31xx_codec_probe(struct snd_soc_codec *codec)
{ {
int ret = 0;
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
int i; int i, ret;
dev_dbg(aic31xx->dev, "## %s\n", __func__); dev_dbg(aic31xx->dev, "## %s\n", __func__);
aic31xx = snd_soc_codec_get_drvdata(codec);
aic31xx->codec = codec; aic31xx->codec = codec;
for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) { for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
...@@ -1169,8 +1208,10 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec) ...@@ -1169,8 +1208,10 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec)
return ret; return ret;
ret = aic31xx_add_widgets(codec); ret = aic31xx_add_widgets(codec);
if (ret)
return ret;
return ret; return 0;
} }
static int aic31xx_codec_remove(struct snd_soc_codec *codec) static int aic31xx_codec_remove(struct snd_soc_codec *codec)
...@@ -1258,89 +1299,31 @@ static const struct of_device_id tlv320aic31xx_of_match[] = { ...@@ -1258,89 +1299,31 @@ static const struct of_device_id tlv320aic31xx_of_match[] = {
{}, {},
}; };
MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match); MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match);
static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx)
{
struct device_node *np = aic31xx->dev->of_node;
unsigned int value = MICBIAS_2_0V;
int ret;
of_property_read_u32(np, "ai31xx-micbias-vg", &value);
switch (value) {
case MICBIAS_2_0V:
case MICBIAS_2_5V:
case MICBIAS_AVDDV:
aic31xx->pdata.micbias_vg = value;
break;
default:
dev_err(aic31xx->dev,
"Bad ai31xx-micbias-vg value %d DT\n",
value);
aic31xx->pdata.micbias_vg = MICBIAS_2_0V;
}
ret = of_get_named_gpio(np, "gpio-reset", 0);
if (ret > 0)
aic31xx->pdata.gpio_reset = ret;
}
#else /* CONFIG_OF */
static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx)
{
}
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
static int aic31xx_device_init(struct aic31xx_priv *aic31xx) #ifdef CONFIG_ACPI
{ static const struct acpi_device_id aic31xx_acpi_match[] = {
int ret, i; { "10TI3100", 0 },
{ }
dev_set_drvdata(aic31xx->dev, aic31xx); };
MODULE_DEVICE_TABLE(acpi, aic31xx_acpi_match);
if (dev_get_platdata(aic31xx->dev)) #endif
memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev),
sizeof(aic31xx->pdata));
else if (aic31xx->dev->of_node)
aic31xx_pdata_from_of(aic31xx);
if (aic31xx->pdata.gpio_reset) {
ret = devm_gpio_request_one(aic31xx->dev,
aic31xx->pdata.gpio_reset,
GPIOF_OUT_INIT_HIGH,
"aic31xx-reset-pin");
if (ret < 0) {
dev_err(aic31xx->dev, "not able to acquire gpio\n");
return ret;
}
}
for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
aic31xx->supplies[i].supply = aic31xx_supply_names[i];
ret = devm_regulator_bulk_get(aic31xx->dev,
ARRAY_SIZE(aic31xx->supplies),
aic31xx->supplies);
if (ret != 0)
dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret);
return ret;
}
static int aic31xx_i2c_probe(struct i2c_client *i2c, static int aic31xx_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct aic31xx_priv *aic31xx; struct aic31xx_priv *aic31xx;
int ret; unsigned int micbias_value = MICBIAS_2_0V;
const struct regmap_config *regmap_config; int i, ret;
dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__, dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__,
id->name, (int) id->driver_data); id->name, (int)id->driver_data);
regmap_config = &aic31xx_i2c_regmap;
aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL); aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL);
if (aic31xx == NULL) if (!aic31xx)
return -ENOMEM; return -ENOMEM;
aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config); aic31xx->regmap = devm_regmap_init_i2c(i2c, &aic31xx_i2c_regmap);
if (IS_ERR(aic31xx->regmap)) { if (IS_ERR(aic31xx->regmap)) {
ret = PTR_ERR(aic31xx->regmap); ret = PTR_ERR(aic31xx->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n", dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
...@@ -1349,13 +1332,49 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, ...@@ -1349,13 +1332,49 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
} }
aic31xx->dev = &i2c->dev; aic31xx->dev = &i2c->dev;
aic31xx->pdata.codec_type = id->driver_data; aic31xx->codec_type = id->driver_data;
ret = aic31xx_device_init(aic31xx); dev_set_drvdata(aic31xx->dev, aic31xx);
if (ret)
fwnode_property_read_u32(aic31xx->dev->fwnode, "ai31xx-micbias-vg",
&micbias_value);
switch (micbias_value) {
case MICBIAS_2_0V:
case MICBIAS_2_5V:
case MICBIAS_AVDDV:
aic31xx->micbias_vg = micbias_value;
break;
default:
dev_err(aic31xx->dev, "Bad ai31xx-micbias-vg value %d\n",
micbias_value);
aic31xx->micbias_vg = MICBIAS_2_0V;
}
if (dev_get_platdata(aic31xx->dev)) {
memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev), sizeof(aic31xx->pdata));
aic31xx->codec_type = aic31xx->pdata.codec_type;
aic31xx->micbias_vg = aic31xx->pdata.micbias_vg;
}
aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(aic31xx->gpio_reset)) {
dev_err(aic31xx->dev, "not able to acquire gpio\n");
return PTR_ERR(aic31xx->gpio_reset);
}
for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
aic31xx->supplies[i].supply = aic31xx_supply_names[i];
ret = devm_regulator_bulk_get(aic31xx->dev,
ARRAY_SIZE(aic31xx->supplies),
aic31xx->supplies);
if (ret) {
dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret);
return ret; return ret;
}
if (aic31xx->pdata.codec_type & DAC31XX_BIT) if (aic31xx->codec_type & DAC31XX_BIT)
return snd_soc_register_codec(&i2c->dev, return snd_soc_register_codec(&i2c->dev,
&soc_codec_driver_aic31xx, &soc_codec_driver_aic31xx,
dac31xx_dai_driver, dac31xx_dai_driver,
...@@ -1386,14 +1405,6 @@ static const struct i2c_device_id aic31xx_i2c_id[] = { ...@@ -1386,14 +1405,6 @@ static const struct i2c_device_id aic31xx_i2c_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id);
#ifdef CONFIG_ACPI
static const struct acpi_device_id aic31xx_acpi_match[] = {
{ "10TI3100", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, aic31xx_acpi_match);
#endif
static struct i2c_driver aic31xx_i2c_driver = { static struct i2c_driver aic31xx_i2c_driver = {
.driver = { .driver = {
.name = "tlv320aic31xx-codec", .name = "tlv320aic31xx-codec",
...@@ -1404,9 +1415,8 @@ static struct i2c_driver aic31xx_i2c_driver = { ...@@ -1404,9 +1415,8 @@ static struct i2c_driver aic31xx_i2c_driver = {
.remove = aic31xx_i2c_remove, .remove = aic31xx_i2c_remove,
.id_table = aic31xx_i2c_id, .id_table = aic31xx_i2c_id,
}; };
module_i2c_driver(aic31xx_i2c_driver); module_i2c_driver(aic31xx_i2c_driver);
MODULE_DESCRIPTION("ASoC TLV320AIC3111 codec driver"); MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
MODULE_AUTHOR("Jyri Sarha"); MODULE_DESCRIPTION("ASoC TLV320AIC31xx CODEC Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/* /*
* ALSA SoC TLV320AIC31XX codec driver * ALSA SoC TLV320AIC31xx CODEC Driver Definitions
*
* Copyright (C) 2013 Texas Instruments, Inc.
*
* This package 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.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* *
* Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
*/ */
#ifndef _TLV320AIC31XX_H #ifndef _TLV320AIC31XX_H
#define _TLV320AIC31XX_H #define _TLV320AIC31XX_H
#define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000 #define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000
#define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ #define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
| SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE \ SNDRV_PCM_FMTBIT_S20_3LE | \
| SNDRV_PCM_FMTBIT_S32_LE) SNDRV_PCM_FMTBIT_S24_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
#define AIC31XX_STEREO_CLASS_D_BIT 0x1 #define AIC31XX_STEREO_CLASS_D_BIT BIT(1)
#define AIC31XX_MINIDSP_BIT 0x2 #define AIC31XX_MINIDSP_BIT BIT(2)
#define DAC31XX_BIT 0x4 #define DAC31XX_BIT BIT(3)
enum aic31xx_type { enum aic31xx_type {
AIC3100 = 0, AIC3100 = 0,
AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, AIC3110 = AIC31XX_STEREO_CLASS_D_BIT,
AIC3120 = AIC31XX_MINIDSP_BIT, AIC3120 = AIC31XX_MINIDSP_BIT,
AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), AIC3111 = AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT,
DAC3100 = DAC31XX_BIT, DAC3100 = DAC31XX_BIT,
DAC3101 = DAC31XX_BIT | AIC31XX_STEREO_CLASS_D_BIT, DAC3101 = DAC31XX_BIT | AIC31XX_STEREO_CLASS_D_BIT,
}; };
...@@ -43,222 +37,167 @@ struct aic31xx_pdata { ...@@ -43,222 +37,167 @@ struct aic31xx_pdata {
#define AIC31XX_REG(page, reg) ((page * 128) + reg) #define AIC31XX_REG(page, reg) ((page * 128) + reg)
/* Page Control Register */ #define AIC31XX_PAGECTL AIC31XX_REG(0, 0) /* Page Control Register */
#define AIC31XX_PAGECTL AIC31XX_REG(0, 0)
/* Page 0 Registers */ /* Page 0 Registers */
/* Software reset register */ #define AIC31XX_RESET AIC31XX_REG(0, 1) /* Software reset register */
#define AIC31XX_RESET AIC31XX_REG(0, 1) #define AIC31XX_OT_FLAG AIC31XX_REG(0, 3) /* OT FLAG register */
/* OT FLAG register */ #define AIC31XX_CLKMUX AIC31XX_REG(0, 4) /* Clock clock Gen muxing, Multiplexers*/
#define AIC31XX_OT_FLAG AIC31XX_REG(0, 3) #define AIC31XX_PLLPR AIC31XX_REG(0, 5) /* PLL P and R-VAL register */
/* Clock clock Gen muxing, Multiplexers*/ #define AIC31XX_PLLJ AIC31XX_REG(0, 6) /* PLL J-VAL register */
#define AIC31XX_CLKMUX AIC31XX_REG(0, 4) #define AIC31XX_PLLDMSB AIC31XX_REG(0, 7) /* PLL D-VAL MSB register */
/* PLL P and R-VAL register */ #define AIC31XX_PLLDLSB AIC31XX_REG(0, 8) /* PLL D-VAL LSB register */
#define AIC31XX_PLLPR AIC31XX_REG(0, 5) #define AIC31XX_NDAC AIC31XX_REG(0, 11) /* DAC NDAC_VAL register*/
/* PLL J-VAL register */ #define AIC31XX_MDAC AIC31XX_REG(0, 12) /* DAC MDAC_VAL register */
#define AIC31XX_PLLJ AIC31XX_REG(0, 6) #define AIC31XX_DOSRMSB AIC31XX_REG(0, 13) /* DAC OSR setting register 1, MSB value */
/* PLL D-VAL MSB register */ #define AIC31XX_DOSRLSB AIC31XX_REG(0, 14) /* DAC OSR setting register 2, LSB value */
#define AIC31XX_PLLDMSB AIC31XX_REG(0, 7)
/* PLL D-VAL LSB register */
#define AIC31XX_PLLDLSB AIC31XX_REG(0, 8)
/* DAC NDAC_VAL register*/
#define AIC31XX_NDAC AIC31XX_REG(0, 11)
/* DAC MDAC_VAL register */
#define AIC31XX_MDAC AIC31XX_REG(0, 12)
/* DAC OSR setting register 1, MSB value */
#define AIC31XX_DOSRMSB AIC31XX_REG(0, 13)
/* DAC OSR setting register 2, LSB value */
#define AIC31XX_DOSRLSB AIC31XX_REG(0, 14)
#define AIC31XX_MINI_DSP_INPOL AIC31XX_REG(0, 16) #define AIC31XX_MINI_DSP_INPOL AIC31XX_REG(0, 16)
/* Clock setting register 8, PLL */ #define AIC31XX_NADC AIC31XX_REG(0, 18) /* Clock setting register 8, PLL */
#define AIC31XX_NADC AIC31XX_REG(0, 18) #define AIC31XX_MADC AIC31XX_REG(0, 19) /* Clock setting register 9, PLL */
/* Clock setting register 9, PLL */ #define AIC31XX_AOSR AIC31XX_REG(0, 20) /* ADC Oversampling (AOSR) Register */
#define AIC31XX_MADC AIC31XX_REG(0, 19) #define AIC31XX_CLKOUTMUX AIC31XX_REG(0, 25) /* Clock setting register 9, Multiplexers */
/* ADC Oversampling (AOSR) Register */ #define AIC31XX_CLKOUTMVAL AIC31XX_REG(0, 26) /* Clock setting register 10, CLOCKOUT M divider value */
#define AIC31XX_AOSR AIC31XX_REG(0, 20) #define AIC31XX_IFACE1 AIC31XX_REG(0, 27) /* Audio Interface Setting Register 1 */
/* Clock setting register 9, Multiplexers */ #define AIC31XX_DATA_OFFSET AIC31XX_REG(0, 28) /* Audio Data Slot Offset Programming */
#define AIC31XX_CLKOUTMUX AIC31XX_REG(0, 25) #define AIC31XX_IFACE2 AIC31XX_REG(0, 29) /* Audio Interface Setting Register 2 */
/* Clock setting register 10, CLOCKOUT M divider value */ #define AIC31XX_BCLKN AIC31XX_REG(0, 30) /* Clock setting register 11, BCLK N Divider */
#define AIC31XX_CLKOUTMVAL AIC31XX_REG(0, 26) #define AIC31XX_IFACESEC1 AIC31XX_REG(0, 31) /* Audio Interface Setting Register 3, Secondary Audio Interface */
/* Audio Interface Setting Register 1 */ #define AIC31XX_IFACESEC2 AIC31XX_REG(0, 32) /* Audio Interface Setting Register 4 */
#define AIC31XX_IFACE1 AIC31XX_REG(0, 27) #define AIC31XX_IFACESEC3 AIC31XX_REG(0, 33) /* Audio Interface Setting Register 5 */
/* Audio Data Slot Offset Programming */ #define AIC31XX_I2C AIC31XX_REG(0, 34) /* I2C Bus Condition */
#define AIC31XX_DATA_OFFSET AIC31XX_REG(0, 28) #define AIC31XX_ADCFLAG AIC31XX_REG(0, 36) /* ADC FLAG */
/* Audio Interface Setting Register 2 */ #define AIC31XX_DACFLAG1 AIC31XX_REG(0, 37) /* DAC Flag Registers */
#define AIC31XX_IFACE2 AIC31XX_REG(0, 29)
/* Clock setting register 11, BCLK N Divider */
#define AIC31XX_BCLKN AIC31XX_REG(0, 30)
/* Audio Interface Setting Register 3, Secondary Audio Interface */
#define AIC31XX_IFACESEC1 AIC31XX_REG(0, 31)
/* Audio Interface Setting Register 4 */
#define AIC31XX_IFACESEC2 AIC31XX_REG(0, 32)
/* Audio Interface Setting Register 5 */
#define AIC31XX_IFACESEC3 AIC31XX_REG(0, 33)
/* I2C Bus Condition */
#define AIC31XX_I2C AIC31XX_REG(0, 34)
/* ADC FLAG */
#define AIC31XX_ADCFLAG AIC31XX_REG(0, 36)
/* DAC Flag Registers */
#define AIC31XX_DACFLAG1 AIC31XX_REG(0, 37)
#define AIC31XX_DACFLAG2 AIC31XX_REG(0, 38) #define AIC31XX_DACFLAG2 AIC31XX_REG(0, 38)
/* Sticky Interrupt flag (overflow) */ #define AIC31XX_OFFLAG AIC31XX_REG(0, 39) /* Sticky Interrupt flag (overflow) */
#define AIC31XX_OFFLAG AIC31XX_REG(0, 39) #define AIC31XX_INTRDACFLAG AIC31XX_REG(0, 44) /* Sticy DAC Interrupt flags */
/* Sticy DAC Interrupt flags */ #define AIC31XX_INTRADCFLAG AIC31XX_REG(0, 45) /* Sticy ADC Interrupt flags */
#define AIC31XX_INTRDACFLAG AIC31XX_REG(0, 44) #define AIC31XX_INTRDACFLAG2 AIC31XX_REG(0, 46) /* DAC Interrupt flags 2 */
/* Sticy ADC Interrupt flags */ #define AIC31XX_INTRADCFLAG2 AIC31XX_REG(0, 47) /* ADC Interrupt flags 2 */
#define AIC31XX_INTRADCFLAG AIC31XX_REG(0, 45) #define AIC31XX_INT1CTRL AIC31XX_REG(0, 48) /* INT1 interrupt control */
/* DAC Interrupt flags 2 */ #define AIC31XX_INT2CTRL AIC31XX_REG(0, 49) /* INT2 interrupt control */
#define AIC31XX_INTRDACFLAG2 AIC31XX_REG(0, 46) #define AIC31XX_GPIO1 AIC31XX_REG(0, 51) /* GPIO1 control */
/* ADC Interrupt flags 2 */
#define AIC31XX_INTRADCFLAG2 AIC31XX_REG(0, 47)
/* INT1 interrupt control */
#define AIC31XX_INT1CTRL AIC31XX_REG(0, 48)
/* INT2 interrupt control */
#define AIC31XX_INT2CTRL AIC31XX_REG(0, 49)
/* GPIO1 control */
#define AIC31XX_GPIO1 AIC31XX_REG(0, 51)
#define AIC31XX_DACPRB AIC31XX_REG(0, 60) #define AIC31XX_DACPRB AIC31XX_REG(0, 60)
/* ADC Instruction Set Register */ #define AIC31XX_ADCPRB AIC31XX_REG(0, 61) /* ADC Instruction Set Register */
#define AIC31XX_ADCPRB AIC31XX_REG(0, 61) #define AIC31XX_DACSETUP AIC31XX_REG(0, 63) /* DAC channel setup register */
/* DAC channel setup register */ #define AIC31XX_DACMUTE AIC31XX_REG(0, 64) /* DAC Mute and volume control register */
#define AIC31XX_DACSETUP AIC31XX_REG(0, 63) #define AIC31XX_LDACVOL AIC31XX_REG(0, 65) /* Left DAC channel digital volume control */
/* DAC Mute and volume control register */ #define AIC31XX_RDACVOL AIC31XX_REG(0, 66) /* Right DAC channel digital volume control */
#define AIC31XX_DACMUTE AIC31XX_REG(0, 64) #define AIC31XX_HSDETECT AIC31XX_REG(0, 67) /* Headset detection */
/* Left DAC channel digital volume control */ #define AIC31XX_ADCSETUP AIC31XX_REG(0, 81) /* ADC Digital Mic */
#define AIC31XX_LDACVOL AIC31XX_REG(0, 65) #define AIC31XX_ADCFGA AIC31XX_REG(0, 82) /* ADC Digital Volume Control Fine Adjust */
/* Right DAC channel digital volume control */ #define AIC31XX_ADCVOL AIC31XX_REG(0, 83) /* ADC Digital Volume Control Coarse Adjust */
#define AIC31XX_RDACVOL AIC31XX_REG(0, 66)
/* Headset detection */
#define AIC31XX_HSDETECT AIC31XX_REG(0, 67)
/* ADC Digital Mic */
#define AIC31XX_ADCSETUP AIC31XX_REG(0, 81)
/* ADC Digital Volume Control Fine Adjust */
#define AIC31XX_ADCFGA AIC31XX_REG(0, 82)
/* ADC Digital Volume Control Coarse Adjust */
#define AIC31XX_ADCVOL AIC31XX_REG(0, 83)
/* Page 1 Registers */ /* Page 1 Registers */
/* Headphone drivers */ #define AIC31XX_HPDRIVER AIC31XX_REG(1, 31) /* Headphone drivers */
#define AIC31XX_HPDRIVER AIC31XX_REG(1, 31) #define AIC31XX_SPKAMP AIC31XX_REG(1, 32) /* Class-D Speakear Amplifier */
/* Class-D Speakear Amplifier */ #define AIC31XX_HPPOP AIC31XX_REG(1, 33) /* HP Output Drivers POP Removal Settings */
#define AIC31XX_SPKAMP AIC31XX_REG(1, 32) #define AIC31XX_SPPGARAMP AIC31XX_REG(1, 34) /* Output Driver PGA Ramp-Down Period Control */
/* HP Output Drivers POP Removal Settings */ #define AIC31XX_DACMIXERROUTE AIC31XX_REG(1, 35) /* DAC_L and DAC_R Output Mixer Routing */
#define AIC31XX_HPPOP AIC31XX_REG(1, 33) #define AIC31XX_LANALOGHPL AIC31XX_REG(1, 36) /* Left Analog Vol to HPL */
/* Output Driver PGA Ramp-Down Period Control */ #define AIC31XX_RANALOGHPR AIC31XX_REG(1, 37) /* Right Analog Vol to HPR */
#define AIC31XX_SPPGARAMP AIC31XX_REG(1, 34) #define AIC31XX_LANALOGSPL AIC31XX_REG(1, 38) /* Left Analog Vol to SPL */
/* DAC_L and DAC_R Output Mixer Routing */ #define AIC31XX_RANALOGSPR AIC31XX_REG(1, 39) /* Right Analog Vol to SPR */
#define AIC31XX_DACMIXERROUTE AIC31XX_REG(1, 35) #define AIC31XX_HPLGAIN AIC31XX_REG(1, 40) /* HPL Driver */
/* Left Analog Vol to HPL */ #define AIC31XX_HPRGAIN AIC31XX_REG(1, 41) /* HPR Driver */
#define AIC31XX_LANALOGHPL AIC31XX_REG(1, 36) #define AIC31XX_SPLGAIN AIC31XX_REG(1, 42) /* SPL Driver */
/* Right Analog Vol to HPR */ #define AIC31XX_SPRGAIN AIC31XX_REG(1, 43) /* SPR Driver */
#define AIC31XX_RANALOGHPR AIC31XX_REG(1, 37) #define AIC31XX_HPCONTROL AIC31XX_REG(1, 44) /* HP Driver Control */
/* Left Analog Vol to SPL */ #define AIC31XX_MICBIAS AIC31XX_REG(1, 46) /* MIC Bias Control */
#define AIC31XX_LANALOGSPL AIC31XX_REG(1, 38) #define AIC31XX_MICPGA AIC31XX_REG(1, 47) /* MIC PGA*/
/* Right Analog Vol to SPR */ #define AIC31XX_MICPGAPI AIC31XX_REG(1, 48) /* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */
#define AIC31XX_RANALOGSPR AIC31XX_REG(1, 39) #define AIC31XX_MICPGAMI AIC31XX_REG(1, 49) /* ADC Input Selection for M-Terminal */
/* HPL Driver */ #define AIC31XX_MICPGACM AIC31XX_REG(1, 50) /* Input CM Settings */
#define AIC31XX_HPLGAIN AIC31XX_REG(1, 40)
/* HPR Driver */ /* Bits, masks, and shifts */
#define AIC31XX_HPRGAIN AIC31XX_REG(1, 41)
/* SPL Driver */
#define AIC31XX_SPLGAIN AIC31XX_REG(1, 42)
/* SPR Driver */
#define AIC31XX_SPRGAIN AIC31XX_REG(1, 43)
/* HP Driver Control */
#define AIC31XX_HPCONTROL AIC31XX_REG(1, 44)
/* MIC Bias Control */
#define AIC31XX_MICBIAS AIC31XX_REG(1, 46)
/* MIC PGA*/
#define AIC31XX_MICPGA AIC31XX_REG(1, 47)
/* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */
#define AIC31XX_MICPGAPI AIC31XX_REG(1, 48)
/* ADC Input Selection for M-Terminal */
#define AIC31XX_MICPGAMI AIC31XX_REG(1, 49)
/* Input CM Settings */
#define AIC31XX_MICPGACM AIC31XX_REG(1, 50)
/* Bits, masks and shifts */
/* AIC31XX_CLKMUX */ /* AIC31XX_CLKMUX */
#define AIC31XX_PLL_CLKIN_MASK 0x0c #define AIC31XX_PLL_CLKIN_MASK GENMASK(3, 2)
#define AIC31XX_PLL_CLKIN_SHIFT 2 #define AIC31XX_PLL_CLKIN_SHIFT (2)
#define AIC31XX_PLL_CLKIN_MCLK 0 #define AIC31XX_PLL_CLKIN_MCLK 0x00
#define AIC31XX_CODEC_CLKIN_MASK 0x03 #define AIC31XX_PLL_CLKIN_BCKL 0x01
#define AIC31XX_CODEC_CLKIN_SHIFT 0 #define AIC31XX_PLL_CLKIN_GPIO1 0x02
#define AIC31XX_CODEC_CLKIN_PLL 3 #define AIC31XX_PLL_CLKIN_DIN 0x03
#define AIC31XX_CODEC_CLKIN_BCLK 1 #define AIC31XX_CODEC_CLKIN_MASK GENMASK(1, 0)
#define AIC31XX_CODEC_CLKIN_SHIFT (0)
/* AIC31XX_PLLPR, AIC31XX_NDAC, AIC31XX_MDAC, AIC31XX_NADC, AIC31XX_MADC, #define AIC31XX_CODEC_CLKIN_MCLK 0x00
AIC31XX_BCLKN */ #define AIC31XX_CODEC_CLKIN_BCLK 0x01
#define AIC31XX_PLL_MASK 0x7f #define AIC31XX_CODEC_CLKIN_GPIO1 0x02
#define AIC31XX_PM_MASK 0x80 #define AIC31XX_CODEC_CLKIN_PLL 0x03
/* AIC31XX_PLLPR */
/* AIC31XX_NDAC */
/* AIC31XX_MDAC */
/* AIC31XX_NADC */
/* AIC31XX_MADC */
/* AIC31XX_BCLKN */
#define AIC31XX_PLL_MASK GENMASK(6, 0)
#define AIC31XX_PM_MASK BIT(7)
/* AIC31XX_IFACE1 */ /* AIC31XX_IFACE1 */
#define AIC31XX_WORD_LEN_16BITS 0x00 #define AIC31XX_IFACE1_DATATYPE_MASK GENMASK(7, 6)
#define AIC31XX_WORD_LEN_20BITS 0x01
#define AIC31XX_WORD_LEN_24BITS 0x02
#define AIC31XX_WORD_LEN_32BITS 0x03
#define AIC31XX_IFACE1_DATALEN_MASK 0x30
#define AIC31XX_IFACE1_DATALEN_SHIFT (4)
#define AIC31XX_IFACE1_DATATYPE_MASK 0xC0
#define AIC31XX_IFACE1_DATATYPE_SHIFT (6) #define AIC31XX_IFACE1_DATATYPE_SHIFT (6)
#define AIC31XX_I2S_MODE 0x00 #define AIC31XX_I2S_MODE 0x00
#define AIC31XX_DSP_MODE 0x01 #define AIC31XX_DSP_MODE 0x01
#define AIC31XX_RIGHT_JUSTIFIED_MODE 0x02 #define AIC31XX_RIGHT_JUSTIFIED_MODE 0x02
#define AIC31XX_LEFT_JUSTIFIED_MODE 0x03 #define AIC31XX_LEFT_JUSTIFIED_MODE 0x03
#define AIC31XX_IFACE1_MASTER_MASK 0x0C #define AIC31XX_IFACE1_DATALEN_MASK GENMASK(5, 4)
#define AIC31XX_BCLK_MASTER 0x08 #define AIC31XX_IFACE1_DATALEN_SHIFT (4)
#define AIC31XX_WCLK_MASTER 0x04 #define AIC31XX_WORD_LEN_16BITS 0x00
#define AIC31XX_WORD_LEN_20BITS 0x01
#define AIC31XX_WORD_LEN_24BITS 0x02
#define AIC31XX_WORD_LEN_32BITS 0x03
#define AIC31XX_IFACE1_MASTER_MASK GENMASK(3, 2)
#define AIC31XX_BCLK_MASTER BIT(2)
#define AIC31XX_WCLK_MASTER BIT(3)
/* AIC31XX_DATA_OFFSET */ /* AIC31XX_DATA_OFFSET */
#define AIC31XX_DATA_OFFSET_MASK 0xFF #define AIC31XX_DATA_OFFSET_MASK GENMASK(7, 0)
/* AIC31XX_IFACE2 */ /* AIC31XX_IFACE2 */
#define AIC31XX_BCLKINV_MASK 0x08 #define AIC31XX_BCLKINV_MASK BIT(3)
#define AIC31XX_BDIVCLK_MASK 0x03 #define AIC31XX_BDIVCLK_MASK GENMASK(1, 0)
#define AIC31XX_DAC2BCLK 0x00 #define AIC31XX_DAC2BCLK 0x00
#define AIC31XX_DACMOD2BCLK 0x01 #define AIC31XX_DACMOD2BCLK 0x01
#define AIC31XX_ADC2BCLK 0x02 #define AIC31XX_ADC2BCLK 0x02
#define AIC31XX_ADCMOD2BCLK 0x03 #define AIC31XX_ADCMOD2BCLK 0x03
/* AIC31XX_ADCFLAG */ /* AIC31XX_ADCFLAG */
#define AIC31XX_ADCPWRSTATUS_MASK 0x40 #define AIC31XX_ADCPWRSTATUS_MASK BIT(6)
/* AIC31XX_DACFLAG1 */ /* AIC31XX_DACFLAG1 */
#define AIC31XX_LDACPWRSTATUS_MASK 0x80 #define AIC31XX_LDACPWRSTATUS_MASK BIT(7)
#define AIC31XX_RDACPWRSTATUS_MASK 0x08 #define AIC31XX_HPLDRVPWRSTATUS_MASK BIT(5)
#define AIC31XX_HPLDRVPWRSTATUS_MASK 0x20 #define AIC31XX_SPLDRVPWRSTATUS_MASK BIT(4)
#define AIC31XX_HPRDRVPWRSTATUS_MASK 0x02 #define AIC31XX_RDACPWRSTATUS_MASK BIT(3)
#define AIC31XX_SPLDRVPWRSTATUS_MASK 0x10 #define AIC31XX_HPRDRVPWRSTATUS_MASK BIT(1)
#define AIC31XX_SPRDRVPWRSTATUS_MASK 0x01 #define AIC31XX_SPRDRVPWRSTATUS_MASK BIT(0)
/* AIC31XX_INTRDACFLAG */ /* AIC31XX_INTRDACFLAG */
#define AIC31XX_HPSCDETECT_MASK 0x80 #define AIC31XX_HPLSCDETECT BIT(7)
#define AIC31XX_BUTTONPRESS_MASK 0x20 #define AIC31XX_HPRSCDETECT BIT(6)
#define AIC31XX_HSPLUG_MASK 0x10 #define AIC31XX_BUTTONPRESS BIT(5)
#define AIC31XX_LDRCTHRES_MASK 0x08 #define AIC31XX_HSPLUG BIT(4)
#define AIC31XX_RDRCTHRES_MASK 0x04 #define AIC31XX_LDRCTHRES BIT(3)
#define AIC31XX_DACSINT_MASK 0x02 #define AIC31XX_RDRCTHRES BIT(2)
#define AIC31XX_DACAINT_MASK 0x01 #define AIC31XX_DACSINT BIT(1)
#define AIC31XX_DACAINT BIT(0)
/* AIC31XX_INT1CTRL */ /* AIC31XX_INT1CTRL */
#define AIC31XX_HSPLUGDET_MASK 0x80 #define AIC31XX_HSPLUGDET BIT(7)
#define AIC31XX_BUTTONPRESSDET_MASK 0x40 #define AIC31XX_BUTTONPRESSDET BIT(6)
#define AIC31XX_DRCTHRES_MASK 0x20 #define AIC31XX_DRCTHRES BIT(5)
#define AIC31XX_AGCNOISE_MASK 0x10 #define AIC31XX_AGCNOISE BIT(4)
#define AIC31XX_OC_MASK 0x08 #define AIC31XX_SC BIT(3)
#define AIC31XX_ENGINE_MASK 0x04 #define AIC31XX_ENGINE BIT(2)
/* AIC31XX_DACSETUP */ /* AIC31XX_DACSETUP */
#define AIC31XX_SOFTSTEP_MASK 0x03 #define AIC31XX_SOFTSTEP_MASK GENMASK(1, 0)
/* AIC31XX_DACMUTE */ /* AIC31XX_DACMUTE */
#define AIC31XX_DACMUTE_MASK 0x0C #define AIC31XX_DACMUTE_MASK GENMASK(3, 2)
/* AIC31XX_MICBIAS */ /* AIC31XX_MICBIAS */
#define AIC31XX_MICBIAS_MASK 0x03 #define AIC31XX_MICBIAS_MASK GENMASK(1, 0)
#define AIC31XX_MICBIAS_SHIFT 0 #define AIC31XX_MICBIAS_SHIFT 0
#endif /* _TLV320AIC31XX_H */ #endif /* _TLV320AIC31XX_H */
...@@ -281,34 +281,34 @@ static const struct snd_kcontrol_new aic32x4_snd_controls[] = { ...@@ -281,34 +281,34 @@ static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
static const struct aic32x4_rate_divs aic32x4_divs[] = { static const struct aic32x4_rate_divs aic32x4_divs[] = {
/* 8k rate */ /* 8k rate */
{AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24}, {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
{AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24}, {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
{AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24}, {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
/* 11.025k rate */ /* 11.025k rate */
{AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16}, {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
{AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16}, {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
/* 16k rate */ /* 16k rate */
{AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12}, {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
{AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12}, {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
{AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12}, {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
/* 22.05k rate */ /* 22.05k rate */
{AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8}, {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
{AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8}, {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
{AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8}, {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
/* 32k rate */ /* 32k rate */
{AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6}, {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
{AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6}, {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
/* 44.1k rate */ /* 44.1k rate */
{AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4}, {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
{AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4}, {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
{AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4}, {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
/* 48k rate */ /* 48k rate */
{AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4}, {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
{AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4}, {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
{AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}, {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4},
/* 96k rate */ /* 96k rate */
{AIC32X4_FREQ_25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1}, {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1},
}; };
static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
...@@ -601,9 +601,9 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, ...@@ -601,9 +601,9 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
switch (freq) { switch (freq) {
case AIC32X4_FREQ_12000000: case 12000000:
case AIC32X4_FREQ_24000000: case 24000000:
case AIC32X4_FREQ_25000000: case 25000000:
aic32x4->sysclk = freq; aic32x4->sysclk = freq;
return 0; return 0;
} }
...@@ -614,16 +614,9 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, ...@@ -614,16 +614,9 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
u8 iface_reg_1; u8 iface_reg_1 = 0;
u8 iface_reg_2; u8 iface_reg_2 = 0;
u8 iface_reg_3; u8 iface_reg_3 = 0;
iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
iface_reg_2 = 0;
iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
iface_reg_3 = iface_reg_3 & ~(1 << 3);
/* set master/slave audio interface */ /* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
...@@ -641,30 +634,37 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ...@@ -641,30 +634,37 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT); iface_reg_1 |= (AIC32X4_DSP_MODE <<
iface_reg_3 |= (1 << 3); /* invert bit clock */ AIC32X4_IFACE1_DATATYPE_SHIFT);
iface_reg_3 |= AIC32X4_BCLKINV_MASK; /* invert bit clock */
iface_reg_2 = 0x01; /* add offset 1 */ iface_reg_2 = 0x01; /* add offset 1 */
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT); iface_reg_1 |= (AIC32X4_DSP_MODE <<
iface_reg_3 |= (1 << 3); /* invert bit clock */ AIC32X4_IFACE1_DATATYPE_SHIFT);
iface_reg_3 |= AIC32X4_BCLKINV_MASK; /* invert bit clock */
break; break;
case SND_SOC_DAIFMT_RIGHT_J: case SND_SOC_DAIFMT_RIGHT_J:
iface_reg_1 |= iface_reg_1 |= (AIC32X4_RIGHT_JUSTIFIED_MODE <<
(AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT); AIC32X4_IFACE1_DATATYPE_SHIFT);
break; break;
case SND_SOC_DAIFMT_LEFT_J: case SND_SOC_DAIFMT_LEFT_J:
iface_reg_1 |= iface_reg_1 |= (AIC32X4_LEFT_JUSTIFIED_MODE <<
(AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT); AIC32X4_IFACE1_DATATYPE_SHIFT);
break; break;
default: default:
printk(KERN_ERR "aic32x4: invalid DAI interface format\n"); printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
return -EINVAL; return -EINVAL;
} }
snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1); snd_soc_update_bits(codec, AIC32X4_IFACE1,
snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2); AIC32X4_IFACE1_DATATYPE_MASK |
snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3); AIC32X4_IFACE1_MASTER_MASK, iface_reg_1);
snd_soc_update_bits(codec, AIC32X4_IFACE2,
AIC32X4_DATA_OFFSET_MASK, iface_reg_2);
snd_soc_update_bits(codec, AIC32X4_IFACE3,
AIC32X4_BCLKINV_MASK, iface_reg_3);
return 0; return 0;
} }
...@@ -674,7 +674,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream, ...@@ -674,7 +674,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
u8 data; u8 iface1_reg = 0;
u8 dacsetup_reg = 0;
int i; int i;
i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params)); i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
...@@ -683,82 +684,88 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream, ...@@ -683,82 +684,88 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
return i; return i;
} }
/* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */ /* MCLK as PLL_CLKIN */
snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN); snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK,
snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK); AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT);
/* PLL as CODEC_CLKIN */
snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK,
AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT);
/* DAC_MOD_CLK as BDIV_CLKIN */
snd_soc_update_bits(codec, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK,
AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT);
/* We will fix R value to 1 and will make P & J=K.D as variable */
snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01);
/* We will fix R value to 1 and will make P & J=K.D as varialble */ /* PLL P value */
data = snd_soc_read(codec, AIC32X4_PLLPR); snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK,
data &= ~(7 << 4); aic32x4_divs[i].p_val << AIC32X4_PLL_P_SHIFT);
snd_soc_write(codec, AIC32X4_PLLPR,
(data | (aic32x4_divs[i].p_val << 4) | 0x01));
/* PLL J value */
snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j); snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
/* PLL D value */
snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8)); snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
snd_soc_write(codec, AIC32X4_PLLDLSB, snd_soc_write(codec, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff));
(aic32x4_divs[i].pll_d & 0xff));
/* NDAC divider value */ /* NDAC divider value */
data = snd_soc_read(codec, AIC32X4_NDAC); snd_soc_update_bits(codec, AIC32X4_NDAC,
data &= ~(0x7f); AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac);
snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
/* MDAC divider value */ /* MDAC divider value */
data = snd_soc_read(codec, AIC32X4_MDAC); snd_soc_update_bits(codec, AIC32X4_MDAC,
data &= ~(0x7f); AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac);
snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
/* DOSR MSB & LSB values */ /* DOSR MSB & LSB values */
snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
snd_soc_write(codec, AIC32X4_DOSRLSB, snd_soc_write(codec, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff));
(aic32x4_divs[i].dosr & 0xff));
/* NADC divider value */ /* NADC divider value */
data = snd_soc_read(codec, AIC32X4_NADC); snd_soc_update_bits(codec, AIC32X4_NADC,
data &= ~(0x7f); AIC32X4_NADC_MASK, aic32x4_divs[i].nadc);
snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
/* MADC divider value */ /* MADC divider value */
data = snd_soc_read(codec, AIC32X4_MADC); snd_soc_update_bits(codec, AIC32X4_MADC,
data &= ~(0x7f); AIC32X4_MADC_MASK, aic32x4_divs[i].madc);
snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
/* AOSR value */ /* AOSR value */
snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr); snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
/* BCLK N divider */ /* BCLK N divider */
data = snd_soc_read(codec, AIC32X4_BCLKN); snd_soc_update_bits(codec, AIC32X4_BCLKN,
data &= ~(0x7f); AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N);
snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
data = snd_soc_read(codec, AIC32X4_IFACE1);
data = data & ~(3 << 4);
switch (params_width(params)) { switch (params_width(params)) {
case 16: case 16:
iface1_reg |= (AIC32X4_WORD_LEN_16BITS <<
AIC32X4_IFACE1_DATALEN_SHIFT);
break; break;
case 20: case 20:
data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT); iface1_reg |= (AIC32X4_WORD_LEN_20BITS <<
AIC32X4_IFACE1_DATALEN_SHIFT);
break; break;
case 24: case 24:
data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT); iface1_reg |= (AIC32X4_WORD_LEN_24BITS <<
AIC32X4_IFACE1_DATALEN_SHIFT);
break; break;
case 32: case 32:
data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT); iface1_reg |= (AIC32X4_WORD_LEN_32BITS <<
AIC32X4_IFACE1_DATALEN_SHIFT);
break; break;
} }
snd_soc_write(codec, AIC32X4_IFACE1, data); snd_soc_update_bits(codec, AIC32X4_IFACE1,
AIC32X4_IFACE1_DATALEN_MASK, iface1_reg);
if (params_channels(params) == 1) { if (params_channels(params) == 1) {
data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN; dacsetup_reg = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN;
} else { } else {
if (aic32x4->swapdacs) if (aic32x4->swapdacs)
data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2RCHN; dacsetup_reg = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2RCHN;
else else
data = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN; dacsetup_reg = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN;
} }
snd_soc_update_bits(codec, AIC32X4_DACSETUP, AIC32X4_DAC_CHAN_MASK, snd_soc_update_bits(codec, AIC32X4_DACSETUP,
data); AIC32X4_DAC_CHAN_MASK, dacsetup_reg);
return 0; return 0;
} }
...@@ -766,13 +773,10 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream, ...@@ -766,13 +773,10 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
static int aic32x4_mute(struct snd_soc_dai *dai, int mute) static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
u8 dac_reg;
dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON; snd_soc_update_bits(codec, AIC32X4_DACMUTE,
if (mute) AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0);
snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
else
snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);
return 0; return 0;
} }
......
...@@ -19,141 +19,189 @@ int aic32x4_remove(struct device *dev); ...@@ -19,141 +19,189 @@ int aic32x4_remove(struct device *dev);
/* tlv320aic32x4 register space (in decimal to match datasheet) */ /* tlv320aic32x4 register space (in decimal to match datasheet) */
#define AIC32X4_PAGE1 128 #define AIC32X4_REG(page, reg) ((page * 128) + reg)
#define AIC32X4_PSEL 0 #define AIC32X4_PSEL AIC32X4_REG(0, 0)
#define AIC32X4_RESET 1
#define AIC32X4_CLKMUX 4 #define AIC32X4_RESET AIC32X4_REG(0, 1)
#define AIC32X4_PLLPR 5 #define AIC32X4_CLKMUX AIC32X4_REG(0, 4)
#define AIC32X4_PLLJ 6 #define AIC32X4_PLLPR AIC32X4_REG(0, 5)
#define AIC32X4_PLLDMSB 7 #define AIC32X4_PLLJ AIC32X4_REG(0, 6)
#define AIC32X4_PLLDLSB 8 #define AIC32X4_PLLDMSB AIC32X4_REG(0, 7)
#define AIC32X4_NDAC 11 #define AIC32X4_PLLDLSB AIC32X4_REG(0, 8)
#define AIC32X4_MDAC 12 #define AIC32X4_NDAC AIC32X4_REG(0, 11)
#define AIC32X4_DOSRMSB 13 #define AIC32X4_MDAC AIC32X4_REG(0, 12)
#define AIC32X4_DOSRLSB 14 #define AIC32X4_DOSRMSB AIC32X4_REG(0, 13)
#define AIC32X4_NADC 18 #define AIC32X4_DOSRLSB AIC32X4_REG(0, 14)
#define AIC32X4_MADC 19 #define AIC32X4_NADC AIC32X4_REG(0, 18)
#define AIC32X4_AOSR 20 #define AIC32X4_MADC AIC32X4_REG(0, 19)
#define AIC32X4_CLKMUX2 25 #define AIC32X4_AOSR AIC32X4_REG(0, 20)
#define AIC32X4_CLKOUTM 26 #define AIC32X4_CLKMUX2 AIC32X4_REG(0, 25)
#define AIC32X4_IFACE1 27 #define AIC32X4_CLKOUTM AIC32X4_REG(0, 26)
#define AIC32X4_IFACE2 28 #define AIC32X4_IFACE1 AIC32X4_REG(0, 27)
#define AIC32X4_IFACE3 29 #define AIC32X4_IFACE2 AIC32X4_REG(0, 28)
#define AIC32X4_BCLKN 30 #define AIC32X4_IFACE3 AIC32X4_REG(0, 29)
#define AIC32X4_IFACE4 31 #define AIC32X4_BCLKN AIC32X4_REG(0, 30)
#define AIC32X4_IFACE5 32 #define AIC32X4_IFACE4 AIC32X4_REG(0, 31)
#define AIC32X4_IFACE6 33 #define AIC32X4_IFACE5 AIC32X4_REG(0, 32)
#define AIC32X4_GPIOCTL 52 #define AIC32X4_IFACE6 AIC32X4_REG(0, 33)
#define AIC32X4_DOUTCTL 53 #define AIC32X4_GPIOCTL AIC32X4_REG(0, 52)
#define AIC32X4_DINCTL 54 #define AIC32X4_DOUTCTL AIC32X4_REG(0, 53)
#define AIC32X4_MISOCTL 55 #define AIC32X4_DINCTL AIC32X4_REG(0, 54)
#define AIC32X4_SCLKCTL 56 #define AIC32X4_MISOCTL AIC32X4_REG(0, 55)
#define AIC32X4_DACSPB 60 #define AIC32X4_SCLKCTL AIC32X4_REG(0, 56)
#define AIC32X4_ADCSPB 61 #define AIC32X4_DACSPB AIC32X4_REG(0, 60)
#define AIC32X4_DACSETUP 63 #define AIC32X4_ADCSPB AIC32X4_REG(0, 61)
#define AIC32X4_DACMUTE 64 #define AIC32X4_DACSETUP AIC32X4_REG(0, 63)
#define AIC32X4_LDACVOL 65 #define AIC32X4_DACMUTE AIC32X4_REG(0, 64)
#define AIC32X4_RDACVOL 66 #define AIC32X4_LDACVOL AIC32X4_REG(0, 65)
#define AIC32X4_ADCSETUP 81 #define AIC32X4_RDACVOL AIC32X4_REG(0, 66)
#define AIC32X4_ADCFGA 82 #define AIC32X4_ADCSETUP AIC32X4_REG(0, 81)
#define AIC32X4_LADCVOL 83 #define AIC32X4_ADCFGA AIC32X4_REG(0, 82)
#define AIC32X4_RADCVOL 84 #define AIC32X4_LADCVOL AIC32X4_REG(0, 83)
#define AIC32X4_LAGC1 86 #define AIC32X4_RADCVOL AIC32X4_REG(0, 84)
#define AIC32X4_LAGC2 87 #define AIC32X4_LAGC1 AIC32X4_REG(0, 86)
#define AIC32X4_LAGC3 88 #define AIC32X4_LAGC2 AIC32X4_REG(0, 87)
#define AIC32X4_LAGC4 89 #define AIC32X4_LAGC3 AIC32X4_REG(0, 88)
#define AIC32X4_LAGC5 90 #define AIC32X4_LAGC4 AIC32X4_REG(0, 89)
#define AIC32X4_LAGC6 91 #define AIC32X4_LAGC5 AIC32X4_REG(0, 90)
#define AIC32X4_LAGC7 92 #define AIC32X4_LAGC6 AIC32X4_REG(0, 91)
#define AIC32X4_RAGC1 94 #define AIC32X4_LAGC7 AIC32X4_REG(0, 92)
#define AIC32X4_RAGC2 95 #define AIC32X4_RAGC1 AIC32X4_REG(0, 94)
#define AIC32X4_RAGC3 96 #define AIC32X4_RAGC2 AIC32X4_REG(0, 95)
#define AIC32X4_RAGC4 97 #define AIC32X4_RAGC3 AIC32X4_REG(0, 96)
#define AIC32X4_RAGC5 98 #define AIC32X4_RAGC4 AIC32X4_REG(0, 97)
#define AIC32X4_RAGC6 99 #define AIC32X4_RAGC5 AIC32X4_REG(0, 98)
#define AIC32X4_RAGC7 100 #define AIC32X4_RAGC6 AIC32X4_REG(0, 99)
#define AIC32X4_PWRCFG (AIC32X4_PAGE1 + 1) #define AIC32X4_RAGC7 AIC32X4_REG(0, 100)
#define AIC32X4_LDOCTL (AIC32X4_PAGE1 + 2)
#define AIC32X4_OUTPWRCTL (AIC32X4_PAGE1 + 9) #define AIC32X4_PWRCFG AIC32X4_REG(1, 1)
#define AIC32X4_CMMODE (AIC32X4_PAGE1 + 10) #define AIC32X4_LDOCTL AIC32X4_REG(1, 2)
#define AIC32X4_HPLROUTE (AIC32X4_PAGE1 + 12) #define AIC32X4_OUTPWRCTL AIC32X4_REG(1, 9)
#define AIC32X4_HPRROUTE (AIC32X4_PAGE1 + 13) #define AIC32X4_CMMODE AIC32X4_REG(1, 10)
#define AIC32X4_LOLROUTE (AIC32X4_PAGE1 + 14) #define AIC32X4_HPLROUTE AIC32X4_REG(1, 12)
#define AIC32X4_LORROUTE (AIC32X4_PAGE1 + 15) #define AIC32X4_HPRROUTE AIC32X4_REG(1, 13)
#define AIC32X4_HPLGAIN (AIC32X4_PAGE1 + 16) #define AIC32X4_LOLROUTE AIC32X4_REG(1, 14)
#define AIC32X4_HPRGAIN (AIC32X4_PAGE1 + 17) #define AIC32X4_LORROUTE AIC32X4_REG(1, 15)
#define AIC32X4_LOLGAIN (AIC32X4_PAGE1 + 18) #define AIC32X4_HPLGAIN AIC32X4_REG(1, 16)
#define AIC32X4_LORGAIN (AIC32X4_PAGE1 + 19) #define AIC32X4_HPRGAIN AIC32X4_REG(1, 17)
#define AIC32X4_HEADSTART (AIC32X4_PAGE1 + 20) #define AIC32X4_LOLGAIN AIC32X4_REG(1, 18)
#define AIC32X4_MICBIAS (AIC32X4_PAGE1 + 51) #define AIC32X4_LORGAIN AIC32X4_REG(1, 19)
#define AIC32X4_LMICPGAPIN (AIC32X4_PAGE1 + 52) #define AIC32X4_HEADSTART AIC32X4_REG(1, 20)
#define AIC32X4_LMICPGANIN (AIC32X4_PAGE1 + 54) #define AIC32X4_MICBIAS AIC32X4_REG(1, 51)
#define AIC32X4_RMICPGAPIN (AIC32X4_PAGE1 + 55) #define AIC32X4_LMICPGAPIN AIC32X4_REG(1, 52)
#define AIC32X4_RMICPGANIN (AIC32X4_PAGE1 + 57) #define AIC32X4_LMICPGANIN AIC32X4_REG(1, 54)
#define AIC32X4_FLOATINGINPUT (AIC32X4_PAGE1 + 58) #define AIC32X4_RMICPGAPIN AIC32X4_REG(1, 55)
#define AIC32X4_LMICPGAVOL (AIC32X4_PAGE1 + 59) #define AIC32X4_RMICPGANIN AIC32X4_REG(1, 57)
#define AIC32X4_RMICPGAVOL (AIC32X4_PAGE1 + 60) #define AIC32X4_FLOATINGINPUT AIC32X4_REG(1, 58)
#define AIC32X4_LMICPGAVOL AIC32X4_REG(1, 59)
#define AIC32X4_FREQ_12000000 12000000 #define AIC32X4_RMICPGAVOL AIC32X4_REG(1, 60)
#define AIC32X4_FREQ_24000000 24000000
#define AIC32X4_FREQ_25000000 25000000 /* Bits, masks, and shifts */
#define AIC32X4_WORD_LEN_16BITS 0x00 /* AIC32X4_CLKMUX */
#define AIC32X4_WORD_LEN_20BITS 0x01 #define AIC32X4_PLL_CLKIN_MASK GENMASK(3, 2)
#define AIC32X4_WORD_LEN_24BITS 0x02 #define AIC32X4_PLL_CLKIN_SHIFT (2)
#define AIC32X4_WORD_LEN_32BITS 0x03 #define AIC32X4_PLL_CLKIN_MCLK (0x00)
#define AIC32X4_PLL_CLKIN_BCKL (0x01)
#define AIC32X4_LADC_EN (1 << 7) #define AIC32X4_PLL_CLKIN_GPIO1 (0x02)
#define AIC32X4_RADC_EN (1 << 6) #define AIC32X4_PLL_CLKIN_DIN (0x03)
#define AIC32X4_CODEC_CLKIN_MASK GENMASK(1, 0)
#define AIC32X4_I2S_MODE 0x00 #define AIC32X4_CODEC_CLKIN_SHIFT (0)
#define AIC32X4_DSP_MODE 0x01 #define AIC32X4_CODEC_CLKIN_MCLK (0x00)
#define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02 #define AIC32X4_CODEC_CLKIN_BCLK (0x01)
#define AIC32X4_LEFT_JUSTIFIED_MODE 0x03 #define AIC32X4_CODEC_CLKIN_GPIO1 (0x02)
#define AIC32X4_CODEC_CLKIN_PLL (0x03)
#define AIC32X4_AVDDWEAKDISABLE 0x08
#define AIC32X4_LDOCTLEN 0x01 /* AIC32X4_PLLPR */
#define AIC32X4_PLLEN BIT(7)
#define AIC32X4_LDOIN_18_36 0x01 #define AIC32X4_PLL_P_MASK GENMASK(6, 4)
#define AIC32X4_LDOIN2HP 0x02 #define AIC32X4_PLL_P_SHIFT (4)
#define AIC32X4_PLL_R_MASK GENMASK(3, 0)
#define AIC32X4_DACSPBLOCK_MASK 0x1f
#define AIC32X4_ADCSPBLOCK_MASK 0x1f /* AIC32X4_NDAC */
#define AIC32X4_NDACEN BIT(7)
#define AIC32X4_PLLJ_SHIFT 6 #define AIC32X4_NDAC_MASK GENMASK(6, 0)
#define AIC32X4_DOSRMSB_SHIFT 4
/* AIC32X4_MDAC */
#define AIC32X4_PLLCLKIN 0x03 #define AIC32X4_MDACEN BIT(7)
#define AIC32X4_MDAC_MASK GENMASK(6, 0)
#define AIC32X4_MICBIAS_LDOIN 0x08
/* AIC32X4_NADC */
#define AIC32X4_NADCEN BIT(7)
#define AIC32X4_NADC_MASK GENMASK(6, 0)
/* AIC32X4_MADC */
#define AIC32X4_MADCEN BIT(7)
#define AIC32X4_MADC_MASK GENMASK(6, 0)
/* AIC32X4_BCLKN */
#define AIC32X4_BCLKEN BIT(7)
#define AIC32X4_BCLK_MASK GENMASK(6, 0)
/* AIC32X4_IFACE1 */
#define AIC32X4_IFACE1_DATATYPE_MASK GENMASK(7, 6)
#define AIC32X4_IFACE1_DATATYPE_SHIFT (6)
#define AIC32X4_I2S_MODE (0x00)
#define AIC32X4_DSP_MODE (0x01)
#define AIC32X4_RIGHT_JUSTIFIED_MODE (0x02)
#define AIC32X4_LEFT_JUSTIFIED_MODE (0x03)
#define AIC32X4_IFACE1_DATALEN_MASK GENMASK(5, 4)
#define AIC32X4_IFACE1_DATALEN_SHIFT (4)
#define AIC32X4_WORD_LEN_16BITS (0x00)
#define AIC32X4_WORD_LEN_20BITS (0x01)
#define AIC32X4_WORD_LEN_24BITS (0x02)
#define AIC32X4_WORD_LEN_32BITS (0x03)
#define AIC32X4_IFACE1_MASTER_MASK GENMASK(3, 2)
#define AIC32X4_BCLKMASTER BIT(2)
#define AIC32X4_WCLKMASTER BIT(3)
/* AIC32X4_IFACE2 */
#define AIC32X4_DATA_OFFSET_MASK GENMASK(7, 0)
/* AIC32X4_IFACE3 */
#define AIC32X4_BCLKINV_MASK BIT(3)
#define AIC32X4_BDIVCLK_MASK GENMASK(1, 0)
#define AIC32X4_BDIVCLK_SHIFT (0)
#define AIC32X4_DAC2BCLK (0x00)
#define AIC32X4_DACMOD2BCLK (0x01)
#define AIC32X4_ADC2BCLK (0x02)
#define AIC32X4_ADCMOD2BCLK (0x03)
/* AIC32X4_DACSETUP */
#define AIC32X4_DAC_CHAN_MASK GENMASK(5, 2)
#define AIC32X4_LDAC2RCHN BIT(5)
#define AIC32X4_LDAC2LCHN BIT(4)
#define AIC32X4_RDAC2LCHN BIT(3)
#define AIC32X4_RDAC2RCHN BIT(2)
/* AIC32X4_DACMUTE */
#define AIC32X4_MUTEON 0x0C
/* AIC32X4_ADCSETUP */
#define AIC32X4_LADC_EN BIT(7)
#define AIC32X4_RADC_EN BIT(6)
/* AIC32X4_PWRCFG */
#define AIC32X4_AVDDWEAKDISABLE BIT(3)
/* AIC32X4_LDOCTL */
#define AIC32X4_LDOCTLEN BIT(0)
/* AIC32X4_CMMODE */
#define AIC32X4_LDOIN_18_36 BIT(0)
#define AIC32X4_LDOIN2HP BIT(1)
/* AIC32X4_MICBIAS */
#define AIC32X4_MICBIAS_LDOIN BIT(3)
#define AIC32X4_MICBIAS_2075V 0x60 #define AIC32X4_MICBIAS_2075V 0x60
/* AIC32X4_LMICPGANIN */
#define AIC32X4_LMICPGANIN_IN2R_10K 0x10 #define AIC32X4_LMICPGANIN_IN2R_10K 0x10
#define AIC32X4_LMICPGANIN_CM1L_10K 0x40 #define AIC32X4_LMICPGANIN_CM1L_10K 0x40
/* AIC32X4_RMICPGANIN */
#define AIC32X4_RMICPGANIN_IN1L_10K 0x10 #define AIC32X4_RMICPGANIN_IN1L_10K 0x10
#define AIC32X4_RMICPGANIN_CM1R_10K 0x40 #define AIC32X4_RMICPGANIN_CM1R_10K 0x40
#define AIC32X4_LMICPGAVOL_NOGAIN 0x80
#define AIC32X4_RMICPGAVOL_NOGAIN 0x80
#define AIC32X4_BCLKMASTER 0x08
#define AIC32X4_WCLKMASTER 0x04
#define AIC32X4_PLLEN (0x01 << 7)
#define AIC32X4_NDACEN (0x01 << 7)
#define AIC32X4_MDACEN (0x01 << 7)
#define AIC32X4_NADCEN (0x01 << 7)
#define AIC32X4_MADCEN (0x01 << 7)
#define AIC32X4_BCLKEN (0x01 << 7)
#define AIC32X4_DACEN (0x03 << 6)
#define AIC32X4_RDAC2LCHN (0x02 << 2)
#define AIC32X4_LDAC2RCHN (0x02 << 4)
#define AIC32X4_LDAC2LCHN (0x01 << 4)
#define AIC32X4_RDAC2RCHN (0x01 << 2)
#define AIC32X4_DAC_CHAN_MASK 0x3c
#define AIC32X4_SSTEP2WCLK 0x01
#define AIC32X4_MUTEON 0x0C
#define AIC32X4_DACMOD2BCLK 0x01
#endif /* _TLV320AIC32X4_H */ #endif /* _TLV320AIC32X4_H */
...@@ -1804,11 +1804,18 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, ...@@ -1804,11 +1804,18 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
if (!ai3x_setup) if (!ai3x_setup)
return -ENOMEM; return -ENOMEM;
ret = of_get_named_gpio(np, "gpio-reset", 0); ret = of_get_named_gpio(np, "reset-gpios", 0);
if (ret >= 0) if (ret >= 0) {
aic3x->gpio_reset = ret; aic3x->gpio_reset = ret;
else } else {
aic3x->gpio_reset = -1; ret = of_get_named_gpio(np, "gpio-reset", 0);
if (ret > 0) {
dev_warn(&i2c->dev, "Using deprecated property \"gpio-reset\", please update your DT");
aic3x->gpio_reset = ret;
} else {
aic3x->gpio_reset = -1;
}
}
if (of_property_read_u32_array(np, "ai3x-gpio-func", if (of_property_read_u32_array(np, "ai3x-gpio-func",
ai3x_setup->gpio_func, 2) >= 0) { ai3x_setup->gpio_func, 2) >= 0) {
......
...@@ -106,6 +106,7 @@ struct tlv320dac33_priv { ...@@ -106,6 +106,7 @@ struct tlv320dac33_priv {
int mode1_latency; /* latency caused by the i2c writes in int mode1_latency; /* latency caused by the i2c writes in
* us */ * us */
u8 burst_bclkdiv; /* BCLK divider value in burst mode */ u8 burst_bclkdiv; /* BCLK divider value in burst mode */
u8 *reg_cache;
unsigned int burst_rate; /* Interface speed in Burst modes */ unsigned int burst_rate; /* Interface speed in Burst modes */
int keep_bclk; /* Keep the BCLK continuously running int keep_bclk; /* Keep the BCLK continuously running
...@@ -121,7 +122,7 @@ struct tlv320dac33_priv { ...@@ -121,7 +122,7 @@ struct tlv320dac33_priv {
unsigned int uthr; unsigned int uthr;
enum dac33_state state; enum dac33_state state;
void *control_data; struct i2c_client *i2c;
}; };
static const u8 dac33_reg[DAC33_CACHEREGNUM] = { static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
...@@ -173,7 +174,8 @@ static const u8 dac33_reg[DAC33_CACHEREGNUM] = { ...@@ -173,7 +174,8 @@ static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec, static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
unsigned reg) unsigned reg)
{ {
u8 *cache = codec->reg_cache; struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
u8 *cache = dac33->reg_cache;
if (reg >= DAC33_CACHEREGNUM) if (reg >= DAC33_CACHEREGNUM)
return 0; return 0;
...@@ -183,7 +185,8 @@ static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec, ...@@ -183,7 +185,8 @@ static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
static inline void dac33_write_reg_cache(struct snd_soc_codec *codec, static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
u8 reg, u8 value) u8 reg, u8 value)
{ {
u8 *cache = codec->reg_cache; struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
u8 *cache = dac33->reg_cache;
if (reg >= DAC33_CACHEREGNUM) if (reg >= DAC33_CACHEREGNUM)
return; return;
...@@ -200,7 +203,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, ...@@ -200,7 +203,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
/* If powered off, return the cached value */ /* If powered off, return the cached value */
if (dac33->chip_power) { if (dac33->chip_power) {
val = i2c_smbus_read_byte_data(codec->control_data, value[0]); val = i2c_smbus_read_byte_data(dac33->i2c, value[0]);
if (val < 0) { if (val < 0) {
dev_err(codec->dev, "Read failed (%d)\n", val); dev_err(codec->dev, "Read failed (%d)\n", val);
value[0] = dac33_read_reg_cache(codec, reg); value[0] = dac33_read_reg_cache(codec, reg);
...@@ -233,7 +236,7 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -233,7 +236,7 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
dac33_write_reg_cache(codec, data[0], data[1]); dac33_write_reg_cache(codec, data[0], data[1]);
if (dac33->chip_power) { if (dac33->chip_power) {
ret = codec->hw_write(codec->control_data, data, 2); ret = i2c_master_send(dac33->i2c, data, 2);
if (ret != 2) if (ret != 2)
dev_err(codec->dev, "Write failed (%d)\n", ret); dev_err(codec->dev, "Write failed (%d)\n", ret);
else else
...@@ -243,19 +246,6 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -243,19 +246,6 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
return ret; return ret;
} }
static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
int ret;
mutex_lock(&dac33->mutex);
ret = dac33_write(codec, reg, value);
mutex_unlock(&dac33->mutex);
return ret;
}
#define DAC33_I2C_ADDR_AUTOINC 0x80 #define DAC33_I2C_ADDR_AUTOINC 0x80
static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg, static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value) unsigned int value)
...@@ -280,7 +270,7 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg, ...@@ -280,7 +270,7 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
if (dac33->chip_power) { if (dac33->chip_power) {
/* We need to set autoincrement mode for 16 bit writes */ /* We need to set autoincrement mode for 16 bit writes */
data[0] |= DAC33_I2C_ADDR_AUTOINC; data[0] |= DAC33_I2C_ADDR_AUTOINC;
ret = codec->hw_write(codec->control_data, data, 3); ret = i2c_master_send(dac33->i2c, data, 3);
if (ret != 3) if (ret != 3)
dev_err(codec->dev, "Write failed (%d)\n", ret); dev_err(codec->dev, "Write failed (%d)\n", ret);
else else
...@@ -1379,8 +1369,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) ...@@ -1379,8 +1369,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
int ret = 0; int ret = 0;
codec->control_data = dac33->control_data;
codec->hw_write = (hw_write_t) i2c_master_send;
dac33->codec = codec; dac33->codec = codec;
/* Read the tlv320dac33 ID registers */ /* Read the tlv320dac33 ID registers */
...@@ -1434,13 +1422,9 @@ static int dac33_soc_remove(struct snd_soc_codec *codec) ...@@ -1434,13 +1422,9 @@ static int dac33_soc_remove(struct snd_soc_codec *codec)
} }
static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
.read = dac33_read_reg_cache,
.write = dac33_write_locked,
.set_bias_level = dac33_set_bias_level, .set_bias_level = dac33_set_bias_level,
.idle_bias_off = true, .idle_bias_off = true,
.reg_cache_size = ARRAY_SIZE(dac33_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = dac33_reg,
.probe = dac33_soc_probe, .probe = dac33_soc_probe,
.remove = dac33_soc_remove, .remove = dac33_soc_remove,
...@@ -1499,7 +1483,14 @@ static int dac33_i2c_probe(struct i2c_client *client, ...@@ -1499,7 +1483,14 @@ static int dac33_i2c_probe(struct i2c_client *client,
if (dac33 == NULL) if (dac33 == NULL)
return -ENOMEM; return -ENOMEM;
dac33->control_data = client; dac33->reg_cache = devm_kmemdup(&client->dev,
dac33_reg,
ARRAY_SIZE(dac33_reg) * sizeof(u8),
GFP_KERNEL);
if (!dac33->reg_cache)
return -ENOMEM;
dac33->i2c = client;
mutex_init(&dac33->mutex); mutex_init(&dac33->mutex);
spin_lock_init(&dac33->lock); spin_lock_init(&dac33->lock);
......
...@@ -241,7 +241,7 @@ int ts3a227e_enable_jack_detect(struct snd_soc_component *component, ...@@ -241,7 +241,7 @@ int ts3a227e_enable_jack_detect(struct snd_soc_component *component,
{ {
struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component); struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component);
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
......
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