Lines Matching +full:gmsl +full:- +full:deserializer

1 // SPDX-License-Identifier: GPL-2.0+
3 * IMI RDACM20 GMSL Camera Driver
5 * Copyright (C) 2017-2020 Jacopo Mondi
6 * Copyright (C) 2017-2020 Kieran Bingham
7 * Copyright (C) 2017-2019 Laurent Pinchart
8 * Copyright (C) 2017-2019 Niklas Söderlund
15 * MAX9271 GMSL serializer.
26 #include <media/v4l2-async.h>
27 #include <media/v4l2-ctrls.h>
28 #include <media/v4l2-subdev.h>
131 /* fifo_hsync_start = 2*(hts - xres) */
132 { 0x460a, (2 * (OV10635_HTS - OV10635_WIDTH)) >> 8 },
133 { 0x460b, (2 * (OV10635_HTS - OV10635_WIDTH)) & 0xff },
219 /* Swap data bits order [9:0] -> [0:9] */
236 { 0xc488, (OV10635_VTS - 8) * 16 >> 8},
237 { 0xc489, (OV10635_VTS - 8) * 16 & 0xff},
238 { 0xc48a, (OV10635_VTS - 8) * 16 >> 8},
239 { 0xc48b, (OV10635_VTS - 8) * 16 & 0xff}, { 0xc48c, 0x00 },
338 ret = i2c_master_send(dev->sensor, buf, 2); in ov10635_read16()
340 dev_dbg(dev->dev, "%s: register 0x%04x write failed (%d)\n", in ov10635_read16()
345 ret = i2c_master_recv(dev->sensor, buf, 2); in ov10635_read16()
347 dev_dbg(dev->dev, "%s: register 0x%04x read failed (%d)\n", in ov10635_read16()
360 dev_dbg(dev->dev, "%s(0x%04x, 0x%02x)\n", __func__, reg, val); in __ov10635_write()
362 ret = i2c_master_send(dev->sensor, buf, 3); in __ov10635_write()
372 dev_err(dev->dev, "%s: register 0x%04x write failed (%d)\n", in ov10635_write()
388 dev_err(dev->dev, in ov10635_set_regs()
402 return max9271_set_serial_link(&dev->serializer, enable); in rdacm20_s_stream()
409 if (code->pad || code->index > 0) in rdacm20_enum_mbus_code()
410 return -EINVAL; in rdacm20_enum_mbus_code()
412 code->code = MEDIA_BUS_FMT_UYVY8_1X16; in rdacm20_enum_mbus_code()
421 struct v4l2_mbus_framefmt *mf = &format->format; in rdacm20_get_fmt()
423 if (format->pad) in rdacm20_get_fmt()
424 return -EINVAL; in rdacm20_get_fmt()
426 mf->width = OV10635_WIDTH; in rdacm20_get_fmt()
427 mf->height = OV10635_HEIGHT; in rdacm20_get_fmt()
428 mf->code = MEDIA_BUS_FMT_UYVY8_1X16; in rdacm20_get_fmt()
429 mf->colorspace = V4L2_COLORSPACE_RAW; in rdacm20_get_fmt()
430 mf->field = V4L2_FIELD_NONE; in rdacm20_get_fmt()
431 mf->ycbcr_enc = V4L2_YCBCR_ENC_601; in rdacm20_get_fmt()
432 mf->quantization = V4L2_QUANTIZATION_FULL_RANGE; in rdacm20_get_fmt()
433 mf->xfer_func = V4L2_XFER_FUNC_NONE; in rdacm20_get_fmt()
458 max9271_wake_up(&dev->serializer); in rdacm20_initialize()
461 ret = max9271_set_serial_link(&dev->serializer, false); in rdacm20_initialize()
469 ret = max9271_configure_i2c(&dev->serializer, in rdacm20_initialize()
480 ret = max9271_enable_gpios(&dev->serializer, MAX9271_GPIO1OUT); in rdacm20_initialize()
484 ret = max9271_clear_gpios(&dev->serializer, MAX9271_GPIO1OUT); in rdacm20_initialize()
489 ret = max9271_configure_gmsl_link(&dev->serializer); in rdacm20_initialize()
493 ret = max9271_verify_id(&dev->serializer); in rdacm20_initialize()
497 ret = max9271_set_address(&dev->serializer, dev->addrs[0]); in rdacm20_initialize()
500 dev->serializer.client->addr = dev->addrs[0]; in rdacm20_initialize()
504 * requires at least 2048 XVCLK cycles (85 micro-seconds at 24MHz) in rdacm20_initialize()
505 * before being available. Stay safe and wait up to 500 micro-seconds. in rdacm20_initialize()
507 ret = max9271_set_gpios(&dev->serializer, MAX9271_GPIO1OUT); in rdacm20_initialize()
515 if (retry--) in rdacm20_initialize()
518 dev_err(dev->dev, "OV10635 ID read failed (%d)\n", in rdacm20_initialize()
520 return -ENXIO; in rdacm20_initialize()
524 if (retry--) in rdacm20_initialize()
527 dev_err(dev->dev, "OV10635 ID mismatch (0x%04x)\n", in rdacm20_initialize()
529 return -ENXIO; in rdacm20_initialize()
534 (dev->addrs[1] << 1) | in rdacm20_initialize()
537 dev_err(dev->dev, in rdacm20_initialize()
541 dev->sensor->addr = dev->addrs[1]; in rdacm20_initialize()
550 dev_info(dev->dev, "Identified RDACM20 camera module\n"); in rdacm20_initialize()
556 * amplitude on the remote deserializer side. in rdacm20_initialize()
564 return max9271_set_high_threshold(&dev->serializer, true); in rdacm20_initialize()
572 dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); in rdacm20_probe()
574 return -ENOMEM; in rdacm20_probe()
575 dev->dev = &client->dev; in rdacm20_probe()
576 dev->serializer.client = client; in rdacm20_probe()
578 ret = of_property_read_u32_array(client->dev.of_node, "reg", in rdacm20_probe()
579 dev->addrs, 2); in rdacm20_probe()
581 dev_err(dev->dev, "Invalid DT reg property: %d\n", ret); in rdacm20_probe()
582 return -EINVAL; in rdacm20_probe()
586 dev->sensor = i2c_new_dummy_device(client->adapter, in rdacm20_probe()
588 if (IS_ERR(dev->sensor)) { in rdacm20_probe()
589 ret = PTR_ERR(dev->sensor); in rdacm20_probe()
599 v4l2_i2c_subdev_init(&dev->sd, client, &rdacm20_subdev_ops); in rdacm20_probe()
600 dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in rdacm20_probe()
602 v4l2_ctrl_handler_init(&dev->ctrls, 1); in rdacm20_probe()
603 v4l2_ctrl_new_std(&dev->ctrls, NULL, V4L2_CID_PIXEL_RATE, in rdacm20_probe()
606 dev->sd.ctrl_handler = &dev->ctrls; in rdacm20_probe()
608 ret = dev->ctrls.error; in rdacm20_probe()
612 dev->pad.flags = MEDIA_PAD_FL_SOURCE; in rdacm20_probe()
613 dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in rdacm20_probe()
614 ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); in rdacm20_probe()
618 ret = v4l2_async_register_subdev(&dev->sd); in rdacm20_probe()
625 v4l2_ctrl_handler_free(&dev->ctrls); in rdacm20_probe()
627 media_entity_cleanup(&dev->sd.entity); in rdacm20_probe()
628 i2c_unregister_device(dev->sensor); in rdacm20_probe()
630 dev_err(&client->dev, "probe failed\n"); in rdacm20_probe()
639 v4l2_async_unregister_subdev(&dev->sd); in rdacm20_remove()
640 v4l2_ctrl_handler_free(&dev->ctrls); in rdacm20_remove()
641 media_entity_cleanup(&dev->sd.entity); in rdacm20_remove()
642 i2c_unregister_device(dev->sensor); in rdacm20_remove()
650 rdacm20_s_stream(&dev->sd, 0); in rdacm20_shutdown()
671 MODULE_DESCRIPTION("GMSL Camera driver for RDACM20");