linux/sound/soc/codecs/da7210.c

// SPDX-License-Identifier: GPL-2.0+
//
// DA7210 ALSA Soc codec driver
//
// Copyright (c) 2009 Dialog Semiconductor
// Written by David Chen <[email protected]>
//
// Copyright (C) 2009 Renesas Solutions Corp.
// Cleanups by Kuninori Morimoto <[email protected]>
//
// Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S

#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>

/* DA7210 register space */
#define DA7210_PAGE_CONTROL
#define DA7210_CONTROL
#define DA7210_STATUS
#define DA7210_STARTUP1
#define DA7210_STARTUP2
#define DA7210_STARTUP3
#define DA7210_MIC_L
#define DA7210_MIC_R
#define DA7210_AUX1_L
#define DA7210_AUX1_R
#define DA7210_AUX2
#define DA7210_IN_GAIN
#define DA7210_INMIX_L
#define DA7210_INMIX_R
#define DA7210_ADC_HPF
#define DA7210_ADC
#define DA7210_ADC_EQ1_2
#define DA7210_ADC_EQ3_4
#define DA7210_ADC_EQ5
#define DA7210_DAC_HPF
#define DA7210_DAC_L
#define DA7210_DAC_R
#define DA7210_DAC_SEL
#define DA7210_SOFTMUTE
#define DA7210_DAC_EQ1_2
#define DA7210_DAC_EQ3_4
#define DA7210_DAC_EQ5
#define DA7210_OUTMIX_L
#define DA7210_OUTMIX_R
#define DA7210_OUT1_L
#define DA7210_OUT1_R
#define DA7210_OUT2
#define DA7210_HP_L_VOL
#define DA7210_HP_R_VOL
#define DA7210_HP_CFG
#define DA7210_ZERO_CROSS
#define DA7210_DAI_SRC_SEL
#define DA7210_DAI_CFG1
#define DA7210_DAI_CFG3
#define DA7210_PLL_DIV1
#define DA7210_PLL_DIV2
#define DA7210_PLL_DIV3
#define DA7210_PLL
#define DA7210_ALC_MAX
#define DA7210_ALC_MIN
#define DA7210_ALC_NOIS
#define DA7210_ALC_ATT
#define DA7210_ALC_REL
#define DA7210_ALC_DEL
#define DA7210_A_HID_UNLOCK
#define DA7210_A_TEST_UNLOCK
#define DA7210_A_PLL1
#define DA7210_A_CP_MODE

/* STARTUP1 bit fields */
#define DA7210_SC_MST_EN

/* MIC_L bit fields */
#define DA7210_MICBIAS_EN
#define DA7210_MIC_L_EN

/* MIC_R bit fields */
#define DA7210_MIC_R_EN

/* INMIX_L bit fields */
#define DA7210_IN_L_EN

/* INMIX_R bit fields */
#define DA7210_IN_R_EN

/* ADC bit fields */
#define DA7210_ADC_ALC_EN
#define DA7210_ADC_L_EN
#define DA7210_ADC_R_EN

/* DAC/ADC HPF fields */
#define DA7210_VOICE_F0_MASK
#define DA7210_VOICE_F0_25
#define DA7210_VOICE_EN

/* DAC_SEL bit fields */
#define DA7210_DAC_L_SRC_DAI_L
#define DA7210_DAC_L_EN
#define DA7210_DAC_R_SRC_DAI_R
#define DA7210_DAC_R_EN

/* OUTMIX_L bit fields */
#define DA7210_OUT_L_EN

/* OUTMIX_R bit fields */
#define DA7210_OUT_R_EN

/* HP_CFG bit fields */
#define DA7210_HP_2CAP_MODE
#define DA7210_HP_SENSE_EN
#define DA7210_HP_L_EN
#define DA7210_HP_MODE
#define DA7210_HP_R_EN

/* DAI_SRC_SEL bit fields */
#define DA7210_DAI_OUT_L_SRC
#define DA7210_DAI_OUT_R_SRC

/* DAI_CFG1 bit fields */
#define DA7210_DAI_WORD_S16_LE
#define DA7210_DAI_WORD_S20_3LE
#define DA7210_DAI_WORD_S24_LE
#define DA7210_DAI_WORD_S32_LE
#define DA7210_DAI_FLEN_64BIT
#define DA7210_DAI_MODE_SLAVE
#define DA7210_DAI_MODE_MASTER

/* DAI_CFG3 bit fields */
#define DA7210_DAI_FORMAT_I2SMODE
#define DA7210_DAI_FORMAT_LEFT_J
#define DA7210_DAI_FORMAT_RIGHT_J
#define DA7210_DAI_OE
#define DA7210_DAI_EN

/*PLL_DIV3 bit fields */
#define DA7210_PLL_DIV_L_MASK
#define DA7210_MCLK_RANGE_10_20_MHZ
#define DA7210_PLL_BYP

/* PLL bit fields */
#define DA7210_PLL_FS_MASK
#define DA7210_PLL_FS_8000
#define DA7210_PLL_FS_11025
#define DA7210_PLL_FS_12000
#define DA7210_PLL_FS_16000
#define DA7210_PLL_FS_22050
#define DA7210_PLL_FS_24000
#define DA7210_PLL_FS_32000
#define DA7210_PLL_FS_44100
#define DA7210_PLL_FS_48000
#define DA7210_PLL_FS_88200
#define DA7210_PLL_FS_96000
#define DA7210_MCLK_DET_EN
#define DA7210_MCLK_SRM_EN
#define DA7210_PLL_EN

/* SOFTMUTE bit fields */
#define DA7210_RAMP_EN

/* CONTROL bit fields */
#define DA7210_REG_EN
#define DA7210_BIAS_EN
#define DA7210_NOISE_SUP_EN

/* IN_GAIN bit fields */
#define DA7210_INPGA_L_VOL
#define DA7210_INPGA_R_VOL

/* ZERO_CROSS bit fields */
#define DA7210_AUX1_L_ZC
#define DA7210_AUX1_R_ZC
#define DA7210_HP_L_ZC
#define DA7210_HP_R_ZC

/* AUX1_L bit fields */
#define DA7210_AUX1_L_VOL
#define DA7210_AUX1_L_EN

/* AUX1_R bit fields */
#define DA7210_AUX1_R_VOL
#define DA7210_AUX1_R_EN

/* AUX2 bit fields */
#define DA7210_AUX2_EN

/* Minimum INPGA and AUX1 volume to enable noise suppression */
#define DA7210_INPGA_MIN_VOL_NS
#define DA7210_AUX1_MIN_VOL_NS

/* OUT1_L bit fields */
#define DA7210_OUT1_L_EN

/* OUT1_R bit fields */
#define DA7210_OUT1_R_EN

/* OUT2 bit fields */
#define DA7210_OUT2_OUTMIX_R
#define DA7210_OUT2_OUTMIX_L
#define DA7210_OUT2_EN

struct pll_div {};

/* PLL dividers table */
static const struct pll_div da7210_pll_div[] =;

enum clk_src {};

#define DA7210_VERSION

/*
 * Playback Volume
 *
 * max		: 0x3F (+15.0 dB)
 *		   (1.5 dB step)
 * min		: 0x11 (-54.0 dB)
 * mute		: 0x10
 * reserved	: 0x00 - 0x0F
 *
 * Reserved area are considered as "mute".
 */
static const DECLARE_TLV_DB_RANGE(hp_out_tlv,
	0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
	/* -54 dB to +15 dB */
	0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)
);

static const DECLARE_TLV_DB_RANGE(lineout_vol_tlv,
	0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
	/* -54dB to 15dB */
	0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)
);

static const DECLARE_TLV_DB_RANGE(mono_vol_tlv,
	0x0, 0x2, TLV_DB_SCALE_ITEM(-1800, 0, 1),
	/* -18dB to 6dB */
	0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0)
);

static const DECLARE_TLV_DB_RANGE(aux1_vol_tlv,
	0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
	/* -48dB to 21dB */
	0x11, 0x3f, TLV_DB_SCALE_ITEM(-4800, 150, 0)
);

static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1);
static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0);
static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);
static const DECLARE_TLV_DB_SCALE(aux2_vol_tlv, -600, 600, 0);
static const DECLARE_TLV_DB_SCALE(inpga_gain_tlv, -450, 150, 0);

/* ADC and DAC high pass filter f0 value */
static const char * const da7210_hpf_cutoff_txt[] =;

