ALCHEMY: AU1200 I2C modifications From: Jordan Crouse Modifications to the existing AU1XXX I2C controller for the Au1200. Signed-off-by: Jordan Crouse --- arch/mips/au1000/db1x00/board_setup.c | 37 +++++++++++++++++++++++++++++ drivers/i2c/busses/Kconfig | 2 +- drivers/i2c/busses/i2c-au1550.c | 29 ++++++++++++++++++----- include/asm-mips/mach-au1x00/au1xxx_psc.h | 7 +++++ 4 files changed, 67 insertions(+), 8 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< #include #include -#include +#if defined(CONFIG_MIPS_PB1550) + #include +#endif +#if defined(CONFIG_MIPS_PB1200) + #include +#endif +#if defined(CONFIG_MIPS_DB1200) + #include +#endif #include #include "i2c-au1550.h" @@ -118,13 +126,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 +382,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 +391,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..a523079 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_psc.h +++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h @@ -48,6 +48,11 @@ #define PSC0_BASE_ADDR 0xb1a00000 #define PSC1_BASE_ADDR 0xb1b00000 #endif +#ifdef CONFIG_SOC_AU1200 +#define PSC0_BASE_ADDR 0xb1a00000 +#define PSC1_BASE_ADDR 0xb1b00000 +#endif + /* The PSC select and control registers are common to * all protocols. */ @@ -513,7 +518,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)