diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-06 09:41:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 11:47:36 -0400 |
commit | 4b25524c7b329f6d7a3f6d14b0f036fd6091def2 (patch) | |
tree | 30b2e770c55661586a423a12313e18ddd7b3d717 | |
parent | 5be4fe633a5ddc268afe71257e82a64773ea2f9d (diff) |
[media] pms: update to the latest V4L2 frameworks
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/pms.c | 237 |
1 files changed, 123 insertions, 114 deletions
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index e753b5e4d2ce..8b80f9808911 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
@@ -30,15 +30,19 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
33 | #include <linux/isa.h> | ||
33 | #include <asm/io.h> | 34 | #include <asm/io.h> |
34 | 35 | ||
35 | #include <linux/videodev2.h> | 36 | #include <linux/videodev2.h> |
36 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
37 | #include <media/v4l2-ioctl.h> | 38 | #include <media/v4l2-ioctl.h> |
39 | #include <media/v4l2-ctrls.h> | ||
40 | #include <media/v4l2-fh.h> | ||
41 | #include <media/v4l2-event.h> | ||
38 | #include <media/v4l2-device.h> | 42 | #include <media/v4l2-device.h> |
39 | 43 | ||
40 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
41 | MODULE_VERSION("0.0.4"); | 45 | MODULE_VERSION("0.0.5"); |
42 | 46 | ||
43 | #define MOTOROLA 1 | 47 | #define MOTOROLA 1 |
44 | #define PHILIPS2 2 /* SAA7191 */ | 48 | #define PHILIPS2 2 /* SAA7191 */ |
@@ -55,11 +59,11 @@ struct i2c_info { | |||
55 | struct pms { | 59 | struct pms { |
56 | struct v4l2_device v4l2_dev; | 60 | struct v4l2_device v4l2_dev; |
57 | struct video_device vdev; | 61 | struct video_device vdev; |
62 | struct v4l2_ctrl_handler hdl; | ||
58 | int height; | 63 | int height; |
59 | int width; | 64 | int width; |
60 | int depth; | 65 | int depth; |
61 | int input; | 66 | int input; |
62 | s32 brightness, saturation, hue, contrast; | ||
63 | struct mutex lock; | 67 | struct mutex lock; |
64 | int i2c_count; | 68 | int i2c_count; |
65 | struct i2c_info i2cinfo[64]; | 69 | struct i2c_info i2cinfo[64]; |
@@ -72,8 +76,6 @@ struct pms { | |||
72 | void __iomem *mem; | 76 | void __iomem *mem; |
73 | }; | 77 | }; |
74 | 78 | ||
75 | static struct pms pms_card; | ||
76 | |||
77 | /* | 79 | /* |
78 | * I/O ports and Shared Memory | 80 | * I/O ports and Shared Memory |
79 | */ | 81 | */ |
@@ -676,8 +678,10 @@ static int pms_querycap(struct file *file, void *priv, | |||
676 | 678 | ||
677 | strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver)); | 679 | strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver)); |
678 | strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card)); | 680 | strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card)); |
679 | strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info)); | 681 | snprintf(vcap->bus_info, sizeof(vcap->bus_info), |
680 | vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; | 682 | "ISA:%s", dev->v4l2_dev.name); |
683 | vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; | ||
684 | vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
681 | return 0; | 685 | return 0; |
682 | } | 686 | } |
683 | 687 | ||
@@ -716,11 +720,9 @@ static int pms_s_input(struct file *file, void *fh, unsigned int inp) | |||
716 | if (inp > 3) | 720 | if (inp > 3) |
717 | return -EINVAL; | 721 | return -EINVAL; |
718 | 722 | ||
719 | mutex_lock(&dev->lock); | ||
720 | dev->input = inp; | 723 | dev->input = inp; |
721 | pms_videosource(dev, inp & 1); | 724 | pms_videosource(dev, inp & 1); |
722 | pms_vcrinput(dev, inp >> 1); | 725 | pms_vcrinput(dev, inp >> 1); |
723 | mutex_unlock(&dev->lock); | ||
724 | return 0; | 726 | return 0; |
725 | } | 727 | } |
726 | 728 | ||
@@ -738,7 +740,6 @@ static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std) | |||
738 | int ret = 0; | 740 | int ret = 0; |
739 | 741 | ||
740 | dev->std = *std; | 742 | dev->std = *std; |
741 | mutex_lock(&dev->lock); | ||
742 | if (dev->std & V4L2_STD_NTSC) { | 743 | if (dev->std & V4L2_STD_NTSC) { |
743 | pms_framerate(dev, 30); | 744 | pms_framerate(dev, 30); |
744 | pms_secamcross(dev, 0); | 745 | pms_secamcross(dev, 0); |
@@ -762,81 +763,31 @@ static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std) | |||
762 | pms_format(dev, 0); | 763 | pms_format(dev, 0); |
763 | break; | 764 | break; |
764 | }*/ | 765 | }*/ |
765 | mutex_unlock(&dev->lock); | ||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | static int pms_queryctrl(struct file *file, void *priv, | ||
770 | struct v4l2_queryctrl *qc) | ||
771 | { | ||
772 | switch (qc->id) { | ||
773 | case V4L2_CID_BRIGHTNESS: | ||
774 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139); | ||
775 | case V4L2_CID_CONTRAST: | ||
776 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70); | ||
777 | case V4L2_CID_SATURATION: | ||
778 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64); | ||
779 | case V4L2_CID_HUE: | ||
780 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0); | ||
781 | } | ||
782 | return -EINVAL; | ||
783 | } | ||
784 | |||
785 | static int pms_g_ctrl(struct file *file, void *priv, | ||
786 | struct v4l2_control *ctrl) | ||
787 | { | ||
788 | struct pms *dev = video_drvdata(file); | ||
789 | int ret = 0; | ||
790 | |||
791 | switch (ctrl->id) { | ||
792 | case V4L2_CID_BRIGHTNESS: | ||
793 | ctrl->value = dev->brightness; | ||
794 | break; | ||
795 | case V4L2_CID_CONTRAST: | ||
796 | ctrl->value = dev->contrast; | ||
797 | break; | ||
798 | case V4L2_CID_SATURATION: | ||
799 | ctrl->value = dev->saturation; | ||
800 | break; | ||
801 | case V4L2_CID_HUE: | ||
802 | ctrl->value = dev->hue; | ||
803 | break; | ||
804 | default: | ||
805 | ret = -EINVAL; | ||
806 | break; | ||
807 | } | ||
808 | return ret; | 766 | return ret; |
809 | } | 767 | } |
810 | 768 | ||
811 | static int pms_s_ctrl(struct file *file, void *priv, | 769 | static int pms_s_ctrl(struct v4l2_ctrl *ctrl) |
812 | struct v4l2_control *ctrl) | ||
813 | { | 770 | { |
814 | struct pms *dev = video_drvdata(file); | 771 | struct pms *dev = container_of(ctrl->handler, struct pms, hdl); |
815 | int ret = 0; | 772 | int ret = 0; |
816 | 773 | ||
817 | mutex_lock(&dev->lock); | ||
818 | switch (ctrl->id) { | 774 | switch (ctrl->id) { |
819 | case V4L2_CID_BRIGHTNESS: | 775 | case V4L2_CID_BRIGHTNESS: |
820 | dev->brightness = ctrl->value; | 776 | pms_brightness(dev, ctrl->val); |
821 | pms_brightness(dev, dev->brightness); | ||
822 | break; | 777 | break; |
823 | case V4L2_CID_CONTRAST: | 778 | case V4L2_CID_CONTRAST: |
824 | dev->contrast = ctrl->value; | 779 | pms_contrast(dev, ctrl->val); |
825 | pms_contrast(dev, dev->contrast); | ||
826 | break; | 780 | break; |
827 | case V4L2_CID_SATURATION: | 781 | case V4L2_CID_SATURATION: |
828 | dev->saturation = ctrl->value; | 782 | pms_saturation(dev, ctrl->val); |
829 | pms_saturation(dev, dev->saturation); | ||
830 | break; | 783 | break; |
831 | case V4L2_CID_HUE: | 784 | case V4L2_CID_HUE: |
832 | dev->hue = ctrl->value; | 785 | pms_hue(dev, ctrl->val); |
833 | pms_hue(dev, dev->hue); | ||
834 | break; | 786 | break; |
835 | default: | 787 | default: |
836 | ret = -EINVAL; | 788 | ret = -EINVAL; |
837 | break; | 789 | break; |
838 | } | 790 | } |
839 | mutex_unlock(&dev->lock); | ||
840 | return ret; | 791 | return ret; |
841 | } | 792 | } |
842 | 793 | ||
@@ -884,13 +835,11 @@ static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fm | |||
884 | 835 | ||
885 | if (ret) | 836 | if (ret) |
886 | return ret; | 837 | return ret; |
887 | mutex_lock(&dev->lock); | ||
888 | dev->width = pix->width; | 838 | dev->width = pix->width; |
889 | dev->height = pix->height; | 839 | dev->height = pix->height; |
890 | dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16; | 840 | dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16; |
891 | pms_resolution(dev, dev->width, dev->height); | 841 | pms_resolution(dev, dev->width, dev->height); |
892 | /* Ok we figured out what to use from our wide choice */ | 842 | /* Ok we figured out what to use from our wide choice */ |
893 | mutex_unlock(&dev->lock); | ||
894 | return 0; | 843 | return 0; |
895 | } | 844 | } |
896 | 845 | ||
@@ -901,7 +850,7 @@ static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc | |||
901 | "RGB 5:5:5", V4L2_PIX_FMT_RGB555, | 850 | "RGB 5:5:5", V4L2_PIX_FMT_RGB555, |
902 | { 0, 0, 0, 0 } | 851 | { 0, 0, 0, 0 } |
903 | }, | 852 | }, |
904 | { 0, 0, 0, | 853 | { 1, 0, 0, |
905 | "RGB 5:6:5", V4L2_PIX_FMT_RGB565, | 854 | "RGB 5:6:5", V4L2_PIX_FMT_RGB565, |
906 | { 0, 0, 0, 0 } | 855 | { 0, 0, 0, 0 } |
907 | }, | 856 | }, |
@@ -922,32 +871,43 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
922 | struct pms *dev = video_drvdata(file); | 871 | struct pms *dev = video_drvdata(file); |
923 | int len; | 872 | int len; |
924 | 873 | ||
925 | mutex_lock(&dev->lock); | ||
926 | len = pms_capture(dev, buf, (dev->depth == 15), count); | 874 | len = pms_capture(dev, buf, (dev->depth == 15), count); |
927 | mutex_unlock(&dev->lock); | ||
928 | return len; | 875 | return len; |
929 | } | 876 | } |
930 | 877 | ||
878 | static unsigned int pms_poll(struct file *file, struct poll_table_struct *wait) | ||
879 | { | ||
880 | struct v4l2_fh *fh = file->private_data; | ||
881 | unsigned int res = POLLIN | POLLRDNORM; | ||
882 | |||
883 | if (v4l2_event_pending(fh)) | ||
884 | res |= POLLPRI; | ||
885 | poll_wait(file, &fh->wait, wait); | ||
886 | return res; | ||
887 | } | ||
888 | |||
931 | static const struct v4l2_file_operations pms_fops = { | 889 | static const struct v4l2_file_operations pms_fops = { |
932 | .owner = THIS_MODULE, | 890 | .owner = THIS_MODULE, |
891 | .open = v4l2_fh_open, | ||
892 | .release = v4l2_fh_release, | ||
893 | .poll = pms_poll, | ||
933 | .unlocked_ioctl = video_ioctl2, | 894 | .unlocked_ioctl = video_ioctl2, |
934 | .read = pms_read, | 895 | .read = pms_read, |
935 | }; | 896 | }; |
936 | 897 | ||
937 | static const struct v4l2_ioctl_ops pms_ioctl_ops = { | 898 | static const struct v4l2_ioctl_ops pms_ioctl_ops = { |
938 | .vidioc_querycap = pms_querycap, | 899 | .vidioc_querycap = pms_querycap, |
939 | .vidioc_g_input = pms_g_input, | 900 | .vidioc_g_input = pms_g_input, |
940 | .vidioc_s_input = pms_s_input, | 901 | .vidioc_s_input = pms_s_input, |
941 | .vidioc_enum_input = pms_enum_input, | 902 | .vidioc_enum_input = pms_enum_input, |
942 | .vidioc_g_std = pms_g_std, | 903 | .vidioc_g_std = pms_g_std, |
943 | .vidioc_s_std = pms_s_std, | 904 | .vidioc_s_std = pms_s_std, |
944 | .vidioc_queryctrl = pms_queryctrl, | 905 | .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap, |
945 | .vidioc_g_ctrl = pms_g_ctrl, | 906 | .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap, |
946 | .vidioc_s_ctrl = pms_s_ctrl, | 907 | .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap, |
947 | .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap, | 908 | .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap, |
948 | .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap, | 909 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, |
949 | .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap, | 910 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
950 | .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap, | ||
951 | }; | 911 | }; |
952 | 912 | ||
953 | /* | 913 | /* |
@@ -1068,76 +1028,125 @@ static int enable; | |||
1068 | module_param(enable, int, 0); | 1028 | module_param(enable, int, 0); |
1069 | #endif | 1029 | #endif |
1070 | 1030 | ||
1071 | static int __init pms_init(void) | 1031 | static const struct v4l2_ctrl_ops pms_ctrl_ops = { |
1032 | .s_ctrl = pms_s_ctrl, | ||
1033 | }; | ||
1034 | |||
1035 | static int pms_probe(struct device *pdev, unsigned int card) | ||
1072 | { | 1036 | { |
1073 | struct pms *dev = &pms_card; | 1037 | struct pms *dev; |
1074 | struct v4l2_device *v4l2_dev = &dev->v4l2_dev; | 1038 | struct v4l2_device *v4l2_dev; |
1039 | struct v4l2_ctrl_handler *hdl; | ||
1075 | int res; | 1040 | int res; |
1076 | 1041 | ||
1077 | strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name)); | ||
1078 | |||
1079 | v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n"); | ||
1080 | |||
1081 | #ifndef MODULE | 1042 | #ifndef MODULE |
1082 | if (!enable) { | 1043 | if (!enable) { |
1083 | v4l2_err(v4l2_dev, | 1044 | pr_err("PMS: not enabled, use pms.enable=1 to probe\n"); |
1084 | "PMS: not enabled, use pms.enable=1 to probe\n"); | ||
1085 | return -ENODEV; | 1045 | return -ENODEV; |
1086 | } | 1046 | } |
1087 | #endif | 1047 | #endif |
1088 | 1048 | ||
1049 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
1050 | if (dev == NULL) | ||
1051 | return -ENOMEM; | ||
1052 | |||
1089 | dev->decoder = PHILIPS2; | 1053 | dev->decoder = PHILIPS2; |
1090 | dev->io = io_port; | 1054 | dev->io = io_port; |
1091 | dev->data = io_port + 1; | 1055 | dev->data = io_port + 1; |
1056 | v4l2_dev = &dev->v4l2_dev; | ||
1057 | hdl = &dev->hdl; | ||
1092 | 1058 | ||
1093 | if (init_mediavision(dev)) { | 1059 | res = v4l2_device_register(pdev, v4l2_dev); |
1060 | if (res < 0) { | ||
1061 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); | ||
1062 | goto free_dev; | ||
1063 | } | ||
1064 | v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.05\n"); | ||
1065 | |||
1066 | res = init_mediavision(dev); | ||
1067 | if (res) { | ||
1094 | v4l2_err(v4l2_dev, "Board not found.\n"); | 1068 | v4l2_err(v4l2_dev, "Board not found.\n"); |
1095 | return -ENODEV; | 1069 | goto free_io; |
1096 | } | 1070 | } |
1097 | 1071 | ||
1098 | res = v4l2_device_register(NULL, v4l2_dev); | 1072 | v4l2_ctrl_handler_init(hdl, 4); |
1099 | if (res < 0) { | 1073 | v4l2_ctrl_new_std(hdl, &pms_ctrl_ops, |
1100 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); | 1074 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 139); |
1101 | return res; | 1075 | v4l2_ctrl_new_std(hdl, &pms_ctrl_ops, |
1076 | V4L2_CID_CONTRAST, 0, 255, 1, 70); | ||
1077 | v4l2_ctrl_new_std(hdl, &pms_ctrl_ops, | ||
1078 | V4L2_CID_SATURATION, 0, 255, 1, 64); | ||
1079 | v4l2_ctrl_new_std(hdl, &pms_ctrl_ops, | ||
1080 | V4L2_CID_HUE, 0, 255, 1, 0); | ||
1081 | if (hdl->error) { | ||
1082 | res = hdl->error; | ||
1083 | goto free_hdl; | ||
1102 | } | 1084 | } |
1103 | 1085 | ||
1086 | mutex_init(&dev->lock); | ||
1104 | strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); | 1087 | strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); |
1105 | dev->vdev.v4l2_dev = v4l2_dev; | 1088 | dev->vdev.v4l2_dev = v4l2_dev; |
1089 | dev->vdev.ctrl_handler = hdl; | ||
1106 | dev->vdev.fops = &pms_fops; | 1090 | dev->vdev.fops = &pms_fops; |
1107 | dev->vdev.ioctl_ops = &pms_ioctl_ops; | 1091 | dev->vdev.ioctl_ops = &pms_ioctl_ops; |
1108 | dev->vdev.release = video_device_release_empty; | 1092 | dev->vdev.release = video_device_release_empty; |
1093 | dev->vdev.lock = &dev->lock; | ||
1094 | dev->vdev.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; | ||
1095 | set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags); | ||
1109 | video_set_drvdata(&dev->vdev, dev); | 1096 | video_set_drvdata(&dev->vdev, dev); |
1110 | mutex_init(&dev->lock); | ||
1111 | dev->std = V4L2_STD_NTSC_M; | 1097 | dev->std = V4L2_STD_NTSC_M; |
1112 | dev->height = 240; | 1098 | dev->height = 240; |
1113 | dev->width = 320; | 1099 | dev->width = 320; |
1114 | dev->depth = 15; | 1100 | dev->depth = 16; |
1115 | dev->brightness = 139; | ||
1116 | dev->contrast = 70; | ||
1117 | dev->hue = 0; | ||
1118 | dev->saturation = 64; | ||
1119 | pms_swsense(dev, 75); | 1101 | pms_swsense(dev, 75); |
1120 | pms_resolution(dev, 320, 240); | 1102 | pms_resolution(dev, 320, 240); |
1121 | pms_videosource(dev, 0); | 1103 | pms_videosource(dev, 0); |
1122 | pms_vcrinput(dev, 0); | 1104 | pms_vcrinput(dev, 0); |
1123 | if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { | 1105 | v4l2_ctrl_handler_setup(hdl); |
1124 | v4l2_device_unregister(&dev->v4l2_dev); | 1106 | res = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr); |
1125 | release_region(dev->io, 3); | 1107 | if (res >= 0) |
1126 | release_region(0x9a01, 1); | 1108 | return 0; |
1127 | iounmap(dev->mem); | 1109 | |
1128 | return -EINVAL; | 1110 | free_hdl: |
1129 | } | 1111 | v4l2_ctrl_handler_free(hdl); |
1130 | return 0; | 1112 | v4l2_device_unregister(&dev->v4l2_dev); |
1113 | free_io: | ||
1114 | release_region(dev->io, 3); | ||
1115 | release_region(0x9a01, 1); | ||
1116 | iounmap(dev->mem); | ||
1117 | free_dev: | ||
1118 | kfree(dev); | ||
1119 | return res; | ||
1131 | } | 1120 | } |
1132 | 1121 | ||
1133 | static void __exit pms_exit(void) | 1122 | static int pms_remove(struct device *pdev, unsigned int card) |
1134 | { | 1123 | { |
1135 | struct pms *dev = &pms_card; | 1124 | struct pms *dev = dev_get_drvdata(pdev); |
1136 | 1125 | ||
1137 | video_unregister_device(&dev->vdev); | 1126 | video_unregister_device(&dev->vdev); |
1127 | v4l2_ctrl_handler_free(&dev->hdl); | ||
1138 | release_region(dev->io, 3); | 1128 | release_region(dev->io, 3); |
1139 | release_region(0x9a01, 1); | 1129 | release_region(0x9a01, 1); |
1140 | iounmap(dev->mem); | 1130 | iounmap(dev->mem); |
1131 | return 0; | ||
1132 | } | ||
1133 | |||
1134 | static struct isa_driver pms_driver = { | ||
1135 | .probe = pms_probe, | ||
1136 | .remove = pms_remove, | ||
1137 | .driver = { | ||
1138 | .name = "pms", | ||
1139 | }, | ||
1140 | }; | ||
1141 | |||
1142 | static int __init pms_init(void) | ||
1143 | { | ||
1144 | return isa_register_driver(&pms_driver, 1); | ||
1145 | } | ||
1146 | |||
1147 | static void __exit pms_exit(void) | ||
1148 | { | ||
1149 | isa_unregister_driver(&pms_driver); | ||
1141 | } | 1150 | } |
1142 | 1151 | ||
1143 | module_init(pms_init); | 1152 | module_init(pms_init); |