aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-24 20:18:58 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-24 20:18:58 -0500
commita26033a1f56b7b1f8a56050c0a9095694aecae11 (patch)
tree8bb03cc2c30770f1e795ea9f7ebeceb6a6ba3fff /drivers/mfd
parent5d01410fe4d92081f349b013a2e7a95429e4f2c9 (diff)
parent8019f6962708985782b65bd97be88046a55e1e4d (diff)
Merge branch 'ib-mfd-iio-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into acpi-pmic
Pull MFD changes that the ACPI PMIC changes depend on from Lee Jones.
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig3
-rw-r--r--drivers/mfd/axp20x.c361
2 files changed, 308 insertions, 56 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 1456ea70bbc7..9af299ba711a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -74,7 +74,8 @@ config MFD_AXP20X
74 select REGMAP_IRQ 74 select REGMAP_IRQ
75 depends on I2C=y 75 depends on I2C=y
76 help 76 help
77 If you say Y here you get support for the X-Powers AXP202 and AXP209. 77 If you say Y here you get support for the X-Powers AXP202, AXP209 and
78 AXP288 power management IC (PMIC).
78 This driver include only the core APIs. You have to select individual 79 This driver include only the core APIs. You have to select individual
79 components like regulators or the PEK (Power Enable Key) under the 80 components like regulators or the PEK (Power Enable Key) under the
80 corresponding menus. 81 corresponding menus.
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 6231adbb295d..971b0eb8d821 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209 2 * axp20x.c - MFD core driver for the X-Powers' Power Management ICs
3 * 3 *
4 * AXP20x comprises an adaptive USB-Compatible PWM charger, 2 BUCK DC-DC 4 * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
5 * converters, 5 LDOs, multiple 12-bit ADCs of voltage, current and temperature 5 * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
6 * as well as 4 configurable GPIOs. 6 * as well as configurable GPIOs.
7 * 7 *
8 * Author: Carlo Caione <carlo@caione.org> 8 * Author: Carlo Caione <carlo@caione.org>
9 * 9 *
@@ -25,9 +25,16 @@
25#include <linux/mfd/core.h> 25#include <linux/mfd/core.h>
26#include <linux/of_device.h> 26#include <linux/of_device.h>
27#include <linux/of_irq.h> 27#include <linux/of_irq.h>
28#include <linux/acpi.h>
28 29
29#define AXP20X_OFF 0x80 30#define AXP20X_OFF 0x80
30 31
32static const char const *axp20x_model_names[] = {
33 "AXP202",
34 "AXP209",
35 "AXP288",
36};
37
31static const struct regmap_range axp20x_writeable_ranges[] = { 38static const struct regmap_range axp20x_writeable_ranges[] = {
32 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), 39 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
33 regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), 40 regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
@@ -47,6 +54,25 @@ static const struct regmap_access_table axp20x_volatile_table = {
47 .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), 54 .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
48}; 55};
49 56
57static const struct regmap_range axp288_writeable_ranges[] = {
58 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
59 regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
60};
61
62static const struct regmap_range axp288_volatile_ranges[] = {
63 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
64};
65
66static const struct regmap_access_table axp288_writeable_table = {
67 .yes_ranges = axp288_writeable_ranges,
68 .n_yes_ranges = ARRAY_SIZE(axp288_writeable_ranges),
69};
70
71static const struct regmap_access_table axp288_volatile_table = {
72 .yes_ranges = axp288_volatile_ranges,
73 .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges),
74};
75
50static struct resource axp20x_pek_resources[] = { 76static struct resource axp20x_pek_resources[] = {
51 { 77 {
52 .name = "PEK_DBR", 78 .name = "PEK_DBR",
@@ -61,6 +87,39 @@ static struct resource axp20x_pek_resources[] = {
61 }, 87 },
62}; 88};
63 89
90static struct resource axp288_battery_resources[] = {
91 {
92 .start = AXP288_IRQ_QWBTU,
93 .end = AXP288_IRQ_QWBTU,
94 .flags = IORESOURCE_IRQ,
95 },
96 {
97 .start = AXP288_IRQ_WBTU,
98 .end = AXP288_IRQ_WBTU,
99 .flags = IORESOURCE_IRQ,
100 },
101 {
102 .start = AXP288_IRQ_QWBTO,
103 .end = AXP288_IRQ_QWBTO,
104 .flags = IORESOURCE_IRQ,
105 },
106 {
107 .start = AXP288_IRQ_WBTO,
108 .end = AXP288_IRQ_WBTO,
109 .flags = IORESOURCE_IRQ,
110 },
111 {
112 .start = AXP288_IRQ_WL2,
113 .end = AXP288_IRQ_WL2,
114 .flags = IORESOURCE_IRQ,
115 },
116 {
117 .start = AXP288_IRQ_WL1,
118 .end = AXP288_IRQ_WL1,
119 .flags = IORESOURCE_IRQ,
120 },
121};
122
64static const struct regmap_config axp20x_regmap_config = { 123static const struct regmap_config axp20x_regmap_config = {
65 .reg_bits = 8, 124 .reg_bits = 8,
66 .val_bits = 8, 125 .val_bits = 8,
@@ -70,47 +129,96 @@ static const struct regmap_config axp20x_regmap_config = {
70 .cache_type = REGCACHE_RBTREE, 129 .cache_type = REGCACHE_RBTREE,
71}; 130};
72 131
73#define AXP20X_IRQ(_irq, _off, _mask) \ 132static const struct regmap_config axp288_regmap_config = {
74 [AXP20X_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } 133 .reg_bits = 8,
134 .val_bits = 8,
135 .wr_table = &axp288_writeable_table,
136 .volatile_table = &axp288_volatile_table,
137 .max_register = AXP288_FG_TUNE5,
138 .cache_type = REGCACHE_RBTREE,
139};
140
141#define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \
142 [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
75 143
76static const struct regmap_irq axp20x_regmap_irqs[] = { 144static const struct regmap_irq axp20x_regmap_irqs[] = {
77 AXP20X_IRQ(ACIN_OVER_V, 0, 7), 145 INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7),
78 AXP20X_IRQ(ACIN_PLUGIN, 0, 6), 146 INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6),
79 AXP20X_IRQ(ACIN_REMOVAL, 0, 5), 147 INIT_REGMAP_IRQ(AXP20X, ACIN_REMOVAL, 0, 5),
80 AXP20X_IRQ(VBUS_OVER_V, 0, 4), 148 INIT_REGMAP_IRQ(AXP20X, VBUS_OVER_V, 0, 4),
81 AXP20X_IRQ(VBUS_PLUGIN, 0, 3), 149 INIT_REGMAP_IRQ(AXP20X, VBUS_PLUGIN, 0, 3),
82 AXP20X_IRQ(VBUS_REMOVAL, 0, 2), 150 INIT_REGMAP_IRQ(AXP20X, VBUS_REMOVAL, 0, 2),
83 AXP20X_IRQ(VBUS_V_LOW, 0, 1), 151 INIT_REGMAP_IRQ(AXP20X, VBUS_V_LOW, 0, 1),
84 AXP20X_IRQ(BATT_PLUGIN, 1, 7), 152 INIT_REGMAP_IRQ(AXP20X, BATT_PLUGIN, 1, 7),
85 AXP20X_IRQ(BATT_REMOVAL, 1, 6), 153 INIT_REGMAP_IRQ(AXP20X, BATT_REMOVAL, 1, 6),
86 AXP20X_IRQ(BATT_ENT_ACT_MODE, 1, 5), 154 INIT_REGMAP_IRQ(AXP20X, BATT_ENT_ACT_MODE, 1, 5),
87 AXP20X_IRQ(BATT_EXIT_ACT_MODE, 1, 4), 155 INIT_REGMAP_IRQ(AXP20X, BATT_EXIT_ACT_MODE, 1, 4),
88 AXP20X_IRQ(CHARG, 1, 3), 156 INIT_REGMAP_IRQ(AXP20X, CHARG, 1, 3),
89 AXP20X_IRQ(CHARG_DONE, 1, 2), 157 INIT_REGMAP_IRQ(AXP20X, CHARG_DONE, 1, 2),
90 AXP20X_IRQ(BATT_TEMP_HIGH, 1, 1), 158 INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_HIGH, 1, 1),
91 AXP20X_IRQ(BATT_TEMP_LOW, 1, 0), 159 INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_LOW, 1, 0),
92 AXP20X_IRQ(DIE_TEMP_HIGH, 2, 7), 160 INIT_REGMAP_IRQ(AXP20X, DIE_TEMP_HIGH, 2, 7),
93 AXP20X_IRQ(CHARG_I_LOW, 2, 6), 161 INIT_REGMAP_IRQ(AXP20X, CHARG_I_LOW, 2, 6),
94 AXP20X_IRQ(DCDC1_V_LONG, 2, 5), 162 INIT_REGMAP_IRQ(AXP20X, DCDC1_V_LONG, 2, 5),
95 AXP20X_IRQ(DCDC2_V_LONG, 2, 4), 163 INIT_REGMAP_IRQ(AXP20X, DCDC2_V_LONG, 2, 4),
96 AXP20X_IRQ(DCDC3_V_LONG, 2, 3), 164 INIT_REGMAP_IRQ(AXP20X, DCDC3_V_LONG, 2, 3),
97 AXP20X_IRQ(PEK_SHORT, 2, 1), 165 INIT_REGMAP_IRQ(AXP20X, PEK_SHORT, 2, 1),
98 AXP20X_IRQ(PEK_LONG, 2, 0), 166 INIT_REGMAP_IRQ(AXP20X, PEK_LONG, 2, 0),
99 AXP20X_IRQ(N_OE_PWR_ON, 3, 7), 167 INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_ON, 3, 7),
100 AXP20X_IRQ(N_OE_PWR_OFF, 3, 6), 168 INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_OFF, 3, 6),
101 AXP20X_IRQ(VBUS_VALID, 3, 5), 169 INIT_REGMAP_IRQ(AXP20X, VBUS_VALID, 3, 5),
102 AXP20X_IRQ(VBUS_NOT_VALID, 3, 4), 170 INIT_REGMAP_IRQ(AXP20X, VBUS_NOT_VALID, 3, 4),
103 AXP20X_IRQ(VBUS_SESS_VALID, 3, 3), 171 INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_VALID, 3, 3),
104 AXP20X_IRQ(VBUS_SESS_END, 3, 2), 172 INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_END, 3, 2),
105 AXP20X_IRQ(LOW_PWR_LVL1, 3, 1), 173 INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL1, 3, 1),
106 AXP20X_IRQ(LOW_PWR_LVL2, 3, 0), 174 INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL2, 3, 0),
107 AXP20X_IRQ(TIMER, 4, 7), 175 INIT_REGMAP_IRQ(AXP20X, TIMER, 4, 7),
108 AXP20X_IRQ(PEK_RIS_EDGE, 4, 6), 176 INIT_REGMAP_IRQ(AXP20X, PEK_RIS_EDGE, 4, 6),
109 AXP20X_IRQ(PEK_FAL_EDGE, 4, 5), 177 INIT_REGMAP_IRQ(AXP20X, PEK_FAL_EDGE, 4, 5),
110 AXP20X_IRQ(GPIO3_INPUT, 4, 3), 178 INIT_REGMAP_IRQ(AXP20X, GPIO3_INPUT, 4, 3),
111 AXP20X_IRQ(GPIO2_INPUT, 4, 2), 179 INIT_REGMAP_IRQ(AXP20X, GPIO2_INPUT, 4, 2),
112 AXP20X_IRQ(GPIO1_INPUT, 4, 1), 180 INIT_REGMAP_IRQ(AXP20X, GPIO1_INPUT, 4, 1),
113 AXP20X_IRQ(GPIO0_INPUT, 4, 0), 181 INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0),
182};
183
184/* some IRQs are compatible with axp20x models */
185static const struct regmap_irq axp288_regmap_irqs[] = {
186 INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2),
187 INIT_REGMAP_IRQ(AXP288, VBUS_RISE, 0, 3),
188 INIT_REGMAP_IRQ(AXP288, OV, 0, 4),
189
190 INIT_REGMAP_IRQ(AXP288, DONE, 1, 2),
191 INIT_REGMAP_IRQ(AXP288, CHARGING, 1, 3),
192 INIT_REGMAP_IRQ(AXP288, SAFE_QUIT, 1, 4),
193 INIT_REGMAP_IRQ(AXP288, SAFE_ENTER, 1, 5),
194 INIT_REGMAP_IRQ(AXP288, ABSENT, 1, 6),
195 INIT_REGMAP_IRQ(AXP288, APPEND, 1, 7),
196
197 INIT_REGMAP_IRQ(AXP288, QWBTU, 2, 0),
198 INIT_REGMAP_IRQ(AXP288, WBTU, 2, 1),
199 INIT_REGMAP_IRQ(AXP288, QWBTO, 2, 2),
200 INIT_REGMAP_IRQ(AXP288, WBTO, 2, 3),
201 INIT_REGMAP_IRQ(AXP288, QCBTU, 2, 4),
202 INIT_REGMAP_IRQ(AXP288, CBTU, 2, 5),
203 INIT_REGMAP_IRQ(AXP288, QCBTO, 2, 6),
204 INIT_REGMAP_IRQ(AXP288, CBTO, 2, 7),
205
206 INIT_REGMAP_IRQ(AXP288, WL2, 3, 0),
207 INIT_REGMAP_IRQ(AXP288, WL1, 3, 1),
208 INIT_REGMAP_IRQ(AXP288, GPADC, 3, 2),
209 INIT_REGMAP_IRQ(AXP288, OT, 3, 7),
210
211 INIT_REGMAP_IRQ(AXP288, GPIO0, 4, 0),
212 INIT_REGMAP_IRQ(AXP288, GPIO1, 4, 1),
213 INIT_REGMAP_IRQ(AXP288, POKO, 4, 2),
214 INIT_REGMAP_IRQ(AXP288, POKL, 4, 3),
215 INIT_REGMAP_IRQ(AXP288, POKS, 4, 4),
216 INIT_REGMAP_IRQ(AXP288, POKN, 4, 5),
217 INIT_REGMAP_IRQ(AXP288, POKP, 4, 6),
218 INIT_REGMAP_IRQ(AXP288, TIMER, 4, 7),
219
220 INIT_REGMAP_IRQ(AXP288, MV_CHNG, 5, 0),
221 INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
114}; 222};
115 223
116static const struct of_device_id axp20x_of_match[] = { 224static const struct of_device_id axp20x_of_match[] = {
@@ -128,16 +236,39 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
128}; 236};
129MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id); 237MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
130 238
239static struct acpi_device_id axp20x_acpi_match[] = {
240 {
241 .id = "INT33F4",
242 .driver_data = AXP288_ID,
243 },
244 { },
245};
246MODULE_DEVICE_TABLE(acpi, axp20x_acpi_match);
247
131static const struct regmap_irq_chip axp20x_regmap_irq_chip = { 248static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
132 .name = "axp20x_irq_chip", 249 .name = "axp20x_irq_chip",
133 .status_base = AXP20X_IRQ1_STATE, 250 .status_base = AXP20X_IRQ1_STATE,
134 .ack_base = AXP20X_IRQ1_STATE, 251 .ack_base = AXP20X_IRQ1_STATE,
135 .mask_base = AXP20X_IRQ1_EN, 252 .mask_base = AXP20X_IRQ1_EN,
136 .num_regs = 5, 253 .mask_invert = true,
254 .init_ack_masked = true,
137 .irqs = axp20x_regmap_irqs, 255 .irqs = axp20x_regmap_irqs,
138 .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs), 256 .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs),
257 .num_regs = 5,
258
259};
260
261static const struct regmap_irq_chip axp288_regmap_irq_chip = {
262 .name = "axp288_irq_chip",
263 .status_base = AXP20X_IRQ1_STATE,
264 .ack_base = AXP20X_IRQ1_STATE,
265 .mask_base = AXP20X_IRQ1_EN,
139 .mask_invert = true, 266 .mask_invert = true,
140 .init_ack_masked = true, 267 .init_ack_masked = true,
268 .irqs = axp288_regmap_irqs,
269 .num_irqs = ARRAY_SIZE(axp288_regmap_irqs),
270 .num_regs = 6,
271
141}; 272};
142 273
143static struct mfd_cell axp20x_cells[] = { 274static struct mfd_cell axp20x_cells[] = {
@@ -150,36 +281,155 @@ static struct mfd_cell axp20x_cells[] = {
150 }, 281 },
151}; 282};
152 283
284static struct resource axp288_adc_resources[] = {
285 {
286 .name = "GPADC",
287 .start = AXP288_IRQ_GPADC,
288 .end = AXP288_IRQ_GPADC,
289 .flags = IORESOURCE_IRQ,
290 },
291};
292
293static struct resource axp288_charger_resources[] = {
294 {
295 .start = AXP288_IRQ_OV,
296 .end = AXP288_IRQ_OV,
297 .flags = IORESOURCE_IRQ,
298 },
299 {
300 .start = AXP288_IRQ_DONE,
301 .end = AXP288_IRQ_DONE,
302 .flags = IORESOURCE_IRQ,
303 },
304 {
305 .start = AXP288_IRQ_CHARGING,
306 .end = AXP288_IRQ_CHARGING,
307 .flags = IORESOURCE_IRQ,
308 },
309 {
310 .start = AXP288_IRQ_SAFE_QUIT,
311 .end = AXP288_IRQ_SAFE_QUIT,
312 .flags = IORESOURCE_IRQ,
313 },
314 {
315 .start = AXP288_IRQ_SAFE_ENTER,
316 .end = AXP288_IRQ_SAFE_ENTER,
317 .flags = IORESOURCE_IRQ,
318 },
319 {
320 .start = AXP288_IRQ_QCBTU,
321 .end = AXP288_IRQ_QCBTU,
322 .flags = IORESOURCE_IRQ,
323 },
324 {
325 .start = AXP288_IRQ_CBTU,
326 .end = AXP288_IRQ_CBTU,
327 .flags = IORESOURCE_IRQ,
328 },
329 {
330 .start = AXP288_IRQ_QCBTO,
331 .end = AXP288_IRQ_QCBTO,
332 .flags = IORESOURCE_IRQ,
333 },
334 {
335 .start = AXP288_IRQ_CBTO,
336 .end = AXP288_IRQ_CBTO,
337 .flags = IORESOURCE_IRQ,
338 },
339};
340
341static struct mfd_cell axp288_cells[] = {
342 {
343 .name = "axp288_adc",
344 .num_resources = ARRAY_SIZE(axp288_adc_resources),
345 .resources = axp288_adc_resources,
346 },
347 {
348 .name = "axp288_charger",
349 .num_resources = ARRAY_SIZE(axp288_charger_resources),
350 .resources = axp288_charger_resources,
351 },
352 {
353 .name = "axp288_battery",
354 .num_resources = ARRAY_SIZE(axp288_battery_resources),
355 .resources = axp288_battery_resources,
356 },
357};
358
153static struct axp20x_dev *axp20x_pm_power_off; 359static struct axp20x_dev *axp20x_pm_power_off;
154static void axp20x_power_off(void) 360static void axp20x_power_off(void)
155{ 361{
362 if (axp20x_pm_power_off->variant == AXP288_ID)
363 return;
364
156 regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, 365 regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
157 AXP20X_OFF); 366 AXP20X_OFF);
158} 367}
159 368
369static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
370{
371 const struct acpi_device_id *acpi_id;
372 const struct of_device_id *of_id;
373
374 if (dev->of_node) {
375 of_id = of_match_device(axp20x_of_match, dev);
376 if (!of_id) {
377 dev_err(dev, "Unable to match OF ID\n");
378 return -ENODEV;
379 }
380 axp20x->variant = (long) of_id->data;
381 } else {
382 acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
383 if (!acpi_id || !acpi_id->driver_data) {
384 dev_err(dev, "Unable to match ACPI ID and data\n");
385 return -ENODEV;
386 }
387 axp20x->variant = (long) acpi_id->driver_data;
388 }
389
390 switch (axp20x->variant) {
391 case AXP202_ID:
392 case AXP209_ID:
393 axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
394 axp20x->cells = axp20x_cells;
395 axp20x->regmap_cfg = &axp20x_regmap_config;
396 axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
397 break;
398 case AXP288_ID:
399 axp20x->cells = axp288_cells;
400 axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
401 axp20x->regmap_cfg = &axp288_regmap_config;
402 axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
403 break;
404 default:
405 dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
406 return -EINVAL;
407 }
408 dev_info(dev, "AXP20x variant %s found\n",
409 axp20x_model_names[axp20x->variant]);
410
411 return 0;
412}
413
160static int axp20x_i2c_probe(struct i2c_client *i2c, 414static int axp20x_i2c_probe(struct i2c_client *i2c,
161 const struct i2c_device_id *id) 415 const struct i2c_device_id *id)
162{ 416{
163 struct axp20x_dev *axp20x; 417 struct axp20x_dev *axp20x;
164 const struct of_device_id *of_id;
165 int ret; 418 int ret;
166 419
167 axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL); 420 axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
168 if (!axp20x) 421 if (!axp20x)
169 return -ENOMEM; 422 return -ENOMEM;
170 423
171 of_id = of_match_device(axp20x_of_match, &i2c->dev); 424 ret = axp20x_match_device(axp20x, &i2c->dev);
172 if (!of_id) { 425 if (ret)
173 dev_err(&i2c->dev, "Unable to setup AXP20X data\n"); 426 return ret;
174 return -ENODEV;
175 }
176 axp20x->variant = (long) of_id->data;
177 427
178 axp20x->i2c_client = i2c; 428 axp20x->i2c_client = i2c;
179 axp20x->dev = &i2c->dev; 429 axp20x->dev = &i2c->dev;
180 dev_set_drvdata(axp20x->dev, axp20x); 430 dev_set_drvdata(axp20x->dev, axp20x);
181 431
182 axp20x->regmap = devm_regmap_init_i2c(i2c, &axp20x_regmap_config); 432 axp20x->regmap = devm_regmap_init_i2c(i2c, axp20x->regmap_cfg);
183 if (IS_ERR(axp20x->regmap)) { 433 if (IS_ERR(axp20x->regmap)) {
184 ret = PTR_ERR(axp20x->regmap); 434 ret = PTR_ERR(axp20x->regmap);
185 dev_err(&i2c->dev, "regmap init failed: %d\n", ret); 435 dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
@@ -188,15 +438,15 @@ static int axp20x_i2c_probe(struct i2c_client *i2c,
188 438
189 ret = regmap_add_irq_chip(axp20x->regmap, i2c->irq, 439 ret = regmap_add_irq_chip(axp20x->regmap, i2c->irq,
190 IRQF_ONESHOT | IRQF_SHARED, -1, 440 IRQF_ONESHOT | IRQF_SHARED, -1,
191 &axp20x_regmap_irq_chip, 441 axp20x->regmap_irq_chip,
192 &axp20x->regmap_irqc); 442 &axp20x->regmap_irqc);
193 if (ret) { 443 if (ret) {
194 dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret); 444 dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret);
195 return ret; 445 return ret;
196 } 446 }
197 447
198 ret = mfd_add_devices(axp20x->dev, -1, axp20x_cells, 448 ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
199 ARRAY_SIZE(axp20x_cells), NULL, 0, NULL); 449 axp20x->nr_cells, NULL, 0, NULL);
200 450
201 if (ret) { 451 if (ret) {
202 dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret); 452 dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
@@ -234,6 +484,7 @@ static struct i2c_driver axp20x_i2c_driver = {
234 .name = "axp20x", 484 .name = "axp20x",
235 .owner = THIS_MODULE, 485 .owner = THIS_MODULE,
236 .of_match_table = of_match_ptr(axp20x_of_match), 486 .of_match_table = of_match_ptr(axp20x_of_match),
487 .acpi_match_table = ACPI_PTR(axp20x_acpi_match),
237 }, 488 },
238 .probe = axp20x_i2c_probe, 489 .probe = axp20x_i2c_probe,
239 .remove = axp20x_i2c_remove, 490 .remove = axp20x_i2c_remove,