diff options
| author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-11-25 10:47:02 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-05 15:42:14 -0500 |
| commit | feba2f817d87891c002739ecdb54eef56740b882 (patch) | |
| tree | 259e475dc91a0e2998294c8d6dc2531e2681fcda | |
| parent | 1ce7981be36e05216df64ffeceb8230d9b569b87 (diff) | |
V4L/DVB (13509): pms: convert from V4L1 to V4L2.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/video/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/media/video/pms.c | 472 |
2 files changed, 287 insertions, 187 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 82ae85c975f5..9dc74c93bf24 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
| @@ -600,7 +600,7 @@ source "drivers/media/video/bt8xx/Kconfig" | |||
| 600 | 600 | ||
| 601 | config VIDEO_PMS | 601 | config VIDEO_PMS |
| 602 | tristate "Mediavision Pro Movie Studio Video For Linux" | 602 | tristate "Mediavision Pro Movie Studio Video For Linux" |
| 603 | depends on ISA && VIDEO_V4L1 | 603 | depends on ISA && VIDEO_V4L2 |
| 604 | help | 604 | help |
| 605 | Say Y if you have such a thing. | 605 | Say Y if you have such a thing. |
| 606 | 606 | ||
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 2919aa42c94e..73ec970ca5ca 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
| @@ -14,8 +14,10 @@ | |||
| 14 | * unless the userspace driver also doesn't work for you... | 14 | * unless the userspace driver also doesn't work for you... |
| 15 | * | 15 | * |
| 16 | * Changes: | 16 | * Changes: |
| 17 | * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it> | 17 | * 25-11-2009 Hans Verkuil <hverkuil@xs4all.nl> |
| 18 | * - pms_capture: report back -EFAULT | 18 | * - converted to version 2 of the V4L API. |
| 19 | * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it> | ||
| 20 | * - pms_capture: report back -EFAULT | ||
| 19 | */ | 21 | */ |
| 20 | 22 | ||
| 21 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| @@ -27,20 +29,21 @@ | |||
| 27 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
| 28 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
| 29 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 32 | #include <linux/version.h> | ||
| 33 | #include <linux/mutex.h> | ||
| 34 | #include <asm/uaccess.h> | ||
| 30 | #include <asm/io.h> | 35 | #include <asm/io.h> |
| 31 | #include <linux/videodev.h> | 36 | |
| 37 | #include <linux/videodev2.h> | ||
| 32 | #include <media/v4l2-common.h> | 38 | #include <media/v4l2-common.h> |
| 33 | #include <media/v4l2-ioctl.h> | 39 | #include <media/v4l2-ioctl.h> |
| 34 | #include <media/v4l2-device.h> | 40 | #include <media/v4l2-device.h> |
| 35 | #include <linux/mutex.h> | ||
| 36 | |||
| 37 | #include <asm/uaccess.h> | ||
| 38 | 41 | ||
| 39 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
| 40 | 43 | ||
| 41 | 44 | ||
| 42 | #define MOTOROLA 1 | 45 | #define MOTOROLA 1 |
| 43 | #define PHILIPS2 2 | 46 | #define PHILIPS2 2 /* SAA7191 */ |
| 44 | #define PHILIPS1 3 | 47 | #define PHILIPS1 3 |
| 45 | #define MVVMEMORYWIDTH 0x40 /* 512 bytes */ | 48 | #define MVVMEMORYWIDTH 0x40 /* 512 bytes */ |
| 46 | 49 | ||
| @@ -54,9 +57,11 @@ struct i2c_info { | |||
| 54 | struct pms { | 57 | struct pms { |
| 55 | struct v4l2_device v4l2_dev; | 58 | struct v4l2_device v4l2_dev; |
| 56 | struct video_device vdev; | 59 | struct video_device vdev; |
| 57 | struct video_picture picture; | ||
| 58 | int height; | 60 | int height; |
| 59 | int width; | 61 | int width; |
| 62 | int depth; | ||
| 63 | int input; | ||
| 64 | s32 brightness, saturation, hue, contrast; | ||
| 60 | unsigned long in_use; | 65 | unsigned long in_use; |
| 61 | struct mutex lock; | 66 | struct mutex lock; |
| 62 | int i2c_count; | 67 | int i2c_count; |
| @@ -64,6 +69,7 @@ struct pms { | |||
| 64 | 69 | ||
| 65 | int decoder; | 70 | int decoder; |
| 66 | int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ | 71 | int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ |
| 72 | v4l2_std_id std; | ||
| 67 | int io; | 73 | int io; |
| 68 | int data; | 74 | int data; |
| 69 | void __iomem *mem; | 75 | void __iomem *mem; |
| @@ -209,7 +215,19 @@ static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or) | |||
| 209 | 215 | ||
| 210 | static void pms_videosource(struct pms *dev, short source) | 216 | static void pms_videosource(struct pms *dev, short source) |
| 211 | { | 217 | { |
| 212 | mvv_write(dev, 0x2E, source ? 0x31 : 0x30); | 218 | switch (dev->decoder) { |
| 219 | case MOTOROLA: | ||
| 220 | break; | ||
| 221 | case PHILIPS2: | ||
| 222 | pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0); | ||
| 223 | break; | ||
| 224 | case PHILIPS1: | ||
| 225 | break; | ||
| 226 | } | ||
| 227 | mvv_write(dev, 0x2E, 0x31); | ||
| 228 | /* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30); | ||
| 229 | But could not make this work correctly. Only Composite input | ||
| 230 | worked for me. */ | ||
| 213 | } | 231 | } |
| 214 | 232 | ||
| 215 | static void pms_hue(struct pms *dev, short hue) | 233 | static void pms_hue(struct pms *dev, short hue) |
| @@ -227,14 +245,14 @@ static void pms_hue(struct pms *dev, short hue) | |||
| 227 | } | 245 | } |
| 228 | } | 246 | } |
| 229 | 247 | ||
| 230 | static void pms_colour(struct pms *dev, short colour) | 248 | static void pms_saturation(struct pms *dev, short sat) |
| 231 | { | 249 | { |
| 232 | switch (dev->decoder) { | 250 | switch (dev->decoder) { |
| 233 | case MOTOROLA: | 251 | case MOTOROLA: |
| 234 | pms_i2c_write(dev, 0x8a, 0x00, colour); | 252 | pms_i2c_write(dev, 0x8a, 0x00, sat); |
| 235 | break; | 253 | break; |
| 236 | case PHILIPS1: | 254 | case PHILIPS1: |
| 237 | pms_i2c_write(dev, 0x42, 0x12, colour); | 255 | pms_i2c_write(dev, 0x42, 0x12, sat); |
| 238 | break; | 256 | break; |
| 239 | } | 257 | } |
| 240 | } | 258 | } |
| @@ -467,7 +485,7 @@ static void pms_swsense(struct pms *dev, short sense) | |||
| 467 | 485 | ||
| 468 | static void pms_framerate(struct pms *dev, short frr) | 486 | static void pms_framerate(struct pms *dev, short frr) |
| 469 | { | 487 | { |
| 470 | int fps = (dev->standard == 1) ? 30 : 25; | 488 | int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25; |
| 471 | 489 | ||
| 472 | if (frr == 0) | 490 | if (frr == 0) |
| 473 | return; | 491 | return; |
| @@ -557,7 +575,7 @@ static void pms_resolution(struct pms *dev, short width, short height) | |||
| 557 | mvv_write(dev, 0x18, fg_height); | 575 | mvv_write(dev, 0x18, fg_height); |
| 558 | mvv_write(dev, 0x19, fg_height >> 8); | 576 | mvv_write(dev, 0x19, fg_height >> 8); |
| 559 | 577 | ||
| 560 | if (dev->standard == 1) { | 578 | if (dev->std & V4L2_STD_525_60) { |
| 561 | mvv_write(dev, 0x1a, 0xfc); | 579 | mvv_write(dev, 0x1a, 0xfc); |
| 562 | mvv_write(dev, 0x1b, 0x00); | 580 | mvv_write(dev, 0x1b, 0x00); |
| 563 | if (height > fg_height) | 581 | if (height > fg_height) |
| @@ -581,7 +599,7 @@ static void pms_resolution(struct pms *dev, short width, short height) | |||
| 581 | mvv_write(dev, 0x22, width + 8); | 599 | mvv_write(dev, 0x22, width + 8); |
| 582 | mvv_write(dev, 0x23, (width + 8) >> 8); | 600 | mvv_write(dev, 0x23, (width + 8) >> 8); |
| 583 | 601 | ||
| 584 | if (dev->standard == 1) | 602 | if (dev->std & V4L2_STD_525_60) |
| 585 | pms_horzdeci(dev, width, 640); | 603 | pms_horzdeci(dev, width, 640); |
| 586 | else | 604 | else |
| 587 | pms_horzdeci(dev, width + 8, 768); | 605 | pms_horzdeci(dev, width + 8, 768); |
| @@ -654,192 +672,252 @@ static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count) | |||
| 654 | * Video4linux interfacing | 672 | * Video4linux interfacing |
| 655 | */ | 673 | */ |
| 656 | 674 | ||
| 657 | static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 675 | static int pms_querycap(struct file *file, void *priv, |
| 676 | struct v4l2_capability *vcap) | ||
| 658 | { | 677 | { |
| 659 | struct pms *dev = video_drvdata(file); | 678 | struct pms *dev = video_drvdata(file); |
| 660 | 679 | ||
| 661 | switch (cmd) { | 680 | strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver)); |
| 662 | case VIDIOCGCAP: { | 681 | strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card)); |
| 663 | struct video_capability *b = arg; | 682 | strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info)); |
| 664 | 683 | vcap->version = KERNEL_VERSION(0, 0, 3); | |
| 665 | strcpy(b->name, "Mediavision PMS"); | 684 | vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; |
| 666 | b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; | 685 | return 0; |
| 667 | b->channels = 4; | 686 | } |
| 668 | b->audios = 0; | ||
| 669 | b->maxwidth = 640; | ||
| 670 | b->maxheight = 480; | ||
| 671 | b->minwidth = 16; | ||
| 672 | b->minheight = 16; | ||
| 673 | return 0; | ||
| 674 | } | ||
| 675 | case VIDIOCGCHAN: { | ||
| 676 | struct video_channel *v = arg; | ||
| 677 | |||
| 678 | if (v->channel < 0 || v->channel > 3) | ||
| 679 | return -EINVAL; | ||
| 680 | v->flags = 0; | ||
| 681 | v->tuners = 1; | ||
| 682 | /* Good question.. its composite or SVHS so.. */ | ||
| 683 | v->type = VIDEO_TYPE_CAMERA; | ||
| 684 | switch (v->channel) { | ||
| 685 | case 0: | ||
| 686 | strcpy(v->name, "Composite"); | ||
| 687 | break; | ||
| 688 | case 1: | ||
| 689 | strcpy(v->name, "SVideo"); | ||
| 690 | break; | ||
| 691 | case 2: | ||
| 692 | strcpy(v->name, "Composite(VCR)"); | ||
| 693 | break; | ||
| 694 | case 3: | ||
| 695 | strcpy(v->name, "SVideo(VCR)"); | ||
| 696 | break; | ||
| 697 | } | ||
| 698 | return 0; | ||
| 699 | } | ||
| 700 | case VIDIOCSCHAN: { | ||
| 701 | struct video_channel *v = arg; | ||
| 702 | |||
| 703 | if (v->channel < 0 || v->channel > 3) | ||
| 704 | return -EINVAL; | ||
| 705 | mutex_lock(&dev->lock); | ||
| 706 | pms_videosource(dev, v->channel & 1); | ||
| 707 | pms_vcrinput(dev, v->channel >> 1); | ||
| 708 | mutex_unlock(&dev->lock); | ||
| 709 | return 0; | ||
| 710 | } | ||
| 711 | case VIDIOCGTUNER: { | ||
| 712 | struct video_tuner *v = arg; | ||
| 713 | |||
| 714 | if (v->tuner) | ||
| 715 | return -EINVAL; | ||
| 716 | strcpy(v->name, "Format"); | ||
| 717 | v->rangelow = 0; | ||
| 718 | v->rangehigh = 0; | ||
| 719 | v->flags = VIDEO_TUNER_PAL | VIDEO_TUNER_NTSC | VIDEO_TUNER_SECAM; | ||
| 720 | switch (dev->standard) { | ||
| 721 | case 0: | ||
| 722 | v->mode = VIDEO_MODE_AUTO; | ||
| 723 | break; | ||
| 724 | case 1: | ||
| 725 | v->mode = VIDEO_MODE_NTSC; | ||
| 726 | break; | ||
| 727 | case 2: | ||
| 728 | v->mode = VIDEO_MODE_PAL; | ||
| 729 | break; | ||
| 730 | case 3: | ||
| 731 | v->mode = VIDEO_MODE_SECAM; | ||
| 732 | break; | ||
| 733 | } | ||
| 734 | return 0; | ||
| 735 | } | ||
| 736 | case VIDIOCSTUNER: { | ||
| 737 | struct video_tuner *v = arg; | ||
| 738 | |||
| 739 | if (v->tuner) | ||
| 740 | return -EINVAL; | ||
| 741 | mutex_lock(&dev->lock); | ||
| 742 | switch (v->mode) { | ||
| 743 | case VIDEO_MODE_AUTO: | ||
| 744 | pms_framerate(dev, 25); | ||
| 745 | pms_secamcross(dev, 0); | ||
| 746 | pms_format(dev, 0); | ||
| 747 | break; | ||
| 748 | case VIDEO_MODE_NTSC: | ||
| 749 | pms_framerate(dev, 30); | ||
| 750 | pms_secamcross(dev, 0); | ||
| 751 | pms_format(dev, 1); | ||
| 752 | break; | ||
| 753 | case VIDEO_MODE_PAL: | ||
| 754 | pms_framerate(dev, 25); | ||
| 755 | pms_secamcross(dev, 0); | ||
| 756 | pms_format(dev, 2); | ||
| 757 | break; | ||
| 758 | case VIDEO_MODE_SECAM: | ||
| 759 | pms_framerate(dev, 25); | ||
| 760 | pms_secamcross(dev, 1); | ||
| 761 | pms_format(dev, 2); | ||
| 762 | break; | ||
| 763 | default: | ||
| 764 | mutex_unlock(&dev->lock); | ||
| 765 | return -EINVAL; | ||
| 766 | } | ||
| 767 | mutex_unlock(&dev->lock); | ||
| 768 | return 0; | ||
| 769 | } | ||
| 770 | case VIDIOCGPICT: { | ||
| 771 | struct video_picture *p = arg; | ||
| 772 | 687 | ||
| 773 | *p = dev->picture; | 688 | static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin) |
| 774 | return 0; | 689 | { |
| 775 | } | 690 | static const char *inputs[4] = { |
| 776 | case VIDIOCSPICT: { | 691 | "Composite", |
| 777 | struct video_picture *p = arg; | 692 | "S-Video", |
| 693 | "Composite (VCR)", | ||
| 694 | "S-Video (VCR)" | ||
| 695 | }; | ||
| 778 | 696 | ||
| 779 | if (!((p->palette == VIDEO_PALETTE_RGB565 && p->depth == 16) || | 697 | if (vin->index > 3) |
| 780 | (p->palette == VIDEO_PALETTE_RGB555 && p->depth == 15))) | 698 | return -EINVAL; |
| 781 | return -EINVAL; | 699 | strlcpy(vin->name, inputs[vin->index], sizeof(vin->name)); |
| 782 | dev->picture = *p; | 700 | vin->type = V4L2_INPUT_TYPE_CAMERA; |
| 701 | vin->audioset = 0; | ||
| 702 | vin->tuner = 0; | ||
| 703 | vin->std = V4L2_STD_ALL; | ||
| 704 | vin->status = 0; | ||
| 705 | return 0; | ||
| 706 | } | ||
| 783 | 707 | ||
| 784 | /* | 708 | static int pms_g_input(struct file *file, void *fh, unsigned int *inp) |
| 785 | * Now load the card. | 709 | { |
| 786 | */ | 710 | struct pms *dev = video_drvdata(file); |
| 787 | 711 | ||
| 788 | mutex_lock(&dev->lock); | 712 | *inp = dev->input; |
| 789 | pms_brightness(dev, p->brightness >> 8); | 713 | return 0; |
| 790 | pms_hue(dev, p->hue >> 8); | 714 | } |
| 791 | pms_colour(dev, p->colour >> 8); | 715 | |
| 792 | pms_contrast(dev, p->contrast >> 8); | 716 | static int pms_s_input(struct file *file, void *fh, unsigned int inp) |
| 793 | mutex_unlock(&dev->lock); | 717 | { |
| 794 | return 0; | 718 | struct pms *dev = video_drvdata(file); |
| 719 | |||
| 720 | if (inp > 3) | ||
| 721 | return -EINVAL; | ||
| 722 | |||
| 723 | mutex_lock(&dev->lock); | ||
| 724 | dev->input = inp; | ||
| 725 | pms_videosource(dev, inp & 1); | ||
| 726 | pms_vcrinput(dev, inp >> 1); | ||
| 727 | mutex_unlock(&dev->lock); | ||
| 728 | return 0; | ||
| 729 | } | ||
| 730 | |||
| 731 | static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std) | ||
| 732 | { | ||
| 733 | struct pms *dev = video_drvdata(file); | ||
| 734 | |||
| 735 | *std = dev->std; | ||
| 736 | return 0; | ||
| 737 | } | ||
| 738 | |||
| 739 | static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std) | ||
| 740 | { | ||
| 741 | struct pms *dev = video_drvdata(file); | ||
| 742 | int ret = 0; | ||
| 743 | |||
| 744 | dev->std = *std; | ||
| 745 | mutex_lock(&dev->lock); | ||
| 746 | if (dev->std & V4L2_STD_NTSC) { | ||
| 747 | pms_framerate(dev, 30); | ||
| 748 | pms_secamcross(dev, 0); | ||
| 749 | pms_format(dev, 1); | ||
| 750 | } else if (dev->std & V4L2_STD_PAL) { | ||
| 751 | pms_framerate(dev, 25); | ||
| 752 | pms_secamcross(dev, 0); | ||
| 753 | pms_format(dev, 2); | ||
| 754 | } else if (dev->std & V4L2_STD_SECAM) { | ||
| 755 | pms_framerate(dev, 25); | ||
| 756 | pms_secamcross(dev, 1); | ||
| 757 | pms_format(dev, 2); | ||
| 758 | } else { | ||
| 759 | ret = -EINVAL; | ||
| 795 | } | 760 | } |
| 796 | case VIDIOCSWIN: { | 761 | /* |
| 797 | struct video_window *vw = arg; | 762 | switch (v->mode) { |
| 798 | 763 | case VIDEO_MODE_AUTO: | |
| 799 | if (vw->flags) | 764 | pms_framerate(dev, 25); |
| 800 | return -EINVAL; | 765 | pms_secamcross(dev, 0); |
| 801 | if (vw->clipcount) | 766 | pms_format(dev, 0); |
| 802 | return -EINVAL; | 767 | break; |
| 803 | if (vw->height < 16 || vw->height > 480) | 768 | }*/ |
| 804 | return -EINVAL; | 769 | mutex_unlock(&dev->lock); |
| 805 | if (vw->width < 16 || vw->width > 640) | 770 | return 0; |
| 806 | return -EINVAL; | 771 | } |
| 807 | dev->width = vw->width; | 772 | |
| 808 | dev->height = vw->height; | 773 | static int pms_queryctrl(struct file *file, void *priv, |
| 809 | mutex_lock(&dev->lock); | 774 | struct v4l2_queryctrl *qc) |
| 810 | pms_resolution(dev, dev->width, dev->height); | 775 | { |
| 811 | /* Ok we figured out what to use from our wide choice */ | 776 | switch (qc->id) { |
| 812 | mutex_unlock(&dev->lock); | 777 | case V4L2_CID_BRIGHTNESS: |
| 813 | return 0; | 778 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139); |
| 779 | case V4L2_CID_CONTRAST: | ||
| 780 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70); | ||
| 781 | case V4L2_CID_SATURATION: | ||
| 782 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64); | ||
| 783 | case V4L2_CID_HUE: | ||
| 784 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0); | ||
| 814 | } | 785 | } |
| 815 | case VIDIOCGWIN: { | 786 | return -EINVAL; |
| 816 | struct video_window *vw = arg; | 787 | } |
| 817 | 788 | ||
| 818 | memset(vw, 0, sizeof(*vw)); | 789 | static int pms_g_ctrl(struct file *file, void *priv, |
| 819 | vw->width = dev->width; | 790 | struct v4l2_control *ctrl) |
| 820 | vw->height = dev->height; | 791 | { |
| 821 | return 0; | 792 | struct pms *dev = video_drvdata(file); |
| 793 | int ret = 0; | ||
| 794 | |||
| 795 | switch (ctrl->id) { | ||
| 796 | case V4L2_CID_BRIGHTNESS: | ||
| 797 | ctrl->value = dev->brightness; | ||
| 798 | break; | ||
| 799 | case V4L2_CID_CONTRAST: | ||
| 800 | ctrl->value = dev->contrast; | ||
| 801 | break; | ||
| 802 | case V4L2_CID_SATURATION: | ||
| 803 | ctrl->value = dev->saturation; | ||
| 804 | break; | ||
| 805 | case V4L2_CID_HUE: | ||
| 806 | ctrl->value = dev->hue; | ||
| 807 | break; | ||
| 808 | default: | ||
| 809 | ret = -EINVAL; | ||
| 810 | break; | ||
| 822 | } | 811 | } |
| 823 | case VIDIOCKEY: | 812 | return ret; |
| 824 | return 0; | 813 | } |
| 825 | case VIDIOCCAPTURE: | 814 | |
| 826 | case VIDIOCGFBUF: | 815 | static int pms_s_ctrl(struct file *file, void *priv, |
| 827 | case VIDIOCSFBUF: | 816 | struct v4l2_control *ctrl) |
| 828 | case VIDIOCGFREQ: | 817 | { |
| 829 | case VIDIOCSFREQ: | 818 | struct pms *dev = video_drvdata(file); |
| 830 | case VIDIOCGAUDIO: | 819 | int ret = 0; |
| 831 | case VIDIOCSAUDIO: | 820 | |
| 832 | return -EINVAL; | 821 | mutex_lock(&dev->lock); |
| 822 | switch (ctrl->id) { | ||
| 823 | case V4L2_CID_BRIGHTNESS: | ||
| 824 | dev->brightness = ctrl->value; | ||
| 825 | pms_brightness(dev, dev->brightness); | ||
| 826 | break; | ||
| 827 | case V4L2_CID_CONTRAST: | ||
| 828 | dev->contrast = ctrl->value; | ||
| 829 | pms_contrast(dev, dev->contrast); | ||
| 830 | break; | ||
| 831 | case V4L2_CID_SATURATION: | ||
| 832 | dev->saturation = ctrl->value; | ||
| 833 | pms_saturation(dev, dev->saturation); | ||
| 834 | break; | ||
| 835 | case V4L2_CID_HUE: | ||
| 836 | dev->hue = ctrl->value; | ||
| 837 | pms_hue(dev, dev->hue); | ||
| 838 | break; | ||
| 833 | default: | 839 | default: |
| 834 | return -ENOIOCTLCMD; | 840 | ret = -EINVAL; |
| 841 | break; | ||
| 835 | } | 842 | } |
| 843 | mutex_unlock(&dev->lock); | ||
| 844 | return ret; | ||
| 845 | } | ||
| 846 | |||
| 847 | static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
| 848 | { | ||
| 849 | struct pms *dev = video_drvdata(file); | ||
| 850 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
| 851 | |||
| 852 | pix->width = dev->width; | ||
| 853 | pix->height = dev->height; | ||
| 854 | pix->pixelformat = dev->width == 15 ? | ||
| 855 | V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565; | ||
| 856 | pix->field = V4L2_FIELD_NONE; | ||
| 857 | pix->bytesperline = 2 * dev->width; | ||
| 858 | pix->sizeimage = 2 * dev->width * dev->height; | ||
| 859 | /* Just a guess */ | ||
| 860 | pix->colorspace = V4L2_COLORSPACE_SRGB; | ||
| 861 | return 0; | ||
| 862 | } | ||
| 863 | |||
| 864 | static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
| 865 | { | ||
| 866 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
| 867 | |||
| 868 | if (pix->height < 16 || pix->height > 480) | ||
| 869 | return -EINVAL; | ||
| 870 | if (pix->width < 16 || pix->width > 640) | ||
| 871 | return -EINVAL; | ||
| 872 | if (pix->pixelformat != V4L2_PIX_FMT_RGB555 && | ||
| 873 | pix->pixelformat != V4L2_PIX_FMT_RGB565) | ||
| 874 | return -EINVAL; | ||
| 875 | pix->field = V4L2_FIELD_NONE; | ||
| 876 | pix->bytesperline = 2 * pix->width; | ||
| 877 | pix->sizeimage = 2 * pix->width * pix->height; | ||
| 878 | /* Just a guess */ | ||
| 879 | pix->colorspace = V4L2_COLORSPACE_SRGB; | ||
| 836 | return 0; | 880 | return 0; |
| 837 | } | 881 | } |
| 838 | 882 | ||
| 839 | static long pms_ioctl(struct file *file, | 883 | static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
| 840 | unsigned int cmd, unsigned long arg) | ||
| 841 | { | 884 | { |
| 842 | return video_usercopy(file, cmd, arg, pms_do_ioctl); | 885 | struct pms *dev = video_drvdata(file); |
| 886 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
| 887 | int ret = pms_try_fmt_vid_cap(file, fh, fmt); | ||
| 888 | |||
| 889 | if (ret) | ||
| 890 | return ret; | ||
| 891 | mutex_lock(&dev->lock); | ||
| 892 | dev->width = pix->width; | ||
| 893 | dev->height = pix->height; | ||
| 894 | dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16; | ||
| 895 | pms_resolution(dev, dev->width, dev->height); | ||
| 896 | /* Ok we figured out what to use from our wide choice */ | ||
| 897 | mutex_unlock(&dev->lock); | ||
| 898 | return 0; | ||
| 899 | } | ||
| 900 | |||
| 901 | static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) | ||
| 902 | { | ||
| 903 | static struct v4l2_fmtdesc formats[] = { | ||
| 904 | { 0, 0, 0, | ||
| 905 | "RGB 5:5:5", V4L2_PIX_FMT_RGB555, | ||
| 906 | { 0, 0, 0, 0 } | ||
| 907 | }, | ||
| 908 | { 0, 0, 0, | ||
| 909 | "RGB 5:6:5", V4L2_PIX_FMT_RGB565, | ||
| 910 | { 0, 0, 0, 0 } | ||
| 911 | }, | ||
| 912 | }; | ||
| 913 | enum v4l2_buf_type type = fmt->type; | ||
| 914 | |||
| 915 | if (fmt->index > 1) | ||
| 916 | return -EINVAL; | ||
| 917 | |||
| 918 | *fmt = formats[fmt->index]; | ||
| 919 | fmt->type = type; | ||
| 920 | return 0; | ||
| 843 | } | 921 | } |
| 844 | 922 | ||
| 845 | static ssize_t pms_read(struct file *file, char __user *buf, | 923 | static ssize_t pms_read(struct file *file, char __user *buf, |
| @@ -849,7 +927,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
| 849 | int len; | 927 | int len; |
| 850 | 928 | ||
| 851 | mutex_lock(&dev->lock); | 929 | mutex_lock(&dev->lock); |
| 852 | len = pms_capture(dev, buf, (dev->picture.depth == 16) ? 0 : 1, count); | 930 | len = pms_capture(dev, buf, (dev->depth == 15), count); |
| 853 | mutex_unlock(&dev->lock); | 931 | mutex_unlock(&dev->lock); |
| 854 | return len; | 932 | return len; |
| 855 | } | 933 | } |
| @@ -873,10 +951,25 @@ static const struct v4l2_file_operations pms_fops = { | |||
| 873 | .owner = THIS_MODULE, | 951 | .owner = THIS_MODULE, |
| 874 | .open = pms_exclusive_open, | 952 | .open = pms_exclusive_open, |
| 875 | .release = pms_exclusive_release, | 953 | .release = pms_exclusive_release, |
| 876 | .ioctl = pms_ioctl, | 954 | .ioctl = video_ioctl2, |
| 877 | .read = pms_read, | 955 | .read = pms_read, |
| 878 | }; | 956 | }; |
| 879 | 957 | ||
| 958 | static const struct v4l2_ioctl_ops pms_ioctl_ops = { | ||
| 959 | .vidioc_querycap = pms_querycap, | ||
| 960 | .vidioc_g_input = pms_g_input, | ||
| 961 | .vidioc_s_input = pms_s_input, | ||
| 962 | .vidioc_enum_input = pms_enum_input, | ||
| 963 | .vidioc_g_std = pms_g_std, | ||
| 964 | .vidioc_s_std = pms_s_std, | ||
| 965 | .vidioc_queryctrl = pms_queryctrl, | ||
| 966 | .vidioc_g_ctrl = pms_g_ctrl, | ||
| 967 | .vidioc_s_ctrl = pms_s_ctrl, | ||
| 968 | .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap, | ||
| 969 | .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap, | ||
| 970 | .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap, | ||
| 971 | .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap, | ||
| 972 | }; | ||
| 880 | 973 | ||
| 881 | /* | 974 | /* |
| 882 | * Probe for and initialise the Mediavision PMS | 975 | * Probe for and initialise the Mediavision PMS |
| @@ -1032,11 +1125,18 @@ static int __init pms_init(void) | |||
| 1032 | strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); | 1125 | strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); |
| 1033 | dev->vdev.v4l2_dev = v4l2_dev; | 1126 | dev->vdev.v4l2_dev = v4l2_dev; |
| 1034 | dev->vdev.fops = &pms_fops; | 1127 | dev->vdev.fops = &pms_fops; |
| 1128 | dev->vdev.ioctl_ops = &pms_ioctl_ops; | ||
| 1035 | dev->vdev.release = video_device_release_empty; | 1129 | dev->vdev.release = video_device_release_empty; |
| 1036 | video_set_drvdata(&dev->vdev, dev); | 1130 | video_set_drvdata(&dev->vdev, dev); |
| 1037 | mutex_init(&dev->lock); | 1131 | mutex_init(&dev->lock); |
| 1132 | dev->std = V4L2_STD_NTSC_M; | ||
| 1038 | dev->height = 240; | 1133 | dev->height = 240; |
| 1039 | dev->width = 320; | 1134 | dev->width = 320; |
| 1135 | dev->depth = 15; | ||
| 1136 | dev->brightness = 139; | ||
| 1137 | dev->contrast = 70; | ||
| 1138 | dev->hue = 0; | ||
| 1139 | dev->saturation = 64; | ||
| 1040 | pms_swsense(dev, 75); | 1140 | pms_swsense(dev, 75); |
| 1041 | pms_resolution(dev, 320, 240); | 1141 | pms_resolution(dev, 320, 240); |
| 1042 | pms_videosource(dev, 0); | 1142 | pms_videosource(dev, 0); |
