diff options
author | Lesly A M <leslyam@ti.com> | 2011-04-14 08:27:53 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-05-26 13:45:24 -0400 |
commit | ca972d13382436530896e90591e2793e7a9e7eba (patch) | |
tree | 414e0e666015509a66342a8f5ce2184e0a1ef9ba /drivers/mfd/twl-core.c | |
parent | d7ac829fa30d44d6553a0ead41f47bb92ee4d73e (diff) |
mfd: TWL5030 version checking in twl-core
Added API to get the TWL5030 Si version from the IDCODE register.
It is used for enabling the workaround for TWL erratum 27.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/twl-core.c')
-rw-r--r-- | drivers/mfd/twl-core.c | 62 |
1 files changed, 62 insertions, 0 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); |