📄 mc521da.c
字号:
mc521da_write_reg(0xff, 0x01); mc521da_write_reg(0x52, 0x30); mc521da_write_reg(0x51, 0x00); mc521da_write_reg(0xda, 0x01); mc521da_write_reg(0x00, 0x8C); /* Wait for changes to take effect */ reg[0] = 0x00; while (i < 256) { i++; mc521da_read_reg(reg, &data); if ((data & 0x80) == 0) break; msleep(5); } /* ISP */ mc521da_write_reg(0xff, 0x02); mc521da_write_reg(0x03, 0x3b); /* Enable Decimator */ mc521da_write_reg(0x7a, 0x74); mc521da_write_reg(0x7b, 0x01); mc521da_write_reg(0x7e, 0x50); mc521da_write_reg(0x7f, 0x50); mc521da_write_reg(0x80, 0x3c); mc521da_write_reg(0x81, 0x3c); } else { /* UXGA */ mc521da_write_reg(0xff, 0x01); mc521da_write_reg(0x52, 0x10); mc521da_write_reg(0x51, 0x00); mc521da_write_reg(0xda, 0x00); /* update */ mc521da_write_reg(0x00, 0x84); /* Wait for changes to take effect */ reg[0] = 0x00; while (i < 256) { i++; mc521da_read_reg(reg, &data); if ((data & 0x80) == 0) break; msleep(5); } /* ISP */ mc521da_write_reg(0xff, 0x02); mc521da_write_reg(0x03, 0x3a); mc521da_write_reg(0x7a, 0x70); mc521da_write_reg(0x7b, 0x00); mc521da_write_reg(0x7e, 0xc8); mc521da_write_reg(0x7f, 0xc8); mc521da_write_reg(0x80, 0x96); mc521da_write_reg(0x81, 0x96); } return 0;}/*! * mc521da sensor interface Initialization * @param param sensor_interface * * @param width u32 * @param height u32 * @return None */static void mc521da_interface(sensor_interface *param, u32 width, u32 height){ param->clk_mode = 0x0; /* gated */ param->pixclk_pol = 0x0; param->data_width = 0x1; param->data_pol = 0x0; param->ext_vsync = 0x0; param->Vsync_pol = 0x0; param->Hsync_pol = 0x0; param->width = width - 1; param->height = height - 1; param->pixel_fmt = IPU_PIX_FMT_UYVY;}extern void gpio_sensor_reset(bool flag);/*! * mc521da Reset function * * @return sensor_interface * */static sensor_interface *mc521da_reset(void){ mc521da_interface(interface_param, format[1].width, format[1].height); set_mclk_rate(&interface_param->mclk); gpio_sensor_reset(true); msleep(10); gpio_sensor_reset(false); msleep(50); return interface_param;}/*! * mc521da sensor configuration * * @param frame_rate int * * @param high_quality int * @return sensor_interface * */static sensor_interface *mc521da_config(int *frame_rate, int high_quality){ int num_clock_per_row, err; int max_rate = 0; int index = 1; u16 frame_height; if (high_quality == 1) index = 0; err = mc521da_write_regs(mc521da_initial); if (err) { /* Reduce the MCLK */ interface_param->mclk = 20000000; mc521da_reset(); printk(KERN_INFO "mc521da: mclk reduced\n"); mc521da_write_regs(mc521da_initial); } mc521da_interface(interface_param, format[index].width, format[index].height); if (index == 0) { mc521da_sensor_downscale(false); } else { mc521da_sensor_downscale(true); } num_clock_per_row = 1845; max_rate = interface_param->mclk * 3 * (index + 1) / (2 * num_clock_per_row * 1300); if ((*frame_rate > max_rate) || (*frame_rate == 0)) { *frame_rate = max_rate; } frame_height = 1300 * max_rate / (*frame_rate); *frame_rate = interface_param->mclk * 3 * (index + 1) / (2 * num_clock_per_row * frame_height); mc521da_write_reg(0xff, 0x01); mc521da_write_reg(0xE, frame_height & 0xFF); mc521da_write_reg(0xF, (frame_height & 0xFF00) >> 8); mc521da_write_reg(0xCC, frame_height & 0xFF); mc521da_write_reg(0xCD, (frame_height & 0xFF00) >> 8); return interface_param;}/*! * mc521da sensor set color configuration * * @param bright int * @param saturation int * @param red int * @param green int * @param blue int * @return None */static voidmc521da_set_color(int bright, int saturation, int red, int green, int blue){ /* Select ISP */ mc521da_write_reg(0xff, 0x02); mc521da_write_reg(0x41, bright); mc521da_write_reg(0xca, red); mc521da_write_reg(0xcb, green); mc521da_write_reg(0xcc, blue);}/*! * mc521da sensor get color configuration * * @param bright int * * @param saturation int * * @param red int * * @param green int * * @param blue int * * @return None */static voidmc521da_get_color(int *bright, int *saturation, int *red, int *green, int *blue){ u8 reg[1]; u8 *pdata; *saturation = 0; /* Select ISP */ mc521da_write_reg(0xff, 0x02); reg[0] = 0x41; pdata = (u8 *) bright; mc521da_read_reg(reg, pdata); reg[0] = 0xCA; pdata = (u8 *) red; mc521da_read_reg(reg, pdata); reg[0] = 0xCB; pdata = (u8 *) green; mc521da_read_reg(reg, pdata); reg[0] = 0xCC; pdata = (u8 *) blue; mc521da_read_reg(reg, pdata);}struct camera_sensor camera_sensor_if = { set_color:mc521da_set_color, get_color:mc521da_get_color, config:mc521da_config, reset:mc521da_reset,};/*! * mc521da I2C detect_client function * * @param adapter struct i2c_adapter * * @param address int * @param kind int * * @return Error code indicating success or failure */static int mc521da_detect_client(struct i2c_adapter *adapter, int address, int kind){ mc521da_i2c_client.adapter = adapter; if (i2c_attach_client(&mc521da_i2c_client)) { mc521da_i2c_client.adapter = NULL; printk(KERN_ERR "mc521da_attach: i2c_attach_client failed\n"); return -1; } interface_param = (sensor_interface *) kmalloc(sizeof(sensor_interface), GFP_KERNEL); if (!interface_param) { printk(KERN_ERR "mc521da_attach: kmalloc failed \n"); return -1; } interface_param->mclk = 25000000; printk(KERN_INFO "mc521da Detected\n"); return 0;}static unsigned short normal_i2c[] = { MC521DA_I2C_ADDRESS, I2C_CLIENT_END };/* Magic definition of all other variables and things */I2C_CLIENT_INSMOD;static int mc521da_attach(struct i2c_adapter *adap){ uint32_t mclk = 25000000; struct clk *clk; int err; clk = clk_get(NULL, "csi_clk"); clk_enable(clk); set_mclk_rate(&mclk); gpio_sensor_reset(true); msleep(10); gpio_sensor_reset(false); msleep(100); err = i2c_probe(adap, &addr_data, &mc521da_detect_client); clk_disable(clk); clk_put(clk); return err;}/*! * mc521da I2C detach function * * @param client struct i2c_client * * @return Error code indicating success or failure */static int mc521da_detach(struct i2c_client *client){ int err; if (!mc521da_i2c_client.adapter) return -1; err = i2c_detach_client(&mc521da_i2c_client); mc521da_i2c_client.adapter = NULL; if (interface_param) kfree(interface_param); interface_param = NULL; return err;}extern void gpio_sensor_active(void);extern void gpio_sensor_inactive(void);/*! * mc521da init function * * @return Error code indicating success or failure */static __init int mc521da_init(void){ gpio_sensor_active(); return i2c_add_driver(&mc521da_i2c_driver);}/*! * mc521da cleanup function * * @return Error code indicating success or failure */static void __exit mc521da_clean(void){ i2c_del_driver(&mc521da_i2c_driver); gpio_sensor_inactive();}module_init(mc521da_init);module_exit(mc521da_clean);/* Exported symbols for modules. */EXPORT_SYMBOL(camera_sensor_if);MODULE_AUTHOR("Freescale Semiconductor, Inc.");MODULE_DESCRIPTION("MC521DA Camera Driver");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -