linux/sound/soc/sunxi/sun50i-codec-analog.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * This driver supports the analog controls for the internal codec
 * found in Allwinner's A64 SoC.
 *
 * Copyright (C) 2016 Chen-Yu Tsai <[email protected]>
 * Copyright (C) 2017 Marcus Cooper <[email protected]>
 * Copyright (C) 2018 Vasily Khoruzhick <[email protected]>
 *
 * Based on sun8i-codec-analog.c
 *
 */

#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>

#include "sun8i-adda-pr-regmap.h"

/* Codec analog control register offsets and bit fields */
#define SUN50I_ADDA_HP_CTRL
#define SUN50I_ADDA_HP_CTRL_PA_CLK_GATE
#define SUN50I_ADDA_HP_CTRL_HPPA_EN
#define SUN50I_ADDA_HP_CTRL_HPVOL

#define SUN50I_ADDA_OL_MIX_CTRL
#define SUN50I_ADDA_OL_MIX_CTRL_MIC1
#define SUN50I_ADDA_OL_MIX_CTRL_MIC2
#define SUN50I_ADDA_OL_MIX_CTRL_PHONE
#define SUN50I_ADDA_OL_MIX_CTRL_PHONEN
#define SUN50I_ADDA_OL_MIX_CTRL_LINEINL
#define SUN50I_ADDA_OL_MIX_CTRL_DACL
#define SUN50I_ADDA_OL_MIX_CTRL_DACR

#define SUN50I_ADDA_OR_MIX_CTRL
#define SUN50I_ADDA_OR_MIX_CTRL_MIC1
#define SUN50I_ADDA_OR_MIX_CTRL_MIC2
#define SUN50I_ADDA_OR_MIX_CTRL_PHONE
#define SUN50I_ADDA_OR_MIX_CTRL_PHONEP
#define SUN50I_ADDA_OR_MIX_CTRL_LINEINR
#define SUN50I_ADDA_OR_MIX_CTRL_DACR
#define SUN50I_ADDA_OR_MIX_CTRL_DACL

#define SUN50I_ADDA_EARPIECE_CTRL0
#define SUN50I_ADDA_EARPIECE_CTRL0_EAR_RAMP_TIME
#define SUN50I_ADDA_EARPIECE_CTRL0_ESPSR

#define SUN50I_ADDA_EARPIECE_CTRL1
#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN
#define SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE
#define SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL

#define SUN50I_ADDA_LINEOUT_CTRL0
#define SUN50I_ADDA_LINEOUT_CTRL0_LEN
#define SUN50I_ADDA_LINEOUT_CTRL0_REN
#define SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL
#define SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL

#define SUN50I_ADDA_LINEOUT_CTRL1
#define SUN50I_ADDA_LINEOUT_CTRL1_VOL

#define SUN50I_ADDA_MIC1_CTRL
#define SUN50I_ADDA_MIC1_CTRL_MIC1G
#define SUN50I_ADDA_MIC1_CTRL_MIC1AMPEN
#define SUN50I_ADDA_MIC1_CTRL_MIC1BOOST

#define SUN50I_ADDA_MIC2_CTRL
#define SUN50I_ADDA_MIC2_CTRL_MIC2G
#define SUN50I_ADDA_MIC2_CTRL_MIC2AMPEN
#define SUN50I_ADDA_MIC2_CTRL_MIC2BOOST

#define SUN50I_ADDA_LINEIN_CTRL
#define SUN50I_ADDA_LINEIN_CTRL_LINEING

#define SUN50I_ADDA_MIX_DAC_CTRL
#define SUN50I_ADDA_MIX_DAC_CTRL_DACAREN
#define SUN50I_ADDA_MIX_DAC_CTRL_DACALEN
#define SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN
#define SUN50I_ADDA_MIX_DAC_CTRL_LMIXEN
#define SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE
#define SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE
#define SUN50I_ADDA_MIX_DAC_CTRL_RHPIS
#define SUN50I_ADDA_MIX_DAC_CTRL_LHPIS

#define SUN50I_ADDA_L_ADCMIX_SRC
#define SUN50I_ADDA_L_ADCMIX_SRC_MIC1
#define SUN50I_ADDA_L_ADCMIX_SRC_MIC2
#define SUN50I_ADDA_L_ADCMIX_SRC_PHONE
#define SUN50I_ADDA_L_ADCMIX_SRC_PHONEN
#define SUN50I_ADDA_L_ADCMIX_SRC_LINEINL
#define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL
#define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR

