2 * Driver for the mt9m111 sensor
4 * Copyright (C) 2008 Erik Andrén
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include "m5602_mt9m111.h"
23 static int mt9m111_s_ctrl(struct v4l2_ctrl
*ctrl
);
24 static void mt9m111_dump_registers(struct sd
*sd
);
26 static struct v4l2_pix_format mt9m111_modes
[] = {
32 .sizeimage
= 640 * 480,
34 .colorspace
= V4L2_COLORSPACE_SRGB
,
39 static const struct v4l2_ctrl_ops mt9m111_ctrl_ops
= {
40 .s_ctrl
= mt9m111_s_ctrl
,
43 static const struct v4l2_ctrl_config mt9m111_greenbal_cfg
= {
44 .ops
= &mt9m111_ctrl_ops
,
45 .id
= M5602_V4L2_CID_GREEN_BALANCE
,
46 .name
= "Green Balance",
47 .type
= V4L2_CTRL_TYPE_INTEGER
,
51 .def
= MT9M111_GREEN_GAIN_DEFAULT
,
52 .flags
= V4L2_CTRL_FLAG_SLIDER
,
55 int mt9m111_probe(struct sd
*sd
)
57 u8 data
[2] = {0x00, 0x00};
59 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)sd
;
62 if (force_sensor
== MT9M111_SENSOR
) {
63 pr_info("Forcing a %s sensor\n", mt9m111
.name
);
66 /* If we want to force another sensor, don't try to probe this
71 PDEBUG(D_PROBE
, "Probing for a mt9m111 sensor");
74 for (i
= 0; i
< ARRAY_SIZE(preinit_mt9m111
); i
++) {
75 if (preinit_mt9m111
[i
][0] == BRIDGE
) {
76 m5602_write_bridge(sd
,
77 preinit_mt9m111
[i
][1],
78 preinit_mt9m111
[i
][2]);
80 data
[0] = preinit_mt9m111
[i
][2];
81 data
[1] = preinit_mt9m111
[i
][3];
82 m5602_write_sensor(sd
,
83 preinit_mt9m111
[i
][1], data
, 2);
87 if (m5602_read_sensor(sd
, MT9M111_SC_CHIPVER
, data
, 2))
90 if ((data
[0] == 0x14) && (data
[1] == 0x3a)) {
91 pr_info("Detected a mt9m111 sensor\n");
98 sd
->gspca_dev
.cam
.cam_mode
= mt9m111_modes
;
99 sd
->gspca_dev
.cam
.nmodes
= ARRAY_SIZE(mt9m111_modes
);
104 int mt9m111_init(struct sd
*sd
)
108 /* Init the sensor */
109 for (i
= 0; i
< ARRAY_SIZE(init_mt9m111
) && !err
; i
++) {
112 if (init_mt9m111
[i
][0] == BRIDGE
) {
113 err
= m5602_write_bridge(sd
,
117 data
[0] = init_mt9m111
[i
][2];
118 data
[1] = init_mt9m111
[i
][3];
119 err
= m5602_write_sensor(sd
,
120 init_mt9m111
[i
][1], data
, 2);
125 mt9m111_dump_registers(sd
);
130 int mt9m111_init_controls(struct sd
*sd
)
132 struct v4l2_ctrl_handler
*hdl
= &sd
->gspca_dev
.ctrl_handler
;
134 sd
->gspca_dev
.vdev
.ctrl_handler
= hdl
;
135 v4l2_ctrl_handler_init(hdl
, 7);
137 sd
->auto_white_bal
= v4l2_ctrl_new_std(hdl
, &mt9m111_ctrl_ops
,
138 V4L2_CID_AUTO_WHITE_BALANCE
,
140 sd
->green_bal
= v4l2_ctrl_new_custom(hdl
, &mt9m111_greenbal_cfg
, NULL
);
141 sd
->red_bal
= v4l2_ctrl_new_std(hdl
, &mt9m111_ctrl_ops
,
142 V4L2_CID_RED_BALANCE
, 0, 0x7ff, 1,
143 MT9M111_RED_GAIN_DEFAULT
);
144 sd
->blue_bal
= v4l2_ctrl_new_std(hdl
, &mt9m111_ctrl_ops
,
145 V4L2_CID_BLUE_BALANCE
, 0, 0x7ff, 1,
146 MT9M111_BLUE_GAIN_DEFAULT
);
148 v4l2_ctrl_new_std(hdl
, &mt9m111_ctrl_ops
, V4L2_CID_GAIN
, 0,
149 (INITIAL_MAX_GAIN
- 1) * 2 * 2 * 2, 1,
150 MT9M111_DEFAULT_GAIN
);
152 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &mt9m111_ctrl_ops
, V4L2_CID_HFLIP
,
154 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &mt9m111_ctrl_ops
, V4L2_CID_VFLIP
,
158 pr_err("Could not initialize controls\n");
162 v4l2_ctrl_auto_cluster(4, &sd
->auto_white_bal
, 0, false);
163 v4l2_ctrl_cluster(2, &sd
->hflip
);
168 int mt9m111_start(struct sd
*sd
)
172 struct cam
*cam
= &sd
->gspca_dev
.cam
;
173 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)sd
;
175 int width
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].width
- 1;
176 int height
= cam
->cam_mode
[sd
->gspca_dev
.curr_mode
].height
;
178 for (i
= 0; i
< ARRAY_SIZE(start_mt9m111
) && !err
; i
++) {
179 if (start_mt9m111
[i
][0] == BRIDGE
) {
180 err
= m5602_write_bridge(sd
,
182 start_mt9m111
[i
][2]);
184 data
[0] = start_mt9m111
[i
][2];
185 data
[1] = start_mt9m111
[i
][3];
186 err
= m5602_write_sensor(sd
,
187 start_mt9m111
[i
][1], data
, 2);
193 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
>> 8) & 0xff);
197 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, (height
& 0xff));
201 for (i
= 0; i
< 2 && !err
; i
++)
202 err
= m5602_write_bridge(sd
, M5602_XB_VSYNC_PARA
, 0);
206 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 0);
210 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 2);
214 for (i
= 0; i
< 2 && !err
; i
++)
215 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
, 0);
219 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
,
220 (width
>> 8) & 0xff);
224 err
= m5602_write_bridge(sd
, M5602_XB_HSYNC_PARA
, width
& 0xff);
228 err
= m5602_write_bridge(sd
, M5602_XB_SIG_INI
, 0);
234 PDEBUG(D_CONF
, "Configuring camera for VGA mode");
238 PDEBUG(D_CONF
, "Configuring camera for QVGA mode");
244 void mt9m111_disconnect(struct sd
*sd
)
249 static int mt9m111_set_hvflip(struct gspca_dev
*gspca_dev
)
252 u8 data
[2] = {0x00, 0x00};
253 struct sd
*sd
= (struct sd
*) gspca_dev
;
257 PDEBUG(D_CONF
, "Set hvflip to %d %d", sd
->hflip
->val
, sd
->vflip
->val
);
259 /* The mt9m111 is flipped by default */
260 hflip
= !sd
->hflip
->val
;
261 vflip
= !sd
->vflip
->val
;
263 /* Set the correct page map */
264 err
= m5602_write_sensor(sd
, MT9M111_PAGE_MAP
, data
, 2);
268 data
[0] = MT9M111_RMB_OVER_SIZED
;
269 if (gspca_dev
->pixfmt
.width
== 640) {
270 data
[1] = MT9M111_RMB_ROW_SKIP_2X
|
271 MT9M111_RMB_COLUMN_SKIP_2X
|
272 (hflip
<< 1) | vflip
;
274 data
[1] = MT9M111_RMB_ROW_SKIP_4X
|
275 MT9M111_RMB_COLUMN_SKIP_4X
|
276 (hflip
<< 1) | vflip
;
278 err
= m5602_write_sensor(sd
, MT9M111_SC_R_MODE_CONTEXT_B
,
283 static int mt9m111_set_auto_white_balance(struct gspca_dev
*gspca_dev
,
286 struct sd
*sd
= (struct sd
*) gspca_dev
;
290 err
= m5602_read_sensor(sd
, MT9M111_CP_OPERATING_MODE_CTL
, data
, 2);
294 data
[1] = ((data
[1] & 0xfd) | ((val
& 0x01) << 1));
296 err
= m5602_write_sensor(sd
, MT9M111_CP_OPERATING_MODE_CTL
, data
, 2);
298 PDEBUG(D_CONF
, "Set auto white balance %d", val
);
302 static int mt9m111_set_gain(struct gspca_dev
*gspca_dev
, __s32 val
)
305 u8 data
[2] = {0x00, 0x00};
306 struct sd
*sd
= (struct sd
*) gspca_dev
;
308 /* Set the correct page map */
309 err
= m5602_write_sensor(sd
, MT9M111_PAGE_MAP
, data
, 2);
313 if (val
>= INITIAL_MAX_GAIN
* 2 * 2 * 2)
316 if ((val
>= INITIAL_MAX_GAIN
* 2 * 2) &&
317 (val
< (INITIAL_MAX_GAIN
- 1) * 2 * 2 * 2))
318 tmp
= (1 << 10) | (val
<< 9) |
319 (val
<< 8) | (val
/ 8);
320 else if ((val
>= INITIAL_MAX_GAIN
* 2) &&
321 (val
< INITIAL_MAX_GAIN
* 2 * 2))
322 tmp
= (1 << 9) | (1 << 8) | (val
/ 4);
323 else if ((val
>= INITIAL_MAX_GAIN
) &&
324 (val
< INITIAL_MAX_GAIN
* 2))
325 tmp
= (1 << 8) | (val
/ 2);
329 data
[1] = (tmp
& 0xff);
330 data
[0] = (tmp
& 0xff00) >> 8;
331 PDEBUG(D_CONF
, "tmp=%d, data[1]=%d, data[0]=%d", tmp
,
334 err
= m5602_write_sensor(sd
, MT9M111_SC_GLOBAL_GAIN
,
340 static int mt9m111_set_green_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
344 struct sd
*sd
= (struct sd
*) gspca_dev
;
346 data
[1] = (val
& 0xff);
347 data
[0] = (val
& 0xff00) >> 8;
349 PDEBUG(D_CONF
, "Set green balance %d", val
);
350 err
= m5602_write_sensor(sd
, MT9M111_SC_GREEN_1_GAIN
,
355 return m5602_write_sensor(sd
, MT9M111_SC_GREEN_2_GAIN
,
359 static int mt9m111_set_blue_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
362 struct sd
*sd
= (struct sd
*) gspca_dev
;
364 data
[1] = (val
& 0xff);
365 data
[0] = (val
& 0xff00) >> 8;
367 PDEBUG(D_CONF
, "Set blue balance %d", val
);
369 return m5602_write_sensor(sd
, MT9M111_SC_BLUE_GAIN
,
373 static int mt9m111_set_red_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
376 struct sd
*sd
= (struct sd
*) gspca_dev
;
378 data
[1] = (val
& 0xff);
379 data
[0] = (val
& 0xff00) >> 8;
381 PDEBUG(D_CONF
, "Set red balance %d", val
);
383 return m5602_write_sensor(sd
, MT9M111_SC_RED_GAIN
,
387 static int mt9m111_s_ctrl(struct v4l2_ctrl
*ctrl
)
389 struct gspca_dev
*gspca_dev
=
390 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
391 struct sd
*sd
= (struct sd
*) gspca_dev
;
394 if (!gspca_dev
->streaming
)
398 case V4L2_CID_AUTO_WHITE_BALANCE
:
399 err
= mt9m111_set_auto_white_balance(gspca_dev
, ctrl
->val
);
400 if (err
|| ctrl
->val
)
402 err
= mt9m111_set_green_balance(gspca_dev
, sd
->green_bal
->val
);
405 err
= mt9m111_set_red_balance(gspca_dev
, sd
->red_bal
->val
);
408 err
= mt9m111_set_blue_balance(gspca_dev
, sd
->blue_bal
->val
);
411 err
= mt9m111_set_gain(gspca_dev
, ctrl
->val
);
414 err
= mt9m111_set_hvflip(gspca_dev
);
423 static void mt9m111_dump_registers(struct sd
*sd
)
425 u8 address
, value
[2] = {0x00, 0x00};
427 pr_info("Dumping the mt9m111 register state\n");
429 pr_info("Dumping the mt9m111 sensor core registers\n");
430 value
[1] = MT9M111_SENSOR_CORE
;
431 m5602_write_sensor(sd
, MT9M111_PAGE_MAP
, value
, 2);
432 for (address
= 0; address
< 0xff; address
++) {
433 m5602_read_sensor(sd
, address
, value
, 2);
434 pr_info("register 0x%x contains 0x%x%x\n",
435 address
, value
[0], value
[1]);
438 pr_info("Dumping the mt9m111 color pipeline registers\n");
439 value
[1] = MT9M111_COLORPIPE
;
440 m5602_write_sensor(sd
, MT9M111_PAGE_MAP
, value
, 2);
441 for (address
= 0; address
< 0xff; address
++) {
442 m5602_read_sensor(sd
, address
, value
, 2);
443 pr_info("register 0x%x contains 0x%x%x\n",
444 address
, value
[0], value
[1]);
447 pr_info("Dumping the mt9m111 camera control registers\n");
448 value
[1] = MT9M111_CAMERA_CONTROL
;
449 m5602_write_sensor(sd
, MT9M111_PAGE_MAP
, value
, 2);
450 for (address
= 0; address
< 0xff; address
++) {
451 m5602_read_sensor(sd
, address
, value
, 2);
452 pr_info("register 0x%x contains 0x%x%x\n",
453 address
, value
[0], value
[1]);
456 pr_info("mt9m111 register state dump complete\n");