From: Sedji Gaouaou <sedji.gaouaou@atmel.com>
To: Guennadi Liakhovetski <g.liakhovetski@gmx.de>,
Linux Media Mailing List <linux-media@vger.kernel.org>,
linux-input@vger.kernel.org
Subject: question about v4l2_subdev
Date: Mon, 31 May 2010 17:38:51 +0200 [thread overview]
Message-ID: <4C03D80B.5090009@atmel.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 391 bytes --]
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
[-- Attachment #2: ov2640_atmel.c --]
[-- Type: text/plain, Size: 24915 bytes --]
/*
* 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@atmel.com>");
MODULE_DESCRIPTION("Omnivision ov955 Image Sensor driver");
MODULE_LICENSE("GPL");
next reply other threads:[~2010-05-31 15:39 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-31 15:38 Sedji Gaouaou [this message]
2010-05-31 18:19 ` question about v4l2_subdev Andy Walls
2010-06-01 8:14 ` Sedji Gaouaou
2010-06-01 14:04 ` Sedji Gaouaou
2010-06-01 20:56 ` David Ellingsworth
2010-06-05 1:27 ` Andy Walls
2010-06-07 10:01 ` Sedji Gaouaou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C03D80B.5090009@atmel.com \
--to=sedji.gaouaou@atmel.com \
--cc=g.liakhovetski@gmx.de \
--cc=linux-input@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.