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.gaou...@atmel.com>");
MODULE_DESCRIPTION("Omnivision ov955 Image Sensor driver");
MODULE_LICENSE("GPL");

Reply via email to