#define SUN50I_ADDA_R_ADCMIX_SRC
#define SUN50I_ADDA_R_ADCMIX_SRC_MIC1
#define SUN50I_ADDA_R_ADCMIX_SRC_MIC2
#define SUN50I_ADDA_R_ADCMIX_SRC_PHONE
#define SUN50I_ADDA_R_ADCMIX_SRC_PHONEP
#define SUN50I_ADDA_R_ADCMIX_SRC_LINEINR
#define SUN50I_ADDA_R_ADCMIX_SRC_OMIXR
#define SUN50I_ADDA_R_ADCMIX_SRC_OMIXL

#define SUN50I_ADDA_ADC_CTRL
#define SUN50I_ADDA_ADC_CTRL_ADCREN
#define SUN50I_ADDA_ADC_CTRL_ADCLEN
#define SUN50I_ADDA_ADC_CTRL_ADCG

#define SUN50I_ADDA_HS_MBIAS_CTRL
#define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN

#define SUN50I_ADDA_MDET_CTRL
#define SUN50I_ADDA_MDET_CTRL_SELDETADC_FS
#define SUN50I_ADDA_MDET_CTRL_SELDETADC_DB
#define SUN50I_ADDA_MDET_CTRL_SELDETADC_BF

#define SUN50I_ADDA_JACK_MIC_CTRL
#define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN
#define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN
#define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN
#define SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN

/* mixer controls */
static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] =;

/* ADC mixer controls */
static const struct snd_kcontrol_new sun50i_codec_adc_mixer_controls[] =;

static const DECLARE_TLV_DB_SCALE(sun50i_codec_out_mixer_pregain_scale,
				  -450, 150, 0);
static const DECLARE_TLV_DB_RANGE(sun50i_codec_mic_gain_scale,
	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
	1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
);

static const DECLARE_TLV_DB_SCALE(sun50i_codec_hp_vol_scale, -6300, 100, 1);

static const DECLARE_TLV_DB_RANGE(sun50i_codec_lineout_vol_scale,
	0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
	2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
);

static const DECLARE_TLV_DB_RANGE(sun50i_codec_earpiece_vol_scale,
	0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
	2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
);

/* volume / mute controls */
static const struct snd_kcontrol_new sun50i_a64_codec_controls[] =;

static const char * const sun50i_codec_hp_src_enum_text[] =;

static SOC_ENUM_DOUBLE_DECL(sun50i_codec_hp_src_enum,
			    SUN50I_ADDA_MIX_DAC_CTRL,
			    SUN50I_ADDA_MIX_DAC_CTRL_LHPIS,
			    SUN50I_ADDA_MIX_DAC_CTRL_RHPIS,
			    sun50i_codec_hp_src_enum_text);

static const struct snd_kcontrol_new sun50i_codec_hp_src[] =;

static const struct snd_kcontrol_new sun50i_codec_hp_switch =;

static const char * const sun50i_codec_lineout_src_enum_text[] =;

static SOC_ENUM_DOUBLE_DECL(sun50i_codec_lineout_src_enum,
			    SUN50I_ADDA_LINEOUT_CTRL0,
			    SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL,
			    SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL,
			    sun50i_codec_lineout_src_enum_text);

static const struct snd_kcontrol_new sun50i_codec_lineout_src[] =;

static const struct snd_kcontrol_new sun50i_codec_lineout_switch =;

static const char * const sun50i_codec_earpiece_src_enum_text[] =;

static SOC_ENUM_SINGLE_DECL(sun50i_codec_earpiece_src_enum,
			    SUN50I_ADDA_EARPIECE_CTRL0,
			    SUN50I_ADDA_EARPIECE_CTRL0_ESPSR,
			    sun50i_codec_earpiece_src_enum_text);

static const struct snd_kcontrol_new sun50i_codec_earpiece_src[] =;

static const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] =;

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

static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] =;

static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] =;

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

static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv =;

static const struct of_device_id sun50i_codec_analog_of_match[] =;
MODULE_DEVICE_TABLE(of, sun50i_codec_analog_of_match);

static int sun50i_codec_analog_probe(struct platform_device *pdev)
{}

static struct platform_driver sun50i_codec_analog_driver =;
module_platform_driver();

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