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
6 This is to use the driver with the old OMAP3 Camera-ISP platform.
8 Signed-off-by: Sergio Aguirre <saaguirre@ti.com>
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(-)
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
25 + tristate "mt9t112 support"
26 + depends on I2C && VIDEO_V4L2
28 + This driver supports MT9T112 cameras from Aptina.
31 tristate "Lens driver for DW9710"
32 depends on I2C && VIDEO_V4L2
33 @@ -832,12 +838,6 @@ config SOC_CAMERA_MT9T031
35 This driver supports MT9T031 cameras from Micron.
37 -config SOC_CAMERA_MT9T112
38 - tristate "mt9t112 support"
39 - depends on SOC_CAMERA && I2C
41 - This driver supports MT9T112 cameras from Aptina.
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
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
71 #include <linux/videodev2.h>
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>
80 /* you can check PLL/clock info */
81 /* #define EXT_CLOCK 24000000 */
86 -#define MAX_WIDTH 2048
87 -#define MAX_HEIGHT 1536
88 +#define MAX_WIDTH 640 /* 2048 */
89 +#define MAX_HEIGHT 480 /* 1536 */
92 #define VGA_HEIGHT 480
93 @@ -91,20 +89,12 @@ struct mt9t112_frame_size {
97 -struct mt9t112_format {
98 - enum v4l2_mbus_pixelcode code;
99 - enum v4l2_colorspace colorspace;
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;
117 @@ -119,38 +109,42 @@ struct mt9t112_priv {
119 ************************************************************************/
121 -static const struct mt9t112_format mt9t112_cfmts[] = {
122 +const static struct v4l2_fmtdesc mt9t112_formats[] = {
124 + .description = "YUYV (YUV 4:2:2), packed",
125 + .pixelformat = V4L2_PIX_FMT_YUYV,
128 - .code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
129 - .colorspace = V4L2_COLORSPACE_JPEG,
133 - .code = V4L2_MBUS_FMT_YVYU8_2X8_BE,
134 - .colorspace = V4L2_COLORSPACE_JPEG,
138 - .code = V4L2_MBUS_FMT_YUYV8_2X8_LE,
139 - .colorspace = V4L2_COLORSPACE_JPEG,
143 - .code = V4L2_MBUS_FMT_YVYU8_2X8_LE,
144 - .colorspace = V4L2_COLORSPACE_JPEG,
148 - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
149 - .colorspace = V4L2_COLORSPACE_SRGB,
153 - .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
154 - .colorspace = V4L2_COLORSPACE_SRGB,
157 + .description = "RGB555, le",
158 + .pixelformat = V4L2_PIX_FMT_RGB555,
161 + .description = "RGB565, le",
162 + .pixelformat = V4L2_PIX_FMT_RGB565,
166 +/************************************************************************
172 +************************************************************************/
173 +const static struct mt9t112_frame_size mt9t112_sizes[] = {
175 + /* { 2048, 1536} */
178 +/************************************************************************
184 +************************************************************************/
185 +const struct v4l2_fract mt9t112_frameintervals[] = {
186 + { .numerator = 1, .denominator = 10 }
189 /************************************************************************
190 @@ -160,11 +154,32 @@ static const struct mt9t112_format mt9t112_cfmts[] = {
193 ************************************************************************/
194 -static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
195 +static u16 mt9t112_pixfmt_to_fmt(u32 pixelformat)
197 - return container_of(i2c_get_clientdata(client),
198 - struct mt9t112_priv,
200 + switch (pixelformat) {
201 + case V4L2_PIX_FMT_RGB555:
203 + case V4L2_PIX_FMT_RGB565:
205 + case V4L2_PIX_FMT_YUYV:
212 +static u16 mt9t112_pixfmt_to_order(u32 pixelformat)
214 + switch (pixelformat) {
215 + case V4L2_PIX_FMT_RGB555:
217 + case V4L2_PIX_FMT_RGB565:
219 + case V4L2_PIX_FMT_YUYV:
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,
229 static int mt9t112_init_pll(const struct i2c_client *client)
231 - struct mt9t112_priv *priv = to_mt9t112(client);
232 + struct mt9t112_priv *priv = i2c_get_clientdata(client);
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)
240 -/************************************************************************
246 -************************************************************************/
247 -static int mt9t112_set_bus_param(struct soc_camera_device *icd,
248 - unsigned long flags)
253 -static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd)
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;
261 - flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ?
262 - SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING;
264 - if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8)
265 - flags |= SOCAM_DATAWIDTH_8;
267 - flags |= SOCAM_DATAWIDTH_10;
269 - return soc_camera_apply_sensor_flags(icl, flags);
272 -static struct soc_camera_ops mt9t112_ops = {
273 - .set_bus_param = mt9t112_set_bus_param,
274 - .query_bus_param = mt9t112_query_bus_param,
277 -/************************************************************************
280 - v4l2_subdev_core_ops
283 -************************************************************************/
284 -static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
285 - struct v4l2_dbg_chip_ident *id)
287 - struct i2c_client *client = sd->priv;
288 - struct mt9t112_priv *priv = to_mt9t112(client);
290 - id->ident = priv->model;
296 -#ifdef CONFIG_VIDEO_ADV_DEBUG
297 -static int mt9t112_g_register(struct v4l2_subdev *sd,
298 - struct v4l2_dbg_register *reg)
300 - struct i2c_client *client = sd->priv;
304 - mt9t112_reg_read(ret, client, reg->reg);
306 - reg->val = (__u64)ret;
311 -static int mt9t112_s_register(struct v4l2_subdev *sd,
312 - struct v4l2_dbg_register *reg)
314 - struct i2c_client *client = sd->priv;
317 - mt9t112_reg_write(ret, client, reg->reg, reg->val);
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,
332 -/************************************************************************
335 - v4l2_subdev_video_ops
338 -************************************************************************/
339 -static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
341 - struct i2c_client *client = sd->priv;
342 - struct mt9t112_priv *priv = to_mt9t112(client);
348 - * If user selected large output size,
349 - * and used it long time,
350 - * mt9t112 camera will be very warm.
352 - * But current driver can not stop mt9t112 camera.
353 - * So, set small size here to solve this problem.
355 - mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
359 - if (!(priv->flags & INIT_DONE)) {
360 - u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE &
361 - priv->info->flags) ? 0x0001 : 0x0000;
363 - ECHECKER(ret, mt9t112_init_camera(client));
365 - /* Invert PCLK (Data sampled on falling edge of pixclk) */
366 - mt9t112_reg_write(ret, client, 0x3C20, param);
370 - priv->flags |= INIT_DONE;
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);
377 - mt9t112_set_a_frame_size(client,
379 - priv->frame.height);
381 - ECHECKER(ret, mt9t112_auto_focus_trigger(client));
383 - dev_dbg(&client->dev, "format : %d\n", priv->format->code);
384 - dev_dbg(&client->dev, "size : %d x %d\n",
386 - priv->frame.height);
388 - CLOCK_INFO(client, EXT_CLOCK);
393 static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
394 - enum v4l2_mbus_pixelcode code)
397 - struct mt9t112_priv *priv = to_mt9t112(client);
398 + struct mt9t112_priv *priv = i2c_get_clientdata(client);
401 - priv->format = NULL;
406 @@ -926,22 +786,23 @@ static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
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)
416 - if (i == ARRAY_SIZE(mt9t112_cfmts))
417 + if (i == ARRAY_SIZE(mt9t112_formats))
420 - priv->frame.width = (u16)width;
421 - priv->frame.height = (u16)height;
422 + priv->pix.width = (u16)width;
423 + priv->pix.height = (u16)height;
425 - priv->format = mt9t112_cfmts + i;
426 + priv->pix.pixelformat = pixelformat;
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)
437 @@ -955,7 +816,8 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
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)
447 @@ -966,77 +828,116 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
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)
455 - struct i2c_client *client = sd->priv;
456 - struct v4l2_rect *rect = &a->c;
458 - return mt9t112_set_params(client, rect->width, rect->height,
459 - V4L2_MBUS_FMT_YUYV8_2X8_BE);
460 + if ((a->c.left != 0) ||
462 + (a->c.width != VGA_WIDTH) ||
463 + (a->c.height != VGA_HEIGHT)) {
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)
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;
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);
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;
503 -static int mt9t112_s_fmt(struct v4l2_subdev *sd,
504 - struct v4l2_mbus_framefmt *mf)
506 +static int mt9t112_v4l2_int_s_fmt_cap(struct v4l2_int_device *s,
507 + struct v4l2_format *f)
509 - struct i2c_client *client = sd->priv;
510 + struct mt9t112_priv *priv = s->priv;
511 + struct i2c_client *client = priv->client;
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);
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)
524 - mt9t112_frame_check(&mf->width, &mf->height);
525 + mt9t112_frame_check(&f->fmt.pix.width, &f->fmt.pix.height);
527 /* TODO: set colorspace */
528 - mf->field = V4L2_FIELD_NONE;
529 + f->fmt.pix.field = V4L2_FIELD_NONE;
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)
539 - if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts))
540 + int index = fmt->index;
541 + enum v4l2_buf_type type = fmt->type;
543 + memset(fmt, 0, sizeof(*fmt));
544 + fmt->index = index;
547 + switch (fmt->type) {
548 + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
549 + if (index >= ARRAY_SIZE(mt9t112_formats))
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;
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,
574 +static int mt9t112_v4l2_int_s_parm(struct v4l2_int_device *s,
575 + struct v4l2_streamparm *a)
577 + /* TODO: set paramters */
581 +static int mt9t112_v4l2_int_g_parm(struct v4l2_int_device *s,
582 + struct v4l2_streamparm *a)
584 + struct v4l2_captureparm *cparm = &a->parm.capture;
586 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
589 + memset(a, 0, sizeof(*a));
590 + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
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;
600 /************************************************************************
602 @@ -1045,27 +946,14 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
605 ************************************************************************/
606 -static struct v4l2_subdev_ops mt9t112_subdev_ops = {
607 - .core = &mt9t112_subdev_core_ops,
608 - .video = &mt9t112_subdev_video_ops,
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)
615 - struct mt9t112_priv *priv = to_mt9t112(client);
616 + struct mt9t112_priv *priv = i2c_get_clientdata(client);
621 - * We must have a parent by now. And it cannot be a wrong one.
622 - * So this entire test is completely redundant.
624 - if (!icd->dev.parent ||
625 - to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
629 * check and show chip ID
631 mt9t112_reg_read(chipid, client, 0x0000);
632 @@ -1089,37 +977,232 @@ static int mt9t112_camera_probe(struct soc_camera_device *icd,
636 +static int mt9t112_v4l2_int_s_power(struct v4l2_int_device *s,
637 + enum v4l2_power power)
639 + struct mt9t112_priv *priv = s->priv;
640 + struct i2c_client *client = priv->client;
644 + case V4L2_POWER_STANDBY:
646 + case V4L2_POWER_OFF:
649 + * If user selected large output size,
650 + * and used it long time,
651 + * mt9t112 camera will be very warm.
653 + * But current driver can not stop mt9t112 camera.
654 + * So, set small size here to solve this problem.
656 + mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
658 + ret = priv->pdata->power_set(s, power);
660 + dev_err(&client->dev, "Unable to set target board power "
661 + "state (OFF/STANDBY)\n");
665 + case V4L2_POWER_ON:
666 + ret = priv->pdata->power_set(s, power);
668 + dev_err(&client->dev, "Unable to set target board power "
672 + if (!(priv->flags & INIT_DONE)) {
673 + u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE &
674 + priv->info->flags) ? 0x0001 : 0x0000;
676 + ECHECKER(ret, mt9t112_detect(client));
677 + ECHECKER(ret, mt9t112_init_camera(client));
679 + /* Invert PCLK (Data sampled on falling edge of pixclk) */
680 + mt9t112_reg_write(ret, client, 0x3C20, param);
684 + priv->flags |= INIT_DONE;
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);
693 + mt9t112_set_a_frame_size(client,
697 + ECHECKER(ret, mt9t112_auto_focus_trigger(client));
699 + dev_dbg(&client->dev, "format : %d\n", priv->pix.pixelformat);
700 + dev_dbg(&client->dev, "size : %d x %d\n",
704 + CLOCK_INFO(client, EXT_CLOCK);
709 +static int mt9t112_v4l2_int_g_priv(struct v4l2_int_device *s, void *p)
711 + struct mt9t112_priv *priv = s->priv;
713 + return priv->pdata->priv_data_set(p);
716 +static int mt9t112_v4l2_int_g_ifparm(struct v4l2_int_device *s,
717 + struct v4l2_ifparm *p)
719 + struct mt9t112_priv *priv = s->priv;
725 + if (!priv->pdata->ifparm)
728 + rval = priv->pdata->ifparm(p);
730 + v4l_err(priv->client, "g_ifparm.Err[%d]\n", rval);
734 + p->u.ycbcr.clock_curr = 40 * 1000000; /* temporal value */
739 +static int mt9t112_v4l2_int_enum_framesizes(struct v4l2_int_device *s,
740 + struct v4l2_frmsizeenum *frms)
744 + for (ifmt = 0; ifmt < ARRAY_SIZE(mt9t112_formats); ifmt++)
745 + if (mt9t112_formats[ifmt].pixelformat == frms->pixel_format)
748 + if (ifmt == ARRAY_SIZE(mt9t112_formats))
751 + /* Do we already reached all discrete framesizes? */
752 + if (frms->index >= ARRAY_SIZE(mt9t112_sizes))
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;
763 +static int mt9t112_v4l2_int_enum_frameintervals(struct v4l2_int_device *s,
764 + struct v4l2_frmivalenum *frmi)
768 + for (ifmt = 0; ifmt < ARRAY_SIZE(mt9t112_formats); ifmt++)
769 + if (mt9t112_formats[ifmt].pixelformat == frmi->pixel_format)
772 + if (ifmt == ARRAY_SIZE(mt9t112_formats))
775 + if (frmi->index >= ARRAY_SIZE(mt9t112_frameintervals))
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;
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 },
817 +static struct v4l2_int_slave mt9t112_slave = {
818 + .ioctls = mt9t112_ioctl_desc,
819 + .num_ioctls = ARRAY_SIZE(mt9t112_ioctl_desc),
822 static int mt9t112_probe(struct i2c_client *client,
823 const struct i2c_device_id *did)
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;
832 - dev_err(&client->dev, "mt9t112: missing soc-camera data!\n");
834 + if (!client->dev.platform_data) {
835 + dev_err(&client->dev, "no platform data?\n");
839 - icl = to_soc_camera_link(icd);
840 - if (!icl || !icl->priv)
843 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
847 - priv->info = icl->priv;
848 + v4l2_int_device = kzalloc(sizeof(*v4l2_int_device), GFP_KERNEL);
849 + if (!v4l2_int_device) {
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;
861 - icd->ops = &mt9t112_ops;
862 + priv->v4l2_int_device = v4l2_int_device;
863 + priv->client = client;
864 + priv->pdata = client->dev.platform_data;
866 - ret = mt9t112_camera_probe(icd, client);
867 + i2c_set_clientdata(client, priv);
869 + //ret = mt9t112_detect(client);
871 + ret = v4l2_int_device_register(priv->v4l2_int_device);
874 i2c_set_clientdata(client, NULL);
875 + kfree(v4l2_int_device);
879 @@ -1128,11 +1211,12 @@ static int mt9t112_probe(struct i2c_client *client,
881 static int mt9t112_remove(struct i2c_client *client)
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);
888 + v4l2_int_device_unregister(priv->v4l2_int_device);
889 i2c_set_clientdata(client, NULL);
891 + kfree(priv->v4l2_int_device);
895 @@ -1172,6 +1256,6 @@ static void __exit mt9t112_module_exit(void)
896 module_init(mt9t112_module_init);
897 module_exit(mt9t112_module_exit);
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
908 #ifndef __MT9T112_H__
909 #define __MT9T112_H__
911 +#include <media/v4l2-int-device.h>
913 #define MT9T112_FLAG_PCLK_RISING_EDGE (1 << 0)
914 #define MT9T112_FLAG_DATAWIDTH_8 (1 << 1) /* default width is 10 */
916 @@ -27,4 +29,15 @@ struct mt9t112_camera_info {
917 struct mt9t112_pll_divider divider;
920 +struct mt9t112_platform_data {
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 */
931 #endif /* __MT9T112_H__ */