dm: fsl_i2c: Make FSL I2C driver compatible with DM
Subsystems (3)
cover dm: fsl_i2c: Make FSL I2C driver compatible with DM
This patch series implements DM for the Freescale I2C driver (as used on MPC8XXX processors) and does some minor refactoring of some functions.
Mario Six (9):
dm: fsl_i2c: Rename I2C register structure
dm: fsl_i2c: Use clearer parameter names
dm: fsl_i2c: Reword and clarify comment
dm: fsl_i2c: Remove unnecessary variable
dm: fsl_i2c: Rename probe method
dm: fsl_i2c: Rename methods for reading/writing data
dm: fsl_i2c: Prepare compatibility functions
dm: fsl_i2c: Factor out adap parameter
dm: fsl_i2c: Enable DM for FSL I2C
arch/m68k/include/asm/fsl_i2c.h | 2 +- arch/powerpc/include/asm/fsl_i2c.h | 12 +- arch/powerpc/include/asm/immap_85xx.h | 4 +- arch/powerpc/include/asm/immap_86xx.h | 4 +- board/keymile/km83xx/km83xx_i2c.c | 28 +-- drivers/i2c/Kconfig | 7 + drivers/i2c/fsl_i2c.c | 379 ++++++++++++++++++++++------------ 7 files changed, 286 insertions(+), 150 deletions(-)
--
2.7.0.GIT
PATCH 1/9 dm: fsl_i2c: Rename I2C register structure
--- arch/m68k/include/asm/fsl_i2c.h | 2 +- arch/powerpc/include/asm/fsl_i2c.h | 2 +- arch/powerpc/include/asm/immap_85xx.h | 4 +- arch/powerpc/include/asm/immap_86xx.h | 4 +- board/keymile/km83xx/km83xx_i2c.c | 28 ++++---- drivers/i2c/fsl_i2c.c | 123 ++++++++++++++++++---------------- 6 files changed, 87 insertions(+), 76 deletions(-)
arch/m68k/include/asm/fsl_i2c.h +1 -1
@@ -16,7 +16,7 @@#include <asm/types.h> -typedef struct fsl_i2c { +typedef struct fsl_i2c_base { u8 adr; /* I2C slave address */ u8 res0[3];
arch/powerpc/include/asm/fsl_i2c.h +1 -1
@@ -16,7 +16,7 @@#include <asm/types.h> -typedef struct fsl_i2c { +typedef struct fsl_i2c_base { u8 adr; /* I2C slave address */ u8 res0[3];
arch/powerpc/include/asm/immap_85xx.h +2 -2
@@ -120,8 +120,8 @@ typedef struct ccsr_local_ecm {/* I2C Registers */ typedef struct ccsr_i2c { -struct fsl_i2c i2c[1 ]; -u8 res[4096 -1 *sizeof (struct fsl_i2c )]; +struct fsl_i2c_base i2c[1 ]; +u8 res[4096 -1 *sizeof (struct fsl_i2c_base )]; }ccsr_i2c_t ;#if defined(CONFIG_MPC8540 ) \
arch/powerpc/include/asm/immap_86xx.h +2 -2
@@ -92,8 +92,8 @@ typedef struct ccsr_local_mcm {/* Daul I2C Registers(0x3000-0x4000) */ typedef struct ccsr_i2c { -struct fsl_i2c i2c[2 ]; -u8 res[4096 -2 *sizeof (struct fsl_i2c )]; +struct fsl_i2c_base i2c[2 ]; +u8 res[4096 -2 *sizeof (struct fsl_i2c_base )]; }ccsr_i2c_t ;/* DUART Registers(0x4000-0x5000) */
board/keymile/km83xx/km83xx_i2c.c +15 -13
@@ -13,31 +13,33 @@static void i2c_write_start_seq (void ) { -struct fsl_i2c *dev; - dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR +CONFIG_SYS_I2C_OFFSET ); +struct fsl_i2c_base *base; + base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + +CONFIG_SYS_I2C_OFFSET );udelay (DELAY_ABORT_SEQ ); -out_8 (&dev->cr, (I2C_CR_MEN |I2C_CR_MSTA )); +out_8 (&base->cr, (I2C_CR_MEN |I2C_CR_MSTA ));udelay (DELAY_ABORT_SEQ ); -out_8 (&dev->cr, (I2C_CR_MEN )); +out_8 (&base->cr, (I2C_CR_MEN )); }int i2c_make_abort (void ) { -struct fsl_i2c *dev; - dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR +CONFIG_SYS_I2C_OFFSET ); +struct fsl_i2c_base *base; + base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + +CONFIG_SYS_I2C_OFFSET );uchar last;int nbr_read =0 ;int i =0 ;int ret =0 ;/* wait after each operation to finsh with a delay */ -out_8 (&dev->cr, (I2C_CR_MSTA )); +out_8 (&base->cr, (I2C_CR_MSTA ));udelay (DELAY_ABORT_SEQ ); -out_8 (&dev->cr, (I2C_CR_MEN |I2C_CR_MSTA )); +out_8 (&base->cr, (I2C_CR_MEN |I2C_CR_MSTA ));udelay (DELAY_ABORT_SEQ ); -in_8 (&dev->dr); +in_8 (&base->dr);udelay (DELAY_ABORT_SEQ ); - last =in_8 (&dev->dr); + last =in_8 (&base->dr); nbr_read++;/*
@@ -47,7 +49,7 @@ int i2c_make_abort(void)while (((last &0x01 ) !=0x01 ) && (nbr_read <CONFIG_SYS_IVM_EEPROM_MAX_LEN )) {udelay (DELAY_ABORT_SEQ ); - last =in_8 (&dev->dr); + last =in_8 (&base->dr); nbr_read++; }if ((last &0x01 ) !=0x01 )
@@ -56,10 +58,10 @@ int i2c_make_abort(void)printf ("[INFO] i2c abort after %d bytes (0x%02x)\n" , nbr_read, last);udelay (DELAY_ABORT_SEQ ); -out_8 (&dev->cr, (I2C_CR_MEN )); +out_8 (&base->cr, (I2C_CR_MEN ));udelay (DELAY_ABORT_SEQ );/* clear status reg */ -out_8 (&dev->sr,0 ); +out_8 (&base->sr,0 );for (i =0 ; i <5 ; i++)i2c_write_start_seq ();
drivers/i2c/fsl_i2c.c +66 -57
310 lines not on this page · raw message
Signature · 1 line
2.7.0.GIT
PATCH 2/9 dm: fsl_i2c: Use clearer parameter names
In reply to Mario Six--- drivers/i2c/fsl_i2c.c | 63 ++++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 31 deletions(-)
drivers/i2c/fsl_i2c.c +32 -31
@@ -416,24 +416,24 @@ __i2c_read(struct i2c_adapter *adap, u8 *data, int length) }static int -fsl_i2c_read (struct i2c_adapter *adap,u8 dev,uint addr,int alen,u8 *data, -int length) +fsl_i2c_read (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +u8 *data,int dlen) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr]; -int i =-1 ;/* signal error */ -u8 *a = (u8 *)&addr; -int len = alen *-1 ; +int ret =-1 ;/* signal error */ +u8 *o = (u8 *)&offset; +int len = olen *-1 ;if (i2c_wait4bus (adap) <0 )return -1 ;/* To handle the need of I2C devices that require to write few bytes * (more than 4 bytes of address as in the case of else part) -* of data before reading, Negative equivalent of length(bytes to write) +* of data before reading, Negative equivalent of dlen(bytes to write) * is passed, but used the +ve part of len for writing data */ -if (alen <0 ) { +if (olen <0 ) {/* Generate a START and send the Address and * the Tx Bytes to the slave. * "START: Address: Write bytes data[len]"
@@ -444,23 +444,24 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data,* "data", which will eventually keep the data READ, * after writing the len bytes out of it */ -if (i2c_write_addr (adap, dev,I2C_WRITE_BIT ,0 ) !=0 ) - i =__i2c_write (adap, data, len); +if (i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 ) + ret =__i2c_write (adap, data, len); -if (i != len) +if (ret != len)return -1 ; -if (length &&i2c_write_addr (adap, dev,I2C_READ_BIT ,1 ) !=0 ) - i =__i2c_read (adap, data, length); +if (dlen &&i2c_write_addr (adap, chip_addr, +I2C_READ_BIT ,1 ) !=0 ) + ret =__i2c_read (adap, data, dlen); }else { -if ((!length || alen >0 ) && -i2c_write_addr (adap, dev,I2C_WRITE_BIT ,0 ) !=0 && -__i2c_write (adap, &a[4 - alen], alen) == alen) - i =0 ;/* No error so far */ - -if (length && -i2c_write_addr (adap, dev,I2C_READ_BIT , alen ?1 :0 ) !=0 ) - i =__i2c_read (adap, data, length); +if ((!dlen || olen >0 ) && +i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && +__i2c_write (adap, &o[4 - olen], olen) == olen) + ret =0 ;/* No error so far */ + +if (dlen &&i2c_write_addr (adap, chip_addr,I2C_READ_BIT , + olen ?1 :0 ) !=0 ) + ret =__i2c_read (adap, data, dlen); }writeb (I2C_CR_MEN , &base->cr);
@@ -468,35 +469,35 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data,if (i2c_wait4bus (adap))/* Wait until STOP */ debug ("i2c_read: wait4bus timed out\n" ); -if (i == length) -return 0 ; +if (ret == dlen) +return 0 ;return -1 ; }static int -fsl_i2c_write (struct i2c_adapter *adap,u8 dev,uint addr,int alen, -u8 *data,int length) +fsl_i2c_write (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +u8 *data,int dlen) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr]; -int i =-1 ;/* signal error */ -u8 *a = (u8 *)&addr; +int ret =-1 ;/* signal error */ +u8 *o = (u8 *)&offset;if (i2c_wait4bus (adap) <0 )return -1 ; -if (i2c_write_addr (adap, dev,I2C_WRITE_BIT ,0 ) !=0 && -__i2c_write (adap, &a[4 - alen], alen) == alen) { - i =__i2c_write (adap, data, length); +if (i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && +__i2c_write (adap, &o[4 - olen], olen) == olen) { + ret =__i2c_write (adap, data, dlen); }writeb (I2C_CR_MEN , &base->cr);if (i2c_wait4bus (adap))/* Wait until STOP */ debug ("i2c_write: wait4bus timed out\n" ); -if (i == length) -return 0 ; +if (ret == dlen) +return 0 ;return -1 ; }
Signature · 1 line
2.7.0.GIT
PATCH 3/9 dm: fsl_i2c: Reword and clarify comment
In reply to Mario Six--- drivers/i2c/fsl_i2c.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-)
drivers/i2c/fsl_i2c.c +6 -14
@@ -428,22 +428,14 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,if (i2c_wait4bus (adap) <0 )return -1 ; -/* To handle the need of I2C devices that require to write few bytes -* (more than 4 bytes of address as in the case of else part) -* of data before reading, Negative equivalent of dlen(bytes to write) -* is passed, but used the +ve part of len for writing data +/* Some drivers use offset lengths in excess of 4 bytes. These drivers +* adhere to the following convention: +* - the offset length is passed as negative (that is, the absolute +* value of olen is the actual offset length) +* - the offset itself is passed in data, which is overwritten by the +* subsequent read operation */ if (olen <0 ) { -/* Generate a START and send the Address and -* the Tx Bytes to the slave. -* "START: Address: Write bytes data[len]" -* IF part supports writing any number of bytes in contrast -* to the else part, which supports writing address offset -* of upto 4 bytes only. -* bytes that need to be written are passed in -* "data", which will eventually keep the data READ, -* after writing the len bytes out of it -*/ if (i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 ) ret =__i2c_write (adap, data, len);
Signature · 1 line
2.7.0.GIT
PATCH 4/9 dm: fsl_i2c: Remove unnecessary variable
In reply to Mario Six--- drivers/i2c/fsl_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/i2c/fsl_i2c.c +2 -3
@@ -423,7 +423,6 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen, (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];int ret =-1 ;/* signal error */ u8 *o = (u8 *)&offset; -int len = olen *-1 ;if (i2c_wait4bus (adap) <0 )return -1 ;
@@ -437,9 +436,9 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,*/ if (olen < 0) { if (i2c_write_addr(adap, chip_addr, I2C_WRITE_BIT, 0) != 0) - ret = __i2c_write(adap, data, len); + ret = __i2c_write(adap, data, -olen); - if (ret != len) + if (ret != -olen) return -1; if (dlen && i2c_write_addr(adap, chip_addr,
Signature · 1 line
2.7.0.GIT
PATCH 5/9 dm: fsl_i2c: Rename probe method
In reply to Mario Six--- drivers/i2c/fsl_i2c.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/i2c/fsl_i2c.c +5 -5
@@ -494,7 +494,7 @@ fsl_i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen, }static int -fsl_i2c_probe (struct i2c_adapter *adap,uchar chip) +fsl_i2c_probe_chip (struct i2c_adapter *adap,uchar chip) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];
@@ -524,24 +524,24 @@ static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,/* * Register fsl i2c adapters */ -U_BOOT_I2C_ADAP_COMPLETE (fsl_0, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read, +U_BOOT_I2C_ADAP_COMPLETE (fsl_0, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read, fsl_i2c_write, fsl_i2c_set_bus_speed,CONFIG_SYS_FSL_I2C_SPEED ,CONFIG_SYS_FSL_I2C_SLAVE , 0)#ifdef CONFIG_SYS_FSL_I2C2_OFFSET -U_BOOT_I2C_ADAP_COMPLETE (fsl_1, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read, +U_BOOT_I2C_ADAP_COMPLETE (fsl_1, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read, fsl_i2c_write, fsl_i2c_set_bus_speed,CONFIG_SYS_FSL_I2C2_SPEED ,CONFIG_SYS_FSL_I2C2_SLAVE , 1)#endif #ifdef CONFIG_SYS_FSL_I2C3_OFFSET -U_BOOT_I2C_ADAP_COMPLETE (fsl_2, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read, +U_BOOT_I2C_ADAP_COMPLETE (fsl_2, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read, fsl_i2c_write, fsl_i2c_set_bus_speed,CONFIG_SYS_FSL_I2C3_SPEED ,CONFIG_SYS_FSL_I2C3_SLAVE , 2)#endif #ifdef CONFIG_SYS_FSL_I2C4_OFFSET -U_BOOT_I2C_ADAP_COMPLETE (fsl_3, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read, +U_BOOT_I2C_ADAP_COMPLETE (fsl_3, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read, fsl_i2c_write, fsl_i2c_set_bus_speed,CONFIG_SYS_FSL_I2C4_SPEED ,CONFIG_SYS_FSL_I2C4_SLAVE ,3 )
Signature · 1 line
2.7.0.GIT
PATCH 6/9 dm: fsl_i2c: Rename methods for reading/writing data
In reply to Mario Six--- drivers/i2c/fsl_i2c.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/i2c/fsl_i2c.c +8 -8
@@ -366,7 +366,7 @@ i2c_write_addr(struct i2c_adapter *adap, u8 dev, u8 dir, int rsta) }static __inline__int -__i2c_write (struct i2c_adapter *adap,u8 *data,int length) +__i2c_write_data (struct i2c_adapter *adap,u8 *data,int length) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];
@@ -383,7 +383,7 @@ __i2c_write(struct i2c_adapter *adap, u8 *data, int length) }static __inline__int -__i2c_read (struct i2c_adapter *adap,u8 *data,int length) +__i2c_read_data (struct i2c_adapter *adap,u8 *data,int length) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];
@@ -436,23 +436,23 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,*/ if (olen <0 ) {if (i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 ) - ret =__i2c_write (adap, data, -olen); + ret =__i2c_write_data (adap, data, -olen);if (ret != -olen)return -1 ;if (dlen &&i2c_write_addr (adap, chip_addr,I2C_READ_BIT ,1 ) !=0 ) - ret =__i2c_read (adap, data, dlen); + ret =__i2c_read_data (adap, data, dlen); }else {if ((!dlen || olen >0 ) &&i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && -__i2c_write (adap, &o[4 - olen], olen) == olen) +__i2c_write_data (adap, &o[4 - olen], olen) == olen) ret =0 ;/* No error so far */ if (dlen &&i2c_write_addr (adap, chip_addr,I2C_READ_BIT , olen ?1 :0 ) !=0 ) - ret =__i2c_read (adap, data, dlen); + ret =__i2c_read_data (adap, data, dlen); }writeb (I2C_CR_MEN , &base->cr);
@@ -479,8 +479,8 @@ fsl_i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,return -1 ;if (i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && -__i2c_write (adap, &o[4 - olen], olen) == olen) { - ret =__i2c_write (adap, data, dlen); +__i2c_write_data (adap, &o[4 - olen], olen) == olen) { + ret =__i2c_write_data (adap, data, dlen); }writeb (I2C_CR_MEN , &base->cr);
Signature · 1 line
2.7.0.GIT
PATCH 7/9 dm: fsl_i2c: Prepare compatibility functions
In reply to Mario Six--- drivers/i2c/fsl_i2c.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-)
drivers/i2c/fsl_i2c.c +39 -8
@@ -247,7 +247,7 @@ err:return ret; } -static void fsl_i2c_init (struct i2c_adapter *adap,int speed,int slaveadd) +static void __i2c_init (struct i2c_adapter *adap,int speed,int slaveadd) {const struct fsl_i2c_base *base;const unsigned long long timeout =usec2ticks (CONFIG_I2C_MBB_TIMEOUT );
@@ -416,8 +416,8 @@ __i2c_read_data(struct i2c_adapter *adap, u8 *data, int length) }static int -fsl_i2c_read (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, -u8 *data,int dlen) +__i2c_read (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +u8 *data,int dlen) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];
@@ -467,8 +467,8 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen, }static int -fsl_i2c_write (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, -u8 *data,int dlen) +__i2c_write (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +u8 *data,int dlen) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];
@@ -494,7 +494,7 @@ fsl_i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen, }static int -fsl_i2c_probe_chip (struct i2c_adapter *adap,uchar chip) +__i2c_probe_chip (struct i2c_adapter *adap,uchar chip) {struct fsl_i2c_base *base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];
@@ -505,10 +505,10 @@ fsl_i2c_probe_chip(struct i2c_adapter *adap, uchar chip)if (chip == (readb (&base->adr) >>1 ))return -1 ; -return fsl_i2c_read (adap, chip,0 ,0 ,NULL ,0 ); +return __i2c_read (adap, chip,0 ,0 ,NULL ,0 ); } -static unsigned int fsl_i2c_set_bus_speed (struct i2c_adapter *adap, +static unsigned int __i2c_set_bus_speed (struct i2c_adapter *adap,unsigned int speed) { struct fsl_i2c_base *base =
@@ -521,6 +521,37 @@ static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,return 0 ; } +static void fsl_i2c_init (struct i2c_adapter *adap,int speed,int slaveadd) +{ +__i2c_init (adap, speed, slaveadd); +} + +static int +fsl_i2c_probe_chip (struct i2c_adapter *adap,uchar chip) +{ +return __i2c_probe_chip (adap, chip); +} + +static int +fsl_i2c_read (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +u8 *data,int dlen) +{ +return __i2c_read (adap, chip_addr, offset, olen, data, dlen); +} + +static int +fsl_i2c_write (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +u8 *data,int dlen) +{ +return __i2c_write (adap, chip_addr, offset, olen, data, dlen); +} + +static unsigned int fsl_i2c_set_bus_speed (struct i2c_adapter *adap, +unsigned int speed) +{ +return __i2c_set_bus_speed (adap, speed); +} +/* * Register fsl i2c adapters */
Signature · 1 line
2.7.0.GIT
PATCH 8/9 dm: fsl_i2c: Factor out adap parameter
In reply to Mario Six--- drivers/i2c/fsl_i2c.c | 116 +++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 67 deletions(-)
drivers/i2c/fsl_i2c.c +49 -67
@@ -247,9 +247,9 @@ err:return ret; } -static void __i2c_init (struct i2c_adapter *adap,int speed,int slaveadd) +static void __i2c_init (const struct fsl_i2c_base *base,int speed,int + slaveadd,int i2c_clk,int busnum) { -const struct fsl_i2c_base *base;const unsigned long long timeout =usec2ticks (CONFIG_I2C_MBB_TIMEOUT );unsigned long long timeval;
@@ -260,11 +260,9 @@ static void __i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)*/ i2c_init_board ();#endif - base = (struct fsl_i2c_base *)i2c_base[adap->hwadapnr]; -writeb (0 , &base->cr);/* stop I2C controller */ udelay (5 );/* let it shutdown in peace */ -set_i2c_bus_speed (base,get_i2c_clock (adap->hwadapnr), speed); +set_i2c_bus_speed (base, i2c_clk, speed);writeb (slaveadd <<1 , &base->adr);/* write slave address */ writeb (0x0 , &base->sr);/* clear status register */ writeb (I2C_CR_MEN , &base->cr);/* start I2C controller */
@@ -276,7 +274,7 @@ static void __i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)if (fsl_i2c_fixup (base))debug ("i2c_init: BUS#%d failed to init\n" , - adap->hwadapnr); + busnum);break ; }
@@ -292,10 +290,8 @@ static void __i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) }static int -i2c_wait4bus (struct i2c_adapter *adap) +i2c_wait4bus (const struct fsl_i2c_base *base) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];unsigned long long timeval =get_ticks ();const unsigned long long timeout =usec2ticks (CONFIG_I2C_MBB_TIMEOUT );
@@ -307,14 +303,12 @@ i2c_wait4bus(struct i2c_adapter *adap)return 0 ; } -static __inline__int -i2c_wait (struct i2c_adapter *adap,int write) +static inline int +i2c_wait (const struct fsl_i2c_base *base,int write) {u32 csr;unsigned long long timeval =get_ticks ();const unsigned long long timeout =usec2ticks (CONFIG_I2C_TIMEOUT ); -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr]; do { csr = readb(&base->sr);
@@ -347,46 +341,39 @@ i2c_wait(struct i2c_adapter *adap, int write)return -1 ; } -static __inline__int -i2c_write_addr (struct i2c_adapter *adap,u8 dev,u8 dir,int rsta) +static inline int +i2c_write_addr (const struct fsl_i2c_base *base,u8 dev,u8 dir,int rsta) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr]; -writeb (I2C_CR_MEN |I2C_CR_MSTA |I2C_CR_MTX | (rsta ?I2C_CR_RSTA :0 ), &base->cr);writeb ((dev <<1 ) | dir, &base->dr); -if (i2c_wait (adap,I2C_WRITE_BIT ) <0 ) +if (i2c_wait (base,I2C_WRITE_BIT ) <0 )return 0 ;return 1 ; } -static __inline__int -__i2c_write_data (struct i2c_adapter *adap,u8 *data,int length) +static inline int +__i2c_write_data (const struct fsl_i2c_base *base,u8 *data,int length) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];int i;for (i =0 ; i < length; i++) {writeb (data[i], &base->dr); -if (i2c_wait (adap,I2C_WRITE_BIT ) <0 ) +if (i2c_wait (base,I2C_WRITE_BIT ) <0 )break ; }return i; } -static __inline__int -__i2c_read_data (struct i2c_adapter *adap,u8 *data,int length) +static inline int +__i2c_read_data (const struct fsl_i2c_base *base,u8 *data,int length) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];int i; writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
@@ -396,7 +383,7 @@ __i2c_read_data(struct i2c_adapter *adap, u8 *data, int length)readb (&base->dr);for (i =0 ; i < length; i++) { -if (i2c_wait (adap,I2C_READ_BIT ) <0 ) +if (i2c_wait (base,I2C_READ_BIT ) <0 )break ;/* Generate ack on last next to last byte */
@@ -416,15 +403,12 @@ __i2c_read_data(struct i2c_adapter *adap, u8 *data, int length) }static int -__i2c_read (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +__i2c_read (const struct fsl_i2c_base *base,u8 chip_addr,u8 *offset,int olen,u8 *data,int dlen) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];int ret =-1 ;/* signal error */ -u8 *o = (u8 *)&offset; -if (i2c_wait4bus (adap) <0 ) +if (i2c_wait4bus (base) <0 )return -1 ;/* Some drivers use offset lengths in excess of 4 bytes. These drivers
@@ -435,29 +419,29 @@ __i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,* subsequent read operation */ if (olen <0 ) { -if (i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 ) - ret =__i2c_write_data (adap, data, -olen); +if (i2c_write_addr (base, chip_addr,I2C_WRITE_BIT ,0 ) !=0 ) + ret =__i2c_write_data (base, data, -olen);if (ret != -olen)return -1 ; -if (dlen &&i2c_write_addr (adap, chip_addr, +if (dlen &&i2c_write_addr (base, chip_addr,I2C_READ_BIT ,1 ) !=0 ) - ret =__i2c_read_data (adap, data, dlen); + ret =__i2c_read_data (base, data, dlen); }else {if ((!dlen || olen >0 ) && -i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && -__i2c_write_data (adap, &o[4 - olen], olen) == olen) +i2c_write_addr (base, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && +__i2c_write_data (base, offset, olen) == olen) ret =0 ;/* No error so far */ -if (dlen &&i2c_write_addr (adap, chip_addr,I2C_READ_BIT , +if (dlen &&i2c_write_addr (base, chip_addr,I2C_READ_BIT , olen ?1 :0 ) !=0 ) - ret =__i2c_read_data (adap, data, dlen); + ret =__i2c_read_data (base, data, dlen); }writeb (I2C_CR_MEN , &base->cr); -if (i2c_wait4bus (adap))/* Wait until STOP */ +if (i2c_wait4bus (base))/* Wait until STOP */ debug ("i2c_read: wait4bus timed out\n" );if (ret == dlen)
@@ -467,24 +451,21 @@ __i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen, }static int -__i2c_write (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen, +__i2c_write (const struct fsl_i2c_base *base,u8 chip_addr,u8 *offset,int olen,u8 *data,int dlen) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];int ret =-1 ;/* signal error */ -u8 *o = (u8 *)&offset; -if (i2c_wait4bus (adap) <0 ) +if (i2c_wait4bus (base) <0 )return -1 ; -if (i2c_write_addr (adap, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && -__i2c_write_data (adap, &o[4 - olen], olen) == olen) { - ret =__i2c_write_data (adap, data, dlen); +if (i2c_write_addr (base, chip_addr,I2C_WRITE_BIT ,0 ) !=0 && +__i2c_write_data (base, offset, olen) == olen) { + ret =__i2c_write_data (base, data, dlen); }writeb (I2C_CR_MEN , &base->cr); -if (i2c_wait4bus (adap))/* Wait until STOP */ +if (i2c_wait4bus (base))/* Wait until STOP */ debug ("i2c_write: wait4bus timed out\n" );if (ret == dlen)
@@ -494,10 +475,8 @@ __i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen, }static int -__i2c_probe_chip (struct i2c_adapter *adap,uchar chip) +__i2c_probe_chip (const struct fsl_i2c_base *base,uchar chip) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr];/* For unknow reason the controller will ACK when * probing for a slave with the same address, so skip * it.
@@ -505,17 +484,14 @@ __i2c_probe_chip(struct i2c_adapter *adap, uchar chip)if (chip == (readb (&base->adr) >>1 ))return -1 ; -return __i2c_read (adap, chip,0 ,0 ,NULL ,0 ); +return __i2c_read (base, chip,0 ,0 ,NULL ,0 ); } -static unsigned int __i2c_set_bus_speed (struct i2c_adapter *adap, -unsigned int speed) +static unsigned int __i2c_set_bus_speed (const struct fsl_i2c_base *base, +unsigned int speed,int i2c_clk) { -struct fsl_i2c_base *base = - (struct fsl_i2c_base *)i2c_base[adap->hwadapnr]; -writeb (0 , &base->cr);/* stop controller */ -set_i2c_bus_speed (base,get_i2c_clock (adap->hwadapnr), speed); +set_i2c_bus_speed (base, i2c_clk, speed);writeb (I2C_CR_MEN , &base->cr);/* start controller */ return 0 ;
@@ -523,33 +499,39 @@ static unsigned int __i2c_set_bus_speed(struct i2c_adapter *adap,static void fsl_i2c_init (struct i2c_adapter *adap,int speed,int slaveadd) { -__i2c_init (adap, speed, slaveadd); +__i2c_init (i2c_base[adap->hwadapnr], speed, slaveadd, +get_i2c_clock (adap->hwadapnr), adap->hwadapnr); }static int fsl_i2c_probe_chip (struct i2c_adapter *adap,uchar chip) { -return __i2c_probe_chip (adap, chip); +return __i2c_probe_chip (i2c_base[adap->hwadapnr], chip); }static int fsl_i2c_read (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen,u8 *data,int dlen) { -return __i2c_read (adap, chip_addr, offset, olen, data, dlen); +u8 *o = (u8 *)&offset; +return __i2c_read (i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen], + olen, data, dlen); }static int fsl_i2c_write (struct i2c_adapter *adap,u8 chip_addr,uint offset,int olen,u8 *data,int dlen) { -return __i2c_write (adap, chip_addr, offset, olen, data, dlen); +u8 *o = (u8 *)&offset; +return __i2c_write (i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen], + olen, data, dlen); }static unsigned int fsl_i2c_set_bus_speed (struct i2c_adapter *adap,unsigned int speed) { -return __i2c_set_bus_speed (adap, speed); +return __i2c_set_bus_speed (i2c_base[adap->hwadapnr], speed, +get_i2c_clock (adap->hwadapnr)); }/*
Signature · 1 line
2.7.0.GIT
PATCH 9/9 dm: fsl_i2c: Enable DM for FSL I2C
In reply to Mario Six--- arch/powerpc/include/asm/fsl_i2c.h | 10 ++++ drivers/i2c/Kconfig | 7 +++ drivers/i2c/fsl_i2c.c | 103 +++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+)
arch/powerpc/include/asm/fsl_i2c.h +10 -0
@@ -68,4 +68,14 @@ typedef struct fsl_i2c_base { u8 res6[0xE8]; } fsl_i2c_t; +#ifdef CONFIG_DM_I2C +struct fsl_i2c_dev { +struct fsl_i2c_base __iomem *base;/* register base */ +u32 i2c_clk; +u32 index; +u8 slaveadd; +uint speed; +}; +#endif +#endif /* _ASM_I2C_H_ */
drivers/i2c/Kconfig +7 -0
@@ -58,6 +58,13 @@ config DM_I2C_GPIO bindings are supported. Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt +config SYS_I2C_FSL + bool "Freescale I2C bus driver" + depends on DM_I2C + help + Add support for Freescale I2C busses as used on MPC8240, MPC8245, and + MPC85xx processors. + config SYS_I2C_CADENCE tristate "Cadence I2C Controller" depends on DM_I2C && (ARCH_ZYNQ || ARM64)
drivers/i2c/fsl_i2c.c +103 -0
142 lines not on this page · raw message
Signature · 1 line
2.7.0.GIT
PATCH 9/9 dm: fsl_i2c: Enable DM for FSL I2C
Hi Mario,
many thanks for this patch set, very welcome.
Will check and test it here on mcf5307 inside some days,
Regards,
Angelo Dureghello
Quoted 198 lines · Mario Six
Signed-off-by Mario Six <[email protected]>--- arch/powerpc/include/asm/fsl_i2c.h | 10 ++++ drivers/i2c/Kconfig | 7 +++ drivers/i2c/fsl_i2c.c | 103 +++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+)arch/powerpc/include/asm/fsl_i2c.h +10
-0@@ -68,4 +68,14 @@ typedef struct fsl_i2c_base { u8 res6[0xE8]; } fsl_i2c_t; +#ifdef CONFIG_DM_I2C +struct fsl_i2c_dev { +struct fsl_i2c_base __iomem *base;/* register base */ +u32 i2c_clk; +u32 index; +u8 slaveadd; +uint speed; +}; +#endif +#endif /* _ASM_I2C_H_ */ drivers/i2c/Kconfig +7
-0@@ -58,6 +58,13 @@ config DM_I2C_GPIO bindings are supported. Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt +config SYS_I2C_FSL + bool "Freescale I2C bus driver" + depends on DM_I2C + help + Add support for Freescale I2C busses as used on MPC8240, MPC8245, and + MPC85xx processors. + config SYS_I2C_CADENCE tristate "Cadence I2C Controller" depends on DM_I2C && (ARCH_ZYNQ || ARM64)drivers/i2c/fsl_i2c.c +103
-0@@ -12,6 +12,8 @@#include <i2c.h> /* Functional interface */ #include <asm/io.h> #include <asm/fsl_i2c.h> /* HW definitions */ +#include <dm.h> +#include <mapmem.h> /* The maximum number of microseconds we will wait until another master has * released the bus. If not defined in the board header file, then use a @@ -34,6 +36,7 @@DECLARE_GLOBAL_DATA_PTR ; +#ifndef CONFIG_DM_I2C static const struct fsl_i2c_base *i2c_base[4 ] = { (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +CONFIG_SYS_FSL_I2C_OFFSET ), #ifdef CONFIG_SYS_FSL_I2C2_OFFSET@@ -46,6 +49,7 @@ static const struct fsl_i2c_base *i2c_base[4] = { (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +CONFIG_SYS_FSL_I2C4_OFFSET ) #endif }; +#endif /* I2C speed map for a DFSR value of 1 */ @@ -192,6 +196,7 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,return speed; } +#ifndef CONFIG_DM_I2C static unsigned int get_i2c_clock (int bus) {if (bus)@@ -199,6 +204,7 @@ static unsigned int get_i2c_clock(int bus) else return gd->arch.i2c1_clk; /* I2C1 clock */ } +#endif static int fsl_i2c_fixup (const struct fsl_i2c_base *base) {@@ -497,6 +503,7 @@ static unsigned int __i2c_set_bus_speed(const struct fsl_i2c_base *base,return 0 ; } +#ifndef CONFIG_DM_I2C static void fsl_i2c_init (struct i2c_adapter *adap,int speed,int slaveadd) { __i2c_init(i2c_base[adap->hwadapnr], speed, slaveadd,@@ -559,3 +566,99 @@ U_BOOT_I2C_ADAP_COMPLETE(fsl_3, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read, CONFIG_SYS_FSL_I2C4_SPEED, CONFIG_SYS_FSL_I2C4_SLAVE, 3)#endif +#else /* CONFIG_DM_I2C */ +static int fsl_i2c_probe_chip (struct udevice *bus,u32 chip_addr, +u32 chip_flags) +{ +struct fsl_i2c_dev *dev =dev_get_priv (bus); +return __i2c_probe_chip (dev->base, chip_addr); +} + +static int fsl_i2c_set_bus_speed (struct udevice *bus,unsigned int speed) +{ +struct fsl_i2c_dev *dev =dev_get_priv (bus); +return __i2c_set_bus_speed (dev->base, speed, dev->i2c_clk); +} + +static int fsl_i2c_ofdata_to_platdata (struct udevice *bus) +{ +struct fsl_i2c_dev *dev =dev_get_priv (bus); +u64 reg; +u32 addr, size; + + reg =fdtdec_get_addr (gd->fdt_blob, bus->of_offset,"reg" ); + addr = reg >>32 ; + size = reg &0xFFFFFFFF ; + + dev->base =map_sysmem (CONFIG_SYS_IMMR + addr, size); + +if (!dev->base) +return -ENOMEM ; + + dev->index =fdtdec_get_int (gd->fdt_blob, bus->of_offset, +"cell-index" ,-1 ); + dev->slaveadd =fdtdec_get_int (gd->fdt_blob, bus->of_offset, +"u-boot,i2c-slave-addr" ,0x7f ); + dev->speed =fdtdec_get_int (gd->fdt_blob, bus->of_offset, +"clock-frequency" ,400000 ); + + dev->i2c_clk = dev->index ? gd->arch.i2c2_clk : gd->arch.i2c1_clk; + +return 0 ; +} + +static int fsl_i2c_probe (struct udevice *bus) +{ +struct fsl_i2c_dev *dev =dev_get_priv (bus); +__i2c_init (dev->base, dev->speed, dev->slaveadd, dev->i2c_clk, + dev->index); +return 0 ; +} + +static int fsl_i2c_xfer (struct udevice *bus,struct i2c_msg *msg,int nmsgs) +{ +struct fsl_i2c_dev *dev =dev_get_priv (bus); +struct i2c_msg *dmsg, *omsg, dummy; + +memset (&dummy,0 ,sizeof (struct i2c_msg )); + +/* We expect either two messages (one with an offset and one with the +* actucal data) or one message (just data) */ +if (nmsgs >2 || nmsgs ==0 ) { +debug ("%s: Only one or two messages are supported." , __func__); +return -1 ; + } + + omsg = nmsgs ==1 ? &dummy : msg; + dmsg = nmsgs ==1 ? msg : msg +1 ; + +if (dmsg->flags &I2C_M_RD ) +return __i2c_read (dev->base, dmsg->addr, omsg->buf, omsg->len, + dmsg->buf, dmsg->len); +else +return __i2c_write (dev->base, dmsg->addr, omsg->buf, omsg->len, + dmsg->buf, dmsg->len); +} + +static const struct dm_i2c_ops fsl_i2c_ops = { + .xfer = fsl_i2c_xfer, + .probe_chip = fsl_i2c_probe_chip, + .set_bus_speed = fsl_i2c_set_bus_speed, +}; + +static const struct udevice_id fsl_i2c_ids[] = { + { .compatible ="fsl-i2c" , }, + {/* sentinel */ } +}; + +U_BOOT_DRIVER (i2c_fsl) = { + .name ="i2c_fsl" , + .id =UCLASS_I2C , + .of_match = fsl_i2c_ids, + .probe = fsl_i2c_probe, + .ofdata_to_platdata = fsl_i2c_ofdata_to_platdata, + .priv_auto_alloc_size =sizeof (struct fsl_i2c_dev ), + .ops = &fsl_i2c_ops, +}; + +#endif /* CONFIG_DM_I2C */