Skip to content

Commit 3912b94

Browse files
committed
Merge: ALSA: hda/tas2781: Add tas2781 hda SPI driver + 6.12.11 stable picks
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/271 This patch was used to add TAS2781 devices on SPI support in sound/pci/hda. Also, apply ALSA patches between 6.12.9 and 6.12.11 stable kernels (6.12.9 update is handled in MR !175) JIRA: https://issues.redhat.com/browse/RHEL-76330 ARK config change: https://gitlab.com/cki-project/kernel-ark/-/merge_requests/3660 Depends: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/175 Signed-off-by: Jaroslav Kysela <jkysela@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: Desnes Nunes <desnesn@redhat.com> Approved-by: David Arcari <darcari@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Jan Stancek <jstancek@redhat.com>
2 parents cdc7ae3 + 9a5495a commit 3912b94

File tree

12 files changed

+3503
-7
lines changed

12 files changed

+3503
-7
lines changed

drivers/acpi/scan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,6 +1769,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
17691769
{"CSC3557", },
17701770
{"INT33FE", },
17711771
{"INT3515", },
1772+
{"TXNW2781", },
17721773
/* Non-conforming _HID for Cirrus Logic already released */
17731774
{"CLSA0100", },
17741775
{"CLSA0101", },

drivers/platform/x86/serial-multi-instantiate.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,17 @@ static const struct smi_node cs35l57_hda = {
384384
.bus_type = SMI_AUTO_DETECT,
385385
};
386386

387+
static const struct smi_node tas2781_hda = {
388+
.instances = {
389+
{ "tas2781-hda", IRQ_RESOURCE_AUTO, 0 },
390+
{ "tas2781-hda", IRQ_RESOURCE_AUTO, 0 },
391+
{ "tas2781-hda", IRQ_RESOURCE_AUTO, 0 },
392+
{ "tas2781-hda", IRQ_RESOURCE_AUTO, 0 },
393+
{}
394+
},
395+
.bus_type = SMI_AUTO_DETECT,
396+
};
397+
387398
/*
388399
* Note new device-ids must also be added to ignore_serial_bus_ids in
389400
* drivers/acpi/scan.c: acpi_device_enumeration_by_parent().
@@ -396,6 +407,7 @@ static const struct acpi_device_id smi_acpi_ids[] = {
396407
{ "CSC3556", (unsigned long)&cs35l56_hda },
397408
{ "CSC3557", (unsigned long)&cs35l57_hda },
398409
{ "INT3515", (unsigned long)&int3515_data },
410+
{ "TXNW2781", (unsigned long)&tas2781_hda },
399411
/* Non-conforming _HID for Cirrus Logic already released */
400412
{ "CLSA0100", (unsigned long)&cs35l41_hda },
401413
{ "CLSA0101", (unsigned long)&cs35l41_hda },
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_SND_HDA_SCODEC_TAS2781_SPI=m

sound/pci/hda/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,20 @@ config SND_HDA_SCODEC_TAS2781_I2C
206206
comment "Set to Y if you want auto-loading the side codec driver"
207207
depends on SND_HDA=y && SND_HDA_SCODEC_TAS2781_I2C=m
208208

209+
config SND_HDA_SCODEC_TAS2781_SPI
210+
tristate "Build TAS2781 HD-audio side codec support for SPI Bus"
211+
depends on SPI_MASTER
212+
depends on ACPI
213+
depends on EFI
214+
depends on SND_SOC
215+
select CRC32
216+
help
217+
Say Y or M here to include TAS2781 SPI HD-audio side codec support
218+
in snd-hda-intel driver, such as ALC287.
219+
220+
comment "Set to Y if you want auto-loading the side codec driver"
221+
depends on SND_HDA=y && SND_HDA_SCODEC_TAS2781_SPI=m
222+
209223
config SND_HDA_CODEC_REALTEK
210224
tristate "Build Realtek HD-audio codec support"
211225
select SND_HDA_GENERIC

sound/pci/hda/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ snd-hda-scodec-cs35l56-spi-y := cs35l56_hda_spi.o
4040
snd-hda-cs-dsp-ctls-y := hda_cs_dsp_ctl.o
4141
snd-hda-scodec-component-y := hda_component.o
4242
snd-hda-scodec-tas2781-i2c-y := tas2781_hda_i2c.o
43+
snd-hda-scodec-tas2781-spi-y := tas2781_hda_spi.o tas2781_spi_fwlib.o
4344

