This source file includes following definitions.
- mt9v022_find_datafmt
- to_mt9v022
- reg_read
- reg_write
- reg_set
- reg_clear
- mt9v022_init
- mt9v022_s_stream
- mt9v022_set_selection
- mt9v022_get_selection
- mt9v022_get_fmt
- mt9v022_s_fmt
- mt9v022_set_fmt
- mt9v022_g_register
- mt9v022_s_register
- mt9v022_s_power
- mt9v022_g_volatile_ctrl
- mt9v022_s_ctrl
- mt9v022_video_probe
- mt9v022_g_skip_top_lines
- mt9v022_enum_mbus_code
- mt9v022_g_mbus_config
- mt9v022_s_mbus_config
- mt9v022_probe
- mt9v022_remove
1
2
3
4
5
6
7 #include <linux/videodev2.h>
8 #include <linux/slab.h>
9 #include <linux/i2c.h>
10 #include <linux/delay.h>
11 #include <linux/log2.h>
12 #include <linux/module.h>
13
14 #include <media/i2c/mt9v022.h>
15 #include <media/soc_camera.h>
16 #include <media/drv-intf/soc_mediabus.h>
17 #include <media/v4l2-subdev.h>
18 #include <media/v4l2-clk.h>
19 #include <media/v4l2-ctrls.h>
20
21
22
23
24
25
26
27 static char *sensor_type;
28 module_param(sensor_type, charp, S_IRUGO);
29 MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
30
31
32 #define MT9V022_CHIP_VERSION 0x00
33 #define MT9V022_COLUMN_START 0x01
34 #define MT9V022_ROW_START 0x02
35 #define MT9V022_WINDOW_HEIGHT 0x03
36 #define MT9V022_WINDOW_WIDTH 0x04
37 #define MT9V022_HORIZONTAL_BLANKING 0x05
38 #define MT9V022_VERTICAL_BLANKING 0x06
39 #define MT9V022_CHIP_CONTROL 0x07
40 #define MT9V022_SHUTTER_WIDTH1 0x08
41 #define MT9V022_SHUTTER_WIDTH2 0x09
42 #define MT9V022_SHUTTER_WIDTH_CTRL 0x0a
43 #define MT9V022_TOTAL_SHUTTER_WIDTH 0x0b
44 #define MT9V022_RESET 0x0c
45 #define MT9V022_READ_MODE 0x0d
46 #define MT9V022_MONITOR_MODE 0x0e
47 #define MT9V022_PIXEL_OPERATION_MODE 0x0f
48 #define MT9V022_LED_OUT_CONTROL 0x1b
49 #define MT9V022_ADC_MODE_CONTROL 0x1c
50 #define MT9V022_REG32 0x20
51 #define MT9V022_ANALOG_GAIN 0x35
52 #define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
53 #define MT9V022_PIXCLK_FV_LV 0x74
54 #define MT9V022_DIGITAL_TEST_PATTERN 0x7f
55 #define MT9V022_AEC_AGC_ENABLE 0xAF
56 #define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
57
58
59 #define MT9V024_PIXCLK_FV_LV 0x72
60 #define MT9V024_MAX_TOTAL_SHUTTER_WIDTH 0xAD
61
62
63 #define MT9V022_CHIP_CONTROL_DEFAULT 0x188
64
65 #define MT9V022_MAX_WIDTH 752
66 #define MT9V022_MAX_HEIGHT 480
67 #define MT9V022_MIN_WIDTH 48
68 #define MT9V022_MIN_HEIGHT 32
69 #define MT9V022_COLUMN_SKIP 1
70 #define MT9V022_ROW_SKIP 4
71
72 #define MT9V022_HORIZONTAL_BLANKING_MIN 43
73 #define MT9V022_HORIZONTAL_BLANKING_MAX 1023
74 #define MT9V022_HORIZONTAL_BLANKING_DEF 94
75 #define MT9V022_VERTICAL_BLANKING_MIN 2
76 #define MT9V022_VERTICAL_BLANKING_MAX 3000
77 #define MT9V022_VERTICAL_BLANKING_DEF 45
78
79 #define is_mt9v022_rev3(id) (id == 0x1313)
80 #define is_mt9v024(id) (id == 0x1324)
81
82
83 struct mt9v022_datafmt {
84 u32 code;
85 enum v4l2_colorspace colorspace;
86 };
87
88
89 static const struct mt9v022_datafmt *mt9v022_find_datafmt(
90 u32 code, const struct mt9v022_datafmt *fmt,
91 int n)
92 {
93 int i;
94 for (i = 0; i < n; i++)
95 if (fmt[i].code == code)
96 return fmt + i;
97
98 return NULL;
99 }
100
101 static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
102
103
104
105
106 {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
107 {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
108 };
109
110 static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
111
112 {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
113 {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
114 };
115
116
117 struct mt9v02x_register {
118 u8 max_total_shutter_width;
119 u8 pixclk_fv_lv;
120 };
121
122 static const struct mt9v02x_register mt9v022_register = {
123 .max_total_shutter_width = MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
124 .pixclk_fv_lv = MT9V022_PIXCLK_FV_LV,
125 };
126
127 static const struct mt9v02x_register mt9v024_register = {
128 .max_total_shutter_width = MT9V024_MAX_TOTAL_SHUTTER_WIDTH,
129 .pixclk_fv_lv = MT9V024_PIXCLK_FV_LV,
130 };
131
132 enum mt9v022_model {
133 MT9V022IX7ATM,
134 MT9V022IX7ATC,
135 };
136
137 struct mt9v022 {
138 struct v4l2_subdev subdev;
139 struct v4l2_ctrl_handler hdl;
140 struct {
141
142 struct v4l2_ctrl *autoexposure;
143 struct v4l2_ctrl *exposure;
144 };
145 struct {
146
147 struct v4l2_ctrl *autogain;
148 struct v4l2_ctrl *gain;
149 };
150 struct v4l2_ctrl *hblank;
151 struct v4l2_ctrl *vblank;
152 struct v4l2_rect rect;
153 struct v4l2_clk *clk;
154 const struct mt9v022_datafmt *fmt;
155 const struct mt9v022_datafmt *fmts;
156 const struct mt9v02x_register *reg;
157 int num_fmts;
158 enum mt9v022_model model;
159 u16 chip_control;
160 u16 chip_version;
161 unsigned short y_skip_top;
162 };
163
164 static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
165 {
166 return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
167 }
168
169 static int reg_read(struct i2c_client *client, const u8 reg)
170 {
171 return i2c_smbus_read_word_swapped(client, reg);
172 }
173
174 static int reg_write(struct i2c_client *client, const u8 reg,
175 const u16 data)
176 {
177 return i2c_smbus_write_word_swapped(client, reg, data);
178 }
179
180 static int reg_set(struct i2c_client *client, const u8 reg,
181 const u16 data)
182 {
183 int ret;
184
185 ret = reg_read(client, reg);
186 if (ret < 0)
187 return ret;
188 return reg_write(client, reg, ret | data);
189 }
190
191 static int reg_clear(struct i2c_client *client, const u8 reg,
192 const u16 data)
193 {
194 int ret;
195
196 ret = reg_read(client, reg);
197 if (ret < 0)
198 return ret;
199 return reg_write(client, reg, ret & ~data);
200 }
201
202 static int mt9v022_init(struct i2c_client *client)
203 {
204 struct mt9v022 *mt9v022 = to_mt9v022(client);
205 int ret;
206
207
208
209
210
211
212 mt9v022->chip_control |= 0x10;
213 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
214 if (!ret)
215 ret = reg_write(client, MT9V022_READ_MODE, 0x300);
216
217
218 if (!ret)
219
220 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
221 if (!ret)
222 ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
223 if (!ret)
224 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
225 if (!ret)
226 ret = reg_write(client, mt9v022->reg->max_total_shutter_width, 480);
227 if (!ret)
228
229 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
230 if (!ret)
231 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
232 if (!ret)
233 return v4l2_ctrl_handler_setup(&mt9v022->hdl);
234
235 return ret;
236 }
237
238 static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
239 {
240 struct i2c_client *client = v4l2_get_subdevdata(sd);
241 struct mt9v022 *mt9v022 = to_mt9v022(client);
242
243 if (enable) {
244
245 mt9v022->chip_control &= ~0x10;
246 if (is_mt9v022_rev3(mt9v022->chip_version) ||
247 is_mt9v024(mt9v022->chip_version)) {
248
249
250
251
252 if (reg_clear(client, MT9V022_REG32, 0x204))
253 return -EIO;
254 }
255 } else {
256
257 mt9v022->chip_control |= 0x10;
258 if (is_mt9v022_rev3(mt9v022->chip_version) ||
259 is_mt9v024(mt9v022->chip_version)) {
260
261
262
263
264
265 if (reg_set(client, MT9V022_REG32, 0x204))
266 return -EIO;
267 }
268 }
269
270 if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
271 return -EIO;
272 return 0;
273 }
274
275 static int mt9v022_set_selection(struct v4l2_subdev *sd,
276 struct v4l2_subdev_pad_config *cfg,
277 struct v4l2_subdev_selection *sel)
278 {
279 struct i2c_client *client = v4l2_get_subdevdata(sd);
280 struct mt9v022 *mt9v022 = to_mt9v022(client);
281 struct v4l2_rect rect = sel->r;
282 int min_row, min_blank;
283 int ret;
284
285 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
286 sel->target != V4L2_SEL_TGT_CROP)
287 return -EINVAL;
288
289
290 if (mt9v022->fmts == mt9v022_colour_fmts) {
291 rect.width = ALIGN(rect.width, 2);
292 rect.height = ALIGN(rect.height, 2);
293
294 }
295
296 soc_camera_limit_side(&rect.left, &rect.width,
297 MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
298
299 soc_camera_limit_side(&rect.top, &rect.height,
300 MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
301
302
303 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
304 if (ret >= 0) {
305 if (ret & 1)
306 ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
307 rect.height + mt9v022->y_skip_top + 43);
308
309
310
311
312
313
314
315
316 }
317
318 if (!ret)
319 ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
320 if (!ret)
321 ret = reg_write(client, MT9V022_ROW_START, rect.top);
322
323
324
325
326 if (is_mt9v024(mt9v022->chip_version)) {
327 min_row = 690;
328 min_blank = 61;
329 } else {
330 min_row = 660;
331 min_blank = 43;
332 }
333 if (!ret)
334 ret = v4l2_ctrl_s_ctrl(mt9v022->hblank,
335 rect.width > min_row - min_blank ?
336 min_blank : min_row - rect.width);
337 if (!ret)
338 ret = v4l2_ctrl_s_ctrl(mt9v022->vblank, 45);
339 if (!ret)
340 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
341 if (!ret)
342 ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
343 rect.height + mt9v022->y_skip_top);
344
345 if (ret < 0)
346 return ret;
347
348 dev_dbg(&client->dev, "Frame %dx%d pixel\n", rect.width, rect.height);
349
350 mt9v022->rect = rect;
351
352 return 0;
353 }
354
355 static int mt9v022_get_selection(struct v4l2_subdev *sd,
356 struct v4l2_subdev_pad_config *cfg,
357 struct v4l2_subdev_selection *sel)
358 {
359 struct i2c_client *client = v4l2_get_subdevdata(sd);
360 struct mt9v022 *mt9v022 = to_mt9v022(client);
361
362 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
363 return -EINVAL;
364
365 switch (sel->target) {
366 case V4L2_SEL_TGT_CROP_BOUNDS:
367 sel->r.left = MT9V022_COLUMN_SKIP;
368 sel->r.top = MT9V022_ROW_SKIP;
369 sel->r.width = MT9V022_MAX_WIDTH;
370 sel->r.height = MT9V022_MAX_HEIGHT;
371 return 0;
372 case V4L2_SEL_TGT_CROP:
373 sel->r = mt9v022->rect;
374 return 0;
375 default:
376 return -EINVAL;
377 }
378 }
379
380 static int mt9v022_get_fmt(struct v4l2_subdev *sd,
381 struct v4l2_subdev_pad_config *cfg,
382 struct v4l2_subdev_format *format)
383 {
384 struct v4l2_mbus_framefmt *mf = &format->format;
385 struct i2c_client *client = v4l2_get_subdevdata(sd);
386 struct mt9v022 *mt9v022 = to_mt9v022(client);
387
388 if (format->pad)
389 return -EINVAL;
390
391 mf->width = mt9v022->rect.width;
392 mf->height = mt9v022->rect.height;
393 mf->code = mt9v022->fmt->code;
394 mf->colorspace = mt9v022->fmt->colorspace;
395 mf->field = V4L2_FIELD_NONE;
396
397 return 0;
398 }
399
400 static int mt9v022_s_fmt(struct v4l2_subdev *sd,
401 const struct mt9v022_datafmt *fmt,
402 struct v4l2_mbus_framefmt *mf)
403 {
404 struct i2c_client *client = v4l2_get_subdevdata(sd);
405 struct mt9v022 *mt9v022 = to_mt9v022(client);
406 struct v4l2_subdev_selection sel = {
407 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
408 .target = V4L2_SEL_TGT_CROP,
409 .r.left = mt9v022->rect.left,
410 .r.top = mt9v022->rect.top,
411 .r.width = mf->width,
412 .r.height = mf->height,
413 };
414 int ret;
415
416
417
418
419
420 switch (mf->code) {
421 case MEDIA_BUS_FMT_Y8_1X8:
422 case MEDIA_BUS_FMT_Y10_1X10:
423 if (mt9v022->model != MT9V022IX7ATM)
424 return -EINVAL;
425 break;
426 case MEDIA_BUS_FMT_SBGGR8_1X8:
427 case MEDIA_BUS_FMT_SBGGR10_1X10:
428 if (mt9v022->model != MT9V022IX7ATC)
429 return -EINVAL;
430 break;
431 default:
432 return -EINVAL;
433 }
434
435
436 ret = mt9v022_set_selection(sd, NULL, &sel);
437 if (!ret) {
438 mf->width = mt9v022->rect.width;
439 mf->height = mt9v022->rect.height;
440 mt9v022->fmt = fmt;
441 mf->colorspace = fmt->colorspace;
442 }
443
444 return ret;
445 }
446
447 static int mt9v022_set_fmt(struct v4l2_subdev *sd,
448 struct v4l2_subdev_pad_config *cfg,
449 struct v4l2_subdev_format *format)
450 {
451 struct v4l2_mbus_framefmt *mf = &format->format;
452 struct i2c_client *client = v4l2_get_subdevdata(sd);
453 struct mt9v022 *mt9v022 = to_mt9v022(client);
454 const struct mt9v022_datafmt *fmt;
455 int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
456 mf->code == MEDIA_BUS_FMT_SBGGR10_1X10;
457
458 if (format->pad)
459 return -EINVAL;
460
461 v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
462 MT9V022_MAX_WIDTH, align,
463 &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
464 MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
465
466 fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
467 mt9v022->num_fmts);
468 if (!fmt) {
469 fmt = mt9v022->fmt;
470 mf->code = fmt->code;
471 }
472
473 mf->colorspace = fmt->colorspace;
474
475 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
476 return mt9v022_s_fmt(sd, fmt, mf);
477 cfg->try_fmt = *mf;
478 return 0;
479 }
480
481 #ifdef CONFIG_VIDEO_ADV_DEBUG
482 static int mt9v022_g_register(struct v4l2_subdev *sd,
483 struct v4l2_dbg_register *reg)
484 {
485 struct i2c_client *client = v4l2_get_subdevdata(sd);
486
487 if (reg->reg > 0xff)
488 return -EINVAL;
489
490 reg->size = 2;
491 reg->val = reg_read(client, reg->reg);
492
493 if (reg->val > 0xffff)
494 return -EIO;
495
496 return 0;
497 }
498
499 static int mt9v022_s_register(struct v4l2_subdev *sd,
500 const struct v4l2_dbg_register *reg)
501 {
502 struct i2c_client *client = v4l2_get_subdevdata(sd);
503
504 if (reg->reg > 0xff)
505 return -EINVAL;
506
507 if (reg_write(client, reg->reg, reg->val) < 0)
508 return -EIO;
509
510 return 0;
511 }
512 #endif
513
514 static int mt9v022_s_power(struct v4l2_subdev *sd, int on)
515 {
516 struct i2c_client *client = v4l2_get_subdevdata(sd);
517 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
518 struct mt9v022 *mt9v022 = to_mt9v022(client);
519
520 return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on);
521 }
522
523 static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
524 {
525 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
526 struct mt9v022, hdl);
527 struct v4l2_subdev *sd = &mt9v022->subdev;
528 struct i2c_client *client = v4l2_get_subdevdata(sd);
529 struct v4l2_ctrl *gain = mt9v022->gain;
530 struct v4l2_ctrl *exp = mt9v022->exposure;
531 unsigned long range;
532 int data;
533
534 switch (ctrl->id) {
535 case V4L2_CID_AUTOGAIN:
536 data = reg_read(client, MT9V022_ANALOG_GAIN);
537 if (data < 0)
538 return -EIO;
539
540 range = gain->maximum - gain->minimum;
541 gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
542 return 0;
543 case V4L2_CID_EXPOSURE_AUTO:
544 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
545 if (data < 0)
546 return -EIO;
547
548 range = exp->maximum - exp->minimum;
549 exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
550 return 0;
551 case V4L2_CID_HBLANK:
552 data = reg_read(client, MT9V022_HORIZONTAL_BLANKING);
553 if (data < 0)
554 return -EIO;
555 ctrl->val = data;
556 return 0;
557 case V4L2_CID_VBLANK:
558 data = reg_read(client, MT9V022_VERTICAL_BLANKING);
559 if (data < 0)
560 return -EIO;
561 ctrl->val = data;
562 return 0;
563 }
564 return -EINVAL;
565 }
566
567 static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
568 {
569 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
570 struct mt9v022, hdl);
571 struct v4l2_subdev *sd = &mt9v022->subdev;
572 struct i2c_client *client = v4l2_get_subdevdata(sd);
573 int data;
574
575 switch (ctrl->id) {
576 case V4L2_CID_VFLIP:
577 if (ctrl->val)
578 data = reg_set(client, MT9V022_READ_MODE, 0x10);
579 else
580 data = reg_clear(client, MT9V022_READ_MODE, 0x10);
581 if (data < 0)
582 return -EIO;
583 return 0;
584 case V4L2_CID_HFLIP:
585 if (ctrl->val)
586 data = reg_set(client, MT9V022_READ_MODE, 0x20);
587 else
588 data = reg_clear(client, MT9V022_READ_MODE, 0x20);
589 if (data < 0)
590 return -EIO;
591 return 0;
592 case V4L2_CID_AUTOGAIN:
593 if (ctrl->val) {
594 if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
595 return -EIO;
596 } else {
597 struct v4l2_ctrl *gain = mt9v022->gain;
598
599 unsigned long range = gain->maximum - gain->minimum;
600
601 unsigned long gain_val = ((gain->val - (s32)gain->minimum) *
602 48 + range / 2) / range + 16;
603
604 if (gain_val >= 32)
605 gain_val &= ~1;
606
607
608
609
610
611 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
612 return -EIO;
613
614 dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
615 reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
616 if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
617 return -EIO;
618 }
619 return 0;
620 case V4L2_CID_EXPOSURE_AUTO:
621 if (ctrl->val == V4L2_EXPOSURE_AUTO) {
622 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
623 } else {
624 struct v4l2_ctrl *exp = mt9v022->exposure;
625 unsigned long range = exp->maximum - exp->minimum;
626 unsigned long shutter = ((exp->val - (s32)exp->minimum) *
627 479 + range / 2) / range + 1;
628
629
630
631
632
633 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
634 if (data < 0)
635 return -EIO;
636 dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
637 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
638 shutter);
639 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
640 shutter) < 0)
641 return -EIO;
642 }
643 return 0;
644 case V4L2_CID_HBLANK:
645 if (reg_write(client, MT9V022_HORIZONTAL_BLANKING,
646 ctrl->val) < 0)
647 return -EIO;
648 return 0;
649 case V4L2_CID_VBLANK:
650 if (reg_write(client, MT9V022_VERTICAL_BLANKING,
651 ctrl->val) < 0)
652 return -EIO;
653 return 0;
654 }
655 return -EINVAL;
656 }
657
658
659
660
661
662 static int mt9v022_video_probe(struct i2c_client *client)
663 {
664 struct mt9v022 *mt9v022 = to_mt9v022(client);
665 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
666 s32 data;
667 int ret;
668 unsigned long flags;
669
670 ret = mt9v022_s_power(&mt9v022->subdev, 1);
671 if (ret < 0)
672 return ret;
673
674
675 data = reg_read(client, MT9V022_CHIP_VERSION);
676
677
678 if (data != 0x1311 && data != 0x1313 && data != 0x1324) {
679 ret = -ENODEV;
680 dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
681 data);
682 goto ei2c;
683 }
684
685 mt9v022->chip_version = data;
686
687 mt9v022->reg = is_mt9v024(data) ? &mt9v024_register :
688 &mt9v022_register;
689
690
691 ret = reg_write(client, MT9V022_RESET, 1);
692 if (ret < 0)
693 goto ei2c;
694
695 udelay(200);
696 if (reg_read(client, MT9V022_RESET)) {
697 dev_err(&client->dev, "Resetting MT9V022 failed!\n");
698 if (ret > 0)
699 ret = -EIO;
700 goto ei2c;
701 }
702
703
704 if (sensor_type && (!strcmp("colour", sensor_type) ||
705 !strcmp("color", sensor_type))) {
706 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
707 mt9v022->model = MT9V022IX7ATC;
708 mt9v022->fmts = mt9v022_colour_fmts;
709 } else {
710 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
711 mt9v022->model = MT9V022IX7ATM;
712 mt9v022->fmts = mt9v022_monochrome_fmts;
713 }
714
715 if (ret < 0)
716 goto ei2c;
717
718 mt9v022->num_fmts = 0;
719
720
721
722
723
724
725 if (ssdd->query_bus_param)
726 flags = ssdd->query_bus_param(ssdd);
727 else
728 flags = SOCAM_DATAWIDTH_10;
729
730 if (flags & SOCAM_DATAWIDTH_10)
731 mt9v022->num_fmts++;
732 else
733 mt9v022->fmts++;
734
735 if (flags & SOCAM_DATAWIDTH_8)
736 mt9v022->num_fmts++;
737
738 mt9v022->fmt = &mt9v022->fmts[0];
739
740 dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
741 data, mt9v022->model == MT9V022IX7ATM ?
742 "monochrome" : "colour");
743
744 ret = mt9v022_init(client);
745 if (ret < 0)
746 dev_err(&client->dev, "Failed to initialise the camera\n");
747
748 ei2c:
749 mt9v022_s_power(&mt9v022->subdev, 0);
750 return ret;
751 }
752
753 static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
754 {
755 struct i2c_client *client = v4l2_get_subdevdata(sd);
756 struct mt9v022 *mt9v022 = to_mt9v022(client);
757
758 *lines = mt9v022->y_skip_top;
759
760 return 0;
761 }
762
763 static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
764 .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
765 .s_ctrl = mt9v022_s_ctrl,
766 };
767
768 static const struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
769 #ifdef CONFIG_VIDEO_ADV_DEBUG
770 .g_register = mt9v022_g_register,
771 .s_register = mt9v022_s_register,
772 #endif
773 .s_power = mt9v022_s_power,
774 };
775
776 static int mt9v022_enum_mbus_code(struct v4l2_subdev *sd,
777 struct v4l2_subdev_pad_config *cfg,
778 struct v4l2_subdev_mbus_code_enum *code)
779 {
780 struct i2c_client *client = v4l2_get_subdevdata(sd);
781 struct mt9v022 *mt9v022 = to_mt9v022(client);
782
783 if (code->pad || code->index >= mt9v022->num_fmts)
784 return -EINVAL;
785
786 code->code = mt9v022->fmts[code->index].code;
787 return 0;
788 }
789
790 static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
791 struct v4l2_mbus_config *cfg)
792 {
793 struct i2c_client *client = v4l2_get_subdevdata(sd);
794 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
795
796 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
797 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
798 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
799 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
800 V4L2_MBUS_DATA_ACTIVE_HIGH;
801 cfg->type = V4L2_MBUS_PARALLEL;
802 cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
803
804 return 0;
805 }
806
807 static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
808 const struct v4l2_mbus_config *cfg)
809 {
810 struct i2c_client *client = v4l2_get_subdevdata(sd);
811 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
812 struct mt9v022 *mt9v022 = to_mt9v022(client);
813 unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg);
814 unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
815 int ret;
816 u16 pixclk = 0;
817
818 if (ssdd->set_bus_param) {
819 ret = ssdd->set_bus_param(ssdd, 1 << (bps - 1));
820 if (ret)
821 return ret;
822 } else if (bps != 10) {
823
824
825
826
827 return -EINVAL;
828 }
829
830 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
831 pixclk |= 0x10;
832
833 if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
834 pixclk |= 0x1;
835
836 if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
837 pixclk |= 0x2;
838
839 ret = reg_write(client, mt9v022->reg->pixclk_fv_lv, pixclk);
840 if (ret < 0)
841 return ret;
842
843 if (!(flags & V4L2_MBUS_MASTER))
844 mt9v022->chip_control &= ~0x8;
845
846 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
847 if (ret < 0)
848 return ret;
849
850 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
851 pixclk, mt9v022->chip_control);
852
853 return 0;
854 }
855
856 static const struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
857 .s_stream = mt9v022_s_stream,
858 .g_mbus_config = mt9v022_g_mbus_config,
859 .s_mbus_config = mt9v022_s_mbus_config,
860 };
861
862 static const struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
863 .g_skip_top_lines = mt9v022_g_skip_top_lines,
864 };
865
866 static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = {
867 .enum_mbus_code = mt9v022_enum_mbus_code,
868 .get_selection = mt9v022_get_selection,
869 .set_selection = mt9v022_set_selection,
870 .get_fmt = mt9v022_get_fmt,
871 .set_fmt = mt9v022_set_fmt,
872 };
873
874 static const struct v4l2_subdev_ops mt9v022_subdev_ops = {
875 .core = &mt9v022_subdev_core_ops,
876 .video = &mt9v022_subdev_video_ops,
877 .sensor = &mt9v022_subdev_sensor_ops,
878 .pad = &mt9v022_subdev_pad_ops,
879 };
880
881 static int mt9v022_probe(struct i2c_client *client,
882 const struct i2c_device_id *did)
883 {
884 struct mt9v022 *mt9v022;
885 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
886 struct i2c_adapter *adapter = client->adapter;
887 struct mt9v022_platform_data *pdata;
888 int ret;
889
890 if (!ssdd) {
891 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
892 return -EINVAL;
893 }
894
895 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
896 dev_warn(&adapter->dev,
897 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
898 return -EIO;
899 }
900
901 mt9v022 = devm_kzalloc(&client->dev, sizeof(struct mt9v022), GFP_KERNEL);
902 if (!mt9v022)
903 return -ENOMEM;
904
905 pdata = ssdd->drv_priv;
906 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
907 v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
908 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
909 V4L2_CID_VFLIP, 0, 1, 1, 0);
910 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
911 V4L2_CID_HFLIP, 0, 1, 1, 0);
912 mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
913 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
914 mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
915 V4L2_CID_GAIN, 0, 127, 1, 64);
916
917
918
919
920
921 mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
922 &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
923 V4L2_EXPOSURE_AUTO);
924 mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
925 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
926
927 mt9v022->hblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
928 V4L2_CID_HBLANK, MT9V022_HORIZONTAL_BLANKING_MIN,
929 MT9V022_HORIZONTAL_BLANKING_MAX, 1,
930 MT9V022_HORIZONTAL_BLANKING_DEF);
931
932 mt9v022->vblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
933 V4L2_CID_VBLANK, MT9V022_VERTICAL_BLANKING_MIN,
934 MT9V022_VERTICAL_BLANKING_MAX, 1,
935 MT9V022_VERTICAL_BLANKING_DEF);
936
937 mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
938 if (mt9v022->hdl.error) {
939 int err = mt9v022->hdl.error;
940
941 dev_err(&client->dev, "control initialisation err %d\n", err);
942 return err;
943 }
944 v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
945 V4L2_EXPOSURE_MANUAL, true);
946 v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
947
948 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
949
950
951
952
953
954 mt9v022->y_skip_top = pdata ? pdata->y_skip_top : 0;
955 mt9v022->rect.left = MT9V022_COLUMN_SKIP;
956 mt9v022->rect.top = MT9V022_ROW_SKIP;
957 mt9v022->rect.width = MT9V022_MAX_WIDTH;
958 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
959
960 mt9v022->clk = v4l2_clk_get(&client->dev, "mclk");
961 if (IS_ERR(mt9v022->clk)) {
962 ret = PTR_ERR(mt9v022->clk);
963 goto eclkget;
964 }
965
966 ret = mt9v022_video_probe(client);
967 if (ret) {
968 v4l2_clk_put(mt9v022->clk);
969 eclkget:
970 v4l2_ctrl_handler_free(&mt9v022->hdl);
971 }
972
973 return ret;
974 }
975
976 static int mt9v022_remove(struct i2c_client *client)
977 {
978 struct mt9v022 *mt9v022 = to_mt9v022(client);
979 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
980
981 v4l2_clk_put(mt9v022->clk);
982 v4l2_device_unregister_subdev(&mt9v022->subdev);
983 if (ssdd->free_bus)
984 ssdd->free_bus(ssdd);
985 v4l2_ctrl_handler_free(&mt9v022->hdl);
986
987 return 0;
988 }
989 static const struct i2c_device_id mt9v022_id[] = {
990 { "mt9v022", 0 },
991 { }
992 };
993 MODULE_DEVICE_TABLE(i2c, mt9v022_id);
994
995 static struct i2c_driver mt9v022_i2c_driver = {
996 .driver = {
997 .name = "mt9v022",
998 },
999 .probe = mt9v022_probe,
1000 .remove = mt9v022_remove,
1001 .id_table = mt9v022_id,
1002 };
1003
1004 module_i2c_driver(mt9v022_i2c_driver);
1005
1006 MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
1007 MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
1008 MODULE_LICENSE("GPL");