From f23d4911319fdebffd0529b31bb66d324ef287e6 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 14:43:25 +0800 Subject: [ARM] pxa: add platform device ID table to pxa i2c driver Signed-off-by: Eric Miao --- arch/arm/mach-pxa/devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index d245e59c51b1..899418e18a21 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -287,7 +287,7 @@ static struct resource pxa3xx_resources_i2c_power[] = { }; struct platform_device pxa3xx_device_i2c_power = { - .name = "pxa2xx-i2c", + .name = "pxa3xx-pwri2c", .id = 1, .resource = pxa3xx_resources_i2c_power, .num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power), -- cgit v1.2.3 From f0a83701399123b0e95cc4d949fcccf9941fd190 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 15:03:11 +0800 Subject: [ARM] pxa: move mach/i2c.h to plat/i2c.h Signed-off-by: Paul Shen Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cm-x300.c | 2 +- arch/arm/mach-pxa/corgi.c | 2 +- arch/arm/mach-pxa/csb726.c | 2 +- arch/arm/mach-pxa/devices.c | 2 +- arch/arm/mach-pxa/em-x270.c | 2 +- arch/arm/mach-pxa/ezx.c | 2 +- arch/arm/mach-pxa/imote2.c | 2 +- arch/arm/mach-pxa/include/mach/i2c.h | 82 ------------------------------------ arch/arm/mach-pxa/littleton.c | 2 +- arch/arm/mach-pxa/magician.c | 2 +- arch/arm/mach-pxa/mainstone.c | 2 +- arch/arm/mach-pxa/mioa701.c | 2 +- arch/arm/mach-pxa/pcm990-baseboard.c | 2 +- arch/arm/mach-pxa/poodle.c | 2 +- arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/pxa3xx.c | 2 +- arch/arm/mach-pxa/saar.c | 2 +- arch/arm/mach-pxa/spitz.c | 2 +- arch/arm/mach-pxa/tosa.c | 2 +- arch/arm/mach-pxa/trizeps4.c | 2 +- arch/arm/mach-pxa/viper.c | 2 +- arch/arm/mach-pxa/zylonite_pxa300.c | 2 +- arch/arm/plat-pxa/include/plat/i2c.h | 82 ++++++++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-pxa.c | 2 +- 24 files changed, 104 insertions(+), 104 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/i2c.h create mode 100644 arch/arm/plat-pxa/include/plat/i2c.h (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index a9f48b1cb54a..a97f87a90d0d 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 930e364ccde9..f04e50583289 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -42,7 +42,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index 2b289f83a61a..f95b32d98993 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 899418e18a21..d3c3b7b025ae 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index bc0f73fbd4ca..3503f523070b 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 7db966dc29ce..4ce63b4e15c5 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/imote2.c b/arch/arm/mach-pxa/imote2.c index 2121309b2474..821e65a4097e 100644 --- a/arch/arm/mach-pxa/imote2.c +++ b/arch/arm/mach-pxa/imote2.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/include/mach/i2c.h b/arch/arm/mach-pxa/include/mach/i2c.h deleted file mode 100644 index 1a9f65e6ec0f..000000000000 --- a/arch/arm/mach-pxa/include/mach/i2c.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * i2c_pxa.h - * - * Copyright (C) 2002 Intrinsyc Software Inc. - * - * 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. - * - */ -#ifndef _I2C_PXA_H_ -#define _I2C_PXA_H_ - -#if 0 -#define DEF_TIMEOUT 3 -#else -/* need a longer timeout if we're dealing with the fact we may well be - * looking at a multi-master environment -*/ -#define DEF_TIMEOUT 32 -#endif - -#define BUS_ERROR (-EREMOTEIO) -#define XFER_NAKED (-ECONNREFUSED) -#define I2C_RETRY (-2000) /* an error has occurred retry transmit */ - -/* ICR initialize bit values -* -* 15. FM 0 (100 Khz operation) -* 14. UR 0 (No unit reset) -* 13. SADIE 0 (Disables the unit from interrupting on slave addresses -* matching its slave address) -* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration -* in master mode) -* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode) -* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent) -* 9. IRFIE 1 (Enable interrupts from full buffer received) -* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty) -* 7. GCD 1 (Disables i2c unit response to general call messages as a slave) -* 6. IUE 0 (Disable unit until we change settings) -* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL) -* 4. MA 0 (Only send stop with the ICR stop bit) -* 3. TB 0 (We are not transmitting a byte initially) -* 2. ACKNAK 0 (Send an ACK after the unit receives a byte) -* 1. STOP 0 (Do not send a STOP) -* 0. START 0 (Do not send a START) -* -*/ -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) - -/* I2C status register init values - * - * 10. BED 1 (Clear bus error detected) - * 9. SAD 1 (Clear slave address detected) - * 7. IRF 1 (Clear IDBR Receive Full) - * 6. ITE 1 (Clear IDBR Transmit Empty) - * 5. ALD 1 (Clear Arbitration Loss Detected) - * 4. SSD 1 (Clear Slave Stop Detected) - */ -#define I2C_ISR_INIT 0x7FF /* status register init */ - -struct i2c_slave_client; - -struct i2c_pxa_platform_data { - unsigned int slave_addr; - struct i2c_slave_client *slave; - unsigned int class; - unsigned int use_pio :1; - unsigned int fast_mode :1; -}; - -extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info); - -#ifdef CONFIG_PXA27x -extern void pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info); -#endif - -#ifdef CONFIG_PXA3xx -extern void pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info); -#endif - -#endif diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index c872b9feb4d4..ad5378b1af94 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index c899bbd94dc0..5a9df973935d 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index a6c8429e975f..f4dabf0273ca 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index ff8052ce0a05..804c25c4a064 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 6c12b5a3132f..095521e9ee24 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 036bbde4d221..74f4ce600ca4 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index a425ec71e657..c54ad8b3343c 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "generic.h" #include "devices.h" diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index b02d4544dc95..462503a2e791 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "generic.h" #include "devices.h" diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index ff8239991430..8241a63ea589 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include "devices.h" diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 5a45fe340a10..229f48577d5e 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index a0bd46ef5d30..168267a5dfb3 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index f79c9cb70ae4..825f540176d2 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include "generic.h" #include "devices.h" diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index dd031cc41847..d33c232b686c 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index c256c57642c0..cefd1c0a854a 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include "generic.h" diff --git a/arch/arm/plat-pxa/include/plat/i2c.h b/arch/arm/plat-pxa/include/plat/i2c.h new file mode 100644 index 000000000000..1a9f65e6ec0f --- /dev/null +++ b/arch/arm/plat-pxa/include/plat/i2c.h @@ -0,0 +1,82 @@ +/* + * i2c_pxa.h + * + * Copyright (C) 2002 Intrinsyc Software Inc. + * + * 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. + * + */ +#ifndef _I2C_PXA_H_ +#define _I2C_PXA_H_ + +#if 0 +#define DEF_TIMEOUT 3 +#else +/* need a longer timeout if we're dealing with the fact we may well be + * looking at a multi-master environment +*/ +#define DEF_TIMEOUT 32 +#endif + +#define BUS_ERROR (-EREMOTEIO) +#define XFER_NAKED (-ECONNREFUSED) +#define I2C_RETRY (-2000) /* an error has occurred retry transmit */ + +/* ICR initialize bit values +* +* 15. FM 0 (100 Khz operation) +* 14. UR 0 (No unit reset) +* 13. SADIE 0 (Disables the unit from interrupting on slave addresses +* matching its slave address) +* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration +* in master mode) +* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode) +* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent) +* 9. IRFIE 1 (Enable interrupts from full buffer received) +* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty) +* 7. GCD 1 (Disables i2c unit response to general call messages as a slave) +* 6. IUE 0 (Disable unit until we change settings) +* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL) +* 4. MA 0 (Only send stop with the ICR stop bit) +* 3. TB 0 (We are not transmitting a byte initially) +* 2. ACKNAK 0 (Send an ACK after the unit receives a byte) +* 1. STOP 0 (Do not send a STOP) +* 0. START 0 (Do not send a START) +* +*/ +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) + +/* I2C status register init values + * + * 10. BED 1 (Clear bus error detected) + * 9. SAD 1 (Clear slave address detected) + * 7. IRF 1 (Clear IDBR Receive Full) + * 6. ITE 1 (Clear IDBR Transmit Empty) + * 5. ALD 1 (Clear Arbitration Loss Detected) + * 4. SSD 1 (Clear Slave Stop Detected) + */ +#define I2C_ISR_INIT 0x7FF /* status register init */ + +struct i2c_slave_client; + +struct i2c_pxa_platform_data { + unsigned int slave_addr; + struct i2c_slave_client *slave; + unsigned int class; + unsigned int use_pio :1; + unsigned int fast_mode :1; +}; + +extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info); + +#ifdef CONFIG_PXA27x +extern void pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info); +#endif + +#ifdef CONFIG_PXA3xx +extern void pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info); +#endif + +#endif diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index e4ee8835b97f..035a6c7e59df 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -36,7 +36,7 @@ #include #include -#include +#include /* * I2C register offsets will be shifted 0 or 1 bit left, depending on -- cgit v1.2.3 From 1a77920e4cbe508c8dc40fef1d0beb21aac8cc17 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 15:34:54 +0800 Subject: [ARM] pxa: add I2C (TWSI) devices to pxa168/pxa910 Signed-off-by: Paul Shen Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/mfp-pxa168.h | 4 ++++ arch/arm/mach-mmp/include/mach/pxa168.h | 24 ++++++++++++++++++++++++ arch/arm/mach-mmp/include/mach/pxa910.h | 24 ++++++++++++++++++++++++ arch/arm/mach-mmp/pxa168.c | 6 ++++++ arch/arm/mach-mmp/pxa910.c | 6 ++++++ 5 files changed, 64 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h index 2e914649b9e4..dc4226371d64 100644 --- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h +++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h @@ -253,6 +253,10 @@ #define GPIO58_LCD_PCLK_WR MFP_CFG(GPIO58, AF1) #define GPIO85_LCD_VSYNC MFP_CFG(GPIO85, AF1) +/* I2C */ +#define GPIO105_CI2C_SDA MFP_CFG(GPIO105, AF1) +#define GPIO106_CI2C_SCL MFP_CFG(GPIO106, AF1) + /* I2S */ #define GPIO113_I2S_MCLK MFP_CFG(GPIO113,AF6) #define GPIO114_I2S_FRM MFP_CFG(GPIO114,AF1) diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h index ef0a8a2076e9..bfdd6299dff5 100644 --- a/arch/arm/mach-mmp/include/mach/pxa168.h +++ b/arch/arm/mach-mmp/include/mach/pxa168.h @@ -1,10 +1,14 @@ #ifndef __ASM_MACH_PXA168_H #define __ASM_MACH_PXA168_H +#include #include +#include extern struct pxa_device_desc pxa168_device_uart1; extern struct pxa_device_desc pxa168_device_uart2; +extern struct pxa_device_desc pxa168_device_twsi0; +extern struct pxa_device_desc pxa168_device_twsi1; static inline int pxa168_add_uart(int id) { @@ -20,4 +24,24 @@ static inline int pxa168_add_uart(int id) return pxa_register_device(d, NULL, 0); } + +static inline int pxa168_add_twsi(int id, struct i2c_pxa_platform_data *data, + struct i2c_board_info *info, unsigned size) +{ + struct pxa_device_desc *d = NULL; + int ret; + + switch (id) { + case 0: d = &pxa168_device_twsi0; break; + case 1: d = &pxa168_device_twsi1; break; + default: + return -EINVAL; + } + + ret = i2c_register_board_info(id, info, size); + if (ret) + return ret; + + return pxa_register_device(d, data, sizeof(*data)); +} #endif /* __ASM_MACH_PXA168_H */ diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h index b7aeaf574c36..a0f0cbee1c07 100644 --- a/arch/arm/mach-mmp/include/mach/pxa910.h +++ b/arch/arm/mach-mmp/include/mach/pxa910.h @@ -1,10 +1,14 @@ #ifndef __ASM_MACH_PXA910_H #define __ASM_MACH_PXA910_H +#include #include +#include extern struct pxa_device_desc pxa910_device_uart1; extern struct pxa_device_desc pxa910_device_uart2; +extern struct pxa_device_desc pxa910_device_twsi0; +extern struct pxa_device_desc pxa910_device_twsi1; static inline int pxa910_add_uart(int id) { @@ -20,4 +24,24 @@ static inline int pxa910_add_uart(int id) return pxa_register_device(d, NULL, 0); } + +static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data, + struct i2c_board_info *info, unsigned size) +{ + struct pxa_device_desc *d = NULL; + int ret; + + switch (id) { + case 0: d = &pxa910_device_twsi0; break; + case 1: d = &pxa910_device_twsi1; break; + default: + return -EINVAL; + } + + ret = i2c_register_board_info(id, info, size); + if (ret) + return ret; + + return pxa_register_device(d, data, sizeof(*data)); +} #endif /* __ASM_MACH_PXA910_H */ diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index ae924468658c..e0729e34f7ad 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -65,11 +65,15 @@ void __init pxa168_init_irq(void) /* APB peripheral clocks */ static APBC_CLK(uart1, PXA168_UART1, 1, 14745600); static APBC_CLK(uart2, PXA168_UART2, 1, 14745600); +static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000); +static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000); /* device and clock bindings */ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL), INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL), + INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL), + INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL), }; static int __init pxa168_init(void) @@ -109,3 +113,5 @@ struct sys_timer pxa168_timer = { /* on-chip devices */ PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22); PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24); +PXA168_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28); +PXA168_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28); diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index 453f8f7758bf..b97328b96ce7 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c @@ -103,11 +103,15 @@ void __init pxa910_init_irq(void) /* APB peripheral clocks */ static APBC_CLK(uart1, PXA910_UART0, 1, 14745600); static APBC_CLK(uart2, PXA910_UART1, 1, 14745600); +static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000); +static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000); /* device and clock bindings */ static struct clk_lookup pxa910_clkregs[] = { INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL), INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL), + INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL), + INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL), }; static int __init pxa910_init(void) @@ -156,3 +160,5 @@ struct sys_timer pxa910_timer = { */ PXA910_DEVICE(uart1, "pxa2xx-uart", 0, UART2, 0xd4017000, 0x30, 21, 22); PXA910_DEVICE(uart2, "pxa2xx-uart", 1, UART3, 0xd4018000, 0x30, 23, 24); +PXA910_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28); +PXA910_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28); -- cgit v1.2.3 From 3d2a98cd5e17052f461390c72efe1076c18fd62d Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 15:59:03 +0800 Subject: [ARM] pxa: simplify secondary PWM handling and use platform_device_id table Signed-off-by: Eric Miao --- arch/arm/mach-pxa/pwm.c | 116 ++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 67 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index fcdd374437a8..dec6f2c8dbf9 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -21,6 +21,16 @@ #include +#define HAS_SECONDARY_PWM 0x10 + +static const struct platform_device_id pwm_id_table[] = { + /* PWM has_secondary_pwm? */ + { "pxa25x-pwm", 0 }, + { "pxa27x-pwm", HAS_SECONDARY_PWM }, + { }, +}; +MODULE_DEVICE_TABLE(platform, pwm_id_table); + /* PWM registers and bits definitions */ #define PWMCR (0x00) #define PWMDCR (0x04) @@ -31,7 +41,8 @@ struct pwm_device { struct list_head node; - struct platform_device *pdev; + struct pwm_device *secondary; + struct platform_device *pdev; const char *label; struct clk *clk; @@ -159,17 +170,17 @@ static inline void __add_pwm(struct pwm_device *pwm) mutex_unlock(&pwm_lock); } -static struct pwm_device *pwm_probe(struct platform_device *pdev, - unsigned int pwm_id, struct pwm_device *parent_pwm) +static int __devinit pwm_probe(struct platform_device *pdev) { - struct pwm_device *pwm; + struct platform_device_id *id = platform_get_device_id(pdev); + struct pwm_device *pwm, *secondary = NULL; struct resource *r; int ret = 0; pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); if (pwm == NULL) { dev_err(&pdev->dev, "failed to allocate memory\n"); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } pwm->clk = clk_get(&pdev->dev, NULL); @@ -180,16 +191,9 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev, pwm->clk_enabled = 0; pwm->use_count = 0; - pwm->pwm_id = pwm_id; + pwm->pwm_id = pdev->id; pwm->pdev = pdev; - if (parent_pwm != NULL) { - /* registers for the second PWM has offset of 0x10 */ - pwm->mmio_base = parent_pwm->mmio_base + 0x10; - __add_pwm(pwm); - return pwm; - } - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { dev_err(&pdev->dev, "no memory resource defined\n"); @@ -211,9 +215,27 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev, goto err_free_mem; } + if (id->driver_data & HAS_SECONDARY_PWM) { + secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (secondary == NULL) { + ret = -ENOMEM; + goto err_free_mem; + } + + *secondary = *pwm; + pwm->secondary = secondary; + + /* registers for the second PWM has offset of 0x10 */ + secondary->mmio_base = pwm->mmio_base + 0x10; + secondary->pwm_id = pdev->id + 2; + } + __add_pwm(pwm); + if (secondary) + __add_pwm(secondary); + platform_set_drvdata(pdev, pwm); - return pwm; + return 0; err_free_mem: release_mem_region(r->start, r->end - r->start + 1); @@ -221,32 +243,7 @@ err_free_clk: clk_put(pwm->clk); err_free: kfree(pwm); - return ERR_PTR(ret); -} - -static int __devinit pxa25x_pwm_probe(struct platform_device *pdev) -{ - struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL); - - if (IS_ERR(pwm)) - return PTR_ERR(pwm); - - return 0; -} - -static int __devinit pxa27x_pwm_probe(struct platform_device *pdev) -{ - struct pwm_device *pwm; - - pwm = pwm_probe(pdev, pdev->id, NULL); - if (IS_ERR(pwm)) - return PTR_ERR(pwm); - - pwm = pwm_probe(pdev, pdev->id + 2, pwm); - if (IS_ERR(pwm)) - return PTR_ERR(pwm); - - return 0; + return ret; } static int __devexit pwm_remove(struct platform_device *pdev) @@ -259,6 +256,12 @@ static int __devexit pwm_remove(struct platform_device *pdev) return -ENODEV; mutex_lock(&pwm_lock); + + if (pwm->secondary) { + list_del(&pwm->secondary->node); + kfree(pwm->secondary); + } + list_del(&pwm->node); mutex_unlock(&pwm_lock); @@ -272,46 +275,25 @@ static int __devexit pwm_remove(struct platform_device *pdev) return 0; } -static struct platform_driver pxa25x_pwm_driver = { +static struct platform_driver pwm_driver = { .driver = { .name = "pxa25x-pwm", + .owner = THIS_MODULE, }, - .probe = pxa25x_pwm_probe, - .remove = __devexit_p(pwm_remove), -}; - -static struct platform_driver pxa27x_pwm_driver = { - .driver = { - .name = "pxa27x-pwm", - }, - .probe = pxa27x_pwm_probe, + .probe = pwm_probe, .remove = __devexit_p(pwm_remove), + .id_table = pwm_id_table, }; static int __init pwm_init(void) { - int ret = 0; - - ret = platform_driver_register(&pxa25x_pwm_driver); - if (ret) { - printk(KERN_ERR "failed to register pxa25x_pwm_driver\n"); - return ret; - } - - ret = platform_driver_register(&pxa27x_pwm_driver); - if (ret) { - printk(KERN_ERR "failed to register pxa27x_pwm_driver\n"); - return ret; - } - - return ret; + return platform_driver_register(&pwm_driver); } arch_initcall(pwm_init); static void __exit pwm_exit(void) { - platform_driver_unregister(&pxa25x_pwm_driver); - platform_driver_unregister(&pxa27x_pwm_driver); + platform_driver_unregister(&pwm_driver); } module_exit(pwm_exit); -- cgit v1.2.3 From a757ad8b391adb2129f8357545aaa678099df473 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 18:51:31 +0800 Subject: [ARM] pxa: allow PWM ID base number to be specified in pwm_id_table PWMs on PXA168/910 start at number 1 instead of 0, (i.e. PWM1/2/3/4 instead of PWM0/1/2/3 on PXA25x/PXA27x/PXA3xx). Allow this number to be specified in pwm_id_table. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/pwm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index dec6f2c8dbf9..5513c51ff984 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -22,11 +22,12 @@ #include #define HAS_SECONDARY_PWM 0x10 +#define PWM_ID_BASE(d) ((d) & 0xf) static const struct platform_device_id pwm_id_table[] = { /* PWM has_secondary_pwm? */ { "pxa25x-pwm", 0 }, - { "pxa27x-pwm", HAS_SECONDARY_PWM }, + { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM }, { }, }; MODULE_DEVICE_TABLE(platform, pwm_id_table); @@ -191,7 +192,7 @@ static int __devinit pwm_probe(struct platform_device *pdev) pwm->clk_enabled = 0; pwm->use_count = 0; - pwm->pwm_id = pdev->id; + pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id; pwm->pdev = pdev; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.3 From a71ef16327a534a88fb1277d28dcd362dbb1992f Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 16:09:21 +0800 Subject: [ARM] pxa: build pwm.c according to HAVE_PWM instead of PXA_PWM The PXA_PWM config option is really redundant since the introduction of HAVE_PWM, replace that with HAVE_PWM to avoid confusion. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 6 ------ arch/arm/mach-pxa/Makefile | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 17d3fbd368a3..47747f96f125 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -505,12 +505,6 @@ config PXA_SSP help Enable support for PXA2xx SSP ports -config PXA_PWM - tristate - default BACKLIGHT_PWM - help - Enable support for PXA2xx/PXA3xx PWM controllers - config TOSA_BT tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" depends on MACH_TOSA diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 682dbf4e14b0..4bcebf72074a 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -15,7 +15,7 @@ endif # Generic drivers that other drivers may depend upon obj-$(CONFIG_PXA_SSP) += ssp.o -obj-$(CONFIG_PXA_PWM) += pwm.o +obj-$(CONFIG_HAVE_PWM) += pwm.o # SoC-specific code obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o -- cgit v1.2.3 From 3852ac7113f313d96af80257a070fd8ab2eea5c6 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 16:28:02 +0800 Subject: [ARM] pxa: move pwm.c to common plat-pxa directory Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Makefile | 1 - arch/arm/mach-pxa/pwm.c | 301 --------------------------------------------- arch/arm/plat-pxa/Makefile | 2 + arch/arm/plat-pxa/pwm.c | 301 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 303 insertions(+), 302 deletions(-) delete mode 100644 arch/arm/mach-pxa/pwm.c create mode 100644 arch/arm/plat-pxa/pwm.c (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 4bcebf72074a..47d01572a04d 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -15,7 +15,6 @@ endif # Generic drivers that other drivers may depend upon obj-$(CONFIG_PXA_SSP) += ssp.o -obj-$(CONFIG_HAVE_PWM) += pwm.o # SoC-specific code obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c deleted file mode 100644 index 5513c51ff984..000000000000 --- a/arch/arm/mach-pxa/pwm.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/pwm.c - * - * simple driver for PWM (Pulse Width Modulator) controller - * - * 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. - * - * 2008-02-13 initial version - * eric miao - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define HAS_SECONDARY_PWM 0x10 -#define PWM_ID_BASE(d) ((d) & 0xf) - -static const struct platform_device_id pwm_id_table[] = { - /* PWM has_secondary_pwm? */ - { "pxa25x-pwm", 0 }, - { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM }, - { }, -}; -MODULE_DEVICE_TABLE(platform, pwm_id_table); - -/* PWM registers and bits definitions */ -#define PWMCR (0x00) -#define PWMDCR (0x04) -#define PWMPCR (0x08) - -#define PWMCR_SD (1 << 6) -#define PWMDCR_FD (1 << 10) - -struct pwm_device { - struct list_head node; - struct pwm_device *secondary; - struct platform_device *pdev; - - const char *label; - struct clk *clk; - int clk_enabled; - void __iomem *mmio_base; - - unsigned int use_count; - unsigned int pwm_id; -}; - -/* - * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE - * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE - */ -int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) -{ - unsigned long long c; - unsigned long period_cycles, prescale, pv, dc; - - if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) - return -EINVAL; - - c = clk_get_rate(pwm->clk); - c = c * period_ns; - do_div(c, 1000000000); - period_cycles = c; - - if (period_cycles < 1) - period_cycles = 1; - prescale = (period_cycles - 1) / 1024; - pv = period_cycles / (prescale + 1) - 1; - - if (prescale > 63) - return -EINVAL; - - if (duty_ns == period_ns) - dc = PWMDCR_FD; - else - dc = (pv + 1) * duty_ns / period_ns; - - /* NOTE: the clock to PWM has to be enabled first - * before writing to the registers - */ - clk_enable(pwm->clk); - __raw_writel(prescale, pwm->mmio_base + PWMCR); - __raw_writel(dc, pwm->mmio_base + PWMDCR); - __raw_writel(pv, pwm->mmio_base + PWMPCR); - clk_disable(pwm->clk); - - return 0; -} -EXPORT_SYMBOL(pwm_config); - -int pwm_enable(struct pwm_device *pwm) -{ - int rc = 0; - - if (!pwm->clk_enabled) { - rc = clk_enable(pwm->clk); - if (!rc) - pwm->clk_enabled = 1; - } - return rc; -} -EXPORT_SYMBOL(pwm_enable); - -void pwm_disable(struct pwm_device *pwm) -{ - if (pwm->clk_enabled) { - clk_disable(pwm->clk); - pwm->clk_enabled = 0; - } -} -EXPORT_SYMBOL(pwm_disable); - -static DEFINE_MUTEX(pwm_lock); -static LIST_HEAD(pwm_list); - -struct pwm_device *pwm_request(int pwm_id, const char *label) -{ - struct pwm_device *pwm; - int found = 0; - - mutex_lock(&pwm_lock); - - list_for_each_entry(pwm, &pwm_list, node) { - if (pwm->pwm_id == pwm_id) { - found = 1; - break; - } - } - - if (found) { - if (pwm->use_count == 0) { - pwm->use_count++; - pwm->label = label; - } else - pwm = ERR_PTR(-EBUSY); - } else - pwm = ERR_PTR(-ENOENT); - - mutex_unlock(&pwm_lock); - return pwm; -} -EXPORT_SYMBOL(pwm_request); - -void pwm_free(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - - if (pwm->use_count) { - pwm->use_count--; - pwm->label = NULL; - } else - pr_warning("PWM device already freed\n"); - - mutex_unlock(&pwm_lock); -} -EXPORT_SYMBOL(pwm_free); - -static inline void __add_pwm(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - list_add_tail(&pwm->node, &pwm_list); - mutex_unlock(&pwm_lock); -} - -static int __devinit pwm_probe(struct platform_device *pdev) -{ - struct platform_device_id *id = platform_get_device_id(pdev); - struct pwm_device *pwm, *secondary = NULL; - struct resource *r; - int ret = 0; - - pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); - if (pwm == NULL) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return -ENOMEM; - } - - pwm->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(pwm->clk)) { - ret = PTR_ERR(pwm->clk); - goto err_free; - } - pwm->clk_enabled = 0; - - pwm->use_count = 0; - pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id; - pwm->pdev = pdev; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) { - dev_err(&pdev->dev, "no memory resource defined\n"); - ret = -ENODEV; - goto err_free_clk; - } - - r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); - if (r == NULL) { - dev_err(&pdev->dev, "failed to request memory resource\n"); - ret = -EBUSY; - goto err_free_clk; - } - - pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); - if (pwm->mmio_base == NULL) { - dev_err(&pdev->dev, "failed to ioremap() registers\n"); - ret = -ENODEV; - goto err_free_mem; - } - - if (id->driver_data & HAS_SECONDARY_PWM) { - secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); - if (secondary == NULL) { - ret = -ENOMEM; - goto err_free_mem; - } - - *secondary = *pwm; - pwm->secondary = secondary; - - /* registers for the second PWM has offset of 0x10 */ - secondary->mmio_base = pwm->mmio_base + 0x10; - secondary->pwm_id = pdev->id + 2; - } - - __add_pwm(pwm); - if (secondary) - __add_pwm(secondary); - - platform_set_drvdata(pdev, pwm); - return 0; - -err_free_mem: - release_mem_region(r->start, r->end - r->start + 1); -err_free_clk: - clk_put(pwm->clk); -err_free: - kfree(pwm); - return ret; -} - -static int __devexit pwm_remove(struct platform_device *pdev) -{ - struct pwm_device *pwm; - struct resource *r; - - pwm = platform_get_drvdata(pdev); - if (pwm == NULL) - return -ENODEV; - - mutex_lock(&pwm_lock); - - if (pwm->secondary) { - list_del(&pwm->secondary->node); - kfree(pwm->secondary); - } - - list_del(&pwm->node); - mutex_unlock(&pwm_lock); - - iounmap(pwm->mmio_base); - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, r->end - r->start + 1); - - clk_put(pwm->clk); - kfree(pwm); - return 0; -} - -static struct platform_driver pwm_driver = { - .driver = { - .name = "pxa25x-pwm", - .owner = THIS_MODULE, - }, - .probe = pwm_probe, - .remove = __devexit_p(pwm_remove), - .id_table = pwm_id_table, -}; - -static int __init pwm_init(void) -{ - return platform_driver_register(&pwm_driver); -} -arch_initcall(pwm_init); - -static void __exit pwm_exit(void) -{ - platform_driver_unregister(&pwm_driver); -} -module_exit(pwm_exit); - -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile index 8f2c4c7fbd48..0264bfb0ca4f 100644 --- a/arch/arm/plat-pxa/Makefile +++ b/arch/arm/plat-pxa/Makefile @@ -7,3 +7,5 @@ obj-y := dma.o obj-$(CONFIG_GENERIC_GPIO) += gpio.o obj-$(CONFIG_PXA3xx) += mfp.o obj-$(CONFIG_ARCH_MMP) += mfp.o + +obj-$(CONFIG_HAVE_PWM) += pwm.o diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c new file mode 100644 index 000000000000..5513c51ff984 --- /dev/null +++ b/arch/arm/plat-pxa/pwm.c @@ -0,0 +1,301 @@ +/* + * linux/arch/arm/mach-pxa/pwm.c + * + * simple driver for PWM (Pulse Width Modulator) controller + * + * 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. + * + * 2008-02-13 initial version + * eric miao + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define HAS_SECONDARY_PWM 0x10 +#define PWM_ID_BASE(d) ((d) & 0xf) + +static const struct platform_device_id pwm_id_table[] = { + /* PWM has_secondary_pwm? */ + { "pxa25x-pwm", 0 }, + { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM }, + { }, +}; +MODULE_DEVICE_TABLE(platform, pwm_id_table); + +/* PWM registers and bits definitions */ +#define PWMCR (0x00) +#define PWMDCR (0x04) +#define PWMPCR (0x08) + +#define PWMCR_SD (1 << 6) +#define PWMDCR_FD (1 << 10) + +struct pwm_device { + struct list_head node; + struct pwm_device *secondary; + struct platform_device *pdev; + + const char *label; + struct clk *clk; + int clk_enabled; + void __iomem *mmio_base; + + unsigned int use_count; + unsigned int pwm_id; +}; + +/* + * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE + * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE + */ +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) +{ + unsigned long long c; + unsigned long period_cycles, prescale, pv, dc; + + if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) + return -EINVAL; + + c = clk_get_rate(pwm->clk); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + if (period_cycles < 1) + period_cycles = 1; + prescale = (period_cycles - 1) / 1024; + pv = period_cycles / (prescale + 1) - 1; + + if (prescale > 63) + return -EINVAL; + + if (duty_ns == period_ns) + dc = PWMDCR_FD; + else + dc = (pv + 1) * duty_ns / period_ns; + + /* NOTE: the clock to PWM has to be enabled first + * before writing to the registers + */ + clk_enable(pwm->clk); + __raw_writel(prescale, pwm->mmio_base + PWMCR); + __raw_writel(dc, pwm->mmio_base + PWMDCR); + __raw_writel(pv, pwm->mmio_base + PWMPCR); + clk_disable(pwm->clk); + + return 0; +} +EXPORT_SYMBOL(pwm_config); + +int pwm_enable(struct pwm_device *pwm) +{ + int rc = 0; + + if (!pwm->clk_enabled) { + rc = clk_enable(pwm->clk); + if (!rc) + pwm->clk_enabled = 1; + } + return rc; +} +EXPORT_SYMBOL(pwm_enable); + +void pwm_disable(struct pwm_device *pwm) +{ + if (pwm->clk_enabled) { + clk_disable(pwm->clk); + pwm->clk_enabled = 0; + } +} +EXPORT_SYMBOL(pwm_disable); + +static DEFINE_MUTEX(pwm_lock); +static LIST_HEAD(pwm_list); + +struct pwm_device *pwm_request(int pwm_id, const char *label) +{ + struct pwm_device *pwm; + int found = 0; + + mutex_lock(&pwm_lock); + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->pwm_id == pwm_id) { + found = 1; + break; + } + } + + if (found) { + if (pwm->use_count == 0) { + pwm->use_count++; + pwm->label = label; + } else + pwm = ERR_PTR(-EBUSY); + } else + pwm = ERR_PTR(-ENOENT); + + mutex_unlock(&pwm_lock); + return pwm; +} +EXPORT_SYMBOL(pwm_request); + +void pwm_free(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + + if (pwm->use_count) { + pwm->use_count--; + pwm->label = NULL; + } else + pr_warning("PWM device already freed\n"); + + mutex_unlock(&pwm_lock); +} +EXPORT_SYMBOL(pwm_free); + +static inline void __add_pwm(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + list_add_tail(&pwm->node, &pwm_list); + mutex_unlock(&pwm_lock); +} + +static int __devinit pwm_probe(struct platform_device *pdev) +{ + struct platform_device_id *id = platform_get_device_id(pdev); + struct pwm_device *pwm, *secondary = NULL; + struct resource *r; + int ret = 0; + + pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (pwm == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + pwm->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(pwm->clk)) { + ret = PTR_ERR(pwm->clk); + goto err_free; + } + pwm->clk_enabled = 0; + + pwm->use_count = 0; + pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id; + pwm->pdev = pdev; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + + r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + if (r == NULL) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto err_free_clk; + } + + pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); + if (pwm->mmio_base == NULL) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); + ret = -ENODEV; + goto err_free_mem; + } + + if (id->driver_data & HAS_SECONDARY_PWM) { + secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (secondary == NULL) { + ret = -ENOMEM; + goto err_free_mem; + } + + *secondary = *pwm; + pwm->secondary = secondary; + + /* registers for the second PWM has offset of 0x10 */ + secondary->mmio_base = pwm->mmio_base + 0x10; + secondary->pwm_id = pdev->id + 2; + } + + __add_pwm(pwm); + if (secondary) + __add_pwm(secondary); + + platform_set_drvdata(pdev, pwm); + return 0; + +err_free_mem: + release_mem_region(r->start, r->end - r->start + 1); +err_free_clk: + clk_put(pwm->clk); +err_free: + kfree(pwm); + return ret; +} + +static int __devexit pwm_remove(struct platform_device *pdev) +{ + struct pwm_device *pwm; + struct resource *r; + + pwm = platform_get_drvdata(pdev); + if (pwm == NULL) + return -ENODEV; + + mutex_lock(&pwm_lock); + + if (pwm->secondary) { + list_del(&pwm->secondary->node); + kfree(pwm->secondary); + } + + list_del(&pwm->node); + mutex_unlock(&pwm_lock); + + iounmap(pwm->mmio_base); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, r->end - r->start + 1); + + clk_put(pwm->clk); + kfree(pwm); + return 0; +} + +static struct platform_driver pwm_driver = { + .driver = { + .name = "pxa25x-pwm", + .owner = THIS_MODULE, + }, + .probe = pwm_probe, + .remove = __devexit_p(pwm_remove), + .id_table = pwm_id_table, +}; + +static int __init pwm_init(void) +{ + return platform_driver_register(&pwm_driver); +} +arch_initcall(pwm_init); + +static void __exit pwm_exit(void) +{ + platform_driver_unregister(&pwm_driver); +} +module_exit(pwm_exit); + +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 2a55b910e0d240984860fa0264866c122751bd09 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 18:02:13 +0800 Subject: [ARM] pxa: add missing IRQ_PXA910_NONE to irqs.h Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/irqs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index e83e45ebf7a4..16295cfd5e29 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -52,6 +52,7 @@ /* * Interrupt numbers for PXA910 */ +#define IRQ_PXA910_NONE (-1) #define IRQ_PXA910_AIRQ 0 #define IRQ_PXA910_SSP3 1 #define IRQ_PXA910_SSP2 2 -- cgit v1.2.3 From a27ba768a11ac7a1d56688d4224cef3a802d1f89 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 13 Apr 2009 18:29:52 +0800 Subject: [ARM] pxa: add PWM devices support for pxa168/910 Signed-off-by: Mingwei Wang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/mfp-pxa168.h | 23 +++++++++++++++++++++++ arch/arm/mach-mmp/include/mach/mfp-pxa910.h | 8 ++++++++ arch/arm/mach-mmp/include/mach/pxa168.h | 20 ++++++++++++++++++++ arch/arm/mach-mmp/include/mach/pxa910.h | 20 ++++++++++++++++++++ arch/arm/mach-mmp/include/mach/regs-apbc.h | 14 ++++++++------ arch/arm/mach-mmp/pxa168.c | 12 ++++++++++++ arch/arm/mach-mmp/pxa910.c | 12 ++++++++++++ arch/arm/plat-pxa/pwm.c | 2 ++ 8 files changed, 105 insertions(+), 6 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h index dc4226371d64..3b216bf41e7f 100644 --- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h +++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h @@ -264,4 +264,27 @@ #define GPIO116_I2S_RXD MFP_CFG(GPIO116,AF2) #define GPIO117_I2S_TXD MFP_CFG(GPIO117,AF2) +/* PWM */ +#define GPIO96_PWM3_OUT MFP_CFG(GPIO96, AF1) +#define GPIO97_PWM2_OUT MFP_CFG(GPIO97, AF1) +#define GPIO98_PWM1_OUT MFP_CFG(GPIO98, AF1) +#define GPIO104_PWM4_OUT MFP_CFG(GPIO104, AF1) +#define GPIO106_PWM2_OUT MFP_CFG(GPIO106, AF2) +#define GPIO74_PWM4_OUT MFP_CFG(GPIO74, AF2) +#define GPIO75_PWM3_OUT MFP_CFG(GPIO75, AF2) +#define GPIO76_PWM2_OUT MFP_CFG(GPIO76, AF2) +#define GPIO77_PWM1_OUT MFP_CFG(GPIO77, AF2) +#define GPIO82_PWM4_OUT MFP_CFG(GPIO82, AF2) +#define GPIO83_PWM3_OUT MFP_CFG(GPIO83, AF2) +#define GPIO84_PWM2_OUT MFP_CFG(GPIO84, AF2) +#define GPIO85_PWM1_OUT MFP_CFG(GPIO85, AF2) +#define GPIO84_PWM1_OUT MFP_CFG(GPIO84, AF4) +#define GPIO122_PWM3_OUT MFP_CFG(GPIO122, AF3) +#define GPIO123_PWM1_OUT MFP_CFG(GPIO123, AF1) +#define GPIO124_PWM2_OUT MFP_CFG(GPIO124, AF1) +#define GPIO125_PWM3_OUT MFP_CFG(GPIO125, AF1) +#define GPIO126_PWM4_OUT MFP_CFG(GPIO126, AF1) +#define GPIO86_PWM1_OUT MFP_CFG(GPIO86, AF2) +#define GPIO86_PWM2_OUT MFP_CFG(GPIO86, AF3) + #endif /* __ASM_MACH_MFP_PXA168_H */ diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h index d97de36c50ad..bf1189ff9a34 100644 --- a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h +++ b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h @@ -159,4 +159,12 @@ #define MMC1_CD_MMC1_CD MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM) #define MMC1_WP_MMC1_WP MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM) +/* PWM */ +#define GPIO27 PWM3 AF2 MFP_CFG(GPIO27, AF2) +#define GPIO51_PWM2_OUT MFP_CFG(GPIO51, AF2) +#define GPIO117_PWM1_OUT MFP_CFG(GPIO117, AF2) +#define GPIO118_PWM2_OUT MFP_CFG(GPIO118, AF2) +#define GPIO119_PWM3_OUT MFP_CFG(GPIO119, AF2) +#define GPIO120_PWM4_OUT MFP_CFG(GPIO120, AF2) + #endif /* __ASM_MACH MFP_PXA910_H */ diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h index bfdd6299dff5..6bf1f0eefcd1 100644 --- a/arch/arm/mach-mmp/include/mach/pxa168.h +++ b/arch/arm/mach-mmp/include/mach/pxa168.h @@ -9,6 +9,10 @@ extern struct pxa_device_desc pxa168_device_uart1; extern struct pxa_device_desc pxa168_device_uart2; extern struct pxa_device_desc pxa168_device_twsi0; extern struct pxa_device_desc pxa168_device_twsi1; +extern struct pxa_device_desc pxa168_device_pwm1; +extern struct pxa_device_desc pxa168_device_pwm2; +extern struct pxa_device_desc pxa168_device_pwm3; +extern struct pxa_device_desc pxa168_device_pwm4; static inline int pxa168_add_uart(int id) { @@ -44,4 +48,20 @@ static inline int pxa168_add_twsi(int id, struct i2c_pxa_platform_data *data, return pxa_register_device(d, data, sizeof(*data)); } + +static inline int pxa168_add_pwm(int id) +{ + struct pxa_device_desc *d = NULL; + + switch (id) { + case 1: d = &pxa168_device_pwm1; break; + case 2: d = &pxa168_device_pwm2; break; + case 3: d = &pxa168_device_pwm3; break; + case 4: d = &pxa168_device_pwm4; break; + default: + return -EINVAL; + } + + return pxa_register_device(d, NULL, 0); +} #endif /* __ASM_MACH_PXA168_H */ diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h index a0f0cbee1c07..6ae1ed7a0a9f 100644 --- a/arch/arm/mach-mmp/include/mach/pxa910.h +++ b/arch/arm/mach-mmp/include/mach/pxa910.h @@ -9,6 +9,10 @@ extern struct pxa_device_desc pxa910_device_uart1; extern struct pxa_device_desc pxa910_device_uart2; extern struct pxa_device_desc pxa910_device_twsi0; extern struct pxa_device_desc pxa910_device_twsi1; +extern struct pxa_device_desc pxa910_device_pwm1; +extern struct pxa_device_desc pxa910_device_pwm2; +extern struct pxa_device_desc pxa910_device_pwm3; +extern struct pxa_device_desc pxa910_device_pwm4; static inline int pxa910_add_uart(int id) { @@ -44,4 +48,20 @@ static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data, return pxa_register_device(d, data, sizeof(*data)); } + +static inline int pxa910_add_pwm(int id) +{ + struct pxa_device_desc *d = NULL; + + switch (id) { + case 1: d = &pxa910_device_pwm1; break; + case 2: d = &pxa910_device_pwm2; break; + case 3: d = &pxa910_device_pwm3; break; + case 4: d = &pxa910_device_pwm4; break; + default: + return -EINVAL; + } + + return pxa_register_device(d, NULL, 0); +} #endif /* __ASM_MACH_PXA910_H */ diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h index c6b8c9dc2026..98ccbee4bd0c 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apbc.h +++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h @@ -22,8 +22,10 @@ #define APBC_PXA168_UART1 APBC_REG(0x000) #define APBC_PXA168_UART2 APBC_REG(0x004) #define APBC_PXA168_GPIO APBC_REG(0x008) -#define APBC_PXA168_PWM0 APBC_REG(0x00c) -#define APBC_PXA168_PWM1 APBC_REG(0x010) +#define APBC_PXA168_PWM1 APBC_REG(0x00c) +#define APBC_PXA168_PWM2 APBC_REG(0x010) +#define APBC_PXA168_PWM3 APBC_REG(0x014) +#define APBC_PXA168_PWM4 APBC_REG(0x018) #define APBC_PXA168_SSP1 APBC_REG(0x01c) #define APBC_PXA168_SSP2 APBC_REG(0x020) #define APBC_PXA168_RTC APBC_REG(0x028) @@ -48,10 +50,10 @@ #define APBC_PXA910_UART0 APBC_REG(0x000) #define APBC_PXA910_UART1 APBC_REG(0x004) #define APBC_PXA910_GPIO APBC_REG(0x008) -#define APBC_PXA910_PWM0 APBC_REG(0x00c) -#define APBC_PXA910_PWM1 APBC_REG(0x010) -#define APBC_PXA910_PWM2 APBC_REG(0x014) -#define APBC_PXA910_PWM3 APBC_REG(0x018) +#define APBC_PXA910_PWM1 APBC_REG(0x00c) +#define APBC_PXA910_PWM2 APBC_REG(0x010) +#define APBC_PXA910_PWM3 APBC_REG(0x014) +#define APBC_PXA910_PWM4 APBC_REG(0x018) #define APBC_PXA910_SSP1 APBC_REG(0x01c) #define APBC_PXA910_SSP2 APBC_REG(0x020) #define APBC_PXA910_IPC APBC_REG(0x024) diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index e0729e34f7ad..71b1ae338753 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -67,6 +67,10 @@ static APBC_CLK(uart1, PXA168_UART1, 1, 14745600); static APBC_CLK(uart2, PXA168_UART2, 1, 14745600); static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000); static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000); +static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000); +static APBC_CLK(pwm2, PXA168_PWM2, 1, 13000000); +static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000); +static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000); /* device and clock bindings */ static struct clk_lookup pxa168_clkregs[] = { @@ -74,6 +78,10 @@ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL), INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL), INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL), + INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL), + INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL), + INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL), + INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL), }; static int __init pxa168_init(void) @@ -115,3 +123,7 @@ PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22); PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24); PXA168_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28); PXA168_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28); +PXA168_DEVICE(pwm1, "pxa168-pwm", 0, NONE, 0xd401a000, 0x10); +PXA168_DEVICE(pwm2, "pxa168-pwm", 1, NONE, 0xd401a400, 0x10); +PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10); +PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10); diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index b97328b96ce7..5882ca6b49fb 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c @@ -105,6 +105,10 @@ static APBC_CLK(uart1, PXA910_UART0, 1, 14745600); static APBC_CLK(uart2, PXA910_UART1, 1, 14745600); static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000); static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000); +static APBC_CLK(pwm1, PXA910_PWM1, 1, 13000000); +static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000); +static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000); +static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); /* device and clock bindings */ static struct clk_lookup pxa910_clkregs[] = { @@ -112,6 +116,10 @@ static struct clk_lookup pxa910_clkregs[] = { INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL), INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL), INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL), + INIT_CLKREG(&clk_pwm1, "pxa910-pwm.0", NULL), + INIT_CLKREG(&clk_pwm2, "pxa910-pwm.1", NULL), + INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL), + INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL), }; static int __init pxa910_init(void) @@ -162,3 +170,7 @@ PXA910_DEVICE(uart1, "pxa2xx-uart", 0, UART2, 0xd4017000, 0x30, 21, 22); PXA910_DEVICE(uart2, "pxa2xx-uart", 1, UART3, 0xd4018000, 0x30, 23, 24); PXA910_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28); PXA910_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28); +PXA910_DEVICE(pwm1, "pxa910-pwm", 0, NONE, 0xd401a000, 0x10); +PXA910_DEVICE(pwm2, "pxa910-pwm", 1, NONE, 0xd401a400, 0x10); +PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10); +PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10); diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c index 5513c51ff984..a9eabdcfa163 100644 --- a/arch/arm/plat-pxa/pwm.c +++ b/arch/arm/plat-pxa/pwm.c @@ -28,6 +28,8 @@ static const struct platform_device_id pwm_id_table[] = { /* PWM has_secondary_pwm? */ { "pxa25x-pwm", 0 }, { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM }, + { "pxa168-pwm", 1 }, + { "pxa910-pwm", 1 }, { }, }; MODULE_DEVICE_TABLE(platform, pwm_id_table); -- cgit v1.2.3 From 46580c03062da8c047238a6b3d2b2b13af1700b5 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Tue, 14 Apr 2009 08:33:49 +0300 Subject: [ARM] pxa: update pxa2xx_spi_chip initialization to use .gpio_cs field Signed-off-by: Mike Rapoport Signed-off-by: Eric Miao --- arch/arm/mach-pxa/corgi.c | 45 +++--------------------------------- arch/arm/mach-pxa/imote2.c | 19 ++-------------- arch/arm/mach-pxa/littleton.c | 17 +------------- arch/arm/mach-pxa/poodle.c | 15 +----------- arch/arm/mach-pxa/spitz.c | 53 +++---------------------------------------- 5 files changed, 10 insertions(+), 139 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index f04e50583289..962dda2e154a 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -445,13 +445,8 @@ static struct ads7846_platform_data corgi_ads7846_info = { .wait_for_sync = corgi_wait_for_hsync, }; -static void corgi_ads7846_cs(u32 command) -{ - gpio_set_value(CORGI_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip corgi_ads7846_chip = { - .cs_control = corgi_ads7846_cs, + .gpio_cs = CORGI_GPIO_ADS7846_CS, }; static void corgi_bl_kick_battery(void) @@ -475,22 +470,12 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = { .kick_battery = corgi_bl_kick_battery, }; -static void corgi_lcdcon_cs(u32 command) -{ - gpio_set_value(CORGI_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip corgi_lcdcon_chip = { - .cs_control = corgi_lcdcon_cs, + .gpio_cs = CORGI_GPIO_LCDCON_CS, }; -static void corgi_max1111_cs(u32 command) -{ - gpio_set_value(CORGI_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip corgi_max1111_chip = { - .cs_control = corgi_max1111_cs, + .gpio_cs = CORGI_GPIO_MAX1111_CS, }; static struct spi_board_info corgi_spi_devices[] = { @@ -520,32 +505,8 @@ static struct spi_board_info corgi_spi_devices[] = { static void __init corgi_init_spi(void) { - int err; - - err = gpio_request(CORGI_GPIO_ADS7846_CS, "ADS7846_CS"); - if (err) - return; - - err = gpio_request(CORGI_GPIO_LCDCON_CS, "LCDCON_CS"); - if (err) - goto err_free_1; - - err = gpio_request(CORGI_GPIO_MAX1111_CS, "MAX1111_CS"); - if (err) - goto err_free_2; - - gpio_direction_output(CORGI_GPIO_ADS7846_CS, 1); - gpio_direction_output(CORGI_GPIO_LCDCON_CS, 1); - gpio_direction_output(CORGI_GPIO_MAX1111_CS, 1); - pxa2xx_set_spi_info(1, &corgi_spi_info); spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices)); - return; - -err_free_2: - gpio_free(CORGI_GPIO_LCDCON_CS); -err_free_1: - gpio_free(CORGI_GPIO_ADS7846_CS); } #else static inline void corgi_init_spi(void) {} diff --git a/arch/arm/mach-pxa/imote2.c b/arch/arm/mach-pxa/imote2.c index 821e65a4097e..3ef98d43d303 100644 --- a/arch/arm/mach-pxa/imote2.c +++ b/arch/arm/mach-pxa/imote2.c @@ -456,25 +456,12 @@ static struct pxa2xx_spi_master pxa_ssp_master_2_info = { .num_chipselect = 1, }; -/* Patch posted by Eric Miao will remove - * the need for these functions. - */ -static void spi1control(u32 command) -{ - gpio_set_value(24, command & PXA2XX_CS_ASSERT ? 0 : 1); -}; - -static void spi3control(u32 command) -{ - gpio_set_value(39, command & PXA2XX_CS_ASSERT ? 0 : 1); -}; - static struct pxa2xx_spi_chip staccel_chip_info = { .tx_threshold = 8, .rx_threshold = 8, .dma_burst_size = 8, .timeout = 235, - .cs_control = spi1control, + .gpio_cs = 24, }; static struct pxa2xx_spi_chip cc2420_info = { @@ -482,7 +469,7 @@ static struct pxa2xx_spi_chip cc2420_info = { .rx_threshold = 8, .dma_burst_size = 8, .timeout = 235, - .cs_control = spi3control, + .gpio_cs = 39, }; static struct spi_board_info spi_board_info[] __initdata = { @@ -538,8 +525,6 @@ static void __init imote2_init(void) /* SPI chip select directions - all other directions should * be handled by drivers.*/ gpio_direction_output(37, 0); - gpio_direction_output(24, 0); - gpio_direction_output(39, 0); platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices)); diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index ad5378b1af94..94a32321ad43 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -179,15 +179,10 @@ static struct pxa2xx_spi_master littleton_spi_info = { .num_chipselect = 1, }; -static void littleton_tdo24m_cs(u32 cmd) -{ - gpio_set_value(LITTLETON_GPIO_LCD_CS, !(cmd == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip littleton_tdo24m_chip = { .rx_threshold = 1, .tx_threshold = 1, - .cs_control = littleton_tdo24m_cs, + .gpio_cs = LITTLETON_GPIO_LCD_CS, }; static struct spi_board_info littleton_spi_devices[] __initdata = { @@ -202,16 +197,6 @@ static struct spi_board_info littleton_spi_devices[] __initdata = { static void __init littleton_init_spi(void) { - int err; - - err = gpio_request(LITTLETON_GPIO_LCD_CS, "LCD_CS"); - if (err) { - pr_warning("failed to request GPIO for LCS CS\n"); - return; - } - - gpio_direction_output(LITTLETON_GPIO_LCD_CS, 1); - pxa2xx_set_spi_info(2, &littleton_spi_info); spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices)); } diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 74f4ce600ca4..ac431ed10399 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -214,13 +214,8 @@ static struct ads7846_platform_data poodle_ads7846_info = { .gpio_pendown = POODLE_GPIO_TP_INT, }; -static void ads7846_cs(u32 command) -{ - gpio_set_value(POODLE_GPIO_TP_CS, !(command == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip poodle_ads7846_chip = { - .cs_control = ads7846_cs, + .gpio_cs = POODLE_GPIO_TP_CS, }; static struct spi_board_info poodle_spi_devices[] = { @@ -236,14 +231,6 @@ static struct spi_board_info poodle_spi_devices[] = { static void __init poodle_init_spi(void) { - int err; - - err = gpio_request(POODLE_GPIO_TP_CS, "ADS7846_CS"); - if (err) - return; - - gpio_direction_output(POODLE_GPIO_TP_CS, 1); - pxa2xx_set_spi_info(1, &poodle_spi_info); spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices)); } diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 229f48577d5e..1182b7988230 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -317,13 +317,8 @@ static struct ads7846_platform_data spitz_ads7846_info = { .wait_for_sync = spitz_wait_for_hsync, }; -static void spitz_ads7846_cs(u32 command) -{ - gpio_set_value(SPITZ_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip spitz_ads7846_chip = { - .cs_control = spitz_ads7846_cs, + .gpio_cs = SPITZ_GPIO_ADS7846_CS, }; static void spitz_bl_kick_battery(void) @@ -347,22 +342,12 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = { .kick_battery = spitz_bl_kick_battery, }; -static void spitz_lcdcon_cs(u32 command) -{ - gpio_set_value(SPITZ_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip spitz_lcdcon_chip = { - .cs_control = spitz_lcdcon_cs, + .gpio_cs = SPITZ_GPIO_LCDCON_CS, }; -static void spitz_max1111_cs(u32 command) -{ - gpio_set_value(SPITZ_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT)); -} - static struct pxa2xx_spi_chip spitz_max1111_chip = { - .cs_control = spitz_max1111_cs, + .gpio_cs = SPITZ_GPIO_MAX1111_CS, }; static struct spi_board_info spitz_spi_devices[] = { @@ -392,30 +377,6 @@ static struct spi_board_info spitz_spi_devices[] = { static void __init spitz_init_spi(void) { - int err; - - err = gpio_request(SPITZ_GPIO_ADS7846_CS, "ADS7846_CS"); - if (err) - return; - - err = gpio_request(SPITZ_GPIO_LCDCON_CS, "LCDCON_CS"); - if (err) - goto err_free_1; - - err = gpio_request(SPITZ_GPIO_MAX1111_CS, "MAX1111_CS"); - if (err) - goto err_free_2; - - err = gpio_direction_output(SPITZ_GPIO_ADS7846_CS, 1); - if (err) - goto err_free_3; - err = gpio_direction_output(SPITZ_GPIO_LCDCON_CS, 1); - if (err) - goto err_free_3; - err = gpio_direction_output(SPITZ_GPIO_MAX1111_CS, 1); - if (err) - goto err_free_3; - if (machine_is_akita()) { spitz_lcdcon_info.gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT; spitz_lcdcon_info.gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON; @@ -423,14 +384,6 @@ static void __init spitz_init_spi(void) pxa2xx_set_spi_info(2, &spitz_spi_info); spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices)); - return; - -err_free_3: - gpio_free(SPITZ_GPIO_MAX1111_CS); -err_free_2: - gpio_free(SPITZ_GPIO_LCDCON_CS); -err_free_1: - gpio_free(SPITZ_GPIO_ADS7846_CS); } #else static inline void spitz_init_spi(void) {} -- cgit v1.2.3 From a01bd58449088b63da45ab5f2c7921893eb7d143 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 17 Apr 2009 11:47:57 +0200 Subject: [ARM] pxa: allow IRQ_BOARD_END to be customized and make zylonite to use it The default value is 16 IRQs. Zylonite needs 32, ASIC3 based boards need 70. My problem is still that due to the way IRQ_GPIO is hardcoded, ASIC3 based boards need 70 IRQs starting at IRQ_BOARD_START. If I define ASIC3 IRQs similar to LoCoMo or SA1111, things break as soon as something selects PXA_HAVE_BOARD_IRQS. Increasing the default number of board IRQs to 70 instead doesn't seem very nice. Signed-off-by: Philipp Zabel Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 1 + arch/arm/mach-pxa/include/mach/irqs.h | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 47747f96f125..3b34f34db204 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -280,6 +280,7 @@ config MACH_ZYLONITE select PXA3xx select PXA_SSP select HAVE_PWM + select PXA_HAVE_BOARD_IRQS config MACH_LITTLETON bool "PXA3xx Form Factor Platform (aka Littleton)" diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 32bb4a2eb7f1..ebf38bbb347f 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -91,13 +91,21 @@ #define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i)) /* - * The next 16 interrupts are for board specific purposes. Since + * The following interrupts are for board specific purposes. Since * the kernel can only run on one machine at a time, we can re-use - * these. If you need more, increase IRQ_BOARD_END, but keep it - * within sensible limits. + * these. There will be 16 IRQs by default. If it is not enough, + * IRQ_BOARD_END is allowed be customized for each board, but keep + * the numbers within sensible limits and in descending order, so + * when multiple config options are selected, the maximum will be + * used. */ #define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM) + +#if defined(CONFIG_MACH_ZYLONITE) +#define IRQ_BOARD_END (IRQ_BOARD_START + 32) +#else #define IRQ_BOARD_END (IRQ_BOARD_START + 16) +#endif #define IRQ_SA1111_START (IRQ_BOARD_END) #define IRQ_GPAIN0 (IRQ_BOARD_END + 0) @@ -188,8 +196,6 @@ #define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1) #elif defined(CONFIG_PXA_HAVE_BOARD_IRQS) #define NR_IRQS (IRQ_BOARD_END) -#elif defined(CONFIG_MACH_ZYLONITE) -#define NR_IRQS (IRQ_BOARD_START + 32) #else #define NR_IRQS (IRQ_BOARD_START) #endif -- cgit v1.2.3 From 94c35a6b5129bc370893d74085c13607f260ef39 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 21 Apr 2009 19:19:36 +0200 Subject: [ARM] pxa: add udc support for pxa3xx As reported by Aric Blumer, the pxa27x_udc driver does work with pxa3xx devices. Add support into device files. Reported-by: Aric Blumer Signed-off-by: Robert Jarzmik Signed-off-by: Matt Reimer Signed-off-by: Eric Miao --- arch/arm/mach-pxa/pxa3xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 462503a2e791..6f678d93bf4e 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -552,7 +552,7 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { -/* &pxa_device_udc, The UDC driver is PXA25x only */ + &pxa27x_device_udc, &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, -- cgit v1.2.3 From d082d36ea82aff6f25e8380770713e6fd0c7290a Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Tue, 26 May 2009 09:10:18 +0300 Subject: [ARM] pxa: add ability to set suspend mode PXA processors have several low-power modes. Currently kernel supports only one of these modes for PM_SUSPEND_MEM. This patch adds ability to set desired suspend mode for PXA27x based machines. Signed-off-by: Mike Rapoport Reviewed-by: Russell King Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/pxa27x.h | 3 +++ arch/arm/mach-pxa/pxa27x.c | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h index 6876e16c2970..0b702693f458 100644 --- a/arch/arm/mach-pxa/include/mach/pxa27x.h +++ b/arch/arm/mach-pxa/include/mach/pxa27x.h @@ -16,4 +16,7 @@ #define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */ #define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ #define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ + +extern int __init pxa27x_set_pwrmode(unsigned int mode); + #endif /* __MACH_PXA27x_H */ diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index c54ad8b3343c..ec68cc16b4e3 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -203,6 +203,23 @@ static struct clk_lookup pxa27x_clkregs[] = { #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] +/* + * allow platforms to override default PWRMODE setting used for PM_SUSPEND_MEM + */ +static unsigned int pwrmode = PWRMODE_SLEEP; + +int __init pxa27x_set_pwrmode(unsigned int mode) +{ + switch (mode) { + case PWRMODE_SLEEP: + case PWRMODE_DEEPSLEEP: + pwrmode = mode; + return 0; + } + + return -EINVAL; +} + /* * List of global PXA peripheral registers to preserve. * More ones like CP and general purpose register values are preserved @@ -254,7 +271,7 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) pxa_cpu_standby(); break; case PM_SUSPEND_MEM: - pxa27x_cpu_suspend(PWRMODE_SLEEP); + pxa27x_cpu_suspend(pwrmode); break; } } -- cgit v1.2.3 From dd5b94aba709aae68d1ba11b5f963df54efa58bb Mon Sep 17 00:00:00 2001 From: Jürgen Schindele Date: Thu, 4 Jun 2009 11:43:22 +0800 Subject: [ARM] pxa: add additional mfp definitions for pxa320 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jürgen Schindele Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/mfp-pxa320.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h index 07897e61d05a..3ce4682eabb6 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h @@ -283,6 +283,9 @@ #define GPIO41_UART1_TXD MFP_CFG_LPM(GPIO41, AF4, FLOAT) #define GPIO42_UART1_RXD MFP_CFG_LPM(GPIO42, AF4, FLOAT) #define GPIO42_UART1_TXD MFP_CFG_LPM(GPIO42, AF2, FLOAT) +#define GPIO75_UART1_RXD MFP_CFG_LPM(GPIO75, AF1, FLOAT) +#define GPIO76_UART1_RXD MFP_CFG_LPM(GPIO76, AF3, FLOAT) +#define GPIO76_UART1_TXD MFP_CFG_LPM(GPIO76, AF1, FLOAT) #define GPIO97_UART1_RXD MFP_CFG_LPM(GPIO97, AF1, FLOAT) #define GPIO97_UART1_TXD MFP_CFG_LPM(GPIO97, AF6, FLOAT) #define GPIO98_UART1_RXD MFP_CFG_LPM(GPIO98, AF6, FLOAT) @@ -291,6 +294,9 @@ #define GPIO43_UART1_RTS MFP_CFG_LPM(GPIO43, AF4, FLOAT) #define GPIO48_UART1_CTS MFP_CFG_LPM(GPIO48, AF4, FLOAT) #define GPIO48_UART1_RTS MFP_CFG_LPM(GPIO48, AF2, FLOAT) +#define GPIO77_UART1_CTS MFP_CFG_LPM(GPIO77, AF1, FLOAT) +#define GPIO82_UART1_RTS MFP_CFG_LPM(GPIO82, AF1, FLOAT) +#define GPIO82_UART1_CTS MFP_CFG_LPM(GPIO82, AF3, FLOAT) #define GPIO99_UART1_CTS MFP_CFG_LPM(GPIO99, AF1, FLOAT) #define GPIO99_UART1_RTS MFP_CFG_LPM(GPIO99, AF6, FLOAT) #define GPIO104_UART1_CTS MFP_CFG_LPM(GPIO104, AF6, FLOAT) @@ -299,13 +305,18 @@ #define GPIO45_UART1_DSR MFP_CFG_LPM(GPIO45, AF2, FLOAT) #define GPIO47_UART1_DTR MFP_CFG_LPM(GPIO47, AF2, FLOAT) #define GPIO47_UART1_DSR MFP_CFG_LPM(GPIO47, AF4, FLOAT) +#define GPIO79_UART1_DSR MFP_CFG_LPM(GPIO79, AF1, FLOAT) +#define GPIO81_UART1_DTR MFP_CFG_LPM(GPIO81, AF1, FLOAT) +#define GPIO81_UART1_DSR MFP_CFG_LPM(GPIO81, AF3, FLOAT) #define GPIO101_UART1_DTR MFP_CFG_LPM(GPIO101, AF6, FLOAT) #define GPIO101_UART1_DSR MFP_CFG_LPM(GPIO101, AF1, FLOAT) #define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF1, FLOAT) #define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF6, FLOAT) #define GPIO44_UART1_DCD MFP_CFG_LPM(GPIO44, AF2, FLOAT) +#define GPIO78_UART1_DCD MFP_CFG_LPM(GPIO78, AF1, FLOAT) #define GPIO100_UART1_DCD MFP_CFG_LPM(GPIO100, AF1, FLOAT) #define GPIO46_UART1_RI MFP_CFG_LPM(GPIO46, AF2, FLOAT) +#define GPIO80_UART1_RI MFP_CFG_LPM(GPIO80, AF1, FLOAT) #define GPIO102_UART1_RI MFP_CFG_LPM(GPIO102, AF1, FLOAT) /* UART2 */ @@ -438,6 +449,9 @@ #define GPIO2_RDY MFP_CFG(GPIO2, AF1) #define GPIO5_NPIOR MFP_CFG(GPIO5, AF3) +#define GPIO6_NPIOW MFP_CFG(GPIO6, AF3) +#define GPIO7_NPIOS16 MFP_CFG(GPIO7, AF3) +#define GPIO8_NPWAIT MFP_CFG(GPIO8, AF3) #define GPIO11_PWM0_OUT MFP_CFG(GPIO11, AF1) #define GPIO12_PWM1_OUT MFP_CFG(GPIO12, AF1) -- cgit v1.2.3 From 3dbeef231e2247f91784f33555ed6f7da7a6f726 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sun, 17 May 2009 23:03:55 +0200 Subject: [ARM] pxa: add vcc_core regulation for cpufreq on pxa2xx Add voltage regulation capability to pxa2xx cpufreq driver. The cpufreq will ask for a "vcc_core" regulator to the regulator framework. If a regulator is found at probe time, it will be used with values specified in PXA270 Electrical, Mechanical, and Thermal Specifications. If not, it will be assumed for now that frequency change will work without voltage control. This assumes that the IPL/SPL installs sane values to an existing voltage regulator (ie. voltage high enough to support the full range). Signed-off-by: Robert Jarzmik Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cpufreq-pxa2xx.c | 104 ++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 19 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 083a1d851d49..3a8ee2272add 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include @@ -47,6 +49,8 @@ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); #define freq_debug 0 #endif +static struct regulator *vcc_core; + static unsigned int pxa27x_maxfreq; module_param(pxa27x_maxfreq, uint, 0); MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz" @@ -58,6 +62,8 @@ typedef struct { unsigned int cccr; unsigned int div2; unsigned int cclkcfg; + int vmin; + int vmax; } pxa_freqs_t; /* Define the refresh period in mSec for the SDRAM and the number of rows */ @@ -82,24 +88,24 @@ static unsigned int sdram_rows; static pxa_freqs_t pxa255_run_freqs[] = { - /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ - { 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */ - {132700, 132700, 0x123, 1, CCLKCFG}, /* 133, 133, 66, 66 */ - {199100, 99500, 0x141, 0, CCLKCFG}, /* 199, 199, 99, 99 */ - {265400, 132700, 0x143, 1, CCLKCFG}, /* 265, 265, 133, 66 */ - {331800, 165900, 0x145, 1, CCLKCFG}, /* 331, 331, 166, 83 */ - {398100, 99500, 0x161, 0, CCLKCFG}, /* 398, 398, 196, 99 */ + /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ + { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */ + {132700, 132700, 0x123, 1, CCLKCFG, -1, -1}, /* 133, 133, 66, 66 */ + {199100, 99500, 0x141, 0, CCLKCFG, -1, -1}, /* 199, 199, 99, 99 */ + {265400, 132700, 0x143, 1, CCLKCFG, -1, -1}, /* 265, 265, 133, 66 */ + {331800, 165900, 0x145, 1, CCLKCFG, -1, -1}, /* 331, 331, 166, 83 */ + {398100, 99500, 0x161, 0, CCLKCFG, -1, -1}, /* 398, 398, 196, 99 */ }; /* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ static pxa_freqs_t pxa255_turbo_freqs[] = { /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ - { 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */ - {199100, 99500, 0x221, 0, CCLKCFG}, /* 99, 199, 50, 99 */ - {298500, 99500, 0x321, 0, CCLKCFG}, /* 99, 287, 50, 99 */ - {298600, 99500, 0x1c1, 0, CCLKCFG}, /* 199, 287, 99, 99 */ - {398100, 99500, 0x241, 0, CCLKCFG}, /* 199, 398, 99, 99 */ + { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */ + {199100, 99500, 0x221, 0, CCLKCFG, -1, -1}, /* 99, 199, 50, 99 */ + {298500, 99500, 0x321, 0, CCLKCFG, -1, -1}, /* 99, 287, 50, 99 */ + {298600, 99500, 0x1c1, 0, CCLKCFG, -1, -1}, /* 199, 287, 99, 99 */ + {398100, 99500, 0x241, 0, CCLKCFG, -1, -1}, /* 199, 398, 99, 99 */ }; #define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs) @@ -148,13 +154,13 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table ((T) ? CCLKCFG_TURBO : 0)) static pxa_freqs_t pxa27x_freqs[] = { - {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1)}, - {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1)}, - {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)}, - {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)}, - {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)}, - {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)}, - {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)} + {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 }, + {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1), 1000000, 1705000 }, + {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 }, + {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 }, + {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 }, + {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1), 1450000, 1705000 }, + {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1), 1550000, 1705000 } }; #define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs) @@ -163,6 +169,47 @@ static struct cpufreq_frequency_table extern unsigned get_clk_frequency_khz(int info); +#ifdef CONFIG_REGULATOR + +static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) +{ + int ret = 0; + int vmin, vmax; + + if (!cpu_is_pxa27x()) + return 0; + + vmin = pxa_freq->vmin; + vmax = pxa_freq->vmax; + if ((vmin == -1) || (vmax == -1)) + return 0; + + ret = regulator_set_voltage(vcc_core, vmin, vmax); + if (ret) + pr_err("cpufreq: Failed to set vcc_core in [%dmV..%dmV]\n", + vmin, vmax); + return ret; +} + +static __init void pxa_cpufreq_init_voltages(void) +{ + vcc_core = regulator_get(NULL, "vcc_core"); + if (IS_ERR(vcc_core)) { + pr_info("cpufreq: Didn't find vcc_core regulator\n"); + vcc_core = NULL; + } else { + pr_info("cpufreq: Found vcc_core regulator\n"); + } +} +#else +static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) +{ + return 0; +} + +static __init void pxa_cpufreq_init_voltages(void) { } +#endif + static void find_freq_tables(struct cpufreq_frequency_table **freq_table, pxa_freqs_t **pxa_freqs) { @@ -251,6 +298,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, unsigned long flags; unsigned int new_freq_cpu, new_freq_mem; unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; + int ret = 0; /* Get the current policy */ find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); @@ -273,6 +321,10 @@ static int pxa_set_target(struct cpufreq_policy *policy, freqs.new / 1000, (pxa_freq_settings[idx].div2) ? (new_freq_mem / 2000) : (new_freq_mem / 1000)); + if (vcc_core && freqs.new > freqs.old) + ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); + if (ret) + return ret; /* * Tell everyone what we're about to do... * you should add a notify client with any platform specific @@ -335,6 +387,18 @@ static int pxa_set_target(struct cpufreq_policy *policy, */ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + /* + * Even if voltage setting fails, we don't report it, as the frequency + * change succeeded. The voltage reduction is not a critical failure, + * only power savings will suffer from this. + * + * Note: if the voltage change fails, and a return value is returned, a + * bug is triggered (seems a deadlock). Should anybody find out where, + * the "return 0" should become a "return ret". + */ + if (vcc_core && freqs.new < freqs.old) + ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); + return 0; } @@ -349,6 +413,8 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) if (cpu_is_pxa27x()) pxa27x_guess_max_freq(); + pxa_cpufreq_init_voltages(); + init_sdram_rows(); /* set default policy and cpuinfo */ -- cgit v1.2.3 From f8f9d5ecfff9b2d04db4decd7d2c86aba86e49e5 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 17 Apr 2009 11:38:23 +0200 Subject: [ARM] pxa/magician: use I2C fast mode Signed-off-by: Philipp Zabel Signed-off-by: Eric Miao --- arch/arm/mach-pxa/magician.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 5a9df973935d..34046c8bfaf5 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -744,6 +744,14 @@ static struct platform_device strataflash = { }, }; +/* + * I2C + */ + +static struct i2c_pxa_platform_data i2c_info = { + .fast_mode = 1, +}; + /* * Platform devices */ @@ -779,7 +787,7 @@ static void __init magician_init(void) pxa_set_ficp_info(&magician_ficp_info); } pxa27x_set_i2c_power_info(NULL); - pxa_set_i2c_info(NULL); + pxa_set_i2c_info(&i2c_info); pxa_set_mci_info(&magician_mci_info); pxa_set_ohci_info(&magician_ohci_info); -- cgit v1.2.3 From 2f1a5bf707a39153d93d04858f69f2d43563d08c Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 28 Apr 2009 13:31:08 +0200 Subject: [ARM] pxa/magician: use ARRAY_AND_SIZE for platform_add_devices Signed-off-by: Philipp Zabel Signed-off-by: Eric Miao --- arch/arm/mach-pxa/magician.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 34046c8bfaf5..ca39669cffc5 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -779,7 +779,7 @@ static void __init magician_init(void) pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config)); - platform_add_devices(devices, ARRAY_SIZE(devices)); + platform_add_devices(ARRAY_AND_SIZE(devices)); err = gpio_request(GPIO83_MAGICIAN_nIR_EN, "nIR_EN"); if (!err) { -- cgit v1.2.3 From d3ca1952e63ffbebab6f2f1c9551df7b3cb731f5 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 28 May 2009 07:05:18 +0200 Subject: [ARM] pxa: add basic support for HP iPAQ hx4700 PDAs This includes - IrDA (pxafixp_ir), - Buttons (gpio-keys), - ASIC3 IRQ/GPIOs (asic3), - EGPIOs (htc-egpio), - ATI Imageon w3220 framebuffer (w100fb), - Backlight (pwm-backlight), - StrataFlash (physmap), - Battery monitor (ds1wm,w1_ds2760,ds2760_battery) - USB gadget support (pxa27x_udc,gpio_vbus). - bq24022 battery charger (pda_power,bq24022) - TSC2046 touchscreen (ads7846) Signed-off-by: Philipp Zabel Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 8 + arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/hx4700.c | 851 ++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/include/mach/hx4700.h | 131 +++++ arch/arm/mach-pxa/include/mach/irqs.h | 4 +- 5 files changed, 994 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-pxa/hx4700.c create mode 100644 arch/arm/mach-pxa/include/mach/hx4700.h (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 3b34f34db204..a911bc961dea 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -309,6 +309,14 @@ config MACH_CM_X300 select PXA3xx select CPU_PXA300 +config MACH_H4700 + bool "HP iPAQ hx4700" + select PXA27x + select IWMMXT + select PXA_SSP + select HAVE_PWM + select PXA_HAVE_BOARD_IRQS + config MACH_MAGICIAN bool "Enable HTC Magician Support" select PXA27x diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 47d01572a04d..e950c40b316e 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_MACH_PCM027) += pcm027.o obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o obj-$(CONFIG_MACH_TOSA) += tosa.o obj-$(CONFIG_MACH_EM_X270) += em-x270.o +obj-$(CONFIG_MACH_H4700) += hx4700.o obj-$(CONFIG_MACH_MAGICIAN) += magician.o obj-$(CONFIG_MACH_HIMALAYA) += himalaya.o obj-$(CONFIG_MACH_MIOA701) += mioa701.o mioa701_bootresume.o diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c new file mode 100644 index 000000000000..0f6568005e16 --- /dev/null +++ b/arch/arm/mach-pxa/hx4700.c @@ -0,0 +1,851 @@ +/* + * Support for HP iPAQ hx4700 PDAs. + * + * Copyright (c) 2008-2009 Philipp Zabel + * + * Based on code: + * Copyright (c) 2004 Hewlett-Packard Company. + * Copyright (c) 2005 SDG Systems, LLC + * Copyright (c) 2006 Anton Vorontsov + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include