rdacm21.c (15413B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * IMI RDACM21 GMSL Camera Driver 4 * 5 * Copyright (C) 2017-2020 Jacopo Mondi 6 * Copyright (C) 2017-2019 Kieran Bingham 7 * Copyright (C) 2017-2019 Laurent Pinchart 8 * Copyright (C) 2017-2019 Niklas Söderlund 9 * Copyright (C) 2016 Renesas Electronics Corporation 10 * Copyright (C) 2015 Cogent Embedded, Inc. 11 */ 12 13#include <linux/delay.h> 14#include <linux/fwnode.h> 15#include <linux/init.h> 16#include <linux/i2c.h> 17#include <linux/module.h> 18#include <linux/slab.h> 19#include <linux/videodev2.h> 20 21#include <media/v4l2-async.h> 22#include <media/v4l2-ctrls.h> 23#include <media/v4l2-subdev.h> 24#include "max9271.h" 25 26#define MAX9271_RESET_CYCLES 10 27 28#define OV490_I2C_ADDRESS 0x24 29 30#define OV490_PAGE_HIGH_REG 0xfffd 31#define OV490_PAGE_LOW_REG 0xfffe 32 33/* 34 * The SCCB slave handling is undocumented; the registers naming scheme is 35 * totally arbitrary. 36 */ 37#define OV490_SCCB_SLAVE_WRITE 0x00 38#define OV490_SCCB_SLAVE_READ 0x01 39#define OV490_SCCB_SLAVE0_DIR 0x80195000 40#define OV490_SCCB_SLAVE0_ADDR_HIGH 0x80195001 41#define OV490_SCCB_SLAVE0_ADDR_LOW 0x80195002 42 43#define OV490_DVP_CTRL3 0x80286009 44 45#define OV490_ODS_CTRL_FRAME_OUTPUT_EN 0x0c 46#define OV490_ODS_CTRL 0x8029d000 47 48#define OV490_HOST_CMD 0x808000c0 49#define OV490_HOST_CMD_TRIGGER 0xc1 50 51#define OV490_ID_VAL 0x0490 52#define OV490_ID(_p, _v) ((((_p) & 0xff) << 8) | ((_v) & 0xff)) 53#define OV490_PID 0x8080300a 54#define OV490_VER 0x8080300b 55#define OV490_PID_TIMEOUT 20 56#define OV490_OUTPUT_EN_TIMEOUT 300 57 58#define OV490_GPIO0 BIT(0) 59#define OV490_SPWDN0 BIT(0) 60#define OV490_GPIO_SEL0 0x80800050 61#define OV490_GPIO_SEL1 0x80800051 62#define OV490_GPIO_DIRECTION0 0x80800054 63#define OV490_GPIO_DIRECTION1 0x80800055 64#define OV490_GPIO_OUTPUT_VALUE0 0x80800058 65#define OV490_GPIO_OUTPUT_VALUE1 0x80800059 66 67#define OV490_ISP_HSIZE_LOW 0x80820060 68#define OV490_ISP_HSIZE_HIGH 0x80820061 69#define OV490_ISP_VSIZE_LOW 0x80820062 70#define OV490_ISP_VSIZE_HIGH 0x80820063 71 72#define OV10640_PID_TIMEOUT 20 73#define OV10640_ID_HIGH 0xa6 74#define OV10640_CHIP_ID 0x300a 75#define OV10640_PIXEL_RATE 55000000 76 77struct rdacm21_device { 78 struct device *dev; 79 struct max9271_device serializer; 80 struct i2c_client *isp; 81 struct v4l2_subdev sd; 82 struct media_pad pad; 83 struct v4l2_mbus_framefmt fmt; 84 struct v4l2_ctrl_handler ctrls; 85 u32 addrs[2]; 86 u16 last_page; 87}; 88 89static inline struct rdacm21_device *sd_to_rdacm21(struct v4l2_subdev *sd) 90{ 91 return container_of(sd, struct rdacm21_device, sd); 92} 93 94static const struct ov490_reg { 95 u16 reg; 96 u8 val; 97} ov490_regs_wizard[] = { 98 {0xfffd, 0x80}, 99 {0xfffe, 0x82}, 100 {0x0071, 0x11}, 101 {0x0075, 0x11}, 102 {0xfffe, 0x29}, 103 {0x6010, 0x01}, 104 /* 105 * OV490 EMB line disable in YUV and RAW data, 106 * NOTE: EMB line is still used in ISP and sensor 107 */ 108 {0xe000, 0x14}, 109 {0xfffe, 0x28}, 110 {0x6000, 0x04}, 111 {0x6004, 0x00}, 112 /* 113 * PCLK polarity - useless due to silicon bug. 114 * Use 0x808000bb register instead. 115 */ 116 {0x6008, 0x00}, 117 {0xfffe, 0x80}, 118 {0x0091, 0x00}, 119 /* bit[3]=0 - PCLK polarity workaround. */ 120 {0x00bb, 0x1d}, 121 /* Ov490 FSIN: app_fsin_from_fsync */ 122 {0xfffe, 0x85}, 123 {0x0008, 0x00}, 124 {0x0009, 0x01}, 125 /* FSIN0 source. */ 126 {0x000A, 0x05}, 127 {0x000B, 0x00}, 128 /* FSIN0 delay. */ 129 {0x0030, 0x02}, 130 {0x0031, 0x00}, 131 {0x0032, 0x00}, 132 {0x0033, 0x00}, 133 /* FSIN1 delay. */ 134 {0x0038, 0x02}, 135 {0x0039, 0x00}, 136 {0x003A, 0x00}, 137 {0x003B, 0x00}, 138 /* FSIN0 length. */ 139 {0x0070, 0x2C}, 140 {0x0071, 0x01}, 141 {0x0072, 0x00}, 142 {0x0073, 0x00}, 143 /* FSIN1 length. */ 144 {0x0074, 0x64}, 145 {0x0075, 0x00}, 146 {0x0076, 0x00}, 147 {0x0077, 0x00}, 148 {0x0000, 0x14}, 149 {0x0001, 0x00}, 150 {0x0002, 0x00}, 151 {0x0003, 0x00}, 152 /* 153 * Load fsin0,load fsin1,load other, 154 * It will be cleared automatically. 155 */ 156 {0x0004, 0x32}, 157 {0x0005, 0x00}, 158 {0x0006, 0x00}, 159 {0x0007, 0x00}, 160 {0xfffe, 0x80}, 161 /* Sensor FSIN. */ 162 {0x0081, 0x00}, 163 /* ov10640 FSIN enable */ 164 {0xfffe, 0x19}, 165 {0x5000, 0x00}, 166 {0x5001, 0x30}, 167 {0x5002, 0x8c}, 168 {0x5003, 0xb2}, 169 {0xfffe, 0x80}, 170 {0x00c0, 0xc1}, 171 /* ov10640 HFLIP=1 by default */ 172 {0xfffe, 0x19}, 173 {0x5000, 0x01}, 174 {0x5001, 0x00}, 175 {0xfffe, 0x80}, 176 {0x00c0, 0xdc}, 177}; 178 179static int ov490_read(struct rdacm21_device *dev, u16 reg, u8 *val) 180{ 181 u8 buf[2] = { reg >> 8, reg }; 182 int ret; 183 184 ret = i2c_master_send(dev->isp, buf, 2); 185 if (ret == 2) 186 ret = i2c_master_recv(dev->isp, val, 1); 187 188 if (ret < 0) { 189 dev_dbg(dev->dev, "%s: register 0x%04x read failed (%d)\n", 190 __func__, reg, ret); 191 return ret; 192 } 193 194 return 0; 195} 196 197static int ov490_write(struct rdacm21_device *dev, u16 reg, u8 val) 198{ 199 u8 buf[3] = { reg >> 8, reg, val }; 200 int ret; 201 202 ret = i2c_master_send(dev->isp, buf, 3); 203 if (ret < 0) { 204 dev_err(dev->dev, "%s: register 0x%04x write failed (%d)\n", 205 __func__, reg, ret); 206 return ret; 207 } 208 209 return 0; 210} 211 212static int ov490_set_page(struct rdacm21_device *dev, u16 page) 213{ 214 u8 page_high = page >> 8; 215 u8 page_low = page; 216 int ret; 217 218 if (page == dev->last_page) 219 return 0; 220 221 if (page_high != (dev->last_page >> 8)) { 222 ret = ov490_write(dev, OV490_PAGE_HIGH_REG, page_high); 223 if (ret) 224 return ret; 225 } 226 227 if (page_low != (u8)dev->last_page) { 228 ret = ov490_write(dev, OV490_PAGE_LOW_REG, page_low); 229 if (ret) 230 return ret; 231 } 232 233 dev->last_page = page; 234 usleep_range(100, 150); 235 236 return 0; 237} 238 239static int ov490_read_reg(struct rdacm21_device *dev, u32 reg, u8 *val) 240{ 241 int ret; 242 243 ret = ov490_set_page(dev, reg >> 16); 244 if (ret) 245 return ret; 246 247 ret = ov490_read(dev, (u16)reg, val); 248 if (ret) 249 return ret; 250 251 dev_dbg(dev->dev, "%s: 0x%08x = 0x%02x\n", __func__, reg, *val); 252 253 return 0; 254} 255 256static int ov490_write_reg(struct rdacm21_device *dev, u32 reg, u8 val) 257{ 258 int ret; 259 260 ret = ov490_set_page(dev, reg >> 16); 261 if (ret) 262 return ret; 263 264 ret = ov490_write(dev, (u16)reg, val); 265 if (ret) 266 return ret; 267 268 dev_dbg(dev->dev, "%s: 0x%08x = 0x%02x\n", __func__, reg, val); 269 270 return 0; 271} 272 273static int rdacm21_s_stream(struct v4l2_subdev *sd, int enable) 274{ 275 struct rdacm21_device *dev = sd_to_rdacm21(sd); 276 277 /* 278 * Enable serial link now that the ISP provides a valid pixel clock 279 * to start serializing video data on the GMSL link. 280 */ 281 return max9271_set_serial_link(&dev->serializer, enable); 282} 283 284static int rdacm21_enum_mbus_code(struct v4l2_subdev *sd, 285 struct v4l2_subdev_state *sd_state, 286 struct v4l2_subdev_mbus_code_enum *code) 287{ 288 if (code->pad || code->index > 0) 289 return -EINVAL; 290 291 code->code = MEDIA_BUS_FMT_YUYV8_1X16; 292 293 return 0; 294} 295 296static int rdacm21_get_fmt(struct v4l2_subdev *sd, 297 struct v4l2_subdev_state *sd_state, 298 struct v4l2_subdev_format *format) 299{ 300 struct v4l2_mbus_framefmt *mf = &format->format; 301 struct rdacm21_device *dev = sd_to_rdacm21(sd); 302 303 if (format->pad) 304 return -EINVAL; 305 306 mf->width = dev->fmt.width; 307 mf->height = dev->fmt.height; 308 mf->code = MEDIA_BUS_FMT_YUYV8_1X16; 309 mf->colorspace = V4L2_COLORSPACE_SRGB; 310 mf->field = V4L2_FIELD_NONE; 311 mf->ycbcr_enc = V4L2_YCBCR_ENC_601; 312 mf->quantization = V4L2_QUANTIZATION_FULL_RANGE; 313 mf->xfer_func = V4L2_XFER_FUNC_NONE; 314 315 return 0; 316} 317 318static const struct v4l2_subdev_video_ops rdacm21_video_ops = { 319 .s_stream = rdacm21_s_stream, 320}; 321 322static const struct v4l2_subdev_pad_ops rdacm21_subdev_pad_ops = { 323 .enum_mbus_code = rdacm21_enum_mbus_code, 324 .get_fmt = rdacm21_get_fmt, 325 .set_fmt = rdacm21_get_fmt, 326}; 327 328static const struct v4l2_subdev_ops rdacm21_subdev_ops = { 329 .video = &rdacm21_video_ops, 330 .pad = &rdacm21_subdev_pad_ops, 331}; 332 333static void ov10640_power_up(struct rdacm21_device *dev) 334{ 335 /* Enable GPIO0#0 (reset) and GPIO1#0 (pwdn) as output lines. */ 336 ov490_write_reg(dev, OV490_GPIO_SEL0, OV490_GPIO0); 337 ov490_write_reg(dev, OV490_GPIO_SEL1, OV490_SPWDN0); 338 ov490_write_reg(dev, OV490_GPIO_DIRECTION0, OV490_GPIO0); 339 ov490_write_reg(dev, OV490_GPIO_DIRECTION1, OV490_SPWDN0); 340 341 /* Power up OV10640 and then reset it. */ 342 ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE1, OV490_SPWDN0); 343 usleep_range(1500, 3000); 344 345 ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, 0x00); 346 usleep_range(1500, 3000); 347 ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_GPIO0); 348 usleep_range(3000, 5000); 349} 350 351static int ov10640_check_id(struct rdacm21_device *dev) 352{ 353 unsigned int i; 354 u8 val; 355 356 /* Read OV10640 ID to test communications. */ 357 for (i = 0; i < OV10640_PID_TIMEOUT; ++i) { 358 ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR, 359 OV490_SCCB_SLAVE_READ); 360 ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH, 361 OV10640_CHIP_ID >> 8); 362 ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, 363 OV10640_CHIP_ID & 0xff); 364 365 /* 366 * Trigger SCCB slave transaction and give it some time 367 * to complete. 368 */ 369 ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER); 370 usleep_range(1000, 1500); 371 372 ov490_read_reg(dev, OV490_SCCB_SLAVE0_DIR, &val); 373 if (val == OV10640_ID_HIGH) 374 break; 375 usleep_range(1000, 1500); 376 } 377 if (i == OV10640_PID_TIMEOUT) { 378 dev_err(dev->dev, "OV10640 ID mismatch: (0x%02x)\n", val); 379 return -ENODEV; 380 } 381 382 dev_dbg(dev->dev, "OV10640 ID = 0x%2x\n", val); 383 384 return 0; 385} 386 387static int ov490_initialize(struct rdacm21_device *dev) 388{ 389 u8 pid, ver, val; 390 unsigned int i; 391 int ret; 392 393 ov10640_power_up(dev); 394 395 /* 396 * Read OV490 Id to test communications. Give it up to 40msec to 397 * exit from reset. 398 */ 399 for (i = 0; i < OV490_PID_TIMEOUT; ++i) { 400 ret = ov490_read_reg(dev, OV490_PID, &pid); 401 if (ret == 0) 402 break; 403 usleep_range(1000, 2000); 404 } 405 if (i == OV490_PID_TIMEOUT) { 406 dev_err(dev->dev, "OV490 PID read failed (%d)\n", ret); 407 return ret; 408 } 409 410 ret = ov490_read_reg(dev, OV490_VER, &ver); 411 if (ret < 0) 412 return ret; 413 414 if (OV490_ID(pid, ver) != OV490_ID_VAL) { 415 dev_err(dev->dev, "OV490 ID mismatch (0x%04x)\n", 416 OV490_ID(pid, ver)); 417 return -ENODEV; 418 } 419 420 /* Wait for firmware boot by reading streamon status. */ 421 for (i = 0; i < OV490_OUTPUT_EN_TIMEOUT; ++i) { 422 ov490_read_reg(dev, OV490_ODS_CTRL, &val); 423 if (val == OV490_ODS_CTRL_FRAME_OUTPUT_EN) 424 break; 425 usleep_range(1000, 2000); 426 } 427 if (i == OV490_OUTPUT_EN_TIMEOUT) { 428 dev_err(dev->dev, "Timeout waiting for firmware boot\n"); 429 return -ENODEV; 430 } 431 432 ret = ov10640_check_id(dev); 433 if (ret) 434 return ret; 435 436 /* Program OV490 with register-value table. */ 437 for (i = 0; i < ARRAY_SIZE(ov490_regs_wizard); ++i) { 438 ret = ov490_write(dev, ov490_regs_wizard[i].reg, 439 ov490_regs_wizard[i].val); 440 if (ret < 0) { 441 dev_err(dev->dev, 442 "%s: register %u (0x%04x) write failed (%d)\n", 443 __func__, i, ov490_regs_wizard[i].reg, ret); 444 445 return -EIO; 446 } 447 448 usleep_range(100, 150); 449 } 450 451 /* 452 * The ISP is programmed with the content of a serial flash memory. 453 * Read the firmware configuration to reflect it through the V4L2 APIs. 454 */ 455 ov490_read_reg(dev, OV490_ISP_HSIZE_HIGH, &val); 456 dev->fmt.width = (val & 0xf) << 8; 457 ov490_read_reg(dev, OV490_ISP_HSIZE_LOW, &val); 458 dev->fmt.width |= (val & 0xff); 459 460 ov490_read_reg(dev, OV490_ISP_VSIZE_HIGH, &val); 461 dev->fmt.height = (val & 0xf) << 8; 462 ov490_read_reg(dev, OV490_ISP_VSIZE_LOW, &val); 463 dev->fmt.height |= val & 0xff; 464 465 /* Set bus width to 12 bits with [0:11] ordering. */ 466 ov490_write_reg(dev, OV490_DVP_CTRL3, 0x10); 467 468 dev_info(dev->dev, "Identified RDACM21 camera module\n"); 469 470 return 0; 471} 472 473static int rdacm21_initialize(struct rdacm21_device *dev) 474{ 475 int ret; 476 477 max9271_wake_up(&dev->serializer); 478 479 /* Enable reverse channel and disable the serial link. */ 480 ret = max9271_set_serial_link(&dev->serializer, false); 481 if (ret) 482 return ret; 483 484 /* Configure I2C bus at 105Kbps speed and configure GMSL. */ 485 ret = max9271_configure_i2c(&dev->serializer, 486 MAX9271_I2CSLVSH_469NS_234NS | 487 MAX9271_I2CSLVTO_1024US | 488 MAX9271_I2CMSTBT_105KBPS); 489 if (ret) 490 return ret; 491 492 ret = max9271_verify_id(&dev->serializer); 493 if (ret) 494 return ret; 495 496 /* 497 * Enable GPIO1 and hold OV490 in reset during max9271 configuration. 498 * The reset signal has to be asserted for at least 250 useconds. 499 */ 500 ret = max9271_enable_gpios(&dev->serializer, MAX9271_GPIO1OUT); 501 if (ret) 502 return ret; 503 504 ret = max9271_clear_gpios(&dev->serializer, MAX9271_GPIO1OUT); 505 if (ret) 506 return ret; 507 usleep_range(250, 500); 508 509 ret = max9271_configure_gmsl_link(&dev->serializer); 510 if (ret) 511 return ret; 512 513 ret = max9271_set_address(&dev->serializer, dev->addrs[0]); 514 if (ret) 515 return ret; 516 dev->serializer.client->addr = dev->addrs[0]; 517 518 ret = max9271_set_translation(&dev->serializer, dev->addrs[1], 519 OV490_I2C_ADDRESS); 520 if (ret) 521 return ret; 522 dev->isp->addr = dev->addrs[1]; 523 524 /* Release OV490 from reset and initialize it. */ 525 ret = max9271_set_gpios(&dev->serializer, MAX9271_GPIO1OUT); 526 if (ret) 527 return ret; 528 usleep_range(3000, 5000); 529 530 ret = ov490_initialize(dev); 531 if (ret) 532 return ret; 533 534 /* 535 * Set reverse channel high threshold to increase noise immunity. 536 * 537 * This should be compensated by increasing the reverse channel 538 * amplitude on the remote deserializer side. 539 */ 540 return max9271_set_high_threshold(&dev->serializer, true); 541} 542 543static int rdacm21_probe(struct i2c_client *client) 544{ 545 struct rdacm21_device *dev; 546 struct fwnode_handle *ep; 547 int ret; 548 549 dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); 550 if (!dev) 551 return -ENOMEM; 552 dev->dev = &client->dev; 553 dev->serializer.client = client; 554 555 ret = of_property_read_u32_array(client->dev.of_node, "reg", 556 dev->addrs, 2); 557 if (ret < 0) { 558 dev_err(dev->dev, "Invalid DT reg property: %d\n", ret); 559 return -EINVAL; 560 } 561 562 /* Create the dummy I2C client for the sensor. */ 563 dev->isp = i2c_new_dummy_device(client->adapter, OV490_I2C_ADDRESS); 564 if (IS_ERR(dev->isp)) 565 return PTR_ERR(dev->isp); 566 567 ret = rdacm21_initialize(dev); 568 if (ret < 0) 569 goto error; 570 571 /* Initialize and register the subdevice. */ 572 v4l2_i2c_subdev_init(&dev->sd, client, &rdacm21_subdev_ops); 573 dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 574 575 v4l2_ctrl_handler_init(&dev->ctrls, 1); 576 v4l2_ctrl_new_std(&dev->ctrls, NULL, V4L2_CID_PIXEL_RATE, 577 OV10640_PIXEL_RATE, OV10640_PIXEL_RATE, 1, 578 OV10640_PIXEL_RATE); 579 dev->sd.ctrl_handler = &dev->ctrls; 580 581 ret = dev->ctrls.error; 582 if (ret) 583 goto error_free_ctrls; 584 585 dev->pad.flags = MEDIA_PAD_FL_SOURCE; 586 dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; 587 ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); 588 if (ret < 0) 589 goto error_free_ctrls; 590 591 ep = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL); 592 if (!ep) { 593 dev_err(&client->dev, 594 "Unable to get endpoint in node %pOF\n", 595 client->dev.of_node); 596 ret = -ENOENT; 597 goto error_free_ctrls; 598 } 599 dev->sd.fwnode = ep; 600 601 ret = v4l2_async_register_subdev(&dev->sd); 602 if (ret) 603 goto error_put_node; 604 605 return 0; 606 607error_put_node: 608 fwnode_handle_put(dev->sd.fwnode); 609error_free_ctrls: 610 v4l2_ctrl_handler_free(&dev->ctrls); 611error: 612 i2c_unregister_device(dev->isp); 613 614 return ret; 615} 616 617static int rdacm21_remove(struct i2c_client *client) 618{ 619 struct rdacm21_device *dev = sd_to_rdacm21(i2c_get_clientdata(client)); 620 621 v4l2_async_unregister_subdev(&dev->sd); 622 v4l2_ctrl_handler_free(&dev->ctrls); 623 i2c_unregister_device(dev->isp); 624 fwnode_handle_put(dev->sd.fwnode); 625 626 return 0; 627} 628 629static const struct of_device_id rdacm21_of_ids[] = { 630 { .compatible = "imi,rdacm21" }, 631 { } 632}; 633MODULE_DEVICE_TABLE(of, rdacm21_of_ids); 634 635static struct i2c_driver rdacm21_i2c_driver = { 636 .driver = { 637 .name = "rdacm21", 638 .of_match_table = rdacm21_of_ids, 639 }, 640 .probe_new = rdacm21_probe, 641 .remove = rdacm21_remove, 642}; 643 644module_i2c_driver(rdacm21_i2c_driver); 645 646MODULE_DESCRIPTION("GMSL Camera driver for RDACM21"); 647MODULE_AUTHOR("Jacopo Mondi"); 648MODULE_LICENSE("GPL v2");