1 // SPDX-License-Identifier: GPL-2.0-only
3 * MFD core driver for Rockchip RK808/RK818
5 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
7 * Author: Chris Zhong <zyw@rock-chips.com>
8 * Author: Zhang Qing <zhangqing@rock-chips.com>
10 * Copyright (C) 2016 PHYTEC Messtechnik GmbH
12 * Author: Wadim Egorov <w.egorov@phytec.de>
15 #include <linux/i2c.h>
16 #include <linux/interrupt.h>
17 #include <linux/mfd/rk808.h>
18 #include <linux/mfd/core.h>
19 #include <linux/module.h>
20 #include <linux/of_device.h>
21 #include <linux/regmap.h>
22 #include <linux/syscore_ops.h>
24 struct rk808_reg_data
{
30 static bool rk808_is_volatile_reg(struct device
*dev
, unsigned int reg
)
34 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
35 * we don't use that feature. It's better to cache.
36 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
37 * bits are cleared in case when we shutoff anyway, but better safe.
41 case RK808_SECONDS_REG
... RK808_WEEKS_REG
:
42 case RK808_RTC_STATUS_REG
:
43 case RK808_VB_MON_REG
:
44 case RK808_THERMAL_REG
:
45 case RK808_DCDC_UV_STS_REG
:
46 case RK808_LDO_UV_STS_REG
:
47 case RK808_DCDC_PG_REG
:
48 case RK808_LDO_PG_REG
:
49 case RK808_DEVCTRL_REG
:
50 case RK808_INT_STS_REG1
:
51 case RK808_INT_STS_REG2
:
58 static bool rk817_is_volatile_reg(struct device
*dev
, unsigned int reg
)
62 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
63 * we don't use that feature. It's better to cache.
67 case RK817_SECONDS_REG
... RK817_WEEKS_REG
:
68 case RK817_RTC_STATUS_REG
:
69 case RK817_INT_STS_REG0
:
70 case RK817_INT_STS_REG1
:
71 case RK817_INT_STS_REG2
:
79 static const struct regmap_config rk818_regmap_config
= {
82 .max_register
= RK818_USB_CTRL_REG
,
83 .cache_type
= REGCACHE_RBTREE
,
84 .volatile_reg
= rk808_is_volatile_reg
,
87 static const struct regmap_config rk805_regmap_config
= {
90 .max_register
= RK805_OFF_SOURCE_REG
,
91 .cache_type
= REGCACHE_RBTREE
,
92 .volatile_reg
= rk808_is_volatile_reg
,
95 static const struct regmap_config rk808_regmap_config
= {
98 .max_register
= RK808_IO_POL_REG
,
99 .cache_type
= REGCACHE_RBTREE
,
100 .volatile_reg
= rk808_is_volatile_reg
,
103 static const struct regmap_config rk817_regmap_config
= {
106 .max_register
= RK817_GPIO_INT_CFG
,
107 .cache_type
= REGCACHE_NONE
,
108 .volatile_reg
= rk817_is_volatile_reg
,
111 static struct resource rtc_resources
[] = {
113 .start
= RK808_IRQ_RTC_ALARM
,
114 .end
= RK808_IRQ_RTC_ALARM
,
115 .flags
= IORESOURCE_IRQ
,
119 static struct resource rk817_rtc_resources
[] = {
120 DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM
),
123 static struct resource rk805_key_resources
[] = {
125 .start
= RK805_IRQ_PWRON_FALL
,
126 .end
= RK805_IRQ_PWRON_FALL
,
127 .flags
= IORESOURCE_IRQ
,
130 .start
= RK805_IRQ_PWRON_RISE
,
131 .end
= RK805_IRQ_PWRON_RISE
,
132 .flags
= IORESOURCE_IRQ
,
136 static struct resource rk817_pwrkey_resources
[] = {
137 DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE
),
138 DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL
),
141 static const struct mfd_cell rk805s
[] = {
142 { .name
= "rk808-clkout", },
143 { .name
= "rk808-regulator", },
144 { .name
= "rk805-pinctrl", },
147 .num_resources
= ARRAY_SIZE(rtc_resources
),
148 .resources
= &rtc_resources
[0],
150 { .name
= "rk805-pwrkey",
151 .num_resources
= ARRAY_SIZE(rk805_key_resources
),
152 .resources
= &rk805_key_resources
[0],
156 static const struct mfd_cell rk808s
[] = {
157 { .name
= "rk808-clkout", },
158 { .name
= "rk808-regulator", },
161 .num_resources
= ARRAY_SIZE(rtc_resources
),
162 .resources
= rtc_resources
,
166 static const struct mfd_cell rk817s
[] = {
167 { .name
= "rk808-clkout",},
168 { .name
= "rk808-regulator",},
170 .name
= "rk8xx-pwrkey",
171 .num_resources
= ARRAY_SIZE(rk817_pwrkey_resources
),
172 .resources
= &rk817_pwrkey_resources
[0],
176 .num_resources
= ARRAY_SIZE(rk817_rtc_resources
),
177 .resources
= &rk817_rtc_resources
[0],
181 static const struct mfd_cell rk818s
[] = {
182 { .name
= "rk808-clkout", },
183 { .name
= "rk808-regulator", },
186 .num_resources
= ARRAY_SIZE(rtc_resources
),
187 .resources
= rtc_resources
,
191 static const struct rk808_reg_data rk805_pre_init_reg
[] = {
192 {RK805_BUCK1_CONFIG_REG
, RK805_BUCK1_2_ILMAX_MASK
,
193 RK805_BUCK1_2_ILMAX_4000MA
},
194 {RK805_BUCK2_CONFIG_REG
, RK805_BUCK1_2_ILMAX_MASK
,
195 RK805_BUCK1_2_ILMAX_4000MA
},
196 {RK805_BUCK3_CONFIG_REG
, RK805_BUCK3_4_ILMAX_MASK
,
197 RK805_BUCK3_ILMAX_3000MA
},
198 {RK805_BUCK4_CONFIG_REG
, RK805_BUCK3_4_ILMAX_MASK
,
199 RK805_BUCK4_ILMAX_3500MA
},
200 {RK805_BUCK4_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_400MA
},
201 {RK805_GPIO_IO_POL_REG
, SLP_SD_MSK
, SLEEP_FUN
},
202 {RK805_THERMAL_REG
, TEMP_HOTDIE_MSK
, TEMP115C
},
205 static const struct rk808_reg_data rk808_pre_init_reg
[] = {
206 { RK808_BUCK3_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_150MA
},
207 { RK808_BUCK4_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_200MA
},
208 { RK808_BOOST_CONFIG_REG
, BOOST_ILMIN_MASK
, BOOST_ILMIN_100MA
},
209 { RK808_BUCK1_CONFIG_REG
, BUCK1_RATE_MASK
, BUCK_ILMIN_200MA
},
210 { RK808_BUCK2_CONFIG_REG
, BUCK2_RATE_MASK
, BUCK_ILMIN_200MA
},
211 { RK808_DCDC_UV_ACT_REG
, BUCK_UV_ACT_MASK
, BUCK_UV_ACT_DISABLE
},
212 { RK808_VB_MON_REG
, MASK_ALL
, VB_LO_ACT
|
216 static const struct rk808_reg_data rk817_pre_init_reg
[] = {
217 {RK817_RTC_CTRL_REG
, RTC_STOP
, RTC_STOP
},
218 {RK817_GPIO_INT_CFG
, RK817_INT_POL_MSK
, RK817_INT_POL_H
},
219 {RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK
| RK817_TSD_TEMP_MSK
,
220 RK817_HOTDIE_105
| RK817_TSD_140
},
223 static const struct rk808_reg_data rk818_pre_init_reg
[] = {
224 /* improve efficiency */
225 { RK818_BUCK2_CONFIG_REG
, BUCK2_RATE_MASK
, BUCK_ILMIN_250MA
},
226 { RK818_BUCK4_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_250MA
},
227 { RK818_BOOST_CONFIG_REG
, BOOST_ILMIN_MASK
, BOOST_ILMIN_100MA
},
228 { RK818_USB_CTRL_REG
, RK818_USB_ILIM_SEL_MASK
,
229 RK818_USB_ILMIN_2000MA
},
230 /* close charger when usb lower then 3.4V */
231 { RK818_USB_CTRL_REG
, RK818_USB_CHG_SD_VSEL_MASK
,
233 /* no action when vref */
234 { RK818_H5V_EN_REG
, BIT(1), RK818_REF_RDY_CTRL
},
236 { RK818_H5V_EN_REG
, BIT(0), RK818_H5V_EN
},
237 { RK808_VB_MON_REG
, MASK_ALL
, VB_LO_ACT
|
241 static const struct regmap_irq rk805_irqs
[] = {
242 [RK805_IRQ_PWRON_RISE
] = {
243 .mask
= RK805_IRQ_PWRON_RISE_MSK
,
246 [RK805_IRQ_VB_LOW
] = {
247 .mask
= RK805_IRQ_VB_LOW_MSK
,
250 [RK805_IRQ_PWRON
] = {
251 .mask
= RK805_IRQ_PWRON_MSK
,
254 [RK805_IRQ_PWRON_LP
] = {
255 .mask
= RK805_IRQ_PWRON_LP_MSK
,
258 [RK805_IRQ_HOTDIE
] = {
259 .mask
= RK805_IRQ_HOTDIE_MSK
,
262 [RK805_IRQ_RTC_ALARM
] = {
263 .mask
= RK805_IRQ_RTC_ALARM_MSK
,
266 [RK805_IRQ_RTC_PERIOD
] = {
267 .mask
= RK805_IRQ_RTC_PERIOD_MSK
,
270 [RK805_IRQ_PWRON_FALL
] = {
271 .mask
= RK805_IRQ_PWRON_FALL_MSK
,
276 static const struct regmap_irq rk808_irqs
[] = {
278 [RK808_IRQ_VOUT_LO
] = {
279 .mask
= RK808_IRQ_VOUT_LO_MSK
,
282 [RK808_IRQ_VB_LO
] = {
283 .mask
= RK808_IRQ_VB_LO_MSK
,
286 [RK808_IRQ_PWRON
] = {
287 .mask
= RK808_IRQ_PWRON_MSK
,
290 [RK808_IRQ_PWRON_LP
] = {
291 .mask
= RK808_IRQ_PWRON_LP_MSK
,
294 [RK808_IRQ_HOTDIE
] = {
295 .mask
= RK808_IRQ_HOTDIE_MSK
,
298 [RK808_IRQ_RTC_ALARM
] = {
299 .mask
= RK808_IRQ_RTC_ALARM_MSK
,
302 [RK808_IRQ_RTC_PERIOD
] = {
303 .mask
= RK808_IRQ_RTC_PERIOD_MSK
,
308 [RK808_IRQ_PLUG_IN_INT
] = {
309 .mask
= RK808_IRQ_PLUG_IN_INT_MSK
,
312 [RK808_IRQ_PLUG_OUT_INT
] = {
313 .mask
= RK808_IRQ_PLUG_OUT_INT_MSK
,
318 static const struct regmap_irq rk818_irqs
[] = {
320 [RK818_IRQ_VOUT_LO
] = {
321 .mask
= RK818_IRQ_VOUT_LO_MSK
,
324 [RK818_IRQ_VB_LO
] = {
325 .mask
= RK818_IRQ_VB_LO_MSK
,
328 [RK818_IRQ_PWRON
] = {
329 .mask
= RK818_IRQ_PWRON_MSK
,
332 [RK818_IRQ_PWRON_LP
] = {
333 .mask
= RK818_IRQ_PWRON_LP_MSK
,
336 [RK818_IRQ_HOTDIE
] = {
337 .mask
= RK818_IRQ_HOTDIE_MSK
,
340 [RK818_IRQ_RTC_ALARM
] = {
341 .mask
= RK818_IRQ_RTC_ALARM_MSK
,
344 [RK818_IRQ_RTC_PERIOD
] = {
345 .mask
= RK818_IRQ_RTC_PERIOD_MSK
,
348 [RK818_IRQ_USB_OV
] = {
349 .mask
= RK818_IRQ_USB_OV_MSK
,
354 [RK818_IRQ_PLUG_IN
] = {
355 .mask
= RK818_IRQ_PLUG_IN_MSK
,
358 [RK818_IRQ_PLUG_OUT
] = {
359 .mask
= RK818_IRQ_PLUG_OUT_MSK
,
362 [RK818_IRQ_CHG_OK
] = {
363 .mask
= RK818_IRQ_CHG_OK_MSK
,
366 [RK818_IRQ_CHG_TE
] = {
367 .mask
= RK818_IRQ_CHG_TE_MSK
,
370 [RK818_IRQ_CHG_TS1
] = {
371 .mask
= RK818_IRQ_CHG_TS1_MSK
,
375 .mask
= RK818_IRQ_TS2_MSK
,
378 [RK818_IRQ_CHG_CVTLIM
] = {
379 .mask
= RK818_IRQ_CHG_CVTLIM_MSK
,
382 [RK818_IRQ_DISCHG_ILIM
] = {
383 .mask
= RK818_IRQ_DISCHG_ILIM_MSK
,
388 static const struct regmap_irq rk817_irqs
[RK817_IRQ_END
] = {
389 REGMAP_IRQ_REG_LINE(0, 8),
390 REGMAP_IRQ_REG_LINE(1, 8),
391 REGMAP_IRQ_REG_LINE(2, 8),
392 REGMAP_IRQ_REG_LINE(3, 8),
393 REGMAP_IRQ_REG_LINE(4, 8),
394 REGMAP_IRQ_REG_LINE(5, 8),
395 REGMAP_IRQ_REG_LINE(6, 8),
396 REGMAP_IRQ_REG_LINE(7, 8),
397 REGMAP_IRQ_REG_LINE(8, 8),
398 REGMAP_IRQ_REG_LINE(9, 8),
399 REGMAP_IRQ_REG_LINE(10, 8),
400 REGMAP_IRQ_REG_LINE(11, 8),
401 REGMAP_IRQ_REG_LINE(12, 8),
402 REGMAP_IRQ_REG_LINE(13, 8),
403 REGMAP_IRQ_REG_LINE(14, 8),
404 REGMAP_IRQ_REG_LINE(15, 8),
405 REGMAP_IRQ_REG_LINE(16, 8),
406 REGMAP_IRQ_REG_LINE(17, 8),
407 REGMAP_IRQ_REG_LINE(18, 8),
408 REGMAP_IRQ_REG_LINE(19, 8),
409 REGMAP_IRQ_REG_LINE(20, 8),
410 REGMAP_IRQ_REG_LINE(21, 8),
411 REGMAP_IRQ_REG_LINE(22, 8),
412 REGMAP_IRQ_REG_LINE(23, 8)
415 static struct regmap_irq_chip rk805_irq_chip
= {
418 .num_irqs
= ARRAY_SIZE(rk805_irqs
),
420 .status_base
= RK805_INT_STS_REG
,
421 .mask_base
= RK805_INT_STS_MSK_REG
,
422 .ack_base
= RK805_INT_STS_REG
,
423 .init_ack_masked
= true,
426 static const struct regmap_irq_chip rk808_irq_chip
= {
429 .num_irqs
= ARRAY_SIZE(rk808_irqs
),
432 .status_base
= RK808_INT_STS_REG1
,
433 .mask_base
= RK808_INT_STS_MSK_REG1
,
434 .ack_base
= RK808_INT_STS_REG1
,
435 .init_ack_masked
= true,
438 static struct regmap_irq_chip rk817_irq_chip
= {
441 .num_irqs
= ARRAY_SIZE(rk817_irqs
),
444 .status_base
= RK817_INT_STS_REG0
,
445 .mask_base
= RK817_INT_STS_MSK_REG0
,
446 .ack_base
= RK817_INT_STS_REG0
,
447 .init_ack_masked
= true,
450 static const struct regmap_irq_chip rk818_irq_chip
= {
453 .num_irqs
= ARRAY_SIZE(rk818_irqs
),
456 .status_base
= RK818_INT_STS_REG1
,
457 .mask_base
= RK818_INT_STS_MSK_REG1
,
458 .ack_base
= RK818_INT_STS_REG1
,
459 .init_ack_masked
= true,
462 static struct i2c_client
*rk808_i2c_client
;
464 static void rk805_device_shutdown(void)
467 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
472 ret
= regmap_update_bits(rk808
->regmap
,
476 dev_err(&rk808_i2c_client
->dev
, "Failed to shutdown device!\n");
479 static void rk805_device_shutdown_prepare(void)
482 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
487 ret
= regmap_update_bits(rk808
->regmap
,
488 RK805_GPIO_IO_POL_REG
,
489 SLP_SD_MSK
, SHUTDOWN_FUN
);
491 dev_err(&rk808_i2c_client
->dev
, "Failed to shutdown device!\n");
494 static void rk808_device_shutdown(void)
497 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
502 ret
= regmap_update_bits(rk808
->regmap
,
504 DEV_OFF_RST
, DEV_OFF_RST
);
506 dev_err(&rk808_i2c_client
->dev
, "Failed to shutdown device!\n");
509 static void rk818_device_shutdown(void)
512 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
517 ret
= regmap_update_bits(rk808
->regmap
,
521 dev_err(&rk808_i2c_client
->dev
, "Failed to shutdown device!\n");
524 static void rk8xx_syscore_shutdown(void)
526 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
529 if (system_state
== SYSTEM_POWER_OFF
&&
530 (rk808
->variant
== RK809_ID
|| rk808
->variant
== RK817_ID
)) {
531 ret
= regmap_update_bits(rk808
->regmap
,
533 RK817_SLPPIN_FUNC_MSK
,
536 dev_warn(&rk808_i2c_client
->dev
,
537 "Cannot switch to power down function\n");
542 static struct syscore_ops rk808_syscore_ops
= {
543 .shutdown
= rk8xx_syscore_shutdown
,
546 static const struct of_device_id rk808_of_match
[] = {
547 { .compatible
= "rockchip,rk805" },
548 { .compatible
= "rockchip,rk808" },
549 { .compatible
= "rockchip,rk809" },
550 { .compatible
= "rockchip,rk817" },
551 { .compatible
= "rockchip,rk818" },
554 MODULE_DEVICE_TABLE(of
, rk808_of_match
);
556 static int rk808_probe(struct i2c_client
*client
,
557 const struct i2c_device_id
*id
)
559 struct device_node
*np
= client
->dev
.of_node
;
561 const struct rk808_reg_data
*pre_init_reg
;
562 const struct mfd_cell
*cells
;
563 int nr_pre_init_regs
;
565 int pm_off
= 0, msb
, lsb
;
566 unsigned char pmic_id_msb
, pmic_id_lsb
;
570 rk808
= devm_kzalloc(&client
->dev
, sizeof(*rk808
), GFP_KERNEL
);
574 if (of_device_is_compatible(np
, "rockchip,rk817") ||
575 of_device_is_compatible(np
, "rockchip,rk809")) {
576 pmic_id_msb
= RK817_ID_MSB
;
577 pmic_id_lsb
= RK817_ID_LSB
;
579 pmic_id_msb
= RK808_ID_MSB
;
580 pmic_id_lsb
= RK808_ID_LSB
;
583 /* Read chip variant */
584 msb
= i2c_smbus_read_byte_data(client
, pmic_id_msb
);
586 dev_err(&client
->dev
, "failed to read the chip id at 0x%x\n",
591 lsb
= i2c_smbus_read_byte_data(client
, pmic_id_lsb
);
593 dev_err(&client
->dev
, "failed to read the chip id at 0x%x\n",
598 rk808
->variant
= ((msb
<< 8) | lsb
) & RK8XX_ID_MSK
;
599 dev_info(&client
->dev
, "chip id: 0x%x\n", (unsigned int)rk808
->variant
);
601 switch (rk808
->variant
) {
603 rk808
->regmap_cfg
= &rk805_regmap_config
;
604 rk808
->regmap_irq_chip
= &rk805_irq_chip
;
605 pre_init_reg
= rk805_pre_init_reg
;
606 nr_pre_init_regs
= ARRAY_SIZE(rk805_pre_init_reg
);
608 nr_cells
= ARRAY_SIZE(rk805s
);
609 rk808
->pm_pwroff_fn
= rk805_device_shutdown
;
610 rk808
->pm_pwroff_prep_fn
= rk805_device_shutdown_prepare
;
613 rk808
->regmap_cfg
= &rk808_regmap_config
;
614 rk808
->regmap_irq_chip
= &rk808_irq_chip
;
615 pre_init_reg
= rk808_pre_init_reg
;
616 nr_pre_init_regs
= ARRAY_SIZE(rk808_pre_init_reg
);
618 nr_cells
= ARRAY_SIZE(rk808s
);
619 rk808
->pm_pwroff_fn
= rk808_device_shutdown
;
622 rk808
->regmap_cfg
= &rk818_regmap_config
;
623 rk808
->regmap_irq_chip
= &rk818_irq_chip
;
624 pre_init_reg
= rk818_pre_init_reg
;
625 nr_pre_init_regs
= ARRAY_SIZE(rk818_pre_init_reg
);
627 nr_cells
= ARRAY_SIZE(rk818s
);
628 rk808
->pm_pwroff_fn
= rk818_device_shutdown
;
632 rk808
->regmap_cfg
= &rk817_regmap_config
;
633 rk808
->regmap_irq_chip
= &rk817_irq_chip
;
634 pre_init_reg
= rk817_pre_init_reg
;
635 nr_pre_init_regs
= ARRAY_SIZE(rk817_pre_init_reg
);
637 nr_cells
= ARRAY_SIZE(rk817s
);
638 register_syscore_ops(&rk808_syscore_ops
);
641 dev_err(&client
->dev
, "Unsupported RK8XX ID %lu\n",
647 i2c_set_clientdata(client
, rk808
);
649 rk808
->regmap
= devm_regmap_init_i2c(client
, rk808
->regmap_cfg
);
650 if (IS_ERR(rk808
->regmap
)) {
651 dev_err(&client
->dev
, "regmap initialization failed\n");
652 return PTR_ERR(rk808
->regmap
);
656 dev_err(&client
->dev
, "No interrupt support, no core IRQ\n");
660 ret
= regmap_add_irq_chip(rk808
->regmap
, client
->irq
,
662 rk808
->regmap_irq_chip
, &rk808
->irq_data
);
664 dev_err(&client
->dev
, "Failed to add irq_chip %d\n", ret
);
668 for (i
= 0; i
< nr_pre_init_regs
; i
++) {
669 ret
= regmap_update_bits(rk808
->regmap
,
670 pre_init_reg
[i
].addr
,
671 pre_init_reg
[i
].mask
,
672 pre_init_reg
[i
].value
);
674 dev_err(&client
->dev
,
676 pre_init_reg
[i
].addr
);
681 ret
= devm_mfd_add_devices(&client
->dev
, PLATFORM_DEVID_NONE
,
682 cells
, nr_cells
, NULL
, 0,
683 regmap_irq_get_domain(rk808
->irq_data
));
685 dev_err(&client
->dev
, "failed to add MFD devices %d\n", ret
);
689 pm_off
= of_property_read_bool(np
,
690 "rockchip,system-power-controller");
691 if (pm_off
&& !pm_power_off
) {
692 rk808_i2c_client
= client
;
693 pm_power_off
= rk808
->pm_pwroff_fn
;
696 if (pm_off
&& !pm_power_off_prepare
) {
697 if (!rk808_i2c_client
)
698 rk808_i2c_client
= client
;
699 pm_power_off_prepare
= rk808
->pm_pwroff_prep_fn
;
705 regmap_del_irq_chip(client
->irq
, rk808
->irq_data
);
709 static int rk808_remove(struct i2c_client
*client
)
711 struct rk808
*rk808
= i2c_get_clientdata(client
);
713 regmap_del_irq_chip(client
->irq
, rk808
->irq_data
);
716 * pm_power_off may points to a function from another module.
717 * Check if the pointer is set by us and only then overwrite it.
719 if (rk808
->pm_pwroff_fn
&& pm_power_off
== rk808
->pm_pwroff_fn
)
723 * As above, check if the pointer is set by us before overwrite.
725 if (rk808
->pm_pwroff_prep_fn
&&
726 pm_power_off_prepare
== rk808
->pm_pwroff_prep_fn
)
727 pm_power_off_prepare
= NULL
;
732 static int rk8xx_suspend(struct device
*dev
)
734 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
737 switch (rk808
->variant
) {
740 ret
= regmap_update_bits(rk808
->regmap
,
742 RK817_SLPPIN_FUNC_MSK
,
752 static int rk8xx_resume(struct device
*dev
)
754 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
757 switch (rk808
->variant
) {
760 ret
= regmap_update_bits(rk808
->regmap
,
762 RK817_SLPPIN_FUNC_MSK
,
771 SIMPLE_DEV_PM_OPS(rk8xx_pm_ops
, rk8xx_suspend
, rk8xx_resume
);
773 static struct i2c_driver rk808_i2c_driver
= {
776 .of_match_table
= rk808_of_match
,
779 .probe
= rk808_probe
,
780 .remove
= rk808_remove
,
783 module_i2c_driver(rk808_i2c_driver
);
785 MODULE_LICENSE("GPL");
786 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
787 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
788 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
789 MODULE_DESCRIPTION("RK808/RK818 PMIC driver");