linux/sound/soc/codecs/max98090.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * max98090.c -- MAX98090 ALSA SoC Audio driver
 *
 * Copyright 2011-2012 Maxim Integrated Products
 */

#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <sound/max98090.h>
#include "max98090.h"

/* Allows for sparsely populated register maps */
static const struct reg_default max98090_reg[] =;

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

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

static int max98090_reset(struct max98090_priv *max98090)
{}

static const DECLARE_TLV_DB_RANGE(max98090_micboost_tlv,
	0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
	2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0)
);

static const DECLARE_TLV_DB_SCALE(max98090_mic_tlv, 0, 100, 0);

static const DECLARE_TLV_DB_SCALE(max98090_line_single_ended_tlv,
	-600, 600, 0);

static const DECLARE_TLV_DB_RANGE(max98090_line_tlv,
	0, 3, TLV_DB_SCALE_ITEM(-600, 300, 0),
	4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0)
);

static const DECLARE_TLV_DB_SCALE(max98090_avg_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(max98090_av_tlv, -1200, 100, 0);

static const DECLARE_TLV_DB_SCALE(max98090_dvg_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(max98090_dv_tlv, -1500, 100, 0);

static const DECLARE_TLV_DB_SCALE(max98090_alcmakeup_tlv, 0, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_alccomp_tlv, -3100, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_drcexp_tlv, -6600, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_sdg_tlv, 50, 200, 0);

static const DECLARE_TLV_DB_RANGE(max98090_mixout_tlv,
	0, 1, TLV_DB_SCALE_ITEM(-1200, 250, 0),
	2, 3, TLV_DB_SCALE_ITEM(-600, 600, 0)
);

static const DECLARE_TLV_DB_RANGE(max98090_hp_tlv,
	0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
	7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
	15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
	22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
	28, 31, TLV_DB_SCALE_ITEM(150, 50, 0)
);

static const DECLARE_TLV_DB_RANGE(max98090_spk_tlv,
	0, 4, TLV_DB_SCALE_ITEM(-4800, 400, 0),
	5, 10, TLV_DB_SCALE_ITEM(-2900, 300, 0),
	11, 14, TLV_DB_SCALE_ITEM(-1200, 200, 0),
	15, 29, TLV_DB_SCALE_ITEM(-500, 100, 0),
	30, 39, TLV_DB_SCALE_ITEM(950, 50, 0)
);

static const DECLARE_TLV_DB_RANGE(max98090_rcv_lout_tlv,
	0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
	7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
	15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
	22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
	28, 31, TLV_DB_SCALE_ITEM(650, 50, 0)
);

static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static const char *max98090_perf_pwr_text[] =;
static const char *max98090_pwr_perf_text[] =;

static SOC_ENUM_SINGLE_DECL(max98090_vcmbandgap_enum,
			    M98090_REG_BIAS_CONTROL,
			    M98090_VCM_MODE_SHIFT,
			    max98090_pwr_perf_text);

static const char *max98090_osr128_text[] =;

static SOC_ENUM_SINGLE_DECL(max98090_osr128_enum,
			    M98090_REG_ADC_CONTROL,
			    M98090_OSR128_SHIFT,
			    max98090_osr128_text);

static const char *max98090_mode_text[] =;

static SOC_ENUM_SINGLE_DECL(max98090_mode_enum,
			    M98090_REG_FILTER_CONFIG,
			    M98090_MODE_SHIFT,
			    max98090_mode_text);

static SOC_ENUM_SINGLE_DECL(max98090_filter_dmic34mode_enum,
			    M98090_REG_FILTER_CONFIG,
			    M98090_FLT_DMIC34MODE_SHIFT,
			    max98090_mode_text);

static const char *max98090_drcatk_text[] =;

static SOC_ENUM_SINGLE_DECL(max98090_drcatk_enum,
			    M98090_REG_DRC_TIMING,
			    M98090_DRCATK_SHIFT,
			    max98090_drcatk_text);

static const char *max98090_drcrls_text[] =;

static SOC_ENUM_SINGLE_DECL(max98090_drcrls_enum,
			    M98090_REG_DRC_TIMING,
			    M98090_DRCRLS_SHIFT,
			    max98090_drcrls_text);

static const char *max98090_alccmp_text[] =;

static SOC_ENUM_SINGLE_DECL(max98090_alccmp_enum,
			    M98090_REG_DRC_COMPRESSOR,
			    M98090_DRCCMP_SHIFT,
			    max98090_alccmp_text);

static const char *max98090_drcexp_text[] =;

static SOC_ENUM_SINGLE_DECL(max98090_drcexp_enum,
			    M98090_REG_DRC_EXPANDER,
			    M98090_DRCEXP_SHIFT,
			    max98090_drcexp_text);

static SOC_ENUM_SINGLE_DECL(max98090_dac_perfmode_enum,
			    M98090_REG_DAC_CONTROL,
			    M98090_PERFMODE_SHIFT,
			    max98090_perf_pwr_text);

static SOC_ENUM_SINGLE_DECL(max98090_dachp_enum,
			    M98090_REG_DAC_CONTROL,
			    M98090_DACHP_SHIFT,
			    max98090_pwr_perf_text);

static SOC_ENUM_SINGLE_DECL(max98090_adchp_enum,
			    M98090_REG_ADC_CONTROL,
			    M98090_ADCHP_SHIFT,
			    max98090_pwr_perf_text);

static const struct snd_kcontrol_new max98090_snd_controls[] =;

static const struct snd_kcontrol_new max98091_snd_controls[] =;

static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
				 struct snd_kcontrol *kcontrol, int event)
{}

static int max98090_shdn_event(struct snd_soc_dapm_widget *w,
				 struct snd_kcontrol *kcontrol, int event)
{}

static const char *mic1_mux_text[] =;

static SOC_ENUM_SINGLE_DECL(mic1_mux_enum,
			    M98090_REG_INPUT_MODE,
			    M98090_EXTMIC1_SHIFT,
			    mic1_mux_text);

static const struct snd_kcontrol_new max98090_mic1_mux =;

static const char *mic2_mux_text[] =;

static SOC_ENUM_SINGLE_DECL(mic2_mux_enum,
			    M98090_REG_INPUT_MODE,
			    M98090_EXTMIC2_SHIFT,
			    mic2_mux_text);

static const struct snd_kcontrol_new max98090_mic2_mux =;

static const char *dmic_mux_text[] =;

static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text);

