linux/drivers/media/i2c/m5mols/m5mols_core.c
<<
>>
Prefs
   1/*
   2 * Driver for M-5MOLS 8M Pixel camera sensor with ISP
   3 *
   4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
   5 * Author: HeungJun Kim <riverful.kim@samsung.com>
   6 *
   7 * Copyright (C) 2009 Samsung Electronics Co., Ltd.
   8 * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 */
  15
  16#include <linux/i2c.h>
  17#include <linux/slab.h>
  18#include <linux/irq.h>
  19#include <linux/interrupt.h>
  20#include <linux/delay.h>
  21#include <linux/gpio.h>
  22#include <linux/regulator/consumer.h>
  23#include <linux/videodev2.h>
  24#include <linux/module.h>
  25#include <media/v4l2-ctrls.h>
  26#include <media/v4l2-device.h>
  27#include <media/v4l2-subdev.h>
  28#include <media/m5mols.h>
  29
  30#include "m5mols.h"
  31#include "m5mols_reg.h"
  32
  33int m5mols_debug;
  34module_param(m5mols_debug, int, 0644);
  35
  36#define MODULE_NAME             "M5MOLS"
  37#define M5MOLS_I2C_CHECK_RETRY  500
  38
  39/* The regulator consumer names for external voltage regulators */
  40static struct regulator_bulk_data supplies[] = {
  41        {
  42                .supply = "core",       /* ARM core power, 1.2V */
  43        }, {
  44                .supply = "dig_18",     /* digital power 1, 1.8V */
  45        }, {
  46                .supply = "d_sensor",   /* sensor power 1, 1.8V */
  47        }, {
  48                .supply = "dig_28",     /* digital power 2, 2.8V */
  49        }, {
  50                .supply = "a_sensor",   /* analog power */
  51        }, {
  52                .supply = "dig_12",     /* digital power 3, 1.2V */
  53        },
  54};
  55
  56static struct v4l2_mbus_framefmt m5mols_default_ffmt[M5MOLS_RESTYPE_MAX] = {
  57        [M5MOLS_RESTYPE_MONITOR] = {
  58                .width          = 1920,
  59                .height         = 1080,
  60                .code           = V4L2_MBUS_FMT_VYUY8_2X8,
  61                .field          = V4L2_FIELD_NONE,
  62                .colorspace     = V4L2_COLORSPACE_JPEG,
  63        },
  64        [M5MOLS_RESTYPE_CAPTURE] = {
  65                .width          = 1920,
  66                .height         = 1080,
  67                .code           = V4L2_MBUS_FMT_JPEG_1X8,
  68                .field          = V4L2_FIELD_NONE,
  69                .colorspace     = V4L2_COLORSPACE_JPEG,
  70        },
  71};
  72#define SIZE_DEFAULT_FFMT       ARRAY_SIZE(m5mols_default_ffmt)
  73
  74static const struct m5mols_resolution m5mols_reg_res[] = {
  75        { 0x01, M5MOLS_RESTYPE_MONITOR, 128, 96 },      /* SUB-QCIF */
  76        { 0x03, M5MOLS_RESTYPE_MONITOR, 160, 120 },     /* QQVGA */
  77        { 0x05, M5MOLS_RESTYPE_MONITOR, 176, 144 },     /* QCIF */
  78        { 0x06, M5MOLS_RESTYPE_MONITOR, 176, 176 },
  79        { 0x08, M5MOLS_RESTYPE_MONITOR, 240, 320 },     /* QVGA */
  80        { 0x09, M5MOLS_RESTYPE_MONITOR, 320, 240 },     /* QVGA */
  81        { 0x0c, M5MOLS_RESTYPE_MONITOR, 240, 400 },     /* WQVGA */
  82        { 0x0d, M5MOLS_RESTYPE_MONITOR, 400, 240 },     /* WQVGA */
  83        { 0x0e, M5MOLS_RESTYPE_MONITOR, 352, 288 },     /* CIF */
  84        { 0x13, M5MOLS_RESTYPE_MONITOR, 480, 360 },
  85        { 0x15, M5MOLS_RESTYPE_MONITOR, 640, 360 },     /* qHD */
  86        { 0x17, M5MOLS_RESTYPE_MONITOR, 640, 480 },     /* VGA */
  87        { 0x18, M5MOLS_RESTYPE_MONITOR, 720, 480 },
  88        { 0x1a, M5MOLS_RESTYPE_MONITOR, 800, 480 },     /* WVGA */
  89        { 0x1f, M5MOLS_RESTYPE_MONITOR, 800, 600 },     /* SVGA */
  90        { 0x21, M5MOLS_RESTYPE_MONITOR, 1280, 720 },    /* HD */
  91        { 0x25, M5MOLS_RESTYPE_MONITOR, 1920, 1080 },   /* 1080p */
  92        { 0x29, M5MOLS_RESTYPE_MONITOR, 3264, 2448 },   /* 2.63fps 8M */
  93        { 0x39, M5MOLS_RESTYPE_MONITOR, 800, 602 },     /* AHS_MON debug */
  94
  95        { 0x02, M5MOLS_RESTYPE_CAPTURE, 320, 240 },     /* QVGA */
  96        { 0x04, M5MOLS_RESTYPE_CAPTURE, 400, 240 },     /* WQVGA */
  97        { 0x07, M5MOLS_RESTYPE_CAPTURE, 480, 360 },
  98        { 0x08, M5MOLS_RESTYPE_CAPTURE, 640, 360 },     /* qHD */
  99        { 0x09, M5MOLS_RESTYPE_CAPTURE, 640, 480 },     /* VGA */
 100        { 0x0a, M5MOLS_RESTYPE_CAPTURE, 800, 480 },     /* WVGA */
 101        { 0x10, M5MOLS_RESTYPE_CAPTURE, 1280, 720 },    /* HD */
 102        { 0x14, M5MOLS_RESTYPE_CAPTURE, 1280, 960 },    /* 1M */
 103        { 0x17, M5MOLS_RESTYPE_CAPTURE, 1600, 1200 },   /* 2M */
 104        { 0x19, M5MOLS_RESTYPE_CAPTURE, 1920, 1080 },   /* Full-HD */
 105        { 0x1a, M5MOLS_RESTYPE_CAPTURE, 2048, 1152 },   /* 3Mega */
 106        { 0x1b, M5MOLS_RESTYPE_CAPTURE, 2048, 1536 },
 107        { 0x1c, M5MOLS_RESTYPE_CAPTURE, 2560, 1440 },   /* 4Mega */
 108        { 0x1d, M5MOLS_RESTYPE_CAPTURE, 2560, 1536 },
 109        { 0x1f, M5MOLS_RESTYPE_CAPTURE, 2560, 1920 },   /* 5Mega */
 110        { 0x21, M5MOLS_RESTYPE_CAPTURE, 3264, 1836 },   /* 6Mega */
 111        { 0x22, M5MOLS_RESTYPE_CAPTURE, 3264, 1960 },
 112        { 0x25, M5MOLS_RESTYPE_CAPTURE, 3264, 2448 },   /* 8Mega */
 113};
 114
 115/**
 116 * m5mols_swap_byte - an byte array to integer conversion function
 117 * @size: size in bytes of I2C packet defined in the M-5MOLS datasheet
 118 *
 119 * Convert I2C data byte array with performing any required byte
 120 * reordering to assure proper values for each data type, regardless
 121 * of the architecture endianness.
 122 */
 123static u32 m5mols_swap_byte(u8 *data, u8 length)
 124{
 125        if (length == 1)
 126                return *data;
 127        else if (length == 2)
 128                return be16_to_cpu(*((u16 *)data));
 129        else
 130                return be32_to_cpu(*((u32 *)data));
 131}
 132
 133/**
 134 * m5mols_read -  I2C read function
 135 * @reg: combination of size, category and command for the I2C packet
 136 * @size: desired size of I2C packet
 137 * @val: read value
 138 *
 139 * Returns 0 on success, or else negative errno.
 140 */
 141static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
 142{
 143        struct i2c_client *client = v4l2_get_subdevdata(sd);
 144        struct m5mols_info *info = to_m5mols(sd);
 145        u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
 146        u8 category = I2C_CATEGORY(reg);
 147        u8 cmd = I2C_COMMAND(reg);
 148        struct i2c_msg msg[2];
 149        u8 wbuf[5];
 150        int ret;
 151
 152        if (!client->adapter)
 153                return -ENODEV;
 154
 155        msg[0].addr = client->addr;
 156        msg[0].flags = 0;
 157        msg[0].len = 5;
 158        msg[0].buf = wbuf;
 159        wbuf[0] = 5;
 160        wbuf[1] = M5MOLS_BYTE_READ;
 161        wbuf[2] = category;
 162        wbuf[3] = cmd;
 163        wbuf[4] = size;
 164
 165        msg[1].addr = client->addr;
 166        msg[1].flags = I2C_M_RD;
 167        msg[1].len = size + 1;
 168        msg[1].buf = rbuf;
 169
 170        /* minimum stabilization time */
 171        usleep_range(200, 200);
 172
 173        ret = i2c_transfer(client->adapter, msg, 2);
 174
 175        if (ret == 2) {
 176                *val = m5mols_swap_byte(&rbuf[1], size);
 177                return 0;
 178        }
 179
 180        if (info->isp_ready)
 181                v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
 182                         size, category, cmd, ret);
 183
 184        return ret < 0 ? ret : -EIO;
 185}
 186
 187int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
 188{
 189        u32 val_32;
 190        int ret;
 191
 192        if (I2C_SIZE(reg) != 1) {
 193                v4l2_err(sd, "Wrong data size\n");
 194                return -EINVAL;
 195        }
 196
 197        ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
 198        if (ret)
 199                return ret;
 200
 201        *val = (u8)val_32;
 202        return ret;
 203}
 204
 205int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
 206{
 207        u32 val_32;
 208        int ret;
 209
 210        if (I2C_SIZE(reg) != 2) {
 211                v4l2_err(sd, "Wrong data size\n");
 212                return -EINVAL;
 213        }
 214
 215        ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
 216        if (ret)
 217                return ret;
 218
 219        *val = (u16)val_32;
 220        return ret;
 221}
 222
 223int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
 224{
 225        if (I2C_SIZE(reg) != 4) {
 226                v4l2_err(sd, "Wrong data size\n");
 227                return -EINVAL;
 228        }
 229
 230        return m5mols_read(sd, I2C_SIZE(reg), reg, val);
 231}
 232
 233/**
 234 * m5mols_write - I2C command write function
 235 * @reg: combination of size, category and command for the I2C packet
 236 * @val: value to write
 237 *
 238 * Returns 0 on success, or else negative errno.
 239 */
 240int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
 241{
 242        struct i2c_client *client = v4l2_get_subdevdata(sd);
 243        struct m5mols_info *info = to_m5mols(sd);
 244        u8 wbuf[M5MOLS_I2C_MAX_SIZE + 4];
 245        u8 category = I2C_CATEGORY(reg);
 246        u8 cmd = I2C_COMMAND(reg);
 247        u8 size = I2C_SIZE(reg);
 248        u32 *buf = (u32 *)&wbuf[4];
 249        struct i2c_msg msg[1];
 250        int ret;
 251
 252        if (!client->adapter)
 253                return -ENODEV;
 254
 255        if (size != 1 && size != 2 && size != 4) {
 256                v4l2_err(sd, "Wrong data size\n");
 257                return -EINVAL;
 258        }
 259
 260        msg->addr = client->addr;
 261        msg->flags = 0;
 262        msg->len = (u16)size + 4;
 263        msg->buf = wbuf;
 264        wbuf[0] = size + 4;
 265        wbuf[1] = M5MOLS_BYTE_WRITE;
 266        wbuf[2] = category;
 267        wbuf[3] = cmd;
 268
 269        *buf = m5mols_swap_byte((u8 *)&val, size);
 270
 271        usleep_range(200, 200);
 272
 273        ret = i2c_transfer(client->adapter, msg, 1);
 274        if (ret == 1)
 275                return 0;
 276
 277        if (info->isp_ready)
 278                v4l2_err(sd, "write failed: cat:%02x cmd:%02x ret:%d\n",
 279                         category, cmd, ret);
 280
 281        return ret < 0 ? ret : -EIO;
 282}
 283
 284/**
 285 * m5mols_busy_wait - Busy waiting with I2C register polling
 286 * @reg: the I2C_REG() address of an 8-bit status register to check
 287 * @value: expected status register value
 288 * @mask: bit mask for the read status register value
 289 * @timeout: timeout in miliseconds, or -1 for default timeout
 290 *
 291 * The @reg register value is ORed with @mask before comparing with @value.
 292 *
 293 * Return: 0 if the requested condition became true within less than
 294 *         @timeout ms, or else negative errno.
 295 */
 296int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
 297                     int timeout)
 298{
 299        int ms = timeout < 0 ? M5MOLS_BUSY_WAIT_DEF_TIMEOUT : timeout;
 300        unsigned long end = jiffies + msecs_to_jiffies(ms);
 301        u8 status;
 302
 303        do {
 304                int ret = m5mols_read_u8(sd, reg, &status);
 305
 306                if (ret < 0 && !(mask & M5MOLS_I2C_RDY_WAIT_FL))
 307                        return ret;
 308                if (!ret && (status & mask & 0xff) == (value & 0xff))
 309                        return 0;
 310                usleep_range(100, 250);
 311        } while (ms > 0 && time_is_after_jiffies(end));
 312
 313        return -EBUSY;
 314}
 315
 316/**
 317 * m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts
 318 *
 319 * Before writing desired interrupt value the INT_FACTOR register should
 320 * be read to clear pending interrupts.
 321 */
 322int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
 323{
 324        struct m5mols_info *info = to_m5mols(sd);
 325        u8 mask = is_available_af(info) ? REG_INT_AF : 0;
 326        u8 dummy;
 327        int ret;
 328
 329        ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
 330        if (!ret)
 331                ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
 332        return ret;
 333}
 334
 335int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 irq_mask, u32 timeout)
 336{
 337        struct m5mols_info *info = to_m5mols(sd);
 338
 339        int ret = wait_event_interruptible_timeout(info->irq_waitq,
 340                                atomic_add_unless(&info->irq_done, -1, 0),
 341                                msecs_to_jiffies(timeout));
 342        if (ret <= 0)
 343                return ret ? ret : -ETIMEDOUT;
 344
 345        return m5mols_busy_wait(sd, SYSTEM_INT_FACTOR, irq_mask,
 346                                M5MOLS_I2C_RDY_WAIT_FL | irq_mask, -1);
 347}
 348
 349/**
 350 * m5mols_reg_mode - Write the mode and check busy status
 351 *
 352 * It always accompanies a little delay changing the M-5MOLS mode, so it is
 353 * needed checking current busy status to guarantee right mode.
 354 */
 355static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
 356{
 357        int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
 358        if (ret < 0)
 359                return ret;
 360        return m5mols_busy_wait(sd, SYSTEM_SYSMODE, mode, 0xff,
 361                                M5MOLS_MODE_CHANGE_TIMEOUT);
 362}
 363
 364/**
 365 * m5mols_set_mode - set the M-5MOLS controller mode
 366 * @mode: the required operation mode
 367 *
 368 * The commands of M-5MOLS are grouped into specific modes. Each functionality
 369 * can be guaranteed only when the sensor is operating in mode which a command
 370 * belongs to.
 371 */
 372int m5mols_set_mode(struct m5mols_info *info, u8 mode)
 373{
 374        struct v4l2_subdev *sd = &info->sd;
 375        int ret = -EINVAL;
 376        u8 reg;
 377
 378        if (mode < REG_PARAMETER || mode > REG_CAPTURE)
 379                return ret;
 380
 381        ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
 382        if (ret || reg == mode)
 383                return ret;
 384
 385        switch (reg) {
 386        case REG_PARAMETER:
 387                ret = m5mols_reg_mode(sd, REG_MONITOR);
 388                if (mode == REG_MONITOR)
 389                        break;
 390                if (!ret)
 391                        ret = m5mols_reg_mode(sd, REG_CAPTURE);
 392                break;
 393
 394        case REG_MONITOR:
 395                if (mode == REG_PARAMETER) {
 396                        ret = m5mols_reg_mode(sd, REG_PARAMETER);
 397                        break;
 398                }
 399
 400                ret = m5mols_reg_mode(sd, REG_CAPTURE);
 401                break;
 402
 403        case REG_CAPTURE:
 404                ret = m5mols_reg_mode(sd, REG_MONITOR);
 405                if (mode == REG_MONITOR)
 406                        break;
 407                if (!ret)
 408                        ret = m5mols_reg_mode(sd, REG_PARAMETER);
 409                break;
 410
 411        default:
 412                v4l2_warn(sd, "Wrong mode: %d\n", mode);
 413        }
 414
 415        if (!ret)
 416                info->mode = mode;
 417
 418        return ret;
 419}
 420
 421/**
 422 * m5mols_get_version - retrieve full revisions information of M-5MOLS
 423 *
 424 * The version information includes revisions of hardware and firmware,
 425 * AutoFocus alghorithm version and the version string.
 426 */
 427static int m5mols_get_version(struct v4l2_subdev *sd)
 428{
 429        struct m5mols_info *info = to_m5mols(sd);
 430        struct m5mols_version *ver = &info->ver;
 431        u8 *str = ver->str;
 432        int i;
 433        int ret;
 434
 435        ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer);
 436        if (!ret)
 437                ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project);
 438        if (!ret)
 439                ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw);
 440        if (!ret)
 441                ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw);
 442        if (!ret)
 443                ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param);
 444        if (!ret)
 445                ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb);
 446        if (!ret)
 447                ret = m5mols_read_u8(sd, AF_VERSION, &ver->af);
 448        if (ret)
 449                return ret;
 450
 451        for (i = 0; i < VERSION_STRING_SIZE; i++) {
 452                ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]);
 453                if (ret)
 454                        return ret;
 455        }
 456
 457        ver->fw = be16_to_cpu(ver->fw);
 458        ver->hw = be16_to_cpu(ver->hw);
 459        ver->param = be16_to_cpu(ver->param);
 460        ver->awb = be16_to_cpu(ver->awb);
 461
 462        v4l2_info(sd, "Manufacturer\t[%s]\n",
 463                        is_manufacturer(info, REG_SAMSUNG_ELECTRO) ?
 464                        "Samsung Electro-Machanics" :
 465                        is_manufacturer(info, REG_SAMSUNG_OPTICS) ?
 466                        "Samsung Fiber-Optics" :
 467                        is_manufacturer(info, REG_SAMSUNG_TECHWIN) ?
 468                        "Samsung Techwin" : "None");
 469        v4l2_info(sd, "Customer/Project\t[0x%02x/0x%02x]\n",
 470                        info->ver.customer, info->ver.project);
 471
 472        if (!is_available_af(info))
 473                v4l2_info(sd, "No support Auto Focus on this firmware\n");
 474
 475        return ret;
 476}
 477
 478/**
 479 * __find_restype - Lookup M-5MOLS resolution type according to pixel code
 480 * @code: pixel code
 481 */
 482static enum m5mols_restype __find_restype(enum v4l2_mbus_pixelcode code)
 483{
 484        enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR;
 485
 486        do {
 487                if (code == m5mols_default_ffmt[type].code)
 488                        return type;
 489        } while (type++ != SIZE_DEFAULT_FFMT);
 490
 491        return 0;
 492}
 493
 494/**
 495 * __find_resolution - Lookup preset and type of M-5MOLS's resolution
 496 * @mf: pixel format to find/negotiate the resolution preset for
 497 * @type: M-5MOLS resolution type
 498 * @resolution: M-5MOLS resolution preset register value
 499 *
 500 * Find nearest resolution matching resolution preset and adjust mf
 501 * to supported values.
 502 */
 503static int __find_resolution(struct v4l2_subdev *sd,
 504                             struct v4l2_mbus_framefmt *mf,
 505                             enum m5mols_restype *type,
 506                             u32 *resolution)
 507{
 508        const struct m5mols_resolution *fsize = &m5mols_reg_res[0];
 509        const struct m5mols_resolution *match = NULL;
 510        enum m5mols_restype stype = __find_restype(mf->code);
 511        int i = ARRAY_SIZE(m5mols_reg_res);
 512        unsigned int min_err = ~0;
 513
 514        while (i--) {
 515                int err;
 516                if (stype == fsize->type) {
 517                        err = abs(fsize->width - mf->width)
 518                                + abs(fsize->height - mf->height);
 519
 520                        if (err < min_err) {
 521                                min_err = err;
 522                                match = fsize;
 523                        }
 524                }
 525                fsize++;
 526        }
 527        if (match) {
 528                mf->width  = match->width;
 529                mf->height = match->height;
 530                *resolution = match->reg;
 531                *type = stype;
 532                return 0;
 533        }
 534
 535        return -EINVAL;
 536}
 537
 538static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info,
 539                                struct v4l2_subdev_fh *fh,
 540                                enum v4l2_subdev_format_whence which,
 541                                enum m5mols_restype type)
 542{
 543        if (which == V4L2_SUBDEV_FORMAT_TRY)
 544                return fh ? v4l2_subdev_get_try_format(fh, 0) : NULL;
 545
 546        return &info->ffmt[type];
 547}
 548
 549static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 550                          struct v4l2_subdev_format *fmt)
 551{
 552        struct m5mols_info *info = to_m5mols(sd);
 553        struct v4l2_mbus_framefmt *format;
 554        int ret = 0;
 555
 556        mutex_lock(&info->lock);
 557
 558        format = __find_format(info, fh, fmt->which, info->res_type);
 559        if (format)
 560                fmt->format = *format;
 561        else
 562                ret = -EINVAL;
 563
 564        mutex_unlock(&info->lock);
 565        return ret;
 566}
 567
 568static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 569                          struct v4l2_subdev_format *fmt)
 570{
 571        struct m5mols_info *info = to_m5mols(sd);
 572        struct v4l2_mbus_framefmt *format = &fmt->format;
 573        struct v4l2_mbus_framefmt *sfmt;
 574        enum m5mols_restype type;
 575        u32 resolution = 0;
 576        int ret;
 577
 578        ret = __find_resolution(sd, format, &type, &resolution);
 579        if (ret < 0)
 580                return ret;
 581
 582        sfmt = __find_format(info, fh, fmt->which, type);
 583        if (!sfmt)
 584                return 0;
 585
 586        mutex_lock(&info->lock);
 587
 588        format->code = m5mols_default_ffmt[type].code;
 589        format->colorspace = V4L2_COLORSPACE_JPEG;
 590        format->field = V4L2_FIELD_NONE;
 591
 592        if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
 593                *sfmt = *format;
 594                info->resolution = resolution;
 595                info->res_type = type;
 596        }
 597
 598        mutex_unlock(&info->lock);
 599        return ret;
 600}
 601
 602static int m5mols_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 603                                 struct v4l2_mbus_frame_desc *fd)
 604{
 605        struct m5mols_info *info = to_m5mols(sd);
 606
 607        if (pad != 0 || fd == NULL)
 608                return -EINVAL;
 609
 610        mutex_lock(&info->lock);
 611        /*
 612         * .get_frame_desc is only used for compressed formats,
 613         * thus we always return the capture frame parameters here.
 614         */
 615        fd->entry[0].length = info->cap.buf_size;
 616        fd->entry[0].pixelcode = info->ffmt[M5MOLS_RESTYPE_CAPTURE].code;
 617        mutex_unlock(&info->lock);
 618
 619        fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
 620        fd->num_entries = 1;
 621
 622        return 0;
 623}
 624
 625static int m5mols_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 626                                 struct v4l2_mbus_frame_desc *fd)
 627{
 628        struct m5mols_info *info = to_m5mols(sd);
 629        struct v4l2_mbus_framefmt *mf = &info->ffmt[M5MOLS_RESTYPE_CAPTURE];
 630
 631        if (pad != 0 || fd == NULL)
 632                return -EINVAL;
 633
 634        fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
 635        fd->num_entries = 1;
 636        fd->entry[0].length = clamp_t(u32, fd->entry[0].length,
 637                                      mf->width * mf->height,
 638                                      M5MOLS_MAIN_JPEG_SIZE_MAX);
 639        mutex_lock(&info->lock);
 640        info->cap.buf_size = fd->entry[0].length;
 641        mutex_unlock(&info->lock);
 642
 643        return 0;
 644}
 645
 646
 647static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
 648                                 struct v4l2_subdev_fh *fh,
 649                                 struct v4l2_subdev_mbus_code_enum *code)
 650{
 651        if (!code || code->index >= SIZE_DEFAULT_FFMT)
 652                return -EINVAL;
 653
 654        code->code = m5mols_default_ffmt[code->index].code;
 655
 656        return 0;
 657}
 658
 659static struct v4l2_subdev_pad_ops m5mols_pad_ops = {
 660        .enum_mbus_code = m5mols_enum_mbus_code,
 661        .get_fmt        = m5mols_get_fmt,
 662        .set_fmt        = m5mols_set_fmt,
 663        .get_frame_desc = m5mols_get_frame_desc,
 664        .set_frame_desc = m5mols_set_frame_desc,
 665};
 666
 667/**
 668 * m5mols_restore_controls - Apply current control values to the registers
 669 *
 670 * m5mols_do_scenemode() handles all parameters for which there is yet no
 671 * individual control. It should be replaced at some point by setting each
 672 * control individually, in required register set up order.
 673 */
 674int m5mols_restore_controls(struct m5mols_info *info)
 675{
 676        int ret;
 677
 678        if (info->ctrl_sync)
 679                return 0;
 680
 681        ret = m5mols_do_scenemode(info, REG_SCENE_NORMAL);
 682        if (ret)
 683                return ret;
 684
 685        ret = v4l2_ctrl_handler_setup(&info->handle);
 686        info->ctrl_sync = !ret;
 687
 688        return ret;
 689}
 690
 691/**
 692 * m5mols_start_monitor - Start the monitor mode
 693 *
 694 * Before applying the controls setup the resolution and frame rate
 695 * in PARAMETER mode, and then switch over to MONITOR mode.
 696 */
 697static int m5mols_start_monitor(struct m5mols_info *info)
 698{
 699        struct v4l2_subdev *sd = &info->sd;
 700        int ret;
 701
 702        ret = m5mols_set_mode(info, REG_PARAMETER);
 703        if (!ret)
 704                ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
 705        if (!ret)
 706                ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
 707        if (!ret)
 708                ret = m5mols_set_mode(info, REG_MONITOR);
 709        if (!ret)
 710                ret = m5mols_restore_controls(info);
 711
 712        return ret;
 713}
 714
 715static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
 716{
 717        struct m5mols_info *info = to_m5mols(sd);
 718        u32 code;
 719        int ret;
 720
 721        mutex_lock(&info->lock);
 722        code = info->ffmt[info->res_type].code;
 723
 724        if (enable) {
 725                if (is_code(code, M5MOLS_RESTYPE_MONITOR))
 726                        ret = m5mols_start_monitor(info);
 727                else if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
 728                        ret = m5mols_start_capture(info);
 729                else
 730                        ret = -EINVAL;
 731        } else {
 732                ret = m5mols_set_mode(info, REG_PARAMETER);
 733        }
 734
 735        mutex_unlock(&info->lock);
 736        return ret;
 737}
 738
 739static const struct v4l2_subdev_video_ops m5mols_video_ops = {
 740        .s_stream       = m5mols_s_stream,
 741};
 742
 743static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
 744{
 745        struct v4l2_subdev *sd = &info->sd;
 746        struct i2c_client *client = v4l2_get_subdevdata(sd);
 747        const struct m5mols_platform_data *pdata = info->pdata;
 748        int ret;
 749
 750        if (info->power == enable)
 751                return 0;
 752
 753        if (enable) {
 754                if (info->set_power) {
 755                        ret = info->set_power(&client->dev, 1);
 756                        if (ret)
 757                                return ret;
 758                }
 759
 760                ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
 761                if (ret) {
 762                        info->set_power(&client->dev, 0);
 763                        return ret;
 764                }
 765
 766                gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
 767                info->power = 1;
 768
 769                return ret;
 770        }
 771
 772        ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
 773        if (ret)
 774                return ret;
 775
 776        if (info->set_power)
 777                info->set_power(&client->dev, 0);
 778
 779        gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
 780
 781        info->isp_ready = 0;
 782        info->power = 0;
 783
 784        return ret;
 785}
 786
 787/* m5mols_update_fw - optional firmware update routine */
 788int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
 789                int (*set_power)(struct m5mols_info *, bool))
 790{
 791        return 0;
 792}
 793
 794/**
 795 * m5mols_fw_start - M-5MOLS internal ARM controller initialization
 796 *
 797 * Execute the M-5MOLS internal ARM controller initialization sequence.
 798 * This function should be called after the supply voltage has been
 799 * applied and before any requests to the device are made.
 800 */
 801static int m5mols_fw_start(struct v4l2_subdev *sd)
 802{
 803        struct m5mols_info *info = to_m5mols(sd);
 804        int ret;
 805
 806        atomic_set(&info->irq_done, 0);
 807        /* Wait until I2C slave is initialized in Flash Writer mode */
 808        ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE,
 809                               M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1);
 810        if (!ret)
 811                ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
 812        if (!ret)
 813                ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000);
 814        if (ret < 0)
 815                return ret;
 816
 817        info->isp_ready = 1;
 818
 819        ret = m5mols_get_version(sd);
 820        if (!ret)
 821                ret = m5mols_update_fw(sd, m5mols_sensor_power);
 822        if (ret)
 823                return ret;
 824
 825        v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n");
 826
 827        ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI);
 828        if (!ret)
 829                ret = m5mols_enable_interrupt(sd,
 830                                REG_INT_AF | REG_INT_CAPTURE);
 831
 832        return ret;
 833}
 834
 835/* Execute the lens soft-landing algorithm */
 836static int m5mols_auto_focus_stop(struct m5mols_info *info)
 837{
 838        int ret;
 839
 840        ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
 841        if (!ret)
 842                ret = m5mols_write(&info->sd, AF_MODE, REG_AF_POWEROFF);
 843        if (!ret)
 844                ret = m5mols_busy_wait(&info->sd, SYSTEM_STATUS, REG_AF_IDLE,
 845                                       0xff, -1);
 846        return ret;
 847}
 848
 849/**
 850 * m5mols_s_power - Main sensor power control function
 851 *
 852 * To prevent breaking the lens when the sensor is powered off the Soft-Landing
 853 * algorithm is called where available. The Soft-Landing algorithm availability
 854 * dependends on the firmware provider.
 855 */
 856static int m5mols_s_power(struct v4l2_subdev *sd, int on)
 857{
 858        struct m5mols_info *info = to_m5mols(sd);
 859        int ret;
 860
 861        mutex_lock(&info->lock);
 862
 863        if (on) {
 864                ret = m5mols_sensor_power(info, true);
 865                if (!ret)
 866                        ret = m5mols_fw_start(sd);
 867        } else {
 868                if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
 869                        ret = m5mols_set_mode(info, REG_MONITOR);
 870                        if (!ret)
 871                                ret = m5mols_auto_focus_stop(info);
 872                        if (ret < 0)
 873                                v4l2_warn(sd, "Soft landing lens failed\n");
 874                }
 875                ret = m5mols_sensor_power(info, false);
 876
 877                info->ctrl_sync = 0;
 878        }
 879
 880        mutex_unlock(&info->lock);
 881        return ret;
 882}
 883
 884static int m5mols_log_status(struct v4l2_subdev *sd)
 885{
 886        struct m5mols_info *info = to_m5mols(sd);
 887
 888        v4l2_ctrl_handler_log_status(&info->handle, sd->name);
 889
 890        return 0;
 891}
 892
 893static const struct v4l2_subdev_core_ops m5mols_core_ops = {
 894        .s_power        = m5mols_s_power,
 895        .log_status     = m5mols_log_status,
 896};
 897
 898/*
 899 * V4L2 subdev internal operations
 900 */
 901static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 902{
 903        struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
 904
 905        *format = m5mols_default_ffmt[0];
 906        return 0;
 907}
 908
 909static const struct v4l2_subdev_internal_ops m5mols_subdev_internal_ops = {
 910        .open           = m5mols_open,
 911};
 912
 913static const struct v4l2_subdev_ops m5mols_ops = {
 914        .core           = &m5mols_core_ops,
 915        .pad            = &m5mols_pad_ops,
 916        .video          = &m5mols_video_ops,
 917};
 918
 919static irqreturn_t m5mols_irq_handler(int irq, void *data)
 920{
 921        struct m5mols_info *info = to_m5mols(data);
 922
 923        atomic_set(&info->irq_done, 1);
 924        wake_up_interruptible(&info->irq_waitq);
 925
 926        return IRQ_HANDLED;
 927}
 928
 929static int m5mols_probe(struct i2c_client *client,
 930                        const struct i2c_device_id *id)
 931{
 932        const struct m5mols_platform_data *pdata = client->dev.platform_data;
 933        unsigned long gpio_flags;
 934        struct m5mols_info *info;
 935        struct v4l2_subdev *sd;
 936        int ret;
 937
 938        if (pdata == NULL) {
 939                dev_err(&client->dev, "No platform data\n");
 940                return -EINVAL;
 941        }
 942
 943        if (!gpio_is_valid(pdata->gpio_reset)) {
 944                dev_err(&client->dev, "No valid RESET GPIO specified\n");
 945                return -EINVAL;
 946        }
 947
 948        if (!client->irq) {
 949                dev_err(&client->dev, "Interrupt not assigned\n");
 950                return -EINVAL;
 951        }
 952
 953        info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 954        if (!info)
 955                return -ENOMEM;
 956
 957        info->pdata = pdata;
 958        info->set_power = pdata->set_power;
 959
 960        gpio_flags = pdata->reset_polarity
 961                   ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
 962        ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
 963                                    "M5MOLS_NRST");
 964        if (ret) {
 965                dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
 966                return ret;
 967        }
 968
 969        ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
 970                                      supplies);
 971        if (ret) {
 972                dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
 973                return ret;
 974        }
 975
 976        sd = &info->sd;
 977        v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
 978        strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
 979        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 980
 981        sd->internal_ops = &m5mols_subdev_internal_ops;
 982        info->pad.flags = MEDIA_PAD_FL_SOURCE;
 983        ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
 984        if (ret < 0)
 985                return ret;
 986        sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 987
 988        init_waitqueue_head(&info->irq_waitq);
 989        mutex_init(&info->lock);
 990
 991        ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
 992                               IRQF_TRIGGER_RISING, MODULE_NAME, sd);
 993        if (ret) {
 994                dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
 995                goto error;
 996        }
 997        info->res_type = M5MOLS_RESTYPE_MONITOR;
 998        info->ffmt[0] = m5mols_default_ffmt[0];
 999        info->ffmt[1] = m5mols_default_ffmt[1];
