blob: e5ddf47030fdd23b4aff11088847da08494bbb50 [file] [log] [blame]
Javier Martin418d93a2011-06-20 13:21:16 +02001/*
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
Laurent Pinchartd6749252012-12-21 16:11:55 -030015#include <linux/clk.h>
Javier Martin418d93a2011-06-20 13:21:16 +020016#include <linux/delay.h>
17#include <linux/device.h>
Laurent Pinchart15693b52012-03-09 10:59:41 -030018#include <linux/gpio.h>
Javier Martin418d93a2011-06-20 13:21:16 +020019#include <linux/i2c.h>
20#include <linux/log2.h>
Lad, Prabhakar8d4da372013-05-26 10:08:54 -030021#include <linux/module.h>
Sachin Kamat64695902013-10-18 00:07:11 -030022#include <linux/of.h>
Lad, Prabhakar8d4da372013-05-26 10:08:54 -030023#include <linux/of_gpio.h>
Javier Martin418d93a2011-06-20 13:21:16 +020024#include <linux/pm.h>
Laurent Pinchart97f21272012-05-08 10:10:36 -030025#include <linux/regulator/consumer.h>
Javier Martin418d93a2011-06-20 13:21:16 +020026#include <linux/slab.h>
Javier Martin418d93a2011-06-20 13:21:16 +020027#include <linux/videodev2.h>
28
29#include <media/mt9p031.h>
Javier Martin418d93a2011-06-20 13:21:16 +020030#include <media/v4l2-ctrls.h>
31#include <media/v4l2-device.h>
Lad, Prabhakar8d4da372013-05-26 10:08:54 -030032#include <media/v4l2-of.h>
Javier Martin418d93a2011-06-20 13:21:16 +020033#include <media/v4l2-subdev.h>
34
Laurent Pinchart08cd43c2012-02-25 13:25:57 -030035#include "aptina-pll.h"
36
Javier Martin418d93a2011-06-20 13:21:16 +020037#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
Laurent Pinchart5266c982012-05-23 06:51:55 -030062#define MT9P031_VERTICAL_BLANK_MIN 1
63#define MT9P031_VERTICAL_BLANK_MAX 4096
64#define MT9P031_VERTICAL_BLANK_DEF 26
Javier Martin418d93a2011-06-20 13:21:16 +020065#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)
Laurent Pinchartdfea0012012-03-09 21:02:57 -030098#define MT9P031_ROW_BLACK_TARGET 0x49
Javier Martin418d93a2011-06-20 13:21:16 +020099#define MT9P031_ROW_BLACK_DEF_OFFSET 0x4b
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300100#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
Javier Martin418d93a2011-06-20 13:21:16 +0200106#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
Laurent Pinchart1c542ba2012-03-09 10:42:52 -0300114enum mt9p031_model {
115 MT9P031_MODEL_COLOR,
116 MT9P031_MODEL_MONOCHROME,
117};
118
Javier Martin418d93a2011-06-20 13:21:16 +0200119struct mt9p031 {
120 struct v4l2_subdev subdev;
121 struct media_pad pad;
122 struct v4l2_rect crop; /* Sensor window */
123 struct v4l2_mbus_framefmt format;
Javier Martin418d93a2011-06-20 13:21:16 +0200124 struct mt9p031_platform_data *pdata;
125 struct mutex power_lock; /* lock to protect power_count */
126 int power_count;
Javier Martin418d93a2011-06-20 13:21:16 +0200127
Laurent Pinchartd6749252012-12-21 16:11:55 -0300128 struct clk *clk;
Laurent Pinchart79971962013-06-08 04:50:42 -0300129 struct regulator_bulk_data regulators[3];
Laurent Pinchart97f21272012-05-08 10:10:36 -0300130
Laurent Pinchart1c542ba2012-03-09 10:42:52 -0300131 enum mt9p031_model model;
Laurent Pinchart08cd43c2012-02-25 13:25:57 -0300132 struct aptina_pll pll;
Laurent Pinchart15693b52012-03-09 10:59:41 -0300133 int reset;
Javier Martin418d93a2011-06-20 13:21:16 +0200134
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300135 struct v4l2_ctrl_handler ctrls;
136 struct v4l2_ctrl *blc_auto;
137 struct v4l2_ctrl *blc_offset;
138
Javier Martin418d93a2011-06-20 13:21:16 +0200139 /* Registers cache */
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{
Laurent Pinchartc27e30502011-10-22 04:57:54 -0300151 return i2c_smbus_read_word_swapped(client, reg);
Javier Martin418d93a2011-06-20 13:21:16 +0200152}
153
154static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data)
155{
Laurent Pinchartc27e30502011-10-22 04:57:54 -0300156 return i2c_smbus_write_word_swapped(client, reg, data);
Javier Martin418d93a2011-06-20 13:21:16 +0200157}
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 /* Disable chip output, synchronous option update */
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
Laurent Pinchartd6749252012-12-21 16:11:55 -0300205static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
Javier Martin418d93a2011-06-20 13:21:16 +0200206{
Laurent Pinchart08cd43c2012-02-25 13:25:57 -0300207 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
Javier Martin418d93a2011-06-20 13:21:16 +0200223 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
Laurent Pinchart08cd43c2012-02-25 13:25:57 -0300224 struct mt9p031_platform_data *pdata = mt9p031->pdata;
Javier Martin418d93a2011-06-20 13:21:16 +0200225
Laurent Pinchartd6749252012-12-21 16:11:55 -0300226 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
Laurent Pinchart08cd43c2012-02-25 13:25:57 -0300232 mt9p031->pll.ext_clock = pdata->ext_freq;
233 mt9p031->pll.pix_clock = pdata->target_freq;
Javier Martin418d93a2011-06-20 13:21:16 +0200234
Laurent Pinchart08cd43c2012-02-25 13:25:57 -0300235 return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
Javier Martin418d93a2011-06-20 13:21:16 +0200236}
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,
Laurent Pinchart08cd43c2012-02-25 13:25:57 -0300249 (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1));
Javier Martin418d93a2011-06-20 13:21:16 +0200250 if (ret < 0)
251 return ret;
252
Laurent Pinchart08cd43c2012-02-25 13:25:57 -0300253 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1);
Javier Martin418d93a2011-06-20 13:21:16 +0200254 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{
Laurent Pinchart79971962013-06-08 04:50:42 -0300274 int ret;
275
Javier Martin418d93a2011-06-20 13:21:16 +0200276 /* Ensure RESET_BAR is low */
Laurent Pinchart2660a222013-05-02 07:57:51 -0300277 if (gpio_is_valid(mt9p031->reset)) {
Laurent Pinchart15693b52012-03-09 10:59:41 -0300278 gpio_set_value(mt9p031->reset, 0);
Javier Martin418d93a2011-06-20 13:21:16 +0200279 usleep_range(1000, 2000);
280 }
281
Laurent Pinchart97f21272012-05-08 10:10:36 -0300282 /* Bring up the supplies */
Laurent Pinchart79971962013-06-08 04:50:42 -0300283 ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators),
284 mt9p031->regulators);
285 if (ret < 0)
286 return ret;
Laurent Pinchart97f21272012-05-08 10:10:36 -0300287
Javier Martin418d93a2011-06-20 13:21:16 +0200288 /* Emable clock */
Laurent Pinchartd6749252012-12-21 16:11:55 -0300289 if (mt9p031->clk)
290 clk_prepare_enable(mt9p031->clk);
Javier Martin418d93a2011-06-20 13:21:16 +0200291
292 /* Now RESET_BAR must be high */
Laurent Pinchart2660a222013-05-02 07:57:51 -0300293 if (gpio_is_valid(mt9p031->reset)) {
Laurent Pinchart15693b52012-03-09 10:59:41 -0300294 gpio_set_value(mt9p031->reset, 1);
Javier Martin418d93a2011-06-20 13:21:16 +0200295 usleep_range(1000, 2000);
296 }
297
298 return 0;
299}
300
301static void mt9p031_power_off(struct mt9p031 *mt9p031)
302{
Laurent Pinchart2660a222013-05-02 07:57:51 -0300303 if (gpio_is_valid(mt9p031->reset)) {
Laurent Pinchart15693b52012-03-09 10:59:41 -0300304 gpio_set_value(mt9p031->reset, 0);
Javier Martin418d93a2011-06-20 13:21:16 +0200305 usleep_range(1000, 2000);
306 }
307
Laurent Pinchart79971962013-06-08 04:50:42 -0300308 regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
309 mt9p031->regulators);
Laurent Pinchart97f21272012-05-08 10:10:36 -0300310
Laurent Pinchartd6749252012-12-21 16:11:55 -0300311 if (mt9p031->clk)
312 clk_disable_unprepare(mt9p031->clk);
Javier Martin418d93a2011-06-20 13:21:16 +0200313}
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 * V4L2 subdev video operations
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 /* Windows position and size.
356 *
357 * TODO: Make sure the start coordinates and window size match the
358 * skipping, binning and mirroring (see description of registers 2 and 4
359 * in table 13, and Binning section on page 41).
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 /* Row and column binning and skipping. Use the maximum binning value
375 * compatible with the skipping settings.
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 /* Blanking - use minimum value for horizontal blanking and default
392 * value for vertical blanking.
393 */
Laurent Pinchart5266c982012-05-23 06:51:55 -0300394 hblank = 346 * ybin + 64 + (80 >> min_t(unsigned int, xbin, 3));
Javier Martin418d93a2011-06-20 13:21:16 +0200395 vblank = MT9P031_VERTICAL_BLANK_DEF;
396
Laurent Pinchart5266c982012-05-23 06:51:55 -0300397 ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank - 1);
Javier Martin418d93a2011-06-20 13:21:16 +0200398 if (ret < 0)
399 return ret;
Laurent Pinchart5266c982012-05-23 06:51:55 -0300400 ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank - 1);
Javier Martin418d93a2011-06-20 13:21:16 +0200401 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 /* Stop sensor readout */
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 /* Switch to master "normal" mode */
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 /* Clamp the width and height to avoid dividing by zero. */
521 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
Ricardo Ribaldaf90580c2013-11-26 05:31:42 -0300522 max_t(unsigned int, __crop->width / 7,
523 MT9P031_WINDOW_WIDTH_MIN),
Javier Martin418d93a2011-06-20 13:21:16 +0200524 __crop->width);
525 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
Ricardo Ribaldaf90580c2013-11-26 05:31:42 -0300526 max_t(unsigned int, __crop->height / 8,
527 MT9P031_WINDOW_HEIGHT_MIN),
528 __crop->height);
Javier Martin418d93a2011-06-20 13:21:16 +0200529
530 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
531 vratio = DIV_ROUND_CLOSEST(__crop->height, height);
532
533 __format = __mt9p031_get_pad_format(mt9p031, fh, format->pad,
534 format->which);
535 __format->width = __crop->width / hratio;
536 __format->height = __crop->height / vratio;
537
538 format->format = *__format;
539
540 return 0;
541}
542
543static int mt9p031_get_crop(struct v4l2_subdev *subdev,
544 struct v4l2_subdev_fh *fh,
545 struct v4l2_subdev_crop *crop)
546{
547 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
548
549 crop->rect = *__mt9p031_get_pad_crop(mt9p031, fh, crop->pad,
550 crop->which);
551 return 0;
552}
553
554static int mt9p031_set_crop(struct v4l2_subdev *subdev,
555 struct v4l2_subdev_fh *fh,
556 struct v4l2_subdev_crop *crop)
557{
558 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
559 struct v4l2_mbus_framefmt *__format;
560 struct v4l2_rect *__crop;
561 struct v4l2_rect rect;
562
563 /* Clamp the crop rectangle boundaries and align them to a multiple of 2
564 * pixels to ensure a GRBG Bayer pattern.
565 */
566 rect.left = clamp(ALIGN(crop->rect.left, 2), MT9P031_COLUMN_START_MIN,
567 MT9P031_COLUMN_START_MAX);
568 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9P031_ROW_START_MIN,
569 MT9P031_ROW_START_MAX);
Ricardo Ribaldaf90580c2013-11-26 05:31:42 -0300570 rect.width = clamp_t(unsigned int, ALIGN(crop->rect.width, 2),
571 MT9P031_WINDOW_WIDTH_MIN,
572 MT9P031_WINDOW_WIDTH_MAX);
573 rect.height = clamp_t(unsigned int, ALIGN(crop->rect.height, 2),
574 MT9P031_WINDOW_HEIGHT_MIN,
575 MT9P031_WINDOW_HEIGHT_MAX);
Javier Martin418d93a2011-06-20 13:21:16 +0200576
Ricardo Ribaldaf90580c2013-11-26 05:31:42 -0300577 rect.width = min_t(unsigned int, rect.width,
578 MT9P031_PIXEL_ARRAY_WIDTH - rect.left);
579 rect.height = min_t(unsigned int, rect.height,
580 MT9P031_PIXEL_ARRAY_HEIGHT - rect.top);
Javier Martin418d93a2011-06-20 13:21:16 +0200581
582 __crop = __mt9p031_get_pad_crop(mt9p031, fh, crop->pad, crop->which);
583
584 if (rect.width != __crop->width || rect.height != __crop->height) {
585 /* Reset the output image size if the crop rectangle size has
586 * been modified.
587 */
588 __format = __mt9p031_get_pad_format(mt9p031, fh, crop->pad,
589 crop->which);
590 __format->width = rect.width;
591 __format->height = rect.height;
592 }
593
594 *__crop = rect;
595 crop->rect = rect;
596
597 return 0;
598}
599
600/* -----------------------------------------------------------------------------
601 * V4L2 subdev control operations
602 */
603
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300604#define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002)
605#define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003)
606#define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004)
607#define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005)
Javier Martin418d93a2011-06-20 13:21:16 +0200608
609static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
610{
611 struct mt9p031 *mt9p031 =
612 container_of(ctrl->handler, struct mt9p031, ctrls);
613 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
614 u16 data;
615 int ret;
616
617 switch (ctrl->id) {
618 case V4L2_CID_EXPOSURE:
619 ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
620 (ctrl->val >> 16) & 0xffff);
621 if (ret < 0)
622 return ret;
623
624 return mt9p031_write(client, MT9P031_SHUTTER_WIDTH_LOWER,
625 ctrl->val & 0xffff);
626
627 case V4L2_CID_GAIN:
628 /* Gain is controlled by 2 analog stages and a digital stage.
629 * Valid values for the 3 stages are
630 *
631 * Stage Min Max Step
632 * ------------------------------------------
633 * First analog stage x1 x2 1
634 * Second analog stage x1 x4 0.125
635 * Digital stage x1 x16 0.125
636 *
637 * To minimize noise, the gain stages should be used in the
638 * second analog stage, first analog stage, digital stage order.
639 * Gain from a previous stage should be pushed to its maximum
640 * value before the next stage is used.
641 */
642 if (ctrl->val <= 32) {
643 data = ctrl->val;
644 } else if (ctrl->val <= 64) {
645 ctrl->val &= ~1;
646 data = (1 << 6) | (ctrl->val >> 1);
647 } else {
648 ctrl->val &= ~7;
649 data = ((ctrl->val - 64) << 5) | (1 << 6) | 32;
650 }
651
652 return mt9p031_write(client, MT9P031_GLOBAL_GAIN, data);
653
654 case V4L2_CID_HFLIP:
655 if (ctrl->val)
656 return mt9p031_set_mode2(mt9p031,
657 0, MT9P031_READ_MODE_2_COL_MIR);
658 else
659 return mt9p031_set_mode2(mt9p031,
660 MT9P031_READ_MODE_2_COL_MIR, 0);
661
662 case V4L2_CID_VFLIP:
663 if (ctrl->val)
664 return mt9p031_set_mode2(mt9p031,
665 0, MT9P031_READ_MODE_2_ROW_MIR);
666 else
667 return mt9p031_set_mode2(mt9p031,
668 MT9P031_READ_MODE_2_ROW_MIR, 0);
669
670 case V4L2_CID_TEST_PATTERN:
671 if (!ctrl->val) {
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300672 /* Restore the black level compensation settings. */
673 if (mt9p031->blc_auto->cur.val != 0) {
674 ret = mt9p031_s_ctrl(mt9p031->blc_auto);
675 if (ret < 0)
676 return ret;
677 }
678 if (mt9p031->blc_offset->cur.val != 0) {
679 ret = mt9p031_s_ctrl(mt9p031->blc_offset);
680 if (ret < 0)
681 return ret;
682 }
Javier Martin418d93a2011-06-20 13:21:16 +0200683 return mt9p031_write(client, MT9P031_TEST_PATTERN,
684 MT9P031_TEST_PATTERN_DISABLE);
685 }
686
687 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_GREEN, 0x05a0);
688 if (ret < 0)
689 return ret;
690 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_RED, 0x0a50);
691 if (ret < 0)
692 return ret;
693 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_BLUE, 0x0aa0);
694 if (ret < 0)
695 return ret;
696
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300697 /* Disable digital black level compensation when using a test
698 * pattern.
699 */
Javier Martin418d93a2011-06-20 13:21:16 +0200700 ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
701 0);
702 if (ret < 0)
703 return ret;
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300704
Javier Martin418d93a2011-06-20 13:21:16 +0200705 ret = mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET, 0);
706 if (ret < 0)
707 return ret;
708
709 return mt9p031_write(client, MT9P031_TEST_PATTERN,
710 ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT)
711 | MT9P031_TEST_PATTERN_ENABLE);
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300712
713 case V4L2_CID_BLC_AUTO:
714 ret = mt9p031_set_mode2(mt9p031,
715 ctrl->val ? 0 : MT9P031_READ_MODE_2_ROW_BLC,
716 ctrl->val ? MT9P031_READ_MODE_2_ROW_BLC : 0);
717 if (ret < 0)
718 return ret;
719
720 return mt9p031_write(client, MT9P031_BLACK_LEVEL_CALIBRATION,
721 ctrl->val ? 0 : MT9P031_BLC_MANUAL_BLC);
722
723 case V4L2_CID_BLC_TARGET_LEVEL:
724 return mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
725 ctrl->val);
726
727 case V4L2_CID_BLC_ANALOG_OFFSET:
728 data = ctrl->val & ((1 << 9) - 1);
729
730 ret = mt9p031_write(client, MT9P031_GREEN1_OFFSET, data);
731 if (ret < 0)
732 return ret;
733 ret = mt9p031_write(client, MT9P031_GREEN2_OFFSET, data);
734 if (ret < 0)
735 return ret;
736 ret = mt9p031_write(client, MT9P031_RED_OFFSET, data);
737 if (ret < 0)
738 return ret;
739 return mt9p031_write(client, MT9P031_BLUE_OFFSET, data);
740
741 case V4L2_CID_BLC_DIGITAL_OFFSET:
742 return mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET,
743 ctrl->val & ((1 << 12) - 1));
Javier Martin418d93a2011-06-20 13:21:16 +0200744 }
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300745
Javier Martin418d93a2011-06-20 13:21:16 +0200746 return 0;
747}
748
749static struct v4l2_ctrl_ops mt9p031_ctrl_ops = {
750 .s_ctrl = mt9p031_s_ctrl,
751};
752
753static const char * const mt9p031_test_pattern_menu[] = {
754 "Disabled",
755 "Color Field",
756 "Horizontal Gradient",
757 "Vertical Gradient",
758 "Diagonal Gradient",
759 "Classic Test Pattern",
760 "Walking 1s",
761 "Monochrome Horizontal Bars",
762 "Monochrome Vertical Bars",
763 "Vertical Color Bars",
764};
765
766static const struct v4l2_ctrl_config mt9p031_ctrls[] = {
767 {
768 .ops = &mt9p031_ctrl_ops,
Laurent Pinchartdfea0012012-03-09 21:02:57 -0300769 .id = V4L2_CID_BLC_AUTO,
770 .type = V4L2_CTRL_TYPE_BOOLEAN,
771 .name = "BLC, Auto",
772 .min = 0,
773 .max = 1,
774 .step = 1,
775 .def = 1,
776 .flags = 0,
777 }, {
778 .ops = &mt9p031_ctrl_ops,
779 .id = V4L2_CID_BLC_TARGET_LEVEL,
780 .type = V4L2_CTRL_TYPE_INTEGER,
781 .name = "BLC Target Level",
782 .min = 0,
783 .max = 4095,
784 .step = 1,
785 .def = 168,
786 .flags = 0,
787 }, {
788 .ops = &mt9p031_ctrl_ops,
789 .id = V4L2_CID_BLC_ANALOG_OFFSET,
790 .type = V4L2_CTRL_TYPE_INTEGER,
791 .name = "BLC Analog Offset",
792 .min = -255,
793 .max = 255,
794 .step = 1,
795 .def = 32,
796 .flags = 0,
797 }, {
798 .ops = &mt9p031_ctrl_ops,
799 .id = V4L2_CID_BLC_DIGITAL_OFFSET,
800 .type = V4L2_CTRL_TYPE_INTEGER,
801 .name = "BLC Digital Offset",
802 .min = -2048,
803 .max = 2047,
804 .step = 1,
805 .def = 40,
806 .flags = 0,
Javier Martin418d93a2011-06-20 13:21:16 +0200807 }
808};
809
810/* -----------------------------------------------------------------------------
811 * V4L2 subdev core operations
812 */
813
814static int mt9p031_set_power(struct v4l2_subdev *subdev, int on)
815{
816 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
817 int ret = 0;
818
819 mutex_lock(&mt9p031->power_lock);
820
821 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
822 * update the power state.
823 */
824 if (mt9p031->power_count == !on) {
825 ret = __mt9p031_set_power(mt9p031, !!on);
826 if (ret < 0)
827 goto out;
828 }
829
830 /* Update the power count. */
831 mt9p031->power_count += on ? 1 : -1;
832 WARN_ON(mt9p031->power_count < 0);
833
834out:
835 mutex_unlock(&mt9p031->power_lock);
836 return ret;
837}
838
839/* -----------------------------------------------------------------------------
840 * V4L2 subdev internal operations
841 */
842
843static int mt9p031_registered(struct v4l2_subdev *subdev)
844{
845 struct i2c_client *client = v4l2_get_subdevdata(subdev);
846 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
847 s32 data;
848 int ret;
849
850 ret = mt9p031_power_on(mt9p031);
851 if (ret < 0) {
852 dev_err(&client->dev, "MT9P031 power up failed\n");
853 return ret;
854 }
855
856 /* Read out the chip version register */
857 data = mt9p031_read(client, MT9P031_CHIP_VERSION);
Guennadi Liakhovetskibbcc9fa2013-04-18 18:35:39 -0300858 mt9p031_power_off(mt9p031);
859
Javier Martin418d93a2011-06-20 13:21:16 +0200860 if (data != MT9P031_CHIP_VERSION_VALUE) {
861 dev_err(&client->dev, "MT9P031 not detected, wrong version "
862 "0x%04x\n", data);
863 return -ENODEV;
864 }
865
Javier Martin418d93a2011-06-20 13:21:16 +0200866 dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
867 client->addr);
868
Guennadi Liakhovetskibbcc9fa2013-04-18 18:35:39 -0300869 return 0;
Javier Martin418d93a2011-06-20 13:21:16 +0200870}
871
872static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
873{
874 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
875 struct v4l2_mbus_framefmt *format;
876 struct v4l2_rect *crop;
877
878 crop = v4l2_subdev_get_try_crop(fh, 0);
879 crop->left = MT9P031_COLUMN_START_DEF;
880 crop->top = MT9P031_ROW_START_DEF;
881 crop->width = MT9P031_WINDOW_WIDTH_DEF;
882 crop->height = MT9P031_WINDOW_HEIGHT_DEF;
883
884 format = v4l2_subdev_get_try_format(fh, 0);
885
Laurent Pinchart1c542ba2012-03-09 10:42:52 -0300886 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
Javier Martin418d93a2011-06-20 13:21:16 +0200887 format->code = V4L2_MBUS_FMT_Y12_1X12;
888 else
889 format->code = V4L2_MBUS_FMT_SGRBG12_1X12;
890
891 format->width = MT9P031_WINDOW_WIDTH_DEF;
892 format->height = MT9P031_WINDOW_HEIGHT_DEF;
893 format->field = V4L2_FIELD_NONE;
894 format->colorspace = V4L2_COLORSPACE_SRGB;
895
Javier Martin418d93a2011-06-20 13:21:16 +0200896 return mt9p031_set_power(subdev, 1);
897}
898
899static int mt9p031_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
900{
901 return mt9p031_set_power(subdev, 0);
902}
903
904static struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = {
905 .s_power = mt9p031_set_power,
906};
907
908static struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
909 .s_stream = mt9p031_s_stream,
910};
911
912static struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
913 .enum_mbus_code = mt9p031_enum_mbus_code,
914 .enum_frame_size = mt9p031_enum_frame_size,
915 .get_fmt = mt9p031_get_format,
916 .set_fmt = mt9p031_set_format,
917 .get_crop = mt9p031_get_crop,
918 .set_crop = mt9p031_set_crop,
919};
920
921static struct v4l2_subdev_ops mt9p031_subdev_ops = {
922 .core = &mt9p031_subdev_core_ops,
923 .video = &mt9p031_subdev_video_ops,
924 .pad = &mt9p031_subdev_pad_ops,
925};
926
927static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
928 .registered = mt9p031_registered,
929 .open = mt9p031_open,
930 .close = mt9p031_close,
931};
932
933/* -----------------------------------------------------------------------------
934 * Driver initialization and probing
935 */
936
Lad, Prabhakar8d4da372013-05-26 10:08:54 -0300937static struct mt9p031_platform_data *
938mt9p031_get_pdata(struct i2c_client *client)
939{
940 struct mt9p031_platform_data *pdata;
941 struct device_node *np;
942
943 if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
944 return client->dev.platform_data;
945
946 np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
947 if (!np)
948 return NULL;
949
950 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
951 if (!pdata)
952 goto done;
953
954 pdata->reset = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0);
955 of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq);
956 of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq);
957
958done:
959 of_node_put(np);
960 return pdata;
961}
962
Javier Martin418d93a2011-06-20 13:21:16 +0200963static int mt9p031_probe(struct i2c_client *client,
964 const struct i2c_device_id *did)
965{
Lad, Prabhakar8d4da372013-05-26 10:08:54 -0300966 struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
Javier Martin418d93a2011-06-20 13:21:16 +0200967 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
968 struct mt9p031 *mt9p031;
969 unsigned int i;
970 int ret;
971
972 if (pdata == NULL) {
973 dev_err(&client->dev, "No platform data\n");
974 return -EINVAL;
975 }
976
977 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
978 dev_warn(&client->dev,
979 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
980 return -EIO;
981 }
982
Laurent Pinchart37b9f212012-12-21 16:34:06 -0300983 mt9p031 = devm_kzalloc(&client->dev, sizeof(*mt9p031), GFP_KERNEL);
Javier Martin418d93a2011-06-20 13:21:16 +0200984 if (mt9p031 == NULL)
985 return -ENOMEM;
986
987 mt9p031->pdata = pdata;
988 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
989 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
Laurent Pinchart1c542ba2012-03-09 10:42:52 -0300990 mt9p031->model = did->driver_data;
Laurent Pinchart15693b52012-03-09 10:59:41 -0300991 mt9p031->reset = -1;
Javier Martin418d93a2011-06-20 13:21:16 +0200992
Laurent Pinchart79971962013-06-08 04:50:42 -0300993 mt9p031->regulators[0].supply = "vdd";
994 mt9p031->regulators[1].supply = "vdd_io";
995 mt9p031->regulators[2].supply = "vaa";
Laurent Pinchart97f21272012-05-08 10:10:36 -0300996
Laurent Pinchart79971962013-06-08 04:50:42 -0300997 ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators);
998 if (ret < 0) {
Laurent Pinchart97f21272012-05-08 10:10:36 -0300999 dev_err(&client->dev, "Unable to get regulators\n");
Laurent Pinchart79971962013-06-08 04:50:42 -03001000 return ret;
Laurent Pinchart97f21272012-05-08 10:10:36 -03001001 }
1002
Lad, Prabhakarb28d7012012-09-25 09:35:43 -03001003 v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
Javier Martin418d93a2011-06-20 13:21:16 +02001004
1005 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1006 V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN,
1007 MT9P031_SHUTTER_WIDTH_MAX, 1,
1008 MT9P031_SHUTTER_WIDTH_DEF);
1009 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1010 V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN,
1011 MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF);
1012 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1013 V4L2_CID_HFLIP, 0, 1, 1, 0);
1014 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1015 V4L2_CID_VFLIP, 0, 1, 1, 0);
Laurent Pinchart8d690c42012-05-09 09:55:58 -03001016 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1017 V4L2_CID_PIXEL_RATE, pdata->target_freq,
1018 pdata->target_freq, 1, pdata->target_freq);
Lad, Prabhakarb28d7012012-09-25 09:35:43 -03001019 v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1020 V4L2_CID_TEST_PATTERN,
1021 ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, 0,
1022 0, mt9p031_test_pattern_menu);
Javier Martin418d93a2011-06-20 13:21:16 +02001023
1024 for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i)
1025 v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
1026
1027 mt9p031->subdev.ctrl_handler = &mt9p031->ctrls;
1028
Laurent Pinchartdfea0012012-03-09 21:02:57 -03001029 if (mt9p031->ctrls.error) {
Javier Martin418d93a2011-06-20 13:21:16 +02001030 printk(KERN_INFO "%s: control initialization error %d\n",
1031 __func__, mt9p031->ctrls.error);
Laurent Pinchartdfea0012012-03-09 21:02:57 -03001032 ret = mt9p031->ctrls.error;
1033 goto done;
1034 }
1035
1036 mt9p031->blc_auto = v4l2_ctrl_find(&mt9p031->ctrls, V4L2_CID_BLC_AUTO);
1037 mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls,
1038 V4L2_CID_BLC_DIGITAL_OFFSET);
Javier Martin418d93a2011-06-20 13:21:16 +02001039
1040 mutex_init(&mt9p031->power_lock);
1041 v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops);
1042 mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
1043
1044 mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
1045 ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0);
1046 if (ret < 0)
1047 goto done;
1048
1049 mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1050
1051 mt9p031->crop.width = MT9P031_WINDOW_WIDTH_DEF;
1052 mt9p031->crop.height = MT9P031_WINDOW_HEIGHT_DEF;
1053 mt9p031->crop.left = MT9P031_COLUMN_START_DEF;
1054 mt9p031->crop.top = MT9P031_ROW_START_DEF;
1055
Laurent Pinchart1c542ba2012-03-09 10:42:52 -03001056 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
Javier Martin418d93a2011-06-20 13:21:16 +02001057 mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12;
1058 else
1059 mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12;
1060
1061 mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF;
1062 mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF;
1063 mt9p031->format.field = V4L2_FIELD_NONE;
1064 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
1065
Laurent Pinchart2660a222013-05-02 07:57:51 -03001066 if (gpio_is_valid(pdata->reset)) {
Laurent Pinchart37b9f212012-12-21 16:34:06 -03001067 ret = devm_gpio_request_one(&client->dev, pdata->reset,
1068 GPIOF_OUT_INIT_LOW, "mt9p031_rst");
Laurent Pinchart15693b52012-03-09 10:59:41 -03001069 if (ret < 0)
1070 goto done;
1071
1072 mt9p031->reset = pdata->reset;
1073 }
1074
Laurent Pinchartd6749252012-12-21 16:11:55 -03001075 ret = mt9p031_clk_setup(mt9p031);
Javier Martin418d93a2011-06-20 13:21:16 +02001076
1077done:
1078 if (ret < 0) {
1079 v4l2_ctrl_handler_free(&mt9p031->ctrls);
1080 media_entity_cleanup(&mt9p031->subdev.entity);
Javier Martin418d93a2011-06-20 13:21:16 +02001081 }
1082
1083 return ret;
1084}
1085
1086static int mt9p031_remove(struct i2c_client *client)
1087{
1088 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
1089 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
1090
1091 v4l2_ctrl_handler_free(&mt9p031->ctrls);
1092 v4l2_device_unregister_subdev(subdev);
1093 media_entity_cleanup(&subdev->entity);
Javier Martin418d93a2011-06-20 13:21:16 +02001094
1095 return 0;
1096}
1097
1098static const struct i2c_device_id mt9p031_id[] = {
Laurent Pinchart1c542ba2012-03-09 10:42:52 -03001099 { "mt9p031", MT9P031_MODEL_COLOR },
1100 { "mt9p031m", MT9P031_MODEL_MONOCHROME },
Javier Martin418d93a2011-06-20 13:21:16 +02001101 { }
1102};
1103MODULE_DEVICE_TABLE(i2c, mt9p031_id);
1104
Lad, Prabhakar8d4da372013-05-26 10:08:54 -03001105#if IS_ENABLED(CONFIG_OF)
1106static const struct of_device_id mt9p031_of_match[] = {
1107 { .compatible = "aptina,mt9p031", },
1108 { .compatible = "aptina,mt9p031m", },
1109 { /* sentinel */ },
1110};
1111MODULE_DEVICE_TABLE(of, mt9p031_of_match);
1112#endif
1113
Javier Martin418d93a2011-06-20 13:21:16 +02001114static struct i2c_driver mt9p031_i2c_driver = {
1115 .driver = {
Lad, Prabhakar8d4da372013-05-26 10:08:54 -03001116 .of_match_table = of_match_ptr(mt9p031_of_match),
Javier Martin418d93a2011-06-20 13:21:16 +02001117 .name = "mt9p031",
1118 },
1119 .probe = mt9p031_probe,
1120 .remove = mt9p031_remove,
1121 .id_table = mt9p031_id,
1122};
1123
Axel Linc6e8d862012-02-12 06:56:32 -03001124module_i2c_driver(mt9p031_i2c_driver);
Javier Martin418d93a2011-06-20 13:21:16 +02001125
1126MODULE_DESCRIPTION("Aptina MT9P031 Camera driver");
1127MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
1128MODULE_LICENSE("GPL v2");