Sound fixes for 3.7-rc3
Slightly a high amount of commits come from Adrian Knoth's HDSPM driver fixes. Other than that, all small trival fixes or quirks that are pretty driver-specific. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJQiqRbAAoJEGwxgFQ9KSmk+UQQALokyK6kpbA6PNF0DxT/Pq+U G9VzD2uSfKRtHToHTgh8I6vtGK69syA8hom3UxqXI2+TRpU1fNflRcVHapMuTxRF vQLwge5fQkQxscSIsindTclZ6pShVv1+DSqlGoDud4uic+37exmNJJVIrheAPsSi NMDHhraLsKfbzgvj0r5W9iprrtgZxHKqMOa5rVmJZJwfwCAHloDuMC2RPC1EN1zQ BYTRbgl4BfZuZnAazNAv2ixWdpw4EgjBsqv1utMeGu6BJ4LOSaJROkgLtbtx0Gfu m4XGbQS7L6EfgVR+EROofzcxak/lHicikzHyJgQXG/LGigAhKKXlIn8M+jWMnAmR 9KPhWceF6Ly2+QpeAs/9HCiACBqsf+iF0cUsPrOtyclokLA6x/gP74TD0P4xPubu knCofOUBkoE/EQFAW/VwK6bQeY1fYpFl/IMWUwSJTRoznp8A68BtnR3TPoTMvy7o oYj06mg7HIRbr4aUvIOTmZvFjmBe148fTUccQvFcq1BU3PqSGrlRlSJbvBo/TK2d OLdZBnwqvoZiY02dFBApjqlLi93kZQHAjLb7sFbhngq0uAtzx/ePI7et8xv+S0B3 RvSdF4BSbQ6iMFZyO86i365ID9xEj9STJRrHasVUoWXS255gurLH+5JZuzDXJmQV zUJAKM0maz6w0HEZ3Zff =K8U8 -----END PGP SIGNATURE----- Merge tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "Slightly a high amount of commits come from Adrian Knoth's HDSPM driver fixes. Other than that, all small trival fixes or quirks that are pretty driver-specific." * tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ASoC: wm8994: Only enable extra BCLK cycles when required ALSA: als3000: check for the kzalloc return value ALSA: sound/isa/opti9xx/miro.c: eliminate possible double free ALSA: hda - Fix silent headphone output from Toshiba P200 ALSA: hdspm - Fix coding style in CTL_ELEM macros ALSA: hdspm - Fix typo in kcontrol element on RME MADI cards ALSA: hdspm - Fix sync_in detection on AES/AES32 ALSA: hdspm - Fix sync_in reporting on RME MADI cards ALSA: hdspm - Also report autosync_sample_rate on MADI and MADIface ALSA: hdspm - Fix reported autosync_sample_rate ALSA: hdspm - Fix sync check reporting on all RME HDSPM cards ALSA: hdspm - Report external rate in slave mode on PCI MADI ALSA: hdspm - Allow DDS/Varispeed to be set from userspace ALSA: hda - add dock support for Thinkpad T430 ASoC: ux500_msp_i2s: Fix devm_* and return code merge error ASoC: Ux500: Dispose of device nodes correctly
This commit is contained in:
commit
22e978f1f2
|
@ -1286,7 +1286,6 @@ static int __devinit snd_miro_probe(struct snd_card *card)
|
|||
|
||||
error = snd_card_miro_aci_detect(card, miro);
|
||||
if (error < 0) {
|
||||
snd_card_free(card);
|
||||
snd_printk(KERN_ERR "unable to detect aci chip\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -394,6 +394,8 @@ static int snd_als300_playback_open(struct snd_pcm_substream *substream)
|
|||
struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
snd_als300_dbgcallenter();
|
||||
chip->playback_substream = substream;
|
||||
runtime->hw = snd_als300_playback_hw;
|
||||
|
@ -425,6 +427,8 @@ static int snd_als300_capture_open(struct snd_pcm_substream *substream)
|
|||
struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
snd_als300_dbgcallenter();
|
||||
chip->capture_substream = substream;
|
||||
runtime->hw = snd_als300_capture_hw;
|
||||
|
|
|
@ -5677,6 +5677,7 @@ static const struct hda_verb alc268_beep_init_verbs[] = {
|
|||
|
||||
enum {
|
||||
ALC268_FIXUP_INV_DMIC,
|
||||
ALC268_FIXUP_HP_EAPD,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc268_fixups[] = {
|
||||
|
@ -5684,10 +5685,26 @@ static const struct alc_fixup alc268_fixups[] = {
|
|||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
[ALC268_FIXUP_HP_EAPD] = {
|
||||
.type = ALC_FIXUP_VERBS,
|
||||
.v.verbs = (const struct hda_verb[]) {
|
||||
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
|
||||
{}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static const struct alc_model_fixup alc268_fixup_models[] = {
|
||||
{.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
|
||||
{.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc268_fixup_tbl[] = {
|
||||
/* below is codec SSID since multiple Toshiba laptops have the
|
||||
* same PCI SSID 1179:ff00
|
||||
*/
|
||||
SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -5722,7 +5739,7 @@ static int patch_alc268(struct hda_codec *codec)
|
|||
|
||||
spec = codec->spec;
|
||||
|
||||
alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups);
|
||||
alc_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
|
||||
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
|
@ -6188,6 +6205,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
|
||||
|
|
|
@ -971,6 +971,7 @@ static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
|
|||
static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
|
||||
static int hdspm_autosync_ref(struct hdspm *hdspm);
|
||||
static int snd_hdspm_set_defaults(struct hdspm *hdspm);
|
||||
static int hdspm_system_clock_mode(struct hdspm *hdspm);
|
||||
static void hdspm_set_sgbuf(struct hdspm *hdspm,
|
||||
struct snd_pcm_substream *substream,
|
||||
unsigned int reg, int channels);
|
||||
|
@ -1989,10 +1990,14 @@ static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
|
|||
rate = hdspm_calc_dds_value(hdspm, period);
|
||||
|
||||
if (rate > 207000) {
|
||||
/* Unreasonable high sample rate as seen on PCI MADI cards.
|
||||
* Use the cached value instead.
|
||||
*/
|
||||
rate = hdspm->system_sample_rate;
|
||||
/* Unreasonable high sample rate as seen on PCI MADI cards. */
|
||||
if (0 == hdspm_system_clock_mode(hdspm)) {
|
||||
/* master mode, return internal sample rate */
|
||||
rate = hdspm->system_sample_rate;
|
||||
} else {
|
||||
/* slave mode, return external sample rate */
|
||||
rate = hdspm_external_sample_rate(hdspm);
|
||||
}
|
||||
}
|
||||
|
||||
return rate;
|
||||
|
@ -2000,12 +2005,14 @@ static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
|
|||
|
||||
|
||||
#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ, \
|
||||
.info = snd_hdspm_info_system_sample_rate, \
|
||||
.get = snd_hdspm_get_system_sample_rate \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
|
||||
.info = snd_hdspm_info_system_sample_rate, \
|
||||
.put = snd_hdspm_put_system_sample_rate, \
|
||||
.get = snd_hdspm_get_system_sample_rate \
|
||||
}
|
||||
|
||||
static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
|
||||
|
@ -2030,6 +2037,16 @@ static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *
|
||||
ucontrol)
|
||||
{
|
||||
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the WordClock sample rate class for the given card.
|
||||
|
@ -2163,6 +2180,7 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
|
|||
hdspm_get_s1_sample_rate(hdspm,
|
||||
kcontrol->private_value-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case AIO:
|
||||
switch (kcontrol->private_value) {
|
||||
|
@ -2183,6 +2201,7 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
|
|||
hdspm_get_s1_sample_rate(hdspm,
|
||||
ucontrol->id.index-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case AES32:
|
||||
|
||||
|
@ -2204,8 +2223,23 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
|
|||
hdspm_get_s1_sample_rate(hdspm,
|
||||
kcontrol->private_value-1);
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case MADI:
|
||||
case MADIface:
|
||||
{
|
||||
int rate = hdspm_external_sample_rate(hdspm);
|
||||
int i, selected_rate = 0;
|
||||
for (i = 1; i < 10; i++)
|
||||
if (HDSPM_bit2freq(i) == rate) {
|
||||
selected_rate = i;
|
||||
break;
|
||||
}
|
||||
ucontrol->value.enumerated.item[0] = selected_rate;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2430,7 +2464,7 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_PREF_SYNC_REF(xname, xindex) \
|
||||
{.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
|
||||
|
@ -2766,12 +2800,12 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_AUTOSYNC_REF(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ, \
|
||||
.info = snd_hdspm_info_autosync_ref, \
|
||||
.get = snd_hdspm_get_autosync_ref, \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ, \
|
||||
.info = snd_hdspm_info_autosync_ref, \
|
||||
.get = snd_hdspm_get_autosync_ref, \
|
||||
}
|
||||
|
||||
static int hdspm_autosync_ref(struct hdspm *hdspm)
|
||||
|
@ -2855,12 +2889,12 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_LINE_OUT(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_line_out, \
|
||||
.get = snd_hdspm_get_line_out, \
|
||||
.put = snd_hdspm_put_line_out \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_line_out, \
|
||||
.get = snd_hdspm_get_line_out, \
|
||||
.put = snd_hdspm_put_line_out \
|
||||
}
|
||||
|
||||
static int hdspm_line_out(struct hdspm * hdspm)
|
||||
|
@ -2912,12 +2946,12 @@ static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_TX_64(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_tx_64, \
|
||||
.get = snd_hdspm_get_tx_64, \
|
||||
.put = snd_hdspm_put_tx_64 \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_tx_64, \
|
||||
.get = snd_hdspm_get_tx_64, \
|
||||
.put = snd_hdspm_put_tx_64 \
|
||||
}
|
||||
|
||||
static int hdspm_tx_64(struct hdspm * hdspm)
|
||||
|
@ -2968,12 +3002,12 @@ static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_C_TMS(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_c_tms, \
|
||||
.get = snd_hdspm_get_c_tms, \
|
||||
.put = snd_hdspm_put_c_tms \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_c_tms, \
|
||||
.get = snd_hdspm_get_c_tms, \
|
||||
.put = snd_hdspm_put_c_tms \
|
||||
}
|
||||
|
||||
static int hdspm_c_tms(struct hdspm * hdspm)
|
||||
|
@ -3024,12 +3058,12 @@ static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_SAFE_MODE(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_safe_mode, \
|
||||
.get = snd_hdspm_get_safe_mode, \
|
||||
.put = snd_hdspm_put_safe_mode \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_safe_mode, \
|
||||
.get = snd_hdspm_get_safe_mode, \
|
||||
.put = snd_hdspm_put_safe_mode \
|
||||
}
|
||||
|
||||
static int hdspm_safe_mode(struct hdspm * hdspm)
|
||||
|
@ -3080,12 +3114,12 @@ static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_EMPHASIS(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_emphasis, \
|
||||
.get = snd_hdspm_get_emphasis, \
|
||||
.put = snd_hdspm_put_emphasis \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_emphasis, \
|
||||
.get = snd_hdspm_get_emphasis, \
|
||||
.put = snd_hdspm_put_emphasis \
|
||||
}
|
||||
|
||||
static int hdspm_emphasis(struct hdspm * hdspm)
|
||||
|
@ -3136,12 +3170,12 @@ static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_DOLBY(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_dolby, \
|
||||
.get = snd_hdspm_get_dolby, \
|
||||
.put = snd_hdspm_put_dolby \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_dolby, \
|
||||
.get = snd_hdspm_get_dolby, \
|
||||
.put = snd_hdspm_put_dolby \
|
||||
}
|
||||
|
||||
static int hdspm_dolby(struct hdspm * hdspm)
|
||||
|
@ -3192,12 +3226,12 @@ static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_PROFESSIONAL(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_professional, \
|
||||
.get = snd_hdspm_get_professional, \
|
||||
.put = snd_hdspm_put_professional \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_professional, \
|
||||
.get = snd_hdspm_get_professional, \
|
||||
.put = snd_hdspm_put_professional \
|
||||
}
|
||||
|
||||
static int hdspm_professional(struct hdspm * hdspm)
|
||||
|
@ -3247,12 +3281,12 @@ static int snd_hdspm_put_professional(struct snd_kcontrol *kcontrol,
|
|||
}
|
||||
|
||||
#define HDSPM_INPUT_SELECT(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_input_select, \
|
||||
.get = snd_hdspm_get_input_select, \
|
||||
.put = snd_hdspm_put_input_select \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_input_select, \
|
||||
.get = snd_hdspm_get_input_select, \
|
||||
.put = snd_hdspm_put_input_select \
|
||||
}
|
||||
|
||||
static int hdspm_input_select(struct hdspm * hdspm)
|
||||
|
@ -3319,12 +3353,12 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_DS_WIRE(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_ds_wire, \
|
||||
.get = snd_hdspm_get_ds_wire, \
|
||||
.put = snd_hdspm_put_ds_wire \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_ds_wire, \
|
||||
.get = snd_hdspm_get_ds_wire, \
|
||||
.put = snd_hdspm_put_ds_wire \
|
||||
}
|
||||
|
||||
static int hdspm_ds_wire(struct hdspm * hdspm)
|
||||
|
@ -3391,12 +3425,12 @@ static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
|
|||
|
||||
|
||||
#define HDSPM_QS_WIRE(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_qs_wire, \
|
||||
.get = snd_hdspm_get_qs_wire, \
|
||||
.put = snd_hdspm_put_qs_wire \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.info = snd_hdspm_info_qs_wire, \
|
||||
.get = snd_hdspm_get_qs_wire, \
|
||||
.put = snd_hdspm_put_qs_wire \
|
||||
}
|
||||
|
||||
static int hdspm_qs_wire(struct hdspm * hdspm)
|
||||
|
@ -3563,15 +3597,15 @@ static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol,
|
|||
}
|
||||
|
||||
#define HDSPM_MIXER(xname, xindex) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.device = 0, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
|
||||
.info = snd_hdspm_info_mixer, \
|
||||
.get = snd_hdspm_get_mixer, \
|
||||
.put = snd_hdspm_put_mixer \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
|
||||
.name = xname, \
|
||||
.index = xindex, \
|
||||
.device = 0, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
|
||||
.info = snd_hdspm_info_mixer, \
|
||||
.get = snd_hdspm_get_mixer, \
|
||||
.put = snd_hdspm_put_mixer \
|
||||
}
|
||||
|
||||
static int snd_hdspm_info_mixer(struct snd_kcontrol *kcontrol,
|
||||
|
@ -3670,12 +3704,12 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
|
|||
*/
|
||||
|
||||
#define HDSPM_PLAYBACK_MIXER \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
|
||||
.info = snd_hdspm_info_playback_mixer, \
|
||||
.get = snd_hdspm_get_playback_mixer, \
|
||||
.put = snd_hdspm_put_playback_mixer \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
|
||||
.info = snd_hdspm_info_playback_mixer, \
|
||||
.get = snd_hdspm_get_playback_mixer, \
|
||||
.put = snd_hdspm_put_playback_mixer \
|
||||
}
|
||||
|
||||
static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
|
||||
|
@ -3851,12 +3885,17 @@ static int hdspm_sync_in_sync_check(struct hdspm *hdspm)
|
|||
break;
|
||||
|
||||
case MADI:
|
||||
case AES32:
|
||||
status = hdspm_read(hdspm, HDSPM_statusRegister2);
|
||||
status = hdspm_read(hdspm, HDSPM_statusRegister);
|
||||
lock = (status & HDSPM_syncInLock) ? 1 : 0;
|
||||
sync = (status & HDSPM_syncInSync) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case AES32:
|
||||
status = hdspm_read(hdspm, HDSPM_statusRegister2);
|
||||
lock = (status & 0x100000) ? 1 : 0;
|
||||
sync = (status & 0x200000) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case MADIface:
|
||||
break;
|
||||
}
|
||||
|
@ -3942,6 +3981,7 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
|
|||
default:
|
||||
val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case AIO:
|
||||
switch (kcontrol->private_value) {
|
||||
|
@ -3954,6 +3994,7 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
|
|||
default:
|
||||
val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case MADI:
|
||||
switch (kcontrol->private_value) {
|
||||
|
@ -3966,6 +4007,7 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
|
|||
case 3: /* SYNC_IN */
|
||||
val = hdspm_sync_in_sync_check(hdspm); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MADIface:
|
||||
val = hdspm_madi_sync_check(hdspm); /* MADI */
|
||||
|
@ -3983,6 +4025,7 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
|
|||
val = hdspm_aes_sync_check(hdspm,
|
||||
kcontrol->private_value-1);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
@ -4427,9 +4470,10 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
|
|||
HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
|
||||
HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
|
||||
HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
|
||||
HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
|
||||
HDSPM_SYNC_CHECK("WC SyncCheck", 0),
|
||||
HDSPM_SYNC_CHECK("MADI SyncCheck", 1),
|
||||
HDSPM_SYNC_CHECK("TCO SyncCHeck", 2),
|
||||
HDSPM_SYNC_CHECK("TCO SyncCheck", 2),
|
||||
HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
|
||||
HDSPM_LINE_OUT("Line Out", 0),
|
||||
HDSPM_TX_64("TX 64 channels mode", 0),
|
||||
|
|
|
@ -1045,6 +1045,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994 *control = codec->control_data;
|
||||
int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
|
||||
int i;
|
||||
|
@ -1063,6 +1064,10 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
|
|||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
/* Don't enable timeslot 2 if not in use */
|
||||
if (wm8994->channels[0] <= 2)
|
||||
mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
|
||||
|
||||
val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1);
|
||||
if ((val & WM8994_AIF1ADCL_SRC) &&
|
||||
(val & WM8994_AIF1ADCR_SRC))
|
||||
|
@ -2687,7 +2692,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
bclk_rate = params_rate(params) * 4;
|
||||
bclk_rate = params_rate(params);
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
bclk_rate *= 16;
|
||||
|
@ -2708,6 +2713,17 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
wm8994->channels[id] = params_channels(params);
|
||||
switch (params_channels(params)) {
|
||||
case 1:
|
||||
case 2:
|
||||
bclk_rate *= 2;
|
||||
break;
|
||||
default:
|
||||
bclk_rate *= 4;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Try to find an appropriate sample rate; look for an exact match. */
|
||||
for (i = 0; i < ARRAY_SIZE(srs); i++)
|
||||
if (srs[i].rate == params_rate(params))
|
||||
|
|
|
@ -77,6 +77,7 @@ struct wm8994_priv {
|
|||
int sysclk_rate[2];
|
||||
int mclk[2];
|
||||
int aifclk[2];
|
||||
int channels[2];
|
||||
struct wm8994_fll_config fll[2], fll_suspend[2];
|
||||
struct completion fll_locked[2];
|
||||
bool fll_locked_irq;
|
||||
|
|
|
@ -57,6 +57,20 @@ static struct snd_soc_card mop500_card = {
|
|||
.num_links = ARRAY_SIZE(mop500_dai_links),
|
||||
};
|
||||
|
||||
static void mop500_of_node_put(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (mop500_dai_links[i].cpu_of_node)
|
||||
of_node_put((struct device_node *)
|
||||
mop500_dai_links[i].cpu_of_node);
|
||||
if (mop500_dai_links[i].codec_of_node)
|
||||
of_node_put((struct device_node *)
|
||||
mop500_dai_links[i].codec_of_node);
|
||||
}
|
||||
}
|
||||
|
||||
static int __devinit mop500_of_probe(struct platform_device *pdev,
|
||||
struct device_node *np)
|
||||
{
|
||||
|
@ -69,6 +83,7 @@ static int __devinit mop500_of_probe(struct platform_device *pdev,
|
|||
|
||||
if (!(msp_np[0] && msp_np[1] && codec_np)) {
|
||||
dev_err(&pdev->dev, "Phandle missing or invalid\n");
|
||||
mop500_of_node_put();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -83,6 +98,7 @@ static int __devinit mop500_of_probe(struct platform_device *pdev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit mop500_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
@ -128,6 +144,7 @@ static int __devexit mop500_remove(struct platform_device *pdev)
|
|||
|
||||
snd_soc_unregister_card(mop500_card);
|
||||
mop500_ab8500_remove(mop500_card);
|
||||
mop500_of_node_put();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
@ -697,14 +698,11 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
|
|||
platform_data = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
|
||||
if (!platform_data)
|
||||
ret = -ENOMEM;
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else
|
||||
if (!platform_data)
|
||||
ret = -EINVAL;
|
||||
|
||||
if (ret)
|
||||
goto err_res;
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
|
||||
pdev->name, platform_data->id);
|
||||
|
|
Loading…
Reference in a new issue