1000
1001        ret = m5mols_sensor_power(info, true);
1002        if (ret)
1003                goto error;
1004
1005        ret = m5mols_fw_start(sd);
1006        if (!ret)
1007                ret = m5mols_init_controls(sd);
1008
1009        ret = m5mols_sensor_power(info, false);
1010        if (!ret)
1011                return 0;
1012error:
1013        media_entity_cleanup(&sd->entity);
1014        return ret;
1015}
1016
1017static int m5mols_remove(struct i2c_client *client)
1018{
1019        struct v4l2_subdev *sd = i2c_get_clientdata(client);
1020
1021        v4l2_device_unregister_subdev(sd);
1022        v4l2_ctrl_handler_free(sd->ctrl_handler);
1023        media_entity_cleanup(&sd->entity);
1024
1025        return 0;
1026}
1027
1028static const struct i2c_device_id m5mols_id[] = {
1029        { MODULE_NAME, 0 },
1030        { },
1031};
1032MODULE_DEVICE_TABLE(i2c, m5mols_id);
1033
1034static struct i2c_driver m5mols_i2c_driver = {
1035        .driver = {
1036                .name   = MODULE_NAME,
1037        },
1038        .probe          = m5mols_probe,
1039        .remove         = m5mols_remove,
1040        .id_table       = m5mols_id,
1041};
1042
1043module_i2c_driver(m5mols_i2c_driver);
1044
1045MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
1046MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
1047MODULE_DESCRIPTION("Fujitsu M-5MOLS 8M Pixel camera driver");
1048MODULE_LICENSE("GPL");
1049