?? mr97311.h
字號(hào):
/****************************************************************************# Mars-Semi MR97311A library ## Copyright (C) 2005 <bradlch@hotmail.com> ## Part of spca5xx project ## 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 ## (at your option) 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 ## #****************************************************************************/static int pcam_start(struct usb_spca50x *pcam);static inline void pcam_stop(struct usb_spca50x *pcam);static int mr97311_config(struct usb_spca50x *pcam);static int pcam_reg_write(struct usb_device *dev, __u16 index, unsigned char *value, int length);static void MISensor_BulkWrite(struct usb_device *dev, unsigned short *pch, char Address, int length, char controlbyte);//MI Register table //elvisenum { REG_HW_MI_0, REG_HW_MI_1, REG_HW_MI_2, REG_HW_MI_3, REG_HW_MI_4, REG_HW_MI_5, REG_HW_MI_6, REG_HW_MI_7, REG_HW_MI_9 = 0x09, REG_HW_MI_B = 0x0B, REG_HW_MI_C, REG_HW_MI_D, REG_HW_MI_1E = 0x1E, REG_HW_MI_20 = 0x20, REG_HW_MI_2B = 0x2B, REG_HW_MI_2C, REG_HW_MI_2D, REG_HW_MI_2E, REG_HW_MI_35 = 0x35, REG_HW_MI_5F = 0x5F, REG_HW_MI_60, REG_HW_MI_61, REG_HW_MI_62, REG_HW_MI_63, REG_HW_MI_64, REG_HW_MI_F1 = 0xF1, ATTR_TOTAL_MI_REG = 242};static inline void pcam_stop(struct usb_spca50x *pcam){ int result; char data[2]; memset(data, 0, 2); data[0] = 1; data[1] = 0; result = pcam_reg_write(pcam->dev, data[0], data, 2); if (result < 0) printk("Camera Stop failed \n");}static int pcam_reg_write(struct usb_device *dev, __u16 index, unsigned char *value, int length){ unsigned char buf[12]; int rc; int i; unsigned char index_value = 0; memset(buf, 0, sizeof(buf)); for (i = 0; i < length; i++) buf[i] = value[i]; rc = usb_control_msg(dev, usb_sndbulkpipe(dev, 4), 0x12, 0xc8, index_value, index, value, length, 5 * HZ); PDEBUG(1, "reg write: 0x%02X , result = 0x%x \n", index, rc); if (rc < 0) { PDEBUG(1, "reg write: error %d \n", rc); } return rc;}static int pcam_start(struct usb_spca50x *pcam){ int err_code; unsigned char data[242]; unsigned short MI_buf[242]; int h_size, v_size; int intpipe; //struct usb_device *dev = pcam->dev; memset(data, 0, 242); memset(MI_buf, 0, 242); PDEBUG(1, "usb_set_interface in pcamCameraStart , interface %d , alt 8 \n", pcam->iface); if (usb_set_interface(pcam->dev, pcam->iface, 8) < 0) { err("Set packet size: set interface error"); return -EBUSY; } data[0] = 0x01; //address data[1] = 0x01; err_code = pcam_reg_write(pcam->dev, data[0], data, 0x02); if (err_code < 0) { printk("Register write failed \n"); return -1; } /* Initialize the MR97113 chip register */ data[0] = 0x00; //address data[1] = 0x0c | 0x01; //reg 0 data[2] = 0x01; //reg 1 switch (pcam->width) { case 1280: h_size = 1280; v_size = 1024; break; case 640: h_size = 640; v_size = 480; break; case 384: h_size = 384; v_size = 288; break; case 352: h_size = 352; v_size = 288; break; case 320: h_size = 320; v_size = 240; break; default: h_size = 352; v_size = 288; break; } data[3] = h_size / 8; //h_size , reg 2 data[4] = v_size / 8; //v_size , reg 3 data[5] = 0x30; // reg 4, MI, PAS5101 : 0x30 for 24mhz , 0x28 for 12mhz data[6] = 4; // reg 5, H start data[7] = 0xc0; // reg 6, gamma 1.5 data[8] = 3; // reg 7, V start //if(pcam->width == 320 ) //data[9]= 0x56; // reg 8, 24MHz, 2:1 scale down //else data[9] = 0x52; // reg 8, 24MHz, no scale down data[10] = 0x5d; // reg 9, I2C device address [for PAS5101 (0x40)] [for MI (0x5d)] err_code = pcam_reg_write(pcam->dev, data[0], data, 0x0b); if (err_code < 0) { PDEBUG(1, "Register write failed \n"); return -1; } data[0] = 0x23; //address data[1] = 0x09; // reg 35, append frame header err_code = pcam_reg_write(pcam->dev, data[0], data, 0x02); if (err_code < 0) { PDEBUG(1, "Register write failed \n"); return -1; } data[0] = 0x3C; //address if (pcam->width == 1280) data[1] = 200; // reg 60, pc-cam frame size (unit: 4KB) 800KB else data[1] = 50; // 50 reg 60, pc-cam frame size (unit: 4KB) 200KB err_code = pcam_reg_write(pcam->dev, data[0], data, 0x02); if (err_code < 0) { PDEBUG(1, "Register write failed \n"); return -1; } if (0) { // fixed dark-gain data[1] = 0; // reg 94, Y Gain (1.75) data[2] = 0; // reg 95, UV Gain (1.75) data[3] = 0x3f; // reg 96, Y Gain/UV Gain/disable auto dark-gain data[4] = 0; // reg 97, set fixed dark level data[5] = 0; // reg 98, don't care } else { // auto dark-gain data[1] = 0; // reg 94, Y Gain (auto) data[2] = 0; // reg 95, UV Gain (1.75) data[3] = 0x78; // reg 96, Y Gain/UV Gain/disable auto dark-gain switch (pcam->width) { case 1280: data[4] = 154; // reg 97, %3 shadow point (unit: 256 pixel) data[5] = 51; // reg 98, %1 highlight point (uint: 256 pixel) break; case 640: data[4] = 36; // reg 97, %3 shadow point (unit: 256 pixel) data[5] = 12; // reg 98, %1 highlight point (uint: 256 pixel) break; case 320: data[4] = 9; // reg 97, %3 shadow point (unit: 256 pixel) data[5] = 3; // reg 98, %1 highlight point (uint: 256 pixel) break; } } // auto dark-gain data[0] = 0x5E; // address err_code = pcam_reg_write(pcam->dev, data[0], data, 0x06); if (err_code < 0) { PDEBUG(1, "Register write failed \n"); return -1; } data[0] = 0x67; data[1] = 0x13; // reg 103, first pixel B, disable sharpness err_code = pcam_reg_write(pcam->dev, data[0], data, 0x02); if (err_code < 0) { PDEBUG(1, "Register write failed \n"); return -1; } /* initialize the value of MI sensor... */ MI_buf[REG_HW_MI_1] = 0x000a; MI_buf[REG_HW_MI_2] = 0x000c; MI_buf[REG_HW_MI_3] = 0x0405; MI_buf[REG_HW_MI_4] = 0x0507; //mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 MI_buf[REG_HW_MI_5] = 0x0013; //13 MI_buf[REG_HW_MI_6] = 0x001f; // vertical blanking //mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking MI_buf[REG_HW_MI_7] = 0x0002; //mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; //mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; MI_buf[REG_HW_MI_9] = 0x0374; MI_buf[REG_HW_MI_B] = 0x0000; MI_buf[REG_HW_MI_C] = 0x0000; MI_buf[REG_HW_MI_D] = 0x0000; MI_buf[REG_HW_MI_1E] = 0x8000;// mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; MI_buf[REG_HW_MI_20] = 0x1104; //0x111c; MI_buf[REG_HW_MI_2B] = 0x0008;// mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; MI_buf[REG_HW_MI_2C] = 0x001f; //lita suggest MI_buf[REG_HW_MI_2D] = 0x0008; MI_buf[REG_HW_MI_2E] = 0x0008; MI_buf[REG_HW_MI_35] = 0x0051; MI_buf[REG_HW_MI_5F] = 0x0904; //fail to write MI_buf[REG_HW_MI_60] = 0x0000; MI_buf[REG_HW_MI_61] = 0x0000; MI_buf[REG_HW_MI_62] = 0x0498; MI_buf[REG_HW_MI_63] = 0x0000; MI_buf[REG_HW_MI_64] = 0x0000; MI_buf[REG_HW_MI_F1] = 0x0001; //changing while setting up the different value of dx/dy if (pcam->width != 1280) { MI_buf[0x01] = 0x010a; MI_buf[0x02] = 0x014c; MI_buf[0x03] = 0x01e5; MI_buf[0x04] = 0x0287; } MI_buf[0x20] = 0x1104; MISensor_BulkWrite(pcam->dev, MI_buf + 1, 1, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 2, 2, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 3, 3, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 4, 4, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 5, 5, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 6, 6, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 7, 7, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 9, 9, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x0B, 0x0B, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x0C, 0x0C, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x0D, 0x0D, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x1E, 0x1E, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x20, 0x20, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x2B, 0x2B, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x2C, 0x2C, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x2D, 0x2D, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x2E, 0x2E, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x35, 0x35, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x5F, 0x5F, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x60, 0x60, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x61, 0x61, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x62, 0x62, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x63, 0x63, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0x64, 0x64, 1, 0); MISensor_BulkWrite(pcam->dev, MI_buf + 0xF1, 0xF1, 1, 0); intpipe = usb_sndintpipe(pcam->dev, 0); err_code = usb_clear_halt(pcam->dev, intpipe); data[0] = 0x00; data[1] = 0x4D; // ISOC transfering enable... err_code = pcam_reg_write(pcam->dev, data[0], data, 0x02); if (err_code < 0) { PDEBUG(1, "Register write failed \n"); return -1; } return 0;}static void MISensor_BulkWrite(struct usb_device *dev, unsigned short *pch, char Address, int length, char controlbyte){ int dest, src, result; unsigned char data[6]; memset(data, 0, 6); for (dest = 3, src = 0; src < length; src++) { data[0] = 0x1f; data[1] = controlbyte; data[2] = Address + src; data[dest] = pch[src] >> 8; //high byte; data[dest + 1] = pch[src]; //low byte; data[dest + 2] = 0; result = usb_control_msg(dev, usb_sndbulkpipe(dev, 4), 0x12, 0xc8, 0, Address, data, 5, 5 * HZ); PDEBUG(1, "reg write: 0x%02X , result = 0x%x \n", Address, result); if (result < 0) { printk("reg write: error %d \n", result); } }}static int mr97311_config(struct usb_spca50x *spca50x){ memset(spca50x->mode_cam, 0x00, TOTMODE * sizeof(struct mwebcam)); spca50x->mode_cam[VGA].width = 640; spca50x->mode_cam[VGA].height = 480; spca50x->mode_cam[VGA].t_palette = P_JPEG | P_RAW | P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16; spca50x->mode_cam[VGA].pipe = 1023; spca50x->mode_cam[VGA].method = 0; spca50x->mode_cam[VGA].mode = 1; spca50x->mode_cam[PAL].width = 384; spca50x->mode_cam[PAL].height = 288; spca50x->mode_cam[PAL].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16; spca50x->mode_cam[PAL].pipe = 1023; spca50x->mode_cam[PAL].method = 1; spca50x->mode_cam[PAL].mode = 1; spca50x->mode_cam[SIF].width = 352; spca50x->mode_cam[SIF].height = 288; spca50x->mode_cam[SIF].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16; spca50x->mode_cam[SIF].pipe = 1023; spca50x->mode_cam[SIF].method = 1; spca50x->mode_cam[SIF].mode = 1; spca50x->mode_cam[CIF].width = 320; spca50x->mode_cam[CIF].height = 240; spca50x->mode_cam[CIF].t_palette = P_JPEG | P_RAW | P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16; spca50x->mode_cam[CIF].pipe = 896; spca50x->mode_cam[CIF].method = 0; spca50x->mode_cam[CIF].mode = 2; spca50x->mode_cam[QPAL].width = 192; spca50x->mode_cam[QPAL].height = 144; spca50x->mode_cam[QPAL].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16; spca50x->mode_cam[QPAL].pipe = 896; spca50x->mode_cam[QPAL].method = 1; spca50x->mode_cam[QPAL].mode = 2; spca50x->mode_cam[QSIF].width = 176; spca50x->mode_cam[QSIF].height = 144; spca50x->mode_cam[QSIF].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16; spca50x->mode_cam[QSIF].pipe = 896; spca50x->mode_cam[QSIF].method = 1; spca50x->mode_cam[QSIF].mode = 2; spca50x->qindex = 1; // set quantization table return 0;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -