diff options
| -rw-r--r-- | drivers/mfd/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mfd/hi6421-pmic-core.c | 113 | ||||
| -rw-r--r-- | include/linux/mfd/hi6421-pmic.h | 41 |
4 files changed, 168 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 049796a28215..609b7a2144d6 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
| @@ -210,6 +210,19 @@ config MFD_MC13XXX_I2C | |||
| 210 | help | 210 | help |
| 211 | Select this if your MC13xxx is connected via an I2C bus. | 211 | Select this if your MC13xxx is connected via an I2C bus. |
| 212 | 212 | ||
| 213 | config MFD_HI6421_PMIC | ||
| 214 | tristate "HiSilicon Hi6421 PMU/Codec IC" | ||
| 215 | depends on OF | ||
| 216 | select MFD_CORE | ||
| 217 | select REGMAP_MMIO | ||
| 218 | help | ||
| 219 | Add support for HiSilicon Hi6421 PMIC. Hi6421 includes multi- | ||
| 220 | functions, such as regulators, RTC, codec, Coulomb counter, etc. | ||
| 221 | This driver includes core APIs _only_. You have to select | ||
| 222 | individul components like voltage regulators under corresponding | ||
| 223 | menus in order to enable them. | ||
| 224 | We communicate with the Hi6421 via memory-mapped I/O. | ||
| 225 | |||
| 213 | config HTC_EGPIO | 226 | config HTC_EGPIO |
| 214 | bool "HTC EGPIO support" | 227 | bool "HTC EGPIO support" |
| 215 | depends on GPIOLIB && ARM | 228 | depends on GPIOLIB && ARM |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index bd111213bd58..1d11a247abbb 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
| @@ -172,6 +172,7 @@ obj-$(CONFIG_MFD_AS3722) += as3722.o | |||
| 172 | obj-$(CONFIG_MFD_STW481X) += stw481x.o | 172 | obj-$(CONFIG_MFD_STW481X) += stw481x.o |
| 173 | obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o | 173 | obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o |
| 174 | obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o | 174 | obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o |
| 175 | obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o | ||
| 175 | 176 | ||
| 176 | intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o | 177 | intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o |
| 177 | obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o | 178 | obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o |
diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c new file mode 100644 index 000000000000..321a2656fd00 --- /dev/null +++ b/drivers/mfd/hi6421-pmic-core.c | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | /* | ||
| 2 | * Device driver for Hi6421 IC | ||
| 3 | * | ||
| 4 | * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. | ||
| 5 | * http://www.hisilicon.com | ||
| 6 | * Copyright (c) <2013-2014> Linaro Ltd. | ||
| 7 | * http://www.linaro.org | ||
| 8 | * | ||
| 9 | * Author: Guodong Xu <guodong.xu@linaro.org> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 19 | * more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/device.h> | ||
| 26 | #include <linux/err.h> | ||
| 27 | #include <linux/mfd/core.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/of.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/regmap.h> | ||
| 32 | #include <linux/mfd/hi6421-pmic.h> | ||
| 33 | |||
| 34 | static const struct mfd_cell hi6421_devs[] = { | ||
| 35 | { .name = "hi6421-regulator", }, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static struct regmap_config hi6421_regmap_config = { | ||
| 39 | .reg_bits = 32, | ||
| 40 | .reg_stride = 4, | ||
| 41 | .val_bits = 8, | ||
| 42 | .max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX), | ||
| 43 | }; | ||
| 44 | |||
| 45 | static int hi6421_pmic_probe(struct platform_device *pdev) | ||
| 46 | { | ||
| 47 | struct hi6421_pmic *pmic; | ||
| 48 | struct resource *res; | ||
| 49 | void __iomem *base; | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); | ||
| 53 | if (!pmic) | ||
| 54 | return -ENOMEM; | ||
| 55 | |||
| 56 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 57 | base = devm_ioremap_resource(&pdev->dev, res); | ||
| 58 | if (IS_ERR(base)) | ||
| 59 | return PTR_ERR(base); | ||
| 60 | |||
| 61 | pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, | ||
| 62 | &hi6421_regmap_config); | ||
| 63 | if (IS_ERR(pmic->regmap)) { | ||
| 64 | dev_err(&pdev->dev, | ||
| 65 | "regmap init failed: %ld\n", PTR_ERR(pmic->regmap)); | ||
| 66 | return PTR_ERR(pmic->regmap); | ||
| 67 | } | ||
| 68 | |||
| 69 | /* set over-current protection debounce 8ms */ | ||
| 70 | regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG, | ||
| 71 | (HI6421_OCP_DEB_SEL_MASK | ||
| 72 | | HI6421_OCP_EN_DEBOUNCE_MASK | ||
| 73 | | HI6421_OCP_AUTO_STOP_MASK), | ||
| 74 | (HI6421_OCP_DEB_SEL_8MS | ||
| 75 | | HI6421_OCP_EN_DEBOUNCE_ENABLE)); | ||
| 76 | |||
| 77 | platform_set_drvdata(pdev, pmic); | ||
| 78 | |||
| 79 | ret = mfd_add_devices(&pdev->dev, 0, hi6421_devs, | ||
| 80 | ARRAY_SIZE(hi6421_devs), NULL, 0, NULL); | ||
| 81 | if (ret) { | ||
| 82 | dev_err(&pdev->dev, "add mfd devices failed: %d\n", ret); | ||
| 83 | return ret; | ||
| 84 | } | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int hi6421_pmic_remove(struct platform_device *pdev) | ||
| 90 | { | ||
| 91 | mfd_remove_devices(&pdev->dev); | ||
| 92 | |||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | static struct of_device_id of_hi6421_pmic_match_tbl[] = { | ||
| 97 | { .compatible = "hisilicon,hi6421-pmic", }, | ||
| 98 | { }, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct platform_driver hi6421_pmic_driver = { | ||
| 102 | .driver = { | ||
| 103 | .name = "hi6421_pmic", | ||
| 104 | .of_match_table = of_hi6421_pmic_match_tbl, | ||
| 105 | }, | ||
| 106 | .probe = hi6421_pmic_probe, | ||
| 107 | .remove = hi6421_pmic_remove, | ||
| 108 | }; | ||
| 109 | module_platform_driver(hi6421_pmic_driver); | ||
| 110 | |||
| 111 | MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>"); | ||
| 112 | MODULE_DESCRIPTION("Hi6421 PMIC driver"); | ||
| 113 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/linux/mfd/hi6421-pmic.h b/include/linux/mfd/hi6421-pmic.h new file mode 100644 index 000000000000..587273e35acf --- /dev/null +++ b/include/linux/mfd/hi6421-pmic.h | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | /* | ||
| 2 | * Header file for device driver Hi6421 PMIC | ||
| 3 | * | ||
| 4 | * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. | ||
| 5 | * http://www.hisilicon.com | ||
| 6 | * Copyright (c) <2013-2014> Linaro Ltd. | ||
| 7 | * http://www.linaro.org | ||
| 8 | * | ||
| 9 | * Author: Guodong Xu <guodong.xu@linaro.org> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #ifndef __HI6421_PMIC_H | ||
| 17 | #define __HI6421_PMIC_H | ||
| 18 | |||
| 19 | /* Hi6421 registers are mapped to memory bus in 4 bytes stride */ | ||
| 20 | #define HI6421_REG_TO_BUS_ADDR(x) (x << 2) | ||
| 21 | |||
| 22 | /* Hi6421 maximum register number */ | ||
| 23 | #define HI6421_REG_MAX 0xFF | ||
| 24 | |||
| 25 | /* Hi6421 OCP (over current protection) and DEB (debounce) control register */ | ||
| 26 | #define HI6421_OCP_DEB_CTRL_REG HI6421_REG_TO_BUS_ADDR(0x51) | ||
| 27 | #define HI6421_OCP_DEB_SEL_MASK 0x0C | ||
| 28 | #define HI6421_OCP_DEB_SEL_8MS 0x00 | ||
| 29 | #define HI6421_OCP_DEB_SEL_16MS 0x04 | ||
| 30 | #define HI6421_OCP_DEB_SEL_32MS 0x08 | ||
| 31 | #define HI6421_OCP_DEB_SEL_64MS 0x0C | ||
| 32 | #define HI6421_OCP_EN_DEBOUNCE_MASK 0x02 | ||
| 33 | #define HI6421_OCP_EN_DEBOUNCE_ENABLE 0x02 | ||
| 34 | #define HI6421_OCP_AUTO_STOP_MASK 0x01 | ||
| 35 | #define HI6421_OCP_AUTO_STOP_ENABLE 0x01 | ||
| 36 | |||
| 37 | struct hi6421_pmic { | ||
| 38 | struct regmap *regmap; | ||
| 39 | }; | ||
| 40 | |||
| 41 | #endif /* __HI6421_PMIC_H */ | ||
