1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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, 0444);
78module_param(debug, bool, 0644);
79
80
81
82
83
84
85
86
87
88
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
98void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
99 struct v4l2_pix_format *pix)
100{
101 switch (mbus->code) {
102 case MEDIA_BUS_FMT_UYVY8_2X8:
103 pix->pixelformat = V4L2_PIX_FMT_UYVY;
104 pix->bytesperline = pix->width * 2;
105 break;
106
107 case MEDIA_BUS_FMT_YUYV8_2X8:
108 pix->pixelformat = V4L2_PIX_FMT_YUYV;
109 pix->bytesperline = pix->width * 2;
110 break;
111
112 case MEDIA_BUS_FMT_YUYV10_1X20:
113 pix->pixelformat = V4L2_PIX_FMT_UYVY;
114 pix->bytesperline = pix->width * 2;
115 break;
116
117 case MEDIA_BUS_FMT_SGRBG12_1X12:
118 pix->pixelformat = V4L2_PIX_FMT_SBGGR16;
119 pix->bytesperline = pix->width * 2;
120 break;
121
122 case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
123 pix->pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8;
124 pix->bytesperline = pix->width;
125 break;
126
127 case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
128 pix->pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8;
129 pix->bytesperline = pix->width;
130 break;
131
132 case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
133 pix->pixelformat = V4L2_PIX_FMT_NV12;
134 pix->bytesperline = pix->width;
135 break;
136
137 case MEDIA_BUS_FMT_Y8_1X8:
138 pix->pixelformat = V4L2_PIX_FMT_GREY;
139 pix->bytesperline = pix->width;
140 break;
141
142 case MEDIA_BUS_FMT_UV8_1X8:
143 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
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
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
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
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
193
194
195
196
197
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
214
215
216
217
218
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
229 vpfe_dev->clks = kcalloc(vpfe_cfg->num_clocks,
230 sizeof(*vpfe_dev->clks), GFP_KERNEL);
231 if (!vpfe_dev->clks)
232 return -ENOMEM;
233
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]);
244 if (IS_ERR(vpfe_dev->clks[i])) {
245 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++)
265 if (!IS_ERR(vpfe_dev->clks[i])) {
266 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
278
279
280
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
291
292
293
294
295static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
296{
297 int ret;
298
299 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
300 "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
307 ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, 0,
308 "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,
317 0, "Imp_Sdram_Irq", vpfe_dev);
318 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
331
332
333
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 =
349 kcalloc(num_subdevs, sizeof(struct v4l2_subdev *),
350 GFP_KERNEL);
351 if (!vpfe_dev->sd)
352 return -ENOMEM;
353
354 for (i = 0, k = 0; i < num_subdevs; i++) {
355 sdinfo = &vpfe_cfg->sub_devs[i];
356
357
358
359
360
361
362
363 if (interface == sdinfo->is_camera) {
364
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
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
406
407
408
409
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
418 ret = register_i2c_devices(vpfe_dev);
419 if (ret)
420 return ret;
421
422
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
444 for (i = 0; i < vpfe_dev->num_ext_subdevs; i++)
445
446
447
448
449 if (vpfe_dev->sd[i]->entity.num_pads) {
450 ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
451 0, &vpfe_dev->vpfe_isif.subdev.entity,
452 0, flags);
453 if (ret < 0)
454 goto out_resizer_register;
455 }
456
457 ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
458 &vpfe_dev->vpfe_ipipeif.subdev.entity,
459 0, flags);
460 if (ret < 0)
461 goto out_resizer_register;
462
463 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
464 &vpfe_dev->vpfe_ipipe.subdev.entity,
465 0, flags);
466 if (ret < 0)
467 goto out_resizer_register;
468
469 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
470 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
471 0, flags);
472 if (ret < 0)
473 goto out_resizer_register;
474
475 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
476 &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
477 0, flags);
478 if (ret < 0)
479 goto out_resizer_register;
480
481 ret = v4l2_device_register_subdev_nodes(&vpfe_dev->v4l2_dev);
482 if (ret < 0)
483 goto out_resizer_register;
484
485 return 0;
486
487out_resizer_register:
488 vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
489out_ipipe_register:
490 vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
491out_ipipeif_register:
492 vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
493out_isif_register:
494 vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
495
496 return ret;
497}
498
499
500
501
502
503
504
505static void vpfe_unregister_entities(struct vpfe_device *vpfe_dev)
506{
507 vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
508 vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
509 vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
510 vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
511}
512
513
514
515
516
517
518
519
520static void vpfe_cleanup_modules(struct vpfe_device *vpfe_dev,
521 struct platform_device *pdev)
522{
523 vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
524 vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
525 vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
526 vpfe_resizer_cleanup(&vpfe_dev->vpfe_resizer, pdev);
527}
528
529
530
531
532
533
534
535
536static int vpfe_initialize_modules(struct vpfe_device *vpfe_dev,
537 struct platform_device *pdev)
538{
539 int ret;
540
541 ret = vpfe_isif_init(&vpfe_dev->vpfe_isif, pdev);
542 if (ret)
543 return ret;
544
545 ret = vpfe_ipipeif_init(&vpfe_dev->vpfe_ipipeif, pdev);
546 if (ret)
547 goto out_isif_init;
548
549 ret = vpfe_ipipe_init(&vpfe_dev->vpfe_ipipe, pdev);
550 if (ret)
551 goto out_ipipeif_init;
552
553 ret = vpfe_resizer_init(&vpfe_dev->vpfe_resizer, pdev);
554 if (ret)
555 goto out_ipipe_init;
556
557 return 0;
558
559out_ipipe_init:
560 vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
561out_ipipeif_init:
562 vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
563out_isif_init:
564 vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
565
566 return ret;
567}
568
569
570
571
572
573
574
575
576static int vpfe_probe(struct platform_device *pdev)
577{
578 struct vpfe_device *vpfe_dev;
579 struct resource *res1;
580 int ret = -ENOMEM;
581
582 vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
583 if (!vpfe_dev)
584 return ret;
585
586 if (pdev->dev.platform_data == NULL) {
587 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
588 ret = -ENOENT;
589 goto probe_free_dev_mem;
590 }
591
592 vpfe_dev->cfg = pdev->dev.platform_data;
593 if (vpfe_dev->cfg->card_name == NULL ||
594 vpfe_dev->cfg->sub_devs == NULL) {
595 v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
596 ret = -ENOENT;
597 goto probe_free_dev_mem;
598 }
599
600
601 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
602 if (!res1) {
603 v4l2_err(pdev->dev.driver,
604 "Unable to get interrupt for VINT0\n");
605 ret = -ENOENT;
606 goto probe_free_dev_mem;
607 }
608 vpfe_dev->ccdc_irq0 = res1->start;
609
610
611 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
612 if (!res1) {
613 v4l2_err(pdev->dev.driver,
614 "Unable to get interrupt for VINT1\n");
615 ret = -ENOENT;
616 goto probe_free_dev_mem;
617 }
618 vpfe_dev->ccdc_irq1 = res1->start;
619
620
621 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
622 if (!res1) {
623 v4l2_err(pdev->dev.driver,
624 "Unable to get interrupt for DMA\n");
625 ret = -ENOENT;
626 goto probe_free_dev_mem;
627 }
628 vpfe_dev->imp_dma_irq = res1->start;
629
630 vpfe_dev->pdev = &pdev->dev;
631
632
633 ret = vpfe_enable_clock(vpfe_dev);
634 if (ret)
635 goto probe_free_dev_mem;
636
637 ret = vpfe_initialize_modules(vpfe_dev, pdev);
638 if (ret)
639 goto probe_disable_clock;
640
641 vpfe_dev->media_dev.dev = vpfe_dev->pdev;
642 strcpy((char *)&vpfe_dev->media_dev.model, "davinci-media");
643
644 ret = media_device_register(&vpfe_dev->media_dev);
645 if (ret) {
646 v4l2_err(pdev->dev.driver,
647 "Unable to register media device.\n");
648 goto probe_out_entities_cleanup;
649 }
650
651 vpfe_dev->v4l2_dev.mdev = &vpfe_dev->media_dev;
652 ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
653 if (ret) {
654 v4l2_err(pdev->dev.driver, "Unable to register v4l2 device.\n");
655 goto probe_out_media_unregister;
656 }
657
658 v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
659
660 platform_set_drvdata(pdev, vpfe_dev);
661
662 ret = vpfe_register_entities(vpfe_dev);
663 if (ret)
664 goto probe_out_v4l2_unregister;
665
666 ret = vpfe_attach_irq(vpfe_dev);
667 if (ret)
668 goto probe_out_entities_unregister;
669
670 return 0;
671
672probe_out_entities_unregister:
673 vpfe_unregister_entities(vpfe_dev);
674 kzfree(vpfe_dev->sd);
675probe_out_v4l2_unregister:
676 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
677probe_out_media_unregister:
678 media_device_unregister(&vpfe_dev->media_dev);
679probe_out_entities_cleanup:
680 vpfe_cleanup_modules(vpfe_dev, pdev);
681probe_disable_clock:
682 vpfe_disable_clock(vpfe_dev);
683probe_free_dev_mem:
684 kzfree(vpfe_dev);
685
686 return ret;
687}
688
689
690
691
692static int vpfe_remove(struct platform_device *pdev)
693{
694 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
695
696 v4l2_info(pdev->dev.driver, "vpfe_remove\n");
697
698 kzfree(vpfe_dev->sd);
699 vpfe_detach_irq(vpfe_dev);
700 vpfe_unregister_entities(vpfe_dev);
701 vpfe_cleanup_modules(vpfe_dev, pdev);
702 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
703 media_device_unregister(&vpfe_dev->media_dev);
704 vpfe_disable_clock(vpfe_dev);
705 kzfree(vpfe_dev);
706
707 return 0;
708}
709
710static struct platform_driver vpfe_driver = {
711 .driver = {
712 .name = CAPTURE_DRV_NAME,
713 },
714 .probe = vpfe_probe,
715 .remove = vpfe_remove,
716};
717
718module_platform_driver(vpfe_driver);
719