Skip to content

Commit bb2ea74

Browse files
committed
Merge tag 'sound-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "Still a bit higher amount than wished, but nothing looks really scary, and all changes are about nice and smooth device-specific fixes. - HD-audio quirks, one revert for a regression and another oneliner - AMD ACP quirks - Fixes for SDCA interrupt handling - A few Intel SOF, avs and NVL fixes - Fixes for TAS2552 DT, NAU8325, and STM32" * tag 'sound-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ASoC: amd: acp: update DMI quirk and add ACP DMIC for Lenovo platforms ASoC: SDCA: Unregister IRQ handlers on module remove ASoC: SDCA: mask Function_Status value ASoC: SDCA: Fix overwritten var within for loop ASoC: stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J ASoC: SOF: Intel: hda: modify period size constraints for ACE4 ALSA: hda/intel: enforce stricter period-size alignment for Intel NVL ASoC: nau8325: Add software reset during probe Revert "ALSA: hda/realtek: Add quirk for Gigabyte Technology to fix headphone" ASoC: Intel: avs: Fix memory leak in avs_register_i2s_test_boards() ASoC: SOF: Intel: fix iteration in is_endpoint_present() ASoC: SOF: Intel: Fix endpoint index if endpoints are missing ASoC: SDCA: Fix errors in IRQ cleanup ASoC: amd: acp: add Lenovo P16s G5 AMD quirk for legacy SDW machine ASoC: dt-bindings: ti,tas2552: Add sound-dai-cells ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14IAH10
2 parents 4e1538b + 00afb18 commit bb2ea74

13 files changed

Lines changed: 165 additions & 38 deletions

File tree

Documentation/devicetree/bindings/sound/ti,tas2552.yaml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ maintainers:
1212
- Baojun Xu <baojun.xu@ti.com>
1313

1414
description: >
15-
The TAS2552 can receive its reference clock via MCLK, BCLK, IVCLKIN pin or
16-
use the internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL,
15+
The TAS2552 can receive its reference clock via MCLK, BCLK, IVCLKIN pin or
16+
use the internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL,
1717
the PDM reference clock is also selectable: PLL, IVCLKIN, BCLK or MCLK.
1818
1919
For system integration the dt-bindings/sound/tas2552.h header file provides
@@ -34,14 +34,20 @@ properties:
3434
maxItems: 1
3535
description: gpio pin to enable/disable the device
3636

37+
'#sound-dai-cells':
38+
const: 0
39+
3740
required:
3841
- compatible
3942
- reg
4043
- vbat-supply
4144
- iovdd-supply
4245
- avdd-supply
4346

44-
additionalProperties: false
47+
allOf:
48+
- $ref: dai-common.yaml#
49+
50+
unevaluatedProperties: false
4551

