question about v4l2_subdev

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I am currently working on the atmel video driver, and I am facing a issue.
I have written a driver for the ov2640 omnivison sensor(enclosed). In the ov2640 driver I am using the v4l2_subdev API. The point is I don't how how can I access it in my video driver? How to register the subdev struct in the atmel driver, so I could access the s_ftm function for instance.


Regards,
Sedji
/*
 * Omnivision ov2640 Camera driver
 *
 * Copyright (C) 2006 Atmel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <mach/gpio.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>

#include <media/atmel-isi.h>
#include "ov2640.h"


static char mclk_name[32] = "isi_clk";
module_param_string(mclk, mclk_name, sizeof(mclk_name), 0644);
MODULE_PARM_DESC(mclk, "Name of the clock used as camera clock input");
MODULE_PARM_DESC(mclk, "Name of mclk parent clock");

struct ov2640 {
	struct v4l2_subdev	sd;
	struct mutex		mutex;
	u8			miscel_ctrl;
	u16			pll_avr_ctrl;
	struct clk		*mclk;
	struct i2c_client	client;
	struct atmel_isi_camera	cam;
};
#define to_ov2640(cam) container_of(cam, struct ov2640, cam)

/*
 * OV2640 register configuration for all combinations of pixel format and
 * image size(for the moment only qvga YUV...)
 */
static struct ov2640_reg dump_list[] = {	
	{ OV2640_REG_TERM, OV2640_VAL_TERM }
};

/* YUV configs */
const static struct ov2640_reg qqcif_yuv[] = { };
const static struct ov2640_reg qqvga_yuv[] = { };
const static struct ov2640_reg sqcif_yuv[] = { 
	{ OV2640_REG_TERM, OV2640_VAL_TERM }
};

const static struct ov2640_reg qcif_yuv[] = {
{0xff, 0x01},{0x12, 0x80},{0xff, 0x00},{0x2c, 0xff},{0x2e, 0xdf},
{0xff, 0x01},{0x3c, 0x32},{0x11, 0x00},{0x09, 0x02},{0x04, 0x28},
{0x13, 0xe5},{0x14, 0x48},{0x2c, 0x0c},{0x33, 0x78},{0x3a, 0x33},
{0x3b, 0xfb},{0x3e, 0x00},{0x43, 0x11},{0x16, 0x10},{0x39, 0x02},
{0x35, 0x88},{0x22, 0x0a},{0x37, 0x40},{0x23, 0x00},{0x34, 0xa0},
{0x36, 0x1a},{0x06, 0x02},{0x07, 0xc0},{0x0d, 0xb7},{0x0e, 0x01},
{0x4c, 0x00},{0x4a, 0x81},{0x21, 0x99},{0x24, 0x3a},{0x25, 0x32},
{0x26, 0x82},{0x5c, 0x00},{0x63, 0x00},{0x5d, 0x55},{0x5e, 0x7d},
{0x5f, 0x7d},{0x60, 0x55},{0x61, 0x70},{0x62, 0x80},{0x7c, 0x05},
{0x20, 0x80},{0x28, 0x30},{0x6c, 0x00},{0x6d, 0x80},{0x6e, 0x00},
{0x70, 0x02},{0x71, 0x94},{0x73, 0xc1},{0x3d, 0x34},{0x5a, 0x57},
{0x4f, 0xbb},{0x50, 0x9c},{0xff, 0x00},{0xe5, 0x7f},{0xf9, 0xc0},
{0x41, 0x24},{0xe0, 0x14},{0x76, 0xff},{0x33, 0xa0},{0x42, 0x20},
{0x43, 0x18},{0x4c, 0x00},{0x87, 0xd0},{0x88, 0x3f},{0xd7, 0x03},
{0xd9, 0x10},{0xd3, 0x82},{0xc8, 0x08},{0xc9, 0x80},{0x7c, 0x00},
{0x7d, 0x02},{0x7c, 0x03},{0x7d, 0x48},{0x7d, 0x48},{0x7c, 0x08},
{0x7d, 0x20},{0x7d, 0x10},{0x7d, 0x0e},{0x90, 0x00},{0x91, 0x0e},
{0x91, 0x1a},{0x91, 0x31},{0x91, 0x5a},{0x91, 0x69},{0x91, 0x75},
{0x91, 0x7e},{0x91, 0x88},{0x91, 0x8f},{0x91, 0x96},{0x91, 0xa3},
{0x91, 0xaf},{0x91, 0xc4},{0x91, 0xd7},{0x91, 0xe8},{0x91, 0x20},
{0x92, 0x00},{0x93, 0x06},{0x93, 0xe3},{0x93, 0x05},{0x93, 0x05},
{0x93, 0x00},{0x93, 0x02},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},
{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x96, 0x00},
{0x97, 0x08},{0x97, 0x19},{0x97, 0x02},{0x97, 0x0c},{0x97, 0x24},
{0x97, 0x30},{0x97, 0x28},{0x97, 0x26},{0x97, 0x02},{0x97, 0x98},
{0x97, 0x80},{0x97, 0x00},{0x97, 0x00},{0xc3, 0xed},{0xa4, 0x00},
{0xa8, 0x00},{0xc5, 0x11},{0xc6, 0x51},{0xbf, 0x80},{0xc7, 0x10},
{0xb6, 0x66},{0xb8, 0xa5},{0xb7, 0x64},{0xb9, 0x7c},{0xb3, 0xaf},
{0xb4, 0x97},{0xb5, 0xff},{0xb0, 0xc5},{0xb1, 0x94},{0xb2, 0x0f},
{0xc4, 0x5c},{0xc0, 0xc8},{0xc1, 0x96},{0x86, 0x1d},{0x50, 0x00},
{0x51, 0x90},{0x52, 0x18},{0x53, 0x00},{0x54, 0x00},{0x55, 0x88},
{0x57, 0x00},{0x5a, 0x90},{0x5b, 0x18},{0x5c, 0x05},{0xc3, 0xed},
{0x7f, 0x00},{0xda, 0x04},{0xe5, 0x1f},{0xe1, 0x67},{0xe0, 0x00},
{0xdd, 0xff},{0x05, 0x00},{0xff, 0x01},{0x11, 0x01},

