Lines Matching +full:sama5d2 +full:- +full:isc

1 // SPDX-License-Identifier: GPL-2.0
3 * Microchip Image Sensor Controller (ISC) driver
5 * Copyright (C) 2016-2019 Microchip Technology, Inc.
11 * Sensor-->PFE-->WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB-->RLP-->DMA
13 * ISC video pipeline integrates the following submodules:
28 #include <linux/clk-provider.h>
40 #include <media/v4l2-ctrls.h>
41 #include <media/v4l2-device.h>
42 #include <media/v4l2-event.h>
43 #include <media/v4l2-image-sizes.h>
44 #include <media/v4l2-ioctl.h>
45 #include <media/v4l2-fwnode.h>
46 #include <media/v4l2-subdev.h>
47 #include <media/videobuf2-dma-contig.h>
49 #include "microchip-isc-regs.h"
50 #include "microchip-isc.h"
59 /* This is a list of the formats that the ISC can *output* */
120 /* This is a list of formats that the ISC can receive as *input* */
217 static void isc_sama5d2_config_csc(struct isc_device *isc) in isc_sama5d2_config_csc() argument
219 struct regmap *regmap = isc->regmap; in isc_sama5d2_config_csc()
222 regmap_write(regmap, ISC_CSC_YR_YG + isc->offsets.csc, in isc_sama5d2_config_csc()
224 regmap_write(regmap, ISC_CSC_YB_OY + isc->offsets.csc, in isc_sama5d2_config_csc()
226 regmap_write(regmap, ISC_CSC_CBR_CBG + isc->offsets.csc, in isc_sama5d2_config_csc()
228 regmap_write(regmap, ISC_CSC_CBB_OCB + isc->offsets.csc, in isc_sama5d2_config_csc()
230 regmap_write(regmap, ISC_CSC_CRR_CRG + isc->offsets.csc, in isc_sama5d2_config_csc()
232 regmap_write(regmap, ISC_CSC_CRB_OCR + isc->offsets.csc, in isc_sama5d2_config_csc()
236 static void isc_sama5d2_config_cbc(struct isc_device *isc) in isc_sama5d2_config_cbc() argument
238 struct regmap *regmap = isc->regmap; in isc_sama5d2_config_cbc()
240 regmap_write(regmap, ISC_CBC_BRIGHT + isc->offsets.cbc, in isc_sama5d2_config_cbc()
241 isc->ctrls.brightness); in isc_sama5d2_config_cbc()
242 regmap_write(regmap, ISC_CBC_CONTRAST + isc->offsets.cbc, in isc_sama5d2_config_cbc()
243 isc->ctrls.contrast); in isc_sama5d2_config_cbc()
246 static void isc_sama5d2_config_cc(struct isc_device *isc) in isc_sama5d2_config_cc() argument
248 struct regmap *regmap = isc->regmap; in isc_sama5d2_config_cc()
259 static void isc_sama5d2_config_ctrls(struct isc_device *isc, in isc_sama5d2_config_ctrls() argument
262 struct isc_ctrls *ctrls = &isc->ctrls; in isc_sama5d2_config_ctrls()
263 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in isc_sama5d2_config_ctrls()
265 ctrls->contrast = 256; in isc_sama5d2_config_ctrls()
267 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); in isc_sama5d2_config_ctrls()
270 static void isc_sama5d2_config_dpc(struct isc_device *isc) in isc_sama5d2_config_dpc() argument
272 /* This module is not present on sama5d2 pipeline */ in isc_sama5d2_config_dpc()
275 static void isc_sama5d2_config_gam(struct isc_device *isc) in isc_sama5d2_config_gam() argument
280 static void isc_sama5d2_config_rlp(struct isc_device *isc) in isc_sama5d2_config_rlp() argument
282 struct regmap *regmap = isc->regmap; in isc_sama5d2_config_rlp()
283 u32 rlp_mode = isc->config.rlp_cfg_mode; in isc_sama5d2_config_rlp()
286 * In sama5d2, the YUV planar modes and the YUYV modes are treated in isc_sama5d2_config_rlp()
288 * Normally, YYCC mode should be Luma(n) - Color B(n) - Color R (n) in isc_sama5d2_config_rlp()
289 * and YCYC should be Luma(n + 1) - Color B (n) - Luma (n) - Color R (n) in isc_sama5d2_config_rlp()
290 * but in sama5d2, the YCYC mode does not exist, and YYCC must be in isc_sama5d2_config_rlp()
295 * sama5d2-compliant mode which is YYCC . in isc_sama5d2_config_rlp()
302 regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, in isc_sama5d2_config_rlp()
306 static void isc_sama5d2_adapt_pipeline(struct isc_device *isc) in isc_sama5d2_adapt_pipeline() argument
308 isc->try_config.bits_pipeline &= ISC_SAMA5D2_PIPELINE; in isc_sama5d2_adapt_pipeline()
313 /* 0 --> gamma 1/1.8 */
326 /* 1 --> gamma 1/2 */
339 /* 2 --> gamma 1/2.2 */
353 static int isc_parse_dt(struct device *dev, struct isc_device *isc) in isc_parse_dt() argument
355 struct device_node *np = dev->of_node; in isc_parse_dt()
360 INIT_LIST_HEAD(&isc->subdev_entities); in isc_parse_dt()
371 return -EINVAL; in isc_parse_dt()
378 return -ENOMEM; in isc_parse_dt()
380 subdev_entity->epn = epn; in isc_parse_dt()
385 subdev_entity->pfe_cfg0 = ISC_PFE_CFG0_HPOL_LOW; in isc_parse_dt()
388 subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_VPOL_LOW; in isc_parse_dt()
391 subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW; in isc_parse_dt()
394 subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC | in isc_parse_dt()
397 list_add_tail(&subdev_entity->list, &isc->subdev_entities); in isc_parse_dt()
405 struct device *dev = &pdev->dev; in microchip_isc_probe()
406 struct isc_device *isc; in microchip_isc_probe() local
413 isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL); in microchip_isc_probe()
414 if (!isc) in microchip_isc_probe()
415 return -ENOMEM; in microchip_isc_probe()
417 platform_set_drvdata(pdev, isc); in microchip_isc_probe()
418 isc->dev = dev; in microchip_isc_probe()
424 isc->regmap = devm_regmap_init_mmio(dev, io_base, &microchip_isc_regmap_config); in microchip_isc_probe()
425 if (IS_ERR(isc->regmap)) { in microchip_isc_probe()
426 ret = PTR_ERR(isc->regmap); in microchip_isc_probe()
436 "microchip-sama5d2-isc", isc); in microchip_isc_probe()
443 isc->gamma_table = isc_sama5d2_gamma_table; in microchip_isc_probe()
444 isc->gamma_max = 2; in microchip_isc_probe()
446 isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; in microchip_isc_probe()
447 isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; in microchip_isc_probe()
449 isc->config_dpc = isc_sama5d2_config_dpc; in microchip_isc_probe()
450 isc->config_csc = isc_sama5d2_config_csc; in microchip_isc_probe()
451 isc->config_cbc = isc_sama5d2_config_cbc; in microchip_isc_probe()
452 isc->config_cc = isc_sama5d2_config_cc; in microchip_isc_probe()
453 isc->config_gam = isc_sama5d2_config_gam; in microchip_isc_probe()
454 isc->config_rlp = isc_sama5d2_config_rlp; in microchip_isc_probe()
455 isc->config_ctrls = isc_sama5d2_config_ctrls; in microchip_isc_probe()
457 isc->adapt_pipeline = isc_sama5d2_adapt_pipeline; in microchip_isc_probe()
459 isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; in microchip_isc_probe()
460 isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; in microchip_isc_probe()
461 isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; in microchip_isc_probe()
462 isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; in microchip_isc_probe()
463 isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; in microchip_isc_probe()
464 isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; in microchip_isc_probe()
465 isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET; in microchip_isc_probe()
466 isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET; in microchip_isc_probe()
467 isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET; in microchip_isc_probe()
469 isc->controller_formats = sama5d2_controller_formats; in microchip_isc_probe()
470 isc->controller_formats_size = ARRAY_SIZE(sama5d2_controller_formats); in microchip_isc_probe()
471 isc->formats_list = sama5d2_formats_list; in microchip_isc_probe()
472 isc->formats_list_size = ARRAY_SIZE(sama5d2_formats_list); in microchip_isc_probe()
474 /* sama5d2-isc - 8 bits per beat */ in microchip_isc_probe()
475 isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; in microchip_isc_probe()
477 /* sama5d2-isc : ISPCK is required and mandatory */ in microchip_isc_probe()
478 isc->ispck_required = true; in microchip_isc_probe()
480 ret = microchip_isc_pipeline_init(isc); in microchip_isc_probe()
484 isc->hclock = devm_clk_get(dev, "hclock"); in microchip_isc_probe()
485 if (IS_ERR(isc->hclock)) { in microchip_isc_probe()
486 ret = PTR_ERR(isc->hclock); in microchip_isc_probe()
491 ret = clk_prepare_enable(isc->hclock); in microchip_isc_probe()
497 ret = microchip_isc_clk_init(isc); in microchip_isc_probe()
499 dev_err(dev, "failed to init isc clock: %d\n", ret); in microchip_isc_probe()
502 ret = v4l2_device_register(dev, &isc->v4l2_dev); in microchip_isc_probe()
508 ret = isc_parse_dt(dev, isc); in microchip_isc_probe()
514 if (list_empty(&isc->subdev_entities)) { in microchip_isc_probe()
516 ret = -ENODEV; in microchip_isc_probe()
520 list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { in microchip_isc_probe()
523 of_fwnode_handle(subdev_entity->epn); in microchip_isc_probe()
525 v4l2_async_nf_init(&subdev_entity->notifier, &isc->v4l2_dev); in microchip_isc_probe()
527 asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier, in microchip_isc_probe()
531 of_node_put(subdev_entity->epn); in microchip_isc_probe()
532 subdev_entity->epn = NULL; in microchip_isc_probe()
539 subdev_entity->notifier.ops = &microchip_isc_async_ops; in microchip_isc_probe()
541 ret = v4l2_async_nf_register(&subdev_entity->notifier); in microchip_isc_probe()
547 if (video_is_registered(&isc->video_dev)) in microchip_isc_probe()
551 regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver); in microchip_isc_probe()
553 ret = isc_mc_init(isc, ver); in microchip_isc_probe()
561 isc->ispck = isc->isc_clks[ISC_ISPCK].clk; in microchip_isc_probe()
563 ret = clk_prepare_enable(isc->ispck); in microchip_isc_probe()
570 ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); in microchip_isc_probe()
576 dev_info(dev, "Microchip ISC version %x\n", ver); in microchip_isc_probe()
581 clk_disable_unprepare(isc->ispck); in microchip_isc_probe()
587 isc_mc_cleanup(isc); in microchip_isc_probe()
590 microchip_isc_subdev_cleanup(isc); in microchip_isc_probe()
593 v4l2_device_unregister(&isc->v4l2_dev); in microchip_isc_probe()
596 clk_disable_unprepare(isc->hclock); in microchip_isc_probe()
598 microchip_isc_clk_cleanup(isc); in microchip_isc_probe()
605 struct isc_device *isc = platform_get_drvdata(pdev); in microchip_isc_remove() local
607 pm_runtime_disable(&pdev->dev); in microchip_isc_remove()
609 isc_mc_cleanup(isc); in microchip_isc_remove()
611 microchip_isc_subdev_cleanup(isc); in microchip_isc_remove()
613 v4l2_device_unregister(&isc->v4l2_dev); in microchip_isc_remove()
615 clk_disable_unprepare(isc->ispck); in microchip_isc_remove()
616 clk_disable_unprepare(isc->hclock); in microchip_isc_remove()
618 microchip_isc_clk_cleanup(isc); in microchip_isc_remove()
623 struct isc_device *isc = dev_get_drvdata(dev); in isc_runtime_suspend() local
625 clk_disable_unprepare(isc->ispck); in isc_runtime_suspend()
626 clk_disable_unprepare(isc->hclock); in isc_runtime_suspend()
633 struct isc_device *isc = dev_get_drvdata(dev); in isc_runtime_resume() local
636 ret = clk_prepare_enable(isc->hclock); in isc_runtime_resume()
640 ret = clk_prepare_enable(isc->ispck); in isc_runtime_resume()
642 clk_disable_unprepare(isc->hclock); in isc_runtime_resume()
653 { .compatible = "atmel,sama5d2-isc" },
663 .name = "microchip-sama5d2-isc",
672 MODULE_DESCRIPTION("The V4L2 driver for Microchip-ISC");