You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'topic/oxygen' into for-linus
This commit is contained in:
+2
-1
@@ -764,7 +764,8 @@ config SND_VIRTUOSO
|
||||
select SND_OXYGEN_LIB
|
||||
help
|
||||
Say Y here to include support for sound cards based on the
|
||||
Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X.
|
||||
Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, and
|
||||
Essence STX.
|
||||
Support for the HDAV1.3 (Deluxe) is very experimental.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
|
||||
@@ -45,6 +45,7 @@ MODULE_PARM_DESC(enable, "enable card");
|
||||
static struct pci_device_id hifier_ids[] __devinitdata = {
|
||||
{ OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
|
||||
{ OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
|
||||
{ OXYGEN_PCI_SUBID_BROKEN_EEPROM },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, hifier_ids);
|
||||
@@ -151,7 +152,6 @@ static const struct oxygen_model model_hifier = {
|
||||
.shortname = "C-Media CMI8787",
|
||||
.longname = "C-Media Oxygen HD Audio",
|
||||
.chip = "CMI8788",
|
||||
.owner = THIS_MODULE,
|
||||
.init = hifier_init,
|
||||
.control_filter = hifier_control_filter,
|
||||
.cleanup = hifier_cleanup,
|
||||
@@ -173,6 +173,13 @@ static const struct oxygen_model model_hifier = {
|
||||
.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
|
||||
};
|
||||
|
||||
static int __devinit get_hifier_model(struct oxygen *chip,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
chip->model = model_hifier;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit hifier_probe(struct pci_dev *pci,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
@@ -185,7 +192,8 @@ static int __devinit hifier_probe(struct pci_dev *pci,
|
||||
++dev;
|
||||
return -ENOENT;
|
||||
}
|
||||
err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier, 0);
|
||||
err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
|
||||
hifier_ids, get_hifier_model);
|
||||
if (err >= 0)
|
||||
++dev;
|
||||
return err;
|
||||
|
||||
+88
-26
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* C-Media CMI8788 driver for C-Media's reference design and for the X-Meridian
|
||||
* C-Media CMI8788 driver for C-Media's reference design and similar models
|
||||
*
|
||||
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
|
||||
*
|
||||
@@ -26,6 +26,7 @@
|
||||
*
|
||||
* GPIO 0 -> DFS0 of AK5385
|
||||
* GPIO 1 -> DFS1 of AK5385
|
||||
* GPIO 8 -> enable headphone amplifier on HT-Omega models
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
@@ -61,7 +62,8 @@ MODULE_PARM_DESC(enable, "enable card");
|
||||
enum {
|
||||
MODEL_CMEDIA_REF, /* C-Media's reference design */
|
||||
MODEL_MERIDIAN, /* AuzenTech X-Meridian */
|
||||
MODEL_HALO, /* HT-Omega Claro halo */
|
||||
MODEL_CLARO, /* HT-Omega Claro */
|
||||
MODEL_CLARO_HALO, /* HT-Omega Claro halo */
|
||||
};
|
||||
|
||||
static struct pci_device_id oxygen_ids[] __devinitdata = {
|
||||
@@ -74,8 +76,8 @@ static struct pci_device_id oxygen_ids[] __devinitdata = {
|
||||
{ OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
|
||||
{ OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
|
||||
{ OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
|
||||
{ OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF },
|
||||
{ OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_HALO },
|
||||
{ OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
|
||||
{ OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, oxygen_ids);
|
||||
@@ -86,6 +88,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
|
||||
#define GPIO_AK5385_DFS_DOUBLE 0x0001
|
||||
#define GPIO_AK5385_DFS_QUAD 0x0002
|
||||
|
||||
#define GPIO_CLARO_HP 0x0100
|
||||
|
||||
struct generic_data {
|
||||
u8 ak4396_ctl2;
|
||||
u16 saved_wm8785_registers[2];
|
||||
@@ -196,10 +200,46 @@ static void meridian_init(struct oxygen *chip)
|
||||
ak5385_init(chip);
|
||||
}
|
||||
|
||||
static void claro_enable_hp(struct oxygen *chip)
|
||||
{
|
||||
msleep(300);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_HP);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP);
|
||||
}
|
||||
|
||||
static void claro_init(struct oxygen *chip)
|
||||
{
|
||||
ak4396_init(chip);
|
||||
wm8785_init(chip);
|
||||
claro_enable_hp(chip);
|
||||
}
|
||||
|
||||
static void claro_halo_init(struct oxygen *chip)
|
||||
{
|
||||
ak4396_init(chip);
|
||||
ak5385_init(chip);
|
||||
claro_enable_hp(chip);
|
||||
}
|
||||
|
||||
static void generic_cleanup(struct oxygen *chip)
|
||||
{
|
||||
}
|
||||
|
||||
static void claro_disable_hp(struct oxygen *chip)
|
||||
{
|
||||
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP);
|
||||
}
|
||||
|
||||
static void claro_cleanup(struct oxygen *chip)
|
||||
{
|
||||
claro_disable_hp(chip);
|
||||
}
|
||||
|
||||
static void claro_suspend(struct oxygen *chip)
|
||||
{
|
||||
claro_disable_hp(chip);
|
||||
}
|
||||
|
||||
static void generic_resume(struct oxygen *chip)
|
||||
{
|
||||
ak4396_registers_init(chip);
|
||||
@@ -211,6 +251,12 @@ static void meridian_resume(struct oxygen *chip)
|
||||
ak4396_registers_init(chip);
|
||||
}
|
||||
|
||||
static void claro_resume(struct oxygen *chip)
|
||||
{
|
||||
ak4396_registers_init(chip);
|
||||
claro_enable_hp(chip);
|
||||
}
|
||||
|
||||
static void set_ak4396_params(struct oxygen *chip,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
@@ -293,30 +339,10 @@ static void set_ak5385_params(struct oxygen *chip,
|
||||
|
||||
static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
|
||||
|
||||
static int generic_probe(struct oxygen *chip, unsigned long driver_data)
|
||||
{
|
||||
if (driver_data == MODEL_MERIDIAN) {
|
||||
chip->model.init = meridian_init;
|
||||
chip->model.resume = meridian_resume;
|
||||
chip->model.set_adc_params = set_ak5385_params;
|
||||
chip->model.device_config = PLAYBACK_0_TO_I2S |
|
||||
PLAYBACK_1_TO_SPDIF |
|
||||
CAPTURE_0_FROM_I2S_2 |
|
||||
CAPTURE_1_FROM_SPDIF;
|
||||
}
|
||||
if (driver_data == MODEL_MERIDIAN || driver_data == MODEL_HALO) {
|
||||
chip->model.misc_flags = OXYGEN_MISC_MIDI;
|
||||
chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct oxygen_model model_generic = {
|
||||
.shortname = "C-Media CMI8788",
|
||||
.longname = "C-Media Oxygen HD Audio",
|
||||
.chip = "CMI8788",
|
||||
.owner = THIS_MODULE,
|
||||
.probe = generic_probe,
|
||||
.init = generic_init,
|
||||
.cleanup = generic_cleanup,
|
||||
.resume = generic_resume,
|
||||
@@ -341,6 +367,42 @@ static const struct oxygen_model model_generic = {
|
||||
.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
|
||||
};
|
||||
|
||||
static int __devinit get_oxygen_model(struct oxygen *chip,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
chip->model = model_generic;
|
||||
switch (id->driver_data) {
|
||||
case MODEL_MERIDIAN:
|
||||
chip->model.init = meridian_init;
|
||||
chip->model.resume = meridian_resume;
|
||||
chip->model.set_adc_params = set_ak5385_params;
|
||||
chip->model.device_config = PLAYBACK_0_TO_I2S |
|
||||
PLAYBACK_1_TO_SPDIF |
|
||||
CAPTURE_0_FROM_I2S_2 |
|
||||
CAPTURE_1_FROM_SPDIF;
|
||||
break;
|
||||
case MODEL_CLARO:
|
||||
chip->model.init = claro_init;
|
||||
chip->model.cleanup = claro_cleanup;
|
||||
chip->model.suspend = claro_suspend;
|
||||
chip->model.resume = claro_resume;
|
||||
break;
|
||||
case MODEL_CLARO_HALO:
|
||||
chip->model.init = claro_halo_init;
|
||||
chip->model.cleanup = claro_cleanup;
|
||||
chip->model.suspend = claro_suspend;
|
||||
chip->model.resume = claro_resume;
|
||||
chip->model.set_adc_params = set_ak5385_params;
|
||||
break;
|
||||
}
|
||||
if (id->driver_data == MODEL_MERIDIAN ||
|
||||
id->driver_data == MODEL_CLARO_HALO) {
|
||||
chip->model.misc_flags = OXYGEN_MISC_MIDI;
|
||||
chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit generic_oxygen_probe(struct pci_dev *pci,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
@@ -353,8 +415,8 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
|
||||
++dev;
|
||||
return -ENOENT;
|
||||
}
|
||||
err = oxygen_pci_probe(pci, index[dev], id[dev],
|
||||
&model_generic, pci_id->driver_data);
|
||||
err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
|
||||
oxygen_ids, get_oxygen_model);
|
||||
if (err >= 0)
|
||||
++dev;
|
||||
return err;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#define OXYGEN_IO_SIZE 0x100
|
||||
|
||||
#define OXYGEN_EEPROM_ID 0x434d /* "CM" */
|
||||
|
||||
/* model-specific configuration of outputs/inputs */
|
||||
#define PLAYBACK_0_TO_I2S 0x0001
|
||||
/* PLAYBACK_0_TO_AC97_0 not implemented */
|
||||
@@ -49,7 +51,13 @@ enum {
|
||||
.subvendor = sv, \
|
||||
.subdevice = sd
|
||||
|
||||
#define BROKEN_EEPROM_DRIVER_DATA ((unsigned long)-1)
|
||||
#define OXYGEN_PCI_SUBID_BROKEN_EEPROM \
|
||||
OXYGEN_PCI_SUBID(PCI_VENDOR_ID_CMEDIA, 0x8788), \
|
||||
.driver_data = BROKEN_EEPROM_DRIVER_DATA
|
||||
|
||||
struct pci_dev;
|
||||
struct pci_device_id;
|
||||
struct snd_card;
|
||||
struct snd_pcm_substream;
|
||||
struct snd_pcm_hardware;
|
||||
@@ -62,8 +70,6 @@ struct oxygen_model {
|
||||
const char *shortname;
|
||||
const char *longname;
|
||||
const char *chip;
|
||||
struct module *owner;
|
||||
int (*probe)(struct oxygen *chip, unsigned long driver_data);
|
||||
void (*init)(struct oxygen *chip);
|
||||
int (*control_filter)(struct snd_kcontrol_new *template);
|
||||
int (*mixer_init)(struct oxygen *chip);
|
||||
@@ -83,6 +89,7 @@ struct oxygen_model {
|
||||
void (*ac97_switch)(struct oxygen *chip,
|
||||
unsigned int reg, unsigned int mute);
|
||||
const unsigned int *dac_tlv;
|
||||
unsigned long private_data;
|
||||
size_t model_data_size;
|
||||
unsigned int device_config;
|
||||
u8 dac_channels;
|
||||
@@ -134,8 +141,12 @@ struct oxygen {
|
||||
/* oxygen_lib.c */
|
||||
|
||||
int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
|
||||
const struct oxygen_model *model,
|
||||
unsigned long driver_data);
|
||||
struct module *owner,
|
||||
const struct pci_device_id *ids,
|
||||
int (*get_model)(struct oxygen *chip,
|
||||
const struct pci_device_id *id
|
||||
)
|
||||
);
|
||||
void oxygen_pci_remove(struct pci_dev *pci);
|
||||
#ifdef CONFIG_PM
|
||||
int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
|
||||
@@ -180,6 +191,9 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
|
||||
void oxygen_reset_uart(struct oxygen *chip);
|
||||
void oxygen_write_uart(struct oxygen *chip, u8 data);
|
||||
|
||||
u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index);
|
||||
void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value);
|
||||
|
||||
static inline void oxygen_set_bits8(struct oxygen *chip,
|
||||
unsigned int reg, u8 value)
|
||||
{
|
||||
|
||||
@@ -254,3 +254,34 @@ void oxygen_write_uart(struct oxygen *chip, u8 data)
|
||||
_write_uart(chip, 0, data);
|
||||
}
|
||||
EXPORT_SYMBOL(oxygen_write_uart);
|
||||
|
||||
u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index)
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,
|
||||
index | OXYGEN_EEPROM_DIR_READ);
|
||||
for (timeout = 0; timeout < 100; ++timeout) {
|
||||
udelay(1);
|
||||
if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)
|
||||
& OXYGEN_EEPROM_BUSY))
|
||||
break;
|
||||
}
|
||||
return oxygen_read16(chip, OXYGEN_EEPROM_DATA);
|
||||
}
|
||||
|
||||
void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value)
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
oxygen_write16(chip, OXYGEN_EEPROM_DATA, value);
|
||||
oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,
|
||||
index | OXYGEN_EEPROM_DIR_WRITE);
|
||||
for (timeout = 0; timeout < 10; ++timeout) {
|
||||
msleep(1);
|
||||
if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)
|
||||
& OXYGEN_EEPROM_BUSY))
|
||||
return;
|
||||
}
|
||||
snd_printk(KERN_ERR "EEPROM write timeout\n");
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
|
||||
MODULE_DESCRIPTION("C-Media CMI8788 helper library");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
#define DRIVER "oxygen"
|
||||
|
||||
static inline int oxygen_uart_input_ready(struct oxygen *chip)
|
||||
{
|
||||
@@ -243,6 +244,62 @@ static void oxygen_proc_init(struct oxygen *chip)
|
||||
#define oxygen_proc_init(chip)
|
||||
#endif
|
||||
|
||||
static const struct pci_device_id *
|
||||
oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
|
||||
{
|
||||
u16 subdevice;
|
||||
|
||||
/*
|
||||
* Make sure the EEPROM pins are available, i.e., not used for SPI.
|
||||
* (This function is called before we initialize or use SPI.)
|
||||
*/
|
||||
oxygen_clear_bits8(chip, OXYGEN_FUNCTION,
|
||||
OXYGEN_FUNCTION_ENABLE_SPI_4_5);
|
||||
/*
|
||||
* Read the subsystem device ID directly from the EEPROM, because the
|
||||
* chip didn't if the first EEPROM word was overwritten.
|
||||
*/
|
||||
subdevice = oxygen_read_eeprom(chip, 2);
|
||||
/*
|
||||
* We use only the subsystem device ID for searching because it is
|
||||
* unique even without the subsystem vendor ID, which may have been
|
||||
* overwritten in the EEPROM.
|
||||
*/
|
||||
for (; ids->vendor; ++ids)
|
||||
if (ids->subdevice == subdevice &&
|
||||
ids->driver_data != BROKEN_EEPROM_DRIVER_DATA)
|
||||
return ids;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void oxygen_restore_eeprom(struct oxygen *chip,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
if (oxygen_read_eeprom(chip, 0) != OXYGEN_EEPROM_ID) {
|
||||
/*
|
||||
* This function gets called only when a known card model has
|
||||
* been detected, i.e., we know there is a valid subsystem
|
||||
* product ID at index 2 in the EEPROM. Therefore, we have
|
||||
* been able to deduce the correct subsystem vendor ID, and
|
||||
* this is enough information to restore the original EEPROM
|
||||
* contents.
|
||||
*/
|
||||
oxygen_write_eeprom(chip, 1, id->subvendor);
|
||||
oxygen_write_eeprom(chip, 0, OXYGEN_EEPROM_ID);
|
||||
|
||||
oxygen_set_bits8(chip, OXYGEN_MISC,
|
||||
OXYGEN_MISC_WRITE_PCI_SUBID);
|
||||
pci_write_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
id->subvendor);
|
||||
pci_write_config_word(chip->pci, PCI_SUBSYSTEM_ID,
|
||||
id->subdevice);
|
||||
oxygen_clear_bits8(chip, OXYGEN_MISC,
|
||||
OXYGEN_MISC_WRITE_PCI_SUBID);
|
||||
|
||||
snd_printk(KERN_INFO "EEPROM ID restored\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void oxygen_init(struct oxygen *chip)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -446,21 +503,26 @@ static void oxygen_card_free(struct snd_card *card)
|
||||
free_irq(chip->irq, chip);
|
||||
flush_scheduled_work();
|
||||
chip->model.cleanup(chip);
|
||||
kfree(chip->model_data);
|
||||
mutex_destroy(&chip->mutex);
|
||||
pci_release_regions(chip->pci);
|
||||
pci_disable_device(chip->pci);
|
||||
}
|
||||
|
||||
int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
|
||||
const struct oxygen_model *model,
|
||||
unsigned long driver_data)
|
||||
struct module *owner,
|
||||
const struct pci_device_id *ids,
|
||||
int (*get_model)(struct oxygen *chip,
|
||||
const struct pci_device_id *id
|
||||
)
|
||||
)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct oxygen *chip;
|
||||
const struct pci_device_id *pci_id;
|
||||
int err;
|
||||
|
||||
err = snd_card_create(index, id, model->owner,
|
||||
sizeof(*chip) + model->model_data_size, &card);
|
||||
err = snd_card_create(index, id, owner, sizeof(*chip), &card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@@ -468,8 +530,6 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
|
||||
chip->card = card;
|
||||
chip->pci = pci;
|
||||
chip->irq = -1;
|
||||
chip->model = *model;
|
||||
chip->model_data = chip + 1;
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
mutex_init(&chip->mutex);
|
||||
INIT_WORK(&chip->spdif_input_bits_work,
|
||||
@@ -481,7 +541,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
|
||||
if (err < 0)
|
||||
goto err_card;
|
||||
|
||||
err = pci_request_regions(pci, model->chip);
|
||||
err = pci_request_regions(pci, DRIVER);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "cannot reserve PCI resources\n");
|
||||
goto err_pci_enable;
|
||||
@@ -495,20 +555,34 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
|
||||
}
|
||||
chip->addr = pci_resource_start(pci, 0);
|
||||
|
||||
pci_id = oxygen_search_pci_id(chip, ids);
|
||||
if (!pci_id) {
|
||||
err = -ENODEV;
|
||||
goto err_pci_regions;
|
||||
}
|
||||
oxygen_restore_eeprom(chip, pci_id);
|
||||
err = get_model(chip, pci_id);
|
||||
if (err < 0)
|
||||
goto err_pci_regions;
|
||||
|
||||
if (chip->model.model_data_size) {
|
||||
chip->model_data = kzalloc(chip->model.model_data_size,
|
||||
GFP_KERNEL);
|
||||
if (!chip->model_data) {
|
||||
err = -ENOMEM;
|
||||
goto err_pci_regions;
|
||||
}
|
||||
}
|
||||
|
||||
pci_set_master(pci);
|
||||
snd_card_set_dev(card, &pci->dev);
|
||||
card->private_free = oxygen_card_free;
|
||||
|
||||
if (chip->model.probe) {
|
||||
err = chip->model.probe(chip, driver_data);
|
||||
if (err < 0)
|
||||
goto err_card;
|
||||
}
|
||||
oxygen_init(chip);
|
||||
chip->model.init(chip);
|
||||
|
||||
err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
|
||||
chip->model.chip, chip);
|
||||
DRIVER, chip);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
|
||||
goto err_card;
|
||||
|
||||
+270
-69
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user