aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2440
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-s3c2440')
-rw-r--r--arch/arm/mach-s3c2440/Kconfig20
-rw-r--r--arch/arm/mach-s3c2440/Makefile1
-rw-r--r--arch/arm/mach-s3c2440/include/mach/gta02.h84
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c647
4 files changed, 750 insertions, 2 deletions
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 80879358eb2f..5486929dc3d0 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -21,8 +21,7 @@ config S3C2440_DMA
21 help 21 help
22 Support for S3C2440 specific DMA code5A 22 Support for S3C2440 specific DMA code5A
23 23
24 24menu "S3C2440 and S3C2442 Machines"
25menu "S3C2440 Machines"
26 25
27config MACH_ANUBIS 26config MACH_ANUBIS
28 bool "Simtec Electronics ANUBIS" 27 bool "Simtec Electronics ANUBIS"
@@ -37,6 +36,18 @@ config MACH_ANUBIS
37 Say Y here if you are using the Simtec Electronics ANUBIS 36 Say Y here if you are using the Simtec Electronics ANUBIS
38 development system 37 development system
39 38
39config MACH_NEO1973_GTA02
40 bool "Openmoko GTA02 / Freerunner phone"
41 select CPU_S3C2442
42 select MFD_PCF50633
43 select PCF50633_GPIO
44 select I2C
45 select POWER_SUPPLY
46 select MACH_NEO1973
47 select S3C2410_PWM
48 help
49 Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
50
40config MACH_OSIRIS 51config MACH_OSIRIS
41 bool "Simtec IM2440D20 (OSIRIS) module" 52 bool "Simtec IM2440D20 (OSIRIS) module"
42 select CPU_S3C2440 53 select CPU_S3C2440
@@ -99,6 +110,11 @@ config SMDK2440_CPU2440
99 select S3C2440_XTAL_16934400 110 select S3C2440_XTAL_16934400
100 select CPU_S3C2440 111 select CPU_S3C2440
101 112
113config SMDK2440_CPU2442
114 bool "SMDM2440 with S3C2442 CPU module"
115 depends on ARCH_S3C2440
116 select CPU_S3C2442
117
102config MACH_AT2440EVB 118config MACH_AT2440EVB
103 bool "Avantech AT2440EVB development board" 119 bool "Avantech AT2440EVB development board"
104 select CPU_S3C2440 120 select CPU_S3C2440
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
index 5f3224531885..e51497ca12ea 100644
--- a/arch/arm/mach-s3c2440/Makefile
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
23obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o 23obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
24obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o 24obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
25obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o 25obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
26obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
26 27
27# extra machine support 28# extra machine support
28 29
diff --git a/arch/arm/mach-s3c2440/include/mach/gta02.h b/arch/arm/mach-s3c2440/include/mach/gta02.h
new file mode 100644
index 000000000000..953331d8d56a
--- /dev/null
+++ b/arch/arm/mach-s3c2440/include/mach/gta02.h
@@ -0,0 +1,84 @@
1#ifndef _GTA02_H
2#define _GTA02_H
3
4#include <mach/regs-gpio.h>
5
6/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
7#define GTA02v1_SYSTEM_REV 0x00000310
8#define GTA02v2_SYSTEM_REV 0x00000320
9#define GTA02v3_SYSTEM_REV 0x00000330
10#define GTA02v4_SYSTEM_REV 0x00000340
11#define GTA02v5_SYSTEM_REV 0x00000350
12/* since A7 is basically same as A6, we use A6 PCB ID */
13#define GTA02v6_SYSTEM_REV 0x00000360
14
15#define GTA02_GPIO_n3DL_GSM S3C2410_GPA(13) /* v1 + v2 + v3 only */
16
17#define GTA02_GPIO_PWR_LED1 S3C2410_GPB(0)
18#define GTA02_GPIO_PWR_LED2 S3C2410_GPB(1)
19#define GTA02_GPIO_AUX_LED S3C2410_GPB(2)
20#define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB(3)
21#define GTA02_GPIO_MODEM_RST S3C2410_GPB(5)
22#define GTA02_GPIO_BT_EN S3C2410_GPB(6)
23#define GTA02_GPIO_MODEM_ON S3C2410_GPB(7)
24#define GTA02_GPIO_EXTINT8 S3C2410_GPB(8)
25#define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9)
26
27#define GTA02_GPIO_PIO5 S3C2410_GPC(5) /* v3 + v4 only */
28
29#define GTA02v3_GPIO_nG1_CS S3C2410_GPD(12) /* v3 + v4 only */
30#define GTA02v3_GPIO_nG2_CS S3C2410_GPD(13) /* v3 + v4 only */
31#define GTA02v5_GPIO_HDQ S3C2410_GPD(14) /* v5 + */
32
33#define GTA02_GPIO_nG1_INT S3C2410_GPF(0)
34#define GTA02_GPIO_IO1 S3C2410_GPF(1)
35#define GTA02_GPIO_PIO_2 S3C2410_GPF(2) /* v2 + v3 + v4 only */
36#define GTA02_GPIO_JACK_INSERT S3C2410_GPF(4)
37#define GTA02_GPIO_WLAN_GPIO1 S3C2410_GPF(5) /* v2 + v3 + v4 only */
38#define GTA02_GPIO_AUX_KEY S3C2410_GPF(6)
39#define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7)
40
41#define GTA02_GPIO_3D_IRQ S3C2410_GPG(4)
42#define GTA02v2_GPIO_nG2_INT S3C2410_GPG(8) /* v2 + v3 + v4 only */
43#define GTA02v3_GPIO_nUSB_OC S3C2410_GPG(9) /* v3 + v4 only */
44#define GTA02v3_GPIO_nUSB_FLT S3C2410_GPG(10) /* v3 + v4 only */
45#define GTA02v3_GPIO_nGSM_OC S3C2410_GPG(11) /* v3 + v4 only */
46
47#define GTA02_GPIO_AMP_SHUT S3C2440_GPJ1 /* v2 + v3 + v4 only */
48#define GTA02v1_GPIO_WLAN_GPIO10 S3C2440_GPJ2
49#define GTA02_GPIO_HP_IN S3C2440_GPJ2 /* v2 + v3 + v4 only */
50#define GTA02_GPIO_INT0 S3C2440_GPJ3 /* v2 + v3 + v4 only */
51#define GTA02_GPIO_nGSM_EN S3C2440_GPJ4
52#define GTA02_GPIO_3D_RESET S3C2440_GPJ5
53#define GTA02_GPIO_nDL_GSM S3C2440_GPJ6 /* v4 + v5 only */
54#define GTA02_GPIO_WLAN_GPIO0 S3C2440_GPJ7
55#define GTA02v1_GPIO_BAT_ID S3C2440_GPJ8
56#define GTA02_GPIO_KEEPACT S3C2440_GPJ8
57#define GTA02v1_GPIO_HP_IN S3C2440_GPJ10
58#define GTA02_CHIP_PWD S3C2440_GPJ11 /* v2 + v3 + v4 only */
59#define GTA02_GPIO_nWLAN_RESET S3C2440_GPJ12 /* v2 + v3 + v4 only */
60
61#define GTA02_IRQ_GSENSOR_1 IRQ_EINT0
62#define GTA02_IRQ_MODEM IRQ_EINT1
63#define GTA02_IRQ_PIO_2 IRQ_EINT2 /* v2 + v3 + v4 only */
64#define GTA02_IRQ_nJACK_INSERT IRQ_EINT4
65#define GTA02_IRQ_WLAN_GPIO1 IRQ_EINT5
66#define GTA02_IRQ_AUX IRQ_EINT6
67#define GTA02_IRQ_nHOLD IRQ_EINT7
68#define GTA02_IRQ_PCF50633 IRQ_EINT9
69#define GTA02_IRQ_3D IRQ_EINT12
70#define GTA02_IRQ_GSENSOR_2 IRQ_EINT16 /* v2 + v3 + v4 only */
71#define GTA02v3_IRQ_nUSB_OC IRQ_EINT17 /* v3 + v4 only */
72#define GTA02v3_IRQ_nUSB_FLT IRQ_EINT18 /* v3 + v4 only */
73#define GTA02v3_IRQ_nGSM_OC IRQ_EINT19 /* v3 + v4 only */
74
75/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */
76#define GTA02_PCB_ID1_0 S3C2410_GPC(13)
77#define GTA02_PCB_ID1_1 S3C2410_GPC(15)
78#define GTA02_PCB_ID1_2 S3C2410_GPD(0)
79#define GTA02_PCB_ID2_0 S3C2410_GPD(3)
80#define GTA02_PCB_ID2_1 S3C2410_GPD(4)
81
82int gta02_get_pcb_revision(void);
83
84#endif /* _GTA02_H */
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
new file mode 100644
index 000000000000..45799c608d8f
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -0,0 +1,647 @@
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
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/interrupt.h>
32#include <linux/list.h>
33#include <linux/delay.h>
34#include <linux/timer.h>
35#include <linux/init.h>
36#include <linux/gpio.h>
37#include <linux/workqueue.h>
38#include <linux/platform_device.h>
39#include <linux/serial_core.h>
40#include <linux/spi/spi.h>
41
42#include <linux/mmc/host.h>
43
44#include <linux/mtd/mtd.h>
45#include <linux/mtd/nand.h>
46#include <linux/mtd/nand_ecc.h>
47#include <linux/mtd/partitions.h>
48#include <linux/mtd/physmap.h>
49#include <linux/io.h>
50
51#include <linux/i2c.h>
52#include <linux/backlight.h>
53#include <linux/regulator/machine.h>
54
55#include <linux/mfd/pcf50633/core.h>
56#include <linux/mfd/pcf50633/mbc.h>
57#include <linux/mfd/pcf50633/adc.h>
58#include <linux/mfd/pcf50633/gpio.h>
59#include <linux/mfd/pcf50633/pmic.h>
60
61#include <asm/mach/arch.h>
62#include <asm/mach/map.h>
63#include <asm/mach/irq.h>
64
65#include <asm/irq.h>
66#include <asm/mach-types.h>
67
68#include <mach/regs-irq.h>
69#include <mach/regs-gpio.h>
70#include <mach/regs-gpioj.h>
71#include <mach/fb.h>
72
73#include <mach/spi.h>
74#include <mach/spi-gpio.h>
75#include <plat/usb-control.h>
76#include <mach/regs-mem.h>
77#include <mach/hardware.h>
78
79#include <mach/gta02.h>
80
81#include <plat/regs-serial.h>
82#include <plat/nand.h>
83#include <plat/devs.h>
84#include <plat/cpu.h>
85#include <plat/pm.h>
86#include <plat/udc.h>
87#include <plat/gpio-cfg.h>
88#include <plat/iic.h>
89
90static struct pcf50633 *gta02_pcf;
91
92/*
93 * This gets called every 1ms when we paniced.
94 */
95
96static long gta02_panic_blink(long count)
97{
98 long delay = 0;
99 static long last_blink;
100 static char led;
101
102 /* Fast blink: 200ms period. */
103 if (count - last_blink < 100)
104 return 0;
105
106 led ^= 1;
107 gpio_direction_output(GTA02_GPIO_AUX_LED, led);
108
109 last_blink = count;
110
111 return delay;
112}
113
114
115static struct map_desc gta02_iodesc[] __initdata = {
116 {
117 .virtual = 0xe0000000,
118 .pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
119 .length = SZ_1M,
120 .type = MT_DEVICE
121 },
122};
123
124#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
125#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
126#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
127
128static struct s3c2410_uartcfg gta02_uartcfgs[] = {
129 [0] = {
130 .hwport = 0,
131 .flags = 0,
132 .ucon = UCON,
133 .ulcon = ULCON,
134 .ufcon = UFCON,
135 },
136 [1] = {
137 .hwport = 1,
138 .flags = 0,
139 .ucon = UCON,
140 .ulcon = ULCON,
141 .ufcon = UFCON,
142 },
143 [2] = {
144 .hwport = 2,
145 .flags = 0,
146 .ucon = UCON,
147 .ulcon = ULCON,
148 .ufcon = UFCON,
149 },
150};
151
152#ifdef CONFIG_CHARGER_PCF50633
153/*
154 * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
155 * We use this to recognize that we can pull 1A from the USB socket.
156 *
157 * These constants are the measured pcf50633 ADC levels with the 1A
158 * charger / 48K resistor, and with no pulldown resistor.
159 */
160
161#define ADC_NOM_CHG_DETECT_1A 6
162#define ADC_NOM_CHG_DETECT_USB 43
163
164static void
165gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
166{
167 int ma;
168
169 /* Interpret charger type */
170 if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
171
172 /*
173 * Sanity - stop GPO driving out now that we have a 1A charger
174 * GPO controls USB Host power generation on GTA02
175 */
176 pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
177
178 ma = 1000;
179 } else
180 ma = 100;
181
182 pcf50633_mbc_usb_curlim_set(pcf, ma);
183}
184
185static struct delayed_work gta02_charger_work;
186static int gta02_usb_vbus_draw;
187
188static void gta02_charger_worker(struct work_struct *work)
189{
190 if (gta02_usb_vbus_draw) {
191 pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
192 return;
193 }
194
195#ifdef CONFIG_PCF50633_ADC
196 pcf50633_adc_async_read(gta02_pcf,
197 PCF50633_ADCC1_MUX_ADCIN1,
198 PCF50633_ADCC1_AVERAGE_16,
199 gta02_configure_pmu_for_charger,
200 NULL);
201#else
202 /*
203 * If the PCF50633 ADC is disabled we fallback to a
204 * 100mA limit for safety.
205 */
206 pcf50633_mbc_usb_curlim_set(pcf, 100);
207#endif
208}
209
210#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
211
212static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
213{
214 if (irq == PCF50633_IRQ_USBINS) {
215 schedule_delayed_work(&gta02_charger_work,
216 GTA02_CHARGER_CONFIGURE_TIMEOUT);
217
218 return;
219 }
220
221 if (irq == PCF50633_IRQ_USBREM) {
222 cancel_delayed_work_sync(&gta02_charger_work);
223 gta02_usb_vbus_draw = 0;
224 }
225}
226
227static void gta02_udc_vbus_draw(unsigned int ma)
228{
229 if (!gta02_pcf)
230 return;
231
232 gta02_usb_vbus_draw = ma;
233
234 schedule_delayed_work(&gta02_charger_work,
235 GTA02_CHARGER_CONFIGURE_TIMEOUT);
236}
237#else /* !CONFIG_CHARGER_PCF50633 */
238#define gta02_pmu_event_callback NULL
239#define gta02_udc_vbus_draw NULL
240#endif
241
242/*
243 * This is called when pc50633 is probed, unfortunately quite late in the
244 * day since it is an I2C bus device. Here we can belatedly define some
245 * platform devices with the advantage that we can mark the pcf50633 as the
246 * parent. This makes them get suspended and resumed with their parent
247 * the pcf50633 still around.
248 */
249
250static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
251
252
253static char *gta02_batteries[] = {
254 "battery",
255};
256
257struct pcf50633_platform_data gta02_pcf_pdata = {
258 .resumers = {
259 [0] = PCF50633_INT1_USBINS |
260 PCF50633_INT1_USBREM |
261 PCF50633_INT1_ALARM,
262 [1] = PCF50633_INT2_ONKEYF,
263 [2] = PCF50633_INT3_ONKEY1S,
264 [3] = PCF50633_INT4_LOWSYS |
265 PCF50633_INT4_LOWBAT |
266 PCF50633_INT4_HIGHTMP,
267 },
268
269 .batteries = gta02_batteries,
270 .num_batteries = ARRAY_SIZE(gta02_batteries),
271
272 .charger_reference_current_ma = 1000,
273
274 .reg_init_data = {
275 [PCF50633_REGULATOR_AUTO] = {
276 .constraints = {
277 .min_uV = 3300000,
278 .max_uV = 3300000,
279 .valid_modes_mask = REGULATOR_MODE_NORMAL,
280 .always_on = 1,
281 .apply_uV = 1,
282 .state_mem = {
283 .enabled = 1,
284 },
285 },
286 },
287 [PCF50633_REGULATOR_DOWN1] = {
288 .constraints = {
289 .min_uV = 1300000,
290 .max_uV = 1600000,
291 .valid_modes_mask = REGULATOR_MODE_NORMAL,
292 .always_on = 1,
293 .apply_uV = 1,
294 },
295 },
296 [PCF50633_REGULATOR_DOWN2] = {
297 .constraints = {
298 .min_uV = 1800000,
299 .max_uV = 1800000,
300 .valid_modes_mask = REGULATOR_MODE_NORMAL,
301 .apply_uV = 1,
302 .always_on = 1,
303 .state_mem = {
304 .enabled = 1,
305 },
306 },
307 },
308 [PCF50633_REGULATOR_HCLDO] = {
309 .constraints = {
310 .min_uV = 2000000,
311 .max_uV = 3300000,
312 .valid_modes_mask = REGULATOR_MODE_NORMAL,
313 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
314 .always_on = 1,
315 },
316 },
317 [PCF50633_REGULATOR_LDO1] = {
318 .constraints = {
319 .min_uV = 3300000,
320 .max_uV = 3300000,
321 .valid_modes_mask = REGULATOR_MODE_NORMAL,
322 .apply_uV = 1,
323 .state_mem = {
324 .enabled = 0,
325 },
326 },
327 },
328 [PCF50633_REGULATOR_LDO2] = {
329 .constraints = {
330 .min_uV = 3300000,
331 .max_uV = 3300000,
332 .valid_modes_mask = REGULATOR_MODE_NORMAL,
333 .apply_uV = 1,
334 },
335 },
336 [PCF50633_REGULATOR_LDO3] = {
337 .constraints = {
338 .min_uV = 3000000,
339 .max_uV = 3000000,
340 .valid_modes_mask = REGULATOR_MODE_NORMAL,
341 .apply_uV = 1,
342 },
343 },
344 [PCF50633_REGULATOR_LDO4] = {
345 .constraints = {
346 .min_uV = 3200000,
347 .max_uV = 3200000,
348 .valid_modes_mask = REGULATOR_MODE_NORMAL,
349 .apply_uV = 1,
350 },
351 },
352 [PCF50633_REGULATOR_LDO5] = {
353 .constraints = {
354 .min_uV = 3000000,
355 .max_uV = 3000000,
356 .valid_modes_mask = REGULATOR_MODE_NORMAL,
357 .apply_uV = 1,
358 .state_mem = {
359 .enabled = 1,
360 },
361 },
362 },
363 [PCF50633_REGULATOR_LDO6] = {
364 .constraints = {
365 .min_uV = 3000000,
366 .max_uV = 3000000,
367 .valid_modes_mask = REGULATOR_MODE_NORMAL,
368 },
369 },
370 [PCF50633_REGULATOR_MEMLDO] = {
371 .constraints = {
372 .min_uV = 1800000,
373 .max_uV = 1800000,
374 .valid_modes_mask = REGULATOR_MODE_NORMAL,
375 .state_mem = {
376 .enabled = 1,
377 },
378 },
379 },
380
381 },
382 .probe_done = gta02_pmu_attach_child_devices,
383 .mbc_event_callback = gta02_pmu_event_callback,
384};
385
386
387/* NOR Flash. */
388
389#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
390#define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */
391
392static struct physmap_flash_data gta02_nor_flash_data = {
393 .width = 2,
394};
395
396static struct resource gta02_nor_flash_resource = {
397 .start = GTA02_FLASH_BASE,
398 .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
399 .flags = IORESOURCE_MEM,
400};
401
402static struct platform_device gta02_nor_flash = {
403 .name = "physmap-flash",
404 .id = 0,
405 .dev = {
406 .platform_data = &gta02_nor_flash_data,
407 },
408 .resource = &gta02_nor_flash_resource,
409 .num_resources = 1,
410};
411
412
413struct platform_device s3c24xx_pwm_device = {
414 .name = "s3c24xx_pwm",
415 .num_resources = 0,
416};
417
418static struct i2c_board_info gta02_i2c_devs[] __initdata = {
419 {
420 I2C_BOARD_INFO("pcf50633", 0x73),
421 .irq = GTA02_IRQ_PCF50633,
422 .platform_data = &gta02_pcf_pdata,
423 },
424 {
425 I2C_BOARD_INFO("wm8753", 0x1a),
426 },
427};
428
429static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
430 [0] = {
431 /*
432 * This name is also hard-coded in the boot loaders, so
433 * changing it would would require all users to upgrade
434 * their boot loaders, some of which are stored in a NOR
435 * that is considered to be immutable.
436 */
437 .name = "neo1973-nand",
438 .nr_chips = 1,
439 .flash_bbt = 1,
440 },
441};
442
443/*
444 * Choose a set of timings derived from S3C@2442B MCP54
445 * data sheet (K5D2G13ACM-D075 MCP Memory).
446 */
447
448static struct s3c2410_platform_nand __initdata gta02_nand_info = {
449 .tacls = 0,
450 .twrph0 = 25,
451 .twrph1 = 15,
452 .nr_sets = ARRAY_SIZE(gta02_nand_sets),
453 .sets = gta02_nand_sets,
454};
455
456
457static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
458{
459 switch (cmd) {
460 case S3C2410_UDC_P_ENABLE:
461 pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
462 gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
463 break;
464 case S3C2410_UDC_P_DISABLE:
465 pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
466 gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
467 break;
468 case S3C2410_UDC_P_RESET:
469 pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
470 /* FIXME: Do something here. */
471 }
472}
473
474/* Get PMU to set USB current limit accordingly. */
475static struct s3c2410_udc_mach_info gta02_udc_cfg = {
476 .vbus_draw = gta02_udc_vbus_draw,
477 .udc_command = gta02_udc_command,
478
479};
480
481
482
483static void gta02_bl_set_intensity(int intensity)
484{
485 struct pcf50633 *pcf = gta02_pcf;
486 int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
487
488 /* We map 8-bit intensity to 6-bit intensity in hardware. */
489 intensity >>= 2;
490
491 /*
492 * This can happen during, eg, print of panic on blanked console,
493 * but we can't service i2c without interrupts active, so abort.
494 */
495 if (in_atomic()) {
496 printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n");
497 return;
498 }
499
500 old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
501 if (intensity == old_intensity)
502 return;
503
504 /* We can't do this anywhere else. */
505 pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5);
506
507 if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3))
508 old_intensity = 0;
509
510 /*
511 * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
512 * if seen, you have to re-enable the LED unit.
513 */
514 if (!intensity || !old_intensity)
515 pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0);
516
517 /* Illegal to set LEDOUT to 0. */
518 if (!intensity)
519 pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
520 else
521 pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
522 intensity);
523
524 if (intensity)
525 pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2);
526
527}
528
529static struct generic_bl_info gta02_bl_info = {
530 .name = "gta02-bl",
531 .max_intensity = 0xff,
532 .default_intensity = 0xff,
533 .set_bl_intensity = gta02_bl_set_intensity,
534};
535
536static struct platform_device gta02_bl_dev = {
537 .name = "generic-bl",
538 .id = 1,
539 .dev = {
540 .platform_data = &gta02_bl_info,
541 },
542};
543
544
545
546/* USB */
547static struct s3c2410_hcd_info gta02_usb_info __initdata = {
548 .port[0] = {
549 .flags = S3C_HCDFLG_USED,
550 },
551 .port[1] = {
552 .flags = 0,
553 },
554};
555
556
557static void __init gta02_map_io(void)
558{
559 s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
560 s3c24xx_init_clocks(12000000);
561 s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
562}
563
564
565/* These are the guys that don't need to be children of PMU. */
566
567static struct platform_device *gta02_devices[] __initdata = {
568 &s3c_device_ohci,
569 &s3c_device_wdt,
570 &s3c_device_sdi,
571 &s3c_device_usbgadget,
572 &s3c_device_nand,
573 &gta02_nor_flash,
574 &s3c24xx_pwm_device,
575 &s3c_device_iis,
576 &s3c_device_i2c0,
577};
578
579/* These guys DO need to be children of PMU. */
580
581static struct platform_device *gta02_devices_pmu_children[] = {
582 &gta02_bl_dev,
583};
584
585
586/*
587 * This is called when pc50633 is probed, quite late in the day since it is an
588 * I2C bus device. Here we can define platform devices with the advantage that
589 * we can mark the pcf50633 as the parent. This makes them get suspended and
590 * resumed with their parent the pcf50633 still around. All devices whose
591 * operation depends on something from pcf50633 must have this relationship
592 * made explicit like this, or suspend and resume will become an unreliable
593 * hellworld.
594 */
595
596static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
597{
598 int n;
599
600 /* Grab a copy of the now probed PMU pointer. */
601 gta02_pcf = pcf;
602
603 for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
604 gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
605
606 platform_add_devices(gta02_devices_pmu_children,
607 ARRAY_SIZE(gta02_devices_pmu_children));
608}
609
610static void gta02_poweroff(void)
611{
612 pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
613}
614
615static void __init gta02_machine_init(void)
616{
617 /* Set the panic callback to make AUX LED blink at ~5Hz. */
618 panic_blink = gta02_panic_blink;
619
620 s3c_pm_init();
621
622#ifdef CONFIG_CHARGER_PCF50633
623 INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
624#endif
625
626 s3c24xx_udc_set_platdata(&gta02_udc_cfg);
627 s3c_ohci_set_platdata(&gta02_usb_info);
628 s3c_nand_set_platdata(&gta02_nand_info);
629 s3c_i2c0_set_platdata(NULL);
630
631 i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
632
633 platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
634 pm_power_off = gta02_poweroff;
635}
636
637
638MACHINE_START(NEO1973_GTA02, "GTA02")
639 /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
640 .phys_io = S3C2410_PA_UART,
641 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
642 .boot_params = S3C2410_SDRAM_PA + 0x100,
643 .map_io = gta02_map_io,
644 .init_irq = s3c24xx_init_irq,
645 .init_machine = gta02_machine_init,
646 .timer = &s3c24xx_timer,
647MACHINE_END