aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c91
-rw-r--r--drivers/media/video/em28xx/em28xx.h2
2 files changed, 42 insertions, 51 deletions
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 15c03f0e69ad..94378ccb7505 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -62,9 +62,9 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
62 62
63 dprintk("Stopping isoc\n"); 63 dprintk("Stopping isoc\n");
64 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 64 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
65 usb_unlink_urb(dev->adev->urb[i]); 65 usb_unlink_urb(dev->adev.urb[i]);
66 usb_free_urb(dev->adev->urb[i]); 66 usb_free_urb(dev->adev.urb[i]);
67 dev->adev->urb[i] = NULL; 67 dev->adev.urb[i] = NULL;
68 } 68 }
69 69
70 return 0; 70 return 0;
@@ -81,8 +81,8 @@ static void em28xx_audio_isocirq(struct urb *urb)
81 unsigned int stride; 81 unsigned int stride;
82 struct snd_pcm_substream *substream; 82 struct snd_pcm_substream *substream;
83 struct snd_pcm_runtime *runtime; 83 struct snd_pcm_runtime *runtime;
84 if (dev->adev->capture_pcm_substream) { 84 if (dev->adev.capture_pcm_substream) {
85 substream = dev->adev->capture_pcm_substream; 85 substream = dev->adev.capture_pcm_substream;
86 runtime = substream->runtime; 86 runtime = substream->runtime;
87 stride = runtime->frame_bits >> 3; 87 stride = runtime->frame_bits >> 3;
88 88
@@ -95,7 +95,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
95 if (!length) 95 if (!length)
96 continue; 96 continue;
97 97
98 oldptr = dev->adev->hwptr_done_capture; 98 oldptr = dev->adev.hwptr_done_capture;
99 if (oldptr + length >= runtime->buffer_size) { 99 if (oldptr + length >= runtime->buffer_size) {
100 unsigned int cnt = 100 unsigned int cnt =
101 runtime->buffer_size - oldptr; 101 runtime->buffer_size - oldptr;
@@ -110,16 +110,16 @@ static void em28xx_audio_isocirq(struct urb *urb)
110 110
111 snd_pcm_stream_lock(substream); 111 snd_pcm_stream_lock(substream);
112 112
113 dev->adev->hwptr_done_capture += length; 113 dev->adev.hwptr_done_capture += length;
114 if (dev->adev->hwptr_done_capture >= 114 if (dev->adev.hwptr_done_capture >=
115 runtime->buffer_size) 115 runtime->buffer_size)
116 dev->adev->hwptr_done_capture -= 116 dev->adev.hwptr_done_capture -=
117 runtime->buffer_size; 117 runtime->buffer_size;
118 118
119 dev->adev->capture_transfer_done += length; 119 dev->adev.capture_transfer_done += length;
120 if (dev->adev->capture_transfer_done >= 120 if (dev->adev.capture_transfer_done >=
121 runtime->period_size) { 121 runtime->period_size) {
122 dev->adev->capture_transfer_done -= 122 dev->adev.capture_transfer_done -=
123 runtime->period_size; 123 runtime->period_size;
124 period_elapsed = 1; 124 period_elapsed = 1;
125 } 125 }
@@ -131,7 +131,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
131 } 131 }
132 urb->status = 0; 132 urb->status = 0;
133 133
134 if (dev->adev->shutdown) 134 if (dev->adev.shutdown)
135 return; 135 return;
136 136
137 status = usb_submit_urb(urb, GFP_ATOMIC); 137 status = usb_submit_urb(urb, GFP_ATOMIC);
@@ -154,17 +154,17 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
154 struct urb *urb; 154 struct urb *urb;
155 int j, k; 155 int j, k;
156 156
157 dev->adev->transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC); 157 dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
158 if (!dev->adev->transfer_buffer[i]) 158 if (!dev->adev.transfer_buffer[i])
159 return -ENOMEM; 159 return -ENOMEM;
160 160
161 memset(dev->adev->transfer_buffer[i], 0x80, sb_size); 161 memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
162 urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); 162 urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
163 if (!urb) { 163 if (!urb) {
164 em28xx_errdev("usb_alloc_urb failed!\n"); 164 em28xx_errdev("usb_alloc_urb failed!\n");
165 for (j = 0; j < i; j++) { 165 for (j = 0; j < i; j++) {
166 usb_free_urb(dev->adev->urb[j]); 166 usb_free_urb(dev->adev.urb[j]);
167 kfree(dev->adev->transfer_buffer[j]); 167 kfree(dev->adev.transfer_buffer[j]);
168 } 168 }
169 return -ENOMEM; 169 return -ENOMEM;
170 } 170 }
@@ -173,7 +173,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
173 urb->context = dev; 173 urb->context = dev;
174 urb->pipe = usb_rcvisocpipe(dev->udev, 0x83); 174 urb->pipe = usb_rcvisocpipe(dev->udev, 0x83);
175 urb->transfer_flags = URB_ISO_ASAP; 175 urb->transfer_flags = URB_ISO_ASAP;
176 urb->transfer_buffer = dev->adev->transfer_buffer[i]; 176 urb->transfer_buffer = dev->adev.transfer_buffer[i];
177 urb->interval = 1; 177 urb->interval = 1;
178 urb->complete = em28xx_audio_isocirq; 178 urb->complete = em28xx_audio_isocirq;
179 urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS; 179 urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
@@ -185,11 +185,11 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
185 urb->iso_frame_desc[j].length = 185 urb->iso_frame_desc[j].length =
186 EM28XX_AUDIO_MAX_PACKET_SIZE; 186 EM28XX_AUDIO_MAX_PACKET_SIZE;
187 } 187 }
188 dev->adev->urb[i] = urb; 188 dev->adev.urb[i] = urb;
189 } 189 }
190 190
191 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 191 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
192 errCode = usb_submit_urb(dev->adev->urb[i], GFP_ATOMIC); 192 errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
193 if (errCode) { 193 if (errCode) {
194 em28xx_isoc_audio_deinit(dev); 194 em28xx_isoc_audio_deinit(dev);
195 195
@@ -202,16 +202,16 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
202 202
203static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) 203static int em28xx_cmd(struct em28xx *dev, int cmd, int arg)
204{ 204{
205 dprintk("%s transfer\n", (dev->adev->capture_stream == STREAM_ON)? 205 dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ?
206 "stop" : "start"); 206 "stop" : "start");
207 207
208 switch (cmd) { 208 switch (cmd) {
209 case EM28XX_CAPTURE_STREAM_EN: 209 case EM28XX_CAPTURE_STREAM_EN:
210 if (dev->adev->capture_stream == STREAM_OFF && arg == 1) { 210 if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
211 dev->adev->capture_stream = STREAM_ON; 211 dev->adev.capture_stream = STREAM_ON;
212 em28xx_init_audio_isoc(dev); 212 em28xx_init_audio_isoc(dev);
213 } else if (dev->adev->capture_stream == STREAM_ON && arg == 0) { 213 } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
214 dev->adev->capture_stream = STREAM_OFF; 214 dev->adev.capture_stream = STREAM_OFF;
215 em28xx_isoc_audio_deinit(dev); 215 em28xx_isoc_audio_deinit(dev);
216 } else { 216 } else {
217 printk(KERN_ERR "An underrun very likely occurred. " 217 printk(KERN_ERR "An underrun very likely occurred. "
@@ -289,17 +289,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
289 goto err; 289 goto err;
290 290
291 runtime->hw = snd_em28xx_hw_capture; 291 runtime->hw = snd_em28xx_hw_capture;
292 if (dev->alt == 0 && dev->adev->users == 0) { 292 if (dev->alt == 0 && dev->adev.users == 0) {
293 int errCode; 293 int errCode;
294 dev->alt = 7; 294 dev->alt = 7;
295 errCode = usb_set_interface(dev->udev, 0, 7); 295 errCode = usb_set_interface(dev->udev, 0, 7);
296 dprintk("changing alternate number to 7\n"); 296 dprintk("changing alternate number to 7\n");
297 } 297 }
298 298
299 dev->adev->users++; 299 dev->adev.users++;
300 300
301 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 301 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
302 dev->adev->capture_pcm_substream = substream; 302 dev->adev.capture_pcm_substream = substream;
303 runtime->private_data = dev; 303 runtime->private_data = dev;
304 304
305 return 0; 305 return 0;
@@ -311,7 +311,7 @@ err:
311static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) 311static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
312{ 312{
313 struct em28xx *dev = snd_pcm_substream_chip(substream); 313 struct em28xx *dev = snd_pcm_substream_chip(substream);
314 dev->adev->users--; 314 dev->adev.users--;
315 315
316 dprintk("closing device\n"); 316 dprintk("closing device\n");
317 317
@@ -320,10 +320,10 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
320 em28xx_audio_analog_set(dev); 320 em28xx_audio_analog_set(dev);
321 mutex_unlock(&dev->lock); 321 mutex_unlock(&dev->lock);
322 322
323 if (dev->adev->users == 0 && dev->adev->shutdown == 1) { 323 if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
324 dprintk("audio users: %d\n", dev->adev->users); 324 dprintk("audio users: %d\n", dev->adev.users);
325 dprintk("disabling audio stream!\n"); 325 dprintk("disabling audio stream!\n");
326 dev->adev->shutdown = 0; 326 dev->adev.shutdown = 0;
327 dprintk("released lock\n"); 327 dprintk("released lock\n");
328 em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); 328 em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
329 } 329 }
@@ -356,7 +356,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
356 356
357 dprintk("Stop capture, if needed\n"); 357 dprintk("Stop capture, if needed\n");
358 358
359 if (dev->adev->capture_stream == STREAM_ON) 359 if (dev->adev.capture_stream == STREAM_ON)
360 em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); 360 em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
361 361
362 return 0; 362 return 0;
@@ -379,7 +379,7 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
379 em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); 379 em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);
380 return 0; 380 return 0;
381 case SNDRV_PCM_TRIGGER_STOP: 381 case SNDRV_PCM_TRIGGER_STOP:
382 dev->adev->shutdown = 1; 382 dev->adev.shutdown = 1;
383 return 0; 383 return 0;
384 default: 384 default:
385 return -EINVAL; 385 return -EINVAL;
@@ -393,7 +393,7 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
393 393
394 snd_pcm_uframes_t hwptr_done; 394 snd_pcm_uframes_t hwptr_done;
395 dev = snd_pcm_substream_chip(substream); 395 dev = snd_pcm_substream_chip(substream);
396 hwptr_done = dev->adev->hwptr_done_capture; 396 hwptr_done = dev->adev.hwptr_done_capture;
397 397
398 return hwptr_done; 398 return hwptr_done;
399} 399}
@@ -420,7 +420,7 @@ static struct snd_pcm_ops snd_em28xx_pcm_capture = {
420 420
421static int em28xx_audio_init(struct em28xx *dev) 421static int em28xx_audio_init(struct em28xx *dev)
422{ 422{
423 struct em28xx_audio *adev; 423 struct em28xx_audio *adev = &dev->adev;
424 struct snd_pcm *pcm; 424 struct snd_pcm *pcm;
425 struct snd_card *card; 425 struct snd_card *card;
426 static int devnr; 426 static int devnr;
@@ -438,16 +438,9 @@ static int em28xx_audio_init(struct em28xx *dev)
438 printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " 438 printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
439 "Rechberger\n"); 439 "Rechberger\n");
440 440
441 adev = kzalloc(sizeof(*adev), GFP_KERNEL);
442 if (!adev) {
443 printk(KERN_ERR "em28xx-audio.c: out of memory\n");
444 return -1;
445 }
446 card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0); 441 card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);
447 if (card == NULL) { 442 if (card == NULL)
448 kfree(adev);
449 return -ENOMEM; 443 return -ENOMEM;
450 }
451 444
452 spin_lock_init(&adev->slock); 445 spin_lock_init(&adev->slock);
453 err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); 446 err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
@@ -471,7 +464,6 @@ static int em28xx_audio_init(struct em28xx *dev)
471 } 464 }
472 adev->sndcard = card; 465 adev->sndcard = card;
473 adev->udev = dev->udev; 466 adev->udev = dev->udev;
474 dev->adev = adev;
475 467
476 return 0; 468 return 0;
477} 469}
@@ -488,10 +480,9 @@ static int em28xx_audio_fini(struct em28xx *dev)
488 return 0; 480 return 0;
489 } 481 }
490 482
491 if (dev->adev) { 483 if (dev->adev.sndcard) {
492 snd_card_free(dev->adev->sndcard); 484 snd_card_free(dev->adev.sndcard);
493 kfree(dev->adev); 485 dev->adev.sndcard = NULL;
494 dev->adev = NULL;
495 } 486 }
496 487
497 return 0; 488 return 0;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index afc5f6d17e0f..6c6b94aa05b2 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -473,7 +473,7 @@ struct em28xx {
473 unsigned long i2c_hash; /* i2c devicelist hash - 473 unsigned long i2c_hash; /* i2c devicelist hash -
474 for boards with generic ID */ 474 for boards with generic ID */
475 475
476 struct em28xx_audio *adev; 476 struct em28xx_audio adev;
477 477
478 /* states */ 478 /* states */
479 enum em28xx_dev_state state; 479 enum em28xx_dev_state state;