Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | // |
Shenghao Ding | e9aa447 | 2024-01-04 22:57:18 +0800 | [diff] [blame] | 3 | // ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 4 | // |
| 5 | // Copyright (C) 2022 - 2023 Texas Instruments Incorporated |
| 6 | // https://www.ti.com |
| 7 | // |
Shenghao Ding | e9aa447 | 2024-01-04 22:57:18 +0800 | [diff] [blame] | 8 | // The TAS2563/TAS2781 driver implements a flexible and configurable |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 9 | // algo coefficient setting for one, two, or even multiple |
Shenghao Ding | e9aa447 | 2024-01-04 22:57:18 +0800 | [diff] [blame] | 10 | // TAS2563/TAS2781 chips. |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 11 | // |
| 12 | // Author: Shenghao Ding <shenghao-ding@ti.com> |
| 13 | // Author: Kevin Lu <kevin-lu@ti.com> |
| 14 | // |
| 15 | |
| 16 | #ifndef __TAS2781_H__ |
| 17 | #define __TAS2781_H__ |
| 18 | |
| 19 | #include "tas2781-dsp.h" |
| 20 | |
| 21 | /* version number */ |
| 22 | #define TAS2781_DRV_VER 1 |
| 23 | #define SMARTAMP_MODULE_NAME "tas2781" |
| 24 | #define TAS2781_GLOBAL_ADDR 0x40 |
Gergo Koteles | c3ca445 | 2023-12-30 01:09:44 +0100 | [diff] [blame] | 25 | #define TAS2563_GLOBAL_ADDR 0x48 |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 26 | #define TASDEVICE_RATES (SNDRV_PCM_RATE_44100 |\ |
| 27 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\ |
| 28 | SNDRV_PCM_RATE_88200) |
| 29 | |
| 30 | #define TASDEVICE_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
| 31 | SNDRV_PCM_FMTBIT_S24_LE | \ |
| 32 | SNDRV_PCM_FMTBIT_S32_LE) |
| 33 | |
| 34 | /*PAGE Control Register (available in page0 of each book) */ |
| 35 | #define TASDEVICE_PAGE_SELECT 0x00 |
| 36 | #define TASDEVICE_BOOKCTL_PAGE 0x00 |
| 37 | #define TASDEVICE_BOOKCTL_REG 127 |
| 38 | #define TASDEVICE_BOOK_ID(reg) (reg / (256 * 128)) |
| 39 | #define TASDEVICE_PAGE_ID(reg) ((reg % (256 * 128)) / 128) |
| 40 | #define TASDEVICE_PAGE_REG(reg) ((reg % (256 * 128)) % 128) |
| 41 | #define TASDEVICE_PGRG(reg) (reg % (256 * 128)) |
| 42 | #define TASDEVICE_REG(book, page, reg) (((book * 256 * 128) + \ |
| 43 | (page * 128)) + reg) |
| 44 | |
| 45 | /*Software Reset */ |
| 46 | #define TAS2781_REG_SWRESET TASDEVICE_REG(0x0, 0X0, 0x01) |
| 47 | #define TAS2781_REG_SWRESET_RESET BIT(0) |
| 48 | |
| 49 | /*I2C Checksum */ |
| 50 | #define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E) |
| 51 | |
| 52 | /* Volume control */ |
| 53 | #define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A) |
| 54 | #define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03) |
| 55 | #define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1) |
| 56 | |
| 57 | #define TASDEVICE_CMD_SING_W 0x1 |
| 58 | #define TASDEVICE_CMD_BURST 0x2 |
| 59 | #define TASDEVICE_CMD_DELAY 0x3 |
| 60 | #define TASDEVICE_CMD_FIELD_W 0x4 |
| 61 | |
| 62 | enum audio_device { |
Shenghao Ding | e9aa447 | 2024-01-04 22:57:18 +0800 | [diff] [blame] | 63 | TAS2563, |
| 64 | TAS2781, |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 65 | }; |
| 66 | |
| 67 | enum device_catlog_id { |
| 68 | LENOVO = 0, |
| 69 | OTHERS |
| 70 | }; |
| 71 | |
| 72 | struct tasdevice { |
| 73 | struct tasdevice_fw *cali_data_fmw; |
| 74 | unsigned int dev_addr; |
| 75 | unsigned int err_code; |
| 76 | unsigned char cur_book; |
| 77 | short cur_prog; |
| 78 | short cur_conf; |
| 79 | bool is_loading; |
| 80 | bool is_loaderr; |
| 81 | }; |
| 82 | |
| 83 | struct tasdevice_irqinfo { |
| 84 | int irq_gpio; |
| 85 | int irq; |
| 86 | }; |
| 87 | |
| 88 | struct calidata { |
| 89 | unsigned char *data; |
| 90 | unsigned long total_sz; |
| 91 | }; |
| 92 | |
| 93 | struct tasdevice_priv { |
| 94 | struct tasdevice tasdevice[TASDEVICE_MAX_CHANNELS]; |
| 95 | struct tasdevice_irqinfo irq_info; |
| 96 | struct tasdevice_rca rcabin; |
| 97 | struct calidata cali_data; |
| 98 | struct tasdevice_fw *fmw; |
| 99 | struct gpio_desc *reset; |
| 100 | struct mutex codec_lock; |
| 101 | struct regmap *regmap; |
| 102 | struct device *dev; |
| 103 | struct tm tm; |
| 104 | |
| 105 | enum device_catlog_id catlog_id; |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 106 | unsigned char cal_binaryname[TASDEVICE_MAX_CHANNELS][64]; |
| 107 | unsigned char crc8_lkp_tbl[CRC8_TABLE_SIZE]; |
| 108 | unsigned char coef_binaryname[64]; |
| 109 | unsigned char rca_binaryname[64]; |
| 110 | unsigned char dev_name[32]; |
| 111 | unsigned char ndev; |
| 112 | unsigned int magic_num; |
| 113 | unsigned int chip_id; |
| 114 | unsigned int sysclk; |
| 115 | |
| 116 | int cur_prog; |
| 117 | int cur_conf; |
| 118 | int fw_state; |
| 119 | int index; |
| 120 | void *client; |
| 121 | void *codec; |
| 122 | bool force_fwload_status; |
| 123 | bool playback_started; |
| 124 | bool isacpi; |
Gergo Koteles | c021ca729 | 2023-12-30 01:09:43 +0100 | [diff] [blame] | 125 | unsigned int global_addr; |
| 126 | |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 127 | int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv, |
| 128 | const struct firmware *fmw, int offset); |
| 129 | int (*fw_parse_program_data)(struct tasdevice_priv *tas_priv, |
| 130 | struct tasdevice_fw *tas_fmw, |
| 131 | const struct firmware *fmw, int offset); |
| 132 | int (*fw_parse_configuration_data)(struct tasdevice_priv *tas_priv, |
| 133 | struct tasdevice_fw *tas_fmw, |
| 134 | const struct firmware *fmw, int offset); |
| 135 | int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv, |
| 136 | struct tasdev_blk *block); |
Gergo Koteles | 76f5f55 | 2023-12-30 01:09:42 +0100 | [diff] [blame] | 137 | |
| 138 | int (*save_calibration)(struct tasdevice_priv *tas_priv); |
| 139 | void (*apply_calibration)(struct tasdevice_priv *tas_priv); |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 140 | }; |
| 141 | |
| 142 | void tas2781_reset(struct tasdevice_priv *tas_dev); |
| 143 | int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, |
Gergo Koteles | 34a1066 | 2024-02-04 21:01:17 +0100 | [diff] [blame] | 144 | struct module *module, |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 145 | void (*cont)(const struct firmware *fw, void *context)); |
| 146 | struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c); |
| 147 | int tasdevice_init(struct tasdevice_priv *tas_priv); |
| 148 | void tasdevice_remove(struct tasdevice_priv *tas_priv); |
Gergo Koteles | 76f5f55 | 2023-12-30 01:09:42 +0100 | [diff] [blame] | 149 | int tasdevice_save_calibration(struct tasdevice_priv *tas_priv); |
| 150 | void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv); |
Shenghao Ding | 678f38e | 2023-06-18 20:28:16 +0800 | [diff] [blame] | 151 | int tasdevice_dev_read(struct tasdevice_priv *tas_priv, |
| 152 | unsigned short chn, unsigned int reg, unsigned int *value); |
| 153 | int tasdevice_dev_write(struct tasdevice_priv *tas_priv, |
| 154 | unsigned short chn, unsigned int reg, unsigned int value); |
| 155 | int tasdevice_dev_bulk_write( |
| 156 | struct tasdevice_priv *tas_priv, unsigned short chn, |
| 157 | unsigned int reg, unsigned char *p_data, unsigned int n_length); |
| 158 | int tasdevice_dev_bulk_read(struct tasdevice_priv *tas_priv, |
| 159 | unsigned short chn, unsigned int reg, unsigned char *p_data, |
| 160 | unsigned int n_length); |
| 161 | int tasdevice_dev_update_bits( |
| 162 | struct tasdevice_priv *tasdevice, unsigned short chn, |
| 163 | unsigned int reg, unsigned int mask, unsigned int value); |
| 164 | int tasdevice_amp_putvol(struct tasdevice_priv *tas_priv, |
| 165 | struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); |
| 166 | int tasdevice_amp_getvol(struct tasdevice_priv *tas_priv, |
| 167 | struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); |
| 168 | int tasdevice_digital_putvol(struct tasdevice_priv *tas_priv, |
| 169 | struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); |
| 170 | int tasdevice_digital_getvol(struct tasdevice_priv *tas_priv, |
| 171 | struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); |
| 172 | |
| 173 | #endif /* __TAS2781_H__ */ |