124 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Device driver for Hi6421 PMIC4 *5 * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.6 * http://www.hisilicon.com7 * Copyright (c) <2013-2017> Linaro Ltd.8 * https://www.linaro.org9 *10 * Author: Guodong Xu <guodong.xu@linaro.org>11 */12 13#include <linux/device.h>14#include <linux/err.h>15#include <linux/mfd/core.h>16#include <linux/mfd/hi6421-pmic.h>17#include <linux/module.h>18#include <linux/of.h>19#include <linux/platform_device.h>20#include <linux/property.h>21#include <linux/regmap.h>22 23static const struct mfd_cell hi6421_devs[] = {24 { .name = "hi6421-regulator", },25};26 27static const struct mfd_cell hi6421v530_devs[] = {28 { .name = "hi6421v530-regulator", },29};30 31static const struct regmap_config hi6421_regmap_config = {32 .reg_bits = 32,33 .reg_stride = 4,34 .val_bits = 8,35 .max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX),36};37 38static const struct of_device_id of_hi6421_pmic_match[] = {39 {40 .compatible = "hisilicon,hi6421-pmic",41 .data = (void *)HI642142 },43 {44 .compatible = "hisilicon,hi6421v530-pmic",45 .data = (void *)HI6421_V53046 },47 { },48};49MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match);50 51static int hi6421_pmic_probe(struct platform_device *pdev)52{53 struct hi6421_pmic *pmic;54 const struct mfd_cell *subdevs;55 enum hi6421_type type;56 void __iomem *base;57 int n_subdevs, ret;58 59 type = (uintptr_t)device_get_match_data(&pdev->dev);60 61 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);62 if (!pmic)63 return -ENOMEM;64 65 base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);66 if (IS_ERR(base))67 return PTR_ERR(base);68 69 pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,70 &hi6421_regmap_config);71 if (IS_ERR(pmic->regmap)) {72 dev_err(&pdev->dev, "Failed to initialise Regmap: %ld\n",73 PTR_ERR(pmic->regmap));74 return PTR_ERR(pmic->regmap);75 }76 77 platform_set_drvdata(pdev, pmic);78 79 switch (type) {80 case HI6421:81 /* set over-current protection debounce 8ms */82 regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG,83 (HI6421_OCP_DEB_SEL_MASK84 | HI6421_OCP_EN_DEBOUNCE_MASK85 | HI6421_OCP_AUTO_STOP_MASK),86 (HI6421_OCP_DEB_SEL_8MS87 | HI6421_OCP_EN_DEBOUNCE_ENABLE));88 89 subdevs = hi6421_devs;90 n_subdevs = ARRAY_SIZE(hi6421_devs);91 break;92 case HI6421_V530:93 subdevs = hi6421v530_devs;94 n_subdevs = ARRAY_SIZE(hi6421v530_devs);95 break;96 default:97 dev_err(&pdev->dev, "Unknown device type %d\n",98 (unsigned int)type);99 return -EINVAL;100 }101 102 ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,103 subdevs, n_subdevs, NULL, 0, NULL);104 if (ret) {105 dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);106 return ret;107 }108 109 return 0;110}111 112static struct platform_driver hi6421_pmic_driver = {113 .driver = {114 .name = "hi6421_pmic",115 .of_match_table = of_hi6421_pmic_match,116 },117 .probe = hi6421_pmic_probe,118};119module_platform_driver(hi6421_pmic_driver);120 121MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>");122MODULE_DESCRIPTION("Hi6421 PMIC driver");123MODULE_LICENSE("GPL v2");124