blob: 57426199ad7af48203a349afe66eaa407db120bf [file] [log] [blame]
Manjunath Hadli91825402012-11-28 02:02:02 -03001/*
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
67#include <linux/interrupt.h>
68#include <linux/module.h>
69#include <linux/slab.h>
70
71#include "vpfe.h"
72#include "vpfe_mc_capture.h"
73
74static bool debug;
75static bool interface;
76
77module_param(interface, bool, S_IRUGO);
78module_param(debug, bool, 0644);
79
80/**
81 * VPFE capture can be used for capturing video such as from TVP5146 or TVP7002
82 * and for capture raw bayer data from camera sensors such as mt9p031. At this
83 * point there is problem in co-existence of mt9p031 and tvp5146 due to i2c
84 * address collision. So set the variable below from bootargs to do either video
85 * capture or camera capture.
86 * interface = 0 - video capture (from TVP514x or such),
87 * interface = 1 - Camera capture (from mt9p031 or such)
88 * Re-visit this when we fix the co-existence issue
89 */
90MODULE_PARM_DESC(interface, "interface 0-1 (default:0)");
91MODULE_PARM_DESC(debug, "Debug level 0-1");
92
93MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR("Texas Instruments");
96
97/* map mbus_fmt to pixelformat */
98void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
99 struct v4l2_pix_format *pix)
100{
101 switch (mbus->code) {
Boris BREZILLON3336f072014-11-10 14:28:33 -0300102 case MEDIA_BUS_FMT_UYVY8_2X8:
Manjunath Hadli91825402012-11-28 02:02:02 -0300103 pix->pixelformat = V4L2_PIX_FMT_UYVY;
104 pix->bytesperline = pix->width * 2;
105 break;
106
Boris BREZILLON3336f072014-11-10 14:28:33 -0300107 case MEDIA_BUS_FMT_YUYV8_2X8:
Manjunath Hadli91825402012-11-28 02:02:02 -0300108 pix->pixelformat = V4L2_PIX_FMT_YUYV;
109 pix->bytesperline = pix->width * 2;
110 break;
111
Boris BREZILLON3336f072014-11-10 14:28:33 -0300112 case MEDIA_BUS_FMT_YUYV10_1X20:
Manjunath Hadli91825402012-11-28 02:02:02 -0300113 pix->pixelformat = V4L2_PIX_FMT_UYVY;
114 pix->bytesperline = pix->width * 2;
115 break;
116
Boris BREZILLON3336f072014-11-10 14:28:33 -0300117 case MEDIA_BUS_FMT_SGRBG12_1X12:
Manjunath Hadli91825402012-11-28 02:02:02 -0300118 pix->pixelformat = V4L2_PIX_FMT_SBGGR16;
119 pix->bytesperline = pix->width * 2;
120 break;
121
Boris BREZILLON3336f072014-11-10 14:28:33 -0300122 case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
Manjunath Hadli91825402012-11-28 02:02:02 -0300123 pix->pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8;
124 pix->bytesperline = pix->width;
125 break;
126
Boris BREZILLON3336f072014-11-10 14:28:33 -0300127 case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
Manjunath Hadli91825402012-11-28 02:02:02 -0300128 pix->pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8;
129 pix->bytesperline = pix->width;
130 break;
131
Boris BREZILLON3336f072014-11-10 14:28:33 -0300132 case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
Manjunath Hadli91825402012-11-28 02:02:02 -0300133 pix->pixelformat = V4L2_PIX_FMT_NV12;
134 pix->bytesperline = pix->width;
135 break;
136
Boris BREZILLON3336f072014-11-10 14:28:33 -0300137 case MEDIA_BUS_FMT_Y8_1X8:
Manjunath Hadli91825402012-11-28 02:02:02 -0300138 pix->pixelformat = V4L2_PIX_FMT_GREY;
139 pix->bytesperline = pix->width;
140 break;
141
Boris BREZILLON3336f072014-11-10 14:28:33 -0300142 case MEDIA_BUS_FMT_UV8_1X8:
Manjunath Hadli91825402012-11-28 02:02:02 -0300143 pix->pixelformat = V4L2_PIX_FMT_UV8;
144 pix->bytesperline = pix->width;
145 break;
146
147 default:
148 pr_err("Invalid mbus code set\n");
149 }
150 /* pitch should be 32 bytes aligned */
151 pix->bytesperline = ALIGN(pix->bytesperline, 32);
152 if (pix->pixelformat == V4L2_PIX_FMT_NV12)
153 pix->sizeimage = pix->bytesperline * pix->height +
154 ((pix->bytesperline * pix->height) >> 1);
155 else
156 pix->sizeimage = pix->bytesperline * pix->height;
157}
158
159/* ISR for VINT0*/
160static irqreturn_t vpfe_isr(int irq, void *dev_id)
161{
162 struct vpfe_device *vpfe_dev = dev_id;
163
164 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_isr\n");
165 vpfe_isif_buffer_isr(&vpfe_dev->vpfe_isif);
166 vpfe_resizer_buffer_isr(&vpfe_dev->vpfe_resizer);
167 return IRQ_HANDLED;
168}
169
170/* vpfe_vdint1_isr() - isr handler for VINT1 interrupt */
171static irqreturn_t vpfe_vdint1_isr(int irq, void *dev_id)
172{
173 struct vpfe_device *vpfe_dev = dev_id;
174
175 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_vdint1_isr\n");
176 vpfe_isif_vidint1_isr(&vpfe_dev->vpfe_isif);
177 return IRQ_HANDLED;
178}
179
180/* vpfe_imp_dma_isr() - ISR for ipipe dma completion */
181static irqreturn_t vpfe_imp_dma_isr(int irq, void *dev_id)
182{
183 struct vpfe_device *vpfe_dev = dev_id;
184
185 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_imp_dma_isr\n");
186 vpfe_ipipeif_ss_buffer_isr(&vpfe_dev->vpfe_ipipeif);
187 vpfe_resizer_dma_isr(&vpfe_dev->vpfe_resizer);
188 return IRQ_HANDLED;
189}
190
191/*
192 * vpfe_disable_clock() - Disable clocks for vpfe capture driver
193 * @vpfe_dev - ptr to vpfe capture device
194 *
195 * Disables clocks defined in vpfe configuration. The function
196 * assumes that at least one clock is to be defined which is
197 * true as of now.
198 */
199static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
200{
201 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
202 int i;
203
204 for (i = 0; i < vpfe_cfg->num_clocks; i++) {
205 clk_disable_unprepare(vpfe_dev->clks[i]);
206 clk_put(vpfe_dev->clks[i]);
207 }
208 kzfree(vpfe_dev->clks);
209 v4l2_info(vpfe_dev->pdev->driver, "vpfe capture clocks disabled\n");
210}
211
212/*
213 * vpfe_enable_clock() - Enable clocks for vpfe capture driver
214 * @vpfe_dev - ptr to vpfe capture device
215 *
216 * Enables clocks defined in vpfe configuration. The function
217 * assumes that at least one clock is to be defined which is
218 * true as of now.
219 */
220static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
221{
222 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
223 int ret = -EFAULT;
224 int i;
225
226 if (!vpfe_cfg->num_clocks)
227 return 0;
228
Navya Sri Nizamkari9ac04a82015-03-10 17:35:57 +0530229 vpfe_dev->clks = kcalloc(vpfe_cfg->num_clocks,
230 sizeof(struct clock *), GFP_KERNEL);
Heena Sirwani31907c02014-09-25 14:43:31 +0530231 if (vpfe_dev->clks == NULL)
Manjunath Hadli91825402012-11-28 02:02:02 -0300232 return -ENOMEM;
Manjunath Hadli91825402012-11-28 02:02:02 -0300233
234 for (i = 0; i < vpfe_cfg->num_clocks; i++) {
235 if (vpfe_cfg->clocks[i] == NULL) {
236 v4l2_err(vpfe_dev->pdev->driver,
237 "clock %s is not defined in vpfe config\n",
238 vpfe_cfg->clocks[i]);
239 goto out;
240 }
241
242 vpfe_dev->clks[i] =
243 clk_get(vpfe_dev->pdev, vpfe_cfg->clocks[i]);
Wei Yongjunb2792652013-03-11 09:57:22 -0300244 if (IS_ERR(vpfe_dev->clks[i])) {
Manjunath Hadli91825402012-11-28 02:02:02 -0300245 v4l2_err(vpfe_dev->pdev->driver,
246 "Failed to get clock %s\n",
247 vpfe_cfg->clocks[i]);
248 goto out;
249 }
250
251 if (clk_prepare_enable(vpfe_dev->clks[i])) {
252 v4l2_err(vpfe_dev->pdev->driver,
253 "vpfe clock %s not enabled\n",
254 vpfe_cfg->clocks[i]);
255 goto out;
256 }
257
258 v4l2_info(vpfe_dev->pdev->driver, "vpss clock %s enabled",
259 vpfe_cfg->clocks[i]);
260 }
261
262 return 0;
263out:
264 for (i = 0; i < vpfe_cfg->num_clocks; i++)
Wei Yongjunb2792652013-03-11 09:57:22 -0300265 if (!IS_ERR(vpfe_dev->clks[i])) {
Manjunath Hadli91825402012-11-28 02:02:02 -0300266 clk_disable_unprepare(vpfe_dev->clks[i]);
267 clk_put(vpfe_dev->clks[i]);
268 }
269
270 v4l2_err(vpfe_dev->pdev->driver, "Failed to enable clocks\n");
271 kzfree(vpfe_dev->clks);
272
273 return ret;
274}
275
276/*
277 * vpfe_detach_irq() - Detach IRQs for vpfe capture driver
278 * @vpfe_dev - ptr to vpfe capture device
279 *
280 * Detach all IRQs defined in vpfe configuration.
281 */
282static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
283{
284 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
285 free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
286 free_irq(vpfe_dev->imp_dma_irq, vpfe_dev);
287}
288
289/*
290 * vpfe_attach_irq() - Attach IRQs for vpfe capture driver
291 * @vpfe_dev - ptr to vpfe capture device
292 *
293 * Attach all IRQs defined in vpfe configuration.
294 */
295static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
296{
297 int ret = 0;
298
Michael Opdenacker381d0a42013-12-09 07:16:22 -0300299 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
Manjunath Hadli91825402012-11-28 02:02:02 -0300300 "vpfe_capture0", vpfe_dev);
301 if (ret < 0) {
302 v4l2_err(&vpfe_dev->v4l2_dev,
303 "Error: requesting VINT0 interrupt\n");
304 return ret;
305 }
306
Michael Opdenacker381d0a42013-12-09 07:16:22 -0300307 ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, 0,
Manjunath Hadli91825402012-11-28 02:02:02 -0300308 "vpfe_capture1", vpfe_dev);
309 if (ret < 0) {
310 v4l2_err(&vpfe_dev->v4l2_dev,
311 "Error: requesting VINT1 interrupt\n");
312 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
313 return ret;
314 }
315
316 ret = request_irq(vpfe_dev->imp_dma_irq, vpfe_imp_dma_isr,
Michael Opdenacker381d0a42013-12-09 07:16:22 -0300317 0, "Imp_Sdram_Irq", vpfe_dev);
Manjunath Hadli91825402012-11-28 02:02:02 -0300318 if (ret < 0) {
319 v4l2_err(&vpfe_dev->v4l2_dev,
320 "Error: requesting IMP IRQ interrupt\n");
321 free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
322 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
323 return ret;
324 }
325
326 return 0;
327}
328
329/*
330 * register_i2c_devices() - register all i2c v4l2 subdevs
331 * @vpfe_dev - ptr to vpfe capture device
332 *
333 * register all i2c v4l2 subdevs
334 */
335static int register_i2c_devices(struct vpfe_device *vpfe_dev)
336{
337 struct vpfe_ext_subdev_info *sdinfo;
338 struct vpfe_config *vpfe_cfg;
339 struct i2c_adapter *i2c_adap;
340 unsigned int num_subdevs;
341 int ret;
342 int i;
343 int k;
344
345 vpfe_cfg = vpfe_dev->cfg;
346 i2c_adap = i2c_get_adapter(1);
347 num_subdevs = vpfe_cfg->num_subdevs;
348 vpfe_dev->sd =
Navya Sri Nizamkari9ac04a82015-03-10 17:35:57 +0530349 kcalloc(num_subdevs, sizeof(struct v4l2_subdev *),
350 GFP_KERNEL);
Heena Sirwani31907c02014-09-25 14:43:31 +0530351 if (vpfe_dev->sd == NULL)
Manjunath Hadli91825402012-11-28 02:02:02 -0300352 return -ENOMEM;
Manjunath Hadli91825402012-11-28 02:02:02 -0300353
354 for (i = 0, k = 0; i < num_subdevs; i++) {
355 sdinfo = &vpfe_cfg->sub_devs[i];
356 /*
357 * register subdevices based on interface setting. Currently
358 * tvp5146 and mt9p031 cannot co-exists due to i2c address
359 * conflicts. So only one of them is registered. Re-visit this
360 * once we have support for i2c switch handling in i2c driver
361 * framework
362 */
363 if (interface == sdinfo->is_camera) {
364 /* setup input path */
365 if (vpfe_cfg->setup_input &&
366 vpfe_cfg->setup_input(sdinfo->grp_id) < 0) {
367 ret = -EFAULT;
368 v4l2_info(&vpfe_dev->v4l2_dev,
369 "could not setup input for %s\n",
370 sdinfo->module_name);
371 goto probe_sd_out;
372 }
373 /* Load up the subdevice */
374 vpfe_dev->sd[k] =
375 v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
376 i2c_adap, &sdinfo->board_info,
377 NULL);
378 if (vpfe_dev->sd[k]) {
379 v4l2_info(&vpfe_dev->v4l2_dev,
380 "v4l2 sub device %s registered\n",
381 sdinfo->module_name);
382
383 vpfe_dev->sd[k]->grp_id = sdinfo->grp_id;
384 k++;
385
386 sdinfo->registered = 1;
387 }
388 } else {
389 v4l2_info(&vpfe_dev->v4l2_dev,
390 "v4l2 sub device %s is not registered\n",
391 sdinfo->module_name);
392 }
393 }
394 vpfe_dev->num_ext_subdevs = k;
395
396 return 0;
397
398probe_sd_out:
399 kzfree(vpfe_dev->sd);
400
401 return ret;
402}
403
404/*
405 * vpfe_register_entities() - register all v4l2 subdevs and media entities
406 * @vpfe_dev - ptr to vpfe capture device
407 *
408 * register all v4l2 subdevs, media entities, and creates links
409 * between entities
410 */
411static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
412{
413 unsigned int flags = 0;
414 int ret;
415 int i;
416
417 /* register i2c devices first */
418 ret = register_i2c_devices(vpfe_dev);
419 if (ret)
420 return ret;
421
422 /* register rest of the sub-devs */
423 ret = vpfe_isif_register_entities(&vpfe_dev->vpfe_isif,
424 &vpfe_dev->v4l2_dev);
425 if (ret)
426 return ret;
427
428 ret = vpfe_ipipeif_register_entities(&vpfe_dev->vpfe_ipipeif,
429 &vpfe_dev->v4l2_dev);
430 if (ret)
431 goto out_isif_register;
432
433 ret = vpfe_ipipe_register_entities(&vpfe_dev->vpfe_ipipe,
434 &vpfe_dev->v4l2_dev);
435 if (ret)
436 goto out_ipipeif_register;
437
438 ret = vpfe_resizer_register_entities(&vpfe_dev->vpfe_resizer,
439 &vpfe_dev->v4l2_dev);
440 if (ret)
441 goto out_ipipe_register;
442
443 /* create links now, starting with external(i2c) entities */
444 for (i = 0; i < vpfe_dev->num_ext_subdevs; i++)
445 /* if entity has no pads (ex: amplifier),
446 cant establish link */
447 if (vpfe_dev->sd[i]->entity.num_pads) {
448 ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
449 0, &vpfe_dev->vpfe_isif.subdev.entity,
450 0, flags);
451 if (ret < 0)
452 goto out_resizer_register;
453 }
454
455 ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
456 &vpfe_dev->vpfe_ipipeif.subdev.entity,
457 0, flags);
458 if (ret < 0)
459 goto out_resizer_register;
460
461 ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
462 &vpfe_dev->vpfe_ipipe.subdev.entity,
463 0, flags);
464 if (ret < 0)
465 goto out_resizer_register;
466
467 ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
468 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
469 0, flags);
470 if (ret < 0)
471 goto out_resizer_register;
472
473 ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
474 &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
475 0, flags);
476 if (ret < 0)
477 goto out_resizer_register;
478
479 ret = v4l2_device_register_subdev_nodes(&vpfe_dev->v4l2_dev);
480 if (ret < 0)
481 goto out_resizer_register;
482
483 return 0;
484
485out_resizer_register:
486 vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
487out_ipipe_register:
488 vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
489out_ipipeif_register:
490 vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
491out_isif_register:
492 vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
493
494 return ret;
495}
496
497/*
498 * vpfe_unregister_entities() - unregister all v4l2 subdevs and media entities
499 * @vpfe_dev - ptr to vpfe capture device
500 *
501 * unregister all v4l2 subdevs and media entities
502 */
503static void vpfe_unregister_entities(struct vpfe_device *vpfe_dev)
504{
505 vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
506 vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
507 vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
508 vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
509}
510
511/*
512 * vpfe_cleanup_modules() - cleanup all non-i2c v4l2 subdevs
513 * @vpfe_dev - ptr to vpfe capture device
514 * @pdev - pointer to platform device
515 *
516 * cleanup all v4l2 subdevs
517 */
518static void vpfe_cleanup_modules(struct vpfe_device *vpfe_dev,
519 struct platform_device *pdev)
520{
521 vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
522 vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
523 vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
524 vpfe_resizer_cleanup(&vpfe_dev->vpfe_resizer, pdev);
525}
526
527/*
528 * vpfe_initialize_modules() - initialize all non-i2c v4l2 subdevs
529 * @vpfe_dev - ptr to vpfe capture device
530 * @pdev - pointer to platform device
531 *
532 * intialize all v4l2 subdevs and media entities
533 */
534static int vpfe_initialize_modules(struct vpfe_device *vpfe_dev,
535 struct platform_device *pdev)
536{
537 int ret;
538
539 ret = vpfe_isif_init(&vpfe_dev->vpfe_isif, pdev);
540 if (ret)
541 return ret;
542
543 ret = vpfe_ipipeif_init(&vpfe_dev->vpfe_ipipeif, pdev);
544 if (ret)
545 goto out_isif_init;
546
547 ret = vpfe_ipipe_init(&vpfe_dev->vpfe_ipipe, pdev);
548 if (ret)
549 goto out_ipipeif_init;
550
551 ret = vpfe_resizer_init(&vpfe_dev->vpfe_resizer, pdev);
552 if (ret)
553 goto out_ipipe_init;
554
555 return 0;
556
557out_ipipe_init:
558 vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
559out_ipipeif_init:
560 vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
561out_isif_init:
562 vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
563
564 return ret;
565}
566
567/*
568 * vpfe_probe() : vpfe probe function
569 * @pdev: platform device pointer
570 *
571 * This function creates device entries by register itself to the V4L2 driver
572 * and initializes fields of each device objects
573 */
574static int vpfe_probe(struct platform_device *pdev)
575{
576 struct vpfe_device *vpfe_dev;
577 struct resource *res1;
578 int ret = -ENOMEM;
579
580 vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
Heena Sirwani31907c02014-09-25 14:43:31 +0530581 if (!vpfe_dev)
Manjunath Hadli91825402012-11-28 02:02:02 -0300582 return ret;
Manjunath Hadli91825402012-11-28 02:02:02 -0300583
584 if (pdev->dev.platform_data == NULL) {
585 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
586 ret = -ENOENT;
587 goto probe_free_dev_mem;
588 }
589
590 vpfe_dev->cfg = pdev->dev.platform_data;
591 if (vpfe_dev->cfg->card_name == NULL ||
592 vpfe_dev->cfg->sub_devs == NULL) {
593 v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
594 ret = -ENOENT;
595 goto probe_free_dev_mem;
596 }
597
598 /* Get VINT0 irq resource */
599 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
600 if (!res1) {
601 v4l2_err(pdev->dev.driver,
602 "Unable to get interrupt for VINT0\n");
603 ret = -ENOENT;
604 goto probe_free_dev_mem;
605 }
606 vpfe_dev->ccdc_irq0 = res1->start;
607
608 /* Get VINT1 irq resource */
609 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
610 if (!res1) {
611 v4l2_err(pdev->dev.driver,
612 "Unable to get interrupt for VINT1\n");
613 ret = -ENOENT;
614 goto probe_free_dev_mem;
615 }
616 vpfe_dev->ccdc_irq1 = res1->start;
617
618 /* Get DMA irq resource */
619 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
620 if (!res1) {
621 v4l2_err(pdev->dev.driver,
622 "Unable to get interrupt for DMA\n");
623 ret = -ENOENT;
624 goto probe_free_dev_mem;
625 }
626 vpfe_dev->imp_dma_irq = res1->start;
627
628 vpfe_dev->pdev = &pdev->dev;
629
630 /* enable vpss clocks */
631 ret = vpfe_enable_clock(vpfe_dev);
632 if (ret)
633 goto probe_free_dev_mem;
634
Wei Yongjun96f83b32013-05-07 07:51:21 -0300635 ret = vpfe_initialize_modules(vpfe_dev, pdev);
636 if (ret)
Manjunath Hadli91825402012-11-28 02:02:02 -0300637 goto probe_disable_clock;
638
639 vpfe_dev->media_dev.dev = vpfe_dev->pdev;
640 strcpy((char *)&vpfe_dev->media_dev.model, "davinci-media");
641
642 ret = media_device_register(&vpfe_dev->media_dev);
643 if (ret) {
644 v4l2_err(pdev->dev.driver,
645 "Unable to register media device.\n");
646 goto probe_out_entities_cleanup;
647 }
648
649 vpfe_dev->v4l2_dev.mdev = &vpfe_dev->media_dev;
650 ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
651 if (ret) {
652 v4l2_err(pdev->dev.driver, "Unable to register v4l2 device.\n");
653 goto probe_out_media_unregister;
654 }
655
656 v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
657 /* set the driver data in platform device */
658 platform_set_drvdata(pdev, vpfe_dev);
659 /* register subdevs/entities */
Wei Yongjun96f83b32013-05-07 07:51:21 -0300660 ret = vpfe_register_entities(vpfe_dev);
661 if (ret)
Manjunath Hadli91825402012-11-28 02:02:02 -0300662 goto probe_out_v4l2_unregister;
663
664 ret = vpfe_attach_irq(vpfe_dev);
665 if (ret)
666 goto probe_out_entities_unregister;
667
668 return 0;
669
670probe_out_entities_unregister:
671 vpfe_unregister_entities(vpfe_dev);
672 kzfree(vpfe_dev->sd);
673probe_out_v4l2_unregister:
674 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
675probe_out_media_unregister:
676 media_device_unregister(&vpfe_dev->media_dev);
677probe_out_entities_cleanup:
678 vpfe_cleanup_modules(vpfe_dev, pdev);
679probe_disable_clock:
680 vpfe_disable_clock(vpfe_dev);
681probe_free_dev_mem:
682 kzfree(vpfe_dev);
683
684 return ret;
685}
686
687/*
688 * vpfe_remove : This function un-registers device from V4L2 driver
689 */
690static int vpfe_remove(struct platform_device *pdev)
691{
692 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
693
694 v4l2_info(pdev->dev.driver, "vpfe_remove\n");
695
696 kzfree(vpfe_dev->sd);
697 vpfe_detach_irq(vpfe_dev);
698 vpfe_unregister_entities(vpfe_dev);
699 vpfe_cleanup_modules(vpfe_dev, pdev);
700 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
701 media_device_unregister(&vpfe_dev->media_dev);
702 vpfe_disable_clock(vpfe_dev);
703 kzfree(vpfe_dev);
704
705 return 0;
706}
707
708static struct platform_driver vpfe_driver = {
709 .driver = {
710 .name = CAPTURE_DRV_NAME,
Manjunath Hadli91825402012-11-28 02:02:02 -0300711 },
712 .probe = vpfe_probe,
713 .remove = vpfe_remove,
714};
715
Sachin Kamat18ace0e2013-03-05 07:52:14 -0300716module_platform_driver(vpfe_driver);