linux/drivers/media/video/ov6650.c
<<
>>
Prefs
   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_GREY8_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, &reg);
 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, &reg);
 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, &reg);
 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, &reg);
 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_GREY8_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_GREY8_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_GREY8_1X8;
 940        case V4L2_MBUS_FMT_GREY8_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 occured 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");
1222