From 9af250afa1a6bb3f0e9934d0f9933aeaf5ba1a87 Mon Sep 17 00:00:00 2001 From: thead_admin Date: Wed, 4 Jan 2023 13:00:38 +0800 Subject: [PATCH] Linux_SDK_V1.0.3 --- vvcam/isp/ic_dev.h | 6 ++ vvcam/isp/isp_ioctl.c | 14 ++++- vvcam/isp/isp_ioctl.h | 3 + vvcam/native/isp/vvcam_isp_driver_of.c | 76 +++++++++++++++++++++----- 4 files changed, 84 insertions(+), 15 deletions(-) diff --git a/vvcam/isp/ic_dev.h b/vvcam/isp/ic_dev.h index 92f7382..59f387b 100755 --- a/vvcam/isp/ic_dev.h +++ b/vvcam/isp/ic_dev.h @@ -1012,6 +1012,9 @@ typedef struct pp_wr_line_entry_s { u32 buf_size; } pp_wr_line_entry_t; + +struct vvcam_isp_driver_dev; + struct isp_ic_dev { void __iomem *base; void __iomem *reset; @@ -1098,6 +1101,9 @@ struct isp_ic_dev { long long unsigned int ut_phy_addr; //for units test void *ut_addr; struct device *device; + int irq_num[2]; + int irq_is_request[2]; + struct vvcam_isp_driver_dev *isp_driver_dev; }; struct isp_extmem_info { diff --git a/vvcam/isp/isp_ioctl.c b/vvcam/isp/isp_ioctl.c index 881209f..fe944d9 100755 --- a/vvcam/isp/isp_ioctl.c +++ b/vvcam/isp/isp_ioctl.c @@ -2827,12 +2827,17 @@ static long isp_get_extmem(struct isp_ic_dev *dev, void __user *args) return ret; } +int vvcam_free_isp_irq(struct isp_ic_dev *dev); +int vvcam_request_isp_irq(struct isp_ic_dev *dev); + long isp_priv_ioctl(struct isp_ic_dev *dev, unsigned int cmd, void __user *args) { int ret = -1; - if (!dev) { + + if (!dev) { return ret; } + /*isp_info("[%s:%d]cmd 0x%08x\n", __func__, __LINE__, cmd);*/ switch (cmd) { case ISPIOC_RESET: @@ -3672,7 +3677,12 @@ long isp_priv_ioctl(struct isp_ic_dev *dev, unsigned int cmd, void __user *args) ret = 0; } break; - + case ISPIOC_FREE_IRQ: + ret = vvcam_free_isp_irq(dev); + break; + case ISPIOC_REQUEST_IRQ: + ret = vvcam_request_isp_irq(dev); + break; default: isp_err("unsupported command %d", cmd); break; diff --git a/vvcam/isp/isp_ioctl.h b/vvcam/isp/isp_ioctl.h index d3848ef..d424273 100755 --- a/vvcam/isp/isp_ioctl.h +++ b/vvcam/isp/isp_ioctl.h @@ -210,6 +210,9 @@ enum { ISPIOC_CFG_DMA_LINE_ENTRY = 0x196, ISPIOC_S_CROP = 0x197, ISPIOC_GET_FRAME_MASK_INFO_ADDR = 0x198, + ISPIOC_FREE_IRQ = 0x199, + ISPIOC_REQUEST_IRQ = 0x200, + }; #define ISP_GEN_CFG_UPDATE(dev) { \ diff --git a/vvcam/native/isp/vvcam_isp_driver_of.c b/vvcam/native/isp/vvcam_isp_driver_of.c index b8c2d23..48db1f4 100755 --- a/vvcam/native/isp/vvcam_isp_driver_of.c +++ b/vvcam/native/isp/vvcam_isp_driver_of.c @@ -106,7 +106,6 @@ struct vvcam_isp_driver_dev struct timer_list isp_timer; struct work_struct vvnative_wq; wait_queue_head_t irq_wait; - int irq_num[2]; void *private; struct clk *aclk; struct clk *hclk; @@ -182,11 +181,11 @@ static void vvnative_isp_work(struct work_struct *work) } if (pisp_dev->rgbgamma.data_changed) { //pr_info("%s pisp_dev->rgbgamma.data_changed %d\n", __func__, - //pisp_dev->rgbgamma.data_changed); + //pisp_dev->rgbgamma.data_changed); isp_s_rgbgamma(pisp_dev); } if (pisp_dev->rgbgamma.changed) { - //pr_info("%s pisp_dev->rgbgamma.changed %d\n", __func__,pisp_dev->rgbgamma.changed); + //pr_info("%s pisp_dev->rgbgamma.changed %d\n", __func__,pisp_dev->rgbgamma.changed); if (pisp_dev->rgbgamma.enable) { isp_enable_rgbgamma(pisp_dev); } else { @@ -401,6 +400,50 @@ static const struct dev_pm_ops vvcam_isp_runtime_pm_ops = { SET_RUNTIME_PM_OPS(vvcam_isp_runtime_suspend, vvcam_isp_runtime_resume, NULL) }; +int vvcam_free_isp_irq(struct isp_ic_dev *dev) +{ + if (dev->irq_is_request[1] == 0) { + return 0; + } + + free_irq(dev->irq_num[1], dev->isp_driver_dev); + dev->irq_is_request[1] = 0; + pr_info("%s isp free irq\n", __func__); + + return 0; +} + +int vvcam_request_isp_irq(struct isp_ic_dev *dev) +{ + if (dev->irq_is_request[1] == 1) { + return 0; + } + + uint32_t irq_mask0 = isp_read_reg(dev, REG_ADDR(miv2_imsc)); + uint32_t irq_mask1 = isp_read_reg(dev, REG_ADDR(miv2_imsc1)); + uint32_t irq_mask2 = isp_read_reg(dev, REG_ADDR(miv2_imsc2)); + + isp_write_reg(dev, REG_ADDR(miv2_icr), 0xfffffff); + isp_write_reg(dev, REG_ADDR(miv2_icr1), 0xfffffff); + isp_write_reg(dev, REG_ADDR(miv2_icr2), 0xfffffff); + + int ret = devm_request_irq(dev->device, dev->irq_num[1], vvcam_mi_irq, + IRQF_TRIGGER_RISING, "MI_IRQ", (char *)dev->isp_driver_dev); + if (ret) { + pr_err("%s, %d:request irq error, 0x%lx!\n", __func__, __LINE__, ret); + return ret; + } + + isp_write_reg(dev, REG_ADDR(miv2_imsc), irq_mask0); + isp_write_reg(dev, REG_ADDR(miv2_imsc1), irq_mask1); + isp_write_reg(dev, REG_ADDR(miv2_imsc2), irq_mask2); + + dev->irq_is_request[1] = 1; + pr_info("%s isp request irq\n", __func__); + + return ret; +} + static int vvcam_isp_open(struct inode * inode, struct file * file) { struct vvcam_isp_driver_dev *pdriver_dev; @@ -568,38 +611,42 @@ static int vvcam_isp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdriver_dev); pdriver_dev->pdev = pdev; - pdriver_dev->irq_num[0] = platform_get_irq(pdev, 0); - if (pdriver_dev->irq_num[0] == 0) { + pisp_dev->irq_num[0] = platform_get_irq(pdev, 0); + if (pisp_dev->irq_num[0] == 0) { pr_err("%s:isp[%d]: could not map IRQ\n", __func__, pdev->id); dev_err(&pdev->dev, "could not map IRQ.\n"); return -ENXIO; } - pr_info("%s:isp[%d]: pdriver_dev->irq_num[0]=%d\n", __func__, pdev->id, pdriver_dev->irq_num[0]); + pr_info("%s:isp[%d]: pisp_dev->irq_num[0]=%d\n", __func__, pdev->id, pisp_dev->irq_num[0]); - pdriver_dev->irq_num[1] = platform_get_irq(pdev, 1); - if (pdriver_dev->irq_num[1] == 0) { + pisp_dev->irq_num[1] = platform_get_irq(pdev, 1); + if (pisp_dev->irq_num[1] == 0) { pr_err("%s:isp[%d]: could not map IRQ\n", __func__, pdev->id); dev_err(&pdev->dev, "could not map IRQ.\n"); return -ENXIO; } - pr_info("%s:isp[%d]: pdriver_dev->irq_num[1]=%d\n", __func__, pdev->id, pdriver_dev->irq_num[1]); + pr_info("%s:isp[%d]: pisp_dev->irq_num[1]=%d\n", __func__, pdev->id, pisp_dev->irq_num[1]); /*init work queue*/ INIT_WORK(&pdriver_dev->vvnative_wq, vvnative_isp_work); - ret = devm_request_irq(&pdev->dev, pdriver_dev->irq_num[0], vvcam_isp_irq, + ret = devm_request_irq(&pdev->dev, pisp_dev->irq_num[0], vvcam_isp_irq, IRQF_TRIGGER_RISING | IRQF_SHARED, "ISP_IRQ", (char *)pdriver_dev); if (ret) { pr_err("%s[%d]:request irq error!\n", __func__, __LINE__); return ret; } + pisp_dev->irq_is_request[0] = 1; - ret = devm_request_irq(&pdev->dev, pdriver_dev->irq_num[1], vvcam_mi_irq, + pisp_dev->isp_driver_dev = pdriver_dev; + + ret = devm_request_irq(&pdev->dev, pisp_dev->irq_num[1], vvcam_mi_irq, IRQF_TRIGGER_RISING, "MI_IRQ", (char *)pdriver_dev); if (ret) { pr_err("%s[%d]:request irq error!\n", __func__, __LINE__); return ret; } + pisp_dev->irq_is_request[1] = 1; init_waitqueue_head(&pdriver_dev->irq_wait); @@ -710,8 +757,11 @@ static int vvcam_isp_remove(struct platform_device *pdev) pisp_dev->ut_addr =NULL; } - free_irq(pdriver_dev->irq_num[0], pdriver_dev); - free_irq(pdriver_dev->irq_num[1], pdriver_dev); + free_irq(pisp_dev->irq_num[0], pdriver_dev); + free_irq(pisp_dev->irq_num[1], pdriver_dev); + pisp_dev->irq_is_request[0] = 0; + pisp_dev->irq_is_request[1] = 0; + cdev_del(&pdriver_dev->cdev); device_destroy(pdriver_dev->class, pdriver_dev->devt);