V4L/DVB (10163): em28xx: allocate adev together with struct em28xx dev
Some devices require different setups on struct_audio. Due to that, we may need to change some fields at dev.adev during device probe. So, this patch moves the dynamic memory allocation of adev at em28xx-alsa to the dynamic allocation of struct em28xx dev that happens during device probe. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Родитель
0b82c5d674
Коммит
9baed99ee7
|
@ -62,9 +62,9 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
|
||||||
|
|
||||||
dprintk("Stopping isoc\n");
|
dprintk("Stopping isoc\n");
|
||||||
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
|
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
|
||||||
usb_unlink_urb(dev->adev->urb[i]);
|
usb_unlink_urb(dev->adev.urb[i]);
|
||||||
usb_free_urb(dev->adev->urb[i]);
|
usb_free_urb(dev->adev.urb[i]);
|
||||||
dev->adev->urb[i] = NULL;
|
dev->adev.urb[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -81,8 +81,8 @@ static void em28xx_audio_isocirq(struct urb *urb)
|
||||||
unsigned int stride;
|
unsigned int stride;
|
||||||
struct snd_pcm_substream *substream;
|
struct snd_pcm_substream *substream;
|
||||||
struct snd_pcm_runtime *runtime;
|
struct snd_pcm_runtime *runtime;
|
||||||
if (dev->adev->capture_pcm_substream) {
|
if (dev->adev.capture_pcm_substream) {
|
||||||
substream = dev->adev->capture_pcm_substream;
|
substream = dev->adev.capture_pcm_substream;
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
stride = runtime->frame_bits >> 3;
|
stride = runtime->frame_bits >> 3;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
|
||||||
if (!length)
|
if (!length)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
oldptr = dev->adev->hwptr_done_capture;
|
oldptr = dev->adev.hwptr_done_capture;
|
||||||
if (oldptr + length >= runtime->buffer_size) {
|
if (oldptr + length >= runtime->buffer_size) {
|
||||||
unsigned int cnt =
|
unsigned int cnt =
|
||||||
runtime->buffer_size - oldptr;
|
runtime->buffer_size - oldptr;
|
||||||
|
@ -110,16 +110,16 @@ static void em28xx_audio_isocirq(struct urb *urb)
|
||||||
|
|
||||||
snd_pcm_stream_lock(substream);
|
snd_pcm_stream_lock(substream);
|
||||||
|
|
||||||
dev->adev->hwptr_done_capture += length;
|
dev->adev.hwptr_done_capture += length;
|
||||||
if (dev->adev->hwptr_done_capture >=
|
if (dev->adev.hwptr_done_capture >=
|
||||||
runtime->buffer_size)
|
runtime->buffer_size)
|
||||||
dev->adev->hwptr_done_capture -=
|
dev->adev.hwptr_done_capture -=
|
||||||
runtime->buffer_size;
|
runtime->buffer_size;
|
||||||
|
|
||||||
dev->adev->capture_transfer_done += length;
|
dev->adev.capture_transfer_done += length;
|
||||||
if (dev->adev->capture_transfer_done >=
|
if (dev->adev.capture_transfer_done >=
|
||||||
runtime->period_size) {
|
runtime->period_size) {
|
||||||
dev->adev->capture_transfer_done -=
|
dev->adev.capture_transfer_done -=
|
||||||
runtime->period_size;
|
runtime->period_size;
|
||||||
period_elapsed = 1;
|
period_elapsed = 1;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
|
||||||
}
|
}
|
||||||
urb->status = 0;
|
urb->status = 0;
|
||||||
|
|
||||||
if (dev->adev->shutdown)
|
if (dev->adev.shutdown)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
status = usb_submit_urb(urb, GFP_ATOMIC);
|
status = usb_submit_urb(urb, GFP_ATOMIC);
|
||||||
|
@ -154,17 +154,17 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
int j, k;
|
int j, k;
|
||||||
|
|
||||||
dev->adev->transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
|
dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
|
||||||
if (!dev->adev->transfer_buffer[i])
|
if (!dev->adev.transfer_buffer[i])
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memset(dev->adev->transfer_buffer[i], 0x80, sb_size);
|
memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
|
||||||
urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
|
urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
|
||||||
if (!urb) {
|
if (!urb) {
|
||||||
em28xx_errdev("usb_alloc_urb failed!\n");
|
em28xx_errdev("usb_alloc_urb failed!\n");
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
usb_free_urb(dev->adev->urb[j]);
|
usb_free_urb(dev->adev.urb[j]);
|
||||||
kfree(dev->adev->transfer_buffer[j]);
|
kfree(dev->adev.transfer_buffer[j]);
|
||||||
}
|
}
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
|
||||||
urb->context = dev;
|
urb->context = dev;
|
||||||
urb->pipe = usb_rcvisocpipe(dev->udev, 0x83);
|
urb->pipe = usb_rcvisocpipe(dev->udev, 0x83);
|
||||||
urb->transfer_flags = URB_ISO_ASAP;
|
urb->transfer_flags = URB_ISO_ASAP;
|
||||||
urb->transfer_buffer = dev->adev->transfer_buffer[i];
|
urb->transfer_buffer = dev->adev.transfer_buffer[i];
|
||||||
urb->interval = 1;
|
urb->interval = 1;
|
||||||
urb->complete = em28xx_audio_isocirq;
|
urb->complete = em28xx_audio_isocirq;
|
||||||
urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
|
urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
|
||||||
|
@ -185,11 +185,11 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
|
||||||
urb->iso_frame_desc[j].length =
|
urb->iso_frame_desc[j].length =
|
||||||
EM28XX_AUDIO_MAX_PACKET_SIZE;
|
EM28XX_AUDIO_MAX_PACKET_SIZE;
|
||||||
}
|
}
|
||||||
dev->adev->urb[i] = urb;
|
dev->adev.urb[i] = urb;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
|
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
|
||||||
errCode = usb_submit_urb(dev->adev->urb[i], GFP_ATOMIC);
|
errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
|
||||||
if (errCode) {
|
if (errCode) {
|
||||||
em28xx_isoc_audio_deinit(dev);
|
em28xx_isoc_audio_deinit(dev);
|
||||||
|
|
||||||
|
@ -202,16 +202,16 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
|
||||||
|
|
||||||
static int em28xx_cmd(struct em28xx *dev, int cmd, int arg)
|
static int em28xx_cmd(struct em28xx *dev, int cmd, int arg)
|
||||||
{
|
{
|
||||||
dprintk("%s transfer\n", (dev->adev->capture_stream == STREAM_ON)?
|
dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ?
|
||||||
"stop" : "start");
|
"stop" : "start");
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case EM28XX_CAPTURE_STREAM_EN:
|
case EM28XX_CAPTURE_STREAM_EN:
|
||||||
if (dev->adev->capture_stream == STREAM_OFF && arg == 1) {
|
if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
|
||||||
dev->adev->capture_stream = STREAM_ON;
|
dev->adev.capture_stream = STREAM_ON;
|
||||||
em28xx_init_audio_isoc(dev);
|
em28xx_init_audio_isoc(dev);
|
||||||
} else if (dev->adev->capture_stream == STREAM_ON && arg == 0) {
|
} else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
|
||||||
dev->adev->capture_stream = STREAM_OFF;
|
dev->adev.capture_stream = STREAM_OFF;
|
||||||
em28xx_isoc_audio_deinit(dev);
|
em28xx_isoc_audio_deinit(dev);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_ERR "An underrun very likely occurred. "
|
printk(KERN_ERR "An underrun very likely occurred. "
|
||||||
|
@ -289,17 +289,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
runtime->hw = snd_em28xx_hw_capture;
|
runtime->hw = snd_em28xx_hw_capture;
|
||||||
if (dev->alt == 0 && dev->adev->users == 0) {
|
if (dev->alt == 0 && dev->adev.users == 0) {
|
||||||
int errCode;
|
int errCode;
|
||||||
dev->alt = 7;
|
dev->alt = 7;
|
||||||
errCode = usb_set_interface(dev->udev, 0, 7);
|
errCode = usb_set_interface(dev->udev, 0, 7);
|
||||||
dprintk("changing alternate number to 7\n");
|
dprintk("changing alternate number to 7\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->adev->users++;
|
dev->adev.users++;
|
||||||
|
|
||||||
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
|
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
|
||||||
dev->adev->capture_pcm_substream = substream;
|
dev->adev.capture_pcm_substream = substream;
|
||||||
runtime->private_data = dev;
|
runtime->private_data = dev;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -311,7 +311,7 @@ err:
|
||||||
static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
|
static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct em28xx *dev = snd_pcm_substream_chip(substream);
|
struct em28xx *dev = snd_pcm_substream_chip(substream);
|
||||||
dev->adev->users--;
|
dev->adev.users--;
|
||||||
|
|
||||||
dprintk("closing device\n");
|
dprintk("closing device\n");
|
||||||
|
|
||||||
|
@ -320,10 +320,10 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
|
||||||
em28xx_audio_analog_set(dev);
|
em28xx_audio_analog_set(dev);
|
||||||
mutex_unlock(&dev->lock);
|
mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
if (dev->adev->users == 0 && dev->adev->shutdown == 1) {
|
if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
|
||||||
dprintk("audio users: %d\n", dev->adev->users);
|
dprintk("audio users: %d\n", dev->adev.users);
|
||||||
dprintk("disabling audio stream!\n");
|
dprintk("disabling audio stream!\n");
|
||||||
dev->adev->shutdown = 0;
|
dev->adev.shutdown = 0;
|
||||||
dprintk("released lock\n");
|
dprintk("released lock\n");
|
||||||
em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
|
em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
|
||||||
|
|
||||||
dprintk("Stop capture, if needed\n");
|
dprintk("Stop capture, if needed\n");
|
||||||
|
|
||||||
if (dev->adev->capture_stream == STREAM_ON)
|
if (dev->adev.capture_stream == STREAM_ON)
|
||||||
em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
|
em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -379,7 +379,7 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
|
||||||
em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);
|
em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);
|
||||||
return 0;
|
return 0;
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
case SNDRV_PCM_TRIGGER_STOP:
|
||||||
dev->adev->shutdown = 1;
|
dev->adev.shutdown = 1;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -393,7 +393,7 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
|
||||||
|
|
||||||
snd_pcm_uframes_t hwptr_done;
|
snd_pcm_uframes_t hwptr_done;
|
||||||
dev = snd_pcm_substream_chip(substream);
|
dev = snd_pcm_substream_chip(substream);
|
||||||
hwptr_done = dev->adev->hwptr_done_capture;
|
hwptr_done = dev->adev.hwptr_done_capture;
|
||||||
|
|
||||||
return hwptr_done;
|
return hwptr_done;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ static struct snd_pcm_ops snd_em28xx_pcm_capture = {
|
||||||
|
|
||||||
static int em28xx_audio_init(struct em28xx *dev)
|
static int em28xx_audio_init(struct em28xx *dev)
|
||||||
{
|
{
|
||||||
struct em28xx_audio *adev;
|
struct em28xx_audio *adev = &dev->adev;
|
||||||
struct snd_pcm *pcm;
|
struct snd_pcm *pcm;
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
static int devnr;
|
static int devnr;
|
||||||
|
@ -438,16 +438,9 @@ static int em28xx_audio_init(struct em28xx *dev)
|
||||||
printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
|
printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
|
||||||
"Rechberger\n");
|
"Rechberger\n");
|
||||||
|
|
||||||
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
|
|
||||||
if (!adev) {
|
|
||||||
printk(KERN_ERR "em28xx-audio.c: out of memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);
|
card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);
|
||||||
if (card == NULL) {
|
if (card == NULL)
|
||||||
kfree(adev);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_init(&adev->slock);
|
spin_lock_init(&adev->slock);
|
||||||
err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
|
err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
|
||||||
|
@ -471,7 +464,6 @@ static int em28xx_audio_init(struct em28xx *dev)
|
||||||
}
|
}
|
||||||
adev->sndcard = card;
|
adev->sndcard = card;
|
||||||
adev->udev = dev->udev;
|
adev->udev = dev->udev;
|
||||||
dev->adev = adev;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -488,10 +480,9 @@ static int em28xx_audio_fini(struct em28xx *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->adev) {
|
if (dev->adev.sndcard) {
|
||||||
snd_card_free(dev->adev->sndcard);
|
snd_card_free(dev->adev.sndcard);
|
||||||
kfree(dev->adev);
|
dev->adev.sndcard = NULL;
|
||||||
dev->adev = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -473,7 +473,7 @@ struct em28xx {
|
||||||
unsigned long i2c_hash; /* i2c devicelist hash -
|
unsigned long i2c_hash; /* i2c devicelist hash -
|
||||||
for boards with generic ID */
|
for boards with generic ID */
|
||||||
|
|
||||||
struct em28xx_audio *adev;
|
struct em28xx_audio adev;
|
||||||
|
|
||||||
/* states */
|
/* states */
|
||||||
enum em28xx_dev_state state;
|
enum em28xx_dev_state state;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче