1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/clk.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/gpio.h>
19#include <linux/i2c.h>
20#include <linux/log2.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/of_gpio.h>
24#include <linux/pm.h>
25#include <linux/regulator/consumer.h>
26#include <linux/slab.h>
27#include <linux/videodev2.h>
28
29#include <media/mt9p031.h>
30#include <media/v4l2-ctrls.h>
31#include <media/v4l2-device.h>
32#include <media/v4l2-of.h>
33#include <media/v4l2-subdev.h>
34
35#include "aptina-pll.h"
36
37#define MT9P031_PIXEL_ARRAY_WIDTH 2752
38#define MT9P031_PIXEL_ARRAY_HEIGHT 2004
39
40#define MT9P031_CHIP_VERSION 0x00
41#define MT9P031_CHIP_VERSION_VALUE 0x1801
42#define MT9P031_ROW_START 0x01
43#define MT9P031_ROW_START_MIN 0
44#define MT9P031_ROW_START_MAX 2004
45#define MT9P031_ROW_START_DEF 54
46#define MT9P031_COLUMN_START 0x02
47#define MT9P031_COLUMN_START_MIN 0
48#define MT9P031_COLUMN_START_MAX 2750
49#define MT9P031_COLUMN_START_DEF 16
50#define MT9P031_WINDOW_HEIGHT 0x03
51#define MT9P031_WINDOW_HEIGHT_MIN 2
52#define MT9P031_WINDOW_HEIGHT_MAX 2006
53#define MT9P031_WINDOW_HEIGHT_DEF 1944
54#define MT9P031_WINDOW_WIDTH 0x04
55#define MT9P031_WINDOW_WIDTH_MIN 2
56#define MT9P031_WINDOW_WIDTH_MAX 2752
57#define MT9P031_WINDOW_WIDTH_DEF 2592
58#define MT9P031_HORIZONTAL_BLANK 0x05
59#define MT9P031_HORIZONTAL_BLANK_MIN 0
60#define MT9P031_HORIZONTAL_BLANK_MAX 4095
61#define MT9P031_VERTICAL_BLANK 0x06
62#define MT9P031_VERTICAL_BLANK_MIN 1
63#define MT9P031_VERTICAL_BLANK_MAX 4096
64#define MT9P031_VERTICAL_BLANK_DEF 26
65#define MT9P031_OUTPUT_CONTROL 0x07
66#define MT9P031_OUTPUT_CONTROL_CEN 2
67#define MT9P031_OUTPUT_CONTROL_SYN 1
68#define MT9P031_OUTPUT_CONTROL_DEF 0x1f82
69#define MT9P031_SHUTTER_WIDTH_UPPER 0x08
70#define MT9P031_SHUTTER_WIDTH_LOWER 0x09
71#define MT9P031_SHUTTER_WIDTH_MIN 1
72#define MT9P031_SHUTTER_WIDTH_MAX 1048575
73#define MT9P031_SHUTTER_WIDTH_DEF 1943
74#define MT9P031_PLL_CONTROL 0x10
75#define MT9P031_PLL_CONTROL_PWROFF 0x0050
76#define MT9P031_PLL_CONTROL_PWRON 0x0051
77#define MT9P031_PLL_CONTROL_USEPLL 0x0052
78#define MT9P031_PLL_CONFIG_1 0x11
79#define MT9P031_PLL_CONFIG_2 0x12
80#define MT9P031_PIXEL_CLOCK_CONTROL 0x0a
81#define MT9P031_FRAME_RESTART 0x0b
82#define MT9P031_SHUTTER_DELAY 0x0c
83#define MT9P031_RST 0x0d
84#define MT9P031_RST_ENABLE 1
85#define MT9P031_RST_DISABLE 0
86#define MT9P031_READ_MODE_1 0x1e
87#define MT9P031_READ_MODE_2 0x20
88#define MT9P031_READ_MODE_2_ROW_MIR (1 << 15)
89#define MT9P031_READ_MODE_2_COL_MIR (1 << 14)
90#define MT9P031_READ_MODE_2_ROW_BLC (1 << 6)
91#define MT9P031_ROW_ADDRESS_MODE 0x22
92#define MT9P031_COLUMN_ADDRESS_MODE 0x23
93#define MT9P031_GLOBAL_GAIN 0x35
94#define MT9P031_GLOBAL_GAIN_MIN 8
95#define MT9P031_GLOBAL_GAIN_MAX 1024
96#define MT9P031_GLOBAL_GAIN_DEF 8
97#define MT9P031_GLOBAL_GAIN_MULT (1 << 6)
98#define MT9P031_ROW_BLACK_TARGET 0x49
99#define MT9P031_ROW_BLACK_DEF_OFFSET 0x4b
100#define MT9P031_GREEN1_OFFSET 0x60
101#define MT9P031_GREEN2_OFFSET 0x61
102#define MT9P031_BLACK_LEVEL_CALIBRATION 0x62
103#define MT9P031_BLC_MANUAL_BLC (1 << 0)
104#define MT9P031_RED_OFFSET 0x63
105#define MT9P031_BLUE_OFFSET 0x64
106#define MT9P031_TEST_PATTERN 0xa0
107#define MT9P031_TEST_PATTERN_SHIFT 3
108#define MT9P031_TEST_PATTERN_ENABLE (1 << 0)
109#define MT9P031_TEST_PATTERN_DISABLE (0 << 0)
110#define MT9P031_TEST_PATTERN_GREEN 0xa1
111#define MT9P031_TEST_PATTERN_RED 0xa2
112#define MT9P031_TEST_PATTERN_BLUE 0xa3
113
114enum mt9p031_model {
115 MT9P031_MODEL_COLOR,
116 MT9P031_MODEL_MONOCHROME,
117};
118
119struct mt9p031 {
120 struct v4l2_subdev subdev;
121 struct media_pad pad;
122 struct v4l2_rect crop;
123 struct v4l2_mbus_framefmt format;
124 struct mt9p031_platform_data *pdata;
125 struct mutex power_lock;
126 int power_count;
127
128 struct clk *clk;
129 struct regulator_bulk_data regulators[3];
130
131 enum mt9p031_model model;
132 struct aptina_pll pll;
133 int reset;
134
135 struct v4l2_ctrl_handler ctrls;
136 struct v4l2_ctrl *blc_auto;
137 struct v4l2_ctrl *blc_offset;
138
139
140 u16 output_control;
141 u16 mode2;
142};
143
144static struct mt9p031 *to_mt9p031(struct v4l2_subdev *sd)
145{
146 return container_of(sd, struct mt9p031, subdev);
147}
148
149static int mt9p031_read(struct i2c_client *client, u8 reg)
150{
151 return i2c_smbus_read_word_swapped(client, reg);
152}
153
154static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data)
155{
156 return i2c_smbus_write_word_swapped(client, reg, data);
157}
158
159static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear,
160 u16 set)
161{
162 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
163 u16 value = (mt9p031->output_control & ~clear) | set;
164 int ret;
165
166 ret = mt9p031_write(client, MT9P031_OUTPUT_CONTROL, value);
167 if (ret < 0)
168 return ret;
169
170 mt9p031->output_control = value;
171 return 0;
172}
173
174static int mt9p031_set_mode2(struct mt9p031 *mt9p031, u16 clear, u16 set)
175{
176 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
177 u16 value = (mt9p031->mode2 & ~clear) | set;
178 int ret;
179
180 ret = mt9p031_write(client, MT9P031_READ_MODE_2, value);
181 if (ret < 0)
182 return ret;
183
184 mt9p031->mode2 = value;
185 return 0;
186}
187
188static int mt9p031_reset(struct mt9p031 *mt9p031)
189{
190 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
191 int ret;
192
193
194 ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_ENABLE);
195 if (ret < 0)
196 return ret;
197 ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_DISABLE);
198 if (ret < 0)
199 return ret;
200
201 return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
202 0);
203}
204
205static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
206{
207 static const struct aptina_pll_limits limits = {
208 .ext_clock_min = 6000000,
209 .ext_clock_max = 27000000,
210 .int_clock_min = 2000000,
211 .int_clock_max = 13500000,
212 .out_clock_min = 180000000,
213 .out_clock_max = 360000000,
214 .pix_clock_max = 96000000,
215 .n_min = 1,
216 .n_max = 64,
217 .m_min = 16,
218 .m_max = 255,
219 .p1_min = 1,
220 .p1_max = 128,
221 };
222
223 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
224 struct mt9p031_platform_data *pdata = mt9p031->pdata;
225
226 mt9p031->clk = devm_clk_get(&client->dev, NULL);
227 if (IS_ERR(mt9p031->clk))
228 return PTR_ERR(mt9p031->clk);
229
230 clk_set_rate(mt9p031->clk, pdata->ext_freq);
231
232 mt9p031->pll.ext_clock = pdata->ext_freq;
233 mt9p031->pll.pix_clock = pdata->target_freq;
234
235 return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
236}
237
238static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
239{
240 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
241 int ret;
242
243 ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
244 MT9P031_PLL_CONTROL_PWRON);
245 if (ret < 0)
246 return ret;
247
248 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1,
249 (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1));
250 if (ret < 0)
251 return ret;
252
253 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1);
254 if (ret < 0)
255 return ret;
256
257 usleep_range(1000, 2000);
258 ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
259 MT9P031_PLL_CONTROL_PWRON |
260 MT9P031_PLL_CONTROL_USEPLL);
261 return ret;
262}
263
264static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
265{
266 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
267
268 return mt9p031_write(client, MT9P031_PLL_CONTROL,
269 MT9P031_PLL_CONTROL_PWROFF);
270}
271
272static int mt9p031_power_on(struct mt9p031 *mt9p031)
273{
274 int ret;
275
276
277 if (gpio_is_valid(mt9p031->reset)) {
278 gpio_set_value(mt9p031->reset, 0);
279 usleep_range(1000, 2000);
280 }
281
282
283 ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators),
284 mt9p031->regulators);
285 if (ret < 0)
286 return ret;
287
288
289 if (mt9p031->clk)
290 clk_prepare_enable(mt9p031->clk);
291
292
293 if (gpio_is_valid(mt9p031->reset)) {
294 gpio_set_value(mt9p031->reset, 1);
295 usleep_range(1000, 2000);
296 }
297
298 return 0;
299}
300
301static void mt9p031_power_off(struct mt9p031 *mt9p031)
302{
303 if (gpio_is_valid(mt9p031->reset)) {
304 gpio_set_value(mt9p031->reset, 0);
305 usleep_range(1000, 2000);
306 }
307
308 regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
309 mt9p031->regulators);
310
311 if (mt9p031->clk)
312 clk_disable_unprepare(mt9p031->clk);
313}
314
315static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
316{
317 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
318 int ret;
319
320 if (!on) {
321 mt9p031_power_off(mt9p031);
322 return 0;
323 }
324
325 ret = mt9p031_power_on(mt9p031);
326 if (ret < 0)
327 return ret;
328
329 ret = mt9p031_reset(mt9p031);
330 if (ret < 0) {
331 dev_err(&client->dev, "Failed to reset the camera\n");
332 return ret;
333 }
334
335 return v4l2_ctrl_handler_setup(&mt9p031->ctrls);
336}
337
338
339
340
341
342static int mt9p031_set_params(struct mt9p031 *mt9p031)
343{
344 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
345 struct v4l2_mbus_framefmt *format = &mt9p031->format;
346 const struct v4l2_rect *crop = &mt9p031->crop;
347 unsigned int hblank;
348 unsigned int vblank;
349 unsigned int xskip;
350 unsigned int yskip;
351 unsigned int xbin;
352 unsigned int ybin;
353 int ret;
354
355
356
357
358
359
360
361 ret = mt9p031_write(client, MT9P031_COLUMN_START, crop->left);
362 if (ret < 0)
363 return ret;
364 ret = mt9p031_write(client, MT9P031_ROW_START, crop->top);
365 if (ret < 0)
366 return ret;
367 ret = mt9p031_write(client, MT9P031_WINDOW_WIDTH, crop->width - 1);
368 if (ret < 0)
369 return ret;
370 ret = mt9p031_write(client, MT9P031_WINDOW_HEIGHT, crop->height - 1);
371 if (ret < 0)
372 return ret;
373
374
375
376
377 xskip = DIV_ROUND_CLOSEST(crop->width, format->width);
378 yskip = DIV_ROUND_CLOSEST(crop->height, format->height);
379 xbin = 1 << (ffs(xskip) - 1);
380 ybin = 1 << (ffs(yskip) - 1);
381
382 ret = mt9p031_write(client, MT9P031_COLUMN_ADDRESS_MODE,
383 ((xbin - 1) << 4) | (xskip - 1));
384 if (ret < 0)
385 return ret;
386 ret = mt9p031_write(client, MT9P031_ROW_ADDRESS_MODE,
387 ((ybin - 1) << 4) | (yskip - 1));
388 if (ret < 0)
389 return ret;
390
391
392
393
394 hblank = 346 * ybin + 64 + (80 >> min_t(unsigned int, xbin, 3));
395 vblank = MT9P031_VERTICAL_BLANK_DEF;
396
397 ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank - 1);
398 if (ret < 0)
399 return ret;
400 ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank - 1);
401 if (ret < 0)
402 return ret;
403
404 return ret;
405}
406
407static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
408{
409 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
410 int ret;
411
412 if (!enable) {
413
414 ret = mt9p031_set_output_control(mt9p031,
415 MT9P031_OUTPUT_CONTROL_CEN, 0);
416 if (ret < 0)
417 return ret;
418
419 return mt9p031_pll_disable(mt9p031);
420 }
421
422 ret = mt9p031_set_params(mt9p031);
423 if (ret < 0)
424 return ret;
425
426
427 ret = mt9p031_set_output_control(mt9p031, 0,
428 MT9P031_OUTPUT_CONTROL_CEN);
429 if (ret < 0)
430 return ret;
431
432 return mt9p031_pll_enable(mt9p031);
433}
434
435static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev,
436 struct v4l2_subdev_fh *fh,
437 struct v4l2_subdev_mbus_code_enum *code)
438{
439 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
440
441 if (code->pad || code->index)
442 return -EINVAL;
443
444 code->code = mt9p031->format.code;
445 return 0;
446}
447
448static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev,
449 struct v4l2_subdev_fh *fh,
450 struct v4l2_subdev_frame_size_enum *fse)
451{
452 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
453
454 if (fse->index >= 8 || fse->code != mt9p031->format.code)
455 return -EINVAL;
456
457 fse->min_width = MT9P031_WINDOW_WIDTH_DEF
458 / min_t(unsigned int, 7, fse->index + 1);
459 fse->max_width = fse->min_width;
460 fse->min_height = MT9P031_WINDOW_HEIGHT_DEF / (fse->index + 1);
461 fse->max_height = fse->min_height;
462
463 return 0;
464}
465
466static struct v4l2_mbus_framefmt *
467__mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh,
468 unsigned int pad, u32 which)
469{
470 switch (which) {
471 case V4L2_SUBDEV_FORMAT_TRY:
472 return v4l2_subdev_get_try_format(fh, pad);
473 case V4L2_SUBDEV_FORMAT_ACTIVE:
474 return &mt9p031->format;
475 default:
476 return NULL;
477 }
478}
479
480static struct v4l2_rect *
481__mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh,
482 unsigned int pad, u32 which)
483{
484 switch (which) {
485 case V4L2_SUBDEV_FORMAT_TRY:
486 return v4l2_subdev_get_try_crop(fh, pad);
487 case V4L2_SUBDEV_FORMAT_ACTIVE:
488 return &mt9p031->crop;
489 default:
490 return NULL;
491 }
492}
493
494static int mt9p031_get_format(struct v4l2_subdev *subdev,
495 struct v4l2_subdev_fh *fh,
496 struct v4l2_subdev_format *fmt)
497{
498 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
499
500 fmt->format = *__mt9p031_get_pad_format(mt9p031, fh, fmt->pad,
501 fmt->which);
502 return 0;
503}
504
505static int mt9p031_set_format(struct v4l2_subdev *subdev,
506 struct v4l2_subdev_fh *fh,
507 struct v4l2_subdev_format *format)
508{
509 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
510 struct v4l2_mbus_framefmt *__format;
511 struct v4l2_rect *__crop;
512 unsigned int width;
513 unsigned int height;
514 unsigned int hratio;
515 unsigned int vratio;
516
517 __crop = __mt9p031_get_pad_crop(mt9p031, fh, format->pad,
518 format->which);
519
520
521 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
522 max(__crop->width / 7, MT9P031_WINDOW_WIDTH_MIN),
523 __crop->width);
524 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
525 max(__crop->height / 8, MT9P031_WINDOW_HEIGHT_MIN),
526 __crop->height);
527
528 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
529 vratio = DIV_ROUND_CLOSEST(__crop->height, height);
530
531 __format = __mt9p031_get_pad_format(mt9p031, fh, format->pad,
532 format->which);
533 __format->width = __crop->width / hratio;
534 __format->height = __crop->height / vratio;
535
536 format->format = *__format;
537
538 return 0;
539}
540
541static int mt9p031_get_crop(struct v4l2_subdev *subdev,
542 struct v4l2_subdev_fh *fh,
543 struct v4l2_subdev_crop *crop)
544{
545 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
546
547 crop->rect = *__mt9p031_get_pad_crop(mt9p031, fh, crop->pad,
548 crop->which);
549 return 0;
550}
551
552static int mt9p031_set_crop(struct v4l2_subdev *subdev,
553 struct v4l2_subdev_fh *fh,
554 struct v4l2_subdev_crop *crop)
555{
556 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
557 struct v4l2_mbus_framefmt *__format;
558 struct v4l2_rect *__crop;
559 struct v4l2_rect rect;
560
561
562
563
564 rect.left = clamp(ALIGN(crop->rect.left, 2), MT9P031_COLUMN_START_MIN,
565 MT9P031_COLUMN_START_MAX);
566 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9P031_ROW_START_MIN,
567 MT9P031_ROW_START_MAX);
568 rect.width = clamp(ALIGN(crop->rect.width, 2),
569 MT9P031_WINDOW_WIDTH_MIN,
570 MT9P031_WINDOW_WIDTH_MAX);
571 rect.height = clamp(ALIGN(crop->rect.height, 2),
572 MT9P031_WINDOW_HEIGHT_MIN,
573 MT9P031_WINDOW_HEIGHT_MAX);
574
575 rect.width = min(rect.width, MT9P031_PIXEL_ARRAY_WIDTH - rect.left);
576 rect.height = min(rect.height, MT9P031_PIXEL_ARRAY_HEIGHT - rect.top);
577
578 __crop = __mt9p031_get_pad_crop(mt9p031, fh, crop->pad, crop->which);
579
580 if (rect.width != __crop->width || rect.height != __crop->height) {
581
582
583
584 __format = __mt9p031_get_pad_format(mt9p031, fh, crop->pad,
585 crop->which);
586 __format->width = rect.width;
587 __format->height = rect.height;
588 }
589
590 *__crop = rect;
591 crop->rect = rect;
592
593 return 0;
594}
595
596
597
598
599
600#define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002)
601#define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003)
602#define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004)
603#define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005)
604
605static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
606{
607 struct mt9p031 *mt9p031 =
608 container_of(ctrl->handler, struct mt9p031, ctrls);
609 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
610 u16 data;
611 int ret;
612
613 switch (ctrl->id) {
614 case V4L2_CID_EXPOSURE:
615 ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
616 (ctrl->val >> 16) & 0xffff);
617 if (ret < 0)
618 return ret;
619
620 return mt9p031_write(client, MT9P031_SHUTTER_WIDTH_LOWER,
621 ctrl->val & 0xffff);
622
623 case V4L2_CID_GAIN:
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638 if (ctrl->val <= 32) {
639 data = ctrl->val;
640 } else if (ctrl->val <= 64) {
641 ctrl->val &= ~1;
642 data = (1 << 6) | (ctrl->val >> 1);
643 } else {
644 ctrl->val &= ~7;
645 data = ((ctrl->val - 64) << 5) | (1 << 6) | 32;
646 }
647
648 return mt9p031_write(client, MT9P031_GLOBAL_GAIN, data);
649
650 case V4L2_CID_HFLIP:
651 if (ctrl->val)
652 return mt9p031_set_mode2(mt9p031,
653 0, MT9P031_READ_MODE_2_COL_MIR);
654 else
655 return mt9p031_set_mode2(mt9p031,
656 MT9P031_READ_MODE_2_COL_MIR, 0);
657
658 case V4L2_CID_VFLIP:
659 if (ctrl->val)
660 return mt9p031_set_mode2(mt9p031,
661 0, MT9P031_READ_MODE_2_ROW_MIR);
662 else
663 return mt9p031_set_mode2(mt9p031,
664 MT9P031_READ_MODE_2_ROW_MIR, 0);
665
666 case V4L2_CID_TEST_PATTERN:
667 if (!ctrl->val) {
668
669 if (mt9p031->blc_auto->cur.val != 0) {
670 ret = mt9p031_s_ctrl(mt9p031->blc_auto);
671 if (ret < 0)
672 return ret;
673 }
674 if (mt9p031->blc_offset->cur.val != 0) {
675 ret = mt9p031_s_ctrl(mt9p031->blc_offset);
676 if (ret < 0)
677 return ret;
678 }
679 return mt9p031_write(client, MT9P031_TEST_PATTERN,
680 MT9P031_TEST_PATTERN_DISABLE);
681 }
682
683 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_GREEN, 0x05a0);
684 if (ret < 0)
685 return ret;
686 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_RED, 0x0a50);
687 if (ret < 0)
688 return ret;
689 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_BLUE, 0x0aa0);
690 if (ret < 0)
691 return ret;
692
693
694
695
696 ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
697 0);
698 if (ret < 0)
699 return ret;
700
701 ret = mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET, 0);
702 if (ret < 0)
703 return ret;
704
705 return mt9p031_write(client, MT9P031_TEST_PATTERN,
706 ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT)
707 | MT9P031_TEST_PATTERN_ENABLE);
708
709 case V4L2_CID_BLC_AUTO:
710 ret = mt9p031_set_mode2(mt9p031,
711 ctrl->val ? 0 : MT9P031_READ_MODE_2_ROW_BLC,
712 ctrl->val ? MT9P031_READ_MODE_2_ROW_BLC : 0);
713 if (ret < 0)
714 return ret;
715
716 return mt9p031_write(client, MT9P031_BLACK_LEVEL_CALIBRATION,
717 ctrl->val ? 0 : MT9P031_BLC_MANUAL_BLC);
718
719 case V4L2_CID_BLC_TARGET_LEVEL:
720 return mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
721 ctrl->val);
722
723 case V4L2_CID_BLC_ANALOG_OFFSET:
724 data = ctrl->val & ((1 << 9) - 1);
725
726 ret = mt9p031_write(client, MT9P031_GREEN1_OFFSET, data);
727 if (ret < 0)
728 return ret;
729 ret = mt9p031_write(client, MT9P031_GREEN2_OFFSET, data);
730 if (ret < 0)
731 return ret;
732 ret = mt9p031_write(client, MT9P031_RED_OFFSET, data);
733 if (ret < 0)
734 return ret;
735 return mt9p031_write(client, MT9P031_BLUE_OFFSET, data);
736
737 case V4L2_CID_BLC_DIGITAL_OFFSET:
738 return mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET,
739 ctrl->val & ((1 << 12) - 1));
740 }
741
742 return 0;
743}
744
745static struct v4l2_ctrl_ops mt9p031_ctrl_ops = {
746 .s_ctrl = mt9p031_s_ctrl,
747};
748
749static const char * const mt9p031_test_pattern_menu[] = {
750 "Disabled",
751 "Color Field",
752 "Horizontal Gradient",
753 "Vertical Gradient",
754 "Diagonal Gradient",
755 "Classic Test Pattern",
756 "Walking 1s",
757 "Monochrome Horizontal Bars",
758 "Monochrome Vertical Bars",
759 "Vertical Color Bars",
760};
761
762static const struct v4l2_ctrl_config mt9p031_ctrls[] = {
763 {
764 .ops = &mt9p031_ctrl_ops,
765 .id = V4L2_CID_BLC_AUTO,
766 .type = V4L2_CTRL_TYPE_BOOLEAN,
767 .name = "BLC, Auto",
768 .min = 0,
769 .max = 1,
770 .step = 1,
771 .def = 1,
772 .flags = 0,
773 }, {
774 .ops = &mt9p031_ctrl_ops,
775 .id = V4L2_CID_BLC_TARGET_LEVEL,
776 .type = V4L2_CTRL_TYPE_INTEGER,
777 .name = "BLC Target Level",
778 .min = 0,
779 .max = 4095,
780 .step = 1,
781 .def = 168,
782 .flags = 0,
783 }, {
784 .ops = &mt9p031_ctrl_ops,
785 .id = V4L2_CID_BLC_ANALOG_OFFSET,
786 .type = V4L2_CTRL_TYPE_INTEGER,
787 .name = "BLC Analog Offset",
788 .min = -255,
789 .max = 255,
790 .step = 1,
791 .def = 32,
792 .flags = 0,
793 }, {
794 .ops = &mt9p031_ctrl_ops,
795 .id = V4L2_CID_BLC_DIGITAL_OFFSET,
796 .type = V4L2_CTRL_TYPE_INTEGER,
797 .name = "BLC Digital Offset",
798 .min = -2048,
799 .max = 2047,
800 .step = 1,
801 .def = 40,
802 .flags = 0,
803 }
804};
805
806
807
808
809
810static int mt9p031_set_power(struct v4l2_subdev *subdev, int on)
811{
812 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
813 int ret = 0;
814
815 mutex_lock(&mt9p031->power_lock);
816
817
818
819
820 if (mt9p031->power_count == !on) {
821 ret = __mt9p031_set_power(mt9p031, !!on);
822 if (ret < 0)
823 goto out;
824 }
825
826
827 mt9p031->power_count += on ? 1 : -1;
828 WARN_ON(mt9p031->power_count < 0);
829
830out:
831 mutex_unlock(&mt9p031->power_lock);
832 return ret;
833}
834
835
836
837
838
839static int mt9p031_registered(struct v4l2_subdev *subdev)
840{
841 struct i2c_client *client = v4l2_get_subdevdata(subdev);
842 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
843 s32 data;
844 int ret;
845
846 ret = mt9p031_power_on(mt9p031);
847 if (ret < 0) {
848 dev_err(&client->dev, "MT9P031 power up failed\n");
849 return ret;
850 }
851
852
853 data = mt9p031_read(client, MT9P031_CHIP_VERSION);
854 mt9p031_power_off(mt9p031);
855
856 if (data != MT9P031_CHIP_VERSION_VALUE) {
857 dev_err(&client->dev, "MT9P031 not detected, wrong version "
858 "0x%04x\n", data);
859 return -ENODEV;
860 }
861
862 dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
863 client->addr);
864
865 return 0;
866}
867
868static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
869{
870 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
871 struct v4l2_mbus_framefmt *format;
872 struct v4l2_rect *crop;
873
874 crop = v4l2_subdev_get_try_crop(fh, 0);
875 crop->left = MT9P031_COLUMN_START_DEF;
876 crop->top = MT9P031_ROW_START_DEF;
877 crop->width = MT9P031_WINDOW_WIDTH_DEF;
878 crop->height = MT9P031_WINDOW_HEIGHT_DEF;
879
880 format = v4l2_subdev_get_try_format(fh, 0);
881
882 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
883 format->code = V4L2_MBUS_FMT_Y12_1X12;
884 else
885 format->code = V4L2_MBUS_FMT_SGRBG12_1X12;
886
887 format->width = MT9P031_WINDOW_WIDTH_DEF;
888 format->height = MT9P031_WINDOW_HEIGHT_DEF;
889 format->field = V4L2_FIELD_NONE;
890 format->colorspace = V4L2_COLORSPACE_SRGB;
891
892 return mt9p031_set_power(subdev, 1);
893}
894
895static int mt9p031_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
896{
897 return mt9p031_set_power(subdev, 0);
898}
899
900static struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = {
901 .s_power = mt9p031_set_power,
902};
903
904static struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
905 .s_stream = mt9p031_s_stream,
906};
907
908static struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
909 .enum_mbus_code = mt9p031_enum_mbus_code,
910 .enum_frame_size = mt9p031_enum_frame_size,
911 .get_fmt = mt9p031_get_format,
912 .set_fmt = mt9p031_set_format,
913 .get_crop = mt9p031_get_crop,
914 .set_crop = mt9p031_set_crop,
915};
916
917static struct v4l2_subdev_ops mt9p031_subdev_ops = {
918 .core = &mt9p031_subdev_core_ops,
919 .video = &mt9p031_subdev_video_ops,
920 .pad = &mt9p031_subdev_pad_ops,
921};
922
923static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
924 .registered = mt9p031_registered,
925 .open = mt9p031_open,
926 .close = mt9p031_close,
927};
928
929
930
931
932
933static struct mt9p031_platform_data *
934mt9p031_get_pdata(struct i2c_client *client)
935{
936 struct mt9p031_platform_data *pdata;
937 struct device_node *np;
938
939 if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
940 return client->dev.platform_data;
941
942 np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
943 if (!np)
944 return NULL;
945
946 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
947 if (!pdata)
948 goto done;
949
950 pdata->reset = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0);
951 of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq);
952 of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq);
953
954done:
955 of_node_put(np);
956 return pdata;
957}
958
959static int mt9p031_probe(struct i2c_client *client,
960 const struct i2c_device_id *did)
961{
962 struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
963 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
964 struct mt9p031 *mt9p031;
965 unsigned int i;
966 int ret;
967
968 if (pdata == NULL) {
969 dev_err(&client->dev, "No platform data\n");
970 return -EINVAL;
971 }
972
973 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
974 dev_warn(&client->dev,
975 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
976 return -EIO;
977 }
978
979 mt9p031 = devm_kzalloc(&client->dev, sizeof(*mt9p031), GFP_KERNEL);
980 if (mt9p031 == NULL)
981 return -ENOMEM;
982
983 mt9p031->pdata = pdata;
984 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
985 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
986 mt9p031->model = did->driver_data;
987 mt9p031->reset = -1;
988
989 mt9p031->regulators[0].supply = "vdd";
990 mt9p031->regulators[1].supply = "vdd_io";
991 mt9p031->regulators[2].supply = "vaa";
992
993 ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators);
994 if (ret < 0) {
995 dev_err(&client->dev, "Unable to get regulators\n");
996 return ret;
997 }
998
999 v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
1000
1001 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1002 V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN,
1003 MT9P031_SHUTTER_WIDTH_MAX, 1,
1004 MT9P031_SHUTTER_WIDTH_DEF);
1005 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1006 V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN,
1007 MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF);
1008 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1009 V4L2_CID_HFLIP, 0, 1, 1, 0);
1010 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1011 V4L2_CID_VFLIP, 0, 1, 1, 0);
1012 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1013 V4L2_CID_PIXEL_RATE, pdata->target_freq,
1014 pdata->target_freq, 1, pdata->target_freq);
1015 v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1016 V4L2_CID_TEST_PATTERN,
1017 ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, 0,
1018 0, mt9p031_test_pattern_menu);
1019
1020 for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i)
1021 v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
1022
1023 mt9p031->subdev.ctrl_handler = &mt9p031->ctrls;
1024
1025 if (mt9p031->ctrls.error) {
1026 printk(KERN_INFO "%s: control initialization error %d\n",
1027 __func__, mt9p031->ctrls.error);
1028 ret = mt9p031->ctrls.error;
1029 goto done;
1030 }
1031
1032 mt9p031->blc_auto = v4l2_ctrl_find(&mt9p031->ctrls, V4L2_CID_BLC_AUTO);
1033 mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls,
1034 V4L2_CID_BLC_DIGITAL_OFFSET);
1035
1036 mutex_init(&mt9p031->power_lock);
1037 v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops);
1038 mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
1039
1040 mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
1041 ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0);
1042 if (ret < 0)
1043 goto done;
1044
1045 mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1046
1047 mt9p031->crop.width = MT9P031_WINDOW_WIDTH_DEF;
1048 mt9p031->crop.height = MT9P031_WINDOW_HEIGHT_DEF;
1049 mt9p031->crop.left = MT9P031_COLUMN_START_DEF;
1050 mt9p031->crop.top = MT9P031_ROW_START_DEF;
1051
1052 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
1053 mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12;
1054 else
1055 mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12;
1056
1057 mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF;
1058 mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF;
1059 mt9p031->format.field = V4L2_FIELD_NONE;
1060 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
1061
1062 if (gpio_is_valid(pdata->reset)) {
1063 ret = devm_gpio_request_one(&client->dev, pdata->reset,
1064 GPIOF_OUT_INIT_LOW, "mt9p031_rst");
1065 if (ret < 0)
1066 goto done;
1067
1068 mt9p031->reset = pdata->reset;
1069 }
1070
1071 ret = mt9p031_clk_setup(mt9p031);
1072
1073done:
1074 if (ret < 0) {
1075 v4l2_ctrl_handler_free(&mt9p031->ctrls);
1076 media_entity_cleanup(&mt9p031->subdev.entity);
1077 }
1078
1079 return ret;
1080}
1081
1082static int mt9p031_remove(struct i2c_client *client)
1083{
1084 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
1085 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
1086
1087 v4l2_ctrl_handler_free(&mt9p031->ctrls);
1088 v4l2_device_unregister_subdev(subdev);
1089 media_entity_cleanup(&subdev->entity);
1090
1091 return 0;
1092}
1093
1094static const struct i2c_device_id mt9p031_id[] = {
1095 { "mt9p031", MT9P031_MODEL_COLOR },
1096 { "mt9p031m", MT9P031_MODEL_MONOCHROME },
1097 { }
1098};
1099MODULE_DEVICE_TABLE(i2c, mt9p031_id);
1100
1101#if IS_ENABLED(CONFIG_OF)
1102static const struct of_device_id mt9p031_of_match[] = {
1103 { .compatible = "aptina,mt9p031", },
1104 { .compatible = "aptina,mt9p031m", },
1105 { },
1106};
1107MODULE_DEVICE_TABLE(of, mt9p031_of_match);
1108#endif
1109
1110static struct i2c_driver mt9p031_i2c_driver = {
1111 .driver = {
1112 .of_match_table = of_match_ptr(mt9p031_of_match),
1113 .name = "mt9p031",
1114 },
1115 .probe = mt9p031_probe,
1116 .remove = mt9p031_remove,
1117 .id_table = mt9p031_id,
1118};
1119
1120module_i2c_driver(mt9p031_i2c_driver);
1121
1122MODULE_DESCRIPTION("Aptina MT9P031 Camera driver");
1123MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
1124MODULE_LICENSE("GPL v2");
1125