Skip to content

Commit fb2e5fc

Browse files
committed
Merge tag 'asoc-fix-v6.3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v6.3 Almost all of this is driver specific fixes and new IDs that have come in during the merge window. A good chunk of them are simple ones from me which came about due to a bunch of Mediatek Chromebooks being enabled in KernelCI, there's more where that came from. We do have one small feature added to the PCM core by Claudiu Beznea in order to allow the sequencing required to resolve a noise issue with the Microchip PDMC driver.
2 parents 26ed1d2 + b56ec29 commit fb2e5fc

File tree

21 files changed

+260
-147
lines changed

21 files changed

+260
-147
lines changed

Documentation/devicetree/bindings/sound/apple,mca.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ properties:
2323
- enum:
2424
- apple,t6000-mca
2525
- apple,t8103-mca
26+
- apple,t8112-mca
2627
- const: apple,mca
2728

2829
reg:

Documentation/devicetree/bindings/sound/microchip,sama7g5-pdmc.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ properties:
6767
maxItems: 4
6868
uniqueItems: true
6969

70+
microchip,startup-delay-us:
71+
description: |
72+
Specifies the delay in microseconds that needs to be applied after
73+
enabling the PDMC microphones to avoid unwanted noise due to microphones
74+
not being ready.
75+
7076
required:
7177
- compatible
7278
- reg

include/sound/soc-component.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ struct snd_soc_component_driver {
190190
bool use_dai_pcm_id; /* use DAI link PCM ID as PCM device number */
191191
int be_pcm_base; /* base device ID for all BE PCMs */
192192

193+
unsigned int start_dma_last;
194+
193195
#ifdef CONFIG_DEBUG_FS
194196
const char *debugfs_prefix;
195197
#endif

sound/soc/amd/yc/acp6x-mach.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
255255
DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
256256
}
257257
},
258+
{
259+
.driver_data = &acp6x_card,
260+
.matches = {
261+
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
262+
DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
263+
}
264+
},
265+
{
266+
.driver_data = &acp6x_card,
267+
.matches = {
268+
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
269+
DMI_MATCH(DMI_BOARD_NAME, "8A43"),
270+
}
271+
},
258272
{}
259273
};
260274

