2023-06-18 20:28:16 +08:00
/* SPDX-License-Identifier: GPL-2.0 */
//
2024-01-04 22:57:18 +08:00
// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier
2023-06-18 20:28:16 +08:00
//
2024-07-09 12:33:40 +08:00
// Copyright (C) 2022 - 2024 Texas Instruments Incorporated
2023-06-18 20:28:16 +08:00
// https://www.ti.com
//
2024-01-04 22:57:18 +08:00
// The TAS2563/TAS2781 driver implements a flexible and configurable
2023-06-18 20:28:16 +08:00
// algo coefficient setting for one, two, or even multiple
2024-01-04 22:57:18 +08:00
// TAS2563/TAS2781 chips.
2023-06-18 20:28:16 +08: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 01:09:44 +01:00
# define TAS2563_GLOBAL_ADDR 0x48
2023-06-18 20:28:16 +08: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 12:33:40 +08:00
# define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0X0, 0x01)
# define TASDEVICE_REG_SWRESET_RESET BIT(0)
2023-06-18 20:28:16 +08:00
/*I2C Checksum */
# define TASDEVICE_I2CChecksum 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
enum audio_device {
2024-01-04 22:57:18 +08:00
TAS2563 ,
TAS2781 ,
2023-06-18 20:28:16 +08:00
} ;
enum device_catlog_id {
LENOVO = 0 ,
OTHERS
} ;
struct tasdevice {
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 ;
} ;
struct tasdevice_irqinfo {
int irq_gpio ;
int irq ;
} ;
struct calidata {
unsigned char * data ;
unsigned long total_sz ;
} ;
struct tasdevice_priv {
struct tasdevice tasdevice [ TASDEVICE_MAX_CHANNELS ] ;
struct tasdevice_irqinfo irq_info ;
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 21:23:07 +08:00
const char * name_prefix ;
2023-06-18 20:28:16 +08:00
unsigned char ndev ;
unsigned int magic_num ;
unsigned int chip_id ;
unsigned int sysclk ;
int cur_prog ;
int cur_conf ;
int fw_state ;
int index ;
void * client ;
void * codec ;
bool force_fwload_status ;
bool playback_started ;
bool isacpi ;
2023-12-30 01:09:43 +01:00
unsigned int global_addr ;
2023-06-18 20:28:16 +08: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 01:09:42 +01:00
int ( * save_calibration ) ( struct tasdevice_priv * tas_priv ) ;
void ( * apply_calibration ) ( struct tasdevice_priv * tas_priv ) ;
2023-06-18 20:28:16 +08:00
} ;
2024-07-09 12:33:40 +08:00
void tasdevice_reset ( struct tasdevice_priv * tas_dev ) ;
2023-06-18 20:28:16 +08:00
int tascodec_init ( struct tasdevice_priv * tas_priv , void * codec ,
2024-02-04 21:01:17 +01:00
struct module * module ,
2023-06-18 20:28:16 +08: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 01:09:42 +01:00
int tasdevice_save_calibration ( struct tasdevice_priv * tas_priv ) ;
void tasdevice_apply_calibration ( struct tasdevice_priv * tas_priv ) ;
2023-06-18 20:28:16 +08: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__ */