diff options
-rw-r--r-- | drivers/mfd/twl-core.c | 62 | ||||
-rw-r--r-- | include/linux/i2c/twl.h | 17 |
2 files changed, 78 insertions, 1 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 960b5bed7f52..2bd9e0676bc2 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -229,6 +229,9 @@ | |||
229 | /* is driver active, bound to a chip? */ | 229 | /* is driver active, bound to a chip? */ |
230 | static bool inuse; | 230 | static bool inuse; |
231 | 231 | ||
232 | /* TWL IDCODE Register value */ | ||
233 | static u32 twl_idcode; | ||
234 | |||
232 | static unsigned int twl_id; | 235 | static unsigned int twl_id; |
233 | unsigned int twl_rev(void) | 236 | unsigned int twl_rev(void) |
234 | { | 237 | { |
@@ -487,6 +490,58 @@ EXPORT_SYMBOL(twl_i2c_read_u8); | |||
487 | 490 | ||
488 | /*----------------------------------------------------------------------*/ | 491 | /*----------------------------------------------------------------------*/ |
489 | 492 | ||
493 | /** | ||
494 | * twl_read_idcode_register - API to read the IDCODE register. | ||
495 | * | ||
496 | * Unlocks the IDCODE register and read the 32 bit value. | ||
497 | */ | ||
498 | static int twl_read_idcode_register(void) | ||
499 | { | ||
500 | int err; | ||
501 | |||
502 | err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK, | ||
503 | REG_UNLOCK_TEST_REG); | ||
504 | if (err) { | ||
505 | pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n", err); | ||
506 | goto fail; | ||
507 | } | ||
508 | |||
509 | err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode), | ||
510 | REG_IDCODE_7_0, 4); | ||
511 | if (err) { | ||
512 | pr_err("TWL4030: unable to read IDCODE -%d\n", err); | ||
513 | goto fail; | ||
514 | } | ||
515 | |||
516 | err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, REG_UNLOCK_TEST_REG); | ||
517 | if (err) | ||
518 | pr_err("TWL4030 Unable to relock IDCODE registers -%d\n", err); | ||
519 | fail: | ||
520 | return err; | ||
521 | } | ||
522 | |||
523 | /** | ||
524 | * twl_get_type - API to get TWL Si type. | ||
525 | * | ||
526 | * Api to get the TWL Si type from IDCODE value. | ||
527 | */ | ||
528 | int twl_get_type(void) | ||
529 | { | ||
530 | return TWL_SIL_TYPE(twl_idcode); | ||
531 | } | ||
532 | EXPORT_SYMBOL_GPL(twl_get_type); | ||
533 | |||
534 | /** | ||
535 | * twl_get_version - API to get TWL Si version. | ||
536 | * | ||
537 | * Api to get the TWL Si version from IDCODE value. | ||
538 | */ | ||
539 | int twl_get_version(void) | ||
540 | { | ||
541 | return TWL_SIL_REV(twl_idcode); | ||
542 | } | ||
543 | EXPORT_SYMBOL_GPL(twl_get_version); | ||
544 | |||
490 | static struct device * | 545 | static struct device * |
491 | add_numbered_child(unsigned chip, const char *name, int num, | 546 | add_numbered_child(unsigned chip, const char *name, int num, |
492 | void *pdata, unsigned pdata_len, | 547 | void *pdata, unsigned pdata_len, |
@@ -1014,6 +1069,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1014 | unsigned i; | 1069 | unsigned i; |
1015 | struct twl4030_platform_data *pdata = client->dev.platform_data; | 1070 | struct twl4030_platform_data *pdata = client->dev.platform_data; |
1016 | u8 temp; | 1071 | u8 temp; |
1072 | int ret = 0; | ||
1017 | 1073 | ||
1018 | if (!pdata) { | 1074 | if (!pdata) { |
1019 | dev_dbg(&client->dev, "no platform data?\n"); | 1075 | dev_dbg(&client->dev, "no platform data?\n"); |
@@ -1060,6 +1116,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1060 | /* setup clock framework */ | 1116 | /* setup clock framework */ |
1061 | clocks_init(&client->dev, pdata->clock); | 1117 | clocks_init(&client->dev, pdata->clock); |
1062 | 1118 | ||
1119 | /* read TWL IDCODE Register */ | ||
1120 | if (twl_id == TWL4030_CLASS_ID) { | ||
1121 | ret = twl_read_idcode_register(); | ||
1122 | WARN(ret < 0, "Error: reading twl_idcode register value\n"); | ||
1123 | } | ||
1124 | |||
1063 | /* load power event scripts */ | 1125 | /* load power event scripts */ |
1064 | if (twl_has_power() && pdata->power) | 1126 | if (twl_has_power() && pdata->power) |
1065 | twl4030_power_init(pdata->power); | 1127 | twl4030_power_init(pdata->power); |
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 4ebd7c32bc59..314218e79c4a 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h | |||
@@ -150,7 +150,12 @@ | |||
150 | #define MMC_PU (0x1 << 3) | 150 | #define MMC_PU (0x1 << 3) |
151 | #define MMC_PD (0x1 << 2) | 151 | #define MMC_PD (0x1 << 2) |
152 | 152 | ||
153 | 153 | #define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF) | |
154 | #define TWL_SIL_REV(rev) ((rev) >> 24) | ||
155 | #define TWL_SIL_5030 0x09002F | ||
156 | #define TWL5030_REV_1_0 0x00 | ||
157 | #define TWL5030_REV_1_1 0x10 | ||
158 | #define TWL5030_REV_1_2 0x30 | ||
154 | 159 | ||
155 | #define TWL4030_CLASS_ID 0x4030 | 160 | #define TWL4030_CLASS_ID 0x4030 |
156 | #define TWL6030_CLASS_ID 0x6030 | 161 | #define TWL6030_CLASS_ID 0x6030 |
@@ -180,6 +185,9 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); | |||
180 | int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); | 185 | int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); |
181 | int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); | 186 | int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); |
182 | 187 | ||
188 | int twl_get_type(void); | ||
189 | int twl_get_version(void); | ||
190 | |||
183 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); | 191 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); |
184 | int twl6030_interrupt_mask(u8 bit_mask, u8 offset); | 192 | int twl6030_interrupt_mask(u8 bit_mask, u8 offset); |
185 | 193 | ||
@@ -279,7 +287,12 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) | |||
279 | *(Use TWL_4030_MODULE_INTBR) | 287 | *(Use TWL_4030_MODULE_INTBR) |
280 | */ | 288 | */ |
281 | 289 | ||
290 | #define REG_IDCODE_7_0 0x00 | ||
291 | #define REG_IDCODE_15_8 0x01 | ||
292 | #define REG_IDCODE_16_23 0x02 | ||
293 | #define REG_IDCODE_31_24 0x03 | ||
282 | #define REG_GPPUPDCTR1 0x0F | 294 | #define REG_GPPUPDCTR1 0x0F |
295 | #define REG_UNLOCK_TEST_REG 0x12 | ||
283 | 296 | ||
284 | /*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */ | 297 | /*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */ |
285 | 298 | ||
@@ -288,6 +301,8 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) | |||
288 | #define SR_I2C_SCL_CTRL_PU BIT(4) | 301 | #define SR_I2C_SCL_CTRL_PU BIT(4) |
289 | #define SR_I2C_SDA_CTRL_PU BIT(6) | 302 | #define SR_I2C_SDA_CTRL_PU BIT(6) |
290 | 303 | ||
304 | #define TWL_EEPROM_R_UNLOCK 0x49 | ||
305 | |||
291 | /*----------------------------------------------------------------------*/ | 306 | /*----------------------------------------------------------------------*/ |
292 | 307 | ||
293 | /* | 308 | /* |