Linux Audio

Check our new training course

In-person Linux kernel drivers training

Jun 16-20, 2025
Register
Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * linux/arch/arm/mach-tcc8k/devices.c
  3 *
  4 * Copyright (C) Telechips, Inc.
  5 * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
  6 *
  7 * Licensed under the terms of GPL v2.
  8 *
  9 */
 10
 11#include <linux/dma-mapping.h>
 12#include <linux/init.h>
 13#include <linux/io.h>
 14#include <linux/kernel.h>
 15#include <linux/module.h>
 16
 17#include <asm/mach/map.h>
 18
 19#include <mach/tcc8k-regs.h>
 20#include <mach/irqs.h>
 21
 22#include "common.h"
 23
 24static u64 tcc8k_dmamask = DMA_BIT_MASK(32);
 25
 26#ifdef CONFIG_MTD_NAND_TCC
 27/* NAND controller */
 28static struct resource tcc_nand_resources[] = {
 29	{
 30		.start	= (resource_size_t)NFC_BASE,
 31		.end	= (resource_size_t)NFC_BASE + 0x7f,
 32		.flags	= IORESOURCE_MEM,
 33	}, {
 34		.start	= INT_NFC,
 35		.end	= INT_NFC,
 36		.flags	= IORESOURCE_IRQ,
 37	},
 38};
 39
 40struct platform_device tcc_nand_device = {
 41	.name = "tcc_nand",
 42	.id = 0,
 43	.num_resources = ARRAY_SIZE(tcc_nand_resources),
 44	.resource = tcc_nand_resources,
 45};
 46#endif
 47
 48#ifdef CONFIG_MMC_TCC8K
 49/* MMC controller */
 50static struct resource tcc8k_mmc0_resource[] = {
 51	{
 52		.start = INT_SD0,
 53		.end   = INT_SD0,
 54		.flags = IORESOURCE_IRQ,
 55	},
 56};
 57
 58static struct resource tcc8k_mmc1_resource[] = {
 59	{
 60		.start = INT_SD1,
 61		.end   = INT_SD1,
 62		.flags = IORESOURCE_IRQ,
 63	},
 64};
 65
 66struct platform_device tcc8k_mmc0_device = {
 67	.name		= "tcc-mmc",
 68	.id		= 0,
 69	.num_resources	= ARRAY_SIZE(tcc8k_mmc0_resource),
 70	.resource	= tcc8k_mmc0_resource,
 71	.dev		= {
 72		.dma_mask		= &tcc8k_dmamask,
 73		.coherent_dma_mask	= DMA_BIT_MASK(32),
 74	}
 75};
 76
 77struct platform_device tcc8k_mmc1_device = {
 78	.name		= "tcc-mmc",
 79	.id		= 1,
 80	.num_resources	= ARRAY_SIZE(tcc8k_mmc1_resource),
 81	.resource	= tcc8k_mmc1_resource,
 82	.dev		= {
 83		.dma_mask		= &tcc8k_dmamask,
 84		.coherent_dma_mask	= DMA_BIT_MASK(32),
 85	}
 86};
 87
 88static inline void tcc8k_init_mmc(void)
 89{
 90	u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS);
 91
 92	reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS;
 93	__raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS);
 94
 95	platform_device_register(&tcc8k_mmc0_device);
 96	platform_device_register(&tcc8k_mmc1_device);
 97}
 98#else
 99static inline void tcc8k_init_mmc(void) { }
