📄 sunplus.c
字号:
/* * Sunplus spca504(abc) spca533 spca536 library * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr * * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#define MODULE_NAME "sunplus"#include "gspca.h"#include "jpeg.h"MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");MODULE_LICENSE("GPL");/* specific webcam descriptor */struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ __u8 packet[ISO_MAX_SIZE + 128]; /* !! no more than 128 ff in an ISO packet */ unsigned char brightness; unsigned char contrast; unsigned char colors; unsigned char autogain; char qindex; char bridge;#define BRIDGE_SPCA504 0#define BRIDGE_SPCA504B 1#define BRIDGE_SPCA504C 2#define BRIDGE_SPCA533 3#define BRIDGE_SPCA536 4 char subtype;#define AiptekMiniPenCam13 1#define LogitechClickSmart420 2#define LogitechClickSmart820 3#define MegapixV4 4};/* V4L2 controls supported by the driver */static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);static struct ctrl sd_ctrls[] = {#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, .maximum = 0xff, .step = 1, .default_value = 0, }, .set = sd_setbrightness, .get = sd_getbrightness, },#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, .maximum = 0xff, .step = 1, .default_value = 0x20, }, .set = sd_setcontrast, .get = sd_getcontrast, },#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Color", .minimum = 0, .maximum = 0xff, .step = 1, .default_value = 0x1a, }, .set = sd_setcolors, .get = sd_getcolors, },#define SD_AUTOGAIN 3 { { .id = V4L2_CID_AUTOGAIN, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Auto Gain", .minimum = 0, .maximum = 1, .step = 1, .default_value = 1, }, .set = sd_setautogain, .get = sd_getautogain, },};static struct v4l2_pix_format vga_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 2}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 640, .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1},};static struct v4l2_pix_format custom_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 2}, {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 464, .sizeimage = 464 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1},};static struct v4l2_pix_format vga_mode2[] = { {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 4}, {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 3}, {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352, .sizeimage = 352 * 288 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 2}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 640, .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1},};#define SPCA50X_OFFSET_DATA 10#define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3#define SPCA504_PCCAM600_OFFSET_COMPRESS 4#define SPCA504_PCCAM600_OFFSET_MODE 5#define SPCA504_PCCAM600_OFFSET_DATA 14 /* Frame packet header offsets for the spca533 */#define SPCA533_OFFSET_DATA 16#define SPCA533_OFFSET_FRAMSEQ 15/* Frame packet header offsets for the spca536 */#define SPCA536_OFFSET_DATA 4#define SPCA536_OFFSET_FRAMSEQ 1/* Initialisation data for the Creative PC-CAM 600 */static const __u16 spca504_pccam600_init_data[][3] = {/* {0xa0, 0x0000, 0x0503}, * capture mode */ {0x00, 0x0000, 0x2000}, {0x00, 0x0013, 0x2301}, {0x00, 0x0003, 0x2000}, {0x00, 0x0001, 0x21ac}, {0x00, 0x0001, 0x21a6}, {0x00, 0x0000, 0x21a7}, /* brightness */ {0x00, 0x0020, 0x21a8}, /* contrast */ {0x00, 0x0001, 0x21ac}, /* sat/hue */ {0x00, 0x0000, 0x21ad}, /* hue */ {0x00, 0x001a, 0x21ae}, /* saturation */ {0x00, 0x0002, 0x21a3}, /* gamma */#if 0 {0xb0, 0x0000, 0x0000}, /* reset auto exposure */ {0x0c, 0x0000, 0x0000}, /* reset auto whiteness */ {0x0c, 0x0004, 0x0000}, /* enable auto whiteness */ {0x30, 0x020f, 0x0001}, /* exposure compensation */ {0x30, 0x01f7, 0x0002}, /* whiteness balance */#endif {0x30, 0x0154, 0x0008}, {0x30, 0x0004, 0x0006}, {0x30, 0x0258, 0x0009}, {0x30, 0x0004, 0x0000}, {0x30, 0x0093, 0x0004}, {0x30, 0x0066, 0x0005}, {0x00, 0x0000, 0x2000}, {0x00, 0x0013, 0x2301}, {0x00, 0x0003, 0x2000}, {0x00, 0x0013, 0x2301}, {0x00, 0x0003, 0x2000}, {}};/* Creative PC-CAM 600 specific open data, sent before using the * generic initialisation data from spca504_open_data. */static const __u16 spca504_pccam600_open_data[][3] = { {0x00, 0x0001, 0x2501}, {0x20, 0x0500, 0x0001}, /* snapshot mode */ {0x00, 0x0003, 0x2880}, {0x00, 0x0001, 0x2881}, {}};/* Initialisation data for the logitech clicksmart 420 */static const __u16 spca504A_clicksmart420_init_data[][3] = {/* {0xa0, 0x0000, 0x0503}, * capture mode */ {0x00, 0x0000, 0x2000}, {0x00, 0x0013, 0x2301}, {0x00, 0x0003, 0x2000}, {0x00, 0x0001, 0x21ac}, {0x00, 0x0001, 0x21a6}, {0x00, 0x0000, 0x21a7}, /* brightness */ {0x00, 0x0020, 0x21a8}, /* contrast */ {0x00, 0x0001, 0x21ac}, /* sat/hue */ {0x00, 0x0000, 0x21ad}, /* hue */ {0x00, 0x001a, 0x21ae}, /* saturation */ {0x00, 0x0002, 0x21a3}, /* gamma */#if 1 {0x30, 0x0004, 0x000a}, {0xb0, 0x0001, 0x0000},#endif#if 0 {0xb0, 0x0000, 0x0000}, /* reset auto exposure */ {0x0c, 0x0000, 0x0000}, /* reset auto whiteness */ {0x0c, 0x0004, 0x0000}, /* enable auto whiteness */ {0x30, 0x020f, 0x0001}, /* exposure compensation */ {0x30, 0x01f7, 0x0002}, /* whiteness balance */#endif#if 1 {0x0a1, 0x0080, 0x0001}, {0x30, 0x0049, 0x0000}, {0x30, 0x0060, 0x0005}, {0x0c, 0x0004, 0x0000}, {0x00, 0x0000, 0x0000}, {0x00, 0x0000, 0x2000}, {0x00, 0x0013, 0x2301}, {0x00, 0x0003, 0x2000}, {0x00, 0x0000, 0x2000},#endif#if 0 {0x30, 0x0154, 0x0008}, {0x30, 0x0004, 0x0006}, {0x30, 0x0258, 0x0009}, {0x30, 0x0004, 0x0000}, {0x30, 0x0093, 0x0004}, {0x30, 0x0066, 0x0005}, {0x00, 0x0000, 0x2000}, {0x00, 0x0013, 0x2301}, {0x00, 0x0003, 0x2000}, {0x00, 0x0013, 0x2301}, {0x00, 0x0003, 0x2000},#endif {}};/* clicksmart 420 open data ? */static const __u16 spca504A_clicksmart420_open_data[][3] = { {0x00, 0x0001, 0x2501}, {0x20, 0x0502, 0x0000}, {0x06, 0x0000, 0x0000}, {0x00, 0x0004, 0x2880}, {0x00, 0x0001, 0x2881},/* look like setting a qTable */ {0x00, 0x0006, 0x2800}, {0x00, 0x0004, 0x2801}, {0x00, 0x0004, 0x2802}, {0x00, 0x0006, 0x2803}, {0x00, 0x000a, 0x2804}, {0x00, 0x0010, 0x2805}, {0x00, 0x0014, 0x2806}, {0x00, 0x0018, 0x2807}, {0x00, 0x0005, 0x2808}, {0x00, 0x0005, 0x2809}, {0x00, 0x0006, 0x280a}, {0x00, 0x0008, 0x280b}, {0x00, 0x000a, 0x280c}, {0x00, 0x0017, 0x280d}, {0x00, 0x0018, 0x280e}, {0x00, 0x0016, 0x280f}, {0x00, 0x0006, 0x2810}, {0x00, 0x0005, 0x2811}, {0x00, 0x0006, 0x2812}, {0x00, 0x000a, 0x2813}, {0x00, 0x0010, 0x2814}, {0x00, 0x0017, 0x2815}, {0x00, 0x001c, 0x2816}, {0x00, 0x0016, 0x2817}, {0x00, 0x0006, 0x2818}, {0x00, 0x0007, 0x2819}, {0x00, 0x0009, 0x281a}, {0x00, 0x000c, 0x281b}, {0x00, 0x0014, 0x281c}, {0x00, 0x0023, 0x281d}, {0x00, 0x0020, 0x281e}, {0x00, 0x0019, 0x281f}, {0x00, 0x0007, 0x2820}, {0x00, 0x0009, 0x2821}, {0x00, 0x000f, 0x2822}, {0x00, 0x0016, 0x2823}, {0x00, 0x001b, 0x2824}, {0x00, 0x002c, 0x2825}, {0x00, 0x0029, 0x2826}, {0x00, 0x001f, 0x2827}, {0x00, 0x000a, 0x2828}, {0x00, 0x000e, 0x2829}, {0x00, 0x0016, 0x282a}, {0x00, 0x001a, 0x282b}, {0x00, 0x0020, 0x282c}, {0x00, 0x002a, 0x282d}, {0x00, 0x002d, 0x282e}, {0x00, 0x0025, 0x282f}, {0x00, 0x0014, 0x2830}, {0x00, 0x001a, 0x2831}, {0x00, 0x001f, 0x2832}, {0x00, 0x0023, 0x2833}, {0x00, 0x0029, 0x2834}, {0x00, 0x0030, 0x2835}, {0x00, 0x0030, 0x2836}, {0x00, 0x0028, 0x2837}, {0x00, 0x001d, 0x2838}, {0x00, 0x0025, 0x2839}, {0x00, 0x0026, 0x283a}, {0x00, 0x0027, 0x283b}, {0x00, 0x002d, 0x283c}, {0x00, 0x0028, 0x283d}, {0x00, 0x0029, 0x283e}, {0x00, 0x0028, 0x283f}, {0x00, 0x0007, 0x2840}, {0x00, 0x0007, 0x2841}, {0x00, 0x000a, 0x2842}, {0x00, 0x0013, 0x2843}, {0x00, 0x0028, 0x2844}, {0x00, 0x0028, 0x2845}, {0x00, 0x0028, 0x2846}, {0x00, 0x0028, 0x2847}, {0x00, 0x0007, 0x2848}, {0x00, 0x0008, 0x2849}, {0x00, 0x000a, 0x284a}, {0x00, 0x001a, 0x284b}, {0x00, 0x0028, 0x284c}, {0x00, 0x0028, 0x284d}, {0x00, 0x0028, 0x284e}, {0x00, 0x0028, 0x284f}, {0x00, 0x000a, 0x2850}, {0x00, 0x000a, 0x2851}, {0x00, 0x0016, 0x2852}, {0x00, 0x0028, 0x2853}, {0x00, 0x0028, 0x2854}, {0x00, 0x0028, 0x2855}, {0x00, 0x0028, 0x2856}, {0x00, 0x0028, 0x2857}, {0x00, 0x0013, 0x2858}, {0x00, 0x001a, 0x2859}, {0x00, 0x0028, 0x285a}, {0x00, 0x0028, 0x285b}, {0x00, 0x0028, 0x285c}, {0x00, 0x0028, 0x285d}, {0x00, 0x0028, 0x285e}, {0x00, 0x0028, 0x285f}, {0x00, 0x0028, 0x2860}, {0x00, 0x0028, 0x2861}, {0x00, 0x0028, 0x2862}, {0x00, 0x0028, 0x2863}, {0x00, 0x0028, 0x2864}, {0x00, 0x0028, 0x2865}, {0x00, 0x0028, 0x2866}, {0x00, 0x0028, 0x2867}, {0x00, 0x0028, 0x2868}, {0x00, 0x0028, 0x2869}, {0x00, 0x0028, 0x286a}, {0x00, 0x0028, 0x286b}, {0x00, 0x0028, 0x286c}, {0x00, 0x0028, 0x286d}, {0x00, 0x0028, 0x286e}, {0x00, 0x0028, 0x286f}, {0x00, 0x0028, 0x2870}, {0x00, 0x0028, 0x2871}, {0x00, 0x0028, 0x2872}, {0x00, 0x0028, 0x2873}, {0x00, 0x0028, 0x2874}, {0x00, 0x0028, 0x2875}, {0x00, 0x0028, 0x2876}, {0x00, 0x0028, 0x2877}, {0x00, 0x0028, 0x2878}, {0x00, 0x0028, 0x2879}, {0x00, 0x0028, 0x287a}, {0x00, 0x0028, 0x287b}, {0x00, 0x0028, 0x287c}, {0x00, 0x0028, 0x287d}, {0x00, 0x0028, 0x287e}, {0x00, 0x0028, 0x287f}, {0xa0, 0x0000, 0x0503}, {}};static const __u8 qtable_creative_pccam[2][64] = { { /* Q-table Y-components */ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, { /* Q-table C-components */ 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}};/* FIXME: This Q-table is identical to the Creative PC-CAM one, * except for one byte. Possibly a typo? * NWG: 18/05/2003. */static const __u8 qtable_spca504_default[2][64] = { { /* Q-table Y-components */ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, 0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e, }, { /* Q-table C-components */ 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}};/* read <len> bytes to gspca_dev->usb_buf */static void reg_r(struct gspca_dev *gspca_dev, __u16 req, __u16 index, __u16 len){#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { err("reg_r: buffer overflow"); return; }#endif usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, len ? gspca_dev->usb_buf : NULL, len, 500);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -