162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (C) 2022 - 2023 Texas Instruments Incorporated
662306a36Sopenharmony_ci// https://www.ti.com
762306a36Sopenharmony_ci//
862306a36Sopenharmony_ci// The TAS2781 driver implements a flexible and configurable
962306a36Sopenharmony_ci// algo coefficient setting for one, two, or even multiple
1062306a36Sopenharmony_ci// TAS2781 chips.
1162306a36Sopenharmony_ci//
1262306a36Sopenharmony_ci// Author: Shenghao Ding <shenghao-ding@ti.com>
1362306a36Sopenharmony_ci// Author: Kevin Lu <kevin-lu@ti.com>
1462306a36Sopenharmony_ci//
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#ifndef __TAS2781_H__
1762306a36Sopenharmony_ci#define __TAS2781_H__
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "tas2781-dsp.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* version number */
2262306a36Sopenharmony_ci#define TAS2781_DRV_VER			1
2362306a36Sopenharmony_ci#define SMARTAMP_MODULE_NAME		"tas2781"
2462306a36Sopenharmony_ci#define TAS2781_GLOBAL_ADDR	0x40
2562306a36Sopenharmony_ci#define TASDEVICE_RATES			(SNDRV_PCM_RATE_44100 |\
2662306a36Sopenharmony_ci	SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
2762306a36Sopenharmony_ci	SNDRV_PCM_RATE_88200)
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define TASDEVICE_FORMATS		(SNDRV_PCM_FMTBIT_S16_LE | \
3062306a36Sopenharmony_ci	SNDRV_PCM_FMTBIT_S24_LE | \
3162306a36Sopenharmony_ci	SNDRV_PCM_FMTBIT_S32_LE)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/*PAGE Control Register (available in page0 of each book) */
3462306a36Sopenharmony_ci#define TASDEVICE_PAGE_SELECT		0x00
3562306a36Sopenharmony_ci#define TASDEVICE_BOOKCTL_PAGE		0x00
3662306a36Sopenharmony_ci#define TASDEVICE_BOOKCTL_REG		127
3762306a36Sopenharmony_ci#define TASDEVICE_BOOK_ID(reg)		(reg / (256 * 128))
3862306a36Sopenharmony_ci#define TASDEVICE_PAGE_ID(reg)		((reg % (256 * 128)) / 128)
3962306a36Sopenharmony_ci#define TASDEVICE_PAGE_REG(reg)		((reg % (256 * 128)) % 128)
4062306a36Sopenharmony_ci#define TASDEVICE_PGRG(reg)		(reg % (256 * 128))
4162306a36Sopenharmony_ci#define TASDEVICE_REG(book, page, reg)	(((book * 256 * 128) + \
4262306a36Sopenharmony_ci					(page * 128)) + reg)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/*Software Reset */
4562306a36Sopenharmony_ci#define TAS2781_REG_SWRESET		TASDEVICE_REG(0x0, 0X0, 0x01)
4662306a36Sopenharmony_ci#define TAS2781_REG_SWRESET_RESET	BIT(0)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/*I2C Checksum */
4962306a36Sopenharmony_ci#define TASDEVICE_I2CChecksum		TASDEVICE_REG(0x0, 0x0, 0x7E)
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* Volume control */
5262306a36Sopenharmony_ci#define TAS2781_DVC_LVL			TASDEVICE_REG(0x0, 0x0, 0x1A)
5362306a36Sopenharmony_ci#define TAS2781_AMP_LEVEL		TASDEVICE_REG(0x0, 0x0, 0x03)
5462306a36Sopenharmony_ci#define TAS2781_AMP_LEVEL_MASK		GENMASK(5, 1)
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define TASDEVICE_CMD_SING_W		0x1
5762306a36Sopenharmony_ci#define TASDEVICE_CMD_BURST		0x2
5862306a36Sopenharmony_ci#define TASDEVICE_CMD_DELAY		0x3
5962306a36Sopenharmony_ci#define TASDEVICE_CMD_FIELD_W		0x4
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cienum audio_device {
6262306a36Sopenharmony_ci	TAS2781	= 0,
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cienum device_catlog_id {
6662306a36Sopenharmony_ci	LENOVO = 0,
6762306a36Sopenharmony_ci	OTHERS
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistruct tasdevice {
7162306a36Sopenharmony_ci	struct tasdevice_fw *cali_data_fmw;
7262306a36Sopenharmony_ci	unsigned int dev_addr;
7362306a36Sopenharmony_ci	unsigned int err_code;
7462306a36Sopenharmony_ci	unsigned char cur_book;
7562306a36Sopenharmony_ci	short cur_prog;
7662306a36Sopenharmony_ci	short cur_conf;
7762306a36Sopenharmony_ci	bool is_loading;
7862306a36Sopenharmony_ci	bool is_loaderr;
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistruct tasdevice_irqinfo {
8262306a36Sopenharmony_ci	int irq_gpio;
8362306a36Sopenharmony_ci	int irq;
8462306a36Sopenharmony_ci};
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistruct calidata {
8762306a36Sopenharmony_ci	unsigned char *data;
8862306a36Sopenharmony_ci	unsigned long total_sz;
8962306a36Sopenharmony_ci};
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cistruct tasdevice_priv {
9262306a36Sopenharmony_ci	struct tasdevice tasdevice[TASDEVICE_MAX_CHANNELS];
9362306a36Sopenharmony_ci	struct tasdevice_irqinfo irq_info;
9462306a36Sopenharmony_ci	struct tasdevice_rca rcabin;
9562306a36Sopenharmony_ci	struct calidata cali_data;
9662306a36Sopenharmony_ci	struct tasdevice_fw *fmw;
9762306a36Sopenharmony_ci	struct gpio_desc *reset;
9862306a36Sopenharmony_ci	struct mutex codec_lock;
9962306a36Sopenharmony_ci	struct regmap *regmap;
10062306a36Sopenharmony_ci	struct device *dev;
10162306a36Sopenharmony_ci	struct tm tm;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	enum device_catlog_id catlog_id;
10462306a36Sopenharmony_ci	const char *acpi_subsystem_id;
10562306a36Sopenharmony_ci	unsigned char cal_binaryname[TASDEVICE_MAX_CHANNELS][64];
10662306a36Sopenharmony_ci	unsigned char crc8_lkp_tbl[CRC8_TABLE_SIZE];
10762306a36Sopenharmony_ci	unsigned char coef_binaryname[64];
10862306a36Sopenharmony_ci	unsigned char rca_binaryname[64];
10962306a36Sopenharmony_ci	unsigned char dev_name[32];
11062306a36Sopenharmony_ci	unsigned char ndev;
11162306a36Sopenharmony_ci	unsigned int magic_num;
11262306a36Sopenharmony_ci	unsigned int chip_id;
11362306a36Sopenharmony_ci	unsigned int sysclk;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	int cur_prog;
11662306a36Sopenharmony_ci	int cur_conf;
11762306a36Sopenharmony_ci	int fw_state;
11862306a36Sopenharmony_ci	int index;
11962306a36Sopenharmony_ci	void *client;
12062306a36Sopenharmony_ci	void *codec;
12162306a36Sopenharmony_ci	bool force_fwload_status;
12262306a36Sopenharmony_ci	bool playback_started;
12362306a36Sopenharmony_ci	bool isacpi;
12462306a36Sopenharmony_ci	int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv,
12562306a36Sopenharmony_ci		const struct firmware *fmw, int offset);
12662306a36Sopenharmony_ci	int (*fw_parse_program_data)(struct tasdevice_priv *tas_priv,
12762306a36Sopenharmony_ci		struct tasdevice_fw *tas_fmw,
12862306a36Sopenharmony_ci		const struct firmware *fmw, int offset);
12962306a36Sopenharmony_ci	int (*fw_parse_configuration_data)(struct tasdevice_priv *tas_priv,
13062306a36Sopenharmony_ci		struct tasdevice_fw *tas_fmw,
13162306a36Sopenharmony_ci		const struct firmware *fmw, int offset);
13262306a36Sopenharmony_ci	int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv,
13362306a36Sopenharmony_ci		struct tasdev_blk *block);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	int (*save_calibration)(struct tasdevice_priv *tas_priv);
13662306a36Sopenharmony_ci	void (*apply_calibration)(struct tasdevice_priv *tas_priv);
13762306a36Sopenharmony_ci};
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_civoid tas2781_reset(struct tasdevice_priv *tas_dev);
14062306a36Sopenharmony_ciint tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
14162306a36Sopenharmony_ci	struct module *module,
14262306a36Sopenharmony_ci	void (*cont)(const struct firmware *fw, void *context));
14362306a36Sopenharmony_cistruct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c);
14462306a36Sopenharmony_ciint tasdevice_init(struct tasdevice_priv *tas_priv);
14562306a36Sopenharmony_civoid tasdevice_remove(struct tasdevice_priv *tas_priv);
14662306a36Sopenharmony_ciint tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
14762306a36Sopenharmony_civoid tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
14862306a36Sopenharmony_ciint tasdevice_dev_read(struct tasdevice_priv *tas_priv,
14962306a36Sopenharmony_ci	unsigned short chn, unsigned int reg, unsigned int *value);
15062306a36Sopenharmony_ciint tasdevice_dev_write(struct tasdevice_priv *tas_priv,
15162306a36Sopenharmony_ci	unsigned short chn, unsigned int reg, unsigned int value);
15262306a36Sopenharmony_ciint tasdevice_dev_bulk_write(
15362306a36Sopenharmony_ci	struct tasdevice_priv *tas_priv, unsigned short chn,
15462306a36Sopenharmony_ci	unsigned int reg, unsigned char *p_data, unsigned int n_length);
15562306a36Sopenharmony_ciint tasdevice_dev_bulk_read(struct tasdevice_priv *tas_priv,
15662306a36Sopenharmony_ci	unsigned short chn, unsigned int reg, unsigned char *p_data,
15762306a36Sopenharmony_ci	unsigned int n_length);
15862306a36Sopenharmony_ciint tasdevice_dev_update_bits(
15962306a36Sopenharmony_ci	struct tasdevice_priv *tasdevice, unsigned short chn,
16062306a36Sopenharmony_ci	unsigned int reg, unsigned int mask, unsigned int value);
16162306a36Sopenharmony_ciint tasdevice_amp_putvol(struct tasdevice_priv *tas_priv,
16262306a36Sopenharmony_ci	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
16362306a36Sopenharmony_ciint tasdevice_amp_getvol(struct tasdevice_priv *tas_priv,
16462306a36Sopenharmony_ci	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
16562306a36Sopenharmony_ciint tasdevice_digital_putvol(struct tasdevice_priv *tas_priv,
16662306a36Sopenharmony_ci	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
16762306a36Sopenharmony_ciint tasdevice_digital_getvol(struct tasdevice_priv *tas_priv,
16862306a36Sopenharmony_ci	struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci#endif /* __TAS2781_H__ */
171