sound/soc/apple/mca.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@
101101
#define SERDES_CONF_UNK3 BIT(14)
102102
#define SERDES_CONF_NO_DATA_FEEDBACK BIT(15)
103103
#define SERDES_CONF_SYNC_SEL GENMASK(18, 16)
104-
#define SERDES_CONF_SOME_RST BIT(19)
105104
#define REG_TX_SERDES_BITSTART 0x08
106105
#define REG_RX_SERDES_BITSTART 0x0c
107106
#define REG_TX_SERDES_SLOTMASK 0x0c
@@ -203,15 +202,24 @@ static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
203202
case SNDRV_PCM_TRIGGER_START:
204203
case SNDRV_PCM_TRIGGER_RESUME:
205204
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
205+
mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
206+
FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
207+
mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
208+
FIELD_PREP(SERDES_CONF_SYNC_SEL, 7));
206209
mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
207210
SERDES_STATUS_EN | SERDES_STATUS_RST,
208211
SERDES_STATUS_RST);
209-
mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
210-
SERDES_CONF_SOME_RST);
211-
readl_relaxed(cl->base + serdes_conf);
212-
mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
213-
WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
212+
/*
213+
* Experiments suggest that it takes at most ~1 us
214+
* for the bit to clear, so wait 2 us for good measure.
215+
*/
216+
udelay(2);
217+
WARN_ON(readl_relaxed(cl->base + serdes_unit + REG_SERDES_STATUS) &
214218
SERDES_STATUS_RST);
219+
mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
220+
FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
221+
mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
222+
FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1));
215223
break;
216224
default:
217225
break;
@@ -942,10 +950,17 @@ static int mca_pcm_new(struct snd_soc_component *component,
942950
chan = mca_request_dma_channel(cl, i);
943951

944952
if (IS_ERR_OR_NULL(chan)) {
953+
mca_pcm_free(component, rtd->pcm);
954+
955+
if (chan && PTR_ERR(chan) == -EPROBE_DEFER)
956+
return PTR_ERR(chan);
957+
945958
dev_err(component->dev, "unable to obtain DMA channel (stream %d cluster %d): %pe\n",
946959
i, cl->no, chan);
947-
mca_pcm_free(component, rtd->pcm);
948-
return -EINVAL;
960+
961+
if (!chan)
962+
return -EINVAL;
963+
return PTR_ERR(chan);
949964
}
950965

951966
cl->dma_chans[i] = chan;

sound/soc/atmel/mchp-pdmc.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ struct mchp_pdmc {
114114
struct clk *gclk;
115115
u32 pdmcen;
116116
u32 suspend_irq;
117+
u32 startup_delay_us;
117118
int mic_no;
118119
int sinc_order;
119120
bool audio_filter_en;
@@ -425,6 +426,7 @@ static const struct snd_soc_component_driver mchp_pdmc_dai_component = {
425426
.open = &mchp_pdmc_open,
426427
.close = &mchp_pdmc_close,
427428
.legacy_dai_naming = 1,
429+
.start_dma_last = 1,
428430
};
429431

430432
static const unsigned int mchp_pdmc_1mic[] = {1};
@@ -632,6 +634,29 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
632634
return 0;
633635
}
634636

637+
static void mchp_pdmc_noise_filter_workaround(struct mchp_pdmc *dd)
638+
{
639+
u32 tmp, steps = 16;
640+
641+
/*
642+
* PDMC doesn't wait for microphones' startup time thus the acquisition
643+
* may start before the microphones are ready leading to poc noises at
644+
* the beginning of capture. To avoid this, we need to wait 50ms (in
645+
* normal startup procedure) or 150 ms (worst case after resume from sleep
646+
* states) after microphones are enabled and then clear the FIFOs (by
647+
* reading the RHR 16 times) and possible interrupts before continuing.
648+
* Also, for this to work the DMA needs to be started after interrupts
649+
* are enabled.
650+
*/
651+
usleep_range(dd->startup_delay_us, dd->startup_delay_us + 5);
652+
653+
while (steps--)
654+
regmap_read(dd->regmap, MCHP_PDMC_RHR, &tmp);
655+
656+
/* Clear interrupts. */
657+
regmap_read(dd->regmap, MCHP_PDMC_ISR, &tmp);
658+
}
659+
635660
static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
636661
int cmd, struct snd_soc_dai *dai)
637662
{
@@ -644,15 +669,17 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
644669
switch (cmd) {
645670
case SNDRV_PCM_TRIGGER_RESUME:
646671
case SNDRV_PCM_TRIGGER_START:
647-
/* Enable overrun and underrun error interrupts */
648-
regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
649-
MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
650-
dd->suspend_irq = 0;
651-
fallthrough;
652672
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
653673
snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
654674
MCHP_PDMC_MR_PDMCEN_MASK,
655675
dd->pdmcen);
676+
677+
mchp_pdmc_noise_filter_workaround(dd);
678+
679+
/* Enable interrupts. */
680+
regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
681+
MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
682+
dd->suspend_irq = 0;
656683
break;
657684
case SNDRV_PCM_TRIGGER_SUSPEND:
658685
regmap_read(dd->regmap, MCHP_PDMC_IMR, &dd->suspend_irq);
@@ -796,6 +823,7 @@ static bool mchp_pdmc_readable_reg(struct device *dev, unsigned int reg)
796823
case MCHP_PDMC_CFGR:
797824
case MCHP_PDMC_IMR:
798825
case MCHP_PDMC_ISR:
826+
case MCHP_PDMC_RHR:
799827
case MCHP_PDMC_VER:
800828
return true;
801829
default:
@@ -817,6 +845,17 @@ static bool mchp_pdmc_writeable_reg(struct device *dev, unsigned int reg)
817845
}
818846
}
819847

848+
static bool mchp_pdmc_volatile_reg(struct device *dev, unsigned int reg)
849+
{
850+
switch (reg) {
851+
case MCHP_PDMC_ISR:
852+
case MCHP_PDMC_RHR:
853+
return true;
854+
default:
855+
return false;
856+
}
857+
}
858+
820859
static bool mchp_pdmc_precious_reg(struct device *dev, unsigned int reg)
821860
{
822861
switch (reg) {
@@ -836,6 +875,7 @@ static const struct regmap_config mchp_pdmc_regmap_config = {
836875
.readable_reg = mchp_pdmc_readable_reg,
837876
.writeable_reg = mchp_pdmc_writeable_reg,
838877
.precious_reg = mchp_pdmc_precious_reg,
878+
.volatile_reg = mchp_pdmc_volatile_reg,
839879
.cache_type = REGCACHE_FLAT,
840880
};
841881

@@ -918,6 +958,9 @@ static int mchp_pdmc_dt_init(struct mchp_pdmc *dd)
918958
dd->channel_mic_map[i].clk_edge = edge;
919959
}
920960

961+
dd->startup_delay_us = 150000;
962+
of_property_read_u32(np, "microchip,startup-delay-us", &dd->startup_delay_us);
963+
921964
return 0;
922965
}
923966

