2023-06-18 12:28:16 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
//
|
2024-01-04 14:57:18 +00:00
|
|
|
// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier
|
2023-06-18 12:28:16 +00:00
|
|
|
//
|
2024-07-09 04:33:40 +00:00
|
|
|
// Copyright (C) 2022 - 2024 Texas Instruments Incorporated
|
2023-06-18 12:28:16 +00:00
|
|
|
// https://www.ti.com
|
|
|
|
//
|
2024-01-04 14:57:18 +00:00
|
|
|
// The TAS2563/TAS2781 driver implements a flexible and configurable
|
2023-06-18 12:28:16 +00:00
|
|
|
// algo coefficient setting for one, two, or even multiple
|
2024-01-04 14:57:18 +00:00
|
|
|
// TAS2563/TAS2781 chips.
|
2023-06-18 12:28:16 +00:00
|
|
|
//
|
|
|
|
// Author: Shenghao Ding <shenghao-ding@ti.com>
|
|
|
|
// Author: Kevin Lu <kevin-lu@ti.com>
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef __TAS2781_H__
|
|
|
|
#define __TAS2781_H__
|
|
|
|
|
|
|
|
#include "tas2781-dsp.h"
|
|
|
|
|
|
|
|
/* version number */
|
|
|
|
#define TAS2781_DRV_VER 1
|
|
|
|
#define SMARTAMP_MODULE_NAME "tas2781"
|
|
|
|
#define TAS2781_GLOBAL_ADDR 0x40
|
ALSA: hda/tas2781: add TAS2563 support for 14ARB7
The INT8866 belongs to the Lenovo Yoga 7 Gen 7 AMD 14ARB7
laptop. It has two TAS2563 amplifier. Add the PNP ID
and calibration functions to handle them.
ACPI excerpt:
Scope (_SB.I2CD)
{
Device (TAS)
{
Name (_HID, "INT8866") // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x004C, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.I2CD",
0x00, ResourceConsumer, , Exclusive,
)
I2cSerialBusV2 (0x004D, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.I2CD",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, SharedAndWake, PullNone, 0x0000,
"\\_SB.GPIO", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0020
}
})
Return (RBUF) /* \_SB_.I2CD.TAS_._CRS.RBUF */
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0F)
}
}
}
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/3b8d4c602e1a46922f53bc9afc8b705d55aa4872.1703891777.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-30 00:09:44 +00:00
|
|
|
#define TAS2563_GLOBAL_ADDR 0x48
|
2023-06-18 12:28:16 +00:00
|
|
|
#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)
|
|
|
|
|
|
|
|
/*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 */
|
2024-07-09 04:33:40 +00:00
|
|
|
#define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0X0, 0x01)
|
|
|
|
#define TASDEVICE_REG_SWRESET_RESET BIT(0)
|
2023-06-18 12:28:16 +00:00
|
|
|
|
|
|
|
/*I2C Checksum */
|
|
|
|
#define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E)
|
|
|
|
|
2024-09-11 23:27:37 +00:00
|
|
|
/* XM_340 */
|
|
|
|
#define TASDEVICE_XM_A1_REG TASDEVICE_REG(0x64, 0x63, 0x3c)
|
|
|
|
/* XM_341 */
|
|
|
|
#define TASDEVICE_XM_A2_REG TASDEVICE_REG(0x64, 0x63, 0x38)
|
|
|
|
|
2023-06-18 12:28:16 +00:00
|
|
|
/* Volume control */
|
2024-07-10 06:42:37 +00:00
|
|
|
#define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0C)
|
2023-06-18 12:28:16 +00:00
|
|
|
#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)
|
|
|
|
|
2024-09-11 23:27:37 +00:00
|
|
|
#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)
|
|
|
|
|
2023-06-18 12:28:16 +00:00
|
|
|
#define TASDEVICE_CMD_SING_W 0x1
|
|
|
|
#define TASDEVICE_CMD_BURST 0x2
|
|
|
|
#define TASDEVICE_CMD_DELAY 0x3
|
|
|
|
#define TASDEVICE_CMD_FIELD_W 0x4
|
|
|
|
|
|
|
|
enum audio_device {
|
2024-01-04 14:57:18 +00:00
|
|
|
TAS2563,
|
|
|
|
TAS2781,
|
2023-06-18 12:28:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum device_catlog_id {
|
|
|
|
LENOVO = 0,
|
|
|
|
OTHERS
|
|
|
|
};
|
|
|
|
|
2024-09-11 23:27:37 +00:00
|
|
|
struct bulk_reg_val {
|
|
|
|
int reg;
|
|
|
|
unsigned char val[4];
|
|
|
|
unsigned char val_len;
|
|
|
|
bool is_locked;
|
|
|
|
};
|
|
|
|
|
2023-06-18 12:28:16 +00:00
|
|
|
struct tasdevice {
|
2024-09-11 23:27:37 +00:00
|
|
|
struct bulk_reg_val *cali_data_backup;
|
2023-06-18 12:28:16 +00:00
|
|
|
struct tasdevice_fw *cali_data_fmw;
|
|
|
|
unsigned int dev_addr;
|
|
|
|
unsigned int err_code;
|
|
|
|
unsigned char cur_book;
|
|
|
|
short cur_prog;
|
|
|
|
short cur_conf;
|
|
|
|
bool is_loading;
|
|
|
|
bool is_loaderr;
|
|
|
|
};
|
|
|
|
|
2024-09-11 23:27:37 +00:00
|
|
|
struct cali_reg {
|
|
|
|
unsigned int r0_reg;
|
|
|
|
unsigned int r0_low_reg;
|
|
|
|
unsigned int invr0_reg;
|
|
|
|
unsigned int pow_reg;
|
|
|
|
unsigned int tlimit_reg;
|
|
|
|
};
|
|
|
|
|
2023-06-18 12:28:16 +00:00
|
|
|
struct calidata {
|
|
|
|
unsigned char *data;
|
|
|
|
unsigned long total_sz;
|
2024-09-11 23:27:37 +00:00
|
|
|
struct cali_reg cali_reg_array;
|
|
|
|
unsigned int cali_dat_sz_per_dev;
|
2023-06-18 12:28:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct tasdevice_priv {
|
|
|
|
struct tasdevice tasdevice[TASDEVICE_MAX_CHANNELS];
|
|
|
|
struct tasdevice_rca rcabin;
|
|
|
|
struct calidata cali_data;
|
|
|
|
struct tasdevice_fw *fmw;
|
|
|
|
struct gpio_desc *reset;
|
|
|
|
struct mutex codec_lock;
|
|
|
|
struct regmap *regmap;
|
|
|
|
struct device *dev;
|
|
|
|
struct tm tm;
|
|
|
|
|
|
|
|
enum device_catlog_id catlog_id;
|
|
|
|
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];
|
2024-06-21 13:23:07 +00:00
|
|
|
const char *name_prefix;
|
2023-06-18 12:28:16 +00:00
|
|
|
unsigned char ndev;
|
|
|
|
unsigned int magic_num;
|
|
|
|
unsigned int chip_id;
|
|
|
|
unsigned int sysclk;
|
|
|
|
|
2024-08-07 15:02:32 +00:00
|
|
|
int irq;
|
2023-06-18 12:28:16 +00:00
|
|
|
int cur_prog;
|
|
|
|
int cur_conf;
|
|
|
|
int fw_state;
|
|
|
|
int index;
|
|
|
|
void *client;
|
|
|
|
void *codec;
|
|
|
|
bool force_fwload_status;
|
|
|
|
bool playback_started;
|
|
|
|
bool isacpi;
|
2024-09-11 23:27:37 +00:00
|
|
|
bool is_user_space_calidata;
|
2023-12-30 00:09:43 +00:00
|
|
|
unsigned int global_addr;
|
|
|
|
|
2023-06-18 12:28:16 +00:00
|
|
|
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);
|
2023-12-30 00:09:42 +00:00
|
|
|
|
|
|
|
int (*save_calibration)(struct tasdevice_priv *tas_priv);
|
|
|
|
void (*apply_calibration)(struct tasdevice_priv *tas_priv);
|
2023-06-18 12:28:16 +00:00
|
|
|
};
|
|
|
|
|
2024-07-09 04:33:40 +00:00
|
|
|
void tasdevice_reset(struct tasdevice_priv *tas_dev);
|
2023-06-18 12:28:16 +00:00
|
|
|
int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
|
2024-02-04 20:01:17 +00:00
|
|
|
struct module *module,
|
2023-06-18 12:28:16 +00:00
|
|
|
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);
|
2023-12-30 00:09:42 +00:00
|
|
|
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
|
|
|
|
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
|
2024-09-11 23:27:37 +00:00
|
|
|
int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
|
|
|
|
unsigned short chn);
|
2023-06-18 12:28:16 +00:00
|
|
|
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
|
|
|
|
unsigned short chn, unsigned int reg, unsigned int *value);
|
|
|
|
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);
|
|
|
|
|
|
|
|
#endif /* __TAS2781_H__ */
|