linux/sound/soc/codecs/sta32x.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system
 *
 * Copyright: 2011 Raumfeld GmbH
 * Author: Johannes Stezenbach <[email protected]>
 *
 * based on code from:
 *	Wolfson Microelectronics PLC.
 *	  Mark Brown <[email protected]>
 *	Freescale Semiconductor, Inc.
 *	  Timur Tabi <[email protected]>
 */

#define pr_fmt(fmt)

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

#include <sound/sta32x.h>
#include "sta32x.h"

#define STA32X_RATES

#define STA32X_FORMATS

/* Power-up register defaults */
static const struct reg_default sta32x_regs[] =;

static const struct regmap_range sta32x_write_regs_range[] =;

static const struct regmap_range sta32x_read_regs_range[] =;

static const struct regmap_range sta32x_volatile_regs_range[] =;

static const struct regmap_access_table sta32x_write_regs =;

static const struct regmap_access_table sta32x_read_regs =;

static const struct regmap_access_table sta32x_volatile_regs =;

/* regulator power supply names */
static const char *sta32x_supply_names[] =;

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

static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1);
static const DECLARE_TLV_DB_SCALE(tone_tlv, -120, 200, 0);

static const char *sta32x_drc_ac[] =;
static const char *sta32x_auto_eq_mode[] =;
static const char *sta32x_auto_gc_mode[] =;
static const char *sta32x_auto_xo_mode[] =;
static const char *sta32x_preset_eq_mode[] =;
static const char *sta32x_limiter_select[] =;
static const char *sta32x_limiter_attack_rate[] =;
static const char *sta32x_limiter_release_rate[] =;
static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_attack_tlv,
	0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),
	8, 16, TLV_DB_SCALE_ITEM(300, 100, 0),
);

static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_release_tlv,
	0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
	1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),
	2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),
	3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),
	8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),
);

static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_attack_tlv,
	0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),
	8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),
	14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),
);

static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_release_tlv,
	0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
	1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),
	3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),
	5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),
	13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
);

static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum,
			    STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
			    sta32x_drc_ac);
static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum,
			    STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
			    sta32x_auto_eq_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum,
			    STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
			    sta32x_auto_gc_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum,
			    STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
			    sta32x_auto_xo_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum,
			    STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
			    sta32x_preset_eq_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum,
			    STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
			    sta32x_limiter_select);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum,
			    STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
			    sta32x_limiter_select);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum,
			    STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
			    sta32x_limiter_select);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum,
			    STA32X_L1AR, STA32X_LxA_SHIFT,
			    sta32x_limiter_attack_rate);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum,
			    STA32X_L2AR, STA32X_LxA_SHIFT,
			    sta32x_limiter_attack_rate);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum,
			    STA32X_L1AR, STA32X_LxR_SHIFT,
			    sta32x_limiter_release_rate);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum,
			    STA32X_L2AR, STA32X_LxR_SHIFT,
			    sta32x_limiter_release_rate);

/* byte array controls for setting biquad, mixer, scaling coefficients;
 * for biquads all five coefficients need to be set in one go,
 * mixer and pre/postscale coefs can be set individually;
 * each coef is 24bit, the bytes are ordered in the same way
 * as given in the STA32x data sheet (big endian; b1, b2, a1, a2, b0)
 */

static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_info *uinfo)
{}

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

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

static int sta32x_sync_coef_shadow(struct snd_soc_component *component)
{}

static int sta32x_cache_sync(struct snd_soc_component *component)
{}

/* work around ESD issue where sta32x resets and loses all configuration */
static void sta32x_watchdog(struct work_struct *work)
{}

static void sta32x_watchdog_start(struct sta32x_priv *sta32x)
{}

static void sta32x_watchdog_stop(struct sta32x_priv *sta32x)
{}

#define SINGLE_COEF(xname, index)

#define BIQUAD_COEFS(xname, index)

static const struct snd_kcontrol_new sta32x_snd_controls[] =;

static const struct snd_soc_dapm_widget sta32x_dapm_widgets[] =;

static const struct snd_soc_dapm_route sta32x_dapm_routes[] =;

/* MCLK interpolation ratio per fs */
static struct {} interpolation_ratios[] =;

/* MCLK to fs clock ratios */
static int mcs_ratio_table[3][7] =;

/**
 * sta32x_set_dai_sysclk - configure MCLK
 * @codec_dai: the codec DAI
 * @clk_id: the clock ID (ignored)
 * @freq: the MCLK input frequency
 * @dir: the clock direction (ignored)
 *
 * The value of MCLK is used to determine which sample rates are supported
 * by the STA32X, based on the mclk_ratios table.
 *
 * This function must be called by the machine driver's 'startup' function,
 * otherwise the list of supported sample rates will not be available in
 * time for ALSA.
 *
 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
 * theoretically possible sample rates to be enabled. Call it again with a
 * proper value set one the external clock is set (most probably you would do
 * that from a machine's driver 'hw_param' hook.
 */
static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
		int clk_id, unsigned int freq, int dir)
{}

/**
 * sta32x_set_dai_fmt - configure the codec for the selected audio format
 * @codec_dai: the codec DAI
 * @fmt: a SND_SOC_DAIFMT_x value indicating the data format
 *
 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
 * codec accordingly.
 */
static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
			      unsigned int fmt)
{}

/**
 * sta32x_hw_params - program the STA32X with the given hardware parameters.
 * @substream: the audio stream
 * @params: the hardware parameters to set
 * @dai: the SOC DAI (ignored)
 *
 * This function programs the hardware with the values provided.
 * Specifically, the sample rate and the data format.
 */
static int sta32x_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{}

static int sta32x_startup_sequence(struct sta32x_priv *sta32x)
{}

/**
 * sta32x_set_bias_level - DAPM callback
 * @component: the component device
 * @level: DAPM power level
 *
 * This is called by ALSA to put the component into low power mode
 * or to wake it up.  If the component is powered off completely
 * all registers must be restored after power on.
 */
static int sta32x_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{}

static const struct snd_soc_dai_ops sta32x_dai_ops =;

static struct snd_soc_dai_driver sta32x_dai =;

static int sta32x_probe(struct snd_soc_component *component)
{}

static void sta32x_remove(struct snd_soc_component *component)
{}

static const struct snd_soc_component_driver sta32x_component =;

static const struct regmap_config sta32x_regmap =;

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

static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x)
{}
#endif

static int sta32x_i2c_probe(struct i2c_client *i2c)
{}

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

static struct i2c_driver sta32x_i2c_driver =;

module_i2c_driver();

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