|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | +// |
| 3 | +// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier |
| 4 | +// |
| 5 | +// Copyright (C) 2024 Texas Instruments Incorporated |
| 6 | +// https://www.ti.com |
| 7 | +// |
| 8 | +// The TAS2781 driver implements a flexible and configurable |
| 9 | +// algo coefficient setting for TAS2781 chips. |
| 10 | +// |
| 11 | +// Author: Baojun Xu <[email protected]> |
| 12 | +// |
| 13 | + |
| 14 | +#ifndef __TAS2781_SPI_H__ |
| 15 | +#define __TAS2781_SPI_H__ |
| 16 | + |
| 17 | +#define TASDEVICE_RATES \ |
| 18 | + (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ |
| 19 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200) |
| 20 | + |
| 21 | +#define TASDEVICE_FORMATS \ |
| 22 | + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ |
| 23 | + SNDRV_PCM_FMTBIT_S32_LE) |
| 24 | + |
| 25 | +#define TASDEVICE_MAX_BOOK_NUM 256 |
| 26 | +#define TASDEVICE_MAX_PAGE 256 |
| 27 | + |
| 28 | +#define TASDEVICE_MAX_SIZE (TASDEVICE_MAX_BOOK_NUM * TASDEVICE_MAX_PAGE) |
| 29 | + |
| 30 | +/* PAGE Control Register (available in page0 of each book) */ |
| 31 | +#define TASDEVICE_PAGE_SELECT 0x00 |
| 32 | +#define TASDEVICE_BOOKCTL_PAGE 0x00 |
| 33 | +#define TASDEVICE_BOOKCTL_REG GENMASK(7, 1) |
| 34 | +#define TASDEVICE_BOOK_ID(reg) (((reg) & GENMASK(24, 16)) >> 16) |
| 35 | +#define TASDEVICE_PAGE_ID(reg) (((reg) & GENMASK(15, 8)) >> 8) |
| 36 | +#define TASDEVICE_REG_ID(reg) (((reg) & GENMASK(7, 1)) >> 1) |
| 37 | +#define TASDEVICE_PAGE_REG(reg) ((reg) & GENMASK(15, 1)) |
| 38 | +#define TASDEVICE_REG(book, page, reg) \ |
| 39 | + (((book) << 16) | ((page) << 8) | ((reg) << 1)) |
| 40 | + |
| 41 | +/* Software Reset */ |
| 42 | +#define TAS2781_REG_SWRESET TASDEVICE_REG(0x0, 0x0, 0x01) |
| 43 | +#define TAS2781_REG_SWRESET_RESET BIT(0) |
| 44 | + |
| 45 | +/* System Reset Check Register */ |
| 46 | +#define TAS2781_REG_CLK_CONFIG TASDEVICE_REG(0x0, 0x0, 0x5c) |
| 47 | +#define TAS2781_REG_CLK_CONFIG_RESET (0x19) |
| 48 | +#define TAS2781_PRE_POST_RESET_CFG 3 |
| 49 | + |
| 50 | +/* Block Checksum */ |
| 51 | +#define TASDEVICE_CHECKSUM TASDEVICE_REG(0x0, 0x0, 0x7e) |
| 52 | + |
| 53 | +/* Volume control */ |
| 54 | +#define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1a) |
| 55 | +#define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03) |
| 56 | +#define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1) |
| 57 | + |
| 58 | +#define TASDEVICE_CMD_SING_W 0x1 |
| 59 | +#define TASDEVICE_CMD_BURST 0x2 |
| 60 | +#define TASDEVICE_CMD_DELAY 0x3 |
| 61 | +#define TASDEVICE_CMD_FIELD_W 0x4 |
| 62 | + |
| 63 | +#define TAS2781_SPI_MAX_FREQ (4 * HZ_PER_MHZ) |
| 64 | + |
| 65 | +#define TASDEVICE_CRC8_POLYNOMIAL 0x4d |
| 66 | +#define TASDEVICE_SPEAKER_CALIBRATION_SIZE 20 |
| 67 | + |
| 68 | +/* Flag of calibration registers address. */ |
| 69 | +#define TASDEVICE_CALIBRATION_REG_ADDRESS BIT(7) |
| 70 | + |
| 71 | +#define TASDEVICE_CALIBRATION_DATA_NAME L"CALI_DATA" |
| 72 | +#define TASDEVICE_CALIBRATION_DATA_SIZE 256 |
| 73 | + |
| 74 | +enum calib_data { |
| 75 | + R0_VAL = 0, |
| 76 | + INV_R0, |
| 77 | + R0LOW, |
| 78 | + POWER, |
| 79 | + TLIM, |
| 80 | + CALIB_MAX |
| 81 | +}; |
| 82 | + |
| 83 | +struct tasdevice_priv { |
| 84 | + struct tasdevice_fw *cali_data_fmw; |
| 85 | + struct tasdevice_rca rcabin; |
| 86 | + struct tasdevice_fw *fmw; |
| 87 | + struct gpio_desc *reset; |
| 88 | + struct mutex codec_lock; |
| 89 | + struct regmap *regmap; |
| 90 | + struct device *dev; |
| 91 | + struct tm tm; |
| 92 | + |
| 93 | + unsigned char crc8_lkp_tbl[CRC8_TABLE_SIZE]; |
| 94 | + unsigned char coef_binaryname[64]; |
| 95 | + unsigned char rca_binaryname[64]; |
| 96 | + unsigned char dev_name[32]; |
| 97 | + |
| 98 | + bool force_fwload_status; |
| 99 | + bool playback_started; |
| 100 | + bool is_loading; |
| 101 | + bool is_loaderr; |
| 102 | + unsigned int cali_reg_array[CALIB_MAX]; |
| 103 | + unsigned int cali_data[CALIB_MAX]; |
| 104 | + unsigned int err_code; |
| 105 | + void *codec; |
| 106 | + int cur_book; |
| 107 | + int cur_prog; |
| 108 | + int cur_conf; |
| 109 | + int fw_state; |
| 110 | + int index; |
| 111 | + int irq; |
| 112 | + |
| 113 | + int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv, |
| 114 | + const struct firmware *fmw, |
| 115 | + int offset); |
| 116 | + int (*fw_parse_program_data)(struct tasdevice_priv *tas_priv, |
| 117 | + struct tasdevice_fw *tas_fmw, |
| 118 | + const struct firmware *fmw, int offset); |
| 119 | + int (*fw_parse_configuration_data)(struct tasdevice_priv *tas_priv, |
| 120 | + struct tasdevice_fw *tas_fmw, |
| 121 | + const struct firmware *fmw, |
| 122 | + int offset); |
| 123 | + int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv, |
| 124 | + struct tasdev_blk *block); |
| 125 | + |
| 126 | + int (*save_calibration)(struct tasdevice_priv *tas_priv); |
| 127 | + void (*apply_calibration)(struct tasdevice_priv *tas_priv); |
| 128 | +}; |
| 129 | + |
| 130 | +int tasdevice_spi_dev_read(struct tasdevice_priv *tas_priv, |
| 131 | + unsigned int reg, unsigned int *value); |
| 132 | +int tasdevice_spi_dev_write(struct tasdevice_priv *tas_priv, |
| 133 | + unsigned int reg, unsigned int value); |
| 134 | +int tasdevice_spi_dev_bulk_write(struct tasdevice_priv *tas_priv, |
| 135 | + unsigned int reg, unsigned char *p_data, |
| 136 | + unsigned int n_length); |
| 137 | +int tasdevice_spi_dev_bulk_read(struct tasdevice_priv *tas_priv, |
| 138 | + unsigned int reg, unsigned char *p_data, |
| 139 | + unsigned int n_length); |
| 140 | +int tasdevice_spi_dev_update_bits(struct tasdevice_priv *tasdevice, |
| 141 | + unsigned int reg, unsigned int mask, |
| 142 | + unsigned int value); |
| 143 | + |
| 144 | +void tasdevice_spi_select_cfg_blk(void *context, int conf_no, |
| 145 | + unsigned char block_type); |
| 146 | +void tasdevice_spi_config_info_remove(void *context); |
| 147 | +int tasdevice_spi_dsp_parser(void *context); |
| 148 | +int tasdevice_spi_rca_parser(void *context, const struct firmware *fmw); |
| 149 | +void tasdevice_spi_dsp_remove(void *context); |
| 150 | +void tasdevice_spi_calbin_remove(void *context); |
| 151 | +int tasdevice_spi_select_tuningprm_cfg(void *context, int prm, int cfg_no, |
| 152 | + int rca_conf_no); |
| 153 | +int tasdevice_spi_prmg_load(void *context, int prm_no); |
| 154 | +int tasdevice_spi_prmg_calibdata_load(void *context, int prm_no); |
| 155 | +void tasdevice_spi_tuning_switch(void *context, int state); |
| 156 | +int tas2781_spi_load_calibration(void *context, char *file_name, |
| 157 | + unsigned short i); |
| 158 | +#endif /* __TAS2781_SPI_H__ */ |
0 commit comments