mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 09:20:50 +07:00
Sound fixes for 3.8-rc1
This update contains overall only driver-specific fixes. Slightly large LOC are seen in usb-audio driver for a couple of new device quirks and cs42l71 ASoC driver for enhanced features. The others are a few small (regression) fixes HD-audio, and yet other small / trival ASoC fixes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJQ0thSAAoJEGwxgFQ9KSmk/i8P+wcdjCcp5FdfZ5YP2h9siEw5 7KJPwwk9eTa0PVB5olgabxSh6L5P+rM69OGiXnHSKF8RwsuZDRp/5pPcaoUVRzH/ 6uibGozfLApeLBuBAJZ96eJhRIigysoSrm5W4FQeNVAbwK67zpIjP/xGwKa0+qfO vsK/BtSn+nVsmFpgOfO6vXZ7gKBlfKGXHYdyFVXzHEhGYSHLdf1IDxnCapIXlh78 0nXHD2FHgKlSM6y/S6W7wiUwyNqbgmnZHwh29iIyes1CrX0wVyvtos3qgwJHukrU WVY87E1TDxD6HLAWTUxqeOIvNyucSarUZ+kvtYg0i31gmRCY8QNXqYVp1wBybqVd Uwbwe4qWwSxXhXluodFsizNwcH9T+KA3IM4B5u6yCT1pFY759pCh/KpLoNfD+maL 6atnBU6lvtTCMxoeSyJFSdAjdOQJUpylQ9TyQaI/PIr6jrEMVC2ki/i3UX+YpQGo oWJj5x8Nl58MUv7GhYGTo7vfm3ZqaUbxN/YugbCeVkrcV0McJNycvddotplD4iTd pqfep1fVpefW9X4pJnvsys2neo7R8e8a87Qg2CfVGXQ91ijevPCf+YAh4EmHShsT vwNcOP/gZ+qQp/bY40SigMj5SZtZ/ZQxT47yPo6OLI4FyhyD+WK4l1AAEK5B1uPA odsIcQg2F6/RjzkDSsSl =JoY5 -----END PGP SIGNATURE----- Merge tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "This update contains overall only driver-specific fixes. Slightly large LOC are seen in usb-audio driver for a couple of new device quirks and cs42l71 ASoC driver for enhanced features. The others are a few small (regression) fixes HD-audio, and yet other small / trival ASoC fixes." * tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: usb-audio: Support for Digidesign Mbox 2 USB sound card: ALSA: HDA: Fix sound resume hang ALSA: hda - bug fix for invalid connection list of Haswell HDMI codec pins ALSA: hda - Fix the wrong pincaps set in ALC861VD dallas/hp fixup ALSA: hda - Set codec->single_adc_amp flag for Realtek codecs ASoC: atmel-ssc: change disable to disable in dts node ASoC: Prevent pop_wait overwrite ALSA: usb-audio: ignore-quirk for HP Wireless Audio ALSA: hda - Always turn on pins for HDMI/DP ALSA: hda - Fix pin configuration of HP Pavilion dv7 ASoC: core: Fix splitting of log messages ASoC: cs42l73: Change VSPIN/VSPOUT to VSPINOUT ASoC: cs42l73: Add DAPM events for power down. ASoC: cs42l73: Add DMIC's as DAPM inputs. ASoC: sigmadsp: Fix endianness conversion issue ASoC: tpa6130a2: Use devm_* APIs
This commit is contained in:
commit
03c850ec32
@ -368,14 +368,14 @@ ssc0: ssc@fff98000 {
|
|||||||
compatible = "atmel,at91rm9200-ssc";
|
compatible = "atmel,at91rm9200-ssc";
|
||||||
reg = <0xfff98000 0x4000>;
|
reg = <0xfff98000 0x4000>;
|
||||||
interrupts = <16 4 5>;
|
interrupts = <16 4 5>;
|
||||||
status = "disable";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
ssc1: ssc@fff9c000 {
|
ssc1: ssc@fff9c000 {
|
||||||
compatible = "atmel,at91rm9200-ssc";
|
compatible = "atmel,at91rm9200-ssc";
|
||||||
reg = <0xfff9c000 0x4000>;
|
reg = <0xfff9c000 0x4000>;
|
||||||
interrupts = <17 4 5>;
|
interrupts = <17 4 5>;
|
||||||
status = "disable";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
macb0: ethernet@fffbc000 {
|
macb0: ethernet@fffbc000 {
|
||||||
|
@ -425,14 +425,14 @@ ssc0: ssc@fff9c000 {
|
|||||||
compatible = "atmel,at91sam9g45-ssc";
|
compatible = "atmel,at91sam9g45-ssc";
|
||||||
reg = <0xfff9c000 0x4000>;
|
reg = <0xfff9c000 0x4000>;
|
||||||
interrupts = <16 4 5>;
|
interrupts = <16 4 5>;
|
||||||
status = "disable";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
ssc1: ssc@fffa0000 {
|
ssc1: ssc@fffa0000 {
|
||||||
compatible = "atmel,at91sam9g45-ssc";
|
compatible = "atmel,at91sam9g45-ssc";
|
||||||
reg = <0xfffa0000 0x4000>;
|
reg = <0xfffa0000 0x4000>;
|
||||||
interrupts = <17 4 5>;
|
interrupts = <17 4 5>;
|
||||||
status = "disable";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
adc0: adc@fffb0000 {
|
adc0: adc@fffb0000 {
|
||||||
|
@ -92,7 +92,7 @@ ssc0: ssc@f0010000 {
|
|||||||
compatible = "atmel,at91sam9g45-ssc";
|
compatible = "atmel,at91sam9g45-ssc";
|
||||||
reg = <0xf0010000 0x4000>;
|
reg = <0xf0010000 0x4000>;
|
||||||
interrupts = <28 4 5>;
|
interrupts = <28 4 5>;
|
||||||
status = "disable";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
tcb0: timer@f8008000 {
|
tcb0: timer@f8008000 {
|
||||||
|
@ -242,7 +242,6 @@ struct snd_soc_dai {
|
|||||||
unsigned int symmetric_rates:1;
|
unsigned int symmetric_rates:1;
|
||||||
struct snd_pcm_runtime *runtime;
|
struct snd_pcm_runtime *runtime;
|
||||||
unsigned int active;
|
unsigned int active;
|
||||||
unsigned char pop_wait:1;
|
|
||||||
unsigned char probed:1;
|
unsigned char probed:1;
|
||||||
|
|
||||||
struct snd_soc_dapm_widget *playback_widget;
|
struct snd_soc_dapm_widget *playback_widget;
|
||||||
|
@ -1039,6 +1039,7 @@ struct snd_soc_pcm_runtime {
|
|||||||
struct snd_soc_dpcm_runtime dpcm[2];
|
struct snd_soc_dpcm_runtime dpcm[2];
|
||||||
|
|
||||||
long pmdown_time;
|
long pmdown_time;
|
||||||
|
unsigned char pop_wait:1;
|
||||||
|
|
||||||
/* runtime devices */
|
/* runtime devices */
|
||||||
struct snd_pcm *pcm;
|
struct snd_pcm *pcm;
|
||||||
|
@ -2876,7 +2876,7 @@ static int azx_free(struct azx *chip)
|
|||||||
azx_notifier_unregister(chip);
|
azx_notifier_unregister(chip);
|
||||||
|
|
||||||
chip->init_failed = 1; /* to be sure */
|
chip->init_failed = 1; /* to be sure */
|
||||||
complete(&chip->probe_wait);
|
complete_all(&chip->probe_wait);
|
||||||
|
|
||||||
if (use_vga_switcheroo(chip)) {
|
if (use_vga_switcheroo(chip)) {
|
||||||
if (chip->disabled && chip->bus)
|
if (chip->disabled && chip->bus)
|
||||||
@ -3504,7 +3504,7 @@ static int azx_probe(struct pci_dev *pci,
|
|||||||
pm_runtime_put_noidle(&pci->dev);
|
pm_runtime_put_noidle(&pci->dev);
|
||||||
|
|
||||||
dev++;
|
dev++;
|
||||||
complete(&chip->probe_wait);
|
complete_all(&chip->probe_wait);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
|
@ -431,9 +431,11 @@ static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
|
|||||||
if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
|
if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
|
||||||
snd_hda_codec_write(codec, pin_nid, 0,
|
snd_hda_codec_write(codec, pin_nid, 0,
|
||||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
|
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
|
||||||
/* Disable pin out until stream is active*/
|
/* Enable pin out: some machines with GM965 gets broken output when
|
||||||
|
* the pin is disabled or changed while using with HDMI
|
||||||
|
*/
|
||||||
snd_hda_codec_write(codec, pin_nid, 0,
|
snd_hda_codec_write(codec, pin_nid, 0,
|
||||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
|
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
|
static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
|
||||||
@ -1341,7 +1343,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
|||||||
struct hdmi_spec *spec = codec->spec;
|
struct hdmi_spec *spec = codec->spec;
|
||||||
int pin_idx = hinfo_to_pin_index(spec, hinfo);
|
int pin_idx = hinfo_to_pin_index(spec, hinfo);
|
||||||
hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
|
hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
|
||||||
int pinctl;
|
|
||||||
bool non_pcm;
|
bool non_pcm;
|
||||||
|
|
||||||
non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
|
non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
|
||||||
@ -1350,11 +1351,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
|||||||
|
|
||||||
hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream);
|
hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream);
|
||||||
|
|
||||||
pinctl = snd_hda_codec_read(codec, pin_nid, 0,
|
|
||||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
||||||
snd_hda_codec_write(codec, pin_nid, 0,
|
|
||||||
AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT);
|
|
||||||
|
|
||||||
return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
|
return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1374,7 +1370,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
|
|||||||
int cvt_idx, pin_idx;
|
int cvt_idx, pin_idx;
|
||||||
struct hdmi_spec_per_cvt *per_cvt;
|
struct hdmi_spec_per_cvt *per_cvt;
|
||||||
struct hdmi_spec_per_pin *per_pin;
|
struct hdmi_spec_per_pin *per_pin;
|
||||||
int pinctl;
|
|
||||||
|
|
||||||
if (hinfo->nid) {
|
if (hinfo->nid) {
|
||||||
cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
|
cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
|
||||||
@ -1391,11 +1386,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
per_pin = &spec->pins[pin_idx];
|
per_pin = &spec->pins[pin_idx];
|
||||||
|
|
||||||
pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
|
|
||||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
||||||
snd_hda_codec_write(codec, per_pin->pin_nid, 0,
|
|
||||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
||||||
pinctl & ~PIN_OUT);
|
|
||||||
snd_hda_spdif_ctls_unassign(codec, pin_idx);
|
snd_hda_spdif_ctls_unassign(codec, pin_idx);
|
||||||
per_pin->chmap_set = false;
|
per_pin->chmap_set = false;
|
||||||
memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
|
memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
|
||||||
@ -1691,6 +1681,30 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
|
|||||||
.unsol_event = hdmi_unsol_event,
|
.unsol_event = hdmi_unsol_event,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void intel_haswell_fixup_connect_list(struct hda_codec *codec)
|
||||||
|
{
|
||||||
|
unsigned int vendor_param;
|
||||||
|
hda_nid_t list[3] = {0x2, 0x3, 0x4};
|
||||||
|
|
||||||
|
vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0);
|
||||||
|
if (vendor_param == -1 || vendor_param & 0x02)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* enable DP1.2 mode */
|
||||||
|
vendor_param |= 0x02;
|
||||||
|
snd_hda_codec_read(codec, 0x08, 0, 0x781, vendor_param);
|
||||||
|
|
||||||
|
vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0);
|
||||||
|
if (vendor_param == -1 || !(vendor_param & 0x02))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* override 3 pins connection list */
|
||||||
|
snd_hda_override_conn_list(codec, 0x05, 3, list);
|
||||||
|
snd_hda_override_conn_list(codec, 0x06, 3, list);
|
||||||
|
snd_hda_override_conn_list(codec, 0x07, 3, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int patch_generic_hdmi(struct hda_codec *codec)
|
static int patch_generic_hdmi(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct hdmi_spec *spec;
|
struct hdmi_spec *spec;
|
||||||
@ -1700,6 +1714,10 @@ static int patch_generic_hdmi(struct hda_codec *codec)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
codec->spec = spec;
|
codec->spec = spec;
|
||||||
|
|
||||||
|
if (codec->vendor_id == 0x80862807)
|
||||||
|
intel_haswell_fixup_connect_list(codec);
|
||||||
|
|
||||||
if (hdmi_parse_codec(codec) < 0) {
|
if (hdmi_parse_codec(codec) < 0) {
|
||||||
codec->spec = NULL;
|
codec->spec = NULL;
|
||||||
kfree(spec);
|
kfree(spec);
|
||||||
|
@ -4373,6 +4373,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
|
|||||||
if (!spec)
|
if (!spec)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
codec->spec = spec;
|
codec->spec = spec;
|
||||||
|
codec->single_adc_amp = 1;
|
||||||
spec->mixer_nid = mixer_nid;
|
spec->mixer_nid = mixer_nid;
|
||||||
snd_hda_gen_init(&spec->gen);
|
snd_hda_gen_init(&spec->gen);
|
||||||
snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
|
snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
|
||||||
@ -6569,8 +6570,8 @@ static void alc861vd_fixup_dallas(struct hda_codec *codec,
|
|||||||
const struct alc_fixup *fix, int action)
|
const struct alc_fixup *fix, int action)
|
||||||
{
|
{
|
||||||
if (action == ALC_FIXUP_ACT_PRE_PROBE) {
|
if (action == ALC_FIXUP_ACT_PRE_PROBE) {
|
||||||
snd_hda_override_pin_caps(codec, 0x18, 0x00001714);
|
snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
|
||||||
snd_hda_override_pin_caps(codec, 0x19, 0x0000171c);
|
snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1725,7 +1725,7 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
|
|||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
|
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
|
||||||
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
|
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
|
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
|
||||||
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
|
"HP Pavilion dv7", STAC_HP_DV7_4000),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
|
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
|
||||||
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
|
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
|
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
|
||||||
|
@ -40,6 +40,7 @@ struct cs42l73_private {
|
|||||||
u32 sysclk;
|
u32 sysclk;
|
||||||
u8 mclksel;
|
u8 mclksel;
|
||||||
u32 mclk;
|
u32 mclk;
|
||||||
|
int shutdwn_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default cs42l73_reg_defaults[] = {
|
static const struct reg_default cs42l73_reg_defaults[] = {
|
||||||
@ -588,7 +589,60 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
|
|||||||
SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
|
SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
|
{
|
||||||
|
struct snd_soc_codec *codec = w->codec;
|
||||||
|
struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
|
/* 150 ms delay between setting PDN and MCLKDIS */
|
||||||
|
priv->shutdwn_delay = 150;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Invalid event = 0x%x\n", event);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
|
{
|
||||||
|
struct snd_soc_codec *codec = w->codec;
|
||||||
|
struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
|
/* 50 ms delay between setting PDN and MCLKDIS */
|
||||||
|
if (priv->shutdwn_delay < 50)
|
||||||
|
priv->shutdwn_delay = 50;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Invalid event = 0x%x\n", event);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
|
{
|
||||||
|
struct snd_soc_codec *codec = w->codec;
|
||||||
|
struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
|
/* 30 ms delay between setting PDN and MCLKDIS */
|
||||||
|
if (priv->shutdwn_delay < 30)
|
||||||
|
priv->shutdwn_delay = 30;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Invalid event = 0x%x\n", event);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
|
static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
|
||||||
|
SND_SOC_DAPM_INPUT("DMICA"),
|
||||||
|
SND_SOC_DAPM_INPUT("DMICB"),
|
||||||
SND_SOC_DAPM_INPUT("LINEINA"),
|
SND_SOC_DAPM_INPUT("LINEINA"),
|
||||||
SND_SOC_DAPM_INPUT("LINEINB"),
|
SND_SOC_DAPM_INPUT("LINEINB"),
|
||||||
SND_SOC_DAPM_INPUT("MIC1"),
|
SND_SOC_DAPM_INPUT("MIC1"),
|
||||||
@ -604,9 +658,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
|
|||||||
CS42L73_PWRCTL2, 3, 1),
|
CS42L73_PWRCTL2, 3, 1),
|
||||||
SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0,
|
SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0,
|
||||||
CS42L73_PWRCTL2, 3, 1),
|
CS42L73_PWRCTL2, 3, 1),
|
||||||
SND_SOC_DAPM_AIF_OUT("VSPOUTL", NULL, 0,
|
SND_SOC_DAPM_AIF_OUT("VSPINOUT", NULL, 0,
|
||||||
CS42L73_PWRCTL2, 4, 1),
|
|
||||||
SND_SOC_DAPM_AIF_OUT("VSPOUTR", NULL, 0,
|
|
||||||
CS42L73_PWRCTL2, 4, 1),
|
CS42L73_PWRCTL2, 4, 1),
|
||||||
|
|
||||||
SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
@ -632,8 +684,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_MIXER("VSP Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
|
||||||
|
|
||||||
SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0,
|
SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0,
|
||||||
CS42L73_PWRCTL2, 0, 1),
|
CS42L73_PWRCTL2, 0, 1),
|
||||||
@ -649,7 +700,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0,
|
SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0,
|
||||||
CS42L73_PWRCTL2, 2, 1),
|
CS42L73_PWRCTL2, 2, 1),
|
||||||
|
|
||||||
SND_SOC_DAPM_AIF_IN("VSPIN", NULL, 0,
|
SND_SOC_DAPM_AIF_IN("VSPINOUT", NULL, 0,
|
||||||
CS42L73_PWRCTL2, 4, 1),
|
CS42L73_PWRCTL2, 4, 1),
|
||||||
|
|
||||||
SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
@ -674,16 +725,20 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||||
|
|
||||||
SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1,
|
SND_SOC_DAPM_SWITCH_E("HP Amp", CS42L73_PWRCTL3, 0, 1,
|
||||||
&hp_amp_ctl),
|
&hp_amp_ctl, cs42l73_hp_amp_event,
|
||||||
|
SND_SOC_DAPM_POST_PMD),
|
||||||
SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
|
SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
|
||||||
&lo_amp_ctl),
|
&lo_amp_ctl),
|
||||||
SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1,
|
SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1,
|
||||||
&spk_amp_ctl),
|
&spk_amp_ctl, cs42l73_spklo_spk_amp_event,
|
||||||
SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1,
|
SND_SOC_DAPM_POST_PMD),
|
||||||
&ear_amp_ctl),
|
SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1,
|
||||||
SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
|
&ear_amp_ctl, cs42l73_ear_amp_event,
|
||||||
&spklo_amp_ctl),
|
SND_SOC_DAPM_POST_PMD),
|
||||||
|
SND_SOC_DAPM_SWITCH_E("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
|
||||||
|
&spklo_amp_ctl, cs42l73_spklo_spk_amp_event,
|
||||||
|
SND_SOC_DAPM_POST_PMD),
|
||||||
|
|
||||||
SND_SOC_DAPM_OUTPUT("HPOUTA"),
|
SND_SOC_DAPM_OUTPUT("HPOUTA"),
|
||||||
SND_SOC_DAPM_OUTPUT("HPOUTB"),
|
SND_SOC_DAPM_OUTPUT("HPOUTB"),
|
||||||
@ -705,7 +760,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
|
|||||||
|
|
||||||
{"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"},
|
{"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"},
|
||||||
{"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"},
|
{"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"},
|
||||||
{"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"},
|
{"ESL DAC", "ESL-VSP Mono Volume", "VSPINOUT"},
|
||||||
/* Loopback */
|
/* Loopback */
|
||||||
{"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"},
|
{"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"},
|
||||||
{"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"},
|
{"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"},
|
||||||
@ -727,7 +782,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
|
|||||||
|
|
||||||
{"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"},
|
{"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"},
|
||||||
{"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"},
|
{"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"},
|
||||||
{"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"},
|
{"SPK DAC", "SPK-VSP Mono Volume", "VSPINOUT"},
|
||||||
/* Loopback */
|
/* Loopback */
|
||||||
{"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"},
|
{"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"},
|
||||||
{"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"},
|
{"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"},
|
||||||
@ -770,8 +825,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
|
|||||||
{"HL Right Mixer", NULL, "ASPINR"},
|
{"HL Right Mixer", NULL, "ASPINR"},
|
||||||
{"HL Left Mixer", NULL, "XSPINL"},
|
{"HL Left Mixer", NULL, "XSPINL"},
|
||||||
{"HL Right Mixer", NULL, "XSPINR"},
|
{"HL Right Mixer", NULL, "XSPINR"},
|
||||||
{"HL Left Mixer", NULL, "VSPIN"},
|
{"HL Left Mixer", NULL, "VSPINOUT"},
|
||||||
{"HL Right Mixer", NULL, "VSPIN"},
|
{"HL Right Mixer", NULL, "VSPINOUT"},
|
||||||
|
|
||||||
{"ASPINL", NULL, "ASP Playback"},
|
{"ASPINL", NULL, "ASP Playback"},
|
||||||
{"ASPINM", NULL, "ASP Playback"},
|
{"ASPINM", NULL, "ASP Playback"},
|
||||||
@ -779,7 +834,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
|
|||||||
{"XSPINL", NULL, "XSP Playback"},
|
{"XSPINL", NULL, "XSP Playback"},
|
||||||
{"XSPINM", NULL, "XSP Playback"},
|
{"XSPINM", NULL, "XSP Playback"},
|
||||||
{"XSPINR", NULL, "XSP Playback"},
|
{"XSPINR", NULL, "XSP Playback"},
|
||||||
{"VSPIN", NULL, "VSP Playback"},
|
{"VSPINOUT", NULL, "VSP Playback"},
|
||||||
|
|
||||||
/* Capture Paths */
|
/* Capture Paths */
|
||||||
{"MIC1", NULL, "MIC1 Bias"},
|
{"MIC1", NULL, "MIC1 Bias"},
|
||||||
@ -795,6 +850,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
|
|||||||
|
|
||||||
{"ADC Left", NULL, "PGA Left"},
|
{"ADC Left", NULL, "PGA Left"},
|
||||||
{"ADC Right", NULL, "PGA Right"},
|
{"ADC Right", NULL, "PGA Right"},
|
||||||
|
{"DMIC Left", NULL, "DMICA"},
|
||||||
|
{"DMIC Right", NULL, "DMICB"},
|
||||||
|
|
||||||
{"Input Left Capture", "ADC Left Input", "ADC Left"},
|
{"Input Left Capture", "ADC Left Input", "ADC Left"},
|
||||||
{"Input Right Capture", "ADC Right Input", "ADC Right"},
|
{"Input Right Capture", "ADC Right Input", "ADC Right"},
|
||||||
@ -819,21 +876,18 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
|
|||||||
{"XSPOUTR", NULL, "XSPR Output Mixer"},
|
{"XSPOUTR", NULL, "XSPR Output Mixer"},
|
||||||
|
|
||||||
/* Voice Capture */
|
/* Voice Capture */
|
||||||
{"VSPL Output Mixer", NULL, "Input Left Capture"},
|
{"VSP Output Mixer", NULL, "Input Left Capture"},
|
||||||
{"VSPR Output Mixer", NULL, "Input Left Capture"},
|
{"VSP Output Mixer", NULL, "Input Right Capture"},
|
||||||
|
|
||||||
{"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"},
|
{"VSPINOUT", "VSP-IP Volume", "VSP Output Mixer"},
|
||||||
{"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"},
|
|
||||||
|
|
||||||
{"VSPOUTL", NULL, "VSPL Output Mixer"},
|
{"VSPINOUT", NULL, "VSP Output Mixer"},
|
||||||
{"VSPOUTR", NULL, "VSPR Output Mixer"},
|
|
||||||
|
|
||||||
{"ASP Capture", NULL, "ASPOUTL"},
|
{"ASP Capture", NULL, "ASPOUTL"},
|
||||||
{"ASP Capture", NULL, "ASPOUTR"},
|
{"ASP Capture", NULL, "ASPOUTR"},
|
||||||
{"XSP Capture", NULL, "XSPOUTL"},
|
{"XSP Capture", NULL, "XSPOUTL"},
|
||||||
{"XSP Capture", NULL, "XSPOUTR"},
|
{"XSP Capture", NULL, "XSPOUTR"},
|
||||||
{"VSP Capture", NULL, "VSPOUTL"},
|
{"VSP Capture", NULL, "VSPINOUT"},
|
||||||
{"VSP Capture", NULL, "VSPOUTR"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cs42l73_mclk_div {
|
struct cs42l73_mclk_div {
|
||||||
@ -1167,6 +1221,14 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
|
|||||||
|
|
||||||
case SND_SOC_BIAS_OFF:
|
case SND_SOC_BIAS_OFF:
|
||||||
snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
|
snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
|
||||||
|
if (cs42l73->shutdwn_delay > 0) {
|
||||||
|
mdelay(cs42l73->shutdwn_delay);
|
||||||
|
cs42l73->shutdwn_delay = 0;
|
||||||
|
} else {
|
||||||
|
mdelay(15); /* Min amount of time requred to power
|
||||||
|
* down.
|
||||||
|
*/
|
||||||
|
}
|
||||||
snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
|
snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ EXPORT_SYMBOL(process_sigma_firmware);
|
|||||||
static int sigma_action_write_regmap(void *control_data,
|
static int sigma_action_write_regmap(void *control_data,
|
||||||
const struct sigma_action *sa, size_t len)
|
const struct sigma_action *sa, size_t len)
|
||||||
{
|
{
|
||||||
return regmap_raw_write(control_data, le16_to_cpu(sa->addr),
|
return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
|
||||||
sa->payload, len - 2);
|
sa->payload, len - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +398,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
|
|||||||
TPA6130A2_MUTE_L;
|
TPA6130A2_MUTE_L;
|
||||||
|
|
||||||
if (data->power_gpio >= 0) {
|
if (data->power_gpio >= 0) {
|
||||||
ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
|
ret = devm_gpio_request(dev, data->power_gpio,
|
||||||
|
"tpa6130a2 enable");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "Failed to request power GPIO (%d)\n",
|
dev_err(dev, "Failed to request power GPIO (%d)\n",
|
||||||
data->power_gpio);
|
data->power_gpio);
|
||||||
@ -419,16 +420,16 @@ static int tpa6130a2_probe(struct i2c_client *client,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->supply = regulator_get(dev, regulator);
|
data->supply = devm_regulator_get(dev, regulator);
|
||||||
if (IS_ERR(data->supply)) {
|
if (IS_ERR(data->supply)) {
|
||||||
ret = PTR_ERR(data->supply);
|
ret = PTR_ERR(data->supply);
|
||||||
dev_err(dev, "Failed to request supply: %d\n", ret);
|
dev_err(dev, "Failed to request supply: %d\n", ret);
|
||||||
goto err_regulator;
|
goto err_gpio;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tpa6130a2_power(1);
|
ret = tpa6130a2_power(1);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err_power;
|
goto err_gpio;
|
||||||
|
|
||||||
|
|
||||||
/* Read version */
|
/* Read version */
|
||||||
@ -440,15 +441,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
|
|||||||
/* Disable the chip */
|
/* Disable the chip */
|
||||||
ret = tpa6130a2_power(0);
|
ret = tpa6130a2_power(0);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err_power;
|
goto err_gpio;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_power:
|
|
||||||
regulator_put(data->supply);
|
|
||||||
err_regulator:
|
|
||||||
if (data->power_gpio >= 0)
|
|
||||||
gpio_free(data->power_gpio);
|
|
||||||
err_gpio:
|
err_gpio:
|
||||||
tpa6130a2_client = NULL;
|
tpa6130a2_client = NULL;
|
||||||
|
|
||||||
@ -457,14 +453,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
|
|||||||
|
|
||||||
static int tpa6130a2_remove(struct i2c_client *client)
|
static int tpa6130a2_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct tpa6130a2_data *data = i2c_get_clientdata(client);
|
|
||||||
|
|
||||||
tpa6130a2_power(0);
|
tpa6130a2_power(0);
|
||||||
|
|
||||||
if (data->power_gpio >= 0)
|
|
||||||
gpio_free(data->power_gpio);
|
|
||||||
|
|
||||||
regulator_put(data->supply);
|
|
||||||
tpa6130a2_client = NULL;
|
tpa6130a2_client = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -113,7 +113,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
|
|||||||
SNDRV_PCM_STREAM_PLAYBACK,
|
SNDRV_PCM_STREAM_PLAYBACK,
|
||||||
SND_SOC_DAPM_STREAM_STOP);
|
SND_SOC_DAPM_STREAM_STOP);
|
||||||
} else
|
} else
|
||||||
codec_dai->pop_wait = 1;
|
rtd->pop_wait = 1;
|
||||||
schedule_delayed_work(&rtd->delayed_work,
|
schedule_delayed_work(&rtd->delayed_work,
|
||||||
msecs_to_jiffies(rtd->pmdown_time));
|
msecs_to_jiffies(rtd->pmdown_time));
|
||||||
} else {
|
} else {
|
||||||
|
@ -4155,9 +4155,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||||||
ret = of_property_read_string_index(np, propname,
|
ret = of_property_read_string_index(np, propname,
|
||||||
2 * i, &routes[i].sink);
|
2 * i, &routes[i].sink);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(card->dev, "ASoC: Property '%s' index %d"
|
dev_err(card->dev,
|
||||||
" could not be read: %d\n", propname, 2 * i,
|
"ASoC: Property '%s' index %d could not be read: %d\n",
|
||||||
ret);
|
propname, 2 * i, ret);
|
||||||
kfree(routes);
|
kfree(routes);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -4165,8 +4165,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||||||
(2 * i) + 1, &routes[i].source);
|
(2 * i) + 1, &routes[i].source);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(card->dev,
|
dev_err(card->dev,
|
||||||
"ASoC: Property '%s' index %d could not be"
|
"ASoC: Property '%s' index %d could not be read: %d\n",
|
||||||
" read: %d\n", propname, (2 * i) + 1, ret);
|
propname, (2 * i) + 1, ret);
|
||||||
kfree(routes);
|
kfree(routes);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -334,11 +334,11 @@ static void close_delayed_work(struct work_struct *work)
|
|||||||
dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
|
dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
|
||||||
codec_dai->driver->playback.stream_name,
|
codec_dai->driver->playback.stream_name,
|
||||||
codec_dai->playback_active ? "active" : "inactive",
|
codec_dai->playback_active ? "active" : "inactive",
|
||||||
codec_dai->pop_wait ? "yes" : "no");
|
rtd->pop_wait ? "yes" : "no");
|
||||||
|
|
||||||
/* are we waiting on this codec DAI stream */
|
/* are we waiting on this codec DAI stream */
|
||||||
if (codec_dai->pop_wait == 1) {
|
if (rtd->pop_wait == 1) {
|
||||||
codec_dai->pop_wait = 0;
|
rtd->pop_wait = 0;
|
||||||
snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
|
snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
|
||||||
SND_SOC_DAPM_STREAM_STOP);
|
SND_SOC_DAPM_STREAM_STOP);
|
||||||
}
|
}
|
||||||
@ -408,7 +408,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
|
|||||||
SND_SOC_DAPM_STREAM_STOP);
|
SND_SOC_DAPM_STREAM_STOP);
|
||||||
} else {
|
} else {
|
||||||
/* start delayed pop wq here for playback streams */
|
/* start delayed pop wq here for playback streams */
|
||||||
codec_dai->pop_wait = 1;
|
rtd->pop_wait = 1;
|
||||||
schedule_delayed_work(&rtd->delayed_work,
|
schedule_delayed_work(&rtd->delayed_work,
|
||||||
msecs_to_jiffies(rtd->pmdown_time));
|
msecs_to_jiffies(rtd->pmdown_time));
|
||||||
}
|
}
|
||||||
@ -480,8 +480,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
|
|||||||
|
|
||||||
/* cancel any delayed stream shutdown that is pending */
|
/* cancel any delayed stream shutdown that is pending */
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||||
codec_dai->pop_wait) {
|
rtd->pop_wait) {
|
||||||
codec_dai->pop_wait = 0;
|
rtd->pop_wait = 0;
|
||||||
cancel_delayed_work(&rtd->delayed_work);
|
cancel_delayed_work(&rtd->delayed_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2181,6 +2181,10 @@ int snd_usbmidi_create(struct snd_card *card,
|
|||||||
umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
|
umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
|
||||||
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
|
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
|
||||||
break;
|
break;
|
||||||
|
case QUIRK_MIDI_MBOX2:
|
||||||
|
umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
|
||||||
|
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
|
||||||
|
break;
|
||||||
case QUIRK_MIDI_RAW_BYTES:
|
case QUIRK_MIDI_RAW_BYTES:
|
||||||
umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
|
umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
|
||||||
/*
|
/*
|
||||||
|
@ -98,6 +98,42 @@
|
|||||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HP Wireless Audio
|
||||||
|
* When not ignored, causes instability issues for some users, forcing them to
|
||||||
|
* blacklist the entire module.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
USB_DEVICE(0x0424, 0xb832),
|
||||||
|
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||||
|
.vendor_name = "Standard Microsystems Corp.",
|
||||||
|
.product_name = "HP Wireless Audio",
|
||||||
|
.ifnum = QUIRK_ANY_INTERFACE,
|
||||||
|
.type = QUIRK_COMPOSITE,
|
||||||
|
.data = (const struct snd_usb_audio_quirk[]) {
|
||||||
|
/* Mixer */
|
||||||
|
{
|
||||||
|
.ifnum = 0,
|
||||||
|
.type = QUIRK_IGNORE_INTERFACE,
|
||||||
|
},
|
||||||
|
/* Playback */
|
||||||
|
{
|
||||||
|
.ifnum = 1,
|
||||||
|
.type = QUIRK_IGNORE_INTERFACE,
|
||||||
|
},
|
||||||
|
/* Capture */
|
||||||
|
{
|
||||||
|
.ifnum = 2,
|
||||||
|
.type = QUIRK_IGNORE_INTERFACE,
|
||||||
|
},
|
||||||
|
/* HID Device, .ifnum = 3 */
|
||||||
|
{
|
||||||
|
.ifnum = -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
|
* Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
|
||||||
* class matches do not take effect without an explicit ID match.
|
* class matches do not take effect without an explicit ID match.
|
||||||
@ -2885,6 +2921,93 @@ YAMAHA_DEVICE(0x7010, "UB99"),
|
|||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/* DIGIDESIGN MBOX 2 */
|
||||||
|
{
|
||||||
|
USB_DEVICE(0x0dba, 0x3000),
|
||||||
|
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||||
|
.vendor_name = "Digidesign",
|
||||||
|
.product_name = "Mbox 2",
|
||||||
|
.ifnum = QUIRK_ANY_INTERFACE,
|
||||||
|
.type = QUIRK_COMPOSITE,
|
||||||
|
.data = (const struct snd_usb_audio_quirk[]) {
|
||||||
|
{
|
||||||
|
.ifnum = 0,
|
||||||
|
.type = QUIRK_IGNORE_INTERFACE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 1,
|
||||||
|
.type = QUIRK_IGNORE_INTERFACE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 2,
|
||||||
|
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
|
||||||
|
.data = &(const struct audioformat) {
|
||||||
|
.formats = SNDRV_PCM_FMTBIT_S24_3BE,
|
||||||
|
.channels = 2,
|
||||||
|
.iface = 2,
|
||||||
|
.altsetting = 2,
|
||||||
|
.altset_idx = 1,
|
||||||
|
.attributes = 0x00,
|
||||||
|
.endpoint = 0x03,
|
||||||
|
.ep_attr = USB_ENDPOINT_SYNC_ASYNC,
|
||||||
|
.maxpacksize = 0x128,
|
||||||
|
.rates = SNDRV_PCM_RATE_48000,
|
||||||
|
.rate_min = 48000,
|
||||||
|
.rate_max = 48000,
|
||||||
|
.nr_rates = 1,
|
||||||
|
.rate_table = (unsigned int[]) {
|
||||||
|
48000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 3,
|
||||||
|
.type = QUIRK_IGNORE_INTERFACE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 4,
|
||||||
|
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
|
||||||
|
.data = &(const struct audioformat) {
|
||||||
|
.formats = SNDRV_PCM_FMTBIT_S24_3BE,
|
||||||
|
.channels = 2,
|
||||||
|
.iface = 4,
|
||||||
|
.altsetting = 2,
|
||||||
|
.altset_idx = 1,
|
||||||
|
.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
|
||||||
|
.endpoint = 0x85,
|
||||||
|
.ep_attr = USB_ENDPOINT_SYNC_SYNC,
|
||||||
|
.maxpacksize = 0x128,
|
||||||
|
.rates = SNDRV_PCM_RATE_48000,
|
||||||
|
.rate_min = 48000,
|
||||||
|
.rate_max = 48000,
|
||||||
|
.nr_rates = 1,
|
||||||
|
.rate_table = (unsigned int[]) {
|
||||||
|
48000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 5,
|
||||||
|
.type = QUIRK_IGNORE_INTERFACE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 6,
|
||||||
|
.type = QUIRK_MIDI_MBOX2,
|
||||||
|
.data = &(const struct snd_usb_midi_endpoint_info) {
|
||||||
|
.out_ep = 0x02,
|
||||||
|
.out_cables = 0x0001,
|
||||||
|
.in_ep = 0x81,
|
||||||
|
.in_interval = 0x01,
|
||||||
|
.in_cables = 0x0001
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
/* Tascam US122 MKII - playback-only support */
|
/* Tascam US122 MKII - playback-only support */
|
||||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
|
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
|
||||||
|
@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
|
|||||||
[QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
|
[QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
|
||||||
[QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
|
[QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
|
||||||
[QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
|
[QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
|
||||||
|
[QUIRK_MIDI_MBOX2] = create_any_midi_quirk,
|
||||||
[QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
|
[QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
|
||||||
[QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
|
[QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
|
||||||
[QUIRK_MIDI_CME] = create_any_midi_quirk,
|
[QUIRK_MIDI_CME] = create_any_midi_quirk,
|
||||||
@ -497,6 +498,92 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mbox2_setup_48_24_magic(struct usb_device *dev)
|
||||||
|
{
|
||||||
|
u8 srate[3];
|
||||||
|
u8 temp[12];
|
||||||
|
|
||||||
|
/* Choose 48000Hz permanently */
|
||||||
|
srate[0] = 0x80;
|
||||||
|
srate[1] = 0xbb;
|
||||||
|
srate[2] = 0x00;
|
||||||
|
|
||||||
|
/* Send the magic! */
|
||||||
|
snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||||
|
0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003);
|
||||||
|
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||||
|
0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003);
|
||||||
|
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||||
|
0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003);
|
||||||
|
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||||
|
0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Digidesign Mbox 2 needs to load firmware onboard
|
||||||
|
* and driver must wait a few seconds for initialisation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MBOX2_FIRMWARE_SIZE 646
|
||||||
|
#define MBOX2_BOOT_LOADING 0x01 /* Hard coded into the device */
|
||||||
|
#define MBOX2_BOOT_READY 0x02 /* Hard coded into the device */
|
||||||
|
|
||||||
|
int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
|
||||||
|
{
|
||||||
|
struct usb_host_config *config = dev->actconfig;
|
||||||
|
int err;
|
||||||
|
u8 bootresponse;
|
||||||
|
int fwsize;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
|
||||||
|
|
||||||
|
if (fwsize != MBOX2_FIRMWARE_SIZE) {
|
||||||
|
snd_printk(KERN_ERR "usb-audio: Invalid firmware size=%d.\n", fwsize);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n");
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
bootresponse = MBOX2_BOOT_LOADING;
|
||||||
|
while ((bootresponse == MBOX2_BOOT_LOADING) && (count < 10)) {
|
||||||
|
msleep(500); /* 0.5 second delay */
|
||||||
|
snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||||
|
/* Control magic - load onboard firmware */
|
||||||
|
0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012);
|
||||||
|
if (bootresponse == MBOX2_BOOT_READY)
|
||||||
|
break;
|
||||||
|
snd_printd("usb-audio: device not ready, resending boot sequence...\n");
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bootresponse != MBOX2_BOOT_READY) {
|
||||||
|
snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_printdd("usb-audio: device initialised!\n");
|
||||||
|
|
||||||
|
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
|
||||||
|
&dev->descriptor, sizeof(dev->descriptor));
|
||||||
|
config = dev->actconfig;
|
||||||
|
if (err < 0)
|
||||||
|
snd_printd("error usb_get_descriptor: %d\n", err);
|
||||||
|
|
||||||
|
err = usb_reset_configuration(dev);
|
||||||
|
if (err < 0)
|
||||||
|
snd_printd("error usb_reset_configuration: %d\n", err);
|
||||||
|
snd_printdd("mbox2_boot: new boot length = %d\n",
|
||||||
|
le16_to_cpu(get_cfg_desc(config)->wTotalLength));
|
||||||
|
|
||||||
|
mbox2_setup_48_24_magic(dev);
|
||||||
|
|
||||||
|
snd_printk(KERN_INFO "usb-audio: Digidesign Mbox 2: 24bit 48kHz");
|
||||||
|
|
||||||
|
return 0; /* Successful boot */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup quirks
|
* Setup quirks
|
||||||
*/
|
*/
|
||||||
@ -655,6 +742,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
|
|||||||
case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
|
case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
|
||||||
return snd_usb_cm6206_boot_quirk(dev);
|
return snd_usb_cm6206_boot_quirk(dev);
|
||||||
|
|
||||||
|
case USB_ID(0x0dba, 0x3000):
|
||||||
|
/* Digidesign Mbox 2 */
|
||||||
|
return snd_usb_mbox2_boot_quirk(dev);
|
||||||
|
|
||||||
case USB_ID(0x133e, 0x0815):
|
case USB_ID(0x133e, 0x0815):
|
||||||
/* Access Music VirusTI Desktop */
|
/* Access Music VirusTI Desktop */
|
||||||
return snd_usb_accessmusic_boot_quirk(dev);
|
return snd_usb_accessmusic_boot_quirk(dev);
|
||||||
|
@ -76,6 +76,7 @@ enum quirk_type {
|
|||||||
QUIRK_MIDI_YAMAHA,
|
QUIRK_MIDI_YAMAHA,
|
||||||
QUIRK_MIDI_MIDIMAN,
|
QUIRK_MIDI_MIDIMAN,
|
||||||
QUIRK_MIDI_NOVATION,
|
QUIRK_MIDI_NOVATION,
|
||||||
|
QUIRK_MIDI_MBOX2,
|
||||||
QUIRK_MIDI_RAW_BYTES,
|
QUIRK_MIDI_RAW_BYTES,
|
||||||
QUIRK_MIDI_EMAGIC,
|
QUIRK_MIDI_EMAGIC,
|
||||||
QUIRK_MIDI_CME,
|
QUIRK_MIDI_CME,
|
||||||
|
Loading…
Reference in New Issue
Block a user