{0xff, 0x01},{0x12, 0x40},{0x17, 0x11},{0x18, 0x43},{0x19, 0x00},
{0x1a, 0x4b},{0x32, 0x09},{0x4f, 0xca},{0x50, 0xa8},{0x5a, 0x23},
{0x6d, 0x00},{0x3d, 0x38},

{0x39, 0x12},{0x35, 0xda},{0x22, 0x1a},{0x37, 0xc3},{0x23, 0x00},
{0x34, 0xc0},{0x36, 0x1a},{0x06, 0x88},{0x07, 0xc0},{0x0d, 0x87},
{0x0e, 0x41},{0x4c, 0x00},{0x48, 0x00},{0x5B, 0x00},{0x42, 0x03},

{0xff, 0x00},{0xe0, 0x04},{0xc0, 0x64},{0xc1, 0x4B},{0x8c, 0x00},
{0x86, 0x1D},{0xd3, 0x82},{0xe0, 0x00},

/* QCIF */
{0xff, 0x00},{0xc0, 0x64},{0xc1, 0x4B},{0x8c, 0x00},{0x86, 0x3D},
{0x50, 0x92},{0x51, 0xC8},{0x52, 0x96},{0x53, 0x00},{0x54, 0x00},
{0x55, 0x00},{0x5a, 0x2C},{0x5b, 0x24},{0x5c, 0x00},{0xd3, 0x04},

{0xFF, 0x00},{0xE0, 0x04},{0xE1, 0x67},{0xD7, 0x01},{0xDA, 0x00},
{0xD3, 0x82},{0xE0, 0x00},

{ OV2640_REG_TERM, OV2640_VAL_TERM }
};

/* QVGA YUV */
const static struct ov2640_reg qvga_yuv[] = {
	/* Value provided by Omnivision */
{0xff, 0x01},{0x12, 0x80},{0xff, 0x00},{0x2c, 0xff},{0x2e, 0xdf},
{0xff, 0x01},{0x3c, 0x32},{0x11, 0x00},{0x09, 0x02},{0x04, 0x28},
{0x13, 0xe5},{0x14, 0x48},{0x2c, 0x0c},{0x33, 0x78},{0x3a, 0x33},
{0x3b, 0xfb},{0x3e, 0x00},{0x43, 0x11},{0x16, 0x10},{0x39, 0x02},
{0x35, 0x88},{0x22, 0x0a},{0x37, 0x40},{0x23, 0x00},{0x34, 0xa0},
{0x36, 0x1a},{0x06, 0x02},{0x07, 0xc0},{0x0d, 0xb7},{0x0e, 0x01},
{0x4c, 0x00},{0x4a, 0x81},{0x21, 0x99},{0x24, 0x3a},{0x25, 0x32},
{0x26, 0x82},{0x5c, 0x00},{0x63, 0x00},{0x5d, 0x55},{0x5e, 0x7d},
{0x5f, 0x7d},{0x60, 0x55},{0x61, 0x70},{0x62, 0x80},{0x7c, 0x05},
{0x20, 0x80},{0x28, 0x30},{0x6c, 0x00},{0x6d, 0x80},{0x6e, 0x00},
{0x70, 0x02},{0x71, 0x94},{0x73, 0xc1},{0x3d, 0x34},{0x5a, 0x57},
{0x4f, 0xbb},{0x50, 0x9c},{0xff, 0x00},{0xe5, 0x7f},{0xf9, 0xc0},
{0x41, 0x24},{0xe0, 0x14},{0x76, 0xff},{0x33, 0xa0},{0x42, 0x20},
{0x43, 0x18},{0x4c, 0x00},{0x87, 0xd0},{0x88, 0x3f},{0xd7, 0x03},
{0xd9, 0x10},{0xd3, 0x82},{0xc8, 0x08},{0xc9, 0x80},{0x7c, 0x00},
{0x7d, 0x02},{0x7c, 0x03},{0x7d, 0x48},{0x7d, 0x48},{0x7c, 0x08},
{0x7d, 0x20},{0x7d, 0x10},{0x7d, 0x0e},{0x90, 0x00},{0x91, 0x0e},
{0x91, 0x1a},{0x91, 0x31},{0x91, 0x5a},{0x91, 0x69},{0x91, 0x75},
{0x91, 0x7e},{0x91, 0x88},{0x91, 0x8f},{0x91, 0x96},{0x91, 0xa3},
{0x91, 0xaf},{0x91, 0xc4},{0x91, 0xd7},{0x91, 0xe8},{0x91, 0x20},
{0x92, 0x00},{0x93, 0x06},{0x93, 0xe3},{0x93, 0x05},{0x93, 0x05},
{0x93, 0x00},{0x93, 0x02},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},
{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x96, 0x00},
{0x97, 0x08},{0x97, 0x19},{0x97, 0x02},{0x97, 0x0c},{0x97, 0x24},
{0x97, 0x30},{0x97, 0x28},{0x97, 0x26},{0x97, 0x02},{0x97, 0x98},
{0x97, 0x80},{0x97, 0x00},{0x97, 0x00},{0xc3, 0xed},{0xa4, 0x00},
{0xa8, 0x00},{0xc5, 0x11},{0xc6, 0x51},{0xbf, 0x80},{0xc7, 0x10},
{0xb6, 0x66},{0xb8, 0xa5},{0xb7, 0x64},{0xb9, 0x7c},{0xb3, 0xaf},
{0xb4, 0x97},{0xb5, 0xff},{0xb0, 0xc5},{0xb1, 0x94},{0xb2, 0x0f},
{0xc4, 0x5c},{0xc0, 0xc8},{0xc1, 0x96},{0x86, 0x1d},{0x50, 0x00},
{0x51, 0x90},{0x52, 0x18},{0x53, 0x00},{0x54, 0x00},{0x55, 0x88},
{0x57, 0x00},{0x5a, 0x90},{0x5b, 0x18},{0x5c, 0x05},{0xc3, 0xed},
{0x7f, 0x00},{0xda, 0x04},{0xe5, 0x1f},{0xe1, 0x67},{0xe0, 0x00},
{0xdd, 0xff},{0x05, 0x00},{0xff, 0x01},{0x11, 0x01},

