Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Device driver for Hi6421 PMIC
0004  *
0005  * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
0006  *              http://www.hisilicon.com
0007  * Copyright (c) <2013-2017> Linaro Ltd.
0008  *              https://www.linaro.org
0009  *
0010  * Author: Guodong Xu <guodong.xu@linaro.org>
0011  */
0012 
0013 #include <linux/device.h>
0014 #include <linux/err.h>
0015 #include <linux/mfd/core.h>
0016 #include <linux/mfd/hi6421-pmic.h>
0017 #include <linux/module.h>
0018 #include <linux/of_device.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/regmap.h>
0021 
0022 static const struct mfd_cell hi6421_devs[] = {
0023     { .name = "hi6421-regulator", },
0024 };
0025 
0026 static const struct mfd_cell hi6421v530_devs[] = {
0027     { .name = "hi6421v530-regulator", },
0028 };
0029 
0030 static const struct regmap_config hi6421_regmap_config = {
0031     .reg_bits = 32,
0032     .reg_stride = 4,
0033     .val_bits = 8,
0034     .max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX),
0035 };
0036 
0037 static const struct of_device_id of_hi6421_pmic_match[] = {
0038     {
0039         .compatible = "hisilicon,hi6421-pmic",
0040         .data = (void *)HI6421
0041     },
0042     {
0043         .compatible = "hisilicon,hi6421v530-pmic",
0044         .data = (void *)HI6421_V530
0045     },
0046     { },
0047 };
0048 MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match);
0049 
0050 static int hi6421_pmic_probe(struct platform_device *pdev)
0051 {
0052     struct hi6421_pmic *pmic;
0053     struct resource *res;
0054     const struct of_device_id *id;
0055     const struct mfd_cell *subdevs;
0056     enum hi6421_type type;
0057     void __iomem *base;
0058     int n_subdevs, ret;
0059 
0060     id = of_match_device(of_hi6421_pmic_match, &pdev->dev);
0061     if (!id)
0062         return -EINVAL;
0063     type = (enum hi6421_type)id->data;
0064 
0065     pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
0066     if (!pmic)
0067         return -ENOMEM;
0068 
0069     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0070     base = devm_ioremap_resource(&pdev->dev, res);
0071     if (IS_ERR(base))
0072         return PTR_ERR(base);
0073 
0074     pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
0075                          &hi6421_regmap_config);
0076     if (IS_ERR(pmic->regmap)) {
0077         dev_err(&pdev->dev, "Failed to initialise Regmap: %ld\n",
0078                         PTR_ERR(pmic->regmap));
0079         return PTR_ERR(pmic->regmap);
0080     }
0081 
0082     platform_set_drvdata(pdev, pmic);
0083 
0084     switch (type) {
0085     case HI6421:
0086         /* set over-current protection debounce 8ms */
0087         regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG,
0088                 (HI6421_OCP_DEB_SEL_MASK
0089                  | HI6421_OCP_EN_DEBOUNCE_MASK
0090                  | HI6421_OCP_AUTO_STOP_MASK),
0091                 (HI6421_OCP_DEB_SEL_8MS
0092                  | HI6421_OCP_EN_DEBOUNCE_ENABLE));
0093 
0094         subdevs = hi6421_devs;
0095         n_subdevs = ARRAY_SIZE(hi6421_devs);
0096         break;
0097     case HI6421_V530:
0098         subdevs = hi6421v530_devs;
0099         n_subdevs = ARRAY_SIZE(hi6421v530_devs);
0100         break;
0101     default:
0102         dev_err(&pdev->dev, "Unknown device type %d\n",
0103                         (unsigned int)type);
0104         return -EINVAL;
0105     }
0106 
0107     ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
0108                    subdevs, n_subdevs, NULL, 0, NULL);
0109     if (ret) {
0110         dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);
0111         return ret;
0112     }
0113 
0114     return 0;
0115 }
0116 
0117 static struct platform_driver hi6421_pmic_driver = {
0118     .driver = {
0119         .name = "hi6421_pmic",
0120         .of_match_table = of_hi6421_pmic_match,
0121     },
0122     .probe  = hi6421_pmic_probe,
0123 };
0124 module_platform_driver(hi6421_pmic_driver);
0125 
0126 MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>");
0127 MODULE_DESCRIPTION("Hi6421 PMIC driver");
0128 MODULE_LICENSE("GPL v2");