]> code.ossystems Code Review - openembedded-core.git/blob
cd4edb92172c6d2db64ad49e125127b7817c3aee
[openembedded-core.git] /
1 From 0d55b08388f12c7c22cae9c6c745995d051624ba Mon Sep 17 00:00:00 2001
2 From: Zheng Ba <zheng.ba@intel.com>
3 Date: Thu, 1 Apr 2010 16:29:43 +0800
4 Subject: [PATCH 3/3] Moorestown Camera Imaging driver Beta 10.0
5
6 Patch-mainline: 2.6.35?
7
8 Changes from Beta 9.0:
9 1. Fixed hsd sighting:
10         3469638 3469639 3469710 3469822 (high)
11         3469697 (medium)
12
13 Changes from Beta 8.0:
14 1. Fixed hsd sighting
15         3469056 3469058 (critical)
16         3469705 3469696 3469709 3469510 (medium)
17
18 Changes from Beta 7.0:
19 1. Fixed hsd sighting 3469681,3469682,3469683 (high)
20
21 Changes from Beta 6.0:
22 1. Fixed hsd sighting 3469668 (high)
23 2. Fixed ov5630 v4l2 view-finding dark issue
24 3. Enabled support for popular v4l2 applications (cheese, skype, ffmpeg)
25
26 Changes from Beta 5.1:
27 1. Fixed CRITICAL sighting 3469558 -- ciapp fails to launch with segment fault
28 2. Fixed HIGH sighting 3479513 -- ov5630 AWB unstable
29 3. Improved KMOT sensor 720p fps from 30 to 40
30
31 Changes from Beta 5.0:
32 Fixed a critical issue of camera driver not loading -- hsd 3469557
33
34 Main changes from Beta 4.0:
35 Fixed 4 HSD sightings: 3469392,3469099,3469470,3469500
36
37 Main changes from Beta 3.0:
38 Fixed 7 HSD sightings: 3469264,3469112,3469395,3469103,3469105,3469471,3469484
39
40 Main changes from Beta 2.0:
41 Fixed 6 HSD sightings: 3469047,3469315,3469317,3469101,3468409,3469391
42
43 Main changes from Beta 1.1:
44 1. Added interrupt mode for jpeg capture and KMOT viewfinding
45 2. Fixed HSD sighting 3469228 and 3469147
46
47 Main changes from Alpha2:
48 Enabled MIPI interface in ISP driver and KMOT sensor s5k4e1.
49 Enabled FIFO in ISP driver, which doubled the fps in view-finding mode.
50 Enabled Subdev Framework in CI kernel driver.
51 Enabled AF Continuous Mode.
52 Enabled AE scene evaluation.
53
54 Enabled the camera drivers in kernel:
55 Device Drivers --> Multimedia support --> Video For Linux
56 Device Drivers --> Mulitmedia support --> Video capture adapters -->
57 --> Moorestown Langwell Camera Imaging Subsystem support.
58
59 Kernel configs:
60 1. camera driver depends on GPIO library and I2C driver.
61 CONFIG_GENERIC_GPIO=y
62 CONFIG_I2C=y
63 CONFIG_GPIOLIB=y
64 2. camera driver depends on videobuf-core and videobuf-dma-contig.
65 VIDEOBUF_GEN=y
66 VIDEOBUF_DMA_CONTIG=y
67 3. enable multimedia support and video capture.
68 CONFIG_MEDIA_SUPPORT=y
69 CONFIG_VIDEO_DEV=y
70 CONFIG_VIDEO_V4L2_COMMON=y
71 CONFIG_VIDEO_MEDIA=y
72 CONFIG_VIDEO_V4L2=y
73 4. camera drivers incluing ISP, 5630, 5630-motor, s5k4e1, s5k4e1-motor, 2650,
74 9665, flash.
75 CONFIG_VIDEO_MRSTCI=y
76 CONFIG_VIDEO_MRST_ISP=y
77 CONFIG_VIDEO_MRST_OV5630=y
78 CONFIG_VIDEO_MRST_OV5630_MOTOR=y
79 CONFIG_VIDEO_MRST_S5K4E1=y
80 CONFIG_VIDEO_MRST_S5K4E1_MOTOR=y
81 CONFIG_VIDEO_MRST_FLASH=y
82 CONFIG_VIDEO_MRST_OV2650=y
83 CONFIG_VIDEO_MRST_OV9665=y
84 Signed-off-by: Zheng Ba <zheng.ba@intel.com>
85 ---
86  drivers/media/video/mrstci/mrstflash/Kconfig       |    9 +
87  drivers/media/video/mrstci/mrstflash/Makefile      |    3 +
88  drivers/media/video/mrstci/mrstflash/mrstflash.c   |  150 +++
89  drivers/media/video/mrstci/mrstov2650/Kconfig      |    9 +
90  drivers/media/video/mrstci/mrstov2650/Makefile     |    3 +
91  drivers/media/video/mrstci/mrstov2650/mrstov2650.c | 1190 ++++++++++++++++++++
92  drivers/media/video/mrstci/mrstov2650/ov2650.h     |  766 +++++++++++++
93  drivers/media/video/mrstci/mrstov5630/Kconfig      |    9 +
94  drivers/media/video/mrstci/mrstov5630/Makefile     |    4 +
95  drivers/media/video/mrstci/mrstov5630/ov5630.c     | 1153 +++++++++++++++++++
96  drivers/media/video/mrstci/mrstov5630/ov5630.h     |  672 +++++++++++
97  .../media/video/mrstci/mrstov5630_motor/Kconfig    |    9 +
98  .../media/video/mrstci/mrstov5630_motor/Makefile   |    3 +
99  .../mrstci/mrstov5630_motor/mrstov5630_motor.c     |  428 +++++++
100  .../video/mrstci/mrstov5630_motor/ov5630_motor.h   |   86 ++
101  drivers/media/video/mrstci/mrstov9665/Kconfig      |    9 +
102  drivers/media/video/mrstci/mrstov9665/Makefile     |    3 +
103  drivers/media/video/mrstci/mrstov9665/mrstov9665.c |  972 ++++++++++++++++
104  drivers/media/video/mrstci/mrstov9665/ov9665.h     |  263 +++++
105  drivers/media/video/mrstci/mrsts5k4e1/Kconfig      |    9 +
106  drivers/media/video/mrstci/mrsts5k4e1/Makefile     |    3 +
107  drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.c | 1024 +++++++++++++++++
108  drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.h |  662 +++++++++++
109  .../media/video/mrstci/mrsts5k4e1_motor/Kconfig    |    9 +
110  .../media/video/mrstci/mrsts5k4e1_motor/Makefile   |    3 +
111  .../mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.c     |  430 +++++++
112  .../mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.h     |  102 ++
113  27 files changed, 7983 insertions(+), 0 deletions(-)
114  create mode 100644 drivers/media/video/mrstci/mrstflash/Kconfig
115  create mode 100644 drivers/media/video/mrstci/mrstflash/Makefile
116  create mode 100644 drivers/media/video/mrstci/mrstflash/mrstflash.c
117  create mode 100644 drivers/media/video/mrstci/mrstov2650/Kconfig
118  create mode 100644 drivers/media/video/mrstci/mrstov2650/Makefile
119  create mode 100644 drivers/media/video/mrstci/mrstov2650/mrstov2650.c
120  create mode 100644 drivers/media/video/mrstci/mrstov2650/ov2650.h
121  create mode 100644 drivers/media/video/mrstci/mrstov5630/Kconfig
122  create mode 100644 drivers/media/video/mrstci/mrstov5630/Makefile
123  create mode 100644 drivers/media/video/mrstci/mrstov5630/ov5630.c
124  create mode 100644 drivers/media/video/mrstci/mrstov5630/ov5630.h
125  create mode 100644 drivers/media/video/mrstci/mrstov5630_motor/Kconfig
126  create mode 100644 drivers/media/video/mrstci/mrstov5630_motor/Makefile
127  create mode 100644 drivers/media/video/mrstci/mrstov5630_motor/mrstov5630_motor.c
128  create mode 100644 drivers/media/video/mrstci/mrstov5630_motor/ov5630_motor.h
129  create mode 100644 drivers/media/video/mrstci/mrstov9665/Kconfig
130  create mode 100644 drivers/media/video/mrstci/mrstov9665/Makefile
131  create mode 100644 drivers/media/video/mrstci/mrstov9665/mrstov9665.c
132  create mode 100644 drivers/media/video/mrstci/mrstov9665/ov9665.h
133  create mode 100755 drivers/media/video/mrstci/mrsts5k4e1/Kconfig
134  create mode 100644 drivers/media/video/mrstci/mrsts5k4e1/Makefile
135  create mode 100755 drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.c
136  create mode 100755 drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.h
137  create mode 100755 drivers/media/video/mrstci/mrsts5k4e1_motor/Kconfig
138  create mode 100644 drivers/media/video/mrstci/mrsts5k4e1_motor/Makefile
139  create mode 100644 drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.c
140  create mode 100644 drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.h
141
142 diff --git a/drivers/media/video/mrstci/mrstflash/Kconfig b/drivers/media/video/mrstci/mrstflash/Kconfig
143 new file mode 100644
144 index 0000000..72099c5
145 --- /dev/null
146 +++ b/drivers/media/video/mrstci/mrstflash/Kconfig
147 @@ -0,0 +1,9 @@
148 +config VIDEO_MRST_FLASH
149 +       tristate "Moorestown flash"
150 +       depends on I2C && VIDEO_MRST_ISP
151 +
152 +       ---help---
153 +         Say Y here if your platform support moorestown flash.
154 +
155 +         To compile this driver as a module, choose M here: the
156 +         module will be called mrstov2650.ko.
157 diff --git a/drivers/media/video/mrstci/mrstflash/Makefile b/drivers/media/video/mrstci/mrstflash/Makefile
158 new file mode 100644
159 index 0000000..068f638
160 --- /dev/null
161 +++ b/drivers/media/video/mrstci/mrstflash/Makefile
162 @@ -0,0 +1,3 @@
163 +obj-$(CONFIG_VIDEO_MRST_FLASH)  += mrstflash.o
164 +
165 +EXTRA_CFLAGS   +=      -I$(src)/../include
166 diff --git a/drivers/media/video/mrstci/mrstflash/mrstflash.c b/drivers/media/video/mrstci/mrstflash/mrstflash.c
167 new file mode 100644
168 index 0000000..5611e6b
169 --- /dev/null
170 +++ b/drivers/media/video/mrstci/mrstflash/mrstflash.c
171 @@ -0,0 +1,150 @@
172 +/*
173 + * Support for Moorestown Langwell Camera Imaging camera flash.
174 + *
175 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
176 + *
177 + * This program is free software; you can redistribute it and/or
178 + * modify it under the terms of the GNU General Public License version
179 + * 2 as published by the Free Software Foundation.
180 + *
181 + * This program is distributed in the hope that it will be useful,
182 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
183 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
184 + * GNU General Public License for more details.
185 + *
186 + * You should have received a copy of the GNU General Public License
187 + * along with this program; if not, write to the Free Software
188 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
189 + * 02110-1301, USA.
190 + *
191 + *
192 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
193 + */
194 +
195 +#include <linux/module.h>
196 +#include <linux/types.h>
197 +#include <linux/kernel.h>
198 +#include <linux/mm.h>
199 +#include <linux/string.h>
200 +#include <linux/errno.h>
201 +#include <linux/init.h>
202 +#include <linux/kmod.h>
203 +#include <linux/device.h>
204 +#include <linux/delay.h>
205 +#include <linux/fs.h>
206 +#include <linux/init.h>
207 +#include <linux/slab.h>
208 +#include <linux/delay.h>
209 +#include <linux/i2c.h>
210 +#include <linux/gpio.h>
211 +#include <linux/videodev2.h>
212 +#include <media/v4l2-device.h>
213 +#include <media/v4l2-chip-ident.h>
214 +#include <media/v4l2-i2c-drv.h>
215 +
216 +static int debug;
217 +module_param(debug, bool, 0644);
218 +MODULE_PARM_DESC(debug, "Debug level (0-1)");
219 +
220 +MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
221 +MODULE_DESCRIPTION("A low-level driver for mrst flash");
222 +MODULE_LICENSE("GPL");
223 +
224 +static int flash_g_chip_ident(struct v4l2_subdev *sd,
225 +               struct v4l2_dbg_chip_ident *chip)
226 +{
227 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
228 +
229 +#define V4L2_IDENT_MRST_FLASH 8248
230 +       return v4l2_chip_ident_i2c_client(client, chip,
231 +                                         V4L2_IDENT_MRST_FLASH, 0);
232 +}
233 +
234 +static const struct v4l2_subdev_core_ops flash_core_ops = {
235 +       .g_chip_ident = flash_g_chip_ident,
236 +};
237 +static const struct v4l2_subdev_ops flash_ops = {
238 +       .core = &flash_core_ops,
239 +};
240 +
241 +static int flash_detect(struct i2c_client *client)
242 +{
243 +       struct i2c_adapter *adapter = client->adapter;
244 +       u8 pid;
245 +
246 +       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
247 +               return -ENODEV;
248 +
249 +       if (adapter->nr != 0)
250 +               return -ENODEV;
251 +
252 +       pid = i2c_smbus_read_byte_data(client, 0x10);
253 +       if (pid == 0x18) {
254 +               printk(KERN_ERR "camera flash device found\n");
255 +               v4l_dbg(1, debug, client, "found camera flash device");
256 +       } else {
257 +               printk(KERN_ERR "no camera flash device found\n");
258 +               return -ENODEV;
259 +       }
260 +
261 +       return 0;
262 +}
263 +
264 +static int flash_probe(struct i2c_client *client,
265 +                       const struct i2c_device_id *id)
266 +{
267 +       u8 pid, ver;
268 +       int ret = -1;
269 +       struct v4l2_subdev *sd;
270 +
271 +       v4l_info(client, "chip found @ 0x%x (%s)\n",
272 +                       client->addr << 1, client->adapter->name);
273 +
274 +       sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
275 +       ret = flash_detect(client);
276 +       if (ret)
277 +               return -ENODEV;
278 +
279 +       v4l2_i2c_subdev_init(sd, client, &flash_ops);
280 +
281 +       ver = i2c_smbus_read_byte_data(client, 0x50);
282 +       v4l_dbg(1, debug, client, "detect:CST from device is 0x%x", ver);
283 +       pid = i2c_smbus_read_byte_data(client, 0x20);
284 +       v4l_dbg(1, debug, client, "detect:MFPC from device is 0x%x", pid);
285 +       pid = i2c_smbus_read_byte_data(client, 0xA0);
286 +       v4l_dbg(1, debug, client, "detect:TCC from device is 0x%x", pid);
287 +       pid = i2c_smbus_read_byte_data(client, 0xB0);
288 +       v4l_dbg(1, debug, client, "detect:FCC from device is 0x%x", pid);
289 +       pid = i2c_smbus_read_byte_data(client, 0xC0);
290 +       v4l_dbg(1, debug, client, "detect:FDC from device is 0x%x", pid);
291 +       i2c_smbus_write_byte_data(client, 0xc0, 0xff); /*set FST to 1000us*/
292 +       pid = i2c_smbus_read_byte_data(client, 0xc0);
293 +       v4l_dbg(1, debug, client, "FDC from device is 0x%x", pid);
294 +
295 +       v4l_dbg(1, debug, client,
296 +               "successfully load camera flash device driver");
297 +       return 0;
298 +}
299 +
300 +static int flash_remove(struct i2c_client *client)
301 +{
302 +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
303 +
304 +       v4l2_device_unregister_subdev(sd);
305 +
306 +       return 0;
307 +}
308 +
309 +static const struct i2c_device_id flash_id[] = {
310 +       {"mrst_camera_flash", 0},
311 +       {}
312 +};
313 +
314 +MODULE_DEVICE_TABLE(i2c, flash_id);
315 +
316 +static struct v4l2_i2c_driver_data v4l2_i2c_data = {
317 +       .name = "mrst_camera_flash",
318 +       .probe = flash_probe,
319 +       .remove = flash_remove,
320 +       .id_table = flash_id,
321 +};
322 diff --git a/drivers/media/video/mrstci/mrstov2650/Kconfig b/drivers/media/video/mrstci/mrstov2650/Kconfig
323 new file mode 100644
324 index 0000000..d39d894
325 --- /dev/null
326 +++ b/drivers/media/video/mrstci/mrstov2650/Kconfig
327 @@ -0,0 +1,9 @@
328 +config VIDEO_MRST_OV2650
329 +       tristate "Moorestown OV2650 SoC Sensor"
330 +       depends on I2C && VIDEO_MRST_ISP
331 +
332 +       ---help---
333 +         Say Y here if your platform support OV2650 SoC Sensor.
334 +
335 +         To compile this driver as a module, choose M here: the
336 +         module will be called mrstov2650.ko.
337 diff --git a/drivers/media/video/mrstci/mrstov2650/Makefile b/drivers/media/video/mrstci/mrstov2650/Makefile
338 new file mode 100644
339 index 0000000..fb16d57
340 --- /dev/null
341 +++ b/drivers/media/video/mrstci/mrstov2650/Makefile
342 @@ -0,0 +1,3 @@
343 +obj-$(CONFIG_VIDEO_MRST_OV2650)         += mrstov2650.o
344 +
345 +EXTRA_CFLAGS   +=      -I$(src)/../include
346 \ No newline at end of file
347 diff --git a/drivers/media/video/mrstci/mrstov2650/mrstov2650.c b/drivers/media/video/mrstci/mrstov2650/mrstov2650.c
348 new file mode 100644
349 index 0000000..7f0d478
350 --- /dev/null
351 +++ b/drivers/media/video/mrstci/mrstov2650/mrstov2650.c
352 @@ -0,0 +1,1190 @@
353 +/*
354 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
355 + *
356 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
357 + *
358 + * This program is free software; you can redistribute it and/or
359 + * modify it under the terms of the GNU General Public License version
360 + * 2 as published by the Free Software Foundation.
361 + *
362 + * This program is distributed in the hope that it will be useful,
363 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
364 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
365 + * GNU General Public License for more details.
366 + *
367 + * You should have received a copy of the GNU General Public License
368 + * along with this program; if not, write to the Free Software
369 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
370 + * 02110-1301, USA.
371 + *
372 + *
373 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
374 + */
375 +
376 +#include <linux/module.h>
377 +#include <linux/types.h>
378 +#include <linux/kernel.h>
379 +#include <linux/mm.h>
380 +#include <linux/string.h>
381 +#include <linux/errno.h>
382 +#include <linux/init.h>
383 +#include <linux/kmod.h>
384 +#include <linux/device.h>
385 +#include <linux/delay.h>
386 +#include <linux/fs.h>
387 +#include <linux/init.h>
388 +#include <linux/slab.h>
389 +#include <linux/delay.h>
390 +#include <linux/i2c.h>
391 +#include <linux/gpio.h>
392 +#include <linux/videodev2.h>
393 +#include <media/v4l2-device.h>
394 +#include <media/v4l2-chip-ident.h>
395 +#include <media/v4l2-i2c-drv.h>
396 +
397 +#include "ci_sensor_common.h"
398 +#include "ov2650.h"
399 +
400 +static int mrstov2650_debug;
401 +module_param(mrstov2650_debug, int, 0644);
402 +MODULE_PARM_DESC(mrstov2650_debug, "Debug level (0-1)");
403 +
404 +#define dprintk(level, fmt, arg...) do {                       \
405 +       if (mrstov2650_debug >= level)                                  \
406 +               printk(KERN_DEBUG "mrstisp@%s: " fmt "\n", \
407 +                      __func__, ## arg); } \
408 +       while (0)
409 +
410 +#define eprintk(fmt, arg...)   \
411 +       printk(KERN_ERR "mrstisp@%s: line %d: " fmt "\n",       \
412 +              __func__, __LINE__, ## arg);
413 +
414 +#define DBG_entering   dprintk(2, "entering");
415 +#define DBG_leaving    dprintk(2, "leaving");
416 +#define DBG_line       dprintk(2, " line: %d", __LINE__);
417 +
418 +static inline struct ci_sensor_config *to_sensor_config(struct v4l2_subdev *sd)
419 +{
420 +       return container_of(sd, struct ci_sensor_config, sd);
421 +}
422 +
423 +static struct ov2650_format_struct {
424 +       __u8 *desc;
425 +       __u32 pixelformat;
426 +       struct regval_list *regs;
427 +} ov2650_formats[] = {
428 +       {
429 +               .desc           = "YUYV 4:2:2",
430 +               .pixelformat    = SENSOR_MODE_BT601,
431 +               .regs           = NULL,
432 +       },
433 +};
434 +#define N_OV2650_FMTS ARRAY_SIZE(ov2650_formats)
435 +
436 +static struct ov2650_res_struct {
437 +       __u8 *desc;
438 +       int res;
439 +       int width;
440 +       int height;
441 +       /* FIXME: correct the fps values.. */
442 +       int fps;
443 +       bool used;
444 +       struct regval_list *regs;
445 +} ov2650_res[] = {
446 +       {
447 +               .desc           = "UXGA",
448 +               .res            = SENSOR_RES_UXGA,
449 +               .width          = 1600,
450 +               .height         = 1200,
451 +               .fps            = 15,
452 +               .used           = 0,
453 +               .regs           = ov2650_res_uxga,
454 +       },
455 +       {
456 +               .desc           = "SXGA",
457 +               .res            = SENSOR_RES_SXGA,
458 +               .width          = 1280,
459 +               .height         = 1024,
460 +               .fps            = 15,
461 +               .used           = 0,
462 +               .regs           = ov2650_res_sxga,
463 +       },
464 +       {
465 +               .desc           = "SVGA",
466 +               .res            = SENSOR_RES_SVGA,
467 +               .width          = 800,
468 +               .height         = 600,
469 +               .fps            = 15,
470 +               .used           = 0,
471 +               .regs           = ov2650_res_svga,
472 +       },
473 +       {
474 +               .desc           = "VGA",
475 +               .res            = SENSOR_RES_VGA,
476 +               .width          = 640,
477 +               .height         = 480,
478 +               .fps            = 15,
479 +               .used           = 0,
480 +               .regs           = ov2650_res_vga_vario,
481 +       },
482 +       {
483 +               .desc           = "QVGA",
484 +               .res            = SENSOR_RES_QVGA,
485 +               .width          = 320,
486 +               .height         = 240,
487 +               .fps            = 15,
488 +               .used           = 0,
489 +               .regs           = ov2650_res_qvga,
490 +       },
491 +};
492 +
493 +#define N_RES (ARRAY_SIZE(ov2650_res))
494 +
495 +/*
496 + * I2C Read & Write stuff
497 + */
498 +static int ov2650_read(struct i2c_client *c, u16 reg, u8 *value)
499 +{
500 +       int ret;
501 +       int i;
502 +       struct i2c_msg msg[2];
503 +       u8 msgbuf[2];
504 +       u8 ret_val = 0;
505 +       *value = 0;
506 +       /* Read needs two message to go */
507 +       memset(&msg, 0, sizeof(msg));
508 +       msgbuf[0] = 0;
509 +       msgbuf[1] = 0;
510 +       i = 0;
511 +       msgbuf[i++] = reg >> 8;
512 +       msgbuf[i++] = reg;
513 +       msg[0].addr = c->addr;
514 +       msg[0].buf = msgbuf;
515 +       msg[0].len = i;
516 +
517 +       msg[1].addr = c->addr;
518 +       msg[1].flags = I2C_M_RD;
519 +       msg[1].buf = &ret_val;
520 +       msg[1].len = 1;
521 +
522 +       ret = i2c_transfer(c->adapter, &msg[0], 2);
523 +       *value = ret_val;
524 +
525 +       ret = (ret == 2) ? 0 : -1;
526 +       return ret;
527 +}
528 +
529 +static int ov2650_write(struct i2c_client *c, u16 reg, u8 value)
530 +{
531 +       int ret, i;
532 +       struct i2c_msg msg;
533 +       u8 msgbuf[3];
534 +
535 +       /* Writing only needs one message */
536 +       memset(&msg, 0, sizeof(msg));
537 +       i = 0;
538 +       msgbuf[i++] = reg >> 8;
539 +       msgbuf[i++] = reg;
540 +       msgbuf[i++] = value;
541 +
542 +       msg.addr = c->addr;
543 +       msg.flags = 0;
544 +       msg.buf = msgbuf;
545 +       msg.len = i;
546 +
547 +       ret = i2c_transfer(c->adapter, &msg, 1);
548 +
549 +       /* If this is a reset register, wait for 1ms */
550 +       if (reg == OV2650_SYS && (value & 0x80))
551 +               msleep(3);
552 +
553 +       ret = (ret == 1) ? 0 : -1;
554 +       return ret;
555 +}
556 +
557 +static int ov2650_write_array(struct i2c_client *c, struct regval_list *vals)
558 +{
559 +       struct regval_list *p;
560 +       u8 read_val = 0;
561 +       int err_num = 0;
562 +       int i = 0;
563 +       p = vals;
564 +       while (p->reg_num != 0xffff) {
565 +               ov2650_write(c, p->reg_num, p->value);
566 +               ov2650_read(c, p->reg_num, &read_val);
567 +               if (read_val != p->value)
568 +                       err_num++;
569 +               p++;
570 +               i++;
571 +       }
572 +       return 0;
573 +}
574 +
575 +static int ov2650_set_data_pin_in(struct i2c_client *client)
576 +{
577 +       int ret = 0;
578 +       u8 reg;
579 +
580 +       ret += ov2650_write(client, 0x30b0, 0x00);
581 +
582 +       ret += ov2650_read(client, 0x30b1, &reg);
583 +       reg &= 0xfc;
584 +       ret += ov2650_write(client, 0x30b1, reg);
585 +
586 +       return ret;
587 +}
588 +
589 +static int ov2650_set_data_pin_out(struct i2c_client *client)
590 +{
591 +       int ret = 0;
592 +       u8 reg;
593 +
594 +       ret += ov2650_write(client, 0x30b0, 0xff);
595 +
596 +       ret += ov2650_read(client, 0x30b1, &reg);
597 +       reg &= 0xfc;
598 +       reg |= 0x03;
599 +       ret += ov2650_write(client, 0x30b1, reg);
600 +
601 +       return ret;
602 +}
603 +/*
604 + * Sensor specific helper function
605 + */
606 +static int ov2650_standby(void)
607 +{
608 +       gpio_set_value(GPIO_STDBY_PIN, 1);
609 +       dprintk(1, "PM: standby called\n");
610 +       return 0;
611 +}
612 +
613 +static int ov2650_wakeup(void)
614 +{
615 +       gpio_set_value(GPIO_STDBY_PIN, 0);
616 +       dprintk(1, "PM: wakeup called\n");
617 +       return 0;
618 +}
619 +
620 +static int ov2650_s_power(struct v4l2_subdev *sd, u32 val)
621 +{
622 +       if (val == 1)
623 +               ov2650_standby();
624 +       if (val == 0)
625 +               ov2650_wakeup();
626 +       return 0;
627 +}
628 +
629 +static int ov2650_init(struct i2c_client *c)
630 +{
631 +       int ret;
632 +       struct v4l2_subdev *sd = i2c_get_clientdata(c);
633 +       struct ci_sensor_config *info = to_sensor_config(sd);
634 +
635 +       /* Fill the configuration structure */
636 +       /* Note this default configuration value */
637 +       info->mode = ov2650_formats[0].pixelformat;
638 +       info->res = ov2650_res[0].res;
639 +       info->type = SENSOR_TYPE_SOC;
640 +       info->bls = SENSOR_BLS_OFF;
641 +       info->gamma = SENSOR_GAMMA_ON;
642 +       info->cconv = SENSOR_CCONV_ON;
643 +       info->blc = SENSOR_BLC_AUTO;
644 +       info->agc = SENSOR_AGC_AUTO;
645 +       info->awb = SENSOR_AWB_AUTO;
646 +       info->aec = SENSOR_AEC_AUTO;
647 +       info->bus_width = SENSOR_BUSWIDTH_8BIT_ZZ;
648 +       info->ycseq = SENSOR_YCSEQ_YCBYCR;
649 +       info->conv422 = SENSOR_CONV422_COSITED;
650 +       info->bpat = SENSOR_BPAT_BGBGGRGR;/* GRGRBGBG; */
651 +       info->field_inv = SENSOR_FIELDINV_NOSWAP;
652 +       info->field_sel = SENSOR_FIELDSEL_BOTH;
653 +       info->hpol = SENSOR_HPOL_REFPOS;
654 +       info->vpol = SENSOR_VPOL_POS;
655 +       info->edge = SENSOR_EDGE_RISING;
656 +       info->flicker_freq = SENSOR_FLICKER_100;
657 +       info->cie_profile = 0;
658 +       memcpy(info->name, "ov2650", 7);
659 +
660 +       ret = ov2650_write(c, OV2650_SYS, 0x80);
661 +       /* Set registers into default config value */
662 +       ret += ov2650_write_array(c, ov2650_def_reg);
663 +
664 +       /* added by wen to stop sensor from streaming */
665 +       ov2650_write(c, 0x3086, 0x0f);
666 +       ov2650_set_data_pin_in(c);
667 +       ssleep(1);
668 +
669 +       return ret;
670 +}
671 +
672 +static int distance(struct ov2650_res_struct *res, u32 w, u32 h)
673 +{
674 +       int ret;
675 +       if (res->width < w || res->height < h)
676 +               return -1;
677 +
678 +       ret = ((res->width - w) + (res->height - h));
679 +       return ret;
680 +}
681 +
682 +static int ov2650_try_res(u32 *w, u32 *h)
683 +{
684 +       struct ov2650_res_struct *res_index, *p = NULL;
685 +       int dis, last_dis = ov2650_res->width + ov2650_res->height;
686 +
687 +       dprintk(1, "&&&&&  before %dx%d", *w, *h);
688 +       for (res_index = ov2650_res;
689 +            res_index < ov2650_res + N_RES;
690 +            res_index++) {
691 +               if ((res_index->width <= *w) && (res_index->height <= *h))
692 +                       break;
693 +               dis = distance(res_index, *w, *h);
694 +               if (dis < last_dis) {
695 +                       last_dis = dis;
696 +                       p = res_index;
697 +               }
698 +       }
699 +       if ((res_index->width < *w) || (res_index->height < *h)) {
700 +               if (res_index != ov2650_res)
701 +                       res_index--;
702 +       }
703 +
704 +       /*
705 +       if (p == NULL) {
706 +               p = ov2650_res;
707 +       }
708 +
709 +       if ((w != NULL) && (h != NULL)) {
710 +               *w = p->width;
711 +               *h = p->height;
712 +       }
713 +       */
714 +       if (res_index == ov2650_res + N_RES)
715 +               res_index = ov2650_res + N_RES - 1;
716 +
717 +       *w = res_index->width;
718 +       *h = res_index->height;
719 +
720 +       dprintk(1, "&&&&&  after %dx%d", *w, *h);
721 +       return 0;
722 +}
723 +
724 +static struct ov2650_res_struct *ov2650_to_res(u32 w, u32 h)
725 +{
726 +       struct ov2650_res_struct *res_index;
727 +
728 +       for (res_index = ov2650_res;
729 +            res_index < ov2650_res + N_RES;
730 +            res_index++)
731 +               if ((res_index->width == w) && (res_index->height == h))
732 +                       break;
733 +
734 +       if (res_index >= ov2650_res + N_RES)
735 +               res_index--;   /* Take the bigger one */
736 +
737 +       return res_index;
738 +}
739 +
740 +static int ov2650_try_fmt(struct v4l2_subdev *sd,
741 +                         struct v4l2_format *fmt)
742 +{
743 +       DBG_entering;
744 +       dprintk(1, "&&&&&  before %dx%d", fmt->fmt.pix.width,
745 +               fmt->fmt.pix.height);
746 +       return ov2650_try_res(&fmt->fmt.pix.width, &fmt->fmt.pix.height);
747 +       dprintk(1, "&&&&&  after %dx%d", fmt->fmt.pix.width,
748 +               fmt->fmt.pix.height);
749 +       DBG_leaving;
750 +}
751 +
752 +static int ov2650_get_fmt(struct v4l2_subdev *sd,
753 +                         struct v4l2_format *fmt)
754 +{
755 +       struct ci_sensor_config *info = to_sensor_config(sd);
756 +       unsigned short width, height;
757 +       int index;
758 +
759 +       ci_sensor_res2size(info->res, &width, &height);
760 +
761 +       /* Marked the current sensor res as being "used" */
762 +       for (index = 0; index < N_RES; index++) {
763 +               if ((width == ov2650_res[index].width) &&
764 +                   (height == ov2650_res[index].height)) {
765 +                       ov2650_res[index].used = 1;
766 +                       continue;
767 +               }
768 +               ov2650_res[index].used = 0;
769 +       }
770 +
771 +       fmt->fmt.pix.width = width;
772 +       fmt->fmt.pix.height = height;
773 +       return 0;
774 +}
775 +
776 +static int ov2650_set_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
777 +{
778 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
779 +       struct ci_sensor_config *info = to_sensor_config(sd);
780 +       int ret = 0;
781 +       struct ov2650_res_struct *res_index;
782 +       u32 width, height;
783 +       int index;
784 +
785 +       DBG_entering;
786 +
787 +       width = fmt->fmt.pix.width;
788 +       height = fmt->fmt.pix.height;
789 +
790 +       ret = ov2650_try_res(&width, &height);
791 +       res_index = ov2650_to_res(width, height);
792 +
793 +       ov2650_wakeup();
794 +
795 +       /* if ((info->res != res_index->res) && (res_index->regs)) { */
796 +       if (res_index->regs) {
797 +
798 +               dprintk(2, "changing res from to %dx%d", width, height);
799 +               ret = ov2650_write(client, OV2650_SYS, 0x80);
800 +               ret += ov2650_write_array(client, ov2650_def_reg);
801 +               ret += ov2650_write_array(client, res_index->regs);
802 +
803 +               /* add to debug
804 +               if(res_index->res == SENSOR_RES_VGA) {
805 +                       ret += ov2650_write_array(c, ov2650_def_reg);
806 +                       ret += ov2650_write_array(c, res_index->regs);
807 +               } else {
808 +                       ret += ov2650_write_array(c, ov2650_res_vga_reverse);
809 +                       ret += ov2650_write_array(c, res_index->regs);
810 +               }
811 +               */
812 +
813 +               /* Add delay here to get better image */
814 +               /*
815 +               if (res_index->res == SENSOR_RES_SXGA ||
816 +                  res_index->res == SENSOR_RES_UXGA)
817 +                       msleep(2000);
818 +               else
819 +                       msleep(900);
820 +                       */
821 +
822 +               /* Marked current sensor res as being "used" */
823 +               for (index = 0; index < N_RES; index++) {
824 +                       if ((width == ov2650_res[index].width) &&
825 +                           (height == ov2650_res[index].height)) {
826 +                               ov2650_res[index].used = 1;
827 +                               continue;
828 +                       }
829 +                       ov2650_res[index].used = 0;
830 +               }
831 +
832 +               for (index = 0; index < N_RES; index++)
833 +                       dprintk(2, "index = %d, used = %d\n", index,
834 +                               ov2650_res[index].used);
835 +
836 +       }
837 +
838 +       info->res = res_index->res;
839 +
840 +       /*
841 +       int i;
842 +       unsigned char value;
843 +       printk(KERN_WARNING "2650 reg dumping start:\n");
844 +       for(i = 0x3000; i <= 0x360B; i ++) {
845 +               ov2650_read(c, i, &value);
846 +               printk(KERN_WARNING "reg at offset %4x = %x\n", i, value);
847 +       }
848 +       printk(KERN_WARNING "2650 reg dumping finished:\n");
849 +       */
850 +
851 +       DBG_leaving;
852 +
853 +       return ret;
854 +}
855 +
856 +static int ov2650_q_hflip(struct v4l2_subdev *sd, __s32 *value)
857 +{
858 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
859 +       int err;
860 +       unsigned char v;
861 +
862 +       err = ov2650_read(client, OV2650_TMC_6, &v);
863 +       *value = (v & 0x02) == 0x02;
864 +       return err;
865 +}
866 +
867 +static int ov2650_t_hflip(struct v4l2_subdev *sd, int value)
868 +{
869 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
870 +       struct ci_sensor_config *info = to_sensor_config(sd);
871 +       unsigned char v, v1 = 0;
872 +       int err;
873 +
874 +       value = value >= 1 ? 1 : 0;
875 +       err = ov2650_read(client, OV2650_TMC_6, &v);
876 +       if (value) {
877 +               v |= 0x02;
878 +               v1 |= 0x08;
879 +               info->bpat = SENSOR_BPAT_GRGRBGBG;/*BGBGGRGR;*/
880 +       } else {
881 +               v &= ~0x02;
882 +               v1 &= ~0x08;
883 +               info->bpat = SENSOR_BPAT_BGBGGRGR;
884 +       }
885 +       err += ov2650_write(client, OV2650_TMC_6, v);
886 +       err += ov2650_write(client, 0x3090, v1);
887 +       msleep(10);  /* FIXME */
888 +
889 +       return err;
890 +}
891 +
892 +static int ov2650_q_vflip(struct v4l2_subdev *sd, __s32 *value)
893 +{
894 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
895 +       int err;
896 +       unsigned char v;
897 +
898 +       err = ov2650_read(client, OV2650_TMC_6, &v);
899 +       *value = (v & 0x01) == 0x01;
900 +       return err;
901 +}
902 +
903 +
904 +static int ov2650_t_vflip(struct v4l2_subdev *sd, int value)
905 +{
906 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
907 +       int err = 0;
908 +       unsigned char v;
909 +
910 +       value = value >= 1 ? 1 : 0;
911 +       err = ov2650_read(client, OV2650_TMC_6, &v);
912 +       if (value)
913 +               v |= 0x01;
914 +       else
915 +               v &= ~0x01;
916 +       err += ov2650_write(client, OV2650_TMC_6, v);
917 +       msleep(10);  /* FIXME */
918 +
919 +       return err;
920 +}
921 +
922 +#if 0
923 +static int ov2650_t_awb(struct i2c_client *c, int value)
924 +{
925 +       unsigned char v;
926 +       int ret;
927 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
928 +
929 +       value = value >= 1 ? 1 : 0;
930 +       ret = ov2650_read(c, OV2650_ISP_CTL_0, &v);
931 +       if (value & 0x01) {
932 +               v |= 0x30;
933 +               info->awb = SENSOR_AWB_AUTO;
934 +       } else {
935 +               v &= ~0x30;
936 +               info->awb = SENSOR_AWB_OFF;
937 +       }
938 +       ret += ov2650_write(c, OV2650_ISP_CTL_0, v);
939 +       msleep(10);  /* FIXME */
940 +
941 +       return ret;
942 +}
943 +
944 +static int ov2650_q_awb(struct i2c_client *c, int *value)
945 +{
946 +       int ret;
947 +       unsigned char v;
948 +
949 +       ret = ov2650_read(c, OV2650_ISP_CTL_0, &v);
950 +       *value = (v & 0x30) == 0x30;
951 +       return ret;
952 +}
953 +
954 +static int ov2650_t_agc(struct i2c_client *c, int value)
955 +{
956 +       unsigned char v;
957 +       int ret;
958 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
959 +
960 +       value = value >= 1 ? 1 : 0;
961 +       ret = ov2650_read(c, OV2650_ISP_CTL_0, &v);
962 +       if (value & 0x01) {
963 +               v |= 0x10;
964 +               info->agc = SENSOR_AGC_AUTO;
965 +       } else {
966 +               v &= ~0x10;
967 +               info->agc = SENSOR_AGC_OFF;
968 +       }
969 +       ret += ov2650_write(c, OV2650_ISP_CTL_0, v);
970 +       msleep(10);  /* FIXME */
971 +
972 +       return ret;
973 +}
974 +
975 +static int ov2650_q_agc(struct i2c_client *c, int *value)
976 +{
977 +       int ret;
978 +       unsigned char v;
979 +
980 +       ret = ov2650_read(c, OV2650_ISP_CTL_0, &v);
981 +       *value = (v & 0x10) == 0x10;
982 +       return ret;
983 +}
984 +
985 +static int ov2650_t_blc(struct i2c_client *c, int value)
986 +{
987 +       unsigned char v;
988 +       int ret;
989 +
990 +       value = value >= 1 ? 1 : 0;
991 +
992 +       ret = ov2650_read(c, OV2650_BLCC, &v);
993 +       if (value & 0x01)
994 +               v |= 0x10;
995 +       else
996 +               v &= ~0x10;
997 +       ret += ov2650_write(c, OV2650_BLCC, v);
998 +       msleep(10);  /* FIXME */
999 +
1000 +       return ret;
1001 +}
1002 +
1003 +static int ov2650_q_blc(struct i2c_client *c, int *value)
1004 +{
1005 +       int ret;
1006 +       unsigned char v;
1007 +
1008 +       ret = ov2650_read(c, OV2650_BLCC, &v);
1009 +       *value = (v & 0x10) == 0x10;
1010 +       return ret;
1011 +}
1012 +#endif
1013 +
1014 +static struct ov2650_control {
1015 +       struct v4l2_queryctrl qc;
1016 +       int (*query)(struct v4l2_subdev *sd, __s32 *value);
1017 +       int (*tweak)(struct v4l2_subdev *sd, int value);
1018 +} ov2650_controls[] = {
1019 +       {
1020 +               .qc = {
1021 +                       .id = V4L2_CID_VFLIP,
1022 +                       .type = V4L2_CTRL_TYPE_BOOLEAN,
1023 +                       .name = "Vertical flip",
1024 +                       .minimum = 0,
1025 +                       .maximum = 1,
1026 +                       .step = 1,
1027 +                       .default_value = 0,
1028 +               },
1029 +               .tweak = ov2650_t_vflip,
1030 +               .query = ov2650_q_vflip,
1031 +       },
1032 +       {
1033 +               .qc = {
1034 +                       .id = V4L2_CID_HFLIP,
1035 +                       .type = V4L2_CTRL_TYPE_BOOLEAN,
1036 +                       .name = "Horizontal mirror",
1037 +                       .minimum = 0,
1038 +                       .maximum = 1,
1039 +                       .step = 1,
1040 +                       .default_value = 0,
1041 +               },
1042 +               .tweak = ov2650_t_hflip,
1043 +               .query = ov2650_q_hflip,
1044 +       },
1045 +#if 0
1046 +       {
1047 +               .parm = {
1048 +                       .index = V4L2_CID_AUTO_WHITE_BALANCE,
1049 +                       .type = V4L2_CTRL_TYPE_BOOLEAN,
1050 +                       .name = "Auto White Balance",
1051 +                       .min = 0,
1052 +                       .max = 1,
1053 +                       .step = 1,
1054 +                       .def_value = 1,
1055 +               },
1056 +               .tweak = ov2650_t_awb,
1057 +               .query = ov2650_q_awb,
1058 +       },
1059 +       {
1060 +               .parm = {
1061 +                       .index = V4L2_CID_AUTOGAIN,
1062 +                       .type = V4L2_CTRL_TYPE_BOOLEAN,
1063 +                       .name = "Auto Gain Control",
1064 +                       .min = 0,
1065 +                       .max = 1,
1066 +                       .step = 1,
1067 +                       .def_value = 1,
1068 +               },
1069 +               .tweak = ov2650_t_agc,
1070 +               .query = ov2650_q_agc,
1071 +
1072 +       },
1073 +       {
1074 +               .parm = {
1075 +                       .index = V4L2_CID_BLACK_LEVEL,
1076 +                       .type = V4L2_CTRL_TYPE_BOOLEAN,
1077 +                       .name = "Black Level Control",
1078 +                       .min = 0,
1079 +                       .max = 1,
1080 +                       .step = 1,
1081 +                       .def_value = 1,
1082 +               },
1083 +               .tweak = ov2650_t_blc,
1084 +               .query = ov2650_q_blc,
1085 +
1086 +       },
1087 +#endif
1088 +};
1089 +#define N_CONTROLS (ARRAY_SIZE(ov2650_controls))
1090 +
1091 +static struct ov2650_control *ov2650_find_control(__u32 id)
1092 +{
1093 +       int i;
1094 +
1095 +       for (i = 0; i < N_CONTROLS; i++)
1096 +               if (ov2650_controls[i].qc.id == id)
1097 +                       return ov2650_controls + i;
1098 +       return NULL;
1099 +}
1100 +
1101 +static int ov2650_queryctrl(struct v4l2_subdev *sd,
1102 +                           struct v4l2_queryctrl *qc)
1103 +{
1104 +       struct ov2650_control *octrl;
1105 +       octrl = ov2650_find_control(qc->id);
1106 +       if (NULL == octrl)
1107 +               return -EINVAL;
1108 +       *qc = octrl->qc;
1109 +       return 0;
1110 +}
1111 +
1112 +static int ov2650_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1113 +{
1114 +       struct ov2650_control *octrl = ov2650_find_control(ctrl->id);
1115 +       int ret;
1116 +
1117 +       if (octrl == NULL)
1118 +               return -EINVAL;
1119 +       ret = octrl->query(sd, &ctrl->value);
1120 +       if (ret >= 0)
1121 +               return 0;
1122 +       return ret;
1123 +}
1124 +
1125 +static int ov2650_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1126 +{
1127 +       struct ov2650_control *octrl = ov2650_find_control(ctrl->id);
1128 +       int ret;
1129 +
1130 +       if (octrl == NULL)
1131 +               return -EINVAL;
1132 +       ret =  octrl->tweak(sd, ctrl->value);
1133 +       if (ret >= 0)
1134 +               return 0;
1135 +       return ret;
1136 +}
1137 +#if 0
1138 +static int ov2650_get_caps(struct i2c_client *c, struct ci_sensor_caps *caps)
1139 +{
1140 +       if (caps == NULL)
1141 +               return -EIO;
1142 +
1143 +       caps->bus_width = SENSOR_BUSWIDTH_8BIT_ZZ;
1144 +       caps->mode      = SENSOR_MODE_BT601;
1145 +       caps->field_inv = SENSOR_FIELDINV_NOSWAP;
1146 +       caps->field_sel = SENSOR_FIELDSEL_BOTH;
1147 +       caps->ycseq     = SENSOR_YCSEQ_YCBYCR;
1148 +       caps->conv422   = SENSOR_CONV422_COSITED;
1149 +       caps->bpat      = SENSOR_BPAT_BGBGGRGR;
1150 +       caps->hpol      = SENSOR_HPOL_REFPOS;
1151 +       caps->vpol      = SENSOR_VPOL_POS;
1152 +       caps->edge      = SENSOR_EDGE_RISING;
1153 +       caps->bls       = SENSOR_BLS_OFF;
1154 +       caps->gamma     = SENSOR_GAMMA_ON;
1155 +       caps->cconv     = SENSOR_CCONV_ON;
1156 +       caps->res       = SENSOR_RES_UXGA | SENSOR_RES_SXGA | SENSOR_RES_SVGA
1157 +           | SENSOR_RES_VGA | SENSOR_RES_QVGA;
1158 +       caps->blc       = SENSOR_BLC_AUTO;
1159 +       caps->agc       = SENSOR_AGC_AUTO;
1160 +       caps->awb       = SENSOR_AWB_AUTO;
1161 +       caps->aec       = SENSOR_AEC_AUTO;
1162 +       caps->cie_profile       = 0;
1163 +       caps->flicker_freq      = SENSOR_FLICKER_100 | SENSOR_FLICKER_120;
1164 +       caps->type      = SENSOR_TYPE_SOC;
1165 +       /* caps->name   = "ov2650"; */
1166 +       strcpy(caps->name, "ov2650");
1167 +
1168 +       return 0;
1169 +}
1170 +
1171 +static int ov2650_get_config(struct i2c_client *c,
1172 +                            struct ci_sensor_config *config)
1173 +{
1174 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
1175 +
1176 +       if (config == NULL) {
1177 +               printk(KERN_WARNING "sensor_get_config: NULL pointer\n");
1178 +               return -EIO;
1179 +       }
1180 +
1181 +       memcpy(config, info, sizeof(struct ci_sensor_config));
1182 +
1183 +       return 0;
1184 +}
1185 +
1186 +static int ov2650_setup(struct i2c_client *c,
1187 +                       const struct ci_sensor_config *config)
1188 +{
1189 +       int ret;
1190 +       struct ov2650_res_struct *res_index;
1191 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
1192 +       u16 width, high;
1193 +
1194 +       /* Soft reset camera first*/
1195 +       ret = ov2650_write(c, OV2650_SYS, 0x80);
1196 +
1197 +       /* Set registers into default config value */
1198 +       ret += ov2650_write_array(c, ov2650_def_reg);
1199 +
1200 +       /* set image resolution */
1201 +       ci_sensor_res2size(config->res, &width, &high);
1202 +       ret += ov2650_try_res(c, &width, &high);
1203 +       res_index = ov2650_find_res(width, high);
1204 +       if (res_index->regs)
1205 +               ret += ov2650_write_array(c, res_index->regs);
1206 +       if (!ret)
1207 +               info->res = res_index->res;
1208 +
1209 +
1210 +       if (config->blc != info->blc) {
1211 +               ret += ov2650_t_blc(c, config->blc);
1212 +               info->blc = config->blc;
1213 +       }
1214 +
1215 +       if (config->agc != info->agc) {
1216 +               ret += ov2650_t_agc(c, config->agc);
1217 +               info->agc = config->agc;
1218 +       }
1219 +
1220 +       if (config->awb != info->awb) {
1221 +               ret += ov2650_t_awb(c, config->awb);
1222 +               info->awb = config->awb;
1223 +       }
1224 +       /* Add some delay here to get a better image*/
1225 +       if (res_index->res == SENSOR_RES_SXGA ||
1226 +           res_index->res == SENSOR_RES_UXGA)
1227 +               msleep(2000);
1228 +       else
1229 +               msleep(900);
1230 +
1231 +       return ret;
1232 +}
1233 +
1234 +/*
1235 + * File operation functions
1236 + */
1237 +
1238 +
1239 +
1240 +static int ov2650_open(struct i2c_setting *c, void *priv)
1241 +{
1242 +       struct i2c_client *client = c->sensor_client;
1243 +       /* Just wake up sensor */
1244 +       if (ov2650_wakeup())
1245 +               return -EIO;
1246 +       ov2650_init(client);
1247 +       /*Sleep sensor now*/
1248 +       ov2650_write(client, 0x3086, 0x0f);
1249 +
1250 +       /* set data pin to input */
1251 +       if (ov2650_set_data_pin_in(client))
1252 +               return -EIO;
1253 +
1254 +       return 0;
1255 +}
1256 +
1257 +static int ov2650_release(struct i2c_setting *c, void *priv)
1258 +{
1259 +       /* Just suspend the sensor */
1260 +       ov2650_standby();
1261 +       return 0;
1262 +}
1263 +
1264 +static int ov2650_on(struct i2c_setting *c)
1265 +{
1266 +       int ret;
1267 +
1268 +       /* Software wake up sensor */
1269 +       ret = ov2650_write(c->sensor_client, 0x3086, 0x00);
1270 +
1271 +       /* set data pin to output */
1272 +       return ret + ov2650_set_data_pin_out(c->sensor_client);
1273 +}
1274 +
1275 +static int ov2650_off(struct i2c_setting *c)
1276 +{
1277 +       int ret;
1278 +
1279 +       /* Software standby sensor */
1280 +       ret = ov2650_write(c->sensor_client, 0x3086, 0x0f);
1281 +
1282 +       /* set data pin to input */
1283 +       return ret + ov2650_set_data_pin_in(c->sensor_client);
1284 +}
1285 +
1286 +static struct sensor_device ov2650 = {
1287 +       .name   = "OV2650",
1288 +       .type   = SENSOR_TYPE_SOC,
1289 +       .minor  = -1,
1290 +       .open   = ov2650_open,
1291 +       .release = ov2650_release,
1292 +       .on = ov2650_on,
1293 +       .off = ov2650_off,
1294 +       .querycap = ov2650_get_caps,
1295 +       .get_config = ov2650_get_config,
1296 +       .set_config = ov2650_setup,
1297 +       .enum_parm = ov2650_queryctrl,
1298 +       .get_parm = ov2650_g_ctrl,
1299 +       .set_parm = ov2650_s_ctrl,
1300 +       .try_res = ov2650_try_res,
1301 +       .set_res = ov2650_set_res,
1302 +       .suspend = ov2650_standby,
1303 +       .resume = ov2650_wakeup,
1304 +       .get_ls_corr_config = NULL,
1305 +       .set_awb = NULL,
1306 +       .set_aec = NULL,
1307 +       .set_blc = NULL,
1308 +       /* TBC */
1309 +};
1310 +#endif
1311 +
1312 +static int ov2650_s_stream(struct v4l2_subdev *sd, int enable)
1313 +{
1314 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
1315 +
1316 +       DBG_entering;
1317 +
1318 +
1319 +       if (enable) {
1320 +               ov2650_write(client, 0x3086, 0x00);
1321 +               ov2650_set_data_pin_out(client);
1322 +               msleep(2000);
1323 +       } else {
1324 +               ov2650_write(client, 0x3086, 0x0f);
1325 +               ov2650_set_data_pin_in(client);
1326 +       }
1327 +
1328 +       DBG_leaving;
1329 +       return 0;
1330 +}
1331 +
1332 +static int ov2650_enum_framesizes(struct v4l2_subdev *sd,
1333 +                                 struct v4l2_frmsizeenum *fsize)
1334 +{
1335 +       unsigned int index = fsize->index;
1336 +
1337 +       DBG_entering;
1338 +
1339 +       if (index >= N_RES)
1340 +               return -EINVAL;
1341 +
1342 +       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1343 +       fsize->discrete.width = ov2650_res[index].width;
1344 +       fsize->discrete.height = ov2650_res[index].height;
1345 +       fsize->reserved[0] = ov2650_res[index].used;
1346 +
1347 +       DBG_leaving;
1348 +
1349 +       return 0;
1350 +}
1351 +
1352 +static int ov2650_enum_frameintervals(struct v4l2_subdev *sd,
1353 +                                     struct v4l2_frmivalenum *fival)
1354 +{
1355 +       unsigned int index = fival->index;
1356 +
1357 +       DBG_entering;
1358 +
1359 +       if (index >= N_RES)
1360 +               return -EINVAL;
1361 +
1362 +       fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1363 +       fival->discrete.numerator = 1;
1364 +       fival->discrete.denominator = ov2650_res[index].fps;
1365 +
1366 +       DBG_leaving;
1367 +
1368 +       return 0;
1369 +}
1370 +static int ov2650_g_chip_ident(struct v4l2_subdev *sd,
1371 +               struct v4l2_dbg_chip_ident *chip)
1372 +{
1373 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
1374 +
1375 +#define V4L2_IDENT_OV2650 8244
1376 +       return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV2650, 0);
1377 +}
1378 +
1379 +#ifdef CONFIG_VIDEO_ADV_DEBUG
1380 +static int ov2650_g_register(struct v4l2_subdev *sd,
1381 +                            struct v4l2_dbg_register *reg)
1382 +{
1383 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
1384 +       unsigned char val = 0;
1385 +       int ret;
1386 +
1387 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
1388 +               return -EINVAL;
1389 +       if (!capable(CAP_SYS_ADMIN))
1390 +               return -EPERM;
1391 +       ret = ov2650_read(client, reg->reg & 0xffff, &val);
1392 +       reg->val = val;
1393 +       reg->size = 1;
1394 +       return ret;
1395 +}
1396 +
1397 +static int ov2650_s_register(struct v4l2_subdev *sd,
1398 +                            struct v4l2_dbg_register *reg)
1399 +{
1400 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
1401 +
1402 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
1403 +               return -EINVAL;
1404 +       if (!capable(CAP_SYS_ADMIN))
1405 +               return -EPERM;
1406 +       ov2650_write(client, reg->reg & 0xffff, reg->val & 0xff);
1407 +       return 0;
1408 +}
1409 +#endif
1410 +
1411 +static const struct v4l2_subdev_video_ops ov2650_video_ops = {
1412 +       .try_fmt = ov2650_try_fmt,
1413 +       .s_fmt = ov2650_set_fmt,
1414 +       .g_fmt = ov2650_get_fmt,
1415 +       .s_stream = ov2650_s_stream,
1416 +       .enum_framesizes = ov2650_enum_framesizes,
1417 +       .enum_frameintervals = ov2650_enum_frameintervals,
1418 +};
1419 +
1420 +static const struct v4l2_subdev_core_ops ov2650_core_ops = {
1421 +       .g_chip_ident = ov2650_g_chip_ident,
1422 +       .queryctrl = ov2650_queryctrl,
1423 +       .g_ctrl = ov2650_g_ctrl,
1424 +       .s_ctrl = ov2650_s_ctrl,
1425 +       .s_gpio = ov2650_s_power,
1426 +       /*.g_ext_ctrls = ov2650_g_ext_ctrls,*/
1427 +       /*.s_ext_ctrls = ov2650_s_ext_ctrls,*/
1428 +#ifdef CONFIG_VIDEO_ADV_DEBUG
1429 +       .g_register = ov2650_g_register,
1430 +       .s_register = ov2650_s_register,
1431 +#endif
1432 +};
1433 +
1434 +static const struct v4l2_subdev_ops ov2650_ops = {
1435 +       .core = &ov2650_core_ops,
1436 +       .video = &ov2650_video_ops,
1437 +};
1438 +
1439 +/*
1440 + * Basic i2c stuff
1441 + */
1442 +#if 0
1443 +static unsigned short normal_i2c[] = {I2C_OV2650 >> 1, I2C_CLIENT_END};
1444 +I2C_CLIENT_INSMOD;
1445 +
1446 +static struct i2c_driver ov2650_driver;
1447 +#endif
1448 +static int ov2650_detect(struct i2c_client *client)
1449 +{
1450 +       struct i2c_adapter *adapter = client->adapter;
1451 +       int adap_id = i2c_adapter_id(adapter);
1452 +       u8 value;
1453 +
1454 +       printk(KERN_WARNING "Now start ov2650 detect\n");
1455 +       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
1456 +               return -ENODEV;
1457 +
1458 +       if (adap_id != 1)
1459 +               return -ENODEV;
1460 +
1461 +       /* if (ov2650_wakeup()) */
1462 +               /* return -ENODEV; */
1463 +       ov2650_wakeup();
1464 +
1465 +       ov2650_read(client, OV2650_PID_L, &value);
1466 +       if (value != 0x52)
1467 +               return -ENODEV;
1468 +
1469 +       return 0;
1470 +}
1471 +
1472 +static int ov2650_probe(struct i2c_client *client,
1473 +                       const struct i2c_device_id *id)
1474 +{
1475 +       struct ci_sensor_config *info;
1476 +       struct v4l2_subdev *sd;
1477 +       int ret = -1;
1478 +
1479 +       DBG_entering;
1480 +
1481 +       printk(KERN_INFO "Init ov2650 sensor \n");
1482 +
1483 +       v4l_info(client, "chip found @ 0x%x (%s)\n",
1484 +                       client->addr << 1, client->adapter->name);
1485 +       /*
1486 +        * Setup sensor configuration structure
1487 +        */
1488 +       info = kzalloc(sizeof(struct ci_sensor_config), GFP_KERNEL);
1489 +       if (!info)
1490 +               return -ENOMEM;
1491 +
1492 +       ret = ov2650_detect(client);
1493 +       if (ret) {
1494 +               kfree(info);
1495 +               return -ENODEV;
1496 +       }
1497 +
1498 +       sd = &info->sd;
1499 +       v4l2_i2c_subdev_init(sd, client, &ov2650_ops);
1500 +
1501 +       /*
1502 +        * TODO: Need to check if this can be here.
1503 +        * Turn into standby mode
1504 +        */
1505 +       /* ov2650_standby(); */
1506 +       ret += ov2650_init(client);
1507 +       ov2650_standby();
1508 +
1509 +       printk(KERN_INFO "Init ov2650 sensor success, ret = %d\n", ret);
1510 +
1511 +       DBG_leaving;
1512 +       return 0;
1513 +}
1514 +
1515 +static int ov2650_remove(struct i2c_client *client)
1516 +{
1517 +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
1518 +
1519 +       v4l2_device_unregister_subdev(sd);
1520 +       kfree(to_sensor_config(sd));
1521 +       return 0;
1522 +}
1523 +
1524 +static const struct i2c_device_id ov2650_id[] = {
1525 +       {"ov2650", 0},
1526 +       {}
1527 +};
1528 +
1529 +MODULE_DEVICE_TABLE(i2c, ov2650_id);
1530 +
1531 +static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1532 +       .name = "ov2650",
1533 +       .probe = ov2650_probe,
1534 +       .remove = ov2650_remove,
1535 +       /* .suspend = ov2650_suspend,
1536 +        * .resume = ov2650_resume, */
1537 +       .id_table = ov2650_id,
1538 +};
1539 +
1540 +MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
1541 +MODULE_DESCRIPTION("A low-level driver for OmniVision 2650 sensors");
1542 +MODULE_LICENSE("GPL");
1543 diff --git a/drivers/media/video/mrstci/mrstov2650/ov2650.h b/drivers/media/video/mrstci/mrstov2650/ov2650.h
1544 new file mode 100644
1545 index 0000000..f5c0418
1546 --- /dev/null
1547 +++ b/drivers/media/video/mrstci/mrstov2650/ov2650.h
1548 @@ -0,0 +1,766 @@
1549 +/*
1550 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
1551 + *
1552 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
1553 + *
1554 + * This program is free software; you can redistribute it and/or
1555 + * modify it under the terms of the GNU General Public License version
1556 + * 2 as published by the Free Software Foundation.
1557 + *
1558 + * This program is distributed in the hope that it will be useful,
1559 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1560 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1561 + * GNU General Public License for more details.
1562 + *
1563 + * You should have received a copy of the GNU General Public License
1564 + * along with this program; if not, write to the Free Software
1565 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1566 + * 02110-1301, USA.
1567 + *
1568 + *
1569 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
1570 + */
1571 +
1572 +#define I2C_OV2650     0x60
1573 +/* Should add to kernel source */
1574 +#define I2C_DRIVERID_OV2650    1047
1575 +/* GPIO pin on Moorestown */
1576 +#define GPIO_SCLK_25   44
1577 +#define GPIO_STB_PIN   47
1578 +#define GPIO_STDBY_PIN 48
1579 +#define GPIO_RESET_PIN 50
1580 +
1581 +/* System control register */
1582 +#define OV2650_AGC             0x3000
1583 +#define OV2650_AGCS    0x3001
1584 +#define OV2650_AEC_H   0x3002
1585 +#define OV2650_AEC_L   0x3003
1586 +#define OV2650_AECL    0x3004
1587 +#define OV2650_AECS_H  0x3008
1588 +#define OV2650_AECS_L  0x3009
1589 +#define OV2650_PID_H   0x300A
1590 +#define OV2650_PID_L   0x300B
1591 +#define OV2650_SCCB            0x300C
1592 +#define OV2650_PCLK            0x300D
1593 +#define OV2650_PLL_1   0x300E
1594 +#define OV2650_PLL_2   0x300F
1595 +#define OV2650_PLL_3   0x3010
1596 +#define OV2650_CLK             0x3011
1597 +#define OV2650_SYS             0x3012
1598 +#define OV2650_AUTO_1  0x3013
1599 +#define OV2650_AUTO_2  0x3014
1600 +#define OV2650_AUTO_3  0x3015
1601 +#define OV2650_AUTO_4  0x3016
1602 +#define OV2650_AUTO_5  0x3017
1603 +#define OV2650_WPT             0x3018
1604 +#define OV2650_BPT             0x3019
1605 +#define OV2650_VPT             0x301A
1606 +#define OV2650_YAVG            0x301B
1607 +#define OV2650_AECG_50 0x301C
1608 +#define OV2650_AECG_60 0x301D
1609 +#define OV2650_RZM_H   0x301E
1610 +#define OV2650_RZM_L   0x301F
1611 +#define OV2650_HS_H            0x3020
1612 +#define OV2650_HS_L            0x3021
1613 +#define OV2650_VS_H            0x3022
1614 +#define OV2650_VS_L            0x3023
1615 +#define OV2650_HW_H            0x3024
1616 +#define OV2650_HW_L            0x3025
1617 +#define OV2650_VH_H            0x3026
1618 +#define OV2650_VH_L            0x3027
1619 +#define OV2650_HTS_H   0x3028
1620 +#define OV2650_HTS_L   0x3029
1621 +#define OV2650_VTS_H   0x302A
1622 +#define OV2650_VTS_L   0x302B
1623 +#define OV2650_EXHTS   0x302C
1624 +#define OV2650_EXVTS_H 0x302D
1625 +#define OV2650_EXVTS_L 0x302E
1626 +#define OV2650_WET_0   0x3030
1627 +#define OV2650_WET_1   0x3031
1628 +#define OV2650_WET_2   0x3032
1629 +#define OV2650_WET_3   0x3033
1630 +#define OV2650_AHS_H   0x3038
1631 +#define OV2650_AHS_L   0x3039
1632 +#define OV2650_AVS_H   0x303A
1633 +#define OV2650_AVS_L   0x303B
1634 +#define OV2650_AHW_H   0x303C
1635 +#define OV2650_AHW_L   0x303D
1636 +#define OV2650_AVH_H   0x303E
1637 +#define OV2650_AVH_L   0x303F
1638 +#define OV2650_HISTO_0 0x3040
1639 +#define OV2650_HISTO_1 0x3041
1640 +#define OV2650_HISTO_2 0x3042
1641 +#define OV2650_HISTO_3 0x3043
1642 +#define OV2650_HISTO_4 0x3044
1643 +#define OV2650_BLC9A   0x3069
1644 +#define OV2650_BLCC            0x306C
1645 +#define OV2650_BLCD            0x306D
1646 +#define OV2650_BLCF            0x306F
1647 +#define OV2650_BD50_L  0x3070
1648 +#define OV2650_BD50_H  0x3071
1649 +#define OV2650_BD60_L  0x3072
1650 +#define OV2650_BD60_H  0x3073
1651 +#define OV2650_TMC_0   0x3076
1652 +#define OV2650_TMC_1   0x3077
1653 +#define OV2650_TMC_2   0x3078
1654 +#define OV2650_TMC_4   0x307A
1655 +#define OV2650_TMC_6   0x307C
1656 +#define OV2650_TMC_8   0x307E
1657 +#define OV2650_TMC_I2C 0x3084
1658 +#define OV2650_TMC_10  0x3086
1659 +#define OV2650_TMC_11  0x3087
1660 +#define OV2650_ISP_XO_H        0x3088
1661 +#define OV2650_ISP_XO_L        0x3089
1662 +#define OV2650_ISP_YO_H        0x308A
1663 +#define OV2650_ISP_YO_L        0x308B
1664 +#define OV2650_TMC_12  0x308C
1665 +#define OV2650_TMC_13  0x308D
1666 +#define OV2650_EFUSE   0x308F
1667 +#define OV2650_IO_CTL_0        0x30B0
1668 +#define OV2650_IO_CRL_1 0x30B1
1669 +#define OV2650_IO_CTL_2 0x30B2
1670 +#define OV2650_LAEC            0x30F0
1671 +#define OV2650_GRP_EOP 0x30FF
1672 +
1673 +/* SC registers */
1674 +#define OV2650_SC_CTL_0        0x3100
1675 +#define OV2650_SC_SYN_CTL_0 0x3104
1676 +#define OV2650_SC_SYN_CTL_1 0x3105
1677 +#define OV2650_SC_SYN_CTL_3 0x3107
1678 +#define OV2650_SC_SYN_CTL_4 0x3108
1679 +
1680 +/* DSP control register */
1681 +#define OV2650_ISP_CTL_0       0x3300
1682 +#define OV2650_ISP_CTL_1       0x3301
1683 +#define OV2650_ISP_CTL_2       0x3302
1684 +#define OV2650_ISP_CTL_3       0x3303
1685 +#define OV2650_ISP_CTL_4       0x3304
1686 +#define OV2650_ISP_CTL_5       0x3305
1687 +#define OV2650_ISP_CTL_6       0x3306
1688 +#define OV2650_ISP_CTL_7       0x3307
1689 +#define OV2650_ISP_CTL_8       0x3308
1690 +#define OV2650_ISP_CTL_9       0x3309
1691 +#define OV2650_ISP_CTL_A       0x330A
1692 +#define OV2650_ISP_CTL_B       0x330B
1693 +#define OV2650_ISP_CTL_10      0x3310
1694 +#define OV2650_ISP_CTL_11      0x3311
1695 +#define OV2650_ISP_CTL_12      0x3312
1696 +#define OV2650_ISP_CTL_13      0x3313
1697 +#define OV2650_ISP_CTL_14      0x3314
1698 +#define OV2650_ISP_CTL_15      0x3315
1699 +#define OV2650_ISP_CTL_16      0x3316
1700 +#define OV2650_ISP_CTL_17      0x3317
1701 +#define OV2650_ISP_CTL_18      0x3318
1702 +#define OV2650_ISP_CTL_19      0x3319
1703 +#define OV2650_ISP_CTL_1A      0x331A
1704 +#define OV2650_ISP_CTL_1B      0x331B
1705 +#define OV2650_ISP_CTL_1C      0x331C
1706 +#define OV2650_ISP_CTL_1D      0x331D
1707 +#define OV2650_ISP_CTL_1E      0x331E
1708 +#define OV2650_ISP_CTL_20      0x3320
1709 +#define OV2650_ISP_CTL_21      0x3321
1710 +#define OV2650_ISP_CTL_22      0x3322
1711 +#define OV2650_ISP_CTL_23      0x3323
1712 +#define OV2650_ISP_CTL_24      0x3324
1713 +#define OV2650_ISP_CTL_27      0x3327
1714 +#define OV2650_ISP_CTL_28      0x3328
1715 +#define OV2650_ISP_CTL_29      0x3329
1716 +#define OV2650_ISP_CTL_2A      0x332A
1717 +#define OV2650_ISP_CTL_2B      0x332B
1718 +#define OV2650_ISP_CTL_2C      0x332C
1719 +#define OV2650_ISP_CTL_2D      0x332D
1720 +#define OV2650_ISP_CTL_2E      0x332E
1721 +#define OV2650_ISP_CTL_2F      0x332F
1722 +#define OV2650_ISP_CTL_30      0x3330
1723 +#define OV2650_ISP_CTL_31      0x3331
1724 +#define OV2650_ISP_CTL_32      0x3332
1725 +#define OV2650_ISP_CTL_33      0x3333
1726 +#define OV2650_ISP_CTL_34      0x3334
1727 +#define OV2650_ISP_CTL_35      0x3335
1728 +#define OV2650_ISP_CTL_36      0x3336
1729 +#define OV2650_ISP_CTL_40      0x3340
1730 +#define OV2650_ISP_CTL_41      0x3341
1731 +#define OV2650_ISP_CTL_42      0x3342
1732 +#define OV2650_ISP_CTL_43      0x3343
1733 +#define OV2650_ISP_CTL_44      0x3344
1734 +#define OV2650_ISP_CTL_45      0x3345
1735 +#define OV2650_ISP_CTL_46      0x3346
1736 +#define OV2650_ISP_CTL_47      0x3347
1737 +#define OV2650_ISP_CTL_48      0x3348
1738 +#define OV2650_ISP_CTL_49      0x3349
1739 +#define OV2650_ISP_CTL_4A      0x334A
1740 +#define OV2650_ISP_CTL_4B      0x334B
1741 +#define OV2650_ISP_CTL_4C      0x334C
1742 +#define OV2650_ISP_CTL_4D      0x334D
1743 +#define OV2650_ISP_CTL_4E      0x334E
1744 +#define OV2650_ISP_CTL_4F      0x334F
1745 +#define OV2650_ISP_CTL_50      0x3350
1746 +#define OV2650_ISP_CTL_51      0x3351
1747 +#define OV2650_ISP_CTL_52      0x3352
1748 +#define OV2650_ISP_CTL_53      0x3353
1749 +#define OV2650_ISP_CTL_54      0x3354
1750 +#define OV2650_ISP_CTL_55      0x3355
1751 +#define OV2650_ISP_CTL_56      0x3356
1752 +#define OV2650_ISP_CTL_57      0x3357
1753 +#define OV2650_ISP_CTL_58      0x3358
1754 +#define OV2650_ISP_CTL_59      0x3359
1755 +#define OV2650_ISP_CTL_5A      0x335A
1756 +#define OV2650_ISP_CTL_5B      0x335B
1757 +#define OV2650_ISP_CTL_5C      0x335C
1758 +#define OV2650_ISP_CTL_5D      0x335D
1759 +#define OV2650_ISP_CTL_5E      0x335E
1760 +#define OV2650_ISP_CTL_5F      0x335F
1761 +#define OV2650_ISP_CTL_60      0x3360
1762 +#define OV2650_ISP_CTL_61      0x3361
1763 +#define OV2650_ISP_CTL_62      0x3362
1764 +#define OV2650_ISP_CTL_63      0x3363
1765 +#define OV2650_ISP_CTL_64      0x3364
1766 +#define OV2650_ISP_CTL_65      0x3365
1767 +#define OV2650_ISP_CTL_6A      0x336A
1768 +#define OV2650_ISP_CTL_6B      0x336B
1769 +#define OV2650_ISP_CTL_6C      0x336C
1770 +#define OV2650_ISP_CTL_6E      0x336E
1771 +#define OV2650_ISP_CTL_71      0x3371
1772 +#define OV2650_ISP_CTL_72      0x3372
1773 +#define OV2650_ISP_CTL_73      0x3373
1774 +#define OV2650_ISP_CTL_74      0x3374
1775 +#define OV2650_ISP_CTL_75      0x3375
1776 +#define OV2650_ISP_CTL_76      0x3376
1777 +#define OV2650_ISP_CTL_77      0x3377
1778 +#define OV2650_ISP_CTL_78      0x3378
1779 +#define OV2650_ISP_CTL_79      0x3379
1780 +#define OV2650_ISP_CTL_7A      0x337A
1781 +#define OV2650_ISP_CTL_7B      0x337B
1782 +#define OV2650_ISP_CTL_7C      0x337C
1783 +#define OV2650_ISP_CTL_80      0x3380
1784 +#define OV2650_ISP_CTL_81      0x3381
1785 +#define OV2650_ISP_CTL_82      0x3382
1786 +#define OV2650_ISP_CTL_83      0x3383
1787 +#define OV2650_ISP_CTL_84      0x3384
1788 +#define OV2650_ISP_CTL_85      0x3385
1789 +#define OV2650_ISP_CTL_86      0x3386
1790 +#define OV2650_ISP_CTL_87      0x3387
1791 +#define OV2650_ISP_CTL_88      0x3388
1792 +#define OV2650_ISP_CTL_89      0x3389
1793 +#define OV2650_ISP_CTL_8A      0x338A
1794 +#define OV2650_ISP_CTL_8B      0x338B
1795 +#define OV2650_ISP_CTL_8C      0x338C
1796 +#define OV2650_ISP_CTL_8D      0x338D
1797 +#define OV2650_ISP_CTL_8E      0x338E
1798 +#define OV2650_ISP_CTL_90      0x3390
1799 +#define OV2650_ISP_CTL_91      0x3391
1800 +#define OV2650_ISP_CTL_92      0x3392
1801 +#define OV2650_ISP_CTL_93      0x3393
1802 +#define OV2650_ISP_CTL_94      0x3394
1803 +#define OV2650_ISP_CTL_95      0x3395
1804 +#define OV2650_ISP_CTL_96      0x3396
1805 +#define OV2650_ISP_CTL_97      0x3397
1806 +#define OV2650_ISP_CTL_98      0x3398
1807 +#define OV2650_ISP_CTL_99      0x3399
1808 +#define OV2650_ISP_CTL_9A      0x339A
1809 +#define OV2650_ISP_CTL_A0      0x33A0
1810 +#define OV2650_ISP_CTL_A1      0x33A1
1811 +#define OV2650_ISP_CTL_A2      0x33A2
1812 +#define OV2650_ISP_CTL_A3      0x33A3
1813 +#define OV2650_ISP_CTL_A4      0x33A4
1814 +#define OV2650_ISP_CTL_A5      0x33A5
1815 +#define OV2650_ISP_CTL_A6      0x33A6
1816 +#define OV2650_ISP_CTL_A7      0x33A7
1817 +#define OV2650_ISP_CTL_A8      0x33A8
1818 +#define OV2650_ISP_CTL_AA      0x33AA
1819 +#define OV2650_ISP_CTL_AB      0x33AB
1820 +#define OV2650_ISP_CTL_AC      0x33AC
1821 +#define OV2650_ISP_CTL_AD      0x33AD
1822 +#define OV2650_ISP_CTL_AE      0x33AE
1823 +#define OV2650_ISP_CTL_AF      0x33AF
1824 +#define OV2650_ISP_CTL_B0      0x33B0
1825 +#define OV2650_ISP_CTL_B1      0x33B1
1826 +#define OV2650_ISP_CTL_B2      0x33B2
1827 +#define OV2650_ISP_CTL_B3      0x33B3
1828 +#define OV2650_ISP_CTL_B4      0x33B4
1829 +#define OV2650_ISP_CTL_B5      0x33B5
1830 +#define OV2650_ISP_CTL_B6      0x33B6
1831 +#define OV2650_ISP_CTL_B7      0x33B7
1832 +#define OV2650_ISP_CTL_B8      0x33B8
1833 +#define OV2650_ISP_CTL_B9      0x33B9
1834 +
1835 +/* Format register */
1836 +#define OV2650_FMT_CTL_0       0x3400
1837 +#define OV2650_FMT_CTL_1       0x3401
1838 +#define OV2650_FMT_CTL_2       0x3402
1839 +#define OV2650_FMT_CTL_3       0x3403
1840 +#define OV2650_FMT_CTL_4       0x3404
1841 +#define OV2650_FMT_CTL_5       0x3405
1842 +#define OV2650_FMT_CTL_6       0x3406
1843 +#define OV2650_FMT_CTL_7       0x3407
1844 +#define OV2650_FMT_CTL_8       0x3408
1845 +#define OV2650_DITHER_CTL      0x3409
1846 +#define OV2650_DVP_CTL_0       0x3600
1847 +#define OV2650_DVP_CTL_1       0x3601
1848 +#define OV2650_DVP_CTL_6       0x3606
1849 +#define OV2650_DVP_CTL_7       0x3607
1850 +#define OV2650_DVP_CTL_9       0x3609
1851 +#define OV2650_DVP_CTL_B       0x360B
1852 +
1853 +/* General definition for ov2650 */
1854 +#define OV2650_OUTWND_MAX_H            UXGA_SIZE_H
1855 +#define OV2650_OUTWND_MAX_V            UXGA_SIZE_V
1856 +
1857 +struct regval_list {
1858 +       u16 reg_num;
1859 +       u8 value;
1860 +};
1861 +
1862 +/*
1863 + * Default register value
1864 + * 1600x1200 YUV
1865 + */
1866 +static struct regval_list ov2650_def_reg[] = {
1867 +       {0x3012, 0x80},
1868 +       {0x308c, 0x80},
1869 +       {0x308d, 0x0e},
1870 +       {0x360b, 0x00},
1871 +       {0x30b0, 0xff},
1872 +       {0x30b1, 0xff},
1873 +       {0x30b2, 0x27},
1874 +
1875 +       {0x300e, 0x34},
1876 +       {0x300f, 0xa6},
1877 +       {0x3010, 0x81},
1878 +       {0x3082, 0x01},
1879 +       {0x30f4, 0x01},
1880 +       {0x3090, 0x33},
1881 +       {0x3091, 0xc0},
1882 +       {0x30ac, 0x42},
1883 +
1884 +       {0x30d1, 0x08},
1885 +       {0x30a8, 0x56},
1886 +       {0x3015, 0x03},
1887 +       {0x3093, 0x00},
1888 +       {0x307e, 0xe5},
1889 +       {0x3079, 0x00},
1890 +       {0x30aa, 0x42},
1891 +       {0x3017, 0x40},
1892 +       {0x30f3, 0x82},
1893 +       {0x306a, 0x0c},
1894 +       {0x306d, 0x00},
1895 +       {0x336a, 0x3c},
1896 +       {0x3076, 0x6a},
1897 +       {0x30d9, 0x8c},
1898 +       {0x3016, 0x82},
1899 +       {0x3601, 0x30},
1900 +       {0x304e, 0x88},
1901 +       {0x30f1, 0x82},
1902 +       {0x3011, 0x02},
1903 +
1904 +       {0x3013, 0xf7},
1905 +       {0x301c, 0x13},
1906 +       {0x301d, 0x17},
1907 +       {0x3070, 0x3e},
1908 +       {0x3072, 0x34},
1909 +
1910 +       {0x30af, 0x00},
1911 +       {0x3048, 0x1f},
1912 +       {0x3049, 0x4e},
1913 +       {0x304a, 0x20},
1914 +       {0x304f, 0x20},
1915 +       {0x304b, 0x02},
1916 +       {0x304c, 0x00},
1917 +       {0x304d, 0x02},
1918 +       {0x304f, 0x20},
1919 +       {0x30a3, 0x10},
1920 +       {0x3013, 0xf7},
1921 +       {0x3014, 0x44},
1922 +       {0x3071, 0x00},
1923 +       {0x3070, 0x3e},
1924 +       {0x3073, 0x00},
1925 +       {0x3072, 0x34},
1926 +       {0x301c, 0x12},
1927 +       {0x301d, 0x16},
1928 +       {0x304d, 0x42},
1929 +       {0x304a, 0x40},
1930 +       {0x304f, 0x40},
1931 +       {0x3095, 0x07},
1932 +       {0x3096, 0x16},
1933 +       {0x3097, 0x1d},
1934 +
1935 +       {0x3020, 0x01},
1936 +       {0x3021, 0x18},
1937 +       {0x3022, 0x00},
1938 +       {0x3023, 0x0a},
1939 +       {0x3024, 0x06},
1940 +       {0x3025, 0x58},
1941 +       {0x3026, 0x04},
1942 +       {0x3027, 0xbc},
1943 +       {0x3088, 0x06},
1944 +       {0x3089, 0x40},
1945 +       {0x308a, 0x04},
1946 +       {0x308b, 0xb0},
1947 +       {0x3316, 0x64},
1948 +       {0x3317, 0x4b},
1949 +       {0x3318, 0x00},
1950 +       {0x331a, 0x64},
1951 +       {0x331b, 0x4b},
1952 +       {0x331c, 0x00},
1953 +       {0x3100, 0x00},
1954 +
1955 +       {0x3320, 0xfa},
1956 +       {0x3321, 0x11},
1957 +       {0x3322, 0x92},
1958 +       {0x3323, 0x01},
1959 +       {0x3324, 0x97},
1960 +       {0x3325, 0x02},
1961 +       {0x3326, 0xff},
1962 +       {0x3327, 0x0c},
1963 +       {0x3328, 0x10},
1964 +       {0x3329, 0x10},
1965 +       {0x332a, 0x58},
1966 +       {0x332b, 0x50},
1967 +       {0x332c, 0xbe},
1968 +       {0x332d, 0xe1},
1969 +       {0x332e, 0x43},
1970 +       {0x332f, 0x36},
1971 +       {0x3330, 0x4d},
1972 +       {0x3331, 0x44},
1973 +       {0x3332, 0xf8},
1974 +       {0x3333, 0x0a},
1975 +       {0x3334, 0xf0},
1976 +       {0x3335, 0xf0},
1977 +       {0x3336, 0xf0},
1978 +       {0x3337, 0x40},
1979 +       {0x3338, 0x40},
1980 +       {0x3339, 0x40},
1981 +       {0x333a, 0x00},
1982 +       {0x333b, 0x00},
1983 +
1984 +       {0x3380, 0x28},
1985 +       {0x3381, 0x48},
1986 +       {0x3382, 0x10},
1987 +       {0x3383, 0x23},
1988 +       {0x3384, 0xc0},
1989 +       {0x3385, 0xe5},
1990 +       {0x3386, 0xc2},
1991 +       {0x3387, 0xb3},
1992 +       {0x3388, 0x0e},
1993 +       {0x3389, 0x98},
1994 +       {0x338a, 0x01},
1995 +
1996 +       {0x3340, 0x0e},
1997 +       {0x3341, 0x1a},
1998 +       {0x3342, 0x31},
1999 +       {0x3343, 0x45},
2000 +       {0x3344, 0x5a},
2001 +       {0x3345, 0x69},
2002 +       {0x3346, 0x75},
2003 +       {0x3347, 0x7e},
2004 +       {0x3348, 0x88},
2005 +       {0x3349, 0x96},
2006 +       {0x334a, 0xa3},
2007 +       {0x334b, 0xaf},
2008 +       {0x334c, 0xc4},
2009 +       {0x334d, 0xd7},
2010 +       {0x334e, 0xe8},
2011 +       {0x334f, 0x20},
2012 +
2013 +       {0x3350, 0x32},
2014 +       {0x3351, 0x25},
2015 +       {0x3352, 0x80},
2016 +       {0x3353, 0x1e},
2017 +       {0x3354, 0x00},
2018 +       {0x3355, 0x85},
2019 +       {0x3356, 0x32},
2020 +       {0x3357, 0x25},
2021 +       {0x3358, 0x80},
2022 +       {0x3359, 0x1b},
2023 +       {0x335a, 0x00},
2024 +       {0x335b, 0x85},
2025 +       {0x335c, 0x32},
2026 +       {0x335d, 0x25},
2027 +       {0x335e, 0x80},
2028 +       {0x335f, 0x1b},
2029 +       {0x3360, 0x00},
2030 +       {0x3361, 0x85},
2031 +       {0x3363, 0x70},
2032 +       {0x3364, 0x7f},
2033 +       {0x3365, 0x00},
2034 +       {0x3366, 0x00},
2035 +
2036 +       {0x3301, 0xff},
2037 +       {0x338B, 0x11},
2038 +       {0x338c, 0x10},
2039 +       {0x338d, 0x40},
2040 +
2041 +       {0x3370, 0xd0},
2042 +       {0x3371, 0x00},
2043 +       {0x3372, 0x00},
2044 +       {0x3373, 0x40},
2045 +       {0x3374, 0x10},
2046 +       {0x3375, 0x10},
2047 +       {0x3376, 0x04},
2048 +       {0x3377, 0x00},
2049 +       {0x3378, 0x04},
2050 +       {0x3379, 0x80},
2051 +
2052 +       {0x3069, 0x84},
2053 +       {0x307c, 0x10},
2054 +       {0x3087, 0x02},
2055 +
2056 +       {0x3300, 0xfc},
2057 +       {0x3302, 0x01},
2058 +       {0x3400, 0x00},
2059 +       {0x3606, 0x20},
2060 +       {0x3601, 0x30},
2061 +       {0x30f3, 0x83},
2062 +       {0x304e, 0x88},
2063 +
2064 +       {0x3086, 0x0f},
2065 +       {0x3086, 0x00},
2066 +
2067 +       {0xffff, 0xff},
2068 +};
2069 +
2070 +/* 800x600 */
2071 +static struct regval_list ov2650_res_svga[] = {
2072 +
2073 +       {0x306f, 0x14},
2074 +       {0x302a, 0x02},
2075 +       {0x302b, 0x84},
2076 +       {0x3012, 0x10},
2077 +       {0x3011, 0x01},
2078 +
2079 +       {0x3070, 0x5d},
2080 +       {0x3072, 0x4d},
2081 +
2082 +       {0x3014, 0x84},
2083 +       {0x301c, 0x07},
2084 +       {0x301d, 0x09},
2085 +       {0x3070, 0x50},
2086 +       {0x3071, 0x00},
2087 +       {0x3072, 0x42},
2088 +       {0x3073, 0x00},
2089 +
2090 +       {0x3020, 0x01},
2091 +       {0x3021, 0x18},
2092 +       {0x3022, 0x00},
2093 +       {0x3023, 0x06},
2094 +       {0x3024, 0x06},
2095 +       {0x3025, 0x58},
2096 +       {0x3026, 0x02},
2097 +       {0x3027, 0x5e},
2098 +       {0x3088, 0x03},
2099 +       {0x3089, 0x20},
2100 +       {0x308a, 0x02},
2101 +       {0x308b, 0x58},
2102 +       {0x3316, 0x64},
2103 +       {0x3317, 0x25},
2104 +       {0x3318, 0x80},
2105 +       {0x3319, 0x08},
2106 +       {0x331a, 0x64},
2107 +       {0x331b, 0x4b},
2108 +       {0x331c, 0x00},
2109 +       {0x331d, 0x38},
2110 +       {0x3100, 0x00},
2111 +
2112 +       {0x3302, 0x11},
2113 +
2114 +       {0x3011, 0x01},
2115 +       {0x300f, 0xa6},
2116 +       {0x300e, 0x36},
2117 +       {0x3010, 0x81},
2118 +       {0x302e, 0x00},
2119 +       {0x302d, 0x00},
2120 +       {0x302c, 0x00},
2121 +       {0x302b, 0x84},
2122 +       {0x3014, 0x84},
2123 +       {0x301c, 0x07},
2124 +       {0x301d, 0x09},
2125 +       {0x3070, 0x50},
2126 +       {0x3071, 0x00},
2127 +       {0x3072, 0x42},
2128 +       {0x3073, 0x00},
2129 +
2130 +       {0x3086, 0x0f},
2131 +       {0x3086, 0x00},
2132 +       {0xffff, 0xff},
2133 +};
2134 +
2135 +/* 640x480 */
2136 +static struct regval_list ov2650_res_vga_vario[] = {
2137 +       {0x306f, 0x14},
2138 +       {0x302a, 0x02},
2139 +       {0x302b, 0x6a},
2140 +       {0x3012, 0x10},
2141 +       {0x3011, 0x01},
2142 +
2143 +       {0x3070, 0x5d},
2144 +       {0x3072, 0x4d},
2145 +
2146 +       {0x301c, 0x05},
2147 +       {0x301d, 0x06},
2148 +
2149 +       {0x3020, 0x01},
2150 +       {0x3021, 0x18},
2151 +       {0x3022, 0x00},
2152 +       {0x3023, 0x06},
2153 +       {0x3024, 0x06},
2154 +       {0x3025, 0x58},
2155 +       {0x3026, 0x02},
2156 +       {0x3027, 0x61},
2157 +       {0x3088, 0x02},
2158 +       {0x3089, 0x80},
2159 +       {0x308a, 0x01},
2160 +       {0x308b, 0xe0},
2161 +       {0x3316, 0x64},
2162 +       {0x3317, 0x25},
2163 +       {0x3318, 0x80},
2164 +       {0x3319, 0x08},
2165 +       {0x331a, 0x28},
2166 +       {0x331b, 0x1e},
2167 +       {0x331c, 0x00},
2168 +       {0x331d, 0x38},
2169 +       {0x3100, 0x00},
2170 +
2171 +       {0x3302, 0x11},
2172 +       {0x3011, 0x00},
2173 +
2174 +       {0x3014, 0x84}, /* note this */
2175 +       {0x3086, 0x0f},
2176 +       {0x3086, 0x00},
2177 +       {0xffff, 0xff},
2178 +};
2179 +
2180 +/* 640x480 reverse */
2181 +/*
2182 +static struct regval_list ov2650_res_vga_reverse[] = {
2183 +       {0x306f, 0x10},
2184 +       {0x302a, 0x04},
2185 +       {0x302b, 0xd4},
2186 +       {0x3012, 0x00},
2187 +       {0x3011, 0x02},
2188 +
2189 +       {0x3070, 0x3e},
2190 +       {0x3072, 0x34},
2191 +
2192 +       {0x301c, 0x12},
2193 +       {0x301d, 0x16},
2194 +
2195 +       {0x3020, 0x01},
2196 +       {0x3021, 0x18},
2197 +       {0x3022, 0x00},
2198 +       {0x3023, 0x0a},
2199 +       {0x3024, 0x06},
2200 +       {0x3025, 0x58},
2201 +       {0x3026, 0x04},
2202 +       {0x3027, 0xbc},
2203 +       {0x3088, 0x06},
2204 +       {0x3089, 0x40},
2205 +       {0x308a, 0x04},
2206 +       {0x308b, 0xb0},
2207 +       {0x3316, 0x64},
2208 +       {0x3317, 0xb4},
2209 +       {0x3318, 0x00},
2210 +       {0x3319, 0x6c},
2211 +       {0x331a, 0x64},
2212 +       {0x331b, 0x4b},
2213 +       {0x331c, 0x00},
2214 +       {0x331d, 0x6c},
2215 +       {0x3100, 0x00},
2216 +
2217 +       {0x3302, 0x01},
2218 +       {0x3011, 0x02},
2219 +
2220 +       {0x3014, 0x44},
2221 +       {0x3086, 0x0f},
2222 +       {0x3086, 0x00},
2223 +       {0xffff, 0xff},
2224 +};
2225 +
2226 +*/
2227 +/* 320x240 */
2228 +static struct regval_list ov2650_res_qvga[] = {
2229 +       {0x306f, 0x14},
2230 +       {0x302a, 0x02},
2231 +       {0x302b, 0x6a},
2232 +
2233 +       {0x3012, 0x10},
2234 +       {0x3011, 0x01},
2235 +
2236 +       {0x3070, 0x5d},
2237 +       {0x3072, 0x4d},
2238 +       {0x301c, 0x05},
2239 +       {0x301d, 0x06},
2240 +
2241 +       {0x3023, 0x06},
2242 +       {0x3026, 0x02},
2243 +       {0x3027, 0x61},
2244 +       {0x3088, 0x01},
2245 +       {0x3089, 0x40},
2246 +       {0x308a, 0x00},
2247 +       {0x308b, 0xf0},
2248 +       {0x3316, 0x64},
2249 +       {0x3317, 0x25},
2250 +       {0x3318, 0x80},
2251 +       {0x3319, 0x08},
2252 +       {0x331a, 0x14},
2253 +       {0x331b, 0x0f},
2254 +       {0x331c, 0x00},
2255 +       {0x331d, 0x38},
2256 +       {0x3100, 0x00},
2257 +
2258 +       {0x3015, 0x02}, /* note this */
2259 +       {0x3014, 0x84},
2260 +       {0x3302, 0x11},
2261 +       {0x3086, 0x0f},
2262 +       {0x3086, 0x00},
2263 +       {0xffff, 0xff},
2264 +};
2265 +
2266 +static struct regval_list ov2650_res_uxga[] = {
2267 +       /* Note this added by debug */
2268 +       {0x3014, 0x84},
2269 +       {0x301c, 0x13},
2270 +       {0x301d, 0x17},
2271 +       {0x3070, 0x40},
2272 +       {0x3071, 0x00},
2273 +       {0x3072, 0x36},
2274 +       {0x3073, 0x00},
2275 +
2276 +       {0xffff, 0xff},
2277 +};
2278 +
2279 +static struct regval_list ov2650_res_sxga[] = {
2280 +       {0x3011, 0x02},
2281 +
2282 +       {0x3020, 0x01},
2283 +       {0x3021, 0x18},
2284 +       {0x3022, 0x00},
2285 +       {0x3023, 0x0a},
2286 +       {0x3024, 0x06},
2287 +       {0x3025, 0x58},
2288 +       {0x3026, 0x04},
2289 +       {0x3027, 0xbc},
2290 +       {0x3088, 0x05},
2291 +       {0x3089, 0x00},
2292 +       {0x308a, 0x04},
2293 +       {0x308b, 0x00},
2294 +       {0x3316, 0x64},
2295 +       {0x3317, 0x4b},
2296 +       {0x3318, 0x00},
2297 +       {0x331a, 0x50},
2298 +       {0x331b, 0x40},
2299 +       {0x331c, 0x00},
2300 +
2301 +       {0x3302, 0x11},
2302 +
2303 +       {0x3014, 0x84},
2304 +       {0x301c, 0x13},
2305 +       {0x301d, 0x17},
2306 +       {0x3070, 0x40},
2307 +       {0x3071, 0x00},
2308 +       {0x3072, 0x36},
2309 +       {0x3073, 0x00},
2310 +
2311 +       {0x3086, 0x0f},
2312 +       {0x3086, 0x00},
2313 +       {0xffff, 0xff},
2314 +};
2315 diff --git a/drivers/media/video/mrstci/mrstov5630/Kconfig b/drivers/media/video/mrstci/mrstov5630/Kconfig
2316 new file mode 100644
2317 index 0000000..a28ddc2
2318 --- /dev/null
2319 +++ b/drivers/media/video/mrstci/mrstov5630/Kconfig
2320 @@ -0,0 +1,9 @@
2321 +config VIDEO_MRST_OV5630
2322 +       tristate "Moorestown OV5630 RAW Sensor"
2323 +       depends on I2C && VIDEO_MRST_ISP
2324 +
2325 +       ---help---
2326 +         Say Y here if your platform support OV5630 RAW Sensor.
2327 +
2328 +         To compile this driver as a module, choose M here: the
2329 +         module will be called mrstov2650.ko.
2330 diff --git a/drivers/media/video/mrstci/mrstov5630/Makefile b/drivers/media/video/mrstci/mrstov5630/Makefile
2331 new file mode 100644
2332 index 0000000..c67abff
2333 --- /dev/null
2334 +++ b/drivers/media/video/mrstci/mrstov5630/Makefile
2335 @@ -0,0 +1,4 @@
2336 +mrstov5630-objs        = ov5630.o
2337 +obj-$(CONFIG_VIDEO_MRST_OV5630)         += mrstov5630.o
2338 +
2339 +EXTRA_CFLAGS   +=      -I$(src)/../include
2340 diff --git a/drivers/media/video/mrstci/mrstov5630/ov5630.c b/drivers/media/video/mrstci/mrstov5630/ov5630.c
2341 new file mode 100644
2342 index 0000000..6498153
2343 --- /dev/null
2344 +++ b/drivers/media/video/mrstci/mrstov5630/ov5630.c
2345 @@ -0,0 +1,1153 @@
2346 +/*
2347 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
2348 + *
2349 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
2350 + *
2351 + * This program is free software; you can redistribute it and/or
2352 + * modify it under the terms of the GNU General Public License version
2353 + * 2 as published by the Free Software Foundation.
2354 + *
2355 + * This program is distributed in the hope that it will be useful,
2356 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2357 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2358 + * GNU General Public License for more details.
2359 + *
2360 + * You should have received a copy of the GNU General Public License
2361 + * along with this program; if not, write to the Free Software
2362 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2363 + * 02110-1301, USA.
2364 + *
2365 + *
2366 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
2367 + */
2368 +
2369 +#include <linux/module.h>
2370 +#include <linux/types.h>
2371 +#include <linux/kernel.h>
2372 +#include <linux/mm.h>
2373 +#include <linux/string.h>
2374 +#include <linux/errno.h>
2375 +#include <linux/init.h>
2376 +#include <linux/kmod.h>
2377 +#include <linux/device.h>
2378 +#include <linux/delay.h>
2379 +#include <linux/fs.h>
2380 +#include <linux/init.h>
2381 +#include <linux/slab.h>
2382 +#include <linux/delay.h>
2383 +#include <linux/i2c.h>
2384 +#include <linux/gpio.h>
2385 +
2386 +#include <media/v4l2-device.h>
2387 +#include <media/v4l2-chip-ident.h>
2388 +#include <media/v4l2-i2c-drv.h>
2389 +
2390 +#include "ci_sensor_common.h"
2391 +#include "ov5630.h"
2392 +
2393 +static int mrstov5630_debug;
2394 +module_param(mrstov5630_debug, int, 0644);
2395 +MODULE_PARM_DESC(mrstov5630_debug, "Debug level (0-1)");
2396 +
2397 +#define dprintk(level, fmt, arg...) do {                       \
2398 +       if (mrstov5630_debug >= level)                                  \
2399 +               printk(KERN_DEBUG "mrstisp@%s: " fmt "\n",      \
2400 +                      __func__, ## arg); } \
2401 +       while (0)
2402 +
2403 +#define eprintk(fmt, arg...)   \
2404 +       printk(KERN_ERR "mrstisp@%s: line %d: " fmt "\n",       \
2405 +              __func__, __LINE__, ## arg);
2406 +
2407 +#define DBG_entering   dprintk(2, "entering");
2408 +#define DBG_leaving    dprintk(2, "leaving");
2409 +#define DBG_line       dprintk(2, " line: %d", __LINE__);
2410 +
2411 +static inline struct ci_sensor_config *to_sensor_config(struct v4l2_subdev *sd)
2412 +{
2413 +       return container_of(sd, struct ci_sensor_config, sd);
2414 +}
2415 +
2416 +/* static int ov5630_set_res(struct i2c_client *c, const int w, const int h);
2417 + */
2418 +static struct ov5630_format_struct {
2419 +       __u8 *desc;
2420 +       __u32 pixelformat;
2421 +       struct regval_list *regs;
2422 +} ov5630_formats[] = {
2423 +       {
2424 +               .desc           = "Raw RGB Bayer",
2425 +               .pixelformat    = SENSOR_MODE_BAYER,
2426 +               .regs           = NULL,
2427 +       },
2428 +};
2429 +#define N_OV5630_FMTS ARRAY_SIZE(ov5630_formats)
2430 +
2431 +static struct ov5630_res_struct {
2432 +       __u8 *desc;
2433 +       int res;
2434 +       int width;
2435 +       int height;
2436 +       /* FIXME: correct the fps values.. */
2437 +       int fps;
2438 +       bool used;
2439 +       struct regval_list *regs;
2440 +} ov5630_res[] = {
2441 +       {
2442 +               .desc           = "QSXGA_PLUS4",
2443 +               .res            = SENSOR_RES_QXGA_PLUS,
2444 +               .width          = 2592,
2445 +               .height         = 1944,
2446 +               .fps            = 15,
2447 +               .used           = 0,
2448 +               .regs           = ov5630_res_qsxga_plus4,
2449 +       },
2450 +       {
2451 +               .desc           = "1080P",
2452 +               .res            = SENSOR_RES_1080P,
2453 +               .width          = 1920,
2454 +               .height         = 1080,
2455 +               .fps            = 25,
2456 +               .used           = 0,
2457 +               .regs           = ov5630_res_1080p,
2458 +       },
2459 +       {
2460 +               .desc           = "XGA_PLUS",
2461 +               .res            = SENSOR_RES_XGA_PLUS,
2462 +               .width          = 1280,
2463 +               .height         = 960,
2464 +               .fps            = 30,
2465 +               .used           = 0,
2466 +               .regs           = ov5630_res_xga_plus,
2467 +       },
2468 +       {
2469 +               .desc           = "720p",
2470 +               .res            = SENSOR_RES_720P,
2471 +               .width          = 1280,
2472 +               .height         = 720,
2473 +               .fps            = 34,
2474 +               .used           = 0,
2475 +               .regs           = ov5630_res_720p,
2476 +       },
2477 +       {
2478 +               .desc           = "VGA",
2479 +               .res            = SENSOR_RES_VGA,
2480 +               .width          = 640,
2481 +               .height         = 480,
2482 +               .fps            = 39,
2483 +               .used           = 0,
2484 +               .regs           = ov5630_res_vga_ac04_bill,
2485 +       },
2486 +};
2487 +
2488 +#define N_RES (ARRAY_SIZE(ov5630_res))
2489 +
2490 +/*
2491 + * I2C Read & Write stuff
2492 + */
2493 +static int ov5630_read(struct i2c_client *c, u32 reg, u32 *value)
2494 +{
2495 +       int ret;
2496 +       int i;
2497 +       struct i2c_msg msg[2];
2498 +       u8 msgbuf[2];
2499 +       u8 ret_val = 0;
2500 +       *value = 0;
2501 +       /* Read needs two message to go */
2502 +       memset(&msg, 0, sizeof(msg));
2503 +       msgbuf[0] = 0;
2504 +       msgbuf[1] = 0;
2505 +       i = 0;
2506 +
2507 +       msgbuf[i++] = ((u16)reg) >> 8;
2508 +       msgbuf[i++] = ((u16)reg) & 0xff;
2509 +       msg[0].addr = c->addr;
2510 +       msg[0].buf = msgbuf;
2511 +       msg[0].len = i;
2512 +
2513 +       msg[1].addr = c->addr;
2514 +       msg[1].flags = I2C_M_RD;
2515 +       msg[1].buf = &ret_val;
2516 +       msg[1].len = 1;
2517 +
2518 +       ret = i2c_transfer(c->adapter, &msg[0], 2);
2519 +       *value = ret_val;
2520 +
2521 +       ret = (ret == 2) ? 0 : -1;
2522 +       return ret;
2523 +}
2524 +
2525 +static int ov5630_write(struct i2c_client *c, u32 reg, u32 value)
2526 +{
2527 +       int ret, i;
2528 +       struct i2c_msg msg;
2529 +       u8 msgbuf[3];
2530 +
2531 +       /* Writing only needs one message */
2532 +       memset(&msg, 0, sizeof(msg));
2533 +       i = 0;
2534 +       msgbuf[i++] = ((u16)reg) >> 8;
2535 +       msgbuf[i++] = (u16)reg & 0xff;
2536 +       msgbuf[i++] = (u8)value;
2537 +
2538 +       msg.addr = c->addr;
2539 +       msg.flags = 0;
2540 +       msg.buf = msgbuf;
2541 +       msg.len = i;
2542 +
2543 +       ret = i2c_transfer(c->adapter, &msg, 1);
2544 +
2545 +       /* If this is a reset register, wait for 1ms */
2546 +       if (reg == OV5630_SYS && (value & 0x80))
2547 +               msleep(3);
2548 +
2549 +       ret = (ret == 1) ? 0 : -1;
2550 +       return ret;
2551 +}
2552 +
2553 +static int ov5630_write_array(struct i2c_client *c, struct regval_list *vals)
2554 +{
2555 +       struct regval_list *p;
2556 +       u32 read_val = 0;
2557 +       int err_num = 0;
2558 +       int i = 0;
2559 +       p = vals;
2560 +       while (p->reg_num != 0xffff) {
2561 +               ov5630_write(c, (u32)p->reg_num, (u32)p->value);
2562 +               ov5630_read(c, (u32)p->reg_num, &read_val);
2563 +               if (read_val != p->value)
2564 +                       err_num++;
2565 +               p++;
2566 +               i++;
2567 +       }
2568 +       return 0;
2569 +}
2570 +
2571 +/*
2572 + * Sensor specific helper function
2573 + */
2574 +static int ov5630_standby(void)
2575 +{
2576 +       gpio_set_value(GPIO_STDBY_PIN, 1);
2577 +       /* ov5630_motor_standby(); */
2578 +       dprintk(1, "PM: standby called\n");
2579 +       return 0;
2580 +}
2581 +
2582 +static int ov5630_wakeup(void)
2583 +{
2584 +       gpio_set_value(GPIO_STDBY_PIN, 0);
2585 +       /* ov5630_motor_wakeup(); */
2586 +       dprintk(1, "PM: wakeup called\n");
2587 +       return 0;
2588 +}
2589 +
2590 +static int ov5630_s_power(struct v4l2_subdev *sd, u32 val)
2591 +{
2592 +       if (val == 1)
2593 +               ov5630_standby();
2594 +       if (val == 0)
2595 +               ov5630_wakeup();
2596 +       return 0;
2597 +}
2598 +
2599 +static int ov5630_set_img_ctrl(struct i2c_client *c,
2600 +                              const struct ci_sensor_config *config)
2601 +{
2602 +       int err = 0;
2603 +       u32 reg_val = 0;
2604 +       /* struct ci_sensor_config *info = i2c_get_clientdata(c); */
2605 +
2606 +       switch (config->blc) {
2607 +       case SENSOR_BLC_OFF:
2608 +               err |= ov5630_read(c, OV5630_ISP_CTL00, &reg_val);
2609 +               err |= ov5630_write(c, OV5630_ISP_CTL00, reg_val & 0xFE);
2610 +               break;
2611 +       case SENSOR_BLC_AUTO:
2612 +               err |= ov5630_read(c, OV5630_ISP_CTL00, &reg_val);
2613 +               err |= ov5630_write(c, OV5630_ISP_CTL00, reg_val | 0x01);
2614 +               break;
2615 +       }
2616 +
2617 +       switch (config->agc) {
2618 +       case SENSOR_AGC_AUTO:
2619 +               err |= ov5630_read(c, OV5630_AUTO_1, &reg_val);
2620 +               err |= ov5630_write(c, OV5630_AUTO_1, reg_val | 0x04);
2621 +               break;
2622 +       case SENSOR_AGC_OFF:
2623 +               err |= ov5630_read(c, OV5630_AUTO_1, &reg_val);
2624 +               err |= ov5630_write(c, OV5630_AUTO_1, reg_val & ~0x04);
2625 +               break;
2626 +       }
2627 +
2628 +       switch (config->awb) {
2629 +       case SENSOR_AWB_AUTO:
2630 +               err |= ov5630_read(c, OV5630_ISP_CTL00, &reg_val);
2631 +               err |= ov5630_write(c, OV5630_ISP_CTL00, reg_val | 0x30);
2632 +               break;
2633 +       case SENSOR_AWB_OFF:
2634 +               err |= ov5630_read(c, OV5630_ISP_CTL00, &reg_val);
2635 +               err |= ov5630_write(c, OV5630_ISP_CTL00, reg_val & ~0x30);
2636 +               break;
2637 +       }
2638 +
2639 +       switch (config->aec) {
2640 +       case SENSOR_AEC_AUTO:
2641 +               err |= ov5630_read(c, OV5630_AUTO_1, &reg_val);
2642 +               err |= ov5630_write(c, OV5630_AUTO_1, reg_val | 0xFB);
2643 +               break;
2644 +       case SENSOR_AEC_OFF:
2645 +               err |= ov5630_read(c, OV5630_AUTO_1, &reg_val);
2646 +               err |= ov5630_write(c, OV5630_AUTO_1, reg_val & 0xF6);
2647 +               break;
2648 +       }
2649 +
2650 +       return err;
2651 +}
2652 +
2653 +static int ov5630_init(struct i2c_client *c)
2654 +{
2655 +       int ret;
2656 +       struct v4l2_subdev *sd = i2c_get_clientdata(c);
2657 +       struct ci_sensor_config *info = to_sensor_config(sd);
2658 +       char *name = "";
2659 +
2660 +       /* Fill the configuration structure */
2661 +       /* Note this default configuration value */
2662 +       info->mode = ov5630_formats[0].pixelformat;
2663 +       info->res = ov5630_res[0].res;
2664 +       info->type = SENSOR_TYPE_RAW;
2665 +       info->bls = SENSOR_BLS_OFF;
2666 +       info->gamma = SENSOR_GAMMA_OFF;
2667 +       info->cconv = SENSOR_CCONV_OFF;
2668 +       info->blc = SENSOR_BLC_AUTO;
2669 +       info->agc = SENSOR_AGC_AUTO;
2670 +       info->awb = SENSOR_AWB_AUTO;
2671 +       info->aec = SENSOR_AEC_AUTO;
2672 +       /* info->bus_width = SENSOR_BUSWIDTH_10BIT; */
2673 +       info->bus_width = SENSOR_BUSWIDTH_10BIT_ZZ;
2674 +       info->ycseq = SENSOR_YCSEQ_YCBYCR;
2675 +       /* info->conv422 = SENSOR_CONV422_NOCOSITED; */
2676 +       info->conv422 = SENSOR_CONV422_COSITED;
2677 +       info->bpat = SENSOR_BPAT_BGBGGRGR;
2678 +       info->field_inv = SENSOR_FIELDINV_NOSWAP;
2679 +       info->field_sel = SENSOR_FIELDSEL_BOTH;
2680 +       info->hpol = SENSOR_HPOL_REFPOS;
2681 +       info->vpol = SENSOR_VPOL_NEG;
2682 +       info->edge = SENSOR_EDGE_RISING;
2683 +       info->flicker_freq = SENSOR_FLICKER_100;
2684 +       info->cie_profile = SENSOR_CIEPROF_F11;
2685 +       name = "ov5630";
2686 +       memcpy(info->name, name, 7);
2687 +
2688 +       /* Reset sensor hardware, and implement the setting*/
2689 +       ret = ov5630_write(c, (u32)OV5630_SYS, (u32)0x80);
2690 +       ret += ov5630_write(c, (u32)OV5630_IMAGE_SYSTEM, (u32)0x00);
2691 +
2692 +       /* Set registers into default config value */
2693 +       ret += ov5630_write_array(c, ov5630_def_reg);
2694 +
2695 +       /* Set MIPI interface */
2696 +#ifdef OV5630_MIPI
2697 +       ret += ov5630_write_array(c, ov5630_mipi);
2698 +#endif
2699 +
2700 +       /* turn off AE AEB AGC */
2701 +       ret += ov5630_set_img_ctrl(c, info);
2702 +
2703 +       /* streaming */
2704 +       /* ret += ov5630_write(c, (u32)OV5630_IMAGE_SYSTEM, (u32)0x01); */
2705 +       /* ret += ov5630_write(c, (u32)0x3096, (u32)0x50); */
2706 +       /* /ssleep(1); */
2707 +
2708 +       /* Added by wen to stop sensor from streaming */
2709 +       ov5630_write(c, (u32)OV5630_IMAGE_SYSTEM, (u32)0x00);
2710 +       ov5630_write(c, 0x30b0, 0x00);
2711 +       ov5630_write(c, 0x30b1, 0x00);
2712 +       return ret;
2713 +}
2714 +
2715 +static int distance(struct ov5630_res_struct *res, u32 w, u32 h)
2716 +{
2717 +       int ret;
2718 +       if (res->width < w || res->height < h)
2719 +               return -1;
2720 +
2721 +       ret = ((res->width - w) + (res->height - h));
2722 +       return ret;
2723 +}
2724 +static int ov5630_try_res(u32 *w, u32 *h)
2725 +{
2726 +       struct ov5630_res_struct *res_index, *p = NULL;
2727 +       int dis, last_dis = ov5630_res->width + ov5630_res->height;
2728 +
2729 +       DBG_entering;
2730 +
2731 +       for (res_index = ov5630_res;
2732 +            res_index < ov5630_res + N_RES;
2733 +            res_index++) {
2734 +               if ((res_index->width < *w) || (res_index->height < *h))
2735 +                       break;
2736 +               dis = distance(res_index, *w, *h);
2737 +               if (dis < last_dis) {
2738 +                       last_dis = dis;
2739 +                       p = res_index;
2740 +               }
2741 +       }
2742 +
2743 +       if (p == NULL)
2744 +               p = ov5630_res;
2745 +       else if ((p->width < *w) || (p->height < *h)) {
2746 +               if (p != ov5630_res)
2747 +                       p--;
2748 +       }
2749 +
2750 +       if ((w != NULL) && (h != NULL)) {
2751 +               *w = p->width;
2752 +               *h = p->height;
2753 +       }
2754 +
2755 +       DBG_leaving;
2756 +       return 0;
2757 +}
2758 +
2759 +static struct ov5630_res_struct *ov5630_to_res(u32 w, u32 h)
2760 +{
2761 +       struct ov5630_res_struct *res_index;
2762 +
2763 +       for (res_index = ov5630_res;
2764 +            res_index < ov5630_res + N_RES;
2765 +            res_index++)
2766 +               if ((res_index->width == w) && (res_index->height == h))
2767 +                       break;
2768 +
2769 +       if (res_index >= ov5630_res + N_RES)
2770 +               res_index--;   /* Take the bigger one */
2771 +
2772 +       return res_index;
2773 +}
2774 +
2775 +static int ov5630_try_fmt(struct v4l2_subdev *sd,
2776 +                         struct v4l2_format *fmt)
2777 +{
2778 +       DBG_entering;
2779 +       return ov5630_try_res(&fmt->fmt.pix.width, &fmt->fmt.pix.height);
2780 +       DBG_leaving;
2781 +}
2782 +
2783 +static int ov5630_get_fmt(struct v4l2_subdev *sd,
2784 +                         struct v4l2_format *fmt)
2785 +{
2786 +       struct ci_sensor_config *info = to_sensor_config(sd);
2787 +       unsigned short width, height;
2788 +       int index;
2789 +
2790 +       ci_sensor_res2size(info->res, &width, &height);
2791 +
2792 +       /* Marked the current sensor res as being "used" */
2793 +       for (index = 0; index < N_RES; index++) {
2794 +               if ((width == ov5630_res[index].width) &&
2795 +                   (height == ov5630_res[index].height)) {
2796 +                       ov5630_res[index].used = 1;
2797 +                       continue;
2798 +               }
2799 +               ov5630_res[index].used = 0;
2800 +       }
2801 +
2802 +       fmt->fmt.pix.width = width;
2803 +       fmt->fmt.pix.height = height;
2804 +       return 0;
2805 +}
2806 +
2807 +static int ov5630_set_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
2808 +{
2809 +       struct i2c_client *c = v4l2_get_subdevdata(sd);
2810 +       struct ci_sensor_config *info = to_sensor_config(sd);
2811 +       int ret = 0;
2812 +       struct ov5630_res_struct *res_index;
2813 +       u32 width, height;
2814 +       int index;
2815 +
2816 +       DBG_entering;
2817 +
2818 +       width = fmt->fmt.pix.width;
2819 +       height = fmt->fmt.pix.height;
2820 +
2821 +       dprintk(1, "was told to set fmt (%d x %d) ", width, height);
2822 +
2823 +       ret = ov5630_try_res(&width, &height);
2824 +
2825 +       dprintk(1, "setting fmt (%d x %d) ", width, height);
2826 +
2827 +       res_index = ov5630_to_res(width, height);
2828 +
2829 +       ov5630_wakeup();
2830 +
2831 +       if (res_index->regs) {
2832 +               /* Soft reset camera first*/
2833 +               ret = ov5630_write(c, (u32)OV5630_SYS, (u32)0x80);
2834 +
2835 +               /* software sleep/standby */
2836 +               ret += ov5630_write(c, (u32)OV5630_IMAGE_SYSTEM, (u32)0x00);
2837 +
2838 +               /* Set registers into default config value */
2839 +               ret += ov5630_write_array(c, ov5630_def_reg);
2840 +
2841 +               /* set image resolution */
2842 +               ret += ov5630_write_array(c, res_index->regs);
2843 +
2844 +               /* turn off AE AEB AGC */
2845 +               ret += ov5630_set_img_ctrl(c, info);
2846 +
2847 +               /* Set MIPI interface */
2848 +#ifdef OV5630_MIPI
2849 +               ret += ov5630_write_array(c, ov5630_mipi);
2850 +#endif
2851 +
2852 +               if (res_index->res == SENSOR_RES_VGA)
2853 +                       ret += ov5630_write(c, (u32)0x3015, (u32)0x03);
2854 +
2855 +               /* streaming */
2856 +               ret = ov5630_write(c, (u32)OV5630_IMAGE_SYSTEM, (u32)0x01);
2857 +               ret = ov5630_write(c, (u32)0x3096, (u32)0x50);
2858 +
2859 +               info->res = res_index->res;
2860 +
2861 +               /* Marked current sensor res as being "used" */
2862 +               for (index = 0; index < N_RES; index++) {
2863 +                       if ((width == ov5630_res[index].width) &&
2864 +                           (height == ov5630_res[index].height)) {
2865 +                               ov5630_res[index].used = 1;
2866 +                               continue;
2867 +                       }
2868 +                       ov5630_res[index].used = 0;
2869 +               }
2870 +
2871 +               for (index = 0; index < N_RES; index++)
2872 +                       dprintk(2, "index = %d, used = %d\n", index,
2873 +                               ov5630_res[index].used);
2874 +       } else {
2875 +               eprintk("no res for (%d x %d)", width, height);
2876 +       }
2877 +
2878 +       DBG_leaving;
2879 +       return ret;
2880 +}
2881 +
2882 +static int ov5630_t_gain(struct v4l2_subdev *sd, int value)
2883 +{
2884 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
2885 +       u32 v;
2886 +
2887 +       DBG_entering;
2888 +
2889 +       dprintk(2, "writing gain %x to 0x3000", value);
2890 +
2891 +       ov5630_read(client, 0x3000, &v);
2892 +       v = (v & 0x80) + value;
2893 +       ov5630_write(client, 0x3000, v);
2894 +
2895 +       dprintk(2, "gain %x was writen to 0x3000", v);
2896 +
2897 +       DBG_leaving;
2898 +       return 0;
2899 +}
2900 +
2901 +static int ov5630_t_exposure(struct v4l2_subdev *sd, int value)
2902 +{
2903 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
2904 +       u32 v;
2905 +       u32 reg_val;
2906 +
2907 +       DBG_entering;
2908 +
2909 +       ov5630_read(client, 0x3013, &v);
2910 +       dprintk(2, "0x3013 = %x", v);
2911 +       if (v & 0x05) {
2912 +               /* turn off agc/aec */
2913 +               v = v & 0xfa;
2914 +               ov5630_write(client, 0x3013, v);
2915 +               /* turn off awb */
2916 +               ov5630_read(client, OV5630_ISP_CTL00, &reg_val);
2917 +               ov5630_write(client, OV5630_ISP_CTL00, reg_val & ~0x30);
2918 +       }
2919 +       ov5630_read(client, 0x3014, &v);
2920 +       dprintk(2, "0x3014 = %x", v);
2921 +       ov5630_read(client, 0x3002, &v);
2922 +       dprintk(2, "0x3002 = %x", v);
2923 +       ov5630_read(client, 0x3003, &v);
2924 +       dprintk(2, "0x3003 = %x", v);
2925 +
2926 +       dprintk(2, "writing exposure %x to 0x3002/3", value);
2927 +
2928 +       v = value >> 8;
2929 +       ov5630_write(client, 0x3002, v);
2930 +       dprintk(2, "exposure %x was writen to 0x3002", v);
2931 +
2932 +       v = value & 0xff;
2933 +       ov5630_write(client, 0x3003, v);
2934 +       dprintk(2, "exposure %x was writen to 0x3003", v);
2935 +
2936 +       DBG_leaving;
2937 +       return 0;
2938 +}
2939 +
2940 +static struct ov5630_control {
2941 +       struct v4l2_queryctrl qc;
2942 +       int (*query)(struct v4l2_subdev *sd, __s32 *value);
2943 +       int (*tweak)(struct v4l2_subdev *sd, int value);
2944 +} ov5630_controls[] = {
2945 +       {
2946 +               .qc = {
2947 +                       .id = V4L2_CID_GAIN,
2948 +                       .type = V4L2_CTRL_TYPE_INTEGER,
2949 +                       .name = "global gain",
2950 +                       .minimum = 0x0,
2951 +                       .maximum = 0xFF,
2952 +                       .step = 0x01,
2953 +                       .default_value = 0x00,
2954 +                       .flags = 0,
2955 +               },
2956 +               .tweak = ov5630_t_gain,
2957 +/*             .query = ov5630_q_gain, */
2958 +       },
2959 +       {
2960 +               .qc = {
2961 +                       .id = V4L2_CID_EXPOSURE,
2962 +                       .type = V4L2_CTRL_TYPE_INTEGER,
2963 +                       .name = "exposure",
2964 +                       .minimum = 0x0,
2965 +                       .maximum = 0xFFFF,
2966 +                       .step = 0x01,
2967 +                       .default_value = 0x00,
2968 +                       .flags = 0,
2969 +               },
2970 +               .tweak = ov5630_t_exposure,
2971 +/*             .query = ov5630_q_exposure; */
2972 +       },
2973 +};
2974 +#define N_CONTROLS (ARRAY_SIZE(ov5630_controls))
2975 +
2976 +/*
2977 +static int ov5630_g_gain(struct v4l2_subdev *sd, int value)
2978 +{
2979 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
2980 +       unsigned char v;
2981 +
2982 +       DBG_entering;
2983 +
2984 +       ov5630_write(client, 0x3000, &v);
2985 +       dprintk(2, "writing gain %x to 0x3000", value);
2986 +
2987 +       value
2988 +       DBG_leaving;
2989 +       return 0
2990 +}
2991 +*/
2992 +
2993 +static struct ov5630_control *ov5630_find_control(__u32 id)
2994 +{
2995 +       int i;
2996 +
2997 +       for (i = 0; i < N_CONTROLS; i++)
2998 +               if (ov5630_controls[i].qc.id == id)
2999 +                       return ov5630_controls + i;
3000 +       return NULL;
3001 +}
3002 +
3003 +static int ov5630_queryctrl(struct v4l2_subdev *sd,
3004 +                           struct v4l2_queryctrl *qc)
3005 +{
3006 +       struct ov5630_control *ctrl = ov5630_find_control(qc->id);
3007 +
3008 +       if (ctrl == NULL)
3009 +               return -EINVAL;
3010 +       *qc = ctrl->qc;
3011 +       return 0;
3012 +}
3013 +
3014 +static int ov5630_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
3015 +{
3016 +       /*
3017 +       struct ov5630_control *octrl = ov5630_find_control(ctrl->id);
3018 +
3019 +       int ret;
3020 +
3021 +       if (octrl == NULL)
3022 +               return -EINVAL;
3023 +       ret = octrl->query(sd, &ctrl->value);
3024 +       if (ret >= 0)
3025 +               return 0;
3026 +       return ret;
3027 +       */
3028 +       return 0;
3029 +}
3030 +
3031 +static int ov5630_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
3032 +{
3033 +       struct ov5630_control *octrl = ov5630_find_control(ctrl->id);
3034 +       int ret;
3035 +
3036 +       if (octrl == NULL)
3037 +               return -EINVAL;
3038 +       ret =  octrl->tweak(sd, ctrl->value);
3039 +       if (ret >= 0)
3040 +               return 0;
3041 +       return ret;
3042 +}
3043 +
3044 +#if 0
3045 +static int ov5630_get_caps(struct i2c_client *c, struct ci_sensor_caps *caps)
3046 +{
3047 +       if (caps == NULL)
3048 +               return -EIO;
3049 +
3050 +       caps->bus_width = SENSOR_BUSWIDTH_10BIT;
3051 +       caps->mode      = SENSOR_MODE_BAYER;
3052 +       caps->field_inv = SENSOR_FIELDINV_NOSWAP;
3053 +       caps->field_sel = SENSOR_FIELDSEL_BOTH;
3054 +       caps->ycseq     = SENSOR_YCSEQ_YCBYCR;
3055 +       caps->conv422   = SENSOR_CONV422_NOCOSITED;
3056 +       caps->bpat      = SENSOR_BPAT_BGBGGRGR;
3057 +       caps->hpol      = SENSOR_HPOL_REFPOS;
3058 +       caps->vpol      = SENSOR_VPOL_NEG;
3059 +       caps->edge      = SENSOR_EDGE_RISING;
3060 +       caps->bls       = SENSOR_BLS_OFF;
3061 +       caps->gamma     = SENSOR_GAMMA_OFF;
3062 +       caps->cconv     = SENSOR_CCONV_OFF;
3063 +       caps->res       = SENSOR_RES_QXGA_PLUS | SENSOR_RES_1080P |
3064 +           SENSOR_RES_XGA_PLUS | SENSOR_RES_720P | SENSOR_RES_VGA;
3065 +       caps->blc       = SENSOR_BLC_OFF;
3066 +       caps->agc       = SENSOR_AGC_OFF;
3067 +       caps->awb       = SENSOR_AWB_OFF;
3068 +       caps->aec       = SENSOR_AEC_OFF;
3069 +       caps->cie_profile = SENSOR_CIEPROF_D65 | SENSOR_CIEPROF_D75 |
3070 +           SENSOR_CIEPROF_F11 | SENSOR_CIEPROF_F12 | SENSOR_CIEPROF_A |
3071 +           SENSOR_CIEPROF_F2;
3072 +       caps->flicker_freq      = SENSOR_FLICKER_100 | SENSOR_FLICKER_120;
3073 +       caps->type      = SENSOR_TYPE_RAW;
3074 +       /* caps->name   = "ov5630"; */
3075 +       strcpy(caps->name, "ov5630");
3076 +
3077 +       return 0;
3078 +}
3079 +
3080 +static int ov5630_get_config(struct i2c_client *c,
3081 +                            struct ci_sensor_config *config)
3082 +{
3083 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
3084 +
3085 +       if (config == NULL) {
3086 +               printk(KERN_WARNING "sensor_get_config: NULL pointer\n");
3087 +               return -EIO;
3088 +       }
3089 +
3090 +       memcpy(config, info, sizeof(struct ci_sensor_config));
3091 +
3092 +       return 0;
3093 +}
3094 +
3095 +static int ov5630_setup(struct i2c_client *c,
3096 +                       const struct ci_sensor_config *config)
3097 +{
3098 +       int ret;
3099 +       u16 width, high;
3100 +       struct ov5630_res_struct *res_index;
3101 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
3102 +
3103 +       /* Soft reset camera first*/
3104 +       ret = ov5630_write(c, (u32)OV5630_SYS, (u32)0x80);
3105 +
3106 +       /* software sleep/standby */
3107 +       ret = ov5630_write(c, (u32)OV5630_IMAGE_SYSTEM, (u32)0x00);
3108 +
3109 +       /* Set registers into default config value */
3110 +       ret = ov5630_write_array(c, ov5630_def_reg);
3111 +
3112 +       /* set image resolution */
3113 +       ci_sensor_res2size(config->res, &width, &high);
3114 +       ret += ov5630_try_res(&width, &high);
3115 +       res_index = ov5630_find_res(width, high);
3116 +       if (res_index->regs)
3117 +               ret += ov5630_write_array(c, res_index->regs);
3118 +       if (!ret)
3119 +               info->res = res_index->res;
3120 +
3121 +       ret += ov5630_set_img_ctrl(c, config);
3122 +
3123 +       /* Set MIPI interface */
3124 +#ifdef OV5630_MIPI
3125 +       ret += ov5630_write_array(c, ov5630_mipi);
3126 +#endif
3127 +
3128 +       /* streaming */
3129 +       ret += ov5630_write(c, (u32)OV5630_IMAGE_SYSTEM, (u32)0x01);
3130 +       ret += ov5630_write(c, (u32)0x3096, (u32)0x50);
3131 +
3132 +       /*Note here for the time delay */
3133 +       /* ssleep(1); */
3134 +       msleep(500);
3135 +       return ret;
3136 +}
3137 +
3138 +/*
3139 + * File operation functions
3140 + */
3141 +static int ov5630_dvp_enable(struct i2c_client *client)
3142 +{
3143 +       int ret;
3144 +
3145 +       u8 reg;
3146 +
3147 +       ret = ov5630_read(client, 0x3506, &reg);
3148 +       reg &= 0xdf;
3149 +       reg |= 0x20;
3150 +       ret += ov5630_write(client, 0x3506, reg);
3151 +
3152 +       return ret;
3153 +}
3154 +
3155 +static int ov5630_dvp_disable(struct i2c_client *client)
3156 +{
3157 +       int ret;
3158 +
3159 +       u8 reg;
3160 +
3161 +       ret = ov5630_read(client, 0x3506, &reg);
3162 +       reg &= 0xdf;
3163 +       ret += ov5630_write(client, 0x3506, reg);
3164 +
3165 +       return ret;
3166 +}
3167 +
3168 +static int ov5630_open(struct i2c_setting *c, void *priv)
3169 +{
3170 +       /* Just wake up sensor */
3171 +       if (ov5630_wakeup())
3172 +               return -EIO;
3173 +       ov5630_init(c->sensor_client);
3174 +       /* ov5630_motor_init(c->motor_client); */
3175 +       ov5630_write(c->sensor_client, (u32)OV5630_IMAGE_SYSTEM, (u32)0x00);
3176 +
3177 +       /* disable dvp_en */
3178 +       ov5630_dvp_disable(c->sensor_client);
3179 +
3180 +       return 0;
3181 +}
3182 +
3183 +static int ov5630_release(struct i2c_setting *c, void *priv)
3184 +{
3185 +       /* Just suspend the sensor */
3186 +       if (ov5630_standby())
3187 +               return -EIO;
3188 +       return 0;
3189 +}
3190 +
3191 +static int ov5630_on(struct i2c_setting *c)
3192 +{
3193 +       int ret;
3194 +
3195 +       /* Software wake up sensor */
3196 +       ret = ov5630_write(c->sensor_client,
3197 +                           (u32)OV5630_IMAGE_SYSTEM, (u32)0x01);
3198 +
3199 +       /* enable dvp_en */
3200 +       return ret + ov5630_dvp_enable(c->sensor_client);
3201 +}
3202 +
3203 +static int ov5630_off(struct i2c_setting *c)
3204 +{
3205 +       int ret;
3206 +
3207 +       /* Software standby sensor */
3208 +       ret = ov5630_write(c->sensor_client,
3209 +                           (u32)OV5630_IMAGE_SYSTEM, (u32)0x00);
3210 +       /* disable dvp_en */
3211 +       return ret + ov5630_dvp_disable(c->sensor_client);
3212 +}
3213 +
3214 +static struct sensor_device ov5630 = {
3215 +       .name   = "ov5630",
3216 +       .type   = SENSOR_TYPE_RAW,
3217 +       .minor  = -1,
3218 +       .open   = ov5630_open,
3219 +       .release = ov5630_release,
3220 +       .on = ov5630_on,
3221 +       .off = ov5630_off,
3222 +       .querycap = ov5630_get_caps,
3223 +       .get_config = ov5630_get_config,
3224 +       .set_config = ov5630_setup,
3225 +       .enum_parm = ov5630_queryctrl,
3226 +       .get_parm = ov5630_g_ctrl,
3227 +       .set_parm = ov5630_s_ctrl,
3228 +       .try_res = ov5630_try_res,
3229 +       .set_res = ov5630_set_res,
3230 +       .get_ls_corr_config = NULL,
3231 +       .mdi_get_focus = ov5630_motor_get_focus,
3232 +       .mdi_set_focus = ov5630_motor_set_focus,
3233 +       .mdi_max_step = ov5630_motor_max_step,
3234 +       .mdi_calibrate = NULL,
3235 +       .read = ov5630_read,
3236 +       .write = ov5630_write,
3237 +       .suspend = ov5630_standby,
3238 +       .resume = ov5630_wakeup,
3239 +       /* TBC */
3240 +};
3241 +#endif
3242 +
3243 +static int ov5630_s_stream(struct v4l2_subdev *sd, int enable)
3244 +{
3245 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
3246 +       DBG_entering;
3247 +
3248 +       if (enable) {
3249 +               ov5630_write(client, (u32)OV5630_IMAGE_SYSTEM, (u32)0x01);
3250 +               ov5630_write(client, 0x30b0, 0xff);
3251 +               ov5630_write(client, 0x30b1, 0xff);
3252 +               msleep(500);
3253 +       } else {
3254 +               ov5630_write(client, (u32)OV5630_IMAGE_SYSTEM, (u32)0x00);
3255 +               ov5630_write(client, 0x30b0, 0x00);
3256 +               ov5630_write(client, 0x30b1, 0x00);
3257 +       }
3258 +
3259 +       DBG_leaving;
3260 +       return 0;
3261 +}
3262 +
3263 +static int ov5630_enum_framesizes(struct v4l2_subdev *sd,
3264 +                                 struct v4l2_frmsizeenum *fsize)
3265 +{
3266 +       unsigned int index = fsize->index;
3267 +
3268 +       DBG_entering;
3269 +
3270 +       if (index >= N_RES)
3271 +               return -EINVAL;
3272 +
3273 +       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
3274 +       fsize->discrete.width = ov5630_res[index].width;
3275 +       fsize->discrete.height = ov5630_res[index].height;
3276 +       fsize->reserved[0] = ov5630_res[index].used;
3277 +
3278 +       DBG_leaving;
3279 +
3280 +       return 0;
3281 +}
3282 +
3283 +static int ov5630_enum_frameintervals(struct v4l2_subdev *sd,
3284 +                                     struct v4l2_frmivalenum *fival)
3285 +{
3286 +       unsigned int index = fival->index;
3287 +
3288 +       DBG_entering;
3289 +
3290 +       if (index >= N_RES)
3291 +               return -EINVAL;
3292 +
3293 +       fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
3294 +       fival->discrete.numerator = 1;
3295 +       fival->discrete.denominator = ov5630_res[index].fps;
3296 +
3297 +       DBG_leaving;
3298 +
3299 +       return 0;
3300 +}
3301 +
3302 +static int ov5630_g_chip_ident(struct v4l2_subdev *sd,
3303 +               struct v4l2_dbg_chip_ident *chip)
3304 +{
3305 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
3306 +
3307 +#define V4L2_IDENT_OV5630 8245
3308 +       return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV5630, 0);
3309 +}
3310 +
3311 +#ifdef CONFIG_VIDEO_ADV_DEBUG
3312 +static int ov5630_g_register(struct v4l2_subdev *sd,
3313 +                            struct v4l2_dbg_register *reg)
3314 +{
3315 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
3316 +       unsigned char val = 0;
3317 +       int ret;
3318 +
3319 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
3320 +               return -EINVAL;
3321 +       if (!capable(CAP_SYS_ADMIN))
3322 +               return -EPERM;
3323 +       ret = ov5630_read(client, reg->reg & 0xffff, &val);
3324 +       reg->val = val;
3325 +       reg->size = 1;
3326 +       return ret;
3327 +}
3328 +
3329 +static int ov5630_s_register(struct v4l2_subdev *sd,
3330 +                            struct v4l2_dbg_register *reg)
3331 +{
3332 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
3333 +
3334 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
3335 +               return -EINVAL;
3336 +       if (!capable(CAP_SYS_ADMIN))
3337 +               return -EPERM;
3338 +       ov5630_write(client, reg->reg & 0xffff, reg->val & 0xff);
3339 +       return 0;
3340 +}
3341 +#endif
3342 +
3343 +static const struct v4l2_subdev_video_ops ov5630_video_ops = {
3344 +       .try_fmt = ov5630_try_fmt,
3345 +       .s_fmt = ov5630_set_fmt,
3346 +       .g_fmt = ov5630_get_fmt,
3347 +       .s_stream = ov5630_s_stream,
3348 +       .enum_framesizes = ov5630_enum_framesizes,
3349 +       .enum_frameintervals = ov5630_enum_frameintervals,
3350 +};
3351 +
3352 +static const struct v4l2_subdev_core_ops ov5630_core_ops = {
3353 +       .g_chip_ident = ov5630_g_chip_ident,
3354 +       .queryctrl = ov5630_queryctrl,
3355 +       .g_ctrl = ov5630_g_ctrl,
3356 +       .s_ctrl = ov5630_s_ctrl,
3357 +       .s_gpio = ov5630_s_power,
3358 +       /*.g_ext_ctrls = ov5630_g_ext_ctrls,*/
3359 +       /*.s_ext_ctrls = ov5630_s_ext_ctrls,*/
3360 +#ifdef CONFIG_VIDEO_ADV_DEBUG
3361 +       .g_register = ov5630_g_register,
3362 +       .s_register = ov5630_s_register,
3363 +#endif
3364 +};
3365 +
3366 +static const struct v4l2_subdev_ops ov5630_ops = {
3367 +       .core = &ov5630_core_ops,
3368 +       .video = &ov5630_video_ops,
3369 +};
3370 +
3371 +/*
3372 + * Basic i2c stuff
3373 + */
3374 +/*
3375 +static unsigned short normal_i2c[] = {I2C_OV5630 >> 1,
3376 +       I2C_CLIENT_END};
3377 +I2C_CLIENT_INSMOD;
3378 +
3379 +static struct i2c_driver ov5630_driver;
3380 +*/
3381 +static int ov5630_detect(struct i2c_client *client)
3382 +{
3383 +       struct i2c_adapter *adapter = client->adapter;
3384 +       int adap_id = i2c_adapter_id(adapter);
3385 +       u32 value;
3386 +
3387 +       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
3388 +               eprintk("error i2c check func");
3389 +               return -ENODEV;
3390 +       }
3391 +
3392 +       if (adap_id != 1) {
3393 +               eprintk("adap_id != 1");
3394 +               return -ENODEV;
3395 +       }
3396 +
3397 +       /* if (ov5630_wakeup()) */
3398 +               /* return -ENODEV; */
3399 +       ov5630_wakeup();
3400 +
3401 +       ov5630_read(client, (u32)OV5630_PID_H, &value);
3402 +       if ((u8)value != 0x56) {
3403 +               dprintk(1, "PID != 0x56, but %x", value);
3404 +               dprintk(2, "client->addr = %x", client->addr);
3405 +               return -ENODEV;
3406 +       }
3407 +
3408 +       printk(KERN_INFO "Init ov5630 sensor success\n");
3409 +       return 0;
3410 +}
3411 +
3412 +static int ov5630_probe(struct i2c_client *client,
3413 +                       const struct i2c_device_id *id)
3414 +{
3415 +       struct ci_sensor_config *info;
3416 +       struct v4l2_subdev *sd;
3417 +       int ret = -1;
3418 +/*     struct i2c_client *motor; */
3419 +
3420 +       DBG_entering;
3421 +       v4l_info(client, "chip found @ 0x%x (%s)\n",
3422 +                client->addr << 1, client->adapter->name);
3423 +       /*
3424 +        * Setup sensor configuration structure
3425 +        */
3426 +       info = kzalloc(sizeof(struct ci_sensor_config), GFP_KERNEL);
3427 +       if (!info) {
3428 +               eprintk("fail to malloc for ci_sensor_config");
3429 +               ret = -ENOMEM;
3430 +               goto out;
3431 +       }
3432 +
3433 +       ret = ov5630_detect(client);
3434 +       if (ret) {
3435 +               dprintk(1, "error ov5630_detect");
3436 +               goto out_free;
3437 +       }
3438 +
3439 +       sd = &info->sd;
3440 +       v4l2_i2c_subdev_init(sd, client, &ov5630_ops);
3441 +
3442 +       /*
3443 +        * Initialization OV5630
3444 +        * then turn into standby mode
3445 +        */
3446 +       /* ret = ov5630_standby(); */
3447 +       ret = ov5630_init(client);
3448 +       if (ret) {
3449 +               eprintk("error calling ov5630_init");
3450 +               goto out_free;
3451 +       }
3452 +       ov5630_standby();
3453 +
3454 +       ret = 0;
3455 +       goto out;
3456 +
3457 +out_free:
3458 +       kfree(info);
3459 +       DBG_leaving;
3460 +out:
3461 +       return ret;
3462 +}
3463 +
3464 +/*
3465 + * XXX: Need to be checked
3466 + */
3467 +static int ov5630_remove(struct i2c_client *client)
3468 +{
3469 +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
3470 +
3471 +       DBG_entering;
3472 +
3473 +       v4l2_device_unregister_subdev(sd);
3474 +       kfree(to_sensor_config(sd));
3475 +
3476 +       DBG_leaving;
3477 +       return 0;
3478 +}
3479 +
3480 +static const struct i2c_device_id ov5630_id[] = {
3481 +       {"ov5630", 0},
3482 +       {}
3483 +};
3484 +
3485 +MODULE_DEVICE_TABLE(i2c, ov5630_id);
3486 +
3487 +static struct v4l2_i2c_driver_data v4l2_i2c_data = {
3488 +       .name = "ov5630",
3489 +       .probe = ov5630_probe,
3490 +       .remove = ov5630_remove,
3491 +       /* .suspend = ov5630_suspend,
3492 +        * .resume = ov5630_resume, */
3493 +       .id_table = ov5630_id,
3494 +};
3495 +
3496 +MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
3497 +MODULE_DESCRIPTION("A low-level driver for OmniVision 5630 sensors");
3498 +MODULE_LICENSE("GPL");
3499 diff --git a/drivers/media/video/mrstci/mrstov5630/ov5630.h b/drivers/media/video/mrstci/mrstov5630/ov5630.h
3500 new file mode 100644
3501 index 0000000..3da0ecd
3502 --- /dev/null
3503 +++ b/drivers/media/video/mrstci/mrstov5630/ov5630.h
3504 @@ -0,0 +1,672 @@
3505 +/*
3506 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
3507 + *
3508 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
3509 + *
3510 + * This program is free software; you can redistribute it and/or
3511 + * modify it under the terms of the GNU General Public License version
3512 + * 2 as published by the Free Software Foundation.
3513 + *
3514 + * This program is distributed in the hope that it will be useful,
3515 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3516 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3517 + * GNU General Public License for more details.
3518 + *
3519 + * You should have received a copy of the GNU General Public License
3520 + * along with this program; if not, write to the Free Software
3521 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
3522 + * 02110-1301, USA.
3523 + *
3524 + *
3525 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
3526 + */
3527 +
3528 +#define I2C_OV5630     0x6C
3529 +/* Should add to kernel source */
3530 +#define I2C_DRIVERID_OV5630    1046
3531 +/* GPIO pin on Moorestown */
3532 +#define GPIO_SCLK_25   44
3533 +#define GPIO_STB_PIN   47
3534 +#define GPIO_STDBY_PIN 49
3535 +#define GPIO_RESET_PIN 50
3536 +
3537 +/* System control register */
3538 +#define OV5630_AGC             0x3000
3539 +#define OV5630_AGCS    0x3001
3540 +#define OV5630_AEC_H   0x3002
3541 +#define OV5630_AEC_L   0x3003
3542 +#define OV5630_LAEC_H  0x3004
3543 +#define OV5630_LAEC_L  0x3005
3544 +#define OV5630_AECS_H  0x3008
3545 +#define OV5630_AECS_L  0x3009
3546 +#define OV5630_PID_H   0x300A
3547 +#define OV5630_PID_L   0x300B
3548 +#define OV5630_SCCB_ID         0x300C
3549 +#define OV5630_PLL_1   0x300E
3550 +#define OV5630_PLL_2   0x300F
3551 +#define OV5630_PLL_3   0x3010
3552 +#define OV5630_PLL_4           0x3011
3553 +#define OV5630_SYS             0x3012
3554 +#define OV5630_AUTO_1  0x3013
3555 +#define OV5630_AUTO_2  0x3014
3556 +#define OV5630_AUTO_3  0x3015
3557 +#define OV5630_AUTO_4  0x3016
3558 +#define OV5630_AUTO_5  0x3017
3559 +#define OV5630_WPT             0x3018
3560 +#define OV5630_BPT             0x3019
3561 +#define OV5630_VPT             0x301A
3562 +#define OV5630_YAVG            0x301B
3563 +#define OV5630_AECG_50 0x301C
3564 +#define OV5630_AECG_60 0x301D
3565 +#define OV5630_ADDVS_H 0x301E
3566 +#define OV5630_ADDVS_L 0x301F
3567 +#define OV5630_FRAME_LENGTH_LINES_H    0x3020
3568 +#define OV5630_FRAME_LENGTH_LINES_L    0x3021
3569 +#define OV5630_LINE_LENGTH_PCK_H       0x3022
3570 +#define OV5630_LINE_LENGTH_PCK_L       0x3023
3571 +#define OV5630_X_ADDR_START_H  0x3024
3572 +#define OV5630_X_ADDR_START_L  0x3025
3573 +#define OV5630_Y_ADDR_START_H  0x3026
3574 +#define OV5630_Y_ADDR_START_L  0x3027
3575 +#define OV5630_X_ADDR_END_H    0x3028
3576 +#define OV5630_X_ADDR_END_L    0x3029
3577 +#define OV5630_Y_ADDR_END_H    0x302A
3578 +#define OV5630_Y_ADDR_END_L    0x302B
3579 +#define OV5630_X_OUTPUT_SIZE_H 0x302C
3580 +#define OV5630_X_OUTPUT_SIZE_L 0x302D
3581 +#define OV5630_Y_OUTPUT_SIZE_H 0x302E
3582 +#define OV5630_Y_OUTPUT_SIZE_L 0x302F
3583 +#define OV5630_FRAME_CNT       0x3030
3584 +#define OV5630_DATR_LMO_0      0x3038
3585 +#define OV5630_DATR_LMO_1      0x3039
3586 +#define OV5630_DATR_LMO_2      0x303A
3587 +#define OV5630_DATR_D56        0x303D
3588 +#define OV5630_DATR_EF 0x303E
3589 +#define OV5630_R_SIGMA_0       0x3048
3590 +#define OV5630_R_SIGMA_1       0x3049
3591 +#define OV5630_R_SIGMA_2       0x304A
3592 +#define OV5630_R_SIGMA_3       0x304B
3593 +#define OV5630_R_SIGMA_4       0x304C
3594 +#define OV5630_R_SIGMA_5       0x304D
3595 +#define OV5630_D56COM  0x304E
3596 +#define OV5630_5060TH  0x3050
3597 +#define OV5630_LMO_TH1 0x3058
3598 +#define OV5630_LMO_TH2 0x3059
3599 +#define OV5630_LMO_K   0x305A
3600 +#define OV5630_BD50ST_H        0x305C
3601 +#define OV5630_BD50ST_L        0x305D
3602 +#define OV5630_BD60ST_H        0x305E
3603 +#define OV5630_BD60ST_L        0x305F
3604 +#define OV5630_HSYNST  0x306D
3605 +#define OV5630_HSYNED  0x306E
3606 +#define OV5630_HSYNED_HSYNST   0x306F
3607 +#define OV5630_TMC_RWIN0       0x3070
3608 +#define OV5630_IO_CTRL0        0x30B0
3609 +#define OV5630_IO_CTRL1        0x30B1
3610 +#define OV5630_IO_CTRL2        0x30B2
3611 +#define OV5630_DSIO_0  0x30B3
3612 +#define OV5630_DSIO_1  0x30B4
3613 +#define OV5630_DSIO_2  0x30B5
3614 +#define OV5630_TMC_10  0x30B6
3615 +#define OV5630_TMC_12  0x30B7
3616 +#define OV5630_TMC_14  0x30B9
3617 +#define OV5630_TMC_COM4        0x30BA
3618 +#define OV5630_TMC_REG6C       0x30BB
3619 +#define OV5630_TMC_REG6E       0x30BC
3620 +#define OV5630_R_CLK_S 0x30BD
3621 +#define OV5630_R_CLK_A 0x30BE
3622 +#define OV5630_R_CLK_A1        0x30BF
3623 +#define OV5630_FRS_0   0x30E0
3624 +#define OV5630_FRS_1   0x30E1
3625 +#define OV5630_FRS_2   0x30E2
3626 +#define OV5630_FRS_3   0x30E3
3627 +#define OV5630_FRS_FECNT       0x30E4
3628 +#define OV5630_FRS_FECNT_0     0x30E5
3629 +#define OV5630_FRS_FECNT_1     0x30E6
3630 +#define OV5630_FRS_RFRM        0x30E7
3631 +#define OV5630_FRS_RSTRB       0x30E8
3632 +#define OV5630_SA1TMC  0x30E9
3633 +#define OV5630_TMC_MISC0       0x30EA
3634 +#define OV5630_TMC_MISC1       0x30EB
3635 +#define OV5630_FLEX_TXP        0x30F0
3636 +#define OV5630_FLEX_FLT        0x30F1
3637 +#define OV5630_FLEX_TXT        0x30F2
3638 +#define OV5630_FLEX_HBK        0x30F3
3639 +#define OV5630_FLEX_HSG        0x30F4
3640 +#define OV5630_FLEX_SA1SFT     0x30F5
3641 +#define OV5630_RVSOPT  0x30F6
3642 +#define OV5630_AUTO    0x30F7
3643 +#define OV5630_IMAGE_TRANSFORM 0x30F8
3644 +#define OV5630_IMAGE_LUM       0x30F9
3645 +#define OV5630_IMAGE_SYSTEM    0x30FA
3646 +#define OV5630_GROUP_WR        0x30FF
3647 +
3648 +/* CIF control register */
3649 +#define OV5630_CIF_CTRL2       0x3202
3650 +
3651 +/* ISP control register */
3652 +#define OV5630_ISP_CTL00       0x3300
3653 +#define OV5630_ISP_CTL01       0x3301
3654 +#define OV5630_ISP_CTL02       0x3302
3655 +#define OV5630_ISP_03  0x3303
3656 +#define OV5630_ISP_DIG_GAIN_MAN        0x3304
3657 +#define OV5630_ISP_BIAS_MAN    0x3305
3658 +#define OV5630_ISP_06  0x3306
3659 +#define OV5630_ISP_STABLE_RANGE        0x3307
3660 +#define OV5630_ISP_R_GAIN_MAN_1        0x3308
3661 +#define OV5630_ISP_R_GAIN_MAN_0        0x3309
3662 +#define OV5630_ISP_G_GAIN_MAN_1        0x330A
3663 +#define OV5630_ISP_G_GAIN_MAN_0        0x330B
3664 +#define OV5630_ISP_B_GAIN_MAN_1        0x330C
3665 +#define OV5630_ISP_B_GAIN_MAN_0        0x330D
3666 +#define OV5630_ISP_STABLE_RANGEW       0x330E
3667 +#define OV5630_ISP_AWB_FRAME_CNT       0x330F
3668 +#define OV5630_ISP_11  0x3311
3669 +#define OV5630_ISP_12  0x3312
3670 +#define OV5630_ISP_13  0x3313
3671 +#define OV5630_ISP_HSIZE_IN_1  0x3314
3672 +#define OV5630_ISP_HSIZE_IN_0  0x3315
3673 +#define OV5630_ISP_VSIZE_IN_1  0x3316
3674 +#define OV5630_ISP_VSIZE_IN_0  0x3317
3675 +#define OV5630_ISP_18  0x3318
3676 +#define OV5630_ISP_19  0x3319
3677 +#define OV5630_ISP_EVEN_MAN0   0x331A
3678 +#define OV5630_ISP_EVEN_MAN1   0x331B
3679 +#define OV5630_ISP_EVEN_MAN2   0x331C
3680 +#define OV5630_ISP_EVEN_MAN3   0x331D
3681 +#define OV5630_ISP_1E  0x331E
3682 +#define OV5630_ISP_1F  0x331F
3683 +#define OV5630_ISP_BLC_LMT_OPTION      0x3320
3684 +#define OV5630_ISP_BLC_THRE    0x3321
3685 +#define OV5630_ISP_22  0x3322
3686 +#define OV5630_ISP_23  0x3323
3687 +#define OV5630_ISP_BLC_MAN0_1  0x3324
3688 +#define OV5630_ISP_BLC_MAN0_0  0x3325
3689 +#define OV5630_ISP_BLC_MAN1_1  0x3326
3690 +#define OV5630_ISP_BLC_MAN1_0  0x3327
3691 +#define OV5630_ISP_BLC_MAN2_1  0x3328
3692 +#define OV5630_ISP_BLC_MAN2_0  0x3329
3693 +#define OV5630_ISP_BLC_MAN3_1  0x332A
3694 +#define OV5630_ISP_BLC_MAN3_0  0x332B
3695 +#define OV5630_ISP_BLC_MAN4_1  0x332C
3696 +#define OV5630_ISP_BLC_MAN4_0  0x332D
3697 +#define OV5630_ISP_BLC_MAN5_1  0x332E
3698 +#define OV5630_ISP_BLC_MAN5_0  0x332F
3699 +#define OV5630_ISP_BLC_MAN6_1  0x3330
3700 +#define OV5630_ISP_BLC_MAN6_0  0x3331
3701 +#define OV5630_ISP_BLC_MAN7_1  0x3332
3702 +#define OV5630_ISP_BLC_MAN7_0  0x3333
3703 +#define OV5630_ISP_CD  0x33CD
3704 +#define OV5630_ISP_FF  0x33FF
3705 +
3706 +/* clipping control register */
3707 +#define OV5630_CLIP_CTRL0      0x3400
3708 +#define OV5630_CLIP_CTRL1      0x3401
3709 +#define OV5630_CLIP_CTRL2      0x3402
3710 +#define OV5630_CLIP_CTRL3      0x3403
3711 +#define OV5630_CLIP_CTRL4      0x3404
3712 +#define OV5630_CLIP_CTRL5      0x3405
3713 +#define OV5630_CLIP_CTRL6      0x3406
3714 +#define OV5630_CLIP_CTRL7      0x3407
3715 +
3716 +/* DVP control register */
3717 +#define OV5630_DVP_CTRL00      0x3500
3718 +#define OV5630_DVP_CTRL01      0x3501
3719 +#define OV5630_DVP_CTRL02      0x3502
3720 +#define OV5630_DVP_CTRL03      0x3503
3721 +#define OV5630_DVP_CTRL04      0x3504
3722 +#define OV5630_DVP_CTRL05      0x3505
3723 +#define OV5630_DVP_CTRL06      0x3506
3724 +#define OV5630_DVP_CTRL07      0x3507
3725 +#define OV5630_DVP_CTRL08      0x3508
3726 +#define OV5630_DVP_CTRL09      0x3509
3727 +#define OV5630_DVP_CTRL0A      0x350A
3728 +#define OV5630_DVP_CTRL0B      0x350B
3729 +#define OV5630_DVP_CTRL0C      0x350C
3730 +#define OV5630_DVP_CTRL0D      0x350D
3731 +#define OV5630_DVP_CTRL0E      0x350E
3732 +#define OV5630_DVP_CTRL0F      0x350F
3733 +#define OV5630_DVP_CTRL10      0x3510
3734 +#define OV5630_DVP_CTRL11      0x3511
3735 +#define OV5630_DVP_CTRL12      0x3512
3736 +#define OV5630_DVP_CTRL13      0x3513
3737 +#define OV5630_DVP_CTRL14      0x3514
3738 +#define OV5630_DVP_CTRL15      0x3515
3739 +#define OV5630_DVP_CTRL16      0x3516
3740 +#define OV5630_DVP_CTRL17      0x3517
3741 +#define OV5630_DVP_CTRL18      0x3518
3742 +#define OV5630_DVP_CTRL19      0x3519
3743 +#define OV5630_DVP_CTRL1A      0x351A
3744 +#define OV5630_DVP_CTRL1B      0x351B
3745 +#define OV5630_DVP_CTRL1C      0x351C
3746 +#define OV5630_DVP_CTRL1D      0x351D
3747 +#define OV5630_DVP_CTRL1E      0x351E
3748 +#define OV5630_DVP_CTRL1F      0x351F
3749 +
3750 +/* MIPI control register */
3751 +#define OV5630_MIPI_CTRL00     0x3600
3752 +#define OV5630_MIPI_CTRL01     0x3601
3753 +#define OV5630_MIPI_CTRL02     0x3602
3754 +#define OV5630_MIPI_CTRL03     0x3603
3755 +#define OV5630_MIPI_CTRL04     0x3604
3756 +#define OV5630_MIPI_CTRL05     0x3605
3757 +#define OV5630_MIPI_CTRL06     0x3606
3758 +#define OV5630_MIPI_CTRL07     0x3607
3759 +#define OV5630_MIPI_CTRL08     0x3608
3760 +#define OV5630_MIPI_CTRL09     0x3609
3761 +#define OV5630_MIPI_CTRL0A     0x360A
3762 +#define OV5630_MIPI_CTRL0B     0x360B
3763 +#define OV5630_MIPI_CTRL0C     0x360C
3764 +#define OV5630_MIPI_CTRL0D     0x360D
3765 +#define OV5630_MIPI_CTRL0E     0x360E
3766 +#define OV5630_MIPI_CTRL0F     0x360F
3767 +#define OV5630_MIPI_CTRL10     0x3610
3768 +#define OV5630_MIPI_CTRL11     0x3611
3769 +#define OV5630_MIPI_CTRL12     0x3612
3770 +#define OV5630_MIPI_CTRL13     0x3613
3771 +#define OV5630_MIPI_CTRL14     0x3614
3772 +#define OV5630_MIPI_CTRL15     0x3615
3773 +#define OV5630_MIPI_CTRL16     0x3616
3774 +#define OV5630_MIPI_CTRL17     0x3617
3775 +#define OV5630_MIPI_CTRL18     0x3618
3776 +#define OV5630_MIPI_CTRL19     0x3619
3777 +#define OV5630_MIPI_CTRL1A     0x361A
3778 +#define OV5630_MIPI_CTRL1B     0x361B
3779 +#define OV5630_MIPI_CTRL1C     0x361C
3780 +#define OV5630_MIPI_CTRL1D     0x361D
3781 +#define OV5630_MIPI_CTRL1E     0x361E
3782 +#define OV5630_MIPI_CTRL1F     0x361F
3783 +#define OV5630_MIPI_CTRL20     0x3620
3784 +#define OV5630_MIPI_CTRL21     0x3621
3785 +#define OV5630_MIPI_CTRL22     0x3622
3786 +#define OV5630_MIPI_CTRL23     0x3623
3787 +#define OV5630_MIPI_CTRL24     0x3624
3788 +#define OV5630_MIPI_CTRL25     0x3625
3789 +#define OV5630_MIPI_CTRL26     0x3626
3790 +#define OV5630_MIPI_CTRL27     0x3627
3791 +#define OV5630_MIPI_CTRL28     0x3628
3792 +#define OV5630_MIPI_CTRL29     0x3629
3793 +#define OV5630_MIPI_CTRL2A     0x362A
3794 +#define OV5630_MIPI_CTRL2B     0x362B
3795 +#define OV5630_MIPI_CTRL2C     0x362C
3796 +#define OV5630_MIPI_CTRL2D     0x362D
3797 +#define OV5630_MIPI_CTRL2E     0x362E
3798 +#define OV5630_MIPI_CTRL2F     0x362F
3799 +#define OV5630_MIPI_CTRL30     0x3630
3800 +#define OV5630_MIPI_CTRL31     0x3631
3801 +#define OV5630_MIPI_CTRL32     0x3632
3802 +#define OV5630_MIPI_CTRL33     0x3633
3803 +#define OV5630_MIPI_CTRL34     0x3634
3804 +#define OV5630_MIPI_CTRL35     0x3635
3805 +#define OV5630_MIPI_CTRL36     0x3636
3806 +#define OV5630_MIPI_CTRL37     0x3637
3807 +#define OV5630_MIPI_CTRL38     0x3638
3808 +#define OV5630_MIPI_CTRL39     0x3639
3809 +#define OV5630_MIPI_CTRL3A     0x363A
3810 +#define OV5630_MIPI_CTRL3B     0x363B
3811 +#define OV5630_MIPI_CTRL3C     0x363C
3812 +#define OV5630_MIPI_CTRL3D     0x363D
3813 +#define OV5630_MIPI_CTRL3E     0x363E
3814 +#define OV5630_MIPI_CTRL3F     0x363F
3815 +#define OV5630_MIPI_RO61       0x3661
3816 +#define OV5630_MIPI_RO62       0x3662
3817 +#define OV5630_MIPI_RO63       0x3663
3818 +#define OV5630_MIPI_RO64       0x3664
3819 +#define OV5630_MIPI_RO65       0x3665
3820 +#define OV5630_MIPI_RO66       0x3666
3821 +
3822 +/* General definition for ov5630 */
3823 +#define OV5630_OUTWND_MAX_H            QSXXGA_PLUS4_SIZE_H
3824 +#define OV5630_OUTWND_MAX_V            QSXGA_PLUS4_SIZE_V
3825 +
3826 +struct regval_list {
3827 +       u16 reg_num;
3828 +       u8 value;
3829 +};
3830 +
3831 +/*
3832 + * Default register value
3833 + * 5Mega Pixel, 2592x1944
3834 + */
3835 +static struct regval_list ov5630_def_reg[] = {
3836 +       {0x300f, 0x00}, /*00*/
3837 +       {0x30b2, 0x32},
3838 +       {0x3084, 0x44},
3839 +       {0x3016, 0x01},
3840 +       {0x308a, 0x25},
3841 +
3842 +       {0x3013, 0xff},
3843 +       {0x3015, 0x03},
3844 +       {0x30bf, 0x02},
3845 +
3846 +       {0x3065, 0x50},
3847 +       {0x3068, 0x08},
3848 +       {0x30ac, 0x05},
3849 +       {0x309e, 0x24},
3850 +       {0x3091, 0x04},
3851 +
3852 +       {0x3075, 0x22},
3853 +       {0x3076, 0x23},
3854 +       {0x3077, 0x24},
3855 +       {0x3078, 0x25},
3856 +
3857 +       {0x30b5, 0x0c},
3858 +       {0x3090, 0x67},
3859 +
3860 +       {0x30f9, 0x11},
3861 +       {0x3311, 0x80},
3862 +       {0x3312, 0x1f},
3863 +
3864 +       {0x3103, 0x10},
3865 +       {0x305c, 0x01},
3866 +       {0x305d, 0x29},
3867 +       {0x305e, 0x00},
3868 +       {0x305f, 0xf7},
3869 +       {0x308d, 0x0b},
3870 +       {0x30ad, 0x20},
3871 +       {0x3072, 0x0d},
3872 +       {0x308b, 0x82},
3873 +       {0x3317, 0x9c},
3874 +       {0x3318, 0x22},
3875 +       {0x3025, 0x20},
3876 +       {0x3027, 0x08},
3877 +       {0x3029, 0x3f},
3878 +       {0x302b, 0xa3},
3879 +       {0x3319, 0x22},
3880 +       {0x30a1, 0xc4},
3881 +       {0x306a, 0x05},
3882 +       {0x3315, 0x22},
3883 +       {0x30ae, 0x25},
3884 +       {0x3304, 0x40},
3885 +       {0x3099, 0x49},
3886 +
3887 +       {0x300e, 0xb1/*b0*/}, /* Note this PLL setting*/
3888 +       {0x300f, 0x10}, /*00*/
3889 +       {0x3010, 0x07}, /*change from 0f according to SV */
3890 +       {0x3011, 0x40},
3891 +       {0x30af, 0x10},
3892 +       {0x304a, 0x00},
3893 +       {0x304d, 0x00},
3894 +
3895 +       {0x304e, 0x22},
3896 +       {0x304d, 0xa0},
3897 +       {0x3058, 0x00},
3898 +       {0x3059, 0xff},
3899 +       {0x305a, 0x00},
3900 +
3901 +       {0x30e9, 0x04},
3902 +       {0x3084, 0x44},
3903 +       {0x3090, 0x67},
3904 +       {0x30e9, 0x04},
3905 +
3906 +       {0x30b5, 0x1c},
3907 +       {0x331f, 0x22},
3908 +       {0x30ae, 0x15},
3909 +       {0x3304, 0x4c},
3910 +
3911 +       {0x3300, 0xfb},
3912 +       {0x3071, 0x34},
3913 +       {0x30e7, 0x01},
3914 +       {0x3302, 0x60},
3915 +       {0x331e, 0x05},
3916 +       {0x3321, 0x04},
3917 +
3918 +       /* Mark end */
3919 +       {0xffff, 0xff},
3920 +
3921 +};
3922 +
3923 +/* MIPI register are removed by Wen */
3924 +
3925 +/* 2592x1944 */
3926 +static struct regval_list ov5630_res_qsxga_plus4[] = {
3927 +       {0x3020, 0x07},
3928 +       {0x3021, 0xbc},
3929 +       {0x3022, 0x0c/*0a*/},
3930 +       {0x3023, 0xa0/*00*/},
3931 +       {0x305c, 0x01},
3932 +       {0x305d, 0x29},
3933 +       {0x305e, 0x00},
3934 +       {0x305f, 0xf7},
3935 +
3936 +       /* 30fps , 96 MHZ*/
3937 +       /* {0x300f, 0x10}, */
3938 +       {0x300f, 0x10},
3939 +       {0x300e, 0xb1},
3940 +       /* mipi */
3941 +#ifdef MIPI
3942 +       {0x30b0, 0x00},
3943 +       {0x30b1, 0xfc},
3944 +       {0x3603, 0x50},
3945 +       {0x3601, 0x0F},
3946 +       /* lan2 bit 10*/
3947 +       {0x3010, 0x07},
3948 +       {0x30fa, 0x01},
3949 +       /* {0x 30f8 09 */
3950 +       {0x3096, 0x50},
3951 +       /* end mipi*/
3952 +#else
3953 +       /* parrral */
3954 +       {0x30fa, 0x01},
3955 +#endif
3956 +       /* end post*/
3957 +       {0xffff, 0xff},
3958 +};
3959 +
3960 +/* 1920x1080 */
3961 +static struct regval_list ov5630_res_1080p[] = {
3962 +       /*res start*/
3963 +       {0x3020, 0x04},
3964 +       {0x3021, 0x5c},
3965 +       {0x3022, 0x0b/*0a*/},
3966 +       {0x3023, 0x32/*00*/},
3967 +       {0x305c, 0x01},
3968 +       {0x305d, 0x2c},
3969 +       {0x3024, 0x01},
3970 +       {0x3025, 0x6e/*70*/},
3971 +       {0x3026, 0x01},
3972 +       {0x3027, 0xb8},
3973 +       {0x3028, 0x08},
3974 +       {0x3029, 0xef},
3975 +       {0x302a, 0x05},
3976 +       {0x302b, 0xf3},
3977 +       {0x302c, 0x07},
3978 +       {0x302d, 0x80},
3979 +       {0x302e, 0x04},
3980 +       {0x302f, 0x38},
3981 +       {0x3314, 0x07},
3982 +       {0x3315, 0x82/*80*/},
3983 +       {0x3316, 0x04},
3984 +       {0x3317, 0x3c},
3985 +
3986 +       /* 30fps , 96 MHZ*/
3987 +       {0x300f, 0x10}, /* 00 */
3988 +       {0x300e, 0xb1},
3989 +
3990 +       /* mipi */
3991 +#ifdef MIPI
3992 +       {0x30b0, 0x00},
3993 +       {0x30b1, 0xfc},
3994 +       {0x3603, 0x50},
3995 +       {0x3601, 0x0F},
3996 +       /* lan2 bit 10*/
3997 +       {0x3010, 0x07},
3998 +       {0x30fa, 0x01},
3999 +       /* {0x 30f8 09 */
4000 +       {0x3096, 0x50},
4001 +       /* end mipi*/
4002 +#else
4003 +       /* parrral */
4004 +       {0x30fa, 0x01},
4005 +#endif
4006 +       /* end post*/
4007 +       {0xffff, 0xff},
4008 +};
4009 +
4010 +/* 1280x960 V1F2_H1F2 */
4011 +static struct regval_list ov5630_res_xga_plus[] = {
4012 +       {0x3020, 0x03},
4013 +       {0x3021, 0xe4},
4014 +       {0x3022, 0x0c/*07*/},
4015 +       {0x3023, 0x8c/*76*/},
4016 +       {0x305c, 0x00},
4017 +       {0x305d, 0xb1},
4018 +       {0x3024, 0x00},
4019 +       {0x3025, 0x30},
4020 +       {0x3026, 0x00},
4021 +       {0x3027, 0x10/*14*/},
4022 +       {0x3028, 0x0a},
4023 +       {0x3029, 0x2f},
4024 +       {0x302a, 0x07},
4025 +       {0x302b, 0xa7/*a7*/},
4026 +       {0x302c, 0x05},
4027 +       {0x302d, 0x00},
4028 +       {0x302e, 0x03},
4029 +       {0x302f, 0xc0},
4030 +
4031 +       {0x30f8, 0x05},
4032 +       {0x30f9, 0x13},
4033 +       {0x3314, 0x05},
4034 +       {0x3315, 0x02/*00*/},
4035 +       {0x3316, 0x03},
4036 +       {0x3317, 0xc4},
4037 +
4038 +       {0x300f, 0x10}, /* 00 */
4039 +       {0x300e, 0xb1},
4040 +
4041 +#ifdef MIPI
4042 +       {0x30b0, 0x00},
4043 +       {0x30b1, 0xfc},
4044 +       {0x3603, 0x50},
4045 +       {0x3601, 0x0F},
4046 +       /* lan2 bit 10*/
4047 +       {0x3010, 0x07},
4048 +       {0x30fa, 0x01},
4049 +       /* {0x 30f8 09 */
4050 +       {0x3096, 0x50},
4051 +       /* end mipi*/
4052 +#else
4053 +       /* parrral */
4054 +       {0x30fa, 0x01},
4055 +#endif
4056 +
4057 +       {0xffff, 0xff},
4058 +};
4059 +
4060 +/* 1280x720, V1F2 & H1F2 */
4061 +static struct regval_list ov5630_res_720p[] = {
4062 +       {0x3020, 0x02},
4063 +       {0x3021, 0xf4},
4064 +       {0x3022, 0x07},
4065 +       {0x3023, 0x80},
4066 +       {0x305c, 0x00},
4067 +       {0x305d, 0xff},
4068 +       {0x305e, 0x00},
4069 +       {0x305f, 0xd4},
4070 +
4071 +       /* Crop then downscale */
4072 +       {0x3024, 0x00},
4073 +       {0x3025, 0x2c},
4074 +       {0x3026, 0x00},
4075 +       {0x3027, 0xf0},
4076 +       {0x3028, 0x0a},
4077 +       {0x3029, 0x2f},
4078 +       {0x302a, 0x08},
4079 +       {0x302b, 0x97},
4080 +
4081 +       {0x30f8, 0x05},
4082 +
4083 +       {0x302c, 0x05},
4084 +       {0x302d, 0x00},
4085 +       {0x302e, 0x02},
4086 +       {0x302f, 0xd0},
4087 +
4088 +       {0x30f9, 0x13},
4089 +       {0x3314, 0x05},
4090 +       {0x3315, 0x04},
4091 +       {0x3316, 0x02},
4092 +       {0x3317, 0xd4},
4093 +
4094 +       /* Add this to test setting from OVT */
4095 +       {0x300f, 0x10}, /*00*/
4096 +       {0x300e, 0xb0},
4097 +
4098 +#ifdef MIPI
4099 +       {0x30b0, 0x00},
4100 +       {0x30b1, 0xfc},
4101 +       {0x3603, 0x50},
4102 +       {0x3601, 0x0F},
4103 +       /* lan2 bit 10*/
4104 +       {0x3010, 0x07},
4105 +       {0x30fa, 0x01},
4106 +       /* {0x 30f8 09 */
4107 +       {0x3096, 0x50},
4108 +       /* end mipi*/
4109 +#else
4110 +       /* parrral */
4111 +       {0x30fa, 0x01},
4112 +#endif
4113 +
4114 +       {0xffff, 0xff},
4115 +};
4116 +
4117 +/*VGA 40fps now*/
4118 +static struct regval_list ov5630_res_vga_ac04_bill[] = {
4119 +       /* res setting*/
4120 +       {0x3020, 0x02},
4121 +       {0x3021, 0x04},
4122 +       {0x3022, 0x08},
4123 +       {0x3023, 0x48},
4124 +       {0x305c, 0x00},
4125 +       {0x305d, 0x5e},
4126 +       {0x3024, 0x00},
4127 +       {0x3025, 0x2c},/*2c*/
4128 +       {0x3026, 0x00},
4129 +       {0x3027, 0x14},
4130 +       {0x3028, 0x0a},
4131 +       {0x3029, 0x2f},
4132 +       {0x302a, 0x07},
4133 +       {0x302b, 0xa3},
4134 +       {0x302c, 0x02},
4135 +       {0x302d, 0x80},
4136 +       {0x302e, 0x01},
4137 +       {0x302f, 0xe0},
4138 +
4139 +       {0x30b3, 0x09},
4140 +       {0x3301, 0xc1},
4141 +       {0x3313, 0xf1},
4142 +       {0x3314, 0x05},
4143 +       {0x3315, 0x04},/*04*/
4144 +       {0x3316, 0x01},
4145 +       {0x3317, 0xe4},
4146 +       {0x3318, 0x20},
4147 +
4148 +       {0x300f, 0x10/*00*/},
4149 +       {0x30f8, 0x09},
4150 +
4151 +       {0x300f, 0x11},
4152 +       {0x300e, 0xb2},
4153 +
4154 +       {0x3015, 0x02},
4155 +       /* mipi */
4156 +#ifdef MIPI
4157 +       {0x30b0, 0x00},
4158 +       {0x30b1, 0xfc},
4159 +       {0x3603, 0x50},
4160 +       {0x3601, 0x0F},
4161 +       /* lan2 bit 10*/
4162 +       {0x3010, 0x07},
4163 +       {0x30fa, 0x01},
4164 +       /* {0x 30f8 09 */
4165 +       {0x3096, 0x50},
4166 +       /* end mipi*/
4167 +#else
4168 +
4169 +       /* parrral */
4170 +       {0x30fa, 0x01},
4171 +       {0x30f8, 0x09},
4172 +       {0x3096, 0x50},
4173 +#endif
4174 +
4175 +       {0xffff, 0xff},
4176 +};
4177 diff --git a/drivers/media/video/mrstci/mrstov5630_motor/Kconfig b/drivers/media/video/mrstci/mrstov5630_motor/Kconfig
4178 new file mode 100644
4179 index 0000000..b6dcf62
4180 --- /dev/null
4181 +++ b/drivers/media/video/mrstci/mrstov5630_motor/Kconfig
4182 @@ -0,0 +1,9 @@
4183 +config VIDEO_MRST_OV5630_MOTOR
4184 +       tristate "Moorestown OV5630 motor"
4185 +       depends on I2C && VIDEO_MRST_ISP && VIDEO_MRST_OV5630
4186 +
4187 +       ---help---
4188 +         Say Y here if your platform support OV5630 motor
4189 +
4190 +         To compile this driver as a module, choose M here: the
4191 +         module will be called mrstov2650.ko.
4192 diff --git a/drivers/media/video/mrstci/mrstov5630_motor/Makefile b/drivers/media/video/mrstci/mrstov5630_motor/Makefile
4193 new file mode 100644
4194 index 0000000..056b2a6
4195 --- /dev/null
4196 +++ b/drivers/media/video/mrstci/mrstov5630_motor/Makefile
4197 @@ -0,0 +1,3 @@
4198 +obj-$(CONFIG_VIDEO_MRST_OV2650)         += mrstov5630_motor.o
4199 +
4200 +EXTRA_CFLAGS   +=      -I$(src)/../include
4201 diff --git a/drivers/media/video/mrstci/mrstov5630_motor/mrstov5630_motor.c b/drivers/media/video/mrstci/mrstov5630_motor/mrstov5630_motor.c
4202 new file mode 100644
4203 index 0000000..1bb7274
4204 --- /dev/null
4205 +++ b/drivers/media/video/mrstci/mrstov5630_motor/mrstov5630_motor.c
4206 @@ -0,0 +1,428 @@
4207 +/*
4208 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
4209 + *
4210 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
4211 + *
4212 + * This program is free software; you can redistribute it and/or
4213 + * modify it under the terms of the GNU General Public License version
4214 + * 2 as published by the Free Software Foundation.
4215 + *
4216 + * This program is distributed in the hope that it will be useful,
4217 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4218 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4219 + * GNU General Public License for more details.
4220 + *
4221 + * You should have received a copy of the GNU General Public License
4222 + * along with this program; if not, write to the Free Software
4223 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
4224 + * 02110-1301, USA.
4225 + *
4226 + *
4227 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
4228 + */
4229 +
4230 +#include <linux/module.h>
4231 +#include <linux/types.h>
4232 +#include <linux/kernel.h>
4233 +#include <linux/mm.h>
4234 +#include <linux/string.h>
4235 +#include <linux/errno.h>
4236 +#include <linux/init.h>
4237 +#include <linux/kmod.h>
4238 +#include <linux/device.h>
4239 +#include <linux/delay.h>
4240 +#include <linux/fs.h>
4241 +#include <linux/init.h>
4242 +#include <linux/slab.h>
4243 +#include <linux/delay.h>
4244 +#include <linux/i2c.h>
4245 +#include <linux/gpio.h>
4246 +
4247 +#include <media/v4l2-device.h>
4248 +#include <media/v4l2-chip-ident.h>
4249 +#include <media/v4l2-i2c-drv.h>
4250 +
4251 +#include "ov5630_motor.h"
4252 +
4253 +/* #define OSPM */
4254 +#include <asm/ipc_defs.h>
4255 +#define PMIC_WRITE1(ipcbuf, reg1, val1) \
4256 +       do { \
4257 +               memset(&ipcbuf, 0, sizeof(struct ipc_pmic_reg_data)); \
4258 +               ipcbuf.ioc = 0; \
4259 +               ipcbuf.num_entries = 1; \
4260 +               ipcbuf.pmic_reg_data[0].register_address = reg1; \
4261 +               ipcbuf.pmic_reg_data[0].value = val1; \
4262 +               if (ipc_pmic_register_write(&ipcbuf, 1) != 0) { \
4263 +                       return -1; \
4264 +               } \
4265 +       } while (0);
4266 +
4267 +static int mrstov5630_motor_debug;
4268 +module_param(mrstov5630_motor_debug, int, 0644);
4269 +MODULE_PARM_DESC(mrstov5630_motor_debug, "Debug level (0-1)");
4270 +
4271 +#define dprintk(level, fmt, arg...) do {                       \
4272 +       if (mrstov5630_motor_debug >= level)                            \
4273 +               printk(KERN_DEBUG "mrstisp@%s: " fmt "\n", \
4274 +                      __func__, ## arg); } \
4275 +       while (0)
4276 +
4277 +#define eprintk(fmt, arg...)   \
4278 +       printk(KERN_ERR "mrstisp@%s: line %d: " fmt "\n",       \
4279 +              __func__, __LINE__, ## arg);
4280 +
4281 +#define DBG_entering   dprintk(2, "entering");
4282 +#define DBG_leaving    dprintk(2, "leaving");
4283 +#define DBG_line       dprintk(2, " line: %d", __LINE__);
4284 +
4285 +static inline struct ov5630_motor *to_motor_config(struct v4l2_subdev *sd)
4286 +{
4287 +       return container_of(sd, struct ov5630_motor, sd);
4288 +}
4289 +
4290 +static int motor_read(struct i2c_client *c, u16 *reg)
4291 +{
4292 +       int ret;
4293 +       struct i2c_msg msg;
4294 +       u8 msgbuf[2];
4295 +
4296 +       /* Read needs two message to go */
4297 +       msgbuf[0] = 0;
4298 +       msgbuf[1] = 0;
4299 +
4300 +       memset(&msg, 0, sizeof(msg));
4301 +       msg.addr = c->addr;
4302 +       msg.buf = msgbuf;
4303 +       msg.len = 2;
4304 +       msg.flags = I2C_M_RD;
4305 +
4306 +       ret = i2c_transfer(c->adapter, &msg, 1);
4307 +
4308 +       *reg = (msgbuf[0] << 8 | msgbuf[1]);
4309 +
4310 +       ret = (ret == 1) ? 0 : -1;
4311 +       return ret;
4312 +}
4313 +
4314 +static int motor_write(struct i2c_client *c, u16 reg)
4315 +{
4316 +       int ret;
4317 +       struct i2c_msg msg;
4318 +       u8 msgbuf[2];
4319 +
4320 +       /* Writing only needs one message */
4321 +       memset(&msg, 0, sizeof(msg));
4322 +       msgbuf[0] = reg >> 8;
4323 +       msgbuf[1] = reg;
4324 +
4325 +       msg.addr = c->addr;
4326 +       msg.flags = 0;
4327 +       msg.buf = msgbuf;
4328 +       msg.len = 2;
4329 +
4330 +       ret = i2c_transfer(c->adapter, &msg, 1);
4331 +
4332 +       ret = (ret == 1) ? 0 : -1;
4333 +       return ret;
4334 +}
4335 +
4336 +static int ov5630_motor_goto_position(struct i2c_client *c,
4337 +                                     unsigned short code,
4338 +                                     struct ov5630_motor *config)
4339 +{
4340 +       int max_code, min_code;
4341 +       u8 cmdh, cmdl;
4342 +       u16 cmd, val = 0;
4343 +
4344 +       max_code = config->macro_code;
4345 +       min_code = config->infin_code;
4346 +
4347 +       if (code > max_code)
4348 +               code = max_code;
4349 +       if (code < min_code)
4350 +               code = min_code;
4351 +
4352 +       cmdh = (MOTOR_DAC_CODE_H(code));
4353 +       cmdl = (MOTOR_DAC_CODE_L(code) | MOTOR_DAC_CTRL_MODE_2(SUB_MODE_4));
4354 +       cmd = cmdh << 8 | cmdl;
4355 +
4356 +       motor_write(c, cmd);
4357 +       /*Delay more than full-scale transition time 8.8ms*/
4358 +       msleep(8);
4359 +       motor_read(c, &val);
4360 +
4361 +       return (cmd == val ? 0 : -1);
4362 +}
4363 +
4364 +int ov5630_motor_wakeup(void)
4365 +{
4366 +       return gpio_direction_output(GPIO_AF_PD, 1);
4367 +}
4368 +
4369 +int ov5630_motor_standby(void)
4370 +{
4371 +       return gpio_direction_output(GPIO_AF_PD, 0);
4372 +}
4373 +
4374 +int ov5630_motor_init(struct i2c_client *client, struct ov5630_motor *config)
4375 +{
4376 +       int ret;
4377 +       int infin_cur, macro_cur;
4378 +#ifdef OSPM
4379 +       /* Power on motor */
4380 +       struct ipc_pmic_reg_data ipcbuf;
4381 +
4382 +       PMIC_WRITE1(ipcbuf, 0x50, 0x27);
4383 +       printk(KERN_WARNING "Power on Vcc33 for motor\n");
4384 +#endif
4385 +
4386 +       infin_cur = MAX(MOTOR_INFIN_CUR, MOTOR_DAC_MIN_CUR);
4387 +       macro_cur = MIN(MOTOR_MACRO_CUR, MOTOR_DAC_MAX_CUR);
4388 +
4389 +       config->infin_cur = infin_cur;
4390 +       config->macro_cur = macro_cur;
4391 +
4392 +       config->infin_code = (int)((infin_cur * MOTOR_DAC_MAX_CODE)
4393 +                                  / MOTOR_DAC_MAX_CUR);
4394 +       config->macro_code = (int)((macro_cur * MOTOR_DAC_MAX_CODE)
4395 +                                  / MOTOR_DAC_MAX_CUR);
4396 +
4397 +       config->max_step = ((config->macro_code - config->infin_code)
4398 +                           >> MOTOR_STEP_SHIFT) + 1;
4399 +       /* Note here, maybe macro_code */
4400 +       ret = ov5630_motor_goto_position(client, config->infin_code, config);
4401 +       if (!ret)
4402 +               config->cur_code = config->infin_code;
4403 +       else
4404 +               printk(KERN_ERR "Error while initializing motor\n");
4405 +
4406 +       return ret;
4407 +}
4408 +
4409 +int ov5630_motor_set_focus(struct i2c_client *c, int step,
4410 +                          struct ov5630_motor *config)
4411 +{
4412 +       int s_code, ret;
4413 +       int max_step = config->max_step;
4414 +       unsigned int val = step;
4415 +
4416 +       DBG_entering;
4417 +       dprintk(1, "setting setp %d", step);
4418 +       if (val > max_step)
4419 +               val = max_step;
4420 +
4421 +       s_code = (val << MOTOR_STEP_SHIFT);
4422 +       s_code += config->infin_code;
4423 +
4424 +       ret = ov5630_motor_goto_position(c, s_code, config);
4425 +       if (!ret)
4426 +               config->cur_code = s_code;
4427 +
4428 +       DBG_leaving;
4429 +       return ret;
4430 +}
4431 +
4432 +static int ov5630_motor_s_ctrl(struct v4l2_subdev *sd,
4433 +                              struct v4l2_control *ctrl)
4434 +{
4435 +       struct i2c_client *c = v4l2_get_subdevdata(sd);
4436 +       struct ov5630_motor *config = to_motor_config(sd);
4437 +       int ret;
4438 +
4439 +       DBG_entering;
4440 +       ret = ov5630_motor_set_focus(c, ctrl->value, config);
4441 +       if (ret) {
4442 +               eprintk("error call ov5630_motor_set_focue");
4443 +               return ret;
4444 +       }
4445 +       DBG_leaving;
4446 +       return 0;
4447 +}
4448 +int ov5630_motor_get_focus(struct i2c_client *c, unsigned int *step,
4449 +                          struct ov5630_motor *config)
4450 +{
4451 +       int ret_step;
4452 +
4453 +       ret_step = ((config->cur_code - config->infin_code)
4454 +                   >> MOTOR_STEP_SHIFT);
4455 +
4456 +       if (ret_step <= config->max_step)
4457 +               *step = ret_step;
4458 +       else
4459 +               *step = config->max_step;
4460 +
4461 +       return 0;
4462 +}
4463 +
4464 +static int ov5630_motor_g_ctrl(struct v4l2_subdev *sd,
4465 +                              struct v4l2_control *ctrl)
4466 +{
4467 +       struct i2c_client *c = v4l2_get_subdevdata(sd);
4468 +       struct ov5630_motor *config = to_motor_config(sd);
4469 +       int ret;
4470 +
4471 +       DBG_entering;
4472 +       dprintk(2, "c = %p, config = %p, ctrl = %p", c, config, ctrl);
4473 +       ret = ov5630_motor_get_focus(c, &ctrl->value, config);
4474 +       if (ret) {
4475 +               eprintk("error call ov5630_motor_get_focue");
4476 +               return ret;
4477 +       }
4478 +       DBG_leaving;
4479 +       return 0;
4480 +}
4481 +int ov5630_motor_max_step(struct i2c_client *c, unsigned int *max_code,
4482 +                          struct ov5630_motor *config)
4483 +{
4484 +       if (config->max_step != 0)
4485 +               *max_code = config->max_step;
4486 +       return 0;
4487 +}
4488 +
4489 +static int ov5630_motor_queryctrl(struct v4l2_subdev *sd,
4490 +                           struct v4l2_queryctrl *qc)
4491 +{
4492 +       struct ov5630_motor *config = to_motor_config(sd);
4493 +
4494 +       DBG_entering;
4495 +
4496 +       if (qc->id != V4L2_CID_FOCUS_ABSOLUTE)
4497 +               return -EINVAL;
4498 +
4499 +       dprintk(1, "got focus range of %d", config->max_step);
4500 +       if (config->max_step != 0)
4501 +               qc->maximum = config->max_step;
4502 +       DBG_leaving;
4503 +       return 0;
4504 +}
4505 +static const struct v4l2_subdev_core_ops ov5630_motor_core_ops = {
4506 +       /*
4507 +       .queryctrl = ov5630_queryctrl,
4508 +       .g_ctrl = ov5630_g_ctrl,
4509 +       */
4510 +       .g_ctrl = ov5630_motor_g_ctrl,
4511 +       .s_ctrl = ov5630_motor_s_ctrl,
4512 +       .queryctrl = ov5630_motor_queryctrl,
4513 +};
4514 +
4515 +static const struct v4l2_subdev_ops ov5630_motor_ops = {
4516 +       .core = &ov5630_motor_core_ops,
4517 +};
4518 +
4519 +static int ov5630_motor_detect(struct i2c_client *client)
4520 +{
4521 +       struct i2c_adapter *adapter = client->adapter;
4522 +       int adap_id = i2c_adapter_id(adapter);
4523 +
4524 +       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
4525 +               eprintk("error i2c check func");
4526 +               return -ENODEV;
4527 +       }
4528 +
4529 +       if (adap_id != 1) {
4530 +               eprintk("adap_id != 1");
4531 +               return -ENODEV;
4532 +       }
4533 +
4534 +       /* if (ov5630_motor_wakeup()) */
4535 +               /* return -ENODEV; */
4536 +       ov5630_motor_wakeup();
4537 +       ssleep(1);
4538 +
4539 +       /*
4540 +       ov5630_motor_read(client, (u32)OV5630_PID_H, &value);
4541 +       if ((u8)value != 0x56) {
4542 +               eprintk("PID != 0x56, but %x", value);
4543 +               dprintk(2, "client->addr = %x", client->addr);
4544 +               return -ENODEV;
4545 +       }
4546 +       */
4547 +
4548 +       return 0;
4549 +}
4550 +
4551 +static int ov5630_motor_probe(struct i2c_client *client,
4552 +                       const struct i2c_device_id *id)
4553 +{
4554 +       struct ov5630_motor *info;
4555 +       struct v4l2_subdev *sd;
4556 +       int ret = -1;
4557 +/*     struct i2c_client *motor; */
4558 +
4559 +       DBG_entering;
4560 +       v4l_info(client, "chip found @ 0x%x (%s)\n",
4561 +                client->addr << 1, client->adapter->name);
4562 +       /*
4563 +        * Setup sensor configuration structure
4564 +        */
4565 +       info = kzalloc(sizeof(struct ov5630_motor), GFP_KERNEL);
4566 +       if (!info) {
4567 +               eprintk("fail to malloc for ci_motor");
4568 +               ret = -ENOMEM;
4569 +               goto out;
4570 +       }
4571 +
4572 +       ret = ov5630_motor_detect(client);
4573 +       if (ret) {
4574 +               eprintk("error ov5630_motor_detect");
4575 +               goto out_free;
4576 +       }
4577 +
4578 +       sd = &info->sd;
4579 +       v4l2_i2c_subdev_init(sd, client, &ov5630_motor_ops);
4580 +
4581 +       /*
4582 +        * Initialization OV5630
4583 +        * then turn into standby mode
4584 +        */
4585 +       /* ret = ov5630_motor_standby(); */
4586 +       ret = ov5630_motor_init(client, info);
4587 +       if (ret) {
4588 +               eprintk("error calling ov5630_motor_init");
4589 +               goto out_free;
4590 +       }
4591 +
4592 +       ret = 0;
4593 +       goto out;
4594 +
4595 +out_free:
4596 +       kfree(info);
4597 +       DBG_leaving;
4598 +out:
4599 +       return ret;
4600 +}
4601 +
4602 +/*
4603 + * XXX: Need to be checked
4604 + */
4605 +static int ov5630_motor_remove(struct i2c_client *client)
4606 +{
4607 +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
4608 +
4609 +       DBG_entering;
4610 +
4611 +       v4l2_device_unregister_subdev(sd);
4612 +       kfree(to_motor_config(sd));
4613 +
4614 +       DBG_leaving;
4615 +       return 0;
4616 +}
4617 +
4618 +static const struct i2c_device_id ov5630_motor_id[] = {
4619 +       {"ov5630_motor", 0},
4620 +       {}
4621 +};
4622 +MODULE_DEVICE_TABLE(i2c, ov5630_motor_id);
4623 +
4624 +static struct v4l2_i2c_driver_data v4l2_i2c_data = {
4625 +       .name = "ov5630_motor",
4626 +       .probe = ov5630_motor_probe,
4627 +       .remove = ov5630_motor_remove,
4628 +       /* .suspend = ov5630_suspend,
4629 +        * .resume = ov5630_resume, */
4630 +       .id_table = ov5630_motor_id,
4631 +};
4632 +MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
4633 +MODULE_DESCRIPTION("A low-level driver for OmniVision 5630 sensors");
4634 +MODULE_LICENSE("GPL");
4635 diff --git a/drivers/media/video/mrstci/mrstov5630_motor/ov5630_motor.h b/drivers/media/video/mrstci/mrstov5630_motor/ov5630_motor.h
4636 new file mode 100644
4637 index 0000000..302c218
4638 --- /dev/null
4639 +++ b/drivers/media/video/mrstci/mrstov5630_motor/ov5630_motor.h
4640 @@ -0,0 +1,86 @@
4641 +/*
4642 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
4643 + *
4644 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
4645 + *
4646 + * This program is free software; you can redistribute it and/or
4647 + * modify it under the terms of the GNU General Public License version
4648 + * 2 as published by the Free Software Foundation.
4649 + *
4650 + * This program is distributed in the hope that it will be useful,
4651 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4652 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4653 + * GNU General Public License for more details.
4654 + *
4655 + * You should have received a copy of the GNU General Public License
4656 + * along with this program; if not, write to the Free Software
4657 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
4658 + * 02110-1301, USA.
4659 + *
4660 + *
4661 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
4662 + */
4663 +
4664 +#include <media/v4l2-subdev.h>
4665 +
4666 +/* VCM start current (mA) */
4667 +#define MOTOR_INFIN_CUR                15
4668 +/* VCM max current for Macro (mA) */
4669 +#define MOTOR_MACRO_CUR                90
4670 +/* DAC output max current (mA) */
4671 +#define MOTOR_DAC_MAX_CUR      100
4672 +/* DAC output min current (mA) */
4673 +#define MOTOR_DAC_MIN_CUR      3
4674 +
4675 +#define MOTOR_DAC_BIT_RES      10
4676 +#define MOTOR_DAC_MAX_CODE     ((1 << MOTOR_DAC_BIT_RES) - 1)
4677 +
4678 +#define MOTOR_STEP_SHIFT       4
4679 +
4680 +#define MAX(x, y)      ((x) > (y) ? (x) : (y))
4681 +#define MIN(x, y)      ((x) < (y) ? (x) : (y))
4682 +
4683 +/* DAC register related define */
4684 +#define MOTOR_POWER_DOWN       (1 << 7)
4685 +#define                PD_ENABLE       (1 << 7)
4686 +#define                PD_DISABLE      (0)
4687 +
4688 +#define MOTOR_DAC_CODE_H(x)    ((x >> 4) & 0x3f)
4689 +#define MOTOR_DAC_CODE_L(x)    ((x << 4) & 0xf0)
4690 +
4691 +#define MOTOR_DAC_CTRL_MODE_0  0x00
4692 +#define MOTOR_DAC_CTRL_MODE_1(x)       (x & 0x07)
4693 +#define MOTOR_DAC_CTRL_MODE_2(x)       ((x & 0x07) | 0x08)
4694 +
4695 +#define SUB_MODE_1     0x01
4696 +#define SUB_MODE_2     0x02
4697 +#define SUB_MODE_3     0x03
4698 +#define SUB_MODE_4     0x04
4699 +#define SUB_MODE_5     0x05
4700 +#define SUB_MODE_6     0x06
4701 +#define SUB_MODE_7     0x07
4702 +
4703 +#define OV5630_MOTOR_ADDR      (0x18 >> 1)
4704 +#define POWER_EN_PIN   7
4705 +#define GPIO_AF_PD     95
4706 +
4707 +struct ov5630_motor{
4708 +       unsigned int infin_cur;
4709 +       unsigned int infin_code;
4710 +       unsigned int macro_cur;
4711 +       unsigned int macro_code;
4712 +       unsigned int max_step;
4713 +       unsigned int cur_code;
4714 +       struct v4l2_subdev sd;
4715 +};
4716 +
4717 +extern int ov5630_motor_init(struct i2c_client *client, struct ov5630_motor
4718 +                            *config);
4719 +extern int ov5630_motor_standby(void);
4720 +extern int ov5630_motor_wakeup(void);
4721 +extern int ov5630_motor_set_focus(struct i2c_client *c, int step,
4722 +                          struct ov5630_motor *config);
4723 +extern int ov5630_motor_get_focus(struct i2c_client *c, unsigned int *step,
4724 +                          struct ov5630_motor *config);
4725 +extern int ov5630_motor_max_step(struct i2c_client *c, unsigned int *max_code,
4726 +                          struct ov5630_motor *config);
4727 diff --git a/drivers/media/video/mrstci/mrstov9665/Kconfig b/drivers/media/video/mrstci/mrstov9665/Kconfig
4728 new file mode 100644
4729 index 0000000..ba9b692
4730 --- /dev/null
4731 +++ b/drivers/media/video/mrstci/mrstov9665/Kconfig
4732 @@ -0,0 +1,9 @@
4733 +config VIDEO_MRST_OV9665
4734 +       tristate "Moorestown OV9665 SoC Sensor"
4735 +       depends on I2C && VIDEO_MRST_ISP
4736 +
4737 +       ---help---
4738 +         Say Y here if your platform support OV9665 SoC Sensor.
4739 +
4740 +         To compile this driver as a module, choose M here: the
4741 +         module will be called mrstov9665.ko.
4742 diff --git a/drivers/media/video/mrstci/mrstov9665/Makefile b/drivers/media/video/mrstci/mrstov9665/Makefile
4743 new file mode 100644
4744 index 0000000..871b6bf
4745 --- /dev/null
4746 +++ b/drivers/media/video/mrstci/mrstov9665/Makefile
4747 @@ -0,0 +1,3 @@
4748 +obj-$(CONFIG_VIDEO_MRST_OV9665)         += mrstov9665.o
4749 +
4750 +EXTRA_CFLAGS   +=      -I$(src)/../include
4751 diff --git a/drivers/media/video/mrstci/mrstov9665/mrstov9665.c b/drivers/media/video/mrstci/mrstov9665/mrstov9665.c
4752 new file mode 100644
4753 index 0000000..04e553a
4754 --- /dev/null
4755 +++ b/drivers/media/video/mrstci/mrstov9665/mrstov9665.c
4756 @@ -0,0 +1,972 @@
4757 +/*
4758 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
4759 + *
4760 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
4761 + *
4762 + * This program is free software; you can redistribute it and/or
4763 + * modify it under the terms of the GNU General Public License version
4764 + * 2 as published by the Free Software Foundation.
4765 + *
4766 + * This program is distributed in the hope that it will be useful,
4767 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4768 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4769 + * GNU General Public License for more details.
4770 + *
4771 + * You should have received a copy of the GNU General Public License
4772 + * along with this program; if not, write to the Free Software
4773 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
4774 + * 02110-1301, USA.
4775 + *
4776 + *
4777 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
4778 + */
4779 +
4780 +#include <linux/module.h>
4781 +#include <linux/types.h>
4782 +#include <linux/kernel.h>
4783 +#include <linux/mm.h>
4784 +#include <linux/string.h>
4785 +#include <linux/errno.h>
4786 +#include <linux/init.h>
4787 +#include <linux/kmod.h>
4788 +#include <linux/device.h>
4789 +#include <linux/delay.h>
4790 +#include <linux/fs.h>
4791 +#include <linux/init.h>
4792 +#include <linux/slab.h>
4793 +#include <linux/delay.h>
4794 +#include <linux/i2c.h>
4795 +#include <linux/gpio.h>
4796 +#include <linux/videodev2.h>
4797 +
4798 +#include <media/v4l2-device.h>
4799 +#include <media/v4l2-chip-ident.h>
4800 +#include <media/v4l2-i2c-drv.h>
4801 +
4802 +#include "ci_sensor_common.h"
4803 +#include "ov9665.h"
4804 +
4805 +static int mrstov9665_debug;
4806 +module_param(mrstov9665_debug, int, 0644);
4807 +MODULE_PARM_DESC(mrstov9665_debug, "Debug level (0-1)");
4808 +
4809 +#define dprintk(level, fmt, arg...) do {                       \
4810 +       if (mrstov9665_debug >= level)                                  \
4811 +               printk(KERN_DEBUG "mrstisp@%s: " fmt "\n", \
4812 +                      __func__, ## arg); } \
4813 +       while (0)
4814 +
4815 +#define eprintk(fmt, arg...)   \
4816 +       printk(KERN_ERR "mrstisp@%s: line %d: " fmt "\n",       \
4817 +              __func__, __LINE__, ## arg);
4818 +
4819 +#define DBG_entering   dprintk(2, "entering");
4820 +#define DBG_leaving    dprintk(2, "leaving");
4821 +#define DBG_line       dprintk(2, " line: %d", __LINE__);
4822 +
4823 +static inline struct ci_sensor_config *to_sensor_config(struct v4l2_subdev *sd)
4824 +{
4825 +       return container_of(sd, struct ci_sensor_config, sd);
4826 +}
4827 +
4828 +static struct ov9665_format_struct {
4829 +       __u8 *desc;
4830 +       __u32 pixelformat;
4831 +       struct regval_list *regs;
4832 +} ov9665_formats[] = {
4833 +       {
4834 +               .desc           = "YUYV 4:2:2",
4835 +               .pixelformat    = SENSOR_MODE_BT601,
4836 +               .regs           = NULL,
4837 +       },
4838 +};
4839 +#define N_OV9665_FMTS ARRAY_SIZE(ov9665_formats)
4840 +
4841 +static struct ov9665_res_struct {
4842 +       __u8 *desc;
4843 +       int res;
4844 +       int width;
4845 +       int height;
4846 +       /* FIXME: correct the fps values.. */
4847 +       int fps;
4848 +       bool used;
4849 +       struct regval_list *regs;
4850 +} ov9665_res[] = {
4851 +       {
4852 +               .desc           = "SXGA",
4853 +               .res            = SENSOR_RES_SXGA,
4854 +               .width          = 1280,
4855 +               .height         = 1024,
4856 +               .fps            = 15,
4857 +               .used           = 0,
4858 +               .regs           = ov9665_res_sxga,
4859 +       },
4860 +       {
4861 +               .desc           = "VGA",
4862 +               .res            = SENSOR_RES_VGA,
4863 +               .width          = 640,
4864 +               .height         = 480,
4865 +               .fps            = 15,
4866 +               .used           = 0,
4867 +               .regs           = ov9665_res_vga,
4868 +       },
4869 +};
4870 +#define N_RES (ARRAY_SIZE(ov9665_res))
4871 +
4872 +/*
4873 + * I2C Read & Write stuff
4874 + */
4875 +static int ov9665_read(struct i2c_client *c, unsigned char reg,
4876 +                      unsigned char *value)
4877 +{
4878 +       int ret;
4879 +
4880 +       ret = i2c_smbus_read_byte_data(c, reg);
4881 +       if (ret >= 0) {
4882 +               *value = (unsigned char) ret;
4883 +               ret = 0;
4884 +       }
4885 +       return ret;
4886 +}
4887 +
4888 +static int ov9665_write(struct i2c_client *c, unsigned char reg,
4889 +                       unsigned char value)
4890 +{
4891 +       int ret = i2c_smbus_write_byte_data(c, reg, value);
4892 +       if (reg == 0x12 && (value & 0x80))
4893 +               msleep(2);  /* Wait for reset to run */
4894 +       return ret;
4895 +}
4896 +
4897 +/*
4898 + * Write a list of register settings; ff/ff stops the process.
4899 + */
4900 +static int ov9665_write_array(struct i2c_client *c, struct regval_list *vals)
4901 +{
4902 +       struct regval_list *p;
4903 +       u8 read_val = 0;
4904 +       int err_num = 0;
4905 +       int i = 0;
4906 +       p = vals;
4907 +       while (p->reg_num != 0xff) {
4908 +               ov9665_write(c, p->reg_num, p->value);
4909 +               ov9665_read(c, p->reg_num, &read_val);
4910 +               if (read_val != p->value)
4911 +                       err_num++;
4912 +               p++;
4913 +               i++;
4914 +       }
4915 +
4916 +       return 0;
4917 +}
4918 +
4919 +static int ov9665_set_data_pin_in(struct i2c_client *client)
4920 +{
4921 +       int ret = 0;
4922 +
4923 +       ret += ov9665_write(client, 0xd5, 0x00);
4924 +       ret += ov9665_write(client, 0xd6, 0x00);
4925 +
4926 +       return ret;
4927 +}
4928 +
4929 +static int ov9665_set_data_pin_out(struct i2c_client *client)
4930 +{
4931 +       int ret = 0;
4932 +
4933 +       ret += ov9665_write(client, 0xd5, 0xff);
4934 +       ret += ov9665_write(client, 0xd6, 0xff);
4935 +
4936 +       return ret;
4937 +}
4938 +/*
4939 + * Sensor specific helper function
4940 + */
4941 +static int ov9665_standby(void)
4942 +{
4943 +       /* Pull the pin to high to hardware standby */
4944 +       gpio_set_value(GPIO_STDBY_PIN, 1);
4945 +       dprintk(1, "PM: standby called\n");
4946 +       return 0;
4947 +}
4948 +
4949 +static int ov9665_wakeup(void)
4950 +{
4951 +       /* Pull the pin to low*/
4952 +       gpio_set_value(GPIO_STDBY_PIN, 0);
4953 +       dprintk(1, "PM: wakeup called\n");
4954 +       msleep(10);
4955 +       return 0;
4956 +}
4957 +
4958 +static int ov9665_s_power(struct v4l2_subdev *sd, u32 val)
4959 +{
4960 +       if (val == 1)
4961 +               ov9665_standby();
4962 +       if (val == 0)
4963 +               ov9665_wakeup();
4964 +       return 0;
4965 +}
4966 +
4967 +static int ov9665_init(struct i2c_client *c)
4968 +{
4969 +       int ret;
4970 +       struct v4l2_subdev *sd = i2c_get_clientdata(c);
4971 +       struct ci_sensor_config *info = to_sensor_config(sd);
4972 +       u8 reg = 0;
4973 +
4974 +       /* Fill the configuration structure */
4975 +       /* Note this default configuration value */
4976 +       info->mode = ov9665_formats[0].pixelformat;
4977 +       info->res = ov9665_res[0].res;
4978 +       info->type = SENSOR_TYPE_SOC;
4979 +       info->bls = SENSOR_BLS_OFF;
4980 +       info->gamma = SENSOR_GAMMA_ON;
4981 +       info->cconv = SENSOR_CCONV_ON;
4982 +       info->blc = SENSOR_BLC_AUTO;
4983 +       info->agc = SENSOR_AGC_AUTO;
4984 +       info->awb = SENSOR_AWB_AUTO;
4985 +       info->aec = SENSOR_AEC_AUTO;
4986 +       info->bus_width = SENSOR_BUSWIDTH_8BIT_ZZ;
4987 +       info->ycseq = SENSOR_YCSEQ_YCBYCR;
4988 +       info->conv422 = SENSOR_CONV422_COSITED;
4989 +       info->bpat = SENSOR_BPAT_GRGRBGBG;
4990 +       info->field_inv = SENSOR_FIELDINV_NOSWAP;
4991 +       info->field_sel = SENSOR_FIELDSEL_BOTH;
4992 +       info->hpol = SENSOR_HPOL_REFPOS;
4993 +       info->vpol = SENSOR_VPOL_POS;
4994 +       info->edge = SENSOR_EDGE_FALLING;
4995 +       info->flicker_freq = SENSOR_FLICKER_100;
4996 +       info->cie_profile = 0;
4997 +       memcpy(info->name, "ov9665", 7);
4998 +
4999 +       ret = ov9665_write(c, 0x12, 0x80);
5000 +       /* Set registers into default config value */
5001 +       ret += ov9665_write_array(c, ov9665_def_reg);
5002 +
5003 +       ov9665_read(c, 0x09, &reg);
5004 +       reg = reg | 0x10;
5005 +       ov9665_write(c, 0x09, reg);
5006 +       ov9665_set_data_pin_in(c);
5007 +       ssleep(1);
5008 +
5009 +       return ret;
5010 +}
5011 +
5012 +static int distance(struct ov9665_res_struct *res, u32 w, u32 h)
5013 +{
5014 +       int ret;
5015 +       if (res->width < w || res->height < h)
5016 +               return -1;
5017 +
5018 +       ret = ((res->width - w) + (res->height - h));
5019 +       return ret;
5020 +}
5021 +static int ov9665_try_res(u32 *w, u32 *h)
5022 +{
5023 +       struct ov9665_res_struct *res_index, *p = NULL;
5024 +       int dis, last_dis = ov9665_res->width + ov9665_res->height;
5025 +
5026 +       dprintk(1, "&&&&&  before %dx%d", *w, *h);
5027 +       for (res_index = ov9665_res;
5028 +            res_index < ov9665_res + N_RES;
5029 +            res_index++) {
5030 +               if ((res_index->width <= *w) && (res_index->height <= *h))
5031 +                       break;
5032 +               dis = distance(res_index, *w, *h);
5033 +               if (dis < last_dis) {
5034 +                       last_dis = dis;
5035 +                       p = res_index;
5036 +               }
5037 +       }
5038 +       if ((res_index->width < *w) || (res_index->height < *h)) {
5039 +               if (res_index != ov9665_res)
5040 +                       res_index--;
5041 +       }
5042 +
5043 +       /*
5044 +       if (p == NULL) {
5045 +               p = ov2650_res;
5046 +       }
5047 +
5048 +       if ((w != NULL) && (h != NULL)) {
5049 +               *w = p->width;
5050 +               *h = p->height;
5051 +       }
5052 +       */
5053 +       if (res_index == ov9665_res + N_RES)
5054 +               res_index = ov9665_res + N_RES - 1;
5055 +
5056 +       *w = res_index->width;
5057 +       *h = res_index->height;
5058 +
5059 +       dprintk(1, "&&&&&  after %dx%d", *w, *h);
5060 +       return 0;
5061 +}
5062 +
5063 +static struct ov9665_res_struct *ov9665_to_res(u32 w, u32 h)
5064 +{
5065 +       struct ov9665_res_struct *res_index;
5066 +
5067 +       for (res_index = ov9665_res;
5068 +            res_index < ov9665_res + N_RES;
5069 +            res_index++)
5070 +               if ((res_index->width == w) && (res_index->height == h))
5071 +                       break;
5072 +
5073 +       if (res_index >= ov9665_res + N_RES)
5074 +               res_index--;   /* Take the bigger one */
5075 +
5076 +       return res_index;
5077 +}
5078 +
5079 +static int ov9665_try_fmt(struct v4l2_subdev *sd,
5080 +                         struct v4l2_format *fmt)
5081 +{
5082 +       DBG_entering;
5083 +       return ov9665_try_res(&fmt->fmt.pix.width, &fmt->fmt.pix.height);
5084 +       DBG_leaving;
5085 +}
5086 +
5087 +static int ov9665_get_fmt(struct v4l2_subdev *sd,
5088 +                         struct v4l2_format *fmt)
5089 +{
5090 +       struct ci_sensor_config *info = to_sensor_config(sd);
5091 +       unsigned short width, height;
5092 +       int index;
5093 +
5094 +       ci_sensor_res2size(info->res, &width, &height);
5095 +
5096 +       /* Marked the current sensor res as being "used" */
5097 +       for (index = 0; index < N_RES; index++) {
5098 +               if ((width == ov9665_res[index].width) &&
5099 +                   (height == ov9665_res[index].height)) {
5100 +                       ov9665_res[index].used = 1;
5101 +                       continue;
5102 +               }
5103 +               ov9665_res[index].used = 0;
5104 +       }
5105 +
5106 +       fmt->fmt.pix.width = width;
5107 +       fmt->fmt.pix.height = height;
5108 +       return 0;
5109 +}
5110 +
5111 +static int ov9665_set_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
5112 +{
5113 +       struct i2c_client *c = v4l2_get_subdevdata(sd);
5114 +       struct ci_sensor_config *info = to_sensor_config(sd);
5115 +       int ret = 0;
5116 +       struct ov9665_res_struct *res_index;
5117 +       u32 width, height;
5118 +       int index;
5119 +
5120 +       DBG_entering;
5121 +
5122 +       width = fmt->fmt.pix.width;
5123 +       height = fmt->fmt.pix.height;
5124 +
5125 +       ret = ov9665_try_res(&width, &height);
5126 +       res_index = ov9665_to_res(width, height);
5127 +
5128 +       ov9665_wakeup();
5129 +       /* if ((info->res != res_index->res) && (res_index->regs)) { */
5130 +       if ( res_index->regs) {
5131 +               ret = ov9665_write(c, 0x12, 0x80);
5132 +               ret += ov9665_write_array(c, ov9665_def_reg);
5133 +               ret += ov9665_write_array(c, res_index->regs);
5134 +               /* Add delay here to get better image */
5135 +
5136 +               for (index = 0; index < N_RES; index++) {
5137 +                       if ((width == ov9665_res[index].width) &&
5138 +                           (height == ov9665_res[index].height)) {
5139 +                               ov9665_res[index].used = 1;
5140 +                               continue;
5141 +                       }
5142 +                       ov9665_res[index].used = 0;
5143 +               }
5144 +
5145 +               for (index = 0; index < N_RES; index++)
5146 +                       dprintk(2, "index = %d, used = %d\n", index,
5147 +                               ov9665_res[index].used);
5148 +
5149 +       }
5150 +       info->res = res_index->res;
5151 +
5152 +       DBG_leaving;
5153 +       return ret;
5154 +}
5155 +
5156 +static int ov9665_q_hflip(struct v4l2_subdev *sd, __s32 *value)
5157 +{
5158 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5159 +       int ret;
5160 +       unsigned char v = 0;
5161 +
5162 +       ret = ov9665_read(client, 0x04, &v);
5163 +       *value = ((v & 0x80) == 0x80);
5164 +       return ret;
5165 +}
5166 +
5167 +static int ov9665_t_hflip(struct v4l2_subdev *sd, int value)
5168 +{
5169 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5170 +       unsigned char v = 0;
5171 +       int ret;
5172 +
5173 +       value = value >= 1 ? 1 : 0;
5174 +       ret = ov9665_read(client, 0x33, &v);
5175 +       if (value)
5176 +               v |= 0x08;
5177 +       else
5178 +               v &= ~0x08;
5179 +       ret += ov9665_write(client, 0x33, v);
5180 +
5181 +       ret += ov9665_read(client, 0x04, &v);
5182 +       if (value)
5183 +               v |= 0x80;
5184 +       else
5185 +               v &= ~0x80;
5186 +       ret += ov9665_write(client, 0x04, v);
5187 +       msleep(10);  /* FIXME */
5188 +       return ret;
5189 +}
5190 +
5191 +static int ov9665_q_vflip(struct v4l2_subdev *sd, __s32 *value)
5192 +{
5193 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5194 +       int ret;
5195 +       unsigned char v = 0;
5196 +
5197 +       ret = ov9665_read(client, 0x04, &v);
5198 +       *value = ((v & 0x40) == 0x40);
5199 +       return ret;
5200 +}
5201 +
5202 +static int ov9665_t_vflip(struct v4l2_subdev *sd, int value)
5203 +{
5204 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5205 +       unsigned char v = 0;
5206 +       int ret;
5207 +
5208 +       value = value >= 1 ? 1 : 0;
5209 +       ret = ov9665_read(client, 0x04, &v);
5210 +       if (value)
5211 +               v |= 0x40;
5212 +       else
5213 +               v &= ~0x40;
5214 +       ret += ov9665_write(client, 0x04, v);
5215 +       msleep(10);  /* FIXME */
5216 +       return ret;
5217 +}
5218 +
5219 +static struct ov9665_control {
5220 +       struct v4l2_queryctrl qc;
5221 +       int (*query)(struct v4l2_subdev *sd, __s32 *value);
5222 +       int (*tweak)(struct v4l2_subdev *sd, int value);
5223 +} ov9665_controls[] = {
5224 +       {
5225 +               .qc = {
5226 +                       .id = V4L2_CID_VFLIP,
5227 +                       .type = V4L2_CTRL_TYPE_BOOLEAN,
5228 +                       .name = "Vertical flip",
5229 +                       .minimum = 0,
5230 +                       .maximum = 1,
5231 +                       .step = 1,
5232 +                       .default_value = 0,
5233 +               },
5234 +               .tweak = ov9665_t_vflip,
5235 +               .query = ov9665_q_vflip,
5236 +       },
5237 +       {
5238 +               .qc = {
5239 +                       .id = V4L2_CID_HFLIP,
5240 +                       .type = V4L2_CTRL_TYPE_BOOLEAN,
5241 +                       .name = "Horizontal mirror",
5242 +                       .minimum = 0,
5243 +                       .maximum = 1,
5244 +                       .step = 1,
5245 +                       .default_value = 0,
5246 +               },
5247 +               .tweak = ov9665_t_hflip,
5248 +               .query = ov9665_q_hflip,
5249 +       },
5250 +};
5251 +#define N_CONTROLS (ARRAY_SIZE(ov9665_controls))
5252 +
5253 +static struct ov9665_control *ov9665_find_control(__u32 id)
5254 +{
5255 +       int i;
5256 +
5257 +       for (i = 0; i < N_CONTROLS; i++)
5258 +               if (ov9665_controls[i].qc.id == id)
5259 +                       return ov9665_controls + i;
5260 +       return NULL;
5261 +}
5262 +
5263 +static int ov9665_queryctrl(struct v4l2_subdev *sd,
5264 +                           struct v4l2_queryctrl *qc)
5265 +{
5266 +       struct ov9665_control *ctrl = ov9665_find_control(qc->id);
5267 +
5268 +       if (ctrl == NULL)
5269 +               return -EINVAL;
5270 +       *qc = ctrl->qc;
5271 +       return 0;
5272 +}
5273 +
5274 +static int ov9665_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
5275 +{
5276 +       struct ov9665_control *octrl = ov9665_find_control(ctrl->id);
5277 +       int ret;
5278 +
5279 +       if (octrl == NULL)
5280 +               return -EINVAL;
5281 +       ret = octrl->query(sd, &ctrl->value);
5282 +       if (ret >= 0)
5283 +               return 0;
5284 +       return ret;
5285 +}
5286 +
5287 +static int ov9665_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
5288 +{
5289 +       struct ov9665_control *octrl = ov9665_find_control(ctrl->id);
5290 +       int ret;
5291 +
5292 +       if (octrl == NULL)
5293 +               return -EINVAL;
5294 +       ret =  octrl->tweak(sd, ctrl->value);
5295 +       if (ret >= 0)
5296 +               return 0;
5297 +       return ret;
5298 +}
5299 +
5300 +#if 0
5301 +static int ov9665_get_caps(struct i2c_client *c, struct ci_sensor_caps *caps)
5302 +{
5303 +       if (caps == NULL)
5304 +               return -EIO;
5305 +
5306 +       caps->bus_width = SENSOR_BUSWIDTH_8BIT_ZZ;
5307 +       caps->mode      = SENSOR_MODE_BT601;
5308 +       caps->field_inv = SENSOR_FIELDINV_NOSWAP;
5309 +       caps->field_sel = SENSOR_FIELDSEL_BOTH;
5310 +       caps->ycseq     = SENSOR_YCSEQ_YCBYCR;
5311 +       caps->conv422   = SENSOR_CONV422_COSITED;
5312 +       caps->bpat      = SENSOR_BPAT_GRGRBGBG;
5313 +       caps->hpol      = SENSOR_HPOL_REFPOS;
5314 +       caps->vpol      = SENSOR_VPOL_POS;
5315 +       caps->edge      = SENSOR_EDGE_FALLING;
5316 +       caps->bls       = SENSOR_BLS_OFF;
5317 +       caps->gamma     = SENSOR_GAMMA_ON;
5318 +       caps->cconv     = SENSOR_CCONV_ON;
5319 +       caps->res       = SENSOR_RES_SXGA | SENSOR_RES_VGA;
5320 +       caps->blc       = SENSOR_BLC_AUTO;
5321 +       caps->agc       = SENSOR_AGC_AUTO;
5322 +       caps->awb       = SENSOR_AWB_AUTO;
5323 +       caps->aec       = SENSOR_AEC_AUTO;
5324 +       caps->cie_profile       = 0;
5325 +       caps->flicker_freq      = SENSOR_FLICKER_100 | SENSOR_FLICKER_120;
5326 +       caps->type      = SENSOR_TYPE_SOC;
5327 +       /* caps->name   = "ov9665"; */
5328 +       strcpy(caps->name, "ov9665");
5329 +
5330 +       return 0;
5331 +}
5332 +
5333 +static int ov9665_get_config(struct i2c_client *c,
5334 +                            struct ci_sensor_config *config)
5335 +{
5336 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
5337 +
5338 +       if (config == NULL) {
5339 +               printk(KERN_WARNING "sensor_get_config: NULL pointer\n");
5340 +               return -EIO;
5341 +       }
5342 +
5343 +       memset(config, 0, sizeof(struct ci_sensor_config *));
5344 +       memcpy(config, info, sizeof(struct ci_sensor_config));
5345 +
5346 +       return 0;
5347 +}
5348 +
5349 +static int ov9665_setup(struct i2c_client *c,
5350 +                       const struct ci_sensor_config *config)
5351 +{
5352 +       int ret;
5353 +       struct ov9665_res_struct *res_index;
5354 +       struct ci_sensor_config *info = i2c_get_clientdata(c);
5355 +       u16 width, high;
5356 +
5357 +       /* Soft reset camera first*/
5358 +       ret = ov9665_write(c, 0x12, 0x80);
5359 +
5360 +       /* Set registers into default config value */
5361 +       ret += ov9665_write_array(c, ov9665_def_reg);
5362 +
5363 +       /* set image resolution */
5364 +       ci_sensor_res2size(config->res, &width, &high);
5365 +       ret += ov9665_try_res(c, &width, &high);
5366 +       res_index = ov9665_find_res(width, high);
5367 +       if (res_index->regs)
5368 +               ret += ov9665_write_array(c, res_index->regs);
5369 +       if (!ret)
5370 +               info->res = res_index->res;
5371 +
5372 +       /* Add some delay here to get a better image*/
5373 +       ssleep(1);
5374 +
5375 +       return ret;
5376 +}
5377 +
5378 +static int ov9665_set_data_pin_in(struct i2c_client *client)
5379 +{
5380 +       int ret = 0;
5381 +
5382 +       ret += ov9665_write(client, 0xd5, 0x00);
5383 +       ret += ov9665_write(client, 0xd6, 0x00);
5384 +
5385 +       return ret;
5386 +}
5387 +
5388 +static int ov9665_set_data_pin_out(struct i2c_client *client)
5389 +{
5390 +       int ret = 0;
5391 +
5392 +       ret += ov9665_write(client, 0xd5, 0xff);
5393 +       ret += ov9665_write(client, 0xd6, 0xff);
5394 +
5395 +       return ret;
5396 +}
5397 +/*
5398 + * File operation functions
5399 + */
5400 +static int ov9665_open(struct i2c_setting *c, void *priv)
5401 +{
5402 +       struct i2c_client *client = c->sensor_client;
5403 +       int ret = 0;
5404 +       u8 reg = 0;
5405 +       /* Just wake up sensor */
5406 +       if (ov9665_wakeup())
5407 +               return -EIO;
5408 +
5409 +       ov9665_init(client);
5410 +       ret = ov9665_read(client, 0x09, &reg);
5411 +       reg = reg | 0x10;
5412 +       ret += ov9665_write(client, 0x09, reg);
5413 +
5414 +       if (ov9665_set_data_pin_in(client))
5415 +               return EIO;
5416 +/*
5417 +       if (ov9665_standby())
5418 +               return EIO;
5419 +*/
5420 +       return ret;
5421 +}
5422 +
5423 +static int ov9665_release(struct i2c_setting *c, void *priv)
5424 +{
5425 +       /* Just suspend the sensor */
5426 +       if (ov9665_standby())
5427 +               return EIO;
5428 +       return 0;
5429 +}
5430 +
5431 +static int ov9665_on(struct i2c_setting *c)
5432 +{
5433 +       struct i2c_client *client = c->sensor_client;
5434 +       int ret = 0;
5435 +       u8 reg = 0;
5436 +
5437 +       ret = ov9665_read(client, 0x09, &reg);
5438 +       reg = reg & ~0x10;
5439 +       ret = ov9665_write(client, 0x09, reg);
5440 +
5441 +       if (ov9665_set_data_pin_out(client))
5442 +               return EIO;
5443 +
5444 +       return ret;
5445 +}
5446 +
5447 +static int ov9665_off(struct i2c_setting *c)
5448 +{
5449 +       struct i2c_client *client = c->sensor_client;
5450 +       int ret = 0;
5451 +       u8 reg = 0;
5452 +/*
5453 +       ret = ov9665_read(client, 0x09, &reg);
5454 +       reg = reg | 0x10;
5455 +       ret += ov9665_write(client, 0x09, reg);
5456 +*/
5457 +       if (ov9665_set_data_pin_in(client))
5458 +               return EIO;
5459 +
5460 +       return ret;
5461 +}
5462 +
5463 +static struct sensor_device ov9665 = {
5464 +       .name   = "OV9665",
5465 +       .type   = SENSOR_TYPE_SOC,
5466 +       .minor  = -1,
5467 +       .open   = ov9665_open,
5468 +       .release = ov9665_release,
5469 +       .on = ov9665_on,
5470 +       .off = ov9665_off,
5471 +       .querycap = ov9665_get_caps,
5472 +       .get_config = ov9665_get_config,
5473 +       .set_config = ov9665_setup,
5474 +       .enum_parm = ov9665_queryctrl,
5475 +       .get_parm = ov9665_g_ctrl,
5476 +       .set_parm = ov9665_s_ctrl,
5477 +       .try_res = ov9665_try_res,
5478 +       .set_res = ov9665_set_res,
5479 +       .suspend = ov9665_standby,
5480 +       .resume = ov9665_wakeup,
5481 +       .get_ls_corr_config = NULL,
5482 +       .set_awb = NULL,
5483 +       .set_aec = NULL,
5484 +       .set_blc = NULL,
5485 +       /* TBC */
5486 +};
5487 +#endif
5488 +
5489 +static int ov9665_s_stream(struct v4l2_subdev *sd, int enable)
5490 +{
5491 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5492 +       u8 reg = 0;
5493 +
5494 +       DBG_entering;
5495 +       if (enable) {
5496 +               ov9665_read(client, 0x09, &reg);
5497 +               reg = reg & ~0x10;
5498 +               ov9665_write(client, 0x09, reg);
5499 +               ov9665_set_data_pin_out(client);
5500 +               ssleep(1);
5501 +
5502 +       } else {
5503 +               ov9665_read(client, 0x09, &reg);
5504 +               reg = reg | 0x10;
5505 +               ov9665_write(client, 0x09, reg);
5506 +               ov9665_set_data_pin_in(client);
5507 +       }
5508 +
5509 +       DBG_leaving;
5510 +       return 0;
5511 +}
5512 +
5513 +static int ov9665_enum_framesizes(struct v4l2_subdev *sd,
5514 +                                 struct v4l2_frmsizeenum *fsize)
5515 +{
5516 +       unsigned int index = fsize->index;
5517 +
5518 +       DBG_entering;
5519 +
5520 +       if (index >= N_RES)
5521 +               return -EINVAL;
5522 +
5523 +       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
5524 +       fsize->discrete.width = ov9665_res[index].width;
5525 +       fsize->discrete.height = ov9665_res[index].height;
5526 +       fsize->reserved[0] = ov9665_res[index].used;
5527 +
5528 +       DBG_leaving;
5529 +
5530 +       return 0;
5531 +}
5532 +
5533 +static int ov9665_enum_frameintervals(struct v4l2_subdev *sd,
5534 +                                     struct v4l2_frmivalenum *fival)
5535 +{
5536 +       unsigned int index = fival->index;
5537 +
5538 +       DBG_entering;
5539 +
5540 +       if (index >= N_RES)
5541 +               return -EINVAL;
5542 +
5543 +       fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
5544 +       fival->discrete.numerator = 1;
5545 +       fival->discrete.denominator = ov9665_res[index].fps;
5546 +
5547 +       DBG_leaving;
5548 +
5549 +       return 0;
5550 +}
5551 +
5552 +static int ov9665_g_chip_ident(struct v4l2_subdev *sd,
5553 +               struct v4l2_dbg_chip_ident *chip)
5554 +{
5555 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5556 +
5557 +#define V4L2_IDENT_OV9665 8246
5558 +       return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV9665, 0);
5559 +}
5560 +
5561 +#ifdef CONFIG_VIDEO_ADV_DEBUG
5562 +static int ov9665_g_register(struct v4l2_subdev *sd,
5563 +                            struct v4l2_dbg_register *reg)
5564 +{
5565 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5566 +       unsigned char val = 0;
5567 +       int ret;
5568 +
5569 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
5570 +               return -EINVAL;
5571 +       if (!capable(CAP_SYS_ADMIN))
5572 +               return -EPERM;
5573 +       ret = ov9665_read(client, reg->reg & 0xffff, &val);
5574 +       reg->val = val;
5575 +       reg->size = 1;
5576 +       return ret;
5577 +}
5578 +
5579 +static int ov9665_s_register(struct v4l2_subdev *sd,
5580 +                            struct v4l2_dbg_register *reg)
5581 +{
5582 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
5583 +
5584 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
5585 +               return -EINVAL;
5586 +       if (!capable(CAP_SYS_ADMIN))
5587 +               return -EPERM;
5588 +       ov9665_write(client, reg->reg & 0xffff, reg->val & 0xff);
5589 +       return 0;
5590 +}
5591 +#endif
5592 +
5593 +static const struct v4l2_subdev_video_ops ov9665_video_ops = {
5594 +       .try_fmt = ov9665_try_fmt,
5595 +       .s_fmt = ov9665_set_fmt,
5596 +       .g_fmt = ov9665_get_fmt,
5597 +       .s_stream = ov9665_s_stream,
5598 +       .enum_framesizes = ov9665_enum_framesizes,
5599 +       .enum_frameintervals = ov9665_enum_frameintervals,
5600 +};
5601 +
5602 +static const struct v4l2_subdev_core_ops ov9665_core_ops = {
5603 +       .g_chip_ident = ov9665_g_chip_ident,
5604 +       .queryctrl = ov9665_queryctrl,
5605 +       .g_ctrl = ov9665_g_ctrl,
5606 +       .s_ctrl = ov9665_s_ctrl,
5607 +       .s_gpio = ov9665_s_power,
5608 +       /*.g_ext_ctrls = ov9665_g_ext_ctrls,*/
5609 +       /*.s_ext_ctrls = ov9665_s_ext_ctrls,*/
5610 +#ifdef CONFIG_VIDEO_ADV_DEBUG
5611 +       .g_register = ov9665_g_register,
5612 +       .s_register = ov9665_s_register,
5613 +#endif
5614 +};
5615 +
5616 +static const struct v4l2_subdev_ops ov9665_ops = {
5617 +       .core = &ov9665_core_ops,
5618 +       .video = &ov9665_video_ops,
5619 +};
5620 +/*
5621 + * Basic i2c stuff
5622 + */
5623 +/*
5624 +static unsigned short normal_i2c[] = {0x30, I2C_CLIENT_END};
5625 +I2C_CLIENT_INSMOD;
5626 +
5627 +static struct i2c_driver ov9665_driver;
5628 +*/
5629 +static int ov9665_detect(struct i2c_client *client)
5630 +{
5631 +       struct i2c_adapter *adapter = client->adapter;
5632 +       int adap_id = i2c_adapter_id(adapter);
5633 +       u8 config = 0;
5634 +
5635 +       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
5636 +               return -ENODEV;
5637 +
5638 +       if (adap_id != 1)
5639 +               return -ENODEV;
5640 +
5641 +       ov9665_wakeup();
5642 +
5643 +       ov9665_read(client, 0x0a, &config);
5644 +       if (config != 0x96)
5645 +               return -ENODEV;
5646 +
5647 +       ov9665_read(client, 0x0b, &config);
5648 +       if (config != 0x63)
5649 +               return -ENODEV;
5650 +
5651 +       return 0;
5652 +}
5653 +
5654 +static int ov9665_probe(struct i2c_client *client,
5655 +                       const struct i2c_device_id *id)
5656 +{
5657 +       struct ci_sensor_config *info;
5658 +       struct v4l2_subdev *sd;
5659 +       int ret = -1;
5660 +
5661 +       DBG_entering;
5662 +       /*
5663 +        * Setup sensor configuration structure
5664 +        */
5665 +       info = kzalloc(sizeof(struct ci_sensor_config), GFP_KERNEL);
5666 +       if (!info)
5667 +               return -ENOMEM;
5668 +
5669 +       ret = ov9665_detect(client);
5670 +       if (ret) {
5671 +               kfree(info);
5672 +               return -ENODEV;
5673 +       }
5674 +
5675 +       sd = &info->sd;
5676 +       v4l2_i2c_subdev_init(sd, client, &ov9665_ops);
5677 +
5678 +       /*
5679 +        * Initialization OV9665
5680 +        * then turn into standby mode
5681 +        */
5682 +       /* ret = ov9665_standby(); */
5683 +       ret = ov9665_init(client);
5684 +       if (ret) {
5685 +               eprintk("error init ov9665");
5686 +               goto err_1;
5687 +       }
5688 +
5689 +       ov9665_standby();
5690 +       printk(KERN_INFO "Init ov9665 sensor success\n");
5691 +       DBG_leaving;
5692 +       return 0;
5693 +
5694 +err_1:
5695 +       kfree(info);
5696 +       return ret;
5697 +}
5698 +
5699 +/*
5700 + * XXX: Need to be checked
5701 + */
5702 +static int ov9665_remove(struct i2c_client *client)
5703 +{
5704 +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
5705 +
5706 +       v4l2_device_unregister_subdev(sd);
5707 +       kfree(to_sensor_config(sd));
5708 +
5709 +       return 0;
5710 +}
5711 +
5712 +static const struct i2c_device_id ov9665_id[] = {
5713 +       {"ov9665", 0},
5714 +       {}
5715 +};
5716 +
5717 +MODULE_DEVICE_TABLE(i2c, ov9665_id);
5718 +
5719 +static struct v4l2_i2c_driver_data v4l2_i2c_data = {
5720 +       .name = "ov9665",
5721 +       .probe = ov9665_probe,
5722 +       .remove = ov9665_remove,
5723 +       .id_table = ov9665_id,
5724 +};
5725 +
5726 +MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
5727 +MODULE_DESCRIPTION("A low-level driver for OmniVision 9665 sensors");
5728 +MODULE_LICENSE("GPL");
5729 diff --git a/drivers/media/video/mrstci/mrstov9665/ov9665.h b/drivers/media/video/mrstci/mrstov9665/ov9665.h
5730 new file mode 100644
5731 index 0000000..6fc9d12
5732 --- /dev/null
5733 +++ b/drivers/media/video/mrstci/mrstov9665/ov9665.h
5734 @@ -0,0 +1,263 @@
5735 +/*
5736 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
5737 + *
5738 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
5739 + *
5740 + * This program is free software; you can redistribute it and/or
5741 + * modify it under the terms of the GNU General Public License version
5742 + * 2 as published by the Free Software Foundation.
5743 + *
5744 + * This program is distributed in the hope that it will be useful,
5745 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5746 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5747 + * GNU General Public License for more details.
5748 + *
5749 + * You should have received a copy of the GNU General Public License
5750 + * along with this program; if not, write to the Free Software
5751 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
5752 + * 02110-1301, USA.
5753 + *
5754 + *
5755 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
5756 + */
5757 +
5758 +#define I2C_OV9665     0x60
5759 +/* Should add to kernel source */
5760 +#define I2C_DRIVERID_OV9665    1047
5761 +/* GPIO pin on Moorestown */
5762 +#define GPIO_SCLK_25   44
5763 +#define GPIO_STB_PIN   47
5764 +#define GPIO_STDBY_PIN 48
5765 +#define GPIO_RESET_PIN 50
5766 +
5767 +struct regval_list {
5768 +       u8 reg_num;
5769 +       u8 value;
5770 +};
5771 +
5772 +/*
5773 + * Default register value
5774 + * 1280x1024 YUV
5775 + */
5776 +static struct regval_list ov9665_def_reg[] = {
5777 +       {0x3E, 0x80},
5778 +       {0x12, 0x80},
5779 +
5780 +       {0xd5, 0xff},
5781 +       {0xd6, 0x3f},
5782 +
5783 +       {0x3d, 0x3c},
5784 +       {0x11, 0x81},
5785 +       {0x2a, 0x00},
5786 +       {0x2b, 0x00},
5787 +
5788 +       {0x3a, 0xf1},
5789 +       {0x3b, 0x00},
5790 +       {0x3c, 0x58},
5791 +       {0x3e, 0x50},
5792 +       {0x71, 0x00},
5793 +
5794 +       {0x15, 0x00},
5795 +       {0x6a, 0x24},
5796 +       {0x85, 0xe7},
5797 +
5798 +       {0x63, 0x01},
5799 +
5800 +       {0x17, 0x0c},
5801 +       {0x18, 0x5c},
5802 +       {0x19, 0x01},
5803 +       {0x1a, 0x82},
5804 +       {0x03, 0x03},
5805 +       {0x2b, 0x00},
5806 +
5807 +       {0x36, 0xb4},
5808 +       {0x65, 0x10},
5809 +       {0x70, 0x02},
5810 +       {0x71, 0x9f},
5811 +       {0x64, 0x24},
5812 +
5813 +       {0x43, 0x00},
5814 +       {0x5D, 0x55},
5815 +       {0x5E, 0x57},
5816 +       {0x5F, 0x21},
5817 +
5818 +       {0x24, 0x3e},
5819 +       {0x25, 0x38},
5820 +       {0x26, 0x72},
5821 +
5822 +       {0x14, 0x68},
5823 +       {0x0C, 0x3a}, /* Auto detect for 50/60 */
5824 +       {0x4F, 0x9E},
5825 +       {0x50, 0x84},
5826 +       {0x5A, 0x67},
5827 +
5828 +       {0x7d, 0x30},
5829 +       {0x7e, 0x00},
5830 +       {0x82, 0x03},
5831 +       {0x7f, 0x00},
5832 +       {0x83, 0x07},
5833 +       {0x80, 0x03},
5834 +       {0x81, 0x04},
5835 +
5836 +       {0x96, 0xf0},
5837 +       {0x97, 0x00},
5838 +       {0x92, 0x33},
5839 +       {0x94, 0x5a},
5840 +       {0x93, 0x3a},
5841 +       {0x95, 0x48},
5842 +       {0x91, 0xfc},
5843 +       {0x90, 0xff},
5844 +       {0x8e, 0x4e},
5845 +       {0x8f, 0x4e},
5846 +       {0x8d, 0x13},
5847 +       {0x8c, 0x0c},
5848 +       {0x8b, 0x0c},
5849 +       {0x86, 0x9e},
5850 +       {0x87, 0x11},
5851 +       {0x88, 0x22},
5852 +       {0x89, 0x05},
5853 +       {0x8a, 0x03},
5854 +
5855 +       {0x9b, 0x0e},
5856 +       {0x9c, 0x1c},
5857 +       {0x9d, 0x34},
5858 +       {0x9e, 0x5a},
5859 +       {0x9f, 0x68},
5860 +       {0xa0, 0x76},
5861 +       {0xa1, 0x82},
5862 +       {0xa2, 0x8e},
5863 +       {0xa3, 0x98},
5864 +       {0xa4, 0xa0},
5865 +       {0xa5, 0xb0},
5866 +       {0xa6, 0xbe},
5867 +       {0xa7, 0xd2},
5868 +       {0xa8, 0xe2},
5869 +       {0xa9, 0xee},
5870 +       {0xaa, 0x18},
5871 +
5872 +       {0xAB, 0xe7},
5873 +       {0xb0, 0x43},
5874 +       {0xac, 0x04},
5875 +       {0x84, 0x40},
5876 +
5877 +       {0xad, 0x84},
5878 +       {0xd9, 0x24},
5879 +       {0xda, 0x00},
5880 +       {0xae, 0x10},
5881 +
5882 +       {0xab, 0xe7},
5883 +       {0xb9, 0xa0},
5884 +       {0xba, 0x80},
5885 +       {0xbb, 0xa0},
5886 +       {0xbc, 0x80},
5887 +
5888 +       {0xbd, 0x08},
5889 +       {0xbe, 0x19},
5890 +       {0xbf, 0x02},
5891 +       {0xc0, 0x08},
5892 +       {0xc1, 0x2a},
5893 +       {0xc2, 0x34},
5894 +       {0xc3, 0x2d},
5895 +       {0xc4, 0x2d},
5896 +       {0xc5, 0x00},
5897 +       {0xc6, 0x98},
5898 +       {0xc7, 0x18},
5899 +       {0x69, 0x48},
5900 +
5901 +       {0x74, 0xc0},
5902 +
5903 +       {0x7c, 0x18},
5904 +       {0x65, 0x11},
5905 +       {0x66, 0x00},
5906 +       {0x41, 0xa0},
5907 +       {0x5b, 0x28},
5908 +       {0x60, 0x84},
5909 +       {0x05, 0x07},
5910 +       {0x03, 0x03},
5911 +       {0xd2, 0x8c},
5912 +
5913 +       {0xc7, 0x90},
5914 +       {0xc8, 0x06},
5915 +       {0xcb, 0x40},
5916 +       {0xcc, 0x40},
5917 +       {0xcf, 0x00},
5918 +       {0xd0, 0x20},
5919 +       {0xd1, 0x00},
5920 +       {0xc7, 0x18},
5921 +
5922 +       {0x0d, 0x82},
5923 +       {0x0d, 0x80},
5924 +
5925 +       {0x09, 0x01},
5926 +
5927 +       {0xff, 0xff},
5928 +};
5929 +
5930 +/* 1280x1024 */
5931 +static struct regval_list ov9665_res_sxga[] = {
5932 +       {0x0c, 0xbc}, /* note this */
5933 +       {0xff, 0xff},
5934 +};
5935 +
5936 +/* 640x480 */
5937 +static struct regval_list ov9665_res_vga[] = {
5938 +       /* Fclk/4 */
5939 +       {0x11, 0x80},
5940 +       {0x63, 0x00},
5941 +
5942 +       {0x12, 0x40}, /*VGA format*/
5943 +       {0x14, 0x30}, /*4x*/
5944 +       {0x0c, 0xbc},
5945 +       {0x4d, 0x09},
5946 +       {0x5c, 0x80}, /* Full average AEC */
5947 +
5948 +       /* Windows setting */
5949 +       {0x17, 0x0c},
5950 +       {0x18, 0x5c},
5951 +       {0x19, 0x02},
5952 +       {0x1a, 0x3f},
5953 +       {0x03, 0x03},
5954 +       {0x32, 0xad},
5955 +
5956 +       /* 50/60Hz AEC */
5957 +       {0x5a, 0x23},
5958 +       {0x2b, 0x00},
5959 +
5960 +       {0x64, 0xa4},
5961 +       /*
5962 +       {0x4F, 0x4f},
5963 +       {0x50, 0x42},
5964 +       */
5965 +       {0x4F, 0x9e},
5966 +       {0x50, 0x84},
5967 +       {0x97, 0x0a},
5968 +       {0xad, 0x82},
5969 +       {0xd9, 0x11},
5970 +
5971 +       /* Scale window */
5972 +       {0xb9, 0x50},
5973 +       {0xba, 0x3c},
5974 +       {0xbb, 0x50},
5975 +       {0xbc, 0x3c},
5976 +
5977 +       {0xad, 0x80},
5978 +       {0xd9, 0x00},
5979 +       {0xac, 0x0f},
5980 +       {0x84, 0x86},
5981 +
5982 +       /*This is for Color Matrix*/
5983 +       {0xbd, 0x05},
5984 +       {0xbe, 0x16},
5985 +       {0xbf, 0x05},
5986 +       {0xc0, 0x07},
5987 +       {0xc1, 0x18},
5988 +       {0xc2, 0x1f},
5989 +       {0xc3, 0x2b},
5990 +       {0xc4, 0x2b},
5991 +       {0xc5, 0x00},
5992 +
5993 +       {0x0d, 0x92},
5994 +       {0x0d, 0x90},
5995 +
5996 +       {0xff, 0xff},
5997 +};
5998 diff --git a/drivers/media/video/mrstci/mrsts5k4e1/Kconfig b/drivers/media/video/mrstci/mrsts5k4e1/Kconfig
5999 new file mode 100755
6000 index 0000000..7dee787
6001 --- /dev/null
6002 +++ b/drivers/media/video/mrstci/mrsts5k4e1/Kconfig
6003 @@ -0,0 +1,9 @@
6004 +config VIDEO_MRST_S5K4E1
6005 +       tristate "Moorestown s5k4e1 RAW Sensor"
6006 +       depends on I2C && VIDEO_MRST_ISP
6007 +
6008 +       ---help---
6009 +         Say Y here if your platform support s5k4e1 RAW Sensor.
6010 +
6011 +         To compile this driver as a module, choose M here: the
6012 +         module will be called mrstov2650.ko.
6013 diff --git a/drivers/media/video/mrstci/mrsts5k4e1/Makefile b/drivers/media/video/mrstci/mrsts5k4e1/Makefile
6014 new file mode 100644
6015 index 0000000..8733fa8
6016 --- /dev/null
6017 +++ b/drivers/media/video/mrstci/mrsts5k4e1/Makefile
6018 @@ -0,0 +1,3 @@
6019 +obj-$(CONFIG_VIDEO_MRST_S5K4E1)         += mrsts5k4e1.o
6020 +
6021 +EXTRA_CFLAGS   +=      -I$(src)/../include
6022 diff --git a/drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.c b/drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.c
6023 new file mode 100755
6024 index 0000000..f644531
6025 --- /dev/null
6026 +++ b/drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.c
6027 @@ -0,0 +1,1024 @@
6028 +/*
6029 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
6030 + *
6031 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
6032 + *
6033 + * This program is free software; you can redistribute it and/or
6034 + * modify it under the terms of the GNU General Public License version
6035 + * 2 as published by the Free Software Foundation.
6036 + *
6037 + * This program is distributed in the hope that it will be useful,
6038 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6039 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6040 + * GNU General Public License for more details.
6041 + *
6042 + * You should have received a copy of the GNU General Public License
6043 + * along with this program; if not, write to the Free Software
6044 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
6045 + * 02110-1301, USA.
6046 + *
6047 + *
6048 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
6049 + */
6050 +
6051 +#include <linux/module.h>
6052 +#include <linux/types.h>
6053 +#include <linux/kernel.h>
6054 +#include <linux/mm.h>
6055 +#include <linux/string.h>
6056 +#include <linux/errno.h>
6057 +#include <linux/init.h>
6058 +#include <linux/kmod.h>
6059 +#include <linux/device.h>
6060 +#include <linux/delay.h>
6061 +#include <linux/fs.h>
6062 +#include <linux/init.h>
6063 +#include <linux/slab.h>
6064 +#include <linux/delay.h>
6065 +#include <linux/i2c.h>
6066 +#include <linux/gpio.h>
6067 +
6068 +#include <media/v4l2-device.h>
6069 +#include <media/v4l2-chip-ident.h>
6070 +#include <media/v4l2-i2c-drv.h>
6071 +
6072 +#include "ci_sensor_common.h"
6073 +#include "mrsts5k4e1.h"
6074 +/* #include "priv.h" */
6075 +/* extern const struct DumpRegs regs_d[]; */
6076 +
6077 +static int s5k4e1_debug;
6078 +module_param(s5k4e1_debug, int, 0644);
6079 +MODULE_PARM_DESC(s5k4e1_debug, "Debug level (0-1)");
6080 +
6081 +#define dprintk(level, fmt, arg...) \
6082 +       do { \
6083 +               if (s5k4e1_debug >= level) \
6084 +                       printk(KERN_DEBUG "mrstisp@%s: " fmt "\n", \
6085 +                              __func__, ## arg);\
6086 +       } while (0)
6087 +
6088 +#define eprintk(fmt, arg...)   \
6089 +       printk(KERN_ERR "mrstisp@%s:" fmt "\n", \
6090 +              __func__, ## arg);
6091 +
6092 +#define DBG_entering   dprintk(1, "entering");
6093 +#define DBG_leaving    dprintk(1, "leaving");
6094 +#define DBG_line       dprintk(1, " line: %d", __LINE__);
6095 +
6096 +static inline struct ci_sensor_config *to_sensor_config(struct v4l2_subdev *sd)
6097 +{
6098 +       return container_of(sd, struct ci_sensor_config, sd);
6099 +}
6100 +
6101 +static struct s5k4e1_format_struct {
6102 +       __u8 *desc;
6103 +       __u32 pixelformat;
6104 +       struct regval_list *regs;
6105 +} s5k4e1_formats[] = {
6106 +       {
6107 +               .desc           = "Raw RGB Bayer",
6108 +               .pixelformat    = SENSOR_MODE_MIPI,
6109 +               .regs           = NULL,
6110 +       },
6111 +};
6112 +#define N_S5K4E1_FMTS ARRAY_SIZE(s5k4e1_formats)
6113 +
6114 +static struct s5k4e1_res_struct {
6115 +       __u8 *desc;
6116 +       int res;
6117 +       int width;
6118 +       int height;
6119 +       /* FIXME: correct the fps values.. */
6120 +       int fps;
6121 +       bool used;
6122 +       struct regval_list *regs;
6123 +} s5k4e1_res[] = {
6124 +       {
6125 +               .desc           = "QSXGA_PLUS4",
6126 +               .res            = SENSOR_RES_QXGA_PLUS,
6127 +               .width          = 2592,
6128 +               .height         = 1944,
6129 +               .fps            = 15,
6130 +               .used           = 0,
6131 +               .regs           = s5k4e1_res_qsxga_plus4,
6132 +       },
6133 +       {
6134 +               .desc           = "1080P",
6135 +               .res            = SENSOR_RES_1080P,
6136 +               .width          = 1920,
6137 +               .height         = 1080,
6138 +               .fps            = 25,
6139 +               .used           = 0,
6140 +               .regs           = s5k4e1_res_1080p,
6141 +       },
6142 +       {
6143 +               .desc           = "VGA_PLUS",
6144 +               .res            = SENSOR_RES_VGA_PLUS,
6145 +               .width          = 1304,
6146 +               .height         = 980,
6147 +               .fps            = 30,
6148 +               .used           = 0,
6149 +               .regs           = s5k4e1_res_vga_ac04_bill,
6150 +       },
6151 +       {
6152 +               .desc           = "720p",
6153 +               .res            = SENSOR_RES_720P,
6154 +               .width          = 1280,
6155 +               .height         = 720,
6156 +               .fps            = 30,
6157 +               .used           = 0,
6158 +               .regs           = s5k4e1_res_720p,
6159 +       },
6160 +       {
6161 +               .desc           = "VGA",
6162 +               .res            = SENSOR_RES_VGA,
6163 +               .width          = 640,
6164 +               .height         = 480,
6165 +               .used           = 0,
6166 +               .fps            = 40,
6167 +               .regs           = s5k4e1_res_vga_ac04_bill,
6168 +       },
6169 +};
6170 +
6171 +#define N_RES (ARRAY_SIZE(s5k4e1_res))
6172 +
6173 +/*
6174 + * I2C Read & Write stuff
6175 + */
6176 +static int s5k4e1_read(struct i2c_client *c, u32 reg, u32 *value)
6177 +{
6178 +       int ret;
6179 +       int i;
6180 +       struct i2c_msg msg[2];
6181 +       u8 msgbuf[2];
6182 +       u8 ret_val = 0;
6183 +       *value = 0;
6184 +       /* Read needs two message to go */
6185 +       memset(&msg, 0, sizeof(msg));
6186 +       msgbuf[0] = 0;
6187 +       msgbuf[1] = 0;
6188 +       i = 0;
6189 +
6190 +       msgbuf[i++] = ((u16)reg) >> 8;
6191 +       msgbuf[i++] = ((u16)reg) & 0xff;
6192 +       msg[0].addr = c->addr;
6193 +       msg[0].buf = msgbuf;
6194 +       msg[0].len = i;
6195 +
6196 +       msg[1].addr = c->addr;
6197 +       msg[1].flags = I2C_M_RD;
6198 +       msg[1].buf = &ret_val;
6199 +       msg[1].len = 1;
6200 +
6201 +       ret = i2c_transfer(c->adapter, &msg[0], 2);
6202 +       *value = ret_val;
6203 +
6204 +       ret = (ret == 2) ? 0 : -1;
6205 +       dprintk(2, "reg:0x%8x, value:0x%8x - %s", reg, *value,
6206 +               (ret ? "failed" : "succesfully"));
6207 +       return ret;
6208 +}
6209 +
6210 +static int s5k4e1_write(struct i2c_client *c, u32 reg, u32 value)
6211 +{
6212 +       int ret, i;
6213 +       struct i2c_msg msg;
6214 +       u8 msgbuf[3];
6215 +
6216 +       /* Writing only needs one message */
6217 +       memset(&msg, 0, sizeof(msg));
6218 +       i = 0;
6219 +       msgbuf[i++] = ((u16)reg) >> 8;
6220 +       msgbuf[i++] = (u16)reg & 0xff;
6221 +       msgbuf[i++] = (u8)value;
6222 +
6223 +       msg.addr = c->addr;
6224 +       msg.flags = 0;
6225 +       msg.buf = msgbuf;
6226 +       msg.len = i;
6227 +
6228 +       ret = i2c_transfer(c->adapter, &msg, 1);
6229 +
6230 +       /* If this is a reset register, wait for 1ms */
6231 +       if (reg == 0x0103 && (value & 0x01))
6232 +               /*Note here, check if this is needed */
6233 +               msleep(4);
6234 +
6235 +       ret = (ret == 1) ? 0 : -1;
6236 +       dprintk(2, "reg:0x%8x, value:0x%8x - %s", reg, value,
6237 +               (ret ? "failed" : "successfully"));
6238 +       return ret;
6239 +}
6240 +
6241 +static int s5k4e1_write_array(struct i2c_client *c, struct regval_list *vals)
6242 +{
6243 +       struct regval_list *p;
6244 +       u32 read_val = 0;
6245 +       int err_num = 0;
6246 +       int i = 0;
6247 +
6248 +       DBG_entering;
6249 +
6250 +       p = vals;
6251 +       while (p->reg_num != 0xffff) {
6252 +               s5k4e1_write(c, (u32)p->reg_num, (u32)p->value);
6253 +               s5k4e1_read(c, (u32)p->reg_num, &read_val);
6254 +               /* msleep(100);*/
6255 +               if (read_val != p->value) {
6256 +                       eprintk("0x%x write error:should be 0x%x, but 0x%x",
6257 +                               p->reg_num, p->value, read_val);
6258 +                       err_num++;
6259 +               }
6260 +               p++;
6261 +               i++;
6262 +       }
6263 +       dprintk(1, "sucessfully wrote %d registers, err is %d", i,
6264 +              err_num);
6265 +       return 0;
6266 +}
6267 +
6268 +/*
6269 + * Sensor specific helper function
6270 + */
6271 +static int s5k4e1_standby(void)
6272 +{
6273 +       gpio_set_value(GPIO_STDBY_PIN, 1);
6274 +       dprintk(1, "PM: standby called\n");
6275 +       return 0;
6276 +}
6277 +
6278 +static int s5k4e1_wakeup(void)
6279 +{
6280 +       gpio_set_value(GPIO_STDBY_PIN, 0);
6281 +       dprintk(1, "PM: wakeup called\n");
6282 +       return 0;
6283 +}
6284 +
6285 +static int s5k4e1_s_power(struct v4l2_subdev *sd, u32 val)
6286 +{
6287 +       if (val == 1)
6288 +               s5k4e1_standby();
6289 +       if (val == 0)
6290 +               s5k4e1_wakeup();
6291 +       return 0;
6292 +}
6293 +
6294 +static int s5k4e1_set_img_ctrl(struct i2c_client *c,
6295 +                              const struct ci_sensor_config *config)
6296 +{
6297 +       int err = 0;
6298 +
6299 +       DBG_entering;
6300 +
6301 +       switch (config->blc) {
6302 +               /* only SENSOR_BLC_AUTO supported */
6303 +       case SENSOR_BLC_AUTO:
6304 +               break;
6305 +       default:
6306 +               dprintk(1, "BLC not supported,\
6307 +                       set to BLC_AUTO by default.");
6308 +       }
6309 +
6310 +       switch (config->bls) {
6311 +               /* only SENSOR_BLS_OFF supported */
6312 +       case SENSOR_BLS_OFF:
6313 +               break;
6314 +       default:
6315 +               dprintk(1, "Black level not supported,\
6316 +                       set to BLS_OFF by default.");
6317 +       }
6318 +
6319 +       switch (config->agc) {
6320 +               /* only SENSOR_AGC_OFF supported */
6321 +       case SENSOR_AGC_OFF:
6322 +               break;
6323 +       default:
6324 +               dprintk(1, "AGC not supported,\
6325 +                       set to AGC_OFF by default.");
6326 +       }
6327 +
6328 +       switch (config->awb) {
6329 +               /* only SENSOR_AWB_OFF supported */
6330 +       case SENSOR_AWB_OFF:
6331 +               break;
6332 +       default:
6333 +               dprintk(1, "AWB not supported,\
6334 +                       set to AWB_OFF by default.");
6335 +       }
6336 +
6337 +       switch (config->aec) {
6338 +               /* only SENSOR_AEC_OFF supported */
6339 +       case SENSOR_AEC_OFF:
6340 +               break;
6341 +       default:
6342 +               dprintk(1, "AEC not supported,\
6343 +                       set to AEC_OFF by default.");
6344 +       }
6345 +
6346 +       DBG_leaving;
6347 +
6348 +       return err;
6349 +}
6350 +static int s5k4e1_init(struct i2c_client *c)
6351 +{
6352 +       int ret = 0;
6353 +       struct v4l2_subdev *sd = i2c_get_clientdata(c);
6354 +       struct ci_sensor_config *info = to_sensor_config(sd);
6355 +       char *name = "";
6356 +
6357 +       DBG_entering;
6358 +
6359 +       /* Fill the configuration structure */
6360 +       /* Note this default configuration value */
6361 +       info->mode = s5k4e1_formats[0].pixelformat;
6362 +       info->res = s5k4e1_res[0].res;
6363 +       info->type = SENSOR_TYPE_RAW;
6364 +       info->bls = SENSOR_BLS_OFF;
6365 +       info->gamma = SENSOR_GAMMA_OFF;
6366 +       info->cconv = SENSOR_CCONV_OFF;
6367 +       info->blc = SENSOR_BLC_AUTO;
6368 +       info->agc = SENSOR_AGC_OFF;
6369 +       info->awb = SENSOR_AWB_OFF;
6370 +       info->aec = SENSOR_AEC_OFF;
6371 +       /*info->bus_width = SENSOR_BUSWIDTH_10BIT_ZZ;*/
6372 +       info->bus_width = SENSOR_BUSWIDTH_12BIT;
6373 +       info->ycseq = SENSOR_YCSEQ_YCBYCR;
6374 +       info->conv422 = SENSOR_CONV422_COSITED;
6375 +       /*info->conv422 = SENSOR_CONV422_NOCOSITED;*/
6376 +       info->bpat = SENSOR_BPAT_GRGRBGBG;
6377 +       info->field_inv = SENSOR_FIELDINV_NOSWAP;
6378 +       info->field_sel = SENSOR_FIELDSEL_BOTH;
6379 +       info->hpol = SENSOR_HPOL_REFPOS;
6380 +       info->vpol = SENSOR_VPOL_NEG;
6381 +       info->edge = SENSOR_EDGE_RISING;
6382 +       info->flicker_freq = SENSOR_FLICKER_100;
6383 +       info->cie_profile = SENSOR_CIEPROF_F11;
6384 +       info->mipi_mode = SENSOR_MIPI_MODE_RAW_10;
6385 +       name = "s5k4e1";
6386 +       memcpy(info->name, name, 7);
6387 +
6388 +       /* Reset sensor hardware, and implement the setting*/
6389 +       ret += s5k4e1_write(c, 0x0100, (u32)0x00);
6390 +       /*TODO: See if we can ignore this*/
6391 +       ret = s5k4e1_write(c, 0x0103, (u32)0x01);
6392 +
6393 +       /* sw reset -- delay 3.1ms */
6394 +       msleep(4);
6395 +
6396 +       /* Set registers into default config value */
6397 +       /* ret += s5k4e1_write_array(c, s5k4e1_def_reg); */
6398 +
6399 +       /* Set MIPI interface */
6400 +#ifdef S5K4E1_MIPI
6401 +       ret += s5k4e1_write_array(c, s5k4e1_mipi);
6402 +#endif
6403 +
6404 +       ret += s5k4e1_set_img_ctrl(c, info); /*FIXME*/
6405 +
6406 +       /* streaming */
6407 +       /* ret += s5k4e1_write(c, 0x0100, (u32)0x01); */
6408 +       ret += s5k4e1_write(c, 0x0100, (u32)0x00);
6409 +
6410 +       msleep(1);
6411 +
6412 +       DBG_leaving;
6413 +
6414 +       return ret;
6415 +}
6416 +
6417 +static int distance(struct s5k4e1_res_struct *res, u32 w, u32 h)
6418 +{
6419 +       int ret;
6420 +
6421 +       DBG_entering;
6422 +
6423 +       if (res->width < w || res->height < h)
6424 +               return -1;
6425 +
6426 +       ret = ((res->width - w) + (res->height - h));
6427 +
6428 +       DBG_leaving;
6429 +
6430 +       return ret;
6431 +}
6432 +
6433 +static int s5k4e1_try_res(u32 *w, u32 *h)
6434 +{
6435 +       struct s5k4e1_res_struct *res_index, *p = NULL;
6436 +       int dis, last_dis = s5k4e1_res->width + s5k4e1_res->height;
6437 +
6438 +       DBG_entering;
6439 +
6440 +       for (res_index = s5k4e1_res;
6441 +            res_index < s5k4e1_res + N_RES;
6442 +            res_index++) {
6443 +               if ((res_index->width < *w) || (res_index->height < *h))
6444 +                       break;
6445 +               dis = distance(res_index, *w, *h);
6446 +               if (dis < last_dis) {
6447 +                       last_dis = dis;
6448 +                       p = res_index;
6449 +               }
6450 +       }
6451 +
6452 +       if (p == NULL)
6453 +               p = s5k4e1_res;
6454 +       else if ((p->width < *w) || (p->height < *h)) {
6455 +               if (p != s5k4e1_res)
6456 +                       p--;
6457 +       }
6458 +
6459 +       if ((w != NULL) && (h != NULL)) {
6460 +               *w = p->width;
6461 +               *h = p->height;
6462 +       }
6463 +
6464 +       DBG_leaving;
6465 +       return 0;
6466 +}
6467 +
6468 +static struct s5k4e1_res_struct *s5k4e1_to_res(u32 w, u32 h)
6469 +{
6470 +       struct s5k4e1_res_struct *res_index;
6471 +
6472 +       DBG_entering;
6473 +
6474 +       for (res_index = s5k4e1_res;
6475 +            res_index < s5k4e1_res + N_RES;
6476 +            res_index++)
6477 +               if ((res_index->width == w) && (res_index->height == h))
6478 +                       break;
6479 +
6480 +       if (res_index >= s5k4e1_res + N_RES)
6481 +               res_index--;   /* Take the bigger one */
6482 +
6483 +       DBG_leaving;
6484 +
6485 +       return res_index;
6486 +}
6487 +
6488 +static int s5k4e1_try_fmt(struct v4l2_subdev *sd,
6489 +                         struct v4l2_format *fmt)
6490 +{
6491 +       DBG_entering;
6492 +       return s5k4e1_try_res(&fmt->fmt.pix.width, &fmt->fmt.pix.height);
6493 +       DBG_leaving;
6494 +}
6495 +
6496 +static int s5k4e1_get_fmt(struct v4l2_subdev *sd,
6497 +                         struct v4l2_format *fmt)
6498 +{
6499 +       struct ci_sensor_config *info = to_sensor_config(sd);
6500 +       unsigned short width, height;
6501 +       int index;
6502 +
6503 +       ci_sensor_res2size(info->res, &width, &height);
6504 +
6505 +       /* Marked the current sensor res as being "used" */
6506 +       for (index = 0; index < N_RES; index++) {
6507 +               if ((width == s5k4e1_res[index].width) &&
6508 +                   (height == s5k4e1_res[index].height)) {
6509 +                       s5k4e1_res[index].used = 1;
6510 +                       continue;
6511 +               }
6512 +               s5k4e1_res[index].used = 0;
6513 +       }
6514 +
6515 +       fmt->fmt.pix.width = width;
6516 +       fmt->fmt.pix.height = height;
6517 +       return 0;
6518 +
6519 +}
6520 +
6521 +#if 0
6522 +/* chuanxiao add, to dump regs */
6523 +static int s5k4e1_dump_regs(struct i2c_client *c)
6524 +{
6525 +       /*struct i2c_client *c = v4l2_get_subdevdata(sd);*/
6526 +       const struct DumpRegs *p = regs_d;
6527 +       u32 value;
6528 +       u32 value1, value2, value3, value4;
6529 +       while (p->ulFlags != eTableEnd) {
6530 +               if (p->ulFlags & eFourBytes) {
6531 +                       s5k4e1_read(c, (u32)p->ulAddr, &value1);
6532 +                       s5k4e1_read(c, (u32)p->ulAddr+1, &value2);
6533 +                       s5k4e1_read(c, (u32)p->ulAddr+2, &value3);
6534 +                       s5k4e1_read(c, (u32)p->ulAddr+3, &value4);
6535 +                       value = value1<<24 | value2<<16 | value3<<8 | value4;
6536 +               } else if (p->ulFlags & eTwoBytes) {
6537 +                       s5k4e1_read(c, (u32)p->ulAddr, &value1);
6538 +                       s5k4e1_read(c, (u32)p->ulAddr+1, &value2);
6539 +                       value = value1<<8 | value2;
6540 +               } else
6541 +                       s5k4e1_read(c, (u32)p->ulAddr, &value);
6542 +               /*
6543 +               if (value == p->ulDefaultValue)
6544 +                       dprintk(0, "%s\t @ 0x%x = 0x%lx (= default value)\n",
6545 +                       p->pszName, p->ulAddr, value);
6546 +               else
6547 +                       dprintk(0, "%s\t @ 0x%x = 0x%lx (default was 0x%lx)\n",
6548 +                       p->pszName, p->ulAddr, value, p->ulDefaultValue);
6549 +               */
6550 +               dprintk(0, "%-30s @ 0x%04X = 0x%08X", p->pszName,
6551 +                       p->ulAddr, value);
6552 +               p++;
6553 +       }
6554 +       return 0;
6555 +}
6556 +#endif
6557 +
6558 +static int s5k4e1_set_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
6559 +{
6560 +       struct i2c_client *c = v4l2_get_subdevdata(sd);
6561 +       struct ci_sensor_config *info = to_sensor_config(sd);
6562 +       int ret = 0;
6563 +       struct s5k4e1_res_struct *res_index;
6564 +       u32 width, height;
6565 +       int index;
6566 +
6567 +       DBG_entering;
6568 +
6569 +       width = fmt->fmt.pix.width;
6570 +       height = fmt->fmt.pix.height;
6571 +
6572 +       dprintk(1, "was told to set fmt (%d x %d) ", width, height);
6573 +       ret = s5k4e1_try_res(&width, &height);
6574 +
6575 +       res_index = s5k4e1_to_res(width, height);
6576 +
6577 +       s5k4e1_wakeup();
6578 +       DBG_line;
6579 +       if (res_index->regs) {
6580 +               /* software sleep/standby */
6581 +               ret += s5k4e1_write(c, 0x0100, (u32)0x00);
6582 +
6583 +               /* Soft reset camera first*/
6584 +               /*TODO: See if we can ignore this*/
6585 +               ret = s5k4e1_write(c, 0x0103, (u32)0xff);
6586 +
6587 +               /* Set registers into default config value */
6588 +               /* ret += s5k4e1_write_array(c, s5k4e1_def_reg);*/
6589 +
6590 +               /* set image resolution */
6591 +               ret += s5k4e1_write_array(c, res_index->regs);
6592 +
6593 +               ret += s5k4e1_set_img_ctrl(c, info);
6594 +
6595 +               /* XXX setup with unknow meaning ... */
6596 +               /* ret += s5k4e1_write(c, 0x30b0, 0xfe); */
6597 +
6598 +               /* Set MIPI interface */
6599 +#ifdef S5K4E1_MIPI
6600 +               ret += s5k4e1_write_array(c, s5k4e1_mipi);
6601 +#endif
6602 +
6603 +               /* streaming */
6604 +               ret = s5k4e1_write(c, 0x0100, (u32)0x01);
6605 +               msleep(1);
6606 +
6607 +               info->res = res_index->res;
6608 +
6609 +               /* Marked current sensor res as being "used" */
6610 +               for (index = 0; index < N_RES; index++) {
6611 +                       if ((width == s5k4e1_res[index].width) &&
6612 +                           (height == s5k4e1_res[index].height)) {
6613 +                               s5k4e1_res[index].used = 1;
6614 +                               continue;
6615 +                       }
6616 +                       s5k4e1_res[index].used = 0;
6617 +               }
6618 +
6619 +               for (index = 0; index < N_RES; index++)
6620 +                       dprintk(2, "index = %d, used = %d\n", index,
6621 +                               s5k4e1_res[index].used);
6622 +
6623 +               DBG_line;
6624 +       } else {
6625 +               eprintk("no res for (%d x %d)", width, height);
6626 +       }
6627 +
6628 +       DBG_leaving;
6629 +       return ret;
6630 +}
6631 +
6632 +static int s5k4e1_t_gain(struct v4l2_subdev *sd, int value)
6633 +{
6634 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
6635 +
6636 +       DBG_entering;
6637 +
6638 +       s5k4e1_write(client, 0x0104, 1); /*hold*/
6639 +
6640 +       /* analog gain */
6641 +       s5k4e1_write(client, 0x0204, value >> 8);
6642 +
6643 +       s5k4e1_write(client, 0x0205, value & 0xff);
6644 +
6645 +       s5k4e1_write(client, 0x0104, 0); /*unhold*/
6646 +
6647 +       dprintk(1, "gain %x was writen to 0x0204/5", value);
6648 +
6649 +       DBG_leaving;
6650 +       return 0;
6651 +}
6652 +
6653 +static int s5k4e1_t_exposure(struct v4l2_subdev *sd, int value)
6654 +{
6655 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
6656 +
6657 +       DBG_entering;
6658 +
6659 +       s5k4e1_write(client, 0x0104, 1); /*hold*/
6660 +
6661 +       /* fine integration time */
6662 +       s5k4e1_write(client, 0x0200, value >> 24);
6663 +
6664 +       s5k4e1_write(client, 0x0201, (value >> 16) & 0xff);
6665 +
6666 +       /* coarse integration time */
6667 +       s5k4e1_write(client, 0x0202, (value & 0xff00) >> 8);
6668 +
6669 +       s5k4e1_write(client, 0x0203, value & 0xff);
6670 +
6671 +       s5k4e1_write(client, 0x0104, 0); /*unhold*/
6672 +
6673 +       dprintk(1, "exposure %x was writen to 0x0200/1/2/3", value);
6674 +
6675 +       DBG_leaving;
6676 +       return 0;
6677 +}
6678 +
6679 +static struct s5k4e1_control {
6680 +       struct v4l2_queryctrl qc;
6681 +       int (*query)(struct v4l2_subdev *sd, __s32 *value);
6682 +       int (*tweak)(struct v4l2_subdev *sd, int value);
6683 +} s5k4e1_controls[] = {
6684 +       {
6685 +               .qc = {
6686 +                       .id = V4L2_CID_GAIN,
6687 +                       .type = V4L2_CTRL_TYPE_INTEGER,
6688 +                       .name = "global gain",
6689 +                       .minimum = 0x0,
6690 +                       .maximum = 0xFFFF,
6691 +                       .step = 0x01,
6692 +                       .default_value = 0x00,
6693 +                       .flags = 0,
6694 +               },
6695 +               .tweak = s5k4e1_t_gain,
6696 +       },
6697 +       {
6698 +               .qc = {
6699 +                       .id = V4L2_CID_EXPOSURE,
6700 +                       .type = V4L2_CTRL_TYPE_INTEGER,
6701 +                       .name = "exposure",
6702 +                       .minimum = 0x0,
6703 +                       .maximum = 0xFFFF,
6704 +                       .step = 0x01,
6705 +                       .default_value = 0x00,
6706 +                       .flags = 0,
6707 +               },
6708 +               .tweak = s5k4e1_t_exposure,
6709 +       },
6710 +};
6711 +#define N_CONTROLS (ARRAY_SIZE(s5k4e1_controls))
6712 +
6713 +static struct s5k4e1_control *s5k4e1_find_control(__u32 id)
6714 +{
6715 +       int i;
6716 +
6717 +       DBG_entering;
6718 +       for (i = 0; i < N_CONTROLS; i++)
6719 +               if (s5k4e1_controls[i].qc.id == id)
6720 +                       return s5k4e1_controls + i;
6721 +       DBG_leaving;
6722 +       return NULL;
6723 +}
6724 +
6725 +static int s5k4e1_queryctrl(struct v4l2_subdev *sd,
6726 +                           struct v4l2_queryctrl *qc)
6727 +{
6728 +       struct s5k4e1_control *ctrl = s5k4e1_find_control(qc->id);
6729 +
6730 +       DBG_entering;
6731 +       if (ctrl == NULL)
6732 +               return -EINVAL;
6733 +       *qc = ctrl->qc;
6734 +
6735 +       DBG_leaving;
6736 +       return 0;
6737 +}
6738 +
6739 +static int s5k4e1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
6740 +{
6741 +/*
6742 +       struct s5k4e1_control *octrl = s5k4e1_find_control(parm->index);
6743 +       int ret;
6744 +
6745 +       if (octrl == NULL)
6746 +               return -EINVAL;
6747 +       ret = octrl->query(client, &parm->value);
6748 +       if (ret >= 0)
6749 +               return 0;
6750 +*/
6751 +       return 0;
6752 +}
6753 +
6754 +static int s5k4e1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
6755 +{
6756 +       struct s5k4e1_control *octrl = s5k4e1_find_control(ctrl->id);
6757 +       int ret;
6758 +
6759 +       DBG_entering;
6760 +
6761 +       if (octrl == NULL)
6762 +               return -EINVAL;
6763 +       ret =  octrl->tweak(sd, ctrl->value);
6764 +       if (ret >= 0)
6765 +               return 0;
6766 +
6767 +       DBG_leaving;
6768 +       return ret;
6769 +}
6770 +
6771 +static int s5k4e1_s_stream(struct v4l2_subdev *sd, int enable)
6772 +{
6773 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
6774 +       DBG_entering;
6775 +
6776 +       if (enable) {
6777 +               s5k4e1_write(client, (u32)0x0100, 0x01);
6778 +               /*chuanxiao add, dump s5k4e1 regs*/
6779 +               /* s5k4e1_dump_regs(client); */
6780 +       } else
6781 +               s5k4e1_write(client, (u32)0x0100, 0x00);
6782 +
6783 +       /*msleep(1);*/
6784 +
6785 +       DBG_leaving;
6786 +       return 0;
6787 +}
6788 +
6789 +static int s5k4e1_enum_framesizes(struct v4l2_subdev *sd,
6790 +                                 struct v4l2_frmsizeenum *fsize)
6791 +{
6792 +       unsigned int index = fsize->index;
6793 +
6794 +       DBG_entering;
6795 +
6796 +       if (index >= N_RES)
6797 +               return -EINVAL;
6798 +
6799 +       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
6800 +       fsize->discrete.width = s5k4e1_res[index].width;
6801 +       fsize->discrete.height = s5k4e1_res[index].height;
6802 +       fsize->reserved[0] = s5k4e1_res[index].used;
6803 +
6804 +       DBG_leaving;
6805 +
6806 +       return 0;
6807 +}
6808 +
6809 +static int s5k4e1_enum_frameintervals(struct v4l2_subdev *sd,
6810 +                                     struct v4l2_frmivalenum *fival)
6811 +{
6812 +       unsigned int index = fival->index;
6813 +
6814 +       DBG_entering;
6815 +
6816 +       if (index >= N_RES)
6817 +               return -EINVAL;
6818 +
6819 +       fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
6820 +       fival->discrete.numerator = 1;
6821 +       fival->discrete.denominator = s5k4e1_res[index].fps;
6822 +
6823 +       DBG_leaving;
6824 +
6825 +       return 0;
6826 +}
6827 +
6828 +static int s5k4e1_g_chip_ident(struct v4l2_subdev *sd,
6829 +               struct v4l2_dbg_chip_ident *chip)
6830 +{
6831 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
6832 +
6833 +       DBG_entering;
6834 +
6835 +#define V4L2_IDENT_S5K4E1 8250
6836 +       DBG_leaving;
6837 +
6838 +       return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_S5K4E1, 0);
6839 +}
6840 +
6841 +#ifdef CONFIG_VIDEO_ADV_DEBUG
6842 +static int s5k4e1_g_register(struct v4l2_subdev *sd,
6843 +                            struct v4l2_dbg_register *reg)
6844 +{
6845 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
6846 +       unsigned char val = 0;
6847 +       int ret;
6848 +
6849 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
6850 +               return -EINVAL;
6851 +       if (!capable(CAP_SYS_ADMIN))
6852 +               return -EPERM;
6853 +       ret = s5k4e1_read(client, reg->reg & 0xffff, &val);
6854 +       reg->val = val;
6855 +       reg->size = 1;
6856 +       return ret;
6857 +}
6858 +
6859 +static int s5k4e1_s_register(struct v4l2_subdev *sd,
6860 +                            struct v4l2_dbg_register *reg)
6861 +{
6862 +       struct i2c_client *client = v4l2_get_subdevdata(sd);
6863 +
6864 +       if (!v4l2_chip_match_i2c_client(client, &reg->match))
6865 +               return -EINVAL;
6866 +       if (!capable(CAP_SYS_ADMIN))
6867 +               return -EPERM;
6868 +       s5k4e1_write(client, reg->reg & 0xffff, reg->val & 0xff);
6869 +       return 0;
6870 +}
6871 +#endif
6872 +
6873 +static const struct v4l2_subdev_video_ops s5k4e1_video_ops = {
6874 +       .try_fmt = s5k4e1_try_fmt,
6875 +       .s_fmt = s5k4e1_set_fmt,
6876 +       .g_fmt = s5k4e1_get_fmt,
6877 +       .s_stream = s5k4e1_s_stream,
6878 +       .enum_framesizes = s5k4e1_enum_framesizes,
6879 +       .enum_frameintervals = s5k4e1_enum_frameintervals,
6880 +};
6881 +
6882 +static const struct v4l2_subdev_core_ops s5k4e1_core_ops = {
6883 +       .g_chip_ident = s5k4e1_g_chip_ident,
6884 +       .queryctrl = s5k4e1_queryctrl,
6885 +       .g_ctrl = s5k4e1_g_ctrl,
6886 +       .s_ctrl = s5k4e1_s_ctrl,
6887 +       .s_gpio = s5k4e1_s_power,
6888 +       /*.g_ext_ctrls = s5k4e1_g_ext_ctrls,*/
6889 +       /*.s_ext_ctrls = s5k4e1_s_ext_ctrls,*/
6890 +#ifdef CONFIG_VIDEO_ADV_DEBUG
6891 +       .g_register = s5k4e1_g_register,
6892 +       .s_register = s5k4e1_s_register,
6893 +#endif
6894 +};
6895 +
6896 +static const struct v4l2_subdev_ops s5k4e1_ops = {
6897 +       .core = &s5k4e1_core_ops,
6898 +       .video = &s5k4e1_video_ops,
6899 +};
6900 +
6901 +/*
6902 + * Basic i2c stuff
6903 + */
6904 +/*
6905 +static unsigned short normal_i2c[] = {0x36, I2C_CLIENT_END};
6906 +I2C_CLIENT_INSMOD;
6907 +
6908 +static struct i2c_driver i2c_driver_s5k4e1_sensor;
6909 +*/
6910 +static int s5k4e1_detect(struct i2c_client *client)
6911 +{
6912 +       struct i2c_adapter *adapter = client->adapter;
6913 +       int adap_id = i2c_adapter_id(adapter);
6914 +       u32 value;
6915 +
6916 +       DBG_entering;
6917 +
6918 +       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
6919 +               eprintk("error i2c check func");
6920 +               return -ENODEV;
6921 +       }
6922 +
6923 +       if (adap_id != 1) {
6924 +               eprintk("adap_id != 1");
6925 +               return -ENODEV;
6926 +       }
6927 +
6928 +       if (s5k4e1_wakeup()) {
6929 +               eprintk("sensor wakeup failed");
6930 +               return -EIO;
6931 +       }
6932 +
6933 +       s5k4e1_read(client, 0x0003, &value);
6934 +       dprintk(1, "Read from 0x0003: %x", value);
6935 +       if ((value != 0x09))
6936 +               return -ENODEV;
6937 +
6938 +       s5k4e1_read(client, 0x0000, &value);
6939 +       dprintk(1, "Read from 0x0000: %x", value);
6940 +       if ((value != 0x4e) && (value != 0x10))
6941 +               return -ENODEV;
6942 +
6943 +       s5k4e1_read(client, 0x0001, &value);
6944 +       dprintk(1, "Read from 0x0001: %x", value);
6945 +       if ((value != 0x4e) && (value != 0x10))
6946 +               return -ENODEV;
6947 +
6948 +       /*TODO EVT3 detect*/
6949 +       s5k4e1_read(client, 0x0002, &value);
6950 +       dprintk(1, "Read from 0x0002: %x", value);
6951 +       if (value == 0x0010) {
6952 +               dprintk(1, "EVT3 module not supported!");
6953 +               return -ENODEV;
6954 +       }
6955 +
6956 +       DBG_leaving;
6957 +       return 0;
6958 +}
6959 +
6960 +static int s5k4e1_probe(struct i2c_client *client,
6961 +                       const struct i2c_device_id *id)
6962 +{
6963 +       struct ci_sensor_config *info;
6964 +       struct v4l2_subdev *sd;
6965 +       int ret = -1;
6966 +
6967 +       DBG_entering;
6968 +
6969 +       v4l_info(client, "chip found @ 0x%x (%s)\n",
6970 +                client->addr << 1, client->adapter->name);
6971 +
6972 +       /*
6973 +        * Setup sensor configuration structure
6974 +        */
6975 +       info = kzalloc(sizeof(struct ci_sensor_config), GFP_KERNEL);
6976 +       if (!info) {
6977 +               dprintk(0, "fail to malloc for ci_sensor_config");
6978 +               ret = -ENOMEM;
6979 +               goto out;
6980 +       }
6981 +
6982 +       ret = s5k4e1_detect(client);
6983 +       if (ret) {
6984 +               dprintk(0, "error s5k4e1_detect");
6985 +               goto out_free;
6986 +       }
6987 +
6988 +       sd = &info->sd;
6989 +       v4l2_i2c_subdev_init(sd, client, &s5k4e1_ops);
6990 +
6991 +       /*
6992 +        * Initialization S5K4E1
6993 +        * then turn into standby mode
6994 +        */
6995 +       ret = s5k4e1_init(client);
6996 +       if (ret) {
6997 +               dprintk(0, "error calling s5k4e1_init");
6998 +               goto out_free;
6999 +       }
7000 +
7001 +       s5k4e1_standby();
7002 +       dprintk(0, "Init s5k4e1 sensor successfully");
7003 +
7004 +       ret = 0;
7005 +       goto out;
7006 +
7007 +out_free:
7008 +       kfree(info);
7009 +       DBG_leaving;
7010 +out:
7011 +
7012 +       DBG_leaving;
7013 +       return ret;
7014 +}
7015 +
7016 +
7017 +static int s5k4e1_remove(struct i2c_client *client)
7018 +{
7019 +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
7020 +
7021 +       DBG_entering;
7022 +
7023 +       v4l2_device_unregister_subdev(sd);
7024 +       kfree(to_sensor_config(sd));
7025 +
7026 +       DBG_leaving;
7027 +       return 0;
7028 +}
7029 +
7030 +/**
7031 + * i2c_driver for s5k4e1_sensor
7032 + */
7033 +static const struct i2c_device_id s5k4e1_id[] = {
7034 +       {"s5k4e1", 0},
7035 +       {}
7036 +};
7037 +
7038 +MODULE_DEVICE_TABLE(i2c, s5k4e1_id);
7039 +
7040 +static struct v4l2_i2c_driver_data v4l2_i2c_data = {
7041 +       .name = "s5k4e1",
7042 +       .probe = s5k4e1_probe,
7043 +       .remove = s5k4e1_remove,
7044 +       /* .suspend = s5k4e1_suspend,
7045 +        * .resume = s5k4e1_resume, */
7046 +       .id_table = s5k4e1_id,
7047 +};
7048 +
7049 +MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
7050 +MODULE_DESCRIPTION("A low-level driver for Samsung S5K4E1 sensors");
7051 +MODULE_LICENSE("GPL");
7052 diff --git a/drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.h b/drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.h
7053 new file mode 100755
7054 index 0000000..d722035
7055 --- /dev/null
7056 +++ b/drivers/media/video/mrstci/mrsts5k4e1/mrsts5k4e1.h
7057 @@ -0,0 +1,662 @@
7058 +/*
7059 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
7060 + *
7061 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
7062 + *
7063 + * This program is free software; you can redistribute it and/or
7064 + * modify it under the terms of the GNU General Public License version
7065 + * 2 as published by the Free Software Foundation.
7066 + *
7067 + * This program is distributed in the hope that it will be useful,
7068 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7069 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7070 + * GNU General Public License for more details.
7071 + *
7072 + * You should have received a copy of the GNU General Public License
7073 + * along with this program; if not, write to the Free Software
7074 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
7075 + * 02110-1301, USA.
7076 + *
7077 + *
7078 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
7079 + */
7080 +
7081 +#define I2C_S5K4E1     0x6C
7082 +/* Should add to kernel source */
7083 +#define I2C_DRIVERID_S5K4E1    1046
7084 +/* GPIO pin on Moorestown */
7085 +#define GPIO_SCLK_25   44
7086 +#define GPIO_STB_PIN   47
7087 +#define GPIO_STDBY_PIN 49
7088 +#define GPIO_RESET_PIN 50
7089 +
7090 +struct regval_list {
7091 +       u16 reg_num;
7092 +       u8 value;
7093 +};
7094 +
7095 +/*
7096 + * Default register value
7097 + * 5Mega Pixel, 2592x1944
7098 + */
7099 +/* MIPI register are removed by Wen */
7100 +
7101 +/* 2592x1944 */
7102 +static struct regval_list s5k4e1_res_qsxga_plus4[] = {
7103 +       /* Reset for operation */
7104 +       {0x0100, 0x00},         /* stream off */
7105 +       {0x0103, 0x01},         /* software reset */
7106 +
7107 +/*
7108 + * Analog Setting
7109 + * This register is for FACTORY ONLY.
7110 + * If you change it without prior notification,
7111 + * You are RESPONSIBLE for the FAILURE that will happen in the future.
7112 + */
7113 +
7114 +/* CDS timing setting ... */
7115 +       {0x3000, 0x04}, /* ct_ld_start (default = 07h) */
7116 +       {0x3001, 0x02}, /* ct_sl_start (default = 05h) */
7117 +       {0x3002, 0x0C}, /* ct_rx_start (default = 21h) */
7118 +       {0x3003, 0x0E}, /* ct_cds_start (default = 23h) */
7119 +       {0x3004, 0x2C}, /* ct_smp_width (default = 60h) */
7120 +       {0x3005, 0x0D}, /* ct_az_width (default = 28h) */
7121 +       {0x3006, 0x39}, /* ct_s1r_width (default = 88h) */
7122 +       {0x3007, 0x02}, /* ct_tx_start (default = 06h) */
7123 +       {0x3008, 0x3C}, /* ct_tx_width 1.5us (default = 7Ch) */
7124 +       {0x3009, 0x3C}, /* ct_stx_width 1.5us (default = 7Ch) */
7125 +       {0x300A, 0x28}, /* ct_dtx_width 1us (default = 3Eh) */
7126 +       {0x300B, 0x15}, /* ct_rmp_rst_start (default = 44h) */
7127 +       {0x300C, 0x15}, /* ct_rmp_sig_start (default = 48h) */
7128 +       {0x300D, 0x02}, /* ct_rmp_lat (default = 02h) */
7129 +       {0x300E, 0xA9}, /* D-Shut en[7], CLP On[5], LD high[4] */
7130 +
7131 +/* CDS option setting ... */
7132 +       {0x3010, 0x00}, /* smp_en[2]=0(00) 1(04) row_id[1:0] = 00 */
7133 +       {0x3011, 0x7A}, /* RST_MX (288), SIG_MX (1024+352) */
7134 +       {0x3012, 0x30}, /* SIG offset1  48 code  */
7135 +       {0x3013, 0xA0}, /* RST offset1  160 code */
7136 +       {0x3014, 0x00}, /* SIG offset2 */
7137 +       {0x3015, 0x00}, /* RST offset2 */
7138 +       {0x3016, 0x02}, /* ADC_SAT (510mV) */
7139 +       {0x3017, 0x94}, /* RMP_INIT[3:0](RMP_REG) 1.8V MS[6:4]=1 */
7140 +       {0x3018, 0x78}, /* rmp option - ramp connect[MSB] +RMP INIT DAC MIN */
7141 +       {0x301D, 0xD4}, /* CLP level (default = 0Fh) */
7142 +
7143 +       {0x3021, 0x02}, /* inrush ctrl[1] off */
7144 +       {0x3022, 0x44}, /* pump ring oscillator set [7:4]=CP, [3:0]=NCP  */
7145 +       {0x3024, 0x40}, /* pix voltage 2.8V   (default = 88h) */
7146 +       {0x3027, 0x08}, /* ntg voltage (default = 04h) */
7147 +
7148 +/* Pixel option setting ... */
7149 +       {0x301C, 0x05}, /* Pixel Bias [3:0] (default = 03h) */
7150 +       {0x30D8, 0x3F}, /* All tx off 2f, on 3f */
7151 +
7152 +/* ADLC setting ... */
7153 +       {0x3070, 0x5F}, /* [6]L-ADLC BPR, [4]ch sel, [3]L-ADLC, [2]F-ADLC */
7154 +       {0x3071, 0x00}, /* F&L-adlc max 127 (default = 11h, max 255) */
7155 +       {0x3080, 0x04}, /* F-ADLC filter A (default = 10h) */
7156 +       {0x3081, 0x38}, /* F-ADLC filter B (default = 20h) */
7157 +
7158 +/* Integration setting ... */
7159 +       {0x0202, 0x03}, /* coarse integration time */
7160 +       {0x0203, 0xCF},
7161 +       {0x0204, 0x00}, /* analog gain[msb] 0100 x8 0080 x4 */
7162 +       {0x0205, 0x80}, /* analog gain[lsb] 0040 x2 0020 x1 */
7163 +
7164 +/* Frame Length */
7165 +       {0x0340, 0x07}, /* Capture 07B4(1960[# of row]+12[V-blank]) */
7166 +       {0x0341, 0xA4}, /* Preview 03E0(980[# of row]+12[V-blank]) */
7167 +
7168 +/* Line Length */
7169 +       {0x0342, 0x0A}, /* 2738 */
7170 +       {0x0343, 0xB2}, /* (Same as sensor default) */
7171 +
7172 +/* embedded 2-line OFF setting ... */
7173 +/* 2608 x 1960  */
7174 +       {0x3084, 0x15}, /* SYNC Mode */
7175 +
7176 +/* (3) MIPI 2-lane Serial(TST = 0000b or TST = 0010b), 30 fps */
7177 +
7178 +       {0x30A9, 0x01},
7179 +       {0x0387, 0x01},
7180 +
7181 +       {0x30BD, 0x00},         /* SEL_CCP[0] */
7182 +       {0x30B2, 0x08},         /* PLL P = 8 */
7183 +       {0x30B3, 0x00},         /* PLL M[8] = 0 */
7184 +       {0x30B5, 0x01},         /* PLL S = 0 */
7185 +       {0x30BE, 0x1A},         /* M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0] */
7186 +
7187 +       {0x30BF, 0xAB},
7188 +       {0x30C0, 0x00},         /* video_offset[7:4] 3240%12 */
7189 +       {0x30C1, 0x01},         /* pack video enable [0] */
7190 +       {0x30C8, 0x0C},         /* video_data_length 3260 = 2608 * 1.25 */
7191 +       {0x30C9, 0xA8},
7192 +       {0x30E2, 0x02},         /* num lanes[1:0] = 2 */
7193 +       {0x30EE, 0x02},         /* DPHY enable [1] */
7194 +       {0x30F1, 0x70},         /* DPHY BANDCTRL 800MHz=80.6MHz */
7195 +       {0x3111, 0x86},         /* Embedded data off [5] */
7196 +
7197 +       {0x034C, 0x0A},
7198 +       {0x034D, 0x20},
7199 +       {0x044E, 0x07},
7200 +       {0x034F, 0x98},
7201 +
7202 +       {0x0344, 0x00},
7203 +       {0x0345, 0x08},
7204 +       {0x0346, 0x00},
7205 +       {0x0347, 0x08},
7206 +       {0x0348, 0x0A},
7207 +       {0x0349, 0x27},
7208 +       {0x034A, 0x07},
7209 +       {0x034B, 0x9F},
7210 +
7211 +       /* This is to set FRAME_NUM > 0 */
7212 +       {0x30d9, 0x00},
7213 +
7214 +       /* Add this setting according to Bill's test */
7215 +       {0x0305, 0x05},
7216 +       {0x0306, 0x00},
7217 +       {0x0307, 0x3c},
7218 +       {0x30b5, 0x02},
7219 +
7220 +       {0x020E, 0x01},      /* Gr Digital Gain */
7221 +       {0x020F, 0x00},
7222 +       {0x0210, 0x01},     /* Red Digital Gain */
7223 +       {0x0211, 0x00},
7224 +       {0x0212, 0x01},     /* Blue Digital Gain */
7225 +       {0x0213, 0x00},
7226 +       {0x0214, 0x01},    /* Gb Digital Gain */
7227 +       {0x0215, 0x00},
7228 +       {0x0204, 0x00},
7229 +       {0x0205, 0x80},
7230 +
7231 +#if 1
7232 +       /*Apply Bill's setting*/
7233 +       {0x30E2, 0x02},
7234 +       {0x0305, 0x05},
7235 +       {0x0306, 0x00},
7236 +       {0x0307, 0x50},         /* vcc_out = 80 */
7237 +       {0x30B5, 0x01},         /* pll_s = 1 */
7238 +       {0x30B4, 0x50},
7239 +
7240 +       {0x30B2, 0x05},
7241 +
7242 +       {0x30BE, 0x1A},         /* DIV_M_PCLK = 5 */
7243 +
7244 +       {0x0100, 0x01},         /* stream on */
7245 +       {0xffff, 0xff},
7246 +#endif
7247 +};
7248 +
7249 +/* 1920x1080 */
7250 +static struct regval_list s5k4e1_res_1080p[] = {
7251 +/* Reset for operation ... */
7252 +       {0x0100, 0x00},         /* stream off */
7253 +       {0x0103, 0x01},         /* software reset */
7254 +
7255 +/*
7256 + * Analog Setting
7257 + * This register is for FACTORY ONLY.
7258 + * If you change it without prior notification,
7259 + * You are RESPONSIBLE for the FAILURE that will happen in the future.
7260 + */
7261 +
7262 +/* CDS timing setting ... */
7263 +       {0x3000, 0x04}, /* ct_ld_start (default = 07h) */
7264 +       {0x3001, 0x02}, /* ct_sl_start (default = 05h) */
7265 +       {0x3002, 0x0C}, /* ct_rx_start (default = 21h) */
7266 +       {0x3003, 0x0E}, /* ct_cds_start (default = 23h) */
7267 +       {0x3004, 0x2C}, /* ct_smp_width (default = 60h) */
7268 +       {0x3005, 0x0D}, /* ct_az_width (default = 28h) */
7269 +       {0x3006, 0x39}, /* ct_s1r_width (default = 88h) */
7270 +       {0x3007, 0x02}, /* ct_tx_start (default = 06h) */
7271 +       {0x3008, 0x3C}, /* ct_tx_width 1.5us (default = 7Ch) */
7272 +       {0x300A, 0x28}, /* ct_dtx_width 1us (default = 3Eh) */
7273 +       {0x300B, 0x15}, /* ct_rmp_rst_start (default = 44h) */
7274 +       {0x300C, 0x15}, /* ct_rmp_sig_start (default = 48h) */
7275 +       {0x300D, 0x02}, /* ct_rmp_lat (default = 02h) */
7276 +       {0x300E, 0xA9}, /* D-Shut en[7], CLP On[5], LD high[4] */
7277 +
7278 +/* CDS option setting ... */
7279 +       {0x3010, 0x00}, /* smp_en[2]=0(00) 1(04) row_id[1:0] = 00 */
7280 +       {0x3011, 0x7A}, /* RST_MX (288), SIG_MX (1024+352) */
7281 +       {0x3012, 0x30}, /* SIG offset1  48 code */
7282 +       {0x3013, 0xA0}, /* RST offset1  160 code */
7283 +       {0x3014, 0x00}, /* SIG offset2 */
7284 +       {0x3015, 0x00}, /* RST offset2 */
7285 +       {0x3016, 0x0A}, /* ADC_SAT (510mV) */
7286 +       {0x3017, 0x94}, /* RMP_INIT[3:0](RMP_REG) 1.8V MS[6:4]=1 */
7287 +       {0x3018, 0x78}, /* rmp option - ramp connect[MSB] +RMP INIT DAC MIN */
7288 +
7289 +       {0x301D, 0xD4}, /* CLP level (default = 0Fh) */
7290 +
7291 +       {0x3021, 0x02}, /* inrush ctrl[1] off */
7292 +       {0x3022, 0x41}, /* pump ring oscillator set [7:4]=CP, [3:0]=NCP */
7293 +       {0x3024, 0x08}, /* pix voltage 2.8V   (default = 88h) */
7294 +       {0x3027, 0x08}, /* ntg voltage (default = 04h) */
7295 +
7296 +/* Pixel option setting ... */
7297 +       {0x301C, 0x05}, /* Pixel Bias [3:0] (default = 03h) */
7298 +       {0x30D8, 0x3F}, /* All tx off 2f, on 3f */
7299 +
7300 +/* ADLC setting ... */
7301 +       {0x3070, 0x5F}, /* [6]L-ADLC BPR, [4]ch sel, [3]L-ADLC, [2]F-ADLC */
7302 +       {0x3071, 0x00}, /* F&L-adlc max 127 (default = 11h, max 255) */
7303 +       {0x3080, 0x04}, /* F-ADLC filter A (default = 10h) */
7304 +       {0x3081, 0x38}, /* F-ADLC filter B (default = 20h) */
7305 +
7306 +/* Integration setting ... */
7307 +       {0x0202, 0x03}, /* coarse integration time */
7308 +       {0x0203, 0xCD},
7309 +       {0x0204, 0x00}, /* analog gain[msb] 0100 x8 0080 x4 */
7310 +       {0x0205, 0x80}, /* analog gain[lsb] 0040 x2 0020 x1 */
7311 +
7312 +/* Frame Length */
7313 +       {0x0340, 0x04}, /*Capture 07B4(1960[# of row]+12[V-blank]) */
7314 +       {0x0341, 0x44}, /*Preview 03E0(980[# of row]+12[V-blank]) */
7315 +
7316 +/* Line Length */
7317 +       {0x0342, 0x0A}, /* 2738 */
7318 +       {0x0343, 0xB2}, /*(Same as sensor default) */
7319 +
7320 +/* embedded 2-line OFF setting ... */
7321 +/* 1920 x 1080 */
7322 +       {0x3084, 0x15}, /* SYNC Mode */
7323 +
7324 +/* PLL & MIPI setting ... */
7325 +/* input clock 25MHz */
7326 +
7327 +/* (3) MIPI 2-lane Serial(TST = 0000b or TST = 0010b), 30 fps */
7328 +       {0x30BD, 0x00},         /* SEL_CCP[0] */
7329 +       {0x30B2, 0x08},         /* PLL P = 8 */
7330 +       {0x30B3, 0x00},         /* PLL M[8] = 0 */
7331 +       {0x30B4, 0x78},         /* PLL M = 129 */
7332 +       {0x30B5, 0x00},         /* PLL S = 0 */
7333 +       {0x30BE, 0x1A},         /* M_PCLKDIV_AUTO[4], M_DIV_PCLK[3:0] */
7334 +
7335 +       {0x30BF, 0xAB},
7336 +       {0x30C0, 0x00},         /* video_offset[7:4] 2400%12 */
7337 +       {0x30C1, 0x01},         /* pack video enable [0] */
7338 +       {0x30C8, 0x09},         /* video_data_length 2400 = 1920 * 1.25 */
7339 +       {0x30C9, 0x60},
7340 +       {0x30E2, 0x02},         /* num lanes[1:0] = 2 */
7341 +       {0x30EE, 0x02},         /* DPHY enable [1] */
7342 +       {0x30F1, 0x70},         /* DPHY BANDCTRL 800MHz=80.6MHz */
7343 +       {0x3111, 0x86},         /* Embedded data off [5] */
7344 +
7345 +       {0x30b4, 0x20},
7346 +       {0x30b5, 0x01},
7347 +
7348 +       {0x30A9, 0x01},
7349 +       {0x0387, 0x01},
7350 +       {0x0344, 0x01}, /*x_addr_start 344 */
7351 +       {0x0345, 0x58},
7352 +       {0x0348, 0x08}, /*x_addr_end 2263 */
7353 +       {0x0349, 0xD7},
7354 +       {0x0346, 0x01}, /*y_addr_start 440 */
7355 +       {0x0347, 0xB8},
7356 +       {0x034A, 0x05}, /*y_addr_end 1519 */
7357 +       {0x034B, 0xEF},
7358 +
7359 +       {0x034C, 0x07}, /*x_output_size 1920 */
7360 +       {0x034D, 0x80},
7361 +       {0x034E, 0x04}, /*y_output_size 1080 */
7362 +       {0x034F, 0x38},
7363 +
7364 +       {0x30d9, 0x00},
7365 +
7366 +       {0x020E, 0x01},      /*Gr Digital Gain */
7367 +       {0x020F, 0x00},
7368 +       {0x0210, 0x01},     /*Red Digital Gain */
7369 +       {0x0211, 0x00},
7370 +       {0x0212, 0x01},     /*Blue Digital Gain */
7371 +       {0x0213, 0x00},
7372 +       {0x0214, 0x01},    /*Gb Digital Gain */
7373 +       {0x0215, 0x00},
7374 +       {0x0204, 0x00},
7375 +       {0x0205, 0x80},
7376 +
7377 +
7378 +       /*Apply Bill's setting*/
7379 +       {0x30E2, 0x02},
7380 +       {0x0305, 0x05},
7381 +       {0x0306, 0x00},
7382 +       {0x0307, 0x50},         /*vcc_out = 80 */
7383 +       {0x30B5, 0x01},         /*pll_s = 1 */
7384 +       {0x30B4, 0x50},
7385 +
7386 +       {0x30B2, 0x05},
7387 +
7388 +       {0x30BE, 0x1A},         /*DIV_M_PCLK = 5 */
7389 +
7390 +       {0x0383, 0x01},
7391 +
7392 +       {0x0100, 0x01},         /* stream on */
7393 +       {0xffff, 0xff},
7394 +
7395 +};
7396 +
7397 +/* 1280x720, V1F2 & H1F2 */
7398 +static struct regval_list s5k4e1_res_720p[] = {
7399 +       {0x0100, 0x00},         /* stream off */
7400 +       {0x0103, 0x01},         /* software reset */
7401 +
7402 +/* CDS timing setting ... */
7403 +       {0x3000, 0x04},
7404 +       {0x3001, 0x02},
7405 +       {0x3002, 0x0C},
7406 +       {0x3003, 0x0E},
7407 +       {0x3004, 0x2C},
7408 +       {0x3005, 0x0D},
7409 +       {0x3006, 0x39},
7410 +       {0x3007, 0x02},
7411 +       {0x3008, 0x3C},
7412 +       {0x3009, 0x3C},
7413 +       {0x300A, 0x28},
7414 +       {0x300B, 0x15},
7415 +       {0x300C, 0x15},
7416 +       {0x300D, 0x02},
7417 +       {0x300E, 0xAB},
7418 +
7419 +/* CDS option setting ... */
7420 +       {0x3010, 0x00},
7421 +       {0x3011, 0x7A},
7422 +       {0x3012, 0x30},
7423 +       {0x3013, 0x90},
7424 +       {0x3014, 0x00},
7425 +       {0x3015, 0x00},
7426 +       {0x3016, 0x0A},
7427 +       {0x3017, 0x84},
7428 +       {0x3018, 0x78},
7429 +       {0x301D, 0xD4},
7430 +
7431 +       {0x3021, 0x02},
7432 +       {0x3022, 0x41},
7433 +       {0x3024, 0x08},
7434 +       {0x3027, 0x08},
7435 +
7436 +/* Pixel option setting ... */
7437 +       {0x301C, 0x05}, /* Pixel Bias [3:0] (default = 03h) */
7438 +       {0x30D8, 0x3F}, /* All tx off 2f, on 3f */
7439 +
7440 +/* ADLC setting ... */
7441 +       {0x3070, 0x5F},
7442 +       {0x3071, 0x00},
7443 +       {0x3080, 0x04},
7444 +       {0x3081, 0x38},
7445 +
7446 +/* Integration setting ...  */
7447 +       {0x0202, 0x03},
7448 +       {0x0203, 0xD8},
7449 +       {0x0204, 0x00},
7450 +       {0x0205, 0x80},
7451 +
7452 +/*Frame Length*/
7453 +       {0x0340, 0x02},
7454 +       {0x0341, 0xDC},
7455 +
7456 +/* Line Length */
7457 +       {0x0342, 0x0A}, /*2738 */
7458 +       {0x0343, 0xB2},
7459 +
7460 +/* Average Sub-sampling */
7461 +       {0x0387, 0x03},
7462 +       {0x30a9, 0x02},
7463 +
7464 +/* embedded 2-line OFF setting ... */
7465 +/* 1280 x 720 */
7466 +       {0x3084, 0x15},
7467 +
7468 +/* PLL & MIPI setting ... */
7469 +
7470 +/* (3) MIPI 2-lane Serial(TST = 0000b or TST = 0010b), 60 fps */
7471 +       {0x30BD, 0x00},
7472 +       {0x30B2, 0x08},
7473 +       {0x30B3, 0x00},
7474 +       {0x30B4, 0x78},
7475 +       {0x30B5, 0x00},
7476 +       {0x30BE, 0x1A},
7477 +
7478 +       {0x30BF, 0xAB},
7479 +       {0x30C0, 0x40},
7480 +       {0x30C1, 0x01},
7481 +       {0x30C8, 0x06},
7482 +       {0x30C9, 0x40},
7483 +
7484 +       {0x30E2, 0x02},
7485 +
7486 +       {0x30b4, 0x20},
7487 +       {0x30b5, 0x01},
7488 +
7489 +       {0x30EE, 0x02},
7490 +       {0x30F1, 0x70},
7491 +       {0x3111, 0x86},
7492 +
7493 +/* MIPI Size Setting ... */
7494 +/* 1304 x 980 */
7495 +       {0x0344, 0x00},
7496 +       {0x0345, 0x18},
7497 +       {0x0348, 0x0A},
7498 +       {0x0349, 0x17},
7499 +       {0x0346, 0x01},
7500 +       {0x0347, 0x04},
7501 +       {0x034A, 0x06},
7502 +       {0x034B, 0xA3},
7503 +
7504 +       {0x0380, 0x00},
7505 +       {0x0381, 0x01},
7506 +       {0x0382, 0x00},
7507 +       {0x0383, 0x01},
7508 +       {0x0384, 0x00},
7509 +       {0x0385, 0x01},
7510 +       {0x0386, 0x00},
7511 +       {0x0387, 0x03},
7512 +
7513 +       {0x034C, 0x05}, /* x_output_size = 1280 */
7514 +       {0x034D, 0x00},
7515 +       {0x034E, 0x02}, /* y_output_size = 720 */
7516 +       {0x034F, 0xD0},
7517 +
7518 +       {0x30d9, 0x00},
7519 +
7520 +       {0x020E, 0x01},
7521 +       {0x020F, 0x00},
7522 +       {0x0210, 0x01},
7523 +       {0x0211, 0x00},
7524 +       {0x0212, 0x01},
7525 +       {0x0213, 0x00},
7526 +       {0x0214, 0x01},
7527 +       {0x0215, 0x00},
7528 +       {0x0204, 0x01},
7529 +       {0x0205, 0x00},
7530 +
7531 +       /*Apply Bill's setting*/
7532 +       {0x30E2, 0x02},
7533 +       {0x0305, 0x05},
7534 +       {0x0306, 0x00},
7535 +       {0x0307, 0x50},         /*vcc_out = 80 */
7536 +       {0x30B5, 0x01},         /*pll_s = 1 */
7537 +       {0x30B4, 0x50},
7538 +
7539 +       {0x30B2, 0x05},
7540 +
7541 +       {0x30BE, 0x15},         /*DIV_M_PCLK = 5 */
7542 +
7543 +       {0x0100, 0x01},         /* stream on */
7544 +       {0xffff, 0xff},
7545 +};
7546 +
7547 +/*VGA*/
7548 +static struct regval_list s5k4e1_res_vga_ac04_bill[] = {
7549 +       {0x0100, 0x00},         /* stream off */
7550 +       {0x0103, 0x01},         /* software reset */
7551 +
7552 +       {0x3000, 0x04},
7553 +       {0x3001, 0x02},
7554 +       {0x3002, 0x0C},
7555 +       {0x3003, 0x0E},
7556 +       {0x3004, 0x2C},
7557 +       {0x3005, 0x0D},
7558 +       {0x3006, 0x39},
7559 +       {0x3007, 0x02},
7560 +       {0x3008, 0x3C},
7561 +       {0x3009, 0x3C},
7562 +       {0x300A, 0x28},
7563 +       {0x300B, 0x15},
7564 +       {0x300C, 0x15},
7565 +       {0x300D, 0x02},
7566 +       {0x300E, 0xA8},
7567 +
7568 +       {0x3010, 0x00},
7569 +       {0x3011, 0x7A},
7570 +       {0x3012, 0x30},
7571 +       {0x3013, 0xA0},
7572 +       {0x3014, 0x00},
7573 +       {0x3015, 0x00},
7574 +       {0x3016, 0x0A},
7575 +       {0x3017, 0x94},
7576 +       {0x3018, 0x78},
7577 +
7578 +       {0x301D, 0xD4},
7579 +
7580 +       {0x3021, 0x02},
7581 +       {0x3022, 0x41},
7582 +       {0x3024, 0x08},
7583 +       {0x3027, 0x08},
7584 +
7585 +       {0x301C, 0x05},
7586 +       {0x30D8, 0x3F},
7587 +
7588 +       {0x3070, 0x5F},
7589 +       {0x3071, 0x00},
7590 +       {0x3080, 0x04},
7591 +       {0x3081, 0x38},
7592 +
7593 +       {0x0202, 0x03},
7594 +       {0x0203, 0xD4},
7595 +       {0x0204, 0x00},
7596 +       {0x0205, 0x20},
7597 +
7598 +       {0x0340, 0x03},
7599 +       {0x0341, 0xE0},
7600 +
7601 +       {0x0342, 0x0A},
7602 +       {0x0343, 0xB2},
7603 +
7604 +       {0x0344, 0x00},
7605 +       {0x0345, 0x18},
7606 +       {0x0348, 0x0A},
7607 +       {0x0349, 0x17},
7608 +       {0x0346, 0x00},
7609 +       {0x0347, 0x14},
7610 +       {0x034A, 0x07},
7611 +       {0x034B, 0x93},
7612 +
7613 +       {0x034C, 0x02},
7614 +       {0x034D, 0x80},
7615 +       {0x034E, 0x01},
7616 +       {0x034F, 0xE0},
7617 +
7618 +       {0x0380, 0x00},
7619 +       {0x0381, 0x01},
7620 +       {0x0382, 0x00},
7621 +       {0x0383, 0x07},
7622 +       {0x0384, 0x00},
7623 +       {0x0385, 0x01},
7624 +       {0x0386, 0x00},
7625 +       {0x0387, 0x07},
7626 +
7627 +       {0x3084, 0x15},
7628 +
7629 +       {0x30BD, 0x00},
7630 +
7631 +
7632 +       {0x30b3, 0x00},
7633 +       {0x30b4, 0x57},
7634 +       {0x30b5, 0x01},
7635 +       {0x30f1, 0x70},
7636 +
7637 +       {0x30BE, 0x1A},
7638 +
7639 +       {0x30BF, 0xAB},
7640 +       {0x30C0, 0x80},
7641 +       {0x30C1, 0x01},
7642 +       {0x30C8, 0x03},
7643 +       {0x30C9, 0x20},
7644 +
7645 +       {0x30b2, 0x06},
7646 +       {0x30E2, 0x02},
7647 +
7648 +       {0x30EE, 0x02},
7649 +
7650 +       {0x3111, 0x86},
7651 +
7652 +       {0x30d9, 0x00},
7653 +
7654 +       {0x020E, 0x01},
7655 +       {0x020F, 0x00},
7656 +       {0x0210, 0x01},
7657 +       {0x0211, 0x00},
7658 +       {0x0212, 0x01},
7659 +       {0x0213, 0x00},
7660 +       {0x0214, 0x01},
7661 +       {0x0215, 0x00},
7662 +       {0x0204, 0x01},
7663 +       {0x0205, 0x00},
7664 +
7665 +#if 1
7666 +       /* Apply Bill's setting */
7667 +       {0x30E2, 0x02},
7668 +       {0x0305, 0x05},
7669 +       {0x0306, 0x00},
7670 +       {0x0307, 0x50},
7671 +       {0x30B5, 0x01},
7672 +       {0x30B4, 0x50},
7673 +
7674 +       {0x30B2, 0x05},
7675 +
7676 +       {0x30BE, 0x15},
7677 +
7678 +       /* {0x0100, 0x01}, */
7679 +       /* {0xffff, 0xff}, */
7680 +#endif
7681 +
7682 +#if 1
7683 +       /* 1304x980 */
7684 +       {0x3013, 0x90},
7685 +       {0x3017, 0x84},
7686 +       {0x30A9, 0x02},
7687 +       {0x300E, 0xAB},
7688 +
7689 +       {0x0387, 0x03},
7690 +       {0x0344, 0x00}, /* x_addr_start = 0 */
7691 +       {0x0345, 0x00},
7692 +       {0x0348, 0x0A}, /* x_addr_end = 2607 */
7693 +       {0x0349, 0x2F},
7694 +       {0x0346, 0x00}, /* y_addr_start = 0 */
7695 +       {0x0347, 0x00},
7696 +       {0x034A, 0x07}, /* y_addr_end = 1959 */
7697 +       {0x034B, 0xA7},
7698 +       {0x0380, 0x00},
7699 +       {0x0381, 0x01},
7700 +       {0x0382, 0x00},
7701 +       {0x0383, 0x01},
7702 +       {0x0384, 0x00},
7703 +       {0x0385, 0x01},
7704 +       {0x0386, 0x00},
7705 +       {0x0387, 0x03},
7706 +       {0x034c, 0x05}, /* x_output_size = 1304 */
7707 +       {0x034d, 0x18},
7708 +       {0x034e, 0x03}, /* y_output_size = 980 */
7709 +       {0x034f, 0xd4},
7710 +       {0x30BF, 0xAB},
7711 +       {0x30c0, 0xa0},
7712 +       {0x30C8, 0x06}, /* x_output_size * 1.25 */
7713 +       {0x30c9, 0x5e},
7714 +
7715 +       {0x0100, 0x01},
7716 +       {0xffff, 0xff},
7717 +
7718 +#endif
7719 +};
7720 diff --git a/drivers/media/video/mrstci/mrsts5k4e1_motor/Kconfig b/drivers/media/video/mrstci/mrsts5k4e1_motor/Kconfig
7721 new file mode 100755
7722 index 0000000..27cb730
7723 --- /dev/null
7724 +++ b/drivers/media/video/mrstci/mrsts5k4e1_motor/Kconfig
7725 @@ -0,0 +1,9 @@
7726 +config VIDEO_MRST_S5K4E1_MOTOR
7727 +       tristate "Moorestown s5k4e1 motor"
7728 +       depends on I2C && VIDEO_MRST_ISP && VIDEO_MRST_S5K4E1
7729 +
7730 +       ---help---
7731 +         Say Y here if your platform support s5k4e1 motor.
7732 +
7733 +         To compile this driver as a module, choose M here: the
7734 +         module will be called mrstov2650.ko.
7735 diff --git a/drivers/media/video/mrstci/mrsts5k4e1_motor/Makefile b/drivers/media/video/mrstci/mrsts5k4e1_motor/Makefile
7736 new file mode 100644
7737 index 0000000..68c9fbc
7738 --- /dev/null
7739 +++ b/drivers/media/video/mrstci/mrsts5k4e1_motor/Makefile
7740 @@ -0,0 +1,3 @@
7741 +obj-$(CONFIG_VIDEO_MRST_S5K4E1_MOTOR)   += mrsts5k4e1_motor.o
7742 +
7743 +EXTRA_CFLAGS   +=      -I$(src)/../include
7744 diff --git a/drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.c b/drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.c
7745 new file mode 100644
7746 index 0000000..cd2813b
7747 --- /dev/null
7748 +++ b/drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.c
7749 @@ -0,0 +1,430 @@
7750 +/*
7751 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
7752 + *
7753 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
7754 + *
7755 + * This program is free software; you can redistribute it and/or
7756 + * modify it under the terms of the GNU General Public License version
7757 + * 2 as published by the Free Software Foundation.
7758 + *
7759 + * This program is distributed in the hope that it will be useful,
7760 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7761 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7762 + * GNU General Public License for more details.
7763 + *
7764 + * You should have received a copy of the GNU General Public License
7765 + * along with this program; if not, write to the Free Software
7766 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
7767 + * 02110-1301, USA.
7768 + *
7769 + *
7770 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
7771 + */
7772 +
7773 +#include <linux/module.h>
7774 +#include <linux/types.h>
7775 +#include <linux/kernel.h>
7776 +#include <linux/mm.h>
7777 +#include <linux/string.h>
7778 +#include <linux/errno.h>
7779 +#include <linux/init.h>
7780 +#include <linux/kmod.h>
7781 +#include <linux/device.h>
7782 +#include <linux/delay.h>
7783 +#include <linux/fs.h>
7784 +#include <linux/slab.h>
7785 +#include <linux/delay.h>
7786 +#include <linux/i2c.h>
7787 +#include <linux/gpio.h>
7788 +
7789 +#include <media/v4l2-device.h>
7790 +#include <media/v4l2-chip-ident.h>
7791 +#include <media/v4l2-i2c-drv.h>
7792 +
7793 +#include "mrsts5k4e1_motor.h"
7794 +
7795 +static int s5k4e1_motor_debug;
7796 +module_param(s5k4e1_motor_debug, int, 0644);
7797 +MODULE_PARM_DESC(s5k4e1_motor_debug, "Debug level (0-1)");
7798 +
7799 +#define dprintk(level, fmt, arg...) \
7800 +    do {                       \
7801 +       if (s5k4e1_motor_debug >= level) \
7802 +               printk(KERN_DEBUG "mrstisp@%s: " fmt "\n", __func__, ## arg); \
7803 +    } while (0)
7804 +
7805 +#define eprintk(fmt, arg...)   \
7806 +       printk(KERN_ERR "mrstisp@%s: line %d: " fmt "\n",       \
7807 +              __func__, __LINE__, ## arg);
7808 +
7809 +#define DBG_entering   dprintk(1, "entering");
7810 +#define DBG_leaving    dprintk(1, "leaving");
7811 +#define DBG_line       dprintk(1, " line: %d", __LINE__);
7812 +
7813 +static inline struct s5k4e1_motor *to_motor_config(struct v4l2_subdev *sd)
7814 +{
7815 +       return container_of(sd, struct s5k4e1_motor, sd);
7816 +}
7817 +
7818 +/*static struct s5k4e1_motor *config; */
7819 +static int motor_read(struct i2c_client *c, u32 *reg)
7820 +{
7821 +       int ret;
7822 +       struct i2c_msg msg;
7823 +       u8 msgbuf[3];
7824 +
7825 +       msgbuf[0] = 0;
7826 +       msgbuf[1] = 0;
7827 +       msgbuf[2] = 0;
7828 +
7829 +       memset(&msg, 0, sizeof(msg));
7830 +       msg.addr = c->addr;
7831 +       msg.buf = msgbuf;
7832 +       msg.len = 3;
7833 +       msg.flags = I2C_M_RD;
7834 +
7835 +       ret = i2c_transfer(c->adapter, &msg, 1);
7836 +
7837 +       *reg = (msgbuf[0] << 16 | msgbuf[1] << 8 | msgbuf[2]);
7838 +
7839 +       ret = (ret == 1) ? 0 : -1;
7840 +       return ret;
7841 +}
7842 +
7843 +static int motor_write(struct i2c_client *c, u32 reg)
7844 +{
7845 +       int ret;
7846 +       struct i2c_msg msg;
7847 +       u8 msgbuf[3];
7848 +
7849 +       memset(&msg, 0, sizeof(msg));
7850 +       msgbuf[0] = (reg & 0x00FFFFFFFF) >> 16;
7851 +       msgbuf[1] = (reg & 0x0000FFFF) >> 8 ;
7852 +       msgbuf[2] = reg;
7853 +
7854 +       msg.addr = c->addr;
7855 +       msg.flags = 0;
7856 +       msg.buf = msgbuf;
7857 +       msg.len = 3;
7858 +
7859 +       ret = i2c_transfer(c->adapter, &msg, 1);
7860 +
7861 +       ret = (ret == 1) ? 0 : -1;
7862 +       return ret;
7863 +}
7864 +
7865 +static int s5k4e1_motor_goto_position(struct i2c_client *c,
7866 +                                     unsigned short code,
7867 +                                     struct s5k4e1_motor *config,
7868 +                                     unsigned int step)
7869 +{
7870 +       int max_code, min_code;
7871 +       int timeout = 25; /*TODO: check the timeout time */
7872 +       u8 cmdh, cmdl, finished;
7873 +       u32 cmd = 0, val = 0;
7874 +
7875 +       max_code = config->macro_code;
7876 +       min_code = config->infin_code;
7877 +
7878 +       if (code > max_code)
7879 +               code = max_code;
7880 +       if (code < min_code)
7881 +               code = min_code;
7882 +
7883 +       cmdh = MOTOR_DAC_CTRL_MODE_1 | (code >> 8); /* PS EN x x M W TD9 TD8*/
7884 +       cmdl = code; /* TD7 ~ TD0 */
7885 +       cmd |= (cmdh << 16) | (cmdl << 8);
7886 +
7887 +       dprintk(1, "cmdh: %x, cmdl: %x, cmd: %x", cmdh, cmdl, cmd);
7888 +       dprintk(1, "DAC code: %x", code);
7889 +
7890 +       motor_write(c, cmd);
7891 +       finished = 0;
7892 +       while ((!finished) && timeout--) {
7893 +               msleep(1);
7894 +               motor_read(c, &val);
7895 +               cmdh = val >> 16;
7896 +               cmdl = val >> 8;
7897 +
7898 +               dprintk(1, "cmdh & MOTOR_F = %x", cmdh & MOTOR_F);
7899 +               finished = cmdh & MOTOR_F;
7900 +               finished = (finished) ? 0 : 1;
7901 +       };
7902 +
7903 +       if (finished) {
7904 +               dprintk(1, "Moving from code %x to code %x takes %d ms.",
7905 +                      config->cur_code, code, 25-timeout);
7906 +               return 0;
7907 +       } else {
7908 +               eprintk("Unable to move motor to step %d, TIMEOUT!!", step);
7909 +               return -1;
7910 +       }
7911 +
7912 +}
7913 +
7914 +int s5k4e1_motor_wakeup(struct i2c_client *client)
7915 +{
7916 +       /* hardware wakeup: set PS = 1 */
7917 +       return motor_write(client, 0xC00000);
7918 +}
7919 +
7920 +int s5k4e1_motor_standby(struct i2c_client *client)
7921 +{
7922 +       /* hardware standby: set PS = 0 */
7923 +       return motor_write(client, 0x400000);
7924 +}
7925 +
7926 +int s5k4e1_motor_init(struct i2c_client *client, struct s5k4e1_motor *config)
7927 +{
7928 +
7929 +       int ret;
7930 +       int infin_cur, macro_cur;
7931 +       int step_res, step_time;
7932 +       int val;
7933 +
7934 +       DBG_entering;
7935 +       infin_cur = MAX(MOTOR_INFIN_CUR, MOTOR_DAC_MIN_CUR);
7936 +       macro_cur = MIN(MOTOR_MACRO_CUR, MOTOR_DAC_MAX_CUR);
7937 +       step_res = 1 << MOTOR_STEP_SHIFT;
7938 +       step_time = MOTOR_STEP_TIME;
7939 +
7940 +       /*config->motor = client;*/
7941 +       config->infin_cur = infin_cur;
7942 +       config->macro_cur = macro_cur;
7943 +
7944 +       config->infin_code = MOTOR_INFIN_CODE;
7945 +       config->macro_code = MOTOR_MACRO_CODE;
7946 +
7947 +       config->max_step = ((config->macro_code - config->infin_code)
7948 +                           >> MOTOR_STEP_SHIFT) + 1;
7949 +       config->step_res = step_res;
7950 +       config->step_time = step_time;
7951 +
7952 +       dprintk(1, "max_step: %d, step_res: %d, step_time: %d",
7953 +               config->max_step, step_res, step_time);
7954 +
7955 +       /* Set motor step time and resolution */
7956 +       val = (MOTOR_DAC_CTRL_MODE_0 << 16) | (step_res << 8) | step_time;
7957 +       ret = motor_write(client, val);
7958 +
7959 +       /* Note here, maybe macro_code */
7960 +       ret |= s5k4e1_motor_goto_position(client, config->infin_code,
7961 +                                         config, 0);
7962 +       if (!ret) {
7963 +               config->cur_code = config->infin_code;
7964 +               dprintk(1, "Motor initialization success!");
7965 +       } else
7966 +               eprintk("Error while initializing motor!!!");
7967 +
7968 +       return ret;
7969 +}
7970 +
7971 +int s5k4e1_motor_set_focus(struct i2c_client *c,
7972 +                          unsigned int step,
7973 +                          struct s5k4e1_motor *config)
7974 +{
7975 +       int s_code, ret;
7976 +       int max_step = config->max_step;
7977 +       unsigned int val = step;
7978 +
7979 +       if (val > max_step)
7980 +               val = max_step;
7981 +
7982 +       s_code = (val << MOTOR_STEP_SHIFT);
7983 +       s_code += config->infin_code;
7984 +
7985 +       ret = s5k4e1_motor_goto_position(c, s_code, config, step);
7986 +       if (!ret)
7987 +               config->cur_code = s_code;
7988 +
7989 +       return ret;
7990 +}
7991 +
7992 +static int s5k4e1_motor_g_ctrl(struct v4l2_subdev *sd,
7993 +                              struct v4l2_control *ctrl)
7994 +{
7995 +       struct i2c_client *c = v4l2_get_subdevdata(sd);
7996 +       struct s5k4e1_motor *config = to_motor_config(sd);
7997 +       int ret;
7998 +
7999 +       DBG_entering;
8000 +       ret = s5k4e1_motor_get_focus(c, &ctrl->value, config);
8001 +       if (ret) {
8002 +               eprintk("error call s5k4e1_motor_get_focue");
8003 +               return ret;
8004 +       }
8005 +       DBG_leaving;
8006 +       return 0;
8007 +}
8008 +
8009 +static int s5k4e1_motor_s_ctrl(struct v4l2_subdev *sd,
8010 +                              struct v4l2_control *ctrl)
8011 +{
8012 +       struct i2c_client *c = v4l2_get_subdevdata(sd);
8013 +       struct s5k4e1_motor *config = to_motor_config(sd);
8014 +       int ret;
8015 +
8016 +       DBG_entering;
8017 +       ret = s5k4e1_motor_set_focus(c, ctrl->value, config);
8018 +       if (ret) {
8019 +               eprintk("error call s5k4e1_motor_set_focue");
8020 +               return ret;
8021 +       }
8022 +       DBG_leaving;
8023 +       return 0;
8024 +}
8025 +
8026 +int s5k4e1_motor_get_focus(struct i2c_client *c,
8027 +                          unsigned int *step,
8028 +                          struct s5k4e1_motor *config)
8029 +{
8030 +       int ret_step;
8031 +
8032 +       ret_step = ((config->cur_code - config->infin_code)
8033 +                   >> MOTOR_STEP_SHIFT);
8034 +
8035 +       if (ret_step <= config->max_step)
8036 +               *step = ret_step;
8037 +       else
8038 +               *step = config->max_step;
8039 +
8040 +       return 0;
8041 +}
8042 +
8043 +int s5k4e1_motor_max_step(struct i2c_client *c,
8044 +                         unsigned int *max_code,
8045 +                         struct s5k4e1_motor *config)
8046 +{
8047 +       if (config->max_step != 0)
8048 +               *max_code = config->max_step;
8049 +       return 0;
8050 +
8051 +}
8052 +
8053 +static int s5k4e1_motor_queryctrl(struct v4l2_subdev *sd,
8054 +                           struct v4l2_queryctrl *qc)
8055 +{
8056 +       struct s5k4e1_motor *config = to_motor_config(sd);
8057 +
8058 +       DBG_entering;
8059 +       dprintk(1, "got focus range of %d", config->max_step);
8060 +       if (config->max_step != 0)
8061 +               qc->maximum = config->max_step;
8062 +       DBG_leaving;
8063 +       return 0;
8064 +}
8065 +
8066 +static const struct v4l2_subdev_core_ops s5k4e1_motor_core_ops = {
8067 +       .g_ctrl = s5k4e1_motor_g_ctrl,
8068 +       .s_ctrl = s5k4e1_motor_s_ctrl,
8069 +       .queryctrl = s5k4e1_motor_queryctrl,
8070 +};
8071 +
8072 +static const struct v4l2_subdev_ops s5k4e1_motor_ops = {
8073 +       .core = &s5k4e1_motor_core_ops,
8074 +};
8075 +
8076 +static int s5k4e1_motor_detect(struct i2c_client *client)
8077 +{
8078 +       struct i2c_adapter *adapter = client->adapter;
8079 +       int adap_id = i2c_adapter_id(adapter);
8080 +
8081 +       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
8082 +               eprintk("error i2c check func");
8083 +               return -ENODEV;
8084 +       }
8085 +
8086 +       if (adap_id != 1) {
8087 +               eprintk("adap_id != 1");
8088 +               return -ENODEV;
8089 +       }
8090 +
8091 +       if (s5k4e1_motor_wakeup(client))
8092 +               eprintk("unable to wakeup s5k4e1 motor.");
8093 +
8094 +       return 0;
8095 +}
8096 +
8097 +static int s5k4e1_motor_probe(struct i2c_client *client,
8098 +                       const struct i2c_device_id *id)
8099 +{
8100 +       struct s5k4e1_motor *info;
8101 +       struct v4l2_subdev *sd;
8102 +       int ret = -1;
8103 +/*     struct i2c_client *motor; */
8104 +
8105 +       DBG_entering;
8106 +       v4l_info(client, "chip found @ 0x%x (%s)\n",
8107 +                client->addr << 1, client->adapter->name);
8108 +       /*
8109 +        * Setup sensor configuration structure
8110 +        */
8111 +       info = kzalloc(sizeof(struct s5k4e1_motor), GFP_KERNEL);
8112 +       if (!info) {
8113 +               eprintk("fail to malloc for ci_motor");
8114 +               ret = -ENOMEM;
8115 +               goto out;
8116 +       }
8117 +
8118 +       ret = s5k4e1_motor_detect(client);
8119 +       if (ret) {
8120 +               eprintk("error s5k4e1_motor_detect");
8121 +               goto out_free;
8122 +       }
8123 +
8124 +       sd = &info->sd;
8125 +       v4l2_i2c_subdev_init(sd, client, &s5k4e1_motor_ops);
8126 +
8127 +       /*
8128 +        * Initialization S5K4E1
8129 +        * then turn into standby mode
8130 +        */
8131 +       ret = s5k4e1_motor_init(client, info);
8132 +       if (ret) {
8133 +               eprintk("error calling s5k4e1_motor_init");
8134 +               goto out_free;
8135 +       }
8136 +
8137 +       ret = 0;
8138 +       goto out;
8139 +
8140 +out_free:
8141 +       kfree(info);
8142 +       DBG_leaving;
8143 +out:
8144 +       return ret;
8145 +}
8146 +
8147 +/*
8148 + * XXX: Need to be checked
8149 + */
8150 +static int s5k4e1_motor_remove(struct i2c_client *client)
8151 +{
8152 +       struct v4l2_subdev *sd = i2c_get_clientdata(client);
8153 +
8154 +       DBG_entering;
8155 +
8156 +       v4l2_device_unregister_subdev(sd);
8157 +       kfree(to_motor_config(sd));
8158 +
8159 +       DBG_leaving;
8160 +       return 0;
8161 +}
8162 +
8163 +static const struct i2c_device_id s5k4e1_motor_id[] = {
8164 +       {"s5k4e1_motor", 0},
8165 +       {}
8166 +};
8167 +MODULE_DEVICE_TABLE(i2c, s5k4e1_motor_id);
8168 +
8169 +static struct v4l2_i2c_driver_data v4l2_i2c_data = {
8170 +       .name = "s5k4e1_motor",
8171 +       .probe = s5k4e1_motor_probe,
8172 +       .remove = s5k4e1_motor_remove,
8173 +       /* .suspend = ov5630_suspend,
8174 +        * .resume = ov5630_resume, */
8175 +       .id_table = s5k4e1_motor_id,
8176 +};
8177 +MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
8178 +MODULE_DESCRIPTION("A low-level driver for Samsung S5K4E1 sensor motor");
8179 +MODULE_LICENSE("GPL");
8180 diff --git a/drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.h b/drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.h
8181 new file mode 100644
8182 index 0000000..04f9436
8183 --- /dev/null
8184 +++ b/drivers/media/video/mrstci/mrsts5k4e1_motor/mrsts5k4e1_motor.h
8185 @@ -0,0 +1,102 @@
8186 +/*
8187 + * Support for Moorestown Langwell Camera Imaging ISP subsystem.
8188 + *
8189 + * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
8190 + *
8191 + * This program is free software; you can redistribute it and/or
8192 + * modify it under the terms of the GNU General Public License version
8193 + * 2 as published by the Free Software Foundation.
8194 + *
8195 + * This program is distributed in the hope that it will be useful,
8196 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8197 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8198 + * GNU General Public License for more details.
8199 + *
8200 + * You should have received a copy of the GNU General Public License
8201 + * along with this program; if not, write to the Free Software
8202 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
8203 + * 02110-1301, USA.
8204 + *
8205 + *
8206 + * Xiaolin Zhang <xiaolin.zhang@intel.com>
8207 + */
8208 +
8209 +#include <media/v4l2-subdev.h>
8210 +
8211 +/* DAC output max current (mA) */
8212 +#define MOTOR_DAC_MAX_CUR      125
8213 +/* DAC output min current (mA) */
8214 +#define MOTOR_DAC_MIN_CUR      1
8215 +/* DAC max code (Hex) */
8216 +#define MOTOR_DAC_CODE_MAX     0x3FF
8217 +/* DAC min code (Hex) */
8218 +#define MOTOR_DAC_CODE_MIN     0x0
8219 +
8220 +/* VCM start code (Hex) */
8221 +#define MOTOR_INFIN_CODE       0x120
8222 +/* VCM stop code (Hex) */
8223 +#define MOTOR_MACRO_CODE       0x205
8224 +
8225 +#define MOTOR_STEP_SHIFT       4       /* Step res = 2^4 = 10H */
8226 +#define MOTOR_STEP_TIME                20      /* Step time = 50us x 20d = 1ms */
8227 +
8228 +/* VCM start current (mA) */
8229 +#define MOTOR_INFIN_CUR                ((MOTOR_DAC_MAX_CUR / MOTOR_DAC_CODE_MAX) \
8230 +                                * MOTOR_INFIN_CODE + 1)
8231 +/* VCM max current for Macro (mA) */
8232 +#define MOTOR_MACRO_CUR                ((MOTOR_DAC_MAX_CUR / MOTOR_DAC_CODE_MAX) \
8233 +                                * MOTOR_MACRO_CODE + 1)
8234 +
8235 +
8236 +#define MOTOR_DAC_BIT_RES      10
8237 +#define MOTOR_DAC_MAX_CODE     ((1 << MOTOR_DAC_BIT_RES) - 1)
8238 +
8239 +#define MOTOR_STEP_SHIFT       4
8240 +
8241 +#define MAX(x, y)      ((x) > (y) ? (x) : (y))
8242 +#define MIN(x, y)      ((x) < (y) ? (x) : (y))
8243 +
8244 +/* DAC register related define */
8245 +#define MOTOR_PS       (1 << 7) /* power save */
8246 +#define MOTOR_EN       (1 << 6) /* out pin status*/
8247 +#define MOTOR_M                (1 << 3) /* mode select */
8248 +#define MOTOR_W                (1 << 2) /* register address */
8249 +#define MOTOR_F                (1 << 4) /* finish flag */
8250 +
8251 +#define MOTOR_DAC_CODE_L(x)    (x & 0xff)
8252 +#define MOTOR_DAC_CODE_H(x)    ((x >> 8) & 0xf3)
8253 +
8254 +/* Step mode setting */
8255 +#define MOTOR_DAC_CTRL_MODE_0  0xCC
8256 +/* DAC code setting */
8257 +#define MOTOR_DAC_CTRL_MODE_1  0xC8
8258 +
8259 +#define S5K4E1_MOTOR_ADDR      (0x18 >> 1)
8260 +/*#define POWER_EN_PIN 7*/
8261 +#define GPIO_AF_PD     95
8262 +
8263 +#define DEBUG  0
8264 +
8265 +struct s5k4e1_motor{
8266 +       /*struct i2c_client *motor;*/
8267 +       unsigned int infin_cur;
8268 +       unsigned int infin_code;
8269 +       unsigned int macro_cur;
8270 +       unsigned int macro_code;
8271 +       unsigned int max_step;
8272 +       unsigned int cur_code;
8273 +       unsigned int step_res;
8274 +       unsigned int step_time;
8275 +       struct v4l2_subdev sd;
8276 +};
8277 +
8278 +extern int s5k4e1_motor_init(struct i2c_client *client,
8279 +                            struct s5k4e1_motor *config);
8280 +extern int s5k4e1_motor_standby(struct i2c_client *client);
8281 +extern int s5k4e1_motor_wakeup(struct i2c_client *client);
8282 +extern int s5k4e1_motor_set_focus(struct i2c_client *c, unsigned int step,
8283 +                                 struct s5k4e1_motor *config);
8284 +extern int s5k4e1_motor_get_focus(struct i2c_client *c, unsigned int *step,
8285 +                                 struct s5k4e1_motor *config);
8286 +extern int s5k4e1_motor_max_step(struct i2c_client *c, unsigned int *max_code,
8287 +                                struct s5k4e1_motor *config);
8288 -- 
8289 1.6.0.6
8290