diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-31 07:37:33 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-01-02 14:14:55 -0500 |
commit | 9baed99ee7a834b1f2599e13f219087f01c63f38 (patch) | |
tree | 7e2f6b062e82db931d39cb13058895190b27e7d1 /drivers/media | |
parent | 0b82c5d6748a15758875f78ac772c6d48ebead2a (diff) |
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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-audio.c | 91 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 2 |
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 | ||
203 | static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) | 203 | static 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: | |||
311 | static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | 311 | static 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 | ||
421 | static int em28xx_audio_init(struct em28xx *dev) | 421 | static 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; |