]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/media/video/mt9v022.c
d2b0981ec1c11fbb9e3a2b5deb4c179530f2f1cc
[linux-2.6.git] / drivers / media / video / mt9v022.c
1 /*
2  * Driver for MT9V022 CMOS Image Sensor from Micron
3  *
4  * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/videodev2.h>
12 #include <linux/slab.h>
13 #include <linux/i2c.h>
14 #include <linux/delay.h>
15 #include <linux/log2.h>
16
17 #include <media/v4l2-subdev.h>
18 #include <media/v4l2-chip-ident.h>
19 #include <media/soc_camera.h>
20
21 /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
22  * The platform has to define ctruct i2c_board_info objects and link to them
23  * from struct soc_camera_link */
24
25 static char *sensor_type;
26 module_param(sensor_type, charp, S_IRUGO);
27 MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
28
29 /* mt9v022 selected register addresses */
30 #define MT9V022_CHIP_VERSION            0x00
31 #define MT9V022_COLUMN_START            0x01
32 #define MT9V022_ROW_START               0x02
33 #define MT9V022_WINDOW_HEIGHT           0x03
34 #define MT9V022_WINDOW_WIDTH            0x04
35 #define MT9V022_HORIZONTAL_BLANKING     0x05
36 #define MT9V022_VERTICAL_BLANKING       0x06
37 #define MT9V022_CHIP_CONTROL            0x07
38 #define MT9V022_SHUTTER_WIDTH1          0x08
39 #define MT9V022_SHUTTER_WIDTH2          0x09
40 #define MT9V022_SHUTTER_WIDTH_CTRL      0x0a
41 #define MT9V022_TOTAL_SHUTTER_WIDTH     0x0b
42 #define MT9V022_RESET                   0x0c
43 #define MT9V022_READ_MODE               0x0d
44 #define MT9V022_MONITOR_MODE            0x0e
45 #define MT9V022_PIXEL_OPERATION_MODE    0x0f
46 #define MT9V022_LED_OUT_CONTROL         0x1b
47 #define MT9V022_ADC_MODE_CONTROL        0x1c
48 #define MT9V022_ANALOG_GAIN             0x34
49 #define MT9V022_BLACK_LEVEL_CALIB_CTRL  0x47
50 #define MT9V022_PIXCLK_FV_LV            0x74
51 #define MT9V022_DIGITAL_TEST_PATTERN    0x7f
52 #define MT9V022_AEC_AGC_ENABLE          0xAF
53 #define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
54
55 /* Progressive scan, master, defaults */
56 #define MT9V022_CHIP_CONTROL_DEFAULT    0x188
57
58 static const struct soc_camera_data_format mt9v022_colour_formats[] = {
59         /* Order important: first natively supported,
60          * second supported with a GPIO extender */
61         {
62                 .name           = "Bayer (sRGB) 10 bit",
63                 .depth          = 10,
64                 .fourcc         = V4L2_PIX_FMT_SBGGR16,
65                 .colorspace     = V4L2_COLORSPACE_SRGB,
66         }, {
67                 .name           = "Bayer (sRGB) 8 bit",
68                 .depth          = 8,
69                 .fourcc         = V4L2_PIX_FMT_SBGGR8,
70                 .colorspace     = V4L2_COLORSPACE_SRGB,
71         }
72 };
73
74 static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
75         /* Order important - see above */
76         {
77                 .name           = "Monochrome 10 bit",
78                 .depth          = 10,
79                 .fourcc         = V4L2_PIX_FMT_Y16,
80         }, {
81                 .name           = "Monochrome 8 bit",
82                 .depth          = 8,
83                 .fourcc         = V4L2_PIX_FMT_GREY,
84         },
85 };
86
87 struct mt9v022 {
88         struct v4l2_subdev subdev;
89         int model;      /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
90         u16 chip_control;
91 };
92
93 static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
94 {
95         return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
96 }
97
98 static int reg_read(struct i2c_client *client, const u8 reg)
99 {
100         s32 data = i2c_smbus_read_word_data(client, reg);
101         return data < 0 ? data : swab16(data);
102 }
103
104 static int reg_write(struct i2c_client *client, const u8 reg,
105                      const u16 data)
106 {
107         return i2c_smbus_write_word_data(client, reg, swab16(data));
108 }
109
110 static int reg_set(struct i2c_client *client, const u8 reg,
111                    const u16 data)
112 {
113         int ret;
114
115         ret = reg_read(client, reg);
116         if (ret < 0)
117                 return ret;
118         return reg_write(client, reg, ret | data);
119 }
120
121 static int reg_clear(struct i2c_client *client, const u8 reg,
122                      const u16 data)
123 {
124         int ret;
125
126         ret = reg_read(client, reg);
127         if (ret < 0)
128                 return ret;
129         return reg_write(client, reg, ret & ~data);
130 }
131
132 static int mt9v022_init(struct soc_camera_device *icd)
133 {
134         struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
135         struct mt9v022 *mt9v022 = to_mt9v022(client);
136         int ret;
137
138         /* Almost the default mode: master, parallel, simultaneous, and an
139          * undocumented bit 0x200, which is present in table 7, but not in 8,
140          * plus snapshot mode to disable scan for now */
141         mt9v022->chip_control |= 0x10;
142         ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
143         if (!ret)
144                 ret = reg_write(client, MT9V022_READ_MODE, 0x300);
145
146         /* All defaults */
147         if (!ret)
148                 /* AEC, AGC on */
149                 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
150         if (!ret)
151                 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
152         if (!ret)
153                 /* default - auto */
154                 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
155         if (!ret)
156                 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
157
158         return ret;
159 }
160
161 static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
162 {
163         struct i2c_client *client = sd->priv;
164         struct mt9v022 *mt9v022 = to_mt9v022(client);
165
166         if (enable)
167                 /* Switch to master "normal" mode */
168                 mt9v022->chip_control &= ~0x10;
169         else
170                 /* Switch to snapshot mode */
171                 mt9v022->chip_control |= 0x10;
172
173         if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
174                 return -EIO;
175         return 0;
176 }
177
178 static int mt9v022_set_bus_param(struct soc_camera_device *icd,
179                                  unsigned long flags)
180 {
181         struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
182         struct mt9v022 *mt9v022 = to_mt9v022(client);
183         struct soc_camera_link *icl = to_soc_camera_link(icd);
184         unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
185         int ret;
186         u16 pixclk = 0;
187
188         /* Only one width bit may be set */
189         if (!is_power_of_2(width_flag))
190                 return -EINVAL;
191
192         if (icl->set_bus_param) {
193                 ret = icl->set_bus_param(icl, width_flag);
194                 if (ret)
195                         return ret;
196         } else {
197                 /*
198                  * Without board specific bus width settings we only support the
199                  * sensors native bus width
200                  */
201                 if (width_flag != SOCAM_DATAWIDTH_10)
202                         return -EINVAL;
203         }
204
205         flags = soc_camera_apply_sensor_flags(icl, flags);
206
207         if (flags & SOCAM_PCLK_SAMPLE_RISING)
208                 pixclk |= 0x10;
209
210         if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
211                 pixclk |= 0x1;
212
213         if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
214                 pixclk |= 0x2;
215
216         ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
217         if (ret < 0)
218                 return ret;
219
220         if (!(flags & SOCAM_MASTER))
221                 mt9v022->chip_control &= ~0x8;
222
223         ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
224         if (ret < 0)
225                 return ret;
226
227         dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
228                 pixclk, mt9v022->chip_control);
229
230         return 0;
231 }
232
233 static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
234 {
235         struct soc_camera_link *icl = to_soc_camera_link(icd);
236         unsigned int width_flag;
237
238         if (icl->query_bus_param)
239                 width_flag = icl->query_bus_param(icl) &
240                         SOCAM_DATAWIDTH_MASK;
241         else
242                 width_flag = SOCAM_DATAWIDTH_10;
243
244         return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
245                 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
246                 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
247                 SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
248                 width_flag;
249 }
250
251 static int mt9v022_set_crop(struct soc_camera_device *icd,
252                             struct v4l2_rect *rect)
253 {
254         struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
255         int ret;
256
257         /* Like in example app. Contradicts the datasheet though */
258         ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
259         if (ret >= 0) {
260                 if (ret & 1) /* Autoexposure */
261                         ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
262                                         rect->height + icd->y_skip_top + 43);
263                 else
264                         ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
265                                         rect->height + icd->y_skip_top + 43);
266         }
267         /* Setup frame format: defaults apart from width and height */
268         if (!ret)
269                 ret = reg_write(client, MT9V022_COLUMN_START, rect->left);
270         if (!ret)
271                 ret = reg_write(client, MT9V022_ROW_START, rect->top);
272         if (!ret)
273                 /* Default 94, Phytec driver says:
274                  * "width + horizontal blank >= 660" */
275                 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
276                                 rect->width > 660 - 43 ? 43 :
277                                 660 - rect->width);
278         if (!ret)
279                 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
280         if (!ret)
281                 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width);
282         if (!ret)
283                 ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
284                                 rect->height + icd->y_skip_top);
285
286         if (ret < 0)
287                 return ret;
288
289         dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height);
290
291         return 0;
292 }
293
294 static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
295 {
296         struct i2c_client *client = sd->priv;
297         struct mt9v022 *mt9v022 = to_mt9v022(client);
298         struct soc_camera_device *icd = client->dev.platform_data;
299         struct v4l2_pix_format *pix = &f->fmt.pix;
300         struct v4l2_rect rect = {
301                 .left   = icd->rect_current.left,
302                 .top    = icd->rect_current.top,
303                 .width  = pix->width,
304                 .height = pix->height,
305         };
306
307         /* The caller provides a supported format, as verified per call to
308          * icd->try_fmt(), datawidth is from our supported format list */
309         switch (pix->pixelformat) {
310         case V4L2_PIX_FMT_GREY:
311         case V4L2_PIX_FMT_Y16:
312                 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
313                         return -EINVAL;
314                 break;
315         case V4L2_PIX_FMT_SBGGR8:
316         case V4L2_PIX_FMT_SBGGR16:
317                 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
318                         return -EINVAL;
319                 break;
320         case 0:
321                 /* No format change, only geometry */
322                 break;
323         default:
324                 return -EINVAL;
325         }
326
327         /* No support for scaling on this camera, just crop. */
328         return mt9v022_set_crop(icd, &rect);
329 }
330
331 static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
332 {
333         struct i2c_client *client = sd->priv;
334         struct soc_camera_device *icd = client->dev.platform_data;
335         struct v4l2_pix_format *pix = &f->fmt.pix;
336
337         v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */,
338                               &pix->height, 32 + icd->y_skip_top,
339                               480 + icd->y_skip_top, 0, 0);
340
341         return 0;
342 }
343
344 static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
345                                 struct v4l2_dbg_chip_ident *id)
346 {
347         struct i2c_client *client = sd->priv;
348         struct mt9v022 *mt9v022 = to_mt9v022(client);
349
350         if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
351                 return -EINVAL;
352
353         if (id->match.addr != client->addr)
354                 return -ENODEV;
355
356         id->ident       = mt9v022->model;
357         id->revision    = 0;
358
359         return 0;
360 }
361
362 #ifdef CONFIG_VIDEO_ADV_DEBUG
363 static int mt9v022_g_register(struct v4l2_subdev *sd,
364                               struct v4l2_dbg_register *reg)
365 {
366         struct i2c_client *client = sd->priv;
367
368         if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
369                 return -EINVAL;
370
371         if (reg->match.addr != client->addr)
372                 return -ENODEV;
373
374         reg->size = 2;
375         reg->val = reg_read(client, reg->reg);
376
377         if (reg->val > 0xffff)
378                 return -EIO;
379
380         return 0;
381 }
382
383 static int mt9v022_s_register(struct v4l2_subdev *sd,
384                               struct v4l2_dbg_register *reg)
385 {
386         struct i2c_client *client = sd->priv;
387
388         if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
389                 return -EINVAL;
390
391         if (reg->match.addr != client->addr)
392                 return -ENODEV;
393
394         if (reg_write(client, reg->reg, reg->val) < 0)
395                 return -EIO;
396
397         return 0;
398 }
399 #endif
400
401 static const struct v4l2_queryctrl mt9v022_controls[] = {
402         {
403                 .id             = V4L2_CID_VFLIP,
404                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
405                 .name           = "Flip Vertically",
406                 .minimum        = 0,
407                 .maximum        = 1,
408                 .step           = 1,
409                 .default_value  = 0,
410         }, {
411                 .id             = V4L2_CID_HFLIP,
412                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
413                 .name           = "Flip Horizontally",
414                 .minimum        = 0,
415                 .maximum        = 1,
416                 .step           = 1,
417                 .default_value  = 0,
418         }, {
419                 .id             = V4L2_CID_GAIN,
420                 .type           = V4L2_CTRL_TYPE_INTEGER,
421                 .name           = "Analog Gain",
422                 .minimum        = 64,
423                 .maximum        = 127,
424                 .step           = 1,
425                 .default_value  = 64,
426                 .flags          = V4L2_CTRL_FLAG_SLIDER,
427         }, {
428                 .id             = V4L2_CID_EXPOSURE,
429                 .type           = V4L2_CTRL_TYPE_INTEGER,
430                 .name           = "Exposure",
431                 .minimum        = 1,
432                 .maximum        = 255,
433                 .step           = 1,
434                 .default_value  = 255,
435                 .flags          = V4L2_CTRL_FLAG_SLIDER,
436         }, {
437                 .id             = V4L2_CID_AUTOGAIN,
438                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
439                 .name           = "Automatic Gain",
440                 .minimum        = 0,
441                 .maximum        = 1,
442                 .step           = 1,
443                 .default_value  = 1,
444         }, {
445                 .id             = V4L2_CID_EXPOSURE_AUTO,
446                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
447                 .name           = "Automatic Exposure",
448                 .minimum        = 0,
449                 .maximum        = 1,
450                 .step           = 1,
451                 .default_value  = 1,
452         }
453 };
454
455 static struct soc_camera_ops mt9v022_ops = {
456         .init                   = mt9v022_init,
457         .set_crop               = mt9v022_set_crop,
458         .set_bus_param          = mt9v022_set_bus_param,
459         .query_bus_param        = mt9v022_query_bus_param,
460         .controls               = mt9v022_controls,
461         .num_controls           = ARRAY_SIZE(mt9v022_controls),
462 };
463
464 static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
465 {
466         struct i2c_client *client = sd->priv;
467         int data;
468
469         switch (ctrl->id) {
470         case V4L2_CID_VFLIP:
471                 data = reg_read(client, MT9V022_READ_MODE);
472                 if (data < 0)
473                         return -EIO;
474                 ctrl->value = !!(data & 0x10);
475                 break;
476         case V4L2_CID_HFLIP:
477                 data = reg_read(client, MT9V022_READ_MODE);
478                 if (data < 0)
479                         return -EIO;
480                 ctrl->value = !!(data & 0x20);
481                 break;
482         case V4L2_CID_EXPOSURE_AUTO:
483                 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
484                 if (data < 0)
485                         return -EIO;
486                 ctrl->value = !!(data & 0x1);
487                 break;
488         case V4L2_CID_AUTOGAIN:
489                 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
490                 if (data < 0)
491                         return -EIO;
492                 ctrl->value = !!(data & 0x2);
493                 break;
494         }
495         return 0;
496 }
497
498 static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
499 {
500         int data;
501         struct i2c_client *client = sd->priv;
502         struct soc_camera_device *icd = client->dev.platform_data;
503         const struct v4l2_queryctrl *qctrl;
504
505         qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
506         if (!qctrl)
507                 return -EINVAL;
508
509         switch (ctrl->id) {
510         case V4L2_CID_VFLIP:
511                 if (ctrl->value)
512                         data = reg_set(client, MT9V022_READ_MODE, 0x10);
513                 else
514                         data = reg_clear(client, MT9V022_READ_MODE, 0x10);
515                 if (data < 0)
516                         return -EIO;
517                 break;
518         case V4L2_CID_HFLIP:
519                 if (ctrl->value)
520                         data = reg_set(client, MT9V022_READ_MODE, 0x20);
521                 else
522                         data = reg_clear(client, MT9V022_READ_MODE, 0x20);
523                 if (data < 0)
524                         return -EIO;
525                 break;
526         case V4L2_CID_GAIN:
527                 /* mt9v022 has minimum == default */
528                 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
529                         return -EINVAL;
530                 else {
531                         unsigned long range = qctrl->maximum - qctrl->minimum;
532                         /* Datasheet says 16 to 64. autogain only works properly
533                          * after setting gain to maximum 14. Larger values
534                          * produce "white fly" noise effect. On the whole,
535                          * manually setting analog gain does no good. */
536                         unsigned long gain = ((ctrl->value - qctrl->minimum) *
537                                               10 + range / 2) / range + 4;
538                         if (gain >= 32)
539                                 gain &= ~1;
540                         /* The user wants to set gain manually, hope, she
541                          * knows, what she's doing... Switch AGC off. */
542
543                         if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
544                                 return -EIO;
545
546                         dev_info(&icd->dev, "Setting gain from %d to %lu\n",
547                                  reg_read(client, MT9V022_ANALOG_GAIN), gain);
548                         if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
549                                 return -EIO;
550                         icd->gain = ctrl->value;
551                 }
552                 break;
553         case V4L2_CID_EXPOSURE:
554                 /* mt9v022 has maximum == default */
555                 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
556                         return -EINVAL;
557                 else {
558                         unsigned long range = qctrl->maximum - qctrl->minimum;
559                         unsigned long shutter = ((ctrl->value - qctrl->minimum) *
560                                                  479 + range / 2) / range + 1;
561                         /* The user wants to set shutter width manually, hope,
562                          * she knows, what she's doing... Switch AEC off. */
563
564                         if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
565                                 return -EIO;
566
567                         dev_dbg(&icd->dev, "Shutter width from %d to %lu\n",
568                                 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
569                                 shutter);
570                         if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
571                                       shutter) < 0)
572                                 return -EIO;
573                         icd->exposure = ctrl->value;
574                 }
575                 break;
576         case V4L2_CID_AUTOGAIN:
577                 if (ctrl->value)
578                         data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
579                 else
580                         data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
581                 if (data < 0)
582                         return -EIO;
583                 break;
584         case V4L2_CID_EXPOSURE_AUTO:
585                 if (ctrl->value)
586                         data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
587                 else
588                         data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
589                 if (data < 0)
590                         return -EIO;
591                 break;
592         }
593         return 0;
594 }
595
596 /* Interface active, can use i2c. If it fails, it can indeed mean, that
597  * this wasn't our capture interface, so, we wait for the right one */
598 static int mt9v022_video_probe(struct soc_camera_device *icd,
599                                struct i2c_client *client)
600 {
601         struct mt9v022 *mt9v022 = to_mt9v022(client);
602         struct soc_camera_link *icl = to_soc_camera_link(icd);
603         s32 data;
604         int ret;
605         unsigned long flags;
606
607         if (!icd->dev.parent ||
608             to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
609                 return -ENODEV;
610
611         /* Read out the chip version register */
612         data = reg_read(client, MT9V022_CHIP_VERSION);
613
614         /* must be 0x1311 or 0x1313 */
615         if (data != 0x1311 && data != 0x1313) {
616                 ret = -ENODEV;
617                 dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n",
618                          data);
619                 goto ei2c;
620         }
621
622         /* Soft reset */
623         ret = reg_write(client, MT9V022_RESET, 1);
624         if (ret < 0)
625                 goto ei2c;
626         /* 15 clock cycles */
627         udelay(200);
628         if (reg_read(client, MT9V022_RESET)) {
629                 dev_err(&icd->dev, "Resetting MT9V022 failed!\n");
630                 if (ret > 0)
631                         ret = -EIO;
632                 goto ei2c;
633         }
634
635         /* Set monochrome or colour sensor type */
636         if (sensor_type && (!strcmp("colour", sensor_type) ||
637                             !strcmp("color", sensor_type))) {
638                 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
639                 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
640                 icd->formats = mt9v022_colour_formats;
641         } else {
642                 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
643                 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
644                 icd->formats = mt9v022_monochrome_formats;
645         }
646
647         if (ret < 0)
648                 goto ei2c;
649
650         icd->num_formats = 0;
651
652         /*
653          * This is a 10bit sensor, so by default we only allow 10bit.
654          * The platform may support different bus widths due to
655          * different routing of the data lines.
656          */
657         if (icl->query_bus_param)
658                 flags = icl->query_bus_param(icl);
659         else
660                 flags = SOCAM_DATAWIDTH_10;
661
662         if (flags & SOCAM_DATAWIDTH_10)
663                 icd->num_formats++;
664         else
665                 icd->formats++;
666
667         if (flags & SOCAM_DATAWIDTH_8)
668                 icd->num_formats++;
669
670         dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
671                  data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
672                  "monochrome" : "colour");
673
674 ei2c:
675         return ret;
676 }
677
678 static void mt9v022_video_remove(struct soc_camera_device *icd)
679 {
680         struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
681         struct soc_camera_link *icl = to_soc_camera_link(icd);
682
683         dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", client->addr,
684                 icd->dev.parent, icd->vdev);
685         if (icl->free_bus)
686                 icl->free_bus(icl);
687 }
688
689 static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
690         .g_ctrl         = mt9v022_g_ctrl,
691         .s_ctrl         = mt9v022_s_ctrl,
692         .g_chip_ident   = mt9v022_g_chip_ident,
693 #ifdef CONFIG_VIDEO_ADV_DEBUG
694         .g_register     = mt9v022_g_register,
695         .s_register     = mt9v022_s_register,
696 #endif
697 };
698
699 static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
700         .s_stream       = mt9v022_s_stream,
701         .s_fmt          = mt9v022_s_fmt,
702         .try_fmt        = mt9v022_try_fmt,
703 };
704
705 static struct v4l2_subdev_ops mt9v022_subdev_ops = {
706         .core   = &mt9v022_subdev_core_ops,
707         .video  = &mt9v022_subdev_video_ops,
708 };
709
710 static int mt9v022_probe(struct i2c_client *client,
711                          const struct i2c_device_id *did)
712 {
713         struct mt9v022 *mt9v022;
714         struct soc_camera_device *icd = client->dev.platform_data;
715         struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
716         struct soc_camera_link *icl;
717         int ret;
718
719         if (!icd) {
720                 dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
721                 return -EINVAL;
722         }
723
724         icl = to_soc_camera_link(icd);
725         if (!icl) {
726                 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
727                 return -EINVAL;
728         }
729
730         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
731                 dev_warn(&adapter->dev,
732                          "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
733                 return -EIO;
734         }
735
736         mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL);
737         if (!mt9v022)
738                 return -ENOMEM;
739
740         v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
741
742         mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
743
744         icd->ops                = &mt9v022_ops;
745         icd->rect_max.left      = 1;
746         icd->rect_max.top       = 4;
747         icd->rect_max.width     = 752;
748         icd->rect_max.height    = 480;
749         icd->rect_current.left  = 1;
750         icd->rect_current.top   = 4;
751         icd->width_min          = 48;
752         icd->height_min         = 32;
753         icd->y_skip_top         = 1;
754
755         ret = mt9v022_video_probe(icd, client);
756         if (ret) {
757                 icd->ops = NULL;
758                 i2c_set_clientdata(client, NULL);
759                 kfree(mt9v022);
760         }
761
762         return ret;
763 }
764
765 static int mt9v022_remove(struct i2c_client *client)
766 {
767         struct mt9v022 *mt9v022 = to_mt9v022(client);
768         struct soc_camera_device *icd = client->dev.platform_data;
769
770         icd->ops = NULL;
771         mt9v022_video_remove(icd);
772         i2c_set_clientdata(client, NULL);
773         client->driver = NULL;
774         kfree(mt9v022);
775
776         return 0;
777 }
778 static const struct i2c_device_id mt9v022_id[] = {
779         { "mt9v022", 0 },
780         { }
781 };
782 MODULE_DEVICE_TABLE(i2c, mt9v022_id);
783
784 static struct i2c_driver mt9v022_i2c_driver = {
785         .driver = {
786                 .name = "mt9v022",
787         },
788         .probe          = mt9v022_probe,
789         .remove         = mt9v022_remove,
790         .id_table       = mt9v022_id,
791 };
792
793 static int __init mt9v022_mod_init(void)
794 {
795         return i2c_add_driver(&mt9v022_i2c_driver);
796 }
797
798 static void __exit mt9v022_mod_exit(void)
799 {
800         i2c_del_driver(&mt9v022_i2c_driver);
801 }
802
803 module_init(mt9v022_mod_init);
804 module_exit(mt9v022_mod_exit);
805
806 MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
807 MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
808 MODULE_LICENSE("GPL");