@ -20,6 +20,7 @@ struct mb85rcxx_config {
@@ -20,6 +20,7 @@ struct mb85rcxx_config {
struct i2c_dt_spec i2c ;
struct gpio_dt_spec wp_gpio ;
size_t size ;
size_t pagesize ;
uint8_t addr_width ;
bool readonly ;
} ;
@ -43,16 +44,31 @@ static uint16_t mb85rcxx_translate_address(const struct device *dev, off_t offse
@@ -43,16 +44,31 @@ static uint16_t mb85rcxx_translate_address(const struct device *dev, off_t offse
{
const struct mb85rcxx_config * cfg = dev - > config ;
off_t page_offset = offset % cfg - > pagesize ;
if ( cfg - > addr_width > 8 ) {
sys_put_be16 ( offset , addr ) ;
sys_put_be16 ( page_ offset, addr ) ;
addr [ 0 ] & = BIT_MASK ( cfg - > addr_width - 8 ) ;
} else {
addr [ 0 ] = offset & BIT_MASK ( cfg - > addr_width ) ;
addr [ 0 ] = page_ offset & BIT_MASK ( cfg - > addr_width ) ;
}
return cfg - > i2c . addr + ( offset > > cfg - > addr_width ) ;
}
static size_t mb85rcxx_remaining_len_in_page ( const struct device * dev , off_t offset , size_t len )
{
const struct mb85rcxx_config * cfg = dev - > config ;
off_t page_offset = offset % cfg - > pagesize ;
size_t rem = cfg - > pagesize - page_offset ;
if ( rem > len ) {
rem = len ;
}
return rem ;
}
static int mb85rcxx_init ( const struct device * dev )
{
const struct mb85rcxx_config * cfg = dev - > config ;
@ -87,6 +103,7 @@ static int mb85rcxx_read(const struct device *dev, off_t offset, void *buf, size
@@ -87,6 +103,7 @@ static int mb85rcxx_read(const struct device *dev, off_t offset, void *buf, size
struct mb85rcxx_data * data = dev - > data ;
uint8_t addr [ 2 ] ;
uint16_t i2c_addr ;
size_t len_in_page ;
int ret ;
if ( offset + len > cfg - > size ) {
@ -94,16 +111,27 @@ static int mb85rcxx_read(const struct device *dev, off_t offset, void *buf, size
@@ -94,16 +111,27 @@ static int mb85rcxx_read(const struct device *dev, off_t offset, void *buf, size
return - EINVAL ;
}
i2c_addr = mb85rcxx_translate_address ( dev , offset , addr ) ;
k_mutex_lock ( & data - > lock , K_FOREVER ) ;
ret = i2c_write_read ( cfg - > i2c . bus , i2c_addr , addr , DIV_ROUND_UP ( cfg - > addr_width , 8 ) , buf ,
len ) ;
if ( ret < 0 ) {
LOG_ERR ( " failed to read FRAM (err %d) " , ret ) ;
while ( len ) {
i2c_addr = mb85rcxx_translate_address ( dev , offset , addr ) ;
len_in_page = mb85rcxx_remaining_len_in_page ( dev , offset , len ) ;
ret = i2c_write_read ( cfg - > i2c . bus , i2c_addr , addr , DIV_ROUND_UP ( cfg - > addr_width , 8 ) ,
buf , len_in_page ) ;
if ( ret < 0 ) {
LOG_ERR ( " failed to read FRAM (err %d) " , ret ) ;
k_mutex_unlock ( & data - > lock ) ;
return ret ;
}
len - = len_in_page ;
* ( char * ) & buf + = len_in_page ;
offset + = len_in_page ;
}
k_mutex_unlock ( & data - > lock ) ;
return ret ;
return 0 ;
}
static int mb85rcxx_i2c_write ( const struct device * dev , uint16_t i2c_addr , uint8_t * addr ,
@ -129,6 +157,7 @@ static int mb85rcxx_write(const struct device *dev, off_t offset, const void *bu
@@ -129,6 +157,7 @@ static int mb85rcxx_write(const struct device *dev, off_t offset, const void *bu
struct mb85rcxx_data * data = dev - > data ;
uint8_t addr [ 2 ] ;
uint16_t i2c_addr ;
size_t len_in_page ;
int ret ;
if ( cfg - > readonly ) {
@ -147,10 +176,24 @@ static int mb85rcxx_write(const struct device *dev, off_t offset, const void *bu
@@ -147,10 +176,24 @@ static int mb85rcxx_write(const struct device *dev, off_t offset, const void *bu
return ret ;
}
i2c_addr = mb85rcxx_translate_address ( dev , offset , addr ) ;
k_mutex_lock ( & data - > lock , K_FOREVER ) ;
ret = mb85rcxx_i2c_write ( dev , i2c_addr , addr , buf , len ) ;
while ( len ) {
i2c_addr = mb85rcxx_translate_address ( dev , offset , addr ) ;
len_in_page = mb85rcxx_remaining_len_in_page ( dev , offset , len ) ;
ret = mb85rcxx_i2c_write ( dev , i2c_addr , addr , buf , len ) ;
if ( ret < 0 ) {
LOG_ERR ( " failed to write to FRAM (err %d) " , ret ) ;
k_mutex_unlock ( & data - > lock ) ;
return ret ;
}
len - = len_in_page ;
* ( char * ) & buf + = len_in_page ;
offset + = len_in_page ;
}
k_mutex_unlock ( & data - > lock ) ;
mb85rcxx_write_protect_set ( dev , 1 ) ;
return ret ;
@ -177,6 +220,9 @@ static const struct eeprom_driver_api mb85rcxx_driver_api = {
@@ -177,6 +220,9 @@ static const struct eeprom_driver_api mb85rcxx_driver_api = {
IF_ENABLED ( DT_INST_NODE_HAS_PROP ( inst , wp_gpios ) , \
( . wp_gpio = GPIO_DT_SPEC_INST_GET ( inst , wp_gpios ) , ) ) \
. size = DT_INST_PROP ( inst , size ) , \
. pagesize = \
COND_CODE_1 ( DT_INST_NODE_HAS_PROP ( inst , pagesize ) , \
( DT_INST_PROP ( inst , pagesize ) ) , ( DT_INST_PROP ( inst , size ) ) ) , \
. addr_width = DT_INST_PROP ( inst , address_width ) , \
. readonly = DT_INST_PROP ( inst , read_only ) } ; \
\