linux/drivers/media/video/mt9m001.c
<<
>>
Prefs
   1/*
   2 * Driver for MT9M001 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/log2.h>
  15
  16#include <media/v4l2-subdev.h>
  17#include <media/v4l2-chip-ident.h>
  18#include <media/soc_camera.h>
  19
  20/*
  21 * mt9m001 i2c address 0x5d
  22 * The platform has to define ctruct i2c_board_info objects and link to them
  23 * from struct soc_camera_link
  24 */
  25
  26/* mt9m001 selected register addresses */
  27#define MT9M001_CHIP_VERSION            0x00
  28#define MT9M001_ROW_START               0x01
  29#define MT9M001_COLUMN_START            0x02
  30#define MT9M001_WINDOW_HEIGHT           0x03
  31#define MT9M001_WINDOW_WIDTH            0x04
  32#define MT9M001_HORIZONTAL_BLANKING     0x05
  33#define MT9M001_VERTICAL_BLANKING       0x06
  34#define MT9M001_OUTPUT_CONTROL          0x07
  35#define MT9M001_SHUTTER_WIDTH           0x09
  36#define MT9M001_FRAME_RESTART           0x0b
  37#define MT9M001_SHUTTER_DELAY           0x0c
  38#define MT9M001_RESET                   0x0d
  39#define MT9M001_READ_OPTIONS1           0x1e
  40#define MT9M001_READ_OPTIONS2           0x20
  41#define MT9M001_GLOBAL_GAIN             0x35
  42#define MT9M001_CHIP_ENABLE             0xF1
  43
  44#define MT9M001_MAX_WIDTH               1280
  45#define MT9M001_MAX_HEIGHT              1024
  46#define MT9M001_MIN_WIDTH               48
  47#define MT9M001_MIN_HEIGHT              32
  48#define MT9M001_COLUMN_SKIP             20
  49#define MT9M001_ROW_SKIP                12
  50
  51/* MT9M001 has only one fixed colorspace per pixelcode */
  52struct mt9m001_datafmt {
  53        enum v4l2_mbus_pixelcode        code;
  54        enum v4l2_colorspace            colorspace;
  55};
  56
  57/* Find a data format by a pixel code in an array */
  58static const struct mt9m001_datafmt *mt9m001_find_datafmt(
  59        enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt,
  60        int n)
  61{
  62        int i;
  63        for (i = 0; i < n; i++)
  64                if (fmt[i].code == code)
  65                        return fmt + i;
  66
  67        return NULL;
  68}
  69
  70static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
  71        /*
  72         * Order important: first natively supported,
  73         * second supported with a GPIO extender
  74         */
  75        {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
  76        {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
  77};
  78
  79static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
  80        /* Order important - see above */
  81        {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
  82        {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
  83};
  84
  85struct mt9m001 {
  86        struct v4l2_subdev subdev;
  87        struct v4l2_rect rect;  /* Sensor window */
  88        const struct mt9m001_datafmt *fmt;
  89        const struct mt9m001_datafmt *fmts;
  90        int num_fmts;
  91        int model;      /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
  92        unsigned int gain;
  93        unsigned int exposure;
  94        unsigned short y_skip_top;      /* Lines to skip at the top */
  95        unsigned char autoexposure;
  96};
  97
  98static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
  99{
 100        return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
 101}
 102
 103static int reg_read(struct i2c_client *client, const u8 reg)
 104{
 105        s32 data = i2c_smbus_read_word_data(client, reg);
 106        return data < 0 ? data : swab16(data);
 107}
 108
 109static int reg_write(struct i2c_client *client, const u8 reg,
 110                     const u16 data)
 111{
 112        return i2c_smbus_write_word_data(client, reg, swab16(data));
 113}
 114
 115static int reg_set(struct i2c_client *client, const u8 reg,
 116                   const u16 data)
 117{
 118        int ret;
 119
 120        ret = reg_read(client, reg);
 121        if (ret < 0)
 122                return ret;
 123        return reg_write(client, reg, ret | data);
 124}
 125
 126static int reg_clear(struct i2c_client *client, const u8 reg,
 127                     const u16 data)
 128{
 129        int ret;
 130
 131        ret = reg_read(client, reg);
 132        if (ret < 0)
 133                return ret;
 134        return reg_write(client, reg, ret & ~data);
 135}
 136
 137static int mt9m001_init(struct i2c_client *client)
 138{
 139        int ret;
 140
 141        dev_dbg(&client->dev, "%s\n", __func__);
 142
 143        /*
 144         * We don't know, whether platform provides reset, issue a soft reset
 145         * too. This returns all registers to their default values.
 146         */
 147        ret = reg_write(client, MT9M001_RESET, 1);
 148        if (!ret)
 149                ret = reg_write(client, MT9M001_RESET, 0);
 150
 151        /* Disable chip, synchronous option update */
 152        if (!ret)
 153                ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
 154
 155        return ret;
 156}
 157
 158static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
 159{
 160        struct i2c_client *client = sd->priv;
 161
 162        /* Switch to master "normal" mode or stop sensor readout */
 163        if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
 164                return -EIO;
 165        return 0;
 166}
 167
 168static int mt9m001_set_bus_param(struct soc_camera_device *icd,
 169                                 unsigned long flags)
 170{
 171        struct soc_camera_link *icl = to_soc_camera_link(icd);
 172        unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
 173
 174        /* Only one width bit may be set */
 175        if (!is_power_of_2(width_flag))
 176                return -EINVAL;
 177
 178        if (icl->set_bus_param)
 179                return icl->set_bus_param(icl, width_flag);
 180
 181        /*
 182         * Without board specific bus width settings we only support the
 183         * sensors native bus width
 184         */
 185        if (width_flag == SOCAM_DATAWIDTH_10)
 186                return 0;
 187
 188        return -EINVAL;
 189}
 190
 191static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
 192{
 193        struct soc_camera_link *icl = to_soc_camera_link(icd);
 194        /* MT9M001 has all capture_format parameters fixed */
 195        unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
 196                SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
 197                SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
 198
 199        if (icl->query_bus_param)
 200                flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
 201        else
 202                flags |= SOCAM_DATAWIDTH_10;
 203
 204        return soc_camera_apply_sensor_flags(icl, flags);
 205}
 206
 207static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 208{
 209        struct i2c_client *client = sd->priv;
 210        struct mt9m001 *mt9m001 = to_mt9m001(client);
 211        struct v4l2_rect rect = a->c;
 212        struct soc_camera_device *icd = client->dev.platform_data;
 213        int ret;
 214        const u16 hblank = 9, vblank = 25;
 215        unsigned int total_h;
 216
 217        if (mt9m001->fmts == mt9m001_colour_fmts)
 218                /*
 219                 * Bayer format - even number of rows for simplicity,
 220                 * but let the user play with the top row.
 221                 */
 222                rect.height = ALIGN(rect.height, 2);
 223
 224        /* Datasheet requirement: see register description */
 225        rect.width = ALIGN(rect.width, 2);
 226        rect.left = ALIGN(rect.left, 2);
 227
 228        soc_camera_limit_side(&rect.left, &rect.width,
 229                     MT9M001_COLUMN_SKIP, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH);
 230
 231        soc_camera_limit_side(&rect.top, &rect.height,
 232                     MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
 233
 234        total_h = rect.height + mt9m001->y_skip_top + vblank;
 235
 236        /* Blanking and start values - default... */
 237        ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
 238        if (!ret)
 239                ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
 240
 241        /*
 242         * The caller provides a supported format, as verified per
 243         * call to icd->try_fmt()
 244         */
 245        if (!ret)
 246                ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
 247        if (!ret)
 248                ret = reg_write(client, MT9M001_ROW_START, rect.top);
 249        if (!ret)
 250                ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
 251        if (!ret)
 252                ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
 253                                rect.height + mt9m001->y_skip_top - 1);
 254        if (!ret && mt9m001->autoexposure) {
 255                ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
 256                if (!ret) {
 257                        const struct v4l2_queryctrl *qctrl =
 258                                soc_camera_find_qctrl(icd->ops,
 259                                                      V4L2_CID_EXPOSURE);
 260                        mt9m001->exposure = (524 + (total_h - 1) *
 261                                 (qctrl->maximum - qctrl->minimum)) /
 262                                1048 + qctrl->minimum;
 263                }
 264        }
 265
 266        if (!ret)
 267                mt9m001->rect = rect;
 268
 269        return ret;
 270}
 271
 272static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 273{
 274        struct i2c_client *client = sd->priv;
 275        struct mt9m001 *mt9m001 = to_mt9m001(client);
 276
 277        a->c    = mt9m001->rect;
 278        a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 279
 280        return 0;
 281}
 282
 283static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 284{
 285        a->bounds.left                  = MT9M001_COLUMN_SKIP;
 286        a->bounds.top                   = MT9M001_ROW_SKIP;
 287        a->bounds.width                 = MT9M001_MAX_WIDTH;
 288        a->bounds.height                = MT9M001_MAX_HEIGHT;
 289        a->defrect                      = a->bounds;
 290        a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 291        a->pixelaspect.numerator        = 1;
 292        a->pixelaspect.denominator      = 1;
 293
 294        return 0;
 295}
 296
 297static int mt9m001_g_fmt(struct v4l2_subdev *sd,
 298                         struct v4l2_mbus_framefmt *mf)
 299{
 300        struct i2c_client *client = sd->priv;
 301        struct mt9m001 *mt9m001 = to_mt9m001(client);
 302
 303        mf->width       = mt9m001->rect.width;
 304        mf->height      = mt9m001->rect.height;
 305        mf->code        = mt9m001->fmt->code;
 306        mf->colorspace  = mt9m001->fmt->colorspace;
 307        mf->field       = V4L2_FIELD_NONE;
 308
 309        return 0;
 310}
 311
 312static int mt9m001_s_fmt(struct v4l2_subdev *sd,
 313                         struct v4l2_mbus_framefmt *mf)
 314{
 315        struct i2c_client *client = sd->priv;
 316        struct mt9m001 *mt9m001 = to_mt9m001(client);
 317        struct v4l2_crop a = {
 318                .c = {
 319                        .left   = mt9m001->rect.left,
 320                        .top    = mt9m001->rect.top,
 321                        .width  = mf->width,
 322                        .height = mf->height,
 323                },
 324        };
 325        int ret;
 326
 327        /* No support for scaling so far, just crop. TODO: use skipping */
 328        ret = mt9m001_s_crop(sd, &a);
 329        if (!ret) {
 330                mf->width       = mt9m001->rect.width;
 331                mf->height      = mt9m001->rect.height;
 332                mt9m001->fmt    = mt9m001_find_datafmt(mf->code,
 333                                        mt9m001->fmts, mt9m001->num_fmts);
 334                mf->colorspace  = mt9m001->fmt->colorspace;
 335        }
 336
 337        return ret;
 338}
 339
 340static int mt9m001_try_fmt(struct v4l2_subdev *sd,
 341                           struct v4l2_mbus_framefmt *mf)
 342{
 343        struct i2c_client *client = sd->priv;
 344        struct mt9m001 *mt9m001 = to_mt9m001(client);
 345        const struct mt9m001_datafmt *fmt;
 346
 347        v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
 348                MT9M001_MAX_WIDTH, 1,
 349                &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
 350                MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);
 351
 352        if (mt9m001->fmts == mt9m001_colour_fmts)
 353                mf->height = ALIGN(mf->height - 1, 2);
 354
 355        fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts,
 356                                   mt9m001->num_fmts);
 357        if (!fmt) {
 358                fmt = mt9m001->fmt;
 359                mf->code = fmt->code;
 360        }
 361
 362        mf->colorspace  = fmt->colorspace;
 363
 364        return 0;
 365}
 366
 367static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
 368                                struct v4l2_dbg_chip_ident *id)
 369{
 370        struct i2c_client *client = sd->priv;
 371        struct mt9m001 *mt9m001 = to_mt9m001(client);
 372
 373        if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
 374                return -EINVAL;
 375
 376        if (id->match.addr != client->addr)
 377                return -ENODEV;
 378
 379        id->ident       = mt9m001->model;
 380        id->revision    = 0;
 381
 382        return 0;
 383}
 384
 385#ifdef CONFIG_VIDEO_ADV_DEBUG
 386static int mt9m001_g_register(struct v4l2_subdev *sd,
 387                              struct v4l2_dbg_register *reg)
 388{
 389        struct i2c_client *client = sd->priv;
 390
 391        if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 392                return -EINVAL;
 393
 394        if (reg->match.addr != client->addr)
 395                return -ENODEV;
 396
 397        reg->size = 2;
 398        reg->val = reg_read(client, reg->reg);
 399
 400        if (reg->val > 0xffff)
 401                return -EIO;
 402
 403        return 0;
 404}
 405
 406static int mt9m001_s_register(struct v4l2_subdev *sd,
 407                              struct v4l2_dbg_register *reg)
 408{
 409        struct i2c_client *client = sd->priv;
 410
 411        if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 412                return -EINVAL;
 413
 414        if (reg->match.addr != client->addr)
 415                return -ENODEV;
 416
 417        if (reg_write(client, reg->reg, reg->val) < 0)
 418                return -EIO;
 419
 420        return 0;
 421}
 422#endif
 423
 424static const struct v4l2_queryctrl mt9m001_controls[] = {
 425        {
 426                .id             = V4L2_CID_VFLIP,
 427                .type           = V4L2_CTRL_TYPE_BOOLEAN,
 428                .name           = "Flip Vertically",
 429                .minimum        = 0,
 430                .maximum        = 1,
 431                .step           = 1,
 432                .default_value  = 0,
 433        }, {
 434                .id             = V4L2_CID_GAIN,
 435                .type           = V4L2_CTRL_TYPE_INTEGER,
 436                .name           = "Gain",
 437                .minimum        = 0,
 438                .maximum        = 127,
 439                .step           = 1,
 440                .default_value  = 64,
 441                .flags          = V4L2_CTRL_FLAG_SLIDER,
 442        }, {
 443                .id             = V4L2_CID_EXPOSURE,
 444                .type           = V4L2_CTRL_TYPE_INTEGER,
 445                .name           = "Exposure",
 446                .minimum        = 1,
 447                .maximum        = 255,
 448                .step           = 1,
 449                .default_value  = 255,
 450                .flags          = V4L2_CTRL_FLAG_SLIDER,
 451        }, {
 452                .id             = V4L2_CID_EXPOSURE_AUTO,
 453                .type           = V4L2_CTRL_TYPE_BOOLEAN,
 454                .name           = "Automatic Exposure",
 455                .minimum        = 0,
 456                .maximum        = 1,
 457                .step           = 1,
 458                .default_value  = 1,
 459        }
 460};
 461
 462static struct soc_camera_ops mt9m001_ops = {
 463        .set_bus_param          = mt9m001_set_bus_param,
 464        .query_bus_param        = mt9m001_query_bus_param,
 465        .controls               = mt9m001_controls,
 466        .num_controls           = ARRAY_SIZE(mt9m001_controls),
 467};
 468
 469static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 470{
 471        struct i2c_client *client = sd->priv;
 472        struct mt9m001 *mt9m001 = to_mt9m001(client);
 473        int data;
 474
 475        switch (ctrl->id) {
 476        case V4L2_CID_VFLIP:
 477                data = reg_read(client, MT9M001_READ_OPTIONS2);
 478                if (data < 0)
 479                        return -EIO;
 480                ctrl->value = !!(data & 0x8000);
 481                break;
 482        case V4L2_CID_EXPOSURE_AUTO:
 483                ctrl->value = mt9m001->autoexposure;
 484                break;
 485        case V4L2_CID_GAIN:
 486                ctrl->value = mt9m001->gain;
 487                break;
 488        case V4L2_CID_EXPOSURE:
 489                ctrl->value = mt9m001->exposure;
 490                break;
 491        }
 492        return 0;
 493}
 494
 495static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 496{
 497        struct i2c_client *client = sd->priv;
 498        struct mt9m001 *mt9m001 = to_mt9m001(client);
 499        struct soc_camera_device *icd = client->dev.platform_data;
 500        const struct v4l2_queryctrl *qctrl;
 501        int data;
 502
 503        qctrl = soc_camera_find_qctrl(&mt9m001_ops, ctrl->id);
 504
 505        if (!qctrl)
 506                return -EINVAL;
 507
 508        switch (ctrl->id) {
 509        case V4L2_CID_VFLIP:
 510                if (ctrl->value)
 511                        data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
 512                else
 513                        data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
 514                if (data < 0)
 515                        return -EIO;
 516                break;
 517        case V4L2_CID_GAIN:
 518                if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
 519                        return -EINVAL;
 520                /* See Datasheet Table 7, Gain settings. */
 521                if (ctrl->value <= qctrl->default_value) {
 522                        /* Pack it into 0..1 step 0.125, register values 0..8 */
 523                        unsigned long range = qctrl->default_value - qctrl->minimum;
 524                        data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
 525
 526                        dev_dbg(&client->dev, "Setting gain %d\n", data);
 527                        data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
 528                        if (data < 0)
 529                                return -EIO;
 530                } else {
 531                        /* Pack it into 1.125..15 variable step, register values 9..67 */
 532                        /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
 533                        unsigned long range = qctrl->maximum - qctrl->default_value - 1;
 534                        unsigned long gain = ((ctrl->value - qctrl->default_value - 1) *
 535                                               111 + range / 2) / range + 9;
 536
 537                        if (gain <= 32)
 538                                data = gain;
 539                        else if (gain <= 64)
 540                                data = ((gain - 32) * 16 + 16) / 32 + 80;
 541                        else
 542                                data = ((gain - 64) * 7 + 28) / 56 + 96;
 543
 544                        dev_dbg(&client->dev, "Setting gain from %d to %d\n",
 545                                 reg_read(client, MT9M001_GLOBAL_GAIN), data);
 546                        data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
 547                        if (data < 0)
 548                                return -EIO;
 549                }
 550
 551                /* Success */
 552                mt9m001->gain = ctrl->value;
 553                break;
 554        case V4L2_CID_EXPOSURE:
 555                /* mt9m001 has maximum == default */
 556                if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
 557                        return -EINVAL;
 558                else {
 559                        unsigned long range = qctrl->maximum - qctrl->minimum;
 560                        unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 +
 561                                                 range / 2) / range + 1;
 562
 563                        dev_dbg(&client->dev,
 564                                "Setting shutter width from %d to %lu\n",
 565                                reg_read(client, MT9M001_SHUTTER_WIDTH),
 566                                shutter);
 567                        if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
 568                                return -EIO;
 569                        mt9m001->exposure = ctrl->value;
 570                        mt9m001->autoexposure = 0;
 571                }
 572                break;
 573        case V4L2_CID_EXPOSURE_AUTO:
 574                if (ctrl->value) {
 575                        const u16 vblank = 25;
 576                        unsigned int total_h = mt9m001->rect.height +
 577                                mt9m001->y_skip_top + vblank;
 578                        if (reg_write(client, MT9M001_SHUTTER_WIDTH,
 579                                      total_h) < 0)
 580                                return -EIO;
 581                        qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
 582                        mt9m001->exposure = (524 + (total_h - 1) *
 583                                 (qctrl->maximum - qctrl->minimum)) /
 584                                1048 + qctrl->minimum;
 585                        mt9m001->autoexposure = 1;
 586                } else
 587                        mt9m001->autoexposure = 0;
 588                break;
 589        }
 590        return 0;
 591}
 592
 593/*
 594 * Interface active, can use i2c. If it fails, it can indeed mean, that
 595 * this wasn't our capture interface, so, we wait for the right one
 596 */
 597static int mt9m001_video_probe(struct soc_camera_device *icd,
 598                               struct i2c_client *client)
 599{
 600        struct mt9m001 *mt9m001 = to_mt9m001(client);
 601        struct soc_camera_link *icl = to_soc_camera_link(icd);
 602        s32 data;
 603        unsigned long flags;
 604        int ret;
 605
 606        /*
 607         * We must have a parent by now. And it cannot be a wrong one.
 608         * So this entire test is completely redundant.
 609         */
 610        if (!icd->dev.parent ||
 611            to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
 612                return -ENODEV;
 613
 614        /* Enable the chip */
 615        data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
 616        dev_dbg(&client->dev, "write: %d\n", data);
 617
 618        /* Read out the chip version register */
 619        data = reg_read(client, MT9M001_CHIP_VERSION);
 620
 621        /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
 622        switch (data) {
 623        case 0x8411:
 624        case 0x8421:
 625                mt9m001->model = V4L2_IDENT_MT9M001C12ST;
 626                mt9m001->fmts = mt9m001_colour_fmts;
 627                break;
 628        case 0x8431:
 629                mt9m001->model = V4L2_IDENT_MT9M001C12STM;
 630                mt9m001->fmts = mt9m001_monochrome_fmts;
 631                break;
 632        default:
 633                dev_err(&client->dev,
 634                        "No MT9M001 chip detected, register read %x\n", data);
 635                return -ENODEV;
 636        }
 637
 638        mt9m001->num_fmts = 0;
 639
 640        /*
 641         * This is a 10bit sensor, so by default we only allow 10bit.
 642         * The platform may support different bus widths due to
 643         * different routing of the data lines.
 644         */
 645        if (icl->query_bus_param)
 646                flags = icl->query_bus_param(icl);
 647        else
 648                flags = SOCAM_DATAWIDTH_10;
 649
 650        if (flags & SOCAM_DATAWIDTH_10)
 651                mt9m001->num_fmts++;
 652        else
 653                mt9m001->fmts++;
 654
 655        if (flags & SOCAM_DATAWIDTH_8)
 656                mt9m001->num_fmts++;
 657
 658        mt9m001->fmt = &mt9m001->fmts[0];
 659
 660        dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
 661                 data == 0x8431 ? "C12STM" : "C12ST");
 662
 663        ret = mt9m001_init(client);
 664        if (ret < 0)
 665                dev_err(&client->dev, "Failed to initialise the camera\n");
 666
 667        /* mt9m001_init() has reset the chip, returning registers to defaults */
 668        mt9m001->gain = 64;
 669        mt9m001->exposure = 255;
 670
 671        return ret;
 672}
 673
 674static void mt9m001_video_remove(struct soc_camera_device *icd)
 675{
 676        struct soc_camera_link *icl = to_soc_camera_link(icd);
 677
 678        dev_dbg(&icd->dev, "Video removed: %p, %p\n",
 679                icd->dev.parent, icd->vdev);
 680        if (icl->free_bus)
 681                icl->free_bus(icl);
 682}
 683
 684static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
 685{
 686        struct i2c_client *client = sd->priv;
 687        struct mt9m001 *mt9m001 = to_mt9m001(client);
 688
 689        *lines = mt9m001->y_skip_top;
 690
 691        return 0;
 692}
 693
 694static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
 695        .g_ctrl         = mt9m001_g_ctrl,
 696        .s_ctrl         = mt9m001_s_ctrl,
 697        .g_chip_ident   = mt9m001_g_chip_ident,
 698#ifdef CONFIG_VIDEO_ADV_DEBUG
 699        .g_register     = mt9m001_g_register,
 700        .s_register     = mt9m001_s_register,
 701#endif
 702};
 703
 704static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
 705                            enum v4l2_mbus_pixelcode *code)
 706{
 707        struct i2c_client *client = sd->priv;
 708        struct mt9m001 *mt9m001 = to_mt9m001(client);
 709
 710        if (index >= mt9m001->num_fmts)
 711                return -EINVAL;
 712
 713        *code = mt9m001->fmts[index].code;
 714        return 0;
 715}
 716
 717static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
 718        .s_stream       = mt9m001_s_stream,
 719        .s_mbus_fmt     = mt9m001_s_fmt,
 720        .g_mbus_fmt     = mt9m001_g_fmt,
 721        .try_mbus_fmt   = mt9m001_try_fmt,
 722        .s_crop         = mt9m001_s_crop,
 723        .g_crop         = mt9m001_g_crop,
 724        .cropcap        = mt9m001_cropcap,
 725        .enum_mbus_fmt  = mt9m001_enum_fmt,
 726};
 727
 728static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
 729        .g_skip_top_lines       = mt9m001_g_skip_top_lines,
 730};
 731
 732static struct v4l2_subdev_ops mt9m001_subdev_ops = {
 733        .core   = &mt9m001_subdev_core_ops,
 734        .video  = &mt9m001_subdev_video_ops,
 735        .sensor = &mt9m001_subdev_sensor_ops,
 736};
 737
 738static int mt9m001_probe(struct i2c_client *client,
 739                         const struct i2c_device_id *did)
 740{
 741        struct mt9m001 *mt9m001;
 742        struct soc_camera_device *icd = client->dev.platform_data;
 743        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 744        struct soc_camera_link *icl;
 745        int ret;
 746
 747        if (!icd) {
 748                dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
 749                return -EINVAL;
 750        }
 751
 752        icl = to_soc_camera_link(icd);
 753        if (!icl) {
 754                dev_err(&client->dev, "MT9M001 driver needs platform data\n");
 755                return -EINVAL;
 756        }
 757
 758        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
 759                dev_warn(&adapter->dev,
 760                         "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
 761                return -EIO;
 762        }
 763
 764        mt9m001 = kzalloc(sizeof(struct mt9m001), GFP_KERNEL);
 765        if (!mt9m001)
 766                return -ENOMEM;
 767
 768        v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
 769
 770        /* Second stage probe - when a capture adapter is there */
 771        icd->ops                = &mt9m001_ops;
 772
 773        mt9m001->y_skip_top     = 0;
 774        mt9m001->rect.left      = MT9M001_COLUMN_SKIP;
 775        mt9m001->rect.top       = MT9M001_ROW_SKIP;
 776        mt9m001->rect.width     = MT9M001_MAX_WIDTH;
 777        mt9m001->rect.height    = MT9M001_MAX_HEIGHT;
 778
 779        /*
 780         * Simulated autoexposure. If enabled, we calculate shutter width
 781         * ourselves in the driver based on vertical blanking and frame width
 782         */
 783        mt9m001->autoexposure = 1;
 784
 785        ret = mt9m001_video_probe(icd, client);
 786        if (ret) {
 787                icd->ops = NULL;
 788                kfree(mt9m001);
 789        }
 790
 791        return ret;
 792}
 793
 794static int mt9m001_remove(struct i2c_client *client)
 795{
 796        struct mt9m001 *mt9m001 = to_mt9m001(client);
 797        struct soc_camera_device *icd = client->dev.platform_data;
 798
 799        icd->ops = NULL;
 800        mt9m001_video_remove(icd);
 801        client->driver = NULL;
 802        kfree(mt9m001);
 803
 804        return 0;
 805}
 806
 807static const struct i2c_device_id mt9m001_id[] = {
 808        { "mt9m001", 0 },
 809        { }
 810};
 811MODULE_DEVICE_TABLE(i2c, mt9m001_id);
 812
 813static struct i2c_driver mt9m001_i2c_driver = {
 814        .driver = {
 815                .name = "mt9m001",
 816        },
 817        .probe          = mt9m001_probe,
 818        .remove         = mt9m001_remove,
 819        .id_table       = mt9m001_id,
 820};
 821
 822static int __init mt9m001_mod_init(void)
 823{
 824        return i2c_add_driver(&mt9m001_i2c_driver);
 825}
 826
 827static void __exit mt9m001_mod_exit(void)
 828{
 829        i2c_del_driver(&mt9m001_i2c_driver);
 830}
 831
 832module_init(mt9m001_mod_init);
 833module_exit(mt9m001_mod_exit);
 834
 835MODULE_DESCRIPTION("Micron MT9M001 Camera driver");
 836MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
 837MODULE_LICENSE("GPL");
 838
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.