100#endif
101
102#ifdef CONFIG_USB_OHCI_HCD
103static int tcc8k_ohci_init(struct device *dev)
104{
105	u32 reg;
106
107	/* Use GPIO PK19 as VBUS control output */
108	reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS);
109	reg &= ~(1 << 19);
110	__raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS);
111	reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS);
112	reg &= ~(1 << 19);
113	__raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS);
114
115	reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS);
116	reg |= (1 << 19);
117	__raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS);
118	/* Turn on VBUS */
119	reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS);
120	reg |= (1 << 19);
121	__raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS);
122
123	return 0;
124}
125
126static struct resource tcc8k_ohci0_resources[] = {
127	[0] = {
128		.start = (resource_size_t)USBH0_BASE,
129		.end   = (resource_size_t)USBH0_BASE + 0x5c,
130		.flags = IORESOURCE_MEM,
131	},
132	[1] = {
133		.start = INT_USBH0,
134		.end   = INT_USBH0,
135		.flags = IORESOURCE_IRQ,
136	}
137};
138
139static struct resource tcc8k_ohci1_resources[] = {
140	[0] = {
141		.start = (resource_size_t)USBH1_BASE,
142		.end   = (resource_size_t)USBH1_BASE + 0x5c,
143		.flags = IORESOURCE_MEM,
144	},
145	[1] = {
146		.start = INT_USBH1,
147		.end   = INT_USBH1,
148		.flags = IORESOURCE_IRQ,
149	}
150};
151
152static struct tccohci_platform_data tcc8k_ohci0_platform_data = {
153	.controller	= 0,
154	.port_mode	= PMM_PERPORT_MODE,
155	.init		= tcc8k_ohci_init,
156};
157
158static struct tccohci_platform_data tcc8k_ohci1_platform_data = {
159	.controller	= 1,
160	.port_mode	= PMM_PERPORT_MODE,
161	.init		= tcc8k_ohci_init,
162};
163
164static struct platform_device ohci0_device = {
165	.name = "tcc-ohci",
166	.id = 0,
167	.dev = {
168		.dma_mask = &tcc8k_dmamask,
169		.coherent_dma_mask = DMA_BIT_MASK(32),
170		.platform_data = &tcc8k_ohci0_platform_data,
171	},
172	.num_resources  = ARRAY_SIZE(tcc8k_ohci0_resources),
173	.resource       = tcc8k_ohci0_resources,
174};
175
176static struct platform_device ohci1_device = {
177	.name = "tcc-ohci",
178	.id = 1,
179	.dev = {
180		.dma_mask = &tcc8k_dmamask,
181		.coherent_dma_mask = DMA_BIT_MASK(32),
182		.platform_data = &tcc8k_ohci1_platform_data,
183	},
184	.num_resources  = ARRAY_SIZE(tcc8k_ohci1_resources),
185	.resource       = tcc8k_ohci1_resources,
186};
187
188static void __init tcc8k_init_usbhost(void)
189{
190	platform_device_register(&ohci0_device);
191	platform_device_register(&ohci1_device);
192}
193#else
194static void __init tcc8k_init_usbhost(void) { }
195#endif
196
197/* USB device controller*/
198#ifdef CONFIG_USB_GADGET_TCC8K
199static struct resource udc_resources[] = {
200	[0] = {
201		.start = INT_USBD,
202		.end   = INT_USBD,
203		.flags = IORESOURCE_IRQ,
204	},
205	[1] = {
206		.start = INT_UDMA,
207		.end   = INT_UDMA,
208		.flags = IORESOURCE_IRQ,
209	},
210};
211
212static struct platform_device tcc8k_udc_device = {
213	.name = "tcc-udc",
214	.id = 0,
215	.resource = udc_resources,
216	.num_resources = ARRAY_SIZE(udc_resources),
217	.dev = {
218		 .dma_mask = &tcc8k_dmamask,
219		 .coherent_dma_mask = DMA_BIT_MASK(32),
220	},
221};
222
223static void __init tcc8k_init_usb_gadget(void)
224{
225	platform_device_register(&tcc8k_udc_device);
226}
227#else
228static void __init tcc8k_init_usb_gadget(void) { }
229#endif	/* CONFIG_USB_GADGET_TCC83X */
230
231static int __init tcc8k_init_devices(void)
232{
233	tcc8k_init_mmc();
234	tcc8k_init_usbhost();
235	tcc8k_init_usb_gadget();
236	return 0;
237}
238
239arch_initcall(tcc8k_init_devices);