linux/sound/soc/codecs/tlv320aic3x.c

// SPDX-License-Identifier: GPL-2.0-only
/* ALSA SoC TLV320AIC3X codec driver
 *
 * Author:      Vladimir Barinov, <[email protected]>
 * Copyright:   (C) 2007 MontaVista Software, Inc., <[email protected]>
 *
 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
 *
 * Notes:
 *  The AIC3X is a driver for a low power stereo audio
 *  codecs aic31, aic32, aic33, aic3007.
 *
 *  It supports full aic33 codec functionality.
 *  The compatibility with aic32, aic31 and aic3007 is as follows:
 *    aic32/aic3007    |        aic31
 *  ---------------------------------------
 *   MONO_LOUT -> N/A  |  MONO_LOUT -> N/A
 *                     |  IN1L -> LINE1L
 *                     |  IN1R -> LINE1R
 *                     |  IN2L -> LINE2L
 *                     |  IN2R -> LINE2R
 *                     |  MIC3L/R -> N/A
 *   truncated internal functionality in
 *   accordance with documentation
 *  ---------------------------------------
 *
 *  Hence the machine layer should disable unsupported inputs/outputs by
 *  snd_soc_dapm_disable_pin(codec, "MONO_LOUT"), etc.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>

#include "tlv320aic3x.h"

#define AIC3X_NUM_SUPPLIES
static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] =;

struct aic3x_priv;

struct aic3x_disable_nb {};

struct aic3x_setup_data {};

/* codec private data */
struct aic3x_priv {};

static const struct reg_default aic3x_reg[] =;

static bool aic3x_volatile_reg(struct device *dev, unsigned int reg)
{}

const struct regmap_config aic3x_regmap =;
EXPORT_SYMBOL_GPL();

#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert)

/*
 * All input lines are connected when !0xf and disconnected with 0xf bit field,
 * so we have to use specific dapm_put call for input mixer
 */
static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{}

/*
 * mic bias power on/off share the same register bits with
 * output voltage of mic bias. when power on mic bias, we
 * need reclaim it to voltage value.
 * 0x0 = Powered off
 * 0x1 = MICBIAS output is powered to 2.0V,
 * 0x2 = MICBIAS output is powered to 2.5V
 * 0x3 = MICBIAS output is connected to AVDD
 */
static int mic_bias_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{}

static const char * const aic3x_left_dac_mux[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_left_dac_enum, DAC_LINE_MUX, 6,
			    aic3x_left_dac_mux);

static const char * const aic3x_right_dac_mux[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_right_dac_enum, DAC_LINE_MUX, 4,
			    aic3x_right_dac_mux);

static const char * const aic3x_left_hpcom_mux[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_left_hpcom_enum, HPLCOM_CFG, 4,
			    aic3x_left_hpcom_mux);

static const char * const aic3x_right_hpcom_mux[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_right_hpcom_enum, HPRCOM_CFG, 3,
			    aic3x_right_hpcom_mux);

static const char * const aic3x_linein_mode_mux[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_line1l_2_l_enum, LINE1L_2_LADC_CTRL, 7,
			    aic3x_linein_mode_mux);
static SOC_ENUM_SINGLE_DECL(aic3x_line1l_2_r_enum, LINE1L_2_RADC_CTRL, 7,
			    aic3x_linein_mode_mux);
static SOC_ENUM_SINGLE_DECL(aic3x_line1r_2_l_enum, LINE1R_2_LADC_CTRL, 7,
			    aic3x_linein_mode_mux);
static SOC_ENUM_SINGLE_DECL(aic3x_line1r_2_r_enum, LINE1R_2_RADC_CTRL, 7,
			    aic3x_linein_mode_mux);
static SOC_ENUM_SINGLE_DECL(aic3x_line2l_2_ldac_enum, LINE2L_2_LADC_CTRL, 7,
			    aic3x_linein_mode_mux);
