Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: hi6421-pmic: Add support for HiSilicon Hi6421v530

Add support for HiSilicon Hi6421v530 PMIC. Hi6421v530 communicates with
main SoC via memory-mapped I/O.

Hi6421v530 and Hi6421 are PMIC chips from the same vendor, HiSilicon,
but at different revisions. They share the same memory-mapped I/O
design. They differ in integrated devices, such as regulator details,
LDO voltage points.

Signed-off-by: Guodong Xu <guodong.xu@linaro.org>
Signed-off-by: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Guodong Xu and committed by
Lee Jones
ec58871f 568e5476

+57 -18
+52 -18
drivers/mfd/hi6421-pmic-core.c
··· 1 1 /* 2 - * Device driver for Hi6421 IC 2 + * Device driver for Hi6421 PMIC 3 3 * 4 4 * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. 5 5 * http://www.hisilicon.com 6 - * Copyright (c) <2013-2014> Linaro Ltd. 6 + * Copyright (c) <2013-2017> Linaro Ltd. 7 7 * http://www.linaro.org 8 8 * 9 9 * Author: Guodong Xu <guodong.xu@linaro.org> ··· 16 16 #include <linux/device.h> 17 17 #include <linux/err.h> 18 18 #include <linux/mfd/core.h> 19 + #include <linux/mfd/hi6421-pmic.h> 19 20 #include <linux/module.h> 20 - #include <linux/of.h> 21 + #include <linux/of_device.h> 21 22 #include <linux/platform_device.h> 22 23 #include <linux/regmap.h> 23 - #include <linux/mfd/hi6421-pmic.h> 24 24 25 25 static const struct mfd_cell hi6421_devs[] = { 26 26 { .name = "hi6421-regulator", }, 27 + }; 28 + 29 + static const struct mfd_cell hi6421v530_devs[] = { 30 + { .name = "hi6421v530-regulator", }, 27 31 }; 28 32 29 33 static const struct regmap_config hi6421_regmap_config = { ··· 37 33 .max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX), 38 34 }; 39 35 36 + static const struct of_device_id of_hi6421_pmic_match[] = { 37 + { 38 + .compatible = "hisilicon,hi6421-pmic", 39 + .data = (void *)HI6421 40 + }, 41 + { 42 + .compatible = "hisilicon,hi6421v530-pmic", 43 + .data = (void *)HI6421_V530 44 + }, 45 + { }, 46 + }; 47 + MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match); 48 + 40 49 static int hi6421_pmic_probe(struct platform_device *pdev) 41 50 { 42 51 struct hi6421_pmic *pmic; 43 52 struct resource *res; 53 + const struct of_device_id *id; 54 + const struct mfd_cell *subdevs; 55 + enum hi6421_type type; 44 56 void __iomem *base; 45 - int ret; 57 + int n_subdevs, ret; 58 + 59 + id = of_match_device(of_hi6421_pmic_match, &pdev->dev); 60 + if (!id) 61 + return -EINVAL; 62 + type = (enum hi6421_type)id->data; 46 63 47 64 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); 48 65 if (!pmic) ··· 82 57 return PTR_ERR(pmic->regmap); 83 58 } 84 59 85 - /* set over-current protection debounce 8ms */ 86 - regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG, 60 + platform_set_drvdata(pdev, pmic); 61 + 62 + switch (type) { 63 + case HI6421: 64 + /* set over-current protection debounce 8ms */ 65 + regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG, 87 66 (HI6421_OCP_DEB_SEL_MASK 88 67 | HI6421_OCP_EN_DEBOUNCE_MASK 89 68 | HI6421_OCP_AUTO_STOP_MASK), 90 69 (HI6421_OCP_DEB_SEL_8MS 91 70 | HI6421_OCP_EN_DEBOUNCE_ENABLE)); 92 71 93 - platform_set_drvdata(pdev, pmic); 72 + subdevs = hi6421_devs; 73 + n_subdevs = ARRAY_SIZE(hi6421_devs); 74 + break; 75 + case HI6421_V530: 76 + subdevs = hi6421v530_devs; 77 + n_subdevs = ARRAY_SIZE(hi6421v530_devs); 78 + break; 79 + default: 80 + dev_err(&pdev->dev, "Unknown device type %d\n", 81 + (unsigned int)type); 82 + return -EINVAL; 83 + } 94 84 95 - ret = devm_mfd_add_devices(&pdev->dev, 0, hi6421_devs, 96 - ARRAY_SIZE(hi6421_devs), NULL, 0, NULL); 85 + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, 86 + subdevs, n_subdevs, NULL, 0, NULL); 97 87 if (ret) { 98 88 dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret); 99 89 return ret; ··· 117 77 return 0; 118 78 } 119 79 120 - static const struct of_device_id of_hi6421_pmic_match_tbl[] = { 121 - { .compatible = "hisilicon,hi6421-pmic", }, 122 - { }, 123 - }; 124 - MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match_tbl); 125 - 126 80 static struct platform_driver hi6421_pmic_driver = { 127 81 .driver = { 128 - .name = "hi6421_pmic", 129 - .of_match_table = of_hi6421_pmic_match_tbl, 82 + .name = "hi6421_pmic", 83 + .of_match_table = of_hi6421_pmic_match, 130 84 }, 131 85 .probe = hi6421_pmic_probe, 132 86 };
+5
include/linux/mfd/hi6421-pmic.h
··· 38 38 struct regmap *regmap; 39 39 }; 40 40 41 + enum hi6421_type { 42 + HI6421 = 0, 43 + HI6421_V530, 44 + }; 45 + 41 46 #endif /* __HI6421_PMIC_H */