{0xff, 0x01},{0x12, 0x40},{0x17, 0x11},{0x18, 0x43},{0x19, 0x00},
{0x1a, 0x4b},{0x32, 0x09},{0x4f, 0xca},{0x50, 0xa8},{0x5a, 0x23},
{0x6d, 0x00},{0x3d, 0x38},

{0x39, 0x12},{0x35, 0xda},{0x22, 0x1a},{0x37, 0xc3},{0x23, 0x00},
{0x34, 0xc0},{0x36, 0x1a},{0x06, 0x88},{0x07, 0xc0},{0x0d, 0x87},
{0x0e, 0x41},{0x4c, 0x00},{0x48, 0x00},{0x5B, 0x00},

{0x42, 0x03},{0xff, 0x00},{0xe0, 0x04},{0xc0, 0x64},{0xc1, 0x4B},
{0x8c, 0x00},{0x86, 0x1D},{0xd3, 0x82},{0xe0, 0x00},

{0xff, 0x00},{0xc0, 0x64},{0xc1, 0x4B},{0x8c, 0x00},{0x86, 0x3D},
{0x50, 0x89},{0x51, 0xC8},{0x52, 0x96},{0x53, 0x00},{0x54, 0x00},
{0x55, 0x00},{0x5a, 0x50},{0x5b, 0x3C},{0x5c, 0x00},{0xd3, 0x04},

/* 10 fps */
/*{0xff, 0x01},{0x11, 0x01},{0x3d, 0x3a},{0x2b, 0x95},*/

/* 15 fps */
/*{0xff, 0x01},{0x11, 0x01},{0x3d, 0x38},{0x2b, 0x00},*/

/* 20 fps */
/*{0xff, 0x01},{0x11, 0x00},{0x3d, 0x3a},{0x2b, 0x95},*/

/* 25 fps */
/*{0xff, 0x01},{0x11, 0x00},{0x3d, 0x39},{0x2b, 0x3c},*/

/* 30 fps*/
{0xff, 0x01},{0x11, 0x01},{0x3d, 0x38},{0x2b, 0x00},

{0xFF, 0x00},{0xE0, 0x04},{0xE1, 0x67},{0xD7, 0x01},{0xDA, 0x00},
{0xD3, 0x82},{0xE0, 0x00},

{ OV2640_REG_TERM, OV2640_VAL_TERM }
};
const static struct ov2640_reg cif_yuv[] = { };
const static struct ov2640_reg vga_yuv[] = { 
{0xff, 0x01},{0x12, 0x80},{0xff, 0x00},{0x2c, 0xff},{0x2e, 0xdf},
{0xff, 0x01},{0x3c, 0x32},{0x11, 0x00},{0x09, 0x02},{0x04, 0x28},
{0x13, 0xe5},{0x14, 0x48},{0x2c, 0x0c},{0x33, 0x78},{0x3a, 0x33},
{0x3b, 0xfb},{0x3e, 0x00},{0x43, 0x11},{0x16, 0x10},{0x39, 0x02},
{0x35, 0x88},{0x22, 0x0a},{0x37, 0x40},{0x23, 0x00},{0x34, 0xa0},
{0x36, 0x1a},{0x06, 0x02},{0x07, 0xc0},{0x0d, 0xb7},{0x0e, 0x01},
{0x4c, 0x00},{0x4a, 0x81},{0x21, 0x99},{0x24, 0x3a},{0x25, 0x32},
{0x26, 0x82},{0x5c, 0x00},{0x63, 0x00},{0x5d, 0x55},{0x5e, 0x7d},
{0x5f, 0x7d},{0x60, 0x55},{0x61, 0x70},{0x62, 0x80},{0x7c, 0x05},
{0x20, 0x80},{0x28, 0x30},{0x6c, 0x00},{0x6d, 0x80},{0x6e, 0x00},
{0x70, 0x02},{0x71, 0x94},{0x73, 0xc1},{0x3d, 0x34},{0x5a, 0x57},
{0x4f, 0xbb},{0x50, 0x9c},{0xff, 0x00},{0xe5, 0x7f},{0xf9, 0xc0},
{0x41, 0x24},{0xe0, 0x14},{0x76, 0xff},{0x33, 0xa0},{0x42, 0x20},
{0x43, 0x18},{0x4c, 0x00},{0x87, 0xd0},{0x88, 0x3f},{0xd7, 0x03},
{0xd9, 0x10},{0xd3, 0x82},{0xc8, 0x08},{0xc9, 0x80},{0x7c, 0x00},
{0x7d, 0x02},{0x7c, 0x03},{0x7d, 0x48},{0x7d, 0x48},{0x7c, 0x08},
{0x7d, 0x20},{0x7d, 0x10},{0x7d, 0x0e},{0x90, 0x00},{0x91, 0x0e},
{0x91, 0x1a},{0x91, 0x31},{0x91, 0x5a},{0x91, 0x69},{0x91, 0x75},
{0x91, 0x7e},{0x91, 0x88},{0x91, 0x8f},{0x91, 0x96},{0x91, 0xa3},
{0x91, 0xaf},{0x91, 0xc4},{0x91, 0xd7},{0x91, 0xe8},{0x91, 0x20},
{0x92, 0x00},{0x93, 0x06},{0x93, 0xe3},{0x93, 0x05},{0x93, 0x05},
{0x93, 0x00},{0x93, 0x02},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},
{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x96, 0x00},
{0x97, 0x08},{0x97, 0x19},{0x97, 0x02},{0x97, 0x0c},{0x97, 0x24},
{0x97, 0x30},{0x97, 0x28},{0x97, 0x26},{0x97, 0x02},{0x97, 0x98},
{0x97, 0x80},{0x97, 0x00},{0x97, 0x00},{0xc3, 0xed},{0xa4, 0x00},
{0xa8, 0x00},{0xc5, 0x11},{0xc6, 0x51},{0xbf, 0x80},{0xc7, 0x10},
{0xb6, 0x66},{0xb8, 0xa5},{0xb7, 0x64},{0xb9, 0x7c},{0xb3, 0xaf},
{0xb4, 0x97},{0xb5, 0xff},{0xb0, 0xc5},{0xb1, 0x94},{0xb2, 0x0f},
{0xc4, 0x5c},{0xc0, 0xc8},{0xc1, 0x96},{0x86, 0x1d},{0x50, 0x00},
{0x51, 0x90},{0x52, 0x18},{0x53, 0x00},{0x54, 0x00},{0x55, 0x88},
{0x57, 0x00},{0x5a, 0x90},{0x5b, 0x18},{0x5c, 0x05},{0xc3, 0xed},
{0x7f, 0x00},{0xda, 0x04},{0xe5, 0x1f},{0xe1, 0x67},{0xe0, 0x00},
{0xdd, 0xff},{0x05, 0x00},{0xff, 0x01},{0x11, 0x01},

{0xff, 0x01},{0x12, 0x40},{0x17, 0x11},{0x18, 0x43},{0x19, 0x00},
{0x1a, 0x4b},{0x32, 0x09},{0x4f, 0xca},{0x50, 0xa8},{0x5a, 0x23},
{0x6d, 0x00},{0x3d, 0x38},

{0x39, 0x12},{0x35, 0xda},{0x22, 0x1a},{0x37, 0xc3},{0x23, 0x00},
{0x34, 0xc0},{0x36, 0x1a},{0x06, 0x88},{0x07, 0xc0},{0x0d, 0x87},
{0x0e, 0x41},{0x4c, 0x00},{0x48, 0x00},{0x5B, 0x00},{0x42, 0x03},

{0xff, 0x00},{0xe0, 0x04},{0xc0, 0x64},{0xc1, 0x4B},{0x8c, 0x00},
{0x86, 0x1D},{0xd3, 0x82},{0xe0, 0x00},

{0xff, 0x00},{0xc0, 0x64},{0xc1, 0x4B},{0x8c, 0x00},{0x86, 0x3D},
{0x50, 0x00},{0x51, 0xC8},{0x52, 0x96},{0x53, 0x00},{0x54, 0x00},
{0x55, 0x00},{0x5a, 0xA0},{0x5b, 0x78},{0x5c, 0x00},{0xd3, 0x04},

/* fps settings are here */
/* 10 fps */
/*{0xff, 0x01},{0x11, 0x01},{0x3d, 0x3a},{0x2b, 0x95},*/

/* 15 fps */
/*{0xff, 0x01},{0x11, 0x01},{0x3d, 0x38},{0x2b, 0x00},*/

