mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 02:19:51 +00:00
Merge branch 'fix/hda' into topic/hda
The fix for power sequence needs to be merged back to topic branch.
This commit is contained in:
commit
1ade819181
24 changed files with 258 additions and 165 deletions
|
@ -193,6 +193,7 @@ static const struct platform_device_id ssp_id_table[] = {
|
|||
{ "pxa25x-nssp", PXA25x_NSSP },
|
||||
{ "pxa27x-ssp", PXA27x_SSP },
|
||||
{ "pxa168-ssp", PXA168_SSP },
|
||||
{ "pxa910-ssp", PXA910_SSP },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
|
|
@ -190,6 +190,19 @@ find_active_client(struct list_head *head)
|
|||
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)
|
||||
{
|
||||
struct vga_switcheroo_client *client;
|
||||
|
@ -291,8 +304,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
|
|||
vga_switchon(new_client);
|
||||
|
||||
vga_set_default_device(new_client->pdev);
|
||||
set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -308,6 +319,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
|
|||
|
||||
active->active = false;
|
||||
|
||||
set_audio_state(active->id, VGA_SWITCHEROO_OFF);
|
||||
|
||||
if (new_client->fb_info) {
|
||||
struct fb_event event;
|
||||
event.info = new_client->fb_info;
|
||||
|
@ -321,11 +334,11 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
|
|||
if (new_client->ops->reprobe)
|
||||
new_client->ops->reprobe(new_client->pdev);
|
||||
|
||||
set_audio_state(active->id, VGA_SWITCHEROO_OFF);
|
||||
|
||||
if (active->pwr_state == VGA_SWITCHEROO_ON)
|
||||
vga_switchoff(active);
|
||||
|
||||
set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
|
||||
|
||||
new_client->active = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -371,8 +384,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
|
|||
/* pwr off the device not in use */
|
||||
if (strncmp(usercmd, "OFF", 3) == 0) {
|
||||
list_for_each_entry(client, &vgasr_priv.clients, list) {
|
||||
if (client->active)
|
||||
if (client->active || client_is_audio(client))
|
||||
continue;
|
||||
set_audio_state(client->id, VGA_SWITCHEROO_OFF);
|
||||
if (client->pwr_state == VGA_SWITCHEROO_ON)
|
||||
vga_switchoff(client);
|
||||
}
|
||||
|
@ -381,10 +395,11 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
|
|||
/* pwr on the device not in use */
|
||||
if (strncmp(usercmd, "ON", 2) == 0) {
|
||||
list_for_each_entry(client, &vgasr_priv.clients, list) {
|
||||
if (client->active)
|
||||
if (client->active || client_is_audio(client))
|
||||
continue;
|
||||
if (client->pwr_state == VGA_SWITCHEROO_OFF)
|
||||
vga_switchon(client);
|
||||
set_audio_state(client->id, VGA_SWITCHEROO_ON);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -160,7 +160,9 @@ enum pxa_ssp_type {
|
|||
PXA25x_SSP, /* pxa 210, 250, 255, 26x */
|
||||
PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
|
||||
PXA27x_SSP,
|
||||
PXA3xx_SSP,
|
||||
PXA168_SSP,
|
||||
PXA910_SSP,
|
||||
CE4100_SSP,
|
||||
};
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ struct pxa2xx_spi_chip {
|
|||
void (*cs_control)(u32 command);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_PXA
|
||||
#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <mach/dma.h>
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
enum vga_switcheroo_state {
|
||||
VGA_SWITCHEROO_OFF,
|
||||
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 {
|
||||
|
@ -50,6 +53,8 @@ void vga_switcheroo_unregister_handler(void);
|
|||
|
||||
int vga_switcheroo_process_delayed_switch(void);
|
||||
|
||||
int vga_switcheroo_get_client_state(struct pci_dev *dev);
|
||||
|
||||
#else
|
||||
|
||||
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,
|
|||
int id, bool active) { return 0; }
|
||||
static inline void vga_switcheroo_unregister_handler(void) {}
|
||||
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
|
||||
|
|
|
@ -502,10 +502,8 @@ static int snd_compr_pause(struct snd_compr_stream *stream)
|
|||
if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
|
||||
return -EPERM;
|
||||
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
|
||||
if (!retval) {
|
||||
if (!retval)
|
||||
stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
|
||||
wake_up(&stream->runtime->sleep);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -544,6 +542,10 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
|
|||
if (!retval) {
|
||||
stream->runtime->state = SNDRV_PCM_STATE_SETUP;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -4423,20 +4423,19 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
|
|||
codec->power_jiffies += delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_power_up - Power-up the codec
|
||||
* @codec: HD-audio codec
|
||||
*
|
||||
* Increment the power-up counter and power up the hardware really when
|
||||
* not turned on yet.
|
||||
*/
|
||||
void snd_hda_power_up(struct hda_codec *codec)
|
||||
/* Transition to powered up, if wait_power_down then wait for a pending
|
||||
* transition to D3 to complete. A pending D3 transition is indicated
|
||||
* with power_transition == -1. */
|
||||
static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
|
||||
{
|
||||
struct hda_bus *bus = codec->bus;
|
||||
|
||||
spin_lock(&codec->power_lock);
|
||||
codec->power_count++;
|
||||
if (codec->power_on || codec->power_transition > 0) {
|
||||
/* Return if power_on or transitioning to power_on, unless currently
|
||||
* powering down. */
|
||||
if ((codec->power_on || codec->power_transition > 0) &&
|
||||
!(wait_power_down && codec->power_transition < 0)) {
|
||||
spin_unlock(&codec->power_lock);
|
||||
return;
|
||||
}
|
||||
|
@ -4460,8 +4459,37 @@ void snd_hda_power_up(struct hda_codec *codec)
|
|||
codec->power_transition = 0;
|
||||
spin_unlock(&codec->power_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_power_up - Power-up the codec
|
||||
* @codec: HD-audio codec
|
||||
*
|
||||
* Increment the power-up counter and power up the hardware really when
|
||||
* not turned on yet.
|
||||
*/
|
||||
void snd_hda_power_up(struct hda_codec *codec)
|
||||
{
|
||||
__snd_hda_power_up(codec, false);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_power_up);
|
||||
|
||||
/**
|
||||
* snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
|
||||
* D3 transition to complete. This differs from snd_hda_power_up() when
|
||||
* power_transition == -1. snd_hda_power_up sees this case as a nop,
|
||||
* snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
|
||||
* back up.
|
||||
* @codec: HD-audio codec
|
||||
*
|
||||
* Cancel any power down operation hapenning on the work queue, then power up.
|
||||
*/
|
||||
void snd_hda_power_up_d3wait(struct hda_codec *codec)
|
||||
{
|
||||
/* This will cancel and wait for pending power_work to complete. */
|
||||
__snd_hda_power_up(codec, true);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait);
|
||||
|
||||
#define power_save(codec) \
|
||||
((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
|
||||
|
||||
|
|
|
@ -1059,10 +1059,12 @@ const char *snd_hda_get_jack_location(u32 cfg);
|
|||
*/
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
void snd_hda_power_up(struct hda_codec *codec);
|
||||
void snd_hda_power_up_d3wait(struct hda_codec *codec);
|
||||
void snd_hda_power_down(struct hda_codec *codec);
|
||||
void snd_hda_update_power_acct(struct hda_codec *codec);
|
||||
#else
|
||||
static inline void snd_hda_power_up(struct hda_codec *codec) {}
|
||||
static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {}
|
||||
static inline void snd_hda_power_down(struct hda_codec *codec) {}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1767,7 +1767,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
|
|||
buff_step);
|
||||
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
|
||||
buff_step);
|
||||
snd_hda_power_up(apcm->codec);
|
||||
snd_hda_power_up_d3wait(apcm->codec);
|
||||
err = hinfo->ops.open(hinfo, apcm->codec, substream);
|
||||
if (err < 0) {
|
||||
azx_release_device(azx_dev);
|
||||
|
@ -2485,9 +2485,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_probe_continue(struct azx *chip);
|
||||
|
||||
#ifdef SUPPORT_VGA_SWITCHEROO
|
||||
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,
|
||||
enum vga_switcheroo_state state)
|
||||
{
|
||||
|
@ -2579,6 +2579,7 @@ static int __devinit register_vga_switcheroo(struct azx *chip)
|
|||
#else
|
||||
#define init_vga_switcheroo(chip) /* NOP */
|
||||
#define register_vga_switcheroo(chip) 0
|
||||
#define check_hdmi_disabled(pci) false
|
||||
#endif /* SUPPORT_VGA_SWITCHER */
|
||||
|
||||
/*
|
||||
|
@ -2639,6 +2640,7 @@ static int azx_dev_free(struct snd_device *device)
|
|||
return azx_free(device->device_data);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_VGA_SWITCHEROO
|
||||
/*
|
||||
* Check of disabled HDMI controller by vga-switcheroo
|
||||
*/
|
||||
|
@ -2671,12 +2673,13 @@ static bool __devinit check_hdmi_disabled(struct pci_dev *pci)
|
|||
struct pci_dev *p = get_bound_vga(pci);
|
||||
|
||||
if (p) {
|
||||
if (vga_default_device() && p != vga_default_device())
|
||||
if (vga_switcheroo_get_client_state(p) == VGA_SWITCHEROO_OFF)
|
||||
vga_inactive = true;
|
||||
pci_dev_put(p);
|
||||
}
|
||||
return vga_inactive;
|
||||
}
|
||||
#endif /* SUPPORT_VGA_SWITCHEROO */
|
||||
|
||||
/*
|
||||
* white/black-listing for position_fix
|
||||
|
@ -3360,6 +3363,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
|||
{ PCI_DEVICE(0x6549, 0x1200),
|
||||
.driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
|
||||
/* 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)
|
||||
/* the following entry conflicts with snd-ctxfi driver,
|
||||
* as ctxfi driver mutates from HD-audio to native mode with
|
||||
|
@ -3376,11 +3384,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
|||
.driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
|
||||
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
|
||||
#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 */
|
||||
{ PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
|
||||
/* VMware HDAudio */
|
||||
|
|
|
@ -4061,7 +4061,7 @@ static void cx_auto_init_digital(struct hda_codec *codec)
|
|||
static int cx_auto_init(struct hda_codec *codec)
|
||||
{
|
||||
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_input(codec);
|
||||
cx_auto_init_digital(codec);
|
||||
|
|
|
@ -1896,6 +1896,7 @@ static int alc_init(struct hda_codec *codec)
|
|||
alc_fix_pll(codec);
|
||||
alc_auto_init_amp(codec, spec->init_amp);
|
||||
|
||||
snd_hda_gen_apply_verbs(codec);
|
||||
alc_init_special_input_src(codec);
|
||||
alc_auto_init_std(codec);
|
||||
|
||||
|
@ -6439,6 +6440,7 @@ enum {
|
|||
ALC662_FIXUP_ASUS_MODE7,
|
||||
ALC662_FIXUP_ASUS_MODE8,
|
||||
ALC662_FIXUP_NO_JACK_DETECT,
|
||||
ALC662_FIXUP_ZOTAC_Z68,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc662_fixups[] = {
|
||||
|
@ -6588,6 +6590,13 @@ static const struct alc_fixup alc662_fixups[] = {
|
|||
.type = ALC_FIXUP_FUNC,
|
||||
.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[] = {
|
||||
|
@ -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(0x17aa, 0x38af, "Lenovo Ideapad Y550P", 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),
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -99,8 +99,9 @@ static void wm2000_reset(struct wm2000_priv *wm2000)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
val = wm2000_read(i2c, reg);
|
||||
|
@ -119,7 +120,7 @@ static int wm2000_poll_bit(struct i2c_client *i2c,
|
|||
static int wm2000_power_up(struct i2c_client *i2c, int analogue)
|
||||
{
|
||||
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
|
||||
int ret, timeout;
|
||||
int ret;
|
||||
|
||||
BUG_ON(wm2000->anc_mode != ANC_OFF);
|
||||
|
||||
|
@ -140,13 +141,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
|
|||
|
||||
/* Wait for ANC engine to become ready */
|
||||
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");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
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");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -173,16 +174,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
|
|||
dev_dbg(&i2c->dev, "Download complete\n");
|
||||
|
||||
if (analogue) {
|
||||
timeout = 248;
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4);
|
||||
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_ANA_SEQ_INCLUDE |
|
||||
WM2000_MODE_MOUSE_ENABLE |
|
||||
WM2000_MODE_THERMAL_ENABLE);
|
||||
} else {
|
||||
timeout = 10;
|
||||
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_MOUSE_ENABLE |
|
||||
WM2000_MODE_THERMAL_ENABLE);
|
||||
|
@ -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);
|
||||
|
||||
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
|
||||
WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
|
||||
dev_err(&i2c->dev, "Timed out waiting for device after %dms\n",
|
||||
timeout * 10);
|
||||
WM2000_STATUS_MOUSE_ACTIVE)) {
|
||||
dev_err(&i2c->dev, "Timed out waiting for device\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
|
||||
int timeout;
|
||||
|
||||
if (analogue) {
|
||||
timeout = 248;
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4);
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_ANA_SEQ_INCLUDE |
|
||||
WM2000_MODE_POWER_DOWN);
|
||||
} else {
|
||||
timeout = 10;
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_POWER_DOWN);
|
||||
}
|
||||
|
||||
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");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
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");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -268,13 +262,13 @@ static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)
|
|||
}
|
||||
|
||||
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");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
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");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
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");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
|
||||
int timeout;
|
||||
|
||||
BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
|
||||
|
||||
if (analogue) {
|
||||
timeout = 248;
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4);
|
||||
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_ANA_SEQ_INCLUDE |
|
||||
WM2000_MODE_THERMAL_ENABLE |
|
||||
WM2000_MODE_STANDBY_ENTRY);
|
||||
} else {
|
||||
timeout = 10;
|
||||
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_THERMAL_ENABLE |
|
||||
WM2000_MODE_STANDBY_ENTRY);
|
||||
}
|
||||
|
||||
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
|
||||
WM2000_STATUS_ANC_DISABLED, timeout)) {
|
||||
WM2000_STATUS_ANC_DISABLED)) {
|
||||
dev_err(&i2c->dev,
|
||||
"Timed out waiting for ANC disable after 1ms\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE,
|
||||
1)) {
|
||||
if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE)) {
|
||||
dev_err(&i2c->dev,
|
||||
"Timed out waiting for standby after %dms\n",
|
||||
timeout * 10);
|
||||
"Timed out waiting for standby\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
|
||||
int timeout;
|
||||
|
||||
BUG_ON(wm2000->anc_mode != ANC_STANDBY);
|
||||
|
||||
wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
|
||||
|
||||
if (analogue) {
|
||||
timeout = 248;
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
|
||||
wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4);
|
||||
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_ANA_SEQ_INCLUDE |
|
||||
WM2000_MODE_THERMAL_ENABLE |
|
||||
WM2000_MODE_MOUSE_ENABLE);
|
||||
} else {
|
||||
timeout = 10;
|
||||
|
||||
wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
|
||||
WM2000_MODE_THERMAL_ENABLE |
|
||||
WM2000_MODE_MOUSE_ENABLE);
|
||||
|
@ -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);
|
||||
|
||||
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
|
||||
WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
|
||||
dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n",
|
||||
timeout * 10);
|
||||
WM2000_STATUS_MOUSE_ACTIVE)) {
|
||||
dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
|
|
@ -1863,6 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
|
|||
return ret;
|
||||
}
|
||||
|
||||
regcache_cache_only(wm8904->regmap, false);
|
||||
regcache_sync(wm8904->regmap);
|
||||
|
||||
/* Enable bias */
|
||||
|
@ -1899,14 +1900,8 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
|
|||
snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
|
||||
WM8904_BIAS_ENA, 0);
|
||||
|
||||
#ifdef CONFIG_REGULATOR
|
||||
/* Post 2.6.34 we will be able to get a callback when
|
||||
* the regulators are disabled which we can use but
|
||||
* for now just assume that the power will be cut if
|
||||
* the regulator API is in use.
|
||||
*/
|
||||
codec->cache_sync = 1;
|
||||
#endif
|
||||
regcache_cache_only(wm8904->regmap, true);
|
||||
regcache_mark_dirty(wm8904->regmap);
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
|
||||
wm8904->supplies);
|
||||
|
@ -2084,10 +2079,8 @@ static int wm8904_probe(struct snd_soc_codec *codec)
|
|||
{
|
||||
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8904_pdata *pdata = wm8904->pdata;
|
||||
u16 *reg_cache = codec->reg_cache;
|
||||
int ret, i;
|
||||
|
||||
codec->cache_sync = 1;
|
||||
codec->control_data = wm8904->regmap;
|
||||
|
||||
switch (wm8904->devtype) {
|
||||
|
@ -2150,6 +2143,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
|
|||
goto err_enable;
|
||||
}
|
||||
|
||||
regcache_cache_only(wm8904->regmap, true);
|
||||
/* Change some default settings - latch VU and enable ZC */
|
||||
snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
|
||||
WM8904_ADC_VU, WM8904_ADC_VU);
|
||||
|
@ -2180,14 +2174,18 @@ static int wm8904_probe(struct snd_soc_codec *codec)
|
|||
if (!pdata->gpio_cfg[i])
|
||||
continue;
|
||||
|
||||
reg_cache[WM8904_GPIO_CONTROL_1 + i]
|
||||
= pdata->gpio_cfg[i] & 0xffff;
|
||||
regmap_update_bits(wm8904->regmap,
|
||||
WM8904_GPIO_CONTROL_1 + i,
|
||||
0xffff,
|
||||
pdata->gpio_cfg[i]);
|
||||
}
|
||||
|
||||
/* Zero is the default value for these anyway */
|
||||
for (i = 0; i < WM8904_MIC_REGS; i++)
|
||||
reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
|
||||
= pdata->mic_cfg[i];
|
||||
regmap_update_bits(wm8904->regmap,
|
||||
WM8904_MIC_BIAS_CONTROL_0 + i,
|
||||
0xffff,
|
||||
pdata->mic_cfg[i]);
|
||||
}
|
||||
|
||||
/* Set Class W by default - this will be managed by the Class
|
||||
|
|
|
@ -46,6 +46,39 @@
|
|||
#define WM8994_NUM_DRC 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[] = {
|
||||
WM8994_AIF1_DRC1_1,
|
||||
WM8994_AIF1_DRC2_1,
|
||||
|
@ -989,6 +1022,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_soc_codec *codec = w->codec;
|
||||
struct wm8994 *control = codec->control_data;
|
||||
int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
|
||||
int i;
|
||||
int dac;
|
||||
int adc;
|
||||
int val;
|
||||
|
@ -1047,6 +1081,13 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
|
|||
WM8994_AIF1DAC2L_ENA);
|
||||
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_POST_PMD:
|
||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
|
||||
|
@ -1072,6 +1113,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
int i;
|
||||
int dac;
|
||||
int adc;
|
||||
int val;
|
||||
|
@ -1122,6 +1164,13 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
|
|||
WM8994_AIF2DACR_ENA);
|
||||
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_POST_PMD:
|
||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
|
||||
|
@ -1190,17 +1239,19 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
|
|||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
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,
|
||||
WM8994_AIF1CLK_ENA_MASK,
|
||||
WM8994_AIF1CLK_ENA);
|
||||
aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
|
||||
wm8994->aif1clk_enable = 0;
|
||||
}
|
||||
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,
|
||||
WM8994_AIF2CLK_ENA_MASK,
|
||||
WM8994_AIF2CLK_ENA);
|
||||
aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
|
||||
wm8994->aif2clk_enable = 0;
|
||||
}
|
||||
break;
|
||||
|
@ -1221,15 +1272,17 @@ static int late_disable_ev(struct snd_soc_dapm_widget *w,
|
|||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
if (wm8994->aif1clk_disable) {
|
||||
aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
|
||||
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
|
||||
WM8994_AIF1CLK_ENA_MASK, 0);
|
||||
aif1clk_ev(w, kcontrol, event);
|
||||
aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
|
||||
wm8994->aif1clk_disable = 0;
|
||||
}
|
||||
if (wm8994->aif2clk_disable) {
|
||||
aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
|
||||
snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
|
||||
WM8994_AIF2CLK_ENA_MASK, 0);
|
||||
aif2clk_ev(w, kcontrol, event);
|
||||
aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
|
||||
wm8994->aif2clk_disable = 0;
|
||||
}
|
||||
break;
|
||||
|
@ -1527,9 +1580,11 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
|
|||
|
||||
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_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_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_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
|
||||
left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
|
||||
|
@ -3879,39 +3934,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
|
|||
|
||||
pm_runtime_put(codec->dev);
|
||||
|
||||
/* Latch volume updates (right only; we always do left then right). */
|
||||
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME,
|
||||
WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
|
||||
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
|
||||
WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
|
||||
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);
|
||||
/* Latch volume update bits */
|
||||
for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
|
||||
snd_soc_update_bits(codec, wm8994_vu_bits[i].reg,
|
||||
wm8994_vu_bits[i].mask,
|
||||
wm8994_vu_bits[i].mask);
|
||||
|
||||
/* Set the low bit of the 3D stereo depth so TLV matches */
|
||||
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
|
||||
|
|
|
@ -2837,8 +2837,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
|
|||
}
|
||||
}
|
||||
|
||||
regcache_cache_only(codec->control_data, true);
|
||||
|
||||
/* Apply platform data settings */
|
||||
snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
|
||||
WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
|
||||
|
@ -3051,7 +3049,6 @@ static int wm8996_remove(struct snd_soc_codec *codec)
|
|||
for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
|
||||
regulator_unregister_notifier(wm8996->supplies[i].consumer,
|
||||
&wm8996->disable_nb[i]);
|
||||
regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3206,14 +3203,15 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
|
|||
dev_info(&i2c->dev, "revision %c\n",
|
||||
(reg & WM8996_CHIP_REV_MASK) + 'A');
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
|
||||
|
||||
ret = wm8996_reset(wm8996);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "Failed to issue reset\n");
|
||||
goto err_regmap;
|
||||
}
|
||||
|
||||
regcache_cache_only(wm8996->regmap, true);
|
||||
regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
|
||||
|
||||
wm8996_init_gpio(wm8996);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include "imx-audmux.h"
|
||||
|
||||
|
@ -249,6 +250,7 @@ EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
|
|||
static int __devinit imx_audmux_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct pinctrl *pinctrl;
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(imx_audmux_dt_ids, &pdev->dev);
|
||||
|
||||
|
@ -257,6 +259,12 @@ static int __devinit imx_audmux_probe(struct platform_device *pdev)
|
|||
if (!audmux_base)
|
||||
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");
|
||||
if (IS_ERR(audmux_clk)) {
|
||||
dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/audio.h>
|
||||
|
||||
#include "../../arm/pxa2xx-pcm.h"
|
||||
#include "pxa-ssp.h"
|
||||
|
@ -194,7 +193,7 @@ static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
|
|||
{
|
||||
u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
|
||||
|
||||
if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
|
||||
if (ssp->type == PXA25x_SSP) {
|
||||
sscr0 &= ~0x0000ff00;
|
||||
sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
|
||||
} else {
|
||||
|
@ -212,7 +211,7 @@ static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
|
|||
u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
|
||||
u32 div;
|
||||
|
||||
if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
|
||||
if (ssp->type == PXA25x_SSP)
|
||||
div = ((sscr0 >> 8) & 0xff) * 2 + 2;
|
||||
else
|
||||
div = ((sscr0 >> 8) & 0xfff) + 1;
|
||||
|
@ -242,7 +241,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
|
|||
break;
|
||||
case PXA_SSP_CLK_PLL:
|
||||
/* Internal PLL is fixed */
|
||||
if (cpu_is_pxa25x())
|
||||
if (ssp->type == PXA25x_SSP)
|
||||
priv->sysclk = 1843200;
|
||||
else
|
||||
priv->sysclk = 13000000;
|
||||
|
@ -266,11 +265,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
|
|||
|
||||
/* The SSP clock must be disabled when changing SSP clock mode
|
||||
* on PXA2xx. On PXA3xx it must be enabled when doing so. */
|
||||
if (!cpu_is_pxa3xx())
|
||||
if (ssp->type != PXA3xx_SSP)
|
||||
clk_disable(ssp->clk);
|
||||
val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
|
||||
pxa_ssp_write_reg(ssp, SSCR0, val);
|
||||
if (!cpu_is_pxa3xx())
|
||||
if (ssp->type != PXA3xx_SSP)
|
||||
clk_enable(ssp->clk);
|
||||
|
||||
return 0;
|
||||
|
@ -294,24 +293,20 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
|
|||
case PXA_SSP_AUDIO_DIV_SCDB:
|
||||
val = pxa_ssp_read_reg(ssp, SSACD);
|
||||
val &= ~SSACD_SCDB;
|
||||
#if defined(CONFIG_PXA3xx)
|
||||
if (cpu_is_pxa3xx())
|
||||
if (ssp->type == PXA3xx_SSP)
|
||||
val &= ~SSACD_SCDX8;
|
||||
#endif
|
||||
switch (div) {
|
||||
case PXA_SSP_CLK_SCDB_1:
|
||||
val |= SSACD_SCDB;
|
||||
break;
|
||||
case PXA_SSP_CLK_SCDB_4:
|
||||
break;
|
||||
#if defined(CONFIG_PXA3xx)
|
||||
case PXA_SSP_CLK_SCDB_8:
|
||||
if (cpu_is_pxa3xx())
|
||||
if (ssp->type == PXA3xx_SSP)
|
||||
val |= SSACD_SCDX8;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -337,10 +332,8 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
|
|||
struct ssp_device *ssp = priv->ssp;
|
||||
u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
|
||||
|
||||
#if defined(CONFIG_PXA3xx)
|
||||
if (cpu_is_pxa3xx())
|
||||
if (ssp->type == PXA3xx_SSP)
|
||||
pxa_ssp_write_reg(ssp, SSACDD, 0);
|
||||
#endif
|
||||
|
||||
switch (freq_out) {
|
||||
case 5622000:
|
||||
|
@ -365,11 +358,10 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
|
|||
break;
|
||||
|
||||
default:
|
||||
#ifdef CONFIG_PXA3xx
|
||||
/* PXA3xx has a clock ditherer which can be used to generate
|
||||
* a wider range of frequencies - calculate a value for it.
|
||||
*/
|
||||
if (cpu_is_pxa3xx()) {
|
||||
if (ssp->type == PXA3xx_SSP) {
|
||||
u32 val;
|
||||
u64 tmp = 19968;
|
||||
tmp *= 1000000;
|
||||
|
@ -386,7 +378,6 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
|
|||
val, freq_out);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -590,10 +581,8 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
|
|||
/* bit size */
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
#ifdef CONFIG_PXA3xx
|
||||
if (cpu_is_pxa3xx())
|
||||
if (ssp->type == PXA3xx_SSP)
|
||||
sscr0 |= SSCR0_FPCKE;
|
||||
#endif
|
||||
sscr0 |= SSCR0_DataSize(16);
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
|
@ -618,9 +607,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
|
|||
* trying and failing a lot; some of the registers
|
||||
* needed for that mode are only available on PXA3xx.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PXA3xx
|
||||
if (!cpu_is_pxa3xx())
|
||||
if (ssp->type != PXA3xx_SSP)
|
||||
return -EINVAL;
|
||||
|
||||
sspsp |= SSPSP_SFRMWDTH(width * 2);
|
||||
|
@ -628,9 +615,6 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
|
|||
sspsp |= SSPSP_EDMYSTOP(3);
|
||||
sspsp |= SSPSP_DMYSTOP(3);
|
||||
sspsp |= SSPSP_DMYSTRT(1);
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
} else {
|
||||
/* The frame width is the width the LRCLK is
|
||||
* asserted for; the delay is expressed in
|
||||
|
|
|
@ -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 ? */
|
||||
if (list) {
|
||||
int err;
|
||||
err = dapm_list_add_widget(list, path->sink);
|
||||
err = dapm_list_add_widget(list, path->source);
|
||||
if (err < 0) {
|
||||
dev_err(widget->dapm->dev, "could not add widget %s\n",
|
||||
widget->name);
|
||||
|
@ -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)
|
||||
paths = is_connected_output_ep(dai->playback_widget, list);
|
||||
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);
|
||||
dapm_clear_walk(&card->dapm);
|
||||
|
|
|
@ -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++) {
|
||||
be = &card->rtd[i];
|
||||
|
||||
if (!be->dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (be->cpu_dai->playback_widget == widget ||
|
||||
be->codec_dai->playback_widget == widget)
|
||||
return be;
|
||||
|
@ -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++) {
|
||||
be = &card->rtd[i];
|
||||
|
||||
if (!be->dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
if (be->cpu_dai->capture_widget == widget ||
|
||||
be->codec_dai->capture_widget == widget)
|
||||
return be;
|
||||
|
|
|
@ -629,3 +629,4 @@ MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
|
|||
MODULE_DESCRIPTION("Tegra30 AHUB driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
MODULE_DEVICE_TABLE(of, tegra30_ahub_of_match);
|
||||
|
|
|
@ -346,6 +346,17 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_wm8903_remove(struct snd_soc_card *card)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = &(card->rtd[0]);
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
|
||||
wm8903_mic_detect(codec, NULL, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_link tegra_wm8903_dai = {
|
||||
.name = "WM8903",
|
||||
.stream_name = "WM8903 PCM",
|
||||
|
@ -363,6 +374,8 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = {
|
|||
.dai_link = &tegra_wm8903_dai,
|
||||
.num_links = 1,
|
||||
|
||||
.remove = tegra_wm8903_remove,
|
||||
|
||||
.controls = tegra_wm8903_controls,
|
||||
.num_controls = ARRAY_SIZE(tegra_wm8903_controls),
|
||||
.dapm_widgets = tegra_wm8903_dapm_widgets,
|
||||
|
|
|
@ -119,6 +119,7 @@ struct snd_usb_substream {
|
|||
unsigned long unlink_mask; /* bitmask of unlinked urbs */
|
||||
|
||||
/* data and sync endpoints for this stream */
|
||||
unsigned int ep_num; /* the endpoint number */
|
||||
struct snd_usb_endpoint *data_endpoint;
|
||||
struct snd_usb_endpoint *sync_endpoint;
|
||||
unsigned long flags;
|
||||
|
|
|
@ -354,17 +354,21 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
|
|||
(get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
|
||||
get_endpoint(alts, 1)->bSynchAddress != 0 &&
|
||||
!implicit_fb)) {
|
||||
snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
|
||||
dev->devnum, fmt->iface, fmt->altsetting);
|
||||
snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n",
|
||||
dev->devnum, fmt->iface, fmt->altsetting,
|
||||
get_endpoint(alts, 1)->bmAttributes,
|
||||
get_endpoint(alts, 1)->bLength,
|
||||
get_endpoint(alts, 1)->bSynchAddress);
|
||||
return -EINVAL;
|
||||
}
|
||||
ep = get_endpoint(alts, 1)->bEndpointAddress;
|
||||
if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
|
||||
if (!implicit_fb &&
|
||||
get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
|
||||
(( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
|
||||
(!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)) ||
|
||||
( is_playback && !implicit_fb))) {
|
||||
snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
|
||||
dev->devnum, fmt->iface, fmt->altsetting);
|
||||
(!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
|
||||
snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n",
|
||||
dev->devnum, fmt->iface, fmt->altsetting,
|
||||
is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1147,7 +1151,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd)
|
||||
{
|
||||
int err;
|
||||
struct snd_usb_substream *subs = substream->runtime->private_data;
|
||||
|
|
|
@ -97,6 +97,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
|
|||
subs->formats |= fp->formats;
|
||||
subs->num_formats++;
|
||||
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,
|
|||
if (as->fmt_type != fp->fmt_type)
|
||||
continue;
|
||||
subs = &as->substream[stream];
|
||||
if (!subs->data_endpoint)
|
||||
continue;
|
||||
if (subs->data_endpoint->ep_num == fp->endpoint) {
|
||||
if (subs->ep_num == fp->endpoint) {
|
||||
list_add_tail(&fp->list, &subs->fmt_list);
|
||||
subs->num_formats++;
|
||||
subs->formats |= fp->formats;
|
||||
|
@ -134,7 +133,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
|
|||
if (as->fmt_type != fp->fmt_type)
|
||||
continue;
|
||||
subs = &as->substream[stream];
|
||||
if (subs->data_endpoint)
|
||||
if (subs->ep_num)
|
||||
continue;
|
||||
err = snd_pcm_new_stream(as->pcm, stream, 1);
|
||||
if (err < 0)
|
||||
|
|
Loading…
Reference in a new issue