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#include <linux/interrupt.h>
65#include <linux/module.h>
66#include <linux/slab.h>
67
68#include "vpfe.h"
69#include "vpfe_mc_capture.h"
70
71static bool debug;
72static bool interface;
73
74module_param(interface, bool, 0444);
75module_param(debug, bool, 0644);
76
77
78
79
80
81
82
83
84
85
86
87MODULE_PARM_DESC(interface, "interface 0-1 (default:0)");
88MODULE_PARM_DESC(debug, "Debug level 0-1");
89
90MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
91MODULE_LICENSE("GPL");
92MODULE_AUTHOR("Texas Instruments");
93
94
95void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
96 struct v4l2_pix_format *pix)
97{
98 switch (mbus->code) {
99 case MEDIA_BUS_FMT_UYVY8_2X8:
100 pix->pixelformat = V4L2_PIX_FMT_UYVY;
101 pix->bytesperline = pix->width * 2;
102 break;
103
104 case MEDIA_BUS_FMT_YUYV8_2X8:
105 pix->pixelformat = V4L2_PIX_FMT_YUYV;
106 pix->bytesperline = pix->width * 2;
107 break;
108
109 case MEDIA_BUS_FMT_YUYV10_1X20:
110 pix->pixelformat = V4L2_PIX_FMT_UYVY;
111 pix->bytesperline = pix->width * 2;
112 break;
113
114 case MEDIA_BUS_FMT_SGRBG12_1X12:
115 pix->pixelformat = V4L2_PIX_FMT_SBGGR16;
116 pix->bytesperline = pix->width * 2;
117 break;
118
119 case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
120 pix->pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8;
121 pix->bytesperline = pix->width;
122 break;
123
124 case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
125 pix->pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8;
126 pix->bytesperline = pix->width;
127 break;
128
129 case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
130 pix->pixelformat = V4L2_PIX_FMT_NV12;
131 pix->bytesperline = pix->width;
132 break;
133
134 case MEDIA_BUS_FMT_Y8_1X8:
135 pix->pixelformat = V4L2_PIX_FMT_GREY;
136 pix->bytesperline = pix->width;
137 break;
138
139 case MEDIA_BUS_FMT_UV8_1X8:
140 pix->pixelformat = V4L2_PIX_FMT_UV8;
141 pix->bytesperline = pix->width;
142 break;
143
144 default:
145 pr_err("Invalid mbus code set\n");
146 }
147
148 pix->bytesperline = ALIGN(pix->bytesperline, 32);
149 if (pix->pixelformat == V4L2_PIX_FMT_NV12)
150 pix->sizeimage = pix->bytesperline * pix->height +
151 ((pix->bytesperline * pix->height) >> 1);
152 else
153 pix->sizeimage = pix->bytesperline * pix->height;
154}
155
156
157static irqreturn_t vpfe_isr(int irq, void *dev_id)
158{
159 struct vpfe_device *vpfe_dev = dev_id;
160
161 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
162 vpfe_isif_buffer_isr(&vpfe_dev->vpfe_isif);
163 vpfe_resizer_buffer_isr(&vpfe_dev->vpfe_resizer);
164 return IRQ_HANDLED;
165}
166
167
168static irqreturn_t vpfe_vdint1_isr(int irq, void *dev_id)
169{
170 struct vpfe_device *vpfe_dev = dev_id;
171
172 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
173 vpfe_isif_vidint1_isr(&vpfe_dev->vpfe_isif);
174 return IRQ_HANDLED;
175}
176
177
178static irqreturn_t vpfe_imp_dma_isr(int irq, void *dev_id)
179{
180 struct vpfe_device *vpfe_dev = dev_id;
181
182 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
183 vpfe_ipipeif_ss_buffer_isr(&vpfe_dev->vpfe_ipipeif);
184 vpfe_resizer_dma_isr(&vpfe_dev->vpfe_resizer);
185 return IRQ_HANDLED;
186}
187
188
189
190
191
192
193
194
195
196static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
197{
198 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
199 int i;
200
201 for (i = 0; i < vpfe_cfg->num_clocks; i++) {
202 clk_disable_unprepare(vpfe_dev->clks[i]);
203 clk_put(vpfe_dev->clks[i]);
204 }
205 kzfree(vpfe_dev->clks);
206 v4l2_info(vpfe_dev->pdev->driver, "vpfe capture clocks disabled\n");
207}
208
209
210
211
212
213
214
215
216
217static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
218{
219 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
220 int ret = -EFAULT;
221 int i;
222
223 if (!vpfe_cfg->num_clocks)
224 return 0;
225
226 vpfe_dev->clks = kcalloc(vpfe_cfg->num_clocks,
227 sizeof(*vpfe_dev->clks), GFP_KERNEL);
228 if (!vpfe_dev->clks)
229 return -ENOMEM;
230
231 for (i = 0; i < vpfe_cfg->num_clocks; i++) {
232 if (vpfe_cfg->clocks[i] == NULL) {
233 v4l2_err(vpfe_dev->pdev->driver,
234 "clock %s is not defined in vpfe config\n",
235 vpfe_cfg->clocks[i]);
236 goto out;
237 }
238
239 vpfe_dev->clks[i] =
240 clk_get(vpfe_dev->pdev, vpfe_cfg->clocks[i]);
241 if (IS_ERR(vpfe_dev->clks[i])) {
242 v4l2_err(vpfe_dev->pdev->driver,
243 "Failed to get clock %s\n",
244 vpfe_cfg->clocks[i]);
245 goto out;
246 }
247
248 if (clk_prepare_enable(vpfe_dev->clks[i])) {
249 v4l2_err(vpfe_dev->pdev->driver,
250 "vpfe clock %s not enabled\n",
251 vpfe_cfg->clocks[i]);
252 goto out;
253 }
254
255 v4l2_info(vpfe_dev->pdev->driver, "vpss clock %s enabled",
256 vpfe_cfg->clocks[i]);
257 }
258
259 return 0;
260out:
261 for (i = 0; i < vpfe_cfg->num_clocks; i++)
262 if (!IS_ERR(vpfe_dev->clks[i])) {
263 clk_disable_unprepare(vpfe_dev->clks[i]);
264 clk_put(vpfe_dev->clks[i]);
265 }
266
267 v4l2_err(vpfe_dev->pdev->driver, "Failed to enable clocks\n");
268 kzfree(vpfe_dev->clks);
269
270 return ret;
271}
272
273
274
275
276
277
278
279static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
280{
281 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
282 free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
283 free_irq(vpfe_dev->imp_dma_irq, vpfe_dev);
284}
285
286
287
288
289
290
291
292static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
293{
294 int ret;
295
296 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
297 "vpfe_capture0", vpfe_dev);
298 if (ret < 0) {
299 v4l2_err(&vpfe_dev->v4l2_dev,
300 "Error: requesting VINT0 interrupt\n");
301 return ret;
302 }
303
304 ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, 0,
305 "vpfe_capture1", vpfe_dev);
306 if (ret < 0) {
307 v4l2_err(&vpfe_dev->v4l2_dev,
308 "Error: requesting VINT1 interrupt\n");
309 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
310 return ret;
311 }
312
313 ret = request_irq(vpfe_dev->imp_dma_irq, vpfe_imp_dma_isr,
314 0, "Imp_Sdram_Irq", vpfe_dev);
315 if (ret < 0) {
316 v4l2_err(&vpfe_dev->v4l2_dev,
317 "Error: requesting IMP IRQ interrupt\n");
318 free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
319 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
320 return ret;
321 }
322
323 return 0;
324}
325
326
327
328
329
330
331
332static int register_i2c_devices(struct vpfe_device *vpfe_dev)
333{
334 struct vpfe_ext_subdev_info *sdinfo;
335 struct vpfe_config *vpfe_cfg;
336 struct i2c_adapter *i2c_adap;
337 unsigned int num_subdevs;
338 int ret;
339 int i;
340 int k;
341
342 vpfe_cfg = vpfe_dev->cfg;
343 i2c_adap = i2c_get_adapter(1);
344 num_subdevs = vpfe_cfg->num_subdevs;
345 vpfe_dev->sd =
346 kcalloc(num_subdevs, sizeof(struct v4l2_subdev *),
347 GFP_KERNEL);
348 if (!vpfe_dev->sd)
349 return -ENOMEM;
350
351 for (i = 0, k = 0; i < num_subdevs; i++) {
352 sdinfo = &vpfe_cfg->sub_devs[i];
353
354
355
356
357
358
359
360 if (interface == sdinfo->is_camera) {
361
362 if (vpfe_cfg->setup_input &&
363 vpfe_cfg->setup_input(sdinfo->grp_id) < 0) {
364 ret = -EFAULT;
365 v4l2_info(&vpfe_dev->v4l2_dev,
366 "could not setup input for %s\n",
367 sdinfo->module_name);
368 goto probe_sd_out;
369 }
370
371 vpfe_dev->sd[k] =
372 v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
373 i2c_adap, &sdinfo->board_info,
374 NULL);
375 if (vpfe_dev->sd[k]) {
376 v4l2_info(&vpfe_dev->v4l2_dev,
377 "v4l2 sub device %s registered\n",
378 sdinfo->module_name);
379
380 vpfe_dev->sd[k]->grp_id = sdinfo->grp_id;
381 k++;
382
383 sdinfo->registered = 1;
384 }
385 } else {
386 v4l2_info(&vpfe_dev->v4l2_dev,
387 "v4l2 sub device %s is not registered\n",
388 sdinfo->module_name);
389 }
390 }
391 vpfe_dev->num_ext_subdevs = k;
392
393 return 0;
394
395probe_sd_out:
396 kzfree(vpfe_dev->sd);
397
398 return ret;
399}
400
401
402
403
404
405
406
407
408static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
409{
410 unsigned int flags = 0;
411 int ret;
412 int i;
413
414
415 ret = register_i2c_devices(vpfe_dev);
416 if (ret)
417 return ret;
418
419
420 ret = vpfe_isif_register_entities(&vpfe_dev->vpfe_isif,
421 &vpfe_dev->v4l2_dev);
422 if (ret)
423 return ret;
424
425 ret = vpfe_ipipeif_register_entities(&vpfe_dev->vpfe_ipipeif,
426 &vpfe_dev->v4l2_dev);
427 if (ret)
428 goto out_isif_register;
429
430 ret = vpfe_ipipe_register_entities(&vpfe_dev->vpfe_ipipe,
431 &vpfe_dev->v4l2_dev);
432 if (ret)
433 goto out_ipipeif_register;
434
435 ret = vpfe_resizer_register_entities(&vpfe_dev->vpfe_resizer,
436 &vpfe_dev->v4l2_dev);
437 if (ret)
438 goto out_ipipe_register;
439
440
441 for (i = 0; i < vpfe_dev->num_ext_subdevs; i++)
442
443
444
445
446 if (vpfe_dev->sd[i]->entity.num_pads) {
447 ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
448 0, &vpfe_dev->vpfe_isif.subdev.entity,
449 0, flags);
450 if (ret < 0)
451 goto out_resizer_register;
452 }
453
454 ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
455 &vpfe_dev->vpfe_ipipeif.subdev.entity,
456 0, flags);
457 if (ret < 0)
458 goto out_resizer_register;
459
460 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
461 &vpfe_dev->vpfe_ipipe.subdev.entity,
462 0, flags);
463 if (ret < 0)
464 goto out_resizer_register;
465
466 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
467 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
468 0, flags);
469 if (ret < 0)
470 goto out_resizer_register;
471
472 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
473 &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
474 0, flags);
475 if (ret < 0)
476 goto out_resizer_register;
477
478 ret = v4l2_device_register_subdev_nodes(&vpfe_dev->v4l2_dev);
479 if (ret < 0)
480 goto out_resizer_register;
481
482 return 0;
483
484out_resizer_register:
485 vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
486out_ipipe_register:
487 vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
488out_ipipeif_register:
489 vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
490out_isif_register:
491 vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
492
493 return ret;
494}
495
496
497
498
499
500
501
502static void vpfe_unregister_entities(struct vpfe_device *vpfe_dev)
503{
504 vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
505 vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
506 vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
507 vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
508}
509
510
511
512
513
514
515
516
517static void vpfe_cleanup_modules(struct vpfe_device *vpfe_dev,
518 struct platform_device *pdev)
519{
520 vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
521 vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
522 vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
523 vpfe_resizer_cleanup(&vpfe_dev->vpfe_resizer, pdev);
524}
525
526
527
528
529
530
531
532
533static int vpfe_initialize_modules(struct vpfe_device *vpfe_dev,
534 struct platform_device *pdev)
535{
536 int ret;
537
538 ret = vpfe_isif_init(&vpfe_dev->vpfe_isif, pdev);
539 if (ret)
540 return ret;
541
542 ret = vpfe_ipipeif_init(&vpfe_dev->vpfe_ipipeif, pdev);
543 if (ret)
544 goto out_isif_init;
545
546 ret = vpfe_ipipe_init(&vpfe_dev->vpfe_ipipe, pdev);
547 if (ret)
548 goto out_ipipeif_init;
549
550 ret = vpfe_resizer_init(&vpfe_dev->vpfe_resizer, pdev);
551 if (ret)
552 goto out_ipipe_init;
553
554 return 0;
555
556out_ipipe_init:
557 vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
558out_ipipeif_init:
559 vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
560out_isif_init:
561 vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
562
563 return ret;
564}
565
566
567
568
569
570
571
572
573static int vpfe_probe(struct platform_device *pdev)
574{
575 struct vpfe_device *vpfe_dev;
576 struct resource *res1;
577 int ret = -ENOMEM;
578
579 vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
580 if (!vpfe_dev)
581 return ret;
582
583 if (pdev->dev.platform_data == NULL) {
584 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
585 ret = -ENOENT;
586 goto probe_free_dev_mem;
587 }
588
589 vpfe_dev->cfg = pdev->dev.platform_data;
590 if (vpfe_dev->cfg->card_name == NULL ||
591 vpfe_dev->cfg->sub_devs == NULL) {
592 v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
593 ret = -ENOENT;
594 goto probe_free_dev_mem;
595 }
596
597
598 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
599 if (!res1) {
600 v4l2_err(pdev->dev.driver,
601 "Unable to get interrupt for VINT0\n");
602 ret = -ENOENT;
603 goto probe_free_dev_mem;
604 }
605 vpfe_dev->ccdc_irq0 = res1->start;
606
607
608 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
609 if (!res1) {
610 v4l2_err(pdev->dev.driver,
611 "Unable to get interrupt for VINT1\n");
612 ret = -ENOENT;
613 goto probe_free_dev_mem;
614 }
615 vpfe_dev->ccdc_irq1 = res1->start;
616
617
618 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
619 if (!res1) {
620 v4l2_err(pdev->dev.driver,
621 "Unable to get interrupt for DMA\n");
622 ret = -ENOENT;
623 goto probe_free_dev_mem;
624 }
625 vpfe_dev->imp_dma_irq = res1->start;
626
627 vpfe_dev->pdev = &pdev->dev;
628
629
630 ret = vpfe_enable_clock(vpfe_dev);
631 if (ret)
632 goto probe_free_dev_mem;
633
634 ret = vpfe_initialize_modules(vpfe_dev, pdev);
635 if (ret)
636 goto probe_disable_clock;
637
638 vpfe_dev->media_dev.dev = vpfe_dev->pdev;
639 strscpy((char *)&vpfe_dev->media_dev.model, "davinci-media",
640 sizeof(vpfe_dev->media_dev.model));
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
658 platform_set_drvdata(pdev, vpfe_dev);
659
660 ret = vpfe_register_entities(vpfe_dev);
661 if (ret)
662 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
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, "%s\n", __func__);
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,
711 },
712 .probe = vpfe_probe,
713 .remove = vpfe_remove,
714};
715
716module_platform_driver(vpfe_driver);
717