aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Martin <javier.martin@vista-silicon.com>2011-06-20 07:21:16 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-11 08:49:28 -0400
commit418d93ac0be6d4a410731b80af4e836614ffe73e (patch)
tree3798de18e556a0b376f62bf29c68a812bd8ebe60
parentb98d32f7e5cfed8deeaa9054e0977333ac419349 (diff)
[media] mt9p031: Aptina (Micron) MT9P031 5MP sensor driver
The MT9P031 is a parallel 12-bit 5MP sensor from Aptina (formerly Micron) controlled through I2C. The driver creates a V4L2 subdevice. It currently supports skipping, cropping, automatic binning, and gain, exposure, h/v flip and test pattern controls. Signed-off-by: Javier Martin <javier.martin@vista-silicon.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/Kconfig7
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/mt9p031.c963
-rw-r--r--include/media/mt9p031.h19
4 files changed, 990 insertions, 0 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 6279663bd227..9da6044b4495 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -467,6 +467,13 @@ config VIDEO_OV7670
467 OV7670 VGA camera. It currently only works with the M88ALP01 467 OV7670 VGA camera. It currently only works with the M88ALP01
468 controller. 468 controller.
469 469
470config VIDEO_MT9P031
471 tristate "Aptina MT9P031 support"
472 depends on I2C && VIDEO_V4L2
473 ---help---
474 This is a Video4Linux2 sensor-level driver for the Aptina
475 (Micron) mt9p031 5 Mpixel camera.
476
470config VIDEO_MT9V011 477config VIDEO_MT9V011
471 tristate "Micron mt9v011 sensor support" 478 tristate "Micron mt9v011 sensor support"
472 depends on I2C && VIDEO_V4L2 479 depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index c06f515d2edf..f52a7712e43e 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
65obj-$(CONFIG_VIDEO_OV7670) += ov7670.o 65obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
66obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o 66obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
68obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o 69obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
69obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o 70obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
70obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 71obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
new file mode 100644
index 000000000000..5cfa39f4bf14
--- /dev/null
+++ b/drivers/media/video/mt9p031.c
@@ -0,0 +1,963 @@
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
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/i2c.h>
18#include <linux/log2.h>
19#include <linux/pm.h>
20#include <linux/slab.h>
21#include <media/v4l2-subdev.h>
22#include <linux/videodev2.h>
23
24#include <media/mt9p031.h>
25#include <media/v4l2-chip-ident.h>
26#include <media/v4l2-ctrls.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-subdev.h>
29
30#define MT9P031_PIXEL_ARRAY_WIDTH 2752
31#define MT9P031_PIXEL_ARRAY_HEIGHT 2004
32
33#define MT9P031_CHIP_VERSION 0x00
34#define MT9P031_CHIP_VERSION_VALUE 0x1801
35#define MT9P031_ROW_START 0x01
36#define MT9P031_ROW_START_MIN 0
37#define MT9P031_ROW_START_MAX 2004
38#define MT9P031_ROW_START_DEF 54
39#define MT9P031_COLUMN_START 0x02
40#define MT9P031_COLUMN_START_MIN 0
41#define MT9P031_COLUMN_START_MAX 2750
42#define MT9P031_COLUMN_START_DEF 16
43#define MT9P031_WINDOW_HEIGHT 0x03
44#define MT9P031_WINDOW_HEIGHT_MIN 2
45#define MT9P031_WINDOW_HEIGHT_MAX 2006
46#define MT9P031_WINDOW_HEIGHT_DEF 1944
47#define MT9P031_WINDOW_WIDTH 0x04
48#define MT9P031_WINDOW_WIDTH_MIN 2
49#define MT9P031_WINDOW_WIDTH_MAX 2752
50#define MT9P031_WINDOW_WIDTH_DEF 2592
51#define MT9P031_HORIZONTAL_BLANK 0x05
52#define MT9P031_HORIZONTAL_BLANK_MIN 0
53#define MT9P031_HORIZONTAL_BLANK_MAX 4095
54#define MT9P031_VERTICAL_BLANK 0x06
55#define MT9P031_VERTICAL_BLANK_MIN 0
56#define MT9P031_VERTICAL_BLANK_MAX 4095
57#define MT9P031_VERTICAL_BLANK_DEF 25
58#define MT9P031_OUTPUT_CONTROL 0x07
59#define MT9P031_OUTPUT_CONTROL_CEN 2
60#define MT9P031_OUTPUT_CONTROL_SYN 1
61#define MT9P031_OUTPUT_CONTROL_DEF 0x1f82
62#define MT9P031_SHUTTER_WIDTH_UPPER 0x08
63#define MT9P031_SHUTTER_WIDTH_LOWER 0x09
64#define MT9P031_SHUTTER_WIDTH_MIN 1
65#define MT9P031_SHUTTER_WIDTH_MAX 1048575
66#define MT9P031_SHUTTER_WIDTH_DEF 1943
67#define MT9P031_PLL_CONTROL 0x10
68#define MT9P031_PLL_CONTROL_PWROFF 0x0050
69#define MT9P031_PLL_CONTROL_PWRON 0x0051
70#define MT9P031_PLL_CONTROL_USEPLL 0x0052
71#define MT9P031_PLL_CONFIG_1 0x11
72#define MT9P031_PLL_CONFIG_2 0x12
73#define MT9P031_PIXEL_CLOCK_CONTROL 0x0a
74#define MT9P031_FRAME_RESTART 0x0b
75#define MT9P031_SHUTTER_DELAY 0x0c
76#define MT9P031_RST 0x0d
77#define MT9P031_RST_ENABLE 1
78#define MT9P031_RST_DISABLE 0
79#define MT9P031_READ_MODE_1 0x1e
80#define MT9P031_READ_MODE_2 0x20
81#define MT9P031_READ_MODE_2_ROW_MIR (1 << 15)
82#define MT9P031_READ_MODE_2_COL_MIR (1 << 14)
83#define MT9P031_READ_MODE_2_ROW_BLC (1 << 6)
84#define MT9P031_ROW_ADDRESS_MODE 0x22
85#define MT9P031_COLUMN_ADDRESS_MODE 0x23
86#define MT9P031_GLOBAL_GAIN 0x35
87#define MT9P031_GLOBAL_GAIN_MIN 8
88#define MT9P031_GLOBAL_GAIN_MAX 1024
89#define MT9P031_GLOBAL_GAIN_DEF 8
90#define MT9P031_GLOBAL_GAIN_MULT (1 << 6)
91#define MT9P031_ROW_BLACK_DEF_OFFSET 0x4b
92#define MT9P031_TEST_PATTERN 0xa0
93#define MT9P031_TEST_PATTERN_SHIFT 3
94#define MT9P031_TEST_PATTERN_ENABLE (1 << 0)
95#define MT9P031_TEST_PATTERN_DISABLE (0 << 0)
96#define MT9P031_TEST_PATTERN_GREEN 0xa1
97#define MT9P031_TEST_PATTERN_RED 0xa2
98#define MT9P031_TEST_PATTERN_BLUE 0xa3
99
100struct mt9p031_pll_divs {
101 u32 ext_freq;
102 u32 target_freq;
103 u8 m;
104 u8 n;
105 u8 p1;
106};
107
108struct mt9p031 {
109 struct v4l2_subdev subdev;
110 struct media_pad pad;
111 struct v4l2_rect crop; /* Sensor window */
112 struct v4l2_mbus_framefmt format;
113 struct v4l2_ctrl_handler ctrls;
114 struct mt9p031_platform_data *pdata;
115 struct mutex power_lock; /* lock to protect power_count */
116 int power_count;
117 u16 xskip;
118 u16 yskip;
119
120 const struct mt9p031_pll_divs *pll;
121
122 /* Registers cache */
123 u16 output_control;
124 u16 mode2;
125};
126
127static struct mt9p031 *to_mt9p031(struct v4l2_subdev *sd)
128{
129 return container_of(sd, struct mt9p031, subdev);
130}
131
132static int mt9p031_read(struct i2c_client *client, u8 reg)
133{
134 s32 data = i2c_smbus_read_word_data(client, reg);
135 return data < 0 ? data : be16_to_cpu(data);
136}
137
138static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data)
139{
140 return i2c_smbus_write_word_data(client, reg, cpu_to_be16(data));
141}
142
143static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear,
144 u16 set)
145{
146 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
147 u16 value = (mt9p031->output_control & ~clear) | set;
148 int ret;
149
150 ret = mt9p031_write(client, MT9P031_OUTPUT_CONTROL, value);
151 if (ret < 0)
152 return ret;
153
154 mt9p031->output_control = value;
155 return 0;
156}
157
158static int mt9p031_set_mode2(struct mt9p031 *mt9p031, u16 clear, u16 set)
159{
160 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
161 u16 value = (mt9p031->mode2 & ~clear) | set;
162 int ret;
163
164 ret = mt9p031_write(client, MT9P031_READ_MODE_2, value);
165 if (ret < 0)
166 return ret;
167
168 mt9p031->mode2 = value;
169 return 0;
170}
171
172static int mt9p031_reset(struct mt9p031 *mt9p031)
173{
174 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
175 int ret;
176
177 /* Disable chip output, synchronous option update */
178 ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_ENABLE);
179 if (ret < 0)
180 return ret;
181 ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_DISABLE);
182 if (ret < 0)
183 return ret;
184
185 return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
186 0);
187}
188
189/*
190 * This static table uses ext_freq and vdd_io values to select suitable
191 * PLL dividers m, n and p1 which have been calculated as specifiec in p36
192 * of Aptina's mt9p031 datasheet. New values should be added here.
193 */
194static const struct mt9p031_pll_divs mt9p031_divs[] = {
195 /* ext_freq target_freq m n p1 */
196 {21000000, 48000000, 26, 2, 6}
197};
198
199static int mt9p031_pll_get_divs(struct mt9p031 *mt9p031)
200{
201 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
202 int i;
203
204 for (i = 0; i < ARRAY_SIZE(mt9p031_divs); i++) {
205 if (mt9p031_divs[i].ext_freq == mt9p031->pdata->ext_freq &&
206 mt9p031_divs[i].target_freq == mt9p031->pdata->target_freq) {
207 mt9p031->pll = &mt9p031_divs[i];
208 return 0;
209 }
210 }
211
212 dev_err(&client->dev, "Couldn't find PLL dividers for ext_freq = %d, "
213 "target_freq = %d\n", mt9p031->pdata->ext_freq,
214 mt9p031->pdata->target_freq);
215 return -EINVAL;
216}
217
218static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
219{
220 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
221 int ret;
222
223 ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
224 MT9P031_PLL_CONTROL_PWRON);
225 if (ret < 0)
226 return ret;
227
228 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1,
229 (mt9p031->pll->m << 8) | (mt9p031->pll->n - 1));
230 if (ret < 0)
231 return ret;
232
233 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll->p1 - 1);
234 if (ret < 0)
235 return ret;
236
237 usleep_range(1000, 2000);
238 ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
239 MT9P031_PLL_CONTROL_PWRON |
240 MT9P031_PLL_CONTROL_USEPLL);
241 return ret;
242}
243
244static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
245{
246 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
247
248 return mt9p031_write(client, MT9P031_PLL_CONTROL,
249 MT9P031_PLL_CONTROL_PWROFF);
250}
251
252static int mt9p031_power_on(struct mt9p031 *mt9p031)
253{
254 /* Ensure RESET_BAR is low */
255 if (mt9p031->pdata->reset) {
256 mt9p031->pdata->reset(&mt9p031->subdev, 1);
257 usleep_range(1000, 2000);
258 }
259
260 /* Emable clock */
261 if (mt9p031->pdata->set_xclk)
262 mt9p031->pdata->set_xclk(&mt9p031->subdev,
263 mt9p031->pdata->ext_freq);
264
265 /* Now RESET_BAR must be high */
266 if (mt9p031->pdata->reset) {
267 mt9p031->pdata->reset(&mt9p031->subdev, 0);
268 usleep_range(1000, 2000);
269 }
270
271 return 0;
272}
273
274static void mt9p031_power_off(struct mt9p031 *mt9p031)
275{
276 if (mt9p031->pdata->reset) {
277 mt9p031->pdata->reset(&mt9p031->subdev, 1);
278 usleep_range(1000, 2000);
279 }
280
281 if (mt9p031->pdata->set_xclk)
282 mt9p031->pdata->set_xclk(&mt9p031->subdev, 0);
283}
284
285static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
286{
287 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
288 int ret;
289
290 if (!on) {
291 mt9p031_power_off(mt9p031);
292 return 0;
293 }
294
295 ret = mt9p031_power_on(mt9p031);
296 if (ret < 0)
297 return ret;
298
299 ret = mt9p031_reset(mt9p031);
300 if (ret < 0) {
301 dev_err(&client->dev, "Failed to reset the camera\n");
302 return ret;
303 }
304
305 return v4l2_ctrl_handler_setup(&mt9p031->ctrls);
306}
307
308/* -----------------------------------------------------------------------------
309 * V4L2 subdev video operations
310 */
311
312static int mt9p031_set_params(struct mt9p031 *mt9p031)
313{
314 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
315 struct v4l2_mbus_framefmt *format = &mt9p031->format;
316 const struct v4l2_rect *crop = &mt9p031->crop;
317 unsigned int hblank;
318 unsigned int vblank;
319 unsigned int xskip;
320 unsigned int yskip;
321 unsigned int xbin;
322 unsigned int ybin;
323 int ret;
324
325 /* Windows position and size.
326 *
327 * TODO: Make sure the start coordinates and window size match the
328 * skipping, binning and mirroring (see description of registers 2 and 4
329 * in table 13, and Binning section on page 41).
330 */
331 ret = mt9p031_write(client, MT9P031_COLUMN_START, crop->left);
332 if (ret < 0)
333 return ret;
334 ret = mt9p031_write(client, MT9P031_ROW_START, crop->top);
335 if (ret < 0)
336 return ret;
337 ret = mt9p031_write(client, MT9P031_WINDOW_WIDTH, crop->width - 1);
338 if (ret < 0)
339 return ret;
340 ret = mt9p031_write(client, MT9P031_WINDOW_HEIGHT, crop->height - 1);
341 if (ret < 0)
342 return ret;
343
344 /* Row and column binning and skipping. Use the maximum binning value
345 * compatible with the skipping settings.
346 */
347 xskip = DIV_ROUND_CLOSEST(crop->width, format->width);
348 yskip = DIV_ROUND_CLOSEST(crop->height, format->height);
349 xbin = 1 << (ffs(xskip) - 1);
350 ybin = 1 << (ffs(yskip) - 1);
351
352 ret = mt9p031_write(client, MT9P031_COLUMN_ADDRESS_MODE,
353 ((xbin - 1) << 4) | (xskip - 1));
354 if (ret < 0)
355 return ret;
356 ret = mt9p031_write(client, MT9P031_ROW_ADDRESS_MODE,
357 ((ybin - 1) << 4) | (yskip - 1));
358 if (ret < 0)
359 return ret;
360
361 /* Blanking - use minimum value for horizontal blanking and default
362 * value for vertical blanking.
363 */
364 hblank = 346 * ybin + 64 + (80 >> max_t(unsigned int, xbin, 3));
365 vblank = MT9P031_VERTICAL_BLANK_DEF;
366
367 ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank);
368 if (ret < 0)
369 return ret;
370 ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank);
371 if (ret < 0)
372 return ret;
373
374 return ret;
375}
376
377static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
378{
379 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
380 int ret;
381
382 if (!enable) {
383 /* Stop sensor readout */
384 ret = mt9p031_set_output_control(mt9p031,
385 MT9P031_OUTPUT_CONTROL_CEN, 0);
386 if (ret < 0)
387 return ret;
388
389 return mt9p031_pll_disable(mt9p031);
390 }
391
392 ret = mt9p031_set_params(mt9p031);
393 if (ret < 0)
394 return ret;
395
396 /* Switch to master "normal" mode */
397 ret = mt9p031_set_output_control(mt9p031, 0,
398 MT9P031_OUTPUT_CONTROL_CEN);
399 if (ret < 0)
400 return ret;
401
402 return mt9p031_pll_enable(mt9p031);
403}
404
405static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev,
406 struct v4l2_subdev_fh *fh,
407 struct v4l2_subdev_mbus_code_enum *code)
408{
409 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
410
411 if (code->pad || code->index)
412 return -EINVAL;
413
414 code->code = mt9p031->format.code;
415 return 0;
416}
417
418static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev,
419 struct v4l2_subdev_fh *fh,
420 struct v4l2_subdev_frame_size_enum *fse)
421{
422 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
423
424 if (fse->index >= 8 || fse->code != mt9p031->format.code)
425 return -EINVAL;
426
427 fse->min_width = MT9P031_WINDOW_WIDTH_DEF
428 / min_t(unsigned int, 7, fse->index + 1);
429 fse->max_width = fse->min_width;
430 fse->min_height = MT9P031_WINDOW_HEIGHT_DEF / (fse->index + 1);
431 fse->max_height = fse->min_height;
432
433 return 0;
434}
435
436static struct v4l2_mbus_framefmt *
437__mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh,
438 unsigned int pad, u32 which)
439{
440 switch (which) {
441 case V4L2_SUBDEV_FORMAT_TRY:
442 return v4l2_subdev_get_try_format(fh, pad);
443 case V4L2_SUBDEV_FORMAT_ACTIVE:
444 return &mt9p031->format;
445 default:
446 return NULL;
447 }
448}
449
450static struct v4l2_rect *
451__mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh,
452 unsigned int pad, u32 which)
453{
454 switch (which) {
455 case V4L2_SUBDEV_FORMAT_TRY:
456 return v4l2_subdev_get_try_crop(fh, pad);
457 case V4L2_SUBDEV_FORMAT_ACTIVE:
458 return &mt9p031->crop;
459 default:
460 return NULL;
461 }
462}
463
464static int mt9p031_get_format(struct v4l2_subdev *subdev,
465 struct v4l2_subdev_fh *fh,
466 struct v4l2_subdev_format *fmt)
467{
468 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
469
470 fmt->format = *__mt9p031_get_pad_format(mt9p031, fh, fmt->pad,
471 fmt->which);
472 return 0;
473}
474
475static int mt9p031_set_format(struct v4l2_subdev *subdev,
476 struct v4l2_subdev_fh *fh,
477 struct v4l2_subdev_format *format)
478{
479 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
480 struct v4l2_mbus_framefmt *__format;
481 struct v4l2_rect *__crop;
482 unsigned int width;
483 unsigned int height;
484 unsigned int hratio;
485 unsigned int vratio;
486
487 __crop = __mt9p031_get_pad_crop(mt9p031, fh, format->pad,
488 format->which);
489
490 /* Clamp the width and height to avoid dividing by zero. */
491 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
492 max(__crop->width / 7, MT9P031_WINDOW_WIDTH_MIN),
493 __crop->width);
494 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
495 max(__crop->height / 8, MT9P031_WINDOW_HEIGHT_MIN),
496 __crop->height);
497
498 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
499 vratio = DIV_ROUND_CLOSEST(__crop->height, height);
500
501 __format = __mt9p031_get_pad_format(mt9p031, fh, format->pad,
502 format->which);
503 __format->width = __crop->width / hratio;
504 __format->height = __crop->height / vratio;
505
506 format->format = *__format;
507
508 return 0;
509}
510
511static int mt9p031_get_crop(struct v4l2_subdev *subdev,
512 struct v4l2_subdev_fh *fh,
513 struct v4l2_subdev_crop *crop)
514{
515 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
516
517 crop->rect = *__mt9p031_get_pad_crop(mt9p031, fh, crop->pad,
518 crop->which);
519 return 0;
520}
521
522static int mt9p031_set_crop(struct v4l2_subdev *subdev,
523 struct v4l2_subdev_fh *fh,
524 struct v4l2_subdev_crop *crop)
525{
526 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
527 struct v4l2_mbus_framefmt *__format;
528 struct v4l2_rect *__crop;
529 struct v4l2_rect rect;
530
531 /* Clamp the crop rectangle boundaries and align them to a multiple of 2
532 * pixels to ensure a GRBG Bayer pattern.
533 */
534 rect.left = clamp(ALIGN(crop->rect.left, 2), MT9P031_COLUMN_START_MIN,
535 MT9P031_COLUMN_START_MAX);
536 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9P031_ROW_START_MIN,
537 MT9P031_ROW_START_MAX);
538 rect.width = clamp(ALIGN(crop->rect.width, 2),
539 MT9P031_WINDOW_WIDTH_MIN,
540 MT9P031_WINDOW_WIDTH_MAX);
541 rect.height = clamp(ALIGN(crop->rect.height, 2),
542 MT9P031_WINDOW_HEIGHT_MIN,
543 MT9P031_WINDOW_HEIGHT_MAX);
544
545 rect.width = min(rect.width, MT9P031_PIXEL_ARRAY_WIDTH - rect.left);
546 rect.height = min(rect.height, MT9P031_PIXEL_ARRAY_HEIGHT - rect.top);
547
548 __crop = __mt9p031_get_pad_crop(mt9p031, fh, crop->pad, crop->which);
549
550 if (rect.width != __crop->width || rect.height != __crop->height) {
551 /* Reset the output image size if the crop rectangle size has
552 * been modified.
553 */
554 __format = __mt9p031_get_pad_format(mt9p031, fh, crop->pad,
555 crop->which);
556 __format->width = rect.width;
557 __format->height = rect.height;
558 }
559
560 *__crop = rect;
561 crop->rect = rect;
562
563 return 0;
564}
565
566/* -----------------------------------------------------------------------------
567 * V4L2 subdev control operations
568 */
569
570#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
571
572static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
573{
574 struct mt9p031 *mt9p031 =
575 container_of(ctrl->handler, struct mt9p031, ctrls);
576 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
577 u16 data;
578 int ret;
579
580 switch (ctrl->id) {
581 case V4L2_CID_EXPOSURE:
582 ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
583 (ctrl->val >> 16) & 0xffff);
584 if (ret < 0)
585 return ret;
586
587 return mt9p031_write(client, MT9P031_SHUTTER_WIDTH_LOWER,
588 ctrl->val & 0xffff);
589
590 case V4L2_CID_GAIN:
591 /* Gain is controlled by 2 analog stages and a digital stage.
592 * Valid values for the 3 stages are
593 *
594 * Stage Min Max Step
595 * ------------------------------------------
596 * First analog stage x1 x2 1
597 * Second analog stage x1 x4 0.125
598 * Digital stage x1 x16 0.125
599 *
600 * To minimize noise, the gain stages should be used in the
601 * second analog stage, first analog stage, digital stage order.
602 * Gain from a previous stage should be pushed to its maximum
603 * value before the next stage is used.
604 */
605 if (ctrl->val <= 32) {
606 data = ctrl->val;
607 } else if (ctrl->val <= 64) {
608 ctrl->val &= ~1;
609 data = (1 << 6) | (ctrl->val >> 1);
610 } else {
611 ctrl->val &= ~7;
612 data = ((ctrl->val - 64) << 5) | (1 << 6) | 32;
613 }
614
615 return mt9p031_write(client, MT9P031_GLOBAL_GAIN, data);
616
617 case V4L2_CID_HFLIP:
618 if (ctrl->val)
619 return mt9p031_set_mode2(mt9p031,
620 0, MT9P031_READ_MODE_2_COL_MIR);
621 else
622 return mt9p031_set_mode2(mt9p031,
623 MT9P031_READ_MODE_2_COL_MIR, 0);
624
625 case V4L2_CID_VFLIP:
626 if (ctrl->val)
627 return mt9p031_set_mode2(mt9p031,
628 0, MT9P031_READ_MODE_2_ROW_MIR);
629 else
630 return mt9p031_set_mode2(mt9p031,
631 MT9P031_READ_MODE_2_ROW_MIR, 0);
632
633 case V4L2_CID_TEST_PATTERN:
634 if (!ctrl->val) {
635 ret = mt9p031_set_mode2(mt9p031,
636 0, MT9P031_READ_MODE_2_ROW_BLC);
637 if (ret < 0)
638 return ret;
639
640 return mt9p031_write(client, MT9P031_TEST_PATTERN,
641 MT9P031_TEST_PATTERN_DISABLE);
642 }
643
644 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_GREEN, 0x05a0);
645 if (ret < 0)
646 return ret;
647 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_RED, 0x0a50);
648 if (ret < 0)
649 return ret;
650 ret = mt9p031_write(client, MT9P031_TEST_PATTERN_BLUE, 0x0aa0);
651 if (ret < 0)
652 return ret;
653
654 ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
655 0);
656 if (ret < 0)
657 return ret;
658 ret = mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET, 0);
659 if (ret < 0)
660 return ret;
661
662 return mt9p031_write(client, MT9P031_TEST_PATTERN,
663 ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT)
664 | MT9P031_TEST_PATTERN_ENABLE);
665 }
666 return 0;
667}
668
669static struct v4l2_ctrl_ops mt9p031_ctrl_ops = {
670 .s_ctrl = mt9p031_s_ctrl,
671};
672
673static const char * const mt9p031_test_pattern_menu[] = {
674 "Disabled",
675 "Color Field",
676 "Horizontal Gradient",
677 "Vertical Gradient",
678 "Diagonal Gradient",
679 "Classic Test Pattern",
680 "Walking 1s",
681 "Monochrome Horizontal Bars",
682 "Monochrome Vertical Bars",
683 "Vertical Color Bars",
684};
685
686static const struct v4l2_ctrl_config mt9p031_ctrls[] = {
687 {
688 .ops = &mt9p031_ctrl_ops,
689 .id = V4L2_CID_TEST_PATTERN,
690 .type = V4L2_CTRL_TYPE_MENU,
691 .name = "Test Pattern",
692 .min = 0,
693 .max = ARRAY_SIZE(mt9p031_test_pattern_menu) - 1,
694 .step = 0,
695 .def = 0,
696 .flags = 0,
697 .menu_skip_mask = 0,
698 .qmenu = mt9p031_test_pattern_menu,
699 }
700};
701
702/* -----------------------------------------------------------------------------
703 * V4L2 subdev core operations
704 */
705
706static int mt9p031_set_power(struct v4l2_subdev *subdev, int on)
707{
708 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
709 int ret = 0;
710
711 mutex_lock(&mt9p031->power_lock);
712
713 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
714 * update the power state.
715 */
716 if (mt9p031->power_count == !on) {
717 ret = __mt9p031_set_power(mt9p031, !!on);
718 if (ret < 0)
719 goto out;
720 }
721
722 /* Update the power count. */
723 mt9p031->power_count += on ? 1 : -1;
724 WARN_ON(mt9p031->power_count < 0);
725
726out:
727 mutex_unlock(&mt9p031->power_lock);
728 return ret;
729}
730
731/* -----------------------------------------------------------------------------
732 * V4L2 subdev internal operations
733 */
734
735static int mt9p031_registered(struct v4l2_subdev *subdev)
736{
737 struct i2c_client *client = v4l2_get_subdevdata(subdev);
738 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
739 s32 data;
740 int ret;
741
742 ret = mt9p031_power_on(mt9p031);
743 if (ret < 0) {
744 dev_err(&client->dev, "MT9P031 power up failed\n");
745 return ret;
746 }
747
748 /* Read out the chip version register */
749 data = mt9p031_read(client, MT9P031_CHIP_VERSION);
750 if (data != MT9P031_CHIP_VERSION_VALUE) {
751 dev_err(&client->dev, "MT9P031 not detected, wrong version "
752 "0x%04x\n", data);
753 return -ENODEV;
754 }
755
756 mt9p031_power_off(mt9p031);
757
758 dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
759 client->addr);
760
761 return ret;
762}
763
764static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
765{
766 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
767 struct v4l2_mbus_framefmt *format;
768 struct v4l2_rect *crop;
769
770 crop = v4l2_subdev_get_try_crop(fh, 0);
771 crop->left = MT9P031_COLUMN_START_DEF;
772 crop->top = MT9P031_ROW_START_DEF;
773 crop->width = MT9P031_WINDOW_WIDTH_DEF;
774 crop->height = MT9P031_WINDOW_HEIGHT_DEF;
775
776 format = v4l2_subdev_get_try_format(fh, 0);
777
778 if (mt9p031->pdata->version == MT9P031_MONOCHROME_VERSION)
779 format->code = V4L2_MBUS_FMT_Y12_1X12;
780 else
781 format->code = V4L2_MBUS_FMT_SGRBG12_1X12;
782
783 format->width = MT9P031_WINDOW_WIDTH_DEF;
784 format->height = MT9P031_WINDOW_HEIGHT_DEF;
785 format->field = V4L2_FIELD_NONE;
786 format->colorspace = V4L2_COLORSPACE_SRGB;
787
788 mt9p031->xskip = 1;
789 mt9p031->yskip = 1;
790 return mt9p031_set_power(subdev, 1);
791}
792
793static int mt9p031_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
794{
795 return mt9p031_set_power(subdev, 0);
796}
797
798static struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = {
799 .s_power = mt9p031_set_power,
800};
801
802static struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
803 .s_stream = mt9p031_s_stream,
804};
805
806static struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
807 .enum_mbus_code = mt9p031_enum_mbus_code,
808 .enum_frame_size = mt9p031_enum_frame_size,
809 .get_fmt = mt9p031_get_format,
810 .set_fmt = mt9p031_set_format,
811 .get_crop = mt9p031_get_crop,
812 .set_crop = mt9p031_set_crop,
813};
814
815static struct v4l2_subdev_ops mt9p031_subdev_ops = {
816 .core = &mt9p031_subdev_core_ops,
817 .video = &mt9p031_subdev_video_ops,
818 .pad = &mt9p031_subdev_pad_ops,
819};
820
821static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
822 .registered = mt9p031_registered,
823 .open = mt9p031_open,
824 .close = mt9p031_close,
825};
826
827/* -----------------------------------------------------------------------------
828 * Driver initialization and probing
829 */
830
831static int mt9p031_probe(struct i2c_client *client,
832 const struct i2c_device_id *did)
833{
834 struct mt9p031_platform_data *pdata = client->dev.platform_data;
835 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
836 struct mt9p031 *mt9p031;
837 unsigned int i;
838 int ret;
839
840 if (pdata == NULL) {
841 dev_err(&client->dev, "No platform data\n");
842 return -EINVAL;
843 }
844
845 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
846 dev_warn(&client->dev,
847 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
848 return -EIO;
849 }
850
851 mt9p031 = kzalloc(sizeof(*mt9p031), GFP_KERNEL);
852 if (mt9p031 == NULL)
853 return -ENOMEM;
854
855 mt9p031->pdata = pdata;
856 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
857 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
858
859 v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4);
860
861 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
862 V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN,
863 MT9P031_SHUTTER_WIDTH_MAX, 1,
864 MT9P031_SHUTTER_WIDTH_DEF);
865 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
866 V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN,
867 MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF);
868 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
869 V4L2_CID_HFLIP, 0, 1, 1, 0);
870 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
871 V4L2_CID_VFLIP, 0, 1, 1, 0);
872
873 for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i)
874 v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
875
876 mt9p031->subdev.ctrl_handler = &mt9p031->ctrls;
877
878 if (mt9p031->ctrls.error)
879 printk(KERN_INFO "%s: control initialization error %d\n",
880 __func__, mt9p031->ctrls.error);
881
882 mutex_init(&mt9p031->power_lock);
883 v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops);
884 mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
885
886 mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
887 ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0);
888 if (ret < 0)
889 goto done;
890
891 mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
892
893 mt9p031->crop.width = MT9P031_WINDOW_WIDTH_DEF;
894 mt9p031->crop.height = MT9P031_WINDOW_HEIGHT_DEF;
895 mt9p031->crop.left = MT9P031_COLUMN_START_DEF;
896 mt9p031->crop.top = MT9P031_ROW_START_DEF;
897
898 if (mt9p031->pdata->version == MT9P031_MONOCHROME_VERSION)
899 mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12;
900 else
901 mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12;
902
903 mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF;
904 mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF;
905 mt9p031->format.field = V4L2_FIELD_NONE;
906 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
907
908 ret = mt9p031_pll_get_divs(mt9p031);
909
910done:
911 if (ret < 0) {
912 v4l2_ctrl_handler_free(&mt9p031->ctrls);
913 media_entity_cleanup(&mt9p031->subdev.entity);
914 kfree(mt9p031);
915 }
916
917 return ret;
918}
919
920static int mt9p031_remove(struct i2c_client *client)
921{
922 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
923 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
924
925 v4l2_ctrl_handler_free(&mt9p031->ctrls);
926 v4l2_device_unregister_subdev(subdev);
927 media_entity_cleanup(&subdev->entity);
928 kfree(mt9p031);
929
930 return 0;
931}
932
933static const struct i2c_device_id mt9p031_id[] = {
934 { "mt9p031", 0 },
935 { }
936};
937MODULE_DEVICE_TABLE(i2c, mt9p031_id);
938
939static struct i2c_driver mt9p031_i2c_driver = {
940 .driver = {
941 .name = "mt9p031",
942 },
943 .probe = mt9p031_probe,
944 .remove = mt9p031_remove,
945 .id_table = mt9p031_id,
946};
947
948static int __init mt9p031_mod_init(void)
949{
950 return i2c_add_driver(&mt9p031_i2c_driver);
951}
952
953static void __exit mt9p031_mod_exit(void)
954{
955 i2c_del_driver(&mt9p031_i2c_driver);
956}
957
958module_init(mt9p031_mod_init);
959module_exit(mt9p031_mod_exit);
960
961MODULE_DESCRIPTION("Aptina MT9P031 Camera driver");
962MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
963MODULE_LICENSE("GPL v2");
diff --git a/include/media/mt9p031.h b/include/media/mt9p031.h
new file mode 100644
index 000000000000..96448c7a318b
--- /dev/null
+++ b/include/media/mt9p031.h
@@ -0,0 +1,19 @@
1#ifndef MT9P031_H
2#define MT9P031_H
3
4struct v4l2_subdev;
5
6enum {
7 MT9P031_COLOR_VERSION,
8 MT9P031_MONOCHROME_VERSION,
9};
10
11struct mt9p031_platform_data {
12 int (*set_xclk)(struct v4l2_subdev *subdev, int hz);
13 int (*reset)(struct v4l2_subdev *subdev, int active);
14 int ext_freq; /* input frequency to the mt9p031 for PLL dividers */
15 int target_freq; /* frequency target for the PLL */
16 int version; /* MT9P031_COLOR_VERSION or MT9P031_MONOCHROME_VERSION */
17};
18
19#endif