Commit 9fa6a693 authored by Shenghao Ding's avatar Shenghao Ding Committed by Takashi Iwai
Browse files

ALSA: hda/tas2781: Remove tas2781_spi_fwlib.c and leverage SND_SOC_TAS2781_FMWLIB



Most codes in tas2781_spi_fwlib.c are same as tas2781-fmwlib.c, mainly for
firmware parsing, only differece is the register reading, bit update and
book switching in i2c and spi. The main purpose of this patch is for code
cleaup and arrange the shared part for i2c and spi.

Signed-off-by: default avatarShenghao Ding <shenghao-ding@ti.com>
Acked-by: default avatarMark Brown <broonie@kernel.org>
Link: https://patch.msgid.link/20250429111055.567-1-shenghao-ding@ti.com


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 849c83fe
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
//
// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier
//
// Copyright (C) 2025 Texas Instruments Incorporated
// https://www.ti.com
//
// The TAS2563/TAS2781 driver implements a flexible and configurable
// algo coefficient setting for one, two, or even multiple
// TAS2563/TAS2781 chips.
//
// Author: Shenghao Ding <shenghao-ding@ti.com>
//

#ifndef __TAS2781_COMLIB_I2C_H__
#define __TAS2781_COMLIB_I2C_H__

void tasdevice_reset(struct tasdevice_priv *tas_dev);
int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
	struct module *module,
	void (*cont)(const struct firmware *fw, void *context));
struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c);
int tasdevice_init(struct tasdevice_priv *tas_priv);
int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
	unsigned short chn);
int tasdevice_dev_update_bits(
	struct tasdevice_priv *tasdevice, unsigned short chn,
	unsigned int reg, unsigned int mask, unsigned int value);
int tasdevice_amp_putvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
int tasdevice_amp_getvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
int tasdevice_digital_getvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
int tasdevice_digital_putvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
#endif /* __TAS2781_COMLIB_I2C_H__ */
+19 −26
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
	SNDRV_PCM_FMTBIT_S24_LE | \
	SNDRV_PCM_FMTBIT_S32_LE)

#define TASDEVICE_CRC8_POLYNOMIAL		0x4d

/* PAGE Control Register (available in page0 of each book) */
#define TASDEVICE_PAGE_SELECT		0x00
#define TASDEVICE_BOOKCTL_PAGE		0x00
@@ -193,6 +195,7 @@ struct tasdevice_priv {
	bool force_fwload_status;
	bool playback_started;
	bool isacpi;
	bool isspi;
	bool is_user_space_calidata;
	unsigned int global_addr;

@@ -210,41 +213,31 @@ struct tasdevice_priv {
	int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv,
		struct tasdev_blk *block);

	int (*change_chn_book)(struct tasdevice_priv *tas_priv,
		unsigned short chn, int book);
	int (*update_bits)(struct tasdevice_priv *tas_priv,
		unsigned short chn, unsigned int reg, unsigned int mask,
		unsigned int value);
	int (*dev_read)(struct tasdevice_priv *tas_priv,
		unsigned short chn, unsigned int reg, unsigned int *value);
	int (*dev_bulk_read)(struct tasdevice_priv *tas_priv,
		unsigned short chn, unsigned int reg, unsigned char *p_data,
		unsigned int n_length);
	int (*save_calibration)(struct tasdevice_priv *tas_priv);
	void (*apply_calibration)(struct tasdevice_priv *tas_priv);
};

void tasdevice_reset(struct tasdevice_priv *tas_dev);
int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
	struct module *module,
	void (*cont)(const struct firmware *fw, void *context));
struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c);
int tasdevice_init(struct tasdevice_priv *tas_priv);
void tasdevice_remove(struct tasdevice_priv *tas_priv);
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
	unsigned short chn);
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned int *value);
int tasdevice_dev_bulk_read(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned char *p_data,
	unsigned int n_length);
int tasdevice_dev_write(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned int value);
int tasdevice_dev_bulk_write(
	struct tasdevice_priv *tas_priv, unsigned short chn,
	unsigned int reg, unsigned char *p_data, unsigned int n_length);
int tasdevice_dev_bulk_read(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned char *p_data,
	unsigned int n_length);
int tasdevice_dev_update_bits(
	struct tasdevice_priv *tasdevice, unsigned short chn,
	unsigned int reg, unsigned int mask, unsigned int value);
