m5mols_core.c (27185B)
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/consumer.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, ®); 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 int ret; 756 757 if (info->power == enable) 758 return 0; 759 760 if (enable) { 761 if (info->set_power) { 762 ret = info->set_power(&client->dev, 1); 763 if (ret) 764 return ret; 765 } 766 767 ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies); 768 if (ret) { 769 if (info->set_power) 770 info->set_power(&client->dev, 0); 771 return ret; 772 } 773 774 gpiod_set_value(info->reset, 0); 775 info->power = 1; 776 777 return ret; 778 } 779 780 ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies); 781 if (ret) 782 return ret; 783 784 if (info->set_power) 785 info->set_power(&client->dev, 0); 786 787 gpiod_set_value(info->reset, 1); 788 789 info->isp_ready = 0; 790 info->power = 0; 791 792 return ret; 793} 794 795/* m5mols_update_fw - optional firmware update routine */ 796int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd, 797 int (*set_power)(struct m5mols_info *, bool)) 798{ 799 return 0; 800} 801 802/** 803 * m5mols_fw_start - M-5MOLS internal ARM controller initialization 804 * @sd: sub-device, as pointed by struct v4l2_subdev 805 * 806 * Execute the M-5MOLS internal ARM controller initialization sequence. 807 * This function should be called after the supply voltage has been 808 * applied and before any requests to the device are made. 809 */ 810static int m5mols_fw_start(struct v4l2_subdev *sd) 811{ 812 struct m5mols_info *info = to_m5mols(sd); 813 int ret; 814 815 atomic_set(&info->irq_done, 0); 816 /* Wait until I2C slave is initialized in Flash Writer mode */ 817 ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE, 818 M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1); 819 if (!ret) 820 ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT); 821 if (!ret) 822 ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000); 823 if (ret < 0) 824 return ret; 825 826 info->isp_ready = 1; 827 828 ret = m5mols_get_version(sd); 829 if (!ret) 830 ret = m5mols_update_fw(sd, m5mols_sensor_power); 831 if (ret) 832 return ret; 833 834 v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n"); 835 836 ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI); 837 if (!ret) 838 ret = m5mols_enable_interrupt(sd, 839 REG_INT_AF | REG_INT_CAPTURE); 840 841 return ret; 842} 843 844/* Execute the lens soft-landing algorithm */ 845static int m5mols_auto_focus_stop(struct m5mols_info *info) 846{ 847 int ret; 848 849 ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP); 850 if (!ret) 851 ret = m5mols_write(&info->sd, AF_MODE, REG_AF_POWEROFF); 852 if (!ret) 853 ret = m5mols_busy_wait(&info->sd, SYSTEM_STATUS, REG_AF_IDLE, 854 0xff, -1); 855 return ret; 856} 857 858/** 859 * m5mols_s_power - Main sensor power control function 860 * @sd: sub-device, as pointed by struct v4l2_subdev 861 * @on: if true, powers on the device; powers off otherwise. 862 * 863 * To prevent breaking the lens when the sensor is powered off the Soft-Landing 864 * algorithm is called where available. The Soft-Landing algorithm availability 865 * dependends on the firmware provider. 866 */ 867static int m5mols_s_power(struct v4l2_subdev *sd, int on) 868{ 869 struct m5mols_info *info = to_m5mols(sd); 870 int ret; 871 872 mutex_lock(&info->lock); 873 874 if (on) { 875 ret = m5mols_sensor_power(info, true); 876 if (!ret) 877 ret = m5mols_fw_start(sd); 878 } else { 879 if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) { 880 ret = m5mols_set_mode(info, REG_MONITOR); 881 if (!ret) 882 ret = m5mols_auto_focus_stop(info); 883 if (ret < 0) 884 v4l2_warn(sd, "Soft landing lens failed\n"); 885 } 886 ret = m5mols_sensor_power(info, false); 887 888 info->ctrl_sync = 0; 889 } 890 891 mutex_unlock(&info->lock); 892 return ret; 893} 894 895static int m5mols_log_status(struct v4l2_subdev *sd) 896{ 897 struct m5mols_info *info = to_m5mols(sd); 898 899 v4l2_ctrl_handler_log_status(&info->handle, sd->name); 900 901 return 0; 902} 903 904static const struct v4l2_subdev_core_ops m5mols_core_ops = { 905 .s_power = m5mols_s_power, 906 .log_status = m5mols_log_status, 907}; 908 909/* 910 * V4L2 subdev internal operations 911 */ 912static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 913{ 914 struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, 915 fh->state, 916 0); 917 918 *format = m5mols_default_ffmt[0]; 919 return 0; 920} 921 922static const struct v4l2_subdev_internal_ops m5mols_subdev_internal_ops = { 923 .open = m5mols_open, 924}; 925 926static const struct v4l2_subdev_ops m5mols_ops = { 927 .core = &m5mols_core_ops, 928 .pad = &m5mols_pad_ops, 929 .video = &m5mols_video_ops, 930}; 931 932static irqreturn_t m5mols_irq_handler(int irq, void *data) 933{ 934 struct m5mols_info *info = to_m5mols(data); 935 936 atomic_set(&info->irq_done, 1); 937 wake_up_interruptible(&info->irq_waitq); 938 939 return IRQ_HANDLED; 940} 941 942static int m5mols_probe(struct i2c_client *client, 943 const struct i2c_device_id *id) 944{ 945 const struct m5mols_platform_data *pdata = client->dev.platform_data; 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 (!client->irq) { 956 dev_err(&client->dev, "Interrupt not assigned\n"); 957 return -EINVAL; 958 } 959 960 info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); 961 if (!info) 962 return -ENOMEM; 963 964 /* This asserts reset, descriptor shall have polarity specified */ 965 info->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); 966 if (IS_ERR(info->reset)) 967 return PTR_ERR(info->reset); 968 /* Notice: the "N" in M5MOLS_NRST implies active low */ 969 gpiod_set_consumer_name(info->reset, "M5MOLS_NRST"); 970 971 info->pdata = pdata; 972 info->set_power = pdata->set_power; 973 974 ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), 975 supplies); 976 if (ret) { 977 dev_err(&client->dev, "Failed to get regulators: %d\n", ret); 978 return ret; 979 } 980 981 sd = &info->sd; 982 v4l2_i2c_subdev_init(sd, client, &m5mols_ops); 983 /* Static name; NEVER use in new drivers! */ 984 strscpy(sd->name, MODULE_NAME, sizeof(sd->name)); 985 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 986 987 sd->internal_ops = &m5mols_subdev_internal_ops; 988 info->pad.flags = MEDIA_PAD_FL_SOURCE; 989 ret = media_entity_pads_init(&sd->entity, 1, &info->pad); 990 if (ret < 0) 991 return ret; 992 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; 993 994 init_waitqueue_head(&info->irq_waitq); 995 mutex_init(&info->lock); 996 997 ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler, 998 IRQF_TRIGGER_RISING, MODULE_NAME, sd); 999 if (ret) { 1000 dev_err(&client->dev, "Interrupt request failed: %d\n", ret); 1001 goto error; 1002 } 1003 info->res_type = M5MOLS_RESTYPE_MONITOR; 1004 info->ffmt[0] = m5mols_default_ffmt[0]; 1005 info->ffmt[1] = m5mols_default_ffmt[1]; 1006 1007 ret = m5mols_sensor_power(info, true); 1008 if (ret) 1009 goto error; 1010 1011 ret = m5mols_fw_start(sd); 1012 if (!ret) 1013 ret = m5mols_init_controls(sd); 1014 1015 ret = m5mols_sensor_power(info, false); 1016 if (!ret) 1017 return 0; 1018error: 1019 media_entity_cleanup(&sd->entity); 1020 return ret; 1021} 1022 1023static int m5mols_remove(struct i2c_client *client) 1024{ 1025 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1026 1027 v4l2_device_unregister_subdev(sd); 1028 v4l2_ctrl_handler_free(sd->ctrl_handler); 1029 media_entity_cleanup(&sd->entity); 1030 1031 return 0; 1032} 1033 1034static const struct i2c_device_id m5mols_id[] = { 1035 { MODULE_NAME, 0 }, 1036 { }, 1037}; 1038MODULE_DEVICE_TABLE(i2c, m5mols_id); 1039 1040static struct i2c_driver m5mols_i2c_driver = { 1041 .driver = { 1042 .name = MODULE_NAME, 1043 }, 1044 .probe = m5mols_probe, 1045 .remove = m5mols_remove, 1046 .id_table = m5mols_id, 1047}; 1048 1049module_i2c_driver(m5mols_i2c_driver); 1050 1051MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>"); 1052MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>"); 1053MODULE_DESCRIPTION("Fujitsu M-5MOLS 8M Pixel camera driver"); 1054MODULE_LICENSE("GPL");