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 @@
#define AC97_ALC650_MULTICH 0x6a
#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 */
#define AC97_SCAP_AUDIO (1<<0) /* audio AC'97 codec */
#define AC97_SCAP_MODEM (1<<1) /* modem AC'97 codec */
......
......@@ -24,6 +24,7 @@
#include <linux/sched.h> /* wake_up() */
#include <asm/semaphore.h> /* struct semaphore */
#include <linux/rwsem.h> /* struct rw_semaphore */
/* Typedef's */
typedef struct timeval snd_timestamp_t;
......@@ -141,8 +142,8 @@ struct _snd_card {
struct list_head devices; /* devices */
unsigned int last_numid; /* last used numeric ID */
rwlock_t control_rwlock; /* control list lock */
rwlock_t control_owner_lock; /* control list lock */
struct rw_semaphore controls_rwsem; /* controls list lock */
rwlock_t ctl_files_rwlock; /* ctl_files list lock */
int controls_count; /* count of all controls */
struct list_head controls; /* all controls for this card */
struct list_head ctl_files; /* active control files */
......
......@@ -155,11 +155,15 @@ static int __init get_id(char **str, char **dst)
return 0;
for (s = *str; isalpha(*s) || isdigit(*s) || *s == '_'; s++);
if (s != *str) {
*dst = (char *)kmalloc(s - *str, GFP_KERNEL);
*dst = (char *)kmalloc((s - *str) + 1, GFP_KERNEL);
s = *str; d = *dst;
while (isalpha(*s) || isdigit(*s) || *s == '_')
while (isalpha(*s) || isdigit(*s) || *s == '_') {
if (d != NULL)
*d++ = *s++;
*d++ = *s;
s++;
}
if (d != NULL)
*d = '\0';
}
*str = s;
if (*s == ',') {
......
......@@ -41,6 +41,7 @@
#define MPU401_HW_CMIPCI 15 /* CMIPCI MPU-401 UART */
#define MPU401_HW_ALS4000 16 /* Avance Logic ALS4000 */
#define MPU401_HW_INTEL8X0 17 /* Intel8x0 driver */
#define MPU401_HW_PC98II 18 /* Roland PC98II */
#define MPU401_MODE_BIT_INPUT 0
#define MPU401_MODE_BIT_OUTPUT 1
......@@ -64,6 +65,7 @@ struct _snd_mpu401 {
unsigned short hardware; /* MPU401_HW_XXXX */
unsigned long port; /* base port of MPU-401 chip */
unsigned long cport; /* port + 1 (usually) */
struct resource *res; /* port resource */
int irq; /* IRQ number of MPU-401 chip (-1 = poll) */
int irq_flags;
......@@ -89,8 +91,8 @@ struct _snd_mpu401 {
/* I/O ports */
#define MPU401C(mpu) ((mpu)->port + 1)
#define MPU401D(mpu) ((mpu)->port + 0)
#define MPU401C(mpu) (mpu)->cport
#define MPU401D(mpu) (mpu)->port
/*
......
......@@ -229,6 +229,7 @@
#define OPL3_HW_OPL3_CS 0x0302 /* CS4232/CS4236+ */
#define OPL3_HW_OPL3_FM801 0x0303 /* FM801 */
#define OPL3_HW_OPL3_CS4281 0x0304 /* CS4281 */
#define OPL3_HW_OPL3_PC98 0x0305 /* PC9800 */
#define OPL3_HW_OPL4 0x0400
#define OPL3_HW_MASK 0xff00
......
......@@ -15,7 +15,7 @@
* 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 <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
snd_iprintf(buffer,
"Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
"Compiled on " __DATE__ " for kernel %s"
#ifdef __SMP__
#ifdef CONFIG_SMP
" (SMP)"
#endif
#ifdef MODVERSIONS
......
......@@ -99,8 +99,8 @@ snd_card_t *snd_card_new(int idx, const char *xid,
card->number = idx;
card->module = module;
INIT_LIST_HEAD(&card->devices);
rwlock_init(&card->control_rwlock);
rwlock_init(&card->control_owner_lock);
init_rwsem(&card->controls_rwsem);
rwlock_init(&card->ctl_files_rwlock);
INIT_LIST_HEAD(&card->controls);
INIT_LIST_HEAD(&card->ctl_files);
spin_lock_init(&card->files_lock);
......@@ -393,8 +393,6 @@ static void choose_default_id(snd_card_t * card)
idx_flag++;
}
}
strcpy(card->id, id);
}
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,
struct slot *slot = (struct slot *)pslot->private_data;
*left = *right = 100;
read_lock(&card->control_rwlock);
down_read(&card->controls_rwsem);
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);
} 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,
} 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);
}
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
return 0;
}
......@@ -655,7 +655,7 @@ static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer,
snd_card_t *card = fmixer->card;
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) {
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)
......@@ -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);
}
}
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
return 0;
}
......@@ -698,9 +698,9 @@ static int snd_mixer_oss_get_recsrc1_sw(snd_mixer_oss_file_t *fmixer,
int left, right;
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);
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
*active = (left || right) ? 1 : 0;
return 0;
}
......@@ -714,9 +714,9 @@ static int snd_mixer_oss_get_recsrc1_route(snd_mixer_oss_file_t *fmixer,
int left, right;
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);
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
*active = (left || right) ? 1 : 0;
return 0;
}
......@@ -728,9 +728,9 @@ static int snd_mixer_oss_put_recsrc1_sw(snd_mixer_oss_file_t *fmixer,
snd_card_t *card = fmixer->card;
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);
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
return 0;
}
......@@ -741,9 +741,9 @@ static int snd_mixer_oss_put_recsrc1_route(snd_mixer_oss_file_t *fmixer,
snd_card_t *card = fmixer->card;
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);
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
return 0;
}
......@@ -764,12 +764,11 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i
err = -ENOMEM;
goto __unlock;
}
read_lock(&card->control_rwlock);
down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock);
read_unlock(&card->control_rwlock);
for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx)))
continue;
......@@ -785,10 +784,8 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i
}
}
err = 0;
goto __unalloc;
__unlock:
read_unlock(&card->control_rwlock);
__unalloc:
up_read(&card->controls_rwsem);
if (uctl)
kfree(uctl);
if (uinfo)
......@@ -813,7 +810,7 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in
err = -ENOMEM;
goto __unlock;
}
read_lock(&card->control_rwlock);
down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, err = -ENOENT; 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
snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
err = 0;
__unlock:
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
if (uctl)
kfree(uctl);
if (uinfo)
......
......@@ -698,7 +698,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
return -ENODEV;
card = pcm->card;
read_lock(&card->control_rwlock);
down_read(&card->controls_rwsem);
list_for_each(list, &card->ctl_files) {
kctl = snd_ctl_file(list);
if (kctl->pid == current->pid) {
......@@ -706,7 +706,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
break;
}
}
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
if (pstr->substream_count == 0)
return -ENODEV;
......
......@@ -412,7 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
add_wait_queue(&rmidi->open_wait, &wait);
while (1) {
subdevice = -1;
read_lock(&card->control_rwlock);
down_read(&card->controls_rwsem);
list_for_each(list, &card->ctl_files) {
kctl = snd_ctl_file(list);
if (kctl->pid == current->pid) {
......@@ -420,7 +420,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
break;
}
}
read_unlock(&card->control_rwlock);
up_read(&card->controls_rwsem);
err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file);
if (err >= 0)
break;
......
......@@ -44,6 +44,7 @@ obj-$(CONFIG_SND_AD1816A) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4231) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_CS4232) += $(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_GUSCLASSIC) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_GUSMAX) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
......
......@@ -19,6 +19,7 @@ obj-$(CONFIG_SND_OPL3SA2) += snd-ainstr-fm.o
obj-$(CONFIG_SND_AD1816A) += snd-ainstr-fm.o
obj-$(CONFIG_SND_CS4232) += 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_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
......
......@@ -134,7 +134,7 @@ EXPORT_SYMBOL(snd_seq_dump_var_event);
EXPORT_SYMBOL(snd_seq_event_port_attach);
EXPORT_SYMBOL(snd_seq_event_port_detach);
/* 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_timeout_in_lock);*/
EXPORT_SYMBOL(snd_use_lock_sync_helper);
......
......@@ -23,7 +23,7 @@
#include <sound/core.h>
#include "seq_lock.h"
#if defined(__SMP__) || defined(CONFIG_SND_DEBUG)
#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
#if 0 /* NOT USED */
/* (interruptible) sleep_on during the specified spinlock */
......
......@@ -3,7 +3,7 @@
#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;
......
......@@ -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 long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
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_DESC(index, "Index value for MPU-401 device.");
......@@ -56,6 +59,11 @@ MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
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;
......@@ -76,7 +84,11 @@ static int __init snd_card_mpu401_probe(int dev)
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
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,
irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
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,
spin_lock_init(&mpu->timer_lock);
mpu->hardware = hardware;
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);
return -EBUSY;
}
}
mpu->port = port;
if (hardware == MPU401_HW_PC98II)
mpu->cport = port + 2;
else
mpu->cport = port + 1;
if (irq >= 0 && irq_flags) {
if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) {
snd_printk("unable to grab IRQ %d\n", irq);
......
......@@ -419,6 +419,26 @@ int snd_opl3_create(snd_card_t * card,
case OPL3_HW_OPL3_CS:
case OPL3_HW_OPL3_FM801:
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;
case OPL3_HW_OPL3_CS4281:
opl3->command = &snd_opl3_cs4281_command;
......@@ -438,6 +458,7 @@ int snd_opl3_create(snd_card_t * card,
opl3->command = &snd_opl3_command;
}
}
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */
......
......@@ -104,13 +104,13 @@ config SND_CMIPCI
config SND_ENS1370
tristate "(Creative) Ensoniq AudioPCI 1370"
depends on SND
depends on SND && SOUND_GAMEPORT
help
Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1370.
config SND_ENS1371
tristate "(Creative) Ensoniq AudioPCI 1371/1373"
depends on SND
depends on SND && SOUND_GAMEPORT
help
Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1371 and
Sound Blaster PCI 64 or 128 soundcards.
......
......@@ -126,6 +126,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x48525300, 0xffffff00, "HMP9701", NULL },
{ 0x49434501, 0xffffffff, "ICE1230", NULL },
{ 0x49434511, 0xffffffff, "ICE1232", NULL }, // alias VIA VT1611A?
{ 0x49434551, 0xffffffff, "VT1616", NULL },
{ 0x49544520, 0xffffffff, "IT2226E", NULL },
{ 0x4e534300, 0xffffffff, "LM4540/43/45/46/48", NULL }, // only guess --jk
{ 0x4e534331, 0xffffffff, "LM4549", NULL },
......@@ -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 =
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)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
......@@ -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)
return err;
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:
/* nothing */
break;
......
......@@ -46,3 +46,4 @@
#define AC97_ID_CS_MASK 0xfffffff8 /* bit 0-2: rev */
#define AC97_ID_ALC650 0x414c4720
#define AC97_ID_YMF753 0x594d4803
#define AC97_ID_VT1616 0x49434551
......@@ -3689,7 +3689,7 @@ struct cs_card_type
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},
{0x5053, 0x3357, "Voyetra", NULL, amp_voyetra, NULL, voyetra_mixer_init},
{0x1071, 0x6003, "Mitac MI6020/21", NULL, amp_voyetra, NULL, NULL},
......
......@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
......@@ -403,6 +404,9 @@ struct _snd_ensoniq {
unsigned char *bugbuf;
dma_addr_t bugbuf_addr;
#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);
......@@ -1572,8 +1576,67 @@ static int __devinit snd_ensoniq_1370_mixer(ensoniq_t * ensoniq)
* 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 =
ENSONIQ_CONTROL("Joystick Enable", ES_JYSTK_EN);
ENSONIQ_JOY_CONTROL("Joystick Enable", ES_JYSTK_EN);
#ifdef CHIP1371
......@@ -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->count = 1;
uinfo->value.enumerated.items = 3;
if (uinfo->value.enumerated.item >= 3)
uinfo->value.enumerated.item = 2;
uinfo->value.enumerated.items = 4;
if (uinfo->value.enumerated.item >= 4)
uinfo->value.enumerated.item = 3;
sprintf(uinfo->value.enumerated.name, "port 0x%x", (uinfo->value.enumerated.item * 8) + 0x200);
return 0;
}
......@@ -1609,14 +1672,20 @@ static int snd_es1371_joystick_addr_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_
unsigned long flags;
unsigned int nval;
int change;
down(&ensoniq->joy_sem);
nval = ES_1371_JOY_ASEL(ucontrol->value.integer.value[0]);
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;
ensoniq->ctrl &= ~ES_1371_JOY_ASELM;
ensoniq->ctrl |= nval;
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);
up(&ensoniq->joy_sem);
return change;
}
......@@ -1680,6 +1749,8 @@ static void snd_ensoniq_proc_done(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);
if (ensoniq->irq < 0)
goto __hw_end;
......@@ -1760,6 +1831,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
if (ensoniq == NULL)
return -ENOMEM;
spin_lock_init(&ensoniq->reg_lock);
init_MUTEX(&ensoniq->joy_sem);
ensoniq->card = card;
ensoniq->pci = pci;
ensoniq->irq = -1;
......@@ -1874,10 +1946,11 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL));
outb(0x00, ES_REG(ensoniq, UART_RES));
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
snd_ctl_add(card, snd_ctl_new1(&snd_ensoniq_control_joystick, ensoniq));
#ifdef CHIP1371
snd_ctl_add(card, snd_ctl_new1(&snd_es1371_joystick_addr, ensoniq));
#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);
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
......
......@@ -517,18 +517,18 @@ static snd_pcm_hardware_t snd_fm801_playback =
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID),
formats: SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
rates: SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
rate_min: 5500,
rate_max: 48000,
channels_min: 1,
channels_max: 2,
buffer_bytes_max: (128*1024),
period_bytes_min: 64,
period_bytes_max: (128*1024),
periods_min: 1,
periods_max: 1024,
fifo_size: 0,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
.rate_min = 5500,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = (128*1024),
.period_bytes_min = 64,
.period_bytes_max = (128*1024),
.periods_min = 1,
.periods_max = 1024,
.fifo_size = 0,
};
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 |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID),
formats: SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
rates: SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
rate_min: 5500,
rate_max: 48000,
channels_min: 1,
channels_max: 2,
buffer_bytes_max: (128*1024),
period_bytes_min: 64,
period_bytes_max: (128*1024),
periods_min: 1,
periods_max: 1024,
fifo_size: 0,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
.rate_min = 5500,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = (128*1024),
.period_bytes_min = 64,
.period_bytes_max = (128*1024),
.periods_min = 1,
.periods_max = 1024,
.fifo_size = 0,
};
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)
}
}
static int __init snd_fm801_mixer(fm801_t *chip)
static int __devinit snd_fm801_mixer(fm801_t *chip)
{
ac97_t ac97;
int err, i;
......@@ -907,7 +907,7 @@ static int __devinit snd_fm801_create(snd_card_t * card,
static snd_device_ops_t ops = {
.dev_free = snd_fm801_dev_free,
};
*rchip = NULL;
if ((err = pci_enable_device(pci)) < 0)
return err;
......@@ -920,13 +920,13 @@ static int __devinit snd_fm801_create(snd_card_t * card,
chip->irq = -1;
chip->port = pci_resource_start(pci, 0);
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_fm801_free(chip);
return -EBUSY;
}
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_fm801_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
......@@ -1070,7 +1070,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
snd_card_free(card);
return err;
}
strcpy(card->driver, "FM801");
strcpy(card->shortname, "ForteMedia FM801-");
strcat(card->shortname, chip->multichannel ? "AU" : "AS");
......@@ -1098,7 +1098,7 @@ static struct pci_driver driver = {
.probe = snd_card_fm801_probe,
.remove = __devexit_p(snd_card_fm801_remove),
};
static int __init alsa_card_fm801_init(void)
{
int err;
......
......@@ -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);
}
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;
......@@ -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;
int err;
......
......@@ -305,7 +305,7 @@ snd_rme96_playback_pointer(snd_pcm_substream_t *substream);
static snd_pcm_uframes_t
snd_rme96_capture_pointer(snd_pcm_substream_t *substream);
static void __init
static void __devinit
snd_rme96_proc_init(rme96_t *rme96);
static void
......@@ -1589,7 +1589,7 @@ snd_rme96_free_adat_pcm(snd_pcm_t *pcm)
snd_pcm_lib_preallocate_free_for_all(pcm);
}
static int __init
static int __devinit
snd_rme96_create(rme96_t *rme96)
{
struct pci_dev *pci = rme96->pci;
......@@ -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_info_entry_t *entry;
......
......@@ -3069,9 +3069,11 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
static int snd_hdsp_free(hdsp_t *hdsp)
{
/* stop the audio, and cancel all interrupts */
hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable);
hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register);
if (hdsp->res_port) {
/* stop the audio, and cancel all interrupts */
hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable);
hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register);
}
if (hdsp->irq >= 0)
free_irq(hdsp->irq, (void *)hdsp);
......
......@@ -1799,7 +1799,7 @@ snd_rme9652_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
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;
......@@ -1869,7 +1869,7 @@ static int snd_rme9652_free(rme9652_t *rme9652)
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;
dma_addr_t pb_addr, cb_addr;
......@@ -2523,7 +2523,7 @@ static snd_pcm_ops_t snd_rme9652_capture_ops = {
.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)
{
snd_pcm_t *pcm;
......@@ -2547,7 +2547,7 @@ static int __init snd_rme9652_create_pcm(snd_card_t *card,
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,
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