This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TVP5158 driver

Other Parts Discussed in Thread: TVP5158

Development environment:
SDK: DVRRDK 02.00.00.24 (McFW) with PSP 04.00.01.13
Board: UDWORKS DM8168

I have developed a system to process images captured with (1CH) analog cameras.
I have been using the McFW and TVP5158, how to get the (RGB888) I do not know the image map.

You are reading the E2E, there was a such as how to use the () mmap, could not be retrieved.
 http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/t/153849.aspx

If you use the DM8168 as image processing board, or has developed how you?

In EZSDK, plans to develop a TVP5158 + V4L2 capture driver available?
I'm sorry rudimentary questions.

  • Hi,

    target board: UDWORKS DM8168(tvp5158 decorder)
    sdk: ezsdk 5.03.01.15 + PSP4.0.1.13 patch2(custom)

    1.I has been ported to ezsdk for the target-board. With reference to (02.00.00.24_linux-psp-dvr-01.00.01.13) DVRRDK.
    2.create tvp5158driver(with reference to tvp7002driver) 
    3.Linux boot
    4.Driver load
    5.Run the example program saLoopBack.c
    5.Run the following command.

    echo 0 > /sys/devices/platoform/vpss/display0/enabled
    echo 1080p-60 > /sys/devices/platoform/vpss/display0/mode

    3.Linux boot

    bootargs 'mem=254M console=ttyO2,115200n8 root=/dev/nfs rw rootfstype=jffs2 \
    nfsroot=192.168.1.15:/home/pal/targetfs/rfs 
    ip=192.168.1.200:192.168.1.15:192.168.1.1:255.255.255.0::eth0:off 
    vram=50M notifyk.vpssm3_sva=0xBF900000'

    Please see the log.

    U-Boot 2010.06 (Feb 07 2012 - 18:52:29)
    
    TI8168-GP rev 1.1
    
    ARM clk: 987MHz
    DDR clk: 796MHz
    
    I2C:   ready
    DRAM:  2 GiB
    NAND:  256 MiB
    MMC:   OMAP SD/MMC: 0
    Net:   Ethernet PHY: GENERIC @ 0x01
    DaVinci EMAC
    Hit any key to stop autoboot:  0
    
    NAND read: device 0 offset 0x280000, size 0x300000
     3145728 bytes read: OK
    ## Booting kernel from Legacy Image at 81000000 ...
       Image Name:   Linux-2.6.37
       Created:      2012-06-13   9:29:03 UTC
       Image Type:   ARM Linux Kernel Image (uncompressed)
       Data Size:    2357476 Bytes = 2.2 MiB
       Load Address: 80008000
       Entry Point:  80008000
       Verifying Checksum ... OK
       Loading Kernel Image ... OK
    OK
    
    Starting kernel ...
    
    Uncompressing Linux... done, booting the kernel.
    Linux version 2.6.37 (pal@pal-laptop) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #8 Wed Jun 13 18:28:52 JST 2012
    CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7f
    CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache
    Machine: ti8168evm
    vram size = 52428800 at 0x0
    reserved size = 52428800 at 0x0
    FB: Reserving 52428800 bytes SDRAM for VRAM
    Memory policy: ECC disabled, Data cache writeback
    OMAP chip is TI8168 1.1
    Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 51716
    Kernel command line: mem=254M console=ttyO2,115200n8 root=/dev/nfs rw rootfstype=jffs2 nfsroot=192.168.1.15:/home/pal/targetfs/rfs ip=192.168.1.200:192.168.1.15:192.168.1.1:255.255.255.0::eth0:off vram=50M notifyk.vpssm3_sva=0xBF900000
    PID hash table entries: 1024 (order: 0, 4096 bytes)
    Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
    Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
    Memory: 204MB = 204MB total
    Memory: 201532k/201532k available, 58564k reserved, 0K highmem
    Virtual kernel memory layout:
        vector  : 0xffff0000 - 0xffff1000   (   4 kB)
        fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
        DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
        vmalloc : 0xd0000000 - 0xf8000000   ( 640 MB)
        lowmem  : 0xc0000000 - 0xcfe00000   ( 254 MB)
        pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
        modules : 0xbf000000 - 0xbfe00000   (  14 MB)
          .init : 0xc0008000 - 0xc0039000   ( 196 kB)
          .text : 0xc0039000 - 0xc0477000   (4344 kB)
          .data : 0xc0478000 - 0xc04bbe00   ( 272 kB)
    SLUB: Genslabs=11, HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
    NR_IRQS:375
    IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts
    Total of 128 interrupts on 1 active controller
    GPMC revision 6.0
    Trying to install interrupt handler for IRQ368
    Trying to install interrupt handler for IRQ369
    Trying to install interrupt handler for IRQ370
    Trying to install interrupt handler for IRQ371
    Trying to install interrupt handler for IRQ372
    Trying to install interrupt handler for IRQ373
    Trying to install interrupt handler for IRQ374
    Trying to install type control for IRQ375
    Trying to set irq flags for IRQ375
    OMAP clockevent source: GPTIMER1 at 27000000 Hz
    Console: colour dummy device 80x30
    Calibrating delay loop... 986.31 BogoMIPS (lpj=4931584)
    pid_max: default: 32768 minimum: 301
    Security Framework initialized
    Mount-cache hash table entries: 512
    CPU: Testing write buffer coherency: ok
    devtmpfs: initialized
    omap_voltage_early_init: voltage driver support not added
    regulator: core version 0.5
    regulator: dummy:
    NET: Registered protocol family 16
    OMAP GPIO hardware version 0.1
    OMAP GPIO hardware version 0.1
    omap_mux_init: Add partition: #1: core, flags: 0
    pass ti8168_evm_init(1180)
    pass ti8168_evm_init(1182)
    3-wired eeprom init done. (H/W ver:05)
    pass ti8168_evm_init(1184)
    _omap_mux_get_by_name: Could not find signal i2c2_scl.i2c2_scl
    _omap_mux_get_by_name: Could not find signal i2c2_sda.i2c2_sda
    pass ti8168_evm_init(1187)
    pass ti8168_evm_init(1193)
    pass ti8168_evm_init(1197)
    pass ti8168_evm_init(1210)
    pass ti8168_evm_init(1227)
    registered ti816x_vpss device
    pass ti8168_evm_init(1231)
    registered TI816x on-chip HDMI device
    pass ti8168_evm_init(1234)
    registered ti816x_sr device
    registered ti81xx_vidout device
    pm_dbg_init: only OMAP3 supported
    bio: create slab <bio-0> at 0
    SCSI subsystem initialized
    usbcore: registered new interface driver usbfs
    usbcore: registered new interface driver hub
    usbcore: registered new device driver usb
    registerd cppi-dma Intr @ IRQ 17
    Cppi41 Init Done
    omap_i2c omap_i2c.1: bus 1 rev4.0 at 400 kHz
    omap_i2c omap_i2c.2: bus 2 rev4.0 at 400 kHz
    Advanced Linux Sound Architecture Driver Version 1.0.23.
    Switching to clocksource gp timer
    musb-hdrc: version 6.0, host, debug=0
    musb-hdrc musb-hdrc.0: dma type: dma-cppi41
    musb-hdrc: kernel must blacklist external hubs
    musb-hdrc musb-hdrc.0: MUSB HDRC host driver
    musb-hdrc musb-hdrc.0: new USB bus registered, assigned bus number 1
    usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
    usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    usb usb1: Product: MUSB HDRC host driver
    usb usb1: Manufacturer: Linux 2.6.37 musb-hcd
    usb usb1: SerialNumber: musb-hdrc.0
    hub 1-0:1.0: USB hub found
    hub 1-0:1.0: 1 port detected
    musb-hdrc musb-hdrc.0: USB Host mode controller at d001e000 using DMA, IRQ 18
    musb-hdrc musb-hdrc.1: dma type: dma-cppi41
    musb-hdrc: kernel must blacklist external hubs
    musb-hdrc musb-hdrc.1: MUSB HDRC host driver
    musb-hdrc musb-hdrc.1: new USB bus registered, assigned bus number 2
    usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
    usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    usb usb2: Product: MUSB HDRC host driver
    usb usb2: Manufacturer: Linux 2.6.37 musb-hcd
    usb usb2: SerialNumber: musb-hdrc.1
    hub 2-0:1.0: USB hub found
    hub 2-0:1.0: 1 port detected
    musb-hdrc musb-hdrc.1: USB Host mode controller at d0028800 using DMA, IRQ 19
    NET: Registered protocol family 2
    IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
    TCP established hash table entries: 8192 (order: 4, 65536 bytes)
    TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
    TCP: Hash tables configured (established 8192 bind 8192)
    TCP reno registered
    UDP hash table entries: 256 (order: 0, 4096 bytes)
    UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
    NET: Registered protocol family 1
    RPC: Registered udp transport module.
    RPC: Registered tcp transport module.
    RPC: Registered tcp NFSv4.1 backchannel transport module.
    NetWinder Floating Point Emulator V0.97 (double precision)
    PMU: registered new PMU device of type 0
    omap-iommu omap-iommu.0: ducati registered
    omap-iommu omap-iommu.1: sys registered
    JFFS2 version 2.2. (NAND) c 2001-2006 Red Hat, Inc.
    msgmni has been set to 393
    io scheduler noop registered
    io scheduler deadline registered
    io scheduler cfq registered (default)
    Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
    omap_uart.0: ttyO0 at MMIO 0x48020000 (irq = 72) is a OMAP UART0
    omap_uart.1: ttyO1 at MMIO 0x48022000 (irq = 73) is a OMAP UART1
    omap_uart.2: ttyO2 at MMIO 0x48024000 (irq = 74) is a OMAP UART2
    console [ttyO2] enabled
    brd: module loaded
    loop: module loaded
    ahci ahci.0: forcing PORTS_IMPL to 0x3
    ahci ahci.0: AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl platform mode
    ahci ahci.0: flags: ncq sntf pm led clo only pmp pio slum part ccc
    scsi0 : ahci_platform
    scsi1 : ahci_platform
    ata1: SATA max UDMA/133 mmio [mem 0x4a140000-0x4a150fff] port 0x100 irq 16
    ata2: SATA max UDMA/133 irq_stat 0x00400040, connection status changed irq 16
    omap2-nand driver initializing
    NAND device: Maf ID: 0xec, Chip ID: 0xda (Samsung, )
     erasesize: 0x20000, writesize: 2048, oobsize: 64
    Creating 6 MTD partitions on "omap2-nand.0":
    0x000000000000-0x000000240000 : "U-Boot"
    0x000000240000-0x000000280000 : "U-Boot Env"
    0x000000280000-0x000000400000 : "U-Boot Logo"
    0x000000400000-0x000000840000 : "Kernel"
    0x000000840000-0x000010840000 : "File System"
    mtd: partition "File System" extends beyond the end of device "omap2-nand.0" -- size truncated to 0xf7c0000
    0x000010000000-0x000010000000 : "Reserved"
    mtd: partition "Reserved" is out of reach -- disabled
    davinci_mdio davinci_mdio.0: davinci mdio revision 1.6
    davinci_mdio davinci_mdio.0: detected phy mask fffffff8
    davinci_mdio.0: probed
    davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver unknown
    davinci_mdio davinci_mdio.0: phy[1]: device 0:01, driver unknown
    davinci_mdio davinci_mdio.0: phy[2]: device 0:02, driver unknown
    usbcore: registered new interface driver cdc_ether
    usbcore: registered new interface driver dm9601
    Initializing USB Mass Storage driver...
    usbcore: registered new interface driver usb-storage
    USB Mass Storage support registered.
    mice: PS/2 mouse device common for all mice
    omap_rtc omap_rtc: rtc core: registered omap_rtc as rtc0
    i2c /dev entries driver
    Linux video capture interface: v2.00
    usbcore: registered new interface driver uvcvideo
    USB Video Class driver (v1.0.0)
    OMAP Watchdog Timer Rev 0x00: initial timeout 60 sec
    usbcore: registered new interface driver usbhid
    usbhid: USB HID core driver
    notify_init : notify drivercreated  for  remote proc id 2 at physical Address 0xbf900000
    usbcore: registered new interface driver snd-usb-audio
    Registered tvp5158 audio codec
    ALSA device list:
      No soundcards found.
    TCP cubic registered
    NET: Registered protocol family 17
    VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
    omap_voltage_late_init: Voltage driver support not added
    Power Management for TI81XX.
    smartreflex-ti816x: ti816x_sr_probe done!
    omap_rtc omap_rtc: setting system clock to 2000-01-01 00:00:00 UTC (946684800)
    mmc0: new high speed SD card at address 0002
    mmcblk0: mmc0:0002 00000 1.86 GiB
     mmcblk0: p1
    davinci_mdio davinci_mdio.0: resetting idled controller
    net eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=0:01, id=1cc914)
    IP-Config: Complete:
         device=eth0, addr=192.168.1.200, mask=255.255.255.0, gw=192.168.1.1,
         host=192.168.1.200, domain=, nis-domain=(none),
         bootserver=192.168.1.15, rootserver=192.168.1.15, rootpath=
    PHY: 0:01 - Link is Up - 100/Full
    ata1: SATA link down (SStatus 0 SControl 300)
    ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
    ata2.15: Port Multiplier 1.2, 0x197b:0x3215 r0, 5 ports, feat 0x5/0xf
    ata2.00: hard resetting link
    ata2.00: SATA link down (SStatus 0 SControl 320)
    ata2.01: hard resetting link
    ata2.01: SATA link up 1.5 Gbps (SStatus 113 SControl 320)
    ata2.02: hard resetting link
    ata2.02: SATA link down (SStatus 0 SControl 320)
    ata2.03: hard resetting link
    ata2.03: SATA link down (SStatus 0 SControl 320)
    ata2.04: hard resetting link
    ata2.04: SATA link down (SStatus 0 SControl 320)
    ata2.01: ATA-8: WDC WD10EALX-009BA0, 15.01H15, max UDMA/133
    ata2.01: 1953525168 sectors, multi 0: LBA48 NCQ (depth 31/32)
    ata2.01: configured for UDMA/133
    ata2: EH complete
    scsi 1:1:0:0: Direct-Access     ATA      WDC WD10EALX-009 15.0 PQ: 0 ANSI: 5
    sd 1:1:0:0: Attached scsi generic sg0 type 0
    sd 1:1:0:0: [sda] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
    sd 1:1:0:0: [sda] Write Protect is off
    sd 1:1:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
     sda: sda1
    sd 1:1:0:0: [sda] Attached SCSI disk
    VFS: Mounted root (nfs filesystem) on device 0:14.
    devtmpfs: mounted
    Freeing init memory: 196K
    INIT: version 2.86 booting
    Error opening /dev/fb0: No such file or directory
    Please wait: booting...
    Starting udev
    udevd (78): /proc/78/oom_adj is deprecated, please use /proc/78/oom_score_adj instead.
    udev: starting version 141
    udevd-event[128]: error changing netif name eth0 to eth1: Device or resource busy
    
    Root filesystem already rw, not remounting
    Caching udev devnodes
    Populating dev cache
    FAT: bogus number of reserved sectors
    VFS: Can't find a valid FAT filesystem on dev sda.
    EXT3-fs (sda): error: can't find ext3 filesystem on dev sda.
    EXT2-fs (sda): error: can't find an ext2 filesystem on dev sda.
    FAT: bogus number of reserved sectors
    VFS: Can't find a valid FAT filesystem on dev sda.
    ISOFS: Unable to identify CD-ROM format.
    FAT: invalid media value (0xb9)
    VFS: Can't find a valid FAT filesystem on dev mmcblk0.
    EXT3-fs (mmcblk0): error: can't find ext3 filesystem on dev mmcblk0.
    EXT2-fs (mmcblk0): error: can't find an ext2 filesystem on dev mmcblk0.
    FAT: invalid media value (0xb9)
    VFS: Can't find a valid FAT filesystem on dev mmcblk0.
    ISOFS: Unable to identify CD-ROM format.
    EXT3-fs: barriers not enabled
    kjournald starting.  Commit interval 5 seconds
    EXT3-fs (sda1): warning: maximal mount count reached, running e2fsck is recommended
    EXT3-fs (sda1): using internal journal
    EXT3-fs (sda1): recovery complete
    EXT3-fs (sda1): mounted filesystem with writeback data mode
    ALSA: Restoring mixer settings...
    NOT configuring network interfaces: / is an NFS mount
    Thu Dec  8 00:55:00 UTC 2011
    INIT: Entering runlevel: 5
    Starting system message bus: dbus.
    Starting telnet daemon.
    Starting syslogd/klogd: done
    Starting thttpd.
    start application
    
     _   _ ___  _   _         _
    | | | |    | ||| |___ ___| | _ ___
    | |_| | |) |  ~  | . |  _| |/_|  -|
    |_____|___ /____/ ___|_| |_| _|-__|
    
    DVR_Netra Board (2011.04)
    
    dvr login:
    

    3.Linux boot
    -----command-----
    insmod syslink.ko
    ./slaveloader startup VPSS-M3 dm816x_hdvpss_v4l2.xem3
    insmod vpss.ko i2c_mode=1
    insmod ti81xxfb.ko debug=1 vram=0:40M,1:1M,2:1M
    insmod ti81xxvo.ko debug=1
    insmod tvp5158.ko debug=1
    insmod ti81xxvin.ko debug=1
    insmod ti81xxhdmi.ko

    -----log-----
    root@dvr:/opt/dvr_rdk/ti816x/kermod# insmod syslink.ko
    SysLink version : 2.00.05.85
    SysLink module created on Date:Jun 7 2012 Time:19:23:42

    root@dvr:/opt/dvr_rdk/ti816x/kermod# ./slaveloader startup VPSS-M3 dm816x_hdvpss_v4l2.xem3
    Attached to slave procId 2.
    Loaded file dm816x_hdvpss_v4l2.xem3 on slave procId 2.
    Started slave procId 2.

    root@dvr:/opt/dvr_rdk/ti816x/kermod# insmod vpss.ko
    [module] vpss probe done.

    root@dvr:/opt/dvr_rdk/ti816x/kermod# insmod ti81xxfb.ko debug=1 vram=0:40M,1:1M,2:1M
    [module] ti81xxfb probe done.

    root@dvr:/opt/dvr_rdk/ti816x/kermod# insmod ti81xxvo.ko debug=1
    root@dvr:/opt/dvr_rdk/ti816x/kermod# insmod tvp5158.ko debug=1
    root@dvr:/opt/dvr_rdk/ti816x/kermod# insmod ti81xxvin.ko debug=1

    tvp5158 2-005c: tvp5158 found @ 0x5c (OMAP I2C adapter)
    tvp5158 2-005c: Rev. 5158 detected.
    tvp5158 2-005c: preset=8
    ti81xxvin ti81xxvin: registered sub device tvp5158
    ti81xxvin ti81xxvin: TI81xx HDVPSS Capture driver initialized

    root@dvr:/opt/dvr_rdk/ti816x/kermod# insmod ti81xxhdmi.ko

    HDMI W1 rev 2.0

    4.Run the example program saLoopBack.c
    -----command&log-----
    root@dvr:/opt/dvr_rdk/ti816x/kermod# ./saLoopBack

    Driver Name: ti81xxvin
    Driver bus info: TI81xx Platform
    Driver is capable of doing capture

    saLoopBack:
     Mode set is 720P60
    ->no response

    5.Run the following command.
     root@dvr:/opt/dvr_rdk/ti816x/kermod# echo 0 > /sys/devices/platform/vpss/display0/enabled
     root@dvr:/opt/dvr_rdk/ti816x/kermod# echo 1080p-60 > /sys/devices/platform/vpss/display0/mode
    ->no response


    When you run the above command, why there is no reply why? 
    Please advise.

    Regards,

    Hideki

  • Hi,

    No response because VIP capture port of HDVPSS is not capturing anything. Here is guide on how to add new decoders to V4L2 capture driver.

    Regards,

    Hardik Shah

  • Hi Hardik Shah

    Thank you for your reply.

    I know "DM81xx AM38xx Adding External Decoders to V4L2 Capture Driver".

    I made ​​a driver to read the document. There is no set value may be wrong.

    By the way,

    5.Run the following command.
    echo 0 > /sys/devices/platoform/vpss/display0/enabled
    echo 1080p-60 > /sys/devices/platoform/vpss/display0/mode

    V4l2 is also involved when you run the above command?

  • Hi,

     

    hideki said:
    echo 0 > /sys/devices/platoform/vpss/display0/enabled
    echo 1080p-60 > /sys/devices/platoform/vpss/display0/mode

    I am not getting the question correctly. But V4L2 is not involved in above commands.

    Regards,

    Hardik Shah

  • Development environment:
    SDK: EZSDK5_04_00_11  with PSP 04.04.00.01
    Board: UDWORKS DM8168

    I had success getting it to work on the EZSDK UDWORKS DM8168 board.

    I've created a "TVP5158 driver" in order to capture a V4L2.
    I was able to output HDMI to capture the image.

    Photo is the result of running the saLoopBack.



  • Hi,

    Great to hear that. Have you created sub-device for TVP5158 or you are programming TVP5158 from some i2c utility.  

    Regards,

    Hardik Shah

  • Hi Hardik

    Thank you.

    Yes,  I created sub-device driver for TVP5158.

    Is it different compared to the color of the output image colorchart Do I need to convert colorspace?
    Input image is YUV422P.

    Do you know what to do?

    Regards,

    Hideki

  • Hi,

    Great to know that you have implemented sub-device for TVP5158. Are you getting bad colors while you do capture? You are using 8-bit capture right? In 8-bit capture TVP5158 send YUV422 only and that is getting captured by VIP port. Did you try dumping the captured image and saw that instead of displaying it on TV.

    Regards,

    Hardik Shah

  • I had to save the map, "captdump.yuv" using the saLoopBackFbdev.
    Input image is a type of 4 Red / Green / Blue / Colorbar.
    This yuv colorspace?


    tvp5158 output, I think that the settings of 8bit (YUV422P).
    Should I convert to yuv-> RGB it?

    ti81xx_vpss.c?
    ti81xxvin_main.c?
    ti81vid_main.c?
    tvp5158.c?

    1667.captdump.zip

  • Hi,

    I am not getting your question correctly. But yes TVP5158 give YUV422 out and you can convert it to YUV420 or RGB using capture hardware before putting it to memory. For RGB please refer saLoopBackFbdev example packaged with PSP.

    Regards,

    Hardik Shah

  • Hi Hideki,

    I'm also trying to create V4L2 camera capture sub-device for TVP5158 on DM814x with Android OS can you please share your files so that I can use it as a reference.

    Thanks & Regards,

    Rajshekar

  • Hello Rajshekar,
    
    I will send the source code TVP5158driver.
    I'm sorry for bad in the source code.
    To use V4L2 architecture, it is necessary to modify the source code for the other below.
    Changes is a place of TODO keyword.
    
    ti81xxvin_main.c
    ti81xx_vpss.c
    board-ti8168evm.c
    ti81xx.h
    v4l2-chip-ident.h
    
    Regards
    hideki yamada
    
    
    
    /*===   file include        ===*/
    #include <linux/delay.h>
    #include <linux/i2c.h>
    #include <linux/slab.h>
    #include <linux/videodev2.h>
    
    #include <media/v4l2-device.h>
    #include <media/v4l2-chip-ident.h>
    #include <media/v4l2-common.h>
    
    #include <media/tvp5158.h>
    #include "tvp5158_regs.h"
    
    /*===   SECTION NAME        ===*/
    
    /*===   user definition     ===*/
    /* Module Name */
    #define TVP5158_MODULE_NAME	"tvp5158"
    
    /* I2C retry attempts */
    #define I2C_RETRY_COUNT		(5)
    
    /* End of registers */
    #define TVP5158_EOR		0xff
    
    /* Private macros for TVP */
    #define LOCK_RETRY_COUNT    (5)
    #define LOCK_RETRY_DELAY    (200)
    
    
    /* Read write definition for registers */
    #define TVP5158_READ		0
    #define TVP5158_WRITE		1
    #define TVP5158_RESERVED	2
    
    
    
    /*===   external variable   ===*/
    
    /*===   external function   ===*/
    
    /*===   public function prototypes  ===*/
    
    /*===   static function prototypes  ===*/
    
    
    /*===   static typedef variable     ===*/
    
    /*===   static variable     ===*/
    /* Debug functions */
    static int debug;
    module_param(debug, bool, 0644);
    MODULE_PARM_DESC(debug, "Debug level (0-1)");
    
    MODULE_AUTHOR("HidekiYamada <hideki.yamada@palgiken.co.jp>");
    MODULE_DESCRIPTION("TVP5158 linux decoder driver");
    MODULE_LICENSE("GPL");
    
    /* Structure for register values */
    struct i2c_reg_value {
    	u8 reg;
    	u8 value;
    	u8 type;
    };
    
    /* Preset definition for handling device operation */
    struct tvp5158_preset_definition {                                              // ���e�킩���Ȃ�
    	char name[50];
    	u32 preset;
    	const struct i2c_reg_value *p_settings;
    	enum v4l2_colorspace color_space;
    	enum v4l2_field scanmode;
    	u16 progressive;
    	u16 lines_per_frame;
    	u16 cpl_min;
    	u16 cpl_max;
    };
    
    /*===   constant variable   ===*/
    /*
     * Register default values (according to tvp5158 datasheet)
     * In the case of read-only registers, the value (0xff) is
     * never written. R/W functionality is controlled by the
     * writable bit in the register struct definition.
     */
    static const struct i2c_reg_value tvp5158_init_default[] = {
    	{ VPS_TVP5158_REG_VID_STD_SELECT,	0x01, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_AUTO_SW_MASK,		0xff, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_Y_BRIGHTNESS,		0x80, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_Y_CONTRAST,		0x80, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_C_SATURATION,		0x80, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_C_HUE,			0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_Y_CTRL_1,			0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_Y_CTRL_2,			0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_C_CTRL_1,			0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_C_CTRL_2,			0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_VID_STD_STATUS,	0x81, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_NR_MAX_NOISE,		0x28, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_NR_CTRL,			0x09, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_OP_MODE_CTRL,		0x08, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_FV_DEC_CTRL,		0x03, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_FV_CTRL,			0x06, TVP5158_WRITE },
    //	{ 0x90,								0xEB, TVP5158_WRITE },	// White
    //	{ 0x91,								0x80, TVP5158_WRITE },	// White
    //	{ 0x92,								0x80, TVP5158_WRITE },	// White
    //	{ 0x93,								0x00, TVP5158_WRITE },	// White
    //	{ 0x90,								0x51, TVP5158_WRITE },	// Red
    //	{ 0x91,								0x5A, TVP5158_WRITE },	// Red
    //	{ 0x92,								0xF0, TVP5158_WRITE },	// Red
    //	{ 0x93,								0x00, TVP5158_WRITE },	// Red
    	{ 0x90,								0x91, TVP5158_WRITE },	// Green
    	{ 0x91,								0x36, TVP5158_WRITE },	// Green
    	{ 0x92,								0x22, TVP5158_WRITE },	// Green
    	{ 0x93,								0x00, TVP5158_WRITE },	// Green
    //	{ 0x90,								0xD2, TVP5158_WRITE },	// Yellow
    //	{ 0x91,								0x10, TVP5158_WRITE },	// Yellow
    //	{ 0x92,								0x92, TVP5158_WRITE },	// Yellow
    //	{ 0x93,								0x00, TVP5158_WRITE },	// Yellow
    	{ 0xA9,								0x04, TVP5158_WRITE },	// FORCE
    	{ VPS_TVP5158_REG_ESYNC_OFFSET_1,	0x02, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_ESYNC_OFFSET_2,	0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1,	0x20, TVP5158_WRITE },	// SINGLE_CH_NON_MUX_EMBEDDED_SNYC 1ch non-interleave 
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2,	0x11, TVP5158_WRITE },	// SINGLE_CH_NON_MUX_EMBEDDED_SNYC video-ded-enable chanid-desenable
    //	{ VPS_TVP5158_REG_OFM_CH_SEL_1,		0xE9, TVP5158_WRITE },  // change ch0 <-> ch1
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,	0x30, TVP5158_WRITE }, 
    	{ VPS_TVP5158_REG_AUDIO_SAMPLE_HZ,	0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_AUDIO_GAIN_1,		0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_AUDIO_GAIN_2,		0x00, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_AUDIO_MIXER,		0x01, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_AUDIO_CASCADE,	0x00, TVP5158_WRITE },
    	{ 0x24,								0x01, TVP5158_WRITE },
    /* This signals end of register values */
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    
    /* Register parameters for 480P */	/* D1 out put pal uchinoura     */
    static const struct i2c_reg_value tvp5158_parms_480P[] = {
    //	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x20, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x00, TVP5158_WRITE },	// non-interleaved mode 1chD1
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2,	0x11, TVP5158_WRITE },	// 
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,  	0x25, TVP5158_WRITE },	// portb-enable outclockp-enable OSC-enable
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    #if 0
    /* Register parameters for 576P */	/* D1 out put pal uchinoura     */
    static const struct i2c_reg_value tvp5158_parms_576P[] = {
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x40, TVP5158_WRITE },
    //	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x00, TVP5158_WRITE },	// non-interleaved mode 1chD1
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2, 	0x11, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,  	0x25, TVP5158_WRITE },
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    /* Register parameters for 1080I60 */	/* D1 out put pal uchinoura     */
    static const struct i2c_reg_value tvp5158_parms_1080I60[] = {
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x20, TVP5158_WRITE },
    //	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x00, TVP5158_WRITE },	// non-interleaved mode 1chD1
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2, 	0x11, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,  	0x25, TVP5158_WRITE },
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    /* Register parameters for 1080P60 */	/* D1 out put pal uchinoura     */
    static const struct i2c_reg_value tvp5158_parms_1080P60[] = {
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x2q0, TVP5158_WRITE },	// non-interleaved mode 1chD1
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2,	0x11, TVP5158_WRITE },	// 
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,  	0x25, TVP5158_WRITE },
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    /* Register parameters for 1080I50 */	/* D1 out put pal uchinoura     */
    static const struct i2c_reg_value tvp5158_parms_1080I50[] = {
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x40, TVP5158_WRITE },
    //	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x00, TVP5158_WRITE },	// non-interleaved mode 1chD1
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2, 	0x11, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,  	0x25, TVP5158_WRITE },
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    /* Register parameters for 720P60 */	/* D1 out put pal uchinoura     */
    static const struct i2c_reg_value tvp5158_parms_720P60[] = {
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x40, TVP5158_WRITE },
    //	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x00, TVP5158_WRITE },	// non-interleaved mode 1chD1
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2, 	0x11, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,  	0x25, TVP5158_WRITE },
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    /* Register parameters for 720P50 */	/* D1 out put pal uchinoura     */
    static const struct i2c_reg_value tvp5158_parms_720P50[] = {
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x40, TVP5158_WRITE },
    //	{ VPS_TVP5158_REG_AVD_OUT_CTRL_1, 	0x00, TVP5158_WRITE },	// non-interleaved mode 1chD1
    	{ VPS_TVP5158_REG_AVD_OUT_CTRL_2, 	0x11, TVP5158_WRITE },
    	{ VPS_TVP5158_REG_OFM_MODE_CTRL,  	0x25, TVP5158_WRITE },
    	{ TVP5158_EOR, 						0xff, TVP5158_RESERVED }
    };
    #endif
    
    /* Struct list for digital video presets */
    
    #if 0
    
    //#define		V4L2_DV_INVALID		0
    //#define		V4L2_DV_480P59_94	1 /* BT.1362 */
    //#define		V4L2_DV_576P50		2 /* BT.1362 */
    //#define		V4L2_DV_720P24		3 /* SMPTE 296M */
    //#define		V4L2_DV_720P25		4 /* SMPTE 296M */
    //#define		V4L2_DV_720P30		5 /* SMPTE 296M */
    //#define		V4L2_DV_720P50		6 /* SMPTE 296M */
    //#define		V4L2_DV_720P59_94	7 /* SMPTE 274M */
    //#define		V4L2_DV_720P60		8 /* SMPTE 274M/296M */
    //#define		V4L2_DV_1080I29_97	9 /* BT.1120/ SMPTE 274M */
    //#define		V4L2_DV_1080I30		10 /* BT.1120/ SMPTE 274M */
    //#define		V4L2_DV_1080I25		11 /* BT.1120 */
    //#define		V4L2_DV_1080I50		12 /* SMPTE 296M */
    //#define		V4L2_DV_1080I60		13 /* SMPTE 296M */
    //#define		V4L2_DV_1080P24		14 /* SMPTE 296M */
    //#define		V4L2_DV_1080P25		15 /* SMPTE 296M */
    //#define		V4L2_DV_1080P30		16 /* SMPTE 296M */
    //#define		V4L2_DV_1080P50		17 /* BT.1120 */
    
    //#define		V4L2_DV_1080P60		18 /* BT.1120 */  
    /* see also http://vektor.theorem.ca/graphics/ycbcr/ */
    
    enum v4l2_colorspace {
    	/* ITU-R 601 -- broadcast NTSC/PAL */
    	V4L2_COLORSPACE_SMPTE170M     = 1,
    
    	/* 1125-Line (US) HDTV */
    	V4L2_COLORSPACE_SMPTE240M     = 2,
    
    	/* HD and modern captures. */
    	V4L2_COLORSPACE_REC709        = 3,
    
    	/* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
    	V4L2_COLORSPACE_BT878         = 4,
    
    	/* These should be useful.  Assume 601 extents. */
    	V4L2_COLORSPACE_470_SYSTEM_M  = 5,
    	V4L2_COLORSPACE_470_SYSTEM_BG = 6,
    
    	/* I know there will be cameras that send this.  So, this is
    	 * unspecified chromaticities and full 0-255 on each of the
    	 * Y'CbCr components
    	 */
    	V4L2_COLORSPACE_JPEG          = 7,
    
    	/* For RGB colourspaces, this is probably a good start. */
    	V4L2_COLORSPACE_SRGB          = 8,
    };
    enum v4l2_field {
    	V4L2_FIELD_ANY           = 0, /* driver can choose from none,
    					 top, bottom, interlaced
    					 depending on whatever it thinks
    					 is approximate ... */
    	V4L2_FIELD_NONE          = 1, /* this device has no fields ... */
    	V4L2_FIELD_TOP           = 2, /* top field only */
    	V4L2_FIELD_BOTTOM        = 3, /* bottom field only */
    	V4L2_FIELD_INTERLACED    = 4, /* both fields interlaced */
    	V4L2_FIELD_SEQ_TB        = 5, /* both fields sequential into one
    					 buffer, top-bottom order */
    	V4L2_FIELD_SEQ_BT        = 6, /* same as above + bottom-top order */
    	V4L2_FIELD_ALTERNATE     = 7, /* both fields alternating into
    					 separate buffers */
    	V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
    					 first and the top field is
    					 transmitted first */
    	V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
    					 first and the bottom field is
    					 transmitted first */
    };
    #endif
    static const struct tvp5158_preset_definition tvp5158_presets[] = {             // ���e�킩���Ȃ�
    #if 0
    	{
    		"V4L2_DV_720P60",
    		V4L2_DV_720P60,
    //		tvp5158_parms_1080P60,
    		tvp5158_parms_720P60,
    		V4L2_COLORSPACE_REC709,
    		V4L2_FIELD_NONE,
    		0,
    		0x2EE,
    		135,
    		153
    	},
    	{
    		"V4L2_DV_1080I60",
    		V4L2_DV_1080I60,
    //		tvp5158_parms_1080P60,
    		tvp5158_parms_1080I60,
    		V4L2_COLORSPACE_REC709,
    		V4L2_FIELD_INTERLACED,
    		0,
    		0x465,
    		181,
    		205
    	},
    	{
    		"V4L2_DV_1080I50",
    		V4L2_DV_1080I50,
    //		tvp5158_parms_1080P60,
    		tvp5158_parms_1080I50,
    		V4L2_COLORSPACE_REC709,
    		V4L2_FIELD_INTERLACED,
    		0,
    		0x465,
    		217,
    		245
    	},
    	{
    		"V4L2_DV_720P50",
    		V4L2_DV_720P50,
    //		tvp5158_parms_1080P60,
    		tvp5158_parms_720P50,
    		V4L2_COLORSPACE_REC709,
    		V4L2_FIELD_NONE,
    		1,
    		0x2EE,
    		163,
    		183
    	},
    	{
    		"V4L2_DV_1080P60",
    		V4L2_DV_1080P60,
    		tvp5158_parms_1080P60,
    		V4L2_COLORSPACE_REC709,
    		V4L2_FIELD_NONE,
    		1,
    		0x465,
    		90,
    		102
    	},
    #endif
    	{
    		"V4L2_DV_480P59_94",
    		V4L2_DV_480P59_94,
    		tvp5158_parms_480P,
    		V4L2_COLORSPACE_SMPTE170M,
    //		V4L2_FIELD_NONE,
    		V4L2_FIELD_INTERLACED,
    //		1,
    		0,	// interlace
    		0x20D,
    		0xffff,
    		0xffff
    	},
    	{
    		"V4L2_DV_1080I60",
    		V4L2_DV_1080I60,
    		tvp5158_parms_480P,
    		V4L2_COLORSPACE_SMPTE170M,
    		V4L2_FIELD_INTERLACED,
    		0,	// interlace
    		0x20D,
    		0xffff,
    		0xffff
    	},
    #if 0
    	{
    		"V4L2_DV_576P50",
    		V4L2_DV_576P50,
    		tvp5158_parms_576P,
    		V4L2_COLORSPACE_SMPTE170M,
    		V4L2_FIELD_NONE,
    		1,
    		0x271,
    		0xffff,
    		0xffff
    	}
    #endif
    };
    
    #define NUM_PRESETS	ARRAY_SIZE(tvp5158_presets)
    
    /*===   global variable     ===*/
    
    
    /*===   implementation      ===*/
    
    
    /* Device definition */
    struct tvp5158 {
    	struct v4l2_subdev sd;
    	const struct tvp5158_config *pdata;
    
    	int ver;
    	int streaming;
    
    	const struct tvp5158_preset_definition *current_preset;
    	u8 gain;
    };
    
    /*
     * to_tvp5158 - Obtain device handler TVP5158
     * @sd: ptr to v4l2_subdev struct
     *
     * Returns device handler tvp5158.
     */
    static inline struct tvp5158 *to_tvp5158(struct v4l2_subdev *sd)
    {
    	return container_of(sd, struct tvp5158, sd);
    }
    
    /*
     * tvp5158_read - Read a value from a register in an TVP5158
     * @sd: ptr to v4l2_subdev struct
     * @addr: TVP5158 register address
     * @dst: pointer to 8-bit destination
     *
     * Returns value read if successful, or non-zero (-1) otherwise.
     */
    static int tvp5158_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
    {
    	struct i2c_client *c = v4l2_get_subdevdata(sd);
    	int retry;
    	int error;
    
    	for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
    		error = i2c_smbus_read_byte_data(c, addr);
    
    		if (error >= 0) {
    			*dst = (u8)error;
    			return 0;
    		}
    
    		msleep_interruptible(10);
    	}
    	v4l2_err(sd, "TVP5158 read error %d\n", error);
    	return error;
    }
    
    /*
     * tvp5158_read_err() - Read a register value with error code
     * @sd: pointer to standard V4L2 sub-device structure
     * @reg: destination register
     * @val: value to be read
     * @err: pointer to error value
     *
     * Read a value in a register and save error value in pointer.
     * Also update the register table if successful
     */
    static inline void tvp5158_read_err(struct v4l2_subdev *sd, u8 reg,
    							u8 *dst, int *err)
    {
    	if (!*err)
    		*err = tvp5158_read(sd, reg, dst);
    }
    
    /*
     * tvp5158_write() - Write a value to a register in TVP5158
     * @sd: ptr to v4l2_subdev struct
     * @addr: TVP5158 register address
     * @value: value to be written to the register
     *
     * Write a value to a register in an TVP5158 decoder device.
     * Returns zero if successful, or non-zero otherwise.
     */
    static int tvp5158_write(struct v4l2_subdev *sd, u8 addr, u8 value)
    {
    	struct i2c_client *c;
    	int retry;
    	int error;
    
    	c = v4l2_get_subdevdata(sd);
    
    	for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
    		error = i2c_smbus_write_byte_data(c, addr, value);
    
    		if (error >= 0)
    			return 0;
    
    		v4l2_warn(sd, "Write: retry ... %d\n", retry);
    		msleep_interruptible(10);
    	}
    	v4l2_err(sd, "TVP5158 write error %d\n", error);
    	return error;
    }
    
    /*
     * tvp5158_write_err() - Write a register value with error code
     * @sd: pointer to standard V4L2 sub-device structure
     * @reg: destination register
     * @val: value to be written
     * @err: pointer to error value
     *
     * Write a value in a register and save error value in pointer.
     * Also update the register table if successful
     */
    static inline void tvp5158_write_err(struct v4l2_subdev *sd, u8 reg,
    							u8 val, int *err)
    {
    	if (!*err)
    		*err = tvp5158_write(sd, reg, val);
    }
    
    /*
     * tvp5158_g_chip_ident() - Get chip identification number
     * @sd: ptr to v4l2_subdev struct
     * @chip: ptr to v4l2_dbg_chip_ident struct
     *
     * Obtains the chip's identification number.
     * Returns zero or -EINVAL if read operation fails.
     */
    
    #if 1 // pal uchinoura
    static void reg_dump(struct v4l2_subdev *sd, int st, int len)
    {
    	int i;
    	unsigned char dat;
    
    	printk("reg dump-------------------------------------------\n");
    	for (i=0; i<len; i++) {
    		if (i%16 == 0) printk("%02X:", i);
    		tvp5158_read(sd, i, &dat);
    		printk("%02X ", dat);
    		if ((i+1)%16 == 0) printk("\n");
    	}
    }
    #endif
    
    static int tvp5158_g_chip_ident(struct v4l2_subdev *sd,
    					struct v4l2_dbg_chip_ident *chip)
    {
    	u8      rev[2]={0};
        u32     chipid;
    	int     error;
    	struct  i2c_client *client = v4l2_get_subdevdata(sd);
    
    	error = tvp5158_read(sd, VPS_TVP5158_REG_CHIP_ID_MSB, &rev[0]);                           // TVP5158_CHIP_REV ����
    	if (error < 0)
    		return error;
    	error = tvp5158_read(sd, VPS_TVP5158_REG_CHIP_ID_LSB, &rev[1]);                           // TVP5158_CHIP_REV ����
    	if (error < 0)
    		return error;
            
        chipid = ((u32)rev[0]<<8) | rev[1];
    	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP5158, chipid);   // v4l2-chip-ident.h �� V4L2_IDENT_TVP5158=5158 �lj�
    }
    
    /*
     * tvp5158_write_inittab() - Write initialization values
     * @sd: ptr to v4l2_subdev struct
     * @regs: ptr to i2c_reg_value struct
     *
     * Write initialization values.
     * Returns zero or -EINVAL if read operation fails.
     */
    static int tvp5158_write_inittab(struct v4l2_subdev *sd,
    					const struct i2c_reg_value *regs)
    {
    	int error = 0;
    	int error2 = 0;
    	u8	rev;
    
    	/* Initialize the first (defined) registers */
    	while (TVP5158_EOR != regs->reg) {
    		if (TVP5158_WRITE == regs->type)
    			tvp5158_write_err(sd, regs->reg, regs->value, &error);
    		rev=0;
    		tvp5158_read_err(sd, regs->reg, &rev, &error2);                           // TVP5158_CHIP_REV ����
    		regs++;
    	}
    
    	return error;
    }
    
    /*
     * tvp5158_s_dv_preset() - Set digital video preset
     * @sd: ptr to v4l2_subdev struct
     * @dv_preset: ptr to v4l2_dv_preset struct
     *
     * Set the digital video preset for a TVP5158 decoder device.
     * Returns zero when successful or -EINVAL if register access fails.
     */
     
                                                                                    // �Ȃɂ�邩�킩���Ȃ��I�I
    static int tvp5158_s_dv_preset(struct v4l2_subdev *sd,
    					struct v4l2_dv_preset *dv_preset)
    {
    	struct tvp5158 *device = to_tvp5158(sd);
    	u32 preset;
    	int i;
    	int	err;
    	unsigned char v_line_status[2];
    
    	v4l2_info(sd, "pass %s(%d)\n", __func__, __LINE__);
    	for (i = 0; i < NUM_PRESETS; i++) {
    		preset = tvp5158_presets[i].preset;
    		v4l2_info(sd, "-preset[%d] ------------------------------\n", i);
    		v4l2_info(sd, "preset         = %s\n", 	tvp5158_presets[i].name);
    		v4l2_info(sd, "reg=0x%X val=0x%X\n", 	tvp5158_presets[i].p_settings->reg, tvp5158_presets[i].p_settings->value);
    		v4l2_info(sd, "color_space    = %d\n", 	tvp5158_presets[i].color_space);
    		v4l2_info(sd, "scanmode       = %d\n", 	tvp5158_presets[i].scanmode);
    		v4l2_info(sd, "progressive    = %d\n", 	tvp5158_presets[i].progressive);
    		v4l2_info(sd, "lines_per_frame= %d\n", 	tvp5158_presets[i].lines_per_frame);
    		v4l2_info(sd, "cpl_min        = %d\n", 	tvp5158_presets[i].cpl_min);
    		v4l2_info(sd, "cpl_max        = %d\n", 	tvp5158_presets[i].cpl_max);
    	}
    	for (i = 0; i < NUM_PRESETS; i++) {
    		preset = tvp5158_presets[i].preset;
    		if (preset == dv_preset->preset) {
    			device->current_preset = &tvp5158_presets[i];
    			v4l2_info(sd, "-selected preset[%d] ------------------------------\n", i);
    			v4l2_info(sd, "preset         = %s\n", device->current_preset->name);
    			v4l2_info(sd, "reg=0x%X val=0x%X\n",  device->current_preset->p_settings->reg, device->current_preset->p_settings->value);
    			v4l2_info(sd, "color_space    = %d\n", device->current_preset->color_space);
    			v4l2_info(sd, "scanmode       = %d\n", device->current_preset->scanmode);
    			v4l2_info(sd, "progressive    = %d\n", device->current_preset->progressive);
    			v4l2_info(sd, "lines_per_frame= %d\n", device->current_preset->lines_per_frame);
    			v4l2_info(sd, "cpl_min        = %d\n", device->current_preset->cpl_min);
    			v4l2_info(sd, "cpl_max        = %d\n", device->current_preset->cpl_max);
    			
    			err = tvp5158_write_inittab(sd, tvp5158_presets[i].p_settings);
    			tvp5158_read(sd, 0xA2, &v_line_status[0]);
    			tvp5158_read(sd, 0xA3, &v_line_status[1]);
    			v4l2_info(sd, "v_line_status:%02X%02X\n", v_line_status[1], v_line_status[0]);
    
    			reg_dump(sd, 0, 256);
    
    			return err;
    		}
    	}
    
    	return -EINVAL;
    }
    
    /*
     * tvp5158_g_ctrl() - Get a control
     * @sd: ptr to v4l2_subdev struct
     * @ctrl: ptr to v4l2_control struct
     *
     * Get a control for a TVP5158 decoder device.
     * Returns zero when successful or -EINVAL if register access fails.
     */
    static int tvp5158_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
    {
    	struct tvp5158 *device = to_tvp5158(sd);
    
    	switch (ctrl->id) {
    	case V4L2_CID_GAIN:                                                         // videodev2.h
    		ctrl->value = device->gain;
    		return 0;
    	default:
    		return -EINVAL;
    	}
    }
    
    /*
     * tvp5158_s_ctrl() - Set a control
     * @sd: ptr to v4l2_subdev struct
     * @ctrl: ptr to v4l2_control struct
     *
     * Set a control in TVP5158 decoder device.
     * Returns zero when successful or -EINVAL if register access fails.
     */
    static int tvp5158_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
    {
    	struct tvp5158 *device = to_tvp5158(sd);
    	int error = 0;
    
    	switch (ctrl->id) {
    	case V4L2_CID_GAIN:
    #if 0
    		tvp5158_write_err(sd, TVP5158_R_FINE_GAIN,                              // ��ۂ̃p�����[�^�ɒu��������
    						ctrl->value & 0xff, &error);
    		tvp5158_write_err(sd, TVP5158_G_FINE_GAIN,
    						ctrl->value & 0xff, &error);
    		tvp5158_write_err(sd, TVP5158_B_FINE_GAIN,
    						ctrl->value & 0xff, &error);
    #endif
    		if (error < 0)
    			return error;
    
    		/* Set only after knowing there is no error */
    		device->gain = ctrl->value & 0xff;
    		return 0;
    	default:
    		return -EINVAL;
    	}
    }
    
    /*
     * tvp5158_queryctrl() - Query a control
     * @sd: ptr to v4l2_subdev struct
     * @qc: ptr to v4l2_queryctrl struct
     *
     * Query a control of a TVP5158 decoder device.
     * Returns zero when successful or -EINVAL if register read fails.
     */
    static int tvp5158_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
    {
    	switch (qc->id) {
    	case V4L2_CID_GAIN:
    		/*
    		 * Gain is supported [0-255, default=0, step=1]
    		 */
    		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
    	default:
    		return -EINVAL;
    	}
    }
    
    /*
     * tvp5158_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt
     * @sd: pointer to standard V4L2 sub-device structure
     * @f: pointer to mediabus format structure
     *
     * Negotiate the image capture size and mediabus format.
     * There is only one possible format, so this single function works for
     * get, set and try.
     */
    static int tvp5158_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
    {
    	struct tvp5158 *device = to_tvp5158(sd);
    	struct v4l2_dv_enum_preset e_preset;
    	int error;
    
    	v4l2_info(sd, "pass %s(%d)\n", __func__, __LINE__);
    
    	/* Calculate height and width based on current standard */
    	error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset);
    	if (error)
    		return error;
    
    	f->width    = e_preset.width;
    	f->height   = e_preset.height;
    #if 1
    	f->code     = V4L2_MBUS_FMT_UYVY8_2X8;
    	f->field    = V4L2_FIELD_INTERLACED;
    	f->colorspace = V4L2_COLORSPACE_SMPTE170M;
    //	f->field    = device->current_preset->scanmode;
    //	f->colorspace = device->current_preset->color_space;
    #else
    	f->code     = V4L2_MBUS_FMT_YUYV10_1X20;
    	f->field    = device->current_preset->scanmode;
    	f->colorspace = device->current_preset->color_space;
    #endif
    //	v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d, Code - %d, Field - %d, ColorSpace - %d",
    //			f->width, f->height, f->code, f->field, f->colorspace);
    	v4l2_info(sd, "MBUS_FMT: Width - %d, Height - %d, Code - %d, Field - %d, ColorSpace - %d",
    			f->width, f->height, f->code, f->field, f->colorspace);
    	return 0;
    }
    
    /*
     * tvp5158_query_dv_preset() - query DV preset
     * @sd: pointer to standard V4L2 sub-device structure
     * @qpreset: standard V4L2 v4l2_dv_preset structure
     *
     * Returns the current DV preset by TVP5158. If no active input is
     * detected, returns -EINVAL
     */
    static int tvp5158_query_dv_preset(struct v4l2_subdev *sd,
    						struct v4l2_dv_preset *qpreset)
    {
    	const struct tvp5158_preset_definition *presets = tvp5158_presets;
    	struct  tvp5158 *device;
    	u8      progressive;
    	u32     lpfr;
    	u32     cpln;
    	int     error = 0;
    	u8      lpf_lsb;
    	u8      lpf_msb;
    	u8      cpl_lsb;
    	u8      cpl_msb;
    	int     index;
    
    	v4l2_info(sd, "pass %s(%d)\n", __func__, __LINE__);
    
    	device = to_tvp5158(sd);
    
    #if 0
    #endif
    #if 1	/* �����I��preset 0�ɂ���	uchinoura	*/
    // 1080P-60
    //	lpfr = 0x465;
    //	cpln = 98;
    //	progressive = 1;
    
    // 1080I-60
    //	lpfr = 0x465;
    //	cpln = 198;
    //	progressive = 0;
    
    // 480P
    //	lpfr = 0x20D;
    //	cpln = 0xFFFF;
    //	progressive = 1;
    	error = tvp5158_read(sd, 0xA2, &lpf_lsb);
    	if (error < 0){
    	}
    	error = tvp5158_read(sd, 0xA3, &lpf_msb);
    	if (error < 0){
    	}
    	lpfr = lpf_msb<<8 | lpf_lsb;
    	v4l2_info(sd, "current lines_per_frame=%d 		%s(%d)\n", lpfr, __func__, __LINE__);
    	
    #endif
    	/* Do checking of video modes */
    v4l2_info(sd, "[pal] NUM_PRESETS:%d\n", NUM_PRESETS);
    #if 0
    	for (index = 0; index < NUM_PRESETS; index++, presets++){
    		v4l2_info(sd, "presets->lines_per_frame=%d %s(%d)\n", presets->lines_per_frame, __func__, __LINE__);
    		v4l2_info(sd, "[pal] idx%d lpfr:%d prg:%d min:%d max:%d\n", index, presets->lines_per_frame, presets->progressive, presets->cpl_min, presets->cpl_max);
    		if (lpfr  == presets->lines_per_frame &&
    			progressive == presets->progressive) {
    			if (presets->cpl_min == 0xffff)
    				break;
    			if (cpln >= presets->cpl_min && cpln <= presets->cpl_max)
    				break;
    		}
    	}
    	if (index == NUM_PRESETS) {
    		v4l2_dbg(1, debug, sd, "detection failed: lpf = %x, cpl = %x\n",
    								lpfr, cpln);
    		/* Could not detect a signal, so return the 'invalid' preset */
    		qpreset->preset = V4L2_DV_INVALID;
    		return 0;
    	}
    #endif
    	/* Set values in found preset */
    //	qpreset->preset = presets->preset;
    	qpreset->preset = V4L2_DV_480P59_94;	// 設定値固定 palgken 
    
    
    	/* Update lines per frame and clocks per line info */
    //	v4l2_dbg(1, debug, sd, "detected preset: %d\n", presets->preset);
    	v4l2_dbg(1, debug, sd, "detected preset: %d\n", qpreset->preset);
    	return 0;
    }
    
    #ifdef CONFIG_VIDEO_ADV_DEBUG
    /*
     * tvp5158_g_register() - Get the value of a register
     * @sd: ptr to v4l2_subdev struct
     * @reg: ptr to v4l2_dbg_register struct
     *
     * Get the value of a TVP5158 decoder device register.
     * Returns zero when successful, -EINVAL if register read fails or
     * access to I2C client fails, -EPERM if the call is not allowed
     * by diabled CAP_SYS_ADMIN.
     */
    static int tvp5158_g_register(struct v4l2_subdev *sd,
    						struct v4l2_dbg_register *reg)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	u8 val;
    	int ret;
    
    	v4l2_info(sd, "pass %s(%d)\n", __func__, __LINE__);
    
    	if (!v4l2_chip_match_i2c_client(client, &reg->match))
    		return -EINVAL;
    	if (!capable(CAP_SYS_ADMIN))
    		return -EPERM;
    
    	ret = tvp5158_read(sd, reg->reg & 0xff, &val);
    	reg->val = val;
    	return ret;
    }
    
    /*
     * tvp5158_s_register() - set a control
     * @sd: ptr to v4l2_subdev struct
     * @reg: ptr to v4l2_dbg_register struct
     *
     * Get the value of a TVP5158 decoder device register.
     * Returns zero when successful, -EINVAL if register read fails or
     * -EPERM if call not allowed.
     */
    static int tvp5158_s_register(struct v4l2_subdev *sd,
    						struct v4l2_dbg_register *reg)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    
    	v4l2_info(sd, "pass %s(%d)\n", __func__, __LINE__);
    
    	if (!v4l2_chip_match_i2c_client(client, &reg->match))
    		return -EINVAL;
    	if (!capable(CAP_SYS_ADMIN))
    		return -EPERM;
    
    	return tvp5158_write(sd, reg->reg & 0xff, reg->val & 0xff);
    }
    #endif
    
    /*
     * tvp5158_enum_mbus_fmt() - Enum supported mediabus formats
     * @sd: pointer to standard V4L2 sub-device structure
     * @index: format index
     * @code: pointer to mediabus format
     *
     * Enumerate supported mediabus formats.
     */
    
    static int tvp5158_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
    					enum v4l2_mbus_pixelcode *code)
    {
    	/* Check requested format index is within range */
    	if (index)
    		return -EINVAL;
    //	*code = V4L2_MBUS_FMT_YUYV10_1X20;
    	*code = V4L2_MBUS_FMT_UYVY8_2X8;
    	return 0;
    }
    
    /*
     * tvp5158_s_stream() - V4L2 decoder i/f handler for s_stream
     * @sd: pointer to standard V4L2 sub-device structure
     * @enable: streaming enable or disable
     *
     * Sets streaming to enable or disable, if possible.
     */
    static int tvp5158_s_stream(struct v4l2_subdev *sd, int enable)
    {
    	struct tvp5158 *device = to_tvp5158(sd);
    	int error = 0;
    
    	if (device->streaming == enable)
    		return 0;
    
    	if (enable) {
    		/* Set output state on (low impedance means stream on) */
    //		error = tvp5158_write(sd, TVP5158_MISC_CTL_2, 0x00);                    // ��ۂ̃p�����[�^�ɒu��������
    		device->streaming = enable;
    	} else {
    		/* Set output state off (high impedance means stream off) */            // ��ۂ̃p�����[�^�ɒu��������
    //		error = tvp5158_write(sd, TVP5158_MISC_CTL_2, 0x03);
    		if (error)
    			v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
    
    		device->streaming = enable;
    	}
    
    	return error;
    }
    
    /*
     * tvp5158_log_status() - Print information about register settings
     * @sd: ptr to v4l2_subdev struct
     *
     * Log register values of a TVP5158 decoder device.
     * Returns zero or -EINVAL if read operation fails.
     */
    static int tvp5158_log_status(struct v4l2_subdev *sd)
    {
    	const struct tvp5158_preset_definition *presets = tvp5158_presets;
    	struct tvp5158 *device = to_tvp5158(sd);
    	struct v4l2_dv_enum_preset e_preset;
    	struct v4l2_dv_preset detected;
    	int i;
    
    	detected.preset = V4L2_DV_INVALID;
    	/* Find my current standard*/
    	tvp5158_query_dv_preset(sd, &detected);
    
    	/* Print standard related code values */
    	for (i = 0; i < NUM_PRESETS; i++, presets++)
    		if (presets->preset == detected.preset)
    			break;
    
    	if (v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset))
    		return -EINVAL;
    
    	v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name);
    	v4l2_info(sd, "   Pixels per line: %u\n", e_preset.width);
    	v4l2_info(sd, "   Lines per frame: %u\n\n", e_preset.height);
    	if (i == NUM_PRESETS) {
    		v4l2_info(sd, "Detected DV Preset: None\n");
    	} else {
    		if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
    			return -EINVAL;
    		v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name);
    		v4l2_info(sd, "  Pixels per line: %u\n", e_preset.width);
    		v4l2_info(sd, "  Lines per frame: %u\n\n", e_preset.height);
    	}
    	v4l2_info(sd, "Streaming enabled: %s\n",
    					device->streaming ? "yes" : "no");
    
    	/* Print the current value of the gain control */
    	v4l2_info(sd, "Gain: %u\n", device->gain);
    
    	return 0;
    }
    
    /*
     * tvp5158_enum_dv_presets() - Enum supported digital video formats
     * @sd: pointer to standard V4L2 sub-device structure
     * @preset: pointer to format struct
     *
     * Enumerate supported digital video formats.
     */
    static int tvp5158_enum_dv_presets(struct v4l2_subdev *sd,
    		struct v4l2_dv_enum_preset *preset)
    {
    	/* Check requested format index is within range */
    	if (preset->index >= NUM_PRESETS)
    		return -EINVAL;
    
    	return v4l_fill_dv_preset_info(tvp5158_presets[preset->index].preset, preset);
    }
    
    /* V4L2 core operation handlers */
    static const struct v4l2_subdev_core_ops tvp5158_core_ops = {
    	.g_chip_ident   = tvp5158_g_chip_ident,
    	.log_status     = tvp5158_log_status,
    	.g_ctrl         = tvp5158_g_ctrl,
    	.s_ctrl         = tvp5158_s_ctrl,
    	.queryctrl      = tvp5158_queryctrl,
    #ifdef CONFIG_VIDEO_ADV_DEBUG
    	.g_register     = tvp5158_g_register,
    	.s_register     = tvp5158_s_register,
    #endif
    };
    
    /* Specific video subsystem operation handlers */
    static const struct v4l2_subdev_video_ops tvp5158_video_ops = {
    	.enum_dv_presets= tvp5158_enum_dv_presets,
    	.s_dv_preset    = tvp5158_s_dv_preset,
    	.query_dv_preset= tvp5158_query_dv_preset,
    	.s_stream       = tvp5158_s_stream,
    	.g_mbus_fmt     = tvp5158_mbus_fmt,
    	.try_mbus_fmt   = tvp5158_mbus_fmt,
    	.s_mbus_fmt     = tvp5158_mbus_fmt,
    	.enum_mbus_fmt  = tvp5158_enum_mbus_fmt,
    };
    
    /* V4L2 top level operation handlers */
    static const struct v4l2_subdev_ops tvp5158_ops = {
    	.core           = &tvp5158_core_ops,
    	.video          = &tvp5158_video_ops,
    };
    
    static struct tvp5158 tvp5158_dev = {
    	.streaming = 0,
    	.current_preset = tvp5158_presets,
    	.gain = 0,
    };
    
    /*
     * tvp5158_probe - Probe a TVP5158 device
     * @c: ptr to i2c_client struct
     * @id: ptr to i2c_device_id struct
     *
     * Initialize the TVP5158 device
     * Returns zero when successful, -EINVAL if register read fails or
     * -EIO if i2c access is not available.
     */
    static int tvp5158_probe(struct i2c_client *c, const struct i2c_device_id *id)
    {
    	struct  v4l2_subdev *sd;
    	struct  tvp5158 *device;
    	struct  v4l2_dv_preset preset;
    	int     polarity_a;
    	int     polarity_b;
    	u8      revision1;
    	u8      revision2;
    
    	int     error;
    
    	/* Check if the adapter supports the needed features */
    	if (!i2c_check_functionality(c->adapter,
    		I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
    		return -EIO;
    
    	if (!c->dev.platform_data) {
    		v4l_err(c, "No platform data!!\n");
    		return -ENODEV;
    	}
    
    	device = kmalloc(sizeof(struct tvp5158), GFP_KERNEL);
    
    	if (!device)
    		return -ENOMEM;
    
    	*device = tvp5158_dev;
    	sd = &device->sd;
    	device->pdata = c->dev.platform_data;
    
    	/* Tell v4l2 the device is ready */
    	v4l2_i2c_subdev_init(sd, c, &tvp5158_ops);
    	v4l_info(c, "tvp5158 found @ 0x%02x (%s)\n",
    					c->addr, c->adapter->name);
    
    	error = tvp5158_read(sd, VPS_TVP5158_REG_CHIP_ID_MSB, &revision1);
    	if (error < 0)
    		goto found_error;
    	error = tvp5158_read(sd, VPS_TVP5158_REG_CHIP_ID_LSB, &revision2);
    	if (error < 0)
    		goto found_error;
    
    	/* Get revision number */
    	v4l2_info(sd, "Rev. %02x%02X detected.\n", revision1, revision2);
    	if ((revision1 != 0x51) || (revision2 != 0x58))
    		v4l2_info(sd, "Unknown revision detected.\n");
    
    	/* Initializes TVP5158 to its default values */
    	error = tvp5158_write_inittab(sd, tvp5158_init_default);
    	if (error < 0)
    		goto found_error;
    
    	/* Set polarity information after registers have been set */
    	polarity_a = 0x20 | device->pdata->hs_polarity << 5
    			| device->pdata->vs_polarity << 2;
    //	error = tvp5158_write(sd, TVP5158_SYNC_CTL_1, polarity_a);                  // ��ۂ̃p�����[�^�̒u������
    	if (error < 0)
    		goto found_error;
    
    	polarity_b = 0x01  | device->pdata->fid_polarity << 2
    			| device->pdata->sog_polarity << 1
    			| device->pdata->clk_polarity;
    //	error = tvp5158_write(sd, TVP5158_MISC_CTL_3, polarity_b);                  // ��ۂ̃p�����[�^�̒u������
    	if (error < 0)
    		goto found_error;
    
    	/* Set registers according to default video mode */
    	preset.preset = device->current_preset->preset;
    	v4l2_info(sd, "preset=%d\n", preset.preset);								// palgiken 120612
    	error = tvp5158_s_dv_preset(sd, &preset);
    
    found_error:
    	if (error < 0)
    		kfree(device);
    
    	return error;
    }
    
    /*
     * tvp5158_remove - Remove TVP5158 device support
     * @c: ptr to i2c_client struct
     *
     * Reset the TVP5158 device
     * Returns zero.
     */
    static int tvp5158_remove(struct i2c_client *c)
    {
    	struct v4l2_subdev *sd = i2c_get_clientdata(c);
    	struct tvp5158 *device = to_tvp5158(sd);
    
    	v4l2_dbg(1, debug, sd, "Removing tvp5158 adapter"
    				"on address 0x%x\n", c->addr);
    
    	v4l2_device_unregister_subdev(sd);
    	kfree(device);
    	return 0;
    }
    
    /* I2C Device ID table */
    static const struct i2c_device_id tvp5158_id[] = {
    	{ "tvp5158", 0 },
    	{ }
    };
    MODULE_DEVICE_TABLE(i2c, tvp5158_id);
    
    /* I2C driver data */
    static struct i2c_driver tvp5158_driver = {
    	.driver = {
    		.owner  = THIS_MODULE,
    		.name   = TVP5158_MODULE_NAME,
    	},
    	.probe      = tvp5158_probe,
    	.remove     = tvp5158_remove,
    	.id_table   = tvp5158_id,
    };
    
    /*
     * tvp5158_init - Initialize driver via I2C interface
     *
     * Register the TVP5158 driver.
     * Return 0 on success or error code on failure.
     */
    static int __init tvp5158_init(void)
    {
    	return i2c_add_driver(&tvp5158_driver);
    }
    
    /*
     * tvp5158_exit - Remove driver via I2C interface
     *
     * Unregister the TVP5158 driver.
     * Returns nothing.
     */
    static void __exit tvp5158_exit(void)
    {
    	i2c_del_driver(&tvp5158_driver);
    }
    
    module_init(tvp5158_init);
    module_exit(tvp5158_exit);
    
  • Hi Hideki Yamada,

    Thanks for your Code.

    Regards,

    Rajshekar

  • Hi Hideki,

    Can you please attach your below mentioned files for TVP5158 driver addition.

    ti81xxvin_main.c
    ti81xx_vpss.c
    board-ti8168evm.c
    ti81xx.h
    v4l2-chip-ident.h
    
    
    Thanks & Regards,
    Rajshekar
  • Hi Raja,

    I send the source code.

    I pray that it works.
    Please tell me if there is something wrong.

    EZSDK ver 5.04.00.11

    Regards,

    Hideki

    0020.tvp5158.zip

  • Hi Hideki,

    I'm trying to add TVP5158 in Android GB version.

    Thanks a lot for your code I will integrate and will update you.

    Thanks & Regards,

    Rajshekar

  • Hi Hideki,

    I have created  TVP5158 driver support based on your code and it is working fine.

    Once again thanks a lot for the code.

    Regards,

    Rajshekar

  • Hi Rajshekar,

    I'm glad to be of help to you.

    Regards,

    Hideki

  • can you send the tvp5158_regs.h to me?

    Thank you

    vefone