* [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs @ 2016-01-14 13:06 Hans de Goede 2016-01-14 13:06 ` [U-Boot] [PATCH 2/2] sunxi: Add support for the I2C controller which is part of the PRCM Hans de Goede 2016-01-21 6:31 ` [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs Heiko Schocher 0 siblings, 2 replies; 4+ messages in thread From: Hans de Goede @ 2016-01-14 13:06 UTC (permalink / raw) To: u-boot On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1, rather then a normal r/w bit which is cleared by writing 0. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/i2c/mvtwsi.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index f20d1b2..698bfc1 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -73,6 +73,17 @@ struct mvtwsi_registers { #define MVTWSI_CONTROL_INTEN 0x00000080 /* + * On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1, + * on other platforms it is a normal r/w bit which is cleared by writing 0. + */ + +#ifdef CONFIG_SUNXI_GEN_SUN6I +#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000008 +#else +#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000000 +#endif + +/* * Status register values -- only those expected in normal master * operation on non-10-bit-address devices; whatever status we don't * expect in nominal conditions (bus errors, arbitration losses, @@ -189,7 +200,7 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status) /* globally set TWSIEN in case it was not */ twsi_control_flags |= MVTWSI_CONTROL_TWSIEN; /* assert START */ - writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control); + writel(twsi_control_flags | MVTWSI_CONTROL_START | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); /* wait for controller to process START */ return twsi_wait(adap, expected_status); } @@ -204,7 +215,7 @@ static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status) /* put byte in data register for sending */ writel(byte, &twsi->data); /* clear any pending interrupt -- that'll cause sending */ - writel(twsi_control_flags, &twsi->control); + writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); /* wait for controller to receive byte and check ACK */ return twsi_wait(adap, expected_status); } @@ -224,7 +235,7 @@ static int twsi_recv(struct i2c_adapter *adap, u8 *byte) else expected_status = MVTWSI_STATUS_DATA_R_NAK; /* acknowledge *previous state* and launch receive */ - writel(twsi_control_flags, &twsi->control); + writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); /* wait for controller to receive byte and assert ACK or NAK */ status = twsi_wait(adap, expected_status); /* if we did receive expected byte then store it */ @@ -246,7 +257,7 @@ static int twsi_stop(struct i2c_adapter *adap, int status) /* assert STOP */ control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP; - writel(control, &twsi->control); + writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); /* wait for IDLE; IFLG won't rise so twsi_wait() is no use. */ do { stop_status = readl(&twsi->status); -- 2.5.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH 2/2] sunxi: Add support for the I2C controller which is part of the PRCM 2016-01-14 13:06 [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs Hans de Goede @ 2016-01-14 13:06 ` Hans de Goede 2016-01-21 6:32 ` Heiko Schocher 2016-01-21 6:31 ` [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs Heiko Schocher 1 sibling, 1 reply; 4+ messages in thread From: Hans de Goede @ 2016-01-14 13:06 UTC (permalink / raw) To: u-boot From: Jelle van der Waa <jelle@vdwaa.nl> Signed-off-by: Jelle van der Waa <jelle@vdwaa.nl> [hdegoede at redhat.com: Minor cleanups] Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 10 ++++++++++ arch/arm/cpu/armv7/sunxi/prcm.c | 12 ++++++++++++ arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 1 + arch/arm/include/asm/arch-sunxi/gpio.h | 2 ++ arch/arm/include/asm/arch-sunxi/i2c.h | 3 +++ arch/arm/include/asm/arch-sunxi/prcm.h | 2 ++ board/sunxi/Kconfig | 6 ++++++ board/sunxi/board.c | 6 ++++++ configs/orangepi_pc_defconfig | 1 + drivers/i2c/mvtwsi.c | 11 +++++++++++ include/configs/sunxi-common.h | 2 +- 11 files changed, 55 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 4501884..1da5455 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -77,6 +77,16 @@ int clock_twi_onoff(int port, int state) struct sunxi_ccm_reg *const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + if (port == 5) { + if (state) + prcm_apb0_enable( + PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_I2C); + else + prcm_apb0_disable( + PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_I2C); + return 0; + } + /* set the apb clock gate for twi */ if (state) setbits_le32(&ccm->apb2_gate, diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/cpu/armv7/sunxi/prcm.c index 19b4938..e1d091f 100644 --- a/arch/arm/cpu/armv7/sunxi/prcm.c +++ b/arch/arm/cpu/armv7/sunxi/prcm.c @@ -33,3 +33,15 @@ void prcm_apb0_enable(u32 flags) /* deassert reset for module */ setbits_le32(&prcm->apb0_reset, flags); } + +void prcm_apb0_disable(u32 flags) +{ + struct sunxi_prcm_reg *prcm = + (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; + + /* assert reset for module */ + clrbits_le32(&prcm->apb0_reset, flags); + + /* close the clock for module */ + clrbits_le32(&prcm->apb0_gate, flags); +} diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 63b161a..0cdefdc 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -134,6 +134,7 @@ #define SUNXI_RTC_BASE 0x01f00000 #define SUNXI_PRCM_BASE 0x01f01400 #define SUN6I_CPUCFG_BASE 0x01f01c00 +#define SUNXI_R_TWI_BASE 0x01f02400 #define SUNXI_R_UART_BASE 0x01f02800 #define SUNXI_R_PIO_BASE 0x01f02c00 #define SUN6I_P2WI_BASE 0x01f03400 diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index a2a9a38..0eca859 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -199,6 +199,8 @@ enum sunxi_gpio_number { #define SUN6I_GPL1_R_P2WI_SDA 3 #define SUN8I_GPL_R_RSB 2 +#define SUN8I_H3_GPL_R_TWI 2 +#define SUN8I_A23_GPL_R_TWI 3 #define SUN8I_GPL_R_UART 2 #define SUN9I_GPN_R_RSB 3 diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h index 561cd2b..4dfd313 100644 --- a/arch/arm/include/asm/arch-sunxi/i2c.h +++ b/arch/arm/include/asm/arch-sunxi/i2c.h @@ -23,6 +23,9 @@ #ifdef CONFIG_I2C4_ENABLE #define CONFIG_I2C_MVTWSI_BASE4 SUNXI_TWI4_BASE #endif +#ifdef CONFIG_R_I2C_ENABLE +#define CONFIG_I2C_MVTWSI_BASE5 SUNXI_R_TWI_BASE +#endif /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ #define CONFIG_SYS_TCLK 24000000 diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h index 82ed541..556c1af 100644 --- a/arch/arm/include/asm/arch-sunxi/prcm.h +++ b/arch/arm/include/asm/arch-sunxi/prcm.h @@ -236,5 +236,7 @@ struct sunxi_prcm_reg { }; void prcm_apb0_enable(u32 flags); +void prcm_apb0_disable(u32 flags); + #endif /* __ASSEMBLY__ */ #endif /* _PRCM_H */ diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 9d67847..7c69be9 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -363,6 +363,12 @@ config I2C3_ENABLE See I2C0_ENABLE help text. endif +config R_I2C_ENABLE + bool "Enable the PRCM I2C/TWI controller" + default n + ---help--- + Set this to y to enable the I2C controller which is part of the PRCM. + if MACH_SUN7I config I2C4_ENABLE bool "Enable I2C/TWI controller 4" diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 386e2e0..1cc39e4 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -422,6 +422,12 @@ void i2c_init_board(void) clock_twi_onoff(4, 1); #endif #endif + +#ifdef CONFIG_R_I2C_ENABLE + clock_twi_onoff(5, 1); + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI); +#endif } #ifdef CONFIG_SPL_BUILD diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig index 358caa5..ea9ed87 100644 --- a/configs/orangepi_pc_defconfig +++ b/configs/orangepi_pc_defconfig @@ -12,3 +12,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_R_I2C_ENABLE=y diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 698bfc1..b5304d8 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -128,6 +128,10 @@ static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap) case 4: return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4; #endif +#ifdef CONFIG_I2C_MVTWSI_BASE5 + case 5: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE5; +#endif default: printf("Missing mvtwsi controller %d base\n", adap->hwadapnr); break; @@ -486,3 +490,10 @@ U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4) #endif +#ifdef CONFIG_I2C_MVTWSI_BASE5 +U_BOOT_I2C_ADAP_COMPLETE(twsi5, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 5) + +#endif diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 790e704..b4dfb3c 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -212,7 +212,7 @@ #if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \ defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \ - defined CONFIG_I2C4_ENABLE + defined CONFIG_I2C4_ENABLE || defined CONFIG_R_I2C_ENABLE #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI #define CONFIG_SYS_I2C_SPEED 400000 -- 2.5.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH 2/2] sunxi: Add support for the I2C controller which is part of the PRCM 2016-01-14 13:06 ` [U-Boot] [PATCH 2/2] sunxi: Add support for the I2C controller which is part of the PRCM Hans de Goede @ 2016-01-21 6:32 ` Heiko Schocher 0 siblings, 0 replies; 4+ messages in thread From: Heiko Schocher @ 2016-01-21 6:32 UTC (permalink / raw) To: u-boot Hello Hans, Am 14.01.2016 um 14:06 schrieb Hans de Goede: > From: Jelle van der Waa <jelle@vdwaa.nl> > > Signed-off-by: Jelle van der Waa <jelle@vdwaa.nl> > [hdegoede at redhat.com: Minor cleanups] > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 10 ++++++++++ > arch/arm/cpu/armv7/sunxi/prcm.c | 12 ++++++++++++ > arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 1 + > arch/arm/include/asm/arch-sunxi/gpio.h | 2 ++ > arch/arm/include/asm/arch-sunxi/i2c.h | 3 +++ > arch/arm/include/asm/arch-sunxi/prcm.h | 2 ++ > board/sunxi/Kconfig | 6 ++++++ > board/sunxi/board.c | 6 ++++++ > configs/orangepi_pc_defconfig | 1 + > drivers/i2c/mvtwsi.c | 11 +++++++++++ > include/configs/sunxi-common.h | 2 +- > 11 files changed, 55 insertions(+), 1 deletion(-) Thanks! Applied to u-boot-i2c.git with fixing 2 checkpatch warnigns. bye, Heiko > > diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c > index 4501884..1da5455 100644 > --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c > +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c > @@ -77,6 +77,16 @@ int clock_twi_onoff(int port, int state) > struct sunxi_ccm_reg *const ccm = > (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; > > + if (port == 5) { > + if (state) > + prcm_apb0_enable( > + PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_I2C); > + else > + prcm_apb0_disable( > + PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_I2C); > + return 0; > + } > + > /* set the apb clock gate for twi */ > if (state) > setbits_le32(&ccm->apb2_gate, > diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/cpu/armv7/sunxi/prcm.c > index 19b4938..e1d091f 100644 > --- a/arch/arm/cpu/armv7/sunxi/prcm.c > +++ b/arch/arm/cpu/armv7/sunxi/prcm.c > @@ -33,3 +33,15 @@ void prcm_apb0_enable(u32 flags) > /* deassert reset for module */ > setbits_le32(&prcm->apb0_reset, flags); > } > + > +void prcm_apb0_disable(u32 flags) > +{ > + struct sunxi_prcm_reg *prcm = > + (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; > + > + /* assert reset for module */ > + clrbits_le32(&prcm->apb0_reset, flags); > + > + /* close the clock for module */ > + clrbits_le32(&prcm->apb0_gate, flags); > +} > diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h > index 63b161a..0cdefdc 100644 > --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h > +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h > @@ -134,6 +134,7 @@ > #define SUNXI_RTC_BASE 0x01f00000 > #define SUNXI_PRCM_BASE 0x01f01400 > #define SUN6I_CPUCFG_BASE 0x01f01c00 > +#define SUNXI_R_TWI_BASE 0x01f02400 > #define SUNXI_R_UART_BASE 0x01f02800 > #define SUNXI_R_PIO_BASE 0x01f02c00 > #define SUN6I_P2WI_BASE 0x01f03400 > diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h > index a2a9a38..0eca859 100644 > --- a/arch/arm/include/asm/arch-sunxi/gpio.h > +++ b/arch/arm/include/asm/arch-sunxi/gpio.h > @@ -199,6 +199,8 @@ enum sunxi_gpio_number { > #define SUN6I_GPL1_R_P2WI_SDA 3 > > #define SUN8I_GPL_R_RSB 2 > +#define SUN8I_H3_GPL_R_TWI 2 > +#define SUN8I_A23_GPL_R_TWI 3 > #define SUN8I_GPL_R_UART 2 > > #define SUN9I_GPN_R_RSB 3 > diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h > index 561cd2b..4dfd313 100644 > --- a/arch/arm/include/asm/arch-sunxi/i2c.h > +++ b/arch/arm/include/asm/arch-sunxi/i2c.h > @@ -23,6 +23,9 @@ > #ifdef CONFIG_I2C4_ENABLE > #define CONFIG_I2C_MVTWSI_BASE4 SUNXI_TWI4_BASE > #endif > +#ifdef CONFIG_R_I2C_ENABLE > +#define CONFIG_I2C_MVTWSI_BASE5 SUNXI_R_TWI_BASE > +#endif > > /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ > #define CONFIG_SYS_TCLK 24000000 > diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h > index 82ed541..556c1af 100644 > --- a/arch/arm/include/asm/arch-sunxi/prcm.h > +++ b/arch/arm/include/asm/arch-sunxi/prcm.h > @@ -236,5 +236,7 @@ struct sunxi_prcm_reg { > }; > > void prcm_apb0_enable(u32 flags); > +void prcm_apb0_disable(u32 flags); > + > #endif /* __ASSEMBLY__ */ > #endif /* _PRCM_H */ > diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig > index 9d67847..7c69be9 100644 > --- a/board/sunxi/Kconfig > +++ b/board/sunxi/Kconfig > @@ -363,6 +363,12 @@ config I2C3_ENABLE > See I2C0_ENABLE help text. > endif > > +config R_I2C_ENABLE > + bool "Enable the PRCM I2C/TWI controller" > + default n > + ---help--- > + Set this to y to enable the I2C controller which is part of the PRCM. > + > if MACH_SUN7I > config I2C4_ENABLE > bool "Enable I2C/TWI controller 4" > diff --git a/board/sunxi/board.c b/board/sunxi/board.c > index 386e2e0..1cc39e4 100644 > --- a/board/sunxi/board.c > +++ b/board/sunxi/board.c > @@ -422,6 +422,12 @@ void i2c_init_board(void) > clock_twi_onoff(4, 1); > #endif > #endif > + > +#ifdef CONFIG_R_I2C_ENABLE > + clock_twi_onoff(5, 1); > + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI); > + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI); > +#endif > } > > #ifdef CONFIG_SPL_BUILD > diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig > index 358caa5..ea9ed87 100644 > --- a/configs/orangepi_pc_defconfig > +++ b/configs/orangepi_pc_defconfig > @@ -12,3 +12,4 @@ CONFIG_SPL=y > # CONFIG_CMD_FLASH is not set > # CONFIG_CMD_FPGA is not set > CONFIG_CMD_GPIO=y > +CONFIG_R_I2C_ENABLE=y > diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c > index 698bfc1..b5304d8 100644 > --- a/drivers/i2c/mvtwsi.c > +++ b/drivers/i2c/mvtwsi.c > @@ -128,6 +128,10 @@ static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap) > case 4: > return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4; > #endif > +#ifdef CONFIG_I2C_MVTWSI_BASE5 > + case 5: > + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE5; > +#endif > default: > printf("Missing mvtwsi controller %d base\n", adap->hwadapnr); > break; > @@ -486,3 +490,10 @@ U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe, > CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4) > > #endif > +#ifdef CONFIG_I2C_MVTWSI_BASE5 > +U_BOOT_I2C_ADAP_COMPLETE(twsi5, twsi_i2c_init, twsi_i2c_probe, > + twsi_i2c_read, twsi_i2c_write, > + twsi_i2c_set_bus_speed, > + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 5) > + > +#endif > diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h > index 790e704..b4dfb3c 100644 > --- a/include/configs/sunxi-common.h > +++ b/include/configs/sunxi-common.h > @@ -212,7 +212,7 @@ > > #if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \ > defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \ > - defined CONFIG_I2C4_ENABLE > + defined CONFIG_I2C4_ENABLE || defined CONFIG_R_I2C_ENABLE > #define CONFIG_SYS_I2C > #define CONFIG_SYS_I2C_MVTWSI > #define CONFIG_SYS_I2C_SPEED 400000 > -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany ^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs 2016-01-14 13:06 [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs Hans de Goede 2016-01-14 13:06 ` [U-Boot] [PATCH 2/2] sunxi: Add support for the I2C controller which is part of the PRCM Hans de Goede @ 2016-01-21 6:31 ` Heiko Schocher 1 sibling, 0 replies; 4+ messages in thread From: Heiko Schocher @ 2016-01-21 6:31 UTC (permalink / raw) To: u-boot Hello Hans, Am 14.01.2016 um 14:06 schrieb Hans de Goede: > On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1, > rather then a normal r/w bit which is cleared by writing 0. > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > drivers/i2c/mvtwsi.c | 19 +++++++++++++++---- > 1 file changed, 15 insertions(+), 4 deletions(-) Thanks! Applied to u-boot-i2c.git with fixing 3 checkpatch errors/warnings. bye, Heiko > > diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c > index f20d1b2..698bfc1 100644 > --- a/drivers/i2c/mvtwsi.c > +++ b/drivers/i2c/mvtwsi.c > @@ -73,6 +73,17 @@ struct mvtwsi_registers { > #define MVTWSI_CONTROL_INTEN 0x00000080 > > /* > + * On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1, > + * on other platforms it is a normal r/w bit which is cleared by writing 0. > + */ > + > +#ifdef CONFIG_SUNXI_GEN_SUN6I > +#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000008 > +#else > +#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000000 > +#endif > + > +/* > * Status register values -- only those expected in normal master > * operation on non-10-bit-address devices; whatever status we don't > * expect in nominal conditions (bus errors, arbitration losses, > @@ -189,7 +200,7 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status) > /* globally set TWSIEN in case it was not */ > twsi_control_flags |= MVTWSI_CONTROL_TWSIEN; > /* assert START */ > - writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control); > + writel(twsi_control_flags | MVTWSI_CONTROL_START | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); > /* wait for controller to process START */ > return twsi_wait(adap, expected_status); > } > @@ -204,7 +215,7 @@ static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status) > /* put byte in data register for sending */ > writel(byte, &twsi->data); > /* clear any pending interrupt -- that'll cause sending */ > - writel(twsi_control_flags, &twsi->control); > + writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); > /* wait for controller to receive byte and check ACK */ > return twsi_wait(adap, expected_status); > } > @@ -224,7 +235,7 @@ static int twsi_recv(struct i2c_adapter *adap, u8 *byte) > else > expected_status = MVTWSI_STATUS_DATA_R_NAK; > /* acknowledge *previous state* and launch receive */ > - writel(twsi_control_flags, &twsi->control); > + writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); > /* wait for controller to receive byte and assert ACK or NAK */ > status = twsi_wait(adap, expected_status); > /* if we did receive expected byte then store it */ > @@ -246,7 +257,7 @@ static int twsi_stop(struct i2c_adapter *adap, int status) > > /* assert STOP */ > control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP; > - writel(control, &twsi->control); > + writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); > /* wait for IDLE; IFLG won't rise so twsi_wait() is no use. */ > do { > stop_status = readl(&twsi->status); > -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-01-21 6:32 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-01-14 13:06 [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs Hans de Goede 2016-01-14 13:06 ` [U-Boot] [PATCH 2/2] sunxi: Add support for the I2C controller which is part of the PRCM Hans de Goede 2016-01-21 6:32 ` Heiko Schocher 2016-01-21 6:31 ` [U-Boot] [PATCH 1/2] i2c: mvtwsi: Fix mvtwsi not working on sun6i and newer sunxi SoCs Heiko Schocher
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox