* question about v4l2_subdev
@ 2010-05-31 15:38 Sedji Gaouaou
2010-05-31 18:19 ` Andy Walls
0 siblings, 1 reply; 7+ messages in thread
From: Sedji Gaouaou @ 2010-05-31 15:38 UTC (permalink / raw)
To: Guennadi Liakhovetski, Linux Media Mailing List, linux-input
[-- 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");
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: question about v4l2_subdev
2010-05-31 15:38 question about v4l2_subdev Sedji Gaouaou
@ 2010-05-31 18:19 ` Andy Walls
2010-06-01 8:14 ` Sedji Gaouaou
0 siblings, 1 reply; 7+ messages in thread
From: Andy Walls @ 2010-05-31 18:19 UTC (permalink / raw)
To: Sedji Gaouaou
Cc: Guennadi Liakhovetski, Linux Media Mailing List, linux-input
On Mon, 2010-05-31 at 17:38 +0200, Sedji Gaouaou wrote:
> 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.
That depends. Is the atmel video driver instantiating a v4l_device for
itself, or is it using some frame work that instantiates one for it?
The details of using the v4l2 framework are in
linux/Documentation/video4linux/v4l2-framework.txt
but, typically
1. Something first should call v4l2_device_register() on a v4l2_device
object. (Typically there is only one v4l2_device object per "bridge"
chip between the PCI, PCIe, or USB bus and the subdevices, even if that
bridge chip has more than one I2C master implementation.)
2. Then, for subdevices connected to the bridge chip via I2C, something
needs to call v4l2_i2c_new_subdev() with the v4l2_device pointer as one
of the arguments, to get back a v4l2_subdevice instance pointer.
3. After that, v4l2_subdev_call() with the v4l2_subdev pointer as one of
the arguments can be used to invoke the subdevice methods.
TV Video capture drivers do this work themselves. Drivers using a
camera framework may have the framework doing some of the work for them.
Regards,
Andy
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: question about v4l2_subdev
2010-05-31 18:19 ` Andy Walls
@ 2010-06-01 8:14 ` Sedji Gaouaou
2010-06-01 14:04 ` Sedji Gaouaou
2010-06-05 1:27 ` Andy Walls
0 siblings, 2 replies; 7+ messages in thread
From: Sedji Gaouaou @ 2010-06-01 8:14 UTC (permalink / raw)
To: Andy Walls; +Cc: Guennadi Liakhovetski, Linux Media Mailing List, linux-input
Hi,
>
> 1. Something first should call v4l2_device_register() on a v4l2_device
> object. (Typically there is only one v4l2_device object per "bridge"
> chip between the PCI, PCIe, or USB bus and the subdevices, even if that
> bridge chip has more than one I2C master implementation.)
>
> 2. Then, for subdevices connected to the bridge chip via I2C, something
> needs to call v4l2_i2c_new_subdev() with the v4l2_device pointer as one
> of the arguments, to get back a v4l2_subdevice instance pointer.
>
> 3. After that, v4l2_subdev_call() with the v4l2_subdev pointer as one of
> the arguments can be used to invoke the subdevice methods.
>
> TV Video capture drivers do this work themselves. Drivers using a
> camera framework may have the framework doing some of the work for them.
>
>
> Regards,
> Andy
>
>
>
Is there a sensor driver which is using this method?
To write the ov2640 driver I have just copied the ov7670.c file, and I
didn't find the v4l2_i2c_new_subdev in it...
Regards,
Sedji
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: question about v4l2_subdev
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
1 sibling, 1 reply; 7+ messages in thread
From: Sedji Gaouaou @ 2010-06-01 14:04 UTC (permalink / raw)
To: Sedji Gaouaou
Cc: Andy Walls, Guennadi Liakhovetski, Linux Media Mailing List,
linux-input
Hi,
Sorry to bother you again, but here is the situation:
I have 2 drivers: an ov2640 driver and my atmel driver.
Basically the ov2640 driver is the same as the ov7670 driver.
So what I don't know is how to call the ov2640 functions(such as set
format) in my atmel driver.
In the ov2640 I used the function: v4l2_i2c_subdev_init, and in the
atmel driver I used v4l2_device_register.
But I don't know where I should use the v4l2_i2c_new_subdev function,
and how to link my atmel video struct to the i2c sensor.
Is there any examples in linux?
Regards,
Sedji
Le 6/1/2010 10:14 AM, Sedji Gaouaou a écrit :
> Hi,
>
>
>>
>> 1. Something first should call v4l2_device_register() on a v4l2_device
>> object. (Typically there is only one v4l2_device object per "bridge"
>> chip between the PCI, PCIe, or USB bus and the subdevices, even if that
>> bridge chip has more than one I2C master implementation.)
>>
>> 2. Then, for subdevices connected to the bridge chip via I2C, something
>> needs to call v4l2_i2c_new_subdev() with the v4l2_device pointer as one
>> of the arguments, to get back a v4l2_subdevice instance pointer.
>>
>> 3. After that, v4l2_subdev_call() with the v4l2_subdev pointer as one of
>> the arguments can be used to invoke the subdevice methods.
>>
>> TV Video capture drivers do this work themselves. Drivers using a
>> camera framework may have the framework doing some of the work for them.
>>
>>
>> Regards,
>> Andy
>>
>>
>>
>
>
> Is there a sensor driver which is using this method?
>
> To write the ov2640 driver I have just copied the ov7670.c file, and I
> didn't find the v4l2_i2c_new_subdev in it...
>
> Regards,
> Sedji
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: question about v4l2_subdev
2010-06-01 14:04 ` Sedji Gaouaou
@ 2010-06-01 20:56 ` David Ellingsworth
0 siblings, 0 replies; 7+ messages in thread
From: David Ellingsworth @ 2010-06-01 20:56 UTC (permalink / raw)
To: Sedji Gaouaou
Cc: Andy Walls, Guennadi Liakhovetski, Linux Media Mailing List,
linux-input
On Tue, Jun 1, 2010 at 10:04 AM, Sedji Gaouaou <sedji.gaouaou@atmel.com> wrote:
> Hi,
>
> Sorry to bother you again, but here is the situation:
> I have 2 drivers: an ov2640 driver and my atmel driver.
> Basically the ov2640 driver is the same as the ov7670 driver.
>
> So what I don't know is how to call the ov2640 functions(such as set format)
> in my atmel driver.
>
> In the ov2640 I used the function: v4l2_i2c_subdev_init, and in the atmel
> driver I used v4l2_device_register.
>
> But I don't know where I should use the v4l2_i2c_new_subdev function, and
> how to link my atmel video struct to the i2c sensor.
>
> Is there any examples in linux?
>
> Regards,
> Sedji
>
If I understand what you're saying, ov2640 and ovv7670 are both video
drivers but they have shared functionality. If the shared
functionality is in the form of controlling say an i2c device of some
sorts then you should implement that functionality as a subdev.
Otherwise, you should extract the shared functionality into its own
module that can be utilized by both drivers (there are many examples
of this within the kernel).
Regards,
David Ellingsworth
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: question about v4l2_subdev
2010-06-01 8:14 ` Sedji Gaouaou
2010-06-01 14:04 ` Sedji Gaouaou
@ 2010-06-05 1:27 ` Andy Walls
2010-06-07 10:01 ` Sedji Gaouaou
1 sibling, 1 reply; 7+ messages in thread
From: Andy Walls @ 2010-06-05 1:27 UTC (permalink / raw)
To: Sedji Gaouaou
Cc: Guennadi Liakhovetski, Linux Media Mailing List, linux-input
On Tue, 2010-06-01 at 10:14 +0200, Sedji Gaouaou wrote:
> Hi,
>
>
> >
> > 1. Something first should call v4l2_device_register() on a v4l2_device
> > object. (Typically there is only one v4l2_device object per "bridge"
> > chip between the PCI, PCIe, or USB bus and the subdevices, even if that
> > bridge chip has more than one I2C master implementation.)
> >
> > 2. Then, for subdevices connected to the bridge chip via I2C, something
> > needs to call v4l2_i2c_new_subdev() with the v4l2_device pointer as one
> > of the arguments, to get back a v4l2_subdevice instance pointer.
> >
> > 3. After that, v4l2_subdev_call() with the v4l2_subdev pointer as one of
> > the arguments can be used to invoke the subdevice methods.
> >
> > TV Video capture drivers do this work themselves. Drivers using a
> > camera framework may have the framework doing some of the work for them.
> >
> >
> > Regards,
> > Andy
> >
> >
> >
>
>
> Is there a sensor driver which is using this method?
>
> To write the ov2640 driver I have just copied the ov7670.c file, and I
> didn't find the v4l2_i2c_new_subdev in it...
Subdev driver modules, like ov7670.c, don't attach themselves; the
bridge chip driver attaches an instance to an I2C bus.
Look at
drivers/media/video/cafe_ccic.c
And examine cafe_pci_probe() and the definition and use of the
sensor_call() macro.
Also note
$ grep -Ril ov7670 drivers/media/video/*
will show you in what drivers, the ov7670 might be used.
Regards,
Andy
> Regards,
> Sedji
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: question about v4l2_subdev
2010-06-05 1:27 ` Andy Walls
@ 2010-06-07 10:01 ` Sedji Gaouaou
0 siblings, 0 replies; 7+ messages in thread
From: Sedji Gaouaou @ 2010-06-07 10:01 UTC (permalink / raw)
To: Andy Walls; +Cc: Guennadi Liakhovetski, Linux Media Mailing List, linux-input
Hi,
>
> Look at
>
> drivers/media/video/cafe_ccic.c
>
> And examine cafe_pci_probe() and the definition and use of the
> sensor_call() macro.
>
> Also note
>
> $ grep -Ril ov7670 drivers/media/video/*
>
> will show you in what drivers, the ov7670 might be used.
>
I had a look at cafe_ccic.c and also at vpif_capture.c.
I tried to use "v4l2_i2c_new_subdev_board", but at boot time I have the
following error:
i2c i2c-0: Failed to register i2c client ov2640 at 0x30 (-16)
I don't understand where it could come from, I pass the proper
i2c_board_info struct, and it seems to check the proper i2c address,
since it is not working.
Basically I do like cafe_ccic.c execpt that I use the
v4l2_i2c_new_subdev_board instead of v4l2_i2c_new_subdev...
Any idea why I can't detect the sensor here?
Regards,
Sedji
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-06-07 10:01 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-31 15:38 question about v4l2_subdev Sedji Gaouaou
2010-05-31 18:19 ` 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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).