📄 ov2640.c
字号:
/* * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. *//* * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License * Version 2 or later at the following locations: * * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html */#include <linux/module.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/ctype.h>#include <linux/types.h>#include <linux/delay.h>#include <linux/device.h>#include <linux/i2c.h>#include <linux/clk.h>#include <asm/arch/mxc_i2c.h>#include <asm/arch/pmic_power.h>#include "mxc_v4l2_capture.h"#include "ov2640.h"static sensor_interface *interface_param = NULL;static int reset_frame_rate = 30;static int ov2640_attach(struct i2c_adapter *adapter);static int ov2640_detach(struct i2c_client *client);static struct i2c_driver ov2640_i2c_driver = { .driver = { .owner = THIS_MODULE, .name = "OV2640 Client", }, .attach_adapter = ov2640_attach, .detach_client = ov2640_detach,};static struct i2c_client ov2640_i2c_client = { .name = "ov2640 I2C dev", .addr = OV2640_I2C_ADDRESS, .driver = &ov2640_i2c_driver,};/*! * ov2640 I2C detect_client function * * @param adapter struct i2c_adapter * * @param address int * @param kind int * * @return Error code indicating success or failure */static int ov2640_detect_client(struct i2c_adapter *adapter, int address, int kind){ ov2640_i2c_client.adapter = adapter; if (i2c_attach_client(&ov2640_i2c_client)) { ov2640_i2c_client.adapter = NULL; printk(KERN_ERR "ov2640_attach: i2c_attach_client failed\n"); return -1; } interface_param = (sensor_interface *) kmalloc(sizeof(sensor_interface), GFP_KERNEL); if (!interface_param) { printk(KERN_ERR "ov2640_attach: kmalloc failed \n"); return -1; } interface_param->mclk = 27000000; printk(KERN_INFO "ov2640 Detected\n"); return 0;}static unsigned short normal_i2c[] = { OV2640_I2C_ADDRESS, I2C_CLIENT_END };/* Magic definition of all other variables and things */I2C_CLIENT_INSMOD;/*! * ov2640 I2C attach function * * @param adapter struct i2c_adapter * * @return Error code indicating success or failure */static int ov2640_attach(struct i2c_adapter *adapter){ uint32_t mclk = 27000000; struct clk *clk; int err; clk = clk_get(NULL, "csi_clk"); clk_enable(clk); set_mclk_rate(&mclk); err = i2c_probe(adapter, &addr_data, &ov2640_detect_client); clk_disable(clk); clk_put(clk); return err;}/*! * ov2640 I2C detach function * * @param client struct i2c_client * * @return Error code indicating success or failure */static int ov2640_detach(struct i2c_client *client){ int err; if (!ov2640_i2c_client.adapter) return -1; err = i2c_detach_client(&ov2640_i2c_client); ov2640_i2c_client.adapter = NULL; if (interface_param) kfree(interface_param); interface_param = NULL; return err;}static int ov2640_i2c_client_xfer(unsigned int addr, u8 reg, char *buf, int num, int tran_flag){ struct i2c_msg msg[2]; int ret; msg[0].addr = addr; msg[0].len = 1; msg[0].buf = ® msg[0].flags = tran_flag; msg[0].flags &= ~I2C_M_RD; msg[1].addr = addr; msg[1].len = num; msg[1].buf = buf; msg[1].flags = tran_flag; if (tran_flag & MXC_I2C_FLAG_READ) { msg[1].flags |= I2C_M_RD; } else { msg[1].flags &= ~I2C_M_RD; } if (ov2640_i2c_client.adapter == NULL) { printk(KERN_ERR "%s:adapter error\n", __func__); return -1; } ret = i2c_transfer(ov2640_i2c_client.adapter, msg, 2); if (ret >= 0) return 0; printk(KERN_ERR "%s:i2c transfer error:%d\n", __func__, ret); return ret;}#ifdef TEST_DEBUGstatic int ov2640_read_reg(u8 reg, u8 * val){ if (ov2640_i2c_client_xfer(0x30, reg, val, 1, MXC_I2C_FLAG_READ) < 0) { printk(KERN_ERR "%s:read reg errorr:reg=%x,val=%x\n", __func__, reg, *val); return -1; } return 0;}#endifstatic int ov2640_write_reg(u8 reg, u8 val){ if (ov2640_i2c_client_xfer(0x30, reg, &val, 1, 0) < 0) { printk(KERN_ERR "%s:write reg errorr:reg=%x,val=%x\n", __func__, reg, val); return -1; } return 0;}//should be replaced by width and height version.static int ov2640_init_1600_1120(void){ ov2640_write_reg(0xff, 1); ov2640_write_reg(0x12, 0x80); udelay(1000); ov2640_write_reg(0xff, 00); ov2640_write_reg(0x2c, 0xff); ov2640_write_reg(0x2e, 0xdf); ov2640_write_reg(0xff, 0x1); ov2640_write_reg(0x3c, 0x32); ov2640_write_reg(0x11, 0x01); ov2640_write_reg(0x09, 0x00); ov2640_write_reg(0x04, 0x28); ov2640_write_reg(0x13, 0xe5); ov2640_write_reg(0x14, 0x48); ov2640_write_reg(0x2c, 0x0c); ov2640_write_reg(0x33, 0x78); ov2640_write_reg(0x3a, 0x33); ov2640_write_reg(0x3b, 0xfb); ov2640_write_reg(0x3e, 0x00); ov2640_write_reg(0x43, 0x11); ov2640_write_reg(0x16, 0x10); ov2640_write_reg(0x39, 0x82); ov2640_write_reg(0x35, 0x88); ov2640_write_reg(0x22, 0x0a); ov2640_write_reg(0x37, 0x40); ov2640_write_reg(0x23, 0x00); ov2640_write_reg(0x34, 0xa0); ov2640_write_reg(0x36, 0x1a); ov2640_write_reg(0x06, 0x02); ov2640_write_reg(0x07, 0xc0); ov2640_write_reg(0x0d, 0xb7); ov2640_write_reg(0x0e, 0x01); ov2640_write_reg(0x4c, 0x00); ov2640_write_reg(0x4a, 0x81); ov2640_write_reg(0x21, 0x99); ov2640_write_reg(0x24, 0x40); ov2640_write_reg(0x25, 0x38); ov2640_write_reg(0x26, 0x82); ov2640_write_reg(0x5c, 0x00); ov2640_write_reg(0x63, 0x00); ov2640_write_reg(0x46, 0x3f); ov2640_write_reg(0x0c, 0x3c); ov2640_write_reg(0x5d, 0x55); ov2640_write_reg(0x5e, 0x7d); ov2640_write_reg(0x5f, 0x7d); ov2640_write_reg(0x60, 0x55); ov2640_write_reg(0x61, 0x70); ov2640_write_reg(0x62, 0x80); ov2640_write_reg(0x7c, 0x05); ov2640_write_reg(0x20, 0x80); ov2640_write_reg(0x28, 0x30); ov2640_write_reg(0x6c, 0x00); ov2640_write_reg(0x6d, 0x80); ov2640_write_reg(0x6e, 00); ov2640_write_reg(0x70, 0x02); ov2640_write_reg(0x71, 0x94); ov2640_write_reg(0x73, 0xc1); ov2640_write_reg(0x3d, 0x34); ov2640_write_reg(0x5a, 0x57); ov2640_write_reg(0x4f, 0xbb); ov2640_write_reg(0x50, 0x9c); ov2640_write_reg(0xff, 0x00); ov2640_write_reg(0xe5, 0x7f); ov2640_write_reg(0xf9, 0xc0); ov2640_write_reg(0x41, 0x24); ov2640_write_reg(0x44, 0x06); ov2640_write_reg(0xe0, 0x14); ov2640_write_reg(0x76, 0xff); ov2640_write_reg(0x33, 0xa0); ov2640_write_reg(0x42, 0x20); ov2640_write_reg(0x43, 0x18); ov2640_write_reg(0x4c, 0x00); ov2640_write_reg(0x87, 0xd0); ov2640_write_reg(0xd7, 0x03); ov2640_write_reg(0xd9, 0x10); ov2640_write_reg(0xd3, 0x82); ov2640_write_reg(0xc8, 0x08); ov2640_write_reg(0xc9, 0x80); ov2640_write_reg(0x7c, 0x00); ov2640_write_reg(0x7d, 0x00); ov2640_write_reg(0x7c, 0x03); ov2640_write_reg(0x7d, 0x48); ov2640_write_reg(0x7d, 0x48); ov2640_write_reg(0x7c, 0x08); ov2640_write_reg(0x7d, 0x20); ov2640_write_reg(0x7d, 0x10); ov2640_write_reg(0x7d, 0x0e); ov2640_write_reg(0x90, 0x00); ov2640_write_reg(0x91, 0x0e); ov2640_write_reg(0x91, 0x1a); ov2640_write_reg(0x91, 0x31); ov2640_write_reg(0x91, 0x5a); ov2640_write_reg(0x91, 0x69); ov2640_write_reg(0x91, 0x75); ov2640_write_reg(0x91, 0x7e); ov2640_write_reg(0x91, 0x88); ov2640_write_reg(0x91, 0x8f); ov2640_write_reg(0x91, 0x96); ov2640_write_reg(0x91, 0xa3); ov2640_write_reg(0x91, 0xaf); ov2640_write_reg(0x91, 0xc4); ov2640_write_reg(0x91, 0xd7); ov2640_write_reg(0x91, 0xe8); ov2640_write_reg(0x91, 0x20); ov2640_write_reg(0x92, 0x00); ov2640_write_reg(0x93, 0x06); ov2640_write_reg(0x93, 0xe3); ov2640_write_reg(0x93, 0x03); ov2640_write_reg(0x93, 0x03); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x93, 0x02); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x93, 0x00); ov2640_write_reg(0x96, 0x00); ov2640_write_reg(0x97, 0x08); ov2640_write_reg(0x97, 0x19); ov2640_write_reg(0x97, 0x02); ov2640_write_reg(0x97, 0x0c); ov2640_write_reg(0x97, 0x24); ov2640_write_reg(0x97, 0x30); ov2640_write_reg(0x97, 0x28); ov2640_write_reg(0x97, 0x26); ov2640_write_reg(0x97, 0x02); ov2640_write_reg(0x97, 0x98); ov2640_write_reg(0x97, 0x80); ov2640_write_reg(0x97, 0x00); ov2640_write_reg(0x97, 0x00); ov2640_write_reg(0xa4, 0x00); ov2640_write_reg(0xa8, 0x00); ov2640_write_reg(0xc5, 0x11); ov2640_write_reg(0xc6, 0x51); ov2640_write_reg(0xbf, 0x80); ov2640_write_reg(0xc7, 0x10); ov2640_write_reg(0xb6, 0x66); ov2640_write_reg(0xb8, 0xa5); ov2640_write_reg(0xb7, 0x64); ov2640_write_reg(0xb9, 0x7c); ov2640_write_reg(0xb3, 0xaf); ov2640_write_reg(0xb4, 0x97); ov2640_write_reg(0xb5, 0xff); ov2640_write_reg(0xb0, 0xc5); ov2640_write_reg(0xb1, 0x94); ov2640_write_reg(0xb2, 0x0f); ov2640_write_reg(0xc4, 0x5c); ov2640_write_reg(0xa6, 0x00); ov2640_write_reg(0xa7, 0x20); ov2640_write_reg(0xa7, 0xd8); ov2640_write_reg(0xa7, 0x1b); ov2640_write_reg(0xa7, 0x31); ov2640_write_reg(0xa7, 0x00); ov2640_write_reg(0xa7, 0x18); ov2640_write_reg(0xa7, 0x20); ov2640_write_reg(0xa7, 0xd8); ov2640_write_reg(0xa7, 0x19); ov2640_write_reg(0xa7, 0x31); ov2640_write_reg(0xa7, 0x00); ov2640_write_reg(0xa7, 0x18); ov2640_write_reg(0xa7, 0x20); ov2640_write_reg(0xa7, 0xd8); ov2640_write_reg(0xa7, 0x19); ov2640_write_reg(0xa7, 0x31); ov2640_write_reg(0xa7, 0x00); ov2640_write_reg(0xa7, 0x18); ov2640_write_reg(0xc0, 0xc8); ov2640_write_reg(0xc1, 0x96); ov2640_write_reg(0x86, 0x3d); ov2640_write_reg(0x50, 0x00); ov2640_write_reg(0x51, 0x90); ov2640_write_reg(0x52, 0x18); ov2640_write_reg(0x53, 0x00); ov2640_write_reg(0x54, 0x00); ov2640_write_reg(0x55, 0x88); ov2640_write_reg(0x57, 0x00); ov2640_write_reg(0x5a, 0x90); ov2640_write_reg(0x5b, 0x18); ov2640_write_reg(0x5c, 0x05); ov2640_write_reg(0xc3, 0xef); ov2640_write_reg(0x7f, 0x00); ov2640_write_reg(0xda, 0x01); ov2640_write_reg(0xe5, 0x1f); ov2640_write_reg(0xe1, 0x67); ov2640_write_reg(0xe0, 0x00); ov2640_write_reg(0xdd, 0x7f); ov2640_write_reg(0x05, 0x00); return 0;}static int ov2640_init_800_600(void){ ov2640_write_reg(0xff, 1); ov2640_write_reg(0x12, 0x80); udelay(1000); ov2640_write_reg(0xff, 00); ov2640_write_reg(0x2c, 0xff); ov2640_write_reg(0x2e, 0xdf); ov2640_write_reg(0xff, 0x1); ov2640_write_reg(0x3c, 0x32); ov2640_write_reg(0x11, 0x01); ov2640_write_reg(0x09, 0x00); ov2640_write_reg(0x04, 0x28); ov2640_write_reg(0x13, 0xe5); ov2640_write_reg(0x14, 0x48); ov2640_write_reg(0x2c, 0x0c); ov2640_write_reg(0x33, 0x78); ov2640_write_reg(0x3a, 0x33); ov2640_write_reg(0x3b, 0xfb); ov2640_write_reg(0x3e, 0x00); ov2640_write_reg(0x43, 0x11); ov2640_write_reg(0x16, 0x10); ov2640_write_reg(0x39, 0x92); ov2640_write_reg(0x35, 0xda); ov2640_write_reg(0x22, 0x1a); ov2640_write_reg(0x37, 0xc3); ov2640_write_reg(0x23, 0x00); ov2640_write_reg(0x34, 0xc0); ov2640_write_reg(0x36, 0x1a); ov2640_write_reg(0x06, 0x88); ov2640_write_reg(0x07, 0xc0); ov2640_write_reg(0x0d, 0x87); ov2640_write_reg(0x0e, 0x41); ov2640_write_reg(0x4c, 0x00); ov2640_write_reg(0x4a, 0x81); ov2640_write_reg(0x21, 0x99); ov2640_write_reg(0x24, 0x40); ov2640_write_reg(0x25, 0x38); ov2640_write_reg(0x26, 0x82); ov2640_write_reg(0x5c, 0x00); ov2640_write_reg(0x63, 0x00); ov2640_write_reg(0x46, 0x22); ov2640_write_reg(0x0c, 0x3c); ov2640_write_reg(0x5d, 0x55); ov2640_write_reg(0x5e, 0x7d); ov2640_write_reg(0x5f, 0x7d); ov2640_write_reg(0x60, 0x55); ov2640_write_reg(0x61, 0x70); ov2640_write_reg(0x62, 0x80); ov2640_write_reg(0x7c, 0x05); ov2640_write_reg(0x20, 0x80); ov2640_write_reg(0x28, 0x30); ov2640_write_reg(0x6c, 0x00); ov2640_write_reg(0x6d, 0x80); ov2640_write_reg(0x6e, 00); ov2640_write_reg(0x70, 0x02); ov2640_write_reg(0x71, 0x94); ov2640_write_reg(0x73, 0xc1); ov2640_write_reg(0x12, 0x40); ov2640_write_reg(0x17, 0x11); ov2640_write_reg(0x18, 0x43); ov2640_write_reg(0x19, 0x00); ov2640_write_reg(0x1a, 0x4b); ov2640_write_reg(0x32, 0x09); ov2640_write_reg(0x37, 0xc0); ov2640_write_reg(0x4f, 0xca); ov2640_write_reg(0x50, 0xa8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -