linux/drivers/media/video/mt9v022.c
<<
>>
Prefs
   1/*
   2 * Driver for MT9V022 CMOS Image Sensor from Micron
   3 *
   4 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/videodev2.h>
  12#include <linux/slab.h>
  13#include <linux/i2c.h>
  14#include <linux/delay.h>
  15#include <linux/log2.h>
  16
  17#include <media/v4l2-subdev.h>
  18#include <media/v4l2-chip-ident.h>
  19#include <media/soc_camera.h>
  20
  21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
  22 * The platform has to define ctruct i2c_board_info objects and link to them
  23 * from struct soc_camera_link */
  24
  25static char *sensor_type;
  26module_param(sensor_type, charp, S_IRUGO);
  27MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
  28
  29/* mt9v022 selected register addresses */
  30#define MT9V022_CHIP_VERSION            0x00
  31#define MT9V022_COLUMN_START            0x01
  32#define MT9V022_ROW_START               0x02
  33#define MT9V022_WINDOW_HEIGHT           0x03
  34#define MT9V022_WINDOW_WIDTH            0x04
  35#define MT9V022_HORIZONTAL_BLANKING     0x05
  36#define MT9V022_VERTICAL_BLANKING       0x06
  37#define MT9V022_CHIP_CONTROL            0x07
  38#define MT9V022_SHUTTER_WIDTH1          0x08
  39#define MT9V022_SHUTTER_WIDTH2          0x09
  40#define MT9V022_SHUTTER_WIDTH_CTRL      0x0a
  41#define MT9V022_TOTAL_SHUTTER_WIDTH     0x0b
  42#define MT9V022_RESET                   0x0c
  43#define MT9V022_READ_MODE               0x0d
  44#define MT9V022_MONITOR_MODE            0x0e
  45#define MT9V022_PIXEL_OPERATION_MODE    0x0f
  46#define MT9V022_LED_OUT_CONTROL         0x1b
  47#define MT9V022_ADC_MODE_CONTROL        0x1c
  48#define MT9V022_ANALOG_GAIN             0x35
  49#define MT9V022_BLACK_LEVEL_CALIB_CTRL  0x47
  50#define MT9V022_PIXCLK_FV_LV            0x74
  51#define MT9V022_DIGITAL_TEST_PATTERN    0x7f
  52#define MT9V022_AEC_AGC_ENABLE          0xAF
  53#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
  54
  55/* Progressive scan, master, defaults */
  56#define MT9V022_CHIP_CONTROL_DEFAULT    0x188
  57
  58#define MT9V022_MAX_WIDTH               752
  59#define MT9V022_MAX_HEIGHT              480
  60#define MT9V022_MIN_WIDTH               48
  61#define MT9V022_MIN_HEIGHT              32
  62#define MT9V022_COLUMN_SKIP             1
  63#define MT9V022_ROW_SKIP                4
  64
  65static const struct soc_camera_data_format mt9v022_colour_formats[] = {
  66        /* Order important: first natively supported,
  67         * second supported with a GPIO extender */
  68        {
  69                .name           = "Bayer (sRGB) 10 bit",
  70                .depth          = 10,
  71                .fourcc         = V4L2_PIX_FMT_SBGGR16,
  72                .colorspace     = V4L2_COLORSPACE_SRGB,
  73        }, {
  74                .name           = "Bayer (sRGB) 8 bit",
  75                .depth          = 8,
  76                .fourcc         = V4L2_PIX_FMT_SBGGR8,
  77                .colorspace     = V4L2_COLORSPACE_SRGB,
  78        }
  79};
  80
  81static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
  82        /* Order important - see above */
  83        {
  84                .name           = "Monochrome 10 bit",
  85                .depth          = 10,
  86                .fourcc         = V4L2_PIX_FMT_Y16,
  87        }, {
  88                .name           = "Monochrome 8 bit",
  89                .depth          = 8,
  90                .fourcc         = V4L2_PIX_FMT_GREY,
  91        },
  92};
  93
  94struct mt9v022 {
  95        struct v4l2_subdev subdev;
  96        struct v4l2_rect rect;  /* Sensor window */
  97        __u32 fourcc;
  98        int model;      /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
  99        u16 chip_control;
 100};
 101
 102static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
 103{
 104        return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
 105}
 106
 107static int reg_read(struct i2c_client *client, const u8 reg)
 108{
 109        s32 data = i2c_smbus_read_word_data(client, reg);
 110        return data < 0 ? data : swab16(data);
 111}
 112
 113static int reg_write(struct i2c_client *client, const u8 reg,
 114                     const u16 data)
 115{
 116        return i2c_smbus_write_word_data(client, reg, swab16(data));
 117}
 118
 119static int reg_set(struct i2c_client *client, const u8 reg,
 120                   const u16 data)
 121{
 122        int ret;
 123
 124        ret = reg_read(client, reg);
 125        if (ret < 0)
 126                return ret;
 127        return reg_write(client, reg, ret | data);
 128}
 129
 130static int reg_clear(struct i2c_client *client, const u8 reg,
 131                     const u16 data)
 132{
 133        int ret;
 134
 135        ret = reg_read(client, reg);
 136        if (ret < 0)
 137                return ret;
 138        return reg_write(client, reg, ret & ~data);
 139}
 140
 141static int mt9v022_init(struct i2c_client *client)
 142{
 143        struct mt9v022 *mt9v022 = to_mt9v022(client);
 144        int ret;
 145
 146        /* Almost the default mode: master, parallel, simultaneous, and an
 147         * undocumented bit 0x200, which is present in table 7, but not in 8,
 148         * plus snapshot mode to disable scan for now */
 149        mt9v022->chip_control |= 0x10;
 150        ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
 151        if (!ret)
 152                ret = reg_write(client, MT9V022_READ_MODE, 0x300);
 153
 154        /* All defaults */
 155        if (!ret)
 156                /* AEC, AGC on */
 157                ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
 158        if (!ret)
 159                ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
 160        if (!ret)
 161                ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
 162        if (!ret)
 163                ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
 164        if (!ret)
 165                /* default - auto */
 166                ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
 167        if (!ret)
 168                ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
 169
 170        return ret;
 171}
 172
 173static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
 174{
 175        struct i2c_client *client = sd->priv;
 176        struct mt9v022 *mt9v022 = to_mt9v022(client);
 177
 178        if (enable)
 179                /* Switch to master "normal" mode */
 180                mt9v022->chip_control &= ~0x10;
 181        else
 182                /* Switch to snapshot mode */
 183                mt9v022->chip_control |= 0x10;
 184
 185        if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
 186                return -EIO;
 187        return 0;
 188}
 189
 190static int mt9v022_set_bus_param(struct soc_camera_device *icd,
 191                                 unsigned long flags)
 192{
 193        struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
 194        struct mt9v022 *mt9v022 = to_mt9v022(client);
 195        struct soc_camera_link *icl = to_soc_camera_link(icd);
 196        unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
 197        int ret;
 198        u16 pixclk = 0;
 199
 200        /* Only one width bit may be set */
 201        if (!is_power_of_2(width_flag))
 202                return -EINVAL;
 203
 204        if (icl->set_bus_param) {
 205                ret = icl->set_bus_param(icl, width_flag);
 206                if (ret)
 207                        return ret;
 208        } else {
 209                /*
 210                 * Without board specific bus width settings we only support the
 211                 * sensors native bus width
 212                 */
 213                if (width_flag != SOCAM_DATAWIDTH_10)
 214                        return -EINVAL;
 215        }
 216
 217        flags = soc_camera_apply_sensor_flags(icl, flags);
 218
 219        if (flags & SOCAM_PCLK_SAMPLE_RISING)
 220                pixclk |= 0x10;
 221
 222        if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
 223                pixclk |= 0x1;
 224
 225        if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
 226                pixclk |= 0x2;
 227
 228        ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
 229        if (ret < 0)
 230                return ret;
 231
 232        if (!(flags & SOCAM_MASTER))
 233                mt9v022->chip_control &= ~0x8;
 234
 235        ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
 236        if (ret < 0)
 237                return ret;
 238
 239        dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
 240                pixclk, mt9v022->chip_control);
 241
 242        return 0;
 243}
 244
 245static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
 246{
 247        struct soc_camera_link *icl = to_soc_camera_link(icd);
 248        unsigned int width_flag;
 249
 250        if (icl->query_bus_param)
 251                width_flag = icl->query_bus_param(icl) &
 252                        SOCAM_DATAWIDTH_MASK;
 253        else
 254                width_flag = SOCAM_DATAWIDTH_10;
 255
 256        return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
 257                SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
 258                SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
 259                SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
 260                width_flag;
 261}
 262
 263static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 264{
 265        struct i2c_client *client = sd->priv;
 266        struct mt9v022 *mt9v022 = to_mt9v022(client);
 267        struct v4l2_rect rect = a->c;
 268        struct soc_camera_device *icd = client->dev.platform_data;
 269        int ret;
 270
 271        /* Bayer format - even size lengths */
 272        if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 ||
 273            mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
 274                rect.width      = ALIGN(rect.width, 2);
 275                rect.height     = ALIGN(rect.height, 2);
 276                /* Let the user play with the starting pixel */
 277        }
 278
 279        soc_camera_limit_side(&rect.left, &rect.width,
 280                     MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
 281
 282        soc_camera_limit_side(&rect.top, &rect.height,
 283                     MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
 284
 285        /* Like in example app. Contradicts the datasheet though */
 286        ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
 287        if (ret >= 0) {
 288                if (ret & 1) /* Autoexposure */
 289                        ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
 290                                        rect.height + icd->y_skip_top + 43);
 291                else
 292                        ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
 293                                        rect.height + icd->y_skip_top + 43);
 294        }
 295        /* Setup frame format: defaults apart from width and height */
 296        if (!ret)
 297                ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
 298        if (!ret)
 299                ret = reg_write(client, MT9V022_ROW_START, rect.top);
 300        if (!ret)
 301                /* Default 94, Phytec driver says:
 302                 * "width + horizontal blank >= 660" */
 303                ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
 304                                rect.width > 660 - 43 ? 43 :
 305                                660 - rect.width);
 306        if (!ret)
 307                ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
 308        if (!ret)
 309                ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
 310        if (!ret)
 311                ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
 312                                rect.height + icd->y_skip_top);
 313
 314        if (ret < 0)
 315                return ret;
 316
 317        dev_dbg(&client->dev, "Frame %ux%u pixel\n", rect.width, rect.height);
 318
 319        mt9v022->rect = rect;
 320
 321        return 0;
 322}
 323
 324static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 325{
 326        struct i2c_client *client = sd->priv;
 327        struct mt9v022 *mt9v022 = to_mt9v022(client);
 328
 329        a->c    = mt9v022->rect;
 330        a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 331
 332        return 0;
 333}
 334
 335static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 336{
 337        a->bounds.left                  = MT9V022_COLUMN_SKIP;
 338        a->bounds.top                   = MT9V022_ROW_SKIP;
 339        a->bounds.width                 = MT9V022_MAX_WIDTH;
 340        a->bounds.height                = MT9V022_MAX_HEIGHT;
 341        a->defrect                      = a->bounds;
 342        a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 343        a->pixelaspect.numerator        = 1;
 344        a->pixelaspect.denominator      = 1;
 345
 346        return 0;
 347}
 348
 349static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 350{
 351        struct i2c_client *client = sd->priv;
 352        struct mt9v022 *mt9v022 = to_mt9v022(client);
 353        struct v4l2_pix_format *pix = &f->fmt.pix;
 354
 355        pix->width              = mt9v022->rect.width;
 356        pix->height             = mt9v022->rect.height;
 357        pix->pixelformat        = mt9v022->fourcc;
 358        pix->field              = V4L2_FIELD_NONE;
 359        pix->colorspace         = V4L2_COLORSPACE_SRGB;
 360
 361        return 0;
 362}
 363
 364static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 365{
 366        struct i2c_client *client = sd->priv;
 367        struct mt9v022 *mt9v022 = to_mt9v022(client);
 368        struct v4l2_pix_format *pix = &f->fmt.pix;
 369        struct v4l2_crop a = {
 370                .c = {
 371                        .left   = mt9v022->rect.left,
 372                        .top    = mt9v022->rect.top,
 373                        .width  = pix->width,
 374                        .height = pix->height,
 375                },
 376        };
 377        int ret;
 378
 379        /* The caller provides a supported format, as verified per call to
 380         * icd->try_fmt(), datawidth is from our supported format list */
 381        switch (pix->pixelformat) {
 382        case V4L2_PIX_FMT_GREY:
 383        case V4L2_PIX_FMT_Y16:
 384                if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
 385                        return -EINVAL;
 386                break;
 387        case V4L2_PIX_FMT_SBGGR8:
 388        case V4L2_PIX_FMT_SBGGR16:
 389                if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
 390                        return -EINVAL;
 391                break;
 392        case 0:
 393                /* No format change, only geometry */
 394                break;
 395        default:
 396                return -EINVAL;
 397        }
 398
 399        /* No support for scaling on this camera, just crop. */
 400        ret = mt9v022_s_crop(sd, &a);
 401        if (!ret) {
 402                pix->width = mt9v022->rect.width;
 403                pix->height = mt9v022->rect.height;
 404                mt9v022->fourcc = pix->pixelformat;
 405        }
 406
 407        return ret;
 408}
 409
 410static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 411{
 412        struct i2c_client *client = sd->priv;
 413        struct soc_camera_device *icd = client->dev.platform_data;
 414        struct v4l2_pix_format *pix = &f->fmt.pix;
 415        int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
 416                pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
 417
 418        v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
 419                MT9V022_MAX_WIDTH, align,
 420                &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top,
 421                MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0);
 422
 423        return 0;
 424}
 425
 426static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
 427                                struct v4l2_dbg_chip_ident *id)
 428{
 429        struct i2c_client *client = sd->priv;
 430        struct mt9v022 *mt9v022 = to_mt9v022(client);
 431
 432        if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
 433                return -EINVAL;
 434
 435        if (id->match.addr != client->addr)
 436                return -ENODEV;
 437
 438        id->ident       = mt9v022->model;
 439        id->revision    = 0;
 440
 441        return 0;
 442}
 443
 444#ifdef CONFIG_VIDEO_ADV_DEBUG
 445static int mt9v022_g_register(struct v4l2_subdev *sd,
 446                              struct v4l2_dbg_register *reg)
 447{
 448        struct i2c_client *client = sd->priv;
 449
 450        if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 451                return -EINVAL;
 452
 453        if (reg->match.addr != client->addr)
 454                return -ENODEV;
 455
 456        reg->size = 2;
 457        reg->val = reg_read(client, reg->reg);
 458
 459        if (reg->val > 0xffff)
 460                return -EIO;
 461
 462        return 0;
 463}
 464
 465static int mt9v022_s_register(struct v4l2_subdev *sd,
 466                              struct v4l2_dbg_register *reg)
 467{
 468        struct i2c_client *client = sd->priv;
 469
 470        if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 471                return -EINVAL;
 472
 473        if (reg->match.addr != client->addr)
 474                return -ENODEV;
 475
 476        if (reg_write(client, reg->reg, reg->val) < 0)
 477                return -EIO;
 478
 479        return 0;
 480}
 481#endif
 482
 483static const struct v4l2_queryctrl mt9v022_controls[] = {
 484        {
 485                .id             = V4L2_CID_VFLIP,
 486                .type           = V4L2_CTRL_TYPE_BOOLEAN,
 487                .name           = "Flip Vertically",
 488                .minimum        = 0,
 489                .maximum        = 1,
 490                .step           = 1,
 491                .default_value  = 0,
 492        }, {
 493                .id             = V4L2_CID_HFLIP,
 494                .type           = V4L2_CTRL_TYPE_BOOLEAN,
 495                .name           = "Flip Horizontally",
 496                .minimum        = 0,
 497                .maximum        = 1,
 498                .step           = 1,
 499                .default_value  = 0,
 500        }, {
 501                .id             = V4L2_CID_GAIN,
 502                .type           = V4L2_CTRL_TYPE_INTEGER,
 503                .name           = "Analog Gain",
 504                .minimum        = 64,
 505                .maximum        = 127,
 506                .step           = 1,
 507                .default_value  = 64,
 508                .flags          = V4L2_CTRL_FLAG_SLIDER,
 509        }, {
 510                .id             = V4L2_CID_EXPOSURE,
 511                .type           = V4L2_CTRL_TYPE_INTEGER,
 512                .name           = "Exposure",
 513                .minimum        = 1,
 514                .maximum        = 255,
 515                .step           = 1,
 516                .default_value  = 255,
 517                .flags          = V4L2_CTRL_FLAG_SLIDER,
 518        }, {
 519                .id             = V4L2_CID_AUTOGAIN,
 520                .type           = V4L2_CTRL_TYPE_BOOLEAN,
 521                .name           = "Automatic Gain",
 522                .minimum        = 0,
 523                .maximum        = 1,
 524                .step           = 1,
 525                .default_value  = 1,
 526        }, {
 527                .id             = V4L2_CID_EXPOSURE_AUTO,
 528                .type           = V4L2_CTRL_TYPE_BOOLEAN,
 529                .name           = "Automatic Exposure",
 530                .minimum        = 0,
 531                .maximum        = 1,
 532                .step           = 1,
 533                .default_value  = 1,
 534        }
 535};
 536
 537static struct soc_camera_ops mt9v022_ops = {
 538        .set_bus_param          = mt9v022_set_bus_param,
 539        .query_bus_param        = mt9v022_query_bus_param,
 540        .controls               = mt9v022_controls,
 541        .num_controls           = ARRAY_SIZE(mt9v022_controls),
 542};
 543
 544static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 545{
 546        struct i2c_client *client = sd->priv;
 547        const struct v4l2_queryctrl *qctrl;
 548        unsigned long range;
 549        int data;
 550
 551        qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
 552
 553        switch (ctrl->id) {
 554        case V4L2_CID_VFLIP:
 555                data = reg_read(client, MT9V022_READ_MODE);
 556                if (data < 0)
 557                        return -EIO;
 558                ctrl->value = !!(data & 0x10);
 559                break;
 560        case V4L2_CID_HFLIP:
 561                data = reg_read(client, MT9V022_READ_MODE);
 562                if (data < 0)
 563                        return -EIO;
 564                ctrl->value = !!(data & 0x20);
 565                break;
 566        case V4L2_CID_EXPOSURE_AUTO:
 567                data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
 568                if (data < 0)
 569                        return -EIO;
 570                ctrl->value = !!(data & 0x1);
 571                break;
 572        case V4L2_CID_AUTOGAIN:
 573                data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
 574                if (data < 0)
 575                        return -EIO;
 576                ctrl->value = !!(data & 0x2);
 577                break;
 578        case V4L2_CID_GAIN:
 579                data = reg_read(client, MT9V022_ANALOG_GAIN);
 580                if (data < 0)
 581                        return -EIO;
 582
 583                range = qctrl->maximum - qctrl->minimum;
 584                ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum;
 585
 586                break;
 587        case V4L2_CID_EXPOSURE:
 588                data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
 589                if (data < 0)
 590                        return -EIO;
 591
 592                range = qctrl->maximum - qctrl->minimum;
 593                ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum;
 594
 595                break;
 596        }
 597        return 0;
 598}
 599
 600static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 601{
 602        int data;
 603        struct i2c_client *client = sd->priv;
 604        const struct v4l2_queryctrl *qctrl;
 605
 606        qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
 607        if (!qctrl)
 608                return -EINVAL;
 609
 610        switch (ctrl->id) {
 611        case V4L2_CID_VFLIP:
 612                if (ctrl->value)
 613                        data = reg_set(client, MT9V022_READ_MODE, 0x10);
 614                else
 615                        data = reg_clear(client, MT9V022_READ_MODE, 0x10);
 616                if (data < 0)
 617                        return -EIO;
 618                break;
 619        case V4L2_CID_HFLIP:
 620                if (ctrl->value)
 621                        data = reg_set(client, MT9V022_READ_MODE, 0x20);
 622                else
 623                        data = reg_clear(client, MT9V022_READ_MODE, 0x20);
 624                if (data < 0)
 625                        return -EIO;
 626                break;
 627        case V4L2_CID_GAIN:
 628                /* mt9v022 has minimum == default */
 629                if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
 630                        return -EINVAL;
 631                else {
 632                        unsigned long range = qctrl->maximum - qctrl->minimum;
 633                        /* Valid values 16 to 64, 32 to 64 must be even. */
 634                        unsigned long gain = ((ctrl->value - qctrl->minimum) *
 635                                              48 + range / 2) / range + 16;
 636                        if (gain >= 32)
 637                                gain &= ~1;
 638                        /* The user wants to set gain manually, hope, she
 639                         * knows, what she's doing... Switch AGC off. */
 640
 641                        if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
 642                                return -EIO;
 643
 644                        dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
 645                                reg_read(client, MT9V022_ANALOG_GAIN), gain);
 646                        if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
 647                                return -EIO;
 648                }
 649                break;
 650        case V4L2_CID_EXPOSURE:
 651                /* mt9v022 has maximum == default */
 652                if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
 653                        return -EINVAL;
 654                else {
 655                        unsigned long range = qctrl->maximum - qctrl->minimum;
 656                        unsigned long shutter = ((ctrl->value - qctrl->minimum) *
 657                                                 479 + range / 2) / range + 1;
 658                        /* The user wants to set shutter width manually, hope,
 659                         * she knows, what she's doing... Switch AEC off. */
 660
 661                        if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
 662                                return -EIO;
 663
 664                        dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
 665                                reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
 666                                shutter);
 667                        if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
 668                                      shutter) < 0)
 669                                return -EIO;
 670                }
 671                break;
 672        case V4L2_CID_AUTOGAIN:
 673                if (ctrl->value)
 674                        data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
 675                else
 676                        data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
 677                if (data < 0)
 678                        return -EIO;
 679                break;
 680        case V4L2_CID_EXPOSURE_AUTO:
 681                if (ctrl->value)
 682                        data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
 683                else
 684                        data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
 685                if (data < 0)
 686                        return -EIO;
 687                break;
 688        }
 689        return 0;
 690}
 691
 692/* Interface active, can use i2c. If it fails, it can indeed mean, that
 693 * this wasn't our capture interface, so, we wait for the right one */
 694static int mt9v022_video_probe(struct soc_camera_device *icd,
 695                               struct i2c_client *client)
 696{
 697        struct mt9v022 *mt9v022 = to_mt9v022(client);
 698        struct soc_camera_link *icl = to_soc_camera_link(icd);
 699        s32 data;
 700        int ret;
 701        unsigned long flags;
 702
 703        if (!icd->dev.parent ||
 704            to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
 705                return -ENODEV;
 706
 707        /* Read out the chip version register */
 708        data = reg_read(client, MT9V022_CHIP_VERSION);
 709
 710        /* must be 0x1311 or 0x1313 */
 711        if (data != 0x1311 && data != 0x1313) {
 712                ret = -ENODEV;
 713                dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
 714                         data);
 715                goto ei2c;
 716        }
 717
 718        /* Soft reset */
 719        ret = reg_write(client, MT9V022_RESET, 1);
 720        if (ret < 0)
 721                goto ei2c;
 722        /* 15 clock cycles */
 723        udelay(200);
 724        if (reg_read(client, MT9V022_RESET)) {
 725                dev_err(&client->dev, "Resetting MT9V022 failed!\n");
 726                if (ret > 0)
 727                        ret = -EIO;
 728                goto ei2c;
 729        }
 730
 731        /* Set monochrome or colour sensor type */
 732        if (sensor_type && (!strcmp("colour", sensor_type) ||
 733                            !strcmp("color", sensor_type))) {
 734                ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
 735                mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
 736                icd->formats = mt9v022_colour_formats;
 737        } else {
 738                ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
 739                mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
 740                icd->formats = mt9v022_monochrome_formats;
 741        }
 742
 743        if (ret < 0)
 744                goto ei2c;
 745
 746        icd->num_formats = 0;
 747
 748        /*
 749         * This is a 10bit sensor, so by default we only allow 10bit.
 750         * The platform may support different bus widths due to
 751         * different routing of the data lines.
 752         */
 753        if (icl->query_bus_param)
 754                flags = icl->query_bus_param(icl);
 755        else
 756                flags = SOCAM_DATAWIDTH_10;
 757
 758        if (flags & SOCAM_DATAWIDTH_10)
 759                icd->num_formats++;
 760        else
 761                icd->formats++;
 762
 763        if (flags & SOCAM_DATAWIDTH_8)
 764                icd->num_formats++;
 765
 766        mt9v022->fourcc = icd->formats->fourcc;
 767
 768        dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
 769                 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
 770                 "monochrome" : "colour");
 771
 772        ret = mt9v022_init(client);
 773        if (ret < 0)
 774                dev_err(&client->dev, "Failed to initialise the camera\n");
 775
 776ei2c:
 777        return ret;
 778}
 779
 780static void mt9v022_video_remove(struct soc_camera_device *icd)
 781{
 782        struct soc_camera_link *icl = to_soc_camera_link(icd);
 783
 784        dev_dbg(&icd->dev, "Video removed: %p, %p\n",
 785                icd->dev.parent, icd->vdev);
 786        if (icl->free_bus)
 787                icl->free_bus(icl);
 788}
 789
 790static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
 791        .g_ctrl         = mt9v022_g_ctrl,
 792        .s_ctrl         = mt9v022_s_ctrl,
 793        .g_chip_ident   = mt9v022_g_chip_ident,
 794#ifdef CONFIG_VIDEO_ADV_DEBUG
 795        .g_register     = mt9v022_g_register,
 796        .s_register     = mt9v022_s_register,
 797#endif
 798};
 799
 800static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
 801        .s_stream       = mt9v022_s_stream,
 802        .s_fmt          = mt9v022_s_fmt,
 803        .g_fmt          = mt9v022_g_fmt,
 804        .try_fmt        = mt9v022_try_fmt,
 805        .s_crop         = mt9v022_s_crop,
 806        .g_crop         = mt9v022_g_crop,
 807        .cropcap        = mt9v022_cropcap,
 808};
 809
 810static struct v4l2_subdev_ops mt9v022_subdev_ops = {
 811        .core   = &mt9v022_subdev_core_ops,
 812        .video  = &mt9v022_subdev_video_ops,
 813};
 814
 815static int mt9v022_probe(struct i2c_client *client,
 816                         const struct i2c_device_id *did)
 817{
 818        struct mt9v022 *mt9v022;
 819        struct soc_camera_device *icd = client->dev.platform_data;
 820        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 821        struct soc_camera_link *icl;
 822        int ret;
 823
 824        if (!icd) {
 825                dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
 826                return -EINVAL;
 827        }
 828
 829        icl = to_soc_camera_link(icd);
 830        if (!icl) {
 831                dev_err(&client->dev, "MT9V022 driver needs platform data\n");
 832                return -EINVAL;
 833        }
 834
 835        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
 836                dev_warn(&adapter->dev,
 837                         "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
 838                return -EIO;
 839        }
 840
 841        mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL);
 842        if (!mt9v022)
 843                return -ENOMEM;
 844
 845        v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
 846
 847        mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
 848
 849        icd->ops                = &mt9v022_ops;
 850        /*
 851         * MT9V022 _really_ corrupts the first read out line.
 852         * TODO: verify on i.MX31
 853         */
 854        icd->y_skip_top         = 1;
 855
 856        mt9v022->rect.left      = MT9V022_COLUMN_SKIP;
 857        mt9v022->rect.top       = MT9V022_ROW_SKIP;
 858        mt9v022->rect.width     = MT9V022_MAX_WIDTH;
 859        mt9v022->rect.height    = MT9V022_MAX_HEIGHT;
 860
 861        ret = mt9v022_video_probe(icd, client);
 862        if (ret) {
 863                icd->ops = NULL;
 864                i2c_set_clientdata(client, NULL);
 865                kfree(mt9v022);
 866        }
 867
 868        return ret;
 869}
 870
 871static int mt9v022_remove(struct i2c_client *client)
 872{
 873        struct mt9v022 *mt9v022 = to_mt9v022(client);
 874        struct soc_camera_device *icd = client->dev.platform_data;
 875
 876        icd->ops = NULL;
 877        mt9v022_video_remove(icd);
 878        i2c_set_clientdata(client, NULL);
 879        client->driver = NULL;
 880        kfree(mt9v022);
 881
 882        return 0;
 883}
 884static const struct i2c_device_id mt9v022_id[] = {
 885        { "mt9v022", 0 },
 886        { }
 887};
 888MODULE_DEVICE_TABLE(i2c, mt9v022_id);
 889
 890static struct i2c_driver mt9v022_i2c_driver = {
 891        .driver = {
 892                .name = "mt9v022",
 893        },
 894        .probe          = mt9v022_probe,
 895        .remove         = mt9v022_remove,
 896        .id_table       = mt9v022_id,
 897};
 898
 899static int __init mt9v022_mod_init(void)
 900{
 901        return i2c_add_driver(&mt9v022_i2c_driver);
 902}
 903
 904static void __exit mt9v022_mod_exit(void)
 905{
 906        i2c_del_driver(&mt9v022_i2c_driver);
 907}
 908
 909module_init(mt9v022_mod_init);
 910module_exit(mt9v022_mod_exit);
 911
 912MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
 913MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
 914MODULE_LICENSE("GPL");
 915