em-x270.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * Support for CompuLab EM-x270 platform
  3. *
  4. * Copyright (C) 2007 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 <asm/mach-types.h>
  18. #include <asm/mach/arch.h>
  19. #include <asm/arch/pxa-regs.h>
  20. #include <asm/arch/pxa2xx-gpio.h>
  21. #include <asm/arch/pxa27x-udc.h>
  22. #include <asm/arch/pxafb.h>
  23. #include <asm/arch/ohci.h>
  24. #include <asm/arch/mmc.h>
  25. #include <asm/arch/bitfield.h>
  26. #include "generic.h"
  27. /* GPIO IRQ usage */
  28. #define EM_X270_MMC_PD (105)
  29. #define EM_X270_ETHIRQ IRQ_GPIO(41)
  30. #define EM_X270_MMC_IRQ IRQ_GPIO(13)
  31. static struct resource em_x270_dm9k_resource[] = {
  32. [0] = {
  33. .start = PXA_CS2_PHYS,
  34. .end = PXA_CS2_PHYS + 3,
  35. .flags = IORESOURCE_MEM,
  36. },
  37. [1] = {
  38. .start = PXA_CS2_PHYS + 8,
  39. .end = PXA_CS2_PHYS + 8 + 0x3f,
  40. .flags = IORESOURCE_MEM,
  41. },
  42. [2] = {
  43. .start = EM_X270_ETHIRQ,
  44. .end = EM_X270_ETHIRQ,
  45. .flags = IORESOURCE_IRQ,
  46. }
  47. };
  48. /* for the moment we limit ourselves to 32bit IO until some
  49. * better IO routines can be written and tested
  50. */
  51. static struct dm9000_plat_data em_x270_dm9k_platdata = {
  52. .flags = DM9000_PLATF_32BITONLY,
  53. };
  54. /* Ethernet device */
  55. static struct platform_device em_x270_dm9k = {
  56. .name = "dm9000",
  57. .id = 0,
  58. .num_resources = ARRAY_SIZE(em_x270_dm9k_resource),
  59. .resource = em_x270_dm9k_resource,
  60. .dev = {
  61. .platform_data = &em_x270_dm9k_platdata,
  62. }
  63. };
  64. /* audio device */
  65. static struct platform_device em_x270_audio = {
  66. .name = "pxa2xx-ac97",
  67. .id = -1,
  68. };
  69. /* WM9712 touchscreen controller. Hopefully the driver will make it to
  70. * the mainstream sometime */
  71. static struct platform_device em_x270_ts = {
  72. .name = "wm97xx-ts",
  73. .id = -1,
  74. };
  75. /* RTC */
  76. static struct resource em_x270_v3020_resource[] = {
  77. [0] = {
  78. .start = PXA_CS4_PHYS,
  79. .end = PXA_CS4_PHYS + 3,
  80. .flags = IORESOURCE_MEM,
  81. },
  82. };
  83. static struct v3020_platform_data em_x270_v3020_platdata = {
  84. .leftshift = 0,
  85. };
  86. static struct platform_device em_x270_rtc = {
  87. .name = "v3020",
  88. .num_resources = ARRAY_SIZE(em_x270_v3020_resource),
  89. .resource = em_x270_v3020_resource,
  90. .id = -1,
  91. .dev = {
  92. .platform_data = &em_x270_v3020_platdata,
  93. }
  94. };
  95. /* NAND flash */
  96. #define GPIO_NAND_CS (11)
  97. #define GPIO_NAND_RB (56)
  98. static inline void nand_cs_on(void)
  99. {
  100. GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
  101. }
  102. static void nand_cs_off(void)
  103. {
  104. dsb();
  105. GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
  106. }
  107. /* hardware specific access to control-lines */
  108. static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
  109. unsigned int ctrl)
  110. {
  111. struct nand_chip *this = mtd->priv;
  112. unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
  113. dsb();
  114. if (ctrl & NAND_CTRL_CHANGE) {
  115. if (ctrl & NAND_ALE)
  116. nandaddr |= (1 << 3);
  117. else
  118. nandaddr &= ~(1 << 3);
  119. if (ctrl & NAND_CLE)
  120. nandaddr |= (1 << 2);
  121. else
  122. nandaddr &= ~(1 << 2);
  123. if (ctrl & NAND_NCE)
  124. nand_cs_on();
  125. else
  126. nand_cs_off();
  127. }
  128. dsb();
  129. this->IO_ADDR_W = (void __iomem *)nandaddr;
  130. if (dat != NAND_CMD_NONE)
  131. writel(dat, this->IO_ADDR_W);
  132. dsb();
  133. }
  134. /* read device ready pin */
  135. static int em_x270_nand_device_ready(struct mtd_info *mtd)
  136. {
  137. dsb();
  138. return GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB);
  139. }
  140. static struct mtd_partition em_x270_partition_info[] = {
  141. [0] = {
  142. .name = "em_x270-0",
  143. .offset = 0,
  144. .size = SZ_4M,
  145. },
  146. [1] = {
  147. .name = "em_x270-1",
  148. .offset = MTDPART_OFS_APPEND,
  149. .size = MTDPART_SIZ_FULL
  150. },
  151. };
  152. static const char *em_x270_part_probes[] = { "cmdlinepart", NULL };
  153. struct platform_nand_data em_x270_nand_platdata = {
  154. .chip = {
  155. .nr_chips = 1,
  156. .chip_offset = 0,
  157. .nr_partitions = ARRAY_SIZE(em_x270_partition_info),
  158. .partitions = em_x270_partition_info,
  159. .chip_delay = 20,
  160. .part_probe_types = em_x270_part_probes,
  161. },
  162. .ctrl = {
  163. .hwcontrol = 0,
  164. .dev_ready = em_x270_nand_device_ready,
  165. .select_chip = 0,
  166. .cmd_ctrl = em_x270_nand_cmd_ctl,
  167. },
  168. };
  169. static struct resource em_x270_nand_resource[] = {
  170. [0] = {
  171. .start = PXA_CS1_PHYS,
  172. .end = PXA_CS1_PHYS + 12,
  173. .flags = IORESOURCE_MEM,
  174. },
  175. };
  176. static struct platform_device em_x270_nand = {
  177. .name = "gen_nand",
  178. .num_resources = ARRAY_SIZE(em_x270_nand_resource),
  179. .resource = em_x270_nand_resource,
  180. .id = -1,
  181. .dev = {
  182. .platform_data = &em_x270_nand_platdata,
  183. }
  184. };
  185. /* platform devices */
  186. static struct platform_device *platform_devices[] __initdata = {
  187. &em_x270_dm9k,
  188. &em_x270_audio,
  189. &em_x270_ts,
  190. &em_x270_rtc,
  191. &em_x270_nand,
  192. };
  193. /* PXA27x OHCI controller setup */
  194. static int em_x270_ohci_init(struct device *dev)
  195. {
  196. /* Set the Power Control Polarity Low */
  197. UHCHR = (UHCHR | UHCHR_PCPL) &
  198. ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
  199. /* enable port 2 transiever */
  200. UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
  201. return 0;
  202. }
  203. static struct pxaohci_platform_data em_x270_ohci_platform_data = {
  204. .port_mode = PMM_PERPORT_MODE,
  205. .init = em_x270_ohci_init,
  206. };
  207. static int em_x270_mci_init(struct device *dev,
  208. irq_handler_t em_x270_detect_int,
  209. void *data)
  210. {
  211. int err;
  212. /* setup GPIO for PXA27x MMC controller */
  213. pxa_gpio_mode(GPIO32_MMCCLK_MD);
  214. pxa_gpio_mode(GPIO112_MMCCMD_MD);
  215. pxa_gpio_mode(GPIO92_MMCDAT0_MD);
  216. pxa_gpio_mode(GPIO109_MMCDAT1_MD);
  217. pxa_gpio_mode(GPIO110_MMCDAT2_MD);
  218. pxa_gpio_mode(GPIO111_MMCDAT3_MD);
  219. /* EM-X270 uses GPIO13 as SD power enable */
  220. pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT);
  221. err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int,
  222. IRQF_DISABLED | IRQF_TRIGGER_FALLING,
  223. "MMC card detect", data);
  224. if (err) {
  225. printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
  226. __func__, err);
  227. return err;
  228. }
  229. return 0;
  230. }
  231. static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
  232. {
  233. /*
  234. FIXME: current hardware implementation does not allow to
  235. enable/disable MMC power. This will be fixed in next HW releases,
  236. and we'll need to add implmentation here.
  237. */
  238. return;
  239. }
  240. static void em_x270_mci_exit(struct device *dev, void *data)
  241. {
  242. free_irq(EM_X270_MMC_IRQ, data);
  243. }
  244. static struct pxamci_platform_data em_x270_mci_platform_data = {
  245. .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31,
  246. .init = em_x270_mci_init,
  247. .setpower = em_x270_mci_setpower,
  248. .exit = em_x270_mci_exit,
  249. };
  250. /* LCD 480x640 */
  251. static struct pxafb_mode_info em_x270_lcd_mode = {
  252. .pixclock = 50000,
  253. .bpp = 16,
  254. .xres = 480,
  255. .yres = 640,
  256. .hsync_len = 8,
  257. .vsync_len = 2,
  258. .left_margin = 8,
  259. .upper_margin = 0,
  260. .right_margin = 24,
  261. .lower_margin = 4,
  262. .cmap_greyscale = 0,
  263. };
  264. static struct pxafb_mach_info em_x270_lcd = {
  265. .modes = &em_x270_lcd_mode,
  266. .num_modes = 1,
  267. .cmap_inverse = 0,
  268. .cmap_static = 0,
  269. .lccr0 = LCCR0_PAS,
  270. .lccr3 = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff),
  271. };
  272. static void __init em_x270_init(void)
  273. {
  274. /* setup LCD */
  275. set_pxa_fb_info(&em_x270_lcd);
  276. /* register EM-X270 platform devices */
  277. platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
  278. /* set MCI and OHCI platform parameters */
  279. pxa_set_mci_info(&em_x270_mci_platform_data);
  280. pxa_set_ohci_info(&em_x270_ohci_platform_data);
  281. /* setup STUART GPIOs */
  282. pxa_gpio_mode(GPIO46_STRXD_MD);
  283. pxa_gpio_mode(GPIO47_STTXD_MD);
  284. /* setup BTUART GPIOs */
  285. pxa_gpio_mode(GPIO42_BTRXD_MD);
  286. pxa_gpio_mode(GPIO43_BTTXD_MD);
  287. pxa_gpio_mode(GPIO44_BTCTS_MD);
  288. pxa_gpio_mode(GPIO45_BTRTS_MD);
  289. /* Setup interrupt for dm9000 */
  290. set_irq_type(EM_X270_ETHIRQ, IRQT_RISING);
  291. }
  292. MACHINE_START(EM_X270, "Compulab EM-x270")
  293. .boot_params = 0xa0000100,
  294. .phys_io = 0x40000000,
  295. .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
  296. .map_io = pxa_map_io,
  297. .init_irq = pxa27x_init_irq,
  298. .timer = &pxa_timer,
  299. .init_machine = em_x270_init,
  300. MACHINE_END