提交 09759d1e 编写于 作者: L Linus Torvalds

Merge tag 'sound-3.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "A usual pattern of half ASoC and half HD-audio fixes, although
  HD-audio fixups have more volumes, in addition to a couple of trivial
  fixes.  Nothing to worry much is found here.

  For ASoC side: a few fixes for PCM rate constraints calculations,
  regmap byte-order fix, the rest driver specific fixes (atmel, fsl,
  omap, kirkwood, wm codecs).

  For HD-audio: Dell headset and mono out fix, ELD update in polling
  mode, ALC283 Chromebook fixes, a few fixes for old AD codecs and
  MBA2, one regression fix"

* tag 'sound-3.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (30 commits)
  ALSA: hda - Fix silent output on MacBook Air 2,1
  ALSA: hda - Fix missing ELD info when using jackpoll_ms parameter
  ALSA: hda/realtek - remove hp_automute_hook from alc283_fixup_chromebook
  ASoC: wm8731: fix dsp mode configuration
  ALSA: hda/realtek - Independent of model for HP
  ALSA: hda - Fix headset mic input after muted internal mic (Dell/Realtek)
  ALSA: hda - Use always amps for auto-mute on AD1986A codec
  ALSA: hda/analog - Handle inverted EAPD properly in vmaster hook
  ALSA: hda - Another fixup for ASUS laptop with ALC660 codec
  ALSA: atmel: Fix possible array overflow
  ALSA: hda - Fix complete_all() timing in deferred probes
  ALSA: hda - Fix bad EAPD setup for HP machines with AD1984A
  ASoC: core: fix devres parameter in devm_snd_soc_register_card()
  ASoC: omap: n810: Convert to clk_prepare_enable/clk_disable_unprepare
  ASoC: fsl: set correct platform drvdata in pcm030_fabric_probe()
  ASoC: fsl: imx-pcm-fiq: Remove unused 'runtime' variable
  ASoC: fsl: imx-pcm-fiq: remove bogus period delta calculation
  ALSA: hda - Fix silent output on ASUS W7J laptop
  ASoC: core: Use consistent byte ordering in snd_soc_bytes_get
  ALSA: dice: fix array limits in dice_proc_read()
  ...
