]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/video/mt9v032.c
Merge tag 'v3.2-rc2' into staging/for_v3.3
[karo-tx-linux.git] / drivers / media / video / mt9v032.c
1 /*
2  * Driver for MT9V032 CMOS Image Sensor from Micron
3  *
4  * Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
5  *
6  * Based on the MT9M001 driver,
7  *
8  * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14
15 #include <linux/delay.h>
16 #include <linux/i2c.h>
17 #include <linux/log2.h>
18 #include <linux/mutex.h>
19 #include <linux/slab.h>
20 #include <linux/videodev2.h>
21 #include <linux/v4l2-mediabus.h>
22 #include <linux/module.h>
23
24 #include <media/mt9v032.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-device.h>
27 #include <media/v4l2-subdev.h>
28
29 #define MT9V032_PIXEL_ARRAY_HEIGHT                      492
30 #define MT9V032_PIXEL_ARRAY_WIDTH                       782
31
32 #define MT9V032_CHIP_VERSION                            0x00
33 #define         MT9V032_CHIP_ID_REV1                    0x1311
34 #define         MT9V032_CHIP_ID_REV3                    0x1313
35 #define MT9V032_COLUMN_START                            0x01
36 #define         MT9V032_COLUMN_START_MIN                1
37 #define         MT9V032_COLUMN_START_DEF                1
38 #define         MT9V032_COLUMN_START_MAX                752
39 #define MT9V032_ROW_START                               0x02
40 #define         MT9V032_ROW_START_MIN                   4
41 #define         MT9V032_ROW_START_DEF                   5
42 #define         MT9V032_ROW_START_MAX                   482
43 #define MT9V032_WINDOW_HEIGHT                           0x03
44 #define         MT9V032_WINDOW_HEIGHT_MIN               1
45 #define         MT9V032_WINDOW_HEIGHT_DEF               480
46 #define         MT9V032_WINDOW_HEIGHT_MAX               480
47 #define MT9V032_WINDOW_WIDTH                            0x04
48 #define         MT9V032_WINDOW_WIDTH_MIN                1
49 #define         MT9V032_WINDOW_WIDTH_DEF                752
50 #define         MT9V032_WINDOW_WIDTH_MAX                752
51 #define MT9V032_HORIZONTAL_BLANKING                     0x05
52 #define         MT9V032_HORIZONTAL_BLANKING_MIN         43
53 #define         MT9V032_HORIZONTAL_BLANKING_MAX         1023
54 #define MT9V032_VERTICAL_BLANKING                       0x06
55 #define         MT9V032_VERTICAL_BLANKING_MIN           4
56 #define         MT9V032_VERTICAL_BLANKING_MAX           3000
57 #define MT9V032_CHIP_CONTROL                            0x07
58 #define         MT9V032_CHIP_CONTROL_MASTER_MODE        (1 << 3)
59 #define         MT9V032_CHIP_CONTROL_DOUT_ENABLE        (1 << 7)
60 #define         MT9V032_CHIP_CONTROL_SEQUENTIAL         (1 << 8)
61 #define MT9V032_SHUTTER_WIDTH1                          0x08
62 #define MT9V032_SHUTTER_WIDTH2                          0x09
63 #define MT9V032_SHUTTER_WIDTH_CONTROL                   0x0a
64 #define MT9V032_TOTAL_SHUTTER_WIDTH                     0x0b
65 #define         MT9V032_TOTAL_SHUTTER_WIDTH_MIN         1
66 #define         MT9V032_TOTAL_SHUTTER_WIDTH_DEF         480
67 #define         MT9V032_TOTAL_SHUTTER_WIDTH_MAX         32767
68 #define MT9V032_RESET                                   0x0c
69 #define MT9V032_READ_MODE                               0x0d
70 #define         MT9V032_READ_MODE_ROW_BIN_MASK          (3 << 0)
71 #define         MT9V032_READ_MODE_ROW_BIN_SHIFT         0
72 #define         MT9V032_READ_MODE_COLUMN_BIN_MASK       (3 << 2)
73 #define         MT9V032_READ_MODE_COLUMN_BIN_SHIFT      2
74 #define         MT9V032_READ_MODE_ROW_FLIP              (1 << 4)
75 #define         MT9V032_READ_MODE_COLUMN_FLIP           (1 << 5)
76 #define         MT9V032_READ_MODE_DARK_COLUMNS          (1 << 6)
77 #define         MT9V032_READ_MODE_DARK_ROWS             (1 << 7)
78 #define MT9V032_PIXEL_OPERATION_MODE                    0x0f
79 #define         MT9V032_PIXEL_OPERATION_MODE_COLOR      (1 << 2)
80 #define         MT9V032_PIXEL_OPERATION_MODE_HDR        (1 << 6)
81 #define MT9V032_ANALOG_GAIN                             0x35
82 #define         MT9V032_ANALOG_GAIN_MIN                 16
83 #define         MT9V032_ANALOG_GAIN_DEF                 16
84 #define         MT9V032_ANALOG_GAIN_MAX                 64
85 #define MT9V032_MAX_ANALOG_GAIN                         0x36
86 #define         MT9V032_MAX_ANALOG_GAIN_MAX             127
87 #define MT9V032_FRAME_DARK_AVERAGE                      0x42
88 #define MT9V032_DARK_AVG_THRESH                         0x46
89 #define         MT9V032_DARK_AVG_LOW_THRESH_MASK        (255 << 0)
90 #define         MT9V032_DARK_AVG_LOW_THRESH_SHIFT       0
91 #define         MT9V032_DARK_AVG_HIGH_THRESH_MASK       (255 << 8)
92 #define         MT9V032_DARK_AVG_HIGH_THRESH_SHIFT      8
93 #define MT9V032_ROW_NOISE_CORR_CONTROL                  0x70
94 #define         MT9V032_ROW_NOISE_CORR_ENABLE           (1 << 5)
95 #define         MT9V032_ROW_NOISE_CORR_USE_BLK_AVG      (1 << 7)
96 #define MT9V032_PIXEL_CLOCK                             0x74
97 #define         MT9V032_PIXEL_CLOCK_INV_LINE            (1 << 0)
98 #define         MT9V032_PIXEL_CLOCK_INV_FRAME           (1 << 1)
99 #define         MT9V032_PIXEL_CLOCK_XOR_LINE            (1 << 2)
100 #define         MT9V032_PIXEL_CLOCK_CONT_LINE           (1 << 3)
101 #define         MT9V032_PIXEL_CLOCK_INV_PXL_CLK         (1 << 4)
102 #define MT9V032_TEST_PATTERN                            0x7f
103 #define         MT9V032_TEST_PATTERN_DATA_MASK          (1023 << 0)
104 #define         MT9V032_TEST_PATTERN_DATA_SHIFT         0
105 #define         MT9V032_TEST_PATTERN_USE_DATA           (1 << 10)
106 #define         MT9V032_TEST_PATTERN_GRAY_MASK          (3 << 11)
107 #define         MT9V032_TEST_PATTERN_GRAY_NONE          (0 << 11)
108 #define         MT9V032_TEST_PATTERN_GRAY_VERTICAL      (1 << 11)
109 #define         MT9V032_TEST_PATTERN_GRAY_HORIZONTAL    (2 << 11)
110 #define         MT9V032_TEST_PATTERN_GRAY_DIAGONAL      (3 << 11)
111 #define         MT9V032_TEST_PATTERN_ENABLE             (1 << 13)
112 #define         MT9V032_TEST_PATTERN_FLIP               (1 << 14)
113 #define MT9V032_AEC_AGC_ENABLE                          0xaf
114 #define         MT9V032_AEC_ENABLE                      (1 << 0)
115 #define         MT9V032_AGC_ENABLE                      (1 << 1)
116 #define MT9V032_THERMAL_INFO                            0xc1
117
118 struct mt9v032 {
119         struct v4l2_subdev subdev;
120         struct media_pad pad;
121
122         struct v4l2_mbus_framefmt format;
123         struct v4l2_rect crop;
124
125         struct v4l2_ctrl_handler ctrls;
126
127         struct mutex power_lock;
128         int power_count;
129
130         struct mt9v032_platform_data *pdata;
131         u16 chip_control;
132         u16 aec_agc;
133 };
134
135 static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
136 {
137         return container_of(sd, struct mt9v032, subdev);
138 }
139
140 static int mt9v032_read(struct i2c_client *client, const u8 reg)
141 {
142         s32 data = i2c_smbus_read_word_swapped(client, reg);
143         dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
144                 data, reg);
145         return data;
146 }
147
148 static int mt9v032_write(struct i2c_client *client, const u8 reg,
149                          const u16 data)
150 {
151         dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
152                 data, reg);
153         return i2c_smbus_write_word_swapped(client, reg, data);
154 }
155
156 static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
157 {
158         struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
159         u16 value = (mt9v032->chip_control & ~clear) | set;
160         int ret;
161
162         ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
163         if (ret < 0)
164                 return ret;
165
166         mt9v032->chip_control = value;
167         return 0;
168 }
169
170 static int
171 mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
172 {
173         struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
174         u16 value = mt9v032->aec_agc;
175         int ret;
176
177         if (enable)
178                 value |= which;
179         else
180                 value &= ~which;
181
182         ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
183         if (ret < 0)
184                 return ret;
185
186         mt9v032->aec_agc = value;
187         return 0;
188 }
189
190 static int mt9v032_power_on(struct mt9v032 *mt9v032)
191 {
192         struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
193         int ret;
194
195         if (mt9v032->pdata->set_clock) {
196                 mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000);
197                 udelay(1);
198         }
199
200         /* Reset the chip and stop data read out */
201         ret = mt9v032_write(client, MT9V032_RESET, 1);
202         if (ret < 0)
203                 return ret;
204
205         ret = mt9v032_write(client, MT9V032_RESET, 0);
206         if (ret < 0)
207                 return ret;
208
209         return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
210 }
211
212 static void mt9v032_power_off(struct mt9v032 *mt9v032)
213 {
214         if (mt9v032->pdata->set_clock)
215                 mt9v032->pdata->set_clock(&mt9v032->subdev, 0);
216 }
217
218 static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
219 {
220         struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
221         int ret;
222
223         if (!on) {
224                 mt9v032_power_off(mt9v032);
225                 return 0;
226         }
227
228         ret = mt9v032_power_on(mt9v032);
229         if (ret < 0)
230                 return ret;
231
232         /* Configure the pixel clock polarity */
233         if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
234                 ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK,
235                                 MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
236                 if (ret < 0)
237                         return ret;
238         }
239
240         /* Disable the noise correction algorithm and restore the controls. */
241         ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
242         if (ret < 0)
243                 return ret;
244
245         return v4l2_ctrl_handler_setup(&mt9v032->ctrls);
246 }
247
248 /* -----------------------------------------------------------------------------
249  * V4L2 subdev video operations
250  */
251
252 static struct v4l2_mbus_framefmt *
253 __mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
254                          unsigned int pad, enum v4l2_subdev_format_whence which)
255 {
256         switch (which) {
257         case V4L2_SUBDEV_FORMAT_TRY:
258                 return v4l2_subdev_get_try_format(fh, pad);
259         case V4L2_SUBDEV_FORMAT_ACTIVE:
260                 return &mt9v032->format;
261         default:
262                 return NULL;
263         }
264 }
265
266 static struct v4l2_rect *
267 __mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
268                        unsigned int pad, enum v4l2_subdev_format_whence which)
269 {
270         switch (which) {
271         case V4L2_SUBDEV_FORMAT_TRY:
272                 return v4l2_subdev_get_try_crop(fh, pad);
273         case V4L2_SUBDEV_FORMAT_ACTIVE:
274                 return &mt9v032->crop;
275         default:
276                 return NULL;
277         }
278 }
279
280 static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
281 {
282         const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE
283                        | MT9V032_CHIP_CONTROL_DOUT_ENABLE
284                        | MT9V032_CHIP_CONTROL_SEQUENTIAL;
285         struct i2c_client *client = v4l2_get_subdevdata(subdev);
286         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
287         struct v4l2_mbus_framefmt *format = &mt9v032->format;
288         struct v4l2_rect *crop = &mt9v032->crop;
289         unsigned int hratio;
290         unsigned int vratio;
291         int ret;
292
293         if (!enable)
294                 return mt9v032_set_chip_control(mt9v032, mode, 0);
295
296         /* Configure the window size and row/column bin */
297         hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
298         vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
299
300         ret = mt9v032_write(client, MT9V032_READ_MODE,
301                     (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT |
302                     (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT);
303         if (ret < 0)
304                 return ret;
305
306         ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
307         if (ret < 0)
308                 return ret;
309
310         ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
311         if (ret < 0)
312                 return ret;
313
314         ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
315         if (ret < 0)
316                 return ret;
317
318         ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
319         if (ret < 0)
320                 return ret;
321
322         ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
323                             max(43, 660 - crop->width));
324         if (ret < 0)
325                 return ret;
326
327         /* Switch to master "normal" mode */
328         return mt9v032_set_chip_control(mt9v032, 0, mode);
329 }
330
331 static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
332                                   struct v4l2_subdev_fh *fh,
333                                   struct v4l2_subdev_mbus_code_enum *code)
334 {
335         if (code->index > 0)
336                 return -EINVAL;
337
338         code->code = V4L2_MBUS_FMT_SGRBG10_1X10;
339         return 0;
340 }
341
342 static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
343                                    struct v4l2_subdev_fh *fh,
344                                    struct v4l2_subdev_frame_size_enum *fse)
345 {
346         if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
347                 return -EINVAL;
348
349         fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index;
350         fse->max_width = fse->min_width;
351         fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index;
352         fse->max_height = fse->min_height;
353
354         return 0;
355 }
356
357 static int mt9v032_get_format(struct v4l2_subdev *subdev,
358                               struct v4l2_subdev_fh *fh,
359                               struct v4l2_subdev_format *format)
360 {
361         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
362
363         format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad,
364                                                    format->which);
365         return 0;
366 }
367
368 static int mt9v032_set_format(struct v4l2_subdev *subdev,
369                               struct v4l2_subdev_fh *fh,
370                               struct v4l2_subdev_format *format)
371 {
372         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
373         struct v4l2_mbus_framefmt *__format;
374         struct v4l2_rect *__crop;
375         unsigned int width;
376         unsigned int height;
377         unsigned int hratio;
378         unsigned int vratio;
379
380         __crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad,
381                                         format->which);
382
383         /* Clamp the width and height to avoid dividing by zero. */
384         width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
385                         max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN),
386                         __crop->width);
387         height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
388                          max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN),
389                          __crop->height);
390
391         hratio = DIV_ROUND_CLOSEST(__crop->width, width);
392         vratio = DIV_ROUND_CLOSEST(__crop->height, height);
393
394         __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad,
395                                             format->which);
396         __format->width = __crop->width / hratio;
397         __format->height = __crop->height / vratio;
398
399         format->format = *__format;
400
401         return 0;
402 }
403
404 static int mt9v032_get_crop(struct v4l2_subdev *subdev,
405                             struct v4l2_subdev_fh *fh,
406                             struct v4l2_subdev_crop *crop)
407 {
408         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
409
410         crop->rect = *__mt9v032_get_pad_crop(mt9v032, fh, crop->pad,
411                                              crop->which);
412         return 0;
413 }
414
415 static int mt9v032_set_crop(struct v4l2_subdev *subdev,
416                             struct v4l2_subdev_fh *fh,
417                             struct v4l2_subdev_crop *crop)
418 {
419         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
420         struct v4l2_mbus_framefmt *__format;
421         struct v4l2_rect *__crop;
422         struct v4l2_rect rect;
423
424         /* Clamp the crop rectangle boundaries and align them to a non multiple
425          * of 2 pixels to ensure a GRBG Bayer pattern.
426          */
427         rect.left = clamp(ALIGN(crop->rect.left + 1, 2) - 1,
428                           MT9V032_COLUMN_START_MIN,
429                           MT9V032_COLUMN_START_MAX);
430         rect.top = clamp(ALIGN(crop->rect.top + 1, 2) - 1,
431                          MT9V032_ROW_START_MIN,
432                          MT9V032_ROW_START_MAX);
433         rect.width = clamp(ALIGN(crop->rect.width, 2),
434                            MT9V032_WINDOW_WIDTH_MIN,
435                            MT9V032_WINDOW_WIDTH_MAX);
436         rect.height = clamp(ALIGN(crop->rect.height, 2),
437                             MT9V032_WINDOW_HEIGHT_MIN,
438                             MT9V032_WINDOW_HEIGHT_MAX);
439
440         rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left);
441         rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top);
442
443         __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which);
444
445         if (rect.width != __crop->width || rect.height != __crop->height) {
446                 /* Reset the output image size if the crop rectangle size has
447                  * been modified.
448                  */
449                 __format = __mt9v032_get_pad_format(mt9v032, fh, crop->pad,
450                                                     crop->which);
451                 __format->width = rect.width;
452                 __format->height = rect.height;
453         }
454
455         *__crop = rect;
456         crop->rect = rect;
457
458         return 0;
459 }
460
461 /* -----------------------------------------------------------------------------
462  * V4L2 subdev control operations
463  */
464
465 #define V4L2_CID_TEST_PATTERN           (V4L2_CID_USER_BASE | 0x1001)
466
467 static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
468 {
469         struct mt9v032 *mt9v032 =
470                         container_of(ctrl->handler, struct mt9v032, ctrls);
471         struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
472         u16 data;
473
474         switch (ctrl->id) {
475         case V4L2_CID_AUTOGAIN:
476                 return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE,
477                                               ctrl->val);
478
479         case V4L2_CID_GAIN:
480                 return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
481
482         case V4L2_CID_EXPOSURE_AUTO:
483                 return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
484                                               ctrl->val);
485
486         case V4L2_CID_EXPOSURE:
487                 return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
488                                      ctrl->val);
489
490         case V4L2_CID_TEST_PATTERN:
491                 switch (ctrl->val) {
492                 case 0:
493                         data = 0;
494                         break;
495                 case 1:
496                         data = MT9V032_TEST_PATTERN_GRAY_VERTICAL
497                              | MT9V032_TEST_PATTERN_ENABLE;
498                         break;
499                 case 2:
500                         data = MT9V032_TEST_PATTERN_GRAY_HORIZONTAL
501                              | MT9V032_TEST_PATTERN_ENABLE;
502                         break;
503                 case 3:
504                         data = MT9V032_TEST_PATTERN_GRAY_DIAGONAL
505                              | MT9V032_TEST_PATTERN_ENABLE;
506                         break;
507                 default:
508                         data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT)
509                              | MT9V032_TEST_PATTERN_USE_DATA
510                              | MT9V032_TEST_PATTERN_ENABLE
511                              | MT9V032_TEST_PATTERN_FLIP;
512                         break;
513                 }
514
515                 return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
516         }
517
518         return 0;
519 }
520
521 static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
522         .s_ctrl = mt9v032_s_ctrl,
523 };
524
525 static const struct v4l2_ctrl_config mt9v032_ctrls[] = {
526         {
527                 .ops            = &mt9v032_ctrl_ops,
528                 .id             = V4L2_CID_TEST_PATTERN,
529                 .type           = V4L2_CTRL_TYPE_INTEGER,
530                 .name           = "Test pattern",
531                 .min            = 0,
532                 .max            = 1023,
533                 .step           = 1,
534                 .def            = 0,
535                 .flags          = 0,
536         }
537 };
538
539 /* -----------------------------------------------------------------------------
540  * V4L2 subdev core operations
541  */
542
543 static int mt9v032_set_power(struct v4l2_subdev *subdev, int on)
544 {
545         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
546         int ret = 0;
547
548         mutex_lock(&mt9v032->power_lock);
549
550         /* If the power count is modified from 0 to != 0 or from != 0 to 0,
551          * update the power state.
552          */
553         if (mt9v032->power_count == !on) {
554                 ret = __mt9v032_set_power(mt9v032, !!on);
555                 if (ret < 0)
556                         goto done;
557         }
558
559         /* Update the power count. */
560         mt9v032->power_count += on ? 1 : -1;
561         WARN_ON(mt9v032->power_count < 0);
562
563 done:
564         mutex_unlock(&mt9v032->power_lock);
565         return ret;
566 }
567
568 /* -----------------------------------------------------------------------------
569  * V4L2 subdev internal operations
570  */
571
572 static int mt9v032_registered(struct v4l2_subdev *subdev)
573 {
574         struct i2c_client *client = v4l2_get_subdevdata(subdev);
575         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
576         s32 data;
577         int ret;
578
579         dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
580                         client->addr);
581
582         ret = mt9v032_power_on(mt9v032);
583         if (ret < 0) {
584                 dev_err(&client->dev, "MT9V032 power up failed\n");
585                 return ret;
586         }
587
588         /* Read and check the sensor version */
589         data = mt9v032_read(client, MT9V032_CHIP_VERSION);
590         if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) {
591                 dev_err(&client->dev, "MT9V032 not detected, wrong version "
592                                 "0x%04x\n", data);
593                 return -ENODEV;
594         }
595
596         mt9v032_power_off(mt9v032);
597
598         dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n",
599                         client->addr);
600
601         return ret;
602 }
603
604 static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
605 {
606         struct v4l2_mbus_framefmt *format;
607         struct v4l2_rect *crop;
608
609         crop = v4l2_subdev_get_try_crop(fh, 0);
610         crop->left = MT9V032_COLUMN_START_DEF;
611         crop->top = MT9V032_ROW_START_DEF;
612         crop->width = MT9V032_WINDOW_WIDTH_DEF;
613         crop->height = MT9V032_WINDOW_HEIGHT_DEF;
614
615         format = v4l2_subdev_get_try_format(fh, 0);
616         format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
617         format->width = MT9V032_WINDOW_WIDTH_DEF;
618         format->height = MT9V032_WINDOW_HEIGHT_DEF;
619         format->field = V4L2_FIELD_NONE;
620         format->colorspace = V4L2_COLORSPACE_SRGB;
621
622         return mt9v032_set_power(subdev, 1);
623 }
624
625 static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
626 {
627         return mt9v032_set_power(subdev, 0);
628 }
629
630 static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
631         .s_power        = mt9v032_set_power,
632 };
633
634 static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
635         .s_stream       = mt9v032_s_stream,
636 };
637
638 static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
639         .enum_mbus_code = mt9v032_enum_mbus_code,
640         .enum_frame_size = mt9v032_enum_frame_size,
641         .get_fmt = mt9v032_get_format,
642         .set_fmt = mt9v032_set_format,
643         .get_crop = mt9v032_get_crop,
644         .set_crop = mt9v032_set_crop,
645 };
646
647 static struct v4l2_subdev_ops mt9v032_subdev_ops = {
648         .core   = &mt9v032_subdev_core_ops,
649         .video  = &mt9v032_subdev_video_ops,
650         .pad    = &mt9v032_subdev_pad_ops,
651 };
652
653 static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
654         .registered = mt9v032_registered,
655         .open = mt9v032_open,
656         .close = mt9v032_close,
657 };
658
659 /* -----------------------------------------------------------------------------
660  * Driver initialization and probing
661  */
662
663 static int mt9v032_probe(struct i2c_client *client,
664                 const struct i2c_device_id *did)
665 {
666         struct mt9v032 *mt9v032;
667         unsigned int i;
668         int ret;
669
670         if (!i2c_check_functionality(client->adapter,
671                                      I2C_FUNC_SMBUS_WORD_DATA)) {
672                 dev_warn(&client->adapter->dev,
673                          "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
674                 return -EIO;
675         }
676
677         mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
678         if (!mt9v032)
679                 return -ENOMEM;
680
681         mutex_init(&mt9v032->power_lock);
682         mt9v032->pdata = client->dev.platform_data;
683
684         v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4);
685
686         v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
687                           V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
688         v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
689                           V4L2_CID_GAIN, MT9V032_ANALOG_GAIN_MIN,
690                           MT9V032_ANALOG_GAIN_MAX, 1, MT9V032_ANALOG_GAIN_DEF);
691         v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops,
692                                V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
693                                V4L2_EXPOSURE_AUTO);
694         v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
695                           V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
696                           MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
697                           MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
698
699         for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
700                 v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
701
702         mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
703
704         if (mt9v032->ctrls.error)
705                 printk(KERN_INFO "%s: control initialization error %d\n",
706                        __func__, mt9v032->ctrls.error);
707
708         mt9v032->crop.left = MT9V032_COLUMN_START_DEF;
709         mt9v032->crop.top = MT9V032_ROW_START_DEF;
710         mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF;
711         mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF;
712
713         mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
714         mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF;
715         mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF;
716         mt9v032->format.field = V4L2_FIELD_NONE;
717         mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
718
719         mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
720
721         v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
722         mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
723         mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
724
725         mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
726         ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
727         if (ret < 0)
728                 kfree(mt9v032);
729
730         return ret;
731 }
732
733 static int mt9v032_remove(struct i2c_client *client)
734 {
735         struct v4l2_subdev *subdev = i2c_get_clientdata(client);
736         struct mt9v032 *mt9v032 = to_mt9v032(subdev);
737
738         v4l2_device_unregister_subdev(subdev);
739         media_entity_cleanup(&subdev->entity);
740         kfree(mt9v032);
741         return 0;
742 }
743
744 static const struct i2c_device_id mt9v032_id[] = {
745         { "mt9v032", 0 },
746         { }
747 };
748 MODULE_DEVICE_TABLE(i2c, mt9v032_id);
749
750 static struct i2c_driver mt9v032_driver = {
751         .driver = {
752                 .name = "mt9v032",
753         },
754         .probe          = mt9v032_probe,
755         .remove         = mt9v032_remove,
756         .id_table       = mt9v032_id,
757 };
758
759 static int __init mt9v032_init(void)
760 {
761         return i2c_add_driver(&mt9v032_driver);
762 }
763
764 static void __exit mt9v032_exit(void)
765 {
766         i2c_del_driver(&mt9v032_driver);
767 }
768
769 module_init(mt9v032_init);
770 module_exit(mt9v032_exit);
771
772 MODULE_DESCRIPTION("Aptina MT9V032 Camera driver");
773 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
774 MODULE_LICENSE("GPL");