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