I use OMAP-L138 LCDK to capture the RAW data from a CMOS image sensor. VPIF interface is used. However, there is no interrupt signals generated. The first thing I want to check is whether the ISR has been called. Does anyone know how to check that? Moreover, any other possible reasons could cause there is no interrupt signals? The code and the registers values for VPIF are attached. Thanks.
/* * TI's OMAP-L138 LCDK Development Board * * Initial code: Syed Mohammed Khasim * * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of * any kind, whether express or implied. */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/console.h> #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> #include <linux/leds.h> #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/platform_device.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> #include <linux/mfd/davinci_aemif.h> #include <linux/videodev2.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/cp_intc.h> #include <mach/da8xx.h> #include <mach/mux.h> #include <mach/nand.h> #include <media/tvp514x.h> #define LCDKBOARD_PHY_ID "davinci_mdio-0:07" #define DA850_LCDK_MMCSD_CD_PIN GPIO_TO_PIN(4, 0) #define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) #define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) #define LCDKBOARD_SATA_REFCLKPN_RATE (100 * 1000 * 1000) #define DA850_LCDK_USER_LED0 GPIO_TO_PIN(6, 12) #define DA850_LCDK_USER_LED1 GPIO_TO_PIN(6, 13) #define DA850_LCDK_USER_LED2 GPIO_TO_PIN(2, 12) #define DA850_LCDK_USER_LED3 GPIO_TO_PIN(0, 9) #define DA850_LCDK_USER_KEY0 GPIO_TO_PIN(2, 4) #define DA850_LCDK_USER_KEY1 GPIO_TO_PIN(2, 5) #if defined(CONFIG_USB_OHCI_HCD) #define HAS_OHCI 1 #else #define HAS_OHCI 0 #endif #define DA850_LCDK_KEYS_DEBOUNCE_MS 10 #define DA850_LCDK_GPIO_KEYS_POLL_MS 200 #define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8) #define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15) #if defined(CONFIG_MTD_NAND_DAVINCI) || \ defined(CONFIG_MTD_NAND_DAVINCI_MODULE) struct mtd_partition omapl138_lcdk_nandflash_partition[] = { { .name = "ubl", .offset = 0x20000, .size = SZ_128K * 5, .mask_flags = MTD_WRITEABLE, }, { .name = "uboot", .offset = MTDPART_OFS_APPEND, .size = SZ_1M * 5, .mask_flags = MTD_WRITEABLE, }, { .name = "env", .offset = MTDPART_OFS_APPEND, .size = SZ_1M * 5, .mask_flags = MTD_WRITEABLE, }, { .name = "kernel", .offset = MTDPART_OFS_APPEND, .size = SZ_1M * 20, .mask_flags = 0, }, { .name = "rootfs", .offset = MTDPART_OFS_APPEND, .size = SZ_1M * 100, .mask_flags = 0, }, { .name = "user0", .offset = MTDPART_OFS_APPEND, .size = SZ_1M * 100, .mask_flags = 0, }, { .name = "user1", .offset = MTDPART_OFS_APPEND, .size = SZ_1M * 100, .mask_flags = 0, }, { .name = "append", .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, .mask_flags = 0, }, }; static struct davinci_nand_pdata omapl138_lcdk_nandflash_data = { .parts = omapl138_lcdk_nandflash_partition, .nr_parts = ARRAY_SIZE(omapl138_lcdk_nandflash_partition), .ecc_mode = NAND_ECC_NONE,//NAND_ECC_HW_OOB_FIRST,// .options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE, .ecc_bits = 1, /* 4 bit mode is not * supported with 16 bit NAND */ .bbt_options = NAND_BBT_USE_FLASH, }; static const short omapl138_lcdk_nand_pins[] = { DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9, DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13, DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4, DA850_NEMA_WE, DA850_NEMA_OE, -1 }; static struct resource omapl138_lcdk_nandflash_resource[] = { { .start = DA8XX_AEMIF_CS3_BASE, .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1, .flags = IORESOURCE_MEM, }, { .start = DA8XX_AEMIF_CTL_BASE, .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1, .flags = IORESOURCE_MEM, }, }; static struct platform_device omapl138_lcdk_nandflash_device = { .name = "davinci_nand", .id = 1, .dev = { .platform_data = &omapl138_lcdk_nandflash_data, }, .resource = omapl138_lcdk_nandflash_resource, .num_resources = ARRAY_SIZE(omapl138_lcdk_nandflash_resource), }; static __init void omapl138_lcdk_nand_init(void) { int ret; ret = davinci_cfg_reg_list(omapl138_lcdk_nand_pins); if (ret) { pr_warn("da850_lcdk_init:" "nand mux setup failed: %d\n", ret); return; } platform_device_register(&omapl138_lcdk_nandflash_device); } #else static void omapl138_lcdk_nand_init(void) { } #endif static short omapl138_lcdk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, DA850_MDIO_D, -1 }; static __init void omapl138_lcdk_config_emac(void) { void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); int ret; u32 val; struct davinci_soc_info *soc_info = &davinci_soc_info; val = __raw_readl(cfgchip3); val &= ~BIT(8); ret = davinci_cfg_reg_list(omapl138_lcdk_mii_pins); if (ret) { pr_warning("%s: cpgmac/mii mux setup failed: %d\n", __func__, ret); return; } /* configure the CFGCHIP3 register for MII */ __raw_writel(val, cfgchip3); pr_info("EMAC: MII PHY configured\n"); soc_info->emac_pdata->phy_id = LCDKBOARD_PHY_ID; ret = da8xx_register_emac(); if (ret) pr_warning("%s: emac registration failed: %d\n", __func__, ret); } /* * The following EDMA channels/slots are not being used by drivers (for * example: Timer, GPIO, UART events etc) on da850/omap-l138 LCDK EVM, * hence they are being reserved for codecs on the DSP side. */ static const s16 da850_dma0_rsv_chans[][2] = { /* (offset, number) */ { 8, 6}, {24, 4}, {30, 2}, {-1, -1} }; static const s16 da850_dma0_rsv_slots[][2] = { /* (offset, number) */ { 8, 6}, {24, 4}, {30, 50}, {-1, -1} }; static const s16 da850_dma1_rsv_chans[][2] = { /* (offset, number) */ { 0, 28}, {30, 2}, {-1, -1} }; static const s16 da850_dma1_rsv_slots[][2] = { /* (offset, number) */ { 0, 28}, {30, 90}, {-1, -1} }; static struct edma_rsv_info da850_edma_cc0_rsv = { .rsv_chans = da850_dma0_rsv_chans, .rsv_slots = da850_dma0_rsv_slots, }; static struct edma_rsv_info da850_edma_cc1_rsv = { .rsv_chans = da850_dma1_rsv_chans, .rsv_slots = da850_dma1_rsv_slots, }; static struct edma_rsv_info *da850_edma_rsv[2] = { &da850_edma_cc0_rsv, &da850_edma_cc1_rsv, }; static const short lcdk_mmcsd0_pins[] = { DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, DA850_GPIO3_12, DA850_GPIO3_13, -1 }; static int da850_lcdk_mmc_get_ro(int index) { return 0; } static int da850_lcdk_mmc_get_cd(int index) { return !gpio_get_value(DA850_LCDK_MMCSD_CD_PIN); } static struct davinci_mmc_config da850_mmc_config = { .get_ro = da850_lcdk_mmc_get_ro, .get_cd = da850_lcdk_mmc_get_cd, .wires = 4, .max_freq = 50000000, .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, .version = MMC_CTLR_VERSION_2, }; static __init void omapl138_lcdk_mmc_init(void) { int ret; ret = davinci_cfg_reg_list(lcdk_mmcsd0_pins); if (ret) { pr_warning("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret); return; } ret = gpio_request_one(DA850_LCDK_MMCSD_CD_PIN, GPIOF_DIR_IN, "MMC CD"); if (ret < 0) { pr_warning("%s: can not open GPIO %d\n", __func__, DA850_LCDK_MMCSD_CD_PIN); return; } ret = da8xx_register_mmcsd0(&da850_mmc_config); if (ret) { pr_warning("%s: MMC/SD0 registration failed: %d\n", __func__, ret); goto mmc_setup_mmcsd_fail; } return; mmc_setup_mmcsd_fail: gpio_free(DA850_LCDK_MMCSD_CD_PIN); } static irqreturn_t omapl138_lcdk_usb_ocic_irq(int irq, void *dev_id); static const short da850_lcdk_usb11_pins[] = { DA850_GPIO2_4, DA850_GPIO6_13, -1 }; static struct da8xx_ohci_root_hub omapl138_lcdk_usb11_pdata = { .type = GPIO_BASED, .method = { .gpio_method = { .power_control_pin = DA850_USB1_VBUS_PIN, .over_current_indicator = DA850_USB1_OC_PIN, }, }, .board_ocic_handler = omapl138_lcdk_usb_ocic_irq, }; static irqreturn_t omapl138_lcdk_usb_ocic_irq(int irq, void *handler) { if (handler != NULL) ((da8xx_ocic_handler_t)handler)(&omapl138_lcdk_usb11_pdata, 1); return IRQ_HANDLED; } /* VGA */ static const short omapl138_lcdk_lcdc_pins[] = { DA850_GPIO2_8, DA850_GPIO2_15, -1 }; /* Backlight and power is for use with LCD expansion header only */ static void da850_panel_power_ctrl(int val) { /* lcd backlight */ gpio_set_value(DA850_LCD_BL_PIN, val); /* lcd power */ gpio_set_value(DA850_LCD_PWR_PIN, val); } static int da850_lcd_hw_init(void) { void __iomem *cfg_mstpri1_base; void __iomem *cfg_mstpri2_base; void __iomem *emifb; void __iomem *myptr; int status; u32 val; /* * Default master priorities in reg 0 are all lower by default than LCD * which is set below to 0. Hence don't need to change here. */ /* set EDMA30TC0 and TC1 to lower than LCDC (4 < 0) */ cfg_mstpri1_base = DA8XX_SYSCFG0_VIRT(DA8XX_MSTPRI1_REG); val = __raw_readl(cfg_mstpri1_base); val &= 0xFFFF00FF; val |= 4 << 8; /* 0-high, 7-low priority*/ val |= 4 << 12; /* 0-high, 7-low priority*/ __raw_writel(val, cfg_mstpri1_base); /* * Reconfigure the LCDC priority to the highest to ensure that * the throughput/latency requirements for the LCDC are met. */ cfg_mstpri2_base = DA8XX_SYSCFG0_VIRT(DA8XX_MSTPRI2_REG); val = __raw_readl(cfg_mstpri2_base); val &= 0x0fffffff; __raw_writel(val, cfg_mstpri2_base); /* set BPRIO */ #define DA8XX_EMIF30_CONTROL_BASE 0xB0000000 #define DA8XX_EMIF30_BPRIO_OFFSET 0x20 #define DA8XX_EMIFB_VIRT(x) (emifb + (x)) emifb = ioremap(DA8XX_EMIF30_CONTROL_BASE, SZ_4K); myptr = DA8XX_EMIFB_VIRT(0x20); __raw_writel(0x20, myptr); status = gpio_request(DA850_LCD_BL_PIN, "lcd bl\n"); if (status < 0) return status; status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr\n"); if (status < 0) { gpio_free(DA850_LCD_BL_PIN); return status; } gpio_direction_output(DA850_LCD_BL_PIN, 0); gpio_direction_output(DA850_LCD_PWR_PIN, 0); /* Switch off panel power and backlight */ da850_panel_power_ctrl(0); /* Switch on panel power and backlight */ da850_panel_power_ctrl(1); return 0; } static void omapl138_lcdk_display_init(void) { int ret; ret = davinci_cfg_reg_list(da850_lcdcntl_pins); if (ret) pr_warn("omapl138_lcdk_init: lcdcntl mux setup failed:%d\n", ret); ret = davinci_cfg_reg_list(omapl138_lcdk_lcdc_pins); if (ret) pr_warn("omapl138_lcdk_init: evm specific lcd mux setup " "failed: %d\n", ret); da850_lcd_hw_init(); ret = da8xx_register_lcdc(&vga_monitor_pdata); if (ret) pr_warn("omapl138_lcdk_init: lcdc registration failed: %d\n", ret); } static __init void omapl138_lcdk_usb_init(void) { u32 cfgchip2; int ret; /* Setup the Ref. clock frequency for the LCDK at 24 MHz. */ cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); cfgchip2 &= ~CFGCHIP2_REFFREQ; cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; /* * Select internal reference clock for USB 2.0 PHY * and use it as a clock source for USB 1.1 PHY * (this is the default setting anyway). */ cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX; cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX; /* * We have to override VBUS/ID signals when MUSB is configured into the * host-only mode -- ID pin will float if no cable is connected, so the * controller won't be able to drive VBUS thinking that it's a B-device. * Otherwise, we want to use the OTG mode and enable VBUS comparators. */ cfgchip2 &= ~CFGCHIP2_OTGMODE; cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN; /* * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A), * with the power on to power good time of 3 ms. */ ret = da8xx_register_usb20(1000, 3); if (ret) pr_warn("%s: USB 2.0 registration failed: %d\n", __func__, ret); __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); if (HAS_OHCI) da8xx_board_usb_init(da850_lcdk_usb11_pins, &omapl138_lcdk_usb11_pdata); return; } static struct davinci_uart_config omapl138_lcdk_uart_config __initdata = { .enabled_uarts = 0x7, }; /* I2C */ static struct i2c_board_info __initdata omapl138_lcdk_i2c_devices[] = { { I2C_BOARD_INFO("tlv320aic3x", 0x18), }, }; static struct i2c_gpio_platform_data da850_gpio_i2c_pdata = { .sda_pin = GPIO_TO_PIN(1, 4), .scl_pin = GPIO_TO_PIN(1, 5), .udelay = 2, /* 250 KHz */ }; static struct platform_device da850_gpio_i2c = { .name = "i2c-gpio", .id = 1, .dev = { .platform_data = &da850_gpio_i2c_pdata, }, }; static void omapl138_lcdk_i2c_init(void) { int ret; ret = davinci_cfg_reg_list(da850_i2c0_pins); if (ret) pr_warn("omapl138_lcdk_init: i2c0 mux setup failed: %d\n", ret); platform_device_register(&da850_gpio_i2c); if (ret) pr_warn("omapl138_lcdk_init: i2c0 registration failed: %d\n", ret); i2c_register_board_info(1, omapl138_lcdk_i2c_devices, ARRAY_SIZE(omapl138_lcdk_i2c_devices)); } /* Set up OMAP-L138 LCDK low-level McASP driver */ static u8 da850_iis_serializer_direction[] = { INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, }; static struct snd_platform_data omapl138_lcdk_snd_data = { .tx_dma_offset = 0x2000, .rx_dma_offset = 0x2000, .op_mode = DAVINCI_MCASP_IIS_MODE, .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), .tdm_slots = 2, .serial_dir = da850_iis_serializer_direction, .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_2, .txnumevt = 1, .rxnumevt = 1, }; static const short omapl138_lcdk_mcasp_pins[] __initconst = { DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, DA850_AXR_13, DA850_AXR_14, -1 }; static void omapl138_lcdk_sound_init(void) { int ret; ret = davinci_cfg_reg_list(omapl138_lcdk_mcasp_pins); if (ret) pr_warn("omapl138_lcdk_init: mcasp mux setup failed: %d\n", ret); da8xx_register_mcasp(0, &omapl138_lcdk_snd_data); } static const short omapl138_lcdk_led_pin_mux[] __initconst = { DA850_GPIO6_12, #if !HAS_OHCI DA850_GPIO6_13, #endif DA850_GPIO2_12, DA850_GPIO0_9, -1 }; static struct gpio_led gpio_leds[] = { { .active_low = 1, .gpio = DA850_LCDK_USER_LED0, .name = "user_led0", }, #if !HAS_OHCI { .active_low = 1, .gpio = DA850_LCDK_USER_LED1, .name = "user_led1", }, #endif { .active_low = 1, .gpio = DA850_LCDK_USER_LED2, .name = "user_led2", }, { .active_low = 1, .gpio = DA850_LCDK_USER_LED3, .name = "user_led3", }, }; static struct gpio_led_platform_data gpio_led_info = { .leds = gpio_leds, .num_leds = ARRAY_SIZE(gpio_leds), }; static struct platform_device leds_gpio = { .name = "leds-gpio", .id = -1, .dev = { .platform_data = &gpio_led_info, }, }; static __init void omapl138_lcdk_led_init(void) { int err; davinci_cfg_reg_list(omapl138_lcdk_led_pin_mux); err = platform_device_register(&leds_gpio); if (err) pr_err("failed to register leds_gpio device\n"); return; }; static const short omapl138_lcdk_keys_pin_mux[] __initconst = { #if !HAS_OHCI DA850_GPIO2_4, #endif DA850_GPIO2_5, -1 }; static struct gpio_keys_button omapl138_lcdk_evm_keys[] = { #if !HAS_OHCI { .type = EV_KEY, .active_low = 1, .wakeup = 0, .debounce_interval = DA850_LCDK_KEYS_DEBOUNCE_MS, .code = KEY_F8, .gpio = DA850_LCDK_USER_KEY0, .desc = "pb1", }, #endif { .type = EV_KEY, .active_low = 1, .wakeup = 0, .debounce_interval = DA850_LCDK_KEYS_DEBOUNCE_MS, .code = KEY_F7, .gpio = DA850_LCDK_USER_KEY1, .desc = "pb2", }, }; static struct gpio_keys_platform_data omapl138_lcdk_evm_keys_pdata = { .buttons = omapl138_lcdk_evm_keys, .nbuttons = ARRAY_SIZE(omapl138_lcdk_evm_keys), .poll_interval = DA850_LCDK_GPIO_KEYS_POLL_MS, }; static struct platform_device omapl138_lcdk_evm_keys_device = { .name = "gpio-keys-polled", .id = 0, .dev = { .platform_data = &omapl138_lcdk_evm_keys_pdata }, }; static __init void omapl138_lcdk_keys_init(void) { int err; davinci_cfg_reg_list(omapl138_lcdk_keys_pin_mux); err = platform_device_register(&omapl138_lcdk_evm_keys_device); if (err) pr_err("failed to register omapl138_lcdk_evm_keys_device\n"); return; }; static struct davinci_pm_config da850_pm_pdata = { .sleepcount = 128, }; static struct platform_device da850_pm_device = { .name = "pm-davinci", .dev = { .platform_data = &da850_pm_pdata, }, .id = -1, }; #define TVP5147_CH0 "tvp514x-0" #define TVP5147_CH1 "tvp514x-1" #define VPIF_STATUS (0x002C) #define VPIF_STATUS_CLR (0x0030) /* Retaining these APIs, since the VPIF drivers do not check NULL handlers */ static int da850_set_vpif_clock(int mux_mode, int hd) { return 0; } static int da850_setup_vpif_input_channel_mode(int mux_mode) { return 0; } static int da850_vpif_setup_input_path(int ch, const char *name) { if (!strcmp(name, "ov2715")) { printk("set up ov2715 input path\n"); } else if (!strcmp(name, "tvp5147")) { printk("set up tvp5147 input path\n"); } else { printk("unknown input path\n"); } return 1; } static int da850_vpif_intr_status(void __iomem *vpif_base, int channel) { int status = 0; int mask; if (channel < 0 || channel > 3) return 0; mask = 1 << channel; status = __raw_readl((vpif_base + VPIF_STATUS)) & mask; __raw_writel(status, (vpif_base + VPIF_STATUS_CLR)); return status; } //#define CONFIG_LCDK_UI_SD_VIDEO_PORT 1 #define CONFIG_LCDK_UI_CAMERA 2 #if defined(CONFIG_LCDK_UI_SD_VIDEO_PORT) /* VPIF capture configuration */ static struct tvp514x_platform_data tvp5147_pdata = { .clk_polarity = 0, .hs_polarity = 1, .vs_polarity = 1 }; #endif #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) static struct vpif_subdev_info da850_vpif_capture_sdev_info[] = { #if defined(CONFIG_LCDK_UI_CAMERA) { .name = "ov2715", .board_info = { I2C_BOARD_INFO("ov2715", 0x6C>>1), .platform_data = (void *)1, }, .vpif_if = { .if_type = VPIF_IF_RAW_BAYER, .hd_pol = 0, .vd_pol = 0, .fid_pol = 0, }, }, #elif defined(CONFIG_LCDK_UI_SD_VIDEO_PORT) { .name = TVP5147_CH0, .board_info = { I2C_BOARD_INFO("tvp5147", 0xBA>>1), .platform_data = &tvp5147_pdata, }, .input = INPUT_CVBS_VI2B, .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, .can_route = 1, .vpif_if = { .if_type = VPIF_IF_BT656, .hd_pol = 1, .vd_pol = 1, .fid_pol = 0, }, }, #endif }; #if defined(CONFIG_LCDK_UI_CAMERA) static const struct vpif_input da850_ch0_inputs[] = { { .input = { .index = 0, .name = "ov2715", .type = V4L2_INPUT_TYPE_CAMERA, .std = V4L2_STD_BAYER_720,//V4L2_STD_BAYER_1920, }, .subdev_name = "ov2715", }, }; static const struct vpif_input da850_ch1_inputs[] = { { .input = { .index = 0, .name = "ov2715", .type = V4L2_INPUT_TYPE_CAMERA, .std = V4L2_STD_BAYER_720,//V4L2_STD_BAYER_1920, }, .subdev_name = "ov2715", }, }; #elif defined(CONFIG_LCDK_UI_SD_VIDEO_PORT) static const struct vpif_input da850_ch0_inputs[] = { { .input = { .index = 0, .name = "Composite", .type = V4L2_INPUT_TYPE_CAMERA, .std = TVP514X_STD_ALL, }, .subdev_name = TVP5147_CH0, }, }; static const struct vpif_input da850_ch1_inputs[] = { { .input = { .index = 0, .name = "Composite", .type = V4L2_INPUT_TYPE_CAMERA, .std = TVP514X_STD_ALL, }, .subdev_name = TVP5147_CH1, }, }; #endif static struct vpif_capture_config da850_vpif_capture_config = { .setup_input_channel_mode = da850_setup_vpif_input_channel_mode, .setup_input_path = da850_vpif_setup_input_path, .intr_status = da850_vpif_intr_status, .subdev_info = da850_vpif_capture_sdev_info, .subdev_count = ARRAY_SIZE(da850_vpif_capture_sdev_info), .chan_config[0] = { .inputs = da850_ch0_inputs, .input_count = ARRAY_SIZE(da850_ch0_inputs), }, .chan_config[1] = { .inputs = da850_ch1_inputs, .input_count = ARRAY_SIZE(da850_ch1_inputs), }, .card_name = "DA850/OMAP-L138 Video Capture", }; static const char *vpif_output[] = { "Composite", "Component", "S-Video", }; static struct vpif_display_config da850_vpif_display_config = { .set_clock = da850_set_vpif_clock, .intr_status = da850_vpif_intr_status, .subdevinfo = NULL, .subdev_count = 0, .output = vpif_output, .output_count = ARRAY_SIZE(vpif_output), .card_name = "DA850/OMAP-L138 Video Display", }; #if defined(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) ||\ defined(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY_MODULE) #define HAS_VPIF_DISPLAY 1 #else #define HAS_VPIF_DISPLAY 0 #endif #if defined(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) ||\ defined(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE_MODULE) #define HAS_VPIF_CAPTURE 1 #else #define HAS_VPIF_CAPTURE 0 #endif static __init void omapl138_lcdk_init(void) { int ret; davinci_serial_init(&omapl138_lcdk_uart_config); /* * shut down uart 0 and 1; they are not used on this board and * accessing them causes endless "too much work in irq53" messages * with arago fs */ __raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); omapl138_lcdk_config_emac(); ret = da850_register_edma(da850_edma_rsv); if (ret) pr_warning("%s: EDMA registration failed: %d\n", __func__, ret); omapl138_lcdk_mmc_init(); omapl138_lcdk_usb_init(); ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_lcdk_init: " "watchdog registration failed: %d\n", ret); ret = da8xx_register_rtc(); if (ret) pr_warning("omapl138_lcdk_init: rtc setup failed: %d\n", ret); omapl138_lcdk_i2c_init(); omapl138_lcdk_sound_init(); ret = da850_register_sata(LCDKBOARD_SATA_REFCLKPN_RATE); if (ret) pr_warning("omapl138_lcdk_init: sata registration failed: %d\n", ret); ret = da850_register_pm(&da850_pm_device); if (ret) pr_warning("da850_evm_init: suspend registration failed: %d\n", ret); if (HAS_VPIF_DISPLAY || HAS_VPIF_CAPTURE) { ret = da850_register_vpif(); if (ret) pr_warning("da850_evm_init: VPIF setup failed: %d\n", ret); } if (HAS_VPIF_CAPTURE) { ret = davinci_cfg_reg_list(da850_vpif_capture_pins); if (ret) pr_warning("da850_evm_init: VPIF capture mux failed:" "%d\n", ret); ret = da850_register_vpif_capture(&da850_vpif_capture_config); if (ret) pr_warning("da850_evm_init: VPIF capture setup failed:" "%d\n", ret); } if (HAS_VPIF_DISPLAY) { ret = davinci_cfg_reg_list(da850_vpif_display_pins); if (ret) pr_warning("da850_evm_init : VPIF capture mux failed :" "%d\n", ret); ret = da850_register_vpif_display(&da850_vpif_display_config); if (ret) pr_warning("da850_evm_init: VPIF display setup failed:" "%d\n", ret); } omapl138_lcdk_led_init(); omapl138_lcdk_keys_init(); omapl138_lcdk_nand_init(); omapl138_lcdk_display_init(); } #ifdef CONFIG_SERIAL_8250_CONSOLE static int __init omapl138_lcdk_console_init(void) { if (!machine_is_omapl138_lcdkboard()) return 0; return add_preferred_console("ttyS", 2, "115200"); } console_initcall(omapl138_lcdk_console_init); #endif static void __init omapl138_lcdk_map_io(void) { da850_init(); } MACHINE_START(OMAPL138_LCDKBOARD, "AM18x/OMAP-L138 lcdk board") .atag_offset = 0x100, .map_io = omapl138_lcdk_map_io, .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = omapl138_lcdk_init, .dma_zone_size = SZ_128M, .restart = da8xx_restart, MACHINE_END
/* * vpif - Video Port Interface driver * VPIF is a receiver and transmitter for video data. It has two channels(0, 1) * that receiveing video byte stream and two channels(2, 3) for video output. * The hardware supports SDTV, HDTV formats, raw data capture. * Currently, the driver supports NTSC and PAL standards. * * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2. * * This program is distributed .as is. WITHOUT ANY WARRANTY of any * kind, whether express or implied; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/kernel.h> #include <linux/io.h> #include <linux/clk.h> #include <linux/err.h> #include <mach/hardware.h> #include <linux/uaccess.h> #include <linux/proc_fs.h> #include "vpif.h" MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver"); MODULE_LICENSE("GPL"); #define VPIF_CH0_MAX_MODES (22) #define VPIF_CH1_MAX_MODES (02) #define VPIF_CH2_MAX_MODES (15) #define VPIF_CH3_MAX_MODES (02) static resource_size_t res_len; static struct resource *res; spinlock_t vpif_lock; void __iomem *vpif_base; struct clk *vpif_clk; /** * ch_params: video standard configuration parameters for vpif * The table must include all presets from supported subdevices. */ const struct vpif_channel_config_params ch_params[] = { /* raw bayer Camera standars */ { .name = "CAMERA", .width = 640, .height = 480, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 0, .sav2eav = 0, .l1 = 0, .l3 = 0, .l5 = 0, .l7 = 0, .l9 = 0, .l11 = 0, .vsize = 0, .capture_format = 1, .vbi_supported = 0, .hd_sd = 0, .stdid = V4L2_STD_BAYER_640, }, { .name = "CAMERA", .width = 1024, .height = 768, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 0, .sav2eav = 0, .l1 = 0, .l3 = 0, .l5 = 0, .l7 = 0, .l9 = 0, .l11 = 0, .vsize = 0, .capture_format = 1, .vbi_supported = 0, .hd_sd = 0, .stdid = V4L2_STD_BAYER_1024, }, { .name = "CAMERA", .width = 1280, .height = 1024, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 0, .sav2eav = 0, .l1 = 0, .l3 = 0, .l5 = 0, .l7 = 0, .l9 = 0, .l11 = 0, .vsize = 0, .capture_format = 1, .vbi_supported = 0, .hd_sd = 0, .stdid = V4L2_STD_BAYER_1280, }, { .name = "CAMERA", .width = 1600, .height = 1200, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 0, .sav2eav = 0, .l1 = 0, .l3 = 0, .l5 = 0, .l7 = 0, .l9 = 0, .l11 = 0, .vsize = 0, .capture_format = 1, .vbi_supported = 0, .hd_sd = 0, .stdid = V4L2_STD_BAYER_1600, }, { .name = "CAMERA", .width = 2048, .height = 1536, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 0, .sav2eav = 0, .l1 = 0, .l3 = 0, .l5 = 0, .l7 = 0, .l9 = 0, .l11 = 0, .vsize = 0, .capture_format = 1, .vbi_supported = 0, .hd_sd = 0, .stdid = V4L2_STD_BAYER_2048, }, { .name = "CAMERA", .width = 1920, .height = 1080, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 0, .sav2eav = 0, .l1 = 0, .l3 = 0, .l5 = 0, .l7 = 0, .l9 = 0, .l11 = 0, .vsize = 0, .capture_format = 1, .vbi_supported = 0, .hd_sd = 0, .stdid = V4L2_STD_BAYER_1920, }, { .name = "CAMERA", .width = 1280, .height = 720, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 0, .sav2eav = 0, .l1 = 0, .l3 = 0, .l5 = 0, .l7 = 0, .l9 = 0, .l11 = 0, .vsize = 0, .capture_format = 1, .vbi_supported = 0, .hd_sd = 0, .stdid = V4L2_STD_BAYER_720, }, /* HDTV formats */ { .name = "480p59_94", .width = 720, .height = 480, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 138-8, .sav2eav = 720, .l1 = 1, .l3 = 43, .l5 = 523, .vsize = 525, .capture_format = 0, .vbi_supported = 0, .hd_sd = 1, .dv_preset = V4L2_DV_480P59_94, }, { .name = "576p50", .width = 720, .height = 576, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 144-8, .sav2eav = 720, .l1 = 1, .l3 = 45, .l5 = 621, .vsize = 625, .capture_format = 0, .vbi_supported = 0, .hd_sd = 1, .dv_preset = V4L2_DV_576P50, }, { .name = "720p50", .width = 1280, .height = 720, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 700-8, .sav2eav = 1280, .l1 = 1, .l3 = 26, .l5 = 746, .vsize = 750, .capture_format = 0, .vbi_supported = 0, .hd_sd = 1, .dv_preset = V4L2_DV_720P50, }, { .name = "720p60", .width = 1280, .height = 720, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 370 - 8, .sav2eav = 1280, .l1 = 1, .l3 = 26, .l5 = 746, .vsize = 750, .capture_format = 0, .vbi_supported = 0, .hd_sd = 1, .dv_preset = V4L2_DV_720P60, }, { .name = "1080I50", .width = 1920, .height = 1080, .frm_fmt = 0, .ycmux_mode = 0, .eav2sav = 720 - 8, .sav2eav = 1920, .l1 = 1, .l3 = 21, .l5 = 561, .l7 = 563, .l9 = 584, .l11 = 1124, .vsize = 1125, .capture_format = 0, .vbi_supported = 0, .hd_sd = 1, .dv_preset = V4L2_DV_1080I50, }, { .name = "1080I60", .width = 1920, .height = 1080, .frm_fmt = 0, .ycmux_mode = 0, .eav2sav = 280 - 8, .sav2eav = 1920, .l1 = 1, .l3 = 21, .l5 = 561, .l7 = 563, .l9 = 584, .l11 = 1124, .vsize = 1125, .capture_format = 0, .vbi_supported = 0, .hd_sd = 1, .dv_preset = V4L2_DV_1080I60, }, { .name = "1080p60", .width = 1920, .height = 1080, .frm_fmt = 1, .ycmux_mode = 0, .eav2sav = 280 - 8, .sav2eav = 1920, .l1 = 1, .l3 = 42, .l5 = 1122, .vsize = 1125, .capture_format = 0, .vbi_supported = 0, .hd_sd = 1, .dv_preset = V4L2_DV_1080P60, }, /* SDTV formats */ { .name = "NTSC_M", .width = 720, .height = 480, .frm_fmt = 0, .ycmux_mode = 1, .eav2sav = 268, .sav2eav = 1440, .l1 = 1, .l3 = 23, .l5 = 263, .l7 = 266, .l9 = 286, .l11 = 525, .vsize = 525, .capture_format = 0, .vbi_supported = 1, .hd_sd = 0, .stdid = V4L2_STD_525_60, }, { .name = "PAL_BDGHIK", .width = 720, .height = 576, .frm_fmt = 0, .ycmux_mode = 1, .eav2sav = 280, .sav2eav = 1440, .l1 = 1, .l3 = 23, .l5 = 311, .l7 = 313, .l9 = 336, .l11 = 624, .vsize = 625, .capture_format = 0, .vbi_supported = 1, .hd_sd = 0, .stdid = V4L2_STD_625_50, }, }; const unsigned int vpif_ch_params_count = ARRAY_SIZE(ch_params); static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val) { if (val) vpif_set_bit(reg, bit); else vpif_clr_bit(reg, bit); } /* This structure is used to keep track of VPIF size register's offsets */ struct vpif_registers { u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl; u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt; u32 vanc1_size, width_mask, len_mask; u8 max_modes; }; static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = { /* Channel0 */ { VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01, VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL, VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF, VPIF_CH0_MAX_MODES, }, /* Channel1 */ { VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01, VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL, VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF, VPIF_CH1_MAX_MODES, }, /* Channel2 */ { VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01, VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL, VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE, VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF, VPIF_CH2_MAX_MODES }, /* Channel3 */ { VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01, VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL, VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE, VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF, VPIF_CH3_MAX_MODES }, }; /* vpif_set_mode_info: * This function is used to set horizontal and vertical config parameters * As per the standard in the channel, configure the values of L1, L3, * L5, L7 L9, L11 in VPIF Register , also write width and height */ static void vpif_set_mode_info(const struct vpif_channel_config_params *config, u8 channel_id, u8 config_channel_id) { u32 value; value = (config->eav2sav & vpifregs[config_channel_id].width_mask); value <<= VPIF_CH_LEN_SHIFT; value |= (config->sav2eav & vpifregs[config_channel_id].width_mask); regw(value, vpifregs[channel_id].h_cfg); value = (config->l1 & vpifregs[config_channel_id].len_mask); value <<= VPIF_CH_LEN_SHIFT; value |= (config->l3 & vpifregs[config_channel_id].len_mask); regw(value, vpifregs[channel_id].v_cfg_00); value = (config->l5 & vpifregs[config_channel_id].len_mask); value <<= VPIF_CH_LEN_SHIFT; value |= (config->l7 & vpifregs[config_channel_id].len_mask); regw(value, vpifregs[channel_id].v_cfg_01); value = (config->l9 & vpifregs[config_channel_id].len_mask); value <<= VPIF_CH_LEN_SHIFT; value |= (config->l11 & vpifregs[config_channel_id].len_mask); regw(value, vpifregs[channel_id].v_cfg_02); value = (config->vsize & vpifregs[config_channel_id].len_mask); regw(value, vpifregs[channel_id].v_cfg); } #if 0 #define DATA_IS_CAPTURED_ON_RISING_EDGE 0 #define DATE_BIT_WIDTH 0 /*8-bit*/ #define INTLINE_INTERVAL 0xFF #define FIELD_ID_POLARITY_INVERT 0 #define VVINV_POLARITY_INVERT 0 #define HVINV_POLARITY_INVERT 0 #define INTFRAME 2 #endif #define DATE_BIT_WIDTH 0x02 /*8-bit*/ #define INTLINE_INTERVAL 0xFF #define DATA_IS_CAPTURED_ON_RISING_EDGE 0 #define FIELD_ID_POLARITY_INVERT 0 #define VVINV_POLARITY_INVERT 0 #define HVINV_POLARITY_INVERT 0 #define INTFRAME 0 /* config_vpif_params * Function to set the parameters of a channel * Mainly modifies the channel ciontrol register * It sets frame format, yc mux mode */ static void config_vpif_params(struct vpif_params *vpifparams, u8 channel_id, u8 found) { const struct vpif_channel_config_params *config = &vpifparams->std_info; u32 value, ch_nip, reg; u8 start, end; int i; start = channel_id; end = channel_id + found; vpifparams->params.data_sz = DATE_BIT_WIDTH;//0x02;//12-bits/pixel for (i = start; i < end; i++) { reg = vpifregs[i].ch_ctrl; if (channel_id < 2) ch_nip = VPIF_CAPTURE_CH_NIP; else ch_nip = VPIF_DISPLAY_CH_NIP; vpif_wr_bit(reg, ch_nip, config->frm_fmt); vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode); vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT, vpifparams->video_params.storage_mode); /* Set raster scanning SDR Format */ vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT); vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format); if (channel_id > 1) /* Set the Pixel enable bit */ vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT); else if (config->capture_format) { /* Set the polarity of various pins */ vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT, vpifparams->iface.fid_pol); vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT, vpifparams->iface.vd_pol); vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT, vpifparams->iface.hd_pol); value = regr(reg); /* Set data width */ value &= ~(((unsigned int)(0x3)) << VPIF_CH_DATA_WIDTH_BIT); value |= ((vpifparams->params.data_sz) << VPIF_CH_DATA_WIDTH_BIT); regw(value, reg); } vpif_wr_bit(reg, 16, INTLINE_INTERVAL); vpif_wr_bit(reg, 17, INTLINE_INTERVAL); vpif_wr_bit(reg, 18, INTLINE_INTERVAL); vpif_wr_bit(reg, 19, INTLINE_INTERVAL); vpif_wr_bit(reg, 7, INTFRAME&0x02); vpif_wr_bit(reg, 6, INTFRAME&0x01); /* Write the pitch in the driver */ regw((vpifparams->video_params.hpitch), vpifregs[i].line_offset); } } /* vpif_set_video_params * This function is used to set video parameters in VPIF register */ int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id) { const struct vpif_channel_config_params *config = &vpifparams->std_info; int found = 1; vpif_set_mode_info(config, channel_id, channel_id); if (!config->ycmux_mode) { /* YC are on separate channels (HDTV formats) */ printk("YC are on separate channel\n"); vpif_set_mode_info(config, channel_id + 1, channel_id); found = 2; } config_vpif_params(vpifparams, channel_id, found); regw(0x80, VPIF_REQ_SIZE); regw(0x01, VPIF_EMULATION_CTRL); return found; } EXPORT_SYMBOL(vpif_set_video_params); void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams, u8 channel_id) { u32 value; value = 0x3F8 & (vbiparams->hstart0); value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16); regw(value, vpifregs[channel_id].vanc0_strt); value = 0x3F8 & (vbiparams->hstart1); value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16); regw(value, vpifregs[channel_id].vanc1_strt); value = 0x3F8 & (vbiparams->hsize0); value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16); regw(value, vpifregs[channel_id].vanc0_size); value = 0x3F8 & (vbiparams->hsize1); value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16); regw(value, vpifregs[channel_id].vanc1_size); } EXPORT_SYMBOL(vpif_set_vbi_display_params); int vpif_channel_getfid(u8 channel_id) { return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK) >> VPIF_CH_FID_SHIFT; } EXPORT_SYMBOL(vpif_channel_getfid); int vpif_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) { count = 0; off=0; memset(page, 0, PAGE_SIZE); count = sprintf(page, "Help:\n" "\tcmd value1(cmd id)\n" "\tstate 0 ---state info :[id]\n" "\twrite reg 1 ---write reg :[id off val]\n" "\tread reg 2 ---read reg :[id off]\n" ); return count; } extern void __iomem *da8xx_syscfg0_base; int vpif_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) { char buf[100]; char *p = (char *)buf; unsigned long len = min((sizeof(buf)-1), (u32)count); unsigned long val[4]={0,0,0,0}; char *end=NULL; int i=0, j=0; u32 reg_value; u8 reg_offset; u32 pinmuxbase; memset(buf, 0, sizeof(char)*100); if(copy_from_user(buf, buffer, len)) return count; buf[len] = ' '; i=0; while(i++<len && j<4){ if(*p==' '){ p++; continue; } if(p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X'){ p++; if(p[0] == 'x' || p[0] == 'X') p++; val[j++] = simple_strtoul(p, &end, 16); p = end; }else{ val[j++] = simple_strtoul(p, &end, 10); p = end; } } printk("val[0]=0x%x, val[1]=0x%x, val[2]=0x%x, val[3]=0x%x\n\n", val[0], val[1], val[2], val[3]); switch(val[0]){ case 0: case 1: reg_value = val[1]; reg_offset = val[2]; regw(reg_value, reg_offset); break; case 2: reg_offset = val[1]; reg_value = regr(reg_offset); printk("read [0x%x] value is 0x%x\n", reg_offset, reg_value); break; case 3: printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 0x120/4 + 15) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 1) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 2) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 3) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 4) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 5) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 6) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 7) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 8) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 0x18) ); printk("pinmux 15=0x%x\n", __raw_readl(da8xx_syscfg0_base + 0x15c) ); break; default : break; } return len; } int vpif_proc_init() { struct proc_dir_entry *proc_cmd; proc_cmd = create_proc_entry("vpif", S_IFREG | S_IRUGO, NULL); if (!proc_cmd) { printk("create_proc_entry: %s return failure \n", "vpif"); } proc_cmd->write_proc = vpif_proc_write; proc_cmd->read_proc = vpif_proc_read; return 0; } static int __init vpif_probe(struct platform_device *pdev) { int status = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; res_len = resource_size(res); res = request_mem_region(res->start, res_len, res->name); if (!res) return -EBUSY; vpif_base = ioremap(res->start, res_len); if (!vpif_base) { status = -EBUSY; goto fail; } vpif_clk = clk_get(&pdev->dev, "vpif"); if (IS_ERR(vpif_clk)) { status = PTR_ERR(vpif_clk); goto clk_fail; } clk_enable(vpif_clk); spin_lock_init(&vpif_lock); dev_info(&pdev->dev, "vpif probe success\n"); vpif_proc_init(); return 0; clk_fail: iounmap(vpif_base); fail: release_mem_region(res->start, res_len); return status; } static int __devexit vpif_remove(struct platform_device *pdev) { if (vpif_clk) { clk_disable(vpif_clk); clk_put(vpif_clk); } iounmap(vpif_base); release_mem_region(res->start, res_len); return 0; } #ifdef CONFIG_PM static int vpif_suspend(struct device *dev) { clk_disable(vpif_clk); return 0; } static int vpif_resume(struct device *dev) { clk_enable(vpif_clk); return 0; } static const struct dev_pm_ops vpif_pm = { .suspend = vpif_suspend, .resume = vpif_resume, }; #define vpif_pm_ops (&vpif_pm) #else #define vpif_pm_ops NULL #endif static struct platform_driver vpif_driver = { .driver = { .name = "vpif", .owner = THIS_MODULE, .pm = vpif_pm_ops, }, .remove = __devexit_p(vpif_remove), .probe = vpif_probe, }; static void vpif_exit(void) { platform_driver_unregister(&vpif_driver); } static int __init vpif_init(void) { return platform_driver_register(&vpif_driver); } subsys_initcall(vpif_init); module_exit(vpif_exit);
reg[0x 0]=0x4c080a01 reg[0x 4]=0x20011405 reg[0x 8]=0x 405 reg[0x c]=0x 0 reg[0x 10]=0x 0 reg[0x 14]=0x 0 reg[0x 18]=0x 0 reg[0x 1c]=0x 0 reg[0x 20]=0x 13 reg[0x 24]=0x 13 reg[0x 28]=0x 0 reg[0x 2c]=0x 0 reg[0x 30]=0x 0 reg[0x 34]=0x 1 reg[0x 38]=0x 100 reg[0x 3c]=0x 0 reg[0x 40]=0xc6400400 reg[0x 44]=0xc6400e00 reg[0x 48]=0xc6400400 reg[0x 4c]=0xc6400e00 reg[0x 50]=0x 0 reg[0x 54]=0x 0 reg[0x 58]=0x 0 reg[0x 5c]=0x 0 reg[0x 60]=0x 0 reg[0x 64]=0x a00 reg[0x 68]=0x 0 reg[0x 6c]=0x 640500 reg[0x 70]=0x 0 reg[0x 74]=0x 2d00000 reg[0x 78]=0x 0 reg[0x 7c]=0x 2d0 reg[0x 80]=0xc6400400 reg[0x 84]=0x 0 reg[0x 88]=0xc64e1400 reg[0x 8c]=0xc64e1e00 reg[0x 90]=0x 0 reg[0x 94]=0x 0 reg[0x 98]=0x 0 reg[0x 9c]=0x 0 reg[0x a0]=0x 0 reg[0x a4]=0x a00 reg[0x a8]=0x 0 reg[0x ac]=0x 0 reg[0x b0]=0x 0 reg[0x b4]=0x 0 reg[0x b8]=0x 0 reg[0x bc]=0x 2d0 reg[0x c0]=0x 0 reg[0x c4]=0x 0 reg[0x c8]=0x 0 reg[0x cc]=0x 0 reg[0x d0]=0x 0 reg[0x d4]=0x 0 reg[0x d8]=0x 0 reg[0x dc]=0x 0 reg[0x e0]=0x 0 reg[0x e4]=0x 0 reg[0x e8]=0x 0 reg[0x ec]=0x 0 reg[0x f0]=0x 0 reg[0x f4]=0x 0 reg[0x f8]=0x 0 reg[0x fc]=0x 0 reg[0x100]=0x 0 reg[0x104]=0x 0 reg[0x108]=0x 0 reg[0x10c]=0x 0 reg[0x110]=0x 0 reg[0x114]=0x 0 reg[0x118]=0x 0 reg[0x11c]=0x 0 reg[0x120]=0x 0 reg[0x124]=0x 0 reg[0x128]=0x 0 reg[0x12c]=0x 0 reg[0x130]=0x 0 reg[0x134]=0x 0 reg[0x138]=0x 0 reg[0x13c]=0x 0 reg[0x140]=0x 0 reg[0x144]=0x 0 reg[0x148]=0x 0 reg[0x14c]=0x 0 reg[0x150]=0x 0 reg[0x154]=0x 0 reg[0x158]=0x 0 reg[0x15c]=0x 0 reg[0x160]=0x 0 reg[0x164]=0x 0 reg[0x168]=0x 0 reg[0x16c]=0x 0 reg[0x170]=0x 0 reg[0x174]=0x 0 reg[0x178]=0x 0 reg[0x17c]=0x 0 reg[0x180]=0x 0 reg[0x184]=0x 0 reg[0x188]=0x 0 reg[0x18c]=0x 0 reg[0x190]=0x 0 reg[0x194]=0x 0 reg[0x198]=0x 0 reg[0x19c]=0x 0 root@omapl138-lcdk:/proc#