vpfe_mc_capture.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /*
  2. * Copyright (C) 2012 Texas Instruments Inc
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. *
  17. * Contributors:
  18. * Manjunath Hadli <manjunath.hadli@ti.com>
  19. * Prabhakar Lad <prabhakar.lad@ti.com>
  20. *
  21. *
  22. * Driver name : VPFE Capture driver
  23. * VPFE Capture driver allows applications to capture and stream video
  24. * frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
  25. * TVP5146 or Raw Bayer RGB image data from an image sensor
  26. * such as Microns' MT9T001, MT9T031 etc.
  27. *
  28. * These SoCs have, in common, a Video Processing Subsystem (VPSS) that
  29. * consists of a Video Processing Front End (VPFE) for capturing
  30. * video/raw image data and Video Processing Back End (VPBE) for displaying
  31. * YUV data through an in-built analog encoder or Digital LCD port. This
  32. * driver is for capture through VPFE. A typical EVM using these SoCs have
  33. * following high level configuration.
  34. *
  35. * decoder(TVP5146/ YUV/
  36. * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
  37. * data input | |
  38. * V |
  39. * SDRAM |
  40. * V
  41. * Image Processor
  42. * |
  43. * V
  44. * SDRAM
  45. * The data flow happens from a decoder connected to the VPFE over a
  46. * YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
  47. * and to the input of VPFE through an optional MUX (if more inputs are
  48. * to be interfaced on the EVM). The input data is first passed through
  49. * CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
  50. * does very little or no processing on YUV data and does pre-process Raw
  51. * Bayer RGB data through modules such as Defect Pixel Correction (DFC)
  52. * Color Space Conversion (CSC), data gain/offset etc. After this, data
  53. * can be written to SDRAM or can be connected to the image processing
  54. * block such as IPIPE (on DM355/DM365 only).
  55. *
  56. * Features supported
  57. * - MMAP IO
  58. * - USERPTR IO
  59. * - Capture using TVP5146 over BT.656
  60. * - Support for interfacing decoders using sub device model
  61. * - Work with DM365 or DM355 or DM6446 CCDC to do Raw Bayer
  62. * RGB/YUV data capture to SDRAM.
  63. * - Chaining of Image Processor
  64. * - SINGLE-SHOT mode
  65. */
  66. #include <linux/interrupt.h>
  67. #include <linux/module.h>
  68. #include <linux/slab.h>
  69. #include "vpfe.h"
  70. #include "vpfe_mc_capture.h"
  71. static bool debug;
  72. static bool interface;
  73. module_param(interface, bool, S_IRUGO);
  74. module_param(debug, bool, 0644);
  75. /**
  76. * VPFE capture can be used for capturing video such as from TVP5146 or TVP7002
  77. * and for capture raw bayer data from camera sensors such as mt9p031. At this
  78. * point there is problem in co-existence of mt9p031 and tvp5146 due to i2c
  79. * address collision. So set the variable below from bootargs to do either video
  80. * capture or camera capture.
  81. * interface = 0 - video capture (from TVP514x or such),
  82. * interface = 1 - Camera capture (from mt9p031 or such)
  83. * Re-visit this when we fix the co-existence issue
  84. */
  85. MODULE_PARM_DESC(interface, "interface 0-1 (default:0)");
  86. MODULE_PARM_DESC(debug, "Debug level 0-1");
  87. MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
  88. MODULE_LICENSE("GPL");
  89. MODULE_AUTHOR("Texas Instruments");
  90. /* map mbus_fmt to pixelformat */
  91. void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
  92. struct v4l2_pix_format *pix)
  93. {
  94. switch (mbus->code) {
  95. case MEDIA_BUS_FMT_UYVY8_2X8:
  96. pix->pixelformat = V4L2_PIX_FMT_UYVY;
  97. pix->bytesperline = pix->width * 2;
  98. break;
  99. case MEDIA_BUS_FMT_YUYV8_2X8:
  100. pix->pixelformat = V4L2_PIX_FMT_YUYV;
  101. pix->bytesperline = pix->width * 2;
  102. break;
  103. case MEDIA_BUS_FMT_YUYV10_1X20:
  104. pix->pixelformat = V4L2_PIX_FMT_UYVY;
  105. pix->bytesperline = pix->width * 2;
  106. break;
  107. case MEDIA_BUS_FMT_SGRBG12_1X12:
  108. pix->pixelformat = V4L2_PIX_FMT_SBGGR16;
  109. pix->bytesperline = pix->width * 2;
  110. break;
  111. case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
  112. pix->pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8;
  113. pix->bytesperline = pix->width;
  114. break;
  115. case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
  116. pix->pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8;
  117. pix->bytesperline = pix->width;
  118. break;
  119. case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
  120. pix->pixelformat = V4L2_PIX_FMT_NV12;
  121. pix->bytesperline = pix->width;
  122. break;
  123. case MEDIA_BUS_FMT_Y8_1X8:
  124. pix->pixelformat = V4L2_PIX_FMT_GREY;
  125. pix->bytesperline = pix->width;
  126. break;
  127. case MEDIA_BUS_FMT_UV8_1X8:
  128. pix->pixelformat = V4L2_PIX_FMT_UV8;
  129. pix->bytesperline = pix->width;
  130. break;
  131. default:
  132. pr_err("Invalid mbus code set\n");
  133. }
  134. /* pitch should be 32 bytes aligned */
  135. pix->bytesperline = ALIGN(pix->bytesperline, 32);
  136. if (pix->pixelformat == V4L2_PIX_FMT_NV12)
  137. pix->sizeimage = pix->bytesperline * pix->height +
  138. ((pix->bytesperline * pix->height) >> 1);
  139. else
  140. pix->sizeimage = pix->bytesperline * pix->height;
  141. }
  142. /* ISR for VINT0*/
  143. static irqreturn_t vpfe_isr(int irq, void *dev_id)
  144. {
  145. struct vpfe_device *vpfe_dev = dev_id;
  146. v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_isr\n");
  147. vpfe_isif_buffer_isr(&vpfe_dev->vpfe_isif);
  148. vpfe_resizer_buffer_isr(&vpfe_dev->vpfe_resizer);
  149. return IRQ_HANDLED;
  150. }
  151. /* vpfe_vdint1_isr() - isr handler for VINT1 interrupt */
  152. static irqreturn_t vpfe_vdint1_isr(int irq, void *dev_id)
  153. {
  154. struct vpfe_device *vpfe_dev = dev_id;
  155. v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_vdint1_isr\n");
  156. vpfe_isif_vidint1_isr(&vpfe_dev->vpfe_isif);
  157. return IRQ_HANDLED;
  158. }
  159. /* vpfe_imp_dma_isr() - ISR for ipipe dma completion */
  160. static irqreturn_t vpfe_imp_dma_isr(int irq, void *dev_id)
  161. {
  162. struct vpfe_device *vpfe_dev = dev_id;
  163. v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_imp_dma_isr\n");
  164. vpfe_ipipeif_ss_buffer_isr(&vpfe_dev->vpfe_ipipeif);
  165. vpfe_resizer_dma_isr(&vpfe_dev->vpfe_resizer);
  166. return IRQ_HANDLED;
  167. }
  168. /*
  169. * vpfe_disable_clock() - Disable clocks for vpfe capture driver
  170. * @vpfe_dev - ptr to vpfe capture device
  171. *
  172. * Disables clocks defined in vpfe configuration. The function
  173. * assumes that at least one clock is to be defined which is
  174. * true as of now.
  175. */
  176. static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
  177. {
  178. struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
  179. int i;
  180. for (i = 0; i < vpfe_cfg->num_clocks; i++) {
  181. clk_disable_unprepare(vpfe_dev->clks[i]);
  182. clk_put(vpfe_dev->clks[i]);
  183. }
  184. kzfree(vpfe_dev->clks);
  185. v4l2_info(vpfe_dev->pdev->driver, "vpfe capture clocks disabled\n");
  186. }
  187. /*
  188. * vpfe_enable_clock() - Enable clocks for vpfe capture driver
  189. * @vpfe_dev - ptr to vpfe capture device
  190. *
  191. * Enables clocks defined in vpfe configuration. The function
  192. * assumes that at least one clock is to be defined which is
  193. * true as of now.
  194. */
  195. static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
  196. {
  197. struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
  198. int ret = -EFAULT;
  199. int i;
  200. if (!vpfe_cfg->num_clocks)
  201. return 0;
  202. vpfe_dev->clks = kcalloc(vpfe_cfg->num_clocks,
  203. sizeof(struct clock *), GFP_KERNEL);
  204. if (vpfe_dev->clks == NULL)
  205. return -ENOMEM;
  206. for (i = 0; i < vpfe_cfg->num_clocks; i++) {
  207. if (vpfe_cfg->clocks[i] == NULL) {
  208. v4l2_err(vpfe_dev->pdev->driver,
  209. "clock %s is not defined in vpfe config\n",
  210. vpfe_cfg->clocks[i]);
  211. goto out;
  212. }
  213. vpfe_dev->clks[i] =
  214. clk_get(vpfe_dev->pdev, vpfe_cfg->clocks[i]);
  215. if (IS_ERR(vpfe_dev->clks[i])) {
  216. v4l2_err(vpfe_dev->pdev->driver,
  217. "Failed to get clock %s\n",
  218. vpfe_cfg->clocks[i]);
  219. goto out;
  220. }
  221. if (clk_prepare_enable(vpfe_dev->clks[i])) {
  222. v4l2_err(vpfe_dev->pdev->driver,
  223. "vpfe clock %s not enabled\n",
  224. vpfe_cfg->clocks[i]);
  225. goto out;
  226. }
  227. v4l2_info(vpfe_dev->pdev->driver, "vpss clock %s enabled",
  228. vpfe_cfg->clocks[i]);
  229. }
  230. return 0;
  231. out:
  232. for (i = 0; i < vpfe_cfg->num_clocks; i++)
  233. if (!IS_ERR(vpfe_dev->clks[i])) {
  234. clk_disable_unprepare(vpfe_dev->clks[i]);
  235. clk_put(vpfe_dev->clks[i]);
  236. }
  237. v4l2_err(vpfe_dev->pdev->driver, "Failed to enable clocks\n");
  238. kzfree(vpfe_dev->clks);
  239. return ret;
  240. }
  241. /*
  242. * vpfe_detach_irq() - Detach IRQs for vpfe capture driver
  243. * @vpfe_dev - ptr to vpfe capture device
  244. *
  245. * Detach all IRQs defined in vpfe configuration.
  246. */
  247. static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
  248. {
  249. free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
  250. free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
  251. free_irq(vpfe_dev->imp_dma_irq, vpfe_dev);
  252. }
  253. /*
  254. * vpfe_attach_irq() - Attach IRQs for vpfe capture driver
  255. * @vpfe_dev - ptr to vpfe capture device
  256. *
  257. * Attach all IRQs defined in vpfe configuration.
  258. */
  259. static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
  260. {
  261. int ret;
  262. ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
  263. "vpfe_capture0", vpfe_dev);
  264. if (ret < 0) {
  265. v4l2_err(&vpfe_dev->v4l2_dev,
  266. "Error: requesting VINT0 interrupt\n");
  267. return ret;
  268. }
  269. ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, 0,
  270. "vpfe_capture1", vpfe_dev);
  271. if (ret < 0) {
  272. v4l2_err(&vpfe_dev->v4l2_dev,
  273. "Error: requesting VINT1 interrupt\n");
  274. free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
  275. return ret;
  276. }
  277. ret = request_irq(vpfe_dev->imp_dma_irq, vpfe_imp_dma_isr,
  278. 0, "Imp_Sdram_Irq", vpfe_dev);
  279. if (ret < 0) {
  280. v4l2_err(&vpfe_dev->v4l2_dev,
  281. "Error: requesting IMP IRQ interrupt\n");
  282. free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
  283. free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
  284. return ret;
  285. }
  286. return 0;
  287. }
  288. /*
  289. * register_i2c_devices() - register all i2c v4l2 subdevs
  290. * @vpfe_dev - ptr to vpfe capture device
  291. *
  292. * register all i2c v4l2 subdevs
  293. */
  294. static int register_i2c_devices(struct vpfe_device *vpfe_dev)
  295. {
  296. struct vpfe_ext_subdev_info *sdinfo;
  297. struct vpfe_config *vpfe_cfg;
  298. struct i2c_adapter *i2c_adap;
  299. unsigned int num_subdevs;
  300. int ret;
  301. int i;
  302. int k;
  303. vpfe_cfg = vpfe_dev->cfg;
  304. i2c_adap = i2c_get_adapter(1);
  305. num_subdevs = vpfe_cfg->num_subdevs;
  306. vpfe_dev->sd =
  307. kcalloc(num_subdevs, sizeof(struct v4l2_subdev *),
  308. GFP_KERNEL);
  309. if (vpfe_dev->sd == NULL)
  310. return -ENOMEM;
  311. for (i = 0, k = 0; i < num_subdevs; i++) {
  312. sdinfo = &vpfe_cfg->sub_devs[i];
  313. /*
  314. * register subdevices based on interface setting. Currently
  315. * tvp5146 and mt9p031 cannot co-exists due to i2c address
  316. * conflicts. So only one of them is registered. Re-visit this
  317. * once we have support for i2c switch handling in i2c driver
  318. * framework
  319. */
  320. if (interface == sdinfo->is_camera) {
  321. /* setup input path */
  322. if (vpfe_cfg->setup_input &&
  323. vpfe_cfg->setup_input(sdinfo->grp_id) < 0) {
  324. ret = -EFAULT;
  325. v4l2_info(&vpfe_dev->v4l2_dev,
  326. "could not setup input for %s\n",
  327. sdinfo->module_name);
  328. goto probe_sd_out;
  329. }
  330. /* Load up the subdevice */
  331. vpfe_dev->sd[k] =
  332. v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
  333. i2c_adap, &sdinfo->board_info,
  334. NULL);
  335. if (vpfe_dev->sd[k]) {
  336. v4l2_info(&vpfe_dev->v4l2_dev,
  337. "v4l2 sub device %s registered\n",
  338. sdinfo->module_name);
  339. vpfe_dev->sd[k]->grp_id = sdinfo->grp_id;
  340. k++;
  341. sdinfo->registered = 1;
  342. }
  343. } else {
  344. v4l2_info(&vpfe_dev->v4l2_dev,
  345. "v4l2 sub device %s is not registered\n",
  346. sdinfo->module_name);
  347. }
  348. }
  349. vpfe_dev->num_ext_subdevs = k;
  350. return 0;
  351. probe_sd_out:
  352. kzfree(vpfe_dev->sd);
  353. return ret;
  354. }
  355. /*
  356. * vpfe_register_entities() - register all v4l2 subdevs and media entities
  357. * @vpfe_dev - ptr to vpfe capture device
  358. *
  359. * register all v4l2 subdevs, media entities, and creates links
  360. * between entities
  361. */
  362. static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
  363. {
  364. unsigned int flags = 0;
  365. int ret;
  366. int i;
  367. /* register i2c devices first */
  368. ret = register_i2c_devices(vpfe_dev);
  369. if (ret)
  370. return ret;
  371. /* register rest of the sub-devs */
  372. ret = vpfe_isif_register_entities(&vpfe_dev->vpfe_isif,
  373. &vpfe_dev->v4l2_dev);
  374. if (ret)
  375. return ret;
  376. ret = vpfe_ipipeif_register_entities(&vpfe_dev->vpfe_ipipeif,
  377. &vpfe_dev->v4l2_dev);
  378. if (ret)
  379. goto out_isif_register;
  380. ret = vpfe_ipipe_register_entities(&vpfe_dev->vpfe_ipipe,
  381. &vpfe_dev->v4l2_dev);
  382. if (ret)
  383. goto out_ipipeif_register;
  384. ret = vpfe_resizer_register_entities(&vpfe_dev->vpfe_resizer,
  385. &vpfe_dev->v4l2_dev);
  386. if (ret)
  387. goto out_ipipe_register;
  388. /* create links now, starting with external(i2c) entities */
  389. for (i = 0; i < vpfe_dev->num_ext_subdevs; i++)
  390. /* if entity has no pads (ex: amplifier),
  391. cant establish link */
  392. if (vpfe_dev->sd[i]->entity.num_pads) {
  393. ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
  394. 0, &vpfe_dev->vpfe_isif.subdev.entity,
  395. 0, flags);
  396. if (ret < 0)
  397. goto out_resizer_register;
  398. }
  399. ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
  400. &vpfe_dev->vpfe_ipipeif.subdev.entity,
  401. 0, flags);
  402. if (ret < 0)
  403. goto out_resizer_register;
  404. ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
  405. &vpfe_dev->vpfe_ipipe.subdev.entity,
  406. 0, flags);
  407. if (ret < 0)
  408. goto out_resizer_register;
  409. ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
  410. 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
  411. 0, flags);
  412. if (ret < 0)
  413. goto out_resizer_register;
  414. ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
  415. &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
  416. 0, flags);
  417. if (ret < 0)
  418. goto out_resizer_register;
  419. ret = v4l2_device_register_subdev_nodes(&vpfe_dev->v4l2_dev);
  420. if (ret < 0)
  421. goto out_resizer_register;
  422. return 0;
  423. out_resizer_register:
  424. vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
  425. out_ipipe_register:
  426. vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
  427. out_ipipeif_register:
  428. vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
  429. out_isif_register:
  430. vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
  431. return ret;
  432. }
  433. /*
  434. * vpfe_unregister_entities() - unregister all v4l2 subdevs and media entities
  435. * @vpfe_dev - ptr to vpfe capture device
  436. *
  437. * unregister all v4l2 subdevs and media entities
  438. */
  439. static void vpfe_unregister_entities(struct vpfe_device *vpfe_dev)
  440. {
  441. vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
  442. vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
  443. vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
  444. vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
  445. }
  446. /*
  447. * vpfe_cleanup_modules() - cleanup all non-i2c v4l2 subdevs
  448. * @vpfe_dev - ptr to vpfe capture device
  449. * @pdev - pointer to platform device
  450. *
  451. * cleanup all v4l2 subdevs
  452. */
  453. static void vpfe_cleanup_modules(struct vpfe_device *vpfe_dev,
  454. struct platform_device *pdev)
  455. {
  456. vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
  457. vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
  458. vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
  459. vpfe_resizer_cleanup(&vpfe_dev->vpfe_resizer, pdev);
  460. }
  461. /*
  462. * vpfe_initialize_modules() - initialize all non-i2c v4l2 subdevs
  463. * @vpfe_dev - ptr to vpfe capture device
  464. * @pdev - pointer to platform device
  465. *
  466. * intialize all v4l2 subdevs and media entities
  467. */
  468. static int vpfe_initialize_modules(struct vpfe_device *vpfe_dev,
  469. struct platform_device *pdev)
  470. {
  471. int ret;
  472. ret = vpfe_isif_init(&vpfe_dev->vpfe_isif, pdev);
  473. if (ret)
  474. return ret;
  475. ret = vpfe_ipipeif_init(&vpfe_dev->vpfe_ipipeif, pdev);
  476. if (ret)
  477. goto out_isif_init;
  478. ret = vpfe_ipipe_init(&vpfe_dev->vpfe_ipipe, pdev);
  479. if (ret)
  480. goto out_ipipeif_init;
  481. ret = vpfe_resizer_init(&vpfe_dev->vpfe_resizer, pdev);
  482. if (ret)
  483. goto out_ipipe_init;
  484. return 0;
  485. out_ipipe_init:
  486. vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
  487. out_ipipeif_init:
  488. vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
  489. out_isif_init:
  490. vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
  491. return ret;
  492. }
  493. /*
  494. * vpfe_probe() : vpfe probe function
  495. * @pdev: platform device pointer
  496. *
  497. * This function creates device entries by register itself to the V4L2 driver
  498. * and initializes fields of each device objects
  499. */
  500. static int vpfe_probe(struct platform_device *pdev)
  501. {
  502. struct vpfe_device *vpfe_dev;
  503. struct resource *res1;
  504. int ret = -ENOMEM;
  505. vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
  506. if (!vpfe_dev)
  507. return ret;
  508. if (pdev->dev.platform_data == NULL) {
  509. v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
  510. ret = -ENOENT;
  511. goto probe_free_dev_mem;
  512. }
  513. vpfe_dev->cfg = pdev->dev.platform_data;
  514. if (vpfe_dev->cfg->card_name == NULL ||
  515. vpfe_dev->cfg->sub_devs == NULL) {
  516. v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
  517. ret = -ENOENT;
  518. goto probe_free_dev_mem;
  519. }
  520. /* Get VINT0 irq resource */
  521. res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  522. if (!res1) {
  523. v4l2_err(pdev->dev.driver,
  524. "Unable to get interrupt for VINT0\n");
  525. ret = -ENOENT;
  526. goto probe_free_dev_mem;
  527. }
  528. vpfe_dev->ccdc_irq0 = res1->start;
  529. /* Get VINT1 irq resource */
  530. res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
  531. if (!res1) {
  532. v4l2_err(pdev->dev.driver,
  533. "Unable to get interrupt for VINT1\n");
  534. ret = -ENOENT;
  535. goto probe_free_dev_mem;
  536. }
  537. vpfe_dev->ccdc_irq1 = res1->start;
  538. /* Get DMA irq resource */
  539. res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
  540. if (!res1) {
  541. v4l2_err(pdev->dev.driver,
  542. "Unable to get interrupt for DMA\n");
  543. ret = -ENOENT;
  544. goto probe_free_dev_mem;
  545. }
  546. vpfe_dev->imp_dma_irq = res1->start;
  547. vpfe_dev->pdev = &pdev->dev;
  548. /* enable vpss clocks */
  549. ret = vpfe_enable_clock(vpfe_dev);
  550. if (ret)
  551. goto probe_free_dev_mem;
  552. ret = vpfe_initialize_modules(vpfe_dev, pdev);
  553. if (ret)
  554. goto probe_disable_clock;
  555. vpfe_dev->media_dev.dev = vpfe_dev->pdev;
  556. strcpy((char *)&vpfe_dev->media_dev.model, "davinci-media");
  557. ret = media_device_register(&vpfe_dev->media_dev);
  558. if (ret) {
  559. v4l2_err(pdev->dev.driver,
  560. "Unable to register media device.\n");
  561. goto probe_out_entities_cleanup;
  562. }
  563. vpfe_dev->v4l2_dev.mdev = &vpfe_dev->media_dev;
  564. ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
  565. if (ret) {
  566. v4l2_err(pdev->dev.driver, "Unable to register v4l2 device.\n");
  567. goto probe_out_media_unregister;
  568. }
  569. v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
  570. /* set the driver data in platform device */
  571. platform_set_drvdata(pdev, vpfe_dev);
  572. /* register subdevs/entities */
  573. ret = vpfe_register_entities(vpfe_dev);
  574. if (ret)
  575. goto probe_out_v4l2_unregister;
  576. ret = vpfe_attach_irq(vpfe_dev);
  577. if (ret)
  578. goto probe_out_entities_unregister;
  579. return 0;
  580. probe_out_entities_unregister:
  581. vpfe_unregister_entities(vpfe_dev);
  582. kzfree(vpfe_dev->sd);
  583. probe_out_v4l2_unregister:
  584. v4l2_device_unregister(&vpfe_dev->v4l2_dev);
  585. probe_out_media_unregister:
  586. media_device_unregister(&vpfe_dev->media_dev);
  587. probe_out_entities_cleanup:
  588. vpfe_cleanup_modules(vpfe_dev, pdev);
  589. probe_disable_clock:
  590. vpfe_disable_clock(vpfe_dev);
  591. probe_free_dev_mem:
  592. kzfree(vpfe_dev);
  593. return ret;
  594. }
  595. /*
  596. * vpfe_remove : This function un-registers device from V4L2 driver
  597. */
  598. static int vpfe_remove(struct platform_device *pdev)
  599. {
  600. struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
  601. v4l2_info(pdev->dev.driver, "vpfe_remove\n");
  602. kzfree(vpfe_dev->sd);
  603. vpfe_detach_irq(vpfe_dev);
  604. vpfe_unregister_entities(vpfe_dev);
  605. vpfe_cleanup_modules(vpfe_dev, pdev);
  606. v4l2_device_unregister(&vpfe_dev->v4l2_dev);
  607. media_device_unregister(&vpfe_dev->media_dev);
  608. vpfe_disable_clock(vpfe_dev);
  609. kzfree(vpfe_dev);
  610. return 0;
  611. }
  612. static struct platform_driver vpfe_driver = {
  613. .driver = {
  614. .name = CAPTURE_DRV_NAME,
  615. },
  616. .probe = vpfe_probe,
  617. .remove = vpfe_remove,
  618. };
  619. module_platform_driver(vpfe_driver);