em-x270.c 7.7 KB

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