00001 00034 #include <linux/module.h> 00035 #include <linux/init.h> 00036 #include <linux/kernel.h> 00037 #include <linux/version.h> 00038 #include <linux/errno.h> 00039 #include <linux/slab.h> 00040 #include <linux/kref.h> 00041 #include <linux/device.h> 00042 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) 00043 #include <linux/mm.h> 00044 #include <linux/videodev.h> 00045 #endif 00046 00047 00048 #include <linux/usb.h> 00049 #include <media/v4l2-common.h> 00050 00051 #include "stk11xx.h" 00052 00053 00054 extern const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES]; 00055 00056 00066 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00067 static ssize_t show_release(struct class_device *class, char *buf) 00068 #else 00069 static ssize_t show_release(struct device *class, struct device_attribute *attr, char *buf) 00070 #endif 00071 { 00072 struct video_device *vdev = to_video_device(class); 00073 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00074 00075 return sprintf(buf, "%d\n", dev->release); 00076 } 00077 00078 00088 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00089 static ssize_t show_videostatus(struct class_device *class, char *buf) 00090 #else 00091 static ssize_t show_videostatus(struct device *class, struct device_attribute *attr, char *buf) 00092 #endif 00093 { 00094 struct video_device *vdev = to_video_device(class); 00095 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00096 00097 return sprintf(buf, 00098 "Nbr ISOC errors : %d\n" 00099 "Nbr dropped frames : %d\n" 00100 "Nbr dumped frames : %d\n", 00101 dev->visoc_errors, 00102 dev->vframes_error, 00103 dev->vframes_dumped); 00104 } 00105 00106 00116 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00117 static ssize_t show_informations(struct class_device *class, char *buf) 00118 #else 00119 static ssize_t show_informations(struct device *class, struct device_attribute *attr, char *buf) 00120 #endif 00121 { 00122 int width, height; 00123 char *pixelfmt = NULL; 00124 00125 struct video_device *vdev = to_video_device(class); 00126 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00127 00128 char *palette_rgb24 = "RGB24 - RGB-8-8-8 - 24 bits"; 00129 char *palette_rgb32 = "RGB32 - RGB-8-8-8-8 - 32 bits"; 00130 char *palette_bgr24 = "BGR24 - BGR-8-8-8 - 24 bits"; 00131 char *palette_bgr32 = "BGR32 - BGR-8-8-8-8 - 32 bits"; 00132 char *palette_uyvy = "UYVY - YUV 4:2:2 - 16 bits"; 00133 char *palette_yuyv = "YUYV - YUV 4:2:2 - 16 bits"; 00134 00135 00136 switch (dev->vsettings.palette) { 00137 case STK11XX_PALETTE_RGB24: 00138 pixelfmt = palette_rgb24; 00139 break; 00140 00141 case STK11XX_PALETTE_RGB32: 00142 pixelfmt = palette_rgb32; 00143 break; 00144 00145 case STK11XX_PALETTE_BGR24: 00146 pixelfmt = palette_bgr24; 00147 break; 00148 00149 case STK11XX_PALETTE_BGR32: 00150 pixelfmt = palette_bgr32; 00151 break; 00152 00153 case STK11XX_PALETTE_UYVY: 00154 pixelfmt = palette_uyvy; 00155 break; 00156 00157 case STK11XX_PALETTE_YUYV: 00158 pixelfmt = palette_yuyv; 00159 break; 00160 } 00161 00162 switch (dev->resolution) { 00163 case STK11XX_80x60: 00164 case STK11XX_128x96: 00165 case STK11XX_160x120: 00166 case STK11XX_213x160: 00167 case STK11XX_320x240: 00168 case STK11XX_640x480: 00169 width = stk11xx_image_sizes[STK11XX_640x480].x; 00170 height = stk11xx_image_sizes[STK11XX_640x480].y; 00171 break; 00172 00173 case STK11XX_800x600: 00174 case STK11XX_1024x768: 00175 case STK11XX_1280x1024: 00176 width = stk11xx_image_sizes[STK11XX_1280x1024].x; 00177 height = stk11xx_image_sizes[STK11XX_1280x1024].y; 00178 break; 00179 00180 default: 00181 width = 0; 00182 height = 0; 00183 } 00184 00185 return sprintf(buf, 00186 "Asked resolution : %dx%d\n" 00187 "Driver resolution : %dx%d\n" 00188 "Webcam resolution : %dx%d\n" 00189 "\n" 00190 "%s\n" 00191 "\n" 00192 "Brightness : 0x%X\n" 00193 "Contrast : 0x%X\n" 00194 "Whiteness : 0x%X\n" 00195 "Colour : 0x%X\n", 00196 dev->view.x, dev->view.y, 00197 stk11xx_image_sizes[dev->resolution].x, stk11xx_image_sizes[dev->resolution].y, 00198 width, height, 00199 pixelfmt, 00200 0xFFFF & dev->vsettings.brightness, 00201 0xFFFF & dev->vsettings.contrast, 00202 0xFFFF & dev->vsettings.whiteness, 00203 0xFFFF & dev->vsettings.colour); 00204 } 00205 00206 00216 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00217 static ssize_t show_fps(struct class_device *class, char *buf) 00218 #else 00219 static ssize_t show_fps(struct device *class, struct device_attribute *attr, char *buf) 00220 #endif 00221 { 00222 struct video_device *vdev = to_video_device(class); 00223 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00224 00225 return sprintf(buf, "%d\n", dev->vsettings.fps); 00226 } 00227 00228 00238 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00239 static ssize_t show_brightness(struct class_device *class, char *buf) 00240 #else 00241 static ssize_t show_brightness(struct device *class, struct device_attribute *attr, char *buf) 00242 #endif 00243 { 00244 struct video_device *vdev = to_video_device(class); 00245 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00246 00247 return sprintf(buf, "%X\n", dev->vsettings.brightness); 00248 } 00249 00250 00260 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00261 static ssize_t store_brightness(struct class_device *class, const char *buf, size_t count) 00262 #else 00263 static ssize_t store_brightness(struct device *class, struct device_attribute *attr, 00264 const char *buf, size_t count) 00265 #endif 00266 { 00267 char *endp; 00268 unsigned long value; 00269 00270 struct video_device *vdev = to_video_device(class); 00271 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00272 00273 value = simple_strtoul(buf, &endp, 16); 00274 00275 dev->vsettings.brightness = (int) value; 00276 00277 dev_stk11xx_set_camera_quality(dev); 00278 00279 return strlen(buf); 00280 } 00281 00291 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00292 static ssize_t show_contrast(struct class_device *class, char *buf) 00293 #else 00294 static ssize_t show_contrast(struct device *class, struct device_attribute *attr, char *buf) 00295 #endif 00296 { 00297 struct video_device *vdev = to_video_device(class); 00298 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00299 00300 return sprintf(buf, "%X\n", dev->vsettings.contrast); 00301 } 00302 00303 00313 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00314 static ssize_t store_contrast(struct class_device *class, const char *buf, size_t count) 00315 #else 00316 static ssize_t store_contrast(struct device *class, struct device_attribute *attr, 00317 const char *buf, size_t count) 00318 #endif 00319 { 00320 char *endp; 00321 unsigned long value; 00322 00323 struct video_device *vdev = to_video_device(class); 00324 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00325 00326 value = simple_strtoul(buf, &endp, 16); 00327 00328 dev->vsettings.contrast = (int) value; 00329 00330 dev_stk11xx_set_camera_quality(dev); 00331 00332 return strlen(buf); 00333 } 00334 00335 00345 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00346 static ssize_t show_whitebalance(struct class_device *class, char *buf) 00347 #else 00348 static ssize_t show_whitebalance(struct device *class, struct device_attribute *attr, char *buf) 00349 #endif 00350 { 00351 struct video_device *vdev = to_video_device(class); 00352 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00353 00354 return sprintf(buf, "%X\n", dev->vsettings.whiteness); 00355 } 00356 00357 00367 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00368 static ssize_t store_whitebalance(struct class_device *class, const char *buf, size_t count) 00369 #else 00370 static ssize_t store_whitebalance(struct device *class, struct device_attribute *attr, 00371 const char *buf, size_t count) 00372 #endif 00373 { 00374 char *endp; 00375 unsigned long value; 00376 00377 struct video_device *vdev = to_video_device(class); 00378 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00379 00380 value = simple_strtoul(buf, &endp, 16); 00381 00382 dev->vsettings.whiteness = (int) value; 00383 00384 dev_stk11xx_set_camera_quality(dev); 00385 00386 return strlen(buf); 00387 } 00388 00389 00399 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00400 static ssize_t show_colour(struct class_device *class, char *buf) 00401 #else 00402 static ssize_t show_colour(struct device *class, struct device_attribute *attr, char *buf) 00403 #endif 00404 { 00405 struct video_device *vdev = to_video_device(class); 00406 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00407 00408 return sprintf(buf, "%X\n", dev->vsettings.colour); 00409 } 00410 00411 00421 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00422 static ssize_t store_colour(struct class_device *class, const char *buf, size_t count) 00423 #else 00424 static ssize_t store_colour(struct device *class, struct device_attribute *attr, 00425 const char *buf, size_t count) 00426 #endif 00427 { 00428 char *endp; 00429 unsigned long value; 00430 00431 struct video_device *vdev = to_video_device(class); 00432 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00433 00434 value = simple_strtoul(buf, &endp, 16); 00435 00436 dev->vsettings.colour = (int) value; 00437 00438 dev_stk11xx_set_camera_quality(dev); 00439 00440 return strlen(buf); 00441 } 00442 00443 00453 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00454 static ssize_t show_hflip(struct class_device *class, char *buf) 00455 #else 00456 static ssize_t show_hflip(struct device *class, struct device_attribute *attr, char *buf) 00457 #endif 00458 { 00459 struct video_device *vdev = to_video_device(class); 00460 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00461 00462 return sprintf(buf, "%d\n", dev->vsettings.hflip); 00463 } 00464 00465 00475 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00476 static ssize_t store_hflip(struct class_device *class, const char *buf, size_t count) 00477 #else 00478 static ssize_t store_hflip(struct device *class, struct device_attribute *attr, 00479 const char *buf, size_t count) 00480 #endif 00481 { 00482 struct video_device *vdev = to_video_device(class); 00483 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00484 00485 if (strncmp(buf, "1", 1) == 0) 00486 dev->vsettings.hflip = 1; 00487 else if (strncmp(buf, "0", 1) == 0) 00488 dev->vsettings.hflip = 0; 00489 else 00490 return -EINVAL; 00491 00492 return strlen(buf); 00493 } 00494 00495 00505 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00506 static ssize_t show_vflip(struct class_device *class, char *buf) 00507 #else 00508 static ssize_t show_vflip(struct device *class, struct device_attribute *attr, char *buf) 00509 #endif 00510 { 00511 struct video_device *vdev = to_video_device(class); 00512 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00513 00514 return sprintf(buf, "%d\n", dev->vsettings.vflip); 00515 } 00516 00517 00527 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00528 static ssize_t store_vflip(struct class_device *class, const char *buf, size_t count) 00529 #else 00530 static ssize_t store_vflip(struct device *class, struct device_attribute *attr, const char *buf, size_t count) 00531 #endif 00532 { 00533 struct video_device *vdev = to_video_device(class); 00534 struct usb_stk11xx *dev = video_get_drvdata(vdev); 00535 00536 if (strncmp(buf, "1", 1) == 0) 00537 dev->vsettings.vflip = 1; 00538 else if (strncmp(buf, "0", 1) == 0) 00539 dev->vsettings.vflip = 0; 00540 else 00541 return -EINVAL; 00542 00543 return strlen(buf); 00544 } 00545 00546 00547 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00548 static CLASS_DEVICE_ATTR(release, S_IRUGO, show_release, NULL); 00549 static CLASS_DEVICE_ATTR(videostatus, S_IRUGO, show_videostatus, NULL); 00550 static CLASS_DEVICE_ATTR(informations, S_IRUGO, show_informations, NULL); 00551 static CLASS_DEVICE_ATTR(fps, S_IRUGO, show_fps, NULL); 00552 static CLASS_DEVICE_ATTR(brightness, S_IRUGO | S_IWUGO, show_brightness, store_brightness); 00553 static CLASS_DEVICE_ATTR(contrast, S_IRUGO | S_IWUGO, show_contrast, store_contrast); 00554 static CLASS_DEVICE_ATTR(whitebalance, S_IRUGO | S_IWUGO, show_whitebalance, store_whitebalance); 00555 static CLASS_DEVICE_ATTR(colour, S_IRUGO | S_IWUGO, show_colour, store_colour); 00556 static CLASS_DEVICE_ATTR(hflip, S_IRUGO | S_IWUGO, show_hflip, store_hflip); 00557 static CLASS_DEVICE_ATTR(vflip, S_IRUGO | S_IWUGO, show_vflip, store_vflip); 00558 #else 00559 static DEVICE_ATTR(release, S_IRUGO, show_release, NULL); 00560 static DEVICE_ATTR(videostatus, S_IRUGO, show_videostatus, NULL); 00561 static DEVICE_ATTR(informations, S_IRUGO, show_informations, NULL); 00562 static DEVICE_ATTR(fps, S_IRUGO, show_fps, NULL); 00563 static DEVICE_ATTR(brightness, S_IRUGO | S_IWUGO, show_brightness, store_brightness); 00564 static DEVICE_ATTR(contrast, S_IRUGO | S_IWUGO, show_contrast, store_contrast); 00565 static DEVICE_ATTR(whitebalance, S_IRUGO | S_IWUGO, show_whitebalance, store_whitebalance); 00566 static DEVICE_ATTR(colour, S_IRUGO | S_IWUGO, show_colour, store_colour); 00567 static DEVICE_ATTR(hflip, S_IRUGO | S_IWUGO, show_hflip, store_hflip); 00568 static DEVICE_ATTR(vflip, S_IRUGO | S_IWUGO, show_vflip, store_vflip); 00569 #endif 00570 00571 00581 int stk11xx_create_sysfs_files(struct video_device *vdev) 00582 { 00583 int ret; 00584 00585 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00586 ret = video_device_create_file(vdev, &class_device_attr_release); 00587 ret = video_device_create_file(vdev, &class_device_attr_videostatus); 00588 ret = video_device_create_file(vdev, &class_device_attr_informations); 00589 ret = video_device_create_file(vdev, &class_device_attr_fps); 00590 ret = video_device_create_file(vdev, &class_device_attr_brightness); 00591 ret = video_device_create_file(vdev, &class_device_attr_contrast); 00592 ret = video_device_create_file(vdev, &class_device_attr_whitebalance); 00593 ret = video_device_create_file(vdev, &class_device_attr_colour); 00594 ret = video_device_create_file(vdev, &class_device_attr_hflip); 00595 ret = video_device_create_file(vdev, &class_device_attr_vflip); 00596 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 00597 ret = video_device_create_file(vdev, &dev_attr_release); 00598 ret = video_device_create_file(vdev, &dev_attr_videostatus); 00599 ret = video_device_create_file(vdev, &dev_attr_informations); 00600 ret = video_device_create_file(vdev, &dev_attr_fps); 00601 ret = video_device_create_file(vdev, &dev_attr_brightness); 00602 ret = video_device_create_file(vdev, &dev_attr_contrast); 00603 ret = video_device_create_file(vdev, &dev_attr_whitebalance); 00604 ret = video_device_create_file(vdev, &dev_attr_colour); 00605 ret = video_device_create_file(vdev, &dev_attr_hflip); 00606 ret = video_device_create_file(vdev, &dev_attr_vflip); 00607 #else 00608 ret = device_create_file(&vdev->dev, &dev_attr_release); 00609 ret = device_create_file(&vdev->dev, &dev_attr_videostatus); 00610 ret = device_create_file(&vdev->dev, &dev_attr_informations); 00611 ret = device_create_file(&vdev->dev, &dev_attr_fps); 00612 ret = device_create_file(&vdev->dev, &dev_attr_brightness); 00613 ret = device_create_file(&vdev->dev, &dev_attr_contrast); 00614 ret = device_create_file(&vdev->dev, &dev_attr_whitebalance); 00615 ret = device_create_file(&vdev->dev, &dev_attr_colour); 00616 ret = device_create_file(&vdev->dev, &dev_attr_hflip); 00617 ret = device_create_file(&vdev->dev, &dev_attr_vflip); 00618 #endif 00619 00620 00621 return ret; 00622 } 00623 00624 00634 void stk11xx_remove_sysfs_files(struct video_device *vdev) 00635 { 00636 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 00637 video_device_remove_file(vdev, &class_device_attr_release); 00638 video_device_remove_file(vdev, &class_device_attr_videostatus); 00639 video_device_remove_file(vdev, &class_device_attr_informations); 00640 video_device_remove_file(vdev, &class_device_attr_fps); 00641 video_device_remove_file(vdev, &class_device_attr_brightness); 00642 video_device_remove_file(vdev, &class_device_attr_contrast); 00643 video_device_remove_file(vdev, &class_device_attr_whitebalance); 00644 video_device_remove_file(vdev, &class_device_attr_colour); 00645 video_device_remove_file(vdev, &class_device_attr_hflip); 00646 video_device_remove_file(vdev, &class_device_attr_vflip); 00647 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 00648 video_device_remove_file(vdev, &dev_attr_release); 00649 video_device_remove_file(vdev, &dev_attr_videostatus); 00650 video_device_remove_file(vdev, &dev_attr_informations); 00651 video_device_remove_file(vdev, &dev_attr_fps); 00652 video_device_remove_file(vdev, &dev_attr_brightness); 00653 video_device_remove_file(vdev, &dev_attr_contrast); 00654 video_device_remove_file(vdev, &dev_attr_whitebalance); 00655 video_device_remove_file(vdev, &dev_attr_colour); 00656 video_device_remove_file(vdev, &dev_attr_hflip); 00657 video_device_remove_file(vdev, &dev_attr_vflip); 00658 #else 00659 device_remove_file(&vdev->dev, &dev_attr_release); 00660 device_remove_file(&vdev->dev, &dev_attr_videostatus); 00661 device_remove_file(&vdev->dev, &dev_attr_informations); 00662 device_remove_file(&vdev->dev, &dev_attr_fps); 00663 device_remove_file(&vdev->dev, &dev_attr_brightness); 00664 device_remove_file(&vdev->dev, &dev_attr_contrast); 00665 device_remove_file(&vdev->dev, &dev_attr_whitebalance); 00666 device_remove_file(&vdev->dev, &dev_attr_colour); 00667 device_remove_file(&vdev->dev, &dev_attr_hflip); 00668 device_remove_file(&vdev->dev, &dev_attr_vflip); 00669 #endif 00670 00671 } 00672