From: Tony Lindgren Date: Thu, 1 Mar 2007 11:33:25 +0000 (-0800) Subject: Merge omap-drivers X-Git-Tag: v2.6.21-omap1~124 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=ba6d3cf6f7900c7586cca6bbd9dca55d7c6386fb;p=linux-2.6-omap-h63xx.git Merge omap-drivers Conflicts: arch/arm/Kconfig arch/arm/boot/.gitignore arch/arm/configs/omap_h2_1610_defconfig arch/arm/configs/omap_osk_5912_defconfig arch/arm/mach-omap1/board-h2.c arch/arm/mach-omap1/clock.c arch/arm/mach-omap2/board-2430sdp.c arch/arm/mach-omap2/board-h4.c arch/arm/oprofile/Makefile arch/arm/oprofile/common.c arch/arm/oprofile/op_arm_model.h arch/arm/oprofile/op_model_v6.c arch/arm/plat-omap/Kconfig arch/arm/plat-omap/Makefile arch/arm/plat-omap/devices.c arch/arm/plat-omap/dsp/dsp_common.c arch/arm/plat-omap/mailbox.c drivers/Makefile drivers/cbus/Kconfig drivers/cbus/retu-pwrbutton.c drivers/cbus/tahvo-usb.c drivers/input/keyboard/Makefile drivers/input/touchscreen/Kconfig drivers/input/touchscreen/ads7846.c drivers/leds/Kconfig drivers/leds/Makefile drivers/spi/Kconfig drivers/spi/Makefile drivers/spi/omap_uwire.c drivers/video/Kconfig drivers/video/Makefile drivers/video/backlight/Kconfig drivers/video/backlight/Makefile drivers/video/omap/Kconfig include/asm-arm/.gitignore include/linux/fb.h include/linux/spi/ads7846.h --- ba6d3cf6f7900c7586cca6bbd9dca55d7c6386fb diff --cc arch/arm/mach-omap1/clock.c index 7e3b24fccff,f625f6dd228..638490e62d5 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@@ -432,7 -432,7 +432,8 @@@ static int omap1_clk_enable(struct clk } if (clk->flags & CLOCK_NO_IDLE_PARENT) -- omap1_clk_deny_idle(clk->parent); ++ if (!cpu_is_omap24xx()) ++ omap1_clk_deny_idle(clk->parent); } ret = clk->enable(clk); @@@ -453,7 -453,7 +454,8 @@@ static void omap1_clk_disable(struct cl if (likely(clk->parent)) { omap1_clk_disable(clk->parent); if (clk->flags & CLOCK_NO_IDLE_PARENT) -- omap1_clk_allow_idle(clk->parent); ++ if (!cpu_is_omap24xx()) ++ omap1_clk_allow_idle(clk->parent); } } } @@@ -469,7 -469,7 +471,7 @@@ static int omap1_clk_enable_generic(str if (unlikely(clk->enable_reg == 0)) { printk(KERN_ERR "clock.c: Enable for %s without enable code\n", clk->name); -- return -EINVAL; ++ return 0; } if (clk->flags & ENABLE_REG_32BIT) { @@@ -649,18 -649,18 +651,10 @@@ int __init omap1_clk_init(void int crystal_type = 0; /* Default 12 MHz */ u32 reg; --#ifdef CONFIG_DEBUG_LL -- /* Resets some clocks that may be left on from bootloader, - * but leaves serial clocks on. - * but leaves serial clocks on. -- */ -- omap_writel(0x3 << 29, MOD_CONF_CTRL_0); --#endif -- /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ reg = omap_readw(SOFT_REQ_REG) & (1 << 4); omap_writew(reg, SOFT_REQ_REG); -- if (!cpu_is_omap15xx()) -- omap_writew(0, SOFT_REQ_REG2); ++ omap_writew(0, SOFT_REQ_REG2); clk_init(&omap1_clk_functions); @@@ -691,7 -691,7 +685,7 @@@ info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); if (info != NULL) { -- if (!cpu_is_omap15xx()) ++ if (!cpu_is_omap1510()) crystal_type = info->system_clock_type; } diff --cc arch/arm/mach-omap2/board-h4.c index df9f3bed351,e85bbebe900..3b1ad1d981a --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@@ -19,9 -19,8 +19,6 @@@ #include #include #include --#include --#include - #include #include #include @@@ -39,13 -38,13 +36,10 @@@ #include #include #include --#include #include "prcm-regs.h" #include -- --#define H4_FLASH_CS 0 --#define H4_SMC91X_CS 1 ++#include static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 }; static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 }; @@@ -123,6 -122,6 +117,8 @@@ static struct flash_platform_data h4_fl }; static struct resource h4_flash_resource = { ++ .start = H4_CS0_BASE, ++ .end = H4_CS0_BASE + SZ_64M - 1, .flags = IORESOURCE_MEM, }; @@@ -136,9 -135,9 +132,28 @@@ static struct platform_device h4_flash_ .resource = &h4_flash_resource, }; ++static struct resource h4_smc91x_resources[] = { ++ [0] = { ++ .start = OMAP24XX_ETHR_START, /* Physical */ ++ .end = OMAP24XX_ETHR_START + 0xf, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), ++ .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device h4_smc91x_device = { ++ .name = "smc91x", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(h4_smc91x_resources), ++ .resource = h4_smc91x_resources, ++}; ++ /* Select between the IrDA and aGPS module */ --#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) static int h4_select_irda(struct device *dev, int state) { unsigned char expa; @@@ -164,11 -163,11 +179,9 @@@ return err; } --static void set_trans_mode(struct work_struct *work) ++static void set_trans_mode(void *data) { -- struct omap_irda_config *irda_config = -- container_of(work, struct omap_irda_config, gpio_expa.work); -- int mode = irda_config->mode; ++ int *mode = data; unsigned char expa; int err = 0; @@@ -178,7 -177,7 +191,7 @@@ expa &= ~0x01; -- if (!(mode & IR_SIRMODE)) { /* MIR/FIR */ ++ if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */ expa |= 0x01; } @@@ -191,17 -190,17 +204,13 @@@ static int h4_transceiver_mode(struct d { struct omap_irda_config *irda_config = dev->platform_data; -- irda_config->mode = mode; cancel_delayed_work(&irda_config->gpio_expa); -- PREPARE_DELAYED_WORK(&irda_config->gpio_expa, set_trans_mode); ++ PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); ++#error this is not permitted - mode is an argument variable schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; } --#else --static int h4_select_irda(struct device *dev, int state) { return 0; } --static int h4_transceiver_mode(struct device *dev, int mode) { return 0; } --#endif static struct omap_irda_config h4_irda_data = { .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, @@@ -257,103 -256,103 +266,32 @@@ static struct platform_device h4_lcd_de }; static struct platform_device *h4_devices[] __initdata = { ++ &h4_smc91x_device, &h4_flash_device, &h4_irda_device, &h4_kp_device, &h4_lcd_device, }; --/* 2420 Sysboot setup (2430 is different) */ --static u32 get_sysboot_value(void) --{ -- return (omap_readl(OMAP242X_CONTROL_STATUS) & 0xFFF); --} -- --/* FIXME: This function should be moved to some other file, gpmc.c? */ -- --/* H4-2420's always used muxed mode, H4-2422's always use non-muxed -- * -- * Note: OMAP-GIT doesn't correctly do is_cpu_omap2422 and is_cpu_omap2423 -- * correctly. The macro needs to look at production_id not just hawkeye. -- */ --static u32 is_gpmc_muxed(void) --{ -- u32 mux; -- mux = get_sysboot_value(); -- if ((mux & 0xF) == 0xd) -- return 1; /* NAND config (could be either) */ -- if (mux & 0x2) /* if mux'ed */ -- return 1; -- else -- return 0; --} -- --static inline void __init h4_init_debug(void) ++static inline void __init h4_init_smc91x(void) { -- int eth_cs; -- unsigned long cs_mem_base; -- unsigned int muxed, rate; -- struct clk *l3ck; -- -- eth_cs = H4_SMC91X_CS; -- -- l3ck = clk_get(NULL, "core_l3_ck"); -- if (IS_ERR(l3ck)) -- rate = 100000000; -- else -- rate = clk_get_rate(l3ck); -- -- if (is_gpmc_muxed()) -- muxed = 0x200; -- else -- muxed = 0; -- /* Make sure CS1 timings are correct */ -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, -- 0x00011000 | muxed); -- -- if (rate >= 160000000) { -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); -- } else if (rate >= 130000000) { -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); -- } else {/* rate = 100000000 */ -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F); -- gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2); -- } -- -- if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { -- printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); -- return; -- } -- ++ GPMC_CONFIG1_1 = 0x00011200; ++ GPMC_CONFIG2_1 = 0x001f1f01; ++ GPMC_CONFIG3_1 = 0x00080803; ++ GPMC_CONFIG4_1 = 0x1c091c09; ++ GPMC_CONFIG5_1 = 0x041f1f1f; ++ GPMC_CONFIG6_1 = 0x000004c4; ++ GPMC_CONFIG7_1 = 0x00000f40 | (0x08000000 >> 24); udelay(100); omap_cfg_reg(M15_24XX_GPIO92); -- if (debug_card_init(cs_mem_base, OMAP24XX_ETHR_GPIO_IRQ) < 0) -- gpmc_cs_free(eth_cs); --} -- --static void __init h4_init_flash(void) --{ -- unsigned long base; -- -- if (gpmc_cs_request(H4_FLASH_CS, SZ_64M, &base) < 0) { -- printk("Can't request GPMC CS for flash\n"); ++ if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) { ++ printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", ++ OMAP24XX_ETHR_GPIO_IRQ); return; } -- h4_flash_resource.start = base; -- h4_flash_resource.end = base + SZ_64M - 1; ++ omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1); } static void __init omap_h4_init_irq(void) @@@ -361,15 -360,15 +299,11 @@@ omap2_init_common_hw(); omap_init_irq(); omap_gpio_init(); -- h4_init_flash(); ++ h4_init_smc91x(); } static struct omap_uart_config h4_uart_config __initdata = { --#ifdef CONFIG_MACH_OMAP2_H4_USB1 -- .enabled_uarts = ((1 << 0) | (1 << 1)), --#else .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), --#endif }; static struct omap_mmc_config h4_mmc_config __initdata = { @@@ -386,113 -385,113 +320,12 @@@ static struct omap_lcd_config h4_lcd_co .ctrl_name = "internal", }; --static struct omap_usb_config h4_usb_config __initdata = { --#ifdef CONFIG_MACH_OMAP2_H4_USB1 -- /* NOTE: usb1 could also be used with 3 wire signaling */ -- .pins[1] = 4, --#endif -- --#ifdef CONFIG_MACH_OMAP_H4_OTG -- /* S1.10 ON -- USB OTG port -- * usb0 switched to Mini-AB port and isp1301 transceiver; -- * S2.POS3 = OFF, S2.POS4 = ON ... to allow battery charging -- */ -- .otg = 1, -- .pins[0] = 4, --#ifdef CONFIG_USB_GADGET_OMAP -- /* use OTG cable, or standard A-to-MiniB */ -- .hmc_mode = 0x14, /* 0:dev/otg 1:host 2:disable */ --#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -- /* use OTG cable, or NONSTANDARD (B-to-MiniB) */ -- .hmc_mode = 0x11, /* 0:host 1:host 2:disable */ --#endif /* XX */ -- --#else -- /* S1.10 OFF -- usb "download port" -- * usb0 switched to Mini-B port and isp1105 transceiver; -- * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging -- */ -- .register_dev = 1, -- .pins[0] = 3, --// .hmc_mode = 0x14, /* 0:dev 1:host 2:disable */ -- .hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */ --#endif --}; -- static struct omap_board_config_kernel h4_config[] = { { OMAP_TAG_UART, &h4_uart_config }, { OMAP_TAG_MMC, &h4_mmc_config }, { OMAP_TAG_LCD, &h4_lcd_config }, -- { OMAP_TAG_USB, &h4_usb_config }, --}; -- --#ifdef CONFIG_MACH_OMAP_H4_TUSB -- --#include -- --static struct musb_hdrc_platform_data tusb_data = { -- .mode = MUSB_OTG, -- .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */ -- -- /* 1.8V supplied by Menelaus, other voltages supplied by VBAT; -- * so no switching. -- */ }; --static void __init tusb_evm_setup(void) --{ -- static char announce[] __initdata = -- KERN_INFO "TUSB 6010 EVM\n"; -- int irq; -- unsigned dmachan = 0; -- -- /* There are at least 32 different combinations of boards that -- * are loosely called "H4", with a 2420 ... different OMAP chip -- * revisions (with pin mux changes for DMAREQ, GPMC errata, etc), -- * modifications of the CPU board, mainboard, EVM, TUSB etc. -- * Plus omap2422, omap2423, etc. -- * -- * So you might need to tweak this setup to make the TUSB EVM -- * behave on your particular setup ... -- */ -- -- /* Already set up: GPMC AD[0..15], CLK, nOE, nWE, nADV_ALE */ -- omap_cfg_reg(E2_GPMC_NCS2); -- omap_cfg_reg(L2_GPMC_NCS7); -- omap_cfg_reg(M1_GPMC_WAIT2); -- -- switch ((system_rev >> 8) & 0x0f) { -- case 0: /* ES 1.0 */ -- case 1: /* ES 2.0 */ -- /* Assume early board revision without optional ES2.0 -- * rework to swap J15 & AA10 so DMAREQ0 works -- */ -- omap_cfg_reg(AA10_242X_GPIO13); -- irq = 13; -- // omap_cfg_reg(J15_24XX_DMAREQ0); -- break; -- default: -- /* Later Menelaus boards can support all 6 DMA request -- * lines, at the price of boot flash A23-A26. -- */ -- omap_cfg_reg(J15_24XX_GPIO99); -- irq = 99; -- dmachan = (1 << 1) | (1 << 0); --#if !(defined(CONFIG_MTD_OMAP_NOR) || defined(CONFIG_MTD_OMAP_NOR_MODULE)) -- dmachan |= (1 << 5) | (1 << 4) (1 << 3) | (1 << 2); --#endif -- break; -- } -- -- if (tusb6010_setup_interface(&tusb_data, -- TUSB6010_REFCLK_24, /* waitpin */ 2, -- /* async cs */ 2, /* sync cs */ 7, -- irq, dmachan) == 0) -- printk(announce); --} -- --#endif -- static void __init omap_h4_init(void) { /* @@@ -513,26 -512,26 +346,10 @@@ } #endif --#ifdef CONFIG_MACH_OMAP2_H4_USB1 -- /* S3.3 controls whether these pins are for UART2 or USB1 */ -- omap_cfg_reg(N14_24XX_USB1_SE0); -- omap_cfg_reg(P15_24XX_USB1_DAT); -- omap_cfg_reg(W20_24XX_USB1_TXEN); -- omap_cfg_reg(V19_24XX_USB1_RCV); --#endif -- platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); omap_board_config = h4_config; omap_board_config_size = ARRAY_SIZE(h4_config); omap_serial_init(); -- -- /* smc91x, debug leds, ps/2, extra uarts */ -- h4_init_debug(); -- --#ifdef CONFIG_MACH_OMAP_H4_TUSB -- tusb_evm_setup(); --#endif -- } static void __init omap_h4_map_io(void) diff --cc arch/arm/oprofile/Makefile index b2041113940,e61d0cc520b..6a94e54848f --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@@ -8,5 -8,6 +8,4 @@@ DRIVER_OBJS = $(addprefix ../../../driv oprofile-y := $(DRIVER_OBJS) common.o backtrace.o oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o - oprofile-$(CONFIG_CPU_V6) += op_model_v6.o -oprofile-$(CONFIG_OPROFILE_ARM11_CORE) += op_model_arm11_core.o -oprofile-$(CONFIG_OPROFILE_ARMV6) += op_model_v6.o -oprofile-$(CONFIG_OPROFILE_MPCORE) += op_model_mpcore.o + diff --cc arch/arm/oprofile/common.c index f4661725b48,0a007b931f6..6f833358cd0 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@@ -135,10 -135,14 +135,6 @@@ int __init oprofile_arch_init(struct op spec = &op_xscale_spec; #endif - #ifdef CONFIG_CPU_V6 - spec = &op_arm11_spec; -#ifdef CONFIG_OPROFILE_ARMV6 - spec = &op_armv6_spec; -#endif - -#ifdef CONFIG_OPROFILE_MPCORE - spec = &op_mpcore_spec; --#endif -- if (spec) { ret = spec->init(); if (ret < 0) diff --cc arch/arm/oprofile/op_arm_model.h index b45efa52994,4899c629aa0..38c6ad15854 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h @@@ -24,10 -24,9 +24,6 @@@ struct op_arm_model_spec extern struct op_arm_model_spec op_xscale_spec; #endif - #ifdef CONFIG_CPU_V6 - extern struct op_arm_model_spec op_arm11_spec; - #endif -extern struct op_arm_model_spec op_armv6_spec; -extern struct op_arm_model_spec op_mpcore_spec; -- extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); diff --cc drivers/Kconfig index bc33d90b376,050323fd79e..abb0e2771d9 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@@ -80,8 -80,8 +80,10 @@@ source "drivers/rtc/Kconfig source "drivers/dma/Kconfig" + source "drivers/auxdisplay/Kconfig" + source "drivers/kvm/Kconfig" +source "drivers/ssi/Kconfig" + endmenu diff --cc drivers/Makefile index 1dc8aba48ea,41c2096ffea..ce913c6bf7a --- a/drivers/Makefile +++ b/drivers/Makefile @@@ -25,17 -25,12 +25,17 @@@ obj-$(CONFIG_CONNECTOR) += connector obj-$(CONFIG_FB_I810) += video/i810/ obj-$(CONFIG_FB_INTEL) += video/intelfb/ +# we also need input/serio early so serio bus is initialized by the time +# serial drivers start registering their serio ports +obj-$(CONFIG_SERIO) += input/serio/ obj-y += serial/ obj-$(CONFIG_PARPORT) += parport/ -obj-y += base/ block/ misc/ mfd/ net/ media/ cbus/ +obj-y += base/ block/ misc/ mfd/ net/ media/ +obj-$(CONFIG_I2C) += i2c/ +obj-y += media/ ssi/ cbus/ obj-$(CONFIG_NUBUS) += nubus/ obj-$(CONFIG_ATM) += atm/ - obj-$(CONFIG_PPC_PMAC) += macintosh/ + obj-y += macintosh/ obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_FC4) += fc4/ obj-$(CONFIG_SCSI) += scsi/ diff --cc drivers/input/keyboard/Makefile index 8b5429d8366,586a0fe53be..17e5ce0bd6d --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@@ -16,7 -16,7 +16,8 @@@ obj-$(CONFIG_KEYBOARD_CORGI) += corgik obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o -obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o -obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o +obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o +obj-$(CONFIG_OMAP_PS2) += innovator_ps2.o +obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o + obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o diff --cc drivers/input/touchscreen/Kconfig index 8b3a3715e0b,971618059a6..6b46c9bf1d2 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@@ -12,16 -12,18 +12,13 @@@ menuconfig INPUT_TOUCHSCREE if INPUT_TOUCHSCREEN config TOUCHSCREEN_ADS7846 - tristate "ADS 7846/7843 based touchscreens" + tristate "ADS 7846 based touchscreens" depends on SPI_MASTER - select HWMON - depends on HWMON = n || HWMON help Say Y here if you have a touchscreen interface using the - ADS7846 or ADS7843 controller, and your board-specific setup + ADS7846 controller, and your board-specific initialization - code includes that in its table of SPI devices. You will - also get hwmon interfaces for the temperature and voltage - sensors this chip provides. + code includes that in its table of SPI devices. - If HWMON is selected, and the driver is told the reference voltage - on your board, you will also get hwmon interfaces for the voltage - (and on ads7846, temperature) sensors of this chip. - If unsure, say N (but it's safe to say "Y"). To compile this driver as a module, choose M here: the diff --cc drivers/input/touchscreen/ads7846.c index 0c496d5d195,0a26e066354..c6164b6f476 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@@ -17,9 -17,9 +17,8 @@@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ --#include ++#include #include --#include #include #include #include @@@ -55,8 -55,8 +54,7 @@@ * files. */ --#define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */ - #define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ -#define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ ++#define TS_POLL_PERIOD msecs_to_jiffies(10) /* this driver doesn't aim at the peak continuous sample rate */ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) @@@ -78,7 -78,12 +76,7 @@@ struct ads7846 char phys[32]; struct spi_device *spi; - struct class_device *hwmon; - -#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) + struct attribute_group *attr_group; - struct class_device *hwmon; -#endif - u16 model; u16 vref_delay_usecs; u16 x_plate_ohms; @@@ -101,16 -106,16 +99,13 @@@ u16 debounce_rep; spinlock_t lock; -- struct hrtimer timer; ++ struct timer_list timer; /* P: lock */ unsigned pendown:1; /* P: lock */ unsigned pending:1; /* P: lock */ // FIXME remove "irq_disabled" unsigned irq_disabled:1; /* P: lock */ unsigned disabled:1; -- int (*filter)(void *data, int data_idx, int *val); -- void *filter_data; -- void (*filter_cleanup)(void *data); int (*get_pendown_state)(void); }; @@@ -147,16 -152,16 +142,15 @@@ #define MAX_12BIT ((1<<12)-1) /* leave ADC powered up (disables penirq) between differential samples */ --#define READ_12BIT_DFR(x, adc, vref) (ADS_START | ADS_A2A1A0_d_ ## x \ -- | ADS_12_BIT | ADS_DFR | \ -- (adc ? ADS_PD10_ADC_ON : 0) | (vref ? ADS_PD10_REF_ON : 0)) ++#define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \ ++ | ADS_12_BIT | ADS_DFR) --#define READ_Y(vref) (READ_12BIT_DFR(y, 1, vref)) --#define READ_Z1(vref) (READ_12BIT_DFR(z1, 1, vref)) --#define READ_Z2(vref) (READ_12BIT_DFR(z2, 1, vref)) ++#define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) ++#define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) ++#define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) --#define READ_X(vref) (READ_12BIT_DFR(x, 1, vref)) --#define PWRDOWN (READ_12BIT_DFR(y, 0, 0)) /* LAST */ ++#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON) ++#define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */ /* single-ended samples need to first power up reference voltage; * we leave both ADC and VREF powered @@@ -164,19 -169,19 +158,14 @@@ #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ | ADS_12_BIT | ADS_SER) --#define REF_ON (READ_12BIT_DFR(x, 1, 1)) --#define REF_OFF (READ_12BIT_DFR(y, 0, 0)) ++#define REF_ON (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON) ++#define REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /*--------------------------------------------------------------------------*/ /* * Non-touchscreen sensors only use single-ended conversions. -- * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; -- * ads7846 lets that pin be unconnected, to use internal vREF. - * - * FIXME make external vREF_mV be a module option, and use that as needed... */ - static const unsigned vREF_mV = 2500; -static unsigned vREF_mV; -module_param(vREF_mV, uint, 0); -MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts"); struct ser_req { u8 ref_on; @@@ -204,55 -209,55 +193,50 @@@ static int ads7846_read12_ser(struct de struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); int status; int sample; -- int use_internal; ++ int i; if (!req) return -ENOMEM; spi_message_init(&req->msg); -- /* FIXME boards with ads7846 might use external vref instead ... */ -- use_internal = (ts->model == 7846); -- -- /* maybe turn on internal vREF, and let it settle */ -- if (use_internal) { -- req->ref_on = REF_ON; -- req->xfer[0].tx_buf = &req->ref_on; -- req->xfer[0].len = 1; -- spi_message_add_tail(&req->xfer[0], &req->msg); -- -- req->xfer[1].rx_buf = &req->scratch; -- req->xfer[1].len = 2; -- -- /* for 1uF, settle for 800 usec; no cap, 100 usec. */ -- req->xfer[1].delay_usecs = ts->vref_delay_usecs; -- spi_message_add_tail(&req->xfer[1], &req->msg); -- } ++ /* activate reference, so it has time to settle; */ ++ req->ref_on = REF_ON; ++ req->xfer[0].tx_buf = &req->ref_on; ++ req->xfer[0].len = 1; ++ req->xfer[1].rx_buf = &req->scratch; ++ req->xfer[1].len = 2; ++ ++ /* ++ * for external VREF, 0 usec (and assume it's always on); ++ * for 1uF, use 800 usec; ++ * no cap, 100 usec. ++ */ ++ req->xfer[1].delay_usecs = ts->vref_delay_usecs; /* take sample */ req->command = (u8) command; req->xfer[2].tx_buf = &req->command; req->xfer[2].len = 1; -- spi_message_add_tail(&req->xfer[2], &req->msg); -- req->xfer[3].rx_buf = &req->sample; req->xfer[3].len = 2; -- spi_message_add_tail(&req->xfer[3], &req->msg); /* REVISIT: take a few more samples, and compare ... */ -- /* maybe off internal vREF */ -- if (use_internal) { -- req->ref_off = REF_OFF; -- req->xfer[4].tx_buf = &req->ref_off; -- req->xfer[4].len = 1; -- spi_message_add_tail(&req->xfer[4], &req->msg); -- -- req->xfer[5].rx_buf = &req->scratch; -- req->xfer[5].len = 2; -- CS_CHANGE(req->xfer[5]); -- spi_message_add_tail(&req->xfer[5], &req->msg); -- } ++ /* turn off reference */ ++ req->ref_off = REF_OFF; ++ req->xfer[4].tx_buf = &req->ref_off; ++ req->xfer[4].len = 1; ++ req->xfer[5].rx_buf = &req->scratch; ++ req->xfer[5].len = 2; ++ ++ CS_CHANGE(req->xfer[5]); ++ ++ /* group all the transfers together, so we can't interfere with ++ * reading touchscreen state; disable penirq while sampling ++ */ ++ for (i = 0; i < 6; i++) ++ spi_message_add_tail(&req->xfer[i], &req->msg); ts->irq_disabled = 1; disable_irq(spi->irq); @@@ -272,60 -277,169 +256,21 @@@ return status ? status : sample; } - #define SHOW(name,var,adjust) static ssize_t \ -#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) - -#define SHOW(name, var, adjust) static ssize_t \ ++#define SHOW(name) static ssize_t \ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ { \ -- struct ads7846 *ts = dev_get_drvdata(dev); \ ssize_t v = ads7846_read12_ser(dev, \ -- READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \ ++ READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \ if (v < 0) \ return v; \ -- return sprintf(buf, "%u\n", adjust(ts, v)); \ ++ return sprintf(buf, "%u\n", (unsigned) v); \ } \ static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); -- --/* Sysfs conventions report temperatures in millidegrees Celcius. - * We could use the low-accuracy two-sample scheme, but can't do the high - * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high -- * accuracy scheme without calibration data. For now we won't try either; - * userspace sees raw sensor values, and must scale appropriately. - * userspace sees raw sensor values, and must scale/calibrate appropriately. -- */ --static inline unsigned null_adjust(struct ads7846 *ts, ssize_t v) --{ -- return v; --} -- - SHOW(temp0, temp0, null_adjust) // temp1_input - SHOW(temp1, temp1, null_adjust) // temp2_input -SHOW(temp0, temp0, null_adjust) /* temp1_input */ -SHOW(temp1, temp1, null_adjust) /* temp2_input */ -- -- --/* sysfs conventions report voltages in millivolts. We can convert voltages -- * if we know vREF. userspace may need to scale vAUX to match the board's -- * external resistors; we assume that vBATT only uses the internal ones. -- */ --static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) --{ -- unsigned retval = v; -- -- /* external resistors may scale vAUX into 0..vREF */ -- retval *= vREF_mV; -- retval = retval >> 12; -- return retval; --} -- --static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) --{ -- unsigned retval = vaux_adjust(ts, v); -- -- /* ads7846 has a resistor ladder to scale this signal down */ -- if (ts->model == 7846) -- retval *= 4; -- return retval; --} -- --SHOW(in0_input, vaux, vaux_adjust) --SHOW(in1_input, vbatt, vbatt_adjust) - - -static struct attribute *ads7846_attributes[] = { - &dev_attr_temp0.attr, - &dev_attr_temp1.attr, - &dev_attr_in0_input.attr, - &dev_attr_in1_input.attr, - NULL, -}; - -static struct attribute_group ads7846_attr_group = { - .attrs = ads7846_attributes, -}; - -static struct attribute *ads7843_attributes[] = { - &dev_attr_in0_input.attr, - &dev_attr_in1_input.attr, - NULL, -}; - -static struct attribute_group ads7843_attr_group = { - .attrs = ads7843_attributes, -}; - -static struct attribute *ads7845_attributes[] = { - &dev_attr_in0_input.attr, - NULL, -}; - -static struct attribute_group ads7845_attr_group = { - .attrs = ads7845_attributes, -}; - -static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) -{ - struct class_device *hwmon; - int err; - - /* hwmon sensors need a reference voltage */ - switch (ts->model) { - case 7846: - if (!vREF_mV) { - dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); - vREF_mV = 2500; - } - break; - case 7845: - case 7843: - if (!vREF_mV) { - dev_warn(&spi->dev, - "external vREF for ADS%d not specified\n", - ts->model); - return 0; - } - break; - } - - /* different chips have different sensor groups */ - switch (ts->model) { - case 7846: - ts->attr_group = &ads7846_attr_group; - break; - case 7845: - ts->attr_group = &ads7845_attr_group; - break; - case 7843: - ts->attr_group = &ads7843_attr_group; - break; - default: - dev_dbg(&spi->dev, "ADS%d not recognized\n", ts->model); - return 0; - } - - err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); - if (err) - return err; - - hwmon = hwmon_device_register(&spi->dev); - if (IS_ERR(hwmon)) { - sysfs_remove_group(&spi->dev.kobj, ts->attr_group); - return PTR_ERR(hwmon); - } - - ts->hwmon = hwmon; - return 0; -} - -static void ads784x_hwmon_unregister(struct spi_device *spi, - struct ads7846 *ts) -{ - if (ts->hwmon) { - sysfs_remove_group(&spi->dev.kobj, ts->attr_group); - hwmon_device_unregister(ts->hwmon); - } -} - -#else -static inline int ads784x_hwmon_register(struct spi_device *spi, - struct ads7846 *ts) -{ - return 0; -} -- -static inline void ads784x_hwmon_unregister(struct spi_device *spi, - struct ads7846 *ts) -{ -} -#endif ++SHOW(temp0) ++SHOW(temp1) ++SHOW(vaux) ++SHOW(vbatt) static int is_pen_down(struct device *dev) { @@@ -373,40 -487,17 +318,49 @@@ static ssize_t ads7846_disable_store(st static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); - /*--------------------------------------------------------------------------*/ -static struct attribute *ads784x_attributes[] = { ++static struct attribute *ads7846_attributes[] = { ++ &dev_attr_temp0.attr, ++ &dev_attr_temp1.attr, ++ &dev_attr_vbatt.attr, ++ &dev_attr_vaux.attr, ++ &dev_attr_pen_down.attr, ++ &dev_attr_disable.attr, ++ NULL, ++}; + - static void ads7846_report_pen_state(struct ads7846 *ts, int down) - { - struct input_dev *input_dev = ts->input; ++static struct attribute_group ads7846_attr_group = { ++ .attrs = ads7846_attributes, ++}; + - input_report_key(input_dev, BTN_TOUCH, down); - if (!down) - input_report_abs(input_dev, ABS_PRESSURE, 0); - #ifdef VERBOSE - pr_debug("%s: %s\n", ts->spi->dev.bus_id, down ? "DOWN" : "UP"); - #endif - } ++/* ++ * ads7843/7845 don't have temperature sensors, and ++ * use the other sensors a bit differently too ++ */ + - static void ads7846_report_pen_position(struct ads7846 *ts, int x, int y, - int pressure) - { - struct input_dev *input_dev = ts->input; ++static struct attribute *ads7843_attributes[] = { ++ &dev_attr_vbatt.attr, ++ &dev_attr_vaux.attr, + &dev_attr_pen_down.attr, + &dev_attr_disable.attr, + NULL, + }; - input_report_abs(input_dev, ABS_X, x); - input_report_abs(input_dev, ABS_Y, y); - input_report_abs(input_dev, ABS_PRESSURE, pressure); -static struct attribute_group ads784x_attr_group = { - .attrs = ads784x_attributes, ++static struct attribute_group ads7843_attr_group = { ++ .attrs = ads7843_attributes, ++}; + - #ifdef VERBOSE - pr_debug("%s: %d/%d/%d\n", ts->spi->dev.bus_id, x, y, pressure); - #endif - } ++static struct attribute *ads7845_attributes[] = { ++ &dev_attr_vaux.attr, ++ &dev_attr_pen_down.attr, ++ &dev_attr_disable.attr, ++ NULL, ++}; + - static void ads7846_sync_events(struct ads7846 *ts) - { - struct input_dev *input_dev = ts->input; ++static struct attribute_group ads7845_attr_group = { ++ .attrs = ads7845_attributes, + }; - input_sync(input_dev); - } + /*--------------------------------------------------------------------------*/ /* * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, @@@ -419,22 -510,22 +373,25 @@@ static void ads7846_rx(void *ads) { struct ads7846 *ts = ads; ++ struct input_dev *input_dev = ts->input; unsigned Rt; ++ unsigned sync = 0; u16 x, y, z1, z2; ++ unsigned long flags; - /* ads7846_rx_val() did in-place conversion (including byteswap) from - * on-the-wire format as part of debouncing to get stable readings. + /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; + * built from two 8 bit values written msb-first. */ -- x = ts->tc.x; -- y = ts->tc.y; -- z1 = ts->tc.z1; -- z2 = ts->tc.z2; ++ x = (be16_to_cpu(ts->tc.x) >> 3) & 0x0fff; ++ y = (be16_to_cpu(ts->tc.y) >> 3) & 0x0fff; ++ z1 = (be16_to_cpu(ts->tc.z1) >> 3) & 0x0fff; ++ z2 = (be16_to_cpu(ts->tc.z2) >> 3) & 0x0fff; /* range filtering */ if (x == MAX_12BIT) x = 0; -- if (likely(x && z1)) { ++ if (likely(x && z1 && !device_suspended(&ts->spi->dev))) { /* compute touch pressure resistance using equation #2 */ Rt = z2; Rt -= z1; @@@ -446,111 -537,130 +403,100 @@@ Rt = 0; /* Sample found inconsistent by debouncing or pressure is beyond - * the maximum. Don't report it to user space, repeat at least - * once more the measurement - */ + * the maximum. Don't report it to user space, repeat at least + * once more the measurement */ if (ts->tc.ignore || Rt > ts->pressure_max) { --#ifdef VERBOSE -- pr_debug("%s: ignored %d pressure %d\n", -- ts->spi->dev.bus_id, ts->tc.ignore, Rt); --#endif -- hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), - HRTIMER_REL); - HRTIMER_MODE_REL); ++ mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); return; } -- /* NOTE: We can't rely on the pressure to determine the pen down - * state. The pressure value can fluctuate for quite a while - * after lifting the pen and in some cases may not even settle at - * the expected value. The only safe way to check for the pen up - * condition is in the timer by reading the pen IRQ state. - * state, even this controller has a pressure sensor. The pressure - * value can fluctuate for quite a while after lifting the pen and - * in some cases may not even settle at the expected value. ++ /* NOTE: "pendown" is inferred from pressure; we don't rely on ++ * being able to check nPENIRQ status, or "friendly" trigger modes ++ * (both-edges is much better than just-falling or low-level). + * - * The only safe way to check for the pen up condition is in the - * timer by reading the pen signal state (it's a GPIO _and_ IRQ). ++ * REVISIT: some boards may require reading nPENIRQ; it's ++ * needed on 7843. and 7845 reads pressure differently... ++ * ++ * REVISIT: the touchscreen might not be connected; this code ++ * won't notice that, even if nPENIRQ never fires ... */ ++ if (!ts->pendown && Rt != 0) { ++ input_report_key(input_dev, BTN_TOUCH, 1); ++ sync = 1; ++ } else if (ts->pendown && Rt == 0) { ++ input_report_key(input_dev, BTN_TOUCH, 0); ++ sync = 1; ++ } ++ if (Rt) { - if (!ts->pendown) { - ads7846_report_pen_state(ts, 1); - ts->pendown = 1; - } - ads7846_report_pen_position(ts, x, y, Rt); - ads7846_sync_events(ts); - struct input_dev *input = ts->input; ++ input_report_abs(input_dev, ABS_X, x); ++ input_report_abs(input_dev, ABS_Y, y); ++ sync = 1; ++ } + - if (!ts->pendown) { - input_report_key(input, BTN_TOUCH, 1); - ts->pendown = 1; -#ifdef VERBOSE - dev_dbg(&ts->spi->dev, "DOWN\n"); -#endif - } - input_report_abs(input, ABS_X, x); - input_report_abs(input, ABS_Y, y); - input_report_abs(input, ABS_PRESSURE, Rt); ++ if (sync) { ++ input_report_abs(input_dev, ABS_PRESSURE, Rt); ++ input_sync(input_dev); + } - hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_REL); - input_sync(input); -#ifdef VERBOSE - dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); ++#ifdef VERBOSE ++ if (Rt || ts->pendown) ++ pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id, ++ x, y, Rt, Rt ? "" : " UP"); + #endif - } + - hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), - HRTIMER_MODE_REL); ++ spin_lock_irqsave(&ts->lock, flags); ++ ++ ts->pendown = (Rt != 0); ++ mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); ++ ++ spin_unlock_irqrestore(&ts->lock, flags); } --static int ads7846_debounce(void *ads, int data_idx, int *val) ++static void ads7846_debounce(void *ads) { struct ads7846 *ts = ads; ++ struct spi_message *m; ++ struct spi_transfer *t; ++ int val; ++ int status; -- if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { -- /* Start over collecting consistent readings. */ -- ts->read_rep = 0; ++ m = &ts->msg[ts->msg_idx]; ++ t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); ++ val = (be16_to_cpu(*(__be16 *)t->rx_buf) >> 3) & 0x0fff; ++ if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) { /* Repeat it, if this was the first read or the read * wasn't consistent enough. */ if (ts->read_cnt < ts->debounce_max) { -- ts->last_read = *val; ++ ts->last_read = val; ts->read_cnt++; -- return ADS7846_FILTER_REPEAT; } else { /* Maximum number of debouncing reached and still * not enough number of consistent readings. Abort * the whole sample, repeat it in the next sampling * period. */ ++ ts->tc.ignore = 1; ts->read_cnt = 0; -- return ADS7846_FILTER_IGNORE; ++ /* Last message will contain ads7846_rx() as the ++ * completion function. ++ */ ++ m = ts->last_msg; } ++ /* Start over collecting consistent readings. */ ++ ts->read_rep = 0; } else { if (++ts->read_rep > ts->debounce_rep) { /* Got a good reading for this coordinate, * go for the next one. */ ++ ts->tc.ignore = 0; ++ ts->msg_idx++; ts->read_cnt = 0; ts->read_rep = 0; -- return ADS7846_FILTER_OK; -- } else { ++ m++; ++ } else /* Read more values that are consistent. */ ts->read_cnt++; -- return ADS7846_FILTER_REPEAT; -- } -- } --} -- --static int ads7846_no_filter(void *ads, int data_idx, int *val) --{ -- return ADS7846_FILTER_OK; --} -- --static void ads7846_rx_val(void *ads) --{ -- struct ads7846 *ts = ads; -- struct spi_message *m; -- struct spi_transfer *t; -- u16 *rx_val; -- int val; -- int action; -- int status; -- -- m = &ts->msg[ts->msg_idx]; -- t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); - rx_val = (u16 *)t->rx_buf; - rx_val = t->rx_buf; - - /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; - * built from two 8 bit values written msb-first. - */ -- val = be16_to_cpu(*rx_val) >> 3; -- -- action = ts->filter(ts->filter_data, ts->msg_idx, &val); -- switch (action) { -- case ADS7846_FILTER_REPEAT: -- break; -- case ADS7846_FILTER_IGNORE: -- ts->tc.ignore = 1; -- /* Last message will contain ads7846_rx() as the -- * completion function. -- */ -- m = ts->last_msg; -- break; -- case ADS7846_FILTER_OK: -- *rx_val = val; -- ts->tc.ignore = 0; -- m = &ts->msg[++ts->msg_idx]; -- break; -- default: -- BUG(); } status = spi_async(ts->spi, m); if (status) @@@ -558,27 -668,34 +504,21 @@@ status); } - static int ads7846_timer(struct hrtimer *handle) -static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) ++static void ads7846_timer(unsigned long handle) { -- struct ads7846 *ts = container_of(handle, struct ads7846, timer); ++ struct ads7846 *ts = (void *)handle; int status = 0; spin_lock_irq(&ts->lock); -- if (unlikely(!ts->get_pendown_state() || -- device_suspended(&ts->spi->dev))) { -- if (ts->pendown) { - ads7846_report_pen_state(ts, 0); - ads7846_sync_events(ts); - struct input_dev *input = ts->input; - - input_report_key(input, BTN_TOUCH, 0); - input_report_abs(input, ABS_PRESSURE, 0); - input_sync(input); - -- ts->pendown = 0; -#ifdef VERBOSE - dev_dbg(&ts->spi->dev, "UP\n"); -#endif -- } -- - /* measurment cycle ended */ ++ if (unlikely(ts->msg_idx && !ts->pendown)) { + /* measurement cycle ended */ if (!device_suspended(&ts->spi->dev)) { ts->irq_disabled = 0; enable_irq(ts->spi->irq); } ts->pending = 0; ++ ts->msg_idx = 0; } else { /* pen is still down, continue with the measurement */ ts->msg_idx = 0; @@@ -588,7 -705,7 +528,6 @@@ } spin_unlock_irq(&ts->lock); -- return HRTIMER_NORESTART; } static irqreturn_t ads7846_irq(int irq, void *handle) @@@ -608,8 -724,8 +546,7 @@@ ts->irq_disabled = 1; disable_irq(ts->spi->irq); ts->pending = 1; -- hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), - HRTIMER_REL); - HRTIMER_MODE_REL); ++ mod_timer(&ts->timer, jiffies); } } spin_unlock_irqrestore(&ts->lock, flags); @@@ -695,8 -811,7 +632,6 @@@ static int __devinit ads7846_probe(stru struct ads7846_platform_data *pdata = spi->dev.platform_data; struct spi_message *m; struct spi_transfer *x; -- int vref; int err; if (!spi->irq) { @@@ -721,12 -840,15 +660,11 @@@ return -EINVAL; } - /* We'd set the wordsize to 12 bits ... except that some controllers - * will then treat the 8 bit command words as 12 bits (and drop the - * four MSBs of the 12 bit result). Result: inputs must be shifted - * to discard the four garbage LSBs. (Also, not all controllers can - * support 12 bit words.) + /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except + * that even if the hardware can do that, the SPI controller driver + * may not. So we stick to very-portable 8 bit words, both RX and TX. */ + spi->bits_per_word = 8; - spi->mode = SPI_MODE_1; - err = spi_setup(spi); - if (err < 0) - return err; ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); input_dev = input_allocate_device(); @@@ -741,13 -862,8 +678,9 @@@ ts->spi = spi; ts->input = input_dev; - ts->hwmon = hwmon; - hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_REL); - hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ++ init_timer(&ts->timer); ++ ts->timer.data = (unsigned long) ts; ts->timer.function = ads7846_timer; spin_lock_init(&ts->lock); @@@ -756,25 -872,25 +689,14 @@@ ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; ts->pressure_max = pdata->pressure_max ? : ~0; -- -- if (pdata->filter != NULL) { -- if (pdata->filter_init != NULL) { -- err = pdata->filter_init(pdata, &ts->filter_data); -- if (err < 0) -- goto err_free_mem; -- } -- ts->filter = pdata->filter; -- ts->filter_cleanup = pdata->filter_cleanup; -- } else if (pdata->debounce_max) { ++ if (pdata->debounce_max) { ts->debounce_max = pdata->debounce_max; -- if (ts->debounce_max < 2) -- ts->debounce_max = 2; ts->debounce_tol = pdata->debounce_tol; ts->debounce_rep = pdata->debounce_rep; -- ts->filter = ads7846_debounce; -- ts->filter_data = ts; ++ if (ts->debounce_rep > ts->debounce_max + 1) ++ ts->debounce_rep = ts->debounce_max - 1; } else -- ts->filter = ads7846_no_filter; ++ ts->debounce_tol = ~0; ts->get_pendown_state = pdata->get_pendown_state; snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); @@@ -796,8 -912,8 +718,6 @@@ input_set_abs_params(input_dev, ABS_PRESSURE, pdata->pressure_min, pdata->pressure_max, 0, 0); -- vref = pdata->keep_vref_on; -- /* set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ @@@ -807,7 -923,7 +727,7 @@@ spi_message_init(m); /* y- still on; turn on only y+ (and ADC) */ -- ts->read_y = READ_Y(vref); ++ ts->read_y = READ_Y; x->tx_buf = &ts->read_y; x->len = 1; spi_message_add_tail(x, m); @@@ -817,7 -933,7 +737,7 @@@ x->len = 2; spi_message_add_tail(x, m); -- m->complete = ads7846_rx_val; ++ m->complete = ads7846_debounce; m->context = ts; m++; @@@ -825,7 -941,7 +745,7 @@@ /* turn y- off, x+ on, then leave in lowpower */ x++; -- ts->read_x = READ_X(vref); ++ ts->read_x = READ_X; x->tx_buf = &ts->read_x; x->len = 1; spi_message_add_tail(x, m); @@@ -835,7 -951,7 +755,7 @@@ x->len = 2; spi_message_add_tail(x, m); -- m->complete = ads7846_rx_val; ++ m->complete = ads7846_debounce; m->context = ts; /* turn y+ off, x- on; we'll use formula #2 */ @@@ -844,7 -960,7 +764,7 @@@ spi_message_init(m); x++; -- ts->read_z1 = READ_Z1(vref); ++ ts->read_z1 = READ_Z1; x->tx_buf = &ts->read_z1; x->len = 1; spi_message_add_tail(x, m); @@@ -854,14 -970,14 +774,14 @@@ x->len = 2; spi_message_add_tail(x, m); -- m->complete = ads7846_rx_val; ++ m->complete = ads7846_debounce; m->context = ts; m++; spi_message_init(m); x++; -- ts->read_z2 = READ_Z2(vref); ++ ts->read_z2 = READ_Z2; x->tx_buf = &ts->read_z2; x->len = 1; spi_message_add_tail(x, m); @@@ -871,7 -987,7 +791,7 @@@ x->len = 2; spi_message_add_tail(x, m); -- m->complete = ads7846_rx_val; ++ m->complete = ads7846_debounce; m->context = ts; } @@@ -896,51 -1012,28 +816,35 @@@ ts->last_msg = m; - if (request_irq(spi->irq, ads7846_irq, - IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, - spi->dev.bus_id, ts)) { + if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, + spi->dev.driver->name, ts)) { dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); err = -EBUSY; -- goto err_cleanup_filter; ++ goto err_free_mem; } - dev_info(&spi->dev, "touchscreen + hwmon, irq %d\n", spi->irq); - err = ads784x_hwmon_register(spi, ts); - if (err) - goto err_free_irq; - + dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); -- /* take a first sample, leaving nPENIRQ active and vREF off; avoid ++ /* take a first sample, leaving nPENIRQ active; avoid * the touchscreen, in case it's not connected. */ (void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); - /* ads7843/7845 don't have temperature sensors, and - * use the other ADC lines a bit differently too - */ - if (ts->model == 7846) { - err = device_create_file(&spi->dev, &dev_attr_temp0); - if (err) - goto err_remove_attr7; - err = device_create_file(&spi->dev, &dev_attr_temp1); - if (err) - goto err_remove_attr6; - } - /* in1 == vBAT (7846), or a non-scaled ADC input */ - if (ts->model != 7845) { - err = device_create_file(&spi->dev, &dev_attr_in1_input); - if (err) - goto err_remove_attr5; - err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); ++ switch (ts->model) { ++ case 7846: ++ ts->attr_group = &ads7846_attr_group; ++ break; ++ case 7845: ++ ts->attr_group = &ads7845_attr_group; ++ break; ++ default: ++ ts->attr_group = &ads7843_attr_group; ++ break; + } - /* in0 == a non-scaled ADC input */ - err = device_create_file(&spi->dev, &dev_attr_in0_input); - if (err) - goto err_remove_attr4; - - /* non-hwmon device attributes */ - err = device_create_file(&spi->dev, &dev_attr_pen_down); - if (err) - goto err_remove_attr3; - err = device_create_file(&spi->dev, &dev_attr_disable); ++ err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); if (err) - goto err_remove_attr2; - goto err_remove_hwmon; ++ goto err_free_irq; err = input_register_device(input_dev); if (err) @@@ -948,29 -1041,16 +852,11 @@@ return 0; - err_remove_attr1: - device_remove_file(&spi->dev, &dev_attr_disable); - err_remove_attr2: - device_remove_file(&spi->dev, &dev_attr_pen_down); - err_remove_attr3: - device_remove_file(&spi->dev, &dev_attr_in0_input); - err_remove_attr4: - if (ts->model != 7845) - device_remove_file(&spi->dev, &dev_attr_in1_input); - err_remove_attr5: - if (ts->model == 7846) { - device_remove_file(&spi->dev, &dev_attr_temp1); - err_remove_attr6: - device_remove_file(&spi->dev, &dev_attr_temp0); - } - err_remove_attr7: + err_remove_attr_group: - sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); - err_remove_hwmon: - ads784x_hwmon_unregister(spi, ts); ++ sysfs_remove_group(&spi->dev.kobj, ts->attr_group); + err_free_irq: free_irq(spi->irq, ts); -- err_cleanup_filter: -- if (ts->filter_cleanup) -- ts->filter_cleanup(ts->filter_data); err_free_mem: - if (!IS_ERR(hwmon)) - hwmon_device_unregister(hwmon); input_free_device(input_dev); kfree(ts); return err; @@@ -980,28 -1060,20 +866,16 @@@ static int __devexit ads7846_remove(str { struct ads7846 *ts = dev_get_drvdata(&spi->dev); - hwmon_device_unregister(ts->hwmon); - ads784x_hwmon_unregister(spi, ts); input_unregister_device(ts->input); ads7846_suspend(spi, PMSG_SUSPEND); - device_remove_file(&spi->dev, &dev_attr_disable); - device_remove_file(&spi->dev, &dev_attr_pen_down); - if (ts->model == 7846) { - device_remove_file(&spi->dev, &dev_attr_temp1); - device_remove_file(&spi->dev, &dev_attr_temp0); - } - if (ts->model != 7845) - device_remove_file(&spi->dev, &dev_attr_in1_input); - device_remove_file(&spi->dev, &dev_attr_in0_input); - sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); ++ sysfs_remove_group(&spi->dev.kobj, ts->attr_group); free_irq(ts->spi->irq, ts); /* suspend left the IRQ disabled */ enable_irq(ts->spi->irq); - if (ts->filter_cleanup != NULL) - if (ts->filter_cleanup) -- ts->filter_cleanup(ts->filter_data); -- kfree(ts); dev_dbg(&spi->dev, "unregistered touchscreen\n"); diff --cc drivers/leds/Kconfig index 7c2c352430f,80acd08f0e9..ca1e845d0e1 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@@ -82,27 -82,18 +82,39 @@@ config LEDS_WRA help This option enables support for the PCEngines WRAP programmable LEDs. +config LEDS_OMAP_DEBUG + boolean "LED Support for OMAP debug board LEDs" + depends on LEDS_CLASS=y && ARCH_OMAP + help + Enables support for the LEDs on the debug board used with OMAP + reference boards like H2/H3/H4 and Perseus2. Up to six of these + may be claimed by the original ARM debug LED API. + +config LEDS_OMAP + tristate "LED Support for OMAP GPIO LEDs" + depends on LEDS_CLASS && ARCH_OMAP + help + This option enables support for the LEDs on OMAP processors. + +config LEDS_OMAP_PWM + tristate "LED Support for OMAP PWM-controlled LEDs" + depends on LEDS_CLASS && ARCH_OMAP && OMAP_DM_TIMER + help + This options enables support for LEDs connected to GPIO lines + controlled by a PWM timer on OMAP CPUs. + + config LEDS_H1940 + tristate "LED Support for iPAQ H1940 device" + depends LEDS_CLASS && ARCH_H1940 + help + This option enables support for the LEDs on the h1940. + + config LEDS_COBALT + tristate "LED Support for Cobalt Server front LED" + depends on LEDS_CLASS && MIPS_COBALT + help + This option enables support for the front LED on Cobalt Server + comment "LED Triggers" config LEDS_TRIGGERS diff --cc drivers/leds/Makefile index d39541a88d0,aa2c18efa5b..dc6985d9468 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@@ -14,8 -14,8 +14,10 @@@ obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o +obj-$(CONFIG_LEDS_OMAP) += leds-omap.o +obj-$(CONFIG_LEDS_OMAP_PWM) += leds-omap-pwm.o + obj-$(CONFIG_LEDS_H1940) += leds-h1940.o + obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o # LED Triggers obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o diff --cc drivers/mtd/nand/Makefile index 69da27e2285,80f1dfc7794..1d5f12ffa6d --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@@ -23,9 -23,8 +23,10 @@@ obj-$(CONFIG_MTD_NAND_TS7250) += ts725 obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o +obj-$(CONFIG_MTD_NAND_OMAP) += omap-nand-flash.o +obj-$(CONFIG_MTD_NAND_OMAP_HW) += omap-hw.o obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o + obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o nand-objs := nand_base.o nand_bbt.o cafe_nand-objs := cafe.o cafe_ecc.o diff --cc drivers/spi/Kconfig index 948a9dc79ad,7e54e48efd5..8c646579f68 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@@ -135,12 -142,17 +156,24 @@@ config SPI_OMAP24X comment "SPI Protocol Masters" depends on SPI_MASTER +config TSC2102 + depends on SPI_MASTER + tristate "TSC2102 codec support" + ---help--- + Say Y here if you want support for the TSC2102 chip. It + will be needed for the touchscreen driver on some boards. ++ + config SPI_AT25 + tristate "SPI EEPROMs from most vendors" + depends on SPI_MASTER && SYSFS + help + Enable this driver to get read/write support to most SPI EEPROMs, + after you configure the board init code to know about each eeprom + on your target board. + + This driver can also be built as a module. If so, the module + will be called at25. + # # Add new SPI protocol masters in alphabetical order above this line # diff --cc drivers/spi/Makefile index 83b3e70365f,3c280ad8920..b0cc0593453 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@@ -22,7 -23,7 +25,8 @@@ obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_u # ... add above this line ... # SPI protocol drivers (device/link on bus) +obj-$(CONFIG_TSC2102) += tsc2102.o + obj-$(CONFIG_SPI_AT25) += at25.o # ... add above this line ... # SPI slave controller drivers (upstream link) diff --cc drivers/spi/omap_uwire.c index b5a4d62c7c3,96f62b2df30..00000000000 deleted file mode 100644,100644 --- a/drivers/spi/omap_uwire.c +++ /dev/null @@@ -1,567 -1,572 +1,0 @@@ --/* -- * omap_uwire.c -- MicroWire interface driver for OMAP -- * -- * Copyright 2003 MontaVista Software Inc. -- * -- * Ported to 2.6 OMAP uwire interface. -- * Copyright (C) 2004 Texas Instruments. -- * - * Generalization patches by Juha Yrjölä - * Generalization patches by Juha Yrjola -- * -- * Copyright (C) 2005 David Brownell (ported to 2.6 SPI interface) - * Copyright (C) 2006 Nokia - * - * Many updates by Imre Deak -- * -- * This program is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License as published by the -- * Free Software Foundation; either version 2 of the License, or (at your -- * option) any later version. -- * -- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- * -- * You should have received a copy of the GNU General Public License along -- * with this program; if not, write to the Free Software Foundation, Inc., -- * 675 Mass Ave, Cambridge, MA 02139, USA. -- */ --#include --#include --#include --#include -#include --#include --#include --#include -- --#include --#include -- --#include --#include --#include --#include --#include -- --#include --#include /* OMAP730_IO_CONF registers */ -- -- --/* FIXME address is now a platform device resource, -- * and irqs should show there too... -- */ --#define UWIRE_BASE_PHYS 0xFFFB3000 --#define UWIRE_BASE ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS)) -- --/* uWire Registers: */ --#define UWIRE_IO_SIZE 0x20 --#define UWIRE_TDR 0x00 --#define UWIRE_RDR 0x00 --#define UWIRE_CSR 0x01 --#define UWIRE_SR1 0x02 --#define UWIRE_SR2 0x03 --#define UWIRE_SR3 0x04 --#define UWIRE_SR4 0x05 --#define UWIRE_SR5 0x06 -- --/* CSR bits */ --#define RDRB (1 << 15) --#define CSRB (1 << 14) --#define START (1 << 13) --#define CS_CMD (1 << 12) -- --/* SR1 or SR2 bits */ --#define UWIRE_READ_FALLING_EDGE 0x0001 --#define UWIRE_READ_RISING_EDGE 0x0000 --#define UWIRE_WRITE_FALLING_EDGE 0x0000 --#define UWIRE_WRITE_RISING_EDGE 0x0002 --#define UWIRE_CS_ACTIVE_LOW 0x0000 --#define UWIRE_CS_ACTIVE_HIGH 0x0004 --#define UWIRE_FREQ_DIV_2 0x0000 --#define UWIRE_FREQ_DIV_4 0x0008 --#define UWIRE_FREQ_DIV_8 0x0010 --#define UWIRE_CHK_READY 0x0020 --#define UWIRE_CLK_INVERTED 0x0040 -- -- --struct uwire_spi { -- struct spi_bitbang bitbang; -- struct clk *ck; --}; -- --struct uwire_state { -- unsigned bits_per_word; -- unsigned div1_idx; --}; -- --/* REVISIT compile time constant for idx_shift? */ --static unsigned int uwire_idx_shift; -- --static inline void uwire_write_reg(int idx, u16 val) --{ -- __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift)); --} -- --static inline u16 uwire_read_reg(int idx) --{ -- return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift)); --} -- --static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags) --{ -- u16 w, val = 0; -- int shift, reg; -- -- if (flags & UWIRE_CLK_INVERTED) -- val ^= 0x03; -- val = flags & 0x3f; -- if (cs & 1) -- shift = 6; -- else -- shift = 0; -- if (cs <= 1) -- reg = UWIRE_SR1; -- else -- reg = UWIRE_SR2; -- -- w = uwire_read_reg(reg); -- w &= ~(0x3f << shift); -- w |= val << shift; -- uwire_write_reg(reg, w); --} -- --static int wait_uwire_csr_flag(u16 mask, u16 val, int might_not_catch) --{ -- u16 w; -- int c = 0; -- unsigned long max_jiffies = jiffies + HZ; -- -- for (;;) { -- w = uwire_read_reg(UWIRE_CSR); -- if ((w & mask) == val) -- break; -- if (time_after(jiffies, max_jiffies)) { -- printk(KERN_ERR "%s: timeout. reg=%#06x " -- "mask=%#06x val=%#06x\n", -- __FUNCTION__, w, mask, val); -- return -1; -- } -- c++; -- if (might_not_catch && c > 64) -- break; -- } -- return 0; --} -- --static void uwire_set_clk1_div(int div1_idx) --{ -- u16 w; -- -- w = uwire_read_reg(UWIRE_SR3); -- w &= ~(0x03 << 1); -- w |= div1_idx << 1; -- uwire_write_reg(UWIRE_SR3, w); --} -- --static void uwire_chipselect(struct spi_device *spi, int value) --{ -- struct uwire_state *ust = spi->controller_state; -- u16 w; -- int old_cs; -- -- -- BUG_ON(wait_uwire_csr_flag(CSRB, 0, 0)); -- -- w = uwire_read_reg(UWIRE_CSR); -- old_cs = (w >> 10) & 0x03; -- if (value == BITBANG_CS_INACTIVE || old_cs != spi->chip_select) { -- /* Deselect this CS, or the previous CS */ -- w &= ~CS_CMD; -- uwire_write_reg(UWIRE_CSR, w); -- } -- /* activate specfied chipselect */ -- if (value == BITBANG_CS_ACTIVE) { -- uwire_set_clk1_div(ust->div1_idx); -- /* invert clock? */ -- if (spi->mode & SPI_CPOL) -- uwire_write_reg(UWIRE_SR4, 1); -- else -- uwire_write_reg(UWIRE_SR4, 0); -- -- w = spi->chip_select << 10; -- w |= CS_CMD; -- uwire_write_reg(UWIRE_CSR, w); -- } --} -- --static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t) --{ -- struct uwire_state *ust = spi->controller_state; -- unsigned len = t->len; -- unsigned bits = ust->bits_per_word; -- unsigned bytes; -- u16 val, w; -- int status = 0;; -- -- if (!t->tx_buf && !t->rx_buf) -- return 0; -- -- /* Microwire doesn't read and write concurrently */ -- if (t->tx_buf && t->rx_buf) -- return -EPERM; -- -- w = spi->chip_select << 10; -- w |= CS_CMD; -- -- if (t->tx_buf) { -- const u8 *buf = t->tx_buf; -- -- /* NOTE: DMA could be used for TX transfers */ -- -- /* write one or two bytes at a time */ -- while (len >= 1) { -- /* tx bit 15 is first sent; we byteswap multibyte words -- * (msb-first) on the way out from memory. -- */ -- val = *buf++; -- if (bits > 8) { -- bytes = 2; -- val |= *buf++ << 8; -- } else -- bytes = 1; -- val <<= 16 - bits; -- --#ifdef VERBOSE -- pr_debug("%s: write-%d =%04x\n", -- spi->dev.bus_id, bits, val); --#endif -- if (wait_uwire_csr_flag(CSRB, 0, 0)) -- goto eio; -- -- uwire_write_reg(UWIRE_TDR, val); -- -- /* start write */ -- val = START | w | (bits << 5); -- -- uwire_write_reg(UWIRE_CSR, val); -- len -= bytes; -- -- /* Wait till write actually starts. -- * This is needed with MPU clock 60+ MHz. -- * REVISIT: we may not have time to catch it... -- */ -- if (wait_uwire_csr_flag(CSRB, CSRB, 1)) -- goto eio; -- -- status += bytes; -- } -- -- /* REVISIT: save this for later to get more i/o overlap */ -- if (wait_uwire_csr_flag(CSRB, 0, 0)) -- goto eio; -- -- } else if (t->rx_buf) { -- u8 *buf = t->rx_buf; -- -- /* read one or two bytes at a time */ -- while (len) { -- if (bits > 8) { -- bytes = 2; -- } else -- bytes = 1; -- -- /* start read */ -- val = START | w | (bits << 0); -- uwire_write_reg(UWIRE_CSR, val); -- len -= bytes; -- -- /* Wait till read actually starts */ -- (void) wait_uwire_csr_flag(CSRB, CSRB, 1); -- -- if (wait_uwire_csr_flag(RDRB | CSRB, -- RDRB, 0)) -- goto eio; -- -- /* rx bit 0 is last received; multibyte words will -- * be properly byteswapped on the way to memory. -- */ -- val = uwire_read_reg(UWIRE_RDR); -- val &= (1 << bits) - 1; -- *buf++ = (u8) val; -- if (bytes == 2) -- *buf++ = val >> 8; -- status += bytes; --#ifdef VERBOSE -- pr_debug("%s: read-%d =%04x\n", -- spi->dev.bus_id, bits, val); --#endif -- -- } -- } -- return status; --eio: -- return -EIO; --} -- --static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) --{ -- struct uwire_state *ust = spi->controller_state; -- struct uwire_spi *uwire; -- unsigned flags = 0; -- unsigned bits; -- unsigned hz; -- unsigned long rate; -- int div1_idx; -- int div1; -- int div2; -- int status; -- -- uwire = spi_master_get_devdata(spi->master); -- -- if (spi->chip_select > 3) { -- pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select); -- status = -ENODEV; -- goto done; -- } -- -- bits = spi->bits_per_word; -- if (t != NULL && t->bits_per_word) -- bits = t->bits_per_word; -- if (!bits) -- bits = 8; -- -- if (bits > 16) { -- pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits); -- status = -ENODEV; -- goto done; -- } -- ust->bits_per_word = bits; -- -- /* mode 0..3, clock inverted separately; -- * standard nCS signaling; -- * don't treat DI=high as "not ready" -- */ -- if (spi->mode & SPI_CS_HIGH) -- flags |= UWIRE_CS_ACTIVE_HIGH; -- -- if (spi->mode & SPI_CPOL) -- flags |= UWIRE_CLK_INVERTED; -- -- switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { -- case SPI_MODE_0: -- case SPI_MODE_3: -- flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE; -- break; -- case SPI_MODE_1: -- case SPI_MODE_2: -- flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE; -- break; -- } -- -- /* assume it's already enabled */ -- rate = clk_get_rate(uwire->ck); -- -- hz = spi->max_speed_hz; -- if (t != NULL && t->speed_hz) -- hz = t->speed_hz; -- -- if (!hz) { -- pr_debug("%s: zero speed?\n", spi->dev.bus_id); -- status = -EINVAL; -- goto done; -- } -- -- /* F_INT = mpu_xor_clk / DIV1 */ -- for (div1_idx = 0; div1_idx < 4; div1_idx++) { -- switch (div1_idx) { -- case 0: -- div1 = 2; -- break; -- case 1: -- div1 = 4; -- break; -- case 2: -- div1 = 7; -- break; -- default: -- case 3: -- div1 = 10; -- break; -- } -- div2 = (rate / div1 + hz - 1) / hz; -- if (div2 <= 8) -- break; -- } -- if (div1_idx == 4) { -- pr_debug("%s: lowest clock %ld, need %d\n", -- spi->dev.bus_id, rate / 10 / 8, hz); - status = -EDOM; - goto done; - status = -EDOM; - goto done; -- } -- -- /* we have to cache this and reset in uwire_chipselect as this is a -- * global parameter and another uwire device can change it under -- * us */ -- ust->div1_idx = div1_idx; -- uwire_set_clk1_div(div1_idx); -- -- rate /= div1; -- -- switch (div2) { -- case 0: -- case 1: -- case 2: -- flags |= UWIRE_FREQ_DIV_2; -- rate /= 2; -- break; -- case 3: -- case 4: -- flags |= UWIRE_FREQ_DIV_4; -- rate /= 4; -- break; -- case 5: -- case 6: -- case 7: -- case 8: -- flags |= UWIRE_FREQ_DIV_8; -- rate /= 8; -- break; -- } -- omap_uwire_configure_mode(spi->chip_select, flags); -- pr_debug("%s: uwire flags %02x, armxor %lu KHz, SCK %lu KHz\n", -- __FUNCTION__, flags, -- clk_get_rate(uwire->ck) / 1000, -- rate / 1000); -- status = 0; --done: -- return status; --} -- --static int uwire_setup(struct spi_device *spi) --{ -- struct uwire_state *ust = spi->controller_state; -- -- if (ust == NULL) { -- ust = kzalloc(sizeof(*ust), GFP_KERNEL); -- if (ust == NULL) -- return -ENOMEM; -- spi->controller_state = ust; -- } -- -- return uwire_setup_transfer(spi, NULL); --} -- - static void uwire_cleanup(const struct spi_device *spi) -static void uwire_cleanup(struct spi_device *spi) --{ -- kfree(spi->controller_state); --} -- --static void uwire_off(struct uwire_spi *uwire) --{ -- uwire_write_reg(UWIRE_SR3, 0); -- clk_disable(uwire->ck); -- clk_put(uwire->ck); -- spi_master_put(uwire->bitbang.master); --} -- --static int uwire_probe(struct platform_device *pdev) --{ -- struct spi_master *master; -- struct uwire_spi *uwire; -- int status; -- -- master = spi_alloc_master(&pdev->dev, sizeof *uwire); -- if (!master) -- return -ENODEV; -- -- uwire = spi_master_get_devdata(master); -- dev_set_drvdata(&pdev->dev, uwire); -- -- uwire->ck = clk_get(&pdev->dev, "armxor_ck"); -- if (!uwire->ck || IS_ERR(uwire->ck)) { -- dev_dbg(&pdev->dev, "no mpu_xor_clk ?\n"); -- spi_master_put(master); -- return -ENODEV; -- } -- clk_enable(uwire->ck); -- -- if (cpu_is_omap730()) -- uwire_idx_shift = 1; -- else -- uwire_idx_shift = 2; -- -- uwire_write_reg(UWIRE_SR3, 1); -- -- master->bus_num = 2; /* "official" */ -- master->num_chipselect = 4; -- master->setup = uwire_setup; -- master->cleanup = uwire_cleanup; -- -- uwire->bitbang.master = master; -- uwire->bitbang.chipselect = uwire_chipselect; -- uwire->bitbang.setup_transfer = uwire_setup_transfer; -- uwire->bitbang.txrx_bufs = uwire_txrx; -- -- status = spi_bitbang_start(&uwire->bitbang); -- if (status < 0) -- uwire_off(uwire); -- return status; --} -- --static int uwire_remove(struct platform_device *pdev) --{ -- struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev); -- int status; -- -- // FIXME remove all child devices, somewhere ... -- -- status = spi_bitbang_stop(&uwire->bitbang); -- uwire_off(uwire); -- return status; --} -- --static struct platform_driver uwire_driver = { -- .driver = { -- .name = "omap_uwire", -- .bus = &platform_bus_type, -- .owner = THIS_MODULE, -- }, -- .probe = uwire_probe, -- .remove = uwire_remove, -- // suspend ... unuse ck -- // resume ... use ck --}; -- --static int __init omap_uwire_init(void) --{ -- /* FIXME move these into the relevant board init code. also, include -- * H3 support; it uses tsc2101 like H2 (on a different chipselect). -- */ -- -- if (machine_is_omap_h2()) { -- /* defaults: W21 SDO, U18 SDI, V19 SCL */ -- omap_cfg_reg(N14_1610_UWIRE_CS0); -- omap_cfg_reg(N15_1610_UWIRE_CS1); -- } -- if (machine_is_omap_perseus2()) { -- /* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */ -- int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000; -- omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9); -- } -- -- return platform_driver_register(&uwire_driver); --} -- --static void __exit omap_uwire_exit(void) --{ -- platform_driver_unregister(&uwire_driver); --} -- --subsys_initcall(omap_uwire_init); --module_exit(omap_uwire_exit); -- --MODULE_LICENSE("GPL"); - diff --cc drivers/video/Kconfig index 64ad6472db5,bda71ad9a0a..e1f4d0f9608 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@@ -1657,9 -1666,9 +1668,5 @@@ if FB || SGI_NEWPORT_CONSOL source "drivers/video/logo/Kconfig" endif - if SYSFS - source "drivers/video/backlight/Kconfig" -if ARCH_OMAP - source "drivers/video/omap/Kconfig" --endif -- endmenu diff --cc drivers/video/backlight/Kconfig index 91584490410,47d15b5d985..73ff033996e --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@@ -66,11 -56,10 +56,19 @@@ config BACKLIGHT_HP68 If you have a HP Jornada 680, say y to enable the backlight driver. +config BACKLIGHT_OMAP + tristate "OMAP LCD Backlight" + depends on BACKLIGHT_DEVICE && (ARCH_OMAP1 || ARCH_OMAP2) + default y + help + This driver controls the LCD backlight level and power + for the PWL module of OMAP processors. Say Y if you plan + to use power saving. ++ + config BACKLIGHT_PROGEAR + tristate "Frontpath ProGear Backlight Driver" + depends on BACKLIGHT_CLASS_DEVICE && PCI && X86 + default n + help + If you have a Frontpath ProGear say Y to enable the + backlight driver. diff --cc drivers/video/backlight/Makefile index c2e0b879fa5,0c3ce46f509..97ad8366f4f --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@@ -5,4 -5,4 +5,5 @@@ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) + obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o +obj-$(CONFIG_BACKLIGHT_OMAP) += omap_bl.o + obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o diff --cc include/linux/i2c-id.h index 8c8a9ed92f2,6bead729e96..23c19bcfdac --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@@ -115,9 -115,11 +115,13 @@@ #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ #define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ + #define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ + #define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ + + #define I2C_DRIVERID_MISC 99 /* Whatever until sorted out */ +#define I2C_DRIVERID_MISC 99 /* Whatever until sorted out */ + #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ #define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ diff --cc include/linux/spi/ads7846.h index c371475829b,3387e44dfd1..adb3dafd33e --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@@ -5,17 -5,17 +5,9 @@@ * * It's OK if the min/max values are zero. */ --enum ads7846_filter { -- ADS7846_FILTER_OK, -- ADS7846_FILTER_REPEAT, -- ADS7846_FILTER_IGNORE, --}; -- struct ads7846_platform_data { u16 model; /* 7843, 7845, 7846. */ u16 vref_delay_usecs; /* 0 for external vref; etc */ - int keep_vref_on : 1; /* set to keep vref on for differential - int keep_vref_on:1; /* set to keep vref on for differential -- * measurements as well */ u16 x_plate_ohms; u16 y_plate_ohms; @@@ -29,9 -29,9 +21,5 @@@ u16 debounce_rep; /* additional consecutive good readings * required after the first two */ int (*get_pendown_state)(void); -- int (*filter_init) (struct ads7846_platform_data *pdata, -- void **filter_data); -- int (*filter) (void *filter_data, int data_idx, int *val); -- void (*filter_cleanup)(void *filter_data); };