#include <dt-bindings/sound/tlv320adc3xxx.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/gpio/driver.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#define ADC3XXX_MICBIAS_PINS …
#define ADC3XXX_GPIO_PINS …
#define ADC3XXX_GPIOS_MAX …
#define ADC3XXX_RATES …
#define ADC3XXX_FORMATS …
#define ADC3XXX_PLL_AUTO …
#define ADC3XXX_PLL_ENABLE …
#define ADC3XXX_PLL_BYPASS …
#define ADC3XXX_PAGE_SIZE …
#define ADC3XXX_REG(page, reg) …
#define ADC3XXX_PAGE_SELECT …
#define ADC3XXX_RESET …
#define ADC3XXX_CLKGEN_MUX …
#define ADC3XXX_PLL_PROG_PR …
#define ADC3XXX_PLL_PROG_J …
#define ADC3XXX_PLL_PROG_D_MSB …
#define ADC3XXX_PLL_PROG_D_LSB …
#define ADC3XXX_ADC_NADC …
#define ADC3XXX_ADC_MADC …
#define ADC3XXX_ADC_AOSR …
#define ADC3XXX_ADC_IADC …
#define ADC3XXX_CLKOUT_MUX …
#define ADC3XXX_CLKOUT_M_DIV …
#define ADC3XXX_INTERFACE_CTRL_1 …
#define ADC3XXX_CH_OFFSET_1 …
#define ADC3XXX_INTERFACE_CTRL_2 …
#define ADC3XXX_BCLK_N_DIV …
#define ADC3XXX_INTERFACE_CTRL_3 …
#define ADC3XXX_INTERFACE_CTRL_4 …
#define ADC3XXX_INTERFACE_CTRL_5 …
#define ADC3XXX_I2S_SYNC …
#define ADC3XXX_ADC_FLAG …
#define ADC3XXX_CH_OFFSET_2 …
#define ADC3XXX_I2S_TDM_CTRL …
#define ADC3XXX_INTR_FLAG_1 …
#define ADC3XXX_INTR_FLAG_2 …
#define ADC3XXX_INTR_FLAG_ADC1 …
#define ADC3XXX_INTR_FLAG_ADC2 …
#define ADC3XXX_INT1_CTRL …
#define ADC3XXX_INT2_CTRL …
#define ADC3XXX_GPIO2_CTRL …
#define ADC3XXX_GPIO1_CTRL …
#define ADC3XXX_DOUT_CTRL …
#define ADC3XXX_SYNC_CTRL_1 …
#define ADC3XXX_SYNC_CTRL_2 …
#define ADC3XXX_CIC_GAIN_CTRL …
#define ADC3XXX_PRB_SELECT …
#define ADC3XXX_INST_MODE_CTRL …
#define ADC3XXX_MIC_POLARITY_CTRL …
#define ADC3XXX_ADC_DIGITAL …
#define ADC3XXX_ADC_FGA …
#define ADC3XXX_LADC_VOL …
#define ADC3XXX_RADC_VOL …
#define ADC3XXX_ADC_PHASE_COMP …
#define ADC3XXX_LEFT_CHN_AGC_1 …
#define ADC3XXX_LEFT_CHN_AGC_2 …
#define ADC3XXX_LEFT_CHN_AGC_3 …
#define ADC3XXX_LEFT_CHN_AGC_4 …
#define ADC3XXX_LEFT_CHN_AGC_5 …
#define ADC3XXX_LEFT_CHN_AGC_6 …
#define ADC3XXX_LEFT_CHN_AGC_7 …
#define ADC3XXX_LEFT_AGC_GAIN …
#define ADC3XXX_RIGHT_CHN_AGC_1 …
#define ADC3XXX_RIGHT_CHN_AGC_2 …
#define ADC3XXX_RIGHT_CHN_AGC_3 …
#define ADC3XXX_RIGHT_CHN_AGC_4 …
#define ADC3XXX_RIGHT_CHN_AGC_5 …
#define ADC3XXX_RIGHT_CHN_AGC_6 …
#define ADC3XXX_RIGHT_CHN_AGC_7 …
#define ADC3XXX_RIGHT_AGC_GAIN …
#define ADC3XXX_DITHER_CTRL …
#define ADC3XXX_MICBIAS_CTRL …
#define ADC3XXX_LEFT_PGA_SEL_1 …
#define ADC3XXX_LEFT_PGA_SEL_2 …
#define ADC3XXX_RIGHT_PGA_SEL_1 …
#define ADC3XXX_RIGHT_PGA_SEL_2 …
#define ADC3XXX_LEFT_APGA_CTRL …
#define ADC3XXX_RIGHT_APGA_CTRL …
#define ADC3XXX_LOW_CURRENT_MODES …
#define ADC3XXX_ANALOG_PGA_FLAGS …
#define ADC3XXX_LEFT_ADC_IIR_COEFF_N0_MSB …
#define ADC3XXX_LEFT_ADC_IIR_COEFF_N0_LSB …
#define ADC3XXX_LEFT_ADC_IIR_COEFF_N1_MSB …
#define ADC3XXX_LEFT_ADC_IIR_COEFF_N1_LSB …
#define ADC3XXX_LEFT_ADC_IIR_COEFF_D1_MSB …
#define ADC3XXX_LEFT_ADC_IIR_COEFF_D1_LSB …
#define ADC3XXX_RIGHT_ADC_IIR_COEFF_N0_MSB …
#define ADC3XXX_RIGHT_ADC_IIR_COEFF_N0_LSB …
#define ADC3XXX_RIGHT_ADC_IIR_COEFF_N1_MSB …
#define ADC3XXX_RIGHT_ADC_IIR_COEFF_N1_LSB …
#define ADC3XXX_RIGHT_ADC_IIR_COEFF_D1_MSB …
#define ADC3XXX_RIGHT_ADC_IIR_COEFF_D1_LSB …
#define ADC3XXX_ENABLE_PLL_SHIFT …
#define ADC3XXX_ENABLE_PLL …
#define ADC3XXX_ENABLE_NADC_SHIFT …
#define ADC3XXX_ENABLE_NADC …
#define ADC3XXX_ENABLE_MADC_SHIFT …
#define ADC3XXX_ENABLE_MADC …
#define ADC3XXX_ENABLE_BCLK_SHIFT …
#define ADC3XXX_ENABLE_BCLK …
#define ADC3XXX_LADC_PWR_ON …
#define ADC3XXX_RADC_PWR_ON …
#define ADC3XXX_SOFT_RESET …
#define ADC3XXX_BCLK_MASTER …
#define ADC3XXX_WCLK_MASTER …
#define ADC3XXX_FORMAT_MASK …
#define ADC3XXX_FORMAT_SHIFT …
#define ADC3XXX_WLENGTH_MASK …
#define ADC3XXX_WLENGTH_SHIFT …
#define ADC3XXX_CLKDIR_MASK …
#define ADC3XXX_CLKDIR_SHIFT …
#define ADC3XXX_FORMAT_I2S …
#define ADC3XXX_FORMAT_DSP …
#define ADC3XXX_FORMAT_RJF …
#define ADC3XXX_FORMAT_LJF …
#define ADC3XXX_IFACE_16BITS …
#define ADC3XXX_IFACE_20BITS …
#define ADC3XXX_IFACE_24BITS …
#define ADC3XXX_IFACE_32BITS …
#define ADC3XXX_PLLP_SHIFT …
#define ADC3XXX_PLLR_SHIFT …
#define ADC3XXX_PLL_PR_MASK …
#define ADC3XXX_PLLJ_MASK …
#define ADC3XXX_PLLD_MSB_MASK …
#define ADC3XXX_PLLD_LSB_MASK …
#define ADC3XXX_NADC_MASK …
#define ADC3XXX_MADC_MASK …
#define ADC3XXX_AOSR_MASK …
#define ADC3XXX_IADC_MASK …
#define ADC3XXX_BDIV_MASK …
#define ADC3XXX_PLL_CLKIN_SHIFT …
#define ADC3XXX_PLL_CLKIN_MCLK …
#define ADC3XXX_PLL_CLKIN_BCLK …
#define ADC3XXX_PLL_CLKIN_ZERO …
#define ADC3XXX_CODEC_CLKIN_SHIFT …
#define ADC3XXX_CODEC_CLKIN_MCLK …
#define ADC3XXX_CODEC_CLKIN_BCLK …
#define ADC3XXX_CODEC_CLKIN_PLL_CLK …
#define ADC3XXX_USE_PLL …
#define ADC3XXX_NO_PLL …
#define ADC3XXX_LPGA_MUTE …
#define ADC3XXX_RPGA_MUTE …
#define ADC3XXX_LPGA_GAIN_MASK …
#define ADC3XXX_RPGA_GAIN_MASK …
#define ADC3XXX_ADC_LOW_CURR_MODE …
#define ADC3XXX_LCH_SEL1_SHIFT …
#define ADC3XXX_LCH_SEL2_SHIFT …
#define ADC3XXX_LCH_SEL3_SHIFT …
#define ADC3XXX_LCH_SEL4_SHIFT …
#define ADC3XXX_LCH_SEL1X_SHIFT …
#define ADC3XXX_LCH_SEL2X_SHIFT …
#define ADC3XXX_LCH_SEL3X_SHIFT …
#define ADC3XXX_LCH_COMMON_MODE …
#define ADC3XXX_BYPASS_LPGA …
#define ADC3XXX_RCH_SEL1_SHIFT …
#define ADC3XXX_RCH_SEL2_SHIFT …
#define ADC3XXX_RCH_SEL3_SHIFT …
#define ADC3XXX_RCH_SEL4_SHIFT …
#define ADC3XXX_RCH_SEL1X_SHIFT …
#define ADC3XXX_RCH_SEL2X_SHIFT …
#define ADC3XXX_RCH_SEL3X_SHIFT …
#define ADC3XXX_RCH_COMMON_MODE …
#define ADC3XXX_BYPASS_RPGA …
#define ADC3XXX_MICBIAS_MASK …
#define ADC3XXX_MICBIAS1_SHIFT …
#define ADC3XXX_MICBIAS2_SHIFT …
#define ADC3XXX_ADC_MAX_VOLUME …
#define ADC3XXX_ADC_POS_VOL …
#define ADC3XXX_GPIO_CTRL_CFG_MASK …
#define ADC3XXX_GPIO_CTRL_CFG_SHIFT …
#define ADC3XXX_GPIO_CTRL_OUTPUT_CTRL_MASK …
#define ADC3XXX_GPIO_CTRL_OUTPUT_CTRL_SHIFT …
#define ADC3XXX_GPIO_CTRL_INPUT_VALUE_MASK …
#define ADC3XXX_GPIO_CTRL_INPUT_VALUE_SHIFT …
enum adc3xxx_type { … };
struct adc3xxx { … };
static const unsigned int adc3xxx_gpio_ctrl_reg[ADC3XXX_GPIO_PINS] = …;
static const unsigned int adc3xxx_micbias_shift[ADC3XXX_MICBIAS_PINS] = …;
static const struct reg_default adc3xxx_defaults[] = …;
static bool adc3xxx_volatile_reg(struct device *dev, unsigned int reg)
{ … }
static const struct regmap_range_cfg adc3xxx_ranges[] = …;
static const struct regmap_config adc3xxx_regmap = …;
struct adc3xxx_rate_divs { … };
static const struct adc3xxx_rate_divs adc3xxx_divs[] = …;
static int adc3xxx_get_divs(struct device *dev, int mclk, int rate, int pll_mode)
{ … }
static int adc3xxx_pll_delay(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{ … }
static int adc3xxx_coefficient_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int adc3xxx_coefficient_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int adc3xxx_coefficient_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
#define TI_COEFFICIENTS(xname, reg, numcoeffs) …
static const char * const adc_softstepping_text[] = …;
static SOC_ENUM_SINGLE_DECL(adc_softstepping_enum, ADC3XXX_ADC_DIGITAL, 0,
adc_softstepping_text);
static const char * const multiplier_text[] = …;
static SOC_ENUM_SINGLE_DECL(left_agc_attack_mult_enum,
ADC3XXX_LEFT_CHN_AGC_4, 0, multiplier_text);
static SOC_ENUM_SINGLE_DECL(right_agc_attack_mult_enum,
ADC3XXX_RIGHT_CHN_AGC_4, 0, multiplier_text);
static SOC_ENUM_SINGLE_DECL(left_agc_decay_mult_enum,
ADC3XXX_LEFT_CHN_AGC_5, 0, multiplier_text);
static SOC_ENUM_SINGLE_DECL(right_agc_decay_mult_enum,
ADC3XXX_RIGHT_CHN_AGC_5, 0, multiplier_text);
static const char * const dither_dc_offset_text[] = …;
static const unsigned int dither_dc_offset_values[] = …;
static SOC_VALUE_ENUM_DOUBLE_DECL(dither_dc_offset_enum,
ADC3XXX_DITHER_CTRL,
4, 0, 0xf, dither_dc_offset_text,
dither_dc_offset_values);
static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 50, 0);
static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 50, 0);
static const DECLARE_TLV_DB_SCALE(adc_fine_tlv, -40, 10, 0);
static const DECLARE_TLV_DB_RANGE(agc_target_tlv,
0, 0, TLV_DB_SCALE_ITEM(-2400, 0, 0),
1, 3, TLV_DB_SCALE_ITEM(-2000, 300, 0),
4, 6, TLV_DB_SCALE_ITEM(-1200, 200, 0),
7, 7, TLV_DB_SCALE_ITEM(-550, 0, 0));
static const DECLARE_TLV_DB_RANGE(agc_thresh_tlv,
0, 30, TLV_DB_SCALE_ITEM(-9000, 200, 0),
31, 31, TLV_DB_SCALE_ITEM(0, 0, 1));
static const DECLARE_TLV_DB_RANGE(agc_hysteresis_tlv,
0, 1, TLV_DB_SCALE_ITEM(100, 100, 0),
2, 2, TLV_DB_SCALE_ITEM(400, 0, 0),
3, 3, TLV_DB_SCALE_ITEM(0, 0, 1));
static const DECLARE_TLV_DB_SCALE(agc_max_tlv, 0, 50, 0);
static const DECLARE_TLV_DB_SCALE(input_attenuation_tlv, -600, 600, 0);
static const struct snd_kcontrol_new adc3xxx_snd_controls[] = …;
static const struct snd_kcontrol_new left_input_mixer_controls[] = …;
static const struct snd_kcontrol_new right_input_mixer_controls[] = …;
static const struct snd_kcontrol_new left_input_dmic_controls[] = …;
static const struct snd_kcontrol_new right_input_dmic_controls[] = …;
static const struct snd_soc_dapm_widget adc3xxx_dapm_widgets[] = …;
static const struct snd_soc_dapm_route adc3xxx_intercon[] = …;
static const struct snd_soc_dapm_route adc3xxx_pll_intercon[] = …;
static const struct snd_soc_dapm_route adc3xxx_bclk_out_intercon[] = …;
static int adc3xxx_gpio_request(struct gpio_chip *chip, unsigned int offset)
{ … }
static int adc3xxx_gpio_direction_out(struct gpio_chip *chip,
unsigned int offset, int value)
{ … }
static void adc3xxx_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{ … }
static int adc3xxx_gpio_get(struct gpio_chip *chip, unsigned int offset)
{ … }
static const struct gpio_chip adc3xxx_gpio_chip = …;
static void adc3xxx_free_gpio(struct adc3xxx *adc3xxx)
{ … }
static void adc3xxx_init_gpio(struct adc3xxx *adc3xxx)
{ … }
static int adc3xxx_parse_dt_gpio(struct adc3xxx *adc3xxx,
const char *propname, unsigned int *cfg)
{ … }
static int adc3xxx_parse_dt_micbias_gpo(struct adc3xxx *adc3xxx,
const char *propname,
unsigned int *cfg)
{ … }
static int adc3xxx_parse_dt_micbias_vg(struct adc3xxx *adc3xxx,
const char *propname, unsigned int *vg)
{ … }
static int adc3xxx_parse_pll_mode(uint32_t val, unsigned int *pll_mode)
{ … }
static void adc3xxx_setup_pll(struct snd_soc_component *component,
int div_entry)
{ … }
static int adc3xxx_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{ … }
static const char *adc3xxx_pll_mode_text(int pll_mode)
{ … }
static int adc3xxx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{ … }
static int adc3xxx_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{ … }
static const struct snd_soc_dai_ops adc3xxx_dai_ops = …;
static struct snd_soc_dai_driver adc3xxx_dai = …;
static const struct snd_soc_component_driver soc_component_dev_adc3xxx = …;
static const struct i2c_device_id adc3xxx_i2c_id[] = …;
MODULE_DEVICE_TABLE(i2c, adc3xxx_i2c_id);
static int adc3xxx_i2c_probe(struct i2c_client *i2c)
{ … }
static void adc3xxx_i2c_remove(struct i2c_client *client)
{ … }
static const struct of_device_id tlv320adc3xxx_of_match[] = …;
MODULE_DEVICE_TABLE(of, tlv320adc3xxx_of_match);
static struct i2c_driver adc3xxx_i2c_driver = …;
module_i2c_driver(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;