1/* 2 * Driver for the s5k83a 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#include <linux/kthread.h> 20#include "m5602_s5k83a.h" 21 22static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); 23static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 24static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); 25static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); 26static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 27static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 28static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 29static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 30static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 31static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); 32 33static struct v4l2_pix_format s5k83a_modes[] = { 34 { 35 640, 36 480, 37 V4L2_PIX_FMT_SBGGR8, 38 V4L2_FIELD_NONE, 39 .sizeimage = 40 640 * 480, 41 .bytesperline = 640, 42 .colorspace = V4L2_COLORSPACE_SRGB, 43 .priv = 0 44 } 45}; 46 47static const struct ctrl s5k83a_ctrls[] = { 48#define GAIN_IDX 0 49 { 50 { 51 .id = V4L2_CID_GAIN, 52 .type = V4L2_CTRL_TYPE_INTEGER, 53 .name = "gain", 54 .minimum = 0x00, 55 .maximum = 0xff, 56 .step = 0x01, 57 .default_value = S5K83A_DEFAULT_GAIN, 58 .flags = V4L2_CTRL_FLAG_SLIDER 59 }, 60 .set = s5k83a_set_gain, 61 .get = s5k83a_get_gain 62 63 }, 64#define BRIGHTNESS_IDX 1 65 { 66 { 67 .id = V4L2_CID_BRIGHTNESS, 68 .type = V4L2_CTRL_TYPE_INTEGER, 69 .name = "brightness", 70 .minimum = 0x00, 71 .maximum = 0xff, 72 .step = 0x01, 73 .default_value = S5K83A_DEFAULT_BRIGHTNESS, 74 .flags = V4L2_CTRL_FLAG_SLIDER 75 }, 76 .set = s5k83a_set_brightness, 77 .get = s5k83a_get_brightness, 78 }, 79#define EXPOSURE_IDX 2 80 { 81 { 82 .id = V4L2_CID_EXPOSURE, 83 .type = V4L2_CTRL_TYPE_INTEGER, 84 .name = "exposure", 85 .minimum = 0x00, 86 .maximum = S5K83A_MAXIMUM_EXPOSURE, 87 .step = 0x01, 88 .default_value = S5K83A_DEFAULT_EXPOSURE, 89 .flags = V4L2_CTRL_FLAG_SLIDER 90 }, 91 .set = s5k83a_set_exposure, 92 .get = s5k83a_get_exposure 93 }, 94#define HFLIP_IDX 3 95 { 96 { 97 .id = V4L2_CID_HFLIP, 98 .type = V4L2_CTRL_TYPE_BOOLEAN, 99 .name = "horizontal flip", 100 .minimum = 0, 101 .maximum = 1, 102 .step = 1, 103 .default_value = 0 104 }, 105 .set = s5k83a_set_hflip, 106 .get = s5k83a_get_hflip 107 }, 108#define VFLIP_IDX 4 109 { 110 { 111 .id = V4L2_CID_VFLIP, 112 .type = V4L2_CTRL_TYPE_BOOLEAN, 113 .name = "vertical flip", 114 .minimum = 0, 115 .maximum = 1, 116 .step = 1, 117 .default_value = 0 118 }, 119 .set = s5k83a_set_vflip, 120 .get = s5k83a_get_vflip 121 } 122}; 123 124static void s5k83a_dump_registers(struct sd *sd); 125static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data); 126static int s5k83a_set_led_indication(struct sd *sd, u8 val); 127static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, 128 __s32 vflip, __s32 hflip); 129 130int s5k83a_probe(struct sd *sd) 131{ 132 struct s5k83a_priv *sens_priv; 133 u8 prod_id = 0, ver_id = 0; 134 int i, err = 0; 135 136 if (force_sensor) { 137 if (force_sensor == S5K83A_SENSOR) { 138 info("Forcing a %s sensor", s5k83a.name); 139 goto sensor_found; 140 } 141 /* If we want to force another sensor, don't try to probe this 142 * one */ 143 return -ENODEV; 144 } 145 146 PDEBUG(D_PROBE, "Probing for a s5k83a sensor"); 147 148 /* Preinit the sensor */ 149 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { 150 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]}; 151 if (preinit_s5k83a[i][0] == SENSOR) 152 err = m5602_write_sensor(sd, preinit_s5k83a[i][1], 153 data, 2); 154 else 155 err = m5602_write_bridge(sd, preinit_s5k83a[i][1], 156 data[0]); 157 } 158 159 /* We don't know what register (if any) that contain the product id 160 * Just pick the first addresses that seem to produce the same results 161 * on multiple machines */ 162 if (m5602_read_sensor(sd, 0x00, &prod_id, 1)) 163 return -ENODEV; 164 165 if (m5602_read_sensor(sd, 0x01, &ver_id, 1)) 166 return -ENODEV; 167 168 if ((prod_id == 0xff) || (ver_id == 0xff)) 169 return -ENODEV; 170 else 171 info("Detected a s5k83a sensor"); 172 173sensor_found: 174 sens_priv = kmalloc( 175 sizeof(struct s5k83a_priv), GFP_KERNEL); 176 if (!sens_priv) 177 return -ENOMEM; 178 179 sens_priv->settings = 180 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL); 181 if (!sens_priv->settings) { 182 kfree(sens_priv); 183 return -ENOMEM; 184 } 185 186 sd->gspca_dev.cam.cam_mode = s5k83a_modes; 187 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); 188 sd->desc->ctrls = s5k83a_ctrls; 189 sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); 190 191 /* null the pointer! thread is't running now */ 192 sens_priv->rotation_thread = NULL; 193 194 for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++) 195 sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value; 196 197 sd->sensor_priv = sens_priv; 198 return 0; 199} 200 201int s5k83a_init(struct sd *sd) 202{ 203 int i, err = 0; 204 s32 *sensor_settings = 205 ((struct s5k83a_priv *) sd->sensor_priv)->settings; 206 207 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { 208 u8 data[2] = {0x00, 0x00}; 209 210 switch (init_s5k83a[i][0]) { 211 case BRIDGE: 212 err = m5602_write_bridge(sd, 213 init_s5k83a[i][1], 214 init_s5k83a[i][2]); 215 break; 216 217 case SENSOR: 218 data[0] = init_s5k83a[i][2]; 219 err = m5602_write_sensor(sd, 220 init_s5k83a[i][1], data, 1); 221 break; 222 223 case SENSOR_LONG: 224 data[0] = init_s5k83a[i][2]; 225 data[1] = init_s5k83a[i][3]; 226 err = m5602_write_sensor(sd, 227 init_s5k83a[i][1], data, 2); 228 break; 229 default: 230 info("Invalid stream command, exiting init"); 231 return -EINVAL; 232 } 233 } 234 235 if (dump_sensor) 236 s5k83a_dump_registers(sd); 237 238 err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); 239 if (err < 0) 240 return err; 241 242 err = s5k83a_set_brightness(&sd->gspca_dev, 243 sensor_settings[BRIGHTNESS_IDX]); 244 if (err < 0) 245 return err; 246 247 err = s5k83a_set_exposure(&sd->gspca_dev, 248 sensor_settings[EXPOSURE_IDX]); 249 if (err < 0) 250 return err; 251 252 err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); 253 if (err < 0) 254 return err; 255 256 err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); 257 258 return err; 259} 260 261static int rotation_thread_function(void *data) 262{ 263 struct sd *sd = (struct sd *) data; 264 struct s5k83a_priv *sens_priv = sd->sensor_priv; 265 u8 reg, previous_rotation = 0; 266 __s32 vflip, hflip; 267 268 set_current_state(TASK_INTERRUPTIBLE); 269 while (!schedule_timeout(100)) { 270 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock)) 271 break; 272 273 s5k83a_get_rotation(sd, ®); 274 if (previous_rotation != reg) { 275 previous_rotation = reg; 276 info("Camera was flipped"); 277 278 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); 279 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); 280 281 if (reg) { 282 vflip = !vflip; 283 hflip = !hflip; 284 } 285 s5k83a_set_flip_real((struct gspca_dev *) sd, 286 vflip, hflip); 287 } 288 289 mutex_unlock(&sd->gspca_dev.usb_lock); 290 set_current_state(TASK_INTERRUPTIBLE); 291 } 292 293 /* return to "front" flip */ 294 if (previous_rotation) { 295 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); 296 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); 297 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip); 298 } 299 300 sens_priv->rotation_thread = NULL; 301 return 0; 302} 303 304int s5k83a_start(struct sd *sd) 305{ 306 int i, err = 0; 307 struct s5k83a_priv *sens_priv = sd->sensor_priv; 308 309 /* Create another thread, polling the GPIO ports of the camera to check 310 if it got rotated. This is how the windows driver does it so we have 311 to assume that there is no better way of accomplishing this */ 312 sens_priv->rotation_thread = kthread_create(rotation_thread_function, 313 sd, "rotation thread"); 314 wake_up_process(sens_priv->rotation_thread); 315 316 /* Preinit the sensor */ 317 for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) { 318 u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]}; 319 if (start_s5k83a[i][0] == SENSOR) 320 err = m5602_write_sensor(sd, start_s5k83a[i][1], 321 data, 2); 322 else 323 err = m5602_write_bridge(sd, start_s5k83a[i][1], 324 data[0]); 325 } 326 if (err < 0) 327 return err; 328 329 return s5k83a_set_led_indication(sd, 1); 330} 331 332int s5k83a_stop(struct sd *sd) 333{ 334 struct s5k83a_priv *sens_priv = sd->sensor_priv; 335 336 if (sens_priv->rotation_thread) 337 kthread_stop(sens_priv->rotation_thread); 338 339 return s5k83a_set_led_indication(sd, 0); 340} 341 342void s5k83a_disconnect(struct sd *sd) 343{ 344 struct s5k83a_priv *sens_priv = sd->sensor_priv; 345 346 s5k83a_stop(sd); 347 348 sd->sensor = NULL; 349 kfree(sens_priv->settings); 350 kfree(sens_priv); 351} 352 353static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 354{ 355 struct sd *sd = (struct sd *) gspca_dev; 356 struct s5k83a_priv *sens_priv = sd->sensor_priv; 357 358 *val = sens_priv->settings[GAIN_IDX]; 359 return 0; 360} 361 362static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) 363{ 364 int err; 365 u8 data[2]; 366 struct sd *sd = (struct sd *) gspca_dev; 367 struct s5k83a_priv *sens_priv = sd->sensor_priv; 368 369 sens_priv->settings[GAIN_IDX] = val; 370 371 data[0] = 0x00; 372 data[1] = 0x20; 373 err = m5602_write_sensor(sd, 0x14, data, 2); 374 if (err < 0) 375 return err; 376 377 data[0] = 0x01; 378 data[1] = 0x00; 379 err = m5602_write_sensor(sd, 0x0d, data, 2); 380 if (err < 0) 381 return err; 382 383 data[0] = val >> 3; /* gain, high 5 bits */ 384 data[1] = val >> 1; /* gain, high 7 bits */ 385 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); 386 387 return err; 388} 389 390static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 391{ 392 struct sd *sd = (struct sd *) gspca_dev; 393 struct s5k83a_priv *sens_priv = sd->sensor_priv; 394 395 *val = sens_priv->settings[BRIGHTNESS_IDX]; 396 return 0; 397} 398 399static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 400{ 401 int err; 402 u8 data[1]; 403 struct sd *sd = (struct sd *) gspca_dev; 404 struct s5k83a_priv *sens_priv = sd->sensor_priv; 405 406 sens_priv->settings[BRIGHTNESS_IDX] = val; 407 data[0] = val; 408 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1); 409 return err; 410} 411 412static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 413{ 414 struct sd *sd = (struct sd *) gspca_dev; 415 struct s5k83a_priv *sens_priv = sd->sensor_priv; 416 417 *val = sens_priv->settings[EXPOSURE_IDX]; 418 return 0; 419} 420 421static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 422{ 423 int err; 424 u8 data[2]; 425 struct sd *sd = (struct sd *) gspca_dev; 426 struct s5k83a_priv *sens_priv = sd->sensor_priv; 427 428 sens_priv->settings[EXPOSURE_IDX] = val; 429 data[0] = 0; 430 data[1] = val; 431 err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2); 432 return err; 433} 434 435static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 436{ 437 struct sd *sd = (struct sd *) gspca_dev; 438 struct s5k83a_priv *sens_priv = sd->sensor_priv; 439 440 *val = sens_priv->settings[VFLIP_IDX]; 441 return 0; 442} 443 444static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, 445 __s32 vflip, __s32 hflip) 446{ 447 int err; 448 u8 data[1]; 449 struct sd *sd = (struct sd *) gspca_dev; 450 451 data[0] = 0x05; 452 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 453 if (err < 0) 454 return err; 455 456 /* six bit is vflip, seven is hflip */ 457 data[0] = S5K83A_FLIP_MASK; 458 data[0] = (vflip) ? data[0] | 0x40 : data[0]; 459 data[0] = (hflip) ? data[0] | 0x80 : data[0]; 460 461 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); 462 if (err < 0) 463 return err; 464 465 data[0] = (vflip) ? 0x0b : 0x0a; 466 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); 467 if (err < 0) 468 return err; 469 470 data[0] = (hflip) ? 0x0a : 0x0b; 471 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); 472 return err; 473} 474 475static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 476{ 477 int err; 478 u8 reg; 479 __s32 hflip; 480 struct sd *sd = (struct sd *) gspca_dev; 481 struct s5k83a_priv *sens_priv = sd->sensor_priv; 482 483 sens_priv->settings[VFLIP_IDX] = val; 484 485 s5k83a_get_hflip(gspca_dev, &hflip); 486 487 err = s5k83a_get_rotation(sd, ®); 488 if (err < 0) 489 return err; 490 if (reg) { 491 val = !val; 492 hflip = !hflip; 493 } 494 495 err = s5k83a_set_flip_real(gspca_dev, val, hflip); 496 return err; 497} 498 499static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 500{ 501 struct sd *sd = (struct sd *) gspca_dev; 502 struct s5k83a_priv *sens_priv = sd->sensor_priv; 503 504 *val = sens_priv->settings[HFLIP_IDX]; 505 return 0; 506} 507 508static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 509{ 510 int err; 511 u8 reg; 512 __s32 vflip; 513 struct sd *sd = (struct sd *) gspca_dev; 514 struct s5k83a_priv *sens_priv = sd->sensor_priv; 515 516 sens_priv->settings[HFLIP_IDX] = val; 517 518 s5k83a_get_vflip(gspca_dev, &vflip); 519 520 err = s5k83a_get_rotation(sd, ®); 521 if (err < 0) 522 return err; 523 if (reg) { 524 val = !val; 525 vflip = !vflip; 526 } 527 528 err = s5k83a_set_flip_real(gspca_dev, vflip, val); 529 return err; 530} 531 532static int s5k83a_set_led_indication(struct sd *sd, u8 val) 533{ 534 int err = 0; 535 u8 data[1]; 536 537 err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data); 538 if (err < 0) 539 return err; 540 541 if (val) 542 data[0] = data[0] | S5K83A_GPIO_LED_MASK; 543 else 544 data[0] = data[0] & ~S5K83A_GPIO_LED_MASK; 545 546 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); 547 548 return err; 549} 550 551/* Get camera rotation on Acer notebooks */ 552static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data) 553{ 554 int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data); 555 *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1; 556 return err; 557} 558 559static void s5k83a_dump_registers(struct sd *sd) 560{ 561 int address; 562 u8 page, old_page; 563 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 564 565 for (page = 0; page < 16; page++) { 566 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 567 info("Dumping the s5k83a register state for page 0x%x", page); 568 for (address = 0; address <= 0xff; address++) { 569 u8 val = 0; 570 m5602_read_sensor(sd, address, &val, 1); 571 info("register 0x%x contains 0x%x", 572 address, val); 573 } 574 } 575 info("s5k83a register state dump complete"); 576 577 for (page = 0; page < 16; page++) { 578 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 579 info("Probing for which registers that are read/write " 580 "for page 0x%x", page); 581 for (address = 0; address <= 0xff; address++) { 582 u8 old_val, ctrl_val, test_val = 0xff; 583 584 m5602_read_sensor(sd, address, &old_val, 1); 585 m5602_write_sensor(sd, address, &test_val, 1); 586 m5602_read_sensor(sd, address, &ctrl_val, 1); 587 588 if (ctrl_val == test_val) 589 info("register 0x%x is writeable", address); 590 else 591 info("register 0x%x is read only", address); 592 593 /* Restore original val */ 594 m5602_write_sensor(sd, address, &old_val, 1); 595 } 596 } 597 info("Read/write register probing complete"); 598 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 599} 600