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