diff options
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r-- | drivers/media/video/vivi.c | 223 |
1 files changed, 178 insertions, 45 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 5e8b0710105b..0960d7f0d394 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -95,6 +95,16 @@ static struct vivi_fmt formats[] = { | |||
95 | .depth = 16, | 95 | .depth = 16, |
96 | }, | 96 | }, |
97 | { | 97 | { |
98 | .name = "4:2:2, packed, YVYU", | ||
99 | .fourcc = V4L2_PIX_FMT_YVYU, | ||
100 | .depth = 16, | ||
101 | }, | ||
102 | { | ||
103 | .name = "4:2:2, packed, VYUY", | ||
104 | .fourcc = V4L2_PIX_FMT_VYUY, | ||
105 | .depth = 16, | ||
106 | }, | ||
107 | { | ||
98 | .name = "RGB565 (LE)", | 108 | .name = "RGB565 (LE)", |
99 | .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ | 109 | .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ |
100 | .depth = 16, | 110 | .depth = 16, |
@@ -114,6 +124,26 @@ static struct vivi_fmt formats[] = { | |||
114 | .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ | 124 | .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ |
115 | .depth = 16, | 125 | .depth = 16, |
116 | }, | 126 | }, |
127 | { | ||
128 | .name = "RGB24 (LE)", | ||
129 | .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ | ||
130 | .depth = 24, | ||
131 | }, | ||
132 | { | ||
133 | .name = "RGB24 (BE)", | ||
134 | .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ | ||
135 | .depth = 24, | ||
136 | }, | ||
137 | { | ||
138 | .name = "RGB32 (LE)", | ||
139 | .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ | ||
140 | .depth = 32, | ||
141 | }, | ||
142 | { | ||
143 | .name = "RGB32 (BE)", | ||
144 | .fourcc = V4L2_PIX_FMT_BGR32, /* bgra */ | ||
145 | .depth = 32, | ||
146 | }, | ||
117 | }; | 147 | }; |
118 | 148 | ||
119 | static struct vivi_fmt *get_format(struct v4l2_format *f) | 149 | static struct vivi_fmt *get_format(struct v4l2_format *f) |
@@ -170,6 +200,7 @@ struct vivi_dev { | |||
170 | struct v4l2_ctrl *gain; | 200 | struct v4l2_ctrl *gain; |
171 | }; | 201 | }; |
172 | struct v4l2_ctrl *volume; | 202 | struct v4l2_ctrl *volume; |
203 | struct v4l2_ctrl *alpha; | ||
173 | struct v4l2_ctrl *button; | 204 | struct v4l2_ctrl *button; |
174 | struct v4l2_ctrl *boolean; | 205 | struct v4l2_ctrl *boolean; |
175 | struct v4l2_ctrl *int32; | 206 | struct v4l2_ctrl *int32; |
@@ -177,6 +208,7 @@ struct vivi_dev { | |||
177 | struct v4l2_ctrl *menu; | 208 | struct v4l2_ctrl *menu; |
178 | struct v4l2_ctrl *string; | 209 | struct v4l2_ctrl *string; |
179 | struct v4l2_ctrl *bitmask; | 210 | struct v4l2_ctrl *bitmask; |
211 | struct v4l2_ctrl *int_menu; | ||
180 | 212 | ||
181 | spinlock_t slock; | 213 | spinlock_t slock; |
182 | struct mutex mutex; | 214 | struct mutex mutex; |
@@ -203,8 +235,10 @@ struct vivi_dev { | |||
203 | enum v4l2_field field; | 235 | enum v4l2_field field; |
204 | unsigned int field_count; | 236 | unsigned int field_count; |
205 | 237 | ||
206 | u8 bars[9][3]; | 238 | u8 bars[9][3]; |
207 | u8 line[MAX_WIDTH * 4]; | 239 | u8 line[MAX_WIDTH * 8]; |
240 | unsigned int pixelsize; | ||
241 | u8 alpha_component; | ||
208 | }; | 242 | }; |
209 | 243 | ||
210 | /* ------------------------------------------------------------------ | 244 | /* ------------------------------------------------------------------ |
@@ -283,6 +317,8 @@ static void precalculate_bars(struct vivi_dev *dev) | |||
283 | switch (dev->fmt->fourcc) { | 317 | switch (dev->fmt->fourcc) { |
284 | case V4L2_PIX_FMT_YUYV: | 318 | case V4L2_PIX_FMT_YUYV: |
285 | case V4L2_PIX_FMT_UYVY: | 319 | case V4L2_PIX_FMT_UYVY: |
320 | case V4L2_PIX_FMT_YVYU: | ||
321 | case V4L2_PIX_FMT_VYUY: | ||
286 | is_yuv = 1; | 322 | is_yuv = 1; |
287 | break; | 323 | break; |
288 | case V4L2_PIX_FMT_RGB565: | 324 | case V4L2_PIX_FMT_RGB565: |
@@ -297,6 +333,11 @@ static void precalculate_bars(struct vivi_dev *dev) | |||
297 | g >>= 3; | 333 | g >>= 3; |
298 | b >>= 3; | 334 | b >>= 3; |
299 | break; | 335 | break; |
336 | case V4L2_PIX_FMT_RGB24: | ||
337 | case V4L2_PIX_FMT_BGR24: | ||
338 | case V4L2_PIX_FMT_RGB32: | ||
339 | case V4L2_PIX_FMT_BGR32: | ||
340 | break; | ||
300 | } | 341 | } |
301 | 342 | ||
302 | if (is_yuv) { | 343 | if (is_yuv) { |
@@ -316,9 +357,11 @@ static void precalculate_bars(struct vivi_dev *dev) | |||
316 | #define TSTAMP_INPUT_X 10 | 357 | #define TSTAMP_INPUT_X 10 |
317 | #define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) | 358 | #define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) |
318 | 359 | ||
319 | static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) | 360 | /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */ |
361 | static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd) | ||
320 | { | 362 | { |
321 | u8 r_y, g_u, b_v; | 363 | u8 r_y, g_u, b_v; |
364 | u8 alpha = dev->alpha_component; | ||
322 | int color; | 365 | int color; |
323 | u8 *p; | 366 | u8 *p; |
324 | 367 | ||
@@ -326,46 +369,56 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) | |||
326 | g_u = dev->bars[colorpos][1]; /* G or precalculated U */ | 369 | g_u = dev->bars[colorpos][1]; /* G or precalculated U */ |
327 | b_v = dev->bars[colorpos][2]; /* B or precalculated V */ | 370 | b_v = dev->bars[colorpos][2]; /* B or precalculated V */ |
328 | 371 | ||
329 | for (color = 0; color < 4; color++) { | 372 | for (color = 0; color < dev->pixelsize; color++) { |
330 | p = buf + color; | 373 | p = buf + color; |
331 | 374 | ||
332 | switch (dev->fmt->fourcc) { | 375 | switch (dev->fmt->fourcc) { |
333 | case V4L2_PIX_FMT_YUYV: | 376 | case V4L2_PIX_FMT_YUYV: |
334 | switch (color) { | 377 | switch (color) { |
335 | case 0: | 378 | case 0: |
336 | case 2: | ||
337 | *p = r_y; | 379 | *p = r_y; |
338 | break; | 380 | break; |
339 | case 1: | 381 | case 1: |
340 | *p = g_u; | 382 | *p = odd ? b_v : g_u; |
341 | break; | ||
342 | case 3: | ||
343 | *p = b_v; | ||
344 | break; | 383 | break; |
345 | } | 384 | } |
346 | break; | 385 | break; |
347 | case V4L2_PIX_FMT_UYVY: | 386 | case V4L2_PIX_FMT_UYVY: |
348 | switch (color) { | 387 | switch (color) { |
388 | case 0: | ||
389 | *p = odd ? b_v : g_u; | ||
390 | break; | ||
349 | case 1: | 391 | case 1: |
350 | case 3: | ||
351 | *p = r_y; | 392 | *p = r_y; |
352 | break; | 393 | break; |
394 | } | ||
395 | break; | ||
396 | case V4L2_PIX_FMT_YVYU: | ||
397 | switch (color) { | ||
353 | case 0: | 398 | case 0: |
354 | *p = g_u; | 399 | *p = r_y; |
355 | break; | 400 | break; |
356 | case 2: | 401 | case 1: |
357 | *p = b_v; | 402 | *p = odd ? g_u : b_v; |
403 | break; | ||
404 | } | ||
405 | break; | ||
406 | case V4L2_PIX_FMT_VYUY: | ||
407 | switch (color) { | ||
408 | case 0: | ||
409 | *p = odd ? g_u : b_v; | ||
410 | break; | ||
411 | case 1: | ||
412 | *p = r_y; | ||
358 | break; | 413 | break; |
359 | } | 414 | } |
360 | break; | 415 | break; |
361 | case V4L2_PIX_FMT_RGB565: | 416 | case V4L2_PIX_FMT_RGB565: |
362 | switch (color) { | 417 | switch (color) { |
363 | case 0: | 418 | case 0: |
364 | case 2: | ||
365 | *p = (g_u << 5) | b_v; | 419 | *p = (g_u << 5) | b_v; |
366 | break; | 420 | break; |
367 | case 1: | 421 | case 1: |
368 | case 3: | ||
369 | *p = (r_y << 3) | (g_u >> 3); | 422 | *p = (r_y << 3) | (g_u >> 3); |
370 | break; | 423 | break; |
371 | } | 424 | } |
@@ -373,11 +426,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) | |||
373 | case V4L2_PIX_FMT_RGB565X: | 426 | case V4L2_PIX_FMT_RGB565X: |
374 | switch (color) { | 427 | switch (color) { |
375 | case 0: | 428 | case 0: |
376 | case 2: | ||
377 | *p = (r_y << 3) | (g_u >> 3); | 429 | *p = (r_y << 3) | (g_u >> 3); |
378 | break; | 430 | break; |
379 | case 1: | 431 | case 1: |
380 | case 3: | ||
381 | *p = (g_u << 5) | b_v; | 432 | *p = (g_u << 5) | b_v; |
382 | break; | 433 | break; |
383 | } | 434 | } |
@@ -385,24 +436,78 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) | |||
385 | case V4L2_PIX_FMT_RGB555: | 436 | case V4L2_PIX_FMT_RGB555: |
386 | switch (color) { | 437 | switch (color) { |
387 | case 0: | 438 | case 0: |
388 | case 2: | ||
389 | *p = (g_u << 5) | b_v; | 439 | *p = (g_u << 5) | b_v; |
390 | break; | 440 | break; |
391 | case 1: | 441 | case 1: |
392 | case 3: | 442 | *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); |
393 | *p = (r_y << 2) | (g_u >> 3); | ||
394 | break; | 443 | break; |
395 | } | 444 | } |
396 | break; | 445 | break; |
397 | case V4L2_PIX_FMT_RGB555X: | 446 | case V4L2_PIX_FMT_RGB555X: |
398 | switch (color) { | 447 | switch (color) { |
399 | case 0: | 448 | case 0: |
449 | *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); | ||
450 | break; | ||
451 | case 1: | ||
452 | *p = (g_u << 5) | b_v; | ||
453 | break; | ||
454 | } | ||
455 | break; | ||
456 | case V4L2_PIX_FMT_RGB24: | ||
457 | switch (color) { | ||
458 | case 0: | ||
459 | *p = r_y; | ||
460 | break; | ||
461 | case 1: | ||
462 | *p = g_u; | ||
463 | break; | ||
400 | case 2: | 464 | case 2: |
401 | *p = (r_y << 2) | (g_u >> 3); | 465 | *p = b_v; |
466 | break; | ||
467 | } | ||
468 | break; | ||
469 | case V4L2_PIX_FMT_BGR24: | ||
470 | switch (color) { | ||
471 | case 0: | ||
472 | *p = b_v; | ||
402 | break; | 473 | break; |
403 | case 1: | 474 | case 1: |
475 | *p = g_u; | ||
476 | break; | ||
477 | case 2: | ||
478 | *p = r_y; | ||
479 | break; | ||
480 | } | ||
481 | break; | ||
482 | case V4L2_PIX_FMT_RGB32: | ||
483 | switch (color) { | ||
484 | case 0: | ||
485 | *p = alpha; | ||
486 | break; | ||
487 | case 1: | ||
488 | *p = r_y; | ||
489 | break; | ||
490 | case 2: | ||
491 | *p = g_u; | ||
492 | break; | ||
404 | case 3: | 493 | case 3: |
405 | *p = (g_u << 5) | b_v; | 494 | *p = b_v; |
495 | break; | ||
496 | } | ||
497 | break; | ||
498 | case V4L2_PIX_FMT_BGR32: | ||
499 | switch (color) { | ||
500 | case 0: | ||
501 | *p = b_v; | ||
502 | break; | ||
503 | case 1: | ||
504 | *p = g_u; | ||
505 | break; | ||
506 | case 2: | ||
507 | *p = r_y; | ||
508 | break; | ||
509 | case 3: | ||
510 | *p = alpha; | ||
406 | break; | 511 | break; |
407 | } | 512 | } |
408 | break; | 513 | break; |
@@ -414,10 +519,10 @@ static void precalculate_line(struct vivi_dev *dev) | |||
414 | { | 519 | { |
415 | int w; | 520 | int w; |
416 | 521 | ||
417 | for (w = 0; w < dev->width * 2; w += 2) { | 522 | for (w = 0; w < dev->width * 2; w++) { |
418 | int colorpos = (w / (dev->width / 8) % 8); | 523 | int colorpos = w / (dev->width / 8) % 8; |
419 | 524 | ||
420 | gen_twopix(dev, dev->line + w * 2, colorpos); | 525 | gen_twopix(dev, dev->line + w * dev->pixelsize, colorpos, w & 1); |
421 | } | 526 | } |
422 | } | 527 | } |
423 | 528 | ||
@@ -433,7 +538,7 @@ static void gen_text(struct vivi_dev *dev, char *basep, | |||
433 | /* Print stream time */ | 538 | /* Print stream time */ |
434 | for (line = y; line < y + 16; line++) { | 539 | for (line = y; line < y + 16; line++) { |
435 | int j = 0; | 540 | int j = 0; |
436 | char *pos = basep + line * dev->width * 2 + x * 2; | 541 | char *pos = basep + line * dev->width * dev->pixelsize + x * dev->pixelsize; |
437 | char *s; | 542 | char *s; |
438 | 543 | ||
439 | for (s = text; *s; s++) { | 544 | for (s = text; *s; s++) { |
@@ -443,9 +548,9 @@ static void gen_text(struct vivi_dev *dev, char *basep, | |||
443 | for (i = 0; i < 7; i++, j++) { | 548 | for (i = 0; i < 7; i++, j++) { |
444 | /* Draw white font on black background */ | 549 | /* Draw white font on black background */ |
445 | if (chr & (1 << (7 - i))) | 550 | if (chr & (1 << (7 - i))) |
446 | gen_twopix(dev, pos + j * 2, WHITE); | 551 | gen_twopix(dev, pos + j * dev->pixelsize, WHITE, (x+y) & 1); |
447 | else | 552 | else |
448 | gen_twopix(dev, pos + j * 2, TEXT_BLACK); | 553 | gen_twopix(dev, pos + j * dev->pixelsize, TEXT_BLACK, (x+y) & 1); |
449 | } | 554 | } |
450 | } | 555 | } |
451 | } | 556 | } |
@@ -466,7 +571,9 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | |||
466 | return; | 571 | return; |
467 | 572 | ||
468 | for (h = 0; h < hmax; h++) | 573 | for (h = 0; h < hmax; h++) |
469 | memcpy(vbuf + h * wmax * 2, dev->line + (dev->mv_count % wmax) * 2, wmax * 2); | 574 | memcpy(vbuf + h * wmax * dev->pixelsize, |
575 | dev->line + (dev->mv_count % wmax) * dev->pixelsize, | ||
576 | wmax * dev->pixelsize); | ||
470 | 577 | ||
471 | /* Updates stream time */ | 578 | /* Updates stream time */ |
472 | 579 | ||
@@ -484,15 +591,16 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | |||
484 | gen_text(dev, vbuf, line++ * 16, 16, str); | 591 | gen_text(dev, vbuf, line++ * 16, 16, str); |
485 | 592 | ||
486 | gain = v4l2_ctrl_g_ctrl(dev->gain); | 593 | gain = v4l2_ctrl_g_ctrl(dev->gain); |
487 | mutex_lock(&dev->ctrl_handler.lock); | 594 | mutex_lock(dev->ctrl_handler.lock); |
488 | snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", | 595 | snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", |
489 | dev->brightness->cur.val, | 596 | dev->brightness->cur.val, |
490 | dev->contrast->cur.val, | 597 | dev->contrast->cur.val, |
491 | dev->saturation->cur.val, | 598 | dev->saturation->cur.val, |
492 | dev->hue->cur.val); | 599 | dev->hue->cur.val); |
493 | gen_text(dev, vbuf, line++ * 16, 16, str); | 600 | gen_text(dev, vbuf, line++ * 16, 16, str); |
494 | snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d ", | 601 | snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d, alpha 0x%02x ", |
495 | dev->autogain->cur.val, gain, dev->volume->cur.val); | 602 | dev->autogain->cur.val, gain, dev->volume->cur.val, |
603 | dev->alpha->cur.val); | ||
496 | gen_text(dev, vbuf, line++ * 16, 16, str); | 604 | gen_text(dev, vbuf, line++ * 16, 16, str); |
497 | snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ", | 605 | snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ", |
498 | dev->int32->cur.val, | 606 | dev->int32->cur.val, |
@@ -503,8 +611,12 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | |||
503 | dev->boolean->cur.val, | 611 | dev->boolean->cur.val, |
504 | dev->menu->qmenu[dev->menu->cur.val], | 612 | dev->menu->qmenu[dev->menu->cur.val], |
505 | dev->string->cur.string); | 613 | dev->string->cur.string); |
506 | mutex_unlock(&dev->ctrl_handler.lock); | ||
507 | gen_text(dev, vbuf, line++ * 16, 16, str); | 614 | gen_text(dev, vbuf, line++ * 16, 16, str); |
615 | snprintf(str, sizeof(str), " integer_menu %lld, value %d ", | ||
616 | dev->int_menu->qmenu_int[dev->int_menu->cur.val], | ||
617 | dev->int_menu->cur.val); | ||
618 | gen_text(dev, vbuf, line++ * 16, 16, str); | ||
619 | mutex_unlock(dev->ctrl_handler.lock); | ||
508 | if (dev->button_pressed) { | 620 | if (dev->button_pressed) { |
509 | dev->button_pressed--; | 621 | dev->button_pressed--; |
510 | snprintf(str, sizeof(str), " button pressed!"); | 622 | snprintf(str, sizeof(str), " button pressed!"); |
@@ -657,7 +769,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
657 | struct vivi_dev *dev = vb2_get_drv_priv(vq); | 769 | struct vivi_dev *dev = vb2_get_drv_priv(vq); |
658 | unsigned long size; | 770 | unsigned long size; |
659 | 771 | ||
660 | size = dev->width * dev->height * 2; | 772 | size = dev->width * dev->height * dev->pixelsize; |
661 | 773 | ||
662 | if (0 == *nbuffers) | 774 | if (0 == *nbuffers) |
663 | *nbuffers = 32; | 775 | *nbuffers = 32; |
@@ -721,7 +833,7 @@ static int buffer_prepare(struct vb2_buffer *vb) | |||
721 | dev->height < 32 || dev->height > MAX_HEIGHT) | 833 | dev->height < 32 || dev->height > MAX_HEIGHT) |
722 | return -EINVAL; | 834 | return -EINVAL; |
723 | 835 | ||
724 | size = dev->width * dev->height * 2; | 836 | size = dev->width * dev->height * dev->pixelsize; |
725 | if (vb2_plane_size(vb, 0) < size) { | 837 | if (vb2_plane_size(vb, 0) < size) { |
726 | dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n", | 838 | dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n", |
727 | __func__, vb2_plane_size(vb, 0), size); | 839 | __func__, vb2_plane_size(vb, 0), size); |
@@ -915,6 +1027,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
915 | } | 1027 | } |
916 | 1028 | ||
917 | dev->fmt = get_format(f); | 1029 | dev->fmt = get_format(f); |
1030 | dev->pixelsize = dev->fmt->depth / 8; | ||
918 | dev->width = f->fmt.pix.width; | 1031 | dev->width = f->fmt.pix.width; |
919 | dev->height = f->fmt.pix.height; | 1032 | dev->height = f->fmt.pix.height; |
920 | dev->field = f->fmt.pix.field; | 1033 | dev->field = f->fmt.pix.field; |
@@ -1016,8 +1129,15 @@ static int vivi_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1016 | { | 1129 | { |
1017 | struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler); | 1130 | struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler); |
1018 | 1131 | ||
1019 | if (ctrl == dev->button) | 1132 | switch (ctrl->id) { |
1020 | dev->button_pressed = 30; | 1133 | case V4L2_CID_ALPHA_COMPONENT: |
1134 | dev->alpha_component = ctrl->val; | ||
1135 | break; | ||
1136 | default: | ||
1137 | if (ctrl == dev->button) | ||
1138 | dev->button_pressed = 30; | ||
1139 | break; | ||
1140 | } | ||
1021 | return 0; | 1141 | return 0; |
1022 | } | 1142 | } |
1023 | 1143 | ||
@@ -1039,17 +1159,10 @@ static unsigned int | |||
1039 | vivi_poll(struct file *file, struct poll_table_struct *wait) | 1159 | vivi_poll(struct file *file, struct poll_table_struct *wait) |
1040 | { | 1160 | { |
1041 | struct vivi_dev *dev = video_drvdata(file); | 1161 | struct vivi_dev *dev = video_drvdata(file); |
1042 | struct v4l2_fh *fh = file->private_data; | ||
1043 | struct vb2_queue *q = &dev->vb_vidq; | 1162 | struct vb2_queue *q = &dev->vb_vidq; |
1044 | unsigned int res; | ||
1045 | 1163 | ||
1046 | dprintk(dev, 1, "%s\n", __func__); | 1164 | dprintk(dev, 1, "%s\n", __func__); |
1047 | res = vb2_poll(q, file, wait); | 1165 | return vb2_poll(q, file, wait); |
1048 | if (v4l2_event_pending(fh)) | ||
1049 | res |= POLLPRI; | ||
1050 | else | ||
1051 | poll_wait(file, &fh->wait, wait); | ||
1052 | return res; | ||
1053 | } | 1166 | } |
1054 | 1167 | ||
1055 | static int vivi_close(struct file *file) | 1168 | static int vivi_close(struct file *file) |
@@ -1165,6 +1278,22 @@ static const struct v4l2_ctrl_config vivi_ctrl_bitmask = { | |||
1165 | .step = 0, | 1278 | .step = 0, |
1166 | }; | 1279 | }; |
1167 | 1280 | ||
1281 | static const s64 vivi_ctrl_int_menu_values[] = { | ||
1282 | 1, 1, 2, 3, 5, 8, 13, 21, 42, | ||
1283 | }; | ||
1284 | |||
1285 | static const struct v4l2_ctrl_config vivi_ctrl_int_menu = { | ||
1286 | .ops = &vivi_ctrl_ops, | ||
1287 | .id = VIVI_CID_CUSTOM_BASE + 7, | ||
1288 | .name = "Integer menu", | ||
1289 | .type = V4L2_CTRL_TYPE_INTEGER_MENU, | ||
1290 | .min = 1, | ||
1291 | .max = 8, | ||
1292 | .def = 4, | ||
1293 | .menu_skip_mask = 0x02, | ||
1294 | .qmenu_int = vivi_ctrl_int_menu_values, | ||
1295 | }; | ||
1296 | |||
1168 | static const struct v4l2_file_operations vivi_fops = { | 1297 | static const struct v4l2_file_operations vivi_fops = { |
1169 | .owner = THIS_MODULE, | 1298 | .owner = THIS_MODULE, |
1170 | .open = v4l2_fh_open, | 1299 | .open = v4l2_fh_open, |
@@ -1252,6 +1381,7 @@ static int __init vivi_create_instance(int inst) | |||
1252 | dev->fmt = &formats[0]; | 1381 | dev->fmt = &formats[0]; |
1253 | dev->width = 640; | 1382 | dev->width = 640; |
1254 | dev->height = 480; | 1383 | dev->height = 480; |
1384 | dev->pixelsize = dev->fmt->depth / 8; | ||
1255 | hdl = &dev->ctrl_handler; | 1385 | hdl = &dev->ctrl_handler; |
1256 | v4l2_ctrl_handler_init(hdl, 11); | 1386 | v4l2_ctrl_handler_init(hdl, 11); |
1257 | dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, | 1387 | dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, |
@@ -1268,6 +1398,8 @@ static int __init vivi_create_instance(int inst) | |||
1268 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | 1398 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); |
1269 | dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, | 1399 | dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, |
1270 | V4L2_CID_GAIN, 0, 255, 1, 100); | 1400 | V4L2_CID_GAIN, 0, 255, 1, 100); |
1401 | dev->alpha = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, | ||
1402 | V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0); | ||
1271 | dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL); | 1403 | dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL); |
1272 | dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL); | 1404 | dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL); |
1273 | dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL); | 1405 | dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL); |
@@ -1275,6 +1407,7 @@ static int __init vivi_create_instance(int inst) | |||
1275 | dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL); | 1407 | dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL); |
1276 | dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL); | 1408 | dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL); |
1277 | dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL); | 1409 | dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL); |
1410 | dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL); | ||
1278 | if (hdl->error) { | 1411 | if (hdl->error) { |
1279 | ret = hdl->error; | 1412 | ret = hdl->error; |
1280 | goto unreg_dev; | 1413 | goto unreg_dev; |