static const struct snd_kcontrol_new max98090_dmic_mux =;

/* LINEA mixer switch */
static const struct snd_kcontrol_new max98090_linea_mixer_controls[] =;

/* LINEB mixer switch */
static const struct snd_kcontrol_new max98090_lineb_mixer_controls[] =;

/* Left ADC mixer switch */
static const struct snd_kcontrol_new max98090_left_adc_mixer_controls[] =;

/* Right ADC mixer switch */
static const struct snd_kcontrol_new max98090_right_adc_mixer_controls[] =;

static const char *lten_mux_text[] =;

static SOC_ENUM_SINGLE_DECL(ltenl_mux_enum,
			    M98090_REG_IO_CONFIGURATION,
			    M98090_LTEN_SHIFT,
			    lten_mux_text);

static SOC_ENUM_SINGLE_DECL(ltenr_mux_enum,
			    M98090_REG_IO_CONFIGURATION,
			    M98090_LTEN_SHIFT,
			    lten_mux_text);

static const struct snd_kcontrol_new max98090_ltenl_mux =;

static const struct snd_kcontrol_new max98090_ltenr_mux =;

static const char *lben_mux_text[] =;

static SOC_ENUM_SINGLE_DECL(lbenl_mux_enum,
			    M98090_REG_IO_CONFIGURATION,
			    M98090_LBEN_SHIFT,
			    lben_mux_text);

static SOC_ENUM_SINGLE_DECL(lbenr_mux_enum,
			    M98090_REG_IO_CONFIGURATION,
			    M98090_LBEN_SHIFT,
			    lben_mux_text);

static const struct snd_kcontrol_new max98090_lbenl_mux =;

static const struct snd_kcontrol_new max98090_lbenr_mux =;

static const char *stenl_mux_text[] =;

static const char *stenr_mux_text[] =;

static SOC_ENUM_SINGLE_DECL(stenl_mux_enum,
			    M98090_REG_ADC_SIDETONE,
			    M98090_DSTSL_SHIFT,
			    stenl_mux_text);

static SOC_ENUM_SINGLE_DECL(stenr_mux_enum,
			    M98090_REG_ADC_SIDETONE,
			    M98090_DSTSR_SHIFT,
			    stenr_mux_text);

static const struct snd_kcontrol_new max98090_stenl_mux =;

static const struct snd_kcontrol_new max98090_stenr_mux =;

/* Left speaker mixer switch */
static const struct
	snd_kcontrol_new max98090_left_speaker_mixer_controls[] =;

/* Right speaker mixer switch */
static const struct
	snd_kcontrol_new max98090_right_speaker_mixer_controls[] =;

/* Left headphone mixer switch */
static const struct snd_kcontrol_new max98090_left_hp_mixer_controls[] =;

/* Right headphone mixer switch */
static const struct snd_kcontrol_new max98090_right_hp_mixer_controls[] =;

/* Left receiver mixer switch */
static const struct snd_kcontrol_new max98090_left_rcv_mixer_controls[] =;

/* Right receiver mixer switch */
static const struct snd_kcontrol_new max98090_right_rcv_mixer_controls[] =;

static const char *linmod_mux_text[] =;