sound/soc/atmel/sam9g20_wm8731.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
9898
.init = at91sam9g20ek_wm8731_init,
9999
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
100100
SND_SOC_DAIFMT_CBP_CFP,
101+
#ifndef ENABLE_MIC_INPUT
102+
.playback_only = true,
103+
#endif
101104
SND_SOC_DAILINK_REG(pcm),
102105
};
103106

sound/soc/codecs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2103,6 +2103,7 @@ config SND_SOC_WSA883X
21032103
config SND_SOC_ZL38060
21042104
tristate "Microsemi ZL38060 Connected Home Audio Processor"
21052105
depends on SPI_MASTER
2106+
depends on GPIOLIB
21062107
select REGMAP
21072108
help
21082109
Support for ZL38060 Connected Home Audio Processor from Microsemi,

sound/soc/codecs/adau7118.c

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -444,22 +444,6 @@ static const struct snd_soc_component_driver adau7118_component_driver = {
444444
.endianness = 1,
445445
};
446446

447-
static void adau7118_regulator_disable(void *data)
448-
{
449-
struct adau7118_data *st = data;
450-
int ret;
451-
/*
452-
* If we fail to disable DVDD, don't bother in trying IOVDD. We
453-
* actually don't want to be left in the situation where DVDD
454-
* is enabled and IOVDD is disabled.
455-
*/
456-
ret = regulator_disable(st->dvdd);
457-
if (ret)
458-
return;
459-
460-
regulator_disable(st->iovdd);
461-
}
462-
463447
static int adau7118_regulator_setup(struct adau7118_data *st)
464448
{
465449
st->iovdd = devm_regulator_get(st->dev, "iovdd");
@@ -481,8 +465,7 @@ static int adau7118_regulator_setup(struct adau7118_data *st)
481465
regcache_cache_only(st->map, true);
482466
}
483467

484-
return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
485-
st);
468+
return 0;
486469
}
487470

488471
static int adau7118_parset_dt(const struct adau7118_data *st)

sound/soc/codecs/da7219-aad.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -339,26 +339,49 @@ static void da7219_aad_hptest_work(struct work_struct *work)
339339
SND_JACK_HEADSET | SND_JACK_LINEOUT);
340340
}
341341

342+
static void da7219_aad_jack_det_work(struct work_struct *work)
343+
{
344+
struct da7219_aad_priv *da7219_aad =
345+
container_of(work, struct da7219_aad_priv, jack_det_work);
346+
struct snd_soc_component *component = da7219_aad->component;
347+
u8 srm_st;
348+
349+
mutex_lock(&da7219_aad->jack_det_mutex);
350+
351+
srm_st = snd_soc_component_read(component, DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
352+
msleep(da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 4);
353+
/* Enable ground switch */
354+
snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
355+
356+
mutex_unlock(&da7219_aad->jack_det_mutex);
357+
}
358+
342359

343360
/*
344361
* IRQ
345362
*/
346363

364+
static irqreturn_t da7219_aad_pre_irq_thread(int irq, void *data)
365+
{
366+
367+
struct da7219_aad_priv *da7219_aad = data;
368+
369+
if (!da7219_aad->jack_inserted)
370+
schedule_work(&da7219_aad->jack_det_work);
371+
372+
return IRQ_WAKE_THREAD;
373+
}
374+
347375
static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
348376
{
349377
struct da7219_aad_priv *da7219_aad = data;
350378
struct snd_soc_component *component = da7219_aad->component;
351379
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
352380
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
353381
u8 events[DA7219_AAD_IRQ_REG_MAX];
354-
u8 statusa, srm_st;
382+
u8 statusa;
355383
int i, report = 0, mask = 0;
356384

357-
srm_st = snd_soc_component_read(component, DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
358-
msleep(da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 4);
359-
/* Enable ground switch */
360-
snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
361-
362385
/* Read current IRQ events */
363386
regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
364387
events, DA7219_AAD_IRQ_REG_MAX);
@@ -377,6 +400,9 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
377400
events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
378401
statusa);
379402

403+
if (!da7219_aad->jack_inserted)
404+
cancel_work_sync(&da7219_aad->jack_det_work);
405+
380406
if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
381407
/* Jack Insertion */
382408
if (events[DA7219_AAD_IRQ_REG_A] &
@@ -940,8 +966,9 @@ int da7219_aad_init(struct snd_soc_component *component)
940966

941967
INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
942968
INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
969+
INIT_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work);
943970

944-
ret = request_threaded_irq(da7219_aad->irq, NULL,
971+
ret = request_threaded_irq(da7219_aad->irq, da7219_aad_pre_irq_thread,
945972
da7219_aad_irq_thread,
946973
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
947974
"da7219-aad", da7219_aad);

0 commit comments

Comments
 (0)