Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mt9v032.c
Go to the documentation of this file.
1 /*
2  * Driver for MT9V032 CMOS Image Sensor from Micron
3  *
4  * Copyright (C) 2010, Laurent Pinchart <[email protected]>
5  *
6  * Based on the MT9M001 driver,
7  *
8  * Copyright (C) 2008, Guennadi Liakhovetski <[email protected]>
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_SYSCLK_FREQ_DEF 26600000
33 
34 #define MT9V032_CHIP_VERSION 0x00
35 #define MT9V032_CHIP_ID_REV1 0x1311
36 #define MT9V032_CHIP_ID_REV3 0x1313
37 #define MT9V032_COLUMN_START 0x01
38 #define MT9V032_COLUMN_START_MIN 1
39 #define MT9V032_COLUMN_START_DEF 1
40 #define MT9V032_COLUMN_START_MAX 752
41 #define MT9V032_ROW_START 0x02
42 #define MT9V032_ROW_START_MIN 4
43 #define MT9V032_ROW_START_DEF 5
44 #define MT9V032_ROW_START_MAX 482
45 #define MT9V032_WINDOW_HEIGHT 0x03
46 #define MT9V032_WINDOW_HEIGHT_MIN 1
47 #define MT9V032_WINDOW_HEIGHT_DEF 480
48 #define MT9V032_WINDOW_HEIGHT_MAX 480
49 #define MT9V032_WINDOW_WIDTH 0x04
50 #define MT9V032_WINDOW_WIDTH_MIN 1
51 #define MT9V032_WINDOW_WIDTH_DEF 752
52 #define MT9V032_WINDOW_WIDTH_MAX 752
53 #define MT9V032_HORIZONTAL_BLANKING 0x05
54 #define MT9V032_HORIZONTAL_BLANKING_MIN 43
55 #define MT9V032_HORIZONTAL_BLANKING_DEF 94
56 #define MT9V032_HORIZONTAL_BLANKING_MAX 1023
57 #define MT9V032_VERTICAL_BLANKING 0x06
58 #define MT9V032_VERTICAL_BLANKING_MIN 4
59 #define MT9V032_VERTICAL_BLANKING_DEF 45
60 #define MT9V032_VERTICAL_BLANKING_MAX 3000
61 #define MT9V032_CHIP_CONTROL 0x07
62 #define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3)
63 #define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
64 #define MT9V032_CHIP_CONTROL_SEQUENTIAL (1 << 8)
65 #define MT9V032_SHUTTER_WIDTH1 0x08
66 #define MT9V032_SHUTTER_WIDTH2 0x09
67 #define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a
68 #define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b
69 #define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1
70 #define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480
71 #define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767
72 #define MT9V032_RESET 0x0c
73 #define MT9V032_READ_MODE 0x0d
74 #define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0)
75 #define MT9V032_READ_MODE_ROW_BIN_SHIFT 0
76 #define MT9V032_READ_MODE_COLUMN_BIN_MASK (3 << 2)
77 #define MT9V032_READ_MODE_COLUMN_BIN_SHIFT 2
78 #define MT9V032_READ_MODE_ROW_FLIP (1 << 4)
79 #define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5)
80 #define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6)
81 #define MT9V032_READ_MODE_DARK_ROWS (1 << 7)
82 #define MT9V032_PIXEL_OPERATION_MODE 0x0f
83 #define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2)
84 #define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6)
85 #define MT9V032_ANALOG_GAIN 0x35
86 #define MT9V032_ANALOG_GAIN_MIN 16
87 #define MT9V032_ANALOG_GAIN_DEF 16
88 #define MT9V032_ANALOG_GAIN_MAX 64
89 #define MT9V032_MAX_ANALOG_GAIN 0x36
90 #define MT9V032_MAX_ANALOG_GAIN_MAX 127
91 #define MT9V032_FRAME_DARK_AVERAGE 0x42
92 #define MT9V032_DARK_AVG_THRESH 0x46
93 #define MT9V032_DARK_AVG_LOW_THRESH_MASK (255 << 0)
94 #define MT9V032_DARK_AVG_LOW_THRESH_SHIFT 0
95 #define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8)
96 #define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8
97 #define MT9V032_ROW_NOISE_CORR_CONTROL 0x70
98 #define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5)
99 #define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7)
100 #define MT9V032_PIXEL_CLOCK 0x74
101 #define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0)
102 #define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1)
103 #define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2)
104 #define MT9V032_PIXEL_CLOCK_CONT_LINE (1 << 3)
105 #define MT9V032_PIXEL_CLOCK_INV_PXL_CLK (1 << 4)
106 #define MT9V032_TEST_PATTERN 0x7f
107 #define MT9V032_TEST_PATTERN_DATA_MASK (1023 << 0)
108 #define MT9V032_TEST_PATTERN_DATA_SHIFT 0
109 #define MT9V032_TEST_PATTERN_USE_DATA (1 << 10)
110 #define MT9V032_TEST_PATTERN_GRAY_MASK (3 << 11)
111 #define MT9V032_TEST_PATTERN_GRAY_NONE (0 << 11)
112 #define MT9V032_TEST_PATTERN_GRAY_VERTICAL (1 << 11)
113 #define MT9V032_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11)
114 #define MT9V032_TEST_PATTERN_GRAY_DIAGONAL (3 << 11)
115 #define MT9V032_TEST_PATTERN_ENABLE (1 << 13)
116 #define MT9V032_TEST_PATTERN_FLIP (1 << 14)
117 #define MT9V032_AEC_AGC_ENABLE 0xaf
118 #define MT9V032_AEC_ENABLE (1 << 0)
119 #define MT9V032_AGC_ENABLE (1 << 1)
120 #define MT9V032_THERMAL_INFO 0xc1
121 
122 struct mt9v032 {
124  struct media_pad pad;
125 
126  struct v4l2_mbus_framefmt format;
127  struct v4l2_rect crop;
128 
130  struct {
133  };
134 
137 
139 
144  struct {
147  };
148 };
149 
150 static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
151 {
152  return container_of(sd, struct mt9v032, subdev);
153 }
154 
155 static int mt9v032_read(struct i2c_client *client, const u8 reg)
156 {
157  s32 data = i2c_smbus_read_word_swapped(client, reg);
158  dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
159  data, reg);
160  return data;
161 }
162 
163 static int mt9v032_write(struct i2c_client *client, const u8 reg,
164  const u16 data)
165 {
166  dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
167  data, reg);
168  return i2c_smbus_write_word_swapped(client, reg, data);
169 }
170 
171 static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
172 {
173  struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
174  u16 value = (mt9v032->chip_control & ~clear) | set;
175  int ret;
176 
177  ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
178  if (ret < 0)
179  return ret;
180 
181  mt9v032->chip_control = value;
182  return 0;
183 }
184 
185 static int
186 mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
187 {
188  struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
189  u16 value = mt9v032->aec_agc;
190  int ret;
191 
192  if (enable)
193  value |= which;
194  else
195  value &= ~which;
196 
197  ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
198  if (ret < 0)
199  return ret;
200 
201  mt9v032->aec_agc = value;
202  return 0;
203 }
204 
205 static int
206 mt9v032_update_hblank(struct mt9v032 *mt9v032)
207 {
208  struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
209  struct v4l2_rect *crop = &mt9v032->crop;
210 
211  return mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
212  max_t(s32, mt9v032->hblank, 660 - crop->width));
213 }
214 
215 #define EXT_CLK 25000000
216 
217 static int mt9v032_power_on(struct mt9v032 *mt9v032)
218 {
219  struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
220  int ret;
221 
222  if (mt9v032->pdata->set_clock) {
223  mt9v032->pdata->set_clock(&mt9v032->subdev, mt9v032->sysclk);
224  udelay(1);
225  }
226 
227  /* Reset the chip and stop data read out */
228  ret = mt9v032_write(client, MT9V032_RESET, 1);
229  if (ret < 0)
230  return ret;
231 
232  ret = mt9v032_write(client, MT9V032_RESET, 0);
233  if (ret < 0)
234  return ret;
235 
236  return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
237 }
238 
239 static void mt9v032_power_off(struct mt9v032 *mt9v032)
240 {
241  if (mt9v032->pdata->set_clock)
242  mt9v032->pdata->set_clock(&mt9v032->subdev, 0);
243 }
244 
245 static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
246 {
247  struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
248  int ret;
249 
250  if (!on) {
251  mt9v032_power_off(mt9v032);
252  return 0;
253  }
254 
255  ret = mt9v032_power_on(mt9v032);
256  if (ret < 0)
257  return ret;
258 
259  /* Configure the pixel clock polarity */
260  if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
261  ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK,
263  if (ret < 0)
264  return ret;
265  }
266 
267  /* Disable the noise correction algorithm and restore the controls. */
268  ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
269  if (ret < 0)
270  return ret;
271 
272  return v4l2_ctrl_handler_setup(&mt9v032->ctrls);
273 }
274 
275 /* -----------------------------------------------------------------------------
276  * V4L2 subdev video operations
277  */
278 
279 static struct v4l2_mbus_framefmt *
280 __mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
281  unsigned int pad, enum v4l2_subdev_format_whence which)
282 {
283  switch (which) {
285  return v4l2_subdev_get_try_format(fh, pad);
287  return &mt9v032->format;
288  default:
289  return NULL;
290  }
291 }
292 
293 static struct v4l2_rect *
294 __mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
295  unsigned int pad, enum v4l2_subdev_format_whence which)
296 {
297  switch (which) {
299  return v4l2_subdev_get_try_crop(fh, pad);
301  return &mt9v032->crop;
302  default:
303  return NULL;
304  }
305 }
306 
307 static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
308 {
312  struct i2c_client *client = v4l2_get_subdevdata(subdev);
313  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
314  struct v4l2_mbus_framefmt *format = &mt9v032->format;
315  struct v4l2_rect *crop = &mt9v032->crop;
316  unsigned int hratio;
317  unsigned int vratio;
318  int ret;
319 
320  if (!enable)
321  return mt9v032_set_chip_control(mt9v032, mode, 0);
322 
323  /* Configure the window size and row/column bin */
324  hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
325  vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
326 
327  ret = mt9v032_write(client, MT9V032_READ_MODE,
328  (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT |
329  (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT);
330  if (ret < 0)
331  return ret;
332 
333  ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
334  if (ret < 0)
335  return ret;
336 
337  ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
338  if (ret < 0)
339  return ret;
340 
341  ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
342  if (ret < 0)
343  return ret;
344 
345  ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
346  if (ret < 0)
347  return ret;
348 
349  ret = mt9v032_update_hblank(mt9v032);
350  if (ret < 0)
351  return ret;
352 
353  /* Switch to master "normal" mode */
354  return mt9v032_set_chip_control(mt9v032, 0, mode);
355 }
356 
357 static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
358  struct v4l2_subdev_fh *fh,
359  struct v4l2_subdev_mbus_code_enum *code)
360 {
361  if (code->index > 0)
362  return -EINVAL;
363 
364  code->code = V4L2_MBUS_FMT_SGRBG10_1X10;
365  return 0;
366 }
367 
368 static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
369  struct v4l2_subdev_fh *fh,
370  struct v4l2_subdev_frame_size_enum *fse)
371 {
372  if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
373  return -EINVAL;
374 
375  fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index;
376  fse->max_width = fse->min_width;
377  fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index;
378  fse->max_height = fse->min_height;
379 
380  return 0;
381 }
382 
383 static int mt9v032_get_format(struct v4l2_subdev *subdev,
384  struct v4l2_subdev_fh *fh,
385  struct v4l2_subdev_format *format)
386 {
387  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
388 
389  format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad,
390  format->which);
391  return 0;
392 }
393 
394 static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032,
395  unsigned int hratio)
396 {
397  struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
398  int ret;
399 
400  ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate,
401  mt9v032->sysclk / hratio);
402  if (ret < 0)
403  dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret);
404 }
405 
406 static int mt9v032_set_format(struct v4l2_subdev *subdev,
407  struct v4l2_subdev_fh *fh,
408  struct v4l2_subdev_format *format)
409 {
410  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
411  struct v4l2_mbus_framefmt *__format;
412  struct v4l2_rect *__crop;
413  unsigned int width;
414  unsigned int height;
415  unsigned int hratio;
416  unsigned int vratio;
417 
418  __crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad,
419  format->which);
420 
421  /* Clamp the width and height to avoid dividing by zero. */
422  width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
423  max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN),
424  __crop->width);
425  height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
426  max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN),
427  __crop->height);
428 
429  hratio = DIV_ROUND_CLOSEST(__crop->width, width);
430  vratio = DIV_ROUND_CLOSEST(__crop->height, height);
431 
432  __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad,
433  format->which);
434  __format->width = __crop->width / hratio;
435  __format->height = __crop->height / vratio;
436  if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
437  mt9v032_configure_pixel_rate(mt9v032, hratio);
438 
439  format->format = *__format;
440 
441  return 0;
442 }
443 
444 static int mt9v032_get_crop(struct v4l2_subdev *subdev,
445  struct v4l2_subdev_fh *fh,
446  struct v4l2_subdev_crop *crop)
447 {
448  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
449 
450  crop->rect = *__mt9v032_get_pad_crop(mt9v032, fh, crop->pad,
451  crop->which);
452  return 0;
453 }
454 
455 static int mt9v032_set_crop(struct v4l2_subdev *subdev,
456  struct v4l2_subdev_fh *fh,
457  struct v4l2_subdev_crop *crop)
458 {
459  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
460  struct v4l2_mbus_framefmt *__format;
461  struct v4l2_rect *__crop;
462  struct v4l2_rect rect;
463 
464  /* Clamp the crop rectangle boundaries and align them to a non multiple
465  * of 2 pixels to ensure a GRBG Bayer pattern.
466  */
467  rect.left = clamp(ALIGN(crop->rect.left + 1, 2) - 1,
470  rect.top = clamp(ALIGN(crop->rect.top + 1, 2) - 1,
473  rect.width = clamp(ALIGN(crop->rect.width, 2),
476  rect.height = clamp(ALIGN(crop->rect.height, 2),
479 
480  rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left);
481  rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top);
482 
483  __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which);
484 
485  if (rect.width != __crop->width || rect.height != __crop->height) {
486  /* Reset the output image size if the crop rectangle size has
487  * been modified.
488  */
489  __format = __mt9v032_get_pad_format(mt9v032, fh, crop->pad,
490  crop->which);
491  __format->width = rect.width;
492  __format->height = rect.height;
493  if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE)
494  mt9v032_configure_pixel_rate(mt9v032, 1);
495  }
496 
497  *__crop = rect;
498  crop->rect = rect;
499 
500  return 0;
501 }
502 
503 /* -----------------------------------------------------------------------------
504  * V4L2 subdev control operations
505  */
506 
507 #define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001)
508 
509 static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
510 {
511  struct mt9v032 *mt9v032 =
512  container_of(ctrl->handler, struct mt9v032, ctrls);
513  struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
514  u32 freq;
515  u16 data;
516 
517  switch (ctrl->id) {
518  case V4L2_CID_AUTOGAIN:
519  return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE,
520  ctrl->val);
521 
522  case V4L2_CID_GAIN:
523  return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
524 
526  return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
527  !ctrl->val);
528 
529  case V4L2_CID_EXPOSURE:
530  return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
531  ctrl->val);
532 
533  case V4L2_CID_HBLANK:
534  mt9v032->hblank = ctrl->val;
535  return mt9v032_update_hblank(mt9v032);
536 
537  case V4L2_CID_VBLANK:
538  return mt9v032_write(client, MT9V032_VERTICAL_BLANKING,
539  ctrl->val);
540 
541  case V4L2_CID_PIXEL_RATE:
542  case V4L2_CID_LINK_FREQ:
543  if (mt9v032->link_freq == NULL)
544  break;
545 
546  freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val];
547  mt9v032->pixel_rate->val64 = freq;
548  mt9v032->sysclk = freq;
549  break;
550 
552  switch (mt9v032->test_pattern->val) {
553  case 0:
554  data = 0;
555  break;
556  case 1:
559  break;
560  case 2:
563  break;
564  case 3:
567  break;
568  default:
569  data = (mt9v032->test_pattern_color->val <<
574  break;
575  }
576  return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
577  }
578 
579  return 0;
580 }
581 
582 static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
583  .s_ctrl = mt9v032_s_ctrl,
584 };
585 
586 static const char * const mt9v032_test_pattern_menu[] = {
587  "Disabled",
588  "Gray Vertical Shade",
589  "Gray Horizontal Shade",
590  "Gray Diagonal Shade",
591  "Plain",
592 };
593 
594 static const struct v4l2_ctrl_config mt9v032_test_pattern_color = {
595  .ops = &mt9v032_ctrl_ops,
597  .type = V4L2_CTRL_TYPE_INTEGER,
598  .name = "Test Pattern Color",
599  .min = 0,
600  .max = 1023,
601  .step = 1,
602  .def = 0,
603  .flags = 0,
604 };
605 
606 /* -----------------------------------------------------------------------------
607  * V4L2 subdev core operations
608  */
609 
610 static int mt9v032_set_power(struct v4l2_subdev *subdev, int on)
611 {
612  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
613  int ret = 0;
614 
615  mutex_lock(&mt9v032->power_lock);
616 
617  /* If the power count is modified from 0 to != 0 or from != 0 to 0,
618  * update the power state.
619  */
620  if (mt9v032->power_count == !on) {
621  ret = __mt9v032_set_power(mt9v032, !!on);
622  if (ret < 0)
623  goto done;
624  }
625 
626  /* Update the power count. */
627  mt9v032->power_count += on ? 1 : -1;
628  WARN_ON(mt9v032->power_count < 0);
629 
630 done:
631  mutex_unlock(&mt9v032->power_lock);
632  return ret;
633 }
634 
635 /* -----------------------------------------------------------------------------
636  * V4L2 subdev internal operations
637  */
638 
639 static int mt9v032_registered(struct v4l2_subdev *subdev)
640 {
641  struct i2c_client *client = v4l2_get_subdevdata(subdev);
642  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
643  s32 data;
644  int ret;
645 
646  dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
647  client->addr);
648 
649  ret = mt9v032_power_on(mt9v032);
650  if (ret < 0) {
651  dev_err(&client->dev, "MT9V032 power up failed\n");
652  return ret;
653  }
654 
655  /* Read and check the sensor version */
656  data = mt9v032_read(client, MT9V032_CHIP_VERSION);
657  if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) {
658  dev_err(&client->dev, "MT9V032 not detected, wrong version "
659  "0x%04x\n", data);
660  return -ENODEV;
661  }
662 
663  mt9v032_power_off(mt9v032);
664 
665  dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n",
666  client->addr);
667 
668  mt9v032_configure_pixel_rate(mt9v032, 1);
669 
670  return ret;
671 }
672 
673 static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
674 {
675  struct v4l2_mbus_framefmt *format;
676  struct v4l2_rect *crop;
677 
678  crop = v4l2_subdev_get_try_crop(fh, 0);
680  crop->top = MT9V032_ROW_START_DEF;
683 
684  format = v4l2_subdev_get_try_format(fh, 0);
685  format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
686  format->width = MT9V032_WINDOW_WIDTH_DEF;
687  format->height = MT9V032_WINDOW_HEIGHT_DEF;
688  format->field = V4L2_FIELD_NONE;
689  format->colorspace = V4L2_COLORSPACE_SRGB;
690 
691  return mt9v032_set_power(subdev, 1);
692 }
693 
694 static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
695 {
696  return mt9v032_set_power(subdev, 0);
697 }
698 
699 static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
700  .s_power = mt9v032_set_power,
701 };
702 
703 static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
704  .s_stream = mt9v032_s_stream,
705 };
706 
707 static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
708  .enum_mbus_code = mt9v032_enum_mbus_code,
709  .enum_frame_size = mt9v032_enum_frame_size,
710  .get_fmt = mt9v032_get_format,
711  .set_fmt = mt9v032_set_format,
712  .get_crop = mt9v032_get_crop,
713  .set_crop = mt9v032_set_crop,
714 };
715 
716 static struct v4l2_subdev_ops mt9v032_subdev_ops = {
717  .core = &mt9v032_subdev_core_ops,
718  .video = &mt9v032_subdev_video_ops,
719  .pad = &mt9v032_subdev_pad_ops,
720 };
721 
722 static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
723  .registered = mt9v032_registered,
724  .open = mt9v032_open,
725  .close = mt9v032_close,
726 };
727 
728 /* -----------------------------------------------------------------------------
729  * Driver initialization and probing
730  */
731 
732 static int mt9v032_probe(struct i2c_client *client,
733  const struct i2c_device_id *did)
734 {
735  struct mt9v032_platform_data *pdata = client->dev.platform_data;
736  struct mt9v032 *mt9v032;
737  unsigned int i;
738  int ret;
739 
740  if (!i2c_check_functionality(client->adapter,
742  dev_warn(&client->adapter->dev,
743  "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
744  return -EIO;
745  }
746 
747  mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
748  if (!mt9v032)
749  return -ENOMEM;
750 
751  mutex_init(&mt9v032->power_lock);
752  mt9v032->pdata = pdata;
753 
754  v4l2_ctrl_handler_init(&mt9v032->ctrls, 10);
755 
756  v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
757  V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
758  v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
761  v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops,
764  v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
768  v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
772  v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
776  mt9v032->test_pattern = v4l2_ctrl_new_std_menu_items(&mt9v032->ctrls,
777  &mt9v032_ctrl_ops, V4L2_CID_TEST_PATTERN,
778  ARRAY_SIZE(mt9v032_test_pattern_menu) - 1, 0, 0,
779  mt9v032_test_pattern_menu);
780  mt9v032->test_pattern_color = v4l2_ctrl_new_custom(&mt9v032->ctrls,
781  &mt9v032_test_pattern_color, NULL);
782 
783  v4l2_ctrl_cluster(2, &mt9v032->test_pattern);
784 
785  mt9v032->pixel_rate =
786  v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
787  V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
788 
789  if (pdata && pdata->link_freqs) {
790  unsigned int def = 0;
791 
792  for (i = 0; pdata->link_freqs[i]; ++i) {
793  if (pdata->link_freqs[i] == pdata->link_def_freq)
794  def = i;
795  }
796 
797  mt9v032->link_freq =
798  v4l2_ctrl_new_int_menu(&mt9v032->ctrls,
799  &mt9v032_ctrl_ops,
800  V4L2_CID_LINK_FREQ, i - 1, def,
801  pdata->link_freqs);
802  v4l2_ctrl_cluster(2, &mt9v032->link_freq);
803  }
804 
805 
806  mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
807 
808  if (mt9v032->ctrls.error)
809  printk(KERN_INFO "%s: control initialization error %d\n",
810  __func__, mt9v032->ctrls.error);
811 
812  mt9v032->crop.left = MT9V032_COLUMN_START_DEF;
813  mt9v032->crop.top = MT9V032_ROW_START_DEF;
814  mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF;
815  mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF;
816 
817  mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
818  mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF;
819  mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF;
820  mt9v032->format.field = V4L2_FIELD_NONE;
821  mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
822 
825  mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF;
826 
827  v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
828  mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
829  mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
830 
831  mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
832  ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
833  if (ret < 0)
834  kfree(mt9v032);
835 
836  return ret;
837 }
838 
839 static int mt9v032_remove(struct i2c_client *client)
840 {
841  struct v4l2_subdev *subdev = i2c_get_clientdata(client);
842  struct mt9v032 *mt9v032 = to_mt9v032(subdev);
843 
845  media_entity_cleanup(&subdev->entity);
846  kfree(mt9v032);
847  return 0;
848 }
849 
850 static const struct i2c_device_id mt9v032_id[] = {
851  { "mt9v032", 0 },
852  { }
853 };
854 MODULE_DEVICE_TABLE(i2c, mt9v032_id);
855 
856 static struct i2c_driver mt9v032_driver = {
857  .driver = {
858  .name = "mt9v032",
859  },
860  .probe = mt9v032_probe,
861  .remove = mt9v032_remove,
862  .id_table = mt9v032_id,
863 };
864 
865 module_i2c_driver(mt9v032_driver);
866 
867 MODULE_DESCRIPTION("Aptina MT9V032 Camera driver");
868 MODULE_AUTHOR("Laurent Pinchart <[email protected]>");
869 MODULE_LICENSE("GPL");