static SOC_ENUM_SINGLE_DECL(aic3x_line2r_2_rdac_enum, LINE2R_2_RADC_CTRL, 7,
			    aic3x_linein_mode_mux);

static const char * const aic3x_adc_hpf[] =;
static SOC_ENUM_DOUBLE_DECL(aic3x_adc_hpf_enum, AIC3X_CODEC_DFILT_CTRL, 6, 4,
			    aic3x_adc_hpf);

static const char * const aic3x_agc_level[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_lagc_level_enum, LAGC_CTRL_A, 4,
			    aic3x_agc_level);
static SOC_ENUM_SINGLE_DECL(aic3x_ragc_level_enum, RAGC_CTRL_A, 4,
			    aic3x_agc_level);

static const char * const aic3x_agc_attack[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_lagc_attack_enum, LAGC_CTRL_A, 2,
			    aic3x_agc_attack);
static SOC_ENUM_SINGLE_DECL(aic3x_ragc_attack_enum, RAGC_CTRL_A, 2,
			    aic3x_agc_attack);

static const char * const aic3x_agc_decay[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_lagc_decay_enum, LAGC_CTRL_A, 0,
			    aic3x_agc_decay);
static SOC_ENUM_SINGLE_DECL(aic3x_ragc_decay_enum, RAGC_CTRL_A, 0,
			    aic3x_agc_decay);

static const char * const aic3x_poweron_time[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_poweron_time_enum, HPOUT_POP_REDUCTION, 4,
			    aic3x_poweron_time);

static const char * const aic3x_rampup_step[] =;
static SOC_ENUM_SINGLE_DECL(aic3x_rampup_step_enum, HPOUT_POP_REDUCTION, 2,
			    aic3x_rampup_step);

/*
 * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps
 */
static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0);
/* ADC PGA gain volumes. From 0 to 59.5 dB in 0.5 dB steps */
static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0);
/*
 * Output stage volumes. From -78.3 to 0 dB. Muted below -78.3 dB.
 * Step size is approximately 0.5 dB over most of the scale but increasing
 * near the very low levels.
 * Define dB scale so that it is mostly correct for range about -55 to 0 dB
 * but having increasing dB difference below that (and where it doesn't count
 * so much). This setting shows -50 dB (actual is -50.3 dB) for register
 * value 100 and -58.5 dB (actual is -78.3 dB) for register value 117.
 */
static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);

/* Output volumes. From 0 to 9 dB in 1 dB steps */
static const DECLARE_TLV_DB_SCALE(out_tlv, 0, 100, 0);

static const struct snd_kcontrol_new aic3x_snd_controls[] =;

/* For other than tlv320aic3104 */
static const struct snd_kcontrol_new aic3x_extra_snd_controls[] =;

static const struct snd_kcontrol_new aic3x_mono_controls[] =;

/*
 * Class-D amplifier gain. From 0 to 18 dB in 6 dB steps
 */
static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0);

static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl =;

/* Left DAC Mux */
static const struct snd_kcontrol_new aic3x_left_dac_mux_controls =;

/* Right DAC Mux */
static const struct snd_kcontrol_new aic3x_right_dac_mux_controls =;

/* Left HPCOM Mux */
static const struct snd_kcontrol_new aic3x_left_hpcom_mux_controls =;

/* Right HPCOM Mux */
static const struct snd_kcontrol_new aic3x_right_hpcom_mux_controls =;

/* Left Line Mixer */
static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] =;

/* Right Line Mixer */
static const struct snd_kcontrol_new aic3x_right_line_mixer_controls[] =;

/* Mono Mixer */
static const struct snd_kcontrol_new aic3x_mono_mixer_controls[] =;

/* Left HP Mixer */
static const struct snd_kcontrol_new aic3x_left_hp_mixer_controls[] =;

/* Right HP Mixer */
static const struct snd_kcontrol_new aic3x_right_hp_mixer_controls[] =;