int tasdevice_amp_putvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
int tasdevice_amp_getvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
int tasdevice_digital_putvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
int tasdevice_digital_getvol(struct tasdevice_priv *tas_priv,
	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);

void tasdevice_remove(struct tasdevice_priv *tas_priv);
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
#endif /* __TAS2781_H__ */
+3 −1
Original line number Diff line number Diff line
@@ -186,7 +186,7 @@ config SND_HDA_SCODEC_TAS2781_I2C
	depends on ACPI
	depends on EFI
	depends on SND_SOC
	select SND_SOC_TAS2781_COMLIB
	select SND_SOC_TAS2781_COMLIB_I2C
	select SND_SOC_TAS2781_FMWLIB
	select CRC32
	help
@@ -202,6 +202,8 @@ config SND_HDA_SCODEC_TAS2781_SPI
	depends on ACPI
	depends on EFI
	depends on SND_SOC
	select SND_SOC_TAS2781_FMWLIB
	select CRC8
	select CRC32
	help
	  Say Y or M here to include TAS2781 SPI HD-audio side codec support
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ snd-hda-scodec-cs35l56-i2c-y := cs35l56_hda_i2c.o
snd-hda-scodec-cs35l56-spi-y :=	cs35l56_hda_spi.o
snd-hda-scodec-component-y :=	hda_component.o
snd-hda-scodec-tas2781-i2c-y :=	tas2781_hda_i2c.o
snd-hda-scodec-tas2781-spi-y :=	tas2781_hda_spi.o tas2781_spi_fwlib.o
snd-hda-scodec-tas2781-spi-y :=	tas2781_hda_spi.o

# common driver
obj-$(CONFIG_SND_HDA) := snd-hda-codec.o

sound/pci/hda/tas2781-spi.h

deleted100644 → 0
+0 −157
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
//
// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier
//
// Copyright (C) 2024 Texas Instruments Incorporated
// https://www.ti.com
//
// The TAS2781 driver implements a flexible and configurable
// algo coefficient setting for TAS2781 chips.
//
// Author: Baojun Xu <baojun.xu@ti.com>
//

#ifndef __TAS2781_SPI_H__
#define __TAS2781_SPI_H__

#define TASDEVICE_RATES			\
	(SNDRV_PCM_RATE_44100 |	SNDRV_PCM_RATE_48000 | \
	SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200)

#define TASDEVICE_FORMATS		\
	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
	SNDRV_PCM_FMTBIT_S32_LE)

#define TASDEVICE_MAX_BOOK_NUM		256
#define TASDEVICE_MAX_PAGE		256

#define TASDEVICE_MAX_SIZE	(TASDEVICE_MAX_BOOK_NUM * TASDEVICE_MAX_PAGE)

/* PAGE Control Register (available in page0 of each book) */
#define TASDEVICE_PAGE_SELECT		0x00
#define TASDEVICE_BOOKCTL_PAGE		0x00
#define TASDEVICE_BOOKCTL_REG		GENMASK(7, 1)
#define TASDEVICE_BOOK_ID(reg)		(((reg) & GENMASK(24, 16)) >> 16)
#define TASDEVICE_PAGE_ID(reg)		(((reg) & GENMASK(15, 8)) >> 8)
#define TASDEVICE_REG_ID(reg)		(((reg) & GENMASK(7, 1)) >> 1)
#define TASDEVICE_PAGE_REG(reg)		((reg) & GENMASK(15, 1))
#define TASDEVICE_REG(book, page, reg)	\
	(((book) << 16) | ((page) << 8) | ((reg) << 1))

/* Software Reset */
#define TAS2781_REG_SWRESET		TASDEVICE_REG(0x0, 0x0, 0x01)
#define TAS2781_REG_SWRESET_RESET	BIT(0)

/* System Reset Check Register */
#define TAS2781_REG_CLK_CONFIG		TASDEVICE_REG(0x0, 0x0, 0x5c)
#define TAS2781_REG_CLK_CONFIG_RESET	(0x19)
#define TAS2781_PRE_POST_RESET_CFG	3

/* Block Checksum */
#define TASDEVICE_CHECKSUM		TASDEVICE_REG(0x0, 0x0, 0x7e)

