PageRenderTime 62ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/arm/mach-s3c2440/mach-gta02.c

https://github.com/Unhelpful/linux-galaxy
C | 582 lines | 414 code | 87 blank | 81 comment | 9 complexity | ec87a413c81a7d7f77a2242f837de022 MD5 | raw file
  1. /*
  2. * linux/arch/arm/mach-s3c2442/mach-gta02.c
  3. *
  4. * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
  5. *
  6. * Copyright (C) 2006-2009 by Openmoko, Inc.
  7. * Authors: Harald Welte <laforge@openmoko.org>
  8. * Andy Green <andy@openmoko.org>
  9. * Werner Almesberger <werner@openmoko.org>
  10. * All rights reserved.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License as
  14. * published by the Free Software Foundation; either version 2 of
  15. * the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25. * MA 02111-1307 USA
  26. *
  27. */
  28. #include <linux/kernel.h>
  29. #include <linux/types.h>
  30. #include <linux/interrupt.h>
  31. #include <linux/list.h>
  32. #include <linux/delay.h>
  33. #include <linux/timer.h>
  34. #include <linux/init.h>
  35. #include <linux/gpio.h>
  36. #include <linux/workqueue.h>
  37. #include <linux/platform_device.h>
  38. #include <linux/serial_core.h>
  39. #include <linux/spi/spi.h>
  40. #include <linux/mmc/host.h>
  41. #include <linux/mtd/mtd.h>
  42. #include <linux/mtd/nand.h>
  43. #include <linux/mtd/nand_ecc.h>
  44. #include <linux/mtd/partitions.h>
  45. #include <linux/mtd/physmap.h>
  46. #include <linux/io.h>
  47. #include <linux/i2c.h>
  48. #include <linux/regulator/machine.h>
  49. #include <linux/mfd/pcf50633/core.h>
  50. #include <linux/mfd/pcf50633/mbc.h>
  51. #include <linux/mfd/pcf50633/adc.h>
  52. #include <linux/mfd/pcf50633/gpio.h>
  53. #include <linux/mfd/pcf50633/pmic.h>
  54. #include <linux/mfd/pcf50633/backlight.h>
  55. #include <asm/mach/arch.h>
  56. #include <asm/mach/map.h>
  57. #include <asm/mach/irq.h>
  58. #include <asm/irq.h>
  59. #include <asm/mach-types.h>
  60. #include <mach/regs-irq.h>
  61. #include <mach/regs-gpio.h>
  62. #include <mach/regs-gpioj.h>
  63. #include <mach/fb.h>
  64. #include <mach/spi.h>
  65. #include <mach/spi-gpio.h>
  66. #include <plat/usb-control.h>
  67. #include <mach/regs-mem.h>
  68. #include <mach/hardware.h>
  69. #include <mach/gta02.h>
  70. #include <plat/regs-serial.h>
  71. #include <plat/nand.h>
  72. #include <plat/devs.h>
  73. #include <plat/cpu.h>
  74. #include <plat/pm.h>
  75. #include <plat/udc.h>
  76. #include <plat/gpio-cfg.h>
  77. #include <plat/iic.h>
  78. static struct pcf50633 *gta02_pcf;
  79. /*
  80. * This gets called frequently when we paniced.
  81. */
  82. static long gta02_panic_blink(int state)
  83. {
  84. long delay = 0;
  85. char led;
  86. led = (state) ? 1 : 0;
  87. gpio_direction_output(GTA02_GPIO_AUX_LED, led);
  88. return delay;
  89. }
  90. static struct map_desc gta02_iodesc[] __initdata = {
  91. {
  92. .virtual = 0xe0000000,
  93. .pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
  94. .length = SZ_1M,
  95. .type = MT_DEVICE
  96. },
  97. };
  98. #define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
  99. #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
  100. #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
  101. static struct s3c2410_uartcfg gta02_uartcfgs[] = {
  102. [0] = {
  103. .hwport = 0,
  104. .flags = 0,
  105. .ucon = UCON,
  106. .ulcon = ULCON,
  107. .ufcon = UFCON,
  108. },
  109. [1] = {
  110. .hwport = 1,
  111. .flags = 0,
  112. .ucon = UCON,
  113. .ulcon = ULCON,
  114. .ufcon = UFCON,
  115. },
  116. [2] = {
  117. .hwport = 2,
  118. .flags = 0,
  119. .ucon = UCON,
  120. .ulcon = ULCON,
  121. .ufcon = UFCON,
  122. },
  123. };
  124. #ifdef CONFIG_CHARGER_PCF50633
  125. /*
  126. * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
  127. * We use this to recognize that we can pull 1A from the USB socket.
  128. *
  129. * These constants are the measured pcf50633 ADC levels with the 1A
  130. * charger / 48K resistor, and with no pulldown resistor.
  131. */
  132. #define ADC_NOM_CHG_DETECT_1A 6
  133. #define ADC_NOM_CHG_DETECT_USB 43
  134. static void
  135. gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
  136. {
  137. int ma;
  138. /* Interpret charger type */
  139. if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
  140. /*
  141. * Sanity - stop GPO driving out now that we have a 1A charger
  142. * GPO controls USB Host power generation on GTA02
  143. */
  144. pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
  145. ma = 1000;
  146. } else
  147. ma = 100;
  148. pcf50633_mbc_usb_curlim_set(pcf, ma);
  149. }
  150. static struct delayed_work gta02_charger_work;
  151. static int gta02_usb_vbus_draw;
  152. static void gta02_charger_worker(struct work_struct *work)
  153. {
  154. if (gta02_usb_vbus_draw) {
  155. pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
  156. return;
  157. }
  158. #ifdef CONFIG_PCF50633_ADC
  159. pcf50633_adc_async_read(gta02_pcf,
  160. PCF50633_ADCC1_MUX_ADCIN1,
  161. PCF50633_ADCC1_AVERAGE_16,
  162. gta02_configure_pmu_for_charger,
  163. NULL);
  164. #else
  165. /*
  166. * If the PCF50633 ADC is disabled we fallback to a
  167. * 100mA limit for safety.
  168. */
  169. pcf50633_mbc_usb_curlim_set(pcf, 100);
  170. #endif
  171. }
  172. #define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
  173. static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
  174. {
  175. if (irq == PCF50633_IRQ_USBINS) {
  176. schedule_delayed_work(&gta02_charger_work,
  177. GTA02_CHARGER_CONFIGURE_TIMEOUT);
  178. return;
  179. }
  180. if (irq == PCF50633_IRQ_USBREM) {
  181. cancel_delayed_work_sync(&gta02_charger_work);
  182. gta02_usb_vbus_draw = 0;
  183. }
  184. }
  185. static void gta02_udc_vbus_draw(unsigned int ma)
  186. {
  187. if (!gta02_pcf)
  188. return;
  189. gta02_usb_vbus_draw = ma;
  190. schedule_delayed_work(&gta02_charger_work,
  191. GTA02_CHARGER_CONFIGURE_TIMEOUT);
  192. }
  193. #else /* !CONFIG_CHARGER_PCF50633 */
  194. #define gta02_pmu_event_callback NULL
  195. #define gta02_udc_vbus_draw NULL
  196. #endif
  197. /*
  198. * This is called when pc50633 is probed, unfortunately quite late in the
  199. * day since it is an I2C bus device. Here we can belatedly define some
  200. * platform devices with the advantage that we can mark the pcf50633 as the
  201. * parent. This makes them get suspended and resumed with their parent
  202. * the pcf50633 still around.
  203. */
  204. static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
  205. static char *gta02_batteries[] = {
  206. "battery",
  207. };
  208. static struct pcf50633_bl_platform_data gta02_backlight_data = {
  209. .default_brightness = 0x3f,
  210. .default_brightness_limit = 0,
  211. .ramp_time = 5,
  212. };
  213. struct pcf50633_platform_data gta02_pcf_pdata = {
  214. .resumers = {
  215. [0] = PCF50633_INT1_USBINS |
  216. PCF50633_INT1_USBREM |
  217. PCF50633_INT1_ALARM,
  218. [1] = PCF50633_INT2_ONKEYF,
  219. [2] = PCF50633_INT3_ONKEY1S,
  220. [3] = PCF50633_INT4_LOWSYS |
  221. PCF50633_INT4_LOWBAT |
  222. PCF50633_INT4_HIGHTMP,
  223. },
  224. .batteries = gta02_batteries,
  225. .num_batteries = ARRAY_SIZE(gta02_batteries),
  226. .charger_reference_current_ma = 1000,
  227. .backlight_data = &gta02_backlight_data,
  228. .reg_init_data = {
  229. [PCF50633_REGULATOR_AUTO] = {
  230. .constraints = {
  231. .min_uV = 3300000,
  232. .max_uV = 3300000,
  233. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  234. .always_on = 1,
  235. .apply_uV = 1,
  236. .state_mem = {
  237. .enabled = 1,
  238. },
  239. },
  240. },
  241. [PCF50633_REGULATOR_DOWN1] = {
  242. .constraints = {
  243. .min_uV = 1300000,
  244. .max_uV = 1600000,
  245. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  246. .always_on = 1,
  247. .apply_uV = 1,
  248. },
  249. },
  250. [PCF50633_REGULATOR_DOWN2] = {
  251. .constraints = {
  252. .min_uV = 1800000,
  253. .max_uV = 1800000,
  254. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  255. .apply_uV = 1,
  256. .always_on = 1,
  257. .state_mem = {
  258. .enabled = 1,
  259. },
  260. },
  261. },
  262. [PCF50633_REGULATOR_HCLDO] = {
  263. .constraints = {
  264. .min_uV = 2000000,
  265. .max_uV = 3300000,
  266. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  267. .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
  268. .always_on = 1,
  269. },
  270. },
  271. [PCF50633_REGULATOR_LDO1] = {
  272. .constraints = {
  273. .min_uV = 3300000,
  274. .max_uV = 3300000,
  275. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  276. .apply_uV = 1,
  277. .state_mem = {
  278. .enabled = 0,
  279. },
  280. },
  281. },
  282. [PCF50633_REGULATOR_LDO2] = {
  283. .constraints = {
  284. .min_uV = 3300000,
  285. .max_uV = 3300000,
  286. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  287. .apply_uV = 1,
  288. },
  289. },
  290. [PCF50633_REGULATOR_LDO3] = {
  291. .constraints = {
  292. .min_uV = 3000000,
  293. .max_uV = 3000000,
  294. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  295. .apply_uV = 1,
  296. },
  297. },
  298. [PCF50633_REGULATOR_LDO4] = {
  299. .constraints = {
  300. .min_uV = 3200000,
  301. .max_uV = 3200000,
  302. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  303. .apply_uV = 1,
  304. },
  305. },
  306. [PCF50633_REGULATOR_LDO5] = {
  307. .constraints = {
  308. .min_uV = 3000000,
  309. .max_uV = 3000000,
  310. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  311. .apply_uV = 1,
  312. .state_mem = {
  313. .enabled = 1,
  314. },
  315. },
  316. },
  317. [PCF50633_REGULATOR_LDO6] = {
  318. .constraints = {
  319. .min_uV = 3000000,
  320. .max_uV = 3000000,
  321. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  322. },
  323. },
  324. [PCF50633_REGULATOR_MEMLDO] = {
  325. .constraints = {
  326. .min_uV = 1800000,
  327. .max_uV = 1800000,
  328. .valid_modes_mask = REGULATOR_MODE_NORMAL,
  329. .state_mem = {
  330. .enabled = 1,
  331. },
  332. },
  333. },
  334. },
  335. .probe_done = gta02_pmu_attach_child_devices,
  336. .mbc_event_callback = gta02_pmu_event_callback,
  337. };
  338. /* NOR Flash. */
  339. #define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
  340. #define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */
  341. static struct physmap_flash_data gta02_nor_flash_data = {
  342. .width = 2,
  343. };
  344. static struct resource gta02_nor_flash_resource = {
  345. .start = GTA02_FLASH_BASE,
  346. .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
  347. .flags = IORESOURCE_MEM,
  348. };
  349. static struct platform_device gta02_nor_flash = {
  350. .name = "physmap-flash",
  351. .id = 0,
  352. .dev = {
  353. .platform_data = &gta02_nor_flash_data,
  354. },
  355. .resource = &gta02_nor_flash_resource,
  356. .num_resources = 1,
  357. };
  358. struct platform_device s3c24xx_pwm_device = {
  359. .name = "s3c24xx_pwm",
  360. .num_resources = 0,
  361. };
  362. static struct i2c_board_info gta02_i2c_devs[] __initdata = {
  363. {
  364. I2C_BOARD_INFO("pcf50633", 0x73),
  365. .irq = GTA02_IRQ_PCF50633,
  366. .platform_data = &gta02_pcf_pdata,
  367. },
  368. {
  369. I2C_BOARD_INFO("wm8753", 0x1a),
  370. },
  371. };
  372. static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
  373. [0] = {
  374. /*
  375. * This name is also hard-coded in the boot loaders, so
  376. * changing it would would require all users to upgrade
  377. * their boot loaders, some of which are stored in a NOR
  378. * that is considered to be immutable.
  379. */
  380. .name = "neo1973-nand",
  381. .nr_chips = 1,
  382. .flash_bbt = 1,
  383. },
  384. };
  385. /*
  386. * Choose a set of timings derived from S3C@2442B MCP54
  387. * data sheet (K5D2G13ACM-D075 MCP Memory).
  388. */
  389. static struct s3c2410_platform_nand __initdata gta02_nand_info = {
  390. .tacls = 0,
  391. .twrph0 = 25,
  392. .twrph1 = 15,
  393. .nr_sets = ARRAY_SIZE(gta02_nand_sets),
  394. .sets = gta02_nand_sets,
  395. };
  396. static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
  397. {
  398. switch (cmd) {
  399. case S3C2410_UDC_P_ENABLE:
  400. pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
  401. gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
  402. break;
  403. case S3C2410_UDC_P_DISABLE:
  404. pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
  405. gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
  406. break;
  407. case S3C2410_UDC_P_RESET:
  408. pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
  409. /* FIXME: Do something here. */
  410. }
  411. }
  412. /* Get PMU to set USB current limit accordingly. */
  413. static struct s3c2410_udc_mach_info gta02_udc_cfg = {
  414. .vbus_draw = gta02_udc_vbus_draw,
  415. .udc_command = gta02_udc_command,
  416. };
  417. /* USB */
  418. static struct s3c2410_hcd_info gta02_usb_info __initdata = {
  419. .port[0] = {
  420. .flags = S3C_HCDFLG_USED,
  421. },
  422. .port[1] = {
  423. .flags = 0,
  424. },
  425. };
  426. static void __init gta02_map_io(void)
  427. {
  428. s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
  429. s3c24xx_init_clocks(12000000);
  430. s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
  431. }
  432. /* These are the guys that don't need to be children of PMU. */
  433. static struct platform_device *gta02_devices[] __initdata = {
  434. &s3c_device_ohci,
  435. &s3c_device_wdt,
  436. &s3c_device_sdi,
  437. &s3c_device_usbgadget,
  438. &s3c_device_nand,
  439. &gta02_nor_flash,
  440. &s3c24xx_pwm_device,
  441. &s3c_device_iis,
  442. &s3c_device_i2c0,
  443. };
  444. /* These guys DO need to be children of PMU. */
  445. static struct platform_device *gta02_devices_pmu_children[] = {
  446. };
  447. /*
  448. * This is called when pc50633 is probed, quite late in the day since it is an
  449. * I2C bus device. Here we can define platform devices with the advantage that
  450. * we can mark the pcf50633 as the parent. This makes them get suspended and
  451. * resumed with their parent the pcf50633 still around. All devices whose
  452. * operation depends on something from pcf50633 must have this relationship
  453. * made explicit like this, or suspend and resume will become an unreliable
  454. * hellworld.
  455. */
  456. static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
  457. {
  458. int n;
  459. /* Grab a copy of the now probed PMU pointer. */
  460. gta02_pcf = pcf;
  461. for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
  462. gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
  463. platform_add_devices(gta02_devices_pmu_children,
  464. ARRAY_SIZE(gta02_devices_pmu_children));
  465. }
  466. static void gta02_poweroff(void)
  467. {
  468. pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
  469. }
  470. static void __init gta02_machine_init(void)
  471. {
  472. /* Set the panic callback to turn AUX LED on or off. */
  473. panic_blink = gta02_panic_blink;
  474. s3c_pm_init();
  475. #ifdef CONFIG_CHARGER_PCF50633
  476. INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
  477. #endif
  478. s3c24xx_udc_set_platdata(&gta02_udc_cfg);
  479. s3c_ohci_set_platdata(&gta02_usb_info);
  480. s3c_nand_set_platdata(&gta02_nand_info);
  481. s3c_i2c0_set_platdata(NULL);
  482. i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
  483. platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
  484. pm_power_off = gta02_poweroff;
  485. }
  486. MACHINE_START(NEO1973_GTA02, "GTA02")
  487. /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
  488. .phys_io = S3C2410_PA_UART,
  489. .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
  490. .boot_params = S3C2410_SDRAM_PA + 0x100,
  491. .map_io = gta02_map_io,
  492. .init_irq = s3c24xx_init_irq,
  493. .init_machine = gta02_machine_init,
  494. .timer = &s3c24xx_timer,
  495. MACHINE_END