0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
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");