diff options
author | Muralidharan Karicheri <m-karicheri2@ti.com> | 2009-09-16 13:15:30 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-09-16 13:28:46 -0400 |
commit | 85609c1ccda64af7d7c277469183f20e4f3b69c3 (patch) | |
tree | a9d7ca458764fc0b8bb4f4f23736b9cf861e3974 | |
parent | 51e68e27d310034332b67a6762914af9589b3db5 (diff) |
DaVinci: DM646x - platform changes for vpif capture and display drivers
VPIF display changes (Chaithrika)
Add platform device and resource structures. Also define a platform specific
clock setup function that can be accessed by the driver to configure the clock
and CPLD.
VPIF caputure changes (Murali)
1) Modify vpif_subdev_info to add board_info, routing information and
vpif interface configuration. Remove addr since it is part of
board_info
2) Add code to setup channel mode and input decoder path for vpif
capture driver
Also incorporated comments against version v0 of the patch series and
added a spinlock to protect writes to common registers
Tested on DM6467 on channel 0 using TVP514x. Following bootargs used
for drivers:
vpif_capture.ch0_bufsize=829440 vpif_display.ch2_bufsize=829440
Signed-off-by: Manjunath Hadli <mrh@ti.com>
Signed-off-by: Brijesh Jadav <brijesh.j@ti.com>
Signed-off-by: Chaithrika U S <chaithrika@ti.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Muralidharan Karicheri <m-karicheri2@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-davinci/board-dm646x-evm.c | 319 | ||||
-rw-r--r-- | arch/arm/mach-davinci/dm646x.c | 104 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/dm646x.h | 59 |
3 files changed, 481 insertions, 1 deletions
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 20547049b489..24e0e13b1492 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/i2c/pcf857x.h> | 34 | #include <linux/i2c/pcf857x.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | 36 | ||
37 | #include <media/tvp514x.h> | ||
38 | |||
37 | #include <asm/setup.h> | 39 | #include <asm/setup.h> |
38 | #include <asm/mach-types.h> | 40 | #include <asm/mach-types.h> |
39 | #include <asm/mach/arch.h> | 41 | #include <asm/mach/arch.h> |
@@ -62,6 +64,30 @@ | |||
62 | #define DM646X_EVM_PHY_MASK (0x2) | 64 | #define DM646X_EVM_PHY_MASK (0x2) |
63 | #define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ | 65 | #define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ |
64 | 66 | ||
67 | #define VIDCLKCTL_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x38) | ||
68 | #define VSCLKDIS_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x6c) | ||
69 | #define VCH2CLK_MASK (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8)) | ||
70 | #define VCH2CLK_SYSCLK8 (BIT(9)) | ||
71 | #define VCH2CLK_AUXCLK (BIT(9) | BIT(8)) | ||
72 | #define VCH3CLK_MASK (BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12)) | ||
73 | #define VCH3CLK_SYSCLK8 (BIT(13)) | ||
74 | #define VCH3CLK_AUXCLK (BIT(14) | BIT(13)) | ||
75 | |||
76 | #define VIDCH2CLK (BIT(10)) | ||
77 | #define VIDCH3CLK (BIT(11)) | ||
78 | #define VIDCH1CLK (BIT(4)) | ||
79 | #define TVP7002_INPUT (BIT(4)) | ||
80 | #define TVP5147_INPUT (~BIT(4)) | ||
81 | #define VPIF_INPUT_ONE_CHANNEL (BIT(5)) | ||
82 | #define VPIF_INPUT_TWO_CHANNEL (~BIT(5)) | ||
83 | #define TVP5147_CH0 "tvp514x-0" | ||
84 | #define TVP5147_CH1 "tvp514x-1" | ||
85 | |||
86 | static void __iomem *vpif_vidclkctl_reg; | ||
87 | static void __iomem *vpif_vsclkdis_reg; | ||
88 | /* spin lock for updating above registers */ | ||
89 | static spinlock_t vpif_reg_lock; | ||
90 | |||
65 | static struct davinci_uart_config uart_config __initdata = { | 91 | static struct davinci_uart_config uart_config __initdata = { |
66 | .enabled_uarts = (1 << 0), | 92 | .enabled_uarts = (1 << 0), |
67 | }; | 93 | }; |
@@ -287,6 +313,40 @@ static struct snd_platform_data dm646x_evm_snd_data[] = { | |||
287 | }, | 313 | }, |
288 | }; | 314 | }; |
289 | 315 | ||
316 | static struct i2c_client *cpld_client; | ||
317 | |||
318 | static int cpld_video_probe(struct i2c_client *client, | ||
319 | const struct i2c_device_id *id) | ||
320 | { | ||
321 | cpld_client = client; | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int __devexit cpld_video_remove(struct i2c_client *client) | ||
326 | { | ||
327 | cpld_client = NULL; | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static const struct i2c_device_id cpld_video_id[] = { | ||
332 | { "cpld_video", 0 }, | ||
333 | { } | ||
334 | }; | ||
335 | |||
336 | static struct i2c_driver cpld_video_driver = { | ||
337 | .driver = { | ||
338 | .name = "cpld_video", | ||
339 | }, | ||
340 | .probe = cpld_video_probe, | ||
341 | .remove = cpld_video_remove, | ||
342 | .id_table = cpld_video_id, | ||
343 | }; | ||
344 | |||
345 | static void evm_init_cpld(void) | ||
346 | { | ||
347 | i2c_add_driver(&cpld_video_driver); | ||
348 | } | ||
349 | |||
290 | static struct i2c_board_info __initdata i2c_info[] = { | 350 | static struct i2c_board_info __initdata i2c_info[] = { |
291 | { | 351 | { |
292 | I2C_BOARD_INFO("24c256", 0x50), | 352 | I2C_BOARD_INFO("24c256", 0x50), |
@@ -301,7 +361,10 @@ static struct i2c_board_info __initdata i2c_info[] = { | |||
301 | }, | 361 | }, |
302 | { | 362 | { |
303 | I2C_BOARD_INFO("tlv320aic33", 0x18), | 363 | I2C_BOARD_INFO("tlv320aic33", 0x18), |
304 | } | 364 | }, |
365 | { | ||
366 | I2C_BOARD_INFO("cpld_video", 0x3b), | ||
367 | }, | ||
305 | }; | 368 | }; |
306 | 369 | ||
307 | static struct davinci_i2c_platform_data i2c_pdata = { | 370 | static struct davinci_i2c_platform_data i2c_pdata = { |
@@ -309,11 +372,265 @@ static struct davinci_i2c_platform_data i2c_pdata = { | |||
309 | .bus_delay = 0 /* usec */, | 372 | .bus_delay = 0 /* usec */, |
310 | }; | 373 | }; |
311 | 374 | ||
375 | static int set_vpif_clock(int mux_mode, int hd) | ||
376 | { | ||
377 | unsigned long flags; | ||
378 | unsigned int value; | ||
379 | int val = 0; | ||
380 | int err = 0; | ||
381 | |||
382 | if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg || !cpld_client) | ||
383 | return -ENXIO; | ||
384 | |||
385 | /* disable the clock */ | ||
386 | spin_lock_irqsave(&vpif_reg_lock, flags); | ||
387 | value = __raw_readl(vpif_vsclkdis_reg); | ||
388 | value |= (VIDCH3CLK | VIDCH2CLK); | ||
389 | __raw_writel(value, vpif_vsclkdis_reg); | ||
390 | spin_unlock_irqrestore(&vpif_reg_lock, flags); | ||
391 | |||
392 | val = i2c_smbus_read_byte(cpld_client); | ||
393 | if (val < 0) | ||
394 | return val; | ||
395 | |||
396 | if (mux_mode == 1) | ||
397 | val &= ~0x40; | ||
398 | else | ||
399 | val |= 0x40; | ||
400 | |||
401 | err = i2c_smbus_write_byte(cpld_client, val); | ||
402 | if (err) | ||
403 | return err; | ||
404 | |||
405 | value = __raw_readl(vpif_vidclkctl_reg); | ||
406 | value &= ~(VCH2CLK_MASK); | ||
407 | value &= ~(VCH3CLK_MASK); | ||
408 | |||
409 | if (hd >= 1) | ||
410 | value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8); | ||
411 | else | ||
412 | value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK); | ||
413 | |||
414 | __raw_writel(value, vpif_vidclkctl_reg); | ||
415 | |||
416 | spin_lock_irqsave(&vpif_reg_lock, flags); | ||
417 | value = __raw_readl(vpif_vsclkdis_reg); | ||
418 | /* enable the clock */ | ||
419 | value &= ~(VIDCH3CLK | VIDCH2CLK); | ||
420 | __raw_writel(value, vpif_vsclkdis_reg); | ||
421 | spin_unlock_irqrestore(&vpif_reg_lock, flags); | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static struct vpif_subdev_info dm646x_vpif_subdev[] = { | ||
427 | { | ||
428 | .name = "adv7343", | ||
429 | .board_info = { | ||
430 | I2C_BOARD_INFO("adv7343", 0x2a), | ||
431 | }, | ||
432 | }, | ||
433 | { | ||
434 | .name = "ths7303", | ||
435 | .board_info = { | ||
436 | I2C_BOARD_INFO("ths7303", 0x2c), | ||
437 | }, | ||
438 | }, | ||
439 | }; | ||
440 | |||
441 | static const char *output[] = { | ||
442 | "Composite", | ||
443 | "Component", | ||
444 | "S-Video", | ||
445 | }; | ||
446 | |||
447 | static struct vpif_display_config dm646x_vpif_display_config = { | ||
448 | .set_clock = set_vpif_clock, | ||
449 | .subdevinfo = dm646x_vpif_subdev, | ||
450 | .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev), | ||
451 | .output = output, | ||
452 | .output_count = ARRAY_SIZE(output), | ||
453 | .card_name = "DM646x EVM", | ||
454 | }; | ||
455 | |||
456 | /** | ||
457 | * setup_vpif_input_path() | ||
458 | * @channel: channel id (0 - CH0, 1 - CH1) | ||
459 | * @sub_dev_name: ptr sub device name | ||
460 | * | ||
461 | * This will set vpif input to capture data from tvp514x or | ||
462 | * tvp7002. | ||
463 | */ | ||
464 | static int setup_vpif_input_path(int channel, const char *sub_dev_name) | ||
465 | { | ||
466 | int err = 0; | ||
467 | int val; | ||
468 | |||
469 | /* for channel 1, we don't do anything */ | ||
470 | if (channel != 0) | ||
471 | return 0; | ||
472 | |||
473 | if (!cpld_client) | ||
474 | return -ENXIO; | ||
475 | |||
476 | val = i2c_smbus_read_byte(cpld_client); | ||
477 | if (val < 0) | ||
478 | return val; | ||
479 | |||
480 | if (!strcmp(sub_dev_name, TVP5147_CH0) || | ||
481 | !strcmp(sub_dev_name, TVP5147_CH1)) | ||
482 | val &= TVP5147_INPUT; | ||
483 | else | ||
484 | val |= TVP7002_INPUT; | ||
485 | |||
486 | err = i2c_smbus_write_byte(cpld_client, val); | ||
487 | if (err) | ||
488 | return err; | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * setup_vpif_input_channel_mode() | ||
494 | * @mux_mode: mux mode. 0 - 1 channel or (1) - 2 channel | ||
495 | * | ||
496 | * This will setup input mode to one channel (TVP7002) or 2 channel (TVP5147) | ||
497 | */ | ||
498 | static int setup_vpif_input_channel_mode(int mux_mode) | ||
499 | { | ||
500 | unsigned long flags; | ||
501 | int err = 0; | ||
502 | int val; | ||
503 | u32 value; | ||
504 | |||
505 | if (!vpif_vsclkdis_reg || !cpld_client) | ||
506 | return -ENXIO; | ||
507 | |||
508 | val = i2c_smbus_read_byte(cpld_client); | ||
509 | if (val < 0) | ||
510 | return val; | ||
511 | |||
512 | spin_lock_irqsave(&vpif_reg_lock, flags); | ||
513 | value = __raw_readl(vpif_vsclkdis_reg); | ||
514 | if (mux_mode) { | ||
515 | val &= VPIF_INPUT_TWO_CHANNEL; | ||
516 | value |= VIDCH1CLK; | ||
517 | } else { | ||
518 | val |= VPIF_INPUT_ONE_CHANNEL; | ||
519 | value &= ~VIDCH1CLK; | ||
520 | } | ||
521 | __raw_writel(value, vpif_vsclkdis_reg); | ||
522 | spin_unlock_irqrestore(&vpif_reg_lock, flags); | ||
523 | |||
524 | err = i2c_smbus_write_byte(cpld_client, val); | ||
525 | if (err) | ||
526 | return err; | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static struct tvp514x_platform_data tvp5146_pdata = { | ||
532 | .clk_polarity = 0, | ||
533 | .hs_polarity = 1, | ||
534 | .vs_polarity = 1 | ||
535 | }; | ||
536 | |||
537 | #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) | ||
538 | |||
539 | static struct vpif_subdev_info vpif_capture_sdev_info[] = { | ||
540 | { | ||
541 | .name = TVP5147_CH0, | ||
542 | .board_info = { | ||
543 | I2C_BOARD_INFO("tvp5146", 0x5d), | ||
544 | .platform_data = &tvp5146_pdata, | ||
545 | }, | ||
546 | .input = INPUT_CVBS_VI2B, | ||
547 | .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, | ||
548 | .can_route = 1, | ||
549 | .vpif_if = { | ||
550 | .if_type = VPIF_IF_BT656, | ||
551 | .hd_pol = 1, | ||
552 | .vd_pol = 1, | ||
553 | .fid_pol = 0, | ||
554 | }, | ||
555 | }, | ||
556 | { | ||
557 | .name = TVP5147_CH1, | ||
558 | .board_info = { | ||
559 | I2C_BOARD_INFO("tvp5146", 0x5c), | ||
560 | .platform_data = &tvp5146_pdata, | ||
561 | }, | ||
562 | .input = INPUT_SVIDEO_VI2C_VI1C, | ||
563 | .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, | ||
564 | .can_route = 1, | ||
565 | .vpif_if = { | ||
566 | .if_type = VPIF_IF_BT656, | ||
567 | .hd_pol = 1, | ||
568 | .vd_pol = 1, | ||
569 | .fid_pol = 0, | ||
570 | }, | ||
571 | }, | ||
572 | }; | ||
573 | |||
574 | static const struct vpif_input dm6467_ch0_inputs[] = { | ||
575 | { | ||
576 | .input = { | ||
577 | .index = 0, | ||
578 | .name = "Composite", | ||
579 | .type = V4L2_INPUT_TYPE_CAMERA, | ||
580 | .std = TVP514X_STD_ALL, | ||
581 | }, | ||
582 | .subdev_name = TVP5147_CH0, | ||
583 | }, | ||
584 | }; | ||
585 | |||
586 | static const struct vpif_input dm6467_ch1_inputs[] = { | ||
587 | { | ||
588 | .input = { | ||
589 | .index = 0, | ||
590 | .name = "S-Video", | ||
591 | .type = V4L2_INPUT_TYPE_CAMERA, | ||
592 | .std = TVP514X_STD_ALL, | ||
593 | }, | ||
594 | .subdev_name = TVP5147_CH1, | ||
595 | }, | ||
596 | }; | ||
597 | |||
598 | static struct vpif_capture_config dm646x_vpif_capture_cfg = { | ||
599 | .setup_input_path = setup_vpif_input_path, | ||
600 | .setup_input_channel_mode = setup_vpif_input_channel_mode, | ||
601 | .subdev_info = vpif_capture_sdev_info, | ||
602 | .subdev_count = ARRAY_SIZE(vpif_capture_sdev_info), | ||
603 | .chan_config[0] = { | ||
604 | .inputs = dm6467_ch0_inputs, | ||
605 | .input_count = ARRAY_SIZE(dm6467_ch0_inputs), | ||
606 | }, | ||
607 | .chan_config[1] = { | ||
608 | .inputs = dm6467_ch1_inputs, | ||
609 | .input_count = ARRAY_SIZE(dm6467_ch1_inputs), | ||
610 | }, | ||
611 | }; | ||
612 | |||
613 | static void __init evm_init_video(void) | ||
614 | { | ||
615 | vpif_vidclkctl_reg = ioremap(VIDCLKCTL_OFFSET, 4); | ||
616 | vpif_vsclkdis_reg = ioremap(VSCLKDIS_OFFSET, 4); | ||
617 | if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg) { | ||
618 | pr_err("Can't map VPIF VIDCLKCTL or VSCLKDIS registers\n"); | ||
619 | return; | ||
620 | } | ||
621 | spin_lock_init(&vpif_reg_lock); | ||
622 | |||
623 | dm646x_setup_vpif(&dm646x_vpif_display_config, | ||
624 | &dm646x_vpif_capture_cfg); | ||
625 | } | ||
626 | |||
312 | static void __init evm_init_i2c(void) | 627 | static void __init evm_init_i2c(void) |
313 | { | 628 | { |
314 | davinci_init_i2c(&i2c_pdata); | 629 | davinci_init_i2c(&i2c_pdata); |
315 | i2c_add_driver(&dm6467evm_cpld_driver); | 630 | i2c_add_driver(&dm6467evm_cpld_driver); |
316 | i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); | 631 | i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); |
632 | evm_init_cpld(); | ||
633 | evm_init_video(); | ||
317 | } | 634 | } |
318 | 635 | ||
319 | static void __init davinci_map_io(void) | 636 | static void __init davinci_map_io(void) |
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 8fa28039f27e..0976049c7b3b 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c | |||
@@ -32,6 +32,15 @@ | |||
32 | #include "clock.h" | 32 | #include "clock.h" |
33 | #include "mux.h" | 33 | #include "mux.h" |
34 | 34 | ||
35 | #define DAVINCI_VPIF_BASE (0x01C12000) | ||
36 | #define VDD3P3V_PWDN_OFFSET (0x48) | ||
37 | #define VSCLKDIS_OFFSET (0x6C) | ||
38 | |||
39 | #define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\ | ||
40 | BIT_MASK(0)) | ||
41 | #define VSCLKDIS_MASK (BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\ | ||
42 | BIT_MASK(8)) | ||
43 | |||
35 | /* | 44 | /* |
36 | * Device specific clocks | 45 | * Device specific clocks |
37 | */ | 46 | */ |
@@ -686,6 +695,75 @@ static struct platform_device dm646x_dit_device = { | |||
686 | .id = -1, | 695 | .id = -1, |
687 | }; | 696 | }; |
688 | 697 | ||
698 | static u64 vpif_dma_mask = DMA_BIT_MASK(32); | ||
699 | |||
700 | static struct resource vpif_resource[] = { | ||
701 | { | ||
702 | .start = DAVINCI_VPIF_BASE, | ||
703 | .end = DAVINCI_VPIF_BASE + 0x03ff, | ||
704 | .flags = IORESOURCE_MEM, | ||
705 | } | ||
706 | }; | ||
707 | |||
708 | static struct platform_device vpif_dev = { | ||
709 | .name = "vpif", | ||
710 | .id = -1, | ||
711 | .dev = { | ||
712 | .dma_mask = &vpif_dma_mask, | ||
713 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
714 | }, | ||
715 | .resource = vpif_resource, | ||
716 | .num_resources = ARRAY_SIZE(vpif_resource), | ||
717 | }; | ||
718 | |||
719 | static struct resource vpif_display_resource[] = { | ||
720 | { | ||
721 | .start = IRQ_DM646X_VP_VERTINT2, | ||
722 | .end = IRQ_DM646X_VP_VERTINT2, | ||
723 | .flags = IORESOURCE_IRQ, | ||
724 | }, | ||
725 | { | ||
726 | .start = IRQ_DM646X_VP_VERTINT3, | ||
727 | .end = IRQ_DM646X_VP_VERTINT3, | ||
728 | .flags = IORESOURCE_IRQ, | ||
729 | }, | ||
730 | }; | ||
731 | |||
732 | static struct platform_device vpif_display_dev = { | ||
733 | .name = "vpif_display", | ||
734 | .id = -1, | ||
735 | .dev = { | ||
736 | .dma_mask = &vpif_dma_mask, | ||
737 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
738 | }, | ||
739 | .resource = vpif_display_resource, | ||
740 | .num_resources = ARRAY_SIZE(vpif_display_resource), | ||
741 | }; | ||
742 | |||
743 | static struct resource vpif_capture_resource[] = { | ||
744 | { | ||
745 | .start = IRQ_DM646X_VP_VERTINT0, | ||
746 | .end = IRQ_DM646X_VP_VERTINT0, | ||
747 | .flags = IORESOURCE_IRQ, | ||
748 | }, | ||
749 | { | ||
750 | .start = IRQ_DM646X_VP_VERTINT1, | ||
751 | .end = IRQ_DM646X_VP_VERTINT1, | ||
752 | .flags = IORESOURCE_IRQ, | ||
753 | }, | ||
754 | }; | ||
755 | |||
756 | static struct platform_device vpif_capture_dev = { | ||
757 | .name = "vpif_capture", | ||
758 | .id = -1, | ||
759 | .dev = { | ||
760 | .dma_mask = &vpif_dma_mask, | ||
761 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
762 | }, | ||
763 | .resource = vpif_capture_resource, | ||
764 | .num_resources = ARRAY_SIZE(vpif_capture_resource), | ||
765 | }; | ||
766 | |||
689 | /*----------------------------------------------------------------------*/ | 767 | /*----------------------------------------------------------------------*/ |
690 | 768 | ||
691 | static struct map_desc dm646x_io_desc[] = { | 769 | static struct map_desc dm646x_io_desc[] = { |
@@ -814,6 +892,32 @@ void __init dm646x_init_mcasp1(struct snd_platform_data *pdata) | |||
814 | platform_device_register(&dm646x_dit_device); | 892 | platform_device_register(&dm646x_dit_device); |
815 | } | 893 | } |
816 | 894 | ||
895 | void dm646x_setup_vpif(struct vpif_display_config *display_config, | ||
896 | struct vpif_capture_config *capture_config) | ||
897 | { | ||
898 | unsigned int value; | ||
899 | void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); | ||
900 | |||
901 | value = __raw_readl(base + VSCLKDIS_OFFSET); | ||
902 | value &= ~VSCLKDIS_MASK; | ||
903 | __raw_writel(value, base + VSCLKDIS_OFFSET); | ||
904 | |||
905 | value = __raw_readl(base + VDD3P3V_PWDN_OFFSET); | ||
906 | value &= ~VDD3P3V_VID_MASK; | ||
907 | __raw_writel(value, base + VDD3P3V_PWDN_OFFSET); | ||
908 | |||
909 | davinci_cfg_reg(DM646X_STSOMUX_DISABLE); | ||
910 | davinci_cfg_reg(DM646X_STSIMUX_DISABLE); | ||
911 | davinci_cfg_reg(DM646X_PTSOMUX_DISABLE); | ||
912 | davinci_cfg_reg(DM646X_PTSIMUX_DISABLE); | ||
913 | |||
914 | vpif_display_dev.dev.platform_data = display_config; | ||
915 | vpif_capture_dev.dev.platform_data = capture_config; | ||
916 | platform_device_register(&vpif_dev); | ||
917 | platform_device_register(&vpif_display_dev); | ||
918 | platform_device_register(&vpif_capture_dev); | ||
919 | } | ||
920 | |||
817 | void __init dm646x_init(void) | 921 | void __init dm646x_init(void) |
818 | { | 922 | { |
819 | davinci_common_init(&davinci_soc_info_dm646x); | 923 | davinci_common_init(&davinci_soc_info_dm646x); |
diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index feb1e02cdbd8..8cec746ae9d2 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
15 | #include <mach/emac.h> | 15 | #include <mach/emac.h> |
16 | #include <mach/asp.h> | 16 | #include <mach/asp.h> |
17 | #include <linux/i2c.h> | ||
18 | #include <linux/videodev2.h> | ||
17 | 19 | ||
18 | #define DM646X_EMAC_BASE (0x01C80000) | 20 | #define DM646X_EMAC_BASE (0x01C80000) |
19 | #define DM646X_EMAC_CNTRL_OFFSET (0x0000) | 21 | #define DM646X_EMAC_CNTRL_OFFSET (0x0000) |
@@ -29,4 +31,61 @@ void __init dm646x_init_ide(void); | |||
29 | void __init dm646x_init_mcasp0(struct snd_platform_data *pdata); | 31 | void __init dm646x_init_mcasp0(struct snd_platform_data *pdata); |
30 | void __init dm646x_init_mcasp1(struct snd_platform_data *pdata); | 32 | void __init dm646x_init_mcasp1(struct snd_platform_data *pdata); |
31 | 33 | ||
34 | void dm646x_video_init(void); | ||
35 | |||
36 | enum vpif_if_type { | ||
37 | VPIF_IF_BT656, | ||
38 | VPIF_IF_BT1120, | ||
39 | VPIF_IF_RAW_BAYER | ||
40 | }; | ||
41 | |||
42 | struct vpif_interface { | ||
43 | enum vpif_if_type if_type; | ||
44 | unsigned hd_pol:1; | ||
45 | unsigned vd_pol:1; | ||
46 | unsigned fid_pol:1; | ||
47 | }; | ||
48 | |||
49 | struct vpif_subdev_info { | ||
50 | const char *name; | ||
51 | struct i2c_board_info board_info; | ||
52 | u32 input; | ||
53 | u32 output; | ||
54 | unsigned can_route:1; | ||
55 | struct vpif_interface vpif_if; | ||
56 | }; | ||
57 | |||
58 | struct vpif_display_config { | ||
59 | int (*set_clock)(int, int); | ||
60 | struct vpif_subdev_info *subdevinfo; | ||
61 | int subdev_count; | ||
62 | const char **output; | ||
63 | int output_count; | ||
64 | const char *card_name; | ||
65 | }; | ||
66 | |||
67 | struct vpif_input { | ||
68 | struct v4l2_input input; | ||
69 | const char *subdev_name; | ||
70 | }; | ||
71 | |||
72 | #define VPIF_CAPTURE_MAX_CHANNELS 2 | ||
73 | |||
74 | struct vpif_capture_chan_config { | ||
75 | const struct vpif_input *inputs; | ||
76 | int input_count; | ||
77 | }; | ||
78 | |||
79 | struct vpif_capture_config { | ||
80 | int (*setup_input_channel_mode)(int); | ||
81 | int (*setup_input_path)(int, const char *); | ||
82 | struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS]; | ||
83 | struct vpif_subdev_info *subdev_info; | ||
84 | int subdev_count; | ||
85 | const char *card_name; | ||
86 | }; | ||
87 | |||
88 | void dm646x_setup_vpif(struct vpif_display_config *, | ||
89 | struct vpif_capture_config *); | ||
90 | |||
32 | #endif /* __ASM_ARCH_DM646X_H */ | 91 | #endif /* __ASM_ARCH_DM646X_H */ |