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>
23 struct rk808_reg_data
{
29 static bool rk808_is_volatile_reg(struct device
*dev
, unsigned int reg
)
33 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
34 * we don't use that feature. It's better to cache.
35 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
36 * bits are cleared in case when we shutoff anyway, but better safe.
40 case RK808_SECONDS_REG
... RK808_WEEKS_REG
:
41 case RK808_RTC_STATUS_REG
:
42 case RK808_VB_MON_REG
:
43 case RK808_THERMAL_REG
:
44 case RK808_DCDC_UV_STS_REG
:
45 case RK808_LDO_UV_STS_REG
:
46 case RK808_DCDC_PG_REG
:
47 case RK808_LDO_PG_REG
:
48 case RK808_DEVCTRL_REG
:
49 case RK808_INT_STS_REG1
:
50 case RK808_INT_STS_REG2
:
57 static bool rk817_is_volatile_reg(struct device
*dev
, unsigned int reg
)
61 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
62 * we don't use that feature. It's better to cache.
66 case RK817_SECONDS_REG
... RK817_WEEKS_REG
:
67 case RK817_RTC_STATUS_REG
:
68 case RK817_INT_STS_REG0
:
69 case RK817_INT_STS_REG1
:
70 case RK817_INT_STS_REG2
:
78 static const struct regmap_config rk818_regmap_config
= {
81 .max_register
= RK818_USB_CTRL_REG
,
82 .cache_type
= REGCACHE_RBTREE
,
83 .volatile_reg
= rk808_is_volatile_reg
,
86 static const struct regmap_config rk805_regmap_config
= {
89 .max_register
= RK805_OFF_SOURCE_REG
,
90 .cache_type
= REGCACHE_RBTREE
,
91 .volatile_reg
= rk808_is_volatile_reg
,
94 static const struct regmap_config rk808_regmap_config
= {
97 .max_register
= RK808_IO_POL_REG
,
98 .cache_type
= REGCACHE_RBTREE
,
99 .volatile_reg
= rk808_is_volatile_reg
,
102 static const struct regmap_config rk817_regmap_config
= {
105 .max_register
= RK817_GPIO_INT_CFG
,
106 .cache_type
= REGCACHE_NONE
,
107 .volatile_reg
= rk817_is_volatile_reg
,
110 static const struct resource rtc_resources
[] = {
111 DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM
),
114 static const struct resource rk817_rtc_resources
[] = {
115 DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM
),
118 static const struct resource rk805_key_resources
[] = {
119 DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE
),
120 DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL
),
123 static const struct resource rk817_pwrkey_resources
[] = {
124 DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE
),
125 DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL
),
128 static const struct mfd_cell rk805s
[] = {
129 { .name
= "rk808-clkout", },
130 { .name
= "rk808-regulator", },
131 { .name
= "rk805-pinctrl", },
134 .num_resources
= ARRAY_SIZE(rtc_resources
),
135 .resources
= &rtc_resources
[0],
137 { .name
= "rk805-pwrkey",
138 .num_resources
= ARRAY_SIZE(rk805_key_resources
),
139 .resources
= &rk805_key_resources
[0],
143 static const struct mfd_cell rk808s
[] = {
144 { .name
= "rk808-clkout", },
145 { .name
= "rk808-regulator", },
148 .num_resources
= ARRAY_SIZE(rtc_resources
),
149 .resources
= rtc_resources
,
153 static const struct mfd_cell rk817s
[] = {
154 { .name
= "rk808-clkout",},
155 { .name
= "rk808-regulator",},
157 .name
= "rk805-pwrkey",
158 .num_resources
= ARRAY_SIZE(rk817_pwrkey_resources
),
159 .resources
= &rk817_pwrkey_resources
[0],
163 .num_resources
= ARRAY_SIZE(rk817_rtc_resources
),
164 .resources
= &rk817_rtc_resources
[0],
168 static const struct mfd_cell rk818s
[] = {
169 { .name
= "rk808-clkout", },
170 { .name
= "rk808-regulator", },
173 .num_resources
= ARRAY_SIZE(rtc_resources
),
174 .resources
= rtc_resources
,
178 static const struct rk808_reg_data rk805_pre_init_reg
[] = {
179 {RK805_BUCK1_CONFIG_REG
, RK805_BUCK1_2_ILMAX_MASK
,
180 RK805_BUCK1_2_ILMAX_4000MA
},
181 {RK805_BUCK2_CONFIG_REG
, RK805_BUCK1_2_ILMAX_MASK
,
182 RK805_BUCK1_2_ILMAX_4000MA
},
183 {RK805_BUCK3_CONFIG_REG
, RK805_BUCK3_4_ILMAX_MASK
,
184 RK805_BUCK3_ILMAX_3000MA
},
185 {RK805_BUCK4_CONFIG_REG
, RK805_BUCK3_4_ILMAX_MASK
,
186 RK805_BUCK4_ILMAX_3500MA
},
187 {RK805_BUCK4_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_400MA
},
188 {RK805_THERMAL_REG
, TEMP_HOTDIE_MSK
, TEMP115C
},
191 static const struct rk808_reg_data rk808_pre_init_reg
[] = {
192 { RK808_BUCK3_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_150MA
},
193 { RK808_BUCK4_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_200MA
},
194 { RK808_BOOST_CONFIG_REG
, BOOST_ILMIN_MASK
, BOOST_ILMIN_100MA
},
195 { RK808_BUCK1_CONFIG_REG
, BUCK1_RATE_MASK
, BUCK_ILMIN_200MA
},
196 { RK808_BUCK2_CONFIG_REG
, BUCK2_RATE_MASK
, BUCK_ILMIN_200MA
},
197 { RK808_DCDC_UV_ACT_REG
, BUCK_UV_ACT_MASK
, BUCK_UV_ACT_DISABLE
},
198 { RK808_VB_MON_REG
, MASK_ALL
, VB_LO_ACT
|
202 static const struct rk808_reg_data rk817_pre_init_reg
[] = {
203 {RK817_RTC_CTRL_REG
, RTC_STOP
, RTC_STOP
},
204 {RK817_GPIO_INT_CFG
, RK817_INT_POL_MSK
, RK817_INT_POL_L
},
205 {RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK
| RK817_TSD_TEMP_MSK
,
206 RK817_HOTDIE_105
| RK817_TSD_140
},
209 static const struct rk808_reg_data rk818_pre_init_reg
[] = {
210 /* improve efficiency */
211 { RK818_BUCK2_CONFIG_REG
, BUCK2_RATE_MASK
, BUCK_ILMIN_250MA
},
212 { RK818_BUCK4_CONFIG_REG
, BUCK_ILMIN_MASK
, BUCK_ILMIN_250MA
},
213 { RK818_BOOST_CONFIG_REG
, BOOST_ILMIN_MASK
, BOOST_ILMIN_100MA
},
214 { RK818_USB_CTRL_REG
, RK818_USB_ILIM_SEL_MASK
,
215 RK818_USB_ILMIN_2000MA
},
216 /* close charger when usb lower then 3.4V */
217 { RK818_USB_CTRL_REG
, RK818_USB_CHG_SD_VSEL_MASK
,
219 /* no action when vref */
220 { RK818_H5V_EN_REG
, BIT(1), RK818_REF_RDY_CTRL
},
222 { RK818_H5V_EN_REG
, BIT(0), RK818_H5V_EN
},
223 { RK808_VB_MON_REG
, MASK_ALL
, VB_LO_ACT
|
227 static const struct regmap_irq rk805_irqs
[] = {
228 [RK805_IRQ_PWRON_RISE
] = {
229 .mask
= RK805_IRQ_PWRON_RISE_MSK
,
232 [RK805_IRQ_VB_LOW
] = {
233 .mask
= RK805_IRQ_VB_LOW_MSK
,
236 [RK805_IRQ_PWRON
] = {
237 .mask
= RK805_IRQ_PWRON_MSK
,
240 [RK805_IRQ_PWRON_LP
] = {
241 .mask
= RK805_IRQ_PWRON_LP_MSK
,
244 [RK805_IRQ_HOTDIE
] = {
245 .mask
= RK805_IRQ_HOTDIE_MSK
,
248 [RK805_IRQ_RTC_ALARM
] = {
249 .mask
= RK805_IRQ_RTC_ALARM_MSK
,
252 [RK805_IRQ_RTC_PERIOD
] = {
253 .mask
= RK805_IRQ_RTC_PERIOD_MSK
,
256 [RK805_IRQ_PWRON_FALL
] = {
257 .mask
= RK805_IRQ_PWRON_FALL_MSK
,
262 static const struct regmap_irq rk808_irqs
[] = {
264 [RK808_IRQ_VOUT_LO
] = {
265 .mask
= RK808_IRQ_VOUT_LO_MSK
,
268 [RK808_IRQ_VB_LO
] = {
269 .mask
= RK808_IRQ_VB_LO_MSK
,
272 [RK808_IRQ_PWRON
] = {
273 .mask
= RK808_IRQ_PWRON_MSK
,
276 [RK808_IRQ_PWRON_LP
] = {
277 .mask
= RK808_IRQ_PWRON_LP_MSK
,
280 [RK808_IRQ_HOTDIE
] = {
281 .mask
= RK808_IRQ_HOTDIE_MSK
,
284 [RK808_IRQ_RTC_ALARM
] = {
285 .mask
= RK808_IRQ_RTC_ALARM_MSK
,
288 [RK808_IRQ_RTC_PERIOD
] = {
289 .mask
= RK808_IRQ_RTC_PERIOD_MSK
,
294 [RK808_IRQ_PLUG_IN_INT
] = {
295 .mask
= RK808_IRQ_PLUG_IN_INT_MSK
,
298 [RK808_IRQ_PLUG_OUT_INT
] = {
299 .mask
= RK808_IRQ_PLUG_OUT_INT_MSK
,
304 static const struct regmap_irq rk818_irqs
[] = {
306 [RK818_IRQ_VOUT_LO
] = {
307 .mask
= RK818_IRQ_VOUT_LO_MSK
,
310 [RK818_IRQ_VB_LO
] = {
311 .mask
= RK818_IRQ_VB_LO_MSK
,
314 [RK818_IRQ_PWRON
] = {
315 .mask
= RK818_IRQ_PWRON_MSK
,
318 [RK818_IRQ_PWRON_LP
] = {
319 .mask
= RK818_IRQ_PWRON_LP_MSK
,
322 [RK818_IRQ_HOTDIE
] = {
323 .mask
= RK818_IRQ_HOTDIE_MSK
,
326 [RK818_IRQ_RTC_ALARM
] = {
327 .mask
= RK818_IRQ_RTC_ALARM_MSK
,
330 [RK818_IRQ_RTC_PERIOD
] = {
331 .mask
= RK818_IRQ_RTC_PERIOD_MSK
,
334 [RK818_IRQ_USB_OV
] = {
335 .mask
= RK818_IRQ_USB_OV_MSK
,
340 [RK818_IRQ_PLUG_IN
] = {
341 .mask
= RK818_IRQ_PLUG_IN_MSK
,
344 [RK818_IRQ_PLUG_OUT
] = {
345 .mask
= RK818_IRQ_PLUG_OUT_MSK
,
348 [RK818_IRQ_CHG_OK
] = {
349 .mask
= RK818_IRQ_CHG_OK_MSK
,
352 [RK818_IRQ_CHG_TE
] = {
353 .mask
= RK818_IRQ_CHG_TE_MSK
,
356 [RK818_IRQ_CHG_TS1
] = {
357 .mask
= RK818_IRQ_CHG_TS1_MSK
,
361 .mask
= RK818_IRQ_TS2_MSK
,
364 [RK818_IRQ_CHG_CVTLIM
] = {
365 .mask
= RK818_IRQ_CHG_CVTLIM_MSK
,
368 [RK818_IRQ_DISCHG_ILIM
] = {
369 .mask
= RK818_IRQ_DISCHG_ILIM_MSK
,
374 static const struct regmap_irq rk817_irqs
[RK817_IRQ_END
] = {
375 REGMAP_IRQ_REG_LINE(0, 8),
376 REGMAP_IRQ_REG_LINE(1, 8),
377 REGMAP_IRQ_REG_LINE(2, 8),
378 REGMAP_IRQ_REG_LINE(3, 8),
379 REGMAP_IRQ_REG_LINE(4, 8),
380 REGMAP_IRQ_REG_LINE(5, 8),
381 REGMAP_IRQ_REG_LINE(6, 8),
382 REGMAP_IRQ_REG_LINE(7, 8),
383 REGMAP_IRQ_REG_LINE(8, 8),
384 REGMAP_IRQ_REG_LINE(9, 8),
385 REGMAP_IRQ_REG_LINE(10, 8),
386 REGMAP_IRQ_REG_LINE(11, 8),
387 REGMAP_IRQ_REG_LINE(12, 8),
388 REGMAP_IRQ_REG_LINE(13, 8),
389 REGMAP_IRQ_REG_LINE(14, 8),
390 REGMAP_IRQ_REG_LINE(15, 8),
391 REGMAP_IRQ_REG_LINE(16, 8),
392 REGMAP_IRQ_REG_LINE(17, 8),
393 REGMAP_IRQ_REG_LINE(18, 8),
394 REGMAP_IRQ_REG_LINE(19, 8),
395 REGMAP_IRQ_REG_LINE(20, 8),
396 REGMAP_IRQ_REG_LINE(21, 8),
397 REGMAP_IRQ_REG_LINE(22, 8),
398 REGMAP_IRQ_REG_LINE(23, 8)
401 static struct regmap_irq_chip rk805_irq_chip
= {
404 .num_irqs
= ARRAY_SIZE(rk805_irqs
),
406 .status_base
= RK805_INT_STS_REG
,
407 .mask_base
= RK805_INT_STS_MSK_REG
,
408 .ack_base
= RK805_INT_STS_REG
,
409 .init_ack_masked
= true,
412 static const struct regmap_irq_chip rk808_irq_chip
= {
415 .num_irqs
= ARRAY_SIZE(rk808_irqs
),
418 .status_base
= RK808_INT_STS_REG1
,
419 .mask_base
= RK808_INT_STS_MSK_REG1
,
420 .ack_base
= RK808_INT_STS_REG1
,
421 .init_ack_masked
= true,
424 static struct regmap_irq_chip rk817_irq_chip
= {
427 .num_irqs
= ARRAY_SIZE(rk817_irqs
),
430 .status_base
= RK817_INT_STS_REG0
,
431 .mask_base
= RK817_INT_STS_MSK_REG0
,
432 .ack_base
= RK817_INT_STS_REG0
,
433 .init_ack_masked
= true,
436 static const struct regmap_irq_chip rk818_irq_chip
= {
439 .num_irqs
= ARRAY_SIZE(rk818_irqs
),
442 .status_base
= RK818_INT_STS_REG1
,
443 .mask_base
= RK818_INT_STS_MSK_REG1
,
444 .ack_base
= RK818_INT_STS_REG1
,
445 .init_ack_masked
= true,
448 static struct i2c_client
*rk808_i2c_client
;
450 static void rk808_pm_power_off(void)
453 unsigned int reg
, bit
;
454 struct rk808
*rk808
= i2c_get_clientdata(rk808_i2c_client
);
456 switch (rk808
->variant
) {
458 reg
= RK805_DEV_CTRL_REG
;
462 reg
= RK808_DEVCTRL_REG
,
466 reg
= RK818_DEVCTRL_REG
;
472 ret
= regmap_update_bits(rk808
->regmap
, reg
, bit
, bit
);
474 dev_err(&rk808_i2c_client
->dev
, "Failed to shutdown device!\n");
477 static void rk8xx_shutdown(struct i2c_client
*client
)
479 struct rk808
*rk808
= i2c_get_clientdata(client
);
482 switch (rk808
->variant
) {
484 ret
= regmap_update_bits(rk808
->regmap
,
485 RK805_GPIO_IO_POL_REG
,
491 ret
= regmap_update_bits(rk808
->regmap
,
493 RK817_SLPPIN_FUNC_MSK
,
500 dev_warn(&client
->dev
,
501 "Cannot switch to power down function\n");
504 static const struct of_device_id rk808_of_match
[] = {
505 { .compatible
= "rockchip,rk805" },
506 { .compatible
= "rockchip,rk808" },
507 { .compatible
= "rockchip,rk809" },
508 { .compatible
= "rockchip,rk817" },
509 { .compatible
= "rockchip,rk818" },
512 MODULE_DEVICE_TABLE(of
, rk808_of_match
);
514 static int rk808_probe(struct i2c_client
*client
,
515 const struct i2c_device_id
*id
)
517 struct device_node
*np
= client
->dev
.of_node
;
519 const struct rk808_reg_data
*pre_init_reg
;
520 const struct mfd_cell
*cells
;
521 int nr_pre_init_regs
;
524 unsigned char pmic_id_msb
, pmic_id_lsb
;
528 rk808
= devm_kzalloc(&client
->dev
, sizeof(*rk808
), GFP_KERNEL
);
532 if (of_device_is_compatible(np
, "rockchip,rk817") ||
533 of_device_is_compatible(np
, "rockchip,rk809")) {
534 pmic_id_msb
= RK817_ID_MSB
;
535 pmic_id_lsb
= RK817_ID_LSB
;
537 pmic_id_msb
= RK808_ID_MSB
;
538 pmic_id_lsb
= RK808_ID_LSB
;
541 /* Read chip variant */
542 msb
= i2c_smbus_read_byte_data(client
, pmic_id_msb
);
544 dev_err(&client
->dev
, "failed to read the chip id at 0x%x\n",
549 lsb
= i2c_smbus_read_byte_data(client
, pmic_id_lsb
);
551 dev_err(&client
->dev
, "failed to read the chip id at 0x%x\n",
556 rk808
->variant
= ((msb
<< 8) | lsb
) & RK8XX_ID_MSK
;
557 dev_info(&client
->dev
, "chip id: 0x%x\n", (unsigned int)rk808
->variant
);
559 switch (rk808
->variant
) {
561 rk808
->regmap_cfg
= &rk805_regmap_config
;
562 rk808
->regmap_irq_chip
= &rk805_irq_chip
;
563 pre_init_reg
= rk805_pre_init_reg
;
564 nr_pre_init_regs
= ARRAY_SIZE(rk805_pre_init_reg
);
566 nr_cells
= ARRAY_SIZE(rk805s
);
569 rk808
->regmap_cfg
= &rk808_regmap_config
;
570 rk808
->regmap_irq_chip
= &rk808_irq_chip
;
571 pre_init_reg
= rk808_pre_init_reg
;
572 nr_pre_init_regs
= ARRAY_SIZE(rk808_pre_init_reg
);
574 nr_cells
= ARRAY_SIZE(rk808s
);
577 rk808
->regmap_cfg
= &rk818_regmap_config
;
578 rk808
->regmap_irq_chip
= &rk818_irq_chip
;
579 pre_init_reg
= rk818_pre_init_reg
;
580 nr_pre_init_regs
= ARRAY_SIZE(rk818_pre_init_reg
);
582 nr_cells
= ARRAY_SIZE(rk818s
);
586 rk808
->regmap_cfg
= &rk817_regmap_config
;
587 rk808
->regmap_irq_chip
= &rk817_irq_chip
;
588 pre_init_reg
= rk817_pre_init_reg
;
589 nr_pre_init_regs
= ARRAY_SIZE(rk817_pre_init_reg
);
591 nr_cells
= ARRAY_SIZE(rk817s
);
594 dev_err(&client
->dev
, "Unsupported RK8XX ID %lu\n",
600 i2c_set_clientdata(client
, rk808
);
602 rk808
->regmap
= devm_regmap_init_i2c(client
, rk808
->regmap_cfg
);
603 if (IS_ERR(rk808
->regmap
)) {
604 dev_err(&client
->dev
, "regmap initialization failed\n");
605 return PTR_ERR(rk808
->regmap
);
609 dev_err(&client
->dev
, "No interrupt support, no core IRQ\n");
613 ret
= regmap_add_irq_chip(rk808
->regmap
, client
->irq
,
615 rk808
->regmap_irq_chip
, &rk808
->irq_data
);
617 dev_err(&client
->dev
, "Failed to add irq_chip %d\n", ret
);
621 for (i
= 0; i
< nr_pre_init_regs
; i
++) {
622 ret
= regmap_update_bits(rk808
->regmap
,
623 pre_init_reg
[i
].addr
,
624 pre_init_reg
[i
].mask
,
625 pre_init_reg
[i
].value
);
627 dev_err(&client
->dev
,
629 pre_init_reg
[i
].addr
);
634 ret
= devm_mfd_add_devices(&client
->dev
, PLATFORM_DEVID_NONE
,
635 cells
, nr_cells
, NULL
, 0,
636 regmap_irq_get_domain(rk808
->irq_data
));
638 dev_err(&client
->dev
, "failed to add MFD devices %d\n", ret
);
642 if (of_property_read_bool(np
, "rockchip,system-power-controller")) {
643 rk808_i2c_client
= client
;
644 pm_power_off
= rk808_pm_power_off
;
650 regmap_del_irq_chip(client
->irq
, rk808
->irq_data
);
654 static int rk808_remove(struct i2c_client
*client
)
656 struct rk808
*rk808
= i2c_get_clientdata(client
);
658 regmap_del_irq_chip(client
->irq
, rk808
->irq_data
);
661 * pm_power_off may points to a function from another module.
662 * Check if the pointer is set by us and only then overwrite it.
664 if (pm_power_off
== rk808_pm_power_off
)
670 static int __maybe_unused
rk8xx_suspend(struct device
*dev
)
672 struct rk808
*rk808
= i2c_get_clientdata(to_i2c_client(dev
));
675 switch (rk808
->variant
) {
677 ret
= regmap_update_bits(rk808
->regmap
,
678 RK805_GPIO_IO_POL_REG
,
684 ret
= regmap_update_bits(rk808
->regmap
,
686 RK817_SLPPIN_FUNC_MSK
,
696 static int __maybe_unused
rk8xx_resume(struct device
*dev
)
698 struct rk808
*rk808
= i2c_get_clientdata(to_i2c_client(dev
));
701 switch (rk808
->variant
) {
704 ret
= regmap_update_bits(rk808
->regmap
,
706 RK817_SLPPIN_FUNC_MSK
,
715 static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops
, rk8xx_suspend
, rk8xx_resume
);
717 static struct i2c_driver rk808_i2c_driver
= {
720 .of_match_table
= rk808_of_match
,
723 .probe
= rk808_probe
,
724 .remove
= rk808_remove
,
725 .shutdown
= rk8xx_shutdown
,
728 module_i2c_driver(rk808_i2c_driver
);
730 MODULE_LICENSE("GPL");
731 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
732 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
733 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
734 MODULE_DESCRIPTION("RK808/RK818 PMIC driver");