/* 20 fps */
/*{0xff, 0x01},{0x11, 0x00},{0x3d, 0x3a},{0x2b, 0x95},*/

/* 25 fps */
{0xff, 0x01},{0x11, 0x00},{0x3d, 0x39},{0x2b, 0x3c},

/* 30 fps*/
/*{0xff, 0x01},{0x11, 0x01},{0x3d, 0x38},{0x2b, 0x00},*/

{0xFF, 0x00},{0xE0, 0x04},{0xE1, 0x67},{0xD7, 0x01},{0xDA, 0x00},
{0xD3, 0x82},{0xE0, 0x00},

{ OV2640_REG_TERM, OV2640_VAL_TERM }
};
const static struct ov2640_reg svga_yuv[] = { 
{0xff, 0x01},{0x12, 0x80},{0xff, 0x00},{0x2c, 0xff},{0x2e, 0xdf},
{0xff, 0x01},{0x3c, 0x32},{0x11, 0x00},{0x09, 0x02},{0x04, 0x28},
{0x13, 0xe5},{0x14, 0x48},{0x2c, 0x0c},{0x33, 0x78},{0x3a, 0x33},
{0x3b, 0xfb},{0x3e, 0x00},{0x43, 0x11},{0x16, 0x10},{0x39, 0x02},
{0x35, 0x88},{0x22, 0x0a},{0x37, 0x40},{0x23, 0x00},{0x34, 0xa0},
{0x36, 0x1a},{0x06, 0x02},{0x07, 0xc0},{0x0d, 0xb7},{0x0e, 0x01},
{0x4c, 0x00},{0x4a, 0x81},{0x21, 0x99},{0x24, 0x3a},{0x25, 0x32},
{0x26, 0x82},{0x5c, 0x00},{0x63, 0x00},{0x5d, 0x55},{0x5e, 0x7d},
{0x5f, 0x7d},{0x60, 0x55},{0x61, 0x70},{0x62, 0x80},{0x7c, 0x05},
{0x20, 0x80},{0x28, 0x30},{0x6c, 0x00},{0x6d, 0x80},{0x6e, 0x00},
{0x70, 0x02},{0x71, 0x94},{0x73, 0xc1},{0x3d, 0x34},{0x5a, 0x57},
{0x4f, 0xbb},{0x50, 0x9c},{0xff, 0x00},{0xe5, 0x7f},{0xf9, 0xc0},
{0x41, 0x24},{0xe0, 0x14},{0x76, 0xff},{0x33, 0xa0},{0x42, 0x20},
{0x43, 0x18},{0x4c, 0x00},{0x87, 0xd0},{0x88, 0x3f},{0xd7, 0x03},
{0xd9, 0x10},{0xd3, 0x82},{0xc8, 0x08},{0xc9, 0x80},{0x7c, 0x00},
{0x7d, 0x02},{0x7c, 0x03},{0x7d, 0x48},{0x7d, 0x48},{0x7c, 0x08},
{0x7d, 0x20},{0x7d, 0x10},{0x7d, 0x0e},{0x90, 0x00},{0x91, 0x0e},
{0x91, 0x1a},{0x91, 0x31},{0x91, 0x5a},{0x91, 0x69},{0x91, 0x75},
{0x91, 0x7e},{0x91, 0x88},{0x91, 0x8f},{0x91, 0x96},{0x91, 0xa3},
{0x91, 0xaf},{0x91, 0xc4},{0x91, 0xd7},{0x91, 0xe8},{0x91, 0x20},
{0x92, 0x00},{0x93, 0x06},{0x93, 0xe3},{0x93, 0x05},{0x93, 0x05},
{0x93, 0x00},{0x93, 0x02},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},
{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x96, 0x00},
{0x97, 0x08},{0x97, 0x19},{0x97, 0x02},{0x97, 0x0c},{0x97, 0x24},
{0x97, 0x30},{0x97, 0x28},{0x97, 0x26},{0x97, 0x02},{0x97, 0x98},
{0x97, 0x80},{0x97, 0x00},{0x97, 0x00},{0xc3, 0xed},{0xa4, 0x00},
{0xa8, 0x00},{0xc5, 0x11},{0xc6, 0x51},{0xbf, 0x80},{0xc7, 0x10},
{0xb6, 0x66},{0xb8, 0xa5},{0xb7, 0x64},{0xb9, 0x7c},{0xb3, 0xaf},
{0xb4, 0x97},{0xb5, 0xff},{0xb0, 0xc5},{0xb1, 0x94},{0xb2, 0x0f},
{0xc4, 0x5c},{0xc0, 0xc8},{0xc1, 0x96},{0x86, 0x1d},{0x50, 0x00},
{0x51, 0x90},{0x52, 0x18},{0x53, 0x00},{0x54, 0x00},{0x55, 0x88},
{0x57, 0x00},{0x5a, 0x90},{0x5b, 0x18},{0x5c, 0x05},{0xc3, 0xed},
{0x7f, 0x00},{0xda, 0x04},{0xe5, 0x1f},{0xe1, 0x67},{0xe0, 0x00},
{0xdd, 0xff},{0x05, 0x00},{0xff, 0x01},{0x11, 0x01},

//SVGA
{0xff, 0x01},{0x12, 0x40},{0x17, 0x11},{0x18, 0x43},{0x19, 0x00},
{0x1a, 0x4b},{0x32, 0x09},{0x4f, 0xca},{0x50, 0xa8},{0x5a, 0x23},
{0x6d, 0x00},{0x3d, 0x38},

{0x39, 0x12},{0x35, 0xda},{0x22, 0x1a},{0x37, 0xc3},{0x23, 0x00},
{0x34, 0xc0},{0x36, 0x1a},{0x06, 0x88},{0x07, 0xc0},{0x0d, 0x87},
{0x0e, 0x41},{0x4c, 0x00},{0x48, 0x00},{0x5B, 0x00},{0x42, 0x03},

{0xff, 0x00},{0xe0, 0x04},{0xc0, 0x64},{0xc1, 0x4B},{0x8c, 0x00},
{0x86, 0x1D},{0xd3, 0x82},{0xe0, 0x00},

/* 25 fps*/
{0xff, 0x01},{0x11, 0x00},{0x3d, 0x39},{0x2b, 0x3c},

//V422
{0xFF, 0x00},{0xE0, 0x04},{0xE1, 0x67},{0xD7, 0x01},{0xDA, 0x00},
{0xD3, 0x82},{0xE0, 0x00},

{ OV2640_REG_TERM, OV2640_VAL_TERM }
};

const static struct ov2640_reg sxga_yuv[] = { 
{0xff, 0x01},{0x12, 0x80},{0xff, 0x00},{0x2c, 0xff},{0x2e, 0xdf},
{0xff, 0x01},{0x3c, 0x32},{0x11, 0x00},{0x09, 0x02},{0x04, 0x28},
{0x13, 0xe5},{0x14, 0x48},{0x2c, 0x0c},{0x33, 0x78},{0x3a, 0x33},
{0x3b, 0xfb},{0x3e, 0x00},{0x43, 0x11},{0x16, 0x10},{0x39, 0x02},
{0x35, 0x88},{0x22, 0x0a},{0x37, 0x40},{0x23, 0x00},{0x34, 0xa0},
{0x36, 0x1a},{0x06, 0x02},{0x07, 0xc0},{0x0d, 0xb7},{0x0e, 0x01},
{0x4c, 0x00},{0x4a, 0x81},{0x21, 0x99},{0x24, 0x3a},{0x25, 0x32},
{0x26, 0x82},{0x5c, 0x00},{0x63, 0x00},{0x5d, 0x55},{0x5e, 0x7d},
{0x5f, 0x7d},{0x60, 0x55},{0x61, 0x70},{0x62, 0x80},{0x7c, 0x05},
{0x20, 0x80},{0x28, 0x30},{0x6c, 0x00},{0x6d, 0x80},{0x6e, 0x00},
{0x70, 0x02},{0x71, 0x94},{0x73, 0xc1},{0x3d, 0x34},{0x5a, 0x57},
{0x4f, 0xbb},{0x50, 0x9c},{0xff, 0x00},{0xe5, 0x7f},{0xf9, 0xc0},
{0x41, 0x24},{0xe0, 0x14},{0x76, 0xff},{0x33, 0xa0},{0x42, 0x20},
{0x43, 0x18},{0x4c, 0x00},{0x87, 0xd0},{0x88, 0x3f},{0xd7, 0x03},
{0xd9, 0x10},{0xd3, 0x82},{0xc8, 0x08},{0xc9, 0x80},{0x7c, 0x00},
{0x7d, 0x02},{0x7c, 0x03},{0x7d, 0x48},{0x7d, 0x48},{0x7c, 0x08},
{0x7d, 0x20},{0x7d, 0x10},{0x7d, 0x0e},{0x90, 0x00},{0x91, 0x0e},
{0x91, 0x1a},{0x91, 0x31},{0x91, 0x5a},{0x91, 0x69},{0x91, 0x75},
{0x91, 0x7e},{0x91, 0x88},{0x91, 0x8f},{0x91, 0x96},{0x91, 0xa3},
{0x91, 0xaf},{0x91, 0xc4},{0x91, 0xd7},{0x91, 0xe8},{0x91, 0x20},
{0x92, 0x00},{0x93, 0x06},{0x93, 0xe3},{0x93, 0x05},{0x93, 0x05},
{0x93, 0x00},{0x93, 0x02},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},
{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x93, 0x00},{0x96, 0x00},
{0x97, 0x08},{0x97, 0x19},{0x97, 0x02},{0x97, 0x0c},{0x97, 0x24},
{0x97, 0x30},{0x97, 0x28},{0x97, 0x26},{0x97, 0x02},{0x97, 0x98},
{0x97, 0x80},{0x97, 0x00},{0x97, 0x00},{0xc3, 0xed},{0xa4, 0x00},
{0xa8, 0x00},{0xc5, 0x11},{0xc6, 0x51},{0xbf, 0x80},{0xc7, 0x10},
{0xb6, 0x66},{0xb8, 0xa5},{0xb7, 0x64},{0xb9, 0x7c},{0xb3, 0xaf},
{0xb4, 0x97},{0xb5, 0xff},{0xb0, 0xc5},{0xb1, 0x94},{0xb2, 0x0f},
{0xc4, 0x5c},{0xc0, 0xc8},{0xc1, 0x96},{0x86, 0x1d},{0x50, 0x00},
{0x51, 0x90},{0x52, 0x18},{0x53, 0x00},{0x54, 0x00},{0x55, 0x88},
{0x57, 0x00},{0x5a, 0x90},{0x5b, 0x18},{0x5c, 0x05},{0xc3, 0xed},
{0x7f, 0x00},{0xda, 0x04},{0xe5, 0x1f},{0xe1, 0x67},{0xe0, 0x00},
{0xdd, 0xff},{0x05, 0x00},{0xff, 0x01},{0x11, 0x00},


