Commit 9a34af4a authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Move more PCI-controller-specific stuff from generic code

Just move struct fields between struct azx and struct hda_intel, and
move some definitions from hda_priv.h to hda_intel.c.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b6050ef6
...@@ -75,6 +75,26 @@ enum { ...@@ -75,6 +75,26 @@ enum {
POS_FIX_COMBO, 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
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
...@@ -312,8 +332,28 @@ struct hda_intel { ...@@ -312,8 +332,28 @@ struct hda_intel {
/* HSW/BDW display HDA controller to restore BCLK from CDCLK */ /* HSW/BDW display HDA controller to restore BCLK from CDCLK */
unsigned int bclk_m; unsigned int bclk_m;
unsigned int bclk_n; 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 #ifdef CONFIG_X86
static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
...@@ -480,6 +520,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); ...@@ -480,6 +520,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
/* called from IRQ */ /* called from IRQ */
static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev) 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; int ok;
ok = azx_position_ok(chip, azx_dev); ok = azx_position_ok(chip, azx_dev);
...@@ -489,7 +530,7 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev) ...@@ -489,7 +530,7 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
} else if (ok == 0 && chip->bus && chip->bus->workq) { } else if (ok == 0 && chip->bus && chip->bus->workq) {
/* bogus IRQ, process it later */ /* bogus IRQ, process it later */
azx_dev->irq_pending = 1; 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; return 0;
} }
...@@ -550,14 +591,15 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) ...@@ -550,14 +591,15 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
*/ */
static void azx_irq_pending_work(struct work_struct *work) 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; int i, pending, ok;
if (!chip->irq_pending_warned) { if (!hda->irq_pending_warned) {
dev_info(chip->card->dev, dev_info(chip->card->dev,
"IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.\n", "IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.\n",
chip->card->number); chip->card->number);
chip->irq_pending_warned = 1; hda->irq_pending_warned = 1;
} }
for (;;) { for (;;) {
...@@ -677,21 +719,24 @@ static LIST_HEAD(card_list); ...@@ -677,21 +719,24 @@ static LIST_HEAD(card_list);
static void azx_add_card_list(struct azx *chip) 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); mutex_lock(&card_list_lock);
list_add(&chip->list, &card_list); list_add(&hda->list, &card_list);
mutex_unlock(&card_list_lock); mutex_unlock(&card_list_lock);
} }
static void azx_del_card_list(struct azx *chip) 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); mutex_lock(&card_list_lock);
list_del_init(&chip->list); list_del_init(&hda->list);
mutex_unlock(&card_list_lock); mutex_unlock(&card_list_lock);
} }
/* trigger power-save check at writing parameter */ /* trigger power-save check at writing parameter */
static int param_set_xint(const char *val, const struct kernel_param *kp) static int param_set_xint(const char *val, const struct kernel_param *kp)
{ {
struct hda_intel *hda;
struct azx *chip; struct azx *chip;
struct hda_codec *c; struct hda_codec *c;
int prev = power_save; int prev = power_save;
...@@ -701,7 +746,8 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) ...@@ -701,7 +746,8 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
return ret; return ret;
mutex_lock(&card_list_lock); 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) if (!chip->bus || chip->disabled)
continue; continue;
list_for_each_entry(c, &chip->bus->codec_list, list) list_for_each_entry(c, &chip->bus->codec_list, list)
...@@ -939,10 +985,11 @@ static void azx_vs_set_state(struct pci_dev *pci, ...@@ -939,10 +985,11 @@ static void azx_vs_set_state(struct pci_dev *pci,
{ {
struct snd_card *card = pci_get_drvdata(pci); struct snd_card *card = pci_get_drvdata(pci);
struct azx *chip = card->private_data; struct azx *chip = card->private_data;
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
bool disabled; bool disabled;
wait_for_completion(&chip->probe_wait); wait_for_completion(&hda->probe_wait);
if (chip->init_failed) if (hda->init_failed)
return; return;
disabled = (state == VGA_SWITCHEROO_OFF); disabled = (state == VGA_SWITCHEROO_OFF);
...@@ -956,7 +1003,7 @@ static void azx_vs_set_state(struct pci_dev *pci, ...@@ -956,7 +1003,7 @@ static void azx_vs_set_state(struct pci_dev *pci,
"Start delayed initialization\n"); "Start delayed initialization\n");
if (azx_probe_continue(chip) < 0) { if (azx_probe_continue(chip) < 0) {
dev_err(chip->card->dev, "initialization error\n"); dev_err(chip->card->dev, "initialization error\n");
chip->init_failed = true; hda->init_failed = true;
} }
} }
} else { } else {
...@@ -986,9 +1033,10 @@ static bool azx_vs_can_switch(struct pci_dev *pci) ...@@ -986,9 +1033,10 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
{ {
struct snd_card *card = pci_get_drvdata(pci); struct snd_card *card = pci_get_drvdata(pci);
struct azx *chip = card->private_data; struct azx *chip = card->private_data;
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
wait_for_completion(&chip->probe_wait); wait_for_completion(&hda->probe_wait);
if (chip->init_failed) if (hda->init_failed)
return false; return false;
if (chip->disabled || !chip->bus) if (chip->disabled || !chip->bus)
return true; return true;
...@@ -1000,11 +1048,12 @@ static bool azx_vs_can_switch(struct pci_dev *pci) ...@@ -1000,11 +1048,12 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
static void init_vga_switcheroo(struct azx *chip) 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); struct pci_dev *p = get_bound_vga(chip->pci);
if (p) { if (p) {
dev_info(chip->card->dev, dev_info(chip->card->dev,
"Handle VGA-switcheroo audio client\n"); "Handle VGA-switcheroo audio client\n");
chip->use_vga_switcheroo = 1; hda->use_vga_switcheroo = 1;
pci_dev_put(p); pci_dev_put(p);
} }
} }
...@@ -1016,9 +1065,10 @@ static const struct vga_switcheroo_client_ops azx_vs_ops = { ...@@ -1016,9 +1065,10 @@ static const struct vga_switcheroo_client_ops azx_vs_ops = {
static int register_vga_switcheroo(struct azx *chip) static int register_vga_switcheroo(struct azx *chip)
{ {
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
int err; int err;
if (!chip->use_vga_switcheroo) if (!hda->use_vga_switcheroo)
return 0; return 0;
/* FIXME: currently only handling DIS controller /* FIXME: currently only handling DIS controller
* is there any machine with two switchable HDMI audio controllers? * is there any machine with two switchable HDMI audio controllers?
...@@ -1028,11 +1078,11 @@ static int register_vga_switcheroo(struct azx *chip) ...@@ -1028,11 +1078,11 @@ static int register_vga_switcheroo(struct azx *chip)
chip->bus != NULL); chip->bus != NULL);
if (err < 0) if (err < 0)
return err; return err;
chip->vga_switcheroo_registered = 1; hda->vga_switcheroo_registered = 1;
/* register as an optimus hdmi audio power domain */ /* register as an optimus hdmi audio power domain */
vga_switcheroo_init_domain_pm_optimus_hdmi_audio(chip->card->dev, vga_switcheroo_init_domain_pm_optimus_hdmi_audio(chip->card->dev,
&chip->hdmi_pm_domain); &hda->hdmi_pm_domain);
return 0; return 0;
} }
#else #else
...@@ -1048,7 +1098,6 @@ static int azx_free(struct azx *chip) ...@@ -1048,7 +1098,6 @@ static int azx_free(struct azx *chip)
{ {
struct pci_dev *pci = chip->pci; struct pci_dev *pci = chip->pci;
struct hda_intel *hda = container_of(chip, struct hda_intel, chip); struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
int i; int i;
if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
...@@ -1059,13 +1108,13 @@ static int azx_free(struct azx *chip) ...@@ -1059,13 +1108,13 @@ static int azx_free(struct azx *chip)
azx_notifier_unregister(chip); azx_notifier_unregister(chip);
chip->init_failed = 1; /* to be sure */ hda->init_failed = 1; /* to be sure */
complete_all(&chip->probe_wait); complete_all(&hda->probe_wait);
if (use_vga_switcheroo(chip)) { if (use_vga_switcheroo(hda)) {
if (chip->disabled && chip->bus) if (chip->disabled && chip->bus)
snd_hda_unlock_devices(chip->bus); snd_hda_unlock_devices(chip->bus);
if (chip->vga_switcheroo_registered) if (hda->vga_switcheroo_registered)
vga_switcheroo_unregister_client(chip->pci); vga_switcheroo_unregister_client(chip->pci);
} }
...@@ -1350,7 +1399,8 @@ static void azx_check_snoop_available(struct azx *chip) ...@@ -1350,7 +1399,8 @@ static void azx_check_snoop_available(struct azx *chip)
static void azx_probe_work(struct work_struct *work) 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);
} }
/* /*
...@@ -1393,11 +1443,11 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1393,11 +1443,11 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
check_msi(chip); check_msi(chip);
chip->dev_index = dev; chip->dev_index = dev;
chip->jackpoll_ms = jackpoll_ms; 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->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_vga_switcheroo(chip);
init_completion(&chip->probe_wait); init_completion(&hda->probe_wait);
assign_position_fix(chip, check_position_fix(chip, position_fix[dev])); assign_position_fix(chip, check_position_fix(chip, position_fix[dev]));
...@@ -1428,7 +1478,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1428,7 +1478,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
} }
/* continue probing in work context as may trigger request module */ /* 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; *rchip = chip;
...@@ -1750,6 +1800,7 @@ static int azx_probe(struct pci_dev *pci, ...@@ -1750,6 +1800,7 @@ static int azx_probe(struct pci_dev *pci,
{ {
static int dev; static int dev;
struct snd_card *card; struct snd_card *card;
struct hda_intel *hda;
struct azx *chip; struct azx *chip;
bool schedule_probe; bool schedule_probe;
int err; int err;
...@@ -1773,6 +1824,7 @@ static int azx_probe(struct pci_dev *pci, ...@@ -1773,6 +1824,7 @@ static int azx_probe(struct pci_dev *pci,
if (err < 0) if (err < 0)
goto out_free; goto out_free;
card->private_data = chip; card->private_data = chip;
hda = container_of(chip, struct hda_intel, chip);
pci_set_drvdata(pci, card); pci_set_drvdata(pci, card);
...@@ -1809,11 +1861,11 @@ static int azx_probe(struct pci_dev *pci, ...@@ -1809,11 +1861,11 @@ static int azx_probe(struct pci_dev *pci,
#endif #endif
if (schedule_probe) if (schedule_probe)
schedule_work(&chip->probe_work); schedule_work(&hda->probe_work);
dev++; dev++;
if (chip->disabled) if (chip->disabled)
complete_all(&chip->probe_wait); complete_all(&hda->probe_wait);
return 0; return 0;
out_free: out_free:
...@@ -1829,6 +1881,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = { ...@@ -1829,6 +1881,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
static int azx_probe_continue(struct azx *chip) 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; struct pci_dev *pci = chip->pci;
int dev = chip->dev_index; int dev = chip->dev_index;
int err; int err;
...@@ -1902,13 +1955,13 @@ static int azx_probe_continue(struct azx *chip) ...@@ -1902,13 +1955,13 @@ static int azx_probe_continue(struct azx *chip)
power_down_all_codecs(chip); power_down_all_codecs(chip);
azx_notifier_register(chip); azx_notifier_register(chip);
azx_add_card_list(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); pm_runtime_put_noidle(&pci->dev);
out_free: out_free:
if (err < 0) if (err < 0)
chip->init_failed = 1; hda->init_failed = 1;
complete_all(&chip->probe_wait); complete_all(&hda->probe_wait);
return err; return err;
} }
......
...@@ -188,26 +188,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; ...@@ -188,26 +188,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
/* 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
/* HD Audio class code */ /* HD Audio class code */
#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403 #define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
...@@ -345,7 +325,6 @@ struct azx { ...@@ -345,7 +325,6 @@ struct azx {
/* locks */ /* locks */
spinlock_t reg_lock; spinlock_t reg_lock;
struct mutex open_mutex; /* Prevents concurrent open/close operations */ struct mutex open_mutex; /* Prevents concurrent open/close operations */
struct completion probe_wait;
/* streams (x num_streams) */ /* streams (x num_streams) */
struct azx_dev *azx_dev; struct azx_dev *azx_dev;
...@@ -379,38 +358,21 @@ struct azx { ...@@ -379,38 +358,21 @@ struct azx {
unsigned int single_cmd:1; unsigned int single_cmd:1;
unsigned int polling_mode:1; unsigned int polling_mode:1;
unsigned int msi:1; unsigned int msi:1;
unsigned int irq_pending_warned:1;
unsigned int probing:1; /* codec probing phase */ unsigned int probing:1; /* codec probing phase */
unsigned int snoop:1; unsigned int snoop:1;
unsigned int align_buffer_size:1; unsigned int align_buffer_size:1;
unsigned int region_requested:1; unsigned int region_requested:1;
/* VGA-switcheroo setup */
unsigned int use_vga_switcheroo:1;
unsigned int vga_switcheroo_registered:1;
unsigned int init_failed:1; /* delayed init failed */
unsigned int disabled:1; /* disabled by VGA-switcher */ unsigned int disabled:1; /* disabled by VGA-switcher */
/* for debugging */ /* for debugging */
unsigned int last_cmd[AZX_MAX_CODECS]; unsigned int last_cmd[AZX_MAX_CODECS];
/* for pending irqs */
struct work_struct irq_pending_work;
struct work_struct probe_work;
/* reboot notifier (for mysterious hangup problem at power-down) */ /* reboot notifier (for mysterious hangup problem at power-down) */
struct notifier_block reboot_notifier; struct notifier_block reboot_notifier;
/* card list (for power_save trigger) */
struct list_head list;
#ifdef CONFIG_SND_HDA_DSP_LOADER #ifdef CONFIG_SND_HDA_DSP_LOADER
struct azx_dev saved_azx_dev; struct azx_dev saved_azx_dev;
#endif #endif
/* secondary power domain for hdmi audio under vga device */
struct dev_pm_domain hdmi_pm_domain;
}; };
#ifdef CONFIG_SND_VERBOSE_PRINTK #ifdef CONFIG_SND_VERBOSE_PRINTK
......
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