d2cdbffc26beae875ddf8e12b816149367ec7f95
[openembedded.git] /
1 From f4b417bf9b373e042f6cfb921bc67dd18d0a752f Mon Sep 17 00:00:00 2001
2 From: Sergio Aguirre <saaguirre@ti.com>
3 Date: Thu, 1 Jul 2010 07:26:38 -0500
4 Subject: [PATCH 51/75] mt9t112: Migrate from soc_camera to v4l2-int-device
5
6 This is to use the driver with the old OMAP3 Camera-ISP platform.
7
8 Signed-off-by: Sergio Aguirre <saaguirre@ti.com>
9 ---
10  drivers/media/video/Kconfig   |   12 +-
11  drivers/media/video/Makefile  |    2 +-
12  drivers/media/video/mt9t112.c |  658 +++++++++++++++++++++++------------------
13  include/media/mt9t112.h       |   13 +
14  4 files changed, 391 insertions(+), 294 deletions(-)
15
16 diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
17 index 7caade9..4c1fb0f 100644
18 --- a/drivers/media/video/Kconfig
19 +++ b/drivers/media/video/Kconfig
20 @@ -354,6 +354,12 @@ config VIDEO_MT9P012
21           MT9P012 camera.  It is currently working with the TI OMAP3
22           camera controller.
23  
24 +config VIDEO_MT9T112
25 +       tristate "mt9t112 support"
26 +       depends on I2C && VIDEO_V4L2
27 +       help
28 +         This driver supports MT9T112 cameras from Aptina.
29 +
30  config VIDEO_DW9710
31         tristate "Lens driver for DW9710"
32         depends on I2C && VIDEO_V4L2
33 @@ -832,12 +838,6 @@ config SOC_CAMERA_MT9T031
34         help
35           This driver supports MT9T031 cameras from Micron.
36  
37 -config SOC_CAMERA_MT9T112
38 -       tristate "mt9t112 support"
39 -       depends on SOC_CAMERA && I2C
40 -       help
41 -         This driver supports MT9T112 cameras from Aptina.
42 -
43  config SOC_CAMERA_MT9V022
44         tristate "mt9v022 support"
45         depends on SOC_CAMERA && I2C
46 diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
47 index 61ae13f..fb7e46c 100644
48 --- a/drivers/media/video/Makefile
49 +++ b/drivers/media/video/Makefile
50 @@ -80,7 +80,6 @@ obj-$(CONFIG_VIDEO_MT9V113) += mt9v113.o
51  obj-$(CONFIG_SOC_CAMERA_MT9M001)       += mt9m001.o
52  obj-$(CONFIG_SOC_CAMERA_MT9M111)       += mt9m111.o
53  obj-$(CONFIG_SOC_CAMERA_MT9T031)       += mt9t031.o
54 -obj-$(CONFIG_SOC_CAMERA_MT9T112)       += mt9t112.o
55  obj-$(CONFIG_SOC_CAMERA_MT9V022)       += mt9v022.o
56  obj-$(CONFIG_SOC_CAMERA_OV772X)                += ov772x.o
57  obj-$(CONFIG_SOC_CAMERA_OV9640)                += ov9640.o
58 @@ -129,6 +128,7 @@ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
59  obj-y                          += isp/
60  obj-$(CONFIG_VIDEO_OMAP3)      += omap34xxcam.o
61  obj-$(CONFIG_VIDEO_MT9P012)     += mt9p012.o
62 +obj-$(CONFIG_VIDEO_MT9T112)    += mt9t112.o
63  obj-$(CONFIG_VIDEO_DW9710)     += dw9710.o
64  obj-$(CONFIG_VIDEO_TPS61059)    += tps61059.o
65  obj-$(CONFIG_VIDEO_OV3640)     += ov3640.o
66 diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
67 index 7438f8d..6f54394 100644
68 --- a/drivers/media/video/mt9t112.c
69 +++ b/drivers/media/video/mt9t112.c
70 @@ -25,10 +25,8 @@
71  #include <linux/videodev2.h>
72  
73  #include <media/mt9t112.h>
74 -#include <media/soc_camera.h>
75 -#include <media/soc_mediabus.h>
76 +#include <media/v4l2-int-device.h>
77  #include <media/v4l2-chip-ident.h>
78 -#include <media/v4l2-common.h>
79  
80  /* you can check PLL/clock info */
81  /* #define EXT_CLOCK 24000000 */
82 @@ -43,8 +41,8 @@
83  /*
84   * frame size
85   */
86 -#define MAX_WIDTH   2048
87 -#define MAX_HEIGHT  1536
88 +#define MAX_WIDTH   640 /* 2048 */
89 +#define MAX_HEIGHT  480 /* 1536 */
90  
91  #define VGA_WIDTH   640
92  #define VGA_HEIGHT  480
93 @@ -91,20 +89,12 @@ struct mt9t112_frame_size {
94         u16 height;
95  };
96  
97 -struct mt9t112_format {
98 -       enum v4l2_mbus_pixelcode code;
99 -       enum v4l2_colorspace colorspace;
100 -       u16 fmt;
101 -       u16 order;
102 -};
103 -
104  struct mt9t112_priv {
105 -       struct v4l2_subdev               subdev;
106 +       struct mt9t112_platform_data    *pdata;
107 +       struct v4l2_int_device          *v4l2_int_device;
108         struct mt9t112_camera_info      *info;
109         struct i2c_client               *client;
110 -       struct soc_camera_device         icd;
111 -       struct mt9t112_frame_size        frame;
112 -       const struct mt9t112_format     *format;
113 +       struct v4l2_pix_format           pix;
114         int                              model;
115         u32                              flags;
116  /* for flags */
117 @@ -119,38 +109,42 @@ struct mt9t112_priv {
118  
119  ************************************************************************/
120  
121 -static const struct mt9t112_format mt9t112_cfmts[] = {
122 +const static struct v4l2_fmtdesc mt9t112_formats[] = {
123 +       {
124 +               .description    = "YUYV (YUV 4:2:2), packed",
125 +               .pixelformat    = V4L2_PIX_FMT_YUYV,
126 +       },
127         {
128 -               .code           = V4L2_MBUS_FMT_YUYV8_2X8_BE,
129 -               .colorspace     = V4L2_COLORSPACE_JPEG,
130 -               .fmt            = 1,
131 -               .order          = 0,
132 -       }, {
133 -               .code           = V4L2_MBUS_FMT_YVYU8_2X8_BE,
134 -               .colorspace     = V4L2_COLORSPACE_JPEG,
135 -               .fmt            = 1,
136 -               .order          = 1,
137 -       }, {
138 -               .code           = V4L2_MBUS_FMT_YUYV8_2X8_LE,
139 -               .colorspace     = V4L2_COLORSPACE_JPEG,
140 -               .fmt            = 1,
141 -               .order          = 2,
142 -       }, {
143 -               .code           = V4L2_MBUS_FMT_YVYU8_2X8_LE,
144 -               .colorspace     = V4L2_COLORSPACE_JPEG,
145 -               .fmt            = 1,
146 -               .order          = 3,
147 -       }, {
148 -               .code           = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
149 -               .colorspace     = V4L2_COLORSPACE_SRGB,
150 -               .fmt            = 8,
151 -               .order          = 2,
152 -       }, {
153 -               .code           = V4L2_MBUS_FMT_RGB565_2X8_LE,
154 -               .colorspace     = V4L2_COLORSPACE_SRGB,
155 -               .fmt            = 4,
156 -               .order          = 2,
157 +               .description    = "RGB555, le",
158 +               .pixelformat    = V4L2_PIX_FMT_RGB555,
159         },
160 +       {
161 +               .description    = "RGB565, le",
162 +               .pixelformat    = V4L2_PIX_FMT_RGB565,
163 +       },
164 +};
165 +
166 +/************************************************************************
167 +
168 +
169 +                       supported sizes
170 +
171 +
172 +************************************************************************/
173 +const static struct mt9t112_frame_size mt9t112_sizes[] = {
174 +       {  640, 480 },
175 +       /* { 2048, 1536} */
176 +};
177 +
178 +/************************************************************************
179 +
180 +
181 +                       supported sizes
182 +
183 +
184 +************************************************************************/
185 +const struct v4l2_fract mt9t112_frameintervals[] = {
186 +       {  .numerator = 1, .denominator = 10 }
187  };
188  
189  /************************************************************************
190 @@ -160,11 +154,32 @@ static const struct mt9t112_format mt9t112_cfmts[] = {
191  
192  
193  ************************************************************************/
194 -static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
195 +static u16 mt9t112_pixfmt_to_fmt(u32 pixelformat)
196  {
197 -       return container_of(i2c_get_clientdata(client),
198 -                           struct mt9t112_priv,
199 -                           subdev);
200 +       switch (pixelformat) {
201 +       case V4L2_PIX_FMT_RGB555:
202 +               return 8;
203 +       case V4L2_PIX_FMT_RGB565:
204 +               return 4;
205 +       case V4L2_PIX_FMT_YUYV:
206 +               /* FALLTHROUGH */
207 +       default:
208 +               return 1;
209 +       }
210 +}
211 +
212 +static u16 mt9t112_pixfmt_to_order(u32 pixelformat)
213 +{
214 +       switch (pixelformat) {
215 +       case V4L2_PIX_FMT_RGB555:
216 +               /* FALLTHROUGH */
217 +       case V4L2_PIX_FMT_RGB565:
218 +               return 2;
219 +       case V4L2_PIX_FMT_YUYV:
220 +               /* FALLTHROUGH */
221 +       default:
222 +               return 0;
223 +       }
224  }
225  
226  static int __mt9t112_reg_read(const struct i2c_client *client, u16 command)
227 @@ -438,7 +453,7 @@ static int mt9t112_set_pll_dividers(const struct i2c_client *client,
228  
229  static int mt9t112_init_pll(const struct i2c_client *client)
230  {
231 -       struct mt9t112_priv *priv = to_mt9t112(client);
232 +       struct mt9t112_priv *priv = i2c_get_clientdata(client);
233         int data, i, ret;
234  
235         mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001);
236 @@ -757,167 +772,12 @@ static int mt9t112_init_camera(const struct i2c_client *client)
237         return ret;
238  }
239  
240 -/************************************************************************
241 -
242 -
243 -                       soc_camera_ops
244 -
245 -
246 -************************************************************************/
247 -static int mt9t112_set_bus_param(struct soc_camera_device *icd,
248 -                                unsigned long  flags)
249 -{
250 -       return 0;
251 -}
252 -
253 -static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd)
254 -{
255 -       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
256 -       struct mt9t112_priv *priv = to_mt9t112(client);
257 -       struct soc_camera_link *icl = to_soc_camera_link(icd);
258 -       unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH |
259 -               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH;
260 -
261 -       flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ?
262 -               SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING;
263 -
264 -       if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8)
265 -               flags |= SOCAM_DATAWIDTH_8;
266 -       else
267 -               flags |= SOCAM_DATAWIDTH_10;
268 -
269 -       return soc_camera_apply_sensor_flags(icl, flags);
270 -}
271 -
272 -static struct soc_camera_ops mt9t112_ops = {
273 -       .set_bus_param          = mt9t112_set_bus_param,
274 -       .query_bus_param        = mt9t112_query_bus_param,
275 -};
276 -
277 -/************************************************************************
278 -
279 -
280 -                       v4l2_subdev_core_ops
281 -
282 -
283 -************************************************************************/
284 -static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
285 -                               struct v4l2_dbg_chip_ident *id)
286 -{
287 -       struct i2c_client *client = sd->priv;
288 -       struct mt9t112_priv *priv = to_mt9t112(client);
289 -
290 -       id->ident    = priv->model;
291 -       id->revision = 0;
292 -
293 -       return 0;
294 -}
295 -
296 -#ifdef CONFIG_VIDEO_ADV_DEBUG
297 -static int mt9t112_g_register(struct v4l2_subdev *sd,
298 -                             struct v4l2_dbg_register *reg)
299 -{
300 -       struct i2c_client *client = sd->priv;
301 -       int                ret;
302 -
303 -       reg->size = 2;
304 -       mt9t112_reg_read(ret, client, reg->reg);
305 -
306 -       reg->val = (__u64)ret;
307 -
308 -       return 0;
309 -}
310 -
311 -static int mt9t112_s_register(struct v4l2_subdev *sd,
312 -                             struct v4l2_dbg_register *reg)
313 -{
314 -       struct i2c_client *client = sd->priv;
315 -       int ret;
316 -
317 -       mt9t112_reg_write(ret, client, reg->reg, reg->val);
318 -
319 -       return ret;
320 -}
321 -#endif
322 -
323 -static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
324 -       .g_chip_ident   = mt9t112_g_chip_ident,
325 -#ifdef CONFIG_VIDEO_ADV_DEBUG
326 -       .g_register     = mt9t112_g_register,
327 -       .s_register     = mt9t112_s_register,
328 -#endif
329 -};
330 -
331 -
332 -/************************************************************************
333 -
334 -
335 -                       v4l2_subdev_video_ops
336 -
337 -
338 -************************************************************************/
339 -static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
340 -{
341 -       struct i2c_client *client = sd->priv;
342 -       struct mt9t112_priv *priv = to_mt9t112(client);
343 -       int ret = 0;
344 -
345 -       if (!enable) {
346 -               /* FIXME
347 -                *
348 -                * If user selected large output size,
349 -                * and used it long time,
350 -                * mt9t112 camera will be very warm.
351 -                *
352 -                * But current driver can not stop mt9t112 camera.
353 -                * So, set small size here to solve this problem.
354 -                */
355 -               mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
356 -               return ret;
357 -       }
358 -
359 -       if (!(priv->flags & INIT_DONE)) {
360 -               u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE &
361 -                            priv->info->flags) ? 0x0001 : 0x0000;
362 -
363 -               ECHECKER(ret, mt9t112_init_camera(client));
364 -
365 -               /* Invert PCLK (Data sampled on falling edge of pixclk) */
366 -               mt9t112_reg_write(ret, client, 0x3C20, param);
367 -
368 -               mdelay(5);
369 -
370 -               priv->flags |= INIT_DONE;
371 -       }
372 -
373 -       mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
374 -       mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
375 -       mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
376 -
377 -       mt9t112_set_a_frame_size(client,
378 -                                priv->frame.width,
379 -                                priv->frame.height);
380 -
381 -       ECHECKER(ret, mt9t112_auto_focus_trigger(client));
382 -
383 -       dev_dbg(&client->dev, "format : %d\n", priv->format->code);
384 -       dev_dbg(&client->dev, "size   : %d x %d\n",
385 -               priv->frame.width,
386 -               priv->frame.height);
387 -
388 -       CLOCK_INFO(client, EXT_CLOCK);
389 -
390 -       return ret;
391 -}
392 -
393  static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
394 -                             enum v4l2_mbus_pixelcode code)
395 +                             u32 pixelformat)
396  {
397 -       struct mt9t112_priv *priv = to_mt9t112(client);
398 +       struct mt9t112_priv *priv = i2c_get_clientdata(client);
399         int i;
400  
401 -       priv->format = NULL;
402 -
403         /*
404          * frame size check
405          */
406 @@ -926,22 +786,23 @@ static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
407         /*
408          * get color format
409          */
410 -       for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
411 -               if (mt9t112_cfmts[i].code == code)
412 +       for (i = 0; i < ARRAY_SIZE(mt9t112_formats); i++)
413 +               if (mt9t112_formats[i].pixelformat == pixelformat)
414                         break;
415  
416 -       if (i == ARRAY_SIZE(mt9t112_cfmts))
417 +       if (i == ARRAY_SIZE(mt9t112_formats))
418                 return -EINVAL;
419  
420 -       priv->frame.width  = (u16)width;
421 -       priv->frame.height = (u16)height;
422 +       priv->pix.width  = (u16)width;
423 +       priv->pix.height = (u16)height;
424  
425 -       priv->format = mt9t112_cfmts + i;
426 +       priv->pix.pixelformat = pixelformat;
427  
428         return 0;
429  }
430  
431 -static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
432 +static int mt9t112_v4l2_int_cropcap(struct v4l2_int_device *s,
433 +                                   struct v4l2_cropcap *a)
434  {
435         a->bounds.left                  = 0;
436         a->bounds.top                   = 0;
437 @@ -955,7 +816,8 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
438         return 0;
439  }
440  
441 -static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
442 +static int mt9t112_v4l2_int_g_crop(struct v4l2_int_device *s,
443 +                                  struct v4l2_crop *a)
444  {
445         a->c.left       = 0;
446         a->c.top        = 0;
447 @@ -966,77 +828,116 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
448         return 0;
449  }
450  
451 -static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
452 +static int mt9t112_v4l2_int_s_crop(struct v4l2_int_device *s,
453 +                                  struct v4l2_crop *a)
454  {
455 -       struct i2c_client *client = sd->priv;
456 -       struct v4l2_rect *rect = &a->c;
457 -
458 -       return mt9t112_set_params(client, rect->width, rect->height,
459 -                                V4L2_MBUS_FMT_YUYV8_2X8_BE);
460 +       if ((a->c.left != 0) ||
461 +           (a->c.top != 0) ||
462 +           (a->c.width != VGA_WIDTH) ||
463 +           (a->c.height != VGA_HEIGHT)) {
464 +               return -EINVAL;
465 +       }
466 +       return 0;
467  }
468  
469 -static int mt9t112_g_fmt(struct v4l2_subdev *sd,
470 -                        struct v4l2_mbus_framefmt *mf)
471 +static int mt9t112_v4l2_int_g_fmt_cap(struct v4l2_int_device *s,
472 +                                     struct v4l2_format *f)
473  {
474 -       struct i2c_client *client = sd->priv;
475 -       struct mt9t112_priv *priv = to_mt9t112(client);
476 +       struct mt9t112_priv *priv = s->priv;
477 +       struct i2c_client *client = priv->client;
478  
479 -       if (!priv->format) {
480 +       if ((priv->pix.pixelformat == 0) ||
481 +           (priv->pix.width == 0) ||
482 +           (priv->pix.height == 0)) {
483                 int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT,
484 -                                            V4L2_MBUS_FMT_YUYV8_2X8_BE);
485 +                                            V4L2_PIX_FMT_YUYV);
486                 if (ret < 0)
487                         return ret;
488         }
489  
490 -       mf->width       = priv->frame.width;
491 -       mf->height      = priv->frame.height;
492 +       f->fmt.pix.width        = priv->pix.width;
493 +       f->fmt.pix.height       = priv->pix.height;
494         /* TODO: set colorspace */
495 -       mf->code        = priv->format->code;
496 -       mf->field       = V4L2_FIELD_NONE;
497 +       f->fmt.pix.pixelformat  = priv->pix.pixelformat;
498 +       f->fmt.pix.field        = V4L2_FIELD_NONE;
499  
500         return 0;
501  }
502  
503 -static int mt9t112_s_fmt(struct v4l2_subdev *sd,
504 -                        struct v4l2_mbus_framefmt *mf)
505 +
506 +static int mt9t112_v4l2_int_s_fmt_cap(struct v4l2_int_device *s,
507 +                                     struct v4l2_format *f)
508  {
509 -       struct i2c_client *client = sd->priv;
510 +       struct mt9t112_priv *priv = s->priv;
511 +       struct i2c_client *client = priv->client;
512  
513         /* TODO: set colorspace */
514 -       return mt9t112_set_params(client, mf->width, mf->height, mf->code);
515 +       return mt9t112_set_params(client, f->fmt.pix.width, f->fmt.pix.height,
516 +                                 f->fmt.pix.pixelformat);
517  }
518  
519 -static int mt9t112_try_fmt(struct v4l2_subdev *sd,
520 -                          struct v4l2_mbus_framefmt *mf)
521 +static int mt9t112_v4l2_int_try_fmt_cap(struct v4l2_int_device *s,
522 +                                       struct v4l2_format *f)
523  {
524 -       mt9t112_frame_check(&mf->width, &mf->height);
525 +       mt9t112_frame_check(&f->fmt.pix.width, &f->fmt.pix.height);
526  
527         /* TODO: set colorspace */
528 -       mf->field = V4L2_FIELD_NONE;
529 +       f->fmt.pix.field = V4L2_FIELD_NONE;
530  
531         return 0;
532  }
533  
534 -static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index,
535 -                          enum v4l2_mbus_pixelcode *code)
536 +static int mt9t112_v4l2_int_enum_fmt_cap(struct v4l2_int_device *s,
537 +                                        struct v4l2_fmtdesc *fmt)
538  {
539 -       if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts))
540 +       int index = fmt->index;
541 +       enum v4l2_buf_type type = fmt->type;
542 +
543 +       memset(fmt, 0, sizeof(*fmt));
544 +       fmt->index = index;
545 +       fmt->type = type;
546 +
547 +       switch (fmt->type) {
548 +       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
549 +               if (index >= ARRAY_SIZE(mt9t112_formats))
550 +                       return -EINVAL;
551 +       break;
552 +       default:
553                 return -EINVAL;
554 +       }
555  
556 -       *code = mt9t112_cfmts[index].code;
557 +       fmt->flags = mt9t112_formats[index].flags;
558 +       strlcpy(fmt->description, mt9t112_formats[index].description,
559 +                                       sizeof(fmt->description));
560 +       fmt->pixelformat = mt9t112_formats[index].pixelformat;
561         return 0;
562  }
563  
564 -static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
565 -       .s_stream       = mt9t112_s_stream,
566 -       .g_mbus_fmt     = mt9t112_g_fmt,
567 -       .s_mbus_fmt     = mt9t112_s_fmt,
568 -       .try_mbus_fmt   = mt9t112_try_fmt,
569 -       .cropcap        = mt9t112_cropcap,
570 -       .g_crop         = mt9t112_g_crop,
571 -       .s_crop         = mt9t112_s_crop,
572 -       .enum_mbus_fmt  = mt9t112_enum_fmt,
573 -};
574 +static int mt9t112_v4l2_int_s_parm(struct v4l2_int_device *s,
575 +                                  struct v4l2_streamparm *a)
576 +{
577 +       /* TODO: set paramters */
578 +       return 0;
579 +}
580 +
581 +static int mt9t112_v4l2_int_g_parm(struct v4l2_int_device *s,
582 +                                  struct v4l2_streamparm *a)
583 +{
584 +       struct v4l2_captureparm *cparm = &a->parm.capture;
585 +
586 +       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
587 +               return -EINVAL;
588 +
589 +       memset(a, 0, sizeof(*a));
590 +       a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
591 +
592 +       cparm->capability = V4L2_CAP_TIMEPERFRAME;
593 +       /* FIXME: Is 10 fps really the only option? */
594 +       cparm->timeperframe.numerator = 1;
595 +       cparm->timeperframe.denominator = 10;
596 +
597 +       return 0;
598 +}
599  
600  /************************************************************************
601  
602 @@ -1045,27 +946,14 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
603  
604  
605  ************************************************************************/
606 -static struct v4l2_subdev_ops mt9t112_subdev_ops = {
607 -       .core   = &mt9t112_subdev_core_ops,
608 -       .video  = &mt9t112_subdev_video_ops,
609 -};
610  
611 -static int mt9t112_camera_probe(struct soc_camera_device *icd,
612 -                               struct i2c_client *client)
613 +static int mt9t112_detect(struct i2c_client *client)
614  {
615 -       struct mt9t112_priv *priv = to_mt9t112(client);
616 +       struct mt9t112_priv *priv = i2c_get_clientdata(client);
617         const char          *devname;
618         int                  chipid;
619  
620         /*
621 -        * We must have a parent by now. And it cannot be a wrong one.
622 -        * So this entire test is completely redundant.
623 -        */
624 -       if (!icd->dev.parent ||
625 -           to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
626 -               return -ENODEV;
627 -
628 -       /*
629          * check and show chip ID
630          */
631         mt9t112_reg_read(chipid, client, 0x0000);
632 @@ -1089,37 +977,232 @@ static int mt9t112_camera_probe(struct soc_camera_device *icd,
633         return 0;
634  }
635  
636 +static int mt9t112_v4l2_int_s_power(struct v4l2_int_device *s,
637 +                                   enum v4l2_power power)
638 +{
639 +       struct mt9t112_priv *priv = s->priv;
640 +       struct i2c_client *client = priv->client;
641 +       int ret;
642 +
643 +       switch (power) {
644 +       case V4L2_POWER_STANDBY:
645 +               /* FALLTHROUGH */
646 +       case V4L2_POWER_OFF:
647 +               /* FIXME
648 +                *
649 +                * If user selected large output size,
650 +                * and used it long time,
651 +                * mt9t112 camera will be very warm.
652 +                *
653 +                * But current driver can not stop mt9t112 camera.
654 +                * So, set small size here to solve this problem.
655 +                */
656 +               mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
657 +
658 +               ret = priv->pdata->power_set(s, power);
659 +               if (ret < 0) {
660 +                       dev_err(&client->dev, "Unable to set target board power "
661 +                                        "state (OFF/STANDBY)\n");
662 +                       return ret;
663 +               }
664 +               break;
665 +       case V4L2_POWER_ON:
666 +               ret = priv->pdata->power_set(s, power);
667 +               if (ret < 0) {
668 +                       dev_err(&client->dev, "Unable to set target board power "
669 +                                        "state (ON)\n");
670 +                       return ret;
671 +               }
672 +               if (!(priv->flags & INIT_DONE)) {
673 +                       u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE &
674 +                                    priv->info->flags) ? 0x0001 : 0x0000;
675 +
676 +                       ECHECKER(ret, mt9t112_detect(client));
677 +                       ECHECKER(ret, mt9t112_init_camera(client));
678 +
679 +                       /* Invert PCLK (Data sampled on falling edge of pixclk) */
680 +                       mt9t112_reg_write(ret, client, 0x3C20, param);
681 +
682 +                       mdelay(5);
683 +
684 +                       priv->flags |= INIT_DONE;
685 +               }
686 +
687 +               mt9t112_mcu_write(ret, client, VAR(26, 7),
688 +                                 mt9t112_pixfmt_to_fmt(priv->pix.pixelformat));
689 +               mt9t112_mcu_write(ret, client, VAR(26, 9),
690 +                                 mt9t112_pixfmt_to_order(priv->pix.pixelformat));
691 +               mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
692 +
693 +               mt9t112_set_a_frame_size(client,
694 +                                        priv->pix.width,
695 +                                        priv->pix.height);
696 +
697 +               ECHECKER(ret, mt9t112_auto_focus_trigger(client));
698 +
699 +               dev_dbg(&client->dev, "format : %d\n", priv->pix.pixelformat);
700 +               dev_dbg(&client->dev, "size   : %d x %d\n",
701 +                       priv->pix.width,
702 +                       priv->pix.height);
703 +
704 +               CLOCK_INFO(client, EXT_CLOCK);
705 +       }
706 +       return 0;
707 +}
708 +
709 +static int mt9t112_v4l2_int_g_priv(struct v4l2_int_device *s, void *p)
710 +{
711 +       struct mt9t112_priv *priv = s->priv;
712 +
713 +       return priv->pdata->priv_data_set(p);
714 +}
715 +
716 +static int mt9t112_v4l2_int_g_ifparm(struct v4l2_int_device *s,
717 +                                    struct v4l2_ifparm *p)
718 +{
719 +       struct mt9t112_priv *priv = s->priv;
720 +       int rval;
721 +
722 +       if (p == NULL)
723 +               return -EINVAL;
724 +
725 +       if (!priv->pdata->ifparm)
726 +               return -EINVAL;
727 +
728 +       rval = priv->pdata->ifparm(p);
729 +       if (rval) {
730 +               v4l_err(priv->client, "g_ifparm.Err[%d]\n", rval);
731 +               return rval;
732 +       }
733 +
734 +       p->u.ycbcr.clock_curr = 40 * 1000000; /* temporal value */
735 +
736 +       return 0;
737 +}
738 +
739 +static int mt9t112_v4l2_int_enum_framesizes(struct v4l2_int_device *s,
740 +                                           struct v4l2_frmsizeenum *frms)
741 +{
742 +       int ifmt;
743 +
744 +       for (ifmt = 0; ifmt < ARRAY_SIZE(mt9t112_formats); ifmt++)
745 +               if (mt9t112_formats[ifmt].pixelformat == frms->pixel_format)
746 +                       break;
747 +
748 +       if (ifmt == ARRAY_SIZE(mt9t112_formats))
749 +               return -EINVAL;
750 +
751 +       /* Do we already reached all discrete framesizes? */
752 +       if (frms->index >= ARRAY_SIZE(mt9t112_sizes))
753 +               return -EINVAL;
754 +
755 +       frms->type = V4L2_FRMSIZE_TYPE_DISCRETE;
756 +       frms->discrete.width = mt9t112_sizes[frms->index].width;
757 +       frms->discrete.height = mt9t112_sizes[frms->index].height;
758 +
759 +       return 0;
760 +
761 +}
762 +
763 +static int mt9t112_v4l2_int_enum_frameintervals(struct v4l2_int_device *s,
764 +                                               struct v4l2_frmivalenum *frmi)
765 +{
766 +       int ifmt;
767 +
768 +       for (ifmt = 0; ifmt < ARRAY_SIZE(mt9t112_formats); ifmt++)
769 +               if (mt9t112_formats[ifmt].pixelformat == frmi->pixel_format)
770 +                       break;
771 +
772 +       if (ifmt == ARRAY_SIZE(mt9t112_formats))
773 +               return -EINVAL;
774 +
775 +       if (frmi->index >= ARRAY_SIZE(mt9t112_frameintervals))
776 +               return -EINVAL;
777 +
778 +       frmi->type = V4L2_FRMSIZE_TYPE_DISCRETE;
779 +       frmi->discrete.numerator =
780 +                               mt9t112_frameintervals[frmi->index].numerator;
781 +       frmi->discrete.denominator =
782 +                               mt9t112_frameintervals[frmi->index].denominator;
783 +       return 0;
784 +}
785 +
786 +static struct v4l2_int_ioctl_desc mt9t112_ioctl_desc[] = {
787 +       { .num = vidioc_int_enum_framesizes_num,
788 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_enum_framesizes },
789 +       { .num = vidioc_int_enum_frameintervals_num,
790 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_enum_frameintervals },
791 +       { .num = vidioc_int_s_power_num,
792 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_s_power },
793 +       { .num = vidioc_int_g_priv_num,
794 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_g_priv },
795 +       { .num = vidioc_int_g_ifparm_num,
796 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_g_ifparm },
797 +       { .num = vidioc_int_enum_fmt_cap_num,
798 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_enum_fmt_cap },
799 +       { .num = vidioc_int_try_fmt_cap_num,
800 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_try_fmt_cap },
801 +       { .num = vidioc_int_g_fmt_cap_num,
802 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_g_fmt_cap },
803 +       { .num = vidioc_int_s_fmt_cap_num,
804 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_s_fmt_cap },
805 +       { .num = vidioc_int_g_parm_num,
806 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_g_parm },
807 +       { .num = vidioc_int_s_parm_num,
808 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_s_parm },
809 +       { .num = vidioc_int_cropcap_num,
810 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_cropcap },
811 +       { .num = vidioc_int_g_crop_num,
812 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_g_crop },
813 +       { .num = vidioc_int_s_crop_num,
814 +         .func = (v4l2_int_ioctl_func *)mt9t112_v4l2_int_s_crop },
815 +};
816 +
817 +static struct v4l2_int_slave mt9t112_slave = {
818 +       .ioctls = mt9t112_ioctl_desc,
819 +       .num_ioctls = ARRAY_SIZE(mt9t112_ioctl_desc),
820 +};
821 +
822  static int mt9t112_probe(struct i2c_client *client,
823                          const struct i2c_device_id *did)
824  {
825         struct mt9t112_priv        *priv;
826 -       struct soc_camera_device   *icd = client->dev.platform_data;
827 -       struct soc_camera_link     *icl;
828 +       struct v4l2_int_device     *v4l2_int_device;
829         int                         ret;
830  
831 -       if (!icd) {
832 -               dev_err(&client->dev, "mt9t112: missing soc-camera data!\n");
833 -               return -EINVAL;
834 +       if (!client->dev.platform_data) {
835 +               dev_err(&client->dev, "no platform data?\n");
836 +               return -ENODEV;
837         }
838  
839 -       icl = to_soc_camera_link(icd);
840 -       if (!icl || !icl->priv)
841 -               return -EINVAL;
842 -
843         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
844         if (!priv)
845                 return -ENOMEM;
846  
847 -       priv->info = icl->priv;
848 +       v4l2_int_device = kzalloc(sizeof(*v4l2_int_device), GFP_KERNEL);
849 +       if (!v4l2_int_device) {
850 +               kfree(priv);
851 +               return -ENOMEM;
852 +       }
853  
854 -       v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
855 +       v4l2_int_device->module = THIS_MODULE;
856 +       strncpy(v4l2_int_device->name, "mt9t112", sizeof(v4l2_int_device->name));
857 +       v4l2_int_device->type = v4l2_int_type_slave;
858 +       v4l2_int_device->u.slave = &mt9t112_slave;
859 +       v4l2_int_device->priv = priv;
860  
861 -       icd->ops = &mt9t112_ops;
862 +       priv->v4l2_int_device = v4l2_int_device;
863 +       priv->client = client;
864 +       priv->pdata = client->dev.platform_data;
865  
866 -       ret = mt9t112_camera_probe(icd, client);
867 +       i2c_set_clientdata(client, priv);
868 +
869 +       //ret = mt9t112_detect(client);
870 +
871 +       ret = v4l2_int_device_register(priv->v4l2_int_device);
872         if (ret) {
873 -               icd->ops = NULL;
874                 i2c_set_clientdata(client, NULL);
875 +               kfree(v4l2_int_device);
876                 kfree(priv);
877         }
878  
879 @@ -1128,11 +1211,12 @@ static int mt9t112_probe(struct i2c_client *client,
880  
881  static int mt9t112_remove(struct i2c_client *client)
882  {
883 -       struct mt9t112_priv *priv = to_mt9t112(client);
884 -       struct soc_camera_device *icd = client->dev.platform_data;
885 +       struct mt9t112_priv *priv = i2c_get_clientdata(client);
886  
887 -       icd->ops = NULL;
888 +       v4l2_int_device_unregister(priv->v4l2_int_device);
889         i2c_set_clientdata(client, NULL);
890 +
891 +       kfree(priv->v4l2_int_device);
892         kfree(priv);
893         return 0;
894  }
895 @@ -1172,6 +1256,6 @@ static void __exit mt9t112_module_exit(void)
896  module_init(mt9t112_module_init);
897  module_exit(mt9t112_module_exit);
898  
899 -MODULE_DESCRIPTION("SoC Camera driver for mt9t112");
900 +MODULE_DESCRIPTION("mt9t112 sensor driver");
901  MODULE_AUTHOR("Kuninori Morimoto");
902  MODULE_LICENSE("GPL v2");
903 diff --git a/include/media/mt9t112.h b/include/media/mt9t112.h
904 index a43c74a..62caaf5 100644
905 --- a/include/media/mt9t112.h
906 +++ b/include/media/mt9t112.h
907 @@ -11,6 +11,8 @@
908  #ifndef __MT9T112_H__
909  #define __MT9T112_H__
910  
911 +#include <media/v4l2-int-device.h>
912 +
913  #define MT9T112_FLAG_PCLK_RISING_EDGE  (1 << 0)
914  #define MT9T112_FLAG_DATAWIDTH_8       (1 << 1) /* default width is 10 */
915  
916 @@ -27,4 +29,15 @@ struct mt9t112_camera_info {
917         struct mt9t112_pll_divider divider;
918  };
919  
920 +struct mt9t112_platform_data {
921 +       char *master;
922 +       int (*power_set) (struct v4l2_int_device *s, enum v4l2_power on);
923 +       int (*ifparm) (struct v4l2_ifparm *p);
924 +       int (*priv_data_set) (void *);
925 +       /* Interface control params */
926 +       bool clk_polarity;
927 +       bool hs_polarity;
928 +       bool vs_polarity;
929 +};
930 +
931  #endif /* __MT9T112_H__ */
932 -- 
933 1.6.6.1
934