Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (122 commits) [ALSA] version 1.0.14rc4 [ALSA] Add speaker pin sequencing to hda_codec.c:snd_hda_parse_pin_def_config() [ALSA] hda-codec - Add ALC861VD Lenovo support [ALSA] hda-codec - Fix connection list in generic parser [ALSA] usb-audio: work around wrong wMaxPacketSize on ESI M4U [ALSA] usb-audio: work around broken M-Audio MidiSport Uno firmware [ALSA] usb-audio: explicitly match Logitech QuickCam [ALSA] hda-codec - Fix a typo [ALSA] hda-codec - Fix ALC880 uniwill auto-mutes [ALSA] hda-codec - Fix AD1988 SPDIF playback route control [ALSA] wm8750 typo fix [ALSA] wavefront: only declare isapnp on CONFIG_PNP [ALSA] hda-codec - bug fixes for stac92xx HDA codecs. [ALSA] add MODULE_FIRMWARE entries [ALSA] do not depend on FW_LOADER when internal firmware images are used [ALSA] hda-codec - Fix resume of STAC92xx codecs [ALSA] usbaudio - Revert the minimal period size fix patch [ALSA] hda-codec - Add support for new HP DV series laptops [ALSA] usb-audio - Fix the minimum period size per transfer mode [ALSA] sound/pcmcia/vx/vxpocket.c: fix an if() condition ...
This commit is contained in:
Коммит
0a3fd051c7
|
@ -821,6 +821,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
6stack-dig 6-jack digital with SPDIF I/O
|
||||
arima Arima W820Di1
|
||||
macpro MacPro support
|
||||
w2jc ASUS W2JC
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC883/888
|
||||
|
@ -852,6 +853,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
3stack-dig 3-jack with SPDIF OUT
|
||||
6stack-dig 6-jack with SPDIF OUT
|
||||
3stack-660 3-jack (for ALC660VD)
|
||||
lenovo Lenovo 3000 C200
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
CMI9880
|
||||
|
@ -909,6 +911,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
macbook Intel Mac Book
|
||||
macbook-pro-v1 Intel Mac Book Pro 1st generation
|
||||
macbook-pro Intel Mac Book Pro 2nd generation
|
||||
imac-intel Intel iMac
|
||||
|
||||
STAC9202/9250/9251
|
||||
ref Reference board, base config
|
||||
|
@ -924,6 +927,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
vaio Setup for VAIO FE550G/SZ110
|
||||
vaio-ar Setup for VAIO AR
|
||||
|
||||
The model name "genric" is treated as a special case. When this
|
||||
model is given, the driver uses the generic codec parser without
|
||||
"codec-patch". It's sometimes good for testing and debugging.
|
||||
|
||||
If the default configuration doesn't work and one of the above
|
||||
matches with your device, report it together with the PCI
|
||||
subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
|
||||
|
@ -1278,6 +1285,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
port - port number or -1 (disable)
|
||||
irq - IRQ number or -1 (disable)
|
||||
pnp - PnP detection - 0 = disable, 1 = enable (default)
|
||||
uart_enter - Issue UART_ENTER command at open - bool, default = on
|
||||
|
||||
This module supports multiple devices and PnP.
|
||||
|
||||
|
@ -1692,6 +1700,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
Module snd-usb-caiaq
|
||||
--------------------
|
||||
|
||||
Module for caiaq UB audio interfaces,
|
||||
* Native Instruments RigKontrol2
|
||||
* Native Instruments Kore Controller
|
||||
* Native Instruments Audio Kontrol 1
|
||||
* Native Instruments Audio 8 DJ
|
||||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
Module snd-usb-usx2y
|
||||
--------------------
|
||||
|
||||
|
@ -2046,4 +2065,4 @@ Links and Addresses
|
|||
https://bugtrack.alsa-project.org/bugs/
|
||||
|
||||
ALSA Developers ML
|
||||
mailto:alsa-devel@lists.sourceforge.net
|
||||
mailto:alsa-devel@alsa-project.org
|
||||
|
|
|
@ -36,8 +36,8 @@ recorded data is not right, try to specify the digital_rate option with
|
|||
other values than the default 32000 (often it's 44100 or 64000).
|
||||
|
||||
If you have an unknown card, please mail the ID and board name to
|
||||
<alsa-devel@lists.sf.net>, regardless of whether audio capture works or
|
||||
not, so that future versions of this driver know about your card.
|
||||
<alsa-devel@alsa-project.org>, regardless of whether audio capture works
|
||||
or not, so that future versions of this driver know about your card.
|
||||
|
||||
|
||||
Audio modes
|
||||
|
|
|
@ -372,7 +372,7 @@ AOA (Apple Onboard Audio) ALSA DRIVER
|
|||
P: Johannes Berg
|
||||
M: johannes@sipsolutions.net
|
||||
L: linuxppc-dev@ozlabs.org
|
||||
L: alsa-devel@alsa-project.org
|
||||
L: alsa-devel@alsa-project.org (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
APM DRIVER
|
||||
|
@ -3239,13 +3239,13 @@ S: Maintained
|
|||
SOUND
|
||||
P: Jaroslav Kysela
|
||||
M: perex@suse.cz
|
||||
L: alsa-devel@alsa-project.org
|
||||
L: alsa-devel@alsa-project.org (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
|
||||
P: Liam Girdwood
|
||||
M: liam.girdwood@wolfsonmicro.com
|
||||
L: alsa-devel@alsa-project.org
|
||||
L: alsa-devel@alsa-project.org (subscribers-only)
|
||||
S: Supported
|
||||
|
||||
SPI SUBSYSTEM
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
#define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */
|
||||
#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */
|
||||
#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */
|
||||
#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */
|
||||
|
||||
#define I2C_DRIVERID_I2CDEV 900
|
||||
#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
|
||||
/* AK4114_REQ_FORMAT bits */
|
||||
#define AK4114_MONO (1<<7) /* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */
|
||||
#define AK4114_DIF2 (1<<5) /* Audio Data Control */
|
||||
#define AK4114_DIF2 (1<<6) /* Audio Data Control */
|
||||
#define AK4114_DIF1 (1<<5) /* Audio Data Control */
|
||||
#define AK4114_DIF0 (1<<4) /* Audio Data Control */
|
||||
#define AK4114_DIF_16R (0) /* STDO: 16-bit, right justified */
|
||||
|
@ -158,7 +158,7 @@
|
|||
#define AK4114_CHECK_NO_STAT (1<<0) /* no statistics */
|
||||
#define AK4114_CHECK_NO_RATE (1<<1) /* no rate check */
|
||||
|
||||
#define AK4114_CONTROLS 14
|
||||
#define AK4114_CONTROLS 15
|
||||
|
||||
typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data);
|
||||
typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
|
||||
#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
|
||||
#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */
|
||||
#define MPU401_INFO_UART_ONLY (1 << 5) /* No ENTER_UART cmd needed */
|
||||
|
||||
#define MPU401_MODE_BIT_INPUT 0
|
||||
#define MPU401_MODE_BIT_OUTPUT 1
|
||||
|
|
|
@ -603,11 +603,8 @@ do { \
|
|||
read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \
|
||||
} while (0)
|
||||
|
||||
#define snd_pcm_group_for_each(pos, substream) \
|
||||
list_for_each(pos, &substream->group->substreams)
|
||||
|
||||
#define snd_pcm_group_substream_entry(pos) \
|
||||
list_entry(pos, struct snd_pcm_substream, link_list)
|
||||
#define snd_pcm_group_for_each_entry(s, substream) \
|
||||
list_for_each_entry(s, &substream->group->substreams, link_list)
|
||||
|
||||
static inline int snd_pcm_running(struct snd_pcm_substream *substream)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
/* include/version.h. Generated by alsa/ksync script. */
|
||||
#define CONFIG_SND_VERSION "1.0.14rc3"
|
||||
#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)"
|
||||
#define CONFIG_SND_VERSION "1.0.14rc4"
|
||||
#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)"
|
||||
|
|
|
@ -1018,7 +1018,7 @@ static int onyx_create(struct i2c_adapter *adapter,
|
|||
onyx->i2c.driver = &onyx_driver;
|
||||
onyx->i2c.adapter = adapter;
|
||||
onyx->i2c.addr = addr & 0x7f;
|
||||
strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1);
|
||||
strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE);
|
||||
|
||||
if (i2c_attach_client(&onyx->i2c)) {
|
||||
printk(KERN_ERR PFX "failed to attach to i2c\n");
|
||||
|
@ -1033,7 +1033,7 @@ static int onyx_create(struct i2c_adapter *adapter,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1);
|
||||
strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
|
||||
onyx->codec.owner = THIS_MODULE;
|
||||
onyx->codec.init = onyx_init_codec;
|
||||
onyx->codec.exit = onyx_exit_codec;
|
||||
|
|
|
@ -899,14 +899,14 @@ static int tas_create(struct i2c_adapter *adapter,
|
|||
tas->i2c.addr = addr;
|
||||
/* seems that half is a saner default */
|
||||
tas->drc_range = TAS3004_DRC_MAX / 2;
|
||||
strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
|
||||
strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE);
|
||||
|
||||
if (i2c_attach_client(&tas->i2c)) {
|
||||
printk(KERN_ERR PFX "failed to attach to i2c\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1);
|
||||
strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
|
||||
tas->codec.owner = THIS_MODULE;
|
||||
tas->codec.init = tas_init_codec;
|
||||
tas->codec.exit = tas_exit_codec;
|
||||
|
|
|
@ -163,8 +163,6 @@ static int soundbus_device_resume(struct device * dev)
|
|||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
extern struct device_attribute soundbus_dev_attrs[];
|
||||
|
||||
static struct bus_type soundbus_bus_type = {
|
||||
.name = "aoa-soundbus",
|
||||
.probe = soundbus_probe,
|
||||
|
|
|
@ -23,9 +23,6 @@
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
|
||||
MODULE_DESCRIPTION("Apple Soundbus: I2S support");
|
||||
/* for auto-loading, declare that we handle this weird
|
||||
* string that macio puts into the relevant device */
|
||||
MODULE_ALIAS("of:Ni2sTi2sC");
|
||||
|
||||
static int force;
|
||||
module_param(force, int, 0444);
|
||||
|
@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, i2sbus_match);
|
||||
|
||||
static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
|
||||
struct dbdma_command_mem *r,
|
||||
int numcmds)
|
||||
|
|
|
@ -199,4 +199,6 @@ struct soundbus_driver {
|
|||
extern int soundbus_register_driver(struct soundbus_driver *drv);
|
||||
extern void soundbus_unregister_driver(struct soundbus_driver *drv);
|
||||
|
||||
extern struct device_attribute soundbus_dev_attrs[];
|
||||
|
||||
#endif /* __SOUNDBUS_H */
|
||||
|
|
|
@ -712,26 +712,23 @@ static int snd_pcm_action_group(struct action_ops *ops,
|
|||
struct snd_pcm_substream *substream,
|
||||
int state, int do_lock)
|
||||
{
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s = NULL;
|
||||
struct snd_pcm_substream *s1;
|
||||
int res = 0;
|
||||
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
if (do_lock && s != substream)
|
||||
spin_lock(&s->self_group.lock);
|
||||
spin_lock_nested(&s->self_group.lock,
|
||||
SINGLE_DEPTH_NESTING);
|
||||
res = ops->pre_action(s, state);
|
||||
if (res < 0)
|
||||
goto _unlock;
|
||||
}
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
res = ops->do_action(s, state);
|
||||
if (res < 0) {
|
||||
if (ops->undo_action) {
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s1 = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s1, substream) {
|
||||
if (s1 == s) /* failed stream */
|
||||
break;
|
||||
ops->undo_action(s1, state);
|
||||
|
@ -741,15 +738,13 @@ static int snd_pcm_action_group(struct action_ops *ops,
|
|||
goto _unlock;
|
||||
}
|
||||
}
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
ops->post_action(s, state);
|
||||
}
|
||||
_unlock:
|
||||
if (do_lock) {
|
||||
/* unlock streams */
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s1 = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s1, substream) {
|
||||
if (s1 != substream)
|
||||
spin_unlock(&s1->self_group.lock);
|
||||
if (s1 == s) /* end */
|
||||
|
@ -1438,7 +1433,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
|
|||
{
|
||||
struct snd_card *card;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
int result = 0;
|
||||
int i, num_drecs;
|
||||
struct drain_rec *drec, drec_tmp, *d;
|
||||
|
@ -1473,8 +1468,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
|
|||
|
||||
/* count only playback streams */
|
||||
num_drecs = 0;
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
runtime = s->runtime;
|
||||
if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
d = &drec[num_drecs++];
|
||||
|
@ -1674,7 +1668,7 @@ static void relink_to_local(struct snd_pcm_substream *substream)
|
|||
|
||||
static int snd_pcm_unlink(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
int res = 0;
|
||||
|
||||
down_write(&snd_pcm_link_rwsem);
|
||||
|
@ -1686,8 +1680,8 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
|
|||
list_del(&substream->link_list);
|
||||
substream->group->count--;
|
||||
if (substream->group->count == 1) { /* detach the last stream, too */
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
relink_to_local(snd_pcm_group_substream_entry(pos));
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
relink_to_local(s);
|
||||
break;
|
||||
}
|
||||
kfree(substream->group);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/log2.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/timer.h>
|
||||
|
||||
|
@ -129,7 +130,7 @@ static int __init rtctimer_init(void)
|
|||
struct snd_timer *timer;
|
||||
|
||||
if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
|
||||
(rtctimer_freq & (rtctimer_freq - 1)) != 0) {
|
||||
!is_power_of_2(rtctimer_freq)) {
|
||||
snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
|
||||
rtctimer_freq);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -42,6 +42,7 @@ static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
|
|||
#endif
|
||||
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
|
||||
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
|
||||
static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
|
||||
|
||||
module_param_array(index, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
|
||||
|
@ -57,6 +58,8 @@ module_param_array(port, long, NULL, 0444);
|
|||
MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
|
||||
module_param_array(irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
|
||||
module_param_array(uart_enter, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open.");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
static int pnp_registered;
|
||||
|
@ -80,10 +83,11 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
|
|||
strcat(card->longname, "polled");
|
||||
}
|
||||
|
||||
if ((err = snd_mpu401_uart_new(card, 0,
|
||||
MPU401_HW_MPU401,
|
||||
port[dev], 0,
|
||||
irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL)) < 0) {
|
||||
err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev],
|
||||
uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY,
|
||||
irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0,
|
||||
NULL);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
|
||||
goto _err;
|
||||
}
|
||||
|
|
|
@ -266,6 +266,16 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_mpu401_do_reset(struct snd_mpu401 *mpu)
|
||||
{
|
||||
if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
|
||||
return -EIO;
|
||||
if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) &&
|
||||
snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* input/output open/close - protected by open_mutex in rawmidi.c
|
||||
*/
|
||||
|
@ -278,9 +288,7 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
|
|||
if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
|
||||
return err;
|
||||
if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
|
||||
if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
|
||||
goto error_out;
|
||||
if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
|
||||
if (snd_mpu401_do_reset(mpu) < 0)
|
||||
goto error_out;
|
||||
}
|
||||
mpu->substream_input = substream;
|
||||
|
@ -302,9 +310,7 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
|
|||
if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
|
||||
return err;
|
||||
if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
|
||||
if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
|
||||
goto error_out;
|
||||
if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
|
||||
if (snd_mpu401_do_reset(mpu) < 0)
|
||||
goto error_out;
|
||||
}
|
||||
mpu->substream_output = substream;
|
||||
|
|
|
@ -898,7 +898,7 @@ static void __devinit snd_mts64_attach(struct parport *p)
|
|||
/* Temporary assignment to forward the parport */
|
||||
platform_set_drvdata(device, p);
|
||||
|
||||
if (platform_device_register(device) < 0) {
|
||||
if (platform_device_add(device) < 0) {
|
||||
platform_device_put(device);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -682,7 +682,7 @@ static void __devinit snd_portman_attach(struct parport *p)
|
|||
/* Temporary assignment to forward the parport */
|
||||
platform_set_drvdata(device, p);
|
||||
|
||||
if (platform_device_register(device) < 0) {
|
||||
if (platform_device_add(device) < 0) {
|
||||
platform_device_put(device);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,20 @@
|
|||
|
||||
#ifdef SND_VX_FW_LOADER
|
||||
|
||||
MODULE_FIRMWARE("vx/bx_1_vxp.b56");
|
||||
MODULE_FIRMWARE("vx/bx_1_vp4.b56");
|
||||
MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
|
||||
MODULE_FIRMWARE("vx/x1_2_v22.xlx");
|
||||
MODULE_FIRMWARE("vx/x1_1_vxp.xlx");
|
||||
MODULE_FIRMWARE("vx/x1_1_vp4.xlx");
|
||||
MODULE_FIRMWARE("vx/bd56002.boot");
|
||||
MODULE_FIRMWARE("vx/bd563v2.boot");
|
||||
MODULE_FIRMWARE("vx/bd563s3.boot");
|
||||
MODULE_FIRMWARE("vx/l_1_vx2.d56");
|
||||
MODULE_FIRMWARE("vx/l_1_v22.d56");
|
||||
MODULE_FIRMWARE("vx/l_1_vxp.d56");
|
||||
MODULE_FIRMWARE("vx/l_1_vp4.d56");
|
||||
|
||||
int snd_vx_setup_firmware(struct vx_core *chip)
|
||||
{
|
||||
static char *fw_files[VX_TYPE_NUMS][4] = {
|
||||
|
|
|
@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
|
|||
#define AK4114_ADDR 0x00 /* fixed address */
|
||||
|
||||
static void ak4114_stats(struct work_struct *work);
|
||||
static void ak4114_init_regs(struct ak4114 *chip);
|
||||
|
||||
static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val)
|
||||
{
|
||||
|
@ -105,7 +106,7 @@ int snd_ak4114_create(struct snd_card *card,
|
|||
for (reg = 0; reg < 5; reg++)
|
||||
chip->txcsb[reg] = txcsb[reg];
|
||||
|
||||
snd_ak4114_reinit(chip);
|
||||
ak4114_init_regs(chip);
|
||||
|
||||
chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
|
||||
chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);
|
||||
|
@ -131,13 +132,10 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char
|
|||
(chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val);
|
||||
}
|
||||
|
||||
void snd_ak4114_reinit(struct ak4114 *chip)
|
||||
static void ak4114_init_regs(struct ak4114 *chip)
|
||||
{
|
||||
unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg;
|
||||
|
||||
chip->init = 1;
|
||||
mb();
|
||||
flush_scheduled_work();
|
||||
/* bring the chip to reset state and powerdown state */
|
||||
reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN));
|
||||
udelay(200);
|
||||
|
@ -150,8 +148,17 @@ void snd_ak4114_reinit(struct ak4114 *chip)
|
|||
reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]);
|
||||
/* release powerdown, everything is initialized now */
|
||||
reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN);
|
||||
}
|
||||
|
||||
void snd_ak4114_reinit(struct ak4114 *chip)
|
||||
{
|
||||
chip->init = 1;
|
||||
mb();
|
||||
flush_scheduled_work();
|
||||
ak4114_init_regs(chip);
|
||||
/* bring up statistics / event queing */
|
||||
chip->init = 0;
|
||||
if (chip->kctls[0])
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
}
|
||||
|
||||
|
@ -428,7 +435,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
|
|||
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||
.info = snd_ak4114_in_bit_info,
|
||||
.get = snd_ak4114_in_bit_get,
|
||||
.private_value = (6<<8) | AK4114_REG_RCS1,
|
||||
.private_value = (6<<8) | AK4114_REG_RCS0,
|
||||
},
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
|
@ -436,7 +443,15 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
|
|||
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||
.info = snd_ak4114_in_bit_info,
|
||||
.get = snd_ak4114_in_bit_get,
|
||||
.private_value = (3<<8) | AK4114_REG_RCS1,
|
||||
.private_value = (3<<8) | AK4114_REG_RCS0,
|
||||
},
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "IEC958 PPL Lock Status",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||
.info = snd_ak4114_in_bit_info,
|
||||
.get = snd_ak4114_in_bit_get,
|
||||
.private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -455,7 +470,7 @@ int snd_ak4114_build(struct ak4114 *ak4114,
|
|||
kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114);
|
||||
if (kctl == NULL)
|
||||
return -ENOMEM;
|
||||
if (!strstr(kctl->id.name, "Playback")) {
|
||||
if (strstr(kctl->id.name, "Playback")) {
|
||||
if (ply_substream == NULL) {
|
||||
snd_ctl_free_one(kctl);
|
||||
ak4114->kctls[idx] = NULL;
|
||||
|
@ -472,9 +487,58 @@ int snd_ak4114_build(struct ak4114 *ak4114,
|
|||
return err;
|
||||
ak4114->kctls[idx] = kctl;
|
||||
}
|
||||
/* trigger workq */
|
||||
schedule_delayed_work(&ak4114->work, HZ / 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* notify kcontrols if any parameters are changed */
|
||||
static void ak4114_notify(struct ak4114 *ak4114,
|
||||
unsigned char rcs0, unsigned char rcs1,
|
||||
unsigned char c0, unsigned char c1)
|
||||
{
|
||||
if (!ak4114->kctls[0])
|
||||
return;
|
||||
|
||||
if (rcs0 & AK4114_PAR)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[0]->id);
|
||||
if (rcs0 & AK4114_V)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[1]->id);
|
||||
if (rcs1 & AK4114_CCRC)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[2]->id);
|
||||
if (rcs1 & AK4114_QCRC)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[3]->id);
|
||||
|
||||
/* rate change */
|
||||
if (c1 & 0xf0)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[4]->id);
|
||||
|
||||
if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[9]->id);
|
||||
if (c0 & AK4114_QINT)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[10]->id);
|
||||
|
||||
if (c0 & AK4114_AUDION)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[11]->id);
|
||||
if (c0 & AK4114_AUTO)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[12]->id);
|
||||
if (c0 & AK4114_DTSCD)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[13]->id);
|
||||
if (c0 & AK4114_UNLCK)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&ak4114->kctls[14]->id);
|
||||
}
|
||||
|
||||
int snd_ak4114_external_rate(struct ak4114 *ak4114)
|
||||
{
|
||||
unsigned char rcs1;
|
||||
|
@ -511,31 +575,7 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
|
|||
ak4114->rcs1 = rcs1;
|
||||
spin_unlock_irqrestore(&ak4114->lock, _flags);
|
||||
|
||||
if (rcs0 & AK4114_PAR)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id);
|
||||
if (rcs0 & AK4114_V)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id);
|
||||
if (rcs1 & AK4114_CCRC)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id);
|
||||
if (rcs1 & AK4114_QCRC)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id);
|
||||
|
||||
/* rate change */
|
||||
if (c1 & 0xf0)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id);
|
||||
|
||||
if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id);
|
||||
if (c0 & AK4114_QINT)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id);
|
||||
|
||||
if (c0 & AK4114_AUDION)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id);
|
||||
if (c0 & AK4114_AUTO)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id);
|
||||
if (c0 & AK4114_DTSCD)
|
||||
snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id);
|
||||
|
||||
ak4114_notify(ak4114, rcs0, rcs1, c0, c1);
|
||||
if (ak4114->change_callback && (c0 | c1) != 0)
|
||||
ak4114->change_callback(ak4114, c0, c1);
|
||||
|
||||
|
@ -558,9 +598,9 @@ static void ak4114_stats(struct work_struct *work)
|
|||
{
|
||||
struct ak4114 *chip = container_of(work, struct ak4114, work.work);
|
||||
|
||||
if (chip->init)
|
||||
return;
|
||||
if (!chip->init)
|
||||
snd_ak4114_check_rate_and_errors(chip, 0);
|
||||
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
}
|
||||
|
||||
|
|
|
@ -358,12 +358,21 @@ config SND_SBAWE
|
|||
config SND_SB16_CSP
|
||||
bool "Sound Blaster 16/AWE CSP support"
|
||||
depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
|
||||
select FW_LOADER
|
||||
select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
help
|
||||
Say Y here to include support for the CSP core. This special
|
||||
coprocessor can do variable tasks like various compression and
|
||||
decompression algorithms.
|
||||
|
||||
config SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
bool "In-kernel firmware for SB16 CSP"
|
||||
depends on SND_SB16_CSP
|
||||
default y
|
||||
help
|
||||
Say Y here to include the static firmware built in the kernel
|
||||
for the SB16 CSP controller. If you choose N here, you need
|
||||
to install the firmware files from the alsa-firmware package.
|
||||
|
||||
config SND_SGALAXY
|
||||
tristate "Aztech Sound Galaxy"
|
||||
depends on SND
|
||||
|
@ -391,7 +400,7 @@ config SND_SSCAPE
|
|||
config SND_WAVEFRONT
|
||||
tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
|
||||
depends on SND
|
||||
select FW_LOADER
|
||||
select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_CS4231_LIB
|
||||
|
@ -402,4 +411,13 @@ config SND_WAVEFRONT
|
|||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-wavefront.
|
||||
|
||||
config SND_WAVEFRONT_FIRMWARE_IN_KERNEL
|
||||
bool "In-kernel firmware for Wavefront"
|
||||
depends on SND_WAVEFRONT
|
||||
default y
|
||||
help
|
||||
Say Y here to include the static firmware built in the kernel
|
||||
for the Wavefront driver. If you choose N here, you need to
|
||||
install the firmware files from the alsa-firmware package.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -129,8 +129,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
|
|||
}
|
||||
acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
|
||||
if (acard->devmpu == NULL) {
|
||||
kfree(cfg);
|
||||
return -EBUSY;
|
||||
mpu_port[dev] = -1;
|
||||
snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
|
||||
}
|
||||
|
||||
pdev = acard->dev;
|
||||
|
@ -162,6 +162,10 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
|
|||
dma2[dev] = pnp_dma(pdev, 1);
|
||||
irq[dev] = pnp_irq(pdev, 0);
|
||||
|
||||
if (acard->devmpu == NULL) {
|
||||
kfree(cfg);
|
||||
return 0;
|
||||
}
|
||||
pdev = acard->devmpu;
|
||||
pnp_init_resource_table(cfg);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -32,8 +32,11 @@
|
|||
#include <sound/ad1848.h>
|
||||
#include <sound/initval.h>
|
||||
|
||||
#define CRD_NAME "Generic AD1848/AD1847/CS4248"
|
||||
#define DEV_NAME "ad1848"
|
||||
|
||||
MODULE_DESCRIPTION(CRD_NAME);
|
||||
MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@suse.cz>");
|
||||
MODULE_DESCRIPTION("AD1848/AD1847/CS4248");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848},"
|
||||
"{Analog Devices,AD1847},"
|
||||
|
@ -48,95 +51,98 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
|
|||
static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */
|
||||
|
||||
module_param_array(index, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(index, "Index value for AD1848 soundcard.");
|
||||
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
|
||||
module_param_array(id, charp, NULL, 0444);
|
||||
MODULE_PARM_DESC(id, "ID string for AD1848 soundcard.");
|
||||
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
|
||||
module_param_array(enable, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(enable, "Enable AD1848 soundcard.");
|
||||
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
|
||||
module_param_array(port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(port, "Port # for AD1848 driver.");
|
||||
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
|
||||
module_param_array(irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(irq, "IRQ # for AD1848 driver.");
|
||||
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(dma1, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver.");
|
||||
MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
|
||||
module_param_array(thinkpad, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
|
||||
|
||||
static int __devinit snd_ad1848_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
|
||||
{
|
||||
if (!enable[n])
|
||||
return 0;
|
||||
|
||||
if (port[n] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (irq[n] == SNDRV_AUTO_IRQ) {
|
||||
snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (dma1[n] == SNDRV_AUTO_DMA) {
|
||||
snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
struct snd_card *card;
|
||||
struct snd_ad1848 *chip;
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
if (port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "ad1848: specify port\n");
|
||||
card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (irq[dev] == SNDRV_AUTO_IRQ) {
|
||||
snd_printk(KERN_ERR "ad1848: specify irq\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dma1[dev] == SNDRV_AUTO_DMA) {
|
||||
snd_printk(KERN_ERR "ad1848: specify dma1\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
||||
if (card == NULL)
|
||||
return -ENOMEM;
|
||||
error = snd_ad1848_create(card, port[n], irq[n], dma1[n],
|
||||
thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_ad1848_create(card, port[dev],
|
||||
irq[dev],
|
||||
dma1[dev],
|
||||
thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
|
||||
&chip)) < 0)
|
||||
goto _err;
|
||||
card->private_data = chip;
|
||||
|
||||
if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
|
||||
goto _err;
|
||||
error = snd_ad1848_pcm(chip, 0, &pcm);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_ad1848_mixer(chip)) < 0)
|
||||
goto _err;
|
||||
error = snd_ad1848_mixer(chip);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
strcpy(card->driver, "AD1848");
|
||||
strcpy(card->shortname, pcm->name);
|
||||
|
||||
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
|
||||
pcm->name, chip->port, irq[dev], dma1[dev]);
|
||||
|
||||
if (thinkpad[dev])
|
||||
pcm->name, chip->port, irq[n], dma1[n]);
|
||||
if (thinkpad[n])
|
||||
strcat(card->longname, " [Thinkpad]");
|
||||
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, dev);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto _err;
|
||||
error = snd_card_register(card);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(dev, card);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
out: snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit snd_ad1848_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(dev));
|
||||
dev_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ad1848 *chip = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
|
@ -144,9 +150,9 @@ static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ad1848_resume(struct platform_device *pdev)
|
||||
static int snd_ad1848_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ad1848 *chip = card->private_data;
|
||||
|
||||
chip->resume(chip);
|
||||
|
@ -155,9 +161,8 @@ static int snd_ad1848_resume(struct platform_device *pdev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define SND_AD1848_DRIVER "snd_ad1848"
|
||||
|
||||
static struct platform_driver snd_ad1848_driver = {
|
||||
static struct isa_driver snd_ad1848_driver = {
|
||||
.match = snd_ad1848_match,
|
||||
.probe = snd_ad1848_probe,
|
||||
.remove = __devexit_p(snd_ad1848_remove),
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -165,57 +170,19 @@ static struct platform_driver snd_ad1848_driver = {
|
|||
.resume = snd_ad1848_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = SND_AD1848_DRIVER
|
||||
},
|
||||
.name = DEV_NAME
|
||||
}
|
||||
};
|
||||
|
||||
static void __init_or_module snd_ad1848_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_ad1848_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_ad1848_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_ad1848_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_AD1848_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "AD1848 soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_ad1848_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_ad1848_exit(void)
|
||||
{
|
||||
snd_ad1848_unregister_all();
|
||||
isa_unregister_driver(&snd_ad1848_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_ad1848_init)
|
||||
module_exit(alsa_card_ad1848_exit)
|
||||
module_init(alsa_card_ad1848_init);
|
||||
module_exit(alsa_card_ad1848_exit);
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/opl3.h>
|
||||
|
||||
#define CRD_NAME "AdLib FM"
|
||||
#define DRV_NAME "snd_adlib"
|
||||
#define DEV_NAME "adlib"
|
||||
|
||||
MODULE_DESCRIPTION(CRD_NAME);
|
||||
MODULE_AUTHOR("Rene Herman");
|
||||
|
@ -31,133 +31,99 @@ MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
|
|||
module_param_array(port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
static int __devinit snd_adlib_match(struct device *dev, unsigned int n)
|
||||
{
|
||||
if (!enable[n])
|
||||
return 0;
|
||||
|
||||
if (port[n] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void snd_adlib_free(struct snd_card *card)
|
||||
{
|
||||
release_and_free_resource(card->private_data);
|
||||
}
|
||||
|
||||
static int __devinit snd_adlib_probe(struct platform_device *device)
|
||||
static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct snd_opl3 *opl3;
|
||||
int error;
|
||||
|
||||
int error, i = device->id;
|
||||
|
||||
if (port[i] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR DRV_NAME ": please specify port\n");
|
||||
error = -EINVAL;
|
||||
goto out0;
|
||||
}
|
||||
|
||||
card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
|
||||
card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
|
||||
if (!card) {
|
||||
snd_printk(KERN_ERR DRV_NAME ": could not create card\n");
|
||||
error = -EINVAL;
|
||||
goto out0;
|
||||
snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
card->private_data = request_region(port[i], 4, CRD_NAME);
|
||||
card->private_data = request_region(port[n], 4, CRD_NAME);
|
||||
if (!card->private_data) {
|
||||
snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n");
|
||||
snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id);
|
||||
error = -EBUSY;
|
||||
goto out1;
|
||||
goto out;
|
||||
}
|
||||
card->private_free = snd_adlib_free;
|
||||
|
||||
error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3);
|
||||
strcpy(card->driver, DEV_NAME);
|
||||
strcpy(card->shortname, CRD_NAME);
|
||||
sprintf(card->longname, CRD_NAME " at %#lx", port[n]);
|
||||
|
||||
error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
|
||||
if (error < 0) {
|
||||
snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n");
|
||||
goto out1;
|
||||
snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
|
||||
if (error < 0) {
|
||||
snd_printk(KERN_ERR DRV_NAME ": could not create FM\n");
|
||||
goto out1;
|
||||
snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
strcpy(card->driver, DRV_NAME);
|
||||
strcpy(card->shortname, CRD_NAME);
|
||||
sprintf(card->longname, CRD_NAME " at %#lx", port[i]);
|
||||
|
||||
snd_card_set_dev(card, &device->dev);
|
||||
snd_card_set_dev(card, dev);
|
||||
|
||||
error = snd_card_register(card);
|
||||
if (error < 0) {
|
||||
snd_printk(KERN_ERR DRV_NAME ": could not register card\n");
|
||||
goto out1;
|
||||
snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
platform_set_drvdata(device, card);
|
||||
dev_set_drvdata(dev, card);
|
||||
return 0;
|
||||
|
||||
out1: snd_card_free(card);
|
||||
out0: return error;
|
||||
out: snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit snd_adlib_remove(struct platform_device *device)
|
||||
static int __devexit snd_adlib_remove(struct device *dev, unsigned int n)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(device));
|
||||
platform_set_drvdata(device, NULL);
|
||||
snd_card_free(dev_get_drvdata(dev));
|
||||
dev_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver snd_adlib_driver = {
|
||||
static struct isa_driver snd_adlib_driver = {
|
||||
.match = snd_adlib_match,
|
||||
.probe = snd_adlib_probe,
|
||||
.remove = __devexit_p(snd_adlib_remove),
|
||||
|
||||
.driver = {
|
||||
.name = DRV_NAME
|
||||
.name = DEV_NAME
|
||||
}
|
||||
};
|
||||
|
||||
static int __init alsa_card_adlib_init(void)
|
||||
{
|
||||
int i, cards;
|
||||
|
||||
if (platform_driver_register(&snd_adlib_driver) < 0) {
|
||||
snd_printk(KERN_ERR DRV_NAME ": could not register driver\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (cards = 0, i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
|
||||
if (!enable[i])
|
||||
continue;
|
||||
|
||||
device = platform_device_register_simple(DRV_NAME, i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n");
|
||||
#endif
|
||||
platform_driver_unregister(&snd_adlib_driver);
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_adlib_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_adlib_driver);
|
||||
isa_unregister_driver(&snd_adlib_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_adlib_init);
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -108,7 +108,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver.");
|
|||
module_param_array(wssdma, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered;
|
||||
#endif
|
||||
|
@ -547,70 +546,78 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
|
|||
return snd_card_register(card);
|
||||
}
|
||||
|
||||
static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_cmi8330_isa_match(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
int dev = pdev->id;
|
||||
|
||||
if (!enable[dev] || is_isapnp_selected(dev))
|
||||
return 0;
|
||||
if (wssport[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify wssport\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (sbport[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify sbport\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_cmi8330_isa_probe(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
|
||||
card = snd_cmi8330_card_new(dev);
|
||||
if (! card)
|
||||
return -ENOMEM;
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
if ((err = snd_cmi8330_probe(card, dev)) < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit snd_cmi8330_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_cmi8330_isa_remove(struct device *devptr,
|
||||
unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
return snd_cmi8330_suspend(platform_get_drvdata(dev));
|
||||
return snd_cmi8330_suspend(dev_get_drvdata(dev));
|
||||
}
|
||||
|
||||
static int snd_cmi8330_nonpnp_resume(struct platform_device *dev)
|
||||
static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
return snd_cmi8330_resume(platform_get_drvdata(dev));
|
||||
return snd_cmi8330_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CMI8330_DRIVER "snd_cmi8330"
|
||||
#define DEV_NAME "cmi8330"
|
||||
|
||||
static struct platform_driver snd_cmi8330_driver = {
|
||||
.probe = snd_cmi8330_nonpnp_probe,
|
||||
.remove = __devexit_p(snd_cmi8330_nonpnp_remove),
|
||||
static struct isa_driver snd_cmi8330_driver = {
|
||||
.match = snd_cmi8330_isa_match,
|
||||
.probe = snd_cmi8330_isa_probe,
|
||||
.remove = __devexit_p(snd_cmi8330_isa_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_cmi8330_nonpnp_suspend,
|
||||
.resume = snd_cmi8330_nonpnp_resume,
|
||||
.suspend = snd_cmi8330_isa_suspend,
|
||||
.resume = snd_cmi8330_isa_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = CMI8330_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static unsigned int __devinitdata cmi8330_pnp_devices;
|
||||
|
||||
static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
|
||||
const struct pnp_card_device_id *pid)
|
||||
{
|
||||
|
@ -640,7 +647,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
|
|||
}
|
||||
pnp_set_card_drvdata(pcard, card);
|
||||
dev++;
|
||||
cmi8330_pnp_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -675,63 +681,28 @@ static struct pnp_card_driver cmi8330_pnpc_driver = {
|
|||
};
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static void __init_or_module snd_cmi8330_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&cmi8330_pnpc_driver);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&snd_cmi8330_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_cmi8330_init(void)
|
||||
{
|
||||
int i, err, cards = 0;
|
||||
int err;
|
||||
|
||||
if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0)
|
||||
err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i] || is_isapnp_selected(i))
|
||||
continue;
|
||||
device = platform_device_register_simple(CMI8330_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
err = pnp_register_card_driver(&cmi8330_pnpc_driver);
|
||||
if (!err) {
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
cards += cmi8330_pnp_devices;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
snd_printk(KERN_ERR "CMI8330 not found or device busy\n");
|
||||
#endif
|
||||
snd_cmi8330_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_cmi8330_exit(void)
|
||||
{
|
||||
snd_cmi8330_unregister_all();
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&cmi8330_pnpc_driver);
|
||||
#endif
|
||||
isa_unregister_driver(&snd_cmi8330_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_cmi8330_init)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -32,8 +32,11 @@
|
|||
#include <sound/mpu401.h>
|
||||
#include <sound/initval.h>
|
||||
|
||||
#define CRD_NAME "Generic CS4231"
|
||||
#define DEV_NAME "cs4231"
|
||||
|
||||
MODULE_DESCRIPTION(CRD_NAME);
|
||||
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
|
||||
MODULE_DESCRIPTION("Generic CS4231");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}");
|
||||
|
||||
|
@ -48,132 +51,136 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
|
|||
static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
|
||||
|
||||
module_param_array(index, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(index, "Index value for CS4231 soundcard.");
|
||||
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
|
||||
module_param_array(id, charp, NULL, 0444);
|
||||
MODULE_PARM_DESC(id, "ID string for CS4231 soundcard.");
|
||||
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
|
||||
module_param_array(enable, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(enable, "Enable CS4231 soundcard.");
|
||||
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
|
||||
module_param_array(port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(port, "Port # for CS4231 driver.");
|
||||
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
|
||||
module_param_array(mpu_port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for CS4231 driver.");
|
||||
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
|
||||
module_param_array(irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(irq, "IRQ # for CS4231 driver.");
|
||||
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(mpu_irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for CS4231 driver.");
|
||||
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(dma1, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver.");
|
||||
MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
|
||||
module_param_array(dma2, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver.");
|
||||
MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
|
||||
|
||||
static int __init snd_cs4231_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
struct snd_card *card;
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_cs4231 *chip;
|
||||
int err;
|
||||
if (!enable[n])
|
||||
return 0;
|
||||
|
||||
if (port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "specify port\n");
|
||||
return -EINVAL;
|
||||
if (port[n] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (irq[dev] == SNDRV_AUTO_IRQ) {
|
||||
snd_printk(KERN_ERR "specify irq\n");
|
||||
return -EINVAL;
|
||||
if (irq[n] == SNDRV_AUTO_IRQ) {
|
||||
snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (dma1[dev] == SNDRV_AUTO_DMA) {
|
||||
snd_printk(KERN_ERR "specify dma1\n");
|
||||
return -EINVAL;
|
||||
if (dma1[n] == SNDRV_AUTO_DMA) {
|
||||
snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
||||
if (card == NULL)
|
||||
return -ENOMEM;
|
||||
if ((err = snd_cs4231_create(card, port[dev], -1,
|
||||
irq[dev],
|
||||
dma1[dev],
|
||||
dma2[dev],
|
||||
CS4231_HW_DETECT,
|
||||
0, &chip)) < 0)
|
||||
goto _err;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct snd_cs4231 *chip;
|
||||
struct snd_pcm *pcm;
|
||||
int error;
|
||||
|
||||
card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n],
|
||||
CS4231_HW_DETECT, 0, &chip);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
card->private_data = chip;
|
||||
|
||||
if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
|
||||
goto _err;
|
||||
error = snd_cs4231_pcm(chip, 0, &pcm);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
strcpy(card->driver, "CS4231");
|
||||
strcpy(card->shortname, pcm->name);
|
||||
|
||||
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
|
||||
pcm->name, chip->port, irq[dev], dma1[dev]);
|
||||
if (dma2[dev] >= 0)
|
||||
sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
|
||||
pcm->name, chip->port, irq[n], dma1[n]);
|
||||
if (dma2[n] >= 0)
|
||||
sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
|
||||
|
||||
if ((err = snd_cs4231_mixer(chip)) < 0)
|
||||
goto _err;
|
||||
if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
|
||||
goto _err;
|
||||
error = snd_cs4231_mixer(chip);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
|
||||
if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
|
||||
mpu_irq[dev] = -1;
|
||||
error = snd_cs4231_timer(chip, 0, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) {
|
||||
if (mpu_irq[n] == SNDRV_AUTO_IRQ)
|
||||
mpu_irq[n] = -1;
|
||||
if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
|
||||
mpu_port[dev], 0,
|
||||
mpu_irq[dev],
|
||||
mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
|
||||
mpu_port[n], 0, mpu_irq[n],
|
||||
mpu_irq[n] >= 0 ? IRQF_DISABLED : 0,
|
||||
NULL) < 0)
|
||||
printk(KERN_WARNING "cs4231: MPU401 not detected\n");
|
||||
printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id);
|
||||
}
|
||||
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, dev);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto _err;
|
||||
error = snd_card_register(card);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(dev, card);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
out: snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit snd_cs4231_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(dev));
|
||||
dev_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct snd_cs4231 *chip;
|
||||
card = platform_get_drvdata(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_cs4231 *chip = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
chip = card->private_data;
|
||||
chip->suspend(chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cs4231_resume(struct platform_device *dev)
|
||||
static int snd_cs4231_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct snd_cs4231 *chip;
|
||||
card = platform_get_drvdata(dev);
|
||||
chip = card->private_data;
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_cs4231 *chip = card->private_data;
|
||||
|
||||
chip->resume(chip);
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SND_CS4231_DRIVER "snd_cs4231"
|
||||
|
||||
static struct platform_driver snd_cs4231_driver = {
|
||||
static struct isa_driver snd_cs4231_driver = {
|
||||
.match = snd_cs4231_match,
|
||||
.probe = snd_cs4231_probe,
|
||||
.remove = __devexit_p(snd_cs4231_remove),
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -181,57 +188,19 @@ static struct platform_driver snd_cs4231_driver = {
|
|||
.resume = snd_cs4231_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = SND_CS4231_DRIVER
|
||||
},
|
||||
.name = DEV_NAME
|
||||
}
|
||||
};
|
||||
|
||||
static void __init_or_module snd_cs4231_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_cs4231_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_cs4231_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_cs4231_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_CS4231_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "CS4231 soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_cs4231_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_cs4231_exit(void)
|
||||
{
|
||||
snd_cs4231_unregister_all();
|
||||
isa_unregister_driver(&snd_cs4231_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_cs4231_init)
|
||||
module_exit(alsa_card_cs4231_exit)
|
||||
module_init(alsa_card_cs4231_init);
|
||||
module_exit(alsa_card_cs4231_exit);
|
||||
|
|
|
@ -405,7 +405,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
|
|||
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
|
||||
int result = 0;
|
||||
unsigned int what;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
int do_start;
|
||||
|
||||
|
@ -425,8 +424,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
|
|||
}
|
||||
|
||||
what = 0;
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
if (s == chip->playback_substream) {
|
||||
what |= CS4231_PLAYBACK_ENABLE;
|
||||
snd_pcm_trigger_done(s, substream);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -75,10 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235},"
|
|||
|
||||
#ifdef CS4232
|
||||
#define IDENT "CS4232"
|
||||
#define CS423X_DRIVER "snd_cs4232"
|
||||
#define DEV_NAME "cs4232"
|
||||
#else
|
||||
#define IDENT "CS4236+"
|
||||
#define CS423X_DRIVER "snd_cs4236"
|
||||
#define DEV_NAME "cs4236"
|
||||
#endif
|
||||
|
||||
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
|
||||
|
@ -126,14 +126,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
|
|||
module_param_array(dma2, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnpc_registered;
|
||||
#ifdef CS4232
|
||||
static int pnp_registered;
|
||||
#endif
|
||||
#endif /* CONFIG_PNP */
|
||||
static unsigned int snd_cs423x_devices;
|
||||
|
||||
struct snd_card_cs4236 {
|
||||
struct snd_cs4231 *chip;
|
||||
|
@ -542,38 +540,55 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
|
|||
return snd_card_register(card);
|
||||
}
|
||||
|
||||
static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_cs423x_isa_match(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
if (!enable[dev] || is_isapnp_selected(dev))
|
||||
return 0;
|
||||
|
||||
if (port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "specify port\n");
|
||||
return -EINVAL;
|
||||
snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (cport[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "specify cport\n");
|
||||
return -EINVAL;
|
||||
snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (irq[dev] == SNDRV_AUTO_IRQ) {
|
||||
snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (dma1[dev] == SNDRV_AUTO_DMA) {
|
||||
snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_cs423x_isa_probe(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
|
||||
card = snd_cs423x_card_new(dev);
|
||||
if (! card)
|
||||
return -ENOMEM;
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
if ((err = snd_cs423x_probe(card, dev)) < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_cs423x_isa_remove(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(pdev));
|
||||
dev_set_drvdata(pdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -594,26 +609,28 @@ static int snd_cs423x_resume(struct snd_card *card)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
return snd_cs423x_suspend(platform_get_drvdata(dev));
|
||||
return snd_cs423x_suspend(dev_get_drvdata(dev));
|
||||
}
|
||||
|
||||
static int snd_cs423x_nonpnp_resume(struct platform_device *dev)
|
||||
static int snd_cs423x_isa_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
return snd_cs423x_resume(platform_get_drvdata(dev));
|
||||
return snd_cs423x_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver cs423x_nonpnp_driver = {
|
||||
.probe = snd_cs423x_nonpnp_probe,
|
||||
.remove = __devexit_p(snd_cs423x_nonpnp_remove),
|
||||
static struct isa_driver cs423x_isa_driver = {
|
||||
.match = snd_cs423x_isa_match,
|
||||
.probe = snd_cs423x_isa_probe,
|
||||
.remove = __devexit_p(snd_cs423x_isa_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_cs423x_nonpnp_suspend,
|
||||
.resume = snd_cs423x_nonpnp_resume,
|
||||
.suspend = snd_cs423x_isa_suspend,
|
||||
.resume = snd_cs423x_isa_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = CS423X_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -651,7 +668,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
|
|||
}
|
||||
pnp_set_drvdata(pdev, card);
|
||||
dev++;
|
||||
snd_cs423x_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -715,7 +731,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
|
|||
}
|
||||
pnp_set_card_drvdata(pcard, card);
|
||||
dev++;
|
||||
snd_cs423x_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -750,45 +765,13 @@ static struct pnp_card_driver cs423x_pnpc_driver = {
|
|||
};
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static void __init_or_module snd_cs423x_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnpc_registered)
|
||||
pnp_unregister_card_driver(&cs423x_pnpc_driver);
|
||||
#ifdef CS4232
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&cs4232_pnp_driver);
|
||||
#endif
|
||||
#endif /* CONFIG_PNP */
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&cs423x_nonpnp_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_cs423x_init(void)
|
||||
{
|
||||
int i, err;
|
||||
int err;
|
||||
|
||||
if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
|
||||
err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i] || is_isapnp_selected(i))
|
||||
continue;
|
||||
device = platform_device_register_simple(CS423X_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
snd_cs423x_devices++;
|
||||
}
|
||||
#ifdef CONFIG_PNP
|
||||
#ifdef CS4232
|
||||
err = pnp_register_driver(&cs4232_pnp_driver);
|
||||
|
@ -799,20 +782,20 @@ static int __init alsa_card_cs423x_init(void)
|
|||
if (!err)
|
||||
pnpc_registered = 1;
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
if (!snd_cs423x_devices) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR IDENT " soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_cs423x_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_cs423x_exit(void)
|
||||
{
|
||||
snd_cs423x_unregister_all();
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnpc_registered)
|
||||
pnp_unregister_card_driver(&cs423x_pnpc_driver);
|
||||
#ifdef CS4232
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&cs4232_pnp_driver);
|
||||
#endif
|
||||
#endif /* CONFIG_PNP */
|
||||
isa_unregister_driver(&cs423x_isa_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_cs423x_init)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -35,8 +35,11 @@
|
|||
#define SNDRV_LEGACY_FIND_FREE_DMA
|
||||
#include <sound/initval.h>
|
||||
|
||||
#define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive"
|
||||
#define DEV_NAME "es1688"
|
||||
|
||||
MODULE_DESCRIPTION(CRD_NAME);
|
||||
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
|
||||
MODULE_DESCRIPTION("ESS ESx688 AudioDrive");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
|
||||
"{ESS,ES1688 PnP AudioDrive,pnp:ESS0102},"
|
||||
|
@ -53,189 +56,157 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
|
|||
static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
|
||||
|
||||
module_param_array(index, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(index, "Index value for ESx688 soundcard.");
|
||||
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
|
||||
module_param_array(id, charp, NULL, 0444);
|
||||
MODULE_PARM_DESC(id, "ID string for ESx688 soundcard.");
|
||||
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
|
||||
module_param_array(enable, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(enable, "Enable ESx688 soundcard.");
|
||||
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
|
||||
module_param_array(port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(port, "Port # for ESx688 driver.");
|
||||
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
|
||||
module_param_array(mpu_port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ESx688 driver.");
|
||||
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
|
||||
module_param_array(irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(irq, "IRQ # for ESx688 driver.");
|
||||
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(mpu_irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver.");
|
||||
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(dma8, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
|
||||
MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
|
||||
#define PFX "es1688: "
|
||||
|
||||
static int __devinit snd_es1688_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
return enable[n];
|
||||
}
|
||||
|
||||
static int __devinit snd_es1688_legacy_create(struct snd_card *card,
|
||||
struct device *dev, unsigned int n, struct snd_es1688 **rchip)
|
||||
{
|
||||
static long possible_ports[] = {0x220, 0x240, 0x260};
|
||||
static int possible_irqs[] = {5, 9, 10, 7, -1};
|
||||
static int possible_dmas[] = {1, 3, 0, -1};
|
||||
int xirq, xdma, xmpu_irq;
|
||||
|
||||
int i, error;
|
||||
|
||||
if (irq[n] == SNDRV_AUTO_IRQ) {
|
||||
irq[n] = snd_legacy_find_free_irq(possible_irqs);
|
||||
if (irq[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
|
||||
dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
if (dma8[n] == SNDRV_AUTO_DMA) {
|
||||
dma8[n] = snd_legacy_find_free_dma(possible_dmas);
|
||||
if (dma8[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free DMA\n",
|
||||
dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (port[n] != SNDRV_AUTO_PORT)
|
||||
return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
|
||||
mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
port[n] = possible_ports[i];
|
||||
error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
|
||||
mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
|
||||
} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct snd_es1688 *chip;
|
||||
struct snd_opl3 *opl3;
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
||||
if (card == NULL)
|
||||
return -ENOMEM;
|
||||
card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
xirq = irq[dev];
|
||||
if (xirq == SNDRV_AUTO_IRQ) {
|
||||
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
|
||||
err = -EBUSY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
xmpu_irq = mpu_irq[dev];
|
||||
xdma = dma8[dev];
|
||||
if (xdma == SNDRV_AUTO_DMA) {
|
||||
if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
|
||||
err = -EBUSY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
error = snd_es1688_legacy_create(card, dev, n, &chip);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if (port[dev] != SNDRV_AUTO_PORT) {
|
||||
if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
|
||||
xirq, xmpu_irq, xdma,
|
||||
ES1688_HW_AUTO, &chip)) < 0)
|
||||
goto _err;
|
||||
} else {
|
||||
/* auto-probe legacy ports */
|
||||
static unsigned long possible_ports[] = {
|
||||
0x220, 0x240, 0x260,
|
||||
};
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
|
||||
err = snd_es1688_create(card, possible_ports[i],
|
||||
mpu_port[dev],
|
||||
xirq, xmpu_irq, xdma,
|
||||
ES1688_HW_AUTO, &chip);
|
||||
if (err >= 0) {
|
||||
port[dev] = possible_ports[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= ARRAY_SIZE(possible_ports))
|
||||
goto _err;
|
||||
}
|
||||
error = snd_es1688_pcm(chip, 0, &pcm);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
|
||||
goto _err;
|
||||
|
||||
if ((err = snd_es1688_mixer(chip)) < 0)
|
||||
goto _err;
|
||||
error = snd_es1688_mixer(chip);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
strcpy(card->driver, "ES1688");
|
||||
strcpy(card->shortname, pcm->name);
|
||||
sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);
|
||||
sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name,
|
||||
chip->port, chip->irq, chip->dma8);
|
||||
|
||||
if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
|
||||
printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port);
|
||||
} else {
|
||||
if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
|
||||
goto _err;
|
||||
if (snd_opl3_create(card, chip->port, chip->port + 2,
|
||||
OPL3_HW_OPL3, 0, &opl3) < 0)
|
||||
printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n",
|
||||
dev->bus_id, chip->port);
|
||||
else {
|
||||
error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
|
||||
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
|
||||
if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
|
||||
chip->mpu_port > 0) {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
|
||||
chip->mpu_port, 0,
|
||||
xmpu_irq,
|
||||
IRQF_DISABLED,
|
||||
NULL)) < 0)
|
||||
goto _err;
|
||||
mpu_irq[n], IRQF_DISABLED, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, dev);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto _err;
|
||||
error = snd_card_register(card);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(dev, card);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
out: snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit snd_es1688_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(dev));
|
||||
dev_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ES1688_DRIVER "snd_es1688"
|
||||
|
||||
static struct platform_driver snd_es1688_driver = {
|
||||
static struct isa_driver snd_es1688_driver = {
|
||||
.match = snd_es1688_match,
|
||||
.probe = snd_es1688_probe,
|
||||
.remove = __devexit_p(snd_es1688_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
.remove = snd_es1688_remove,
|
||||
#if 0 /* FIXME */
|
||||
.suspend = snd_es1688_suspend,
|
||||
.resume = snd_es1688_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = ES1688_DRIVER
|
||||
},
|
||||
.name = DEV_NAME
|
||||
}
|
||||
};
|
||||
|
||||
static void __init_or_module snd_es1688_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_es1688_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_es1688_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_es1688_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(ES1688_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_es1688_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_es1688_exit(void)
|
||||
{
|
||||
snd_es1688_unregister_all();
|
||||
isa_unregister_driver(&snd_es1688_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_es1688_init)
|
||||
module_exit(alsa_card_es1688_exit)
|
||||
module_init(alsa_card_es1688_init);
|
||||
module_exit(alsa_card_es1688_exit);
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/isapnp.h>
|
||||
|
@ -2035,8 +2035,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
|
|||
module_param_array(dma2, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered, pnpc_registered;
|
||||
|
||||
|
@ -2237,7 +2235,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
|
|||
return snd_card_register(card);
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
|
||||
static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
return enable[dev] && !is_isapnp_selected(dev);
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
|
@ -2245,18 +2248,17 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d
|
|||
card = snd_es18xx_card_new(dev);
|
||||
if (! card)
|
||||
return -ENOMEM;
|
||||
snd_card_set_dev(card, &devptr->dev);
|
||||
snd_card_set_dev(card, devptr);
|
||||
if ((err = snd_audiodrive_probe(card, dev)) < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
platform_set_drvdata(devptr, card);
|
||||
dev_set_drvdata(devptr, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
int err;
|
||||
static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
|
||||
static int possible_dmas[] = {1, 0, 3, 5, -1};
|
||||
|
@ -2281,13 +2283,13 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (port[dev] != SNDRV_AUTO_PORT) {
|
||||
return snd_es18xx_nonpnp_probe1(dev, pdev);
|
||||
return snd_es18xx_isa_probe1(dev, pdev);
|
||||
} else {
|
||||
static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280};
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
|
||||
port[dev] = possible_ports[i];
|
||||
err = snd_es18xx_nonpnp_probe1(dev, pdev);
|
||||
err = snd_es18xx_isa_probe1(dev, pdev);
|
||||
if (! err)
|
||||
return 0;
|
||||
}
|
||||
|
@ -2295,43 +2297,44 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_es18xx_isa_remove(struct device *devptr,
|
||||
unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
return snd_es18xx_suspend(platform_get_drvdata(dev), state);
|
||||
return snd_es18xx_suspend(dev_get_drvdata(dev), state);
|
||||
}
|
||||
|
||||
static int snd_es18xx_nonpnp_resume(struct platform_device *dev)
|
||||
static int snd_es18xx_isa_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
return snd_es18xx_resume(platform_get_drvdata(dev));
|
||||
return snd_es18xx_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ES18XX_DRIVER "snd_es18xx"
|
||||
#define DEV_NAME "es18xx"
|
||||
|
||||
static struct platform_driver snd_es18xx_nonpnp_driver = {
|
||||
.probe = snd_es18xx_nonpnp_probe,
|
||||
.remove = __devexit_p(snd_es18xx_nonpnp_remove),
|
||||
static struct isa_driver snd_es18xx_isa_driver = {
|
||||
.match = snd_es18xx_isa_match,
|
||||
.probe = snd_es18xx_isa_probe,
|
||||
.remove = __devexit_p(snd_es18xx_isa_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_es18xx_nonpnp_suspend,
|
||||
.resume = snd_es18xx_nonpnp_resume,
|
||||
.suspend = snd_es18xx_isa_suspend,
|
||||
.resume = snd_es18xx_isa_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = ES18XX_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static unsigned int __devinitdata es18xx_pnp_devices;
|
||||
|
||||
static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
|
||||
const struct pnp_device_id *id)
|
||||
{
|
||||
|
@ -2362,7 +2365,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
|
|||
}
|
||||
pnp_set_drvdata(pdev, card);
|
||||
dev++;
|
||||
es18xx_pnp_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2424,7 +2426,6 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
|
|||
|
||||
pnp_set_card_drvdata(pcard, card);
|
||||
dev++;
|
||||
es18xx_pnp_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2460,44 +2461,14 @@ static struct pnp_card_driver es18xx_pnpc_driver = {
|
|||
};
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static void __init_or_module snd_es18xx_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnpc_registered)
|
||||
pnp_unregister_card_driver(&es18xx_pnpc_driver);
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&es18xx_pnp_driver);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&snd_es18xx_nonpnp_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_es18xx_init(void)
|
||||
{
|
||||
int i, err, cards = 0;
|
||||
int err;
|
||||
|
||||
if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
|
||||
err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i] || is_isapnp_selected(i))
|
||||
continue;
|
||||
device = platform_device_register_simple(ES18XX_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
err = pnp_register_driver(&es18xx_pnp_driver);
|
||||
if (!err)
|
||||
|
@ -2505,22 +2476,19 @@ static int __init alsa_card_es18xx_init(void)
|
|||
err = pnp_register_card_driver(&es18xx_pnpc_driver);
|
||||
if (!err)
|
||||
pnpc_registered = 1;
|
||||
cards += es18xx_pnp_devices;
|
||||
#endif
|
||||
|
||||
if(!cards) {
|
||||
#ifdef MODULE
|
||||
snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_es18xx_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_es18xx_exit(void)
|
||||
{
|
||||
snd_es18xx_unregister_all();
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnpc_registered)
|
||||
pnp_unregister_card_driver(&es18xx_pnpc_driver);
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&es18xx_pnp_driver);
|
||||
#endif
|
||||
isa_unregister_driver(&snd_es18xx_isa_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_es18xx_init)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -33,8 +33,11 @@
|
|||
#define SNDRV_LEGACY_FIND_FREE_DMA
|
||||
#include <sound/initval.h>
|
||||
|
||||
#define CRD_NAME "Gravis UltraSound Classic"
|
||||
#define DEV_NAME "gusclassic"
|
||||
|
||||
MODULE_DESCRIPTION(CRD_NAME);
|
||||
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
|
||||
MODULE_DESCRIPTION("Gravis UltraSound Classic");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}");
|
||||
|
||||
|
@ -51,32 +54,80 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
|
|||
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
|
||||
|
||||
module_param_array(index, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard.");
|
||||
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
|
||||
module_param_array(id, charp, NULL, 0444);
|
||||
MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard.");
|
||||
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
|
||||
module_param_array(enable, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard.");
|
||||
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
|
||||
module_param_array(port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(port, "Port # for GUS Classic driver.");
|
||||
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
|
||||
module_param_array(irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver.");
|
||||
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(dma1, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver.");
|
||||
MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
|
||||
module_param_array(dma2, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver.");
|
||||
MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
|
||||
module_param_array(joystick_dac, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver.");
|
||||
MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
|
||||
module_param_array(channels, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver.");
|
||||
MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
|
||||
module_param_array(pcm_channels, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
|
||||
MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n)
|
||||
{
|
||||
return enable[n];
|
||||
}
|
||||
|
||||
static int __devinit snd_gusclassic_create(struct snd_card *card,
|
||||
struct device *dev, unsigned int n, struct snd_gus_card **rgus)
|
||||
{
|
||||
static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260};
|
||||
static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
|
||||
static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
|
||||
|
||||
#define PFX "gusclassic: "
|
||||
int i, error;
|
||||
|
||||
static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
|
||||
if (irq[n] == SNDRV_AUTO_IRQ) {
|
||||
irq[n] = snd_legacy_find_free_irq(possible_irqs);
|
||||
if (irq[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
|
||||
dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
if (dma1[n] == SNDRV_AUTO_DMA) {
|
||||
dma1[n] = snd_legacy_find_free_dma(possible_dmas);
|
||||
if (dma1[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free DMA1\n",
|
||||
dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
if (dma2[n] == SNDRV_AUTO_DMA) {
|
||||
dma2[n] = snd_legacy_find_free_dma(possible_dmas);
|
||||
if (dma2[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free DMA2\n",
|
||||
dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (port[n] != SNDRV_AUTO_PORT)
|
||||
return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
|
||||
0, channels[n], pcm_channels[n], 0, rgus);
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
port[n] = possible_ports[i];
|
||||
error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
|
||||
0, channels[n], pcm_channels[n], 0, rgus);
|
||||
} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus)
|
||||
{
|
||||
unsigned char d;
|
||||
|
||||
|
@ -95,187 +146,104 @@ static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __devinit snd_gusclassic_init(int dev, struct snd_gus_card * gus)
|
||||
static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n)
|
||||
{
|
||||
gus->equal_irq = 0;
|
||||
gus->codec_flag = 0;
|
||||
gus->max_flag = 0;
|
||||
gus->joystick_dac = joystick_dac[dev];
|
||||
}
|
||||
|
||||
static int __devinit snd_gusclassic_probe(struct platform_device *pdev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
|
||||
static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
|
||||
int xirq, xdma1, xdma2;
|
||||
struct snd_card *card;
|
||||
struct snd_gus_card *gus = NULL;
|
||||
int err;
|
||||
struct snd_gus_card *gus;
|
||||
int error;
|
||||
|
||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
||||
if (card == NULL)
|
||||
return -ENOMEM;
|
||||
if (pcm_channels[dev] < 2)
|
||||
pcm_channels[dev] = 2;
|
||||
card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
xirq = irq[dev];
|
||||
if (xirq == SNDRV_AUTO_IRQ) {
|
||||
if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
|
||||
err = -EBUSY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
xdma1 = dma1[dev];
|
||||
if (xdma1 == SNDRV_AUTO_DMA) {
|
||||
if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
|
||||
err = -EBUSY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
xdma2 = dma2[dev];
|
||||
if (xdma2 == SNDRV_AUTO_DMA) {
|
||||
if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
|
||||
err = -EBUSY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
if (pcm_channels[n] < 2)
|
||||
pcm_channels[n] = 2;
|
||||
|
||||
if (port[dev] != SNDRV_AUTO_PORT) {
|
||||
err = snd_gus_create(card,
|
||||
port[dev],
|
||||
xirq, xdma1, xdma2,
|
||||
0, channels[dev], pcm_channels[dev],
|
||||
0, &gus);
|
||||
} else {
|
||||
/* auto-probe legacy ports */
|
||||
static unsigned long possible_ports[] = {
|
||||
0x220, 0x230, 0x240, 0x250, 0x260,
|
||||
};
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
|
||||
err = snd_gus_create(card,
|
||||
possible_ports[i],
|
||||
xirq, xdma1, xdma2,
|
||||
0, channels[dev], pcm_channels[dev],
|
||||
0, &gus);
|
||||
if (err >= 0) {
|
||||
port[dev] = possible_ports[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err < 0)
|
||||
goto _err;
|
||||
error = snd_gusclassic_create(card, dev, n, &gus);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_gusclassic_detect(gus)) < 0)
|
||||
goto _err;
|
||||
error = snd_gusclassic_detect(gus);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
snd_gusclassic_init(dev, gus);
|
||||
if ((err = snd_gus_initialize(gus)) < 0)
|
||||
goto _err;
|
||||
gus->joystick_dac = joystick_dac[n];
|
||||
|
||||
error = snd_gus_initialize(gus);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
error = -ENODEV;
|
||||
if (gus->max_flag || gus->ess_flag) {
|
||||
snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
|
||||
err = -ENODEV;
|
||||
goto _err;
|
||||
snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was "
|
||||
"not detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((err = snd_gf1_new_mixer(gus)) < 0)
|
||||
goto _err;
|
||||
error = snd_gf1_new_mixer(gus);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0)
|
||||
goto _err;
|
||||
error = snd_gf1_pcm_new(gus, 0, 0, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if (!gus->ace_flag) {
|
||||
if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
|
||||
goto _err;
|
||||
error = snd_gf1_rawmidi_new(gus, 0, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
}
|
||||
sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1);
|
||||
if (xdma2 >= 0)
|
||||
sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
|
||||
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
sprintf(card->longname + strlen(card->longname),
|
||||
" at 0x%lx, irq %d, dma %d",
|
||||
gus->gf1.port, gus->gf1.irq, gus->gf1.dma1);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto _err;
|
||||
if (gus->gf1.dma2 >= 0)
|
||||
sprintf(card->longname + strlen(card->longname),
|
||||
"&%d", gus->gf1.dma2);
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
snd_card_set_dev(card, dev);
|
||||
|
||||
error = snd_card_register(card);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
dev_set_drvdata(dev, card);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
out: snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit snd_gusclassic_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(dev));
|
||||
dev_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GUSCLASSIC_DRIVER "snd_gusclassic"
|
||||
|
||||
static struct platform_driver snd_gusclassic_driver = {
|
||||
static struct isa_driver snd_gusclassic_driver = {
|
||||
.match = snd_gusclassic_match,
|
||||
.probe = snd_gusclassic_probe,
|
||||
.remove = __devexit_p(snd_gusclassic_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
#if 0 /* FIXME */
|
||||
.suspend = snd_gusclassic_suspend,
|
||||
.remove = snd_gusclassic_remove,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = GUSCLASSIC_DRIVER
|
||||
},
|
||||
.name = DEV_NAME
|
||||
}
|
||||
};
|
||||
|
||||
static void __init_or_module snd_gusclassic_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_gusclassic_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_gusclassic_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_gusclassic_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(GUSCLASSIC_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "GUS Classic soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_gusclassic_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_gusclassic_exit(void)
|
||||
{
|
||||
snd_gusclassic_unregister_all();
|
||||
isa_unregister_driver(&snd_gusclassic_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_gusclassic_init)
|
||||
module_exit(alsa_card_gusclassic_exit)
|
||||
module_init(alsa_card_gusclassic_init);
|
||||
module_exit(alsa_card_gusclassic_exit);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -37,8 +37,11 @@
|
|||
#define SNDRV_LEGACY_FIND_FREE_DMA
|
||||
#include <sound/initval.h>
|
||||
|
||||
#define CRD_NAME "Gravis UltraSound Extreme"
|
||||
#define DEV_NAME "gusextreme"
|
||||
|
||||
MODULE_DESCRIPTION(CRD_NAME);
|
||||
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
|
||||
MODULE_DESCRIPTION("Gravis UltraSound Extreme");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}");
|
||||
|
||||
|
@ -59,42 +62,106 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
|
|||
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
|
||||
|
||||
module_param_array(index, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard.");
|
||||
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
|
||||
module_param_array(id, charp, NULL, 0444);
|
||||
MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard.");
|
||||
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
|
||||
module_param_array(enable, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard.");
|
||||
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
|
||||
module_param_array(port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(port, "Port # for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
|
||||
module_param_array(gf1_port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional).");
|
||||
MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional).");
|
||||
module_param_array(mpu_port, long, NULL, 0444);
|
||||
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
|
||||
module_param_array(irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(mpu_irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(gf1_irq, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver.");
|
||||
module_param_array(dma8, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
|
||||
module_param_array(dma1, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver.");
|
||||
module_param_array(joystick_dac, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
|
||||
module_param_array(channels, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
|
||||
module_param_array(pcm_channels, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
|
||||
MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
|
||||
{
|
||||
return enable[n];
|
||||
}
|
||||
|
||||
static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
|
||||
struct device *dev, unsigned int n, struct snd_es1688 **rchip)
|
||||
{
|
||||
static long possible_ports[] = {0x220, 0x240, 0x260};
|
||||
static int possible_irqs[] = {5, 9, 10, 7, -1};
|
||||
static int possible_dmas[] = {1, 3, 0, -1};
|
||||
|
||||
#define PFX "gusextreme: "
|
||||
int i, error;
|
||||
|
||||
static int __devinit snd_gusextreme_detect(int dev,
|
||||
struct snd_card *card,
|
||||
struct snd_gus_card * gus,
|
||||
if (irq[n] == SNDRV_AUTO_IRQ) {
|
||||
irq[n] = snd_legacy_find_free_irq(possible_irqs);
|
||||
if (irq[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free IRQ "
|
||||
"for ES1688\n", dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
if (dma8[n] == SNDRV_AUTO_DMA) {
|
||||
dma8[n] = snd_legacy_find_free_dma(possible_dmas);
|
||||
if (dma8[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free DMA "
|
||||
"for ES1688\n", dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (port[n] != SNDRV_AUTO_PORT)
|
||||
return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
|
||||
mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
port[n] = possible_ports[i];
|
||||
error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
|
||||
mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
|
||||
} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card,
|
||||
struct device *dev, unsigned int n, struct snd_gus_card **rgus)
|
||||
{
|
||||
static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1};
|
||||
static int possible_dmas[] = {5, 6, 7, 3, 1, -1};
|
||||
|
||||
if (gf1_irq[n] == SNDRV_AUTO_IRQ) {
|
||||
gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs);
|
||||
if (gf1_irq[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free IRQ "
|
||||
"for GF1\n", dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
if (dma1[n] == SNDRV_AUTO_DMA) {
|
||||
dma1[n] = snd_legacy_find_free_dma(possible_dmas);
|
||||
if (dma1[n] < 0) {
|
||||
snd_printk(KERN_ERR "%s: unable to find a free DMA "
|
||||
"for GF1\n", dev->bus_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1,
|
||||
0, channels[n], pcm_channels[n], 0, rgus);
|
||||
}
|
||||
|
||||
static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
|
||||
struct snd_es1688 *es1688)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -117,12 +184,13 @@ static int __devinit snd_gusextreme_detect(int dev,
|
|||
spin_lock_irqsave(&es1688->mixer_lock, flags);
|
||||
snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */
|
||||
spin_unlock_irqrestore(&es1688->mixer_lock, flags);
|
||||
|
||||
spin_lock_irqsave(&es1688->reg_lock, flags);
|
||||
outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
|
||||
outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
|
||||
outb(0, 0x201);
|
||||
outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
|
||||
outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
|
||||
outb(0, 0x201);
|
||||
outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
|
||||
outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
|
||||
spin_unlock_irqrestore(&es1688->reg_lock, flags);
|
||||
|
||||
udelay(100);
|
||||
|
@ -139,253 +207,172 @@ static int __devinit snd_gusextreme_detect(int dev,
|
|||
snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __devinit snd_gusextreme_init(int dev, struct snd_gus_card * gus)
|
||||
{
|
||||
gus->joystick_dac = joystick_dac[dev];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip)
|
||||
{
|
||||
struct snd_card *card = chip->card;
|
||||
struct snd_ctl_elem_id id1, id2;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&id1, 0, sizeof(id1));
|
||||
memset(&id2, 0, sizeof(id2));
|
||||
id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||
|
||||
/* reassign AUX to SYNTHESIZER */
|
||||
strcpy(id1.name, "Aux Playback Volume");
|
||||
strcpy(id2.name, "Synth Playback Volume");
|
||||
if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
|
||||
return err;
|
||||
error = snd_ctl_rename_id(card, &id1, &id2);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
/* reassign Master Playback Switch to Synth Playback Switch */
|
||||
strcpy(id1.name, "Master Playback Switch");
|
||||
strcpy(id2.name, "Synth Playback Switch");
|
||||
if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
|
||||
return err;
|
||||
error = snd_ctl_rename_id(card, &id1, &id2);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit snd_gusextreme_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
|
||||
static int possible_ess_dmas[] = {1, 3, 0, -1};
|
||||
static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
|
||||
static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
|
||||
int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
|
||||
struct snd_card *card;
|
||||
struct snd_gus_card *gus;
|
||||
struct snd_es1688 *es1688;
|
||||
struct snd_opl3 *opl3;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
||||
if (card == NULL)
|
||||
return -ENOMEM;
|
||||
card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
xgf1_irq = gf1_irq[dev];
|
||||
if (xgf1_irq == SNDRV_AUTO_IRQ) {
|
||||
if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
xess_irq = irq[dev];
|
||||
if (xess_irq == SNDRV_AUTO_IRQ) {
|
||||
if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (mpu_port[dev] == SNDRV_AUTO_PORT)
|
||||
mpu_port[dev] = 0;
|
||||
xmpu_irq = mpu_irq[dev];
|
||||
if (xmpu_irq > 15)
|
||||
xmpu_irq = -1;
|
||||
xgf1_dma = dma1[dev];
|
||||
if (xgf1_dma == SNDRV_AUTO_DMA) {
|
||||
if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
xess_dma = dma8[dev];
|
||||
if (xess_dma == SNDRV_AUTO_DMA) {
|
||||
if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
|
||||
snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (mpu_port[n] == SNDRV_AUTO_PORT)
|
||||
mpu_port[n] = 0;
|
||||
|
||||
if (port[dev] != SNDRV_AUTO_PORT) {
|
||||
err = snd_es1688_create(card, port[dev], mpu_port[dev],
|
||||
xess_irq, xmpu_irq, xess_dma,
|
||||
ES1688_HW_1688, &es1688);
|
||||
} else {
|
||||
/* auto-probe legacy ports */
|
||||
static unsigned long possible_ports[] = {0x220, 0x240, 0x260};
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
|
||||
err = snd_es1688_create(card,
|
||||
possible_ports[i],
|
||||
mpu_port[dev],
|
||||
xess_irq, xmpu_irq, xess_dma,
|
||||
ES1688_HW_1688, &es1688);
|
||||
if (err >= 0) {
|
||||
port[dev] = possible_ports[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err < 0)
|
||||
if (mpu_irq[n] > 15)
|
||||
mpu_irq[n] = -1;
|
||||
|
||||
error = snd_gusextreme_es1688_create(card, dev, n, &es1688);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if (gf1_port[dev] < 0)
|
||||
gf1_port[dev] = port[dev] + 0x20;
|
||||
if ((err = snd_gus_create(card,
|
||||
gf1_port[dev],
|
||||
xgf1_irq,
|
||||
xgf1_dma,
|
||||
-1,
|
||||
0, channels[dev],
|
||||
pcm_channels[dev], 0,
|
||||
&gus)) < 0)
|
||||
if (gf1_port[n] < 0)
|
||||
gf1_port[n] = es1688->port + 0x20;
|
||||
|
||||
error = snd_gusextreme_gus_card_create(card, dev, n, &gus);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0)
|
||||
error = snd_gusextreme_detect(gus, es1688);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
snd_gusextreme_init(dev, gus);
|
||||
if ((err = snd_gus_initialize(gus)) < 0)
|
||||
gus->joystick_dac = joystick_dac[n];
|
||||
|
||||
error = snd_gus_initialize(gus);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
error = -ENODEV;
|
||||
if (!gus->ess_flag) {
|
||||
snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
|
||||
err = -ENODEV;
|
||||
snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not "
|
||||
"detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
|
||||
goto out;
|
||||
}
|
||||
if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0)
|
||||
gus->codec_flag = 1;
|
||||
|
||||
error = snd_es1688_pcm(es1688, 0, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_es1688_mixer(es1688)) < 0)
|
||||
error = snd_es1688_mixer(es1688);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
snd_component_add(card, "ES1688");
|
||||
if (pcm_channels[dev] > 0) {
|
||||
if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
|
||||
|
||||
if (pcm_channels[n] > 0) {
|
||||
error = snd_gf1_pcm_new(gus, 1, 1, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
}
|
||||
if ((err = snd_gf1_new_mixer(gus)) < 0)
|
||||
|
||||
error = snd_gf1_new_mixer(gus);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if ((err = snd_gusextreme_mixer(es1688)) < 0)
|
||||
error = snd_gusextreme_mixer(es1688);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if (snd_opl3_create(card, es1688->port, es1688->port + 2,
|
||||
OPL3_HW_OPL3, 0, &opl3) < 0) {
|
||||
printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
|
||||
} else {
|
||||
if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
|
||||
OPL3_HW_OPL3, 0, &opl3) < 0)
|
||||
printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n",
|
||||
dev->bus_id, es1688->port);
|
||||
else {
|
||||
error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (es1688->mpu_port >= 0x300 &&
|
||||
(err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
|
||||
if (es1688->mpu_port >= 0x300) {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
|
||||
es1688->mpu_port, 0,
|
||||
xmpu_irq,
|
||||
IRQF_DISABLED,
|
||||
NULL)) < 0)
|
||||
mpu_irq[n], IRQF_DISABLED, NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, "
|
||||
"irq %i&%i, dma %i&%i", es1688->port,
|
||||
gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8);
|
||||
|
||||
snd_card_set_dev(card, dev);
|
||||
|
||||
error = snd_card_register(card);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
|
||||
es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
|
||||
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto out;
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(dev, card);
|
||||
return 0;
|
||||
|
||||
out:
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
out: snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit snd_gusextreme_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(dev));
|
||||
dev_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GUSEXTREME_DRIVER "snd_gusextreme"
|
||||
|
||||
static struct platform_driver snd_gusextreme_driver = {
|
||||
static struct isa_driver snd_gusextreme_driver = {
|
||||
.match = snd_gusextreme_match,
|
||||
.probe = snd_gusextreme_probe,
|
||||
.remove = __devexit_p(snd_gusextreme_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
.remove = snd_gusextreme_remove,
|
||||
#if 0 /* FIXME */
|
||||
.suspend = snd_gusextreme_suspend,
|
||||
.resume = snd_gusextreme_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = GUSEXTREME_DRIVER
|
||||
},
|
||||
.name = DEV_NAME
|
||||
}
|
||||
};
|
||||
|
||||
static void __init_or_module snd_gusextreme_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_gusextreme_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_gusextreme_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_gusextreme_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(GUSEXTREME_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_gusextreme_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_gusextreme_exit(void)
|
||||
{
|
||||
snd_gusextreme_unregister_all();
|
||||
isa_unregister_driver(&snd_gusextreme_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_gusextreme_init)
|
||||
module_exit(alsa_card_gusextreme_exit)
|
||||
module_init(alsa_card_gusextreme_init);
|
||||
module_exit(alsa_card_gusextreme_exit);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -72,8 +72,6 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver.");
|
|||
module_param_array(pcm_channels, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
|
||||
struct snd_gusmax {
|
||||
int irq;
|
||||
struct snd_card *card;
|
||||
|
@ -205,9 +203,13 @@ static void snd_gusmax_free(struct snd_card *card)
|
|||
free_irq(maxcard->irq, (void *)maxcard);
|
||||
}
|
||||
|
||||
static int __devinit snd_gusmax_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
return enable[dev];
|
||||
}
|
||||
|
||||
static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
|
||||
static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
|
||||
int xirq, xdma1, xdma2, err;
|
||||
|
@ -333,7 +335,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
|
|||
if (xdma2 >= 0)
|
||||
sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
|
||||
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto _err;
|
||||
|
@ -341,7 +343,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
|
|||
maxcard->gus = gus;
|
||||
maxcard->cs4231 = cs4231;
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
|
@ -349,70 +351,33 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int __devexit snd_gusmax_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GUSMAX_DRIVER "snd_gusmax"
|
||||
#define DEV_NAME "gusmax"
|
||||
|
||||
static struct platform_driver snd_gusmax_driver = {
|
||||
static struct isa_driver snd_gusmax_driver = {
|
||||
.match = snd_gusmax_match,
|
||||
.probe = snd_gusmax_probe,
|
||||
.remove = __devexit_p(snd_gusmax_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
.driver = {
|
||||
.name = GUSMAX_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
static void __init_or_module snd_gusmax_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_gusmax_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_gusmax_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_gusmax_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(GUSMAX_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "GUS MAX soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_gusmax_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_gusmax_exit(void)
|
||||
{
|
||||
snd_gusmax_unregister_all();
|
||||
isa_unregister_driver(&snd_gusmax_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_gusmax_init)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
|
@ -115,9 +115,6 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver.");
|
|||
module_param_array(effect, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
static int pnp_registered;
|
||||
|
||||
struct snd_interwave {
|
||||
int irq;
|
||||
struct snd_card *card;
|
||||
|
@ -138,6 +135,7 @@ struct snd_interwave {
|
|||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered;
|
||||
|
||||
static struct pnp_card_device_id snd_interwave_pnpids[] = {
|
||||
#ifndef SNDRV_STB
|
||||
|
@ -793,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr)
|
||||
static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
|
@ -802,18 +800,30 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device
|
|||
if (! card)
|
||||
return -ENOMEM;
|
||||
|
||||
snd_card_set_dev(card, &devptr->dev);
|
||||
snd_card_set_dev(card, devptr);
|
||||
if ((err = snd_interwave_probe(card, dev)) < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
platform_set_drvdata(devptr, card);
|
||||
dev_set_drvdata(devptr, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_interwave_isa_match(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
if (!enable[dev])
|
||||
return 0;
|
||||
#ifdef CONFIG_PNP
|
||||
if (isapnp[dev])
|
||||
return 0;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_interwave_isa_probe(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
int err;
|
||||
static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
|
||||
static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
|
||||
|
@ -838,13 +848,13 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (port[dev] != SNDRV_AUTO_PORT)
|
||||
return snd_interwave_nonpnp_probe1(dev, pdev);
|
||||
return snd_interwave_isa_probe1(dev, pdev);
|
||||
else {
|
||||
static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
|
||||
port[dev] = possible_ports[i];
|
||||
err = snd_interwave_nonpnp_probe1(dev, pdev);
|
||||
err = snd_interwave_isa_probe1(dev, pdev);
|
||||
if (! err)
|
||||
return 0;
|
||||
}
|
||||
|
@ -852,16 +862,17 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver snd_interwave_driver = {
|
||||
.probe = snd_interwave_nonpnp_probe,
|
||||
.remove = __devexit_p(snd_interwave_nonpnp_remove),
|
||||
static struct isa_driver snd_interwave_driver = {
|
||||
.match = snd_interwave_isa_match,
|
||||
.probe = snd_interwave_isa_probe,
|
||||
.remove = __devexit_p(snd_interwave_isa_remove),
|
||||
/* FIXME: suspend,resume */
|
||||
.driver = {
|
||||
.name = INTERWAVE_DRIVER
|
||||
|
@ -869,8 +880,6 @@ static struct platform_driver snd_interwave_driver = {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static unsigned int __devinitdata interwave_pnp_devices;
|
||||
|
||||
static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
|
||||
const struct pnp_card_device_id *pid)
|
||||
{
|
||||
|
@ -900,7 +909,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
|
|||
}
|
||||
pnp_set_card_drvdata(pcard, card);
|
||||
dev++;
|
||||
interwave_pnp_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -921,64 +929,29 @@ static struct pnp_card_driver interwave_pnpc_driver = {
|
|||
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static void __init_or_module snd_interwave_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&interwave_pnpc_driver);
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&snd_interwave_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_interwave_init(void)
|
||||
{
|
||||
int i, err, cards = 0;
|
||||
int err;
|
||||
|
||||
if ((err = platform_driver_register(&snd_interwave_driver)) < 0)
|
||||
err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
#ifdef CONFIG_PNP
|
||||
if (isapnp[i])
|
||||
continue;
|
||||
#endif
|
||||
device = platform_device_register_simple(INTERWAVE_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
|
||||
/* ISA PnP cards */
|
||||
err = pnp_register_card_driver(&interwave_pnpc_driver);
|
||||
if (!err) {
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
cards += interwave_pnp_devices;;
|
||||
}
|
||||
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "InterWave soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_interwave_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_interwave_exit(void)
|
||||
{
|
||||
snd_interwave_unregister_all();
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&interwave_pnpc_driver);
|
||||
#endif
|
||||
isa_unregister_driver(&snd_interwave_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_interwave_init)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -91,12 +91,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
|
|||
module_param_array(opl3sa3_ymode, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered;
|
||||
static int pnpc_registered;
|
||||
#endif
|
||||
static unsigned int snd_opl3sa2_devices;
|
||||
|
||||
/* control ports */
|
||||
#define OPL3SA2_PM_CTRL 0x01
|
||||
|
@ -783,7 +781,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
|
|||
}
|
||||
pnp_set_drvdata(pdev, card);
|
||||
dev++;
|
||||
snd_opl3sa2_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -850,7 +847,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
|
|||
}
|
||||
pnp_set_card_drvdata(pcard, card);
|
||||
dev++;
|
||||
snd_opl3sa2_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -884,116 +880,95 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = {
|
|||
};
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_opl3sa2_isa_match(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
int dev = pdev->id;
|
||||
|
||||
if (!enable[dev])
|
||||
return 0;
|
||||
#ifdef CONFIG_PNP
|
||||
if (isapnp[dev])
|
||||
return 0;
|
||||
#endif
|
||||
if (port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify port\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (wss_port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify wss_port\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (fm_port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify fm_port\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (midi_port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify midi_port\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_opl3sa2_isa_probe(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
|
||||
card = snd_opl3sa2_card_new(dev);
|
||||
if (! card)
|
||||
return -ENOMEM;
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit snd_opl3sa2_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_opl3sa2_isa_remove(struct device *devptr,
|
||||
unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
return snd_opl3sa2_suspend(platform_get_drvdata(dev), state);
|
||||
return snd_opl3sa2_suspend(dev_get_drvdata(dev), state);
|
||||
}
|
||||
|
||||
static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev)
|
||||
static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
return snd_opl3sa2_resume(platform_get_drvdata(dev));
|
||||
return snd_opl3sa2_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define OPL3SA2_DRIVER "snd_opl3sa2"
|
||||
#define DEV_NAME "opl3sa2"
|
||||
|
||||
static struct platform_driver snd_opl3sa2_nonpnp_driver = {
|
||||
.probe = snd_opl3sa2_nonpnp_probe,
|
||||
.remove = __devexit( snd_opl3sa2_nonpnp_remove),
|
||||
static struct isa_driver snd_opl3sa2_isa_driver = {
|
||||
.match = snd_opl3sa2_isa_match,
|
||||
.probe = snd_opl3sa2_isa_probe,
|
||||
.remove = __devexit( snd_opl3sa2_isa_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_opl3sa2_nonpnp_suspend,
|
||||
.resume = snd_opl3sa2_nonpnp_resume,
|
||||
.suspend = snd_opl3sa2_isa_suspend,
|
||||
.resume = snd_opl3sa2_isa_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = OPL3SA2_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
static void __init_or_module snd_opl3sa2_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnpc_registered)
|
||||
pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&opl3sa2_pnp_driver);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_opl3sa2_init(void)
|
||||
{
|
||||
int i, err;
|
||||
int err;
|
||||
|
||||
if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
|
||||
err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
#ifdef CONFIG_PNP
|
||||
if (isapnp[i])
|
||||
continue;
|
||||
#endif
|
||||
device = platform_device_register_simple(OPL3SA2_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
snd_opl3sa2_devices++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
err = pnp_register_driver(&opl3sa2_pnp_driver);
|
||||
if (!err)
|
||||
|
@ -1002,20 +977,18 @@ static int __init alsa_card_opl3sa2_init(void)
|
|||
if (!err)
|
||||
pnpc_registered = 1;
|
||||
#endif
|
||||
|
||||
if (!snd_opl3sa2_devices) {
|
||||
#ifdef MODULE
|
||||
snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_opl3sa2_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_opl3sa2_exit(void)
|
||||
{
|
||||
snd_opl3sa2_unregister_all();
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnpc_registered)
|
||||
pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&opl3sa2_pnp_driver);
|
||||
#endif
|
||||
isa_unregister_driver(&snd_opl3sa2_isa_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_opl3sa2_init)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ioport.h>
|
||||
|
@ -137,10 +137,6 @@ struct snd_miro {
|
|||
|
||||
static void snd_miro_proc_init(struct snd_miro * miro);
|
||||
|
||||
#define DRIVER_NAME "snd-miro"
|
||||
|
||||
static struct platform_device *device;
|
||||
|
||||
static char * snd_opti9xx_names[] = {
|
||||
"unkown",
|
||||
"82C928", "82C929",
|
||||
|
@ -558,7 +554,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
|
|||
return change;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new snd_miro_controls[] = {
|
||||
static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = {
|
||||
MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
|
||||
MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
|
||||
MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
|
||||
|
@ -570,7 +566,7 @@ MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2),
|
|||
|
||||
/* Equalizer with seven bands (only PCM20)
|
||||
from -12dB up to +12dB on each band */
|
||||
static struct snd_kcontrol_new snd_miro_eq_controls[] = {
|
||||
static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = {
|
||||
MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
|
||||
MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
|
||||
MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
|
||||
|
@ -580,15 +576,15 @@ MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6),
|
|||
MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new snd_miro_radio_control[] = {
|
||||
static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = {
|
||||
MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new snd_miro_line_control[] = {
|
||||
static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = {
|
||||
MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new snd_miro_preamp_control[] = {
|
||||
static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Mic Boost",
|
||||
|
@ -598,7 +594,7 @@ static struct snd_kcontrol_new snd_miro_preamp_control[] = {
|
|||
.put = snd_miro_put_preamp,
|
||||
}};
|
||||
|
||||
static struct snd_kcontrol_new snd_miro_amp_control[] = {
|
||||
static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Line Boost",
|
||||
|
@ -608,7 +604,7 @@ static struct snd_kcontrol_new snd_miro_amp_control[] = {
|
|||
.put = snd_miro_put_amp,
|
||||
}};
|
||||
|
||||
static struct snd_kcontrol_new snd_miro_capture_control[] = {
|
||||
static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "PCM Capture Switch",
|
||||
|
@ -618,7 +614,7 @@ static struct snd_kcontrol_new snd_miro_capture_control[] = {
|
|||
.put = snd_miro_put_capture,
|
||||
}};
|
||||
|
||||
static unsigned char aci_init_values[][2] __initdata = {
|
||||
static unsigned char aci_init_values[][2] __devinitdata = {
|
||||
{ ACI_SET_MUTE, 0x00 },
|
||||
{ ACI_SET_POWERAMP, 0x00 },
|
||||
{ ACI_SET_PREAMP, 0x00 },
|
||||
|
@ -641,7 +637,7 @@ static unsigned char aci_init_values[][2] __initdata = {
|
|||
{ ACI_SET_MASTER + 1, 0x20 },
|
||||
};
|
||||
|
||||
static int __init snd_set_aci_init_values(struct snd_miro *miro)
|
||||
static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
|
||||
{
|
||||
int idx, error;
|
||||
|
||||
|
@ -751,7 +747,8 @@ static long snd_legacy_find_free_ioport(long *port_table, long size)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware)
|
||||
static int __devinit snd_miro_init(struct snd_miro *chip,
|
||||
unsigned short hardware)
|
||||
{
|
||||
static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
|
||||
|
||||
|
@ -962,7 +959,7 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
|
|||
snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp);
|
||||
}
|
||||
|
||||
static void __init snd_miro_proc_init(struct snd_miro * miro)
|
||||
static void __devinit snd_miro_proc_init(struct snd_miro * miro)
|
||||
{
|
||||
struct snd_info_entry *entry;
|
||||
|
||||
|
@ -974,7 +971,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro)
|
|||
* Init
|
||||
*/
|
||||
|
||||
static int __init snd_miro_configure(struct snd_miro *chip)
|
||||
static int __devinit snd_miro_configure(struct snd_miro *chip)
|
||||
{
|
||||
unsigned char wss_base_bits;
|
||||
unsigned char irq_bits;
|
||||
|
@ -1131,7 +1128,8 @@ __skip_mpu:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip)
|
||||
static int __devinit snd_card_miro_detect(struct snd_card *card,
|
||||
struct snd_miro *chip)
|
||||
{
|
||||
int i, err;
|
||||
unsigned char value;
|
||||
|
@ -1157,7 +1155,8 @@ static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *c
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro)
|
||||
static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
|
||||
struct snd_miro * miro)
|
||||
{
|
||||
unsigned char regval;
|
||||
int i;
|
||||
|
@ -1213,7 +1212,12 @@ static void snd_card_miro_free(struct snd_card *card)
|
|||
release_and_free_resource(miro->res_mc_base);
|
||||
}
|
||||
|
||||
static int __init snd_miro_probe(struct platform_device *devptr)
|
||||
static int __devinit snd_miro_match(struct device *devptr, unsigned int n)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
|
||||
{
|
||||
static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
|
||||
static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
|
||||
|
@ -1399,56 +1403,44 @@ static int __init snd_miro_probe(struct platform_device *devptr)
|
|||
return error;
|
||||
}
|
||||
|
||||
snd_card_set_dev(card, &devptr->dev);
|
||||
snd_card_set_dev(card, devptr);
|
||||
|
||||
if ((error = snd_card_register(card))) {
|
||||
snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
|
||||
platform_set_drvdata(devptr, card);
|
||||
dev_set_drvdata(devptr, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit snd_miro_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver snd_miro_driver = {
|
||||
#define DEV_NAME "miro"
|
||||
|
||||
static struct isa_driver snd_miro_driver = {
|
||||
.match = snd_miro_match,
|
||||
.probe = snd_miro_probe,
|
||||
.remove = __devexit_p(snd_miro_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
.driver = {
|
||||
.name = DRIVER_NAME
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
static int __init alsa_card_miro_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = platform_driver_register(&snd_miro_driver)) < 0)
|
||||
return error;
|
||||
device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
|
||||
if (! IS_ERR(device)) {
|
||||
if (platform_get_drvdata(device))
|
||||
return 0;
|
||||
platform_device_unregister(device);
|
||||
}
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "no miro soundcard found\n");
|
||||
#endif
|
||||
platform_driver_unregister(&snd_miro_driver);
|
||||
return PTR_ERR(device);
|
||||
return isa_register_driver(&snd_miro_driver, 1);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_miro_exit(void)
|
||||
{
|
||||
platform_device_unregister(device);
|
||||
platform_driver_unregister(&snd_miro_driver);
|
||||
isa_unregister_driver(&snd_miro_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_miro_init)
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
|
@ -259,7 +259,6 @@ struct snd_opti9xx {
|
|||
};
|
||||
|
||||
static int snd_opti9xx_pnp_is_probed;
|
||||
static struct platform_device *snd_opti9xx_platform_device;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
|
||||
|
@ -281,10 +280,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
|
|||
#endif /* CONFIG_PNP */
|
||||
|
||||
#ifdef OPTi93X
|
||||
#define DRIVER_NAME "snd-card-opti93x"
|
||||
#define DEV_NAME "opti93x"
|
||||
#else
|
||||
#define DRIVER_NAME "snd-card-opti92x"
|
||||
#endif /* OPTi93X */
|
||||
#define DEV_NAME "opti92x"
|
||||
#endif
|
||||
|
||||
static char * snd_opti9xx_names[] = {
|
||||
"unkown",
|
||||
|
@ -294,7 +293,7 @@ static char * snd_opti9xx_names[] = {
|
|||
};
|
||||
|
||||
|
||||
static long __init snd_legacy_find_free_ioport(long *port_table, long size)
|
||||
static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
|
||||
{
|
||||
while (*port_table != -1) {
|
||||
if (request_region(*port_table, size, "ALSA test")) {
|
||||
|
@ -306,7 +305,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware)
|
||||
static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
|
||||
unsigned short hardware)
|
||||
{
|
||||
static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
|
||||
|
||||
|
@ -451,7 +451,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
|
|||
(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
|
||||
|
||||
|
||||
static int __init snd_opti9xx_configure(struct snd_opti9xx *chip)
|
||||
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
|
||||
{
|
||||
unsigned char wss_base_bits;
|
||||
unsigned char irq_bits;
|
||||
|
@ -934,10 +934,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream,
|
|||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
{
|
||||
unsigned int what = 0;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
if (s == chip->playback_substream) {
|
||||
what |= OPTi93X_PLAYBACK_ENABLE;
|
||||
snd_pcm_trigger_done(s, substream);
|
||||
|
@ -1291,7 +1289,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip,
|
|||
}
|
||||
codec->dma2 = chip->dma2;
|
||||
|
||||
if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) {
|
||||
if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) {
|
||||
snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
|
||||
snd_opti93x_free(codec);
|
||||
return -EBUSY;
|
||||
|
@ -1561,7 +1559,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
|||
return change;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new snd_opti93x_controls[] = {
|
||||
static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = {
|
||||
OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
|
||||
OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
|
||||
OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
|
||||
|
@ -1622,7 +1620,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip)
|
|||
|
||||
#endif /* OPTi93X */
|
||||
|
||||
static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip)
|
||||
static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
|
||||
struct snd_opti9xx *chip)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
|
@ -1676,7 +1675,8 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card,
|
||||
static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
|
||||
struct pnp_card_link *card,
|
||||
const struct pnp_card_device_id *pid)
|
||||
{
|
||||
struct pnp_dev *pdev;
|
||||
|
@ -1778,7 +1778,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
|
|||
release_and_free_resource(chip->res_mc_base);
|
||||
}
|
||||
|
||||
static int __init snd_opti9xx_probe(struct snd_card *card)
|
||||
static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
||||
{
|
||||
static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
|
||||
int error;
|
||||
|
@ -1924,7 +1924,18 @@ static struct snd_card *snd_opti9xx_card_new(void)
|
|||
return card;
|
||||
}
|
||||
|
||||
static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
|
||||
static int __devinit snd_opti9xx_isa_match(struct device *devptr,
|
||||
unsigned int dev)
|
||||
{
|
||||
if (snd_opti9xx_pnp_is_probed)
|
||||
return 0;
|
||||
if (isapnp)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_opti9xx_isa_probe(struct device *devptr,
|
||||
unsigned int dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int error;
|
||||
|
@ -1940,9 +1951,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
|
|||
static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
|
||||
#endif /* CS4231 || OPTi93X */
|
||||
|
||||
if (snd_opti9xx_pnp_is_probed)
|
||||
return -EBUSY;
|
||||
|
||||
if (mpu_port == SNDRV_AUTO_PORT) {
|
||||
if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
|
||||
snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
|
||||
|
@ -1984,33 +1992,35 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
|
|||
snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
snd_card_set_dev(card, &devptr->dev);
|
||||
snd_card_set_dev(card, devptr);
|
||||
if ((error = snd_opti9xx_probe(card)) < 0) {
|
||||
snd_card_free(card);
|
||||
return error;
|
||||
}
|
||||
platform_set_drvdata(devptr, card);
|
||||
dev_set_drvdata(devptr, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
|
||||
unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver snd_opti9xx_driver = {
|
||||
.probe = snd_opti9xx_nonpnp_probe,
|
||||
.remove = __devexit_p(snd_opti9xx_nonpnp_remove),
|
||||
static struct isa_driver snd_opti9xx_driver = {
|
||||
.match = snd_opti9xx_isa_match,
|
||||
.probe = snd_opti9xx_isa_probe,
|
||||
.remove = __devexit_p(snd_opti9xx_isa_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
.driver = {
|
||||
.name = DRIVER_NAME
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
|
||||
static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
|
||||
const struct pnp_card_device_id *pid)
|
||||
{
|
||||
struct snd_card *card;
|
||||
|
@ -2074,11 +2084,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
#define is_isapnp_selected() isapnp
|
||||
#else
|
||||
#define is_isapnp_selected() 0
|
||||
#endif
|
||||
#ifdef OPTi93X
|
||||
#define CHIP_NAME "82C93x"
|
||||
#else
|
||||
|
@ -2087,42 +2092,19 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
|
|||
|
||||
static int __init alsa_card_opti9xx_init(void)
|
||||
{
|
||||
int error;
|
||||
struct platform_device *device;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
pnp_register_card_driver(&opti9xx_pnpc_driver);
|
||||
if (snd_opti9xx_pnp_is_probed)
|
||||
return 0;
|
||||
#endif
|
||||
if (! is_isapnp_selected()) {
|
||||
error = platform_driver_register(&snd_opti9xx_driver);
|
||||
if (error < 0)
|
||||
return error;
|
||||
device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
|
||||
if (!IS_ERR(device)) {
|
||||
if (platform_get_drvdata(device)) {
|
||||
snd_opti9xx_platform_device = device;
|
||||
return 0;
|
||||
}
|
||||
platform_device_unregister(device);
|
||||
}
|
||||
platform_driver_unregister(&snd_opti9xx_driver);
|
||||
}
|
||||
#ifdef CONFIG_PNP
|
||||
pnp_unregister_card_driver(&opti9xx_pnpc_driver);
|
||||
#endif
|
||||
#ifdef MODULE
|
||||
printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n");
|
||||
#endif
|
||||
return -ENODEV;
|
||||
return isa_register_driver(&snd_opti9xx_driver, 1);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_opti9xx_exit(void)
|
||||
{
|
||||
if (!snd_opti9xx_pnp_is_probed) {
|
||||
platform_device_unregister(snd_opti9xx_platform_device);
|
||||
platform_driver_unregister(&snd_opti9xx_driver);
|
||||
isa_unregister_driver(&snd_opti9xx_driver);
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_PNP
|
||||
pnp_unregister_card_driver(&opti9xx_pnpc_driver);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/sb.h>
|
||||
|
@ -128,7 +128,6 @@ module_param_array(seq_ports, int, NULL, 0444);
|
|||
MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
|
||||
#endif
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered;
|
||||
#endif
|
||||
|
@ -519,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr)
|
||||
static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev)
|
||||
{
|
||||
struct snd_card_sb16 *acard;
|
||||
struct snd_card *card;
|
||||
|
@ -539,19 +538,23 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev
|
|||
awe_port[dev] = port[dev] + 0x400;
|
||||
#endif
|
||||
|
||||
snd_card_set_dev(card, &devptr->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
if ((err = snd_sb16_probe(card, dev)) < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
platform_set_drvdata(devptr, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
return enable[dev] && !is_isapnp_selected(dev);
|
||||
}
|
||||
|
||||
static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
int err;
|
||||
static int possible_irqs[] = {5, 9, 10, 7, -1};
|
||||
static int possible_dmas8[] = {1, 3, 0, -1};
|
||||
|
@ -577,13 +580,13 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (port[dev] != SNDRV_AUTO_PORT)
|
||||
return snd_sb16_nonpnp_probe1(dev, pdev);
|
||||
return snd_sb16_isa_probe1(dev, pdev);
|
||||
else {
|
||||
static int possible_ports[] = {0x220, 0x240, 0x260, 0x280};
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
|
||||
port[dev] = possible_ports[i];
|
||||
err = snd_sb16_nonpnp_probe1(dev, pdev);
|
||||
err = snd_sb16_isa_probe1(dev, pdev);
|
||||
if (! err)
|
||||
return 0;
|
||||
}
|
||||
|
@ -591,47 +594,47 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(pdev));
|
||||
dev_set_drvdata(pdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int snd_sb16_isa_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
return snd_sb16_suspend(platform_get_drvdata(dev), state);
|
||||
return snd_sb16_suspend(dev_get_drvdata(dev), state);
|
||||
}
|
||||
|
||||
static int snd_sb16_nonpnp_resume(struct platform_device *dev)
|
||||
static int snd_sb16_isa_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
return snd_sb16_resume(platform_get_drvdata(dev));
|
||||
return snd_sb16_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SNDRV_SBAWE
|
||||
#define SND_SB16_DRIVER "snd_sbawe"
|
||||
#define DEV_NAME "sbawe"
|
||||
#else
|
||||
#define SND_SB16_DRIVER "snd_sb16"
|
||||
#define DEV_NAME "sb16"
|
||||
#endif
|
||||
|
||||
static struct platform_driver snd_sb16_nonpnp_driver = {
|
||||
.probe = snd_sb16_nonpnp_probe,
|
||||
.remove = __devexit_p(snd_sb16_nonpnp_remove),
|
||||
static struct isa_driver snd_sb16_isa_driver = {
|
||||
.match = snd_sb16_isa_match,
|
||||
.probe = snd_sb16_isa_probe,
|
||||
.remove = __devexit_p(snd_sb16_isa_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_sb16_nonpnp_suspend,
|
||||
.resume = snd_sb16_nonpnp_resume,
|
||||
.suspend = snd_sb16_isa_suspend,
|
||||
.resume = snd_sb16_isa_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = SND_SB16_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static unsigned int __devinitdata sb16_pnp_devices;
|
||||
|
||||
static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
|
||||
const struct pnp_card_device_id *pid)
|
||||
{
|
||||
|
@ -653,7 +656,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
|
|||
}
|
||||
pnp_set_card_drvdata(pcard, card);
|
||||
dev++;
|
||||
sb16_pnp_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -695,68 +697,29 @@ static struct pnp_card_driver sb16_pnpc_driver = {
|
|||
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static void __init_or_module snd_sb16_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&sb16_pnpc_driver);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&snd_sb16_nonpnp_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_sb16_init(void)
|
||||
{
|
||||
int i, err, cards = 0;
|
||||
int err;
|
||||
|
||||
if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0)
|
||||
err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i] || is_isapnp_selected(i))
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_SB16_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
#ifdef CONFIG_PNP
|
||||
/* PnP cards at last */
|
||||
err = pnp_register_card_driver(&sb16_pnpc_driver);
|
||||
if (!err) {
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
cards += sb16_pnp_devices;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");
|
||||
#ifdef SNDRV_SBAWE_EMU8000
|
||||
snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n");
|
||||
#else
|
||||
snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n");
|
||||
#endif
|
||||
#endif
|
||||
snd_sb16_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_sb16_exit(void)
|
||||
{
|
||||
snd_sb16_unregister_all();
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&sb16_pnpc_driver);
|
||||
#endif
|
||||
isa_unregister_driver(&snd_sb16_isa_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_sb16_init)
|
||||
|
|
|
@ -36,6 +36,13 @@
|
|||
MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
|
||||
MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor");
|
||||
MODULE_LICENSE("GPL");
|
||||
#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
MODULE_FIRMWARE("sb16/mulaw_main.csp");
|
||||
MODULE_FIRMWARE("sb16/alaw_main.csp");
|
||||
MODULE_FIRMWARE("sb16/ima_adpcm_init.csp");
|
||||
MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp");
|
||||
MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
|
||||
#endif
|
||||
|
||||
#ifdef SNDRV_LITTLE_ENDIAN
|
||||
#define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
|
||||
|
@ -161,13 +168,17 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
|
|||
*/
|
||||
static void snd_sb_csp_free(struct snd_hwdep *hwdep)
|
||||
{
|
||||
#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
int i;
|
||||
#endif
|
||||
struct snd_sb_csp *p = hwdep->private_data;
|
||||
if (p) {
|
||||
if (p->running & SNDRV_SB_CSP_ST_RUNNING)
|
||||
snd_sb_csp_stop(p);
|
||||
#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i)
|
||||
release_firmware(p->csp_programs[i]);
|
||||
#endif
|
||||
kfree(p);
|
||||
}
|
||||
}
|
||||
|
@ -690,9 +701,7 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use
|
|||
return err;
|
||||
}
|
||||
|
||||
#define FIRMWARE_IN_THE_KERNEL
|
||||
|
||||
#ifdef FIRMWARE_IN_THE_KERNEL
|
||||
#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
#include "sb16_csp_codecs.h"
|
||||
|
||||
static const struct firmware snd_sb_csp_static_programs[] = {
|
||||
|
@ -714,22 +723,19 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
|
|||
"sb16/ima_adpcm_capture.csp",
|
||||
};
|
||||
const struct firmware *program;
|
||||
int err;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT);
|
||||
program = p->csp_programs[index];
|
||||
if (!program) {
|
||||
err = request_firmware(&program, names[index],
|
||||
p->chip->card->dev);
|
||||
if (err >= 0)
|
||||
p->csp_programs[index] = program;
|
||||
else {
|
||||
#ifdef FIRMWARE_IN_THE_KERNEL
|
||||
#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
|
||||
program = &snd_sb_csp_static_programs[index];
|
||||
#else
|
||||
int err = request_firmware(&program, names[index],
|
||||
p->chip->card->dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
p->csp_programs[index] = program;
|
||||
}
|
||||
return snd_sb_csp_load(p, program->data, program->size, flags);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -56,8 +56,6 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
|
|||
module_param_array(dma8, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
|
||||
struct snd_sb8 {
|
||||
struct resource *fm_res; /* used to block FM i/o region for legacy cards */
|
||||
struct snd_sb *chip;
|
||||
|
@ -83,9 +81,23 @@ static void snd_sb8_free(struct snd_card *card)
|
|||
release_and_free_resource(acard->fm_res);
|
||||
}
|
||||
|
||||
static int __devinit snd_sb8_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
if (!enable[dev])
|
||||
return 0;
|
||||
if (irq[dev] == SNDRV_AUTO_IRQ) {
|
||||
snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
if (dma8[dev] == SNDRV_AUTO_DMA) {
|
||||
snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
struct snd_sb *chip;
|
||||
struct snd_card *card;
|
||||
struct snd_sb8 *acard;
|
||||
|
@ -180,12 +192,12 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
|
|||
chip->port,
|
||||
irq[dev], dma8[dev]);
|
||||
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto _err;
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
|
@ -193,17 +205,18 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int __devexit snd_sb8_remove(struct platform_device *pdev)
|
||||
static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(pdev));
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
snd_card_free(dev_get_drvdata(pdev));
|
||||
dev_set_drvdata(pdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int snd_sb8_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_sb8 *acard = card->private_data;
|
||||
struct snd_sb *chip = acard->chip;
|
||||
|
||||
|
@ -213,9 +226,9 @@ static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_sb8_resume(struct platform_device *dev)
|
||||
static int snd_sb8_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_sb8 *acard = card->private_data;
|
||||
struct snd_sb *chip = acard->chip;
|
||||
|
||||
|
@ -226,9 +239,10 @@ static int snd_sb8_resume(struct platform_device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define SND_SB8_DRIVER "snd_sb8"
|
||||
#define DEV_NAME "sb8"
|
||||
|
||||
static struct platform_driver snd_sb8_driver = {
|
||||
static struct isa_driver snd_sb8_driver = {
|
||||
.match = snd_sb8_match,
|
||||
.probe = snd_sb8_probe,
|
||||
.remove = __devexit_p(snd_sb8_remove),
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -236,56 +250,18 @@ static struct platform_driver snd_sb8_driver = {
|
|||
.resume = snd_sb8_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = SND_SB8_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
static void __init_or_module snd_sb8_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_sb8_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_sb8_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_sb8_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_SB8_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_sb8_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_sb8_exit(void)
|
||||
{
|
||||
snd_sb8_unregister_all();
|
||||
isa_unregister_driver(&snd_sb8_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_sb8_init)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -64,8 +64,6 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
|
|||
module_param_array(dma1, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
|
||||
|
||||
static struct platform_device *devices[SNDRV_CARDS];
|
||||
|
||||
#define SGALAXY_AUXC_LEFT 18
|
||||
#define SGALAXY_AUXC_RIGHT 19
|
||||
|
||||
|
@ -96,7 +94,8 @@ static int snd_sgalaxy_sbdsp_reset(unsigned long port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val)
|
||||
static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port,
|
||||
unsigned char val)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -114,7 +113,7 @@ static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
|
|||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
|
||||
static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
|
||||
{
|
||||
static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1,
|
||||
0x10, 0x18, 0x20, -1, -1, -1, -1};
|
||||
|
@ -161,7 +160,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init snd_sgalaxy_detect(int dev, int irq, int dma)
|
||||
static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
|
||||
{
|
||||
#if 0
|
||||
snd_printdd(PFX "switching to WSS mode\n");
|
||||
|
@ -182,7 +181,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7
|
|||
AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
|
||||
};
|
||||
|
||||
static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
|
||||
static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip)
|
||||
{
|
||||
struct snd_card *card = chip->card;
|
||||
struct snd_ctl_elem_id id1, id2;
|
||||
|
@ -218,23 +217,29 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init snd_sgalaxy_probe(struct platform_device *devptr)
|
||||
static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev)
|
||||
{
|
||||
if (!enable[dev])
|
||||
return 0;
|
||||
if (sbport[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify SB port\n");
|
||||
return 0;
|
||||
}
|
||||
if (wssport[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify WSS port\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
|
||||
{
|
||||
int dev = devptr->id;
|
||||
static int possible_irqs[] = {7, 9, 10, 11, -1};
|
||||
static int possible_dmas[] = {1, 3, 0, -1};
|
||||
int err, xirq, xdma1;
|
||||
struct snd_card *card;
|
||||
struct snd_ad1848 *chip;
|
||||
|
||||
if (sbport[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify SB port\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (wssport[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR PFX "specify WSS port\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
||||
if (card == NULL)
|
||||
return -ENOMEM;
|
||||
|
@ -283,12 +288,12 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
|
|||
sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
|
||||
wssport[dev], xirq, xdma1);
|
||||
|
||||
snd_card_set_dev(card, &devptr->dev);
|
||||
snd_card_set_dev(card, devptr);
|
||||
|
||||
if ((err = snd_card_register(card)) < 0)
|
||||
goto _err;
|
||||
|
||||
platform_set_drvdata(devptr, card);
|
||||
dev_set_drvdata(devptr, card);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
|
@ -296,17 +301,18 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int __devexit snd_sgalaxy_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct snd_ad1848 *chip = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
|
@ -314,9 +320,9 @@ static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_sgalaxy_resume(struct platform_device *pdev)
|
||||
static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct snd_ad1848 *chip = card->private_data;
|
||||
|
||||
chip->resume(chip);
|
||||
|
@ -328,9 +334,10 @@ static int snd_sgalaxy_resume(struct platform_device *pdev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define SND_SGALAXY_DRIVER "snd_sgalaxy"
|
||||
#define DEV_NAME "sgalaxy"
|
||||
|
||||
static struct platform_driver snd_sgalaxy_driver = {
|
||||
static struct isa_driver snd_sgalaxy_driver = {
|
||||
.match = snd_sgalaxy_match,
|
||||
.probe = snd_sgalaxy_probe,
|
||||
.remove = __devexit_p(snd_sgalaxy_remove),
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -338,56 +345,18 @@ static struct platform_driver snd_sgalaxy_driver = {
|
|||
.resume = snd_sgalaxy_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = SND_SGALAXY_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
static void __init_or_module snd_sgalaxy_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(devices); ++i)
|
||||
platform_device_unregister(devices[i]);
|
||||
platform_driver_unregister(&snd_sgalaxy_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_sgalaxy_init(void)
|
||||
{
|
||||
int i, cards, err;
|
||||
|
||||
err = platform_driver_register(&snd_sgalaxy_driver);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_SGALAXY_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n");
|
||||
#endif
|
||||
snd_sgalaxy_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS);
|
||||
}
|
||||
|
||||
static void __exit alsa_card_sgalaxy_exit(void)
|
||||
{
|
||||
snd_sgalaxy_unregister_all();
|
||||
isa_unregister_driver(&snd_sgalaxy_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_sgalaxy_init)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
@ -68,8 +68,6 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
|
|||
module_param_array(dma, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered;
|
||||
static struct pnp_card_device_id sscape_pnpids[] = {
|
||||
|
@ -1254,9 +1252,27 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
|
|||
}
|
||||
|
||||
|
||||
static int __devinit snd_sscape_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
|
||||
{
|
||||
/*
|
||||
* Make sure we were given ALL of the other parameters.
|
||||
*/
|
||||
if (port[i] == SNDRV_AUTO_PORT)
|
||||
return 0;
|
||||
|
||||
if (irq[i] == SNDRV_AUTO_IRQ ||
|
||||
mpu_irq[i] == SNDRV_AUTO_IRQ ||
|
||||
dma[i] == SNDRV_AUTO_DMA) {
|
||||
printk(KERN_INFO
|
||||
"sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
struct snd_card *card;
|
||||
int ret;
|
||||
|
||||
|
@ -1264,30 +1280,31 @@ static int __devinit snd_sscape_probe(struct platform_device *pdev)
|
|||
ret = create_sscape(dev, &card);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
if ((ret = snd_card_register(card)) < 0) {
|
||||
printk(KERN_ERR "sscape: Failed to register sound card\n");
|
||||
return ret;
|
||||
}
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit snd_sscape_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SSCAPE_DRIVER "snd_sscape"
|
||||
#define DEV_NAME "sscape"
|
||||
|
||||
static struct platform_driver snd_sscape_driver = {
|
||||
static struct isa_driver snd_sscape_driver = {
|
||||
.match = snd_sscape_match,
|
||||
.probe = snd_sscape_probe,
|
||||
.remove = __devexit_p(snd_sscape_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
.driver = {
|
||||
.name = SSCAPE_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1386,72 +1403,6 @@ static struct pnp_card_driver sscape_pnpc_driver = {
|
|||
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static void __init_or_module sscape_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&sscape_pnpc_driver);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&snd_sscape_driver);
|
||||
}
|
||||
|
||||
static int __init sscape_manual_probe(void)
|
||||
{
|
||||
struct platform_device *device;
|
||||
int i, ret;
|
||||
|
||||
ret = platform_driver_register(&snd_sscape_driver);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; ++i) {
|
||||
/*
|
||||
* We do NOT probe for ports.
|
||||
* If we're not given a port number for this
|
||||
* card then we completely ignore this line
|
||||
* of parameters.
|
||||
*/
|
||||
if (port[i] == SNDRV_AUTO_PORT)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Make sure we were given ALL of the other parameters.
|
||||
*/
|
||||
if (irq[i] == SNDRV_AUTO_IRQ ||
|
||||
mpu_irq[i] == SNDRV_AUTO_IRQ ||
|
||||
dma[i] == SNDRV_AUTO_DMA) {
|
||||
printk(KERN_INFO
|
||||
"sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
|
||||
sscape_unregister_all();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* This cards looks OK ...
|
||||
*/
|
||||
device = platform_device_register_simple(SSCAPE_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sscape_exit(void)
|
||||
{
|
||||
sscape_unregister_all();
|
||||
}
|
||||
|
||||
|
||||
static int __init sscape_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1462,7 +1413,7 @@ static int __init sscape_init(void)
|
|||
* of allocating cards, because the operator is
|
||||
* S-P-E-L-L-I-N-G it out for us...
|
||||
*/
|
||||
ret = sscape_manual_probe();
|
||||
ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#ifdef CONFIG_PNP
|
||||
|
@ -1472,5 +1423,14 @@ static int __init sscape_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __exit sscape_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&sscape_pnpc_driver);
|
||||
#endif
|
||||
isa_unregister_driver(&snd_sscape_driver);
|
||||
}
|
||||
|
||||
module_init(sscape_init);
|
||||
module_exit(sscape_exit);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <sound/core.h>
|
||||
|
@ -40,7 +40,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}");
|
|||
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
|
||||
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
|
||||
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
|
||||
#ifdef CONFIG_PNP
|
||||
static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
|
||||
#endif
|
||||
static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
|
||||
static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
|
||||
static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
|
||||
|
@ -83,8 +85,6 @@ MODULE_PARM_DESC(fm_port, "FM port #.");
|
|||
module_param_array(use_cs4232_midi, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
|
||||
|
||||
static struct platform_device *platform_devices[SNDRV_CARDS];
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static int pnp_registered;
|
||||
|
||||
|
@ -588,56 +588,67 @@ snd_wavefront_probe (struct snd_card *card, int dev)
|
|||
return snd_card_register(card);
|
||||
}
|
||||
|
||||
static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev)
|
||||
static int __devinit snd_wavefront_isa_match(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
int dev = pdev->id;
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
|
||||
if (!enable[dev])
|
||||
return 0;
|
||||
#ifdef CONFIG_PNP
|
||||
if (isapnp[dev])
|
||||
return 0;
|
||||
#endif
|
||||
if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk("specify CS4232 port\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
|
||||
snd_printk("specify ICS2115 port\n");
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit snd_wavefront_isa_probe(struct device *pdev,
|
||||
unsigned int dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
int err;
|
||||
|
||||
card = snd_wavefront_card_new(dev);
|
||||
if (! card)
|
||||
return -ENOMEM;
|
||||
snd_card_set_dev(card, &pdev->dev);
|
||||
snd_card_set_dev(card, pdev);
|
||||
if ((err = snd_wavefront_probe(card, dev)) < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
dev_set_drvdata(pdev, card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr)
|
||||
static int __devexit snd_wavefront_isa_remove(struct device *devptr,
|
||||
unsigned int dev)
|
||||
{
|
||||
snd_card_free(platform_get_drvdata(devptr));
|
||||
platform_set_drvdata(devptr, NULL);
|
||||
snd_card_free(dev_get_drvdata(devptr));
|
||||
dev_set_drvdata(devptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define WAVEFRONT_DRIVER "snd_wavefront"
|
||||
#define DEV_NAME "wavefront"
|
||||
|
||||
static struct platform_driver snd_wavefront_driver = {
|
||||
.probe = snd_wavefront_nonpnp_probe,
|
||||
.remove = __devexit_p(snd_wavefront_nonpnp_remove),
|
||||
static struct isa_driver snd_wavefront_driver = {
|
||||
.match = snd_wavefront_isa_match,
|
||||
.probe = snd_wavefront_isa_probe,
|
||||
.remove = __devexit_p(snd_wavefront_isa_remove),
|
||||
/* FIXME: suspend, resume */
|
||||
.driver = {
|
||||
.name = WAVEFRONT_DRIVER
|
||||
.name = DEV_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static unsigned int __devinitdata wavefront_pnp_devices;
|
||||
|
||||
static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
|
||||
const struct pnp_card_device_id *pid)
|
||||
{
|
||||
|
@ -670,7 +681,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
|
|||
|
||||
pnp_set_card_drvdata(pcard, card);
|
||||
dev++;
|
||||
wavefront_pnp_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -691,67 +701,28 @@ static struct pnp_card_driver wavefront_pnpc_driver = {
|
|||
|
||||
#endif /* CONFIG_PNP */
|
||||
|
||||
static void __init_or_module snd_wavefront_unregister_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&wavefront_pnpc_driver);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
|
||||
platform_device_unregister(platform_devices[i]);
|
||||
platform_driver_unregister(&snd_wavefront_driver);
|
||||
}
|
||||
|
||||
static int __init alsa_card_wavefront_init(void)
|
||||
{
|
||||
int i, err, cards = 0;
|
||||
int err;
|
||||
|
||||
if ((err = platform_driver_register(&snd_wavefront_driver)) < 0)
|
||||
err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
#ifdef CONFIG_PNP
|
||||
if (isapnp[i])
|
||||
continue;
|
||||
#endif
|
||||
device = platform_device_register_simple(WAVEFRONT_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device))
|
||||
continue;
|
||||
if (!platform_get_drvdata(device)) {
|
||||
platform_device_unregister(device);
|
||||
continue;
|
||||
}
|
||||
platform_devices[i] = device;
|
||||
cards++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
err = pnp_register_card_driver(&wavefront_pnpc_driver);
|
||||
if (!err) {
|
||||
if (!err)
|
||||
pnp_registered = 1;
|
||||
cards += wavefront_pnp_devices;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cards) {
|
||||
#ifdef MODULE
|
||||
printk (KERN_ERR "No WaveFront cards found or devices busy\n");
|
||||
#endif
|
||||
snd_wavefront_unregister_all();
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_card_wavefront_exit(void)
|
||||
{
|
||||
snd_wavefront_unregister_all();
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp_registered)
|
||||
pnp_unregister_card_driver(&wavefront_pnpc_driver);
|
||||
#endif
|
||||
isa_unregister_driver(&snd_wavefront_driver);
|
||||
}
|
||||
|
||||
module_init(alsa_card_wavefront_init)
|
||||
|
|
|
@ -35,9 +35,7 @@
|
|||
|
||||
#define WAIT_IDLE 0xff
|
||||
|
||||
#define FIRMWARE_IN_THE_KERNEL
|
||||
|
||||
#ifdef FIRMWARE_IN_THE_KERNEL
|
||||
#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
|
||||
#include "yss225.c"
|
||||
static const struct firmware yss225_registers_firmware = {
|
||||
.data = (u8 *)yss225_registers,
|
||||
|
@ -258,21 +256,21 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
|
|||
{
|
||||
unsigned int i;
|
||||
int err;
|
||||
const struct firmware *firmware;
|
||||
const struct firmware *firmware = NULL;
|
||||
|
||||
if (dev->fx_initialized)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
|
||||
firmware = &yss225_registers_firmware;
|
||||
#else
|
||||
err = request_firmware(&firmware, "yamaha/yss225_registers.bin",
|
||||
dev->card->dev);
|
||||
if (err < 0) {
|
||||
#ifdef FIRMWARE_IN_THE_KERNEL
|
||||
firmware = &yss225_registers_firmware;
|
||||
#else
|
||||
err = -1;
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i + 1 < firmware->size; i += 2) {
|
||||
if (firmware->data[i] >= 8 && firmware->data[i] < 16) {
|
||||
|
@ -295,9 +293,12 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
|
|||
err = 0;
|
||||
|
||||
out:
|
||||
#ifdef FIRMWARE_IN_THE_KERNEL
|
||||
if (firmware != &yss225_registers_firmware)
|
||||
#endif
|
||||
#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
|
||||
release_firmware(firmware);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
|
||||
MODULE_FIRMWARE("yamaha/yss225_registers.bin");
|
||||
#endif
|
||||
|
|
|
@ -576,7 +576,7 @@ config SND_INTEL8X0M
|
|||
config SND_KORG1212
|
||||
tristate "Korg 1212 IO"
|
||||
depends on SND
|
||||
select FW_LOADER
|
||||
select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL
|
||||
select SND_PCM
|
||||
help
|
||||
Say Y here to include support for Korg 1212IO soundcards.
|
||||
|
@ -584,10 +584,19 @@ config SND_KORG1212
|
|||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-korg1212.
|
||||
|
||||
config SND_KORG1212_FIRMWARE_IN_KERNEL
|
||||
bool "In-kernel firmware for Korg1212 driver"
|
||||
depends on SND_KORG1212
|
||||
default y
|
||||
help
|
||||
Say Y here to include the static firmware built in the kernel
|
||||
for the Korg1212 driver. If you choose N here, you need to
|
||||
install the firmware files from the alsa-firmware package.
|
||||
|
||||
config SND_MAESTRO3
|
||||
tristate "ESS Allegro/Maestro3"
|
||||
depends on SND
|
||||
select FW_LOADER
|
||||
select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL
|
||||
select SND_AC97_CODEC
|
||||
help
|
||||
Say Y here to include support for soundcards based on ESS Maestro 3
|
||||
|
@ -596,6 +605,15 @@ config SND_MAESTRO3
|
|||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-maestro3.
|
||||
|
||||
config SND_MAESTRO3_FIRMWARE_IN_KERNEL
|
||||
bool "In-kernel firmware for Maestro3 driver"
|
||||
depends on SND_MAESTRO3
|
||||
default y
|
||||
help
|
||||
Say Y here to include the static firmware built in the kernel
|
||||
for the Maestro3 driver. If you choose N here, you need to
|
||||
install the firmware files from the alsa-firmware package.
|
||||
|
||||
config SND_MIXART
|
||||
tristate "Digigram miXart"
|
||||
depends on SND
|
||||
|
@ -737,7 +755,7 @@ config SND_VX222
|
|||
config SND_YMFPCI
|
||||
tristate "Yamaha YMF724/740/744/754"
|
||||
depends on SND
|
||||
select FW_LOADER
|
||||
select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_AC97_CODEC
|
||||
|
@ -748,6 +766,15 @@ config SND_YMFPCI
|
|||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-ymfpci.
|
||||
|
||||
config SND_YMFPCI_FIRMWARE_IN_KERNEL
|
||||
bool "In-kernel firmware for YMFPCI driver"
|
||||
depends on SND_YMFPCI
|
||||
default y
|
||||
help
|
||||
Say Y here to include the static firmware built in the kernel
|
||||
for the YMFPCI driver. If you choose N here, you need to
|
||||
install the firmware files from the alsa-firmware package.
|
||||
|
||||
config SND_AC97_POWER_SAVE
|
||||
bool "AC97 Power-Saving Mode"
|
||||
depends on SND_AC97_CODEC && EXPERIMENTAL
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
|
||||
#
|
||||
|
||||
snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o
|
||||
snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o
|
||||
|
||||
ifneq ($(CONFIG_PROC_FS),)
|
||||
snd-ac97-codec-objs += ac97_proc.o
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
#include <sound/ac97_codec.h>
|
||||
#include <sound/asoundef.h>
|
||||
#include <sound/initval.h>
|
||||
#include "ac97_local.h"
|
||||
#include "ac97_id.h"
|
||||
#include "ac97_patch.h"
|
||||
|
||||
#include "ac97_patch.c"
|
||||
|
||||
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
|
||||
MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
|
||||
|
@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns
|
|||
* Controls
|
||||
*/
|
||||
|
||||
int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
|
||||
|
||||
|
@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
|
||||
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
|
||||
|
@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
|
||||
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
|
||||
|
@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save)
|
|||
}
|
||||
|
||||
/* volume and switch controls */
|
||||
int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
int mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
int shift = (kcontrol->private_value >> 8) & 0x0f;
|
||||
|
@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
|
||||
int reg = kcontrol->private_value & 0xff;
|
||||
|
@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
|
||||
int reg = kcontrol->private_value & 0xff;
|
||||
|
@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]),
|
|||
AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
|
||||
};
|
||||
|
||||
const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
|
||||
static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
|
||||
AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0),
|
||||
AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0)
|
||||
};
|
||||
|
@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
|||
return change;
|
||||
}
|
||||
|
||||
const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
|
||||
static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
|
||||
{
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ,
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
|
@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha
|
|||
}
|
||||
}
|
||||
|
||||
int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
|
||||
static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
|
||||
{
|
||||
unsigned short mask, val, orig, res;
|
||||
|
||||
|
@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x)
|
|||
return x;
|
||||
}
|
||||
|
||||
struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97)
|
||||
static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
|
||||
struct snd_ac97 * ac97)
|
||||
{
|
||||
struct snd_kcontrol_new template;
|
||||
memcpy(&template, _template, sizeof(template));
|
||||
|
@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix)
|
|||
}
|
||||
|
||||
/* remove the control with the given name and optional suffix */
|
||||
int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix)
|
||||
static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
|
||||
const char *suffix)
|
||||
{
|
||||
struct snd_ctl_elem_id id;
|
||||
memset(&id, 0, sizeof(id));
|
||||
|
@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co
|
|||
}
|
||||
|
||||
/* rename the control with the given name and optional suffix */
|
||||
int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix)
|
||||
static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
|
||||
const char *dst, const char *suffix)
|
||||
{
|
||||
struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
|
||||
if (kctl) {
|
||||
|
@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst,
|
|||
}
|
||||
|
||||
/* rename both Volume and Switch controls - don't check the return value */
|
||||
void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst)
|
||||
static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
|
||||
const char *dst)
|
||||
{
|
||||
snd_ac97_rename_ctl(ac97, src, dst, "Switch");
|
||||
snd_ac97_rename_ctl(ac97, src, dst, "Volume");
|
||||
}
|
||||
|
||||
/* swap controls */
|
||||
int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix)
|
||||
static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
|
||||
const char *s2, const char *suffix)
|
||||
{
|
||||
struct snd_kcontrol *kctl1, *kctl2;
|
||||
kctl1 = ctl_find(ac97, s1, suffix);
|
||||
|
|
|
@ -22,59 +22,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24))
|
||||
#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
|
||||
#define AC97_SINGLE(xname, reg, shift, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
|
||||
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
|
||||
.private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) }
|
||||
#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
|
||||
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
|
||||
.private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
|
||||
#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \
|
||||
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
|
||||
.private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
|
||||
|
||||
/* enum control */
|
||||
struct ac97_enum {
|
||||
unsigned char reg;
|
||||
unsigned char shift_l;
|
||||
unsigned char shift_r;
|
||||
unsigned short mask;
|
||||
const char **texts;
|
||||
};
|
||||
|
||||
#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
|
||||
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
|
||||
.mask = xmask, .texts = xtexts }
|
||||
#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
|
||||
AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
|
||||
#define AC97_ENUM(xname, xenum) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \
|
||||
.get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
|
||||
.private_value = (unsigned long)&xenum }
|
||||
|
||||
/* ac97_codec.c */
|
||||
extern const struct snd_kcontrol_new snd_ac97_controls_3d[];
|
||||
extern const struct snd_kcontrol_new snd_ac97_controls_spdif[];
|
||||
struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97);
|
||||
void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem);
|
||||
int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
|
||||
int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
|
||||
int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix);
|
||||
int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix);
|
||||
int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix);
|
||||
void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst);
|
||||
void snd_ac97_restore_status(struct snd_ac97 *ac97);
|
||||
void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
|
||||
int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
|
||||
int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name,
|
||||
int modem);
|
||||
int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
|
||||
unsigned short mask, unsigned short value);
|
||||
|
||||
|
|
|
@ -23,20 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include "ac97_patch.h"
|
||||
#include "ac97_id.h"
|
||||
#include "ac97_local.h"
|
||||
#include "ac97_patch.h"
|
||||
|
||||
/*
|
||||
* Chip specific initialization
|
||||
|
@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
|
|||
.build_post_spdif = patch_yamaha_ymf753_post_spdif
|
||||
};
|
||||
|
||||
int patch_yamaha_ymf753(struct snd_ac97 * ac97)
|
||||
static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
|
||||
This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
|
||||
|
@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
|
|||
.build_specific = patch_wolfson_wm9703_specific,
|
||||
};
|
||||
|
||||
int patch_wolfson03(struct snd_ac97 * ac97)
|
||||
static int patch_wolfson03(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_wolfson_wm9703_ops;
|
||||
return 0;
|
||||
|
@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
|
|||
.build_specific = patch_wolfson_wm9704_specific,
|
||||
};
|
||||
|
||||
int patch_wolfson04(struct snd_ac97 * ac97)
|
||||
static int patch_wolfson04(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* WM9704M/9704Q */
|
||||
ac97->build_ops = &patch_wolfson_wm9704_ops;
|
||||
|
@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
|
|||
.build_specific = patch_wolfson_wm9705_specific,
|
||||
};
|
||||
|
||||
int patch_wolfson05(struct snd_ac97 * ac97)
|
||||
static int patch_wolfson05(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* WM9705, WM9710 */
|
||||
ac97->build_ops = &patch_wolfson_wm9705_ops;
|
||||
|
@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
|
|||
.build_specific = patch_wolfson_wm9711_specific,
|
||||
};
|
||||
|
||||
int patch_wolfson11(struct snd_ac97 * ac97)
|
||||
static int patch_wolfson11(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* WM9711, WM9712 */
|
||||
ac97->build_ops = &patch_wolfson_wm9711_ops;
|
||||
|
@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
int patch_wolfson13(struct snd_ac97 * ac97)
|
||||
static int patch_wolfson13(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* WM9713, WM9714 */
|
||||
ac97->build_ops = &patch_wolfson_wm9713_ops;
|
||||
|
@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97)
|
|||
/*
|
||||
* Tritech codec
|
||||
*/
|
||||
int patch_tritech_tr28028(struct snd_ac97 * ac97)
|
||||
static int patch_tritech_tr28028(struct snd_ac97 * ac97)
|
||||
{
|
||||
snd_ac97_write_cache(ac97, 0x26, 0x0300);
|
||||
snd_ac97_write_cache(ac97, 0x26, 0x0000);
|
||||
|
@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
|
|||
.build_specific = patch_sigmatel_stac97xx_specific
|
||||
};
|
||||
|
||||
int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
|
||||
static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_sigmatel_stac9700_ops;
|
||||
return 0;
|
||||
|
@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
|
|||
.build_specific = patch_sigmatel_stac9708_specific
|
||||
};
|
||||
|
||||
int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
|
||||
static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
|
||||
{
|
||||
unsigned int codec72, codec6c;
|
||||
|
||||
|
@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
|
||||
static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_sigmatel_stac9700_ops;
|
||||
if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
|
||||
|
@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
|
||||
static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
|
||||
{
|
||||
// patch for SigmaTel
|
||||
ac97->build_ops = &patch_sigmatel_stac9700_ops;
|
||||
|
@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
|
||||
static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
|
||||
{
|
||||
// patch for SigmaTel
|
||||
ac97->build_ops = &patch_sigmatel_stac9700_ops;
|
||||
|
@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
|
|||
.build_specific = patch_sigmatel_stac9758_specific
|
||||
};
|
||||
|
||||
int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
|
||||
static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
|
||||
{
|
||||
static unsigned short regs[4] = {
|
||||
AC97_SIGMATEL_OUTSEL,
|
||||
|
@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = {
|
|||
.build_spdif = patch_cirrus_build_spdif
|
||||
};
|
||||
|
||||
int patch_cirrus_spdif(struct snd_ac97 * ac97)
|
||||
static int patch_cirrus_spdif(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
|
||||
WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
|
||||
|
@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int patch_cirrus_cs4299(struct snd_ac97 * ac97)
|
||||
static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* force the detection of PC Beep */
|
||||
ac97->flags |= AC97_HAS_PC_BEEP;
|
||||
|
@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = {
|
|||
.build_spdif = patch_conexant_build_spdif
|
||||
};
|
||||
|
||||
int patch_conexant(struct snd_ac97 * ac97)
|
||||
static int patch_conexant(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_conexant_ops;
|
||||
ac97->flags |= AC97_CX_SPDIF;
|
||||
|
@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int patch_cx20551(struct snd_ac97 *ac97)
|
||||
static int patch_cx20551(struct snd_ac97 *ac97)
|
||||
{
|
||||
snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
|
||||
return 0;
|
||||
|
@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = {
|
|||
{ } /* terminator */
|
||||
};
|
||||
|
||||
int patch_ad1819(struct snd_ac97 * ac97)
|
||||
static int patch_ad1819(struct snd_ac97 * ac97)
|
||||
{
|
||||
unsigned short scfg;
|
||||
|
||||
|
@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
int patch_ad1881(struct snd_ac97 * ac97)
|
||||
static int patch_ad1881(struct snd_ac97 * ac97)
|
||||
{
|
||||
static const char cfg_idxs[3][2] = {
|
||||
{2, 1},
|
||||
|
@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
int patch_ad1885(struct snd_ac97 * ac97)
|
||||
static int patch_ad1885(struct snd_ac97 * ac97)
|
||||
{
|
||||
patch_ad1881(ac97);
|
||||
/* This is required to deal with the Intel D815EEAL2 */
|
||||
|
@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
int patch_ad1886(struct snd_ac97 * ac97)
|
||||
static int patch_ad1886(struct snd_ac97 * ac97)
|
||||
{
|
||||
patch_ad1881(ac97);
|
||||
/* Presario700 workaround */
|
||||
|
@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
|
|||
snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
|
||||
}
|
||||
|
||||
int patch_ad1981a(struct snd_ac97 *ac97)
|
||||
static int patch_ad1981a(struct snd_ac97 *ac97)
|
||||
{
|
||||
patch_ad1881(ac97);
|
||||
ac97->build_ops = &patch_ad1981a_build_ops;
|
||||
|
@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
int patch_ad1981b(struct snd_ac97 *ac97)
|
||||
static int patch_ad1981b(struct snd_ac97 *ac97)
|
||||
{
|
||||
patch_ad1881(ac97);
|
||||
ac97->build_ops = &patch_ad1981b_build_ops;
|
||||
|
@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
|
|||
.update_jacks = ad1888_update_jacks,
|
||||
};
|
||||
|
||||
int patch_ad1888(struct snd_ac97 * ac97)
|
||||
static int patch_ad1888(struct snd_ac97 * ac97)
|
||||
{
|
||||
unsigned short misc;
|
||||
|
||||
|
@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = {
|
|||
.update_jacks = ad1888_update_jacks,
|
||||
};
|
||||
|
||||
int patch_ad1980(struct snd_ac97 * ac97)
|
||||
static int patch_ad1980(struct snd_ac97 * ac97)
|
||||
{
|
||||
patch_ad1888(ac97);
|
||||
ac97->build_ops = &patch_ad1980_build_ops;
|
||||
|
@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = {
|
|||
.update_jacks = ad1985_update_jacks,
|
||||
};
|
||||
|
||||
int patch_ad1985(struct snd_ac97 * ac97)
|
||||
static int patch_ad1985(struct snd_ac97 * ac97)
|
||||
{
|
||||
unsigned short misc;
|
||||
|
||||
|
@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = {
|
|||
.update_jacks = ad1986_update_jacks,
|
||||
};
|
||||
|
||||
int patch_ad1986(struct snd_ac97 * ac97)
|
||||
static int patch_ad1986(struct snd_ac97 * ac97)
|
||||
{
|
||||
patch_ad1881(ac97);
|
||||
ac97->build_ops = &patch_ad1986_build_ops;
|
||||
|
@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = {
|
|||
.update_jacks = alc650_update_jacks
|
||||
};
|
||||
|
||||
int patch_alc650(struct snd_ac97 * ac97)
|
||||
static int patch_alc650(struct snd_ac97 * ac97)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
|
@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = {
|
|||
.update_jacks = alc655_update_jacks
|
||||
};
|
||||
|
||||
int patch_alc655(struct snd_ac97 * ac97)
|
||||
static int patch_alc655(struct snd_ac97 * ac97)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
|
@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97)
|
|||
(ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
|
||||
ac97->subsystem_device == 0x0161 || /* LG K1 Express */
|
||||
ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
|
||||
ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */
|
||||
ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */
|
||||
val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
|
||||
else
|
||||
|
@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = {
|
|||
.update_jacks = alc850_update_jacks
|
||||
};
|
||||
|
||||
int patch_alc850(struct snd_ac97 *ac97)
|
||||
static int patch_alc850(struct snd_ac97 *ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_alc850_ops;
|
||||
|
||||
|
@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = {
|
|||
.update_jacks = cm9738_update_jacks
|
||||
};
|
||||
|
||||
int patch_cm9738(struct snd_ac97 * ac97)
|
||||
static int patch_cm9738(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_cm9738_ops;
|
||||
/* FIXME: can anyone confirm below? */
|
||||
|
@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = {
|
|||
.update_jacks = cm9739_update_jacks
|
||||
};
|
||||
|
||||
int patch_cm9739(struct snd_ac97 * ac97)
|
||||
static int patch_cm9739(struct snd_ac97 * ac97)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
|
@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = {
|
|||
.update_jacks = cm9761_update_jacks
|
||||
};
|
||||
|
||||
int patch_cm9761(struct snd_ac97 *ac97)
|
||||
static int patch_cm9761(struct snd_ac97 *ac97)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
|
@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = {
|
|||
.build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
|
||||
};
|
||||
|
||||
int patch_cm9780(struct snd_ac97 *ac97)
|
||||
static int patch_cm9780(struct snd_ac97 *ac97)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
|
@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = {
|
|||
.build_specific = patch_vt1616_specific
|
||||
};
|
||||
|
||||
int patch_vt1616(struct snd_ac97 * ac97)
|
||||
static int patch_vt1616(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_vt1616_ops;
|
||||
return 0;
|
||||
|
@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97)
|
|||
/*
|
||||
* VT1617A codec
|
||||
*/
|
||||
|
||||
/*
|
||||
* unfortunately, the vt1617a stashes the twiddlers required for
|
||||
* nooding the i/o jacks on 2 different regs. * thameans that we cant
|
||||
* use the easy way provided by AC97_ENUM_DOUBLE() we have to write
|
||||
* are own funcs.
|
||||
*
|
||||
* NB: this is absolutely and utterly different from the vt1618. dunno
|
||||
* about the 1616.
|
||||
*/
|
||||
|
||||
/* copied from ac97_surround_jack_mode_info() */
|
||||
static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
/* ordering in this list reflects vt1617a docs for Reg 20 and
|
||||
* 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
|
||||
* is SM51EN *AND* it's Bit14, not Bit15 so the table is very
|
||||
* counter-intuitive */
|
||||
|
||||
static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
|
||||
"Surr LFE/C Mic3", "LineIn LFE/C Mic3",
|
||||
"LineIn Mic2", "LineIn Mic2 Mic1",
|
||||
"Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
|
||||
return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
|
||||
}
|
||||
|
||||
static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ushort usSM51, usMS;
|
||||
|
||||
struct snd_ac97 *pac97;
|
||||
|
||||
pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
|
||||
|
||||
/* grab our desirec bits, then mash them together in a manner
|
||||
* consistent with Table 6 on page 17 in the 1617a docs */
|
||||
|
||||
usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
|
||||
usMS = snd_ac97_read(pac97, 0x20) >> 8;
|
||||
|
||||
ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ushort usSM51, usMS, usReg;
|
||||
|
||||
struct snd_ac97 *pac97;
|
||||
|
||||
pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
|
||||
|
||||
usSM51 = ucontrol->value.enumerated.item[0] >> 1;
|
||||
usMS = ucontrol->value.enumerated.item[0] & 1;
|
||||
|
||||
/* push our values into the register - consider that things will be left
|
||||
* in a funky state if the write fails */
|
||||
|
||||
usReg = snd_ac97_read(pac97, 0x7a);
|
||||
snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
|
||||
usReg = snd_ac97_read(pac97, 0x20);
|
||||
snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
|
||||
|
||||
AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
|
||||
/*
|
||||
* These are used to enable/disable surround sound on motherboards
|
||||
* that have 3 bidirectional analog jacks
|
||||
*/
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Smart 5.1 Select",
|
||||
.info = snd_ac97_vt1617a_smart51_info,
|
||||
.get = snd_ac97_vt1617a_smart51_get,
|
||||
.put = snd_ac97_vt1617a_smart51_put,
|
||||
},
|
||||
};
|
||||
|
||||
int patch_vt1617a(struct snd_ac97 * ac97)
|
||||
{
|
||||
/* bring analog power consumption to normal, like WinXP driver
|
||||
* for EPIA SP
|
||||
int err = 0;
|
||||
|
||||
/* we choose to not fail out at this point, but we tell the
|
||||
caller when we return */
|
||||
|
||||
err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
|
||||
ARRAY_SIZE(snd_ac97_controls_vt1617a));
|
||||
|
||||
/* bring analog power consumption to normal by turning off the
|
||||
* headphone amplifier, like WinXP driver for EPIA SP
|
||||
*/
|
||||
snd_ac97_write_cache(ac97, 0x5c, 0x20);
|
||||
ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
|
||||
ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
|
||||
ac97->build_ops = &patch_vt1616_ops;
|
||||
return 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = {
|
|||
.update_jacks = it2646_update_jacks
|
||||
};
|
||||
|
||||
int patch_it2646(struct snd_ac97 * ac97)
|
||||
static int patch_it2646(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_it2646_ops;
|
||||
/* full DAC volume */
|
||||
|
@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = {
|
|||
.build_specific = patch_si3036_specific,
|
||||
};
|
||||
|
||||
int mpatch_si3036(struct snd_ac97 * ac97)
|
||||
static int mpatch_si3036(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_si3036_ops;
|
||||
snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
|
||||
|
@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = {
|
|||
{ } /* terminator */
|
||||
};
|
||||
|
||||
int patch_lm4550(struct snd_ac97 *ac97)
|
||||
static int patch_lm4550(struct snd_ac97 *ac97)
|
||||
{
|
||||
ac97->res_table = lm4550_restbl;
|
||||
return 0;
|
||||
|
@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = {
|
|||
.build_specific = patch_ucb1400_specific,
|
||||
};
|
||||
|
||||
int patch_ucb1400(struct snd_ac97 * ac97)
|
||||
static int patch_ucb1400(struct snd_ac97 * ac97)
|
||||
{
|
||||
ac97->build_ops = &patch_ucb1400_ops;
|
||||
/* enable headphone driver and smart low power mode by default */
|
||||
|
|
|
@ -22,44 +22,72 @@
|
|||
*
|
||||
*/
|
||||
|
||||
int patch_yamaha_ymf753(struct snd_ac97 * ac97);
|
||||
int patch_wolfson00(struct snd_ac97 * ac97);
|
||||
int patch_wolfson03(struct snd_ac97 * ac97);
|
||||
int patch_wolfson04(struct snd_ac97 * ac97);
|
||||
int patch_wolfson05(struct snd_ac97 * ac97);
|
||||
int patch_wolfson11(struct snd_ac97 * ac97);
|
||||
int patch_wolfson13(struct snd_ac97 * ac97);
|
||||
int patch_tritech_tr28028(struct snd_ac97 * ac97);
|
||||
int patch_sigmatel_stac9700(struct snd_ac97 * ac97);
|
||||
int patch_sigmatel_stac9708(struct snd_ac97 * ac97);
|
||||
int patch_sigmatel_stac9721(struct snd_ac97 * ac97);
|
||||
int patch_sigmatel_stac9744(struct snd_ac97 * ac97);
|
||||
int patch_sigmatel_stac9756(struct snd_ac97 * ac97);
|
||||
int patch_sigmatel_stac9758(struct snd_ac97 * ac97);
|
||||
int patch_cirrus_cs4299(struct snd_ac97 * ac97);
|
||||
int patch_cirrus_spdif(struct snd_ac97 * ac97);
|
||||
int patch_conexant(struct snd_ac97 * ac97);
|
||||
int patch_cx20551(struct snd_ac97 * ac97);
|
||||
int patch_ad1819(struct snd_ac97 * ac97);
|
||||
int patch_ad1881(struct snd_ac97 * ac97);
|
||||
int patch_ad1885(struct snd_ac97 * ac97);
|
||||
int patch_ad1886(struct snd_ac97 * ac97);
|
||||
int patch_ad1888(struct snd_ac97 * ac97);
|
||||
int patch_ad1980(struct snd_ac97 * ac97);
|
||||
int patch_ad1981a(struct snd_ac97 * ac97);
|
||||
int patch_ad1981b(struct snd_ac97 * ac97);
|
||||
int patch_ad1985(struct snd_ac97 * ac97);
|
||||
int patch_ad1986(struct snd_ac97 * ac97);
|
||||
int patch_alc650(struct snd_ac97 * ac97);
|
||||
int patch_alc655(struct snd_ac97 * ac97);
|
||||
int patch_alc850(struct snd_ac97 * ac97);
|
||||
int patch_cm9738(struct snd_ac97 * ac97);
|
||||
int patch_cm9739(struct snd_ac97 * ac97);
|
||||
int patch_cm9761(struct snd_ac97 * ac97);
|
||||
int patch_cm9780(struct snd_ac97 * ac97);
|
||||
int patch_vt1616(struct snd_ac97 * ac97);
|
||||
int patch_vt1617a(struct snd_ac97 * ac97);
|
||||
int patch_it2646(struct snd_ac97 * ac97);
|
||||
int patch_ucb1400(struct snd_ac97 * ac97);
|
||||
int mpatch_si3036(struct snd_ac97 * ac97);
|
||||
int patch_lm4550(struct snd_ac97 * ac97);
|
||||
#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \
|
||||
((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \
|
||||
((invert) << 24))
|
||||
#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \
|
||||
(AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
|
||||
#define AC97_SINGLE(xname, reg, shift, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_ac97_info_volsw, \
|
||||
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
|
||||
.private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) }
|
||||
#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_ac97_info_volsw, \
|
||||
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
|
||||
.private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
|
||||
#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.info = snd_ac97_info_volsw, \
|
||||
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
|
||||
.private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
|
||||
|
||||
/* enum control */
|
||||
struct ac97_enum {
|
||||
unsigned char reg;
|
||||
unsigned char shift_l;
|
||||
unsigned char shift_r;
|
||||
unsigned short mask;
|
||||
const char **texts;
|
||||
};
|
||||
|
||||
#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
|
||||
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
|
||||
.mask = xmask, .texts = xtexts }
|
||||
#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
|
||||
AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
|
||||
#define AC97_ENUM(xname, xenum) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_ac97_info_enum_double, \
|
||||
.get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
|
||||
.private_value = (unsigned long)&xenum }
|
||||
|
||||
/* ac97_codec.c */
|
||||
static const struct snd_kcontrol_new snd_ac97_controls_3d[];
|
||||
static const struct snd_kcontrol_new snd_ac97_controls_spdif[];
|
||||
static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
|
||||
struct snd_ac97 * ac97);
|
||||
static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
|
||||
static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
|
||||
const char *suffix);
|
||||
static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
|
||||
const char *dst, const char *suffix);
|
||||
static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
|
||||
const char *s2, const char *suffix);
|
||||
static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
|
||||
const char *dst);
|
||||
static void snd_ac97_restore_status(struct snd_ac97 *ac97);
|
||||
static void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
|
||||
static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <sound/control.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <sound/asoundef.h>
|
||||
#include "ac97_patch.h"
|
||||
#include "ac97_id.h"
|
||||
#include "ac97_local.h"
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,40 +0,0 @@
|
|||
/***************************************************************************
|
||||
* au88x0_sb.h
|
||||
*
|
||||
* Wed Oct 29 22:10:42 2003
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CHIP_AU8820
|
||||
/* AU8820 starting @ 64KiB offset */
|
||||
#define SBEMU_BASE 0x10000
|
||||
#else
|
||||
/* AU8810? and AU8830 starting @ 164KiB offset */
|
||||
#define SBEMU_BASE 0x29000
|
||||
#endif
|
||||
|
||||
#define FM_A_STATUS (SBEMU_BASE + 0x00) /* read */
|
||||
#define FM_A_ADDRESS (SBEMU_BASE + 0x00) /* write */
|
||||
#define FM_A_DATA (SBEMU_BASE + 0x04)
|
||||
#define FM_B_STATUS (SBEMU_BASE + 0x08)
|
||||
#define FM_B_ADDRESS (SBEMU_BASE + 0x08)
|
||||
#define FM_B_DATA (SBEMU_BASE + 0x0C)
|
||||
#define SB_MIXER_ADDR (SBEMU_BASE + 0x10)
|
||||
#define SB_MIXER_DATA (SBEMU_BASE + 0x14)
|
||||
#define SB_RESET (SBEMU_BASE + 0x18)
|
||||
#define SB_RESET_ALIAS (SBEMU_BASE + 0x1C)
|
||||
#define FM_STATUS2 (SBEMU_BASE + 0x20)
|
||||
#define FM_ADDR2 (SBEMU_BASE + 0x20)
|
||||
#define FM_DATA2 (SBEMU_BASE + 0x24)
|
||||
#define SB_DSP_READ (SBEMU_BASE + 0x28)
|
||||
#define SB_DSP_WRITE (SBEMU_BASE + 0x30)
|
||||
#define SB_DSP_WRITE_STATUS (SBEMU_BASE + 0x30) /* bit 7 */
|
||||
#define SB_DSP_READ_STATUS (SBEMU_BASE + 0x38) /* bit 7 */
|
||||
#define SB_LACR (SBEMU_BASE + 0x40) /* ? */
|
||||
#define SB_LADCR (SBEMU_BASE + 0x44) /* ? */
|
||||
#define SB_LAMR (SBEMU_BASE + 0x48) /* ? */
|
||||
#define SB_LARR (SBEMU_BASE + 0x4C) /* ? */
|
||||
#define SB_VERSION (SBEMU_BASE + 0x50)
|
||||
#define SB_CTRLSTAT (SBEMU_BASE + 0x54)
|
||||
#define SB_TIMERSTAT (SBEMU_BASE + 0x58)
|
||||
#define FM_RAM (SBEMU_BASE + 0x100) /* 0x40 ULONG */
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
|
||||
* Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
|
||||
* Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de>
|
||||
*
|
||||
* Framework borrowed from Bart Hartgers's als4000.c.
|
||||
* Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
|
||||
|
@ -52,6 +52,9 @@
|
|||
* - full duplex 16bit playback/record at independent sampling rate
|
||||
* - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
|
||||
* - game port (legacy address support)
|
||||
* - builtin 3D enhancement (said to be YAMAHA Ymersion)
|
||||
* - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
|
||||
* features supported)
|
||||
* - built-in General DirectX timer having a 20 bits counter
|
||||
* with 1us resolution (see below!)
|
||||
* - I2S serial port for external DAC
|
||||
|
@ -94,6 +97,10 @@
|
|||
*
|
||||
* BUGS
|
||||
* - full-duplex might *still* be problematic, not fully tested recently
|
||||
* - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
|
||||
* if you set PCM output switch to "pre 3D" instead of "post 3D".
|
||||
* If this can't be set, then get a mixer application that Isn't Stupid (tm)
|
||||
* (e.g. kmix, gamix) - unfortunately several are!!
|
||||
*
|
||||
* TODO
|
||||
* - test MPU401 MIDI playback etc.
|
||||
|
@ -622,7 +629,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
|
|||
return (nreg != oreg);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
|
||||
AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
|
||||
AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
|
||||
AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
|
||||
|
@ -652,7 +659,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
|
|||
AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
|
||||
AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
|
||||
AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
|
||||
AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
|
||||
AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
|
||||
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
|
||||
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
|
||||
AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
|
||||
|
@ -678,7 +685,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
|
|||
#endif
|
||||
};
|
||||
|
||||
static const u16 __devinitdata snd_azf3328_init_values[][2] = {
|
||||
static u16 __devinitdata snd_azf3328_init_values[][2] = {
|
||||
{ IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
|
||||
{ IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
|
||||
{ IDX_MIXER_BASSTREBLE, 0x0000 },
|
||||
|
@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream)
|
|||
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
|
||||
|
||||
snd_azf3328_dbgcallenter();
|
||||
|
||||
chip->playback_substream = NULL;
|
||||
snd_azf3328_dbgcallleave();
|
||||
return 0;
|
||||
|
@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG_MISC
|
||||
static void
|
||||
snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
|
||||
{
|
||||
#if DEBUG_MISC
|
||||
u16 tmp;
|
||||
|
||||
snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
|
||||
|
@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
|
|||
for (tmp=0; tmp <= 0x01; tmp += 1)
|
||||
snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
|
||||
|
||||
for (tmp = 0; tmp <= 0x6E; tmp += 2)
|
||||
snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp));
|
||||
#endif
|
||||
for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
|
||||
snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp));
|
||||
|
||||
for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
|
||||
snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp));
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}
|
||||
#endif
|
||||
|
||||
static int __devinit
|
||||
snd_azf3328_create(struct snd_card *card,
|
||||
|
@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
|
|||
|
||||
#ifdef MODULE
|
||||
printk(
|
||||
"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
|
||||
"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
|
||||
"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
|
||||
"azt3328: Hardware was completely undocumented, unfortunately.\n"
|
||||
"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
|
||||
"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
|
||||
1024000 / seqtimer_scaling, seqtimer_scaling);
|
||||
|
|
|
@ -106,8 +106,8 @@
|
|||
#define IRQ_RECORDING 0x0002
|
||||
#define IRQ_MPU401 0x0010
|
||||
#define IRQ_TIMER 0x0020 /* DirectX timer */
|
||||
#define IRQ_UNKNOWN1 0x0040 /* probably unused */
|
||||
#define IRQ_UNKNOWN2 0x0080 /* probably unused */
|
||||
#define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */
|
||||
#define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */
|
||||
#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
|
||||
#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
|
||||
#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */
|
||||
|
|
|
@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
|
|||
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
|
||||
/* Viewcast Osprey 200 */
|
||||
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
|
||||
/* ATI TV-Wonder */
|
||||
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000),
|
||||
/* Leadtek Winfast tv 2000xp delux */
|
||||
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
|
||||
/* Voodoo TV 200 */
|
||||
|
@ -833,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
|
|||
pci->device, pci->subsystem_vendor, pci->subsystem_device);
|
||||
snd_printk(KERN_DEBUG "please mail id, board name, and, "
|
||||
"if it works, the correct digital_rate option to "
|
||||
"<alsa-devel@lists.sf.net>\n");
|
||||
"<alsa-devel@alsa-project.org>\n");
|
||||
return 32000; /* default rate */
|
||||
}
|
||||
|
||||
|
|
|
@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
|
|||
struct snd_ca0106_pcm *epcm;
|
||||
int channel;
|
||||
int result = 0;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
u32 basic = 0;
|
||||
u32 extended = 0;
|
||||
|
@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
|
|||
running=0;
|
||||
break;
|
||||
}
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
runtime = s->runtime;
|
||||
epcm = runtime->private_data;
|
||||
channel = epcm->channel_id;
|
||||
|
|
|
@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
|
|||
snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
|
||||
snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n");
|
||||
snd_printk(KERN_ERR " broken or not working on your soundcard upon\n");
|
||||
snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n");
|
||||
snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n");
|
||||
|
||||
return -EIO;
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -56,6 +56,8 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/darla20_dsp.fw");
|
||||
|
||||
#define FW_DARLA20_DSP 0
|
||||
|
||||
static const struct firmware card_fw[] = {
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/darla24_dsp.fw");
|
||||
|
||||
#define FW_DARLA24_DSP 0
|
||||
|
||||
static const struct firmware card_fw[] = {
|
||||
|
|
|
@ -68,6 +68,10 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/echo3g_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/3g_asic.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_ECHO3G_DSP 1
|
||||
#define FW_3G_ASIC 2
|
||||
|
|
|
@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
|||
struct audiopipe *pipe = runtime->private_data;
|
||||
int i, err;
|
||||
u32 channelmask = 0;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
for (i = 0; i < DSP_MAXPIPES; i++) {
|
||||
if (s == chip->substream[i]) {
|
||||
channelmask |= 1 << i;
|
||||
|
|
|
@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip)
|
|||
|
||||
chip->asic_code = &card_fw[FW_3G_ASIC];
|
||||
|
||||
/* Now give the new ASIC a little time to set up */
|
||||
mdelay(2);
|
||||
/* Now give the new ASIC some time to set up */
|
||||
msleep(1000);
|
||||
/* See if it worked */
|
||||
box_type = check_asic_status(chip);
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/gina20_dsp.fw");
|
||||
|
||||
#define FW_GINA20_DSP 0
|
||||
|
||||
static const struct firmware card_fw[] = {
|
||||
|
|
|
@ -66,6 +66,12 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/gina24_301_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/gina24_361_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/gina24_301_asic.fw");
|
||||
MODULE_FIRMWARE("ea/gina24_361_asic.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_GINA24_301_DSP 1
|
||||
#define FW_GINA24_361_DSP 2
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/indigo_dsp.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_INDIGO_DSP 1
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/indigo_dj_dsp.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_INDIGO_DJ_DSP 1
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/indigo_io_dsp.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_INDIGO_IO_DSP 1
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/layla20_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/layla20_asic.fw");
|
||||
|
||||
#define FW_LAYLA20_DSP 0
|
||||
#define FW_LAYLA20_ASIC 1
|
||||
|
||||
|
|
|
@ -68,6 +68,12 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/layla24_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/layla24_1_asic.fw");
|
||||
MODULE_FIRMWARE("ea/layla24_2A_asic.fw");
|
||||
MODULE_FIRMWARE("ea/layla24_2S_asic.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_LAYLA24_DSP 1
|
||||
#define FW_LAYLA24_1_ASIC 2
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/mia_dsp.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_MIA_DSP 1
|
||||
|
||||
|
|
|
@ -64,6 +64,15 @@
|
|||
#include <asm/atomic.h>
|
||||
#include "echoaudio.h"
|
||||
|
||||
MODULE_FIRMWARE("ea/loader_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/mona_301_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/mona_361_dsp.fw");
|
||||
MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw");
|
||||
MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw");
|
||||
MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw");
|
||||
MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw");
|
||||
MODULE_FIRMWARE("ea/mona_2_asic.fw");
|
||||
|
||||
#define FW_361_LOADER 0
|
||||
#define FW_MONA_301_DSP 1
|
||||
#define FW_MONA_361_DSP 2
|
||||
|
|
|
@ -49,6 +49,13 @@
|
|||
#include "p17v.h"
|
||||
|
||||
|
||||
#define HANA_FILENAME "emu/hana.fw"
|
||||
#define DOCK_FILENAME "emu/audio_dock.fw"
|
||||
|
||||
MODULE_FIRMWARE(HANA_FILENAME);
|
||||
MODULE_FIRMWARE(DOCK_FILENAME);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* EMU10K1 init / done
|
||||
*************************************************************************/
|
||||
|
@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
|
|||
int tmp,tmp2;
|
||||
int reg;
|
||||
int err;
|
||||
const char *hana_filename = "emu/hana.fw";
|
||||
const char *dock_filename = "emu/audio_dock.fw";
|
||||
|
||||
snd_printk(KERN_INFO "emu1010: Special config.\n");
|
||||
/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
|
||||
|
@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
|
|||
return -ENODEV;
|
||||
}
|
||||
snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
|
||||
if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) {
|
||||
snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename);
|
||||
if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) {
|
||||
snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -938,7 +943,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
|
|||
/* Return to Audio Dock programming mode */
|
||||
snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
|
||||
if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) {
|
||||
if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
|
||||
return err;
|
||||
}
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
|
||||
|
@ -1216,6 +1221,15 @@ static struct snd_emu_chip_details emu_chip_details[] = {
|
|||
.spi_dac = 1,
|
||||
.i2c_adc = 1,
|
||||
.spk71 = 1} ,
|
||||
{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
|
||||
.driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",
|
||||
.id = "EMU1010",
|
||||
.emu10k2_chip = 1,
|
||||
.ca0108_chip = 1,
|
||||
.ca_cardbus_chip = 1,
|
||||
.spi_dac = 1,
|
||||
.i2c_adc = 1,
|
||||
.spk71 = 1} ,
|
||||
{.vendor = 0x1102, .device = 0x0008,
|
||||
.driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
|
||||
.id = "Audigy2",
|
||||
|
|
|
@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
|
|||
struct snd_emu10k1_pcm *epcm;
|
||||
int channel;
|
||||
int result = 0;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
u32 basic = 0;
|
||||
u32 inte = 0;
|
||||
|
@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
|
|||
running = 0;
|
||||
break;
|
||||
}
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
runtime = s->runtime;
|
||||
epcm = runtime->private_data;
|
||||
channel = substream->pcm->device-emu->p16v_device_offset;
|
||||
|
|
|
@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
|
|||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
{
|
||||
unsigned int what = 0;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
if (s == ensoniq->playback1_substream) {
|
||||
what |= ES_P1_PAUSE;
|
||||
snd_pcm_trigger_done(s, substream);
|
||||
|
@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
|
|||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
{
|
||||
unsigned int what = 0;
|
||||
struct list_head *pos;
|
||||
struct snd_pcm_substream *s;
|
||||
snd_pcm_group_for_each(pos, substream) {
|
||||
s = snd_pcm_group_substream_entry(pos);
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
if (s == ensoniq->playback1_substream) {
|
||||
what |= ES_DAC1_EN;
|
||||
snd_pcm_trigger_done(s, substream);
|
||||
|
|
|
@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
|
|||
runtime->hw = snd_es1968_playback;
|
||||
runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
|
||||
calc_available_memory_size(chip);
|
||||
#if 0
|
||||
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
1024);
|
||||
#endif
|
||||
|
||||
spin_lock_irq(&chip->substream_lock);
|
||||
list_add(&es->list, &chip->substream_list);
|
||||
spin_unlock_irq(&chip->substream_lock);
|
||||
|
@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
|
|||
runtime->hw = snd_es1968_capture;
|
||||
runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
|
||||
calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
|
||||
#if 0
|
||||
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
1024);
|
||||
#endif
|
||||
snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
|
||||
|
||||
spin_lock_irq(&chip->substream_lock);
|
||||
list_add(&es->list, &chip->substream_list);
|
||||
spin_unlock_irq(&chip->substream_lock);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
snd-hda-intel-objs := hda_intel.o
|
||||
snd-hda-codec-objs := hda_codec.o \
|
||||
# since snd-hda-intel is the only driver using hda-codec,
|
||||
# merge it into a single module although it was originally
|
||||
# designed to be individual modules
|
||||
snd-hda-intel-objs += hda_codec.o \
|
||||
hda_generic.o \
|
||||
patch_realtek.o \
|
||||
patch_cmedia.o \
|
||||
|
@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \
|
|||
patch_conexant.o \
|
||||
patch_via.o
|
||||
ifdef CONFIG_PROC_FS
|
||||
snd-hda-codec-objs += hda_proc.o
|
||||
snd-hda-intel-objs += hda_proc.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -233,7 +233,7 @@ enum {
|
|||
*/
|
||||
|
||||
/* Amp gain/mute */
|
||||
#define AC_AMP_MUTE (1<<8)
|
||||
#define AC_AMP_MUTE (1<<7)
|
||||
#define AC_AMP_GAIN (0x7f)
|
||||
#define AC_AMP_GET_INDEX (0xf<<0)
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
|
|||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
memcpy(node->conn_list, conn_list, nconns);
|
||||
memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
|
||||
node->nconns = nconns;
|
||||
node->wid_caps = get_wcaps(codec, nid);
|
||||
node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||
|
|
|
@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
|
|||
"{ATI, SB600},"
|
||||
"{ATI, RS600},"
|
||||
"{ATI, RS690},"
|
||||
"{ATI, RS780},"
|
||||
"{ATI, R600},"
|
||||
"{VIA, VT8251},"
|
||||
"{VIA, VT8237A},"
|
||||
"{SiS, SIS966},"
|
||||
|
@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
|||
#define RIRB_INT_MASK 0x05
|
||||
|
||||
/* STATESTS int mask: SD2,SD1,SD0 */
|
||||
#define AZX_MAX_CODECS 3
|
||||
#define STATESTS_INT_MASK 0x07
|
||||
|
||||
/* SD_CTL bits */
|
||||
|
@ -978,7 +981,7 @@ static unsigned int azx_max_codecs[] __devinitdata = {
|
|||
static int __devinit azx_codec_create(struct azx *chip, const char *model)
|
||||
{
|
||||
struct hda_bus_template bus_temp;
|
||||
int c, codecs, err;
|
||||
int c, codecs, audio_codecs, err;
|
||||
|
||||
memset(&bus_temp, 0, sizeof(bus_temp));
|
||||
bus_temp.private_data = chip;
|
||||
|
@ -990,8 +993,21 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
|
|||
if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
|
||||
return err;
|
||||
|
||||
codecs = 0;
|
||||
for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
|
||||
codecs = audio_codecs = 0;
|
||||
for (c = 0; c < AZX_MAX_CODECS; c++) {
|
||||
if ((chip->codec_mask & (1 << c)) & probe_mask) {
|
||||
struct hda_codec *codec;
|
||||
err = snd_hda_codec_new(chip->bus, c, &codec);
|
||||
if (err < 0)
|
||||
continue;
|
||||
codecs++;
|
||||
if (codec->afg)
|
||||
audio_codecs++;
|
||||
}
|
||||
}
|
||||
if (!audio_codecs) {
|
||||
/* probe additional slots if no codec is found */
|
||||
for (; c < azx_max_codecs[chip->driver_type]; c++) {
|
||||
if ((chip->codec_mask & (1 << c)) & probe_mask) {
|
||||
err = snd_hda_codec_new(chip->bus, c, NULL);
|
||||
if (err < 0)
|
||||
|
@ -999,7 +1015,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
|
|||
codecs++;
|
||||
}
|
||||
}
|
||||
if (! codecs) {
|
||||
}
|
||||
if (!codecs) {
|
||||
snd_printk(KERN_ERR SFX "no codecs initialized\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
@ -1518,7 +1535,7 @@ static int azx_dev_free(struct snd_device *device)
|
|||
/*
|
||||
* white/black-listing for position_fix
|
||||
*/
|
||||
static const struct snd_pci_quirk position_fix_list[] __devinitdata = {
|
||||
static struct snd_pci_quirk position_fix_list[] __devinitdata = {
|
||||
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
|
||||
{}
|
||||
};
|
||||
|
@ -1758,6 +1775,8 @@ static struct pci_device_id azx_ids[] = {
|
|||
{ 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
|
||||
{ 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
|
||||
{ 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
|
||||
{ 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */
|
||||
{ 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */
|
||||
{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
|
||||
{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
|
||||
{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
|
||||
|
|
|
@ -148,6 +148,11 @@ struct hda_multi_out {
|
|||
|
||||
int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
|
||||
int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
|
||||
int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream);
|
||||
int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
|
||||
struct snd_pcm_substream *substream);
|
||||
int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
|
||||
|
@ -217,6 +222,12 @@ enum {
|
|||
AUTO_PIN_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
AUTO_PIN_LINE_OUT,
|
||||
AUTO_PIN_SPEAKER_OUT,
|
||||
AUTO_PIN_HP_OUT
|
||||
};
|
||||
|
||||
extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
|
||||
|
||||
struct auto_pin_cfg {
|
||||
|
@ -225,6 +236,7 @@ struct auto_pin_cfg {
|
|||
int speaker_outs;
|
||||
hda_nid_t speaker_pins[5];
|
||||
int hp_outs;
|
||||
int line_out_type; /* AUTO_PIN_XXX_OUT */
|
||||
hda_nid_t hp_pins[5];
|
||||
hda_nid_t input_pins[AUTO_PIN_LAST];
|
||||
hda_nid_t dig_out_pin;
|
||||
|
|
|
@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
|
|||
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
|
||||
}
|
||||
|
||||
static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
|
||||
format, substream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Analog capture
|
||||
*/
|
||||
|
@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
|
|||
.nid = 0, /* fill later */
|
||||
.ops = {
|
||||
.open = ad198x_dig_playback_pcm_open,
|
||||
.close = ad198x_dig_playback_pcm_close
|
||||
.close = ad198x_dig_playback_pcm_close,
|
||||
.prepare = ad198x_dig_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -739,41 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = {
|
|||
{ } /* end */
|
||||
};
|
||||
|
||||
/* additional verbs for 3-stack model */
|
||||
static struct hda_verb ad1986a_3st_init_verbs[] = {
|
||||
/* Mic and line-in selectors */
|
||||
{0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
|
||||
{0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_verb ad1986a_ch2_init[] = {
|
||||
/* Surround out -> Line In */
|
||||
{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
|
||||
{ 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
|
||||
{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
|
||||
/* Line-in selectors */
|
||||
{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
|
||||
/* CLFE -> Mic in */
|
||||
{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
|
||||
{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
|
||||
{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
|
||||
/* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
|
||||
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_verb ad1986a_ch4_init[] = {
|
||||
/* Surround out -> Surround */
|
||||
{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
|
||||
{ 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
|
||||
{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
|
||||
{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
/* CLFE -> Mic in */
|
||||
{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
|
||||
{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
|
||||
{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
|
||||
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_verb ad1986a_ch6_init[] = {
|
||||
/* Surround out -> Surround out */
|
||||
{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
|
||||
{ 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
|
||||
{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
|
||||
{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
/* CLFE -> CLFE */
|
||||
{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
|
||||
{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
|
||||
{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
|
||||
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
|
@ -828,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
|
||||
SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
|
||||
SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
|
||||
SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
|
||||
SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
|
||||
SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
|
||||
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
|
||||
|
@ -882,9 +889,8 @@ static int patch_ad1986a(struct hda_codec *codec)
|
|||
case AD1986A_3STACK:
|
||||
spec->num_mixers = 2;
|
||||
spec->mixers[1] = ad1986a_3st_mixers;
|
||||
spec->num_init_verbs = 3;
|
||||
spec->init_verbs[1] = ad1986a_3st_init_verbs;
|
||||
spec->init_verbs[2] = ad1986a_ch2_init;
|
||||
spec->num_init_verbs = 2;
|
||||
spec->init_verbs[1] = ad1986a_ch2_init;
|
||||
spec->channel_mode = ad1986a_modes;
|
||||
spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
|
||||
spec->need_dac_fix = 1;
|
||||
|
@ -1892,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
|
|||
|
||||
sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
|
||||
if (sel > 0) {
|
||||
sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0);
|
||||
if (sel <= 3)
|
||||
sel = snd_hda_codec_read(codec, 0x0b, 0,
|
||||
AC_VERB_GET_CONNECT_SEL, 0);
|
||||
if (sel < 3)
|
||||
sel++;
|
||||
else
|
||||
sel = 0;
|
||||
|
@ -1906,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
|
|||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
unsigned int sel;
|
||||
unsigned int val, sel;
|
||||
int change;
|
||||
|
||||
val = ucontrol->value.enumerated.item[0];
|
||||
sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
|
||||
if (! ucontrol->value.enumerated.item[0]) {
|
||||
if (!val) {
|
||||
change = sel != 0;
|
||||
if (change)
|
||||
snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0);
|
||||
if (change || codec->in_resume)
|
||||
snd_hda_codec_write(codec, 0x02, 0,
|
||||
AC_VERB_SET_CONNECT_SEL, 0);
|
||||
} else {
|
||||
change = sel == 0;
|
||||
if (change)
|
||||
snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1);
|
||||
sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1;
|
||||
change |= sel == ucontrol->value.enumerated.item[0];
|
||||
if (change)
|
||||
snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL,
|
||||
ucontrol->value.enumerated.item[0] - 1);
|
||||
if (change || codec->in_resume)
|
||||
snd_hda_codec_write(codec, 0x02, 0,
|
||||
AC_VERB_SET_CONNECT_SEL, 1);
|
||||
sel = snd_hda_codec_read(codec, 0x0b, 0,
|
||||
AC_VERB_GET_CONNECT_SEL, 0) + 1;
|
||||
change |= sel != val;
|
||||
if (change || codec->in_resume)
|
||||
snd_hda_codec_write(codec, 0x0b, 0,
|
||||
AC_VERB_SET_CONNECT_SEL, val - 1);
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
|
|||
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
|
||||
}
|
||||
|
||||
static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct atihdmi_spec *spec = codec->spec;
|
||||
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
|
||||
format, substream);
|
||||
}
|
||||
|
||||
static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
|
||||
.substreams = 1,
|
||||
.channels_min = 2,
|
||||
|
@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
|
|||
.nid = 0x2, /* NID to query formats and rates and setup streams */
|
||||
.ops = {
|
||||
.open = atihdmi_dig_playback_pcm_open,
|
||||
.close = atihdmi_dig_playback_pcm_close
|
||||
.close = atihdmi_dig_playback_pcm_close,
|
||||
.prepare = atihdmi_dig_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -160,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec)
|
|||
*/
|
||||
struct hda_codec_preset snd_hda_preset_atihdmi[] = {
|
||||
{ .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
|
||||
{ .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi },
|
||||
{ .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
|
||||
{ .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi },
|
||||
{} /* terminator */
|
||||
};
|
||||
|
|
|
@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
|
|||
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
|
||||
}
|
||||
|
||||
static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct cmi_spec *spec = codec->spec;
|
||||
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
|
||||
format, substream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Analog capture
|
||||
*/
|
||||
|
@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = {
|
|||
/* NID is set in cmi9880_build_pcms */
|
||||
.ops = {
|
||||
.open = cmi9880_dig_playback_pcm_open,
|
||||
.close = cmi9880_dig_playback_pcm_close
|
||||
.close = cmi9880_dig_playback_pcm_close,
|
||||
.prepare = cmi9880_dig_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
|
|||
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
|
||||
}
|
||||
|
||||
static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
|
||||
stream_tag,
|
||||
format, substream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Analog capture
|
||||
*/
|
||||
|
@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = {
|
|||
.nid = 0, /* fill later */
|
||||
.ops = {
|
||||
.open = conexant_dig_playback_pcm_open,
|
||||
.close = conexant_dig_playback_pcm_close
|
||||
.close = conexant_dig_playback_pcm_close,
|
||||
.prepare = conexant_dig_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -452,115 +465,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
|
|||
.put = conexant_ch_mode_put, \
|
||||
.private_value = nid | (dir<<16) }
|
||||
|
||||
static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
hda_nid_t nid = kcontrol->private_value & 0xffff;
|
||||
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
long *valp = ucontrol->value.integer.value;
|
||||
unsigned int val = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_DATA, 0x00);
|
||||
|
||||
*valp = (val & mask) != 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
hda_nid_t nid = kcontrol->private_value & 0xffff;
|
||||
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
long val = *ucontrol->value.integer.value;
|
||||
unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_GPIO_DATA,
|
||||
0x00);
|
||||
unsigned int old_data = gpio_data;
|
||||
|
||||
/* Set/unset the masked GPIO bit(s) as needed */
|
||||
if (val == 0)
|
||||
gpio_data &= ~mask;
|
||||
else
|
||||
gpio_data |= mask;
|
||||
if (gpio_data == old_data && !codec->in_resume)
|
||||
return 0;
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
|
||||
.info = cxt_gpio_data_info, \
|
||||
.get = cxt_gpio_data_get, \
|
||||
.put = cxt_gpio_data_put, \
|
||||
.private_value = nid | (mask<<16) }
|
||||
#if 0
|
||||
static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
hda_nid_t nid = kcontrol->private_value & 0xffff;
|
||||
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
long *valp = ucontrol->value.integer.value;
|
||||
unsigned int val = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_DIGI_CONVERT, 0x00);
|
||||
|
||||
*valp = (val & mask) != 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
hda_nid_t nid = kcontrol->private_value & 0xffff;
|
||||
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
long val = *ucontrol->value.integer.value;
|
||||
unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_DIGI_CONVERT,
|
||||
0x00);
|
||||
unsigned int old_data = ctrl_data;
|
||||
|
||||
/* Set/unset the masked control bit(s) as needed */
|
||||
if (val == 0)
|
||||
ctrl_data &= ~mask;
|
||||
else
|
||||
ctrl_data |= mask;
|
||||
if (ctrl_data == old_data && !codec->in_resume)
|
||||
return 0;
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
|
||||
ctrl_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
|
||||
.info = cxt_spdif_ctrl_info, \
|
||||
.get = cxt_spdif_ctrl_get, \
|
||||
.put = cxt_spdif_ctrl_put, \
|
||||
.private_value = nid | (mask<<16) }
|
||||
#endif
|
||||
#endif /* CONFIG_SND_DEBUG */
|
||||
|
||||
/* Conexant 5045 specific */
|
||||
|
@ -599,6 +503,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
|
|||
bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
|
||||
snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
|
||||
snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
|
||||
|
||||
bits = spec->cur_eapd ? 0 : 0x80;
|
||||
snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits);
|
||||
snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits);
|
||||
|
@ -624,6 +529,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol,
|
|||
return change;
|
||||
}
|
||||
|
||||
/* toggle input of built-in and mic jack appropriately */
|
||||
static void cxt5045_hp_automic(struct hda_codec *codec)
|
||||
{
|
||||
static struct hda_verb mic_jack_on[] = {
|
||||
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
|
||||
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
|
||||
{}
|
||||
};
|
||||
static struct hda_verb mic_jack_off[] = {
|
||||
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
|
||||
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
|
||||
{}
|
||||
};
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x12, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
if (present)
|
||||
snd_hda_sequence_write(codec, mic_jack_on);
|
||||
else
|
||||
snd_hda_sequence_write(codec, mic_jack_off);
|
||||
}
|
||||
|
||||
|
||||
/* mute internal speaker if HP is plugged */
|
||||
static void cxt5045_hp_automute(struct hda_codec *codec)
|
||||
|
@ -648,6 +576,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
|
|||
case CONEXANT_HP_EVENT:
|
||||
cxt5045_hp_automute(codec);
|
||||
break;
|
||||
case CONEXANT_MIC_EVENT:
|
||||
cxt5045_hp_automic(codec);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,12 +591,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
|
|||
.get = conexant_mux_enum_get,
|
||||
.put = conexant_mux_enum_put
|
||||
},
|
||||
HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Master Playback Volume",
|
||||
|
@ -688,7 +618,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
|
|||
static struct hda_verb cxt5045_init_verbs[] = {
|
||||
/* Line in, Mic */
|
||||
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
|
||||
/* HP, Amp */
|
||||
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
|
||||
{0x17, AC_VERB_SET_CONNECT_SEL,0x01},
|
||||
|
@ -701,18 +631,29 @@ static struct hda_verb cxt5045_init_verbs[] = {
|
|||
{0x17, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04},
|
||||
/* Record selector: Int mic */
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL,0x0},
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
|
||||
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
|
||||
/* SPDIF route: PCM */
|
||||
{ 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
/* pin sensing on HP and Mic jacks */
|
||||
{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
|
||||
/* EAPD */
|
||||
{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
|
||||
static struct hda_verb cxt5045_hp_sense_init_verbs[] = {
|
||||
/* pin sensing on HP jack */
|
||||
{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
|
||||
/* pin sensing on HP jack */
|
||||
{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
/* Test configuration for debugging, modelled after the ALC260 test
|
||||
* configuration.
|
||||
|
@ -733,6 +674,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
|
|||
/* Output controls */
|
||||
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
|
||||
|
||||
/* Modes for retasking pin widgets */
|
||||
CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
|
||||
|
@ -742,25 +687,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
|
|||
CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
|
||||
|
||||
/* Loopback mixer controls */
|
||||
HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT),
|
||||
|
||||
HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Input Source",
|
||||
|
@ -768,14 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
|
|||
.get = conexant_mux_enum_get,
|
||||
.put = conexant_mux_enum_put,
|
||||
},
|
||||
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct hda_verb cxt5045_test_init_verbs[] = {
|
||||
/* Set connections */
|
||||
{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
{ 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
/* Enable retasking pins as output, initially without power amp */
|
||||
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
|
||||
/* Disable digital (SPDIF) pins initially, but users can enable
|
||||
* them via a mixer switch. In the case of SPDIF-out, this initverb
|
||||
|
@ -804,6 +744,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = {
|
|||
* pin)
|
||||
*/
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
|
||||
{0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
|
||||
|
||||
/* Mute all inputs to mixer widget (even unconnected ones) */
|
||||
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
|
||||
|
@ -828,6 +769,7 @@ static int cxt5045_init(struct hda_codec *codec)
|
|||
|
||||
enum {
|
||||
CXT5045_LAPTOP, /* Laptops w/ EAPD support */
|
||||
CXT5045_FUJITSU, /* Laptops w/ EAPD support */
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
CXT5045_TEST,
|
||||
#endif
|
||||
|
@ -836,6 +778,7 @@ enum {
|
|||
|
||||
static const char *cxt5045_models[CXT5045_MODELS] = {
|
||||
[CXT5045_LAPTOP] = "laptop",
|
||||
[CXT5045_FUJITSU] = "fujitsu",
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
[CXT5045_TEST] = "test",
|
||||
#endif
|
||||
|
@ -844,7 +787,11 @@ static const char *cxt5045_models[CXT5045_MODELS] = {
|
|||
static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP),
|
||||
SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP),
|
||||
SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP),
|
||||
SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP),
|
||||
SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP),
|
||||
SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP),
|
||||
SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU),
|
||||
SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP),
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -877,16 +824,23 @@ static int patch_cxt5045(struct hda_codec *codec)
|
|||
|
||||
|
||||
codec->patch_ops = conexant_patch_ops;
|
||||
codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
|
||||
|
||||
board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
|
||||
cxt5045_models,
|
||||
cxt5045_cfg_tbl);
|
||||
switch (board_config) {
|
||||
case CXT5045_LAPTOP:
|
||||
codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
|
||||
spec->input_mux = &cxt5045_capture_source;
|
||||
spec->num_init_verbs = 2;
|
||||
spec->init_verbs[1] = cxt5045_init_verbs;
|
||||
spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
|
||||
spec->mixers[0] = cxt5045_mixers;
|
||||
codec->patch_ops.init = cxt5045_init;
|
||||
break;
|
||||
case CXT5045_FUJITSU:
|
||||
spec->input_mux = &cxt5045_capture_source;
|
||||
spec->num_init_verbs = 2;
|
||||
spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
|
||||
spec->mixers[0] = cxt5045_mixers;
|
||||
codec->patch_ops.init = cxt5045_init;
|
||||
break;
|
||||
|
@ -913,10 +867,9 @@ static struct hda_channel_mode cxt5047_modes[1] = {
|
|||
};
|
||||
|
||||
static struct hda_input_mux cxt5047_capture_source = {
|
||||
.num_items = 2,
|
||||
.num_items = 1,
|
||||
.items = {
|
||||
{ "ExtMic", 0x0 },
|
||||
{ "IntMic", 0x1 },
|
||||
{ "Mic", 0x2 },
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1009,7 +962,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec)
|
|||
};
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x08, 0,
|
||||
present = snd_hda_codec_read(codec, 0x15, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
if (present)
|
||||
snd_hda_sequence_write(codec, mic_jack_on);
|
||||
|
@ -1033,37 +986,20 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
|
|||
}
|
||||
|
||||
static struct snd_kcontrol_new cxt5047_mixers[] = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Capture Source",
|
||||
.info = conexant_mux_enum_info,
|
||||
.get = conexant_mux_enum_get,
|
||||
.put = conexant_mux_enum_put
|
||||
},
|
||||
HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Master Playback Volume",
|
||||
.info = snd_hda_mixer_amp_volume_info,
|
||||
.get = snd_hda_mixer_amp_volume_get,
|
||||
.put = cxt5047_hp_master_vol_put,
|
||||
.private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
|
||||
},
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Master Playback Switch",
|
||||
.info = cxt_eapd_info,
|
||||
.get = cxt_eapd_get,
|
||||
.put = cxt5047_hp_master_sw_put,
|
||||
.private_value = 0x13,
|
||||
},
|
||||
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT),
|
||||
|
||||
{}
|
||||
};
|
||||
|
@ -1133,18 +1069,19 @@ static struct hda_verb cxt5047_init_verbs[] = {
|
|||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
|
||||
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
|
||||
/* HP, Amp, Speaker */
|
||||
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
|
||||
{0x1A, AC_VERB_SET_CONNECT_SEL,0x00},
|
||||
/* HP, Speaker */
|
||||
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
|
||||
{0x13, AC_VERB_SET_CONNECT_SEL,0x1},
|
||||
{0x1d, AC_VERB_SET_CONNECT_SEL,0x0},
|
||||
/* Record selector: Mic */
|
||||
{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
|
||||
{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
|
||||
{0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
|
||||
{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
|
||||
{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
|
||||
{0x1d, AC_VERB_SET_CONNECT_SEL,0x0},
|
||||
/* Record selector: Front mic */
|
||||
{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
|
||||
{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
|
||||
/* SPDIF route: PCM */
|
||||
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
|
||||
/* Enable unsolicited events */
|
||||
|
@ -1161,8 +1098,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
|
|||
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
|
||||
/* Speaker routing */
|
||||
{0x1d, AC_VERB_SET_CONNECT_SEL,0x1},
|
||||
/* Change default to ExtMic for recording */
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL,0x2},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -1172,7 +1107,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = {
|
|||
{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
|
||||
/* Record selector: Ext Mic */
|
||||
{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL,0x02},
|
||||
{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
|
||||
/* Speaker routing */
|
||||
|
@ -1242,14 +1176,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
|
|||
.get = conexant_mux_enum_get,
|
||||
.put = conexant_mux_enum_put,
|
||||
},
|
||||
/* Controls for GPIO pins, assuming they exist and are configured
|
||||
* as outputs
|
||||
*/
|
||||
CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
|
||||
CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
|
||||
CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
|
||||
CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
|
||||
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -62,6 +62,7 @@ enum {
|
|||
STAC_MACBOOK,
|
||||
STAC_MACBOOK_PRO_V1,
|
||||
STAC_MACBOOK_PRO_V2,
|
||||
STAC_IMAC_INTEL,
|
||||
STAC_922X_MODELS
|
||||
};
|
||||
|
||||
|
@ -175,8 +176,8 @@ static hda_nid_t stac9205_mux_nids[2] = {
|
|||
0x19, 0x1a
|
||||
};
|
||||
|
||||
static hda_nid_t stac9205_dmic_nids[3] = {
|
||||
0x17, 0x18, 0
|
||||
static hda_nid_t stac9205_dmic_nids[2] = {
|
||||
0x17, 0x18,
|
||||
};
|
||||
|
||||
static hda_nid_t stac9200_pin_nids[8] = {
|
||||
|
@ -524,12 +525,6 @@ static unsigned int d945gtp5_pin_configs[10] = {
|
|||
0x02a19320, 0x40000100,
|
||||
};
|
||||
|
||||
static unsigned int macbook_pin_configs[10] = {
|
||||
0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110,
|
||||
0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e,
|
||||
0x400000fc, 0x400000fb,
|
||||
};
|
||||
|
||||
static unsigned int macbook_pro_v1_pin_configs[10] = {
|
||||
0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010,
|
||||
0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e,
|
||||
|
@ -542,14 +537,21 @@ static unsigned int macbook_pro_v2_pin_configs[10] = {
|
|||
0x400000fc, 0x400000fb,
|
||||
};
|
||||
|
||||
static unsigned int imac_intel_pin_configs[10] = {
|
||||
0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe,
|
||||
0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa,
|
||||
0x400000fc, 0x400000fb,
|
||||
};
|
||||
|
||||
static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
|
||||
[STAC_D945_REF] = ref922x_pin_configs,
|
||||
[STAC_D945GTP3] = d945gtp3_pin_configs,
|
||||
[STAC_D945GTP5] = d945gtp5_pin_configs,
|
||||
[STAC_MACMINI] = d945gtp5_pin_configs,
|
||||
[STAC_MACBOOK] = macbook_pin_configs,
|
||||
[STAC_MACMINI] = macbook_pro_v1_pin_configs,
|
||||
[STAC_MACBOOK] = macbook_pro_v1_pin_configs,
|
||||
[STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs,
|
||||
[STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs,
|
||||
[STAC_IMAC_INTEL] = imac_intel_pin_configs,
|
||||
};
|
||||
|
||||
static const char *stac922x_models[STAC_922X_MODELS] = {
|
||||
|
@ -560,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
|
|||
[STAC_MACBOOK] = "macbook",
|
||||
[STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
|
||||
[STAC_MACBOOK_PRO_V2] = "macbook-pro",
|
||||
[STAC_IMAC_INTEL] = "imac-intel",
|
||||
};
|
||||
|
||||
static struct snd_pci_quirk stac922x_cfg_tbl[] = {
|
||||
|
@ -820,6 +823,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
|
|||
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
|
||||
}
|
||||
|
||||
static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
|
||||
stream_tag, format, substream);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Analog capture callbacks
|
||||
|
@ -854,7 +868,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
|
|||
/* NID is set in stac92xx_build_pcms */
|
||||
.ops = {
|
||||
.open = stac92xx_dig_playback_pcm_open,
|
||||
.close = stac92xx_dig_playback_pcm_close
|
||||
.close = stac92xx_dig_playback_pcm_close,
|
||||
.prepare = stac92xx_dig_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1055,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
|
|||
static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
unsigned int wcaps, wtype;
|
||||
int i, num_dacs = 0;
|
||||
|
||||
/* use the wcaps cache to count all DACs available for line-outs */
|
||||
for (i = 0; i < codec->num_nodes; i++) {
|
||||
wcaps = codec->wcaps[i];
|
||||
wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||
if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
|
||||
num_dacs++;
|
||||
}
|
||||
|
||||
snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
|
||||
|
||||
switch (cfg->line_outs) {
|
||||
case 3:
|
||||
/* add line-in as side */
|
||||
if (cfg->input_pins[AUTO_PIN_LINE]) {
|
||||
if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
|
||||
cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
|
||||
spec->line_switch = 1;
|
||||
cfg->line_outs++;
|
||||
|
@ -1067,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
|
|||
break;
|
||||
case 2:
|
||||
/* add line-in as clfe and mic as side */
|
||||
if (cfg->input_pins[AUTO_PIN_LINE]) {
|
||||
if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
|
||||
cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
|
||||
spec->line_switch = 1;
|
||||
cfg->line_outs++;
|
||||
}
|
||||
if (cfg->input_pins[AUTO_PIN_MIC]) {
|
||||
if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
|
||||
cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
|
||||
spec->mic_switch = 1;
|
||||
cfg->line_outs++;
|
||||
|
@ -1080,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
|
|||
break;
|
||||
case 1:
|
||||
/* add line-in as surr and mic as clfe */
|
||||
if (cfg->input_pins[AUTO_PIN_LINE]) {
|
||||
if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
|
||||
cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
|
||||
spec->line_switch = 1;
|
||||
cfg->line_outs++;
|
||||
}
|
||||
if (cfg->input_pins[AUTO_PIN_MIC]) {
|
||||
if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
|
||||
cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
|
||||
spec->mic_switch = 1;
|
||||
cfg->line_outs++;
|
||||
|
@ -1096,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < spec->multiout.num_dacs; i++) {
|
||||
if (spec->multiout.dac_nids[i] == nid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX The line_out pin widget connection list may not be set to the
|
||||
* desired DAC nid. This is the case on 927x where ports A and B can
|
||||
* be routed to several DACs.
|
||||
*
|
||||
* This requires an analysis of the line-out/hp pin configuration
|
||||
* to provide a best fit for pin/DAC configurations that are routable.
|
||||
* For now, 927x DAC4 is not supported and 927x DAC1 output to ports
|
||||
* A and B is not supported.
|
||||
* Fill in the dac_nids table from the parsed pin configuration
|
||||
* This function only works when every pin in line_out_pins[]
|
||||
* contains atleast one DAC in its connection list. Some 92xx
|
||||
* codecs are not connected directly to a DAC, such as the 9200
|
||||
* and 9202/925x. For those, dac_nids[] must be hard-coded.
|
||||
*/
|
||||
/* fill in the dac_nids table from the parsed pin configuration */
|
||||
static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
|
||||
const struct auto_pin_cfg *cfg)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
hda_nid_t nid;
|
||||
int i;
|
||||
int i, j, conn_len = 0;
|
||||
hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
|
||||
unsigned int wcaps, wtype;
|
||||
|
||||
/* check the pins hardwired to audio widget */
|
||||
for (i = 0; i < cfg->line_outs; i++) {
|
||||
nid = cfg->line_out_pins[i];
|
||||
spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
|
||||
conn_len = snd_hda_get_connections(codec, nid, conn,
|
||||
HDA_MAX_CONNECTIONS);
|
||||
for (j = 0; j < conn_len; j++) {
|
||||
wcaps = snd_hda_param_read(codec, conn[j],
|
||||
AC_PAR_AUDIO_WIDGET_CAP);
|
||||
wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||
|
||||
if (wtype != AC_WID_AUD_OUT ||
|
||||
(wcaps & AC_WCAP_DIGITAL))
|
||||
continue;
|
||||
/* conn[j] is a DAC routed to this line-out */
|
||||
if (!is_in_dac_nids(spec, conn[j]))
|
||||
break;
|
||||
}
|
||||
|
||||
spec->multiout.num_dacs = cfg->line_outs;
|
||||
if (j == conn_len) {
|
||||
/* error out, no available DAC found */
|
||||
snd_printk(KERN_ERR
|
||||
"%s: No available DAC for pin 0x%x\n",
|
||||
__func__, nid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spec->multiout.dac_nids[i] = conn[j];
|
||||
spec->multiout.num_dacs++;
|
||||
if (conn_len > 1) {
|
||||
/* select this DAC in the pin's input mux */
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_CONNECT_SEL, j);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
|
||||
spec->multiout.num_dacs,
|
||||
spec->multiout.dac_nids[0],
|
||||
spec->multiout.dac_nids[1],
|
||||
spec->multiout.dac_nids[2],
|
||||
spec->multiout.dac_nids[3],
|
||||
spec->multiout.dac_nids[4]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1189,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
|
|||
|
||||
static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < spec->multiout.num_dacs; i++) {
|
||||
if (spec->multiout.dac_nids[i] == nid)
|
||||
if (is_in_dac_nids(spec, nid))
|
||||
return 1;
|
||||
}
|
||||
if (spec->multiout.hp_nid == nid)
|
||||
return 1;
|
||||
return 0;
|
||||
|
@ -1236,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
|
|||
add_spec_dacs(spec, nid);
|
||||
}
|
||||
for (i = 0; i < cfg->speaker_outs; i++) {
|
||||
nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0,
|
||||
nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
|
||||
AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
|
||||
if (check_in_dac_nids(spec, nid))
|
||||
nid = 0;
|
||||
if (check_in_dac_nids(spec, nid))
|
||||
nid = 0;
|
||||
if (! nid)
|
||||
continue;
|
||||
add_spec_dacs(spec, nid);
|
||||
|
@ -1355,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
|
|||
imux->num_items++;
|
||||
}
|
||||
|
||||
if (imux->num_items == 1) {
|
||||
if (imux->num_items) {
|
||||
/*
|
||||
* Set the current input for the muxes.
|
||||
* The STAC9221 has two input muxes with identical source
|
||||
|
@ -1675,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
|
|||
{
|
||||
unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
|
||||
0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
|
||||
if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN))
|
||||
return;
|
||||
|
||||
/* if setting pin direction bits, clear the current
|
||||
direction bits first */
|
||||
if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
|
||||
pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
|
||||
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pin_ctl | flag);
|
||||
|
@ -1751,6 +1819,7 @@ static int stac92xx_resume(struct hda_codec *codec)
|
|||
|
||||
stac92xx_init(codec);
|
||||
stac92xx_set_config_regs(codec);
|
||||
snd_hda_resume_ctls(codec, spec->mixer);
|
||||
for (i = 0; i < spec->num_mixers; i++)
|
||||
snd_hda_resume_ctls(codec, spec->mixers[i]);
|
||||
if (spec->multiout.dig_out_nid)
|
||||
|
@ -1905,12 +1974,18 @@ static int patch_stac922x(struct hda_codec *codec)
|
|||
*/
|
||||
printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
|
||||
switch (codec->subsystem_id) {
|
||||
case 0x106b0a00: /* MacBook First generatoin */
|
||||
spec->board_config = STAC_MACBOOK;
|
||||
break;
|
||||
case 0x106b0200: /* MacBook Pro first generation */
|
||||
spec->board_config = STAC_MACBOOK_PRO_V1;
|
||||
break;
|
||||
case 0x106b1e00: /* MacBook Pro second generation */
|
||||
spec->board_config = STAC_MACBOOK_PRO_V2;
|
||||
break;
|
||||
case 0x106b0700: /* Intel-based iMac */
|
||||
spec->board_config = STAC_IMAC_INTEL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1931,7 +2006,7 @@ static int patch_stac922x(struct hda_codec *codec)
|
|||
|
||||
spec->adc_nids = stac922x_adc_nids;
|
||||
spec->mux_nids = stac922x_mux_nids;
|
||||
spec->num_muxes = 2;
|
||||
spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
|
||||
spec->num_dmics = 0;
|
||||
|
||||
spec->init = stac922x_core_init;
|
||||
|
@ -1992,7 +2067,7 @@ static int patch_stac927x(struct hda_codec *codec)
|
|||
case STAC_D965_3ST:
|
||||
spec->adc_nids = stac927x_adc_nids;
|
||||
spec->mux_nids = stac927x_mux_nids;
|
||||
spec->num_muxes = 3;
|
||||
spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
|
||||
spec->num_dmics = 0;
|
||||
spec->init = d965_core_init;
|
||||
spec->mixer = stac9227_mixer;
|
||||
|
@ -2000,7 +2075,7 @@ static int patch_stac927x(struct hda_codec *codec)
|
|||
case STAC_D965_5ST:
|
||||
spec->adc_nids = stac927x_adc_nids;
|
||||
spec->mux_nids = stac927x_mux_nids;
|
||||
spec->num_muxes = 3;
|
||||
spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
|
||||
spec->num_dmics = 0;
|
||||
spec->init = d965_core_init;
|
||||
spec->mixer = stac9227_mixer;
|
||||
|
@ -2008,7 +2083,7 @@ static int patch_stac927x(struct hda_codec *codec)
|
|||
default:
|
||||
spec->adc_nids = stac927x_adc_nids;
|
||||
spec->mux_nids = stac927x_mux_nids;
|
||||
spec->num_muxes = 3;
|
||||
spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
|
||||
spec->num_dmics = 0;
|
||||
spec->init = stac927x_core_init;
|
||||
spec->mixer = stac927x_mixer;
|
||||
|
@ -2067,9 +2142,9 @@ static int patch_stac9205(struct hda_codec *codec)
|
|||
|
||||
spec->adc_nids = stac9205_adc_nids;
|
||||
spec->mux_nids = stac9205_mux_nids;
|
||||
spec->num_muxes = 2;
|
||||
spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
|
||||
spec->dmic_nids = stac9205_dmic_nids;
|
||||
spec->num_dmics = 2;
|
||||
spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
|
||||
spec->dmux_nid = 0x1d;
|
||||
|
||||
spec->init = stac9205_core_init;
|
||||
|
@ -2294,6 +2369,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = {
|
|||
SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
|
||||
SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
|
||||
SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
|
||||
SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
|
|||
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
|
||||
}
|
||||
|
||||
static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
|
||||
stream_tag, format, substream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Analog capture
|
||||
*/
|
||||
|
@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
|
|||
/* NID is set in via_build_pcms */
|
||||
.ops = {
|
||||
.open = via_dig_playback_pcm_open,
|
||||
.close = via_dig_playback_pcm_close
|
||||
.close = via_dig_playback_pcm_close,
|
||||
.prepare = via_dig_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
|
|||
|
||||
|
||||
/* entry point */
|
||||
const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
|
||||
struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
|
||||
{
|
||||
.subvendor = VT1724_SUBDEVICE_AV710,
|
||||
.name = "Chaintech AV-710",
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#define WM_DAC_CTRL 0x02
|
||||
#define WM_INT_CTRL 0x03
|
||||
|
||||
extern const struct snd_ice1712_card_info snd_vt1724_amp_cards[];
|
||||
extern struct snd_ice1712_card_info snd_vt1724_amp_cards[];
|
||||
|
||||
|
||||
#endif /* __SOUND_AMP_H */
|
||||
|
|
|
@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
|
|||
* mixers
|
||||
*/
|
||||
|
||||
static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Master Playback Switch",
|
||||
|
@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new wm_controls[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "PCM Playback Switch",
|
||||
|
@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "AC97 Playback Switch",
|
||||
|
@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "AC97 Playback Switch",
|
||||
|
@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
|
|||
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
|
||||
|
@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
|
|||
* hence the driver needs to sets up it properly.
|
||||
*/
|
||||
|
||||
static const unsigned char aureon51_eeprom[] __devinitdata = {
|
||||
static unsigned char aureon51_eeprom[] __devinitdata = {
|
||||
[ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
|
||||
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
|
||||
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
|
||||
|
@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = {
|
|||
[ICE_EEP2_GPIO_STATE2] = 0x00,
|
||||
};
|
||||
|
||||
static const unsigned char aureon71_eeprom[] __devinitdata = {
|
||||
static unsigned char aureon71_eeprom[] __devinitdata = {
|
||||
[ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
|
||||
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
|
||||
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
|
||||
|
@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = {
|
|||
};
|
||||
#define prodigy71_eeprom aureon71_eeprom
|
||||
|
||||
static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
|
||||
static unsigned char prodigy71lt_eeprom[] __devinitdata = {
|
||||
[ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
|
||||
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
|
||||
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
|
||||
|
@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
|
|||
#define prodigy71xt_eeprom prodigy71lt_eeprom
|
||||
|
||||
/* entry point */
|
||||
const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
|
||||
struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
|
||||
{
|
||||
.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
|
||||
.name = "Terratec Aureon 5.1-Sky",
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */
|
||||
#define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/
|
||||
|
||||
extern const struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
|
||||
extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
|
||||
|
||||
/* GPIO bits */
|
||||
#define AUREON_CS8415_CS (1 << 22)
|
||||
|
|
|
@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
|
||||
static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
|
||||
{
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READ),
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
|
@ -429,7 +429,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __
|
|||
* initialize the chips on M-Audio cards
|
||||
*/
|
||||
|
||||
static const struct snd_akm4xxx akm_audiophile __devinitdata = {
|
||||
static struct snd_akm4xxx akm_audiophile __devinitdata = {
|
||||
.type = SND_AK4528,
|
||||
.num_adcs = 2,
|
||||
.num_dacs = 2,
|
||||
|
@ -438,7 +438,7 @@ static const struct snd_akm4xxx akm_audiophile __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 0,
|
||||
.data_mask = ICE1712_DELTA_AP_DOUT,
|
||||
|
@ -450,7 +450,7 @@ static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
|
|||
.mask_flags = 0,
|
||||
};
|
||||
|
||||
static const struct snd_akm4xxx akm_delta410 __devinitdata = {
|
||||
static struct snd_akm4xxx akm_delta410 __devinitdata = {
|
||||
.type = SND_AK4529,
|
||||
.num_adcs = 2,
|
||||
.num_dacs = 8,
|
||||
|
@ -459,7 +459,7 @@ static const struct snd_akm4xxx akm_delta410 __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
|
||||
.caddr = 0,
|
||||
.cif = 0,
|
||||
.data_mask = ICE1712_DELTA_AP_DOUT,
|
||||
|
@ -471,7 +471,7 @@ static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
|
|||
.mask_flags = 0,
|
||||
};
|
||||
|
||||
static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
|
||||
static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
|
||||
.type = SND_AK4524,
|
||||
.num_adcs = 8,
|
||||
.num_dacs = 8,
|
||||
|
@ -481,7 +481,7 @@ static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 0, /* the default level of the CIF pin from AK4524 */
|
||||
.data_mask = ICE1712_DELTA_1010LT_DOUT,
|
||||
|
@ -493,7 +493,7 @@ static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
|
|||
.mask_flags = 0,
|
||||
};
|
||||
|
||||
static const struct snd_akm4xxx akm_delta44 __devinitdata = {
|
||||
static struct snd_akm4xxx akm_delta44 __devinitdata = {
|
||||
.type = SND_AK4524,
|
||||
.num_adcs = 4,
|
||||
.num_dacs = 4,
|
||||
|
@ -503,7 +503,7 @@ static const struct snd_akm4xxx akm_delta44 __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 0, /* the default level of the CIF pin from AK4524 */
|
||||
.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
|
||||
|
@ -515,7 +515,7 @@ static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
|
|||
.mask_flags = 0,
|
||||
};
|
||||
|
||||
static const struct snd_akm4xxx akm_vx442 __devinitdata = {
|
||||
static struct snd_akm4xxx akm_vx442 __devinitdata = {
|
||||
.type = SND_AK4524,
|
||||
.num_adcs = 4,
|
||||
.num_dacs = 4,
|
||||
|
@ -525,7 +525,7 @@ static const struct snd_akm4xxx akm_vx442 __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 0,
|
||||
.data_mask = ICE1712_VX442_DOUT,
|
||||
|
@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
|
|||
* additional controls for M-Audio cards
|
||||
*/
|
||||
|
||||
static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
|
||||
static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
|
||||
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
|
||||
static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
|
||||
static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
|
||||
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
|
||||
static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
|
||||
static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
|
||||
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
|
||||
static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
|
||||
static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
|
||||
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
|
||||
static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
|
||||
static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
|
||||
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
|
||||
|
||||
|
||||
|
@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
|
|||
|
||||
|
||||
/* entry point */
|
||||
const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
|
||||
struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
|
||||
{
|
||||
.subvendor = ICE1712_SUBDEVICE_DELTA1010,
|
||||
.name = "M Audio Delta 1010",
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
|
||||
|
||||
/* entry point */
|
||||
extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[];
|
||||
extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
|
|||
|
||||
/*
|
||||
*/
|
||||
static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
|
||||
static struct snd_akm4xxx akm_ews88mt __devinitdata = {
|
||||
.num_adcs = 8,
|
||||
.num_dacs = 8,
|
||||
.type = SND_AK4524,
|
||||
|
@ -342,7 +342,7 @@ static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 1, /* CIF high */
|
||||
.data_mask = ICE1712_EWS88_SERIAL_DATA,
|
||||
|
@ -354,7 +354,7 @@ static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
|
|||
.mask_flags = 0,
|
||||
};
|
||||
|
||||
static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
|
||||
static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
|
||||
.num_adcs = 2,
|
||||
.num_dacs = 2,
|
||||
.type = SND_AK4524,
|
||||
|
@ -363,7 +363,7 @@ static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 1, /* CIF high */
|
||||
.data_mask = ICE1712_EWS88_SERIAL_DATA,
|
||||
|
@ -375,7 +375,7 @@ static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
|
|||
.mask_flags = 0,
|
||||
};
|
||||
|
||||
static const struct snd_akm4xxx akm_6fire __devinitdata = {
|
||||
static struct snd_akm4xxx akm_6fire __devinitdata = {
|
||||
.num_adcs = 6,
|
||||
.num_dacs = 6,
|
||||
.type = SND_AK4524,
|
||||
|
@ -384,7 +384,7 @@ static const struct snd_akm4xxx akm_6fire __devinitdata = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 1, /* CIF high */
|
||||
.data_mask = ICE1712_6FIRE_SERIAL_DATA,
|
||||
|
@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn
|
|||
return val != nval;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Input Sensitivity Switch",
|
||||
|
@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
|
|||
return ndata != data;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
|
||||
static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Input Sensitivity Switch",
|
||||
.info = snd_ice1712_ewx_io_sense_info,
|
||||
|
@ -687,7 +687,7 @@ static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitda
|
|||
.count = 8,
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
|
||||
static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Output Sensitivity Switch",
|
||||
.info = snd_ice1712_ewx_io_sense_info,
|
||||
|
@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct
|
|||
.private_value = xshift | (xinvert << 8),\
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
|
||||
EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
|
||||
EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
|
||||
EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
|
||||
|
@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str
|
|||
.private_value = xshift | (xinvert << 8),\
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
|
||||
static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Analog Input Select",
|
||||
|
@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
|
|||
|
||||
|
||||
/* entry point */
|
||||
const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
|
||||
struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
|
||||
{
|
||||
.subvendor = ICE1712_SUBDEVICE_EWX2496,
|
||||
.name = "TerraTec EWX24/96",
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define ICE1712_SUBDEVICE_PHASE88 0x3b155111
|
||||
|
||||
/* entry point */
|
||||
extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[];
|
||||
extern struct snd_ice1712_card_info snd_ice1712_ews_cards[];
|
||||
|
||||
|
||||
/* TerraTec EWX 24/96 configuration definitions */
|
||||
|
|
|
@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
|
|||
static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
|
||||
{
|
||||
/* Hoontech STDSP24 with modified hardware */
|
||||
static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
|
||||
static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
|
||||
.num_adcs = 2,
|
||||
.num_dacs = 2,
|
||||
.type = SND_AK4524,
|
||||
|
@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
|
||||
static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
|
||||
.caddr = 2,
|
||||
.cif = 1, /* CIF high */
|
||||
.data_mask = ICE1712_STDSP24_SERIAL_DATA,
|
||||
|
@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
|
|||
|
||||
|
||||
/* entry point */
|
||||
const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
|
||||
struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
|
||||
{
|
||||
.subvendor = ICE1712_SUBDEVICE_STDSP24,
|
||||
.name = "Hoontech SoundTrack Audio DSP24",
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче