t613.c
来自「trident tm5600的linux驱动」· C语言 代码 · 共 1,192 行 · 第 1/3 页
C
1,192 行
0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9, 0xa0, 0xff}, {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */ 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6, 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3, 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa, 0xa0, 0xff}, {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */ 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8, 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed, 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc, 0xa0, 0xff}};static const __u8 tas5130a_sensor_init[][8] = { {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, {},};static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};/* read 1 byte */static int reg_r(struct gspca_dev *gspca_dev, __u16 index){ usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, 1, 500); return gspca_dev->usb_buf[0];}static void reg_w(struct gspca_dev *gspca_dev, __u16 index){ usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, NULL, 0, 500);}static void reg_w_buf(struct gspca_dev *gspca_dev, const __u8 *buffer, __u16 len){ if (len <= USB_BUF_SZ) { memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x01, 0, gspca_dev->usb_buf, len, 500); } else { __u8 *tmpbuf; tmpbuf = kmalloc(len, GFP_KERNEL); memcpy(tmpbuf, buffer, len); usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x01, 0, tmpbuf, len, 500); kfree(tmpbuf); }}/* Reported as OM6802*/static void om6802_sensor_init(struct gspca_dev *gspca_dev){ int i; const __u8 *p; __u8 byte; __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; static const __u8 sensor_init[] = { 0xdf, 0x6d, 0xdd, 0x18, 0x5a, 0xe0, 0x5c, 0x07, 0x5d, 0xb0, 0x5e, 0x1e, 0x60, 0x71, 0xef, 0x00, 0xe9, 0x00, 0xea, 0x00, 0x90, 0x24, 0x91, 0xb2, 0x82, 0x32, 0xfd, 0x41, 0x00 /* table end */ }; reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); msleep(5); i = 4; while (--i < 0) { byte = reg_r(gspca_dev, 0x0060); if (!(byte & 0x01)) break; msleep(100); } byte = reg_r(gspca_dev, 0x0063); if (byte != 0x17) { err("Bad sensor reset %02x", byte); /* continue? */ } p = sensor_init; while (*p != 0) { val[1] = *p++; val[3] = *p++; if (*p == 0) reg_w(gspca_dev, 0x3c80); reg_w_buf(gspca_dev, val, sizeof val); i = 4; while (--i >= 0) { msleep(15); byte = reg_r(gspca_dev, 0x60); if (!(byte & 0x01)) break; } } msleep(15); reg_w(gspca_dev, 0x3c80);}/* this function is called at probe time */static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id){ struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; cam = &gspca_dev->cam; cam->epaddr = 0x01; cam->cam_mode = vga_mode_t16; cam->nmodes = ARRAY_SIZE(vga_mode_t16); sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; sd->gamma = GAMMA_DEF; sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value; return 0;}static void setbrightness(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; unsigned int brightness; __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; brightness = sd->brightness; if (brightness < 7) { set6[1] = 0x26; set6[3] = 0x70 - brightness * 0x10; } else { set6[3] = 0x00 + ((brightness - 7) * 0x10); } reg_w_buf(gspca_dev, set6, sizeof set6);}static void setcontrast(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; unsigned int contrast = sd->contrast; __u16 reg_to_write; if (contrast < 7) reg_to_write = 0x8ea9 - contrast * 0x200; else reg_to_write = 0x00a9 + (contrast - 7) * 0x200; reg_w(gspca_dev, reg_to_write);}static void setcolors(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; __u16 reg_to_write; reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */ reg_w(gspca_dev, reg_to_write);}static void setgamma(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; PDEBUG(D_CONF, "Gamma: %d", sd->gamma); reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);}static void setwhitebalance(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; __u8 white_balance[8] = {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38}; if (sd->whitebalance) white_balance[7] = 0x3c; reg_w_buf(gspca_dev, white_balance, sizeof white_balance);}static void setsharpness(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; __u16 reg_to_write; reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; reg_w(gspca_dev, reg_to_write);}/* this function is called at probe and resume time */static int sd_init(struct gspca_dev *gspca_dev){ /* some of this registers are not really neded, because * they are overriden by setbrigthness, setcontrast, etc, * but wont hurt anyway, and can help someone with similar webcam * to see the initial parameters.*/ struct sd *sd = (struct sd *) gspca_dev; int i; __u8 byte, test_byte; static const __u8 read_indexs[] = { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; static const __u8 n1[] = {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; static const __u8 n2[] = {0x08, 0x00}; static const __u8 n3[] = {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; static const __u8 n4[] = {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8, 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48, 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0, 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; static const __u8 nset9[4] = { 0x0b, 0x04, 0x0a, 0x78 }; static const __u8 nset8[6] = { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; byte = reg_r(gspca_dev, 0x06); test_byte = reg_r(gspca_dev, 0x07); if (byte == 0x08 && test_byte == 0x07) { PDEBUG(D_CONF, "sensor om6802"); sd->sensor = SENSOR_OM6802; } else if (byte == 0x08 && test_byte == 0x01) { PDEBUG(D_CONF, "sensor tas5130a"); sd->sensor = SENSOR_TAS5130A; } else { PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte); sd->sensor = SENSOR_TAS5130A; } reg_w_buf(gspca_dev, n1, sizeof n1); test_byte = 0; i = 5; while (--i >= 0) { reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); test_byte = reg_r(gspca_dev, 0x0063); msleep(100); if (test_byte == 0x17) break; /* OK */ } if (i < 0) { err("Bad sensor reset %02x", test_byte);/* return -EIO; *//*fixme: test - continue */ } reg_w_buf(gspca_dev, n2, sizeof n2); i = 0; while (read_indexs[i] != 0x00) { test_byte = reg_r(gspca_dev, read_indexs[i]); PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i], test_byte); i++; } reg_w_buf(gspca_dev, n3, sizeof n3); reg_w_buf(gspca_dev, n4, sizeof n4); reg_r(gspca_dev, 0x0080); reg_w(gspca_dev, 0x2c80); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, sizeof sensor_data[sd->sensor].data3); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, sizeof sensor_data[sd->sensor].data2); reg_w(gspca_dev, 0x3880); reg_w(gspca_dev, 0x3880); reg_w(gspca_dev, 0x338e); setbrightness(gspca_dev); setcontrast(gspca_dev); setgamma(gspca_dev); setcolors(gspca_dev); setsharpness(gspca_dev); setwhitebalance(gspca_dev); reg_w(gspca_dev, 0x2087); /* tied to white balance? */ reg_w(gspca_dev, 0x2088); reg_w(gspca_dev, 0x2089); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, sizeof sensor_data[sd->sensor].data4); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, sizeof sensor_data[sd->sensor].data5); reg_w_buf(gspca_dev, nset8, sizeof nset8); reg_w_buf(gspca_dev, nset9, sizeof nset9); reg_w(gspca_dev, 0x2880); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, sizeof sensor_data[sd->sensor].data3); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, sizeof sensor_data[sd->sensor].data2); return 0;}static void setflip(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; __u8 flipcmd[8] = {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; if (sd->mirror) flipcmd[3] = 0x01; reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);}static void seteffect(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; reg_w_buf(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]); if (sd->effect == 1 || sd->effect == 5) { PDEBUG(D_CONF, "This effect have been disabled for webcam \"safety\""); return; } if (sd->effect == 1 || sd->effect == 4) reg_w(gspca_dev, 0x4aa6); else reg_w(gspca_dev, 0xfaa6);}static void setlightfreq(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; if (sd->freq == 2) /* 60hz */ freq[1] = 0x00; reg_w_buf(gspca_dev, freq, sizeof freq);}/* Is this really needed? * i added some module parameters for test with some users */static void poll_sensor(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; static const __u8 poll1[] = {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?