* [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator
@ 2015-09-30 11:05 Fei Wang
2015-09-30 11:05 ` [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver Fei Wang
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
The patch sets add support for Hi6220 PMIC Hi655x MFD core and its regulator driver.
Current testing and support board is Hikey which is one of Linaro 96boards.
It is an arm64 open source board. For more information about this board,
please access https://www.96boards.org.
This is hardware layout for access PMIC Hi655x from AP SoC Hi6220.
Between PMIC Hi655x and Hi6220, the physical signal channel is SSI.We can use memory-mapped I/O to communicate.
+----------------+ +-------------+
| | | |
| Hi6220 | SSI bus | Hi655x |
| |-------------| |
| |(REGMAP_MMIO)| |
+----------------+ +-------------+
This patchset are based on 4.3-rc1.
Fei Wang (8):
dt-bindings: pmic: Document Hi655x pmic driver
mfd: Hi655x: Add support for PMIC Hi655x MFD
arm64: dts: add Hi655x pmic node
regulator: Hi655x: Add support for Hi655x regulator
arm64: dts: Add Hi655x regulator config node
dt-bindings: mtcmos: Document Hi6220 mtcmos driver
mtcmos: Hi6220: Add Hi6220 mtcmos regulator driver
arm64: dts: Add Hi6220 mtcmos regulator node
.../devicetree/bindings/mfd/hisilicon,hi655x.txt | 80 +++
.../bindings/regulator/hisilicon,hi6220-mtcmos.txt | 32 ++
arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 275 +++++++++++
drivers/mfd/Kconfig | 9 +
drivers/mfd/Makefile | 1 +
drivers/mfd/hi655x-pmic.c | 358 ++++++++++++++
drivers/regulator/Kconfig | 16 +
drivers/regulator/Makefile | 2 +
drivers/regulator/hi6220-mtcmos.c | 281 +++++++++++
drivers/regulator/hi655x-regulator.c | 517 ++++++++++++++++++++
include/linux/mfd/hi655x-pmic.h | 56 +++
include/linux/regulator/hi655x-regulator.h | 69 +++
12 files changed, 1696 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
create mode 100644 Documentation/devicetree/bindings/regulator/hisilicon,hi6220-mtcmos.txt
create mode 100644 drivers/mfd/hi655x-pmic.c
create mode 100644 drivers/regulator/hi6220-mtcmos.c
create mode 100644 drivers/regulator/hi655x-regulator.c
create mode 100644 include/linux/mfd/hi655x-pmic.h
create mode 100644 include/linux/regulator/hi655x-regulator.h
--
1.7.9.5
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
2015-09-30 17:39 ` Mark Brown
` (2 more replies)
2015-09-30 11:05 ` [PATCH 2/8] mfd: Hi655x: Add support for PMIC Hi655x MFD Fei Wang
` (6 subsequent siblings)
7 siblings, 3 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
Document the new compatible for Hisilicon Hi655x pmic driver.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
.../devicetree/bindings/mfd/hisilicon,hi655x.txt | 80 ++++++++++++++++++++
1 file changed, 80 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
new file mode 100644
index 0000000..17bd8ca
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
@@ -0,0 +1,80 @@
+Hisilicon hi655x Power Management Integrated Circuit (PMIC)
+
+hi655x consists of a large and varied group of sub-devices:
+
+Device Supply Names Description
+------ ------------ -----------
+hi655x-powerkey : : Powerkey
+hi655x-regulator-pmic : : Regulators
+hi655x-usbvbus : : USB plug detection
+hi655x-pmu-rtc : : RTC
+hi655x-coul : : Coulomb
+
+Required properties:
+- compatible : Should be "hisilicon,hi655x-pmic-driver"
+- reg: Base address of PMIC on hi6220 soc
+- #interrupt-cells: Should be 2, is the local IRQ number for hi655x.
+- interrupt-controller: hi655x has internal IRQs (has own IRQ domain).
+- pmu_irq_gpio: should be &gpio_pmu_irq_n, is the IRQ gpio of hi655x.
+
+Example:
+ pmic: pmic at F8000000 {
+ compatible = "hisilicon,hi655x-pmic-driver";
+ reg = <0x0 0xF8000000 0x0 0x1000>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ pmu_irq_gpio = <&gpio_pmu_irq_n>;
+ status = "ok";
+
+ ponkey:ponkey at b1{
+ compatible = "hisilicon,hi655x-powerkey";
+ interrupt-parent = <&pmic>;
+ interrupts = <6 0>, <5 0>, <4 0>;
+ interrupt-names = "down", "up", "hold 1s";
+ };
+
+ coul: coul at 1 {
+ compatible = "hisilicon,hi655x-coul";
+ interrupt-parent = <&pmic>;
+ interrupts = <24 0>, <25 0>, <26 0>, <27 0>;
+ interrupt-names = "cl_int_i", "cl_out_i", "cl_in_i", "vbat_int_i";
+ battery_product_index = <0>;
+ status = "ok";
+ };
+
+ rtc: rtc at 1 {
+ compatible = "hisilicon,hi655x-pmu-rtc";
+ interrupt-parent = <&pmic>;
+ interrupts = <20 0>;
+ interrupt-names = "hi655x_pmu_rtc";
+ board_id = <1>;
+ };
+
+ usbvbus:usbvbus at b2{
+ compatible = "hisilicon,hi655x-usbvbus";
+ interrupt-parent = <&pmic>;
+ interrupts = <9 0>, <8 0>;
+ interrupt-names = "connect", "disconnect";
+ };
+
+ ldo2: regulator at a21 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3200000>;
+ hisilicon,valid-modes-mask = <0x02>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x029 0x02a 0x02b>;
+ hisilicon,ctrl-data = <0x1 0x1>;
+ hisilicon,vset-regs = <0x072>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <2500000>,<2600000>,<2700000>,<2800000>,<2900000>,<3000000>,<3100000>,<3200000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "sensor_analog";
+ };
+ };
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/8] mfd: Hi655x: Add support for PMIC Hi655x MFD
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
2015-09-30 11:05 ` [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
2015-09-30 11:05 ` [PATCH 3/8] arm64: dts: add Hi655x pmic node Fei Wang
` (5 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
Add core files for Hi655x MFD driver.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
drivers/mfd/Kconfig | 9 +
drivers/mfd/Makefile | 1 +
drivers/mfd/hi655x-pmic.c | 358 +++++++++++++++++++++++++++++++++++++++
include/linux/mfd/hi655x-pmic.h | 56 ++++++
4 files changed, 424 insertions(+)
create mode 100644 drivers/mfd/hi655x-pmic.c
create mode 100644 include/linux/mfd/hi655x-pmic.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 99d6367..d320def 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -273,6 +273,15 @@ config MFD_HI6421_PMIC
menus in order to enable them.
We communicate with the Hi6421 via memory-mapped I/O.
+config MFD_HI655X_PMIC
+ tristate "HiSilicon Hi655X series PMU/Codec IC"
+ depends on ARCH_HISI
+ depends on OF
+ select MFD_CORE
+ select REGMAP_MMIO
+ help
+ Select this option to enable Hisilicon hi655x series pmic driver.
+
config HTC_EGPIO
bool "HTC EGPIO support"
depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a59e3fc..11ec427 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -185,6 +185,7 @@ obj-$(CONFIG_MFD_STW481X) += stw481x.o
obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o
obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o
obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o
+obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o
obj-$(CONFIG_MFD_DLN2) += dln2.o
obj-$(CONFIG_MFD_RT5033) += rt5033.o
obj-$(CONFIG_MFD_SKY81452) += sky81452.o
diff --git a/drivers/mfd/hi655x-pmic.c b/drivers/mfd/hi655x-pmic.c
new file mode 100644
index 0000000..caeca4e
--- /dev/null
+++ b/drivers/mfd/hi655x-pmic.c
@@ -0,0 +1,358 @@
+/*
+ * Device driver for PMIC DRIVER in HI655X IC
+ *
+ * Copyright (c) 2015 Hisilicon Co. Ltd
+ *
+ * Fei Wang <w.f@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/irqdomain.h>
+#include <linux/mfd/hi655x-pmic.h>
+#include <linux/regmap.h>
+
+
+static const struct of_device_id of_hi655x_pmic_child_match_tbl[] = {
+ { .compatible = "hisilicon,hi655x-regulator-pmic", },
+ { .compatible = "hisilicon,hi655x-powerkey", },
+ { .compatible = "hisilicon,hi655x-usbvbus", },
+ { .compatible = "hisilicon,hi655x-coul", },
+ { .compatible = "hisilicon,hi655x-pmu-rtc", },
+ {},
+};
+
+static const struct of_device_id of_hi655x_pmic_match_tbl[] = {
+ { .compatible = "hisilicon,hi655x-pmic-driver", },
+ {},
+};
+
+static unsigned int hi655x_pmic_get_version(struct hi655x_pmic *pmic)
+{
+ u32 val;
+
+ regmap_read(pmic->regmap,
+ HI655X_REG_TO_BUS_ADDR(HI655X_VER_REG), &val);
+
+ return val;
+}
+
+static irqreturn_t hi655x_pmic_irq_handler(int irq, void *data)
+{
+ struct hi655x_pmic *pmic = (struct hi655x_pmic *)data;
+ u32 pending;
+ u32 ret = IRQ_NONE;
+ unsigned long offset;
+ int i;
+
+ for (i = 0; i < HI655X_IRQ_ARRAY; i++) {
+ regmap_read(pmic->regmap,
+ HI655X_REG_TO_BUS_ADDR(i + HI655X_IRQ_STAT_BASE),
+ &pending);
+ if (pending != 0)
+ pr_debug("pending[%d]=0x%x\n\r", i, pending);
+
+ /* clear pmic-sub-interrupt */
+ regmap_write(pmic->regmap,
+ HI655X_REG_TO_BUS_ADDR(i + HI655X_IRQ_STAT_BASE),
+ pending);
+
+ if (pending) {
+ for_each_set_bit(offset, (unsigned long *)&pending,
+ HI655X_BITS)
+ generic_handle_irq(pmic->irqs[offset +
+ i * HI655X_BITS]);
+ ret = IRQ_HANDLED;
+ }
+ }
+ return ret;
+}
+
+
+static void hi655x_pmic_irq_mask(struct irq_data *d)
+{
+
+ u32 data, offset;
+ unsigned long pmic_spin_flag = 0;
+ struct hi655x_pmic *pmic = irq_data_get_irq_chip_data(d);
+
+ offset = ((irqd_to_hwirq(d) >> 3) + HI655X_IRQ_MASK_BASE);
+ spin_lock_irqsave(&pmic->ssi_hw_lock, pmic_spin_flag);
+ regmap_read(pmic->regmap, HI655X_REG_TO_BUS_ADDR(offset), &data);
+ data |= (1 << (irqd_to_hwirq(d) & 0x07));
+ regmap_write(pmic->regmap, HI655X_REG_TO_BUS_ADDR(offset), data);
+ spin_unlock_irqrestore(&pmic->ssi_hw_lock, pmic_spin_flag);
+}
+
+static void hi655x_pmic_irq_unmask(struct irq_data *d)
+{
+ u32 data, offset;
+ unsigned long pmic_spin_flag = 0;
+ struct hi655x_pmic *pmic = irq_data_get_irq_chip_data(d);
+
+ offset = ((irqd_to_hwirq(d) >> 3) + HI655X_IRQ_MASK_BASE);
+ spin_lock_irqsave(&pmic->ssi_hw_lock, pmic_spin_flag);
+ regmap_read(pmic->regmap, HI655X_REG_TO_BUS_ADDR(offset), &data);
+ data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
+ regmap_write(pmic->regmap, HI655X_REG_TO_BUS_ADDR(offset), data);
+ spin_unlock_irqrestore(&pmic->ssi_hw_lock, pmic_spin_flag);
+}
+
+
+static struct irq_chip hi655x_pmic_irqchip = {
+ .name = "hisi-hi655x-pmic-irqchip",
+ .irq_mask = hi655x_pmic_irq_mask,
+ .irq_unmask = hi655x_pmic_irq_unmask,
+};
+
+static int hi655x_pmic_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct hi655x_pmic *pmic = d->host_data;
+
+ irq_set_chip_and_handler_name(virq, &hi655x_pmic_irqchip,
+ handle_simple_irq, "hisi-hi655x-pmic-irqchip");
+ irq_set_chip_data(virq, pmic);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
+
+ return 0;
+}
+
+static struct irq_domain_ops hi655x_domain_ops = {
+ .map = hi655x_pmic_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static inline void hi655x_pmic_clear_int(struct hi655x_pmic *pmic)
+{
+ int addr;
+
+ for (addr = HI655X_IRQ_STAT_BASE; addr < (HI655X_IRQ_STAT_BASE
+ + HI655X_IRQ_ARRAY); addr++) {
+ regmap_write(pmic->regmap,
+ HI655X_REG_TO_BUS_ADDR(addr), HI655X_IRQ_CLR);
+ }
+}
+
+static inline void hi655x_pmic_mask_int(struct hi655x_pmic *pmic)
+{
+ int addr;
+
+ for (addr = HI655X_IRQ_MASK_BASE; addr < (HI655X_IRQ_MASK_BASE
+ + HI655X_IRQ_ARRAY); addr++) {
+ regmap_write(pmic->regmap,
+ HI655X_REG_TO_BUS_ADDR(addr), HI655X_IRQ_MASK);
+ }
+}
+
+
+
+static struct regmap_config hi655x_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 8,
+ .max_register = HI655X_REG_TO_BUS_ADDR(0xFF),
+};
+
+
+static int hi655x_pmic_probe(struct platform_device *pdev)
+{
+ int i = 0;
+ int ret = 0;
+ u32 virq = 0;
+ int pmu_on = 1;
+ enum of_gpio_flags gpio_flags;
+
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct hi655x_pmic *pmic = NULL;
+ struct device_node *gpio_np = NULL;
+ void __iomem *base;
+
+ pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
+
+ /*
+ * init spin lock
+ */
+ spin_lock_init(&pmic->ssi_hw_lock);
+
+ /*
+ * get resources
+ */
+ pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!pmic->res) {
+ dev_err(dev, "platform_get_resource err\n");
+ return -ENOENT;
+ }
+ if (!devm_request_mem_region(dev, pmic->res->start,
+ resource_size(pmic->res), pdev->name)) {
+ dev_err(dev, "cannot claim register memory\n");
+ return -ENOMEM;
+ }
+ base = ioremap(pmic->res->start, resource_size(pmic->res));
+ if (!base) {
+ dev_err(dev, "cannot map register memory\n");
+ return -ENOMEM;
+ }
+ pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
+ &hi655x_regmap_config);
+
+ /*
+ * confirm pmu is exist&effective
+ */
+
+ pmic->ver = hi655x_pmic_get_version(pmic);
+ if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) {
+ dev_warn(dev, "it is wrong pmu version\n");
+ pmu_on = 0;
+ }
+
+ regmap_write(pmic->regmap, HI655X_REG_TO_BUS_ADDR(0x1b5), 0xff);
+
+ gpio_np = of_parse_phandle(np, "pmu_irq_gpio", 0);
+ if (!gpio_np) {
+ dev_err(dev, "can't parse property\n");
+ return -ENOENT;
+ }
+ pmic->gpio = of_get_gpio_flags(gpio_np, 0, &gpio_flags);
+ if (pmic->gpio < 0) {
+ dev_err(dev, "failed to of_get_gpio_flags %d\n", pmic->gpio);
+ return pmic->gpio;
+ }
+ if (!gpio_is_valid(pmic->gpio)) {
+ dev_err(dev, "it is invalid gpio %d\n", pmic->gpio);
+ return -EINVAL;
+ }
+ ret = gpio_request_one(pmic->gpio, GPIOF_IN, "hi655x_pmic_irq");
+ if (ret < 0) {
+ dev_err(dev, "failed to request gpio %d ret = %d\n",
+ pmic->gpio, ret);
+ return ret;
+ }
+ pmic->irq = gpio_to_irq(pmic->gpio);
+
+ /*
+ * clear PMIC sub-interrupt
+ */
+ hi655x_pmic_clear_int(pmic);
+
+ /*
+ * mask PMIC sub-interrupt
+ */
+ hi655x_pmic_mask_int(pmic);
+
+ /*
+ * register irq domain
+ */
+ pmic->domain = irq_domain_add_simple(np,
+ HI655X_NR_IRQ, 0, &hi655x_domain_ops, pmic);
+ if (!pmic->domain) {
+ dev_err(dev, "failed irq domain add simple!\n");
+ ret = -ENODEV;
+ goto irq_domain_add_simple;
+ }
+
+ /*
+ * here call map function
+ */
+ for (i = 0; i < HI655X_NR_IRQ; i++) {
+ virq = irq_create_mapping(pmic->domain, i);
+ if (0 == virq) {
+ dev_err(dev, "Failed mapping hwirq\n");
+ ret = -ENOSPC;
+ goto irq_create_mapping;
+ }
+ pmic->irqs[i] = virq;
+ }
+
+ /*
+ * We must make sure the GPIO status which is high.
+ */
+ if (pmu_on) {
+ ret = request_threaded_irq(pmic->irq, hi655x_pmic_irq_handler,
+ NULL, IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
+ "hi655x-pmic-irq", pmic);
+ if (ret < 0) {
+ dev_err(dev, "could not claim pmic %d\n", ret);
+ ret = -ENODEV;
+ goto request_threaded_irq;
+ }
+ }
+
+ pmic->dev = dev;
+
+ /*
+ * bind pmic to device
+ */
+ platform_set_drvdata(pdev, pmic);
+
+ /*
+ * populate sub nodes
+ */
+ of_platform_populate(np, of_hi655x_pmic_child_match_tbl, NULL, dev);
+ return 0;
+irq_domain_add_simple:
+irq_create_mapping:
+request_threaded_irq:
+ free_irq(pmic->irq, pmic);
+ gpio_free(pmic->gpio);
+ return ret;
+}
+
+static int hi655x_pmic_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct hi655x_pmic *pmic = platform_get_drvdata(pdev);
+
+ free_irq(pmic->irq, pmic);
+ gpio_free(pmic->gpio);
+ devm_release_mem_region(dev, pmic->res->start,
+ resource_size(pmic->res));
+ devm_kfree(dev, pmic);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver hi655x_pmic_driver = {
+ .driver = {
+ .name = "hisi,hi655x-pmic",
+ .owner = THIS_MODULE,
+ .of_match_table = of_hi655x_pmic_match_tbl,
+ },
+ .probe = hi655x_pmic_probe,
+ .remove = hi655x_pmic_remove,
+};
+module_platform_driver(hi655x_pmic_driver);
+
+MODULE_AUTHOR("Fei Wang <w.f@huawei.com>");
+MODULE_DESCRIPTION("Hisi hi655x pmic driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/hi655x-pmic.h b/include/linux/mfd/hi655x-pmic.h
new file mode 100644
index 0000000..e66246c
--- /dev/null
+++ b/include/linux/mfd/hi655x-pmic.h
@@ -0,0 +1,56 @@
+/*
+ * Header file for device driver Hi655X PMIC
+ *
+ * Copyright (C) 2015 Hisilicon Co. Ltd.
+ *
+ * Fei Wang <w.f@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#ifndef __HI655X_PMIC_H
+#define __HI655X_PMIC_H
+
+/* Hi655x registers are mapped to memory bus in 4 bytes stride */
+#define HI655X_REG_TO_BUS_ADDR(x) ((x) << 2)
+
+#define HI655X_BITS (8)
+
+/*numb of sub-interrupt*/
+#define HI655X_NR_IRQ (32)
+
+#define HI655X_IRQ_STAT_BASE (0x003)
+#define HI655X_IRQ_MASK_BASE (0x007)
+#define HI655X_IRQ_ARRAY (4)
+#define HI655X_IRQ_MASK (0xFF)
+#define HI655X_IRQ_CLR (0xFF)
+#define HI655X_VER_REG (0x000)
+
+#define PMU_VER_START 0x10
+#define PMU_VER_END 0x38
+
+struct hi655x_pmic {
+ struct resource *res;
+ struct device *dev;
+ struct regmap *regmap;
+ spinlock_t ssi_hw_lock;
+ struct clk *clk;
+ struct irq_domain *domain;
+ int irq;
+ int gpio;
+ unsigned int irqs[HI655X_NR_IRQ];
+ unsigned int ver;
+};
+#endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/8] arm64: dts: add Hi655x pmic node
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
2015-09-30 11:05 ` [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver Fei Wang
2015-09-30 11:05 ` [PATCH 2/8] mfd: Hi655x: Add support for PMIC Hi655x MFD Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
2015-09-30 11:05 ` [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator Fei Wang
` (4 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
This patch add Hi655x device node for pmic in dts.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 3f03380..4e4830b 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -168,4 +168,13 @@
clock-names = "uartclk", "apb_pclk";
};
};
+
+ pmic: pmic at F8000000 {
+ compatible = "hisilicon,hi655x-pmic-driver";
+ reg = <0x0 0xf8000000 0x0 0x1000>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ pmu_irq_gpio = <&gpio_pmu_irq_n>;
+ status = "ok";
+ };
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
` (2 preceding siblings ...)
2015-09-30 11:05 ` [PATCH 3/8] arm64: dts: add Hi655x pmic node Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
2015-09-30 17:58 ` Mark Brown
2015-10-08 7:47 ` Javier Martinez Canillas
2015-09-30 11:05 ` [PATCH 5/8] arm64: dts: Add Hi655x regulator config node Fei Wang
` (3 subsequent siblings)
7 siblings, 2 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
Add Hi655x regulator driver.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
drivers/regulator/Kconfig | 8 +
drivers/regulator/Makefile | 1 +
drivers/regulator/hi655x-regulator.c | 517 ++++++++++++++++++++++++++++
include/linux/regulator/hi655x-regulator.h | 69 ++++
4 files changed, 595 insertions(+)
create mode 100644 drivers/regulator/hi655x-regulator.c
create mode 100644 include/linux/regulator/hi655x-regulator.h
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 64bccff..d13210b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -261,6 +261,14 @@ config REGULATOR_HI6421
21 general purpose LDOs, 3 dedicated LDOs, and 5 BUCKs. All
of them come with support to either ECO (idle) or sleep mode.
+config REGULATOR_HI655X
+ tristate "Hisilicon HI655X PMIC regulators support"
+ depends on ARCH_HISI
+ depends on MFD_HI655X_PMIC && OF
+ help
+ This driver provides support for the voltage regulators of the
+ Hisilicon Hi655x PMIC device.
+
config REGULATOR_ISL9305
tristate "Intersil ISL9305 regulator"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0f81749..8e4db96 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o
+obj-$(CONFIG_REGULATOR_HI655X) += hi655x-regulator.o
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c
new file mode 100644
index 0000000..3423a84
--- /dev/null
+++ b/drivers/regulator/hi655x-regulator.c
@@ -0,0 +1,517 @@
+/*
+ * Device driver for regulators in HI655X IC
+ *
+ * Copyright (c) 2015 Hisilicon.
+ *
+ * Fei Wang <w.f@huawei.com>
+ *
+ * this regulator's probe function will be called lots of times,,
+ * because of there are lots of regulator nodes in dtb.
+ * so,that's say, the driver must be inited before the regulator nodes
+ * registor to system.
+ *
+ * Makefile have proved my guess, please refor to the makefile.
+ * when the code is rebuild i hope we can build pmu sub_system.
+ * init order can not base on compile
+ */
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/regulator/hi655x-regulator.h>
+#include <linux/mfd/hi655x-pmic.h>
+#include <linux/regmap.h>
+
+#define REG_VALUE_SETBITS(reg_value, pos, bits, bits_value) \
+ (reg_value = (reg_value & \
+ ~((((unsigned int)1 << bits) - 1) << pos)) | \
+ ((unsigned int)(bits_value & \
+ (((unsigned int)1 << bits) - 1)) << pos))
+
+#define REG_VALUE_GETBITS(reg_value, pos, bits) \
+ ((reg_value >> pos) & (((unsigned int)1 << bits) - 1))
+
+static int hi655x_regulator_pmic_is_enabled(struct regulator_dev *rdev)
+{
+ int ret = 0;
+ unsigned int value = 0;
+
+ struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
+ struct hi655x_regulator_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
+ struct hi655x_regulator_ctrl_data *ctrl_data = &(sreg->ctrl_data);
+
+ /*
+ * regulator is all set,but the pmu is only subset.
+ * maybe this "buck"/"ldo"/"lvs" is not contrl by a core.
+ * and in regulator have a "status" member ("okey" or "disable").
+ */
+ regmap_read(rdev->regmap, ctrl_regs->status_reg, &value);
+ ret = (int)REG_VALUE_GETBITS(value, ctrl_data->shift,
+ ctrl_data->mask);
+
+ return ret;
+}
+
+static int hi655x_regulator_pmic_enable(struct regulator_dev *rdev)
+{
+ int ret = 0;
+ unsigned char value_u8 = 0;
+ unsigned int value_u32 = 0;
+ struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
+ struct hi655x_regulator_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
+ struct hi655x_regulator_ctrl_data *ctrl_data = &(sreg->ctrl_data);
+
+ REG_VALUE_SETBITS(value_u32, ctrl_data->shift, ctrl_data->mask, 0x1);
+ value_u8 = (unsigned char)value_u32;
+ regmap_write(rdev->regmap, ctrl_regs->enable_reg, value_u8);
+ udelay(sreg->off_on_delay);
+
+ return ret;
+}
+
+static int hi655x_regulator_pmic_disable(struct regulator_dev *rdev)
+{
+ int ret = 0;
+ int flag = 1;
+ unsigned char value_u8 = 0;
+ unsigned int value_u32 = 0;
+
+ struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
+ struct hi655x_regulator_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
+ struct hi655x_regulator_ctrl_data *ctrl_data = &(sreg->ctrl_data);
+
+ /*
+ * regulator is all set,but the pmu is only subset.
+ * maybe this "buck"/"ldo"/"lvs" is not contrl by a core.
+ * and in regulator have a "status" member (okey or disable).
+ * maybe we can del some regulator which is not contrl by core.
+ */
+ if (sreg->type == PMIC_BOOST_TYPE)
+ flag = 0;
+
+ /*
+ * for flag init value = 1;
+ */
+
+ REG_VALUE_SETBITS(value_u32, ctrl_data->shift, ctrl_data->mask, flag);
+ value_u8 = (unsigned char)value_u32;
+ regmap_write(rdev->regmap, ctrl_regs->disable_reg, value_u8);
+ return ret;
+}
+
+static int hi655x_regulator_pmic_list_voltage_linear(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+
+ struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
+ /*
+ * regulator is all set,but the pmu is only subset.
+ * maybe this "buck"/"ldo"/"lvs" is not contrl by a core.
+ * and in regulator have a "status" member (okey or disable).
+ * maybe we can del some regulator which is not contrl by core.
+ * we will return min_uV
+ */
+ if (sreg->type == PMIC_LVS_TYPE)
+ return 900000;
+
+ if (selector >= sreg->vol_numb) {
+ pr_err("selector err %s %d\n", __func__, __LINE__);
+ return -1;
+ }
+
+ return sreg->vset_table[selector];
+}
+
+static int hi655x_regulator_pmic_get_voltage(struct regulator_dev *rdev)
+{
+ int index = 0;
+ unsigned int value = 0;
+
+ struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
+ struct hi655x_regulator_vset_regs *vset_regs = &(sreg->vset_regs);
+ struct hi655x_regulator_vset_data *vset_data = &(sreg->vset_data);
+
+ if (sreg->type == PMIC_LVS_TYPE)
+ return 900000;
+
+ regmap_read(rdev->regmap, vset_regs->vset_reg, &value);
+ index = (unsigned int)REG_VALUE_GETBITS(value,
+ vset_data->shift, vset_data->mask);
+
+ return sreg->vset_table[index];
+}
+
+static int hi655x_regulator_pmic_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ int i = 0;
+ int ret = 0;
+ int vol = 0;
+ unsigned int value = 0;
+
+ struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
+ struct hi655x_regulator_vset_regs *vset_regs = &(sreg->vset_regs);
+ struct hi655x_regulator_vset_data *vset_data = &(sreg->vset_data);
+
+ if (sreg->type == PMIC_LVS_TYPE)
+ return 0;
+ /*
+ * search the matched vol and get its index
+ */
+ for (i = 0; i < sreg->vol_numb; i++) {
+ vol = sreg->vset_table[i];
+
+ if ((vol >= min_uV) && (vol <= max_uV))
+ break;
+ }
+
+ if (i == sreg->vol_numb)
+ return -1;
+
+
+ regmap_read(rdev->regmap, vset_regs->vset_reg, &value);
+ REG_VALUE_SETBITS(value, vset_data->shift, vset_data->mask, i);
+ regmap_write(rdev->regmap, vset_regs->vset_reg, value);
+ *selector = i;
+
+ return ret;
+}
+
+static unsigned int hi655x_regulator_pmic_get_mode(
+ struct regulator_dev *rdev)
+{
+ return REGULATOR_MODE_NORMAL;
+}
+
+static int hi655x_regulator_pmic_set_mode(struct regulator_dev *rdev,
+ unsigned int mode)
+
+{
+ return 0;
+}
+
+static unsigned int hi655x_regulator_pmic_get_optimum_mode(
+ struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA)
+
+{
+ return REGULATOR_MODE_NORMAL;
+}
+
+static struct regulator_ops hi655x_regulator_pmic_rops = {
+ .is_enabled = hi655x_regulator_pmic_is_enabled,
+ .enable = hi655x_regulator_pmic_enable,
+ .disable = hi655x_regulator_pmic_disable,
+ .list_voltage = hi655x_regulator_pmic_list_voltage_linear,
+ .get_voltage = hi655x_regulator_pmic_get_voltage,
+ .set_voltage = hi655x_regulator_pmic_set_voltage,
+ .get_mode = hi655x_regulator_pmic_get_mode,
+ .set_mode = hi655x_regulator_pmic_set_mode,
+ .get_optimum_mode = hi655x_regulator_pmic_get_optimum_mode,
+};
+
+static int hi655x_regualtor_pmic_dt_parse(struct hi655x_regulator *sreg,
+ struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct hi655x_regulator hi655x_regulator_pmic = {
+ .rdesc = {
+ .ops = &hi655x_regulator_pmic_rops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ .dt_parse = hi655x_regualtor_pmic_dt_parse,
+};
+
+
+static const struct of_device_id of_hi655x_regulator_match_tbl[] = {
+ {
+ .compatible = "hisilicon,hi655x-regulator-pmic",
+ .data = &hi655x_regulator_pmic,
+ },
+ { /* end */ }
+};
+
+static struct regulator_init_data *hi655x_of_get_regulator_init_data(
+ struct device *dev, struct device_node *np)
+{
+ struct regulator_init_data *init_data = NULL;
+ const __be32 *num_consumer_supplies = NULL;
+ struct regulator_consumer_supply *consumer_supplies = NULL;
+ int consumer_id = 0;
+
+ init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
+ if (!init_data)
+ return NULL;
+
+ num_consumer_supplies = of_get_property(np,
+ "hisilicon,num_consumer_supplies", NULL);
+
+ if ((NULL == num_consumer_supplies) || (0 == *num_consumer_supplies)) {
+ dev_warn(dev, "%s no consumer_supplies\n", __func__);
+ return init_data;
+ }
+
+ init_data->num_consumer_supplies = be32_to_cpu(*num_consumer_supplies);
+ init_data->consumer_supplies = (struct regulator_consumer_supply *)
+ devm_kzalloc(dev, init_data->num_consumer_supplies *
+ sizeof(struct regulator_consumer_supply), GFP_KERNEL);
+
+ if (NULL == init_data->consumer_supplies) {
+ dev_err(dev, "%s devm_kzalloc consumer_supplies err\n",
+ __func__);
+ return NULL;
+ }
+
+ consumer_supplies = init_data->consumer_supplies;
+
+ for (consumer_id = 0; consumer_id < init_data->num_consumer_supplies;
+ consumer_id++, consumer_supplies++) {
+ int ret = of_property_read_string_index(np,
+ "hisilicon,consumer-supplies",
+ consumer_id, &consumer_supplies->supply);
+
+ if (ret) {
+ dev_err(dev,
+ "%s %s of_property_read_string_index consumer-supplies err\n",
+ __func__, np->name);
+ }
+ }
+
+ return init_data;
+}
+
+static int hi655x_of_get_regulator_constraint(
+ struct regulation_constraints *constraints, struct device_node *np)
+{
+ const __be32 *min_uV, *max_uV;
+ unsigned int *valid_modes_mask;
+ unsigned int *valid_ops_mask;
+ unsigned int *initial_mode;
+
+ if (!np)
+ return -1;
+
+ if (!constraints)
+ return -1;
+
+ (constraints)->name = of_get_property(np, "regulator-name", NULL);
+
+ min_uV = of_get_property(np, "regulator-min-microvolt", NULL);
+ if (min_uV) {
+ (constraints)->min_uV = be32_to_cpu(*min_uV);
+ (constraints)->min_uA = be32_to_cpu(*min_uV);
+ }
+
+ max_uV = of_get_property(np, "regulator-max-microvolt", NULL);
+ if (max_uV) {
+ (constraints)->max_uV = be32_to_cpu(*max_uV);
+ (constraints)->max_uA = be32_to_cpu(*max_uV);
+ }
+
+ valid_modes_mask = (unsigned int *)of_get_property(np,
+ "hisilicon,valid-modes-mask", NULL);
+
+ if (valid_modes_mask)
+ (constraints)->valid_modes_mask =
+ be32_to_cpu(*valid_modes_mask);
+
+ valid_ops_mask = (unsigned int *)of_get_property(np,
+ "hisilicon,valid-ops-mask", NULL);
+ if (valid_ops_mask)
+ (constraints)->valid_ops_mask =
+ be32_to_cpu(*valid_ops_mask);
+
+ initial_mode = (unsigned int *)of_get_property(np,
+ "hisilicon,initial-mode", NULL);
+ if (initial_mode)
+ (constraints)->initial_mode = be32_to_cpu(*initial_mode);
+
+ (constraints)->always_on = !!(of_find_property(np,
+ "regulator-always-on", NULL));
+
+ (constraints)->boot_on = !!(of_find_property(np,
+ "regulator-boot-on", NULL));
+ return 0;
+
+}
+
+static int hi655x_of_get_regulator_sreg(struct hi655x_regulator *sreg,
+ struct device *dev, struct device_node *np)
+{
+ int *vol_numb;
+ unsigned int *off_on_delay;
+ enum hi655x_regulator_type *regulator_type;
+ const char *status = NULL;
+ unsigned int *vset_table = NULL;
+ int *regulator_id;
+
+ status = of_get_property(np, "hisilicon,regulator-status", NULL);
+ if (status)
+ sreg->status = !(strcmp(status, "okey"));
+
+ regulator_type = (enum hi655x_regulator_type *)of_get_property(np,
+ "hisilicon,regulator-type", NULL);
+
+ if (regulator_type)
+ sreg->type = be32_to_cpu(*regulator_type);
+
+ off_on_delay = (unsigned int *)of_get_property(np,
+ "hisilicon,off-on-delay", NULL);
+ if (off_on_delay)
+ sreg->off_on_delay = be32_to_cpu(*off_on_delay);
+
+ (void)of_property_read_u32_array(np, "hisilicon,ctrl-regs",
+ (unsigned int *)(&sreg->ctrl_regs), 0x3);
+
+ (void)of_property_read_u32_array(np, "hisilicon,ctrl-data",
+ (unsigned int *)(&sreg->ctrl_data), 0x2);
+
+ (void)of_property_read_u32_array(np, "hisilicon,vset-regs",
+ (unsigned int *)(&sreg->vset_regs), 0x1);
+
+ (void)of_property_read_u32_array(np, "hisilicon,vset-data",
+ (unsigned int *)(&sreg->vset_data), 0x2);
+
+ vol_numb = (int *)of_get_property(np, "hisilicon,regulator-n-vol",
+ NULL);
+ if (vol_numb)
+ sreg->vol_numb = be32_to_cpu(*vol_numb);
+
+ regulator_id = (int *)of_get_property(np,
+ "hisilicon, hisi-scharger-regulator-id", NULL);
+
+ if (regulator_id)
+ sreg->regulator_id = be32_to_cpu(*regulator_id);
+
+ vset_table = devm_kzalloc(dev, sreg->vol_numb * sizeof(int),
+ GFP_KERNEL);
+ if (!vset_table)
+ return -1;
+
+ (void)of_property_read_u32_array(np,
+ "hisilicon,vset-table", (unsigned int *)vset_table,
+ sreg->vol_numb);
+ sreg->vset_table = vset_table;
+
+ return 0;
+
+}
+
+static int hi655x_regulator_probe(struct platform_device *pdev)
+{
+
+ int ret = 0;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct hi655x_pmic *pmic;
+ struct regulator_dev *rdev = NULL;
+ struct regulator_desc *rdesc = NULL;
+ struct hi655x_regulator *sreg = NULL;
+ struct regulator_init_data *initdata = NULL;
+ const struct of_device_id *match = NULL;
+ const struct hi655x_regulator *template = NULL;
+ struct regulator_config config = { };
+
+ pmic = dev_get_drvdata(dev->parent);
+
+ /*
+ * build hi655x_regulator device
+ */
+
+ /* to check which type of regulator this is */
+ match = of_match_device(of_hi655x_regulator_match_tbl, &pdev->dev);
+
+ if (NULL == match) {
+ dev_err(dev, "of match hi655x regulator fail!\n\r");
+ return -EINVAL;
+ }
+ /*tempdev is regulator device*/
+ template = match->data;
+
+ /*
+ *initdata mem will release auto;
+ *this is kernel 3.10 import.
+ */
+
+ /*just for getting "std regulator node" value-key about constraint*/
+ initdata = hi655x_of_get_regulator_init_data(dev, np);
+ if (!initdata) {
+ dev_err(dev, "get regulator init data error !\n");
+ return -EINVAL;
+ }
+
+ ret = hi655x_of_get_regulator_constraint(&initdata->constraints, np);
+ if (!!ret) {
+ dev_err(dev, "get regulator constraint error !\n");
+ return -EINVAL;
+ }
+
+ /* TODO:hi655x regulator supports two modes */
+ sreg = kmemdup(template, sizeof(*sreg), GFP_KERNEL);
+ if (!sreg)
+ return -ENOMEM;
+
+ if (0 != hi655x_of_get_regulator_sreg(sreg, dev, np)) {
+ kfree(sreg);
+ return -EINVAL;
+ }
+
+ rdesc = &sreg->rdesc;
+ rdesc->n_voltages = sreg->vol_numb;
+ rdesc->name = initdata->constraints.name;
+ rdesc->id = sreg->regulator_id;
+ rdesc->min_uV = initdata->constraints.min_uV;
+
+ /*just for skeleton for future*/
+ /* to parse device tree data for regulator specific */
+ config.dev = &pdev->dev;
+ config.init_data = initdata;
+ config.driver_data = sreg;
+ config.regmap = pmic->regmap;
+ config.of_node = pdev->dev.of_node;
+ /* register regulator */
+ rdev = regulator_register(rdesc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(dev, "regulator failed to register %s\n", rdesc->name);
+ ret = PTR_ERR(rdev);
+ return -EINVAL;
+ }
+
+ platform_set_drvdata(pdev, rdev);
+ regulator_has_full_constraints();
+
+ return ret;
+}
+
+static int hi655x_regulator_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver hi655x_regulator_driver = {
+ .driver = {
+ .name = "hi655x_regulator",
+ .owner = THIS_MODULE,
+ .of_match_table = of_hi655x_regulator_match_tbl,
+ },
+ .probe = hi655x_regulator_probe,
+ .remove = hi655x_regulator_remove,
+};
+module_platform_driver(hi655x_regulator_driver);
+
+MODULE_AUTHOR("Fei Wang <w.f@huawei.com>");
+MODULE_DESCRIPTION("Hisi hi655x regulator driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/regulator/hi655x-regulator.h b/include/linux/regulator/hi655x-regulator.h
new file mode 100644
index 0000000..387b352
--- /dev/null
+++ b/include/linux/regulator/hi655x-regulator.h
@@ -0,0 +1,69 @@
+/*
+ * Device driver for regulators in HI655X IC
+ *
+ * Copyright (c) 2015 Hisilicon.
+ *
+ * Fei Wang <w.f@huawei.com>
+ *
+ * this regulator's probe function will be called lots of times,,
+ * because of there are lots of regulator nodes in dtb.
+ * so,that's say, the driver must be inited before the regulator nodes
+ * registor to system.
+ *
+ * Makefile have proved my guess, please refor to the makefile.
+ * when the code is rebuild i hope we can build pmu sub_system.
+ * init order can not base on compile
+ */
+
+#ifndef __HISI_HI655X_REGULATOR_H__
+#define __HISI_HI655X_REGULATOR_H__
+
+enum hi655x_regulator_type {
+ PMIC_BUCK_TYPE = 0,
+ PMIC_LDO_TYPE = 1,
+ PMIC_LVS_TYPE = 2,
+ PMIC_BOOST_TYPE = 3,
+ MTCMOS_SC_ON_TYPE = 4,
+ MTCMOS_ACPU_ON_TYPE = 5,
+ SCHARGE_TYPE = 6,
+};
+
+struct hi655x_regulator_ctrl_regs {
+ unsigned int enable_reg;
+ unsigned int disable_reg;
+ unsigned int status_reg;
+};
+
+struct hi655x_regulator_vset_regs {
+ unsigned int vset_reg;
+};
+
+struct hi655x_regulator_ctrl_data {
+ int shift;
+ unsigned int mask;
+};
+
+struct hi655x_regulator_vset_data {
+ int shift;
+ unsigned int mask;
+};
+
+struct hi655x_regulator {
+ int status; /*this property in child node*/
+ unsigned int off_on_delay; /*this property in parent node*/
+ enum hi655x_regulator_type type; /*this property in child node*/
+ int regulator_id;
+
+ /*this property must be unify which is in child node*/
+ struct hi655x_regulator_ctrl_regs ctrl_regs;
+ struct hi655x_regulator_ctrl_data ctrl_data;
+
+ struct hi655x_regulator_vset_regs vset_regs;
+ struct hi655x_regulator_vset_data vset_data;
+ unsigned int vol_numb;
+ unsigned int *vset_table;
+ struct regulator_desc rdesc;
+ int (*dt_parse)(struct hi655x_regulator*, struct platform_device*);
+};
+
+#endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 5/8] arm64: dts: Add Hi655x regulator config node
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
` (3 preceding siblings ...)
2015-09-30 11:05 ` [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
2015-09-30 11:05 ` [PATCH 6/8] dt-bindings: mtcmos: Document Hi6220 mtcmos driver Fei Wang
` (2 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
This patch add hi655x regulator dts file for Hi6220 SoC.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 245 +++++++++++++++++++++++++++++
1 file changed, 245 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 4e4830b..40f895b 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -176,5 +176,250 @@
interrupt-controller;
pmu_irq_gpio = <&gpio_pmu_irq_n>;
status = "ok";
+
+ ldo2: regulator at a21 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3200000>;
+ hisilicon,valid-modes-mask = <0x02>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x029 0x02a 0x02b>;
+ hisilicon,ctrl-data = <0x1 0x1>;
+ hisilicon,vset-regs = <0x072>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <2500000>,<2600000>,
+ <2700000>,<2800000>,
+ <2900000>,<3000000>,
+ <3100000>,<3200000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "sensor_analog";
+ };
+
+ ldo7: regulator at a26 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ hisilicon,valid-modes-mask = <0x0a>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x029 0x02a 0x02b>;
+ hisilicon,ctrl-data = <0x6 0x1>;
+ hisilicon,vset-regs = <0x078>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <1800000>,<1850000>,
+ <2850000>,<2900000>,
+ <3000000>,<3100000>,
+ <3200000>,<3300000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "sd_card_io";
+ };
+
+ ldo10: regulator at a29 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ hisilicon,valid-modes-mask = <0x0a>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <360>;
+ hisilicon,ctrl-regs = <0x02c 0x02d 0x02e>;
+ hisilicon,ctrl-data = <0x1 0x1>;
+ hisilicon,vset-regs = <0x07b>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <1800000>,<1850000>,
+ <1900000>,<2750000>,
+ <2800000>,<2850000>,
+ <2900000>,<3000000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "sd_card";
+ };
+
+ ldo13: regulator at a32 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo13";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1950000>;
+ hisilicon,valid-modes-mask = <0x0a>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x02c 0x02d 0x02e>;
+ hisilicon,ctrl-data = <0x4 0x1>;
+ hisilicon,vset-regs = <0x07e>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <1600000>,<1650000>,
+ <1700000>,<1750000>,
+ <1800000>,<1850000>,
+ <1900000>,<1950000>;
+ hisilicon,num_consumer_supplies = <3>;
+ hisilicon,consumer-supplies = "scamera_core",
+ "mcamera_io",
+ "scamera_io";
+ };
+
+ ldo14: regulator at a33 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo14";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3200000>;
+ hisilicon,valid-modes-mask = <0x02>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x02c 0x02d 0x02e>;
+ hisilicon,ctrl-data = <0x5 0x1>;
+ hisilicon,vset-regs = <0x07f>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <2500000>,<2600000>,
+ <2700000>,<2800000>,
+ <2900000>,<3000000>,
+ <3100000>,<3200000>;
+ hisilicon,num_consumer_supplies = <3>;
+ hisilicon,consumer-supplies = "scamera_avdd",
+ "mcamera_avdd",
+ "mcamera_vcm";
+ };
+
+ ldo15: regulator at a34 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo15";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-boot-on;
+ regulator-always-on;
+ hisilicon,valid-modes-mask = <0x0a>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x02c 0x02d 0x02e>;
+ hisilicon,ctrl-data = <0x6 0x1>;
+ hisilicon,vset-regs = <0x080>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <1600000>,<1650000>,
+ <1700000>,<1750000>,
+ <1800000>,<1850000>,
+ <1900000>,<1950000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "codec_analog";
+ };
+
+ ldo17: regulator at a36 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo17";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3200000>;
+ hisilicon,valid-modes-mask = <0x02>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x02f 0x030 0x031>;
+ hisilicon,ctrl-data = <0x0 0x1>;
+ hisilicon,vset-regs = <0x082>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <2500000>,<2600000>,
+ <2700000>,<2800000>,
+ <2900000>,<3000000>,
+ <3100000>,<3200000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "vibrator";
+ };
+
+ ldo19: regulator at a38 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo19";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ hisilicon,valid-modes-mask = <0x0a>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <360>;
+ hisilicon,ctrl-regs = <0x02f 0x030 0x031>;
+ hisilicon,ctrl-data = <0x2 0x1>;
+ hisilicon,vset-regs = <0x084>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <1800000>,<1850000>,
+ <1900000>,<2750000>,
+ <2800000>,<2850000>,
+ <2900000>,<3000000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "emmc_vddm";
+ };
+
+ ldo21: regulator at a40 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo21"; regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ hisilicon,valid-modes-mask = <0x02>; hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x02f 0x030 0x031>;
+ hisilicon,ctrl-data = <0x4 0x1>;
+ hisilicon,vset-regs = <0x086>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <1650000>,<1700000>,
+ <1750000>,<1800000>,
+ <1850000>,<1900000>,
+ <1950000>,<2000000>;
+ };
+
+ ldo22: regulator at a41 {
+ compatible = "hisilicon,hi655x-regulator-pmic";
+ regulator-name = "ldo22";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ hisilicon,valid-modes-mask = <0x02>;
+ hisilicon,valid-ops-mask = <0x01d>;
+ hisilicon,initial-mode = <0x02>;
+ hisilicon,regulator-type = <0x01>;
+
+ hisilicon,off-on-delay = <120>;
+ hisilicon,ctrl-regs = <0x02f 0x030 0x031>;
+ hisilicon,ctrl-data = <0x5 0x1>;
+ hisilicon,vset-regs = <0x087>;
+ hisilicon,vset-data = <0 0x3>;
+ hisilicon,regulator-n-vol = <8>;
+ hisilicon,vset-table = <900000>,<1000000>,
+ <1050000>,<1100000>,
+ <1150000>,<1175000>,
+ <1185000>,<1200000>;
+ hisilicon,num_consumer_supplies = <1>;
+ hisilicon,consumer-supplies = "mcamera_core";
+ };
};
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 6/8] dt-bindings: mtcmos: Document Hi6220 mtcmos driver
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
` (4 preceding siblings ...)
2015-09-30 11:05 ` [PATCH 5/8] arm64: dts: Add Hi655x regulator config node Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
2015-09-30 11:05 ` [PATCH 7/8] mtcmos: Hi6220: Add Hi6220 mtcmos regulator driver Fei Wang
2015-09-30 11:05 ` [PATCH 8/8] arm64: dts: Add Hi6220 mtcmos regulator node Fei Wang
7 siblings, 0 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
Document the new compatible for Hisilicon Hi6220 mtcmos driver.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
.../bindings/regulator/hisilicon,hi6220-mtcmos.txt | 32 ++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/hisilicon,hi6220-mtcmos.txt
diff --git a/Documentation/devicetree/bindings/regulator/hisilicon,hi6220-mtcmos.txt b/Documentation/devicetree/bindings/regulator/hisilicon,hi6220-mtcmos.txt
new file mode 100644
index 0000000..748ac62
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/hisilicon,hi6220-mtcmos.txt
@@ -0,0 +1,32 @@
+Hi6220 mtcmos Voltage regulators
+
+Required parent device properties:
+- compatible: Must be "hisilicon,hi6220-mtcmos-driver"
+- hisilicon,mtcmos-steady-us: The time to wait for power steady
+- hisilicon,mtcmos-sc-on-base: address of hi6220 soc control register
+
+Required child device properties:
+- regulator-name: The name of mtcmos
+- hisilicon,ctrl-regs: offset of ctrl-regs
+- hisilicon,ctrl-data: the bit to ctrl the regulator
+
+Example:
+ mtcmos {
+ compatible = "hisilicon,hi6220-mtcmos-driver";
+ hisilicon,mtcmos-steady-us = <10>;
+ hisilicon,mtcmos-sc-on-base = <0xf7800000>;
+ hisilicon,mtcmos-acpu-on-base = <0xf65a0000>;
+
+ mtcmos1: regulator at a1{
+ regulator-name = "G3D_PD_VDD";
+ regulator-compatible = "mtcmos1";
+ hisilicon,ctrl-regs = <0x830 0x834 0x83c>;
+ hisilicon,ctrl-data = <1 0x1>;
+ };
+ mtcmos2: regulator at a2{
+ regulator-name = "SOC_MED";
+ regulator-compatible = "mtcmos2";
+ hisilicon,ctrl-regs = <0x830 0x834 0x83c>;
+ hisilicon,ctrl-data = <2 0x1>;
+ };
+ };
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7/8] mtcmos: Hi6220: Add Hi6220 mtcmos regulator driver
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
` (5 preceding siblings ...)
2015-09-30 11:05 ` [PATCH 6/8] dt-bindings: mtcmos: Document Hi6220 mtcmos driver Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
2015-09-30 11:05 ` [PATCH 8/8] arm64: dts: Add Hi6220 mtcmos regulator node Fei Wang
7 siblings, 0 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
Add Hi6220 mtcmos regulator driver.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
drivers/regulator/Kconfig | 8 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/hi6220-mtcmos.c | 281 +++++++++++++++++++++++++++++++++++++
3 files changed, 290 insertions(+)
create mode 100644 drivers/regulator/hi6220-mtcmos.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index d13210b..b5af2c6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -269,6 +269,14 @@ config REGULATOR_HI655X
This driver provides support for the voltage regulators of the
Hisilicon Hi655x PMIC device.
+config REGULATOR_HI6220
+ tristate "Hisilicon Hi6220 MTCMOS regulator support"
+ depends on ARCH_HISI
+ default ARCH_HISI
+ help
+ This driver provides support for the mtcmos regulators on the
+ Hisilicon Hi6220 chip.
+
config REGULATOR_ISL9305
tristate "Intersil ISL9305 regulator"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 8e4db96..0590e8f 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o
obj-$(CONFIG_REGULATOR_HI655X) += hi655x-regulator.o
+obj-$(CONFIG_REGULATOR_HI6220) += hi6220-mtcmos.o
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
diff --git a/drivers/regulator/hi6220-mtcmos.c b/drivers/regulator/hi6220-mtcmos.c
new file mode 100644
index 0000000..4e84843
--- /dev/null
+++ b/drivers/regulator/hi6220-mtcmos.c
@@ -0,0 +1,281 @@
+/*
+ * Device driver for MTCMOS DRIVER in hi6220 SOC
+ *
+ * Copyright (c) 2015 Hisilicon Co. Ltd
+ *
+ * Fei Wang <w.f@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+
+enum {
+ HI6220_MTCMOS1,
+ HI6220_MTCMOS2,
+ HI6220_RG_MAX,
+};
+
+struct hi6220_mtcmos_ctrl_regs {
+ unsigned int enable_reg;
+ unsigned int disable_reg;
+ unsigned int status_reg;
+};
+
+struct hi6220_mtcmos_ctrl_data {
+ int shift;
+ unsigned int mask;
+};
+
+struct hi6220_mtcmos_info {
+ struct regulator_desc rdesc;
+ struct hi6220_mtcmos_ctrl_regs ctrl_regs;
+ struct hi6220_mtcmos_ctrl_data ctrl_data;
+};
+
+struct hi6220_mtcmos {
+ struct regulator_dev *rdev[HI6220_RG_MAX];
+ void __iomem *sc_on_regs;
+ int mtcmos_steady_time;
+ spinlock_t mtcmos_spin_lock;
+};
+
+static int hi6220_mtcmos_is_on(struct hi6220_mtcmos *mtcmos,
+ unsigned int regs, unsigned int mask, int shift)
+{
+ unsigned int ret;
+ unsigned long mtcmos_spin_flag = 0;
+
+ spin_lock_irqsave(&mtcmos->mtcmos_spin_lock, mtcmos_spin_flag);
+ ret = readl(mtcmos->sc_on_regs + regs);
+ spin_unlock_irqrestore(&mtcmos->mtcmos_spin_lock, mtcmos_spin_flag);
+
+ ret &= (mask << shift);
+ return !!ret;
+}
+
+int hi6220_mtcmos_on(struct hi6220_mtcmos *mtcmos,
+ unsigned int regs, unsigned int mask, int shift)
+{
+ unsigned long mtcmos_spin_flag = 0;
+
+ spin_lock_irqsave(&mtcmos->mtcmos_spin_lock, mtcmos_spin_flag);
+ writel(mask << shift, mtcmos->sc_on_regs + regs);
+ udelay(mtcmos->mtcmos_steady_time);
+ spin_unlock_irqrestore(&mtcmos->mtcmos_spin_lock, mtcmos_spin_flag);
+
+ return 0;
+}
+
+int hi6220_mtcmos_off(struct hi6220_mtcmos *mtcmos,
+ unsigned int regs, unsigned int mask, int shift)
+{
+ unsigned long mtcmos_spin_flag = 0;
+
+ spin_lock_irqsave(&mtcmos->mtcmos_spin_lock, mtcmos_spin_flag);
+ writel(mask << shift, mtcmos->sc_on_regs + regs);
+ udelay(mtcmos->mtcmos_steady_time);
+ spin_unlock_irqrestore(&mtcmos->mtcmos_spin_lock,
+ mtcmos_spin_flag);
+
+ return 0;
+}
+
+static int hi6220_regulator_mtcmos_is_enabled(struct regulator_dev *rdev)
+{
+ int ret;
+ struct hi6220_mtcmos_info *sreg = rdev_get_drvdata(rdev);
+ struct platform_device *pdev =
+ container_of(rdev->dev.parent, struct platform_device, dev);
+ struct hi6220_mtcmos *mtcmos = platform_get_drvdata(pdev);
+ struct hi6220_mtcmos_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
+ struct hi6220_mtcmos_ctrl_data *ctrl_data = &(sreg->ctrl_data);
+
+ ret = hi6220_mtcmos_is_on(mtcmos, ctrl_regs->status_reg,
+ ctrl_data->mask, ctrl_data->shift);
+ return ret;
+}
+
+static int hi6220_regulator_mtcmos_enabled(struct regulator_dev *rdev)
+{
+ int ret;
+ struct hi6220_mtcmos_info *sreg = rdev_get_drvdata(rdev);
+ struct platform_device *pdev =
+ container_of(rdev->dev.parent, struct platform_device, dev);
+ struct hi6220_mtcmos *mtcmos = platform_get_drvdata(pdev);
+ struct hi6220_mtcmos_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
+ struct hi6220_mtcmos_ctrl_data *ctrl_data = &(sreg->ctrl_data);
+
+ ret = hi6220_mtcmos_on(mtcmos, ctrl_regs->enable_reg,
+ ctrl_data->mask, ctrl_data->shift);
+ if (0 == hi6220_mtcmos_is_on(mtcmos, ctrl_regs->status_reg,
+ ctrl_data->mask, ctrl_data->shift)) {
+ return -1;
+ }
+ return ret;
+}
+
+static int hi6220_regulator_mtcmos_disabled(struct regulator_dev *rdev)
+{
+ int ret;
+ struct hi6220_mtcmos_info *sreg = rdev_get_drvdata(rdev);
+ struct platform_device *pdev =
+ container_of(rdev->dev.parent, struct platform_device, dev);
+ struct hi6220_mtcmos *mtcmos = platform_get_drvdata(pdev);
+ struct hi6220_mtcmos_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
+ struct hi6220_mtcmos_ctrl_data *ctrl_data = &(sreg->ctrl_data);
+
+ ret = hi6220_mtcmos_off(mtcmos, ctrl_regs->disable_reg,
+ ctrl_data->mask, ctrl_data->shift);
+
+ return ret;
+}
+
+static struct regulator_ops hi6220_mtcmos_mtcmos_rops = {
+ .is_enabled = hi6220_regulator_mtcmos_is_enabled,
+ .enable = hi6220_regulator_mtcmos_enabled,
+ .disable = hi6220_regulator_mtcmos_disabled,
+};
+
+#define HI6220_MTCMOS(vreg) \
+{ \
+ .rdesc = { \
+ .name = #vreg, \
+ .ops = &hi6220_mtcmos_mtcmos_rops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }, \
+}
+
+static struct hi6220_mtcmos_info hi6220_mtcmos_info[] = {
+ HI6220_MTCMOS(MTCMOS1),
+ HI6220_MTCMOS(MTCMOS2),
+};
+
+static struct of_regulator_match hi6220_mtcmos_matches[] = {
+ { .name = "mtcmos1",
+ .driver_data = &hi6220_mtcmos_info[HI6220_MTCMOS1], },
+ { .name = "mtcmos2",
+ .driver_data = &hi6220_mtcmos_info[HI6220_MTCMOS2], },
+};
+
+static int hi6220_mtcmos_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct hi6220_mtcmos *mtcmos;
+ const __be32 *sc_on_regs = NULL;
+ void __iomem *regs;
+ struct device *dev;
+ struct device_node *np, *child;
+ int count, i;
+ struct regulator_config config = { };
+ struct regulator_init_data *init_data;
+ struct hi6220_mtcmos_info *sreg;
+
+ dev = &pdev->dev;
+ np = dev->of_node;
+ mtcmos = devm_kzalloc(dev,
+ sizeof(struct hi6220_mtcmos), GFP_KERNEL);
+ if (!mtcmos)
+ return -ENOMEM;
+
+ spin_lock_init((spinlock_t *)&mtcmos->mtcmos_spin_lock);
+ sc_on_regs = of_get_property(np, "hisilicon,mtcmos-sc-on-base", NULL);
+ if (sc_on_regs) {
+ regs = ioremap(be32_to_cpu(*sc_on_regs), 0x1000);
+ mtcmos->sc_on_regs = regs;
+ }
+ ret = of_property_read_u32(np, "hisilicon,mtcmos-steady-us",
+ &mtcmos->mtcmos_steady_time);
+
+ count = of_regulator_match(&pdev->dev, np,
+ hi6220_mtcmos_matches,
+ ARRAY_SIZE(hi6220_mtcmos_matches));
+
+ for (i = 0; i < HI6220_RG_MAX; i++) {
+ init_data = hi6220_mtcmos_matches[i].init_data;
+ if (!init_data)
+ continue;
+ sreg = hi6220_mtcmos_matches[i].driver_data;
+ config.dev = &pdev->dev;
+ config.init_data = init_data;
+ config.driver_data = sreg;
+ config.of_node = hi6220_mtcmos_matches[i].of_node;
+ child = config.of_node;
+
+ ret = of_property_read_u32_array(child, "hisilicon,ctrl-regs",
+ (unsigned int *)(&sreg->ctrl_regs), 0x3);
+ ret = of_property_read_u32_array(child, "hisilicon,ctrl-data",
+ (unsigned int *)(&sreg->ctrl_data), 0x2);
+
+ mtcmos->rdev[i] = regulator_register(&sreg->rdesc, &config);
+ if (IS_ERR(mtcmos->rdev[i])) {
+ ret = PTR_ERR(mtcmos->rdev[i]);
+ dev_err(&pdev->dev, "failed to register mtcmos %s\n",
+ sreg->rdesc.name);
+ while (--i >= 0)
+ regulator_unregister(mtcmos->rdev[i]);
+
+ return ret;
+ }
+ }
+
+ platform_set_drvdata(pdev, mtcmos);
+
+ return 0;
+}
+
+static const struct of_device_id of_hi6220_mtcmos_match_tbl[] = {
+ { .compatible = "hisilicon,hi6220-mtcmos-driver", },
+ {}
+};
+
+static struct platform_driver mtcmos_driver = {
+ .driver = {
+ .name = "hisi_hi6220_mtcmos",
+ .owner = THIS_MODULE,
+ .of_match_table = of_hi6220_mtcmos_match_tbl,
+ },
+ .probe = hi6220_mtcmos_probe,
+};
+
+static int __init hi6220_mtcmos_init(void)
+{
+ return platform_driver_register(&mtcmos_driver);
+}
+
+static void __exit hi6220_mtcmos_exit(void)
+{
+ platform_driver_unregister(&mtcmos_driver);
+}
+
+fs_initcall(hi6220_mtcmos_init);
+module_exit(hi6220_mtcmos_exit);
+
+MODULE_AUTHOR("Fei Wang <w.f@huawei.com>");
+MODULE_DESCRIPTION("Hi6220 mtcmo interface driver");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 8/8] arm64: dts: Add Hi6220 mtcmos regulator node
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
` (6 preceding siblings ...)
2015-09-30 11:05 ` [PATCH 7/8] mtcmos: Hi6220: Add Hi6220 mtcmos regulator driver Fei Wang
@ 2015-09-30 11:05 ` Fei Wang
7 siblings, 0 replies; 18+ messages in thread
From: Fei Wang @ 2015-09-30 11:05 UTC (permalink / raw)
To: linux-arm-kernel
This patch add mtcmos regulator dts file for Hi6220 SoC.
Signed-off-by: Fei Wang <w.f@huawei.com>
---
arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 40f895b..9b1a6ed 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -167,6 +167,27 @@
clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
clock-names = "uartclk", "apb_pclk";
};
+
+ mtcmos {
+ compatible = "hisilicon,hi6220-mtcmos-driver";
+ hisilicon,mtcmos-steady-us = <10>;
+ hisilicon,mtcmos-sc-on-base = <0xf7800000>;
+ hisilicon,mtcmos-acpu-on-base = <0xf65a0000>;
+
+ mtcmos1: regulator at a1{
+ regulator-name = "G3D_PD_VDD";
+ regulator-compatible = "mtcmos1";
+ hisilicon,ctrl-regs = <0x830 0x834 0x83c>;
+ hisilicon,ctrl-data = <1 0x1>;
+ };
+
+ mtcmos2: regulator at a2{
+ regulator-name = "SOC_MED";
+ regulator-compatible = "mtcmos2";
+ hisilicon,ctrl-regs = <0x830 0x834 0x83c>;
+ hisilicon,ctrl-data = <2 0x1>;
+ };
+ };
};
pmic: pmic at F8000000 {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver
2015-09-30 11:05 ` [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver Fei Wang
@ 2015-09-30 17:39 ` Mark Brown
2015-10-08 6:33 ` wangfei
2015-10-01 7:56 ` Lee Jones
2015-10-01 7:58 ` Lee Jones
2 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2015-09-30 17:39 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Sep 30, 2015 at 07:05:04PM +0800, Fei Wang wrote:
> +Hisilicon hi655x Power Management Integrated Circuit (PMIC)
> +
> +hi655x consists of a large and varied group of sub-devices:
> +
> +Device Supply Names Description
> +------ ------------ -----------
> +hi655x-powerkey : : Powerkey
> +hi655x-regulator-pmic : : Regulators
> +hi655x-usbvbus : : USB plug detection
> +hi655x-pmu-rtc : : RTC
> +hi655x-coul : : Coulomb
...counter?
There's no documentation of the bindings for any of the above devices or
how things are structured, you need to provide binding documentation
which is understandable standalone. None of the properties are
documented, nor is the set of regulators supported or how this is
structured.
> + coul: coul at 1 {
> + compatible = "hisilicon,hi655x-coul";
> + interrupt-parent = <&pmic>;
> + interrupts = <24 0>, <25 0>, <26 0>, <27 0>;
> + interrupt-names = "cl_int_i", "cl_out_i", "cl_in_i", "vbat_int_i";
> + battery_product_index = <0>;
For example, the "battery_product_index" property here is undocumented.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150930/57546c23/attachment.sig>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator
2015-09-30 11:05 ` [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator Fei Wang
@ 2015-09-30 17:58 ` Mark Brown
2015-10-08 7:38 ` wangfei
2015-10-08 7:47 ` Javier Martinez Canillas
1 sibling, 1 reply; 18+ messages in thread
From: Mark Brown @ 2015-09-30 17:58 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Sep 30, 2015 at 07:05:07PM +0800, Fei Wang wrote:
> +config REGULATOR_HI655X
> + tristate "Hisilicon HI655X PMIC regulators support"
> + depends on ARCH_HISI
> + depends on MFD_HI655X_PMIC && OF
You've got some tab/space confusion above. Also, can't we have an ||
COMPILE_TEST here?
> +#define REG_VALUE_SETBITS(reg_value, pos, bits, bits_value) \
> + (reg_value = (reg_value & \
> + ~((((unsigned int)1 << bits) - 1) << pos)) | \
> + ((unsigned int)(bits_value & \
> + (((unsigned int)1 << bits) - 1)) << pos))
> +
> +#define REG_VALUE_GETBITS(reg_value, pos, bits) \
> + ((reg_value >> pos) & (((unsigned int)1 << bits) - 1))
These are just really hard to read, sorry, and they appear to duplicate
existing regmap functionality. If there is a strong reason to add them
consider doing so in the core and if you can then please@least make
them regular inline functions rather than using macros. It's much safer
and more readable.
> +static int hi655x_regulator_pmic_is_enabled(struct regulator_dev *rdev)
> +{
> + int ret = 0;
> + unsigned int value = 0;
> +
> + struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
> + struct hi655x_regulator_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
> + struct hi655x_regulator_ctrl_data *ctrl_data = &(sreg->ctrl_data);
> +
> + /*
> + * regulator is all set,but the pmu is only subset.
> + * maybe this "buck"/"ldo"/"lvs" is not contrl by a core.
> + * and in regulator have a "status" member ("okey" or "disable").
> + */
I'm having a hard time parsing the above comment. Please also use the
normal kernel comment style (this is a problem throughout the driver).
> + regmap_read(rdev->regmap, ctrl_regs->status_reg, &value);
> + ret = (int)REG_VALUE_GETBITS(value, ctrl_data->shift,
> + ctrl_data->mask);
This appears to just duplicate regulator core functionality for reading
enable state from a bitfield? Also note that the cast here isn't a
great advert for the macros above.
> +static int hi655x_regulator_pmic_enable(struct regulator_dev *rdev)
> +{
> + int ret = 0;
> + unsigned char value_u8 = 0;
> + unsigned int value_u32 = 0;
> + struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
> + struct hi655x_regulator_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
> + struct hi655x_regulator_ctrl_data *ctrl_data = &(sreg->ctrl_data);
> +
> + REG_VALUE_SETBITS(value_u32, ctrl_data->shift, ctrl_data->mask, 0x1);
> + value_u8 = (unsigned char)value_u32;
> + regmap_write(rdev->regmap, ctrl_regs->enable_reg, value_u8);
I'm not *entirely* sure what this is supposed to be doing but it looks
like it's duplicating core functionality in a fashion that's really
quite hard to read. Why not just use the core functions for setting
bits?
> + udelay(sreg->off_on_delay);
Use the regualtor core delay functionality please.
> +static int hi655x_regulator_pmic_list_voltage_linear(struct regulator_dev *rdev,
> + unsigned int selector)
This is *definitely* duplicating core functionality, I think you want to
use regulator_list_voltage_linear_range() or possibly just plain
_linear() and use separate operations for the LVS regulator.
We at least need to restructure the code so that the core helper
functions are used and we don't have regulator type decisions everywhere
- the whole goal of having per regulator ops is to avoid having to open
code decisions about which regulator we're dealing with into each op
function.
> +static unsigned int hi655x_regulator_pmic_get_mode(
> + struct regulator_dev *rdev)
> +{
> + return REGULATOR_MODE_NORMAL;
> +}
Don't implement empty functions, remove all these.
> + num_consumer_supplies = of_get_property(np,
> + "hisilicon,num_consumer_supplies", NULL);
> +
> + if ((NULL == num_consumer_supplies) || (0 == *num_consumer_supplies)) {
> + dev_warn(dev, "%s no consumer_supplies\n", __func__);
> + return init_data;
> + }
Obviously the binding is completely undocumented but this is setting off
alarm bells - why is the driver even considering consumers? Please make
sure you are using the core regulator bindings rather than open coding
something which translates into platform data (which is what this looks
like).
I'm not going to review any more of the DT code without binding
documentation.
> + /*
> + *initdata mem will release auto;
> + *this is kernel 3.10 import.
> + */
Remove anything related to your vendor kernel support, this is not
relevant to upstream.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150930/0666e632/attachment.sig>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver
2015-09-30 11:05 ` [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver Fei Wang
2015-09-30 17:39 ` Mark Brown
@ 2015-10-01 7:56 ` Lee Jones
2015-10-01 7:58 ` Lee Jones
2 siblings, 0 replies; 18+ messages in thread
From: Lee Jones @ 2015-10-01 7:56 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, 30 Sep 2015, Fei Wang wrote:
> Document the new compatible for Hisilicon Hi655x pmic driver.
s/pmic/PMIC/
> Signed-off-by: Fei Wang <w.f@huawei.com>
> ---
> .../devicetree/bindings/mfd/hisilicon,hi655x.txt | 80 ++++++++++++++++++++
> 1 file changed, 80 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
> new file mode 100644
> index 0000000..17bd8ca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
> @@ -0,0 +1,80 @@
> +Hisilicon hi655x Power Management Integrated Circuit (PMIC)
> +
> +hi655x consists of a large and varied group of sub-devices:
> +
> +Device Supply Names Description
> +------ ------------ -----------
> +hi655x-powerkey : : Powerkey
> +hi655x-regulator-pmic : : Regulators
> +hi655x-usbvbus : : USB plug detection
> +hi655x-pmu-rtc : : RTC
> +hi655x-coul : : Coulomb
As Mark said, these all need documentation.
> +Required properties:
> +- compatible : Should be "hisilicon,hi655x-pmic-driver"
> +- reg: Base address of PMIC on hi6220 soc
> +- #interrupt-cells: Should be 2, is the local IRQ number for hi655x.
> +- interrupt-controller: hi655x has internal IRQs (has own IRQ domain).
> +- pmu_irq_gpio: should be &gpio_pmu_irq_n, is the IRQ gpio of hi655x.
Better if you tab these out, like:
- compatible : Should be "hisilicon,hi655x-pmic-driver"
- reg : Base address of PMIC on hi6220 soc
Etc ...
> +Example:
> + pmic: pmic at F8000000 {
s/F/f/
> + compatible = "hisilicon,hi655x-pmic-driver";
> + reg = <0x0 0xF8000000 0x0 0x1000>;
Small a => f please.
> + #interrupt-cells = <2>;
> + interrupt-controller;
> + pmu_irq_gpio = <&gpio_pmu_irq_n>;
This should be <name>-gpios.
No underscores please.
> + status = "ok";
Use "okay" instead.
> + ponkey:ponkey at b1{
White space issues here.
Where is the 'reg' property?
> + compatible = "hisilicon,hi655x-powerkey";
> + interrupt-parent = <&pmic>;
> + interrupts = <6 0>, <5 0>, <4 0>;
Use #defines (same goes for all below).
> + interrupt-names = "down", "up", "hold 1s";
White space in a name seems wrong to me.
> + };
> +
> + coul: coul at 1 {
What is @1?
Is this label used?
> + compatible = "hisilicon,hi655x-coul";
> + interrupt-parent = <&pmic>;
> + interrupts = <24 0>, <25 0>, <26 0>, <27 0>;
> + interrupt-names = "cl_int_i", "cl_out_i", "cl_in_i", "vbat_int_i";
> + battery_product_index = <0>;
Documentation? It doesn't look like a generic propriety either, so
should be have a vendor prefix.
> + status = "ok";
"okay"
> + };
> +
> + rtc: rtc at 1 {
Is this label used?
> + compatible = "hisilicon,hi655x-pmu-rtc";
> + interrupt-parent = <&pmic>;
> + interrupts = <20 0>;
> + interrupt-names = "hi655x_pmu_rtc";
> + board_id = <1>;
What's this? No IDs in DT please.
> + };
> +
> + usbvbus:usbvbus at b2{
Whitespace.
'reg'?
> + compatible = "hisilicon,hi655x-usbvbus";
> + interrupt-parent = <&pmic>;
> + interrupts = <9 0>, <8 0>;
> + interrupt-names = "connect", "disconnect";
> + };
> +
> + ldo2: regulator at a21 {
Tabbing seems wrong here.
> + compatible = "hisilicon,hi655x-regulator-pmic";
> + regulator-name = "ldo2";
> + regulator-min-microvolt = <2500000>;
> + regulator-max-microvolt = <3200000>;
> + hisilicon,valid-modes-mask = <0x02>;
> + hisilicon,valid-ops-mask = <0x01d>;
> + hisilicon,initial-mode = <0x02>;
> + hisilicon,regulator-type = <0x01>;
> +
> + hisilicon,off-on-delay = <120>;
> + hisilicon,ctrl-regs = <0x029 0x02a 0x02b>;
> + hisilicon,ctrl-data = <0x1 0x1>;
> + hisilicon,vset-regs = <0x072>;
> + hisilicon,vset-data = <0 0x3>;
> + hisilicon,regulator-n-vol = <8>;
> + hisilicon,vset-table = <2500000>,<2600000>,<2700000>,<2800000>,<2900000>,<3000000>,<3100000>,<3200000>;
Whitespace.
> + hisilicon,num_consumer_supplies = <1>;
> + hisilicon,consumer-supplies = "sensor_analog";
All of these vendor properties need documenting and signing of by Mark
(the Regulator Maintainer).
> + };
> + };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver
2015-09-30 11:05 ` [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver Fei Wang
2015-09-30 17:39 ` Mark Brown
2015-10-01 7:56 ` Lee Jones
@ 2015-10-01 7:58 ` Lee Jones
2015-10-08 7:03 ` wangfei
2 siblings, 1 reply; 18+ messages in thread
From: Lee Jones @ 2015-10-01 7:58 UTC (permalink / raw)
To: linux-arm-kernel
I just noticed that you Cc'ed all of the Core ARM people too. Please
do not do that. I'm sure they have enough of their own mail to trawl
though.
Only mail relevant parties i.e. those who show up when you use:
./scripts/get_maintainer.pl.
> Document the new compatible for Hisilicon Hi655x pmic driver.
>
> Signed-off-by: Fei Wang <w.f@huawei.com>
> ---
> .../devicetree/bindings/mfd/hisilicon,hi655x.txt | 80 ++++++++++++++++++++
> 1 file changed, 80 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
> new file mode 100644
> index 0000000..17bd8ca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
> @@ -0,0 +1,80 @@
> +Hisilicon hi655x Power Management Integrated Circuit (PMIC)
> +
> +hi655x consists of a large and varied group of sub-devices:
> +
> +Device Supply Names Description
> +------ ------------ -----------
> +hi655x-powerkey : : Powerkey
> +hi655x-regulator-pmic : : Regulators
> +hi655x-usbvbus : : USB plug detection
> +hi655x-pmu-rtc : : RTC
> +hi655x-coul : : Coulomb
> +
> +Required properties:
> +- compatible : Should be "hisilicon,hi655x-pmic-driver"
> +- reg: Base address of PMIC on hi6220 soc
> +- #interrupt-cells: Should be 2, is the local IRQ number for hi655x.
> +- interrupt-controller: hi655x has internal IRQs (has own IRQ domain).
> +- pmu_irq_gpio: should be &gpio_pmu_irq_n, is the IRQ gpio of hi655x.
> +
> +Example:
> + pmic: pmic at F8000000 {
> + compatible = "hisilicon,hi655x-pmic-driver";
> + reg = <0x0 0xF8000000 0x0 0x1000>;
> + #interrupt-cells = <2>;
> + interrupt-controller;
> + pmu_irq_gpio = <&gpio_pmu_irq_n>;
> + status = "ok";
> +
> + ponkey:ponkey at b1{
> + compatible = "hisilicon,hi655x-powerkey";
> + interrupt-parent = <&pmic>;
> + interrupts = <6 0>, <5 0>, <4 0>;
> + interrupt-names = "down", "up", "hold 1s";
> + };
> +
> + coul: coul at 1 {
> + compatible = "hisilicon,hi655x-coul";
> + interrupt-parent = <&pmic>;
> + interrupts = <24 0>, <25 0>, <26 0>, <27 0>;
> + interrupt-names = "cl_int_i", "cl_out_i", "cl_in_i", "vbat_int_i";
> + battery_product_index = <0>;
> + status = "ok";
> + };
> +
> + rtc: rtc at 1 {
> + compatible = "hisilicon,hi655x-pmu-rtc";
> + interrupt-parent = <&pmic>;
> + interrupts = <20 0>;
> + interrupt-names = "hi655x_pmu_rtc";
> + board_id = <1>;
> + };
> +
> + usbvbus:usbvbus at b2{
> + compatible = "hisilicon,hi655x-usbvbus";
> + interrupt-parent = <&pmic>;
> + interrupts = <9 0>, <8 0>;
> + interrupt-names = "connect", "disconnect";
> + };
> +
> + ldo2: regulator at a21 {
> + compatible = "hisilicon,hi655x-regulator-pmic";
> + regulator-name = "ldo2";
> + regulator-min-microvolt = <2500000>;
> + regulator-max-microvolt = <3200000>;
> + hisilicon,valid-modes-mask = <0x02>;
> + hisilicon,valid-ops-mask = <0x01d>;
> + hisilicon,initial-mode = <0x02>;
> + hisilicon,regulator-type = <0x01>;
> +
> + hisilicon,off-on-delay = <120>;
> + hisilicon,ctrl-regs = <0x029 0x02a 0x02b>;
> + hisilicon,ctrl-data = <0x1 0x1>;
> + hisilicon,vset-regs = <0x072>;
> + hisilicon,vset-data = <0 0x3>;
> + hisilicon,regulator-n-vol = <8>;
> + hisilicon,vset-table = <2500000>,<2600000>,<2700000>,<2800000>,<2900000>,<3000000>,<3100000>,<3200000>;
> + hisilicon,num_consumer_supplies = <1>;
> + hisilicon,consumer-supplies = "sensor_analog";
> + };
> + };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver
2015-09-30 17:39 ` Mark Brown
@ 2015-10-08 6:33 ` wangfei
2015-10-12 16:49 ` Mark Brown
0 siblings, 1 reply; 18+ messages in thread
From: wangfei @ 2015-10-08 6:33 UTC (permalink / raw)
To: linux-arm-kernel
On 2015/10/1 1:39, Mark Brown wrote:
> On Wed, Sep 30, 2015 at 07:05:04PM +0800, Fei Wang wrote:
>
>> +Hisilicon hi655x Power Management Integrated Circuit (PMIC)
>> +
>> +hi655x consists of a large and varied group of sub-devices:
>> +
>> +Device Supply Names Description
>> +------ ------------ -----------
>> +hi655x-powerkey : : Powerkey
>> +hi655x-regulator-pmic : : Regulators
>> +hi655x-usbvbus : : USB plug detection
>> +hi655x-pmu-rtc : : RTC
>> +hi655x-coul : : Coulomb
>
> ...counter?
>
> There's no documentation of the bindings for any of the above devices or
> how things are structured, you need to provide binding documentation
> which is understandable standalone. None of the properties are
> documented, nor is the set of regulators supported or how this is
> structured.
OK,i will add them.
>
>> + coul: coul at 1 {
>> + compatible = "hisilicon,hi655x-coul";
>> + interrupt-parent = <&pmic>;
>> + interrupts = <24 0>, <25 0>, <26 0>, <27 0>;
>> + interrupt-names = "cl_int_i", "cl_out_i", "cl_in_i", "vbat_int_i";
>> + battery_product_index = <0>;
>
> For example, the "battery_product_index" property here is undocumented.
now on hikey, we only enable hi655x-regulator-pmic function, and regulator is child node of pmic.do i need to document regulator dt-binding in this file or create a new regulator dt-binding file?
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver
2015-10-01 7:58 ` Lee Jones
@ 2015-10-08 7:03 ` wangfei
0 siblings, 0 replies; 18+ messages in thread
From: wangfei @ 2015-10-08 7:03 UTC (permalink / raw)
To: linux-arm-kernel
On 2015/10/1 15:58, Lee Jones wrote:
> I just noticed that you Cc'ed all of the Core ARM people too. Please
> do not do that. I'm sure they have enough of their own mail to trawl
> though.
>
> Only mail relevant parties i.e. those who show up when you use:
>
> ./scripts/get_maintainer.pl.
>
OK?i see?thank you?
>> Document the new compatible for Hisilicon Hi655x pmic driver.
>>
>> Signed-off-by: Fei Wang <w.f@huawei.com>
>> ---
>> .../devicetree/bindings/mfd/hisilicon,hi655x.txt | 80 ++++++++++++++++++++
>> 1 file changed, 80 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
>> new file mode 100644
>> index 0000000..17bd8ca
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
>> @@ -0,0 +1,80 @@
>> +Hisilicon hi655x Power Management Integrated Circuit (PMIC)
>> +
>> +hi655x consists of a large and varied group of sub-devices:
>> +
>> +Device Supply Names Description
>> +------ ------------ -----------
>> +hi655x-powerkey : : Powerkey
>> +hi655x-regulator-pmic : : Regulators
>> +hi655x-usbvbus : : USB plug detection
>> +hi655x-pmu-rtc : : RTC
>> +hi655x-coul : : Coulomb
>> +
>> +Required properties:
>> +- compatible : Should be "hisilicon,hi655x-pmic-driver"
>> +- reg: Base address of PMIC on hi6220 soc
>> +- #interrupt-cells: Should be 2, is the local IRQ number for hi655x.
>> +- interrupt-controller: hi655x has internal IRQs (has own IRQ domain).
>> +- pmu_irq_gpio: should be &gpio_pmu_irq_n, is the IRQ gpio of hi655x.
>> +
>> +Example:
>> + pmic: pmic at F8000000 {
>> + compatible = "hisilicon,hi655x-pmic-driver";
>> + reg = <0x0 0xF8000000 0x0 0x1000>;
>> + #interrupt-cells = <2>;
>> + interrupt-controller;
>> + pmu_irq_gpio = <&gpio_pmu_irq_n>;
>> + status = "ok";
>> +
>> + ponkey:ponkey at b1{
>> + compatible = "hisilicon,hi655x-powerkey";
>> + interrupt-parent = <&pmic>;
>> + interrupts = <6 0>, <5 0>, <4 0>;
>> + interrupt-names = "down", "up", "hold 1s";
>> + };
>> +
>> + coul: coul at 1 {
>> + compatible = "hisilicon,hi655x-coul";
>> + interrupt-parent = <&pmic>;
>> + interrupts = <24 0>, <25 0>, <26 0>, <27 0>;
>> + interrupt-names = "cl_int_i", "cl_out_i", "cl_in_i", "vbat_int_i";
>> + battery_product_index = <0>;
>> + status = "ok";
>> + };
>> +
>> + rtc: rtc at 1 {
>> + compatible = "hisilicon,hi655x-pmu-rtc";
>> + interrupt-parent = <&pmic>;
>> + interrupts = <20 0>;
>> + interrupt-names = "hi655x_pmu_rtc";
>> + board_id = <1>;
>> + };
>> +
>> + usbvbus:usbvbus at b2{
>> + compatible = "hisilicon,hi655x-usbvbus";
>> + interrupt-parent = <&pmic>;
>> + interrupts = <9 0>, <8 0>;
>> + interrupt-names = "connect", "disconnect";
>> + };
>> +
>> + ldo2: regulator at a21 {
>> + compatible = "hisilicon,hi655x-regulator-pmic";
>> + regulator-name = "ldo2";
>> + regulator-min-microvolt = <2500000>;
>> + regulator-max-microvolt = <3200000>;
>> + hisilicon,valid-modes-mask = <0x02>;
>> + hisilicon,valid-ops-mask = <0x01d>;
>> + hisilicon,initial-mode = <0x02>;
>> + hisilicon,regulator-type = <0x01>;
>> +
>> + hisilicon,off-on-delay = <120>;
>> + hisilicon,ctrl-regs = <0x029 0x02a 0x02b>;
>> + hisilicon,ctrl-data = <0x1 0x1>;
>> + hisilicon,vset-regs = <0x072>;
>> + hisilicon,vset-data = <0 0x3>;
>> + hisilicon,regulator-n-vol = <8>;
>> + hisilicon,vset-table = <2500000>,<2600000>,<2700000>,<2800000>,<2900000>,<3000000>,<3100000>,<3200000>;
>> + hisilicon,num_consumer_supplies = <1>;
>> + hisilicon,consumer-supplies = "sensor_analog";
>> + };
>> + };
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator
2015-09-30 17:58 ` Mark Brown
@ 2015-10-08 7:38 ` wangfei
0 siblings, 0 replies; 18+ messages in thread
From: wangfei @ 2015-10-08 7:38 UTC (permalink / raw)
To: linux-arm-kernel
On 2015/10/1 1:58, Mark Brown wrote:
> On Wed, Sep 30, 2015 at 07:05:07PM +0800, Fei Wang wrote:
>
>> +config REGULATOR_HI655X
>> + tristate "Hisilicon HI655X PMIC regulators support"
>> + depends on ARCH_HISI
>> + depends on MFD_HI655X_PMIC && OF
>
> You've got some tab/space confusion above. Also, can't we have an ||
> COMPILE_TEST here?
>
OK, i will add it.
>> +#define REG_VALUE_SETBITS(reg_value, pos, bits, bits_value) \
>> + (reg_value = (reg_value & \
>> + ~((((unsigned int)1 << bits) - 1) << pos)) | \
>> + ((unsigned int)(bits_value & \
>> + (((unsigned int)1 << bits) - 1)) << pos))
>> +
>> +#define REG_VALUE_GETBITS(reg_value, pos, bits) \
>> + ((reg_value >> pos) & (((unsigned int)1 << bits) - 1))
>
> These are just really hard to read, sorry, and they appear to duplicate
> existing regmap functionality. If there is a strong reason to add them
> consider doing so in the core and if you can then please at least make
> them regular inline functions rather than using macros. It's much safer
> and more readable.
>
i agree with you ?i will refactor all the unreadable code?
>> +static int hi655x_regulator_pmic_is_enabled(struct regulator_dev *rdev)
>> +{
>> + int ret = 0;
>> + unsigned int value = 0;
>> +
>> + struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
>> + struct hi655x_regulator_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
>> + struct hi655x_regulator_ctrl_data *ctrl_data = &(sreg->ctrl_data);
>> +
>> + /*
>> + * regulator is all set,but the pmu is only subset.
>> + * maybe this "buck"/"ldo"/"lvs" is not contrl by a core.
>> + * and in regulator have a "status" member ("okey" or "disable").
>> + */
>
> I'm having a hard time parsing the above comment. Please also use the
> normal kernel comment style (this is a problem throughout the driver).
>
OK. i will modify all of these?
>> + regmap_read(rdev->regmap, ctrl_regs->status_reg, &value);
>> + ret = (int)REG_VALUE_GETBITS(value, ctrl_data->shift,
>> + ctrl_data->mask);
>
> This appears to just duplicate regulator core functionality for reading
> enable state from a bitfield? Also note that the cast here isn't a
> great advert for the macros above.
>
>> +static int hi655x_regulator_pmic_enable(struct regulator_dev *rdev)
>> +{
>> + int ret = 0;
>> + unsigned char value_u8 = 0;
>> + unsigned int value_u32 = 0;
>> + struct hi655x_regulator *sreg = rdev_get_drvdata(rdev);
>> + struct hi655x_regulator_ctrl_regs *ctrl_regs = &(sreg->ctrl_regs);
>> + struct hi655x_regulator_ctrl_data *ctrl_data = &(sreg->ctrl_data);
>> +
>> + REG_VALUE_SETBITS(value_u32, ctrl_data->shift, ctrl_data->mask, 0x1);
>> + value_u8 = (unsigned char)value_u32;
>> + regmap_write(rdev->regmap, ctrl_regs->enable_reg, value_u8);
>
> I'm not *entirely* sure what this is supposed to be doing but it looks
> like it's duplicating core functionality in a fashion that's really
> quite hard to read. Why not just use the core functions for setting
> bits?
>
>> + udelay(sreg->off_on_delay);
>
> Use the regualtor core delay functionality please.
OK?i will modify it?
>
>> +static int hi655x_regulator_pmic_list_voltage_linear(struct regulator_dev *rdev,
>> + unsigned int selector)
>
> This is *definitely* duplicating core functionality, I think you want to
> use regulator_list_voltage_linear_range() or possibly just plain
> _linear() and use separate operations for the LVS regulator.
>
> We at least need to restructure the code so that the core helper
> functions are used and we don't have regulator type decisions everywhere
> - the whole goal of having per regulator ops is to avoid having to open
> code decisions about which regulator we're dealing with into each op
> function.
>
OK?i will modify it?
>> +static unsigned int hi655x_regulator_pmic_get_mode(
>> + struct regulator_dev *rdev)
>> +{
>> + return REGULATOR_MODE_NORMAL;
>> +}
>
> Don't implement empty functions, remove all these.
>
>> + num_consumer_supplies = of_get_property(np,
>> + "hisilicon,num_consumer_supplies", NULL);
>> +
>> + if ((NULL == num_consumer_supplies) || (0 == *num_consumer_supplies)) {
>> + dev_warn(dev, "%s no consumer_supplies\n", __func__);
>> + return init_data;
>> + }
>
> Obviously the binding is completely undocumented but this is setting off
> alarm bells - why is the driver even considering consumers? Please make
> sure you are using the core regulator bindings rather than open coding
> something which translates into platform data (which is what this looks
> like).
>
> I'm not going to review any more of the DT code without binding
> documentation.
I will document the dt-binding first?
>
>> + /*
>> + *initdata mem will release auto;
>> + *this is kernel 3.10 import.
>> + */
>
> Remove anything related to your vendor kernel support, this is not
> relevant to upstream.
>
Thanks?Mark?i agree with you and will modify all of you mentioned soon?
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator
2015-09-30 11:05 ` [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator Fei Wang
2015-09-30 17:58 ` Mark Brown
@ 2015-10-08 7:47 ` Javier Martinez Canillas
1 sibling, 0 replies; 18+ messages in thread
From: Javier Martinez Canillas @ 2015-10-08 7:47 UTC (permalink / raw)
To: linux-arm-kernel
Hello Fei Wang,
On Wed, Sep 30, 2015 at 1:05 PM, Fei Wang <w.f@huawei.com> wrote:
> Add Hi655x regulator driver.
>
> Signed-off-by: Fei Wang <w.f@huawei.com>
> ---
[snip]
>
> +config REGULATOR_HI655X
> + tristate "Hisilicon HI655X PMIC regulators support"
The Kconfig symbol is tree state which means it can be built as a module...
> +
> +static const struct of_device_id of_hi655x_regulator_match_tbl[] = {
> + {
> + .compatible = "hisilicon,hi655x-regulator-pmic",
> + .data = &hi655x_regulator_pmic,
> + },
> + { /* end */ }
> +};
...but the OF module alias information is not built into the module so
module autoloading won't work.
Please add a MODULE_DEVICE_TABLE(of, of_hi655x_regulator_match_tbl) here.
Best regards,
Javier
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver
2015-10-08 6:33 ` wangfei
@ 2015-10-12 16:49 ` Mark Brown
0 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2015-10-12 16:49 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Oct 08, 2015 at 02:33:06PM +0800, wangfei wrote:
> On 2015/10/1 1:39, Mark Brown wrote:
> > On Wed, Sep 30, 2015 at 07:05:04PM +0800, Fei Wang wrote:
Please fix your mail client to word wrap within paragraphs at something
substantially less than 80 columns. Doing this makes your messages much
easier to read and reply to.
> >> + coul: coul at 1 {
> >> + compatible = "hisilicon,hi655x-coul";
> >> + interrupt-parent = <&pmic>;
> >> + interrupts = <24 0>, <25 0>, <26 0>, <27 0>;
> >> + interrupt-names = "cl_int_i", "cl_out_i", "cl_in_i", "vbat_int_i";
> >> + battery_product_index = <0>;
> > For example, the "battery_product_index" property here is undocumented.
> now on hikey, we only enable hi655x-regulator-pmic function, and
> regulator is child node of pmic.do i need to document regulator
> dt-binding in this file or create a new regulator dt-binding file?
Either is possible, though it is common to split the DT documentation
into per subsystem files for ease of reference and to avoid cross tree
merge issues.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151012/123109fb/attachment.sig>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2015-10-12 16:49 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-30 11:05 [PATCH 0/8] Add Support for Hi6220 PMIC Hi6553 MFD Core and Regulator Fei Wang
2015-09-30 11:05 ` [PATCH 1/8] dt-bindings: pmic: Document Hi655x pmic driver Fei Wang
2015-09-30 17:39 ` Mark Brown
2015-10-08 6:33 ` wangfei
2015-10-12 16:49 ` Mark Brown
2015-10-01 7:56 ` Lee Jones
2015-10-01 7:58 ` Lee Jones
2015-10-08 7:03 ` wangfei
2015-09-30 11:05 ` [PATCH 2/8] mfd: Hi655x: Add support for PMIC Hi655x MFD Fei Wang
2015-09-30 11:05 ` [PATCH 3/8] arm64: dts: add Hi655x pmic node Fei Wang
2015-09-30 11:05 ` [PATCH 4/8] regulator: Hi655x: Add support for Hi655x regulator Fei Wang
2015-09-30 17:58 ` Mark Brown
2015-10-08 7:38 ` wangfei
2015-10-08 7:47 ` Javier Martinez Canillas
2015-09-30 11:05 ` [PATCH 5/8] arm64: dts: Add Hi655x regulator config node Fei Wang
2015-09-30 11:05 ` [PATCH 6/8] dt-bindings: mtcmos: Document Hi6220 mtcmos driver Fei Wang
2015-09-30 11:05 ` [PATCH 7/8] mtcmos: Hi6220: Add Hi6220 mtcmos regulator driver Fei Wang
2015-09-30 11:05 ` [PATCH 8/8] arm64: dts: Add Hi6220 mtcmos regulator node Fei Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).