/* Left HPCOM Mixer */
static const struct snd_kcontrol_new aic3x_left_hpcom_mixer_controls[] =;

/* Right HPCOM Mixer */
static const struct snd_kcontrol_new aic3x_right_hpcom_mixer_controls[] =;

/* Left PGA Mixer */
static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] =;

/* Right PGA Mixer */
static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] =;

/* Left PGA Mixer for tlv320aic3104 */
static const struct snd_kcontrol_new aic3104_left_pga_mixer_controls[] =;

/* Right PGA Mixer for tlv320aic3104 */
static const struct snd_kcontrol_new aic3104_right_pga_mixer_controls[] =;

/* Left Line1 Mux */
static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls =;
static const struct snd_kcontrol_new aic3x_right_line1l_mux_controls =;

/* Right Line1 Mux */
static const struct snd_kcontrol_new aic3x_right_line1r_mux_controls =;
static const struct snd_kcontrol_new aic3x_left_line1r_mux_controls =;

/* Left Line2 Mux */
static const struct snd_kcontrol_new aic3x_left_line2_mux_controls =;

/* Right Line2 Mux */
static const struct snd_kcontrol_new aic3x_right_line2_mux_controls =;

static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] =;

/* For other than tlv320aic3104 */
static const struct snd_soc_dapm_widget aic3x_extra_dapm_widgets[] =;

/* For tlv320aic3104 */
static const struct snd_soc_dapm_widget aic3104_extra_dapm_widgets[] =;

static const struct snd_soc_dapm_widget aic3x_dapm_mono_widgets[] =;

static const struct snd_soc_dapm_widget aic3007_dapm_widgets[] =;

static const struct snd_soc_dapm_route intercon[] =;

/* For other than tlv320aic3104 */
static const struct snd_soc_dapm_route intercon_extra[] =;

/* For tlv320aic3104 */
static const struct snd_soc_dapm_route intercon_extra_3104[] =;

static const struct snd_soc_dapm_route intercon_mono[] =;

static const struct snd_soc_dapm_route intercon_3007[] =;

static int aic3x_add_widgets(struct snd_soc_component *component)
{}

static int aic3x_hw_params(struct snd_pcm_substream *substream,
			   struct snd_pcm_hw_params *params,
			   struct snd_soc_dai *dai)
{}

static int aic3x_prepare(struct snd_pcm_substream *substream,
			 struct snd_soc_dai *dai)
{}

static int aic3x_mute(struct snd_soc_dai *dai, int mute, int direction)
{}

static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
				int clk_id, unsigned int freq, int dir)
{}

static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
			     unsigned int fmt)
{}

static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
				  unsigned int tx_mask, unsigned int rx_mask,
				  int slots, int slot_width)
{}

static int aic3x_regulator_event(struct notifier_block *nb,
				 unsigned long event, void *data)
{}

static int aic3x_set_power(struct snd_soc_component *component, int power)
{}

static int aic3x_set_bias_level(struct snd_soc_component *component,
				enum snd_soc_bias_level level)
{}

#define AIC3X_RATES
#define AIC3X_FORMATS

static const struct snd_soc_dai_ops aic3x_dai_ops =;

static struct snd_soc_dai_driver aic3x_dai =;

static void aic3x_mono_init(struct snd_soc_component *component)
{}

/*
 * initialise the AIC3X driver
 * register the mixer and dsp interfaces with the kernel
 */
static int aic3x_init(struct snd_soc_component *component)
{}

static int aic3x_component_probe(struct snd_soc_component *component)
{}

static const struct snd_soc_component_driver soc_component_dev_aic3x =;

static void aic3x_configure_ocmv(struct device *dev, struct aic3x_priv *aic3x)
{}


static const struct reg_sequence aic3007_class_d[] =;

int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver_data)
{}
EXPORT_SYMBOL();

void aic3x_remove(struct device *dev)
{}
EXPORT_SYMBOL();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();