diff options
Diffstat (limited to 'drivers/mfd/hi6421-pmic-core.c')
-rw-r--r-- | drivers/mfd/hi6421-pmic-core.c | 89 |
1 files changed, 57 insertions, 32 deletions
diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c index 3fd703fe3aba..6fb7ba272e09 100644 --- a/drivers/mfd/hi6421-pmic-core.c +++ b/drivers/mfd/hi6421-pmic-core.c @@ -1,40 +1,35 @@ /* - * Device driver for Hi6421 IC + * Device driver for Hi6421 PMIC * * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. * http://www.hisilicon.com - * Copyright (c) <2013-2014> Linaro Ltd. + * Copyright (c) <2013-2017> Linaro Ltd. * http://www.linaro.org * * Author: Guodong Xu <guodong.xu@linaro.org> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/device.h> #include <linux/err.h> #include <linux/mfd/core.h> +#include <linux/mfd/hi6421-pmic.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/regmap.h> -#include <linux/mfd/hi6421-pmic.h> 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, @@ -42,12 +37,33 @@ static const struct regmap_config hi6421_regmap_config = { .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 ret; + 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) @@ -61,41 +77,50 @@ static int hi6421_pmic_probe(struct platform_device *pdev) pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, &hi6421_regmap_config); if (IS_ERR(pmic->regmap)) { - dev_err(&pdev->dev, - "regmap init failed: %ld\n", PTR_ERR(pmic->regmap)); + dev_err(&pdev->dev, "Failed to initialise Regmap: %ld\n", + PTR_ERR(pmic->regmap)); return PTR_ERR(pmic->regmap); } - /* set over-current protection debounce 8ms */ - regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG, + 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)); - platform_set_drvdata(pdev, pmic); + 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, 0, hi6421_devs, - ARRAY_SIZE(hi6421_devs), NULL, 0, NULL); + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, + subdevs, n_subdevs, NULL, 0, NULL); if (ret) { - dev_err(&pdev->dev, "add mfd devices failed: %d\n", ret); + dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret); return ret; } return 0; } -static const struct of_device_id of_hi6421_pmic_match_tbl[] = { - { .compatible = "hisilicon,hi6421-pmic", }, - { }, -}; -MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match_tbl); - static struct platform_driver hi6421_pmic_driver = { .driver = { - .name = "hi6421_pmic", - .of_match_table = of_hi6421_pmic_match_tbl, + .name = "hi6421_pmic", + .of_match_table = of_hi6421_pmic_match, }, .probe = hi6421_pmic_probe, }; |