Commit e2094b53 authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Jaroslav Kysela

[PATCH] ALSA update [7/12] - 2002/08/26

  - AC'97 codec
    - added ac97_can_amap() condition
    - removed powerup/powerdown sequence when sample rate is changed
    - added ac97_is_rev22 check function
    - added AC97_EI_* defines
    - available rates are in array
  - CS46xx
    - improved the SCB link mechanism
    - SMP deadlock should have been fixed now
  - OSS mixer emulation
    - added the proc interface for the configuration of OSS mixer volumes
  - rawmidi midlevel
    - removed unused snd_rawmidi_transmit_reset and snd_rawmidi_receive_reset functions
  - USB MIDI driver
    - integration of USB MIDI driver into USB audio driver by Clemens
  - intel8x0 - the big intel8x0 driver update
    - added support for ICH4
    - rewrited I/O (the third AC'97 codec registers are available only through memory)
    - code cleanups
    - ALI5455 specific code
    - added proc interface
  - VIA686, VIA8233
    - set the max periods to 128
parent a2755d79
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */ #define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */
#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */ #define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */
#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */ #define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */
#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR DAC Rate */ #define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */
#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */ #define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */
#define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */ #define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */
#define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */ #define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */
...@@ -68,25 +68,43 @@ ...@@ -68,25 +68,43 @@
#define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */ #define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */
#define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */ #define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */
/* extended audio ID bit defines */
#define AC97_EI_VRA 0x0001 /* Variable bit rate supported */
#define AC97_EI_DRA 0x0002 /* Double rate supported */
#define AC97_EI_SPDIF 0x0004 /* S/PDIF out supported */
#define AC97_EI_VRM 0x0008 /* Variable bit rate supported for MIC */
#define AC97_EI_DACS_SLOT_MASK 0x0030 /* DACs slot assignment */
#define AC97_EI_DACS_SLOT_SHIFT 4
#define AC97_EI_CDAC 0x0040 /* PCM Center DAC available */
#define AC97_EI_SDAC 0x0080 /* PCM Surround DACs available */
#define AC97_EI_LDAC 0x0100 /* PCM LFE DAC available */
#define AC97_EI_AMAP 0x0200 /* indicates optional slot/DAC mapping based on codec ID */
#define AC97_EI_REV_MASK 0x0c00 /* AC'97 revision mask */
#define AC97_EI_REV_22 0x0100 /* AC'97 revision 2.2 */
#define AC97_EI_REV_SHIFT 8
#define AC97_EI_ADDR_MASK 0xc000 /* physical codec ID (address) */
#define AC97_EI_ADDR_SHIFT 14
/* extended audio status and control bit defines */ /* extended audio status and control bit defines */
#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */ #define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */ #define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
#define AC97_EA_SPDIF 0x0004 /* S/PDIF Enable bit */ #define AC97_EA_SPDIF 0x0004 /* S/PDIF out enable bit */
#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */ #define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
#define AC97_EA_SPSA_SLOT_MASK 0x0030 /* Mask for slot assignment bits */
#define AC97_EA_SPSA_SLOT_SHIFT 4
#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */ #define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
#define AC97_EA_SDAC 0x0040 /* PCM Surround DACs are ready (Read only) */ #define AC97_EA_SDAC 0x0080 /* PCM Surround DACs are ready (Read only) */
#define AC97_EA_LDAC 0x0080 /* PCM LFE DAC is ready (Read only) */ #define AC97_EA_LDAC 0x0100 /* PCM LFE DAC is ready (Read only) */
#define AC97_EA_MDAC 0x0100 /* MIC ADC is ready (Read only) */ #define AC97_EA_MDAC 0x0200 /* MIC ADC is ready (Read only) */
#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */ #define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */ #define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */ #define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */ #define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */ #define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
#define AC97_EA_SLOT_MASK 0xffcf /* Mask for slot assignment bits */
#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
/* S/PDIF control bit defines */ /* S/PDIF control bit defines */
#define AC97_SC_PRO 0x0001 /* Professional status */ #define AC97_SC_PRO 0x0001 /* Professional status */
...@@ -145,8 +163,16 @@ ...@@ -145,8 +163,16 @@
#define AC97_CS_SPDIF (1<<2) /* Cirrus Logic uses funky SPDIF */ #define AC97_CS_SPDIF (1<<2) /* Cirrus Logic uses funky SPDIF */
#define AC97_CX_SPDIF (1<<3) /* Conexant's spdif interface */ #define AC97_CX_SPDIF (1<<3) /* Conexant's spdif interface */
/* /* rates indexes */
#define AC97_RATES_FRONT_DAC 0
#define AC97_RATES_SURR_DAC 1
#define AC97_RATES_LFE_DAC 2
#define AC97_RATES_ADC 3
#define AC97_RATES_MIC_ADC 4
#define AC97_RATES_SPDIF 5
/*
*
*/ */
typedef struct _snd_ac97 ac97_t; typedef struct _snd_ac97 ac97_t;
...@@ -172,11 +198,7 @@ struct _snd_ac97 { ...@@ -172,11 +198,7 @@ struct _snd_ac97 {
unsigned int scaps; /* driver capabilities */ unsigned int scaps; /* driver capabilities */
unsigned int flags; /* specific code */ unsigned int flags; /* specific code */
unsigned int clock; /* AC'97 clock (usually 48000Hz) */ unsigned int clock; /* AC'97 clock (usually 48000Hz) */
unsigned int rates_front_dac; unsigned int rates[6]; /* see AC97_RATES_* defines */
unsigned int rates_surr_dac;
unsigned int rates_lfe_dac;
unsigned int rates_adc;
unsigned int rates_mic_adc;
unsigned int spdif_status; unsigned int spdif_status;
unsigned short regs[0x80]; /* register cache */ unsigned short regs[0x80]; /* register cache */
unsigned int limited_regs; /* allow limited registers only */ unsigned int limited_regs; /* allow limited registers only */
...@@ -192,6 +214,17 @@ struct _snd_ac97 { ...@@ -192,6 +214,17 @@ struct _snd_ac97 {
} spec; } spec;
}; };
/* conditions */
static inline int ac97_is_rev22(ac97_t * ac97)
{
return (ac97->ext_id & AC97_EI_REV_MASK) == AC97_EI_REV_22;
}
static inline int ac97_can_amap(ac97_t * ac97)
{
return (ac97->ext_id & AC97_EI_AMAP) != 0;
}
/* functions */
int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97); int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97);
void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value); void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value);
......
...@@ -1817,6 +1817,8 @@ struct _snd_cs46xx { ...@@ -1817,6 +1817,8 @@ struct _snd_cs46xx {
int current_gpio; int current_gpio;
#endif #endif
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
struct semaphore spos_mutex;
dsp_spos_instance_t * dsp_spos_instance; dsp_spos_instance_t * dsp_spos_instance;
#else /* for compatibility */ #else /* for compatibility */
cs46xx_pcm_t *playback_pcm; cs46xx_pcm_t *playback_pcm;
......
...@@ -109,6 +109,7 @@ typedef struct _dsp_scb_descriptor_t { ...@@ -109,6 +109,7 @@ typedef struct _dsp_scb_descriptor_t {
snd_info_entry_t *proc_info; snd_info_entry_t *proc_info;
int ref_count; int ref_count;
spinlock_t lock;
int deleted; int deleted;
} dsp_scb_descriptor_t; } dsp_scb_descriptor_t;
...@@ -141,8 +142,6 @@ typedef struct _dsp_spos_instance_t { ...@@ -141,8 +142,6 @@ typedef struct _dsp_spos_instance_t {
segment_desc_t code; segment_desc_t code;
/* PCM playback */ /* PCM playback */
struct semaphore pcm_mutex;
dsp_scb_descriptor_t * master_mix_scb; dsp_scb_descriptor_t * master_mix_scb;
int npcm_channels; int npcm_channels;
int nsrc_scb; int nsrc_scb;
...@@ -162,7 +161,6 @@ typedef struct _dsp_spos_instance_t { ...@@ -162,7 +161,6 @@ typedef struct _dsp_spos_instance_t {
snd_info_entry_t * proc_sample_dump_info_entry; snd_info_entry_t * proc_sample_dump_info_entry;
/* SCB's descriptors */ /* SCB's descriptors */
struct semaphore scb_mutex;
int nscb; int nscb;
int scb_highest_frag_index; int scb_highest_frag_index;
dsp_scb_descriptor_t scbs[DSP_MAX_SCB_DESC]; dsp_scb_descriptor_t scbs[DSP_MAX_SCB_DESC];
......
...@@ -34,6 +34,8 @@ typedef int (*snd_mixer_oss_put_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixe ...@@ -34,6 +34,8 @@ typedef int (*snd_mixer_oss_put_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixe
typedef int (*snd_mixer_oss_get_recsrce_t)(snd_mixer_oss_file_t *fmixer, int *active_index); typedef int (*snd_mixer_oss_get_recsrce_t)(snd_mixer_oss_file_t *fmixer, int *active_index);
typedef int (*snd_mixer_oss_put_recsrce_t)(snd_mixer_oss_file_t *fmixer, int active_index); typedef int (*snd_mixer_oss_put_recsrce_t)(snd_mixer_oss_file_t *fmixer, int active_index);
#define SNDRV_OSS_MAX_MIXERS 32
struct _snd_oss_mixer_slot { struct _snd_oss_mixer_slot {
int number; int number;
int stereo: 1; int stereo: 1;
...@@ -50,12 +52,14 @@ struct _snd_oss_mixer { ...@@ -50,12 +52,14 @@ struct _snd_oss_mixer {
snd_card_t *card; snd_card_t *card;
char id[16]; char id[16];
char name[32]; char name[32];
snd_mixer_oss_slot_t slots[32]; /* OSS mixer slots */ snd_mixer_oss_slot_t slots[SNDRV_OSS_MAX_MIXERS]; /* OSS mixer slots */
unsigned int mask_recsrc; /* exclusive recsrc mask */ unsigned int mask_recsrc; /* exclusive recsrc mask */
snd_mixer_oss_get_recsrce_t get_recsrc; snd_mixer_oss_get_recsrce_t get_recsrc;
snd_mixer_oss_put_recsrce_t put_recsrc; snd_mixer_oss_put_recsrce_t put_recsrc;
void *private_data_recsrc; void *private_data_recsrc;
void (*private_free_recsrc)(snd_mixer_oss_t *mixer); void (*private_free_recsrc)(snd_mixer_oss_t *mixer);
struct semaphore reg_mutex;
snd_info_entry_t *proc_entry;
/* --- */ /* --- */
int oss_recsrc; int oss_recsrc;
}; };
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define MPU401_HW_YMFPCI 14 /* YMF DS-XG PCI */ #define MPU401_HW_YMFPCI 14 /* YMF DS-XG PCI */
#define MPU401_HW_CMIPCI 15 /* CMIPCI MPU-401 UART */ #define MPU401_HW_CMIPCI 15 /* CMIPCI MPU-401 UART */
#define MPU401_HW_ALS4000 16 /* Avance Logic ALS4000 */ #define MPU401_HW_ALS4000 16 /* Avance Logic ALS4000 */
#define MPU401_HW_INTEL8X0 17 /* Intel8x0 driver */
#define MPU401_MODE_BIT_INPUT 0 #define MPU401_MODE_BIT_INPUT 0
#define MPU401_MODE_BIT_OUTPUT 1 #define MPU401_MODE_BIT_OUTPUT 1
......
...@@ -140,9 +140,9 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic) ...@@ -140,9 +140,9 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define snd_usb_audio_t_magic 0xa15a3e01 #define snd_usb_audio_t_magic 0xa15a3e01
#define usb_mixer_elem_info_t_magic 0xa15a3e02 #define usb_mixer_elem_info_t_magic 0xa15a3e02
#define snd_usb_stream_t_magic 0xa15a3e03 #define snd_usb_stream_t_magic 0xa15a3e03
#define usbmidi_t_magic 0xa15a3f01 #define snd_usb_midi_t_magic 0xa15a3f01
#define usbmidi_out_endpoint_t_magic 0xa15a3f02 #define snd_usb_midi_out_endpoint_t_magic 0xa15a3f02
#define usbmidi_in_endpoint_t_magic 0xa15a3f03 #define snd_usb_midi_in_endpoint_t_magic 0xa15a3f03
#else #else
......
/* include/version.h. Generated automatically by configure. */ /* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc3" #define CONFIG_SND_VERSION "0.9.0rc3"
#define CONFIG_SND_DATE " (Wed Aug 21 14:00:18 2002 UTC)" #define CONFIG_SND_DATE " (Mon Aug 26 16:28:35 2002 UTC)"
...@@ -95,6 +95,7 @@ ifeq ($(CONFIG_SND_SB16_CSP),y) ...@@ -95,6 +95,7 @@ ifeq ($(CONFIG_SND_SB16_CSP),y)
obj-$(CONFIG_SND_SB16) += snd-hwdep.o obj-$(CONFIG_SND_SB16) += snd-hwdep.o
obj-$(CONFIG_SND_SBAWE) += snd-hwdep.o obj-$(CONFIG_SND_SBAWE) += snd-hwdep.o
endif endif
obj-$(CONFIG_SND_USB_AUDIO) += snd-pcm.o snd-timer.o snd.o
obj-m := $(sort $(obj-m)) obj-m := $(sort $(obj-m))
......
This diff is collapsed.
...@@ -173,11 +173,11 @@ int snd_pcm_hw_refine(snd_pcm_substream_t *substream, ...@@ -173,11 +173,11 @@ int snd_pcm_hw_refine(snd_pcm_substream_t *substream,
continue; continue;
#ifdef RULES_DEBUG #ifdef RULES_DEBUG
printk("%s = ", snd_pcm_hw_param_names[k]); printk("%s = ", snd_pcm_hw_param_names[k]);
printk("%x -> ", *m); printk("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
#endif #endif
changed = snd_mask_refine(m, constrs_mask(constrs, k)); changed = snd_mask_refine(m, constrs_mask(constrs, k));
#ifdef RULES_DEBUG #ifdef RULES_DEBUG
printk("%x\n", *m); printk("%04x%04x%04x%04x\n", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
#endif #endif
if (changed) if (changed)
params->cmask |= 1 << k; params->cmask |= 1 << k;
......
...@@ -820,11 +820,6 @@ int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control, ...@@ -820,11 +820,6 @@ int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
void snd_rawmidi_receive_reset(snd_rawmidi_substream_t * substream)
{
/* TODO: reset current state */
}
int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count) int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count)
{ {
unsigned long flags; unsigned long flags;
...@@ -969,11 +964,6 @@ static ssize_t snd_rawmidi_read(struct file *file, char *buf, size_t count, loff ...@@ -969,11 +964,6 @@ static ssize_t snd_rawmidi_read(struct file *file, char *buf, size_t count, loff
return result; return result;
} }
void snd_rawmidi_transmit_reset(snd_rawmidi_substream_t * substream)
{
/* TODO: reset current state */
}
int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream) int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream)
{ {
snd_rawmidi_runtime_t *runtime = substream->runtime; snd_rawmidi_runtime_t *runtime = substream->runtime;
...@@ -1564,9 +1554,7 @@ EXPORT_SYMBOL(snd_rawmidi_input_params); ...@@ -1564,9 +1554,7 @@ EXPORT_SYMBOL(snd_rawmidi_input_params);
EXPORT_SYMBOL(snd_rawmidi_drop_output); EXPORT_SYMBOL(snd_rawmidi_drop_output);
EXPORT_SYMBOL(snd_rawmidi_drain_output); EXPORT_SYMBOL(snd_rawmidi_drain_output);
EXPORT_SYMBOL(snd_rawmidi_drain_input); EXPORT_SYMBOL(snd_rawmidi_drain_input);
EXPORT_SYMBOL(snd_rawmidi_receive_reset);
EXPORT_SYMBOL(snd_rawmidi_receive); EXPORT_SYMBOL(snd_rawmidi_receive);
EXPORT_SYMBOL(snd_rawmidi_transmit_reset);
EXPORT_SYMBOL(snd_rawmidi_transmit_empty); EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
EXPORT_SYMBOL(snd_rawmidi_transmit_peek); EXPORT_SYMBOL(snd_rawmidi_transmit_peek);
EXPORT_SYMBOL(snd_rawmidi_transmit_ack); EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
......
...@@ -73,6 +73,7 @@ obj-$(CONFIG_SND_CS46XX) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-mi ...@@ -73,6 +73,7 @@ obj-$(CONFIG_SND_CS46XX) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-mi
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_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_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_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 snd-seq-virmidi.o
obj-m := $(sort $(obj-m)) obj-m := $(sort $(obj-m))
......
...@@ -50,7 +50,6 @@ static void snd_gf1_interrupt_midi_in(snd_gus_card_t * gus) ...@@ -50,7 +50,6 @@ static void snd_gf1_interrupt_midi_in(snd_gus_card_t * gus)
if (stat & 0x10) { /* framing error */ if (stat & 0x10) { /* framing error */
gus->gf1.uart_framing++; gus->gf1.uart_framing++;
spin_unlock_irqrestore(&gus->uart_cmd_lock, flags); spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
snd_rawmidi_receive_reset(gus->midi_substream_input);
continue; continue;
} }
byte = snd_gf1_uart_get(gus); byte = snd_gf1_uart_get(gus);
...@@ -58,7 +57,6 @@ static void snd_gf1_interrupt_midi_in(snd_gus_card_t * gus) ...@@ -58,7 +57,6 @@ static void snd_gf1_interrupt_midi_in(snd_gus_card_t * gus)
snd_rawmidi_receive(gus->midi_substream_input, &byte, 1); snd_rawmidi_receive(gus->midi_substream_input, &byte, 1);
if (stat & 0x20) { if (stat & 0x20) {
gus->gf1.uart_overrun++; gus->gf1.uart_overrun++;
snd_rawmidi_receive_reset(gus->midi_substream_input);
} }
} }
} }
......
...@@ -1501,7 +1501,7 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97) ...@@ -1501,7 +1501,7 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
goto __access_ok; goto __access_ok;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/100); schedule_timeout(HZ/100);
} while (end_time - (signed long)jiffies >= 0); } while (time_after_eq(end_time, jiffies));
snd_printd("AC'97 %d:%d does not respond - RESET [REC_GAIN = 0x%x]\n", ac97->num, ac97->addr, err); snd_printd("AC'97 %d:%d does not respond - RESET [REC_GAIN = 0x%x]\n", ac97->num, ac97->addr, err);
snd_ac97_free(ac97); snd_ac97_free(ac97);
return -ENXIO; return -ENXIO;
...@@ -1536,31 +1536,38 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97) ...@@ -1536,31 +1536,38 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
goto __ready_ok; goto __ready_ok;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/10); schedule_timeout(HZ/10);
} while (end_time - (signed long)jiffies >= 0); } while (time_after_eq(end_time, jiffies));
snd_printk("AC'97 %d:%d analog subsections not ready\n", ac97->num, ac97->addr); snd_printk("AC'97 %d:%d analog subsections not ready\n", ac97->num, ac97->addr);
__ready_ok: __ready_ok:
if (ac97->clock == 0) if (ac97->clock == 0)
ac97->clock = 48000; /* standard value */ ac97->clock = 48000; /* standard value */
ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
if (ac97->ext_id & 0x0189) /* L/R, MIC, SDAC, LDAC VRA support */ if (ac97->ext_id & 0x0189) /* L/R, MIC, SDAC, LDAC VRA support */
snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, ac97->ext_id & 0x0189); snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, ac97->ext_id & 0x0189);
if (ac97->ext_id & 0x0001) { /* VRA support */ if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */
snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, &ac97->rates_front_dac); snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, &ac97->rates[AC97_RATES_FRONT_DAC]);
snd_ac97_determine_rates(ac97, AC97_PCM_LR_ADC_RATE, &ac97->rates_adc); snd_ac97_determine_rates(ac97, AC97_PCM_LR_ADC_RATE, &ac97->rates[AC97_RATES_ADC]);
} else { } else {
ac97->rates_front_dac = SNDRV_PCM_RATE_48000; ac97->rates[AC97_RATES_FRONT_DAC] = SNDRV_PCM_RATE_48000;
ac97->rates_adc = SNDRV_PCM_RATE_48000; ac97->rates[AC97_RATES_ADC] = SNDRV_PCM_RATE_48000;
} }
if (ac97->ext_id & 0x0008) { /* MIC VRA support */ if (ac97->ext_id & AC97_EI_SPDIF) {
snd_ac97_determine_rates(ac97, AC97_PCM_MIC_ADC_RATE, &ac97->rates_mic_adc); /* codec specific code (patch) should override these values */
ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_32000;
}
if (ac97->ext_id & AC97_EI_VRM) { /* MIC VRA support */
snd_ac97_determine_rates(ac97, AC97_PCM_MIC_ADC_RATE, &ac97->rates[AC97_RATES_MIC_ADC]);
} else { } else {
ac97->rates_mic_adc = SNDRV_PCM_RATE_48000; ac97->rates[AC97_RATES_MIC_ADC] = SNDRV_PCM_RATE_48000;
} }
if (ac97->ext_id & 0x0080) { /* SDAC support */ if (ac97->ext_id & AC97_EI_SDAC) { /* SDAC support */
snd_ac97_determine_rates(ac97, AC97_PCM_SURR_DAC_RATE, &ac97->rates_surr_dac); snd_ac97_determine_rates(ac97, AC97_PCM_SURR_DAC_RATE, &ac97->rates[AC97_RATES_SURR_DAC]);
ac97->scaps |= AC97_SCAP_SURROUND_DAC; ac97->scaps |= AC97_SCAP_SURROUND_DAC;
} }
if (ac97->ext_id & 0x0100) { /* LDAC support */ if (ac97->ext_id & AC97_EI_LDAC) { /* LDAC support */
snd_ac97_determine_rates(ac97, AC97_PCM_LFE_DAC_RATE, &ac97->rates_lfe_dac); snd_ac97_determine_rates(ac97, AC97_PCM_LFE_DAC_RATE, &ac97->rates[AC97_RATES_LFE_DAC]);
ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC; ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
} }
/* additional initializations */ /* additional initializations */
...@@ -1849,54 +1856,35 @@ int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate) ...@@ -1849,54 +1856,35 @@ int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate)
{ {
unsigned short mask; unsigned short mask;
unsigned int tmp; unsigned int tmp;
signed long end_time;
switch (reg) { switch (reg) {
case AC97_PCM_MIC_ADC_RATE: case AC97_PCM_MIC_ADC_RATE:
mask = 0x0000; mask = 0x0000;
if ((ac97->regs[AC97_EXTENDED_STATUS] & 0x0008) == 0) /* MIC VRA */ if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRM) == 0) /* MIC VRA */
if (rate != 48000) if (rate != 48000)
return -EINVAL; return -EINVAL;
break; break;
case AC97_PCM_FRONT_DAC_RATE: case AC97_PCM_FRONT_DAC_RATE:
mask = 0x0200; mask = 0x0200;
if ((ac97->regs[AC97_EXTENDED_STATUS] & 0x0001) == 0) /* VRA */ if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRA) == 0) /* VRA */
if (rate != 48000) if (rate != 48000)
return -EINVAL; return -EINVAL;
break; break;
case AC97_PCM_LR_ADC_RATE: case AC97_PCM_LR_ADC_RATE:
mask = 0x0100; mask = 0x0100;
if ((ac97->regs[AC97_EXTENDED_STATUS] & 0x0001) == 0) /* VRA */ if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRA) == 0) /* VRA */
if (rate != 48000) if (rate != 48000)
return -EINVAL; return -EINVAL;
break; break;
case AC97_SPDIF:
return 0;
default: return -EINVAL; default: return -EINVAL;
} }
tmp = ((unsigned int)rate * ac97->clock) / 48000; tmp = ((unsigned int)rate * ac97->clock) / 48000;
if (tmp > 65535) if (tmp > 65535)
return -EINVAL; return -EINVAL;
snd_ac97_update_bits(ac97, AC97_POWERDOWN, mask, mask);
end_time = jiffies + (HZ / 50);
do {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (end_time - (signed long)jiffies >= 0);
snd_ac97_update(ac97, reg, tmp & 0xffff); snd_ac97_update(ac97, reg, tmp & 0xffff);
udelay(10); snd_ac97_read(ac97, reg);
// XXXX update spdif rate here too?
snd_ac97_update_bits(ac97, AC97_POWERDOWN, mask, 0);
end_time = jiffies + (HZ / 50);
do {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (end_time - (signed long)jiffies >= 0);
end_time = jiffies + (HZ / 10);
do {
if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0003) == 0x0003)
break;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (end_time - (signed long)jiffies >= 0);
return 0; return 0;
} }
......
...@@ -166,6 +166,7 @@ int patch_cirrus_spdif(ac97_t * ac97) ...@@ -166,6 +166,7 @@ int patch_cirrus_spdif(ac97_t * ac97)
*/ */
ac97->flags |= AC97_CS_SPDIF; ac97->flags |= AC97_CS_SPDIF;
ac97->rates[AC97_RATES_SPDIF] &= ~SNDRV_PCM_RATE_32000;
ac97->ext_id |= AC97_EA_SPDIF; /* force the detection of spdif */ ac97->ext_id |= AC97_EA_SPDIF; /* force the detection of spdif */
snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080); snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080);
return 0; return 0;
......
This diff is collapsed.
...@@ -28,11 +28,11 @@ ...@@ -28,11 +28,11 @@
* constants * constants
*/ */
#define CS46XX_BA0_SIZE 0x1000 #define CS46XX_BA0_SIZE 0x1000
#define CS46XX_BA1_DATA0_SIZE 0x3000 #define CS46XX_BA1_DATA0_SIZE 0x3000
#define CS46XX_BA1_DATA1_SIZE 0x3800 #define CS46XX_BA1_DATA1_SIZE 0x3800
#define CS46XX_BA1_PRG_SIZE 0x7000 #define CS46XX_BA1_PRG_SIZE 0x7000
#define CS46XX_BA1_REG_SIZE 0x0100 #define CS46XX_BA1_REG_SIZE 0x0100
#define CS46XX_PERIOD_SIZE 2048 #define CS46XX_PERIOD_SIZE 2048
...@@ -84,7 +84,7 @@ static inline unsigned int snd_cs46xx_peekBA0(cs46xx_t *chip, unsigned long offs ...@@ -84,7 +84,7 @@ static inline unsigned int snd_cs46xx_peekBA0(cs46xx_t *chip, unsigned long offs
} }
dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip); dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip);
void cs46xx_dsp_spos_destroy (dsp_spos_instance_t * instance); void cs46xx_dsp_spos_destroy (cs46xx_t * chip);
int cs46xx_dsp_load_module (cs46xx_t * chip,dsp_module_desc_t * module); int cs46xx_dsp_load_module (cs46xx_t * chip,dsp_module_desc_t * module);
symbol_entry_t * cs46xx_dsp_lookup_symbol (cs46xx_t * chip,char * symbol_name,int symbol_type); symbol_entry_t * cs46xx_dsp_lookup_symbol (cs46xx_t * chip,char * symbol_name,int symbol_type);
symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip,u32 address,int symbol_type); symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip,u32 address,int symbol_type);
......
...@@ -222,16 +222,13 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip) ...@@ -222,16 +222,13 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
return NULL; return NULL;
memset(ins, 0, sizeof(*ins)); memset(ins, 0, sizeof(*ins));
init_MUTEX(&ins->scb_mutex);
init_MUTEX(&ins->pcm_mutex);
/* better to use vmalloc for this big table */ /* better to use vmalloc for this big table */
ins->symbol_table.nsymbols = 0; ins->symbol_table.nsymbols = 0;
ins->symbol_table.symbols = vmalloc(sizeof(symbol_entry_t) * DSP_MAX_SYMBOLS); ins->symbol_table.symbols = vmalloc(sizeof(symbol_entry_t) * DSP_MAX_SYMBOLS);
ins->symbol_table.highest_frag_index = 0; ins->symbol_table.highest_frag_index = 0;
if (ins->symbol_table.symbols == NULL) { if (ins->symbol_table.symbols == NULL) {
cs46xx_dsp_spos_destroy(ins); cs46xx_dsp_spos_destroy(chip);
return NULL; return NULL;
} }
...@@ -240,7 +237,7 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip) ...@@ -240,7 +237,7 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL);
if (ins->code.data == NULL) { if (ins->code.data == NULL) {
cs46xx_dsp_spos_destroy(ins); cs46xx_dsp_spos_destroy(chip);
return NULL; return NULL;
} }
...@@ -251,7 +248,7 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip) ...@@ -251,7 +248,7 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
ins->modules = kmalloc(sizeof(dsp_module_desc_t) * DSP_MAX_MODULES, GFP_KERNEL); ins->modules = kmalloc(sizeof(dsp_module_desc_t) * DSP_MAX_MODULES, GFP_KERNEL);
if (ins->modules == NULL) { if (ins->modules == NULL) {
cs46xx_dsp_spos_destroy(ins); cs46xx_dsp_spos_destroy(chip);
return NULL; return NULL;
} }
...@@ -265,19 +262,19 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip) ...@@ -265,19 +262,19 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
return ins; return ins;
} }
void cs46xx_dsp_spos_destroy (dsp_spos_instance_t * ins) void cs46xx_dsp_spos_destroy (cs46xx_t * chip)
{ {
int i; int i;
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
snd_assert(ins != NULL, return); snd_assert(ins != NULL, return);
down(&ins->scb_mutex); down(&chip->spos_mutex);
for (i = 0; i < ins->nscb; ++i) { for (i = 0; i < ins->nscb; ++i) {
if (ins->scbs[i].deleted) continue; if (ins->scbs[i].deleted) continue;
cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
} }
up(&ins->scb_mutex);
if (ins->code.data) if (ins->code.data)
kfree(ins->code.data); kfree(ins->code.data);
...@@ -286,6 +283,7 @@ void cs46xx_dsp_spos_destroy (dsp_spos_instance_t * ins) ...@@ -286,6 +283,7 @@ void cs46xx_dsp_spos_destroy (dsp_spos_instance_t * ins)
if (ins->modules) if (ins->modules)
kfree(ins->modules); kfree(ins->modules);
kfree(ins); kfree(ins);
up(&chip->spos_mutex);
} }
int cs46xx_dsp_load_module (cs46xx_t * chip, dsp_module_desc_t * module) int cs46xx_dsp_load_module (cs46xx_t * chip, dsp_module_desc_t * module)
...@@ -479,6 +477,7 @@ static void cs46xx_dsp_proc_modules_read (snd_info_entry_t *entry, snd_info_buff ...@@ -479,6 +477,7 @@ static void cs46xx_dsp_proc_modules_read (snd_info_entry_t *entry, snd_info_buff
dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_spos_instance_t * ins = chip->dsp_spos_instance;
int i,j; int i,j;
down(&chip->spos_mutex);
snd_iprintf(buffer, "MODULES:\n"); snd_iprintf(buffer, "MODULES:\n");
for ( i = 0; i < ins->nmodules; ++i ) { for ( i = 0; i < ins->nmodules; ++i ) {
snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name); snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name);
...@@ -491,6 +490,7 @@ static void cs46xx_dsp_proc_modules_read (snd_info_entry_t *entry, snd_info_buff ...@@ -491,6 +490,7 @@ static void cs46xx_dsp_proc_modules_read (snd_info_entry_t *entry, snd_info_buff
desc->segment_type,desc->offset, desc->size); desc->segment_type,desc->offset, desc->size);
} }
} }
up(&chip->spos_mutex);
} }
static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer) static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
...@@ -500,6 +500,7 @@ static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_bu ...@@ -500,6 +500,7 @@ static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_bu
int i,j,col; int i,j,col;
unsigned long dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET; unsigned long dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
down(&chip->spos_mutex);
snd_iprintf(buffer, "TASK TREES:\n"); snd_iprintf(buffer, "TASK TREES:\n");
for ( i = 0; i < ins->ntask; ++i) { for ( i = 0; i < ins->ntask; ++i) {
snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name); snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name);
...@@ -516,6 +517,7 @@ static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_bu ...@@ -516,6 +517,7 @@ static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_bu
} }
snd_iprintf(buffer,"\n"); snd_iprintf(buffer,"\n");
up(&chip->spos_mutex);
} }
static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer) static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
...@@ -524,6 +526,7 @@ static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t ...@@ -524,6 +526,7 @@ static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t
dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_spos_instance_t * ins = chip->dsp_spos_instance;
int i; int i;
down(&chip->spos_mutex);
snd_iprintf(buffer, "SCB's:\n"); snd_iprintf(buffer, "SCB's:\n");
for ( i = 0; i < ins->nscb; ++i) { for ( i = 0; i < ins->nscb; ++i) {
if (ins->scbs[i].deleted) if (ins->scbs[i].deleted)
...@@ -546,6 +549,7 @@ static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t ...@@ -546,6 +549,7 @@ static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t
} }
snd_iprintf(buffer,"\n"); snd_iprintf(buffer,"\n");
up(&chip->spos_mutex);
} }
static void cs46xx_dsp_proc_parameter_dump_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer) static void cs46xx_dsp_proc_parameter_dump_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
...@@ -809,12 +813,14 @@ int cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip) ...@@ -809,12 +813,14 @@ int cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip)
} }
ins->proc_scb_info_entry = entry; ins->proc_scb_info_entry = entry;
down(&chip->spos_mutex);
/* register/update SCB's entries on proc */ /* register/update SCB's entries on proc */
for (i = 0; i < ins->nscb; ++i) { for (i = 0; i < ins->nscb; ++i) {
if (ins->scbs[i].deleted) continue; if (ins->scbs[i].deleted) continue;
cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i)); cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i));
} }
up(&chip->spos_mutex);
return 0; return 0;
} }
...@@ -854,12 +860,12 @@ int cs46xx_dsp_proc_done (cs46xx_t *chip) ...@@ -854,12 +860,12 @@ int cs46xx_dsp_proc_done (cs46xx_t *chip)
ins->proc_task_info_entry = NULL; ins->proc_task_info_entry = NULL;
} }
down(&ins->scb_mutex); down(&chip->spos_mutex);
for (i = 0; i < ins->nscb; ++i) { for (i = 0; i < ins->nscb; ++i) {
if (ins->scbs[i].deleted) continue; if (ins->scbs[i].deleted) continue;
cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
} }
up(&ins->scb_mutex); up(&chip->spos_mutex);
if (ins->proc_dsp_dir) { if (ins->proc_dsp_dir) {
snd_info_unregister (ins->proc_dsp_dir); snd_info_unregister (ins->proc_dsp_dir);
...@@ -930,6 +936,7 @@ static dsp_scb_descriptor_t * _map_scb (cs46xx_t *chip,char * name,u32 dest) ...@@ -930,6 +936,7 @@ static dsp_scb_descriptor_t * _map_scb (cs46xx_t *chip,char * name,u32 dest)
ins->scbs[index].proc_info = NULL; ins->scbs[index].proc_info = NULL;
ins->scbs[index].ref_count = 1; ins->scbs[index].ref_count = 1;
ins->scbs[index].deleted = 0; ins->scbs[index].deleted = 0;
spin_lock_init(&ins->scbs[index].lock);
desc = (ins->scbs + index); desc = (ins->scbs + index);
ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER); ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER);
...@@ -1313,9 +1320,11 @@ int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip) ...@@ -1313,9 +1320,11 @@ int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip)
codec_out_scb, codec_out_scb,
sec_codec_out_scb, sec_codec_out_scb,
SCB_ON_PARENT_SUBLIST_SCB); SCB_ON_PARENT_SUBLIST_SCB);
if (!magic_snoop_scb) goto _fail_end; if (!magic_snoop_scb) goto _fail_end;
ins->ref_snoop_scb = magic_snoop_scb; ins->ref_snoop_scb = magic_snoop_scb;
/* The asynch. transfer task */ /* The asynch. transfer task */
asynch_tx_scb = cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR, asynch_tx_scb = cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
SPDIFO_SCB_INST, SPDIFO_SCB_INST,
...@@ -1576,6 +1585,8 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip) ...@@ -1576,6 +1585,8 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL); snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL);
snd_assert (ins->spdif_in_src != NULL,return -EINVAL); snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
down(&chip->spos_mutex);
/* create and start the asynchronous receiver SCB */ /* create and start the asynchronous receiver SCB */
ins->asynch_rx_scb = cs46xx_dsp_create_asynch_fg_rx_scb(chip,"AsynchFGRxSCB", ins->asynch_rx_scb = cs46xx_dsp_create_asynch_fg_rx_scb(chip,"AsynchFGRxSCB",
ASYNCRX_SCB_ADDR, ASYNCRX_SCB_ADDR,
...@@ -1586,6 +1597,7 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip) ...@@ -1586,6 +1597,7 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
save_flags(flags); save_flags(flags);
cli(); cli();
/* reset SPDIF input sample buffer pointer */ /* reset SPDIF input sample buffer pointer */
snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2, snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2,
(SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC); (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC);
...@@ -1605,6 +1617,7 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip) ...@@ -1605,6 +1617,7 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
/* monitor state */ /* monitor state */
ins->spdif_status_in = 1; ins->spdif_status_in = 1;
up(&chip->spos_mutex);
return 0; return 0;
} }
...@@ -1616,6 +1629,7 @@ int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip) ...@@ -1616,6 +1629,7 @@ int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip)
snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL); snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL);
snd_assert (ins->spdif_in_src != NULL,return -EINVAL); snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
down(&chip->spos_mutex);
/* Remove the asynchronous receiver SCB */ /* Remove the asynchronous receiver SCB */
cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb); cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb);
ins->asynch_rx_scb = NULL; ins->asynch_rx_scb = NULL;
...@@ -1624,6 +1638,7 @@ int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip) ...@@ -1624,6 +1638,7 @@ int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip)
/* monitor state */ /* monitor state */
ins->spdif_status_in = 0; ins->spdif_status_in = 0;
up(&chip->spos_mutex);
/* restore amplifier */ /* restore amplifier */
chip->active_ctrl(chip, -1); chip->active_ctrl(chip, -1);
...@@ -1639,9 +1654,11 @@ int cs46xx_dsp_enable_pcm_capture (cs46xx_t *chip) ...@@ -1639,9 +1654,11 @@ int cs46xx_dsp_enable_pcm_capture (cs46xx_t *chip)
snd_assert (ins->pcm_input == NULL,return -EINVAL); snd_assert (ins->pcm_input == NULL,return -EINVAL);
snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL); snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL);
down(&chip->spos_mutex);
ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR, ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR,
"PCMSerialInput_Wave"); "PCMSerialInput_Wave");
up(&chip->spos_mutex);
return 0; return 0;
} }
...@@ -1651,8 +1668,10 @@ int cs46xx_dsp_disable_pcm_capture (cs46xx_t *chip) ...@@ -1651,8 +1668,10 @@ int cs46xx_dsp_disable_pcm_capture (cs46xx_t *chip)
snd_assert (ins->pcm_input != NULL,return -EINVAL); snd_assert (ins->pcm_input != NULL,return -EINVAL);
down(&chip->spos_mutex);
cs46xx_dsp_remove_scb (chip,ins->pcm_input); cs46xx_dsp_remove_scb (chip,ins->pcm_input);
ins->pcm_input = NULL; ins->pcm_input = NULL;
up(&chip->spos_mutex);
return 0; return 0;
} }
...@@ -1664,9 +1683,11 @@ int cs46xx_dsp_enable_adc_capture (cs46xx_t *chip) ...@@ -1664,9 +1683,11 @@ int cs46xx_dsp_enable_adc_capture (cs46xx_t *chip)
snd_assert (ins->adc_input == NULL,return -EINVAL); snd_assert (ins->adc_input == NULL,return -EINVAL);
snd_assert (ins->codec_in_scb != NULL,return -EINVAL); snd_assert (ins->codec_in_scb != NULL,return -EINVAL);
down(&chip->spos_mutex);
ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR, ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR,
"PCMSerialInput_ADC"); "PCMSerialInput_ADC");
up(&chip->spos_mutex);
return 0; return 0;
} }
...@@ -1676,8 +1697,10 @@ int cs46xx_dsp_disable_adc_capture (cs46xx_t *chip) ...@@ -1676,8 +1697,10 @@ int cs46xx_dsp_disable_adc_capture (cs46xx_t *chip)
snd_assert (ins->adc_input != NULL,return -EINVAL); snd_assert (ins->adc_input != NULL,return -EINVAL);
down(&chip->spos_mutex);
cs46xx_dsp_remove_scb (chip,ins->adc_input); cs46xx_dsp_remove_scb (chip,ins->adc_input);
ins->adc_input = NULL; ins->adc_input = NULL;
up(&chip->spos_mutex);
return 0; return 0;
} }
...@@ -1697,7 +1720,7 @@ int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data) ...@@ -1697,7 +1720,7 @@ int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data)
snd_cs46xx_poke(chip,( SPIOWRITE_SCB_ADDR << 2), temp); snd_cs46xx_poke(chip,( SPIOWRITE_SCB_ADDR << 2), temp);
snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 1) << 2), data); /* offset 1 <-- data1 */ snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 1) << 2), data); /* offset 1 <-- data1 */
snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 2) << 2), data); /* offset 1 <-- data2*/ snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 2) << 2), data); /* offset 1 <-- data2 */
/* Poke this location to tell the task to start */ /* Poke this location to tell the task to start */
snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 6) << 2), SPIOWRITE_SCB_ADDR << 0x10); snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 6) << 2), SPIOWRITE_SCB_ADDR << 0x10);
......
This diff is collapsed.
...@@ -1628,7 +1628,7 @@ static int snd_ice1712_capture_open(snd_pcm_substream_t * substream) ...@@ -1628,7 +1628,7 @@ static int snd_ice1712_capture_open(snd_pcm_substream_t * substream)
ice->capture_con_substream = substream; ice->capture_con_substream = substream;
runtime->hw = snd_ice1712_capture; runtime->hw = snd_ice1712_capture;
runtime->hw.rates = ice->ac97->rates_adc; runtime->hw.rates = ice->ac97->rates[AC97_RATES_ADC];
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
runtime->hw.rate_min = 48000; runtime->hw.rate_min = 48000;
return 0; return 0;
...@@ -1660,8 +1660,6 @@ static int snd_ice1712_capture_close(snd_pcm_substream_t * substream) ...@@ -1660,8 +1660,6 @@ static int snd_ice1712_capture_close(snd_pcm_substream_t * substream)
{ {
ice1712_t *ice = snd_pcm_substream_chip(substream); ice1712_t *ice = snd_pcm_substream_chip(substream);
/* disable ADC power */
snd_ac97_update_bits(ice->ac97, AC97_POWERDOWN, 0x0100, 0x0100);
ice->capture_con_substream = NULL; ice->capture_con_substream = NULL;
return 0; return 0;
} }
...@@ -2396,14 +2394,6 @@ static int __init snd_ice1712_build_pro_mixer(ice1712_t *ice) ...@@ -2396,14 +2394,6 @@ static int __init snd_ice1712_build_pro_mixer(ice1712_t *ice)
return 0; return 0;
} }
static void snd_ice1712_ac97_init(ac97_t *ac97)
{
// ice1712_t *ice = snd_magic_cast(ice1712_t, ac97->private_data, return);
/* disable center DAC/surround DAC/LFE DAC/MIC ADC */
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, 0xe800, 0xe800);
}
static void snd_ice1712_mixer_free_ac97(ac97_t *ac97) static void snd_ice1712_mixer_free_ac97(ac97_t *ac97)
{ {
ice1712_t *ice = snd_magic_cast(ice1712_t, ac97->private_data, return); ice1712_t *ice = snd_magic_cast(ice1712_t, ac97->private_data, return);
...@@ -2419,7 +2409,6 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice) ...@@ -2419,7 +2409,6 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
memset(&ac97, 0, sizeof(ac97)); memset(&ac97, 0, sizeof(ac97));
ac97.write = snd_ice1712_ac97_write; ac97.write = snd_ice1712_ac97_write;
ac97.read = snd_ice1712_ac97_read; ac97.read = snd_ice1712_ac97_read;
ac97.init = snd_ice1712_ac97_init;
ac97.private_data = ice; ac97.private_data = ice;
ac97.private_free = snd_ice1712_mixer_free_ac97; ac97.private_free = snd_ice1712_mixer_free_ac97;
if ((err = snd_ac97_mixer(ice->card, &ac97, &ice->ac97)) < 0) { if ((err = snd_ac97_mixer(ice->card, &ac97, &ice->ac97)) < 0) {
...@@ -2437,7 +2426,6 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice) ...@@ -2437,7 +2426,6 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
memset(&ac97, 0, sizeof(ac97)); memset(&ac97, 0, sizeof(ac97));
ac97.write = snd_ice1712_pro_ac97_write; ac97.write = snd_ice1712_pro_ac97_write;
ac97.read = snd_ice1712_pro_ac97_read; ac97.read = snd_ice1712_pro_ac97_read;
ac97.init = snd_ice1712_ac97_init;
ac97.private_data = ice; ac97.private_data = ice;
ac97.private_free = snd_ice1712_mixer_free_ac97; ac97.private_free = snd_ice1712_mixer_free_ac97;
if ((err = snd_ac97_mixer(ice->card, &ac97, &ice->ac97)) < 0) { if ((err = snd_ac97_mixer(ice->card, &ac97, &ice->ac97)) < 0) {
......
This diff is collapsed.
...@@ -605,7 +605,7 @@ static snd_pcm_hardware_t snd_via686a_playback = ...@@ -605,7 +605,7 @@ static snd_pcm_hardware_t snd_via686a_playback =
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 128 * 1024, .period_bytes_max = 128 * 1024,
.periods_min = 2, .periods_min = 2,
.periods_max = 1024, .periods_max = 128,
.fifo_size = 0, .fifo_size = 0,
}; };
...@@ -624,7 +624,7 @@ static snd_pcm_hardware_t snd_via686a_capture = ...@@ -624,7 +624,7 @@ static snd_pcm_hardware_t snd_via686a_capture =
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 128 * 1024, .period_bytes_max = 128 * 1024,
.periods_min = 2, .periods_min = 2,
.periods_max = 1024, .periods_max = 128,
.fifo_size = 0, .fifo_size = 0,
}; };
...@@ -636,21 +636,17 @@ static int snd_via686a_playback_open(snd_pcm_substream_t * substream) ...@@ -636,21 +636,17 @@ static int snd_via686a_playback_open(snd_pcm_substream_t * substream)
chip->playback.substream = substream; chip->playback.substream = substream;
runtime->hw = snd_via686a_playback; runtime->hw = snd_via686a_playback;
runtime->hw.rates = chip->ac97->rates_front_dac; runtime->hw.rates = chip->ac97->rates[AC97_RATES_FRONT_DAC];
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
runtime->hw.rate_min = 48000; runtime->hw.rate_min = 48000;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0) if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err; return err;
if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
return err; return err;
#if 0 /* we may remove following constaint when we modify table entries
/* applying the following constraint together with the power-of-2 rule in interrupt */
* above may result in too narrow space.
* this one is not strictly necessary, so let's disable it.
*/
if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err; return err;
#endif
return 0; return 0;
} }
...@@ -662,17 +658,15 @@ static int snd_via686a_capture_open(snd_pcm_substream_t * substream) ...@@ -662,17 +658,15 @@ static int snd_via686a_capture_open(snd_pcm_substream_t * substream)
chip->capture.substream = substream; chip->capture.substream = substream;
runtime->hw = snd_via686a_capture; runtime->hw = snd_via686a_capture;
runtime->hw.rates = chip->ac97->rates_adc; runtime->hw.rates = chip->ac97->rates[AC97_RATES_ADC];
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
runtime->hw.rate_min = 48000; runtime->hw.rate_min = 48000;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0) if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err; return err;
if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
return err; return err;
#if 0
if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err; return err;
#endif
return 0; return 0;
} }
...@@ -683,8 +677,6 @@ static int snd_via686a_playback_close(snd_pcm_substream_t * substream) ...@@ -683,8 +677,6 @@ static int snd_via686a_playback_close(snd_pcm_substream_t * substream)
clean_via_table(&chip->playback, substream, chip->pci); clean_via_table(&chip->playback, substream, chip->pci);
snd_pcm_sgbuf_delete(substream); snd_pcm_sgbuf_delete(substream);
chip->playback.substream = NULL; chip->playback.substream = NULL;
/* disable DAC power */
snd_ac97_update_bits(chip->ac97, AC97_POWERDOWN, 0x0200, 0x0200);
return 0; return 0;
} }
...@@ -695,8 +687,6 @@ static int snd_via686a_capture_close(snd_pcm_substream_t * substream) ...@@ -695,8 +687,6 @@ static int snd_via686a_capture_close(snd_pcm_substream_t * substream)
clean_via_table(&chip->capture, substream, chip->pci); clean_via_table(&chip->capture, substream, chip->pci);
snd_pcm_sgbuf_delete(substream); snd_pcm_sgbuf_delete(substream);
chip->capture.substream = NULL; chip->capture.substream = NULL;
/* disable ADC power */
snd_ac97_update_bits(chip->ac97, AC97_POWERDOWN, 0x0100, 0x0100);
return 0; return 0;
} }
...@@ -764,16 +754,6 @@ static int __devinit snd_via686a_pcm(via686a_t *chip, int device, snd_pcm_t ** r ...@@ -764,16 +754,6 @@ static int __devinit snd_via686a_pcm(via686a_t *chip, int device, snd_pcm_t ** r
* Mixer part * Mixer part
*/ */
static void snd_via686a_codec_init(ac97_t *ac97)
{
// via686a_t *chip = snd_magic_cast(via686a_t, ac97->private_data, return);
/* disable DAC & ADC power */
snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x0300, 0x0300);
/* disable center DAC/surround DAC/LFE DAC/MIC ADC */
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, 0xe800, 0xe800);
}
static void snd_via686a_mixer_free_ac97(ac97_t *ac97) static void snd_via686a_mixer_free_ac97(ac97_t *ac97)
{ {
via686a_t *chip = snd_magic_cast(via686a_t, ac97->private_data, return); via686a_t *chip = snd_magic_cast(via686a_t, ac97->private_data, return);
...@@ -788,7 +768,6 @@ static int __devinit snd_via686a_mixer(via686a_t *chip) ...@@ -788,7 +768,6 @@ static int __devinit snd_via686a_mixer(via686a_t *chip)
memset(&ac97, 0, sizeof(ac97)); memset(&ac97, 0, sizeof(ac97));
ac97.write = snd_via686a_codec_write; ac97.write = snd_via686a_codec_write;
ac97.read = snd_via686a_codec_read; ac97.read = snd_via686a_codec_read;
ac97.init = snd_via686a_codec_init;
ac97.wait = snd_via686a_codec_wait; ac97.wait = snd_via686a_codec_wait;
ac97.private_data = chip; ac97.private_data = chip;
ac97.private_free = snd_via686a_mixer_free_ac97; ac97.private_free = snd_via686a_mixer_free_ac97;
......
...@@ -591,7 +591,7 @@ static snd_pcm_hardware_t snd_via8233_playback = ...@@ -591,7 +591,7 @@ static snd_pcm_hardware_t snd_via8233_playback =
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 128 * 1024, .period_bytes_max = 128 * 1024,
.periods_min = 2, .periods_min = 2,
.periods_max = 1024, .periods_max = 128,
.fifo_size = 0, .fifo_size = 0,
}; };
...@@ -610,7 +610,7 @@ static snd_pcm_hardware_t snd_via8233_capture = ...@@ -610,7 +610,7 @@ static snd_pcm_hardware_t snd_via8233_capture =
.period_bytes_min = 32, .period_bytes_min = 32,
.period_bytes_max = 128 * 1024, .period_bytes_max = 128 * 1024,
.periods_min = 2, .periods_min = 2,
.periods_max = 1024, .periods_max = 128,
.fifo_size = 0, .fifo_size = 0,
}; };
...@@ -634,17 +634,15 @@ static int snd_via8233_playback_open(snd_pcm_substream_t * substream) ...@@ -634,17 +634,15 @@ static int snd_via8233_playback_open(snd_pcm_substream_t * substream)
chip->playback.substream = substream; chip->playback.substream = substream;
runtime->hw = snd_via8233_playback; runtime->hw = snd_via8233_playback;
runtime->hw.rates = chip->ac97->rates_front_dac; runtime->hw.rates = chip->ac97->rates[AC97_RATES_FRONT_DAC];
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
runtime->hw.rate_min = 48000; runtime->hw.rate_min = 48000;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0) if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err; return err;
if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
return err; return err;
#if 0
if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err; return err;
#endif
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
return 0; return 0;
} }
...@@ -657,17 +655,15 @@ static int snd_via8233_capture_open(snd_pcm_substream_t * substream) ...@@ -657,17 +655,15 @@ static int snd_via8233_capture_open(snd_pcm_substream_t * substream)
chip->capture.substream = substream; chip->capture.substream = substream;
runtime->hw = snd_via8233_capture; runtime->hw = snd_via8233_capture;
runtime->hw.rates = chip->ac97->rates_adc; runtime->hw.rates = chip->ac97->rates[AC97_RATES_ADC];
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
runtime->hw.rate_min = 48000; runtime->hw.rate_min = 48000;
if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0) if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
return err; return err;
if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) if ((err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
return err; return err;
#if 0
if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err; return err;
#endif
return 0; return 0;
} }
...@@ -679,8 +675,6 @@ static int snd_via8233_playback_close(snd_pcm_substream_t * substream) ...@@ -679,8 +675,6 @@ static int snd_via8233_playback_close(snd_pcm_substream_t * substream)
clean_via_table(&chip->playback, substream, chip->pci); clean_via_table(&chip->playback, substream, chip->pci);
snd_pcm_sgbuf_delete(substream); snd_pcm_sgbuf_delete(substream);
chip->playback.substream = NULL; chip->playback.substream = NULL;
/* disable DAC power */
snd_ac97_update_bits(chip->ac97, AC97_POWERDOWN, 0x0200, 0x0200);
return 0; return 0;
} }
...@@ -692,8 +686,6 @@ static int snd_via8233_capture_close(snd_pcm_substream_t * substream) ...@@ -692,8 +686,6 @@ static int snd_via8233_capture_close(snd_pcm_substream_t * substream)
clean_via_table(&chip->capture, substream, chip->pci); clean_via_table(&chip->capture, substream, chip->pci);
snd_pcm_sgbuf_delete(substream); snd_pcm_sgbuf_delete(substream);
chip->capture.substream = NULL; chip->capture.substream = NULL;
/* disable ADC power */
snd_ac97_update_bits(chip->ac97, AC97_POWERDOWN, 0x0100, 0x0100);
return 0; return 0;
} }
...@@ -760,16 +752,6 @@ static int __devinit snd_via8233_pcm(via8233_t *chip, int device, snd_pcm_t ** r ...@@ -760,16 +752,6 @@ static int __devinit snd_via8233_pcm(via8233_t *chip, int device, snd_pcm_t ** r
* Mixer part * Mixer part
*/ */
static void snd_via8233_codec_init(ac97_t *ac97)
{
// via8233_t *chip = snd_magic_cast(via8233_t, ac97->private_data, return);
/* disable DAC & ADC power */
snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x0300, 0x0300);
/* disable center DAC/surround DAC/LFE DAC/MIC ADC */
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, 0xe800, 0xe800);
}
static void snd_via8233_mixer_free_ac97(ac97_t *ac97) static void snd_via8233_mixer_free_ac97(ac97_t *ac97)
{ {
via8233_t *chip = snd_magic_cast(via8233_t, ac97->private_data, return); via8233_t *chip = snd_magic_cast(via8233_t, ac97->private_data, return);
...@@ -784,7 +766,6 @@ static int __devinit snd_via8233_mixer(via8233_t *chip) ...@@ -784,7 +766,6 @@ static int __devinit snd_via8233_mixer(via8233_t *chip)
memset(&ac97, 0, sizeof(ac97)); memset(&ac97, 0, sizeof(ac97));
ac97.write = snd_via8233_codec_write; ac97.write = snd_via8233_codec_write;
ac97.read = snd_via8233_codec_read; ac97.read = snd_via8233_codec_read;
ac97.init = snd_via8233_codec_init;
ac97.private_data = chip; ac97.private_data = chip;
ac97.private_free = snd_via8233_mixer_free_ac97; ac97.private_free = snd_via8233_mixer_free_ac97;
ac97.clock = chip->ac97_clock; ac97.clock = chip->ac97_clock;
......
CONFIG_SND_USB_AUDIO CONFIG_SND_USB_AUDIO
Say 'Y' or 'M' to include support for USB audio devices. Say 'Y' or 'M' to include support for USB audio devices.
To support USB MIDI devices, you need to enable ALSA sequencer support
CONFIG_SND_USB_MIDI (CONFIG_SND_SEQUENCER).
Say 'Y' or 'M' to include support for MIDI devices connected via USB.
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
mainmenu_option next_comment mainmenu_option next_comment
comment 'ALSA USB devices' comment 'ALSA USB devices'
dep_tristate 'USB Audio driver' CONFIG_SND_USB_AUDIO $CONFIG_SND dep_tristate 'USB Audio/MIDI driver' CONFIG_SND_USB_AUDIO $CONFIG_SND
dep_tristate 'USB MIDI driver' CONFIG_SND_USB_MIDI $CONFIG_SND $CONFIG_SND_SEQUENCER
endmenu endmenu
...@@ -3,10 +3,14 @@ ...@@ -3,10 +3,14 @@
# #
snd-usb-audio-objs := usbaudio.o usbmixer.o snd-usb-audio-objs := usbaudio.o usbmixer.o
ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
snd-usb-midi-objs := usbmidi.o snd-usb-midi-objs := usbmidi.o
endif
# Toplevel Module Dependency # Toplevel Module Dependency
obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o
obj-$(CONFIG_SND_USB_MIDI) += snd-usb-midi.o ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-midi.o
endif
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <sound/core.h> #include <sound/core.h>
#include <sound/info.h> #include <sound/info.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/seq_device.h>
#define SNDRV_GET_ID #define SNDRV_GET_ID
#include <sound/initval.h> #include <sound/initval.h>
...@@ -1234,6 +1235,7 @@ static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1234,6 +1235,7 @@ static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
static void usb_audio_disconnect(struct usb_device *dev, void *ptr); static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
static struct usb_device_id usb_audio_ids [] = { static struct usb_device_id usb_audio_ids [] = {
#include "usbquirks.h"
{ .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
.bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL },
...@@ -1716,11 +1718,14 @@ static int snd_usb_audio_stream_new(snd_usb_audio_t *chip, unsigned char *buffer ...@@ -1716,11 +1718,14 @@ static int snd_usb_audio_stream_new(snd_usb_audio_t *chip, unsigned char *buffer
/* /*
* parse audio control descriptor and create pcm streams * parse audio control descriptor and create pcm/midi streams
*/ */
static int snd_usb_create_pcm(snd_usb_audio_t *chip, int ctrlif, static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
unsigned char *buffer, int buflen) const snd_usb_audio_quirk_t *quirk);
static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
unsigned char *buffer, int buflen)
{ {
struct usb_device *dev = chip->dev; struct usb_device *dev = chip->dev;
struct usb_config_descriptor *config; struct usb_config_descriptor *config;
...@@ -1752,6 +1757,15 @@ static int snd_usb_create_pcm(snd_usb_audio_t *chip, int ctrlif, ...@@ -1752,6 +1757,15 @@ static int snd_usb_create_pcm(snd_usb_audio_t *chip, int ctrlif,
continue; continue;
} }
iface = &config->interface[j]; iface = &config->interface[j];
if (iface->altsetting[0].bInterfaceClass == USB_CLASS_AUDIO &&
iface->altsetting[0].bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
if (snd_usb_create_midi_interface(chip, j, NULL) < 0) {
snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
continue;
}
usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1);
continue;
}
if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO || if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO ||
iface->altsetting[0].bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { iface->altsetting[0].bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) {
snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, iface->altsetting[0].bInterfaceClass); snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, iface->altsetting[0].bInterfaceClass);
...@@ -1808,6 +1822,37 @@ static int snd_usb_create_pcm(snd_usb_audio_t *chip, int ctrlif, ...@@ -1808,6 +1822,37 @@ static int snd_usb_create_pcm(snd_usb_audio_t *chip, int ctrlif,
return 0; return 0;
} }
static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
const snd_usb_audio_quirk_t *quirk)
{
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
snd_seq_device_t *seq_device;
snd_usb_midi_t *umidi;
int err;
err = snd_seq_device_new(chip->card, chip->next_seq_device,
SNDRV_SEQ_DEV_ID_USBMIDI,
sizeof(snd_usb_midi_t), &seq_device);
if (err < 0)
return err;
chip->next_seq_device++;
strcpy(seq_device->name, chip->card->shortname);
umidi = (snd_usb_midi_t *)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
umidi->chip = chip;
umidi->ifnum = ifnum;
umidi->quirk = quirk;
umidi->seq_client = -1;
#endif
return 0;
}
static inline int snd_usb_create_quirk(snd_usb_audio_t *chip, int ifnum,
const snd_usb_audio_quirk_t *quirk)
{
/* in the future, there may be quirks for PCM devices */
return snd_usb_create_midi_interface(chip, ifnum, quirk);
}
/* /*
* free the chip instance * free the chip instance
...@@ -1835,7 +1880,9 @@ static int snd_usb_audio_dev_free(snd_device_t *device) ...@@ -1835,7 +1880,9 @@ static int snd_usb_audio_dev_free(snd_device_t *device)
/* /*
* create a chip instance and set its names. * create a chip instance and set its names.
*/ */
static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev, snd_usb_audio_t **rchip) static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev,
const snd_usb_audio_quirk_t *quirk,
snd_usb_audio_t **rchip)
{ {
snd_usb_audio_t *chip; snd_usb_audio_t *chip;
int err, len; int err, len;
...@@ -1858,18 +1905,50 @@ static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev, snd_us ...@@ -1858,18 +1905,50 @@ static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev, snd_us
} }
strcpy(card->driver, "USB-Audio"); strcpy(card->driver, "USB-Audio");
strcpy(card->shortname, "USB Audio Driver");
/* retrieve the device string as shortname */
if (dev->descriptor.iProduct)
len = usb_string(dev, dev->descriptor.iProduct,
card->shortname, sizeof(card->shortname));
else
len = 0;
if (len <= 0) {
if (quirk && quirk->product_name) {
strncpy(card->shortname, quirk->product_name, sizeof(card->shortname) - 1);
card->shortname[sizeof(card->shortname) - 1] = '\0';
} else {
sprintf(card->shortname, "USB Device %#04x:%#04x",
dev->descriptor.idVendor, dev->descriptor.idProduct);
}
}
/* retrieve the vendor and device strings as longname */ /* retrieve the vendor and device strings as longname */
len = usb_string(dev, 1, card->longname, sizeof(card->longname) - 1); if (dev->descriptor.iManufacturer)
if (len <= 0) len = usb_string(dev, dev->descriptor.iManufacturer,
card->longname, sizeof(card->longname) - 1);
else
len = 0; len = 0;
else { if (len <= 0) {
if (quirk && quirk->vendor_name) {
strncpy(card->longname, quirk->vendor_name, sizeof(card->longname) - 2);
card->longname[sizeof(card->longname) - 2] = '\0';
len = strlen(card->longname);
} else {
len = 0;
}
}
if (len > 0) {
card->longname[len] = ' '; card->longname[len] = ' ';
len++; len++;
} }
card->longname[len] = 0; card->longname[len] = '\0';
usb_string(dev, 2, card->longname + len, sizeof(card->longname) - len); if ((!dev->descriptor.iProduct
|| usb_string(dev, dev->descriptor.iProduct,
card->longname + len, sizeof(card->longname) - len) <= 0)
&& quirk && quirk->product_name) {
strncpy(card->longname + len, quirk->product_name, sizeof(card->longname) - len - 1);
card->longname[sizeof(card->longname) - 1] = '\0';
}
*rchip = chip; *rchip = chip;
return 0; return 0;
...@@ -1926,12 +2005,16 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1926,12 +2005,16 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_config_descriptor *config = dev->actconfig; struct usb_config_descriptor *config = dev->actconfig;
const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)id->driver_info;
unsigned char *buffer; unsigned char *buffer;
unsigned int index; unsigned int index;
int i, buflen; int i, buflen;
snd_card_t *card; snd_card_t *card;
snd_usb_audio_t *chip; snd_usb_audio_t *chip;
if (quirk && ifnum != quirk->ifnum)
return NULL;
if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {
snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", config->bConfigurationValue); snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", config->bConfigurationValue);
return NULL; return NULL;
...@@ -1966,7 +2049,7 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1966,7 +2049,7 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
snd_printk(KERN_ERR "cannot create a card instance %d\n", i); snd_printk(KERN_ERR "cannot create a card instance %d\n", i);
goto __error; goto __error;
} }
if (snd_usb_audio_create(card, dev, &chip) < 0) { if (snd_usb_audio_create(card, dev, quirk, &chip) < 0) {
snd_card_free(card); snd_card_free(card);
goto __error; goto __error;
} }
...@@ -1980,10 +2063,15 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1980,10 +2063,15 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
} }
} }
if (snd_usb_create_pcm(chip, ifnum, buffer, buflen) < 0) if (!quirk) {
goto __error; if (snd_usb_create_streams(chip, ifnum, buffer, buflen) < 0)
if (snd_usb_create_mixer(chip, ifnum, buffer, buflen) < 0) goto __error;
goto __error; if (snd_usb_create_mixer(chip, ifnum, buffer, buflen) < 0)
goto __error;
} else {
if (snd_usb_create_quirk(chip, ifnum, quirk) < 0)
goto __error;
}
/* we are allowed to call snd_card_register() many times */ /* we are allowed to call snd_card_register() many times */
if (snd_card_register(chip->card) < 0) { if (snd_card_register(chip->card) < 0) {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define USB_SUBCLASS_AUDIO_CONTROL 0x01 #define USB_SUBCLASS_AUDIO_CONTROL 0x01
#define USB_SUBCLASS_AUDIO_STREAMING 0x02 #define USB_SUBCLASS_AUDIO_STREAMING 0x02
#define USB_SUBCLASS_MIDI_STREAMING 0x03
#define USB_DT_CS_DEVICE 0x21 #define USB_DT_CS_DEVICE 0x21
#define USB_DT_CS_CONFIG 0x22 #define USB_DT_CS_CONFIG 0x22
...@@ -56,6 +57,8 @@ ...@@ -56,6 +57,8 @@
#define EP_GENERAL 0x01 #define EP_GENERAL 0x01
#define MS_GENERAL 0x01
/* endpoint attributes */ /* endpoint attributes */
#define EP_ATTR_MASK 0x0c #define EP_ATTR_MASK 0x0c
#define EP_ATTR_ASYNC 0x04 #define EP_ATTR_ASYNC 0x04
...@@ -115,6 +118,11 @@ ...@@ -115,6 +118,11 @@
#define USB_AUDIO_FORMAT_IEC1937_MPEG2_LAYER23_LS 0x2006 #define USB_AUDIO_FORMAT_IEC1937_MPEG2_LAYER23_LS 0x2006
/* maximum number of endpoints per interface */
#define MIDI_MAX_ENDPOINTS 2
#define SNDRV_SEQ_DEV_ID_USBMIDI "usb-midi"
/* /*
*/ */
...@@ -130,8 +138,53 @@ struct snd_usb_audio { ...@@ -130,8 +138,53 @@ struct snd_usb_audio {
struct list_head pcm_list; /* list of pcm streams */ struct list_head pcm_list; /* list of pcm streams */
int pcm_devs; int pcm_devs;
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
int next_seq_device;
#endif
}; };
/*
* Information about devices with broken descriptors
*/
typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
struct snd_usb_audio_quirk {
const char *vendor_name;
const char *product_name;
int ifnum;
/* MIDI specific */
struct snd_usb_midi_endpoint_info {
int16_t epnum; /* ep number, -1 autodetect */
uint16_t out_cables; /* bitmask */
uint16_t in_cables; /* bitmask */
} endpoints[MIDI_MAX_ENDPOINTS];
};
/*
* USB MIDI sequencer device data
*/
typedef struct snd_usb_midi snd_usb_midi_t;
typedef struct snd_usb_midi_endpoint snd_usb_midi_endpoint_t;
typedef struct snd_usb_midi_out_endpoint snd_usb_midi_out_endpoint_t;
typedef struct snd_usb_midi_in_endpoint snd_usb_midi_in_endpoint_t;
struct snd_usb_midi {
/* filled by usbaudio.c */
snd_usb_audio_t *chip;
int ifnum;
const snd_usb_audio_quirk_t *quirk;
/* used internally in usbmidi.c */
int seq_client;
struct snd_usb_midi_endpoint {
snd_usb_midi_out_endpoint_t *out;
snd_usb_midi_in_endpoint_t *in;
snd_rawmidi_t *rmidi[0x10];
} endpoints[MIDI_MAX_ENDPOINTS];
};
/* /*
*/ */
......
This diff is collapsed.
/*
* ALSA USB Audio Driver
*
* Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>,
* Clemens Ladisch <clemens@ladisch.de>
*
*
* 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
*/
/*
* The contents of this file are part of the driver's id_table.
*
* In a perfect world, this file would be empty.
*/
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
{
/* from NetBSD's umidi driver */
USB_DEVICE(0x0499, 0x1000), /* Yamaha UX256 */
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.ifnum = 0,
.endpoints = {
{
.epnum = -1,
.out_cables = 0xffff,
.in_cables = 0x00ff
}
}
}
},
{
/* from Nagano Daisuke's usb-midi driver */
USB_DEVICE(0x0499, 0x1001), /* Yamaha MU1000 */
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.ifnum = 0,
.endpoints = {
{
.epnum = 1,
.out_cables = 0x000f,
.in_cables = 0x0001
}
}
}
},
/*
* I don't know whether the following Yamaha devices need entries or not:
* 0x1002 MU2000 0x1008 UX96
* 0x1003 MU500 0x1009 UX16
* 0x1004 UW500 0x100e S08
* 0x1005 MOTIF6 0x100f CLP-150
* 0x1006 MOTIF7 0x1010 CLP-170
* 0x1007 MOTIF8
*/
/*
* Once upon a time people thought, "Wouldn't it be nice if there was a
* standard for USB MIDI devices, so that device drivers would not be forced
* to know about the quirks of specific devices?" So Roland went ahead and
* wrote the USB Device Class Definition for MIDI Devices, and the USB-IF
* endorsed it, and now everybody designing USB MIDI devices does so in
* agreement with this standard (or at least tries to).
*
* And if you prefer a happy end, you can imagine that Roland devices set a
* good example. Instead of being completely fucked up due to the lack of
* class-specific descriptors.
*/
{
USB_DEVICE(0x0582, 0x0000),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "UA-100",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0007,
.in_cables = 0x0007
}
}
}
},
{
USB_DEVICE(0x0582, 0x0002),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-4",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x000f,
.in_cables = 0x000f
}
}
}
},
{
USB_DEVICE(0x0582, 0x0003),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SC-8850",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x003f,
.in_cables = 0x003f
}
}
}
},
{
USB_DEVICE(0x0582, 0x0004),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "U-8",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0003,
.in_cables = 0x0003
}
}
}
},
{
USB_DEVICE(0x0582, 0x0005),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-2",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0003,
.in_cables = 0x0003
}
}
}
},
{
USB_DEVICE(0x0582, 0x0007),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SC-8820",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0013,
.in_cables = 0x0013
}
}
}
},
{
USB_DEVICE(0x0582, 0x0008),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "PC-300",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0001,
.in_cables = 0x0001
}
}
}
},
{
USB_DEVICE(0x0582, 0x0009),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-1",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0001,
.in_cables = 0x0001
}
}
}
},
{
USB_DEVICE(0x0582, 0x000b),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SK-500",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0013,
.in_cables = 0x0013
}
}
}
},
{
USB_DEVICE(0x0582, 0x000c),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "SC-D70",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0007,
.in_cables = 0x0007
}
}
}
},
{
USB_DEVICE(0x0582, 0x0012),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
.product_name = "XV-5050",
.ifnum = 0,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0001,
.in_cables = 0x0001
}
}
}
},
{
USB_DEVICE(0x0582, 0x0014),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-880",
.ifnum = 0,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x01ff,
.in_cables = 0x01ff
}
}
}
},
{
USB_DEVICE(0x0582, 0x0016),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "SD-90",
.ifnum = 2,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x000f,
.in_cables = 0x000f
}
}
}
},
{
USB_DEVICE(0x0582, 0x0023),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UM-550",
.ifnum = 0,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x003f,
.in_cables = 0x003f
}
}
}
},
{
USB_DEVICE(0x0582, 0x0027),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "SD-20",
.ifnum = 0,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0003,
.in_cables = 0x0007
}
}
}
},
{
USB_DEVICE(0x0582, 0x0029),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "SD-80",
.ifnum = 0,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x000f,
.in_cables = 0x000f
}
}
}
},
{
USB_DEVICE(0x0582, 0x002b),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
.product_name = "UA-700",
.ifnum = 3,
.endpoints = {
{
.epnum = -1,
.out_cables = 0x0003,
.in_cables = 0x0003
}
}
}
},
#endif /* CONFIG_SND_SEQUENCER(_MODULE) */
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