//SXGA
{0xff, 0x00},{0xc0, 0xc8},{0xc1, 0x96},{0x8c, 0x00},{0x86, 0x3d},
{0x50, 0x00},{0x51, 0x90},{0x52, 0x2c},{0x53, 0x00},{0x54, 0x00},
{0x55, 0x88},{0x5a, 0x40},{0x5b, 0x00},{0x5c, 0x05},{0xd3, 0x82},

//V422
{0xFF, 0x00},{0xE0, 0x04},{0xE1, 0x67},{0xD7, 0x01},{0xDA, 0x00},
{0xD3, 0x82},{0xE0, 0x00},

{ OV2640_REG_TERM, OV2640_VAL_TERM }
};

/* 565 configs */
const static struct ov2640_reg qqcif_565[] = { };
const static struct ov2640_reg qqvga_565[] = { };
const static struct ov2640_reg qcif_565[] = { };
const static struct ov2640_reg qvga_565[] = { };
const static struct ov2640_reg cif_565[] = { };
const static struct ov2640_reg vga_565[] = { };
const static struct ov2640_reg svga_565[] = { };
const static struct ov2640_reg sxga_565[] = { };

/* 555 configs */
const static struct ov2640_reg qqcif_555[] = { };
const static struct ov2640_reg qqvga_555[] = { };
const static struct ov2640_reg qcif_555[] = { };
const static struct ov2640_reg qvga_555[] = { };
const static struct ov2640_reg cif_555[] = { };
const static struct ov2640_reg vga_555[] = { };
const static struct ov2640_reg svga_555[] = { };
const static struct ov2640_reg sxga_555[] = { };

const static struct ov2640_reg *
	ov2640_reg_init[NUM_PIXEL_FORMATS][NUM_IMAGE_SIZES] =
{
 { qqcif_yuv, qqvga_yuv, qcif_yuv, qvga_yuv, cif_yuv, vga_yuv, svga_yuv, sxga_yuv },
 { qqcif_565, qqvga_565, qcif_565, qvga_565, cif_565, vga_565, svga_565, sxga_565 },
 { qqcif_555, qqvga_555, qcif_555, qvga_555, cif_555, vga_555, svga_555, sxga_555 },
};
//static struct i2c_driver ov2640_driver;

static inline struct ov2640 *to_state(struct v4l2_subdev *sd)
{
	return container_of(sd, struct ov2640, sd);
}


/*
 * Write a value to a register in an OV2640 sensor device.
 * Returns zero if successful, or non-zero otherwise.
 */
static int
ov2640_write_reg(struct v4l2_subdev *sd, u8 reg, u8 val)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	int err;
	struct i2c_msg msg[1];
	unsigned char data[2];
	
	if (!client->adapter)
		return -ENODEV;

	msg->addr = client->addr;
	msg->flags = 0;
	msg->len = 2;
	msg->buf = data;
	data[0] = reg;
	data[1] = val;
	err = i2c_transfer(client->adapter, msg, 1);
	if (err >= 0)
		return 0;
	return err;
}
/*
 * Read a value from a register in an OV2640 sensor device.
 * The value is returned in 'val'.
 * Returns zero if successful, or non-zero otherwise.
 */
static int
ov2640_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *val)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	int err;
	struct i2c_msg msg[1];
	unsigned char data[1];

	if (!client->adapter)
		return -ENODEV;

	msg->addr = client->addr;
	msg->flags = 0;
	msg->len = 1;
	msg->buf = data;
	*data = reg;
	err = i2c_transfer(client->adapter, msg, 1);
	if (err >= 0) {
		msg->flags = I2C_M_RD;
		err = i2c_transfer(client->adapter, msg, 1);
	}
	if (err >= 0) {
		*val = *data;
		return 0;
	}
	return err;
}


/* fct use to initialize all the registers */
static int
ov2640_write_regs(struct v4l2_subdev *sd, const struct ov2640_reg reglist[])
{
	int err;
	const struct ov2640_reg *next = reglist;

	while (!((next->reg == OV2640_REG_TERM)
		&& (next->val == OV2640_VAL_TERM))) {
		err = ov2640_write_reg(sd, next->reg, next->val);
		udelay(100);
		if (err)
			return err;
		next++;
	}
	return 0;
}


/*
 * Find the best match for a requested image capture size.  The best match
 * is chosen as the nearest match that has the same number or fewer pixels
 * as the requested size, or the smallest image size if the requested size
 * has fewer pixels than the smallest image.
 */
static enum image_size
ov2640_find_size(unsigned int width, unsigned int height)
{
	enum image_size isize;
	unsigned long pixels = width*height;

	for (isize = QQCIF; isize < SXGA; isize++) {
		if (ov2640_sizes[isize + 1].height *
			ov2640_sizes[isize + 1].width > pixels)
			return isize;
	}
	return SXGA;
}


