projects/linux·blob master · refs

583 lines · 18.3 KiB

1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright 2020 Google Inc
4 * Copyright 2025 Linaro Ltd.
5 *
6 * Samsung S2MPG1x ACPM driver
7 */
8
9#include <linux/array_size.h>
10#include <linux/bitops.h>
11#include <linux/device.h>
12#include <linux/firmware/samsung/exynos-acpm-protocol.h>
13#include <linux/mfd/samsung/core.h>
14#include <linux/mfd/samsung/rtc.h>
15#include <linux/mfd/samsung/s2mpg10.h>
16#include <linux/mfd/samsung/s2mpg11.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/platform_device.h>
20#include <linux/pm.h>
21#include <linux/property.h>
22#include <linux/regmap.h>
23#include "sec-core.h"
24
25#define ACPM_ADDR_BITS 8
26#define ACPM_MAX_BULK_DATA 8
27
28struct sec_pmic_acpm_platform_data {
29 int device_type;
30
31 unsigned int acpm_chan_id;
32 u8 speedy_channel;
33
34 const struct regmap_config *regmap_cfg_common;
35 const struct regmap_config *regmap_cfg_pmic;
36 const struct regmap_config *regmap_cfg_rtc;
37 const struct regmap_config *regmap_cfg_meter;
38};
39
40static const struct regmap_range s2mpg10_common_registers[] = {
41 regmap_reg_range(0x00, 0x02), /* CHIP_ID_M, INT, INT_MASK */
42 regmap_reg_range(0x0a, 0x0c), /* Speedy control */
43 regmap_reg_range(0x1a, 0x2a), /* Debug */
44};
45
46static const struct regmap_range s2mpg10_common_ro_registers[] = {
47 regmap_reg_range(0x00, 0x01), /* CHIP_ID_M, INT */
48 regmap_reg_range(0x28, 0x2a), /* Debug */
49};
50
51static const struct regmap_range s2mpg10_common_nonvolatile_registers[] = {
52 regmap_reg_range(0x00, 0x00), /* CHIP_ID_M */
53 regmap_reg_range(0x02, 0x02), /* INT_MASK */
54 regmap_reg_range(0x0a, 0x0c), /* Speedy control */
55};
56
57static const struct regmap_range s2mpg10_common_precious_registers[] = {
58 regmap_reg_range(0x01, 0x01), /* INT */
59};
60
61static const struct regmap_access_table s2mpg10_common_wr_table = {
62 .yes_ranges = s2mpg10_common_registers,
63 .n_yes_ranges = ARRAY_SIZE(s2mpg10_common_registers),
64 .no_ranges = s2mpg10_common_ro_registers,
65 .n_no_ranges = ARRAY_SIZE(s2mpg10_common_ro_registers),
66};
67
68static const struct regmap_access_table s2mpg10_common_rd_table = {
69 .yes_ranges = s2mpg10_common_registers,
70 .n_yes_ranges = ARRAY_SIZE(s2mpg10_common_registers),
71};
72
73static const struct regmap_access_table s2mpg10_common_volatile_table = {
74 .no_ranges = s2mpg10_common_nonvolatile_registers,
75 .n_no_ranges = ARRAY_SIZE(s2mpg10_common_nonvolatile_registers),
76};
77
78static const struct regmap_access_table s2mpg10_common_precious_table = {
79 .yes_ranges = s2mpg10_common_precious_registers,
80 .n_yes_ranges = ARRAY_SIZE(s2mpg10_common_precious_registers),
81};
82
83static const struct regmap_config s2mpg10_regmap_config_common = {
84 .name = "common",
85 .reg_bits = ACPM_ADDR_BITS,
86 .val_bits = 8,
87 .max_register = S2MPG10_COMMON_SPD_DEBUG4,
88 .wr_table = &s2mpg10_common_wr_table,
89 .rd_table = &s2mpg10_common_rd_table,
90 .volatile_table = &s2mpg10_common_volatile_table,
91 .precious_table = &s2mpg10_common_precious_table,
92 .num_reg_defaults_raw = S2MPG10_COMMON_SPD_DEBUG4 + 1,
93 .cache_type = REGCACHE_FLAT,
94};
95
96static const struct regmap_range s2mpg10_pmic_registers[] = {
97 regmap_reg_range(0x00, 0xf6), /* All PMIC registers */
98};
99
100static const struct regmap_range s2mpg10_pmic_ro_registers[] = {
101 regmap_reg_range(0x00, 0x05), /* INTx */
102 regmap_reg_range(0x0c, 0x0f), /* STATUSx PWRONSRC OFFSRC */
103 regmap_reg_range(0xc7, 0xc7), /* GPIO input */
104};
105
106static const struct regmap_range s2mpg10_pmic_nonvolatile_registers[] = {
107 regmap_reg_range(0x06, 0x0b), /* INTxM */
108};
109
110static const struct regmap_range s2mpg10_pmic_precious_registers[] = {
111 regmap_reg_range(0x00, 0x05), /* INTx */
112};
113
114static const struct regmap_access_table s2mpg10_pmic_wr_table = {
115 .yes_ranges = s2mpg10_pmic_registers,
116 .n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_registers),
117 .no_ranges = s2mpg10_pmic_ro_registers,
118 .n_no_ranges = ARRAY_SIZE(s2mpg10_pmic_ro_registers),
119};
120
121static const struct regmap_access_table s2mpg10_pmic_rd_table = {
122 .yes_ranges = s2mpg10_pmic_registers,
123 .n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_registers),
124};
125
126static const struct regmap_access_table s2mpg10_pmic_volatile_table = {
127 .no_ranges = s2mpg10_pmic_nonvolatile_registers,
128 .n_no_ranges = ARRAY_SIZE(s2mpg10_pmic_nonvolatile_registers),
129};
130
131static const struct regmap_access_table s2mpg10_pmic_precious_table = {
132 .yes_ranges = s2mpg10_pmic_precious_registers,
133 .n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_precious_registers),
134};
135
136static const struct regmap_config s2mpg10_regmap_config_pmic = {
137 .name = "pmic",
138 .reg_bits = ACPM_ADDR_BITS,
139 .val_bits = 8,
140 .max_register = S2MPG10_PMIC_LDO_SENSE4,
141 .wr_table = &s2mpg10_pmic_wr_table,
142 .rd_table = &s2mpg10_pmic_rd_table,
143 .volatile_table = &s2mpg10_pmic_volatile_table,
144 .precious_table = &s2mpg10_pmic_precious_table,
145 .num_reg_defaults_raw = S2MPG10_PMIC_LDO_SENSE4 + 1,
146 .cache_type = REGCACHE_FLAT,
147};
148
149static const struct regmap_range s2mpg10_rtc_registers[] = {
150 regmap_reg_range(0x00, 0x2b), /* All RTC registers */
151};
152
153static const struct regmap_range s2mpg10_rtc_volatile_registers[] = {
154 regmap_reg_range(0x01, 0x01), /* RTC_UPDATE */
155 regmap_reg_range(0x05, 0x0c), /* Time / date */
156};
157
158static const struct regmap_access_table s2mpg10_rtc_rd_table = {
159 .yes_ranges = s2mpg10_rtc_registers,
160 .n_yes_ranges = ARRAY_SIZE(s2mpg10_rtc_registers),
161};
162
163static const struct regmap_access_table s2mpg10_rtc_volatile_table = {
164 .yes_ranges = s2mpg10_rtc_volatile_registers,
165 .n_yes_ranges = ARRAY_SIZE(s2mpg10_rtc_volatile_registers),
166};
167
168static const struct regmap_config s2mpg10_regmap_config_rtc = {
169 .name = "rtc",
170 .reg_bits = ACPM_ADDR_BITS,
171 .val_bits = 8,
172 .max_register = S2MPG10_RTC_OSC_CTRL,
173 .rd_table = &s2mpg10_rtc_rd_table,
174 .volatile_table = &s2mpg10_rtc_volatile_table,
175 .num_reg_defaults_raw = S2MPG10_RTC_OSC_CTRL + 1,
176 .cache_type = REGCACHE_FLAT,
177};
178
179static const struct regmap_range s2mpg10_meter_registers[] = {
180 regmap_reg_range(0x00, 0x21), /* Meter config */
181 regmap_reg_range(0x40, 0x8a), /* Meter data */
182 regmap_reg_range(0xee, 0xee), /* Offset */
183 regmap_reg_range(0xf1, 0xf1), /* Trim */
184};
185
186static const struct regmap_range s2mpg10_meter_ro_registers[] = {
187 regmap_reg_range(0x40, 0x8a), /* Meter data */
188};
189
190static const struct regmap_access_table s2mpg10_meter_wr_table = {
191 .yes_ranges = s2mpg10_meter_registers,
192 .n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_registers),
193 .no_ranges = s2mpg10_meter_ro_registers,
194 .n_no_ranges = ARRAY_SIZE(s2mpg10_meter_ro_registers),
195};
196
197static const struct regmap_access_table s2mpg10_meter_rd_table = {
198 .yes_ranges = s2mpg10_meter_registers,
199 .n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_registers),
200};
201
202static const struct regmap_access_table s2mpg10_meter_volatile_table = {
203 .yes_ranges = s2mpg10_meter_ro_registers,
204 .n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_ro_registers),
205};
206
207static const struct regmap_config s2mpg10_regmap_config_meter = {
208 .name = "meter",
209 .reg_bits = ACPM_ADDR_BITS,
210 .val_bits = 8,
211 .max_register = S2MPG10_METER_BUCK_METER_TRIM3,
212 .wr_table = &s2mpg10_meter_wr_table,
213 .rd_table = &s2mpg10_meter_rd_table,
214 .volatile_table = &s2mpg10_meter_volatile_table,
215 .num_reg_defaults_raw = S2MPG10_METER_BUCK_METER_TRIM3 + 1,
216 .cache_type = REGCACHE_FLAT,
217};
218
219static const struct regmap_range s2mpg11_common_registers[] = {
220 regmap_reg_range(0x00, 0x02), /* CHIP_ID_S, INT, INT_MASK */
221 regmap_reg_range(0x0a, 0x0c), /* Speedy control */
222 regmap_reg_range(0x1a, 0x27), /* Debug */
223};
224
225static const struct regmap_range s2mpg11_common_ro_registers[] = {
226 regmap_reg_range(0x00, 0x01), /* CHIP_ID_S, INT */
227 regmap_reg_range(0x25, 0x27), /* Debug */
228};
229
230static const struct regmap_range s2mpg11_common_nonvolatile_registers[] = {
231 regmap_reg_range(0x00, 0x00), /* CHIP_ID_S */
232 regmap_reg_range(0x02, 0x02), /* INT_MASK */
233 regmap_reg_range(0x0a, 0x0c), /* Speedy control */
234};
235
236static const struct regmap_range s2mpg11_common_precious_registers[] = {
237 regmap_reg_range(0x01, 0x01), /* INT */
238};
239
240static const struct regmap_access_table s2mpg11_common_wr_table = {
241 .yes_ranges = s2mpg11_common_registers,
242 .n_yes_ranges = ARRAY_SIZE(s2mpg11_common_registers),
243 .no_ranges = s2mpg11_common_ro_registers,
244 .n_no_ranges = ARRAY_SIZE(s2mpg11_common_ro_registers),
245};
246
247static const struct regmap_access_table s2mpg11_common_rd_table = {
248 .yes_ranges = s2mpg11_common_registers,
249 .n_yes_ranges = ARRAY_SIZE(s2mpg11_common_registers),
250};
251
252static const struct regmap_access_table s2mpg11_common_volatile_table = {
253 .no_ranges = s2mpg11_common_nonvolatile_registers,
254 .n_no_ranges = ARRAY_SIZE(s2mpg11_common_nonvolatile_registers),
255};
256
257static const struct regmap_access_table s2mpg11_common_precious_table = {
258 .yes_ranges = s2mpg11_common_precious_registers,
259 .n_yes_ranges = ARRAY_SIZE(s2mpg11_common_precious_registers),
260};
261
262static const struct regmap_config s2mpg11_regmap_config_common = {
263 .name = "common",
264 .reg_bits = ACPM_ADDR_BITS,
265 .val_bits = 8,
266 .max_register = S2MPG11_COMMON_SPD_DEBUG4,
267 .wr_table = &s2mpg11_common_wr_table,
268 .rd_table = &s2mpg11_common_rd_table,
269 .volatile_table = &s2mpg11_common_volatile_table,
270 .precious_table = &s2mpg11_common_precious_table,
271 .num_reg_defaults_raw = S2MPG11_COMMON_SPD_DEBUG4 + 1,
272 .cache_type = REGCACHE_FLAT,
273};
274
275static const struct regmap_range s2mpg11_pmic_registers[] = {
276 regmap_reg_range(0x00, 0x5a), /* All PMIC registers */
277 regmap_reg_range(0x5c, 0xb7), /* All PMIC registers */
278};
279
280static const struct regmap_range s2mpg11_pmic_ro_registers[] = {
281 regmap_reg_range(0x00, 0x05), /* INTx */
282 regmap_reg_range(0x0c, 0x0d), /* STATUS OFFSRC */
283 regmap_reg_range(0x98, 0x98), /* GPIO input */
284};
285
286static const struct regmap_range s2mpg11_pmic_nonvolatile_registers[] = {
287 regmap_reg_range(0x06, 0x0b), /* INTxM */
288};
289
290static const struct regmap_range s2mpg11_pmic_precious_registers[] = {
291 regmap_reg_range(0x00, 0x05), /* INTx */
292};
293
294static const struct regmap_access_table s2mpg11_pmic_wr_table = {
295 .yes_ranges = s2mpg11_pmic_registers,
296 .n_yes_ranges = ARRAY_SIZE(s2mpg11_pmic_registers),
297 .no_ranges = s2mpg11_pmic_ro_registers,
298 .n_no_ranges = ARRAY_SIZE(s2mpg11_pmic_ro_registers),
299};
300
301static const struct regmap_access_table s2mpg11_pmic_rd_table = {
302 .yes_ranges = s2mpg11_pmic_registers,
303 .n_yes_ranges = ARRAY_SIZE(s2mpg11_pmic_registers),
304};
305
306static const struct regmap_access_table s2mpg11_pmic_volatile_table = {
307 .no_ranges = s2mpg11_pmic_nonvolatile_registers,
308 .n_no_ranges = ARRAY_SIZE(s2mpg11_pmic_nonvolatile_registers),
309};
310
311static const struct regmap_access_table s2mpg11_pmic_precious_table = {
312 .yes_ranges = s2mpg11_pmic_precious_registers,
313 .n_yes_ranges = ARRAY_SIZE(s2mpg11_pmic_precious_registers),
314};
315
316static const struct regmap_config s2mpg11_regmap_config_pmic = {
317 .name = "pmic",
318 .reg_bits = ACPM_ADDR_BITS,
319 .val_bits = 8,
320 .max_register = S2MPG11_PMIC_LDO_SENSE2,
321 .wr_table = &s2mpg11_pmic_wr_table,
322 .rd_table = &s2mpg11_pmic_rd_table,
323 .volatile_table = &s2mpg11_pmic_volatile_table,
324 .precious_table = &s2mpg11_pmic_precious_table,
325 .num_reg_defaults_raw = S2MPG11_PMIC_LDO_SENSE2 + 1,
326 .cache_type = REGCACHE_FLAT,
327};
328
329static const struct regmap_range s2mpg11_meter_registers[] = {
330 regmap_reg_range(0x00, 0x3e), /* Meter config */
331 regmap_reg_range(0x40, 0x8a), /* Meter data */
332 regmap_reg_range(0x8d, 0x9c), /* Meter data */
333};
334
335static const struct regmap_range s2mpg11_meter_ro_registers[] = {
336 regmap_reg_range(0x40, 0x9c), /* Meter data */
337};
338
339static const struct regmap_access_table s2mpg11_meter_wr_table = {
340 .yes_ranges = s2mpg11_meter_registers,
341 .n_yes_ranges = ARRAY_SIZE(s2mpg11_meter_registers),
342 .no_ranges = s2mpg11_meter_ro_registers,
343 .n_no_ranges = ARRAY_SIZE(s2mpg11_meter_ro_registers),
344};
345
346static const struct regmap_access_table s2mpg11_meter_rd_table = {
347 .yes_ranges = s2mpg11_meter_registers,
348 .n_yes_ranges = ARRAY_SIZE(s2mpg11_meter_registers),
349};
350
351static const struct regmap_access_table s2mpg11_meter_volatile_table = {
352 .yes_ranges = s2mpg11_meter_ro_registers,
353 .n_yes_ranges = ARRAY_SIZE(s2mpg11_meter_ro_registers),
354};
355
356static const struct regmap_config s2mpg11_regmap_config_meter = {
357 .name = "meter",
358 .reg_bits = ACPM_ADDR_BITS,
359 .val_bits = 8,
360 .max_register = S2MPG11_METER_LPF_DATA_NTC7_2,
361 .wr_table = &s2mpg11_meter_wr_table,
362 .rd_table = &s2mpg11_meter_rd_table,
363 .volatile_table = &s2mpg11_meter_volatile_table,
364 .num_reg_defaults_raw = S2MPG11_METER_LPF_DATA_NTC7_2 + 1,
365 .cache_type = REGCACHE_FLAT,
366};
367
368struct sec_pmic_acpm_shared_bus_context {
369 struct acpm_handle *acpm;
370 unsigned int acpm_chan_id;
371 u8 speedy_channel;
372};
373
374enum sec_pmic_acpm_accesstype {
375 SEC_PMIC_ACPM_ACCESSTYPE_COMMON = 0x00,
376 SEC_PMIC_ACPM_ACCESSTYPE_PMIC = 0x01,
377 SEC_PMIC_ACPM_ACCESSTYPE_RTC = 0x02,
378 SEC_PMIC_ACPM_ACCESSTYPE_METER = 0x0a,
379 SEC_PMIC_ACPM_ACCESSTYPE_WLWP = 0x0b,
380 SEC_PMIC_ACPM_ACCESSTYPE_TRIM = 0x0f,
381};
382
383struct sec_pmic_acpm_bus_context {
384 struct sec_pmic_acpm_shared_bus_context *shared;
385 enum sec_pmic_acpm_accesstype type;
386};
387
388static int sec_pmic_acpm_bus_write(void *context, const void *data,
389 size_t count)
390{
391 struct sec_pmic_acpm_bus_context *ctx = context;
392 struct acpm_handle *acpm = ctx->shared->acpm;
393 const struct acpm_pmic_ops *pmic_ops = &acpm->ops->pmic;
394 size_t val_count = count - BITS_TO_BYTES(ACPM_ADDR_BITS);
395 const u8 *d = data;
396 const u8 *vals = &d[BITS_TO_BYTES(ACPM_ADDR_BITS)];
397 u8 reg;
398
399 if (val_count < 1 || val_count > ACPM_MAX_BULK_DATA)
400 return -EINVAL;
401
402 reg = d[0];
403
404 return pmic_ops->bulk_write(acpm, ctx->shared->acpm_chan_id, ctx->type, reg,
405 ctx->shared->speedy_channel, val_count, vals);
406}
407
408static int sec_pmic_acpm_bus_read(void *context, const void *reg_buf, size_t reg_size,
409 void *val_buf, size_t val_size)
410{
411 struct sec_pmic_acpm_bus_context *ctx = context;
412 struct acpm_handle *acpm = ctx->shared->acpm;
413 const struct acpm_pmic_ops *pmic_ops = &acpm->ops->pmic;
414 const u8 *r = reg_buf;
415 u8 reg;
416
417 if (reg_size != BITS_TO_BYTES(ACPM_ADDR_BITS) || !val_size ||
418 val_size > ACPM_MAX_BULK_DATA)
419 return -EINVAL;
420
421 reg = r[0];
422
423 return pmic_ops->bulk_read(acpm, ctx->shared->acpm_chan_id, ctx->type, reg,
424 ctx->shared->speedy_channel, val_size, val_buf);
425}
426
427static int sec_pmic_acpm_bus_reg_update_bits(void *context, unsigned int reg, unsigned int mask,
428 unsigned int val)
429{
430 struct sec_pmic_acpm_bus_context *ctx = context;
431 struct acpm_handle *acpm = ctx->shared->acpm;
432 const struct acpm_pmic_ops *pmic_ops = &acpm->ops->pmic;
433
434 return pmic_ops->update_reg(acpm, ctx->shared->acpm_chan_id, ctx->type, reg & 0xff,
435 ctx->shared->speedy_channel, val, mask);
436}
437
438static const struct regmap_bus sec_pmic_acpm_regmap_bus = {
439 .write = sec_pmic_acpm_bus_write,
440 .read = sec_pmic_acpm_bus_read,
441 .reg_update_bits = sec_pmic_acpm_bus_reg_update_bits,
442 .max_raw_read = ACPM_MAX_BULK_DATA,
443 .max_raw_write = ACPM_MAX_BULK_DATA,
444};
445
446static struct regmap *sec_pmic_acpm_regmap_init(struct device *dev,
447 struct sec_pmic_acpm_shared_bus_context *shared_ctx,
448 enum sec_pmic_acpm_accesstype type,
449 const struct regmap_config *cfg, bool do_attach)
450{
451 struct sec_pmic_acpm_bus_context *ctx;
452 struct regmap *regmap;
453
454 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
455 if (!ctx)
456 return ERR_PTR(-ENOMEM);
457
458 ctx->shared = shared_ctx;
459 ctx->type = type;
460
461 regmap = devm_regmap_init(dev, &sec_pmic_acpm_regmap_bus, ctx, cfg);
462 if (IS_ERR(regmap))
463 return dev_err_cast_probe(dev, regmap, "regmap init (%s) failed\n", cfg->name);
464
465 if (do_attach) {
466 int ret;
467
468 ret = regmap_attach_dev(dev, regmap, cfg);
469 if (ret)
470 return dev_err_ptr_probe(dev, ret, "regmap attach (%s) failed\n",
471 cfg->name);
472 }
473
474 return regmap;
475}
476
477static int sec_pmic_acpm_probe(struct platform_device *pdev)
478{
479 struct regmap *regmap_common, *regmap_pmic, *regmap;
480 const struct sec_pmic_acpm_platform_data *pdata;
481 struct sec_pmic_acpm_shared_bus_context *shared_ctx;
482 struct acpm_handle *acpm;
483 struct device *dev = &pdev->dev;
484 int ret, irq;
485
486 pdata = device_get_match_data(dev);
487 if (!pdata)
488 return dev_err_probe(dev, -ENODEV, "unsupported device type\n");
489
490 acpm = devm_acpm_get_by_node(dev, dev->parent->of_node);
491 if (IS_ERR(acpm))
492 return dev_err_probe(dev, PTR_ERR(acpm), "failed to get acpm\n");
493
494 irq = platform_get_irq(pdev, 0);
495 if (irq < 0)
496 return irq;
497
498 shared_ctx = devm_kzalloc(dev, sizeof(*shared_ctx), GFP_KERNEL);
499 if (!shared_ctx)
500 return -ENOMEM;
501
502 shared_ctx->acpm = acpm;
503 shared_ctx->acpm_chan_id = pdata->acpm_chan_id;
504 shared_ctx->speedy_channel = pdata->speedy_channel;
505
506 regmap_common = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_COMMON,
507 pdata->regmap_cfg_common, true);
508 if (IS_ERR(regmap_common))
509 return PTR_ERR(regmap_common);
510
511 regmap_pmic = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_PMIC,
512 pdata->regmap_cfg_pmic, false);
513 if (IS_ERR(regmap_pmic))
514 return PTR_ERR(regmap_pmic);
515
516 if (pdata->regmap_cfg_rtc) {
517 regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_RTC,
518 pdata->regmap_cfg_rtc, true);
519 if (IS_ERR(regmap))
520 return PTR_ERR(regmap);
521 }
522
523 regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_METER,
524 pdata->regmap_cfg_meter, true);
525 if (IS_ERR(regmap))
526 return PTR_ERR(regmap);
527
528 ret = sec_pmic_probe(dev, pdata->device_type, irq, regmap_pmic, NULL);
529 if (ret)
530 return ret;
531
532 if (device_property_read_bool(dev, "wakeup-source"))
533 devm_device_init_wakeup(dev);
534
535 return 0;
536}
537
538static void sec_pmic_acpm_shutdown(struct platform_device *pdev)
539{
540 sec_pmic_shutdown(&pdev->dev);
541}
542
543static const struct sec_pmic_acpm_platform_data s2mpg10_data = {
544 .device_type = S2MPG10,
545 .acpm_chan_id = 2,
546 .speedy_channel = 0,
547 .regmap_cfg_common = &s2mpg10_regmap_config_common,
548 .regmap_cfg_pmic = &s2mpg10_regmap_config_pmic,
549 .regmap_cfg_rtc = &s2mpg10_regmap_config_rtc,
550 .regmap_cfg_meter = &s2mpg10_regmap_config_meter,
551};
552
553static const struct sec_pmic_acpm_platform_data s2mpg11_data = {
554 .device_type = S2MPG11,
555 .acpm_chan_id = 2,
556 .speedy_channel = 1,
557 .regmap_cfg_common = &s2mpg11_regmap_config_common,
558 .regmap_cfg_pmic = &s2mpg11_regmap_config_pmic,
559 .regmap_cfg_meter = &s2mpg11_regmap_config_meter,
560};
561
562static const struct of_device_id sec_pmic_acpm_of_match[] = {
563 { .compatible = "samsung,s2mpg10-pmic", .data = &s2mpg10_data, },
564 { .compatible = "samsung,s2mpg11-pmic", .data = &s2mpg11_data, },
565 { },
566};
567MODULE_DEVICE_TABLE(of, sec_pmic_acpm_of_match);
568
569static struct platform_driver sec_pmic_acpm_driver = {
570 .driver = {
571 .name = "sec-pmic-acpm",
572 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
573 .pm = pm_sleep_ptr(&sec_pmic_pm_ops),
574 .of_match_table = sec_pmic_acpm_of_match,
575 },
576 .probe = sec_pmic_acpm_probe,
577 .shutdown = sec_pmic_acpm_shutdown,
578};
579module_platform_driver(sec_pmic_acpm_driver);
580
581MODULE_AUTHOR("André Draszik <[email protected]>");
582MODULE_DESCRIPTION("ACPM driver for the Samsung S2MPG1x");
583MODULE_LICENSE("GPL");