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)
#define intel8x0_t_magic 0xa15a2a01
#define es1968_t_magic 0xa15a2b01
#define esschan_t_magic 0xa15a2b02
#define via686a_t_magic 0xa15a2c01
#define via82xx_t_magic 0xa15a2c01
#define pdplus_t_magic 0xa15a2d01
#define cmipci_t_magic 0xa15a2e01
#define ymfpci_t_magic 0xa15a2f01
......@@ -126,7 +126,6 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define m3_dma_t_magic 0xa15a3202
#define nm256_t_magic 0xa15a3301
#define nm256_dma_t_magic 0xa15a3302
#define via8233_t_magic 0xa15a3401
#define pmac_t_magic 0xa15a3501
#define ali_t_magic 0xa15a3601
#define mtpav_t_magic 0xa15a3701
......
/* include/version.h. Generated automatically by configure. */
#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
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_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_VIA8233) += snd-pcm.o snd-timer.o snd.o
obj-$(CONFIG_SND_VIA82XX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.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_EMU10K1) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
......
......@@ -28,7 +28,5 @@
struct ioctl32_mapper hwdep_mappers[] = {
{ SNDRV_HWDEP_IOCTL_PVERSION, NULL },
{ SNDRV_HWDEP_IOCTL_INFO, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_INFO, NULL },
{ 0 },
};
......@@ -47,14 +47,10 @@ int snd_ioctl32_register(struct ioctl32_mapper *mappers)
int err;
struct ioctl32_mapper *m;
lock_kernel();
for (m = mappers; m->cmd; m++) {
err = register_ioctl32_conversion(m->cmd, m->handler);
if (err < 0) {
unlock_kernel();
return err;
}
m->registered++;
if (err >= 0)
m->registered++;
}
return 0;
}
......@@ -63,14 +59,12 @@ void snd_ioctl32_unregister(struct ioctl32_mapper *mappers)
{
struct ioctl32_mapper *m;
lock_kernel();
for (m = mappers; m->cmd; m++) {
if (m->registered) {
unregister_ioctl32_conversion(m->cmd);
m->registered = 0;
}
}
unlock_kernel();
}
......@@ -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_list data;
mm_segment_t oldseg = get_fs();
mm_segment_t oldseg;
int err;
set_fs(KERNEL_DS);
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
memset(&data, 0, sizeof(data));
data.offset = data32.offset;
data.space = data32.space;
data.used = data32.used;
data.count = data32.count;
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);
set_fs(oldseg);
if (err < 0)
goto __err;
return err;
/* copy the result */
data32.offset = data.offset;
data32.space = data.space;
data32.used = data.used;
data32.count = data.count;
//data.pids = data.pids;
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
__err:
set_fs(oldseg);
return err;
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT;
return 0;
}
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
struct sndrv_ctl_elem_info data;
struct sndrv_ctl_elem_info32 data32;
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))) {
err = -EFAULT;
goto __err;
}
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
memset(&data, 0, sizeof(data));
data.id = data32.id;
/* we need to copy the item index.
* hope this doesn't break anything..
*/
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);
set_fs(oldseg);
if (err < 0)
goto __err;
return err;
/* restore info to 32bit */
data32.id = data.id;
data32.type = data.type;
......@@ -215,10 +205,8 @@ static int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigne
break;
}
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
err = -EFAULT;
__err:
set_fs(oldseg);
return err;
return -EFAULT;
return 0;
}
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
struct sndrv_ctl_elem_value32 data32;
int err, i;
int type;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
mm_segment_t oldseg;
/* FIXME: check the sane ioctl.. */
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
memset(&data, 0, sizeof(data));
data.id = data32.id;
data.indirect = data32.indirect;
if (data.indirect) /* FIXME: this is not correct for long arrays */
data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr);
type = get_ctl_type(file, &data.id);
if (type < 0) {
err = type;
goto __err;
}
if (type < 0)
return type;
if (! data.indirect) {
switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
......@@ -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);
set_fs(oldseg);
if (err < 0)
goto __err;
return err;
/* restore info to 32bit */
if (! data.indirect) {
switch (type) {
......@@ -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)))
err = -EFAULT;
__err:
set_fs(oldseg);
return err;
return -EFAULT;
return 0;
}
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[] = {
{ SNDRV_CTL_IOCTL_ELEM_LOCK, NULL },
{ SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL },
{ SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_INFO, NULL },
{ SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL },
{ SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL },
{ SNDRV_CTL_IOCTL_PCM_INFO, NULL },
......@@ -427,37 +411,13 @@ static void snd_ioctl32_done(void)
static int __init snd_ioctl32_init(void)
{
int err;
err = snd_ioctl32_register(control_mappers);
if (err < 0)
return err;
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;
}
snd_ioctl32_register(control_mappers);
snd_ioctl32_register(pcm_mappers);
snd_ioctl32_register(rawmidi_mappers);
snd_ioctl32_register(timer_mappers);
snd_ioctl32_register(hwdep_mappers);
#ifdef CONFIG_SND_SEQUENCER
err = snd_ioctl32_register(seq_mappers);
if (err < 0) {
snd_ioctl32_done();
return err;
}
snd_ioctl32_register(seq_mappers);
#endif
return 0;
}
......
......@@ -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 data;\
mm_segment_t oldseg = get_fs();\
mm_segment_t oldseg;\
int err;\
set_fs(KERNEL_DS);\
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {\
err = -EFAULT;\
goto __err;\
}\
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))\
return -EFAULT;\
memset(&data, 0, sizeof(data));\
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);\
if (err < 0) \
goto __err;\
return err;\
if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
convert_to_32(type, &data32, &data);\
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {\
err = -EFAULT;\
goto __err;\
}\
if (copy_to_user((void*)arg, &data32, sizeof(data32)))\
return -EFAULT;\
}\
__err: set_fs(oldseg);\
return err;\
return 0;\
}
#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
{
struct sndrv_xferi32 data32;
struct sndrv_xferi data;
mm_segment_t oldseg = get_fs();
mm_segment_t oldseg;
int err;
set_fs(KERNEL_DS);
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
memset(&data, 0, sizeof(data));
data.result = data32.result;
data.buf = A(data32.buf);
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);
set_fs(oldseg);
if (err < 0)
goto __err;
return err;
/* copy the result */
data32.result = data.result;
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
__err:
set_fs(oldseg);
return err;
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT;
return 0;
}
......@@ -237,9 +233,7 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
void *bufs[128];
int err = 0, ch, i;
u32 *bufptr;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
mm_segment_t oldseg;
/* 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
/* check validty of the command */
switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
err = -EINVAL;
goto __err;
}
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
err = -EBADFD;
goto __err;
}
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
return -EINVAL;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
break;
case SNDRV_PCM_IOCTL_READN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
err = -EINVAL;
goto __err;
}
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
return -EINVAL;
break;
}
if ((ch = substream->runtime->channels) > 128) {
err = -EINVAL;
goto __err;
}
if (get_user(data32.frames, &srcptr->frames)) {
err = -EFAULT;
goto __err;
}
if ((ch = substream->runtime->channels) > 128)
return -EINVAL;
if (get_user(data32.frames, &srcptr->frames))
return -EFAULT;
__get_user(data32.bufs, &srcptr->bufs);
bufptr = (u32*)TO_PTR(data32.bufs);
for (i = 0; i < ch; i++) {
u32 ptr;
if (get_user(ptr, bufptr)) {
err = -EFAULT;
goto __err;
}
if (get_user(ptr, bufptr))
return -EFAULT;
bufs[ch] = (void*)TO_PTR(ptr);
bufptr++;
}
oldseg = get_fs();
set_fs(KERNEL_DS);
switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_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
err = snd_pcm_lib_readv(substream, bufs, data32.frames);
break;
}
set_fs(oldseg);
if (err < 0)
goto __err;
return err;
if (put_user(err, &srcptr->result))
err = -EFAULT;
__err:
set_fs(oldseg);
return err < 0 ? err : 0;
return -EFAULT;
return 0;
}
......@@ -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 data;
mm_segment_t oldseg = get_fs();
mm_segment_t oldseg;
int err;
set_fs(KERNEL_DS);
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
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);
set_fs(oldseg);
if (err < 0)
goto __err;
return err;
snd_pcm_hw_convert_to_old_params(&data32, &data);
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
__err: set_fs(oldseg);
return err;
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT;
return 0;
}
......@@ -451,9 +431,5 @@ struct ioctl32_mapper pcm_mappers[] = {
{ SNDRV_PCM_IOCTL_LINK, 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 },
};
......@@ -1169,10 +1169,14 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int free_flag)
return err;
}
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,
card->number,
name);
mixer->name);
for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++)
mixer->slots[idx].number = idx;
card->mixer_oss = mixer;
......
......@@ -80,6 +80,9 @@ int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream)
{
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_shrink(sgbuf, 0);
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
obj-$(CONFIG_SND_ICE1712) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_INTEL8X0) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
obj-$(CONFIG_SND_SONICVIBES) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_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_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
......
......@@ -146,6 +146,8 @@ snd_seq_oss_synth_register(snd_seq_device_t *dev)
debug_printk(("synth %s registered %d\n", rec->name, i));
spin_unlock_irqrestore(&register_lock, flags);
dev->driver_data = rec;
if (i < SNDRV_CARDS)
snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name);
return 0;
}
......@@ -176,6 +178,8 @@ snd_seq_oss_synth_unregister(snd_seq_device_t *dev)
max_synth_devs = index + 1;
}
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);
kfree(rec);
......
......@@ -35,7 +35,7 @@ obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o
obj-$(CONFIG_SND_INTEL8X0) += 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_TRIDENT) += 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,
if (device->flags & SND_I2C_DEVICE_ADDRTEN)
return -EIO; /* not yet implemented */
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;
}
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;
}
res++;
}
snd_i2c_bit_stop(bus);
......@@ -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)
return -EIO; /* not yet implemented */
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;
}
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;
}
*bytes++ = (unsigned char)err;
res++;
}
......@@ -300,10 +308,9 @@ static int snd_i2c_bit_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
if (addr & 0x7f80) /* invalid address */
return -EINVAL;
snd_i2c_bit_start(bus);
if ((err = snd_i2c_bit_sendbyte(bus, addr << 1)) < 0)
return err;
err = snd_i2c_bit_sendbyte(bus, addr << 1);
snd_i2c_bit_stop(bus);
return 1; /* present */
return err;
}
EXPORT_SYMBOL(snd_i2c_bus_create);
......
......@@ -82,8 +82,5 @@ CONFIG_SND_INTEL8X0
CONFIG_SND_SONICVIBES
Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards.
CONFIG_SND_VIA686
Say 'Y' or 'M' to include support for VIA VT82C686A/B South Bridge.
CONFIG_SND_VIA8233
Say 'Y' or 'M' to include support for VIA VT8233 South Bridge.
CONFIG_SND_VIA82XX
Say 'Y' or 'M' to include support for VIA VT82C686A/B, VT8233 South Bridge.
......@@ -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 'Intel i810/i820/i830/i840/MX440 integrated audio' CONFIG_SND_INTEL8X0 $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 8233 South Bridge' CONFIG_SND_VIA8233 $CONFIG_SND
dep_tristate 'VIA 82C686A/B, 8233 South Bridge' CONFIG_SND_VIA82XX $CONFIG_SND
# define gameport if necessary
if [ "$CONFIG_INPUT_GAMEPORT" != "n" ]; then
......
......@@ -17,8 +17,7 @@ snd-maestro3-objs := maestro3.o
snd-rme32-objs := rme32.o
snd-rme96-objs := rme96.o
snd-sonicvibes-objs := sonicvibes.o
snd-via686-objs := via686.o
snd-via8233-objs := via8233.o
snd-via82xx-objs := via82xx.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
......@@ -35,8 +34,7 @@ obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o
obj-$(CONFIG_SND_RME32) += snd-rme32.o
obj-$(CONFIG_SND_RME96) += snd-rme96.o
obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
obj-$(CONFIG_SND_VIA686) += snd-via686.o
obj-$(CONFIG_SND_VIA8233) += snd-via8233.o
obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
obj-$(CONFIG_SND) += ac97/ ali5451/ cs46xx/ emu10k1/ korg1212/ nm256/ rme9652/ trident/ ymfpci/
......
......@@ -17,8 +17,7 @@ obj-$(CONFIG_SND_FM801) += snd-ac97-codec.o
obj-$(CONFIG_SND_ICE1712) += snd-ac97-codec.o
obj-$(CONFIG_SND_INTEL8X0) += snd-ac97-codec.o
obj-$(CONFIG_SND_MAESTRO3) += snd-ac97-codec.o
obj-$(CONFIG_SND_VIA686) += snd-ac97-codec.o
obj-$(CONFIG_SND_VIA8233) += snd-ac97-codec.o
obj-$(CONFIG_SND_VIA82XX) += snd-ac97-codec.o
obj-$(CONFIG_SND_ALI5451) += snd-ac97-codec.o
obj-$(CONFIG_SND_CS46XX) += 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[] = {
{ 0x41445300, 0xffffff00, "Analog Devices", NULL },
{ 0x414c4300, 0xffffff00, "Realtek", NULL },
{ 0x414c4700, 0xffffff00, "Avance Logic", NULL },
{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL },
{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL },
{ 0x43585400, 0xffffff00, "Conexant", NULL },
{ 0x45838300, 0xffffff00, "ESS Technology", NULL },
......@@ -95,6 +96,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885 },
{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886 },
{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881 },
{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881 },
{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1881 },
{ 0x414c4300, 0xfffffff0, "RL5306", NULL },
{ 0x414c4310, 0xfffffff0, "RL5382", NULL },
......@@ -104,6 +106,8 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x414c4730, 0xffffffff, "ALC101", NULL },
{ 0x414c4740, 0xfffffff0, "ALC202", NULL },
{ 0x414c4750, 0xfffffff0, "ALC250", NULL },
{ 0x434d4941, 0xffffffff, "CMI9738", NULL },
{ 0x434d4961, 0xffffffff, "CMI9739", NULL },
{ 0x43525900, 0xfffffff8, "CS4297", NULL },
{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif },
{ 0x43525920, 0xfffffff8, "CS4294/4298", NULL },
......@@ -122,6 +126,8 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x4e534331, 0xffffffff, "LM4549", NULL },
{ 0x53494c22, 0xffffffff, "Si3036", 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]
{ 0x54524123, 0xffffffff, "TR28602", NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL },
......@@ -130,14 +136,19 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x574d4c00, 0xffffffff, "WM9701A", patch_wolfson00 },
{ 0x574d4c03, 0xffffffff, "WM9703/9707", patch_wolfson03 },
{ 0x574d4c04, 0xffffffff, "WM9704 (quad)", patch_wolfson04 },
{ 0x574d4c05, 0xffffffff, "WM9705", NULL }, // patch?
{ 0x594d4800, 0xffffffff, "YMF743", NULL },
{ 0x594d4802, 0xffffffff, "YMF752", NULL },
{ 0x594d4803, 0xffffffff, "YMF753", NULL },
{ 0x83847600, 0xffffffff, "STAC9700/83/84", NULL },
{ 0x83847604, 0xffffffff, "STAC9701/3/4/5", NULL },
{ 0x83847605, 0xffffffff, "STAC9704", NULL },
{ 0x83847608, 0xffffffff, "STAC9708/11", patch_sigmatel_stac9708 },
{ 0x83847609, 0xffffffff, "STAC9721/23", patch_sigmatel_stac9721 },
{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744 },
{ 0x83847650, 0xffffffff, "STAC9750/51", NULL }, // patch?
{ 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756 },
{ 0x83847666, 0xffffffff, "STAC9766/67", NULL }, // patch?
{ 0, 0, NULL, NULL }
};
......@@ -201,6 +212,7 @@ static int snd_ac97_valid_reg(ac97_t *ac97, unsigned short reg)
return 1;
case AC97_ID_AD1885: /* AD1885 */
case AC97_ID_AD1886: /* AD1886 */
case AC97_ID_AD1886A: /* AD1886A - !!verify!! --jk */
case AC97_ID_AD1887: /* AD1887 - !!verify!! --jk */
if (reg == 0x5a)
return 1;
......
......@@ -30,6 +30,7 @@
#define AC97_ID_AD1885 0x41445360
#define AC97_ID_AD1886 0x41445361
#define AC97_ID_AD1887 0x41445362
#define AC97_ID_AD1886A 0x41445363
#define AC97_ID_TR28028 0x54524108
#define AC97_ID_STAC9700 0x83847600
#define AC97_ID_STAC9704 0x83847604
......
......@@ -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);
int count;
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
......@@ -639,7 +642,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
* 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
......@@ -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_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_CRW |
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,
* ACSTS = Status Register = 464h
* 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;
udelay(10);
}
......@@ -705,7 +708,7 @@ static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
* Read the data returned from the AC97 register.
* 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:
return result;
......@@ -2107,7 +2110,8 @@ static void cs4281_suspend(cs4281_t *chip)
/* remember the status registers */
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. */
snd_cs4281_pokeBA0(chip, BA0_SERMC, 0);
......@@ -2150,7 +2154,8 @@ static void cs4281_resume(cs4281_t *chip)
/* restore the status registers */
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)
snd_ac97_resume(chip->ac97);
......
......@@ -3239,6 +3239,9 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->reg_lock);
#ifdef CONFIG_SND_CS46XX_NEW_DSP
init_MUTEX(&chip->spos_mutex);
#endif
chip->card = card;
chip->pci = pci;
chip->capt.hw_size = PAGE_SIZE;
......
......@@ -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_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_ES1373_8 },
{ .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>,
* Jaroslav Kysela <perex@suse.cz>,
* Thomas Sailer <sailer@ife.ee.ethz.ch>,
......@@ -70,6 +70,8 @@ MODULE_DESCRIPTION("ESS Solo-1");
MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{ESS,ES1938},"
"{ESS,ES1946},"
"{ESS,ES1969},"
"{TerraTec,128i PCI}}");
#ifndef PCI_VENDOR_ID_ESS
......
......@@ -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)
{
if (chip->res_io_port)
snd_es1968_reset(chip);
snd_es1968_set_acpi(chip, ACPI_D3);
chip->master_switch = NULL;
chip->master_volume = NULL;
if (chip->res_io_port) {
snd_es1968_reset(chip);
release_resource(chip->res_io_port);
kfree_nocheck(chip->res_io_port);
}
......
......@@ -414,7 +414,8 @@ MODULE_PARM_SYNTAX(snd_omni, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
#define ICE1712_6FIRE_TX2 0x40 /* 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
......@@ -509,7 +510,7 @@ struct _snd_ice1712 {
snd_i2c_device_t *cs8404; /* CS8404A I2C device */
snd_i2c_device_t *cs8427; /* CS8427 I2C device */
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_stream_bits;
......@@ -2411,14 +2412,13 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
ac97.read = snd_ice1712_ac97_read;
ac97.private_data = ice;
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");
// return err;
} else {
else {
if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0)
return err;
return 0;
}
return 0;
}
/* hmm.. can we have both consumer and pro ac97 mixers? */
if (! (ice->eeprom.aclink & ICE1712_CFG_PRO_I2S)) {
......@@ -2428,11 +2428,10 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
ac97.read = snd_ice1712_pro_ac97_read;
ac97.private_data = ice;
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");
// return err;
}
return 0;
else
return 0;
}
/* I2S mixer only */
strcat(ice->card->mixername, "ICE1712 - multitrack");
......@@ -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 char *texts[4] = {
static char *texts[2] = {
"+4dBu", "-10dBV",
};
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
......@@ -3354,26 +3353,32 @@ static snd_kcontrol_new_t snd_ice1712_ews88d_controls[] __devinitdata = {
* DMX 6Fire controls
*/
#if 0 // XXX not working yet
static int snd_ice1712_6fire_read_pca(ice1712_t *ice)
#define PCF9554_REG_INPUT 0
#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;
snd_i2c_lock(ice->i2c);
byte = 0; /* read port */
byte = reg;
snd_i2c_sendbytes(ice->pcf8575, &byte, 1);
byte = 0;
if (snd_i2c_readbytes(ice->pcf8575, &byte, 1) != 1) {
snd_i2c_unlock(ice->i2c);
printk("cannot read pca\n");
return -EIO;
}
snd_i2c_unlock(ice->i2c);
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];
snd_i2c_lock(ice->i2c);
bytes[0] = 1; /* write port */
bytes[0] = reg;
bytes[1] = data;
if (snd_i2c_sendbytes(ice->pcf8575, bytes, 2) != 2) {
snd_i2c_unlock(ice->i2c);
......@@ -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 data;
if ((data = snd_ice1712_6fire_read_pca(ice)) < 0)
if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
return data;
data = (data >> shift) & 1;
if (invert)
......@@ -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 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;
ndata = data & ~(1 << shift);
if (ucontrol->value.integer.value[0])
......@@ -3423,27 +3428,77 @@ static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_
if (invert)
ndata ^= (1 << shift);
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 0;
}
#define DMX6FIRE_CONTROL(xiface, xname, xshift, xinvert, xaccess) \
{ .iface = xiface,\
static int snd_ice1712_6fire_select_input_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
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,\
.access = xaccess,\
.info = snd_ice1712_6fire_control_info,\
.get = snd_ice1712_6fire_control_get,\
.put = snd_ice1712_6fire_control_put,\
.private_value = xshift | (xinvert << 8),\
}
static snd_kcontrol_new_t snd_ice1712_6fire_led __devinitdata =
DMX6FIRE_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Breakbox LED", 6, 0, 0);
#endif // XXX not working yet
static snd_kcontrol_new_t snd_ice1712_6fire_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.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)
}
break;
case ICE1712_SUBDEVICE_DMX6FIRE:
#if 0 // XXX not working yet
if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", 0x40>>1, &ice->pcf8575)) < 0)
if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->pcf8575)) < 0) {
snd_printk("PCF9554 initialization failed\n");
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");
return err;
}
#endif // XXX not working yet
#endif
break;
case ICE1712_SUBDEVICE_EWS88MT:
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)
}
break;
case ICE1712_SUBDEVICE_DMX6FIRE:
#if 0 // XXX not working yet
err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_led, ice));
if (err < 0)
return err;
#endif
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_controls[idx], ice));
if (err < 0)
return err;
}
break;
}
......
......@@ -326,10 +326,6 @@ struct _snd_intel8x0 {
char ac97_name[32];
char ctrl_name[32];
unsigned long dma_playback_size;
unsigned long dma_capture_size;
unsigned long dma_mic_size;
int irq;
unsigned int mmio;
......@@ -428,7 +424,7 @@ static void iputbyte(intel8x0_t *chip, u32 offset, u8 val)
if (chip->bm_mmio)
writeb(val, chip->remap_bmaddr + offset);
else
return outb(val, chip->bmaddr + offset);
outb(val, chip->bmaddr + offset);
}
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)
writew(val, chip->remap_bmaddr + offset);
else
return outw(val, chip->bmaddr + offset);
outw(val, chip->bmaddr + offset);
}
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)
writel(val, chip->remap_bmaddr + offset);
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)
if (chip->mmio)
writew(val, chip->remap_addr + offset);
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)
if (codecs < 2)
goto __skip_secondary;
for (i = 1; i < codecs; i++) {
ac97.num = i;
if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0)
return err;
chip->ac97[i] = x97;
......@@ -1995,7 +1992,13 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
snd_intel8x0_setup_periods(chip, ichdev);
port = ichdev->reg_offset;
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);
spin_unlock_irqrestore(&chip->reg_lock, flags);
#if 0
......@@ -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 += ichdev->position;
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 */
while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
;
......@@ -2279,6 +2285,7 @@ static struct shortname_table {
{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" },
{ 0x746d, "AMD AMD8111" },
{ 0x7445, "AMD AMD768" },
{ 0x5455, "ALi M5455" },
{ 0, 0 },
};
......
......@@ -1517,10 +1517,8 @@ static int
snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol,
snd_ctl_elem_info_t * uinfo)
{
static char *_texts[5] =
{ "Optical", "Coaxial", "Internal", "XLR" };
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->count = 1;
......@@ -1614,8 +1612,8 @@ snd_rme32_info_clockmode_control(snd_kcontrol_t * kcontrol,
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 = 4;
if (uinfo->value.enumerated.item > 3) {
uinfo->value.enumerated.item = 3;
}
strcpy(uinfo->value.enumerated.name,
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)
new_client->id = keywest_ctx->id++; /* Automatically unique */
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;
}
/* Tell the i2c layer a new client has arrived */
if (i2c_attach_client(new_client)) {
snd_printk(KERN_ERR "tumbler: cannot attach i2c client\n");
err = -ENODEV;
goto __err;
}
......
......@@ -1170,8 +1170,7 @@ static int __init snd_pmac_detect(pmac_t *chip)
// chip->can_byte_swap = 0; /* FIXME: check this */
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
if (device_is_compatible(sound, "tumbler") ||
device_is_compatible(sound, "snapper")) {
if (device_is_compatible(sound, "tumbler")) {
chip->model = PMAC_TUMBLER;
chip->can_capture = 0; /* no capture */
chip->can_duplex = 0;
......@@ -1180,6 +1179,15 @@ static int __init snd_pmac_detect(pmac_t *chip)
chip->freq_table = tumbler_freqs;
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);
if (prop)
chip->device_id = *prop;
......
......@@ -40,6 +40,7 @@
#endif
#endif
#include <linux/nvram.h>
#include <linux/tty.h>
#include <linux/vt_kern.h>
#include <asm/dbdma.h>
#include <asm/prom.h>
......@@ -115,7 +116,7 @@ struct snd_pmac_beep {
*/
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 {
......
......@@ -94,8 +94,10 @@ static int __init snd_pmac_probe(void)
goto __error;
break;
case PMAC_TUMBLER:
strcpy(card->driver, "PMac Tumbler");
strcpy(card->shortname, "PowerMac Tumbler");
case PMAC_SNAPPER:
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",
card->shortname, chip->device_id, chip->subframe);
if ((err = snd_pmac_tumbler_init(chip)) < 0)
......
This diff is collapsed.
......@@ -63,7 +63,7 @@ static unsigned int master_volume_table[] = {
0x00071457, 0x00077fbb, 0x0007f17b,
};
/* treble table */
/* treble table for TAS3001c */
/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
static unsigned int treble_volume_table[] = {
0x96, 0x95, 0x94,
......@@ -93,7 +93,7 @@ static unsigned int treble_volume_table[] = {
0x01,
};
/* bass table */
/* bass table for TAS3001c */
/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
static unsigned int bass_volume_table[] = {
0x86, 0x82, 0x7f,
......@@ -186,3 +186,65 @@ static unsigned int mixer_volume_table[] = {
0x5f4e52, 0x64f403, 0x6aef5d,
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}}");
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 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_DESC(snd_index, "Index value for the USB audio adapter.");
......@@ -63,6 +65,27 @@ MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);
MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(snd_enable, "Enable USB audio adapter.");
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)
subs->running = 0;
#ifndef SND_USB_ASYNC_UNLINK
if (in_interrupt())
return 0;
#endif
alive = 0;
for (i = 0; i < subs->nurbs; i++) {
if (test_bit(i, &subs->active_mask)) {
......@@ -545,7 +572,11 @@ static int deactivate_urbs(snd_usb_substream_t *subs)
}
}
}
#ifdef SND_USB_ASYNC_UNLINK
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
}
u->urb->dev = subs->dev;
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->context = u;
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
u->urb->transfer_buffer_length = NRPACKS * 3;
u->urb->dev = subs->dev;
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->context = u;
u->urb->complete = snd_complete_sync_urb;
......@@ -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
*/
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);
if (card == NULL) {
snd_printk(KERN_ERR "cannot create a card instance %d\n", i);
......
......@@ -73,6 +73,7 @@ struct usb_mixer_elem_info {
int channels;
int val_type;
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
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
} 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.max = cval->max - cval->min;
}
......@@ -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++) {
if (cval->cmask & (1 << c)) {
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;
}
val = get_relative_value(cval, val);
ucontrol->value.integer.value[cnt] = val;
cnt++;
......@@ -525,8 +545,10 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
} else {
/* master channel */
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;
}
val = get_relative_value(cval, val);
ucontrol->value.integer.value[0] = val;
}
......@@ -592,6 +614,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
int nameid = desc[desc[0] - 1];
snd_kcontrol_t *kctl;
usb_mixer_elem_info_t *cval;
int minchn = 0;
if (control == USB_FEATURE_GEQ) {
/* FIXME: not supported yet */
......@@ -614,22 +637,25 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
else {
int i, c = 0;
for (i = 0; i < 16; i++)
if (ctl_mask & (1 << i))
if (ctl_mask & (1 << i)) {
if (! minchn)
minchn = i + 1;
c++;
}
cval->channels = c;
}
/* get min/max values */
if (cval->val_type == USB_MIXER_BOOLEAN ||
cval->val_type == USB_MIXER_INV_BOOLEAN)
cval->val_type == USB_MIXER_INV_BOOLEAN) {
cval->max = 1;
else {
if (get_ctl_value(cval, GET_MAX, ((cval->control+1) << 8) | (ctl_mask ? 1 : 0), &cval->max) < 0 ||
get_ctl_value(cval, GET_MIN, ((cval->control+1) << 8) | (ctl_mask ? 1 : 0), &cval->min) < 0) {
cval->initialized = 1;
} else {
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_magic_kfree(cval);
return;
}
else
cval->initialized = 1;
}
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,
int i, len;
snd_kcontrol_t *kctl;
usb_audio_term_t iterm;
int minchn = 0;
cval = snd_magic_kcalloc(usb_mixer_elem_info_t, 0, GFP_KERNEL);
if (! cval)
......@@ -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)) {
cval->cmask |= (1 << i);
cval->channels++;
if (! minchn)
minchn = i + 1;
}
}
/* get min/max values */
if (get_ctl_value(cval, GET_MAX, ((in_ch+1) << 8) | 1, &cval->max) < 0 ||
get_ctl_value(cval, GET_MIN, ((in_ch+1) << 8) | 1, &cval->min) < 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) | minchn, &cval->min) < 0)
snd_printk(KERN_ERR "cannot get min/max values for mixer\n");
snd_magic_kfree(cval);
return;
}
else
cval->initialized = 1;
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
if (! kctl) {
......@@ -994,11 +1022,10 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char
/* get min/max values */
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_magic_kfree(cval);
continue;
}
else
cval->initialized = 1;
kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
if (! kctl) {
......@@ -1158,6 +1185,7 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned
cval->channels = 1;
cval->min = 1;
cval->max = num_ins;
cval->initialized = 1;
namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL);
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