From 8791ed3295950b06a0edd8aea1d0717f66f3e5cf Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Thu, 27 Mar 2008 14:51:40 -0400 Subject: plat-orion: make i2c-mv64xxx available for all Orion families Signed-off-by: Lennert Buytenhek Reviewed-by: Tzachi Perelstein Acked-by: Russell King Signed-off-by: Nicolas Pitre --- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 5fa9c3c67e0c..b04c99580d0d 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -645,7 +645,7 @@ config I2C_PCA_ISA config I2C_MV64XXX tristate "Marvell mv64xxx I2C Controller" - depends on (MV64X60 || ARCH_ORION) && EXPERIMENTAL + depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL help If you say yes to this option, support will be included for the built-in I2C interface on the Marvell 64xxx line of host bridges. -- cgit v1.2.3 From a683b14df8f4320d0ef6cac93a6d9806173bf339 Mon Sep 17 00:00:00 2001 From: eric miao Date: Mon, 3 Mar 2008 09:44:25 +0800 Subject: [ARM] pxa: separate GPIOs and their mode definitions to pxa2xx-gpio.h two reasons: 1. GPIO namings and their mode definitions are conceptually not part of the PXA register definitions 2. this is actually a temporary move in the transition of PXA2xx to use MFP-alike APIs (as what PXA3xx is now doing), so that legacy code will still work and new code can be added in step by step Signed-off-by: eric miao Signed-off-by: Russell King --- arch/arm/mach-pxa/clock.c | 1 + arch/arm/mach-pxa/cm-x270-pci.c | 1 + arch/arm/mach-pxa/cm-x270.c | 1 + arch/arm/mach-pxa/colibri.c | 1 + arch/arm/mach-pxa/corgi.c | 1 + arch/arm/mach-pxa/corgi_pm.c | 1 + arch/arm/mach-pxa/corgi_ssp.c | 1 + arch/arm/mach-pxa/em-x270.c | 1 + arch/arm/mach-pxa/gpio.c | 1 + arch/arm/mach-pxa/idp.c | 1 + arch/arm/mach-pxa/irq.c | 1 + arch/arm/mach-pxa/leds-trizeps4.c | 1 + arch/arm/mach-pxa/lpd270.c | 1 + arch/arm/mach-pxa/lubbock.c | 1 + arch/arm/mach-pxa/mainstone.c | 1 + arch/arm/mach-pxa/pcm027.c | 1 + arch/arm/mach-pxa/pcm990-baseboard.c | 1 + arch/arm/mach-pxa/poodle.c | 1 + arch/arm/mach-pxa/sharpsl_pm.c | 1 + arch/arm/mach-pxa/spitz.c | 1 + arch/arm/mach-pxa/spitz_pm.c | 1 + arch/arm/mach-pxa/tosa.c | 1 + arch/arm/mach-pxa/trizeps4.c | 1 + drivers/i2c/busses/i2c-pxa.c | 1 + drivers/input/keyboard/corgikbd.c | 1 + drivers/input/keyboard/spitzkbd.c | 1 + drivers/input/touchscreen/corgi_ts.c | 1 + drivers/net/irda/pxaficp_ir.c | 1 + drivers/pcmcia/pxa2xx_cm_x270.c | 1 + drivers/video/pxafb.c | 1 + include/asm-arm/arch-pxa/pxa-regs.h | 301 -------------------------------- include/asm-arm/arch-pxa/pxa2xx-gpio.h | 304 +++++++++++++++++++++++++++++++++ sound/arm/pxa2xx-ac97.c | 1 + sound/soc/pxa/pxa2xx-ac97.c | 1 + sound/soc/pxa/pxa2xx-i2s.c | 1 + 35 files changed, 337 insertions(+), 301 deletions(-) create mode 100644 include/asm-arm/arch-pxa/pxa2xx-gpio.h (limited to 'drivers/i2c/busses') diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index df5ae2710ab1..e97dc59813c8 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -13,6 +13,7 @@ #include #include +#include #include #include "devices.h" diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c index fcda7d5cb693..ac7f05f9f3eb 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.c +++ b/arch/arm/mach-pxa/cm-x270-pci.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index ecdbc96a4de1..6d4416a4f378 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/colibri.c b/arch/arm/mach-pxa/colibri.c index 6db54e31c397..43bf5a183e90 100644 --- a/arch/arm/mach-pxa/colibri.c +++ b/arch/arm/mach-pxa/colibri.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "generic.h" diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 9292576b83b3..259ca821e464 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 392c38717362..0a85f706e887 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "sharpsl.h" #define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 31706224a04c..eccc45d21f75 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -21,6 +21,7 @@ #include #include +#include #include #include "sharpsl.h" diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 3bb31314429a..edc4f07a230d 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c index f96cae04f6f5..1a7057991da6 100644 --- a/arch/arm/mach-pxa/gpio.c +++ b/arch/arm/mach-pxa/gpio.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "generic.h" diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 0a9434432c55..2637633f9166 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index fbff557bb225..a9a0c3fab159 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "generic.h" diff --git a/arch/arm/mach-pxa/leds-trizeps4.c b/arch/arm/mach-pxa/leds-trizeps4.c index 2271d20ffeda..21880daabafe 100644 --- a/arch/arm/mach-pxa/leds-trizeps4.c +++ b/arch/arm/mach-pxa/leds-trizeps4.c @@ -18,6 +18,7 @@ #include #include +#include #include #include "leds.h" diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index afa62ffe3ad5..a20e4b1649d6 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index e7ae4bb3e361..81567ec983a4 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 72a436fb9a29..75be0c74a640 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index c14696b9979d..3b945eb0aee3 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c @@ -29,6 +29,7 @@ #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 3dda16a20049..20b2974e3960 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -25,6 +25,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 209eabf0ed3e..ca5ac196b47b 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index f9d1b61e1185..34cd585075b0 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "sharpsl.h" diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 9e7773fca01c..62a02c3927c5 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 745a4dc7acdd..7a7f5f947cc5 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "sharpsl.h" #define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index f99112d50b41..d427d87b4fe8 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index f207fcd30cd7..931885d86b91 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 2d2087ad708f..6fd2d6a84eff 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -39,6 +39,7 @@ #include #include #include +#include struct pxa_i2c { spinlock_t lock; diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 790fed368aae..5d6cc7f1dc94 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #define KB_ROWS 8 diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 1d59a2dc3c17..0be74bfc58fe 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -23,6 +23,7 @@ #include #include #include +#include #define KB_ROWS 7 #define KB_COLS 11 diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 99d92f5c93d6..a22576779acd 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -22,6 +22,7 @@ #include #include #include +#include #define PWR_MODE_ACTIVE 0 diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 8c09344f58dc..8239c520f1ef 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_MACH_MAINSTONE #include diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index fbf2f3a6984c..e7ab060ff118 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c @@ -20,6 +20,7 @@ #include #include +#include #include #include "soc_common.h" diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 97facb121c73..757651954e6c 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index e659be4df3ac..e78adf8268ea 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1236,307 +1236,6 @@ #endif - -/* GPIO alternate function assignments */ - -#define GPIO1_RST 1 /* reset */ -#define GPIO6_MMCCLK 6 /* MMC Clock */ -#define GPIO7_48MHz 7 /* 48 MHz clock output */ -#define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ -#define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ -#define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ -#define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */ -#define GPIO12_32KHz 12 /* 32 kHz out */ -#define GPIO12_CIF_DD_7 12 /* Camera data pin 7 */ -#define GPIO13_MBGNT 13 /* memory controller grant */ -#define GPIO14_MBREQ 14 /* alternate bus master request */ -#define GPIO15_nCS_1 15 /* chip select 1 */ -#define GPIO16_PWM0 16 /* PWM0 output */ -#define GPIO17_PWM1 17 /* PWM1 output */ -#define GPIO17_CIF_DD_6 17 /* Camera data pin 6 */ -#define GPIO18_RDY 18 /* Ext. Bus Ready */ -#define GPIO19_DREQ1 19 /* External DMA Request */ -#define GPIO20_DREQ0 20 /* External DMA Request */ -#define GPIO23_SCLK 23 /* SSP clock */ -#define GPIO24_SFRM 24 /* SSP Frame */ -#define GPIO25_STXD 25 /* SSP transmit */ -#define GPIO26_SRXD 26 /* SSP receive */ -#define GPIO27_SEXTCLK 27 /* SSP ext_clk */ -#define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */ -#define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */ -#define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ -#define GPIO31_SYNC 31 /* AC97/I2S sync */ -#define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */ -#define GPIO32_SYSCLK 32 /* I2S System Clock */ -#define GPIO32_MMCCLK 32 /* MMC Clock (PXA270) */ -#define GPIO33_nCS_5 33 /* chip select 5 */ -#define GPIO34_FFRXD 34 /* FFUART receive */ -#define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ -#define GPIO35_FFCTS 35 /* FFUART Clear to send */ -#define GPIO36_FFDCD 36 /* FFUART Data carrier detect */ -#define GPIO37_FFDSR 37 /* FFUART data set ready */ -#define GPIO38_FFRI 38 /* FFUART Ring Indicator */ -#define GPIO39_MMCCS1 39 /* MMC Chip Select 1 */ -#define GPIO39_FFTXD 39 /* FFUART transmit data */ -#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */ -#define GPIO41_FFRTS 41 /* FFUART request to send */ -#define GPIO42_BTRXD 42 /* BTUART receive data */ -#define GPIO42_HWRXD 42 /* HWUART receive data */ -#define GPIO43_BTTXD 43 /* BTUART transmit data */ -#define GPIO43_HWTXD 43 /* HWUART transmit data */ -#define GPIO44_BTCTS 44 /* BTUART clear to send */ -#define GPIO44_HWCTS 44 /* HWUART clear to send */ -#define GPIO45_BTRTS 45 /* BTUART request to send */ -#define GPIO45_HWRTS 45 /* HWUART request to send */ -#define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */ -#define GPIO46_ICPRXD 46 /* ICP receive data */ -#define GPIO46_STRXD 46 /* STD_UART receive data */ -#define GPIO47_ICPTXD 47 /* ICP transmit data */ -#define GPIO47_STTXD 47 /* STD_UART transmit data */ -#define GPIO48_nPOE 48 /* Output Enable for Card Space */ -#define GPIO49_nPWE 49 /* Write Enable for Card Space */ -#define GPIO50_nPIOR 50 /* I/O Read for Card Space */ -#define GPIO50_CIF_DD_3 50 /* Camera data pin 3 */ -#define GPIO51_nPIOW 51 /* I/O Write for Card Space */ -#define GPIO51_CIF_DD_2 51 /* Camera data pin 2 */ -#define GPIO52_nPCE_1 52 /* Card Enable for Card Space */ -#define GPIO52_CIF_DD_4 52 /* Camera data pin 4 */ -#define GPIO53_nPCE_2 53 /* Card Enable for Card Space */ -#define GPIO53_MMCCLK 53 /* MMC Clock */ -#define GPIO53_CIF_MCLK 53 /* Camera Master Clock */ -#define GPIO54_MMCCLK 54 /* MMC Clock */ -#define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ -#define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27x) */ -#define GPIO54_CIF_PCLK 54 /* Camera Pixel Clock */ -#define GPIO55_nPREG 55 /* Card Address bit 26 */ -#define GPIO55_CIF_DD_1 55 /* Camera data pin 1 */ -#define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ -#define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ -#define GPIO58_LDD_0 58 /* LCD data pin 0 */ -#define GPIO59_LDD_1 59 /* LCD data pin 1 */ -#define GPIO60_LDD_2 60 /* LCD data pin 2 */ -#define GPIO61_LDD_3 61 /* LCD data pin 3 */ -#define GPIO62_LDD_4 62 /* LCD data pin 4 */ -#define GPIO63_LDD_5 63 /* LCD data pin 5 */ -#define GPIO64_LDD_6 64 /* LCD data pin 6 */ -#define GPIO65_LDD_7 65 /* LCD data pin 7 */ -#define GPIO66_LDD_8 66 /* LCD data pin 8 */ -#define GPIO66_MBREQ 66 /* alternate bus master req */ -#define GPIO67_LDD_9 67 /* LCD data pin 9 */ -#define GPIO67_MMCCS0 67 /* MMC Chip Select 0 */ -#define GPIO68_LDD_10 68 /* LCD data pin 10 */ -#define GPIO68_MMCCS1 68 /* MMC Chip Select 1 */ -#define GPIO69_LDD_11 69 /* LCD data pin 11 */ -#define GPIO69_MMCCLK 69 /* MMC_CLK */ -#define GPIO70_LDD_12 70 /* LCD data pin 12 */ -#define GPIO70_RTCCLK 70 /* Real Time clock (1 Hz) */ -#define GPIO71_LDD_13 71 /* LCD data pin 13 */ -#define GPIO71_3_6MHz 71 /* 3.6 MHz Oscillator clock */ -#define GPIO72_LDD_14 72 /* LCD data pin 14 */ -#define GPIO72_32kHz 72 /* 32 kHz clock */ -#define GPIO73_LDD_15 73 /* LCD data pin 15 */ -#define GPIO73_MBGNT 73 /* Memory controller grant */ -#define GPIO74_LCD_FCLK 74 /* LCD Frame clock */ -#define GPIO75_LCD_LCLK 75 /* LCD line clock */ -#define GPIO76_LCD_PCLK 76 /* LCD Pixel clock */ -#define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */ -#define GPIO78_nCS_2 78 /* chip select 2 */ -#define GPIO79_nCS_3 79 /* chip select 3 */ -#define GPIO80_nCS_4 80 /* chip select 4 */ -#define GPIO81_NSCLK 81 /* NSSP clock */ -#define GPIO81_CIF_DD_0 81 /* Camera data pin 0 */ -#define GPIO82_NSFRM 82 /* NSSP Frame */ -#define GPIO82_CIF_DD_5 82 /* Camera data pin 5 */ -#define GPIO83_NSTXD 83 /* NSSP transmit */ -#define GPIO84_NSRXD 84 /* NSSP receive */ -#define GPIO84_CIF_FV 84 /* Camera frame start signal */ -#define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ -#define GPIO85_CIF_LV 85 /* Camera line start signal */ -#define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ -#define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ -#define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ -#define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ -#define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ -#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ -#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ -#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ -#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ -#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ - -/* GPIO alternate function mode & direction */ - -#define GPIO_IN 0x000 -#define GPIO_OUT 0x080 -#define GPIO_ALT_FN_1_IN 0x100 -#define GPIO_ALT_FN_1_OUT 0x180 -#define GPIO_ALT_FN_2_IN 0x200 -#define GPIO_ALT_FN_2_OUT 0x280 -#define GPIO_ALT_FN_3_IN 0x300 -#define GPIO_ALT_FN_3_OUT 0x380 -#define GPIO_MD_MASK_NR 0x07f -#define GPIO_MD_MASK_DIR 0x080 -#define GPIO_MD_MASK_FN 0x300 -#define GPIO_DFLT_LOW 0x400 -#define GPIO_DFLT_HIGH 0x800 - -#define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) -#define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) -#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) -#define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) -#define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) -#define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) -#define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT) -#define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT) -#define GPIO12_CIF_DD_7_MD (12 | GPIO_ALT_FN_2_IN) -#define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT) -#define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN) -#define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT) -#define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT) -#define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT) -#define GPIO17_CIF_DD_6_MD (17 | GPIO_ALT_FN_2_IN) -#define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN) -#define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN) -#define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN) -#define GPIO23_SCLK_MD (23 | GPIO_ALT_FN_2_OUT) -#define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT) -#define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT) -#define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN) -#define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) -#define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) -#define GPIO28_BITCLK_IN_I2S_MD (28 | GPIO_ALT_FN_2_IN) -#define GPIO28_BITCLK_OUT_I2S_MD (28 | GPIO_ALT_FN_1_OUT) -#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) -#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) -#define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) -#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) -#define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) -#define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) -#define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) -#define GPIO32_SYSCLK_I2S_MD (32 | GPIO_ALT_FN_1_OUT) -#define GPIO32_MMCCLK_MD (32 | GPIO_ALT_FN_2_OUT) -#define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) -#define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) -#define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) -#define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) -#define GPIO35_KP_MKOUT6_MD (35 | GPIO_ALT_FN_2_OUT) -#define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN) -#define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN) -#define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN) -#define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT) -#define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) -#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) -#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) -#define GPIO41_KP_MKOUT7_MD (41 | GPIO_ALT_FN_1_OUT) -#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) -#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) -#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) -#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT) -#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) -#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN) -#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) -#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT) -#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) -#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) -#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) -#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) -#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT) -#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) -#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT) -#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) -#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN) -#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT) -#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT) -#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO50_CIF_DD_3_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) -#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) -#define GPIO51_CIF_DD_2_MD (51 | GPIO_ALT_FN_1_IN) -#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) -#define GPIO52_CIF_DD_4_MD (52 | GPIO_ALT_FN_1_IN) -#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) -#define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) -#define GPIO53_CIF_MCLK_MD (53 | GPIO_ALT_FN_2_OUT) -#define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) -#define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) -#define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) -#define GPIO54_CIF_PCLK_MD (54 | GPIO_ALT_FN_3_IN) -#define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) -#define GPIO55_CIF_DD_1_MD (55 | GPIO_ALT_FN_1_IN) -#define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) -#define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN) -#define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT) -#define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT) -#define GPIO60_LDD_2_MD (60 | GPIO_ALT_FN_2_OUT) -#define GPIO61_LDD_3_MD (61 | GPIO_ALT_FN_2_OUT) -#define GPIO62_LDD_4_MD (62 | GPIO_ALT_FN_2_OUT) -#define GPIO63_LDD_5_MD (63 | GPIO_ALT_FN_2_OUT) -#define GPIO64_LDD_6_MD (64 | GPIO_ALT_FN_2_OUT) -#define GPIO65_LDD_7_MD (65 | GPIO_ALT_FN_2_OUT) -#define GPIO66_LDD_8_MD (66 | GPIO_ALT_FN_2_OUT) -#define GPIO66_MBREQ_MD (66 | GPIO_ALT_FN_1_IN) -#define GPIO67_LDD_9_MD (67 | GPIO_ALT_FN_2_OUT) -#define GPIO67_MMCCS0_MD (67 | GPIO_ALT_FN_1_OUT) -#define GPIO68_LDD_10_MD (68 | GPIO_ALT_FN_2_OUT) -#define GPIO68_MMCCS1_MD (68 | GPIO_ALT_FN_1_OUT) -#define GPIO69_LDD_11_MD (69 | GPIO_ALT_FN_2_OUT) -#define GPIO69_MMCCLK_MD (69 | GPIO_ALT_FN_1_OUT) -#define GPIO70_LDD_12_MD (70 | GPIO_ALT_FN_2_OUT) -#define GPIO70_RTCCLK_MD (70 | GPIO_ALT_FN_1_OUT) -#define GPIO71_LDD_13_MD (71 | GPIO_ALT_FN_2_OUT) -#define GPIO71_3_6MHz_MD (71 | GPIO_ALT_FN_1_OUT) -#define GPIO72_LDD_14_MD (72 | GPIO_ALT_FN_2_OUT) -#define GPIO72_32kHz_MD (72 | GPIO_ALT_FN_1_OUT) -#define GPIO73_LDD_15_MD (73 | GPIO_ALT_FN_2_OUT) -#define GPIO73_MBGNT_MD (73 | GPIO_ALT_FN_1_OUT) -#define GPIO74_LCD_FCLK_MD (74 | GPIO_ALT_FN_2_OUT) -#define GPIO75_LCD_LCLK_MD (75 | GPIO_ALT_FN_2_OUT) -#define GPIO76_LCD_PCLK_MD (76 | GPIO_ALT_FN_2_OUT) -#define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT) -#define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT) -#define GPIO78_nPCE_2_MD (78 | GPIO_ALT_FN_1_OUT) -#define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT) -#define GPIO79_pSKTSEL_MD (79 | GPIO_ALT_FN_1_OUT) -#define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) -#define GPIO81_NSSP_CLK_OUT (81 | GPIO_ALT_FN_1_OUT) -#define GPIO81_NSSP_CLK_IN (81 | GPIO_ALT_FN_1_IN) -#define GPIO81_CIF_DD_0_MD (81 | GPIO_ALT_FN_2_IN) -#define GPIO82_NSSP_FRM_OUT (82 | GPIO_ALT_FN_1_OUT) -#define GPIO82_NSSP_FRM_IN (82 | GPIO_ALT_FN_1_IN) -#define GPIO82_CIF_DD_5_MD (82 | GPIO_ALT_FN_3_IN) -#define GPIO83_NSSP_TX (83 | GPIO_ALT_FN_1_OUT) -#define GPIO83_NSSP_RX (83 | GPIO_ALT_FN_2_IN) -#define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) -#define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) -#define GPIO84_CIF_FV_MD (84 | GPIO_ALT_FN_3_IN) -#define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) -#define GPIO85_CIF_LV_MD (85 | GPIO_ALT_FN_3_IN) -#define GPIO86_nPCE_1_MD (86 | GPIO_ALT_FN_1_OUT) -#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) -#define GPIO95_KP_MKIN6_MD (95 | GPIO_ALT_FN_3_IN) -#define GPIO96_KP_DKIN3_MD (96 | GPIO_ALT_FN_1_IN) -#define GPIO97_KP_MKIN3_MD (97 | GPIO_ALT_FN_3_IN) -#define GPIO100_KP_MKIN0_MD (100 | GPIO_ALT_FN_1_IN) -#define GPIO101_KP_MKIN1_MD (101 | GPIO_ALT_FN_1_IN) -#define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) -#define GPIO102_KP_MKIN2_MD (102 | GPIO_ALT_FN_1_IN) -#define GPIO103_KP_MKOUT0_MD (103 | GPIO_ALT_FN_2_OUT) -#define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) -#define GPIO104_KP_MKOUT1_MD (104 | GPIO_ALT_FN_2_OUT) -#define GPIO105_KP_MKOUT2_MD (105 | GPIO_ALT_FN_2_OUT) -#define GPIO106_KP_MKOUT3_MD (106 | GPIO_ALT_FN_2_OUT) -#define GPIO107_KP_MKOUT4_MD (107 | GPIO_ALT_FN_2_OUT) -#define GPIO108_KP_MKOUT5_MD (108 | GPIO_ALT_FN_2_OUT) -#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) -#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) -#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) -#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_IN) -#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) - /* * Power Manager */ diff --git a/include/asm-arm/arch-pxa/pxa2xx-gpio.h b/include/asm-arm/arch-pxa/pxa2xx-gpio.h new file mode 100644 index 000000000000..fb4189447538 --- /dev/null +++ b/include/asm-arm/arch-pxa/pxa2xx-gpio.h @@ -0,0 +1,304 @@ +#ifndef __ASM_ARCH_PXA2XX_GPIO_H +#define __ASM_ARCH_PXA2XX_GPIO_H + +/* GPIO alternate function assignments */ + +#define GPIO1_RST 1 /* reset */ +#define GPIO6_MMCCLK 6 /* MMC Clock */ +#define GPIO7_48MHz 7 /* 48 MHz clock output */ +#define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ +#define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ +#define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ +#define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */ +#define GPIO12_32KHz 12 /* 32 kHz out */ +#define GPIO12_CIF_DD_7 12 /* Camera data pin 7 */ +#define GPIO13_MBGNT 13 /* memory controller grant */ +#define GPIO14_MBREQ 14 /* alternate bus master request */ +#define GPIO15_nCS_1 15 /* chip select 1 */ +#define GPIO16_PWM0 16 /* PWM0 output */ +#define GPIO17_PWM1 17 /* PWM1 output */ +#define GPIO17_CIF_DD_6 17 /* Camera data pin 6 */ +#define GPIO18_RDY 18 /* Ext. Bus Ready */ +#define GPIO19_DREQ1 19 /* External DMA Request */ +#define GPIO20_DREQ0 20 /* External DMA Request */ +#define GPIO23_SCLK 23 /* SSP clock */ +#define GPIO24_SFRM 24 /* SSP Frame */ +#define GPIO25_STXD 25 /* SSP transmit */ +#define GPIO26_SRXD 26 /* SSP receive */ +#define GPIO27_SEXTCLK 27 /* SSP ext_clk */ +#define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */ +#define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */ +#define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ +#define GPIO31_SYNC 31 /* AC97/I2S sync */ +#define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */ +#define GPIO32_SYSCLK 32 /* I2S System Clock */ +#define GPIO32_MMCCLK 32 /* MMC Clock (PXA270) */ +#define GPIO33_nCS_5 33 /* chip select 5 */ +#define GPIO34_FFRXD 34 /* FFUART receive */ +#define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ +#define GPIO35_FFCTS 35 /* FFUART Clear to send */ +#define GPIO36_FFDCD 36 /* FFUART Data carrier detect */ +#define GPIO37_FFDSR 37 /* FFUART data set ready */ +#define GPIO38_FFRI 38 /* FFUART Ring Indicator */ +#define GPIO39_MMCCS1 39 /* MMC Chip Select 1 */ +#define GPIO39_FFTXD 39 /* FFUART transmit data */ +#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */ +#define GPIO41_FFRTS 41 /* FFUART request to send */ +#define GPIO42_BTRXD 42 /* BTUART receive data */ +#define GPIO42_HWRXD 42 /* HWUART receive data */ +#define GPIO43_BTTXD 43 /* BTUART transmit data */ +#define GPIO43_HWTXD 43 /* HWUART transmit data */ +#define GPIO44_BTCTS 44 /* BTUART clear to send */ +#define GPIO44_HWCTS 44 /* HWUART clear to send */ +#define GPIO45_BTRTS 45 /* BTUART request to send */ +#define GPIO45_HWRTS 45 /* HWUART request to send */ +#define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */ +#define GPIO46_ICPRXD 46 /* ICP receive data */ +#define GPIO46_STRXD 46 /* STD_UART receive data */ +#define GPIO47_ICPTXD 47 /* ICP transmit data */ +#define GPIO47_STTXD 47 /* STD_UART transmit data */ +#define GPIO48_nPOE 48 /* Output Enable for Card Space */ +#define GPIO49_nPWE 49 /* Write Enable for Card Space */ +#define GPIO50_nPIOR 50 /* I/O Read for Card Space */ +#define GPIO50_CIF_DD_3 50 /* Camera data pin 3 */ +#define GPIO51_nPIOW 51 /* I/O Write for Card Space */ +#define GPIO51_CIF_DD_2 51 /* Camera data pin 2 */ +#define GPIO52_nPCE_1 52 /* Card Enable for Card Space */ +#define GPIO52_CIF_DD_4 52 /* Camera data pin 4 */ +#define GPIO53_nPCE_2 53 /* Card Enable for Card Space */ +#define GPIO53_MMCCLK 53 /* MMC Clock */ +#define GPIO53_CIF_MCLK 53 /* Camera Master Clock */ +#define GPIO54_MMCCLK 54 /* MMC Clock */ +#define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ +#define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27x) */ +#define GPIO54_CIF_PCLK 54 /* Camera Pixel Clock */ +#define GPIO55_nPREG 55 /* Card Address bit 26 */ +#define GPIO55_CIF_DD_1 55 /* Camera data pin 1 */ +#define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ +#define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ +#define GPIO58_LDD_0 58 /* LCD data pin 0 */ +#define GPIO59_LDD_1 59 /* LCD data pin 1 */ +#define GPIO60_LDD_2 60 /* LCD data pin 2 */ +#define GPIO61_LDD_3 61 /* LCD data pin 3 */ +#define GPIO62_LDD_4 62 /* LCD data pin 4 */ +#define GPIO63_LDD_5 63 /* LCD data pin 5 */ +#define GPIO64_LDD_6 64 /* LCD data pin 6 */ +#define GPIO65_LDD_7 65 /* LCD data pin 7 */ +#define GPIO66_LDD_8 66 /* LCD data pin 8 */ +#define GPIO66_MBREQ 66 /* alternate bus master req */ +#define GPIO67_LDD_9 67 /* LCD data pin 9 */ +#define GPIO67_MMCCS0 67 /* MMC Chip Select 0 */ +#define GPIO68_LDD_10 68 /* LCD data pin 10 */ +#define GPIO68_MMCCS1 68 /* MMC Chip Select 1 */ +#define GPIO69_LDD_11 69 /* LCD data pin 11 */ +#define GPIO69_MMCCLK 69 /* MMC_CLK */ +#define GPIO70_LDD_12 70 /* LCD data pin 12 */ +#define GPIO70_RTCCLK 70 /* Real Time clock (1 Hz) */ +#define GPIO71_LDD_13 71 /* LCD data pin 13 */ +#define GPIO71_3_6MHz 71 /* 3.6 MHz Oscillator clock */ +#define GPIO72_LDD_14 72 /* LCD data pin 14 */ +#define GPIO72_32kHz 72 /* 32 kHz clock */ +#define GPIO73_LDD_15 73 /* LCD data pin 15 */ +#define GPIO73_MBGNT 73 /* Memory controller grant */ +#define GPIO74_LCD_FCLK 74 /* LCD Frame clock */ +#define GPIO75_LCD_LCLK 75 /* LCD line clock */ +#define GPIO76_LCD_PCLK 76 /* LCD Pixel clock */ +#define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */ +#define GPIO78_nCS_2 78 /* chip select 2 */ +#define GPIO79_nCS_3 79 /* chip select 3 */ +#define GPIO80_nCS_4 80 /* chip select 4 */ +#define GPIO81_NSCLK 81 /* NSSP clock */ +#define GPIO81_CIF_DD_0 81 /* Camera data pin 0 */ +#define GPIO82_NSFRM 82 /* NSSP Frame */ +#define GPIO82_CIF_DD_5 82 /* Camera data pin 5 */ +#define GPIO83_NSTXD 83 /* NSSP transmit */ +#define GPIO84_NSRXD 84 /* NSSP receive */ +#define GPIO84_CIF_FV 84 /* Camera frame start signal */ +#define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ +#define GPIO85_CIF_LV 85 /* Camera line start signal */ +#define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ +#define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ +#define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ +#define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ +#define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ +#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ +#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ +#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ +#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ +#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ + +/* GPIO alternate function mode & direction */ + +#define GPIO_IN 0x000 +#define GPIO_OUT 0x080 +#define GPIO_ALT_FN_1_IN 0x100 +#define GPIO_ALT_FN_1_OUT 0x180 +#define GPIO_ALT_FN_2_IN 0x200 +#define GPIO_ALT_FN_2_OUT 0x280 +#define GPIO_ALT_FN_3_IN 0x300 +#define GPIO_ALT_FN_3_OUT 0x380 +#define GPIO_MD_MASK_NR 0x07f +#define GPIO_MD_MASK_DIR 0x080 +#define GPIO_MD_MASK_FN 0x300 +#define GPIO_DFLT_LOW 0x400 +#define GPIO_DFLT_HIGH 0x800 + +#define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) +#define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) +#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) +#define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) +#define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) +#define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) +#define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT) +#define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT) +#define GPIO12_CIF_DD_7_MD (12 | GPIO_ALT_FN_2_IN) +#define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT) +#define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN) +#define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT) +#define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT) +#define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT) +#define GPIO17_CIF_DD_6_MD (17 | GPIO_ALT_FN_2_IN) +#define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN) +#define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN) +#define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN) +#define GPIO23_SCLK_MD (23 | GPIO_ALT_FN_2_OUT) +#define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT) +#define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT) +#define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN) +#define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) +#define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) +#define GPIO28_BITCLK_IN_I2S_MD (28 | GPIO_ALT_FN_2_IN) +#define GPIO28_BITCLK_OUT_I2S_MD (28 | GPIO_ALT_FN_1_OUT) +#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) +#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) +#define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) +#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) +#define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) +#define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) +#define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) +#define GPIO32_SYSCLK_I2S_MD (32 | GPIO_ALT_FN_1_OUT) +#define GPIO32_MMCCLK_MD (32 | GPIO_ALT_FN_2_OUT) +#define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) +#define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) +#define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) +#define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) +#define GPIO35_KP_MKOUT6_MD (35 | GPIO_ALT_FN_2_OUT) +#define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN) +#define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN) +#define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN) +#define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT) +#define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) +#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) +#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) +#define GPIO41_KP_MKOUT7_MD (41 | GPIO_ALT_FN_1_OUT) +#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) +#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) +#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) +#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT) +#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) +#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN) +#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) +#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT) +#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) +#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) +#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) +#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) +#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT) +#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) +#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT) +#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) +#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN) +#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT) +#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT) +#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN) +#define GPIO50_CIF_DD_3_MD (50 | GPIO_ALT_FN_1_IN) +#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) +#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) +#define GPIO51_CIF_DD_2_MD (51 | GPIO_ALT_FN_1_IN) +#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) +#define GPIO52_CIF_DD_4_MD (52 | GPIO_ALT_FN_1_IN) +#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) +#define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) +#define GPIO53_CIF_MCLK_MD (53 | GPIO_ALT_FN_2_OUT) +#define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) +#define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) +#define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) +#define GPIO54_CIF_PCLK_MD (54 | GPIO_ALT_FN_3_IN) +#define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) +#define GPIO55_CIF_DD_1_MD (55 | GPIO_ALT_FN_1_IN) +#define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) +#define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN) +#define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT) +#define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT) +#define GPIO60_LDD_2_MD (60 | GPIO_ALT_FN_2_OUT) +#define GPIO61_LDD_3_MD (61 | GPIO_ALT_FN_2_OUT) +#define GPIO62_LDD_4_MD (62 | GPIO_ALT_FN_2_OUT) +#define GPIO63_LDD_5_MD (63 | GPIO_ALT_FN_2_OUT) +#define GPIO64_LDD_6_MD (64 | GPIO_ALT_FN_2_OUT) +#define GPIO65_LDD_7_MD (65 | GPIO_ALT_FN_2_OUT) +#define GPIO66_LDD_8_MD (66 | GPIO_ALT_FN_2_OUT) +#define GPIO66_MBREQ_MD (66 | GPIO_ALT_FN_1_IN) +#define GPIO67_LDD_9_MD (67 | GPIO_ALT_FN_2_OUT) +#define GPIO67_MMCCS0_MD (67 | GPIO_ALT_FN_1_OUT) +#define GPIO68_LDD_10_MD (68 | GPIO_ALT_FN_2_OUT) +#define GPIO68_MMCCS1_MD (68 | GPIO_ALT_FN_1_OUT) +#define GPIO69_LDD_11_MD (69 | GPIO_ALT_FN_2_OUT) +#define GPIO69_MMCCLK_MD (69 | GPIO_ALT_FN_1_OUT) +#define GPIO70_LDD_12_MD (70 | GPIO_ALT_FN_2_OUT) +#define GPIO70_RTCCLK_MD (70 | GPIO_ALT_FN_1_OUT) +#define GPIO71_LDD_13_MD (71 | GPIO_ALT_FN_2_OUT) +#define GPIO71_3_6MHz_MD (71 | GPIO_ALT_FN_1_OUT) +#define GPIO72_LDD_14_MD (72 | GPIO_ALT_FN_2_OUT) +#define GPIO72_32kHz_MD (72 | GPIO_ALT_FN_1_OUT) +#define GPIO73_LDD_15_MD (73 | GPIO_ALT_FN_2_OUT) +#define GPIO73_MBGNT_MD (73 | GPIO_ALT_FN_1_OUT) +#define GPIO74_LCD_FCLK_MD (74 | GPIO_ALT_FN_2_OUT) +#define GPIO75_LCD_LCLK_MD (75 | GPIO_ALT_FN_2_OUT) +#define GPIO76_LCD_PCLK_MD (76 | GPIO_ALT_FN_2_OUT) +#define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT) +#define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT) +#define GPIO78_nPCE_2_MD (78 | GPIO_ALT_FN_1_OUT) +#define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT) +#define GPIO79_pSKTSEL_MD (79 | GPIO_ALT_FN_1_OUT) +#define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) +#define GPIO81_NSSP_CLK_OUT (81 | GPIO_ALT_FN_1_OUT) +#define GPIO81_NSSP_CLK_IN (81 | GPIO_ALT_FN_1_IN) +#define GPIO81_CIF_DD_0_MD (81 | GPIO_ALT_FN_2_IN) +#define GPIO82_NSSP_FRM_OUT (82 | GPIO_ALT_FN_1_OUT) +#define GPIO82_NSSP_FRM_IN (82 | GPIO_ALT_FN_1_IN) +#define GPIO82_CIF_DD_5_MD (82 | GPIO_ALT_FN_3_IN) +#define GPIO83_NSSP_TX (83 | GPIO_ALT_FN_1_OUT) +#define GPIO83_NSSP_RX (83 | GPIO_ALT_FN_2_IN) +#define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) +#define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) +#define GPIO84_CIF_FV_MD (84 | GPIO_ALT_FN_3_IN) +#define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) +#define GPIO85_CIF_LV_MD (85 | GPIO_ALT_FN_3_IN) +#define GPIO86_nPCE_1_MD (86 | GPIO_ALT_FN_1_OUT) +#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) +#define GPIO95_KP_MKIN6_MD (95 | GPIO_ALT_FN_3_IN) +#define GPIO96_KP_DKIN3_MD (96 | GPIO_ALT_FN_1_IN) +#define GPIO97_KP_MKIN3_MD (97 | GPIO_ALT_FN_3_IN) +#define GPIO100_KP_MKIN0_MD (100 | GPIO_ALT_FN_1_IN) +#define GPIO101_KP_MKIN1_MD (101 | GPIO_ALT_FN_1_IN) +#define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) +#define GPIO102_KP_MKIN2_MD (102 | GPIO_ALT_FN_1_IN) +#define GPIO103_KP_MKOUT0_MD (103 | GPIO_ALT_FN_2_OUT) +#define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) +#define GPIO104_KP_MKOUT1_MD (104 | GPIO_ALT_FN_2_OUT) +#define GPIO105_KP_MKOUT2_MD (105 | GPIO_ALT_FN_2_OUT) +#define GPIO106_KP_MKOUT3_MD (106 | GPIO_ALT_FN_2_OUT) +#define GPIO107_KP_MKOUT4_MD (107 | GPIO_ALT_FN_2_OUT) +#define GPIO108_KP_MKOUT5_MD (108 | GPIO_ALT_FN_2_OUT) +#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) +#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) +#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) +#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) +#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) +#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_IN) +#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) + +#endif /* __ASM_ARCH_PXA2XX_GPIO_H */ diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index fd7bc865e672..8704e2825b10 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 711b916e58a6..fe9c297ae6f2 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 692b90002489..425071030970 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -25,6 +25,7 @@ #include #include +#include #include #include "pxa2xx-pcm.h" -- cgit v1.2.3 From 3d4382913f9a86f0d9ff47740feb427415fe7234 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 22 Apr 2008 22:16:46 +0200 Subject: i2c-algo-pca: Remove trailing whitespaces and unnecessary UTF Remove trailing whitespaces to make further patches more readable. Also remove an unnecessary UTF-char for simplicity ("us" for microseconds is fine enough). Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-pca.c | 42 ++++++++++++++++++++-------------------- drivers/i2c/busses/i2c-pca-isa.c | 4 ++-- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 2a16211f12e5..ebec91d71e1e 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -1,5 +1,5 @@ /* - * i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters + * i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters * Copyright (C) 2004 Arcom Control Systems * * This program is free software; you can redistribute it and/or modify @@ -99,7 +99,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap) * * returns after the address has been sent */ -static void pca_address(struct i2c_algo_pca_data *adap, +static void pca_address(struct i2c_algo_pca_data *adap, struct i2c_msg *msg) { int sta = pca_get_con(adap); @@ -108,9 +108,9 @@ static void pca_address(struct i2c_algo_pca_data *adap, addr = ( (0x7f & msg->addr) << 1 ); if (msg->flags & I2C_M_RD ) addr |= 1; - DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n", + DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n", msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr); - + pca_outw(adap, I2C_PCA_DAT, addr); sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); @@ -124,7 +124,7 @@ static void pca_address(struct i2c_algo_pca_data *adap, * * Returns after the byte has been transmitted */ -static void pca_tx_byte(struct i2c_algo_pca_data *adap, +static void pca_tx_byte(struct i2c_algo_pca_data *adap, __u8 b) { int sta = pca_get_con(adap); @@ -142,19 +142,19 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap, * * returns immediately. */ -static void pca_rx_byte(struct i2c_algo_pca_data *adap, +static void pca_rx_byte(struct i2c_algo_pca_data *adap, __u8 *b, int ack) { *b = pca_inw(adap, I2C_PCA_DAT); DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK"); } -/* +/* * Setup ACK or NACK for next received byte and wait for it to arrive. * * Returns after next byte has arrived. */ -static void pca_rx_ack(struct i2c_algo_pca_data *adap, +static void pca_rx_ack(struct i2c_algo_pca_data *adap, int ack) { int sta = pca_get_con(adap); @@ -168,8 +168,8 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap, pca_wait(adap); } -/* - * Reset the i2c bus / SIO +/* + * Reset the i2c bus / SIO */ static void pca_reset(struct i2c_algo_pca_data *adap) { @@ -203,14 +203,14 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, for (curmsg = 0; curmsg < num; curmsg++) { int addr, i; msg = &msgs[curmsg]; - + addr = (0x7f & msg->addr) ; - + if (msg->flags & I2C_M_RD ) - printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n", + printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n", curmsg, msg->len, addr, (addr<<1) | 1); else { - printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s", + printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s", curmsg, msg->len, addr, addr<<1, msg->len == 0 ? "" : ", "); for(i=0; i < msg->len; i++) @@ -237,7 +237,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, case 0x10: /* A repeated start condition has been transmitted */ pca_address(adap, msg); break; - + case 0x18: /* SLA+W has been transmitted; ACK has been received */ case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */ if (numbytes < msg->len) { @@ -287,7 +287,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */ DEB2("Arbitration lost\n"); goto out; - + case 0x58: /* Data byte has been received; NOT ACK has been returned */ if ( numbytes == msg->len - 1 ) { pca_rx_byte(adap, &msg->buf[numbytes], 0); @@ -320,13 +320,13 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state); break; } - + } ret = curmsg; out: DEB1(KERN_CRIT "}}} transfered %d/%d messages. " - "status is %#04x. control is %#04x\n", + "status is %#04x. control is %#04x\n", curmsg, num, pca_status(adap), pca_get_con(adap)); return ret; @@ -350,7 +350,7 @@ static int pca_init(struct i2c_algo_pca_data *adap) pca_outw(adap, I2C_PCA_ADR, own << 1); pca_set_con(adap, I2C_PCA_CON_ENSIO | clock); - udelay(500); /* 500 µs for oscilator to stabilise */ + udelay(500); /* 500 us for oscilator to stabilise */ return 0; } @@ -360,8 +360,8 @@ static const struct i2c_algorithm pca_algo = { .functionality = pca_func, }; -/* - * registering functions to load algorithms at runtime +/* + * registering functions to load algorithms at runtime */ int i2c_pca_add_bus(struct i2c_adapter *adap) { diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index 496ee875eb4f..93ed3251893d 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -78,7 +78,7 @@ pca_isa_readbyte(struct i2c_algo_pca_data *adap, int reg) int res = inb(base+reg); #ifdef DEBUG_IO { - static char *names[] = { "STA", "DAT", "ADR", "CON" }; + static char *names[] = { "STA", "DAT", "ADR", "CON" }; printk("*** read %s => %#04x\n", names[reg], res); } #endif @@ -93,7 +93,7 @@ static int pca_isa_waitforinterrupt(struct i2c_algo_pca_data *adap) ret = wait_event_interruptible(pca_wait, pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI); } else { - while ((pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) + while ((pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) udelay(100); } return ret; -- cgit v1.2.3 From c01b0831057381c7f6e0bfb3634bac8c5f7fb256 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 22 Apr 2008 22:16:46 +0200 Subject: i2c-algo-pca: Extend for future drivers The separation between algorithm and adapter was unsharp at places. This was partly hidden by the fact, that the ISA-driver allowed just one instance and had all private data in static variables. This patch makes neccessary preparations to add a platform driver on top of the algorithm, while still supporting ISA. Note: Due to lack of hardware, the ISA-driver could not be tested except that it builds. Concerning the core struct i2c_algo_pca_data: - A private data field was added, all hardware dependant data may go here. Similar to other algorithms, now a pointer to this data is passed to the adapter's functions. In order to make as less changes as possible to the ISA-driver, it leaves the private data empty and still only uses its static variables. - A "reset_chip" function pointer was added; such a functionality must come from the adapter, not the algorithm. - use a variable "i2c_clock" instead of a function pointer "get_clock", allowing for write access to a default in case a wrong value was supplied. In the algorithm-file: - move "i2c-pca-algo.h" into "linux/i2c-algo-pca.h" - now using per_instance timeout values (i2c_adap->timeout) - error messages specify the device, not only the driver name - restructure initialization to easily support "i2c_add_numbered_adapter" - drop "retries" and "own" (i2c address) as they were unused (The state-machine for I2C-communication was not touched.) In the ISA-driver: - adapt to new algorithm Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-pca.c | 88 ++++++++++++++++++++-------------------- drivers/i2c/algos/i2c-algo-pca.h | 26 ------------ drivers/i2c/busses/i2c-pca-isa.c | 51 +++++++++-------------- include/linux/i2c-algo-pca.h | 37 ++++++++++++++--- 4 files changed, 95 insertions(+), 107 deletions(-) delete mode 100644 drivers/i2c/algos/i2c-algo-pca.h (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index ebec91d71e1e..e954a20b97a6 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -1,6 +1,7 @@ /* * i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters * Copyright (C) 2004 Arcom Control Systems + * Copyright (C) 2008 Pengutronix * * 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 @@ -21,14 +22,10 @@ #include #include #include -#include #include #include #include #include -#include "i2c-algo-pca.h" - -#define DRIVER "i2c-algo-pca" #define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0) #define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0) @@ -36,15 +33,15 @@ static int i2c_debug; -#define pca_outw(adap, reg, val) adap->write_byte(adap, reg, val) -#define pca_inw(adap, reg) adap->read_byte(adap, reg) +#define pca_outw(adap, reg, val) adap->write_byte(adap->data, reg, val) +#define pca_inw(adap, reg) adap->read_byte(adap->data, reg) #define pca_status(adap) pca_inw(adap, I2C_PCA_STA) -#define pca_clock(adap) adap->get_clock(adap) -#define pca_own(adap) adap->get_own(adap) +#define pca_clock(adap) adap->i2c_clock #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val) #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON) -#define pca_wait(adap) adap->wait_for_interrupt(adap) +#define pca_wait(adap) adap->wait_for_completion(adap->data) +#define pca_reset(adap) adap->reset_chip(adap->data) /* * Generate a start condition on the i2c bus. @@ -168,15 +165,6 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap, pca_wait(adap); } -/* - * Reset the i2c bus / SIO - */ -static void pca_reset(struct i2c_algo_pca_data *adap) -{ - /* apparently only an external reset will do it. not a lot can be done */ - printk(KERN_ERR DRIVER ": Haven't figured out how to do a reset yet\n"); -} - static int pca_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) @@ -187,7 +175,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, int numbytes = 0; int state; int ret; - int timeout = 100; + int timeout = i2c_adap->timeout; while ((state = pca_status(adap)) != 0xf8 && timeout--) { msleep(10); @@ -317,7 +305,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, pca_reset(adap); goto out; default: - printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state); + dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state); break; } @@ -337,53 +325,65 @@ static u32 pca_func(struct i2c_adapter *adap) return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } -static int pca_init(struct i2c_algo_pca_data *adap) +static const struct i2c_algorithm pca_algo = { + .master_xfer = pca_xfer, + .functionality = pca_func, +}; + +static int pca_init(struct i2c_adapter *adap) { static int freqs[] = {330,288,217,146,88,59,44,36}; - int own, clock; + int clock; + struct i2c_algo_pca_data *pca_data = adap->algo_data; + + if (pca_data->i2c_clock > 7) { + printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n", + adap->name); + pca_data->i2c_clock = I2C_PCA_CON_59kHz; + } + + adap->algo = &pca_algo; - own = pca_own(adap); - clock = pca_clock(adap); - DEB1(KERN_INFO DRIVER ": own address is %#04x\n", own); - DEB1(KERN_INFO DRIVER ": clock freqeuncy is %dkHz\n", freqs[clock]); + pca_reset(pca_data); - pca_outw(adap, I2C_PCA_ADR, own << 1); + clock = pca_clock(pca_data); + DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); - pca_set_con(adap, I2C_PCA_CON_ENSIO | clock); + pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); udelay(500); /* 500 us for oscilator to stabilise */ return 0; } -static const struct i2c_algorithm pca_algo = { - .master_xfer = pca_xfer, - .functionality = pca_func, -}; - /* * registering functions to load algorithms at runtime */ int i2c_pca_add_bus(struct i2c_adapter *adap) { - struct i2c_algo_pca_data *pca_adap = adap->algo_data; int rval; - /* register new adapter to i2c module... */ - adap->algo = &pca_algo; + rval = pca_init(adap); + if (rval) + return rval; - adap->timeout = 100; /* default values, should */ - adap->retries = 3; /* be replaced by defines */ + return i2c_add_adapter(adap); +} +EXPORT_SYMBOL(i2c_pca_add_bus); - if ((rval = pca_init(pca_adap))) - return rval; +int i2c_pca_add_numbered_bus(struct i2c_adapter *adap) +{ + int rval; - rval = i2c_add_adapter(adap); + rval = pca_init(adap); + if (rval) + return rval; - return rval; + return i2c_add_numbered_adapter(adap); } -EXPORT_SYMBOL(i2c_pca_add_bus); +EXPORT_SYMBOL(i2c_pca_add_numbered_bus); -MODULE_AUTHOR("Ian Campbell "); +MODULE_AUTHOR("Ian Campbell , " + "Wolfram Sang "); MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm"); MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/algos/i2c-algo-pca.h b/drivers/i2c/algos/i2c-algo-pca.h deleted file mode 100644 index 2fee07e05211..000000000000 --- a/drivers/i2c/algos/i2c-algo-pca.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef I2C_PCA9564_H -#define I2C_PCA9564_H 1 - -#define I2C_PCA_STA 0x00 /* STATUS Read Only */ -#define I2C_PCA_TO 0x00 /* TIMEOUT Write Only */ -#define I2C_PCA_DAT 0x01 /* DATA Read/Write */ -#define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */ -#define I2C_PCA_CON 0x03 /* CONTROL Read/Write */ - -#define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */ -#define I2C_PCA_CON_ENSIO 0x40 /* Enable */ -#define I2C_PCA_CON_STA 0x20 /* Start */ -#define I2C_PCA_CON_STO 0x10 /* Stop */ -#define I2C_PCA_CON_SI 0x08 /* Serial Interrupt */ -#define I2C_PCA_CON_CR 0x07 /* Clock Rate (MASK) */ - -#define I2C_PCA_CON_330kHz 0x00 -#define I2C_PCA_CON_288kHz 0x01 -#define I2C_PCA_CON_217kHz 0x02 -#define I2C_PCA_CON_146kHz 0x03 -#define I2C_PCA_CON_88kHz 0x04 -#define I2C_PCA_CON_59kHz 0x05 -#define I2C_PCA_CON_44kHz 0x06 -#define I2C_PCA_CON_36kHz 0x07 - -#endif /* I2C_PCA9564_H */ diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index 93ed3251893d..a119784bae10 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -1,6 +1,7 @@ /* * i2c-pca-isa.c driver for PCA9564 on ISA boards * Copyright (C) 2004 Arcom Control Systems + * Copyright (C) 2008 Pengutronix * * 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 @@ -22,11 +23,9 @@ #include #include #include -#include #include #include #include - #include #include #include @@ -34,13 +33,9 @@ #include #include -#include "../algos/i2c-algo-pca.h" - +#define DRIVER "i2c-pca-isa" #define IO_SIZE 4 -#undef DEBUG_IO -//#define DEBUG_IO - static unsigned long base = 0x330; static int irq = 10; @@ -48,22 +43,9 @@ static int irq = 10; * in the actual clock rate */ static int clock = I2C_PCA_CON_59kHz; -static int own = 0x55; - static wait_queue_head_t pca_wait; -static int pca_isa_getown(struct i2c_algo_pca_data *adap) -{ - return (own); -} - -static int pca_isa_getclock(struct i2c_algo_pca_data *adap) -{ - return (clock); -} - -static void -pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val) +static void pca_isa_writebyte(void *pd, int reg, int val) { #ifdef DEBUG_IO static char *names[] = { "T/O", "DAT", "ADR", "CON" }; @@ -72,8 +54,7 @@ pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val) outb(val, base+reg); } -static int -pca_isa_readbyte(struct i2c_algo_pca_data *adap, int reg) +static int pca_isa_readbyte(void *pd, int reg) { int res = inb(base+reg); #ifdef DEBUG_IO @@ -85,31 +66,37 @@ pca_isa_readbyte(struct i2c_algo_pca_data *adap, int reg) return res; } -static int pca_isa_waitforinterrupt(struct i2c_algo_pca_data *adap) +static int pca_isa_waitforcompletion(void *pd) { int ret = 0; if (irq > -1) { ret = wait_event_interruptible(pca_wait, - pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI); + pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI); } else { - while ((pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) + while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) udelay(100); } return ret; } +static void pca_isa_resetchip(void *pd) +{ + /* apparently only an external reset will do it. not a lot can be done */ + printk(KERN_WARNING DRIVER ": Haven't figured out how to do a reset yet\n"); +} + static irqreturn_t pca_handler(int this_irq, void *dev_id) { wake_up_interruptible(&pca_wait); return IRQ_HANDLED; } static struct i2c_algo_pca_data pca_isa_data = { - .get_own = pca_isa_getown, - .get_clock = pca_isa_getclock, + /* .data intentionally left NULL, not needed with ISA */ .write_byte = pca_isa_writebyte, .read_byte = pca_isa_readbyte, - .wait_for_interrupt = pca_isa_waitforinterrupt, + .wait_for_completion = pca_isa_waitforcompletion, + .reset_chip = pca_isa_resetchip, }; static struct i2c_adapter pca_isa_ops = { @@ -117,6 +104,7 @@ static struct i2c_adapter pca_isa_ops = { .id = I2C_HW_A_ISA, .algo_data = &pca_isa_data, .name = "PCA9564 ISA Adapter", + .timeout = 100, }; static int __devinit pca_isa_probe(struct device *dev, unsigned int id) @@ -144,6 +132,7 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id) } } + pca_isa_data.i2c_clock = clock; if (i2c_pca_add_bus(&pca_isa_ops) < 0) { dev_err(dev, "Failed to add i2c bus\n"); goto out_irq; @@ -178,7 +167,7 @@ static struct isa_driver pca_isa_driver = { .remove = __devexit_p(pca_isa_remove), .driver = { .owner = THIS_MODULE, - .name = "i2c-pca-isa", + .name = DRIVER, } }; @@ -204,7 +193,5 @@ MODULE_PARM_DESC(irq, "IRQ"); module_param(clock, int, 0); MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet"); -module_param(own, int, 0); /* the driver can't do slave mode, so there's no real point in this */ - module_init(pca_isa_init); module_exit(pca_isa_exit); diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h index fce47c051bb1..adcb3dc7ac26 100644 --- a/include/linux/i2c-algo-pca.h +++ b/include/linux/i2c-algo-pca.h @@ -1,14 +1,41 @@ #ifndef _LINUX_I2C_ALGO_PCA_H #define _LINUX_I2C_ALGO_PCA_H +/* Clock speeds for the bus */ +#define I2C_PCA_CON_330kHz 0x00 +#define I2C_PCA_CON_288kHz 0x01 +#define I2C_PCA_CON_217kHz 0x02 +#define I2C_PCA_CON_146kHz 0x03 +#define I2C_PCA_CON_88kHz 0x04 +#define I2C_PCA_CON_59kHz 0x05 +#define I2C_PCA_CON_44kHz 0x06 +#define I2C_PCA_CON_36kHz 0x07 + +/* PCA9564 registers */ +#define I2C_PCA_STA 0x00 /* STATUS Read Only */ +#define I2C_PCA_TO 0x00 /* TIMEOUT Write Only */ +#define I2C_PCA_DAT 0x01 /* DATA Read/Write */ +#define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */ +#define I2C_PCA_CON 0x03 /* CONTROL Read/Write */ + +#define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */ +#define I2C_PCA_CON_ENSIO 0x40 /* Enable */ +#define I2C_PCA_CON_STA 0x20 /* Start */ +#define I2C_PCA_CON_STO 0x10 /* Stop */ +#define I2C_PCA_CON_SI 0x08 /* Serial Interrupt */ +#define I2C_PCA_CON_CR 0x07 /* Clock Rate (MASK) */ + struct i2c_algo_pca_data { - int (*get_own) (struct i2c_algo_pca_data *adap); /* Obtain own address */ - int (*get_clock) (struct i2c_algo_pca_data *adap); - void (*write_byte) (struct i2c_algo_pca_data *adap, int reg, int val); - int (*read_byte) (struct i2c_algo_pca_data *adap, int reg); - int (*wait_for_interrupt) (struct i2c_algo_pca_data *adap); + void *data; /* private low level data */ + void (*write_byte) (void *data, int reg, int val); + int (*read_byte) (void *data, int reg); + int (*wait_for_completion) (void *data); + void (*reset_chip) (void *data); + /* i2c_clock values are defined in linux/i2c-algo-pca.h */ + unsigned int i2c_clock; }; int i2c_pca_add_bus(struct i2c_adapter *); +int i2c_pca_add_numbered_bus(struct i2c_adapter *); #endif /* _LINUX_I2C_ALGO_PCA_H */ -- cgit v1.2.3 From 244fbbb81c46eefcc5f3a9cc37c4668f9d8ff801 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 22 Apr 2008 22:16:46 +0200 Subject: i2c: Add platform driver on top of the new pca-algorithm Tested on a blackfin. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 15 +- drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-pca-platform.c | 298 ++++++++++++++++++++++++++++++++++ include/linux/i2c-pca-platform.h | 12 ++ 4 files changed, 324 insertions(+), 2 deletions(-) create mode 100644 drivers/i2c/busses/i2c-pca-platform.c create mode 100644 include/linux/i2c-pca-platform.h (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b04c99580d0d..51de2ccc1519 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -632,8 +632,8 @@ config I2C_PCA_ISA select I2C_ALGOPCA default n help - This driver supports ISA boards using the Philips PCA 9564 - Parallel bus to I2C bus controller + This driver supports ISA boards using the Philips PCA9564 + parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module will be called i2c-pca-isa. @@ -643,6 +643,17 @@ config I2C_PCA_ISA delays when I2C/SMBus chip drivers are loaded (e.g. at boot time). If unsure, say N. +config I2C_PCA_PLATFORM + tristate "PCA9564 as platform device" + select I2C_ALGOPCA + default n + help + This driver supports a memory mapped Philips PCA9564 + parallel bus to I2C bus controller. + + This driver can also be built as a module. If so, the module + will be called i2c-pca-platform. + config I2C_MV64XXX tristate "Marvell mv64xxx I2C Controller" depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ea7068f1eb6b..378d5c07e048 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o +obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o obj-$(CONFIG_I2C_PNX) += i2c-pnx.o diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c new file mode 100644 index 000000000000..9d75f51e8f0e --- /dev/null +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -0,0 +1,298 @@ +/* + * i2c_pca_platform.c + * + * Platform driver for the PCA9564 I2C controller. + * + * Copyright (C) 2008 Pengutronix + * + * 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 + +#define res_len(r) ((r)->end - (r)->start + 1) + +struct i2c_pca_pf_data { + void __iomem *reg_base; + int irq; /* if 0, use polling */ + int gpio; + wait_queue_head_t wait; + struct i2c_adapter adap; + struct i2c_algo_pca_data algo_data; + unsigned long io_base; + unsigned long io_size; +}; + +/* Read/Write functions for different register alignments */ + +static int i2c_pca_pf_readbyte8(void *pd, int reg) +{ + struct i2c_pca_pf_data *i2c = pd; + return ioread8(i2c->reg_base + reg); +} + +static int i2c_pca_pf_readbyte16(void *pd, int reg) +{ + struct i2c_pca_pf_data *i2c = pd; + return ioread8(i2c->reg_base + reg * 2); +} + +static int i2c_pca_pf_readbyte32(void *pd, int reg) +{ + struct i2c_pca_pf_data *i2c = pd; + return ioread8(i2c->reg_base + reg * 4); +} + +static void i2c_pca_pf_writebyte8(void *pd, int reg, int val) +{ + struct i2c_pca_pf_data *i2c = pd; + iowrite8(val, i2c->reg_base + reg); +} + +static void i2c_pca_pf_writebyte16(void *pd, int reg, int val) +{ + struct i2c_pca_pf_data *i2c = pd; + iowrite8(val, i2c->reg_base + reg * 2); +} + +static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) +{ + struct i2c_pca_pf_data *i2c = pd; + iowrite8(val, i2c->reg_base + reg * 4); +} + + +static int i2c_pca_pf_waitforcompletion(void *pd) +{ + struct i2c_pca_pf_data *i2c = pd; + int ret = 0; + + if (i2c->irq) { + ret = wait_event_interruptible(i2c->wait, + i2c->algo_data.read_byte(i2c, I2C_PCA_CON) + & I2C_PCA_CON_SI); + } else { + /* + * Do polling... + * XXX: Could get stuck in extreme cases! + * Maybe add timeout, but using irqs is preferred anyhow. + */ + while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) + & I2C_PCA_CON_SI) == 0) + udelay(100); + } + + return ret; +} + +static void i2c_pca_pf_dummyreset(void *pd) +{ + struct i2c_pca_pf_data *i2c = pd; + printk(KERN_WARNING "%s: No reset-pin found. Chip may get stuck!\n", + i2c->adap.name); +} + +static void i2c_pca_pf_resetchip(void *pd) +{ + struct i2c_pca_pf_data *i2c = pd; + + gpio_set_value(i2c->gpio, 0); + ndelay(100); + gpio_set_value(i2c->gpio, 1); +} + +static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id) +{ + struct i2c_pca_pf_data *i2c = dev_id; + + if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) + return IRQ_NONE; + + wake_up_interruptible(&i2c->wait); + + return IRQ_HANDLED; +} + + +static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) +{ + struct i2c_pca_pf_data *i2c; + struct resource *res; + struct i2c_pca9564_pf_platform_data *platform_data = + pdev->dev.platform_data; + int ret = 0; + int irq; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + /* If irq is 0, we do polling. */ + + if (res == NULL) { + ret = -ENODEV; + goto e_print; + } + + if (!request_mem_region(res->start, res_len(res), res->name)) { + ret = -ENOMEM; + goto e_print; + } + + i2c = kzalloc(sizeof(struct i2c_pca_pf_data), GFP_KERNEL); + if (!i2c) { + ret = -ENOMEM; + goto e_alloc; + } + + init_waitqueue_head(&i2c->wait); + + i2c->reg_base = ioremap(res->start, res_len(res)); + if (!i2c->reg_base) { + ret = -EIO; + goto e_remap; + } + i2c->io_base = res->start; + i2c->io_size = res_len(res); + i2c->irq = irq; + + i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0; + i2c->adap.owner = THIS_MODULE; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx", + (unsigned long) res->start); + i2c->adap.algo_data = &i2c->algo_data; + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.timeout = platform_data->timeout; + + i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed; + i2c->algo_data.data = i2c; + + switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { + case IORESOURCE_MEM_32BIT: + i2c->algo_data.write_byte = i2c_pca_pf_writebyte32; + i2c->algo_data.read_byte = i2c_pca_pf_readbyte32; + break; + case IORESOURCE_MEM_16BIT: + i2c->algo_data.write_byte = i2c_pca_pf_writebyte16; + i2c->algo_data.read_byte = i2c_pca_pf_readbyte16; + break; + case IORESOURCE_MEM_8BIT: + default: + i2c->algo_data.write_byte = i2c_pca_pf_writebyte8; + i2c->algo_data.read_byte = i2c_pca_pf_readbyte8; + break; + } + + i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion; + + i2c->gpio = platform_data->gpio; + i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset; + + /* Use gpio_is_valid() when in mainline */ + if (i2c->gpio > -1) { + ret = gpio_request(i2c->gpio, i2c->adap.name); + if (ret == 0) { + gpio_direction_output(i2c->gpio, 1); + i2c->algo_data.reset_chip = i2c_pca_pf_resetchip; + } else { + printk(KERN_WARNING "%s: Registering gpio failed!\n", + i2c->adap.name); + i2c->gpio = ret; + } + } + + if (irq) { + ret = request_irq(irq, i2c_pca_pf_handler, + IRQF_TRIGGER_FALLING, i2c->adap.name, i2c); + if (ret) + goto e_reqirq; + } + + if (i2c_pca_add_numbered_bus(&i2c->adap) < 0) { + ret = -ENODEV; + goto e_adapt; + } + + platform_set_drvdata(pdev, i2c); + + printk(KERN_INFO "%s registered.\n", i2c->adap.name); + + return 0; + +e_adapt: + if (irq) + free_irq(irq, i2c); +e_reqirq: + if (i2c->gpio > -1) + gpio_free(i2c->gpio); + + iounmap(i2c->reg_base); +e_remap: + kfree(i2c); +e_alloc: + release_mem_region(res->start, res_len(res)); +e_print: + printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret); + return ret; +} + +static int __devexit i2c_pca_pf_remove(struct platform_device *pdev) +{ + struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, NULL); + + i2c_del_adapter(&i2c->adap); + + if (i2c->irq) + free_irq(i2c->irq, i2c); + + if (i2c->gpio > -1) + gpio_free(i2c->gpio); + + iounmap(i2c->reg_base); + release_mem_region(i2c->io_base, i2c->io_size); + kfree(i2c); + + return 0; +} + +static struct platform_driver i2c_pca_pf_driver = { + .probe = i2c_pca_pf_probe, + .remove = __devexit_p(i2c_pca_pf_remove), + .driver = { + .name = "i2c-pca-platform", + .owner = THIS_MODULE, + }, +}; + +static int __init i2c_pca_pf_init(void) +{ + return platform_driver_register(&i2c_pca_pf_driver); +} + +static void __exit i2c_pca_pf_exit(void) +{ + platform_driver_unregister(&i2c_pca_pf_driver); +} + +MODULE_AUTHOR("Wolfram Sang "); +MODULE_DESCRIPTION("I2C-PCA9564 platform driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_pca_pf_init); +module_exit(i2c_pca_pf_exit); + diff --git a/include/linux/i2c-pca-platform.h b/include/linux/i2c-pca-platform.h new file mode 100644 index 000000000000..3d191873f2d1 --- /dev/null +++ b/include/linux/i2c-pca-platform.h @@ -0,0 +1,12 @@ +#ifndef I2C_PCA9564_PLATFORM_H +#define I2C_PCA9564_PLATFORM_H + +struct i2c_pca9564_pf_platform_data { + int gpio; /* pin to reset chip. driver will work when + * not supplied (negative value), but it + * cannot exit some error conditions then */ + int i2c_clock_speed; /* values are defined in linux/i2c-algo-pca.h */ + int timeout; /* timeout = this value * 10us */ +}; + +#endif /* I2C_PCA9564_PLATFORM_H */ -- cgit v1.2.3 From 681aae82c5804f8bbecbb495da90587d4167753c Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 22 Apr 2008 22:16:46 +0200 Subject: i2c-ibm_iic: Change the log levels Change the log levels based on feedback from linxppc-dev. Signed-off-by: Sean MacLennan Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-ibm_iic.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 22bb247d0e60..b330a0c9a6a5 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -650,7 +650,7 @@ static inline u8 iic_clckdiv(unsigned int opb) opb /= 1000000; if (opb < 20 || opb > 150){ - printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n", + printk(KERN_WARNING "ibm-iic: invalid OPB clock frequency %u MHz\n", opb); opb = opb < 20 ? 20 : 150; } @@ -672,7 +672,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ ocp->def->index); if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) { - printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n", + printk(KERN_ERR "ibm-iic%d: failed to allocate device data\n", ocp->def->index); return -ENOMEM; } @@ -687,7 +687,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ } if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){ - printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n", + printk(KERN_ERR "ibm-iic%d: failed to ioremap device registers\n", dev->idx); ret = -ENXIO; goto fail2; @@ -745,7 +745,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ adap->nr = dev->idx >= 0 ? dev->idx : 0; if ((ret = i2c_add_numbered_adapter(adap)) < 0) { - printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n", + printk(KERN_ERR "ibm-iic%d: failed to register i2c adapter\n", dev->idx); goto fail; } @@ -778,7 +778,7 @@ static void __devexit iic_remove(struct ocp_device *ocp) struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp); BUG_ON(dev == NULL); if (i2c_del_adapter(&dev->adap)){ - printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n", + printk(KERN_ERR "ibm-iic%d: failed to delete i2c adapter :(\n", dev->idx); /* That's *very* bad, just shutdown IRQ ... */ if (dev->irq >= 0){ -- cgit v1.2.3 From 838349b5c6454ebce8ec3e8c448941cf8608ffea Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 22 Apr 2008 22:16:47 +0200 Subject: i2c-ibm_iic: Support building as an of_platform driver This patch allows the i2c-ibm_iic driver to be built either as an ocp driver or an of_platform driver. This allows it to run under the powerpc arch but maintains backward compatibility with the ppc arch. Signed-off-by: Sean MacLennan Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 2 +- drivers/i2c/busses/i2c-ibm_iic.c | 187 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 187 insertions(+), 2 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 51de2ccc1519..1577bcad288a 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -246,7 +246,7 @@ config I2C_PIIX4 config I2C_IBM_IIC tristate "IBM PPC 4xx on-chip I2C interface" - depends on IBM_OCP + depends on 4xx help Say Y here if you want to use IIC peripheral found on embedded IBM PPC 4xx based systems. diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index b330a0c9a6a5..85dbf34382e1 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -6,6 +6,9 @@ * Copyright (c) 2003, 2004 Zultys Technologies. * Eugene Surovegin or * + * Copyright (c) 2008 PIKA Technologies + * Sean MacLennan + * * Based on original work by * Ian DaSilva * Armin Kuster @@ -39,12 +42,17 @@ #include #include #include + +#ifdef CONFIG_IBM_OCP #include #include +#else +#include +#endif #include "i2c-ibm_iic.h" -#define DRIVER_VERSION "2.1" +#define DRIVER_VERSION "2.2" MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION); MODULE_LICENSE("GPL"); @@ -657,6 +665,7 @@ static inline u8 iic_clckdiv(unsigned int opb) return (u8)((opb + 9) / 10 - 1); } +#ifdef CONFIG_IBM_OCP /* * Register single IIC interface */ @@ -828,5 +837,181 @@ static void __exit iic_exit(void) ocp_unregister_driver(&ibm_iic_driver); } +#else /* !CONFIG_IBM_OCP */ + +static int __devinit iic_request_irq(struct of_device *ofdev, + struct ibm_iic_private *dev) +{ + struct device_node *np = ofdev->node; + int irq; + + if (iic_force_poll) + return NO_IRQ; + + irq = irq_of_parse_and_map(np, 0); + if (irq == NO_IRQ) { + dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n"); + return NO_IRQ; + } + + /* Disable interrupts until we finish initialization, assumes + * level-sensitive IRQ setup... + */ + iic_interrupt_mode(dev, 0); + if (request_irq(irq, iic_handler, 0, "IBM IIC", dev)) { + dev_err(&ofdev->dev, "request_irq %d failed\n", irq); + /* Fallback to the polling mode */ + return NO_IRQ; + } + + return irq; +} + +/* + * Register single IIC interface + */ +static int __devinit iic_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device_node *np = ofdev->node; + struct ibm_iic_private *dev; + struct i2c_adapter *adap; + const u32 *indexp, *freq; + int ret; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + dev_err(&ofdev->dev, "failed to allocate device data\n"); + return -ENOMEM; + } + + dev_set_drvdata(&ofdev->dev, dev); + + indexp = of_get_property(np, "index", NULL); + if (!indexp) { + dev_err(&ofdev->dev, "no index specified\n"); + ret = -EINVAL; + goto error_cleanup; + } + dev->idx = *indexp; + + dev->vaddr = of_iomap(np, 0); + if (dev->vaddr == NULL) { + dev_err(&ofdev->dev, "failed to iomap device\n"); + ret = -ENXIO; + goto error_cleanup; + } + + init_waitqueue_head(&dev->wq); + + dev->irq = iic_request_irq(ofdev, dev); + if (dev->irq == NO_IRQ) + dev_warn(&ofdev->dev, "using polling mode\n"); + + /* Board specific settings */ + if (iic_force_fast || of_get_property(np, "fast-mode", NULL)) + dev->fast_mode = 1; + + freq = of_get_property(np, "clock-frequency", NULL); + if (freq == NULL) { + freq = of_get_property(np->parent, "clock-frequency", NULL); + if (freq == NULL) { + dev_err(&ofdev->dev, "Unable to get bus frequency\n"); + ret = -EINVAL; + goto error_cleanup; + } + } + + dev->clckdiv = iic_clckdiv(*freq); + dev_dbg(&ofdev->dev, "clckdiv = %d\n", dev->clckdiv); + + /* Initialize IIC interface */ + iic_dev_init(dev); + + /* Register it with i2c layer */ + adap = &dev->adap; + adap->dev.parent = &ofdev->dev; + strlcpy(adap->name, "IBM IIC", sizeof(adap->name)); + i2c_set_adapdata(adap, dev); + adap->id = I2C_HW_OCP; + adap->class = I2C_CLASS_HWMON; + adap->algo = &iic_algo; + adap->timeout = 1; + adap->nr = dev->idx; + + ret = i2c_add_numbered_adapter(adap); + if (ret < 0) { + dev_err(&ofdev->dev, "failed to register i2c adapter\n"); + goto error_cleanup; + } + + dev_info(&ofdev->dev, "using %s mode\n", + dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); + + return 0; + +error_cleanup: + if (dev->irq != NO_IRQ) { + iic_interrupt_mode(dev, 0); + free_irq(dev->irq, dev); + } + + if (dev->vaddr) + iounmap(dev->vaddr); + + dev_set_drvdata(&ofdev->dev, NULL); + kfree(dev); + return ret; +} + +/* + * Cleanup initialized IIC interface + */ +static int __devexit iic_remove(struct of_device *ofdev) +{ + struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev); + + dev_set_drvdata(&ofdev->dev, NULL); + + i2c_del_adapter(&dev->adap); + + if (dev->irq != NO_IRQ) { + iic_interrupt_mode(dev, 0); + free_irq(dev->irq, dev); + } + + iounmap(dev->vaddr); + kfree(dev); + + return 0; +} + +static const struct of_device_id ibm_iic_match[] = { + { .compatible = "ibm,iic-405ex", }, + { .compatible = "ibm,iic-405gp", }, + { .compatible = "ibm,iic-440gp", }, + { .compatible = "ibm,iic-440gpx", }, + { .compatible = "ibm,iic-440grx", }, + {} +}; + +static struct of_platform_driver ibm_iic_driver = { + .name = "ibm-iic", + .match_table = ibm_iic_match, + .probe = iic_probe, + .remove = __devexit_p(iic_remove), +}; + +static int __init iic_init(void) +{ + return of_register_platform_driver(&ibm_iic_driver); +} + +static void __exit iic_exit(void) +{ + of_unregister_platform_driver(&ibm_iic_driver); +} +#endif /* CONFIG_IBM_OCP */ + module_init(iic_init); module_exit(iic_exit); -- cgit v1.2.3 From a26c20b1fa6d16fd3c402785b943a5e915eda30a Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Tue, 22 Apr 2008 22:16:47 +0200 Subject: i2c: Renesas SH7760 I2C master driver Driver for I2C interfaces in master mode on SH7760. Signed-off-by: Manuel Lauss Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 9 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-sh7760.c | 577 ++++++++++++++++++++++++++++++++++++++++ include/asm-sh/i2c-sh7760.h | 22 ++ 4 files changed, 609 insertions(+) create mode 100644 drivers/i2c/busses/i2c-sh7760.c create mode 100644 include/asm-sh/i2c-sh7760.h (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 1577bcad288a..d01d0b175e1c 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -683,4 +683,13 @@ config I2C_PMCMSP This driver can also be built as module. If so, the module will be called i2c-pmcmsp. +config I2C_SH7760 + tristate "Renesas SH7760 I2C Controller" + depends on CPU_SUBTYPE_SH7760 + help + This driver supports the 2 I2C interfaces on the Renesas SH7760. + + This driver can also be built as a module. If so, the module + will be called i2c-sh7760. + endmenu diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 378d5c07e048..8e72b2649dc7 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o obj-$(CONFIG_I2C_PXA) += i2c-pxa.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o +obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c new file mode 100644 index 000000000000..5e0e254976de --- /dev/null +++ b/drivers/i2c/busses/i2c-sh7760.c @@ -0,0 +1,577 @@ +/* + * I2C bus driver for the SH7760 I2C Interfaces. + * + * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss + * + * licensed under the terms outlined in the file COPYING. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* register offsets */ +#define I2CSCR 0x0 /* slave ctrl */ +#define I2CMCR 0x4 /* master ctrl */ +#define I2CSSR 0x8 /* slave status */ +#define I2CMSR 0xC /* master status */ +#define I2CSIER 0x10 /* slave irq enable */ +#define I2CMIER 0x14 /* master irq enable */ +#define I2CCCR 0x18 /* clock dividers */ +#define I2CSAR 0x1c /* slave address */ +#define I2CMAR 0x20 /* master address */ +#define I2CRXTX 0x24 /* data port */ +#define I2CFCR 0x28 /* fifo control */ +#define I2CFSR 0x2C /* fifo status */ +#define I2CFIER 0x30 /* fifo irq enable */ +#define I2CRFDR 0x34 /* rx fifo count */ +#define I2CTFDR 0x38 /* tx fifo count */ + +#define REGSIZE 0x3C + +#define MCR_MDBS 0x80 /* non-fifo mode switch */ +#define MCR_FSCL 0x40 /* override SCL pin */ +#define MCR_FSDA 0x20 /* override SDA pin */ +#define MCR_OBPC 0x10 /* override pins */ +#define MCR_MIE 0x08 /* master if enable */ +#define MCR_TSBE 0x04 +#define MCR_FSB 0x02 /* force stop bit */ +#define MCR_ESG 0x01 /* en startbit gen. */ + +#define MSR_MNR 0x40 /* nack received */ +#define MSR_MAL 0x20 /* arbitration lost */ +#define MSR_MST 0x10 /* sent a stop */ +#define MSR_MDE 0x08 +#define MSR_MDT 0x04 +#define MSR_MDR 0x02 +#define MSR_MAT 0x01 /* slave addr xfer done */ + +#define MIE_MNRE 0x40 /* nack irq en */ +#define MIE_MALE 0x20 /* arblos irq en */ +#define MIE_MSTE 0x10 /* stop irq en */ +#define MIE_MDEE 0x08 +#define MIE_MDTE 0x04 +#define MIE_MDRE 0x02 +#define MIE_MATE 0x01 /* address sent irq en */ + +#define FCR_RFRST 0x02 /* reset rx fifo */ +#define FCR_TFRST 0x01 /* reset tx fifo */ + +#define FSR_TEND 0x04 /* last byte sent */ +#define FSR_RDF 0x02 /* rx fifo trigger */ +#define FSR_TDFE 0x01 /* tx fifo empty */ + +#define FIER_TEIE 0x04 /* tx fifo empty irq en */ +#define FIER_RXIE 0x02 /* rx fifo trig irq en */ +#define FIER_TXIE 0x01 /* tx fifo trig irq en */ + +#define FIFO_SIZE 16 + +struct cami2c { + void __iomem *iobase; + struct i2c_adapter adap; + + /* message processing */ + struct i2c_msg *msg; +#define IDF_SEND 1 +#define IDF_RECV 2 +#define IDF_STOP 4 + int flags; + +#define IDS_DONE 1 +#define IDS_ARBLOST 2 +#define IDS_NACK 4 + int status; + struct completion xfer_done; + + int irq; + struct resource *ioarea; +}; + +static inline void OUT32(struct cami2c *cam, int reg, unsigned long val) +{ + ctrl_outl(val, (unsigned long)cam->iobase + reg); +} + +static inline unsigned long IN32(struct cami2c *cam, int reg) +{ + return ctrl_inl((unsigned long)cam->iobase + reg); +} + +static irqreturn_t sh7760_i2c_irq(int irq, void *ptr) +{ + struct cami2c *id = ptr; + struct i2c_msg *msg = id->msg; + char *data = msg->buf; + unsigned long msr, fsr, fier, len; + + msr = IN32(id, I2CMSR); + fsr = IN32(id, I2CFSR); + + /* arbitration lost */ + if (msr & MSR_MAL) { + OUT32(id, I2CMCR, 0); + OUT32(id, I2CSCR, 0); + OUT32(id, I2CSAR, 0); + id->status |= IDS_DONE | IDS_ARBLOST; + goto out; + } + + if (msr & MSR_MNR) { + /* NACK handling is very screwed up. After receiving a + * NAK IRQ one has to wait a bit before writing to any + * registers, or the ctl will lock up. After that delay + * do a normal i2c stop. Then wait at least 1 ms before + * attempting another transfer or ctl will stop working + */ + udelay(100); /* wait or risk ctl hang */ + OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); + OUT32(id, I2CMCR, MCR_MIE | MCR_FSB); + OUT32(id, I2CFIER, 0); + OUT32(id, I2CMIER, MIE_MSTE); + OUT32(id, I2CSCR, 0); + OUT32(id, I2CSAR, 0); + id->status |= IDS_NACK; + msr &= ~MSR_MAT; + fsr = 0; + /* In some cases the MST bit is also set. */ + } + + /* i2c-stop was sent */ + if (msr & MSR_MST) { + id->status |= IDS_DONE; + goto out; + } + + /* i2c slave addr was sent; set to "normal" operation */ + if (msr & MSR_MAT) + OUT32(id, I2CMCR, MCR_MIE); + + fier = IN32(id, I2CFIER); + + if (fsr & FSR_RDF) { + len = IN32(id, I2CRFDR); + if (msg->len <= len) { + if (id->flags & IDF_STOP) { + OUT32(id, I2CMCR, MCR_MIE | MCR_FSB); + OUT32(id, I2CFIER, 0); + /* manual says: wait >= 0.5 SCL times */ + udelay(5); + /* next int should be MST */ + } else { + id->status |= IDS_DONE; + /* keep the RDF bit: ctrl holds SCL low + * until the setup for the next i2c_msg + * clears this bit. + */ + fsr &= ~FSR_RDF; + } + } + while (msg->len && len) { + *data++ = IN32(id, I2CRXTX); + msg->len--; + len--; + } + + if (msg->len) { + len = (msg->len >= FIFO_SIZE) ? FIFO_SIZE - 1 + : msg->len - 1; + + OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xf) << 4)); + } + + } else if (id->flags & IDF_SEND) { + if ((fsr & FSR_TEND) && (msg->len < 1)) { + if (id->flags & IDF_STOP) { + OUT32(id, I2CMCR, MCR_MIE | MCR_FSB); + } else { + id->status |= IDS_DONE; + /* keep the TEND bit: ctl holds SCL low + * until the setup for the next i2c_msg + * clears this bit. + */ + fsr &= ~FSR_TEND; + } + } + if (fsr & FSR_TDFE) { + while (msg->len && (IN32(id, I2CTFDR) < FIFO_SIZE)) { + OUT32(id, I2CRXTX, *data++); + msg->len--; + } + + if (msg->len < 1) { + fier &= ~FIER_TXIE; + OUT32(id, I2CFIER, fier); + } else { + len = (msg->len >= FIFO_SIZE) ? 2 : 0; + OUT32(id, I2CFCR, + FCR_RFRST | ((len & 3) << 2)); + } + } + } +out: + if (id->status & IDS_DONE) { + OUT32(id, I2CMIER, 0); + OUT32(id, I2CFIER, 0); + id->msg = NULL; + complete(&id->xfer_done); + } + /* clear status flags and ctrl resumes work */ + OUT32(id, I2CMSR, ~msr); + OUT32(id, I2CFSR, ~fsr); + OUT32(id, I2CSSR, 0); + + return IRQ_HANDLED; +} + + +/* prepare and start a master receive operation */ +static void sh7760_i2c_mrecv(struct cami2c *id) +{ + int len; + + id->flags |= IDF_RECV; + + /* set the slave addr reg; otherwise rcv wont work! */ + OUT32(id, I2CSAR, 0xfe); + OUT32(id, I2CMAR, (id->msg->addr << 1) | 1); + + /* adjust rx fifo trigger */ + if (id->msg->len >= FIFO_SIZE) + len = FIFO_SIZE - 1; /* trigger at fifo full */ + else + len = id->msg->len - 1; /* trigger before all received */ + + OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); + OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xF) << 4)); + + OUT32(id, I2CMSR, 0); + OUT32(id, I2CMCR, MCR_MIE | MCR_ESG); + OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE); + OUT32(id, I2CFIER, FIER_RXIE); +} + +/* prepare and start a master send operation */ +static void sh7760_i2c_msend(struct cami2c *id) +{ + int len; + + id->flags |= IDF_SEND; + + /* set the slave addr reg; otherwise xmit wont work! */ + OUT32(id, I2CSAR, 0xfe); + OUT32(id, I2CMAR, (id->msg->addr << 1) | 0); + + /* adjust tx fifo trigger */ + if (id->msg->len >= FIFO_SIZE) + len = 2; /* trig: 2 bytes left in TX fifo */ + else + len = 0; /* trig: 8 bytes left in TX fifo */ + + OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); + OUT32(id, I2CFCR, FCR_RFRST | ((len & 3) << 2)); + + while (id->msg->len && IN32(id, I2CTFDR) < FIFO_SIZE) { + OUT32(id, I2CRXTX, *(id->msg->buf)); + (id->msg->len)--; + (id->msg->buf)++; + } + + OUT32(id, I2CMSR, 0); + OUT32(id, I2CMCR, MCR_MIE | MCR_ESG); + OUT32(id, I2CFSR, 0); + OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE); + OUT32(id, I2CFIER, FIER_TEIE | (id->msg->len ? FIER_TXIE : 0)); +} + +static inline int sh7760_i2c_busy_check(struct cami2c *id) +{ + return (IN32(id, I2CMCR) & MCR_FSDA); +} + +static int sh7760_i2c_master_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, + int num) +{ + struct cami2c *id = adap->algo_data; + int i, retr; + + if (sh7760_i2c_busy_check(id)) { + dev_err(&adap->dev, "sh7760-i2c%d: bus busy!\n", adap->nr); + return -EBUSY; + } + + i = 0; + while (i < num) { + retr = adap->retries; +retry: + id->flags = ((i == (num-1)) ? IDF_STOP : 0); + id->status = 0; + id->msg = msgs; + init_completion(&id->xfer_done); + + if (msgs->flags & I2C_M_RD) + sh7760_i2c_mrecv(id); + else + sh7760_i2c_msend(id); + + wait_for_completion(&id->xfer_done); + + if (id->status == 0) { + num = -EIO; + break; + } + + if (id->status & IDS_NACK) { + /* wait a bit or i2c module stops working */ + mdelay(1); + num = -EREMOTEIO; + break; + } + + if (id->status & IDS_ARBLOST) { + if (retr--) { + mdelay(2); + goto retry; + } + num = -EREMOTEIO; + break; + } + + msgs++; + i++; + } + + id->msg = NULL; + id->flags = 0; + id->status = 0; + + OUT32(id, I2CMCR, 0); + OUT32(id, I2CMSR, 0); + OUT32(id, I2CMIER, 0); + OUT32(id, I2CFIER, 0); + + /* reset slave module registers too: master mode enables slave + * module for receive ops (ack, data). Without this reset, + * eternal bus activity might be reported after NACK / ARBLOST. + */ + OUT32(id, I2CSCR, 0); + OUT32(id, I2CSAR, 0); + OUT32(id, I2CSSR, 0); + + return num; +} + +static u32 sh7760_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); +} + +static const struct i2c_algorithm sh7760_i2c_algo = { + .master_xfer = sh7760_i2c_master_xfer, + .functionality = sh7760_i2c_func, +}; + +/* calculate CCR register setting for a desired scl clock. SCL clock is + * derived from I2C module clock (iclk) which in turn is derived from + * peripheral module clock (mclk, usually around 33MHz): + * iclk = mclk/(CDF + 1). iclk must be < 20MHz. + * scl = iclk/(SCGD*8 + 20). + */ +static int __devinit calc_CCR(unsigned long scl_hz) +{ + struct clk *mclk; + unsigned long mck, m1, dff, odff, iclk; + signed char cdf, cdfm; + int scgd, scgdm, scgds; + + mclk = clk_get(NULL, "module_clk"); + if (IS_ERR(mclk)) { + return PTR_ERR(mclk); + } else { + mck = mclk->rate; + clk_put(mclk); + } + + odff = scl_hz; + scgdm = cdfm = m1 = 0; + for (cdf = 3; cdf >= 0; cdf--) { + iclk = mck / (1 + cdf); + if (iclk >= 20000000) + continue; + scgds = ((iclk / scl_hz) - 20) >> 3; + for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) { + m1 = iclk / (20 + (scgd << 3)); + dff = abs(scl_hz - m1); + if (dff < odff) { + odff = dff; + cdfm = cdf; + scgdm = scgd; + } + } + } + /* fail if more than 25% off of requested SCL */ + if (odff > (scl_hz >> 2)) + return -EINVAL; + + /* create a CCR register value */ + return ((scgdm << 2) | cdfm); +} + +static int __devinit sh7760_i2c_probe(struct platform_device *pdev) +{ + struct sh7760_i2c_platdata *pd; + struct resource *res; + struct cami2c *id; + int ret; + + pd = pdev->dev.platform_data; + if (!pd) { + dev_err(&pdev->dev, "no platform_data!\n"); + ret = -ENODEV; + goto out0; + } + + id = kzalloc(sizeof(struct cami2c), GFP_KERNEL); + if (!id) { + dev_err(&pdev->dev, "no mem for private data\n"); + ret = -ENOMEM; + goto out0; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no mmio resources\n"); + ret = -ENODEV; + goto out1; + } + + id->ioarea = request_mem_region(res->start, REGSIZE, pdev->name); + if (!id->ioarea) { + dev_err(&pdev->dev, "mmio already reserved\n"); + ret = -EBUSY; + goto out1; + } + + id->iobase = ioremap(res->start, REGSIZE); + if (!id->iobase) { + dev_err(&pdev->dev, "cannot ioremap\n"); + ret = -ENODEV; + goto out2; + } + + id->irq = platform_get_irq(pdev, 0); + + id->adap.nr = pdev->id; + id->adap.algo = &sh7760_i2c_algo; + id->adap.class = I2C_CLASS_ALL; + id->adap.retries = 3; + id->adap.algo_data = id; + id->adap.dev.parent = &pdev->dev; + snprintf(id->adap.name, sizeof(id->adap.name), + "SH7760 I2C at %08lx", (unsigned long)res->start); + + OUT32(id, I2CMCR, 0); + OUT32(id, I2CMSR, 0); + OUT32(id, I2CMIER, 0); + OUT32(id, I2CMAR, 0); + OUT32(id, I2CSIER, 0); + OUT32(id, I2CSAR, 0); + OUT32(id, I2CSCR, 0); + OUT32(id, I2CSSR, 0); + OUT32(id, I2CFIER, 0); + OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); + OUT32(id, I2CFSR, 0); + + ret = calc_CCR(pd->speed_khz * 1000); + if (ret < 0) { + dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n", + pd->speed_khz); + goto out3; + } + OUT32(id, I2CCCR, ret); + + if (request_irq(id->irq, sh7760_i2c_irq, IRQF_DISABLED, + SH7760_I2C_DEVNAME, id)) { + dev_err(&pdev->dev, "cannot get irq %d\n", id->irq); + ret = -EBUSY; + goto out3; + } + + ret = i2c_add_numbered_adapter(&id->adap); + if (ret < 0) { + dev_err(&pdev->dev, "reg adap failed: %d\n", ret); + goto out4; + } + + platform_set_drvdata(pdev, id); + + dev_info(&pdev->dev, "%d kHz mmio %08x irq %d\n", + pd->speed_khz, res->start, id->irq); + + return 0; + +out4: + free_irq(id->irq, id); +out3: + iounmap(id->iobase); +out2: + release_resource(id->ioarea); + kfree(id->ioarea); +out1: + kfree(id); +out0: + return ret; +} + +static int __devexit sh7760_i2c_remove(struct platform_device *pdev) +{ + struct cami2c *id = platform_get_drvdata(pdev); + + i2c_del_adapter(&id->adap); + free_irq(id->irq, id); + iounmap(id->iobase); + release_resource(id->ioarea); + kfree(id->ioarea); + kfree(id); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver sh7760_i2c_drv = { + .driver = { + .name = SH7760_I2C_DEVNAME, + .owner = THIS_MODULE, + }, + .probe = sh7760_i2c_probe, + .remove = __devexit_p(sh7760_i2c_remove), +}; + +static int __init sh7760_i2c_init(void) +{ + return platform_driver_register(&sh7760_i2c_drv); +} + +static void __exit sh7760_i2c_exit(void) +{ + platform_driver_unregister(&sh7760_i2c_drv); +} + +module_init(sh7760_i2c_init); +module_exit(sh7760_i2c_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SH7760 I2C bus driver"); +MODULE_AUTHOR("Manuel Lauss "); diff --git a/include/asm-sh/i2c-sh7760.h b/include/asm-sh/i2c-sh7760.h new file mode 100644 index 000000000000..24182116711f --- /dev/null +++ b/include/asm-sh/i2c-sh7760.h @@ -0,0 +1,22 @@ +/* + * MMIO/IRQ and platform data for SH7760 I2C channels + */ + +#ifndef _I2C_SH7760_H_ +#define _I2C_SH7760_H_ + +#define SH7760_I2C_DEVNAME "sh7760-i2c" + +#define SH7760_I2C0_MMIO 0xFE140000 +#define SH7760_I2C0_MMIOEND 0xFE14003B +#define SH7760_I2C0_IRQ 62 + +#define SH7760_I2C1_MMIO 0xFE150000 +#define SH7760_I2C1_MMIOEND 0xFE15003B +#define SH7760_I2C1_IRQ 63 + +struct sh7760_i2c_platdata { + unsigned int speed_khz; +}; + +#endif -- cgit v1.2.3 From 08882d20932224d5c4500a855a2f4b1216e5f836 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 22 Apr 2008 22:16:47 +0200 Subject: i2c: Replace remaining __FUNCTION__ occurrences __FUNCTION__ is gcc-specific, use __func__. Signed-off-by: Harvey Harrison Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-davinci.c | 6 +++--- drivers/i2c/busses/i2c-pmcmsp.c | 4 ++-- drivers/i2c/busses/i2c-pnx.c | 44 ++++++++++++++++++++-------------------- drivers/i2c/busses/i2c-pxa.c | 2 +- drivers/i2c/busses/i2c-s3c2410.c | 4 ++-- drivers/i2c/chips/isp1301_omap.c | 28 ++++++++++++------------- drivers/i2c/i2c-core.c | 2 +- 7 files changed, 45 insertions(+), 45 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index fde26345a379..c7dbb9d0423e 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -328,7 +328,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) int i; int ret; - dev_dbg(dev->dev, "%s: msgs: %d\n", __FUNCTION__, num); + dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); ret = i2c_davinci_wait_bus_not_busy(dev, 1); if (ret < 0) { @@ -342,7 +342,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) return ret; } - dev_dbg(dev->dev, "%s:%d ret: %d\n", __FUNCTION__, __LINE__, ret); + dev_dbg(dev->dev, "%s:%d ret: %d\n", __func__, __LINE__, ret); return num; } @@ -364,7 +364,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) u16 w; while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) { - dev_dbg(dev->dev, "%s: stat=0x%x\n", __FUNCTION__, stat); + dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat); if (count++ == 100) { dev_warn(dev->dev, "Too much work in one IRQ\n"); break; diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index b03af5653c65..9ea0f8aa74f4 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -467,7 +467,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd( (cmd->read_len == 0 || cmd->write_len == 0))) { dev_err(&pmcmsptwi_adapter.dev, "%s: Cannot transfer less than 1 byte\n", - __FUNCTION__); + __func__); return -EINVAL; } @@ -475,7 +475,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd( cmd->write_len > MSP_MAX_BYTES_PER_RW) { dev_err(&pmcmsptwi_adapter.dev, "%s: Cannot transfer more than %d bytes\n", - __FUNCTION__, MSP_MAX_BYTES_PER_RW); + __func__, MSP_MAX_BYTES_PER_RW); return -EINVAL; } diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index f8d0dff0de7e..6695d5902ed4 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -76,7 +76,7 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) { struct i2c_pnx_algo_data *alg_data = adap->algo_data; - dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __FUNCTION__, + dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__, slave_addr, alg_data->mif.mode); /* Check for 7 bit slave addresses only */ @@ -110,14 +110,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); - dev_dbg(&adap->dev, "%s(): sending %#x\n", __FUNCTION__, + dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__, (slave_addr << 1) | start_bit | alg_data->mif.mode); /* Write the slave address, START bit and R/W bit */ iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode, I2C_REG_TX(alg_data)); - dev_dbg(&adap->dev, "%s(): exit\n", __FUNCTION__); + dev_dbg(&adap->dev, "%s(): exit\n", __func__); return 0; } @@ -135,7 +135,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap) long timeout = 1000; dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); + __func__, ioread32(I2C_REG_STS(alg_data))); /* Write a STOP bit to TX FIFO */ iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data)); @@ -149,7 +149,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap) } dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); + __func__, ioread32(I2C_REG_STS(alg_data))); } /** @@ -164,7 +164,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) u32 val; dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); + __func__, ioread32(I2C_REG_STS(alg_data))); if (alg_data->mif.len > 0) { /* We still have something to talk about... */ @@ -179,7 +179,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) alg_data->mif.len--; iowrite32(val, I2C_REG_TX(alg_data)); - dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __FUNCTION__, + dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__, val, alg_data->mif.len + 1); if (alg_data->mif.len == 0) { @@ -197,7 +197,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) del_timer_sync(&alg_data->mif.timer); dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n", - __FUNCTION__); + __func__); complete(&alg_data->mif.complete); } @@ -213,13 +213,13 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) /* Stop timer. */ del_timer_sync(&alg_data->mif.timer); dev_dbg(&adap->dev, "%s(): Waking up xfer routine after " - "zero-xfer.\n", __FUNCTION__); + "zero-xfer.\n", __func__); complete(&alg_data->mif.complete); } dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); + __func__, ioread32(I2C_REG_STS(alg_data))); return 0; } @@ -237,14 +237,14 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) u32 ctl = 0; dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); + __func__, ioread32(I2C_REG_STS(alg_data))); /* Check, whether there is already data, * or we didn't 'ask' for it yet. */ if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { dev_dbg(&adap->dev, "%s(): Write dummy data to fill " - "Rx-fifo...\n", __FUNCTION__); + "Rx-fifo...\n", __func__); if (alg_data->mif.len == 1) { /* Last byte, do not acknowledge next rcv. */ @@ -276,7 +276,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) if (alg_data->mif.len > 0) { val = ioread32(I2C_REG_RX(alg_data)); *alg_data->mif.buf++ = (u8) (val & 0xff); - dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __FUNCTION__, val, + dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val, alg_data->mif.len); alg_data->mif.len--; @@ -300,7 +300,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) } dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); + __func__, ioread32(I2C_REG_STS(alg_data))); return 0; } @@ -312,7 +312,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) struct i2c_pnx_algo_data *alg_data = adap->algo_data; dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", - __FUNCTION__, + __func__, ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data)), alg_data->mif.mode); @@ -336,7 +336,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) /* Slave did not acknowledge, generate a STOP */ dev_dbg(&adap->dev, "%s(): " "Slave did not acknowledge, generating a STOP.\n", - __FUNCTION__); + __func__); i2c_pnx_stop(adap); /* Disable master interrupts. */ @@ -375,7 +375,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data)), + __func__, ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data))); return IRQ_HANDLED; @@ -447,7 +447,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) u32 stat = ioread32(I2C_REG_STS(alg_data)); dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n", - __FUNCTION__, num, ioread32(I2C_REG_STS(alg_data))); + __func__, num, ioread32(I2C_REG_STS(alg_data))); bus_reset_if_active(adap); @@ -473,7 +473,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) alg_data->mif.ret = 0; alg_data->last = (i == num - 1); - dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __FUNCTION__, + dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__, alg_data->mif.mode, alg_data->mif.len); @@ -498,7 +498,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (!(rc = alg_data->mif.ret)) completed++; dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n", - __FUNCTION__, rc); + __func__, rc); /* Clear TDI and AFI bits in case they are set. */ if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { @@ -522,7 +522,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) alg_data->mif.len = 0; dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n", - __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); + __func__, ioread32(I2C_REG_STS(alg_data))); if (completed != num) return ((rc < 0) ? rc : -EREMOTEIO); @@ -563,7 +563,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) if (!i2c_pnx || !i2c_pnx->adapter) { dev_err(&pdev->dev, "%s: no platform data supplied\n", - __FUNCTION__); + __func__); ret = -EINVAL; goto out; } diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 6fd2d6a84eff..330fff464ea9 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -155,7 +155,7 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname) readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c))); } -#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__) +#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __func__) #else #define i2c_debug 0 diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index c44ada5f4292..5ece33ea5e22 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -276,12 +276,12 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) switch (i2c->state) { case STATE_IDLE: - dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __FUNCTION__); + dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__); goto out; break; case STATE_STOP: - dev_err(i2c->dev, "%s: called in STATE_STOP\n", __FUNCTION__); + dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__); s3c24xx_i2c_disable_irq(i2c); goto out_ack; diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 2a3160153f54..b1b45dddb17e 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -658,7 +658,7 @@ pulldown: OTG_CTRL_REG |= OTG_PULLUP; } - check_state(isp, __FUNCTION__); + check_state(isp, __func__); dump_regs(isp, "otg->isp1301"); } @@ -782,7 +782,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) if (otg_ctrl & OTG_DRIVER_SEL) { switch (isp->otg.state) { case OTG_STATE_A_IDLE: - b_idle(isp, __FUNCTION__); + b_idle(isp, __func__); break; default: break; @@ -826,7 +826,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) isp->otg.host->otg_port); } - check_state(isp, __FUNCTION__); + check_state(isp, __func__); return ret; } @@ -837,7 +837,7 @@ static int otg_init(struct isp1301 *isp) if (!otg_dev) return -ENODEV; - dump_regs(isp, __FUNCTION__); + dump_regs(isp, __func__); /* some of these values are board-specific... */ OTG_SYSCON_2_REG |= OTG_EN /* for B-device: */ @@ -853,9 +853,9 @@ static int otg_init(struct isp1301 *isp) update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); - check_state(isp, __FUNCTION__); + check_state(isp, __func__); pr_debug("otg: %s, %s %06x\n", - state_name(isp), __FUNCTION__, OTG_CTRL_REG); + state_name(isp), __func__, OTG_CTRL_REG); OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG | B_SRP_TMROUT | B_HNP_FAIL @@ -1041,11 +1041,11 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) OTG1_DP_PULLDOWN); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); - dump_regs(isp, __FUNCTION__); + dump_regs(isp, __func__); #endif /* FALLTHROUGH */ case OTG_STATE_B_SRP_INIT: - b_idle(isp, __FUNCTION__); + b_idle(isp, __func__); OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; /* FALLTHROUGH */ case OTG_STATE_B_IDLE: @@ -1077,7 +1077,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) */ update_otg1(isp, isp_stat); update_otg2(isp, isp_bstat); - check_state(isp, __FUNCTION__); + check_state(isp, __func__); #endif dump_regs(isp, "isp1301->otg"); @@ -1310,7 +1310,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) */ isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV); - dump_regs(isp, __FUNCTION__); + dump_regs(isp, __func__); return 0; @@ -1365,7 +1365,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, INTR_VBUS_VLD); dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); - dump_regs(isp, __FUNCTION__); + dump_regs(isp, __func__); /* If this has a Mini-AB connector, this mode is highly * nonstandard ... but can be handy for testing, so long @@ -1416,7 +1416,7 @@ isp1301_start_srp(struct otg_transceiver *dev) pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG); #ifdef CONFIG_USB_OTG - check_state(isp, __FUNCTION__); + check_state(isp, __func__); #endif return 0; } @@ -1463,7 +1463,7 @@ isp1301_start_hnp(struct otg_transceiver *dev) } pr_debug("otg: HNP %s, %06x ...\n", state_name(isp), OTG_CTRL_REG); - check_state(isp, __FUNCTION__); + check_state(isp, __func__); return 0; #else /* srp-only */ @@ -1601,7 +1601,7 @@ fail2: update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); #endif - dump_regs(isp, __FUNCTION__); + dump_regs(isp, __func__); #ifdef VERBOSE mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e186df657119..6c7fa8d53c0e 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1506,7 +1506,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, read_write = I2C_SMBUS_READ; if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { dev_err(&adapter->dev, "%s called with invalid " - "block proc call size (%d)\n", __FUNCTION__, + "block proc call size (%d)\n", __func__, data->block[0]); return -1; } -- cgit v1.2.3 From 4c03f68fc4ab902353336b6b0c6933617821cf70 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 22 Apr 2008 22:16:47 +0200 Subject: i2c: Remove trailing whitespaces in busses/Kconfig Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index d01d0b175e1c..495c971ce5bf 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -135,7 +135,7 @@ config I2C_ELEKTOR This supports the PCF8584 ISA bus I2C adapter. Say Y if you own such an adapter. - This support is also available as a module. If so, the module + This support is also available as a module. If so, the module will be called i2c-elektor. config I2C_GPIO @@ -190,7 +190,7 @@ config I2C_I810 select I2C_ALGOBIT help If you say yes to this option, support will be included for the Intel - 810/815 family of mainboard I2C interfaces. Specifically, the + 810/815 family of mainboard I2C interfaces. Specifically, the following versions of the chipset are supported: i810AA i810AB @@ -248,8 +248,8 @@ config I2C_IBM_IIC tristate "IBM PPC 4xx on-chip I2C interface" depends on 4xx help - Say Y here if you want to use IIC peripheral found on - embedded IBM PPC 4xx based systems. + Say Y here if you want to use IIC peripheral found on + embedded IBM PPC 4xx based systems. This driver can also be built as a module. If so, the module will be called i2c-ibm_iic. @@ -269,7 +269,7 @@ config I2C_IXP2000 depends on ARCH_IXP2000 select I2C_ALGOBIT help - Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based + Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based system and are using GPIO lines for an I2C bus. This support is also available as a module. If so, the module @@ -354,7 +354,7 @@ config I2C_PARPORT on the parport driver. This is meant for embedded systems. Don't say Y here if you intend to say Y or M there. - This support is also available as a module. If so, the module + This support is also available as a module. If so, the module will be called i2c-parport. config I2C_PARPORT_LIGHT @@ -372,12 +372,12 @@ config I2C_PARPORT_LIGHT the clean but heavy parport handling is not an option. The drawback is a reduced portability and the impossibility to daisy-chain other parallel port devices. - + Don't say Y here if you said Y or M to i2c-parport. Saying M to both is possible but both modules should not be loaded at the same time. - This support is also available as a module. If so, the module + This support is also available as a module. If so, the module will be called i2c-parport-light. config I2C_PASEMI @@ -401,7 +401,7 @@ config I2C_PROSAVAGE This driver is deprecated in favor of the savagefb driver. - This support is also available as a module. If so, the module + This support is also available as a module. If so, the module will be called i2c-prosavage. config I2C_S3C2410 @@ -417,7 +417,7 @@ config I2C_SAVAGE4 depends on PCI select I2C_ALGOBIT help - If you say yes to this option, support will be included for the + If you say yes to this option, support will be included for the S3 Savage 4 I2C interface. This driver is deprecated in favor of the savagefb driver. @@ -452,7 +452,7 @@ config SCx200_I2C If you don't know what to do here, say N. - This support is also available as a module. If so, the module + This support is also available as a module. If so, the module will be called scx200_i2c. This driver is deprecated and will be dropped soon. Use i2c-gpio @@ -483,14 +483,14 @@ config SCx200_ACB If you don't know what to do here, say N. - This support is also available as a module. If so, the module + This support is also available as a module. If so, the module will be called scx200_acb. config I2C_SIS5595 tristate "SiS 5595" depends on PCI help - If you say yes to this option, support will be included for the + If you say yes to this option, support will be included for the SiS5595 SMBus (a subset of I2C) interface. This driver can also be built as a module. If so, the module @@ -500,7 +500,7 @@ config I2C_SIS630 tristate "SiS 630/730" depends on PCI help - If you say yes to this option, support will be included for the + If you say yes to this option, support will be included for the SiS630 and SiS730 SMBus (a subset of I2C) interface. This driver can also be built as a module. If so, the module @@ -634,7 +634,7 @@ config I2C_PCA_ISA help This driver supports ISA boards using the Philips PCA9564 parallel bus to I2C bus controller. - + This driver can also be built as a module. If so, the module will be called i2c-pca-isa. -- cgit v1.2.3 From 4dd39bb12f5b9f0d9a98f29071dc1c51e9306954 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 22 Apr 2008 22:16:47 +0200 Subject: i2c-bfin-twi: Add repeat start feature to avoid break of a bundle of i2c master xfer operation - Create a new mode TWI_I2C_MODE_REPEAT. - No change to smbus operation. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-bfin-twi.c | 185 +++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 71 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 7dbdaeb707a9..86956a8f0ae5 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -39,9 +39,10 @@ #define POLL_TIMEOUT (2 * HZ) /* SMBus mode*/ -#define TWI_I2C_MODE_STANDARD 0x01 -#define TWI_I2C_MODE_STANDARDSUB 0x02 -#define TWI_I2C_MODE_COMBINED 0x04 +#define TWI_I2C_MODE_STANDARD 1 +#define TWI_I2C_MODE_STANDARDSUB 2 +#define TWI_I2C_MODE_COMBINED 3 +#define TWI_I2C_MODE_REPEAT 4 struct bfin_twi_iface { int irq; @@ -58,6 +59,9 @@ struct bfin_twi_iface { struct timer_list timeout_timer; struct i2c_adapter adap; struct completion complete; + struct i2c_msg *pmsg; + int msg_num; + int cur_msg; }; static struct bfin_twi_iface twi_iface; @@ -76,12 +80,16 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) /* start receive immediately after complete sending in * combine mode. */ - else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { + else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MDIR | RSTART); - } else if (iface->manual_stop) + else if (iface->manual_stop) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP); + else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && + iface->cur_msg+1 < iface->msg_num) + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() + | RSTART); SSYNC(); /* Clear status */ bfin_write_TWI_INT_STAT(XMTSERV); @@ -108,6 +116,11 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP); SSYNC(); + } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && + iface->cur_msg+1 < iface->msg_num) { + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() + | RSTART); + SSYNC(); } /* Clear interrupt source */ bfin_write_TWI_INT_STAT(RCVSERV); @@ -119,7 +132,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_STAT(0x3e); bfin_write_TWI_MASTER_CTL(0); SSYNC(); - iface->result = -1; + iface->result = -EIO; /* if both err and complete int stats are set, return proper * results. */ @@ -170,6 +183,42 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | MDIR); SSYNC(); + } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && + iface->cur_msg+1 < iface->msg_num) { + iface->cur_msg++; + iface->transPtr = iface->pmsg[iface->cur_msg].buf; + iface->writeNum = iface->readNum = + iface->pmsg[iface->cur_msg].len; + /* Set Transmit device address */ + bfin_write_TWI_MASTER_ADDR( + iface->pmsg[iface->cur_msg].addr); + if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD) + iface->read_write = I2C_SMBUS_READ; + else { + iface->read_write = I2C_SMBUS_WRITE; + /* Transmit first data */ + if (iface->writeNum > 0) { + bfin_write_TWI_XMT_DATA8( + *(iface->transPtr++)); + iface->writeNum--; + SSYNC(); + } + } + + if (iface->pmsg[iface->cur_msg].len <= 255) + bfin_write_TWI_MASTER_CTL( + iface->pmsg[iface->cur_msg].len << 6); + else { + bfin_write_TWI_MASTER_CTL(0xff << 6); + iface->manual_stop = 1; + } + /* remove restart bit and enable master receive */ + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & + ~RSTART); + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | + MEN | ((iface->read_write == I2C_SMBUS_READ) ? + MDIR : 0)); + SSYNC(); } else { iface->result = 1; bfin_write_TWI_INT_MASK(0); @@ -221,7 +270,6 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, { struct bfin_twi_iface *iface = adap->algo_data; struct i2c_msg *pmsg; - int i, ret; int rc = 0; if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) @@ -231,81 +279,76 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, yield(); } - ret = 0; - for (i = 0; rc >= 0 && i < num; i++) { - pmsg = &msgs[i]; - if (pmsg->flags & I2C_M_TEN) { - dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr " - "not supported !\n"); - rc = -EINVAL; - break; - } + iface->pmsg = msgs; + iface->msg_num = num; + iface->cur_msg = 0; - iface->cur_mode = TWI_I2C_MODE_STANDARD; - iface->manual_stop = 0; - iface->transPtr = pmsg->buf; - iface->writeNum = iface->readNum = pmsg->len; - iface->result = 0; - iface->timeout_count = 10; - /* Set Transmit device address */ - bfin_write_TWI_MASTER_ADDR(pmsg->addr); - - /* FIFO Initiation. Data in FIFO should be - * discarded before start a new operation. - */ - bfin_write_TWI_FIFO_CTL(0x3); - SSYNC(); - bfin_write_TWI_FIFO_CTL(0); - SSYNC(); + pmsg = &msgs[0]; + if (pmsg->flags & I2C_M_TEN) { + dev_err(&adap->dev, "10 bits addr not supported!\n"); + return -EINVAL; + } - if (pmsg->flags & I2C_M_RD) - iface->read_write = I2C_SMBUS_READ; - else { - iface->read_write = I2C_SMBUS_WRITE; - /* Transmit first data */ - if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); - iface->writeNum--; - SSYNC(); - } + iface->cur_mode = TWI_I2C_MODE_REPEAT; + iface->manual_stop = 0; + iface->transPtr = pmsg->buf; + iface->writeNum = iface->readNum = pmsg->len; + iface->result = 0; + iface->timeout_count = 10; + /* Set Transmit device address */ + bfin_write_TWI_MASTER_ADDR(pmsg->addr); + + /* FIFO Initiation. Data in FIFO should be + * discarded before start a new operation. + */ + bfin_write_TWI_FIFO_CTL(0x3); + SSYNC(); + bfin_write_TWI_FIFO_CTL(0); + SSYNC(); + + if (pmsg->flags & I2C_M_RD) + iface->read_write = I2C_SMBUS_READ; + else { + iface->read_write = I2C_SMBUS_WRITE; + /* Transmit first data */ + if (iface->writeNum > 0) { + bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); + iface->writeNum--; + SSYNC(); } + } - /* clear int stat */ - bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV); + /* clear int stat */ + bfin_write_TWI_INT_STAT(MERR | MCOMP | XMTSERV | RCVSERV); - /* Interrupt mask . Enable XMT, RCV interrupt */ - bfin_write_TWI_INT_MASK(MCOMP | MERR | - ((iface->read_write == I2C_SMBUS_READ)? - RCVSERV : XMTSERV)); - SSYNC(); + /* Interrupt mask . Enable XMT, RCV interrupt */ + bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV); + SSYNC(); - if (pmsg->len > 0 && pmsg->len <= 255) - bfin_write_TWI_MASTER_CTL(pmsg->len << 6); - else if (pmsg->len > 255) { - bfin_write_TWI_MASTER_CTL(0xff << 6); - iface->manual_stop = 1; - } else - break; + if (pmsg->len <= 255) + bfin_write_TWI_MASTER_CTL(pmsg->len << 6); + else { + bfin_write_TWI_MASTER_CTL(0xff << 6); + iface->manual_stop = 1; + } - iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; - add_timer(&iface->timeout_timer); + iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; + add_timer(&iface->timeout_timer); - /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | - ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | - ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); - SSYNC(); + /* Master enable */ + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | + ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | + ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); + SSYNC(); - wait_for_completion(&iface->complete); + wait_for_completion(&iface->complete); - rc = iface->result; - if (rc == 1) - ret++; - else if (rc == -1) - break; - } + rc = iface->result; - return ret; + if (rc == 1) + return num; + else + return rc; } /* -- cgit v1.2.3 From aa3d02091747727f7ff2e1f2455ad8363a9e6946 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Tue, 22 Apr 2008 22:16:48 +0200 Subject: i2c-bfin-twi: Add platform_resource interface to support multi-port TWI controllers - Dynamic alloc the resource of TWI driver data according to board information - TWI register read/write accessor based on dynamic regs_base - Support TWI0/TWI1 for BF54x Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 2 +- drivers/i2c/busses/i2c-bfin-twi.c | 283 ++++++++++++++++++++++++-------------- 2 files changed, 177 insertions(+), 108 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 495c971ce5bf..7d538ddfd37e 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -100,7 +100,7 @@ config I2C_AU1550 config I2C_BLACKFIN_TWI tristate "Blackfin TWI I2C support" - depends on BF534 || BF536 || BF537 + depends on BF534 || BF536 || BF537 || BF54x help This is the TWI I2C device driver for Blackfin 534/536/537/54x. This driver can also be built as a module. If so, the module diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 86956a8f0ae5..f2b558f17ca2 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -62,43 +62,66 @@ struct bfin_twi_iface { struct i2c_msg *pmsg; int msg_num; int cur_msg; + void __iomem *regs_base; }; -static struct bfin_twi_iface twi_iface; + +#define DEFINE_TWI_REG(reg, off) \ +static inline u16 read_##reg(struct bfin_twi_iface *iface) \ + { return bfin_read16(iface->regs_base + (off)); } \ +static inline void write_##reg(struct bfin_twi_iface *iface, u16 v) \ + { bfin_write16(iface->regs_base + (off), v); } + +DEFINE_TWI_REG(CLKDIV, 0x00) +DEFINE_TWI_REG(CONTROL, 0x04) +DEFINE_TWI_REG(SLAVE_CTL, 0x08) +DEFINE_TWI_REG(SLAVE_STAT, 0x0C) +DEFINE_TWI_REG(SLAVE_ADDR, 0x10) +DEFINE_TWI_REG(MASTER_CTL, 0x14) +DEFINE_TWI_REG(MASTER_STAT, 0x18) +DEFINE_TWI_REG(MASTER_ADDR, 0x1C) +DEFINE_TWI_REG(INT_STAT, 0x20) +DEFINE_TWI_REG(INT_MASK, 0x24) +DEFINE_TWI_REG(FIFO_CTL, 0x28) +DEFINE_TWI_REG(FIFO_STAT, 0x2C) +DEFINE_TWI_REG(XMT_DATA8, 0x80) +DEFINE_TWI_REG(XMT_DATA16, 0x84) +DEFINE_TWI_REG(RCV_DATA8, 0x88) +DEFINE_TWI_REG(RCV_DATA16, 0x8C) static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) { - unsigned short twi_int_status = bfin_read_TWI_INT_STAT(); - unsigned short mast_stat = bfin_read_TWI_MASTER_STAT(); + unsigned short twi_int_status = read_INT_STAT(iface); + unsigned short mast_stat = read_MASTER_STAT(iface); if (twi_int_status & XMTSERV) { /* Transmit next data */ if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); + write_XMT_DATA8(iface, *(iface->transPtr++)); iface->writeNum--; } /* start receive immediately after complete sending in * combine mode. */ else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | MDIR | RSTART); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) | MDIR | RSTART); else if (iface->manual_stop) - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | STOP); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) | STOP); else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | RSTART); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) | RSTART); SSYNC(); /* Clear status */ - bfin_write_TWI_INT_STAT(XMTSERV); + write_INT_STAT(iface, XMTSERV); SSYNC(); } if (twi_int_status & RCVSERV) { if (iface->readNum > 0) { /* Receive next data */ - *(iface->transPtr) = bfin_read_TWI_RCV_DATA8(); + *(iface->transPtr) = read_RCV_DATA8(iface); if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { /* Change combine mode into sub mode after * read first data. @@ -113,33 +136,33 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) iface->transPtr++; iface->readNum--; } else if (iface->manual_stop) { - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | STOP); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) | STOP); SSYNC(); } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) { - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | RSTART); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) | RSTART); SSYNC(); } /* Clear interrupt source */ - bfin_write_TWI_INT_STAT(RCVSERV); + write_INT_STAT(iface, RCVSERV); SSYNC(); } if (twi_int_status & MERR) { - bfin_write_TWI_INT_STAT(MERR); - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_STAT(0x3e); - bfin_write_TWI_MASTER_CTL(0); + write_INT_STAT(iface, MERR); + write_INT_MASK(iface, 0); + write_MASTER_STAT(iface, 0x3e); + write_MASTER_CTL(iface, 0); SSYNC(); iface->result = -EIO; /* if both err and complete int stats are set, return proper * results. */ if (twi_int_status & MCOMP) { - bfin_write_TWI_INT_STAT(MCOMP); - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_CTL(0); + write_INT_STAT(iface, MCOMP); + write_INT_MASK(iface, 0); + write_MASTER_CTL(iface, 0); SSYNC(); /* If it is a quick transfer, only address bug no data, * not an err, return 1. @@ -156,7 +179,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) return; } if (twi_int_status & MCOMP) { - bfin_write_TWI_INT_STAT(MCOMP); + write_INT_STAT(iface, MCOMP); SSYNC(); if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { if (iface->readNum == 0) { @@ -165,23 +188,22 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) */ iface->readNum = 1; iface->manual_stop = 1; - bfin_write_TWI_MASTER_CTL( - bfin_read_TWI_MASTER_CTL() - | (0xff << 6)); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) | (0xff << 6)); } else { /* set the readd number in other * combine mode. */ - bfin_write_TWI_MASTER_CTL( - (bfin_read_TWI_MASTER_CTL() & + write_MASTER_CTL(iface, + (read_MASTER_CTL(iface) & (~(0xff << 6))) | - ( iface->readNum << 6)); + (iface->readNum << 6)); } /* remove restart bit and enable master receive */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & - ~RSTART); - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | - MEN | MDIR); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) & ~RSTART); + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) | MEN | MDIR); SSYNC(); } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) { @@ -190,7 +212,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) iface->writeNum = iface->readNum = iface->pmsg[iface->cur_msg].len; /* Set Transmit device address */ - bfin_write_TWI_MASTER_ADDR( + write_MASTER_ADDR(iface, iface->pmsg[iface->cur_msg].addr); if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD) iface->read_write = I2C_SMBUS_READ; @@ -198,7 +220,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) iface->read_write = I2C_SMBUS_WRITE; /* Transmit first data */ if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8( + write_XMT_DATA8(iface, *(iface->transPtr++)); iface->writeNum--; SSYNC(); @@ -206,23 +228,23 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) } if (iface->pmsg[iface->cur_msg].len <= 255) - bfin_write_TWI_MASTER_CTL( + write_MASTER_CTL(iface, iface->pmsg[iface->cur_msg].len << 6); else { - bfin_write_TWI_MASTER_CTL(0xff << 6); + write_MASTER_CTL(iface, 0xff << 6); iface->manual_stop = 1; } /* remove restart bit and enable master receive */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & - ~RSTART); - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | + write_MASTER_CTL(iface, + read_MASTER_CTL(iface) & ~RSTART); + write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0)); SSYNC(); } else { iface->result = 1; - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_CTL(0); + write_INT_MASK(iface, 0); + write_MASTER_CTL(iface, 0); SSYNC(); complete(&iface->complete); } @@ -272,12 +294,11 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg; int rc = 0; - if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) + if (!(read_CONTROL(iface) & TWI_ENA)) return -ENXIO; - while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) { + while (read_MASTER_STAT(iface) & BUSBUSY) yield(); - } iface->pmsg = msgs; iface->msg_num = num; @@ -296,14 +317,14 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, iface->result = 0; iface->timeout_count = 10; /* Set Transmit device address */ - bfin_write_TWI_MASTER_ADDR(pmsg->addr); + write_MASTER_ADDR(iface, pmsg->addr); /* FIFO Initiation. Data in FIFO should be * discarded before start a new operation. */ - bfin_write_TWI_FIFO_CTL(0x3); + write_FIFO_CTL(iface, 0x3); SSYNC(); - bfin_write_TWI_FIFO_CTL(0); + write_FIFO_CTL(iface, 0); SSYNC(); if (pmsg->flags & I2C_M_RD) @@ -312,23 +333,23 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, iface->read_write = I2C_SMBUS_WRITE; /* Transmit first data */ if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); + write_XMT_DATA8(iface, *(iface->transPtr++)); iface->writeNum--; SSYNC(); } } /* clear int stat */ - bfin_write_TWI_INT_STAT(MERR | MCOMP | XMTSERV | RCVSERV); + write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV); /* Interrupt mask . Enable XMT, RCV interrupt */ - bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV); + write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV); SSYNC(); if (pmsg->len <= 255) - bfin_write_TWI_MASTER_CTL(pmsg->len << 6); + write_MASTER_CTL(iface, pmsg->len << 6); else { - bfin_write_TWI_MASTER_CTL(0xff << 6); + write_MASTER_CTL(iface, 0xff << 6); iface->manual_stop = 1; } @@ -336,7 +357,7 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, add_timer(&iface->timeout_timer); /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | + write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); SSYNC(); @@ -362,12 +383,11 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr, struct bfin_twi_iface *iface = adap->algo_data; int rc = 0; - if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) + if (!(read_CONTROL(iface) & TWI_ENA)) return -ENXIO; - while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) { + while (read_MASTER_STAT(iface) & BUSBUSY) yield(); - } iface->writeNum = 0; iface->readNum = 0; @@ -439,15 +459,15 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr, /* FIFO Initiation. Data in FIFO should be discarded before * start a new operation. */ - bfin_write_TWI_FIFO_CTL(0x3); + write_FIFO_CTL(iface, 0x3); SSYNC(); - bfin_write_TWI_FIFO_CTL(0); + write_FIFO_CTL(iface, 0); /* clear int stat */ - bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV); + write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV); /* Set Transmit device address */ - bfin_write_TWI_MASTER_ADDR(addr); + write_MASTER_ADDR(iface, addr); SSYNC(); iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; @@ -455,60 +475,64 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr, switch (iface->cur_mode) { case TWI_I2C_MODE_STANDARDSUB: - bfin_write_TWI_XMT_DATA8(iface->command); - bfin_write_TWI_INT_MASK(MCOMP | MERR | + write_XMT_DATA8(iface, iface->command); + write_INT_MASK(iface, MCOMP | MERR | ((iface->read_write == I2C_SMBUS_READ) ? RCVSERV : XMTSERV)); SSYNC(); if (iface->writeNum + 1 <= 255) - bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6); + write_MASTER_CTL(iface, (iface->writeNum + 1) << 6); else { - bfin_write_TWI_MASTER_CTL(0xff << 6); + write_MASTER_CTL(iface, 0xff << 6); iface->manual_stop = 1; } /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | + write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); break; case TWI_I2C_MODE_COMBINED: - bfin_write_TWI_XMT_DATA8(iface->command); - bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV); + write_XMT_DATA8(iface, iface->command); + write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV); SSYNC(); if (iface->writeNum > 0) - bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6); + write_MASTER_CTL(iface, (iface->writeNum + 1) << 6); else - bfin_write_TWI_MASTER_CTL(0x1 << 6); + write_MASTER_CTL(iface, 0x1 << 6); /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | + write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); break; default: - bfin_write_TWI_MASTER_CTL(0); + write_MASTER_CTL(iface, 0); if (size != I2C_SMBUS_QUICK) { /* Don't access xmit data register when this is a * read operation. */ if (iface->read_write != I2C_SMBUS_READ) { if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); + write_XMT_DATA8(iface, + *(iface->transPtr++)); if (iface->writeNum <= 255) - bfin_write_TWI_MASTER_CTL(iface->writeNum << 6); + write_MASTER_CTL(iface, + iface->writeNum << 6); else { - bfin_write_TWI_MASTER_CTL(0xff << 6); + write_MASTER_CTL(iface, + 0xff << 6); iface->manual_stop = 1; } iface->writeNum--; } else { - bfin_write_TWI_XMT_DATA8(iface->command); - bfin_write_TWI_MASTER_CTL(1 << 6); + write_XMT_DATA8(iface, iface->command); + write_MASTER_CTL(iface, 1 << 6); } } else { if (iface->readNum > 0 && iface->readNum <= 255) - bfin_write_TWI_MASTER_CTL(iface->readNum << 6); + write_MASTER_CTL(iface, + iface->readNum << 6); else if (iface->readNum > 255) { - bfin_write_TWI_MASTER_CTL(0xff << 6); + write_MASTER_CTL(iface, 0xff << 6); iface->manual_stop = 1; } else { del_timer(&iface->timeout_timer); @@ -516,13 +540,13 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr, } } } - bfin_write_TWI_INT_MASK(MCOMP | MERR | + write_INT_MASK(iface, MCOMP | MERR | ((iface->read_write == I2C_SMBUS_READ) ? RCVSERV : XMTSERV)); SSYNC(); /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | + write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); break; @@ -557,10 +581,10 @@ static struct i2c_algorithm bfin_twi_algorithm = { static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state) { -/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/ + struct bfin_twi_iface *iface = platform_get_drvdata(dev); /* Disable TWI */ - bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA); + write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA); SSYNC(); return 0; @@ -568,24 +592,53 @@ static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state) static int i2c_bfin_twi_resume(struct platform_device *dev) { -/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/ + struct bfin_twi_iface *iface = platform_get_drvdata(dev); /* Enable TWI */ - bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); + write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); SSYNC(); return 0; } -static int i2c_bfin_twi_probe(struct platform_device *dev) +static int i2c_bfin_twi_probe(struct platform_device *pdev) { - struct bfin_twi_iface *iface = &twi_iface; + struct bfin_twi_iface *iface; struct i2c_adapter *p_adap; + struct resource *res; int rc; + iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL); + if (!iface) { + dev_err(&pdev->dev, "Cannot allocate memory\n"); + rc = -ENOMEM; + goto out_error_nomem; + } + spin_lock_init(&(iface->lock)); init_completion(&(iface->complete)); - iface->irq = IRQ_TWI; + + /* Find and map our resources */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); + rc = -ENOENT; + goto out_error_get_res; + } + + iface->regs_base = ioremap(res->start, res->end - res->start + 1); + if (iface->regs_base == NULL) { + dev_err(&pdev->dev, "Cannot map IO\n"); + rc = -ENXIO; + goto out_error_ioremap; + } + + iface->irq = platform_get_irq(pdev, 0); + if (iface->irq < 0) { + dev_err(&pdev->dev, "No IRQ specified\n"); + rc = -ENOENT; + goto out_error_no_irq; + } init_timer(&(iface->timeout_timer)); iface->timeout_timer.function = bfin_twi_timeout; @@ -593,39 +646,55 @@ static int i2c_bfin_twi_probe(struct platform_device *dev) p_adap = &iface->adap; p_adap->id = I2C_HW_BLACKFIN; - p_adap->nr = dev->id; - strlcpy(p_adap->name, dev->name, sizeof(p_adap->name)); + p_adap->nr = pdev->id; + strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name)); p_adap->algo = &bfin_twi_algorithm; p_adap->algo_data = iface; p_adap->class = I2C_CLASS_ALL; - p_adap->dev.parent = &dev->dev; + p_adap->dev.parent = &pdev->dev; rc = request_irq(iface->irq, bfin_twi_interrupt_entry, - IRQF_DISABLED, dev->name, iface); + IRQF_DISABLED, pdev->name, iface); if (rc) { - dev_err(&(p_adap->dev), "i2c-bfin-twi: can't get IRQ %d !\n", - iface->irq); - return -ENODEV; + dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq); + rc = -ENODEV; + goto out_error_req_irq; } /* Set TWI internal clock as 10MHz */ - bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); + write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); /* Set Twi interface clock as specified */ - bfin_write_TWI_CLKDIV((( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ ) - << 8) | (( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ ) + write_CLKDIV(iface, ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + << 8) | ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) & 0xFF)); /* Enable TWI */ - bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); + write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); SSYNC(); rc = i2c_add_numbered_adapter(p_adap); - if (rc < 0) - free_irq(iface->irq, iface); - else - platform_set_drvdata(dev, iface); + if (rc < 0) { + dev_err(&pdev->dev, "Can't add i2c adapter!\n"); + goto out_error_add_adapter; + } + + platform_set_drvdata(pdev, iface); + dev_info(&pdev->dev, "Blackfin I2C TWI controller, regs_base@%p\n", + iface->regs_base); + + return 0; + +out_error_add_adapter: + free_irq(iface->irq, iface); +out_error_req_irq: +out_error_no_irq: + iounmap(iface->regs_base); +out_error_ioremap: +out_error_get_res: + kfree(iface); +out_error_nomem: return rc; } @@ -637,6 +706,8 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev) i2c_del_adapter(&(iface->adap)); free_irq(iface->irq, iface); + iounmap(iface->regs_base); + kfree(iface); return 0; } @@ -654,8 +725,6 @@ static struct platform_driver i2c_bfin_twi_driver = { static int __init i2c_bfin_twi_init(void) { - pr_info("I2C: Blackfin I2C TWI driver\n"); - return platform_driver_register(&i2c_bfin_twi_driver); } -- cgit v1.2.3 From 74d362e0b3afb7a324855ab9675eb6cda78fda8c Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Tue, 22 Apr 2008 22:16:48 +0200 Subject: i2c-bfin-twi: Add missing pin mux operation Blackfin TWI controller hardware pin should be requested from GPIO port controller Before BF54x, there is no need to do this. But as long as BF54x and BF52x are supported by this generic driver, the missing pin mux operation should be added. Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-bfin-twi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index f2b558f17ca2..446b4f855b03 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -34,6 +34,7 @@ #include #include +#include #include #define POLL_TIMEOUT (2 * HZ) @@ -89,6 +90,11 @@ DEFINE_TWI_REG(XMT_DATA16, 0x84) DEFINE_TWI_REG(RCV_DATA8, 0x88) DEFINE_TWI_REG(RCV_DATA16, 0x8C) +static const u16 pin_req[2][3] = { + {P_TWI0_SCL, P_TWI0_SDA, 0}, + {P_TWI1_SCL, P_TWI1_SDA, 0}, +}; + static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) { unsigned short twi_int_status = read_INT_STAT(iface); @@ -653,6 +659,12 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) p_adap->class = I2C_CLASS_ALL; p_adap->dev.parent = &pdev->dev; + rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi"); + if (rc) { + dev_err(&pdev->dev, "Can't setup pin mux!\n"); + goto out_error_pin_mux; + } + rc = request_irq(iface->irq, bfin_twi_interrupt_entry, IRQF_DISABLED, pdev->name, iface); if (rc) { @@ -690,6 +702,8 @@ out_error_add_adapter: free_irq(iface->irq, iface); out_error_req_irq: out_error_no_irq: + peripheral_free_list(pin_req[pdev->id]); +out_error_pin_mux: iounmap(iface->regs_base); out_error_ioremap: out_error_get_res: @@ -706,6 +720,7 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev) i2c_del_adapter(&(iface->adap)); free_irq(iface->irq, iface); + peripheral_free_list(pin_req[pdev->id]); iounmap(iface->regs_base); kfree(iface); -- cgit v1.2.3 From fa6ad222713a65980528348e7f75abc768b78297 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Tue, 22 Apr 2008 22:16:48 +0200 Subject: i2c-bfin-twi: Cleanup driver descriptions, versions and some module useful information Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-bfin-twi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 446b4f855b03..332640e2f685 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -693,8 +693,8 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, iface); - dev_info(&pdev->dev, "Blackfin I2C TWI controller, regs_base@%p\n", - iface->regs_base); + dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Contoller, " + "regs_base@%p\n", iface->regs_base); return 0; @@ -748,9 +748,9 @@ static void __exit i2c_bfin_twi_exit(void) platform_driver_unregister(&i2c_bfin_twi_driver); } -MODULE_AUTHOR("Sonic Zhang "); -MODULE_DESCRIPTION("I2C-Bus adapter routines for Blackfin TWI"); -MODULE_LICENSE("GPL"); - module_init(i2c_bfin_twi_init); module_exit(i2c_bfin_twi_exit); + +MODULE_AUTHOR("Bryan Wu, Sonic Zhang"); +MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From bd584996b092a019a3ac32fcde7c3851935add96 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 22 Apr 2008 22:16:48 +0200 Subject: i2c-bfin-twi: Use simpler comment headers and strip out information that is maintained in the scm's log Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-bfin-twi.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 332640e2f685..4ea31c018ef6 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -1,25 +1,11 @@ /* - * drivers/i2c/busses/i2c-bfin-twi.c + * Blackfin On-Chip Two Wire Interface Driver * - * Description: Driver for Blackfin Two Wire Interface + * Copyright 2005-2007 Analog Devices Inc. * - * Author: sonicz + * Enter bugs at http://blackfin.uclinux.org/ * - * Copyright (c) 2005-2007 Analog Devices, Inc. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Licensed under the GPL-2 or later. */ #include -- cgit v1.2.3 From d4ce220d493c2f9c41bad510c959c2130b2f1d0d Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Tue, 22 Apr 2008 22:16:48 +0200 Subject: i2c-bfin-twi: Just let i2c-bfin-twi driver depends on BLACKFIN Simply use "depends on BLACKFIN" (which is technically correct) and just document which machines have the device. Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 7d538ddfd37e..e70caaf8f10c 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -100,9 +100,12 @@ config I2C_AU1550 config I2C_BLACKFIN_TWI tristate "Blackfin TWI I2C support" - depends on BF534 || BF536 || BF537 || BF54x + depends on BLACKFIN help - This is the TWI I2C device driver for Blackfin 534/536/537/54x. + This is the TWI I2C device driver for Blackfin BF522, BF525, + BF527, BF534, BF536, BF537 and BF54x. For other Blackfin processors, + please don't use this driver. + This driver can also be built as a module. If so, the module will be called i2c-bfin-twi. -- cgit v1.2.3 From afc13b765ea71d316ce4974d3dc5a96cc73a0e95 Mon Sep 17 00:00:00 2001 From: Hans Schillstrom Date: Tue, 22 Apr 2008 22:16:48 +0200 Subject: i2c-bfin-twi: Fix mismatch in add timer and delete timer Move init_completion to just before i2c transfer. http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3385 Signed-off-by: Hans Schillstrom Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-bfin-twi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 4ea31c018ef6..0cd4d36240db 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -308,6 +308,7 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, iface->writeNum = iface->readNum = pmsg->len; iface->result = 0; iface->timeout_count = 10; + init_completion(&(iface->complete)); /* Set Transmit device address */ write_MASTER_ADDR(iface, pmsg->addr); @@ -447,6 +448,7 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr, iface->read_write = read_write; iface->command = command; iface->timeout_count = 10; + init_completion(&(iface->complete)); /* FIFO Initiation. Data in FIFO should be discarded before * start a new operation. @@ -608,7 +610,6 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) } spin_lock_init(&(iface->lock)); - init_completion(&(iface->complete)); /* Find and map our resources */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.3 From dec1a998bdafb4e4a18c1259bf01ffe85db368c2 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Apr 2008 22:16:48 +0200 Subject: i2c/scx200_acb: Don't use 0 as NULL pointer Don't use 0 as NULL pointer. Spotted by sparse. Signed-off-by: Adrian Bunk Signed-off-by: Jean Delvare --- drivers/i2c/busses/scx200_acb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index f5e7a70da831..61abe0f33255 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -527,7 +527,7 @@ static int __init scx200_create_isa(const char *text, unsigned long base, if (iface == NULL) return -ENOMEM; - if (request_region(base, 8, iface->adapter.name) == 0) { + if (!request_region(base, 8, iface->adapter.name)) { printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", base, base + 8 - 1); rc = -EBUSY; -- cgit v1.2.3 From da672773d8f8169938ebf53449c99afc09938f66 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 22 Apr 2008 22:16:49 +0200 Subject: i2c: New driver for the SuperH Mobile I2C bus controller This is V5 of the SuperH Mobile I2C Controller Driver. A simple Master only driver for the I2C block included in processors such as sh7343, sh7722 and sh7723. Tested on a sh7722 MigoR using a rs5c732b rtc. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-sh_mobile.c | 500 +++++++++++++++++++++++++++++++++++++ 3 files changed, 511 insertions(+) create mode 100644 drivers/i2c/busses/i2c-sh_mobile.c (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index e70caaf8f10c..48438cc5d0ca 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -695,4 +695,14 @@ config I2C_SH7760 This driver can also be built as a module. If so, the module will be called i2c-sh7760. +config I2C_SH_MOBILE + tristate "SuperH Mobile I2C Controller" + depends on SUPERH + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Renesas SH-Mobile processor. + + This driver can also be built as a module. If so, the module + will be called i2c-sh_mobile. + endmenu diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 8e72b2649dc7..e8c882a5ea66 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_I2C_PXA) += i2c-pxa.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o +obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c new file mode 100644 index 000000000000..840e634fa31f --- /dev/null +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -0,0 +1,500 @@ +/* + * SuperH Mobile I2C Controller + * + * Copyright (C) 2008 Magnus Damm + * + * Portions of the code based on out-of-tree driver i2c-sh7343.c + * Copyright (c) 2006 Carlos Munoz + * + * 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 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum sh_mobile_i2c_op { + OP_START = 0, + OP_TX_ONLY, + OP_TX_STOP, + OP_TX_TO_RX, + OP_RX_ONLY, + OP_RX_STOP, +}; + +struct sh_mobile_i2c_data { + struct device *dev; + void __iomem *reg; + struct i2c_adapter adap; + + struct clk *clk; + u_int8_t iccl; + u_int8_t icch; + + spinlock_t lock; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int sr; +}; + +#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ + +/* Register offsets */ +#define ICDR(pd) (pd->reg + 0x00) +#define ICCR(pd) (pd->reg + 0x04) +#define ICSR(pd) (pd->reg + 0x08) +#define ICIC(pd) (pd->reg + 0x0c) +#define ICCL(pd) (pd->reg + 0x10) +#define ICCH(pd) (pd->reg + 0x14) + +/* Register bits */ +#define ICCR_ICE 0x80 +#define ICCR_RACK 0x40 +#define ICCR_TRS 0x10 +#define ICCR_BBSY 0x04 +#define ICCR_SCP 0x01 + +#define ICSR_SCLM 0x80 +#define ICSR_SDAM 0x40 +#define SW_DONE 0x20 +#define ICSR_BUSY 0x10 +#define ICSR_AL 0x08 +#define ICSR_TACK 0x04 +#define ICSR_WAIT 0x02 +#define ICSR_DTE 0x01 + +#define ICIC_ALE 0x08 +#define ICIC_TACKE 0x04 +#define ICIC_WAITE 0x02 +#define ICIC_DTEE 0x01 + +static void activate_ch(struct sh_mobile_i2c_data *pd) +{ + /* Make sure the clock is enabled */ + clk_enable(pd->clk); + + /* Enable channel and configure rx ack */ + iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); + + /* Mask all interrupts */ + iowrite8(0, ICIC(pd)); + + /* Set the clock */ + iowrite8(pd->iccl, ICCL(pd)); + iowrite8(pd->icch, ICCH(pd)); +} + +static void deactivate_ch(struct sh_mobile_i2c_data *pd) +{ + /* Clear/disable interrupts */ + iowrite8(0, ICSR(pd)); + iowrite8(0, ICIC(pd)); + + /* Disable channel */ + iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); + + /* Disable clock */ + clk_disable(pd->clk); +} + +static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, + enum sh_mobile_i2c_op op, unsigned char data) +{ + unsigned char ret = 0; + unsigned long flags; + + dev_dbg(pd->dev, "op %d, data in 0x%02x\n", op, data); + + spin_lock_irqsave(&pd->lock, flags); + + switch (op) { + case OP_START: + iowrite8(0x94, ICCR(pd)); + break; + case OP_TX_ONLY: + iowrite8(data, ICDR(pd)); + break; + case OP_TX_STOP: + iowrite8(data, ICDR(pd)); + iowrite8(0x90, ICCR(pd)); + iowrite8(ICIC_ALE | ICIC_TACKE, ICIC(pd)); + break; + case OP_TX_TO_RX: + iowrite8(data, ICDR(pd)); + iowrite8(0x81, ICCR(pd)); + break; + case OP_RX_ONLY: + ret = ioread8(ICDR(pd)); + break; + case OP_RX_STOP: + ret = ioread8(ICDR(pd)); + iowrite8(0xc0, ICCR(pd)); + break; + } + + spin_unlock_irqrestore(&pd->lock, flags); + + dev_dbg(pd->dev, "op %d, data out 0x%02x\n", op, ret); + return ret; +} + +static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) +{ + struct platform_device *dev = dev_id; + struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev); + struct i2c_msg *msg = pd->msg; + unsigned char data, sr; + int wakeup = 0; + + sr = ioread8(ICSR(pd)); + pd->sr |= sr; + + dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, + (msg->flags & I2C_M_RD) ? "read" : "write", + pd->pos, msg->len); + + if (sr & (ICSR_AL | ICSR_TACK)) { + iowrite8(0, ICIC(pd)); /* disable interrupts */ + wakeup = 1; + goto do_wakeup; + } + + if (pd->pos == msg->len) { + i2c_op(pd, OP_RX_ONLY, 0); + wakeup = 1; + goto do_wakeup; + } + + if (pd->pos == -1) { + data = (msg->addr & 0x7f) << 1; + data |= (msg->flags & I2C_M_RD) ? 1 : 0; + } else + data = msg->buf[pd->pos]; + + if ((pd->pos == -1) || !(msg->flags & I2C_M_RD)) { + if (msg->flags & I2C_M_RD) + i2c_op(pd, OP_TX_TO_RX, data); + else if (pd->pos == (msg->len - 1)) { + i2c_op(pd, OP_TX_STOP, data); + wakeup = 1; + } else + i2c_op(pd, OP_TX_ONLY, data); + } else { + if (pd->pos == (msg->len - 1)) + data = i2c_op(pd, OP_RX_STOP, 0); + else + data = i2c_op(pd, OP_RX_ONLY, 0); + + msg->buf[pd->pos] = data; + } + pd->pos++; + + do_wakeup: + if (wakeup) { + pd->sr |= SW_DONE; + wake_up(&pd->wait); + } + + return IRQ_HANDLED; +} + +static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) +{ + /* Initialize channel registers */ + iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); + + /* Enable channel and configure rx ack */ + iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); + + /* Set the clock */ + iowrite8(pd->iccl, ICCL(pd)); + iowrite8(pd->icch, ICCH(pd)); + + pd->msg = usr_msg; + pd->pos = -1; + pd->sr = 0; + + /* Enable all interrupts except wait */ + iowrite8(ioread8(ICIC(pd)) | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, + ICIC(pd)); + return 0; +} + +static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, + struct i2c_msg *msgs, + int num) +{ + struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); + struct i2c_msg *msg; + int err = 0; + u_int8_t val; + int i, k, retry_count; + + activate_ch(pd); + + /* Process all messages */ + for (i = 0; i < num; i++) { + msg = &msgs[i]; + + err = start_ch(pd, msg); + if (err) + break; + + i2c_op(pd, OP_START, 0); + + /* The interrupt handler takes care of the rest... */ + k = wait_event_timeout(pd->wait, + pd->sr & (ICSR_TACK | SW_DONE), + 5 * HZ); + if (!k) + dev_err(pd->dev, "Transfer request timed out\n"); + + retry_count = 10; +again: + val = ioread8(ICSR(pd)); + + dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); + + if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) { + err = -EIO; + break; + } + + /* the interrupt handler may wake us up before the + * transfer is finished, so poll the hardware + * until we're done. + */ + + if (!(!(val & ICSR_BUSY) && (val & ICSR_SCLM) && + (val & ICSR_SDAM))) { + msleep(1); + if (retry_count--) + goto again; + + err = -EIO; + dev_err(pd->dev, "Polling timed out\n"); + break; + } + } + + deactivate_ch(pd); + + if (!err) + err = num; + return err; +} + +static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static struct i2c_algorithm sh_mobile_i2c_algorithm = { + .functionality = sh_mobile_i2c_func, + .master_xfer = sh_mobile_i2c_xfer, +}; + +static void sh_mobile_i2c_setup_channel(struct platform_device *dev) +{ + struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev); + unsigned long peripheral_clk = clk_get_rate(pd->clk); + u_int32_t num; + u_int32_t denom; + u_int32_t tmp; + + spin_lock_init(&pd->lock); + init_waitqueue_head(&pd->wait); + + /* Calculate the value for iccl. From the data sheet: + * iccl = (p clock / transfer rate) * (L / (L + H)) + * where L and H are the SCL low/high ratio (5/4 in this case). + * We also round off the result. + */ + num = peripheral_clk * 5; + denom = NORMAL_SPEED * 9; + tmp = num * 10 / denom; + if (tmp % 10 >= 5) + pd->iccl = (u_int8_t)((num/denom) + 1); + else + pd->iccl = (u_int8_t)(num/denom); + + /* Calculate the value for icch. From the data sheet: + icch = (p clock / transfer rate) * (H / (L + H)) */ + num = peripheral_clk * 4; + tmp = num * 10 / denom; + if (tmp % 10 >= 5) + pd->icch = (u_int8_t)((num/denom) + 1); + else + pd->icch = (u_int8_t)(num/denom); +} + +static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) +{ + struct resource *res; + int ret = -ENXIO; + int q, m; + int k = 0; + int n = 0; + + while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) { + for (n = res->start; hook && n <= res->end; n++) { + if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED, + dev->dev.bus_id, dev)) + goto rollback; + } + k++; + } + + if (hook) + return k > 0 ? 0 : -ENOENT; + + k--; + ret = 0; + + rollback: + for (q = k; k >= 0; k--) { + for (m = n; m >= res->start; m--) + free_irq(m, dev); + + res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1); + m = res->end; + } + + return ret; +} + +static int sh_mobile_i2c_probe(struct platform_device *dev) +{ + struct sh_mobile_i2c_data *pd; + struct i2c_adapter *adap; + struct resource *res; + int size; + int ret; + + pd = kzalloc(sizeof(struct sh_mobile_i2c_data), GFP_KERNEL); + if (pd == NULL) { + dev_err(&dev->dev, "cannot allocate private data\n"); + return -ENOMEM; + } + + pd->clk = clk_get(&dev->dev, "peripheral_clk"); + if (IS_ERR(pd->clk)) { + dev_err(&dev->dev, "cannot get peripheral clock\n"); + ret = PTR_ERR(pd->clk); + goto err; + } + + ret = sh_mobile_i2c_hook_irqs(dev, 1); + if (ret) { + dev_err(&dev->dev, "cannot request IRQ\n"); + goto err_clk; + } + + pd->dev = &dev->dev; + platform_set_drvdata(dev, pd); + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&dev->dev, "cannot find IO resource\n"); + ret = -ENOENT; + goto err_irq; + } + + size = (res->end - res->start) + 1; + + pd->reg = ioremap(res->start, size); + if (pd->reg == NULL) { + dev_err(&dev->dev, "cannot map IO\n"); + ret = -ENXIO; + goto err_irq; + } + + /* setup the private data */ + adap = &pd->adap; + i2c_set_adapdata(adap, pd); + + adap->owner = THIS_MODULE; + adap->algo = &sh_mobile_i2c_algorithm; + adap->dev.parent = &dev->dev; + adap->retries = 5; + adap->nr = dev->id; + + strlcpy(adap->name, dev->name, sizeof(adap->name)); + + sh_mobile_i2c_setup_channel(dev); + + ret = i2c_add_numbered_adapter(adap); + if (ret < 0) { + dev_err(&dev->dev, "cannot add numbered adapter\n"); + goto err_all; + } + + return 0; + + err_all: + iounmap(pd->reg); + err_irq: + sh_mobile_i2c_hook_irqs(dev, 0); + err_clk: + clk_put(pd->clk); + err: + kfree(pd); + return ret; +} + +static int sh_mobile_i2c_remove(struct platform_device *dev) +{ + struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev); + + i2c_del_adapter(&pd->adap); + iounmap(pd->reg); + sh_mobile_i2c_hook_irqs(dev, 0); + clk_put(pd->clk); + kfree(pd); + return 0; +} + +static struct platform_driver sh_mobile_i2c_driver = { + .driver = { + .name = "i2c-sh_mobile", + .owner = THIS_MODULE, + }, + .probe = sh_mobile_i2c_probe, + .remove = sh_mobile_i2c_remove, +}; + +static int __init sh_mobile_i2c_adap_init(void) +{ + return platform_driver_register(&sh_mobile_i2c_driver); +} + +static void __exit sh_mobile_i2c_adap_exit(void) +{ + platform_driver_unregister(&sh_mobile_i2c_driver); +} + +module_init(sh_mobile_i2c_adap_init); +module_exit(sh_mobile_i2c_adap_exit); + +MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver"); +MODULE_AUTHOR("Magnus Damm"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From add8eda7f2be781af0224241e870715cf0cfd75a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 22 Apr 2008 22:16:49 +0200 Subject: i2c: Fix platform driver hotplug/coldplug Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable I2C platform drivers, to allow module auto loading. [ db: add some more drivers ] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-at91.c | 2 +- drivers/i2c/busses/i2c-au1550.c | 1 + drivers/i2c/busses/i2c-bfin-twi.c | 1 + drivers/i2c/busses/i2c-davinci.c | 3 +++ drivers/i2c/busses/i2c-gpio.c | 1 + drivers/i2c/busses/i2c-iop3xx.c | 1 + drivers/i2c/busses/i2c-ixp2000.c | 1 + drivers/i2c/busses/i2c-mpc.c | 3 +++ drivers/i2c/busses/i2c-ocores.c | 3 +++ drivers/i2c/busses/i2c-omap.c | 1 + drivers/i2c/busses/i2c-pmcmsp.c | 3 +++ drivers/i2c/busses/i2c-pnx.c | 1 + drivers/i2c/busses/i2c-powermac.c | 3 +++ drivers/i2c/busses/i2c-pxa.c | 1 + drivers/i2c/busses/i2c-s3c2410.c | 1 + drivers/i2c/busses/i2c-simtec.c | 3 +++ drivers/i2c/busses/i2c-versatile.c | 1 + 17 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/i2c/busses') diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index c09b036913bd..73d61946a534 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -298,7 +298,7 @@ static int at91_i2c_resume(struct platform_device *pdev) #endif /* work with "modprobe at91_i2c" from hotplugging or coldplugging */ -MODULE_ALIAS("at91_i2c"); +MODULE_ALIAS("platform:at91_i2c"); static struct platform_driver at91_i2c_driver = { .probe = at91_i2c_probe, diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index 1953b26da56a..491718fe46b7 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -472,6 +472,7 @@ i2c_au1550_exit(void) MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:au1xpsc_smbus"); module_init (i2c_au1550_init); module_exit (i2c_au1550_exit); diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 0cd4d36240db..48d084bdf7c8 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -741,3 +741,4 @@ module_exit(i2c_bfin_twi_exit); MODULE_AUTHOR("Bryan Wu, Sonic Zhang"); MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:i2c-bfin-twi"); diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index c7dbb9d0423e..7ecbfc429b19 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -553,6 +553,9 @@ static int davinci_i2c_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:i2c_davinci"); + static struct platform_driver davinci_i2c_driver = { .probe = davinci_i2c_probe, .remove = davinci_i2c_remove, diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 3ca19fc234fb..7c1b762aa681 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -220,3 +220,4 @@ module_exit(i2c_gpio_exit); MODULE_AUTHOR("Haavard Skinnemoen "); MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:i2c-gpio"); diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index ab41400c883e..39884e797594 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -550,3 +550,4 @@ module_exit (i2c_iop3xx_exit); MODULE_AUTHOR("D-TACQ Solutions Ltd "); MODULE_DESCRIPTION("IOP3xx iic algorithm and driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:IOP3xx-I2C"); diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index 6352121a2827..5af9e6521e6c 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c @@ -164,4 +164,5 @@ module_exit(ixp2000_i2c_exit); MODULE_AUTHOR ("Deepak Saxena "); MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:IXP2000-I2C"); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index bbe787b243b7..18beb0ad7bf3 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -392,6 +392,9 @@ static int fsl_i2c_remove(struct platform_device *pdev) return 0; }; +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:fsl-i2c"); + /* Structure for a device driver */ static struct platform_driver fsl_i2c_driver = { .probe = fsl_i2c_probe, diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index e417c2c3ca22..f145692cbb76 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -312,6 +312,9 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:ocores-i2c"); + static struct platform_driver ocores_i2c_driver = { .probe = ocores_i2c_probe, .remove = __devexit_p(ocores_i2c_remove), diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 7ba31770d773..e7eb7bf9ddec 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -693,3 +693,4 @@ module_exit(omap_i2c_exit_driver); MODULE_AUTHOR("MontaVista Software, Inc. (and others)"); MODULE_DESCRIPTION("TI OMAP I2C bus adapter"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:i2c_omap"); diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 9ea0f8aa74f4..63b3e2c11cff 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -627,6 +627,9 @@ static struct i2c_adapter pmcmsptwi_adapter = { .name = DRV_NAME, }; +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:" DRV_NAME); + static struct platform_driver pmcmsptwi_driver = { .probe = pmcmsptwi_probe, .remove = __devexit_p(pmcmsptwi_remove), diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 6695d5902ed4..1ca21084ffcf 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -697,6 +697,7 @@ static void __exit i2c_adap_pnx_exit(void) MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev "); MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pnx-i2c"); /* We need to make sure I2C is initialized before USB */ subsys_initcall(i2c_adap_pnx_init); diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 7813127649a1..22f6d5c00d80 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -263,6 +263,9 @@ static int __devexit i2c_powermac_probe(struct platform_device *dev) } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:i2c-powermac"); + static struct platform_driver i2c_powermac_driver = { .probe = i2c_powermac_probe, .remove = __devexit_p(i2c_powermac_remove), diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 330fff464ea9..eb69fbadc9cb 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1132,6 +1132,7 @@ static void __exit i2c_adap_pxa_exit(void) } MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa2xx-i2c"); module_init(i2c_adap_pxa_init); module_exit(i2c_adap_pxa_exit); diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 5ece33ea5e22..1305ef190fc1 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -948,3 +948,4 @@ module_exit(i2c_adap_s3c_exit); MODULE_DESCRIPTION("S3C24XX I2C Bus driver"); MODULE_AUTHOR("Ben Dooks, "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c2410-i2c"); diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 10af8d31e12a..042fda295f3a 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -159,6 +159,9 @@ static int simtec_i2c_remove(struct platform_device *dev) /* device driver */ +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:simtec-i2c"); + static struct platform_driver simtec_i2c_driver = { .driver = { .name = "simtec-i2c", diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c index 081d9578ce10..4678babd3ce6 100644 --- a/drivers/i2c/busses/i2c-versatile.c +++ b/drivers/i2c/busses/i2c-versatile.c @@ -151,3 +151,4 @@ module_exit(i2c_versatile_exit); MODULE_DESCRIPTION("ARM Versatile I2C bus driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:versatile-i2c"); -- cgit v1.2.3