em-x270.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  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 <asm/arch/mfp-pxa27x.h>
  23. #include <asm/arch/pxa-regs.h>
  24. #include <asm/arch/pxa27x-udc.h>
  25. #include <asm/arch/audio.h>
  26. #include <asm/arch/pxafb.h>
  27. #include <asm/arch/ohci.h>
  28. #include <asm/arch/mmc.h>
  29. #include <asm/arch/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. /* Set the Power Control Polarity Low */
  325. UHCHR = (UHCHR | UHCHR_PCPL) &
  326. ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
  327. /* enable port 2 transiever */
  328. UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
  329. return 0;
  330. }
  331. static struct pxaohci_platform_data em_x270_ohci_platform_data = {
  332. .port_mode = PMM_PERPORT_MODE,
  333. .init = em_x270_ohci_init,
  334. };
  335. static void __init em_x270_init_ohci(void)
  336. {
  337. pxa_set_ohci_info(&em_x270_ohci_platform_data);
  338. }
  339. #else
  340. static inline void em_x270_init_ohci(void) {}
  341. #endif
  342. /* MCI controller setup */
  343. #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
  344. static int em_x270_mci_init(struct device *dev,
  345. irq_handler_t em_x270_detect_int,
  346. void *data)
  347. {
  348. int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int,
  349. IRQF_DISABLED | IRQF_TRIGGER_FALLING,
  350. "MMC card detect", data);
  351. if (err) {
  352. printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
  353. __func__, err);
  354. return err;
  355. }
  356. return 0;
  357. }
  358. static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
  359. {
  360. /*
  361. FIXME: current hardware implementation does not allow to
  362. enable/disable MMC power. This will be fixed in next HW releases,
  363. and we'll need to add implmentation here.
  364. */
  365. return;
  366. }
  367. static void em_x270_mci_exit(struct device *dev, void *data)
  368. {
  369. int irq = gpio_to_irq(GPIO13_MMC_CD);
  370. free_irq(irq, data);
  371. }
  372. static struct pxamci_platform_data em_x270_mci_platform_data = {
  373. .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31,
  374. .init = em_x270_mci_init,
  375. .setpower = em_x270_mci_setpower,
  376. .exit = em_x270_mci_exit,
  377. };
  378. static void __init em_x270_init_mmc(void)
  379. {
  380. pxa_set_mci_info(&em_x270_mci_platform_data);
  381. }
  382. #else
  383. static inline void em_x270_init_mmc(void) {}
  384. #endif
  385. /* LCD 480x640 */
  386. #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
  387. static struct pxafb_mode_info em_x270_lcd_mode = {
  388. .pixclock = 50000,
  389. .bpp = 16,
  390. .xres = 480,
  391. .yres = 640,
  392. .hsync_len = 8,
  393. .vsync_len = 2,
  394. .left_margin = 8,
  395. .upper_margin = 0,
  396. .right_margin = 24,
  397. .lower_margin = 4,
  398. .cmap_greyscale = 0,
  399. };
  400. static struct pxafb_mach_info em_x270_lcd = {
  401. .modes = &em_x270_lcd_mode,
  402. .num_modes = 1,
  403. .lcd_conn = LCD_COLOR_TFT_16BPP,
  404. };
  405. static void __init em_x270_init_lcd(void)
  406. {
  407. set_pxa_fb_info(&em_x270_lcd);
  408. }
  409. #else
  410. static inline void em_x270_init_lcd(void) {}
  411. #endif
  412. #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
  413. static void __init em_x270_init_ac97(void)
  414. {
  415. pxa_set_ac97_info(NULL);
  416. }
  417. #else
  418. static inline void em_x270_init_ac97(void) {}
  419. #endif
  420. #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
  421. static unsigned int em_x270_matrix_keys[] = {
  422. KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
  423. KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
  424. KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
  425. };
  426. struct pxa27x_keypad_platform_data em_x270_keypad_info = {
  427. /* code map for the matrix keys */
  428. .matrix_key_rows = 3,
  429. .matrix_key_cols = 3,
  430. .matrix_key_map = em_x270_matrix_keys,
  431. .matrix_key_map_size = ARRAY_SIZE(em_x270_matrix_keys),
  432. };
  433. static void __init em_x270_init_keypad(void)
  434. {
  435. pxa_set_keypad_info(&em_x270_keypad_info);
  436. }
  437. #else
  438. static inline void em_x270_init_keypad(void) {}
  439. #endif
  440. #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
  441. static struct gpio_keys_button gpio_keys_button[] = {
  442. [0] = {
  443. .desc = "sleep/wakeup",
  444. .code = KEY_SUSPEND,
  445. .type = EV_PWR,
  446. .gpio = 1,
  447. .wakeup = 1,
  448. },
  449. };
  450. static struct gpio_keys_platform_data em_x270_gpio_keys_data = {
  451. .buttons = gpio_keys_button,
  452. .nbuttons = 1,
  453. };
  454. static struct platform_device em_x270_gpio_keys = {
  455. .name = "gpio-keys",
  456. .id = -1,
  457. .dev = {
  458. .platform_data = &em_x270_gpio_keys_data,
  459. },
  460. };
  461. static void __init em_x270_init_gpio_keys(void)
  462. {
  463. platform_device_register(&em_x270_gpio_keys);
  464. }
  465. #else
  466. static inline void em_x270_init_gpio_keys(void) {}
  467. #endif
  468. static void __init em_x270_init(void)
  469. {
  470. pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
  471. em_x270_init_dm9000();
  472. em_x270_init_rtc();
  473. em_x270_init_nand();
  474. em_x270_init_lcd();
  475. em_x270_init_mmc();
  476. em_x270_init_ohci();
  477. em_x270_init_keypad();
  478. em_x270_init_gpio_keys();
  479. em_x270_init_ac97();
  480. }
  481. MACHINE_START(EM_X270, "Compulab EM-X270")
  482. .boot_params = 0xa0000100,
  483. .phys_io = 0x40000000,
  484. .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
  485. .map_io = pxa_map_io,
  486. .init_irq = pxa27x_init_irq,
  487. .timer = &pxa_timer,
  488. .init_machine = em_x270_init,
  489. MACHINE_END