diff options
Diffstat (limited to 'drivers/mfd/88pm80x.c')
-rw-r--r-- | drivers/mfd/88pm80x.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c index f736a46eb8c0..5e72f65ef94c 100644 --- a/drivers/mfd/88pm80x.c +++ b/drivers/mfd/88pm80x.c | |||
@@ -18,6 +18,23 @@ | |||
18 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | 20 | ||
21 | /* 88pm80x chips have same definition for chip id register. */ | ||
22 | #define PM80X_CHIP_ID (0x00) | ||
23 | #define PM80X_CHIP_ID_NUM(x) (((x) >> 5) & 0x7) | ||
24 | #define PM80X_CHIP_ID_REVISION(x) ((x) & 0x1F) | ||
25 | |||
26 | struct pm80x_chip_mapping { | ||
27 | unsigned int id; | ||
28 | int type; | ||
29 | }; | ||
30 | |||
31 | static struct pm80x_chip_mapping chip_mapping[] = { | ||
32 | /* 88PM800 chip id number */ | ||
33 | {0x3, CHIP_PM800}, | ||
34 | /* 88PM805 chip id number */ | ||
35 | {0x0, CHIP_PM805}, | ||
36 | }; | ||
37 | |||
21 | /* | 38 | /* |
22 | * workaround: some registers needed by pm805 are defined in pm800, so | 39 | * workaround: some registers needed by pm805 are defined in pm800, so |
23 | * need to use this global variable to maintain the relation between | 40 | * need to use this global variable to maintain the relation between |
@@ -31,12 +48,13 @@ const struct regmap_config pm80x_regmap_config = { | |||
31 | }; | 48 | }; |
32 | EXPORT_SYMBOL_GPL(pm80x_regmap_config); | 49 | EXPORT_SYMBOL_GPL(pm80x_regmap_config); |
33 | 50 | ||
34 | int pm80x_init(struct i2c_client *client, | 51 | |
35 | const struct i2c_device_id *id) | 52 | int pm80x_init(struct i2c_client *client) |
36 | { | 53 | { |
37 | struct pm80x_chip *chip; | 54 | struct pm80x_chip *chip; |
38 | struct regmap *map; | 55 | struct regmap *map; |
39 | int ret = 0; | 56 | unsigned int val; |
57 | int i, ret = 0; | ||
40 | 58 | ||
41 | chip = | 59 | chip = |
42 | devm_kzalloc(&client->dev, sizeof(struct pm80x_chip), GFP_KERNEL); | 60 | devm_kzalloc(&client->dev, sizeof(struct pm80x_chip), GFP_KERNEL); |
@@ -51,10 +69,6 @@ int pm80x_init(struct i2c_client *client, | |||
51 | return ret; | 69 | return ret; |
52 | } | 70 | } |
53 | 71 | ||
54 | chip->id = id->driver_data; | ||
55 | if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805) | ||
56 | return -EINVAL; | ||
57 | |||
58 | chip->client = client; | 72 | chip->client = client; |
59 | chip->regmap = map; | 73 | chip->regmap = map; |
60 | 74 | ||
@@ -64,6 +78,25 @@ int pm80x_init(struct i2c_client *client, | |||
64 | dev_set_drvdata(chip->dev, chip); | 78 | dev_set_drvdata(chip->dev, chip); |
65 | i2c_set_clientdata(chip->client, chip); | 79 | i2c_set_clientdata(chip->client, chip); |
66 | 80 | ||
81 | ret = regmap_read(chip->regmap, PM80X_CHIP_ID, &val); | ||
82 | if (ret < 0) { | ||
83 | dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret); | ||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | for (i = 0; i < ARRAY_SIZE(chip_mapping); i++) { | ||
88 | if (chip_mapping[i].id == PM80X_CHIP_ID_NUM(val)) { | ||
89 | chip->type = chip_mapping[i].type; | ||
90 | break; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | if (i == ARRAY_SIZE(chip_mapping)) { | ||
95 | dev_err(chip->dev, | ||
96 | "Failed to detect Marvell 88PM800:ChipID[0x%x]\n", val); | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
67 | device_init_wakeup(&client->dev, 1); | 100 | device_init_wakeup(&client->dev, 1); |
68 | 101 | ||
69 | /* | 102 | /* |