linux/sound/soc/codecs/es8311.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * es8311.c -- es8311 ALSA SoC audio driver
 *
 * Copyright (C) 2024 Matteo Martelli <[email protected]>
 *
 * Author: Matteo Martelli <[email protected]>
 */

#include "linux/array_size.h"
#include "sound/pcm.h"
#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include "es8311.h"

#define ES8311_NUM_RATES
#define ES8311_RATES
#define ES8311_FORMATS

struct es8311_priv {};

static const DECLARE_TLV_DB_SCALE(es8311_adc_vol_tlv, -9550, 50, 0);
static const DECLARE_TLV_DB_SCALE(es8311_pga_gain_tlv, 0, 300, 0);
static const DECLARE_TLV_DB_SCALE(es8311_adc_scale_tlv, 0, 600, 0);

#define ES8311_DB_LRCK_STEPS

static const char *const es8311_level_winsize_txt[] =;

static SOC_ENUM_SINGLE_DECL(
	es8311_alc_winsize, ES8311_ADC4,
	ES8311_ADC4_ALC_WINSIZE_SHIFT, es8311_level_winsize_txt);
static const DECLARE_TLV_DB_RANGE(es8311_level_tlv,
	0, 1, TLV_DB_SCALE_ITEM(-3010, 600, 0),
	2, 3, TLV_DB_SCALE_ITEM(-2060, 250, 0),
	4, 5, TLV_DB_SCALE_ITEM(-1610, 160, 0),
	6, 7, TLV_DB_SCALE_ITEM(-1320, 120, 0),
	8, 9, TLV_DB_SCALE_ITEM(-1100, 90, 0),
	10, 11, TLV_DB_SCALE_ITEM(-930, 80, 0),
	12, 15, TLV_DB_SCALE_ITEM(-780, 60, 0),
);

static const char *const es8311_ramprate_txt[] =;
static SOC_ENUM_SINGLE_DECL(
	es8311_adc_ramprate, ES8311_ADC1,
	ES8311_ADC1_RAMPRATE_SHIFT, es8311_ramprate_txt);

static const char *const es8311_automute_winsize_txt[] =;
static SOC_ENUM_SINGLE_DECL(
	es8311_automute_winsize, ES8311_ADC6,
	ES8311_ADC6_AUTOMUTE_WS_SHIFT, es8311_automute_winsize_txt);
static const DECLARE_TLV_DB_RANGE(es8311_automute_ng_tlv,
	0, 7, TLV_DB_SCALE_ITEM(-9600, 600, 0),
	8, 15, TLV_DB_SCALE_ITEM(-5100, 300, 0),
);
static const DECLARE_TLV_DB_SCALE(es8311_automute_vol_tlv, -2800, 400, 0);

static const DECLARE_TLV_DB_SCALE(es8311_dac_vol_tlv, -9550, 50, 0);
static SOC_ENUM_SINGLE_DECL(
	es8311_drc_winsize, ES8311_DAC4,
	ES8311_DAC4_DRC_WINSIZE_SHIFT, es8311_level_winsize_txt);
static SOC_ENUM_SINGLE_DECL(
	es8311_dac_ramprate, ES8311_DAC6,
	ES8311_DAC6_RAMPRATE_SHIFT, es8311_ramprate_txt);

static const char *const es8311_out_mode_txt[] =;
static SOC_ENUM_SINGLE_DECL(
	es8311_out_mode, ES8311_SYS9,
	ES8311_SYS9_HPSW_SHIFT, es8311_out_mode_txt);

static const struct snd_kcontrol_new es8311_snd_controls[] =;

static const char *const es8311_diff_src_txt[] =;
static SOC_ENUM_SINGLE_DECL(
	es8311_diff_src_enum, ES8311_SYS10,
	ES8311_SYS10_LINESEL_SHIFT, es8311_diff_src_txt);
static const struct snd_kcontrol_new es8311_diff_src_mux =;

static const char *const es8311_dmic_src_txt[] =;
static SOC_ENUM_SINGLE_DECL(
	es8311_dmic_src_enum, ES8311_SYS10,
	ES8311_SYS10_DMIC_ON_SHIFT, es8311_dmic_src_txt);
static const struct snd_kcontrol_new es8311_dmic_src_mux =;

static const char * const es8311_aif1tx_src_txt[] =;
static SOC_ENUM_SINGLE_DECL(
	es8311_aif1tx_src_enum, ES8311_GPIO,
	ES8311_GPIO_ADCDAT_SEL_SHIFT, es8311_aif1tx_src_txt);
static const struct snd_kcontrol_new es8311_aif1tx_src_mux =;

static const char * const es8311_dac_src_txt[] =;
static SOC_ENUM_SINGLE_DECL(
	es8311_dac_src_enum, ES8311_SDP_IN,
	ES8311_SDP_IN_SEL_SHIFT, es8311_dac_src_txt);
static const struct snd_kcontrol_new es8311_dac_src_mux =;

static const struct snd_soc_dapm_widget es8311_dapm_widgets[] =;

static const struct snd_soc_dapm_route es8311_dapm_routes[] =;

/* Bit clock divider values:
 * from 1 to 20: the register takes the div value - 1
 * above 20: the register takes the corresponding idx of the div value
 *           in the following table + 20
 */
#define ES8311_BCLK_DIV_IDX_OFFSET
static const unsigned int es8311_bclk_divs[] =;

struct es8311_mclk_coeff {};

#define ES8311_MCLK_MAX_FREQ

/* Coefficients for common master clock frequencies based on clock table from
 * documentation. Limited to have a ratio of adc (or dac) clock to lrclk equal
 * to 256. This to keep the default adc and dac oversampling and adc scale
 * settings. Internal mclk dividers and multipliers are dynamically adjusted to
 * support, respectively, multiples (up to x8) and factors (/2,4,8) of listed
 * mclks frequencies (see es8311_cmp_adj_mclk_coeff).
 * All rates are supported when mclk/rate ratio is 32, 64, 128, 256, 384 or 512
 * (upper limit due to max mclk freq of 49.2MHz).
 */
static const struct es8311_mclk_coeff es8311_mclk_coeffs[] =;

/* Compare coeff with provided mclk_freq and adjust it if needed.
 * If frequencies match, return 0 and the unaltered coeff copy into out_coeff.
 * If mclk_freq is a valid multiple or factor of coeff mclk freq, return 0 and
 * the adjusted coeff copy into out_coeff.
 * Return -EINVAL otherwise.
 */
static int es8311_cmp_adj_mclk_coeff(unsigned int mclk_freq,
				     const struct es8311_mclk_coeff *coeff,
				     struct es8311_mclk_coeff *out_coeff)
{}

static int es8311_get_mclk_coeff(unsigned int mclk_freq, unsigned int rate,
				 struct es8311_mclk_coeff *out_coeff)
{}

static void es8311_set_sysclk_constraints(unsigned int mclk_freq,
					  struct es8311_priv *es8311)
{}

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

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

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

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

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

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

static const struct snd_soc_dai_ops es8311_dai_ops =;

static struct snd_soc_dai_driver es8311_dai =;

static void es8311_reset(struct snd_soc_component *component, bool reset)
{}

static int es8311_suspend(struct snd_soc_component *component)
{}

static int es8311_resume(struct snd_soc_component *component)
{}

static int es8311_component_probe(struct snd_soc_component *component)
{}

static const struct regmap_config es8311_regmap_config =;

static const struct snd_soc_component_driver es8311_component_driver =;

static int es8311_i2c_probe(struct i2c_client *i2c_client)
{}

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

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

static struct i2c_driver es8311_i2c_driver =;

module_i2c_driver();

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