linux-2.6.37: update shr.patch and move gta02-dont-block-dai-switch.patch to gitoriou...
[openembedded.git] / recipes / linux / linux-2.6.37 / shr.patch
blob41e4541d2d831cae0b4c83e7cee52b2ddc05e580
1 All patches from shr kernel repository
2 rebased on top of openmoko kernel repository
4 https://gitorious.org/shr/linux/commits/shr-2.6.37-nodrm
6 f576ab9fd power_supply: Ignore -ENODATA errors when generating uevents
7 3a4d877 wm8753: allow setting DAI mode even while pcm is active
8 bd961d3 nand/s3c2410: add mising badblocksbits value
9 f12719d nand: Fix S3C NAND clok stop
10 acf3f89 input: lis302dl: fix the resume path
11 4682e58 (AG: there's some more rationale for changing this here
12 0737f9a Temporarily rename pcf50633-gpio -> pcf50633-gpio.0
13 3d04b2b lis302dl accelerometer driver
14 58aa277 Use 100 as HZ value on S3C24XX
15 42920dc wm8753: use snd_soc_jack on neo1973
16 8d2fadf Force GPS power up on resume if it were powered up on suspend
17 3f2ddad s3c2410_ts: jitter less touchscreen for glamo, version 4
18 6f5f745 Openmoko resume reason sysfs node ported from 2.6.29
19 9b2268e Rename /dev/s3c2410_serialXXX to /dev/ttySACXXX
20 8a3a0a2 glamo-display: fix WSOD for 242 timming
21 0b6c220 Enable powering off after 8s POWER press
22 d96f9c7 Fix high power consumption in suspend
23 2475b0a tslib relies on ts pressures events so this hack is needed to get tslib stuff working
24 f4fdac1 ar6000_delay.patch
25 85ee74f usbhost.patch
26 1cbab82 touchscreen: ignore unexpected interrupts
27 516ebb8 wm8753: fix build with gcc-4.4.2, which works ok with 4.1.2
29 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
30 index d56d21c0..fea7f49 100644
31 --- a/arch/arm/Kconfig
32 +++ b/arch/arm/Kconfig
33 @@ -1302,7 +1302,7 @@ source kernel/Kconfig.preempt
35 config HZ
36 int
37 - default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
38 + default 200 if ARCH_EBSA110 || ARCH_S5P64X0 || \
39 ARCH_S5P6442 || ARCH_S5PV210 || ARCH_S5PV310
40 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
41 default AT91_TIMER_HZ if ARCH_AT91
42 diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
43 index 035d116..16d9855 100644
44 --- a/arch/arm/mach-s3c2440/Makefile
45 +++ b/arch/arm/mach-s3c2440/Makefile
46 @@ -38,6 +38,7 @@ obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o \
47 gta02-pm-bt.o \
48 gta02-pm-gps.o \
49 gta02-pm-gsm.o \
50 + gta02-pm-usbhost.o \
51 gta02-pm-wlan.o \
52 gta02-fiq.o \
53 gta02-hdq.o \
54 diff --git a/arch/arm/mach-s3c2440/gta02-pm-gps.c b/arch/arm/mach-s3c2440/gta02-pm-gps.c
55 index 5f57eb4..092f5a0 100644
56 --- a/arch/arm/mach-s3c2440/gta02-pm-gps.c
57 +++ b/arch/arm/mach-s3c2440/gta02-pm-gps.c
58 @@ -42,7 +42,7 @@ int gta02_pm_gps_is_on(void)
59 EXPORT_SYMBOL_GPL(gta02_pm_gps_is_on);
61 /* This is the POWERON pin */
62 -static void gps_pwron_set(int on)
63 +static void gps_pwron_set(int on, int ignore_state)
65 if (on) {
66 /* return UART pins to being UART pins */
67 @@ -50,7 +50,7 @@ static void gps_pwron_set(int on)
68 /* remove pulldown now it won't be floating any more */
69 s3c_gpio_setpull(S3C2410_GPH(5), S3C_GPIO_PULL_NONE);
71 - if (!gta02_gps.power_was_on)
72 + if (!gta02_gps.power_was_on || ignore_state)
73 regulator_enable(gta02_gps.regulator);
74 } else {
76 @@ -61,7 +61,7 @@ static void gps_pwron_set(int on)
77 gpio_set_value(S3C2410_GPH(4), 0);
78 /* don't let RX from unpowered GPS float */
79 s3c_gpio_setpull(S3C2410_GPH(5), S3C_GPIO_PULL_DOWN);
80 - if (gta02_gps.power_was_on)
81 + if (gta02_gps.power_was_on || ignore_state)
82 regulator_disable(gta02_gps.regulator);
85 @@ -108,7 +108,7 @@ static ssize_t power_gps_write(struct device *dev,
86 unsigned long on = simple_strtoul(buf, NULL, 10);
88 if (!strcmp(attr->attr.name, "power_on")) {
89 - gps_pwron_set(on);
90 + gps_pwron_set(on, 0);
91 gta02_gps.power_was_on = !!on;
92 #ifdef CONFIG_PM
93 } else if (!strcmp(attr->attr.name, "keep_on_in_suspend")) {
94 @@ -123,7 +123,7 @@ static int gta02_pm_gps_suspend(struct device *dev)
96 if (!gta02_gps.keep_on_in_suspend ||
97 !gta02_gps.power_was_on)
98 - gps_pwron_set(0);
99 + gps_pwron_set(0, 0);
100 else
101 dev_warn(dev, "GTA02: keeping gps ON "
102 "during suspend\n");
103 @@ -133,7 +133,7 @@ static int gta02_pm_gps_suspend(struct device *dev)
104 static int gta02_pm_gps_resume(struct device *dev)
106 if (!gta02_gps.keep_on_in_suspend && gta02_gps.power_was_on)
107 - gps_pwron_set(1);
108 + gps_pwron_set(1, 1);
110 return 0;
112 diff --git a/arch/arm/mach-s3c2440/gta02-pm-usbhost.c b/arch/arm/mach-s3c2440/gta02-pm-usbhost.c
113 new file mode 100644
114 index 0000000..233340a
115 --- /dev/null
116 +++ b/arch/arm/mach-s3c2440/gta02-pm-usbhost.c
117 @@ -0,0 +1,174 @@
119 + * USBHOST Management code for the Openmoko Freerunner GSM Phone
121 + * (C) 2007 by Openmoko Inc.
122 + * Author: Harald Welte <laforge@openmoko.org>
123 + * All rights reserved.
125 + * This program is free software; you can redistribute it and/or modify
126 + * it under the terms of the GNU General Public License version 2 as
127 + * published by the Free Software Foundation
129 + */
131 +#include <linux/module.h>
132 +#include <linux/init.h>
133 +#include <linux/kernel.h>
134 +#include <linux/platform_device.h>
135 +#include <linux/console.h>
136 +#include <linux/errno.h>
137 +#include <linux/interrupt.h>
138 +#include <linux/delay.h>
139 +#include <linux/err.h>
140 +#include <linux/regulator/consumer.h>
142 +#include <mach/gpio.h>
143 +#include <asm/mach-types.h>
145 +#include <mach/hardware.h>
147 +#include <mach/gta02.h>
148 +#include <mach/regs-gpio.h>
149 +#include <mach/regs-gpioj.h>
151 +static struct regulator *gta02_usbhost_regulator;
153 +static ssize_t usbhost_read(struct device *dev, struct device_attribute *attr,
154 + char *buf)
156 + if (!strcmp(attr->attr.name, "power_on")) {
157 + if (regulator_is_enabled(gta02_usbhost_regulator))
158 + goto out_1;
161 + return strlcpy(buf, "0\n", 3);
162 +out_1:
163 + return strlcpy(buf, "1\n", 3);
166 +static void usbhost_on_off(struct device *dev, int on)
169 + on = !!on;
171 + if (on == regulator_is_enabled(gta02_usbhost_regulator))
172 + return;
174 + if (!on) {
175 + regulator_disable(gta02_usbhost_regulator);
176 + return;
179 + regulator_enable(gta02_usbhost_regulator);
182 +static ssize_t usbhost_write(struct device *dev, struct device_attribute *attr,
183 + const char *buf, size_t count)
185 + unsigned long on = simple_strtoul(buf, NULL, 10);
187 + if (!strcmp(attr->attr.name, "power_on")) {
188 + usbhost_on_off(dev, on);
190 + return count;
193 + return count;
196 +static DEVICE_ATTR(power_on, 0644, usbhost_read, usbhost_write);
198 +#ifdef CONFIG_PM
200 +static int gta02_usbhost_suspend(struct device *dev)
202 + return 0;
205 +static int gta02_usbhost_suspend_late(struct device *dev)
207 + return 0;
210 +static int gta02_usbhost_resume(struct device *dev)
212 + return 0;
215 +static struct dev_pm_ops gta02_usbhost_pm_ops = {
216 + .suspend = gta02_usbhost_suspend,
217 + .suspend_noirq = gta02_usbhost_suspend_late,
218 + .resume = gta02_usbhost_resume,
221 +#define GTA02_USBHOST_PM_OPS (&gta02_usbhost_pm_ops)
223 +#else
224 +#define GTA02_USBHOST_PM_OPS NULL
225 +#endif /* CONFIG_PM */
227 +static struct attribute *gta02_usbhost_sysfs_entries[] = {
228 + &dev_attr_power_on.attr,
229 + NULL
232 +static struct attribute_group gta02_usbhost_attr_group = {
233 + .name = NULL,
234 + .attrs = gta02_usbhost_sysfs_entries,
237 +static int __init gta02_usbhost_probe(struct platform_device *pdev)
239 + int ret;
241 + gta02_usbhost_regulator = regulator_get_exclusive(&pdev->dev, "USBHOST");
243 + if (IS_ERR(gta02_usbhost_regulator)) {
244 + ret = PTR_ERR(gta02_usbhost_regulator);
245 + dev_err(&pdev->dev, "Failed to get regulator: %d\n", ret);
246 + return ret;
249 + ret = sysfs_create_group(&pdev->dev.kobj, &gta02_usbhost_attr_group);
250 + if (ret) {
251 + dev_err(&pdev->dev, "Failed to create sysfs entries: %d\n", ret);
252 + return ret;
255 + return 0;
258 +static int gta02_usbhost_remove(struct platform_device *pdev)
260 + usbhost_on_off(&pdev->dev, 0);
262 + sysfs_remove_group(&pdev->dev.kobj, &gta02_usbhost_attr_group);
263 + regulator_put(gta02_usbhost_regulator);
265 + return 0;
268 +static struct platform_driver gta02_usbhost_driver = {
269 + .probe = gta02_usbhost_probe,
270 + .remove = gta02_usbhost_remove,
271 + .driver = {
272 + .name = "gta02-pm-usbhost",
273 + .pm = GTA02_USBHOST_PM_OPS,
274 + },
277 +static int __devinit gta02_usbhost_init(void)
279 + return platform_driver_register(&gta02_usbhost_driver);
281 +module_init(gta02_usbhost_init);
283 +static void gta02_usbhost_exit(void)
285 + platform_driver_unregister(&gta02_usbhost_driver);
287 +module_exit(gta02_usbhost_exit);
289 +MODULE_LICENSE("GPL");
290 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
291 +MODULE_DESCRIPTION("Openmoko Freerunner USBHOST Power Management");
292 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
293 index 450f1f2..6c2279e 100644
294 --- a/arch/arm/mach-s3c2440/mach-gta02.c
295 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
296 @@ -62,6 +62,7 @@
298 #include <linux/input.h>
299 #include <linux/gpio_keys.h>
300 +#include <linux/lis302dl.h>
302 #include <linux/leds.h>
303 #include <linux/leds_pwm.h>
304 @@ -109,6 +110,7 @@
305 #include <linux/jbt6k74.h>
306 #include <linux/glamofb.h>
307 #include <linux/mfd/glamo.h>
308 +#include <linux/mfd/glamo-core.h>
310 static struct pcf50633 *gta02_pcf;
312 @@ -127,6 +129,10 @@ static long gta02_panic_blink(int state)
313 return delay;
316 +struct platform_device gta02_resume_reason_device = {
317 + .name = "neo1973-resume",
318 + .num_resources = 0,
321 static struct map_desc gta02_iodesc[] __initdata = {
323 @@ -177,6 +183,10 @@ static struct platform_device gta02_pm_gsm_dev = {
324 .name = "gta02-pm-gsm",
327 +static struct platform_device gta02_pm_usbhost_dev = {
328 + .name = "gta02-pm-usbhost",
331 static struct platform_device gta02_pm_wlan_dev = {
332 .name = "gta02-pm-wlan",
334 @@ -186,6 +196,11 @@ static struct regulator_consumer_supply gsm_supply_consumer = {
335 .supply = "GSM",
338 +static struct regulator_consumer_supply usbhost_supply_consumer = {
339 + .dev = &gta02_pm_usbhost_dev.dev,
340 + .supply = "USBHOST",
343 static struct regulator_init_data gsm_supply_init_data = {
344 .constraints = {
345 .min_uV = 3700000,
346 @@ -197,6 +212,17 @@ static struct regulator_init_data gsm_supply_init_data = {
347 .consumer_supplies = &gsm_supply_consumer,
350 +static struct regulator_init_data usbhost_supply_init_data = {
351 + .constraints = {
352 + .min_uV = 3700000,
353 + .max_uV = 3700000,
354 + .valid_modes_mask = REGULATOR_MODE_NORMAL,
355 + .valid_ops_mask = REGULATOR_CHANGE_STATUS,
356 + },
357 + .num_consumer_supplies = 1,
358 + .consumer_supplies = &usbhost_supply_consumer,
361 static struct fixed_voltage_config gsm_supply_config = {
362 .supply_name = "GSM",
363 .microvolts = 3700000,
364 @@ -205,6 +231,14 @@ static struct fixed_voltage_config gsm_supply_config = {
365 .init_data = &gsm_supply_init_data,
368 +static struct fixed_voltage_config usbhost_supply_config = {
369 + .supply_name = "USBHOST",
370 + .microvolts = 3700000,
371 + .gpio = GTA02_GPIO_PCF(PCF50633_GPO),
372 + .enable_high = 1,
373 + .init_data = &usbhost_supply_init_data,
376 static struct platform_device gta02_gsm_supply_device = {
377 .name = "reg-fixed-voltage",
378 .id = 1,
379 @@ -213,6 +247,14 @@ static struct platform_device gta02_gsm_supply_device = {
383 +static struct platform_device gta02_usbhost_supply_device = {
384 + .name = "reg-fixed-voltage",
385 + .id = 2,
386 + .dev = {
387 + .platform_data = &usbhost_supply_config,
388 + },
392 * we crank down SD Card clock dynamically when GPS is powered
394 @@ -304,6 +346,202 @@ static struct glamo_platform_data gta02_glamo_pdata = {
395 .glamo_external_reset = gta02_glamo_external_reset,
398 +/* SPI: Accelerometers attached to SPI of s3c244x */
401 + * Situation is that Linux SPI can't work in an interrupt context, so we
402 + * implement our own bitbang here. Arbitration is needed because not only
403 + * can this interrupt happen at any time even if foreground wants to use
404 + * the bitbang API from Linux, but multiple motion sensors can be on the
405 + * same SPI bus, and multiple interrupts can happen.
407 + * Foreground / interrupt arbitration is okay because the interrupts are
408 + * disabled around all the foreground SPI code.
410 + * Interrupt / Interrupt arbitration is evidently needed, otherwise we
411 + * lose edge-triggered service after a while due to the two sensors sharing
412 + * the SPI bus having irqs at the same time eventually.
414 + * Servicing is typ 75 - 100us at 400MHz.
415 + */
417 +/* #define DEBUG_SPEW_MS */
418 +#define MG_PER_SAMPLE 18
420 +struct lis302dl_platform_data lis302_pdata_top;
421 +struct lis302dl_platform_data lis302_pdata_bottom;
424 + * generic SPI RX and TX bitbang
425 + * only call with interrupts off!
426 + */
428 +static void __gta02_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx,
429 + int tx_bytes, u8 *rx, int rx_bytes)
431 + struct lis302dl_platform_data *pdata = lis->pdata;
432 + int n;
433 + u8 shifter = 0;
434 + unsigned long other_cs;
436 + /*
437 + * Huh... "quirk"... CS on this device is not really "CS" like you can
438 + * expect.
440 + * When it is 0 it selects SPI interface mode.
441 + * When it is 1 it selects I2C interface mode.
443 + * Because we have 2 devices on one interface we have to make sure
444 + * that the "disabled" device (actually in I2C mode) don't think we're
445 + * talking to it.
447 + * When we talk to the "enabled" device, the "disabled" device sees
448 + * the clocks as I2C clocks, creating havoc.
450 + * I2C sees MOSI going LOW while CLK HIGH as a START action, thus we
451 + * must ensure this is never issued.
452 + */
454 + if (&lis302_pdata_top == pdata)
455 + other_cs = lis302_pdata_bottom.pin_chip_select;
456 + else
457 + other_cs = lis302_pdata_top.pin_chip_select;
459 + s3c2410_gpio_setpin(other_cs, 1);
460 + s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
461 + s3c2410_gpio_setpin(pdata->pin_clk, 1);
462 + s3c2410_gpio_setpin(pdata->pin_chip_select, 0);
464 + /* send the register index, r/w and autoinc bits */
465 + for (n = 0; n < (tx_bytes << 3); n++) {
466 + if (!(n & 7))
467 + shifter = ~tx[n >> 3];
468 + s3c2410_gpio_setpin(pdata->pin_clk, 0);
469 + s3c2410_gpio_setpin(pdata->pin_mosi, !(shifter & 0x80));
470 + s3c2410_gpio_setpin(pdata->pin_clk, 1);
471 + shifter <<= 1;
474 + for (n = 0; n < (rx_bytes << 3); n++) { /* 8 bits each */
475 + s3c2410_gpio_setpin(pdata->pin_clk, 0);
476 + shifter <<= 1;
477 + if (s3c2410_gpio_getpin(pdata->pin_miso))
478 + shifter |= 1;
479 + if ((n & 7) == 7)
480 + rx[n >> 3] = shifter;
481 + s3c2410_gpio_setpin(pdata->pin_clk, 1);
483 + s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
484 + s3c2410_gpio_setpin(other_cs, 1);
488 +static int gta02_lis302dl_bitbang_read_reg(struct lis302dl_info *lis, u8 reg)
490 + u8 data = 0xc0 | reg; /* read, autoincrement */
491 + unsigned long flags;
493 + local_irq_save(flags);
495 + __gta02_lis302dl_bitbang(lis, &data, 1, &data, 1);
497 + local_irq_restore(flags);
499 + return data;
502 +static void gta02_lis302dl_bitbang_write_reg(struct lis302dl_info *lis, u8 reg,
503 + u8 val)
505 + u8 data[2] = { 0x00 | reg, val }; /* write, no autoincrement */
506 + unsigned long flags;
508 + local_irq_save(flags);
510 + __gta02_lis302dl_bitbang(lis, &data[0], 2, NULL, 0);
512 + local_irq_restore(flags);
517 +void gta02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume)
519 + struct lis302dl_platform_data *pdata = lis->pdata;
521 + if (!resume) {
522 + /*
523 + * we don't want to power them with a high level
524 + * because GSENSOR_3V3 is not up during suspend
525 + */
526 + s3c2410_gpio_setpin(pdata->pin_chip_select, 0);
527 + s3c2410_gpio_setpin(pdata->pin_clk, 0);
528 + s3c2410_gpio_setpin(pdata->pin_mosi, 0);
529 + /* misnomer: it is a pullDOWN in 2442 */
530 + s3c2410_gpio_pullup(pdata->pin_miso, 1);
531 + return;
534 + /* back to normal */
535 + s3c2410_gpio_setpin(pdata->pin_chip_select, 1);
536 + s3c2410_gpio_setpin(pdata->pin_clk, 1);
537 + /* misnomer: it is a pullDOWN in 2442 */
538 + s3c2410_gpio_pullup(pdata->pin_miso, 0);
540 + s3c2410_gpio_cfgpin(pdata->pin_chip_select, S3C2410_GPIO_OUTPUT);
541 + s3c2410_gpio_cfgpin(pdata->pin_clk, S3C2410_GPIO_OUTPUT);
542 + s3c2410_gpio_cfgpin(pdata->pin_mosi, S3C2410_GPIO_OUTPUT);
543 + s3c2410_gpio_cfgpin(pdata->pin_miso, S3C2410_GPIO_INPUT);
549 +struct lis302dl_platform_data lis302_pdata_top = {
550 + .name = "lis302-1 (top)",
551 + .pin_chip_select= S3C2410_GPD(12),
552 + .pin_clk = S3C2410_GPG(7),
553 + .pin_mosi = S3C2410_GPG(6),
554 + .pin_miso = S3C2410_GPG(5),
555 + .interrupt = GTA02_IRQ_GSENSOR_1,
556 + .open_drain = 1, /* altered at runtime by PCB rev */
557 + .lis302dl_bitbang = __gta02_lis302dl_bitbang,
558 + .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg,
559 + .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg,
560 + .lis302dl_suspend_io = gta02_lis302dl_suspend_io,
563 +struct lis302dl_platform_data lis302_pdata_bottom = {
564 + .name = "lis302-2 (bottom)",
565 + .pin_chip_select= S3C2410_GPD(13),
566 + .pin_clk = S3C2410_GPG(7),
567 + .pin_mosi = S3C2410_GPG(6),
568 + .pin_miso = S3C2410_GPG(5),
569 + .interrupt = GTA02_IRQ_GSENSOR_2,
570 + .open_drain = 1, /* altered at runtime by PCB rev */
571 + .lis302dl_bitbang = __gta02_lis302dl_bitbang,
572 + .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg,
573 + .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg,
574 + .lis302dl_suspend_io = gta02_lis302dl_suspend_io,
578 +static struct platform_device s3c_device_spi_acc1 = {
579 + .name = "lis302dl",
580 + .id = 1,
581 + .dev = {
582 + .platform_data = &lis302_pdata_top,
583 + },
586 +static struct platform_device s3c_device_spi_acc2 = {
587 + .name = "lis302dl",
588 + .id = 2,
589 + .dev = {
590 + .platform_data = &lis302_pdata_bottom,
591 + },
594 /* JBT6k74 display controller */
595 static void gta02_jbt6k74_probe_completed(struct device *dev)
597 @@ -498,6 +736,11 @@ static struct regulator_consumer_supply hcldo_consumers[] = {
601 +static void gta02_poweroff(void)
603 + pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
606 struct pcf50633_platform_data gta02_pcf_pdata = {
607 .resumers = {
608 [0] = PCF50633_INT1_USBINS |
609 @@ -534,7 +777,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
610 .min_uV = 1300000,
611 .max_uV = 1600000,
612 .valid_modes_mask = REGULATOR_MODE_NORMAL,
613 - .always_on = 1,
614 + .always_on = 0,
615 .apply_uV = 1,
618 @@ -626,6 +869,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
620 .probe_done = gta02_pmu_attach_child_devices,
621 .mbc_event_callback = gta02_pmu_event_callback,
622 + .force_shutdown = gta02_poweroff,
626 @@ -728,11 +972,31 @@ static struct s3c2410_hcd_info gta02_usb_info __initdata = {
630 +static int glamo_slowed = 0;
632 +static void gta02_ts_hook_before_adc ()
634 + if (!glamo_slowed) {
635 + glamo_slowed = 1;
636 + glamo_pixclock_slow(dev_get_drvdata (&gta02_glamo_dev.dev));
640 +static void gta02_ts_hook_after_adc ()
642 + if (glamo_slowed) {
643 + glamo_slowed = 0;
644 + glamo_pixclock_fast(dev_get_drvdata (&gta02_glamo_dev.dev));
648 /* Touchscreen */
649 static struct s3c2410_ts_mach_info gta02_ts_info = {
650 - .delay = 10000,
651 + .delay = 1000,
652 .presc = 0xff, /* slow as we can go */
653 - .oversampling_shift = 2,
654 + .oversampling_shift = 0,
655 + .before_adc_hook = gta02_ts_hook_before_adc,
656 + .after_adc_hook = gta02_ts_hook_after_adc,
659 /* Buttons */
660 @@ -1073,6 +1337,9 @@ static struct platform_device *gta02_devices[] __initdata = {
661 static struct platform_device *gta02_devices_pmu_children[] = {
662 &gta02_hdq_device,
663 &gta02_platform_bat,
664 + &gta02_resume_reason_device,
665 + &s3c_device_spi_acc1,
666 + &s3c_device_spi_acc2,
670 @@ -1102,11 +1369,6 @@ static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
671 regulator_has_full_constraints();
674 -static void gta02_poweroff(void)
676 - pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
679 struct gta02_device_children {
680 const char *dev_name;
681 size_t num_children;
682 @@ -1116,12 +1378,17 @@ struct gta02_device_children {
684 static struct platform_device* gta02_pcf50633_gpio_children[] = {
685 &gta02_gsm_supply_device,
686 + &gta02_usbhost_supply_device,
689 static struct platform_device* gta02_gsm_supply_children[] = {
690 &gta02_pm_gsm_dev,
693 +static struct platform_device* gta02_usbhost_supply_children[] = {
694 + &gta02_pm_usbhost_dev,
697 static struct platform_device* gta02_hdq_children[] = {
698 &bq27000_battery_device,
700 @@ -1130,7 +1397,7 @@ static struct platform_device* gta02_hdq_children[] = {
701 static struct gta02_device_children gta02_device_children[] = {
703 .dev_name = "pcf50633-gpio.0",
704 - .num_children = 1,
705 + .num_children = 2,
706 .children = gta02_pcf50633_gpio_children,
709 @@ -1139,6 +1406,11 @@ static struct gta02_device_children gta02_device_children[] = {
710 .children = gta02_gsm_supply_children,
713 + .dev_name = "reg-fixed-voltage.2",
714 + .num_children = 1,
715 + .children = gta02_usbhost_supply_children,
716 + },
718 .dev_name = "spi2.0",
719 .probed_callback = gta02_jbt6k74_probe_completed,
721 @@ -1228,6 +1500,10 @@ static void __init gta02_machine_init(void)
723 s3c_pm_init();
725 + /* we need push-pull interrupt from motion sensors */
726 + lis302_pdata_top.open_drain = 0;
727 + lis302_pdata_bottom.open_drain = 0;
729 #ifdef CONFIG_CHARGER_PCF50633
730 INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
731 #endif
732 diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h
733 index 26fdb22..f475349 100644
734 --- a/arch/arm/plat-samsung/include/plat/ts.h
735 +++ b/arch/arm/plat-samsung/include/plat/ts.h
736 @@ -15,6 +15,8 @@ struct s3c2410_ts_mach_info {
737 int presc;
738 int oversampling_shift;
739 void (*cfg_gpio)(struct platform_device *dev);
740 + void (*before_adc_hook)(void);
741 + void (*after_adc_hook)(void);
744 extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
745 diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c
746 index 2231d80..d342876 100644
747 --- a/arch/arm/plat-samsung/time.c
748 +++ b/arch/arm/plat-samsung/time.c
749 @@ -195,12 +195,12 @@ static void s3c2410_timer_setup (void)
751 /* configure clock tick */
753 - timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
754 + timer_usec_ticks = timer_mask_usec_ticks(12, pclk);
756 tscaler = clk_get_parent(tdiv);
758 - clk_set_rate(tscaler, pclk / 3);
759 - clk_set_rate(tdiv, pclk / 6);
760 + clk_set_rate(tscaler, pclk / 6);
761 + clk_set_rate(tdiv, pclk / 12);
762 clk_set_parent(tin, tdiv);
764 tcnt = clk_get_rate(tin) / HZ;
765 diff --git a/drivers/ar6000/hif/hif2.c b/drivers/ar6000/hif/hif2.c
766 index 386d96e..90178d0 100644
767 --- a/drivers/ar6000/hif/hif2.c
768 +++ b/drivers/ar6000/hif/hif2.c
769 @@ -517,6 +517,8 @@ static int ar6000_do_activate(struct hif_device *hif)
770 goto out_func_ready;
773 + mdelay (10);
775 ret = htcCallbacks.deviceInsertedHandler(hif);
776 if (ret == A_OK)
777 return 0;
778 diff --git a/drivers/gpio/pcf50633-gpio.c b/drivers/gpio/pcf50633-gpio.c
779 index eb044e8..9dd3735 100644
780 --- a/drivers/gpio/pcf50633-gpio.c
781 +++ b/drivers/gpio/pcf50633-gpio.c
782 @@ -206,7 +206,7 @@ static struct platform_driver pcf50633_gpio_driver = {
783 .probe = pcf50633_gpio_probe,
784 .remove = __devexit_p(pcf50633_gpio_remove),
785 .driver = {
786 - .name = "pcf50633-gpio",
787 + .name = "pcf50633-gpio.0",
788 .owner = THIS_MODULE,
791 diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
792 index e8c0b55..cd31e49 100644
793 --- a/drivers/input/misc/Kconfig
794 +++ b/drivers/input/misc/Kconfig
795 @@ -455,4 +455,13 @@ config INPUT_ADXL34X_SPI
796 To compile this driver as a module, choose M here: the
797 module will be called adxl34x-spi.
799 +config INPUT_LIS302DL
800 + tristate "STmicro LIS302DL 3-axis accelerometer"
801 + depends on SPI_MASTER
802 + help
803 + SPI driver for the STmicro LIS302DL 3-axis accelerometer.
805 + The userspece interface is a 3-axis (X/Y/Z) relative movement
806 + Linux input device, reporting REL_[XYZ] events.
808 endif
809 diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
810 index 4d5cea7..63b49bc 100644
811 --- a/drivers/input/misc/Makefile
812 +++ b/drivers/input/misc/Makefile
813 @@ -43,4 +43,5 @@ obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o
814 obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
815 obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
816 obj-$(CONFIG_INPUT_YEALINK) += yealink.o
817 +obj-$(CONFIG_INPUT_LIS302DL) += lis302dl.o
819 diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
820 new file mode 100644
821 index 0000000..1ba7a8f
822 --- /dev/null
823 +++ b/drivers/input/misc/lis302dl.c
824 @@ -0,0 +1,898 @@
825 +/* Linux kernel driver for the ST LIS302D 3-axis accelerometer
827 + * Copyright (C) 2007-2008 by Openmoko, Inc.
828 + * Author: Harald Welte <laforge@openmoko.org>
829 + * converted to private bitbang by:
830 + * Andy Green <andy@openmoko.com>
831 + * ability to set acceleration threshold added by:
832 + * Simon Kagstrom <simon.kagstrom@gmail.com>
833 + * All rights reserved.
835 + * This program is free software; you can redistribute it and/or
836 + * modify it under the terms of the GNU General Public License as
837 + * published by the Free Software Foundation; either version 2 of
838 + * the License, or (at your option) any later version.
840 + * This program is distributed in the hope that it will be useful,
841 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
842 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
843 + * GNU General Public License for more details.
845 + * You should have received a copy of the GNU General Public License
846 + * along with this program; if not, write to the Free Software
847 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
848 + * MA 02111-1307 USA
850 + * TODO
851 + * * statistics for overflow events
852 + * * configuration interface (sysfs) for
853 + * * enable/disable x/y/z axis data ready
854 + * * enable/disable resume from freee fall / click
855 + * * free fall / click parameters
856 + * * high pass filter parameters
857 + */
858 +#include <linux/kernel.h>
859 +#include <linux/types.h>
860 +#include <linux/module.h>
861 +#include <linux/device.h>
862 +#include <linux/platform_device.h>
863 +#include <linux/delay.h>
864 +#include <linux/irq.h>
865 +#include <linux/interrupt.h>
866 +#include <linux/sysfs.h>
868 +#include <linux/lis302dl.h>
870 +/* Utility functions */
871 +static u8 __reg_read(struct lis302dl_info *lis, u8 reg)
873 + return (lis->pdata->lis302dl_bitbang_reg_read)(lis, reg);
876 +static void __reg_write(struct lis302dl_info *lis, u8 reg, u8 val)
878 + (lis->pdata->lis302dl_bitbang_reg_write)(lis, reg, val);
881 +static void __reg_set_bit_mask(struct lis302dl_info *lis, u8 reg, u8 mask,
882 + u8 val)
884 + u_int8_t tmp;
886 + val &= mask;
888 + tmp = __reg_read(lis, reg);
889 + tmp &= ~mask;
890 + tmp |= val;
891 + __reg_write(lis, reg, tmp);
894 +static int __ms_to_duration(struct lis302dl_info *lis, int ms)
896 + /* If we have 400 ms sampling rate, the stepping is 2.5 ms,
897 + * on 100 ms the stepping is 10ms */
898 + if (lis->flags & LIS302DL_F_DR)
899 + return min((ms * 10) / 25, 637);
901 + return min(ms / 10, 2550);
904 +static int __duration_to_ms(struct lis302dl_info *lis, int duration)
906 + if (lis->flags & LIS302DL_F_DR)
907 + return (duration * 25) / 10;
909 + return duration * 10;
912 +static u8 __mg_to_threshold(struct lis302dl_info *lis, int mg)
914 + /* If FS is set each bit is 71mg, otherwise 18mg. The THS register
915 + * has 7 bits for the threshold value */
916 + if (lis->flags & LIS302DL_F_FS)
917 + return min(mg / 71, 127);
919 + return min(mg / 18, 127);
922 +static int __threshold_to_mg(struct lis302dl_info *lis, u8 threshold)
924 + if (lis->flags & LIS302DL_F_FS)
925 + return threshold * 71;
927 + return threshold * 18;
930 +/* interrupt handling related */
932 +enum lis302dl_intmode {
933 + LIS302DL_INTMODE_GND = 0x00,
934 + LIS302DL_INTMODE_FF_WU_1 = 0x01,
935 + LIS302DL_INTMODE_FF_WU_2 = 0x02,
936 + LIS302DL_INTMODE_FF_WU_12 = 0x03,
937 + LIS302DL_INTMODE_DATA_READY = 0x04,
938 + LIS302DL_INTMODE_CLICK = 0x07,
941 +static void __lis302dl_int_mode(struct device *dev, int int_pin,
942 + enum lis302dl_intmode mode)
944 + struct lis302dl_info *lis = dev_get_drvdata(dev);
946 + switch (int_pin) {
947 + case 1:
948 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x07, mode);
949 + break;
950 + case 2:
951 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x38, mode << 3);
952 + break;
953 + default:
954 + BUG();
958 +static void __enable_wakeup(struct lis302dl_info *lis)
960 + __reg_write(lis, LIS302DL_REG_CTRL1, 0);
962 + /* First zero to get to a known state */
963 + __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, LIS302DL_FFWUCFG_XHIE |
964 + LIS302DL_FFWUCFG_YHIE | LIS302DL_FFWUCFG_ZHIE |
965 + LIS302DL_FFWUCFG_LIR);
966 + __reg_write(lis, LIS302DL_REG_FF_WU_THS_1,
967 + __mg_to_threshold(lis, lis->wakeup.threshold));
968 + __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
969 + __ms_to_duration(lis, lis->wakeup.duration));
971 + /* Route the interrupt for wakeup */
972 + __lis302dl_int_mode(lis->dev, 1,
973 + LIS302DL_INTMODE_FF_WU_1);
975 + __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET);
976 + __reg_read(lis, LIS302DL_REG_OUT_X);
977 + __reg_read(lis, LIS302DL_REG_OUT_Y);
978 + __reg_read(lis, LIS302DL_REG_OUT_Z);
979 + __reg_read(lis, LIS302DL_REG_STATUS);
980 + __reg_read(lis, LIS302DL_REG_FF_WU_SRC_1);
981 + __reg_read(lis, LIS302DL_REG_FF_WU_SRC_2);
982 + __reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD | 7);
985 +static void __enable_data_collection(struct lis302dl_info *lis)
987 + u_int8_t ctrl1 = LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen |
988 + LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen;
990 + /* make sure we're powered up and generate data ready */
991 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1);
993 + /* If the threshold is zero, let the device generated an interrupt
994 + * on each datum */
995 + if (lis->threshold == 0) {
996 + __reg_write(lis, LIS302DL_REG_CTRL2, 0);
997 + __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_DATA_READY);
998 + __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_DATA_READY);
999 + } else {
1000 + __reg_write(lis, LIS302DL_REG_CTRL2,
1001 + LIS302DL_CTRL2_HPFF1);
1002 + __reg_write(lis, LIS302DL_REG_FF_WU_THS_1,
1003 + __mg_to_threshold(lis, lis->threshold));
1004 + __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
1005 + __ms_to_duration(lis, lis->duration));
1007 + /* Clear the HP filter "starting point" */
1008 + __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET);
1009 + __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1,
1010 + LIS302DL_FFWUCFG_XHIE | LIS302DL_FFWUCFG_YHIE |
1011 + LIS302DL_FFWUCFG_ZHIE | LIS302DL_FFWUCFG_LIR);
1012 + __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_FF_WU_12);
1013 + __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_FF_WU_12);
1017 +#if 0
1018 +static void _report_btn_single(struct input_dev *inp, int btn)
1020 + input_report_key(inp, btn, 1);
1021 + input_sync(inp);
1022 + input_report_key(inp, btn, 0);
1025 +static void _report_btn_double(struct input_dev *inp, int btn)
1027 + input_report_key(inp, btn, 1);
1028 + input_sync(inp);
1029 + input_report_key(inp, btn, 0);
1030 + input_sync(inp);
1031 + input_report_key(inp, btn, 1);
1032 + input_sync(inp);
1033 + input_report_key(inp, btn, 0);
1035 +#endif
1038 +static void lis302dl_bitbang_read_sample(struct lis302dl_info *lis)
1040 + u8 data = 0xc0 | LIS302DL_REG_STATUS; /* read, autoincrement */
1041 + u8 read[(LIS302DL_REG_OUT_Z - LIS302DL_REG_STATUS) + 1];
1042 + unsigned long flags;
1043 + int mg_per_sample = __threshold_to_mg(lis, 1);
1045 + /* grab the set of register containing status and XYZ data */
1047 + local_irq_save(flags);
1048 + (lis->pdata->lis302dl_bitbang)(lis, &data, 1, &read[0], sizeof(read));
1049 + local_irq_restore(flags);
1051 + /*
1052 + * at the minute the test below fails 50% of the time due to
1053 + * a problem with level interrupts causing ISRs to get called twice.
1054 + * This is a workaround for that, but actually this test is still
1055 + * valid and the information can be used for overrrun stats.
1056 + */
1058 + /* has any kind of overrun been observed by the lis302dl? */
1059 + if (read[0] & (LIS302DL_STATUS_XOR |
1060 + LIS302DL_STATUS_YOR |
1061 + LIS302DL_STATUS_ZOR))
1062 + lis->overruns++;
1064 + /* we have a valid sample set? */
1065 + if (read[0] & LIS302DL_STATUS_XYZDA) {
1066 + input_report_abs(lis->input_dev, ABS_X, mg_per_sample *
1067 + (s8)read[LIS302DL_REG_OUT_X - LIS302DL_REG_STATUS]);
1068 + input_report_abs(lis->input_dev, ABS_Y, mg_per_sample *
1069 + (s8)read[LIS302DL_REG_OUT_Y - LIS302DL_REG_STATUS]);
1070 + input_report_abs(lis->input_dev, ABS_Z, mg_per_sample *
1071 + (s8)read[LIS302DL_REG_OUT_Z - LIS302DL_REG_STATUS]);
1073 + input_sync(lis->input_dev);
1076 + if (lis->threshold)
1077 + /* acknowledge the wakeup source */
1078 + __reg_read(lis, LIS302DL_REG_FF_WU_SRC_1);
1081 +static irqreturn_t lis302dl_interrupt(int irq, void *_lis)
1083 + struct lis302dl_info *lis = _lis;
1085 + lis302dl_bitbang_read_sample(lis);
1086 + return IRQ_HANDLED;
1089 +/* sysfs */
1091 +static ssize_t show_overruns(struct device *dev, struct device_attribute *attr,
1092 + char *buf)
1094 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1096 + return sprintf(buf, "%u\n", lis->overruns);
1099 +static DEVICE_ATTR(overruns, S_IRUGO, show_overruns, NULL);
1101 +static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
1102 + char *buf)
1104 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1105 + u8 ctrl1;
1106 + unsigned long flags;
1108 + local_irq_save(flags);
1109 + ctrl1 = __reg_read(lis, LIS302DL_REG_CTRL1);
1110 + local_irq_restore(flags);
1112 + return sprintf(buf, "%d\n", ctrl1 & LIS302DL_CTRL1_DR ? 400 : 100);
1115 +static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
1116 + const char *buf, size_t count)
1118 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1119 + unsigned long flags;
1121 + local_irq_save(flags);
1123 + if (!strcmp(buf, "400\n")) {
1124 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
1125 + LIS302DL_CTRL1_DR);
1126 + lis->flags |= LIS302DL_F_DR;
1127 + } else {
1128 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
1129 + 0);
1130 + lis->flags &= ~LIS302DL_F_DR;
1132 + local_irq_restore(flags);
1134 + return count;
1137 +static DEVICE_ATTR(sample_rate, S_IRUGO | S_IWUSR, show_rate, set_rate);
1139 +static ssize_t show_scale(struct device *dev, struct device_attribute *attr,
1140 + char *buf)
1142 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1143 + u_int8_t ctrl1;
1144 + unsigned long flags;
1146 + local_irq_save(flags);
1147 + ctrl1 = __reg_read(lis, LIS302DL_REG_CTRL1);
1148 + local_irq_restore(flags);
1150 + return sprintf(buf, "%s\n", ctrl1 & LIS302DL_CTRL1_FS ? "9.2" : "2.3");
1153 +static ssize_t set_scale(struct device *dev, struct device_attribute *attr,
1154 + const char *buf, size_t count)
1156 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1157 + unsigned long flags;
1159 + local_irq_save(flags);
1161 + if (!strcmp(buf, "9.2\n")) {
1162 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
1163 + LIS302DL_CTRL1_FS);
1164 + lis->flags |= LIS302DL_F_FS;
1165 + } else {
1166 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
1167 + 0);
1168 + lis->flags &= ~LIS302DL_F_FS;
1171 + if (lis->flags & LIS302DL_F_INPUT_OPEN)
1172 + __enable_data_collection(lis);
1174 + local_irq_restore(flags);
1176 + return count;
1179 +static DEVICE_ATTR(full_scale, S_IRUGO | S_IWUSR, show_scale, set_scale);
1181 +static ssize_t show_threshold(struct device *dev, struct device_attribute *attr,
1182 + char *buf)
1184 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1186 + /* Display the device view of the threshold setting */
1187 + return sprintf(buf, "%d\n", __threshold_to_mg(lis,
1188 + __mg_to_threshold(lis, lis->threshold)));
1191 +static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
1192 + const char *buf, size_t count)
1194 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1195 + unsigned int val;
1197 + if (sscanf(buf, "%u\n", &val) != 1)
1198 + return -EINVAL;
1199 + /* 8g is the maximum if FS is 1 */
1200 + if (val > 8000)
1201 + return -ERANGE;
1203 + /* Set the threshold and write it out if the device is used */
1204 + lis->threshold = val;
1206 + if (lis->flags & LIS302DL_F_INPUT_OPEN) {
1207 + unsigned long flags;
1209 + local_irq_save(flags);
1210 + __enable_data_collection(lis);
1211 + local_irq_restore(flags);
1214 + return count;
1217 +static DEVICE_ATTR(threshold, S_IRUGO | S_IWUSR, show_threshold, set_threshold);
1219 +static ssize_t show_duration(struct device *dev, struct device_attribute *attr,
1220 + char *buf)
1222 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1224 + return sprintf(buf, "%d\n", __duration_to_ms(lis,
1225 + __ms_to_duration(lis, lis->duration)));
1228 +static ssize_t set_duration(struct device *dev, struct device_attribute *attr,
1229 + const char *buf, size_t count)
1231 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1232 + unsigned int val;
1234 + if (sscanf(buf, "%u\n", &val) != 1)
1235 + return -EINVAL;
1236 + if (val > 2550)
1237 + return -ERANGE;
1239 + lis->duration = val;
1240 + if (lis->flags & LIS302DL_F_INPUT_OPEN)
1241 + __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
1242 + __ms_to_duration(lis, lis->duration));
1244 + return count;
1247 +static DEVICE_ATTR(duration, S_IRUGO | S_IWUSR, show_duration, set_duration);
1249 +static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr,
1250 + char *buf)
1252 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1253 + int n = 0;
1254 + u8 reg[0x40];
1255 + char *end = buf;
1256 + unsigned long flags;
1258 + local_irq_save(flags);
1260 + for (n = 0; n < sizeof(reg); n++)
1261 + reg[n] = __reg_read(lis, n);
1263 + local_irq_restore(flags);
1265 + for (n = 0; n < sizeof(reg); n += 16) {
1266 + hex_dump_to_buffer(reg + n, 16, 16, 1, end, 128, 0);
1267 + end += strlen(end);
1268 + *end++ = '\n';
1269 + *end++ = '\0';
1272 + return end - buf;
1274 +static DEVICE_ATTR(dump, S_IRUGO, lis302dl_dump, NULL);
1276 +/* Configure freefall/wakeup interrupts */
1277 +static ssize_t set_wakeup_threshold(struct device *dev,
1278 + struct device_attribute *attr, const char *buf, size_t count)
1280 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1281 + unsigned int threshold;
1283 + if (sscanf(buf, "%u\n", &threshold) != 1)
1284 + return -EINVAL;
1286 + if (threshold > 8000)
1287 + return -ERANGE;
1289 + /* Zero turns the feature off */
1290 + if (threshold == 0) {
1291 + if (lis->flags & LIS302DL_F_IRQ_WAKE) {
1292 + disable_irq_wake(lis->pdata->interrupt);
1293 + lis->flags &= ~LIS302DL_F_IRQ_WAKE;
1296 + return count;
1299 + lis->wakeup.threshold = threshold;
1301 + if (!(lis->flags & LIS302DL_F_IRQ_WAKE)) {
1302 + enable_irq_wake(lis->pdata->interrupt);
1303 + lis->flags |= LIS302DL_F_IRQ_WAKE;
1306 + return count;
1309 +static ssize_t show_wakeup_threshold(struct device *dev,
1310 + struct device_attribute *attr, char *buf)
1312 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1314 + /* All events off? */
1315 + if (lis->wakeup.threshold == 0)
1316 + return sprintf(buf, "off\n");
1318 + return sprintf(buf, "%u\n", lis->wakeup.threshold);
1321 +static DEVICE_ATTR(wakeup_threshold, S_IRUGO | S_IWUSR, show_wakeup_threshold,
1322 + set_wakeup_threshold);
1324 +static ssize_t set_wakeup_duration(struct device *dev,
1325 + struct device_attribute *attr, const char *buf, size_t count)
1327 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1328 + unsigned int duration;
1330 + if (sscanf(buf, "%u\n", &duration) != 1)
1331 + return -EINVAL;
1333 + if (duration > 2550)
1334 + return -ERANGE;
1336 + lis->wakeup.duration = duration;
1338 + return count;
1341 +static ssize_t show_wakeup_duration(struct device *dev,
1342 + struct device_attribute *attr, char *buf)
1344 + struct lis302dl_info *lis = dev_get_drvdata(dev);
1346 + return sprintf(buf, "%u\n", lis->wakeup.duration);
1349 +static DEVICE_ATTR(wakeup_duration, S_IRUGO | S_IWUSR, show_wakeup_duration,
1350 + set_wakeup_duration);
1352 +static struct attribute *lis302dl_sysfs_entries[] = {
1353 + &dev_attr_sample_rate.attr,
1354 + &dev_attr_full_scale.attr,
1355 + &dev_attr_threshold.attr,
1356 + &dev_attr_duration.attr,
1357 + &dev_attr_dump.attr,
1358 + &dev_attr_wakeup_threshold.attr,
1359 + &dev_attr_wakeup_duration.attr,
1360 + &dev_attr_overruns.attr,
1361 + NULL
1364 +static struct attribute_group lis302dl_attr_group = {
1365 + .name = NULL,
1366 + .attrs = lis302dl_sysfs_entries,
1369 +/* input device handling and driver core interaction */
1371 +static int lis302dl_input_open(struct input_dev *inp)
1373 + struct lis302dl_info *lis = input_get_drvdata(inp);
1374 + unsigned long flags;
1376 + local_irq_save(flags);
1378 + __enable_data_collection(lis);
1379 + lis->flags |= LIS302DL_F_INPUT_OPEN;
1381 + local_irq_restore(flags);
1383 + return 0;
1386 +static void lis302dl_input_close(struct input_dev *inp)
1388 + struct lis302dl_info *lis = input_get_drvdata(inp);
1389 + u_int8_t ctrl1 = LIS302DL_CTRL1_Xen | LIS302DL_CTRL1_Yen |
1390 + LIS302DL_CTRL1_Zen;
1391 + unsigned long flags;
1393 + local_irq_save(flags);
1395 + /* since the input core already serializes access and makes sure we
1396 + * only see close() for the close of the last user, we can safely
1397 + * disable the data ready events */
1398 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00);
1399 + lis->flags &= ~LIS302DL_F_INPUT_OPEN;
1401 + /* however, don't power down the whole device if still needed */
1402 + if (!(lis->flags & LIS302DL_F_WUP_FF ||
1403 + lis->flags & LIS302DL_F_WUP_CLICK)) {
1404 + __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD,
1405 + 0x00);
1407 + local_irq_restore(flags);
1410 +/* get the device to reload its coefficients from EEPROM and wait for it
1411 + * to complete
1412 + */
1414 +static int __lis302dl_reset_device(struct lis302dl_info *lis)
1416 + int timeout = 10;
1418 + __reg_write(lis, LIS302DL_REG_CTRL2,
1419 + LIS302DL_CTRL2_BOOT | LIS302DL_CTRL2_FDS);
1421 + while ((__reg_read(lis, LIS302DL_REG_CTRL2)
1422 + & LIS302DL_CTRL2_BOOT) && (timeout--))
1423 + mdelay(1);
1425 + return !!(timeout < 0);
1428 +static int __devinit lis302dl_probe(struct platform_device *pdev)
1430 + int rc;
1431 + struct lis302dl_info *lis;
1432 + u_int8_t wai;
1433 + unsigned long flags;
1434 + struct lis302dl_platform_data *pdata = pdev->dev.platform_data;
1436 + lis = kzalloc(sizeof(*lis), GFP_KERNEL);
1437 + if (!lis)
1438 + return -ENOMEM;
1440 + lis->dev = &pdev->dev;
1442 + dev_set_drvdata(lis->dev, lis);
1444 + lis->pdata = pdata;
1446 + rc = sysfs_create_group(&lis->dev->kobj, &lis302dl_attr_group);
1447 + if (rc) {
1448 + dev_err(lis->dev, "error creating sysfs group\n");
1449 + goto bail_free_lis;
1452 + /* initialize input layer details */
1453 + lis->input_dev = input_allocate_device();
1454 + if (!lis->input_dev) {
1455 + dev_err(lis->dev, "Unable to allocate input device\n");
1456 + goto bail_sysfs;
1459 + input_set_drvdata(lis->input_dev, lis);
1460 + lis->input_dev->name = pdata->name;
1461 + /* SPI Bus not defined as a valid bus for input subsystem*/
1462 + lis->input_dev->id.bustype = BUS_I2C; /* lie about it */
1463 + lis->input_dev->open = lis302dl_input_open;
1464 + lis->input_dev->close = lis302dl_input_close;
1466 + rc = input_register_device(lis->input_dev);
1467 + if (rc) {
1468 + dev_err(lis->dev, "error %d registering input device\n", rc);
1469 + goto bail_inp_dev;
1472 + local_irq_save(flags);
1473 + /* Configure our IO */
1474 + (lis->pdata->lis302dl_suspend_io)(lis, 1);
1476 + wai = __reg_read(lis, LIS302DL_REG_WHO_AM_I);
1477 + if (wai != LIS302DL_WHO_AM_I_MAGIC) {
1478 + dev_err(lis->dev, "unknown who_am_i signature 0x%02x\n", wai);
1479 + dev_set_drvdata(lis->dev, NULL);
1480 + rc = -ENODEV;
1481 + local_irq_restore(flags);
1482 + goto bail_inp_reg;
1485 + set_bit(EV_ABS, lis->input_dev->evbit);
1486 + input_set_abs_params(lis->input_dev, ABS_X, 0, 0, 0, 0);
1487 + input_set_abs_params(lis->input_dev, ABS_Y, 0, 0, 0, 0);
1488 + input_set_abs_params(lis->input_dev, ABS_Z, 0, 0, 0, 0);
1491 + lis->threshold = 0;
1492 + lis->duration = 0;
1493 + memset(&lis->wakeup, 0, sizeof(lis->wakeup));
1495 + if (__lis302dl_reset_device(lis))
1496 + dev_err(lis->dev, "device BOOT reload failed\n");
1498 + /* force us powered */
1499 + __reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD |
1500 + LIS302DL_CTRL1_Xen |
1501 + LIS302DL_CTRL1_Yen |
1502 + LIS302DL_CTRL1_Zen);
1503 + mdelay(1);
1505 + __reg_write(lis, LIS302DL_REG_CTRL2, 0);
1506 + __reg_write(lis, LIS302DL_REG_CTRL3,
1507 + LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL);
1508 + __reg_write(lis, LIS302DL_REG_FF_WU_THS_1, 0x0);
1509 + __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, 0x00);
1510 + __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, 0x0);
1512 + /* start off in powered down mode; we power up when someone opens us */
1513 + __reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_Xen |
1514 + LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen);
1516 + if (pdata->open_drain)
1517 + /* switch interrupt to open collector, active-low */
1518 + __reg_write(lis, LIS302DL_REG_CTRL3,
1519 + LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL);
1520 + else
1521 + /* push-pull, active-low */
1522 + __reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL);
1524 + __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_GND);
1525 + __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_GND);
1527 + __reg_read(lis, LIS302DL_REG_STATUS);
1528 + __reg_read(lis, LIS302DL_REG_FF_WU_SRC_1);
1529 + __reg_read(lis, LIS302DL_REG_FF_WU_SRC_2);
1530 + __reg_read(lis, LIS302DL_REG_CLICK_SRC);
1531 + local_irq_restore(flags);
1533 + dev_info(lis->dev, "Found %s\n", pdata->name);
1535 + lis->pdata = pdata;
1537 + set_irq_handler(lis->pdata->interrupt, handle_level_irq);
1539 + rc = request_irq(lis->pdata->interrupt, lis302dl_interrupt,
1540 + IRQF_TRIGGER_LOW, "lis302dl", lis);
1542 + if (rc < 0) {
1543 + dev_err(lis->dev, "error requesting IRQ %d\n",
1544 + lis->pdata->interrupt);
1545 + goto bail_inp_reg;
1547 + return 0;
1549 +bail_inp_reg:
1550 + input_unregister_device(lis->input_dev);
1551 +bail_inp_dev:
1552 + input_free_device(lis->input_dev);
1553 +bail_sysfs:
1554 + sysfs_remove_group(&lis->dev->kobj, &lis302dl_attr_group);
1555 +bail_free_lis:
1556 + kfree(lis);
1557 + return rc;
1560 +static int __devexit lis302dl_remove(struct platform_device *pdev)
1562 + struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev);
1563 + unsigned long flags;
1565 + /* Disable interrupts */
1566 + if (lis->flags & LIS302DL_F_IRQ_WAKE)
1567 + disable_irq_wake(lis->pdata->interrupt);
1568 + free_irq(lis->pdata->interrupt, lis);
1570 + /* Reset and power down the device */
1571 + local_irq_save(flags);
1572 + __reg_write(lis, LIS302DL_REG_CTRL3, 0x00);
1573 + __reg_write(lis, LIS302DL_REG_CTRL2, 0x00);
1574 + __reg_write(lis, LIS302DL_REG_CTRL1, 0x00);
1575 + local_irq_restore(flags);
1577 + /* Cleanup resources */
1578 + sysfs_remove_group(&pdev->dev.kobj, &lis302dl_attr_group);
1579 + input_unregister_device(lis->input_dev);
1580 + if (lis->input_dev)
1581 + input_free_device(lis->input_dev);
1582 + dev_set_drvdata(lis->dev, NULL);
1583 + kfree(lis);
1585 + return 0;
1588 +#ifdef CONFIG_PM
1590 +static u8 regs_to_save[] = {
1591 + LIS302DL_REG_CTRL2,
1592 + LIS302DL_REG_CTRL3,
1593 + LIS302DL_REG_FF_WU_CFG_1,
1594 + LIS302DL_REG_FF_WU_THS_1,
1595 + LIS302DL_REG_FF_WU_DURATION_1,
1596 + LIS302DL_REG_FF_WU_CFG_2,
1597 + LIS302DL_REG_FF_WU_THS_2,
1598 + LIS302DL_REG_FF_WU_DURATION_2,
1599 + LIS302DL_REG_CLICK_CFG,
1600 + LIS302DL_REG_CLICK_THSY_X,
1601 + LIS302DL_REG_CLICK_THSZ,
1602 + LIS302DL_REG_CLICK_TIME_LIMIT,
1603 + LIS302DL_REG_CLICK_LATENCY,
1604 + LIS302DL_REG_CLICK_WINDOW,
1605 + LIS302DL_REG_CTRL1,
1608 +static int lis302dl_suspend(struct platform_device *pdev, pm_message_t state)
1610 + struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev);
1611 + unsigned long flags;
1612 + u_int8_t tmp;
1613 + int n;
1615 + /* determine if we want to wake up from the accel. */
1616 + if (lis->flags & LIS302DL_F_WUP_CLICK)
1617 + return 0;
1619 + disable_irq(lis->pdata->interrupt);
1620 + local_irq_save(flags);
1622 + /*
1623 + * When we share SPI over multiple sensors, there is a race here
1624 + * that one or more sensors will lose. In that case, the shared
1625 + * SPI bus GPIO will be in sleep mode and partially pulled down. So
1626 + * we explicitly put our IO into "wake" mode here before the final
1627 + * traffic to the sensor.
1628 + */
1629 + (lis->pdata->lis302dl_suspend_io)(lis, 1);
1631 + /* save registers */
1632 + for (n = 0; n < ARRAY_SIZE(regs_to_save); n++)
1633 + lis->regs[regs_to_save[n]] =
1634 + __reg_read(lis, regs_to_save[n]);
1636 + /* power down or enable wakeup */
1638 + if (lis->wakeup.threshold == 0) {
1639 + tmp = __reg_read(lis, LIS302DL_REG_CTRL1);
1640 + tmp &= ~LIS302DL_CTRL1_PD;
1641 + __reg_write(lis, LIS302DL_REG_CTRL1, tmp);
1642 + } else
1643 + __enable_wakeup(lis);
1645 + /* place our IO to the device in sleep-compatible states */
1646 + (lis->pdata->lis302dl_suspend_io)(lis, 0);
1648 + local_irq_restore(flags);
1650 + return 0;
1653 +static int lis302dl_resume(struct platform_device *pdev)
1655 + struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev);
1656 + unsigned long flags;
1657 + int n;
1659 + if (lis->flags & LIS302DL_F_WUP_CLICK)
1660 + return 0;
1662 + local_irq_save(flags);
1664 + /* get our IO to the device back in operational states */
1665 + (lis->pdata->lis302dl_suspend_io)(lis, 1);
1667 + /* resume from powerdown first! */
1668 + __reg_write(lis, LIS302DL_REG_CTRL1,
1669 + LIS302DL_CTRL1_PD |
1670 + LIS302DL_CTRL1_Xen |
1671 + LIS302DL_CTRL1_Yen |
1672 + LIS302DL_CTRL1_Zen);
1673 + mdelay(1);
1675 + if (__lis302dl_reset_device(lis))
1676 + dev_err(&pdev->dev, "device BOOT reload failed\n");
1678 + /* restore registers after resume */
1679 + for (n = 0; n < ARRAY_SIZE(regs_to_save); n++)
1680 + __reg_write(lis, regs_to_save[n], lis->regs[regs_to_save[n]]);
1682 + /* if someone had us open, reset the non-wake threshold stuff */
1683 + if (lis->flags & LIS302DL_F_INPUT_OPEN)
1684 + __enable_data_collection(lis);
1686 + local_irq_restore(flags);
1687 + enable_irq(lis->pdata->interrupt);
1689 + return 0;
1691 +#else
1692 +#define lis302dl_suspend NULL
1693 +#define lis302dl_resume NULL
1694 +#endif
1696 +static struct platform_driver lis302dl_driver = {
1697 + .driver = {
1698 + .name = "lis302dl",
1699 + .owner = THIS_MODULE,
1700 + },
1702 + .probe = lis302dl_probe,
1703 + .remove = __devexit_p(lis302dl_remove),
1704 + .suspend = lis302dl_suspend,
1705 + .resume = lis302dl_resume,
1708 +static int __devinit lis302dl_init(void)
1710 + return platform_driver_register(&lis302dl_driver);
1713 +static void __exit lis302dl_exit(void)
1715 + platform_driver_unregister(&lis302dl_driver);
1718 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
1719 +MODULE_LICENSE("GPL");
1721 +module_init(lis302dl_init);
1722 +module_exit(lis302dl_exit);
1723 diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
1724 index 8feb7f3..21c113b 100644
1725 --- a/drivers/input/touchscreen/s3c2410_ts.c
1726 +++ b/drivers/input/touchscreen/s3c2410_ts.c
1727 @@ -20,7 +20,7 @@
1728 * Copyright 2009 Simtec Electronics <linux@simtec.co.uk>
1730 * Additional work by Herbert Pötzl <herbert@13thfloor.at> and
1731 - * Harald Welte <laforge@openmoko.org>
1732 + * Harald Welte <laforge@openmoko.org> and Gennady Kupava <gb@bsdmn.com>
1735 #include <linux/errno.h>
1736 @@ -85,10 +85,19 @@ struct s3c2410ts {
1737 int count;
1738 int shift;
1739 int features;
1740 + int expectedintr; /* kind of interrupt we are waiting for */
1741 +#ifdef CONFIG_MACH_NEO1973_GTA02
1742 + void (*before_adc_hook)(void);
1743 + void (*after_adc_hook)(void);
1744 +#endif
1747 static struct s3c2410ts ts;
1749 +#define WAITFORINT_UP (0)
1750 +#define WAITFORINT_DOWN (1)
1751 +#define WAITFORINT_NOTHING (2)
1754 * get_down - return the down state of the pen
1755 * @data0: The data read from ADCDAT0 register.
1756 @@ -126,6 +135,7 @@ static void touch_timer_fire(unsigned long data)
1757 input_report_abs(ts.input, ABS_Y, ts.yp);
1759 input_report_key(ts.input, BTN_TOUCH, 1);
1760 + input_report_abs(ts.input, ABS_PRESSURE, 1);
1761 input_sync(ts.input);
1763 ts.xp = 0;
1764 @@ -133,6 +143,9 @@ static void touch_timer_fire(unsigned long data)
1765 ts.count = 0;
1768 +#ifdef CONFIG_MACH_NEO1973_GTA02
1769 + ts.before_adc_hook();
1770 +#endif
1771 s3c_adc_start(ts.client, 0, 1 << ts.shift);
1772 } else {
1773 ts.xp = 0;
1774 @@ -140,8 +153,10 @@ static void touch_timer_fire(unsigned long data)
1775 ts.count = 0;
1777 input_report_key(ts.input, BTN_TOUCH, 0);
1778 + input_report_abs(ts.input, ABS_PRESSURE, 0);
1779 input_sync(ts.input);
1782 + ts.expectedintr = WAITFORINT_DOWN;
1783 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
1786 @@ -166,13 +181,22 @@ static irqreturn_t stylus_irq(int irq, void *dev_id)
1788 down = get_down(data0, data1);
1790 - /* TODO we should never get an interrupt with down set while
1791 - * the timer is running, but maybe we ought to verify that the
1792 - * timer isn't running anyways. */
1793 + /* sitautions below can actually happen on openmoko hardware while
1794 + various debugging facilities are turned off */
1795 + if (ts.expectedintr == WAITFORINT_NOTHING)
1796 + return IRQ_HANDLED;
1797 + if (!down && ts.expectedintr == WAITFORINT_DOWN) {
1798 + writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
1799 + return IRQ_HANDLED;
1800 + } else if (down && ts.expectedintr == WAITFORINT_UP) {
1801 + writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC);
1802 + return IRQ_HANDLED;
1804 + ts.expectedintr = WAITFORINT_NOTHING;
1806 - if (down)
1807 - s3c_adc_start(ts.client, 0, 1 << ts.shift);
1808 - else
1809 + if (down) {
1810 + mod_timer(&touch_timer, jiffies + 2);
1811 + } else
1812 dev_dbg(ts.dev, "%s: count=%d\n", __func__, ts.count);
1814 if (ts.features & FEAT_PEN_IRQ) {
1815 @@ -203,6 +227,11 @@ static void s3c24xx_ts_conversion(struct s3c_adc_client *client,
1817 ts.count++;
1819 +#ifdef CONFIG_MACH_NEO1973_GTA02
1820 + if (!*left)
1821 + ts.after_adc_hook();
1822 +#endif
1824 /* From tests, it seems that it is unlikely to get a pen-up
1825 * event during the conversion process which means we can
1826 * ignore any pen-up events with less than the requisite
1827 @@ -226,7 +255,8 @@ static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select)
1828 writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
1829 ts.io + S3C2410_ADCTSC);
1830 } else {
1831 - mod_timer(&touch_timer, jiffies+1);
1832 + mod_timer(&touch_timer, jiffies + 3);
1833 + ts.expectedintr = WAITFORINT_UP;
1834 writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC);
1837 @@ -304,6 +334,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
1838 if ((info->delay & 0xffff) > 0)
1839 writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
1841 + ts.expectedintr = WAITFORINT_DOWN;
1842 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
1844 input_dev = input_allocate_device();
1845 @@ -318,6 +349,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
1846 ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
1847 input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0);
1848 input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0);
1849 + input_set_abs_params(ts.input, ABS_PRESSURE, 0, 1, 0, 0);
1851 ts.input->name = "S3C24XX TouchScreen";
1852 ts.input->id.bustype = BUS_HOST;
1853 @@ -328,6 +360,11 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
1854 ts.shift = info->oversampling_shift;
1855 ts.features = platform_get_device_id(pdev)->driver_data;
1857 +#ifdef CONFIG_MACH_NEO1973_GTA02
1858 + ts.before_adc_hook = info->before_adc_hook;
1859 + ts.after_adc_hook = info->after_adc_hook;
1860 +#endif
1862 ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
1863 "s3c2410_ts_pen", ts.input);
1864 if (ret) {
1865 @@ -382,8 +419,18 @@ static int __devexit s3c2410ts_remove(struct platform_device *pdev)
1866 #ifdef CONFIG_PM
1867 static int s3c2410ts_suspend(struct device *dev)
1869 + ts.expectedintr = WAITFORINT_NOTHING;
1870 writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC);
1871 disable_irq(ts.irq_tc);
1873 + del_timer_sync(&touch_timer);
1874 + /* TODO - need to fix races better, as timer can fire
1875 + between TSC_SLEEP and del_timer_sync() and shedule next adc */
1877 +#ifdef CONFIG_MACH_NEO1973_GTA02
1878 + ts.after_adc_hook();
1879 +#endif
1881 clk_disable(ts.clock);
1883 return 0;
1884 @@ -401,6 +448,7 @@ static int s3c2410ts_resume(struct device *dev)
1885 if ((info->delay & 0xffff) > 0)
1886 writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
1888 + ts.expectedintr = WAITFORINT_DOWN;
1889 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
1891 return 0;
1892 diff --git a/drivers/mfd/glamo-core.c b/drivers/mfd/glamo-core.c
1893 index 8880263..a0556b8 100644
1894 --- a/drivers/mfd/glamo-core.c
1895 +++ b/drivers/mfd/glamo-core.c
1896 @@ -160,6 +160,19 @@ static void reg_set_bit_mask(struct glamo_core *glamo,
1897 spin_unlock(&glamo->lock);
1902 +static void reg_checkandset_bit_mask(struct glamo_core *glamo,
1903 + uint16_t reg, uint16_t mask,
1904 + uint16_t val, uint16_t check)
1906 + spin_lock(&glamo->lock);
1907 + if (__reg_read(glamo, reg) & mask == check)
1908 + __reg_set_bit_mask(glamo, reg, mask, val);
1909 + spin_unlock(&glamo->lock);
1913 static inline void __reg_set_bit(struct glamo_core *glamo,
1914 uint16_t reg, uint16_t bit)
1916 @@ -169,6 +182,49 @@ static inline void __reg_set_bit(struct glamo_core *glamo,
1917 __reg_write(glamo, reg, tmp);
1920 +void glamo_pixclock_slow (struct glamo_core *glamo)
1923 + int x, lastx = 0;
1924 + int timeout = 1000000;
1925 + int threshold = 5;
1926 + int fa;
1928 + int evcnt = 0;
1930 + for (fa = 0; fa < timeout; fa++) {
1931 + x = glamo_reg_read(glamo, 0x1100 + GLAMO_REG_LCD_STATUS1) & 0x3ff;
1934 + if (x == lastx) {
1935 + evcnt++;
1936 + if (evcnt == threshold)
1937 + break;
1938 + } else {
1939 + evcnt = 0;
1940 + lastx = x;
1941 + }
1943 + if (fa == timeout) {
1944 + printk (KERN_WARNING "Glamo: Error waiting for stable x position.\n");
1947 + /* then, make glamo slower */
1948 + /* it's not a problems if in rare case we do not slow down glamo properly
1949 + as all we'll get in that case is singe jittered value */
1951 + glamo->slowed_divider = glamo_reg_read (glamo, 0x36) & 0xFF;
1952 + reg_set_bit_mask (glamo, 0x36, 0xFF, 0xFF);
1956 +void glamo_pixclock_fast (struct glamo_core *glamo)
1958 + reg_checkandset_bit_mask (glamo, 0x36, 0xFF, glamo->slowed_divider, 0xFF);
1960 +EXPORT_SYMBOL_GPL(glamo_pixclock_fast);
1961 +EXPORT_SYMBOL_GPL(glamo_pixclock_slow);
1963 static inline void __reg_clear_bit(struct glamo_core *glamo,
1964 uint16_t reg, uint16_t bit)
1966 @@ -930,6 +986,7 @@ static int __devinit glamo_probe(struct platform_device *pdev)
1967 glamo->irq = platform_get_irq(pdev, 0);
1968 glamo->irq_base = irq_base = platform_get_irq(pdev, 1);
1969 glamo->pdata = pdev->dev.platform_data;
1970 + glamo->slowed_divider = 0xFF;
1972 if (glamo->irq < 0) {
1973 ret = glamo->irq;
1974 @@ -965,7 +1022,7 @@ static int __devinit glamo_probe(struct platform_device *pdev)
1975 goto err_free;
1978 - glamo->base = ioremap(glamo->mem->start, resource_size(glamo->mem));
1979 + glamo->base = ioremap(glamo->mem->start, resource_size(glamo->mem)+0x1100);
1980 if (!glamo->base) {
1981 dev_err(&pdev->dev, "Failed to ioremap() memory region\n");
1982 goto err_release_mem_region;
1983 diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
1984 index f9ad427..56dd025 100644
1985 --- a/drivers/mfd/pcf50633-core.c
1986 +++ b/drivers/mfd/pcf50633-core.c
1987 @@ -376,7 +376,7 @@ static struct mfd_cell pcf50633_cells[] = {
1988 PCF50633_CELL_RESOURCES("pcf50633-mbc", pcf50633_mbc_resources),
1989 PCF50633_CELL_RESOURCES("pcf50633-adc", pcf50633_adc_resources),
1990 PCF50633_CELL("pcf50633-backlight"),
1991 - PCF50633_CELL("pcf50633-gpio"),
1992 + PCF50633_CELL("pcf50633-gpio.0"),
1993 PCF50633_CELL_ID("pcf50633-regltr", 0),
1994 PCF50633_CELL_ID("pcf50633-regltr", 1),
1995 PCF50633_CELL_ID("pcf50633-regltr", 2),
1996 diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
1997 index 4d073f1..35c3563 100644
1998 --- a/drivers/misc/Kconfig
1999 +++ b/drivers/misc/Kconfig
2000 @@ -452,6 +452,13 @@ config PCH_PHUB
2001 To compile this driver as a module, choose M here: the module will
2002 be called pch_phub.
2004 +config OPENMOKO_RESUME_REASON
2005 + tristate "Openmoko resume reason driver"
2006 + depends on SYSFS
2007 + help
2008 + This driver adds a sysfs entry for accessing the resume reason
2009 + of the openmoko board.
2011 source "drivers/misc/c2port/Kconfig"
2012 source "drivers/misc/eeprom/Kconfig"
2013 source "drivers/misc/cb710/Kconfig"
2014 diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
2015 index 98009cc..1f0e902 100644
2016 --- a/drivers/misc/Makefile
2017 +++ b/drivers/misc/Makefile
2018 @@ -42,3 +42,4 @@ obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
2019 obj-$(CONFIG_PCH_PHUB) += pch_phub.o
2020 obj-y += ti-st/
2021 obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o
2022 +obj-$(CONFIG_OPENMOKO_RESUME_REASON) += neo1973_pm_resume_reason.o
2023 diff --git a/drivers/misc/neo1973_pm_resume_reason.c b/drivers/misc/neo1973_pm_resume_reason.c
2024 new file mode 100644
2025 index 0000000..5bcc818
2026 --- /dev/null
2027 +++ b/drivers/misc/neo1973_pm_resume_reason.c
2028 @@ -0,0 +1,142 @@
2030 + * Resume reason sysfs for the FIC Neo1973 GSM Phone
2032 + * (C) 2008 by Openmoko Inc.
2033 + * Author: Andy Green <andy@openmoko.com>
2034 + * All rights reserved.
2036 + * This program is free software; you can redistribute it and/or modify
2037 + * it under the terms of the GNU General Public License resume_reason 2 as
2038 + * published by the Free Software Foundation
2040 + */
2042 +#include <linux/module.h>
2043 +#include <linux/init.h>
2044 +#include <linux/kernel.h>
2045 +#include <linux/platform_device.h>
2046 +#include <linux/io.h>
2048 +#include <mach/hardware.h>
2049 +#include <asm/mach-types.h>
2051 +#ifdef CONFIG_MACH_NEO1973_GTA02
2052 +#include <mach/gta02.h>
2053 +#include <linux/mfd/pcf50633/core.h>
2054 +#endif
2056 +static unsigned int *gstatus4_mapped;
2057 +static char *resume_reasons[][17] = { { /* GTA01 */
2058 + "EINT00_NULL",
2059 + "EINT01_GSM",
2060 + "EINT02_NULL",
2061 + "EINT03_NULL",
2062 + "EINT04_JACK",
2063 + "EINT05_SDCARD",
2064 + "EINT06_AUXKEY",
2065 + "EINT07_HOLDKEY",
2066 + "EINT08_NULL",
2067 + "EINT09_NULL",
2068 + "EINT10_NULL",
2069 + "EINT11_NULL",
2070 + "EINT12_NULL",
2071 + "EINT13_NULL",
2072 + "EINT14_NULL",
2073 + "EINT15_NULL",
2074 + NULL
2075 +}, { /* GTA02 */
2076 + "EINT00_ACCEL1",
2077 + "EINT01_GSM",
2078 + "EINT02_BLUETOOTH",
2079 + "EINT03_DEBUGBRD",
2080 + "EINT04_JACK",
2081 + "EINT05_WLAN",
2082 + "EINT06_AUXKEY",
2083 + "EINT07_HOLDKEY",
2084 + "EINT08_ACCEL2",
2085 + "EINT09_PMU",
2086 + "EINT10_NULL",
2087 + "EINT11_NULL",
2088 + "EINT12_GLAMO",
2089 + "EINT13_NULL",
2090 + "EINT14_NULL",
2091 + "EINT15_NULL",
2092 + NULL
2093 +} };
2095 +static ssize_t resume_reason_read(struct device *dev,
2096 + struct device_attribute *attr,
2097 + char *buf)
2099 + int bit = 0;
2100 + char *end = buf;
2101 + int gta = !!machine_is_neo1973_gta02();
2103 + for (bit = 0; resume_reasons[gta][bit]; bit++) {
2104 + if ((*gstatus4_mapped) & (1 << bit))
2105 + end += sprintf(end, "* %s\n", resume_reasons[gta][bit]);
2106 + else
2107 + end += sprintf(end, " %s\n", resume_reasons[gta][bit]);
2110 + return end - buf;
2114 +static DEVICE_ATTR(resume_reason, 0644, resume_reason_read, NULL);
2116 +static struct attribute *neo1973_resume_reason_sysfs_entries[] = {
2117 + &dev_attr_resume_reason.attr,
2118 + NULL
2121 +static struct attribute_group neo1973_resume_reason_attr_group = {
2122 + .name = NULL,
2123 + .attrs = neo1973_resume_reason_sysfs_entries,
2126 +static int __init neo1973_resume_reason_probe(struct platform_device *pdev)
2128 + dev_info(&pdev->dev, "starting\n");
2130 + gstatus4_mapped = ioremap(0x560000BC /* GSTATUS4 */, 0x4);
2131 + if (!gstatus4_mapped) {
2132 + dev_err(&pdev->dev, "failed to ioremap() memory region\n");
2133 + return -EINVAL;
2136 + return sysfs_create_group(&pdev->dev.kobj,
2137 + &neo1973_resume_reason_attr_group);
2140 +static int neo1973_resume_reason_remove(struct platform_device *pdev)
2142 + sysfs_remove_group(&pdev->dev.kobj, &neo1973_resume_reason_attr_group);
2143 + iounmap(gstatus4_mapped);
2144 + return 0;
2147 +static struct platform_driver neo1973_resume_reason_driver = {
2148 + .probe = neo1973_resume_reason_probe,
2149 + .remove = neo1973_resume_reason_remove,
2150 + .driver = {
2151 + .name = "neo1973-resume",
2152 + },
2155 +static int __devinit neo1973_resume_reason_init(void)
2157 + return platform_driver_register(&neo1973_resume_reason_driver);
2160 +static void neo1973_resume_reason_exit(void)
2162 + platform_driver_unregister(&neo1973_resume_reason_driver);
2165 +module_init(neo1973_resume_reason_init);
2166 +module_exit(neo1973_resume_reason_exit);
2168 +MODULE_LICENSE("GPL");
2169 +MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
2170 +MODULE_DESCRIPTION("Neo1973 resume_reason");
2171 diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
2172 index cb5d2c0..9ca6a0e 100644
2173 --- a/drivers/mtd/nand/s3c2410.c
2174 +++ b/drivers/mtd/nand/s3c2410.c
2175 @@ -55,7 +55,7 @@ static int hardware_ecc = 0;
2176 #endif
2178 #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP
2179 -static int clock_stop = 1;
2180 +static const int clock_stop = 1;
2181 #else
2182 static const int clock_stop = 0;
2183 #endif
2184 @@ -96,6 +96,12 @@ enum s3c_cpu_type {
2185 TYPE_S3C2440,
2188 +enum s3c_nand_clk_state {
2189 + CLOCK_DISABLE = 0,
2190 + CLOCK_ENABLE,
2191 + CLOCK_SUSPEND,
2194 /* overview of the s3c2410 nand state */
2197 @@ -111,6 +117,7 @@ enum s3c_cpu_type {
2198 * @mtd_count: The number of MTDs created from this controller.
2199 * @save_sel: The contents of @sel_reg to be saved over suspend.
2200 * @clk_rate: The clock rate from @clk.
2201 + * @clk_state: The current clock state.
2202 * @cpu_type: The exact type of this controller.
2204 struct s3c2410_nand_info {
2205 @@ -129,6 +136,7 @@ struct s3c2410_nand_info {
2206 int mtd_count;
2207 unsigned long save_sel;
2208 unsigned long clk_rate;
2209 + enum s3c_nand_clk_state clk_state;
2211 enum s3c_cpu_type cpu_type;
2213 @@ -159,11 +167,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev)
2214 return dev->dev.platform_data;
2217 -static inline int allow_clk_stop(struct s3c2410_nand_info *info)
2218 +static inline int allow_clk_suspend(struct s3c2410_nand_info *info)
2220 return clock_stop;
2223 +/**
2224 + * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock.
2225 + * @info: The controller instance.
2226 + * @new_state: State to which clock should be set.
2227 + */
2228 +static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info,
2229 + enum s3c_nand_clk_state new_state)
2231 + if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND)
2232 + return;
2234 + if (info->clk_state == CLOCK_ENABLE) {
2235 + if (new_state != CLOCK_ENABLE)
2236 + clk_disable(info->clk);
2237 + } else {
2238 + if (new_state == CLOCK_ENABLE)
2239 + clk_enable(info->clk);
2242 + info->clk_state = new_state;
2245 /* timing calculations */
2247 #define NS_IN_KHZ 1000000
2248 @@ -333,8 +363,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
2249 nmtd = this->priv;
2250 info = nmtd->info;
2252 - if (chip != -1 && allow_clk_stop(info))
2253 - clk_enable(info->clk);
2254 + if (chip != -1)
2255 + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE);
2257 cur = readl(info->sel_reg);
2259 @@ -356,8 +386,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
2261 writel(cur, info->sel_reg);
2263 - if (chip == -1 && allow_clk_stop(info))
2264 - clk_disable(info->clk);
2265 + if (chip == -1)
2266 + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND);
2269 /* s3c2410_nand_hwcontrol
2270 @@ -694,8 +724,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev)
2271 /* free the common resources */
2273 if (info->clk != NULL && !IS_ERR(info->clk)) {
2274 - if (!allow_clk_stop(info))
2275 - clk_disable(info->clk);
2276 + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
2277 clk_put(info->clk);
2280 @@ -773,6 +802,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
2281 chip->priv = nmtd;
2282 chip->options = set->options;
2283 chip->controller = &info->controller;
2284 + chip->badblockbits = 8;
2286 switch (info->cpu_type) {
2287 case TYPE_S3C2410:
2288 @@ -947,7 +977,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
2289 goto exit_error;
2292 - clk_enable(info->clk);
2293 + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE);
2295 /* allocate and map the resource */
2297 @@ -1026,9 +1056,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
2298 goto exit_error;
2301 - if (allow_clk_stop(info)) {
2302 + if (allow_clk_suspend(info)) {
2303 dev_info(&pdev->dev, "clock idle support enabled\n");
2304 - clk_disable(info->clk);
2305 + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND);
2308 pr_debug("initialised ok\n");
2309 @@ -1059,8 +1089,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm)
2311 writel(info->save_sel | info->sel_bit, info->sel_reg);
2313 - if (!allow_clk_stop(info))
2314 - clk_disable(info->clk);
2315 + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
2318 return 0;
2319 @@ -1072,7 +1101,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev)
2320 unsigned long sel;
2322 if (info) {
2323 - clk_enable(info->clk);
2324 + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE);
2325 s3c2410_nand_inithw(info);
2327 /* Restore the state of the nFCE line. */
2328 @@ -1082,8 +1111,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev)
2329 sel |= info->save_sel & info->sel_bit;
2330 writel(sel, info->sel_reg);
2332 - if (allow_clk_stop(info))
2333 - clk_disable(info->clk);
2334 + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND);
2337 return 0;
2338 diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
2339 index cd1f907..605514a 100644
2340 --- a/drivers/power/power_supply_sysfs.c
2341 +++ b/drivers/power/power_supply_sysfs.c
2342 @@ -270,7 +270,7 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
2343 attr = &power_supply_attrs[psy->properties[j]];
2345 ret = power_supply_show_property(dev, attr, prop_buf);
2346 - if (ret == -ENODEV) {
2347 + if (ret == -ENODEV || ret == -ENODATA) {
2348 /* When a battery is absent, we expect -ENODEV. Don't abort;
2349 send the uevent with at least the the PRESENT=0 property */
2350 ret = 0;
2351 diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
2352 index ac1f0b0..3a1fdb7 100644
2353 --- a/drivers/serial/samsung.c
2354 +++ b/drivers/serial/samsung.c
2355 @@ -883,7 +883,7 @@ static struct uart_ops s3c24xx_serial_ops = {
2357 static struct uart_driver s3c24xx_uart_drv = {
2358 .owner = THIS_MODULE,
2359 - .dev_name = "s3c2410_serial",
2360 + .dev_name = S3C24XX_SERIAL_NAME,
2361 .nr = CONFIG_SERIAL_SAMSUNG_UARTS,
2362 .cons = S3C24XX_SERIAL_CONSOLE,
2363 .driver_name = S3C24XX_SERIAL_NAME,
2364 diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
2365 index a68af2d..02bd7b0 100644
2366 --- a/drivers/usb/host/ohci-s3c2410.c
2367 +++ b/drivers/usb/host/ohci-s3c2410.c
2368 @@ -22,6 +22,10 @@
2369 #include <linux/platform_device.h>
2370 #include <linux/clk.h>
2371 #include <plat/usb-control.h>
2372 +#include <mach/hardware.h>
2373 +#include <mach/gpio-fns.h>
2374 +#include <mach/regs-gpio.h>
2375 +#include <mach/gta02.h>
2377 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
2379 @@ -306,6 +310,42 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
2380 local_irq_restore(flags);
2383 +/* switching of USB pads */
2384 +static ssize_t show_usb_mode(struct device *dev, struct device_attribute *attr,
2385 + char *buf)
2387 + if (__raw_readl(S3C24XX_MISCCR) & S3C2410_MISCCR_USBHOST)
2388 + return sprintf(buf, "host\n");
2390 + return sprintf(buf, "device\n");
2393 +static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr,
2394 + const char *buf, size_t count)
2396 + if (!strncmp(buf, "host", 4)) {
2397 + printk("s3c2410: changing usb to host\n");
2398 + s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST,
2399 + S3C2410_MISCCR_USBHOST);
2400 + /* FIXME:
2401 + * - call machine-specific disable-pullup function i
2402 + * - enable +Vbus (if hardware supports it)
2403 + */
2404 + s3c2410_gpio_setpin(GTA02_GPIO_USB_PULLUP, 0);
2405 + } else if (!strncmp(buf, "device", 6)) {
2406 + printk("s3c2410: changing usb to device\n");
2407 + s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, 0);
2408 + s3c2410_gpio_setpin(GTA02_GPIO_USB_PULLUP, 1);
2409 + } else {
2410 + printk("s3c2410: unknown mode\n");
2411 + return -EINVAL;
2414 + return count;
2417 +static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode);
2419 /* may be called without controller electrically present */
2420 /* may be called with controller, bus, and devices active */
2422 @@ -323,6 +363,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
2423 static void
2424 usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev)
2426 + device_remove_file(&dev->dev, &dev_attr_usb_mode);
2427 usb_remove_hcd(hcd);
2428 s3c2410_stop_hc(dev);
2429 iounmap(hcd->regs);
2430 @@ -390,8 +431,15 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
2431 if (retval != 0)
2432 goto err_ioremap;
2434 + retval = device_create_file(&dev->dev, &dev_attr_usb_mode);
2435 + if (retval != 0)
2436 + goto err_hcd;
2438 return 0;
2440 + err_hcd:
2441 + usb_remove_hcd(hcd);
2443 err_ioremap:
2444 s3c2410_stop_hc(dev);
2445 iounmap(hcd->regs);
2446 diff --git a/drivers/video/glamo-fb.c b/drivers/video/glamo-fb.c
2447 index 3f8ec8d..a428047 100644
2448 --- a/drivers/video/glamo-fb.c
2449 +++ b/drivers/video/glamo-fb.c
2450 @@ -312,7 +312,7 @@ static int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
2451 glamofb_reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
2452 GLAMO_LCD_CMD_TYPE_DISP |
2453 GLAMO_LCD_CMD_DATA_DISP_SYNC);
2455 + mdelay(1);
2456 glamofb_reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
2457 GLAMO_LCD_CMD_TYPE_DISP |
2458 GLAMO_LCD_CMD_DATA_DISP_FIRE);
2459 diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
2460 new file mode 100644
2461 index 0000000..01c4ac9
2462 --- /dev/null
2463 +++ b/include/linux/lis302dl.h
2464 @@ -0,0 +1,155 @@
2465 +#ifndef _LINUX_LIS302DL_H
2466 +#define _LINUX_LIS302DL_H
2468 +#include <linux/types.h>
2469 +#include <linux/spi/spi.h>
2470 +#include <linux/input.h>
2473 +struct lis302dl_info;
2475 +struct lis302dl_platform_data {
2476 + char *name;
2477 + unsigned long pin_chip_select;
2478 + unsigned long pin_clk;
2479 + unsigned long pin_mosi;
2480 + unsigned long pin_miso;
2481 + int open_drain;
2482 + int interrupt;
2483 + void (*lis302dl_bitbang)(struct lis302dl_info *lis, u8 *tx,
2484 + int tx_bytes, u8 *rx, int rx_bytes);
2485 + void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming);
2486 + int (*lis302dl_bitbang_reg_read)(struct lis302dl_info *, u8 reg);
2487 + void (*lis302dl_bitbang_reg_write)(struct lis302dl_info *, u8 reg,
2488 + u8 val);
2491 +struct lis302dl_info {
2492 + struct lis302dl_platform_data *pdata;
2493 + struct device *dev;
2494 + struct input_dev *input_dev;
2495 + unsigned int flags;
2496 + unsigned int threshold;
2497 + unsigned int duration;
2498 + u32 overruns;
2499 + struct {
2500 + unsigned int threshold; /* mg */
2501 + unsigned int duration; /* ms */
2502 + } wakeup;
2503 + u_int8_t regs[0x40];
2506 +enum lis302dl_reg {
2507 + LIS302DL_REG_WHO_AM_I = 0x0f,
2508 + LIS302DL_REG_CTRL1 = 0x20,
2509 + LIS302DL_REG_CTRL2 = 0x21,
2510 + LIS302DL_REG_CTRL3 = 0x22,
2511 + LIS302DL_REG_HP_FILTER_RESET = 0x23,
2512 + LIS302DL_REG_STATUS = 0x27,
2513 + LIS302DL_REG_OUT_X = 0x29,
2514 + LIS302DL_REG_OUT_Y = 0x2b,
2515 + LIS302DL_REG_OUT_Z = 0x2d,
2516 + LIS302DL_REG_FF_WU_CFG_1 = 0x30,
2517 + LIS302DL_REG_FF_WU_SRC_1 = 0x31,
2518 + LIS302DL_REG_FF_WU_THS_1 = 0x32,
2519 + LIS302DL_REG_FF_WU_DURATION_1 = 0x33,
2520 + LIS302DL_REG_FF_WU_CFG_2 = 0x34,
2521 + LIS302DL_REG_FF_WU_SRC_2 = 0x35,
2522 + LIS302DL_REG_FF_WU_THS_2 = 0x36,
2523 + LIS302DL_REG_FF_WU_DURATION_2 = 0x37,
2524 + LIS302DL_REG_CLICK_CFG = 0x38,
2525 + LIS302DL_REG_CLICK_SRC = 0x39,
2526 + LIS302DL_REG_CLICK_THSY_X = 0x3b,
2527 + LIS302DL_REG_CLICK_THSZ = 0x3c,
2528 + LIS302DL_REG_CLICK_TIME_LIMIT = 0x3d,
2529 + LIS302DL_REG_CLICK_LATENCY = 0x3e,
2530 + LIS302DL_REG_CLICK_WINDOW = 0x3f,
2533 +enum lis302dl_reg_ctrl1 {
2534 + LIS302DL_CTRL1_Xen = 0x01,
2535 + LIS302DL_CTRL1_Yen = 0x02,
2536 + LIS302DL_CTRL1_Zen = 0x04,
2537 + LIS302DL_CTRL1_STM = 0x08,
2538 + LIS302DL_CTRL1_STP = 0x10,
2539 + LIS302DL_CTRL1_FS = 0x20,
2540 + LIS302DL_CTRL1_PD = 0x40,
2541 + LIS302DL_CTRL1_DR = 0x80,
2544 +enum lis302dl_reg_ctrl2 {
2545 + LIS302DL_CTRL2_HPC1 = 0x01,
2546 + LIS302DL_CTRL2_HPC2 = 0x02,
2547 + LIS302DL_CTRL2_HPFF1 = 0x04,
2548 + LIS302DL_CTRL2_HPFF2 = 0x08,
2549 + LIS302DL_CTRL2_FDS = 0x10,
2550 + LIS302DL_CTRL2_BOOT = 0x40,
2551 + LIS302DL_CTRL2_SIM = 0x80,
2553 +enum lis302dl_reg_ctrl3 {
2554 + LIS302DL_CTRL3_PP_OD = 0x40,
2555 + LIS302DL_CTRL3_IHL = 0x80,
2558 +enum lis302dl_reg_status {
2559 + LIS302DL_STATUS_XDA = 0x01,
2560 + LIS302DL_STATUS_YDA = 0x02,
2561 + LIS302DL_STATUS_ZDA = 0x04,
2562 + LIS302DL_STATUS_XYZDA = 0x08,
2563 + LIS302DL_STATUS_XOR = 0x10,
2564 + LIS302DL_STATUS_YOR = 0x20,
2565 + LIS302DL_STATUS_ZOR = 0x40,
2566 + LIS302DL_STATUS_XYZOR = 0x80,
2569 +/* Wakeup/freefall interrupt defs */
2570 +enum lis302dl_reg_ffwucfg {
2571 + LIS302DL_FFWUCFG_XLIE = 0x01,
2572 + LIS302DL_FFWUCFG_XHIE = 0x02,
2573 + LIS302DL_FFWUCFG_YLIE = 0x04,
2574 + LIS302DL_FFWUCFG_YHIE = 0x08,
2575 + LIS302DL_FFWUCFG_ZLIE = 0x10,
2576 + LIS302DL_FFWUCFG_ZHIE = 0x20,
2577 + LIS302DL_FFWUCFG_LIR = 0x40,
2578 + LIS302DL_FFWUCFG_AOI = 0x80,
2581 +enum lis302dl_reg_ffwuths {
2582 + LIS302DL_FFWUTHS_DCRM = 0x80,
2585 +enum lis302dl_reg_ffwusrc {
2586 + LIS302DL_FFWUSRC_XL = 0x01,
2587 + LIS302DL_FFWUSRC_XH = 0x02,
2588 + LIS302DL_FFWUSRC_YL = 0x04,
2589 + LIS302DL_FFWUSRC_YH = 0x08,
2590 + LIS302DL_FFWUSRC_ZL = 0x10,
2591 + LIS302DL_FFWUSRC_ZH = 0x20,
2592 + LIS302DL_FFWUSRC_IA = 0x40,
2595 +enum lis302dl_reg_cloik_src {
2596 + LIS302DL_CLICKSRC_SINGLE_X = 0x01,
2597 + LIS302DL_CLICKSRC_DOUBLE_X = 0x02,
2598 + LIS302DL_CLICKSRC_SINGLE_Y = 0x04,
2599 + LIS302DL_CLICKSRC_DOUBLE_Y = 0x08,
2600 + LIS302DL_CLICKSRC_SINGLE_Z = 0x10,
2601 + LIS302DL_CLICKSRC_DOUBLE_Z = 0x20,
2602 + LIS302DL_CLICKSRC_IA = 0x40,
2605 +#define LIS302DL_WHO_AM_I_MAGIC 0x3b
2607 +#define LIS302DL_F_WUP_FF_1 0x0001 /* wake up from free fall */
2608 +#define LIS302DL_F_WUP_FF_2 0x0002
2609 +#define LIS302DL_F_WUP_FF 0x0003
2610 +#define LIS302DL_F_WUP_CLICK 0x0004
2611 +#define LIS302DL_F_POWER 0x0010
2612 +#define LIS302DL_F_FS 0x0020 /* ADC full scale */
2613 +#define LIS302DL_F_INPUT_OPEN 0x0040 /* Set if input device is opened */
2614 +#define LIS302DL_F_IRQ_WAKE 0x0080 /* IRQ is setup in wake mode */
2615 +#define LIS302DL_F_DR 0x0100 /* Data rate, 400Hz/100Hz */
2618 +#endif /* _LINUX_LIS302DL_H */
2620 diff --git a/include/linux/mfd/glamo-core.h b/include/linux/mfd/glamo-core.h
2621 index 8275a2f..8e3e56e 100644
2622 --- a/include/linux/mfd/glamo-core.h
2623 +++ b/include/linux/mfd/glamo-core.h
2624 @@ -37,6 +37,7 @@ struct glamo_core {
2625 enum glamo_engine_state engine_state[__NUM_GLAMO_ENGINES];
2626 spinlock_t lock;
2627 uint16_t saved_irq_mask;
2628 + int slowed_divider;
2629 #ifdef CONFIG_DEBUG_FS
2630 struct dentry *debugfs_dir;
2631 #endif
2632 @@ -55,4 +56,6 @@ int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine);
2633 void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine);
2634 int glamo_engine_reclock(struct glamo_core *glamo,
2635 enum glamo_engine engine, int ps);
2636 +void glamo_pixclock_slow (struct glamo_core *glamo);
2637 +void glamo_pixclock_fast (struct glamo_core *glamo);
2638 #endif /* __GLAMO_CORE_H */
2639 diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
2640 index 28ee2e6..85b8a45 100644
2641 --- a/sound/soc/codecs/wm8753.c
2642 +++ b/sound/soc/codecs/wm8753.c
2643 @@ -190,6 +190,9 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
2644 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
2645 u16 ioctl;
2647 + if (wm8753->dai_func == ucontrol->value.integer.value[0])
2648 + return 1;
2650 if (codec->active)
2651 return -EBUSY;
2653 @@ -680,7 +683,9 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
2654 Nmod = target % source;
2655 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
2657 - do_div(Kpart, source);
2658 + // with this, gcc-4.4.2 emits the reference to uldivmod, but then optimizes it out
2659 + //do_div(Kpart, source);
2660 + __do_div_asm(Kpart, source);
2662 K = Kpart & 0xFFFFFFFF;
2664 diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
2665 index dc5893d4..37835ca 100644
2666 --- a/sound/soc/s3c24xx/neo1973_wm8753.c
2667 +++ b/sound/soc/s3c24xx/neo1973_wm8753.c
2668 @@ -23,6 +23,7 @@
2669 #include <sound/pcm.h>
2670 #include <sound/soc.h>
2671 #include <sound/soc-dapm.h>
2672 +#include <sound/jack.h>
2673 #include <sound/tlv.h>
2675 #include <asm/mach-types.h>
2676 @@ -252,6 +253,8 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
2678 /* GTA01 specific controlls */
2680 +static struct snd_soc_jack hs_jack;
2682 #ifdef CONFIG_MACH_NEO1973_GTA01
2684 static const struct snd_soc_dapm_widget wm8753_dapm_widgets_gta01[] = {
2685 @@ -318,6 +321,29 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {};
2686 static const struct snd_soc_dapm_widget wm8753_dapm_widgets_gta02[] = {};
2687 #endif
2689 +static struct snd_soc_jack_pin hs_jack_pins[] = {
2691 + .pin = "Headset Mic",
2692 + .mask = SND_JACK_MICROPHONE,
2693 + },
2695 + .pin = "Stereo Out",
2696 + .mask = SND_JACK_HEADPHONE,
2697 + .invert = 1,
2698 + },
2701 +static struct snd_soc_jack_gpio hs_jack_gpios[] = {
2703 + .gpio = GTA02_GPIO_JACK_INSERT,
2704 + .name = "headset-gpio",
2705 + .report = SND_JACK_HEADSET,
2706 + .debounce_time = 100,
2707 + },
2712 static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
2714 struct snd_soc_codec *codec = rtd->codec;
2715 @@ -397,6 +423,24 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
2717 snd_soc_dapm_sync(codec);
2719 + err = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack);
2720 + if (err) {
2721 + dev_err(codec->card->dev, "failed to alloc headset jack\n");
2722 + return err;
2725 + err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins);
2726 + if (err) {
2727 + dev_err(codec->card->dev, "failed to add headset jack pins\n");
2728 + return err;
2731 + err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios);
2732 + if (err) {
2733 + dev_err(codec->card->dev, "failed to add headset jack gpios\n");
2734 + return err;
2737 return 0;
2740 @@ -551,6 +595,7 @@ static inline void neo1973_gta02_exit(void) {}
2741 static void __exit neo1973_exit(void)
2743 snd_soc_unregister_dais(&neo1973_snd_device->dev, 1);
2744 + snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios);
2745 platform_device_unregister(neo1973_snd_device);
2747 if (machine_is_neo1973_gta02())