• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Support for CompuLab EM-X270 platform
3  *
4  * Copyright (C) 2007, 2008 CompuLab, Ltd.
5  * Author: Mike Rapoport <mike@compulab.co.il>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 
12 #include <linux/irq.h>
13 #include <linux/platform_device.h>
14 
15 #include <linux/dm9000.h>
16 #include <linux/rtc-v3020.h>
17 #include <linux/mtd/nand.h>
18 #include <linux/mtd/partitions.h>
19 #include <linux/input.h>
20 #include <linux/gpio_keys.h>
21 #include <linux/gpio.h>
22 
23 #include <asm/mach-types.h>
24 #include <asm/mach/arch.h>
25 
26 #include <mach/mfp-pxa27x.h>
27 #include <mach/pxa-regs.h>
28 #include <mach/pxa27x-udc.h>
29 #include <mach/audio.h>
30 #include <mach/pxafb.h>
31 #include <mach/ohci.h>
32 #include <mach/mmc.h>
33 #include <mach/pxa27x_keypad.h>
34 
35 #include "generic.h"
36 
37 /* GPIO IRQ usage */
38 #define GPIO41_ETHIRQ		(41)
39 #define GPIO13_MMC_CD		(13)
40 #define EM_X270_ETHIRQ		IRQ_GPIO(GPIO41_ETHIRQ)
41 #define EM_X270_MMC_CD		IRQ_GPIO(GPIO13_MMC_CD)
42 
43 /* NAND control GPIOs */
44 #define GPIO11_NAND_CS	(11)
45 #define GPIO56_NAND_RB	(56)
46 
47 static unsigned long em_x270_pin_config[] = {
48 	/* AC'97 */
49 	GPIO28_AC97_BITCLK,
50 	GPIO29_AC97_SDATA_IN_0,
51 	GPIO30_AC97_SDATA_OUT,
52 	GPIO31_AC97_SYNC,
53 	GPIO98_AC97_SYSCLK,
54 	GPIO113_AC97_nRESET,
55 
56 	/* BTUART */
57 	GPIO42_BTUART_RXD,
58 	GPIO43_BTUART_TXD,
59 	GPIO44_BTUART_CTS,
60 	GPIO45_BTUART_RTS,
61 
62 	/* STUART */
63 	GPIO46_STUART_RXD,
64 	GPIO47_STUART_TXD,
65 
66 	/* MCI controller */
67 	GPIO32_MMC_CLK,
68 	GPIO112_MMC_CMD,
69 	GPIO92_MMC_DAT_0,
70 	GPIO109_MMC_DAT_1,
71 	GPIO110_MMC_DAT_2,
72 	GPIO111_MMC_DAT_3,
73 
74 	/* LCD */
75 	GPIO58_LCD_LDD_0,
76 	GPIO59_LCD_LDD_1,
77 	GPIO60_LCD_LDD_2,
78 	GPIO61_LCD_LDD_3,
79 	GPIO62_LCD_LDD_4,
80 	GPIO63_LCD_LDD_5,
81 	GPIO64_LCD_LDD_6,
82 	GPIO65_LCD_LDD_7,
83 	GPIO66_LCD_LDD_8,
84 	GPIO67_LCD_LDD_9,
85 	GPIO68_LCD_LDD_10,
86 	GPIO69_LCD_LDD_11,
87 	GPIO70_LCD_LDD_12,
88 	GPIO71_LCD_LDD_13,
89 	GPIO72_LCD_LDD_14,
90 	GPIO73_LCD_LDD_15,
91 	GPIO74_LCD_FCLK,
92 	GPIO75_LCD_LCLK,
93 	GPIO76_LCD_PCLK,
94 	GPIO77_LCD_BIAS,
95 
96 	/* QCI */
97 	GPIO84_CIF_FV,
98 	GPIO25_CIF_LV,
99 	GPIO53_CIF_MCLK,
100 	GPIO54_CIF_PCLK,
101 	GPIO81_CIF_DD_0,
102 	GPIO55_CIF_DD_1,
103 	GPIO51_CIF_DD_2,
104 	GPIO50_CIF_DD_3,
105 	GPIO52_CIF_DD_4,
106 	GPIO48_CIF_DD_5,
107 	GPIO17_CIF_DD_6,
108 	GPIO12_CIF_DD_7,
109 
110 	/* I2C */
111 	GPIO117_I2C_SCL,
112 	GPIO118_I2C_SDA,
113 
114 	/* Keypad */
115 	GPIO100_KP_MKIN_0	| WAKEUP_ON_LEVEL_HIGH,
116 	GPIO101_KP_MKIN_1	| WAKEUP_ON_LEVEL_HIGH,
117 	GPIO102_KP_MKIN_2	| WAKEUP_ON_LEVEL_HIGH,
118 	GPIO34_KP_MKIN_3	| WAKEUP_ON_LEVEL_HIGH,
119 	GPIO39_KP_MKIN_4	| WAKEUP_ON_LEVEL_HIGH,
120 	GPIO99_KP_MKIN_5	| WAKEUP_ON_LEVEL_HIGH,
121 	GPIO91_KP_MKIN_6	| WAKEUP_ON_LEVEL_HIGH,
122 	GPIO36_KP_MKIN_7	| WAKEUP_ON_LEVEL_HIGH,
123 	GPIO103_KP_MKOUT_0,
124 	GPIO104_KP_MKOUT_1,
125 	GPIO105_KP_MKOUT_2,
126 	GPIO106_KP_MKOUT_3,
127 	GPIO107_KP_MKOUT_4,
128 	GPIO108_KP_MKOUT_5,
129 	GPIO96_KP_MKOUT_6,
130 	GPIO22_KP_MKOUT_7,
131 
132 	/* SSP1 */
133 	GPIO26_SSP1_RXD,
134 	GPIO23_SSP1_SCLK,
135 	GPIO24_SSP1_SFRM,
136 	GPIO57_SSP1_TXD,
137 
138 	/* SSP2 */
139 	GPIO19_SSP2_SCLK,
140 	GPIO14_SSP2_SFRM,
141 	GPIO89_SSP2_TXD,
142 	GPIO88_SSP2_RXD,
143 
144 	/* SDRAM and local bus */
145 	GPIO15_nCS_1,
146 	GPIO78_nCS_2,
147 	GPIO79_nCS_3,
148 	GPIO80_nCS_4,
149 	GPIO49_nPWE,
150 	GPIO18_RDY,
151 
152 	/* GPIO */
153 	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
154 
155 	/* power controls */
156 	GPIO20_GPIO	| MFP_LPM_DRIVE_LOW,	/* GPRS_PWEN */
157 	GPIO115_GPIO	| MFP_LPM_DRIVE_LOW,	/* WLAN_PWEN */
158 
159 	/* NAND controls */
160 	GPIO11_GPIO	| MFP_LPM_DRIVE_HIGH,	/* NAND CE# */
161 	GPIO56_GPIO,				/* NAND Ready/Busy */
162 
163 	/* interrupts */
164 	GPIO13_GPIO,	/* MMC card detect */
165 	GPIO41_GPIO,	/* DM9000 interrupt */
166 };
167 
168 #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
169 static struct resource em_x270_dm9000_resource[] = {
170 	[0] = {
171 		.start = PXA_CS2_PHYS,
172 		.end   = PXA_CS2_PHYS + 3,
173 		.flags = IORESOURCE_MEM,
174 	},
175 	[1] = {
176 		.start = PXA_CS2_PHYS + 8,
177 		.end   = PXA_CS2_PHYS + 8 + 0x3f,
178 		.flags = IORESOURCE_MEM,
179 	},
180 	[2] = {
181 		.start = EM_X270_ETHIRQ,
182 		.end   = EM_X270_ETHIRQ,
183 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
184 	}
185 };
186 
187 static struct dm9000_plat_data em_x270_dm9000_platdata = {
188 	.flags		= DM9000_PLATF_32BITONLY,
189 };
190 
191 static struct platform_device em_x270_dm9000 = {
192 	.name		= "dm9000",
193 	.id		= 0,
194 	.num_resources	= ARRAY_SIZE(em_x270_dm9000_resource),
195 	.resource	= em_x270_dm9000_resource,
196 	.dev		= {
197 		.platform_data = &em_x270_dm9000_platdata,
198 	}
199 };
200 
em_x270_init_dm9000(void)201 static void __init em_x270_init_dm9000(void)
202 {
203 	platform_device_register(&em_x270_dm9000);
204 }
205 #else
em_x270_init_dm9000(void)206 static inline void em_x270_init_dm9000(void) {}
207 #endif
208 
209 /* V3020 RTC */
210 #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
211 static struct resource em_x270_v3020_resource[] = {
212 	[0] = {
213 		.start = PXA_CS4_PHYS,
214 		.end   = PXA_CS4_PHYS + 3,
215 		.flags = IORESOURCE_MEM,
216 	},
217 };
218 
219 static struct v3020_platform_data em_x270_v3020_platdata = {
220 	.leftshift = 0,
221 };
222 
223 static struct platform_device em_x270_rtc = {
224 	.name		= "v3020",
225 	.num_resources	= ARRAY_SIZE(em_x270_v3020_resource),
226 	.resource	= em_x270_v3020_resource,
227 	.id		= -1,
228 	.dev		= {
229 		.platform_data = &em_x270_v3020_platdata,
230 	}
231 };
232 
em_x270_init_rtc(void)233 static void __init em_x270_init_rtc(void)
234 {
235 	platform_device_register(&em_x270_rtc);
236 }
237 #else
em_x270_init_rtc(void)238 static inline void em_x270_init_rtc(void) {}
239 #endif
240 
241 /* NAND flash */
242 #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
nand_cs_on(void)243 static inline void nand_cs_on(void)
244 {
245 	gpio_set_value(GPIO11_NAND_CS, 0);
246 }
247 
nand_cs_off(void)248 static void nand_cs_off(void)
249 {
250 	dsb();
251 
252 	gpio_set_value(GPIO11_NAND_CS, 1);
253 }
254 
255 /* hardware specific access to control-lines */
em_x270_nand_cmd_ctl(struct mtd_info * mtd,int dat,unsigned int ctrl)256 static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
257 				 unsigned int ctrl)
258 {
259 	struct nand_chip *this = mtd->priv;
260 	unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
261 
262 	dsb();
263 
264 	if (ctrl & NAND_CTRL_CHANGE) {
265 		if (ctrl & NAND_ALE)
266 			nandaddr |=  (1 << 3);
267 		else
268 			nandaddr &= ~(1 << 3);
269 		if (ctrl & NAND_CLE)
270 			nandaddr |=  (1 << 2);
271 		else
272 			nandaddr &= ~(1 << 2);
273 		if (ctrl & NAND_NCE)
274 			nand_cs_on();
275 		else
276 			nand_cs_off();
277 	}
278 
279 	dsb();
280 	this->IO_ADDR_W = (void __iomem *)nandaddr;
281 	if (dat != NAND_CMD_NONE)
282 		writel(dat, this->IO_ADDR_W);
283 
284 	dsb();
285 }
286 
287 /* read device ready pin */
em_x270_nand_device_ready(struct mtd_info * mtd)288 static int em_x270_nand_device_ready(struct mtd_info *mtd)
289 {
290 	dsb();
291 
292 	return gpio_get_value(GPIO56_NAND_RB);
293 }
294 
295 static struct mtd_partition em_x270_partition_info[] = {
296 	[0] = {
297 		.name	= "em_x270-0",
298 		.offset	= 0,
299 		.size	= SZ_4M,
300 	},
301 	[1] = {
302 		.name	= "em_x270-1",
303 		.offset	= MTDPART_OFS_APPEND,
304 		.size	= MTDPART_SIZ_FULL
305 	},
306 };
307 
308 static const char *em_x270_part_probes[] = { "cmdlinepart", NULL };
309 
310 struct platform_nand_data em_x270_nand_platdata = {
311 	.chip = {
312 		.nr_chips = 1,
313 		.chip_offset = 0,
314 		.nr_partitions = ARRAY_SIZE(em_x270_partition_info),
315 		.partitions = em_x270_partition_info,
316 		.chip_delay = 20,
317 		.part_probe_types = em_x270_part_probes,
318 	},
319 	.ctrl = {
320 		.hwcontrol = 0,
321 		.dev_ready = em_x270_nand_device_ready,
322 		.select_chip = 0,
323 		.cmd_ctrl = em_x270_nand_cmd_ctl,
324 	},
325 };
326 
327 static struct resource em_x270_nand_resource[] = {
328 	[0] = {
329 		.start = PXA_CS1_PHYS,
330 		.end   = PXA_CS1_PHYS + 12,
331 		.flags = IORESOURCE_MEM,
332 	},
333 };
334 
335 static struct platform_device em_x270_nand = {
336 	.name		= "gen_nand",
337 	.num_resources	= ARRAY_SIZE(em_x270_nand_resource),
338 	.resource	= em_x270_nand_resource,
339 	.id		= -1,
340 	.dev		= {
341 		.platform_data = &em_x270_nand_platdata,
342 	}
343 };
344 
em_x270_init_nand(void)345 static void __init em_x270_init_nand(void)
346 {
347 	int err;
348 
349 	err = gpio_request(GPIO11_NAND_CS, "NAND CS");
350 	if (err) {
351 		pr_warning("EM-X270: failed to request NAND CS gpio\n");
352 		return;
353 	}
354 
355 	gpio_direction_output(GPIO11_NAND_CS, 1);
356 
357 	err = gpio_request(GPIO56_NAND_RB, "NAND R/B");
358 	if (err) {
359 		pr_warning("EM-X270: failed to request NAND R/B gpio\n");
360 		gpio_free(GPIO11_NAND_CS);
361 		return;
362 	}
363 
364 	gpio_direction_input(GPIO56_NAND_RB);
365 
366 	platform_device_register(&em_x270_nand);
367 }
368 #else
em_x270_init_nand(void)369 static inline void em_x270_init_nand(void) {}
370 #endif
371 
372 /* PXA27x OHCI controller setup */
373 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
em_x270_ohci_init(struct device * dev)374 static int em_x270_ohci_init(struct device *dev)
375 {
376 	/* enable port 2 transiever */
377 	UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
378 
379 	return 0;
380 }
381 
382 static struct pxaohci_platform_data em_x270_ohci_platform_data = {
383 	.port_mode	= PMM_PERPORT_MODE,
384 	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
385 	.init		= em_x270_ohci_init,
386 };
387 
em_x270_init_ohci(void)388 static void __init em_x270_init_ohci(void)
389 {
390 	pxa_set_ohci_info(&em_x270_ohci_platform_data);
391 }
392 #else
em_x270_init_ohci(void)393 static inline void em_x270_init_ohci(void) {}
394 #endif
395 
396 /* MCI controller setup */
397 #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
em_x270_mci_init(struct device * dev,irq_handler_t em_x270_detect_int,void * data)398 static int em_x270_mci_init(struct device *dev,
399 			    irq_handler_t em_x270_detect_int,
400 			    void *data)
401 {
402 	int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int,
403 			      IRQF_DISABLED | IRQF_TRIGGER_FALLING,
404 			      "MMC card detect", data);
405 	if (err) {
406 		printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
407 		       __func__, err);
408 		return err;
409 	}
410 
411 	return 0;
412 }
413 
em_x270_mci_setpower(struct device * dev,unsigned int vdd)414 static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
415 {
416 	/*
417 	   FIXME: current hardware implementation does not allow to
418 	   enable/disable MMC power. This will be fixed in next HW releases,
419 	   and we'll need to add implmentation here.
420 	*/
421 	return;
422 }
423 
em_x270_mci_exit(struct device * dev,void * data)424 static void em_x270_mci_exit(struct device *dev, void *data)
425 {
426 	int irq = gpio_to_irq(GPIO13_MMC_CD);
427 	free_irq(irq, data);
428 }
429 
430 static struct pxamci_platform_data em_x270_mci_platform_data = {
431 	.ocr_mask	= MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31,
432 	.init 		= em_x270_mci_init,
433 	.setpower 	= em_x270_mci_setpower,
434 	.exit		= em_x270_mci_exit,
435 };
436 
em_x270_init_mmc(void)437 static void __init em_x270_init_mmc(void)
438 {
439 	pxa_set_mci_info(&em_x270_mci_platform_data);
440 }
441 #else
em_x270_init_mmc(void)442 static inline void em_x270_init_mmc(void) {}
443 #endif
444 
445 /* LCD 480x640 */
446 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
447 static struct pxafb_mode_info em_x270_lcd_mode = {
448 	.pixclock	= 50000,
449 	.bpp		= 16,
450 	.xres		= 480,
451 	.yres		= 640,
452 	.hsync_len	= 8,
453 	.vsync_len	= 2,
454 	.left_margin	= 8,
455 	.upper_margin	= 0,
456 	.right_margin	= 24,
457 	.lower_margin	= 4,
458 	.cmap_greyscale	= 0,
459 };
460 
461 static struct pxafb_mach_info em_x270_lcd = {
462 	.modes		= &em_x270_lcd_mode,
463 	.num_modes	= 1,
464 	.lcd_conn	= LCD_COLOR_TFT_16BPP,
465 };
em_x270_init_lcd(void)466 static void __init em_x270_init_lcd(void)
467 {
468 	set_pxa_fb_info(&em_x270_lcd);
469 }
470 #else
em_x270_init_lcd(void)471 static inline void em_x270_init_lcd(void) {}
472 #endif
473 
474 #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
em_x270_init_ac97(void)475 static void __init em_x270_init_ac97(void)
476 {
477 	pxa_set_ac97_info(NULL);
478 }
479 #else
em_x270_init_ac97(void)480 static inline void em_x270_init_ac97(void) {}
481 #endif
482 
483 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
484 static unsigned int em_x270_matrix_keys[] = {
485 	KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
486 	KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
487 	KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
488 };
489 
490 struct pxa27x_keypad_platform_data em_x270_keypad_info = {
491 	/* code map for the matrix keys */
492 	.matrix_key_rows	= 3,
493 	.matrix_key_cols	= 3,
494 	.matrix_key_map		= em_x270_matrix_keys,
495 	.matrix_key_map_size	= ARRAY_SIZE(em_x270_matrix_keys),
496 };
497 
em_x270_init_keypad(void)498 static void __init em_x270_init_keypad(void)
499 {
500 	pxa_set_keypad_info(&em_x270_keypad_info);
501 }
502 #else
em_x270_init_keypad(void)503 static inline void em_x270_init_keypad(void) {}
504 #endif
505 
506 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
507 static struct gpio_keys_button gpio_keys_button[] = {
508 	[0] = {
509 		.desc	= "sleep/wakeup",
510 		.code	= KEY_SUSPEND,
511 		.type	= EV_PWR,
512 		.gpio	= 1,
513 		.wakeup	= 1,
514 	},
515 };
516 
517 static struct gpio_keys_platform_data em_x270_gpio_keys_data = {
518 	.buttons	= gpio_keys_button,
519 	.nbuttons	= 1,
520 };
521 
522 static struct platform_device em_x270_gpio_keys = {
523 	.name		= "gpio-keys",
524 	.id		= -1,
525 	.dev		= {
526 		.platform_data	= &em_x270_gpio_keys_data,
527 	},
528 };
529 
em_x270_init_gpio_keys(void)530 static void __init em_x270_init_gpio_keys(void)
531 {
532 	platform_device_register(&em_x270_gpio_keys);
533 }
534 #else
em_x270_init_gpio_keys(void)535 static inline void em_x270_init_gpio_keys(void) {}
536 #endif
537 
em_x270_init(void)538 static void __init em_x270_init(void)
539 {
540 	pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
541 
542 	em_x270_init_dm9000();
543 	em_x270_init_rtc();
544 	em_x270_init_nand();
545 	em_x270_init_lcd();
546 	em_x270_init_mmc();
547 	em_x270_init_ohci();
548 	em_x270_init_keypad();
549 	em_x270_init_gpio_keys();
550 	em_x270_init_ac97();
551 }
552 
553 MACHINE_START(EM_X270, "Compulab EM-X270")
554 	.boot_params	= 0xa0000100,
555 	.phys_io	= 0x40000000,
556 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
557 	.map_io		= pxa_map_io,
558 	.init_irq	= pxa27x_init_irq,
559 	.timer		= &pxa_timer,
560 	.init_machine	= em_x270_init,
561 MACHINE_END
562