em-x270.c 7.7 KB

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