Commit b532ff20 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull sound fixes from Takashi Iwai:

 - Fix a regression of USB-audio PCM assignment since 3.4
 - A few VGA-switcheroo-related fixes for proper HDMI audio enablement
 - Fixed the missing initializations of HD-audio verbs, which may have
   resulted in various breakage
 - Some driver-specific ASoC updates
 - A few fixes for the dynamic PCM code
 - The addition of pinctrl support for the i.MX audmux which didn't make
   it into -rc1 due to cross tree dependency issues
 - A few minor fixes in compress API codes

* tag 'sound-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Don't forget to call init verbs added by fixup list
  ALSA: HDA: Pin fixup for Zotac Z68 motherboard
  ALSA: compress_core: cleanup pointers on stop
  ALSA: compress_core: don't wake up on pause
  ALSA: hda - Fix detection of Creative SoundCore3D controllers
  vga_switcheroo: Enable/disable audio clients at the right time
  ALSA: hda - HDMI Audio init all connectors when VGA-switcheroo is off
  vga_switcheroo: Fix error without CONFIG_VGA_SWITCHEROO
  ALSA: hda - Fix uninitialized HDMI controllers with VGA-switcheroo
  vga_switcheroo: Add a helper function to get the client state
  ALSA: usb-audio: Fix substream assignments
  ASoC: tegra: add MODULE_DEVICE_TABLE to tegra30_ahub
  ASoC: wm2000: Always use a 4s timeout for the firmware
  ASoC: dapm: Fix input list to use source widgets
  ASoC: dpcm: Fix dpcm_get_be() to check that DAI is BE
  ASoC: wm8994: Apply volume updates with clocks enabled
  ASoC: wm8994: Ensure all AIFnCLK events are run from the _late variants
  ASoC: imx-audmux: add pinctrl support
  ASoC: dapm: Fix connected widget capture path query.
