Commit 7a4b62d0 authored by Jaroslav Kysela's avatar Jaroslav Kysela

Merge http://linux.bkbits.net/linux-2.5

into suse.cz:/home/perex/bk/linux-sound/linux-sound
parents e2a6cbc0 729bd50d
......@@ -117,7 +117,6 @@
#include <asm/bitops.h>
#include <asm/io.h>
#define LINUX_2_1
typedef struct net_device_stats hp100_stats_t;
#include "hp100.h"
......@@ -285,7 +284,6 @@ static struct hp100_pci_id hp100_pci_ids[] = {
#define HP100_PCI_IDS_SIZE (sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))
#if LINUX_VERSION_CODE >= 0x20400
static struct pci_device_id hp100_pci_tbl[] __initdata = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
......@@ -294,7 +292,6 @@ static struct pci_device_id hp100_pci_tbl[] __initdata = {
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE(pci, hp100_pci_tbl);
#endif /* LINUX_VERSION_CODE >= 0x20400 */
static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
......@@ -356,8 +353,8 @@ static void hp100_RegisterDump(struct net_device *dev);
* address - Jean II */
static inline dma_addr_t virt_to_whatever(struct net_device *dev, u32 * ptr)
{
return ((u_long) ptr) +
((struct hp100_private *) (dev->priv))->whatever_offset;
return ((u_long) ptr) +
((struct hp100_private *) (dev->priv))->whatever_offset;
}
/* TODO: This function should not really be needed in a good design... */
......@@ -376,9 +373,7 @@ int __init hp100_probe(struct net_device *dev)
{
int base_addr = dev ? dev->base_addr : 0;
int ioaddr = 0;
#ifdef CONFIG_PCI
int pci_start_index = 0;
#endif
#ifdef HP100_DEBUG_B
hp100_outw(0x4200, TRACE);
......@@ -854,7 +849,10 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
printk("100Mb/s Voice Grade AnyLAN network.\n");
break;
case HP100_LAN_10:
printk("10Mb/s network.\n");
printk("10Mb/s network (10baseT).\n");
break;
case HP100_LAN_COAX:
printk("10Mb/s network (coax).\n");
break;
default:
printk("Warning! Link down.\n");
......@@ -889,7 +887,7 @@ static void hp100_hwinit(struct net_device *dev)
wait();
} else {
hp100_outw(HP100_INT_EN | HP100_RESET_LB, OPTION_LSW);
hp100_cascade_reset(dev, TRUE);
hp100_cascade_reset(dev, 1);
hp100_page(MAC_CTRL);
hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1);
}
......@@ -900,7 +898,7 @@ static void hp100_hwinit(struct net_device *dev)
wait();
/* Go into reset again. */
hp100_cascade_reset(dev, TRUE);
hp100_cascade_reset(dev, 1);
/* Set Option Registers to a safe state */
hp100_outw(HP100_DEBUG_EN |
......@@ -943,13 +941,13 @@ static void hp100_hwinit(struct net_device *dev)
wait(); /* TODO: Do we really need this? */
/* Enable Hardware (e.g. unreset) */
hp100_cascade_reset(dev, FALSE);
hp100_cascade_reset(dev, 0);
/* ------- initialisation complete ----------- */
/* Finally try to log in the Hub if there may be a VG connection. */
if (lp->lan_type != HP100_LAN_10)
hp100_login_to_vg_hub(dev, FALSE); /* relogin */
if ((lp->lan_type == HP100_LAN_100) || (lp->lan_type == HP100_LAN_ERR))
hp100_login_to_vg_hub(dev, 0); /* relogin */
}
......@@ -1191,7 +1189,7 @@ static int hp100_close(struct net_device *dev)
hp100_stop_interface(dev);
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
lp->hub_status = hp100_login_to_vg_hub(dev, 0);
netif_stop_queue(dev);
......@@ -1508,13 +1506,31 @@ static void hp100_BM_shutdown(struct net_device *dev)
hp100_andb(~HP100_BM_MASTER, BM);
} /* end of shutdown procedure for non-etr parts */
hp100_cascade_reset(dev, TRUE);
hp100_cascade_reset(dev, 1);
}
hp100_page(PERFORMANCE);
/* hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_RESET_HB, OPTION_LSW ); */
/* Busmaster mode should be shut down now. */
}
static int hp100_check_lan(struct net_device *dev)
{
struct hp100_private *lp = (struct hp100_private *) dev->priv;
if (lp->lan_type < 0) { /* no LAN type detected yet? */
hp100_stop_interface(dev);
if ((lp->lan_type = hp100_sense_lan(dev)) < 0) {
printk("hp100: %s: no connection found - check wire\n", dev->name);
hp100_start_interface(dev); /* 10Mb/s RX packets maybe handled */
return -EIO;
}
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, 0); /* relogin */
hp100_start_interface(dev);
}
return 0;
}
/*
* transmit functions
*/
......@@ -1550,23 +1566,14 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
if (jiffies - dev->trans_start < HZ)
return -EAGAIN;
if (lp->lan_type < 0) { /* no LAN type detected yet? */
hp100_stop_interface(dev);
if ((lp->lan_type = hp100_sense_lan(dev)) < 0) {
printk("hp100: %s: no connection found - check wire\n", dev->name);
hp100_start_interface(dev); /* 10Mb/s RX pkts maybe handled */
return -EIO;
}
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); /* relogin */
hp100_start_interface(dev);
}
if (hp100_check_lan(dev))
return -EIO;
if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) {
/* we have a 100Mb/s adapter but it isn't connected to hub */
printk("hp100: %s: login to 100Mb/s hub retry\n", dev->name);
hp100_stop_interface(dev);
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
lp->hub_status = hp100_login_to_vg_hub(dev, 0);
hp100_start_interface(dev);
} else {
spin_lock_irqsave(&lp->lock, flags);
......@@ -1577,18 +1584,18 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
if (i == HP100_LAN_ERR)
printk("hp100: %s: link down detected\n", dev->name);
else if (lp->lan_type != i) { /* cable change! */
/* it's very hard - all network setting must be changed!!! */
/* it's very hard - all network settings must be changed!!! */
printk("hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name);
lp->lan_type = i;
hp100_stop_interface(dev);
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
lp->hub_status = hp100_login_to_vg_hub(dev, 0);
hp100_start_interface(dev);
} else {
printk("hp100: %s: interface reset\n", dev->name);
hp100_stop_interface(dev);
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
lp->hub_status = hp100_login_to_vg_hub(dev, 0);
hp100_start_interface(dev);
}
}
......@@ -1699,17 +1706,8 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->len <= 0)
return 0;
if (lp->lan_type < 0) { /* no LAN type detected yet? */
hp100_stop_interface(dev);
if ((lp->lan_type = hp100_sense_lan(dev)) < 0) {
printk("hp100: %s: no connection found - check wire\n", dev->name);
hp100_start_interface(dev); /* 10Mb/s RX packets maybe handled */
return -EIO;
}
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE); /* relogin */
hp100_start_interface(dev);
}
if (hp100_check_lan(dev))
return -EIO;
/* If there is not enough free memory on the card... */
i = hp100_inl(TX_MEM_FREE) & 0x7fffffff;
......@@ -1729,7 +1727,7 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* we have a 100Mb/s adapter but it isn't connected to hub */
printk("hp100: %s: login to 100Mb/s hub retry\n", dev->name);
hp100_stop_interface(dev);
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
lp->hub_status = hp100_login_to_vg_hub(dev, 0);
hp100_start_interface(dev);
} else {
spin_lock_irqsave(&lp->lock, flags);
......@@ -1745,13 +1743,13 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->lan_type = i;
hp100_stop_interface(dev);
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
lp->hub_status = hp100_login_to_vg_hub(dev, 0);
hp100_start_interface(dev);
} else {
printk("hp100: %s: interface reset\n", dev->name);
hp100_stop_interface(dev);
if (lp->lan_type == HP100_LAN_100)
lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
lp->hub_status = hp100_login_to_vg_hub(dev, 0);
hp100_start_interface(dev);
mdelay(1);
}
......@@ -2220,7 +2218,7 @@ static void hp100_set_multicast_list(struct net_device *dev)
#ifdef HP100_DEBUG
printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name);
#endif
lp->hub_status = hp100_login_to_vg_hub(dev, TRUE); /* force a relogin to the hub */
lp->hub_status = hp100_login_to_vg_hub(dev, 1); /* force a relogin to the hub */
}
} else {
int i;
......@@ -2245,7 +2243,7 @@ static void hp100_set_multicast_list(struct net_device *dev)
#ifdef HP100_DEBUG
printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name);
#endif
lp->hub_status = hp100_login_to_vg_hub(dev, TRUE); /* force a relogin to the hub */
lp->hub_status = hp100_login_to_vg_hub(dev, 1); /* force a relogin to the hub */
}
}
}
......@@ -2539,7 +2537,7 @@ static int hp100_sense_lan(struct net_device *dev)
hp100_page(MAC_CTRL);
hp100_outb(val_10, 10_LAN_CFG_1);
hp100_page(PERFORMANCE);
return HP100_LAN_10;
return HP100_LAN_COAX;
}
if ((lp->id->id == 0x02019F022) ||
......@@ -2685,7 +2683,7 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
*/
hp100_page(MAC_CTRL);
startst = hp100_inb(VG_LAN_CFG_1);
if ((force_relogin == TRUE) || (hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST)) {
if ((force_relogin == 1) || (hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST)) {
#ifdef HP100_DEBUG_TRAINING
printk("hp100: %s: Start training\n", dev->name);
#endif
......@@ -2847,7 +2845,7 @@ static void hp100_cascade_reset(struct net_device *dev, u_short enable)
printk("hp100: %s: cascade_reset\n", dev->name);
#endif
if (enable == TRUE) {
if (enable) {
hp100_outw(HP100_HW_RST | HP100_RESET_LB, OPTION_LSW);
if (lp->chip == HP100_CHIPID_LASSEN) {
/* Lassen requires a PCI transmit fifo reset */
......
......@@ -518,12 +518,9 @@
*/
#define HP100_LAN_100 100 /* lan_type value for VG */
#define HP100_LAN_10 10 /* lan_type value for 10BaseT */
#define HP100_LAN_COAX 9 /* lan_type value for Coax */
#define HP100_LAN_ERR (-1) /* lan_type value for link down */
#define TRUE 1
#define FALSE 0
/*
* Bus Master Data Structures ----------------------------------------------
*/
......
......@@ -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 */
......
......@@ -111,6 +111,8 @@ snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid);
snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id);
int snd_ctl_register(snd_card_t *card);
int snd_ctl_disconnect(snd_card_t *card);
int snd_ctl_can_unregister(snd_card_t *card);
int snd_ctl_unregister(snd_card_t *card);
int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
......
......@@ -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;
......@@ -58,8 +59,9 @@ typedef enum {
} snd_device_type_t;
typedef enum {
SNDRV_DEV_BUILD = 0,
SNDRV_DEV_REGISTERED = 1
SNDRV_DEV_BUILD,
SNDRV_DEV_REGISTERED,
SNDRV_DEV_DISCONNECTED
} snd_device_state_t;
typedef enum {
......@@ -73,11 +75,13 @@ typedef struct _snd_device snd_device_t;
typedef int (snd_dev_free_t)(snd_device_t *device);
typedef int (snd_dev_register_t)(snd_device_t *device);
typedef int (snd_dev_disconnect_t)(snd_device_t *device);
typedef int (snd_dev_unregister_t)(snd_device_t *device);
typedef struct {
snd_dev_free_t *dev_free;
snd_dev_register_t *dev_register;
snd_dev_disconnect_t *dev_disconnect;
snd_dev_unregister_t *dev_unregister;
} snd_device_ops_t;
......@@ -109,6 +113,15 @@ typedef struct _snd_hwdep snd_hwdep_t;
typedef struct _snd_oss_mixer snd_mixer_oss_t;
#endif
/* monitor files for graceful shutdown (hotplug) */
struct snd_monitor_file {
struct file *file;
struct snd_monitor_file *next;
};
struct snd_shutdown_f_ops; /* define it later */
/* main structure for soundcard */
struct _snd_card {
......@@ -129,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 */
......@@ -139,6 +152,12 @@ struct _snd_card {
snd_info_entry_t *proc_id; /* the card id */
struct proc_dir_entry *proc_root_link; /* number link to real id */
struct snd_monitor_file *files; /* all files associated to this card */
struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown state */
spinlock_t files_lock; /* lock the files for this card */
int shutdown; /* this card is going down */
wait_queue_head_t shutdown_sleep;
#ifdef CONFIG_PM
int (*set_power_state) (snd_card_t *card, unsigned int state);
void *power_state_private_data;
......@@ -285,19 +304,27 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count);
/* init.c */
extern int snd_cards_count;
extern unsigned int snd_cards_lock;
extern snd_card_t *snd_cards[SNDRV_CARDS];
extern rwlock_t snd_card_rwlock;
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
extern int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int free_flag);
#define SND_MIXER_OSS_NOTIFY_REGISTER 0
#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1
#define SND_MIXER_OSS_NOTIFY_FREE 2
extern int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int cmd);
#endif
snd_card_t *snd_card_new(int idx, const char *id,
struct module *module, int extra_size);
int snd_card_disconnect(snd_card_t *card);
int snd_card_free(snd_card_t *card);
int snd_card_free_in_thread(snd_card_t *card);
int snd_card_register(snd_card_t *card);
int snd_card_info_init(void);
int snd_card_info_done(void);
int snd_component_add(snd_card_t *card, const char *component);
int snd_card_file_add(snd_card_t *card, struct file *file);
int snd_card_file_remove(snd_card_t *card, struct file *file);
/* device.c */
......@@ -305,6 +332,8 @@ int snd_device_new(snd_card_t *card, snd_device_type_t type,
void *device_data, snd_device_ops_t *ops);
int snd_device_register(snd_card_t *card, void *device_data);
int snd_device_register_all(snd_card_t *card);
int snd_device_disconnect(snd_card_t *card, void *device_data);
int snd_device_disconnect_all(snd_card_t *card);
int snd_device_free(snd_card_t *card, void *device_data);
int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd);
......
......@@ -1663,6 +1663,8 @@ typedef struct _snd_cs46xx_pcm_t {
snd_pcm_substream_t *substream;
pcm_channel_descriptor_t * pcm_channel;
int pcm_channel_id; /* Fron Rear, Center Lfe ... */
} cs46xx_pcm_t;
typedef struct {
......
......@@ -63,7 +63,6 @@
#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
#define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2
#define DSP_SPDIF_STATUS_HW_ENABLED 4
#define DSP_SPDIF_STATUS_AC3_MODE 8
struct _dsp_module_desc_t;
......@@ -141,7 +140,6 @@ typedef struct _pcm_channel_descriptor_t {
dsp_scb_descriptor_t * pcm_reader_scb;
dsp_scb_descriptor_t * src_scb;
dsp_scb_descriptor_t * mixer_scb;
int pcm_channel_id;
void * private_data;
} pcm_channel_descriptor_t;
......@@ -196,6 +194,10 @@ typedef struct _dsp_spos_instance_t {
int spdif_status_in;
u16 spdif_input_volume_right;
u16 spdif_input_volume_left;
/* spdif channel status,
left right and user validity bits */
int spdif_csuv_default;
int spdif_csuv_stream;
/* SPDIF input sample rate converter */
dsp_scb_descriptor_t * spdif_in_src;
......
......@@ -155,12 +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);
if ((d = *dst) != NULL) {
s = *str;
while (isalpha(*s) || isdigit(*s) || *s == '_')
*d++ = *s++;
*dst = (char *)kmalloc((s - *str) + 1, GFP_KERNEL);
s = *str; d = *dst;
while (isalpha(*s) || isdigit(*s) || *s == '_') {
if (d != NULL)
*d++ = *s;
s++;
}
if (d != NULL)
*d = '\0';
}
*str = s;
if (*s == ',') {
......
......@@ -61,6 +61,7 @@ struct _snd_oss_mixer {
void (*private_free_recsrc)(snd_mixer_oss_t *mixer);
struct semaphore reg_mutex;
snd_info_entry_t *proc_entry;
int oss_dev_alloc;
/* --- */
int oss_recsrc;
};
......
......@@ -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
......
......@@ -443,8 +443,9 @@ struct _snd_pcm {
};
typedef struct _snd_pcm_notify {
int (*n_register) (unsigned short minor, snd_pcm_t * pcm);
int (*n_unregister) (unsigned short minor, snd_pcm_t * pcm);
int (*n_register) (snd_pcm_t * pcm);
int (*n_disconnect) (snd_pcm_t * pcm);
int (*n_unregister) (snd_pcm_t * pcm);
struct list_head list;
} snd_pcm_notify_t;
......
......@@ -77,6 +77,7 @@ typedef struct _snd_pcm_oss_stream {
typedef struct _snd_pcm_oss {
int reg;
unsigned int reg_mask;
} snd_pcm_oss_t;
#endif /* __SOUND_PCM_OSS_H */
......@@ -225,7 +225,6 @@ typedef struct _snd_sb sb_t;
#define SB_DT019X_MIC_DEV 0x6a
#define SB_DT019X_SPKR_DEV 0x6a
#define SB_DT019X_LINE_DEV 0x6e
#define SB_DT019X_OUTPUT_SW1 0x3c
#define SB_DT019X_OUTPUT_SW2 0x4c
#define SB_DT019X_CAPTURE_SW 0x6c
......@@ -235,6 +234,14 @@ typedef struct _snd_sb sb_t;
#define SB_DT019X_CAP_SYNTH 0x07
#define SB_DT019X_CAP_MAIN 0x07
#define SB_ALS4000_MONO_IO_CTRL 0x4b
#define SB_ALS4000_MIC_IN_GAIN 0x4d
#define SB_ALS4000_FMDAC 0x4f
#define SB_ALS4000_3D_SND_FX 0x50
#define SB_ALS4000_3D_TIME_DELAY 0x51
#define SB_ALS4000_3D_AUTO_MUTE 0x52
#define SB_ALS4000_QSOUND 0xdb
/* IRQ setting bitmap */
#define SB_IRQSETUP_IRQ9 0x01
#define SB_IRQSETUP_IRQ5 0x02
......
......@@ -101,10 +101,18 @@
/* Global registers */
enum global_control_bits {
CHANNEL_IDX = 0x0000003f, OVERRUN_IE = 0x00000400,
UNDERRUN_IE = 0x00000800, ENDLP_IE = 0x00001000,
MIDLP_IE = 0x00002000, ETOG_IE = 0x00004000,
EDROP_IE = 0x00008000, BANK_B_EN = 0x00010000
CHANNEL_IDX = 0x0000003f,
OVERRUN_IE = 0x00000400, /* interrupt enable: capture overrun */
UNDERRUN_IE = 0x00000800, /* interrupt enable: playback underrun */
ENDLP_IE = 0x00001000, /* interrupt enable: end of buffer */
MIDLP_IE = 0x00002000, /* interrupt enable: middle buffer */
ETOG_IE = 0x00004000, /* interrupt enable: envelope toggling */
EDROP_IE = 0x00008000, /* interrupt enable: envelope drop */
BANK_B_EN = 0x00010000, /* SiS: enable bank B (64 channels) */
PCMIN_B_MIX = 0x00020000, /* SiS: PCM IN B mixing enable */
I2S_OUT_ASSIGN = 0x00040000, /* SiS: I2S Out contains surround PCM */
SPDIF_OUT_ASSIGN= 0x00080000, /* SiS: 0=S/PDIF L/R | 1=PCM Out FIFO */
MAIN_OUT_ASSIGN = 0x00100000, /* SiS: 0=PCM Out FIFO | 1=MMC Out buffer */
};
enum miscint_bits {
......@@ -423,6 +431,8 @@ struct _snd_trident {
int ChanPCM; /* max number of PCM channels */
int ChanPCMcnt; /* actual number of PCM channels */
int ac97_detect; /* 1 = AC97 in detection phase */
struct _snd_4dwave synth; /* synth specific variables */
spinlock_t event_lock;
......
/* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc5"
#define CONFIG_SND_DATE " (Sun Nov 10 19:48:18 2002 UTC)"
#define CONFIG_SND_VERSION "0.9.0rc6"
#define CONFIG_SND_DATE " (Wed Dec 11 21:24:39 2002 UTC)"
......@@ -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.
......@@ -56,7 +56,8 @@ int snd_device_free(snd_card_t *card, void *device_data)
continue;
/* unlink */
list_del(&dev->list);
if (dev->state == SNDRV_DEV_REGISTERED && dev->ops->dev_unregister) {
if ((dev->state == SNDRV_DEV_REGISTERED || dev->state == SNDRV_DEV_DISCONNECTED) &&
dev->ops->dev_unregister) {
if (dev->ops->dev_unregister(dev))
snd_printk(KERN_ERR "device unregister failure\n");
} else {
......@@ -72,6 +73,28 @@ int snd_device_free(snd_card_t *card, void *device_data)
return -ENXIO;
}
int snd_device_disconnect(snd_card_t *card, void *device_data)
{
struct list_head *list;
snd_device_t *dev;
snd_assert(card != NULL, return -ENXIO);
snd_assert(device_data != NULL, return -ENXIO);
list_for_each(list, &card->devices) {
dev = snd_device(list);
if (dev->device_data != device_data)
continue;
if (dev->state == SNDRV_DEV_REGISTERED && dev->ops->dev_disconnect) {
if (dev->ops->dev_disconnect(dev))
snd_printk(KERN_ERR "device disconnect failure\n");
dev->state = SNDRV_DEV_DISCONNECTED;
}
return 0;
}
snd_printd("device disconnect %p (from %p), not found\n", device_data, __builtin_return_address(0));
return -ENXIO;
}
int snd_device_register(snd_card_t *card, void *device_data)
{
struct list_head *list;
......@@ -113,6 +136,21 @@ int snd_device_register_all(snd_card_t *card)
return 0;
}
int snd_device_disconnect_all(snd_card_t *card)
{
snd_device_t *dev;
struct list_head *list;
int err = 0;
snd_assert(card != NULL, return -ENXIO);
list_for_each(list, &card->devices) {
dev = snd_device(list);
if (snd_device_disconnect(card, dev->device_data) < 0)
err = -ENXIO;
}
return err;
}
int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd)
{
snd_device_t *dev;
......
......@@ -933,11 +933,7 @@ snd_info_entry_t *snd_info_create_device(const char *name, unsigned int number,
p = create_proc_entry(entry->name, entry->mode, snd_proc_dev);
if (p) {
snd_info_device_entry_prepare(p, entry);
#ifndef LINUX_2_2
/* we should not set this - at least on 2.4.14 or later it causes
problems! */
/* p->proc_fops = &snd_fops; */
#else
#ifdef LINUX_2_2
p->ops = &snd_info_device_inode_operations;
#endif
} else {
......@@ -1028,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
......
This diff is collapsed.
......@@ -24,7 +24,6 @@
#include <linux/init.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <sound/core.h>
#include <sound/control.h>
......
......@@ -20,7 +20,6 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <asm/uaccess.h>
......
......@@ -20,7 +20,6 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <sound/core.h>
#include <sound/timer.h>
#include <asm/uaccess.h>
......
......@@ -20,7 +20,6 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <sound/core.h>
#include <sound/timer.h>
#include <asm/uaccess.h>
......
......@@ -45,14 +45,20 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
int cardnum = SNDRV_MINOR_OSS_CARD(minor(inode->i_rdev));
snd_card_t *card;
snd_mixer_oss_file_t *fmixer;
int err;
if ((card = snd_cards[cardnum]) == NULL)
return -ENODEV;
if (card->mixer_oss == NULL)
return -ENODEV;
err = snd_card_file_add(card, file);
if (err < 0)
return err;
fmixer = (snd_mixer_oss_file_t *)snd_kcalloc(sizeof(*fmixer), GFP_KERNEL);
if (fmixer == NULL)
if (fmixer == NULL) {
snd_card_file_remove(card, file);
return -ENOMEM;
}
fmixer->card = card;
fmixer->mixer = card->mixer_oss;
file->private_data = fmixer;
......@@ -64,6 +70,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
snd_card_file_remove(card, file);
return -EFAULT;
}
return 0;
......@@ -79,6 +86,7 @@ static int snd_mixer_oss_release(struct inode *inode, struct file *file)
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
snd_card_file_remove(fmixer->card, file);
kfree(fmixer);
}
return 0;
......@@ -554,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) {
......@@ -571,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;
}
......@@ -647,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)
......@@ -677,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;
}
......@@ -690,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;
}
......@@ -706,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;
}
......@@ -720,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;
}
......@@ -733,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;
}
......@@ -756,16 +764,15 @@ 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;
pslot = &fmixer->mixer->slots[idx];
pslot = &mixer->slots[idx];
slot = (struct slot *)pslot->private_data;
if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
continue;
......@@ -777,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)
......@@ -805,14 +810,14 @@ 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);
for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx)))
continue;
pslot = &fmixer->mixer->slots[idx];
pslot = &mixer->slots[idx];
slot = (struct slot *)pslot->private_data;
if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
continue;
......@@ -830,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)
......@@ -1200,10 +1205,11 @@ static int snd_mixer_oss_free1(void *private)
return 0;
}
static int snd_mixer_oss_notify_handler(snd_card_t * card, int free_flag)
static int snd_mixer_oss_notify_handler(snd_card_t * card, int cmd)
{
if (!free_flag) {
snd_mixer_oss_t *mixer;
snd_mixer_oss_t *mixer;
if (cmd == SND_MIXER_OSS_NOTIFY_REGISTER) {
char name[128];
int idx, err;
......@@ -1220,6 +1226,7 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int free_flag)
snd_magic_kfree(mixer);
return err;
}
mixer->oss_dev_alloc = 1;
mixer->card = card;
if (*card->mixername) {
strncpy(mixer->name, card->mixername, sizeof(mixer->name) - 1);
......@@ -1236,14 +1243,21 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int free_flag)
card->mixer_oss = mixer;
snd_mixer_oss_build(mixer);
snd_mixer_oss_proc_init(mixer);
} else {
snd_mixer_oss_t *mixer = card->mixer_oss;
} else if (cmd == SND_MIXER_OSS_NOTIFY_DISCONNECT) {
mixer = card->mixer_oss;
if (mixer == NULL || !mixer->oss_dev_alloc)
return 0;
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, mixer->card, 0);
mixer->oss_dev_alloc = 0;
} else { /* free */
mixer = card->mixer_oss;
if (mixer == NULL)
return 0;
#ifdef SNDRV_OSS_INFO_DEV_MIXERS
snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIXERS, mixer->card->number);
#endif
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, mixer->card, 0);
if (mixer->oss_dev_alloc)
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, mixer->card, 0);
snd_mixer_oss_proc_done(mixer);
return snd_mixer_oss_free1(mixer);
}
......@@ -1257,7 +1271,7 @@ static int __init alsa_mixer_oss_init(void)
snd_mixer_oss_notify_callback = snd_mixer_oss_notify_handler;
for (idx = 0; idx < SNDRV_CARDS; idx++) {
if (snd_cards[idx])
snd_mixer_oss_notify_handler(snd_cards[idx], 0);
snd_mixer_oss_notify_handler(snd_cards[idx], SND_MIXER_OSS_NOTIFY_REGISTER);
}
return 0;
}
......@@ -1269,7 +1283,7 @@ static void __exit alsa_mixer_oss_exit(void)
snd_mixer_oss_notify_callback = NULL;
for (idx = 0; idx < SNDRV_CARDS; idx++) {
if (snd_cards[idx])
snd_mixer_oss_notify_handler(snd_cards[idx], 1);
snd_mixer_oss_notify_handler(snd_cards[idx], SND_MIXER_OSS_NOTIFY_FREE);
}
}
......
......@@ -1554,13 +1554,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
err = -ENODEV;
goto __error1;
}
err = snd_card_file_add(pcm->card, file);
if (err < 0)
goto __error1;
if (!try_inc_mod_count(pcm->card->module)) {
err = -EFAULT;
goto __error1;
goto __error2;
}
if (snd_task_name(current, task_name, sizeof(task_name)) < 0) {
err = -EFAULT;
goto __error1;
goto __error;
}
if (file->f_mode & FMODE_WRITE)
psetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, task_name);
......@@ -1584,13 +1587,12 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
init_waitqueue_entry(&wait, current);
add_wait_queue(&pcm->open_wait, &wait);
down(&pcm->open_mutex);
while (1) {
down(&pcm->open_mutex);
err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
minor, psetup, csetup);
if (err >= 0)
break;
up(&pcm->open_mutex);
if (err == -EAGAIN) {
if (nonblock) {
err = -EBUSY;
......@@ -1599,7 +1601,9 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
} else
break;
set_current_state(TASK_INTERRUPTIBLE);
up(&pcm->open_mutex);
schedule();
down(&pcm->open_mutex);
if (signal_pending(current)) {
err = -ERESTARTSYS;
break;
......@@ -1607,13 +1611,15 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&pcm->open_wait, &wait);
up(&pcm->open_mutex);
if (err < 0)
goto __error;
up(&pcm->open_mutex);
return err;
__error:
dec_mod_count(pcm->card->module);
__error2:
snd_card_file_remove(pcm->card, file);
__error1:
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
......@@ -1639,6 +1645,7 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
up(&pcm->open_mutex);
wake_up(&pcm->open_wait);
dec_mod_count(pcm->card->module);
snd_card_file_remove(pcm->card, file);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
......@@ -2108,7 +2115,7 @@ static snd_minor_t snd_pcm_oss_reg =
.f_ops = &snd_pcm_oss_f_reg,
};
static void register_oss_dsp(unsigned short native_minor, snd_pcm_t *pcm, int index)
static void register_oss_dsp(snd_pcm_t *pcm, int index)
{
char name[128];
sprintf(name, "dsp%i%i", pcm->card->number, pcm->device);
......@@ -2119,14 +2126,13 @@ static void register_oss_dsp(unsigned short native_minor, snd_pcm_t *pcm, int in
}
}
static int snd_pcm_oss_register_minor(unsigned short native_minor,
snd_pcm_t * pcm)
static int snd_pcm_oss_register_minor(snd_pcm_t * pcm)
{
pcm->oss.reg = 0;
if (dsp_map[pcm->card->number] == pcm->device) {
char name[128];
int duplex;
register_oss_dsp(native_minor, pcm, 0);
register_oss_dsp(pcm, 0);
duplex = (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count > 0 &&
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count &&
!(pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX));
......@@ -2137,10 +2143,12 @@ static int snd_pcm_oss_register_minor(unsigned short native_minor,
name);
#endif
pcm->oss.reg++;
pcm->oss.reg_mask |= 1;
}
if (adsp_map[pcm->card->number] == pcm->device) {
register_oss_dsp(native_minor, pcm, 1);
register_oss_dsp(pcm, 1);
pcm->oss.reg++;
pcm->oss.reg_mask |= 2;
}
if (pcm->oss.reg)
......@@ -2149,20 +2157,32 @@ static int snd_pcm_oss_register_minor(unsigned short native_minor,
return 0;
}
static int snd_pcm_oss_unregister_minor(unsigned short native_minor,
snd_pcm_t * pcm)
static int snd_pcm_oss_disconnect_minor(snd_pcm_t * pcm)
{
if (pcm->oss.reg) {
if (dsp_map[pcm->card->number] == pcm->device) {
if (pcm->oss.reg_mask & 1) {
pcm->oss.reg_mask &= ~1;
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
pcm->card, 0);
}
if (pcm->oss.reg_mask & 2) {
pcm->oss.reg_mask &= ~2;
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
pcm->card, 1);
}
}
return 0;
}
static int snd_pcm_oss_unregister_minor(snd_pcm_t * pcm)
{
snd_pcm_oss_disconnect_minor(pcm);
if (pcm->oss.reg) {
if (dsp_map[pcm->card->number] == pcm->device) {
#ifdef SNDRV_OSS_INFO_DEV_AUDIO
snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_AUDIO, pcm->card->number);
#endif
}
if (adsp_map[pcm->card->number] == pcm->device)
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
pcm->card, 1);
pcm->oss.reg = 0;
snd_pcm_oss_proc_done(pcm);
}
......@@ -2172,6 +2192,7 @@ static int snd_pcm_oss_unregister_minor(unsigned short native_minor,
static snd_pcm_notify_t snd_pcm_oss_notify =
{
.n_register = snd_pcm_oss_register_minor,
.n_disconnect = snd_pcm_oss_disconnect_minor,
.n_unregister = snd_pcm_oss_unregister_minor,
};
......@@ -2180,8 +2201,6 @@ static int __init alsa_pcm_oss_init(void)
int i;
int err;
if ((err = snd_pcm_notify(&snd_pcm_oss_notify, 0)) < 0)
return err;
/* check device map table */
for (i = 0; i < SNDRV_CARDS; i++) {
if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
......@@ -2193,6 +2212,8 @@ static int __init alsa_pcm_oss_init(void)
adsp_map[i] = 1;
}
}
if ((err = snd_pcm_notify(&snd_pcm_oss_notify, 0)) < 0)
return err;
return 0;
}
......
......@@ -37,9 +37,10 @@ snd_pcm_t *snd_pcm_devices[SNDRV_CARDS * SNDRV_PCM_DEVICES];
static LIST_HEAD(snd_pcm_notify_list);
static DECLARE_MUTEX(register_mutex);
int snd_pcm_free(snd_pcm_t *pcm);
static int snd_pcm_free(snd_pcm_t *pcm);
static int snd_pcm_dev_free(snd_device_t *device);
static int snd_pcm_dev_register(snd_device_t *device);
static int snd_pcm_dev_disconnect(snd_device_t *device);
static int snd_pcm_dev_unregister(snd_device_t *device);
void snd_pcm_lock(int xup)
......@@ -590,7 +591,7 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
}
int snd_pcm_new(snd_card_t * card, char *id, int device,
int playback_count, int capture_count,
int playback_count, int capture_count,
snd_pcm_t ** rpcm)
{
snd_pcm_t *pcm;
......@@ -598,6 +599,7 @@ int snd_pcm_new(snd_card_t * card, char *id, int device,
static snd_device_ops_t ops = {
.dev_free = snd_pcm_dev_free,
.dev_register = snd_pcm_dev_register,
.dev_disconnect = snd_pcm_dev_disconnect,
.dev_unregister = snd_pcm_dev_unregister
};
......@@ -653,7 +655,7 @@ static void snd_pcm_free_stream(snd_pcm_str_t * pstr)
#endif
}
int snd_pcm_free(snd_pcm_t *pcm)
static int snd_pcm_free(snd_pcm_t *pcm)
{
snd_assert(pcm != NULL, return -ENXIO);
if (pcm->private_free)
......@@ -664,7 +666,7 @@ int snd_pcm_free(snd_pcm_t *pcm)
return 0;
}
int snd_pcm_dev_free(snd_device_t *device)
static int snd_pcm_dev_free(snd_device_t *device)
{
snd_pcm_t *pcm = snd_magic_cast(snd_pcm_t, device->device_data, return -ENXIO);
return snd_pcm_free(pcm);
......@@ -696,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) {
......@@ -704,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;
......@@ -793,7 +795,7 @@ void snd_pcm_release_substream(snd_pcm_substream_t *substream)
substream->pstr->substream_opened--;
}
int snd_pcm_dev_register(snd_device_t *device)
static int snd_pcm_dev_register(snd_device_t *device)
{
int idx, cidx, err;
unsigned short minor;
......@@ -837,7 +839,25 @@ int snd_pcm_dev_register(snd_device_t *device)
list_for_each(list, &snd_pcm_notify_list) {
snd_pcm_notify_t *notify;
notify = list_entry(list, snd_pcm_notify_t, list);
notify->n_register(-1 /* idx + SNDRV_MINOR_PCM */, pcm);
notify->n_register(pcm);
}
snd_pcm_lock(1);
return 0;
}
static int snd_pcm_dev_disconnect(snd_device_t *device)
{
snd_pcm_t *pcm = snd_magic_cast(snd_pcm_t, device->device_data, return -ENXIO);
struct list_head *list;
int idx;
snd_pcm_lock(0);
idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
snd_pcm_devices[idx] = NULL;
list_for_each(list, &snd_pcm_notify_list) {
snd_pcm_notify_t *notify;
notify = list_entry(list, snd_pcm_notify_t, list);
notify->n_disconnect(pcm);
}
snd_pcm_lock(1);
return 0;
......@@ -853,10 +873,7 @@ static int snd_pcm_dev_unregister(snd_device_t *device)
snd_assert(pcm != NULL, return -ENXIO);
snd_pcm_lock(0);
idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
if (snd_pcm_devices[idx] != pcm) {
snd_pcm_lock(1);
return -EINVAL;
}
snd_pcm_devices[idx] = NULL;
for (cidx = 0; cidx < 2; cidx++) {
devtype = -1;
switch (cidx) {
......@@ -874,9 +891,8 @@ static int snd_pcm_dev_unregister(snd_device_t *device)
list_for_each(list, &snd_pcm_notify_list) {
snd_pcm_notify_t *notify;
notify = list_entry(list, snd_pcm_notify_t, list);
notify->n_unregister(-1 /* SNDRV_MINOR_PCM + idx */, pcm);
notify->n_unregister(pcm);
}
snd_pcm_devices[idx] = NULL;
snd_pcm_lock(1);
return snd_pcm_free(pcm);
}
......@@ -892,16 +908,14 @@ int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree)
for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
if (snd_pcm_devices[idx] == NULL)
continue;
notify->n_unregister(-1 /* idx + SNDRV_MINOR_PCM */,
snd_pcm_devices[idx]);
notify->n_unregister(snd_pcm_devices[idx]);
}
} else {
list_add_tail(&notify->list, &snd_pcm_notify_list);
for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
if (snd_pcm_devices[idx] == NULL)
continue;
notify->n_register(-1 /* idx + SNDRV_MINOR_PCM */,
snd_pcm_devices[idx]);
notify->n_register(snd_pcm_devices[idx]);
}
}
snd_pcm_lock(1);
......
......@@ -106,12 +106,12 @@ int snd_pcm_update_hw_ptr_interrupt(snd_pcm_substream_t *substream)
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp);
#ifdef CONFIG_SND_DEBUG
if (pos > runtime->buffer_size) {
if (pos >= runtime->buffer_size) {
snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
} else
#endif
snd_runtime_check(pos <= runtime->buffer_size, return 0);
snd_runtime_check(pos < runtime->buffer_size, return 0);
pos -= pos % runtime->min_align;
new_hw_ptr = runtime->hw_ptr_base + pos;
......@@ -172,12 +172,12 @@ int snd_pcm_update_hw_ptr(snd_pcm_substream_t *substream)
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp);
#ifdef CONFIG_SND_DEBUG
if (pos > runtime->buffer_size) {
if (pos >= runtime->buffer_size) {
snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
} else
#endif
snd_runtime_check(pos <= runtime->buffer_size, return 0);
snd_runtime_check(pos < runtime->buffer_size, return 0);
pos -= pos % runtime->min_align;
new_hw_ptr = runtime->hw_ptr_base + pos;
......
......@@ -1796,9 +1796,12 @@ int snd_pcm_open(struct inode *inode, struct file *file)
err = -ENODEV;
goto __error1;
}
err = snd_card_file_add(pcm->card, file);
if (err < 0)
goto __error1;
if (!try_inc_mod_count(pcm->card->module)) {
err = -EFAULT;
goto __error1;
goto __error2;
}
init_waitqueue_entry(&wait, current);
add_wait_queue(&pcm->open_wait, &wait);
......@@ -1831,6 +1834,8 @@ int snd_pcm_open(struct inode *inode, struct file *file)
__error:
dec_mod_count(pcm->card->module);
__error2:
snd_card_file_remove(pcm->card, file);
__error1:
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
......@@ -1859,6 +1864,7 @@ int snd_pcm_release(struct inode *inode, struct file *file)
up(&pcm->open_mutex);
wake_up(&pcm->open_wait);
dec_mod_count(pcm->card->module);
snd_card_file_remove(pcm->card, file);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
......
......@@ -51,6 +51,7 @@ MODULE_PARM_SYNTAX(amidi_map, "default:1,skill:advanced");
static int snd_rawmidi_free(snd_rawmidi_t *rawmidi);
static int snd_rawmidi_dev_free(snd_device_t *device);
static int snd_rawmidi_dev_register(snd_device_t *device);
static int snd_rawmidi_dev_disconnect(snd_device_t *device);
static int snd_rawmidi_dev_unregister(snd_device_t *device);
snd_rawmidi_t *snd_rawmidi_devices[SNDRV_CARDS * SNDRV_RAWMIDI_DEVICES];
......@@ -389,24 +390,29 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
if (rmidi == NULL)
return -ENODEV;
card = rmidi->card;
#ifdef CONFIG_SND_OSSEMUL
if (maj == SOUND_MAJOR && !rmidi->ossreg)
return -ENXIO;
#endif
fflags = snd_rawmidi_file_flags(file);
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
return -EINVAL; /* invalid combination */
card = rmidi->card;
err = snd_card_file_add(card, file);
if (err < 0)
return -ENODEV;
fflags = snd_rawmidi_file_flags(file);
if ((file->f_flags & O_APPEND) || maj != CONFIG_SND_MAJOR) /* OSS emul? */
fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
rawmidi_file = snd_magic_kmalloc(snd_rawmidi_file_t, 0, GFP_KERNEL);
if (rawmidi_file == NULL)
if (rawmidi_file == NULL) {
snd_card_file_remove(card, file);
return -ENOMEM;
}
init_waitqueue_entry(&wait, current);
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) {
......@@ -414,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;
......@@ -443,6 +449,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
if (err >= 0) {
file->private_data = rawmidi_file;
} else {
snd_card_file_remove(card, file);
snd_magic_kfree(rawmidi_file);
}
return err;
......@@ -507,12 +514,15 @@ int snd_rawmidi_kernel_release(snd_rawmidi_file_t * rfile)
static int snd_rawmidi_release(struct inode *inode, struct file *file)
{
snd_rawmidi_file_t *rfile;
snd_rawmidi_t *rmidi;
int err;
rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return -ENXIO);
err = snd_rawmidi_kernel_release(rfile);
wake_up(&rfile->rmidi->open_wait);
rmidi = rfile->rmidi;
wake_up(&rmidi->open_wait);
snd_magic_kfree(rfile);
snd_card_file_remove(rmidi->card, file);
return err;
}
......@@ -1318,6 +1328,7 @@ int snd_rawmidi_new(snd_card_t * card, char *id, int device,
static snd_device_ops_t ops = {
.dev_free = snd_rawmidi_dev_free,
.dev_register = snd_rawmidi_dev_register,
.dev_disconnect = snd_rawmidi_dev_disconnect,
.dev_unregister = snd_rawmidi_dev_unregister
};
......@@ -1466,6 +1477,18 @@ static int snd_rawmidi_dev_register(snd_device_t *device)
return 0;
}
static int snd_rawmidi_dev_disconnect(snd_device_t *device)
{
snd_rawmidi_t *rmidi = snd_magic_cast(snd_rawmidi_t, device->device_data, return -ENXIO);
int idx;
down(&register_mutex);
idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
snd_rawmidi_devices[idx] = NULL;
up(&register_mutex);
return 0;
}
static int snd_rawmidi_dev_unregister(snd_device_t *device)
{
int idx;
......@@ -1474,10 +1497,7 @@ static int snd_rawmidi_dev_unregister(snd_device_t *device)
snd_assert(rmidi != NULL, return -ENXIO);
down(&register_mutex);
idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
if (snd_rawmidi_devices[idx] != rmidi) {
up(&register_mutex);
return -EINVAL;
}
snd_rawmidi_devices[idx] = NULL;
if (rmidi->proc_entry) {
snd_info_unregister(rmidi->proc_entry);
rmidi->proc_entry = NULL;
......@@ -1498,7 +1518,6 @@ static int snd_rawmidi_dev_unregister(snd_device_t *device)
if (rmidi->ops && rmidi->ops->dev_unregister)
rmidi->ops->dev_unregister(rmidi);
snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
snd_rawmidi_devices[idx] = NULL;
up(&register_mutex);
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
if (rmidi->seq_dev) {
......@@ -1526,10 +1545,10 @@ void snd_rawmidi_set_ops(snd_rawmidi_t *rmidi, int stream, snd_rawmidi_ops_t *op
static int __init alsa_rawmidi_init(void)
{
int i;
snd_ctl_register_ioctl(snd_rawmidi_control_ioctl);
#ifdef CONFIG_SND_OSSEMUL
{ int i;
/* check device map table */
for (i = 0; i < SNDRV_CARDS; i++) {
if (midi_map[i] < 0 || midi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
......@@ -1541,6 +1560,7 @@ static int __init alsa_rawmidi_init(void)
amidi_map[i] = 1;
}
}
}
#endif /* CONFIG_SND_OSSEMUL */
return 0;
}
......
......@@ -29,50 +29,53 @@ endif
obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_SERIAL_U16550) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_MTPAV) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_MPU401) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_ALS100) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_AZT2320) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_DT019X) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_ES18XX) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_OPL3SA2) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_AD1816A) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_CS4231) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_CS4232) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_CS4236) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_ES1688) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_GUSCLASSIC) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_GUSMAX) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_GUSEXTREME) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_INTERWAVE) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_INTERWAVE_STB) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_OPTI93X) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_SB8) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_SB16) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_SBAWE) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o snd-seq-virmidi.o
obj-$(CONFIG_SND_ES968) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_WAVEFRONT) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_ALS4000) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_CMIPCI) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_CS4281) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_ENS1370) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_ENS1371) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_ES1938) += snd-seq-device.o snd-seq-midi-emul.o snd-seq.o snd-seq-instr.o snd-seq-midi.o snd-seq-midi-event.o
obj-$(CONFIG_SND_ES1968) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_FM801) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_ICE1712) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_INTEL8X0) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_SONICVIBES) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_VIA82XX) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_ALI5451) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_CS46XX) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_EMU10K1) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-virmidi.o
obj-$(CONFIG_SND_TRIDENT) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_YMFPCI) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_USB_AUDIO) += snd-seq.o snd-seq-device.o snd-seq-midi-event.o
RAWMIDI_OBJS = snd-seq-midi.o snd-seq-midi-event.o
OPL3_OBJS = snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o
obj-$(CONFIG_SND_SERIAL_U16550) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_MTPAV) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_MPU401) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ALS100) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_AZT2320) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_DT019X) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ES18XX) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPL3SA2) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
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)
obj-$(CONFIG_SND_GUSEXTREME) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_INTERWAVE) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_INTERWAVE_STB) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI92X_AD1848) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI92X_CS4231) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI93X) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_SB8) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_SB16) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_SBAWE) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o
obj-$(CONFIG_SND_ES968) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_WAVEFRONT) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ALS4000) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CMIPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4281) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ENS1370) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ENS1371) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ES1938) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ES1968) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_FM801) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ICE1712) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_INTEL8X0) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_SONICVIBES) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_VIA82XX) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ALI5451) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_CS46XX) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_EMU10K1) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-virmidi.o
obj-$(CONFIG_SND_TRIDENT) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_YMFPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_USB_AUDIO) += $(RAWMIDI_OBJS)
obj-m := $(sort $(obj-m))
......@@ -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);
......
......@@ -92,6 +92,7 @@ static snd_info_entry_t *info_entry = NULL;
static int snd_seq_device_free(snd_seq_device_t *dev);
static int snd_seq_device_dev_free(snd_device_t *device);
static int snd_seq_device_dev_register(snd_device_t *device);
static int snd_seq_device_dev_disconnect(snd_device_t *device);
static int snd_seq_device_dev_unregister(snd_device_t *device);
static int init_device(snd_seq_device_t *dev, ops_list_t *ops);
......@@ -166,6 +167,7 @@ int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize,
static snd_device_ops_t dops = {
.dev_free = snd_seq_device_dev_free,
.dev_register = snd_seq_device_dev_register,
.dev_disconnect = snd_seq_device_dev_disconnect,
.dev_unregister = snd_seq_device_dev_unregister
};
......@@ -268,6 +270,24 @@ static int snd_seq_device_dev_register(snd_device_t *device)
return 0;
}
/*
* disconnect the device
*/
static int snd_seq_device_dev_disconnect(snd_device_t *device)
{
snd_seq_device_t *dev = snd_magic_cast(snd_seq_device_t, device->device_data, return -ENXIO);
ops_list_t *ops;
ops = find_driver(dev->id, 0);
if (ops == NULL)
return -ENOENT;
free_device(dev, ops);
unlock_driver(ops);
return 0;
}
/*
* unregister the existing device
*/
......
......@@ -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;
......
......@@ -76,8 +76,12 @@ static devfs_handle_t devfs_handle = NULL;
void snd_request_card(int card)
{
char str[32];
int locked;
if (snd_cards[card] != NULL)
read_lock(&snd_card_rwlock);
locked = snd_cards_lock & (1 << card);
read_unlock(&snd_card_rwlock);
if (locked)
return;
if (card < 0 || card >= snd_ecards_limit)
return;
......@@ -423,9 +427,13 @@ EXPORT_SYMBOL(snd_cards);
EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
#endif
EXPORT_SYMBOL(snd_card_new);
EXPORT_SYMBOL(snd_card_disconnect);
EXPORT_SYMBOL(snd_card_free);
EXPORT_SYMBOL(snd_card_free_in_thread);
EXPORT_SYMBOL(snd_card_register);
EXPORT_SYMBOL(snd_component_add);
EXPORT_SYMBOL(snd_card_file_add);
EXPORT_SYMBOL(snd_card_file_remove);
#ifdef CONFIG_PM
EXPORT_SYMBOL(snd_power_wait);
#endif
......
......@@ -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);
......
......@@ -13,56 +13,35 @@ snd-opl3-synth-objs += opl3_oss.o
endif
endif
# Toplevel Module Dependency
obj-$(CONFIG_SND_ALS100) += snd-opl3-lib.o
obj-$(CONFIG_SND_AZT2320) += snd-opl3-lib.o
obj-$(CONFIG_SND_DT019X) += snd-opl3-lib.o
obj-$(CONFIG_SND_ES18XX) += snd-opl3-lib.o
obj-$(CONFIG_SND_OPL3SA2) += snd-opl3-lib.o
obj-$(CONFIG_SND_AD1816A) += snd-opl3-lib.o
obj-$(CONFIG_SND_CS4232) += snd-opl3-lib.o
obj-$(CONFIG_SND_CS4236) += snd-opl3-lib.o
obj-$(CONFIG_SND_ES1688) += snd-opl3-lib.o
obj-$(CONFIG_SND_GUSEXTREME) += snd-opl3-lib.o
obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opl3-lib.o
obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opl3-lib.o
obj-$(CONFIG_SND_OPTI93X) += snd-opl3-lib.o
obj-$(CONFIG_SND_SB8) += snd-opl3-lib.o
obj-$(CONFIG_SND_SB16) += snd-opl3-lib.o
obj-$(CONFIG_SND_SBAWE) += snd-opl3-lib.o
obj-$(CONFIG_SND_WAVEFRONT) += snd-opl3-lib.o
obj-$(CONFIG_SND_ALS4000) += snd-opl3-lib.o
obj-$(CONFIG_SND_CMIPCI) += snd-opl3-lib.o
obj-$(CONFIG_SND_CS4281) += snd-opl3-lib.o
obj-$(CONFIG_SND_ES1938) += snd-opl3-lib.o
obj-$(CONFIG_SND_FM801) += snd-opl3-lib.o
obj-$(CONFIG_SND_SONICVIBES) += snd-opl3-lib.o
obj-$(CONFIG_SND_YMFPCI) += snd-opl3-lib.o
OPL3_OBJS = snd-opl3-lib.o
ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
obj-$(CONFIG_SND_ALS100) += snd-opl3-synth.o
obj-$(CONFIG_SND_AZT2320) += snd-opl3-synth.o
obj-$(CONFIG_SND_DT019X) += snd-opl3-synth.o
obj-$(CONFIG_SND_ES18XX) += snd-opl3-synth.o
obj-$(CONFIG_SND_OPL3SA2) += snd-opl3-synth.o
obj-$(CONFIG_SND_AD1816A) += snd-opl3-synth.o
obj-$(CONFIG_SND_CS4232) += snd-opl3-synth.o
obj-$(CONFIG_SND_CS4236) += snd-opl3-synth.o
obj-$(CONFIG_SND_ES1688) += snd-opl3-synth.o
obj-$(CONFIG_SND_GUSEXTREME) += snd-opl3-synth.o
obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opl3-synth.o
obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opl3-synth.o
obj-$(CONFIG_SND_OPTI93X) += snd-opl3-synth.o
obj-$(CONFIG_SND_SB8) += snd-opl3-synth.o
obj-$(CONFIG_SND_SB16) += snd-opl3-synth.o
obj-$(CONFIG_SND_SBAWE) += snd-opl3-synth.o
obj-$(CONFIG_SND_WAVEFRONT) += snd-opl3-synth.o
obj-$(CONFIG_SND_ALS4000) += snd-opl3-synth.o
obj-$(CONFIG_SND_CMIPCI) += snd-opl3-synth.o
obj-$(CONFIG_SND_CS4281) += snd-opl3-synth.o
obj-$(CONFIG_SND_ES1938) += snd-opl3-synth.o
obj-$(CONFIG_SND_FM801) += snd-opl3-synth.o
obj-$(CONFIG_SND_SONICVIBES) += snd-opl3-synth.o
obj-$(CONFIG_SND_YMFPCI) += snd-opl3-synth.o
OPL3_OBJS += snd-opl3-synth.o
endif
# Toplevel Module Dependency
obj-$(CONFIG_SND_ALS100) += $(OPL3_OBJS)
obj-$(CONFIG_SND_AZT2320) += $(OPL3_OBJS)
obj-$(CONFIG_SND_DT019X) += $(OPL3_OBJS)
obj-$(CONFIG_SND_ES18XX) += $(OPL3_OBJS)
obj-$(CONFIG_SND_OPL3SA2) += $(OPL3_OBJS)
obj-$(CONFIG_SND_AD1816A) += $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4232) += $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4236) += $(OPL3_OBJS)
obj-$(CONFIG_SND_ES1688) += $(OPL3_OBJS)
obj-$(CONFIG_SND_GUSEXTREME) += $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI92X_AD1848) += $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI92X_CS4231) += $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI93X) += $(OPL3_OBJS)
obj-$(CONFIG_SND_SB8) += $(OPL3_OBJS)
obj-$(CONFIG_SND_SB16) += $(OPL3_OBJS)
obj-$(CONFIG_SND_SBAWE) += $(OPL3_OBJS)
obj-$(CONFIG_SND_WAVEFRONT) += $(OPL3_OBJS)
obj-$(CONFIG_SND_ALS4000) += $(OPL3_OBJS)
obj-$(CONFIG_SND_CMIPCI) += $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4281) += $(OPL3_OBJS)
obj-$(CONFIG_SND_ES1938) += $(OPL3_OBJS)
obj-$(CONFIG_SND_FM801) += $(OPL3_OBJS)
obj-$(CONFIG_SND_SONICVIBES) += $(OPL3_OBJS)
obj-$(CONFIG_SND_YMFPCI) += $(OPL3_OBJS)
obj-m := $(sort $(obj-m))
......@@ -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 */
......
......@@ -266,7 +266,6 @@ static int snd_opl3_seq_new_device(snd_seq_device_t *dev)
snd_seq_fm_init(&opl3->fm_ops, NULL);
/* setup system timer */
memset(&opl3->tlist, 0, sizeof(opl3->tlist));
init_timer(&opl3->tlist);
opl3->tlist.function = snd_opl3_timer_func;
opl3->tlist.data = (unsigned long) opl3;
......
......@@ -51,6 +51,9 @@
#define SNDRV_GET_ID
#include <sound/initval.h>
/* hack: OSS defines midi_devs, so undefine it (versioned symbols) */
#undef midi_devs
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("Dummy soundcard for virtual rawmidi devices");
MODULE_LICENSE("GPL");
......
......@@ -445,6 +445,9 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream,
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
int result = 0;
unsigned int what;
snd_pcm_substream_t *s;
int do_start;
#if 0
printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, cs4231_inb(chip, CS4231P(STATUS)));
......@@ -452,38 +455,39 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
do_start = 1; break;
case SNDRV_PCM_TRIGGER_STOP:
{
unsigned int what = 0;
snd_pcm_substream_t *s = substream;
do {
if (s == chip->playback_substream) {
what |= CS4231_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
} else if (s == chip->capture_substream) {
what |= CS4231_RECORD_ENABLE;
snd_pcm_trigger_done(s, substream);
}
s = s->link_next;
} while (s != substream);
spin_lock(&chip->reg_lock);
if (cmd == SNDRV_PCM_TRIGGER_START) {
chip->image[CS4231_IFACE_CTRL] |= what;
if (chip->trigger)
chip->trigger(chip, what, 1);
} else {
chip->image[CS4231_IFACE_CTRL] &= ~what;
if (chip->trigger)
chip->trigger(chip, what, 0);
}
snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
spin_unlock(&chip->reg_lock);
break;
}
case SNDRV_PCM_TRIGGER_SUSPEND:
do_start = 0; break;
default:
result = -EINVAL;
break;
return -EINVAL;
}
what = 0;
s = substream;
do {
if (s == chip->playback_substream) {
what |= CS4231_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
} else if (s == chip->capture_substream) {
what |= CS4231_RECORD_ENABLE;
snd_pcm_trigger_done(s, substream);
}
s = s->link_next;
} while (s != substream);
spin_lock(&chip->reg_lock);
if (do_start) {
chip->image[CS4231_IFACE_CTRL] |= what;
if (chip->trigger)
chip->trigger(chip, what, 1);
} else {
chip->image[CS4231_IFACE_CTRL] &= ~what;
if (chip->trigger)
chip->trigger(chip, what, 0);
}
snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
spin_unlock(&chip->reg_lock);
#if 0
snd_cs4231_debug(chip);
#endif
......@@ -1188,7 +1192,9 @@ int snd_cs4231_probe(cs4231_t *chip)
static snd_pcm_hardware_t snd_cs4231_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_SYNC_START),
.formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
......@@ -1207,7 +1213,9 @@ static snd_pcm_hardware_t snd_cs4231_playback =
static snd_pcm_hardware_t snd_cs4231_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_SYNC_START),
.formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
......
......@@ -263,6 +263,8 @@ static struct isapnp_card_id snd_card_pnpids[] __devinitdata = {
ISAPNP_CS4232('C','S','C',0xd937,0x0000,0x0010,0x0003),
/* CS4235 without MPU401 */
ISAPNP_CS4232_WOMPU('C','S','C',0xe825,0x0100,0x0110),
/* IBM IntelliStation M Pro 6898 11U - CS4236B */
ISAPNP_CS4232_WOMPU('C','S','C',0xe835,0x0000,0x0010),
/* Some noname CS4236 based card */
ISAPNP_CS4232('C','S','C',0xe936,0x0000,0x0010,0x0003),
/* CS4236B */
......@@ -609,12 +611,10 @@ module_exit(alsa_card_cs423x_exit)
/* format is: snd-cs4232=enable,index,id,isapnp,port,
cport,mpu_port,fm_port,sb_port,
irq,mpu_irq,dma1,dma1_size,
dma2,dma2_size */
irq,mpu_irq,dma1,dma2 */
/* format is: snd-cs4236=enable,index,id,isapnp,port,
cport,mpu_port,fm_port,sb_port,
irq,mpu_irq,dma1,dma1_size,
dma2,dma2_size */
irq,mpu_irq,dma1,dma2 */
static int __init alsa_card_cs423x_setup(char *str)
{
......
......@@ -444,8 +444,7 @@ static int snd_es18xx_playback_hw_params(snd_pcm_substream_t * substream,
if (snd_pcm_format_width(params_format(hw_params)) == 16)
shift++;
switch (substream->number) {
case 0:
if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
if ((chip->caps & ES18XX_DUPLEX_MONO) &&
(chip->capture_a_substream) &&
params_channels(hw_params) != 1) {
......@@ -453,10 +452,8 @@ static int snd_es18xx_playback_hw_params(snd_pcm_substream_t * substream,
return -EBUSY;
}
chip->dma2_shift = shift;
break;
case 1:
} else {
chip->dma1_shift = shift;
break;
}
if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
return err;
......@@ -495,19 +492,12 @@ static int snd_es18xx_playback1_trigger(es18xx_t *chip,
snd_pcm_substream_t * substream,
int cmd)
{
if (cmd == SNDRV_PCM_TRIGGER_START) {
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
if (chip->active & DAC2)
return 0;
chip->active |= DAC2;
} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
if (!(chip->active & DAC2))
return 0;
chip->active &= ~DAC2;
} else {
return -EINVAL;
}
if (cmd == SNDRV_PCM_TRIGGER_START) {
/* Start DMA */
if (chip->dma2 >= 4)
snd_es18xx_mixer_write(chip, 0x78, 0xb3);
......@@ -523,8 +513,12 @@ static int snd_es18xx_playback1_trigger(es18xx_t *chip,
/* Enable PCM output */
snd_es18xx_dsp_command(chip, 0xD1);
#endif
}
else {
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
if (!(chip->active & DAC2))
return 0;
chip->active &= ~DAC2;
/* Stop DMA */
snd_es18xx_mixer_write(chip, 0x78, 0x00);
#ifdef AVOID_POPS
......@@ -536,7 +530,10 @@ static int snd_es18xx_playback1_trigger(es18xx_t *chip,
/* Disable PCM output */
snd_es18xx_dsp_command(chip, 0xD3);
#endif
}
break;
default:
return -EINVAL;
}
return 0;
}
......@@ -608,24 +605,27 @@ static int snd_es18xx_capture_trigger(snd_pcm_substream_t *substream,
{
es18xx_t *chip = snd_pcm_substream_chip(substream);
if (cmd == SNDRV_PCM_TRIGGER_START) {
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
if (chip->active & ADC1)
return 0;
chip->active |= ADC1;
} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
/* Start DMA */
snd_es18xx_write(chip, 0xB8, 0x0f);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
if (!(chip->active & ADC1))
return 0;
chip->active &= ~ADC1;
} else {
/* Stop DMA */
snd_es18xx_write(chip, 0xB8, 0x00);
break;
default:
return -EINVAL;
}
if (cmd == SNDRV_PCM_TRIGGER_START)
/* Start DMA */
snd_es18xx_write(chip, 0xB8, 0x0f);
else
/* Stop DMA */
snd_es18xx_write(chip, 0xB8, 0x00);
return 0;
}
......@@ -670,19 +670,12 @@ static int snd_es18xx_playback2_trigger(es18xx_t *chip,
snd_pcm_substream_t *substream,
int cmd)
{
if (cmd == SNDRV_PCM_TRIGGER_START) {
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
if (chip->active & DAC1)
return 0;
chip->active |= DAC1;
} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
if (!(chip->active & DAC1))
return 0;
chip->active &= ~DAC1;
} else {
return -EINVAL;
}
if (cmd == SNDRV_PCM_TRIGGER_START) {
/* Start DMA */
snd_es18xx_write(chip, 0xB8, 0x05);
#ifdef AVOID_POPS
......@@ -691,8 +684,12 @@ static int snd_es18xx_playback2_trigger(es18xx_t *chip,
/* Enable Audio 1 */
snd_es18xx_dsp_command(chip, 0xD1);
#endif
}
else {
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
if (!(chip->active & DAC1))
return 0;
chip->active &= ~DAC1;
/* Stop DMA */
snd_es18xx_write(chip, 0xB8, 0x00);
#ifdef AVOID_POPS
......@@ -701,33 +698,31 @@ static int snd_es18xx_playback2_trigger(es18xx_t *chip,
/* Disable Audio 1 */
snd_es18xx_dsp_command(chip, 0xD3);
#endif
}
break;
default:
return -EINVAL;
}
return 0;
}
static int snd_es18xx_playback_prepare(snd_pcm_substream_t *substream)
{
es18xx_t *chip = snd_pcm_substream_chip(substream);
switch (substream->number) {
case 0:
if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
return snd_es18xx_playback1_prepare(chip, substream);
case 1:
else
return snd_es18xx_playback2_prepare(chip, substream);
}
return -EINVAL;
}
static int snd_es18xx_playback_trigger(snd_pcm_substream_t *substream,
int cmd)
{
es18xx_t *chip = snd_pcm_substream_chip(substream);
switch (substream->number) {
case 0:
if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
return snd_es18xx_playback1_trigger(chip, substream, cmd);
case 1:
else
return snd_es18xx_playback2_trigger(chip, substream, cmd);
}
return -EINVAL;
}
static void snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
......@@ -798,19 +793,17 @@ static snd_pcm_uframes_t snd_es18xx_playback_pointer(snd_pcm_substream_t * subst
es18xx_t *chip = snd_pcm_substream_chip(substream);
int pos;
switch (substream->number) {
case 0:
if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
if (!(chip->active & DAC2))
return 0;
pos = chip->dma2_size - snd_dma_residue(chip->dma2);
return pos >> chip->dma2_shift;
case 1:
} else {
if (!(chip->active & DAC1))
return 0;
pos = chip->dma1_size - snd_dma_residue(chip->dma1);
return pos >> chip->dma1_shift;
}
return 0;
}
static snd_pcm_uframes_t snd_es18xx_capture_pointer(snd_pcm_substream_t * substream)
......@@ -827,6 +820,7 @@ static snd_pcm_uframes_t snd_es18xx_capture_pointer(snd_pcm_substream_t * substr
static snd_pcm_hardware_t snd_es18xx_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
......@@ -846,6 +840,7 @@ static snd_pcm_hardware_t snd_es18xx_playback =
static snd_pcm_hardware_t snd_es18xx_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
......@@ -867,20 +862,17 @@ static int snd_es18xx_playback_open(snd_pcm_substream_t * substream)
snd_pcm_runtime_t *runtime = substream->runtime;
es18xx_t *chip = snd_pcm_substream_chip(substream);
switch (substream->number) {
case 0:
if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
if ((chip->caps & ES18XX_DUPLEX_MONO) &&
chip->capture_a_substream &&
chip->capture_a_substream->runtime->channels != 1)
return -EAGAIN;
chip->playback_a_substream = substream;
break;
case 1:
} else if (substream->number <= 1) {
if (chip->capture_a_substream)
return -EAGAIN;
chip->playback_b_substream = substream;
break;
default:
} else {
snd_BUG();
return -EINVAL;
}
......@@ -912,17 +904,10 @@ static int snd_es18xx_playback_close(snd_pcm_substream_t * substream)
{
es18xx_t *chip = snd_pcm_substream_chip(substream);
switch (substream->number) {
case 0:
if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
chip->playback_a_substream = NULL;
break;
case 1:
else
chip->playback_b_substream = NULL;
break;
default:
snd_BUG();
return -EINVAL;
}
snd_pcm_lib_free_pages(substream);
return 0;
......@@ -1544,6 +1529,9 @@ static int __init snd_es18xx_probe(es18xx_t *chip)
snd_printd("[0x%lx] ESS%x chip found\n", chip->port, chip->version);
if (chip->dma1 == chip->dma2)
chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME);
return snd_es18xx_initialize(chip);
}
......@@ -1600,6 +1588,8 @@ int __init snd_es18xx_pcm(es18xx_t *chip, int device, snd_pcm_t ** rpcm)
pcm->info_flags = 0;
if (chip->caps & ES18XX_DUPLEX_SAME)
pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
if (! (chip->caps & ES18XX_PCM2))
pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
sprintf(pcm->name, "ESS AudioDrive ES%x", chip->version);
chip->pcm = pcm;
......@@ -1709,7 +1699,7 @@ static int snd_es18xx_free(es18xx_t *chip)
disable_dma(chip->dma1);
free_dma(chip->dma1);
}
if (chip->dma2 >= 0) {
if (chip->dma2 >= 0 && chip->dma1 != chip->dma2) {
disable_dma(chip->dma2);
free_dma(chip->dma2);
}
......@@ -1773,7 +1763,7 @@ static int __init snd_es18xx_new_device(snd_card_t * card,
}
chip->dma1 = dma1;
if (request_dma(dma2, "ES18xx DMA 2")) {
if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) {
snd_es18xx_free(chip);
printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2);
return -EBUSY;
......@@ -2181,10 +2171,16 @@ static int __init snd_audiodrive_probe(int dev)
#endif
sprintf(card->driver, "ES%x", chip->version);
sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version);
sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d",
card->shortname,
chip->port,
xirq, xdma1, xdma2);
if (xdma1 != xdma2)
sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d",
card->shortname,
chip->port,
xirq, xdma1, xdma2);
else
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
card->shortname,
chip->port,
xirq, xdma1);
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
return err;
......
......@@ -182,6 +182,8 @@ static struct isapnp_card_id snd_sb16_pnpids[] __devinitdata = {
/* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0024,0x0031),
/* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0025,0x0031),
/* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0026,0x0031),
/* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0027,0x0031),
......@@ -664,7 +666,7 @@ static int __init alsa_card_sb16_setup(char *str)
{
static unsigned __initdata nr_dev = 0;
int __attribute__ ((__unused__)) pnp = INT_MAX;
int __attribute__ ((__unused__)) csp = INT_MAX;
int __attribute__ ((__unused__)) xcsp = INT_MAX;
if (nr_dev >= SNDRV_CARDS)
return 0;
......@@ -681,7 +683,7 @@ static int __init alsa_card_sb16_setup(char *str)
get_option(&str,&mic_agc[nr_dev]) == 2
#ifdef CONFIG_SND_SB16_CSP
&&
get_option(&str,&csp[nr_dev]) == 2
get_option(&str,&xcsp) == 2
#endif
#ifdef SNDRV_SBAWE_EMU8000
&&
......@@ -694,8 +696,8 @@ static int __init alsa_card_sb16_setup(char *str)
isapnp[nr_dev] = pnp;
#endif
#ifdef CONFIG_SND_SB16_CSP
if (csp != INT_MAX)
csp[nr_dev] = csp;
if (xcsp != INT_MAX)
csp[nr_dev] = xcsp;
#endif
nr_dev++;
return 1;
......
......@@ -10,6 +10,12 @@
* Note: 16-bit wide is assigned to first direction which made request.
* With full duplex - playback is preferred with abstract layer.
*
* Note: Some chip revisions have hardware bug. Changing capture
* channel from full-duplex 8bit DMA to 16bit DMA will block
* 16bit DMA transfers from DSP chip (capture) until 8bit transfer
* to DSP chip (playback) starts. This bug can be avoided with
* "16bit DMA Allocation" setting set to Playback or Capture.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......
This diff is collapsed.
......@@ -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.
......
This diff is collapsed.
......@@ -43,4 +43,7 @@
#define AC97_ID_CS4299 0x43525930
#define AC97_ID_CS4201 0x43525948
#define AC97_ID_CS4205 0x43525958
#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
......@@ -37,6 +37,20 @@
* Chip specific initialization
*/
int patch_yamaha_ymf753(ac97_t * 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.
The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48.
By default, no output pin is selected, and the S/PDIF signal is not output.
There is also a bit to mute S/PDIF output in a vendor-specific register.
*/
ac97->caps |= AC97_BC_BASS_TREBLE;
ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */
return 0;
}
int patch_wolfson00(ac97_t * ac97)
{
/* This sequence is suspect because it was designed for
......
......@@ -22,6 +22,7 @@
*
*/
int patch_yamaha_ymf753(ac97_t * ac97);
int patch_wolfson00(ac97_t * ac97);
int patch_wolfson03(ac97_t * ac97);
int patch_wolfson04(ac97_t * ac97);
......
......@@ -529,7 +529,8 @@ static int snd_ali_reset_5451(ali_t *codec)
udelay(5000);
}
return -1;
snd_printk(KERN_WARNING "ali5451: reset time out\n");
return 0;
}
#ifdef CODEC_RESET
......@@ -1209,59 +1210,64 @@ static int snd_ali_trigger(snd_pcm_substream_t *substream,
unsigned int what, whati, capture_flag;
snd_ali_voice_t *pvoice = NULL, *evoice = NULL;
unsigned int val;
int do_start;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
do_start = 1; break;
case SNDRV_PCM_TRIGGER_STOP:
{
what = whati = capture_flag = 0;
s = substream;
do {
if ((ali_t *) _snd_pcm_chip(s->pcm) == codec) {
pvoice = (snd_ali_voice_t *) s->runtime->private_data;
evoice = pvoice->extra;
what |= 1 << (pvoice->number & 0x1f);
if (evoice == NULL) {
whati |= 1 << (pvoice->number & 0x1f);
} else {
whati |= 1 << (evoice->number & 0x1f);
what |= 1 << (evoice->number & 0x1f);
}
if (cmd == SNDRV_PCM_TRIGGER_START) {
pvoice->running = 1;
if (evoice != NULL)
evoice->running = 1;
}
snd_pcm_trigger_done(s, substream);
if (pvoice->mode)
capture_flag = 1;
case SNDRV_PCM_TRIGGER_SUSPEND:
do_start = 0; break;
default:
return -EINVAL;
}
what = whati = capture_flag = 0;
s = substream;
do {
if ((ali_t *) _snd_pcm_chip(s->pcm) == codec) {
pvoice = (snd_ali_voice_t *) s->runtime->private_data;
evoice = pvoice->extra;
what |= 1 << (pvoice->number & 0x1f);
if (evoice == NULL) {
whati |= 1 << (pvoice->number & 0x1f);
} else {
whati |= 1 << (evoice->number & 0x1f);
what |= 1 << (evoice->number & 0x1f);
}
s = s->link_next;
} while (s != substream);
spin_lock(&codec->reg_lock);
if (cmd == SNDRV_PCM_TRIGGER_STOP) {
outl(what, ALI_REG(codec, ALI_STOP));
pvoice->running = 0;
if (evoice != NULL)
evoice->running = 0;
}
val = inl(ALI_REG(codec, ALI_AINTEN));
if (cmd == SNDRV_PCM_TRIGGER_START) {
val |= whati;
} else {
val &= ~whati;
}
outl(val, ALI_REG(codec, ALI_AINTEN));
if (cmd == SNDRV_PCM_TRIGGER_START) {
outl(what, ALI_REG(codec, ALI_START));
if (do_start) {
pvoice->running = 1;
if (evoice != NULL)
evoice->running = 1;
} else {
pvoice->running = 0;
if (evoice != NULL)
evoice->running = 0;
}
snd_pcm_trigger_done(s, substream);
if (pvoice->mode)
capture_flag = 1;
}
snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati);
spin_unlock(&codec->reg_lock);
break;
s = s->link_next;
} while (s != substream);
spin_lock(&codec->reg_lock);
if (! do_start) {
outl(what, ALI_REG(codec, ALI_STOP));
}
default:
return -EINVAL;
val = inl(ALI_REG(codec, ALI_AINTEN));
if (do_start) {
val |= whati;
} else {
val &= ~whati;
}
outl(val, ALI_REG(codec, ALI_AINTEN));
if (do_start) {
outl(what, ALI_REG(codec, ALI_START));
}
snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati);
spin_unlock(&codec->reg_lock);
return 0;
}
......@@ -1543,7 +1549,9 @@ static snd_pcm_hardware_t snd_ali_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_SYNC_START),
.formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
......@@ -1567,7 +1575,9 @@ static snd_pcm_hardware_t snd_ali_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_SYNC_START),
.formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
......@@ -1999,14 +2009,10 @@ static int snd_ali_chip_init(ali_t *codec)
if (codec->revision == ALI_5451_V02) {
pci_dev = codec->pci_m1533;
if (pci_dev == NULL)
return -1;
pci_read_config_byte(pci_dev, 0x59, &temp);
pci_dev = pci_find_device(0x10b9,0x7101, pci_dev);
if (pci_dev == NULL)
return -1;
pci_read_config_byte(pci_dev,0xb8,&temp);
pci_dev = codec->pci_m7101;
pci_read_config_byte(pci_dev, 0xb8, &temp);
temp |= 1 << 6;
pci_write_config_byte(pci_dev, 0xB8, temp);
}
......@@ -2139,10 +2145,22 @@ static int __devinit snd_ali_create(snd_card_t * card,
codec->chregs.data.aint = 0x00;
codec->chregs.data.ainten = 0x00;
pci_dev = pci_find_device(0x10b9,0x1533, pci_dev);
/* M1533: southbridge */
pci_dev = pci_find_device(0x10b9, 0x1533, NULL);
codec->pci_m1533 = pci_dev;
pci_dev = pci_find_device(0x10b9,0x7101, pci_dev);
if (! codec->pci_m1533) {
snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
snd_ali_free(codec);
return -ENODEV;
}
/* M7101: power management */
pci_dev = pci_find_device(0x10b9, 0x7101, NULL);
codec->pci_m7101 = pci_dev;
if (! codec->pci_m7101) {
snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
snd_ali_free(codec);
return -ENODEV;
}
snd_ali_printk("snd_device_new is called.\n");
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
......
......@@ -2,6 +2,7 @@
* card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
* Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>,
* Jaroslav Kysela <perex@suse.cz>
* Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
*
* Framework borrowed from Massimo Piccioni's card-als100.c.
*
......@@ -11,6 +12,9 @@
* bought an ALS4000 based soundcard, I was forced to base this driver
* on reverse engineering.
*
* Note: this is no longer true. Pretty verbose chip docu (ALS4000a.PDF)
* can be found on the ALSA web site.
*
* The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an
* ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport
* interface. These subsystems can be mapped into ISA io-port space,
......@@ -23,11 +27,21 @@
*
* The ALS4000 can do real full duplex playback/capture.
*
* BUGS
* The box suggests there is some support for 3D sound, but I did not
* investigate this yet.
*
* FMDAC:
* - 0x4f -> port 0x14
* - port 0x15 |= 1
*
* Enable/disable 3D sound:
* - 0x50 -> port 0x14
* - change bit 6 (0x40) of port 0x15
*
* Set QSound:
* - 0xdb -> port 0x14
* - set port 0x15:
* 0x3e (mode 3), 0x3c (mode 2), 0x3a (mode 1), 0x38 (mode 0)
*
* Set KSound:
* - value -> some port 0x0c0d
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -256,11 +270,18 @@ static int snd_als4000_playback_prepare(snd_pcm_substream_t *substream)
count >>=1;
count--;
/* FIXME: from second playback on, there's a lot more clicks and pops
* involved here than on first playback. Fiddling with
* tons of different settings didn't help (DMA, speaker on/off,
* reordering, ...). Something seems to get enabled on playback
* that I haven't found out how to disable again, which then causes
* the switching pops to reach the speakers the next time here. */
spin_lock_irqsave(&chip->reg_lock, flags);
snd_als4000_set_rate(chip, runtime->rate);
snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
/* SPEAKER_ON not needed, since dma_on seems to also enable speaker */
/* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */
snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
snd_sbdsp_command(chip, playback_cmd(chip).format);
snd_sbdsp_command(chip, count);
......@@ -359,9 +380,9 @@ static void snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock_irqrestore(&chip->mixer_lock, flags);
if (sb_status & SB_IRQTYPE_8BIT)
inb(SBP(chip, DATA_AVAIL));
snd_sb_ack_8bit(chip);
if (sb_status & SB_IRQTYPE_16BIT)
inb(SBP(chip, DATA_AVAIL_16));
snd_sb_ack_16bit(chip);
if (sb_status & SB_IRQTYPE_MPUIN)
inb(chip->mpu_port);
if (sb_status & 0x20)
......@@ -547,14 +568,14 @@ static void __devinit snd_als4000_configure(sb_t *chip)
spin_unlock_irqrestore(&chip->reg_lock,flags);
}
static void snd_card_als4k_free( snd_card_t *card )
static void snd_card_als4000_free( snd_card_t *card )
{
snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data;
/* make sure that interrupts are disabled */
snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);
}
static int __devinit snd_card_als4k_probe(struct pci_dev *pci,
static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
static int dev;
......@@ -608,7 +629,7 @@ static int __devinit snd_card_als4k_probe(struct pci_dev *pci,
acard = (snd_card_als4000_t *)card->private_data;
acard->gcr = gcr;
card->private_free = snd_card_als4k_free;
card->private_free = snd_card_als4000_free;
if ((err = snd_sbdsp_create(card,
gcr + 0x10,
......@@ -672,7 +693,7 @@ static int __devinit snd_card_als4k_probe(struct pci_dev *pci,
return 0;
}
static void __devexit snd_card_als4k_remove(struct pci_dev *pci)
static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
pci_set_drvdata(pci, NULL);
......@@ -681,11 +702,11 @@ static void __devexit snd_card_als4k_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ALS4000",
.id_table = snd_als4000_ids,
.probe = snd_card_als4k_probe,
.remove = __devexit_p(snd_card_als4k_remove),
.probe = snd_card_als4000_probe,
.remove = __devexit_p(snd_card_als4000_remove),
};
static int __init alsa_card_als4k_init(void)
static int __init alsa_card_als4000_init(void)
{
int err;
......@@ -698,13 +719,13 @@ static int __init alsa_card_als4k_init(void)
return 0;
}
static void __exit alsa_card_als4k_exit(void)
static void __exit alsa_card_als4000_exit(void)
{
pci_unregister_driver(&driver);
}
module_init(alsa_card_als4k_init)
module_exit(alsa_card_als4k_exit)
module_init(alsa_card_als4000_init)
module_exit(alsa_card_als4000_exit)
#ifndef MODULE
......
This diff is collapsed.
......@@ -735,12 +735,14 @@ static int snd_cs4281_trigger(snd_pcm_substream_t *substream, int cmd)
dma->valFCR &= ~BA0_FCR_FEN;
break;
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
snd_cs4281_pokeBA0(chip, dma->regDMR, dma->valDMR & ~BA0_DMR_DMA);
dma->valDMR |= BA0_DMR_DMA;
dma->valDCR &= ~BA0_DCR_MSK;
dma->valFCR |= BA0_FCR_FEN;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
dma->valDMR &= ~(BA0_DMR_DMA|BA0_DMR_POLL);
dma->valDCR |= BA0_DCR_MSK;
dma->valFCR &= ~BA0_FCR_FEN;
......@@ -900,6 +902,7 @@ static snd_pcm_hardware_t snd_cs4281_playback =
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_SYNC_START),
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
......@@ -925,6 +928,7 @@ static snd_pcm_hardware_t snd_cs4281_capture =
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_SYNC_START),
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
......@@ -1804,7 +1808,7 @@ static int snd_cs4281_midi_output_open(snd_rawmidi_substream_t * substream)
spin_lock_irqsave(&chip->reg_lock, flags);
chip->uartm |= CS4281_MODE_OUTPUT;
chip->midcr |= BA0_MIDCR_TXE;
chip->midi_input = substream;
chip->midi_output = substream;
if (!(chip->uartm & CS4281_MODE_INPUT)) {
snd_cs4281_midi_reset(chip);
} else {
......
This diff is collapsed.
......@@ -152,6 +152,7 @@ dsp_scb_descriptor_t * cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * s
dsp_scb_descriptor_t * parent_scb,
int scb_child_type);
dsp_scb_descriptor_t * cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
int sample_rate,
u16 src_buffer_addr,
u16 src_delay_buffer_addr,u32 dest,
dsp_scb_descriptor_t * parent_scb,
......@@ -202,8 +203,6 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sa
int pcm_channel_id);
void cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,
pcm_channel_descriptor_t * pcm_channel);
void cs46xx_dsp_set_src_sample_rate(cs46xx_t * chip,dsp_scb_descriptor_t * src,
u32 rate);
int cs46xx_dsp_pcm_unlink (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
int cs46xx_dsp_pcm_link (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
dsp_scb_descriptor_t * cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
......@@ -217,6 +216,6 @@ int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
int period_size);
int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
int period_size);
int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 right,u16 left);
int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 right,u16 left);
int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 left,u16 right);
int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 left,u16 right);
#endif /* __CS46XX_LIB_H__ */
This diff is collapsed.
......@@ -185,6 +185,25 @@ typedef enum {
#define SP_SPDOUT_CONTROL 0x804D
#define SP_SPDOUT_CSUV 0x808E
static inline u8 _wrap_all_bits (u8 val) {
u8 wrapped;
/* wrap all 8 bits */
wrapped =
((val & 0x1 ) << 7) |
((val & 0x2 ) << 5) |
((val & 0x4 ) << 3) |
((val & 0x8 ) << 1) |
((val & 0x10) >> 1) |
((val & 0x20) >> 3) |
((val & 0x40) >> 5) |
((val & 0x80) >> 7);
return wrapped;
}
static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t * scb)
{
/* update nextSCB and subListPtr in SCB */
......@@ -195,12 +214,11 @@ static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descripto
}
static inline void cs46xx_dsp_scb_set_volume (cs46xx_t * chip,dsp_scb_descriptor_t * scb,
u16 right,u16 left) {
unsigned int val = ((0xffff - right) << 16 | (0xffff - left));
u16 left,u16 right) {
unsigned int val = ((0xffff - left) << 16 | (0xffff - right));
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
}
#endif /* __DSP_SPOS_H__ */
#endif /* CONFIG_SND_CS46XX_NEW_DSP */
This diff is collapsed.
......@@ -199,7 +199,7 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
.name = "EMU10K1/Audigy",
.name = "EMU10K1_Audigy",
.id_table = snd_emu10k1_ids,
.probe = snd_card_emu10k1_probe,
.remove = __devexit_p(snd_card_emu10k1_remove),
......
This diff is collapsed.
......@@ -985,7 +985,7 @@ static void snd_es1938_free_pcm(snd_pcm_t *pcm)
snd_pcm_lib_preallocate_free_for_all(pcm);
}
static int __init snd_es1938_new_pcm(es1938_t *chip, int device, snd_pcm_t ** rpcm)
static int __devinit snd_es1938_new_pcm(es1938_t *chip, int device, snd_pcm_t ** rpcm)
{
snd_pcm_t *pcm;
int err;
......@@ -1364,7 +1364,7 @@ static int snd_es1938_dev_free(snd_device_t *device)
return snd_es1938_free(chip);
}
static int __init snd_es1938_create(snd_card_t * card,
static int __devinit snd_es1938_create(snd_card_t * card,
struct pci_dev * pci,
unsigned long dma1size,
unsigned long dma2size,
......@@ -1541,7 +1541,7 @@ static void snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#define ES1938_DMA_SIZE 64
static int __init snd_es1938_mixer(snd_pcm_t *pcm)
static int __devinit snd_es1938_mixer(snd_pcm_t *pcm)
{
snd_card_t *card;
es1938_t *chip;
......
This diff is collapsed.
This diff is collapsed.
......@@ -5,7 +5,7 @@
export-objs := ice1712.o
snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o
snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o amp.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o
This diff is collapsed.
/*
* ALSA driver for ICEnsemble VT1724 (Envy24HT)
*
* Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
*
* Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <sound/driver.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "ice1712.h"
#include "amp.h"
static int __devinit snd_vt1724_amp_init(ice1712_t *ice)
{
/* only use basic functionality for now */
ice->num_total_dacs = 2; /* only PSDOUT0 is connected */
return 0;
}
/* entry point */
struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
{
VT1724_SUBDEVICE_AUDIO2000,
"AMP Ltd AUDIO2000",
snd_vt1724_amp_init,
},
{ } /* terminator */
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -218,6 +218,11 @@ struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
"Hoontech SoundTrack Audio DSP24",
snd_ice1712_hoontech_init,
},
{
ICE1712_SUBDEVICE_STDSP24_MEDIA7_1,
"Hoontech STA DSP24 Media 7.1",
snd_ice1712_hoontech_init,
},
{ } /* terminator */
};
......@@ -27,6 +27,7 @@
#define HOONTECH_DEVICE_DESC "{Hoontech SoundTrack DSP 24},"
#define ICE1712_SUBDEVICE_STDSP24 0x12141217 /* Hoontech SoundTrack Audio DSP 24 */
#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -178,7 +178,7 @@ void snd_hammerfall_free_buffer (struct pci_dev *pcidev, void *addr)
printk ("Hammerfall memory allocator: unknown buffer address or PCI device ID");
}
static void hammerfall_free_buffers (void)
static void __exit hammerfall_free_buffers (void)
{
int i;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -12,6 +12,5 @@ obj-$(CONFIG_SND_EMU10K1) += snd-util-mem.o
obj-$(CONFIG_SND_TRIDENT) += snd-util-mem.o
ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
obj-$(CONFIG_SND_SBAWE) += snd-util-mem.o
obj-$(CONFIG_SND) += emux/
endif
obj-$(CONFIG_SND) += emux/
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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