4652
examples:
4753
- |
@@ -54,6 +60,7 @@ examples:
5460
audio-codec@41 {
5561
compatible = "ti,tas2552";
5662
reg = <0x41>;
63+
#sound-dai-cells = <0>;
5764
vbat-supply = <&reg_vbat>;
5865
iovdd-supply = <&reg_iovdd>;
5966
avdd-supply = <&reg_avdd>;

include/sound/sdca_interrupts.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ struct sdca_interrupt_info {
6969
int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *interrupt_info,
7070
int sdca_irq, const char *name, irq_handler_t handler,
7171
void *data);
72+
void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *interrupt_info,
73+
int sdca_irq, const char *name, void *data);
7274
int sdca_irq_data_populate(struct device *dev, struct regmap *function_regmap,
7375
struct snd_soc_component *component,
7476
struct sdca_function_data *function,
@@ -81,6 +83,9 @@ int sdca_irq_populate_early(struct device *dev, struct regmap *function_regmap,
8183
int sdca_irq_populate(struct sdca_function_data *function,
8284
struct snd_soc_component *component,
8385
struct sdca_interrupt_info *info);
86+
void sdca_irq_cleanup(struct device *dev,
87+
struct sdca_function_data *function,
88+
struct sdca_interrupt_info *info);
8489
struct sdca_interrupt_info *sdca_irq_allocate(struct device *dev,
8590
struct regmap *regmap, int irq);
8691

sound/hda/codecs/realtek/alc269.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7680,6 +7680,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
76807680
SND_PCI_QUIRK(0x17aa, 0x38fd, "ThinkBook plus Gen5 Hybrid", ALC287_FIXUP_TAS2781_I2C),
76817681
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
76827682
SND_PCI_QUIRK(0x17aa, 0x390d, "Lenovo Yoga Pro 7 14ASP10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
7683+
SND_PCI_QUIRK(0x17aa, 0x3911, "Lenovo Yoga Pro 7 14IAH10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
76837684
SND_PCI_QUIRK(0x17aa, 0x3913, "Lenovo 145", ALC236_FIXUP_LENOVO_INV_DMIC),
76847685
SND_PCI_QUIRK(0x17aa, 0x391a, "Lenovo Yoga Slim 7 14AKP10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
76857686
SND_PCI_QUIRK(0x17aa, 0x391f, "Yoga S990-16 pro Quad YC Quad", ALC287_FIXUP_TXNW2781_I2C),

sound/hda/codecs/realtek/alc662.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,6 @@ enum {
313313
ALC897_FIXUP_HEADSET_MIC_PIN2,
314314
ALC897_FIXUP_UNIS_H3C_X500S,
315315
ALC897_FIXUP_HEADSET_MIC_PIN3,
316-
ALC897_FIXUP_H610M_HP_PIN,
317316
};
318317

319318
static const struct hda_fixup alc662_fixups[] = {
@@ -767,13 +766,6 @@ static const struct hda_fixup alc662_fixups[] = {
767766
{ }
768767
},
769768
},
770-
[ALC897_FIXUP_H610M_HP_PIN] = {
771-
.type = HDA_FIXUP_PINS,
772-
.v.pins = (const struct hda_pintbl[]) {
773-
{ 0x19, 0x0321403f }, /* HP out */
774-
{ }
775-
},
776-
},
777769
};
778770

779771
static const struct hda_quirk alc662_fixup_tbl[] = {
@@ -823,7 +815,6 @@ static const struct hda_quirk alc662_fixup_tbl[] = {
823815
SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
824816
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
825817
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
826-
SND_PCI_QUIRK(0x1458, 0xa194, "H610M H V2 DDR4", ALC897_FIXUP_H610M_HP_PIN),
827818
SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
828819
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
829820
SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),

sound/hda/controllers/intel.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ enum {
295295
#define AZX_DCAPS_INTEL_LNL \
296296
(AZX_DCAPS_INTEL_SKYLAKE | AZX_DCAPS_PIO_COMMANDS)
297297

298+
#define AZX_DCAPS_INTEL_NVL \
299+
(AZX_DCAPS_INTEL_LNL & ~AZX_DCAPS_NO_ALIGN_BUFSIZE)
300+
298301
/* quirks for ATI SB / AMD Hudson */
299302
#define AZX_DCAPS_PRESET_ATI_SB \
300303
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\
@@ -2565,8 +2568,8 @@ static const struct pci_device_id azx_ids[] = {
25652568
/* Wildcat Lake */
25662569
{ PCI_DEVICE_DATA(INTEL, HDA_WCL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_LNL) },
25672570
/* Nova Lake */
2568-
{ PCI_DEVICE_DATA(INTEL, HDA_NVL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_LNL) },
2569-
{ PCI_DEVICE_DATA(INTEL, HDA_NVL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_LNL) },
2571+
{ PCI_DEVICE_DATA(INTEL, HDA_NVL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_NVL) },
2572+
{ PCI_DEVICE_DATA(INTEL, HDA_NVL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_NVL) },
25702573
/* Apollolake (Broxton-P) */
25712574
{ PCI_DEVICE_DATA(INTEL, HDA_APL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
25722575
/* Gemini-Lake */

sound/soc/amd/acp/acp-sdw-legacy-mach.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,33 @@ static const struct dmi_system_id soc_sdw_quirk_table[] = {
9999
.callback = soc_sdw_quirk_cb,
100100
.matches = {
101101
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
102-
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YW"),
102+
DMI_MATCH(DMI_PRODUCT_SKU, "21YW"),
103103
},
104-
.driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
104+
.driver_data = (void *)((ASOC_SDW_CODEC_SPKR) | (ASOC_SDW_ACP_DMIC)),
105105
},
106106
{
107107
.callback = soc_sdw_quirk_cb,
108108
.matches = {
109109
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
110-
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YX"),
110+
DMI_MATCH(DMI_PRODUCT_SKU, "21YX"),
111111
},
112-
.driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
112+
.driver_data = (void *)((ASOC_SDW_CODEC_SPKR) | (ASOC_SDW_ACP_DMIC)),
113+
},
114+
{
115+
.callback = soc_sdw_quirk_cb,
116+
.matches = { /* Lenovo P16s G5 AMD */
117+
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
118+
DMI_MATCH(DMI_PRODUCT_SKU, "21XG"),
119+
},
120+
.driver_data = (void *)(ASOC_SDW_ACP_DMIC),
121+
},
122+
{
123+
.callback = soc_sdw_quirk_cb,
124+
.matches = { /* Lenovo P16s G5 AMD */
125+
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
126+
DMI_MATCH(DMI_PRODUCT_SKU, "21XH"),
127+
},
128+
.driver_data = (void *)(ASOC_SDW_ACP_DMIC),
113129
},
114130
{
115131
.callback = soc_sdw_quirk_cb,

sound/soc/codecs/nau8325.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ static bool nau8325_readable_reg(struct device *dev, unsigned int reg)
142142
static bool nau8325_writeable_reg(struct device *dev, unsigned int reg)
143143
{
144144
switch (reg) {
145-
case NAU8325_R00_HARDWARE_RST:
145+
case NAU8325_R00_HARDWARE_RST ... NAU8325_R01_SOFTWARE_RST:
146146
case NAU8325_R03_CLK_CTRL ... NAU8325_R06_INT_CLR_STATUS:
147147
case NAU8325_R09_IRQOUT ... NAU8325_R13_DAC_VOLUME:
148148
case NAU8325_R29_DAC_CTRL1 ... NAU8325_R2A_DAC_CTRL2:
@@ -670,6 +670,12 @@ static void nau8325_reset_chip(struct regmap *regmap)
670670
regmap_write(regmap, NAU8325_R00_HARDWARE_RST, 0x0000);
671671
}
672672

673+
static void nau8325_software_reset(struct regmap *regmap)
674+
{
675+
regmap_write(regmap, NAU8325_R01_SOFTWARE_RST, 0x0000);
676+
regmap_write(regmap, NAU8325_R01_SOFTWARE_RST, 0x0000);
677+
}
678+
673679
static void nau8325_init_regs(struct nau8325 *nau8325)
674680
{
675681
struct regmap *regmap = nau8325->regmap;
@@ -856,6 +862,7 @@ static int nau8325_i2c_probe(struct i2c_client *i2c)
856862
nau8325_print_device_properties(nau8325);
857863

858864
nau8325_reset_chip(nau8325->regmap);
865+
nau8325_software_reset(nau8325->regmap);
859866
ret = regmap_read(nau8325->regmap, NAU8325_R02_DEVICE_ID, &value);
860867
if (ret) {
861868
dev_dbg(dev, "Failed to read device id (%d)", ret);

sound/soc/intel/avs/board_selection.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,19 +520,22 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev)
520520
if (num_elems > max_ssps) {
521521
dev_err(adev->dev, "board supports only %d SSP, %d specified\n",
522522
max_ssps, num_elems);
523-
return -EINVAL;
523+
ret = -EINVAL;
524+
goto exit;
524525
}
525526

526527
for (ssp_port = 0; ssp_port < num_elems; ssp_port++) {
527528
tdm_slots = array[1 + ssp_port];
528529
for_each_set_bit(tdm_slot, &tdm_slots, 16) {
529530
ret = avs_register_i2s_test_board(adev, ssp_port, tdm_slot);
530531
if (ret)
531-
return ret;
532+
goto exit;
532533
}
533534
}
534535

535-
return 0;
536+
exit:
537+
kfree(array);
538+
return ret;
536539
}
537540

538541
static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)

sound/soc/sdca/sdca_class_function.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ static int class_function_component_probe(struct snd_soc_component *component)
198198
return sdca_irq_populate(drv->function, component, core->irq_info);
199199
}
200200

201+
static void class_function_component_remove(struct snd_soc_component *component)
202+
{
203+
struct class_function_drv *drv = snd_soc_component_get_drvdata(component);
204+
struct sdca_class_drv *core = drv->core;
205+
206+
sdca_irq_cleanup(component->dev, drv->function, core->irq_info);
207+
}
208+
201209
static int class_function_set_jack(struct snd_soc_component *component,
202210
struct snd_soc_jack *jack, void *d)
203211
{
@@ -209,6 +217,7 @@ static int class_function_set_jack(struct snd_soc_component *component,
209217

210218
static const struct snd_soc_component_driver class_function_component_drv = {
211219
.probe = class_function_component_probe,
220+
.remove = class_function_component_remove,
212221
.endianness = 1,
213222
};
214223

@@ -402,6 +411,13 @@ static int class_function_probe(struct auxiliary_device *auxdev,
402411
return 0;
403412
}
404413

414+
static void class_function_remove(struct auxiliary_device *auxdev)
415+
{
416+
struct class_function_drv *drv = auxiliary_get_drvdata(auxdev);
417+
418+
sdca_irq_cleanup(drv->dev, drv->function, drv->core->irq_info);
419+
}
420+
405421
static int class_function_runtime_suspend(struct device *dev)
406422
{
407423
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
@@ -550,6 +566,7 @@ static struct auxiliary_driver class_function_drv = {
550566
},
551567

552568
.probe = class_function_probe,
569+
.remove = class_function_remove,
553570
.id_table = class_function_id_table
554571
};
555572
module_auxiliary_driver(class_function_drv);

sound/soc/sdca/sdca_interrupts.c

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,7 @@ static irqreturn_t function_status_handler(int irq, void *data)
117117

118118
status = val;
119119
for_each_set_bit(mask, &status, BITS_PER_BYTE) {
120-
mask = 1 << mask;
121-
122-
switch (mask) {
120+
switch (BIT(mask)) {
123121
case SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION:
124122
//FIXME: Add init writes
125123
break;
@@ -140,7 +138,7 @@ static irqreturn_t function_status_handler(int irq, void *data)
140138
}
141139
}
142140

143-
ret = regmap_write(interrupt->function_regmap, reg, val);
141+
ret = regmap_write(interrupt->function_regmap, reg, val & 0x7F);
144142
if (ret < 0) {
145143
dev_err(dev, "failed to clear function status: %d\n", ret);
146144
goto error;
@@ -252,8 +250,7 @@ static int sdca_irq_request_locked(struct device *dev,
252250
if (irq < 0)
253251
return irq;
254252

255-
ret = devm_request_threaded_irq(dev, irq, NULL, handler,
256-
IRQF_ONESHOT, name, data);
253+
ret = request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, name, data);
257254
if (ret)
258255
return ret;
259256

@@ -264,6 +261,22 @@ static int sdca_irq_request_locked(struct device *dev,
264261
return 0;
265262
}
266263

264+
static void sdca_irq_free_locked(struct device *dev, struct sdca_interrupt_info *info,
265+
int sdca_irq, const char *name, void *data)
266+
{
267+
int irq;
268+
269+
irq = regmap_irq_get_virq(info->irq_data, sdca_irq);
270+
if (irq < 0)
271+
return;
272+
273+
free_irq(irq, data);
274+
275+
info->irqs[sdca_irq].irq = 0;
276+
277+
dev_dbg(dev, "freed irq %d for %s\n", irq, name);
278+
}
279+
267280
/**
268281
* sdca_irq_request - request an individual SDCA interrupt
269282
* @dev: Pointer to the struct device against which things should be allocated.
@@ -302,6 +315,30 @@ int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *info,
302315
}
303316
EXPORT_SYMBOL_NS_GPL(sdca_irq_request, "SND_SOC_SDCA");
304317

318+
/**
319+
* sdca_irq_free - free an individual SDCA interrupt
320+
* @dev: Pointer to the struct device.
321+
* @info: Pointer to the interrupt information structure.
322+
* @sdca_irq: SDCA interrupt position.
323+
* @name: Name to be given to the IRQ.
324+
* @data: Private data pointer that will be passed to the handler.
325+
*
326+
* Typically this is handled internally by sdca_irq_cleanup, however if
327+
* a device requires custom IRQ handling this can be called manually before
328+
* calling sdca_irq_cleanup, which will then skip that IRQ whilst processing.
329+
*/
330+
void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *info,
331+
int sdca_irq, const char *name, void *data)
332+
{
333+
if (sdca_irq < 0 || sdca_irq >= SDCA_MAX_INTERRUPTS)
334+
return;
335+
336+
guard(mutex)(&info->irq_lock);
337+
338+
sdca_irq_free_locked(dev, info, sdca_irq, name, data);
339+
}
340+
EXPORT_SYMBOL_NS_GPL(sdca_irq_free, "SND_SOC_SDCA");
341+
305342
/**
306343
* sdca_irq_data_populate - Populate common interrupt data
307344
* @dev: Pointer to the Function device.
@@ -328,8 +365,8 @@ int sdca_irq_data_populate(struct device *dev, struct regmap *regmap,
328365
if (!dev)
329366
return -ENODEV;
330367

331-
name = devm_kasprintf(dev, GFP_KERNEL, "%s %s %s", function->desc->name,
332-
entity->label, control->label);
368+
name = kasprintf(GFP_KERNEL, "%s %s %s", function->desc->name,
369+
entity->label, control->label);
333370
if (!name)
334371
return -ENOMEM;
335372

@@ -516,6 +553,35 @@ int sdca_irq_populate(struct sdca_function_data *function,
516553
}
517554
EXPORT_SYMBOL_NS_GPL(sdca_irq_populate, "SND_SOC_SDCA");
518555

556+
/**
557+
* sdca_irq_cleanup - Free all the individual IRQs for an SDCA Function
558+
* @sdev: Device pointer against which the sdca_interrupt_info was allocated.
559+
* @function: Pointer to the SDCA Function.
560+
* @info: Pointer to the SDCA interrupt info for this device.
561+
*
562+
* Typically this would be called from the driver for a single SDCA Function.
563+
*/
564+
void sdca_irq_cleanup(struct device *dev,
565+
struct sdca_function_data *function,
566+
struct sdca_interrupt_info *info)
567+
{
568+
int i;
569+
570+
guard(mutex)(&info->irq_lock);
571+
572+
for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
573+
struct sdca_interrupt *interrupt = &info->irqs[i];
574+
575+
if (interrupt->function != function || !interrupt->irq)
576+
continue;
577+
578+
sdca_irq_free_locked(dev, info, i, interrupt->name, interrupt);
579+
580+
kfree(interrupt->name);
581+
}
582+
}
583+
EXPORT_SYMBOL_NS_GPL(sdca_irq_cleanup, "SND_SOC_SDCA");
584+
519585
/**
520586
* sdca_irq_allocate - allocate an SDCA interrupt structure for a device
521587
* @sdev: Device pointer against which things should be allocated.

0 commit comments

Comments
 (0)