static SOC_ENUM_SINGLE_DECL(da7210_dac_hpf_cutoff,
			    DA7210_DAC_HPF, 0, da7210_hpf_cutoff_txt);

static SOC_ENUM_SINGLE_DECL(da7210_adc_hpf_cutoff,
			    DA7210_ADC_HPF, 0, da7210_hpf_cutoff_txt);

/* ADC and DAC voice (8kHz) high pass cutoff value */
static const char * const da7210_vf_cutoff_txt[] =;

static SOC_ENUM_SINGLE_DECL(da7210_dac_vf_cutoff,
			    DA7210_DAC_HPF, 4, da7210_vf_cutoff_txt);

static SOC_ENUM_SINGLE_DECL(da7210_adc_vf_cutoff,
			    DA7210_ADC_HPF, 4, da7210_vf_cutoff_txt);

static const char *da7210_hp_mode_txt[] =;

static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel,
			    DA7210_HP_CFG, 0, da7210_hp_mode_txt);

/* ALC can be enabled only if noise suppression is disabled */
static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{}

/* Noise suppression can be enabled only if following conditions are met
 *  ALC disabled
 *  ZC enabled for HP and AUX1 PGA
 *  INPGA_L_VOL and INPGA_R_VOL >= 10.5 dB
 *  AUX1_L_VOL and AUX1_R_VOL >= 6 dB
 */
static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new da7210_snd_controls[] =;

/*
 * DAPM Controls
 *
 * Current DAPM implementation covers almost all codec components e.g. IOs,
 * mixers, PGAs,ADC and DAC.
 */
/* In Mixer Left */
static const struct snd_kcontrol_new da7210_dapm_inmixl_controls[] =;

/* In Mixer Right */
static const struct snd_kcontrol_new da7210_dapm_inmixr_controls[] =;

/* Out Mixer Left */
static const struct snd_kcontrol_new da7210_dapm_outmixl_controls[] =;

/* Out Mixer Right */
static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] =;

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

/* DAPM widgets */
static const struct snd_soc_dapm_widget da7210_dapm_widgets[] =;

/* DAPM audio route definition */
static const struct snd_soc_dapm_route da7210_audio_map[] =;

/* Codec private data */
struct da7210_priv {};

static const struct reg_default da7210_reg_defaults[] =;

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

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

/*
 * Set PCM DAI word length.
 */
static int da7210_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{}

/*
 * Set DAI mode and Format
 */
static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
{}

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

#define DA7210_FORMATS

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

/**
 * da7210_set_dai_pll	:Configure the codec PLL
 * @codec_dai: pointer to codec DAI
 * @pll_id: da7210 has only one pll, so pll_id is always zero
 * @source: clock source
 * @fref: MCLK frequency, should be < 20MHz
 * @fout: FsDM value, Refer page 44 & 45 of datasheet
 *
 * Note: Supported PLL input frequencies are 12MHz, 13MHz, 13.5MHz, 14.4MHz,
 *       19.2MHz, 19.6MHz and 19.8MHz
 *
 * Return: Zero for success, negative error code for error
 */
static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
			      int source, unsigned int fref, unsigned int fout)
{}

/* DAI operations */
static const struct snd_soc_dai_ops da7210_dai_ops =;

static struct snd_soc_dai_driver da7210_dai =;

static int da7210_probe(struct snd_soc_component *component)
{}

static const struct snd_soc_component_driver soc_component_dev_da7210 =;

#if IS_ENABLED(CONFIG_I2C)

static const struct reg_sequence da7210_regmap_i2c_patch[] =;

static const struct regmap_config da7210_regmap_config_i2c =;

static int da7210_i2c_probe(struct i2c_client *i2c)
{}

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

/* I2C codec control layer */
static struct i2c_driver da7210_i2c_driver =;
#endif

#if defined(CONFIG_SPI_MASTER)

static const struct reg_sequence da7210_regmap_spi_patch[] =;

static const struct regmap_config da7210_regmap_config_spi =;

static int da7210_spi_probe(struct spi_device *spi)
{}

static struct spi_driver da7210_spi_driver =;
#endif

static int __init da7210_modinit(void)
{}
module_init();

static void __exit da7210_exit(void)
{}
module_exit(da7210_exit);

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