mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-08 15:04:45 +00:00
sound fixes for 6.7-rc7
Apparently there were so many kids wishing bug fixes that made Santa busy; here we have lots of fixes although it's a bit late. But all changes are device-specific, hence it should be relatively safe to apply. Most of changes are for Cirrus codecs (for both ASoC and HD-audio), while the remaining are fixes for TI codecs, HD-audio and USB-audio quirks. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmWFuhMOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE8hhw/+Pgazo/uYRbm9UdkhU/h65Jt1mwk9cNxhGoBw wI4PORTcFMYz2sY/IFtVdHL2ljG00ffaiQnHV4Ifi+/KobojI/PpyUkvA5c1/L3c 4i8BdwfWu4cEr7zSNtA3p18PY/8Ka1o6rRLPHHKX/AnGuzx4gv/chbOUCLkDuD96 Yq6W4X6YuT0Sb9xPa9nZRQHxw4OrAc7XbV0yswnvEBgKAzpSNwOM3RxiUncwL2xK UMX7gIBEIg38I5T5hGIZtiAJapoCSOmOXgunJrR9XB3LYQm7QZM30YGeAjYordhq z05qFiv03GLRAhnS1smn4udhjloSDNb/4Vz1kg5u2VV+6SOFjjfA7N6/P+rbXXEA 45UzQY5tf/oqDfuAzVUJ2Tbjdzs4Rxzi9k3Zr9Ig5sXPGkyQA30Iy9OQZxDFsSbR kToEVNJWflf/BXfHhOl/DcKniXmeJD3FYCmCQFXPK8t3JOcjXB6UM5qqkZBfl0A5 QCKGBudgGbsDbIPeiYS//l+VTWXUU02wVIr8jn0YltVbatOQI1RoDqg9KTT9ISi3 kfIGhtLAoHgqPe2DCmONinZr3cDGtG8M3czTr2aZBgLLv3tHP/QfIUbq6T1aYbD0 kolo9jmBDcK2V1t/mWhZh3LsGwNx1qcIIkEaVsh7nsicSyGpkRjpedL1A+XwY/fT izGrIE4= =KNH2 -----END PGP SIGNATURE----- Merge tag 'sound-6.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "Apparently there were so many kids wishing bug fixes that made Santa busy; here we have lots of fixes although it's a bit late. But all changes are device-specific, hence it should be relatively safe to apply. Most of changes are for Cirrus codecs (for both ASoC and HD-audio), while the remaining are fixes for TI codecs, HD-audio and USB-audio quirks" * tag 'sound-6.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (24 commits) ALSA: hda: cs35l41: Only add SPI CS GPIO if SPI is enabled in kernel ALSA: hda: cs35l41: Do not allow uninitialised variables to be freed ASoC: fsl_sai: Fix channel swap issue on i.MX8MP ASoC: hdmi-codec: fix missing report for jack initial status ALSA: hda/realtek: Add quirks for ASUS Zenbook 2023 Models ALSA: hda: cs35l41: Support additional ASUS Zenbook 2023 Models ALSA: hda/realtek: Add quirks for ASUS Zenbook 2022 Models ALSA: hda: cs35l41: Support additional ASUS Zenbook 2022 Models ALSA: hda/realtek: Add quirks for ASUS ROG 2023 models ALSA: hda: cs35l41: Support additional ASUS ROG 2023 models ALSA: hda: cs35l41: Add config table to support many laptops without _DSD ASoC: Intel: bytcr_rt5640: Add new swapped-speakers quirk ASoC: Intel: bytcr_rt5640: Add quirk for the Medion Lifetab S10346 kselftest: alsa: fixed a print formatting warning ALSA: usb-audio: Increase delay in MOTU M quirk ASoC: tas2781: check the validity of prm_no/cfg_no ALSA: hda/tas2781: select program 0, conf 0 by default ALSA: hda/realtek: Add quirk for ASUS ROG GV302XA ASoC: cs42l43: Don't enable bias sense during type detect ASoC: Intel: soc-acpi-intel-mtl-match: Change CS35L56 prefixes to AMPn ...
This commit is contained in:
commit
5414aea7b7
@ -1826,6 +1826,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
|
||||
if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type))
|
||||
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
|
||||
gpiod_put(cs35l41->reset_gpio);
|
||||
gpiod_put(cs35l41->cs_gpio);
|
||||
acpi_dev_put(cs35l41->dacpi);
|
||||
kfree(cs35l41->acpi_subsystem_id);
|
||||
|
||||
@ -1853,6 +1854,7 @@ void cs35l41_hda_remove(struct device *dev)
|
||||
if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type))
|
||||
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
|
||||
gpiod_put(cs35l41->reset_gpio);
|
||||
gpiod_put(cs35l41->cs_gpio);
|
||||
kfree(cs35l41->acpi_subsystem_id);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41);
|
||||
|
@ -35,8 +35,8 @@ struct cs35l41_amp_efi_data {
|
||||
} __packed;
|
||||
|
||||
enum cs35l41_hda_spk_pos {
|
||||
CS35l41_LEFT,
|
||||
CS35l41_RIGHT,
|
||||
CS35L41_LEFT,
|
||||
CS35L41_RIGHT,
|
||||
};
|
||||
|
||||
enum cs35l41_hda_gpio_function {
|
||||
@ -50,6 +50,7 @@ struct cs35l41_hda {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct gpio_desc *cs_gpio;
|
||||
struct cs35l41_hw_cfg hw_cfg;
|
||||
struct hda_codec *codec;
|
||||
|
||||
|
@ -6,9 +6,303 @@
|
||||
//
|
||||
// Author: Stefan Binding <sbinding@opensource.cirrus.com>
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/string.h>
|
||||
#include "cs35l41_hda_property.h"
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#define MAX_AMPS 4
|
||||
|
||||
struct cs35l41_config {
|
||||
const char *ssid;
|
||||
enum {
|
||||
SPI,
|
||||
I2C
|
||||
} bus;
|
||||
int num_amps;
|
||||
enum {
|
||||
INTERNAL,
|
||||
EXTERNAL
|
||||
} boost_type;
|
||||
u8 channel[MAX_AMPS];
|
||||
int reset_gpio_index; /* -1 if no reset gpio */
|
||||
int spkid_gpio_index; /* -1 if no spkid gpio */
|
||||
int cs_gpio_index; /* -1 if no cs gpio, or cs-gpios already exists, max num amps == 2 */
|
||||
int boost_ind_nanohenry; /* Required if boost_type == Internal */
|
||||
int boost_peak_milliamp; /* Required if boost_type == Internal */
|
||||
int boost_cap_microfarad; /* Required if boost_type == Internal */
|
||||
};
|
||||
|
||||
static const struct cs35l41_config cs35l41_config_table[] = {
|
||||
/*
|
||||
* Device 103C89C6 does have _DSD, however it is setup to use the wrong boost type.
|
||||
* We can override the _DSD to correct the boost type here.
|
||||
* Since this laptop has valid ACPI, we do not need to handle cs-gpios, since that already exists
|
||||
* in the ACPI. The Reset GPIO is also valid, so we can use the Reset defined in _DSD.
|
||||
*/
|
||||
{ "103C89C6", SPI, 2, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, -1, -1, -1, 1000, 4500, 24 },
|
||||
{ "104312AF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431433", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431463", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431473", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "10431483", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "10431493", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104314D3", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104314E3", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431503", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431533", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431573", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431663", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "104316D3", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "104316F3", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "104317F3", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431863", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104318D3", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "10431C9F", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CAF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CCF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CDF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CEF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431D1F", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431DA2", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431E02", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431EE2", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
|
||||
{ "10431F12", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431F1F", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
|
||||
{ "10431F62", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{}
|
||||
};
|
||||
|
||||
static int cs35l41_add_gpios(struct cs35l41_hda *cs35l41, struct device *physdev, int reset_gpio,
|
||||
int spkid_gpio, int cs_gpio_index, int num_amps)
|
||||
{
|
||||
struct acpi_gpio_mapping *gpio_mapping = NULL;
|
||||
struct acpi_gpio_params *reset_gpio_params = NULL;
|
||||
struct acpi_gpio_params *spkid_gpio_params = NULL;
|
||||
struct acpi_gpio_params *cs_gpio_params = NULL;
|
||||
unsigned int num_entries = 0;
|
||||
unsigned int reset_index, spkid_index, csgpio_index;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* GPIO Mapping only needs to be done once, since it would be available for subsequent amps
|
||||
*/
|
||||
if (cs35l41->dacpi->driver_gpios)
|
||||
return 0;
|
||||
|
||||
if (reset_gpio >= 0) {
|
||||
reset_index = num_entries;
|
||||
num_entries++;
|
||||
}
|
||||
|
||||
if (spkid_gpio >= 0) {
|
||||
spkid_index = num_entries;
|
||||
num_entries++;
|
||||
}
|
||||
|
||||
if ((cs_gpio_index >= 0) && (num_amps == 2)) {
|
||||
csgpio_index = num_entries;
|
||||
num_entries++;
|
||||
}
|
||||
|
||||
if (!num_entries)
|
||||
return 0;
|
||||
|
||||
/* must include termination entry */
|
||||
num_entries++;
|
||||
|
||||
gpio_mapping = devm_kcalloc(physdev, num_entries, sizeof(struct acpi_gpio_mapping),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!gpio_mapping)
|
||||
goto err;
|
||||
|
||||
if (reset_gpio >= 0) {
|
||||
gpio_mapping[reset_index].name = "reset-gpios";
|
||||
reset_gpio_params = devm_kcalloc(physdev, num_amps, sizeof(struct acpi_gpio_params),
|
||||
GFP_KERNEL);
|
||||
if (!reset_gpio_params)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < num_amps; i++)
|
||||
reset_gpio_params[i].crs_entry_index = reset_gpio;
|
||||
|
||||
gpio_mapping[reset_index].data = reset_gpio_params;
|
||||
gpio_mapping[reset_index].size = num_amps;
|
||||
}
|
||||
|
||||
if (spkid_gpio >= 0) {
|
||||
gpio_mapping[spkid_index].name = "spk-id-gpios";
|
||||
spkid_gpio_params = devm_kcalloc(physdev, num_amps, sizeof(struct acpi_gpio_params),
|
||||
GFP_KERNEL);
|
||||
if (!spkid_gpio_params)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < num_amps; i++)
|
||||
spkid_gpio_params[i].crs_entry_index = spkid_gpio;
|
||||
|
||||
gpio_mapping[spkid_index].data = spkid_gpio_params;
|
||||
gpio_mapping[spkid_index].size = num_amps;
|
||||
}
|
||||
|
||||
if ((cs_gpio_index >= 0) && (num_amps == 2)) {
|
||||
gpio_mapping[csgpio_index].name = "cs-gpios";
|
||||
/* only one GPIO CS is supported without using _DSD, obtained using index 0 */
|
||||
cs_gpio_params = devm_kzalloc(physdev, sizeof(struct acpi_gpio_params), GFP_KERNEL);
|
||||
if (!cs_gpio_params)
|
||||
goto err;
|
||||
|
||||
cs_gpio_params->crs_entry_index = cs_gpio_index;
|
||||
|
||||
gpio_mapping[csgpio_index].data = cs_gpio_params;
|
||||
gpio_mapping[csgpio_index].size = 1;
|
||||
}
|
||||
|
||||
return devm_acpi_dev_add_driver_gpios(physdev, gpio_mapping);
|
||||
err:
|
||||
devm_kfree(physdev, gpio_mapping);
|
||||
devm_kfree(physdev, reset_gpio_params);
|
||||
devm_kfree(physdev, spkid_gpio_params);
|
||||
devm_kfree(physdev, cs_gpio_params);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
|
||||
const char *hid)
|
||||
{
|
||||
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
|
||||
const struct cs35l41_config *cfg;
|
||||
struct gpio_desc *cs_gpiod;
|
||||
struct spi_device *spi;
|
||||
bool dsd_found;
|
||||
int ret;
|
||||
|
||||
for (cfg = cs35l41_config_table; cfg->ssid; cfg++) {
|
||||
if (!strcasecmp(cfg->ssid, cs35l41->acpi_subsystem_id))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cfg->ssid)
|
||||
return -ENOENT;
|
||||
|
||||
if (!cs35l41->dacpi || cs35l41->dacpi != ACPI_COMPANION(physdev)) {
|
||||
dev_err(cs35l41->dev, "ACPI Device does not match, cannot override _DSD.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(cs35l41->dev, "Adding DSD properties for %s\n", cs35l41->acpi_subsystem_id);
|
||||
|
||||
dsd_found = acpi_dev_has_props(cs35l41->dacpi);
|
||||
|
||||
if (!dsd_found) {
|
||||
ret = cs35l41_add_gpios(cs35l41, physdev, cfg->reset_gpio_index,
|
||||
cfg->spkid_gpio_index, cfg->cs_gpio_index,
|
||||
cfg->num_amps);
|
||||
if (ret) {
|
||||
dev_err(cs35l41->dev, "Error adding GPIO mapping: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else if (cfg->reset_gpio_index >= 0 || cfg->spkid_gpio_index >= 0) {
|
||||
dev_warn(cs35l41->dev, "Cannot add Reset/Speaker ID/SPI CS GPIO Mapping, "
|
||||
"_DSD already exists.\n");
|
||||
}
|
||||
|
||||
if (cfg->bus == SPI) {
|
||||
cs35l41->index = id;
|
||||
|
||||
#if IS_ENABLED(CONFIG_SPI)
|
||||
/*
|
||||
* Manually set the Chip Select for the second amp <cs_gpio_index> in the node.
|
||||
* This is only supported for systems with 2 amps, since we cannot expand the
|
||||
* default number of chip selects without using cs-gpios
|
||||
* The CS GPIO must be set high prior to communicating with the first amp (which
|
||||
* uses a native chip select), to ensure the second amp does not clash with the
|
||||
* first.
|
||||
*/
|
||||
if (cfg->cs_gpio_index >= 0) {
|
||||
spi = to_spi_device(cs35l41->dev);
|
||||
|
||||
if (cfg->num_amps != 2) {
|
||||
dev_warn(cs35l41->dev,
|
||||
"Cannot update SPI CS, Number of Amps (%d) != 2\n",
|
||||
cfg->num_amps);
|
||||
} else if (dsd_found) {
|
||||
dev_warn(cs35l41->dev,
|
||||
"Cannot update SPI CS, _DSD already exists.\n");
|
||||
} else {
|
||||
/*
|
||||
* This is obtained using driver_gpios, since only one GPIO for CS
|
||||
* exists, this can be obtained using index 0.
|
||||
*/
|
||||
cs_gpiod = gpiod_get_index(physdev, "cs", 0, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(cs_gpiod)) {
|
||||
dev_err(cs35l41->dev,
|
||||
"Unable to get Chip Select GPIO descriptor\n");
|
||||
return PTR_ERR(cs_gpiod);
|
||||
}
|
||||
if (id == 1) {
|
||||
spi_set_csgpiod(spi, 0, cs_gpiod);
|
||||
cs35l41->cs_gpio = cs_gpiod;
|
||||
} else {
|
||||
gpiod_set_value_cansleep(cs_gpiod, true);
|
||||
gpiod_put(cs_gpiod);
|
||||
}
|
||||
spi_setup(spi);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (cfg->num_amps > 2)
|
||||
/*
|
||||
* i2c addresses for 3/4 amps are used in order: 0x40, 0x41, 0x42, 0x43,
|
||||
* subtracting 0x40 would give zero-based index
|
||||
*/
|
||||
cs35l41->index = id - 0x40;
|
||||
else
|
||||
/* i2c addr 0x40 for first amp (always), 0x41/0x42 for 2nd amp */
|
||||
cs35l41->index = id == 0x40 ? 0 : 1;
|
||||
}
|
||||
|
||||
if (cfg->num_amps == 3)
|
||||
/* 3 amps means a center channel, so no duplicate channels */
|
||||
cs35l41->channel_index = 0;
|
||||
else
|
||||
/*
|
||||
* if 4 amps, there are duplicate channels, so they need different indexes
|
||||
* if 2 amps, no duplicate channels, channel_index would be 0
|
||||
*/
|
||||
cs35l41->channel_index = cs35l41->index / 2;
|
||||
|
||||
cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(cs35l41->dacpi), "reset",
|
||||
cs35l41->index, GPIOD_OUT_LOW,
|
||||
"cs35l41-reset");
|
||||
cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, cfg->num_amps, -1);
|
||||
|
||||
hw_cfg->spk_pos = cfg->channel[cs35l41->index];
|
||||
|
||||
if (cfg->boost_type == INTERNAL) {
|
||||
hw_cfg->bst_type = CS35L41_INT_BOOST;
|
||||
hw_cfg->bst_ind = cfg->boost_ind_nanohenry;
|
||||
hw_cfg->bst_ipk = cfg->boost_peak_milliamp;
|
||||
hw_cfg->bst_cap = cfg->boost_cap_microfarad;
|
||||
hw_cfg->gpio1.func = CS35L41_NOT_USED;
|
||||
hw_cfg->gpio1.valid = true;
|
||||
} else {
|
||||
hw_cfg->bst_type = CS35L41_EXT_BOOST;
|
||||
hw_cfg->bst_ind = -1;
|
||||
hw_cfg->bst_ipk = -1;
|
||||
hw_cfg->bst_cap = -1;
|
||||
hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
|
||||
hw_cfg->gpio1.valid = true;
|
||||
}
|
||||
|
||||
hw_cfg->gpio2.func = CS35L41_INTERRUPT;
|
||||
hw_cfg->gpio2.valid = true;
|
||||
hw_cfg->valid = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device CLSA010(0/1) doesn't have _DSD so a gpiod_get by the label reset won't work.
|
||||
@ -43,44 +337,6 @@ static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device 103C89C6 does have _DSD, however it is setup to use the wrong boost type.
|
||||
* We can override the _DSD to correct the boost type here.
|
||||
* Since this laptop has valid ACPI, we do not need to handle cs-gpios, since that already exists
|
||||
* in the ACPI.
|
||||
*/
|
||||
static int hp_vision_acpi_fix(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
|
||||
const char *hid)
|
||||
{
|
||||
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
|
||||
|
||||
dev_info(cs35l41->dev, "Adding DSD properties for %s\n", cs35l41->acpi_subsystem_id);
|
||||
|
||||
cs35l41->index = id;
|
||||
cs35l41->channel_index = 0;
|
||||
|
||||
/*
|
||||
* This system has _DSD, it just contains an error, so we can still get the reset using
|
||||
* the "reset" label.
|
||||
*/
|
||||
cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(cs35l41->dacpi), "reset",
|
||||
cs35l41->index, GPIOD_OUT_LOW,
|
||||
"cs35l41-reset");
|
||||
cs35l41->speaker_id = -ENOENT;
|
||||
hw_cfg->spk_pos = cs35l41->index ? 0 : 1; // right:left
|
||||
hw_cfg->gpio1.func = CS35L41_NOT_USED;
|
||||
hw_cfg->gpio1.valid = true;
|
||||
hw_cfg->gpio2.func = CS35L41_INTERRUPT;
|
||||
hw_cfg->gpio2.valid = true;
|
||||
hw_cfg->bst_type = CS35L41_INT_BOOST;
|
||||
hw_cfg->bst_ind = 1000;
|
||||
hw_cfg->bst_ipk = 4500;
|
||||
hw_cfg->bst_cap = 24;
|
||||
hw_cfg->valid = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cs35l41_prop_model {
|
||||
const char *hid;
|
||||
const char *ssid;
|
||||
@ -91,7 +347,36 @@ struct cs35l41_prop_model {
|
||||
static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
|
||||
{ "CLSA0100", NULL, lenovo_legion_no_acpi },
|
||||
{ "CLSA0101", NULL, lenovo_legion_no_acpi },
|
||||
{ "CSC3551", "103C89C6", hp_vision_acpi_fix },
|
||||
{ "CSC3551", "103C89C6", generic_dsd_config },
|
||||
{ "CSC3551", "104312AF", generic_dsd_config },
|
||||
{ "CSC3551", "10431433", generic_dsd_config },
|
||||
{ "CSC3551", "10431463", generic_dsd_config },
|
||||
{ "CSC3551", "10431473", generic_dsd_config },
|
||||
{ "CSC3551", "10431483", generic_dsd_config },
|
||||
{ "CSC3551", "10431493", generic_dsd_config },
|
||||
{ "CSC3551", "104314D3", generic_dsd_config },
|
||||
{ "CSC3551", "104314E3", generic_dsd_config },
|
||||
{ "CSC3551", "10431503", generic_dsd_config },
|
||||
{ "CSC3551", "10431533", generic_dsd_config },
|
||||
{ "CSC3551", "10431573", generic_dsd_config },
|
||||
{ "CSC3551", "10431663", generic_dsd_config },
|
||||
{ "CSC3551", "104316D3", generic_dsd_config },
|
||||
{ "CSC3551", "104316F3", generic_dsd_config },
|
||||
{ "CSC3551", "104317F3", generic_dsd_config },
|
||||
{ "CSC3551", "10431863", generic_dsd_config },
|
||||
{ "CSC3551", "104318D3", generic_dsd_config },
|
||||
{ "CSC3551", "10431C9F", generic_dsd_config },
|
||||
{ "CSC3551", "10431CAF", generic_dsd_config },
|
||||
{ "CSC3551", "10431CCF", generic_dsd_config },
|
||||
{ "CSC3551", "10431CDF", generic_dsd_config },
|
||||
{ "CSC3551", "10431CEF", generic_dsd_config },
|
||||
{ "CSC3551", "10431D1F", generic_dsd_config },
|
||||
{ "CSC3551", "10431DA2", generic_dsd_config },
|
||||
{ "CSC3551", "10431E02", generic_dsd_config },
|
||||
{ "CSC3551", "10431EE2", generic_dsd_config },
|
||||
{ "CSC3551", "10431F12", generic_dsd_config },
|
||||
{ "CSC3551", "10431F1F", generic_dsd_config },
|
||||
{ "CSC3551", "10431F62", generic_dsd_config },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -104,7 +389,7 @@ int cs35l41_add_dsd_properties(struct cs35l41_hda *cs35l41, struct device *physd
|
||||
if (!strcmp(model->hid, hid) &&
|
||||
(!model->ssid ||
|
||||
(cs35l41->acpi_subsystem_id &&
|
||||
!strcmp(model->ssid, cs35l41->acpi_subsystem_id))))
|
||||
!strcasecmp(model->ssid, cs35l41->acpi_subsystem_id))))
|
||||
return model->add_prop(cs35l41, physdev, id, hid);
|
||||
}
|
||||
|
||||
|
@ -9948,21 +9948,28 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
|
||||
SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650P", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603V", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1493, "ASUS GV601V", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X/GA402N", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604VI/VC/VE/VG/VJ/VQ/VU/VV/VY/VZ", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603VQ/VU/VV/VJ/VI", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1493, "ASUS GV601VV/VU/VJ/VQ/VI", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G614JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS G513PI/PU/PV", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1503, "ASUS G733PY/PZ/PZV/PYV", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
|
||||
SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1533, "ASUS GV302XA/XJ/XQ/XU/XV/XI", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301VV/VQ/VU/VJ/VA/VC/VE/VVC/VQC/VUC/VJC/VEC/VCC", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZV", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZI/ZJ/ZQ/ZU/ZV", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x16d3, "ASUS UX5304VA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS UX7602VI/BZ", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
|
||||
SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally RC71L_RC71L", ALC294_FIXUP_ASUS_ALLY),
|
||||
SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally NR2301L/X", ALC294_FIXUP_ASUS_ALLY),
|
||||
SND_PCI_QUIRK(0x1043, 0x1863, "ASUS UX6404VI/VV", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
|
||||
SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC294_FIXUP_CS35L41_I2C_2),
|
||||
@ -9987,23 +9994,30 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x1c43, "ASUS UX8406MA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1c62, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JI", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JYR/JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JU/JV/JI", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY/JZ/JI/JG", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS ROG Strix G17 2023 (G713PV)", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1ccf, "ASUS G814JU/JV/JI", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1cdf, "ASUS G814JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1cef, "ASUS G834JY/JZ/JI/JG", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS G713PI/PU/PV/PVN", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f1f, "ASUS H7604JI/JV/J3D", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
|
||||
SND_PCI_QUIRK(0x1043, 0x3a20, "ASUS G614JZR", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
|
@ -543,6 +543,10 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
|
||||
|
||||
tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
|
||||
tasdevice_prmg_load(tas_priv, 0);
|
||||
if (tas_priv->fmw->nr_programs > 0)
|
||||
tas_priv->cur_prog = 0;
|
||||
if (tas_priv->fmw->nr_configurations > 0)
|
||||
tas_priv->cur_conf = 0;
|
||||
|
||||
/* If calibrated data occurs error, dsp will still works with default
|
||||
* calibrated data inside algo.
|
||||
|
@ -62,7 +62,7 @@ static struct i2c_driver cs35l45_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "cs35l45",
|
||||
.of_match_table = cs35l45_of_match,
|
||||
.pm = &cs35l45_pm_ops,
|
||||
.pm = pm_ptr(&cs35l45_pm_ops),
|
||||
},
|
||||
.id_table = cs35l45_id_i2c,
|
||||
.probe = cs35l45_i2c_probe,
|
||||
|
@ -64,7 +64,7 @@ static struct spi_driver cs35l45_spi_driver = {
|
||||
.driver = {
|
||||
.name = "cs35l45",
|
||||
.of_match_table = cs35l45_of_match,
|
||||
.pm = &cs35l45_pm_ops,
|
||||
.pm = pm_ptr(&cs35l45_pm_ops),
|
||||
},
|
||||
.id_table = cs35l45_id_spi,
|
||||
.probe = cs35l45_spi_probe,
|
||||
|
@ -947,6 +947,8 @@ static int cs35l45_enter_hibernate(struct cs35l45_private *cs35l45)
|
||||
|
||||
cs35l45_setup_hibernate(cs35l45);
|
||||
|
||||
regmap_set_bits(cs35l45->regmap, CS35L45_IRQ1_MASK_2, CS35L45_DSP_VIRT2_MBOX_MASK);
|
||||
|
||||
// Don't wait for ACK since bus activity would wake the device
|
||||
regmap_write(cs35l45->regmap, CS35L45_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE);
|
||||
|
||||
@ -967,6 +969,8 @@ static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45)
|
||||
CSPL_MBOX_CMD_OUT_OF_HIBERNATE);
|
||||
if (!ret) {
|
||||
dev_dbg(cs35l45->dev, "Wake success at cycle: %d\n", j);
|
||||
regmap_clear_bits(cs35l45->regmap, CS35L45_IRQ1_MASK_2,
|
||||
CS35L45_DSP_VIRT2_MBOX_MASK);
|
||||
return 0;
|
||||
}
|
||||
usleep_range(100, 200);
|
||||
@ -982,7 +986,7 @@ static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)
|
||||
static int cs35l45_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
|
||||
|
||||
@ -999,7 +1003,7 @@ static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused cs35l45_runtime_resume(struct device *dev)
|
||||
static int cs35l45_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
@ -1026,6 +1030,46 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs35l45_sys_suspend(struct device *dev)
|
||||
{
|
||||
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg(cs35l45->dev, "System suspend, disabling IRQ\n");
|
||||
disable_irq(cs35l45->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l45_sys_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg(cs35l45->dev, "Late system suspend, reenabling IRQ\n");
|
||||
enable_irq(cs35l45->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l45_sys_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg(cs35l45->dev, "Early system resume, disabling IRQ\n");
|
||||
disable_irq(cs35l45->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l45_sys_resume(struct device *dev)
|
||||
{
|
||||
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg(cs35l45->dev, "System resume, reenabling IRQ\n");
|
||||
enable_irq(cs35l45->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
|
||||
{
|
||||
struct device_node *node = cs35l45->dev->of_node;
|
||||
@ -1466,10 +1510,12 @@ void cs35l45_remove(struct cs35l45_private *cs35l45)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs35l45_remove, SND_SOC_CS35L45);
|
||||
|
||||
const struct dev_pm_ops cs35l45_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(cs35l45_runtime_suspend, cs35l45_runtime_resume, NULL)
|
||||
EXPORT_GPL_DEV_PM_OPS(cs35l45_pm_ops) = {
|
||||
RUNTIME_PM_OPS(cs35l45_runtime_suspend, cs35l45_runtime_resume, NULL)
|
||||
|
||||
SYSTEM_SLEEP_PM_OPS(cs35l45_sys_suspend, cs35l45_sys_resume)
|
||||
NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l45_sys_suspend_noirq, cs35l45_sys_resume_noirq)
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(cs35l45_pm_ops, SND_SOC_CS35L45);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC CS35L45 driver");
|
||||
MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>");
|
||||
|
@ -237,7 +237,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool force_high)
|
||||
static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = priv->core;
|
||||
unsigned int val = 0x3 << CS42L43_HSBIAS_MODE_SHIFT;
|
||||
@ -247,16 +247,17 @@ static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool force_high)
|
||||
regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
|
||||
CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
|
||||
|
||||
if (!force_high && priv->bias_low)
|
||||
val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
|
||||
if (!type_detect) {
|
||||
if (priv->bias_low)
|
||||
val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
|
||||
|
||||
if (priv->bias_sense_ua) {
|
||||
regmap_update_bits(cs42l43->regmap,
|
||||
CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
|
||||
CS42L43_HSBIAS_SENSE_EN_MASK |
|
||||
CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
|
||||
CS42L43_HSBIAS_SENSE_EN_MASK |
|
||||
CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
|
||||
if (priv->bias_sense_ua)
|
||||
regmap_update_bits(cs42l43->regmap,
|
||||
CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
|
||||
CS42L43_HSBIAS_SENSE_EN_MASK |
|
||||
CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
|
||||
CS42L43_HSBIAS_SENSE_EN_MASK |
|
||||
CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
|
||||
}
|
||||
|
||||
regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
|
||||
|
@ -850,8 +850,9 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai)
|
||||
static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
|
||||
unsigned int jack_status)
|
||||
{
|
||||
if (hcp->jack && jack_status != hcp->jack_status) {
|
||||
snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
|
||||
if (jack_status != hcp->jack_status) {
|
||||
if (hcp->jack)
|
||||
snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
|
||||
hcp->jack_status = jack_status;
|
||||
}
|
||||
}
|
||||
@ -880,6 +881,13 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component,
|
||||
|
||||
if (hcp->hcd.ops->hook_plugged_cb) {
|
||||
hcp->jack = jack;
|
||||
|
||||
/*
|
||||
* Report the initial jack status which may have been provided
|
||||
* by the parent hdmi driver while the hpd hook was registered.
|
||||
*/
|
||||
snd_soc_jack_report(jack, hcp->jack_status, SND_JACK_LINEOUT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2189,11 +2189,11 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
|
||||
goto out;
|
||||
}
|
||||
|
||||
conf = &(tas_fmw->configs[cfg_no]);
|
||||
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
|
||||
if (cfg_info[rca_conf_no]->active_dev & (1 << i)) {
|
||||
if (tas_priv->tasdevice[i].cur_prog != prm_no
|
||||
|| tas_priv->force_fwload_status) {
|
||||
if (prm_no >= 0
|
||||
&& (tas_priv->tasdevice[i].cur_prog != prm_no
|
||||
|| tas_priv->force_fwload_status)) {
|
||||
tas_priv->tasdevice[i].cur_conf = -1;
|
||||
tas_priv->tasdevice[i].is_loading = true;
|
||||
prog_status++;
|
||||
@ -2228,7 +2228,8 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
|
||||
}
|
||||
|
||||
for (i = 0, status = 0; i < tas_priv->ndev; i++) {
|
||||
if (tas_priv->tasdevice[i].cur_conf != cfg_no
|
||||
if (cfg_no >= 0
|
||||
&& tas_priv->tasdevice[i].cur_conf != cfg_no
|
||||
&& (cfg_info[rca_conf_no]->active_dev & (1 << i))
|
||||
&& (tas_priv->tasdevice[i].is_loaderr == false)) {
|
||||
status++;
|
||||
@ -2238,6 +2239,7 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
|
||||
}
|
||||
|
||||
if (status) {
|
||||
conf = &(tas_fmw->configs[cfg_no]);
|
||||
status = 0;
|
||||
tasdevice_load_data(tas_priv, &(conf->dev_data));
|
||||
for (i = 0; i < tas_priv->ndev; i++) {
|
||||
@ -2281,7 +2283,7 @@ int tasdevice_prmg_load(void *context, int prm_no)
|
||||
}
|
||||
|
||||
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
|
||||
if (tas_priv->tasdevice[i].cur_prog != prm_no) {
|
||||
if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
|
||||
tas_priv->tasdevice[i].cur_conf = -1;
|
||||
tas_priv->tasdevice[i].is_loading = true;
|
||||
prog_status++;
|
||||
@ -2326,7 +2328,7 @@ int tasdevice_prmg_calibdata_load(void *context, int prm_no)
|
||||
}
|
||||
|
||||
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
|
||||
if (tas_priv->tasdevice[i].cur_prog != prm_no) {
|
||||
if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
|
||||
tas_priv->tasdevice[i].cur_conf = -1;
|
||||
tas_priv->tasdevice[i].is_loading = true;
|
||||
prog_status++;
|
||||
|
@ -714,6 +714,9 @@ static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
unsigned int ofs = sai->soc_data->reg_offset;
|
||||
|
||||
/* Clear xMR to avoid channel swap with mclk_with_tere enabled case */
|
||||
regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0);
|
||||
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
|
||||
FSL_SAI_CR3_TRCE_MASK, 0);
|
||||
|
||||
|
@ -83,6 +83,7 @@ enum {
|
||||
#define BYT_RT5640_HSMIC2_ON_IN1 BIT(27)
|
||||
#define BYT_RT5640_JD_HP_ELITEP_1000G2 BIT(28)
|
||||
#define BYT_RT5640_USE_AMCR0F28 BIT(29)
|
||||
#define BYT_RT5640_SWAPPED_SPEAKERS BIT(30)
|
||||
|
||||
#define BYTCR_INPUT_DEFAULTS \
|
||||
(BYT_RT5640_IN3_MAP | \
|
||||
@ -157,6 +158,8 @@ static void log_quirks(struct device *dev)
|
||||
dev_info(dev, "quirk MONO_SPEAKER enabled\n");
|
||||
if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)
|
||||
dev_info(dev, "quirk NO_SPEAKERS enabled\n");
|
||||
if (byt_rt5640_quirk & BYT_RT5640_SWAPPED_SPEAKERS)
|
||||
dev_info(dev, "quirk SWAPPED_SPEAKERS enabled\n");
|
||||
if (byt_rt5640_quirk & BYT_RT5640_LINEOUT)
|
||||
dev_info(dev, "quirk LINEOUT enabled\n");
|
||||
if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)
|
||||
@ -894,6 +897,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
||||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{
|
||||
/* Medion Lifetab S10346 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
|
||||
/* Above strings are much too generic, also match on BIOS date */
|
||||
DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
|
||||
},
|
||||
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
|
||||
BYT_RT5640_SWAPPED_SPEAKERS |
|
||||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{ /* Mele PCG03 Mini PC */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"),
|
||||
@ -1619,11 +1635,11 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
||||
const char *platform_name;
|
||||
struct acpi_device *adev;
|
||||
struct device *codec_dev;
|
||||
const char *cfg_spk;
|
||||
bool sof_parent;
|
||||
int ret_val = 0;
|
||||
int dai_index = 0;
|
||||
int i, cfg_spk;
|
||||
int aif;
|
||||
int i, aif;
|
||||
|
||||
is_bytcr = false;
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
@ -1783,13 +1799,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) {
|
||||
cfg_spk = 0;
|
||||
cfg_spk = "0";
|
||||
spk_type = "none";
|
||||
} else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
|
||||
cfg_spk = 1;
|
||||
cfg_spk = "1";
|
||||
spk_type = "mono";
|
||||
} else if (byt_rt5640_quirk & BYT_RT5640_SWAPPED_SPEAKERS) {
|
||||
cfg_spk = "swapped";
|
||||
spk_type = "swapped";
|
||||
} else {
|
||||
cfg_spk = 2;
|
||||
cfg_spk = "2";
|
||||
spk_type = "stereo";
|
||||
}
|
||||
|
||||
@ -1804,7 +1823,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
||||
headset2_string = " cfg-hs2:in1";
|
||||
|
||||
snprintf(byt_rt5640_components, sizeof(byt_rt5640_components),
|
||||
"cfg-spk:%d cfg-mic:%s aif:%d%s%s", cfg_spk,
|
||||
"cfg-spk:%s cfg-mic:%s aif:%d%s%s", cfg_spk,
|
||||
map_name[BYT_RT5640_MAP(byt_rt5640_quirk)], aif,
|
||||
lineout_string, headset2_string);
|
||||
byt_rt5640_card.components = byt_rt5640_components;
|
||||
|
@ -306,13 +306,13 @@ static const struct snd_soc_acpi_adr_device cs35l56_1_adr[] = {
|
||||
.adr = 0x00013701FA355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_r_endpoint,
|
||||
.name_prefix = "cs35l56-8"
|
||||
.name_prefix = "AMP8"
|
||||
},
|
||||
{
|
||||
.adr = 0x00013601FA355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_3_endpoint,
|
||||
.name_prefix = "cs35l56-7"
|
||||
.name_prefix = "AMP7"
|
||||
}
|
||||
};
|
||||
|
||||
@ -321,13 +321,13 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_adr[] = {
|
||||
.adr = 0x00023301FA355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_l_endpoint,
|
||||
.name_prefix = "cs35l56-1"
|
||||
.name_prefix = "AMP1"
|
||||
},
|
||||
{
|
||||
.adr = 0x00023201FA355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_2_endpoint,
|
||||
.name_prefix = "cs35l56-2"
|
||||
.name_prefix = "AMP2"
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -597,9 +597,6 @@ static struct snd_sof_dsp_ops sof_mt8186_ops = {
|
||||
|
||||
static struct snd_sof_of_mach sof_mt8186_machs[] = {
|
||||
{
|
||||
.compatible = "google,steelix",
|
||||
.sof_tplg_filename = "sof-mt8186-google-steelix.tplg"
|
||||
}, {
|
||||
.compatible = "mediatek,mt8186",
|
||||
.sof_tplg_filename = "sof-mt8186.tplg",
|
||||
},
|
||||
|
@ -1387,7 +1387,7 @@ static int snd_usb_motu_microbookii_boot_quirk(struct usb_device *dev)
|
||||
|
||||
static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
|
||||
{
|
||||
msleep(2000);
|
||||
msleep(4000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1630,7 +1630,7 @@ int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
|
||||
unsigned int id)
|
||||
{
|
||||
switch (id) {
|
||||
case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
|
||||
case USB_ID(0x07fd, 0x0008): /* MOTU M Series, 1st hardware version */
|
||||
return snd_usb_motu_m_series_boot_quirk(dev);
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ static void find_controls(void)
|
||||
err = snd_ctl_elem_info(card_data->handle,
|
||||
ctl_data->info);
|
||||
if (err < 0) {
|
||||
ksft_print_msg("%s getting info for %d\n",
|
||||
ksft_print_msg("%s getting info for %s\n",
|
||||
snd_strerror(err),
|
||||
ctl_data->name);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user