linux/sound/soc/codecs/tas5805m.c

// SPDX-License-Identifier: GPL-2.0
//
// Driver for the TAS5805M Audio Amplifier
//
// Author: Andy Liu <[email protected]>
// Author: Daniel Beer <[email protected]>
//
// This is based on a driver originally written by Andy Liu at TI and
// posted here:
//
//    https://e2e.ti.com/support/audio-group/audio/f/audio-forum/722027/linux-tas5825m-linux-drivers
//
// It has been simplified a little and reworked for the 5.x ALSA SoC API.

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/atomic.h>
#include <linux/workqueue.h>

#include <sound/soc.h>
#include <sound/pcm.h>
#include <sound/initval.h>

/* Datasheet-defined registers on page 0, book 0 */
#define REG_PAGE
#define REG_DEVICE_CTRL_1
#define REG_DEVICE_CTRL_2
#define REG_SIG_CH_CTRL
#define REG_SAP_CTRL_1
#define REG_FS_MON
#define REG_BCK_MON
#define REG_CLKDET_STATUS
#define REG_VOL_CTL
#define REG_AGAIN
#define REG_ADR_PIN_CTRL
#define REG_ADR_PIN_CONFIG
#define REG_CHAN_FAULT
#define REG_GLOBAL_FAULT1
#define REG_GLOBAL_FAULT2
#define REG_FAULT
#define REG_BOOK

/* DEVICE_CTRL_2 register values */
#define DCTRL2_MODE_DEEP_SLEEP
#define DCTRL2_MODE_SLEEP
#define DCTRL2_MODE_HIZ
#define DCTRL2_MODE_PLAY

#define DCTRL2_MUTE
#define DCTRL2_DIS_DSP

/* This sequence of register writes must always be sent, prior to the
 * 5ms delay while we wait for the DSP to boot.
 */
static const uint8_t dsp_cfg_preboot[] =;

static const uint32_t tas5805m_volume[] =;

#define TAS5805M_VOLUME_MAX
#define TAS5805M_VOLUME_MIN

struct tas5805m_priv {};

static void set_dsp_scale(struct regmap *rm, int offset, int vol)
{}

static void tas5805m_refresh(struct tas5805m_priv *tas5805m)
{}

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

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

static inline int volume_is_valid(int v)
{}

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

static const struct snd_kcontrol_new tas5805m_snd_controls[] =;

static void send_cfg(struct regmap *rm,
		     const uint8_t *s, unsigned int len)
{}

/* The TAS5805M DSP can't be configured until the I2S clock has been
 * present and stable for 5ms, or else it won't boot and we get no
 * sound.
 */
static int tas5805m_trigger(struct snd_pcm_substream *substream, int cmd,
			    struct snd_soc_dai *dai)
{}

static void do_work(struct work_struct *work)
{}

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

static const struct snd_soc_dapm_route tas5805m_audio_map[] =;

static const struct snd_soc_dapm_widget tas5805m_dapm_widgets[] =;

static const struct snd_soc_component_driver soc_codec_dev_tas5805m =;

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

static const struct snd_soc_dai_ops tas5805m_dai_ops =;

static struct snd_soc_dai_driver tas5805m_dai =;

static const struct regmap_config tas5805m_regmap =;

static int tas5805m_i2c_probe(struct i2c_client *i2c)
{}

static void tas5805m_i2c_remove(struct i2c_client *i2c)
{}

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

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id tas5805m_of_match[] =;
MODULE_DEVICE_TABLE(of, tas5805m_of_match);
#endif

static struct i2c_driver tas5805m_i2c_driver =;

module_i2c_driver();

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