/* Volume control */
#define TAS2781_DVC_LVL			TASDEVICE_REG(0x0, 0x0, 0x1a)
#define TAS2781_AMP_LEVEL		TASDEVICE_REG(0x0, 0x0, 0x03)
#define TAS2781_AMP_LEVEL_MASK		GENMASK(5, 1)

#define TASDEVICE_CMD_SING_W		0x1
#define TASDEVICE_CMD_BURST		0x2
#define TASDEVICE_CMD_DELAY		0x3
#define TASDEVICE_CMD_FIELD_W		0x4

#define TAS2781_SPI_MAX_FREQ		(4 * HZ_PER_MHZ)

#define TASDEVICE_CRC8_POLYNOMIAL		0x4d
#define TASDEVICE_SPEAKER_CALIBRATION_SIZE	20

/* Flag of calibration registers address. */
#define TASDEVICE_CALIBRATION_REG_ADDRESS	BIT(7)

#define TASDEVICE_CALIBRATION_DATA_NAME	L"CALI_DATA"
#define TASDEVICE_CALIBRATION_DATA_SIZE	256

enum calib_data {
	R0_VAL = 0,
	INV_R0,
	R0LOW,
	POWER,
	TLIM,
	CALIB_MAX
};

struct tasdevice_priv {
	struct tasdevice_fw *cali_data_fmw;
	struct tasdevice_rca rcabin;
	struct tasdevice_fw *fmw;
	struct gpio_desc *reset;
	struct mutex codec_lock;
	struct regmap *regmap;
	struct device *dev;

	unsigned char crc8_lkp_tbl[CRC8_TABLE_SIZE];
	unsigned char coef_binaryname[64];
	unsigned char rca_binaryname[64];
	unsigned char dev_name[32];

	bool force_fwload_status;
	bool playback_started;
	bool is_loading;
	bool is_loaderr;
	unsigned int cali_reg_array[CALIB_MAX];
	unsigned int cali_data[CALIB_MAX];
	unsigned int err_code;
	void *codec;
	int cur_book;
	int cur_prog;
	int cur_conf;
	int fw_state;
	int index;
	int irq;

	int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv,
					const struct firmware *fmw,
					int offset);
	int (*fw_parse_program_data)(struct tasdevice_priv *tas_priv,
				     struct tasdevice_fw *tas_fmw,
				     const struct firmware *fmw, int offset);
	int (*fw_parse_configuration_data)(struct tasdevice_priv *tas_priv,
					   struct tasdevice_fw *tas_fmw,
					   const struct firmware *fmw,
					   int offset);
	int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv,
				    struct tasdev_blk *block);

	int (*save_calibration)(struct tasdevice_priv *tas_priv);
	void (*apply_calibration)(struct tasdevice_priv *tas_priv);
};

int tasdevice_spi_dev_read(struct tasdevice_priv *tas_priv,
			   unsigned int reg, unsigned int *value);
int tasdevice_spi_dev_write(struct tasdevice_priv *tas_priv,
			    unsigned int reg, unsigned int value);
int tasdevice_spi_dev_bulk_write(struct tasdevice_priv *tas_priv,
				 unsigned int reg, unsigned char *p_data,
				 unsigned int n_length);
int tasdevice_spi_dev_bulk_read(struct tasdevice_priv *tas_priv,
				unsigned int reg, unsigned char *p_data,
				unsigned int n_length);
int tasdevice_spi_dev_update_bits(struct tasdevice_priv *tasdevice,
				  unsigned int reg, unsigned int mask,
				  unsigned int value);

void tasdevice_spi_select_cfg_blk(void *context, int conf_no,
				  unsigned char block_type);
void tasdevice_spi_config_info_remove(void *context);
int tasdevice_spi_dsp_parser(void *context);
int tasdevice_spi_rca_parser(void *context, const struct firmware *fmw);
void tasdevice_spi_dsp_remove(void *context);
void tasdevice_spi_calbin_remove(void *context);
int tasdevice_spi_select_tuningprm_cfg(void *context, int prm, int cfg_no,
				       int rca_conf_no);
int tasdevice_spi_prmg_load(void *context, int prm_no);
int tasdevice_spi_prmg_calibdata_load(void *context, int prm_no);
void tasdevice_spi_tuning_switch(void *context, int state);
int tas2781_spi_load_calibration(void *context, char *file_name,
				 unsigned short i);
#endif /* __TAS2781_SPI_H__ */
Loading