diff options
Diffstat (limited to 'drivers/staging/hikey9xx')
-rw-r--r-- | drivers/staging/hikey9xx/Kconfig | 11 | ||||
-rw-r--r-- | drivers/staging/hikey9xx/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 8 | ||||
-rw-r--r-- | drivers/staging/hikey9xx/hi6421v600-regulator.c | 299 | ||||
-rw-r--r-- | drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml | 18 |
5 files changed, 11 insertions, 326 deletions
diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig index 82bb4a22b286..c4dc1016edf2 100644 --- a/drivers/staging/hikey9xx/Kconfig +++ b/drivers/staging/hikey9xx/Kconfig @@ -39,14 +39,3 @@ config MFD_HI6421_SPMI individual components like voltage regulators under corresponding menus in order to enable them. We communicate with the Hi6421v600 via a SPMI bus. - -# to be placed at drivers/regulator -config REGULATOR_HI6421V600 - tristate "HiSilicon Hi6421v600 PMIC voltage regulator support" - depends on MFD_HI6421_SPMI && OF - depends on REGULATOR - select REGMAP - help - This driver provides support for the voltage regulators on - HiSilicon Hi6421v600 PMU / Codec IC. - This is used on Kirin 3670 boards, like HiKey 970. diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile index 1924fadac952..9103735d8377 100644 --- a/drivers/staging/hikey9xx/Makefile +++ b/drivers/staging/hikey9xx/Makefile @@ -4,4 +4,3 @@ obj-$(CONFIG_PHY_HI3670_USB) += phy-hi3670-usb3.o obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o -obj-$(CONFIG_REGULATOR_HI6421V600) += hi6421v600-regulator.o diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c index 4ebcfea9f3bf..626140cb96f2 100644 --- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c +++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c @@ -48,9 +48,9 @@ enum hi6421_spmi_pmic_irq_list { /* * The IRQs are mapped as: * - * ====================== ============= ============ ===== - * IRQ MASK REGISTER IRQ REGISTER BIT - * ====================== ============= ============ ===== + * ====================== ============= ============ ===== + * IRQ MASK REGISTER IRQ REGISTER BIT + * ====================== ============= ============ ===== * OTMP 0x0202 0x212 bit 0 * VBUS_CONNECT 0x0202 0x212 bit 1 * VBUS_DISCONNECT 0x0202 0x212 bit 2 @@ -66,7 +66,7 @@ enum hi6421_spmi_pmic_irq_list { * SIM0_HPD_F 0x0203 0x213 bit 3 * SIM1_HPD_R 0x0203 0x213 bit 4 * SIM1_HPD_F 0x0203 0x213 bit 5 - * ====================== ============= ============ ===== + * ====================== ============= ============ ===== */ #define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202 #define SOC_PMIC_IRQ0_ADDR 0x0212 diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c deleted file mode 100644 index f6a14e9c3cbf..000000000000 --- a/drivers/staging/hikey9xx/hi6421v600-regulator.c +++ /dev/null @@ -1,299 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Device driver for regulators in Hisi IC -// -// Copyright (c) 2013 Linaro Ltd. -// Copyright (c) 2011 Hisilicon. -// Copyright (c) 2020-2021 Huawei Technologies Co., Ltd -// -// Guodong Xu <guodong.xu@linaro.org> - -#include <linux/delay.h> -#include <linux/mfd/hi6421-spmi-pmic.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/regmap.h> -#include <linux/regulator/driver.h> -#include <linux/spmi.h> - -struct hi6421_spmi_reg_info { - struct regulator_desc desc; - struct hi6421_spmi_pmic *pmic; - u8 eco_mode_mask; - u32 eco_uA; - - /* Serialize regulator enable logic */ - struct mutex enable_mutex; -}; - -static const unsigned int ldo3_voltages[] = { - 1500000, 1550000, 1600000, 1650000, - 1700000, 1725000, 1750000, 1775000, - 1800000, 1825000, 1850000, 1875000, - 1900000, 1925000, 1950000, 2000000 -}; - -static const unsigned int ldo4_voltages[] = { - 1725000, 1750000, 1775000, 1800000, - 1825000, 1850000, 1875000, 1900000 -}; - -static const unsigned int ldo9_voltages[] = { - 1750000, 1800000, 1825000, 2800000, - 2850000, 2950000, 3000000, 3300000 -}; - -static const unsigned int ldo15_voltages[] = { - 1800000, 1850000, 2400000, 2600000, - 2700000, 2850000, 2950000, 3000000 -}; - -static const unsigned int ldo17_voltages[] = { - 2500000, 2600000, 2700000, 2800000, - 3000000, 3100000, 3200000, 3300000 -}; - -static const unsigned int ldo34_voltages[] = { - 2600000, 2700000, 2800000, 2900000, - 3000000, 3100000, 3200000, 3300000 -}; - -/** - * HI6421V600_LDO() - specify a LDO power line - * @_id: LDO id name string - * @vtable: voltage table - * @ereg: enable register - * @emask: enable mask - * @vreg: voltage select register - * @odelay: off/on delay time in uS - * @etime: enable time in uS - * @ecomask: eco mode mask - * @ecoamp: eco mode load uppler limit in uA - */ -#define HI6421V600_LDO(_id, vtable, ereg, emask, vreg, \ - odelay, etime, ecomask, ecoamp) \ - [HI6421V600_##_id] = { \ - .desc = { \ - .name = #_id, \ - .of_match = of_match_ptr(#_id), \ - .regulators_node = of_match_ptr("regulators"), \ - .ops = &hi6421_spmi_ldo_rops, \ - .type = REGULATOR_VOLTAGE, \ - .id = HI6421V600_##_id, \ - .owner = THIS_MODULE, \ - .volt_table = vtable, \ - .n_voltages = ARRAY_SIZE(vtable), \ - .vsel_mask = (1 << (ARRAY_SIZE(vtable) - 1)) - 1, \ - .vsel_reg = vreg, \ - .enable_reg = ereg, \ - .enable_mask = emask, \ - .enable_time = etime, \ - .ramp_delay = etime, \ - .off_on_delay = odelay, \ - }, \ - .eco_mode_mask = ecomask, \ - .eco_uA = ecoamp, \ - } - -static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) -{ - struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); - struct hi6421_spmi_pmic *pmic = sreg->pmic; - int ret; - - /* cannot enable more than one regulator at one time */ - mutex_lock(&sreg->enable_mutex); - - ret = regmap_update_bits(pmic->regmap, rdev->desc->enable_reg, - rdev->desc->enable_mask, - rdev->desc->enable_mask); - - /* Avoid powering up multiple devices at the same time */ - usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 60); - - mutex_unlock(&sreg->enable_mutex); - - return ret; -} - -static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev) -{ - struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); - struct hi6421_spmi_pmic *pmic = sreg->pmic; - - return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg, - rdev->desc->enable_mask, 0); -} - -static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) -{ - struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); - struct hi6421_spmi_pmic *pmic = sreg->pmic; - u32 reg_val; - - regmap_read(pmic->regmap, rdev->desc->enable_reg, ®_val); - - if (reg_val & sreg->eco_mode_mask) - return REGULATOR_MODE_IDLE; - - return REGULATOR_MODE_NORMAL; -} - -static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, - unsigned int mode) -{ - struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); - struct hi6421_spmi_pmic *pmic = sreg->pmic; - u32 val; - - switch (mode) { - case REGULATOR_MODE_NORMAL: - val = 0; - break; - case REGULATOR_MODE_IDLE: - val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1); - break; - default: - return -EINVAL; - } - - return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg, - sreg->eco_mode_mask, val); -} - -static unsigned int -hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev, - int input_uV, int output_uV, - int load_uA) -{ - struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); - - if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA)) - return REGULATOR_MODE_NORMAL; - - return REGULATOR_MODE_IDLE; -} - -static const struct regulator_ops hi6421_spmi_ldo_rops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = hi6421_spmi_regulator_enable, - .disable = hi6421_spmi_regulator_disable, - .list_voltage = regulator_list_voltage_table, - .map_voltage = regulator_map_voltage_iterate, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_mode = hi6421_spmi_regulator_get_mode, - .set_mode = hi6421_spmi_regulator_set_mode, - .get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode, -}; - -/* HI6421v600 regulators with known registers */ -enum hi6421_spmi_regulator_id { - HI6421V600_LDO3, - HI6421V600_LDO4, - HI6421V600_LDO9, - HI6421V600_LDO15, - HI6421V600_LDO16, - HI6421V600_LDO17, - HI6421V600_LDO33, - HI6421V600_LDO34, -}; - -static struct hi6421_spmi_reg_info regulator_info[] = { - HI6421V600_LDO(LDO3, ldo3_voltages, - 0x16, 0x01, 0x51, - 20000, 120, - 0, 0), - HI6421V600_LDO(LDO4, ldo4_voltages, - 0x17, 0x01, 0x52, - 20000, 120, - 0x10, 10000), - HI6421V600_LDO(LDO9, ldo9_voltages, - 0x1c, 0x01, 0x57, - 20000, 360, - 0x10, 10000), - HI6421V600_LDO(LDO15, ldo15_voltages, - 0x21, 0x01, 0x5c, - 20000, 360, - 0x10, 10000), - HI6421V600_LDO(LDO16, ldo15_voltages, - 0x22, 0x01, 0x5d, - 20000, 360, - 0x10, 10000), - HI6421V600_LDO(LDO17, ldo17_voltages, - 0x23, 0x01, 0x5e, - 20000, 120, - 0x10, 10000), - HI6421V600_LDO(LDO33, ldo17_voltages, - 0x32, 0x01, 0x6d, - 20000, 120, - 0, 0), - HI6421V600_LDO(LDO34, ldo34_voltages, - 0x33, 0x01, 0x6e, - 20000, 120, - 0, 0), -}; - -static int hi6421_spmi_regulator_probe(struct platform_device *pdev) -{ - struct device *pmic_dev = pdev->dev.parent; - struct regulator_config config = { }; - struct hi6421_spmi_reg_info *sreg; - struct hi6421_spmi_reg_info *info; - struct device *dev = &pdev->dev; - struct hi6421_spmi_pmic *pmic; - struct regulator_dev *rdev; - int i; - - /* - * This driver is meant to be called by hi6421-spmi-core, - * which should first set drvdata. If this doesn't happen, hit - * a warn on and return. - */ - pmic = dev_get_drvdata(pmic_dev); - if (WARN_ON(!pmic)) - return -ENODEV; - - sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); - if (!sreg) - return -ENOMEM; - - sreg->pmic = pmic; - mutex_init(&sreg->enable_mutex); - - for (i = 0; i < ARRAY_SIZE(regulator_info); i++) { - info = ®ulator_info[i]; - - config.dev = pdev->dev.parent; - config.driver_data = sreg; - config.regmap = pmic->regmap; - - rdev = devm_regulator_register(dev, &info->desc, &config); - if (IS_ERR(rdev)) { - dev_err(dev, "failed to register %s\n", - info->desc.name); - return PTR_ERR(rdev); - } - } - - return 0; -} - -static const struct platform_device_id hi6421_spmi_regulator_table[] = { - { .name = "hi6421v600-regulator" }, - {}, -}; -MODULE_DEVICE_TABLE(platform, hi6421_spmi_regulator_table); - -static struct platform_driver hi6421_spmi_regulator_driver = { - .id_table = hi6421_spmi_regulator_table, - .driver = { - .name = "hi6421v600-regulator", - }, - .probe = hi6421_spmi_regulator_probe, -}; -module_platform_driver(hi6421_spmi_regulator_driver); - -MODULE_DESCRIPTION("Hi6421v600 SPMI regulator driver"); -MODULE_LICENSE("GPL v2"); - diff --git a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml index 21f68a9c2df1..6b755039a74c 100644 --- a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml +++ b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml @@ -16,7 +16,11 @@ description: | The PMIC part is provided by drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. +allOf: + - $ref: spmi.yaml# + properties: + $nodename: pattern: "spmi@[0-9a-f]" @@ -26,13 +30,8 @@ properties: reg: maxItems: 1 - "#address-cells": - const: 2 - - "#size-cells": - const: 0 - spmi-channel: + $ref: /schemas/types.yaml#/definitions/uint32 description: | number of the Kirin 970 SPMI channel where the SPMI devices are connected. @@ -40,18 +39,16 @@ required: - compatible - reg - spmi-channel - - "#address-cells" - - "#size-cells" patternProperties: - "^pmic@[0-9a-f]$": + "@[0-9a-f]$": description: | PMIC properties, which are specific to the used SPMI PMIC device(s). When used in combination with HiSilicon 6421v600, the properties are documented at drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. -additionalProperties: false +unevaluatedProperties: false examples: - | @@ -63,7 +60,6 @@ examples: compatible = "hisilicon,kirin970-spmi-controller"; #address-cells = <2>; #size-cells = <0>; - status = "ok"; reg = <0x0 0xfff24000 0x0 0x1000>; spmi-channel = <2>; |