mirror of https://gitee.com/openkylin/linux.git
sound fixes for 4.20-rc5
As a usual pattern, we've got relatively large updates at rc5. - A fix for races in ALSA control user elements - ASoC DAPM regression due to component refactoring - A fix in error handling of ASoC iteration macro - ASoC Intel SST Skylake kconfig fix; a new Kconfig will appear as a consequence, but in the end it's a good cleanup - HD-audio and USB-audio quirks as always - Assort of ASoC driver fixes (pcm186x, Intel cht, rockchip, pcm3060, rsnd, omap, wm_adsp, qcom, sunxi, stm32) -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAlv+yaEOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE8rJRAAs3PHBkPy5xVd8bTFiWNPiMrts3GWjTMiQbPf oQcgfXjJFyAnsdIQlCGwF9dLCVCRQDGUqe1Uf01CCP/0yzY2aXjzNa8SF8Mxt2PZ F5AZs8BgQyMKNqHCvyFEUwrPTwhNj3APk19oBdB+lfU7alFf/JNkuBP3cnYASGeJ CybHJzRtPr8r12a46olttU7CqGC6twoNG84It6C+gfIvmG4Wqh0nHVVubLXpwCJG mDt/fgsCwXDfUD41mNZ2KjIufWWI1SHcHWSCP9xV8W9vcugH1AvD/DkvBp4JpGuG 92emTcOVJNV3Xg5fOeL3wMmk8YiDtxezdQs0ZWKSDLINo8Q9jvfCHvFGW3fJI85y Fwwm8c2s/MYUEfyUyqbdNekFmQ9t4Gt+tjRKMjZhmj1N40CuyFQOC2kx4oF8J15Z 7U8/eOQ6paUV+E2Tbrui5qsdt3IzV3YAAJwbVPXjqJQ26uxKwgNzd0oO1mGKUX5N f5h2EMb3mwCPwsxZR8Bi5NmSpCyUXNKDrUogauPjV1IX8x3vC5TpwrI9IWupUNQu oUOsJxc8Mp4qeufspfdaB3m/8nQJ66sxfLTMuagT7Iy007DfLP2V8xyjAbNtxwq4 yg2/xTxpictFiAQ5h+Ignk96+aSS1VS77XFTVsyq3cYGRtw2ByUtffG1TUlBu9sg mAw9P7I= =GXsL -----END PGP SIGNATURE----- Merge tag 'sound-4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "As a usual pattern, we've got relatively large updates at rc5: - A fix for races in ALSA control user elements - ASoC DAPM regression due to component refactoring - A fix in error handling of ASoC iteration macro - ASoC Intel SST Skylake kconfig fix; a new Kconfig will appear as a consequence, but in the end it's a good cleanup - HD-audio and USB-audio quirks as always - Assort of ASoC driver fixes (pcm186x, Intel cht, rockchip, pcm3060, rsnd, omap, wm_adsp, qcom, sunxi, stm32)" * tag 'sound-4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (34 commits) ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock ALSA: hda/realtek - Support ALC300 ALSA: hda/realtek - Add auto-mute quirk for HP Spectre x360 laptop ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops ALSA: control: Fix race between adding and removing a user element ALSA: sparc: Fix invalid snd_free_pages() at error path ALSA: wss: Fix invalid snd_free_pages() at error path ALSA: hda/realtek - fix headset mic detection for MSI MS-B171 ALSA: hda: Add ASRock N68C-S UCC the power_save blacklist ALSA: ac97: Fix incorrect bit shift at AC97-SPSA control write ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns with CPU_IDLE ASoC: omap-mcbsp: Fix latency value calculation for pm_qos ASoC: acpi: fix: continue searching when machine is ignored ASoC: Intel: Skylake: fix Kconfigs, make HDaudio codec optional MAINTAINERS: add ASoC maintainers for sound dt-bindings ASoC: pcm186x: Fix device reset-registers trigger value ASoC: dapm: Recalculate audio map forcely when card instantiated ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred probing ASoC: pcm3060: Rename output widgets ...
This commit is contained in:
commit
b905e2db5c
|
@ -14010,6 +14010,7 @@ S: Supported
|
|||
F: Documentation/devicetree/bindings/sound/
|
||||
F: Documentation/sound/soc/
|
||||
F: sound/soc/
|
||||
F: include/dt-bindings/sound/
|
||||
F: include/sound/soc*
|
||||
|
||||
SOUNDWIRE SUBSYSTEM
|
||||
|
|
|
@ -1192,7 +1192,7 @@ struct snd_soc_pcm_runtime {
|
|||
((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \
|
||||
(i)++)
|
||||
#define for_each_rtd_codec_dai_rollback(rtd, i, dai) \
|
||||
for (; ((i--) >= 0) && ((dai) = rtd->codec_dais[i]);)
|
||||
for (; ((--i) >= 0) && ((dai) = rtd->codec_dais[i]);)
|
||||
|
||||
|
||||
/* mixer control */
|
||||
|
|
|
@ -348,6 +348,40 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* add a new kcontrol object; call with card->controls_rwsem locked */
|
||||
static int __snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
struct snd_ctl_elem_id id;
|
||||
unsigned int idx;
|
||||
unsigned int count;
|
||||
|
||||
id = kcontrol->id;
|
||||
if (id.index > UINT_MAX - kcontrol->count)
|
||||
return -EINVAL;
|
||||
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
dev_err(card->dev,
|
||||
"control %i:%i:%i:%s:%i is already present\n",
|
||||
id.iface, id.device, id.subdevice, id.name, id.index);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (snd_ctl_find_hole(card, kcontrol->count) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
list_add_tail(&kcontrol->list, &card->controls);
|
||||
card->controls_count += kcontrol->count;
|
||||
kcontrol->id.numid = card->last_numid + 1;
|
||||
card->last_numid += kcontrol->count;
|
||||
|
||||
id = kcontrol->id;
|
||||
count = kcontrol->count;
|
||||
for (idx = 0; idx < count; idx++, id.index++, id.numid++)
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_ctl_add - add the control instance to the card
|
||||
* @card: the card instance
|
||||
|
@ -364,45 +398,18 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
|
|||
*/
|
||||
int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
struct snd_ctl_elem_id id;
|
||||
unsigned int idx;
|
||||
unsigned int count;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (! kcontrol)
|
||||
return err;
|
||||
if (snd_BUG_ON(!card || !kcontrol->info))
|
||||
goto error;
|
||||
id = kcontrol->id;
|
||||
if (id.index > UINT_MAX - kcontrol->count)
|
||||
goto error;
|
||||
|
||||
down_write(&card->controls_rwsem);
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
up_write(&card->controls_rwsem);
|
||||
dev_err(card->dev, "control %i:%i:%i:%s:%i is already present\n",
|
||||
id.iface,
|
||||
id.device,
|
||||
id.subdevice,
|
||||
id.name,
|
||||
id.index);
|
||||
err = -EBUSY;
|
||||
goto error;
|
||||
}
|
||||
if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
|
||||
up_write(&card->controls_rwsem);
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
list_add_tail(&kcontrol->list, &card->controls);
|
||||
card->controls_count += kcontrol->count;
|
||||
kcontrol->id.numid = card->last_numid + 1;
|
||||
card->last_numid += kcontrol->count;
|
||||
id = kcontrol->id;
|
||||
count = kcontrol->count;
|
||||
err = __snd_ctl_add(card, kcontrol);
|
||||
up_write(&card->controls_rwsem);
|
||||
for (idx = 0; idx < count; idx++, id.index++, id.numid++)
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
@ -1361,9 +1368,12 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
|||
kctl->tlv.c = snd_ctl_elem_user_tlv;
|
||||
|
||||
/* This function manage to free the instance on failure. */
|
||||
err = snd_ctl_add(card, kctl);
|
||||
if (err < 0)
|
||||
return err;
|
||||
down_write(&card->controls_rwsem);
|
||||
err = __snd_ctl_add(card, kctl);
|
||||
if (err < 0) {
|
||||
snd_ctl_free_one(kctl);
|
||||
goto unlock;
|
||||
}
|
||||
offset = snd_ctl_get_ioff(kctl, &info->id);
|
||||
snd_ctl_build_ioff(&info->id, kctl, offset);
|
||||
/*
|
||||
|
@ -1374,10 +1384,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
|||
* which locks the element.
|
||||
*/
|
||||
|
||||
down_write(&card->controls_rwsem);
|
||||
card->user_ctl_count++;
|
||||
up_write(&card->controls_rwsem);
|
||||
|
||||
unlock:
|
||||
up_write(&card->controls_rwsem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1531,7 +1531,6 @@ static int snd_wss_playback_open(struct snd_pcm_substream *substream)
|
|||
if (err < 0) {
|
||||
if (chip->release_dma)
|
||||
chip->release_dma(chip, chip->dma_private_data, chip->dma1);
|
||||
snd_free_pages(runtime->dma_area, runtime->dma_bytes);
|
||||
return err;
|
||||
}
|
||||
chip->playback_substream = substream;
|
||||
|
@ -1572,7 +1571,6 @@ static int snd_wss_capture_open(struct snd_pcm_substream *substream)
|
|||
if (err < 0) {
|
||||
if (chip->release_dma)
|
||||
chip->release_dma(chip, chip->dma_private_data, chip->dma2);
|
||||
snd_free_pages(runtime->dma_area, runtime->dma_bytes);
|
||||
return err;
|
||||
}
|
||||
chip->capture_substream = substream;
|
||||
|
|
|
@ -824,7 +824,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
|||
{
|
||||
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
|
||||
int reg = kcontrol->private_value & 0xff;
|
||||
int shift = (kcontrol->private_value >> 8) & 0xff;
|
||||
int shift = (kcontrol->private_value >> 8) & 0x0f;
|
||||
int mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
// int invert = (kcontrol->private_value >> 24) & 0xff;
|
||||
unsigned short value, old, new;
|
||||
|
|
|
@ -2169,6 +2169,8 @@ static struct snd_pci_quirk power_save_blacklist[] = {
|
|||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
||||
SND_PCI_QUIRK(0x1849, 0xc892, "Asrock B85M-ITX", 0),
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
||||
SND_PCI_QUIRK(0x1849, 0x0397, "Asrock N68C-S UCC", 0),
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
||||
SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0),
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
||||
SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0),
|
||||
|
|
|
@ -388,6 +388,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
|||
case 0x10ec0285:
|
||||
case 0x10ec0298:
|
||||
case 0x10ec0289:
|
||||
case 0x10ec0300:
|
||||
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
|
||||
break;
|
||||
case 0x10ec0275:
|
||||
|
@ -2830,6 +2831,7 @@ enum {
|
|||
ALC269_TYPE_ALC215,
|
||||
ALC269_TYPE_ALC225,
|
||||
ALC269_TYPE_ALC294,
|
||||
ALC269_TYPE_ALC300,
|
||||
ALC269_TYPE_ALC700,
|
||||
};
|
||||
|
||||
|
@ -2864,6 +2866,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
|
|||
case ALC269_TYPE_ALC215:
|
||||
case ALC269_TYPE_ALC225:
|
||||
case ALC269_TYPE_ALC294:
|
||||
case ALC269_TYPE_ALC300:
|
||||
case ALC269_TYPE_ALC700:
|
||||
ssids = alc269_ssids;
|
||||
break;
|
||||
|
@ -5358,6 +5361,16 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec,
|
|||
spec->gen.preferred_dacs = preferred_pairs;
|
||||
}
|
||||
|
||||
/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
|
||||
static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
if (action != HDA_FIXUP_ACT_PRE_PROBE)
|
||||
return;
|
||||
|
||||
snd_hda_override_wcaps(codec, 0x03, 0);
|
||||
}
|
||||
|
||||
/* for hda_fixup_thinkpad_acpi() */
|
||||
#include "thinkpad_helper.c"
|
||||
|
||||
|
@ -5495,6 +5508,8 @@ enum {
|
|||
ALC255_FIXUP_DELL_HEADSET_MIC,
|
||||
ALC295_FIXUP_HP_X360,
|
||||
ALC221_FIXUP_HP_HEADSET_MIC,
|
||||
ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
|
||||
ALC295_FIXUP_HP_AUTO_MUTE,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc269_fixups[] = {
|
||||
|
@ -5659,6 +5674,8 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
[ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc269_fixup_hp_mute_led_mic3,
|
||||
.chained = true,
|
||||
.chain_id = ALC295_FIXUP_HP_AUTO_MUTE
|
||||
},
|
||||
[ALC269_FIXUP_HP_GPIO_LED] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
|
@ -6362,6 +6379,14 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_HEADSET_MIC
|
||||
},
|
||||
[ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc285_fixup_invalidate_dacs,
|
||||
},
|
||||
[ALC295_FIXUP_HP_AUTO_MUTE] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_auto_mute_via_amp,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
|
@ -6532,6 +6557,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
|
||||
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
|
||||
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
|
||||
|
@ -7034,6 +7060,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
|||
{0x12, 0x90a60130},
|
||||
{0x19, 0x03a11020},
|
||||
{0x21, 0x0321101f}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
|
||||
{0x12, 0x90a60130},
|
||||
{0x14, 0x90170110},
|
||||
{0x19, 0x04a11040},
|
||||
{0x21, 0x04211020}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
{0x12, 0x90a60120},
|
||||
{0x14, 0x90170110},
|
||||
|
@ -7295,6 +7326,10 @@ static int patch_alc269(struct hda_codec *codec)
|
|||
spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
|
||||
alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
|
||||
break;
|
||||
case 0x10ec0300:
|
||||
spec->codec_variant = ALC269_TYPE_ALC300;
|
||||
spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
|
||||
break;
|
||||
case 0x10ec0700:
|
||||
case 0x10ec0701:
|
||||
case 0x10ec0703:
|
||||
|
@ -8405,6 +8440,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
|
|||
HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
|
||||
HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
|
||||
HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
|
||||
HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
|
||||
|
|
|
@ -2187,11 +2187,6 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
|
|||
*/
|
||||
snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,
|
||||
AC_PWRST_D3);
|
||||
err = snd_hdac_display_power(bus, false);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "Cannot turn on display power on i915\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
hlink = snd_hdac_ext_bus_get_link(bus, dev_name(dev));
|
||||
if (!hlink) {
|
||||
|
@ -2201,7 +2196,11 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
|
|||
|
||||
snd_hdac_ext_bus_link_put(bus, hlink);
|
||||
|
||||
return 0;
|
||||
err = snd_hdac_display_power(bus, false);
|
||||
if (err < 0)
|
||||
dev_err(dev, "Cannot turn off display power on i915\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hdac_hdmi_runtime_resume(struct device *dev)
|
||||
|
|
|
@ -139,7 +139,7 @@ enum pcm186x_type {
|
|||
#define PCM186X_MAX_REGISTER PCM186X_CURR_TRIM_CTRL
|
||||
|
||||
/* PCM186X_PAGE */
|
||||
#define PCM186X_RESET 0xff
|
||||
#define PCM186X_RESET 0xfe
|
||||
|
||||
/* PCM186X_ADCX_INPUT_SEL_X */
|
||||
#define PCM186X_ADC_INPUT_SEL_POL BIT(7)
|
||||
|
|
|
@ -198,20 +198,16 @@ static const struct snd_kcontrol_new pcm3060_dapm_controls[] = {
|
|||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget pcm3060_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_OUTPUT("OUTL+"),
|
||||
SND_SOC_DAPM_OUTPUT("OUTR+"),
|
||||
SND_SOC_DAPM_OUTPUT("OUTL-"),
|
||||
SND_SOC_DAPM_OUTPUT("OUTR-"),
|
||||
SND_SOC_DAPM_OUTPUT("OUTL"),
|
||||
SND_SOC_DAPM_OUTPUT("OUTR"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("INL"),
|
||||
SND_SOC_DAPM_INPUT("INR"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route pcm3060_dapm_map[] = {
|
||||
{ "OUTL+", NULL, "Playback" },
|
||||
{ "OUTR+", NULL, "Playback" },
|
||||
{ "OUTL-", NULL, "Playback" },
|
||||
{ "OUTR-", NULL, "Playback" },
|
||||
{ "OUTL", NULL, "Playback" },
|
||||
{ "OUTR", NULL, "Playback" },
|
||||
|
||||
{ "Capture", NULL, "INL" },
|
||||
{ "Capture", NULL, "INR" },
|
||||
|
|
|
@ -765,38 +765,41 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem,
|
|||
|
||||
static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
|
||||
{
|
||||
u16 scratch[4];
|
||||
unsigned int scratch[4];
|
||||
unsigned int addr = dsp->base + ADSP2_SCRATCH0;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2_SCRATCH0,
|
||||
scratch, sizeof(scratch));
|
||||
if (ret) {
|
||||
adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
|
||||
return;
|
||||
for (i = 0; i < ARRAY_SIZE(scratch); ++i) {
|
||||
ret = regmap_read(dsp->regmap, addr + i, &scratch[i]);
|
||||
if (ret) {
|
||||
adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
|
||||
be16_to_cpu(scratch[0]),
|
||||
be16_to_cpu(scratch[1]),
|
||||
be16_to_cpu(scratch[2]),
|
||||
be16_to_cpu(scratch[3]));
|
||||
scratch[0], scratch[1], scratch[2], scratch[3]);
|
||||
}
|
||||
|
||||
static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp)
|
||||
{
|
||||
u32 scratch[2];
|
||||
unsigned int scratch[2];
|
||||
int ret;
|
||||
|
||||
ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1,
|
||||
scratch, sizeof(scratch));
|
||||
|
||||
ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1,
|
||||
&scratch[0]);
|
||||
if (ret) {
|
||||
adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
|
||||
adsp_err(dsp, "Failed to read SCRATCH0_1: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
scratch[0] = be32_to_cpu(scratch[0]);
|
||||
scratch[1] = be32_to_cpu(scratch[1]);
|
||||
ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH2_3,
|
||||
&scratch[1]);
|
||||
if (ret) {
|
||||
adsp_err(dsp, "Failed to read SCRATCH2_3: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
|
||||
scratch[0] & 0xFFFF,
|
||||
|
|
|
@ -101,22 +101,42 @@ config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
|
|||
codec, then enable this option by saying Y or m. This is a
|
||||
recommended option
|
||||
|
||||
config SND_SOC_INTEL_SKYLAKE_SSP_CLK
|
||||
tristate
|
||||
|
||||
config SND_SOC_INTEL_SKYLAKE
|
||||
tristate "SKL/BXT/KBL/GLK/CNL... Platforms"
|
||||
depends on PCI && ACPI
|
||||
select SND_SOC_INTEL_SKYLAKE_COMMON
|
||||
help
|
||||
If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
|
||||
GeminiLake or CannonLake platform with the DSP enabled in the BIOS
|
||||
then enable this option by saying Y or m.
|
||||
|
||||
if SND_SOC_INTEL_SKYLAKE
|
||||
|
||||
config SND_SOC_INTEL_SKYLAKE_SSP_CLK
|
||||
tristate
|
||||
|
||||
config SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
|
||||
bool "HDAudio codec support"
|
||||
help
|
||||
If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
|
||||
GeminiLake or CannonLake platform with an HDaudio codec
|
||||
then enable this option by saying Y
|
||||
|
||||
config SND_SOC_INTEL_SKYLAKE_COMMON
|
||||
tristate
|
||||
select SND_HDA_EXT_CORE
|
||||
select SND_HDA_DSP_LOADER
|
||||
select SND_SOC_TOPOLOGY
|
||||
select SND_SOC_INTEL_SST
|
||||
select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
|
||||
select SND_SOC_ACPI_INTEL_MATCH
|
||||
help
|
||||
If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
|
||||
GeminiLake or CannonLake platform with the DSP enabled in the BIOS
|
||||
then enable this option by saying Y or m.
|
||||
|
||||
endif ## SND_SOC_INTEL_SKYLAKE
|
||||
|
||||
config SND_SOC_ACPI_INTEL_MATCH
|
||||
tristate
|
||||
select SND_SOC_ACPI if ACPI
|
||||
|
|
|
@ -293,16 +293,6 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH
|
|||
Say Y if you have such a device.
|
||||
If unsure select "N".
|
||||
|
||||
config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH
|
||||
tristate "SKL/KBL/BXT/APL with HDA Codecs"
|
||||
select SND_SOC_HDAC_HDMI
|
||||
select SND_SOC_HDAC_HDA
|
||||
help
|
||||
This adds support for ASoC machine driver for Intel platforms
|
||||
SKL/KBL/BXT/APL with iDisp, HDA audio codecs.
|
||||
Say Y or m if you have such a device. This is a recommended option.
|
||||
If unsure select "N".
|
||||
|
||||
config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
|
||||
tristate "GLK with RT5682 and MAX98357A in I2S Mode"
|
||||
depends on MFD_INTEL_LPSS && I2C && ACPI
|
||||
|
@ -319,4 +309,18 @@ config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
|
|||
|
||||
endif ## SND_SOC_INTEL_SKYLAKE
|
||||
|
||||
if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
|
||||
|
||||
config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH
|
||||
tristate "SKL/KBL/BXT/APL with HDA Codecs"
|
||||
select SND_SOC_HDAC_HDMI
|
||||
# SND_SOC_HDAC_HDA is already selected
|
||||
help
|
||||
This adds support for ASoC machine driver for Intel platforms
|
||||
SKL/KBL/BXT/APL with iDisp, HDA audio codecs.
|
||||
Say Y or m if you have such a device. This is a recommended option.
|
||||
If unsure select "N".
|
||||
|
||||
endif ## SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
|
||||
|
||||
endif ## SND_SOC_INTEL_MACH
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -35,6 +36,8 @@
|
|||
#define CHT_PLAT_CLK_3_HZ 19200000
|
||||
#define CHT_CODEC_DAI "HiFi"
|
||||
|
||||
#define QUIRK_PMC_PLT_CLK_0 0x01
|
||||
|
||||
struct cht_mc_private {
|
||||
struct clk *mclk;
|
||||
struct snd_soc_jack jack;
|
||||
|
@ -385,11 +388,29 @@ static struct snd_soc_card snd_soc_card_cht = {
|
|||
.num_controls = ARRAY_SIZE(cht_mc_controls),
|
||||
};
|
||||
|
||||
static const struct dmi_system_id cht_max98090_quirk_table[] = {
|
||||
{
|
||||
/* Swanky model Chromebook (Toshiba Chromebook 2) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"),
|
||||
},
|
||||
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static int snd_cht_mc_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct dmi_system_id *dmi_id;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret_val = 0;
|
||||
struct cht_mc_private *drv;
|
||||
const char *mclk_name;
|
||||
int quirks = 0;
|
||||
|
||||
dmi_id = dmi_first_match(cht_max98090_quirk_table);
|
||||
if (dmi_id)
|
||||
quirks = (unsigned long)dmi_id->driver_data;
|
||||
|
||||
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
|
||||
if (!drv)
|
||||
|
@ -411,11 +432,16 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
|||
snd_soc_card_cht.dev = &pdev->dev;
|
||||
snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
|
||||
|
||||
drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
|
||||
if (quirks & QUIRK_PMC_PLT_CLK_0)
|
||||
mclk_name = "pmc_plt_clk_0";
|
||||
else
|
||||
mclk_name = "pmc_plt_clk_3";
|
||||
|
||||
drv->mclk = devm_clk_get(&pdev->dev, mclk_name);
|
||||
if (IS_ERR(drv->mclk)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to get MCLK from pmc_plt_clk_3: %ld\n",
|
||||
PTR_ERR(drv->mclk));
|
||||
"Failed to get MCLK from %s: %ld\n",
|
||||
mclk_name, PTR_ERR(drv->mclk));
|
||||
return PTR_ERR(drv->mclk);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
#include "skl.h"
|
||||
#include "skl-sst-dsp.h"
|
||||
#include "skl-sst-ipc.h"
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
|
||||
#include "../../../soc/codecs/hdac_hda.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* initialize the PCI registers
|
||||
|
@ -658,6 +660,8 @@ static void skl_clock_device_unregister(struct skl *skl)
|
|||
platform_device_unregister(skl->clk_dev);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
|
||||
|
||||
#define IDISP_INTEL_VENDOR_ID 0x80860000
|
||||
|
||||
/*
|
||||
|
@ -676,6 +680,8 @@ static void load_codec_module(struct hda_codec *codec)
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
|
||||
|
||||
/*
|
||||
* Probe the given codec address
|
||||
*/
|
||||
|
@ -685,9 +691,11 @@ static int probe_codec(struct hdac_bus *bus, int addr)
|
|||
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
|
||||
unsigned int res = -1;
|
||||
struct skl *skl = bus_to_skl(bus);
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
|
||||
struct hdac_hda_priv *hda_codec;
|
||||
struct hdac_device *hdev;
|
||||
int err;
|
||||
#endif
|
||||
struct hdac_device *hdev;
|
||||
|
||||
mutex_lock(&bus->cmd_mutex);
|
||||
snd_hdac_bus_send_cmd(bus, cmd);
|
||||
|
@ -697,6 +705,7 @@ static int probe_codec(struct hdac_bus *bus, int addr)
|
|||
return -EIO;
|
||||
dev_dbg(bus->dev, "codec #%d probed OK: %x\n", addr, res);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
|
||||
hda_codec = devm_kzalloc(&skl->pci->dev, sizeof(*hda_codec),
|
||||
GFP_KERNEL);
|
||||
if (!hda_codec)
|
||||
|
@ -715,6 +724,13 @@ static int probe_codec(struct hdac_bus *bus, int addr)
|
|||
load_codec_module(&hda_codec->codec);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
hdev = devm_kzalloc(&skl->pci->dev, sizeof(*hdev), GFP_KERNEL);
|
||||
if (!hdev)
|
||||
return -ENOMEM;
|
||||
|
||||
return snd_hdac_ext_bus_device_init(bus, addr, hdev);
|
||||
#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
|
||||
}
|
||||
|
||||
/* Codec initialization */
|
||||
|
@ -815,6 +831,12 @@ static void skl_probe_work(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* we are done probing so decrement link counts
|
||||
*/
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list)
|
||||
snd_hdac_ext_bus_link_put(bus, hlink);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
|
||||
err = snd_hdac_display_power(bus, false);
|
||||
if (err < 0) {
|
||||
|
@ -824,12 +846,6 @@ static void skl_probe_work(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* we are done probing so decrement link counts
|
||||
*/
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list)
|
||||
snd_hdac_ext_bus_link_put(bus, hlink);
|
||||
|
||||
/* configure PM */
|
||||
pm_runtime_put_noidle(bus->dev);
|
||||
pm_runtime_allow(bus->dev);
|
||||
|
@ -870,7 +886,7 @@ static int skl_create(struct pci_dev *pci,
|
|||
hbus = skl_to_hbus(skl);
|
||||
bus = skl_to_bus(skl);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDA)
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
|
||||
ext_ops = snd_soc_hdac_hda_get_ops();
|
||||
#endif
|
||||
snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, ext_ops);
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "../codecs/twl6040.h"
|
||||
|
||||
struct abe_twl6040 {
|
||||
struct snd_soc_card card;
|
||||
struct snd_soc_dai_link dai_links[2];
|
||||
int jack_detection; /* board can detect jack events */
|
||||
int mclk_freq; /* MCLK frequency speed for twl6040 */
|
||||
};
|
||||
|
@ -208,40 +210,10 @@ static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd)
|
|||
ARRAY_SIZE(dmic_audio_map));
|
||||
}
|
||||
|
||||
/* Digital audio interface glue - connects codec <--> CPU */
|
||||
static struct snd_soc_dai_link abe_twl6040_dai_links[] = {
|
||||
{
|
||||
.name = "TWL6040",
|
||||
.stream_name = "TWL6040",
|
||||
.codec_dai_name = "twl6040-legacy",
|
||||
.codec_name = "twl6040-codec",
|
||||
.init = omap_abe_twl6040_init,
|
||||
.ops = &omap_abe_ops,
|
||||
},
|
||||
{
|
||||
.name = "DMIC",
|
||||
.stream_name = "DMIC Capture",
|
||||
.codec_dai_name = "dmic-hifi",
|
||||
.codec_name = "dmic-codec",
|
||||
.init = omap_abe_dmic_init,
|
||||
.ops = &omap_abe_dmic_ops,
|
||||
},
|
||||
};
|
||||
|
||||
/* Audio machine driver */
|
||||
static struct snd_soc_card omap_abe_card = {
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
.dapm_widgets = twl6040_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
};
|
||||
|
||||
static int omap_abe_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct snd_soc_card *card = &omap_abe_card;
|
||||
struct snd_soc_card *card;
|
||||
struct device_node *dai_node;
|
||||
struct abe_twl6040 *priv;
|
||||
int num_links = 0;
|
||||
|
@ -252,12 +224,18 @@ static int omap_abe_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
card = &priv->card;
|
||||
card->dev = &pdev->dev;
|
||||
card->owner = THIS_MODULE;
|
||||
card->dapm_widgets = twl6040_dapm_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets);
|
||||
card->dapm_routes = audio_map;
|
||||
card->num_dapm_routes = ARRAY_SIZE(audio_map);
|
||||
|
||||
if (snd_soc_of_parse_card_name(card, "ti,model")) {
|
||||
dev_err(&pdev->dev, "Card name is not provided\n");
|
||||
return -ENODEV;
|
||||
|
@ -274,14 +252,27 @@ static int omap_abe_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "McPDM node is not provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
abe_twl6040_dai_links[0].cpu_of_node = dai_node;
|
||||
abe_twl6040_dai_links[0].platform_of_node = dai_node;
|
||||
|
||||
priv->dai_links[0].name = "DMIC";
|
||||
priv->dai_links[0].stream_name = "TWL6040";
|
||||
priv->dai_links[0].cpu_of_node = dai_node;
|
||||
priv->dai_links[0].platform_of_node = dai_node;
|
||||
priv->dai_links[0].codec_dai_name = "twl6040-legacy";
|
||||
priv->dai_links[0].codec_name = "twl6040-codec";
|
||||
priv->dai_links[0].init = omap_abe_twl6040_init;
|
||||
priv->dai_links[0].ops = &omap_abe_ops;
|
||||
|
||||
dai_node = of_parse_phandle(node, "ti,dmic", 0);
|
||||
if (dai_node) {
|
||||
num_links = 2;
|
||||
abe_twl6040_dai_links[1].cpu_of_node = dai_node;
|
||||
abe_twl6040_dai_links[1].platform_of_node = dai_node;
|
||||
priv->dai_links[1].name = "TWL6040";
|
||||
priv->dai_links[1].stream_name = "DMIC Capture";
|
||||
priv->dai_links[1].cpu_of_node = dai_node;
|
||||
priv->dai_links[1].platform_of_node = dai_node;
|
||||
priv->dai_links[1].codec_dai_name = "dmic-hifi";
|
||||
priv->dai_links[1].codec_name = "dmic-codec";
|
||||
priv->dai_links[1].init = omap_abe_dmic_init;
|
||||
priv->dai_links[1].ops = &omap_abe_dmic_ops;
|
||||
} else {
|
||||
num_links = 1;
|
||||
}
|
||||
|
@ -300,7 +291,7 @@ static int omap_abe_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
card->dai_link = abe_twl6040_dai_links;
|
||||
card->dai_link = priv->dai_links;
|
||||
card->num_links = num_links;
|
||||
|
||||
snd_soc_card_set_drvdata(card, priv);
|
||||
|
|
|
@ -48,6 +48,8 @@ struct omap_dmic {
|
|||
struct device *dev;
|
||||
void __iomem *io_base;
|
||||
struct clk *fclk;
|
||||
struct pm_qos_request pm_qos_req;
|
||||
int latency;
|
||||
int fclk_freq;
|
||||
int out_freq;
|
||||
int clk_div;
|
||||
|
@ -124,6 +126,8 @@ static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
|
|||
|
||||
mutex_lock(&dmic->mutex);
|
||||
|
||||
pm_qos_remove_request(&dmic->pm_qos_req);
|
||||
|
||||
if (!dai->active)
|
||||
dmic->active = 0;
|
||||
|
||||
|
@ -228,6 +232,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
/* packet size is threshold * channels */
|
||||
dma_data = snd_soc_dai_get_dma_data(dai, substream);
|
||||
dma_data->maxburst = dmic->threshold * channels;
|
||||
dmic->latency = (OMAP_DMIC_THRES_MAX - dmic->threshold) * USEC_PER_SEC /
|
||||
params_rate(params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -238,6 +244,9 @@ static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
|
|||
struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
|
||||
u32 ctrl;
|
||||
|
||||
if (pm_qos_request_active(&dmic->pm_qos_req))
|
||||
pm_qos_update_request(&dmic->pm_qos_req, dmic->latency);
|
||||
|
||||
/* Configure uplink threshold */
|
||||
omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold);
|
||||
|
||||
|
|
|
@ -308,9 +308,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
pkt_size = channels;
|
||||
}
|
||||
|
||||
latency = ((((buffer_size - pkt_size) / channels) * 1000)
|
||||
/ (params->rate_num / params->rate_den));
|
||||
|
||||
latency = (buffer_size - pkt_size) / channels;
|
||||
latency = latency * USEC_PER_SEC /
|
||||
(params->rate_num / params->rate_den);
|
||||
mcbsp->latency[substream->stream] = latency;
|
||||
|
||||
omap_mcbsp_set_threshold(substream, pkt_size);
|
||||
|
|
|
@ -54,6 +54,8 @@ struct omap_mcpdm {
|
|||
unsigned long phys_base;
|
||||
void __iomem *io_base;
|
||||
int irq;
|
||||
struct pm_qos_request pm_qos_req;
|
||||
int latency[2];
|
||||
|
||||
struct mutex mutex;
|
||||
|
||||
|
@ -277,6 +279,9 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
|
||||
int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
||||
int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
|
||||
int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
|
||||
|
||||
mutex_lock(&mcpdm->mutex);
|
||||
|
||||
|
@ -289,6 +294,14 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
|
|||
}
|
||||
}
|
||||
|
||||
if (mcpdm->latency[stream2])
|
||||
pm_qos_update_request(&mcpdm->pm_qos_req,
|
||||
mcpdm->latency[stream2]);
|
||||
else if (mcpdm->latency[stream1])
|
||||
pm_qos_remove_request(&mcpdm->pm_qos_req);
|
||||
|
||||
mcpdm->latency[stream1] = 0;
|
||||
|
||||
mutex_unlock(&mcpdm->mutex);
|
||||
}
|
||||
|
||||
|
@ -300,7 +313,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
int stream = substream->stream;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
u32 threshold;
|
||||
int channels;
|
||||
int channels, latency;
|
||||
int link_mask = 0;
|
||||
|
||||
channels = params_channels(params);
|
||||
|
@ -344,14 +357,25 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
dma_data->maxburst =
|
||||
(MCPDM_DN_THRES_MAX - threshold) * channels;
|
||||
latency = threshold;
|
||||
} else {
|
||||
/* If playback is not running assume a stereo stream to come */
|
||||
if (!mcpdm->config[!stream].link_mask)
|
||||
mcpdm->config[!stream].link_mask = (0x3 << 3);
|
||||
|
||||
dma_data->maxburst = threshold * channels;
|
||||
latency = (MCPDM_DN_THRES_MAX - threshold);
|
||||
}
|
||||
|
||||
/*
|
||||
* The DMA must act to a DMA request within latency time (usec) to avoid
|
||||
* under/overflow
|
||||
*/
|
||||
mcpdm->latency[stream] = latency * USEC_PER_SEC / params_rate(params);
|
||||
|
||||
if (!mcpdm->latency[stream])
|
||||
mcpdm->latency[stream] = 10;
|
||||
|
||||
/* Check if we need to restart McPDM with this stream */
|
||||
if (mcpdm->config[stream].link_mask &&
|
||||
mcpdm->config[stream].link_mask != link_mask)
|
||||
|
@ -366,6 +390,20 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
|
||||
struct pm_qos_request *pm_qos_req = &mcpdm->pm_qos_req;
|
||||
int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
||||
int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
|
||||
int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
|
||||
int latency = mcpdm->latency[stream2];
|
||||
|
||||
/* Prevent omap hardware from hitting off between FIFO fills */
|
||||
if (!latency || mcpdm->latency[stream1] < latency)
|
||||
latency = mcpdm->latency[stream1];
|
||||
|
||||
if (pm_qos_request_active(pm_qos_req))
|
||||
pm_qos_update_request(pm_qos_req, latency);
|
||||
else if (latency)
|
||||
pm_qos_add_request(pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency);
|
||||
|
||||
if (!omap_mcpdm_active(mcpdm)) {
|
||||
omap_mcpdm_start(mcpdm);
|
||||
|
@ -427,6 +465,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
|
|||
free_irq(mcpdm->irq, (void *)mcpdm);
|
||||
pm_runtime_disable(mcpdm->dev);
|
||||
|
||||
if (pm_qos_request_active(&mcpdm->pm_qos_req))
|
||||
pm_qos_remove_request(&mcpdm->pm_qos_req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
|
|||
struct device_node *cpu = NULL;
|
||||
struct device *dev = card->dev;
|
||||
struct snd_soc_dai_link *link;
|
||||
struct of_phandle_args args;
|
||||
int ret, num_links;
|
||||
|
||||
ret = snd_soc_of_parse_card_name(card, "model");
|
||||
|
@ -47,12 +48,14 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
|
|||
goto err;
|
||||
}
|
||||
|
||||
link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
|
||||
if (!link->cpu_of_node) {
|
||||
ret = of_parse_phandle_with_args(cpu, "sound-dai",
|
||||
"#sound-dai-cells", 0, &args);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "error getting cpu phandle\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
link->cpu_of_node = args.np;
|
||||
link->id = args.args[0];
|
||||
|
||||
ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
|
||||
if (ret) {
|
||||
|
|
|
@ -1112,204 +1112,204 @@ static int q6afe_of_xlate_dai_name(struct snd_soc_component *component,
|
|||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = {
|
||||
SND_SOC_DAPM_AIF_OUT("HDMI_RX", "HDMI Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback",
|
||||
SND_SOC_DAPM_AIF_IN("HDMI_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_0_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_1_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_2_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_3_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_4_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_5_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SLIMBUS_6_RX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_TX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_TX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_TX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_TX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_TX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_TX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_TX", NULL, 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_MI2S_RX", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_TX", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_MI2S_RX", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_MI2S_TX", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_MI2S_TX", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX_SD1",
|
||||
"Secondary MI2S Playback SD1",
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRI_MI2S_RX", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRI_MI2S_TX", NULL,
|
||||
0, 0, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_0", "Primary TDM0 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_1", "Primary TDM1 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_2", "Primary TDM2 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_3", "Primary TDM3 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_4", "Primary TDM4 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_5", "Primary TDM5 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_6", "Primary TDM6 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_7", "Primary TDM7 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_0", "Primary TDM0 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_1", "Primary TDM1 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_2", "Primary TDM2 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_3", "Primary TDM3 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_4", "Primary TDM4 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_5", "Primary TDM5 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_6", "Primary TDM6 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_7", "Primary TDM7 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback",
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6", NULL,
|
||||
0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture",
|
||||
SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL,
|
||||
0, 0, 0, 0),
|
||||
};
|
||||
|
||||
|
|
|
@ -49,14 +49,14 @@
|
|||
#define AFE_PORT_I2S_SD1 0x2
|
||||
#define AFE_PORT_I2S_SD2 0x3
|
||||
#define AFE_PORT_I2S_SD3 0x4
|
||||
#define AFE_PORT_I2S_SD0_MASK BIT(0x1)
|
||||
#define AFE_PORT_I2S_SD1_MASK BIT(0x2)
|
||||
#define AFE_PORT_I2S_SD2_MASK BIT(0x3)
|
||||
#define AFE_PORT_I2S_SD3_MASK BIT(0x4)
|
||||
#define AFE_PORT_I2S_SD0_1_MASK GENMASK(2, 1)
|
||||
#define AFE_PORT_I2S_SD2_3_MASK GENMASK(4, 3)
|
||||
#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(3, 1)
|
||||
#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(4, 1)
|
||||
#define AFE_PORT_I2S_SD0_MASK BIT(0x0)
|
||||
#define AFE_PORT_I2S_SD1_MASK BIT(0x1)
|
||||
#define AFE_PORT_I2S_SD2_MASK BIT(0x2)
|
||||
#define AFE_PORT_I2S_SD3_MASK BIT(0x3)
|
||||
#define AFE_PORT_I2S_SD0_1_MASK GENMASK(1, 0)
|
||||
#define AFE_PORT_I2S_SD2_3_MASK GENMASK(3, 2)
|
||||
#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(2, 0)
|
||||
#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(3, 0)
|
||||
#define AFE_PORT_I2S_QUAD01 0x5
|
||||
#define AFE_PORT_I2S_QUAD23 0x6
|
||||
#define AFE_PORT_I2S_6CHS 0x7
|
||||
|
|
|
@ -122,7 +122,6 @@ static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
|
|||
.rate_max = 48000, \
|
||||
}, \
|
||||
.name = "MultiMedia"#num, \
|
||||
.probe = fe_dai_probe, \
|
||||
.id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \
|
||||
}
|
||||
|
||||
|
@ -511,38 +510,6 @@ static void q6asm_dai_pcm_free(struct snd_pcm *pcm)
|
|||
}
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_route afe_pcm_routes[] = {
|
||||
{"MM_DL1", NULL, "MultiMedia1 Playback" },
|
||||
{"MM_DL2", NULL, "MultiMedia2 Playback" },
|
||||
{"MM_DL3", NULL, "MultiMedia3 Playback" },
|
||||
{"MM_DL4", NULL, "MultiMedia4 Playback" },
|
||||
{"MM_DL5", NULL, "MultiMedia5 Playback" },
|
||||
{"MM_DL6", NULL, "MultiMedia6 Playback" },
|
||||
{"MM_DL7", NULL, "MultiMedia7 Playback" },
|
||||
{"MM_DL7", NULL, "MultiMedia8 Playback" },
|
||||
{"MultiMedia1 Capture", NULL, "MM_UL1"},
|
||||
{"MultiMedia2 Capture", NULL, "MM_UL2"},
|
||||
{"MultiMedia3 Capture", NULL, "MM_UL3"},
|
||||
{"MultiMedia4 Capture", NULL, "MM_UL4"},
|
||||
{"MultiMedia5 Capture", NULL, "MM_UL5"},
|
||||
{"MultiMedia6 Capture", NULL, "MM_UL6"},
|
||||
{"MultiMedia7 Capture", NULL, "MM_UL7"},
|
||||
{"MultiMedia8 Capture", NULL, "MM_UL8"},
|
||||
|
||||
};
|
||||
|
||||
static int fe_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm;
|
||||
|
||||
dapm = snd_soc_component_get_dapm(dai->component);
|
||||
snd_soc_dapm_add_routes(dapm, afe_pcm_routes,
|
||||
ARRAY_SIZE(afe_pcm_routes));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct snd_soc_component_driver q6asm_fe_dai_component = {
|
||||
.name = DRV_NAME,
|
||||
.ops = &q6asm_dai_ops,
|
||||
|
|
|
@ -909,6 +909,25 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"MM_UL6", NULL, "MultiMedia6 Mixer"},
|
||||
{"MM_UL7", NULL, "MultiMedia7 Mixer"},
|
||||
{"MM_UL8", NULL, "MultiMedia8 Mixer"},
|
||||
|
||||
{"MM_DL1", NULL, "MultiMedia1 Playback" },
|
||||
{"MM_DL2", NULL, "MultiMedia2 Playback" },
|
||||
{"MM_DL3", NULL, "MultiMedia3 Playback" },
|
||||
{"MM_DL4", NULL, "MultiMedia4 Playback" },
|
||||
{"MM_DL5", NULL, "MultiMedia5 Playback" },
|
||||
{"MM_DL6", NULL, "MultiMedia6 Playback" },
|
||||
{"MM_DL7", NULL, "MultiMedia7 Playback" },
|
||||
{"MM_DL8", NULL, "MultiMedia8 Playback" },
|
||||
|
||||
{"MultiMedia1 Capture", NULL, "MM_UL1"},
|
||||
{"MultiMedia2 Capture", NULL, "MM_UL2"},
|
||||
{"MultiMedia3 Capture", NULL, "MM_UL3"},
|
||||
{"MultiMedia4 Capture", NULL, "MM_UL4"},
|
||||
{"MultiMedia5 Capture", NULL, "MM_UL5"},
|
||||
{"MultiMedia6 Capture", NULL, "MM_UL6"},
|
||||
{"MultiMedia7 Capture", NULL, "MM_UL7"},
|
||||
{"MultiMedia8 Capture", NULL, "MM_UL8"},
|
||||
|
||||
};
|
||||
|
||||
static int routing_hw_params(struct snd_pcm_substream *substream,
|
||||
|
|
|
@ -33,6 +33,7 @@ static const struct snd_pcm_hardware snd_rockchip_hardware = {
|
|||
|
||||
static const struct snd_dmaengine_pcm_config rk_dmaengine_pcm_config = {
|
||||
.pcm_hardware = &snd_rockchip_hardware,
|
||||
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
|
||||
.prealloc_buffer_size = 32 * 1024,
|
||||
};
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
|
|||
if (rsnd_ssi_is_multi_slave(mod, io))
|
||||
return 0;
|
||||
|
||||
if (ssi->rate) {
|
||||
if (ssi->usrcnt > 1) {
|
||||
if (ssi->rate != rate) {
|
||||
dev_err(dev, "SSI parent/child should use same rate\n");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -10,11 +10,17 @@ struct snd_soc_acpi_mach *
|
|||
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
|
||||
{
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
struct snd_soc_acpi_mach *mach_alt;
|
||||
|
||||
for (mach = machines; mach->id[0]; mach++) {
|
||||
if (acpi_dev_present(mach->id, NULL, -1)) {
|
||||
if (mach->machine_quirk)
|
||||
mach = mach->machine_quirk(mach);
|
||||
if (mach->machine_quirk) {
|
||||
mach_alt = mach->machine_quirk(mach);
|
||||
if (!mach_alt)
|
||||
continue; /* not full match, ignore */
|
||||
mach = mach_alt;
|
||||
}
|
||||
|
||||
return mach;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2131,6 +2131,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
|
|||
}
|
||||
|
||||
card->instantiated = 1;
|
||||
dapm_mark_endpoints_dirty(card);
|
||||
snd_soc_dapm_sync(&card->dapm);
|
||||
mutex_unlock(&card->mutex);
|
||||
mutex_unlock(&client_mutex);
|
||||
|
|
|
@ -390,7 +390,7 @@ static int stm32_sai_add_mclk_provider(struct stm32_sai_sub_data *sai)
|
|||
char *mclk_name, *p, *s = (char *)pname;
|
||||
int ret, i = 0;
|
||||
|
||||
mclk = devm_kzalloc(dev, sizeof(mclk), GFP_KERNEL);
|
||||
mclk = devm_kzalloc(dev, sizeof(*mclk), GFP_KERNEL);
|
||||
if (!mclk)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ config SND_SUN8I_CODEC_ANALOG
|
|||
config SND_SUN50I_CODEC_ANALOG
|
||||
tristate "Allwinner sun50i Codec Analog Controls Support"
|
||||
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
select SND_SUNXI_ADDA_PR_REGMAP
|
||||
select SND_SUN8I_ADDA_PR_REGMAP
|
||||
help
|
||||
Say Y or M if you want to add support for the analog controls for
|
||||
the codec embedded in Allwinner A64 SoC.
|
||||
|
|
|
@ -481,7 +481,11 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
|
|||
{ "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch",
|
||||
"AIF1 Slot 0 Right"},
|
||||
|
||||
/* ADC routes */
|
||||
/* ADC Routes */
|
||||
{ "AIF1 Slot 0 Right ADC", NULL, "ADC" },
|
||||
{ "AIF1 Slot 0 Left ADC", NULL, "ADC" },
|
||||
|
||||
/* ADC Mixer Routes */
|
||||
{ "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch",
|
||||
"AIF1 Slot 0 Left ADC" },
|
||||
{ "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch",
|
||||
|
@ -605,16 +609,10 @@ static int sun8i_codec_probe(struct platform_device *pdev)
|
|||
|
||||
static int sun8i_codec_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||
struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
sun8i_codec_runtime_suspend(&pdev->dev);
|
||||
|
||||
clk_disable_unprepare(scodec->clk_module);
|
||||
clk_disable_unprepare(scodec->clk_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1146,10 +1146,8 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
|
|||
runtime->hw = snd_cs4231_playback;
|
||||
|
||||
err = snd_cs4231_open(chip, CS4231_MODE_PLAY);
|
||||
if (err < 0) {
|
||||
snd_free_pages(runtime->dma_area, runtime->dma_bytes);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
chip->playback_substream = substream;
|
||||
chip->p_periods_sent = 0;
|
||||
snd_pcm_set_sync(substream);
|
||||
|
@ -1167,10 +1165,8 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
|
|||
runtime->hw = snd_cs4231_capture;
|
||||
|
||||
err = snd_cs4231_open(chip, CS4231_MODE_RECORD);
|
||||
if (err < 0) {
|
||||
snd_free_pages(runtime->dma_area, runtime->dma_bytes);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
chip->capture_substream = substream;
|
||||
chip->c_periods_sent = 0;
|
||||
snd_pcm_set_sync(substream);
|
||||
|
|
|
@ -3382,5 +3382,15 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
|
|||
.ifnum = QUIRK_NO_INTERFACE
|
||||
}
|
||||
},
|
||||
/* Dell WD19 Dock */
|
||||
{
|
||||
USB_DEVICE(0x0bda, 0x402e),
|
||||
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Dell",
|
||||
.product_name = "WD19 Dock",
|
||||
.profile_name = "Dell-WD15-Dock",
|
||||
.ifnum = QUIRK_NO_INTERFACE
|
||||
}
|
||||
},
|
||||
|
||||
#undef USB_DEVICE_VENDOR_SPEC
|
||||
|
|
Loading…
Reference in New Issue