1 /* 2 * Driver for the mt9m111 sensor 3 * 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> 7 * 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 12 * 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. 16 * 17 */ 18 19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20 21 #include "m5602_mt9m111.h" 22 23 static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl); 24 static void mt9m111_dump_registers(struct sd *sd); 25 26 static struct v4l2_pix_format mt9m111_modes[] = { 27 { 28 640, 29 480, 30 V4L2_PIX_FMT_SBGGR8, 31 V4L2_FIELD_NONE, 32 .sizeimage = 640 * 480, 33 .bytesperline = 640, 34 .colorspace = V4L2_COLORSPACE_SRGB, 35 .priv = 0 36 } 37 }; 38 39 static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = { 40 .s_ctrl = mt9m111_s_ctrl, 41 }; 42 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, 48 .min = 0, 49 .max = 0x7ff, 50 .step = 1, 51 .def = MT9M111_GREEN_GAIN_DEFAULT, 52 .flags = V4L2_CTRL_FLAG_SLIDER, 53 }; 54 55 int mt9m111_probe(struct sd *sd) 56 { 57 u8 data[2] = {0x00, 0x00}; 58 int i; 59 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 60 61 if (force_sensor) { 62 if (force_sensor == MT9M111_SENSOR) { 63 pr_info("Forcing a %s sensor\n", mt9m111.name); 64 goto sensor_found; 65 } 66 /* If we want to force another sensor, don't try to probe this 67 * one */ 68 return -ENODEV; 69 } 70 71 PDEBUG(D_PROBE, "Probing for a mt9m111 sensor"); 72 73 /* Do the preinit */ 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]); 79 } else { 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); 84 } 85 } 86 87 if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) 88 return -ENODEV; 89 90 if ((data[0] == 0x14) && (data[1] == 0x3a)) { 91 pr_info("Detected a mt9m111 sensor\n"); 92 goto sensor_found; 93 } 94 95 return -ENODEV; 96 97 sensor_found: 98 sd->gspca_dev.cam.cam_mode = mt9m111_modes; 99 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); 100 101 return 0; 102 } 103 104 int mt9m111_init(struct sd *sd) 105 { 106 int i, err = 0; 107 108 /* Init the sensor */ 109 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { 110 u8 data[2]; 111 112 if (init_mt9m111[i][0] == BRIDGE) { 113 err = m5602_write_bridge(sd, 114 init_mt9m111[i][1], 115 init_mt9m111[i][2]); 116 } else { 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); 121 } 122 } 123 124 if (dump_sensor) 125 mt9m111_dump_registers(sd); 126 127 return 0; 128 } 129 130 int mt9m111_init_controls(struct sd *sd) 131 { 132 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; 133 134 sd->gspca_dev.vdev.ctrl_handler = hdl; 135 v4l2_ctrl_handler_init(hdl, 7); 136 137 sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, 138 V4L2_CID_AUTO_WHITE_BALANCE, 139 0, 1, 1, 0); 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); 147 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); 151 152 sd->hflip = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, V4L2_CID_HFLIP, 153 0, 1, 1, 0); 154 sd->vflip = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, V4L2_CID_VFLIP, 155 0, 1, 1, 0); 156 157 if (hdl->error) { 158 pr_err("Could not initialize controls\n"); 159 return hdl->error; 160 } 161 162 v4l2_ctrl_auto_cluster(4, &sd->auto_white_bal, 0, false); 163 v4l2_ctrl_cluster(2, &sd->hflip); 164 165 return 0; 166 } 167 168 int mt9m111_start(struct sd *sd) 169 { 170 int i, err = 0; 171 u8 data[2]; 172 struct cam *cam = &sd->gspca_dev.cam; 173 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 174 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; 177 178 for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) { 179 if (start_mt9m111[i][0] == BRIDGE) { 180 err = m5602_write_bridge(sd, 181 start_mt9m111[i][1], 182 start_mt9m111[i][2]); 183 } else { 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); 188 } 189 } 190 if (err < 0) 191 return err; 192 193 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); 194 if (err < 0) 195 return err; 196 197 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); 198 if (err < 0) 199 return err; 200 201 for (i = 0; i < 2 && !err; i++) 202 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); 203 if (err < 0) 204 return err; 205 206 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 207 if (err < 0) 208 return err; 209 210 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); 211 if (err < 0) 212 return err; 213 214 for (i = 0; i < 2 && !err; i++) 215 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); 216 if (err < 0) 217 return err; 218 219 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 220 (width >> 8) & 0xff); 221 if (err < 0) 222 return err; 223 224 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff); 225 if (err < 0) 226 return err; 227 228 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 229 if (err < 0) 230 return err; 231 232 switch (width) { 233 case 640: 234 PDEBUG(D_CONF, "Configuring camera for VGA mode"); 235 break; 236 237 case 320: 238 PDEBUG(D_CONF, "Configuring camera for QVGA mode"); 239 break; 240 } 241 return err; 242 } 243 244 void mt9m111_disconnect(struct sd *sd) 245 { 246 sd->sensor = NULL; 247 } 248 249 static int mt9m111_set_hvflip(struct gspca_dev *gspca_dev) 250 { 251 int err; 252 u8 data[2] = {0x00, 0x00}; 253 struct sd *sd = (struct sd *) gspca_dev; 254 int hflip; 255 int vflip; 256 257 PDEBUG(D_CONF, "Set hvflip to %d %d", sd->hflip->val, sd->vflip->val); 258 259 /* The mt9m111 is flipped by default */ 260 hflip = !sd->hflip->val; 261 vflip = !sd->vflip->val; 262 263 /* Set the correct page map */ 264 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 265 if (err < 0) 266 return err; 267 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; 273 } else { 274 data[1] = MT9M111_RMB_ROW_SKIP_4X | 275 MT9M111_RMB_COLUMN_SKIP_4X | 276 (hflip << 1) | vflip; 277 } 278 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 279 data, 2); 280 return err; 281 } 282 283 static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, 284 __s32 val) 285 { 286 struct sd *sd = (struct sd *) gspca_dev; 287 int err; 288 u8 data[2]; 289 290 err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); 291 if (err < 0) 292 return err; 293 294 data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1)); 295 296 err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); 297 298 PDEBUG(D_CONF, "Set auto white balance %d", val); 299 return err; 300 } 301 302 static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) 303 { 304 int err, tmp; 305 u8 data[2] = {0x00, 0x00}; 306 struct sd *sd = (struct sd *) gspca_dev; 307 308 /* Set the correct page map */ 309 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 310 if (err < 0) 311 return err; 312 313 if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2) 314 return -EINVAL; 315 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); 326 else 327 tmp = val; 328 329 data[1] = (tmp & 0xff); 330 data[0] = (tmp & 0xff00) >> 8; 331 PDEBUG(D_CONF, "tmp=%d, data[1]=%d, data[0]=%d", tmp, 332 data[1], data[0]); 333 334 err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, 335 data, 2); 336 337 return err; 338 } 339 340 static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) 341 { 342 int err; 343 u8 data[2]; 344 struct sd *sd = (struct sd *) gspca_dev; 345 346 data[1] = (val & 0xff); 347 data[0] = (val & 0xff00) >> 8; 348 349 PDEBUG(D_CONF, "Set green balance %d", val); 350 err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN, 351 data, 2); 352 if (err < 0) 353 return err; 354 355 return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN, 356 data, 2); 357 } 358 359 static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 360 { 361 u8 data[2]; 362 struct sd *sd = (struct sd *) gspca_dev; 363 364 data[1] = (val & 0xff); 365 data[0] = (val & 0xff00) >> 8; 366 367 PDEBUG(D_CONF, "Set blue balance %d", val); 368 369 return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN, 370 data, 2); 371 } 372 373 static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 374 { 375 u8 data[2]; 376 struct sd *sd = (struct sd *) gspca_dev; 377 378 data[1] = (val & 0xff); 379 data[0] = (val & 0xff00) >> 8; 380 381 PDEBUG(D_CONF, "Set red balance %d", val); 382 383 return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN, 384 data, 2); 385 } 386 387 static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl) 388 { 389 struct gspca_dev *gspca_dev = 390 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 391 struct sd *sd = (struct sd *) gspca_dev; 392 int err; 393 394 if (!gspca_dev->streaming) 395 return 0; 396 397 switch (ctrl->id) { 398 case V4L2_CID_AUTO_WHITE_BALANCE: 399 err = mt9m111_set_auto_white_balance(gspca_dev, ctrl->val); 400 if (err || ctrl->val) 401 return err; 402 err = mt9m111_set_green_balance(gspca_dev, sd->green_bal->val); 403 if (err) 404 return err; 405 err = mt9m111_set_red_balance(gspca_dev, sd->red_bal->val); 406 if (err) 407 return err; 408 err = mt9m111_set_blue_balance(gspca_dev, sd->blue_bal->val); 409 break; 410 case V4L2_CID_GAIN: 411 err = mt9m111_set_gain(gspca_dev, ctrl->val); 412 break; 413 case V4L2_CID_HFLIP: 414 err = mt9m111_set_hvflip(gspca_dev); 415 break; 416 default: 417 return -EINVAL; 418 } 419 420 return err; 421 } 422 423 static void mt9m111_dump_registers(struct sd *sd) 424 { 425 u8 address, value[2] = {0x00, 0x00}; 426 427 pr_info("Dumping the mt9m111 register state\n"); 428 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]); 436 } 437 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]); 445 } 446 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]); 454 } 455 456 pr_info("mt9m111 register state dump complete\n"); 457 } 458