Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
b54fc8dd
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b54fc8dd
编写于
3月 24, 2009
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/oxygen' into for-linus
上级
9fb5430c
873591db
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
507 addition
and
116 deletion
+507
-116
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/ALSA-Configuration.txt
+1
-1
sound/pci/Kconfig
sound/pci/Kconfig
+2
-1
sound/pci/oxygen/hifier.c
sound/pci/oxygen/hifier.c
+10
-2
sound/pci/oxygen/oxygen.c
sound/pci/oxygen/oxygen.c
+88
-26
sound/pci/oxygen/oxygen.h
sound/pci/oxygen/oxygen.h
+18
-4
sound/pci/oxygen/oxygen_io.c
sound/pci/oxygen/oxygen_io.c
+31
-0
sound/pci/oxygen/oxygen_lib.c
sound/pci/oxygen/oxygen_lib.c
+87
-13
sound/pci/oxygen/virtuoso.c
sound/pci/oxygen/virtuoso.c
+270
-69
未找到文件。
Documentation/sound/alsa/ALSA-Configuration.txt
浏览文件 @
b54fc8dd
...
...
@@ -1859,7 +1859,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
-------------------
Module for sound cards based on the Asus AV100/AV200 chips,
i.e., Xonar D1, DX, D2, D2X
and HDAV1.3 (Deluxe)
.
i.e., Xonar D1, DX, D2, D2X
, HDAV1.3 (Deluxe), and Essence STX
.
This module supports autoprobe and multiple cards.
...
...
sound/pci/Kconfig
浏览文件 @
b54fc8dd
...
...
@@ -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
...
...
sound/pci/oxygen/hifier.c
浏览文件 @
b54fc8dd
...
...
@@ -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
;
...
...
sound/pci/oxygen/oxygen.c
浏览文件 @
b54fc8dd
/*
* 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_C
MEDIA_REF
},
{
OXYGEN_PCI_SUBID
(
0x7284
,
0x9781
),
.
driver_data
=
MODEL_HALO
},
{
OXYGEN_PCI_SUBID
(
0x7284
,
0x9761
),
.
driver_data
=
MODEL_C
LARO
},
{
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
;
...
...
sound/pci/oxygen/oxygen.h
浏览文件 @
b54fc8dd
...
...
@@ -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
)
{
...
...
sound/pci/oxygen/oxygen_io.c
浏览文件 @
b54fc8dd
...
...
@@ -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
"
);
}
sound/pci/oxygen/oxygen_lib.c
浏览文件 @
b54fc8dd
...
...
@@ -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
;
...
...
sound/pci/oxygen/virtuoso.c
浏览文件 @
b54fc8dd
...
...
@@ -112,6 +112,34 @@
* CS4362A: AD0 <- 0
*/
/*
* Xonar Essence STX
* -----------------
*
* CMI8788:
*
* I²C <-> PCM1792A
*
* GPI 0 <- external power present
*
* GPIO 0 -> enable output to speakers
* GPIO 1 -> route HP to front panel (0) or rear jack (1)
* GPIO 2 -> M0 of CS5381
* GPIO 3 -> M1 of CS5381
* GPIO 7 -> route output to speaker jacks (0) or HP (1)
* GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
* PCM1792A:
*
* AD0 <- 0
*
* H6 daughterboard
* ----------------
*
* GPIO 4 <- 0
* GPIO 5 <- 0
*/
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mutex.h>
...
...
@@ -152,6 +180,7 @@ enum {
MODEL_DX
,
MODEL_HDAV
,
/* without daughterboard */
MODEL_HDAV_H6
,
/* with H6 daughterboard */
MODEL_STX
,
};
static
struct
pci_device_id
xonar_ids
[]
__devinitdata
=
{
...
...
@@ -160,6 +189,8 @@ static struct pci_device_id xonar_ids[] __devinitdata = {
{
OXYGEN_PCI_SUBID
(
0x1043
,
0x82b7
),
.
driver_data
=
MODEL_D2X
},
{
OXYGEN_PCI_SUBID
(
0x1043
,
0x8314
),
.
driver_data
=
MODEL_HDAV
},
{
OXYGEN_PCI_SUBID
(
0x1043
,
0x834f
),
.
driver_data
=
MODEL_D1
},
{
OXYGEN_PCI_SUBID
(
0x1043
,
0x835c
),
.
driver_data
=
MODEL_STX
},
{
OXYGEN_PCI_SUBID_BROKEN_EEPROM
},
{
}
};
MODULE_DEVICE_TABLE
(
pci
,
xonar_ids
);
...
...
@@ -183,12 +214,14 @@ MODULE_DEVICE_TABLE(pci, xonar_ids);
#define GPIO_HDAV_DB_H6 0x0000
#define GPIO_HDAV_DB_XX 0x0020
#define GPIO_ST_HP_REAR 0x0002
#define GPIO_ST_HP 0x0080
#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1))
/* 10011, ADx=i, /W=0 */
#define I2C_DEVICE_CS4398 0x9e
/* 10011, AD1=1, AD0=1, /W=0 */
#define I2C_DEVICE_CS4362A 0x30
/* 001100, AD0=0, /W=0 */
struct
xonar_data
{
unsigned
int
model
;
unsigned
int
anti_pop_delay
;
unsigned
int
dacs
;
u16
output_enable_bit
;
...
...
@@ -334,15 +367,9 @@ static void xonar_d2_init(struct oxygen *chip)
struct
xonar_data
*
data
=
chip
->
model_data
;
data
->
anti_pop_delay
=
300
;
data
->
dacs
=
4
;
data
->
output_enable_bit
=
GPIO_D2_OUTPUT_ENABLE
;
data
->
pcm1796_oversampling
=
PCM1796_OS_64
;
if
(
data
->
model
==
MODEL_D2X
)
{
data
->
ext_power_reg
=
OXYGEN_GPIO_DATA
;
data
->
ext_power_int_reg
=
OXYGEN_GPIO_INTERRUPT_MASK
;
data
->
ext_power_bit
=
GPIO_D2X_EXT_POWER
;
oxygen_clear_bits16
(
chip
,
OXYGEN_GPIO_CONTROL
,
GPIO_D2X_EXT_POWER
);
}
pcm1796_init
(
chip
);
...
...
@@ -355,6 +382,18 @@ static void xonar_d2_init(struct oxygen *chip)
snd_component_add
(
chip
->
card
,
"CS5381"
);
}
static
void
xonar_d2x_init
(
struct
oxygen
*
chip
)
{
struct
xonar_data
*
data
=
chip
->
model_data
;
data
->
ext_power_reg
=
OXYGEN_GPIO_DATA
;
data
->
ext_power_int_reg
=
OXYGEN_GPIO_INTERRUPT_MASK
;
data
->
ext_power_bit
=
GPIO_D2X_EXT_POWER
;
oxygen_clear_bits16
(
chip
,
OXYGEN_GPIO_CONTROL
,
GPIO_D2X_EXT_POWER
);
xonar_d2_init
(
chip
);
}
static
void
update_cs4362a_volumes
(
struct
oxygen
*
chip
)
{
u8
mute
;
...
...
@@ -422,11 +461,6 @@ static void xonar_d1_init(struct oxygen *chip)
data
->
cs4398_fm
=
CS4398_FM_SINGLE
|
CS4398_DEM_NONE
|
CS4398_DIF_LJUST
;
data
->
cs4362a_fm
=
CS4362A_FM_SINGLE
|
CS4362A_ATAPI_B_R
|
CS4362A_ATAPI_A_L
;
if
(
data
->
model
==
MODEL_DX
)
{
data
->
ext_power_reg
=
OXYGEN_GPI_DATA
;
data
->
ext_power_int_reg
=
OXYGEN_GPI_INTERRUPT_MASK
;
data
->
ext_power_bit
=
GPI_DX_EXT_POWER
;
}
oxygen_write16
(
chip
,
OXYGEN_2WIRE_BUS_STATUS
,
OXYGEN_2WIRE_LENGTH_8
|
...
...
@@ -447,6 +481,17 @@ static void xonar_d1_init(struct oxygen *chip)
snd_component_add
(
chip
->
card
,
"CS5361"
);
}
static
void
xonar_dx_init
(
struct
oxygen
*
chip
)
{
struct
xonar_data
*
data
=
chip
->
model_data
;
data
->
ext_power_reg
=
OXYGEN_GPI_DATA
;
data
->
ext_power_int_reg
=
OXYGEN_GPI_INTERRUPT_MASK
;
data
->
ext_power_bit
=
GPI_DX_EXT_POWER
;
xonar_d1_init
(
chip
);
}
static
void
xonar_hdav_init
(
struct
oxygen
*
chip
)
{
struct
xonar_data
*
data
=
chip
->
model_data
;
...
...
@@ -458,6 +503,7 @@ static void xonar_hdav_init(struct oxygen *chip)
OXYGEN_2WIRE_SPEED_FAST
);
data
->
anti_pop_delay
=
100
;
data
->
dacs
=
chip
->
model
.
private_data
==
MODEL_HDAV_H6
?
4
:
1
;
data
->
output_enable_bit
=
GPIO_DX_OUTPUT_ENABLE
;
data
->
ext_power_reg
=
OXYGEN_GPI_DATA
;
data
->
ext_power_int_reg
=
OXYGEN_GPI_INTERRUPT_MASK
;
...
...
@@ -484,6 +530,36 @@ static void xonar_hdav_init(struct oxygen *chip)
snd_component_add
(
chip
->
card
,
"CS5381"
);
}
static
void
xonar_stx_init
(
struct
oxygen
*
chip
)
{
struct
xonar_data
*
data
=
chip
->
model_data
;
oxygen_write16
(
chip
,
OXYGEN_2WIRE_BUS_STATUS
,
OXYGEN_2WIRE_LENGTH_8
|
OXYGEN_2WIRE_INTERRUPT_MASK
|
OXYGEN_2WIRE_SPEED_FAST
);
data
->
anti_pop_delay
=
100
;
data
->
dacs
=
1
;
data
->
output_enable_bit
=
GPIO_DX_OUTPUT_ENABLE
;
data
->
ext_power_reg
=
OXYGEN_GPI_DATA
;
data
->
ext_power_int_reg
=
OXYGEN_GPI_INTERRUPT_MASK
;
data
->
ext_power_bit
=
GPI_DX_EXT_POWER
;
data
->
pcm1796_oversampling
=
PCM1796_OS_64
;
pcm1796_init
(
chip
);
oxygen_set_bits16
(
chip
,
OXYGEN_GPIO_CONTROL
,
GPIO_DX_INPUT_ROUTE
|
GPIO_ST_HP_REAR
|
GPIO_ST_HP
);
oxygen_clear_bits16
(
chip
,
OXYGEN_GPIO_DATA
,
GPIO_DX_INPUT_ROUTE
|
GPIO_ST_HP_REAR
|
GPIO_ST_HP
);
xonar_common_init
(
chip
);
snd_component_add
(
chip
->
card
,
"PCM1792A"
);
snd_component_add
(
chip
->
card
,
"CS5381"
);
}
static
void
xonar_disable_output
(
struct
oxygen
*
chip
)
{
struct
xonar_data
*
data
=
chip
->
model_data
;
...
...
@@ -511,6 +587,11 @@ static void xonar_hdav_cleanup(struct oxygen *chip)
xonar_disable_output
(
chip
);
}
static
void
xonar_st_cleanup
(
struct
oxygen
*
chip
)
{
xonar_disable_output
(
chip
);
}
static
void
xonar_d2_suspend
(
struct
oxygen
*
chip
)
{
xonar_d2_cleanup
(
chip
);
...
...
@@ -527,6 +608,11 @@ static void xonar_hdav_suspend(struct oxygen *chip)
msleep
(
2
);
}
static
void
xonar_st_suspend
(
struct
oxygen
*
chip
)
{
xonar_st_cleanup
(
chip
);
}
static
void
xonar_d2_resume
(
struct
oxygen
*
chip
)
{
pcm1796_init
(
chip
);
...
...
@@ -554,6 +640,12 @@ static void xonar_hdav_resume(struct oxygen *chip)
xonar_enable_output
(
chip
);
}
static
void
xonar_st_resume
(
struct
oxygen
*
chip
)
{
pcm1796_init
(
chip
);
xonar_enable_output
(
chip
);
}
static
void
xonar_hdav_pcm_hardware_filter
(
unsigned
int
channel
,
struct
snd_pcm_hardware
*
hardware
)
{
...
...
@@ -733,6 +825,72 @@ static const struct snd_kcontrol_new front_panel_switch = {
.
private_value
=
GPIO_DX_FRONT_PANEL
,
};
static
int
st_output_switch_info
(
struct
snd_kcontrol
*
ctl
,
struct
snd_ctl_elem_info
*
info
)
{
static
const
char
*
const
names
[
3
]
=
{
"Speakers"
,
"Headphones"
,
"FP Headphones"
};
info
->
type
=
SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
info
->
count
=
1
;
info
->
value
.
enumerated
.
items
=
3
;
if
(
info
->
value
.
enumerated
.
item
>=
3
)
info
->
value
.
enumerated
.
item
=
2
;
strcpy
(
info
->
value
.
enumerated
.
name
,
names
[
info
->
value
.
enumerated
.
item
]);
return
0
;
}
static
int
st_output_switch_get
(
struct
snd_kcontrol
*
ctl
,
struct
snd_ctl_elem_value
*
value
)
{
struct
oxygen
*
chip
=
ctl
->
private_data
;
u16
gpio
;
gpio
=
oxygen_read16
(
chip
,
OXYGEN_GPIO_DATA
);
if
(
!
(
gpio
&
GPIO_ST_HP
))
value
->
value
.
enumerated
.
item
[
0
]
=
0
;
else
if
(
gpio
&
GPIO_ST_HP_REAR
)
value
->
value
.
enumerated
.
item
[
0
]
=
1
;
else
value
->
value
.
enumerated
.
item
[
0
]
=
2
;
return
0
;
}
static
int
st_output_switch_put
(
struct
snd_kcontrol
*
ctl
,
struct
snd_ctl_elem_value
*
value
)
{
struct
oxygen
*
chip
=
ctl
->
private_data
;
u16
gpio_old
,
gpio
;
mutex_lock
(
&
chip
->
mutex
);
gpio_old
=
oxygen_read16
(
chip
,
OXYGEN_GPIO_DATA
);
gpio
=
gpio_old
;
switch
(
value
->
value
.
enumerated
.
item
[
0
])
{
case
0
:
gpio
&=
~
(
GPIO_ST_HP
|
GPIO_ST_HP_REAR
);
break
;
case
1
:
gpio
|=
GPIO_ST_HP
|
GPIO_ST_HP_REAR
;
break
;
case
2
:
gpio
=
(
gpio
|
GPIO_ST_HP
)
&
~
GPIO_ST_HP_REAR
;
break
;
}
oxygen_write16
(
chip
,
OXYGEN_GPIO_DATA
,
gpio
);
mutex_unlock
(
&
chip
->
mutex
);
return
gpio
!=
gpio_old
;
}
static
const
struct
snd_kcontrol_new
st_output_switch
=
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"Analog Output"
,
.
info
=
st_output_switch_info
,
.
get
=
st_output_switch_get
,
.
put
=
st_output_switch_put
,
};
static
void
xonar_line_mic_ac97_switch
(
struct
oxygen
*
chip
,
unsigned
int
reg
,
unsigned
int
mute
)
{
...
...
@@ -745,8 +903,8 @@ static void xonar_line_mic_ac97_switch(struct oxygen *chip,
}
}
static
const
DECLARE_TLV_DB_SCALE
(
pcm1796_db_scale
,
-
12
000
,
50
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
cs4362a_db_scale
,
-
127
00
,
100
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
pcm1796_db_scale
,
-
6
000
,
50
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
cs4362a_db_scale
,
-
60
00
,
100
,
0
);
static
int
xonar_d2_control_filter
(
struct
snd_kcontrol_new
*
template
)
{
...
...
@@ -763,6 +921,15 @@ static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
return
0
;
}
static
int
xonar_st_control_filter
(
struct
snd_kcontrol_new
*
template
)
{
if
(
!
strncmp
(
template
->
name
,
"CD Capture "
,
11
))
return
1
;
/* no CD input */
if
(
!
strcmp
(
template
->
name
,
"Stereo Upmixing"
))
return
1
;
/* stereo only - we don't need upmixing */
return
0
;
}
static
int
xonar_d2_mixer_init
(
struct
oxygen
*
chip
)
{
return
snd_ctl_add
(
chip
->
card
,
snd_ctl_new1
(
&
alt_switch
,
chip
));
...
...
@@ -773,51 +940,14 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
return
snd_ctl_add
(
chip
->
card
,
snd_ctl_new1
(
&
front_panel_switch
,
chip
));
}
static
int
xonar_
model_probe
(
struct
oxygen
*
chip
,
unsigned
long
driver_data
)
static
int
xonar_
st_mixer_init
(
struct
oxygen
*
chip
)
{
static
const
char
*
const
names
[]
=
{
[
MODEL_D1
]
=
"Xonar D1"
,
[
MODEL_DX
]
=
"Xonar DX"
,
[
MODEL_D2
]
=
"Xonar D2"
,
[
MODEL_D2X
]
=
"Xonar D2X"
,
[
MODEL_HDAV
]
=
"Xonar HDAV1.3"
,
[
MODEL_HDAV_H6
]
=
"Xonar HDAV1.3+H6"
,
};
static
const
u8
dacs
[]
=
{
[
MODEL_D1
]
=
2
,
[
MODEL_DX
]
=
2
,
[
MODEL_D2
]
=
4
,
[
MODEL_D2X
]
=
4
,
[
MODEL_HDAV
]
=
1
,
[
MODEL_HDAV_H6
]
=
4
,
};
struct
xonar_data
*
data
=
chip
->
model_data
;
data
->
model
=
driver_data
;
if
(
data
->
model
==
MODEL_HDAV
)
{
oxygen_clear_bits16
(
chip
,
OXYGEN_GPIO_CONTROL
,
GPIO_HDAV_DB_MASK
);
switch
(
oxygen_read16
(
chip
,
OXYGEN_GPIO_DATA
)
&
GPIO_HDAV_DB_MASK
)
{
case
GPIO_HDAV_DB_H6
:
data
->
model
=
MODEL_HDAV_H6
;
break
;
case
GPIO_HDAV_DB_XX
:
snd_printk
(
KERN_ERR
"unknown daughterboard
\n
"
);
return
-
ENODEV
;
}
}
data
->
dacs
=
dacs
[
data
->
model
];
chip
->
model
.
shortname
=
names
[
data
->
model
];
return
0
;
return
snd_ctl_add
(
chip
->
card
,
snd_ctl_new1
(
&
st_output_switch
,
chip
));
}
static
const
struct
oxygen_model
model_xonar_d2
=
{
.
longname
=
"Asus Virtuoso 200"
,
.
chip
=
"AV200"
,
.
owner
=
THIS_MODULE
,
.
probe
=
xonar_model_probe
,
.
init
=
xonar_d2_init
,
.
control_filter
=
xonar_d2_control_filter
,
.
mixer_init
=
xonar_d2_mixer_init
,
...
...
@@ -837,8 +967,8 @@ static const struct oxygen_model model_xonar_d2 = {
MIDI_OUTPUT
|
MIDI_INPUT
,
.
dac_channels
=
8
,
.
dac_volume_min
=
0x0f
,
.
dac_volume_max
=
0xff
,
.
dac_volume_min
=
255
-
2
*
60
,
.
dac_volume_max
=
255
,
.
misc_flags
=
OXYGEN_MISC_MIDI
,
.
function_flags
=
OXYGEN_FUNCTION_SPI
|
OXYGEN_FUNCTION_ENABLE_SPI_4_5
,
...
...
@@ -849,8 +979,6 @@ static const struct oxygen_model model_xonar_d2 = {
static
const
struct
oxygen_model
model_xonar_d1
=
{
.
longname
=
"Asus Virtuoso 100"
,
.
chip
=
"AV200"
,
.
owner
=
THIS_MODULE
,
.
probe
=
xonar_model_probe
,
.
init
=
xonar_d1_init
,
.
control_filter
=
xonar_d1_control_filter
,
.
mixer_init
=
xonar_d1_mixer_init
,
...
...
@@ -868,7 +996,7 @@ static const struct oxygen_model model_xonar_d1 = {
PLAYBACK_1_TO_SPDIF
|
CAPTURE_0_FROM_I2S_2
,
.
dac_channels
=
8
,
.
dac_volume_min
=
0
,
.
dac_volume_min
=
127
-
6
0
,
.
dac_volume_max
=
127
,
.
function_flags
=
OXYGEN_FUNCTION_2WIRE
,
.
dac_i2s_format
=
OXYGEN_I2S_FORMAT_LJUST
,
...
...
@@ -878,8 +1006,6 @@ static const struct oxygen_model model_xonar_d1 = {
static
const
struct
oxygen_model
model_xonar_hdav
=
{
.
longname
=
"Asus Virtuoso 200"
,
.
chip
=
"AV200"
,
.
owner
=
THIS_MODULE
,
.
probe
=
xonar_model_probe
,
.
init
=
xonar_hdav_init
,
.
cleanup
=
xonar_hdav_cleanup
,
.
suspend
=
xonar_hdav_suspend
,
...
...
@@ -897,16 +1023,43 @@ static const struct oxygen_model model_xonar_hdav = {
PLAYBACK_1_TO_SPDIF
|
CAPTURE_0_FROM_I2S_2
,
.
dac_channels
=
8
,
.
dac_volume_min
=
0x0f
,
.
dac_volume_max
=
0xff
,
.
dac_volume_min
=
255
-
2
*
60
,
.
dac_volume_max
=
255
,
.
misc_flags
=
OXYGEN_MISC_MIDI
,
.
function_flags
=
OXYGEN_FUNCTION_2WIRE
,
.
dac_i2s_format
=
OXYGEN_I2S_FORMAT_LJUST
,
.
adc_i2s_format
=
OXYGEN_I2S_FORMAT_LJUST
,
};
static
int
__devinit
xonar_probe
(
struct
pci_dev
*
pci
,
const
struct
pci_device_id
*
pci_id
)
static
const
struct
oxygen_model
model_xonar_st
=
{
.
longname
=
"Asus Virtuoso 100"
,
.
chip
=
"AV200"
,
.
init
=
xonar_stx_init
,
.
control_filter
=
xonar_st_control_filter
,
.
mixer_init
=
xonar_st_mixer_init
,
.
cleanup
=
xonar_st_cleanup
,
.
suspend
=
xonar_st_suspend
,
.
resume
=
xonar_st_resume
,
.
set_dac_params
=
set_pcm1796_params
,
.
set_adc_params
=
set_cs53x1_params
,
.
update_dac_volume
=
update_pcm1796_volume
,
.
update_dac_mute
=
update_pcm1796_mute
,
.
ac97_switch
=
xonar_line_mic_ac97_switch
,
.
dac_tlv
=
pcm1796_db_scale
,
.
model_data_size
=
sizeof
(
struct
xonar_data
),
.
device_config
=
PLAYBACK_0_TO_I2S
|
PLAYBACK_1_TO_SPDIF
|
CAPTURE_0_FROM_I2S_2
,
.
dac_channels
=
2
,
.
dac_volume_min
=
255
-
2
*
60
,
.
dac_volume_max
=
255
,
.
function_flags
=
OXYGEN_FUNCTION_2WIRE
,
.
dac_i2s_format
=
OXYGEN_I2S_FORMAT_LJUST
,
.
adc_i2s_format
=
OXYGEN_I2S_FORMAT_LJUST
,
};
static
int
__devinit
get_xonar_model
(
struct
oxygen
*
chip
,
const
struct
pci_device_id
*
id
)
{
static
const
struct
oxygen_model
*
const
models
[]
=
{
[
MODEL_D1
]
=
&
model_xonar_d1
,
...
...
@@ -914,7 +1067,57 @@ static int __devinit xonar_probe(struct pci_dev *pci,
[
MODEL_D2
]
=
&
model_xonar_d2
,
[
MODEL_D2X
]
=
&
model_xonar_d2
,
[
MODEL_HDAV
]
=
&
model_xonar_hdav
,
[
MODEL_STX
]
=
&
model_xonar_st
,
};
static
const
char
*
const
names
[]
=
{
[
MODEL_D1
]
=
"Xonar D1"
,
[
MODEL_DX
]
=
"Xonar DX"
,
[
MODEL_D2
]
=
"Xonar D2"
,
[
MODEL_D2X
]
=
"Xonar D2X"
,
[
MODEL_HDAV
]
=
"Xonar HDAV1.3"
,
[
MODEL_HDAV_H6
]
=
"Xonar HDAV1.3+H6"
,
[
MODEL_STX
]
=
"Xonar Essence STX"
,
};
unsigned
int
model
=
id
->
driver_data
;
if
(
model
>=
ARRAY_SIZE
(
models
)
||
!
models
[
model
])
return
-
EINVAL
;
chip
->
model
=
*
models
[
model
];
switch
(
model
)
{
case
MODEL_D2X
:
chip
->
model
.
init
=
xonar_d2x_init
;
break
;
case
MODEL_DX
:
chip
->
model
.
init
=
xonar_dx_init
;
break
;
case
MODEL_HDAV
:
oxygen_clear_bits16
(
chip
,
OXYGEN_GPIO_CONTROL
,
GPIO_HDAV_DB_MASK
);
switch
(
oxygen_read16
(
chip
,
OXYGEN_GPIO_DATA
)
&
GPIO_HDAV_DB_MASK
)
{
case
GPIO_HDAV_DB_H6
:
model
=
MODEL_HDAV_H6
;
break
;
case
GPIO_HDAV_DB_XX
:
snd_printk
(
KERN_ERR
"unknown daughterboard
\n
"
);
return
-
ENODEV
;
}
break
;
case
MODEL_STX
:
oxygen_clear_bits16
(
chip
,
OXYGEN_GPIO_CONTROL
,
GPIO_HDAV_DB_MASK
);
break
;
}
chip
->
model
.
shortname
=
names
[
model
];
chip
->
model
.
private_data
=
model
;
return
0
;
}
static
int
__devinit
xonar_probe
(
struct
pci_dev
*
pci
,
const
struct
pci_device_id
*
pci_id
)
{
static
int
dev
;
int
err
;
...
...
@@ -924,10 +1127,8 @@ static int __devinit xonar_probe(struct pci_dev *pci,
++
dev
;
return
-
ENOENT
;
}
BUG_ON
(
pci_id
->
driver_data
>=
ARRAY_SIZE
(
models
));
err
=
oxygen_pci_probe
(
pci
,
index
[
dev
],
id
[
dev
],
models
[
pci_id
->
driver_data
],
pci_id
->
driver_data
);
err
=
oxygen_pci_probe
(
pci
,
index
[
dev
],
id
[
dev
],
THIS_MODULE
,
xonar_ids
,
get_xonar_model
);
if
(
err
>=
0
)
++
dev
;
return
err
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录