Merge tag 'sound-6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"This became a bit larger than wished for, often seen as a bump at the
middle, but almost all changes are small device-specific fixes, so the
risk must be pretty low.
- SoundWire fix for missing symbol export
- Fixes for device-tree bindings
- A fix for OOB access in USB-audio, spotted by fuzzer
- Quirks for HD-audio, SoundWire, AMD ACP
- A series of ASoC tlv320 and wsa codec fixes
- Other misc fixes in PCM OSS error-handling, Cirrus scodec test,
ASoC ops endianess, davinci, simple-card, and tegra"
* tag 'sound-6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (33 commits)
ALSA: hda/tas2781: Add newly-released HP laptop
ASoC: rt5640: Fix duplicate clock properties in DT binding
ALSA: hda/realtek: Add quirk for HP Pavilion x360 to enable mute LED
ASoC: tlv320adcx140: fix word length
ASoC: tlv320adcx140: Propagate error codes during probe
ASoC: tlv320adcx140: fix null pointer
ASoC: tlv320adcx140: invert DRE_ENABLE
ASoC: sdw_utils: cs42l43: Enable Headphone pin for LINEOUT jack type
ASoC: sdw_utils: Call init callbacks on the correct codec DAI
soundwire: Add missing EXPORT for sdw_slave_type
ALSA: usb-audio: Prevent excessive number of frames
ALSA: hda/cirrus_scodec_test: Fix test suite name
ALSA: hda/cirrus_scodec_test: Fix incorrect setup of gpiochip
ALSA: hda/realtek: Add quirk for Asus Zephyrus G14 2025 using CS35L56, fix speakers
ASoC: amd: yc: Fix microphone on ASUS M6500RE
ASoC: tegra: Revert fix for uninitialized flat cache warning in tegra210_ahub
ASoC: dt-bindings: rockchip-spdif: Allow "port" node
ASoC: dt-bindings: realtek,rt5640: Allow 7 for realtek,jack-detect-source
ASoC: dt-bindings: realtek,rt5640: Add missing properties/node
ASoC: dt-bindings: realtek,rt5640: Document port node
...
This commit is contained in:
@@ -49,6 +49,10 @@ properties:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: Headphone detect interrupt
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
@@ -47,6 +47,12 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: mclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: The CODEC's interrupt output.
|
||||
@@ -98,6 +104,7 @@ properties:
|
||||
- 4 # Use GPIO2 for jack-detect
|
||||
- 5 # Use GPIO3 for jack-detect
|
||||
- 6 # Use GPIO4 for jack-detect
|
||||
- 7 # Use HDA header for jack-detect
|
||||
|
||||
realtek,jack-detect-not-inverted:
|
||||
description:
|
||||
@@ -121,6 +128,10 @@ properties:
|
||||
- 2 # Scale current by 1.0
|
||||
- 3 # Scale current by 1.5
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -70,6 +70,9 @@ properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -23,6 +23,7 @@ const struct device_type sdw_slave_type = {
|
||||
.release = sdw_slave_release,
|
||||
.uevent = sdw_slave_uevent,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sdw_slave_type);
|
||||
|
||||
int sdw_slave_add(struct sdw_bus *bus,
|
||||
struct sdw_slave_id *id, struct fwnode_handle *fwnode)
|
||||
|
||||
@@ -1402,7 +1402,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s
|
||||
#define snd_pcm_lib_mmap_iomem NULL
|
||||
#endif
|
||||
|
||||
void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);
|
||||
int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);
|
||||
|
||||
/**
|
||||
* snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer
|
||||
|
||||
@@ -1074,7 +1074,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
||||
runtime->oss.params = 0;
|
||||
runtime->oss.prepare = 1;
|
||||
runtime->oss.buffer_used = 0;
|
||||
snd_pcm_runtime_buffer_set_silence(runtime);
|
||||
err = snd_pcm_runtime_buffer_set_silence(runtime);
|
||||
if (err < 0)
|
||||
goto failure;
|
||||
|
||||
runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size);
|
||||
|
||||
|
||||
@@ -730,13 +730,18 @@ static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime)
|
||||
}
|
||||
|
||||
/* fill the PCM buffer with the current silence format; called from pcm_oss.c */
|
||||
void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
|
||||
int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
snd_pcm_buffer_access_lock(runtime);
|
||||
int err;
|
||||
|
||||
err = snd_pcm_buffer_access_lock(runtime);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (runtime->dma_area)
|
||||
snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
|
||||
bytes_to_samples(runtime, runtime->dma_bytes));
|
||||
snd_pcm_buffer_access_unlock(runtime);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_runtime_buffer_set_silence);
|
||||
|
||||
|
||||
@@ -6613,6 +6613,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8a2e, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a30, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a31, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a34, "HP Pavilion x360 2-in-1 Laptop 14-ek0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a4f, "HP Victus 15-fa0xxx (MB 8A4F)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a6e, "HP EDNA 360", ALC287_FIXUP_CS35L41_I2C_4),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a74, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
|
||||
@@ -6817,6 +6818,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8f42, "HP ZBook 8 G2a 14W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8f57, "HP Trekker G7JC", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8f62, "HP ZBook 8 G2a 16W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x1043, 0x1024, "ASUS Zephyrus G14 2025", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1032, "ASUS VivoBook X513EA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1034, "ASUS GU605C", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
|
||||
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
||||
|
||||
@@ -103,6 +103,7 @@ static int cirrus_scodec_test_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
/* GPIO core modifies our struct gpio_chip so use a copy */
|
||||
gpio_priv->chip = cirrus_scodec_test_gpio_chip;
|
||||
gpio_priv->chip.parent = &pdev->dev;
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &gpio_priv->chip, gpio_priv);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret, "Failed to add gpiochip\n");
|
||||
@@ -319,7 +320,7 @@ static struct kunit_case cirrus_scodec_test_cases[] = {
|
||||
};
|
||||
|
||||
static struct kunit_suite cirrus_scodec_test_suite = {
|
||||
.name = "snd-hda-scodec-cs35l56-test",
|
||||
.name = "snd-hda-cirrus-scodec-test",
|
||||
.init = cirrus_scodec_test_case_init,
|
||||
.test_cases = cirrus_scodec_test_cases,
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// TAS2781 HDA I2C driver
|
||||
//
|
||||
// Copyright 2023 - 2025 Texas Instruments, Inc.
|
||||
// Copyright 2023 - 2026 Texas Instruments, Inc.
|
||||
//
|
||||
// Author: Shenghao Ding <shenghao-ding@ti.com>
|
||||
// Current maintainer: Baojun Xu <baojun.xu@ti.com>
|
||||
@@ -60,6 +60,7 @@ struct tas2781_hda_i2c_priv {
|
||||
int (*save_calibration)(struct tas2781_hda *h);
|
||||
|
||||
int hda_chip_id;
|
||||
bool skip_calibration;
|
||||
};
|
||||
|
||||
static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
|
||||
@@ -491,7 +492,8 @@ static void tasdevice_dspfw_init(void *context)
|
||||
/* If calibrated data occurs error, dsp will still works with default
|
||||
* calibrated data inside algo.
|
||||
*/
|
||||
hda_priv->save_calibration(tas_hda);
|
||||
if (!hda_priv->skip_calibration)
|
||||
hda_priv->save_calibration(tas_hda);
|
||||
}
|
||||
|
||||
static void tasdev_fw_ready(const struct firmware *fmw, void *context)
|
||||
@@ -548,6 +550,7 @@ static int tas2781_hda_bind(struct device *dev, struct device *master,
|
||||
void *master_data)
|
||||
{
|
||||
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
|
||||
struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv;
|
||||
struct hda_component_parent *parent = master_data;
|
||||
struct hda_component *comp;
|
||||
struct hda_codec *codec;
|
||||
@@ -568,11 +571,22 @@ static int tas2781_hda_bind(struct device *dev, struct device *master,
|
||||
case 0x1028:
|
||||
tas_hda->catlog_id = DELL;
|
||||
break;
|
||||
case 0x103C:
|
||||
tas_hda->catlog_id = HP;
|
||||
break;
|
||||
default:
|
||||
tas_hda->catlog_id = LENOVO;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using ASUS ROG Xbox Ally X (RC73XA) UEFI calibration data
|
||||
* causes audio dropouts during playback, use fallback data
|
||||
* from DSP firmware as a workaround.
|
||||
*/
|
||||
if (codec->core.subsystem_id == 0x10431384)
|
||||
hda_priv->skip_calibration = true;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
comp->dev = dev;
|
||||
|
||||
@@ -416,6 +416,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M6500RE"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "tlv320adcx140.h"
|
||||
|
||||
struct adcx140_priv {
|
||||
struct snd_soc_component *component;
|
||||
struct regulator *supply_areg;
|
||||
struct gpio_desc *gpio_reset;
|
||||
struct regmap *regmap;
|
||||
@@ -338,7 +337,7 @@ static const struct snd_kcontrol_new adcx140_dapm_ch4_dre_en_switch =
|
||||
SOC_DAPM_SINGLE("Switch", ADCX140_CH4_CFG0, 0, 1, 0);
|
||||
|
||||
static const struct snd_kcontrol_new adcx140_dapm_dre_en_switch =
|
||||
SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 0);
|
||||
SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 1);
|
||||
|
||||
/* Output Mixer */
|
||||
static const struct snd_kcontrol_new adcx140_output_mixer_controls[] = {
|
||||
@@ -699,7 +698,6 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
|
||||
{
|
||||
int pwr_ctrl = 0;
|
||||
int ret = 0;
|
||||
struct snd_soc_component *component = adcx140->component;
|
||||
|
||||
if (power_state)
|
||||
pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ;
|
||||
@@ -711,7 +709,7 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
|
||||
ret = regmap_write(adcx140->regmap, ADCX140_PHASE_CALIB,
|
||||
adcx140->phase_calib_on ? 0x00 : 0x40);
|
||||
if (ret)
|
||||
dev_err(component->dev, "%s: register write error %d\n",
|
||||
dev_err(adcx140->dev, "%s: register write error %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
@@ -727,7 +725,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
|
||||
struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
|
||||
u8 data = 0;
|
||||
|
||||
switch (params_width(params)) {
|
||||
switch (params_physical_width(params)) {
|
||||
case 16:
|
||||
data = ADCX140_16_BIT_WORD;
|
||||
break;
|
||||
@@ -742,7 +740,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s: Unsupported width %d\n",
|
||||
__func__, params_width(params));
|
||||
__func__, params_physical_width(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1156,6 +1154,9 @@ static int adcx140_i2c_probe(struct i2c_client *i2c)
|
||||
adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev,
|
||||
"reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(adcx140->gpio_reset))
|
||||
return dev_err_probe(&i2c->dev, PTR_ERR(adcx140->gpio_reset),
|
||||
"Failed to get Reset GPIO\n");
|
||||
if (!adcx140->gpio_reset)
|
||||
dev_info(&i2c->dev, "Reset GPIO not defined\n");
|
||||
|
||||
adcx140->supply_areg = devm_regulator_get_optional(adcx140->dev,
|
||||
|
||||
@@ -678,6 +678,7 @@ struct wsa881x_priv {
|
||||
*/
|
||||
unsigned int sd_n_val;
|
||||
int active_ports;
|
||||
bool hw_init;
|
||||
bool port_prepared[WSA881X_MAX_SWR_PORTS];
|
||||
bool port_enable[WSA881X_MAX_SWR_PORTS];
|
||||
};
|
||||
@@ -687,6 +688,9 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x)
|
||||
struct regmap *rm = wsa881x->regmap;
|
||||
unsigned int val = 0;
|
||||
|
||||
if (wsa881x->hw_init)
|
||||
return;
|
||||
|
||||
regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
|
||||
ARRAY_SIZE(wsa881x_rev_2_0));
|
||||
|
||||
@@ -724,6 +728,8 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x)
|
||||
regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A);
|
||||
regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2);
|
||||
regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05);
|
||||
|
||||
wsa881x->hw_init = true;
|
||||
}
|
||||
|
||||
static int wsa881x_component_probe(struct snd_soc_component *comp)
|
||||
@@ -1067,6 +1073,9 @@ static int wsa881x_update_status(struct sdw_slave *slave,
|
||||
{
|
||||
struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (status == SDW_SLAVE_UNATTACHED)
|
||||
wsa881x->hw_init = false;
|
||||
|
||||
if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
|
||||
wsa881x_init(wsa881x);
|
||||
|
||||
|
||||
@@ -475,6 +475,7 @@ struct wsa883x_priv {
|
||||
int active_ports;
|
||||
int dev_mode;
|
||||
int comp_offset;
|
||||
bool hw_init;
|
||||
/*
|
||||
* Protects temperature reading code (related to speaker protection) and
|
||||
* fields: temperature and pa_on.
|
||||
@@ -1043,6 +1044,9 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
|
||||
struct regmap *regmap = wsa883x->regmap;
|
||||
int variant, version, ret;
|
||||
|
||||
if (wsa883x->hw_init)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1054,22 +1058,23 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
|
||||
|
||||
switch (variant) {
|
||||
case WSA8830:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n",
|
||||
version);
|
||||
break;
|
||||
case WSA8835:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n",
|
||||
version);
|
||||
break;
|
||||
case WSA8832:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n",
|
||||
version);
|
||||
break;
|
||||
case WSA8835_V2:
|
||||
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n",
|
||||
version);
|
||||
dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n",
|
||||
version);
|
||||
break;
|
||||
default:
|
||||
dev_warn(wsa883x->dev, "unknown variant: %d\n", variant);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1085,6 +1090,8 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
|
||||
wsa883x->comp_offset);
|
||||
}
|
||||
|
||||
wsa883x->hw_init = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1093,6 +1100,9 @@ static int wsa883x_update_status(struct sdw_slave *slave,
|
||||
{
|
||||
struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (status == SDW_SLAVE_UNATTACHED)
|
||||
wsa883x->hw_init = false;
|
||||
|
||||
if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
|
||||
return wsa883x_init(wsa883x);
|
||||
|
||||
|
||||
@@ -1534,7 +1534,7 @@ static void wsa884x_init(struct wsa884x_priv *wsa884x)
|
||||
|
||||
wsa884x_set_gain_parameters(wsa884x);
|
||||
|
||||
wsa884x->hw_init = false;
|
||||
wsa884x->hw_init = true;
|
||||
}
|
||||
|
||||
static int wsa884x_update_status(struct sdw_slave *slave,
|
||||
@@ -2109,7 +2109,6 @@ static int wsa884x_probe(struct sdw_slave *pdev,
|
||||
|
||||
/* Start in cache-only until device is enumerated */
|
||||
regcache_cache_only(wsa884x->regmap, true);
|
||||
wsa884x->hw_init = true;
|
||||
|
||||
if (IS_REACHABLE(CONFIG_HWMON)) {
|
||||
struct device *hwmon;
|
||||
|
||||
@@ -1179,9 +1179,9 @@ void graph_util_parse_link_direction(struct device_node *np,
|
||||
bool is_playback_only = of_property_read_bool(np, "playback-only");
|
||||
bool is_capture_only = of_property_read_bool(np, "capture-only");
|
||||
|
||||
if (playback_only)
|
||||
if (np && playback_only)
|
||||
*playback_only = is_playback_only;
|
||||
if (capture_only)
|
||||
if (np && capture_only)
|
||||
*capture_only = is_capture_only;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);
|
||||
|
||||
@@ -764,6 +764,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
||||
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
|
||||
},
|
||||
/* Pantherlake devices*/
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0DD6")
|
||||
},
|
||||
.driver_data = (void *)(SOC_SDW_SIDECAR_AMPS),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
|
||||
@@ -44,7 +44,7 @@ static const struct snd_soc_dapm_route cs42l43_dmic_map[] = {
|
||||
static struct snd_soc_jack_pin soc_jack_pins[] = {
|
||||
{
|
||||
.pin = "Headphone",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
.mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
|
||||
},
|
||||
{
|
||||
.pin = "Headset Mic",
|
||||
|
||||
@@ -841,6 +841,19 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr)
|
||||
}
|
||||
EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, "SND_SOC_SDW_UTILS");
|
||||
|
||||
static struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_sdw_id(const struct sdw_slave_id *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
|
||||
if (id->part_id == codec_info_list[i].part_id &&
|
||||
(!codec_info_list[i].version_id ||
|
||||
id->sdw_version == codec_info_list[i].version_id))
|
||||
return &codec_info_list[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id)
|
||||
{
|
||||
int i;
|
||||
@@ -873,22 +886,46 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, i
|
||||
}
|
||||
EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, "SND_SOC_SDW_UTILS");
|
||||
|
||||
static int asoc_sdw_find_codec_info_dai_index(const struct asoc_sdw_codec_info *codec_info,
|
||||
const char *dai_name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < codec_info->dai_num; i++) {
|
||||
if (!strcmp(codec_info->dais[i].dai_name, dai_name))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
|
||||
struct asoc_sdw_codec_info *codec_info;
|
||||
struct snd_soc_dai *dai;
|
||||
struct sdw_slave *sdw_peripheral;
|
||||
const char *spk_components="";
|
||||
int dai_index;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for_each_rtd_codec_dais(rtd, i, dai) {
|
||||
codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index);
|
||||
if (is_sdw_slave(dai->component->dev))
|
||||
sdw_peripheral = dev_to_sdw_dev(dai->component->dev);
|
||||
else if (dai->component->dev->parent && is_sdw_slave(dai->component->dev->parent))
|
||||
sdw_peripheral = dev_to_sdw_dev(dai->component->dev->parent);
|
||||
else
|
||||
continue;
|
||||
|
||||
codec_info = asoc_sdw_find_codec_info_sdw_id(&sdw_peripheral->id);
|
||||
if (!codec_info)
|
||||
return -EINVAL;
|
||||
|
||||
dai_index = asoc_sdw_find_codec_info_dai_index(codec_info, dai->name);
|
||||
WARN_ON(dai_index < 0);
|
||||
|
||||
/*
|
||||
* A codec dai can be connected to different dai links for capture and playback,
|
||||
* but we only need to call the rtd_init function once.
|
||||
@@ -898,6 +935,10 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
if (codec_info->dais[dai_index].rtd_init_done)
|
||||
continue;
|
||||
|
||||
dev_dbg(card->dev, "%#x/%s initializing for %s/%s\n",
|
||||
codec_info->part_id, codec_info->dais[dai_index].dai_name,
|
||||
dai->component->name, dai->name);
|
||||
|
||||
/*
|
||||
* Add card controls and dapm widgets for the first codec dai.
|
||||
* The controls and widgets will be used for all codec dais.
|
||||
|
||||
@@ -543,11 +543,11 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
|
||||
ucontrol->value.bytes.data[0] &= ~params->mask;
|
||||
break;
|
||||
case 2:
|
||||
((u16 *)(&ucontrol->value.bytes.data))[0]
|
||||
((__be16 *)(&ucontrol->value.bytes.data))[0]
|
||||
&= cpu_to_be16(~params->mask);
|
||||
break;
|
||||
case 4:
|
||||
((u32 *)(&ucontrol->value.bytes.data))[0]
|
||||
((__be32 *)(&ucontrol->value.bytes.data))[0]
|
||||
&= cpu_to_be32(~params->mask);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -2077,7 +2077,7 @@ static const struct regmap_config tegra210_ahub_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = TEGRA210_MAX_REGISTER_ADDR,
|
||||
.cache_type = REGCACHE_FLAT_S,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config tegra186_ahub_regmap_config = {
|
||||
@@ -2085,7 +2085,7 @@ static const struct regmap_config tegra186_ahub_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = TEGRA186_MAX_REGISTER_ADDR,
|
||||
.cache_type = REGCACHE_FLAT_S,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config tegra264_ahub_regmap_config = {
|
||||
@@ -2094,7 +2094,7 @@ static const struct regmap_config tegra264_ahub_regmap_config = {
|
||||
.reg_stride = 4,
|
||||
.writeable_reg = tegra264_ahub_wr_reg,
|
||||
.max_register = TEGRA264_MAX_REGISTER_ADDR,
|
||||
.cache_type = REGCACHE_FLAT_S,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct tegra_ahub_soc_data soc_data_tegra210 = {
|
||||
|
||||
@@ -194,27 +194,32 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
|
||||
dai->cpus->of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
|
||||
if (!dai->cpus->of_node)
|
||||
return -EINVAL;
|
||||
if (!dai->cpus->of_node) {
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
dai->platforms->of_node = dai->cpus->of_node;
|
||||
|
||||
evm_soc_card.dev = &pdev->dev;
|
||||
ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_put;
|
||||
|
||||
mclk = devm_clk_get(&pdev->dev, "mclk");
|
||||
if (PTR_ERR(mclk) == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
ret = -EPROBE_DEFER;
|
||||
goto err_put;
|
||||
} else if (IS_ERR(mclk)) {
|
||||
dev_dbg(&pdev->dev, "mclk not found.\n");
|
||||
mclk = NULL;
|
||||
}
|
||||
|
||||
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
if (!drvdata) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
drvdata->mclk = mclk;
|
||||
|
||||
@@ -224,7 +229,8 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
||||
if (!drvdata->mclk) {
|
||||
dev_err(&pdev->dev,
|
||||
"No clock or clock rate defined.\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
drvdata->sysclk = clk_get_rate(drvdata->mclk);
|
||||
} else if (drvdata->mclk) {
|
||||
@@ -240,8 +246,25 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
||||
snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_put:
|
||||
dai->platforms->of_node = NULL;
|
||||
|
||||
if (dai->cpus->of_node) {
|
||||
of_node_put(dai->cpus->of_node);
|
||||
dai->cpus->of_node = NULL;
|
||||
}
|
||||
|
||||
if (dai->codecs->of_node) {
|
||||
of_node_put(dai->codecs->of_node);
|
||||
dai->codecs->of_node = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1553,7 +1553,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
|
||||
|
||||
for (i = 0; i < ctx->packets; i++) {
|
||||
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail);
|
||||
if (counts < 0)
|
||||
if (counts < 0 || frames + counts >= ep->max_urb_frames)
|
||||
break;
|
||||
/* set up descriptor */
|
||||
urb->iso_frame_desc[i].offset = frames * stride;
|
||||
|
||||
Reference in New Issue
Block a user