diff options
Diffstat (limited to 'drivers/mfd/rsmu_spi.c')
| -rw-r--r-- | drivers/mfd/rsmu_spi.c | 48 | 
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/mfd/rsmu_spi.c b/drivers/mfd/rsmu_spi.c index d2f3d8f1e05a..a4a595bb8d0d 100644 --- a/drivers/mfd/rsmu_spi.c +++ b/drivers/mfd/rsmu_spi.c @@ -19,19 +19,21 @@  #define	RSMU_CM_PAGE_ADDR		0x7C  #define	RSMU_SABRE_PAGE_ADDR		0x7F -#define	RSMU_HIGHER_ADDR_MASK		0xFF80 -#define	RSMU_HIGHER_ADDR_SHIFT		7 -#define	RSMU_LOWER_ADDR_MASK		0x7F +#define	RSMU_PAGE_MASK			0xFFFFFF80 +#define	RSMU_ADDR_MASK			0x7F  static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)  {  	struct spi_device *client = to_spi_device(rsmu->dev);  	struct spi_transfer xfer = {0};  	struct spi_message msg; -	u8 cmd[256] = {0}; -	u8 rsp[256] = {0}; +	u8 cmd[RSMU_MAX_READ_COUNT + 1] = {0}; +	u8 rsp[RSMU_MAX_READ_COUNT + 1] = {0};  	int ret; +	if (bytes > RSMU_MAX_READ_COUNT) +		return -EINVAL; +  	cmd[0] = reg | 0x80;  	xfer.rx_buf = rsp;  	xfer.len = bytes + 1; @@ -66,7 +68,10 @@ static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes  	struct spi_device *client = to_spi_device(rsmu->dev);  	struct spi_transfer xfer = {0};  	struct spi_message msg; -	u8 cmd[256] = {0}; +	u8 cmd[RSMU_MAX_WRITE_COUNT + 1] = {0}; + +	if (bytes > RSMU_MAX_WRITE_COUNT) +		return -EINVAL;  	cmd[0] = reg;  	memcpy(&cmd[1], buf, bytes); @@ -86,26 +91,35 @@ static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes   * 16-bit register address: the lower 7 bits of the register address come   * from the offset addr byte and the upper 9 bits come from the page register.   */ -static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg) +static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg)  {  	u8 page_reg; -	u8 buf[2]; +	u8 buf[4];  	u16 bytes; -	u16 page; +	u32 page;  	int err;  	switch (rsmu->type) {  	case RSMU_CM: +		/* Do not modify page register for none-scsr registers */ +		if (reg < RSMU_CM_SCSR_BASE) +			return 0;  		page_reg = RSMU_CM_PAGE_ADDR; -		page = reg & RSMU_HIGHER_ADDR_MASK; +		page = reg & RSMU_PAGE_MASK;  		buf[0] = (u8)(page & 0xff);  		buf[1] = (u8)((page >> 8) & 0xff); -		bytes = 2; +		buf[2] = (u8)((page >> 16) & 0xff); +		buf[3] = (u8)((page >> 24) & 0xff); +		bytes = 4;  		break;  	case RSMU_SABRE: +		/* Do not modify page register if reg is page register itself */ +		if ((reg & RSMU_ADDR_MASK) == RSMU_ADDR_MASK) +			return 0;  		page_reg = RSMU_SABRE_PAGE_ADDR; -		page = reg >> RSMU_HIGHER_ADDR_SHIFT; -		buf[0] = (u8)(page & 0xff); +		page = reg & RSMU_PAGE_MASK; +		/* The three page bits are located in the single Page Register */ +		buf[0] = (u8)((page >> 7) & 0x7);  		bytes = 1;  		break;  	default: @@ -130,7 +144,7 @@ static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg)  static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)  {  	struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context); -	u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK); +	u8 addr = (u8)(reg & RSMU_ADDR_MASK);  	int err;  	err = rsmu_write_page_register(rsmu, reg); @@ -147,7 +161,7 @@ static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)  static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)  {  	struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context); -	u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK); +	u8 addr = (u8)(reg & RSMU_ADDR_MASK);  	u8 data = (u8)val;  	int err; @@ -164,9 +178,9 @@ static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)  }  static const struct regmap_config rsmu_cm_regmap_config = { -	.reg_bits = 16, +	.reg_bits = 32,  	.val_bits = 8, -	.max_register = 0xD000, +	.max_register = 0x20120000,  	.reg_read = rsmu_reg_read,  	.reg_write = rsmu_reg_write,  	.cache_type = REGCACHE_NONE,  |