From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sedji Gaouaou Subject: question about v4l2_subdev Date: Mon, 31 May 2010 17:38:51 +0200 Message-ID: <4C03D80B.5090009@atmel.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------080800000501040606050409" Return-path: Received: from newsmtp5.atmel.com ([204.2.163.5]:26610 "EHLO sjogate2.atmel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751152Ab0EaPjI (ORCPT ); Mon, 31 May 2010 11:39:08 -0400 Sender: linux-input-owner@vger.kernel.org List-Id: linux-input@vger.kernel.org To: Guennadi Liakhovetski , Linux Media Mailing List , linux-input@vger.kernel.org This is a multi-part message in MIME format. --------------080800000501040606050409 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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 --------------080800000501040606050409 Content-Type: text/plain; name="ov2640_atmel.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ov2640_atmel.c" /* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #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 "); MODULE_DESCRIPTION("Omnivision ov955 Image Sensor driver"); MODULE_LICENSE("GPL"); --------------080800000501040606050409--