4445
# common driver
4546
obj-$(CONFIG_SND_HDA) := snd-hda-codec.o
@@ -72,6 +73,7 @@ obj-$(CONFIG_SND_HDA_SCODEC_CS35L56_SPI) += snd-hda-scodec-cs35l56-spi.o
7273
obj-$(CONFIG_SND_HDA_CS_DSP_CONTROLS) += snd-hda-cs-dsp-ctls.o
7374
obj-$(CONFIG_SND_HDA_SCODEC_COMPONENT) += snd-hda-scodec-component.o
7475
obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_I2C) += snd-hda-scodec-tas2781-i2c.o
76+
obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_SPI) += snd-hda-scodec-tas2781-spi.o
7577

7678
# this must be the last entry after codec drivers;
7779
# otherwise the codec patches won't be hooked before the PCI probe

sound/pci/hda/patch_realtek.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7118,6 +7118,11 @@ static void tas2781_fixup_i2c(struct hda_codec *cdc,
71187118
comp_generic_fixup(cdc, action, "i2c", "TIAS2781", "-%s:00", 1);
71197119
}
71207120

7121+
static void tas2781_fixup_spi(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
7122+
{
7123+
comp_generic_fixup(cdc, action, "spi", "TXNW2781", "-%s:00-tas2781-hda.%d", 2);
7124+
}
7125+
71217126
static void yoga7_14arb7_fixup_i2c(struct hda_codec *cdc,
71227127
const struct hda_fixup *fix, int action)
71237128
{
@@ -7752,6 +7757,7 @@ enum {
77527757
ALC236_FIXUP_DELL_DUAL_CODECS,
77537758
ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
77547759
ALC287_FIXUP_TAS2781_I2C,
7760+
ALC245_FIXUP_TAS2781_SPI_2,
77557761
ALC287_FIXUP_YOGA7_14ARB7_I2C,
77567762
ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
77577763
ALC245_FIXUP_HP_X360_MUTE_LEDS,
@@ -9975,6 +9981,12 @@ static const struct hda_fixup alc269_fixups[] = {
99759981
.chained = true,
99769982
.chain_id = ALC285_FIXUP_THINKPAD_HEADSET_JACK,
99779983
},
9984+
[ALC245_FIXUP_TAS2781_SPI_2] = {
9985+
.type = HDA_FIXUP_FUNC,
9986+
.v.func = tas2781_fixup_spi,
9987+
.chained = true,
9988+
.chain_id = ALC285_FIXUP_HP_GPIO_LED,
9989+
},
99789990
[ALC287_FIXUP_YOGA7_14ARB7_I2C] = {
99799991
.type = HDA_FIXUP_FUNC,
99809992
.v.func = yoga7_14arb7_fixup_i2c,
@@ -10533,6 +10545,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
1053310545
SND_PCI_QUIRK(0x103c, 0x8d84, "HP EliteBook X G1i", ALC285_FIXUP_HP_GPIO_LED),
1053410546
SND_PCI_QUIRK(0x103c, 0x8d91, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED),
1053510547
SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED),
10548+
SND_PCI_QUIRK(0x103c, 0x8de8, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2),
10549+
SND_PCI_QUIRK(0x103c, 0x8de9, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2),
1053610550
SND_PCI_QUIRK(0x103c, 0x8e18, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED),
1053710551
SND_PCI_QUIRK(0x103c, 0x8e19, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED),
1053810552
SND_PCI_QUIRK(0x103c, 0x8e1a, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED),
@@ -10625,6 +10639,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
1062510639
SND_PCI_QUIRK(0x1043, 0x1e1f, "ASUS Vivobook 15 X1504VAP", ALC2XX_FIXUP_HEADSET_MIC),
1062610640
SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
1062710641
SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
10642+
SND_PCI_QUIRK(0x1043, 0x1e63, "ASUS H7606W", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
10643+
SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
1062810644
SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
1062910645
SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C),
1063010646
SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
@@ -10979,6 +10995,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
1097910995
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
1098010996
SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC),
1098110997
SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
10998+
SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2),
1098210999
SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
1098311000
SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
1098411001
SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),

sound/pci/hda/tas2781-spi.h

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
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 <baojun.xu@ti.com>
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

Comments
 (0)