summaryrefslogtreecommitdiff
path: root/sound/pci/hda/tas2781-spi.h
blob: ecfc3c8bb821474c8f20d7dab01b009f8c66ae62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* 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;
	struct tm tm;

	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__ */