static SOC_ENUM_SINGLE_DECL(linmod_mux_enum,
			    M98090_REG_LOUTR_MIXER,
			    M98090_LINMOD_SHIFT,
			    linmod_mux_text);

static const struct snd_kcontrol_new max98090_linmod_mux =;

static const char *mixhpsel_mux_text[] =;

/*
 * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable
 */
static SOC_ENUM_SINGLE_DECL(mixhplsel_mux_enum,
			    M98090_REG_HP_CONTROL,
			    M98090_MIXHPLSEL_SHIFT,
			    mixhpsel_mux_text);

static const struct snd_kcontrol_new max98090_mixhplsel_mux =;

static SOC_ENUM_SINGLE_DECL(mixhprsel_mux_enum,
			    M98090_REG_HP_CONTROL,
			    M98090_MIXHPRSEL_SHIFT,
			    mixhpsel_mux_text);

static const struct snd_kcontrol_new max98090_mixhprsel_mux =;

static const struct snd_soc_dapm_widget max98090_dapm_widgets[] =;

static const struct snd_soc_dapm_widget max98091_dapm_widgets[] =;

static const struct snd_soc_dapm_route max98090_dapm_routes[] =;

static const struct snd_soc_dapm_route max98091_dapm_routes[] =;

static int max98090_add_widgets(struct snd_soc_component *component)
{}

static const int pclk_rates[] =;

static const int lrclk_rates[] =;

static const int user_pclk_rates[] =;

static const int user_lrclk_rates[] =;

static const unsigned long long ni_value[] =;

static const unsigned long long mi_value[] =;

static void max98090_configure_bclk(struct snd_soc_component *component)
{}

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

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

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

static const int dmic_divisors[] =;

static const int comp_lrclk_rates[] =;

struct dmic_table {};

static const struct dmic_table dmic_table[] =;

static int max98090_find_divisor(int target_freq, int pclk)
{}

static int max98090_find_closest_pclk(int pclk)
{}

static int max98090_configure_dmic(struct max98090_priv *max98090,
				   int target_dmic_clk, int pclk, int fs)
{}

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

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

/*
 * PLL / Sysclk
 */
static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
				   int clk_id, unsigned int freq, int dir)
{}

static int max98090_dai_mute(struct snd_soc_dai *codec_dai, int mute,
			     int direction)
{}

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

static void max98090_pll_det_enable_work(struct work_struct *work)
{}

static void max98090_pll_det_disable_work(struct work_struct *work)
{}

static void max98090_pll_work(struct max98090_priv *max98090)
{}

static void max98090_jack_work(struct work_struct *work)
{}

static irqreturn_t max98090_interrupt(int irq, void *data)
{}

/**
 * max98090_mic_detect - Enable microphone detection via the MAX98090 IRQ
 *
 * @component:  MAX98090 component
 * @jack:   jack to report detection events on
 *
 * Enable microphone detection via IRQ on the MAX98090.  If GPIOs are
 * being used to bring out signals to the processor then only platform
 * data configuration is needed for MAX98090 and processor GPIOs should
 * be configured using snd_soc_jack_add_gpios() instead.
 *
 * If no jack is supplied detection will be disabled.
 */
int max98090_mic_detect(struct snd_soc_component *component,
	struct snd_soc_jack *jack)
{}
EXPORT_SYMBOL_GPL();

#define MAX98090_RATES
#define MAX98090_FORMATS

static const struct snd_soc_dai_ops max98090_dai_ops =;

static struct snd_soc_dai_driver max98090_dai =;

static int max98090_probe(struct snd_soc_component *component)
{}

static void max98090_remove(struct snd_soc_component *component)
{}

static void max98090_seq_notifier(struct snd_soc_component *component,
	enum snd_soc_dapm_type event, int subseq)
{}

static const struct snd_soc_component_driver soc_component_dev_max98090 =;

static const struct regmap_config max98090_regmap =;

static const struct i2c_device_id max98090_i2c_id[] =;
MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);

static int max98090_i2c_probe(struct i2c_client *i2c)
{}

static void max98090_i2c_shutdown(struct i2c_client *i2c)
{}

static void max98090_i2c_remove(struct i2c_client *client)
{}

#ifdef CONFIG_PM
static int max98090_runtime_resume(struct device *dev)
{}

static int max98090_runtime_suspend(struct device *dev)
{}
#endif

#ifdef CONFIG_PM_SLEEP
static int max98090_resume(struct device *dev)
{}
#endif

static const struct dev_pm_ops max98090_pm =;

#ifdef CONFIG_OF
static const struct of_device_id max98090_of_match[] =;
MODULE_DEVICE_TABLE(of, max98090_of_match);
#endif

#ifdef CONFIG_ACPI
static const struct acpi_device_id max98090_acpi_match[] =;
MODULE_DEVICE_TABLE(acpi, max98090_acpi_match);
#endif

static struct i2c_driver max98090_i2c_driver =;

module_i2c_driver();

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