ALSA: ctxfi - Clean up probe routines
Clean up probe routines and model detection routines so that the driver
won't call and check the PCI subsystem id at each time.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 7898a37..002a70e 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -39,29 +39,40 @@
| (0x10 << 16) \
| ((IEC958_AES3_CON_FS_48000) << 24))
-static const struct ct_atc_chip_sub_details atc_sub_details[NUM_CTCARDS] = {
- [CTSB0760] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB0760,
- .nm_model = "SB076x"},
- [CTHENDRIX] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_HENDRIX,
- .nm_model = "Hendrix"},
- [CTSB08801] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB08801,
- .nm_model = "SB0880"},
- [CTSB08802] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB08802,
- .nm_model = "SB0880"},
- [CTSB08803] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB08803,
- .nm_model = "SB0880"}
+static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X),
+ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0x6000,
+ PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "UAA", CTUAA),
+ SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE,
+ "Unknown", CT20K1_UNKNOWN),
+ { } /* terminator */
};
-static struct ct_atc_chip_details atc_chip_details[] = {
- {.vendor = PCI_VENDOR_ID_CREATIVE,
- .device = PCI_DEVICE_ID_CREATIVE_20K1,
- .sub_details = NULL,
- .nm_card = "X-Fi 20k1"},
- {.vendor = PCI_VENDOR_ID_CREATIVE,
- .device = PCI_DEVICE_ID_CREATIVE_20K2,
- .sub_details = atc_sub_details,
- .nm_card = "X-Fi 20k2"},
- {} /* terminator */
+static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
+ "SB0760", CTSB0760),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
+ "SB0880", CTSB0880),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
+ "SB0880", CTSB0880),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08803,
+ "SB0880", CTSB0880),
+ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0x6000,
+ PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "UAA", CTHENDRIX),
+ { } /* terminator */
+};
+
+static const char *ct_subsys_name[NUM_CTCARDS] = {
+ [CTSB055X] = "SB055x",
+ [CTSB073X] = "SB073x",
+ [CTSB0760] = "SB076x",
+ [CTUAA] = "UAA",
+ [CT20K1_UNKNOWN] = "Unknown",
+ [CTHENDRIX] = "Hendrix",
+ [CTSB0880] = "SB0880",
};
static struct {
@@ -1208,62 +1219,39 @@
static int __devinit atc_identify_card(struct ct_atc *atc)
{
- u16 subsys;
- u8 revision;
- struct pci_dev *pci = atc->pci;
- const struct ct_atc_chip_details *d;
- enum CTCARDS i;
+ const struct snd_pci_quirk *p;
+ const struct snd_pci_quirk *list;
- subsys = pci->subsystem_device;
- revision = pci->revision;
- atc->chip_details = NULL;
- atc->model = NUM_CTCARDS;
- for (d = atc_chip_details; d->vendor; d++) {
- if (d->vendor != pci->vendor || d->device != pci->device)
- continue;
-
- if (NULL == d->sub_details) {
- atc->chip_details = d;
- break;
- }
- for (i = 0; i < NUM_CTCARDS; i++) {
- if ((d->sub_details[i].subsys == subsys) ||
- (((subsys & 0x6000) == 0x6000) &&
- ((d->sub_details[i].subsys & 0x6000) == 0x6000))) {
- atc->model = i;
- break;
- }
- }
- if (i >= NUM_CTCARDS)
- continue;
-
- atc->chip_details = d;
+ switch (atc->chip_type) {
+ case ATC20K1:
+ atc->chip_name = "20K1";
+ list = subsys_20k1_list;
break;
- /* not take revision into consideration now */
- }
- if (!d->vendor)
+ case ATC20K2:
+ atc->chip_name = "20K2";
+ list = subsys_20k2_list;
+ break;
+ default:
return -ENOENT;
-
+ }
+ p = snd_pci_quirk_lookup(atc->pci, list);
+ if (!p)
+ return -ENOENT;
+ atc->model = p->value;
+ atc->model_name = ct_subsys_name[atc->model];
+ snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
+ atc->chip_name, atc->model_name,
+ atc->pci->subsystem_vendor,
+ atc->pci->subsystem_device);
return 0;
}
int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
{
enum CTALSADEVS i;
- struct hw *hw = atc->hw;
int err;
- switch (hw->get_chip_type(hw)) {
- case ATC20K1:
- alsa_dev_funcs[MIXER].public_name = "20K1";
- break;
- case ATC20K2:
- alsa_dev_funcs[MIXER].public_name = "20K2";
- break;
- default:
- alsa_dev_funcs[MIXER].public_name = "Unknown";
- break;
- }
+ alsa_dev_funcs[MIXER].public_name = atc->chip_name;
for (i = 0; i < NUM_CTALSADEVS; i++) {
if (NULL == alsa_dev_funcs[i].create)
@@ -1287,7 +1275,7 @@
struct card_conf info = {0};
int i, err;
- err = create_hw_obj(atc->pci, &hw);
+ err = create_hw_obj(atc->pci, atc->chip_type, atc->model, &hw);
if (err) {
printk(KERN_ERR "Failed to create hw obj!!!\n");
return err;
@@ -1328,7 +1316,6 @@
struct sum_desc sum_dsc = {0};
struct sum_mgr *sum_mgr;
int err, i;
- unsigned short subsys_id;
atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
if (NULL == atc->daios)
@@ -1359,13 +1346,10 @@
}
atc->n_daio++;
}
- subsys_id = atc->pci->subsystem_device;
- if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) {
- /* SB073x cards */
+ if (atc->model == CTSB073X)
da_desc.type = SPDIFI1;
- } else {
+ else
da_desc.type = SPDIFIO;
- }
err = daio_mgr->get_daio(daio_mgr, &da_desc,
(struct daio **)&atc->daios[i]);
if (err) {
@@ -1555,7 +1539,8 @@
*/
int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
- unsigned int rsr, unsigned int msr, struct ct_atc **ratc)
+ unsigned int rsr, unsigned int msr,
+ int chip_type, struct ct_atc **ratc)
{
struct ct_atc *atc;
static struct snd_device_ops ops = {
@@ -1576,6 +1561,7 @@
atc->pci = pci;
atc->rsr = rsr;
atc->msr = msr;
+ atc->chip_type = chip_type;
spin_lock_init(&atc->atc_lock);
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 04459aa..a033472 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -37,15 +37,6 @@
NUM_CTALSADEVS /* This should always be the last */
};
-enum CTCARDS {
- CTSB0760,
- CTHENDRIX,
- CTSB08801,
- CTSB08802,
- CTSB08803,
- NUM_CTCARDS /* This should always be the last */
-};
-
struct ct_atc_chip_sub_details {
u16 subsys;
const char *nm_model;
@@ -89,8 +80,10 @@
unsigned int msr; /* master sample rate in rsr */
unsigned int pll_rate; /* current rate of Phase Lock Loop */
- const struct ct_atc_chip_details *chip_details;
- enum CTCARDS model;
+ int chip_type;
+ int model;
+ const char *chip_name;
+ const char *model_name;
struct ct_vm *vm; /* device virtual memory manager for this card */
int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
@@ -147,7 +140,7 @@
int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
- unsigned int rsr, unsigned int msr,
+ unsigned int rsr, unsigned int msr, int chip_type,
struct ct_atc **ratc);
int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
index befead4..082e35c0 100644
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -116,7 +116,7 @@
static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
{
- switch (hw->get_chip_type(hw)) {
+ switch (hw->chip_type) {
case ATC20K1:
switch (type) {
case SPDIFOO: return 0;
@@ -343,7 +343,7 @@
int err;
unsigned int idx_l, idx_r;
- switch (((struct hw *)hw)->get_chip_type(hw)) {
+ switch (((struct hw *)hw)->chip_type) {
case ATC20K1:
idx_l = idx_20k1[desc->type].left;
idx_r = idx_20k1[desc->type].right;
@@ -367,7 +367,7 @@
if (desc->type <= DAIO_OUT_MAX) {
daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops;
} else {
- switch (((struct hw *)hw)->get_chip_type(hw)) {
+ switch (((struct hw *)hw)->chip_type) {
case ATC20K1:
daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1;
break;
diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c
index 5ec6813..8e64f48 100644
--- a/sound/pci/ctxfi/cthardware.c
+++ b/sound/pci/ctxfi/cthardware.c
@@ -20,34 +20,16 @@
#include "cthw20k2.h"
#include <linux/bug.h>
-static enum CHIPTYP __devinitdata get_chip_type(struct hw *hw)
-{
- enum CHIPTYP type;
-
- switch (hw->pci->device) {
- case 0x0005: /* 20k1 device */
- type = ATC20K1;
- break;
- case 0x000B: /* 20k2 device */
- type = ATC20K2;
- break;
- default:
- type = ATCNONE;
- break;
- }
-
- return type;
-}
-
-int __devinit create_hw_obj(struct pci_dev *pci, struct hw **rhw)
+int __devinit create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
+ enum CTCARDS model, struct hw **rhw)
{
int err;
- switch (pci->device) {
- case 0x0005: /* 20k1 device */
+ switch (chip_type) {
+ case ATC20K1:
err = create_20k1_hw_obj(rhw);
break;
- case 0x000B: /* 20k2 device */
+ case ATC20K2:
err = create_20k2_hw_obj(rhw);
break;
default:
@@ -58,7 +40,8 @@
return err;
(*rhw)->pci = pci;
- (*rhw)->get_chip_type = get_chip_type;
+ (*rhw)->chip_type = chip_type;
+ (*rhw)->model = model;
return 0;
}
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index 8f11644..4a8e04f 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -27,6 +27,19 @@
ATCNONE
};
+enum CTCARDS {
+ /* 20k1 models */
+ CTSB055X,
+ CTSB073X,
+ CTUAA,
+ CT20K1_UNKNOWN,
+ /* 20k2 models */
+ CTSB0760,
+ CTHENDRIX,
+ CTSB0880,
+ NUM_CTCARDS /* This should always be the last */
+};
+
/* Type of input source for ADC */
enum ADCSRC{
ADC_MICIN,
@@ -48,7 +61,6 @@
int (*card_init)(struct hw *hw, struct card_conf *info);
int (*card_stop)(struct hw *hw);
int (*pll_init)(struct hw *hw, unsigned int rsr);
- enum CHIPTYP (*get_chip_type)(struct hw *hw);
int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
int (*have_digit_io_switch)(struct hw *hw);
@@ -156,9 +168,13 @@
int irq;
unsigned long io_base;
unsigned long mem_base;
+
+ enum CHIPTYP chip_type;
+ enum CTCARDS model;
};
-int create_hw_obj(struct pci_dev *pci, struct hw **rhw);
+int create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
+ enum CTCARDS model, struct hw **rhw);
int destroy_hw_obj(struct hw *hw);
unsigned int get_field(unsigned int data, unsigned int field);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 38b87b6..5d58650 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1432,11 +1432,9 @@
{
u32 data;
u16 gpioorg;
- u16 subsys_id;
unsigned int ret;
- pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id);
- if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) {
+ if (hw->model == CTSB055X) {
/* SB055x, unmute outputs */
gpioorg = (u16)hw_read_20kx(hw, GPIO);
gpioorg &= 0xffbf; /* set GPIO6 to low */
@@ -1538,19 +1536,14 @@
static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
{
- u16 subsys_id;
-
- pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id);
- if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) {
- /* SB055x cards */
+ switch (hw->model) {
+ case CTSB055X:
return is_adc_input_selected_SB055x(hw, type);
- } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) {
- /* SB073x cards */
+ case CTSB073X:
return is_adc_input_selected_hendrix(hw, type);
- } else if ((subsys_id & 0xf000) == 0x6000) {
- /* Vista compatible cards */
+ case CTHENDRIX:
return is_adc_input_selected_hendrix(hw, type);
- } else {
+ default:
return is_adc_input_selected_SBx(hw, type);
}
}
@@ -1692,20 +1685,17 @@
static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
{
- u16 subsys_id;
+ int state = type == ADC_MICIN;
- pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id);
- if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) {
- /* SB055x cards */
- return adc_input_select_SB055x(hw, type, (ADC_MICIN == type));
- } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) {
- /* SB073x cards */
- return adc_input_select_hendrix(hw, type, (ADC_MICIN == type));
- } else if ((subsys_id & 0xf000) == 0x6000) {
- /* Vista compatible cards */
- return adc_input_select_hendrix(hw, type, (ADC_MICIN == type));
- } else {
- return adc_input_select_SBx(hw, type, (ADC_MICIN == type));
+ switch (hw->model) {
+ case CTSB055X:
+ return adc_input_select_SB055x(hw, type, state);
+ case CTSB073X:
+ return adc_input_select_hendrix(hw, type, state);
+ case CTHENDRIX:
+ return adc_input_select_hendrix(hw, type, state);
+ default:
+ return adc_input_select_SBx(hw, type, state);
}
}
@@ -1781,28 +1771,16 @@
static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
{
- int err;
- u16 subsys_id;
-
- pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id);
- if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) {
- /* Sb055x card */
- err = adc_init_SB055x(hw, info->input, info->mic20db);
- } else {
- err = adc_init_SBx(hw, info->input, info->mic20db);
- }
-
- return err;
+ if (hw->model == CTSB055X)
+ return adc_init_SB055x(hw, info->input, info->mic20db);
+ else
+ return adc_init_SBx(hw, info->input, info->mic20db);
}
static int hw_have_digit_io_switch(struct hw *hw)
{
- u16 subsys_id;
-
- pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id);
/* SB073x and Vista compatible cards have no digit IO switch */
- return !((subsys_id == 0x0029) || (subsys_id == 0x0031)
- || ((subsys_id & 0xf000) == 0x6000));
+ return !(hw->model == CTSB073X || hw->model == CTHENDRIX);
}
#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
@@ -1918,7 +1896,6 @@
{
int err;
struct pci_dev *pci = hw->pci;
- u16 subsys_id;
err = pci_enable_device(pci);
if (err < 0)
@@ -1939,8 +1916,7 @@
goto error1;
/* Switch to X-Fi mode from UAA mode if neeeded */
- pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsys_id);
- if ((0x5 == pci->device) && (0x6000 == (subsys_id & 0x6000))) {
+ if (hw->model == CTHENDRIX) {
err = uaa_to_xfi(pci);
if (err)
goto error2;
@@ -2004,7 +1980,6 @@
{
int err;
unsigned int gctl;
- u16 subsys_id;
u32 data;
struct dac_conf dac_info = {0};
struct adc_conf adc_info = {0};
@@ -2044,19 +2019,20 @@
hw_write_20kx(hw, SRCIP, 0);
mdelay(30);
- pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id);
/* Detect the card ID and configure GPIO accordingly. */
- if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) {
- /* SB055x cards */
+ switch (hw->model) {
+ case CTSB055X:
hw_write_20kx(hw, GPIOCTL, 0x13fe);
- } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) {
- /* SB073x cards */
+ break;
+ case CTSB073X:
hw_write_20kx(hw, GPIOCTL, 0x00e6);
- } else if ((subsys_id & 0xf000) == 0x6000) {
- /* Vista compatible cards */
+ break;
+ case CTHENDRIX: /* Vista compatible cards */
hw_write_20kx(hw, GPIOCTL, 0x00c2);
- } else {
+ break;
+ default:
hw_write_20kx(hw, GPIOCTL, 0x01e6);
+ break;
}
trn_info.vm_pgt_phys = info->vm_pgt_phys;
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 279dac6..2d3dd89 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -15,6 +15,7 @@
#include <sound/core.h>
#include <sound/initval.h>
#include "ctatc.h"
+#include "cthardware.h"
MODULE_AUTHOR("Creative Technology Ltd");
MODULE_DESCRIPTION("X-Fi driver version 1.03");
@@ -41,8 +42,12 @@
static struct pci_device_id ct_pci_dev_ids[] = {
/* only X-Fi is supported, so... */
- { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1) },
- { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1),
+ .driver_data = ATC20K1,
+ },
+ { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2),
+ .driver_data = ATC20K2,
+ },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, ct_pci_dev_ids);
@@ -79,7 +84,8 @@
"1 and 2, Value 2 is assumed.\n");
multiple = 2;
}
- err = ct_atc_create(card, pci, reference_rate, multiple, &atc);
+ err = ct_atc_create(card, pci, reference_rate, multiple,
+ pci_id->driver_data, &atc);
if (err < 0)
goto error;
@@ -92,7 +98,8 @@
strcpy(card->driver, "SB-XFi");
strcpy(card->shortname, "Creative X-Fi");
- strcpy(card->longname, "Creative ALSA Driver X-Fi");
+ snprintf(card->longname, sizeof(card->longname), "%s %s %s",
+ card->shortname, atc->chip_name, atc->model_name);
err = snd_card_register(card);
if (err < 0)