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