...@@ -104,7 +104,8 @@ struct device; ...@@ -104,7 +104,8 @@ struct device;
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.kcontrol_news = wcontrols, .num_kcontrols = 1} .kcontrol_news = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \ #define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, \ { .id = snd_soc_dapm_mux, .name = wname, \
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.kcontrol_news = wcontrols, .num_kcontrols = 1} .kcontrol_news = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \ #define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_virt_mux, .name = wname, \ { .id = snd_soc_dapm_virt_mux, .name = wname, \
......
...@@ -357,7 +357,8 @@ static int set_sample_rates(struct atmel_abdac *dac) ...@@ -357,7 +357,8 @@ static int set_sample_rates(struct atmel_abdac *dac)
if (new_rate < 0) if (new_rate < 0)
break; break;
/* make sure we are below the ABDAC clock */ /* make sure we are below the ABDAC clock */
if (new_rate <= clk_get_rate(dac->pclk)) { if (index < MAX_NUM_RATES &&
new_rate <= clk_get_rate(dac->pclk)) {
dac->rates[index] = new_rate / 256; dac->rates[index] = new_rate / 256;
index++; index++;
} }
......
...@@ -1019,7 +1019,7 @@ static void dice_proc_read(struct snd_info_entry *entry, ...@@ -1019,7 +1019,7 @@ static void dice_proc_read(struct snd_info_entry *entry,
if (dice_proc_read_mem(dice, &tx_rx_header, sections[2], 2) < 0) if (dice_proc_read_mem(dice, &tx_rx_header, sections[2], 2) < 0)
return; return;
quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx)); quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx) / 4);
for (stream = 0; stream < tx_rx_header.number; ++stream) { for (stream = 0; stream < tx_rx_header.number; ++stream) {
if (dice_proc_read_mem(dice, &buf.tx, sections[2] + 2 + if (dice_proc_read_mem(dice, &buf.tx, sections[2] + 2 +
stream * tx_rx_header.size, stream * tx_rx_header.size,
...@@ -1045,7 +1045,7 @@ static void dice_proc_read(struct snd_info_entry *entry, ...@@ -1045,7 +1045,7 @@ static void dice_proc_read(struct snd_info_entry *entry,
if (dice_proc_read_mem(dice, &tx_rx_header, sections[4], 2) < 0) if (dice_proc_read_mem(dice, &tx_rx_header, sections[4], 2) < 0)
return; return;
quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx)); quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx) / 4);
for (stream = 0; stream < tx_rx_header.number; ++stream) { for (stream = 0; stream < tx_rx_header.number; ++stream) {
if (dice_proc_read_mem(dice, &buf.rx, sections[4] + 2 + if (dice_proc_read_mem(dice, &buf.rx, sections[4] + 2 +
stream * tx_rx_header.size, stream * tx_rx_header.size,
......
...@@ -3876,7 +3876,8 @@ static int azx_probe(struct pci_dev *pci, ...@@ -3876,7 +3876,8 @@ static int azx_probe(struct pci_dev *pci,
} }
dev++; dev++;
complete_all(&chip->probe_wait); if (chip->disabled)
complete_all(&chip->probe_wait);
return 0; return 0;
out_free: out_free:
...@@ -3953,10 +3954,10 @@ static int azx_probe_continue(struct azx *chip) ...@@ -3953,10 +3954,10 @@ static int azx_probe_continue(struct azx *chip)
if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || chip->use_vga_switcheroo) if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || chip->use_vga_switcheroo)
pm_runtime_put_noidle(&pci->dev); pm_runtime_put_noidle(&pci->dev);
return 0;
out_free: out_free:
chip->init_failed = 1; if (err < 0)
chip->init_failed = 1;
complete_all(&chip->probe_wait);
return err; return err;
} }
......
...@@ -147,6 +147,8 @@ static void ad_vmaster_eapd_hook(void *private_data, int enabled) ...@@ -147,6 +147,8 @@ static void ad_vmaster_eapd_hook(void *private_data, int enabled)
if (!spec->eapd_nid) if (!spec->eapd_nid)
return; return;
if (codec->inv_eapd)
enabled = !enabled;
snd_hda_codec_update_cache(codec, spec->eapd_nid, 0, snd_hda_codec_update_cache(codec, spec->eapd_nid, 0,
AC_VERB_SET_EAPD_BTLENABLE, AC_VERB_SET_EAPD_BTLENABLE,
enabled ? 0x02 : 0x00); enabled ? 0x02 : 0x00);
...@@ -359,6 +361,9 @@ static int patch_ad1986a(struct hda_codec *codec) ...@@ -359,6 +361,9 @@ static int patch_ad1986a(struct hda_codec *codec)
*/ */
spec->gen.multiout.no_share_stream = 1; spec->gen.multiout.no_share_stream = 1;
/* AD1986A can't manage the dynamic pin on/off smoothly */
spec->gen.auto_mute_via_amp = 1;
snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl, snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl,
ad1986a_fixups); ad1986a_fixups);
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
...@@ -962,6 +967,7 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec, ...@@ -962,6 +967,7 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
switch (action) { switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE: case HDA_FIXUP_ACT_PRE_PROBE:
spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook; spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
spec->gen.own_eapd_ctl = 1;
snd_hda_sequence_write_cache(codec, gpio_init_verbs); snd_hda_sequence_write_cache(codec, gpio_init_verbs);
break; break;
case HDA_FIXUP_ACT_PROBE: case HDA_FIXUP_ACT_PROBE:
......
...@@ -1142,32 +1142,34 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, ...@@ -1142,32 +1142,34 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) static void jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack)
{ {
struct hdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
int pin_idx = pin_nid_to_pin_index(spec, jack->nid);
if (pin_idx < 0)
return;
if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
snd_hda_jack_report_sync(codec);
}
static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
{
int tag = res >> AC_UNSOL_RES_TAG_SHIFT; int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
int pin_nid;
int pin_idx;
struct hda_jack_tbl *jack; struct hda_jack_tbl *jack;
int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT;
jack = snd_hda_jack_tbl_get_from_tag(codec, tag); jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
if (!jack) if (!jack)
return; return;
pin_nid = jack->nid;
jack->jack_dirty = 1; jack->jack_dirty = 1;
_snd_printd(SND_PR_VERBOSE, _snd_printd(SND_PR_VERBOSE,
"HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n", "HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n",
codec->addr, pin_nid, dev_entry, !!(res & AC_UNSOL_RES_IA), codec->addr, jack->nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
!!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
pin_idx = pin_nid_to_pin_index(spec, pin_nid); jack_callback(codec, jack);
if (pin_idx < 0)
return;
if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
snd_hda_jack_report_sync(codec);
} }
static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
...@@ -2095,7 +2097,8 @@ static int generic_hdmi_init(struct hda_codec *codec) ...@@ -2095,7 +2097,8 @@ static int generic_hdmi_init(struct hda_codec *codec)
hda_nid_t pin_nid = per_pin->pin_nid; hda_nid_t pin_nid = per_pin->pin_nid;
hdmi_init_pin(codec, pin_nid); hdmi_init_pin(codec, pin_nid);
snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); snd_hda_jack_detect_enable_callback(codec, pin_nid, pin_nid,
codec->jackpoll_interval > 0 ? jack_callback : NULL);
} }
return 0; return 0;
} }
......
...@@ -1780,6 +1780,7 @@ enum { ...@@ -1780,6 +1780,7 @@ enum {
ALC889_FIXUP_DAC_ROUTE, ALC889_FIXUP_DAC_ROUTE,
ALC889_FIXUP_MBP_VREF, ALC889_FIXUP_MBP_VREF,
ALC889_FIXUP_IMAC91_VREF, ALC889_FIXUP_IMAC91_VREF,
ALC889_FIXUP_MBA21_VREF,
ALC882_FIXUP_INV_DMIC, ALC882_FIXUP_INV_DMIC,
ALC882_FIXUP_NO_PRIMARY_HP, ALC882_FIXUP_NO_PRIMARY_HP,
ALC887_FIXUP_ASUS_BASS, ALC887_FIXUP_ASUS_BASS,
...@@ -1884,17 +1885,13 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec, ...@@ -1884,17 +1885,13 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec,
} }
} }
/* Set VREF on speaker pins on imac91 */ static void alc889_fixup_mac_pins(struct hda_codec *codec,
static void alc889_fixup_imac91_vref(struct hda_codec *codec, const hda_nid_t *nids, int num_nids)
const struct hda_fixup *fix, int action)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
static hda_nid_t nids[2] = { 0x18, 0x1a };
int i; int i;
if (action != HDA_FIXUP_ACT_INIT) for (i = 0; i < num_nids; i++) {
return;
for (i = 0; i < ARRAY_SIZE(nids); i++) {
unsigned int val; unsigned int val;
val = snd_hda_codec_get_pin_target(codec, nids[i]); val = snd_hda_codec_get_pin_target(codec, nids[i]);
val |= AC_PINCTL_VREF_50; val |= AC_PINCTL_VREF_50;
...@@ -1903,6 +1900,26 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec, ...@@ -1903,6 +1900,26 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec,
spec->gen.keep_vref_in_automute = 1; spec->gen.keep_vref_in_automute = 1;
} }
/* Set VREF on speaker pins on imac91 */
static void alc889_fixup_imac91_vref(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
static hda_nid_t nids[2] = { 0x18, 0x1a };
if (action == HDA_FIXUP_ACT_INIT)
alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
}
/* Set VREF on speaker pins on mba21 */
static void alc889_fixup_mba21_vref(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
static hda_nid_t nids[2] = { 0x18, 0x19 };
if (action == HDA_FIXUP_ACT_INIT)
alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
}
/* Don't take HP output as primary /* Don't take HP output as primary
* Strangely, the speaker output doesn't work on Vaio Z and some Vaio * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
* all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
...@@ -2102,6 +2119,12 @@ static const struct hda_fixup alc882_fixups[] = { ...@@ -2102,6 +2119,12 @@ static const struct hda_fixup alc882_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC882_FIXUP_GPIO1, .chain_id = ALC882_FIXUP_GPIO1,
}, },
[ALC889_FIXUP_MBA21_VREF] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc889_fixup_mba21_vref,
.chained = true,
.chain_id = ALC889_FIXUP_MBP_VREF,
},
[ALC882_FIXUP_INV_DMIC] = { [ALC882_FIXUP_INV_DMIC] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_inv_dmic_0x12, .v.func = alc_fixup_inv_dmic_0x12,
...@@ -2172,7 +2195,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ...@@ -2172,7 +2195,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
...@@ -3287,6 +3310,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) ...@@ -3287,6 +3310,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
alc_write_coef_idx(codec, 0x18, 0x7388); alc_write_coef_idx(codec, 0x18, 0x7388);
break; break;
case 0x10ec0668: case 0x10ec0668:
alc_write_coef_idx(codec, 0x11, 0x0001);
alc_write_coef_idx(codec, 0x15, 0x0d60); alc_write_coef_idx(codec, 0x15, 0x0d60);
alc_write_coef_idx(codec, 0xc3, 0x0000); alc_write_coef_idx(codec, 0xc3, 0x0000);
break; break;
...@@ -3315,6 +3339,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) ...@@ -3315,6 +3339,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
alc_write_coef_idx(codec, 0x18, 0x7388); alc_write_coef_idx(codec, 0x18, 0x7388);
break; break;
case 0x10ec0668: case 0x10ec0668:
alc_write_coef_idx(codec, 0x11, 0x0001);
alc_write_coef_idx(codec, 0x15, 0x0d50); alc_write_coef_idx(codec, 0x15, 0x0d50);
alc_write_coef_idx(codec, 0xc3, 0x0000); alc_write_coef_idx(codec, 0xc3, 0x0000);
break; break;
...@@ -3600,11 +3625,6 @@ static void alc283_hp_automute_hook(struct hda_codec *codec, ...@@ -3600,11 +3625,6 @@ static void alc283_hp_automute_hook(struct hda_codec *codec,
vref); vref);
} }
static void alc283_chromebook_caps(struct hda_codec *codec)
{
snd_hda_override_wcaps(codec, 0x03, 0);
}
static void alc283_fixup_chromebook(struct hda_codec *codec, static void alc283_fixup_chromebook(struct hda_codec *codec,
const struct hda_fixup *fix, int action) const struct hda_fixup *fix, int action)
{ {
...@@ -3613,9 +3633,26 @@ static void alc283_fixup_chromebook(struct hda_codec *codec, ...@@ -3613,9 +3633,26 @@ static void alc283_fixup_chromebook(struct hda_codec *codec,
switch (action) { switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE: case HDA_FIXUP_ACT_PRE_PROBE:
alc283_chromebook_caps(codec); snd_hda_override_wcaps(codec, 0x03, 0);
/* Disable AA-loopback as it causes white noise */ /* Disable AA-loopback as it causes white noise */
spec->gen.mixer_nid = 0; spec->gen.mixer_nid = 0;
break;
case HDA_FIXUP_ACT_INIT:
/* Enable Line1 input control by verb */
val = alc_read_coef_idx(codec, 0x1a);
alc_write_coef_idx(codec, 0x1a, val | (1 << 4));
break;
}
}
static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct alc_spec *spec = codec->spec;
int val;
switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE:
spec->gen.hp_automute_hook = alc283_hp_automute_hook; spec->gen.hp_automute_hook = alc283_hp_automute_hook;
break; break;
case HDA_FIXUP_ACT_INIT: case HDA_FIXUP_ACT_INIT:
...@@ -3623,9 +3660,6 @@ static void alc283_fixup_chromebook(struct hda_codec *codec, ...@@ -3623,9 +3660,6 @@ static void alc283_fixup_chromebook(struct hda_codec *codec,
/* Set to manual mode */ /* Set to manual mode */
val = alc_read_coef_idx(codec, 0x06); val = alc_read_coef_idx(codec, 0x06);
alc_write_coef_idx(codec, 0x06, val & ~0x000c); alc_write_coef_idx(codec, 0x06, val & ~0x000c);
/* Enable Line1 input control by verb */
val = alc_read_coef_idx(codec, 0x1a);
alc_write_coef_idx(codec, 0x1a, val | (1 << 4));
break; break;
} }
} }
...@@ -3821,6 +3855,7 @@ enum { ...@@ -3821,6 +3855,7 @@ enum {
ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
ALC269VB_FIXUP_ORDISSIMO_EVE2, ALC269VB_FIXUP_ORDISSIMO_EVE2,
ALC283_FIXUP_CHROME_BOOK, ALC283_FIXUP_CHROME_BOOK,
ALC283_FIXUP_SENSE_COMBO_JACK,
ALC282_FIXUP_ASUS_TX300, ALC282_FIXUP_ASUS_TX300,
ALC283_FIXUP_INT_MIC, ALC283_FIXUP_INT_MIC,
ALC290_FIXUP_MONO_SPEAKERS, ALC290_FIXUP_MONO_SPEAKERS,
...@@ -4120,6 +4155,12 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -4120,6 +4155,12 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc283_fixup_chromebook, .v.func = alc283_fixup_chromebook,
}, },
[ALC283_FIXUP_SENSE_COMBO_JACK] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc283_fixup_sense_combo_jack,
.chained = true,
.chain_id = ALC283_FIXUP_CHROME_BOOK,
},
[ALC282_FIXUP_ASUS_TX300] = { [ALC282_FIXUP_ASUS_TX300] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc282_fixup_asus_tx300, .v.func = alc282_fixup_asus_tx300,
...@@ -4202,6 +4243,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -4202,6 +4243,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS), SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
...@@ -4210,7 +4252,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -4210,7 +4252,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK),
SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
...@@ -4318,6 +4359,8 @@ static const struct hda_model_fixup alc269_fixup_models[] = { ...@@ -4318,6 +4359,8 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
{.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
{.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
{.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-chrome"},
{.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
{} {}
}; };
...@@ -4493,6 +4536,7 @@ enum { ...@@ -4493,6 +4536,7 @@ enum {
ALC861_FIXUP_AMP_VREF_0F, ALC861_FIXUP_AMP_VREF_0F,
ALC861_FIXUP_NO_JACK_DETECT, ALC861_FIXUP_NO_JACK_DETECT,
ALC861_FIXUP_ASUS_A6RP, ALC861_FIXUP_ASUS_A6RP,
ALC660_FIXUP_ASUS_W7J,
}; };
/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
...@@ -4542,10 +4586,22 @@ static const struct hda_fixup alc861_fixups[] = { ...@@ -4542,10 +4586,22 @@ static const struct hda_fixup alc861_fixups[] = {
.v.func = alc861_fixup_asus_amp_vref_0f, .v.func = alc861_fixup_asus_amp_vref_0f,
.chained = true, .chained = true,
.chain_id = ALC861_FIXUP_NO_JACK_DETECT, .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
},
[ALC660_FIXUP_ASUS_W7J] = {
.type = HDA_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) {
/* ASUS W7J needs a magic pin setup on unused NID 0x10
* for enabling outputs
*/
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
{ }
},
} }
}; };
static const struct snd_pci_quirk alc861_fixup_tbl[] = { static const struct snd_pci_quirk alc861_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
......
...@@ -97,6 +97,8 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev) ...@@ -97,6 +97,8 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
goto out; goto out;
} }
snd_soc_card_set_drvdata(card, priv);
card->dev = &pdev->dev; card->dev = &pdev->dev;
card->owner = THIS_MODULE; card->owner = THIS_MODULE;
card->dai_link = dai; card->dai_link = dai;
......
...@@ -248,19 +248,6 @@ ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), ...@@ -248,19 +248,6 @@ ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
ARIZONA_OUT1_OSR_SHIFT, 1, 0),
SOC_SINGLE("HPOUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
ARIZONA_OUT2_OSR_SHIFT, 1, 0),
SOC_SINGLE("HPOUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
ARIZONA_OUT3_OSR_SHIFT, 1, 0),
SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
ARIZONA_OUT4_OSR_SHIFT, 1, 0),
SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
ARIZONA_OUT5_OSR_SHIFT, 1, 0),
SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
ARIZONA_OUT6_OSR_SHIFT, 1, 0),
SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
...@@ -293,18 +280,6 @@ SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_6L, ...@@ -293,18 +280,6 @@ SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_6L,
ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_VOL_SHIFT, ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_VOL_SHIFT,
0xbf, 0, digital_tlv), 0xbf, 0, digital_tlv),
SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
ARIZONA_OUTPUT_PATH_CONFIG_1R,
ARIZONA_OUT1L_PGA_VOL_SHIFT,
0x34, 0x40, 0, ana_tlv),
SOC_DOUBLE_R_RANGE_TLV("HPOUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
ARIZONA_OUTPUT_PATH_CONFIG_2R,
ARIZONA_OUT2L_PGA_VOL_SHIFT,
0x34, 0x40, 0, ana_tlv),
SOC_DOUBLE_R_RANGE_TLV("HPOUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
ARIZONA_OUTPUT_PATH_CONFIG_3R,
ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT, SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
......
...@@ -447,10 +447,10 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -447,10 +447,10 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
iface |= 0x0001; iface |= 0x0001;
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
iface |= 0x0003; iface |= 0x0013;
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
iface |= 0x0013; iface |= 0x0003;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -1259,6 +1259,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, ...@@ -1259,6 +1259,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
/* disable POBCTRL, SOFT_ST and BUFDCOPEN */ /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
snd_soc_write(codec, WM8990_ANTIPOP2, 0x0); snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
codec->cache_sync = 1;
break; break;
} }
......
...@@ -69,7 +69,6 @@ static int pcm030_fabric_probe(struct platform_device *op) ...@@ -69,7 +69,6 @@ static int pcm030_fabric_probe(struct platform_device *op)
return -ENOMEM; return -ENOMEM;
card->dev = &op->dev; card->dev = &op->dev;
platform_set_drvdata(op, pdata);
pdata->card = card; pdata->card = card;
...@@ -98,6 +97,8 @@ static int pcm030_fabric_probe(struct platform_device *op) ...@@ -98,6 +97,8 @@ static int pcm030_fabric_probe(struct platform_device *op)
if (ret) if (ret)
dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret); dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
platform_set_drvdata(op, pdata);
return ret; return ret;
} }
......
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE) SNDRV_PCM_FMTBIT_S32_LE)
#define KIRKWOOD_SPDIF_FORMATS \
(SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE)
static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai, static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt) unsigned int fmt)
{ {
...@@ -244,15 +248,15 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, ...@@ -244,15 +248,15 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
ctl); ctl);
} }
if (dai->id == 0)
ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN; /* i2s */
else
ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN; /* spdif */
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
/* configure */ /* configure */
ctl = priv->ctl_play; ctl = priv->ctl_play;
if (dai->id == 0)
ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN; /* i2s */
else
ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN; /* spdif */
value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK; value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
writel(value, priv->io + KIRKWOOD_PLAYCTL); writel(value, priv->io + KIRKWOOD_PLAYCTL);
...@@ -449,14 +453,14 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = { ...@@ -449,14 +453,14 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = {
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_96000, SNDRV_PCM_RATE_96000,
.formats = KIRKWOOD_I2S_FORMATS, .formats = KIRKWOOD_SPDIF_FORMATS,
}, },
.capture = { .capture = {
.channels_min = 1, .channels_min = 1,
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_96000, SNDRV_PCM_RATE_96000,
.formats = KIRKWOOD_I2S_FORMATS, .formats = KIRKWOOD_SPDIF_FORMATS,
}, },
.ops = &kirkwood_i2s_dai_ops, .ops = &kirkwood_i2s_dai_ops,
}, },
...@@ -493,7 +497,7 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = { ...@@ -493,7 +497,7 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
.rates = SNDRV_PCM_RATE_8000_192000 | .rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT, SNDRV_PCM_RATE_KNOT,
.formats = KIRKWOOD_I2S_FORMATS, .formats = KIRKWOOD_SPDIF_FORMATS,
}, },
.capture = { .capture = {
.channels_min = 1, .channels_min = 1,
...@@ -501,7 +505,7 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = { ...@@ -501,7 +505,7 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
.rates = SNDRV_PCM_RATE_8000_192000 | .rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT, SNDRV_PCM_RATE_KNOT,
.formats = KIRKWOOD_I2S_FORMATS, .formats = KIRKWOOD_SPDIF_FORMATS,
}, },
.ops = &kirkwood_i2s_dai_ops, .ops = &kirkwood_i2s_dai_ops,
}, },
......
...@@ -100,12 +100,12 @@ static int n810_startup(struct snd_pcm_substream *substream) ...@@ -100,12 +100,12 @@ static int n810_startup(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
n810_ext_control(&codec->dapm); n810_ext_control(&codec->dapm);
return clk_enable(sys_clkout2); return clk_prepare_enable(sys_clkout2);
} }
static void n810_shutdown(struct snd_pcm_substream *substream) static void n810_shutdown(struct snd_pcm_substream *substream)
{ {
clk_disable(sys_clkout2); clk_disable_unprepare(sys_clkout2);
} }
static int n810_hw_params(struct snd_pcm_substream *substream, static int n810_hw_params(struct snd_pcm_substream *substream,
......
...@@ -37,6 +37,7 @@ config SND_SOC_SH4_SIU ...@@ -37,6 +37,7 @@ config SND_SOC_SH4_SIU
config SND_SOC_RCAR config SND_SOC_RCAR
tristate "R-Car series SRU/SCU/SSIU/SSI support" tristate "R-Car series SRU/SCU/SSIU/SSI support"
select SND_SIMPLE_CARD select SND_SIMPLE_CARD
select REGMAP
help help
This option enables R-Car SUR/SCU/SSIU/SSI sound support This option enables R-Car SUR/SCU/SSIU/SSI sound support
......
...@@ -3212,11 +3212,11 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, ...@@ -3212,11 +3212,11 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
break; break;
case 2: case 2:
((u16 *)(&ucontrol->value.bytes.data))[0] ((u16 *)(&ucontrol->value.bytes.data))[0]
&= ~params->mask; &= cpu_to_be16(~params->mask);
break; break;
case 4: case 4:
((u32 *)(&ucontrol->value.bytes.data))[0] ((u32 *)(&ucontrol->value.bytes.data))[0]
&= ~params->mask; &= cpu_to_be32(~params->mask);
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -66,7 +66,7 @@ static void devm_card_release(struct device *dev, void *res) ...@@ -66,7 +66,7 @@ static void devm_card_release(struct device *dev, void *res)
*/ */
int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
{ {
struct device **ptr; struct snd_soc_card **ptr;
int ret; int ret;
ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL); ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL);
...@@ -75,7 +75,7 @@ int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) ...@@ -75,7 +75,7 @@ int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
ret = snd_soc_register_card(card); ret = snd_soc_register_card(card);
if (ret == 0) { if (ret == 0) {
*ptr = dev; *ptr = card;
devres_add(dev, ptr); devres_add(dev, ptr);
} else { } else {
devres_free(ptr); devres_free(ptr);
......
...@@ -148,12 +148,12 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, ...@@ -148,12 +148,12 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
} }
} }
static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw, static void soc_pcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
struct snd_soc_pcm_stream *codec_stream, struct snd_soc_pcm_stream *codec_stream,
struct snd_soc_pcm_stream *cpu_stream) struct snd_soc_pcm_stream *cpu_stream)
{ {
hw->rate_min = max(codec_stream->rate_min, cpu_stream->rate_min); struct snd_pcm_hardware *hw = &runtime->hw;
hw->rate_max = max(codec_stream->rate_max, cpu_stream->rate_max);
hw->channels_min = max(codec_stream->channels_min, hw->channels_min = max(codec_stream->channels_min,
cpu_stream->channels_min); cpu_stream->channels_min);
hw->channels_max = min(codec_stream->channels_max, hw->channels_max = min(codec_stream->channels_max,
...@@ -166,6 +166,13 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw, ...@@ -166,6 +166,13 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
if (cpu_stream->rates if (cpu_stream->rates
& (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
hw->rates |= codec_stream->rates; hw->rates |= codec_stream->rates;
snd_pcm_limit_hw_rates(runtime);
hw->rate_min = max(hw->rate_min, cpu_stream->rate_min);
hw->rate_min = max(hw->rate_min, codec_stream->rate_min);
hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max);
hw->rate_max = min_not_zero(hw->rate_max, codec_stream->rate_max);
} }
/* /*
...@@ -235,15 +242,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) ...@@ -235,15 +242,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
/* Check that the codec and cpu DAIs are compatible */ /* Check that the codec and cpu DAIs are compatible */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->playback, soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->playback,
&cpu_dai_drv->playback); &cpu_dai_drv->playback);
} else { } else {
soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->capture, soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->capture,
&cpu_dai_drv->capture); &cpu_dai_drv->capture);
} }
ret = -EINVAL; ret = -EINVAL;
snd_pcm_limit_hw_rates(runtime);
if (!runtime->hw.rates) { if (!runtime->hw.rates) {
printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n",
codec_dai->name, cpu_dai->name); codec_dai->name, cpu_dai->name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册