| /* SPDX-License-Identifier: GPL-2.0 */ | |
| // | |
| // ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier | |
| // | |
| // Copyright (C) 2022 - 2026 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> | |
| // Author: Kevin Lu <kevin-lu@ti.com> | |
| // Author: Baojun Xu <baojun.xu@ti.com> | |
| // | |
| #ifndef __TAS2781_H__ | |
| #define __TAS2781_H__ | |
| #ifdef CONFIG_SND_SOC_TAS2781_ACOUST_I2C | |
| #include <linux/debugfs.h> | |
| #endif | |
| #include "tas2781-dsp.h" | |
| /* version number */ | |
| #define TAS2781_DRV_VER 1 | |
| #define SMARTAMP_MODULE_NAME "tas2781" | |
| #define TAS2781_GLOBAL_ADDR 0x40 | |
| #define TAS2563_GLOBAL_ADDR 0x48 | |
| #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_CRC8_POLYNOMIAL 0x4d | |
| /* PAGE Control Register (available in page0 of each book) */ | |
| #define TASDEVICE_PAGE_SELECT 0x00 | |
| #define TASDEVICE_BOOKCTL_PAGE 0x00 | |
| #define TASDEVICE_BOOKCTL_REG 127 | |
| #define TASDEVICE_BOOK_ID(reg) (reg / (256 * 128)) | |
| #define TASDEVICE_PAGE_ID(reg) ((reg % (256 * 128)) / 128) | |
| #define TASDEVICE_PAGE_REG(reg) ((reg % (256 * 128)) % 128) | |
| #define TASDEVICE_PGRG(reg) (reg % (256 * 128)) | |
| #define TASDEVICE_REG(book, page, reg) (((book * 256 * 128) + \ | |
| (page * 128)) + reg) | |
| /* Software Reset, compatble with new device (TAS5825). */ | |
| #define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0x0, 0x01) | |
| #define TASDEVICE_REG_SWRESET_RESET BIT(0) | |
| #define TAS5825_REG_SWRESET_RESET (BIT(0) | BIT(4)) | |
| /* Checksum */ | |
| #define TASDEVICE_CHECKSUM_REG TASDEVICE_REG(0x0, 0x0, 0x7e) | |
| /* XM_340 */ | |
| #define TASDEVICE_XM_A1_REG TASDEVICE_REG(0x64, 0x02, 0x4c) | |
| /* XM_341 */ | |
| #define TASDEVICE_XM_A2_REG TASDEVICE_REG(0x64, 0x02, 0x64) | |
| /* Volume control */ | |
| #define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0c) | |
| #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 TAS2563_IDLE TASDEVICE_REG(0x00, 0x00, 0x3e) | |
| #define TAS2563_PRM_R0_REG TASDEVICE_REG(0x00, 0x0f, 0x34) | |
| #define TAS2563_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x02, 0x70) | |
| #define TAS2563_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x02, 0x48) | |
| #define TAS2563_PRM_ENFF_REG TASDEVICE_REG(0x00, 0x0d, 0x54) | |
| #define TAS2563_PRM_DISTCK_REG TASDEVICE_REG(0x00, 0x0d, 0x58) | |
| #define TAS2563_PRM_TE_SCTHR_REG TASDEVICE_REG(0x00, 0x0f, 0x60) | |
| #define TAS2563_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x0d, 0x74) | |
| #define TAS2563_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x0d, 0x7c) | |
| /* prm_Int_B0 */ | |
| #define TAS2563_TE_TA1_REG TASDEVICE_REG(0x00, 0x10, 0x0c) | |
| /* prm_Int_A1 */ | |
| #define TAS2563_TE_TA1_AT_REG TASDEVICE_REG(0x00, 0x10, 0x10) | |
| /* prm_TE_Beta */ | |
| #define TAS2563_TE_TA2_REG TASDEVICE_REG(0x00, 0x0f, 0x64) | |
| /* prm_TE_Beta1 */ | |
| #define TAS2563_TE_AT_REG TASDEVICE_REG(0x00, 0x0f, 0x68) | |
| /* prm_TE_1_Beta1 */ | |
| #define TAS2563_TE_DT_REG TASDEVICE_REG(0x00, 0x0f, 0x70) | |
| #define TAS2781_PRM_INT_MASK_REG TASDEVICE_REG(0x00, 0x00, 0x3b) | |
| #define TAS2781_PRM_CLK_CFG_REG TASDEVICE_REG(0x00, 0x00, 0x5c) | |
| #define TAS2781_PRM_RSVD_REG TASDEVICE_REG(0x00, 0x01, 0x19) | |
| #define TAS2781_PRM_TEST_57_REG TASDEVICE_REG(0x00, 0xfd, 0x39) | |
| #define TAS2781_PRM_TEST_62_REG TASDEVICE_REG(0x00, 0xfd, 0x3e) | |
| #define TAS2781_PRM_PVDD_UVLO_REG TASDEVICE_REG(0x00, 0x00, 0x71) | |
| #define TAS2781_PRM_CHNL_0_REG TASDEVICE_REG(0x00, 0x00, 0x03) | |
| #define TAS2781_PRM_NG_CFG0_REG TASDEVICE_REG(0x00, 0x00, 0x35) | |
| #define TAS2781_PRM_IDLE_CH_DET_REG TASDEVICE_REG(0x00, 0x00, 0x66) | |
| #define TAS2781_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x14, 0x38) | |
| #define TAS2781_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x14, 0x40) | |
| #define TAS2781_PRM_SINEGAIN2_REG TASDEVICE_REG(0x00, 0x14, 0x44) | |
| #define TAS2781_TEST_UNLOCK_REG TASDEVICE_REG(0x00, 0xfd, 0x0d) | |
| #define TAS2781_TEST_PAGE_UNLOCK 0x0d | |
| #define TAS2781_RUNTIME_LATCH_RE_REG TASDEVICE_REG(0x00, 0x00, 0x49) | |
| #define TAS2781_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x62, 0x48) | |
| #define TAS2781_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x63, 0x44) | |
| enum audio_device { | |
| TAS2020, | |
| TAS2118, | |
| TAS2120, | |
| TAS2320, | |
| TAS2563, | |
| TAS2568, | |
| TAS2570, | |
| TAS2572, | |
| TAS2573, | |
| TAS2574, | |
| TAS2781, | |
| TAS5802, | |
| TAS5806M, | |
| TAS5806MD, | |
| TAS5815, | |
| TAS5822, | |
| TAS5825, | |
| TAS5827, | |
| TAS5828, | |
| TAS5830, | |
| TAS5832, | |
| TAS_OTHERS, | |
| }; | |
| enum dspbin_type { | |
| TASDEV_BASIC, | |
| TASDEV_ALPHA, | |
| TASDEV_BETA, | |
| }; | |
| struct bulk_reg_val { | |
| int reg; | |
| unsigned char val[4]; | |
| unsigned char val_len; | |
| bool is_locked; | |
| }; | |
| struct tasdevice { | |
| struct bulk_reg_val *cali_data_backup; | |
| struct bulk_reg_val alp_cali_bckp; | |
| struct tasdevice_fw *cali_data_fmw; | |
| void *cali_specific; | |
| unsigned int dev_addr; | |
| unsigned int err_code; | |
| unsigned char cur_book; | |
| short cur_prog; | |
| short cur_conf; | |
| bool is_loading; | |
| bool is_loaderr; | |
| }; | |
| struct cali_reg { | |
| unsigned int r0_reg; | |
| unsigned int r0_low_reg; | |
| unsigned int invr0_reg; | |
| unsigned int pow_reg; | |
| unsigned int tlimit_reg; | |
| }; | |
| struct calidata { | |
| unsigned char *data; | |
| unsigned long total_sz; | |
| struct cali_reg cali_reg_array; | |
| unsigned int cali_dat_sz_per_dev; | |
| }; | |
| /* | |
| * To enable CONFIG_SND_SOC_TAS2781_ACOUST_I2C will create a bridge to the | |
| * acoustic tuning tool which can tune the chips' acoustic effect. Due to the | |
| * whole directly exposing the registers, there exist some potential risks. So | |
| * this define is invisible in Kconfig, anyone who wants to use acoustic tool | |
| * have to edit the source manually. | |
| */ | |
| #ifdef CONFIG_SND_SOC_TAS2781_ACOUST_I2C | |
| #define TASDEV_DATA_PAYLOAD_SIZE 128 | |
| struct acoustic_data { | |
| unsigned char len; | |
| unsigned char id; | |
| unsigned char addr; | |
| unsigned char book; | |
| unsigned char page; | |
| unsigned char reg; | |
| unsigned char data[TASDEV_DATA_PAYLOAD_SIZE]; | |
| }; | |
| #endif | |
| struct tasdevice_priv { | |
| struct tasdevice tasdevice[TASDEVICE_MAX_CHANNELS]; | |
| struct tasdevice_rca rcabin; | |
| struct calidata cali_data; | |
| #ifdef CONFIG_SND_SOC_TAS2781_ACOUST_I2C | |
| struct acoustic_data acou_data; | |
| #endif | |
| struct tasdevice_fw *fmw; | |
| struct gpio_desc *reset; | |
| struct mutex codec_lock; | |
| struct regmap *regmap; | |
| struct device *dev; | |
| unsigned char cal_binaryname[TASDEVICE_MAX_CHANNELS][64]; | |
| unsigned char crc8_lkp_tbl[CRC8_TABLE_SIZE]; | |
| unsigned char coef_binaryname[64]; | |
| unsigned char rca_binaryname[64]; | |
| unsigned char dev_name[32]; | |
| const unsigned char (*dvc_tlv_table)[4]; | |
| const char *name_prefix; | |
| unsigned char ndev; | |
| unsigned int dspbin_typ; | |
| unsigned int magic_num; | |
| unsigned int chip_id; | |
| unsigned int sysclk; | |
| int speaker_id; | |
| int irq; | |
| int cur_prog; | |
| int cur_conf; | |
| int fw_state; | |
| int index; | |
| void *client; | |
| void *codec; | |
| bool force_fwload_status; | |
| bool playback_started; | |
| bool isacpi; | |
| bool isspi; | |
| unsigned int global_addr; | |
| 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 (*fw_parse_fct_param_address)(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 (*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 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); | |
| void tasdevice_remove(struct tasdevice_priv *tas_priv); | |
| #endif /* __TAS2781_H__ */ |