vvcam_isp_driver_of.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. *
  25. *****************************************************************************
  26. *
  27. * The GPL License (GPL)
  28. *
  29. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  30. *
  31. * This program is free software; you can redistribute it and/or
  32. * modify it under the terms of the GNU General Public License
  33. * as published by the Free Software Foundation; either version 2
  34. * of the License, or (at your option) any later version.
  35. *
  36. * This program is distributed in the hope that it will be useful,
  37. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39. * GNU General Public License for more details.
  40. *
  41. * You should have received a copy of the GNU General Public License
  42. * along with this program;
  43. *
  44. *****************************************************************************
  45. *
  46. * Note: This software is released under dual MIT and GPL licenses. A
  47. * recipient may use this file under the terms of either the MIT license or
  48. * GPL License. If you wish to use only one license not the other, you can
  49. * indicate your decision by deleting one of the above license notices in your
  50. * version of this file.
  51. *
  52. *****************************************************************************/
  53. #include <asm/io.h>
  54. #include <linux/cdev.h>
  55. #include <linux/module.h>
  56. #include <linux/platform_device.h>
  57. #include <linux/delay.h>
  58. #include <linux/clk.h>
  59. #include <linux/io.h>
  60. #include <linux/mm.h>
  61. #include <linux/timer.h>
  62. #include <linux/kernel.h>
  63. #include <linux/init.h>
  64. #include <linux/workqueue.h>
  65. #include <linux/slab.h>
  66. #include <linux/proc_fs.h>
  67. #include <linux/debugfs.h>
  68. #include <linux/miscdevice.h>
  69. #include <linux/uaccess.h>
  70. #include <linux/interrupt.h>
  71. #include <linux/of_reserved_mem.h>
  72. #include <linux/pm_runtime.h>
  73. #include <linux/of.h>
  74. #include <linux/of_address.h>
  75. #include <linux/dma-mapping.h>
  76. #include <linux/dma-buf.h>
  77. #include "isp_ioctl.h"
  78. #include "mrv_all_regs.h"
  79. #include "isp_wdr.h"
  80. extern MrvAllRegister_t *all_regs;
  81. #define VIVCAM_ISP_NAME "vivisp_ry"
  82. #define VIVCAM_ISP_MAXCNT 1
  83. #define VIVCAM_ISP_IRQ_NUMBER 16
  84. struct vvcam_isp_driver_dev
  85. {
  86. struct cdev cdev;
  87. dev_t devt;
  88. struct class *class;
  89. struct mutex vvmutex;
  90. unsigned int device_idx;
  91. struct timer_list isp_timer;
  92. struct work_struct vvnative_wq;
  93. wait_queue_head_t irq_wait;
  94. int irq_num[2];
  95. void *private;
  96. struct clk *aclk;
  97. struct clk *hclk;
  98. struct clk *cclk;
  99. struct platform_device *pdev;
  100. };
  101. static unsigned int vvcam_isp_major = 0;
  102. static unsigned int vvcam_isp_minor = 0;
  103. static struct class *vvcam_isp_class;
  104. static unsigned int devise_register_index = 0;
  105. static bool isp_irq = false;
  106. static unsigned int vvnative_isp_poll(struct file * filp, poll_table *wait)
  107. {
  108. unsigned int mask = 0;
  109. struct vvcam_isp_driver_dev *pdriver_dev = filp->private_data;
  110. poll_wait(filp, &pdriver_dev->irq_wait, wait);
  111. //pr_info("poll isp_irq %d\n", isp_irq);
  112. if (isp_irq) {
  113. mask |= POLLIN |POLLRDNORM;
  114. isp_irq = false;
  115. }
  116. return mask;
  117. }
  118. static void vvnative_isp_work(struct work_struct *work)
  119. {
  120. /*Todo update those module that does not have shandow register*/
  121. struct vvcam_isp_driver_dev *pdriver_dev = container_of(work, struct vvcam_isp_driver_dev, vvnative_wq);
  122. struct isp_ic_dev * pisp_dev = pdriver_dev->private;
  123. //pr_info("%s enter \n", __func__);
  124. isp_irq = true;
  125. wake_up_interruptible(&pdriver_dev->irq_wait);
  126. if (pisp_dev->isp_mis & MRV_ISP_MIS_FRAME_MASK) {
  127. if (pisp_dev->wdr.changed) {
  128. pr_info("%s pisp_dev->wdr.changed %d\n", __func__,
  129. pisp_dev->wdr.changed);
  130. isp_s_wdr(pisp_dev);
  131. }
  132. if (pisp_dev->flt.changed) {
  133. pr_info("%s pisp_dev->flt.changed %d\n", __func__,
  134. pisp_dev->flt.changed);
  135. isp_s_flt(pisp_dev);
  136. }
  137. #ifndef ISP_CPROC_SHD_RY
  138. if (pisp_dev->cproc.changed) {
  139. pr_info("%s pisp_dev->cproc.changed %d\n", __func__,
  140. pisp_dev->cproc.changed);
  141. isp_s_cproc(pisp_dev);
  142. }
  143. #endif
  144. if (pisp_dev->gamma_out.changed) {
  145. pr_info("%s pisp_dev->gamma_out.changed %d\n", __func__,
  146. pisp_dev->gamma_out.changed);
  147. isp_s_gamma_out(pisp_dev);
  148. }
  149. }
  150. }
  151. static irqreturn_t vvcam_ry_isp_irq(int irq, void *dev_id)
  152. {
  153. struct vvcam_isp_driver_dev *pdriver_dev ;
  154. struct isp_ic_dev * pisp_dev;
  155. u64 isp_mis, mi_mis = 0;
  156. pdriver_dev = (struct vvcam_isp_driver_dev *)dev_id;
  157. pisp_dev = pdriver_dev->private;
  158. isp_mis = isp_read_reg(pisp_dev, REG_ADDR(isp_mis));
  159. if (isp_mis) {
  160. isp_mis_t mis_data;
  161. mis_data.irq_src = SRC_ISP_IRQ;
  162. mis_data.val = isp_mis;
  163. pisp_dev->isp_mis = isp_mis;
  164. isp_irq_write_circle_queue(&mis_data, &pisp_dev->circle_list);
  165. isp_write_reg(pisp_dev, REG_ADDR(isp_icr), isp_mis);
  166. if(isp_mis & MRV_ISP_MIS_ISP_OFF_MASK) {
  167. isp_write_reg(pisp_dev, REG_ADDR(isp_imsc), isp_read_reg(pisp_dev, REG_ADDR(isp_imsc))&(~MRV_ISP_MIS_ISP_OFF_MASK));
  168. }
  169. if (isp_mis & MRV_ISP_MIS_FLASH_ON_MASK)
  170. mi_mis |= 0x1;
  171. }
  172. if (isp_mis & MRV_ISP_MIS_VSM_END_MASK) { // MP_JDP_FRAME_END
  173. //isp_info("%s MRV_ISP_MIS_VSM_END_MASK >>> MP_JDP_FRAME_END_MASK...\n", __func__);
  174. mi_mis |= MP_JDP_FRAME_END_MASK;
  175. }
  176. if (isp_mis & MRV_ISP_MIS_SHUTTER_OFF_MASK) { // drop frame
  177. //isp_info("%s drop frame\n", __func__);
  178. mi_mis = 0x100000001;
  179. }
  180. if (mi_mis) {
  181. isp_mis_t mis_data;
  182. mis_data.irq_src = SRC_MI_IRQ;
  183. mis_data.val = mi_mis;
  184. isp_irq_write_circle_queue(&mis_data, &pisp_dev->circle_list);
  185. }
  186. if (isp_mis != 0 ||mi_mis != 0 ) {
  187. schedule_work(&pdriver_dev->vvnative_wq);
  188. } else {
  189. return IRQ_HANDLED; // return IRQ_NONE;
  190. }
  191. return IRQ_HANDLED;
  192. }
  193. static irqreturn_t vvcam_ry_mi_irq(int irq, void *dev_id)
  194. {
  195. struct vvcam_isp_driver_dev *pdriver_dev ;
  196. struct isp_ic_dev * pisp_dev;
  197. u32 mi_mis, mi_mis_addr, mi_icr_addr;
  198. #ifdef ISP_MIV2_RY
  199. u32 miv2_mis1, miv2_mis3;
  200. #endif
  201. #if defined(ISP_MI_PP_READ_RY) || defined (ISP_3DNR_V3) || defined (ISP_MI_PP_WRITE_RY) || defined (ISP_MI_HDR_RY)
  202. u32 miv2_mis2;
  203. #endif
  204. pdriver_dev = (struct vvcam_isp_driver_dev *)dev_id;
  205. pisp_dev = pdriver_dev->private;
  206. #ifdef ISP_MIV2_RY
  207. mi_icr_addr = REG_ADDR(miv2_icr);
  208. mi_mis_addr = REG_ADDR(miv2_mis);
  209. miv2_mis1 = isp_read_reg(pisp_dev, REG_ADDR(miv2_mis1));
  210. if (miv2_mis1) {
  211. /*pr_info("%s mi mis1 0x%08x\n", __func__, miv2_mis1);*/
  212. isp_write_reg(pisp_dev, REG_ADDR(miv2_icr1), miv2_mis1);
  213. }
  214. #ifdef POST_ISP_SDK_TEST
  215. miv2_mis3 = isp_read_reg(pisp_dev, REG_ADDR(miv2_mis3));
  216. if (miv2_mis3) {
  217. pr_info("%s mi mis3 0x%08x\n", __func__, miv2_mis3);
  218. isp_write_reg(pisp_dev, REG_ADDR(miv2_icr3), miv2_mis3);
  219. }
  220. #endif
  221. #elif defined(ISP_MIV1_RY)
  222. mi_icr_addr = REG_ADDR(mi_icr);
  223. mi_mis_addr = REG_ADDR(mi_mis);
  224. #endif
  225. /*mi_mis = isp_read_reg(pisp_dev, mi_mis_addr);*/
  226. #if defined(ISP_MI_PP_READ_RY) || defined (ISP_3DNR_V3) || defined (ISP_MI_PP_WRITE_RY) || defined (ISP_MI_HDR_RY)
  227. miv2_mis2 = isp_read_reg(pisp_dev, REG_ADDR(miv2_mis2));
  228. /*pr_info("%s isp mis 0x%08x, mi mis 0x%08x post mis 0x%08x\n", __func__, \
  229. isp_mis, mi_mis, miv2_mis2);*/
  230. #else
  231. /*pr_info("%s isp mis 0x%08x, mi mis 0x%08x\n", __func__, \
  232. isp_mis, mi_mis);*/
  233. #endif
  234. if (mi_mis) {
  235. isp_mis_t mis_data;
  236. mis_data.irq_src = SRC_MI_IRQ;
  237. mis_data.val = mi_mis;
  238. isp_irq_write_circle_queue(&mis_data, &pisp_dev->circle_list);
  239. isp_write_reg(pisp_dev, mi_icr_addr, mi_mis);
  240. }
  241. #ifdef ISP_MIV2_RY
  242. if (miv2_mis1) {
  243. isp_mis_t mis_data;
  244. mis_data.irq_src = SRC_MI1_IRQ;
  245. mis_data.val = mi_mis;
  246. isp_irq_write_circle_queue(&mis_data, &pisp_dev->circle_list);
  247. isp_write_reg(pisp_dev, mi_icr_addr, mi_mis);
  248. }
  249. #endif
  250. #if defined(ISP_MI_PP_READ_RY) || defined (ISP_3DNR_V3) || defined (ISP_MI_PP_WRITE_RY) || defined (ISP_MI_HDR_RY)
  251. if (miv2_mis2) {
  252. isp_mis_t mis_data;
  253. mis_data.irq_src = SRC_MI2_IRQ;
  254. mis_data.val = miv2_mis2;
  255. isp_irq_write_circle_queue(&mis_data, &pisp_dev->circle_list);
  256. isp_write_reg(pisp_dev, REG_ADDR(miv2_icr2), miv2_mis2);
  257. }
  258. #endif
  259. #if defined(ISP_MI_PP_READ_RY) || defined (ISP_3DNR_V3) || defined (ISP_MI_PP_WRITE_RY) || defined (ISP_MI_HDR_RY)
  260. if (mi_mis != 0 || miv2_mis2 != 0) {
  261. #else
  262. if (mi_mis != 0 ) {
  263. #endif
  264. schedule_work(&pdriver_dev->vvnative_wq);
  265. } else {
  266. return IRQ_HANDLED; // return IRQ_NONE;
  267. }
  268. return IRQ_HANDLED;
  269. }
  270. static int vvcam_isp_runtime_suspend(struct device *dev)
  271. {
  272. struct vvcam_isp_driver_dev *pdriver_dev = dev_get_drvdata(dev);
  273. clk_disable_unprepare(pdriver_dev->aclk);
  274. clk_disable_unprepare(pdriver_dev->hclk);
  275. clk_disable_unprepare(pdriver_dev->cclk);
  276. pr_info("ry %s\n", __func__);
  277. return 0;
  278. }
  279. static int vvcam_isp_runtime_resume(struct device *dev)
  280. {
  281. struct vvcam_isp_driver_dev *pdriver_dev = dev_get_drvdata(dev);
  282. int ret = 0;
  283. ret = clk_prepare_enable(pdriver_dev->cclk);
  284. if (ret < 0) {
  285. dev_err(dev, "could not prepare or enable core clock\n");
  286. //return ret;
  287. }
  288. ret = clk_prepare_enable(pdriver_dev->hclk);
  289. if (ret < 0) {
  290. dev_err(dev, "could not prepare or enable ahb clock\n");
  291. clk_disable_unprepare(pdriver_dev->cclk);
  292. //return ret;
  293. }
  294. ret = clk_prepare_enable(pdriver_dev->aclk);
  295. if (ret < 0) {
  296. dev_err(dev, "could not prepare or enable axi clock\n");
  297. clk_disable_unprepare(pdriver_dev->cclk);
  298. clk_disable_unprepare(pdriver_dev->hclk);
  299. //return ret;
  300. }
  301. pr_info("%s ry Enabled clock\n", __func__);
  302. return ret;
  303. }
  304. static const struct dev_pm_ops vvcam_isp_runtime_pm_ops = {
  305. SET_RUNTIME_PM_OPS(vvcam_isp_runtime_suspend, vvcam_isp_runtime_resume, NULL)
  306. };
  307. static int vvcam_isp_open(struct inode * inode, struct file * file)
  308. {
  309. int ret = 0;
  310. struct vvcam_isp_driver_dev *pdriver_dev;
  311. struct isp_ic_dev * pisp_dev;
  312. pdriver_dev = container_of(inode->i_cdev, struct vvcam_isp_driver_dev, cdev);
  313. file->private_data = pdriver_dev;
  314. pisp_dev = pdriver_dev->private;
  315. /*create circle queue*/
  316. isp_irq_create_circle_queue(&(pisp_dev->circle_list), QUEUE_NODE_COUNT);
  317. struct device *dev = &pdriver_dev->pdev->dev;
  318. if (pm_runtime_get_sync(dev)) {
  319. ret = vvcam_isp_runtime_resume(dev);
  320. if (ret)
  321. pr_err("fail to resume isp %s %d\n", __func__, __LINE__);
  322. }
  323. return 0;
  324. };
  325. static long vvcam_isp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  326. {
  327. long ret = 0;
  328. struct vvcam_isp_driver_dev *pdriver_dev;
  329. struct isp_ic_dev * pisp_dev;
  330. pdriver_dev = file->private_data;
  331. if (pdriver_dev == NULL)
  332. {
  333. pr_err("%s:file private is null point error\n", __func__);
  334. return -ENOMEM;
  335. }
  336. pisp_dev = pdriver_dev->private;
  337. //pr_info("%s:isp[%d] pdriver_dev =0x%px\n", __func__,pdriver_dev->device_idx,pdriver_dev);
  338. //pr_info("%s:pisp_dev =0x%px\n", __func__,pisp_dev);
  339. mutex_lock(&pdriver_dev->vvmutex);
  340. ret = isp_priv_ioctl(pisp_dev, cmd ,(void __user *)arg);
  341. mutex_unlock(&pdriver_dev->vvmutex);
  342. return ret;
  343. };
  344. static int vvcam_isp_release(struct inode * inode, struct file * file)
  345. {
  346. int ret = 0;
  347. struct vvcam_isp_driver_dev *pdriver_dev;
  348. struct isp_ic_dev *pisp_dev;
  349. if ((inode == NULL) || (file == NULL) ) {
  350. isp_info("%s: %dx\n", __func__, __LINE__);
  351. return 0;
  352. }
  353. pdriver_dev = container_of(inode->i_cdev, struct vvcam_isp_driver_dev, cdev);
  354. file->private_data = pdriver_dev;
  355. pisp_dev = pdriver_dev->private;
  356. pr_info("enter %s\n", __func__);
  357. isp_irq_destroy_circle_queue(&(pisp_dev->circle_list));
  358. struct device *dev = &pdriver_dev->pdev->dev;
  359. if (pisp_dev->ut_addr != NULL) {
  360. #define UT_USED_SIZE 0x01000000
  361. dma_free_coherent(dev, UT_USED_SIZE,
  362. pisp_dev->ut_addr, pisp_dev->ut_phy_addr);
  363. pisp_dev->ut_addr=NULL;
  364. }
  365. if (pisp_dev->ut_addr != NULL) {
  366. #define UT_USED_SIZE 0x01000000
  367. dma_free_coherent(dev, UT_USED_SIZE,
  368. pisp_dev->ut_addr, pisp_dev->ut_phy_addr);
  369. pisp_dev->ut_addr = NULL;
  370. }
  371. if (pm_runtime_put_sync(dev)) {
  372. pr_info("fail to resume isp %s %d\n", __func__, __LINE__);
  373. }
  374. return 0;
  375. };
  376. static int vvcam_isp_mmap(struct file *pFile, struct vm_area_struct *vma)
  377. {
  378. int ret = 0;
  379. ulong phy_base_addr = 0;
  380. unsigned long pfn_start = (phy_base_addr >> PAGE_SHIFT) + vma->vm_pgoff;
  381. unsigned long size = vma->vm_end - vma->vm_start;
  382. pr_info("phy: 0x%lx, size: 0x%lx\n", pfn_start << PAGE_SHIFT, size);
  383. vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  384. if (remap_pfn_range(vma, vma->vm_start,pfn_start,size, vma->vm_page_prot))
  385. {
  386. pr_err("-->%s: remap_pfn_range error!\n", __func__);
  387. return -EIO;
  388. }
  389. return ret;
  390. };
  391. static struct file_operations vvcam_isp_fops = {
  392. .owner = THIS_MODULE,
  393. .open = vvcam_isp_open,
  394. .release = vvcam_isp_release,
  395. .unlocked_ioctl = vvcam_isp_ioctl,
  396. .mmap = vvcam_isp_mmap,
  397. .poll = vvnative_isp_poll,
  398. };
  399. static int vvcam_isp_probe(struct platform_device *pdev)
  400. {
  401. int ret = 0;
  402. struct device_node *np;
  403. struct vvcam_isp_driver_dev *pdriver_dev;
  404. struct isp_ic_dev * pisp_dev;
  405. struct resource *mem;
  406. pr_info("enter %s\n", __func__);
  407. pdev->id = devise_register_index;
  408. if (pdev->id >= VIVCAM_ISP_MAXCNT)
  409. {
  410. pr_err("%s:pdev id is %d error\n", __func__,pdev->id);
  411. return -EINVAL;
  412. }
  413. pdriver_dev = devm_kzalloc(&pdev->dev,sizeof(struct vvcam_isp_driver_dev), GFP_KERNEL);
  414. if (pdriver_dev == NULL)
  415. {
  416. pr_err("%s:alloc struct vvcam_isp_driver_dev error\n", __func__);
  417. return -ENOMEM;
  418. }
  419. memset(pdriver_dev,0,sizeof(struct vvcam_isp_driver_dev ));
  420. pr_info("%s:isp[%d]: pdriver_dev =0x%px\n", __func__,pdev->id,pdriver_dev);
  421. pisp_dev = devm_kzalloc(&pdev->dev,sizeof(struct isp_ic_dev), GFP_KERNEL);
  422. if (pisp_dev == NULL)
  423. {
  424. pr_err("%s:alloc struct isp_ic_dev error\n", __func__);
  425. return -ENOMEM;
  426. }
  427. memset(pisp_dev,0,sizeof(struct isp_ic_dev ));
  428. pr_info("%s:isp[%d]: psensor_dev =0x%px\n", __func__,pdev->id,pisp_dev);
  429. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  430. pisp_dev->base = devm_ioremap_resource(&pdev->dev, mem);
  431. if (IS_ERR(pisp_dev->base))
  432. return PTR_ERR(pisp_dev->base);
  433. pr_info("%s:isp[%d]: pisp_dev->base=0x%px, phy_addr base=0x%llx\n", __func__,
  434. pdev->id, pisp_dev->base, mem->start);
  435. pisp_dev->reset = NULL;
  436. pisp_dev->device = &pdev->dev;
  437. pdriver_dev->private = pisp_dev;
  438. pdriver_dev->device_idx = pdev->id;
  439. mutex_init(&pdriver_dev->vvmutex);
  440. platform_set_drvdata(pdev, pdriver_dev);
  441. pdriver_dev->pdev = pdev;
  442. pdriver_dev->irq_num[0] = platform_get_irq(pdev, 0);
  443. if (pdriver_dev->irq_num[0] == 0) {
  444. pr_err("%s:isp[%d]: could not map IRQ\n", __func__, pdev->id);
  445. dev_err(&pdev->dev, "could not map IRQ.\n");
  446. return -ENXIO;
  447. }
  448. pr_info("%s:isp[%d]: pdriver_dev->irq_num[0]=%d\n", __func__, pdev->id, pdriver_dev->irq_num[0]);
  449. pdriver_dev->irq_num[1] = platform_get_irq(pdev, 1);
  450. if (pdriver_dev->irq_num[1] == 0) {
  451. pr_err("%s:isp[%d]: could not map IRQ\n", __func__, pdev->id);
  452. dev_err(&pdev->dev, "could not map IRQ.\n");
  453. return -ENXIO;
  454. }
  455. pr_info("%s:isp[%d]: pdriver_dev->irq_num[1]=%d\n", __func__, pdev->id, pdriver_dev->irq_num[1]);
  456. /*init work queue*/
  457. INIT_WORK(&pdriver_dev->vvnative_wq, vvnative_isp_work);
  458. ret = devm_request_irq(&pdev->dev, pdriver_dev->irq_num[0], vvcam_ry_isp_irq,
  459. IRQF_TRIGGER_RISING | IRQF_SHARED, "ISP_IRQ", (char *)pdriver_dev);
  460. if (ret) {
  461. pr_err("%s[%d]:request irq error!\n", __func__, __LINE__);
  462. return ret;
  463. }
  464. ret = devm_request_irq(&pdev->dev, pdriver_dev->irq_num[1], vvcam_ry_mi_irq,
  465. IRQF_TRIGGER_RISING, "MI_IRQ", (char *)pdriver_dev);
  466. if (ret) {
  467. pr_err("%s[%d]:request irq error!\n", __func__, __LINE__);
  468. return ret;
  469. }
  470. init_waitqueue_head(&pdriver_dev->irq_wait);
  471. /*parse clk info from dts*/
  472. pdriver_dev->aclk = devm_clk_get(&pdev->dev, "aclk");
  473. if (IS_ERR(pdriver_dev->aclk)) {
  474. dev_err(&pdev->dev, "failed to get aclk");
  475. //return -1;
  476. }
  477. pdriver_dev->hclk = devm_clk_get(&pdev->dev, "hclk");
  478. if (IS_ERR(pdriver_dev->hclk)) {
  479. dev_err(&pdev->dev, "failed to get hclk");
  480. //return -1;
  481. }
  482. pdriver_dev->cclk = devm_clk_get(&pdev->dev, "cclk");
  483. if (IS_ERR(pdriver_dev->aclk)) {
  484. dev_err(&pdev->dev, "failed to get core_clk");
  485. //return -1;
  486. }
  487. dev_err(&pdev->dev, "parse clk success");
  488. if ((devise_register_index == 0)) {
  489. int ret;
  490. if (vvcam_isp_major == 0) {
  491. ret = alloc_chrdev_region(&pdriver_dev->devt, 0, VIVCAM_ISP_MAXCNT, VIVCAM_ISP_NAME);
  492. if (ret != 0)
  493. {
  494. pr_err("%s:alloc_chrdev_region error\n", __func__);
  495. return ret;
  496. }
  497. vvcam_isp_major = MAJOR(pdriver_dev->devt);
  498. vvcam_isp_minor = MINOR(pdriver_dev->devt);
  499. }
  500. else
  501. {
  502. pdriver_dev->devt = MKDEV(vvcam_isp_major, vvcam_isp_minor);
  503. ret = register_chrdev_region(pdriver_dev->devt, VIVCAM_ISP_MAXCNT, VIVCAM_ISP_NAME);
  504. if (ret)
  505. {
  506. pr_err("%s:register_chrdev_region error\n", __func__);
  507. return ret;
  508. }
  509. }
  510. vvcam_isp_class = class_create(THIS_MODULE, VIVCAM_ISP_NAME);
  511. if (IS_ERR(vvcam_isp_class))
  512. {
  513. pr_err("%s[%d]:class_create error!\n", __func__, __LINE__);
  514. return -EINVAL;
  515. }
  516. }
  517. pdriver_dev->devt = MKDEV(vvcam_isp_major, vvcam_isp_minor + pdev->id);
  518. cdev_init(&pdriver_dev->cdev, &vvcam_isp_fops);
  519. ret = cdev_add(&pdriver_dev->cdev, pdriver_dev->devt, 1);
  520. if ( ret )
  521. {
  522. pr_err("%s[%d]:cdev_add error!\n", __func__, __LINE__);
  523. return ret;
  524. }
  525. pdriver_dev->class = vvcam_isp_class;
  526. device_create(pdriver_dev->class, NULL, pdriver_dev->devt,
  527. pdriver_dev, "%s%d", VIVCAM_ISP_NAME, pdev->id);
  528. struct device *dev = &pdriver_dev->pdev->dev;
  529. pm_runtime_enable(dev);
  530. ret = vvcam_isp_runtime_resume(dev);
  531. if (ret < 0) {
  532. dev_err(dev, "fail to resume isp ry\n");
  533. }
  534. vvcam_isp_runtime_suspend(dev);
  535. if (ret < 0) {
  536. dev_err(dev, "fail to suspend isp ry\n");
  537. }
  538. devise_register_index++;
  539. pr_info("exit %s\n", __func__);
  540. return ret;
  541. }
  542. static int vvcam_isp_remove(struct platform_device *pdev)
  543. {
  544. struct vvcam_isp_driver_dev *pdriver_dev;
  545. struct isp_ic_dev * pisp_dev;
  546. pr_info("enter %s\n", __func__);
  547. devise_register_index--;
  548. pdriver_dev = platform_get_drvdata(pdev);
  549. pisp_dev = pdriver_dev->private;
  550. if (pisp_dev->ut_addr != NULL) {
  551. #define UT_USED_SIZE 0x01000000
  552. dma_free_coherent(&pdev->dev, UT_USED_SIZE,
  553. pisp_dev->ut_addr, pisp_dev->ut_phy_addr);
  554. pisp_dev->ut_addr = NULL;
  555. }
  556. free_irq(pdriver_dev->irq_num[0], pdriver_dev);
  557. free_irq(pdriver_dev->irq_num[1], pdriver_dev);
  558. cdev_del(&pdriver_dev->cdev);
  559. device_destroy(pdriver_dev->class, pdriver_dev->devt);
  560. unregister_chrdev_region(pdriver_dev->devt, VIVCAM_ISP_MAXCNT);
  561. if (devise_register_index == 0)
  562. {
  563. class_destroy(pdriver_dev->class);
  564. }
  565. return 0;
  566. }
  567. static const struct of_device_id isp_of_match[] = {
  568. { .compatible = "thead,light-isp_ry", },
  569. { /* sentinel */ },
  570. };
  571. static struct platform_driver vvcam_isp_driver = {
  572. .probe = vvcam_isp_probe,
  573. .remove = vvcam_isp_remove,
  574. .driver = {
  575. .name = VIVCAM_ISP_NAME,
  576. .owner = THIS_MODULE,
  577. .of_match_table = of_match_ptr(isp_of_match),
  578. .pm = &vvcam_isp_runtime_pm_ops,
  579. }
  580. };
  581. static int __init vvcam_isp_init_module(void)
  582. {
  583. int ret = 0;
  584. pr_info("enter %s\n", __func__);
  585. ret = platform_driver_register(&vvcam_isp_driver);
  586. if (ret)
  587. {
  588. pr_err("register platform driver failed.\n");
  589. return ret;
  590. }
  591. return ret;
  592. }
  593. static void __exit vvcam_isp_exit_module(void)
  594. {
  595. pr_info("enter %s\n", __func__);
  596. platform_driver_unregister(&vvcam_isp_driver);
  597. }
  598. module_init(vvcam_isp_init_module);
  599. module_exit(vvcam_isp_exit_module);
  600. MODULE_DESCRIPTION("ISP");
  601. MODULE_LICENSE("GPL");