diff options
Diffstat (limited to 'drivers/media/video/ks0127.c')
-rw-r--r-- | drivers/media/video/ks0127.c | 152 |
1 files changed, 62 insertions, 90 deletions
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index bae2d2beb709..c97d55a43c07 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c | |||
@@ -201,7 +201,7 @@ struct ks0127 { | |||
201 | int format_height; | 201 | int format_height; |
202 | int cap_width; | 202 | int cap_width; |
203 | int cap_height; | 203 | int cap_height; |
204 | int norm; | 204 | v4l2_std_id norm; |
205 | int ks_type; | 205 | int ks_type; |
206 | u8 regs[256]; | 206 | u8 regs[256]; |
207 | }; | 207 | }; |
@@ -408,20 +408,22 @@ static void ks0127_reset(struct i2c_client *c) | |||
408 | static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | 408 | static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) |
409 | { | 409 | { |
410 | struct ks0127 *ks = i2c_get_clientdata(c); | 410 | struct ks0127 *ks = i2c_get_clientdata(c); |
411 | struct v4l2_routing *route = arg; | ||
411 | int *iarg = (int *)arg; | 412 | int *iarg = (int *)arg; |
413 | v4l2_std_id *istd = arg; | ||
412 | int status; | 414 | int status; |
413 | 415 | ||
414 | if (!ks) | 416 | if (!ks) |
415 | return -ENODEV; | 417 | return -ENODEV; |
416 | 418 | ||
417 | switch (cmd) { | 419 | switch (cmd) { |
418 | case DECODER_INIT: | 420 | case VIDIOC_INT_INIT: |
419 | v4l_dbg(1, debug, c, "DECODER_INIT\n"); | 421 | v4l_dbg(1, debug, c, "VIDIOC_INT_INIT\n"); |
420 | ks0127_reset(c); | 422 | ks0127_reset(c); |
421 | break; | 423 | break; |
422 | 424 | ||
423 | case DECODER_SET_INPUT: | 425 | case VIDIOC_INT_S_VIDEO_ROUTING: |
424 | switch(*iarg) { | 426 | switch (route->input) { |
425 | case KS_INPUT_COMPOSITE_1: | 427 | case KS_INPUT_COMPOSITE_1: |
426 | case KS_INPUT_COMPOSITE_2: | 428 | case KS_INPUT_COMPOSITE_2: |
427 | case KS_INPUT_COMPOSITE_3: | 429 | case KS_INPUT_COMPOSITE_3: |
@@ -429,7 +431,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
429 | case KS_INPUT_COMPOSITE_5: | 431 | case KS_INPUT_COMPOSITE_5: |
430 | case KS_INPUT_COMPOSITE_6: | 432 | case KS_INPUT_COMPOSITE_6: |
431 | v4l_dbg(1, debug, c, | 433 | v4l_dbg(1, debug, c, |
432 | "DECODER_SET_INPUT %d: Composite\n", *iarg); | 434 | "VIDIOC_S_INPUT %d: Composite\n", *iarg); |
433 | /* autodetect 50/60 Hz */ | 435 | /* autodetect 50/60 Hz */ |
434 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); | 436 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
435 | /* VSE=0 */ | 437 | /* VSE=0 */ |
@@ -463,7 +465,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
463 | case KS_INPUT_SVIDEO_2: | 465 | case KS_INPUT_SVIDEO_2: |
464 | case KS_INPUT_SVIDEO_3: | 466 | case KS_INPUT_SVIDEO_3: |
465 | v4l_dbg(1, debug, c, | 467 | v4l_dbg(1, debug, c, |
466 | "DECODER_SET_INPUT %d: S-Video\n", *iarg); | 468 | "VIDIOC_S_INPUT %d: S-Video\n", *iarg); |
467 | /* autodetect 50/60 Hz */ | 469 | /* autodetect 50/60 Hz */ |
468 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); | 470 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
469 | /* VSE=0 */ | 471 | /* VSE=0 */ |
@@ -495,9 +497,8 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
495 | 497 | ||
496 | case KS_INPUT_YUV656: | 498 | case KS_INPUT_YUV656: |
497 | v4l_dbg(1, debug, c, | 499 | v4l_dbg(1, debug, c, |
498 | "DECODER_SET_INPUT 15: YUV656\n"); | 500 | "VIDIOC_S_INPUT 15: YUV656\n"); |
499 | if (ks->norm == VIDEO_MODE_NTSC || | 501 | if (ks->norm & V4L2_STD_525_60) |
500 | ks->norm == KS_STD_PAL_M) | ||
501 | /* force 60 Hz */ | 502 | /* force 60 Hz */ |
502 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); | 503 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); |
503 | else | 504 | else |
@@ -541,7 +542,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
541 | 542 | ||
542 | default: | 543 | default: |
543 | v4l_dbg(1, debug, c, | 544 | v4l_dbg(1, debug, c, |
544 | "DECODER_SET_INPUT: Unknown input %d\n", *iarg); | 545 | "VIDIOC_INT_S_VIDEO_ROUTING: Unknown input %d\n", route->input); |
545 | break; | 546 | break; |
546 | } | 547 | } |
547 | 548 | ||
@@ -550,77 +551,37 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
550 | ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); | 551 | ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); |
551 | break; | 552 | break; |
552 | 553 | ||
553 | case DECODER_SET_OUTPUT: | 554 | case VIDIOC_S_STD: /* sam This block mixes old and new norm names... */ |
554 | switch(*iarg) { | ||
555 | case KS_OUTPUT_YUV656E: | ||
556 | v4l_dbg(1, debug, c, | ||
557 | "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); | ||
558 | return -EINVAL; | ||
559 | |||
560 | case KS_OUTPUT_EXV: | ||
561 | v4l_dbg(1, debug, c, | ||
562 | "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); | ||
563 | ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); | ||
564 | break; | ||
565 | } | ||
566 | break; | ||
567 | |||
568 | case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ | ||
569 | /* Set to automatic SECAM/Fsc mode */ | 555 | /* Set to automatic SECAM/Fsc mode */ |
570 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); | 556 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); |
571 | 557 | ||
572 | ks->norm = *iarg; | 558 | ks->norm = *istd; |
573 | switch (*iarg) { | ||
574 | /* this is untested !! */ | ||
575 | /* It just detects PAL_N/NTSC_M (no special frequencies) */ | ||
576 | /* And you have to set the standard a second time afterwards */ | ||
577 | case VIDEO_MODE_AUTO: | ||
578 | v4l_dbg(1, debug, c, | ||
579 | "DECODER_SET_NORM: AUTO\n"); | ||
580 | 559 | ||
581 | /* The chip determines the format */ | 560 | if (*istd & V4L2_STD_NTSC) { |
582 | /* based on the current field rate */ | ||
583 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); | ||
584 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); | ||
585 | /* This is wrong for PAL ! As I said, */ | ||
586 | /* you need to set the standard once again !! */ | ||
587 | ks->format_height = 240; | ||
588 | ks->format_width = 704; | ||
589 | break; | ||
590 | |||
591 | case VIDEO_MODE_NTSC: | ||
592 | v4l_dbg(1, debug, c, | 561 | v4l_dbg(1, debug, c, |
593 | "DECODER_SET_NORM: NTSC_M\n"); | 562 | "VIDIOC_S_STD: NTSC_M\n"); |
594 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); | 563 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); |
595 | ks->format_height = 240; | 564 | ks->format_height = 240; |
596 | ks->format_width = 704; | 565 | ks->format_width = 704; |
597 | break; | 566 | } else if (*istd & V4L2_STD_PAL_N) { |
598 | |||
599 | case KS_STD_NTSC_N: | ||
600 | v4l_dbg(1, debug, c, | 567 | v4l_dbg(1, debug, c, |
601 | "KS0127_SET_NORM: NTSC_N (fixme)\n"); | 568 | "KS0127_SET_NORM: NTSC_N (fixme)\n"); |
602 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); | 569 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); |
603 | ks->format_height = 240; | 570 | ks->format_height = 240; |
604 | ks->format_width = 704; | 571 | ks->format_width = 704; |
605 | break; | 572 | } else if (*istd & V4L2_STD_PAL) { |
606 | |||
607 | case VIDEO_MODE_PAL: | ||
608 | v4l_dbg(1, debug, c, | 573 | v4l_dbg(1, debug, c, |
609 | "DECODER_SET_NORM: PAL_N\n"); | 574 | "VIDIOC_S_STD: PAL_N\n"); |
610 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); | 575 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); |
611 | ks->format_height = 290; | 576 | ks->format_height = 290; |
612 | ks->format_width = 704; | 577 | ks->format_width = 704; |
613 | break; | 578 | } else if (*istd & V4L2_STD_PAL_M) { |
614 | |||
615 | case KS_STD_PAL_M: | ||
616 | v4l_dbg(1, debug, c, | 579 | v4l_dbg(1, debug, c, |
617 | "KS0127_SET_NORM: PAL_M (fixme)\n"); | 580 | "KS0127_SET_NORM: PAL_M (fixme)\n"); |
618 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); | 581 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); |
619 | ks->format_height = 290; | 582 | ks->format_height = 290; |
620 | ks->format_width = 704; | 583 | ks->format_width = 704; |
621 | break; | 584 | } else if (*istd & V4L2_STD_SECAM) { |
622 | |||
623 | case VIDEO_MODE_SECAM: | ||
624 | v4l_dbg(1, debug, c, | 585 | v4l_dbg(1, debug, c, |
625 | "KS0127_SET_NORM: SECAM\n"); | 586 | "KS0127_SET_NORM: SECAM\n"); |
626 | ks->format_height = 290; | 587 | ks->format_height = 290; |
@@ -632,29 +593,34 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
632 | schedule_timeout_interruptible(HZ/10+1); | 593 | schedule_timeout_interruptible(HZ/10+1); |
633 | 594 | ||
634 | /* did it autodetect? */ | 595 | /* did it autodetect? */ |
635 | if (ks0127_read(c, KS_DEMOD) & 0x40) | 596 | if (!(ks0127_read(c, KS_DEMOD) & 0x40)) |
636 | break; | 597 | /* force to secam mode */ |
637 | 598 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); | |
638 | /* force to secam mode */ | 599 | } else { |
639 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); | ||
640 | break; | ||
641 | |||
642 | default: | ||
643 | v4l_dbg(1, debug, c, | 600 | v4l_dbg(1, debug, c, |
644 | "DECODER_SET_NORM: Unknown norm %d\n", *iarg); | 601 | "VIDIOC_S_STD: Unknown norm %llx\n", *istd); |
645 | break; | ||
646 | } | 602 | } |
647 | break; | 603 | break; |
648 | 604 | ||
649 | case DECODER_SET_PICTURE: | 605 | case VIDIOC_QUERYCTRL: |
606 | { | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | |||
610 | case VIDIOC_S_CTRL: | ||
650 | v4l_dbg(1, debug, c, | 611 | v4l_dbg(1, debug, c, |
651 | "DECODER_SET_PICTURE: not yet supported\n"); | 612 | "VIDIOC_S_CTRL: not yet supported\n"); |
652 | return -EINVAL; | 613 | return -EINVAL; |
653 | 614 | ||
654 | /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ | 615 | case VIDIOC_G_CTRL: |
655 | /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ | 616 | v4l_dbg(1, debug, c, |
656 | /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ | 617 | "VIDIOC_G_CTRL: not yet supported\n"); |
657 | /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ | 618 | return -EINVAL; |
619 | |||
620 | /* sam todo: KS0127_SET_BRIGHTNESS: Merge into VIDIOC_S_CTRL */ | ||
621 | /* sam todo: KS0127_SET_CONTRAST: Merge into VIDIOC_S_CTRL */ | ||
622 | /* sam todo: KS0127_SET_HUE: Merge into VIDIOC_S_CTRL? */ | ||
623 | /* sam todo: KS0127_SET_SATURATION: Merge into VIDIOC_S_CTRL */ | ||
658 | /* sam todo: KS0127_SET_AGC_MODE: */ | 624 | /* sam todo: KS0127_SET_AGC_MODE: */ |
659 | /* sam todo: KS0127_SET_AGC: */ | 625 | /* sam todo: KS0127_SET_AGC: */ |
660 | /* sam todo: KS0127_SET_CHROMA_MODE: */ | 626 | /* sam todo: KS0127_SET_CHROMA_MODE: */ |
@@ -670,22 +636,21 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
670 | /* sam todo: KS0127_SET_UNUSEV: */ | 636 | /* sam todo: KS0127_SET_UNUSEV: */ |
671 | /* sam todo: KS0127_SET_VSALIGN_MODE: */ | 637 | /* sam todo: KS0127_SET_VSALIGN_MODE: */ |
672 | 638 | ||
673 | case DECODER_ENABLE_OUTPUT: | 639 | case VIDIOC_STREAMON: |
640 | case VIDIOC_STREAMOFF: | ||
674 | { | 641 | { |
675 | int enable; | 642 | int enable = cmd == VIDIOC_STREAMON; |
676 | 643 | ||
677 | iarg = arg; | ||
678 | enable = (*iarg != 0); | ||
679 | if (enable) { | 644 | if (enable) { |
680 | v4l_dbg(1, debug, c, | 645 | v4l_dbg(1, debug, c, |
681 | "DECODER_ENABLE_OUTPUT on\n"); | 646 | "VIDIOC_STREAMON\n"); |
682 | /* All output pins on */ | 647 | /* All output pins on */ |
683 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); | 648 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); |
684 | /* Obey the OEN pin */ | 649 | /* Obey the OEN pin */ |
685 | ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); | 650 | ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); |
686 | } else { | 651 | } else { |
687 | v4l_dbg(1, debug, c, | 652 | v4l_dbg(1, debug, c, |
688 | "DECODER_ENABLE_OUTPUT off\n"); | 653 | "VIDIOC_STREAMOFF\n"); |
689 | /* Video output pins off */ | 654 | /* Video output pins off */ |
690 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); | 655 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); |
691 | /* Ignore the OEN pin */ | 656 | /* Ignore the OEN pin */ |
@@ -699,19 +664,26 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) | |||
699 | /* sam todo: KS0127_SET_HEIGHT: */ | 664 | /* sam todo: KS0127_SET_HEIGHT: */ |
700 | /* sam todo: KS0127_SET_HSCALE: */ | 665 | /* sam todo: KS0127_SET_HSCALE: */ |
701 | 666 | ||
702 | case DECODER_GET_STATUS: | 667 | case VIDIOC_QUERYSTD: |
703 | v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); | 668 | case VIDIOC_INT_G_INPUT_STATUS: { |
704 | *iarg = 0; | 669 | int stat = V4L2_IN_ST_NO_SIGNAL; |
670 | v4l2_std_id std = V4L2_STD_ALL; | ||
671 | v4l_dbg(1, debug, c, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n"); | ||
705 | status = ks0127_read(c, KS_STAT); | 672 | status = ks0127_read(c, KS_STAT); |
706 | if (!(status & 0x20)) /* NOVID not set */ | 673 | if (!(status & 0x20)) /* NOVID not set */ |
707 | *iarg = (*iarg | DECODER_STATUS_GOOD); | 674 | stat = 0; |
708 | if ((status & 0x01)) /* CLOCK set */ | 675 | if (!(status & 0x01)) /* CLOCK set */ |
709 | *iarg = (*iarg | DECODER_STATUS_COLOR); | 676 | stat |= V4L2_IN_ST_NO_COLOR; |
710 | if ((status & 0x08)) /* PALDET set */ | 677 | if ((status & 0x08)) /* PALDET set */ |
711 | *iarg = (*iarg | DECODER_STATUS_PAL); | 678 | std = V4L2_STD_PAL; |
712 | else | 679 | else |
713 | *iarg = (*iarg | DECODER_STATUS_NTSC); | 680 | std = V4L2_STD_NTSC; |
681 | if (cmd == VIDIOC_QUERYSTD) | ||
682 | *istd = std; | ||
683 | else | ||
684 | *iarg = stat; | ||
714 | break; | 685 | break; |
686 | } | ||
715 | 687 | ||
716 | /* Catch any unknown command */ | 688 | /* Catch any unknown command */ |
717 | default: | 689 | default: |