Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 349311
b: refs/heads/master
c: 0a8c290
h: refs/heads/master
i:
  349309: 7b10058
  349307: 2a97863
  349303: c89adc3
  349295: 3d0ba0a
  349279: c03da0c
  349247: 4521ace
  349183: 07a3f5b
v: v3
  • Loading branch information
Ashish Jangam authored and Samuel Ortiz committed Jan 27, 2013
1 parent a37a5aa commit 713b235
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ab4e8f8b7bdfeff0c961fdbbdacb262d68f094c0
refs/heads/master: 0a8c290ac58a86d5e1f2193abcd4d74ec075e20c
61 changes: 61 additions & 0 deletions trunk/drivers/mfd/da9052-i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,66 @@
#include <linux/of_device.h>
#endif

/* I2C safe register check */
static inline bool i2c_safe_reg(unsigned char reg)
{
switch (reg) {
case DA9052_STATUS_A_REG:
case DA9052_STATUS_B_REG:
case DA9052_STATUS_C_REG:
case DA9052_STATUS_D_REG:
case DA9052_ADC_RES_L_REG:
case DA9052_ADC_RES_H_REG:
case DA9052_VDD_RES_REG:
case DA9052_ICHG_AV_REG:
case DA9052_TBAT_RES_REG:
case DA9052_ADCIN4_RES_REG:
case DA9052_ADCIN5_RES_REG:
case DA9052_ADCIN6_RES_REG:
case DA9052_TJUNC_RES_REG:
case DA9052_TSI_X_MSB_REG:
case DA9052_TSI_Y_MSB_REG:
case DA9052_TSI_LSB_REG:
case DA9052_TSI_Z_MSB_REG:
return true;
default:
return false;
}
}

/*
* There is an issue with DA9052 and DA9053_AA/BA/BB PMIC where the PMIC
* gets lockup up or fails to respond following a system reset.
* This fix is to follow any read or write with a dummy read to a safe
* register.
*/
int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
{
int val;

switch (da9052->chip_id) {
case DA9052:
case DA9053_AA:
case DA9053_BA:
case DA9053_BB:
/* A dummy read to a safe register address. */
if (!i2c_safe_reg(reg))
return regmap_read(da9052->regmap,
DA9052_PARK_REGISTER,
&val);
break;
default:
/*
* For other chips parking of I2C register
* to a safe place is not required.
*/
break;
}

return 0;
}
EXPORT_SYMBOL(da9052_i2c_fix);

static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
{
int reg_val, ret;
Expand Down Expand Up @@ -83,6 +143,7 @@ static int da9052_i2c_probe(struct i2c_client *client,

da9052->dev = &client->dev;
da9052->chip_irq = client->irq;
da9052->fix_io = da9052_i2c_fix;

i2c_set_clientdata(client, da9052);

Expand Down
66 changes: 62 additions & 4 deletions trunk/include/linux/mfd/da9052/da9052.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ struct da9052 {
u8 chip_id;

int chip_irq;

/* SOC I/O transfer related fixes for DA9052/53 */
int (*fix_io) (struct da9052 *da9052, unsigned char reg);
};

/* ADC API */
Expand All @@ -113,32 +116,87 @@ static inline int da9052_reg_read(struct da9052 *da9052, unsigned char reg)
ret = regmap_read(da9052->regmap, reg, &val);
if (ret < 0)
return ret;

if (da9052->fix_io) {
ret = da9052->fix_io(da9052, reg);
if (ret < 0)
return ret;
}

return val;
}

static inline int da9052_reg_write(struct da9052 *da9052, unsigned char reg,
unsigned char val)
{
return regmap_write(da9052->regmap, reg, val);
int ret;

ret = regmap_write(da9052->regmap, reg, val);
if (ret < 0)
return ret;

if (da9052->fix_io) {
ret = da9052->fix_io(da9052, reg);
if (ret < 0)
return ret;
}

return ret;
}

static inline int da9052_group_read(struct da9052 *da9052, unsigned char reg,
unsigned reg_cnt, unsigned char *val)
{
return regmap_bulk_read(da9052->regmap, reg, val, reg_cnt);
int ret;

ret = regmap_bulk_read(da9052->regmap, reg, val, reg_cnt);
if (ret < 0)
return ret;

if (da9052->fix_io) {
ret = da9052->fix_io(da9052, reg);
if (ret < 0)
return ret;
}

return ret;
}

static inline int da9052_group_write(struct da9052 *da9052, unsigned char reg,
unsigned reg_cnt, unsigned char *val)
{
return regmap_raw_write(da9052->regmap, reg, val, reg_cnt);
int ret;

ret = regmap_raw_write(da9052->regmap, reg, val, reg_cnt);
if (ret < 0)
return ret;

if (da9052->fix_io) {
ret = da9052->fix_io(da9052, reg);
if (ret < 0)
return ret;
}

return ret;
}

static inline int da9052_reg_update(struct da9052 *da9052, unsigned char reg,
unsigned char bit_mask,
unsigned char reg_val)
{
return regmap_update_bits(da9052->regmap, reg, bit_mask, reg_val);
int ret;

ret = regmap_update_bits(da9052->regmap, reg, bit_mask, reg_val);
if (ret < 0)
return ret;

if (da9052->fix_io) {
ret = da9052->fix_io(da9052, reg);
if (ret < 0)
return ret;
}

return ret;
}

int da9052_device_init(struct da9052 *da9052, u8 chip_id);
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/mfd/da9052/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#define DA9052_STATUS_C_REG 3
#define DA9052_STATUS_D_REG 4

/* PARK REGISTER */
#define DA9052_PARK_REGISTER DA9052_STATUS_D_REG

/* EVENT REGISTERS */
#define DA9052_EVENT_A_REG 5
#define DA9052_EVENT_B_REG 6
Expand Down

0 comments on commit 713b235

Please sign in to comment.