1/*
2 *  Copyright (C) 2000 Deep Blue Solutions Ltd
3 *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
4 *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/physmap.h>
20#include <linux/basic_mmio_gpio.h>
21#include <linux/gpio.h>
22#include <linux/regulator/fixed.h>
23#include <linux/regulator/machine.h>
24#include <asm/mach-types.h>
25#include <asm/mach/arch.h>
26
27#include "common.h"
28#include "devices-imx21.h"
29#include "hardware.h"
30#include "iomux-mx21.h"
31
32#define MX21ADS_CS8900A_REG		(MX21_CS1_BASE_ADDR + 0x000000)
33#define MX21ADS_ST16C255_IOBASE_REG	(MX21_CS1_BASE_ADDR + 0x200000)
34#define MX21ADS_VERSION_REG		(MX21_CS1_BASE_ADDR + 0x400000)
35#define MX21ADS_IO_REG			(MX21_CS1_BASE_ADDR + 0x800000)
36
37#define MX21ADS_MMC_CD			IMX_GPIO_NR(4, 25)
38#define MX21ADS_CS8900A_IRQ_GPIO	IMX_GPIO_NR(5, 11)
39#define MX21ADS_MMGPIO_BASE		(6 * 32)
40
41/* MX21ADS_IO_REG bit definitions */
42#define MX21ADS_IO_SD_WP		(MX21ADS_MMGPIO_BASE + 0)
43#define MX21ADS_IO_TP6			(MX21ADS_IO_SD_WP)
44#define MX21ADS_IO_SW_SEL		(MX21ADS_MMGPIO_BASE + 1)
45#define MX21ADS_IO_TP7			(MX21ADS_IO_SW_SEL)
46#define MX21ADS_IO_RESET_E_UART		(MX21ADS_MMGPIO_BASE + 2)
47#define MX21ADS_IO_RESET_BASE		(MX21ADS_MMGPIO_BASE + 3)
48#define MX21ADS_IO_CSI_CTL2		(MX21ADS_MMGPIO_BASE + 4)
49#define MX21ADS_IO_CSI_CTL1		(MX21ADS_MMGPIO_BASE + 5)
50#define MX21ADS_IO_CSI_CTL0		(MX21ADS_MMGPIO_BASE + 6)
51#define MX21ADS_IO_UART1_EN		(MX21ADS_MMGPIO_BASE + 7)
52#define MX21ADS_IO_UART4_EN		(MX21ADS_MMGPIO_BASE + 8)
53#define MX21ADS_IO_LCDON		(MX21ADS_MMGPIO_BASE + 9)
54#define MX21ADS_IO_IRDA_EN		(MX21ADS_MMGPIO_BASE + 10)
55#define MX21ADS_IO_IRDA_FIR_SEL		(MX21ADS_MMGPIO_BASE + 11)
56#define MX21ADS_IO_IRDA_MD0_B		(MX21ADS_MMGPIO_BASE + 12)
57#define MX21ADS_IO_IRDA_MD1		(MX21ADS_MMGPIO_BASE + 13)
58#define MX21ADS_IO_LED4_ON		(MX21ADS_MMGPIO_BASE + 14)
59#define MX21ADS_IO_LED3_ON		(MX21ADS_MMGPIO_BASE + 15)
60
61static const int mx21ads_pins[] __initconst = {
62
63	/* CS8900A */
64	(GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
65
66	/* UART1 */
67	PE12_PF_UART1_TXD,
68	PE13_PF_UART1_RXD,
69	PE14_PF_UART1_CTS,
70	PE15_PF_UART1_RTS,
71
72	/* UART3 (IrDA) - only TXD and RXD */
73	PE8_PF_UART3_TXD,
74	PE9_PF_UART3_RXD,
75
76	/* UART4 */
77	PB26_AF_UART4_RTS,
78	PB28_AF_UART4_TXD,
79	PB29_AF_UART4_CTS,
80	PB31_AF_UART4_RXD,
81
82	/* LCDC */
83	PA5_PF_LSCLK,
84	PA6_PF_LD0,
85	PA7_PF_LD1,
86	PA8_PF_LD2,
87	PA9_PF_LD3,
88	PA10_PF_LD4,
89	PA11_PF_LD5,
90	PA12_PF_LD6,
91	PA13_PF_LD7,
92	PA14_PF_LD8,
93	PA15_PF_LD9,
94	PA16_PF_LD10,
95	PA17_PF_LD11,
96	PA18_PF_LD12,
97	PA19_PF_LD13,
98	PA20_PF_LD14,
99	PA21_PF_LD15,
100	PA22_PF_LD16,
101	PA24_PF_REV,     /* Sharp panel dedicated signal */
102	PA25_PF_CLS,     /* Sharp panel dedicated signal */
103	PA26_PF_PS,      /* Sharp panel dedicated signal */
104	PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
105	PA28_PF_HSYNC,
106	PA29_PF_VSYNC,
107	PA30_PF_CONTRAST,
108	PA31_PF_OE_ACD,
109
110	/* MMC/SDHC */
111	PE18_PF_SD1_D0,
112	PE19_PF_SD1_D1,
113	PE20_PF_SD1_D2,
114	PE21_PF_SD1_D3,
115	PE22_PF_SD1_CMD,
116	PE23_PF_SD1_CLK,
117
118	/* NFC */
119	PF0_PF_NRFB,
120	PF1_PF_NFCE,
121	PF2_PF_NFWP,
122	PF3_PF_NFCLE,
123	PF4_PF_NFALE,
124	PF5_PF_NFRE,
125	PF6_PF_NFWE,
126	PF7_PF_NFIO0,
127	PF8_PF_NFIO1,
128	PF9_PF_NFIO2,
129	PF10_PF_NFIO3,
130	PF11_PF_NFIO4,
131	PF12_PF_NFIO5,
132	PF13_PF_NFIO6,
133	PF14_PF_NFIO7,
134};
135
136/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
137static struct physmap_flash_data mx21ads_flash_data = {
138	.width = 4,
139};
140
141static struct resource mx21ads_flash_resource =
142	DEFINE_RES_MEM(MX21_CS0_BASE_ADDR, SZ_32M);
143
144static struct platform_device mx21ads_nor_mtd_device = {
145	.name = "physmap-flash",
146	.id = 0,
147	.dev = {
148		.platform_data = &mx21ads_flash_data,
149	},
150	.num_resources = 1,
151	.resource = &mx21ads_flash_resource,
152};
153
154static struct resource mx21ads_cs8900_resources[] __initdata = {
155	DEFINE_RES_MEM(MX21ADS_CS8900A_REG, SZ_1K),
156	/* irq number is run-time assigned */
157	DEFINE_RES_IRQ(-1),
158};
159
160static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = {
161	.name = "cs89x0",
162	.id = 0,
163	.res = mx21ads_cs8900_resources,
164	.num_res = ARRAY_SIZE(mx21ads_cs8900_resources),
165};
166
167static const struct imxuart_platform_data uart_pdata_rts __initconst = {
168	.flags = IMXUART_HAVE_RTSCTS,
169};
170
171static const struct imxuart_platform_data uart_pdata_norts __initconst = {
172};
173
174static struct resource mx21ads_mmgpio_resource =
175	DEFINE_RES_MEM_NAMED(MX21ADS_IO_REG, SZ_2, "dat");
176
177static struct bgpio_pdata mx21ads_mmgpio_pdata = {
178	.base	= MX21ADS_MMGPIO_BASE,
179	.ngpio	= 16,
180};
181
182static struct platform_device mx21ads_mmgpio = {
183	.name = "basic-mmio-gpio",
184	.id = PLATFORM_DEVID_AUTO,
185	.resource = &mx21ads_mmgpio_resource,
186	.num_resources = 1,
187	.dev = {
188		.platform_data = &mx21ads_mmgpio_pdata,
189	},
190};
191
192static struct regulator_consumer_supply mx21ads_lcd_regulator_consumer =
193	REGULATOR_SUPPLY("lcd", "imx-fb.0");
194
195static struct regulator_init_data mx21ads_lcd_regulator_init_data = {
196	.constraints = {
197		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
198	},
199	.consumer_supplies	= &mx21ads_lcd_regulator_consumer,
200	.num_consumer_supplies	= 1,
201};
202
203static struct fixed_voltage_config mx21ads_lcd_regulator_pdata = {
204	.supply_name	= "LCD",
205	.microvolts	= 3300000,
206	.gpio		= MX21ADS_IO_LCDON,
207	.enable_high	= 1,
208	.init_data	= &mx21ads_lcd_regulator_init_data,
209};
210
211static struct platform_device mx21ads_lcd_regulator = {
212	.name = "reg-fixed-voltage",
213	.id = PLATFORM_DEVID_AUTO,
214	.dev = {
215		.platform_data = &mx21ads_lcd_regulator_pdata,
216	},
217};
218
219/*
220 * Connected is a portrait Sharp-QVGA display
221 * of type: LQ035Q7DB02
222 */
223static struct imx_fb_videomode mx21ads_modes[] = {
224	{
225		.mode = {
226			.name		= "Sharp-LQ035Q7",
227			.refresh	= 60,
228			.xres		= 240,
229			.yres		= 320,
230			.pixclock	= 188679, /* in ps (5.3MHz) */
231			.hsync_len	= 2,
232			.left_margin	= 6,
233			.right_margin	= 16,
234			.vsync_len	= 1,
235			.upper_margin	= 8,
236			.lower_margin	= 10,
237		},
238		.pcr		= 0xfb108bc7,
239		.bpp		= 16,
240	},
241};
242
243static const struct imx_fb_platform_data mx21ads_fb_data __initconst = {
244	.mode = mx21ads_modes,
245	.num_modes = ARRAY_SIZE(mx21ads_modes),
246
247	.pwmr		= 0x00a903ff,
248	.lscr1		= 0x00120300,
249	.dmacr		= 0x00020008,
250};
251
252static int mx21ads_sdhc_get_ro(struct device *dev)
253{
254	return gpio_get_value(MX21ADS_IO_SD_WP);
255}
256
257static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
258	void *data)
259{
260	int ret;
261
262	ret = gpio_request(MX21ADS_IO_SD_WP, "mmc-ro");
263	if (ret)
264		return ret;
265
266	return request_irq(gpio_to_irq(MX21ADS_MMC_CD), detect_irq,
267			   IRQF_TRIGGER_FALLING, "mmc-detect", data);
268}
269
270static void mx21ads_sdhc_exit(struct device *dev, void *data)
271{
272	free_irq(gpio_to_irq(MX21ADS_MMC_CD), data);
273	gpio_free(MX21ADS_IO_SD_WP);
274}
275
276static const struct imxmmc_platform_data mx21ads_sdhc_pdata __initconst = {
277	.ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
278	.get_ro = mx21ads_sdhc_get_ro,
279	.init = mx21ads_sdhc_init,
280	.exit = mx21ads_sdhc_exit,
281};
282
283static const struct mxc_nand_platform_data
284mx21ads_nand_board_info __initconst = {
285	.width = 1,
286	.hw_ecc = 1,
287};
288
289static struct platform_device *platform_devices[] __initdata = {
290	&mx21ads_mmgpio,
291	&mx21ads_lcd_regulator,
292	&mx21ads_nor_mtd_device,
293};
294
295static void __init mx21ads_board_init(void)
296{
297	imx21_soc_init();
298
299	mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
300			"mx21ads");
301
302	imx21_add_imx_uart0(&uart_pdata_rts);
303	imx21_add_imx_uart2(&uart_pdata_norts);
304	imx21_add_imx_uart3(&uart_pdata_rts);
305	imx21_add_mxc_mmc(0, &mx21ads_sdhc_pdata);
306	imx21_add_mxc_nand(&mx21ads_nand_board_info);
307
308	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
309
310	imx21_add_imx_fb(&mx21ads_fb_data);
311
312	mx21ads_cs8900_resources[1].start =
313			gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO);
314	mx21ads_cs8900_resources[1].end =
315			gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO);
316	platform_device_register_full(&mx21ads_cs8900_devinfo);
317}
318
319static void __init mx21ads_timer_init(void)
320{
321	mx21_clocks_init(32768, 26000000);
322}
323
324MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
325	/* maintainer: Freescale Semiconductor, Inc. */
326	.atag_offset = 0x100,
327	.map_io		= mx21_map_io,
328	.init_early = imx21_init_early,
329	.init_irq = mx21_init_irq,
330	.init_time	= mx21ads_timer_init,
331	.init_machine = mx21ads_board_init,
332	.restart	= mxc_restart,
333MACHINE_END
334