From 2c3c1048746a4622d8c89a29670120dc8fab93c4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:49:45 +0200 Subject: Adding upstream version 6.1.76. Signed-off-by: Daniel Baumann --- drivers/mfd/hi6421-pmic-core.c | 128 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 drivers/mfd/hi6421-pmic-core.c (limited to 'drivers/mfd/hi6421-pmic-core.c') diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c new file mode 100644 index 000000000..eba88b80d --- /dev/null +++ b/drivers/mfd/hi6421-pmic-core.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Device driver for Hi6421 PMIC + * + * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. + * http://www.hisilicon.com + * Copyright (c) <2013-2017> Linaro Ltd. + * https://www.linaro.org + * + * Author: Guodong Xu + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct mfd_cell hi6421_devs[] = { + { .name = "hi6421-regulator", }, +}; + +static const struct mfd_cell hi6421v530_devs[] = { + { .name = "hi6421v530-regulator", }, +}; + +static const struct regmap_config hi6421_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 8, + .max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX), +}; + +static const struct of_device_id of_hi6421_pmic_match[] = { + { + .compatible = "hisilicon,hi6421-pmic", + .data = (void *)HI6421 + }, + { + .compatible = "hisilicon,hi6421v530-pmic", + .data = (void *)HI6421_V530 + }, + { }, +}; +MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match); + +static int hi6421_pmic_probe(struct platform_device *pdev) +{ + struct hi6421_pmic *pmic; + struct resource *res; + const struct of_device_id *id; + const struct mfd_cell *subdevs; + enum hi6421_type type; + void __iomem *base; + int n_subdevs, ret; + + id = of_match_device(of_hi6421_pmic_match, &pdev->dev); + if (!id) + return -EINVAL; + type = (enum hi6421_type)id->data; + + pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, + &hi6421_regmap_config); + if (IS_ERR(pmic->regmap)) { + dev_err(&pdev->dev, "Failed to initialise Regmap: %ld\n", + PTR_ERR(pmic->regmap)); + return PTR_ERR(pmic->regmap); + } + + platform_set_drvdata(pdev, pmic); + + switch (type) { + case HI6421: + /* set over-current protection debounce 8ms */ + regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG, + (HI6421_OCP_DEB_SEL_MASK + | HI6421_OCP_EN_DEBOUNCE_MASK + | HI6421_OCP_AUTO_STOP_MASK), + (HI6421_OCP_DEB_SEL_8MS + | HI6421_OCP_EN_DEBOUNCE_ENABLE)); + + subdevs = hi6421_devs; + n_subdevs = ARRAY_SIZE(hi6421_devs); + break; + case HI6421_V530: + subdevs = hi6421v530_devs; + n_subdevs = ARRAY_SIZE(hi6421v530_devs); + break; + default: + dev_err(&pdev->dev, "Unknown device type %d\n", + (unsigned int)type); + return -EINVAL; + } + + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, + subdevs, n_subdevs, NULL, 0, NULL); + if (ret) { + dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret); + return ret; + } + + return 0; +} + +static struct platform_driver hi6421_pmic_driver = { + .driver = { + .name = "hi6421_pmic", + .of_match_table = of_hi6421_pmic_match, + }, + .probe = hi6421_pmic_probe, +}; +module_platform_driver(hi6421_pmic_driver); + +MODULE_AUTHOR("Guodong Xu "); +MODULE_DESCRIPTION("Hi6421 PMIC driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3