|
@@ -44,7 +44,6 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/pci.h>
|
|
|
#include <linux/mutex.h>
|
|
|
-#include <linux/reboot.h>
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/pm_runtime.h>
|
|
|
#include <linux/clocksource.h>
|
|
@@ -66,6 +65,52 @@
|
|
|
#include "hda_controller.h"
|
|
|
#include "hda_priv.h"
|
|
|
|
|
|
+/* position fix mode */
|
|
|
+enum {
|
|
|
+ POS_FIX_AUTO,
|
|
|
+ POS_FIX_LPIB,
|
|
|
+ POS_FIX_POSBUF,
|
|
|
+ POS_FIX_VIACOMBO,
|
|
|
+ POS_FIX_COMBO,
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines for ATI HD Audio support in SB450 south bridge */
|
|
|
+#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
|
|
|
+#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
|
|
|
+
|
|
|
+/* Defines for Nvidia HDA support */
|
|
|
+#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
|
|
|
+#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
|
|
|
+#define NVIDIA_HDA_ISTRM_COH 0x4d
|
|
|
+#define NVIDIA_HDA_OSTRM_COH 0x4c
|
|
|
+#define NVIDIA_HDA_ENABLE_COHBIT 0x01
|
|
|
+
|
|
|
+/* Defines for Intel SCH HDA snoop control */
|
|
|
+#define INTEL_SCH_HDA_DEVC 0x78
|
|
|
+#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
|
|
|
+
|
|
|
+/* Define IN stream 0 FIFO size offset in VIA controller */
|
|
|
+#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90
|
|
|
+/* Define VIA HD Audio Device ID*/
|
|
|
+#define VIA_HDAC_DEVICE_ID 0x3288
|
|
|
+
|
|
|
+/* max number of SDs */
|
|
|
+/* ICH, ATI and VIA have 4 playback and 4 capture */
|
|
|
+#define ICH6_NUM_CAPTURE 4
|
|
|
+#define ICH6_NUM_PLAYBACK 4
|
|
|
+
|
|
|
+/* ULI has 6 playback and 5 capture */
|
|
|
+#define ULI_NUM_CAPTURE 5
|
|
|
+#define ULI_NUM_PLAYBACK 6
|
|
|
+
|
|
|
+/* ATI HDMI may have up to 8 playbacks and 0 capture */
|
|
|
+#define ATIHDMI_NUM_CAPTURE 0
|
|
|
+#define ATIHDMI_NUM_PLAYBACK 8
|
|
|
+
|
|
|
+/* TERA has 4 playback and 3 capture */
|
|
|
+#define TERA_NUM_CAPTURE 3
|
|
|
+#define TERA_NUM_PLAYBACK 4
|
|
|
+
|
|
|
|
|
|
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
|
|
|
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
|
|
@@ -294,8 +339,8 @@ static char *driver_short_names[] = {
|
|
|
* Clock) to 24MHz BCLK: BCLK = CDCLK * M / N
|
|
|
* The values will be lost when the display power well is disabled.
|
|
|
*/
|
|
|
-#define ICH6_REG_EM4 0x100c
|
|
|
-#define ICH6_REG_EM5 0x1010
|
|
|
+#define AZX_REG_EM4 0x100c
|
|
|
+#define AZX_REG_EM5 0x1010
|
|
|
|
|
|
struct hda_intel {
|
|
|
struct azx chip;
|
|
@@ -303,8 +348,28 @@ struct hda_intel {
|
|
|
/* HSW/BDW display HDA controller to restore BCLK from CDCLK */
|
|
|
unsigned int bclk_m;
|
|
|
unsigned int bclk_n;
|
|
|
-};
|
|
|
|
|
|
+ /* for pending irqs */
|
|
|
+ struct work_struct irq_pending_work;
|
|
|
+
|
|
|
+ /* sync probing */
|
|
|
+ struct completion probe_wait;
|
|
|
+ struct work_struct probe_work;
|
|
|
+
|
|
|
+ /* card list (for power_save trigger) */
|
|
|
+ struct list_head list;
|
|
|
+
|
|
|
+ /* extra flags */
|
|
|
+ unsigned int irq_pending_warned:1;
|
|
|
+
|
|
|
+ /* VGA-switcheroo setup */
|
|
|
+ unsigned int use_vga_switcheroo:1;
|
|
|
+ unsigned int vga_switcheroo_registered:1;
|
|
|
+ unsigned int init_failed:1; /* delayed init failed */
|
|
|
+
|
|
|
+ /* secondary power domain for hdmi audio under vga device */
|
|
|
+ struct dev_pm_domain hdmi_pm_domain;
|
|
|
+};
|
|
|
|
|
|
#ifdef CONFIG_X86
|
|
|
static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
|
|
@@ -386,7 +451,7 @@ static void azx_init_pci(struct azx *chip)
|
|
|
*/
|
|
|
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);
|
|
|
+ update_pci_byte(chip->pci, AZX_PCIREG_TCSEL, 0x07, 0);
|
|
|
}
|
|
|
|
|
|
/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
|
|
@@ -434,11 +499,44 @@ static void azx_init_pci(struct azx *chip)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* calculate runtime delay from LPIB */
|
|
|
+static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev,
|
|
|
+ unsigned int pos)
|
|
|
+{
|
|
|
+ struct snd_pcm_substream *substream = azx_dev->substream;
|
|
|
+ int stream = substream->stream;
|
|
|
+ unsigned int lpib_pos = azx_get_pos_lpib(chip, azx_dev);
|
|
|
+ int delay;
|
|
|
+
|
|
|
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
|
+ delay = pos - lpib_pos;
|
|
|
+ else
|
|
|
+ delay = lpib_pos - pos;
|
|
|
+ if (delay < 0) {
|
|
|
+ if (delay >= azx_dev->delay_negative_threshold)
|
|
|
+ delay = 0;
|
|
|
+ else
|
|
|
+ delay += azx_dev->bufsize;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (delay >= azx_dev->period_bytes) {
|
|
|
+ dev_info(chip->card->dev,
|
|
|
+ "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
|
|
|
+ delay, azx_dev->period_bytes);
|
|
|
+ delay = 0;
|
|
|
+ chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
|
|
|
+ chip->get_delay[stream] = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return bytes_to_frames(substream->runtime, delay);
|
|
|
+}
|
|
|
+
|
|
|
static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
|
|
|
|
|
|
/* called from IRQ */
|
|
|
static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
{
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
int ok;
|
|
|
|
|
|
ok = azx_position_ok(chip, azx_dev);
|
|
@@ -448,7 +546,7 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
} else if (ok == 0 && chip->bus && chip->bus->workq) {
|
|
|
/* bogus IRQ, process it later */
|
|
|
azx_dev->irq_pending = 1;
|
|
|
- queue_work(chip->bus->workq, &chip->irq_pending_work);
|
|
|
+ queue_work(chip->bus->workq, &hda->irq_pending_work);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -464,6 +562,8 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
*/
|
|
|
static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
{
|
|
|
+ struct snd_pcm_substream *substream = azx_dev->substream;
|
|
|
+ int stream = substream->stream;
|
|
|
u32 wallclk;
|
|
|
unsigned int pos;
|
|
|
|
|
@@ -471,7 +571,25 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
if (wallclk < (azx_dev->period_wallclk * 2) / 3)
|
|
|
return -1; /* bogus (too early) interrupt */
|
|
|
|
|
|
- pos = azx_get_position(chip, azx_dev, true);
|
|
|
+ if (chip->get_position[stream])
|
|
|
+ pos = chip->get_position[stream](chip, azx_dev);
|
|
|
+ else { /* use the position buffer as default */
|
|
|
+ pos = azx_get_pos_posbuf(chip, azx_dev);
|
|
|
+ if (!pos || pos == (u32)-1) {
|
|
|
+ dev_info(chip->card->dev,
|
|
|
+ "Invalid position buffer, using LPIB read method instead.\n");
|
|
|
+ chip->get_position[stream] = azx_get_pos_lpib;
|
|
|
+ pos = azx_get_pos_lpib(chip, azx_dev);
|
|
|
+ chip->get_delay[stream] = NULL;
|
|
|
+ } else {
|
|
|
+ chip->get_position[stream] = azx_get_pos_posbuf;
|
|
|
+ if (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)
|
|
|
+ chip->get_delay[stream] = azx_get_delay_from_lpib;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pos >= azx_dev->bufsize)
|
|
|
+ pos = 0;
|
|
|
|
|
|
if (WARN_ONCE(!azx_dev->period_bytes,
|
|
|
"hda-intel: zero azx_dev->period_bytes"))
|
|
@@ -489,14 +607,15 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
*/
|
|
|
static void azx_irq_pending_work(struct work_struct *work)
|
|
|
{
|
|
|
- struct azx *chip = container_of(work, struct azx, irq_pending_work);
|
|
|
+ struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work);
|
|
|
+ struct azx *chip = &hda->chip;
|
|
|
int i, pending, ok;
|
|
|
|
|
|
- if (!chip->irq_pending_warned) {
|
|
|
+ if (!hda->irq_pending_warned) {
|
|
|
dev_info(chip->card->dev,
|
|
|
"IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.\n",
|
|
|
chip->card->number);
|
|
|
- chip->irq_pending_warned = 1;
|
|
|
+ hda->irq_pending_warned = 1;
|
|
|
}
|
|
|
|
|
|
for (;;) {
|
|
@@ -554,27 +673,86 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/* get the current DMA position with correction on VIA chips */
|
|
|
+static unsigned int azx_via_get_position(struct azx *chip,
|
|
|
+ struct azx_dev *azx_dev)
|
|
|
+{
|
|
|
+ unsigned int link_pos, mini_pos, bound_pos;
|
|
|
+ unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
|
|
|
+ unsigned int fifo_size;
|
|
|
+
|
|
|
+ link_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
|
|
|
+ if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
|
+ /* Playback, no problem using link position */
|
|
|
+ return link_pos;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Capture */
|
|
|
+ /* For new chipset,
|
|
|
+ * use mod to get the DMA position just like old chipset
|
|
|
+ */
|
|
|
+ mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
|
|
|
+ mod_dma_pos %= azx_dev->period_bytes;
|
|
|
+
|
|
|
+ /* azx_dev->fifo_size can't get FIFO size of in stream.
|
|
|
+ * Get from base address + offset.
|
|
|
+ */
|
|
|
+ fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
|
|
|
+
|
|
|
+ if (azx_dev->insufficient) {
|
|
|
+ /* Link position never gather than FIFO size */
|
|
|
+ if (link_pos <= fifo_size)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ azx_dev->insufficient = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (link_pos <= fifo_size)
|
|
|
+ mini_pos = azx_dev->bufsize + link_pos - fifo_size;
|
|
|
+ else
|
|
|
+ mini_pos = link_pos - fifo_size;
|
|
|
+
|
|
|
+ /* Find nearest previous boudary */
|
|
|
+ mod_mini_pos = mini_pos % azx_dev->period_bytes;
|
|
|
+ mod_link_pos = link_pos % azx_dev->period_bytes;
|
|
|
+ if (mod_link_pos >= fifo_size)
|
|
|
+ bound_pos = link_pos - mod_link_pos;
|
|
|
+ else if (mod_dma_pos >= mod_mini_pos)
|
|
|
+ bound_pos = mini_pos - mod_mini_pos;
|
|
|
+ else {
|
|
|
+ bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
|
|
|
+ if (bound_pos >= azx_dev->bufsize)
|
|
|
+ bound_pos = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Calculate real DMA position we want */
|
|
|
+ return bound_pos + mod_dma_pos;
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_PM
|
|
|
static DEFINE_MUTEX(card_list_lock);
|
|
|
static LIST_HEAD(card_list);
|
|
|
|
|
|
static void azx_add_card_list(struct azx *chip)
|
|
|
{
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
mutex_lock(&card_list_lock);
|
|
|
- list_add(&chip->list, &card_list);
|
|
|
+ list_add(&hda->list, &card_list);
|
|
|
mutex_unlock(&card_list_lock);
|
|
|
}
|
|
|
|
|
|
static void azx_del_card_list(struct azx *chip)
|
|
|
{
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
mutex_lock(&card_list_lock);
|
|
|
- list_del_init(&chip->list);
|
|
|
+ list_del_init(&hda->list);
|
|
|
mutex_unlock(&card_list_lock);
|
|
|
}
|
|
|
|
|
|
/* trigger power-save check at writing parameter */
|
|
|
static int param_set_xint(const char *val, const struct kernel_param *kp)
|
|
|
{
|
|
|
+ struct hda_intel *hda;
|
|
|
struct azx *chip;
|
|
|
struct hda_codec *c;
|
|
|
int prev = power_save;
|
|
@@ -584,7 +762,8 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
|
|
|
return ret;
|
|
|
|
|
|
mutex_lock(&card_list_lock);
|
|
|
- list_for_each_entry(chip, &card_list, list) {
|
|
|
+ list_for_each_entry(hda, &card_list, list) {
|
|
|
+ chip = &hda->chip;
|
|
|
if (!chip->bus || chip->disabled)
|
|
|
continue;
|
|
|
list_for_each_entry(c, &chip->bus->codec_list, list)
|
|
@@ -789,29 +968,6 @@ static const struct dev_pm_ops azx_pm = {
|
|
|
#endif /* CONFIG_PM */
|
|
|
|
|
|
|
|
|
-/*
|
|
|
- * reboot notifier for hang-up problem at power-down
|
|
|
- */
|
|
|
-static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
|
|
|
-{
|
|
|
- struct azx *chip = container_of(nb, struct azx, reboot_notifier);
|
|
|
- snd_hda_bus_reboot_notify(chip->bus);
|
|
|
- azx_stop_chip(chip);
|
|
|
- return NOTIFY_OK;
|
|
|
-}
|
|
|
-
|
|
|
-static void azx_notifier_register(struct azx *chip)
|
|
|
-{
|
|
|
- chip->reboot_notifier.notifier_call = azx_halt;
|
|
|
- register_reboot_notifier(&chip->reboot_notifier);
|
|
|
-}
|
|
|
-
|
|
|
-static void azx_notifier_unregister(struct azx *chip)
|
|
|
-{
|
|
|
- if (chip->reboot_notifier.notifier_call)
|
|
|
- unregister_reboot_notifier(&chip->reboot_notifier);
|
|
|
-}
|
|
|
-
|
|
|
static int azx_probe_continue(struct azx *chip);
|
|
|
|
|
|
#ifdef SUPPORT_VGA_SWITCHEROO
|
|
@@ -822,10 +978,11 @@ static void azx_vs_set_state(struct pci_dev *pci,
|
|
|
{
|
|
|
struct snd_card *card = pci_get_drvdata(pci);
|
|
|
struct azx *chip = card->private_data;
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
bool disabled;
|
|
|
|
|
|
- wait_for_completion(&chip->probe_wait);
|
|
|
- if (chip->init_failed)
|
|
|
+ wait_for_completion(&hda->probe_wait);
|
|
|
+ if (hda->init_failed)
|
|
|
return;
|
|
|
|
|
|
disabled = (state == VGA_SWITCHEROO_OFF);
|
|
@@ -839,7 +996,7 @@ static void azx_vs_set_state(struct pci_dev *pci,
|
|
|
"Start delayed initialization\n");
|
|
|
if (azx_probe_continue(chip) < 0) {
|
|
|
dev_err(chip->card->dev, "initialization error\n");
|
|
|
- chip->init_failed = true;
|
|
|
+ hda->init_failed = true;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
@@ -869,9 +1026,10 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
|
|
|
{
|
|
|
struct snd_card *card = pci_get_drvdata(pci);
|
|
|
struct azx *chip = card->private_data;
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
|
|
|
- wait_for_completion(&chip->probe_wait);
|
|
|
- if (chip->init_failed)
|
|
|
+ wait_for_completion(&hda->probe_wait);
|
|
|
+ if (hda->init_failed)
|
|
|
return false;
|
|
|
if (chip->disabled || !chip->bus)
|
|
|
return true;
|
|
@@ -883,11 +1041,12 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
|
|
|
|
|
|
static void init_vga_switcheroo(struct azx *chip)
|
|
|
{
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
struct pci_dev *p = get_bound_vga(chip->pci);
|
|
|
if (p) {
|
|
|
dev_info(chip->card->dev,
|
|
|
"Handle VGA-switcheroo audio client\n");
|
|
|
- chip->use_vga_switcheroo = 1;
|
|
|
+ hda->use_vga_switcheroo = 1;
|
|
|
pci_dev_put(p);
|
|
|
}
|
|
|
}
|
|
@@ -899,9 +1058,10 @@ static const struct vga_switcheroo_client_ops azx_vs_ops = {
|
|
|
|
|
|
static int register_vga_switcheroo(struct azx *chip)
|
|
|
{
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
int err;
|
|
|
|
|
|
- if (!chip->use_vga_switcheroo)
|
|
|
+ if (!hda->use_vga_switcheroo)
|
|
|
return 0;
|
|
|
/* FIXME: currently only handling DIS controller
|
|
|
* is there any machine with two switchable HDMI audio controllers?
|
|
@@ -911,11 +1071,11 @@ static int register_vga_switcheroo(struct azx *chip)
|
|
|
chip->bus != NULL);
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
- chip->vga_switcheroo_registered = 1;
|
|
|
+ hda->vga_switcheroo_registered = 1;
|
|
|
|
|
|
/* register as an optimus hdmi audio power domain */
|
|
|
vga_switcheroo_init_domain_pm_optimus_hdmi_audio(chip->card->dev,
|
|
|
- &chip->hdmi_pm_domain);
|
|
|
+ &hda->hdmi_pm_domain);
|
|
|
return 0;
|
|
|
}
|
|
|
#else
|
|
@@ -931,7 +1091,6 @@ static int azx_free(struct azx *chip)
|
|
|
{
|
|
|
struct pci_dev *pci = chip->pci;
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
-
|
|
|
int i;
|
|
|
|
|
|
if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
|
|
@@ -942,13 +1101,13 @@ static int azx_free(struct azx *chip)
|
|
|
|
|
|
azx_notifier_unregister(chip);
|
|
|
|
|
|
- chip->init_failed = 1; /* to be sure */
|
|
|
- complete_all(&chip->probe_wait);
|
|
|
+ hda->init_failed = 1; /* to be sure */
|
|
|
+ complete_all(&hda->probe_wait);
|
|
|
|
|
|
- if (use_vga_switcheroo(chip)) {
|
|
|
+ if (use_vga_switcheroo(hda)) {
|
|
|
if (chip->disabled && chip->bus)
|
|
|
snd_hda_unlock_devices(chip->bus);
|
|
|
- if (chip->vga_switcheroo_registered)
|
|
|
+ if (hda->vga_switcheroo_registered)
|
|
|
vga_switcheroo_unregister_client(chip->pci);
|
|
|
}
|
|
|
|
|
@@ -1084,6 +1243,30 @@ static int check_position_fix(struct azx *chip, int fix)
|
|
|
return POS_FIX_AUTO;
|
|
|
}
|
|
|
|
|
|
+static void assign_position_fix(struct azx *chip, int fix)
|
|
|
+{
|
|
|
+ static azx_get_pos_callback_t callbacks[] = {
|
|
|
+ [POS_FIX_AUTO] = NULL,
|
|
|
+ [POS_FIX_LPIB] = azx_get_pos_lpib,
|
|
|
+ [POS_FIX_POSBUF] = azx_get_pos_posbuf,
|
|
|
+ [POS_FIX_VIACOMBO] = azx_via_get_position,
|
|
|
+ [POS_FIX_COMBO] = azx_get_pos_lpib,
|
|
|
+ };
|
|
|
+
|
|
|
+ chip->get_position[0] = chip->get_position[1] = callbacks[fix];
|
|
|
+
|
|
|
+ /* combo mode uses LPIB only for playback */
|
|
|
+ if (fix == POS_FIX_COMBO)
|
|
|
+ chip->get_position[1] = NULL;
|
|
|
+
|
|
|
+ if (fix == POS_FIX_POSBUF &&
|
|
|
+ (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
|
|
|
+ chip->get_delay[0] = chip->get_delay[1] =
|
|
|
+ azx_get_delay_from_lpib;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* black-lists for probe_mask
|
|
|
*/
|
|
@@ -1209,7 +1392,8 @@ static void azx_check_snoop_available(struct azx *chip)
|
|
|
|
|
|
static void azx_probe_work(struct work_struct *work)
|
|
|
{
|
|
|
- azx_probe_continue(container_of(work, struct azx, probe_work));
|
|
|
+ struct hda_intel *hda = container_of(work, struct hda_intel, probe_work);
|
|
|
+ azx_probe_continue(&hda->chip);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1252,19 +1436,13 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|
|
check_msi(chip);
|
|
|
chip->dev_index = dev;
|
|
|
chip->jackpoll_ms = jackpoll_ms;
|
|
|
- INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
|
|
|
INIT_LIST_HEAD(&chip->pcm_list);
|
|
|
- INIT_LIST_HEAD(&chip->list);
|
|
|
+ INIT_WORK(&hda->irq_pending_work, azx_irq_pending_work);
|
|
|
+ INIT_LIST_HEAD(&hda->list);
|
|
|
init_vga_switcheroo(chip);
|
|
|
- init_completion(&chip->probe_wait);
|
|
|
+ init_completion(&hda->probe_wait);
|
|
|
|
|
|
- chip->position_fix[0] = chip->position_fix[1] =
|
|
|
- check_position_fix(chip, position_fix[dev]);
|
|
|
- /* combo mode uses LPIB for playback */
|
|
|
- if (chip->position_fix[0] == POS_FIX_COMBO) {
|
|
|
- chip->position_fix[0] = POS_FIX_LPIB;
|
|
|
- chip->position_fix[1] = POS_FIX_AUTO;
|
|
|
- }
|
|
|
+ assign_position_fix(chip, check_position_fix(chip, position_fix[dev]));
|
|
|
|
|
|
check_probe_mask(chip, dev);
|
|
|
|
|
@@ -1293,7 +1471,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|
|
}
|
|
|
|
|
|
/* continue probing in work context as may trigger request module */
|
|
|
- INIT_WORK(&chip->probe_work, azx_probe_work);
|
|
|
+ INIT_WORK(&hda->probe_work, azx_probe_work);
|
|
|
|
|
|
*rchip = chip;
|
|
|
|
|
@@ -1351,7 +1529,7 @@ static int azx_first_init(struct azx *chip)
|
|
|
NULL);
|
|
|
if (p_smbus) {
|
|
|
if (p_smbus->revision < 0x30)
|
|
|
- gcap &= ~ICH6_GCAP_64OK;
|
|
|
+ gcap &= ~AZX_GCAP_64OK;
|
|
|
pci_dev_put(p_smbus);
|
|
|
}
|
|
|
}
|
|
@@ -1359,7 +1537,7 @@ static int azx_first_init(struct azx *chip)
|
|
|
/* disable 64bit DMA address on some devices */
|
|
|
if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
|
|
|
dev_dbg(card->dev, "Disabling 64bit DMA\n");
|
|
|
- gcap &= ~ICH6_GCAP_64OK;
|
|
|
+ gcap &= ~AZX_GCAP_64OK;
|
|
|
}
|
|
|
|
|
|
/* disable buffer size rounding to 128-byte multiples if supported */
|
|
@@ -1375,7 +1553,7 @@ static int azx_first_init(struct azx *chip)
|
|
|
}
|
|
|
|
|
|
/* allow 64bit DMA address if supported by H/W */
|
|
|
- if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
|
|
|
+ if ((gcap & AZX_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
|
|
|
pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
|
|
|
else {
|
|
|
pci_set_dma_mask(pci, DMA_BIT_MASK(32));
|
|
@@ -1615,6 +1793,7 @@ static int azx_probe(struct pci_dev *pci,
|
|
|
{
|
|
|
static int dev;
|
|
|
struct snd_card *card;
|
|
|
+ struct hda_intel *hda;
|
|
|
struct azx *chip;
|
|
|
bool schedule_probe;
|
|
|
int err;
|
|
@@ -1638,6 +1817,7 @@ static int azx_probe(struct pci_dev *pci,
|
|
|
if (err < 0)
|
|
|
goto out_free;
|
|
|
card->private_data = chip;
|
|
|
+ hda = container_of(chip, struct hda_intel, chip);
|
|
|
|
|
|
pci_set_drvdata(pci, card);
|
|
|
|
|
@@ -1674,11 +1854,11 @@ static int azx_probe(struct pci_dev *pci,
|
|
|
#endif
|
|
|
|
|
|
if (schedule_probe)
|
|
|
- schedule_work(&chip->probe_work);
|
|
|
+ schedule_work(&hda->probe_work);
|
|
|
|
|
|
dev++;
|
|
|
if (chip->disabled)
|
|
|
- complete_all(&chip->probe_wait);
|
|
|
+ complete_all(&hda->probe_wait);
|
|
|
return 0;
|
|
|
|
|
|
out_free:
|
|
@@ -1694,6 +1874,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
|
|
|
|
|
|
static int azx_probe_continue(struct azx *chip)
|
|
|
{
|
|
|
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
struct pci_dev *pci = chip->pci;
|
|
|
int dev = chip->dev_index;
|
|
|
int err;
|
|
@@ -1767,13 +1948,13 @@ static int azx_probe_continue(struct azx *chip)
|
|
|
power_down_all_codecs(chip);
|
|
|
azx_notifier_register(chip);
|
|
|
azx_add_card_list(chip);
|
|
|
- if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || chip->use_vga_switcheroo)
|
|
|
+ if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || hda->use_vga_switcheroo)
|
|
|
pm_runtime_put_noidle(&pci->dev);
|
|
|
|
|
|
out_free:
|
|
|
if (err < 0)
|
|
|
- chip->init_failed = 1;
|
|
|
- complete_all(&chip->probe_wait);
|
|
|
+ hda->init_failed = 1;
|
|
|
+ complete_all(&hda->probe_wait);
|
|
|
return err;
|
|
|
}
|
|
|
|