/drivers/media/video/ov6650.c
C | 1221 lines | 1006 code | 161 blank | 54 comment | 118 complexity | 381193bf591a3b7695574ecbede80088 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/* 2 * V4L2 SoC Camera driver for OmniVision OV6650 Camera Sensor 3 * 4 * Copyright (C) 2010 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> 5 * 6 * Based on OmniVision OV96xx Camera Driver 7 * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com> 8 * 9 * Based on ov772x camera driver: 10 * Copyright (C) 2008 Renesas Solutions Corp. 11 * Kuninori Morimoto <morimoto.kuninori@renesas.com> 12 * 13 * Based on ov7670 and soc_camera_platform driver, 14 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> 15 * Copyright (C) 2008 Magnus Damm 16 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> 17 * 18 * Hardware specific bits initialy based on former work by Matt Callow 19 * drivers/media/video/omap/sensor_ov6650.c 20 * Copyright (C) 2006 Matt Callow 21 * 22 * This program is free software; you can redistribute it and/or modify 23 * it under the terms of the GNU General Public License version 2 as 24 * published by the Free Software Foundation. 25 */ 26 27#include <linux/bitops.h> 28#include <linux/delay.h> 29#include <linux/i2c.h> 30#include <linux/slab.h> 31 32#include <media/soc_camera.h> 33#include <media/v4l2-chip-ident.h> 34 35 36/* Register definitions */ 37#define REG_GAIN 0x00 /* range 00 - 3F */ 38#define REG_BLUE 0x01 39#define REG_RED 0x02 40#define REG_SAT 0x03 /* [7:4] saturation [0:3] reserved */ 41#define REG_HUE 0x04 /* [7:6] rsrvd [5] hue en [4:0] hue */ 42 43#define REG_BRT 0x06 44 45#define REG_PIDH 0x0a 46#define REG_PIDL 0x0b 47 48#define REG_AECH 0x10 49#define REG_CLKRC 0x11 /* Data Format and Internal Clock */ 50 /* [7:6] Input system clock (MHz)*/ 51 /* 00=8, 01=12, 10=16, 11=24 */ 52 /* [5:0]: Internal Clock Pre-Scaler */ 53#define REG_COMA 0x12 /* [7] Reset */ 54#define REG_COMB 0x13 55#define REG_COMC 0x14 56#define REG_COMD 0x15 57#define REG_COML 0x16 58#define REG_HSTRT 0x17 59#define REG_HSTOP 0x18 60#define REG_VSTRT 0x19 61#define REG_VSTOP 0x1a 62#define REG_PSHFT 0x1b 63#define REG_MIDH 0x1c 64#define REG_MIDL 0x1d 65#define REG_HSYNS 0x1e 66#define REG_HSYNE 0x1f 67#define REG_COME 0x20 68#define REG_YOFF 0x21 69#define REG_UOFF 0x22 70#define REG_VOFF 0x23 71#define REG_AEW 0x24 72#define REG_AEB 0x25 73#define REG_COMF 0x26 74#define REG_COMG 0x27 75#define REG_COMH 0x28 76#define REG_COMI 0x29 77 78#define REG_FRARL 0x2b 79#define REG_COMJ 0x2c 80#define REG_COMK 0x2d 81#define REG_AVGY 0x2e 82#define REG_REF0 0x2f 83#define REG_REF1 0x30 84#define REG_REF2 0x31 85#define REG_FRAJH 0x32 86#define REG_FRAJL 0x33 87#define REG_FACT 0x34 88#define REG_L1AEC 0x35 89#define REG_AVGU 0x36 90#define REG_AVGV 0x37 91 92#define REG_SPCB 0x60 93#define REG_SPCC 0x61 94#define REG_GAM1 0x62 95#define REG_GAM2 0x63 96#define REG_GAM3 0x64 97#define REG_SPCD 0x65 98 99#define REG_SPCE 0x68 100#define REG_ADCL 0x69 101 102#define REG_RMCO 0x6c 103#define REG_GMCO 0x6d 104#define REG_BMCO 0x6e 105 106 107/* Register bits, values, etc. */ 108#define OV6650_PIDH 0x66 /* high byte of product ID number */ 109#define OV6650_PIDL 0x50 /* low byte of product ID number */ 110#define OV6650_MIDH 0x7F /* high byte of mfg ID */ 111#define OV6650_MIDL 0xA2 /* low byte of mfg ID */ 112 113#define DEF_GAIN 0x00 114#define DEF_BLUE 0x80 115#define DEF_RED 0x80 116 117#define SAT_SHIFT 4 118#define SAT_MASK (0xf << SAT_SHIFT) 119#define SET_SAT(x) (((x) << SAT_SHIFT) & SAT_MASK) 120 121#define HUE_EN BIT(5) 122#define HUE_MASK 0x1f 123#define DEF_HUE 0x10 124#define SET_HUE(x) (HUE_EN | ((x) & HUE_MASK)) 125 126#define DEF_AECH 0x4D 127 128#define CLKRC_6MHz 0x00 129#define CLKRC_12MHz 0x40 130#define CLKRC_16MHz 0x80 131#define CLKRC_24MHz 0xc0 132#define CLKRC_DIV_MASK 0x3f 133#define GET_CLKRC_DIV(x) (((x) & CLKRC_DIV_MASK) + 1) 134 135#define COMA_RESET BIT(7) 136#define COMA_QCIF BIT(5) 137#define COMA_RAW_RGB BIT(4) 138#define COMA_RGB BIT(3) 139#define COMA_BW BIT(2) 140#define COMA_WORD_SWAP BIT(1) 141#define COMA_BYTE_SWAP BIT(0) 142#define DEF_COMA 0x00 143 144#define COMB_FLIP_V BIT(7) 145#define COMB_FLIP_H BIT(5) 146#define COMB_BAND_FILTER BIT(4) 147#define COMB_AWB BIT(2) 148#define COMB_AGC BIT(1) 149#define COMB_AEC BIT(0) 150#define DEF_COMB 0x5f 151 152#define COML_ONE_CHANNEL BIT(7) 153 154#define DEF_HSTRT 0x24 155#define DEF_HSTOP 0xd4 156#define DEF_VSTRT 0x04 157#define DEF_VSTOP 0x94 158 159#define COMF_HREF_LOW BIT(4) 160 161#define COMJ_PCLK_RISING BIT(4) 162#define COMJ_VSYNC_HIGH BIT(0) 163 164/* supported resolutions */ 165#define W_QCIF (DEF_HSTOP - DEF_HSTRT) 166#define W_CIF (W_QCIF << 1) 167#define H_QCIF (DEF_VSTOP - DEF_VSTRT) 168#define H_CIF (H_QCIF << 1) 169 170#define FRAME_RATE_MAX 30 171 172 173struct ov6650_reg { 174 u8 reg; 175 u8 val; 176}; 177 178struct ov6650 { 179 struct v4l2_subdev subdev; 180 181 int gain; 182 int blue; 183 int red; 184 int saturation; 185 int hue; 186 int brightness; 187 int exposure; 188 int gamma; 189 int aec; 190 bool vflip; 191 bool hflip; 192 bool awb; 193 bool agc; 194 bool half_scale; /* scale down output by 2 */ 195 struct v4l2_rect rect; /* sensor cropping window */ 196 unsigned long pclk_limit; /* from host */ 197 unsigned long pclk_max; /* from resolution and format */ 198 struct v4l2_fract tpf; /* as requested with s_parm */ 199 enum v4l2_mbus_pixelcode code; 200 enum v4l2_colorspace colorspace; 201}; 202 203 204static enum v4l2_mbus_pixelcode ov6650_codes[] = { 205 V4L2_MBUS_FMT_YUYV8_2X8, 206 V4L2_MBUS_FMT_UYVY8_2X8, 207 V4L2_MBUS_FMT_YVYU8_2X8, 208 V4L2_MBUS_FMT_VYUY8_2X8, 209 V4L2_MBUS_FMT_SBGGR8_1X8, 210 V4L2_MBUS_FMT_Y8_1X8, 211}; 212 213static const struct v4l2_queryctrl ov6650_controls[] = { 214 { 215 .id = V4L2_CID_AUTOGAIN, 216 .type = V4L2_CTRL_TYPE_BOOLEAN, 217 .name = "AGC", 218 .minimum = 0, 219 .maximum = 1, 220 .step = 1, 221 .default_value = 1, 222 }, 223 { 224 .id = V4L2_CID_GAIN, 225 .type = V4L2_CTRL_TYPE_INTEGER, 226 .name = "Gain", 227 .minimum = 0, 228 .maximum = 0x3f, 229 .step = 1, 230 .default_value = DEF_GAIN, 231 }, 232 { 233 .id = V4L2_CID_AUTO_WHITE_BALANCE, 234 .type = V4L2_CTRL_TYPE_BOOLEAN, 235 .name = "AWB", 236 .minimum = 0, 237 .maximum = 1, 238 .step = 1, 239 .default_value = 1, 240 }, 241 { 242 .id = V4L2_CID_BLUE_BALANCE, 243 .type = V4L2_CTRL_TYPE_INTEGER, 244 .name = "Blue", 245 .minimum = 0, 246 .maximum = 0xff, 247 .step = 1, 248 .default_value = DEF_BLUE, 249 }, 250 { 251 .id = V4L2_CID_RED_BALANCE, 252 .type = V4L2_CTRL_TYPE_INTEGER, 253 .name = "Red", 254 .minimum = 0, 255 .maximum = 0xff, 256 .step = 1, 257 .default_value = DEF_RED, 258 }, 259 { 260 .id = V4L2_CID_SATURATION, 261 .type = V4L2_CTRL_TYPE_INTEGER, 262 .name = "Saturation", 263 .minimum = 0, 264 .maximum = 0xf, 265 .step = 1, 266 .default_value = 0x8, 267 }, 268 { 269 .id = V4L2_CID_HUE, 270 .type = V4L2_CTRL_TYPE_INTEGER, 271 .name = "Hue", 272 .minimum = 0, 273 .maximum = HUE_MASK, 274 .step = 1, 275 .default_value = DEF_HUE, 276 }, 277 { 278 .id = V4L2_CID_BRIGHTNESS, 279 .type = V4L2_CTRL_TYPE_INTEGER, 280 .name = "Brightness", 281 .minimum = 0, 282 .maximum = 0xff, 283 .step = 1, 284 .default_value = 0x80, 285 }, 286 { 287 .id = V4L2_CID_EXPOSURE_AUTO, 288 .type = V4L2_CTRL_TYPE_INTEGER, 289 .name = "AEC", 290 .minimum = 0, 291 .maximum = 3, 292 .step = 1, 293 .default_value = 0, 294 }, 295 { 296 .id = V4L2_CID_EXPOSURE, 297 .type = V4L2_CTRL_TYPE_INTEGER, 298 .name = "Exposure", 299 .minimum = 0, 300 .maximum = 0xff, 301 .step = 1, 302 .default_value = DEF_AECH, 303 }, 304 { 305 .id = V4L2_CID_GAMMA, 306 .type = V4L2_CTRL_TYPE_INTEGER, 307 .name = "Gamma", 308 .minimum = 0, 309 .maximum = 0xff, 310 .step = 1, 311 .default_value = 0x12, 312 }, 313 { 314 .id = V4L2_CID_VFLIP, 315 .type = V4L2_CTRL_TYPE_BOOLEAN, 316 .name = "Flip Vertically", 317 .minimum = 0, 318 .maximum = 1, 319 .step = 1, 320 .default_value = 0, 321 }, 322 { 323 .id = V4L2_CID_HFLIP, 324 .type = V4L2_CTRL_TYPE_BOOLEAN, 325 .name = "Flip Horizontally", 326 .minimum = 0, 327 .maximum = 1, 328 .step = 1, 329 .default_value = 0, 330 }, 331}; 332 333/* read a register */ 334static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) 335{ 336 int ret; 337 u8 data = reg; 338 struct i2c_msg msg = { 339 .addr = client->addr, 340 .flags = 0, 341 .len = 1, 342 .buf = &data, 343 }; 344 345 ret = i2c_transfer(client->adapter, &msg, 1); 346 if (ret < 0) 347 goto err; 348 349 msg.flags = I2C_M_RD; 350 ret = i2c_transfer(client->adapter, &msg, 1); 351 if (ret < 0) 352 goto err; 353 354 *val = data; 355 return 0; 356 357err: 358 dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg); 359 return ret; 360} 361 362/* write a register */ 363static int ov6650_reg_write(struct i2c_client *client, u8 reg, u8 val) 364{ 365 int ret; 366 unsigned char data[2] = { reg, val }; 367 struct i2c_msg msg = { 368 .addr = client->addr, 369 .flags = 0, 370 .len = 2, 371 .buf = data, 372 }; 373 374 ret = i2c_transfer(client->adapter, &msg, 1); 375 udelay(100); 376 377 if (ret < 0) { 378 dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg); 379 return ret; 380 } 381 return 0; 382} 383 384 385/* Read a register, alter its bits, write it back */ 386static int ov6650_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 mask) 387{ 388 u8 val; 389 int ret; 390 391 ret = ov6650_reg_read(client, reg, &val); 392 if (ret) { 393 dev_err(&client->dev, 394 "[Read]-Modify-Write of register 0x%02x failed!\n", 395 reg); 396 return ret; 397 } 398 399 val &= ~mask; 400 val |= set; 401 402 ret = ov6650_reg_write(client, reg, val); 403 if (ret) 404 dev_err(&client->dev, 405 "Read-Modify-[Write] of register 0x%02x failed!\n", 406 reg); 407 408 return ret; 409} 410 411static struct ov6650 *to_ov6650(const struct i2c_client *client) 412{ 413 return container_of(i2c_get_clientdata(client), struct ov6650, subdev); 414} 415 416/* Start/Stop streaming from the device */ 417static int ov6650_s_stream(struct v4l2_subdev *sd, int enable) 418{ 419 return 0; 420} 421 422/* Alter bus settings on camera side */ 423static int ov6650_set_bus_param(struct soc_camera_device *icd, 424 unsigned long flags) 425{ 426 struct soc_camera_link *icl = to_soc_camera_link(icd); 427 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 428 int ret; 429 430 flags = soc_camera_apply_sensor_flags(icl, flags); 431 432 if (flags & SOCAM_PCLK_SAMPLE_RISING) 433 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0); 434 else 435 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING); 436 if (ret) 437 return ret; 438 439 if (flags & SOCAM_HSYNC_ACTIVE_LOW) 440 ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0); 441 else 442 ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW); 443 if (ret) 444 return ret; 445 446 if (flags & SOCAM_VSYNC_ACTIVE_HIGH) 447 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0); 448 else 449 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH); 450 451 return ret; 452} 453 454/* Request bus settings on camera side */ 455static unsigned long ov6650_query_bus_param(struct soc_camera_device *icd) 456{ 457 struct soc_camera_link *icl = to_soc_camera_link(icd); 458 459 unsigned long flags = SOCAM_MASTER | 460 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | 461 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW | 462 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | 463 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8; 464 465 return soc_camera_apply_sensor_flags(icl, flags); 466} 467 468/* Get status of additional camera capabilities */ 469static int ov6650_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 470{ 471 struct i2c_client *client = v4l2_get_subdevdata(sd); 472 struct ov6650 *priv = to_ov6650(client); 473 uint8_t reg; 474 int ret = 0; 475 476 switch (ctrl->id) { 477 case V4L2_CID_AUTOGAIN: 478 ctrl->value = priv->agc; 479 break; 480 case V4L2_CID_GAIN: 481 if (priv->agc) { 482 ret = ov6650_reg_read(client, REG_GAIN, ®); 483 ctrl->value = reg; 484 } else { 485 ctrl->value = priv->gain; 486 } 487 break; 488 case V4L2_CID_AUTO_WHITE_BALANCE: 489 ctrl->value = priv->awb; 490 break; 491 case V4L2_CID_BLUE_BALANCE: 492 if (priv->awb) { 493 ret = ov6650_reg_read(client, REG_BLUE, ®); 494 ctrl->value = reg; 495 } else { 496 ctrl->value = priv->blue; 497 } 498 break; 499 case V4L2_CID_RED_BALANCE: 500 if (priv->awb) { 501 ret = ov6650_reg_read(client, REG_RED, ®); 502 ctrl->value = reg; 503 } else { 504 ctrl->value = priv->red; 505 } 506 break; 507 case V4L2_CID_SATURATION: 508 ctrl->value = priv->saturation; 509 break; 510 case V4L2_CID_HUE: 511 ctrl->value = priv->hue; 512 break; 513 case V4L2_CID_BRIGHTNESS: 514 ctrl->value = priv->brightness; 515 break; 516 case V4L2_CID_EXPOSURE_AUTO: 517 ctrl->value = priv->aec; 518 break; 519 case V4L2_CID_EXPOSURE: 520 if (priv->aec) { 521 ret = ov6650_reg_read(client, REG_AECH, ®); 522 ctrl->value = reg; 523 } else { 524 ctrl->value = priv->exposure; 525 } 526 break; 527 case V4L2_CID_GAMMA: 528 ctrl->value = priv->gamma; 529 break; 530 case V4L2_CID_VFLIP: 531 ctrl->value = priv->vflip; 532 break; 533 case V4L2_CID_HFLIP: 534 ctrl->value = priv->hflip; 535 break; 536 } 537 return ret; 538} 539 540/* Set status of additional camera capabilities */ 541static int ov6650_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 542{ 543 struct i2c_client *client = v4l2_get_subdevdata(sd); 544 struct ov6650 *priv = to_ov6650(client); 545 int ret = 0; 546 547 switch (ctrl->id) { 548 case V4L2_CID_AUTOGAIN: 549 ret = ov6650_reg_rmw(client, REG_COMB, 550 ctrl->value ? COMB_AGC : 0, COMB_AGC); 551 if (!ret) 552 priv->agc = ctrl->value; 553 break; 554 case V4L2_CID_GAIN: 555 ret = ov6650_reg_write(client, REG_GAIN, ctrl->value); 556 if (!ret) 557 priv->gain = ctrl->value; 558 break; 559 case V4L2_CID_AUTO_WHITE_BALANCE: 560 ret = ov6650_reg_rmw(client, REG_COMB, 561 ctrl->value ? COMB_AWB : 0, COMB_AWB); 562 if (!ret) 563 priv->awb = ctrl->value; 564 break; 565 case V4L2_CID_BLUE_BALANCE: 566 ret = ov6650_reg_write(client, REG_BLUE, ctrl->value); 567 if (!ret) 568 priv->blue = ctrl->value; 569 break; 570 case V4L2_CID_RED_BALANCE: 571 ret = ov6650_reg_write(client, REG_RED, ctrl->value); 572 if (!ret) 573 priv->red = ctrl->value; 574 break; 575 case V4L2_CID_SATURATION: 576 ret = ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->value), 577 SAT_MASK); 578 if (!ret) 579 priv->saturation = ctrl->value; 580 break; 581 case V4L2_CID_HUE: 582 ret = ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->value), 583 HUE_MASK); 584 if (!ret) 585 priv->hue = ctrl->value; 586 break; 587 case V4L2_CID_BRIGHTNESS: 588 ret = ov6650_reg_write(client, REG_BRT, ctrl->value); 589 if (!ret) 590 priv->brightness = ctrl->value; 591 break; 592 case V4L2_CID_EXPOSURE_AUTO: 593 switch (ctrl->value) { 594 case V4L2_EXPOSURE_AUTO: 595 ret = ov6650_reg_rmw(client, REG_COMB, COMB_AEC, 0); 596 break; 597 default: 598 ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_AEC); 599 break; 600 } 601 if (!ret) 602 priv->aec = ctrl->value; 603 break; 604 case V4L2_CID_EXPOSURE: 605 ret = ov6650_reg_write(client, REG_AECH, ctrl->value); 606 if (!ret) 607 priv->exposure = ctrl->value; 608 break; 609 case V4L2_CID_GAMMA: 610 ret = ov6650_reg_write(client, REG_GAM1, ctrl->value); 611 if (!ret) 612 priv->gamma = ctrl->value; 613 break; 614 case V4L2_CID_VFLIP: 615 ret = ov6650_reg_rmw(client, REG_COMB, 616 ctrl->value ? COMB_FLIP_V : 0, COMB_FLIP_V); 617 if (!ret) 618 priv->vflip = ctrl->value; 619 break; 620 case V4L2_CID_HFLIP: 621 ret = ov6650_reg_rmw(client, REG_COMB, 622 ctrl->value ? COMB_FLIP_H : 0, COMB_FLIP_H); 623 if (!ret) 624 priv->hflip = ctrl->value; 625 break; 626 } 627 628 return ret; 629} 630 631/* Get chip identification */ 632static int ov6650_g_chip_ident(struct v4l2_subdev *sd, 633 struct v4l2_dbg_chip_ident *id) 634{ 635 id->ident = V4L2_IDENT_OV6650; 636 id->revision = 0; 637 638 return 0; 639} 640 641#ifdef CONFIG_VIDEO_ADV_DEBUG 642static int ov6650_get_register(struct v4l2_subdev *sd, 643 struct v4l2_dbg_register *reg) 644{ 645 struct i2c_client *client = v4l2_get_subdevdata(sd); 646 int ret; 647 u8 val; 648 649 if (reg->reg & ~0xff) 650 return -EINVAL; 651 652 reg->size = 1; 653 654 ret = ov6650_reg_read(client, reg->reg, &val); 655 if (!ret) 656 reg->val = (__u64)val; 657 658 return ret; 659} 660 661static int ov6650_set_register(struct v4l2_subdev *sd, 662 struct v4l2_dbg_register *reg) 663{ 664 struct i2c_client *client = v4l2_get_subdevdata(sd); 665 666 if (reg->reg & ~0xff || reg->val & ~0xff) 667 return -EINVAL; 668 669 return ov6650_reg_write(client, reg->reg, reg->val); 670} 671#endif 672 673static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 674{ 675 struct i2c_client *client = v4l2_get_subdevdata(sd); 676 struct ov6650 *priv = to_ov6650(client); 677 678 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 679 a->c = priv->rect; 680 681 return 0; 682} 683 684static int ov6650_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 685{ 686 struct i2c_client *client = v4l2_get_subdevdata(sd); 687 struct ov6650 *priv = to_ov6650(client); 688 struct v4l2_rect *rect = &a->c; 689 int ret; 690 691 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 692 return -EINVAL; 693 694 rect->left = ALIGN(rect->left, 2); 695 rect->width = ALIGN(rect->width, 2); 696 rect->top = ALIGN(rect->top, 2); 697 rect->height = ALIGN(rect->height, 2); 698 soc_camera_limit_side(&rect->left, &rect->width, 699 DEF_HSTRT << 1, 2, W_CIF); 700 soc_camera_limit_side(&rect->top, &rect->height, 701 DEF_VSTRT << 1, 2, H_CIF); 702 703 ret = ov6650_reg_write(client, REG_HSTRT, rect->left >> 1); 704 if (!ret) { 705 priv->rect.left = rect->left; 706 ret = ov6650_reg_write(client, REG_HSTOP, 707 (rect->left + rect->width) >> 1); 708 } 709 if (!ret) { 710 priv->rect.width = rect->width; 711 ret = ov6650_reg_write(client, REG_VSTRT, rect->top >> 1); 712 } 713 if (!ret) { 714 priv->rect.top = rect->top; 715 ret = ov6650_reg_write(client, REG_VSTOP, 716 (rect->top + rect->height) >> 1); 717 } 718 if (!ret) 719 priv->rect.height = rect->height; 720 721 return ret; 722} 723 724static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 725{ 726 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 727 return -EINVAL; 728 729 a->bounds.left = DEF_HSTRT << 1; 730 a->bounds.top = DEF_VSTRT << 1; 731 a->bounds.width = W_CIF; 732 a->bounds.height = H_CIF; 733 a->defrect = a->bounds; 734 a->pixelaspect.numerator = 1; 735 a->pixelaspect.denominator = 1; 736 737 return 0; 738} 739 740static int ov6650_g_fmt(struct v4l2_subdev *sd, 741 struct v4l2_mbus_framefmt *mf) 742{ 743 struct i2c_client *client = v4l2_get_subdevdata(sd); 744 struct ov6650 *priv = to_ov6650(client); 745 746 mf->width = priv->rect.width >> priv->half_scale; 747 mf->height = priv->rect.height >> priv->half_scale; 748 mf->code = priv->code; 749 mf->colorspace = priv->colorspace; 750 mf->field = V4L2_FIELD_NONE; 751 752 return 0; 753} 754 755static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect) 756{ 757 return width > rect->width >> 1 || height > rect->height >> 1; 758} 759 760static u8 to_clkrc(struct v4l2_fract *timeperframe, 761 unsigned long pclk_limit, unsigned long pclk_max) 762{ 763 unsigned long pclk; 764 765 if (timeperframe->numerator && timeperframe->denominator) 766 pclk = pclk_max * timeperframe->denominator / 767 (FRAME_RATE_MAX * timeperframe->numerator); 768 else 769 pclk = pclk_max; 770 771 if (pclk_limit && pclk_limit < pclk) 772 pclk = pclk_limit; 773 774 return (pclk_max - 1) / pclk; 775} 776 777/* set the format we will capture in */ 778static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) 779{ 780 struct i2c_client *client = v4l2_get_subdevdata(sd); 781 struct soc_camera_device *icd = client->dev.platform_data; 782 struct soc_camera_sense *sense = icd->sense; 783 struct ov6650 *priv = to_ov6650(client); 784 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); 785 struct v4l2_crop a = { 786 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 787 .c = { 788 .left = priv->rect.left + (priv->rect.width >> 1) - 789 (mf->width >> (1 - half_scale)), 790 .top = priv->rect.top + (priv->rect.height >> 1) - 791 (mf->height >> (1 - half_scale)), 792 .width = mf->width << half_scale, 793 .height = mf->height << half_scale, 794 }, 795 }; 796 enum v4l2_mbus_pixelcode code = mf->code; 797 unsigned long mclk, pclk; 798 u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask, clkrc; 799 int ret; 800 801 /* select color matrix configuration for given color encoding */ 802 switch (code) { 803 case V4L2_MBUS_FMT_Y8_1X8: 804 dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); 805 coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; 806 coma_set |= COMA_BW; 807 break; 808 case V4L2_MBUS_FMT_YUYV8_2X8: 809 dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n"); 810 coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP; 811 coma_set |= COMA_WORD_SWAP; 812 break; 813 case V4L2_MBUS_FMT_YVYU8_2X8: 814 dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n"); 815 coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP | 816 COMA_BYTE_SWAP; 817 break; 818 case V4L2_MBUS_FMT_UYVY8_2X8: 819 dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n"); 820 if (half_scale) { 821 coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; 822 coma_set |= COMA_BYTE_SWAP; 823 } else { 824 coma_mask |= COMA_RGB | COMA_BW; 825 coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; 826 } 827 break; 828 case V4L2_MBUS_FMT_VYUY8_2X8: 829 dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n"); 830 if (half_scale) { 831 coma_mask |= COMA_RGB | COMA_BW; 832 coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; 833 } else { 834 coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; 835 coma_set |= COMA_BYTE_SWAP; 836 } 837 break; 838 case V4L2_MBUS_FMT_SBGGR8_1X8: 839 dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n"); 840 coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP; 841 coma_set |= COMA_RAW_RGB | COMA_RGB; 842 break; 843 default: 844 dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code); 845 return -EINVAL; 846 } 847 priv->code = code; 848 849 if (code == V4L2_MBUS_FMT_Y8_1X8 || 850 code == V4L2_MBUS_FMT_SBGGR8_1X8) { 851 coml_mask = COML_ONE_CHANNEL; 852 coml_set = 0; 853 priv->pclk_max = 4000000; 854 } else { 855 coml_mask = 0; 856 coml_set = COML_ONE_CHANNEL; 857 priv->pclk_max = 8000000; 858 } 859 860 if (code == V4L2_MBUS_FMT_SBGGR8_1X8) 861 priv->colorspace = V4L2_COLORSPACE_SRGB; 862 else if (code != 0) 863 priv->colorspace = V4L2_COLORSPACE_JPEG; 864 865 if (half_scale) { 866 dev_dbg(&client->dev, "max resolution: QCIF\n"); 867 coma_set |= COMA_QCIF; 868 priv->pclk_max /= 2; 869 } else { 870 dev_dbg(&client->dev, "max resolution: CIF\n"); 871 coma_mask |= COMA_QCIF; 872 } 873 priv->half_scale = half_scale; 874 875 if (sense) { 876 if (sense->master_clock == 8000000) { 877 dev_dbg(&client->dev, "8MHz input clock\n"); 878 clkrc = CLKRC_6MHz; 879 } else if (sense->master_clock == 12000000) { 880 dev_dbg(&client->dev, "12MHz input clock\n"); 881 clkrc = CLKRC_12MHz; 882 } else if (sense->master_clock == 16000000) { 883 dev_dbg(&client->dev, "16MHz input clock\n"); 884 clkrc = CLKRC_16MHz; 885 } else if (sense->master_clock == 24000000) { 886 dev_dbg(&client->dev, "24MHz input clock\n"); 887 clkrc = CLKRC_24MHz; 888 } else { 889 dev_err(&client->dev, 890 "unspported input clock, check platform data\n"); 891 return -EINVAL; 892 } 893 mclk = sense->master_clock; 894 priv->pclk_limit = sense->pixel_clock_max; 895 } else { 896 clkrc = CLKRC_24MHz; 897 mclk = 24000000; 898 priv->pclk_limit = 0; 899 dev_dbg(&client->dev, "using default 24MHz input clock\n"); 900 } 901 902 clkrc |= to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); 903 904 pclk = priv->pclk_max / GET_CLKRC_DIV(clkrc); 905 dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n", 906 mclk / pclk, 10 * mclk % pclk / pclk); 907 908 ret = ov6650_s_crop(sd, &a); 909 if (!ret) 910 ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask); 911 if (!ret) 912 ret = ov6650_reg_write(client, REG_CLKRC, clkrc); 913 if (!ret) 914 ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask); 915 916 if (!ret) { 917 mf->colorspace = priv->colorspace; 918 mf->width = priv->rect.width >> half_scale; 919 mf->height = priv->rect.height >> half_scale; 920 } 921 922 return ret; 923} 924 925static int ov6650_try_fmt(struct v4l2_subdev *sd, 926 struct v4l2_mbus_framefmt *mf) 927{ 928 struct i2c_client *client = v4l2_get_subdevdata(sd); 929 struct ov6650 *priv = to_ov6650(client); 930 931 if (is_unscaled_ok(mf->width, mf->height, &priv->rect)) 932 v4l_bound_align_image(&mf->width, 2, W_CIF, 1, 933 &mf->height, 2, H_CIF, 1, 0); 934 935 mf->field = V4L2_FIELD_NONE; 936 937 switch (mf->code) { 938 case V4L2_MBUS_FMT_Y10_1X10: 939 mf->code = V4L2_MBUS_FMT_Y8_1X8; 940 case V4L2_MBUS_FMT_Y8_1X8: 941 case V4L2_MBUS_FMT_YVYU8_2X8: 942 case V4L2_MBUS_FMT_YUYV8_2X8: 943 case V4L2_MBUS_FMT_VYUY8_2X8: 944 case V4L2_MBUS_FMT_UYVY8_2X8: 945 mf->colorspace = V4L2_COLORSPACE_JPEG; 946 break; 947 default: 948 mf->code = V4L2_MBUS_FMT_SBGGR8_1X8; 949 case V4L2_MBUS_FMT_SBGGR8_1X8: 950 mf->colorspace = V4L2_COLORSPACE_SRGB; 951 break; 952 } 953 954 return 0; 955} 956 957static int ov6650_enum_fmt(struct v4l2_subdev *sd, unsigned int index, 958 enum v4l2_mbus_pixelcode *code) 959{ 960 if (index >= ARRAY_SIZE(ov6650_codes)) 961 return -EINVAL; 962 963 *code = ov6650_codes[index]; 964 return 0; 965} 966 967static int ov6650_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) 968{ 969 struct i2c_client *client = v4l2_get_subdevdata(sd); 970 struct ov6650 *priv = to_ov6650(client); 971 struct v4l2_captureparm *cp = &parms->parm.capture; 972 973 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 974 return -EINVAL; 975 976 memset(cp, 0, sizeof(*cp)); 977 cp->capability = V4L2_CAP_TIMEPERFRAME; 978 cp->timeperframe.numerator = GET_CLKRC_DIV(to_clkrc(&priv->tpf, 979 priv->pclk_limit, priv->pclk_max)); 980 cp->timeperframe.denominator = FRAME_RATE_MAX; 981 982 dev_dbg(&client->dev, "Frame interval: %u/%u s\n", 983 cp->timeperframe.numerator, cp->timeperframe.denominator); 984 985 return 0; 986} 987 988static int ov6650_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) 989{ 990 struct i2c_client *client = v4l2_get_subdevdata(sd); 991 struct ov6650 *priv = to_ov6650(client); 992 struct v4l2_captureparm *cp = &parms->parm.capture; 993 struct v4l2_fract *tpf = &cp->timeperframe; 994 int div, ret; 995 u8 clkrc; 996 997 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 998 return -EINVAL; 999 1000 if (cp->extendedmode != 0) 1001 return -EINVAL; 1002 1003 if (tpf->numerator == 0 || tpf->denominator == 0) 1004 div = 1; /* Reset to full rate */ 1005 else 1006 div = (tpf->numerator * FRAME_RATE_MAX) / tpf->denominator; 1007 1008 if (div == 0) 1009 div = 1; 1010 else if (div > GET_CLKRC_DIV(CLKRC_DIV_MASK)) 1011 div = GET_CLKRC_DIV(CLKRC_DIV_MASK); 1012 1013 /* 1014 * Keep result to be used as tpf limit 1015 * for subseqent clock divider calculations 1016 */ 1017 priv->tpf.numerator = div; 1018 priv->tpf.denominator = FRAME_RATE_MAX; 1019 1020 clkrc = to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); 1021 1022 ret = ov6650_reg_rmw(client, REG_CLKRC, clkrc, CLKRC_DIV_MASK); 1023 if (!ret) { 1024 tpf->numerator = GET_CLKRC_DIV(clkrc); 1025 tpf->denominator = FRAME_RATE_MAX; 1026 } 1027 1028 return ret; 1029} 1030 1031/* Soft reset the camera. This has nothing to do with the RESET pin! */ 1032static int ov6650_reset(struct i2c_client *client) 1033{ 1034 int ret; 1035 1036 dev_dbg(&client->dev, "reset\n"); 1037 1038 ret = ov6650_reg_rmw(client, REG_COMA, COMA_RESET, 0); 1039 if (ret) 1040 dev_err(&client->dev, 1041 "An error occurred while entering soft reset!\n"); 1042 1043 return ret; 1044} 1045 1046/* program default register values */ 1047static int ov6650_prog_dflt(struct i2c_client *client) 1048{ 1049 int ret; 1050 1051 dev_dbg(&client->dev, "initializing\n"); 1052 1053 ret = ov6650_reg_write(client, REG_COMA, 0); /* ~COMA_RESET */ 1054 if (!ret) 1055 ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_BAND_FILTER); 1056 1057 return ret; 1058} 1059 1060static int ov6650_video_probe(struct soc_camera_device *icd, 1061 struct i2c_client *client) 1062{ 1063 u8 pidh, pidl, midh, midl; 1064 int ret = 0; 1065 1066 /* 1067 * check and show product ID and manufacturer ID 1068 */ 1069 ret = ov6650_reg_read(client, REG_PIDH, &pidh); 1070 if (!ret) 1071 ret = ov6650_reg_read(client, REG_PIDL, &pidl); 1072 if (!ret) 1073 ret = ov6650_reg_read(client, REG_MIDH, &midh); 1074 if (!ret) 1075 ret = ov6650_reg_read(client, REG_MIDL, &midl); 1076 1077 if (ret) 1078 return ret; 1079 1080 if ((pidh != OV6650_PIDH) || (pidl != OV6650_PIDL)) { 1081 dev_err(&client->dev, "Product ID error 0x%02x:0x%02x\n", 1082 pidh, pidl); 1083 return -ENODEV; 1084 } 1085 1086 dev_info(&client->dev, 1087 "ov6650 Product ID 0x%02x:0x%02x Manufacturer ID 0x%02x:0x%02x\n", 1088 pidh, pidl, midh, midl); 1089 1090 ret = ov6650_reset(client); 1091 if (!ret) 1092 ret = ov6650_prog_dflt(client); 1093 1094 return ret; 1095} 1096 1097static struct soc_camera_ops ov6650_ops = { 1098 .set_bus_param = ov6650_set_bus_param, 1099 .query_bus_param = ov6650_query_bus_param, 1100 .controls = ov6650_controls, 1101 .num_controls = ARRAY_SIZE(ov6650_controls), 1102}; 1103 1104static struct v4l2_subdev_core_ops ov6650_core_ops = { 1105 .g_ctrl = ov6650_g_ctrl, 1106 .s_ctrl = ov6650_s_ctrl, 1107 .g_chip_ident = ov6650_g_chip_ident, 1108#ifdef CONFIG_VIDEO_ADV_DEBUG 1109 .g_register = ov6650_get_register, 1110 .s_register = ov6650_set_register, 1111#endif 1112}; 1113 1114static struct v4l2_subdev_video_ops ov6650_video_ops = { 1115 .s_stream = ov6650_s_stream, 1116 .g_mbus_fmt = ov6650_g_fmt, 1117 .s_mbus_fmt = ov6650_s_fmt, 1118 .try_mbus_fmt = ov6650_try_fmt, 1119 .enum_mbus_fmt = ov6650_enum_fmt, 1120 .cropcap = ov6650_cropcap, 1121 .g_crop = ov6650_g_crop, 1122 .s_crop = ov6650_s_crop, 1123 .g_parm = ov6650_g_parm, 1124 .s_parm = ov6650_s_parm, 1125}; 1126 1127static struct v4l2_subdev_ops ov6650_subdev_ops = { 1128 .core = &ov6650_core_ops, 1129 .video = &ov6650_video_ops, 1130}; 1131 1132/* 1133 * i2c_driver function 1134 */ 1135static int ov6650_probe(struct i2c_client *client, 1136 const struct i2c_device_id *did) 1137{ 1138 struct ov6650 *priv; 1139 struct soc_camera_device *icd = client->dev.platform_data; 1140 struct soc_camera_link *icl; 1141 int ret; 1142 1143 if (!icd) { 1144 dev_err(&client->dev, "Missing soc-camera data!\n"); 1145 return -EINVAL; 1146 } 1147 1148 icl = to_soc_camera_link(icd); 1149 if (!icl) { 1150 dev_err(&client->dev, "Missing platform_data for driver\n"); 1151 return -EINVAL; 1152 } 1153 1154 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1155 if (!priv) { 1156 dev_err(&client->dev, 1157 "Failed to allocate memory for private data!\n"); 1158 return -ENOMEM; 1159 } 1160 1161 v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops); 1162 1163 icd->ops = &ov6650_ops; 1164 1165 priv->rect.left = DEF_HSTRT << 1; 1166 priv->rect.top = DEF_VSTRT << 1; 1167 priv->rect.width = W_CIF; 1168 priv->rect.height = H_CIF; 1169 priv->half_scale = false; 1170 priv->code = V4L2_MBUS_FMT_YUYV8_2X8; 1171 priv->colorspace = V4L2_COLORSPACE_JPEG; 1172 1173 ret = ov6650_video_probe(icd, client); 1174 1175 if (ret) { 1176 icd->ops = NULL; 1177 kfree(priv); 1178 } 1179 1180 return ret; 1181} 1182 1183static int ov6650_remove(struct i2c_client *client) 1184{ 1185 struct ov6650 *priv = to_ov6650(client); 1186 1187 kfree(priv); 1188 return 0; 1189} 1190 1191static const struct i2c_device_id ov6650_id[] = { 1192 { "ov6650", 0 }, 1193 { } 1194}; 1195MODULE_DEVICE_TABLE(i2c, ov6650_id); 1196 1197static struct i2c_driver ov6650_i2c_driver = { 1198 .driver = { 1199 .name = "ov6650", 1200 }, 1201 .probe = ov6650_probe, 1202 .remove = ov6650_remove, 1203 .id_table = ov6650_id, 1204}; 1205 1206static int __init ov6650_module_init(void) 1207{ 1208 return i2c_add_driver(&ov6650_i2c_driver); 1209} 1210 1211static void __exit ov6650_module_exit(void) 1212{ 1213 i2c_del_driver(&ov6650_i2c_driver); 1214} 1215 1216module_init(ov6650_module_init); 1217module_exit(ov6650_module_exit); 1218 1219MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650"); 1220MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>"); 1221MODULE_LICENSE("GPL v2");