Commit a58bec86 authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA update

  - control API - replace global control lock with semaphore
  - ac97 - added VT1616 support
  - add code for PC98 architecture
  - ENS1370/1371 - added gameport code
  - HDSP - fixed oops when device is not detected
  - replace __SMP__ with CONFIG_SMP

parent 91fd73cd
...@@ -199,6 +199,10 @@ ...@@ -199,6 +199,10 @@
#define AC97_ALC650_MULTICH 0x6a #define AC97_ALC650_MULTICH 0x6a
#define AC97_ALC650_CLOCK 0x7a #define AC97_ALC650_CLOCK 0x7a
/* specific - Yamaha YMF753 */
#define AC97_YMF753_DIT_CTRL2 0x66 /* DIT Control 2 */
#define AC97_YMF753_3D_MODE_SEL 0x68 /* 3D Mode Select */
/* ac97->scaps */ /* ac97->scaps */
#define AC97_SCAP_AUDIO (1<<0) /* audio AC'97 codec */ #define AC97_SCAP_AUDIO (1<<0) /* audio AC'97 codec */
#define AC97_SCAP_MODEM (1<<1) /* modem AC'97 codec */ #define AC97_SCAP_MODEM (1<<1) /* modem AC'97 codec */
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/sched.h> /* wake_up() */ #include <linux/sched.h> /* wake_up() */
#include <asm/semaphore.h> /* struct semaphore */ #include <asm/semaphore.h> /* struct semaphore */
#include <linux/rwsem.h> /* struct rw_semaphore */
/* Typedef's */ /* Typedef's */
typedef struct timeval snd_timestamp_t; typedef struct timeval snd_timestamp_t;
...@@ -141,8 +142,8 @@ struct _snd_card { ...@@ -141,8 +142,8 @@ struct _snd_card {
struct list_head devices; /* devices */ struct list_head devices; /* devices */
unsigned int last_numid; /* last used numeric ID */ unsigned int last_numid; /* last used numeric ID */
rwlock_t control_rwlock; /* control list lock */ struct rw_semaphore controls_rwsem; /* controls list lock */
rwlock_t control_owner_lock; /* control list lock */ rwlock_t ctl_files_rwlock; /* ctl_files list lock */
int controls_count; /* count of all controls */ int controls_count; /* count of all controls */
struct list_head controls; /* all controls for this card */ struct list_head controls; /* all controls for this card */
struct list_head ctl_files; /* active control files */ struct list_head ctl_files; /* active control files */
......
...@@ -155,11 +155,15 @@ static int __init get_id(char **str, char **dst) ...@@ -155,11 +155,15 @@ static int __init get_id(char **str, char **dst)
return 0; return 0;
for (s = *str; isalpha(*s) || isdigit(*s) || *s == '_'; s++); for (s = *str; isalpha(*s) || isdigit(*s) || *s == '_'; s++);
if (s != *str) { if (s != *str) {
*dst = (char *)kmalloc(s - *str, GFP_KERNEL); *dst = (char *)kmalloc((s - *str) + 1, GFP_KERNEL);
s = *str; d = *dst; s = *str; d = *dst;
while (isalpha(*s) || isdigit(*s) || *s == '_') while (isalpha(*s) || isdigit(*s) || *s == '_') {
if (d != NULL) if (d != NULL)
*d++ = *s++; *d++ = *s;
s++;
}
if (d != NULL)
*d = '\0';
} }
*str = s; *str = s;
if (*s == ',') { if (*s == ',') {
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#define MPU401_HW_CMIPCI 15 /* CMIPCI MPU-401 UART */ #define MPU401_HW_CMIPCI 15 /* CMIPCI MPU-401 UART */
#define MPU401_HW_ALS4000 16 /* Avance Logic ALS4000 */ #define MPU401_HW_ALS4000 16 /* Avance Logic ALS4000 */
#define MPU401_HW_INTEL8X0 17 /* Intel8x0 driver */ #define MPU401_HW_INTEL8X0 17 /* Intel8x0 driver */
#define MPU401_HW_PC98II 18 /* Roland PC98II */
#define MPU401_MODE_BIT_INPUT 0 #define MPU401_MODE_BIT_INPUT 0
#define MPU401_MODE_BIT_OUTPUT 1 #define MPU401_MODE_BIT_OUTPUT 1
...@@ -64,6 +65,7 @@ struct _snd_mpu401 { ...@@ -64,6 +65,7 @@ struct _snd_mpu401 {
unsigned short hardware; /* MPU401_HW_XXXX */ unsigned short hardware; /* MPU401_HW_XXXX */
unsigned long port; /* base port of MPU-401 chip */ unsigned long port; /* base port of MPU-401 chip */
unsigned long cport; /* port + 1 (usually) */
struct resource *res; /* port resource */ struct resource *res; /* port resource */
int irq; /* IRQ number of MPU-401 chip (-1 = poll) */ int irq; /* IRQ number of MPU-401 chip (-1 = poll) */
int irq_flags; int irq_flags;
...@@ -89,8 +91,8 @@ struct _snd_mpu401 { ...@@ -89,8 +91,8 @@ struct _snd_mpu401 {
/* I/O ports */ /* I/O ports */
#define MPU401C(mpu) ((mpu)->port + 1) #define MPU401C(mpu) (mpu)->cport
#define MPU401D(mpu) ((mpu)->port + 0) #define MPU401D(mpu) (mpu)->port
/* /*
......
...@@ -229,6 +229,7 @@ ...@@ -229,6 +229,7 @@
#define OPL3_HW_OPL3_CS 0x0302 /* CS4232/CS4236+ */ #define OPL3_HW_OPL3_CS 0x0302 /* CS4232/CS4236+ */
#define OPL3_HW_OPL3_FM801 0x0303 /* FM801 */ #define OPL3_HW_OPL3_FM801 0x0303 /* FM801 */
#define OPL3_HW_OPL3_CS4281 0x0304 /* CS4281 */ #define OPL3_HW_OPL3_CS4281 0x0304 /* CS4281 */
#define OPL3_HW_OPL3_PC98 0x0305 /* PC9800 */
#define OPL3_HW_OPL4 0x0400 #define OPL3_HW_OPL4 0x0400
#define OPL3_HW_MASK 0xff00 #define OPL3_HW_MASK 0xff00
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* 2002-04-04 Tomas Kasparek better rates handling (allow non-standard rates) * 2002-04-04 Tomas Kasparek better rates handling (allow non-standard rates)
*/ */
/* $Id: sa11xx-uda1341.c,v 1.5 2002/10/21 18:28:19 perex Exp $ */ /* $Id: sa11xx-uda1341.c,v 1.6 2002/12/04 18:52:05 perex Exp $ */
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/module.h> #include <linux/module.h>
......
This diff is collapsed.
...@@ -1024,7 +1024,7 @@ static void snd_info_version_read(snd_info_entry_t *entry, snd_info_buffer_t * b ...@@ -1024,7 +1024,7 @@ static void snd_info_version_read(snd_info_entry_t *entry, snd_info_buffer_t * b
snd_iprintf(buffer, snd_iprintf(buffer,
"Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n" "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
"Compiled on " __DATE__ " for kernel %s" "Compiled on " __DATE__ " for kernel %s"
#ifdef __SMP__ #ifdef CONFIG_SMP
" (SMP)" " (SMP)"
#endif #endif
#ifdef MODVERSIONS #ifdef MODVERSIONS
......
...@@ -99,8 +99,8 @@ snd_card_t *snd_card_new(int idx, const char *xid, ...@@ -99,8 +99,8 @@ snd_card_t *snd_card_new(int idx, const char *xid,
card->number = idx; card->number = idx;
card->module = module; card->module = module;
INIT_LIST_HEAD(&card->devices); INIT_LIST_HEAD(&card->devices);
rwlock_init(&card->control_rwlock); init_rwsem(&card->controls_rwsem);
rwlock_init(&card->control_owner_lock); rwlock_init(&card->ctl_files_rwlock);
INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->controls);
INIT_LIST_HEAD(&card->ctl_files); INIT_LIST_HEAD(&card->ctl_files);
spin_lock_init(&card->files_lock); spin_lock_init(&card->files_lock);
...@@ -393,8 +393,6 @@ static void choose_default_id(snd_card_t * card) ...@@ -393,8 +393,6 @@ static void choose_default_id(snd_card_t * card)
idx_flag++; idx_flag++;
} }
} }
strcpy(card->id, id);
} }
int snd_card_register(snd_card_t * card) int snd_card_register(snd_card_t * card)
......
...@@ -562,7 +562,7 @@ static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer, ...@@ -562,7 +562,7 @@ static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer,
struct slot *slot = (struct slot *)pslot->private_data; struct slot *slot = (struct slot *)pslot->private_data;
*left = *right = 100; *left = *right = 100;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) { } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {
...@@ -579,7 +579,7 @@ static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer, ...@@ -579,7 +579,7 @@ static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer,
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) { } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {
snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1); snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
} }
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
return 0; return 0;
} }
...@@ -655,7 +655,7 @@ static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer, ...@@ -655,7 +655,7 @@ static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer,
snd_card_t *card = fmixer->card; snd_card_t *card = fmixer->card;
struct slot *slot = (struct slot *)pslot->private_data; struct slot *slot = (struct slot *)pslot->private_data;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME)
...@@ -685,7 +685,7 @@ static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer, ...@@ -685,7 +685,7 @@ static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer,
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1); snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
} }
} }
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
return 0; return 0;
} }
...@@ -698,9 +698,9 @@ static int snd_mixer_oss_get_recsrc1_sw(snd_mixer_oss_file_t *fmixer, ...@@ -698,9 +698,9 @@ static int snd_mixer_oss_get_recsrc1_sw(snd_mixer_oss_file_t *fmixer,
int left, right; int left, right;
left = right = 1; left = right = 1;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CSWITCH], &left, &right, 0); snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CSWITCH], &left, &right, 0);
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
*active = (left || right) ? 1 : 0; *active = (left || right) ? 1 : 0;
return 0; return 0;
} }
...@@ -714,9 +714,9 @@ static int snd_mixer_oss_get_recsrc1_route(snd_mixer_oss_file_t *fmixer, ...@@ -714,9 +714,9 @@ static int snd_mixer_oss_get_recsrc1_route(snd_mixer_oss_file_t *fmixer,
int left, right; int left, right;
left = right = 1; left = right = 1;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CROUTE], &left, &right, 1); snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CROUTE], &left, &right, 1);
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
*active = (left || right) ? 1 : 0; *active = (left || right) ? 1 : 0;
return 0; return 0;
} }
...@@ -728,9 +728,9 @@ static int snd_mixer_oss_put_recsrc1_sw(snd_mixer_oss_file_t *fmixer, ...@@ -728,9 +728,9 @@ static int snd_mixer_oss_put_recsrc1_sw(snd_mixer_oss_file_t *fmixer,
snd_card_t *card = fmixer->card; snd_card_t *card = fmixer->card;
struct slot *slot = (struct slot *)pslot->private_data; struct slot *slot = (struct slot *)pslot->private_data;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0); snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0);
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
return 0; return 0;
} }
...@@ -741,9 +741,9 @@ static int snd_mixer_oss_put_recsrc1_route(snd_mixer_oss_file_t *fmixer, ...@@ -741,9 +741,9 @@ static int snd_mixer_oss_put_recsrc1_route(snd_mixer_oss_file_t *fmixer,
snd_card_t *card = fmixer->card; snd_card_t *card = fmixer->card;
struct slot *slot = (struct slot *)pslot->private_data; struct slot *slot = (struct slot *)pslot->private_data;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1); snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1);
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
return 0; return 0;
} }
...@@ -764,12 +764,11 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i ...@@ -764,12 +764,11 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i
err = -ENOMEM; err = -ENOMEM;
goto __unlock; goto __unlock;
} }
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock); snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock); snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock); snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock);
read_unlock(&card->control_rwlock);
for (idx = 0; idx < 32; idx++) { for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx))) if (!(mixer->mask_recsrc & (1 << idx)))
continue; continue;
...@@ -785,10 +784,8 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i ...@@ -785,10 +784,8 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i
} }
} }
err = 0; err = 0;
goto __unalloc;
__unlock: __unlock:
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
__unalloc:
if (uctl) if (uctl)
kfree(uctl); kfree(uctl);
if (uinfo) if (uinfo)
...@@ -813,7 +810,7 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in ...@@ -813,7 +810,7 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in
err = -ENOMEM; err = -ENOMEM;
goto __unlock; goto __unlock;
} }
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock); snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock); snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
...@@ -838,7 +835,7 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in ...@@ -838,7 +835,7 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in
snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
err = 0; err = 0;
__unlock: __unlock:
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
if (uctl) if (uctl)
kfree(uctl); kfree(uctl);
if (uinfo) if (uinfo)
......
...@@ -698,7 +698,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream, ...@@ -698,7 +698,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
return -ENODEV; return -ENODEV;
card = pcm->card; card = pcm->card;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
list_for_each(list, &card->ctl_files) { list_for_each(list, &card->ctl_files) {
kctl = snd_ctl_file(list); kctl = snd_ctl_file(list);
if (kctl->pid == current->pid) { if (kctl->pid == current->pid) {
...@@ -706,7 +706,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream, ...@@ -706,7 +706,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
break; break;
} }
} }
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
if (pstr->substream_count == 0) if (pstr->substream_count == 0)
return -ENODEV; return -ENODEV;
......
...@@ -412,7 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) ...@@ -412,7 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
add_wait_queue(&rmidi->open_wait, &wait); add_wait_queue(&rmidi->open_wait, &wait);
while (1) { while (1) {
subdevice = -1; subdevice = -1;
read_lock(&card->control_rwlock); down_read(&card->controls_rwsem);
list_for_each(list, &card->ctl_files) { list_for_each(list, &card->ctl_files) {
kctl = snd_ctl_file(list); kctl = snd_ctl_file(list);
if (kctl->pid == current->pid) { if (kctl->pid == current->pid) {
...@@ -420,7 +420,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) ...@@ -420,7 +420,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
break; break;
} }
} }
read_unlock(&card->control_rwlock); up_read(&card->controls_rwsem);
err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file); err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file);
if (err >= 0) if (err >= 0)
break; break;
......
...@@ -44,6 +44,7 @@ obj-$(CONFIG_SND_AD1816A) += $(RAWMIDI_OBJS) $(OPL3_OBJS) ...@@ -44,6 +44,7 @@ obj-$(CONFIG_SND_AD1816A) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4231) += $(RAWMIDI_OBJS) obj-$(CONFIG_SND_CS4231) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(CONFIG_SND_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4236) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(CONFIG_SND_CS4236) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_PC98_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ES1688) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(CONFIG_SND_ES1688) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_GUSCLASSIC) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(CONFIG_SND_GUSCLASSIC) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_GUSMAX) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(CONFIG_SND_GUSMAX) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
......
...@@ -19,6 +19,7 @@ obj-$(CONFIG_SND_OPL3SA2) += snd-ainstr-fm.o ...@@ -19,6 +19,7 @@ obj-$(CONFIG_SND_OPL3SA2) += snd-ainstr-fm.o
obj-$(CONFIG_SND_AD1816A) += snd-ainstr-fm.o obj-$(CONFIG_SND_AD1816A) += snd-ainstr-fm.o
obj-$(CONFIG_SND_CS4232) += snd-ainstr-fm.o obj-$(CONFIG_SND_CS4232) += snd-ainstr-fm.o
obj-$(CONFIG_SND_CS4236) += snd-ainstr-fm.o obj-$(CONFIG_SND_CS4236) += snd-ainstr-fm.o
obj-$(CONFIG_SND_PC98_CS4232) += snd-ainstr-fm.o
obj-$(CONFIG_SND_ES1688) += snd-ainstr-fm.o obj-$(CONFIG_SND_ES1688) += snd-ainstr-fm.o
obj-$(CONFIG_SND_GUSCLASSIC) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o obj-$(CONFIG_SND_GUSCLASSIC) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(CONFIG_SND_GUSMAX) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o obj-$(CONFIG_SND_GUSMAX) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
......
...@@ -134,7 +134,7 @@ EXPORT_SYMBOL(snd_seq_dump_var_event); ...@@ -134,7 +134,7 @@ EXPORT_SYMBOL(snd_seq_dump_var_event);
EXPORT_SYMBOL(snd_seq_event_port_attach); EXPORT_SYMBOL(snd_seq_event_port_attach);
EXPORT_SYMBOL(snd_seq_event_port_detach); EXPORT_SYMBOL(snd_seq_event_port_detach);
/* seq_lock.c */ /* seq_lock.c */
#if defined(__SMP__) || defined(CONFIG_SND_DEBUG) #if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
/*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/ /*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/
/*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/ /*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/
EXPORT_SYMBOL(snd_use_lock_sync_helper); EXPORT_SYMBOL(snd_use_lock_sync_helper);
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <sound/core.h> #include <sound/core.h>
#include "seq_lock.h" #include "seq_lock.h"
#if defined(__SMP__) || defined(CONFIG_SND_DEBUG) #if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
#if 0 /* NOT USED */ #if 0 /* NOT USED */
/* (interruptible) sleep_on during the specified spinlock */ /* (interruptible) sleep_on during the specified spinlock */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#if defined(__SMP__) || defined(CONFIG_SND_DEBUG) #if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
typedef atomic_t snd_use_lock_t; typedef atomic_t snd_use_lock_t;
......
...@@ -40,6 +40,9 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ ...@@ -40,6 +40,9 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */ 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 irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
#ifdef CONFIG_PC9800
static int pc98ii[SNDRV_CARDS]; /* PC98-II dauther board */
#endif
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(index, "Index value for MPU-401 device."); MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
...@@ -56,6 +59,11 @@ MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC); ...@@ -56,6 +59,11 @@ MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC); MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
#ifdef CONFIG_PC9800
MODULE_PARM(pc98ii, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
#endif
static snd_card_t *snd_mpu401_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; static snd_card_t *snd_mpu401_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
...@@ -76,7 +84,11 @@ static int __init snd_card_mpu401_probe(int dev) ...@@ -76,7 +84,11 @@ static int __init snd_card_mpu401_probe(int dev)
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL) if (card == NULL)
return -ENOMEM; return -ENOMEM;
if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, if (snd_mpu401_uart_new(card, 0,
#ifdef CONFIG_PC9800
pc98ii[dev] ? MPU401_HW_PC98II :
#endif
MPU401_HW_MPU401,
port[dev], 0, port[dev], 0,
irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) { irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
......
...@@ -401,12 +401,17 @@ int snd_mpu401_uart_new(snd_card_t * card, int device, ...@@ -401,12 +401,17 @@ int snd_mpu401_uart_new(snd_card_t * card, int device,
spin_lock_init(&mpu->timer_lock); spin_lock_init(&mpu->timer_lock);
mpu->hardware = hardware; mpu->hardware = hardware;
if (!integrated) { if (!integrated) {
if ((mpu->res = request_region(port, 2, "MPU401 UART")) == NULL) { int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) {
snd_device_free(card, rmidi); snd_device_free(card, rmidi);
return -EBUSY; return -EBUSY;
} }
} }
mpu->port = port; mpu->port = port;
if (hardware == MPU401_HW_PC98II)
mpu->cport = port + 2;
else
mpu->cport = port + 1;
if (irq >= 0 && irq_flags) { if (irq >= 0 && irq_flags) {
if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) { if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) {
snd_printk("unable to grab IRQ %d\n", irq); snd_printk("unable to grab IRQ %d\n", irq);
......
...@@ -419,6 +419,26 @@ int snd_opl3_create(snd_card_t * card, ...@@ -419,6 +419,26 @@ int snd_opl3_create(snd_card_t * card,
case OPL3_HW_OPL3_CS: case OPL3_HW_OPL3_CS:
case OPL3_HW_OPL3_FM801: case OPL3_HW_OPL3_FM801:
opl3->command = &snd_opl3_command; opl3->command = &snd_opl3_command;
break;
case OPL3_HW_OPL3_PC98:
opl3->command = &snd_opl3_command;
/* Initialize? */
opl3->command(opl3, OPL3_RIGHT | 0x05, 0x05);
opl3->command(opl3, OPL3_RIGHT | 0x08, 0x04);
opl3->command(opl3, OPL3_RIGHT | 0x08, 0x00);
opl3->command(opl3, OPL3_LEFT | 0xf7, 0x00);
opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
inb(opl3->l_port);
opl3->command(opl3, OPL3_LEFT | 0x02, 0xff);
opl3->command(opl3, OPL3_LEFT | 0x04, 0x21);
inb(opl3->l_port);
opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
break; break;
case OPL3_HW_OPL3_CS4281: case OPL3_HW_OPL3_CS4281:
opl3->command = &snd_opl3_cs4281_command; opl3->command = &snd_opl3_cs4281_command;
...@@ -438,6 +458,7 @@ int snd_opl3_create(snd_card_t * card, ...@@ -438,6 +458,7 @@ int snd_opl3_create(snd_card_t * card,
opl3->command = &snd_opl3_command; opl3->command = &snd_opl3_command;
} }
} }
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT); opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */ opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */
......
...@@ -104,13 +104,13 @@ config SND_CMIPCI ...@@ -104,13 +104,13 @@ config SND_CMIPCI
config SND_ENS1370 config SND_ENS1370
tristate "(Creative) Ensoniq AudioPCI 1370" tristate "(Creative) Ensoniq AudioPCI 1370"
depends on SND depends on SND && SOUND_GAMEPORT
help help
Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1370. Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1370.
config SND_ENS1371 config SND_ENS1371
tristate "(Creative) Ensoniq AudioPCI 1371/1373" tristate "(Creative) Ensoniq AudioPCI 1371/1373"
depends on SND depends on SND && SOUND_GAMEPORT
help help
Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1371 and Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1371 and
Sound Blaster PCI 64 or 128 soundcards. Sound Blaster PCI 64 or 128 soundcards.
......
...@@ -126,6 +126,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { ...@@ -126,6 +126,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x48525300, 0xffffff00, "HMP9701", NULL }, { 0x48525300, 0xffffff00, "HMP9701", NULL },
{ 0x49434501, 0xffffffff, "ICE1230", NULL }, { 0x49434501, 0xffffffff, "ICE1230", NULL },
{ 0x49434511, 0xffffffff, "ICE1232", NULL }, // alias VIA VT1611A? { 0x49434511, 0xffffffff, "ICE1232", NULL }, // alias VIA VT1611A?
{ 0x49434551, 0xffffffff, "VT1616", NULL },
{ 0x49544520, 0xffffffff, "IT2226E", NULL }, { 0x49544520, 0xffffffff, "IT2226E", NULL },
{ 0x4e534300, 0xffffffff, "LM4540/43/45/46/48", NULL }, // only guess --jk { 0x4e534300, 0xffffffff, "LM4540/43/45/46/48", NULL }, // only guess --jk
{ 0x4e534331, 0xffffffff, "LM4549", NULL }, { 0x4e534331, 0xffffffff, "LM4549", NULL },
...@@ -678,6 +679,13 @@ AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0) ...@@ -678,6 +679,13 @@ AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0)
static const snd_kcontrol_new_t snd_ac97_control_eapd = static const snd_kcontrol_new_t snd_ac97_control_eapd =
AC97_SINGLE("External Amplifier Power Down", AC97_POWERDOWN, 15, 1, 0); AC97_SINGLE("External Amplifier Power Down", AC97_POWERDOWN, 15, 1, 0);
static const snd_kcontrol_new_t snd_ac97_controls_vt1616[] = {
AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
};
static int snd_ac97_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) static int snd_ac97_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{ {
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
...@@ -1583,6 +1591,14 @@ static int snd_ac97_mixer_build(snd_card_t * card, ac97_t * ac97) ...@@ -1583,6 +1591,14 @@ static int snd_ac97_mixer_build(snd_card_t * card, ac97_t * ac97)
if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_alc650[idx], ac97))) < 0) if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_alc650[idx], ac97))) < 0)
return err; return err;
break; break;
case AC97_ID_VT1616:
if (snd_ac97_try_bit(ac97, 0x5a, 9))
if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_vt1616[0], ac97))) < 0)
return err;
for (idx = 1; idx < ARRAY_SIZE(snd_ac97_controls_vt1616); idx++)
if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_vt1616[idx], ac97))) < 0)
return err;
break;
default: default:
/* nothing */ /* nothing */
break; break;
......
...@@ -46,3 +46,4 @@ ...@@ -46,3 +46,4 @@
#define AC97_ID_CS_MASK 0xfffffff8 /* bit 0-2: rev */ #define AC97_ID_CS_MASK 0xfffffff8 /* bit 0-2: rev */
#define AC97_ID_ALC650 0x414c4720 #define AC97_ID_ALC650 0x414c4720
#define AC97_ID_YMF753 0x594d4803 #define AC97_ID_YMF753 0x594d4803
#define AC97_ID_VT1616 0x49434551
...@@ -3689,7 +3689,7 @@ struct cs_card_type ...@@ -3689,7 +3689,7 @@ struct cs_card_type
void (*mixer_init)(cs46xx_t *); void (*mixer_init)(cs46xx_t *);
}; };
static struct cs_card_type __initdata cards[] = { static struct cs_card_type __devinitdata cards[] = {
{0x1489, 0x7001, "Genius Soundmaker 128 value", NULL, amp_none, NULL, NULL}, {0x1489, 0x7001, "Genius Soundmaker 128 value", NULL, amp_none, NULL, NULL},
{0x5053, 0x3357, "Voyetra", NULL, amp_voyetra, NULL, voyetra_mixer_init}, {0x5053, 0x3357, "Voyetra", NULL, amp_voyetra, NULL, voyetra_mixer_init},
{0x1071, 0x6003, "Mitac MI6020/21", NULL, amp_voyetra, NULL, NULL}, {0x1071, 0x6003, "Mitac MI6020/21", NULL, amp_voyetra, NULL, NULL},
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/control.h> #include <sound/control.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -403,6 +404,9 @@ struct _snd_ensoniq { ...@@ -403,6 +404,9 @@ struct _snd_ensoniq {
unsigned char *bugbuf; unsigned char *bugbuf;
dma_addr_t bugbuf_addr; dma_addr_t bugbuf_addr;
#endif #endif
struct gameport gameport;
struct semaphore joy_sem; // gameport configuration semaphore
}; };
static void snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs);
...@@ -1572,8 +1576,67 @@ static int __devinit snd_ensoniq_1370_mixer(ensoniq_t * ensoniq) ...@@ -1572,8 +1576,67 @@ static int __devinit snd_ensoniq_1370_mixer(ensoniq_t * ensoniq)
* General Switches... * General Switches...
*/ */
/* MQ: gameport driver connectivity */
#define ENSONIQ_JOY_CONTROL(xname, mask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
.get = snd_ensoniq_control_get, .put = snd_ensoniq_joy_control_put, \
.private_value = mask }
static int snd_ensoniq_joy_enable(ensoniq_t *ensoniq)
{
static int last_jiffies = 0;
unsigned long flags;
if (!request_region(ensoniq->gameport.io, 8, "ens137x: gameport")) {
#define ES___GAMEPORT_LOG_DELAY (30*HZ)
// avoid log pollution: limit to 2 infos per minute
if (jiffies > last_jiffies + ES___GAMEPORT_LOG_DELAY) {
last_jiffies = jiffies;
snd_printk("gameport io port 0x%03x in use", ensoniq->gameport.io);
}
return 0;
}
spin_lock_irqsave(&ensoniq->reg_lock, flags);
ensoniq->ctrl |= ES_JYSTK_EN;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
gameport_register_port(&ensoniq->gameport);
return 1;
}
static int snd_ensoniq_joy_disable(ensoniq_t *ensoniq)
{
unsigned long flags;
gameport_unregister_port(&ensoniq->gameport);
spin_lock_irqsave(&ensoniq->reg_lock, flags);
ensoniq->ctrl &= ~ES_JYSTK_EN;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
release_region(ensoniq->gameport.io, 8);
return 1;
}
static int snd_ensoniq_joy_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
unsigned int nval;
int change;
down(&ensoniq->joy_sem);
nval = ucontrol->value.integer.value[0] ? ES_JYSTK_EN : 0;
change = (ensoniq->ctrl & ES_JYSTK_EN) != nval; // spinlock shouldn't be needed because of joy_sem
if (change) {
if (nval) // enable
change = snd_ensoniq_joy_enable(ensoniq);
else change = snd_ensoniq_joy_disable(ensoniq);
}
up(&ensoniq->joy_sem);
return change;
}
static snd_kcontrol_new_t snd_ensoniq_control_joystick __devinitdata = static snd_kcontrol_new_t snd_ensoniq_control_joystick __devinitdata =
ENSONIQ_CONTROL("Joystick Enable", ES_JYSTK_EN); ENSONIQ_JOY_CONTROL("Joystick Enable", ES_JYSTK_EN);
#ifdef CHIP1371 #ifdef CHIP1371
...@@ -1585,9 +1648,9 @@ static int snd_es1371_joystick_addr_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_ ...@@ -1585,9 +1648,9 @@ static int snd_es1371_joystick_addr_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_
{ {
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1; uinfo->count = 1;
uinfo->value.enumerated.items = 3; uinfo->value.enumerated.items = 4;
if (uinfo->value.enumerated.item >= 3) if (uinfo->value.enumerated.item >= 4)
uinfo->value.enumerated.item = 2; uinfo->value.enumerated.item = 3;
sprintf(uinfo->value.enumerated.name, "port 0x%x", (uinfo->value.enumerated.item * 8) + 0x200); sprintf(uinfo->value.enumerated.name, "port 0x%x", (uinfo->value.enumerated.item * 8) + 0x200);
return 0; return 0;
} }
...@@ -1609,14 +1672,20 @@ static int snd_es1371_joystick_addr_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_ ...@@ -1609,14 +1672,20 @@ static int snd_es1371_joystick_addr_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_
unsigned long flags; unsigned long flags;
unsigned int nval; unsigned int nval;
int change; int change;
down(&ensoniq->joy_sem);
nval = ES_1371_JOY_ASEL(ucontrol->value.integer.value[0]); nval = ES_1371_JOY_ASEL(ucontrol->value.integer.value[0]);
spin_lock_irqsave(&ensoniq->reg_lock, flags); spin_lock_irqsave(&ensoniq->reg_lock, flags);
if (!(change = !(ensoniq->ctrl & ES_JYSTK_EN)))
goto no_change; // FIXME: now we allow change only when joystick is disabled
change = (ensoniq->ctrl & ES_1371_JOY_ASELM) != nval; change = (ensoniq->ctrl & ES_1371_JOY_ASELM) != nval;
ensoniq->ctrl &= ~ES_1371_JOY_ASELM; ensoniq->ctrl &= ~ES_1371_JOY_ASELM;
ensoniq->ctrl |= nval; ensoniq->ctrl |= nval;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
ensoniq->gameport.io = 0x200 + ES_1371_JOY_ASELI(nval) * 8;
no_change:
spin_unlock_irqrestore(&ensoniq->reg_lock, flags); spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
up(&ensoniq->joy_sem);
return change; return change;
} }
...@@ -1680,6 +1749,8 @@ static void snd_ensoniq_proc_done(ensoniq_t * ensoniq) ...@@ -1680,6 +1749,8 @@ static void snd_ensoniq_proc_done(ensoniq_t * ensoniq)
static int snd_ensoniq_free(ensoniq_t *ensoniq) static int snd_ensoniq_free(ensoniq_t *ensoniq)
{ {
if (ensoniq->ctrl & ES_JYSTK_EN)
snd_ensoniq_joy_disable(ensoniq);
snd_ensoniq_proc_done(ensoniq); snd_ensoniq_proc_done(ensoniq);
if (ensoniq->irq < 0) if (ensoniq->irq < 0)
goto __hw_end; goto __hw_end;
...@@ -1760,6 +1831,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, ...@@ -1760,6 +1831,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
if (ensoniq == NULL) if (ensoniq == NULL)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&ensoniq->reg_lock); spin_lock_init(&ensoniq->reg_lock);
init_MUTEX(&ensoniq->joy_sem);
ensoniq->card = card; ensoniq->card = card;
ensoniq->pci = pci; ensoniq->pci = pci;
ensoniq->irq = -1; ensoniq->irq = -1;
...@@ -1874,10 +1946,11 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, ...@@ -1874,10 +1946,11 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL));
outb(0x00, ES_REG(ensoniq, UART_RES)); outb(0x00, ES_REG(ensoniq, UART_RES));
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
snd_ctl_add(card, snd_ctl_new1(&snd_ensoniq_control_joystick, ensoniq));
#ifdef CHIP1371 #ifdef CHIP1371
snd_ctl_add(card, snd_ctl_new1(&snd_es1371_joystick_addr, ensoniq)); snd_ctl_add(card, snd_ctl_new1(&snd_es1371_joystick_addr, ensoniq));
#endif #endif
snd_ctl_add(card, snd_ctl_new1(&snd_ensoniq_control_joystick, ensoniq));
ensoniq->gameport.io = 0x200; // FIXME: is ES1371 configured like this above ?
synchronize_irq(ensoniq->irq); synchronize_irq(ensoniq->irq);
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
......
...@@ -517,18 +517,18 @@ static snd_pcm_hardware_t snd_fm801_playback = ...@@ -517,18 +517,18 @@ static snd_pcm_hardware_t snd_fm801_playback =
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID), SNDRV_PCM_INFO_MMAP_VALID),
formats: SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
rates: SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
rate_min: 5500, .rate_min = 5500,
rate_max: 48000, .rate_max = 48000,
channels_min: 1, .channels_min = 1,
channels_max: 2, .channels_max = 2,
buffer_bytes_max: (128*1024), .buffer_bytes_max = (128*1024),
period_bytes_min: 64, .period_bytes_min = 64,
period_bytes_max: (128*1024), .period_bytes_max = (128*1024),
periods_min: 1, .periods_min = 1,
periods_max: 1024, .periods_max = 1024,
fifo_size: 0, .fifo_size = 0,
}; };
static snd_pcm_hardware_t snd_fm801_capture = static snd_pcm_hardware_t snd_fm801_capture =
...@@ -536,18 +536,18 @@ static snd_pcm_hardware_t snd_fm801_capture = ...@@ -536,18 +536,18 @@ static snd_pcm_hardware_t snd_fm801_capture =
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID), SNDRV_PCM_INFO_MMAP_VALID),
formats: SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
rates: SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
rate_min: 5500, .rate_min = 5500,
rate_max: 48000, .rate_max = 48000,
channels_min: 1, .channels_min = 1,
channels_max: 2, .channels_max = 2,
buffer_bytes_max: (128*1024), .buffer_bytes_max = (128*1024),
period_bytes_min: 64, .period_bytes_min = 64,
period_bytes_max: (128*1024), .period_bytes_max = (128*1024),
periods_min: 1, .periods_min = 1,
periods_max: 1024, .periods_max = 1024,
fifo_size: 0, .fifo_size = 0,
}; };
static int snd_fm801_playback_open(snd_pcm_substream_t * substream) static int snd_fm801_playback_open(snd_pcm_substream_t * substream)
...@@ -834,7 +834,7 @@ static void snd_fm801_mixer_free_ac97(ac97_t *ac97) ...@@ -834,7 +834,7 @@ static void snd_fm801_mixer_free_ac97(ac97_t *ac97)
} }
} }
static int __init snd_fm801_mixer(fm801_t *chip) static int __devinit snd_fm801_mixer(fm801_t *chip)
{ {
ac97_t ac97; ac97_t ac97;
int err, i; int err, i;
...@@ -907,7 +907,7 @@ static int __devinit snd_fm801_create(snd_card_t * card, ...@@ -907,7 +907,7 @@ static int __devinit snd_fm801_create(snd_card_t * card,
static snd_device_ops_t ops = { static snd_device_ops_t ops = {
.dev_free = snd_fm801_dev_free, .dev_free = snd_fm801_dev_free,
}; };
*rchip = NULL; *rchip = NULL;
if ((err = pci_enable_device(pci)) < 0) if ((err = pci_enable_device(pci)) < 0)
return err; return err;
...@@ -920,13 +920,13 @@ static int __devinit snd_fm801_create(snd_card_t * card, ...@@ -920,13 +920,13 @@ static int __devinit snd_fm801_create(snd_card_t * card,
chip->irq = -1; chip->irq = -1;
chip->port = pci_resource_start(pci, 0); chip->port = pci_resource_start(pci, 0);
if ((chip->res_port = request_region(chip->port, 0x80, "FM801")) == NULL) { if ((chip->res_port = request_region(chip->port, 0x80, "FM801")) == NULL) {
snd_fm801_free(chip);
snd_printk("unable to grab region 0x%lx-0x%lx\n", chip->port, chip->port + 0x80 - 1); snd_printk("unable to grab region 0x%lx-0x%lx\n", chip->port, chip->port + 0x80 - 1);
snd_fm801_free(chip);
return -EBUSY; return -EBUSY;
} }
if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) { if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) {
snd_fm801_free(chip);
snd_printk("unable to grab IRQ %d\n", chip->irq); snd_printk("unable to grab IRQ %d\n", chip->irq);
snd_fm801_free(chip);
return -EBUSY; return -EBUSY;
} }
chip->irq = pci->irq; chip->irq = pci->irq;
...@@ -1070,7 +1070,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci, ...@@ -1070,7 +1070,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
strcpy(card->driver, "FM801"); strcpy(card->driver, "FM801");
strcpy(card->shortname, "ForteMedia FM801-"); strcpy(card->shortname, "ForteMedia FM801-");
strcat(card->shortname, chip->multichannel ? "AU" : "AS"); strcat(card->shortname, chip->multichannel ? "AU" : "AS");
...@@ -1098,7 +1098,7 @@ static struct pci_driver driver = { ...@@ -1098,7 +1098,7 @@ static struct pci_driver driver = {
.probe = snd_card_fm801_probe, .probe = snd_card_fm801_probe,
.remove = __devexit_p(snd_card_fm801_remove), .remove = __devexit_p(snd_card_fm801_remove),
}; };
static int __init alsa_card_fm801_init(void) static int __init alsa_card_fm801_init(void)
{ {
int err; int err;
......
...@@ -1894,7 +1894,7 @@ static void snd_korg1212_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *b ...@@ -1894,7 +1894,7 @@ static void snd_korg1212_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *b
snd_iprintf(buffer, " Irq count: %ld\n", korg1212->irqcount); snd_iprintf(buffer, " Irq count: %ld\n", korg1212->irqcount);
} }
static void __init snd_korg1212_proc_init(korg1212_t *korg1212) static void __devinit snd_korg1212_proc_init(korg1212_t *korg1212)
{ {
snd_info_entry_t *entry; snd_info_entry_t *entry;
...@@ -1920,7 +1920,7 @@ static void snd_korg1212_proc_done(korg1212_t * korg1212) ...@@ -1920,7 +1920,7 @@ static void snd_korg1212_proc_done(korg1212_t * korg1212)
} }
} }
static int __init snd_korg1212_create(korg1212_t *korg1212) static int __devinit snd_korg1212_create(korg1212_t *korg1212)
{ {
struct pci_dev *pci = korg1212->pci; struct pci_dev *pci = korg1212->pci;
int err; int err;
......
...@@ -305,7 +305,7 @@ snd_rme96_playback_pointer(snd_pcm_substream_t *substream); ...@@ -305,7 +305,7 @@ snd_rme96_playback_pointer(snd_pcm_substream_t *substream);
static snd_pcm_uframes_t static snd_pcm_uframes_t
snd_rme96_capture_pointer(snd_pcm_substream_t *substream); snd_rme96_capture_pointer(snd_pcm_substream_t *substream);
static void __init static void __devinit
snd_rme96_proc_init(rme96_t *rme96); snd_rme96_proc_init(rme96_t *rme96);
static void static void
...@@ -1589,7 +1589,7 @@ snd_rme96_free_adat_pcm(snd_pcm_t *pcm) ...@@ -1589,7 +1589,7 @@ snd_rme96_free_adat_pcm(snd_pcm_t *pcm)
snd_pcm_lib_preallocate_free_for_all(pcm); snd_pcm_lib_preallocate_free_for_all(pcm);
} }
static int __init static int __devinit
snd_rme96_create(rme96_t *rme96) snd_rme96_create(rme96_t *rme96)
{ {
struct pci_dev *pci = rme96->pci; struct pci_dev *pci = rme96->pci;
...@@ -1838,7 +1838,7 @@ snd_rme96_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) ...@@ -1838,7 +1838,7 @@ snd_rme96_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
} }
} }
static void __init static void __devinit
snd_rme96_proc_init(rme96_t *rme96) snd_rme96_proc_init(rme96_t *rme96)
{ {
snd_info_entry_t *entry; snd_info_entry_t *entry;
......
...@@ -3069,9 +3069,11 @@ static int __devinit snd_hdsp_create(snd_card_t *card, ...@@ -3069,9 +3069,11 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
static int snd_hdsp_free(hdsp_t *hdsp) static int snd_hdsp_free(hdsp_t *hdsp)
{ {
/* stop the audio, and cancel all interrupts */ if (hdsp->res_port) {
hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable); /* stop the audio, and cancel all interrupts */
hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register); hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable);
hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register);
}
if (hdsp->irq >= 0) if (hdsp->irq >= 0)
free_irq(hdsp->irq, (void *)hdsp); free_irq(hdsp->irq, (void *)hdsp);
......
...@@ -1799,7 +1799,7 @@ snd_rme9652_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) ...@@ -1799,7 +1799,7 @@ snd_rme9652_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
snd_iprintf(buffer, "\n"); snd_iprintf(buffer, "\n");
} }
static void __init snd_rme9652_proc_init(rme9652_t *rme9652) static void __devinit snd_rme9652_proc_init(rme9652_t *rme9652)
{ {
snd_info_entry_t *entry; snd_info_entry_t *entry;
...@@ -1869,7 +1869,7 @@ static int snd_rme9652_free(rme9652_t *rme9652) ...@@ -1869,7 +1869,7 @@ static int snd_rme9652_free(rme9652_t *rme9652)
return 0; return 0;
} }
static int __init snd_rme9652_initialize_memory(rme9652_t *rme9652) static int __devinit snd_rme9652_initialize_memory(rme9652_t *rme9652)
{ {
void *pb, *cb; void *pb, *cb;
dma_addr_t pb_addr, cb_addr; dma_addr_t pb_addr, cb_addr;
...@@ -2523,7 +2523,7 @@ static snd_pcm_ops_t snd_rme9652_capture_ops = { ...@@ -2523,7 +2523,7 @@ static snd_pcm_ops_t snd_rme9652_capture_ops = {
.copy = snd_rme9652_capture_copy, .copy = snd_rme9652_capture_copy,
}; };
static int __init snd_rme9652_create_pcm(snd_card_t *card, static int __devinit snd_rme9652_create_pcm(snd_card_t *card,
rme9652_t *rme9652) rme9652_t *rme9652)
{ {
snd_pcm_t *pcm; snd_pcm_t *pcm;
...@@ -2547,7 +2547,7 @@ static int __init snd_rme9652_create_pcm(snd_card_t *card, ...@@ -2547,7 +2547,7 @@ static int __init snd_rme9652_create_pcm(snd_card_t *card,
return 0; return 0;
} }
static int __init snd_rme9652_create(snd_card_t *card, static int __devinit snd_rme9652_create(snd_card_t *card,
rme9652_t *rme9652, rme9652_t *rme9652,
int precise_ptr) int precise_ptr)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment