/* * linux/arch/arm/mach-tcc8k/devices.c * * Copyright (C) Telechips, Inc. * Copyright (C) 2009 Hans J. Koch * * Licensed under the terms of GPL v2. * */ #include #include #include #include #include #include #include #include #include "common.h" static u64 tcc8k_dmamask = DMA_BIT_MASK(32); #ifdef CONFIG_MTD_NAND_TCC /* NAND controller */ static struct resource tcc_nand_resources[] = { { .start = (resource_size_t)NFC_BASE, .end = (resource_size_t)NFC_BASE + 0x7f, .flags = IORESOURCE_MEM, }, { .start = INT_NFC, .end = INT_NFC, .flags = IORESOURCE_IRQ, }, }; struct platform_device tcc_nand_device = { .name = "tcc_nand", .id = 0, .num_resources = ARRAY_SIZE(tcc_nand_resources), .resource = tcc_nand_resources, }; #endif #ifdef CONFIG_MMC_TCC8K /* MMC controller */ static struct resource tcc8k_mmc0_resource[] = { { .start = INT_SD0, .end = INT_SD0, .flags = IORESOURCE_IRQ, }, }; static struct resource tcc8k_mmc1_resource[] = { { .start = INT_SD1, .end = INT_SD1, .flags = IORESOURCE_IRQ, }, }; struct platform_device tcc8k_mmc0_device = { .name = "tcc-mmc", .id = 0, .num_resources = ARRAY_SIZE(tcc8k_mmc0_resource), .resource = tcc8k_mmc0_resource, .dev = { .dma_mask = &tcc8k_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), } }; struct platform_device tcc8k_mmc1_device = { .name = "tcc-mmc", .id = 1, .num_resources = ARRAY_SIZE(tcc8k_mmc1_resource), .resource = tcc8k_mmc1_resource, .dev = { .dma_mask = &tcc8k_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), } }; static inline void tcc8k_init_mmc(void) { u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS); reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS; __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS); platform_device_register(&tcc8k_mmc0_device); platform_device_register(&tcc8k_mmc1_device); } #else static inline void tcc8k_init_mmc(void) { } #endif #ifdef CONFIG_USB_OHCI_HCD static int tcc8k_ohci_init(struct device *dev) { u32 reg; /* Use GPIO PK19 as VBUS control output */ reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS); reg &= ~(1 << 19); __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS); reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS); reg &= ~(1 << 19); __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS); reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS); reg |= (1 << 19); __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS); /* Turn on VBUS */ reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS); reg |= (1 << 19); __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS); return 0; } static struct resource tcc8k_ohci0_resources[] = { [0] = { .start = (resource_size_t)USBH0_BASE, .end = (resource_size_t)USBH0_BASE + 0x5c, .flags = IORESOURCE_MEM, }, [1] = { .start = INT_USBH0, .end = INT_USBH0, .flags = IORESOURCE_IRQ, } }; static struct resource tcc8k_ohci1_resources[] = { [0] = { .start = (resource_size_t)USBH1_BASE, .end = (resource_size_t)USBH1_BASE + 0x5c, .flags = IORESOURCE_MEM, }, [1] = { .start = INT_USBH1, .end = INT_USBH1, .flags = IORESOURCE_IRQ, } }; static struct tccohci_platform_data tcc8k_ohci0_platform_data = { .controller = 0, .port_mode = PMM_PERPORT_MODE, .init = tcc8k_ohci_init, }; static struct tccohci_platform_data tcc8k_ohci1_platform_data = { .controller = 1, .port_mode = PMM_PERPORT_MODE, .init = tcc8k_ohci_init, }; static struct platform_device ohci0_device = { .name = "tcc-ohci", .id = 0, .dev = { .dma_mask = &tcc8k_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &tcc8k_ohci0_platform_data, }, .num_resources = ARRAY_SIZE(tcc8k_ohci0_resources), .resource = tcc8k_ohci0_resources, }; static struct platform_device ohci1_device = { .name = "tcc-ohci", .id = 1, .dev = { .dma_mask = &tcc8k_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &tcc8k_ohci1_platform_data, }, .num_resources = ARRAY_SIZE(tcc8k_ohci1_resources), .resource = tcc8k_ohci1_resources, }; static void __init tcc8k_init_usbhost(void) { platform_device_register(&ohci0_device); platform_device_register(&ohci1_device); } #else static void __init tcc8k_init_usbhost(void) { } #endif /* USB device controller*/ #ifdef CONFIG_USB_GADGET_TCC8K static struct resource udc_resources[] = { [0] = { .start = INT_USBD, .end = INT_USBD, .flags = IORESOURCE_IRQ, }, [1] = { .start = INT_UDMA, .end = INT_UDMA, .flags = IORESOURCE_IRQ, }, }; static struct platform_device tcc8k_udc_device = { .name = "tcc-udc", .id = 0, .resource = udc_resources, .num_resources = ARRAY_SIZE(udc_resources), .dev = { .dma_mask = &tcc8k_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), }, }; static void __init tcc8k_init_usb_gadget(void) { platform_device_register(&tcc8k_udc_device); } #else static void __init tcc8k_init_usb_gadget(void) { } #endif /* CONFIG_USB_GADGET_TCC83X */ static int __init tcc8k_init_devices(void) { tcc8k_init_mmc(); tcc8k_init_usbhost(); tcc8k_init_usb_gadget(); return 0; } arch_initcall(tcc8k_init_devices);