static int ov2640_init(struct v4l2_subdev *sd, u32 val)
{
	return ov2640_write_regs(sd, vga_yuv);
}


static int ov2640_get_format(struct atmel_isi_camera *cam,
			   struct atmel_isi_format *fmt)
{
	int err = 0;

	return err;
}

static int ov2640_s_fmt(struct v4l2_subdev *sd,
			struct v4l2_mbus_framefmt *mf)
{
	int err;
	printk(KERN_INFO "ov2640 s fmt\n");

	/* For time being only YUV422 vga */
	err = ov2640_write_regs(sd, vga_yuv);

	return err;
}

static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
{
	int err = 0;
	printk(KERN_INFO "ov2640 start frame\n");	
	/* Set the color bar test mode: to test wether the sensor is
	 * properly configure or not.
	 */
	/*err = ov2640_write_reg(&info->sd, 0xFF, 0x01);
	err = ov2640_write_reg(&info->sd, OV2640_COM7, OV2640_COLORBAR);*/

	return err;
}


static int ov2640_reset(struct ov2640 *is)
{
	int err;
	
	err = ov2640_write_reg(&is->sd, 0XFF, 0x01);
	/* Reset Pin = COM7 bit 7*/
	err = ov2640_write_reg(&is->sd, OV2640_COM7, OV2640_RESET);
	if (err)
		pr_debug("ov2640_reset failed\n");
	return err;
}


static int ov2640_detect(struct v4l2_subdev *sd)
{
	int err = 0;
	u8 midh, midl, pidh;
	
	/* Try to identify the camera */
	if (ov2640_read_reg(sd, OV2640_MIDH, &midh))
		return -ENODEV;
	if (ov2640_read_reg(sd, OV2640_MIDL, &midl))
		return -ENODEV;
	if (ov2640_read_reg(sd, OV2640_PIDH, &pidh))
		return -ENODEV;

	if ((midh != OV2640_MIDH_MAGIC)
		|| (midl != OV2640_MIDL_MAGIC)
		|| (pidh != OV2640_PID_MAGIC))
		/*
		 * We didn't read the values we expected, so
		 * this must not be an OV2640.
		 */
		return -ENODEV;
	
	return err;
}


static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
		struct v4l2_dbg_chip_ident *chip)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV2640, 0);
}
/* ----------------------------------------------------------------------- */

static const struct v4l2_subdev_core_ops ov2640_core_ops = {
	.g_chip_ident = ov2640_g_chip_ident,	
	.reset = ov2640_reset,
	.init = ov2640_init,
};

static const struct v4l2_subdev_video_ops ov2640_video_ops = {
	.s_stream	= ov2640_s_stream,
	.s_fmt	 	= ov2640_s_fmt,
};

static const struct v4l2_subdev_ops ov2640_ops = {
	.core = &ov2640_core_ops,
	.video = &ov2640_video_ops,
};

/* ----------------------------------------------------------------------- */
static struct clk *mclk;

static int ov2640_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct v4l2_subdev *sd;
	struct ov2640 *info;
	int ret;
	
	/*
	 * Set up the master clock, if available. If clk_get() fails,
	 * this hopefully means that the board generates a suitable
	 * master clock some other way, which is fine by us.
	 *
	 * We need to do this before probing the i2c bus, as the
	 * camera won't ack any messages when it doesn't have a clock.
	 */

	mclk = clk_get(NULL, mclk_name);
	if (!IS_ERR(mclk)) {
		clk_enable(mclk);
		pr_debug("isi_clk enable\n");
	}
	else {
		mclk = NULL;
		pr_debug("no isi clock enable\n");
	}

	info = kzalloc(sizeof(struct ov2640), GFP_KERNEL);
	if (info == NULL)
		return -ENOMEM;
	sd = &info->sd;
	v4l2_i2c_subdev_init(sd, client, &ov2640_ops);

	/* Make sure it's an ov2640 */
	ret =ov2640_detect(sd);
	if (ret) {
		pr_debug("chip found @ 0x%x (%s) is not an ov2640 chip.\n",
			client->addr << 1, client->adapter->name);
		kfree(info);
		return ret;
	}

	/* default config */
	ov2640_write_regs(sd, vga_yuv);

	v4l_info(client, "chip found @ 0x%02x (%s)\n",
			client->addr << 1, client->adapter->name);

	return 0;
}


static int ov2640_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd = i2c_get_clientdata(client);

	v4l2_device_unregister_subdev(sd);
	kfree(to_state(sd));
	return 0;
}


static const struct i2c_device_id ov2640_i2c_id[] = {
	{ "ov2640", 0 },
	{ }
};


MODULE_DEVICE_TABLE(i2c, ov2640_i2c_id);

static struct v4l2_i2c_driver_data v4l2_i2c_data = {
	.name = "ov2640",
	.probe = ov2640_probe,
	.remove = ov2640_remove,
	.id_table = ov2640_i2c_id,
};

MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@xxxxxxxxx>");
MODULE_DESCRIPTION("Omnivision ov955 Image Sensor driver");
MODULE_LICENSE("GPL");

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux