Another try.. now without redundant declarations. Jordan
ALCHEMY: AU1200 I2C modifications From: Jordan Crouse <jordan.crouse@xxxxxxx> Modifications to the existing AU1XXX I2C controller for the Au1200. Signed-off-by: Jordan Crouse <jordan.crouse@xxxxxxx> --- arch/mips/au1000/db1x00/board_setup.c | 37 +++++++++++++++++++++++++++++ drivers/i2c/busses/Kconfig | 2 +- drivers/i2c/busses/i2c-au1550.c | 22 ++++++++++++----- include/asm-mips/mach-au1x00/au1xxx_psc.h | 2 +- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c index f00ec3b..a2638c8 100644 --- a/arch/mips/au1000/db1x00/board_setup.c +++ b/arch/mips/au1000/db1x00/board_setup.c @@ -76,6 +76,43 @@ #if defined(CONFIG_IRDA) && (defined(CON #endif bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */ +#if defined(CONFIG_I2C_AU1550) && defined(CONFIG_MIPS_DB1200) + { + u32 freq0, clksrc; + + /* Select SMBUS in CPLD */ + bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); + + pin_func = au_readl(SYS_PINFUNC); + au_sync(); + pin_func &= ~(3<<17 | 1<<4); + /* Set GPIOs correctly */ + pin_func |= 2<<17; + au_writel(pin_func, SYS_PINFUNC); + au_sync(); + + /* The i2c driver depends on 50Mhz clock */ + freq0 = au_readl(SYS_FREQCTRL0); + au_sync(); + freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1); + freq0 |= (3<<SYS_FC_FRDIV1_BIT); + /* 396Mhz / (3+1)*2 == 49.5Mhz */ + au_writel(freq0, SYS_FREQCTRL0); + au_sync(); + freq0 |= SYS_FC_FE1; + au_writel(freq0, SYS_FREQCTRL0); + au_sync(); + + clksrc = au_readl(SYS_CLKSRC); + au_sync(); + clksrc &= ~0x01f00000; + /* bit 22 is EXTCLK0 for PSC0 */ + clksrc |= (0x3 << 22); + au_writel(clksrc, SYS_CLKSRC); + au_sync(); + } +#endif + #ifdef CONFIG_MIPS_MIRAGE /* enable GPIO[31:0] inputs */ au_writel(0, SYS_PININPUTEN); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index d6d4494..e023563 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -76,7 +76,7 @@ config I2C_AMD8111 config I2C_AU1550 tristate "Au1550 SMBus interface" - depends on I2C && SOC_AU1550 + depends on I2C && (SOC_AU1550 || SOC_AU1200) help If you say yes to this option, support will be included for the Au1550 SMBus interface. diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index d06edce..368fd96 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -34,8 +34,7 @@ #include <linux/init.h> #include <linux/errno.h> #include <linux/i2c.h> -#include <asm/mach-au1x00/au1000.h> -#include <asm/mach-pb1x00/pb1550.h> +#include <asm/mach-au1x00/au1xxx.h> #include <asm/mach-au1x00/au1xxx_psc.h> #include "i2c-au1550.h" @@ -118,13 +117,20 @@ do_address(struct i2c_au1550_data *adap, /* Reset the FIFOs, clear events. */ - sp->psc_smbpcr = PSC_SMBPCR_DC; + stat = sp->psc_smbstat; sp->psc_smbevnt = PSC_SMBEVNT_ALLCLR; au_sync(); - do { - stat = sp->psc_smbpcr; + + if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) + { + sp->psc_smbpcr = PSC_SMBPCR_DC; au_sync(); - } while ((stat & PSC_SMBPCR_DC) != 0); + do { + stat = sp->psc_smbpcr; + au_sync(); + } while ((stat & PSC_SMBPCR_DC) != 0); + udelay(50); + } /* Write out the i2c chip address and specify operation */ @@ -367,7 +373,7 @@ static struct i2c_au1550_data pb1550_i2c SMBUS_PSC_BASE, 200, 200 }; -static struct i2c_adapter pb1550_board_adapter = { +struct i2c_adapter pb1550_board_adapter = { name: "pb1550 adapter", id: I2C_HW_AU1550_PSC, algo: NULL, @@ -376,6 +382,8 @@ static struct i2c_adapter pb1550_board_a client_unregister: pb1550_unreg, }; +EXPORT_SYMBOL(pb1550_board_adapter); + /* BIG hack to support the control interface on the Wolfson WM8731 * audio codec on the Pb1550 board. We get an address and two data * bytes to write, create an i2c message, and send it across the diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h index faa5ffe..c097ac3 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_psc.h +++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h @@ -513,7 +513,7 @@ #define PSC_SMBEVNT_ALLCLR (PSC_SMBEVNT_ /* Transmit register control. */ -#define PSC_SMBTXRX_RSR (1 << 30) +#define PSC_SMBTXRX_RSR (1 << 28) #define PSC_SMBTXRX_STP (1 << 29) #define PSC_SMBTXRX_DATAMASK (0xff)