@ -6,14 +6,14 @@
* SPDX - License - Identifier : GPL - 2.0 +
*/
# include <common.h>
# include <dm.h>
# include <linux/types.h>
# include <linux/delay.h>
# include <linux/errno.h>
# include <linux/io.h>
# include <linux/sizes.h>
# include <linux/errno .h>
# include <i2c .h>
# include <linux/types .h>
# include <dm .h>
# include <fdtdec.h>
# include <i2c.h>
struct uniphier_i2c_regs {
u32 dtrm ; /* data transmission */
@ -38,7 +38,8 @@ struct uniphier_i2c_regs {
# define IOBUS_FREQ 100000000
struct uniphier_i2c_dev {
struct uniphier_i2c_priv {
struct udevice * dev ;
struct uniphier_i2c_regs __iomem * regs ; /* register base */
unsigned long input_clk ; /* master clock (Hz) */
unsigned long wait_us ; /* wait for every byte transfer (us) */
@ -47,7 +48,7 @@ struct uniphier_i2c_dev {
static int uniphier_i2c_probe ( struct udevice * dev )
{
fdt_addr_t addr ;
struct uniphier_i2c_de v * priv = dev_get_priv ( dev ) ;
struct uniphier_i2c_pri v * priv = dev_get_priv ( dev ) ;
addr = devfdt_get_addr ( dev ) ;
if ( addr = = FDT_ADDR_T_NONE )
@ -59,15 +60,17 @@ static int uniphier_i2c_probe(struct udevice *dev)
priv - > input_clk = IOBUS_FREQ ;
priv - > dev = dev ;
/* deassert reset */
writel ( 0x3 , & priv - > regs - > brst ) ;
return 0 ;
}
static int send_and_recv_byte ( struct uniphier_i2c_dev * de v , u32 dtrm )
static int send_and_recv_byte ( struct uniphier_i2c_priv * pri v , u32 dtrm )
{
writel ( dtrm , & de v- > regs - > dtrm ) ;
writel ( dtrm , & pri v- > regs - > dtrm ) ;
/*
* This controller only provides interruption to inform the completion
@ -75,72 +78,72 @@ static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm)
* Unfortunately , U - Boot does not have a good support of interrupt .
* Wait for a while .
*/
udelay ( de v- > wait_us ) ;
udelay ( pri v- > wait_us ) ;
return readl ( & de v- > regs - > drec ) ;
return readl ( & pri v- > regs - > drec ) ;
}
static int send_byte ( struct uniphier_i2c_dev * de v , u32 dtrm , bool * stop )
static int send_byte ( struct uniphier_i2c_priv * pri v , u32 dtrm , bool * stop )
{
int ret = 0 ;
u32 drec ;
drec = send_and_recv_byte ( de v, dtrm ) ;
drec = send_and_recv_byte ( pri v, dtrm ) ;
if ( drec & I2C_DREC_LAB ) {
debu g ( " uniphier_i2c: bus arbitration failed \n " ) ;
dev_d bg ( priv - > dev , " uniphier_i2c: bus arbitration failed \n " ) ;
* stop = false ;
ret = - EREMOTEIO ;
}
if ( drec & I2C_DREC_LRB ) {
debu g ( " uniphier_i2c: slave did not return ACK \n " ) ;
dev_d bg ( priv - > dev , " uniphier_i2c: slave did not return ACK \n " ) ;
ret = - EREMOTEIO ;
}
return ret ;
}
static int uniphier_i2c_transmit ( struct uniphier_i2c_dev * de v , uint addr ,
static int uniphier_i2c_transmit ( struct uniphier_i2c_priv * pri v , uint addr ,
uint len , const u8 * buf , bool * stop )
{
int ret ;
debu g ( " %s: addr = %x, len = %d \n " , __func__ , addr , len ) ;
dev_d bg ( priv - > dev , " %s: addr = %x, len = %d \n " , __func__ , addr , len ) ;
ret = send_byte ( de v, I2C_DTRM_STA | I2C_DTRM_NACK | addr < < 1 , stop ) ;
ret = send_byte ( pri v, I2C_DTRM_STA | I2C_DTRM_NACK | addr < < 1 , stop ) ;
if ( ret < 0 )
goto fail ;
while ( len - - ) {
ret = send_byte ( de v, I2C_DTRM_NACK | * buf + + , stop ) ;
ret = send_byte ( pri v, I2C_DTRM_NACK | * buf + + , stop ) ;
if ( ret < 0 )
goto fail ;
}
fail :
if ( * stop )
writel ( I2C_DTRM_STO | I2C_DTRM_NACK , & de v- > regs - > dtrm ) ;
writel ( I2C_DTRM_STO | I2C_DTRM_NACK , & pri v- > regs - > dtrm ) ;
return ret ;
}
static int uniphier_i2c_receive ( struct uniphier_i2c_dev * de v , uint addr ,
static int uniphier_i2c_receive ( struct uniphier_i2c_priv * pri v , uint addr ,
uint len , u8 * buf , bool * stop )
{
int ret ;
debu g ( " %s: addr = %x, len = %d \n " , __func__ , addr , len ) ;
dev_d bg ( priv - > dev , " %s: addr = %x, len = %d \n " , __func__ , addr , len ) ;
ret = send_byte ( de v, I2C_DTRM_STA | I2C_DTRM_NACK |
ret = send_byte ( pri v, I2C_DTRM_STA | I2C_DTRM_NACK |
I2C_DTRM_RD | addr < < 1 , stop ) ;
if ( ret < 0 )
goto fail ;
while ( len - - )
* buf + + = send_and_recv_byte ( de v, len ? 0 : I2C_DTRM_NACK ) ;
* buf + + = send_and_recv_byte ( pri v, len ? 0 : I2C_DTRM_NACK ) ;
fail :
if ( * stop )
writel ( I2C_DTRM_STO | I2C_DTRM_NACK , & de v- > regs - > dtrm ) ;
writel ( I2C_DTRM_STO | I2C_DTRM_NACK , & pri v- > regs - > dtrm ) ;
return ret ;
}
@ -149,7 +152,7 @@ static int uniphier_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
int nmsgs )
{
int ret = 0 ;
struct uniphier_i2c_dev * de v = dev_get_priv ( bus ) ;
struct uniphier_i2c_priv * pri v = dev_get_priv ( bus ) ;
bool stop ;
for ( ; nmsgs > 0 ; nmsgs - - , msg + + ) {
@ -157,10 +160,10 @@ static int uniphier_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
stop = nmsgs > 1 & & msg [ 1 ] . flags & I2C_M_RD ? false : true ;
if ( msg - > flags & I2C_M_RD )
ret = uniphier_i2c_receive ( de v, msg - > addr , msg - > len ,
ret = uniphier_i2c_receive ( pri v, msg - > addr , msg - > len ,
msg - > buf , & stop ) ;
else
ret = uniphier_i2c_transmit ( de v, msg - > addr , msg - > len ,
ret = uniphier_i2c_transmit ( pri v, msg - > addr , msg - > len ,
msg - > buf , & stop ) ;
if ( ret < 0 )
@ -172,7 +175,7 @@ static int uniphier_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
static int uniphier_i2c_set_bus_speed ( struct udevice * bus , unsigned int speed )
{
struct uniphier_i2c_de v * priv = dev_get_priv ( bus ) ;
struct uniphier_i2c_pri v * priv = dev_get_priv ( bus ) ;
/* max supported frequency is 400 kHz */
if ( speed > 400000 )
@ -211,6 +214,6 @@ U_BOOT_DRIVER(uniphier_i2c) = {
. id = UCLASS_I2C ,
. of_match = uniphier_i2c_of_match ,
. probe = uniphier_i2c_probe ,
. priv_auto_alloc_size = sizeof ( struct uniphier_i2c_de v ) ,
. priv_auto_alloc_size = sizeof ( struct uniphier_i2c_pri v ) ,
. ops = & uniphier_i2c_ops ,
} ;