13d0407baSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
23d0407baSopenharmony_ci/*
33d0407baSopenharmony_ci * MFD core driver for Rockchip RK808/RK818
43d0407baSopenharmony_ci *
53d0407baSopenharmony_ci * Copyright (c) 2014-2018, Fuzhou Rockchip Electronics Co., Ltd
63d0407baSopenharmony_ci *
73d0407baSopenharmony_ci * Author: Chris Zhong <zyw@rock-chips.com>
83d0407baSopenharmony_ci * Author: Zhang Qing <zhangqing@rock-chips.com>
93d0407baSopenharmony_ci *
103d0407baSopenharmony_ci * Copyright (C) 2016 PHYTEC Messtechnik GmbH
113d0407baSopenharmony_ci *
123d0407baSopenharmony_ci * Author: Wadim Egorov <w.egorov@phytec.de>
133d0407baSopenharmony_ci */
143d0407baSopenharmony_ci
153d0407baSopenharmony_ci#include <linux/i2c.h>
163d0407baSopenharmony_ci#include <linux/interrupt.h>
173d0407baSopenharmony_ci#include <linux/mfd/rk808.h>
183d0407baSopenharmony_ci#include <linux/mfd/core.h>
193d0407baSopenharmony_ci#include <linux/module.h>
203d0407baSopenharmony_ci#include <linux/of_device.h>
213d0407baSopenharmony_ci#include <linux/reboot.h>
223d0407baSopenharmony_ci#include <linux/regmap.h>
233d0407baSopenharmony_ci#include <linux/syscore_ops.h>
243d0407baSopenharmony_ci#include <linux/pinctrl/consumer.h>
253d0407baSopenharmony_ci#include <linux/pinctrl/devinfo.h>
263d0407baSopenharmony_ci
273d0407baSopenharmony_cistruct rk808_reg_data {
283d0407baSopenharmony_ci    int addr;
293d0407baSopenharmony_ci    int mask;
303d0407baSopenharmony_ci    int value;
313d0407baSopenharmony_ci};
323d0407baSopenharmony_ci
333d0407baSopenharmony_cistatic bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
343d0407baSopenharmony_ci{
353d0407baSopenharmony_ci    /*
363d0407baSopenharmony_ci     * Notes:
373d0407baSopenharmony_ci     * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
383d0407baSopenharmony_ci     *   we don't use that feature.  It's better to cache.
393d0407baSopenharmony_ci     * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
403d0407baSopenharmony_ci     *   bits are cleared in case when we shutoff anyway, but better safe.
413d0407baSopenharmony_ci     */
423d0407baSopenharmony_ci
433d0407baSopenharmony_ci    switch (reg) {
443d0407baSopenharmony_ci        case RK808_SECONDS_REG ... RK808_WEEKS_REG:
453d0407baSopenharmony_ci        case RK808_RTC_STATUS_REG:
463d0407baSopenharmony_ci        case RK808_VB_MON_REG:
473d0407baSopenharmony_ci        case RK808_THERMAL_REG:
483d0407baSopenharmony_ci        case RK808_DCDC_UV_STS_REG:
493d0407baSopenharmony_ci        case RK808_LDO_UV_STS_REG:
503d0407baSopenharmony_ci        case RK808_DCDC_PG_REG:
513d0407baSopenharmony_ci        case RK808_LDO_PG_REG:
523d0407baSopenharmony_ci        case RK808_DEVCTRL_REG:
533d0407baSopenharmony_ci        case RK808_INT_STS_REG1:
543d0407baSopenharmony_ci        case RK808_INT_STS_REG2:
553d0407baSopenharmony_ci            return true;
563d0407baSopenharmony_ci        default:
573d0407baSopenharmony_ci            break;
583d0407baSopenharmony_ci    }
593d0407baSopenharmony_ci
603d0407baSopenharmony_ci    return false;
613d0407baSopenharmony_ci}
623d0407baSopenharmony_ci
633d0407baSopenharmony_cistatic bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
643d0407baSopenharmony_ci{
653d0407baSopenharmony_ci    /*
663d0407baSopenharmony_ci     * Notes:
673d0407baSopenharmony_ci     * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
683d0407baSopenharmony_ci     *   we don't use that feature.  It's better to cache.
693d0407baSopenharmony_ci     */
703d0407baSopenharmony_ci
713d0407baSopenharmony_ci    switch (reg) {
723d0407baSopenharmony_ci        case RK817_SECONDS_REG ... RK817_WEEKS_REG:
733d0407baSopenharmony_ci        case RK817_RTC_STATUS_REG:
743d0407baSopenharmony_ci        case RK817_ADC_CONFIG0 ... RK817_CURE_ADC_K0:
753d0407baSopenharmony_ci        case RK817_CHRG_STS:
763d0407baSopenharmony_ci        case RK817_CHRG_OUT:
773d0407baSopenharmony_ci        case RK817_CHRG_IN:
783d0407baSopenharmony_ci        case RK817_SYS_STS:
793d0407baSopenharmony_ci        case RK817_INT_STS_REG0:
803d0407baSopenharmony_ci        case RK817_INT_STS_REG1:
813d0407baSopenharmony_ci        case RK817_INT_STS_REG2:
823d0407baSopenharmony_ci            return true;
833d0407baSopenharmony_ci        default:
843d0407baSopenharmony_ci            break;
853d0407baSopenharmony_ci    }
863d0407baSopenharmony_ci
873d0407baSopenharmony_ci    return false;
883d0407baSopenharmony_ci}
893d0407baSopenharmony_ci
903d0407baSopenharmony_cistatic bool rk818_is_volatile_reg(struct device *dev, unsigned int reg)
913d0407baSopenharmony_ci{
923d0407baSopenharmony_ci    /*
933d0407baSopenharmony_ci     * Notes:
943d0407baSopenharmony_ci     * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
953d0407baSopenharmony_ci     *   we don't use that feature.  It's better to cache.
963d0407baSopenharmony_ci     * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
973d0407baSopenharmony_ci     *   bits are cleared in case when we shutoff anyway, but better safe.
983d0407baSopenharmony_ci     */
993d0407baSopenharmony_ci
1003d0407baSopenharmony_ci    switch (reg) {
1013d0407baSopenharmony_ci        case RK808_SECONDS_REG ... RK808_WEEKS_REG:
1023d0407baSopenharmony_ci        case RK808_RTC_STATUS_REG:
1033d0407baSopenharmony_ci        case RK808_VB_MON_REG:
1043d0407baSopenharmony_ci        case RK808_THERMAL_REG:
1053d0407baSopenharmony_ci        case RK808_DCDC_EN_REG:
1063d0407baSopenharmony_ci        case RK808_LDO_EN_REG:
1073d0407baSopenharmony_ci        case RK808_DCDC_UV_STS_REG:
1083d0407baSopenharmony_ci        case RK808_LDO_UV_STS_REG:
1093d0407baSopenharmony_ci        case RK808_DCDC_PG_REG:
1103d0407baSopenharmony_ci        case RK808_LDO_PG_REG:
1113d0407baSopenharmony_ci        case RK808_DEVCTRL_REG:
1123d0407baSopenharmony_ci        case RK808_INT_STS_REG1:
1133d0407baSopenharmony_ci        case RK808_INT_STS_REG2:
1143d0407baSopenharmony_ci        case RK808_INT_STS_MSK_REG1:
1153d0407baSopenharmony_ci        case RK808_INT_STS_MSK_REG2:
1163d0407baSopenharmony_ci        case RK816_INT_STS_REG1:
1173d0407baSopenharmony_ci        case RK816_INT_STS_MSK_REG1:
1183d0407baSopenharmony_ci        case RK818_SUP_STS_REG ... RK818_SAVE_DATA19:
1193d0407baSopenharmony_ci            return true;
1203d0407baSopenharmony_ci        default:
1213d0407baSopenharmony_ci            break;
1223d0407baSopenharmony_ci    }
1233d0407baSopenharmony_ci
1243d0407baSopenharmony_ci    return false;
1253d0407baSopenharmony_ci}
1263d0407baSopenharmony_ci
1273d0407baSopenharmony_cistatic const struct regmap_config rk818_regmap_config = {
1283d0407baSopenharmony_ci    .reg_bits = RK_REG_BITS,
1293d0407baSopenharmony_ci    .val_bits = RK_VAL_BITS,
1303d0407baSopenharmony_ci    .max_register = RK818_SAVE_DATA19,
1313d0407baSopenharmony_ci    .cache_type = REGCACHE_RBTREE,
1323d0407baSopenharmony_ci    .volatile_reg = rk818_is_volatile_reg,
1333d0407baSopenharmony_ci};
1343d0407baSopenharmony_ci
1353d0407baSopenharmony_cistatic const struct regmap_config rk805_regmap_config = {
1363d0407baSopenharmony_ci    .reg_bits = RK_REG_BITS,
1373d0407baSopenharmony_ci    .val_bits = RK_VAL_BITS,
1383d0407baSopenharmony_ci    .max_register = RK805_OFF_SOURCE_REG,
1393d0407baSopenharmony_ci    .cache_type = REGCACHE_RBTREE,
1403d0407baSopenharmony_ci    .volatile_reg = rk808_is_volatile_reg,
1413d0407baSopenharmony_ci};
1423d0407baSopenharmony_ci
1433d0407baSopenharmony_cistatic const struct regmap_config rk808_regmap_config = {
1443d0407baSopenharmony_ci    .reg_bits = RK_REG_BITS,
1453d0407baSopenharmony_ci    .val_bits = RK_VAL_BITS,
1463d0407baSopenharmony_ci    .max_register = RK808_IO_POL_REG,
1473d0407baSopenharmony_ci    .cache_type = REGCACHE_RBTREE,
1483d0407baSopenharmony_ci    .volatile_reg = rk808_is_volatile_reg,
1493d0407baSopenharmony_ci};
1503d0407baSopenharmony_ci
1513d0407baSopenharmony_cistatic const struct regmap_config rk816_regmap_config = {
1523d0407baSopenharmony_ci    .reg_bits = RK_REG_BITS,
1533d0407baSopenharmony_ci    .val_bits = RK_VAL_BITS,
1543d0407baSopenharmony_ci    .max_register = RK816_DATA18_REG,
1553d0407baSopenharmony_ci    .cache_type = REGCACHE_RBTREE,
1563d0407baSopenharmony_ci    .volatile_reg = rk818_is_volatile_reg,
1573d0407baSopenharmony_ci};
1583d0407baSopenharmony_ci
1593d0407baSopenharmony_cistatic const struct regmap_config rk817_regmap_config = {
1603d0407baSopenharmony_ci    .reg_bits = RK_REG_BITS,
1613d0407baSopenharmony_ci    .val_bits = RK_VAL_BITS,
1623d0407baSopenharmony_ci    .max_register = RK817_GPIO_INT_CFG,
1633d0407baSopenharmony_ci    .num_reg_defaults_raw = RK817_GPIO_INT_CFG + 1,
1643d0407baSopenharmony_ci    .cache_type = REGCACHE_RBTREE,
1653d0407baSopenharmony_ci    .volatile_reg = rk817_is_volatile_reg,
1663d0407baSopenharmony_ci};
1673d0407baSopenharmony_ci
1683d0407baSopenharmony_cistatic struct resource rtc_resources[] = {
1693d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
1703d0407baSopenharmony_ci};
1713d0407baSopenharmony_ci
1723d0407baSopenharmony_cistatic struct resource rk816_rtc_resources[] = {
1733d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK816_IRQ_RTC_ALARM),
1743d0407baSopenharmony_ci};
1753d0407baSopenharmony_ci
1763d0407baSopenharmony_cistatic struct resource rk817_rtc_resources[] = {
1773d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
1783d0407baSopenharmony_ci};
1793d0407baSopenharmony_ci
1803d0407baSopenharmony_cistatic struct resource rk805_key_resources[] = {
1813d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
1823d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
1833d0407baSopenharmony_ci};
1843d0407baSopenharmony_ci
1853d0407baSopenharmony_cistatic struct resource rk816_pwrkey_resources[] = {
1863d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK816_IRQ_PWRON_FALL),
1873d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK816_IRQ_PWRON_RISE),
1883d0407baSopenharmony_ci};
1893d0407baSopenharmony_ci
1903d0407baSopenharmony_cistatic struct resource rk817_pwrkey_resources[] = {
1913d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
1923d0407baSopenharmony_ci    DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
1933d0407baSopenharmony_ci};
1943d0407baSopenharmony_ci
1953d0407baSopenharmony_cistatic const struct mfd_cell rk805s[] = {
1963d0407baSopenharmony_ci    {
1973d0407baSopenharmony_ci        .name = "rk808-clkout",
1983d0407baSopenharmony_ci    },
1993d0407baSopenharmony_ci    {
2003d0407baSopenharmony_ci        .name = "rk808-regulator",
2013d0407baSopenharmony_ci    },
2023d0407baSopenharmony_ci    {
2033d0407baSopenharmony_ci        .name = "rk805-pinctrl",
2043d0407baSopenharmony_ci    },
2053d0407baSopenharmony_ci    {
2063d0407baSopenharmony_ci        .name = "rk808-rtc",
2073d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rtc_resources),
2083d0407baSopenharmony_ci        .resources = &rtc_resources[0],
2093d0407baSopenharmony_ci    },
2103d0407baSopenharmony_ci    {
2113d0407baSopenharmony_ci        .name = "rk805-pwrkey",
2123d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rk805_key_resources),
2133d0407baSopenharmony_ci        .resources = &rk805_key_resources[0],
2143d0407baSopenharmony_ci    },
2153d0407baSopenharmony_ci};
2163d0407baSopenharmony_ci
2173d0407baSopenharmony_cistatic const struct mfd_cell rk808s[] = {
2183d0407baSopenharmony_ci    {
2193d0407baSopenharmony_ci        .name = "rk808-clkout",
2203d0407baSopenharmony_ci    },
2213d0407baSopenharmony_ci    {
2223d0407baSopenharmony_ci        .name = "rk808-regulator",
2233d0407baSopenharmony_ci    },
2243d0407baSopenharmony_ci    {
2253d0407baSopenharmony_ci        .name = "rk808-rtc",
2263d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rtc_resources),
2273d0407baSopenharmony_ci        .resources = rtc_resources,
2283d0407baSopenharmony_ci    },
2293d0407baSopenharmony_ci};
2303d0407baSopenharmony_ci
2313d0407baSopenharmony_cistatic const struct mfd_cell rk816s[] = {
2323d0407baSopenharmony_ci    {
2333d0407baSopenharmony_ci        .name = "rk808-clkout",
2343d0407baSopenharmony_ci    },
2353d0407baSopenharmony_ci    {
2363d0407baSopenharmony_ci        .name = "rk808-regulator",
2373d0407baSopenharmony_ci    },
2383d0407baSopenharmony_ci    {
2393d0407baSopenharmony_ci        .name = "rk805-pinctrl",
2403d0407baSopenharmony_ci    },
2413d0407baSopenharmony_ci    {
2423d0407baSopenharmony_ci        .name = "rk816-battery",
2433d0407baSopenharmony_ci        .of_compatible = "rk816-battery",
2443d0407baSopenharmony_ci    },
2453d0407baSopenharmony_ci    {
2463d0407baSopenharmony_ci        .name = "rk805-pwrkey",
2473d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rk816_pwrkey_resources),
2483d0407baSopenharmony_ci        .resources = &rk816_pwrkey_resources[0],
2493d0407baSopenharmony_ci    },
2503d0407baSopenharmony_ci    {
2513d0407baSopenharmony_ci        .name = "rk808-rtc",
2523d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rk816_rtc_resources),
2533d0407baSopenharmony_ci        .resources = &rk816_rtc_resources[0],
2543d0407baSopenharmony_ci    },
2553d0407baSopenharmony_ci};
2563d0407baSopenharmony_ci
2573d0407baSopenharmony_cistatic const struct mfd_cell rk817s[] = {
2583d0407baSopenharmony_ci    {
2593d0407baSopenharmony_ci        .name = "rk808-clkout",
2603d0407baSopenharmony_ci    },
2613d0407baSopenharmony_ci    {
2623d0407baSopenharmony_ci        .name = "rk808-regulator",
2633d0407baSopenharmony_ci    },
2643d0407baSopenharmony_ci    {
2653d0407baSopenharmony_ci        .name = "rk817-battery",
2663d0407baSopenharmony_ci        .of_compatible = "rk817,battery",
2673d0407baSopenharmony_ci    },
2683d0407baSopenharmony_ci    {
2693d0407baSopenharmony_ci        .name = "rk817-charger",
2703d0407baSopenharmony_ci        .of_compatible = "rk817,charger",
2713d0407baSopenharmony_ci    },
2723d0407baSopenharmony_ci    {
2733d0407baSopenharmony_ci        .name = "rk805-pwrkey",
2743d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
2753d0407baSopenharmony_ci        .resources = &rk817_pwrkey_resources[0],
2763d0407baSopenharmony_ci    },
2773d0407baSopenharmony_ci    {
2783d0407baSopenharmony_ci        .name = "rk808-rtc",
2793d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rk817_rtc_resources),
2803d0407baSopenharmony_ci        .resources = &rk817_rtc_resources[0],
2813d0407baSopenharmony_ci    },
2823d0407baSopenharmony_ci    {
2833d0407baSopenharmony_ci        .name = "rk817-codec",
2843d0407baSopenharmony_ci        .of_compatible = "rockchip,rk817-codec",
2853d0407baSopenharmony_ci    },
2863d0407baSopenharmony_ci};
2873d0407baSopenharmony_ci
2883d0407baSopenharmony_cistatic const struct mfd_cell rk818s[] = {
2893d0407baSopenharmony_ci    {
2903d0407baSopenharmony_ci        .name = "rk808-clkout",
2913d0407baSopenharmony_ci    },
2923d0407baSopenharmony_ci    {
2933d0407baSopenharmony_ci        .name = "rk808-regulator",
2943d0407baSopenharmony_ci    },
2953d0407baSopenharmony_ci    {
2963d0407baSopenharmony_ci        .name = "rk818-battery",
2973d0407baSopenharmony_ci        .of_compatible = "rk818-battery",
2983d0407baSopenharmony_ci    },
2993d0407baSopenharmony_ci    {
3003d0407baSopenharmony_ci        .name = "rk818-charger",
3013d0407baSopenharmony_ci    },
3023d0407baSopenharmony_ci    {
3033d0407baSopenharmony_ci        .name = "rk808-rtc",
3043d0407baSopenharmony_ci        .num_resources = ARRAY_SIZE(rtc_resources),
3053d0407baSopenharmony_ci        .resources = rtc_resources,
3063d0407baSopenharmony_ci    },
3073d0407baSopenharmony_ci};
3083d0407baSopenharmony_ci
3093d0407baSopenharmony_cistatic const struct rk808_reg_data rk805_pre_init_reg[] = {
3103d0407baSopenharmony_ci    {RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
3113d0407baSopenharmony_ci    {RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN},
3123d0407baSopenharmony_ci    {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
3133d0407baSopenharmony_ci    {RK808_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
3143d0407baSopenharmony_ci};
3153d0407baSopenharmony_ci
3163d0407baSopenharmony_cistatic struct rk808_reg_data rk805_suspend_reg[] = {
3173d0407baSopenharmony_ci    {RK805_BUCK3_CONFIG_REG, PWM_MODE_MSK, AUTO_PWM_MODE},
3183d0407baSopenharmony_ci};
3193d0407baSopenharmony_ci
3203d0407baSopenharmony_cistatic struct rk808_reg_data rk805_resume_reg[] = {
3213d0407baSopenharmony_ci    {RK805_BUCK3_CONFIG_REG, PWM_MODE_MSK, FPWM_MODE},
3223d0407baSopenharmony_ci};
3233d0407baSopenharmony_ci
3243d0407baSopenharmony_cistatic const struct rk808_reg_data rk808_pre_init_reg[] = {
3253d0407baSopenharmony_ci    {RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA},
3263d0407baSopenharmony_ci    {RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA},
3273d0407baSopenharmony_ci    {RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA},
3283d0407baSopenharmony_ci    {RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK, BUCK_ILMIN_200MA},
3293d0407baSopenharmony_ci    {RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_200MA},
3303d0407baSopenharmony_ci    {RK808_DCDC_UV_ACT_REG, BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE},
3313d0407baSopenharmony_ci    {RK808_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
3323d0407baSopenharmony_ci    {RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | VB_LO_SEL_3500MV},
3333d0407baSopenharmony_ci};
3343d0407baSopenharmony_ci
3353d0407baSopenharmony_cistatic const struct rk808_reg_data rk816_pre_init_reg[] = {
3363d0407baSopenharmony_ci    /* buck4 Max ILMIT */
3373d0407baSopenharmony_ci    {RK816_BUCK4_CONFIG_REG, REG_WRITE_MSK, BUCK4_MAX_ILIMIT},
3383d0407baSopenharmony_ci    /* hotdie temperature: 105c */
3393d0407baSopenharmony_ci    {RK816_THERMAL_REG, REG_WRITE_MSK, TEMP105C},
3403d0407baSopenharmony_ci    /* set buck 12.5mv/us */
3413d0407baSopenharmony_ci    {RK816_BUCK1_CONFIG_REG, BUCK_RATE_MSK, BUCK_RATE_12_5MV_US},
3423d0407baSopenharmony_ci    {RK816_BUCK2_CONFIG_REG, BUCK_RATE_MSK, BUCK_RATE_12_5MV_US},
3433d0407baSopenharmony_ci    /* enable RTC_PERIOD & RTC_ALARM int */
3443d0407baSopenharmony_ci    {RK816_INT_STS_MSK_REG2, REG_WRITE_MSK, RTC_PERIOD_ALARM_INT_EN},
3453d0407baSopenharmony_ci    /* set bat 3.0 low and act shutdown */
3463d0407baSopenharmony_ci    {RK816_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK, RK816_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN},
3473d0407baSopenharmony_ci    /* enable PWRON rising/faling int */
3483d0407baSopenharmony_ci    {RK816_INT_STS_MSK_REG1, REG_WRITE_MSK, RK816_PWRON_FALL_RISE_INT_EN},
3493d0407baSopenharmony_ci    /* enable PLUG IN/OUT int */
3503d0407baSopenharmony_ci    {RK816_INT_STS_MSK_REG3, REG_WRITE_MSK, PLUGIN_OUT_INT_EN},
3513d0407baSopenharmony_ci    /* clear int flags */
3523d0407baSopenharmony_ci    {RK816_INT_STS_REG1, REG_WRITE_MSK, ALL_INT_FLAGS_ST},
3533d0407baSopenharmony_ci    {RK816_INT_STS_REG2, REG_WRITE_MSK, ALL_INT_FLAGS_ST},
3543d0407baSopenharmony_ci    {RK816_INT_STS_REG3, REG_WRITE_MSK, ALL_INT_FLAGS_ST},
3553d0407baSopenharmony_ci    {RK816_DCDC_EN_REG2, BOOST_EN_MASK, BOOST_DISABLE},
3563d0407baSopenharmony_ci    /* set write mask bit 1, otherwise 'is_enabled()' get wrong status */
3573d0407baSopenharmony_ci    {RK816_LDO_EN_REG1, REGS_WMSK, REGS_WMSK},
3583d0407baSopenharmony_ci    {RK816_LDO_EN_REG2, REGS_WMSK, REGS_WMSK},
3593d0407baSopenharmony_ci};
3603d0407baSopenharmony_ci
3613d0407baSopenharmony_cistatic const struct rk808_reg_data rk817_pre_init_reg[] = {
3623d0407baSopenharmony_ci    {RK817_SYS_CFG(3), RK817_SLPPOL_MSK, RK817_SLPPOL_L},
3633d0407baSopenharmony_ci    {RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
3643d0407baSopenharmony_ci    {RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
3653d0407baSopenharmony_ci    {RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK, RK817_HOTDIE_105 | RK817_TSD_140},
3663d0407baSopenharmony_ci};
3673d0407baSopenharmony_ci
3683d0407baSopenharmony_cistatic const struct rk808_reg_data rk818_pre_init_reg[] = {
3693d0407baSopenharmony_ci    /* improve efficiency */
3703d0407baSopenharmony_ci    {RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_250MA},
3713d0407baSopenharmony_ci    {RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_250MA},
3723d0407baSopenharmony_ci    {RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA},
3733d0407baSopenharmony_ci    {RK818_USB_CTRL_REG, RK818_USB_ILIM_SEL_MASK, RK818_USB_ILMIN_2000MA},
3743d0407baSopenharmony_ci    /* close charger when usb lower then 3.4V */
3753d0407baSopenharmony_ci    {RK818_USB_CTRL_REG, RK818_USB_CHG_SD_VSEL_MASK, (0x7 << 4)},
3763d0407baSopenharmony_ci    /* no action when vref */
3773d0407baSopenharmony_ci    {RK818_H5V_EN_REG, BIT(1), RK818_REF_RDY_CTRL},
3783d0407baSopenharmony_ci    /* enable HDMI 5V */
3793d0407baSopenharmony_ci    {RK818_H5V_EN_REG, BIT(0), RK818_H5V_EN},
3803d0407baSopenharmony_ci    {RK808_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
3813d0407baSopenharmony_ci    {RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | VB_LO_SEL_3500MV},
3823d0407baSopenharmony_ci    {RK808_CLK32OUT_REG, CLK32KOUT2_FUNC_MASK, CLK32KOUT2_FUNC},
3833d0407baSopenharmony_ci};
3843d0407baSopenharmony_ci
3853d0407baSopenharmony_cistatic const struct regmap_irq rk805_irqs[] = {
3863d0407baSopenharmony_ci    [RK805_IRQ_PWRON_RISE] =
3873d0407baSopenharmony_ci        {
3883d0407baSopenharmony_ci            .mask = RK805_IRQ_PWRON_RISE_MSK,
3893d0407baSopenharmony_ci            .reg_offset = 0,
3903d0407baSopenharmony_ci        },
3913d0407baSopenharmony_ci    [RK805_IRQ_VB_LOW] =
3923d0407baSopenharmony_ci        {
3933d0407baSopenharmony_ci            .mask = RK805_IRQ_VB_LOW_MSK,
3943d0407baSopenharmony_ci            .reg_offset = 0,
3953d0407baSopenharmony_ci        },
3963d0407baSopenharmony_ci    [RK805_IRQ_PWRON] =
3973d0407baSopenharmony_ci        {
3983d0407baSopenharmony_ci            .mask = RK805_IRQ_PWRON_MSK,
3993d0407baSopenharmony_ci            .reg_offset = 0,
4003d0407baSopenharmony_ci        },
4013d0407baSopenharmony_ci    [RK805_IRQ_PWRON_LP] =
4023d0407baSopenharmony_ci        {
4033d0407baSopenharmony_ci            .mask = RK805_IRQ_PWRON_LP_MSK,
4043d0407baSopenharmony_ci            .reg_offset = 0,
4053d0407baSopenharmony_ci        },
4063d0407baSopenharmony_ci    [RK805_IRQ_HOTDIE] =
4073d0407baSopenharmony_ci        {
4083d0407baSopenharmony_ci            .mask = RK805_IRQ_HOTDIE_MSK,
4093d0407baSopenharmony_ci            .reg_offset = 0,
4103d0407baSopenharmony_ci        },
4113d0407baSopenharmony_ci    [RK805_IRQ_RTC_ALARM] =
4123d0407baSopenharmony_ci        {
4133d0407baSopenharmony_ci            .mask = RK805_IRQ_RTC_ALARM_MSK,
4143d0407baSopenharmony_ci            .reg_offset = 0,
4153d0407baSopenharmony_ci        },
4163d0407baSopenharmony_ci    [RK805_IRQ_RTC_PERIOD] =
4173d0407baSopenharmony_ci        {
4183d0407baSopenharmony_ci            .mask = RK805_IRQ_RTC_PERIOD_MSK,
4193d0407baSopenharmony_ci            .reg_offset = 0,
4203d0407baSopenharmony_ci        },
4213d0407baSopenharmony_ci    [RK805_IRQ_PWRON_FALL] =
4223d0407baSopenharmony_ci        {
4233d0407baSopenharmony_ci            .mask = RK805_IRQ_PWRON_FALL_MSK,
4243d0407baSopenharmony_ci            .reg_offset = 0,
4253d0407baSopenharmony_ci        },
4263d0407baSopenharmony_ci};
4273d0407baSopenharmony_ci
4283d0407baSopenharmony_cistatic const struct regmap_irq rk808_irqs[] = {
4293d0407baSopenharmony_ci    /* INT_STS */
4303d0407baSopenharmony_ci    [RK808_IRQ_VOUT_LO] =
4313d0407baSopenharmony_ci        {
4323d0407baSopenharmony_ci            .mask = RK808_IRQ_VOUT_LO_MSK,
4333d0407baSopenharmony_ci            .reg_offset = 0,
4343d0407baSopenharmony_ci        },
4353d0407baSopenharmony_ci    [RK808_IRQ_VB_LO] =
4363d0407baSopenharmony_ci        {
4373d0407baSopenharmony_ci            .mask = RK808_IRQ_VB_LO_MSK,
4383d0407baSopenharmony_ci            .reg_offset = 0,
4393d0407baSopenharmony_ci        },
4403d0407baSopenharmony_ci    [RK808_IRQ_PWRON] =
4413d0407baSopenharmony_ci        {
4423d0407baSopenharmony_ci            .mask = RK808_IRQ_PWRON_MSK,
4433d0407baSopenharmony_ci            .reg_offset = 0,
4443d0407baSopenharmony_ci        },
4453d0407baSopenharmony_ci    [RK808_IRQ_PWRON_LP] =
4463d0407baSopenharmony_ci        {
4473d0407baSopenharmony_ci            .mask = RK808_IRQ_PWRON_LP_MSK,
4483d0407baSopenharmony_ci            .reg_offset = 0,
4493d0407baSopenharmony_ci        },
4503d0407baSopenharmony_ci    [RK808_IRQ_HOTDIE] =
4513d0407baSopenharmony_ci        {
4523d0407baSopenharmony_ci            .mask = RK808_IRQ_HOTDIE_MSK,
4533d0407baSopenharmony_ci            .reg_offset = 0,
4543d0407baSopenharmony_ci        },
4553d0407baSopenharmony_ci    [RK808_IRQ_RTC_ALARM] =
4563d0407baSopenharmony_ci        {
4573d0407baSopenharmony_ci            .mask = RK808_IRQ_RTC_ALARM_MSK,
4583d0407baSopenharmony_ci            .reg_offset = 0,
4593d0407baSopenharmony_ci        },
4603d0407baSopenharmony_ci    [RK808_IRQ_RTC_PERIOD] =
4613d0407baSopenharmony_ci        {
4623d0407baSopenharmony_ci            .mask = RK808_IRQ_RTC_PERIOD_MSK,
4633d0407baSopenharmony_ci            .reg_offset = 0,
4643d0407baSopenharmony_ci        },
4653d0407baSopenharmony_ci
4663d0407baSopenharmony_ci    /* INT_STS2 */
4673d0407baSopenharmony_ci    [RK808_IRQ_PLUG_IN_INT] =
4683d0407baSopenharmony_ci        {
4693d0407baSopenharmony_ci            .mask = RK808_IRQ_PLUG_IN_INT_MSK,
4703d0407baSopenharmony_ci            .reg_offset = 1,
4713d0407baSopenharmony_ci        },
4723d0407baSopenharmony_ci    [RK808_IRQ_PLUG_OUT_INT] =
4733d0407baSopenharmony_ci        {
4743d0407baSopenharmony_ci            .mask = RK808_IRQ_PLUG_OUT_INT_MSK,
4753d0407baSopenharmony_ci            .reg_offset = 1,
4763d0407baSopenharmony_ci        },
4773d0407baSopenharmony_ci};
4783d0407baSopenharmony_ci
4793d0407baSopenharmony_cistatic struct rk808_reg_data rk816_suspend_reg[] = {
4803d0407baSopenharmony_ci    /* set bat 3.4v low and act irq */
4813d0407baSopenharmony_ci    {RK816_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK, RK816_VBAT_LOW_3V4 | EN_VBAT_LOW_IRQ},
4823d0407baSopenharmony_ci};
4833d0407baSopenharmony_ci
4843d0407baSopenharmony_cistatic struct rk808_reg_data rk816_resume_reg[] = {
4853d0407baSopenharmony_ci    /* set bat 3.0v low and act shutdown */
4863d0407baSopenharmony_ci    {RK816_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK, RK816_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN},
4873d0407baSopenharmony_ci};
4883d0407baSopenharmony_ci
4893d0407baSopenharmony_cistatic const struct regmap_irq rk816_irqs[] = {
4903d0407baSopenharmony_ci    /* INT_STS */
4913d0407baSopenharmony_ci    [RK816_IRQ_PWRON_FALL] =
4923d0407baSopenharmony_ci        {
4933d0407baSopenharmony_ci            .mask = RK816_IRQ_PWRON_FALL_MSK,
4943d0407baSopenharmony_ci            .reg_offset = 0,
4953d0407baSopenharmony_ci        },
4963d0407baSopenharmony_ci    [RK816_IRQ_PWRON_RISE] =
4973d0407baSopenharmony_ci        {
4983d0407baSopenharmony_ci            .mask = RK816_IRQ_PWRON_RISE_MSK,
4993d0407baSopenharmony_ci            .reg_offset = 0,
5003d0407baSopenharmony_ci        },
5013d0407baSopenharmony_ci    [RK816_IRQ_VB_LOW] =
5023d0407baSopenharmony_ci        {
5033d0407baSopenharmony_ci            .mask = RK816_IRQ_VB_LOW_MSK,
5043d0407baSopenharmony_ci            .reg_offset = 1,
5053d0407baSopenharmony_ci        },
5063d0407baSopenharmony_ci    [RK816_IRQ_PWRON] =
5073d0407baSopenharmony_ci        {
5083d0407baSopenharmony_ci            .mask = RK816_IRQ_PWRON_MSK,
5093d0407baSopenharmony_ci            .reg_offset = 1,
5103d0407baSopenharmony_ci        },
5113d0407baSopenharmony_ci    [RK816_IRQ_PWRON_LP] =
5123d0407baSopenharmony_ci        {
5133d0407baSopenharmony_ci            .mask = RK816_IRQ_PWRON_LP_MSK,
5143d0407baSopenharmony_ci            .reg_offset = 1,
5153d0407baSopenharmony_ci        },
5163d0407baSopenharmony_ci    [RK816_IRQ_HOTDIE] =
5173d0407baSopenharmony_ci        {
5183d0407baSopenharmony_ci            .mask = RK816_IRQ_HOTDIE_MSK,
5193d0407baSopenharmony_ci            .reg_offset = 1,
5203d0407baSopenharmony_ci        },
5213d0407baSopenharmony_ci    [RK816_IRQ_RTC_ALARM] =
5223d0407baSopenharmony_ci        {
5233d0407baSopenharmony_ci            .mask = RK816_IRQ_RTC_ALARM_MSK,
5243d0407baSopenharmony_ci            .reg_offset = 1,
5253d0407baSopenharmony_ci        },
5263d0407baSopenharmony_ci    [RK816_IRQ_RTC_PERIOD] =
5273d0407baSopenharmony_ci        {
5283d0407baSopenharmony_ci            .mask = RK816_IRQ_RTC_PERIOD_MSK,
5293d0407baSopenharmony_ci            .reg_offset = 1,
5303d0407baSopenharmony_ci        },
5313d0407baSopenharmony_ci    [RK816_IRQ_USB_OV] =
5323d0407baSopenharmony_ci        {
5333d0407baSopenharmony_ci            .mask = RK816_IRQ_USB_OV_MSK,
5343d0407baSopenharmony_ci            .reg_offset = 1,
5353d0407baSopenharmony_ci        },
5363d0407baSopenharmony_ci};
5373d0407baSopenharmony_ci
5383d0407baSopenharmony_cistatic struct rk808_reg_data rk818_suspend_reg[] = {
5393d0407baSopenharmony_ci    /* set bat 3.4v low and act irq */
5403d0407baSopenharmony_ci    {RK808_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK, RK808_VBAT_LOW_3V4 | EN_VBAT_LOW_IRQ},
5413d0407baSopenharmony_ci};
5423d0407baSopenharmony_ci
5433d0407baSopenharmony_cistatic struct rk808_reg_data rk818_resume_reg[] = {
5443d0407baSopenharmony_ci    /* set bat 3.0v low and act shutdown */
5453d0407baSopenharmony_ci    {RK808_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK, RK808_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN},
5463d0407baSopenharmony_ci};
5473d0407baSopenharmony_ci
5483d0407baSopenharmony_cistatic const struct regmap_irq rk818_irqs[] = {
5493d0407baSopenharmony_ci    /* INT_STS */
5503d0407baSopenharmony_ci    [RK818_IRQ_VOUT_LO] =
5513d0407baSopenharmony_ci        {
5523d0407baSopenharmony_ci            .mask = RK818_IRQ_VOUT_LO_MSK,
5533d0407baSopenharmony_ci            .reg_offset = 0,
5543d0407baSopenharmony_ci        },
5553d0407baSopenharmony_ci    [RK818_IRQ_VB_LO] =
5563d0407baSopenharmony_ci        {
5573d0407baSopenharmony_ci            .mask = RK818_IRQ_VB_LO_MSK,
5583d0407baSopenharmony_ci            .reg_offset = 0,
5593d0407baSopenharmony_ci        },
5603d0407baSopenharmony_ci    [RK818_IRQ_PWRON] =
5613d0407baSopenharmony_ci        {
5623d0407baSopenharmony_ci            .mask = RK818_IRQ_PWRON_MSK,
5633d0407baSopenharmony_ci            .reg_offset = 0,
5643d0407baSopenharmony_ci        },
5653d0407baSopenharmony_ci    [RK818_IRQ_PWRON_LP] =
5663d0407baSopenharmony_ci        {
5673d0407baSopenharmony_ci            .mask = RK818_IRQ_PWRON_LP_MSK,
5683d0407baSopenharmony_ci            .reg_offset = 0,
5693d0407baSopenharmony_ci        },
5703d0407baSopenharmony_ci    [RK818_IRQ_HOTDIE] =
5713d0407baSopenharmony_ci        {
5723d0407baSopenharmony_ci            .mask = RK818_IRQ_HOTDIE_MSK,
5733d0407baSopenharmony_ci            .reg_offset = 0,
5743d0407baSopenharmony_ci        },
5753d0407baSopenharmony_ci    [RK818_IRQ_RTC_ALARM] =
5763d0407baSopenharmony_ci        {
5773d0407baSopenharmony_ci            .mask = RK818_IRQ_RTC_ALARM_MSK,
5783d0407baSopenharmony_ci            .reg_offset = 0,
5793d0407baSopenharmony_ci        },
5803d0407baSopenharmony_ci    [RK818_IRQ_RTC_PERIOD] =
5813d0407baSopenharmony_ci        {
5823d0407baSopenharmony_ci            .mask = RK818_IRQ_RTC_PERIOD_MSK,
5833d0407baSopenharmony_ci            .reg_offset = 0,
5843d0407baSopenharmony_ci        },
5853d0407baSopenharmony_ci    [RK818_IRQ_USB_OV] =
5863d0407baSopenharmony_ci        {
5873d0407baSopenharmony_ci            .mask = RK818_IRQ_USB_OV_MSK,
5883d0407baSopenharmony_ci            .reg_offset = 0,
5893d0407baSopenharmony_ci        },
5903d0407baSopenharmony_ci
5913d0407baSopenharmony_ci    /* INT_STS2 */
5923d0407baSopenharmony_ci    [RK818_IRQ_PLUG_IN] =
5933d0407baSopenharmony_ci        {
5943d0407baSopenharmony_ci            .mask = RK818_IRQ_PLUG_IN_MSK,
5953d0407baSopenharmony_ci            .reg_offset = 1,
5963d0407baSopenharmony_ci        },
5973d0407baSopenharmony_ci    [RK818_IRQ_PLUG_OUT] =
5983d0407baSopenharmony_ci        {
5993d0407baSopenharmony_ci            .mask = RK818_IRQ_PLUG_OUT_MSK,
6003d0407baSopenharmony_ci            .reg_offset = 1,
6013d0407baSopenharmony_ci        },
6023d0407baSopenharmony_ci    [RK818_IRQ_CHG_OK] =
6033d0407baSopenharmony_ci        {
6043d0407baSopenharmony_ci            .mask = RK818_IRQ_CHG_OK_MSK,
6053d0407baSopenharmony_ci            .reg_offset = 1,
6063d0407baSopenharmony_ci        },
6073d0407baSopenharmony_ci    [RK818_IRQ_CHG_TE] =
6083d0407baSopenharmony_ci        {
6093d0407baSopenharmony_ci            .mask = RK818_IRQ_CHG_TE_MSK,
6103d0407baSopenharmony_ci            .reg_offset = 1,
6113d0407baSopenharmony_ci        },
6123d0407baSopenharmony_ci    [RK818_IRQ_CHG_TS1] =
6133d0407baSopenharmony_ci        {
6143d0407baSopenharmony_ci            .mask = RK818_IRQ_CHG_TS1_MSK,
6153d0407baSopenharmony_ci            .reg_offset = 1,
6163d0407baSopenharmony_ci        },
6173d0407baSopenharmony_ci    [RK818_IRQ_TS2] =
6183d0407baSopenharmony_ci        {
6193d0407baSopenharmony_ci            .mask = RK818_IRQ_TS2_MSK,
6203d0407baSopenharmony_ci            .reg_offset = 1,
6213d0407baSopenharmony_ci        },
6223d0407baSopenharmony_ci    [RK818_IRQ_CHG_CVTLIM] =
6233d0407baSopenharmony_ci        {
6243d0407baSopenharmony_ci            .mask = RK818_IRQ_CHG_CVTLIM_MSK,
6253d0407baSopenharmony_ci            .reg_offset = 1,
6263d0407baSopenharmony_ci        },
6273d0407baSopenharmony_ci    [RK818_IRQ_DISCHG_ILIM] =
6283d0407baSopenharmony_ci        {
6293d0407baSopenharmony_ci            .mask = RK818_IRQ_DISCHG_ILIM_MSK,
6303d0407baSopenharmony_ci            .reg_offset = 1,
6313d0407baSopenharmony_ci        },
6323d0407baSopenharmony_ci};
6333d0407baSopenharmony_ci
6343d0407baSopenharmony_cistatic const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
6353d0407baSopenharmony_ci    REGMAP_IRQ_REG_LINE(0, 8),  REGMAP_IRQ_REG_LINE(1, 8),  REGMAP_IRQ_REG_LINE(2, 8),  REGMAP_IRQ_REG_LINE(3, 8),
6363d0407baSopenharmony_ci    REGMAP_IRQ_REG_LINE(4, 8),  REGMAP_IRQ_REG_LINE(5, 8),  REGMAP_IRQ_REG_LINE(6, 8),  REGMAP_IRQ_REG_LINE(7, 8),
6373d0407baSopenharmony_ci    REGMAP_IRQ_REG_LINE(8, 8),  REGMAP_IRQ_REG_LINE(9, 8),  REGMAP_IRQ_REG_LINE(10, 8), REGMAP_IRQ_REG_LINE(11, 8),
6383d0407baSopenharmony_ci    REGMAP_IRQ_REG_LINE(12, 8), REGMAP_IRQ_REG_LINE(13, 8), REGMAP_IRQ_REG_LINE(14, 8), REGMAP_IRQ_REG_LINE(15, 8),
6393d0407baSopenharmony_ci    REGMAP_IRQ_REG_LINE(16, 8), REGMAP_IRQ_REG_LINE(17, 8), REGMAP_IRQ_REG_LINE(18, 8), REGMAP_IRQ_REG_LINE(19, 8),
6403d0407baSopenharmony_ci    REGMAP_IRQ_REG_LINE(20, 8), REGMAP_IRQ_REG_LINE(21, 8), REGMAP_IRQ_REG_LINE(22, 8), REGMAP_IRQ_REG_LINE(23, 8)};
6413d0407baSopenharmony_ci
6423d0407baSopenharmony_cistatic struct regmap_irq_chip rk805_irq_chip = {
6433d0407baSopenharmony_ci    .name = "rk805",
6443d0407baSopenharmony_ci    .irqs = rk805_irqs,
6453d0407baSopenharmony_ci    .num_irqs = ARRAY_SIZE(rk805_irqs),
6463d0407baSopenharmony_ci    .num_regs = 1,
6473d0407baSopenharmony_ci    .status_base = RK805_INT_STS_REG,
6483d0407baSopenharmony_ci    .mask_base = RK805_INT_STS_MSK_REG,
6493d0407baSopenharmony_ci    .ack_base = RK805_INT_STS_REG,
6503d0407baSopenharmony_ci    .init_ack_masked = true,
6513d0407baSopenharmony_ci};
6523d0407baSopenharmony_ci
6533d0407baSopenharmony_cistatic const struct regmap_irq_chip rk808_irq_chip = {
6543d0407baSopenharmony_ci    .name = "rk808",
6553d0407baSopenharmony_ci    .irqs = rk808_irqs,
6563d0407baSopenharmony_ci    .num_irqs = ARRAY_SIZE(rk808_irqs),
6573d0407baSopenharmony_ci    .num_regs = 2,
6583d0407baSopenharmony_ci    .irq_reg_stride = 2,
6593d0407baSopenharmony_ci    .status_base = RK808_INT_STS_REG1,
6603d0407baSopenharmony_ci    .mask_base = RK808_INT_STS_MSK_REG1,
6613d0407baSopenharmony_ci    .ack_base = RK808_INT_STS_REG1,
6623d0407baSopenharmony_ci    .init_ack_masked = true,
6633d0407baSopenharmony_ci};
6643d0407baSopenharmony_ci
6653d0407baSopenharmony_cistatic const struct regmap_irq rk816_battery_irqs[] = {
6663d0407baSopenharmony_ci    /* INT_STS */
6673d0407baSopenharmony_ci    [RK816_IRQ_PLUG_IN] =
6683d0407baSopenharmony_ci        {
6693d0407baSopenharmony_ci            .mask = RK816_IRQ_PLUG_IN_MSK,
6703d0407baSopenharmony_ci            .reg_offset = 0,
6713d0407baSopenharmony_ci        },
6723d0407baSopenharmony_ci    [RK816_IRQ_PLUG_OUT] =
6733d0407baSopenharmony_ci        {
6743d0407baSopenharmony_ci            .mask = RK816_IRQ_PLUG_OUT_MSK,
6753d0407baSopenharmony_ci            .reg_offset = 0,
6763d0407baSopenharmony_ci        },
6773d0407baSopenharmony_ci    [RK816_IRQ_CHG_OK] =
6783d0407baSopenharmony_ci        {
6793d0407baSopenharmony_ci            .mask = RK816_IRQ_CHG_OK_MSK,
6803d0407baSopenharmony_ci            .reg_offset = 0,
6813d0407baSopenharmony_ci        },
6823d0407baSopenharmony_ci    [RK816_IRQ_CHG_TE] =
6833d0407baSopenharmony_ci        {
6843d0407baSopenharmony_ci            .mask = RK816_IRQ_CHG_TE_MSK,
6853d0407baSopenharmony_ci            .reg_offset = 0,
6863d0407baSopenharmony_ci        },
6873d0407baSopenharmony_ci    [RK816_IRQ_CHG_TS] =
6883d0407baSopenharmony_ci        {
6893d0407baSopenharmony_ci            .mask = RK816_IRQ_CHG_TS_MSK,
6903d0407baSopenharmony_ci            .reg_offset = 0,
6913d0407baSopenharmony_ci        },
6923d0407baSopenharmony_ci    [RK816_IRQ_CHG_CVTLIM] =
6933d0407baSopenharmony_ci        {
6943d0407baSopenharmony_ci            .mask = RK816_IRQ_CHG_CVTLIM_MSK,
6953d0407baSopenharmony_ci            .reg_offset = 0,
6963d0407baSopenharmony_ci        },
6973d0407baSopenharmony_ci    [RK816_IRQ_DISCHG_ILIM] =
6983d0407baSopenharmony_ci        {
6993d0407baSopenharmony_ci            .mask = RK816_IRQ_DISCHG_ILIM_MSK,
7003d0407baSopenharmony_ci            .reg_offset = 0,
7013d0407baSopenharmony_ci        },
7023d0407baSopenharmony_ci};
7033d0407baSopenharmony_ci
7043d0407baSopenharmony_cistatic struct regmap_irq_chip rk816_irq_chip = {
7053d0407baSopenharmony_ci    .name = "rk816",
7063d0407baSopenharmony_ci    .irqs = rk816_irqs,
7073d0407baSopenharmony_ci    .num_irqs = ARRAY_SIZE(rk816_irqs),
7083d0407baSopenharmony_ci    .num_regs = 2,
7093d0407baSopenharmony_ci    .irq_reg_stride = 3,
7103d0407baSopenharmony_ci    .status_base = RK816_INT_STS_REG1,
7113d0407baSopenharmony_ci    .mask_base = RK816_INT_STS_MSK_REG1,
7123d0407baSopenharmony_ci    .ack_base = RK816_INT_STS_REG1,
7133d0407baSopenharmony_ci    .init_ack_masked = true,
7143d0407baSopenharmony_ci};
7153d0407baSopenharmony_ci
7163d0407baSopenharmony_cistatic struct regmap_irq_chip rk816_battery_irq_chip = {
7173d0407baSopenharmony_ci    .name = "rk816_battery",
7183d0407baSopenharmony_ci    .irqs = rk816_battery_irqs,
7193d0407baSopenharmony_ci    .num_irqs = ARRAY_SIZE(rk816_battery_irqs),
7203d0407baSopenharmony_ci    .num_regs = 1,
7213d0407baSopenharmony_ci    .status_base = RK816_INT_STS_REG3,
7223d0407baSopenharmony_ci    .mask_base = RK816_INT_STS_MSK_REG3,
7233d0407baSopenharmony_ci    .ack_base = RK816_INT_STS_REG3,
7243d0407baSopenharmony_ci    .init_ack_masked = true,
7253d0407baSopenharmony_ci};
7263d0407baSopenharmony_ci
7273d0407baSopenharmony_cistatic struct regmap_irq_chip rk817_irq_chip = {
7283d0407baSopenharmony_ci    .name = "rk817",
7293d0407baSopenharmony_ci    .irqs = rk817_irqs,
7303d0407baSopenharmony_ci    .num_irqs = ARRAY_SIZE(rk817_irqs),
7313d0407baSopenharmony_ci    .num_regs = 3,
7323d0407baSopenharmony_ci    .irq_reg_stride = 2,
7333d0407baSopenharmony_ci    .status_base = RK817_INT_STS_REG0,
7343d0407baSopenharmony_ci    .mask_base = RK817_INT_STS_MSK_REG0,
7353d0407baSopenharmony_ci    .ack_base = RK817_INT_STS_REG0,
7363d0407baSopenharmony_ci    .init_ack_masked = true,
7373d0407baSopenharmony_ci};
7383d0407baSopenharmony_ci
7393d0407baSopenharmony_cistatic const struct regmap_irq_chip rk818_irq_chip = {
7403d0407baSopenharmony_ci    .name = "rk818",
7413d0407baSopenharmony_ci    .irqs = rk818_irqs,
7423d0407baSopenharmony_ci    .num_irqs = ARRAY_SIZE(rk818_irqs),
7433d0407baSopenharmony_ci    .num_regs = 2,
7443d0407baSopenharmony_ci    .irq_reg_stride = 2,
7453d0407baSopenharmony_ci    .status_base = RK818_INT_STS_REG1,
7463d0407baSopenharmony_ci    .mask_base = RK818_INT_STS_MSK_REG1,
7473d0407baSopenharmony_ci    .ack_base = RK818_INT_STS_REG1,
7483d0407baSopenharmony_ci    .init_ack_masked = true,
7493d0407baSopenharmony_ci};
7503d0407baSopenharmony_ci
7513d0407baSopenharmony_cistatic struct i2c_client *rk808_i2c_client;
7523d0407baSopenharmony_cistatic struct rk808_reg_data *suspend_reg, *resume_reg;
7533d0407baSopenharmony_cistatic int suspend_reg_num, resume_reg_num;
7543d0407baSopenharmony_ci
7553d0407baSopenharmony_cistatic void rk805_device_shutdown_prepare(void)
7563d0407baSopenharmony_ci{
7573d0407baSopenharmony_ci    int ret;
7583d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
7593d0407baSopenharmony_ci
7603d0407baSopenharmony_ci    if (!rk808) {
7613d0407baSopenharmony_ci        return;
7623d0407baSopenharmony_ci    }
7633d0407baSopenharmony_ci
7643d0407baSopenharmony_ci    ret = regmap_update_bits(rk808->regmap, RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SHUTDOWN_FUN);
7653d0407baSopenharmony_ci    if (ret) {
7663d0407baSopenharmony_ci        dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
7673d0407baSopenharmony_ci    }
7683d0407baSopenharmony_ci}
7693d0407baSopenharmony_ci
7703d0407baSopenharmony_cistatic void rk817_shutdown_prepare(void)
7713d0407baSopenharmony_ci{
7723d0407baSopenharmony_ci    int ret;
7733d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
7743d0407baSopenharmony_ci
7753d0407baSopenharmony_ci    /* close rtc int when power off */
7763d0407baSopenharmony_ci    regmap_update_bits(rk808->regmap, RK817_INT_STS_MSK_REG0, (RK_REG_VAL_THREE << RK_REG_SHIFT_MASK_FIVE),
7773d0407baSopenharmony_ci                       (RK_REG_VAL_THREE << RK_REG_SHIFT_MASK_FIVE));
7783d0407baSopenharmony_ci    regmap_update_bits(rk808->regmap, RK817_RTC_INT_REG, (RK_REG_VAL_THREE << RK_REG_SHIFT_MASK_TWO),
7793d0407baSopenharmony_ci                       (RK_REG_VAL_ZERO << RK_REG_SHIFT_MASK_TWO));
7803d0407baSopenharmony_ci
7813d0407baSopenharmony_ci    if (rk808->pins && rk808->pins->p && rk808->pins->power_off) {
7823d0407baSopenharmony_ci        ret =
7833d0407baSopenharmony_ci            regmap_update_bits(rk808->regmap, RK817_SYS_CFG(RK_REG_VAL_THREE), RK817_SLPPIN_FUNC_MSK, SLPPIN_NULL_FUN);
7843d0407baSopenharmony_ci        if (ret) {
7853d0407baSopenharmony_ci            pr_err("shutdown: config SLPPIN_NULL_FUN error!\n");
7863d0407baSopenharmony_ci        }
7873d0407baSopenharmony_ci
7883d0407baSopenharmony_ci        ret = regmap_update_bits(rk808->regmap, RK817_SYS_CFG(RK_REG_VAL_THREE), RK817_SLPPOL_MSK, RK817_SLPPOL_H);
7893d0407baSopenharmony_ci        if (ret) {
7903d0407baSopenharmony_ci            pr_err("shutdown: config RK817_SLPPOL_H error!\n");
7913d0407baSopenharmony_ci        }
7923d0407baSopenharmony_ci
7933d0407baSopenharmony_ci        ret = pinctrl_select_state(rk808->pins->p, rk808->pins->power_off);
7943d0407baSopenharmony_ci        if (ret) {
7953d0407baSopenharmony_ci            pr_info("%s:failed to activate pwroff state\n", __func__);
7963d0407baSopenharmony_ci        }
7973d0407baSopenharmony_ci    }
7983d0407baSopenharmony_ci
7993d0407baSopenharmony_ci    /* pmic sleep shutdown function */
8003d0407baSopenharmony_ci    ret = regmap_update_bits(rk808->regmap, RK817_SYS_CFG(RK_REG_VAL_THREE), RK817_SLPPIN_FUNC_MSK, SLPPIN_DN_FUN);
8013d0407baSopenharmony_ci    if (ret) {
8023d0407baSopenharmony_ci        dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
8033d0407baSopenharmony_ci    }
8043d0407baSopenharmony_ci    /* pmic need the SCL clock to synchronize register */
8053d0407baSopenharmony_ci    mdelay(RK_DELAY_COUNT_TWO_MS);
8063d0407baSopenharmony_ci}
8073d0407baSopenharmony_ci
8083d0407baSopenharmony_cistatic void rk8xx_device_shutdown(void)
8093d0407baSopenharmony_ci{
8103d0407baSopenharmony_ci    int ret;
8113d0407baSopenharmony_ci    unsigned int reg, bit;
8123d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
8133d0407baSopenharmony_ci
8143d0407baSopenharmony_ci    switch (rk808->variant) {
8153d0407baSopenharmony_ci        case RK805_ID:
8163d0407baSopenharmony_ci            reg = RK805_DEV_CTRL_REG;
8173d0407baSopenharmony_ci            bit = DEV_OFF;
8183d0407baSopenharmony_ci            break;
8193d0407baSopenharmony_ci        case RK808_ID:
8203d0407baSopenharmony_ci            reg = RK808_DEVCTRL_REG, bit = DEV_OFF_RST;
8213d0407baSopenharmony_ci            break;
8223d0407baSopenharmony_ci        case RK816_ID:
8233d0407baSopenharmony_ci            reg = RK816_DEV_CTRL_REG;
8243d0407baSopenharmony_ci            bit = DEV_OFF;
8253d0407baSopenharmony_ci            break;
8263d0407baSopenharmony_ci        case RK818_ID:
8273d0407baSopenharmony_ci            reg = RK818_DEVCTRL_REG;
8283d0407baSopenharmony_ci            bit = DEV_OFF;
8293d0407baSopenharmony_ci            break;
8303d0407baSopenharmony_ci        default:
8313d0407baSopenharmony_ci            return;
8323d0407baSopenharmony_ci    }
8333d0407baSopenharmony_ci
8343d0407baSopenharmony_ci    ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
8353d0407baSopenharmony_ci    if (ret) {
8363d0407baSopenharmony_ci        dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
8373d0407baSopenharmony_ci    }
8383d0407baSopenharmony_ci}
8393d0407baSopenharmony_ci
8403d0407baSopenharmony_ci/* Called in syscore shutdown */
8413d0407baSopenharmony_cistatic void (*pm_shutdown)(void);
8423d0407baSopenharmony_ci
8433d0407baSopenharmony_cistatic void rk8xx_syscore_shutdown(void)
8443d0407baSopenharmony_ci{
8453d0407baSopenharmony_ci    int ret;
8463d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
8473d0407baSopenharmony_ci
8483d0407baSopenharmony_ci    if (!rk808) {
8493d0407baSopenharmony_ci        dev_warn(&rk808_i2c_client->dev, "have no rk808, so do nothing here\n");
8503d0407baSopenharmony_ci        return;
8513d0407baSopenharmony_ci    }
8523d0407baSopenharmony_ci
8533d0407baSopenharmony_ci    /* close rtc int when power off */
8543d0407baSopenharmony_ci    regmap_update_bits(rk808->regmap, RK808_INT_STS_MSK_REG1, (RK_REG_VAL_THREE << RK_REG_SHIFT_MASK_FIVE),
8553d0407baSopenharmony_ci                       (RK_REG_VAL_THREE << RK_REG_SHIFT_MASK_FIVE));
8563d0407baSopenharmony_ci    regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, (RK_REG_VAL_THREE << RK_REG_SHIFT_MASK_TWO),
8573d0407baSopenharmony_ci                       (RK_REG_VAL_ZERO << RK_REG_SHIFT_MASK_TWO));
8583d0407baSopenharmony_ci    /*
8593d0407baSopenharmony_ci     * For PMIC that power off supplies by write register via i2c bus,
8603d0407baSopenharmony_ci     * it's better to do power off at syscore shutdown here.
8613d0407baSopenharmony_ci     *
8623d0407baSopenharmony_ci     * Because when run to kernel's "pm_power_off" call, i2c may has
8633d0407baSopenharmony_ci     * been stopped or PMIC may not be able to get i2c transfer while
8643d0407baSopenharmony_ci     * there are too many devices are competiting.
8653d0407baSopenharmony_ci     */
8663d0407baSopenharmony_ci    if (system_state == SYSTEM_POWER_OFF) {
8673d0407baSopenharmony_ci        if (rk808->variant == RK809_ID || rk808->variant == RK817_ID) {
8683d0407baSopenharmony_ci            ret = regmap_update_bits(rk808->regmap, RK817_SYS_CFG(RK_REG_VAL_THREE), RK817_SLPPIN_FUNC_MSK,
8693d0407baSopenharmony_ci                                     SLPPIN_DN_FUN);
8703d0407baSopenharmony_ci            if (ret) {
8713d0407baSopenharmony_ci                dev_warn(&rk808_i2c_client->dev, "Cannot switch to power down function\n");
8723d0407baSopenharmony_ci            }
8733d0407baSopenharmony_ci        }
8743d0407baSopenharmony_ci
8753d0407baSopenharmony_ci        if (pm_shutdown) {
8763d0407baSopenharmony_ci            dev_info(&rk808_i2c_client->dev, "System power off\n");
8773d0407baSopenharmony_ci            pm_shutdown();
8783d0407baSopenharmony_ci            mdelay(RK_DELAY_COUNT_TEN_MS);
8793d0407baSopenharmony_ci            dev_info(&rk808_i2c_client->dev, "Power off failed !\n");
8803d0407baSopenharmony_ci            while (1) {
8813d0407baSopenharmony_ci                ;
8823d0407baSopenharmony_ci            }
8833d0407baSopenharmony_ci        }
8843d0407baSopenharmony_ci    }
8853d0407baSopenharmony_ci}
8863d0407baSopenharmony_ci
8873d0407baSopenharmony_cistatic struct syscore_ops rk808_syscore_ops = {
8883d0407baSopenharmony_ci    .shutdown = rk8xx_syscore_shutdown,
8893d0407baSopenharmony_ci};
8903d0407baSopenharmony_ci
8913d0407baSopenharmony_ci/*
8923d0407baSopenharmony_ci * RK8xx PMICs would do real power off in syscore shutdown, if "pm_power_off"
8933d0407baSopenharmony_ci * is not assigned(e.g. PSCI is not enabled), we have to provide a dummy
8943d0407baSopenharmony_ci * callback for it, otherwise there comes a halt in Reboot system call:
8953d0407baSopenharmony_ci *
8963d0407baSopenharmony_ci * if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
8973d0407baSopenharmony_ci *        cmd = LINUX_REBOOT_CMD_HALT;
8983d0407baSopenharmony_ci */
8993d0407baSopenharmony_cistatic void rk808_pm_power_off_dummy(void)
9003d0407baSopenharmony_ci{
9013d0407baSopenharmony_ci    pr_info("Dummy power off for RK8xx PMICs, should never reach here!\n");
9023d0407baSopenharmony_ci
9033d0407baSopenharmony_ci    while (1) {
9043d0407baSopenharmony_ci        ;
9053d0407baSopenharmony_ci    }
9063d0407baSopenharmony_ci}
9073d0407baSopenharmony_ci
9083d0407baSopenharmony_cistatic ssize_t rk8xx_dbg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
9093d0407baSopenharmony_ci{
9103d0407baSopenharmony_ci    int ret;
9113d0407baSopenharmony_ci    char cmd;
9123d0407baSopenharmony_ci    u32 input[2], addr, data;
9133d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
9143d0407baSopenharmony_ci
9153d0407baSopenharmony_ci    ret = sscanf(buf, "%c ", &cmd);
9163d0407baSopenharmony_ci    if (ret != RK_SSCAN_RET_RESULT_ONE) {
9173d0407baSopenharmony_ci        pr_err("Unknown command\n");
9183d0407baSopenharmony_ci        goto out;
9193d0407baSopenharmony_ci    }
9203d0407baSopenharmony_ci    switch (cmd) {
9213d0407baSopenharmony_ci        case 'w':
9223d0407baSopenharmony_ci            ret = sscanf(buf, "%c %x %x ", &cmd, &input[0], &input[1]);
9233d0407baSopenharmony_ci            if (ret != RK_SSCAN_RET_RESULT_THREE) {
9243d0407baSopenharmony_ci                pr_err("error! cmd format: echo w [addr] [value]\n");
9253d0407baSopenharmony_ci                goto out;
9263d0407baSopenharmony_ci            };
9273d0407baSopenharmony_ci            addr = input[0] & RK_INPUT_MASK;
9283d0407baSopenharmony_ci            data = input[1] & RK_INPUT_MASK;
9293d0407baSopenharmony_ci            pr_info("cmd : %c %x %x\n\n", cmd, input[0], input[1]);
9303d0407baSopenharmony_ci            regmap_write(rk808->regmap, addr, data);
9313d0407baSopenharmony_ci            regmap_read(rk808->regmap, addr, &data);
9323d0407baSopenharmony_ci            pr_info("new: %x %x\n", addr, data);
9333d0407baSopenharmony_ci            break;
9343d0407baSopenharmony_ci        case 'r':
9353d0407baSopenharmony_ci            ret = sscanf(buf, "%c %x ", &cmd, &input[0]);
9363d0407baSopenharmony_ci            if (ret != RK_SSCAN_RET_RESULT_TWO) {
9373d0407baSopenharmony_ci                pr_err("error! cmd format: echo r [addr]\n");
9383d0407baSopenharmony_ci                goto out;
9393d0407baSopenharmony_ci            };
9403d0407baSopenharmony_ci            pr_info("cmd : %c %x\n\n", cmd, input[0]);
9413d0407baSopenharmony_ci            addr = input[0] & RK_INPUT_MASK;
9423d0407baSopenharmony_ci            regmap_read(rk808->regmap, addr, &data);
9433d0407baSopenharmony_ci            pr_info("%x %x\n", input[0], data);
9443d0407baSopenharmony_ci            break;
9453d0407baSopenharmony_ci        default:
9463d0407baSopenharmony_ci            pr_err("Unknown command\n");
9473d0407baSopenharmony_ci            break;
9483d0407baSopenharmony_ci    }
9493d0407baSopenharmony_ci
9503d0407baSopenharmony_ciout:
9513d0407baSopenharmony_ci    return count;
9523d0407baSopenharmony_ci}
9533d0407baSopenharmony_ci
9543d0407baSopenharmony_cistatic int rk817_pinctrl_init(struct device *dev, struct rk808 *rk808)
9553d0407baSopenharmony_ci{
9563d0407baSopenharmony_ci    int ret;
9573d0407baSopenharmony_ci    struct platform_device *pinctrl_dev;
9583d0407baSopenharmony_ci    struct pinctrl_state *default_st;
9593d0407baSopenharmony_ci
9603d0407baSopenharmony_ci    pinctrl_dev = platform_device_alloc("rk805-pinctrl", -1);
9613d0407baSopenharmony_ci    if (!pinctrl_dev) {
9623d0407baSopenharmony_ci        dev_err(dev, "Alloc pinctrl dev failed!\n");
9633d0407baSopenharmony_ci        return -ENOMEM;
9643d0407baSopenharmony_ci    }
9653d0407baSopenharmony_ci
9663d0407baSopenharmony_ci    pinctrl_dev->dev.parent = dev;
9673d0407baSopenharmony_ci    ret = platform_device_add(pinctrl_dev);
9683d0407baSopenharmony_ci    if (ret) {
9693d0407baSopenharmony_ci        platform_device_put(pinctrl_dev);
9703d0407baSopenharmony_ci        dev_err(dev, "Add rk805-pinctrl dev failed!\n");
9713d0407baSopenharmony_ci        return ret;
9723d0407baSopenharmony_ci    }
9733d0407baSopenharmony_ci    if (dev->pins && !IS_ERR(dev->pins->p)) {
9743d0407baSopenharmony_ci        dev_info(dev, "had get a pinctrl!\n");
9753d0407baSopenharmony_ci        return 0;
9763d0407baSopenharmony_ci    }
9773d0407baSopenharmony_ci
9783d0407baSopenharmony_ci    rk808->pins = devm_kzalloc(dev, sizeof(struct rk808_pin_info), GFP_KERNEL);
9793d0407baSopenharmony_ci    if (!rk808->pins) {
9803d0407baSopenharmony_ci        return -ENOMEM;
9813d0407baSopenharmony_ci    }
9823d0407baSopenharmony_ci
9833d0407baSopenharmony_ci    rk808->pins->p = devm_pinctrl_get(dev);
9843d0407baSopenharmony_ci    if (IS_ERR(rk808->pins->p)) {
9853d0407baSopenharmony_ci        rk808->pins->p = NULL;
9863d0407baSopenharmony_ci        dev_err(dev, "no pinctrl handle\n");
9873d0407baSopenharmony_ci        return 0;
9883d0407baSopenharmony_ci    }
9893d0407baSopenharmony_ci    default_st = pinctrl_lookup_state(rk808->pins->p, PINCTRL_STATE_DEFAULT);
9903d0407baSopenharmony_ci    if (IS_ERR(default_st)) {
9913d0407baSopenharmony_ci        dev_dbg(dev, "no default pinctrl state\n");
9923d0407baSopenharmony_ci        return -EINVAL;
9933d0407baSopenharmony_ci    }
9943d0407baSopenharmony_ci
9953d0407baSopenharmony_ci    ret = pinctrl_select_state(rk808->pins->p, default_st);
9963d0407baSopenharmony_ci    if (ret) {
9973d0407baSopenharmony_ci        dev_dbg(dev, "failed to activate default pinctrl state\n");
9983d0407baSopenharmony_ci        return -EINVAL;
9993d0407baSopenharmony_ci    }
10003d0407baSopenharmony_ci
10013d0407baSopenharmony_ci    rk808->pins->power_off = pinctrl_lookup_state(rk808->pins->p, "pmic-power-off");
10023d0407baSopenharmony_ci    if (IS_ERR(rk808->pins->power_off)) {
10033d0407baSopenharmony_ci        rk808->pins->power_off = NULL;
10043d0407baSopenharmony_ci        dev_dbg(dev, "no power-off pinctrl state\n");
10053d0407baSopenharmony_ci    }
10063d0407baSopenharmony_ci
10073d0407baSopenharmony_ci    rk808->pins->sleep = pinctrl_lookup_state(rk808->pins->p, "pmic-sleep");
10083d0407baSopenharmony_ci    if (IS_ERR(rk808->pins->sleep)) {
10093d0407baSopenharmony_ci        rk808->pins->sleep = NULL;
10103d0407baSopenharmony_ci        dev_dbg(dev, "no sleep-setting state\n");
10113d0407baSopenharmony_ci    }
10123d0407baSopenharmony_ci
10133d0407baSopenharmony_ci    rk808->pins->reset = pinctrl_lookup_state(rk808->pins->p, "pmic-reset");
10143d0407baSopenharmony_ci    if (IS_ERR(rk808->pins->reset)) {
10153d0407baSopenharmony_ci        rk808->pins->reset = NULL;
10163d0407baSopenharmony_ci        dev_dbg(dev, "no reset-setting pinctrl state\n");
10173d0407baSopenharmony_ci        return 0;
10183d0407baSopenharmony_ci    }
10193d0407baSopenharmony_ci    ret = pinctrl_select_state(rk808->pins->p, rk808->pins->reset);
10203d0407baSopenharmony_ci    if (ret) {
10213d0407baSopenharmony_ci        dev_dbg(dev, "failed to activate reset-setting pinctrl state\n");
10223d0407baSopenharmony_ci    }
10233d0407baSopenharmony_ci
10243d0407baSopenharmony_ci    return 0;
10253d0407baSopenharmony_ci}
10263d0407baSopenharmony_ci
10273d0407baSopenharmony_cistruct rk817_reboot_data_t {
10283d0407baSopenharmony_ci    struct rk808 *rk808;
10293d0407baSopenharmony_ci    struct notifier_block reboot_notifier;
10303d0407baSopenharmony_ci};
10313d0407baSopenharmony_ci
10323d0407baSopenharmony_cistatic struct rk817_reboot_data_t rk817_reboot_data;
10333d0407baSopenharmony_ci
10343d0407baSopenharmony_cistatic int rk817_reboot_notifier_handler(struct notifier_block *nb, unsigned long action, void *cmd)
10353d0407baSopenharmony_ci{
10363d0407baSopenharmony_ci    struct rk817_reboot_data_t *data;
10373d0407baSopenharmony_ci    struct device *dev;
10383d0407baSopenharmony_ci    int value, power_en_active0, power_en_active1;
10393d0407baSopenharmony_ci    int ret, i;
10403d0407baSopenharmony_ci    static const char *const pmic_rst_reg_only_cmd[] = {
10413d0407baSopenharmony_ci        "loader", "bootloader", "fastboot", "recovery", "ums", "panic", "watchdog", "charge",
10423d0407baSopenharmony_ci    };
10433d0407baSopenharmony_ci
10443d0407baSopenharmony_ci    data = container_of(nb, struct rk817_reboot_data_t, reboot_notifier);
10453d0407baSopenharmony_ci    dev = &data->rk808->i2c->dev;
10463d0407baSopenharmony_ci
10473d0407baSopenharmony_ci    regmap_read(data->rk808->regmap, RK817_POWER_EN_SAVE0, &power_en_active0);
10483d0407baSopenharmony_ci    if (power_en_active0 != 0) {
10493d0407baSopenharmony_ci        regmap_read(data->rk808->regmap, RK817_POWER_EN_SAVE1, &power_en_active1);
10503d0407baSopenharmony_ci        value = power_en_active0 & RK_BYTE_LOW_FOUR_BIT_MASK;
10513d0407baSopenharmony_ci        regmap_write(data->rk808->regmap, RK817_POWER_EN_REG(RK_POWER_EN_REG_VALUE_ZERO),
10523d0407baSopenharmony_ci                     value | RK_BYTE_HIGH_FOUR_BIT_MASK);
10533d0407baSopenharmony_ci        value = (power_en_active0 & RK_BYTE_HIGH_FOUR_BIT_MASK) >> RK_BYTE_FOUR_BIT_SHIFT_MASK;
10543d0407baSopenharmony_ci        regmap_write(data->rk808->regmap, RK817_POWER_EN_REG(RK_POWER_EN_REG_VALUE_ONE),
10553d0407baSopenharmony_ci                     value | RK_BYTE_HIGH_FOUR_BIT_MASK);
10563d0407baSopenharmony_ci        value = power_en_active1 & RK_BYTE_LOW_FOUR_BIT_MASK;
10573d0407baSopenharmony_ci        regmap_write(data->rk808->regmap, RK817_POWER_EN_REG(RK_POWER_EN_REG_VALUE_TWO),
10583d0407baSopenharmony_ci                     value | RK_BYTE_HIGH_FOUR_BIT_MASK);
10593d0407baSopenharmony_ci        value = (power_en_active1 & RK_BYTE_HIGH_FOUR_BIT_MASK) >> RK_BYTE_FOUR_BIT_SHIFT_MASK;
10603d0407baSopenharmony_ci        regmap_write(data->rk808->regmap, RK817_POWER_EN_REG(RK_POWER_EN_REG_VALUE_THREE),
10613d0407baSopenharmony_ci                     value | RK_BYTE_HIGH_FOUR_BIT_MASK);
10623d0407baSopenharmony_ci    } else {
10633d0407baSopenharmony_ci        dev_info(dev, "reboot: not restore POWER_EN\n");
10643d0407baSopenharmony_ci    }
10653d0407baSopenharmony_ci
10663d0407baSopenharmony_ci    if (action != SYS_RESTART || !cmd) {
10673d0407baSopenharmony_ci        return NOTIFY_OK;
10683d0407baSopenharmony_ci    }
10693d0407baSopenharmony_ci
10703d0407baSopenharmony_ci    /*
10713d0407baSopenharmony_ci     * When system restart, there are two rst actions of PMIC sleep if
10723d0407baSopenharmony_ci     * board hardware support:
10733d0407baSopenharmony_ci     *
10743d0407baSopenharmony_ci     *    0b'00: reset the PMIC itself completely.
10753d0407baSopenharmony_ci     *    0b'01: reset the 'RST' related register only.
10763d0407baSopenharmony_ci     *
10773d0407baSopenharmony_ci     * In the case of 0b'00, PMIC reset itself which triggers SoC NPOR-reset
10783d0407baSopenharmony_ci     * at the same time, so the command: reboot load/bootload/recovery, etc
10793d0407baSopenharmony_ci     * is not effect any more.
10803d0407baSopenharmony_ci     *
10813d0407baSopenharmony_ci     * Here we check if this reboot cmd is what we expect for 0b'01.
10823d0407baSopenharmony_ci     */
10833d0407baSopenharmony_ci    for (i = 0; i < ARRAY_SIZE(pmic_rst_reg_only_cmd); i++) {
10843d0407baSopenharmony_ci        if (!strcmp(cmd, pmic_rst_reg_only_cmd[i])) {
10853d0407baSopenharmony_ci            ret = regmap_update_bits(data->rk808->regmap, RK817_SYS_CFG(RK_REG_VAL_THREE), RK817_RST_FUNC_MSK,
10863d0407baSopenharmony_ci                                     RK817_RST_FUNC_REG);
10873d0407baSopenharmony_ci            if (ret) {
10883d0407baSopenharmony_ci                dev_err(dev, "reboot: force RK817_RST_FUNC_REG error!\n");
10893d0407baSopenharmony_ci            } else {
10903d0407baSopenharmony_ci                dev_info(dev, "reboot: force RK817_RST_FUNC_REG ok!\n");
10913d0407baSopenharmony_ci            }
10923d0407baSopenharmony_ci            break;
10933d0407baSopenharmony_ci        }
10943d0407baSopenharmony_ci    }
10953d0407baSopenharmony_ci
10963d0407baSopenharmony_ci    return NOTIFY_OK;
10973d0407baSopenharmony_ci}
10983d0407baSopenharmony_ci
10993d0407baSopenharmony_cistatic void rk817_of_property_prepare(struct rk808 *rk808, struct device *dev)
11003d0407baSopenharmony_ci{
11013d0407baSopenharmony_ci    u32 inner;
11023d0407baSopenharmony_ci    int ret, func, msk, val;
11033d0407baSopenharmony_ci    struct device_node *np = dev->of_node;
11043d0407baSopenharmony_ci
11053d0407baSopenharmony_ci    ret = of_property_read_u32_index(np, "fb-inner-reg-idxs", 0, &inner);
11063d0407baSopenharmony_ci    if (!ret && inner == RK817_ID_DCDC3) {
11073d0407baSopenharmony_ci        regmap_update_bits(rk808->regmap, RK817_POWER_CONFIG, RK817_BUCK3_FB_RES_MSK, RK817_BUCK3_FB_RES_INTER);
11083d0407baSopenharmony_ci    } else {
11093d0407baSopenharmony_ci        regmap_update_bits(rk808->regmap, RK817_POWER_CONFIG, RK817_BUCK3_FB_RES_MSK, RK817_BUCK3_FB_RES_EXT);
11103d0407baSopenharmony_ci    }
11113d0407baSopenharmony_ci    dev_info(dev, "support dcdc3 fb mode:%d, %d\n", ret, inner);
11123d0407baSopenharmony_ci
11133d0407baSopenharmony_ci    ret = of_property_read_u32(np, "pmic-reset-func", &func);
11143d0407baSopenharmony_ci
11153d0407baSopenharmony_ci    msk = RK817_SLPPIN_FUNC_MSK | RK817_RST_FUNC_MSK;
11163d0407baSopenharmony_ci    val = SLPPIN_NULL_FUN;
11173d0407baSopenharmony_ci
11183d0407baSopenharmony_ci    if (!ret && func < RK817_RST_FUNC_CNT) {
11193d0407baSopenharmony_ci        val |= RK817_RST_FUNC_MSK & (func << RK817_RST_FUNC_SFT);
11203d0407baSopenharmony_ci    } else {
11213d0407baSopenharmony_ci        val |= RK817_RST_FUNC_REG;
11223d0407baSopenharmony_ci    }
11233d0407baSopenharmony_ci
11243d0407baSopenharmony_ci    regmap_update_bits(rk808->regmap, RK817_SYS_CFG(RK_REG_VAL_THREE), msk, val);
11253d0407baSopenharmony_ci
11263d0407baSopenharmony_ci    dev_info(dev, "support pmic reset mode:%d,%d\n", ret, func);
11273d0407baSopenharmony_ci
11283d0407baSopenharmony_ci    rk817_reboot_data.rk808 = rk808;
11293d0407baSopenharmony_ci    rk817_reboot_data.reboot_notifier.notifier_call = rk817_reboot_notifier_handler;
11303d0407baSopenharmony_ci    ret = register_reboot_notifier(&rk817_reboot_data.reboot_notifier);
11313d0407baSopenharmony_ci    if (ret) {
11323d0407baSopenharmony_ci        dev_err(dev, "failed to register reboot nb\n");
11333d0407baSopenharmony_ci    }
11343d0407baSopenharmony_ci}
11353d0407baSopenharmony_ci
11363d0407baSopenharmony_cistatic struct kobject *rk8xx_kobj;
11373d0407baSopenharmony_cistatic struct device_attribute rk8xx_attrs = __ATTR(rk8xx_dbg, 0200, NULL, rk8xx_dbg_store);
11383d0407baSopenharmony_ci
11393d0407baSopenharmony_cistatic const struct of_device_id rk808_of_match[] = {
11403d0407baSopenharmony_ci    {.compatible = "rockchip,rk805"},
11413d0407baSopenharmony_ci    {.compatible = "rockchip,rk808"},
11423d0407baSopenharmony_ci    {.compatible = "rockchip,rk809"},
11433d0407baSopenharmony_ci    {.compatible = "rockchip,rk816"},
11443d0407baSopenharmony_ci    {.compatible = "rockchip,rk817"},
11453d0407baSopenharmony_ci    {.compatible = "rockchip,rk818"},
11463d0407baSopenharmony_ci    {},
11473d0407baSopenharmony_ci};
11483d0407baSopenharmony_ciMODULE_DEVICE_TABLE(of, rk808_of_match);
11493d0407baSopenharmony_ci
11503d0407baSopenharmony_cistatic int rk808_probe(struct i2c_client *client, const struct i2c_device_id *id)
11513d0407baSopenharmony_ci{
11523d0407baSopenharmony_ci    struct device_node *np = client->dev.of_node;
11533d0407baSopenharmony_ci    struct rk808 *rk808;
11543d0407baSopenharmony_ci    const struct rk808_reg_data *pre_init_reg;
11553d0407baSopenharmony_ci    const struct regmap_irq_chip *battery_irq_chip = NULL;
11563d0407baSopenharmony_ci    const struct mfd_cell *cells;
11573d0407baSopenharmony_ci    unsigned char pmic_id_msb, pmic_id_lsb;
11583d0407baSopenharmony_ci    u8 on_source = 0, off_source = 0;
11593d0407baSopenharmony_ci    unsigned int on, off;
11603d0407baSopenharmony_ci    int pm_off = 0, msb, lsb;
11613d0407baSopenharmony_ci    int nr_pre_init_regs;
11623d0407baSopenharmony_ci    int nr_cells;
11633d0407baSopenharmony_ci    int ret;
11643d0407baSopenharmony_ci    int i;
11653d0407baSopenharmony_ci    void (*of_property_prepare_fn)(struct rk808 * rk808, struct device * dev) = NULL;
11663d0407baSopenharmony_ci    int (*pinctrl_init)(struct device * dev, struct rk808 * rk808) = NULL;
11673d0407baSopenharmony_ci    void (*device_shutdown_fn)(void) = NULL;
11683d0407baSopenharmony_ci
11693d0407baSopenharmony_ci    rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
11703d0407baSopenharmony_ci    if (!rk808) {
11713d0407baSopenharmony_ci        return -ENOMEM;
11723d0407baSopenharmony_ci    }
11733d0407baSopenharmony_ci
11743d0407baSopenharmony_ci    if (of_device_is_compatible(np, "rockchip,rk817") || of_device_is_compatible(np, "rockchip,rk809")) {
11753d0407baSopenharmony_ci        pmic_id_msb = RK817_ID_MSB;
11763d0407baSopenharmony_ci        pmic_id_lsb = RK817_ID_LSB;
11773d0407baSopenharmony_ci    } else {
11783d0407baSopenharmony_ci        pmic_id_msb = RK808_ID_MSB;
11793d0407baSopenharmony_ci        pmic_id_lsb = RK808_ID_LSB;
11803d0407baSopenharmony_ci    }
11813d0407baSopenharmony_ci
11823d0407baSopenharmony_ci    /* Read chip variant */
11833d0407baSopenharmony_ci    msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
11843d0407baSopenharmony_ci    if (msb < 0) {
11853d0407baSopenharmony_ci        dev_err(&client->dev, "failed to read the chip id at 0x%x\n", RK808_ID_MSB);
11863d0407baSopenharmony_ci        return msb;
11873d0407baSopenharmony_ci    }
11883d0407baSopenharmony_ci
11893d0407baSopenharmony_ci    lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
11903d0407baSopenharmony_ci    if (lsb < 0) {
11913d0407baSopenharmony_ci        dev_err(&client->dev, "failed to read the chip id at 0x%x\n", RK808_ID_LSB);
11923d0407baSopenharmony_ci        return lsb;
11933d0407baSopenharmony_ci    }
11943d0407baSopenharmony_ci
11953d0407baSopenharmony_ci    rk808->variant = ((msb << RK_REG_SHIFT_MASK_EIGHT) | lsb) & RK8XX_ID_MSK;
11963d0407baSopenharmony_ci    dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
11973d0407baSopenharmony_ci
11983d0407baSopenharmony_ci    switch (rk808->variant) {
11993d0407baSopenharmony_ci        case RK805_ID:
12003d0407baSopenharmony_ci            rk808->regmap_cfg = &rk805_regmap_config;
12013d0407baSopenharmony_ci            rk808->regmap_irq_chip = &rk805_irq_chip;
12023d0407baSopenharmony_ci            pre_init_reg = rk805_pre_init_reg;
12033d0407baSopenharmony_ci            nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
12043d0407baSopenharmony_ci            cells = rk805s;
12053d0407baSopenharmony_ci            nr_cells = ARRAY_SIZE(rk805s);
12063d0407baSopenharmony_ci            on_source = RK805_ON_SOURCE_REG;
12073d0407baSopenharmony_ci            off_source = RK805_OFF_SOURCE_REG;
12083d0407baSopenharmony_ci            suspend_reg = rk805_suspend_reg;
12093d0407baSopenharmony_ci            suspend_reg_num = ARRAY_SIZE(rk805_suspend_reg);
12103d0407baSopenharmony_ci            resume_reg = rk805_resume_reg;
12113d0407baSopenharmony_ci            resume_reg_num = ARRAY_SIZE(rk805_resume_reg);
12123d0407baSopenharmony_ci            device_shutdown_fn = rk8xx_device_shutdown;
12133d0407baSopenharmony_ci            rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare;
12143d0407baSopenharmony_ci            break;
12153d0407baSopenharmony_ci        case RK808_ID:
12163d0407baSopenharmony_ci            rk808->regmap_cfg = &rk808_regmap_config;
12173d0407baSopenharmony_ci            rk808->regmap_irq_chip = &rk808_irq_chip;
12183d0407baSopenharmony_ci            pre_init_reg = rk808_pre_init_reg;
12193d0407baSopenharmony_ci            nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
12203d0407baSopenharmony_ci            cells = rk808s;
12213d0407baSopenharmony_ci            nr_cells = ARRAY_SIZE(rk808s);
12223d0407baSopenharmony_ci            device_shutdown_fn = rk8xx_device_shutdown;
12233d0407baSopenharmony_ci            break;
12243d0407baSopenharmony_ci        case RK816_ID:
12253d0407baSopenharmony_ci            rk808->regmap_cfg = &rk816_regmap_config;
12263d0407baSopenharmony_ci            rk808->regmap_irq_chip = &rk816_irq_chip;
12273d0407baSopenharmony_ci            battery_irq_chip = &rk816_battery_irq_chip;
12283d0407baSopenharmony_ci            pre_init_reg = rk816_pre_init_reg;
12293d0407baSopenharmony_ci            nr_pre_init_regs = ARRAY_SIZE(rk816_pre_init_reg);
12303d0407baSopenharmony_ci            cells = rk816s;
12313d0407baSopenharmony_ci            nr_cells = ARRAY_SIZE(rk816s);
12323d0407baSopenharmony_ci            on_source = RK816_ON_SOURCE_REG;
12333d0407baSopenharmony_ci            off_source = RK816_OFF_SOURCE_REG;
12343d0407baSopenharmony_ci            suspend_reg = rk816_suspend_reg;
12353d0407baSopenharmony_ci            suspend_reg_num = ARRAY_SIZE(rk816_suspend_reg);
12363d0407baSopenharmony_ci            resume_reg = rk816_resume_reg;
12373d0407baSopenharmony_ci            resume_reg_num = ARRAY_SIZE(rk816_resume_reg);
12383d0407baSopenharmony_ci            device_shutdown_fn = rk8xx_device_shutdown;
12393d0407baSopenharmony_ci            break;
12403d0407baSopenharmony_ci        case RK818_ID:
12413d0407baSopenharmony_ci            rk808->regmap_cfg = &rk818_regmap_config;
12423d0407baSopenharmony_ci            rk808->regmap_irq_chip = &rk818_irq_chip;
12433d0407baSopenharmony_ci            pre_init_reg = rk818_pre_init_reg;
12443d0407baSopenharmony_ci            nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
12453d0407baSopenharmony_ci            cells = rk818s;
12463d0407baSopenharmony_ci            nr_cells = ARRAY_SIZE(rk818s);
12473d0407baSopenharmony_ci            on_source = RK818_ON_SOURCE_REG;
12483d0407baSopenharmony_ci            off_source = RK818_OFF_SOURCE_REG;
12493d0407baSopenharmony_ci            suspend_reg = rk818_suspend_reg;
12503d0407baSopenharmony_ci            suspend_reg_num = ARRAY_SIZE(rk818_suspend_reg);
12513d0407baSopenharmony_ci            resume_reg = rk818_resume_reg;
12523d0407baSopenharmony_ci            resume_reg_num = ARRAY_SIZE(rk818_resume_reg);
12533d0407baSopenharmony_ci            device_shutdown_fn = rk8xx_device_shutdown;
12543d0407baSopenharmony_ci            break;
12553d0407baSopenharmony_ci        case RK809_ID:
12563d0407baSopenharmony_ci        case RK817_ID:
12573d0407baSopenharmony_ci            rk808->regmap_cfg = &rk817_regmap_config;
12583d0407baSopenharmony_ci            rk808->regmap_irq_chip = &rk817_irq_chip;
12593d0407baSopenharmony_ci            pre_init_reg = rk817_pre_init_reg;
12603d0407baSopenharmony_ci            nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
12613d0407baSopenharmony_ci            cells = rk817s;
12623d0407baSopenharmony_ci            nr_cells = ARRAY_SIZE(rk817s);
12633d0407baSopenharmony_ci            on_source = RK817_ON_SOURCE_REG;
12643d0407baSopenharmony_ci            off_source = RK817_OFF_SOURCE_REG;
12653d0407baSopenharmony_ci            rk808->pm_pwroff_prep_fn = rk817_shutdown_prepare;
12663d0407baSopenharmony_ci            of_property_prepare_fn = rk817_of_property_prepare;
12673d0407baSopenharmony_ci            pinctrl_init = rk817_pinctrl_init;
12683d0407baSopenharmony_ci            break;
12693d0407baSopenharmony_ci        default:
12703d0407baSopenharmony_ci            dev_err(&client->dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
12713d0407baSopenharmony_ci            return -EINVAL;
12723d0407baSopenharmony_ci    }
12733d0407baSopenharmony_ci
12743d0407baSopenharmony_ci    rk808->i2c = client;
12753d0407baSopenharmony_ci    rk808_i2c_client = client;
12763d0407baSopenharmony_ci    i2c_set_clientdata(client, rk808);
12773d0407baSopenharmony_ci
12783d0407baSopenharmony_ci    rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
12793d0407baSopenharmony_ci    if (IS_ERR(rk808->regmap)) {
12803d0407baSopenharmony_ci        dev_err(&client->dev, "regmap initialization failed\n");
12813d0407baSopenharmony_ci        return PTR_ERR(rk808->regmap);
12823d0407baSopenharmony_ci    }
12833d0407baSopenharmony_ci
12843d0407baSopenharmony_ci    if (on_source && off_source) {
12853d0407baSopenharmony_ci        ret = regmap_read(rk808->regmap, on_source, &on);
12863d0407baSopenharmony_ci        if (ret) {
12873d0407baSopenharmony_ci            dev_err(&client->dev, "read 0x%x failed\n", on_source);
12883d0407baSopenharmony_ci            return ret;
12893d0407baSopenharmony_ci        }
12903d0407baSopenharmony_ci
12913d0407baSopenharmony_ci        ret = regmap_read(rk808->regmap, off_source, &off);
12923d0407baSopenharmony_ci        if (ret) {
12933d0407baSopenharmony_ci            dev_err(&client->dev, "read 0x%x failed\n", off_source);
12943d0407baSopenharmony_ci            return ret;
12953d0407baSopenharmony_ci        }
12963d0407baSopenharmony_ci
12973d0407baSopenharmony_ci        dev_info(&client->dev, "source: on=0x%02x, off=0x%02x\n", on, off);
12983d0407baSopenharmony_ci    }
12993d0407baSopenharmony_ci
13003d0407baSopenharmony_ci    if (!client->irq) {
13013d0407baSopenharmony_ci        dev_err(&client->dev, "No interrupt support, no core IRQ\n");
13023d0407baSopenharmony_ci        return -EINVAL;
13033d0407baSopenharmony_ci    }
13043d0407baSopenharmony_ci
13053d0407baSopenharmony_ci    if (of_property_prepare_fn) {
13063d0407baSopenharmony_ci        of_property_prepare_fn(rk808, &client->dev);
13073d0407baSopenharmony_ci    }
13083d0407baSopenharmony_ci
13093d0407baSopenharmony_ci    for (i = 0; i < nr_pre_init_regs; i++) {
13103d0407baSopenharmony_ci        ret = regmap_update_bits(rk808->regmap, pre_init_reg[i].addr, pre_init_reg[i].mask, pre_init_reg[i].value);
13113d0407baSopenharmony_ci        if (ret) {
13123d0407baSopenharmony_ci            dev_err(&client->dev, "0x%x write err\n", pre_init_reg[i].addr);
13133d0407baSopenharmony_ci            return ret;
13143d0407baSopenharmony_ci        }
13153d0407baSopenharmony_ci    }
13163d0407baSopenharmony_ci
13173d0407baSopenharmony_ci    if (pinctrl_init) {
13183d0407baSopenharmony_ci        ret = pinctrl_init(&client->dev, rk808);
13193d0407baSopenharmony_ci        if (ret) {
13203d0407baSopenharmony_ci            return ret;
13213d0407baSopenharmony_ci        }
13223d0407baSopenharmony_ci    }
13233d0407baSopenharmony_ci
13243d0407baSopenharmony_ci    ret = regmap_add_irq_chip(rk808->regmap, client->irq, IRQF_ONESHOT, -1, rk808->regmap_irq_chip, &rk808->irq_data);
13253d0407baSopenharmony_ci    if (ret) {
13263d0407baSopenharmony_ci        dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
13273d0407baSopenharmony_ci        return ret;
13283d0407baSopenharmony_ci    }
13293d0407baSopenharmony_ci
13303d0407baSopenharmony_ci    if (battery_irq_chip) {
13313d0407baSopenharmony_ci        ret = regmap_add_irq_chip(rk808->regmap, client->irq, IRQF_ONESHOT | IRQF_SHARED, -1, battery_irq_chip,
13323d0407baSopenharmony_ci                                  &rk808->battery_irq_data);
13333d0407baSopenharmony_ci        if (ret) {
13343d0407baSopenharmony_ci            dev_err(&client->dev, "Failed to add batterry irq_chip %d\n", ret);
13353d0407baSopenharmony_ci            regmap_del_irq_chip(client->irq, rk808->irq_data);
13363d0407baSopenharmony_ci            return ret;
13373d0407baSopenharmony_ci        }
13383d0407baSopenharmony_ci    }
13393d0407baSopenharmony_ci
13403d0407baSopenharmony_ci    ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, cells, nr_cells, NULL, 0,
13413d0407baSopenharmony_ci                               regmap_irq_get_domain(rk808->irq_data));
13423d0407baSopenharmony_ci    if (ret) {
13433d0407baSopenharmony_ci        dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
13443d0407baSopenharmony_ci        goto err_irq;
13453d0407baSopenharmony_ci    }
13463d0407baSopenharmony_ci
13473d0407baSopenharmony_ci    pm_off = of_property_read_bool(np, "rockchip,system-power-controller");
13483d0407baSopenharmony_ci    if (pm_off) {
13493d0407baSopenharmony_ci        if (!pm_power_off_prepare) {
13503d0407baSopenharmony_ci            pm_power_off_prepare = rk808->pm_pwroff_prep_fn;
13513d0407baSopenharmony_ci        }
13523d0407baSopenharmony_ci
13533d0407baSopenharmony_ci        if (device_shutdown_fn) {
13543d0407baSopenharmony_ci            register_syscore_ops(&rk808_syscore_ops);
13553d0407baSopenharmony_ci            /* power off system in the syscore shutdown ! */
13563d0407baSopenharmony_ci            pm_shutdown = device_shutdown_fn;
13573d0407baSopenharmony_ci        }
13583d0407baSopenharmony_ci    }
13593d0407baSopenharmony_ci
13603d0407baSopenharmony_ci    rk8xx_kobj = kobject_create_and_add("rk8xx", NULL);
13613d0407baSopenharmony_ci    if (rk8xx_kobj) {
13623d0407baSopenharmony_ci        ret = sysfs_create_file(rk8xx_kobj, &rk8xx_attrs.attr);
13633d0407baSopenharmony_ci        if (ret) {
13643d0407baSopenharmony_ci            dev_err(&client->dev, "create rk8xx sysfs error\n");
13653d0407baSopenharmony_ci        }
13663d0407baSopenharmony_ci    }
13673d0407baSopenharmony_ci
13683d0407baSopenharmony_ci    if (!pm_power_off) {
13693d0407baSopenharmony_ci        pm_power_off = rk808_pm_power_off_dummy;
13703d0407baSopenharmony_ci    }
13713d0407baSopenharmony_ci
13723d0407baSopenharmony_ci    return 0;
13733d0407baSopenharmony_ci
13743d0407baSopenharmony_cierr_irq:
13753d0407baSopenharmony_ci    regmap_del_irq_chip(client->irq, rk808->irq_data);
13763d0407baSopenharmony_ci    if (battery_irq_chip) {
13773d0407baSopenharmony_ci        regmap_del_irq_chip(client->irq, rk808->battery_irq_data);
13783d0407baSopenharmony_ci    }
13793d0407baSopenharmony_ci    return ret;
13803d0407baSopenharmony_ci}
13813d0407baSopenharmony_ci
13823d0407baSopenharmony_cistatic int rk808_remove(struct i2c_client *client)
13833d0407baSopenharmony_ci{
13843d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(client);
13853d0407baSopenharmony_ci
13863d0407baSopenharmony_ci    regmap_del_irq_chip(client->irq, rk808->irq_data);
13873d0407baSopenharmony_ci    mfd_remove_devices(&client->dev);
13883d0407baSopenharmony_ci
13893d0407baSopenharmony_ci    /**
13903d0407baSopenharmony_ci     * pm_power_off may points to a function from another module.
13913d0407baSopenharmony_ci     * Check if the pointer is set by us and only then overwrite it.
13923d0407baSopenharmony_ci     */
13933d0407baSopenharmony_ci    if (pm_power_off == rk808_pm_power_off_dummy) {
13943d0407baSopenharmony_ci        pm_power_off = NULL;
13953d0407baSopenharmony_ci    }
13963d0407baSopenharmony_ci
13973d0407baSopenharmony_ci    /**
13983d0407baSopenharmony_ci     * As above, check if the pointer is set by us before overwrite.
13993d0407baSopenharmony_ci     */
14003d0407baSopenharmony_ci    if (rk808->pm_pwroff_prep_fn && pm_power_off_prepare == rk808->pm_pwroff_prep_fn) {
14013d0407baSopenharmony_ci        pm_power_off_prepare = NULL;
14023d0407baSopenharmony_ci    }
14033d0407baSopenharmony_ci
14043d0407baSopenharmony_ci    if (pm_shutdown) {
14053d0407baSopenharmony_ci        unregister_syscore_ops(&rk808_syscore_ops);
14063d0407baSopenharmony_ci    }
14073d0407baSopenharmony_ci
14083d0407baSopenharmony_ci    return 0;
14093d0407baSopenharmony_ci}
14103d0407baSopenharmony_ci
14113d0407baSopenharmony_cistatic int __maybe_unused rk8xx_suspend(struct device *dev)
14123d0407baSopenharmony_ci{
14133d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
14143d0407baSopenharmony_ci    int i, ret = 0;
14153d0407baSopenharmony_ci    int value;
14163d0407baSopenharmony_ci
14173d0407baSopenharmony_ci    for (i = 0; i < suspend_reg_num; i++) {
14183d0407baSopenharmony_ci        ret = regmap_update_bits(rk808->regmap, suspend_reg[i].addr, suspend_reg[i].mask, suspend_reg[i].value);
14193d0407baSopenharmony_ci        if (ret) {
14203d0407baSopenharmony_ci            dev_err(dev, "0x%x write err\n", suspend_reg[i].addr);
14213d0407baSopenharmony_ci            return ret;
14223d0407baSopenharmony_ci        }
14233d0407baSopenharmony_ci    }
14243d0407baSopenharmony_ci
14253d0407baSopenharmony_ci    switch (rk808->variant) {
14263d0407baSopenharmony_ci        case RK805_ID:
14273d0407baSopenharmony_ci            ret = regmap_update_bits(rk808->regmap, RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN);
14283d0407baSopenharmony_ci            break;
14293d0407baSopenharmony_ci        case RK809_ID:
14303d0407baSopenharmony_ci        case RK817_ID:
14313d0407baSopenharmony_ci            if (rk808->pins && rk808->pins->p && rk808->pins->sleep) {
14323d0407baSopenharmony_ci                ret = regmap_update_bits(rk808->regmap, RK817_SYS_CFG(3), RK817_SLPPIN_FUNC_MSK, SLPPIN_NULL_FUN);
14333d0407baSopenharmony_ci                if (ret) {
14343d0407baSopenharmony_ci                    dev_err(dev, "suspend: config SLPPIN_NULL_FUN error!\n");
14353d0407baSopenharmony_ci                    return ret;
14363d0407baSopenharmony_ci                }
14373d0407baSopenharmony_ci
14383d0407baSopenharmony_ci                ret = regmap_update_bits(rk808->regmap, RK817_SYS_CFG(3), RK817_SLPPOL_MSK, RK817_SLPPOL_H);
14393d0407baSopenharmony_ci                if (ret) {
14403d0407baSopenharmony_ci                    dev_err(dev, "suspend: config RK817_SLPPOL_H error!\n");
14413d0407baSopenharmony_ci                    return ret;
14423d0407baSopenharmony_ci                }
14433d0407baSopenharmony_ci
14443d0407baSopenharmony_ci                /* pmic need the SCL clock to synchronize register */
14453d0407baSopenharmony_ci                regmap_read(rk808->regmap, RK817_SYS_STS, &value);
14463d0407baSopenharmony_ci                mdelay(2);
14473d0407baSopenharmony_ci                ret = pinctrl_select_state(rk808->pins->p, rk808->pins->sleep);
14483d0407baSopenharmony_ci                if (ret) {
14493d0407baSopenharmony_ci                    dev_err(dev, "failed to act slp pinctrl state\n");
14503d0407baSopenharmony_ci                    return ret;
14513d0407baSopenharmony_ci                }
14523d0407baSopenharmony_ci            }
14533d0407baSopenharmony_ci            break;
14543d0407baSopenharmony_ci        default:
14553d0407baSopenharmony_ci            break;
14563d0407baSopenharmony_ci    }
14573d0407baSopenharmony_ci
14583d0407baSopenharmony_ci    return ret;
14593d0407baSopenharmony_ci}
14603d0407baSopenharmony_ci
14613d0407baSopenharmony_cistatic int __maybe_unused rk8xx_resume(struct device *dev)
14623d0407baSopenharmony_ci{
14633d0407baSopenharmony_ci    struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
14643d0407baSopenharmony_ci    int i, ret = 0;
14653d0407baSopenharmony_ci    int value;
14663d0407baSopenharmony_ci
14673d0407baSopenharmony_ci    for (i = 0; i < resume_reg_num; i++) {
14683d0407baSopenharmony_ci        ret = regmap_update_bits(rk808->regmap, resume_reg[i].addr, resume_reg[i].mask, resume_reg[i].value);
14693d0407baSopenharmony_ci        if (ret) {
14703d0407baSopenharmony_ci            dev_err(dev, "0x%x write err\n", resume_reg[i].addr);
14713d0407baSopenharmony_ci            return ret;
14723d0407baSopenharmony_ci        }
14733d0407baSopenharmony_ci    }
14743d0407baSopenharmony_ci
14753d0407baSopenharmony_ci    switch (rk808->variant) {
14763d0407baSopenharmony_ci        case RK809_ID:
14773d0407baSopenharmony_ci        case RK817_ID:
14783d0407baSopenharmony_ci            if (rk808->pins && rk808->pins->p && rk808->pins->reset) {
14793d0407baSopenharmony_ci                ret = regmap_update_bits(rk808->regmap, RK817_SYS_CFG(3), RK817_SLPPIN_FUNC_MSK, SLPPIN_NULL_FUN);
14803d0407baSopenharmony_ci                if (ret) {
14813d0407baSopenharmony_ci                    dev_err(dev, "resume: config SLPPIN_NULL_FUN error!\n");
14823d0407baSopenharmony_ci                    return ret;
14833d0407baSopenharmony_ci                }
14843d0407baSopenharmony_ci
14853d0407baSopenharmony_ci                ret = regmap_update_bits(rk808->regmap, RK817_SYS_CFG(3), RK817_SLPPOL_MSK, RK817_SLPPOL_L);
14863d0407baSopenharmony_ci                if (ret) {
14873d0407baSopenharmony_ci                    dev_err(dev, "resume: config RK817_SLPPOL_L error!\n");
14883d0407baSopenharmony_ci                    return ret;
14893d0407baSopenharmony_ci                }
14903d0407baSopenharmony_ci
14913d0407baSopenharmony_ci                /* pmic need the SCL clock to synchronize register */
14923d0407baSopenharmony_ci                regmap_read(rk808->regmap, RK817_SYS_STS, &value);
14933d0407baSopenharmony_ci                mdelay(2);
14943d0407baSopenharmony_ci                ret = pinctrl_select_state(rk808->pins->p, rk808->pins->reset);
14953d0407baSopenharmony_ci                if (ret) {
14963d0407baSopenharmony_ci                    dev_dbg(dev, "failed to act reset pinctrl state\n");
14973d0407baSopenharmony_ci                }
14983d0407baSopenharmony_ci            }
14993d0407baSopenharmony_ci            break;
15003d0407baSopenharmony_ci        default:
15013d0407baSopenharmony_ci            break;
15023d0407baSopenharmony_ci    }
15033d0407baSopenharmony_ci
15043d0407baSopenharmony_ci    return ret;
15053d0407baSopenharmony_ci}
15063d0407baSopenharmony_ciSIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
15073d0407baSopenharmony_ci
15083d0407baSopenharmony_cistatic struct i2c_driver rk808_i2c_driver = {
15093d0407baSopenharmony_ci    .driver =
15103d0407baSopenharmony_ci        {
15113d0407baSopenharmony_ci            .name = "rk808",
15123d0407baSopenharmony_ci            .of_match_table = rk808_of_match,
15133d0407baSopenharmony_ci            .pm = &rk8xx_pm_ops,
15143d0407baSopenharmony_ci        },
15153d0407baSopenharmony_ci    .probe = rk808_probe,
15163d0407baSopenharmony_ci    .remove = rk808_remove,
15173d0407baSopenharmony_ci};
15183d0407baSopenharmony_ci
15193d0407baSopenharmony_ci#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
15203d0407baSopenharmony_cistatic int __init rk808_i2c_driver_init(void)
15213d0407baSopenharmony_ci{
15223d0407baSopenharmony_ci    return i2c_add_driver(&rk808_i2c_driver);
15233d0407baSopenharmony_ci}
15243d0407baSopenharmony_cisubsys_initcall(rk808_i2c_driver_init);
15253d0407baSopenharmony_ci
15263d0407baSopenharmony_cistatic void __exit rk808_i2c_driver_exit(void)
15273d0407baSopenharmony_ci{
15283d0407baSopenharmony_ci    i2c_del_driver(&rk808_i2c_driver);
15293d0407baSopenharmony_ci}
15303d0407baSopenharmony_cimodule_exit(rk808_i2c_driver_exit);
15313d0407baSopenharmony_ci#else
15323d0407baSopenharmony_cimodule_i2c_driver(rk808_i2c_driver);
15333d0407baSopenharmony_ci#endif
15343d0407baSopenharmony_ci
15353d0407baSopenharmony_ciMODULE_LICENSE("GPL");
15363d0407baSopenharmony_ciMODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
15373d0407baSopenharmony_ciMODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
15383d0407baSopenharmony_ciMODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
15393d0407baSopenharmony_ciMODULE_DESCRIPTION("RK808/RK818 PMIC driver");
1540