root/drivers/media/usb/gspca/m5602/m5602_ov9650.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ov9650_probe
  2. ov9650_init
  3. ov9650_init_controls
  4. ov9650_start
  5. ov9650_stop
  6. ov9650_disconnect
  7. ov9650_set_exposure
  8. ov9650_set_gain
  9. ov9650_set_red_balance
  10. ov9650_set_blue_balance
  11. ov9650_set_hvflip
  12. ov9650_set_auto_exposure
  13. ov9650_set_auto_white_balance
  14. ov9650_set_auto_gain
  15. ov9650_s_ctrl
  16. ov9650_dump_registers

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 
   3 /*
   4  * Driver for the ov9650 sensor
   5  *
   6  * Copyright (C) 2008 Erik Andrén
   7  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
   8  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
   9  *
  10  * Portions of code to USB interface and ALi driver software,
  11  * Copyright (c) 2006 Willem Duinker
  12  * v4l2 interface modeled after the V4L2 driver
  13  * for SN9C10x PC Camera Controllers
  14  */
  15 
  16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  17 
  18 #include "m5602_ov9650.h"
  19 
  20 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl);
  21 static void ov9650_dump_registers(struct sd *sd);
  22 
  23 static const unsigned char preinit_ov9650[][3] = {
  24         /* [INITCAM] */
  25         {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
  26         {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
  27         {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
  28         {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
  29         {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
  30         {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
  31 
  32         {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
  33         {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
  34         {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
  35         {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
  36         {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
  37         {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
  38         {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
  39         {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
  40         /* Reset chip */
  41         {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
  42         /* Enable double clock */
  43         {SENSOR, OV9650_CLKRC, 0x80},
  44         /* Do something out of spec with the power */
  45         {SENSOR, OV9650_OFON, 0x40}
  46 };
  47 
  48 static const unsigned char init_ov9650[][3] = {
  49         /* [INITCAM] */
  50         {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
  51         {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
  52         {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
  53         {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
  54         {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
  55         {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
  56 
  57         {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
  58         {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
  59         {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
  60         {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
  61         {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
  62         {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
  63         {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
  64         {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
  65 
  66         /* Reset chip */
  67         {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
  68         /* One extra reset is needed in order to make the sensor behave
  69            properly when resuming from ram, could be a timing issue */
  70         {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
  71 
  72         /* Enable double clock */
  73         {SENSOR, OV9650_CLKRC, 0x80},
  74         /* Do something out of spec with the power */
  75         {SENSOR, OV9650_OFON, 0x40},
  76 
  77         /* Set fast AGC/AEC algorithm with unlimited step size */
  78         {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
  79                               OV9650_AEC_UNLIM_STEP_SIZE},
  80 
  81         {SENSOR, OV9650_CHLF, 0x10},
  82         {SENSOR, OV9650_ARBLM, 0xbf},
  83         {SENSOR, OV9650_ACOM38, 0x81},
  84         /* Turn off color matrix coefficient double option */
  85         {SENSOR, OV9650_COM16, 0x00},
  86         /* Enable color matrix for RGB/YUV, Delay Y channel,
  87         set output Y/UV delay to 1 */
  88         {SENSOR, OV9650_COM13, 0x19},
  89         /* Enable digital BLC, Set output mode to U Y V Y */
  90         {SENSOR, OV9650_TSLB, 0x0c},
  91         /* Limit the AGC/AEC stable upper region */
  92         {SENSOR, OV9650_COM24, 0x00},
  93         /* Enable HREF and some out of spec things */
  94         {SENSOR, OV9650_COM12, 0x73},
  95         /* Set all DBLC offset signs to positive and
  96         do some out of spec stuff */
  97         {SENSOR, OV9650_DBLC1, 0xdf},
  98         {SENSOR, OV9650_COM21, 0x06},
  99         {SENSOR, OV9650_RSVD35, 0x91},
 100         /* Necessary, no camera stream without it */
 101         {SENSOR, OV9650_RSVD16, 0x06},
 102         {SENSOR, OV9650_RSVD94, 0x99},
 103         {SENSOR, OV9650_RSVD95, 0x99},
 104         {SENSOR, OV9650_RSVD96, 0x04},
 105         /* Enable full range output */
 106         {SENSOR, OV9650_COM15, 0x0},
 107         /* Enable HREF at optical black, enable ADBLC bias,
 108         enable ADBLC, reset timings at format change */
 109         {SENSOR, OV9650_COM6, 0x4b},
 110         /* Subtract 32 from the B channel bias */
 111         {SENSOR, OV9650_BBIAS, 0xa0},
 112         /* Subtract 32 from the Gb channel bias */
 113         {SENSOR, OV9650_GbBIAS, 0xa0},
 114         /* Do not bypass the analog BLC and to some out of spec stuff */
 115         {SENSOR, OV9650_Gr_COM, 0x00},
 116         /* Subtract 32 from the R channel bias */
 117         {SENSOR, OV9650_RBIAS, 0xa0},
 118         /* Subtract 32 from the R channel bias */
 119         {SENSOR, OV9650_RBIAS, 0x0},
 120         {SENSOR, OV9650_COM26, 0x80},
 121         {SENSOR, OV9650_ACOMA9, 0x98},
 122         /* Set the AGC/AEC stable region upper limit */
 123         {SENSOR, OV9650_AEW, 0x68},
 124         /* Set the AGC/AEC stable region lower limit */
 125         {SENSOR, OV9650_AEB, 0x5c},
 126         /* Set the high and low limit nibbles to 3 */
 127         {SENSOR, OV9650_VPT, 0xc3},
 128         /* Set the Automatic Gain Ceiling (AGC) to 128x,
 129         drop VSYNC at frame drop,
 130         limit exposure timing,
 131         drop frame when the AEC step is larger than the exposure gap */
 132         {SENSOR, OV9650_COM9, 0x6e},
 133         /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
 134         and set PWDN to SLVS (slave mode vertical sync) */
 135         {SENSOR, OV9650_COM10, 0x42},
 136         /* Set horizontal column start high to default value */
 137         {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
 138         /* Set horizontal column end */
 139         {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
 140         /* Complementing register to the two writes above */
 141         {SENSOR, OV9650_HREF, 0xb2},
 142         /* Set vertical row start high bits */
 143         {SENSOR, OV9650_VSTRT, 0x02},
 144         /* Set vertical row end low bits */
 145         {SENSOR, OV9650_VSTOP, 0x7e},
 146         /* Set complementing vertical frame control */
 147         {SENSOR, OV9650_VREF, 0x10},
 148         {SENSOR, OV9650_ADC, 0x04},
 149         {SENSOR, OV9650_HV, 0x40},
 150 
 151         /* Enable denoise, and white-pixel erase */
 152         {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
 153                  OV9650_WHITE_PIXEL_ENABLE |
 154                  OV9650_WHITE_PIXEL_OPTION},
 155 
 156         /* Enable VARIOPIXEL */
 157         {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
 158         {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
 159 
 160         /* Put the sensor in soft sleep mode */
 161         {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
 162 };
 163 
 164 static const unsigned char res_init_ov9650[][3] = {
 165         {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
 166 
 167         {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
 168         {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
 169         {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
 170         {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
 171         {BRIDGE, M5602_XB_SIG_INI, 0x01}
 172 };
 173 
 174 /* Vertically and horizontally flips the image if matched, needed for machines
 175    where the sensor is mounted upside down */
 176 static
 177     const
 178         struct dmi_system_id ov9650_flip_dmi_table[] = {
 179         {
 180                 .ident = "ASUS A6Ja",
 181                 .matches = {
 182                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 183                         DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
 184                 }
 185         },
 186         {
 187                 .ident = "ASUS A6JC",
 188                 .matches = {
 189                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 190                         DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
 191                 }
 192         },
 193         {
 194                 .ident = "ASUS A6K",
 195                 .matches = {
 196                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 197                         DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
 198                 }
 199         },
 200         {
 201                 .ident = "ASUS A6Kt",
 202                 .matches = {
 203                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 204                         DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
 205                 }
 206         },
 207         {
 208                 .ident = "ASUS A6VA",
 209                 .matches = {
 210                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 211                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
 212                 }
 213         },
 214         {
 215 
 216                 .ident = "ASUS A6VC",
 217                 .matches = {
 218                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 219                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
 220                 }
 221         },
 222         {
 223                 .ident = "ASUS A6VM",
 224                 .matches = {
 225                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 226                         DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
 227                 }
 228         },
 229         {
 230                 .ident = "ASUS A7V",
 231                 .matches = {
 232                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 233                         DMI_MATCH(DMI_PRODUCT_NAME, "A7V")
 234                 }
 235         },
 236         {
 237                 .ident = "Alienware Aurora m9700",
 238                 .matches = {
 239                         DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
 240                         DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
 241                 }
 242         },
 243         {}
 244 };
 245 
 246 static struct v4l2_pix_format ov9650_modes[] = {
 247         {
 248                 176,
 249                 144,
 250                 V4L2_PIX_FMT_SBGGR8,
 251                 V4L2_FIELD_NONE,
 252                 .sizeimage =
 253                         176 * 144,
 254                 .bytesperline = 176,
 255                 .colorspace = V4L2_COLORSPACE_SRGB,
 256                 .priv = 9
 257         }, {
 258                 320,
 259                 240,
 260                 V4L2_PIX_FMT_SBGGR8,
 261                 V4L2_FIELD_NONE,
 262                 .sizeimage =
 263                         320 * 240,
 264                 .bytesperline = 320,
 265                 .colorspace = V4L2_COLORSPACE_SRGB,
 266                 .priv = 8
 267         }, {
 268                 352,
 269                 288,
 270                 V4L2_PIX_FMT_SBGGR8,
 271                 V4L2_FIELD_NONE,
 272                 .sizeimage =
 273                         352 * 288,
 274                 .bytesperline = 352,
 275                 .colorspace = V4L2_COLORSPACE_SRGB,
 276                 .priv = 9
 277         }, {
 278                 640,
 279                 480,
 280                 V4L2_PIX_FMT_SBGGR8,
 281                 V4L2_FIELD_NONE,
 282                 .sizeimage =
 283                         640 * 480,
 284                 .bytesperline = 640,
 285                 .colorspace = V4L2_COLORSPACE_SRGB,
 286                 .priv = 9
 287         }
 288 };
 289 
 290 static const struct v4l2_ctrl_ops ov9650_ctrl_ops = {
 291         .s_ctrl = ov9650_s_ctrl,
 292 };
 293 
 294 int ov9650_probe(struct sd *sd)
 295 {
 296         int err = 0;
 297         u8 prod_id = 0, ver_id = 0, i;
 298         struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 299 
 300         if (force_sensor) {
 301                 if (force_sensor == OV9650_SENSOR) {
 302                         pr_info("Forcing an %s sensor\n", ov9650.name);
 303                         goto sensor_found;
 304                 }
 305                 /* If we want to force another sensor,
 306                    don't try to probe this one */
 307                 return -ENODEV;
 308         }
 309 
 310         gspca_dbg(gspca_dev, D_PROBE, "Probing for an ov9650 sensor\n");
 311 
 312         /* Run the pre-init before probing the sensor */
 313         for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
 314                 u8 data = preinit_ov9650[i][2];
 315                 if (preinit_ov9650[i][0] == SENSOR)
 316                         err = m5602_write_sensor(sd,
 317                                 preinit_ov9650[i][1], &data, 1);
 318                 else
 319                         err = m5602_write_bridge(sd,
 320                                 preinit_ov9650[i][1], data);
 321         }
 322 
 323         if (err < 0)
 324                 return err;
 325 
 326         if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
 327                 return -ENODEV;
 328 
 329         if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
 330                 return -ENODEV;
 331 
 332         if ((prod_id == 0x96) && (ver_id == 0x52)) {
 333                 pr_info("Detected an ov9650 sensor\n");
 334                 goto sensor_found;
 335         }
 336         return -ENODEV;
 337 
 338 sensor_found:
 339         sd->gspca_dev.cam.cam_mode = ov9650_modes;
 340         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes);
 341 
 342         return 0;
 343 }
 344 
 345 int ov9650_init(struct sd *sd)
 346 {
 347         int i, err = 0;
 348         u8 data;
 349 
 350         if (dump_sensor)
 351                 ov9650_dump_registers(sd);
 352 
 353         for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
 354                 data = init_ov9650[i][2];
 355                 if (init_ov9650[i][0] == SENSOR)
 356                         err = m5602_write_sensor(sd, init_ov9650[i][1],
 357                                                   &data, 1);
 358                 else
 359                         err = m5602_write_bridge(sd, init_ov9650[i][1], data);
 360         }
 361 
 362         return 0;
 363 }
 364 
 365 int ov9650_init_controls(struct sd *sd)
 366 {
 367         struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
 368 
 369         sd->gspca_dev.vdev.ctrl_handler = hdl;
 370         v4l2_ctrl_handler_init(hdl, 9);
 371 
 372         sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
 373                                                V4L2_CID_AUTO_WHITE_BALANCE,
 374                                                0, 1, 1, 1);
 375         sd->red_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
 376                                         V4L2_CID_RED_BALANCE, 0, 255, 1,
 377                                         RED_GAIN_DEFAULT);
 378         sd->blue_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
 379                                         V4L2_CID_BLUE_BALANCE, 0, 255, 1,
 380                                         BLUE_GAIN_DEFAULT);
 381 
 382         sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &ov9650_ctrl_ops,
 383                           V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO);
 384         sd->expo = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_EXPOSURE,
 385                           0, 0x1ff, 4, EXPOSURE_DEFAULT);
 386 
 387         sd->autogain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops,
 388                                          V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
 389         sd->gain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_GAIN, 0,
 390                                      0x3ff, 1, GAIN_DEFAULT);
 391 
 392         sd->hflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_HFLIP,
 393                                       0, 1, 1, 0);
 394         sd->vflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_VFLIP,
 395                                       0, 1, 1, 0);
 396 
 397         if (hdl->error) {
 398                 pr_err("Could not initialize controls\n");
 399                 return hdl->error;
 400         }
 401 
 402         v4l2_ctrl_auto_cluster(3, &sd->auto_white_bal, 0, false);
 403         v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false);
 404         v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
 405         v4l2_ctrl_cluster(2, &sd->hflip);
 406 
 407         return 0;
 408 }
 409 
 410 int ov9650_start(struct sd *sd)
 411 {
 412         u8 data;
 413         int i, err = 0;
 414         struct cam *cam = &sd->gspca_dev.cam;
 415 
 416         int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
 417         int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
 418         int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
 419         int hor_offs = OV9650_LEFT_OFFSET;
 420         struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 421 
 422         if ((!dmi_check_system(ov9650_flip_dmi_table) &&
 423                 sd->vflip->val) ||
 424                 (dmi_check_system(ov9650_flip_dmi_table) &&
 425                 !sd->vflip->val))
 426                 ver_offs--;
 427 
 428         if (width <= 320)
 429                 hor_offs /= 2;
 430 
 431         /* Synthesize the vsync/hsync setup */
 432         for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
 433                 if (res_init_ov9650[i][0] == BRIDGE)
 434                         err = m5602_write_bridge(sd, res_init_ov9650[i][1],
 435                                 res_init_ov9650[i][2]);
 436                 else if (res_init_ov9650[i][0] == SENSOR) {
 437                         data = res_init_ov9650[i][2];
 438                         err = m5602_write_sensor(sd,
 439                                 res_init_ov9650[i][1], &data, 1);
 440                 }
 441         }
 442         if (err < 0)
 443                 return err;
 444 
 445         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
 446                                  ((ver_offs >> 8) & 0xff));
 447         if (err < 0)
 448                 return err;
 449 
 450         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
 451         if (err < 0)
 452                 return err;
 453 
 454         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
 455         if (err < 0)
 456                 return err;
 457 
 458         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
 459         if (err < 0)
 460                 return err;
 461 
 462         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
 463         if (err < 0)
 464                 return err;
 465 
 466         for (i = 0; i < 2 && !err; i++)
 467                 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
 468         if (err < 0)
 469                 return err;
 470 
 471         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
 472         if (err < 0)
 473                 return err;
 474 
 475         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
 476         if (err < 0)
 477                 return err;
 478 
 479         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
 480                                  (hor_offs >> 8) & 0xff);
 481         if (err < 0)
 482                 return err;
 483 
 484         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
 485         if (err < 0)
 486                 return err;
 487 
 488         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
 489                                  ((width + hor_offs) >> 8) & 0xff);
 490         if (err < 0)
 491                 return err;
 492 
 493         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
 494                                  ((width + hor_offs) & 0xff));
 495         if (err < 0)
 496                 return err;
 497 
 498         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
 499         if (err < 0)
 500                 return err;
 501 
 502         switch (width) {
 503         case 640:
 504                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
 505 
 506                 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
 507                        OV9650_RAW_RGB_SELECT;
 508                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
 509                 break;
 510 
 511         case 352:
 512                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for CIF mode\n");
 513 
 514                 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
 515                                 OV9650_RAW_RGB_SELECT;
 516                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
 517                 break;
 518 
 519         case 320:
 520                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n");
 521 
 522                 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
 523                                 OV9650_RAW_RGB_SELECT;
 524                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
 525                 break;
 526 
 527         case 176:
 528                 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QCIF mode\n");
 529 
 530                 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
 531                         OV9650_RAW_RGB_SELECT;
 532                 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
 533                 break;
 534         }
 535         return err;
 536 }
 537 
 538 int ov9650_stop(struct sd *sd)
 539 {
 540         u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X;
 541         return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
 542 }
 543 
 544 void ov9650_disconnect(struct sd *sd)
 545 {
 546         ov9650_stop(sd);
 547 
 548         sd->sensor = NULL;
 549 }
 550 
 551 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 552 {
 553         struct sd *sd = (struct sd *) gspca_dev;
 554         u8 i2c_data;
 555         int err;
 556 
 557         gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val);
 558 
 559         /* The 6 MSBs */
 560         i2c_data = (val >> 10) & 0x3f;
 561         err = m5602_write_sensor(sd, OV9650_AECHM,
 562                                   &i2c_data, 1);
 563         if (err < 0)
 564                 return err;
 565 
 566         /* The 8 middle bits */
 567         i2c_data = (val >> 2) & 0xff;
 568         err = m5602_write_sensor(sd, OV9650_AECH,
 569                                   &i2c_data, 1);
 570         if (err < 0)
 571                 return err;
 572 
 573         /* The 2 LSBs */
 574         i2c_data = val & 0x03;
 575         err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
 576         return err;
 577 }
 578 
 579 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 580 {
 581         int err;
 582         u8 i2c_data;
 583         struct sd *sd = (struct sd *) gspca_dev;
 584 
 585         gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
 586 
 587         /* The 2 MSB */
 588         /* Read the OV9650_VREF register first to avoid
 589            corrupting the VREF high and low bits */
 590         err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
 591         if (err < 0)
 592                 return err;
 593 
 594         /* Mask away all uninteresting bits */
 595         i2c_data = ((val & 0x0300) >> 2) |
 596                         (i2c_data & 0x3f);
 597         err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
 598         if (err < 0)
 599                 return err;
 600 
 601         /* The 8 LSBs */
 602         i2c_data = val & 0xff;
 603         err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
 604         return err;
 605 }
 606 
 607 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 608 {
 609         int err;
 610         u8 i2c_data;
 611         struct sd *sd = (struct sd *) gspca_dev;
 612 
 613         gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", val);
 614 
 615         i2c_data = val & 0xff;
 616         err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
 617         return err;
 618 }
 619 
 620 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 621 {
 622         int err;
 623         u8 i2c_data;
 624         struct sd *sd = (struct sd *) gspca_dev;
 625 
 626         gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", val);
 627 
 628         i2c_data = val & 0xff;
 629         err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
 630         return err;
 631 }
 632 
 633 static int ov9650_set_hvflip(struct gspca_dev *gspca_dev)
 634 {
 635         int err;
 636         u8 i2c_data;
 637         struct sd *sd = (struct sd *) gspca_dev;
 638         int hflip = sd->hflip->val;
 639         int vflip = sd->vflip->val;
 640 
 641         gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n", hflip, vflip);
 642 
 643         if (dmi_check_system(ov9650_flip_dmi_table))
 644                 vflip = !vflip;
 645 
 646         i2c_data = (hflip << 5) | (vflip << 4);
 647         err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 648         if (err < 0)
 649                 return err;
 650 
 651         /* When vflip is toggled we need to readjust the bridge hsync/vsync */
 652         if (gspca_dev->streaming)
 653                 err = ov9650_start(sd);
 654 
 655         return err;
 656 }
 657 
 658 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
 659                                     __s32 val)
 660 {
 661         int err;
 662         u8 i2c_data;
 663         struct sd *sd = (struct sd *) gspca_dev;
 664 
 665         gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
 666 
 667         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 668         if (err < 0)
 669                 return err;
 670 
 671         val = (val == V4L2_EXPOSURE_AUTO);
 672         i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
 673 
 674         return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
 675 }
 676 
 677 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
 678                                          __s32 val)
 679 {
 680         int err;
 681         u8 i2c_data;
 682         struct sd *sd = (struct sd *) gspca_dev;
 683 
 684         gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
 685 
 686         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 687         if (err < 0)
 688                 return err;
 689 
 690         i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
 691         err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
 692 
 693         return err;
 694 }
 695 
 696 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
 697 {
 698         int err;
 699         u8 i2c_data;
 700         struct sd *sd = (struct sd *) gspca_dev;
 701 
 702         gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
 703 
 704         err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 705         if (err < 0)
 706                 return err;
 707 
 708         i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
 709 
 710         return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
 711 }
 712 
 713 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl)
 714 {
 715         struct gspca_dev *gspca_dev =
 716                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 717         struct sd *sd = (struct sd *) gspca_dev;
 718         int err;
 719 
 720         if (!gspca_dev->streaming)
 721                 return 0;
 722 
 723         switch (ctrl->id) {
 724         case V4L2_CID_AUTO_WHITE_BALANCE:
 725                 err = ov9650_set_auto_white_balance(gspca_dev, ctrl->val);
 726                 if (err || ctrl->val)
 727                         return err;
 728                 err = ov9650_set_red_balance(gspca_dev, sd->red_bal->val);
 729                 if (err)
 730                         return err;
 731                 err = ov9650_set_blue_balance(gspca_dev, sd->blue_bal->val);
 732                 break;
 733         case V4L2_CID_EXPOSURE_AUTO:
 734                 err = ov9650_set_auto_exposure(gspca_dev, ctrl->val);
 735                 if (err || ctrl->val == V4L2_EXPOSURE_AUTO)
 736                         return err;
 737                 err = ov9650_set_exposure(gspca_dev, sd->expo->val);
 738                 break;
 739         case V4L2_CID_AUTOGAIN:
 740                 err = ov9650_set_auto_gain(gspca_dev, ctrl->val);
 741                 if (err || ctrl->val)
 742                         return err;
 743                 err = ov9650_set_gain(gspca_dev, sd->gain->val);
 744                 break;
 745         case V4L2_CID_HFLIP:
 746                 err = ov9650_set_hvflip(gspca_dev);
 747                 break;
 748         default:
 749                 return -EINVAL;
 750         }
 751 
 752         return err;
 753 }
 754 
 755 static void ov9650_dump_registers(struct sd *sd)
 756 {
 757         int address;
 758         pr_info("Dumping the ov9650 register state\n");
 759         for (address = 0; address < 0xa9; address++) {
 760                 u8 value;
 761                 m5602_read_sensor(sd, address, &value, 1);
 762                 pr_info("register 0x%x contains 0x%x\n", address, value);
 763         }
 764 
 765         pr_info("ov9650 register state dump complete\n");
 766 
 767         pr_info("Probing for which registers that are read/write\n");
 768         for (address = 0; address < 0xff; address++) {
 769                 u8 old_value, ctrl_value;
 770                 u8 test_value[2] = {0xff, 0xff};
 771 
 772                 m5602_read_sensor(sd, address, &old_value, 1);
 773                 m5602_write_sensor(sd, address, test_value, 1);
 774                 m5602_read_sensor(sd, address, &ctrl_value, 1);
 775 
 776                 if (ctrl_value == test_value[0])
 777                         pr_info("register 0x%x is writeable\n", address);
 778                 else
 779                         pr_info("register 0x%x is read only\n", address);
 780 
 781                 /* Restore original value */
 782                 m5602_write_sensor(sd, address, &old_value, 1);
 783         }
 784 }

/* [<][>][^][v][top][bottom][index][help] */