diff options
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r-- | drivers/media/video/vivi.c | 806 |
1 files changed, 323 insertions, 483 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index cdbe70385c12..e17b6fee046b 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -13,29 +13,23 @@ | |||
13 | * License, or (at your option) any later version | 13 | * License, or (at your option) any later version |
14 | */ | 14 | */ |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/delay.h> | ||
17 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
18 | #include <linux/fs.h> | ||
19 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
20 | #include <linux/slab.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/init.h> | 18 | #include <linux/init.h> |
24 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
25 | #include <linux/pci.h> | 20 | #include <linux/slab.h> |
26 | #include <linux/random.h> | 21 | #include <linux/font.h> |
27 | #include <linux/version.h> | 22 | #include <linux/version.h> |
28 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
29 | #include <linux/videodev2.h> | 24 | #include <linux/videodev2.h> |
30 | #include <linux/dma-mapping.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
33 | #include <linux/highmem.h> | 26 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) |
34 | #include <linux/freezer.h> | 27 | #include <linux/freezer.h> |
28 | #endif | ||
35 | #include <media/videobuf-vmalloc.h> | 29 | #include <media/videobuf-vmalloc.h> |
36 | #include <media/v4l2-device.h> | 30 | #include <media/v4l2-device.h> |
37 | #include <media/v4l2-ioctl.h> | 31 | #include <media/v4l2-ioctl.h> |
38 | #include "font.h" | 32 | #include <media/v4l2-common.h> |
39 | 33 | ||
40 | #define VIVI_MODULE_NAME "vivi" | 34 | #define VIVI_MODULE_NAME "vivi" |
41 | 35 | ||
@@ -44,8 +38,11 @@ | |||
44 | #define WAKE_DENOMINATOR 1001 | 38 | #define WAKE_DENOMINATOR 1001 |
45 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ | 39 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ |
46 | 40 | ||
41 | #define MAX_WIDTH 1920 | ||
42 | #define MAX_HEIGHT 1200 | ||
43 | |||
47 | #define VIVI_MAJOR_VERSION 0 | 44 | #define VIVI_MAJOR_VERSION 0 |
48 | #define VIVI_MINOR_VERSION 6 | 45 | #define VIVI_MINOR_VERSION 7 |
49 | #define VIVI_RELEASE 0 | 46 | #define VIVI_RELEASE 0 |
50 | #define VIVI_VERSION \ | 47 | #define VIVI_VERSION \ |
51 | KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) | 48 | KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) |
@@ -70,56 +67,8 @@ static unsigned int vid_limit = 16; | |||
70 | module_param(vid_limit, uint, 0644); | 67 | module_param(vid_limit, uint, 0644); |
71 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); | 68 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); |
72 | 69 | ||
73 | 70 | /* Global font descriptor */ | |
74 | /* supported controls */ | 71 | static const u8 *font8x16; |
75 | static struct v4l2_queryctrl vivi_qctrl[] = { | ||
76 | { | ||
77 | .id = V4L2_CID_AUDIO_VOLUME, | ||
78 | .name = "Volume", | ||
79 | .minimum = 0, | ||
80 | .maximum = 65535, | ||
81 | .step = 65535/100, | ||
82 | .default_value = 65535, | ||
83 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
84 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
85 | }, { | ||
86 | .id = V4L2_CID_BRIGHTNESS, | ||
87 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
88 | .name = "Brightness", | ||
89 | .minimum = 0, | ||
90 | .maximum = 255, | ||
91 | .step = 1, | ||
92 | .default_value = 127, | ||
93 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
94 | }, { | ||
95 | .id = V4L2_CID_CONTRAST, | ||
96 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
97 | .name = "Contrast", | ||
98 | .minimum = 0, | ||
99 | .maximum = 255, | ||
100 | .step = 0x1, | ||
101 | .default_value = 0x10, | ||
102 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
103 | }, { | ||
104 | .id = V4L2_CID_SATURATION, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
106 | .name = "Saturation", | ||
107 | .minimum = 0, | ||
108 | .maximum = 255, | ||
109 | .step = 0x1, | ||
110 | .default_value = 127, | ||
111 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
112 | }, { | ||
113 | .id = V4L2_CID_HUE, | ||
114 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
115 | .name = "Hue", | ||
116 | .minimum = -128, | ||
117 | .maximum = 127, | ||
118 | .step = 0x1, | ||
119 | .default_value = 0, | ||
120 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
121 | } | ||
122 | }; | ||
123 | 72 | ||
124 | #define dprintk(dev, level, fmt, arg...) \ | 73 | #define dprintk(dev, level, fmt, arg...) \ |
125 | v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) | 74 | v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) |
@@ -214,41 +163,38 @@ struct vivi_dev { | |||
214 | struct list_head vivi_devlist; | 163 | struct list_head vivi_devlist; |
215 | struct v4l2_device v4l2_dev; | 164 | struct v4l2_device v4l2_dev; |
216 | 165 | ||
166 | /* controls */ | ||
167 | int brightness; | ||
168 | int contrast; | ||
169 | int saturation; | ||
170 | int hue; | ||
171 | int volume; | ||
172 | |||
217 | spinlock_t slock; | 173 | spinlock_t slock; |
218 | struct mutex mutex; | 174 | struct mutex mutex; |
219 | 175 | ||
220 | int users; | ||
221 | |||
222 | /* various device info */ | 176 | /* various device info */ |
223 | struct video_device *vfd; | 177 | struct video_device *vfd; |
224 | 178 | ||
225 | struct vivi_dmaqueue vidq; | 179 | struct vivi_dmaqueue vidq; |
226 | 180 | ||
227 | /* Several counters */ | 181 | /* Several counters */ |
228 | int h, m, s, ms; | 182 | unsigned ms; |
229 | unsigned long jiffies; | 183 | unsigned long jiffies; |
230 | char timestr[13]; | ||
231 | 184 | ||
232 | int mv_count; /* Controls bars movement */ | 185 | int mv_count; /* Controls bars movement */ |
233 | 186 | ||
234 | /* Input Number */ | 187 | /* Input Number */ |
235 | int input; | 188 | int input; |
236 | 189 | ||
237 | /* Control 'registers' */ | ||
238 | int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; | ||
239 | }; | ||
240 | |||
241 | struct vivi_fh { | ||
242 | struct vivi_dev *dev; | ||
243 | |||
244 | /* video capture */ | 190 | /* video capture */ |
245 | struct vivi_fmt *fmt; | 191 | struct vivi_fmt *fmt; |
246 | unsigned int width, height; | 192 | unsigned int width, height; |
247 | struct videobuf_queue vb_vidq; | 193 | struct videobuf_queue vb_vidq; |
248 | 194 | ||
249 | enum v4l2_buf_type type; | 195 | unsigned long generating; |
250 | unsigned char bars[8][3]; | 196 | u8 bars[9][3]; |
251 | int input; /* Input Number on bars */ | 197 | u8 line[MAX_WIDTH * 4]; |
252 | }; | 198 | }; |
253 | 199 | ||
254 | /* ------------------------------------------------------------------ | 200 | /* ------------------------------------------------------------------ |
@@ -259,19 +205,20 @@ struct vivi_fh { | |||
259 | 205 | ||
260 | enum colors { | 206 | enum colors { |
261 | WHITE, | 207 | WHITE, |
262 | AMBAR, | 208 | AMBER, |
263 | CYAN, | 209 | CYAN, |
264 | GREEN, | 210 | GREEN, |
265 | MAGENTA, | 211 | MAGENTA, |
266 | RED, | 212 | RED, |
267 | BLUE, | 213 | BLUE, |
268 | BLACK, | 214 | BLACK, |
215 | TEXT_BLACK, | ||
269 | }; | 216 | }; |
270 | 217 | ||
271 | /* R G B */ | 218 | /* R G B */ |
272 | #define COLOR_WHITE {204, 204, 204} | 219 | #define COLOR_WHITE {204, 204, 204} |
273 | #define COLOR_AMBAR {208, 208, 0} | 220 | #define COLOR_AMBER {208, 208, 0} |
274 | #define COLOR_CIAN { 0, 206, 206} | 221 | #define COLOR_CYAN { 0, 206, 206} |
275 | #define COLOR_GREEN { 0, 239, 0} | 222 | #define COLOR_GREEN { 0, 239, 0} |
276 | #define COLOR_MAGENTA {239, 0, 239} | 223 | #define COLOR_MAGENTA {239, 0, 239} |
277 | #define COLOR_RED {205, 0, 0} | 224 | #define COLOR_RED {205, 0, 0} |
@@ -279,56 +226,24 @@ enum colors { | |||
279 | #define COLOR_BLACK { 0, 0, 0} | 226 | #define COLOR_BLACK { 0, 0, 0} |
280 | 227 | ||
281 | struct bar_std { | 228 | struct bar_std { |
282 | u8 bar[8][3]; | 229 | u8 bar[9][3]; |
283 | }; | 230 | }; |
284 | 231 | ||
285 | /* Maximum number of bars are 10 - otherwise, the input print code | 232 | /* Maximum number of bars are 10 - otherwise, the input print code |
286 | should be modified */ | 233 | should be modified */ |
287 | static struct bar_std bars[] = { | 234 | static struct bar_std bars[] = { |
288 | { /* Standard ITU-R color bar sequence */ | 235 | { /* Standard ITU-R color bar sequence */ |
289 | { | 236 | { COLOR_WHITE, COLOR_AMBER, COLOR_CYAN, COLOR_GREEN, |
290 | COLOR_WHITE, | 237 | COLOR_MAGENTA, COLOR_RED, COLOR_BLUE, COLOR_BLACK, COLOR_BLACK } |
291 | COLOR_AMBAR, | ||
292 | COLOR_CIAN, | ||
293 | COLOR_GREEN, | ||
294 | COLOR_MAGENTA, | ||
295 | COLOR_RED, | ||
296 | COLOR_BLUE, | ||
297 | COLOR_BLACK, | ||
298 | } | ||
299 | }, { | 238 | }, { |
300 | { | 239 | { COLOR_WHITE, COLOR_AMBER, COLOR_BLACK, COLOR_WHITE, |
301 | COLOR_WHITE, | 240 | COLOR_AMBER, COLOR_BLACK, COLOR_WHITE, COLOR_AMBER, COLOR_BLACK } |
302 | COLOR_AMBAR, | ||
303 | COLOR_BLACK, | ||
304 | COLOR_WHITE, | ||
305 | COLOR_AMBAR, | ||
306 | COLOR_BLACK, | ||
307 | COLOR_WHITE, | ||
308 | COLOR_AMBAR, | ||
309 | } | ||
310 | }, { | 241 | }, { |
311 | { | 242 | { COLOR_WHITE, COLOR_CYAN, COLOR_BLACK, COLOR_WHITE, |
312 | COLOR_WHITE, | 243 | COLOR_CYAN, COLOR_BLACK, COLOR_WHITE, COLOR_CYAN, COLOR_BLACK } |
313 | COLOR_CIAN, | ||
314 | COLOR_BLACK, | ||
315 | COLOR_WHITE, | ||
316 | COLOR_CIAN, | ||
317 | COLOR_BLACK, | ||
318 | COLOR_WHITE, | ||
319 | COLOR_CIAN, | ||
320 | } | ||
321 | }, { | 244 | }, { |
322 | { | 245 | { COLOR_WHITE, COLOR_GREEN, COLOR_BLACK, COLOR_WHITE, |
323 | COLOR_WHITE, | 246 | COLOR_GREEN, COLOR_BLACK, COLOR_WHITE, COLOR_GREEN, COLOR_BLACK } |
324 | COLOR_GREEN, | ||
325 | COLOR_BLACK, | ||
326 | COLOR_WHITE, | ||
327 | COLOR_GREEN, | ||
328 | COLOR_BLACK, | ||
329 | COLOR_WHITE, | ||
330 | COLOR_GREEN, | ||
331 | } | ||
332 | }, | 247 | }, |
333 | }; | 248 | }; |
334 | 249 | ||
@@ -344,21 +259,18 @@ static struct bar_std bars[] = { | |||
344 | (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) | 259 | (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) |
345 | 260 | ||
346 | /* precalculate color bar values to speed up rendering */ | 261 | /* precalculate color bar values to speed up rendering */ |
347 | static void precalculate_bars(struct vivi_fh *fh) | 262 | static void precalculate_bars(struct vivi_dev *dev) |
348 | { | 263 | { |
349 | struct vivi_dev *dev = fh->dev; | 264 | u8 r, g, b; |
350 | unsigned char r, g, b; | ||
351 | int k, is_yuv; | 265 | int k, is_yuv; |
352 | 266 | ||
353 | fh->input = dev->input; | 267 | for (k = 0; k < 9; k++) { |
354 | 268 | r = bars[dev->input].bar[k][0]; | |
355 | for (k = 0; k < 8; k++) { | 269 | g = bars[dev->input].bar[k][1]; |
356 | r = bars[fh->input].bar[k][0]; | 270 | b = bars[dev->input].bar[k][2]; |
357 | g = bars[fh->input].bar[k][1]; | ||
358 | b = bars[fh->input].bar[k][2]; | ||
359 | is_yuv = 0; | 271 | is_yuv = 0; |
360 | 272 | ||
361 | switch (fh->fmt->fourcc) { | 273 | switch (dev->fmt->fourcc) { |
362 | case V4L2_PIX_FMT_YUYV: | 274 | case V4L2_PIX_FMT_YUYV: |
363 | case V4L2_PIX_FMT_UYVY: | 275 | case V4L2_PIX_FMT_UYVY: |
364 | is_yuv = 1; | 276 | is_yuv = 1; |
@@ -378,16 +290,15 @@ static void precalculate_bars(struct vivi_fh *fh) | |||
378 | } | 290 | } |
379 | 291 | ||
380 | if (is_yuv) { | 292 | if (is_yuv) { |
381 | fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ | 293 | dev->bars[k][0] = TO_Y(r, g, b); /* Luma */ |
382 | fh->bars[k][1] = TO_U(r, g, b); /* Cb */ | 294 | dev->bars[k][1] = TO_U(r, g, b); /* Cb */ |
383 | fh->bars[k][2] = TO_V(r, g, b); /* Cr */ | 295 | dev->bars[k][2] = TO_V(r, g, b); /* Cr */ |
384 | } else { | 296 | } else { |
385 | fh->bars[k][0] = r; | 297 | dev->bars[k][0] = r; |
386 | fh->bars[k][1] = g; | 298 | dev->bars[k][1] = g; |
387 | fh->bars[k][2] = b; | 299 | dev->bars[k][2] = b; |
388 | } | 300 | } |
389 | } | 301 | } |
390 | |||
391 | } | 302 | } |
392 | 303 | ||
393 | #define TSTAMP_MIN_Y 24 | 304 | #define TSTAMP_MIN_Y 24 |
@@ -395,20 +306,20 @@ static void precalculate_bars(struct vivi_fh *fh) | |||
395 | #define TSTAMP_INPUT_X 10 | 306 | #define TSTAMP_INPUT_X 10 |
396 | #define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) | 307 | #define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) |
397 | 308 | ||
398 | static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) | 309 | static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) |
399 | { | 310 | { |
400 | unsigned char r_y, g_u, b_v; | 311 | u8 r_y, g_u, b_v; |
401 | unsigned char *p; | ||
402 | int color; | 312 | int color; |
313 | u8 *p; | ||
403 | 314 | ||
404 | r_y = fh->bars[colorpos][0]; /* R or precalculated Y */ | 315 | r_y = dev->bars[colorpos][0]; /* R or precalculated Y */ |
405 | g_u = fh->bars[colorpos][1]; /* G or precalculated U */ | 316 | g_u = dev->bars[colorpos][1]; /* G or precalculated U */ |
406 | b_v = fh->bars[colorpos][2]; /* B or precalculated V */ | 317 | b_v = dev->bars[colorpos][2]; /* B or precalculated V */ |
407 | 318 | ||
408 | for (color = 0; color < 4; color++) { | 319 | for (color = 0; color < 4; color++) { |
409 | p = buf + color; | 320 | p = buf + color; |
410 | 321 | ||
411 | switch (fh->fmt->fourcc) { | 322 | switch (dev->fmt->fourcc) { |
412 | case V4L2_PIX_FMT_YUYV: | 323 | case V4L2_PIX_FMT_YUYV: |
413 | switch (color) { | 324 | switch (color) { |
414 | case 0: | 325 | case 0: |
@@ -489,123 +400,88 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) | |||
489 | } | 400 | } |
490 | } | 401 | } |
491 | 402 | ||
492 | static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, | 403 | static void precalculate_line(struct vivi_dev *dev) |
493 | int hmax, int line, int count, char *timestr) | ||
494 | { | 404 | { |
495 | int w, i, j; | 405 | int w; |
496 | int pos = inipos; | ||
497 | char *s; | ||
498 | u8 chr; | ||
499 | |||
500 | /* We will just duplicate the second pixel at the packet */ | ||
501 | wmax /= 2; | ||
502 | 406 | ||
503 | /* Generate a standard color bar pattern */ | 407 | for (w = 0; w < dev->width * 2; w += 2) { |
504 | for (w = 0; w < wmax; w++) { | 408 | int colorpos = (w / (dev->width / 8) % 8); |
505 | int colorpos = ((w + count) * 8/(wmax + 1)) % 8; | ||
506 | 409 | ||
507 | gen_twopix(fh, basep + pos, colorpos); | 410 | gen_twopix(dev, dev->line + w * 2, colorpos); |
508 | pos += 4; /* only 16 bpp supported for now */ | ||
509 | } | 411 | } |
412 | } | ||
510 | 413 | ||
511 | /* Prints input entry number */ | 414 | static void gen_text(struct vivi_dev *dev, char *basep, |
512 | 415 | int y, int x, char *text) | |
513 | /* Checks if it is possible to input number */ | 416 | { |
514 | if (TSTAMP_MAX_Y >= hmax) | 417 | int line; |
515 | goto end; | ||
516 | |||
517 | if (TSTAMP_INPUT_X + strlen(timestr) >= wmax) | ||
518 | goto end; | ||
519 | |||
520 | if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) { | ||
521 | chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y]; | ||
522 | pos = TSTAMP_INPUT_X; | ||
523 | for (i = 0; i < 7; i++) { | ||
524 | /* Draw white font on black background */ | ||
525 | if (chr & 1 << (7 - i)) | ||
526 | gen_twopix(fh, basep + pos, WHITE); | ||
527 | else | ||
528 | gen_twopix(fh, basep + pos, BLACK); | ||
529 | pos += 2; | ||
530 | } | ||
531 | } | ||
532 | 418 | ||
533 | /* Checks if it is possible to show timestamp */ | 419 | /* Checks if it is possible to show string */ |
534 | if (TSTAMP_MIN_X + strlen(timestr) >= wmax) | 420 | if (y + 16 >= dev->height || x + strlen(text) * 8 >= dev->width) |
535 | goto end; | 421 | return; |
536 | 422 | ||
537 | /* Print stream time */ | 423 | /* Print stream time */ |
538 | if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) { | 424 | for (line = y; line < y + 16; line++) { |
539 | j = TSTAMP_MIN_X; | 425 | int j = 0; |
540 | for (s = timestr; *s; s++) { | 426 | char *pos = basep + line * dev->width * 2 + x * 2; |
541 | chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y]; | 427 | char *s; |
542 | for (i = 0; i < 7; i++) { | 428 | |
543 | pos = inipos + j * 2; | 429 | for (s = text; *s; s++) { |
430 | u8 chr = font8x16[*s * 16 + line - y]; | ||
431 | int i; | ||
432 | |||
433 | for (i = 0; i < 7; i++, j++) { | ||
544 | /* Draw white font on black background */ | 434 | /* Draw white font on black background */ |
545 | if (chr & 1 << (7 - i)) | 435 | if (chr & (1 << (7 - i))) |
546 | gen_twopix(fh, basep + pos, WHITE); | 436 | gen_twopix(dev, pos + j * 2, WHITE); |
547 | else | 437 | else |
548 | gen_twopix(fh, basep + pos, BLACK); | 438 | gen_twopix(dev, pos + j * 2, TEXT_BLACK); |
549 | j++; | ||
550 | } | 439 | } |
551 | } | 440 | } |
552 | } | 441 | } |
553 | |||
554 | end: | ||
555 | return; | ||
556 | } | 442 | } |
557 | 443 | ||
558 | static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf) | 444 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) |
559 | { | 445 | { |
560 | struct vivi_dev *dev = fh->dev; | 446 | int hmax = buf->vb.height; |
561 | int h , pos = 0; | 447 | int wmax = buf->vb.width; |
562 | int hmax = buf->vb.height; | ||
563 | int wmax = buf->vb.width; | ||
564 | struct timeval ts; | 448 | struct timeval ts; |
565 | char *tmpbuf; | ||
566 | void *vbuf = videobuf_to_vmalloc(&buf->vb); | 449 | void *vbuf = videobuf_to_vmalloc(&buf->vb); |
450 | unsigned ms; | ||
451 | char str[100]; | ||
452 | int h, line = 1; | ||
567 | 453 | ||
568 | if (!vbuf) | 454 | if (!vbuf) |
569 | return; | 455 | return; |
570 | 456 | ||
571 | tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); | 457 | for (h = 0; h < hmax; h++) |
572 | if (!tmpbuf) | 458 | memcpy(vbuf + h * wmax * 2, dev->line + (dev->mv_count % wmax) * 2, wmax * 2); |
573 | return; | ||
574 | |||
575 | for (h = 0; h < hmax; h++) { | ||
576 | gen_line(fh, tmpbuf, 0, wmax, hmax, h, dev->mv_count, | ||
577 | dev->timestr); | ||
578 | memcpy(vbuf + pos, tmpbuf, wmax * 2); | ||
579 | pos += wmax*2; | ||
580 | } | ||
581 | |||
582 | dev->mv_count++; | ||
583 | |||
584 | kfree(tmpbuf); | ||
585 | 459 | ||
586 | /* Updates stream time */ | 460 | /* Updates stream time */ |
587 | 461 | ||
588 | dev->ms += jiffies_to_msecs(jiffies-dev->jiffies); | 462 | dev->ms += jiffies_to_msecs(jiffies - dev->jiffies); |
589 | dev->jiffies = jiffies; | 463 | dev->jiffies = jiffies; |
590 | if (dev->ms >= 1000) { | 464 | ms = dev->ms; |
591 | dev->ms -= 1000; | 465 | snprintf(str, sizeof(str), " %02d:%02d:%02d:%03d ", |
592 | dev->s++; | 466 | (ms / (60 * 60 * 1000)) % 24, |
593 | if (dev->s >= 60) { | 467 | (ms / (60 * 1000)) % 60, |
594 | dev->s -= 60; | 468 | (ms / 1000) % 60, |
595 | dev->m++; | 469 | ms % 1000); |
596 | if (dev->m > 60) { | 470 | gen_text(dev, vbuf, line++ * 16, 16, str); |
597 | dev->m -= 60; | 471 | snprintf(str, sizeof(str), " %dx%d, input %d ", |
598 | dev->h++; | 472 | dev->width, dev->height, dev->input); |
599 | if (dev->h > 24) | 473 | gen_text(dev, vbuf, line++ * 16, 16, str); |
600 | dev->h -= 24; | 474 | |
601 | } | 475 | snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", |
602 | } | 476 | dev->brightness, |
603 | } | 477 | dev->contrast, |
604 | sprintf(dev->timestr, "%02d:%02d:%02d:%03d", | 478 | dev->saturation, |
605 | dev->h, dev->m, dev->s, dev->ms); | 479 | dev->hue); |
606 | 480 | gen_text(dev, vbuf, line++ * 16, 16, str); | |
607 | dprintk(dev, 2, "vivifill at %s: Buffer 0x%08lx size= %d\n", | 481 | snprintf(str, sizeof(str), " volume %3d ", dev->volume); |
608 | dev->timestr, (unsigned long)tmpbuf, pos); | 482 | gen_text(dev, vbuf, line++ * 16, 16, str); |
483 | |||
484 | dev->mv_count += 2; | ||
609 | 485 | ||
610 | /* Advice that buffer was filled */ | 486 | /* Advice that buffer was filled */ |
611 | buf->vb.field_count++; | 487 | buf->vb.field_count++; |
@@ -614,12 +490,10 @@ static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf) | |||
614 | buf->vb.state = VIDEOBUF_DONE; | 490 | buf->vb.state = VIDEOBUF_DONE; |
615 | } | 491 | } |
616 | 492 | ||
617 | static void vivi_thread_tick(struct vivi_fh *fh) | 493 | static void vivi_thread_tick(struct vivi_dev *dev) |
618 | { | 494 | { |
619 | struct vivi_buffer *buf; | ||
620 | struct vivi_dev *dev = fh->dev; | ||
621 | struct vivi_dmaqueue *dma_q = &dev->vidq; | 495 | struct vivi_dmaqueue *dma_q = &dev->vidq; |
622 | 496 | struct vivi_buffer *buf; | |
623 | unsigned long flags = 0; | 497 | unsigned long flags = 0; |
624 | 498 | ||
625 | dprintk(dev, 1, "Thread tick\n"); | 499 | dprintk(dev, 1, "Thread tick\n"); |
@@ -642,22 +516,20 @@ static void vivi_thread_tick(struct vivi_fh *fh) | |||
642 | do_gettimeofday(&buf->vb.ts); | 516 | do_gettimeofday(&buf->vb.ts); |
643 | 517 | ||
644 | /* Fill buffer */ | 518 | /* Fill buffer */ |
645 | vivi_fillbuff(fh, buf); | 519 | vivi_fillbuff(dev, buf); |
646 | dprintk(dev, 1, "filled buffer %p\n", buf); | 520 | dprintk(dev, 1, "filled buffer %p\n", buf); |
647 | 521 | ||
648 | wake_up(&buf->vb.done); | 522 | wake_up(&buf->vb.done); |
649 | dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); | 523 | dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); |
650 | unlock: | 524 | unlock: |
651 | spin_unlock_irqrestore(&dev->slock, flags); | 525 | spin_unlock_irqrestore(&dev->slock, flags); |
652 | return; | ||
653 | } | 526 | } |
654 | 527 | ||
655 | #define frames_to_ms(frames) \ | 528 | #define frames_to_ms(frames) \ |
656 | ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) | 529 | ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) |
657 | 530 | ||
658 | static void vivi_sleep(struct vivi_fh *fh) | 531 | static void vivi_sleep(struct vivi_dev *dev) |
659 | { | 532 | { |
660 | struct vivi_dev *dev = fh->dev; | ||
661 | struct vivi_dmaqueue *dma_q = &dev->vidq; | 533 | struct vivi_dmaqueue *dma_q = &dev->vidq; |
662 | int timeout; | 534 | int timeout; |
663 | DECLARE_WAITQUEUE(wait, current); | 535 | DECLARE_WAITQUEUE(wait, current); |
@@ -672,7 +544,7 @@ static void vivi_sleep(struct vivi_fh *fh) | |||
672 | /* Calculate time to wake up */ | 544 | /* Calculate time to wake up */ |
673 | timeout = msecs_to_jiffies(frames_to_ms(1)); | 545 | timeout = msecs_to_jiffies(frames_to_ms(1)); |
674 | 546 | ||
675 | vivi_thread_tick(fh); | 547 | vivi_thread_tick(dev); |
676 | 548 | ||
677 | schedule_timeout_interruptible(timeout); | 549 | schedule_timeout_interruptible(timeout); |
678 | 550 | ||
@@ -683,15 +555,14 @@ stop_task: | |||
683 | 555 | ||
684 | static int vivi_thread(void *data) | 556 | static int vivi_thread(void *data) |
685 | { | 557 | { |
686 | struct vivi_fh *fh = data; | 558 | struct vivi_dev *dev = data; |
687 | struct vivi_dev *dev = fh->dev; | ||
688 | 559 | ||
689 | dprintk(dev, 1, "thread started\n"); | 560 | dprintk(dev, 1, "thread started\n"); |
690 | 561 | ||
691 | set_freezable(); | 562 | set_freezable(); |
692 | 563 | ||
693 | for (;;) { | 564 | for (;;) { |
694 | vivi_sleep(fh); | 565 | vivi_sleep(dev); |
695 | 566 | ||
696 | if (kthread_should_stop()) | 567 | if (kthread_should_stop()) |
697 | break; | 568 | break; |
@@ -700,39 +571,61 @@ static int vivi_thread(void *data) | |||
700 | return 0; | 571 | return 0; |
701 | } | 572 | } |
702 | 573 | ||
703 | static int vivi_start_thread(struct vivi_fh *fh) | 574 | static void vivi_start_generating(struct file *file) |
704 | { | 575 | { |
705 | struct vivi_dev *dev = fh->dev; | 576 | struct vivi_dev *dev = video_drvdata(file); |
706 | struct vivi_dmaqueue *dma_q = &dev->vidq; | 577 | struct vivi_dmaqueue *dma_q = &dev->vidq; |
707 | 578 | ||
708 | dma_q->frame = 0; | ||
709 | dma_q->ini_jiffies = jiffies; | ||
710 | |||
711 | dprintk(dev, 1, "%s\n", __func__); | 579 | dprintk(dev, 1, "%s\n", __func__); |
712 | 580 | ||
713 | dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); | 581 | if (test_and_set_bit(0, &dev->generating)) |
582 | return; | ||
583 | file->private_data = dev; | ||
584 | |||
585 | /* Resets frame counters */ | ||
586 | dev->ms = 0; | ||
587 | dev->mv_count = 0; | ||
588 | dev->jiffies = jiffies; | ||
589 | |||
590 | dma_q->frame = 0; | ||
591 | dma_q->ini_jiffies = jiffies; | ||
592 | dma_q->kthread = kthread_run(vivi_thread, dev, dev->v4l2_dev.name); | ||
714 | 593 | ||
715 | if (IS_ERR(dma_q->kthread)) { | 594 | if (IS_ERR(dma_q->kthread)) { |
716 | v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); | 595 | v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); |
717 | return PTR_ERR(dma_q->kthread); | 596 | clear_bit(0, &dev->generating); |
597 | return; | ||
718 | } | 598 | } |
719 | /* Wakes thread */ | 599 | /* Wakes thread */ |
720 | wake_up_interruptible(&dma_q->wq); | 600 | wake_up_interruptible(&dma_q->wq); |
721 | 601 | ||
722 | dprintk(dev, 1, "returning from %s\n", __func__); | 602 | dprintk(dev, 1, "returning from %s\n", __func__); |
723 | return 0; | ||
724 | } | 603 | } |
725 | 604 | ||
726 | static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) | 605 | static void vivi_stop_generating(struct file *file) |
727 | { | 606 | { |
728 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 607 | struct vivi_dev *dev = video_drvdata(file); |
608 | struct vivi_dmaqueue *dma_q = &dev->vidq; | ||
729 | 609 | ||
730 | dprintk(dev, 1, "%s\n", __func__); | 610 | dprintk(dev, 1, "%s\n", __func__); |
611 | |||
612 | if (!file->private_data) | ||
613 | return; | ||
614 | if (!test_and_clear_bit(0, &dev->generating)) | ||
615 | return; | ||
616 | |||
731 | /* shutdown control thread */ | 617 | /* shutdown control thread */ |
732 | if (dma_q->kthread) { | 618 | if (dma_q->kthread) { |
733 | kthread_stop(dma_q->kthread); | 619 | kthread_stop(dma_q->kthread); |
734 | dma_q->kthread = NULL; | 620 | dma_q->kthread = NULL; |
735 | } | 621 | } |
622 | videobuf_stop(&dev->vb_vidq); | ||
623 | videobuf_mmap_free(&dev->vb_vidq); | ||
624 | } | ||
625 | |||
626 | static int vivi_is_generating(struct vivi_dev *dev) | ||
627 | { | ||
628 | return test_bit(0, &dev->generating); | ||
736 | } | 629 | } |
737 | 630 | ||
738 | /* ------------------------------------------------------------------ | 631 | /* ------------------------------------------------------------------ |
@@ -741,10 +634,9 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) | |||
741 | static int | 634 | static int |
742 | buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | 635 | buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) |
743 | { | 636 | { |
744 | struct vivi_fh *fh = vq->priv_data; | 637 | struct vivi_dev *dev = vq->priv_data; |
745 | struct vivi_dev *dev = fh->dev; | ||
746 | 638 | ||
747 | *size = fh->width*fh->height*2; | 639 | *size = dev->width * dev->height * 2; |
748 | 640 | ||
749 | if (0 == *count) | 641 | if (0 == *count) |
750 | *count = 32; | 642 | *count = 32; |
@@ -760,49 +652,43 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
760 | 652 | ||
761 | static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) | 653 | static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) |
762 | { | 654 | { |
763 | struct vivi_fh *fh = vq->priv_data; | 655 | struct vivi_dev *dev = vq->priv_data; |
764 | struct vivi_dev *dev = fh->dev; | ||
765 | 656 | ||
766 | dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); | 657 | dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); |
767 | 658 | ||
768 | if (in_interrupt()) | ||
769 | BUG(); | ||
770 | |||
771 | videobuf_vmalloc_free(&buf->vb); | 659 | videobuf_vmalloc_free(&buf->vb); |
772 | dprintk(dev, 1, "free_buffer: freed\n"); | 660 | dprintk(dev, 1, "free_buffer: freed\n"); |
773 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 661 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
774 | } | 662 | } |
775 | 663 | ||
776 | #define norm_maxw() 1024 | ||
777 | #define norm_maxh() 768 | ||
778 | static int | 664 | static int |
779 | buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | 665 | buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, |
780 | enum v4l2_field field) | 666 | enum v4l2_field field) |
781 | { | 667 | { |
782 | struct vivi_fh *fh = vq->priv_data; | 668 | struct vivi_dev *dev = vq->priv_data; |
783 | struct vivi_dev *dev = fh->dev; | ||
784 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 669 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
785 | int rc; | 670 | int rc; |
786 | 671 | ||
787 | dprintk(dev, 1, "%s, field=%d\n", __func__, field); | 672 | dprintk(dev, 1, "%s, field=%d\n", __func__, field); |
788 | 673 | ||
789 | BUG_ON(NULL == fh->fmt); | 674 | BUG_ON(NULL == dev->fmt); |
790 | 675 | ||
791 | if (fh->width < 48 || fh->width > norm_maxw() || | 676 | if (dev->width < 48 || dev->width > MAX_WIDTH || |
792 | fh->height < 32 || fh->height > norm_maxh()) | 677 | dev->height < 32 || dev->height > MAX_HEIGHT) |
793 | return -EINVAL; | 678 | return -EINVAL; |
794 | 679 | ||
795 | buf->vb.size = fh->width*fh->height*2; | 680 | buf->vb.size = dev->width * dev->height * 2; |
796 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 681 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
797 | return -EINVAL; | 682 | return -EINVAL; |
798 | 683 | ||
799 | /* These properties only change when queue is idle, see s_fmt */ | 684 | /* These properties only change when queue is idle, see s_fmt */ |
800 | buf->fmt = fh->fmt; | 685 | buf->fmt = dev->fmt; |
801 | buf->vb.width = fh->width; | 686 | buf->vb.width = dev->width; |
802 | buf->vb.height = fh->height; | 687 | buf->vb.height = dev->height; |
803 | buf->vb.field = field; | 688 | buf->vb.field = field; |
804 | 689 | ||
805 | precalculate_bars(fh); | 690 | precalculate_bars(dev); |
691 | precalculate_line(dev); | ||
806 | 692 | ||
807 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 693 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
808 | rc = videobuf_iolock(vq, &buf->vb, NULL); | 694 | rc = videobuf_iolock(vq, &buf->vb, NULL); |
@@ -811,7 +697,6 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
811 | } | 697 | } |
812 | 698 | ||
813 | buf->vb.state = VIDEOBUF_PREPARED; | 699 | buf->vb.state = VIDEOBUF_PREPARED; |
814 | |||
815 | return 0; | 700 | return 0; |
816 | 701 | ||
817 | fail: | 702 | fail: |
@@ -822,9 +707,8 @@ fail: | |||
822 | static void | 707 | static void |
823 | buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 708 | buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) |
824 | { | 709 | { |
825 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 710 | struct vivi_dev *dev = vq->priv_data; |
826 | struct vivi_fh *fh = vq->priv_data; | 711 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
827 | struct vivi_dev *dev = fh->dev; | ||
828 | struct vivi_dmaqueue *vidq = &dev->vidq; | 712 | struct vivi_dmaqueue *vidq = &dev->vidq; |
829 | 713 | ||
830 | dprintk(dev, 1, "%s\n", __func__); | 714 | dprintk(dev, 1, "%s\n", __func__); |
@@ -836,9 +720,8 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
836 | static void buffer_release(struct videobuf_queue *vq, | 720 | static void buffer_release(struct videobuf_queue *vq, |
837 | struct videobuf_buffer *vb) | 721 | struct videobuf_buffer *vb) |
838 | { | 722 | { |
839 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 723 | struct vivi_dev *dev = vq->priv_data; |
840 | struct vivi_fh *fh = vq->priv_data; | 724 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
841 | struct vivi_dev *dev = (struct vivi_dev *)fh->dev; | ||
842 | 725 | ||
843 | dprintk(dev, 1, "%s\n", __func__); | 726 | dprintk(dev, 1, "%s\n", __func__); |
844 | 727 | ||
@@ -858,16 +741,14 @@ static struct videobuf_queue_ops vivi_video_qops = { | |||
858 | static int vidioc_querycap(struct file *file, void *priv, | 741 | static int vidioc_querycap(struct file *file, void *priv, |
859 | struct v4l2_capability *cap) | 742 | struct v4l2_capability *cap) |
860 | { | 743 | { |
861 | struct vivi_fh *fh = priv; | 744 | struct vivi_dev *dev = video_drvdata(file); |
862 | struct vivi_dev *dev = fh->dev; | ||
863 | 745 | ||
864 | strcpy(cap->driver, "vivi"); | 746 | strcpy(cap->driver, "vivi"); |
865 | strcpy(cap->card, "vivi"); | 747 | strcpy(cap->card, "vivi"); |
866 | strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); | 748 | strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); |
867 | cap->version = VIVI_VERSION; | 749 | cap->version = VIVI_VERSION; |
868 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | | 750 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ |
869 | V4L2_CAP_STREAMING | | 751 | V4L2_CAP_READWRITE; |
870 | V4L2_CAP_READWRITE; | ||
871 | return 0; | 752 | return 0; |
872 | } | 753 | } |
873 | 754 | ||
@@ -889,28 +770,25 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | |||
889 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | 770 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, |
890 | struct v4l2_format *f) | 771 | struct v4l2_format *f) |
891 | { | 772 | { |
892 | struct vivi_fh *fh = priv; | 773 | struct vivi_dev *dev = video_drvdata(file); |
893 | 774 | ||
894 | f->fmt.pix.width = fh->width; | 775 | f->fmt.pix.width = dev->width; |
895 | f->fmt.pix.height = fh->height; | 776 | f->fmt.pix.height = dev->height; |
896 | f->fmt.pix.field = fh->vb_vidq.field; | 777 | f->fmt.pix.field = dev->vb_vidq.field; |
897 | f->fmt.pix.pixelformat = fh->fmt->fourcc; | 778 | f->fmt.pix.pixelformat = dev->fmt->fourcc; |
898 | f->fmt.pix.bytesperline = | 779 | f->fmt.pix.bytesperline = |
899 | (f->fmt.pix.width * fh->fmt->depth) >> 3; | 780 | (f->fmt.pix.width * dev->fmt->depth) >> 3; |
900 | f->fmt.pix.sizeimage = | 781 | f->fmt.pix.sizeimage = |
901 | f->fmt.pix.height * f->fmt.pix.bytesperline; | 782 | f->fmt.pix.height * f->fmt.pix.bytesperline; |
902 | 783 | return 0; | |
903 | return (0); | ||
904 | } | 784 | } |
905 | 785 | ||
906 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | 786 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, |
907 | struct v4l2_format *f) | 787 | struct v4l2_format *f) |
908 | { | 788 | { |
909 | struct vivi_fh *fh = priv; | 789 | struct vivi_dev *dev = video_drvdata(file); |
910 | struct vivi_dev *dev = fh->dev; | ||
911 | struct vivi_fmt *fmt; | 790 | struct vivi_fmt *fmt; |
912 | enum v4l2_field field; | 791 | enum v4l2_field field; |
913 | unsigned int maxw, maxh; | ||
914 | 792 | ||
915 | fmt = get_format(f); | 793 | fmt = get_format(f); |
916 | if (!fmt) { | 794 | if (!fmt) { |
@@ -928,113 +806,109 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
928 | return -EINVAL; | 806 | return -EINVAL; |
929 | } | 807 | } |
930 | 808 | ||
931 | maxw = norm_maxw(); | ||
932 | maxh = norm_maxh(); | ||
933 | |||
934 | f->fmt.pix.field = field; | 809 | f->fmt.pix.field = field; |
935 | v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, | 810 | v4l_bound_align_image(&f->fmt.pix.width, 48, MAX_WIDTH, 2, |
936 | &f->fmt.pix.height, 32, maxh, 0, 0); | 811 | &f->fmt.pix.height, 32, MAX_HEIGHT, 0, 0); |
937 | f->fmt.pix.bytesperline = | 812 | f->fmt.pix.bytesperline = |
938 | (f->fmt.pix.width * fmt->depth) >> 3; | 813 | (f->fmt.pix.width * fmt->depth) >> 3; |
939 | f->fmt.pix.sizeimage = | 814 | f->fmt.pix.sizeimage = |
940 | f->fmt.pix.height * f->fmt.pix.bytesperline; | 815 | f->fmt.pix.height * f->fmt.pix.bytesperline; |
941 | |||
942 | return 0; | 816 | return 0; |
943 | } | 817 | } |
944 | 818 | ||
945 | /*FIXME: This seems to be generic enough to be at videodev2 */ | ||
946 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | 819 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, |
947 | struct v4l2_format *f) | 820 | struct v4l2_format *f) |
948 | { | 821 | { |
949 | struct vivi_fh *fh = priv; | 822 | struct vivi_dev *dev = video_drvdata(file); |
950 | struct videobuf_queue *q = &fh->vb_vidq; | 823 | struct videobuf_queue *q = &dev->vb_vidq; |
951 | 824 | ||
952 | int ret = vidioc_try_fmt_vid_cap(file, fh, f); | 825 | int ret = vidioc_try_fmt_vid_cap(file, priv, f); |
953 | if (ret < 0) | 826 | if (ret < 0) |
954 | return ret; | 827 | return ret; |
955 | 828 | ||
956 | mutex_lock(&q->vb_lock); | 829 | mutex_lock(&q->vb_lock); |
957 | 830 | ||
958 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | 831 | if (vivi_is_generating(dev)) { |
959 | dprintk(fh->dev, 1, "%s queue busy\n", __func__); | 832 | dprintk(dev, 1, "%s device busy\n", __func__); |
960 | ret = -EBUSY; | 833 | ret = -EBUSY; |
961 | goto out; | 834 | goto out; |
962 | } | 835 | } |
963 | 836 | ||
964 | fh->fmt = get_format(f); | 837 | dev->fmt = get_format(f); |
965 | fh->width = f->fmt.pix.width; | 838 | dev->width = f->fmt.pix.width; |
966 | fh->height = f->fmt.pix.height; | 839 | dev->height = f->fmt.pix.height; |
967 | fh->vb_vidq.field = f->fmt.pix.field; | 840 | dev->vb_vidq.field = f->fmt.pix.field; |
968 | fh->type = f->type; | ||
969 | |||
970 | ret = 0; | 841 | ret = 0; |
971 | out: | 842 | out: |
972 | mutex_unlock(&q->vb_lock); | 843 | mutex_unlock(&q->vb_lock); |
973 | |||
974 | return ret; | 844 | return ret; |
975 | } | 845 | } |
976 | 846 | ||
977 | static int vidioc_reqbufs(struct file *file, void *priv, | 847 | static int vidioc_reqbufs(struct file *file, void *priv, |
978 | struct v4l2_requestbuffers *p) | 848 | struct v4l2_requestbuffers *p) |
979 | { | 849 | { |
980 | struct vivi_fh *fh = priv; | 850 | struct vivi_dev *dev = video_drvdata(file); |
981 | 851 | ||
982 | return (videobuf_reqbufs(&fh->vb_vidq, p)); | 852 | return videobuf_reqbufs(&dev->vb_vidq, p); |
983 | } | 853 | } |
984 | 854 | ||
985 | static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) | 855 | static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) |
986 | { | 856 | { |
987 | struct vivi_fh *fh = priv; | 857 | struct vivi_dev *dev = video_drvdata(file); |
988 | 858 | ||
989 | return (videobuf_querybuf(&fh->vb_vidq, p)); | 859 | return videobuf_querybuf(&dev->vb_vidq, p); |
990 | } | 860 | } |
991 | 861 | ||
992 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) | 862 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) |
993 | { | 863 | { |
994 | struct vivi_fh *fh = priv; | 864 | struct vivi_dev *dev = video_drvdata(file); |
995 | 865 | ||
996 | return (videobuf_qbuf(&fh->vb_vidq, p)); | 866 | return videobuf_qbuf(&dev->vb_vidq, p); |
997 | } | 867 | } |
998 | 868 | ||
999 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) | 869 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) |
1000 | { | 870 | { |
1001 | struct vivi_fh *fh = priv; | 871 | struct vivi_dev *dev = video_drvdata(file); |
1002 | 872 | ||
1003 | return (videobuf_dqbuf(&fh->vb_vidq, p, | 873 | return videobuf_dqbuf(&dev->vb_vidq, p, |
1004 | file->f_flags & O_NONBLOCK)); | 874 | file->f_flags & O_NONBLOCK); |
1005 | } | 875 | } |
1006 | 876 | ||
1007 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 877 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1008 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | 878 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) |
1009 | { | 879 | { |
1010 | struct vivi_fh *fh = priv; | 880 | struct vivi_dev *dev = video_drvdata(file); |
1011 | 881 | ||
1012 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); | 882 | return videobuf_cgmbuf(&dev->vb_vidq, mbuf, 8); |
1013 | } | 883 | } |
1014 | #endif | 884 | #endif |
1015 | 885 | ||
1016 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | 886 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) |
1017 | { | 887 | { |
1018 | struct vivi_fh *fh = priv; | 888 | struct vivi_dev *dev = video_drvdata(file); |
889 | int ret; | ||
1019 | 890 | ||
1020 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 891 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1021 | return -EINVAL; | ||
1022 | if (i != fh->type) | ||
1023 | return -EINVAL; | 892 | return -EINVAL; |
893 | ret = videobuf_streamon(&dev->vb_vidq); | ||
894 | if (ret) | ||
895 | return ret; | ||
1024 | 896 | ||
1025 | return videobuf_streamon(&fh->vb_vidq); | 897 | vivi_start_generating(file); |
898 | return 0; | ||
1026 | } | 899 | } |
1027 | 900 | ||
1028 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | 901 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) |
1029 | { | 902 | { |
1030 | struct vivi_fh *fh = priv; | 903 | struct vivi_dev *dev = video_drvdata(file); |
904 | int ret; | ||
1031 | 905 | ||
1032 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 906 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1033 | return -EINVAL; | ||
1034 | if (i != fh->type) | ||
1035 | return -EINVAL; | 907 | return -EINVAL; |
1036 | 908 | ret = videobuf_streamoff(&dev->vb_vidq); | |
1037 | return videobuf_streamoff(&fh->vb_vidq); | 909 | if (!ret) |
910 | vivi_stop_generating(file); | ||
911 | return ret; | ||
1038 | } | 912 | } |
1039 | 913 | ||
1040 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) | 914 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) |
@@ -1052,80 +926,104 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
1052 | inp->type = V4L2_INPUT_TYPE_CAMERA; | 926 | inp->type = V4L2_INPUT_TYPE_CAMERA; |
1053 | inp->std = V4L2_STD_525_60; | 927 | inp->std = V4L2_STD_525_60; |
1054 | sprintf(inp->name, "Camera %u", inp->index); | 928 | sprintf(inp->name, "Camera %u", inp->index); |
1055 | 929 | return 0; | |
1056 | return (0); | ||
1057 | } | 930 | } |
1058 | 931 | ||
1059 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | 932 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) |
1060 | { | 933 | { |
1061 | struct vivi_fh *fh = priv; | 934 | struct vivi_dev *dev = video_drvdata(file); |
1062 | struct vivi_dev *dev = fh->dev; | ||
1063 | 935 | ||
1064 | *i = dev->input; | 936 | *i = dev->input; |
1065 | 937 | return 0; | |
1066 | return (0); | ||
1067 | } | 938 | } |
939 | |||
1068 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | 940 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) |
1069 | { | 941 | { |
1070 | struct vivi_fh *fh = priv; | 942 | struct vivi_dev *dev = video_drvdata(file); |
1071 | struct vivi_dev *dev = fh->dev; | ||
1072 | 943 | ||
1073 | if (i >= NUM_INPUTS) | 944 | if (i >= NUM_INPUTS) |
1074 | return -EINVAL; | 945 | return -EINVAL; |
1075 | 946 | ||
1076 | dev->input = i; | 947 | dev->input = i; |
1077 | precalculate_bars(fh); | 948 | precalculate_bars(dev); |
1078 | 949 | precalculate_line(dev); | |
1079 | return (0); | 950 | return 0; |
1080 | } | 951 | } |
1081 | 952 | ||
1082 | /* --- controls ---------------------------------------------- */ | 953 | /* --- controls ---------------------------------------------- */ |
1083 | static int vidioc_queryctrl(struct file *file, void *priv, | 954 | static int vidioc_queryctrl(struct file *file, void *priv, |
1084 | struct v4l2_queryctrl *qc) | 955 | struct v4l2_queryctrl *qc) |
1085 | { | 956 | { |
1086 | int i; | 957 | switch (qc->id) { |
1087 | 958 | case V4L2_CID_AUDIO_VOLUME: | |
1088 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | 959 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 200); |
1089 | if (qc->id && qc->id == vivi_qctrl[i].id) { | 960 | case V4L2_CID_BRIGHTNESS: |
1090 | memcpy(qc, &(vivi_qctrl[i]), | 961 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127); |
1091 | sizeof(*qc)); | 962 | case V4L2_CID_CONTRAST: |
1092 | return (0); | 963 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 16); |
1093 | } | 964 | case V4L2_CID_SATURATION: |
1094 | 965 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127); | |
966 | case V4L2_CID_HUE: | ||
967 | return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); | ||
968 | } | ||
1095 | return -EINVAL; | 969 | return -EINVAL; |
1096 | } | 970 | } |
1097 | 971 | ||
1098 | static int vidioc_g_ctrl(struct file *file, void *priv, | 972 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1099 | struct v4l2_control *ctrl) | 973 | struct v4l2_control *ctrl) |
1100 | { | 974 | { |
1101 | struct vivi_fh *fh = priv; | 975 | struct vivi_dev *dev = video_drvdata(file); |
1102 | struct vivi_dev *dev = fh->dev; | ||
1103 | int i; | ||
1104 | |||
1105 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | ||
1106 | if (ctrl->id == vivi_qctrl[i].id) { | ||
1107 | ctrl->value = dev->qctl_regs[i]; | ||
1108 | return 0; | ||
1109 | } | ||
1110 | 976 | ||
977 | switch (ctrl->id) { | ||
978 | case V4L2_CID_AUDIO_VOLUME: | ||
979 | ctrl->value = dev->volume; | ||
980 | return 0; | ||
981 | case V4L2_CID_BRIGHTNESS: | ||
982 | ctrl->value = dev->brightness; | ||
983 | return 0; | ||
984 | case V4L2_CID_CONTRAST: | ||
985 | ctrl->value = dev->contrast; | ||
986 | return 0; | ||
987 | case V4L2_CID_SATURATION: | ||
988 | ctrl->value = dev->saturation; | ||
989 | return 0; | ||
990 | case V4L2_CID_HUE: | ||
991 | ctrl->value = dev->hue; | ||
992 | return 0; | ||
993 | } | ||
1111 | return -EINVAL; | 994 | return -EINVAL; |
1112 | } | 995 | } |
996 | |||
1113 | static int vidioc_s_ctrl(struct file *file, void *priv, | 997 | static int vidioc_s_ctrl(struct file *file, void *priv, |
1114 | struct v4l2_control *ctrl) | 998 | struct v4l2_control *ctrl) |
1115 | { | 999 | { |
1116 | struct vivi_fh *fh = priv; | 1000 | struct vivi_dev *dev = video_drvdata(file); |
1117 | struct vivi_dev *dev = fh->dev; | 1001 | struct v4l2_queryctrl qc; |
1118 | int i; | 1002 | int err; |
1119 | 1003 | ||
1120 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | 1004 | qc.id = ctrl->id; |
1121 | if (ctrl->id == vivi_qctrl[i].id) { | 1005 | err = vidioc_queryctrl(file, priv, &qc); |
1122 | if (ctrl->value < vivi_qctrl[i].minimum || | 1006 | if (err < 0) |
1123 | ctrl->value > vivi_qctrl[i].maximum) { | 1007 | return err; |
1124 | return -ERANGE; | 1008 | if (ctrl->value < qc.minimum || ctrl->value > qc.maximum) |
1125 | } | 1009 | return -ERANGE; |
1126 | dev->qctl_regs[i] = ctrl->value; | 1010 | switch (ctrl->id) { |
1127 | return 0; | 1011 | case V4L2_CID_AUDIO_VOLUME: |
1128 | } | 1012 | dev->volume = ctrl->value; |
1013 | return 0; | ||
1014 | case V4L2_CID_BRIGHTNESS: | ||
1015 | dev->brightness = ctrl->value; | ||
1016 | return 0; | ||
1017 | case V4L2_CID_CONTRAST: | ||
1018 | dev->contrast = ctrl->value; | ||
1019 | return 0; | ||
1020 | case V4L2_CID_SATURATION: | ||
1021 | dev->saturation = ctrl->value; | ||
1022 | return 0; | ||
1023 | case V4L2_CID_HUE: | ||
1024 | dev->hue = ctrl->value; | ||
1025 | return 0; | ||
1026 | } | ||
1129 | return -EINVAL; | 1027 | return -EINVAL; |
1130 | } | 1028 | } |
1131 | 1029 | ||
@@ -1133,134 +1031,58 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1133 | File operations for the device | 1031 | File operations for the device |
1134 | ------------------------------------------------------------------*/ | 1032 | ------------------------------------------------------------------*/ |
1135 | 1033 | ||
1136 | static int vivi_open(struct file *file) | ||
1137 | { | ||
1138 | struct vivi_dev *dev = video_drvdata(file); | ||
1139 | struct vivi_fh *fh = NULL; | ||
1140 | int retval = 0; | ||
1141 | |||
1142 | mutex_lock(&dev->mutex); | ||
1143 | dev->users++; | ||
1144 | |||
1145 | if (dev->users > 1) { | ||
1146 | dev->users--; | ||
1147 | mutex_unlock(&dev->mutex); | ||
1148 | return -EBUSY; | ||
1149 | } | ||
1150 | |||
1151 | dprintk(dev, 1, "open %s type=%s users=%d\n", | ||
1152 | video_device_node_name(dev->vfd), | ||
1153 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); | ||
1154 | |||
1155 | /* allocate + initialize per filehandle data */ | ||
1156 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1157 | if (NULL == fh) { | ||
1158 | dev->users--; | ||
1159 | retval = -ENOMEM; | ||
1160 | } | ||
1161 | mutex_unlock(&dev->mutex); | ||
1162 | |||
1163 | if (retval) | ||
1164 | return retval; | ||
1165 | |||
1166 | file->private_data = fh; | ||
1167 | fh->dev = dev; | ||
1168 | |||
1169 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1170 | fh->fmt = &formats[0]; | ||
1171 | fh->width = 640; | ||
1172 | fh->height = 480; | ||
1173 | |||
1174 | /* Resets frame counters */ | ||
1175 | dev->h = 0; | ||
1176 | dev->m = 0; | ||
1177 | dev->s = 0; | ||
1178 | dev->ms = 0; | ||
1179 | dev->mv_count = 0; | ||
1180 | dev->jiffies = jiffies; | ||
1181 | sprintf(dev->timestr, "%02d:%02d:%02d:%03d", | ||
1182 | dev->h, dev->m, dev->s, dev->ms); | ||
1183 | |||
1184 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &vivi_video_qops, | ||
1185 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, | ||
1186 | sizeof(struct vivi_buffer), fh); | ||
1187 | |||
1188 | vivi_start_thread(fh); | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | static ssize_t | 1034 | static ssize_t |
1194 | vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | 1035 | vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) |
1195 | { | 1036 | { |
1196 | struct vivi_fh *fh = file->private_data; | 1037 | struct vivi_dev *dev = video_drvdata(file); |
1197 | 1038 | ||
1198 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1039 | vivi_start_generating(file); |
1199 | return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0, | 1040 | return videobuf_read_stream(&dev->vb_vidq, data, count, ppos, 0, |
1200 | file->f_flags & O_NONBLOCK); | 1041 | file->f_flags & O_NONBLOCK); |
1201 | } | ||
1202 | return 0; | ||
1203 | } | 1042 | } |
1204 | 1043 | ||
1205 | static unsigned int | 1044 | static unsigned int |
1206 | vivi_poll(struct file *file, struct poll_table_struct *wait) | 1045 | vivi_poll(struct file *file, struct poll_table_struct *wait) |
1207 | { | 1046 | { |
1208 | struct vivi_fh *fh = file->private_data; | 1047 | struct vivi_dev *dev = video_drvdata(file); |
1209 | struct vivi_dev *dev = fh->dev; | 1048 | struct videobuf_queue *q = &dev->vb_vidq; |
1210 | struct videobuf_queue *q = &fh->vb_vidq; | ||
1211 | 1049 | ||
1212 | dprintk(dev, 1, "%s\n", __func__); | 1050 | dprintk(dev, 1, "%s\n", __func__); |
1213 | 1051 | ||
1214 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 1052 | vivi_start_generating(file); |
1215 | return POLLERR; | ||
1216 | |||
1217 | return videobuf_poll_stream(file, q, wait); | 1053 | return videobuf_poll_stream(file, q, wait); |
1218 | } | 1054 | } |
1219 | 1055 | ||
1220 | static int vivi_close(struct file *file) | 1056 | static int vivi_close(struct file *file) |
1221 | { | 1057 | { |
1222 | struct vivi_fh *fh = file->private_data; | ||
1223 | struct vivi_dev *dev = fh->dev; | ||
1224 | struct vivi_dmaqueue *vidq = &dev->vidq; | ||
1225 | struct video_device *vdev = video_devdata(file); | 1058 | struct video_device *vdev = video_devdata(file); |
1059 | struct vivi_dev *dev = video_drvdata(file); | ||
1226 | 1060 | ||
1227 | vivi_stop_thread(vidq); | 1061 | vivi_stop_generating(file); |
1228 | videobuf_stop(&fh->vb_vidq); | ||
1229 | videobuf_mmap_free(&fh->vb_vidq); | ||
1230 | |||
1231 | kfree(fh); | ||
1232 | |||
1233 | mutex_lock(&dev->mutex); | ||
1234 | dev->users--; | ||
1235 | mutex_unlock(&dev->mutex); | ||
1236 | |||
1237 | dprintk(dev, 1, "close called (dev=%s, users=%d)\n", | ||
1238 | video_device_node_name(vdev), dev->users); | ||
1239 | 1062 | ||
1063 | dprintk(dev, 1, "close called (dev=%s)\n", | ||
1064 | video_device_node_name(vdev)); | ||
1240 | return 0; | 1065 | return 0; |
1241 | } | 1066 | } |
1242 | 1067 | ||
1243 | static int vivi_mmap(struct file *file, struct vm_area_struct *vma) | 1068 | static int vivi_mmap(struct file *file, struct vm_area_struct *vma) |
1244 | { | 1069 | { |
1245 | struct vivi_fh *fh = file->private_data; | 1070 | struct vivi_dev *dev = video_drvdata(file); |
1246 | struct vivi_dev *dev = fh->dev; | ||
1247 | int ret; | 1071 | int ret; |
1248 | 1072 | ||
1249 | dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); | 1073 | dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); |
1250 | 1074 | ||
1251 | ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); | 1075 | ret = videobuf_mmap_mapper(&dev->vb_vidq, vma); |
1252 | 1076 | ||
1253 | dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", | 1077 | dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", |
1254 | (unsigned long)vma->vm_start, | 1078 | (unsigned long)vma->vm_start, |
1255 | (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, | 1079 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, |
1256 | ret); | 1080 | ret); |
1257 | |||
1258 | return ret; | 1081 | return ret; |
1259 | } | 1082 | } |
1260 | 1083 | ||
1261 | static const struct v4l2_file_operations vivi_fops = { | 1084 | static const struct v4l2_file_operations vivi_fops = { |
1262 | .owner = THIS_MODULE, | 1085 | .owner = THIS_MODULE, |
1263 | .open = vivi_open, | ||
1264 | .release = vivi_close, | 1086 | .release = vivi_close, |
1265 | .read = vivi_read, | 1087 | .read = vivi_read, |
1266 | .poll = vivi_poll, | 1088 | .poll = vivi_poll, |
@@ -1282,11 +1104,11 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = { | |||
1282 | .vidioc_enum_input = vidioc_enum_input, | 1104 | .vidioc_enum_input = vidioc_enum_input, |
1283 | .vidioc_g_input = vidioc_g_input, | 1105 | .vidioc_g_input = vidioc_g_input, |
1284 | .vidioc_s_input = vidioc_s_input, | 1106 | .vidioc_s_input = vidioc_s_input, |
1107 | .vidioc_streamon = vidioc_streamon, | ||
1108 | .vidioc_streamoff = vidioc_streamoff, | ||
1285 | .vidioc_queryctrl = vidioc_queryctrl, | 1109 | .vidioc_queryctrl = vidioc_queryctrl, |
1286 | .vidioc_g_ctrl = vidioc_g_ctrl, | 1110 | .vidioc_g_ctrl = vidioc_g_ctrl, |
1287 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1111 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1288 | .vidioc_streamon = vidioc_streamon, | ||
1289 | .vidioc_streamoff = vidioc_streamoff, | ||
1290 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1112 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1291 | .vidiocgmbuf = vidiocgmbuf, | 1113 | .vidiocgmbuf = vidiocgmbuf, |
1292 | #endif | 1114 | #endif |
@@ -1330,7 +1152,7 @@ static int __init vivi_create_instance(int inst) | |||
1330 | { | 1152 | { |
1331 | struct vivi_dev *dev; | 1153 | struct vivi_dev *dev; |
1332 | struct video_device *vfd; | 1154 | struct video_device *vfd; |
1333 | int ret, i; | 1155 | int ret; |
1334 | 1156 | ||
1335 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1157 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1336 | if (!dev) | 1158 | if (!dev) |
@@ -1342,6 +1164,20 @@ static int __init vivi_create_instance(int inst) | |||
1342 | if (ret) | 1164 | if (ret) |
1343 | goto free_dev; | 1165 | goto free_dev; |
1344 | 1166 | ||
1167 | dev->fmt = &formats[0]; | ||
1168 | dev->width = 640; | ||
1169 | dev->height = 480; | ||
1170 | dev->volume = 200; | ||
1171 | dev->brightness = 127; | ||
1172 | dev->contrast = 16; | ||
1173 | dev->saturation = 127; | ||
1174 | dev->hue = 0; | ||
1175 | |||
1176 | videobuf_queue_vmalloc_init(&dev->vb_vidq, &vivi_video_qops, | ||
1177 | NULL, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1178 | V4L2_FIELD_INTERLACED, | ||
1179 | sizeof(struct vivi_buffer), dev); | ||
1180 | |||
1345 | /* init video dma queues */ | 1181 | /* init video dma queues */ |
1346 | INIT_LIST_HEAD(&dev->vidq.active); | 1182 | INIT_LIST_HEAD(&dev->vidq.active); |
1347 | init_waitqueue_head(&dev->vidq.wq); | 1183 | init_waitqueue_head(&dev->vidq.wq); |
@@ -1357,6 +1193,7 @@ static int __init vivi_create_instance(int inst) | |||
1357 | 1193 | ||
1358 | *vfd = vivi_template; | 1194 | *vfd = vivi_template; |
1359 | vfd->debug = debug; | 1195 | vfd->debug = debug; |
1196 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
1360 | 1197 | ||
1361 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); | 1198 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); |
1362 | if (ret < 0) | 1199 | if (ret < 0) |
@@ -1364,10 +1201,6 @@ static int __init vivi_create_instance(int inst) | |||
1364 | 1201 | ||
1365 | video_set_drvdata(vfd, dev); | 1202 | video_set_drvdata(vfd, dev); |
1366 | 1203 | ||
1367 | /* Set all controls to their default value. */ | ||
1368 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | ||
1369 | dev->qctl_regs[i] = vivi_qctrl[i].default_value; | ||
1370 | |||
1371 | /* Now that everything is fine, let's add it to device list */ | 1204 | /* Now that everything is fine, let's add it to device list */ |
1372 | list_add_tail(&dev->vivi_devlist, &vivi_devlist); | 1205 | list_add_tail(&dev->vivi_devlist, &vivi_devlist); |
1373 | 1206 | ||
@@ -1396,8 +1229,15 @@ free_dev: | |||
1396 | */ | 1229 | */ |
1397 | static int __init vivi_init(void) | 1230 | static int __init vivi_init(void) |
1398 | { | 1231 | { |
1232 | const struct font_desc *font = find_font("VGA8x16"); | ||
1399 | int ret = 0, i; | 1233 | int ret = 0, i; |
1400 | 1234 | ||
1235 | if (font == NULL) { | ||
1236 | printk(KERN_ERR "vivi: could not find font\n"); | ||
1237 | return -ENODEV; | ||
1238 | } | ||
1239 | font8x16 = font->data; | ||
1240 | |||
1401 | if (n_devs <= 0) | 1241 | if (n_devs <= 0) |
1402 | n_devs = 1; | 1242 | n_devs = 1; |
1403 | 1243 | ||
@@ -1412,7 +1252,7 @@ static int __init vivi_init(void) | |||
1412 | } | 1252 | } |
1413 | 1253 | ||
1414 | if (ret < 0) { | 1254 | if (ret < 0) { |
1415 | printk(KERN_INFO "Error %d while loading vivi driver\n", ret); | 1255 | printk(KERN_ERR "vivi: error %d while loading driver\n", ret); |
1416 | return ret; | 1256 | return ret; |
1417 | } | 1257 | } |
1418 | 1258 | ||