1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for GalaxyCore GC0310 VGA camera sensor. 4 * 5 * Copyright (c) 2013 Intel Corporation. All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License version 9 * 2 as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 */ 17 18 #include <linux/module.h> 19 #include <linux/types.h> 20 #include <linux/kernel.h> 21 #include <linux/mm.h> 22 #include <linux/string.h> 23 #include <linux/errno.h> 24 #include <linux/init.h> 25 #include <linux/kmod.h> 26 #include <linux/device.h> 27 #include <linux/delay.h> 28 #include <linux/slab.h> 29 #include <linux/i2c.h> 30 #include <linux/moduleparam.h> 31 #include <media/v4l2-device.h> 32 #include <linux/io.h> 33 #include "../include/linux/atomisp_gmin_platform.h" 34 35 #include "gc0310.h" 36 37 /* 38 * gc0310_write_reg_array - Initializes a list of GC0310 registers 39 * @client: i2c driver client structure 40 * @reglist: list of registers to be written 41 * @count: number of register, value pairs in the list 42 */ 43 static int gc0310_write_reg_array(struct i2c_client *client, 44 const struct gc0310_reg *reglist, int count) 45 { 46 int i, err; 47 48 for (i = 0; i < count; i++) { 49 err = i2c_smbus_write_byte_data(client, reglist[i].reg, reglist[i].val); 50 if (err) { 51 dev_err(&client->dev, "write error: wrote 0x%x to offset 0x%x error %d", 52 reglist[i].val, reglist[i].reg, err); 53 return err; 54 } 55 } 56 57 return 0; 58 } 59 60 static int gc0310_exposure_set(struct gc0310_device *dev, u32 exp) 61 { 62 struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); 63 64 return i2c_smbus_write_word_swapped(client, GC0310_AEC_PK_EXPO_H, exp); 65 } 66 67 static int gc0310_gain_set(struct gc0310_device *dev, u32 gain) 68 { 69 struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); 70 u8 again, dgain; 71 int ret; 72 73 /* Taken from original driver, this never sets dgain lower then 32? */ 74 75 /* Change 0 - 95 to 32 - 127 */ 76 gain += 32; 77 78 if (gain < 64) { 79 again = 0x0; /* sqrt(2) */ 80 dgain = gain; 81 } else { 82 again = 0x2; /* 2 * sqrt(2) */ 83 dgain = gain / 2; 84 } 85 86 ret = i2c_smbus_write_byte_data(client, GC0310_AGC_ADJ, again); 87 if (ret) 88 return ret; 89 90 return i2c_smbus_write_byte_data(client, GC0310_DGC_ADJ, dgain); 91 } 92 93 static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl) 94 { 95 struct gc0310_device *dev = 96 container_of(ctrl->handler, struct gc0310_device, ctrls.handler); 97 int ret; 98 99 if (!dev->power_on) 100 return 0; 101 102 switch (ctrl->id) { 103 case V4L2_CID_EXPOSURE: 104 ret = gc0310_exposure_set(dev, ctrl->val); 105 break; 106 case V4L2_CID_GAIN: 107 ret = gc0310_gain_set(dev, ctrl->val); 108 break; 109 default: 110 ret = -EINVAL; 111 break; 112 } 113 114 return ret; 115 } 116 117 static const struct v4l2_ctrl_ops ctrl_ops = { 118 .s_ctrl = gc0310_s_ctrl, 119 }; 120 121 static int power_ctrl(struct v4l2_subdev *sd, bool flag) 122 { 123 int ret = 0; 124 struct gc0310_device *dev = to_gc0310_sensor(sd); 125 126 if (!dev || !dev->platform_data) 127 return -ENODEV; 128 129 if (flag) { 130 /* The upstream module driver (written to Crystal 131 * Cove) had this logic to pulse the rails low first. 132 * This appears to break things on the MRD7 with the 133 * X-Powers PMIC... 134 * 135 * ret = dev->platform_data->v1p8_ctrl(sd, 0); 136 * ret |= dev->platform_data->v2p8_ctrl(sd, 0); 137 * mdelay(50); 138 */ 139 ret |= dev->platform_data->v1p8_ctrl(sd, 1); 140 ret |= dev->platform_data->v2p8_ctrl(sd, 1); 141 usleep_range(10000, 15000); 142 } 143 144 if (!flag || ret) { 145 ret |= dev->platform_data->v1p8_ctrl(sd, 0); 146 ret |= dev->platform_data->v2p8_ctrl(sd, 0); 147 } 148 return ret; 149 } 150 151 static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) 152 { 153 int ret; 154 struct gc0310_device *dev = to_gc0310_sensor(sd); 155 156 if (!dev || !dev->platform_data) 157 return -ENODEV; 158 159 /* GPIO0 == "reset" (active low), GPIO1 == "power down" */ 160 if (flag) { 161 /* Pulse reset, then release power down */ 162 ret = dev->platform_data->gpio0_ctrl(sd, 0); 163 usleep_range(5000, 10000); 164 ret |= dev->platform_data->gpio0_ctrl(sd, 1); 165 usleep_range(10000, 15000); 166 ret |= dev->platform_data->gpio1_ctrl(sd, 0); 167 usleep_range(10000, 15000); 168 } else { 169 ret = dev->platform_data->gpio1_ctrl(sd, 1); 170 ret |= dev->platform_data->gpio0_ctrl(sd, 0); 171 } 172 return ret; 173 } 174 175 static int power_up(struct v4l2_subdev *sd) 176 { 177 struct gc0310_device *dev = to_gc0310_sensor(sd); 178 struct i2c_client *client = v4l2_get_subdevdata(sd); 179 int ret; 180 181 if (!dev->platform_data) { 182 dev_err(&client->dev, 183 "no camera_sensor_platform_data"); 184 return -ENODEV; 185 } 186 187 if (dev->power_on) 188 return 0; /* Already on */ 189 190 /* power control */ 191 ret = power_ctrl(sd, 1); 192 if (ret) 193 goto fail_power; 194 195 /* flis clock control */ 196 ret = dev->platform_data->flisclk_ctrl(sd, 1); 197 if (ret) 198 goto fail_clk; 199 200 /* gpio ctrl */ 201 ret = gpio_ctrl(sd, 1); 202 if (ret) { 203 ret = gpio_ctrl(sd, 1); 204 if (ret) 205 goto fail_gpio; 206 } 207 208 msleep(100); 209 210 dev->power_on = true; 211 return 0; 212 213 fail_gpio: 214 dev->platform_data->flisclk_ctrl(sd, 0); 215 fail_clk: 216 power_ctrl(sd, 0); 217 fail_power: 218 dev_err(&client->dev, "sensor power-up failed\n"); 219 220 return ret; 221 } 222 223 static int power_down(struct v4l2_subdev *sd) 224 { 225 struct gc0310_device *dev = to_gc0310_sensor(sd); 226 struct i2c_client *client = v4l2_get_subdevdata(sd); 227 int ret = 0; 228 229 if (!dev->platform_data) { 230 dev_err(&client->dev, 231 "no camera_sensor_platform_data"); 232 return -ENODEV; 233 } 234 235 if (!dev->power_on) 236 return 0; /* Already off */ 237 238 /* gpio ctrl */ 239 ret = gpio_ctrl(sd, 0); 240 if (ret) { 241 ret = gpio_ctrl(sd, 0); 242 if (ret) 243 dev_err(&client->dev, "gpio failed 2\n"); 244 } 245 246 ret = dev->platform_data->flisclk_ctrl(sd, 0); 247 if (ret) 248 dev_err(&client->dev, "flisclk failed\n"); 249 250 /* power control */ 251 ret = power_ctrl(sd, 0); 252 if (ret) 253 dev_err(&client->dev, "vprog failed.\n"); 254 255 dev->power_on = false; 256 return ret; 257 } 258 259 static struct v4l2_mbus_framefmt * 260 gc0310_get_pad_format(struct gc0310_device *dev, 261 struct v4l2_subdev_state *state, 262 unsigned int pad, enum v4l2_subdev_format_whence which) 263 { 264 if (which == V4L2_SUBDEV_FORMAT_TRY) 265 return v4l2_subdev_get_try_format(&dev->sd, state, pad); 266 267 return &dev->mode.fmt; 268 } 269 270 /* The GC0310 currently only supports 1 fixed fmt */ 271 static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt) 272 { 273 memset(fmt, 0, sizeof(*fmt)); 274 fmt->width = GC0310_NATIVE_WIDTH; 275 fmt->height = GC0310_NATIVE_HEIGHT; 276 fmt->field = V4L2_FIELD_NONE; 277 fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; 278 } 279 280 static int gc0310_set_fmt(struct v4l2_subdev *sd, 281 struct v4l2_subdev_state *sd_state, 282 struct v4l2_subdev_format *format) 283 { 284 struct gc0310_device *dev = to_gc0310_sensor(sd); 285 struct v4l2_mbus_framefmt *fmt; 286 287 fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which); 288 gc0310_fill_format(fmt); 289 290 format->format = *fmt; 291 return 0; 292 } 293 294 static int gc0310_get_fmt(struct v4l2_subdev *sd, 295 struct v4l2_subdev_state *sd_state, 296 struct v4l2_subdev_format *format) 297 { 298 struct gc0310_device *dev = to_gc0310_sensor(sd); 299 struct v4l2_mbus_framefmt *fmt; 300 301 fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which); 302 format->format = *fmt; 303 return 0; 304 } 305 306 static int gc0310_detect(struct i2c_client *client) 307 { 308 struct i2c_adapter *adapter = client->adapter; 309 int ret; 310 311 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) 312 return -ENODEV; 313 314 ret = i2c_smbus_read_word_swapped(client, GC0310_SC_CMMN_CHIP_ID_H); 315 if (ret < 0) { 316 dev_err(&client->dev, "read sensor_id failed: %d\n", ret); 317 return -ENODEV; 318 } 319 320 dev_dbg(&client->dev, "sensor ID = 0x%x\n", ret); 321 322 if (ret != GC0310_ID) { 323 dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n", 324 ret, GC0310_ID); 325 return -ENODEV; 326 } 327 328 dev_dbg(&client->dev, "detect gc0310 success\n"); 329 330 return 0; 331 } 332 333 static int gc0310_s_stream(struct v4l2_subdev *sd, int enable) 334 { 335 struct gc0310_device *dev = to_gc0310_sensor(sd); 336 struct i2c_client *client = v4l2_get_subdevdata(sd); 337 int ret; 338 339 dev_dbg(&client->dev, "%s S enable=%d\n", __func__, enable); 340 mutex_lock(&dev->input_lock); 341 342 if (enable) { 343 ret = power_up(sd); 344 if (ret) 345 goto error_unlock; 346 347 ret = gc0310_write_reg_array(client, gc0310_reset_register, 348 ARRAY_SIZE(gc0310_reset_register)); 349 if (ret) 350 goto error_power_down; 351 352 ret = gc0310_write_reg_array(client, gc0310_VGA_30fps, 353 ARRAY_SIZE(gc0310_VGA_30fps)); 354 if (ret) 355 goto error_power_down; 356 357 /* restore value of all ctrls */ 358 ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler); 359 if (ret) 360 goto error_power_down; 361 362 /* enable per frame MIPI and sensor ctrl reset */ 363 ret = i2c_smbus_write_byte_data(client, 0xFE, 0x30); 364 if (ret) 365 goto error_power_down; 366 } 367 368 ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_3); 369 if (ret) 370 goto error_power_down; 371 372 ret = i2c_smbus_write_byte_data(client, GC0310_SW_STREAM, 373 enable ? GC0310_START_STREAMING : GC0310_STOP_STREAMING); 374 if (ret) 375 goto error_power_down; 376 377 ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_0); 378 if (ret) 379 goto error_power_down; 380 381 if (!enable) 382 power_down(sd); 383 384 mutex_unlock(&dev->input_lock); 385 return 0; 386 387 error_power_down: 388 power_down(sd); 389 error_unlock: 390 mutex_unlock(&dev->input_lock); 391 return ret; 392 } 393 394 static int gc0310_s_config(struct v4l2_subdev *sd, 395 int irq, void *platform_data) 396 { 397 struct gc0310_device *dev = to_gc0310_sensor(sd); 398 struct i2c_client *client = v4l2_get_subdevdata(sd); 399 int ret = 0; 400 401 if (!platform_data) 402 return -ENODEV; 403 404 dev->platform_data = 405 (struct camera_sensor_platform_data *)platform_data; 406 407 mutex_lock(&dev->input_lock); 408 /* power off the module, then power on it in future 409 * as first power on by board may not fulfill the 410 * power on sequqence needed by the module 411 */ 412 dev->power_on = true; /* force power_down() to run */ 413 ret = power_down(sd); 414 if (ret) { 415 dev_err(&client->dev, "gc0310 power-off err.\n"); 416 goto fail_power_off; 417 } 418 419 ret = power_up(sd); 420 if (ret) { 421 dev_err(&client->dev, "gc0310 power-up err.\n"); 422 goto fail_power_on; 423 } 424 425 ret = dev->platform_data->csi_cfg(sd, 1); 426 if (ret) 427 goto fail_csi_cfg; 428 429 /* config & detect sensor */ 430 ret = gc0310_detect(client); 431 if (ret) { 432 dev_err(&client->dev, "gc0310_detect err s_config.\n"); 433 goto fail_csi_cfg; 434 } 435 436 /* turn off sensor, after probed */ 437 ret = power_down(sd); 438 if (ret) { 439 dev_err(&client->dev, "gc0310 power-off err.\n"); 440 goto fail_csi_cfg; 441 } 442 mutex_unlock(&dev->input_lock); 443 444 return 0; 445 446 fail_csi_cfg: 447 dev->platform_data->csi_cfg(sd, 0); 448 fail_power_on: 449 power_down(sd); 450 dev_err(&client->dev, "sensor power-gating failed\n"); 451 fail_power_off: 452 mutex_unlock(&dev->input_lock); 453 return ret; 454 } 455 456 static int gc0310_g_frame_interval(struct v4l2_subdev *sd, 457 struct v4l2_subdev_frame_interval *interval) 458 { 459 interval->interval.numerator = 1; 460 interval->interval.denominator = GC0310_FPS; 461 462 return 0; 463 } 464 465 static int gc0310_enum_mbus_code(struct v4l2_subdev *sd, 466 struct v4l2_subdev_state *sd_state, 467 struct v4l2_subdev_mbus_code_enum *code) 468 { 469 /* We support only a single format */ 470 if (code->index) 471 return -EINVAL; 472 473 code->code = MEDIA_BUS_FMT_SGRBG8_1X8; 474 return 0; 475 } 476 477 static int gc0310_enum_frame_size(struct v4l2_subdev *sd, 478 struct v4l2_subdev_state *sd_state, 479 struct v4l2_subdev_frame_size_enum *fse) 480 { 481 /* We support only a single resolution */ 482 if (fse->index) 483 return -EINVAL; 484 485 fse->min_width = GC0310_NATIVE_WIDTH; 486 fse->max_width = GC0310_NATIVE_WIDTH; 487 fse->min_height = GC0310_NATIVE_HEIGHT; 488 fse->max_height = GC0310_NATIVE_HEIGHT; 489 490 return 0; 491 } 492 493 static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) 494 { 495 *frames = GC0310_SKIP_FRAMES; 496 return 0; 497 } 498 499 static const struct v4l2_subdev_sensor_ops gc0310_sensor_ops = { 500 .g_skip_frames = gc0310_g_skip_frames, 501 }; 502 503 static const struct v4l2_subdev_video_ops gc0310_video_ops = { 504 .s_stream = gc0310_s_stream, 505 .g_frame_interval = gc0310_g_frame_interval, 506 }; 507 508 static const struct v4l2_subdev_pad_ops gc0310_pad_ops = { 509 .enum_mbus_code = gc0310_enum_mbus_code, 510 .enum_frame_size = gc0310_enum_frame_size, 511 .get_fmt = gc0310_get_fmt, 512 .set_fmt = gc0310_set_fmt, 513 }; 514 515 static const struct v4l2_subdev_ops gc0310_ops = { 516 .video = &gc0310_video_ops, 517 .pad = &gc0310_pad_ops, 518 .sensor = &gc0310_sensor_ops, 519 }; 520 521 static int gc0310_init_controls(struct gc0310_device *dev) 522 { 523 struct v4l2_ctrl_handler *hdl = &dev->ctrls.handler; 524 525 v4l2_ctrl_handler_init(hdl, 2); 526 527 /* Use the same lock for controls as for everything else */ 528 hdl->lock = &dev->input_lock; 529 dev->sd.ctrl_handler = hdl; 530 531 dev->ctrls.exposure = 532 v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, 4095, 1, 1023); 533 534 /* 32 steps at base gain 1 + 64 half steps at base gain 2 */ 535 dev->ctrls.gain = 536 v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_GAIN, 0, 95, 1, 31); 537 538 return hdl->error; 539 } 540 541 static void gc0310_remove(struct i2c_client *client) 542 { 543 struct v4l2_subdev *sd = i2c_get_clientdata(client); 544 struct gc0310_device *dev = to_gc0310_sensor(sd); 545 546 dev_dbg(&client->dev, "gc0310_remove...\n"); 547 548 dev->platform_data->csi_cfg(sd, 0); 549 550 v4l2_device_unregister_subdev(sd); 551 media_entity_cleanup(&dev->sd.entity); 552 v4l2_ctrl_handler_free(&dev->ctrls.handler); 553 kfree(dev); 554 } 555 556 static int gc0310_probe(struct i2c_client *client) 557 { 558 struct gc0310_device *dev; 559 int ret; 560 void *pdata; 561 562 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 563 if (!dev) 564 return -ENOMEM; 565 566 mutex_init(&dev->input_lock); 567 v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops); 568 gc0310_fill_format(&dev->mode.fmt); 569 570 pdata = gmin_camera_platform_data(&dev->sd, 571 ATOMISP_INPUT_FORMAT_RAW_8, 572 atomisp_bayer_order_grbg); 573 if (!pdata) { 574 ret = -EINVAL; 575 goto out_free; 576 } 577 578 ret = gc0310_s_config(&dev->sd, client->irq, pdata); 579 if (ret) 580 goto out_free; 581 582 ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA); 583 if (ret) 584 goto out_free; 585 586 dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 587 dev->pad.flags = MEDIA_PAD_FL_SOURCE; 588 dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; 589 590 ret = gc0310_init_controls(dev); 591 if (ret) { 592 gc0310_remove(client); 593 return ret; 594 } 595 596 ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); 597 if (ret) 598 gc0310_remove(client); 599 600 return ret; 601 out_free: 602 v4l2_device_unregister_subdev(&dev->sd); 603 kfree(dev); 604 return ret; 605 } 606 607 static const struct acpi_device_id gc0310_acpi_match[] = { 608 {"XXGC0310"}, 609 {"INT0310"}, 610 {}, 611 }; 612 MODULE_DEVICE_TABLE(acpi, gc0310_acpi_match); 613 614 static struct i2c_driver gc0310_driver = { 615 .driver = { 616 .name = "gc0310", 617 .acpi_match_table = gc0310_acpi_match, 618 }, 619 .probe_new = gc0310_probe, 620 .remove = gc0310_remove, 621 }; 622 module_i2c_driver(gc0310_driver); 623 624 MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>"); 625 MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors"); 626 MODULE_LICENSE("GPL"); 627