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

[PATCH] ALSA update [8/12] - 2002/09/06

  - VIA686 and VIA8233 driver merge to VIA82xx
  - ioctl32 fixes
  - fixed OOPS in snd_pcm_sgbuf_delete (not initialized)
  - I2C - call hw_stop() before returning at the error pointer
  - AC'97 codec - added more AC97 IDs by Laszlo Melis
  - CS46xx - mutex initialization fix
  - ENS1371 - added one more card to S/PDIF capabilities
  - intel8x0
    - fixed secondary and third codec indexes
  - PPC Keywest - initialize MCS in loop until it succeeds
  - PPC Tumbler - the initial support for snapper (TAS3004) on some tibook
  - USB Audio - mixer fixes
parent e2094b53
...@@ -113,7 +113,7 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic) ...@@ -113,7 +113,7 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define intel8x0_t_magic 0xa15a2a01 #define intel8x0_t_magic 0xa15a2a01
#define es1968_t_magic 0xa15a2b01 #define es1968_t_magic 0xa15a2b01
#define esschan_t_magic 0xa15a2b02 #define esschan_t_magic 0xa15a2b02
#define via686a_t_magic 0xa15a2c01 #define via82xx_t_magic 0xa15a2c01
#define pdplus_t_magic 0xa15a2d01 #define pdplus_t_magic 0xa15a2d01
#define cmipci_t_magic 0xa15a2e01 #define cmipci_t_magic 0xa15a2e01
#define ymfpci_t_magic 0xa15a2f01 #define ymfpci_t_magic 0xa15a2f01
...@@ -126,7 +126,6 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic) ...@@ -126,7 +126,6 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define m3_dma_t_magic 0xa15a3202 #define m3_dma_t_magic 0xa15a3202
#define nm256_t_magic 0xa15a3301 #define nm256_t_magic 0xa15a3301
#define nm256_dma_t_magic 0xa15a3302 #define nm256_dma_t_magic 0xa15a3302
#define via8233_t_magic 0xa15a3401
#define pmac_t_magic 0xa15a3501 #define pmac_t_magic 0xa15a3501
#define ali_t_magic 0xa15a3601 #define ali_t_magic 0xa15a3601
#define mtpav_t_magic 0xa15a3701 #define mtpav_t_magic 0xa15a3701
......
/* 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 " (Mon Aug 26 16:28:35 2002 UTC)" #define CONFIG_SND_DATE " (Fri Sep 06 15:06:56 2002 UTC)"
...@@ -78,8 +78,7 @@ obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd.o ...@@ -78,8 +78,7 @@ obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd.o
obj-$(CONFIG_SND_RME32) += snd-pcm.o snd-timer.o snd.o obj-$(CONFIG_SND_RME32) += snd-pcm.o snd-timer.o snd.o
obj-$(CONFIG_SND_RME96) += snd-pcm.o snd-timer.o snd.o obj-$(CONFIG_SND_RME96) += snd-pcm.o snd-timer.o snd.o
obj-$(CONFIG_SND_SONICVIBES) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_SONICVIBES) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_VIA686) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_VIA82XX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_VIA8233) += snd-pcm.o snd-timer.o snd.o
obj-$(CONFIG_SND_ALI5451) += snd.o snd-rawmidi.o snd-timer.o snd-pcm.o obj-$(CONFIG_SND_ALI5451) += snd.o snd-rawmidi.o snd-timer.o snd-pcm.o
obj-$(CONFIG_SND_CS46XX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_CS46XX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_EMU10K1) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_EMU10K1) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
......
...@@ -28,7 +28,5 @@ ...@@ -28,7 +28,5 @@
struct ioctl32_mapper hwdep_mappers[] = { struct ioctl32_mapper hwdep_mappers[] = {
{ SNDRV_HWDEP_IOCTL_PVERSION, NULL }, { SNDRV_HWDEP_IOCTL_PVERSION, NULL },
{ SNDRV_HWDEP_IOCTL_INFO, NULL }, { SNDRV_HWDEP_IOCTL_INFO, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_INFO, NULL },
{ 0 }, { 0 },
}; };
...@@ -47,14 +47,10 @@ int snd_ioctl32_register(struct ioctl32_mapper *mappers) ...@@ -47,14 +47,10 @@ int snd_ioctl32_register(struct ioctl32_mapper *mappers)
int err; int err;
struct ioctl32_mapper *m; struct ioctl32_mapper *m;
lock_kernel();
for (m = mappers; m->cmd; m++) { for (m = mappers; m->cmd; m++) {
err = register_ioctl32_conversion(m->cmd, m->handler); err = register_ioctl32_conversion(m->cmd, m->handler);
if (err < 0) { if (err >= 0)
unlock_kernel(); m->registered++;
return err;
}
m->registered++;
} }
return 0; return 0;
} }
...@@ -63,14 +59,12 @@ void snd_ioctl32_unregister(struct ioctl32_mapper *mappers) ...@@ -63,14 +59,12 @@ void snd_ioctl32_unregister(struct ioctl32_mapper *mappers)
{ {
struct ioctl32_mapper *m; struct ioctl32_mapper *m;
lock_kernel();
for (m = mappers; m->cmd; m++) { for (m = mappers; m->cmd; m++) {
if (m->registered) { if (m->registered) {
unregister_ioctl32_conversion(m->cmd); unregister_ioctl32_conversion(m->cmd);
m->registered = 0; m->registered = 0;
} }
} }
unlock_kernel();
} }
...@@ -100,36 +94,32 @@ static int _snd_ioctl32_ctl_elem_list(unsigned int fd, unsigned int cmd, unsigne ...@@ -100,36 +94,32 @@ static int _snd_ioctl32_ctl_elem_list(unsigned int fd, unsigned int cmd, unsigne
{ {
struct sndrv_ctl_elem_list32 data32; struct sndrv_ctl_elem_list32 data32;
struct sndrv_ctl_elem_list data; struct sndrv_ctl_elem_list data;
mm_segment_t oldseg = get_fs(); mm_segment_t oldseg;
int err; int err;
set_fs(KERNEL_DS); if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { return -EFAULT;
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.offset = data32.offset; data.offset = data32.offset;
data.space = data32.space; data.space = data32.space;
data.used = data32.used; data.used = data32.used;
data.count = data32.count; data.count = data32.count;
data.pids = A(data32.pids); data.pids = A(data32.pids);
oldseg = get_fs();
set_fs(KERNEL_DS);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
set_fs(oldseg);
if (err < 0) if (err < 0)
goto __err; return err;
/* copy the result */ /* copy the result */
data32.offset = data.offset; data32.offset = data.offset;
data32.space = data.space; data32.space = data.space;
data32.used = data.used; data32.used = data.used;
data32.count = data.count; data32.count = data.count;
//data.pids = data.pids; //data.pids = data.pids;
if (copy_to_user((void*)arg, &data32, sizeof(data32))) { if (copy_to_user((void*)arg, &data32, sizeof(data32)))
err = -EFAULT; return -EFAULT;
goto __err; return 0;
}
__err:
set_fs(oldseg);
return err;
} }
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_list, ctl_elem_list, SNDRV_CTL_IOCTL_ELEM_LIST); DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_list, ctl_elem_list, SNDRV_CTL_IOCTL_ELEM_LIST);
...@@ -171,22 +161,22 @@ static int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigne ...@@ -171,22 +161,22 @@ static int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigne
struct sndrv_ctl_elem_info data; struct sndrv_ctl_elem_info data;
struct sndrv_ctl_elem_info32 data32; struct sndrv_ctl_elem_info32 data32;
int err; int err;
mm_segment_t oldseg = get_fs(); mm_segment_t oldseg;
set_fs(KERNEL_DS); if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { return -EFAULT;
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.id = data32.id; data.id = data32.id;
/* we need to copy the item index. /* we need to copy the item index.
* hope this doesn't break anything.. * hope this doesn't break anything..
*/ */
data.value.enumerated.item = data32.value.enumerated.item; data.value.enumerated.item = data32.value.enumerated.item;
oldseg = get_fs();
set_fs(KERNEL_DS);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
set_fs(oldseg);
if (err < 0) if (err < 0)
goto __err; return err;
/* restore info to 32bit */ /* restore info to 32bit */
data32.id = data.id; data32.id = data.id;
data32.type = data.type; data32.type = data.type;
...@@ -215,10 +205,8 @@ static int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigne ...@@ -215,10 +205,8 @@ static int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigne
break; break;
} }
if (copy_to_user((void*)arg, &data32, sizeof(data32))) if (copy_to_user((void*)arg, &data32, sizeof(data32)))
err = -EFAULT; return -EFAULT;
__err: return 0;
set_fs(oldseg);
return err;
} }
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_info, ctl_elem_info, SNDRV_CTL_IOCTL_ELEM_INFO); DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_info, ctl_elem_info, SNDRV_CTL_IOCTL_ELEM_INFO);
...@@ -281,26 +269,20 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign ...@@ -281,26 +269,20 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign
struct sndrv_ctl_elem_value32 data32; struct sndrv_ctl_elem_value32 data32;
int err, i; int err, i;
int type; int type;
mm_segment_t oldseg = get_fs(); mm_segment_t oldseg;
set_fs(KERNEL_DS);
/* FIXME: check the sane ioctl.. */ /* FIXME: check the sane ioctl.. */
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
err = -EFAULT; return -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.id = data32.id; data.id = data32.id;
data.indirect = data32.indirect; data.indirect = data32.indirect;
if (data.indirect) /* FIXME: this is not correct for long arrays */ if (data.indirect) /* FIXME: this is not correct for long arrays */
data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr); data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr);
type = get_ctl_type(file, &data.id); type = get_ctl_type(file, &data.id);
if (type < 0) { if (type < 0)
err = type; return type;
goto __err;
}
if (! data.indirect) { if (! data.indirect) {
switch (type) { switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
...@@ -329,9 +311,12 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign ...@@ -329,9 +311,12 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign
} }
} }
oldseg = get_fs();
set_fs(KERNEL_DS);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
set_fs(oldseg);
if (err < 0) if (err < 0)
goto __err; return err;
/* restore info to 32bit */ /* restore info to 32bit */
if (! data.indirect) { if (! data.indirect) {
switch (type) { switch (type) {
...@@ -360,10 +345,8 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign ...@@ -360,10 +345,8 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign
} }
} }
if (copy_to_user((void*)arg, &data32, sizeof(data32))) if (copy_to_user((void*)arg, &data32, sizeof(data32)))
err = -EFAULT; return -EFAULT;
__err: return 0;
set_fs(oldseg);
return err;
} }
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_read, ctl_elem_value, SNDRV_CTL_IOCTL_ELEM_READ); DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_read, ctl_elem_value, SNDRV_CTL_IOCTL_ELEM_READ);
...@@ -392,6 +375,7 @@ static struct ioctl32_mapper control_mappers[] = { ...@@ -392,6 +375,7 @@ static struct ioctl32_mapper control_mappers[] = {
{ SNDRV_CTL_IOCTL_ELEM_LOCK, NULL }, { SNDRV_CTL_IOCTL_ELEM_LOCK, NULL },
{ SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL }, { SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL },
{ SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL }, { SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_INFO, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL }, { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL },
{ SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL }, { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL },
{ SNDRV_CTL_IOCTL_PCM_INFO, NULL }, { SNDRV_CTL_IOCTL_PCM_INFO, NULL },
...@@ -427,37 +411,13 @@ static void snd_ioctl32_done(void) ...@@ -427,37 +411,13 @@ static void snd_ioctl32_done(void)
static int __init snd_ioctl32_init(void) static int __init snd_ioctl32_init(void)
{ {
int err; snd_ioctl32_register(control_mappers);
snd_ioctl32_register(pcm_mappers);
err = snd_ioctl32_register(control_mappers); snd_ioctl32_register(rawmidi_mappers);
if (err < 0) snd_ioctl32_register(timer_mappers);
return err; snd_ioctl32_register(hwdep_mappers);
err = snd_ioctl32_register(pcm_mappers);
if (err < 0) {
snd_ioctl32_done();
return err;
}
err = snd_ioctl32_register(rawmidi_mappers);
if (err < 0) {
snd_ioctl32_done();
return err;
}
err = snd_ioctl32_register(timer_mappers);
if (err < 0) {
snd_ioctl32_done();
return err;
}
err = snd_ioctl32_register(hwdep_mappers);
if (err < 0) {
snd_ioctl32_done();
return err;
}
#ifdef CONFIG_SND_SEQUENCER #ifdef CONFIG_SND_SEQUENCER
err = snd_ioctl32_register(seq_mappers); snd_ioctl32_register(seq_mappers);
if (err < 0) {
snd_ioctl32_done();
return err;
}
#endif #endif
return 0; return 0;
} }
......
...@@ -60,27 +60,23 @@ static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long ...@@ -60,27 +60,23 @@ static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long
{\ {\
struct sndrv_##type##32 data32;\ struct sndrv_##type##32 data32;\
struct sndrv_##type data;\ struct sndrv_##type data;\
mm_segment_t oldseg = get_fs();\ mm_segment_t oldseg;\
int err;\ int err;\
set_fs(KERNEL_DS);\ if (copy_from_user(&data32, (void*)arg, sizeof(data32)))\
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {\ return -EFAULT;\
err = -EFAULT;\
goto __err;\
}\
memset(&data, 0, sizeof(data));\ memset(&data, 0, sizeof(data));\
convert_from_32(type, &data, &data32);\ convert_from_32(type, &data, &data32);\
oldseg = get_fs();\
set_fs(KERNEL_DS);\
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\ err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\
if (err < 0) \ if (err < 0) \
goto __err;\ return err;\
if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\ if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
convert_to_32(type, &data32, &data);\ convert_to_32(type, &data32, &data);\
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {\ if (copy_to_user((void*)arg, &data32, sizeof(data32)))\
err = -EFAULT;\ return -EFAULT;\
goto __err;\
}\
}\ }\
__err: set_fs(oldseg);\ return 0;\
return err;\
} }
#define DEFINE_ALSA_IOCTL_ENTRY(name,type,native_ctl) \ #define DEFINE_ALSA_IOCTL_ENTRY(name,type,native_ctl) \
......
...@@ -189,30 +189,26 @@ static int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long a ...@@ -189,30 +189,26 @@ static int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long a
{ {
struct sndrv_xferi32 data32; struct sndrv_xferi32 data32;
struct sndrv_xferi data; struct sndrv_xferi data;
mm_segment_t oldseg = get_fs(); mm_segment_t oldseg;
int err; int err;
set_fs(KERNEL_DS); if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { return -EFAULT;
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.result = data32.result; data.result = data32.result;
data.buf = A(data32.buf); data.buf = A(data32.buf);
data.frames = data32.frames; data.frames = data32.frames;
oldseg = get_fs();
set_fs(KERNEL_DS);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
set_fs(oldseg);
if (err < 0) if (err < 0)
goto __err; return err;
/* copy the result */ /* copy the result */
data32.result = data.result; data32.result = data.result;
if (copy_to_user((void*)arg, &data32, sizeof(data32))) { if (copy_to_user((void*)arg, &data32, sizeof(data32)))
err = -EFAULT; return -EFAULT;
goto __err; return 0;
}
__err:
set_fs(oldseg);
return err;
} }
...@@ -237,9 +233,7 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a ...@@ -237,9 +233,7 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
void *bufs[128]; void *bufs[128];
int err = 0, ch, i; int err = 0, ch, i;
u32 *bufptr; u32 *bufptr;
mm_segment_t oldseg = get_fs(); mm_segment_t oldseg;
set_fs(KERNEL_DS);
/* FIXME: need to check whether fop->ioctl is sane */ /* FIXME: need to check whether fop->ioctl is sane */
...@@ -250,41 +244,31 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a ...@@ -250,41 +244,31 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
/* check validty of the command */ /* check validty of the command */
switch (native_ctl) { switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES: case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
err = -EINVAL; return -EINVAL;
goto __err; if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
} return -EBADFD;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
err = -EBADFD;
goto __err;
}
break; break;
case SNDRV_PCM_IOCTL_READN_FRAMES: case SNDRV_PCM_IOCTL_READN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
err = -EINVAL; return -EINVAL;
goto __err;
}
break; break;
} }
if ((ch = substream->runtime->channels) > 128) { if ((ch = substream->runtime->channels) > 128)
err = -EINVAL; return -EINVAL;
goto __err; if (get_user(data32.frames, &srcptr->frames))
} return -EFAULT;
if (get_user(data32.frames, &srcptr->frames)) {
err = -EFAULT;
goto __err;
}
__get_user(data32.bufs, &srcptr->bufs); __get_user(data32.bufs, &srcptr->bufs);
bufptr = (u32*)TO_PTR(data32.bufs); bufptr = (u32*)TO_PTR(data32.bufs);
for (i = 0; i < ch; i++) { for (i = 0; i < ch; i++) {
u32 ptr; u32 ptr;
if (get_user(ptr, bufptr)) { if (get_user(ptr, bufptr))
err = -EFAULT; return -EFAULT;
goto __err;
}
bufs[ch] = (void*)TO_PTR(ptr); bufs[ch] = (void*)TO_PTR(ptr);
bufptr++; bufptr++;
} }
oldseg = get_fs();
set_fs(KERNEL_DS);
switch (native_ctl) { switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES: case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
err = snd_pcm_lib_writev(substream, bufs, data32.frames); err = snd_pcm_lib_writev(substream, bufs, data32.frames);
...@@ -293,14 +277,12 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a ...@@ -293,14 +277,12 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
err = snd_pcm_lib_readv(substream, bufs, data32.frames); err = snd_pcm_lib_readv(substream, bufs, data32.frames);
break; break;
} }
set_fs(oldseg);
if (err < 0) if (err < 0)
goto __err; return err;
if (put_user(err, &srcptr->result)) if (put_user(err, &srcptr->result))
err = -EFAULT; return -EFAULT;
__err: return 0;
set_fs(oldseg);
return err < 0 ? err : 0;
} }
...@@ -363,24 +345,22 @@ static int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, uns ...@@ -363,24 +345,22 @@ static int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, uns
{ {
struct sndrv_pcm_hw_params_old32 data32; struct sndrv_pcm_hw_params_old32 data32;
struct sndrv_pcm_hw_params data; struct sndrv_pcm_hw_params data;
mm_segment_t oldseg = get_fs(); mm_segment_t oldseg;
int err; int err;
set_fs(KERNEL_DS);
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
err = -EFAULT; return -EFAULT;
goto __err;
}
snd_pcm_hw_convert_from_old_params(&data, &data32); snd_pcm_hw_convert_from_old_params(&data, &data32);
oldseg = get_fs();
set_fs(KERNEL_DS);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
set_fs(oldseg);
if (err < 0) if (err < 0)
goto __err; return err;
snd_pcm_hw_convert_to_old_params(&data32, &data); snd_pcm_hw_convert_to_old_params(&data32, &data);
if (copy_to_user((void*)arg, &data32, sizeof(data32))) { if (copy_to_user((void*)arg, &data32, sizeof(data32)))
err = -EFAULT; return -EFAULT;
goto __err; return 0;
}
__err: set_fs(oldseg);
return err;
} }
...@@ -451,9 +431,5 @@ struct ioctl32_mapper pcm_mappers[] = { ...@@ -451,9 +431,5 @@ struct ioctl32_mapper pcm_mappers[] = {
{ SNDRV_PCM_IOCTL_LINK, NULL }, { SNDRV_PCM_IOCTL_LINK, NULL },
{ SNDRV_PCM_IOCTL_UNLINK, NULL }, { SNDRV_PCM_IOCTL_UNLINK, NULL },
{ SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL },
{ SNDRV_CTL_IOCTL_PCM_INFO, NULL },
{ SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL },
{ 0 }, { 0 },
}; };
...@@ -1169,10 +1169,14 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int free_flag) ...@@ -1169,10 +1169,14 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int free_flag)
return err; return err;
} }
mixer->card = card; mixer->card = card;
strcpy(mixer->name, name); if (*card->mixername) {
strncpy(mixer->name, card->mixername, sizeof(mixer->name) - 1);
mixer->name[sizeof(mixer->name)-1] = 0;
} else
strcpy(mixer->name, name);
snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIXERS, snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIXERS,
card->number, card->number,
name); mixer->name);
for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++) for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++)
mixer->slots[idx].number = idx; mixer->slots[idx].number = idx;
card->mixer_oss = mixer; card->mixer_oss = mixer;
......
...@@ -80,6 +80,9 @@ int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream) ...@@ -80,6 +80,9 @@ int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream)
{ {
struct snd_sg_buf *sgbuf; struct snd_sg_buf *sgbuf;
/* return in case, when sgbuf is not initialized */
if (substream->dma_private == NULL)
return -EINVAL;
sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL); sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL);
sgbuf_shrink(sgbuf, 0); sgbuf_shrink(sgbuf, 0);
if (sgbuf->table) if (sgbuf->table)
......
...@@ -67,7 +67,7 @@ obj-$(CONFIG_SND_FM801) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-mid ...@@ -67,7 +67,7 @@ obj-$(CONFIG_SND_FM801) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-mid
obj-$(CONFIG_SND_ICE1712) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.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_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_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_VIA686) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.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_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_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_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
......
...@@ -146,6 +146,8 @@ snd_seq_oss_synth_register(snd_seq_device_t *dev) ...@@ -146,6 +146,8 @@ snd_seq_oss_synth_register(snd_seq_device_t *dev)
debug_printk(("synth %s registered %d\n", rec->name, i)); debug_printk(("synth %s registered %d\n", rec->name, i));
spin_unlock_irqrestore(&register_lock, flags); spin_unlock_irqrestore(&register_lock, flags);
dev->driver_data = rec; dev->driver_data = rec;
if (i < SNDRV_CARDS)
snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name);
return 0; return 0;
} }
...@@ -176,6 +178,8 @@ snd_seq_oss_synth_unregister(snd_seq_device_t *dev) ...@@ -176,6 +178,8 @@ snd_seq_oss_synth_unregister(snd_seq_device_t *dev)
max_synth_devs = index + 1; max_synth_devs = index + 1;
} }
spin_unlock_irqrestore(&register_lock, flags); spin_unlock_irqrestore(&register_lock, flags);
if (rec->seq_device < SNDRV_CARDS)
snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, rec->seq_device, NULL);
snd_use_lock_sync(&rec->use_lock); snd_use_lock_sync(&rec->use_lock);
kfree(rec); kfree(rec);
......
...@@ -35,7 +35,7 @@ obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o ...@@ -35,7 +35,7 @@ obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o
obj-$(CONFIG_SND_INTEL8X0) += snd-mpu401-uart.o obj-$(CONFIG_SND_INTEL8X0) += snd-mpu401-uart.o
obj-$(CONFIG_SND_SONICVIBES) += snd-mpu401-uart.o obj-$(CONFIG_SND_SONICVIBES) += snd-mpu401-uart.o
obj-$(CONFIG_SND_VIA686) += snd-mpu401-uart.o obj-$(CONFIG_SND_VIA82XX) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ALI5451) += snd-mpu401-uart.o obj-$(CONFIG_SND_ALI5451) += snd-mpu401-uart.o
obj-$(CONFIG_SND_TRIDENT) += snd-mpu401-uart.o obj-$(CONFIG_SND_TRIDENT) += snd-mpu401-uart.o
obj-$(CONFIG_SND_YMFPCI) += snd-mpu401-uart.o obj-$(CONFIG_SND_YMFPCI) += snd-mpu401-uart.o
......
...@@ -260,11 +260,15 @@ static int snd_i2c_bit_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, ...@@ -260,11 +260,15 @@ static int snd_i2c_bit_sendbytes(snd_i2c_device_t *device, unsigned char *bytes,
if (device->flags & SND_I2C_DEVICE_ADDRTEN) if (device->flags & SND_I2C_DEVICE_ADDRTEN)
return -EIO; /* not yet implemented */ return -EIO; /* not yet implemented */
snd_i2c_bit_start(bus); snd_i2c_bit_start(bus);
if ((err = snd_i2c_bit_sendbyte(bus, device->addr << 1)) < 0) if ((err = snd_i2c_bit_sendbyte(bus, device->addr << 1)) < 0) {
snd_i2c_bit_hw_stop(bus);
return err; return err;
}
while (count-- > 0) { while (count-- > 0) {
if ((err = snd_i2c_bit_sendbyte(bus, *bytes++)) < 0) if ((err = snd_i2c_bit_sendbyte(bus, *bytes++)) < 0) {
snd_i2c_bit_hw_stop(bus);
return err; return err;
}
res++; res++;
} }
snd_i2c_bit_stop(bus); snd_i2c_bit_stop(bus);
...@@ -279,11 +283,15 @@ static int snd_i2c_bit_readbytes(snd_i2c_device_t *device, unsigned char *bytes, ...@@ -279,11 +283,15 @@ static int snd_i2c_bit_readbytes(snd_i2c_device_t *device, unsigned char *bytes,
if (device->flags & SND_I2C_DEVICE_ADDRTEN) if (device->flags & SND_I2C_DEVICE_ADDRTEN)
return -EIO; /* not yet implemented */ return -EIO; /* not yet implemented */
snd_i2c_bit_start(bus); snd_i2c_bit_start(bus);
if ((err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1)) < 0) if ((err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1)) < 0) {
snd_i2c_bit_hw_stop(bus);
return err; return err;
}
while (count-- > 0) { while (count-- > 0) {
if ((err = snd_i2c_bit_readbyte(bus, count == 0)) < 0) if ((err = snd_i2c_bit_readbyte(bus, count == 0)) < 0) {
snd_i2c_bit_hw_stop(bus);
return err; return err;
}
*bytes++ = (unsigned char)err; *bytes++ = (unsigned char)err;
res++; res++;
} }
...@@ -300,10 +308,9 @@ static int snd_i2c_bit_probeaddr(snd_i2c_bus_t *bus, unsigned short addr) ...@@ -300,10 +308,9 @@ static int snd_i2c_bit_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
if (addr & 0x7f80) /* invalid address */ if (addr & 0x7f80) /* invalid address */
return -EINVAL; return -EINVAL;
snd_i2c_bit_start(bus); snd_i2c_bit_start(bus);
if ((err = snd_i2c_bit_sendbyte(bus, addr << 1)) < 0) err = snd_i2c_bit_sendbyte(bus, addr << 1);
return err;
snd_i2c_bit_stop(bus); snd_i2c_bit_stop(bus);
return 1; /* present */ return err;
} }
EXPORT_SYMBOL(snd_i2c_bus_create); EXPORT_SYMBOL(snd_i2c_bus_create);
......
...@@ -82,8 +82,5 @@ CONFIG_SND_INTEL8X0 ...@@ -82,8 +82,5 @@ CONFIG_SND_INTEL8X0
CONFIG_SND_SONICVIBES CONFIG_SND_SONICVIBES
Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards. Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards.
CONFIG_SND_VIA686 CONFIG_SND_VIA82XX
Say 'Y' or 'M' to include support for VIA VT82C686A/B South Bridge. Say 'Y' or 'M' to include support for VIA VT82C686A/B, VT8233 South Bridge.
CONFIG_SND_VIA8233
Say 'Y' or 'M' to include support for VIA VT8233 South Bridge.
...@@ -27,8 +27,7 @@ dep_tristate 'ForteMedia FM801' CONFIG_SND_FM801 $CONFIG_SND ...@@ -27,8 +27,7 @@ dep_tristate 'ForteMedia FM801' CONFIG_SND_FM801 $CONFIG_SND
dep_tristate 'ICEnsemble ICE1712 (Envy24)' CONFIG_SND_ICE1712 $CONFIG_SND dep_tristate 'ICEnsemble ICE1712 (Envy24)' CONFIG_SND_ICE1712 $CONFIG_SND
dep_tristate 'Intel i810/i820/i830/i840/MX440 integrated audio' CONFIG_SND_INTEL8X0 $CONFIG_SND dep_tristate 'Intel i810/i820/i830/i840/MX440 integrated audio' CONFIG_SND_INTEL8X0 $CONFIG_SND
dep_tristate 'S3 SonicVibes' CONFIG_SND_SONICVIBES $CONFIG_SND dep_tristate 'S3 SonicVibes' CONFIG_SND_SONICVIBES $CONFIG_SND
dep_tristate 'VIA 82C686A/B South Bridge' CONFIG_SND_VIA686 $CONFIG_SND dep_tristate 'VIA 82C686A/B, 8233 South Bridge' CONFIG_SND_VIA82XX $CONFIG_SND
dep_tristate 'VIA 8233 South Bridge' CONFIG_SND_VIA8233 $CONFIG_SND
# define gameport if necessary # define gameport if necessary
if [ "$CONFIG_INPUT_GAMEPORT" != "n" ]; then if [ "$CONFIG_INPUT_GAMEPORT" != "n" ]; then
......
...@@ -17,8 +17,7 @@ snd-maestro3-objs := maestro3.o ...@@ -17,8 +17,7 @@ snd-maestro3-objs := maestro3.o
snd-rme32-objs := rme32.o snd-rme32-objs := rme32.o
snd-rme96-objs := rme96.o snd-rme96-objs := rme96.o
snd-sonicvibes-objs := sonicvibes.o snd-sonicvibes-objs := sonicvibes.o
snd-via686-objs := via686.o snd-via82xx-objs := via82xx.o
snd-via8233-objs := via8233.o
# Toplevel Module Dependency # Toplevel Module Dependency
obj-$(CONFIG_SND_ALS4000) += snd-als4000.o obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
...@@ -35,8 +34,7 @@ obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o ...@@ -35,8 +34,7 @@ obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o
obj-$(CONFIG_SND_RME32) += snd-rme32.o obj-$(CONFIG_SND_RME32) += snd-rme32.o
obj-$(CONFIG_SND_RME96) += snd-rme96.o obj-$(CONFIG_SND_RME96) += snd-rme96.o
obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
obj-$(CONFIG_SND_VIA686) += snd-via686.o obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
obj-$(CONFIG_SND_VIA8233) += snd-via8233.o
obj-$(CONFIG_SND) += ac97/ ali5451/ cs46xx/ emu10k1/ korg1212/ nm256/ rme9652/ trident/ ymfpci/ obj-$(CONFIG_SND) += ac97/ ali5451/ cs46xx/ emu10k1/ korg1212/ nm256/ rme9652/ trident/ ymfpci/
......
...@@ -17,8 +17,7 @@ obj-$(CONFIG_SND_FM801) += snd-ac97-codec.o ...@@ -17,8 +17,7 @@ obj-$(CONFIG_SND_FM801) += snd-ac97-codec.o
obj-$(CONFIG_SND_ICE1712) += snd-ac97-codec.o obj-$(CONFIG_SND_ICE1712) += snd-ac97-codec.o
obj-$(CONFIG_SND_INTEL8X0) += snd-ac97-codec.o obj-$(CONFIG_SND_INTEL8X0) += snd-ac97-codec.o
obj-$(CONFIG_SND_MAESTRO3) += snd-ac97-codec.o obj-$(CONFIG_SND_MAESTRO3) += snd-ac97-codec.o
obj-$(CONFIG_SND_VIA686) += snd-ac97-codec.o obj-$(CONFIG_SND_VIA82XX) += snd-ac97-codec.o
obj-$(CONFIG_SND_VIA8233) += snd-ac97-codec.o
obj-$(CONFIG_SND_ALI5451) += snd-ac97-codec.o obj-$(CONFIG_SND_ALI5451) += snd-ac97-codec.o
obj-$(CONFIG_SND_CS46XX) += snd-ac97-codec.o obj-$(CONFIG_SND_CS46XX) += snd-ac97-codec.o
obj-$(CONFIG_SND_EMU10K1) += snd-ac97-codec.o obj-$(CONFIG_SND_EMU10K1) += snd-ac97-codec.o
......
...@@ -65,6 +65,7 @@ static const ac97_codec_id_t snd_ac97_codec_id_vendors[] = { ...@@ -65,6 +65,7 @@ static const ac97_codec_id_t snd_ac97_codec_id_vendors[] = {
{ 0x41445300, 0xffffff00, "Analog Devices", NULL }, { 0x41445300, 0xffffff00, "Analog Devices", NULL },
{ 0x414c4300, 0xffffff00, "Realtek", NULL }, { 0x414c4300, 0xffffff00, "Realtek", NULL },
{ 0x414c4700, 0xffffff00, "Avance Logic", NULL }, { 0x414c4700, 0xffffff00, "Avance Logic", NULL },
{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL },
{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL }, { 0x43525900, 0xffffff00, "Cirrus Logic", NULL },
{ 0x43585400, 0xffffff00, "Conexant", NULL }, { 0x43585400, 0xffffff00, "Conexant", NULL },
{ 0x45838300, 0xffffff00, "ESS Technology", NULL }, { 0x45838300, 0xffffff00, "ESS Technology", NULL },
...@@ -95,6 +96,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { ...@@ -95,6 +96,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885 }, { 0x41445360, 0xffffffff, "AD1885", patch_ad1885 },
{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886 }, { 0x41445361, 0xffffffff, "AD1886", patch_ad1886 },
{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881 }, { 0x41445362, 0xffffffff, "AD1887", patch_ad1881 },
{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881 },
{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1881 }, { 0x41445372, 0xffffffff, "AD1981A", patch_ad1881 },
{ 0x414c4300, 0xfffffff0, "RL5306", NULL }, { 0x414c4300, 0xfffffff0, "RL5306", NULL },
{ 0x414c4310, 0xfffffff0, "RL5382", NULL }, { 0x414c4310, 0xfffffff0, "RL5382", NULL },
...@@ -104,6 +106,8 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { ...@@ -104,6 +106,8 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x414c4730, 0xffffffff, "ALC101", NULL }, { 0x414c4730, 0xffffffff, "ALC101", NULL },
{ 0x414c4740, 0xfffffff0, "ALC202", NULL }, { 0x414c4740, 0xfffffff0, "ALC202", NULL },
{ 0x414c4750, 0xfffffff0, "ALC250", NULL }, { 0x414c4750, 0xfffffff0, "ALC250", NULL },
{ 0x434d4941, 0xffffffff, "CMI9738", NULL },
{ 0x434d4961, 0xffffffff, "CMI9739", NULL },
{ 0x43525900, 0xfffffff8, "CS4297", NULL }, { 0x43525900, 0xfffffff8, "CS4297", NULL },
{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif }, { 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif },
{ 0x43525920, 0xfffffff8, "CS4294/4298", NULL }, { 0x43525920, 0xfffffff8, "CS4294/4298", NULL },
...@@ -122,6 +126,8 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { ...@@ -122,6 +126,8 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x4e534331, 0xffffffff, "LM4549", NULL }, { 0x4e534331, 0xffffffff, "LM4549", NULL },
{ 0x53494c22, 0xffffffff, "Si3036", NULL }, { 0x53494c22, 0xffffffff, "Si3036", NULL },
{ 0x53494c23, 0xffffffff, "Si3038", NULL }, { 0x53494c23, 0xffffffff, "Si3038", NULL },
{ 0x54524102, 0xffffffff, "TR28022", NULL },
{ 0x54524106, 0xffffffff, "TR28026", NULL },
{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028 }, // added by xin jin [07/09/99] { 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028 }, // added by xin jin [07/09/99]
{ 0x54524123, 0xffffffff, "TR28602", NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] { 0x54524123, 0xffffffff, "TR28602", NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL }, { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL },
...@@ -130,14 +136,19 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { ...@@ -130,14 +136,19 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x574d4c00, 0xffffffff, "WM9701A", patch_wolfson00 }, { 0x574d4c00, 0xffffffff, "WM9701A", patch_wolfson00 },
{ 0x574d4c03, 0xffffffff, "WM9703/9707", patch_wolfson03 }, { 0x574d4c03, 0xffffffff, "WM9703/9707", patch_wolfson03 },
{ 0x574d4c04, 0xffffffff, "WM9704 (quad)", patch_wolfson04 }, { 0x574d4c04, 0xffffffff, "WM9704 (quad)", patch_wolfson04 },
{ 0x574d4c05, 0xffffffff, "WM9705", NULL }, // patch?
{ 0x594d4800, 0xffffffff, "YMF743", NULL }, { 0x594d4800, 0xffffffff, "YMF743", NULL },
{ 0x594d4802, 0xffffffff, "YMF752", NULL },
{ 0x594d4803, 0xffffffff, "YMF753", NULL },
{ 0x83847600, 0xffffffff, "STAC9700/83/84", NULL }, { 0x83847600, 0xffffffff, "STAC9700/83/84", NULL },
{ 0x83847604, 0xffffffff, "STAC9701/3/4/5", NULL }, { 0x83847604, 0xffffffff, "STAC9701/3/4/5", NULL },
{ 0x83847605, 0xffffffff, "STAC9704", NULL }, { 0x83847605, 0xffffffff, "STAC9704", NULL },
{ 0x83847608, 0xffffffff, "STAC9708/11", patch_sigmatel_stac9708 }, { 0x83847608, 0xffffffff, "STAC9708/11", patch_sigmatel_stac9708 },
{ 0x83847609, 0xffffffff, "STAC9721/23", patch_sigmatel_stac9721 }, { 0x83847609, 0xffffffff, "STAC9721/23", patch_sigmatel_stac9721 },
{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744 }, { 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744 },
{ 0x83847650, 0xffffffff, "STAC9750/51", NULL }, // patch?
{ 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756 }, { 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756 },
{ 0x83847666, 0xffffffff, "STAC9766/67", NULL }, // patch?
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
...@@ -201,6 +212,7 @@ static int snd_ac97_valid_reg(ac97_t *ac97, unsigned short reg) ...@@ -201,6 +212,7 @@ static int snd_ac97_valid_reg(ac97_t *ac97, unsigned short reg)
return 1; return 1;
case AC97_ID_AD1885: /* AD1885 */ case AC97_ID_AD1885: /* AD1885 */
case AC97_ID_AD1886: /* AD1886 */ case AC97_ID_AD1886: /* AD1886 */
case AC97_ID_AD1886A: /* AD1886A - !!verify!! --jk */
case AC97_ID_AD1887: /* AD1887 - !!verify!! --jk */ case AC97_ID_AD1887: /* AD1887 - !!verify!! --jk */
if (reg == 0x5a) if (reg == 0x5a)
return 1; return 1;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define AC97_ID_AD1885 0x41445360 #define AC97_ID_AD1885 0x41445360
#define AC97_ID_AD1886 0x41445361 #define AC97_ID_AD1886 0x41445361
#define AC97_ID_AD1887 0x41445362 #define AC97_ID_AD1887 0x41445362
#define AC97_ID_AD1886A 0x41445363
#define AC97_ID_TR28028 0x54524108 #define AC97_ID_TR28028 0x54524108
#define AC97_ID_STAC9700 0x83847600 #define AC97_ID_STAC9700 0x83847600
#define AC97_ID_STAC9704 0x83847604 #define AC97_ID_STAC9704 0x83847604
......
...@@ -629,6 +629,9 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97, ...@@ -629,6 +629,9 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
cs4281_t *chip = snd_magic_cast(cs4281_t, ac97->private_data, return -ENXIO); cs4281_t *chip = snd_magic_cast(cs4281_t, ac97->private_data, return -ENXIO);
int count; int count;
unsigned short result; unsigned short result;
// FIXME: volatile is necessary in the following due to a bug of
// some gcc versions
volatile int ac97_num = ((volatile ac97_t *)ac97)->num;
/* /*
* 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
...@@ -639,7 +642,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97, ...@@ -639,7 +642,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
* 6. Read ACSTS = Status Register = 464h, check VSTS bit * 6. Read ACSTS = Status Register = 464h, check VSTS bit
*/ */
snd_cs4281_peekBA0(chip, ac97->num ? BA0_ACSDA2 : BA0_ACSDA); snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSDA2 : BA0_ACSDA);
/* /*
* Setup the AC97 control registers on the CS461x to send the * Setup the AC97 control registers on the CS461x to send the
...@@ -658,7 +661,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97, ...@@ -658,7 +661,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
snd_cs4281_pokeBA0(chip, BA0_ACCDA, 0); snd_cs4281_pokeBA0(chip, BA0_ACCDA, 0);
snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_CRW | snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_CRW |
BA0_ACCTL_VFRM | BA0_ACCTL_ESYN | BA0_ACCTL_VFRM | BA0_ACCTL_ESYN |
(ac97->num ? BA0_ACCTL_TC : 0)); (ac97_num ? BA0_ACCTL_TC : 0));
/* /*
...@@ -691,7 +694,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97, ...@@ -691,7 +694,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
* ACSTS = Status Register = 464h * ACSTS = Status Register = 464h
* VSTS - Valid Status * VSTS - Valid Status
*/ */
if (snd_cs4281_peekBA0(chip, ac97->num ? BA0_ACSTS2 : BA0_ACSTS) & BA0_ACSTS_VSTS) if (snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSTS2 : BA0_ACSTS) & BA0_ACSTS_VSTS)
goto __ok2; goto __ok2;
udelay(10); udelay(10);
} }
...@@ -705,7 +708,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97, ...@@ -705,7 +708,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
* Read the data returned from the AC97 register. * Read the data returned from the AC97 register.
* ACSDA = Status Data Register = 474h * ACSDA = Status Data Register = 474h
*/ */
result = snd_cs4281_peekBA0(chip, ac97->num ? BA0_ACSDA2 : BA0_ACSDA); result = snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSDA2 : BA0_ACSDA);
__end: __end:
return result; return result;
...@@ -2107,7 +2110,8 @@ static void cs4281_suspend(cs4281_t *chip) ...@@ -2107,7 +2110,8 @@ static void cs4281_suspend(cs4281_t *chip)
/* remember the status registers */ /* remember the status registers */
for (i = 0; number_of(saved_regs); i++) for (i = 0; number_of(saved_regs); i++)
chip->suspend_regs[i] = snd_cs4281_peekBA0(chip, saved_regs[i]); if (saved_regs[i])
chip->suspend_regs[i] = snd_cs4281_peekBA0(chip, saved_regs[i]);
/* Turn off the serial ports. */ /* Turn off the serial ports. */
snd_cs4281_pokeBA0(chip, BA0_SERMC, 0); snd_cs4281_pokeBA0(chip, BA0_SERMC, 0);
...@@ -2150,7 +2154,8 @@ static void cs4281_resume(cs4281_t *chip) ...@@ -2150,7 +2154,8 @@ static void cs4281_resume(cs4281_t *chip)
/* restore the status registers */ /* restore the status registers */
for (i = 0; number_of(saved_regs); i++) for (i = 0; number_of(saved_regs); i++)
snd_cs4281_pokeBA0(chip, saved_regs[i], chip->suspend_regs[i]); if (saved_regs[i])
snd_cs4281_pokeBA0(chip, saved_regs[i], chip->suspend_regs[i]);
if (chip->ac97) if (chip->ac97)
snd_ac97_resume(chip->ac97); snd_ac97_resume(chip->ac97);
......
...@@ -3239,6 +3239,9 @@ int __devinit snd_cs46xx_create(snd_card_t * card, ...@@ -3239,6 +3239,9 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
if (chip == NULL) if (chip == NULL)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->reg_lock);
#ifdef CONFIG_SND_CS46XX_NEW_DSP
init_MUTEX(&chip->spos_mutex);
#endif
chip->card = card; chip->card = card;
chip->pci = pci; chip->pci = pci;
chip->capt.hw_size = PAGE_SIZE; chip->capt.hw_size = PAGE_SIZE;
......
...@@ -1298,6 +1298,7 @@ static struct { ...@@ -1298,6 +1298,7 @@ static struct {
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
{ .vid = PCI_ANY_ID, .did = PCI_ANY_ID } { .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
}; };
......
/* /*
* Driver for ESS Solo-1 (ES1938, ES1946) soundcard * Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard
* Copyright (c) by Jaromir Koutek <miri@punknet.cz>, * Copyright (c) by Jaromir Koutek <miri@punknet.cz>,
* Jaroslav Kysela <perex@suse.cz>, * Jaroslav Kysela <perex@suse.cz>,
* Thomas Sailer <sailer@ife.ee.ethz.ch>, * Thomas Sailer <sailer@ife.ee.ethz.ch>,
...@@ -70,6 +70,8 @@ MODULE_DESCRIPTION("ESS Solo-1"); ...@@ -70,6 +70,8 @@ MODULE_DESCRIPTION("ESS Solo-1");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}"); MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{ESS,ES1938}," MODULE_DEVICES("{{ESS,ES1938},"
"{ESS,ES1946},"
"{ESS,ES1969},"
"{TerraTec,128i PCI}}"); "{TerraTec,128i PCI}}");
#ifndef PCI_VENDOR_ID_ESS #ifndef PCI_VENDOR_ID_ESS
......
...@@ -2501,11 +2501,13 @@ static int snd_es1968_set_power_state(snd_card_t *card, unsigned int power_state ...@@ -2501,11 +2501,13 @@ static int snd_es1968_set_power_state(snd_card_t *card, unsigned int power_state
static int snd_es1968_free(es1968_t *chip) static int snd_es1968_free(es1968_t *chip)
{ {
if (chip->res_io_port)
snd_es1968_reset(chip);
snd_es1968_set_acpi(chip, ACPI_D3); snd_es1968_set_acpi(chip, ACPI_D3);
chip->master_switch = NULL; chip->master_switch = NULL;
chip->master_volume = NULL; chip->master_volume = NULL;
if (chip->res_io_port) { if (chip->res_io_port) {
snd_es1968_reset(chip);
release_resource(chip->res_io_port); release_resource(chip->res_io_port);
kfree_nocheck(chip->res_io_port); kfree_nocheck(chip->res_io_port);
} }
......
...@@ -414,7 +414,8 @@ MODULE_PARM_SYNTAX(snd_omni, SNDRV_ENABLED "," SNDRV_ENABLE_DESC); ...@@ -414,7 +414,8 @@ MODULE_PARM_SYNTAX(snd_omni, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
#define ICE1712_6FIRE_TX2 0x40 /* MIDI2 */ #define ICE1712_6FIRE_TX2 0x40 /* MIDI2 */
#define ICE1712_6FIRE_RX2 0x80 /* MIDI2 */ #define ICE1712_6FIRE_RX2 0x80 /* MIDI2 */
#define ICE1712_6FIRE_CS8427_ADDR (0x22>>1) /* ?? */ #define ICE1712_6FIRE_PCF9554_ADDR (0x40>>1)
#define ICE1712_6FIRE_CS8427_ADDR (0x22>>1)
/* /*
* DMA mode values * DMA mode values
...@@ -509,7 +510,7 @@ struct _snd_ice1712 { ...@@ -509,7 +510,7 @@ struct _snd_ice1712 {
snd_i2c_device_t *cs8404; /* CS8404A I2C device */ snd_i2c_device_t *cs8404; /* CS8404A I2C device */
snd_i2c_device_t *cs8427; /* CS8427 I2C device */ snd_i2c_device_t *cs8427; /* CS8427 I2C device */
snd_i2c_device_t *pcf8574[2]; /* PCF8574 Output/Input (EWS88MT) */ snd_i2c_device_t *pcf8574[2]; /* PCF8574 Output/Input (EWS88MT) */
snd_i2c_device_t *pcf8575; /* PCF8575 (EWS88D) */ snd_i2c_device_t *pcf8575; /* PCF8575 (EWS88D) / PCF9554 (6Fire) */
unsigned char cs8403_spdif_bits; unsigned char cs8403_spdif_bits;
unsigned char cs8403_spdif_stream_bits; unsigned char cs8403_spdif_stream_bits;
...@@ -2411,14 +2412,13 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice) ...@@ -2411,14 +2412,13 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
ac97.read = snd_ice1712_ac97_read; ac97.read = snd_ice1712_ac97_read;
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)
printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n"); printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");
// return err; else {
} else {
if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0) if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0)
return err; return err;
return 0;
} }
return 0;
} }
/* hmm.. can we have both consumer and pro ac97 mixers? */ /* hmm.. can we have both consumer and pro ac97 mixers? */
if (! (ice->eeprom.aclink & ICE1712_CFG_PRO_I2S)) { if (! (ice->eeprom.aclink & ICE1712_CFG_PRO_I2S)) {
...@@ -2428,11 +2428,10 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice) ...@@ -2428,11 +2428,10 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
ac97.read = snd_ice1712_pro_ac97_read; ac97.read = snd_ice1712_pro_ac97_read;
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)
printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
// return err; else
} return 0;
return 0;
} }
/* I2S mixer only */ /* I2S mixer only */
strcat(ice->card->mixername, "ICE1712 - multitrack"); strcat(ice->card->mixername, "ICE1712 - multitrack");
...@@ -3111,7 +3110,7 @@ static snd_kcontrol_new_t snd_ice1712_mixer_pro_peak __devinitdata = { ...@@ -3111,7 +3110,7 @@ static snd_kcontrol_new_t snd_ice1712_mixer_pro_peak __devinitdata = {
static int snd_ice1712_ewx_io_sense_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ static int snd_ice1712_ewx_io_sense_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){
static char *texts[4] = { static char *texts[2] = {
"+4dBu", "-10dBV", "+4dBu", "-10dBV",
}; };
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
...@@ -3354,26 +3353,32 @@ static snd_kcontrol_new_t snd_ice1712_ews88d_controls[] __devinitdata = { ...@@ -3354,26 +3353,32 @@ static snd_kcontrol_new_t snd_ice1712_ews88d_controls[] __devinitdata = {
* DMX 6Fire controls * DMX 6Fire controls
*/ */
#if 0 // XXX not working yet #define PCF9554_REG_INPUT 0
static int snd_ice1712_6fire_read_pca(ice1712_t *ice) #define PCF9554_REG_OUTPUT 1
#define PCF9554_REG_POLARITY 2
#define PCF9554_REG_CONFIG 3
static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg)
{ {
unsigned char byte; unsigned char byte;
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
byte = 0; /* read port */ byte = reg;
snd_i2c_sendbytes(ice->pcf8575, &byte, 1); snd_i2c_sendbytes(ice->pcf8575, &byte, 1);
byte = 0;
if (snd_i2c_readbytes(ice->pcf8575, &byte, 1) != 1) { if (snd_i2c_readbytes(ice->pcf8575, &byte, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
printk("cannot read pca\n");
return -EIO; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return byte; return byte;
} }
static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char data) static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data)
{ {
unsigned char bytes[2]; unsigned char bytes[2];
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
bytes[0] = 1; /* write port */ bytes[0] = reg;
bytes[1] = data; bytes[1] = data;
if (snd_i2c_sendbytes(ice->pcf8575, bytes, 2) != 2) { if (snd_i2c_sendbytes(ice->pcf8575, bytes, 2) != 2) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
...@@ -3399,7 +3404,7 @@ static int snd_ice1712_6fire_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_ ...@@ -3399,7 +3404,7 @@ static int snd_ice1712_6fire_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_
int invert = (kcontrol->private_value >> 8) & 1; int invert = (kcontrol->private_value >> 8) & 1;
int data; int data;
if ((data = snd_ice1712_6fire_read_pca(ice)) < 0) if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
return data; return data;
data = (data >> shift) & 1; data = (data >> shift) & 1;
if (invert) if (invert)
...@@ -3415,7 +3420,7 @@ static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_ ...@@ -3415,7 +3420,7 @@ static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_
int invert = (kcontrol->private_value >> 8) & 1; int invert = (kcontrol->private_value >> 8) & 1;
int data, ndata; int data, ndata;
if ((data = snd_ice1712_6fire_read_pca(ice)) < 0) if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
return data; return data;
ndata = data & ~(1 << shift); ndata = data & ~(1 << shift);
if (ucontrol->value.integer.value[0]) if (ucontrol->value.integer.value[0])
...@@ -3423,27 +3428,77 @@ static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_ ...@@ -3423,27 +3428,77 @@ static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_
if (invert) if (invert)
ndata ^= (1 << shift); ndata ^= (1 << shift);
if (data != ndata) { if (data != ndata) {
snd_ice1712_6fire_write_pca(ice, (unsigned char)ndata); snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
return 1; return 1;
} }
return 0; return 0;
} }
#define DMX6FIRE_CONTROL(xiface, xname, xshift, xinvert, xaccess) \ static int snd_ice1712_6fire_select_input_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{ .iface = xiface,\ {
static char *texts[4] = {
"Internal", "Front Input", "Rear Input", "Wave Table"
};
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 4;
if (uinfo->value.enumerated.item >= 4)
uinfo->value.enumerated.item = 1;
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
return 0;
}
static int snd_ice1712_6fire_select_input_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ice1712_t *ice = snd_kcontrol_chip(kcontrol);
int data;
if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
return data;
ucontrol->value.integer.value[0] = data & 3;
return 0;
}
static int snd_ice1712_6fire_select_input_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ice1712_t *ice = snd_kcontrol_chip(kcontrol);
int data, ndata;
if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
return data;
ndata = data & ~3;
ndata |= (ucontrol->value.integer.value[0] & 3);
if (data != ndata) {
snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
return 1;
}
return 0;
}
#define DMX6FIRE_CONTROL(xname, xshift, xinvert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
.name = xname,\ .name = xname,\
.access = xaccess,\
.info = snd_ice1712_6fire_control_info,\ .info = snd_ice1712_6fire_control_info,\
.get = snd_ice1712_6fire_control_get,\ .get = snd_ice1712_6fire_control_get,\
.put = snd_ice1712_6fire_control_put,\ .put = snd_ice1712_6fire_control_put,\
.private_value = xshift | (xinvert << 8),\ .private_value = xshift | (xinvert << 8),\
} }
static snd_kcontrol_new_t snd_ice1712_6fire_led __devinitdata = static snd_kcontrol_new_t snd_ice1712_6fire_controls[] __devinitdata = {
DMX6FIRE_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Breakbox LED", 6, 0, 0); {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
#endif // XXX not working yet .name = "Analog Input Select",
.info = snd_ice1712_6fire_select_input_info,
.get = snd_ice1712_6fire_select_input_get,
.put = snd_ice1712_6fire_select_input_put,
},
DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 0),
// DMX6FIRE_CONTROL("Master Clock Select", 3, 0),
DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0),
DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0),
DMX6FIRE_CONTROL("Breakbox LED", 6, 0),
};
/* /*
* *
...@@ -3808,14 +3863,16 @@ static int __devinit snd_ice1712_chip_init(ice1712_t *ice) ...@@ -3808,14 +3863,16 @@ static int __devinit snd_ice1712_chip_init(ice1712_t *ice)
} }
break; break;
case ICE1712_SUBDEVICE_DMX6FIRE: case ICE1712_SUBDEVICE_DMX6FIRE:
#if 0 // XXX not working yet if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->pcf8575)) < 0) {
if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", 0x40>>1, &ice->pcf8575)) < 0) snd_printk("PCF9554 initialization failed\n");
return err; return err;
if ((err = snd_cs8427_create(ice->i2c, 0x11, &ice->cs8427)) < 0) { }
#if 0 // XXX not working...
if ((err = snd_cs8427_create(ice->i2c, ICE1712_6FIRE_CS8427_ADDR, &ice->cs8427)) < 0) {
snd_printk("CS8427 initialization failed\n"); snd_printk("CS8427 initialization failed\n");
return err; return err;
} }
#endif // XXX not working yet #endif
break; break;
case ICE1712_SUBDEVICE_EWS88MT: case ICE1712_SUBDEVICE_EWS88MT:
if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->cs8404)) < 0) if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->cs8404)) < 0)
...@@ -4052,11 +4109,11 @@ static int __init snd_ice1712_build_controls(ice1712_t *ice) ...@@ -4052,11 +4109,11 @@ static int __init snd_ice1712_build_controls(ice1712_t *ice)
} }
break; break;
case ICE1712_SUBDEVICE_DMX6FIRE: case ICE1712_SUBDEVICE_DMX6FIRE:
#if 0 // XXX not working yet for (idx = 0; idx < sizeof(snd_ice1712_6fire_controls)/sizeof(snd_ice1712_6fire_controls[0]); idx++) {
err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_led, ice)); err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice));
if (err < 0) if (err < 0)
return err; return err;
#endif }
break; break;
} }
......
...@@ -326,10 +326,6 @@ struct _snd_intel8x0 { ...@@ -326,10 +326,6 @@ struct _snd_intel8x0 {
char ac97_name[32]; char ac97_name[32];
char ctrl_name[32]; char ctrl_name[32];
unsigned long dma_playback_size;
unsigned long dma_capture_size;
unsigned long dma_mic_size;
int irq; int irq;
unsigned int mmio; unsigned int mmio;
...@@ -428,7 +424,7 @@ static void iputbyte(intel8x0_t *chip, u32 offset, u8 val) ...@@ -428,7 +424,7 @@ static void iputbyte(intel8x0_t *chip, u32 offset, u8 val)
if (chip->bm_mmio) if (chip->bm_mmio)
writeb(val, chip->remap_bmaddr + offset); writeb(val, chip->remap_bmaddr + offset);
else else
return outb(val, chip->bmaddr + offset); outb(val, chip->bmaddr + offset);
} }
static void iputword(intel8x0_t *chip, u32 offset, u16 val) static void iputword(intel8x0_t *chip, u32 offset, u16 val)
...@@ -436,7 +432,7 @@ static void iputword(intel8x0_t *chip, u32 offset, u16 val) ...@@ -436,7 +432,7 @@ static void iputword(intel8x0_t *chip, u32 offset, u16 val)
if (chip->bm_mmio) if (chip->bm_mmio)
writew(val, chip->remap_bmaddr + offset); writew(val, chip->remap_bmaddr + offset);
else else
return outw(val, chip->bmaddr + offset); outw(val, chip->bmaddr + offset);
} }
static void iputdword(intel8x0_t *chip, u32 offset, u32 val) static void iputdword(intel8x0_t *chip, u32 offset, u32 val)
...@@ -444,7 +440,7 @@ static void iputdword(intel8x0_t *chip, u32 offset, u32 val) ...@@ -444,7 +440,7 @@ static void iputdword(intel8x0_t *chip, u32 offset, u32 val)
if (chip->bm_mmio) if (chip->bm_mmio)
writel(val, chip->remap_bmaddr + offset); writel(val, chip->remap_bmaddr + offset);
else else
return outl(val, chip->bmaddr + offset); outl(val, chip->bmaddr + offset);
} }
/* /*
...@@ -464,7 +460,7 @@ static void iaputword(intel8x0_t *chip, u32 offset, u16 val) ...@@ -464,7 +460,7 @@ static void iaputword(intel8x0_t *chip, u32 offset, u16 val)
if (chip->mmio) if (chip->mmio)
writew(val, chip->remap_addr + offset); writew(val, chip->remap_addr + offset);
else else
return outw(val, chip->addr + offset); outw(val, chip->addr + offset);
} }
/* /*
...@@ -1583,6 +1579,7 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock) ...@@ -1583,6 +1579,7 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
if (codecs < 2) if (codecs < 2)
goto __skip_secondary; goto __skip_secondary;
for (i = 1; i < codecs; i++) { for (i = 1; i < codecs; i++) {
ac97.num = i;
if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0) if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0)
return err; return err;
chip->ac97[i] = x97; chip->ac97[i] = x97;
...@@ -1995,7 +1992,13 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip) ...@@ -1995,7 +1992,13 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
snd_intel8x0_setup_periods(chip, ichdev); snd_intel8x0_setup_periods(chip, ichdev);
port = ichdev->reg_offset; port = ichdev->reg_offset;
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM); /* trigger */ /* trigger */
if (chip->device_type != DEVICE_ALI)
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
else {
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
iputbyte(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
}
do_gettimeofday(&start_time); do_gettimeofday(&start_time);
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
#if 0 #if 0
...@@ -2014,7 +2017,10 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip) ...@@ -2014,7 +2017,10 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << 1; pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << 1;
pos += ichdev->position; pos += ichdev->position;
do_gettimeofday(&stop_time); do_gettimeofday(&stop_time);
iputbyte(chip, port + ICH_REG_OFF_CR, 0); /* stop */ /* stop */
if (chip->device_type == DEVICE_ALI)
iputbyte(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
iputbyte(chip, port + ICH_REG_OFF_CR, 0);
/* reset whole DMA things */ /* reset whole DMA things */
while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
; ;
...@@ -2279,6 +2285,7 @@ static struct shortname_table { ...@@ -2279,6 +2285,7 @@ static struct shortname_table {
{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" }, { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" },
{ 0x746d, "AMD AMD8111" }, { 0x746d, "AMD AMD8111" },
{ 0x7445, "AMD AMD768" }, { 0x7445, "AMD AMD768" },
{ 0x5455, "ALi M5455" },
{ 0, 0 }, { 0, 0 },
}; };
......
...@@ -1517,10 +1517,8 @@ static int ...@@ -1517,10 +1517,8 @@ static int
snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol, snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol,
snd_ctl_elem_info_t * uinfo) snd_ctl_elem_info_t * uinfo)
{ {
static char *_texts[5] =
{ "Optical", "Coaxial", "Internal", "XLR" };
rme32_t *rme32 = _snd_kcontrol_chip(kcontrol); rme32_t *rme32 = _snd_kcontrol_chip(kcontrol);
char *texts[4] = { _texts[0], _texts[1], _texts[2], _texts[3] }; static char *texts[4] = { "Optical", "Coaxial", "Internal", "XLR" };
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1; uinfo->count = 1;
...@@ -1614,8 +1612,8 @@ snd_rme32_info_clockmode_control(snd_kcontrol_t * kcontrol, ...@@ -1614,8 +1612,8 @@ snd_rme32_info_clockmode_control(snd_kcontrol_t * kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1; uinfo->count = 1;
uinfo->value.enumerated.items = 4; uinfo->value.enumerated.items = 4;
if (uinfo->value.enumerated.item > 4) { if (uinfo->value.enumerated.item > 3) {
uinfo->value.enumerated.item = 4; uinfo->value.enumerated.item = 3;
} }
strcpy(uinfo->value.enumerated.name, strcpy(uinfo->value.enumerated.name,
texts[uinfo->value.enumerated.item]); texts[uinfo->value.enumerated.item]);
......
This diff is collapsed.
This diff is collapsed.
...@@ -74,11 +74,14 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter) ...@@ -74,11 +74,14 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
new_client->id = keywest_ctx->id++; /* Automatically unique */ new_client->id = keywest_ctx->id++; /* Automatically unique */
keywest_ctx->client = new_client; keywest_ctx->client = new_client;
if ((err = keywest_ctx->init_client(keywest_ctx)) < 0) if ((err = keywest_ctx->init_client(keywest_ctx)) < 0) {
snd_printk(KERN_ERR "tumbler: cannot initialize the MCS\n");
goto __err; goto __err;
}
/* Tell the i2c layer a new client has arrived */ /* Tell the i2c layer a new client has arrived */
if (i2c_attach_client(new_client)) { if (i2c_attach_client(new_client)) {
snd_printk(KERN_ERR "tumbler: cannot attach i2c client\n");
err = -ENODEV; err = -ENODEV;
goto __err; goto __err;
} }
......
...@@ -1170,8 +1170,7 @@ static int __init snd_pmac_detect(pmac_t *chip) ...@@ -1170,8 +1170,7 @@ static int __init snd_pmac_detect(pmac_t *chip)
// chip->can_byte_swap = 0; /* FIXME: check this */ // chip->can_byte_swap = 0; /* FIXME: check this */
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
} }
if (device_is_compatible(sound, "tumbler") || if (device_is_compatible(sound, "tumbler")) {
device_is_compatible(sound, "snapper")) {
chip->model = PMAC_TUMBLER; chip->model = PMAC_TUMBLER;
chip->can_capture = 0; /* no capture */ chip->can_capture = 0; /* no capture */
chip->can_duplex = 0; chip->can_duplex = 0;
...@@ -1180,6 +1179,15 @@ static int __init snd_pmac_detect(pmac_t *chip) ...@@ -1180,6 +1179,15 @@ static int __init snd_pmac_detect(pmac_t *chip)
chip->freq_table = tumbler_freqs; chip->freq_table = tumbler_freqs;
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
} }
if (device_is_compatible(sound, "snapper")) {
chip->model = PMAC_SNAPPER;
chip->can_capture = 0; /* no capture */
chip->can_duplex = 0;
// chip->can_byte_swap = 0; /* FIXME: check this */
chip->num_freqs = 2;
chip->freq_table = tumbler_freqs;
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
prop = (unsigned int *)get_property(sound, "device-id", 0); prop = (unsigned int *)get_property(sound, "device-id", 0);
if (prop) if (prop)
chip->device_id = *prop; chip->device_id = *prop;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#endif #endif
#endif #endif
#include <linux/nvram.h> #include <linux/nvram.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> #include <linux/vt_kern.h>
#include <asm/dbdma.h> #include <asm/dbdma.h>
#include <asm/prom.h> #include <asm/prom.h>
...@@ -115,7 +116,7 @@ struct snd_pmac_beep { ...@@ -115,7 +116,7 @@ struct snd_pmac_beep {
*/ */
enum snd_pmac_model { enum snd_pmac_model {
PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER, PMAC_SNAPPER
}; };
struct snd_pmac { struct snd_pmac {
......
...@@ -94,8 +94,10 @@ static int __init snd_pmac_probe(void) ...@@ -94,8 +94,10 @@ static int __init snd_pmac_probe(void)
goto __error; goto __error;
break; break;
case PMAC_TUMBLER: case PMAC_TUMBLER:
strcpy(card->driver, "PMac Tumbler"); case PMAC_SNAPPER:
strcpy(card->shortname, "PowerMac Tumbler"); name_ext = chip->model == PMAC_TUMBLER ? "Tumbler" : "Snapper";
sprintf(card->driver, "PMac %s", name_ext);
sprintf(card->shortname, "PowerMac %s", name_ext);
sprintf(card->longname, "%s (Dev %d) Sub-frame %d", sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
card->shortname, chip->device_id, chip->subframe); card->shortname, chip->device_id, chip->subframe);
if ((err = snd_pmac_tumbler_init(chip)) < 0) if ((err = snd_pmac_tumbler_init(chip)) < 0)
......
This diff is collapsed.
...@@ -63,7 +63,7 @@ static unsigned int master_volume_table[] = { ...@@ -63,7 +63,7 @@ static unsigned int master_volume_table[] = {
0x00071457, 0x00077fbb, 0x0007f17b, 0x00071457, 0x00077fbb, 0x0007f17b,
}; };
/* treble table */ /* treble table for TAS3001c */
/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */ /* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
static unsigned int treble_volume_table[] = { static unsigned int treble_volume_table[] = {
0x96, 0x95, 0x94, 0x96, 0x95, 0x94,
...@@ -93,7 +93,7 @@ static unsigned int treble_volume_table[] = { ...@@ -93,7 +93,7 @@ static unsigned int treble_volume_table[] = {
0x01, 0x01,
}; };
/* bass table */ /* bass table for TAS3001c */
/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */ /* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
static unsigned int bass_volume_table[] = { static unsigned int bass_volume_table[] = {
0x86, 0x82, 0x7f, 0x86, 0x82, 0x7f,
...@@ -186,3 +186,65 @@ static unsigned int mixer_volume_table[] = { ...@@ -186,3 +186,65 @@ static unsigned int mixer_volume_table[] = {
0x5f4e52, 0x64f403, 0x6aef5d, 0x5f4e52, 0x64f403, 0x6aef5d,
0x714575, 0x77fbaa, 0x7f17af, 0x714575, 0x77fbaa, 0x7f17af,
}; };
/* treble table for TAS3004 */
/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
static unsigned int snapper_treble_volume_table[] = {
0x96, 0x95, 0x94,
0x93, 0x92, 0x91,
0x90, 0x8f, 0x8e,
0x8d, 0x8c, 0x8b,
0x8a, 0x89, 0x88,
0x87, 0x86, 0x85,
0x84, 0x83, 0x82,
0x81, 0x80, 0x7f,
0x7e, 0x7d, 0x7c,
0x7b, 0x7a, 0x79,
0x78, 0x77, 0x76,
0x75, 0x74, 0x73,
0x72, 0x71, 0x70,
0x6f, 0x6d, 0x6c,
0x6b, 0x69, 0x68,
0x67, 0x65, 0x63,
0x62, 0x60, 0x5d,
0x5b, 0x59, 0x56,
0x53, 0x51, 0x4d,
0x4a, 0x47, 0x43,
0x3f, 0x3b, 0x36,
0x31, 0x2c, 0x26,
0x20, 0x1a, 0x13,
0x08, 0x04, 0x01,
0x01,
};
/* bass table for TAS3004 */
/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
static unsigned int snapper_bass_volume_table[] = {
0x96, 0x95, 0x94,
0x93, 0x92, 0x91,
0x90, 0x8f, 0x8e,
0x8d, 0x8c, 0x8b,
0x8a, 0x89, 0x88,
0x87, 0x86, 0x85,
0x84, 0x83, 0x82,
0x81, 0x80, 0x7f,
0x7e, 0x7d, 0x7c,
0x7b, 0x7a, 0x79,
0x78, 0x77, 0x76,
0x75, 0x74, 0x73,
0x72, 0x71, 0x6f,
0x6e, 0x6d, 0x6b,
0x6a, 0x69, 0x67,
0x66, 0x65, 0x63,
0x62, 0x61, 0x5f,
0x5d, 0x5b, 0x58,
0x55, 0x52, 0x4f,
0x4c, 0x49, 0x46,
0x43, 0x3f, 0x3b,
0x37, 0x33, 0x2e,
0x29, 0x24, 0x1e,
0x18, 0x11, 0x0a,
0x01,
};
...@@ -53,6 +53,8 @@ MODULE_DEVICES("{{Generic,USB Audio}}"); ...@@ -53,6 +53,8 @@ MODULE_DEVICES("{{Generic,USB Audio}}");
static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int snd_vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for this card */
static int snd_pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */
MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(snd_index, "Index value for the USB audio adapter."); MODULE_PARM_DESC(snd_index, "Index value for the USB audio adapter.");
...@@ -63,6 +65,27 @@ MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC); ...@@ -63,6 +65,27 @@ MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);
MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(snd_enable, "Enable USB audio adapter."); MODULE_PARM_DESC(snd_enable, "Enable USB audio adapter.");
MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC); MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);
MODULE_PARM(snd_vid, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(snd_vid, "Vendor ID for the USB audio device.");
MODULE_PARM_SYNTAX(snd_vid, SNDRV_ENABLED ",allows:{{-1,0xffff}},base:16");
MODULE_PARM(snd_pid, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(snd_pid, "Product ID for the USB audio device.");
MODULE_PARM_SYNTAX(snd_pid, SNDRV_ENABLED ",allows:{{-1,0xffff}},base:16");
/*
* for using ASYNC unlink mode, define the following.
* this will make the driver quicker response for request to STOP-trigger,
* but it may cause oops by some unknown reason (bug of usb driver?),
* so turning off might be sure.
*/
/* #define SND_USE_ASYNC_UNLINK */
#ifdef SND_USB_ASYNC_UNLINK
#define UNLINK_FLAGS USB_ASYNC_UNLINK
#else
#define UNLINK_FLAGS 0
#endif
/* /*
...@@ -528,6 +551,10 @@ static int deactivate_urbs(snd_usb_substream_t *subs) ...@@ -528,6 +551,10 @@ static int deactivate_urbs(snd_usb_substream_t *subs)
subs->running = 0; subs->running = 0;
#ifndef SND_USB_ASYNC_UNLINK
if (in_interrupt())
return 0;
#endif
alive = 0; alive = 0;
for (i = 0; i < subs->nurbs; i++) { for (i = 0; i < subs->nurbs; i++) {
if (test_bit(i, &subs->active_mask)) { if (test_bit(i, &subs->active_mask)) {
...@@ -545,7 +572,11 @@ static int deactivate_urbs(snd_usb_substream_t *subs) ...@@ -545,7 +572,11 @@ static int deactivate_urbs(snd_usb_substream_t *subs)
} }
} }
} }
#ifdef SND_USB_ASYNC_UNLINK
return alive; return alive;
#else
return 0;
#endif
} }
...@@ -803,7 +834,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run ...@@ -803,7 +834,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run
} }
u->urb->dev = subs->dev; u->urb->dev = subs->dev;
u->urb->pipe = subs->datapipe; u->urb->pipe = subs->datapipe;
u->urb->transfer_flags = USB_ISO_ASAP | USB_ASYNC_UNLINK; u->urb->transfer_flags = USB_ISO_ASAP | UNLINK_FLAGS;
u->urb->number_of_packets = u->packets; u->urb->number_of_packets = u->packets;
u->urb->context = u; u->urb->context = u;
u->urb->complete = snd_complete_urb; u->urb->complete = snd_complete_urb;
...@@ -825,7 +856,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run ...@@ -825,7 +856,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run
u->urb->transfer_buffer_length = NRPACKS * 3; u->urb->transfer_buffer_length = NRPACKS * 3;
u->urb->dev = subs->dev; u->urb->dev = subs->dev;
u->urb->pipe = subs->syncpipe; u->urb->pipe = subs->syncpipe;
u->urb->transfer_flags = USB_ISO_ASAP | USB_ASYNC_UNLINK; u->urb->transfer_flags = USB_ISO_ASAP | UNLINK_FLAGS;
u->urb->number_of_packets = u->packets; u->urb->number_of_packets = u->packets;
u->urb->context = u; u->urb->context = u;
u->urb->complete = snd_complete_sync_urb; u->urb->complete = snd_complete_sync_urb;
...@@ -2043,7 +2074,9 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -2043,7 +2074,9 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
* now look for an empty slot and create a new card instance * now look for an empty slot and create a new card instance
*/ */
for (i = 0; i < SNDRV_CARDS; i++) for (i = 0; i < SNDRV_CARDS; i++)
if (snd_enable[i] && ! usb_chip[i]) { if (snd_enable[i] && ! usb_chip[i] &&
(snd_vid[i] == -1 || snd_vid[i] == dev->descriptor.idVendor) &&
(snd_pid[i] == -1 || snd_pid[i] == dev->descriptor.idProduct)) {
card = snd_card_new(snd_index[i], snd_id[i], THIS_MODULE, 0); card = snd_card_new(snd_index[i], snd_id[i], THIS_MODULE, 0);
if (card == NULL) { if (card == NULL) {
snd_printk(KERN_ERR "cannot create a card instance %d\n", i); snd_printk(KERN_ERR "cannot create a card instance %d\n", i);
......
...@@ -73,6 +73,7 @@ struct usb_mixer_elem_info { ...@@ -73,6 +73,7 @@ struct usb_mixer_elem_info {
int channels; int channels;
int val_type; int val_type;
int min, max; int min, max;
unsigned int initialized: 1;
}; };
...@@ -498,6 +499,23 @@ static int mixer_ctl_feature_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t ...@@ -498,6 +499,23 @@ static int mixer_ctl_feature_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
uinfo->value.integer.min = 0; uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1; uinfo->value.integer.max = 1;
} else { } else {
if (! cval->initialized) {
int minchn = 0;
if (cval->cmask) {
int i;
for (i = 0; i < MAX_CHANNELS; i++)
if (cval->cmask & (1 << i)) {
minchn = i + 1;
break;
}
}
if (get_ctl_value(cval, GET_MAX, ((cval->control+1) << 8) | minchn, &cval->max) < 0 ||
get_ctl_value(cval, GET_MIN, ((cval->control+1) << 8) | minchn, &cval->min) < 0) {
snd_printk(KERN_ERR "%d:%d: cannot get min/max values for control %d\n", cval->id, cval->ctrlif, cval->control);
return -EINVAL;
}
cval->initialized = 1;
}
uinfo->value.integer.min = 0; uinfo->value.integer.min = 0;
uinfo->value.integer.max = cval->max - cval->min; uinfo->value.integer.max = cval->max - cval->min;
} }
...@@ -515,8 +533,10 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t ...@@ -515,8 +533,10 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
for (c = 0; c < MAX_CHANNELS; c++) { for (c = 0; c < MAX_CHANNELS; c++) {
if (cval->cmask & (1 << c)) { if (cval->cmask & (1 << c)) {
err = get_cur_mix_value(cval, c + 1, &val); err = get_cur_mix_value(cval, c + 1, &val);
if (err < 0) if (err < 0) {
printk("cannot get current value for control %d ch %d: err = %d\n", cval->control, c + 1, err);
return err; return err;
}
val = get_relative_value(cval, val); val = get_relative_value(cval, val);
ucontrol->value.integer.value[cnt] = val; ucontrol->value.integer.value[cnt] = val;
cnt++; cnt++;
...@@ -525,8 +545,10 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t ...@@ -525,8 +545,10 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
} else { } else {
/* master channel */ /* master channel */
err = get_cur_mix_value(cval, 0, &val); err = get_cur_mix_value(cval, 0, &val);
if (err < 0) if (err < 0) {
printk("cannot get current value for control %d master ch: err = %d\n", cval->control, err);
return err; return err;
}
val = get_relative_value(cval, val); val = get_relative_value(cval, val);
ucontrol->value.integer.value[0] = val; ucontrol->value.integer.value[0] = val;
} }
...@@ -592,6 +614,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc, ...@@ -592,6 +614,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
int nameid = desc[desc[0] - 1]; int nameid = desc[desc[0] - 1];
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
usb_mixer_elem_info_t *cval; usb_mixer_elem_info_t *cval;
int minchn = 0;
if (control == USB_FEATURE_GEQ) { if (control == USB_FEATURE_GEQ) {
/* FIXME: not supported yet */ /* FIXME: not supported yet */
...@@ -614,22 +637,25 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc, ...@@ -614,22 +637,25 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
else { else {
int i, c = 0; int i, c = 0;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
if (ctl_mask & (1 << i)) if (ctl_mask & (1 << i)) {
if (! minchn)
minchn = i + 1;
c++; c++;
}
cval->channels = c; cval->channels = c;
} }
/* get min/max values */ /* get min/max values */
if (cval->val_type == USB_MIXER_BOOLEAN || if (cval->val_type == USB_MIXER_BOOLEAN ||
cval->val_type == USB_MIXER_INV_BOOLEAN) cval->val_type == USB_MIXER_INV_BOOLEAN) {
cval->max = 1; cval->max = 1;
else { cval->initialized = 1;
if (get_ctl_value(cval, GET_MAX, ((cval->control+1) << 8) | (ctl_mask ? 1 : 0), &cval->max) < 0 || } else {
get_ctl_value(cval, GET_MIN, ((cval->control+1) << 8) | (ctl_mask ? 1 : 0), &cval->min) < 0) { if (get_ctl_value(cval, GET_MAX, ((cval->control+1) << 8) | minchn, &cval->max) < 0 ||
get_ctl_value(cval, GET_MIN, ((cval->control+1) << 8) | minchn, &cval->min) < 0)
snd_printk(KERN_ERR "%d:%d: cannot get min/max values for control %d\n", cval->id, cval->ctrlif, control); snd_printk(KERN_ERR "%d:%d: cannot get min/max values for control %d\n", cval->id, cval->ctrlif, control);
snd_magic_kfree(cval); else
return; cval->initialized = 1;
}
} }
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
...@@ -759,6 +785,7 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc, ...@@ -759,6 +785,7 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
int i, len; int i, len;
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
usb_audio_term_t iterm; usb_audio_term_t iterm;
int minchn = 0;
cval = snd_magic_kcalloc(usb_mixer_elem_info_t, 0, GFP_KERNEL); cval = snd_magic_kcalloc(usb_mixer_elem_info_t, 0, GFP_KERNEL);
if (! cval) if (! cval)
...@@ -776,16 +803,17 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc, ...@@ -776,16 +803,17 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
if (check_matrix_bitmap(desc + 9 + num_ins, in_ch, i, num_outs)) { if (check_matrix_bitmap(desc + 9 + num_ins, in_ch, i, num_outs)) {
cval->cmask |= (1 << i); cval->cmask |= (1 << i);
cval->channels++; cval->channels++;
if (! minchn)
minchn = i + 1;
} }
} }
/* get min/max values */ /* get min/max values */
if (get_ctl_value(cval, GET_MAX, ((in_ch+1) << 8) | 1, &cval->max) < 0 || if (get_ctl_value(cval, GET_MAX, ((in_ch+1) << 8) | minchn, &cval->max) < 0 ||
get_ctl_value(cval, GET_MIN, ((in_ch+1) << 8) | 1, &cval->min) < 0) { get_ctl_value(cval, GET_MIN, ((in_ch+1) << 8) | minchn, &cval->min) < 0)
snd_printk(KERN_ERR "cannot get min/max values for mixer\n"); snd_printk(KERN_ERR "cannot get min/max values for mixer\n");
snd_magic_kfree(cval); else
return; cval->initialized = 1;
}
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
if (! kctl) { if (! kctl) {
...@@ -994,11 +1022,10 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char ...@@ -994,11 +1022,10 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char
/* get min/max values */ /* get min/max values */
if (get_ctl_value(cval, GET_MAX, cval->control, &cval->max) < 0 || if (get_ctl_value(cval, GET_MAX, cval->control, &cval->max) < 0 ||
get_ctl_value(cval, GET_MIN, cval->control, &cval->min) < 0) { get_ctl_value(cval, GET_MIN, cval->control, &cval->min) < 0)
snd_printk(KERN_ERR "cannot get min/max values for proc/ext unit\n"); snd_printk(KERN_ERR "cannot get min/max values for proc/ext unit\n");
snd_magic_kfree(cval); else
continue; cval->initialized = 1;
}
kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
if (! kctl) { if (! kctl) {
...@@ -1158,6 +1185,7 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned ...@@ -1158,6 +1185,7 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned
cval->channels = 1; cval->channels = 1;
cval->min = 1; cval->min = 1;
cval->max = num_ins; cval->max = num_ins;
cval->initialized = 1;
namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL); namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL);
if (! namelist) { if (! namelist) {
......
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