em-x270.c 12 KB

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