The tas2781-hda driver can be modified to support tas2563 as well.
Before knowing this information, I created another series for a
new driver.
https://lore.kernel.org/lkml/[email protected]/
This series now extends tas2781-hda, addresses differences and
fixes various bugs.
The tas2563 is a smart amplifier. Similar to tas2562 but with DSP. Some
Lenovo laptops have it to drive the bass speakers. By default, it is in
software shutdown state.
To make the DSP work it needs a firmware and some calibration data.
The latter can be read from the EFI in Lenovo laptops.
For the correct configuration it needs additional register data.
It captured after running the Windows driver.
The firmware can be extracted as TAS2563Firmware.bin from the Windows
driver with innoextract.
https://download.lenovo.com/consumer/mobiles/h5yd037fbfyy7kd0.exe
The driver will search for it as TAS2XXX3870.bin with the 14ARB7.
The captured registers extracted with TI's regtool:
https://github.com/soyersoyer/tas2563rca/raw/main/INT8866RCA2.bin
Gergo Koteles (16):
ASoC: tas2781: add support for fw version 0x0503
ALSA: hda/tas2781: leave hda_component in usable state
ASoC: tas2781: disable regmap regcache
ALSA: hda/tas2781: handle missing calibration data
ALSA: hda/tas2781: fix typos in comment
ASoC: tas2781: add ptrs to calibration functions
ALSA: hda/tas2781: load_calibration just load
ASoC: tas2781: add configurable global_addr
ALSA: hda/tas2781: add TAS2563 support for 14ARB7
ASoC: tas2781: check negative indexes
ASoC: tas2781: use 0 as default prog/conf index
ASoC: tas2781: move set_drv_data outside tasdevice_init
ALSA: hda/tas2781: remove sound controls in unbind
ALSA: hda/tas2781: call cleaner functions only once
ALSA: hda/tas2781: reset the amp before component_add
ALSA: hda/tas2781: configure the amp after firmware load
include/sound/tas2781.h | 8 +
sound/pci/hda/tas2781_hda_i2c.c | 364 +++++++++++++++++++-----------
sound/soc/codecs/tas2781-comlib.c | 23 +-
sound/soc/codecs/tas2781-fmwlib.c | 11 +-
sound/soc/codecs/tas2781-i2c.c | 2 +
5 files changed, 270 insertions(+), 138 deletions(-)
base-commit: ffc253263a1375a65fa6c9f62a893e9767fbebfa
--
2.43.0
On Thu, Dec 07, 2023 at 01:58:22AM +0100, Gergo Koteles wrote:
> Gergo Koteles (16):
> ASoC: tas2781: add support for fw version 0x0503
> ALSA: hda/tas2781: leave hda_component in usable state
> ASoC: tas2781: disable regmap regcache
> ALSA: hda/tas2781: handle missing calibration data
> ALSA: hda/tas2781: fix typos in comment
> ASoC: tas2781: add ptrs to calibration functions
> ALSA: hda/tas2781: load_calibration just load
> ASoC: tas2781: add configurable global_addr
> ALSA: hda/tas2781: add TAS2563 support for 14ARB7
> ASoC: tas2781: check negative indexes
> ASoC: tas2781: use 0 as default prog/conf index
> ASoC: tas2781: move set_drv_data outside tasdevice_init
> ALSA: hda/tas2781: remove sound controls in unbind
> ALSA: hda/tas2781: call cleaner functions only once
> ALSA: hda/tas2781: reset the amp before component_add
> ALSA: hda/tas2781: configure the amp after firmware load
Please don't randomly interleave ASoC and ALSA patches like this without
some strong need, it just makes everything harder to manage.
On Thu, 07 Dec 2023 14:55:25 +0100,
Mark Brown wrote:
>
> On Thu, Dec 07, 2023 at 01:58:22AM +0100, Gergo Koteles wrote:
>
> > Gergo Koteles (16):
> > ASoC: tas2781: add support for fw version 0x0503
> > ALSA: hda/tas2781: leave hda_component in usable state
> > ASoC: tas2781: disable regmap regcache
> > ALSA: hda/tas2781: handle missing calibration data
> > ALSA: hda/tas2781: fix typos in comment
> > ASoC: tas2781: add ptrs to calibration functions
> > ALSA: hda/tas2781: load_calibration just load
> > ASoC: tas2781: add configurable global_addr
> > ALSA: hda/tas2781: add TAS2563 support for 14ARB7
> > ASoC: tas2781: check negative indexes
> > ASoC: tas2781: use 0 as default prog/conf index
> > ASoC: tas2781: move set_drv_data outside tasdevice_init
> > ALSA: hda/tas2781: remove sound controls in unbind
> > ALSA: hda/tas2781: call cleaner functions only once
> > ALSA: hda/tas2781: reset the amp before component_add
> > ALSA: hda/tas2781: configure the amp after firmware load
>
> Please don't randomly interleave ASoC and ALSA patches like this without
> some strong need, it just makes everything harder to manage.
And, some look really like rather individual fixes; they deserve for
Fixes tag and Cc-to-stable, at least.
thanks,
Takashi
The tas2781-hda driver can be modified to support tas2563 as well.
Before knowing this information, I created another series for a
new driver.
Link: https://lore.kernel.org/lkml/[email protected]/
This series now extends tas2781-hda.
The tas2563 is a smart amplifier. Similar to tas2562 but with DSP. Some
Lenovo laptops have it to drive the bass speakers. By default, it is in
software shutdown state.
To make the DSP work it needs a firmware and some calibration data.
The latter can be read from the EFI in Lenovo laptops.
For the correct configuration it needs additional register data.
It captured after running the Windows driver.
The firmware can be extracted as TAS2563Firmware.bin from the Windows
driver with innoextract.
https://download.lenovo.com/consumer/mobiles/h5yd037fbfyy7kd0.exe
The driver will search for it as TAS2XXX3870.bin with the Lenovo Yoga 7
14ARB7.
The captured registers extracted with TI's regtool:
https://github.com/soyersoyer/tas2563rca/raw/main/INT8866RCA2.bin
Changes since v1:
- fixes were sent as individual patches
- rebased onto for-next
- adding the missed fixup
Gergo Koteles (4):
ALSA: hda/tas2781: add ptrs to calibration functions
ALSA: hda/tas2781: add configurable global i2c address
ALSA: hda/tas2781: add TAS2563 support for 14ARB7
ALSA: hda/tas2781: add fixup for Lenovo 14ARB7
include/sound/tas2781.h | 8 +++
sound/pci/hda/patch_realtek.c | 14 ++++
sound/pci/hda/tas2781_hda_i2c.c | 115 ++++++++++++++++++++++++++----
sound/soc/codecs/tas2781-comlib.c | 15 ++++
4 files changed, 137 insertions(+), 15 deletions(-)
base-commit: 64bf8dec54cfe57f416884a6b3d54c7f4259e93f
--
2.43.0
Make calibration functions configurable to support different calibration
data storage modes.
Signed-off-by: Gergo Koteles <[email protected]>
---
include/sound/tas2781.h | 5 +++++
sound/pci/hda/tas2781_hda_i2c.c | 25 +++++++++++--------------
sound/soc/codecs/tas2781-comlib.c | 15 +++++++++++++++
3 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h
index a6c808b22318..e17ceab4fead 100644
--- a/include/sound/tas2781.h
+++ b/include/sound/tas2781.h
@@ -131,6 +131,9 @@ struct tasdevice_priv {
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);
};
void tas2781_reset(struct tasdevice_priv *tas_dev);
@@ -139,6 +142,8 @@ int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
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);
+int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
+void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
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,
diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c
index dfe281b57aa6..0f8d5f947f54 100644
--- a/sound/pci/hda/tas2781_hda_i2c.c
+++ b/sound/pci/hda/tas2781_hda_i2c.c
@@ -479,7 +479,7 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv)
dev_dbg(tas_priv->dev, "%4ld-%2d-%2d, %2d:%2d:%2d\n",
tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
- tas2781_apply_calib(tas_priv);
+ tasdevice_apply_calibration(tas_priv);
} else
tas_priv->cali_data.total_sz = 0;
@@ -582,7 +582,7 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
/* If calibrated data occurs error, dsp will still works with default
* calibrated data inside algo.
*/
- tas2781_save_calibration(tas_priv);
+ tasdevice_save_calibration(tas_priv);
out:
mutex_unlock(&tas_hda->priv->codec_lock);
@@ -683,10 +683,6 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
const char *device_name;
int ret;
- if (strstr(dev_name(&clt->dev), "TIAS2781"))
- device_name = "TIAS2781";
- else
- return -ENODEV;
tas_hda = devm_kzalloc(&clt->dev, sizeof(*tas_hda), GFP_KERNEL);
if (!tas_hda)
@@ -699,6 +695,13 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
if (!tas_hda->priv)
return -ENOMEM;
+ if (strstr(dev_name(&clt->dev), "TIAS2781")) {
+ device_name = "TIAS2781";
+ tas_hda->priv->save_calibration = tas2781_save_calibration;
+ tas_hda->priv->apply_calibration = tas2781_apply_calib;
+ } else
+ return -ENODEV;
+
tas_hda->priv->irq_info.irq = clt->irq;
ret = tas2781_read_acpi(tas_hda->priv, device_name);
if (ret)
@@ -765,8 +768,6 @@ static int tas2781_runtime_suspend(struct device *dev)
static int tas2781_runtime_resume(struct device *dev)
{
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
- unsigned long calib_data_sz =
- tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
dev_dbg(tas_hda->dev, "Runtime Resume\n");
@@ -777,8 +778,7 @@ static int tas2781_runtime_resume(struct device *dev)
/* If calibrated data occurs error, dsp will still works with default
* calibrated data inside algo.
*/
- if (tas_hda->priv->cali_data.total_sz > calib_data_sz)
- tas2781_apply_calib(tas_hda->priv);
+ tasdevice_apply_calibration(tas_hda->priv);
mutex_unlock(&tas_hda->priv->codec_lock);
@@ -809,8 +809,6 @@ static int tas2781_system_suspend(struct device *dev)
static int tas2781_system_resume(struct device *dev)
{
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
- unsigned long calib_data_sz =
- tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
int i, ret;
dev_info(tas_hda->priv->dev, "System Resume\n");
@@ -832,8 +830,7 @@ static int tas2781_system_resume(struct device *dev)
/* If calibrated data occurs error, dsp will still work with default
* calibrated data inside algo.
*/
- if (tas_hda->priv->cali_data.total_sz > calib_data_sz)
- tas2781_apply_calib(tas_hda->priv);
+ tasdevice_apply_calibration(tas_hda->priv);
mutex_unlock(&tas_hda->priv->codec_lock);
return 0;
diff --git a/sound/soc/codecs/tas2781-comlib.c b/sound/soc/codecs/tas2781-comlib.c
index 00e35169ae49..b7e56ceb1acf 100644
--- a/sound/soc/codecs/tas2781-comlib.c
+++ b/sound/soc/codecs/tas2781-comlib.c
@@ -412,6 +412,21 @@ void tasdevice_remove(struct tasdevice_priv *tas_priv)
}
EXPORT_SYMBOL_GPL(tasdevice_remove);
+int tasdevice_save_calibration(struct tasdevice_priv *tas_priv)
+{
+ if (tas_priv->save_calibration)
+ return tas_priv->save_calibration(tas_priv);
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(tasdevice_save_calibration);
+
+void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv)
+{
+ if (tas_priv->apply_calibration && tas_priv->cali_data.total_sz)
+ tas_priv->apply_calibration(tas_priv);
+}
+EXPORT_SYMBOL_GPL(tasdevice_apply_calibration);
+
static int tasdevice_clamp(int val, int max, unsigned int invert)
{
if (val > max)
--
2.43.0
Make the global i2c address configurable to support compatible amplifiers
with different global i2c address.
Signed-off-by: Gergo Koteles <[email protected]>
---
include/sound/tas2781.h | 2 ++
sound/pci/hda/tas2781_hda_i2c.c | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h
index e17ceab4fead..dde9f8120d4c 100644
--- a/include/sound/tas2781.h
+++ b/include/sound/tas2781.h
@@ -121,6 +121,8 @@ struct tasdevice_priv {
bool force_fwload_status;
bool playback_started;
bool isacpi;
+ unsigned int global_addr;
+
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,
diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c
index 0f8d5f947f54..49477d17b07c 100644
--- a/sound/pci/hda/tas2781_hda_i2c.c
+++ b/sound/pci/hda/tas2781_hda_i2c.c
@@ -81,7 +81,7 @@ static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
if (i2c_acpi_get_i2c_resource(ares, &sb)) {
if (tas_priv->ndev < TASDEVICE_MAX_CHANNELS &&
- sb->slave_address != TAS2781_GLOBAL_ADDR) {
+ sb->slave_address != tas_priv->global_addr) {
tas_priv->tasdevice[tas_priv->ndev].dev_addr =
(unsigned int)sb->slave_address;
tas_priv->ndev++;
@@ -699,6 +699,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
device_name = "TIAS2781";
tas_hda->priv->save_calibration = tas2781_save_calibration;
tas_hda->priv->apply_calibration = tas2781_apply_calib;
+ tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;
} else
return -ENODEV;
--
2.43.0
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 <[email protected]>
---
include/sound/tas2781.h | 1 +
sound/pci/hda/tas2781_hda_i2c.c | 87 +++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+)
diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h
index dde9f8120d4c..0a86ab8d47b9 100644
--- a/include/sound/tas2781.h
+++ b/include/sound/tas2781.h
@@ -22,6 +22,7 @@
#define TAS2781_DRV_VER 1
#define SMARTAMP_MODULE_NAME "tas2781"
#define TAS2781_GLOBAL_ADDR 0x40
+#define TAS2563_GLOBAL_ADDR 0x48
#define TASDEVICE_RATES (SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
SNDRV_PCM_RATE_88200)
diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c
index 49477d17b07c..057688ca29bf 100644
--- a/sound/pci/hda/tas2781_hda_i2c.c
+++ b/sound/pci/hda/tas2781_hda_i2c.c
@@ -65,6 +65,24 @@ enum calib_data {
CALIB_MAX
};
+#define TAS2563_MAX_CHANNELS 4
+
+#define TAS2563_CAL_POWER TASDEVICE_REG(0, 0x0d, 0x3c)
+#define TAS2563_CAL_R0 TASDEVICE_REG(0, 0x0f, 0x34)
+#define TAS2563_CAL_INVR0 TASDEVICE_REG(0, 0x0f, 0x40)
+#define TAS2563_CAL_R0_LOW TASDEVICE_REG(0, 0x0f, 0x48)
+#define TAS2563_CAL_TLIM TASDEVICE_REG(0, 0x10, 0x14)
+#define TAS2563_CAL_N 5
+#define TAS2563_CAL_DATA_SIZE 4
+#define TAS2563_CAL_CH_SIZE 20
+#define TAS2563_CAL_ARRAY_SIZE 80
+
+static unsigned int cal_regs[TAS2563_CAL_N] = {
+ TAS2563_CAL_POWER, TAS2563_CAL_R0, TAS2563_CAL_INVR0,
+ TAS2563_CAL_R0_LOW, TAS2563_CAL_TLIM,
+};
+
+
struct tas2781_hda {
struct device *dev;
struct tasdevice_priv *priv;
@@ -404,6 +422,69 @@ static const struct snd_kcontrol_new tas2781_dsp_conf_ctrl = {
.put = tasdevice_config_put,
};
+static void tas2563_apply_calib(struct tasdevice_priv *tas_priv)
+{
+ unsigned int data;
+ int offset = 0;
+ int ret;
+
+ for (int i = 0; i < tas_priv->ndev; i++) {
+ for (int j = 0; j < TAS2563_CAL_N; ++j) {
+ data = cpu_to_be32(
+ *(uint32_t *)&tas_priv->cali_data.data[offset]);
+ ret = tasdevice_dev_bulk_write(tas_priv, i, cal_regs[j],
+ (unsigned char *)&data, TAS2563_CAL_DATA_SIZE);
+ if (ret)
+ dev_err(tas_priv->dev,
+ "Error writing calib regs\n");
+ offset += TAS2563_CAL_DATA_SIZE;
+ }
+ }
+}
+
+static int tas2563_save_calibration(struct tasdevice_priv *tas_priv)
+{
+ static efi_guid_t efi_guid = EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc,
+ 0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92);
+
+ static efi_char16_t *efi_vars[TAS2563_MAX_CHANNELS][TAS2563_CAL_N] = {
+ { L"Power_1", L"R0_1", L"InvR0_1", L"R0_Low_1", L"TLim_1" },
+ { L"Power_2", L"R0_2", L"InvR0_2", L"R0_Low_2", L"TLim_2" },
+ { L"Power_3", L"R0_3", L"InvR0_3", L"R0_Low_3", L"TLim_3" },
+ { L"Power_4", L"R0_4", L"InvR0_4", L"R0_Low_4", L"TLim_4" },
+ };
+
+ unsigned long max_size = TAS2563_CAL_DATA_SIZE;
+ unsigned int offset = 0;
+ efi_status_t status;
+ unsigned int attr;
+
+ tas_priv->cali_data.data = devm_kzalloc(tas_priv->dev,
+ TAS2563_CAL_ARRAY_SIZE, GFP_KERNEL);
+ if (!tas_priv->cali_data.data)
+ return -ENOMEM;
+
+ for (int i = 0; i < tas_priv->ndev; ++i) {
+ for (int j = 0; j < TAS2563_CAL_N; ++j) {
+ status = efi.get_variable(efi_vars[i][j],
+ &efi_guid, &attr, &max_size,
+ &tas_priv->cali_data.data[offset]);
+ if (status != EFI_SUCCESS ||
+ max_size != TAS2563_CAL_DATA_SIZE) {
+ dev_warn(tas_priv->dev,
+ "Calibration data read failed %ld\n", status);
+ return -EINVAL;
+ }
+ offset += TAS2563_CAL_DATA_SIZE;
+ }
+ }
+
+ tas_priv->cali_data.total_sz = offset;
+ tasdevice_apply_calibration(tas_priv);
+
+ return 0;
+}
+
static void tas2781_apply_calib(struct tasdevice_priv *tas_priv)
{
static const unsigned char page_array[CALIB_MAX] = {
@@ -700,6 +781,11 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
tas_hda->priv->save_calibration = tas2781_save_calibration;
tas_hda->priv->apply_calibration = tas2781_apply_calib;
tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;
+ } else if (strstr(dev_name(&clt->dev), "INT8866")) {
+ device_name = "INT8866";
+ tas_hda->priv->save_calibration = tas2563_save_calibration;
+ tas_hda->priv->apply_calibration = tas2563_apply_calib;
+ tas_hda->priv->global_addr = TAS2563_GLOBAL_ADDR;
} else
return -ENODEV;
@@ -849,6 +935,7 @@ static const struct i2c_device_id tas2781_hda_i2c_id[] = {
static const struct acpi_device_id tas2781_acpi_hda_match[] = {
{"TIAS2781", 0 },
+ {"INT8866", 0 },
{}
};
MODULE_DEVICE_TABLE(acpi, tas2781_acpi_hda_match);
--
2.43.0
The 14ARB7 has two tas2563 amplifier on i2c.
Connect it to the tas2781 driver.
Signed-off-by: Gergo Koteles <[email protected]>
---
sound/pci/hda/patch_realtek.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 19040887ff67..67468f7d1c90 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6989,6 +6989,12 @@ static void tas2781_fixup_i2c(struct hda_codec *cdc,
tas2781_generic_fixup(cdc, action, "i2c", "TIAS2781");
}
+static void yoga7_14arb7_fixup_i2c(struct hda_codec *cdc,
+ const struct hda_fixup *fix, int action)
+{
+ tas2781_generic_fixup(cdc, action, "i2c", "INT8866");
+}
+
/* for alc295_fixup_hp_top_speakers */
#include "hp_x360_helper.c"
@@ -7460,6 +7466,7 @@ enum {
ALC236_FIXUP_DELL_DUAL_CODECS,
ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
ALC287_FIXUP_TAS2781_I2C,
+ ALC287_FIXUP_YOGA7_14ARB7_I2C,
ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
ALC245_FIXUP_HP_X360_MUTE_LEDS,
ALC287_FIXUP_THINKPAD_I2S_SPK,
@@ -9578,6 +9585,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
},
+ [ALC287_FIXUP_YOGA7_14ARB7_I2C] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = yoga7_14arb7_fixup_i2c,
+ .chained = true,
+ .chain_id = ALC285_FIXUP_THINKPAD_HEADSET_JACK,
+ },
[ALC245_FIXUP_HP_MUTE_LED_COEFBIT] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc245_fixup_hp_mute_led_coefbit,
@@ -10231,6 +10244,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C),
--
2.43.0
On Sat, 30 Dec 2023 01:09:41 +0100,
Gergo Koteles wrote:
>
> The tas2781-hda driver can be modified to support tas2563 as well.
> Before knowing this information, I created another series for a
> new driver.
> Link: https://lore.kernel.org/lkml/[email protected]/
>
> This series now extends tas2781-hda.
>
> The tas2563 is a smart amplifier. Similar to tas2562 but with DSP. Some
> Lenovo laptops have it to drive the bass speakers. By default, it is in
> software shutdown state.
>
> To make the DSP work it needs a firmware and some calibration data.
> The latter can be read from the EFI in Lenovo laptops.
>
> For the correct configuration it needs additional register data.
> It captured after running the Windows driver.
>
> The firmware can be extracted as TAS2563Firmware.bin from the Windows
> driver with innoextract.
> https://download.lenovo.com/consumer/mobiles/h5yd037fbfyy7kd0.exe
>
> The driver will search for it as TAS2XXX3870.bin with the Lenovo Yoga 7
> 14ARB7.
>
> The captured registers extracted with TI's regtool:
> https://github.com/soyersoyer/tas2563rca/raw/main/INT8866RCA2.bin
>
> Changes since v1:
> - fixes were sent as individual patches
> - rebased onto for-next
> - adding the missed fixup
>
> Gergo Koteles (4):
> ALSA: hda/tas2781: add ptrs to calibration functions
> ALSA: hda/tas2781: add configurable global i2c address
> ALSA: hda/tas2781: add TAS2563 support for 14ARB7
> ALSA: hda/tas2781: add fixup for Lenovo 14ARB7
Thanks, I guess I'll take this series later for 6.8 unless any
objection is raised from reviewers.
But, I'd like to hear clarifications of some points beforehand:
- Did we get consensus about the ACPI HID? I didn't follow the
previous thread completely.
Since those models have been already in the market for quite some
time, we'd have to accept "INT8866", I'm afraid. But it's still
very important to know whether a similar problem can be avoided in
future.
- Will be the firmware files upstreamed to linux-firmware tree later?
Otherwise users will have significant difficulties.
Takashi
Hi Takashi,
On Sat, 2023-12-30 at 17:59 +0100, Takashi Iwai wrote:
> Thanks, I guess I'll take this series later for 6.8 unless any
> objection is raised from reviewers.
>
> But, I'd like to hear clarifications of some points beforehand:
>
> - Did we get consensus about the ACPI HID? I didn't follow the
> previous thread completely.
>
The INT8866 is a (wrong) PNP ID, that should only be used by the owner
"Interphase Corporation".
Intel has also mistakenly used the INT PNP prefix in the past, and now
TI/leNovo.
> Since those models have been already in the market for quite some
> time, we'd have to accept "INT8866", I'm afraid. But it's still
> very important to know whether a similar problem can be avoided in
> future.
>
> - Will be the firmware files upstreamed to linux-firmware tree later?
> Otherwise users will have significant difficulties.
Shenghao sent the two files to [email protected] a few days
ago, but I think the "Allegedly GPLv2+ ... Found in hex form in kernel
source." Licence needs to be fixed before acceptance.
But even if it is not included in the linux-firmware package, it is
easier for users to put two files in place per OS installation than
patching the kernel.
Regards,
Gergo
On Sat, 30 Dec 2023 21:18:06 +0100,
Gergo Koteles wrote:
>
> Hi Takashi,
>
> On Sat, 2023-12-30 at 17:59 +0100, Takashi Iwai wrote:
> > Thanks, I guess I'll take this series later for 6.8 unless any
> > objection is raised from reviewers.
> >
> > But, I'd like to hear clarifications of some points beforehand:
> >
> > - Did we get consensus about the ACPI HID? I didn't follow the
> > previous thread completely.
> >
>
> The INT8866 is a (wrong) PNP ID, that should only be used by the owner
> "Interphase Corporation".
> Intel has also mistakenly used the INT PNP prefix in the past, and now
> TI/leNovo.
Yeah, and the question is whether TI / Lenovo recognize the problem
and will avoid such a failure in future again.
> > Since those models have been already in the market for quite some
> > time, we'd have to accept "INT8866", I'm afraid. But it's still
> > very important to know whether a similar problem can be avoided in
> > future.
> >
> > - Will be the firmware files upstreamed to linux-firmware tree later?
> > Otherwise users will have significant difficulties.
>
> Shenghao sent the two files?to [email protected] a few days
> ago, but I think the "Allegedly GPLv2+ ... Found in hex form in kernel
> source." Licence needs to be fixed before acceptance.
OK, that sounds promising.
> But even if it is not included in the linux-firmware package, it is
> easier for users to put two files in place per OS installation than
> patching the kernel.
Sure.
thanks,
Takashi
On Sat, 30 Dec 2023 01:09:41 +0100,
Gergo Koteles wrote:
>
> The tas2781-hda driver can be modified to support tas2563 as well.
> Before knowing this information, I created another series for a
> new driver.
> Link: https://lore.kernel.org/lkml/[email protected]/
>
> This series now extends tas2781-hda.
>
> The tas2563 is a smart amplifier. Similar to tas2562 but with DSP. Some
> Lenovo laptops have it to drive the bass speakers. By default, it is in
> software shutdown state.
>
> To make the DSP work it needs a firmware and some calibration data.
> The latter can be read from the EFI in Lenovo laptops.
>
> For the correct configuration it needs additional register data.
> It captured after running the Windows driver.
>
> The firmware can be extracted as TAS2563Firmware.bin from the Windows
> driver with innoextract.
> https://download.lenovo.com/consumer/mobiles/h5yd037fbfyy7kd0.exe
>
> The driver will search for it as TAS2XXX3870.bin with the Lenovo Yoga 7
> 14ARB7.
>
> The captured registers extracted with TI's regtool:
> https://github.com/soyersoyer/tas2563rca/raw/main/INT8866RCA2.bin
>
> Changes since v1:
> - fixes were sent as individual patches
> - rebased onto for-next
> - adding the missed fixup
>
> Gergo Koteles (4):
> ALSA: hda/tas2781: add ptrs to calibration functions
> ALSA: hda/tas2781: add configurable global i2c address
> ALSA: hda/tas2781: add TAS2563 support for 14ARB7
> ALSA: hda/tas2781: add fixup for Lenovo 14ARB7
Applies all patches to for-next branch now.
thanks,
Takashi