Newer
Older
* hda_intel.c - Implementation of primary alsa driver code base
* for Intel HD Audio.
*
* Copyright(c) 2004 Intel Corporation. All rights reserved.
*
* Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
* PeiSen Hou <pshou@realtek.com.tw>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* CONTACTS:
*
* Matt Jared matt.jared@intel.com
* Andy Kopp andy.kopp@intel.com
* Dan Kogan dan.d.kogan@intel.com
*
* CHANGES:
*
* 2004.12.01 Major rewrite by tiwai, merged the work of pshou
*
*/
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/clocksource.h>
#include <linux/time.h>
#include <linux/completion.h>
#ifdef CONFIG_X86
/* for snoop control */
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#endif
#include <linux/vgaarb.h>
#include "hda_i915.h"
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static char *model[SNDRV_CARDS];
static int position_fix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int jackpoll_ms[SNDRV_CARDS];
static bool single_cmd;
#ifdef CONFIG_SND_HDA_PATCH_LOADER
static char *patch[SNDRV_CARDS];
#endif
#ifdef CONFIG_SND_HDA_INPUT_BEEP
static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
CONFIG_SND_HDA_INPUT_BEEP_MODE};
#endif
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
module_param_array(model, charp, NULL, 0444);
module_param_array(position_fix, int, NULL, 0444);
MODULE_PARM_DESC(position_fix, "DMA pointer read method."
"(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
module_param_array(bdl_pos_adj, int, NULL, 0644);
MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
module_param_array(probe_mask, int, NULL, 0444);
MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
module_param_array(probe_only, int, NULL, 0444);
MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
module_param_array(jackpoll_ms, int, NULL, 0444);
MODULE_PARM_DESC(jackpoll_ms, "Ms between polling for jack events (default = 0, using unsol events only)");
module_param(single_cmd, bool, 0444);
MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
"(for debugging only).");
module_param(enable_msi, bint, 0444);
MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
#ifdef CONFIG_SND_HDA_PATCH_LOADER
module_param_array(patch, charp, NULL, 0444);
MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
#endif
#ifdef CONFIG_SND_HDA_INPUT_BEEP
module_param_array(beep_mode, bool, NULL, 0444);
MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
static int param_set_xint(const char *val, const struct kernel_param *kp);
static struct kernel_param_ops param_ops_xint = {
.set = param_set_xint,
.get = param_get_int,
};
#define param_check_xint param_check_int
static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
module_param(power_save, xint, 0644);
MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
"(in second, 0 = disable).");
/* reset the HD-audio controller in power save mode.
* this may give more power-saving, but will take longer time to
* wake up.
*/
static bool power_save_controller = 1;
module_param(power_save_controller, bool, 0644);
MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
static int align_buffer_size = -1;
module_param(align_buffer_size, bint, 0644);
MODULE_PARM_DESC(align_buffer_size,
"Force buffer and period sizes to be multiple of 128 bytes.");
#ifdef CONFIG_X86
static bool hda_snoop = true;
module_param_named(snoop, hda_snoop, bool, 0444);
MODULE_PARM_DESC(snoop, "Enable/disable snooping");
#else
#define hda_snoop true
#endif
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
"{Intel, ICH6M},"
"{Intel, ESB2},"
"{Intel, ICH10},"
"{Intel, PCH},"
"{Intel, CPT},"
"{Intel, PPT},"
"{Intel, LPT_LP},"
"{Intel, WPT_LP},"
"{Intel, PBG},"
"{ATI, SB450},"
"{ATI, RS600},"
"{ATI, RS780},"
"{ATI, R600},"
"{ATI, RV630},"
"{ATI, RV610},"
"{ATI, RV670},"
"{ATI, RV635},"
"{ATI, RV620},"
"{ATI, RV770},"
"{VIA, VT8251},"
"{SiS, SIS966},"
"{ULI, M5461}}");
#if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
#define SUPPORT_VGA_SWITCHEROO
#endif
#endif
/* DSP lock helpers */
#ifdef CONFIG_SND_HDA_DSP_LOADER
#define dsp_lock_init(dev) mutex_init(&(dev)->dsp_mutex)
#define dsp_lock(dev) mutex_lock(&(dev)->dsp_mutex)
#define dsp_unlock(dev) mutex_unlock(&(dev)->dsp_mutex)
#define dsp_is_locked(dev) ((dev)->locked)
#else
#define dsp_lock_init(dev) do {} while (0)
#define dsp_lock(dev) do {} while (0)
#define dsp_unlock(dev) do {} while (0)
#define dsp_is_locked(dev) 0
#endif
#define CREATE_TRACE_POINTS
#include "hda_intel_trace.h"
/* driver types */
enum {
AZX_DRIVER_ICH,
AZX_DRIVER_ATIHDMI,
AZX_DRIVER_VIA,
AZX_DRIVER_SIS,
AZX_DRIVER_ULI,
AZX_DRIVER_GENERIC,
AZX_NUM_DRIVERS, /* keep this as last entry */
/* quirks for Intel PCH */
#define AZX_DCAPS_INTEL_PCH_NOPM \
(AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \
AZX_DCAPS_COUNT_LPIB_DELAY)
#define AZX_DCAPS_INTEL_PCH \
(AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME)
#define AZX_DCAPS_INTEL_HASWELL \
(AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_ALIGN_BUFSIZE | \
AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME | \
AZX_DCAPS_I915_POWERWELL)
/* quirks for ATI SB / AMD Hudson */
#define AZX_DCAPS_PRESET_ATI_SB \
(AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \
AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
/* quirks for ATI/AMD HDMI */
#define AZX_DCAPS_PRESET_ATI_HDMI \
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
/* quirks for Nvidia */
#define AZX_DCAPS_PRESET_NVIDIA \
(AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT)
#define AZX_DCAPS_PRESET_CTHDA \
(AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY)
/*
* VGA-switcher support
*/
#ifdef SUPPORT_VGA_SWITCHEROO
#define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo)
#else
#define use_vga_switcheroo(chip) 0
#endif
static char *driver_short_names[] = {
[AZX_DRIVER_PCH] = "HDA Intel PCH",
[AZX_DRIVER_SCH] = "HDA Intel MID",
[AZX_DRIVER_HDMI] = "HDA Intel HDMI",
[AZX_DRIVER_ATI] = "HDA ATI SB",
[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
[AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
[AZX_DRIVER_SIS] = "HDA SIS966",
[AZX_DRIVER_ULI] = "HDA ULI M5461",
[AZX_DRIVER_NVIDIA] = "HDA NVidia",
[AZX_DRIVER_TERA] = "HDA Teradici",
[AZX_DRIVER_CTX] = "HDA Creative",
[AZX_DRIVER_CTHDA] = "HDA Creative",
[AZX_DRIVER_GENERIC] = "HD-Audio Generic",
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
* macros for easy use
*/
#define azx_writel(chip,reg,value) \
writel(value, (chip)->remap_addr + ICH6_REG_##reg)
#define azx_readl(chip,reg) \
readl((chip)->remap_addr + ICH6_REG_##reg)
#define azx_writew(chip,reg,value) \
writew(value, (chip)->remap_addr + ICH6_REG_##reg)
#define azx_readw(chip,reg) \
readw((chip)->remap_addr + ICH6_REG_##reg)
#define azx_writeb(chip,reg,value) \
writeb(value, (chip)->remap_addr + ICH6_REG_##reg)
#define azx_readb(chip,reg) \
readb((chip)->remap_addr + ICH6_REG_##reg)
#define azx_sd_writel(dev,reg,value) \
writel(value, (dev)->sd_addr + ICH6_REG_##reg)
#define azx_sd_readl(dev,reg) \
readl((dev)->sd_addr + ICH6_REG_##reg)
#define azx_sd_writew(dev,reg,value) \
writew(value, (dev)->sd_addr + ICH6_REG_##reg)
#define azx_sd_readw(dev,reg) \
readw((dev)->sd_addr + ICH6_REG_##reg)
#define azx_sd_writeb(dev,reg,value) \
writeb(value, (dev)->sd_addr + ICH6_REG_##reg)
#define azx_sd_readb(dev,reg) \
readb((dev)->sd_addr + ICH6_REG_##reg)
/* for pcm support */
#define get_azx_dev(substream) (substream->runtime->private_data)
static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
if (!dmab || !dmab->area || !dmab->bytes)
return;
#ifdef CONFIG_SND_DMA_SGBUF
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
struct snd_sg_buf *sgbuf = dmab->private_data;
set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
set_pages_array_wb(sgbuf->page_table, sgbuf->pages);
return;
#endif
pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
if (on)
set_memory_wc((unsigned long)dmab->area, pages);
else
set_memory_wb((unsigned long)dmab->area, pages);
}
static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
bool on)
{
}
static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
struct snd_pcm_substream *substream, bool on)
__mark_pages_wc(chip, snd_pcm_get_dma_buf(substream), on);
azx_dev->wc_marked = on;
}
}
#else
/* NOP for other archs */
static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
bool on)
{
}
static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
struct snd_pcm_substream *substream, bool on)
static int azx_acquire_irq(struct azx *chip, int do_disconnect);
static int azx_send_cmd(struct hda_bus *bus, unsigned int val);
/*
* Interface for HD codec
*/
/*
* CORB / RIRB interface
*/
static int azx_alloc_cmd_io(struct azx *chip)
{
int err;
/* single page (at least 4096 bytes) must suffice for both ringbuffes */
err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n");
static void azx_init_cmd_io(struct azx *chip)
spin_lock_irq(&chip->reg_lock);
/* CORB set up */
chip->corb.addr = chip->rb.addr;
chip->corb.buf = (u32 *)chip->rb.area;
azx_writel(chip, CORBLBASE, (u32)chip->corb.addr);
azx_writel(chip, CORBUBASE, upper_32_bits(chip->corb.addr));
/* set the corb size to 256 entries (ULI requires explicitly) */
azx_writeb(chip, CORBSIZE, 0x02);
/* set the corb write pointer to 0 */
azx_writew(chip, CORBWP, 0);
azx_writew(chip, CORBRP, ICH6_CORBRP_RST);
for (timeout = 1000; timeout > 0; timeout--) {
if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST)
break;
udelay(1);
}
if (timeout <= 0)
dev_err(chip->card->dev, "CORB reset timeout#1, CORBRP = %d\n",
azx_readw(chip, CORBRP));
azx_writew(chip, CORBRP, 0);
for (timeout = 1000; timeout > 0; timeout--) {
if (azx_readw(chip, CORBRP) == 0)
break;
udelay(1);
}
if (timeout <= 0)
dev_err(chip->card->dev, "CORB reset timeout#2, CORBRP = %d\n",
azx_readw(chip, CORBRP));
azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);
/* RIRB set up */
chip->rirb.addr = chip->rb.addr + 2048;
chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
chip->rirb.wp = chip->rirb.rp = 0;
memset(chip->rirb.cmds, 0, sizeof(chip->rirb.cmds));
azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
/* set the rirb size to 256 entries (ULI requires explicitly) */
azx_writeb(chip, RIRBSIZE, 0x02);
azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
/* set N=1, get RIRB response interrupt for new entry */
if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
azx_writew(chip, RINTCNT, 0xc0);
else
azx_writew(chip, RINTCNT, 1);
/* enable rirb dma and response irq */
azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
spin_unlock_irq(&chip->reg_lock);
static void azx_free_cmd_io(struct azx *chip)
spin_lock_irq(&chip->reg_lock);
/* disable ringbuffer DMAs */
azx_writeb(chip, RIRBCTL, 0);
azx_writeb(chip, CORBCTL, 0);
spin_unlock_irq(&chip->reg_lock);
static unsigned int azx_command_addr(u32 cmd)
{
unsigned int addr = cmd >> 28;
if (addr >= AZX_MAX_CODECS) {
snd_BUG();
addr = 0;
}
return addr;
}
static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
struct azx *chip = bus->private_data;
unsigned int addr = azx_command_addr(val);
spin_lock_irq(&chip->reg_lock);
wp = azx_readw(chip, CORBWP);
if (wp == 0xffff) {
/* something wrong, controller likely turned to D3 */
spin_unlock_irq(&chip->reg_lock);
rp = azx_readw(chip, CORBRP);
if (wp == rp) {
/* oops, it's full */
spin_unlock_irq(&chip->reg_lock);
return -EAGAIN;
}
chip->rirb.cmds[addr]++;
azx_writew(chip, CORBWP, wp);
spin_unlock_irq(&chip->reg_lock);
return 0;
}
#define ICH6_RIRB_EX_UNSOL_EV (1<<4)
/* retrieve RIRB entry - called from interrupt handler */
static void azx_update_rirb(struct azx *chip)
unsigned int addr;
wp = azx_readw(chip, RIRBWP);
if (wp == 0xffff) {
/* something wrong, controller likely turned to D3 */
return;
}
if (wp == chip->rirb.wp)
return;
chip->rirb.wp = wp;
while (chip->rirb.rp != wp) {
chip->rirb.rp++;
chip->rirb.rp %= ICH6_MAX_RIRB_ENTRIES;
rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
res = le32_to_cpu(chip->rirb.buf[rp]);
addr = res_ex & 0xf;
if ((addr >= AZX_MAX_CODECS) || !(chip->codec_mask & (1 << addr))) {
dev_err(chip->card->dev, "spurious response %#x:%#x, rp = %d, wp = %d",
res, res_ex,
chip->rirb.rp, wp);
snd_BUG();
}
else if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
else if (chip->rirb.cmds[addr]) {
chip->rirb.res[addr] = res;
chip->rirb.cmds[addr]--;
} else if (printk_ratelimit()) {
dev_err(chip->card->dev, "spurious response %#x:%#x, last cmd=%#08x\n",
res, res_ex,
chip->last_cmd[addr]);
static unsigned int azx_rirb_get_response(struct hda_bus *bus,
unsigned int addr)
struct azx *chip = bus->private_data;
unsigned long timeout;
unsigned long loopcounter;
int do_poll = 0;
again:
timeout = jiffies + msecs_to_jiffies(1000);
for (loopcounter = 0;; loopcounter++) {
if (chip->polling_mode || do_poll) {
spin_lock_irq(&chip->reg_lock);
azx_update_rirb(chip);
spin_unlock_irq(&chip->reg_lock);
}
if (!chip->rirb.cmds[addr]) {
if (!do_poll)
chip->poll_count = 0;
return chip->rirb.res[addr]; /* the last value */
if (time_after(jiffies, timeout))
break;
if (bus->needs_damn_long_delay || loopcounter > 3000)
msleep(2); /* temporary workaround */
else {
udelay(10);
cond_resched();
}
if (!bus->no_response_fallback)
return -1;
if (!chip->polling_mode && chip->poll_count < 2) {
dev_dbg(chip->card->dev,
"azx_get_response timeout, polling the codec once: last cmd=0x%08x\n",
chip->last_cmd[addr]);
do_poll = 1;
chip->poll_count++;
goto again;
}
if (!chip->polling_mode) {
dev_warn(chip->card->dev,
"azx_get_response timeout, switching to polling mode: last cmd=0x%08x\n",
chip->last_cmd[addr]);
chip->polling_mode = 1;
goto again;
}
dev_warn(chip->card->dev,
"No response from codec, disabling MSI: last cmd=0x%08x\n",
chip->last_cmd[addr]);
free_irq(chip->irq, chip);
chip->irq = -1;
pci_disable_msi(chip->pci);
chip->msi = 0;
if (azx_acquire_irq(chip, 1) < 0) {
bus->rirb_error = 1;
if (chip->probing) {
/* If this critical timeout happens during the codec probing
* phase, this is likely an access to a non-existing codec
* slot. Better to return an error and reset the system.
*/
return -1;
}
/* a fatal communication error; need either to reset or to fallback
* to the single_cmd mode
*/
if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) {
bus->response_reset = 1;
return -1; /* give a chance to retry */
}
dev_err(chip->card->dev,
"azx_get_response timeout, switching to single_cmd mode: last cmd=0x%08x\n",
chip->last_cmd[addr]);
chip->single_cmd = 1;
bus->response_reset = 0;
/* release CORB/RIRB */
azx_free_cmd_io(chip);
/* disable unsolicited responses */
azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL);
return -1;
}
/*
* Use the single immediate command instead of CORB/RIRB for simplicity
*
* Note: according to Intel, this is not preferred use. The command was
* intended for the BIOS only, and may get confused with unsolicited
* responses. So, we shouldn't use it for normal operation from the
* driver.
* I left the codes, however, for debugging/testing purposes.
*/
/* receive a response */
static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
{
int timeout = 50;
while (timeout--) {
/* check IRV busy bit */
if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
/* reuse rirb.res as the response return value */
chip->rirb.res[addr] = azx_readl(chip, IR);
return 0;
}
udelay(1);
}
if (printk_ratelimit())
dev_dbg(chip->card->dev, "get_response timeout: IRS=0x%x\n",
azx_readw(chip, IRS));
chip->rirb.res[addr] = -1;
static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
struct azx *chip = bus->private_data;
unsigned int addr = azx_command_addr(val);
bus->rirb_error = 0;
if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
azx_writew(chip, IRS, azx_readw(chip, IRS) |
ICH6_IRS_VALID);
azx_writew(chip, IRS, azx_readw(chip, IRS) |
ICH6_IRS_BUSY);
return azx_single_wait_for_response(chip, addr);
if (printk_ratelimit())
dev_dbg(chip->card->dev,
"send_cmd timeout: IRS=0x%x, val=0x%x\n",
azx_readw(chip, IRS), val);
static unsigned int azx_single_get_response(struct hda_bus *bus,
unsigned int addr)
struct azx *chip = bus->private_data;
return chip->rirb.res[addr];
/*
* The below are the main callbacks from hda_codec.
*
* They are just the skeleton to call sub-callbacks according to the
* current setting of chip->single_cmd.
*/
/* send a command */
static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
struct azx *chip = bus->private_data;
chip->last_cmd[azx_command_addr(val)] = val;
if (chip->single_cmd)
return azx_single_send_cmd(bus, val);
return azx_corb_send_cmd(bus, val);
}
/* get a response */
static unsigned int azx_get_response(struct hda_bus *bus,
unsigned int addr)
struct azx *chip = bus->private_data;
if (chip->single_cmd)
return azx_single_get_response(bus, addr);
return azx_rirb_get_response(bus, addr);
static void azx_power_notify(struct hda_bus *bus, bool power_up);
#ifdef CONFIG_SND_HDA_DSP_LOADER
static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
unsigned int byte_size,
struct snd_dma_buffer *bufp);
static void azx_load_dsp_trigger(struct hda_bus *bus, bool start);
static void azx_load_dsp_cleanup(struct hda_bus *bus,
struct snd_dma_buffer *dmab);
#endif
/* enter link reset */
static void azx_enter_link_reset(struct azx *chip)
{
unsigned long timeout;
/* reset controller */
azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
timeout = jiffies + msecs_to_jiffies(100);
while ((azx_readb(chip, GCTL) & ICH6_GCTL_RESET) &&
time_before(jiffies, timeout))
usleep_range(500, 1000);
}
/* exit link reset */
static void azx_exit_link_reset(struct azx *chip)
unsigned long timeout;
azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
timeout = jiffies + msecs_to_jiffies(100);
while (!azx_readb(chip, GCTL) &&
time_before(jiffies, timeout))
usleep_range(500, 1000);
}
/* reset codec link */
static int azx_reset(struct azx *chip, int full_reset)
{
if (!full_reset)
goto __skip;
/* clear STATESTS */
azx_writew(chip, STATESTS, STATESTS_INT_MASK);
/* delay for >= 100us for codec PLL to settle per spec
* Rev 0.9 section 5.5.1
*/
usleep_range(500, 1000);
/* Brent Chartrand said to wait >= 540us for codecs to initialize */
usleep_range(1000, 1200);
__skip:
if (!azx_readb(chip, GCTL)) {
dev_dbg(chip->card->dev, "azx_reset: controller not ready!\n");
if (!chip->single_cmd)
azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
ICH6_GCTL_UNSOL);
dev_dbg(chip->card->dev, "codec_mask = 0x%x\n",
chip->codec_mask);
}
return 0;
}
/*
* Lowlevel interface
*/
/* enable interrupts */
static void azx_int_enable(struct azx *chip)
{
/* enable controller CIE and GIE */
azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) |
ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN);
}
/* disable interrupts */
static void azx_int_disable(struct azx *chip)
{
int i;
/* disable interrupts in stream descriptor */
for (i = 0; i < chip->num_streams; i++) {
struct azx_dev *azx_dev = &chip->azx_dev[i];
azx_sd_writeb(azx_dev, SD_CTL,
azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK);
}
/* disable SIE for all streams */
azx_writeb(chip, INTCTL, 0);
/* disable controller CIE and GIE */
azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) &
~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN));
}
/* clear interrupts */
static void azx_int_clear(struct azx *chip)
for (i = 0; i < chip->num_streams; i++) {
struct azx_dev *azx_dev = &chip->azx_dev[i];
azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
}
/* clear STATESTS */
azx_writew(chip, STATESTS, STATESTS_INT_MASK);
/* clear rirb status */
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
/* clear int status */
azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM);
}
/* start a stream */
static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
/*
* Before stream start, initialize parameter
*/
azx_dev->insufficient = 1;
azx_writel(chip, INTCTL,
azx_readl(chip, INTCTL) | (1 << azx_dev->index));
/* set DMA start and interrupt mask */
azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
SD_CTL_DMA_START | SD_INT_MASK);
}
/* stop DMA */
static void azx_stream_clear(struct azx *chip, struct azx_dev *azx_dev)
{
azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
~(SD_CTL_DMA_START | SD_INT_MASK));
azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
}
/* stop a stream */
static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
{
azx_stream_clear(chip, azx_dev);
azx_writel(chip, INTCTL,
azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
* reset and start the controller registers
static void azx_init_chip(struct azx *chip, int full_reset)
if (chip->initialized)
return;
azx_reset(chip, full_reset);
/* initialize interrupts */
azx_int_clear(chip);
azx_int_enable(chip);
/* initialize the codec command I/O */
if (!chip->single_cmd)
azx_init_cmd_io(chip);
/* program the position buffer */
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr));
chip->initialized = 1;
}
/*
* initialize the PCI registers
*/
/* update bits in a PCI register byte */
static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
unsigned char mask, unsigned char val)
{
unsigned char data;
pci_read_config_byte(pci, reg, &data);
data &= ~mask;
data |= (val & mask);
pci_write_config_byte(pci, reg, data);
}
static void azx_init_pci(struct azx *chip)
{
/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
* TCSEL == Traffic Class Select Register, which sets PCI express QOS
* Ensuring these bits are 0 clears playback static on some HD Audio
* codecs.
* The PCI register TCSEL is defined in the Intel manuals.
if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
dev_dbg(chip->card->dev, "Clearing TCSEL\n");
update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,