diff options
author | Martin Jansa <Martin.Jansa@gmail.com> | 2011-01-06 09:49:04 +0100 |
---|---|---|
committer | Martin Jansa <Martin.Jansa@gmail.com> | 2011-01-10 16:22:15 +0100 |
commit | 6a8e0ff1792d66d9c17b566af3644620a138467a (patch) | |
tree | 025a334717afb961dfcc766dd3b8cba613a5cb8f /recipes/linux/linux-2.6.37/shr.patch | |
parent | 8beda7610877824086447f176b8e2b1bd8f21cad (diff) | |
download | openembedded-6a8e0ff1792d66d9c17b566af3644620a138467a.tar.gz |
linux-2.6.37: update openmoko and shr patch, add support for om-gta01
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Diffstat (limited to 'recipes/linux/linux-2.6.37/shr.patch')
-rw-r--r-- | recipes/linux/linux-2.6.37/shr.patch | 1200 |
1 files changed, 1189 insertions, 11 deletions
diff --git a/recipes/linux/linux-2.6.37/shr.patch b/recipes/linux/linux-2.6.37/shr.patch index 7400d31d2e..bcca6efc49 100644 --- a/recipes/linux/linux-2.6.37/shr.patch +++ b/recipes/linux/linux-2.6.37/shr.patch @@ -1,13 +1,1110 @@ -From ba03d027f8a6ae3eb6d6805a2d27fce422e7adad Mon Sep 17 00:00:00 2001 -From: Martin Jansa <Martin.Jansa@gmail.com> -Date: Sat, 7 Nov 2009 20:33:06 +0100 -Subject: [PATCH] wm8753: fix build with gcc-4.4.2, which works ok with 4.1.2 +All patches from shr kernel repository +rebased on top of openmoko kernel repository -Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com> ---- - sound/soc/codecs/wm8753.c | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) +http://gitorious.org/~jama/htc-msm-2-6-32/openmoko-kernel/commits/shr-2.6.37 +ccd549e Use 100 as HZ value on S3C24XX +7afc3f0 wm8753: use snd_soc_jack on neo1973 +4941630 Force GPS power up on resume if it were powered up on suspend +ef4b55b s3c2410_ts: jitter less touchscreen for glamo, version 4 +dc7bd23 Openmoko resume reason sysfs node ported from 2.6.29 +40e1523 Rename /dev/s3c2410_serialXXX to /dev/ttySACXXX +41fb019 glamo-display: fix WSOD for 242 timming +2d81aa9 Enable powering off after 8s POWER press +743f76b Fix high power consumption in suspend +3adb6be tslib relies on ts pressures events so this hack is needed to get tslib stuff working +dcd1e55 ar6000_delay.patch +f00d735 usbhost.patch +4633ec7 touchscreen: ignore unexpected interrupts +1b95598 wm8753: fix build with gcc-4.4.2, which works ok with 4.1.2 + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index d56d21c..fea7f49 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1302,7 +1302,7 @@ source kernel/Kconfig.preempt + + config HZ + int +- default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \ ++ default 200 if ARCH_EBSA110 || ARCH_S5P64X0 || \ + ARCH_S5P6442 || ARCH_S5PV210 || ARCH_S5PV310 + default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER + default AT91_TIMER_HZ if ARCH_AT91 +diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile +index 035d116..16d9855 100644 +--- a/arch/arm/mach-s3c2440/Makefile ++++ b/arch/arm/mach-s3c2440/Makefile +@@ -38,6 +38,7 @@ obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o \ + gta02-pm-bt.o \ + gta02-pm-gps.o \ + gta02-pm-gsm.o \ ++ gta02-pm-usbhost.o \ + gta02-pm-wlan.o \ + gta02-fiq.o \ + gta02-hdq.o \ +diff --git a/arch/arm/mach-s3c2440/gta02-pm-gps.c b/arch/arm/mach-s3c2440/gta02-pm-gps.c +index 5f57eb4..092f5a0 100644 +--- a/arch/arm/mach-s3c2440/gta02-pm-gps.c ++++ b/arch/arm/mach-s3c2440/gta02-pm-gps.c +@@ -42,7 +42,7 @@ int gta02_pm_gps_is_on(void) + EXPORT_SYMBOL_GPL(gta02_pm_gps_is_on); + + /* This is the POWERON pin */ +-static void gps_pwron_set(int on) ++static void gps_pwron_set(int on, int ignore_state) + { + if (on) { + /* return UART pins to being UART pins */ +@@ -50,7 +50,7 @@ static void gps_pwron_set(int on) + /* remove pulldown now it won't be floating any more */ + s3c_gpio_setpull(S3C2410_GPH(5), S3C_GPIO_PULL_NONE); + +- if (!gta02_gps.power_was_on) ++ if (!gta02_gps.power_was_on || ignore_state) + regulator_enable(gta02_gps.regulator); + } else { + /* +@@ -61,7 +61,7 @@ static void gps_pwron_set(int on) + gpio_set_value(S3C2410_GPH(4), 0); + /* don't let RX from unpowered GPS float */ + s3c_gpio_setpull(S3C2410_GPH(5), S3C_GPIO_PULL_DOWN); +- if (gta02_gps.power_was_on) ++ if (gta02_gps.power_was_on || ignore_state) + regulator_disable(gta02_gps.regulator); + } + } +@@ -108,7 +108,7 @@ static ssize_t power_gps_write(struct device *dev, + unsigned long on = simple_strtoul(buf, NULL, 10); + + if (!strcmp(attr->attr.name, "power_on")) { +- gps_pwron_set(on); ++ gps_pwron_set(on, 0); + gta02_gps.power_was_on = !!on; + #ifdef CONFIG_PM + } else if (!strcmp(attr->attr.name, "keep_on_in_suspend")) { +@@ -123,7 +123,7 @@ static int gta02_pm_gps_suspend(struct device *dev) + { + if (!gta02_gps.keep_on_in_suspend || + !gta02_gps.power_was_on) +- gps_pwron_set(0); ++ gps_pwron_set(0, 0); + else + dev_warn(dev, "GTA02: keeping gps ON " + "during suspend\n"); +@@ -133,7 +133,7 @@ static int gta02_pm_gps_suspend(struct device *dev) + static int gta02_pm_gps_resume(struct device *dev) + { + if (!gta02_gps.keep_on_in_suspend && gta02_gps.power_was_on) +- gps_pwron_set(1); ++ gps_pwron_set(1, 1); + + return 0; + } +diff --git a/arch/arm/mach-s3c2440/gta02-pm-usbhost.c b/arch/arm/mach-s3c2440/gta02-pm-usbhost.c +new file mode 100644 +index 0000000..233340a +--- /dev/null ++++ b/arch/arm/mach-s3c2440/gta02-pm-usbhost.c +@@ -0,0 +1,174 @@ ++/* ++ * USBHOST Management code for the Openmoko Freerunner GSM Phone ++ * ++ * (C) 2007 by Openmoko Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <linux/console.h> ++#include <linux/errno.h> ++#include <linux/interrupt.h> ++#include <linux/delay.h> ++#include <linux/err.h> ++#include <linux/regulator/consumer.h> ++ ++#include <mach/gpio.h> ++#include <asm/mach-types.h> ++ ++#include <mach/hardware.h> ++ ++#include <mach/gta02.h> ++#include <mach/regs-gpio.h> ++#include <mach/regs-gpioj.h> ++ ++static struct regulator *gta02_usbhost_regulator; ++ ++static ssize_t usbhost_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ if (!strcmp(attr->attr.name, "power_on")) { ++ if (regulator_is_enabled(gta02_usbhost_regulator)) ++ goto out_1; ++ } ++ ++ return strlcpy(buf, "0\n", 3); ++out_1: ++ return strlcpy(buf, "1\n", 3); ++} ++ ++static void usbhost_on_off(struct device *dev, int on) ++{ ++ ++ on = !!on; ++ ++ if (on == regulator_is_enabled(gta02_usbhost_regulator)) ++ return; ++ ++ if (!on) { ++ regulator_disable(gta02_usbhost_regulator); ++ return; ++ } ++ ++ regulator_enable(gta02_usbhost_regulator); ++} ++ ++static ssize_t usbhost_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long on = simple_strtoul(buf, NULL, 10); ++ ++ if (!strcmp(attr->attr.name, "power_on")) { ++ usbhost_on_off(dev, on); ++ ++ return count; ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(power_on, 0644, usbhost_read, usbhost_write); ++ ++#ifdef CONFIG_PM ++ ++static int gta02_usbhost_suspend(struct device *dev) ++{ ++ return 0; ++} ++ ++static int gta02_usbhost_suspend_late(struct device *dev) ++{ ++ return 0; ++} ++ ++static int gta02_usbhost_resume(struct device *dev) ++{ ++ return 0; ++} ++ ++static struct dev_pm_ops gta02_usbhost_pm_ops = { ++ .suspend = gta02_usbhost_suspend, ++ .suspend_noirq = gta02_usbhost_suspend_late, ++ .resume = gta02_usbhost_resume, ++}; ++ ++#define GTA02_USBHOST_PM_OPS (>a02_usbhost_pm_ops) ++ ++#else ++#define GTA02_USBHOST_PM_OPS NULL ++#endif /* CONFIG_PM */ ++ ++static struct attribute *gta02_usbhost_sysfs_entries[] = { ++ &dev_attr_power_on.attr, ++ NULL ++}; ++ ++static struct attribute_group gta02_usbhost_attr_group = { ++ .name = NULL, ++ .attrs = gta02_usbhost_sysfs_entries, ++}; ++ ++static int __init gta02_usbhost_probe(struct platform_device *pdev) ++{ ++ int ret; ++ ++ gta02_usbhost_regulator = regulator_get_exclusive(&pdev->dev, "USBHOST"); ++ ++ if (IS_ERR(gta02_usbhost_regulator)) { ++ ret = PTR_ERR(gta02_usbhost_regulator); ++ dev_err(&pdev->dev, "Failed to get regulator: %d\n", ret); ++ return ret; ++ } ++ ++ ret = sysfs_create_group(&pdev->dev.kobj, >a02_usbhost_attr_group); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to create sysfs entries: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int gta02_usbhost_remove(struct platform_device *pdev) ++{ ++ usbhost_on_off(&pdev->dev, 0); ++ ++ sysfs_remove_group(&pdev->dev.kobj, >a02_usbhost_attr_group); ++ regulator_put(gta02_usbhost_regulator); ++ ++ return 0; ++} ++ ++static struct platform_driver gta02_usbhost_driver = { ++ .probe = gta02_usbhost_probe, ++ .remove = gta02_usbhost_remove, ++ .driver = { ++ .name = "gta02-pm-usbhost", ++ .pm = GTA02_USBHOST_PM_OPS, ++ }, ++}; ++ ++static int __devinit gta02_usbhost_init(void) ++{ ++ return platform_driver_register(>a02_usbhost_driver); ++} ++module_init(gta02_usbhost_init); ++ ++static void gta02_usbhost_exit(void) ++{ ++ platform_driver_unregister(>a02_usbhost_driver); ++} ++module_exit(gta02_usbhost_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("Openmoko Freerunner USBHOST Power Management"); +diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c +index 450f1f2..b4b60aa 100644 +--- a/arch/arm/mach-s3c2440/mach-gta02.c ++++ b/arch/arm/mach-s3c2440/mach-gta02.c +@@ -109,6 +109,7 @@ + #include <linux/jbt6k74.h> + #include <linux/glamofb.h> + #include <linux/mfd/glamo.h> ++#include <linux/mfd/glamo-core.h> + + static struct pcf50633 *gta02_pcf; + +@@ -127,6 +128,10 @@ static long gta02_panic_blink(int state) + return delay; + } + ++struct platform_device gta02_resume_reason_device = { ++ .name = "neo1973-resume", ++ .num_resources = 0, ++}; + + static struct map_desc gta02_iodesc[] __initdata = { + { +@@ -177,6 +182,10 @@ static struct platform_device gta02_pm_gsm_dev = { + .name = "gta02-pm-gsm", + }; + ++static struct platform_device gta02_pm_usbhost_dev = { ++ .name = "gta02-pm-usbhost", ++}; ++ + static struct platform_device gta02_pm_wlan_dev = { + .name = "gta02-pm-wlan", + }; +@@ -186,6 +195,11 @@ static struct regulator_consumer_supply gsm_supply_consumer = { + .supply = "GSM", + }; + ++static struct regulator_consumer_supply usbhost_supply_consumer = { ++ .dev = >a02_pm_usbhost_dev.dev, ++ .supply = "USBHOST", ++}; ++ + static struct regulator_init_data gsm_supply_init_data = { + .constraints = { + .min_uV = 3700000, +@@ -197,6 +211,17 @@ static struct regulator_init_data gsm_supply_init_data = { + .consumer_supplies = &gsm_supply_consumer, + }; + ++static struct regulator_init_data usbhost_supply_init_data = { ++ .constraints = { ++ .min_uV = 3700000, ++ .max_uV = 3700000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .valid_ops_mask = REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = &usbhost_supply_consumer, ++}; ++ + static struct fixed_voltage_config gsm_supply_config = { + .supply_name = "GSM", + .microvolts = 3700000, +@@ -205,6 +230,14 @@ static struct fixed_voltage_config gsm_supply_config = { + .init_data = &gsm_supply_init_data, + }; + ++static struct fixed_voltage_config usbhost_supply_config = { ++ .supply_name = "USBHOST", ++ .microvolts = 3700000, ++ .gpio = GTA02_GPIO_PCF(PCF50633_GPO), ++ .enable_high = 1, ++ .init_data = &usbhost_supply_init_data, ++}; ++ + static struct platform_device gta02_gsm_supply_device = { + .name = "reg-fixed-voltage", + .id = 1, +@@ -213,6 +246,14 @@ static struct platform_device gta02_gsm_supply_device = { + }, + }; + ++static struct platform_device gta02_usbhost_supply_device = { ++ .name = "reg-fixed-voltage", ++ .id = 2, ++ .dev = { ++ .platform_data = &usbhost_supply_config, ++ }, ++}; ++ + /* + * we crank down SD Card clock dynamically when GPS is powered + */ +@@ -498,6 +539,11 @@ static struct regulator_consumer_supply hcldo_consumers[] = { + }, + }; + ++static void gta02_poweroff(void) ++{ ++ pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1); ++} ++ + struct pcf50633_platform_data gta02_pcf_pdata = { + .resumers = { + [0] = PCF50633_INT1_USBINS | +@@ -534,7 +580,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = { + .min_uV = 1300000, + .max_uV = 1600000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, +- .always_on = 1, ++ .always_on = 0, + .apply_uV = 1, + }, + }, +@@ -626,6 +672,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = { + }, + .probe_done = gta02_pmu_attach_child_devices, + .mbc_event_callback = gta02_pmu_event_callback, ++ .force_shutdown = gta02_poweroff, + }; + + +@@ -728,11 +775,31 @@ static struct s3c2410_hcd_info gta02_usb_info __initdata = { + }, + }; + ++static int glamo_slowed = 0; ++ ++static void gta02_ts_hook_before_adc () ++{ ++ if (!glamo_slowed) { ++ glamo_slowed = 1; ++ glamo_pixclock_slow(dev_get_drvdata (>a02_glamo_dev.dev)); ++ } ++}; ++ ++static void gta02_ts_hook_after_adc () ++{ ++ if (glamo_slowed) { ++ glamo_slowed = 0; ++ glamo_pixclock_fast(dev_get_drvdata (>a02_glamo_dev.dev)); ++ } ++}; ++ + /* Touchscreen */ + static struct s3c2410_ts_mach_info gta02_ts_info = { +- .delay = 10000, ++ .delay = 1000, + .presc = 0xff, /* slow as we can go */ +- .oversampling_shift = 2, ++ .oversampling_shift = 0, ++ .before_adc_hook = gta02_ts_hook_before_adc, ++ .after_adc_hook = gta02_ts_hook_after_adc, + }; + + /* Buttons */ +@@ -1073,6 +1140,7 @@ static struct platform_device *gta02_devices[] __initdata = { + static struct platform_device *gta02_devices_pmu_children[] = { + >a02_hdq_device, + >a02_platform_bat, ++ >a02_resume_reason_device, + }; + + +@@ -1102,11 +1170,6 @@ static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf) + regulator_has_full_constraints(); + } + +-static void gta02_poweroff(void) +-{ +- pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1); +-} +- + struct gta02_device_children { + const char *dev_name; + size_t num_children; +@@ -1116,12 +1179,17 @@ struct gta02_device_children { + + static struct platform_device* gta02_pcf50633_gpio_children[] = { + >a02_gsm_supply_device, ++ >a02_usbhost_supply_device, + }; + + static struct platform_device* gta02_gsm_supply_children[] = { + >a02_pm_gsm_dev, + }; + ++static struct platform_device* gta02_usbhost_supply_children[] = { ++ >a02_pm_usbhost_dev, ++}; ++ + static struct platform_device* gta02_hdq_children[] = { + &bq27000_battery_device, + }; +@@ -1130,7 +1198,7 @@ static struct platform_device* gta02_hdq_children[] = { + static struct gta02_device_children gta02_device_children[] = { + { + .dev_name = "pcf50633-gpio.0", +- .num_children = 1, ++ .num_children = 2, + .children = gta02_pcf50633_gpio_children, + }, + { +@@ -1139,6 +1207,11 @@ static struct gta02_device_children gta02_device_children[] = { + .children = gta02_gsm_supply_children, + }, + { ++ .dev_name = "reg-fixed-voltage.2", ++ .num_children = 1, ++ .children = gta02_usbhost_supply_children, ++ }, ++ { + .dev_name = "spi2.0", + .probed_callback = gta02_jbt6k74_probe_completed, + }, +diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h +index 26fdb22..f475349 100644 +--- a/arch/arm/plat-samsung/include/plat/ts.h ++++ b/arch/arm/plat-samsung/include/plat/ts.h +@@ -15,6 +15,8 @@ struct s3c2410_ts_mach_info { + int presc; + int oversampling_shift; + void (*cfg_gpio)(struct platform_device *dev); ++ void (*before_adc_hook)(void); ++ void (*after_adc_hook)(void); + }; + + extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); +diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c +index 2231d80..d342876 100644 +--- a/arch/arm/plat-samsung/time.c ++++ b/arch/arm/plat-samsung/time.c +@@ -195,12 +195,12 @@ static void s3c2410_timer_setup (void) + + /* configure clock tick */ + +- timer_usec_ticks = timer_mask_usec_ticks(6, pclk); ++ timer_usec_ticks = timer_mask_usec_ticks(12, pclk); + + tscaler = clk_get_parent(tdiv); + +- clk_set_rate(tscaler, pclk / 3); +- clk_set_rate(tdiv, pclk / 6); ++ clk_set_rate(tscaler, pclk / 6); ++ clk_set_rate(tdiv, pclk / 12); + clk_set_parent(tin, tdiv); + + tcnt = clk_get_rate(tin) / HZ; +diff --git a/drivers/ar6000/hif/hif2.c b/drivers/ar6000/hif/hif2.c +index 386d96e..90178d0 100644 +--- a/drivers/ar6000/hif/hif2.c ++++ b/drivers/ar6000/hif/hif2.c +@@ -517,6 +517,8 @@ static int ar6000_do_activate(struct hif_device *hif) + goto out_func_ready; + } + ++ mdelay (10); ++ + ret = htcCallbacks.deviceInsertedHandler(hif); + if (ret == A_OK) + return 0; +diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c +index 8feb7f3..21c113b 100644 +--- a/drivers/input/touchscreen/s3c2410_ts.c ++++ b/drivers/input/touchscreen/s3c2410_ts.c +@@ -20,7 +20,7 @@ + * Copyright 2009 Simtec Electronics <linux@simtec.co.uk> + * + * Additional work by Herbert Pƶtzl <herbert@13thfloor.at> and +- * Harald Welte <laforge@openmoko.org> ++ * Harald Welte <laforge@openmoko.org> and Gennady Kupava <gb@bsdmn.com> + */ + + #include <linux/errno.h> +@@ -85,10 +85,19 @@ struct s3c2410ts { + int count; + int shift; + int features; ++ int expectedintr; /* kind of interrupt we are waiting for */ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ void (*before_adc_hook)(void); ++ void (*after_adc_hook)(void); ++#endif + }; + + static struct s3c2410ts ts; + ++#define WAITFORINT_UP (0) ++#define WAITFORINT_DOWN (1) ++#define WAITFORINT_NOTHING (2) ++ + /** + * get_down - return the down state of the pen + * @data0: The data read from ADCDAT0 register. +@@ -126,6 +135,7 @@ static void touch_timer_fire(unsigned long data) + input_report_abs(ts.input, ABS_Y, ts.yp); + + input_report_key(ts.input, BTN_TOUCH, 1); ++ input_report_abs(ts.input, ABS_PRESSURE, 1); + input_sync(ts.input); + + ts.xp = 0; +@@ -133,6 +143,9 @@ static void touch_timer_fire(unsigned long data) + ts.count = 0; + } + ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ ts.before_adc_hook(); ++#endif + s3c_adc_start(ts.client, 0, 1 << ts.shift); + } else { + ts.xp = 0; +@@ -140,8 +153,10 @@ static void touch_timer_fire(unsigned long data) + ts.count = 0; + + input_report_key(ts.input, BTN_TOUCH, 0); ++ input_report_abs(ts.input, ABS_PRESSURE, 0); + input_sync(ts.input); +- ++ ++ ts.expectedintr = WAITFORINT_DOWN; + writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); + } + } +@@ -166,13 +181,22 @@ static irqreturn_t stylus_irq(int irq, void *dev_id) + + down = get_down(data0, data1); + +- /* TODO we should never get an interrupt with down set while +- * the timer is running, but maybe we ought to verify that the +- * timer isn't running anyways. */ ++ /* sitautions below can actually happen on openmoko hardware while ++ various debugging facilities are turned off */ ++ if (ts.expectedintr == WAITFORINT_NOTHING) ++ return IRQ_HANDLED; ++ if (!down && ts.expectedintr == WAITFORINT_DOWN) { ++ writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); ++ return IRQ_HANDLED; ++ } else if (down && ts.expectedintr == WAITFORINT_UP) { ++ writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC); ++ return IRQ_HANDLED; ++ } ++ ts.expectedintr = WAITFORINT_NOTHING; + +- if (down) +- s3c_adc_start(ts.client, 0, 1 << ts.shift); +- else ++ if (down) { ++ mod_timer(&touch_timer, jiffies + 2); ++ } else + dev_dbg(ts.dev, "%s: count=%d\n", __func__, ts.count); + + if (ts.features & FEAT_PEN_IRQ) { +@@ -203,6 +227,11 @@ static void s3c24xx_ts_conversion(struct s3c_adc_client *client, + + ts.count++; + ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ if (!*left) ++ ts.after_adc_hook(); ++#endif ++ + /* From tests, it seems that it is unlikely to get a pen-up + * event during the conversion process which means we can + * ignore any pen-up events with less than the requisite +@@ -226,7 +255,8 @@ static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select) + writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, + ts.io + S3C2410_ADCTSC); + } else { +- mod_timer(&touch_timer, jiffies+1); ++ mod_timer(&touch_timer, jiffies + 3); ++ ts.expectedintr = WAITFORINT_UP; + writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC); + } + } +@@ -304,6 +334,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) + if ((info->delay & 0xffff) > 0) + writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY); + ++ ts.expectedintr = WAITFORINT_DOWN; + writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); + + input_dev = input_allocate_device(); +@@ -318,6 +349,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) + ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0); + input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0); ++ input_set_abs_params(ts.input, ABS_PRESSURE, 0, 1, 0, 0); + + ts.input->name = "S3C24XX TouchScreen"; + ts.input->id.bustype = BUS_HOST; +@@ -328,6 +360,11 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) + ts.shift = info->oversampling_shift; + ts.features = platform_get_device_id(pdev)->driver_data; + ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ ts.before_adc_hook = info->before_adc_hook; ++ ts.after_adc_hook = info->after_adc_hook; ++#endif ++ + ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED, + "s3c2410_ts_pen", ts.input); + if (ret) { +@@ -382,8 +419,18 @@ static int __devexit s3c2410ts_remove(struct platform_device *pdev) + #ifdef CONFIG_PM + static int s3c2410ts_suspend(struct device *dev) + { ++ ts.expectedintr = WAITFORINT_NOTHING; + writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC); + disable_irq(ts.irq_tc); ++ ++ del_timer_sync(&touch_timer); ++ /* TODO - need to fix races better, as timer can fire ++ between TSC_SLEEP and del_timer_sync() and shedule next adc */ ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ ts.after_adc_hook(); ++#endif ++ + clk_disable(ts.clock); + + return 0; +@@ -401,6 +448,7 @@ static int s3c2410ts_resume(struct device *dev) + if ((info->delay & 0xffff) > 0) + writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY); + ++ ts.expectedintr = WAITFORINT_DOWN; + writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); + + return 0; +diff --git a/drivers/mfd/glamo-core.c b/drivers/mfd/glamo-core.c +index 8880263..a0556b8 100644 +--- a/drivers/mfd/glamo-core.c ++++ b/drivers/mfd/glamo-core.c +@@ -160,6 +160,19 @@ static void reg_set_bit_mask(struct glamo_core *glamo, + spin_unlock(&glamo->lock); + } + ++ ++ ++static void reg_checkandset_bit_mask(struct glamo_core *glamo, ++ uint16_t reg, uint16_t mask, ++ uint16_t val, uint16_t check) ++{ ++ spin_lock(&glamo->lock); ++ if (__reg_read(glamo, reg) & mask == check) ++ __reg_set_bit_mask(glamo, reg, mask, val); ++ spin_unlock(&glamo->lock); ++} ++ ++ + static inline void __reg_set_bit(struct glamo_core *glamo, + uint16_t reg, uint16_t bit) + { +@@ -169,6 +182,49 @@ static inline void __reg_set_bit(struct glamo_core *glamo, + __reg_write(glamo, reg, tmp); + } + ++void glamo_pixclock_slow (struct glamo_core *glamo) ++{ ++ ++ int x, lastx = 0; ++ int timeout = 1000000; ++ int threshold = 5; ++ int fa; ++ ++ int evcnt = 0; ++ ++ for (fa = 0; fa < timeout; fa++) { ++ x = glamo_reg_read(glamo, 0x1100 + GLAMO_REG_LCD_STATUS1) & 0x3ff; ++ ++ ++ if (x == lastx) { ++ evcnt++; ++ if (evcnt == threshold) ++ break; ++ } else { ++ evcnt = 0; ++ lastx = x; ++ } ++ } ++ if (fa == timeout) { ++ printk (KERN_WARNING "Glamo: Error waiting for stable x position.\n"); ++ } ++ ++ /* then, make glamo slower */ ++ /* it's not a problems if in rare case we do not slow down glamo properly ++ as all we'll get in that case is singe jittered value */ ++ ++ glamo->slowed_divider = glamo_reg_read (glamo, 0x36) & 0xFF; ++ reg_set_bit_mask (glamo, 0x36, 0xFF, 0xFF); ++ ++} ++ ++void glamo_pixclock_fast (struct glamo_core *glamo) ++{ ++ reg_checkandset_bit_mask (glamo, 0x36, 0xFF, glamo->slowed_divider, 0xFF); ++} ++EXPORT_SYMBOL_GPL(glamo_pixclock_fast); ++EXPORT_SYMBOL_GPL(glamo_pixclock_slow); ++ + static inline void __reg_clear_bit(struct glamo_core *glamo, + uint16_t reg, uint16_t bit) + { +@@ -930,6 +986,7 @@ static int __devinit glamo_probe(struct platform_device *pdev) + glamo->irq = platform_get_irq(pdev, 0); + glamo->irq_base = irq_base = platform_get_irq(pdev, 1); + glamo->pdata = pdev->dev.platform_data; ++ glamo->slowed_divider = 0xFF; + + if (glamo->irq < 0) { + ret = glamo->irq; +@@ -965,7 +1022,7 @@ static int __devinit glamo_probe(struct platform_device *pdev) + goto err_free; + } + +- glamo->base = ioremap(glamo->mem->start, resource_size(glamo->mem)); ++ glamo->base = ioremap(glamo->mem->start, resource_size(glamo->mem)+0x1100); + if (!glamo->base) { + dev_err(&pdev->dev, "Failed to ioremap() memory region\n"); + goto err_release_mem_region; +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 4d073f1..35c3563 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -452,6 +452,13 @@ config PCH_PHUB + To compile this driver as a module, choose M here: the module will + be called pch_phub. + ++config OPENMOKO_RESUME_REASON ++ tristate "Openmoko resume reason driver" ++ depends on SYSFS ++ help ++ This driver adds a sysfs entry for accessing the resume reason ++ of the openmoko board. ++ + source "drivers/misc/c2port/Kconfig" + source "drivers/misc/eeprom/Kconfig" + source "drivers/misc/cb710/Kconfig" +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index 98009cc..1f0e902 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -42,3 +42,4 @@ obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o + obj-$(CONFIG_PCH_PHUB) += pch_phub.o + obj-y += ti-st/ + obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o ++obj-$(CONFIG_OPENMOKO_RESUME_REASON) += neo1973_pm_resume_reason.o +diff --git a/drivers/misc/neo1973_pm_resume_reason.c b/drivers/misc/neo1973_pm_resume_reason.c +new file mode 100644 +index 0000000..5bcc818 +--- /dev/null ++++ b/drivers/misc/neo1973_pm_resume_reason.c +@@ -0,0 +1,142 @@ ++/* ++ * Resume reason sysfs for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2008 by Openmoko Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License resume_reason 2 as ++ * published by the Free Software Foundation ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <linux/io.h> ++ ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++#include <mach/gta02.h> ++#include <linux/mfd/pcf50633/core.h> ++#endif ++ ++static unsigned int *gstatus4_mapped; ++static char *resume_reasons[][17] = { { /* GTA01 */ ++ "EINT00_NULL", ++ "EINT01_GSM", ++ "EINT02_NULL", ++ "EINT03_NULL", ++ "EINT04_JACK", ++ "EINT05_SDCARD", ++ "EINT06_AUXKEY", ++ "EINT07_HOLDKEY", ++ "EINT08_NULL", ++ "EINT09_NULL", ++ "EINT10_NULL", ++ "EINT11_NULL", ++ "EINT12_NULL", ++ "EINT13_NULL", ++ "EINT14_NULL", ++ "EINT15_NULL", ++ NULL ++}, { /* GTA02 */ ++ "EINT00_ACCEL1", ++ "EINT01_GSM", ++ "EINT02_BLUETOOTH", ++ "EINT03_DEBUGBRD", ++ "EINT04_JACK", ++ "EINT05_WLAN", ++ "EINT06_AUXKEY", ++ "EINT07_HOLDKEY", ++ "EINT08_ACCEL2", ++ "EINT09_PMU", ++ "EINT10_NULL", ++ "EINT11_NULL", ++ "EINT12_GLAMO", ++ "EINT13_NULL", ++ "EINT14_NULL", ++ "EINT15_NULL", ++ NULL ++} }; ++ ++static ssize_t resume_reason_read(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ int bit = 0; ++ char *end = buf; ++ int gta = !!machine_is_neo1973_gta02(); ++ ++ for (bit = 0; resume_reasons[gta][bit]; bit++) { ++ if ((*gstatus4_mapped) & (1 << bit)) ++ end += sprintf(end, "* %s\n", resume_reasons[gta][bit]); ++ else ++ end += sprintf(end, " %s\n", resume_reasons[gta][bit]); ++ } ++ ++ return end - buf; ++} ++ ++ ++static DEVICE_ATTR(resume_reason, 0644, resume_reason_read, NULL); ++ ++static struct attribute *neo1973_resume_reason_sysfs_entries[] = { ++ &dev_attr_resume_reason.attr, ++ NULL ++}; ++ ++static struct attribute_group neo1973_resume_reason_attr_group = { ++ .name = NULL, ++ .attrs = neo1973_resume_reason_sysfs_entries, ++}; ++ ++static int __init neo1973_resume_reason_probe(struct platform_device *pdev) ++{ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ gstatus4_mapped = ioremap(0x560000BC /* GSTATUS4 */, 0x4); ++ if (!gstatus4_mapped) { ++ dev_err(&pdev->dev, "failed to ioremap() memory region\n"); ++ return -EINVAL; ++ } ++ ++ return sysfs_create_group(&pdev->dev.kobj, ++ &neo1973_resume_reason_attr_group); ++} ++ ++static int neo1973_resume_reason_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, &neo1973_resume_reason_attr_group); ++ iounmap(gstatus4_mapped); ++ return 0; ++} ++ ++static struct platform_driver neo1973_resume_reason_driver = { ++ .probe = neo1973_resume_reason_probe, ++ .remove = neo1973_resume_reason_remove, ++ .driver = { ++ .name = "neo1973-resume", ++ }, ++}; ++ ++static int __devinit neo1973_resume_reason_init(void) ++{ ++ return platform_driver_register(&neo1973_resume_reason_driver); ++} ++ ++static void neo1973_resume_reason_exit(void) ++{ ++ platform_driver_unregister(&neo1973_resume_reason_driver); ++} ++ ++module_init(neo1973_resume_reason_init); ++module_exit(neo1973_resume_reason_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Neo1973 resume_reason"); +diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c +index ac1f0b0..3a1fdb7 100644 +--- a/drivers/serial/samsung.c ++++ b/drivers/serial/samsung.c +@@ -883,7 +883,7 @@ static struct uart_ops s3c24xx_serial_ops = { + + static struct uart_driver s3c24xx_uart_drv = { + .owner = THIS_MODULE, +- .dev_name = "s3c2410_serial", ++ .dev_name = S3C24XX_SERIAL_NAME, + .nr = CONFIG_SERIAL_SAMSUNG_UARTS, + .cons = S3C24XX_SERIAL_CONSOLE, + .driver_name = S3C24XX_SERIAL_NAME, +diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c +index a68af2d..02bd7b0 100644 +--- a/drivers/usb/host/ohci-s3c2410.c ++++ b/drivers/usb/host/ohci-s3c2410.c +@@ -22,6 +22,10 @@ + #include <linux/platform_device.h> + #include <linux/clk.h> + #include <plat/usb-control.h> ++#include <mach/hardware.h> ++#include <mach/gpio-fns.h> ++#include <mach/regs-gpio.h> ++#include <mach/gta02.h> + + #define valid_port(idx) ((idx) == 1 || (idx) == 2) + +@@ -306,6 +310,42 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) + local_irq_restore(flags); + } + ++/* switching of USB pads */ ++static ssize_t show_usb_mode(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ if (__raw_readl(S3C24XX_MISCCR) & S3C2410_MISCCR_USBHOST) ++ return sprintf(buf, "host\n"); ++ ++ return sprintf(buf, "device\n"); ++} ++ ++static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ if (!strncmp(buf, "host", 4)) { ++ printk("s3c2410: changing usb to host\n"); ++ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, ++ S3C2410_MISCCR_USBHOST); ++ /* FIXME: ++ * - call machine-specific disable-pullup function i ++ * - enable +Vbus (if hardware supports it) ++ */ ++ s3c2410_gpio_setpin(GTA02_GPIO_USB_PULLUP, 0); ++ } else if (!strncmp(buf, "device", 6)) { ++ printk("s3c2410: changing usb to device\n"); ++ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, 0); ++ s3c2410_gpio_setpin(GTA02_GPIO_USB_PULLUP, 1); ++ } else { ++ printk("s3c2410: unknown mode\n"); ++ return -EINVAL; ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode); ++ + /* may be called without controller electrically present */ + /* may be called with controller, bus, and devices active */ + +@@ -323,6 +363,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) + static void + usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) + { ++ device_remove_file(&dev->dev, &dev_attr_usb_mode); + usb_remove_hcd(hcd); + s3c2410_stop_hc(dev); + iounmap(hcd->regs); +@@ -390,8 +431,15 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, + if (retval != 0) + goto err_ioremap; + ++ retval = device_create_file(&dev->dev, &dev_attr_usb_mode); ++ if (retval != 0) ++ goto err_hcd; ++ + return 0; + ++ err_hcd: ++ usb_remove_hcd(hcd); ++ + err_ioremap: + s3c2410_stop_hc(dev); + iounmap(hcd->regs); +diff --git a/drivers/video/glamo-fb.c b/drivers/video/glamo-fb.c +index 3f8ec8d..a428047 100644 +--- a/drivers/video/glamo-fb.c ++++ b/drivers/video/glamo-fb.c +@@ -312,7 +312,7 @@ static int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) + glamofb_reg_write(gfb, GLAMO_REG_LCD_COMMAND1, + GLAMO_LCD_CMD_TYPE_DISP | + GLAMO_LCD_CMD_DATA_DISP_SYNC); +- ++ mdelay(1); + glamofb_reg_write(gfb, GLAMO_REG_LCD_COMMAND1, + GLAMO_LCD_CMD_TYPE_DISP | + GLAMO_LCD_CMD_DATA_DISP_FIRE); +diff --git a/include/linux/mfd/glamo-core.h b/include/linux/mfd/glamo-core.h +index 8275a2f..8e3e56e 100644 +--- a/include/linux/mfd/glamo-core.h ++++ b/include/linux/mfd/glamo-core.h +@@ -37,6 +37,7 @@ struct glamo_core { + enum glamo_engine_state engine_state[__NUM_GLAMO_ENGINES]; + spinlock_t lock; + uint16_t saved_irq_mask; ++ int slowed_divider; + #ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_dir; + #endif +@@ -55,4 +56,6 @@ int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine); + void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine); + int glamo_engine_reclock(struct glamo_core *glamo, + enum glamo_engine engine, int ps); ++void glamo_pixclock_slow (struct glamo_core *glamo); ++void glamo_pixclock_fast (struct glamo_core *glamo); + #endif /* __GLAMO_CORE_H */ diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 28ee2e6..d5b4a40 100644 --- a/sound/soc/codecs/wm8753.c @@ -23,6 +1120,87 @@ index 28ee2e6..d5b4a40 100644 K = Kpart & 0xFFFFFFFF; --- -1.7.4.rc1 - +diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c +index dc5893d..37835ca 100644 +--- a/sound/soc/s3c24xx/neo1973_wm8753.c ++++ b/sound/soc/s3c24xx/neo1973_wm8753.c +@@ -23,6 +23,7 @@ + #include <sound/pcm.h> + #include <sound/soc.h> + #include <sound/soc-dapm.h> ++#include <sound/jack.h> + #include <sound/tlv.h> + + #include <asm/mach-types.h> +@@ -252,6 +253,8 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { + + /* GTA01 specific controlls */ + ++static struct snd_soc_jack hs_jack; ++ + #ifdef CONFIG_MACH_NEO1973_GTA01 + + static const struct snd_soc_dapm_widget wm8753_dapm_widgets_gta01[] = { +@@ -318,6 +321,29 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {}; + static const struct snd_soc_dapm_widget wm8753_dapm_widgets_gta02[] = {}; + #endif + ++static struct snd_soc_jack_pin hs_jack_pins[] = { ++ { ++ .pin = "Headset Mic", ++ .mask = SND_JACK_MICROPHONE, ++ }, ++ { ++ .pin = "Stereo Out", ++ .mask = SND_JACK_HEADPHONE, ++ .invert = 1, ++ }, ++}; ++ ++static struct snd_soc_jack_gpio hs_jack_gpios[] = { ++ { ++ .gpio = GTA02_GPIO_JACK_INSERT, ++ .name = "headset-gpio", ++ .report = SND_JACK_HEADSET, ++ .debounce_time = 100, ++ }, ++}; ++ ++ ++ + static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) + { + struct snd_soc_codec *codec = rtd->codec; +@@ -397,6 +423,24 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) + + snd_soc_dapm_sync(codec); + ++ err = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); ++ if (err) { ++ dev_err(codec->card->dev, "failed to alloc headset jack\n"); ++ return err; ++ } ++ ++ err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); ++ if (err) { ++ dev_err(codec->card->dev, "failed to add headset jack pins\n"); ++ return err; ++ } ++ ++ err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); ++ if (err) { ++ dev_err(codec->card->dev, "failed to add headset jack gpios\n"); ++ return err; ++ } ++ + return 0; + } + +@@ -551,6 +595,7 @@ static inline void neo1973_gta02_exit(void) {} + static void __exit neo1973_exit(void) + { + snd_soc_unregister_dais(&neo1973_snd_device->dev, 1); ++ snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); + platform_device_unregister(neo1973_snd_device); + + if (machine_is_neo1973_gta02()) |