parents fea7c783 2e8b2b29
...@@ -190,6 +190,19 @@ find_active_client(struct list_head *head) ...@@ -190,6 +190,19 @@ find_active_client(struct list_head *head)
return NULL; return NULL;
} }
int vga_switcheroo_get_client_state(struct pci_dev *pdev)
{
struct vga_switcheroo_client *client;
client = find_client_from_pci(&vgasr_priv.clients, pdev);
if (!client)
return VGA_SWITCHEROO_NOT_FOUND;
if (!vgasr_priv.active)
return VGA_SWITCHEROO_INIT;
return client->pwr_state;
}
EXPORT_SYMBOL(vga_switcheroo_get_client_state);
void vga_switcheroo_unregister_client(struct pci_dev *pdev) void vga_switcheroo_unregister_client(struct pci_dev *pdev)
{ {
struct vga_switcheroo_client *client; struct vga_switcheroo_client *client;
...@@ -291,8 +304,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) ...@@ -291,8 +304,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
vga_switchon(new_client); vga_switchon(new_client);
vga_set_default_device(new_client->pdev); vga_set_default_device(new_client->pdev);
set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
return 0; return 0;
} }
...@@ -308,6 +319,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) ...@@ -308,6 +319,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
active->active = false; active->active = false;
set_audio_state(active->id, VGA_SWITCHEROO_OFF);
if (new_client->fb_info) { if (new_client->fb_info) {
struct fb_event event; struct fb_event event;
event.info = new_client->fb_info; event.info = new_client->fb_info;
...@@ -321,11 +334,11 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) ...@@ -321,11 +334,11 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
if (new_client->ops->reprobe) if (new_client->ops->reprobe)
new_client->ops->reprobe(new_client->pdev); new_client->ops->reprobe(new_client->pdev);
set_audio_state(active->id, VGA_SWITCHEROO_OFF);
if (active->pwr_state == VGA_SWITCHEROO_ON) if (active->pwr_state == VGA_SWITCHEROO_ON)
vga_switchoff(active); vga_switchoff(active);
set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
new_client->active = true; new_client->active = true;
return 0; return 0;
} }
...@@ -371,8 +384,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, ...@@ -371,8 +384,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
/* pwr off the device not in use */ /* pwr off the device not in use */
if (strncmp(usercmd, "OFF", 3) == 0) { if (strncmp(usercmd, "OFF", 3) == 0) {
list_for_each_entry(client, &vgasr_priv.clients, list) { list_for_each_entry(client, &vgasr_priv.clients, list) {
if (client->active) if (client->active || client_is_audio(client))
continue; continue;
set_audio_state(client->id, VGA_SWITCHEROO_OFF);
if (client->pwr_state == VGA_SWITCHEROO_ON) if (client->pwr_state == VGA_SWITCHEROO_ON)
vga_switchoff(client); vga_switchoff(client);
} }
...@@ -381,10 +395,11 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, ...@@ -381,10 +395,11 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
/* pwr on the device not in use */ /* pwr on the device not in use */
if (strncmp(usercmd, "ON", 2) == 0) { if (strncmp(usercmd, "ON", 2) == 0) {
list_for_each_entry(client, &vgasr_priv.clients, list) { list_for_each_entry(client, &vgasr_priv.clients, list) {
if (client->active) if (client->active || client_is_audio(client))
continue; continue;
if (client->pwr_state == VGA_SWITCHEROO_OFF) if (client->pwr_state == VGA_SWITCHEROO_OFF)
vga_switchon(client); vga_switchon(client);
set_audio_state(client->id, VGA_SWITCHEROO_ON);
} }
goto out; goto out;
} }
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
enum vga_switcheroo_state { enum vga_switcheroo_state {
VGA_SWITCHEROO_OFF, VGA_SWITCHEROO_OFF,
VGA_SWITCHEROO_ON, VGA_SWITCHEROO_ON,
/* below are referred only from vga_switcheroo_get_client_state() */
VGA_SWITCHEROO_INIT,
VGA_SWITCHEROO_NOT_FOUND,
}; };
enum vga_switcheroo_client_id { enum vga_switcheroo_client_id {
...@@ -50,6 +53,8 @@ void vga_switcheroo_unregister_handler(void); ...@@ -50,6 +53,8 @@ void vga_switcheroo_unregister_handler(void);
int vga_switcheroo_process_delayed_switch(void); int vga_switcheroo_process_delayed_switch(void);
int vga_switcheroo_get_client_state(struct pci_dev *dev);
#else #else
static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
...@@ -62,5 +67,7 @@ static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, ...@@ -62,5 +67,7 @@ static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
int id, bool active) { return 0; } int id, bool active) { return 0; }
static inline void vga_switcheroo_unregister_handler(void) {} static inline void vga_switcheroo_unregister_handler(void) {}
static inline int vga_switcheroo_process_delayed_switch(void) { return 0; } static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; }
#endif #endif
...@@ -502,10 +502,8 @@ static int snd_compr_pause(struct snd_compr_stream *stream) ...@@ -502,10 +502,8 @@ static int snd_compr_pause(struct snd_compr_stream *stream)
if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING) if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
return -EPERM; return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH); retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
if (!retval) { if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_PAUSED; stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
wake_up(&stream->runtime->sleep);
}
return retval; return retval;
} }
...@@ -544,6 +542,10 @@ static int snd_compr_stop(struct snd_compr_stream *stream) ...@@ -544,6 +542,10 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
if (!retval) { if (!retval) {
stream->runtime->state = SNDRV_PCM_STATE_SETUP; stream->runtime->state = SNDRV_PCM_STATE_SETUP;
wake_up(&stream->runtime->sleep); wake_up(&stream->runtime->sleep);
stream->runtime->hw_pointer = 0;
stream->runtime->app_pointer = 0;
stream->runtime->total_bytes_available = 0;
stream->runtime->total_bytes_transferred = 0;
} }
return retval; return retval;
} }
......
...@@ -2484,9 +2484,9 @@ static void azx_notifier_unregister(struct azx *chip) ...@@ -2484,9 +2484,9 @@ static void azx_notifier_unregister(struct azx *chip)
static int DELAYED_INIT_MARK azx_first_init(struct azx *chip); static int DELAYED_INIT_MARK azx_first_init(struct azx *chip);
static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip); static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip);
#ifdef SUPPORT_VGA_SWITCHEROO
static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci); static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci);
#ifdef SUPPORT_VGA_SWITCHEROO
static void azx_vs_set_state(struct pci_dev *pci, static void azx_vs_set_state(struct pci_dev *pci,
enum vga_switcheroo_state state) enum vga_switcheroo_state state)
{ {
...@@ -2578,6 +2578,7 @@ static int __devinit register_vga_switcheroo(struct azx *chip) ...@@ -2578,6 +2578,7 @@ static int __devinit register_vga_switcheroo(struct azx *chip)
#else #else
#define init_vga_switcheroo(chip) /* NOP */ #define init_vga_switcheroo(chip) /* NOP */
#define register_vga_switcheroo(chip) 0 #define register_vga_switcheroo(chip) 0
#define check_hdmi_disabled(pci) false
#endif /* SUPPORT_VGA_SWITCHER */ #endif /* SUPPORT_VGA_SWITCHER */
/* /*
...@@ -2638,6 +2639,7 @@ static int azx_dev_free(struct snd_device *device) ...@@ -2638,6 +2639,7 @@ static int azx_dev_free(struct snd_device *device)
return azx_free(device->device_data); return azx_free(device->device_data);
} }
#ifdef SUPPORT_VGA_SWITCHEROO
/* /*
* Check of disabled HDMI controller by vga-switcheroo * Check of disabled HDMI controller by vga-switcheroo
*/ */
...@@ -2670,12 +2672,13 @@ static bool __devinit check_hdmi_disabled(struct pci_dev *pci) ...@@ -2670,12 +2672,13 @@ static bool __devinit check_hdmi_disabled(struct pci_dev *pci)
struct pci_dev *p = get_bound_vga(pci); struct pci_dev *p = get_bound_vga(pci);
if (p) { if (p) {
if (vga_default_device() && p != vga_default_device()) if (vga_switcheroo_get_client_state(p) == VGA_SWITCHEROO_OFF)
vga_inactive = true; vga_inactive = true;
pci_dev_put(p); pci_dev_put(p);
} }
return vga_inactive; return vga_inactive;
} }
#endif /* SUPPORT_VGA_SWITCHEROO */
/* /*
* white/black-listing for position_fix * white/black-listing for position_fix
...@@ -3351,6 +3354,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { ...@@ -3351,6 +3354,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(0x6549, 0x1200), { PCI_DEVICE(0x6549, 0x1200),
.driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
/* Creative X-Fi (CA0110-IBG) */ /* Creative X-Fi (CA0110-IBG) */
/* CTHDA chips */
{ PCI_DEVICE(0x1102, 0x0010),
.driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
{ PCI_DEVICE(0x1102, 0x0012),
.driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
/* the following entry conflicts with snd-ctxfi driver, /* the following entry conflicts with snd-ctxfi driver,
* as ctxfi driver mutates from HD-audio to native mode with * as ctxfi driver mutates from HD-audio to native mode with
...@@ -3367,11 +3375,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { ...@@ -3367,11 +3375,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
.driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
#endif #endif
/* CTHDA chips */
{ PCI_DEVICE(0x1102, 0x0010),
.driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
{ PCI_DEVICE(0x1102, 0x0012),
.driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
/* Vortex86MX */ /* Vortex86MX */
{ PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
/* VMware HDAudio */ /* VMware HDAudio */
......
...@@ -4061,7 +4061,7 @@ static void cx_auto_init_digital(struct hda_codec *codec) ...@@ -4061,7 +4061,7 @@ static void cx_auto_init_digital(struct hda_codec *codec)
static int cx_auto_init(struct hda_codec *codec) static int cx_auto_init(struct hda_codec *codec)
{ {
struct conexant_spec *spec = codec->spec; struct conexant_spec *spec = codec->spec;
/*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ snd_hda_gen_apply_verbs(codec);
cx_auto_init_output(codec); cx_auto_init_output(codec);
cx_auto_init_input(codec); cx_auto_init_input(codec);
cx_auto_init_digital(codec); cx_auto_init_digital(codec);
......
...@@ -1896,6 +1896,7 @@ static int alc_init(struct hda_codec *codec) ...@@ -1896,6 +1896,7 @@ static int alc_init(struct hda_codec *codec)
alc_fix_pll(codec); alc_fix_pll(codec);
alc_auto_init_amp(codec, spec->init_amp); alc_auto_init_amp(codec, spec->init_amp);
snd_hda_gen_apply_verbs(codec);
alc_init_special_input_src(codec); alc_init_special_input_src(codec);
alc_auto_init_std(codec); alc_auto_init_std(codec);
...@@ -6439,6 +6440,7 @@ enum { ...@@ -6439,6 +6440,7 @@ enum {
ALC662_FIXUP_ASUS_MODE7, ALC662_FIXUP_ASUS_MODE7,
ALC662_FIXUP_ASUS_MODE8, ALC662_FIXUP_ASUS_MODE8,
ALC662_FIXUP_NO_JACK_DETECT, ALC662_FIXUP_NO_JACK_DETECT,
ALC662_FIXUP_ZOTAC_Z68,
}; };
static const struct alc_fixup alc662_fixups[] = { static const struct alc_fixup alc662_fixups[] = {
...@@ -6588,6 +6590,13 @@ static const struct alc_fixup alc662_fixups[] = { ...@@ -6588,6 +6590,13 @@ static const struct alc_fixup alc662_fixups[] = {
.type = ALC_FIXUP_FUNC, .type = ALC_FIXUP_FUNC,
.v.func = alc_fixup_no_jack_detect, .v.func = alc_fixup_no_jack_detect,
}, },
[ALC662_FIXUP_ZOTAC_Z68] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
{ 0x1b, 0x02214020 }, /* Front HP */
{ }
}
},
}; };
static const struct snd_pci_quirk alc662_fixup_tbl[] = { static const struct snd_pci_quirk alc662_fixup_tbl[] = {
...@@ -6601,6 +6610,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { ...@@ -6601,6 +6610,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
#if 0 #if 0
......
...@@ -99,8 +99,9 @@ static void wm2000_reset(struct wm2000_priv *wm2000) ...@@ -99,8 +99,9 @@ static void wm2000_reset(struct wm2000_priv *wm2000)
} }
static int wm2000_poll_bit(struct i2c_client *i2c, static int wm2000_poll_bit(struct i2c_client *i2c,
unsigned int reg, u8 mask, int timeout) unsigned int reg, u8 mask)
{ {
int timeout = 4000;
int val; int val;
val = wm2000_read(i2c, reg); val = wm2000_read(i2c, reg);
...@@ -119,7 +120,7 @@ static int wm2000_poll_bit(struct i2c_client *i2c, ...@@ -119,7 +120,7 @@ static int wm2000_poll_bit(struct i2c_client *i2c,
static int wm2000_power_up(struct i2c_client *i2c, int analogue) static int wm2000_power_up(struct i2c_client *i2c, int analogue)
{ {
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
int ret, timeout; int ret;
BUG_ON(wm2000->anc_mode != ANC_OFF); BUG_ON(wm2000->anc_mode != ANC_OFF);
...@@ -140,13 +141,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) ...@@ -140,13 +141,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
/* Wait for ANC engine to become ready */ /* Wait for ANC engine to become ready */
if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
WM2000_ANC_ENG_IDLE, 1)) { WM2000_ANC_ENG_IDLE)) {
dev_err(&i2c->dev, "ANC engine failed to reset\n"); dev_err(&i2c->dev, "ANC engine failed to reset\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_BOOT_COMPLETE, 1)) { WM2000_STATUS_BOOT_COMPLETE)) {
dev_err(&i2c->dev, "ANC engine failed to initialise\n"); dev_err(&i2c->dev, "ANC engine failed to initialise\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -173,16 +174,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) ...@@ -173,16 +174,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
dev_dbg(&i2c->dev, "Download complete\n"); dev_dbg(&i2c->dev, "Download complete\n");
if (analogue) { if (analogue) {
timeout = 248; wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4);
wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_ANA_SEQ_INCLUDE |
WM2000_MODE_MOUSE_ENABLE | WM2000_MODE_MOUSE_ENABLE |
WM2000_MODE_THERMAL_ENABLE); WM2000_MODE_THERMAL_ENABLE);
} else { } else {
timeout = 10;
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_MOUSE_ENABLE | WM2000_MODE_MOUSE_ENABLE |
WM2000_MODE_THERMAL_ENABLE); WM2000_MODE_THERMAL_ENABLE);
...@@ -201,9 +199,8 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) ...@@ -201,9 +199,8 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_MOUSE_ACTIVE, timeout)) { WM2000_STATUS_MOUSE_ACTIVE)) {
dev_err(&i2c->dev, "Timed out waiting for device after %dms\n", dev_err(&i2c->dev, "Timed out waiting for device\n");
timeout * 10);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -218,28 +215,25 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) ...@@ -218,28 +215,25 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
static int wm2000_power_down(struct i2c_client *i2c, int analogue) static int wm2000_power_down(struct i2c_client *i2c, int analogue)
{ {
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
int timeout;
if (analogue) { if (analogue) {
timeout = 248; wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4);
wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_ANA_SEQ_INCLUDE |
WM2000_MODE_POWER_DOWN); WM2000_MODE_POWER_DOWN);
} else { } else {
timeout = 10;
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_POWER_DOWN); WM2000_MODE_POWER_DOWN);
} }
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) { WM2000_STATUS_POWER_DOWN_COMPLETE)) {
dev_err(&i2c->dev, "Timeout waiting for ANC power down\n"); dev_err(&i2c->dev, "Timeout waiting for ANC power down\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
WM2000_ANC_ENG_IDLE, 1)) { WM2000_ANC_ENG_IDLE)) {
dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n"); dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -268,13 +262,13 @@ static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue) ...@@ -268,13 +262,13 @@ static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)
} }
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_ANC_DISABLED, 10)) { WM2000_STATUS_ANC_DISABLED)) {
dev_err(&i2c->dev, "Timeout waiting for ANC disable\n"); dev_err(&i2c->dev, "Timeout waiting for ANC disable\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
WM2000_ANC_ENG_IDLE, 1)) { WM2000_ANC_ENG_IDLE)) {
dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n"); dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -311,7 +305,7 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue) ...@@ -311,7 +305,7 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)
wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_MOUSE_ACTIVE, 10)) { WM2000_STATUS_MOUSE_ACTIVE)) {
dev_err(&i2c->dev, "Timed out waiting for MOUSE\n"); dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -325,38 +319,32 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue) ...@@ -325,38 +319,32 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)
static int wm2000_enter_standby(struct i2c_client *i2c, int analogue) static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)
{ {
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
int timeout;
BUG_ON(wm2000->anc_mode != ANC_ACTIVE); BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
if (analogue) { if (analogue) {
timeout = 248; wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4);
wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_ANA_SEQ_INCLUDE |
WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_THERMAL_ENABLE |
WM2000_MODE_STANDBY_ENTRY); WM2000_MODE_STANDBY_ENTRY);
} else { } else {
timeout = 10;
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_THERMAL_ENABLE |
WM2000_MODE_STANDBY_ENTRY); WM2000_MODE_STANDBY_ENTRY);
} }
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_ANC_DISABLED, timeout)) { WM2000_STATUS_ANC_DISABLED)) {
dev_err(&i2c->dev, dev_err(&i2c->dev,
"Timed out waiting for ANC disable after 1ms\n"); "Timed out waiting for ANC disable after 1ms\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE, if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE)) {
1)) {
dev_err(&i2c->dev, dev_err(&i2c->dev,
"Timed out waiting for standby after %dms\n", "Timed out waiting for standby\n");
timeout * 10);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -374,23 +362,19 @@ static int wm2000_enter_standby(struct i2c_client *i2c, int analogue) ...@@ -374,23 +362,19 @@ static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)
static int wm2000_exit_standby(struct i2c_client *i2c, int analogue) static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)
{ {
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
int timeout;
BUG_ON(wm2000->anc_mode != ANC_STANDBY); BUG_ON(wm2000->anc_mode != ANC_STANDBY);
wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0); wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
if (analogue) { if (analogue) {
timeout = 248; wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4);
wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_ANA_SEQ_INCLUDE |
WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_THERMAL_ENABLE |
WM2000_MODE_MOUSE_ENABLE); WM2000_MODE_MOUSE_ENABLE);
} else { } else {
timeout = 10;
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_THERMAL_ENABLE |
WM2000_MODE_MOUSE_ENABLE); WM2000_MODE_MOUSE_ENABLE);
...@@ -400,9 +384,8 @@ static int wm2000_exit_standby(struct i2c_client *i2c, int analogue) ...@@ -400,9 +384,8 @@ static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)
wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_MOUSE_ACTIVE, timeout)) { WM2000_STATUS_MOUSE_ACTIVE)) {
dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n", dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
timeout * 10);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
......
...@@ -46,6 +46,39 @@ ...@@ -46,6 +46,39 @@
#define WM8994_NUM_DRC 3 #define WM8994_NUM_DRC 3
#define WM8994_NUM_EQ 3 #define WM8994_NUM_EQ 3
static struct {
unsigned int reg;
unsigned int mask;
} wm8994_vu_bits[] = {
{ WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
{ WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
{ WM8994_LEFT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU },
{ WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU },
{ WM8994_SPEAKER_VOLUME_LEFT, WM8994_SPKOUT_VU },
{ WM8994_SPEAKER_VOLUME_RIGHT, WM8994_SPKOUT_VU },
{ WM8994_LEFT_OUTPUT_VOLUME, WM8994_HPOUT1_VU },
{ WM8994_RIGHT_OUTPUT_VOLUME, WM8994_HPOUT1_VU },
{ WM8994_LEFT_OPGA_VOLUME, WM8994_MIXOUT_VU },
{ WM8994_RIGHT_OPGA_VOLUME, WM8994_MIXOUT_VU },
{ WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1DAC1_VU },
{ WM8994_AIF1_DAC1_RIGHT_VOLUME, WM8994_AIF1DAC1_VU },
{ WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU },
{ WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU },
{ WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2DAC_VU },
{ WM8994_AIF2_DAC_RIGHT_VOLUME, WM8994_AIF2DAC_VU },
{ WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1ADC1_VU },
{ WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1ADC1_VU },
{ WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU },
{ WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
{ WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2ADC_VU },
{ WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
{ WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_VU },
{ WM8994_DAC1_RIGHT_VOLUME, WM8994_DAC1_VU },
{ WM8994_DAC2_LEFT_VOLUME, WM8994_DAC2_VU },
{ WM8994_DAC2_RIGHT_VOLUME, WM8994_DAC2_VU },
};
static int wm8994_drc_base[] = { static int wm8994_drc_base[] = {
WM8994_AIF1_DRC1_1, WM8994_AIF1_DRC1_1,
WM8994_AIF1_DRC2_1, WM8994_AIF1_DRC2_1,
...@@ -989,6 +1022,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, ...@@ -989,6 +1022,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
struct snd_soc_codec *codec = w->codec; struct snd_soc_codec *codec = w->codec;
struct wm8994 *control = codec->control_data; struct wm8994 *control = codec->control_data;
int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
int i;
int dac; int dac;
int adc; int adc;
int val; int val;
...@@ -1047,6 +1081,13 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, ...@@ -1047,6 +1081,13 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
WM8994_AIF1DAC2L_ENA); WM8994_AIF1DAC2L_ENA);
break; break;
case SND_SOC_DAPM_POST_PMU:
for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
snd_soc_write(codec, wm8994_vu_bits[i].reg,
snd_soc_read(codec,
wm8994_vu_bits[i].reg));
break;
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD:
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
...@@ -1072,6 +1113,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, ...@@ -1072,6 +1113,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
{ {
struct snd_soc_codec *codec = w->codec; struct snd_soc_codec *codec = w->codec;
int i;
int dac; int dac;
int adc; int adc;
int val; int val;
...@@ -1122,6 +1164,13 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, ...@@ -1122,6 +1164,13 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
WM8994_AIF2DACR_ENA); WM8994_AIF2DACR_ENA);
break; break;
case SND_SOC_DAPM_POST_PMU:
for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
snd_soc_write(codec, wm8994_vu_bits[i].reg,
snd_soc_read(codec,
wm8994_vu_bits[i].reg));
break;
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD:
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
...@@ -1190,17 +1239,19 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w, ...@@ -1190,17 +1239,19 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
if (wm8994->aif1clk_enable) { if (wm8994->aif1clk_enable) {
aif1clk_ev(w, kcontrol, event); aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU);
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
WM8994_AIF1CLK_ENA_MASK, WM8994_AIF1CLK_ENA_MASK,
WM8994_AIF1CLK_ENA); WM8994_AIF1CLK_ENA);
aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
wm8994->aif1clk_enable = 0; wm8994->aif1clk_enable = 0;
} }
if (wm8994->aif2clk_enable) { if (wm8994->aif2clk_enable) {
aif2clk_ev(w, kcontrol, event); aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU);
snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
WM8994_AIF2CLK_ENA_MASK, WM8994_AIF2CLK_ENA_MASK,
WM8994_AIF2CLK_ENA); WM8994_AIF2CLK_ENA);
aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
wm8994->aif2clk_enable = 0; wm8994->aif2clk_enable = 0;
} }
break; break;
...@@ -1221,15 +1272,17 @@ static int late_disable_ev(struct snd_soc_dapm_widget *w, ...@@ -1221,15 +1272,17 @@ static int late_disable_ev(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
if (wm8994->aif1clk_disable) { if (wm8994->aif1clk_disable) {
aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
WM8994_AIF1CLK_ENA_MASK, 0); WM8994_AIF1CLK_ENA_MASK, 0);
aif1clk_ev(w, kcontrol, event); aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
wm8994->aif1clk_disable = 0; wm8994->aif1clk_disable = 0;
} }
if (wm8994->aif2clk_disable) { if (wm8994->aif2clk_disable) {
aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
WM8994_AIF2CLK_ENA_MASK, 0); WM8994_AIF2CLK_ENA_MASK, 0);
aif2clk_ev(w, kcontrol, event); aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
wm8994->aif2clk_disable = 0; wm8994->aif2clk_disable = 0;
} }
break; break;
...@@ -1527,9 +1580,11 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) ...@@ -1527,9 +1580,11 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev, SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev, SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
...@@ -3879,39 +3934,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) ...@@ -3879,39 +3934,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
pm_runtime_put(codec->dev); pm_runtime_put(codec->dev);
/* Latch volume updates (right only; we always do left then right). */ /* Latch volume update bits */
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); snd_soc_update_bits(codec, wm8994_vu_bits[i].reg,
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME, wm8994_vu_bits[i].mask,
WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); wm8994_vu_bits[i].mask);
snd_soc_update_bits(codec, WM8994_AIF1_DAC2_LEFT_VOLUME,
WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
snd_soc_update_bits(codec, WM8994_AIF2_DAC_LEFT_VOLUME,
WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
snd_soc_update_bits(codec, WM8994_AIF1_ADC1_LEFT_VOLUME,
WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
snd_soc_update_bits(codec, WM8994_AIF1_ADC2_LEFT_VOLUME,
WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
snd_soc_update_bits(codec, WM8994_AIF2_ADC_LEFT_VOLUME,
WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
snd_soc_update_bits(codec, WM8994_DAC1_LEFT_VOLUME,
WM8994_DAC1_VU, WM8994_DAC1_VU);
snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
WM8994_DAC1_VU, WM8994_DAC1_VU);
snd_soc_update_bits(codec, WM8994_DAC2_LEFT_VOLUME,
WM8994_DAC2_VU, WM8994_DAC2_VU);
snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
WM8994_DAC2_VU, WM8994_DAC2_VU);
/* Set the low bit of the 3D stereo depth so TLV matches */ /* Set the low bit of the 3D stereo depth so TLV matches */
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2, snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pinctrl/consumer.h>
#include "imx-audmux.h" #include "imx-audmux.h"
...@@ -249,6 +250,7 @@ EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); ...@@ -249,6 +250,7 @@ EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
static int __devinit imx_audmux_probe(struct platform_device *pdev) static int __devinit imx_audmux_probe(struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;
struct pinctrl *pinctrl;
const struct of_device_id *of_id = const struct of_device_id *of_id =
of_match_device(imx_audmux_dt_ids, &pdev->dev); of_match_device(imx_audmux_dt_ids, &pdev->dev);
...@@ -257,6 +259,12 @@ static int __devinit imx_audmux_probe(struct platform_device *pdev) ...@@ -257,6 +259,12 @@ static int __devinit imx_audmux_probe(struct platform_device *pdev)
if (!audmux_base) if (!audmux_base)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl)) {
dev_err(&pdev->dev, "setup pinctrl failed!");
return PTR_ERR(pinctrl);
}
audmux_clk = clk_get(&pdev->dev, "audmux"); audmux_clk = clk_get(&pdev->dev, "audmux");
if (IS_ERR(audmux_clk)) { if (IS_ERR(audmux_clk)) {
dev_dbg(&pdev->dev, "cannot get clock: %ld\n", dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
......
...@@ -913,7 +913,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, ...@@ -913,7 +913,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
/* do we need to add this widget to the list ? */ /* do we need to add this widget to the list ? */
if (list) { if (list) {
int err; int err;
err = dapm_list_add_widget(list, path->sink); err = dapm_list_add_widget(list, path->source);
if (err < 0) { if (err < 0) {
dev_err(widget->dapm->dev, "could not add widget %s\n", dev_err(widget->dapm->dev, "could not add widget %s\n",
widget->name); widget->name);
...@@ -954,7 +954,7 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, ...@@ -954,7 +954,7 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
if (stream == SNDRV_PCM_STREAM_PLAYBACK) if (stream == SNDRV_PCM_STREAM_PLAYBACK)
paths = is_connected_output_ep(dai->playback_widget, list); paths = is_connected_output_ep(dai->playback_widget, list);
else else
paths = is_connected_input_ep(dai->playback_widget, list); paths = is_connected_input_ep(dai->capture_widget, list);
trace_snd_soc_dapm_connected(paths, stream); trace_snd_soc_dapm_connected(paths, stream);
dapm_clear_walk(&card->dapm); dapm_clear_walk(&card->dapm);
......
...@@ -794,6 +794,9 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, ...@@ -794,6 +794,9 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
for (i = 0; i < card->num_links; i++) { for (i = 0; i < card->num_links; i++) {
be = &card->rtd[i]; be = &card->rtd[i];
if (!be->dai_link->no_pcm)
continue;
if (be->cpu_dai->playback_widget == widget || if (be->cpu_dai->playback_widget == widget ||
be->codec_dai->playback_widget == widget) be->codec_dai->playback_widget == widget)
return be; return be;
...@@ -803,6 +806,9 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, ...@@ -803,6 +806,9 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
for (i = 0; i < card->num_links; i++) { for (i = 0; i < card->num_links; i++) {
be = &card->rtd[i]; be = &card->rtd[i];
if (!be->dai_link->no_pcm)
continue;
if (be->cpu_dai->capture_widget == widget || if (be->cpu_dai->capture_widget == widget ||
be->codec_dai->capture_widget == widget) be->codec_dai->capture_widget == widget)
return be; return be;
......
...@@ -629,3 +629,4 @@ MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); ...@@ -629,3 +629,4 @@ MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("Tegra30 AHUB driver"); MODULE_DESCRIPTION("Tegra30 AHUB driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME); MODULE_ALIAS("platform:" DRV_NAME);
MODULE_DEVICE_TABLE(of, tegra30_ahub_of_match);
...@@ -119,6 +119,7 @@ struct snd_usb_substream { ...@@ -119,6 +119,7 @@ struct snd_usb_substream {
unsigned long unlink_mask; /* bitmask of unlinked urbs */ unsigned long unlink_mask; /* bitmask of unlinked urbs */
/* data and sync endpoints for this stream */ /* data and sync endpoints for this stream */
unsigned int ep_num; /* the endpoint number */
struct snd_usb_endpoint *data_endpoint; struct snd_usb_endpoint *data_endpoint;
struct snd_usb_endpoint *sync_endpoint; struct snd_usb_endpoint *sync_endpoint;
unsigned long flags; unsigned long flags;
......
...@@ -97,6 +97,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, ...@@ -97,6 +97,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
subs->formats |= fp->formats; subs->formats |= fp->formats;
subs->num_formats++; subs->num_formats++;
subs->fmt_type = fp->fmt_type; subs->fmt_type = fp->fmt_type;
subs->ep_num = fp->endpoint;
} }
/* /*
...@@ -119,9 +120,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, ...@@ -119,9 +120,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
if (as->fmt_type != fp->fmt_type) if (as->fmt_type != fp->fmt_type)
continue; continue;
subs = &as->substream[stream]; subs = &as->substream[stream];
if (!subs->data_endpoint) if (subs->ep_num == fp->endpoint) {
continue;
if (subs->data_endpoint->ep_num == fp->endpoint) {
list_add_tail(&fp->list, &subs->fmt_list); list_add_tail(&fp->list, &subs->fmt_list);
subs->num_formats++; subs->num_formats++;
subs->formats |= fp->formats; subs->formats |= fp->formats;
...@@ -134,7 +133,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, ...@@ -134,7 +133,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
if (as->fmt_type != fp->fmt_type) if (as->fmt_type != fp->fmt_type)
continue; continue;
subs = &as->substream[stream]; subs = &as->substream[stream];
if (subs->data_endpoint) if (subs->ep_num)
continue; continue;
err = snd_pcm_new_stream(as->pcm, stream, 1); err = snd_pcm_new_stream(as->pcm, stream, 1);
if (err < 0) if (err < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment