arkn141_itu656_drv.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/mm.h>
  4. #include <linux/cdev.h>
  5. #include <linux/fs.h>
  6. #include <linux/errno.h>
  7. #include <linux/sched.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/delay.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/poll.h>
  12. #include <linux/gpio.h>
  13. #include <linux/spinlock.h>
  14. #include <linux/dma-mapping.h>
  15. #include "arkn141_itu656.h"
  16. static int get_one_finish_frame(struct ark_itu656in_context *context)
  17. {
  18. int i;
  19. char tmp;
  20. int id = -1;
  21. if (context->frame_finish_count > 0) {
  22. id = context->frame_finish[0];
  23. context->frame_finish_count -= 1;
  24. for (i = 0; i < context->frame_finish_count; i++) {
  25. tmp = context->frame_finish[1 + i];
  26. context->frame_finish[i] = tmp;
  27. }
  28. }
  29. return id;
  30. }
  31. static void dvr_init(struct ark_itu656in_context *context, struct itu656in_para *para)
  32. {
  33. int i;
  34. memcpy(&context->itu656in, para, sizeof(struct itu656in_para));
  35. for(i = 0; i < context->framebuf_num; i++){
  36. context->framebuf_phyaddr[i].yaddr = context->buffer_phyaddr + ITU656_FRAME_SIZE*i;
  37. if (context->itu656in.interlace)
  38. context->framebuf_phyaddr[i].uvaddr = context->framebuf_phyaddr[i].yaddr + \
  39. context->itu656in.width * context->itu656in.height * 2;
  40. else
  41. context->framebuf_phyaddr[i].uvaddr = context->framebuf_phyaddr[i].yaddr + \
  42. context->itu656in.width * context->itu656in.height;
  43. }
  44. }
  45. static long dvr_ioctl(struct file *filp,
  46. unsigned int cmd, unsigned long arg)
  47. {
  48. struct dvr_dev *dvr_dev = (struct dvr_dev *)filp->private_data;
  49. struct ark_itu656in_context *context;
  50. unsigned long error = 0;
  51. unsigned long flags;
  52. int i;
  53. if(!dvr_dev)
  54. {
  55. itu656_ERROR("error null device");
  56. return -ENXIO;
  57. }
  58. context = &dvr_dev->context;
  59. spin_lock_irqsave(&context->spin_lock, flags);
  60. switch (cmd)
  61. {
  62. case ARK_DVR_START:
  63. {
  64. itu656_INFO("camera startting.");
  65. if(dvr_dev->start)
  66. dvr_dev->start(context);
  67. break;
  68. }
  69. case ARK_DVR_STOP:
  70. {
  71. if(dvr_dev->stop)
  72. dvr_dev->stop(context);
  73. break;
  74. }
  75. case ARK_DVR_INIT:
  76. {
  77. struct itu656in_para para = {0};
  78. if(copy_from_user(&para, (void *)arg, sizeof(struct itu656in_para))){
  79. printk("%s: copy from user para error\n", __func__);
  80. error = -EFAULT;
  81. goto end;
  82. }
  83. dvr_init(context, &para);
  84. break;
  85. }
  86. case ARK_DVR_GET_BUFFER_INFO:
  87. {
  88. struct itu656_framebuf_para para;
  89. para.num = context->framebuf_num;
  90. memcpy(&para.buf, &context->framebuf_phyaddr, sizeof(context->framebuf_phyaddr));
  91. if(copy_to_user((void*)arg, &para, sizeof(struct itu656_framebuf_para))) {
  92. error = -EFAULT;
  93. printk("%s %d: copy from user para error\n", __func__, __LINE__);
  94. goto end;
  95. }
  96. break;
  97. }
  98. case ARK_DVR_GET_BUFFER_READY:
  99. {
  100. struct itu656_framebuf_addr buf = {0};
  101. int id;
  102. id = get_one_finish_frame(context);
  103. if(id < 0 || context->framebuf_status[id] != FRAMEBUF_STATUS_READY){
  104. error = -EFAULT;
  105. goto end;
  106. }
  107. buf = context->framebuf_phyaddr[id];
  108. if (copy_to_user((void*)arg, &buf, sizeof(buf))) {
  109. printk("%s %d: copy_to_user error\n",__FUNCTION__, __LINE__);
  110. error = -EFAULT;
  111. goto end;
  112. }
  113. break;
  114. }
  115. case ARK_DVR_SET_BUFFER_FREE:
  116. {
  117. struct itu656_framebuf_addr buf;
  118. if(copy_from_user(&buf, (void *)arg, sizeof(buf))){
  119. printk("%s %d: copy_from_user error\n",__FUNCTION__, __LINE__);
  120. error = -EFAULT;
  121. goto end;
  122. }
  123. for (i = 0; i < context->framebuf_num; i++) {
  124. if (buf.yaddr == context->framebuf_phyaddr[i].yaddr && buf.uvaddr == context->framebuf_phyaddr[i].uvaddr) {
  125. //if (context->framebuf_status[i] == FRAMEBUF_STATUS_READY)
  126. if (context->framebuf_status[i] == FRAMEBUF_STATUS_BUSY) {
  127. context->framebuf_status[i] = FRAMEBUF_STATUS_FREE;
  128. //printk(KERN_ALERT "### set free buf(0x%x) %s.\n", context->framebuf_phyaddr[i].yaddr, state?"success":"failed");
  129. } else {
  130. printk(KERN_ALERT "itu656 app free no-ready buf %d. status:%d\n", i, context->framebuf_status[i]);
  131. }
  132. break;
  133. }
  134. }
  135. break;
  136. }
  137. default:
  138. printk("%s: error cmd 0x%x\n", __func__, cmd);
  139. error = -EFAULT;
  140. goto end;
  141. }
  142. end:
  143. spin_unlock_irqrestore(&context->spin_lock, flags);
  144. return error;
  145. }
  146. static int dvr_open(struct inode *inode, struct file *filp)
  147. {
  148. struct dvr_dev * dvr_dev =
  149. container_of(inode->i_cdev, struct dvr_dev, cdev);
  150. if(dvr_dev)
  151. filp->private_data = dvr_dev;
  152. else
  153. itu656_ERROR("err open null cdev.");
  154. return 0;
  155. }
  156. static int dvr_fasync(int fd, struct file * filp, int on)
  157. {
  158. struct dvr_dev *dvr_dev = (struct dvr_dev*)filp->private_data;
  159. int retval;
  160. retval = fasync_helper(fd,filp,on,&dvr_dev->fasync_queue);
  161. if(retval < 0)
  162. return retval;
  163. return 0;
  164. }
  165. static int dvr_release(struct inode *inode, struct file *filp)
  166. {
  167. if(filp->f_flags & FASYNC)
  168. {
  169. /* remove this filp from the asynchronusly notified filp's */
  170. dvr_fasync(-1, filp, 0);
  171. }
  172. return 0;
  173. }
  174. static int dvr_read(struct file *filp, char __user *user, size_t size, loff_t *ppos)
  175. {
  176. struct dvr_dev *dvr_dev = (struct dvr_dev *)filp->private_data;
  177. struct ark_itu656in_context *context = &dvr_dev->context;
  178. unsigned int count = 0;
  179. unsigned long flags;
  180. //printk(KERN_ALERT "### camera read size: %d\n", size);
  181. if (size > context->framebuf_num)
  182. return -EINVAL;
  183. wait_event_interruptible(dvr_dev->frame_finish_waitq, context->frame_finish_count > 0);
  184. spin_lock_irqsave(&context->spin_lock, flags);
  185. #if 0 //test
  186. count = min(size, (size_t)context->frame_finish_count);
  187. #else
  188. count = min(1, (size_t)context->frame_finish_count);
  189. if(context->framebuf_status[context->frame_finish[0]] == FRAMEBUF_STATUS_READY)
  190. {
  191. context->framebuf_status[context->frame_finish[0]] = FRAMEBUF_STATUS_BUSY;
  192. }
  193. else
  194. {
  195. printk(KERN_ALERT "### arkn141 itu656 read error state:%hhd\n", context->framebuf_status[context->frame_finish[0]]);
  196. goto exit;
  197. }
  198. #endif
  199. if (copy_to_user(user, context->frame_finish, count)) {
  200. printk("%s %d: copy_to_user error\n",
  201. __FUNCTION__, __LINE__);
  202. spin_unlock_irqrestore(&context->spin_lock, flags);
  203. return -EFAULT;
  204. }
  205. exit:
  206. context->frame_finish_count -= count;
  207. if (context->frame_finish_count > 0) {
  208. int i;
  209. char tmp;
  210. for (i = 0; i < context->frame_finish_count; i++) {
  211. tmp = context->frame_finish[count + i];
  212. context->frame_finish[i] = tmp;
  213. }
  214. }
  215. spin_unlock_irqrestore(&context->spin_lock, flags);
  216. return count;
  217. }
  218. static unsigned int dvr_poll(struct file *filp, poll_table *wait)
  219. {
  220. struct dvr_dev *dvr_dev = (struct dvr_dev *)filp->private_data;
  221. struct ark_itu656in_context *context = &dvr_dev->context;
  222. unsigned int mask = 0;
  223. poll_wait(filp, &dvr_dev->frame_finish_waitq, wait);
  224. spin_lock_irq(&context->spin_lock);
  225. if (context->frame_finish_count > 0)
  226. mask |= POLLIN | POLLRDNORM;
  227. spin_unlock_irq(&context->spin_lock);
  228. return mask;
  229. }
  230. /* VFS methods */
  231. static struct file_operations dvr_fops = {
  232. .owner = THIS_MODULE,
  233. .open = dvr_open,
  234. .release = dvr_release,
  235. .unlocked_ioctl = dvr_ioctl,
  236. .fasync = dvr_fasync,
  237. .read = dvr_read,
  238. .poll = dvr_poll,
  239. };
  240. static int arkn141_dvr_probe(struct platform_device *pdev)
  241. {
  242. struct ark_itu656in_context *context;
  243. struct dvr_dev *dvr_dev;
  244. struct resource *res;
  245. void __iomem *regs;
  246. dev_t dev;
  247. u32 value;
  248. int ret = -1;
  249. int i;
  250. dvr_dev = devm_kzalloc(&pdev->dev, sizeof(struct dvr_dev), GFP_KERNEL);
  251. if (dvr_dev == NULL) {
  252. dev_err(&pdev->dev, "%s %d: failed to allocate memory\n",
  253. __FUNCTION__, __LINE__);
  254. return -ENOMEM;
  255. }
  256. //g_dvr_dev = dvr_dev;
  257. dvr_dev->driver_name = "dvr";
  258. dvr_dev->name = "ark_dvr";
  259. dvr_dev->major = DVR_MAJOR; /* if 0, let system choose */
  260. dvr_dev->minor_start = 0;
  261. dvr_dev->minor_num = 1; /* one dev only */
  262. dvr_dev->num = 1;
  263. dvr_dev->start = dvr_start;
  264. dvr_dev->stop = dvr_stop;
  265. dvr_dev->fasync_queue = NULL;
  266. dev = MKDEV(dvr_dev->major, dvr_dev->minor_start);
  267. ret= register_chrdev_region(dev, dvr_dev->num, (char *)dvr_dev->name);
  268. if (ret != 0){
  269. dev_err(&pdev->dev, "%s %d: register driver error\n",
  270. __FUNCTION__, __LINE__);
  271. goto err_driver_register;
  272. }
  273. cdev_init(&dvr_dev->cdev, &dvr_fops);
  274. ret= cdev_add(&dvr_dev->cdev, dev, dvr_dev->num);
  275. if (ret != 0){
  276. dev_err(&pdev->dev, "%s %d: cdev add error\n", __FUNCTION__, __LINE__);
  277. goto err_cdev_add;
  278. }
  279. #if ITU656_DEV_CLASS_CREATE
  280. dvr_dev->itu656_class = class_create(THIS_MODULE, "itu656_class");
  281. if(IS_ERR(dvr_dev->itu656_class)) {
  282. dev_err(&pdev->dev, "Err: failed in creating ark isp scale class.\n");
  283. dvr_dev->itu656_class = NULL;
  284. goto err_class_add;
  285. }
  286. dvr_dev->itu656_device = device_create(dvr_dev->itu656_class, NULL, dev, NULL, dvr_dev->driver_name);
  287. if (IS_ERR(dvr_dev->itu656_device)) {
  288. dev_err(&pdev->dev, "Err: failed in creating ark isp scale device.\n");
  289. dvr_dev->itu656_device = NULL;
  290. goto err_class_add;
  291. }
  292. #endif
  293. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  294. if (IS_ERR(res)) {
  295. ret = PTR_ERR(res);
  296. goto err_mem_res_req;
  297. }
  298. regs = devm_ioremap_resource(&pdev->dev, res);
  299. if (IS_ERR(regs)) {
  300. ret = PTR_ERR(regs);
  301. goto err_mem_res_req;
  302. }
  303. dvr_dev->context.itu656_base = regs;
  304. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  305. if (IS_ERR(res)) {
  306. ret = PTR_ERR(res);
  307. goto err_mem_res_req;
  308. }
  309. regs = ioremap(res->start, resource_size(res)); /* baseaddr conflict */
  310. if (IS_ERR(regs)) {
  311. ret = PTR_ERR(regs);
  312. goto err_mem_res_req;
  313. }
  314. dvr_dev->context.sys_base = regs;
  315. res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
  316. if (IS_ERR(res)) {
  317. ret = PTR_ERR(res);
  318. goto err_mem_res1_req;
  319. }
  320. regs = ioremap(res->start, resource_size(res)); /* baseaddr conflict */
  321. if (IS_ERR(regs)) {
  322. ret = PTR_ERR(regs);
  323. goto err_mem_res1_req;
  324. }
  325. dvr_dev->context.deinterlace_base = regs;
  326. dvr_dev->context.itu656_irq = platform_get_irq(pdev, 0);
  327. if (dvr_dev->context.itu656_irq < 0) {
  328. dev_err(&pdev->dev, "%s %d: can't get itu656_irq resource.\n", __FUNCTION__, __LINE__);
  329. goto err_irq;
  330. }
  331. ret = devm_request_irq(
  332. &pdev->dev,
  333. dvr_dev->context.itu656_irq,
  334. ark_itu656_int_handler,
  335. IRQF_SHARED,
  336. "dvr_itu656",
  337. dvr_dev
  338. );
  339. if(ret){
  340. dev_err(&pdev->dev, "%s %d: can't get assigned itu656_irq %d, error %d\n",
  341. __FUNCTION__, __LINE__, dvr_dev->context.itu656_irq, ret);
  342. goto err_irq;
  343. }
  344. dvr_dev->context.deinterlace_irq = platform_get_irq(pdev, 1);
  345. if (dvr_dev->context.deinterlace_irq < 0) {
  346. dev_err(&pdev->dev, "%s %d: can't get deinterlace_irq resource.\n", __FUNCTION__, __LINE__);
  347. goto err_irq;
  348. }
  349. ret = devm_request_irq(
  350. &pdev->dev,
  351. dvr_dev->context.deinterlace_irq,
  352. ark_deinterlace_int_handler,
  353. IRQF_SHARED,
  354. "dvr_deinterlace",
  355. dvr_dev
  356. );
  357. if(ret){
  358. dev_err(&pdev->dev, "%s %d: can't get assigned deinterlace_irq %d, error %d\n",
  359. __FUNCTION__, __LINE__, dvr_dev->context.deinterlace_irq, ret);
  360. goto err_irq;
  361. }
  362. //init context
  363. context = &dvr_dev->context;
  364. context->work_status = 0;
  365. context->deinter_status = 0;
  366. context->frame_finish_count = 0;
  367. context->framebuf_num = ITU656_FRAME_NUM;
  368. #ifdef ITU656_STATIC_FRAME_SIZE
  369. context->buffer_size = ITU656_FRAME_SIZE*ITU656_FRAME_NUM;// + 0x200000; //extra 2M memory for write overflow bug
  370. #else
  371. context->buffer_size = ITU656_FRAME_SIZE*ITU656_FRAME_NUM + 0x200000; //extra 2M memory for write overflow bug
  372. #endif
  373. #if 0
  374. context->buffer_virtaddr = (void *)__get_free_pages(GFP_KERNEL, get_order(context->buffer_size));
  375. if (!context->buffer_virtaddr){
  376. dev_err(&pdev->dev, "%s %d: get buffer failed.\n", __FUNCTION__, __LINE__);
  377. ret = -ENOMEM;
  378. goto err_buffer;
  379. }
  380. context->buffer_phyaddr = virt_to_phys(context->buffer_virtaddr);
  381. #else
  382. context->buffer_virtaddr = dma_alloc_wc(&pdev->dev, context->buffer_size,
  383. (dma_addr_t *)&context->buffer_phyaddr,
  384. GFP_KERNEL);
  385. if (!context->buffer_virtaddr){
  386. dev_err(&pdev->dev, "%s %d: get buffer failed.\n", __FUNCTION__, __LINE__);
  387. ret = -ENOMEM;
  388. goto err_buffer;
  389. }
  390. #endif
  391. for(i = 0; i < context->framebuf_num; i++){
  392. context->framebuf_phyaddr[i].yaddr = context->buffer_phyaddr + ITU656_FRAME_SIZE*i;
  393. }
  394. if(!of_property_read_u32(pdev->dev.of_node, "channel", &value)) {
  395. if(value >= ITU656_CH0 && value <= ITU656_CH0_CH1)
  396. context->itu_channel = value;
  397. }
  398. INIT_LIST_HEAD(&context->framebuf_push_list);
  399. spin_lock_init(&context->spin_lock);
  400. init_waitqueue_head(&dvr_dev->frame_finish_waitq);
  401. dvr_dev->context.dev = &pdev->dev;
  402. platform_set_drvdata(pdev, dvr_dev);
  403. timer_setup(&dvr_dev->timer, dither_timeout_timer, 0);
  404. printk("arkn141 itu656 probe success\n");
  405. return 0;
  406. err_buffer:
  407. err_irq:
  408. iounmap(dvr_dev->context.deinterlace_base);
  409. err_mem_res1_req:
  410. iounmap(dvr_dev->context.sys_base);
  411. err_mem_res_req:
  412. #if ITU656_DEV_CLASS_CREATE
  413. if (dvr_dev->itu656_class) {
  414. if (dvr_dev->itu656_device) {
  415. device_destroy(dvr_dev->itu656_class, dev);
  416. }
  417. class_destroy(dvr_dev->itu656_class);
  418. }
  419. #endif
  420. err_class_add:
  421. cdev_del(&dvr_dev->cdev);
  422. err_cdev_add:
  423. unregister_chrdev_region(dev, dvr_dev->num);
  424. err_driver_register:
  425. printk(KERN_ALERT "arkn141 itu656 probe failed\n");
  426. return ret;
  427. }
  428. static int arkn141_dvr_remove(struct platform_device *pdev)
  429. {
  430. dev_t dev;
  431. struct dvr_dev *dvr_dev;
  432. dvr_dev = platform_get_drvdata(pdev);
  433. if (dvr_dev == NULL)
  434. return -ENODEV;
  435. iounmap(dvr_dev->context.deinterlace_base);
  436. iounmap(dvr_dev->context.sys_base);
  437. dev = MKDEV(dvr_dev->major, dvr_dev->minor_start);
  438. #if ITU656_DEV_CLASS_CREATE
  439. if (dvr_dev->itu656_class) {
  440. if (dvr_dev->itu656_device) {
  441. device_destroy(dvr_dev->itu656_class, dev);
  442. }
  443. class_destroy(dvr_dev->itu656_class);
  444. }
  445. #endif
  446. cdev_del(&dvr_dev->cdev);
  447. unregister_chrdev_region(dev, dvr_dev->num);
  448. #if 0
  449. free_pages((unsigned long)dvr_dev->context.buffer_virtaddr, get_order(dvr_dev->context.buffer_size));
  450. #else
  451. if(dvr_dev->context.buffer_virtaddr)
  452. dma_free_wc(&pdev->dev, dvr_dev->context.buffer_size, dvr_dev->context.buffer_virtaddr, dvr_dev->context.buffer_phyaddr);
  453. #endif
  454. return 0;
  455. }
  456. static const struct of_device_id arkn141_itu656_of_match[] = {
  457. { .compatible = "arkmicro,arkn141-itu656", },
  458. { }
  459. };
  460. MODULE_DEVICE_TABLE(of, arkn141_itu656_of_match);
  461. static struct platform_driver arkn141_itu656_driver = {
  462. .driver = {
  463. .name = "arkn141-itu656",
  464. .of_match_table = of_match_ptr(arkn141_itu656_of_match),
  465. },
  466. .probe = arkn141_dvr_probe,
  467. .remove = arkn141_dvr_remove,
  468. };
  469. module_platform_driver(arkn141_itu656_driver);
  470. MODULE_AUTHOR("Leo");
  471. MODULE_DESCRIPTION("ArkMicro arkn141 Itu656 Driver");
  472. MODULE_LICENSE("GPL v2");