* [PATCH 01/14] mfd: remove unused 88pm80x driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-11 7:24 ` Krzysztof Kozlowski
2026-09-09 13:21 ` [PATCH 02/14] mfd: remove unused rdc321x southbridge support Arnd Bergmann
` (13 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
This pair of drivers was originally added as companion chips for pxa/mmp
SoCs, but the corresponding platform code was never merged, so it has
been unused the entire time.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
.../devicetree/bindings/regulator/88pm800.txt | 38 --
drivers/input/misc/88pm80x_onkey.c | 152 -----
drivers/input/misc/Kconfig | 10 -
drivers/input/misc/Makefile | 1 -
drivers/mfd/88pm800.c | 619 ------------------
drivers/mfd/88pm805.c | 275 --------
drivers/mfd/88pm80x.c | 159 -----
drivers/mfd/Kconfig | 24 -
drivers/mfd/Makefile | 2 -
drivers/regulator/88pm800-regulator.c | 287 --------
drivers/regulator/Kconfig | 10 -
drivers/regulator/Makefile | 1 -
drivers/rtc/Kconfig | 10 -
drivers/rtc/Makefile | 1 -
drivers/rtc/rtc-88pm80x.c | 340 ----------
include/linux/mfd/88pm80x.h | 370 -----------
16 files changed, 2299 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/regulator/88pm800.txt
delete mode 100644 drivers/input/misc/88pm80x_onkey.c
delete mode 100644 drivers/mfd/88pm800.c
delete mode 100644 drivers/mfd/88pm805.c
delete mode 100644 drivers/mfd/88pm80x.c
delete mode 100644 drivers/regulator/88pm800-regulator.c
delete mode 100644 drivers/rtc/rtc-88pm80x.c
delete mode 100644 include/linux/mfd/88pm80x.h
diff --git a/Documentation/devicetree/bindings/regulator/88pm800.txt b/Documentation/devicetree/bindings/regulator/88pm800.txt
deleted file mode 100644
index e8a54c2a5821..000000000000
--- a/Documentation/devicetree/bindings/regulator/88pm800.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-Marvell 88PM800 regulator
-
-Required properties:
-- compatible: "marvell,88pm800"
-- reg: I2C slave address
-- regulators: A node that houses a sub-node for each regulator within the
- device. Each sub-node is identified using the node's name (or the deprecated
- regulator-compatible property if present), with valid values listed below.
- The content of each sub-node is defined by the standard binding for
- regulators; see regulator.txt.
-
-The valid names for regulators are:
-
- buck1, buck2, buck3, buck4, buck5, ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7,
- ldo8, ldo9, ldo10, ldo11, ldo12, ldo13, ldo14, ldo15, ldo16, ldo17, ldo18, ldo19
-
-Example:
-
- pmic: 88pm800@31 {
- compatible = "marvell,88pm800";
- reg = <0x31>;
-
- regulators {
- buck1 {
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <3950000>;
- regulator-boot-on;
- regulator-always-on;
- };
- ldo1 {
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <15000000>;
- regulator-boot-on;
- regulator-always-on;
- };
-...
- };
- };
diff --git a/drivers/input/misc/88pm80x_onkey.c b/drivers/input/misc/88pm80x_onkey.c
deleted file mode 100644
index fee28e537898..000000000000
--- a/drivers/input/misc/88pm80x_onkey.c
+++ /dev/null
@@ -1,152 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Marvell 88PM80x ONKEY driver
- *
- * Copyright (C) 2012 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- * Qiao Zhou <zhouqiao@marvell.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/input.h>
-#include <linux/mfd/88pm80x.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-
-#define PM800_LONG_ONKEY_EN (1 << 0)
-#define PM800_LONG_KEY_DELAY (8) /* 1 .. 16 seconds */
-#define PM800_LONKEY_PRESS_TIME ((PM800_LONG_KEY_DELAY-1) << 4)
-#define PM800_LONKEY_PRESS_TIME_MASK (0xF0)
-#define PM800_SW_PDOWN (1 << 5)
-
-struct pm80x_onkey_info {
- struct input_dev *idev;
- struct pm80x_chip *pm80x;
- struct regmap *map;
- int irq;
-};
-
-/* 88PM80x gives us an interrupt when ONKEY is held */
-static irqreturn_t pm80x_onkey_handler(int irq, void *data)
-{
- struct pm80x_onkey_info *info = data;
- int ret = 0;
- unsigned int val;
-
- ret = regmap_read(info->map, PM800_STATUS_1, &val);
- if (ret < 0) {
- dev_err(info->idev->dev.parent, "failed to read status: %d\n", ret);
- return IRQ_NONE;
- }
- val &= PM800_ONKEY_STS1;
-
- input_report_key(info->idev, KEY_POWER, val);
- input_sync(info->idev);
-
- return IRQ_HANDLED;
-}
-
-static SIMPLE_DEV_PM_OPS(pm80x_onkey_pm_ops, pm80x_dev_suspend,
- pm80x_dev_resume);
-
-static int pm80x_onkey_probe(struct platform_device *pdev)
-{
-
- struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm80x_onkey_info *info;
- int err;
-
- info = kzalloc_obj(*info);
- if (!info)
- return -ENOMEM;
-
- info->pm80x = chip;
-
- info->irq = platform_get_irq(pdev, 0);
- if (info->irq < 0) {
- err = -EINVAL;
- goto out;
- }
-
- info->map = info->pm80x->regmap;
- if (!info->map) {
- dev_err(&pdev->dev, "no regmap!\n");
- err = -EINVAL;
- goto out;
- }
-
- info->idev = input_allocate_device();
- if (!info->idev) {
- dev_err(&pdev->dev, "Failed to allocate input dev\n");
- err = -ENOMEM;
- goto out;
- }
-
- info->idev->name = "88pm80x_on";
- info->idev->phys = "88pm80x_on/input0";
- info->idev->id.bustype = BUS_I2C;
- info->idev->dev.parent = &pdev->dev;
- info->idev->evbit[0] = BIT_MASK(EV_KEY);
- __set_bit(KEY_POWER, info->idev->keybit);
-
- err = pm80x_request_irq(info->pm80x, info->irq, pm80x_onkey_handler,
- IRQF_ONESHOT, "onkey", info);
- if (err < 0) {
- dev_err(&pdev->dev, "Failed to request IRQ: #%d: %d\n",
- info->irq, err);
- goto out_reg;
- }
-
- err = input_register_device(info->idev);
- if (err) {
- dev_err(&pdev->dev, "Can't register input device: %d\n", err);
- goto out_irq;
- }
-
- platform_set_drvdata(pdev, info);
-
- /* Enable long onkey detection */
- regmap_update_bits(info->map, PM800_RTC_MISC4, PM800_LONG_ONKEY_EN,
- PM800_LONG_ONKEY_EN);
- /* Set 8-second interval */
- regmap_update_bits(info->map, PM800_RTC_MISC3,
- PM800_LONKEY_PRESS_TIME_MASK,
- PM800_LONKEY_PRESS_TIME);
-
- device_init_wakeup(&pdev->dev, 1);
- return 0;
-
-out_irq:
- pm80x_free_irq(info->pm80x, info->irq, info);
-out_reg:
- input_free_device(info->idev);
-out:
- kfree(info);
- return err;
-}
-
-static void pm80x_onkey_remove(struct platform_device *pdev)
-{
- struct pm80x_onkey_info *info = platform_get_drvdata(pdev);
-
- pm80x_free_irq(info->pm80x, info->irq, info);
- input_unregister_device(info->idev);
- kfree(info);
-}
-
-static struct platform_driver pm80x_onkey_driver = {
- .driver = {
- .name = "88pm80x-onkey",
- .pm = &pm80x_onkey_pm_ops,
- },
- .probe = pm80x_onkey_probe,
- .remove = pm80x_onkey_remove,
-};
-
-module_platform_driver(pm80x_onkey_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Marvell 88PM80x ONKEY driver");
-MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
-MODULE_ALIAS("platform:88pm80x-onkey");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 169768e3d5bb..013ae22311ee 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -23,16 +23,6 @@ config INPUT_88PM860X_ONKEY
To compile this driver as a module, choose M here: the module
will be called 88pm860x_onkey.
-config INPUT_88PM80X_ONKEY
- tristate "88PM80x ONKEY support"
- depends on MFD_88PM800
- help
- Support the ONKEY of Marvell 88PM80x PMICs as an input device
- reporting power button status.
-
- To compile this driver as a module, choose M here: the module
- will be called 88pm80x_onkey.
-
config INPUT_88PM886_ONKEY
tristate "Marvell 88PM886 onkey support"
depends on MFD_88PM886_PMIC
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 1339619f0769..b120799b05eb 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -6,7 +6,6 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
-obj-$(CONFIG_INPUT_88PM80X_ONKEY) += 88pm80x_onkey.o
obj-$(CONFIG_INPUT_88PM886_ONKEY) += 88pm886-onkey.o
obj-$(CONFIG_INPUT_AB8500_PONKEY) += ab8500-ponkey.o
obj-$(CONFIG_INPUT_AD714X) += ad714x.o
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
deleted file mode 100644
index e9941da58b18..000000000000
--- a/drivers/mfd/88pm800.c
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * Base driver for Marvell 88PM800
- *
- * Copyright (C) 2012 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- * Joseph(Yossi) Hanin <yhanin@marvell.com>
- * Qiao Zhou <zhouqiao@marvell.com>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file "COPYING" in the main directory of this
- * archive for more details.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/88pm80x.h>
-#include <linux/slab.h>
-
-/* Interrupt Registers */
-#define PM800_INT_STATUS1 (0x05)
-#define PM800_ONKEY_INT_STS1 (1 << 0)
-#define PM800_EXTON_INT_STS1 (1 << 1)
-#define PM800_CHG_INT_STS1 (1 << 2)
-#define PM800_BAT_INT_STS1 (1 << 3)
-#define PM800_RTC_INT_STS1 (1 << 4)
-#define PM800_CLASSD_OC_INT_STS1 (1 << 5)
-
-#define PM800_INT_STATUS2 (0x06)
-#define PM800_VBAT_INT_STS2 (1 << 0)
-#define PM800_VSYS_INT_STS2 (1 << 1)
-#define PM800_VCHG_INT_STS2 (1 << 2)
-#define PM800_TINT_INT_STS2 (1 << 3)
-#define PM800_GPADC0_INT_STS2 (1 << 4)
-#define PM800_TBAT_INT_STS2 (1 << 5)
-#define PM800_GPADC2_INT_STS2 (1 << 6)
-#define PM800_GPADC3_INT_STS2 (1 << 7)
-
-#define PM800_INT_STATUS3 (0x07)
-
-#define PM800_INT_STATUS4 (0x08)
-#define PM800_GPIO0_INT_STS4 (1 << 0)
-#define PM800_GPIO1_INT_STS4 (1 << 1)
-#define PM800_GPIO2_INT_STS4 (1 << 2)
-#define PM800_GPIO3_INT_STS4 (1 << 3)
-#define PM800_GPIO4_INT_STS4 (1 << 4)
-
-#define PM800_INT_ENA_1 (0x09)
-#define PM800_ONKEY_INT_ENA1 (1 << 0)
-#define PM800_EXTON_INT_ENA1 (1 << 1)
-#define PM800_CHG_INT_ENA1 (1 << 2)
-#define PM800_BAT_INT_ENA1 (1 << 3)
-#define PM800_RTC_INT_ENA1 (1 << 4)
-#define PM800_CLASSD_OC_INT_ENA1 (1 << 5)
-
-#define PM800_INT_ENA_2 (0x0A)
-#define PM800_VBAT_INT_ENA2 (1 << 0)
-#define PM800_VSYS_INT_ENA2 (1 << 1)
-#define PM800_VCHG_INT_ENA2 (1 << 2)
-#define PM800_TINT_INT_ENA2 (1 << 3)
-
-#define PM800_INT_ENA_3 (0x0B)
-#define PM800_GPADC0_INT_ENA3 (1 << 0)
-#define PM800_GPADC1_INT_ENA3 (1 << 1)
-#define PM800_GPADC2_INT_ENA3 (1 << 2)
-#define PM800_GPADC3_INT_ENA3 (1 << 3)
-#define PM800_GPADC4_INT_ENA3 (1 << 4)
-
-#define PM800_INT_ENA_4 (0x0C)
-#define PM800_GPIO0_INT_ENA4 (1 << 0)
-#define PM800_GPIO1_INT_ENA4 (1 << 1)
-#define PM800_GPIO2_INT_ENA4 (1 << 2)
-#define PM800_GPIO3_INT_ENA4 (1 << 3)
-#define PM800_GPIO4_INT_ENA4 (1 << 4)
-
-/* number of INT_ENA & INT_STATUS regs */
-#define PM800_INT_REG_NUM (4)
-
-/* Interrupt Number in 88PM800 */
-enum {
- PM800_IRQ_ONKEY, /*EN1b0 *//*0 */
- PM800_IRQ_EXTON, /*EN1b1 */
- PM800_IRQ_CHG, /*EN1b2 */
- PM800_IRQ_BAT, /*EN1b3 */
- PM800_IRQ_RTC, /*EN1b4 */
- PM800_IRQ_CLASSD, /*EN1b5 *//*5 */
- PM800_IRQ_VBAT, /*EN2b0 */
- PM800_IRQ_VSYS, /*EN2b1 */
- PM800_IRQ_VCHG, /*EN2b2 */
- PM800_IRQ_TINT, /*EN2b3 */
- PM800_IRQ_GPADC0, /*EN3b0 *//*10 */
- PM800_IRQ_GPADC1, /*EN3b1 */
- PM800_IRQ_GPADC2, /*EN3b2 */
- PM800_IRQ_GPADC3, /*EN3b3 */
- PM800_IRQ_GPADC4, /*EN3b4 */
- PM800_IRQ_GPIO0, /*EN4b0 *//*15 */
- PM800_IRQ_GPIO1, /*EN4b1 */
- PM800_IRQ_GPIO2, /*EN4b2 */
- PM800_IRQ_GPIO3, /*EN4b3 */
- PM800_IRQ_GPIO4, /*EN4b4 *//*19 */
- PM800_MAX_IRQ,
-};
-
-/* PM800: generation identification number */
-#define PM800_CHIP_GEN_ID_NUM 0x3
-
-static const struct i2c_device_id pm80x_id_table[] = {
- { "88PM800" },
- {} /* NULL terminated */
-};
-MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
-
-static const struct resource rtc_resources[] = {
- DEFINE_RES_IRQ_NAMED(PM800_IRQ_RTC, "88pm80x-rtc"),
-};
-
-static struct mfd_cell rtc_devs[] = {
- {
- .name = "88pm80x-rtc",
- .num_resources = ARRAY_SIZE(rtc_resources),
- .resources = &rtc_resources[0],
- .id = -1,
- },
-};
-
-static struct resource onkey_resources[] = {
- DEFINE_RES_IRQ_NAMED(PM800_IRQ_ONKEY, "88pm80x-onkey"),
-};
-
-static const struct mfd_cell onkey_devs[] = {
- {
- .name = "88pm80x-onkey",
- .num_resources = 1,
- .resources = &onkey_resources[0],
- .id = -1,
- },
-};
-
-static const struct mfd_cell regulator_devs[] = {
- {
- .name = "88pm80x-regulator",
- .id = -1,
- },
-};
-
-static const struct regmap_irq pm800_irqs[] = {
- /* INT0 */
- [PM800_IRQ_ONKEY] = {
- .mask = PM800_ONKEY_INT_ENA1,
- },
- [PM800_IRQ_EXTON] = {
- .mask = PM800_EXTON_INT_ENA1,
- },
- [PM800_IRQ_CHG] = {
- .mask = PM800_CHG_INT_ENA1,
- },
- [PM800_IRQ_BAT] = {
- .mask = PM800_BAT_INT_ENA1,
- },
- [PM800_IRQ_RTC] = {
- .mask = PM800_RTC_INT_ENA1,
- },
- [PM800_IRQ_CLASSD] = {
- .mask = PM800_CLASSD_OC_INT_ENA1,
- },
- /* INT1 */
- [PM800_IRQ_VBAT] = {
- .reg_offset = 1,
- .mask = PM800_VBAT_INT_ENA2,
- },
- [PM800_IRQ_VSYS] = {
- .reg_offset = 1,
- .mask = PM800_VSYS_INT_ENA2,
- },
- [PM800_IRQ_VCHG] = {
- .reg_offset = 1,
- .mask = PM800_VCHG_INT_ENA2,
- },
- [PM800_IRQ_TINT] = {
- .reg_offset = 1,
- .mask = PM800_TINT_INT_ENA2,
- },
- /* INT2 */
- [PM800_IRQ_GPADC0] = {
- .reg_offset = 2,
- .mask = PM800_GPADC0_INT_ENA3,
- },
- [PM800_IRQ_GPADC1] = {
- .reg_offset = 2,
- .mask = PM800_GPADC1_INT_ENA3,
- },
- [PM800_IRQ_GPADC2] = {
- .reg_offset = 2,
- .mask = PM800_GPADC2_INT_ENA3,
- },
- [PM800_IRQ_GPADC3] = {
- .reg_offset = 2,
- .mask = PM800_GPADC3_INT_ENA3,
- },
- [PM800_IRQ_GPADC4] = {
- .reg_offset = 2,
- .mask = PM800_GPADC4_INT_ENA3,
- },
- /* INT3 */
- [PM800_IRQ_GPIO0] = {
- .reg_offset = 3,
- .mask = PM800_GPIO0_INT_ENA4,
- },
- [PM800_IRQ_GPIO1] = {
- .reg_offset = 3,
- .mask = PM800_GPIO1_INT_ENA4,
- },
- [PM800_IRQ_GPIO2] = {
- .reg_offset = 3,
- .mask = PM800_GPIO2_INT_ENA4,
- },
- [PM800_IRQ_GPIO3] = {
- .reg_offset = 3,
- .mask = PM800_GPIO3_INT_ENA4,
- },
- [PM800_IRQ_GPIO4] = {
- .reg_offset = 3,
- .mask = PM800_GPIO4_INT_ENA4,
- },
-};
-
-static int device_gpadc_init(struct pm80x_chip *chip,
- struct pm80x_platform_data *pdata)
-{
- struct pm80x_subchip *subchip = chip->subchip;
- struct regmap *map = subchip->regmap_gpadc;
- int data = 0, mask = 0, ret = 0;
-
- if (!map) {
- dev_warn(chip->dev,
- "Warning: gpadc regmap is not available!\n");
- return -EINVAL;
- }
- /*
- * initialize GPADC without activating it turn on GPADC
- * measurments
- */
- ret = regmap_update_bits(map,
- PM800_GPADC_MISC_CONFIG2,
- PM800_GPADC_MISC_GPFSM_EN,
- PM800_GPADC_MISC_GPFSM_EN);
- if (ret < 0)
- goto out;
- /*
- * This function configures the ADC as requires for
- * CP implementation.CP does not "own" the ADC configuration
- * registers and relies on AP.
- * Reason: enable automatic ADC measurements needed
- * for CP to get VBAT and RF temperature readings.
- */
- ret = regmap_update_bits(map, PM800_GPADC_MEAS_EN1,
- PM800_MEAS_EN1_VBAT, PM800_MEAS_EN1_VBAT);
- if (ret < 0)
- goto out;
- ret = regmap_update_bits(map, PM800_GPADC_MEAS_EN2,
- (PM800_MEAS_EN2_RFTMP | PM800_MEAS_GP0_EN),
- (PM800_MEAS_EN2_RFTMP | PM800_MEAS_GP0_EN));
- if (ret < 0)
- goto out;
-
- /*
- * the defult of PM800 is GPADC operates at 100Ks/s rate
- * and Number of GPADC slots with active current bias prior
- * to GPADC sampling = 1 slot for all GPADCs set for
- * Temprature mesurmants
- */
- mask = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN1 |
- PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3);
-
- if (pdata && (pdata->batt_det == 0))
- data = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN1 |
- PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3);
- else
- data = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN2 |
- PM800_GPADC_GP_BIAS_EN3);
-
- ret = regmap_update_bits(map, PM800_GP_BIAS_ENA1, mask, data);
- if (ret < 0)
- goto out;
-
- dev_info(chip->dev, "pm800 device_gpadc_init: Done\n");
- return 0;
-
-out:
- dev_info(chip->dev, "pm800 device_gpadc_init: Failed!\n");
- return ret;
-}
-
-static int device_onkey_init(struct pm80x_chip *chip,
- struct pm80x_platform_data *pdata)
-{
- int ret;
-
- ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
- ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
- NULL);
- if (ret) {
- dev_err(chip->dev, "Failed to add onkey subdev\n");
- return ret;
- }
-
- return 0;
-}
-
-static int device_rtc_init(struct pm80x_chip *chip,
- struct pm80x_platform_data *pdata)
-{
- int ret;
-
- if (pdata) {
- rtc_devs[0].platform_data = pdata->rtc;
- rtc_devs[0].pdata_size =
- pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
- }
- ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
- ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
- if (ret) {
- dev_err(chip->dev, "Failed to add rtc subdev\n");
- return ret;
- }
-
- return 0;
-}
-
-static int device_regulator_init(struct pm80x_chip *chip,
- struct pm80x_platform_data *pdata)
-{
- int ret;
-
- ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0],
- ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
- if (ret) {
- dev_err(chip->dev, "Failed to add regulator subdev\n");
- return ret;
- }
-
- return 0;
-}
-
-static int device_irq_init_800(struct pm80x_chip *chip)
-{
- struct regmap *map = chip->regmap;
- unsigned long flags = IRQF_ONESHOT;
- int data, mask, ret = -EINVAL;
-
- if (!map || !chip->irq) {
- dev_err(chip->dev, "incorrect parameters\n");
- return -EINVAL;
- }
-
- /*
- * irq_mode defines the way of clearing interrupt. it's read-clear by
- * default.
- */
- mask =
- PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
- PM800_WAKEUP2_INT_MASK;
-
- data = PM800_WAKEUP2_INT_CLEAR;
- ret = regmap_update_bits(map, PM800_WAKEUP2, mask, data);
-
- if (ret < 0)
- goto out;
-
- ret =
- regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
- chip->regmap_irq_chip, &chip->irq_data);
-
-out:
- return ret;
-}
-
-static void device_irq_exit_800(struct pm80x_chip *chip)
-{
- regmap_del_irq_chip(chip->irq, chip->irq_data);
-}
-
-static const struct regmap_irq_chip pm800_irq_chip = {
- .name = "88pm800",
- .irqs = pm800_irqs,
- .num_irqs = ARRAY_SIZE(pm800_irqs),
-
- .num_regs = 4,
- .status_base = PM800_INT_STATUS1,
- .unmask_base = PM800_INT_ENA_1,
- .ack_base = PM800_INT_STATUS1,
-};
-
-static int pm800_pages_init(struct pm80x_chip *chip)
-{
- struct pm80x_subchip *subchip;
- struct i2c_client *client = chip->client;
-
- int ret = 0;
-
- subchip = chip->subchip;
- if (!subchip || !subchip->power_page_addr || !subchip->gpadc_page_addr)
- return -ENODEV;
-
- /* PM800 block power page */
- subchip->power_page = i2c_new_dummy_device(client->adapter,
- subchip->power_page_addr);
- if (IS_ERR(subchip->power_page)) {
- ret = PTR_ERR(subchip->power_page);
- goto out;
- }
-
- subchip->regmap_power = devm_regmap_init_i2c(subchip->power_page,
- &pm80x_regmap_config);
- if (IS_ERR(subchip->regmap_power)) {
- ret = PTR_ERR(subchip->regmap_power);
- dev_err(chip->dev,
- "Failed to allocate regmap_power: %d\n", ret);
- goto out;
- }
-
- i2c_set_clientdata(subchip->power_page, chip);
-
- /* PM800 block GPADC */
- subchip->gpadc_page = i2c_new_dummy_device(client->adapter,
- subchip->gpadc_page_addr);
- if (IS_ERR(subchip->gpadc_page)) {
- ret = PTR_ERR(subchip->gpadc_page);
- goto out;
- }
-
- subchip->regmap_gpadc = devm_regmap_init_i2c(subchip->gpadc_page,
- &pm80x_regmap_config);
- if (IS_ERR(subchip->regmap_gpadc)) {
- ret = PTR_ERR(subchip->regmap_gpadc);
- dev_err(chip->dev,
- "Failed to allocate regmap_gpadc: %d\n", ret);
- goto out;
- }
- i2c_set_clientdata(subchip->gpadc_page, chip);
-
-out:
- return ret;
-}
-
-static void pm800_pages_exit(struct pm80x_chip *chip)
-{
- struct pm80x_subchip *subchip;
-
- subchip = chip->subchip;
-
- if (subchip && subchip->power_page)
- i2c_unregister_device(subchip->power_page);
-
- if (subchip && subchip->gpadc_page)
- i2c_unregister_device(subchip->gpadc_page);
-}
-
-static int device_800_init(struct pm80x_chip *chip,
- struct pm80x_platform_data *pdata)
-{
- int ret;
- unsigned int val;
-
- /*
- * alarm wake up bit will be clear in device_irq_init(),
- * read before that
- */
- ret = regmap_read(chip->regmap, PM800_RTC_CONTROL, &val);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read RTC register: %d\n", ret);
- goto out;
- }
- if (val & PM800_ALARM_WAKEUP) {
- if (pdata && pdata->rtc)
- pdata->rtc->rtc_wakeup = 1;
- }
-
- ret = device_gpadc_init(chip, pdata);
- if (ret < 0) {
- dev_err(chip->dev, "[%s]Failed to init gpadc\n", __func__);
- goto out;
- }
-
- chip->regmap_irq_chip = &pm800_irq_chip;
-
- ret = device_irq_init_800(chip);
- if (ret < 0) {
- dev_err(chip->dev, "[%s]Failed to init pm800 irq\n", __func__);
- goto out;
- }
-
- ret = device_onkey_init(chip, pdata);
- if (ret) {
- dev_err(chip->dev, "Failed to add onkey subdev\n");
- goto out_dev;
- }
-
- ret = device_rtc_init(chip, pdata);
- if (ret) {
- dev_err(chip->dev, "Failed to add rtc subdev\n");
- goto out;
- }
-
- ret = device_regulator_init(chip, pdata);
- if (ret) {
- dev_err(chip->dev, "Failed to add regulators subdev\n");
- goto out;
- }
-
- return 0;
-out_dev:
- mfd_remove_devices(chip->dev);
- device_irq_exit_800(chip);
-out:
- return ret;
-}
-
-static int pm800_probe(struct i2c_client *client)
-{
- int ret = 0;
- struct pm80x_chip *chip;
- struct pm80x_platform_data *pdata = dev_get_platdata(&client->dev);
- struct pm80x_subchip *subchip;
-
- ret = pm80x_init(client);
- if (ret) {
- dev_err(&client->dev, "pm800_init fail\n");
- goto out_init;
- }
-
- chip = i2c_get_clientdata(client);
-
- /* init subchip for PM800 */
- subchip =
- devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
- GFP_KERNEL);
- if (!subchip) {
- ret = -ENOMEM;
- goto err_subchip_alloc;
- }
-
- /* pm800 has 2 addtional pages to support power and gpadc. */
- subchip->power_page_addr = client->addr + 1;
- subchip->gpadc_page_addr = client->addr + 2;
- chip->subchip = subchip;
-
- ret = pm800_pages_init(chip);
- if (ret) {
- dev_err(&client->dev, "pm800_pages_init failed!\n");
- goto err_device_init;
- }
-
- ret = device_800_init(chip, pdata);
- if (ret) {
- dev_err(chip->dev, "Failed to initialize 88pm800 devices\n");
- goto err_device_init;
- }
-
- if (pdata && pdata->plat_config)
- pdata->plat_config(chip, pdata);
-
- return 0;
-
-err_device_init:
- pm800_pages_exit(chip);
-err_subchip_alloc:
- pm80x_deinit();
-out_init:
- return ret;
-}
-
-static void pm800_remove(struct i2c_client *client)
-{
- struct pm80x_chip *chip = i2c_get_clientdata(client);
-
- mfd_remove_devices(chip->dev);
- device_irq_exit_800(chip);
-
- pm800_pages_exit(chip);
- pm80x_deinit();
-}
-
-static struct i2c_driver pm800_driver = {
- .driver = {
- .name = "88PM800",
- .pm = pm_sleep_ptr(&pm80x_pm_ops),
- },
- .probe = pm800_probe,
- .remove = pm800_remove,
- .id_table = pm80x_id_table,
-};
-
-static int __init pm800_i2c_init(void)
-{
- return i2c_add_driver(&pm800_driver);
-}
-subsys_initcall(pm800_i2c_init);
-
-static void __exit pm800_i2c_exit(void)
-{
- i2c_del_driver(&pm800_driver);
-}
-module_exit(pm800_i2c_exit);
-
-MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM800");
-MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
deleted file mode 100644
index f5d6663172ee..000000000000
--- a/drivers/mfd/88pm805.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Base driver for Marvell 88PM805
- *
- * Copyright (C) 2012 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- * Joseph(Yossi) Hanin <yhanin@marvell.com>
- * Qiao Zhou <zhouqiao@marvell.com>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file "COPYING" in the main directory of this
- * archive for more details.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/88pm80x.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-static const struct i2c_device_id pm80x_id_table[] = {
- { "88PM805" },
- {} /* NULL terminated */
-};
-MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
-
-/* Interrupt Number in 88PM805 */
-enum {
- PM805_IRQ_LDO_OFF, /*0 */
- PM805_IRQ_SRC_DPLL_LOCK, /*1 */
- PM805_IRQ_CLIP_FAULT,
- PM805_IRQ_MIC_CONFLICT,
- PM805_IRQ_HP2_SHRT,
- PM805_IRQ_HP1_SHRT, /*5 */
- PM805_IRQ_FINE_PLL_FAULT,
- PM805_IRQ_RAW_PLL_FAULT,
- PM805_IRQ_VOLP_BTN_DET,
- PM805_IRQ_VOLM_BTN_DET,
- PM805_IRQ_SHRT_BTN_DET, /*10 */
- PM805_IRQ_MIC_DET, /*11 */
-
- PM805_MAX_IRQ,
-};
-
-static struct resource codec_resources[] = {
- /* Headset microphone insertion or removal */
- DEFINE_RES_IRQ_NAMED(PM805_IRQ_MIC_DET, "micin"),
-
- /* Audio short HP1 */
- DEFINE_RES_IRQ_NAMED(PM805_IRQ_HP1_SHRT, "audio-short1"),
-
- /* Audio short HP2 */
- DEFINE_RES_IRQ_NAMED(PM805_IRQ_HP2_SHRT, "audio-short2"),
-};
-
-static const struct mfd_cell codec_devs[] = {
- {
- .name = "88pm80x-codec",
- .num_resources = ARRAY_SIZE(codec_resources),
- .resources = &codec_resources[0],
- .id = -1,
- },
-};
-
-static const struct regmap_irq pm805_irqs[] = {
- /* INT0 */
- [PM805_IRQ_LDO_OFF] = {
- .mask = PM805_INT1_HP1_SHRT,
- },
- [PM805_IRQ_SRC_DPLL_LOCK] = {
- .mask = PM805_INT1_HP2_SHRT,
- },
- [PM805_IRQ_CLIP_FAULT] = {
- .mask = PM805_INT1_MIC_CONFLICT,
- },
- [PM805_IRQ_MIC_CONFLICT] = {
- .mask = PM805_INT1_CLIP_FAULT,
- },
- [PM805_IRQ_HP2_SHRT] = {
- .mask = PM805_INT1_LDO_OFF,
- },
- [PM805_IRQ_HP1_SHRT] = {
- .mask = PM805_INT1_SRC_DPLL_LOCK,
- },
- /* INT1 */
- [PM805_IRQ_FINE_PLL_FAULT] = {
- .reg_offset = 1,
- .mask = PM805_INT2_MIC_DET,
- },
- [PM805_IRQ_RAW_PLL_FAULT] = {
- .reg_offset = 1,
- .mask = PM805_INT2_SHRT_BTN_DET,
- },
- [PM805_IRQ_VOLP_BTN_DET] = {
- .reg_offset = 1,
- .mask = PM805_INT2_VOLM_BTN_DET,
- },
- [PM805_IRQ_VOLM_BTN_DET] = {
- .reg_offset = 1,
- .mask = PM805_INT2_VOLP_BTN_DET,
- },
- [PM805_IRQ_SHRT_BTN_DET] = {
- .reg_offset = 1,
- .mask = PM805_INT2_RAW_PLL_FAULT,
- },
- [PM805_IRQ_MIC_DET] = {
- .reg_offset = 1,
- .mask = PM805_INT2_FINE_PLL_FAULT,
- },
-};
-
-static int device_irq_init_805(struct pm80x_chip *chip)
-{
- struct regmap *map = chip->regmap;
- unsigned long flags = IRQF_ONESHOT;
- int data, mask, ret = -EINVAL;
-
- if (!map || !chip->irq) {
- dev_err(chip->dev, "incorrect parameters\n");
- return -EINVAL;
- }
-
- /*
- * irq_mode defines the way of clearing interrupt. it's read-clear by
- * default.
- */
- mask =
- PM805_STATUS0_INT_CLEAR | PM805_STATUS0_INV_INT |
- PM800_STATUS0_INT_MASK;
-
- data = PM805_STATUS0_INT_CLEAR;
- ret = regmap_update_bits(map, PM805_INT_STATUS0, mask, data);
- /*
- * PM805_INT_STATUS is under 32K clock domain, so need to
- * add proper delay before the next I2C register access.
- */
- usleep_range(1000, 3000);
-
- if (ret < 0)
- goto out;
-
- ret =
- regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
- chip->regmap_irq_chip, &chip->irq_data);
-
-out:
- return ret;
-}
-
-static void device_irq_exit_805(struct pm80x_chip *chip)
-{
- regmap_del_irq_chip(chip->irq, chip->irq_data);
-}
-
-static const struct regmap_irq_chip pm805_irq_chip = {
- .name = "88pm805",
- .irqs = pm805_irqs,
- .num_irqs = ARRAY_SIZE(pm805_irqs),
-
- .num_regs = 2,
- .status_base = PM805_INT_STATUS1,
- .mask_base = PM805_INT_MASK1,
- .ack_base = PM805_INT_STATUS1,
-};
-
-static int device_805_init(struct pm80x_chip *chip)
-{
- int ret = 0;
- struct regmap *map = chip->regmap;
-
- if (!map) {
- dev_err(chip->dev, "regmap is invalid\n");
- return -EINVAL;
- }
-
- chip->regmap_irq_chip = &pm805_irq_chip;
-
- ret = device_irq_init_805(chip);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to init pm805 irq!\n");
- goto out_irq_init;
- }
-
- ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
- ARRAY_SIZE(codec_devs), &codec_resources[0], 0,
- NULL);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to add codec subdev\n");
- goto out_codec;
- } else
- dev_info(chip->dev, "[%s]:Added mfd codec_devs\n", __func__);
-
- return 0;
-
-out_codec:
- device_irq_exit_805(chip);
-out_irq_init:
- return ret;
-}
-
-static int pm805_probe(struct i2c_client *client)
-{
- int ret = 0;
- struct pm80x_chip *chip;
- struct pm80x_platform_data *pdata = dev_get_platdata(&client->dev);
-
- ret = pm80x_init(client);
- if (ret) {
- dev_err(&client->dev, "pm805_init fail!\n");
- goto out_init;
- }
-
- chip = i2c_get_clientdata(client);
-
- ret = device_805_init(chip);
- if (ret) {
- dev_err(chip->dev, "Failed to initialize 88pm805 devices\n");
- goto err_805_init;
- }
-
- if (pdata && pdata->plat_config)
- pdata->plat_config(chip, pdata);
-
-err_805_init:
- pm80x_deinit();
-out_init:
- return ret;
-}
-
-static void pm805_remove(struct i2c_client *client)
-{
- struct pm80x_chip *chip = i2c_get_clientdata(client);
-
- mfd_remove_devices(chip->dev);
- device_irq_exit_805(chip);
-
- pm80x_deinit();
-}
-
-static struct i2c_driver pm805_driver = {
- .driver = {
- .name = "88PM805",
- .pm = pm_sleep_ptr(&pm80x_pm_ops),
- },
- .probe = pm805_probe,
- .remove = pm805_remove,
- .id_table = pm80x_id_table,
-};
-
-static int __init pm805_i2c_init(void)
-{
- return i2c_add_driver(&pm805_driver);
-}
-subsys_initcall(pm805_i2c_init);
-
-static void __exit pm805_i2c_exit(void)
-{
- i2c_del_driver(&pm805_driver);
-}
-module_exit(pm805_i2c_exit);
-
-MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM805");
-MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
deleted file mode 100644
index bbc1a87f0c8f..000000000000
--- a/drivers/mfd/88pm80x.c
+++ /dev/null
@@ -1,159 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * I2C driver for Marvell 88PM80x
- *
- * Copyright (C) 2012 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- * Joseph(Yossi) Hanin <yhanin@marvell.com>
- * Qiao Zhou <zhouqiao@marvell.com>
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/mfd/88pm80x.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/err.h>
-
-/* 88pm80x chips have same definition for chip id register. */
-#define PM80X_CHIP_ID (0x00)
-#define PM80X_CHIP_ID_NUM(x) (((x) >> 5) & 0x7)
-#define PM80X_CHIP_ID_REVISION(x) ((x) & 0x1F)
-
-struct pm80x_chip_mapping {
- unsigned int id;
- int type;
-};
-
-static struct pm80x_chip_mapping chip_mapping[] = {
- /* 88PM800 chip id number */
- {0x3, CHIP_PM800},
- /* 88PM805 chip id number */
- {0x0, CHIP_PM805},
- /* 88PM860 chip id number */
- {0x4, CHIP_PM860},
-};
-
-/*
- * workaround: some registers needed by pm805 are defined in pm800, so
- * need to use this global variable to maintain the relation between
- * pm800 and pm805. would remove it after HW chip fixes the issue.
- */
-static struct pm80x_chip *g_pm80x_chip;
-
-const struct regmap_config pm80x_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-};
-EXPORT_SYMBOL_GPL(pm80x_regmap_config);
-
-
-int pm80x_init(struct i2c_client *client)
-{
- struct pm80x_chip *chip;
- struct regmap *map;
- unsigned int val;
- int i, ret = 0;
-
- chip =
- devm_kzalloc(&client->dev, sizeof(struct pm80x_chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- map = devm_regmap_init_i2c(client, &pm80x_regmap_config);
- if (IS_ERR(map)) {
- ret = PTR_ERR(map);
- dev_err(&client->dev, "Failed to allocate register map: %d\n",
- ret);
- return ret;
- }
-
- chip->client = client;
- chip->regmap = map;
-
- chip->irq = client->irq;
-
- chip->dev = &client->dev;
- i2c_set_clientdata(chip->client, chip);
-
- ret = regmap_read(chip->regmap, PM80X_CHIP_ID, &val);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(chip_mapping); i++) {
- if (chip_mapping[i].id == PM80X_CHIP_ID_NUM(val)) {
- chip->type = chip_mapping[i].type;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(chip_mapping)) {
- dev_err(chip->dev,
- "Failed to detect Marvell 88PM800:ChipID[0x%x]\n", val);
- return -EINVAL;
- }
-
- device_init_wakeup(&client->dev, 1);
-
- /*
- * workaround: set g_pm80x_chip to the first probed chip. if the
- * second chip is probed, just point to the companion to each
- * other so that pm805 can access those specific register. would
- * remove it after HW chip fixes the issue.
- */
- if (!g_pm80x_chip)
- g_pm80x_chip = chip;
- else {
- chip->companion = g_pm80x_chip->client;
- g_pm80x_chip->companion = chip->client;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(pm80x_init);
-
-int pm80x_deinit(void)
-{
- /*
- * workaround: clear the dependency between pm800 and pm805.
- * would remove it after HW chip fixes the issue.
- */
- if (g_pm80x_chip->companion)
- g_pm80x_chip->companion = NULL;
- else
- g_pm80x_chip = NULL;
- return 0;
-}
-EXPORT_SYMBOL_GPL(pm80x_deinit);
-
-static int pm80x_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pm80x_chip *chip = i2c_get_clientdata(client);
-
- if (chip && chip->wu_flag)
- if (device_may_wakeup(chip->dev))
- enable_irq_wake(chip->irq);
-
- return 0;
-}
-
-static int pm80x_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pm80x_chip *chip = i2c_get_clientdata(client);
-
- if (chip && chip->wu_flag)
- if (device_may_wakeup(chip->dev))
- disable_irq_wake(chip->irq);
-
- return 0;
-}
-
-EXPORT_GPL_SIMPLE_DEV_PM_OPS(pm80x_pm_ops, pm80x_suspend, pm80x_resume);
-
-MODULE_DESCRIPTION("I2C Driver for Marvell 88PM80x");
-MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index e4fd4572472f..de81d2bb4917 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -858,30 +858,6 @@ config MFD_KEMPLD
This driver can also be built as a module. If so, the module
will be called kempld-core.
-config MFD_88PM800
- tristate "Marvell 88PM800"
- depends on I2C
- select REGMAP_I2C
- select REGMAP_IRQ
- select MFD_CORE
- help
- This supports for Marvell 88PM800 Power Management IC.
- This includes the I2C driver and the core APIs _only_, you have to
- select individual components like voltage regulators, RTC and
- battery-charger under the corresponding menus.
-
-config MFD_88PM805
- tristate "Marvell 88PM805"
- depends on I2C
- select REGMAP_I2C
- select REGMAP_IRQ
- select MFD_CORE
- help
- This supports for Marvell 88PM805 Power Management IC. This includes
- the I2C driver and the core APIs _only_, you have to select individual
- components like codec device, headset/Mic device under the
- corresponding menus.
-
config MFD_88PM860X
bool "Marvell 88PM8606/88PM8607"
depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 72d3944b0ad8..fe7156a5187a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -5,8 +5,6 @@
88pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o
obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
-obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o
-obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
obj-$(CONFIG_MFD_88PM886_PMIC) += 88pm886.o
obj-$(CONFIG_MFD_ACT8945A) += act8945a.o
obj-$(CONFIG_MFD_SM501) += sm501.o
diff --git a/drivers/regulator/88pm800-regulator.c b/drivers/regulator/88pm800-regulator.c
deleted file mode 100644
index 83e8860309dc..000000000000
--- a/drivers/regulator/88pm800-regulator.c
+++ /dev/null
@@ -1,287 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Regulators driver for Marvell 88PM800
- *
- * Copyright (C) 2012 Marvell International Ltd.
- * Joseph(Yossi) Hanin <yhanin@marvell.com>
- * Yi Zhang <yizhang@marvell.com>
- */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/regmap.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/88pm80x.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/regulator/of_regulator.h>
-
-/* LDO1 with DVC[0..3] */
-#define PM800_LDO1_VOUT (0x08) /* VOUT1 */
-#define PM800_LDO1_VOUT_2 (0x09)
-#define PM800_LDO1_VOUT_3 (0x0A)
-#define PM800_LDO2_VOUT (0x0B)
-#define PM800_LDO3_VOUT (0x0C)
-#define PM800_LDO4_VOUT (0x0D)
-#define PM800_LDO5_VOUT (0x0E)
-#define PM800_LDO6_VOUT (0x0F)
-#define PM800_LDO7_VOUT (0x10)
-#define PM800_LDO8_VOUT (0x11)
-#define PM800_LDO9_VOUT (0x12)
-#define PM800_LDO10_VOUT (0x13)
-#define PM800_LDO11_VOUT (0x14)
-#define PM800_LDO12_VOUT (0x15)
-#define PM800_LDO13_VOUT (0x16)
-#define PM800_LDO14_VOUT (0x17)
-#define PM800_LDO15_VOUT (0x18)
-#define PM800_LDO16_VOUT (0x19)
-#define PM800_LDO17_VOUT (0x1A)
-#define PM800_LDO18_VOUT (0x1B)
-#define PM800_LDO19_VOUT (0x1C)
-
-/* BUCK1 with DVC[0..3] */
-#define PM800_BUCK1 (0x3C)
-#define PM800_BUCK1_1 (0x3D)
-#define PM800_BUCK1_2 (0x3E)
-#define PM800_BUCK1_3 (0x3F)
-#define PM800_BUCK2 (0x40)
-#define PM800_BUCK3 (0x41)
-#define PM800_BUCK4 (0x42)
-#define PM800_BUCK4_1 (0x43)
-#define PM800_BUCK4_2 (0x44)
-#define PM800_BUCK4_3 (0x45)
-#define PM800_BUCK5 (0x46)
-
-#define PM800_BUCK_ENA (0x50)
-#define PM800_LDO_ENA1_1 (0x51)
-#define PM800_LDO_ENA1_2 (0x52)
-#define PM800_LDO_ENA1_3 (0x53)
-
-#define PM800_LDO_ENA2_1 (0x56)
-#define PM800_LDO_ENA2_2 (0x57)
-#define PM800_LDO_ENA2_3 (0x58)
-
-#define PM800_BUCK1_MISC1 (0x78)
-#define PM800_BUCK3_MISC1 (0x7E)
-#define PM800_BUCK4_MISC1 (0x81)
-#define PM800_BUCK5_MISC1 (0x84)
-
-struct pm800_regulator_info {
- struct regulator_desc desc;
- int max_ua;
-};
-
-/*
- * vreg - the buck regs string.
- * ereg - the string for the enable register.
- * ebit - the bit number in the enable register.
- * amax - the current
- * Buck has 2 kinds of voltage steps. It is easy to find voltage by ranges,
- * not the constant voltage table.
- * n_volt - Number of available selectors
- */
-#define PM800_BUCK(match, vreg, ereg, ebit, amax, volt_ranges, n_volt) \
-{ \
- .desc = { \
- .name = #vreg, \
- .of_match = of_match_ptr(#match), \
- .regulators_node = of_match_ptr("regulators"), \
- .ops = &pm800_volt_range_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = PM800_ID_##vreg, \
- .owner = THIS_MODULE, \
- .n_voltages = n_volt, \
- .linear_ranges = volt_ranges, \
- .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
- .vsel_reg = PM800_##vreg, \
- .vsel_mask = 0x7f, \
- .enable_reg = PM800_##ereg, \
- .enable_mask = 1 << (ebit), \
- }, \
- .max_ua = (amax), \
-}
-
-/*
- * vreg - the LDO regs string
- * ereg - the string for the enable register.
- * ebit - the bit number in the enable register.
- * amax - the current
- * volt_table - the LDO voltage table
- * For all the LDOes, there are too many ranges. Using volt_table will be
- * simpler and faster.
- */
-#define PM800_LDO(match, vreg, ereg, ebit, amax, ldo_volt_table) \
-{ \
- .desc = { \
- .name = #vreg, \
- .of_match = of_match_ptr(#match), \
- .regulators_node = of_match_ptr("regulators"), \
- .ops = &pm800_volt_table_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = PM800_ID_##vreg, \
- .owner = THIS_MODULE, \
- .n_voltages = ARRAY_SIZE(ldo_volt_table), \
- .vsel_reg = PM800_##vreg##_VOUT, \
- .vsel_mask = 0xf, \
- .enable_reg = PM800_##ereg, \
- .enable_mask = 1 << (ebit), \
- .volt_table = ldo_volt_table, \
- }, \
- .max_ua = (amax), \
-}
-
-/* Ranges are sorted in ascending order. */
-static const struct linear_range buck1_volt_range[] = {
- REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500),
- REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x54, 50000),
-};
-
-/* BUCK 2~5 have same ranges. */
-static const struct linear_range buck2_5_volt_range[] = {
- REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500),
- REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x72, 50000),
-};
-
-static const unsigned int ldo1_volt_table[] = {
- 600000, 650000, 700000, 750000, 800000, 850000, 900000, 950000,
- 1000000, 1050000, 1100000, 1150000, 1200000, 1300000, 1400000, 1500000,
-};
-
-static const unsigned int ldo2_volt_table[] = {
- 1700000, 1800000, 1900000, 2000000, 2100000, 2500000, 2700000, 2800000,
-};
-
-/* LDO 3~17 have same voltage table. */
-static const unsigned int ldo3_17_volt_table[] = {
- 1200000, 1250000, 1700000, 1800000, 1850000, 1900000, 2500000, 2600000,
- 2700000, 2750000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000,
-};
-
-/* LDO 18~19 have same voltage table. */
-static const unsigned int ldo18_19_volt_table[] = {
- 1700000, 1800000, 1900000, 2500000, 2800000, 2900000, 3100000, 3300000,
-};
-
-static int pm800_get_current_limit(struct regulator_dev *rdev)
-{
- struct pm800_regulator_info *info = rdev_get_drvdata(rdev);
-
- return info->max_ua;
-}
-
-static const struct regulator_ops pm800_volt_range_ops = {
- .list_voltage = regulator_list_voltage_linear_range,
- .map_voltage = regulator_map_voltage_linear_range,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_current_limit = pm800_get_current_limit,
-};
-
-static const struct regulator_ops pm800_volt_table_ops = {
- .list_voltage = regulator_list_voltage_table,
- .map_voltage = regulator_map_voltage_iterate,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_current_limit = pm800_get_current_limit,
-};
-
-/* The array is indexed by id(PM800_ID_XXX) */
-static struct pm800_regulator_info pm800_regulator_info[] = {
- PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55),
- PM800_BUCK(buck2, BUCK2, BUCK_ENA, 1, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(buck3, BUCK3, BUCK_ENA, 2, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(buck4, BUCK4, BUCK_ENA, 3, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(buck5, BUCK5, BUCK_ENA, 4, 1200000, buck2_5_volt_range, 0x73),
-
- PM800_LDO(ldo1, LDO1, LDO_ENA1_1, 0, 200000, ldo1_volt_table),
- PM800_LDO(ldo2, LDO2, LDO_ENA1_1, 1, 10000, ldo2_volt_table),
- PM800_LDO(ldo3, LDO3, LDO_ENA1_1, 2, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo4, LDO4, LDO_ENA1_1, 3, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo5, LDO5, LDO_ENA1_1, 4, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo6, LDO6, LDO_ENA1_1, 5, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo7, LDO7, LDO_ENA1_1, 6, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo8, LDO8, LDO_ENA1_1, 7, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo9, LDO9, LDO_ENA1_2, 0, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo10, LDO10, LDO_ENA1_2, 1, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo11, LDO11, LDO_ENA1_2, 2, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo12, LDO12, LDO_ENA1_2, 3, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo13, LDO13, LDO_ENA1_2, 4, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo14, LDO14, LDO_ENA1_2, 5, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo15, LDO15, LDO_ENA1_2, 6, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo16, LDO16, LDO_ENA1_2, 7, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo17, LDO17, LDO_ENA1_3, 0, 300000, ldo3_17_volt_table),
- PM800_LDO(ldo18, LDO18, LDO_ENA1_3, 1, 200000, ldo18_19_volt_table),
- PM800_LDO(ldo19, LDO19, LDO_ENA1_3, 2, 200000, ldo18_19_volt_table),
-};
-
-static int pm800_regulator_probe(struct platform_device *pdev)
-{
- struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent);
- struct regulator_config config = { };
- struct regulator_init_data *init_data;
- int i, ret;
-
- if (pdata && pdata->num_regulators) {
- unsigned int count = 0;
-
- /* Check whether num_regulator is valid. */
- for (i = 0; i < ARRAY_SIZE(pdata->regulators); i++) {
- if (pdata->regulators[i])
- count++;
- }
- if (count != pdata->num_regulators)
- return -EINVAL;
- }
-
- config.dev = chip->dev;
- config.regmap = chip->subchip->regmap_power;
- for (i = 0; i < PM800_ID_RG_MAX; i++) {
- struct regulator_dev *regulator;
-
- if (pdata && pdata->num_regulators) {
- init_data = pdata->regulators[i];
- if (!init_data)
- continue;
-
- config.init_data = init_data;
- }
-
- config.driver_data = &pm800_regulator_info[i];
-
- regulator = devm_regulator_register(&pdev->dev,
- &pm800_regulator_info[i].desc, &config);
- if (IS_ERR(regulator)) {
- ret = PTR_ERR(regulator);
- dev_err(&pdev->dev, "Failed to register %s\n",
- pm800_regulator_info[i].desc.name);
- return ret;
- }
- }
-
- return 0;
-}
-
-static struct platform_driver pm800_regulator_driver = {
- .driver = {
- .name = "88pm80x-regulator",
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
- .probe = pm800_regulator_probe,
-};
-
-module_platform_driver(pm800_regulator_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Joseph(Yossi) Hanin <yhanin@marvell.com>");
-MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM800 PMIC");
-MODULE_ALIAS("platform:88pm800-regulator");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 89789ac7a786..73b43dc1b3be 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -75,16 +75,6 @@ config REGULATOR_88PG86X
They provide two I2C-controlled DC/DC step-down converters with
sleep mode and separate enable pins.
-config REGULATOR_88PM800
- tristate "Marvell 88PM800 Power regulators"
- depends on MFD_88PM800
- help
- This driver supports Marvell 88PM800 voltage regulator chips.
- It delivers digitally programmable output,
- the voltage is programmed via I2C interface.
- It's suitable to support PXA988 chips to control VCC_MAIN and
- various voltages.
-
config REGULATOR_88PM8607
tristate "Marvell 88PM8607 Power regulators"
depends on MFD_88PM860X=y
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 5a764cec8df8..972f105567b5 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o
-obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_88PM886) += 88pm886-regulator.o
obj-$(CONFIG_REGULATOR_CROS_EC) += cros-ec-regulator.o
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 0636b9ead2c2..5674211afe91 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -172,16 +172,6 @@ config RTC_DRV_88PM860X
This driver can also be built as a module. If so, the module
will be called rtc-88pm860x.
-config RTC_DRV_88PM80X
- tristate "Marvell 88PM80x"
- depends on MFD_88PM800
- help
- If you say yes here you get support for RTC function in Marvell
- 88PM80x chips.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-88pm80x.
-
config RTC_DRV_88PM886
tristate "Marvell 88PM886 RTC driver"
depends on MFD_88PM886_PMIC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0347645b021f..84bb2af5849e 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_RTC_LIB_KUNIT_TEST) += test_rtc_lib.o
# Keep the list ordered.
-obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o
obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o
obj-$(CONFIG_RTC_DRV_88PM886) += rtc-88pm886.o
obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c
deleted file mode 100644
index a3e52a5a708f..000000000000
--- a/drivers/rtc/rtc-88pm80x.c
+++ /dev/null
@@ -1,340 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Real Time Clock driver for Marvell 88PM80x PMIC
- *
- * Copyright (c) 2012 Marvell International Ltd.
- * Wenzeng Chen<wzch@marvell.com>
- * Qiao Zhou <zhouqiao@marvell.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/regmap.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/88pm80x.h>
-#include <linux/rtc.h>
-
-#define PM800_RTC_COUNTER1 (0xD1)
-#define PM800_RTC_COUNTER2 (0xD2)
-#define PM800_RTC_COUNTER3 (0xD3)
-#define PM800_RTC_COUNTER4 (0xD4)
-#define PM800_RTC_EXPIRE1_1 (0xD5)
-#define PM800_RTC_EXPIRE1_2 (0xD6)
-#define PM800_RTC_EXPIRE1_3 (0xD7)
-#define PM800_RTC_EXPIRE1_4 (0xD8)
-#define PM800_RTC_TRIM1 (0xD9)
-#define PM800_RTC_TRIM2 (0xDA)
-#define PM800_RTC_TRIM3 (0xDB)
-#define PM800_RTC_TRIM4 (0xDC)
-#define PM800_RTC_EXPIRE2_1 (0xDD)
-#define PM800_RTC_EXPIRE2_2 (0xDE)
-#define PM800_RTC_EXPIRE2_3 (0xDF)
-#define PM800_RTC_EXPIRE2_4 (0xE0)
-
-#define PM800_POWER_DOWN_LOG1 (0xE5)
-#define PM800_POWER_DOWN_LOG2 (0xE6)
-
-struct pm80x_rtc_info {
- struct pm80x_chip *chip;
- struct regmap *map;
- struct rtc_device *rtc_dev;
- struct device *dev;
-
- int irq;
-};
-
-static irqreturn_t rtc_update_handler(int irq, void *data)
-{
- struct pm80x_rtc_info *info = (struct pm80x_rtc_info *)data;
- int mask;
-
- mask = PM800_ALARM | PM800_ALARM_WAKEUP;
- regmap_update_bits(info->map, PM800_RTC_CONTROL, mask | PM800_ALARM1_EN,
- mask);
- rtc_update_irq(info->rtc_dev, 1, RTC_AF);
- return IRQ_HANDLED;
-}
-
-static int pm80x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct pm80x_rtc_info *info = dev_get_drvdata(dev);
-
- if (enabled)
- regmap_update_bits(info->map, PM800_RTC_CONTROL,
- PM800_ALARM1_EN, PM800_ALARM1_EN);
- else
- regmap_update_bits(info->map, PM800_RTC_CONTROL,
- PM800_ALARM1_EN, 0);
- return 0;
-}
-
-/*
- * Calculate the next alarm time given the requested alarm time mask
- * and the current time.
- */
-static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
- struct rtc_time *alrm)
-{
- unsigned long next_time;
- unsigned long now_time;
-
- next->tm_year = now->tm_year;
- next->tm_mon = now->tm_mon;
- next->tm_mday = now->tm_mday;
- next->tm_hour = alrm->tm_hour;
- next->tm_min = alrm->tm_min;
- next->tm_sec = alrm->tm_sec;
-
- now_time = rtc_tm_to_time64(now);
- next_time = rtc_tm_to_time64(next);
-
- if (next_time < now_time) {
- /* Advance one day */
- next_time += 60 * 60 * 24;
- rtc_time64_to_tm(next_time, next);
- }
-}
-
-static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- struct pm80x_rtc_info *info = dev_get_drvdata(dev);
- unsigned char buf[4];
- unsigned long ticks, base, data;
- regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
- base = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
- (buf[1] << 8) | buf[0];
- dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]);
-
- /* load 32-bit read-only counter */
- regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
- data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
- (buf[1] << 8) | buf[0];
- ticks = base + data;
- dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
- base, data, ticks);
- rtc_time64_to_tm(ticks, tm);
- return 0;
-}
-
-static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct pm80x_rtc_info *info = dev_get_drvdata(dev);
- unsigned char buf[4];
- unsigned long ticks, base, data;
-
- ticks = rtc_tm_to_time64(tm);
-
- /* load 32-bit read-only counter */
- regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
- data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
- (buf[1] << 8) | buf[0];
- base = ticks - data;
- dev_dbg(info->dev, "set base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
- base, data, ticks);
- buf[0] = base & 0xFF;
- buf[1] = (base >> 8) & 0xFF;
- buf[2] = (base >> 16) & 0xFF;
- buf[3] = (base >> 24) & 0xFF;
- regmap_raw_write(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
-
- return 0;
-}
-
-static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct pm80x_rtc_info *info = dev_get_drvdata(dev);
- unsigned char buf[4];
- unsigned long ticks, base, data;
- int ret;
-
- regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
- base = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
- (buf[1] << 8) | buf[0];
- dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]);
-
- regmap_raw_read(info->map, PM800_RTC_EXPIRE1_1, buf, 4);
- data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
- (buf[1] << 8) | buf[0];
- ticks = base + data;
- dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
- base, data, ticks);
-
- rtc_time64_to_tm(ticks, &alrm->time);
- regmap_read(info->map, PM800_RTC_CONTROL, &ret);
- alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0;
- alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0;
- return 0;
-}
-
-static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct pm80x_rtc_info *info = dev_get_drvdata(dev);
- struct rtc_time now_tm, alarm_tm;
- unsigned long ticks, base, data;
- unsigned char buf[4];
- int mask;
-
- regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_ALARM1_EN, 0);
-
- regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
- base = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
- (buf[1] << 8) | buf[0];
- dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]);
-
- /* load 32-bit read-only counter */
- regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
- data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
- (buf[1] << 8) | buf[0];
- ticks = base + data;
- dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
- base, data, ticks);
-
- rtc_time64_to_tm(ticks, &now_tm);
- dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks);
- rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time);
- /* get new ticks for alarm in 24 hours */
- ticks = rtc_tm_to_time64(&alarm_tm);
- dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks);
- data = ticks - base;
-
- buf[0] = data & 0xff;
- buf[1] = (data >> 8) & 0xff;
- buf[2] = (data >> 16) & 0xff;
- buf[3] = (data >> 24) & 0xff;
- regmap_raw_write(info->map, PM800_RTC_EXPIRE1_1, buf, 4);
- if (alrm->enabled) {
- mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN;
- regmap_update_bits(info->map, PM800_RTC_CONTROL, mask, mask);
- } else {
- mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN;
- regmap_update_bits(info->map, PM800_RTC_CONTROL, mask,
- PM800_ALARM | PM800_ALARM_WAKEUP);
- }
- return 0;
-}
-
-static const struct rtc_class_ops pm80x_rtc_ops = {
- .read_time = pm80x_rtc_read_time,
- .set_time = pm80x_rtc_set_time,
- .read_alarm = pm80x_rtc_read_alarm,
- .set_alarm = pm80x_rtc_set_alarm,
- .alarm_irq_enable = pm80x_rtc_alarm_irq_enable,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int pm80x_rtc_suspend(struct device *dev)
-{
- return pm80x_dev_suspend(dev);
-}
-
-static int pm80x_rtc_resume(struct device *dev)
-{
- return pm80x_dev_resume(dev);
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(pm80x_rtc_pm_ops, pm80x_rtc_suspend, pm80x_rtc_resume);
-
-static int pm80x_rtc_probe(struct platform_device *pdev)
-{
- struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev);
- struct pm80x_rtc_info *info;
- struct device_node *node = pdev->dev.of_node;
- int ret;
-
- if (!pdata && !node) {
- dev_err(&pdev->dev,
- "pm80x-rtc requires platform data or of_node\n");
- return -EINVAL;
- }
-
- if (!pdata) {
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- return -ENOMEM;
- }
- }
-
- info =
- devm_kzalloc(&pdev->dev, sizeof(struct pm80x_rtc_info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
- info->irq = platform_get_irq(pdev, 0);
- if (info->irq < 0) {
- ret = -EINVAL;
- goto out;
- }
-
- info->chip = chip;
- info->map = chip->regmap;
- if (!info->map) {
- dev_err(&pdev->dev, "no regmap!\n");
- ret = -EINVAL;
- goto out;
- }
-
- info->dev = &pdev->dev;
- dev_set_drvdata(&pdev->dev, info);
-
- info->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(info->rtc_dev))
- return PTR_ERR(info->rtc_dev);
-
- ret = pm80x_request_irq(chip, info->irq, rtc_update_handler,
- IRQF_ONESHOT, "rtc", info);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
- info->irq, ret);
- goto out;
- }
-
- info->rtc_dev->ops = &pm80x_rtc_ops;
- info->rtc_dev->range_max = U32_MAX;
-
- ret = devm_rtc_register_device(info->rtc_dev);
- if (ret)
- goto out_rtc;
-
- /*
- * enable internal XO instead of internal 3.25MHz clock since it can
- * free running in PMIC power-down state.
- */
- regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_RTC1_USE_XO,
- PM800_RTC1_USE_XO);
-
- /* remember whether this power up is caused by PMIC RTC or not */
- info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup;
-
- device_init_wakeup(&pdev->dev, true);
-
- return 0;
-out_rtc:
- pm80x_free_irq(chip, info->irq, info);
-out:
- return ret;
-}
-
-static void pm80x_rtc_remove(struct platform_device *pdev)
-{
- struct pm80x_rtc_info *info = platform_get_drvdata(pdev);
- pm80x_free_irq(info->chip, info->irq, info);
-}
-
-static struct platform_driver pm80x_rtc_driver = {
- .driver = {
- .name = "88pm80x-rtc",
- .pm = &pm80x_rtc_pm_ops,
- },
- .probe = pm80x_rtc_probe,
- .remove = pm80x_rtc_remove,
-};
-
-module_platform_driver(pm80x_rtc_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Marvell 88PM80x RTC driver");
-MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
-MODULE_ALIAS("platform:88pm80x-rtc");
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
deleted file mode 100644
index 551ef1c367d6..000000000000
--- a/include/linux/mfd/88pm80x.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Marvell 88PM80x Interface
- *
- * Copyright (C) 2012 Marvell International Ltd.
- * Qiao Zhou <zhouqiao@marvell.com>
- */
-
-#ifndef __LINUX_MFD_88PM80X_H
-#define __LINUX_MFD_88PM80X_H
-
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/regmap.h>
-#include <linux/atomic.h>
-
-enum {
- CHIP_INVALID = 0,
- CHIP_PM800,
- CHIP_PM805,
- CHIP_PM860,
- CHIP_MAX,
-};
-
-enum {
- PM800_ID_BUCK1 = 0,
- PM800_ID_BUCK2,
- PM800_ID_BUCK3,
- PM800_ID_BUCK4,
- PM800_ID_BUCK5,
-
- PM800_ID_LDO1,
- PM800_ID_LDO2,
- PM800_ID_LDO3,
- PM800_ID_LDO4,
- PM800_ID_LDO5,
- PM800_ID_LDO6,
- PM800_ID_LDO7,
- PM800_ID_LDO8,
- PM800_ID_LDO9,
- PM800_ID_LDO10,
- PM800_ID_LDO11,
- PM800_ID_LDO12,
- PM800_ID_LDO13,
- PM800_ID_LDO14,
- PM800_ID_LDO15,
- PM800_ID_LDO16,
- PM800_ID_LDO17,
- PM800_ID_LDO18,
- PM800_ID_LDO19,
-
- PM800_ID_RG_MAX,
-};
-#define PM800_MAX_REGULATOR PM800_ID_RG_MAX /* 5 Bucks, 19 LDOs */
-#define PM800_NUM_BUCK (5) /*5 Bucks */
-#define PM800_NUM_LDO (19) /*19 Bucks */
-
-/* page 0 basic: slave adder 0x60 */
-
-#define PM800_STATUS_1 (0x01)
-#define PM800_ONKEY_STS1 BIT(0)
-#define PM800_EXTON_STS1 BIT(1)
-#define PM800_CHG_STS1 BIT(2)
-#define PM800_BAT_STS1 BIT(3)
-#define PM800_VBUS_STS1 BIT(4)
-#define PM800_LDO_PGOOD_STS1 BIT(5)
-#define PM800_BUCK_PGOOD_STS1 BIT(6)
-
-#define PM800_STATUS_2 (0x02)
-#define PM800_RTC_ALARM_STS2 BIT(0)
-
-/* Wakeup Registers */
-#define PM800_WAKEUP1 (0x0D)
-
-#define PM800_WAKEUP2 (0x0E)
-#define PM800_WAKEUP2_INV_INT BIT(0)
-#define PM800_WAKEUP2_INT_CLEAR BIT(1)
-#define PM800_WAKEUP2_INT_MASK BIT(2)
-
-#define PM800_POWER_UP_LOG (0x10)
-
-/* Referance and low power registers */
-#define PM800_LOW_POWER1 (0x20)
-#define PM800_LOW_POWER2 (0x21)
-#define PM800_LOW_POWER_CONFIG3 (0x22)
-#define PM800_LOW_POWER_CONFIG4 (0x23)
-
-/* GPIO register */
-#define PM800_GPIO_0_1_CNTRL (0x30)
-#define PM800_GPIO0_VAL BIT(0)
-#define PM800_GPIO0_GPIO_MODE(x) (x << 1)
-#define PM800_GPIO1_VAL BIT(4)
-#define PM800_GPIO1_GPIO_MODE(x) (x << 5)
-
-#define PM800_GPIO_2_3_CNTRL (0x31)
-#define PM800_GPIO2_VAL BIT(0)
-#define PM800_GPIO2_GPIO_MODE(x) (x << 1)
-#define PM800_GPIO3_VAL BIT(4)
-#define PM800_GPIO3_GPIO_MODE(x) (x << 5)
-#define PM800_GPIO3_MODE_MASK 0x1F
-#define PM800_GPIO3_HEADSET_MODE PM800_GPIO3_GPIO_MODE(6)
-
-#define PM800_GPIO_4_CNTRL (0x32)
-#define PM800_GPIO4_VAL BIT(0)
-#define PM800_GPIO4_GPIO_MODE(x) (x << 1)
-
-#define PM800_HEADSET_CNTRL (0x38)
-#define PM800_HEADSET_DET_EN BIT(7)
-#define PM800_HSDET_SLP BIT(1)
-/* PWM register */
-#define PM800_PWM1 (0x40)
-#define PM800_PWM2 (0x41)
-#define PM800_PWM3 (0x42)
-#define PM800_PWM4 (0x43)
-
-/* RTC Registers */
-#define PM800_RTC_CONTROL (0xD0)
-#define PM800_RTC_MISC1 (0xE1)
-#define PM800_RTC_MISC2 (0xE2)
-#define PM800_RTC_MISC3 (0xE3)
-#define PM800_RTC_MISC4 (0xE4)
-#define PM800_RTC_MISC5 (0xE7)
-/* bit definitions of RTC Register 1 (0xD0) */
-#define PM800_ALARM1_EN BIT(0)
-#define PM800_ALARM_WAKEUP BIT(4)
-#define PM800_ALARM BIT(5)
-#define PM800_RTC1_USE_XO BIT(7)
-
-/* Regulator Control Registers: BUCK1,BUCK5,LDO1 have DVC */
-
-/* buck registers */
-#define PM800_SLEEP_BUCK1 (0x30)
-
-/* BUCK Sleep Mode Register 1: BUCK[1..4] */
-#define PM800_BUCK_SLP1 (0x5A)
-#define PM800_BUCK1_SLP1_SHIFT 0
-#define PM800_BUCK1_SLP1_MASK (0x3 << PM800_BUCK1_SLP1_SHIFT)
-
-/* page 2 GPADC: slave adder 0x02 */
-#define PM800_GPADC_MEAS_EN1 (0x01)
-#define PM800_MEAS_EN1_VBAT BIT(2)
-#define PM800_GPADC_MEAS_EN2 (0x02)
-#define PM800_MEAS_EN2_RFTMP BIT(0)
-#define PM800_MEAS_GP0_EN BIT(2)
-#define PM800_MEAS_GP1_EN BIT(3)
-#define PM800_MEAS_GP2_EN BIT(4)
-#define PM800_MEAS_GP3_EN BIT(5)
-#define PM800_MEAS_GP4_EN BIT(6)
-
-#define PM800_GPADC_MISC_CONFIG1 (0x05)
-#define PM800_GPADC_MISC_CONFIG2 (0x06)
-#define PM800_GPADC_MISC_GPFSM_EN BIT(0)
-#define PM800_GPADC_SLOW_MODE(x) (x << 3)
-
-#define PM800_GPADC_MISC_CONFIG3 (0x09)
-#define PM800_GPADC_MISC_CONFIG4 (0x0A)
-
-#define PM800_GPADC_PREBIAS1 (0x0F)
-#define PM800_GPADC0_GP_PREBIAS_TIME(x) (x << 0)
-#define PM800_GPADC_PREBIAS2 (0x10)
-
-#define PM800_GP_BIAS_ENA1 (0x14)
-#define PM800_GPADC_GP_BIAS_EN0 BIT(0)
-#define PM800_GPADC_GP_BIAS_EN1 BIT(1)
-#define PM800_GPADC_GP_BIAS_EN2 BIT(2)
-#define PM800_GPADC_GP_BIAS_EN3 BIT(3)
-
-#define PM800_GP_BIAS_OUT1 (0x15)
-#define PM800_BIAS_OUT_GP0 BIT(0)
-#define PM800_BIAS_OUT_GP1 BIT(1)
-#define PM800_BIAS_OUT_GP2 BIT(2)
-#define PM800_BIAS_OUT_GP3 BIT(3)
-
-#define PM800_GPADC0_LOW_TH 0x20
-#define PM800_GPADC1_LOW_TH 0x21
-#define PM800_GPADC2_LOW_TH 0x22
-#define PM800_GPADC3_LOW_TH 0x23
-#define PM800_GPADC4_LOW_TH 0x24
-
-#define PM800_GPADC0_UPP_TH 0x30
-#define PM800_GPADC1_UPP_TH 0x31
-#define PM800_GPADC2_UPP_TH 0x32
-#define PM800_GPADC3_UPP_TH 0x33
-#define PM800_GPADC4_UPP_TH 0x34
-
-#define PM800_VBBAT_MEAS1 0x40
-#define PM800_VBBAT_MEAS2 0x41
-#define PM800_VBAT_MEAS1 0x42
-#define PM800_VBAT_MEAS2 0x43
-#define PM800_VSYS_MEAS1 0x44
-#define PM800_VSYS_MEAS2 0x45
-#define PM800_VCHG_MEAS1 0x46
-#define PM800_VCHG_MEAS2 0x47
-#define PM800_TINT_MEAS1 0x50
-#define PM800_TINT_MEAS2 0x51
-#define PM800_PMOD_MEAS1 0x52
-#define PM800_PMOD_MEAS2 0x53
-
-#define PM800_GPADC0_MEAS1 0x54
-#define PM800_GPADC0_MEAS2 0x55
-#define PM800_GPADC1_MEAS1 0x56
-#define PM800_GPADC1_MEAS2 0x57
-#define PM800_GPADC2_MEAS1 0x58
-#define PM800_GPADC2_MEAS2 0x59
-#define PM800_GPADC3_MEAS1 0x5A
-#define PM800_GPADC3_MEAS2 0x5B
-#define PM800_GPADC4_MEAS1 0x5C
-#define PM800_GPADC4_MEAS2 0x5D
-
-#define PM800_GPADC4_AVG1 0xA8
-#define PM800_GPADC4_AVG2 0xA9
-
-/* 88PM805 Registers */
-#define PM805_MAIN_POWERUP (0x01)
-#define PM805_INT_STATUS0 (0x02) /* for ena/dis all interrupts */
-
-#define PM805_STATUS0_INT_CLEAR (1 << 0)
-#define PM805_STATUS0_INV_INT (1 << 1)
-#define PM800_STATUS0_INT_MASK (1 << 2)
-
-#define PM805_INT_STATUS1 (0x03)
-
-#define PM805_INT1_HP1_SHRT BIT(0)
-#define PM805_INT1_HP2_SHRT BIT(1)
-#define PM805_INT1_MIC_CONFLICT BIT(2)
-#define PM805_INT1_CLIP_FAULT BIT(3)
-#define PM805_INT1_LDO_OFF BIT(4)
-#define PM805_INT1_SRC_DPLL_LOCK BIT(5)
-
-#define PM805_INT_STATUS2 (0x04)
-
-#define PM805_INT2_MIC_DET BIT(0)
-#define PM805_INT2_SHRT_BTN_DET BIT(1)
-#define PM805_INT2_VOLM_BTN_DET BIT(2)
-#define PM805_INT2_VOLP_BTN_DET BIT(3)
-#define PM805_INT2_RAW_PLL_FAULT BIT(4)
-#define PM805_INT2_FINE_PLL_FAULT BIT(5)
-
-#define PM805_INT_MASK1 (0x05)
-#define PM805_INT_MASK2 (0x06)
-#define PM805_SHRT_BTN_DET BIT(1)
-
-/* number of status and int reg in a row */
-#define PM805_INT_REG_NUM (2)
-
-#define PM805_MIC_DET1 (0x07)
-#define PM805_MIC_DET_EN_MIC_DET BIT(0)
-#define PM805_MIC_DET2 (0x08)
-#define PM805_MIC_DET_STATUS1 (0x09)
-
-#define PM805_MIC_DET_STATUS3 (0x0A)
-#define PM805_AUTO_SEQ_STATUS1 (0x0B)
-#define PM805_AUTO_SEQ_STATUS2 (0x0C)
-
-#define PM805_ADC_SETTING1 (0x10)
-#define PM805_ADC_SETTING2 (0x11)
-#define PM805_ADC_SETTING3 (0x11)
-#define PM805_ADC_GAIN1 (0x12)
-#define PM805_ADC_GAIN2 (0x13)
-#define PM805_DMIC_SETTING (0x15)
-#define PM805_DWS_SETTING (0x16)
-#define PM805_MIC_CONFLICT_STS (0x17)
-
-#define PM805_PDM_SETTING1 (0x20)
-#define PM805_PDM_SETTING2 (0x21)
-#define PM805_PDM_SETTING3 (0x22)
-#define PM805_PDM_CONTROL1 (0x23)
-#define PM805_PDM_CONTROL2 (0x24)
-#define PM805_PDM_CONTROL3 (0x25)
-
-#define PM805_HEADPHONE_SETTING (0x26)
-#define PM805_HEADPHONE_GAIN_A2A (0x27)
-#define PM805_HEADPHONE_SHORT_STATE (0x28)
-#define PM805_EARPHONE_SETTING (0x29)
-#define PM805_AUTO_SEQ_SETTING (0x2A)
-
-struct pm80x_rtc_pdata {
- int vrtc;
- int rtc_wakeup;
-};
-
-struct pm80x_subchip {
- struct i2c_client *power_page; /* chip client for power page */
- struct i2c_client *gpadc_page; /* chip client for gpadc page */
- struct regmap *regmap_power;
- struct regmap *regmap_gpadc;
- unsigned short power_page_addr; /* power page I2C address */
- unsigned short gpadc_page_addr; /* gpadc page I2C address */
-};
-
-struct pm80x_chip {
- struct pm80x_subchip *subchip;
- struct device *dev;
- struct i2c_client *client;
- struct i2c_client *companion;
- struct regmap *regmap;
- const struct regmap_irq_chip *regmap_irq_chip;
- struct regmap_irq_chip_data *irq_data;
- int type;
- int irq;
- int irq_mode;
- unsigned long wu_flag;
- spinlock_t lock;
-};
-
-struct pm80x_platform_data {
- struct pm80x_rtc_pdata *rtc;
- /*
- * For the regulator not defined, set regulators[not_defined] to be
- * NULL. num_regulators are the number of regulators supposed to be
- * initialized. If all regulators are not defined, set num_regulators
- * to be 0.
- */
- struct regulator_init_data *regulators[PM800_ID_RG_MAX];
- unsigned int num_regulators;
- int irq_mode; /* Clear interrupt by read/write(0/1) */
- int batt_det; /* enable/disable */
- int (*plat_config)(struct pm80x_chip *chip,
- struct pm80x_platform_data *pdata);
-};
-
-extern const struct dev_pm_ops pm80x_pm_ops;
-extern const struct regmap_config pm80x_regmap_config;
-
-static inline int pm80x_request_irq(struct pm80x_chip *pm80x, int irq,
- irq_handler_t handler, unsigned long flags,
- const char *name, void *data)
-{
- if (!pm80x->irq_data)
- return -EINVAL;
- return request_threaded_irq(regmap_irq_get_virq(pm80x->irq_data, irq),
- NULL, handler, flags, name, data);
-}
-
-static inline void pm80x_free_irq(struct pm80x_chip *pm80x, int irq, void *data)
-{
- if (!pm80x->irq_data)
- return;
- free_irq(regmap_irq_get_virq(pm80x->irq_data, irq), data);
-}
-
-#ifdef CONFIG_PM
-static inline int pm80x_dev_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- int irq = platform_get_irq(pdev, 0);
-
- if (device_may_wakeup(dev))
- set_bit(irq, &chip->wu_flag);
-
- return 0;
-}
-
-static inline int pm80x_dev_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- int irq = platform_get_irq(pdev, 0);
-
- if (device_may_wakeup(dev))
- clear_bit(irq, &chip->wu_flag);
-
- return 0;
-}
-#endif
-
-extern int pm80x_init(struct i2c_client *client);
-extern int pm80x_deinit(void);
-#endif /* __LINUX_MFD_88PM80X_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* Re: [PATCH 01/14] mfd: remove unused 88pm80x driver
2026-09-09 13:21 ` [PATCH 01/14] mfd: remove unused 88pm80x driver Arnd Bergmann
@ 2026-09-11 7:24 ` Krzysztof Kozlowski
0 siblings, 0 replies; 36+ messages in thread
From: Krzysztof Kozlowski @ 2026-09-11 7:24 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Sebastian Reichel,
Alexandre Belloni, Helge Deller, dri-devel, linux-doc,
linux-media, devicetree, linux-hwmon, patches, linux-watchdog,
linux-gpio, linux-iio, linux-input, linux-leds, linux-pm,
linux-rtc, linux-fbdev, linux-sound, linuxppc-dev, llvm
On Wed, Sep 09, 2026 at 03:21:38PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This pair of drivers was originally added as companion chips for pxa/mmp
> SoCs, but the corresponding platform code was never merged, so it has
> been unused the entire time.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> .../devicetree/bindings/regulator/88pm800.txt | 38 --
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 02/14] mfd: remove unused rdc321x southbridge support
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
2026-09-09 13:21 ` [PATCH 01/14] mfd: remove unused 88pm80x driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 14:09 ` Guenter Roeck
2026-09-09 13:21 ` [PATCH 05/14] mfd: remove unused adp5520 driver Arnd Bergmann
` (12 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
The rdc321x was a 486-class SoC developed by RDC. While RDC's later
products closely resemble the DM&P Vortex86 product line and are still
sold under both names, I checked the datasheets for those and found that
the GPIO and WDT blocks on them are incompatible with the rtc321x.
Remove this driver, as there is no way to run Linux any more on the
older chips after i486 support has been removed.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/gpio/Kconfig | 8 -
drivers/gpio/Makefile | 1 -
drivers/gpio/gpio-rdc321x.c | 199 ---------------------
drivers/mfd/Kconfig | 9 -
drivers/mfd/Makefile | 1 -
drivers/mfd/rdc321x-southbridge.c | 96 ----------
drivers/watchdog/Kconfig | 11 --
drivers/watchdog/Makefile | 1 -
drivers/watchdog/rdc321x_wdt.c | 281 ------------------------------
include/linux/mfd/rdc321x.h | 27 ---
10 files changed, 634 deletions(-)
delete mode 100644 drivers/gpio/gpio-rdc321x.c
delete mode 100644 drivers/mfd/rdc321x-southbridge.c
delete mode 100644 drivers/watchdog/rdc321x_wdt.c
delete mode 100644 include/linux/mfd/rdc321x.h
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a48586bb8edb..aef0db9fe101 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1946,14 +1946,6 @@ config GPIO_PCIE_IDIO_24
Input filter control is not supported by this driver, and the input
filters are deactivated by this driver.
-config GPIO_RDC321X
- tristate "RDC R-321x GPIO support"
- select MFD_CORE
- select MFD_RDC321X
- help
- Support for the RDC R321x SoC GPIOs over southbridge
- PCI configuration space.
-
config GPIO_SODAVILLE
bool "Intel Sodaville GPIO support"
depends on X86 && OF
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index dc9e6d643b5b..2e3a14688b59 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -156,7 +156,6 @@ obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
obj-$(CONFIG_GPIO_RDA) += gpio-rda.o
-obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o
obj-$(CONFIG_GPIO_REG) += gpio-reg.o
obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c
deleted file mode 100644
index ba62b81aa8ae..000000000000
--- a/drivers/gpio/gpio-rdc321x.c
+++ /dev/null
@@ -1,199 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * RDC321x GPIO driver
- *
- * Copyright (C) 2008, Volker Weiss <dev@tintuc.de>
- * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/gpio/driver.h>
-#include <linux/mfd/rdc321x.h>
-#include <linux/slab.h>
-
-struct rdc321x_gpio {
- spinlock_t lock;
- struct pci_dev *sb_pdev;
- u32 data_reg[2];
- int reg1_ctrl_base;
- int reg1_data_base;
- int reg2_ctrl_base;
- int reg2_data_base;
- struct gpio_chip chip;
-};
-
-/* read GPIO pin */
-static int rdc_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
-{
- struct rdc321x_gpio *gpch;
- u32 value = 0;
- int reg;
-
- gpch = gpiochip_get_data(chip);
- reg = gpio < 32 ? gpch->reg1_data_base : gpch->reg2_data_base;
-
- spin_lock(&gpch->lock);
- pci_write_config_dword(gpch->sb_pdev, reg,
- gpch->data_reg[gpio < 32 ? 0 : 1]);
- pci_read_config_dword(gpch->sb_pdev, reg, &value);
- spin_unlock(&gpch->lock);
-
- return (1 << (gpio & 0x1f)) & value ? 1 : 0;
-}
-
-static void rdc_gpio_set_value_impl(struct gpio_chip *chip,
- unsigned gpio, int value)
-{
- struct rdc321x_gpio *gpch;
- int reg = (gpio < 32) ? 0 : 1;
-
- gpch = gpiochip_get_data(chip);
-
- if (value)
- gpch->data_reg[reg] |= 1 << (gpio & 0x1f);
- else
- gpch->data_reg[reg] &= ~(1 << (gpio & 0x1f));
-
- pci_write_config_dword(gpch->sb_pdev,
- reg ? gpch->reg2_data_base : gpch->reg1_data_base,
- gpch->data_reg[reg]);
-}
-
-/* set GPIO pin to value */
-static int rdc_gpio_set_value(struct gpio_chip *chip, unsigned int gpio,
- int value)
-{
- struct rdc321x_gpio *gpch;
-
- gpch = gpiochip_get_data(chip);
- spin_lock(&gpch->lock);
- rdc_gpio_set_value_impl(chip, gpio, value);
- spin_unlock(&gpch->lock);
-
- return 0;
-}
-
-static int rdc_gpio_config(struct gpio_chip *chip,
- unsigned gpio, int value)
-{
- struct rdc321x_gpio *gpch;
- int err;
- u32 reg;
-
- gpch = gpiochip_get_data(chip);
-
- spin_lock(&gpch->lock);
- err = pci_read_config_dword(gpch->sb_pdev, gpio < 32 ?
- gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, ®);
- if (err)
- goto unlock;
-
- reg |= 1 << (gpio & 0x1f);
-
- err = pci_write_config_dword(gpch->sb_pdev, gpio < 32 ?
- gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, reg);
- if (err)
- goto unlock;
-
- rdc_gpio_set_value_impl(chip, gpio, value);
-
-unlock:
- spin_unlock(&gpch->lock);
-
- return pcibios_err_to_errno(err);
-}
-
-/* configure GPIO pin as input */
-static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
-{
- return rdc_gpio_config(chip, gpio, 1);
-}
-
-/*
- * Cache the initial value of both GPIO data registers
- */
-static int rdc321x_gpio_probe(struct platform_device *pdev)
-{
- int err;
- struct resource *r;
- struct rdc321x_gpio *rdc321x_gpio_dev;
- struct rdc321x_gpio_pdata *pdata;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data supplied\n");
- return -ENODEV;
- }
-
- rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio),
- GFP_KERNEL);
- if (!rdc321x_gpio_dev)
- return -ENOMEM;
-
- r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1");
- if (!r) {
- dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n");
- return -ENODEV;
- }
-
- spin_lock_init(&rdc321x_gpio_dev->lock);
- rdc321x_gpio_dev->sb_pdev = pdata->sb_pdev;
- rdc321x_gpio_dev->reg1_ctrl_base = r->start;
- rdc321x_gpio_dev->reg1_data_base = r->start + 0x4;
-
- r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2");
- if (!r) {
- dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n");
- return -ENODEV;
- }
-
- rdc321x_gpio_dev->reg2_ctrl_base = r->start;
- rdc321x_gpio_dev->reg2_data_base = r->start + 0x4;
-
- rdc321x_gpio_dev->chip.label = "rdc321x-gpio";
- rdc321x_gpio_dev->chip.owner = THIS_MODULE;
- rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input;
- rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config;
- rdc321x_gpio_dev->chip.get = rdc_gpio_get_value;
- rdc321x_gpio_dev->chip.set = rdc_gpio_set_value;
- rdc321x_gpio_dev->chip.base = 0;
- rdc321x_gpio_dev->chip.ngpio = pdata->max_gpios;
-
- platform_set_drvdata(pdev, rdc321x_gpio_dev);
-
- /* This might not be, what others (BIOS, bootloader, etc.)
- wrote to these registers before, but it's a good guess. Still
- better than just using 0xffffffff. */
- err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
- rdc321x_gpio_dev->reg1_data_base,
- &rdc321x_gpio_dev->data_reg[0]);
- if (err)
- return pcibios_err_to_errno(err);
-
- err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
- rdc321x_gpio_dev->reg2_data_base,
- &rdc321x_gpio_dev->data_reg[1]);
- if (err)
- return pcibios_err_to_errno(err);
-
- dev_info(&pdev->dev, "registering %d GPIOs\n",
- rdc321x_gpio_dev->chip.ngpio);
- return devm_gpiochip_add_data(&pdev->dev, &rdc321x_gpio_dev->chip,
- rdc321x_gpio_dev);
-}
-
-static struct platform_driver rdc321x_gpio_driver = {
- .driver.name = "rdc321x-gpio",
- .probe = rdc321x_gpio_probe,
-};
-
-module_platform_driver(rdc321x_gpio_driver);
-
-MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
-MODULE_DESCRIPTION("RDC321x GPIO driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:rdc321x-gpio");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index de81d2bb4917..ce0c39b50af7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1289,15 +1289,6 @@ config MFD_SY7636A
To enable support for building sub-devices as modules,
choose M here.
-config MFD_RDC321X
- tristate "RDC R-321x southbridge"
- select MFD_CORE
- depends on PCI
- help
- Say yes here if you want to have support for the RDC R-321x SoC
- southbridge which provides access to GPIOs and Watchdog using the
- southbridge PCI device configuration space.
-
config MFD_RT4831
tristate "Richtek RT4831 four channel WLED and Display Bias Voltage"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index fe7156a5187a..a54eb18af56a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -200,7 +200,6 @@ obj-$(CONFIG_MFD_KEMPLD) += kempld-core.o
obj-$(CONFIG_MFD_INTEL_QUARK_I2C_GPIO) += intel_quark_i2c_gpio.o
obj-$(CONFIG_LPC_SCH) += lpc_sch.o
obj-$(CONFIG_LPC_ICH) += lpc_ich.o
-obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c
deleted file mode 100644
index c44a76285147..000000000000
--- a/drivers/mfd/rdc321x-southbridge.c
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * RDC321x MFD southbridge driver
- *
- * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
- * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/rdc321x.h>
-
-static struct rdc321x_wdt_pdata rdc321x_wdt_pdata;
-
-static const struct resource rdc321x_wdt_resource[] = {
- {
- .name = "wdt-reg",
- .start = RDC321X_WDT_CTRL,
- .end = RDC321X_WDT_CTRL + 0x3,
- .flags = IORESOURCE_IO,
- }
-};
-
-static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = {
- .max_gpios = RDC321X_NUM_GPIO,
-};
-
-static const struct resource rdc321x_gpio_resources[] = {
- {
- .name = "gpio-reg1",
- .start = RDC321X_GPIO_CTRL_REG1,
- .end = RDC321X_GPIO_CTRL_REG1 + 0x7,
- .flags = IORESOURCE_IO,
- }, {
- .name = "gpio-reg2",
- .start = RDC321X_GPIO_CTRL_REG2,
- .end = RDC321X_GPIO_CTRL_REG2 + 0x7,
- .flags = IORESOURCE_IO,
- }
-};
-
-static const struct mfd_cell rdc321x_sb_cells[] = {
- {
- .name = "rdc321x-wdt",
- .resources = rdc321x_wdt_resource,
- .num_resources = ARRAY_SIZE(rdc321x_wdt_resource),
- .platform_data = &rdc321x_wdt_pdata,
- .pdata_size = sizeof(rdc321x_wdt_pdata),
- }, {
- .name = "rdc321x-gpio",
- .resources = rdc321x_gpio_resources,
- .num_resources = ARRAY_SIZE(rdc321x_gpio_resources),
- .platform_data = &rdc321x_gpio_pdata,
- .pdata_size = sizeof(rdc321x_gpio_pdata),
- },
-};
-
-static int rdc321x_sb_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- int err;
-
- err = pci_enable_device(pdev);
- if (err) {
- dev_err(&pdev->dev, "failed to enable device\n");
- return err;
- }
-
- rdc321x_gpio_pdata.sb_pdev = pdev;
- rdc321x_wdt_pdata.sb_pdev = pdev;
-
- return devm_mfd_add_devices(&pdev->dev, -1,
- rdc321x_sb_cells,
- ARRAY_SIZE(rdc321x_sb_cells),
- NULL, 0, NULL);
-}
-
-static const struct pci_device_id rdc321x_sb_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
- {}
-};
-MODULE_DEVICE_TABLE(pci, rdc321x_sb_table);
-
-static struct pci_driver rdc321x_sb_driver = {
- .name = "RDC321x Southbridge",
- .id_table = rdc321x_sb_table,
- .probe = rdc321x_sb_probe,
-};
-
-module_pci_driver(rdc321x_sb_driver);
-
-MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver");
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ddf88b07ce34..7832cb8b2e7a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1572,17 +1572,6 @@ config NV_TCO
To compile this driver as a module, choose M here: the
module will be called nv_tco.
-config RDC321X_WDT
- tristate "RDC R-321x SoC watchdog"
- depends on X86_32 || COMPILE_TEST
- depends on PCI
- help
- This is the driver for the built in hardware watchdog
- in the RDC R-321x SoC.
-
- To compile this driver as a module, choose M here: the
- module will be called rdc321x_wdt.
-
config 60XX_WDT
tristate "SBC-60XX Watchdog Timer"
depends on (X86 || COMPILE_TEST) && HAS_IOPORT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 9ac406677aba..460be2a566c4 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -138,7 +138,6 @@ obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o
obj-$(CONFIG_NV_TCO) += nv_tco.o
-obj-$(CONFIG_RDC321X_WDT) += rdc321x_wdt.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
deleted file mode 100644
index 8955177072fa..000000000000
--- a/drivers/watchdog/rdc321x_wdt.c
+++ /dev/null
@@ -1,281 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * RDC321x watchdog driver
- *
- * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
- *
- * This driver is highly inspired from the cpu5_wdt driver
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/completion.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
-#include <linux/watchdog.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/mfd/rdc321x.h>
-
-#define RDC_WDT_MASK 0x80000000 /* Mask */
-#define RDC_WDT_EN 0x00800000 /* Enable bit */
-#define RDC_WDT_WTI 0x00200000 /* Generate CPU reset/NMI/WDT on timeout */
-#define RDC_WDT_RST 0x00100000 /* Reset bit */
-#define RDC_WDT_WIF 0x00040000 /* WDT IRQ Flag */
-#define RDC_WDT_IRT 0x00000100 /* IRQ Routing table */
-#define RDC_WDT_CNT 0x00000001 /* WDT count */
-
-#define RDC_CLS_TMR 0x80003844 /* Clear timer */
-
-#define RDC_WDT_INTERVAL (HZ/10+1)
-
-static int ticks = 1000;
-
-/* some device data */
-
-static struct {
- struct completion stop;
- int running;
- struct timer_list timer;
- int queue;
- int default_ticks;
- unsigned long inuse;
- spinlock_t lock;
- struct pci_dev *sb_pdev;
- int base_reg;
-} rdc321x_wdt_device;
-
-/* generic helper functions */
-
-static void rdc321x_wdt_trigger(struct timer_list *unused)
-{
- unsigned long flags;
- u32 val;
-
- if (rdc321x_wdt_device.running)
- ticks--;
-
- /* keep watchdog alive */
- spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
- pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
- rdc321x_wdt_device.base_reg, &val);
- val |= RDC_WDT_EN;
- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
- rdc321x_wdt_device.base_reg, val);
- spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
-
- /* requeue?? */
- if (rdc321x_wdt_device.queue && ticks)
- mod_timer(&rdc321x_wdt_device.timer,
- jiffies + RDC_WDT_INTERVAL);
- else {
- /* ticks doesn't matter anyway */
- complete(&rdc321x_wdt_device.stop);
- }
-
-}
-
-static void rdc321x_wdt_reset(void)
-{
- ticks = rdc321x_wdt_device.default_ticks;
-}
-
-static void rdc321x_wdt_start(void)
-{
- unsigned long flags;
-
- if (!rdc321x_wdt_device.queue) {
- rdc321x_wdt_device.queue = 1;
-
- /* Clear the timer */
- spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
- rdc321x_wdt_device.base_reg, RDC_CLS_TMR);
-
- /* Enable watchdog and set the timeout to 81.92 us */
- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
- rdc321x_wdt_device.base_reg,
- RDC_WDT_EN | RDC_WDT_CNT);
- spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
-
- mod_timer(&rdc321x_wdt_device.timer,
- jiffies + RDC_WDT_INTERVAL);
- }
-
- /* if process dies, counter is not decremented */
- rdc321x_wdt_device.running++;
-}
-
-static int rdc321x_wdt_stop(void)
-{
- if (rdc321x_wdt_device.running)
- rdc321x_wdt_device.running = 0;
-
- ticks = rdc321x_wdt_device.default_ticks;
-
- return -EIO;
-}
-
-/* filesystem operations */
-static int rdc321x_wdt_open(struct inode *inode, struct file *file)
-{
- if (test_and_set_bit(0, &rdc321x_wdt_device.inuse))
- return -EBUSY;
-
- return stream_open(inode, file);
-}
-
-static int rdc321x_wdt_release(struct inode *inode, struct file *file)
-{
- clear_bit(0, &rdc321x_wdt_device.inuse);
- return 0;
-}
-
-static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
- u32 value;
- static const struct watchdog_info ident = {
- .options = WDIOF_CARDRESET,
- .identity = "RDC321x WDT",
- };
- unsigned long flags;
-
- switch (cmd) {
- case WDIOC_KEEPALIVE:
- rdc321x_wdt_reset();
- break;
- case WDIOC_GETSTATUS:
- /* Read the value from the DATA register */
- spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
- pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
- rdc321x_wdt_device.base_reg, &value);
- spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
- if (copy_to_user(argp, &value, sizeof(u32)))
- return -EFAULT;
- break;
- case WDIOC_GETSUPPORT:
- if (copy_to_user(argp, &ident, sizeof(ident)))
- return -EFAULT;
- break;
- case WDIOC_SETOPTIONS:
- if (copy_from_user(&value, argp, sizeof(int)))
- return -EFAULT;
- switch (value) {
- case WDIOS_ENABLECARD:
- rdc321x_wdt_start();
- break;
- case WDIOS_DISABLECARD:
- return rdc321x_wdt_stop();
- default:
- return -EINVAL;
- }
- break;
- default:
- return -ENOTTY;
- }
- return 0;
-}
-
-static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- if (!count)
- return -EIO;
-
- rdc321x_wdt_reset();
-
- return count;
-}
-
-static const struct file_operations rdc321x_wdt_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = rdc321x_wdt_ioctl,
- .compat_ioctl = compat_ptr_ioctl,
- .open = rdc321x_wdt_open,
- .write = rdc321x_wdt_write,
- .release = rdc321x_wdt_release,
-};
-
-static struct miscdevice rdc321x_wdt_misc = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &rdc321x_wdt_fops,
-};
-
-static int rdc321x_wdt_probe(struct platform_device *pdev)
-{
- int err;
- struct resource *r;
- struct rdc321x_wdt_pdata *pdata;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data supplied\n");
- return -ENODEV;
- }
-
- r = platform_get_resource_byname(pdev, IORESOURCE_IO, "wdt-reg");
- if (!r) {
- dev_err(&pdev->dev, "failed to get wdt-reg resource\n");
- return -ENODEV;
- }
-
- rdc321x_wdt_device.sb_pdev = pdata->sb_pdev;
- rdc321x_wdt_device.base_reg = r->start;
- rdc321x_wdt_device.queue = 0;
- rdc321x_wdt_device.default_ticks = ticks;
-
- err = misc_register(&rdc321x_wdt_misc);
- if (err < 0) {
- dev_err(&pdev->dev, "misc_register failed\n");
- return err;
- }
-
- spin_lock_init(&rdc321x_wdt_device.lock);
-
- /* Reset the watchdog */
- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
- rdc321x_wdt_device.base_reg, RDC_WDT_RST);
-
- init_completion(&rdc321x_wdt_device.stop);
-
- clear_bit(0, &rdc321x_wdt_device.inuse);
-
- timer_setup(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0);
-
- dev_info(&pdev->dev, "watchdog init success\n");
-
- return 0;
-}
-
-static void rdc321x_wdt_remove(struct platform_device *pdev)
-{
- if (rdc321x_wdt_device.queue) {
- rdc321x_wdt_device.queue = 0;
- wait_for_completion(&rdc321x_wdt_device.stop);
- }
-
- misc_deregister(&rdc321x_wdt_misc);
-}
-
-static struct platform_driver rdc321x_wdt_driver = {
- .probe = rdc321x_wdt_probe,
- .remove = rdc321x_wdt_remove,
- .driver = {
- .name = "rdc321x-wdt",
- },
-};
-
-module_platform_driver(rdc321x_wdt_driver);
-
-MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
-MODULE_DESCRIPTION("RDC321x watchdog driver");
-MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/rdc321x.h b/include/linux/mfd/rdc321x.h
deleted file mode 100644
index 697933b2227b..000000000000
--- a/include/linux/mfd/rdc321x.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __RDC321X_MFD_H
-#define __RDC321X_MFD_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-/* Offsets to be accessed in the southbridge PCI
- * device configuration register */
-#define RDC321X_WDT_CTRL 0x44
-#define RDC321X_GPIO_CTRL_REG1 0x48
-#define RDC321X_GPIO_DATA_REG1 0x4c
-#define RDC321X_GPIO_CTRL_REG2 0x84
-#define RDC321X_GPIO_DATA_REG2 0x88
-
-#define RDC321X_NUM_GPIO 59
-
-struct rdc321x_gpio_pdata {
- struct pci_dev *sb_pdev;
- unsigned max_gpios;
-};
-
-struct rdc321x_wdt_pdata {
- struct pci_dev *sb_pdev;
-};
-
-#endif /* __RDC321X_MFD_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* Re: [PATCH 02/14] mfd: remove unused rdc321x southbridge support
2026-09-09 13:21 ` [PATCH 02/14] mfd: remove unused rdc321x southbridge support Arnd Bergmann
@ 2026-09-09 14:09 ` Guenter Roeck
0 siblings, 0 replies; 36+ messages in thread
From: Guenter Roeck @ 2026-09-09 14:09 UTC (permalink / raw)
To: Arnd Bergmann, Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Support Opensource,
dri-devel, linux-doc, devicetree, patches, linux-watchdog,
linux-fbdev
On 9/9/26 06:21, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> The rdc321x was a 486-class SoC developed by RDC. While RDC's later
> products closely resemble the DM&P Vortex86 product line and are still
> sold under both names, I checked the datasheets for those and found that
> the GPIO and WDT blocks on them are incompatible with the rtc321x.
>
> Remove this driver, as there is no way to run Linux any more on the
> older chips after i486 support has been removed.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Guenter Roeck <linux@roeck-us.net>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 05/14] mfd: remove unused adp5520 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
2026-09-09 13:21 ` [PATCH 01/14] mfd: remove unused 88pm80x driver Arnd Bergmann
2026-09-09 13:21 ` [PATCH 02/14] mfd: remove unused rdc321x southbridge support Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:21 ` [PATCH 06/14] mfd: remove unused da903x driver Arnd Bergmann
` (11 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
This driver requires the use of platform_data definitions rather than
devicetree, but that was last used on the blackfin architecture in
2018 and nothing could have used it upstream since.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
.../ABI/testing/sysfs-class-backlight | 11 -
MAINTAINERS | 11 -
drivers/gpio/Kconfig | 7 -
drivers/gpio/Makefile | 1 -
drivers/gpio/gpio-adp5520.c | 169 --------
drivers/input/keyboard/Kconfig | 10 -
drivers/input/keyboard/Makefile | 1 -
drivers/input/keyboard/adp5520-keys.c | 191 ---------
drivers/leds/Kconfig | 11 -
drivers/leds/Makefile | 1 -
drivers/leds/leds-adp5520.c | 195 ---------
drivers/mfd/Kconfig | 10 -
drivers/mfd/Makefile | 1 -
drivers/mfd/adp5520.c | 346 ----------------
drivers/video/backlight/Kconfig | 10 -
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/adp5520_bl.c | 385 ------------------
include/linux/mfd/adp5520.h | 298 --------------
18 files changed, 1659 deletions(-)
delete mode 100644 drivers/gpio/gpio-adp5520.c
delete mode 100644 drivers/input/keyboard/adp5520-keys.c
delete mode 100644 drivers/leds/leds-adp5520.c
delete mode 100644 drivers/mfd/adp5520.c
delete mode 100644 drivers/video/backlight/adp5520_bl.c
delete mode 100644 include/linux/mfd/adp5520.h
diff --git a/Documentation/ABI/testing/sysfs-class-backlight b/Documentation/ABI/testing/sysfs-class-backlight
index c453646b06e2..b73d66942fbb 100644
--- a/Documentation/ABI/testing/sysfs-class-backlight
+++ b/Documentation/ABI/testing/sysfs-class-backlight
@@ -97,17 +97,6 @@ Description:
The <ambient light zone> is device-driver specific:
- For ADP5520 and ADP5501, <ambient light zone> can be:
-
- =========== ================================================
- Ambient sysfs entry
- light zone
- =========== ================================================
- daylight /sys/class/backlight/<backlight>/daylight_max
- office /sys/class/backlight/<backlight>/office_max
- dark /sys/class/backlight/<backlight>/dark_max
- =========== ================================================
-
For ADP8860, <ambient light zone> can be:
=========== ================================================
diff --git a/MAINTAINERS b/MAINTAINERS
index c5e2140cdac0..86df3fadba87 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -550,17 +550,6 @@ F: Documentation/devicetree/bindings/media/i2c/adi,adp1653.txt
F: drivers/media/i2c/adp1653.c
F: include/media/i2c/adp1653.h
-ADP5520 BACKLIGHT DRIVER WITH IO EXPANDER (ADP5520/ADP5501)
-M: Michael Hennerich <michael.hennerich@analog.com>
-S: Supported
-W: http://wiki.analog.com/ADP5520
-W: https://ez.analog.com/linux-software-drivers
-F: drivers/gpio/gpio-adp5520.c
-F: drivers/input/keyboard/adp5520-keys.c
-F: drivers/leds/leds-adp5520.c
-F: drivers/mfd/adp5520.c
-F: drivers/video/backlight/adp5520_bl.c
-
ADP5585 GPIO EXPANDER, PWM AND KEYPAD CONTROLLER DRIVER
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-gpio@vger.kernel.org
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index aef0db9fe101..98b9931c59ff 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1325,13 +1325,6 @@ endmenu
menu "MFD GPIO expanders"
-config GPIO_ADP5520
- tristate "GPIO Support for ADP5520 PMIC"
- depends on PMIC_ADP5520
- help
- This option enables support for on-chip GPIO found
- on Analog Devices ADP5520 PMICs.
-
config GPIO_ADP5585
tristate "GPIO Support for ADP5585"
depends on MFD_ADP5585
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2e3a14688b59..1fafd15d3fa6 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -28,7 +28,6 @@ obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
-obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
obj-$(CONFIG_GPIO_ADP5585) += gpio-adp5585.o
obj-$(CONFIG_GPIO_AGGREGATOR) += gpio-aggregator.o
obj-$(CONFIG_GPIO_ALTERA_A10SR) += gpio-altera-a10sr.o
diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c
deleted file mode 100644
index 6305c8b7dc05..000000000000
--- a/drivers/gpio/gpio-adp5520.c
+++ /dev/null
@@ -1,169 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * GPIO driver for Analog Devices ADP5520 MFD PMICs
- *
- * Copyright 2009 Analog Devices Inc.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/adp5520.h>
-#include <linux/gpio/driver.h>
-
-struct adp5520_gpio {
- struct device *master;
- struct gpio_chip gpio_chip;
- unsigned char lut[ADP5520_MAXGPIOS];
- unsigned long output;
-};
-
-static int adp5520_gpio_get_value(struct gpio_chip *chip, unsigned off)
-{
- struct adp5520_gpio *dev;
- uint8_t reg_val;
-
- dev = gpiochip_get_data(chip);
-
- /*
- * There are dedicated registers for GPIO IN/OUT.
- * Make sure we return the right value, even when configured as output
- */
-
- if (test_bit(off, &dev->output))
- adp5520_read(dev->master, ADP5520_GPIO_OUT, ®_val);
- else
- adp5520_read(dev->master, ADP5520_GPIO_IN, ®_val);
-
- return !!(reg_val & dev->lut[off]);
-}
-
-static int adp5520_gpio_set_value(struct gpio_chip *chip,
- unsigned int off, int val)
-{
- struct adp5520_gpio *dev;
- dev = gpiochip_get_data(chip);
-
- if (val)
- return adp5520_set_bits(dev->master, ADP5520_GPIO_OUT,
- dev->lut[off]);
- else
- return adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT,
- dev->lut[off]);
-}
-
-static int adp5520_gpio_direction_input(struct gpio_chip *chip, unsigned off)
-{
- struct adp5520_gpio *dev;
- dev = gpiochip_get_data(chip);
-
- clear_bit(off, &dev->output);
-
- return adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_2,
- dev->lut[off]);
-}
-
-static int adp5520_gpio_direction_output(struct gpio_chip *chip,
- unsigned off, int val)
-{
- struct adp5520_gpio *dev;
- int ret = 0;
- dev = gpiochip_get_data(chip);
-
- set_bit(off, &dev->output);
-
- if (val)
- ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_OUT,
- dev->lut[off]);
- else
- ret |= adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT,
- dev->lut[off]);
-
- ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_2,
- dev->lut[off]);
-
- return ret;
-}
-
-static int adp5520_gpio_probe(struct platform_device *pdev)
-{
- struct adp5520_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct adp5520_gpio *dev;
- struct gpio_chip *gc;
- int ret, i, gpios;
- unsigned char ctl_mask = 0;
-
- if (pdata == NULL) {
- dev_err(&pdev->dev, "missing platform data\n");
- return -ENODEV;
- }
-
- if (pdev->id != ID_ADP5520) {
- dev_err(&pdev->dev, "only ADP5520 supports GPIO\n");
- return -ENODEV;
- }
-
- dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
- if (dev == NULL)
- return -ENOMEM;
-
- dev->master = pdev->dev.parent;
-
- for (gpios = 0, i = 0; i < ADP5520_MAXGPIOS; i++)
- if (pdata->gpio_en_mask & (1 << i))
- dev->lut[gpios++] = 1 << i;
-
- if (gpios < 1)
- return -EINVAL;
-
- gc = &dev->gpio_chip;
- gc->direction_input = adp5520_gpio_direction_input;
- gc->direction_output = adp5520_gpio_direction_output;
- gc->get = adp5520_gpio_get_value;
- gc->set = adp5520_gpio_set_value;
- gc->can_sleep = true;
-
- gc->base = pdata->gpio_start;
- gc->ngpio = gpios;
- gc->label = pdev->name;
- gc->owner = THIS_MODULE;
-
- ret = adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_1,
- pdata->gpio_en_mask);
-
- if (pdata->gpio_en_mask & ADP5520_GPIO_C3)
- ctl_mask |= ADP5520_C3_MODE;
-
- if (pdata->gpio_en_mask & ADP5520_GPIO_R3)
- ctl_mask |= ADP5520_R3_MODE;
-
- if (ctl_mask)
- ret = adp5520_set_bits(dev->master, ADP5520_LED_CONTROL,
- ctl_mask);
-
- ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP,
- pdata->gpio_pullup_mask);
-
- if (ret) {
- dev_err(&pdev->dev, "failed to write\n");
- return ret;
- }
-
- return devm_gpiochip_add_data(&pdev->dev, &dev->gpio_chip, dev);
-}
-
-static struct platform_driver adp5520_gpio_driver = {
- .driver = {
- .name = "adp5520-gpio",
- },
- .probe = adp5520_gpio_probe,
-};
-
-module_platform_driver(adp5520_gpio_driver);
-
-MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
-MODULE_DESCRIPTION("GPIO ADP5520 Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:adp5520-gpio");
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index d8c64f333462..ec3fe4632d8d 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -27,16 +27,6 @@ config KEYBOARD_ADC
To compile this driver as a module, choose M here: the
module will be called adc_keys.
-config KEYBOARD_ADP5520
- tristate "Keypad Support for ADP5520 PMIC"
- depends on PMIC_ADP5520
- help
- This option enables support for the keypad scan matrix
- on Analog Devices ADP5520 PMICs.
-
- To compile this driver as a module, choose M here: the module will
- be called adp5520-keys.
-
config KEYBOARD_ADP5585
tristate "ADP558x keypad support"
depends on MFD_ADP5585
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 60bb7baf802f..c1a443c64962 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -6,7 +6,6 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_KEYBOARD_ADC) += adc-keys.o
-obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5585) += adp5585-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c
deleted file mode 100644
index 980d739e45b8..000000000000
--- a/drivers/input/keyboard/adp5520-keys.c
+++ /dev/null
@@ -1,191 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Keypad driver for Analog Devices ADP5520 MFD PMICs
- *
- * Copyright 2009 Analog Devices Inc.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/mfd/adp5520.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-
-struct adp5520_keys {
- struct input_dev *input;
- struct notifier_block notifier;
- struct device *master;
- unsigned short keycode[ADP5520_KEYMAPSIZE];
-};
-
-static void adp5520_keys_report_event(struct adp5520_keys *dev,
- unsigned short keymask, int value)
-{
- int i;
-
- for (i = 0; i < ADP5520_MAXKEYS; i++)
- if (keymask & (1 << i))
- input_report_key(dev->input, dev->keycode[i], value);
-
- input_sync(dev->input);
-}
-
-static int adp5520_keys_notifier(struct notifier_block *nb,
- unsigned long event, void *data)
-{
- struct adp5520_keys *dev;
- uint8_t reg_val_lo, reg_val_hi;
- unsigned short keymask;
-
- dev = container_of(nb, struct adp5520_keys, notifier);
-
- if (event & ADP5520_KP_INT) {
- adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, ®_val_lo);
- adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, ®_val_hi);
-
- keymask = (reg_val_hi << 8) | reg_val_lo;
- /* Read twice to clear */
- adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, ®_val_lo);
- adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, ®_val_hi);
- keymask |= (reg_val_hi << 8) | reg_val_lo;
- adp5520_keys_report_event(dev, keymask, 1);
- }
-
- if (event & ADP5520_KR_INT) {
- adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, ®_val_lo);
- adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, ®_val_hi);
-
- keymask = (reg_val_hi << 8) | reg_val_lo;
- /* Read twice to clear */
- adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, ®_val_lo);
- adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, ®_val_hi);
- keymask |= (reg_val_hi << 8) | reg_val_lo;
- adp5520_keys_report_event(dev, keymask, 0);
- }
-
- return 0;
-}
-
-static int adp5520_keys_probe(struct platform_device *pdev)
-{
- struct adp5520_keys_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct input_dev *input;
- struct adp5520_keys *dev;
- int ret, i;
- unsigned char en_mask, ctl_mask = 0;
-
- if (pdev->id != ID_ADP5520) {
- dev_err(&pdev->dev, "only ADP5520 supports Keypad\n");
- return -EINVAL;
- }
-
- if (!pdata) {
- dev_err(&pdev->dev, "missing platform data\n");
- return -EINVAL;
- }
-
- if (!(pdata->rows_en_mask && pdata->cols_en_mask))
- return -EINVAL;
-
- dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- dev_err(&pdev->dev, "failed to alloc memory\n");
- return -ENOMEM;
- }
-
- input = devm_input_allocate_device(&pdev->dev);
- if (!input)
- return -ENOMEM;
-
- dev->master = pdev->dev.parent;
- dev->input = input;
-
- input->name = pdev->name;
- input->phys = "adp5520-keys/input0";
- input->dev.parent = &pdev->dev;
-
- input->id.bustype = BUS_I2C;
- input->id.vendor = 0x0001;
- input->id.product = 0x5520;
- input->id.version = 0x0001;
-
- input->keycodesize = sizeof(dev->keycode[0]);
- input->keycodemax = pdata->keymapsize;
- input->keycode = dev->keycode;
-
- memcpy(dev->keycode, pdata->keymap,
- pdata->keymapsize * input->keycodesize);
-
- /* setup input device */
- __set_bit(EV_KEY, input->evbit);
-
- if (pdata->repeat)
- __set_bit(EV_REP, input->evbit);
-
- for (i = 0; i < input->keycodemax; i++)
- __set_bit(dev->keycode[i], input->keybit);
- __clear_bit(KEY_RESERVED, input->keybit);
-
- ret = input_register_device(input);
- if (ret) {
- dev_err(&pdev->dev, "unable to register input device\n");
- return ret;
- }
-
- en_mask = pdata->rows_en_mask | pdata->cols_en_mask;
-
- ret = adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_1, en_mask);
-
- if (en_mask & ADP5520_COL_C3)
- ctl_mask |= ADP5520_C3_MODE;
-
- if (en_mask & ADP5520_ROW_R3)
- ctl_mask |= ADP5520_R3_MODE;
-
- if (ctl_mask)
- ret |= adp5520_set_bits(dev->master, ADP5520_LED_CONTROL,
- ctl_mask);
-
- ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP,
- pdata->rows_en_mask);
-
- if (ret) {
- dev_err(&pdev->dev, "failed to write\n");
- return -EIO;
- }
-
- dev->notifier.notifier_call = adp5520_keys_notifier;
- ret = adp5520_register_notifier(dev->master, &dev->notifier,
- ADP5520_KP_IEN | ADP5520_KR_IEN);
- if (ret) {
- dev_err(&pdev->dev, "failed to register notifier\n");
- return ret;
- }
-
- platform_set_drvdata(pdev, dev);
- return 0;
-}
-
-static void adp5520_keys_remove(struct platform_device *pdev)
-{
- struct adp5520_keys *dev = platform_get_drvdata(pdev);
-
- adp5520_unregister_notifier(dev->master, &dev->notifier,
- ADP5520_KP_IEN | ADP5520_KR_IEN);
-}
-
-static struct platform_driver adp5520_keys_driver = {
- .driver = {
- .name = "adp5520-keys",
- },
- .probe = adp5520_keys_probe,
- .remove = adp5520_keys_remove,
-};
-module_platform_driver(adp5520_keys_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Keys ADP5520 Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:adp5520-keys");
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index d0d3182236be..5d6fc2a06016 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -718,17 +718,6 @@ config LEDS_LT3593
LT3593 controller. This controller uses a special one-wire pulse
coding protocol to set the brightness.
-config LEDS_ADP5520
- tristate "LED Support for ADP5520/ADP5501 PMIC"
- depends on LEDS_CLASS
- depends on PMIC_ADP5520
- help
- This option enables support for on-chip LED drivers found
- on Analog Devices ADP5520/ADP5501 PMICs.
-
- To compile this driver as a module, choose M here: the module will
- be called leds-adp5520.
-
config LEDS_MAX5970
tristate "LED Support for Maxim 5970"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index a68244bd50fb..96deebbca9d5 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_LEDS_KUNIT_TEST) += led-test.o
# LED Platform Drivers (keep this sorted, M-| sort)
obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
obj-$(CONFIG_LEDS_ACER_A500) += leds-acer-a500.o
-obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o
obj-$(CONFIG_LEDS_APU) += leds-apu.o
obj-$(CONFIG_LEDS_ARIEL) += leds-ariel.o
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
deleted file mode 100644
index 13e5bc80e56e..000000000000
--- a/drivers/leds/leds-adp5520.c
+++ /dev/null
@@ -1,195 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * LEDs driver for Analog Devices ADP5520/ADP5501 MFD PMICs
- *
- * Copyright 2009 Analog Devices Inc.
- *
- * Loosely derived from leds-da903x:
- * Copyright (C) 2008 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
- *
- * Copyright (C) 2006-2008 Marvell International Ltd.
- * Eric Miao <eric.miao@marvell.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/mfd/adp5520.h>
-#include <linux/slab.h>
-
-struct adp5520_led {
- struct led_classdev cdev;
- struct device *master;
- int id;
- int flags;
-};
-
-static int adp5520_led_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct adp5520_led *led;
-
- led = container_of(led_cdev, struct adp5520_led, cdev);
- return adp5520_write(led->master, ADP5520_LED1_CURRENT + led->id - 1,
- value >> 2);
-}
-
-static int adp5520_led_setup(struct adp5520_led *led)
-{
- struct device *dev = led->master;
- int flags = led->flags;
- int ret = 0;
-
- switch (led->id) {
- case FLAG_ID_ADP5520_LED1_ADP5501_LED0:
- ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
- (flags >> ADP5520_FLAG_OFFT_SHIFT) &
- ADP5520_FLAG_OFFT_MASK);
- ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
- ADP5520_LED1_EN);
- break;
- case FLAG_ID_ADP5520_LED2_ADP5501_LED1:
- ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
- ((flags >> ADP5520_FLAG_OFFT_SHIFT) &
- ADP5520_FLAG_OFFT_MASK) << 2);
- ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
- ADP5520_R3_MODE);
- ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
- ADP5520_LED2_EN);
- break;
- case FLAG_ID_ADP5520_LED3_ADP5501_LED2:
- ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
- ((flags >> ADP5520_FLAG_OFFT_SHIFT) &
- ADP5520_FLAG_OFFT_MASK) << 4);
- ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
- ADP5520_C3_MODE);
- ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
- ADP5520_LED3_EN);
- break;
- }
-
- return ret;
-}
-
-static int adp5520_led_prepare(struct platform_device *pdev)
-{
- struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct device *dev = pdev->dev.parent;
- int ret = 0;
-
- ret |= adp5520_write(dev, ADP5520_LED1_CURRENT, 0);
- ret |= adp5520_write(dev, ADP5520_LED2_CURRENT, 0);
- ret |= adp5520_write(dev, ADP5520_LED3_CURRENT, 0);
- ret |= adp5520_write(dev, ADP5520_LED_TIME, pdata->led_on_time << 6);
- ret |= adp5520_write(dev, ADP5520_LED_FADE, FADE_VAL(pdata->fade_in,
- pdata->fade_out));
-
- return ret;
-}
-
-static int adp5520_led_probe(struct platform_device *pdev)
-{
- struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct adp5520_led *led, *led_dat;
- struct led_info *cur_led;
- int ret, i;
-
- if (pdata == NULL) {
- dev_err(&pdev->dev, "missing platform data\n");
- return -ENODEV;
- }
-
- if (pdata->num_leds > ADP5520_01_MAXLEDS) {
- dev_err(&pdev->dev, "can't handle more than %d LEDS\n",
- ADP5520_01_MAXLEDS);
- return -EFAULT;
- }
-
- led = devm_kcalloc(&pdev->dev, pdata->num_leds, sizeof(*led),
- GFP_KERNEL);
- if (!led)
- return -ENOMEM;
-
- ret = adp5520_led_prepare(pdev);
- if (ret) {
- dev_err(&pdev->dev, "failed to write\n");
- return ret;
- }
-
- for (i = 0; i < pdata->num_leds; ++i) {
- cur_led = &pdata->leds[i];
- led_dat = &led[i];
-
- led_dat->cdev.name = cur_led->name;
- led_dat->cdev.default_trigger = cur_led->default_trigger;
- led_dat->cdev.brightness_set_blocking = adp5520_led_set;
- led_dat->cdev.brightness = LED_OFF;
-
- if (cur_led->flags & ADP5520_FLAG_LED_MASK)
- led_dat->flags = cur_led->flags;
- else
- led_dat->flags = i + 1;
-
- led_dat->id = led_dat->flags & ADP5520_FLAG_LED_MASK;
-
- led_dat->master = pdev->dev.parent;
-
- ret = led_classdev_register(led_dat->master, &led_dat->cdev);
- if (ret) {
- dev_err(&pdev->dev, "failed to register LED %d\n",
- led_dat->id);
- goto err;
- }
-
- ret = adp5520_led_setup(led_dat);
- if (ret) {
- dev_err(&pdev->dev, "failed to write\n");
- i++;
- goto err;
- }
- }
-
- platform_set_drvdata(pdev, led);
- return 0;
-
-err:
- if (i > 0) {
- for (i = i - 1; i >= 0; i--)
- led_classdev_unregister(&led[i].cdev);
- }
-
- return ret;
-}
-
-static void adp5520_led_remove(struct platform_device *pdev)
-{
- struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct adp5520_led *led;
- int i;
-
- led = platform_get_drvdata(pdev);
-
- adp5520_clr_bits(led->master, ADP5520_LED_CONTROL,
- ADP5520_LED1_EN | ADP5520_LED2_EN | ADP5520_LED3_EN);
-
- for (i = 0; i < pdata->num_leds; i++) {
- led_classdev_unregister(&led[i].cdev);
- }
-}
-
-static struct platform_driver adp5520_led_driver = {
- .driver = {
- .name = "adp5520-led",
- },
- .probe = adp5520_led_probe,
- .remove = adp5520_led_remove,
-};
-
-module_platform_driver(adp5520_led_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("LEDS ADP5520(01) Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:adp5520-led");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2b621a77619c..5126bae8e61f 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -115,16 +115,6 @@ config MFD_AS3722
controllers, 11 LDOs, RTC, automatic battery, temperature and
over current monitoring, GPIOs, ADC and a watchdog.
-config PMIC_ADP5520
- bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
- depends on I2C=y
- help
- Say yes here to add support for Analog Devices ADP5520 and ADP5501,
- Multifunction Power Management IC. This includes
- the I2C driver and the core APIs _only_, you have to select
- individual components like LCD backlight, LEDs, GPIOs and Kepad
- under the corresponding menus.
-
config MFD_AAT2870_CORE
bool "AnalogicTech AAT2870"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 36f0ab039b77..a6cc4fcc3e1d 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -193,7 +193,6 @@ obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
# ab8500-core need to come after db8500-prcmu (which provides the channel)
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
-obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
obj-$(CONFIG_MFD_ADP5585) += adp5585.o
obj-$(CONFIG_MFD_KEMPLD) += kempld-core.o
obj-$(CONFIG_MFD_INTEL_QUARK_I2C_GPIO) += intel_quark_i2c_gpio.o
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
deleted file mode 100644
index bd6f4965ebc8..000000000000
--- a/drivers/mfd/adp5520.c
+++ /dev/null
@@ -1,346 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Base driver for Analog Devices ADP5520/ADP5501 MFD PMICs
- * LCD Backlight: drivers/video/backlight/adp5520_bl
- * LEDs : drivers/led/leds-adp5520
- * GPIO : drivers/gpio/adp5520-gpio (ADP5520 only)
- * Keys : drivers/input/keyboard/adp5520-keys (ADP5520 only)
- *
- * Copyright 2009 Analog Devices Inc.
- *
- * Author: Michael Hennerich <michael.hennerich@analog.com>
- *
- * Derived from da903x:
- * Copyright (C) 2008 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
- *
- * Copyright (C) 2006-2008 Marvell International Ltd.
- * Eric Miao <eric.miao@marvell.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-
-#include <linux/mfd/adp5520.h>
-
-struct adp5520_chip {
- struct i2c_client *client;
- struct device *dev;
- struct mutex lock;
- struct blocking_notifier_head notifier_list;
- int irq;
- unsigned long id;
- uint8_t mode;
-};
-
-static int __adp5520_read(struct i2c_client *client,
- int reg, uint8_t *val)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
- return ret;
- }
-
- *val = (uint8_t)ret;
- return 0;
-}
-
-static int __adp5520_write(struct i2c_client *client,
- int reg, uint8_t val)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, reg, val);
- if (ret < 0) {
- dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
- val, reg);
- return ret;
- }
- return 0;
-}
-
-static int __adp5520_ack_bits(struct i2c_client *client, int reg,
- uint8_t bit_mask)
-{
- struct adp5520_chip *chip = i2c_get_clientdata(client);
- uint8_t reg_val;
- int ret;
-
- mutex_lock(&chip->lock);
-
- ret = __adp5520_read(client, reg, ®_val);
-
- if (!ret) {
- reg_val |= bit_mask;
- ret = __adp5520_write(client, reg, reg_val);
- }
-
- mutex_unlock(&chip->lock);
- return ret;
-}
-
-int adp5520_write(struct device *dev, int reg, uint8_t val)
-{
- return __adp5520_write(to_i2c_client(dev), reg, val);
-}
-EXPORT_SYMBOL_GPL(adp5520_write);
-
-int adp5520_read(struct device *dev, int reg, uint8_t *val)
-{
- return __adp5520_read(to_i2c_client(dev), reg, val);
-}
-EXPORT_SYMBOL_GPL(adp5520_read);
-
-int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask)
-{
- struct adp5520_chip *chip = dev_get_drvdata(dev);
- uint8_t reg_val;
- int ret;
-
- mutex_lock(&chip->lock);
-
- ret = __adp5520_read(chip->client, reg, ®_val);
-
- if (!ret && ((reg_val & bit_mask) != bit_mask)) {
- reg_val |= bit_mask;
- ret = __adp5520_write(chip->client, reg, reg_val);
- }
-
- mutex_unlock(&chip->lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(adp5520_set_bits);
-
-int adp5520_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
-{
- struct adp5520_chip *chip = dev_get_drvdata(dev);
- uint8_t reg_val;
- int ret;
-
- mutex_lock(&chip->lock);
-
- ret = __adp5520_read(chip->client, reg, ®_val);
-
- if (!ret && (reg_val & bit_mask)) {
- reg_val &= ~bit_mask;
- ret = __adp5520_write(chip->client, reg, reg_val);
- }
-
- mutex_unlock(&chip->lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(adp5520_clr_bits);
-
-int adp5520_register_notifier(struct device *dev, struct notifier_block *nb,
- unsigned int events)
-{
- struct adp5520_chip *chip = dev_get_drvdata(dev);
-
- if (chip->irq) {
- adp5520_set_bits(chip->dev, ADP5520_INTERRUPT_ENABLE,
- events & (ADP5520_KP_IEN | ADP5520_KR_IEN |
- ADP5520_OVP_IEN | ADP5520_CMPR_IEN));
-
- return blocking_notifier_chain_register(&chip->notifier_list,
- nb);
- }
-
- return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(adp5520_register_notifier);
-
-int adp5520_unregister_notifier(struct device *dev, struct notifier_block *nb,
- unsigned int events)
-{
- struct adp5520_chip *chip = dev_get_drvdata(dev);
-
- adp5520_clr_bits(chip->dev, ADP5520_INTERRUPT_ENABLE,
- events & (ADP5520_KP_IEN | ADP5520_KR_IEN |
- ADP5520_OVP_IEN | ADP5520_CMPR_IEN));
-
- return blocking_notifier_chain_unregister(&chip->notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(adp5520_unregister_notifier);
-
-static irqreturn_t adp5520_irq_thread(int irq, void *data)
-{
- struct adp5520_chip *chip = data;
- unsigned int events;
- uint8_t reg_val;
- int ret;
-
- ret = __adp5520_read(chip->client, ADP5520_MODE_STATUS, ®_val);
- if (ret)
- goto out;
-
- events = reg_val & (ADP5520_OVP_INT | ADP5520_CMPR_INT |
- ADP5520_GPI_INT | ADP5520_KR_INT | ADP5520_KP_INT);
-
- blocking_notifier_call_chain(&chip->notifier_list, events, NULL);
- /* ACK, Sticky bits are W1C */
- __adp5520_ack_bits(chip->client, ADP5520_MODE_STATUS, events);
-
-out:
- return IRQ_HANDLED;
-}
-
-static int __remove_subdev(struct device *dev, void *unused)
-{
- platform_device_unregister(to_platform_device(dev));
- return 0;
-}
-
-static int adp5520_remove_subdevs(struct adp5520_chip *chip)
-{
- return device_for_each_child(chip->dev, NULL, __remove_subdev);
-}
-
-static int adp5520_probe(struct i2c_client *client)
-{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
- struct adp5520_platform_data *pdata = dev_get_platdata(&client->dev);
- struct platform_device *pdev;
- struct adp5520_chip *chip;
- int ret;
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&client->dev, "SMBUS Word Data not Supported\n");
- return -EIO;
- }
-
- if (pdata == NULL) {
- dev_err(&client->dev, "missing platform data\n");
- return -ENODEV;
- }
-
- chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- i2c_set_clientdata(client, chip);
- chip->client = client;
-
- chip->dev = &client->dev;
- chip->irq = client->irq;
- chip->id = id->driver_data;
- mutex_init(&chip->lock);
-
- if (chip->irq) {
- BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);
-
- ret = request_threaded_irq(chip->irq, NULL, adp5520_irq_thread,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "adp5520", chip);
- if (ret) {
- dev_err(&client->dev, "failed to request irq %d\n",
- chip->irq);
- return ret;
- }
- }
-
- ret = adp5520_write(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
- if (ret) {
- dev_err(&client->dev, "failed to write\n");
- goto out_free_irq;
- }
-
- if (pdata->keys) {
- pdev = platform_device_register_data(chip->dev, "adp5520-keys",
- chip->id, pdata->keys, sizeof(*pdata->keys));
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- goto out_remove_subdevs;
- }
- }
-
- if (pdata->gpio) {
- pdev = platform_device_register_data(chip->dev, "adp5520-gpio",
- chip->id, pdata->gpio, sizeof(*pdata->gpio));
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- goto out_remove_subdevs;
- }
- }
-
- if (pdata->leds) {
- pdev = platform_device_register_data(chip->dev, "adp5520-led",
- chip->id, pdata->leds, sizeof(*pdata->leds));
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- goto out_remove_subdevs;
- }
- }
-
- if (pdata->backlight) {
- pdev = platform_device_register_data(chip->dev,
- "adp5520-backlight",
- chip->id,
- pdata->backlight,
- sizeof(*pdata->backlight));
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- goto out_remove_subdevs;
- }
- }
-
- return 0;
-
-out_remove_subdevs:
- adp5520_remove_subdevs(chip);
-
-out_free_irq:
- if (chip->irq)
- free_irq(chip->irq, chip);
-
- return ret;
-}
-
-static int adp5520_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
-
- adp5520_read(chip->dev, ADP5520_MODE_STATUS, &chip->mode);
- /* All other bits are W1C */
- chip->mode &= ADP5520_BL_EN | ADP5520_DIM_EN | ADP5520_nSTNBY;
- adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0);
- return 0;
-}
-
-static int adp5520_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
-
- adp5520_write(chip->dev, ADP5520_MODE_STATUS, chip->mode);
- return 0;
-}
-
-static DEFINE_SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume);
-
-static const struct i2c_device_id adp5520_id[] = {
- { "pmic-adp5520", ID_ADP5520 },
- { "pmic-adp5501", ID_ADP5501 },
- { }
-};
-
-static struct i2c_driver adp5520_driver = {
- .driver = {
- .name = "adp5520",
- .pm = pm_sleep_ptr(&adp5520_pm),
- .suppress_bind_attrs = true,
- },
- .probe = adp5520_probe,
- .id_table = adp5520_id,
-};
-builtin_i2c_driver(adp5520_driver);
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index dbf4ca23a9b6..63e5059563b4 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -365,16 +365,6 @@ config BACKLIGHT_WM831X
If you have a backlight driven by the ISINK and DCDC of a
WM831x PMIC say y to enable the backlight driver for it.
-config BACKLIGHT_ADP5520
- tristate "Backlight Driver for ADP5520/ADP5501 using WLED"
- depends on PMIC_ADP5520
- help
- If you have a LCD backlight connected to the BST/BL_SNK output of
- ADP5520 or ADP5501, say Y here to enable this driver.
-
- To compile this driver as a module, choose M here: the module will
- be called adp5520_bl.
-
config BACKLIGHT_ADP8860
tristate "Backlight Driver for ADP8860/ADP8861/ADP8863 using WLED"
depends on I2C
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 34469711c6cd..1a6bef13430b 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
-obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
deleted file mode 100644
index 81c40d355aae..000000000000
--- a/drivers/video/backlight/adp5520_bl.c
+++ /dev/null
@@ -1,385 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Backlight driver for Analog Devices ADP5520/ADP5501 MFD PMICs
- *
- * Copyright 2009 Analog Devices Inc.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/backlight.h>
-#include <linux/mfd/adp5520.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-struct adp5520_bl {
- struct device *master;
- struct adp5520_backlight_platform_data *pdata;
- struct mutex lock;
- unsigned long cached_daylight_max;
- int id;
- int current_brightness;
-};
-
-static int adp5520_bl_set(struct backlight_device *bl, int brightness)
-{
- struct adp5520_bl *data = bl_get_data(bl);
- struct device *master = data->master;
- int ret = 0;
-
- if (data->pdata->en_ambl_sens) {
- if ((brightness > 0) && (brightness < ADP5020_MAX_BRIGHTNESS)) {
- /* Disable Ambient Light auto adjust */
- ret |= adp5520_clr_bits(master, ADP5520_BL_CONTROL,
- ADP5520_BL_AUTO_ADJ);
- ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX,
- brightness);
- } else {
- /*
- * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
- * restore daylight l3 sysfs brightness
- */
- ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX,
- data->cached_daylight_max);
- ret |= adp5520_set_bits(master, ADP5520_BL_CONTROL,
- ADP5520_BL_AUTO_ADJ);
- }
- } else {
- ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX, brightness);
- }
-
- if (data->current_brightness && brightness == 0)
- ret |= adp5520_set_bits(master,
- ADP5520_MODE_STATUS, ADP5520_DIM_EN);
- else if (data->current_brightness == 0 && brightness)
- ret |= adp5520_clr_bits(master,
- ADP5520_MODE_STATUS, ADP5520_DIM_EN);
-
- if (!ret)
- data->current_brightness = brightness;
-
- return ret;
-}
-
-static int adp5520_bl_update_status(struct backlight_device *bl)
-{
- return adp5520_bl_set(bl, backlight_get_brightness(bl));
-}
-
-static int adp5520_bl_get_brightness(struct backlight_device *bl)
-{
- struct adp5520_bl *data = bl_get_data(bl);
- int error;
- uint8_t reg_val;
-
- error = adp5520_read(data->master, ADP5520_BL_VALUE, ®_val);
-
- return error ? data->current_brightness : reg_val;
-}
-
-static const struct backlight_ops adp5520_bl_ops = {
- .update_status = adp5520_bl_update_status,
- .get_brightness = adp5520_bl_get_brightness,
-};
-
-static int adp5520_bl_setup(struct backlight_device *bl)
-{
- struct adp5520_bl *data = bl_get_data(bl);
- struct device *master = data->master;
- struct adp5520_backlight_platform_data *pdata = data->pdata;
- int ret = 0;
-
- ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX,
- pdata->l1_daylight_max);
- ret |= adp5520_write(master, ADP5520_DAYLIGHT_DIM,
- pdata->l1_daylight_dim);
-
- if (pdata->en_ambl_sens) {
- data->cached_daylight_max = pdata->l1_daylight_max;
- ret |= adp5520_write(master, ADP5520_OFFICE_MAX,
- pdata->l2_office_max);
- ret |= adp5520_write(master, ADP5520_OFFICE_DIM,
- pdata->l2_office_dim);
- ret |= adp5520_write(master, ADP5520_DARK_MAX,
- pdata->l3_dark_max);
- ret |= adp5520_write(master, ADP5520_DARK_DIM,
- pdata->l3_dark_dim);
- ret |= adp5520_write(master, ADP5520_L2_TRIP,
- pdata->l2_trip);
- ret |= adp5520_write(master, ADP5520_L2_HYS,
- pdata->l2_hyst);
- ret |= adp5520_write(master, ADP5520_L3_TRIP,
- pdata->l3_trip);
- ret |= adp5520_write(master, ADP5520_L3_HYS,
- pdata->l3_hyst);
- ret |= adp5520_write(master, ADP5520_ALS_CMPR_CFG,
- ALS_CMPR_CFG_VAL(pdata->abml_filt,
- ADP5520_L3_EN));
- }
-
- ret |= adp5520_write(master, ADP5520_BL_CONTROL,
- BL_CTRL_VAL(pdata->fade_led_law,
- pdata->en_ambl_sens));
-
- ret |= adp5520_write(master, ADP5520_BL_FADE, FADE_VAL(pdata->fade_in,
- pdata->fade_out));
-
- ret |= adp5520_set_bits(master, ADP5520_MODE_STATUS,
- ADP5520_BL_EN | ADP5520_DIM_EN);
-
- return ret;
-}
-
-static ssize_t adp5520_show(struct device *dev, char *buf, int reg)
-{
- struct adp5520_bl *data = dev_get_drvdata(dev);
- int ret;
- uint8_t reg_val;
-
- mutex_lock(&data->lock);
- ret = adp5520_read(data->master, reg, ®_val);
- mutex_unlock(&data->lock);
-
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%u\n", reg_val);
-}
-
-static ssize_t adp5520_store(struct device *dev, const char *buf,
- size_t count, int reg)
-{
- struct adp5520_bl *data = dev_get_drvdata(dev);
- unsigned long val;
- int ret;
-
- ret = kstrtoul(buf, 10, &val);
- if (ret)
- return ret;
-
- mutex_lock(&data->lock);
- adp5520_write(data->master, reg, val);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t adp5520_bl_dark_max_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return adp5520_show(dev, buf, ADP5520_DARK_MAX);
-}
-
-static ssize_t adp5520_bl_dark_max_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return adp5520_store(dev, buf, count, ADP5520_DARK_MAX);
-}
-static DEVICE_ATTR(dark_max, 0664, adp5520_bl_dark_max_show,
- adp5520_bl_dark_max_store);
-
-static ssize_t adp5520_bl_office_max_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return adp5520_show(dev, buf, ADP5520_OFFICE_MAX);
-}
-
-static ssize_t adp5520_bl_office_max_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return adp5520_store(dev, buf, count, ADP5520_OFFICE_MAX);
-}
-static DEVICE_ATTR(office_max, 0664, adp5520_bl_office_max_show,
- adp5520_bl_office_max_store);
-
-static ssize_t adp5520_bl_daylight_max_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return adp5520_show(dev, buf, ADP5520_DAYLIGHT_MAX);
-}
-
-static ssize_t adp5520_bl_daylight_max_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct adp5520_bl *data = dev_get_drvdata(dev);
- int ret;
-
- ret = kstrtoul(buf, 10, &data->cached_daylight_max);
- if (ret < 0)
- return ret;
-
- return adp5520_store(dev, buf, count, ADP5520_DAYLIGHT_MAX);
-}
-static DEVICE_ATTR(daylight_max, 0664, adp5520_bl_daylight_max_show,
- adp5520_bl_daylight_max_store);
-
-static ssize_t adp5520_bl_dark_dim_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return adp5520_show(dev, buf, ADP5520_DARK_DIM);
-}
-
-static ssize_t adp5520_bl_dark_dim_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return adp5520_store(dev, buf, count, ADP5520_DARK_DIM);
-}
-static DEVICE_ATTR(dark_dim, 0664, adp5520_bl_dark_dim_show,
- adp5520_bl_dark_dim_store);
-
-static ssize_t adp5520_bl_office_dim_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return adp5520_show(dev, buf, ADP5520_OFFICE_DIM);
-}
-
-static ssize_t adp5520_bl_office_dim_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return adp5520_store(dev, buf, count, ADP5520_OFFICE_DIM);
-}
-static DEVICE_ATTR(office_dim, 0664, adp5520_bl_office_dim_show,
- adp5520_bl_office_dim_store);
-
-static ssize_t adp5520_bl_daylight_dim_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return adp5520_show(dev, buf, ADP5520_DAYLIGHT_DIM);
-}
-
-static ssize_t adp5520_bl_daylight_dim_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return adp5520_store(dev, buf, count, ADP5520_DAYLIGHT_DIM);
-}
-static DEVICE_ATTR(daylight_dim, 0664, adp5520_bl_daylight_dim_show,
- adp5520_bl_daylight_dim_store);
-
-static struct attribute *adp5520_bl_attributes[] = {
- &dev_attr_dark_max.attr,
- &dev_attr_dark_dim.attr,
- &dev_attr_office_max.attr,
- &dev_attr_office_dim.attr,
- &dev_attr_daylight_max.attr,
- &dev_attr_daylight_dim.attr,
- NULL
-};
-
-static const struct attribute_group adp5520_bl_attr_group = {
- .attrs = adp5520_bl_attributes,
-};
-
-static int adp5520_bl_probe(struct platform_device *pdev)
-{
- struct backlight_properties props;
- struct backlight_device *bl;
- struct adp5520_bl *data;
- int ret = 0;
-
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- data->master = pdev->dev.parent;
- data->pdata = dev_get_platdata(&pdev->dev);
-
- if (data->pdata == NULL) {
- dev_err(&pdev->dev, "missing platform data\n");
- return -ENODEV;
- }
-
- data->id = pdev->id;
- data->current_brightness = 0;
-
- mutex_init(&data->lock);
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = ADP5020_MAX_BRIGHTNESS;
- bl = devm_backlight_device_register(&pdev->dev, pdev->name,
- data->master, data, &adp5520_bl_ops,
- &props);
- if (IS_ERR(bl)) {
- dev_err(&pdev->dev, "failed to register backlight\n");
- return PTR_ERR(bl);
- }
-
- bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
- if (data->pdata->en_ambl_sens)
- ret = sysfs_create_group(&bl->dev.kobj,
- &adp5520_bl_attr_group);
-
- if (ret) {
- dev_err(&pdev->dev, "failed to register sysfs\n");
- return ret;
- }
-
- platform_set_drvdata(pdev, bl);
- ret = adp5520_bl_setup(bl);
- if (ret) {
- dev_err(&pdev->dev, "failed to setup\n");
- if (data->pdata->en_ambl_sens)
- sysfs_remove_group(&bl->dev.kobj,
- &adp5520_bl_attr_group);
- return ret;
- }
-
- backlight_update_status(bl);
-
- return 0;
-}
-
-static void adp5520_bl_remove(struct platform_device *pdev)
-{
- struct backlight_device *bl = platform_get_drvdata(pdev);
- struct adp5520_bl *data = bl_get_data(bl);
-
- adp5520_clr_bits(data->master, ADP5520_MODE_STATUS, ADP5520_BL_EN);
-
- if (data->pdata->en_ambl_sens)
- sysfs_remove_group(&bl->dev.kobj,
- &adp5520_bl_attr_group);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int adp5520_bl_suspend(struct device *dev)
-{
- struct backlight_device *bl = dev_get_drvdata(dev);
-
- return adp5520_bl_set(bl, 0);
-}
-
-static int adp5520_bl_resume(struct device *dev)
-{
- struct backlight_device *bl = dev_get_drvdata(dev);
-
- backlight_update_status(bl);
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(adp5520_bl_pm_ops, adp5520_bl_suspend,
- adp5520_bl_resume);
-
-static struct platform_driver adp5520_bl_driver = {
- .driver = {
- .name = "adp5520-backlight",
- .pm = &adp5520_bl_pm_ops,
- },
- .probe = adp5520_bl_probe,
- .remove = adp5520_bl_remove,
-};
-
-module_platform_driver(adp5520_bl_driver);
-
-MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
-MODULE_DESCRIPTION("ADP5520(01) Backlight Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:adp5520-backlight");
diff --git a/include/linux/mfd/adp5520.h b/include/linux/mfd/adp5520.h
deleted file mode 100644
index 9a14f80ec4ad..000000000000
--- a/include/linux/mfd/adp5520.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Definitions and platform data for Analog Devices
- * ADP5520/ADP5501 MFD PMICs (Backlight, LED, GPIO and Keys)
- *
- * Copyright 2009 Analog Devices Inc.
- */
-
-
-#ifndef __LINUX_MFD_ADP5520_H
-#define __LINUX_MFD_ADP5520_H
-
-#define ID_ADP5520 5520
-#define ID_ADP5501 5501
-
-/*
- * ADP5520/ADP5501 Register Map
- */
-
-#define ADP5520_MODE_STATUS 0x00
-#define ADP5520_INTERRUPT_ENABLE 0x01
-#define ADP5520_BL_CONTROL 0x02
-#define ADP5520_BL_TIME 0x03
-#define ADP5520_BL_FADE 0x04
-#define ADP5520_DAYLIGHT_MAX 0x05
-#define ADP5520_DAYLIGHT_DIM 0x06
-#define ADP5520_OFFICE_MAX 0x07
-#define ADP5520_OFFICE_DIM 0x08
-#define ADP5520_DARK_MAX 0x09
-#define ADP5520_DARK_DIM 0x0A
-#define ADP5520_BL_VALUE 0x0B
-#define ADP5520_ALS_CMPR_CFG 0x0C
-#define ADP5520_L2_TRIP 0x0D
-#define ADP5520_L2_HYS 0x0E
-#define ADP5520_L3_TRIP 0x0F
-#define ADP5520_L3_HYS 0x10
-#define ADP5520_LED_CONTROL 0x11
-#define ADP5520_LED_TIME 0x12
-#define ADP5520_LED_FADE 0x13
-#define ADP5520_LED1_CURRENT 0x14
-#define ADP5520_LED2_CURRENT 0x15
-#define ADP5520_LED3_CURRENT 0x16
-
-/*
- * ADP5520 Register Map
- */
-
-#define ADP5520_GPIO_CFG_1 0x17
-#define ADP5520_GPIO_CFG_2 0x18
-#define ADP5520_GPIO_IN 0x19
-#define ADP5520_GPIO_OUT 0x1A
-#define ADP5520_GPIO_INT_EN 0x1B
-#define ADP5520_GPIO_INT_STAT 0x1C
-#define ADP5520_GPIO_INT_LVL 0x1D
-#define ADP5520_GPIO_DEBOUNCE 0x1E
-#define ADP5520_GPIO_PULLUP 0x1F
-#define ADP5520_KP_INT_STAT_1 0x20
-#define ADP5520_KP_INT_STAT_2 0x21
-#define ADP5520_KR_INT_STAT_1 0x22
-#define ADP5520_KR_INT_STAT_2 0x23
-#define ADP5520_KEY_STAT_1 0x24
-#define ADP5520_KEY_STAT_2 0x25
-
-/*
- * MODE_STATUS bits
- */
-
-#define ADP5520_nSTNBY (1 << 7)
-#define ADP5520_BL_EN (1 << 6)
-#define ADP5520_DIM_EN (1 << 5)
-#define ADP5520_OVP_INT (1 << 4)
-#define ADP5520_CMPR_INT (1 << 3)
-#define ADP5520_GPI_INT (1 << 2)
-#define ADP5520_KR_INT (1 << 1)
-#define ADP5520_KP_INT (1 << 0)
-
-/*
- * INTERRUPT_ENABLE bits
- */
-
-#define ADP5520_AUTO_LD_EN (1 << 4)
-#define ADP5520_CMPR_IEN (1 << 3)
-#define ADP5520_OVP_IEN (1 << 2)
-#define ADP5520_KR_IEN (1 << 1)
-#define ADP5520_KP_IEN (1 << 0)
-
-/*
- * BL_CONTROL bits
- */
-
-#define ADP5520_BL_LVL ((x) << 5)
-#define ADP5520_BL_LAW ((x) << 4)
-#define ADP5520_BL_AUTO_ADJ (1 << 3)
-#define ADP5520_OVP_EN (1 << 2)
-#define ADP5520_FOVR (1 << 1)
-#define ADP5520_KP_BL_EN (1 << 0)
-
-/*
- * ALS_CMPR_CFG bits
- */
-
-#define ADP5520_L3_OUT (1 << 3)
-#define ADP5520_L2_OUT (1 << 2)
-#define ADP5520_L3_EN (1 << 1)
-
-#define ADP5020_MAX_BRIGHTNESS 0x7F
-
-#define FADE_VAL(in, out) ((0xF & (in)) | ((0xF & (out)) << 4))
-#define BL_CTRL_VAL(law, auto) (((1 & (auto)) << 3) | ((0x3 & (law)) << 4))
-#define ALS_CMPR_CFG_VAL(filt, l3_en) (((0x7 & filt) << 5) | l3_en)
-
-/*
- * LEDs subdevice bits and masks
- */
-
-#define ADP5520_01_MAXLEDS 3
-
-#define ADP5520_FLAG_LED_MASK 0x3
-#define ADP5520_FLAG_OFFT_SHIFT 8
-#define ADP5520_FLAG_OFFT_MASK 0x3
-
-#define ADP5520_R3_MODE (1 << 5)
-#define ADP5520_C3_MODE (1 << 4)
-#define ADP5520_LED_LAW (1 << 3)
-#define ADP5520_LED3_EN (1 << 2)
-#define ADP5520_LED2_EN (1 << 1)
-#define ADP5520_LED1_EN (1 << 0)
-
-/*
- * GPIO subdevice bits and masks
- */
-
-#define ADP5520_MAXGPIOS 8
-
-#define ADP5520_GPIO_C3 (1 << 7) /* LED2 or GPIO7 aka C3 */
-#define ADP5520_GPIO_C2 (1 << 6)
-#define ADP5520_GPIO_C1 (1 << 5)
-#define ADP5520_GPIO_C0 (1 << 4)
-#define ADP5520_GPIO_R3 (1 << 3) /* LED3 or GPIO3 aka R3 */
-#define ADP5520_GPIO_R2 (1 << 2)
-#define ADP5520_GPIO_R1 (1 << 1)
-#define ADP5520_GPIO_R0 (1 << 0)
-
-struct adp5520_gpio_platform_data {
- unsigned gpio_start;
- u8 gpio_en_mask;
- u8 gpio_pullup_mask;
-};
-
-/*
- * Keypad subdevice bits and masks
- */
-
-#define ADP5520_MAXKEYS 16
-
-#define ADP5520_COL_C3 (1 << 7) /* LED2 or GPIO7 aka C3 */
-#define ADP5520_COL_C2 (1 << 6)
-#define ADP5520_COL_C1 (1 << 5)
-#define ADP5520_COL_C0 (1 << 4)
-#define ADP5520_ROW_R3 (1 << 3) /* LED3 or GPIO3 aka R3 */
-#define ADP5520_ROW_R2 (1 << 2)
-#define ADP5520_ROW_R1 (1 << 1)
-#define ADP5520_ROW_R0 (1 << 0)
-
-#define ADP5520_KEY(row, col) (col + row * 4)
-#define ADP5520_KEYMAPSIZE ADP5520_MAXKEYS
-
-struct adp5520_keys_platform_data {
- int rows_en_mask; /* Number of rows */
- int cols_en_mask; /* Number of columns */
- const unsigned short *keymap; /* Pointer to keymap */
- unsigned short keymapsize; /* Keymap size */
- unsigned repeat:1; /* Enable key repeat */
-};
-
-
-/*
- * LEDs subdevice platform data
- */
-
-#define FLAG_ID_ADP5520_LED1_ADP5501_LED0 1 /* ADP5520 PIN ILED */
-#define FLAG_ID_ADP5520_LED2_ADP5501_LED1 2 /* ADP5520 PIN C3 */
-#define FLAG_ID_ADP5520_LED3_ADP5501_LED2 3 /* ADP5520 PIN R3 */
-
-#define ADP5520_LED_DIS_BLINK (0 << ADP5520_FLAG_OFFT_SHIFT)
-#define ADP5520_LED_OFFT_600ms (1 << ADP5520_FLAG_OFFT_SHIFT)
-#define ADP5520_LED_OFFT_800ms (2 << ADP5520_FLAG_OFFT_SHIFT)
-#define ADP5520_LED_OFFT_1200ms (3 << ADP5520_FLAG_OFFT_SHIFT)
-
-#define ADP5520_LED_ONT_200ms 0
-#define ADP5520_LED_ONT_600ms 1
-#define ADP5520_LED_ONT_800ms 2
-#define ADP5520_LED_ONT_1200ms 3
-
-struct adp5520_leds_platform_data {
- int num_leds;
- struct led_info *leds;
- u8 fade_in; /* Backlight Fade-In Timer */
- u8 fade_out; /* Backlight Fade-Out Timer */
- u8 led_on_time;
-};
-
-/*
- * Backlight subdevice platform data
- */
-
-#define ADP5520_FADE_T_DIS 0 /* Fade Timer Disabled */
-#define ADP5520_FADE_T_300ms 1 /* 0.3 Sec */
-#define ADP5520_FADE_T_600ms 2
-#define ADP5520_FADE_T_900ms 3
-#define ADP5520_FADE_T_1200ms 4
-#define ADP5520_FADE_T_1500ms 5
-#define ADP5520_FADE_T_1800ms 6
-#define ADP5520_FADE_T_2100ms 7
-#define ADP5520_FADE_T_2400ms 8
-#define ADP5520_FADE_T_2700ms 9
-#define ADP5520_FADE_T_3000ms 10
-#define ADP5520_FADE_T_3500ms 11
-#define ADP5520_FADE_T_4000ms 12
-#define ADP5520_FADE_T_4500ms 13
-#define ADP5520_FADE_T_5000ms 14
-#define ADP5520_FADE_T_5500ms 15 /* 5.5 Sec */
-
-#define ADP5520_BL_LAW_LINEAR 0
-#define ADP5520_BL_LAW_SQUARE 1
-#define ADP5520_BL_LAW_CUBIC1 2
-#define ADP5520_BL_LAW_CUBIC2 3
-
-#define ADP5520_BL_AMBL_FILT_80ms 0 /* Light sensor filter time */
-#define ADP5520_BL_AMBL_FILT_160ms 1
-#define ADP5520_BL_AMBL_FILT_320ms 2
-#define ADP5520_BL_AMBL_FILT_640ms 3
-#define ADP5520_BL_AMBL_FILT_1280ms 4
-#define ADP5520_BL_AMBL_FILT_2560ms 5
-#define ADP5520_BL_AMBL_FILT_5120ms 6
-#define ADP5520_BL_AMBL_FILT_10240ms 7 /* 10.24 sec */
-
- /*
- * Blacklight current 0..30mA
- */
-#define ADP5520_BL_CUR_mA(I) ((I * 127) / 30)
-
- /*
- * L2 comparator current 0..1000uA
- */
-#define ADP5520_L2_COMP_CURR_uA(I) ((I * 255) / 1000)
-
- /*
- * L3 comparator current 0..127uA
- */
-#define ADP5520_L3_COMP_CURR_uA(I) ((I * 255) / 127)
-
-struct adp5520_backlight_platform_data {
- u8 fade_in; /* Backlight Fade-In Timer */
- u8 fade_out; /* Backlight Fade-Out Timer */
- u8 fade_led_law; /* fade-on/fade-off transfer characteristic */
-
- u8 en_ambl_sens; /* 1 = enable ambient light sensor */
- u8 abml_filt; /* Light sensor filter time */
- u8 l1_daylight_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
- u8 l1_daylight_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
- u8 l2_office_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
- u8 l2_office_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
- u8 l3_dark_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
- u8 l3_dark_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
- u8 l2_trip; /* use L2_COMP_CURR_uA(I) 0 <= I <= 1000 uA */
- u8 l2_hyst; /* use L2_COMP_CURR_uA(I) 0 <= I <= 1000 uA */
- u8 l3_trip; /* use L3_COMP_CURR_uA(I) 0 <= I <= 127 uA */
- u8 l3_hyst; /* use L3_COMP_CURR_uA(I) 0 <= I <= 127 uA */
-};
-
-/*
- * MFD chip platform data
- */
-
-struct adp5520_platform_data {
- struct adp5520_keys_platform_data *keys;
- struct adp5520_gpio_platform_data *gpio;
- struct adp5520_leds_platform_data *leds;
- struct adp5520_backlight_platform_data *backlight;
-};
-
-/*
- * MFD chip functions
- */
-
-extern int adp5520_read(struct device *dev, int reg, uint8_t *val);
-extern int adp5520_write(struct device *dev, int reg, u8 val);
-extern int adp5520_clr_bits(struct device *dev, int reg, uint8_t bit_mask);
-extern int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask);
-
-extern int adp5520_register_notifier(struct device *dev,
- struct notifier_block *nb, unsigned int events);
-
-extern int adp5520_unregister_notifier(struct device *dev,
- struct notifier_block *nb, unsigned int events);
-
-#endif /* __LINUX_MFD_ADP5520_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* [PATCH 06/14] mfd: remove unused da903x driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (2 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 05/14] mfd: remove unused adp5520 driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 15:46 ` Sebastian Reichel
2026-09-09 13:21 ` [PATCH 07/14] mfd: remove unused lp8788 driver Arnd Bergmann
` (10 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
This driver was used on a handful of ARM/PXA boards until those
got removed a few years ago. Without devicetree support, there is
no way to use them upstream.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
MAINTAINERS | 1 -
drivers/input/touchscreen/Kconfig | 13 -
drivers/input/touchscreen/Makefile | 1 -
drivers/input/touchscreen/da9034-ts.c | 365 ----------------
drivers/leds/Kconfig | 8 -
drivers/leds/Makefile | 1 -
drivers/leds/leds-da903x.c | 145 -------
drivers/mfd/Kconfig | 11 -
drivers/mfd/Makefile | 2 -
drivers/mfd/da903x.c | 565 -------------------------
drivers/power/supply/Kconfig | 7 -
drivers/power/supply/Makefile | 1 -
drivers/power/supply/da9030_battery.c | 581 --------------------------
drivers/regulator/Kconfig | 8 -
drivers/regulator/Makefile | 1 -
drivers/regulator/da903x-regulator.c | 495 ----------------------
drivers/video/backlight/Kconfig | 7 -
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/da903x_bl.c | 160 -------
19 files changed, 2373 deletions(-)
delete mode 100644 drivers/input/touchscreen/da9034-ts.c
delete mode 100644 drivers/leds/leds-da903x.c
delete mode 100644 drivers/mfd/da903x.c
delete mode 100644 drivers/power/supply/da9030_battery.c
delete mode 100644 drivers/regulator/da903x-regulator.c
delete mode 100644 drivers/video/backlight/da903x_bl.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 86df3fadba87..360655cce7d1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7509,7 +7509,6 @@ F: drivers/input/misc/da72??.[ch]
F: drivers/input/misc/da90??_onkey.c
F: drivers/input/touchscreen/da9052_tsi.c
F: drivers/leds/leds-da90??.c
-F: drivers/mfd/da903x.c
F: drivers/mfd/da90??-*.c
F: drivers/mfd/da91??-*.c
F: drivers/pinctrl/pinctrl-da90??.c
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 9b9ae8ac3f7f..80bffbead88b 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -282,19 +282,6 @@ config TOUCHSCREEN_CYTTSP5
To compile this driver as a module, choose M here: the
module will be called cyttsp5.
-config TOUCHSCREEN_DA9034
- tristate "Touchscreen support for Dialog Semiconductor DA9034"
- depends on PMIC_DA903X
- default y
- help
- Say Y here to enable the support for the touchscreen found
- on Dialog Semiconductor DA9034 PMIC.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called da9034-ts.
-
config TOUCHSCREEN_DA9052
tristate "Dialog DA9052/DA9053 TSI"
depends on PMIC_DA9052
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index bfd9de83389d..31ebdce6d09f 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP5) += cyttsp5.o
-obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o
obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c
deleted file mode 100644
index 2943f6a58388..000000000000
--- a/drivers/input/touchscreen/da9034-ts.c
+++ /dev/null
@@ -1,365 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Touchscreen driver for Dialog Semiconductor DA9034
- *
- * Copyright (C) 2006-2008 Marvell International Ltd.
- * Fengwei Yin <fengwei.yin@marvell.com>
- * Bin Yang <bin.yang@marvell.com>
- * Eric Miao <eric.miao@marvell.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/workqueue.h>
-#include <linux/mfd/da903x.h>
-#include <linux/slab.h>
-
-#define DA9034_MANUAL_CTRL 0x50
-#define DA9034_LDO_ADC_EN (1 << 4)
-
-#define DA9034_AUTO_CTRL1 0x51
-
-#define DA9034_AUTO_CTRL2 0x52
-#define DA9034_AUTO_TSI_EN (1 << 3)
-#define DA9034_PEN_DETECT (1 << 4)
-
-#define DA9034_TSI_CTRL1 0x53
-#define DA9034_TSI_CTRL2 0x54
-#define DA9034_TSI_X_MSB 0x6c
-#define DA9034_TSI_Y_MSB 0x6d
-#define DA9034_TSI_XY_LSB 0x6e
-
-enum {
- STATE_IDLE, /* wait for pendown */
- STATE_BUSY, /* TSI busy sampling */
- STATE_STOP, /* sample available */
- STATE_WAIT, /* Wait to start next sample */
-};
-
-enum {
- EVENT_PEN_DOWN,
- EVENT_PEN_UP,
- EVENT_TSI_READY,
- EVENT_TIMEDOUT,
-};
-
-struct da9034_touch {
- struct device *da9034_dev;
- struct input_dev *input_dev;
-
- struct delayed_work tsi_work;
- struct notifier_block notifier;
-
- int state;
-
- int interval_ms;
- int x_inverted;
- int y_inverted;
-
- int last_x;
- int last_y;
-};
-
-static inline int is_pen_down(struct da9034_touch *touch)
-{
- return da903x_query_status(touch->da9034_dev, DA9034_STATUS_PEN_DOWN);
-}
-
-static inline int detect_pen_down(struct da9034_touch *touch, int on)
-{
- if (on)
- return da903x_set_bits(touch->da9034_dev,
- DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
- else
- return da903x_clr_bits(touch->da9034_dev,
- DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
-}
-
-static int read_tsi(struct da9034_touch *touch)
-{
- uint8_t _x, _y, _v;
- int ret;
-
- ret = da903x_read(touch->da9034_dev, DA9034_TSI_X_MSB, &_x);
- if (ret)
- return ret;
-
- ret = da903x_read(touch->da9034_dev, DA9034_TSI_Y_MSB, &_y);
- if (ret)
- return ret;
-
- ret = da903x_read(touch->da9034_dev, DA9034_TSI_XY_LSB, &_v);
- if (ret)
- return ret;
-
- touch->last_x = ((_x << 2) & 0x3fc) | (_v & 0x3);
- touch->last_y = ((_y << 2) & 0x3fc) | ((_v & 0xc) >> 2);
-
- return 0;
-}
-
-static inline int start_tsi(struct da9034_touch *touch)
-{
- return da903x_set_bits(touch->da9034_dev,
- DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
-}
-
-static inline int stop_tsi(struct da9034_touch *touch)
-{
- return da903x_clr_bits(touch->da9034_dev,
- DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
-}
-
-static inline void report_pen_down(struct da9034_touch *touch)
-{
- int x = touch->last_x;
- int y = touch->last_y;
-
- x &= 0xfff;
- if (touch->x_inverted)
- x = 1024 - x;
- y &= 0xfff;
- if (touch->y_inverted)
- y = 1024 - y;
-
- input_report_abs(touch->input_dev, ABS_X, x);
- input_report_abs(touch->input_dev, ABS_Y, y);
- input_report_key(touch->input_dev, BTN_TOUCH, 1);
-
- input_sync(touch->input_dev);
-}
-
-static inline void report_pen_up(struct da9034_touch *touch)
-{
- input_report_key(touch->input_dev, BTN_TOUCH, 0);
- input_sync(touch->input_dev);
-}
-
-static void da9034_event_handler(struct da9034_touch *touch, int event)
-{
- int err;
-
- switch (touch->state) {
- case STATE_IDLE:
- if (event != EVENT_PEN_DOWN)
- break;
-
- /* Enable auto measurement of the TSI, this will
- * automatically disable pen down detection
- */
- err = start_tsi(touch);
- if (err)
- goto err_reset;
-
- touch->state = STATE_BUSY;
- break;
-
- case STATE_BUSY:
- if (event != EVENT_TSI_READY)
- break;
-
- err = read_tsi(touch);
- if (err)
- goto err_reset;
-
- /* Disable auto measurement of the TSI, so that
- * pen down status will be available
- */
- err = stop_tsi(touch);
- if (err)
- goto err_reset;
-
- touch->state = STATE_STOP;
-
- /* FIXME: PEN_{UP/DOWN} events are expected to be
- * available by stopping TSI, but this is found not
- * always true, delay and simulate such an event
- * here is more reliable
- */
- mdelay(1);
- da9034_event_handler(touch,
- is_pen_down(touch) ? EVENT_PEN_DOWN :
- EVENT_PEN_UP);
- break;
-
- case STATE_STOP:
- if (event == EVENT_PEN_DOWN) {
- report_pen_down(touch);
- schedule_delayed_work(&touch->tsi_work,
- msecs_to_jiffies(touch->interval_ms));
- touch->state = STATE_WAIT;
- }
-
- if (event == EVENT_PEN_UP) {
- report_pen_up(touch);
- touch->state = STATE_IDLE;
- }
- break;
-
- case STATE_WAIT:
- if (event != EVENT_TIMEDOUT)
- break;
-
- if (is_pen_down(touch)) {
- start_tsi(touch);
- touch->state = STATE_BUSY;
- } else {
- report_pen_up(touch);
- touch->state = STATE_IDLE;
- }
- break;
- }
- return;
-
-err_reset:
- touch->state = STATE_IDLE;
- stop_tsi(touch);
- detect_pen_down(touch, 1);
-}
-
-static void da9034_tsi_work(struct work_struct *work)
-{
- struct da9034_touch *touch =
- container_of(work, struct da9034_touch, tsi_work.work);
-
- da9034_event_handler(touch, EVENT_TIMEDOUT);
-}
-
-static int da9034_touch_notifier(struct notifier_block *nb,
- unsigned long event, void *data)
-{
- struct da9034_touch *touch =
- container_of(nb, struct da9034_touch, notifier);
-
- if (event & DA9034_EVENT_TSI_READY)
- da9034_event_handler(touch, EVENT_TSI_READY);
-
- if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
- da9034_event_handler(touch, EVENT_PEN_DOWN);
-
- return 0;
-}
-
-static int da9034_touch_open(struct input_dev *dev)
-{
- struct da9034_touch *touch = input_get_drvdata(dev);
- int ret;
-
- ret = da903x_register_notifier(touch->da9034_dev, &touch->notifier,
- DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
- if (ret)
- return -EBUSY;
-
- /* Enable ADC LDO */
- ret = da903x_set_bits(touch->da9034_dev,
- DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
- if (ret)
- return ret;
-
- /* TSI_DELAY: 3 slots, TSI_SKIP: 3 slots */
- ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL1, 0x1b);
- if (ret)
- return ret;
-
- ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL2, 0x00);
- if (ret)
- return ret;
-
- touch->state = STATE_IDLE;
- detect_pen_down(touch, 1);
-
- return 0;
-}
-
-static void da9034_touch_close(struct input_dev *dev)
-{
- struct da9034_touch *touch = input_get_drvdata(dev);
-
- da903x_unregister_notifier(touch->da9034_dev, &touch->notifier,
- DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
-
- cancel_delayed_work_sync(&touch->tsi_work);
-
- touch->state = STATE_IDLE;
- stop_tsi(touch);
- detect_pen_down(touch, 0);
-
- /* Disable ADC LDO */
- da903x_clr_bits(touch->da9034_dev,
- DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
-}
-
-
-static int da9034_touch_probe(struct platform_device *pdev)
-{
- struct da9034_touch_pdata *pdata = dev_get_platdata(&pdev->dev);
- struct da9034_touch *touch;
- struct input_dev *input_dev;
- int error;
-
- touch = devm_kzalloc(&pdev->dev, sizeof(struct da9034_touch),
- GFP_KERNEL);
- if (!touch) {
- dev_err(&pdev->dev, "failed to allocate driver data\n");
- return -ENOMEM;
- }
-
- touch->da9034_dev = pdev->dev.parent;
-
- if (pdata) {
- touch->interval_ms = pdata->interval_ms;
- touch->x_inverted = pdata->x_inverted;
- touch->y_inverted = pdata->y_inverted;
- } else {
- /* fallback into default */
- touch->interval_ms = 10;
- }
-
- INIT_DELAYED_WORK(&touch->tsi_work, da9034_tsi_work);
- touch->notifier.notifier_call = da9034_touch_notifier;
-
- input_dev = devm_input_allocate_device(&pdev->dev);
- if (!input_dev) {
- dev_err(&pdev->dev, "failed to allocate input device\n");
- return -ENOMEM;
- }
-
- input_dev->name = pdev->name;
- input_dev->open = da9034_touch_open;
- input_dev->close = da9034_touch_close;
- input_dev->dev.parent = &pdev->dev;
-
- __set_bit(EV_ABS, input_dev->evbit);
- __set_bit(ABS_X, input_dev->absbit);
- __set_bit(ABS_Y, input_dev->absbit);
- input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
-
- __set_bit(EV_KEY, input_dev->evbit);
- __set_bit(BTN_TOUCH, input_dev->keybit);
-
- touch->input_dev = input_dev;
- input_set_drvdata(input_dev, touch);
-
- error = input_register_device(input_dev);
- if (error)
- return error;
-
- return 0;
-}
-
-static struct platform_driver da9034_touch_driver = {
- .driver = {
- .name = "da9034-touch",
- },
- .probe = da9034_touch_probe,
-};
-module_platform_driver(da9034_touch_driver);
-
-MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:da9034-touch");
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 5d6fc2a06016..5aab4765d6d7 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -638,14 +638,6 @@ config LEDS_WM8350
This option enables support for LEDs driven by the Wolfson
Microelectronics WM8350 AudioPlus PMIC.
-config LEDS_DA903X
- tristate "LED Support for DA9030/DA9034 PMIC"
- depends on LEDS_CLASS
- depends on PMIC_DA903X
- help
- This option enables support for on-chip LED drivers found
- on Dialog Semiconductor DA9030/DA9034 PMICs.
-
config LEDS_DA9052
tristate "Dialog DA9052/DA9053 LEDS"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 96deebbca9d5..148301cf4865 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -28,7 +28,6 @@ obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
obj-$(CONFIG_LEDS_CPCAP) += leds-cpcap.o
obj-$(CONFIG_LEDS_CROS_EC) += leds-cros_ec.o
-obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
obj-$(CONFIG_LEDS_DA9052) += leds-da9052.o
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
obj-$(CONFIG_LEDS_GPIO_REGISTER) += leds-gpio-register.o
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
deleted file mode 100644
index 71209b3c8f1e..000000000000
--- a/drivers/leds/leds-da903x.c
+++ /dev/null
@@ -1,145 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * LEDs driver for Dialog Semiconductor DA9030/DA9034
- *
- * Copyright (C) 2008 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
- *
- * Copyright (C) 2006-2008 Marvell International Ltd.
- * Eric Miao <eric.miao@marvell.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/mfd/da903x.h>
-#include <linux/slab.h>
-
-#define DA9030_LED1_CONTROL 0x20
-#define DA9030_LED2_CONTROL 0x21
-#define DA9030_LED3_CONTROL 0x22
-#define DA9030_LED4_CONTROL 0x23
-#define DA9030_LEDPC_CONTROL 0x24
-#define DA9030_MISC_CONTROL_A 0x26 /* Vibrator Control */
-
-#define DA9034_LED1_CONTROL 0x35
-#define DA9034_LED2_CONTROL 0x36
-#define DA9034_VIBRA 0x40
-
-struct da903x_led {
- struct led_classdev cdev;
- struct device *master;
- int id;
- int flags;
-};
-
-#define DA9030_LED_OFFSET(id) ((id) - DA9030_ID_LED_1)
-#define DA9034_LED_OFFSET(id) ((id) - DA9034_ID_LED_1)
-
-static int da903x_led_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct da903x_led *led =
- container_of(led_cdev, struct da903x_led, cdev);
- uint8_t val;
- int offset, ret = -EINVAL;
-
- switch (led->id) {
- case DA9030_ID_LED_1:
- case DA9030_ID_LED_2:
- case DA9030_ID_LED_3:
- case DA9030_ID_LED_4:
- case DA9030_ID_LED_PC:
- offset = DA9030_LED_OFFSET(led->id);
- val = led->flags & ~0x87;
- val |= value ? 0x80 : 0; /* EN bit */
- val |= (0x7 - (value >> 5)) & 0x7; /* PWM<2:0> */
- ret = da903x_write(led->master, DA9030_LED1_CONTROL + offset,
- val);
- break;
- case DA9030_ID_VIBRA:
- val = led->flags & ~0x80;
- val |= value ? 0x80 : 0; /* EN bit */
- ret = da903x_write(led->master, DA9030_MISC_CONTROL_A, val);
- break;
- case DA9034_ID_LED_1:
- case DA9034_ID_LED_2:
- offset = DA9034_LED_OFFSET(led->id);
- val = (value * 0x5f / LED_FULL) & 0x7f;
- val |= (led->flags & DA9034_LED_RAMP) ? 0x80 : 0;
- ret = da903x_write(led->master, DA9034_LED1_CONTROL + offset,
- val);
- break;
- case DA9034_ID_VIBRA:
- val = value & 0xfe;
- ret = da903x_write(led->master, DA9034_VIBRA, val);
- break;
- }
-
- return ret;
-}
-
-static int da903x_led_probe(struct platform_device *pdev)
-{
- struct led_info *pdata = dev_get_platdata(&pdev->dev);
- struct da903x_led *led;
- int id, ret;
-
- if (pdata == NULL)
- return 0;
-
- id = pdev->id;
-
- if (!((id >= DA9030_ID_LED_1 && id <= DA9030_ID_VIBRA) ||
- (id >= DA9034_ID_LED_1 && id <= DA9034_ID_VIBRA))) {
- dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", id);
- return -EINVAL;
- }
-
- led = devm_kzalloc(&pdev->dev, sizeof(struct da903x_led), GFP_KERNEL);
- if (!led)
- return -ENOMEM;
-
- led->cdev.name = pdata->name;
- led->cdev.default_trigger = pdata->default_trigger;
- led->cdev.brightness_set_blocking = da903x_led_set;
- led->cdev.brightness = LED_OFF;
-
- led->id = id;
- led->flags = pdata->flags;
- led->master = pdev->dev.parent;
-
- ret = led_classdev_register(led->master, &led->cdev);
- if (ret) {
- dev_err(&pdev->dev, "failed to register LED %d\n", id);
- return ret;
- }
-
- platform_set_drvdata(pdev, led);
-
- return 0;
-}
-
-static void da903x_led_remove(struct platform_device *pdev)
-{
- struct da903x_led *led = platform_get_drvdata(pdev);
-
- led_classdev_unregister(&led->cdev);
-}
-
-static struct platform_driver da903x_led_driver = {
- .driver = {
- .name = "da903x-led",
- },
- .probe = da903x_led_probe,
- .remove = da903x_led_remove,
-};
-
-module_platform_driver(da903x_led_driver);
-
-MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
-MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:da903x-led");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 5126bae8e61f..fda9d7ad5743 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -408,17 +408,6 @@ config MFD_TN48M_CPLD
for the SFP slots as well as power supply related information.
SFP support depends on the GPIO driver being selected.
-config PMIC_DA903X
- bool "Dialog Semiconductor DA9030/DA9034 PMIC Support"
- depends on I2C=y
- help
- Say yes here to add support for Dialog Semiconductor DA9030 (a.k.a
- ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC
- usually found on PXA processors-based platforms. This includes
- the I2C driver and the core APIs _only_, you have to select
- individual components like LCD backlight, voltage regulators,
- LEDs and battery-charger under the corresponding menus.
-
config PMIC_DA9052
bool
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a6cc4fcc3e1d..82795e65cbe7 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -139,8 +139,6 @@ ifeq ($(CONFIG_SA1100_ASSABET),y)
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
endif
-obj-$(CONFIG_PMIC_DA903X) += da903x.o
-
obj-$(CONFIG_PMIC_DA9052) += da9052-irq.o
obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
deleted file mode 100644
index e86b39de3303..000000000000
--- a/drivers/mfd/da903x.c
+++ /dev/null
@@ -1,565 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Base driver for Dialog Semiconductor DA9030/DA9034
- *
- * Copyright (C) 2008 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
- *
- * Copyright (C) 2006-2008 Marvell International Ltd.
- * Eric Miao <eric.miao@marvell.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/mfd/da903x.h>
-#include <linux/slab.h>
-
-#define DA9030_CHIP_ID 0x00
-#define DA9030_EVENT_A 0x01
-#define DA9030_EVENT_B 0x02
-#define DA9030_EVENT_C 0x03
-#define DA9030_STATUS 0x04
-#define DA9030_IRQ_MASK_A 0x05
-#define DA9030_IRQ_MASK_B 0x06
-#define DA9030_IRQ_MASK_C 0x07
-#define DA9030_SYS_CTRL_A 0x08
-#define DA9030_SYS_CTRL_B 0x09
-#define DA9030_FAULT_LOG 0x0a
-
-#define DA9034_CHIP_ID 0x00
-#define DA9034_EVENT_A 0x01
-#define DA9034_EVENT_B 0x02
-#define DA9034_EVENT_C 0x03
-#define DA9034_EVENT_D 0x04
-#define DA9034_STATUS_A 0x05
-#define DA9034_STATUS_B 0x06
-#define DA9034_IRQ_MASK_A 0x07
-#define DA9034_IRQ_MASK_B 0x08
-#define DA9034_IRQ_MASK_C 0x09
-#define DA9034_IRQ_MASK_D 0x0a
-#define DA9034_SYS_CTRL_A 0x0b
-#define DA9034_SYS_CTRL_B 0x0c
-#define DA9034_FAULT_LOG 0x0d
-
-struct da903x_chip;
-
-struct da903x_chip_ops {
- int (*init_chip)(struct da903x_chip *);
- int (*unmask_events)(struct da903x_chip *, unsigned int events);
- int (*mask_events)(struct da903x_chip *, unsigned int events);
- int (*read_events)(struct da903x_chip *, unsigned int *events);
- int (*read_status)(struct da903x_chip *, unsigned int *status);
-};
-
-struct da903x_chip {
- struct i2c_client *client;
- struct device *dev;
- const struct da903x_chip_ops *ops;
-
- int type;
- uint32_t events_mask;
-
- struct mutex lock;
- struct work_struct irq_work;
-
- struct blocking_notifier_head notifier_list;
-};
-
-static inline int __da903x_read(struct i2c_client *client,
- int reg, uint8_t *val)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
- return ret;
- }
-
- *val = (uint8_t)ret;
- return 0;
-}
-
-static inline int __da903x_reads(struct i2c_client *client, int reg,
- int len, uint8_t *val)
-{
- int ret;
-
- ret = i2c_smbus_read_i2c_block_data(client, reg, len, val);
- if (ret < 0) {
- dev_err(&client->dev, "failed reading from 0x%02x\n", reg);
- return ret;
- }
- return 0;
-}
-
-static inline int __da903x_write(struct i2c_client *client,
- int reg, uint8_t val)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, reg, val);
- if (ret < 0) {
- dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
- val, reg);
- return ret;
- }
- return 0;
-}
-
-static inline int __da903x_writes(struct i2c_client *client, int reg,
- int len, uint8_t *val)
-{
- int ret;
-
- ret = i2c_smbus_write_i2c_block_data(client, reg, len, val);
- if (ret < 0) {
- dev_err(&client->dev, "failed writings to 0x%02x\n", reg);
- return ret;
- }
- return 0;
-}
-
-int da903x_register_notifier(struct device *dev, struct notifier_block *nb,
- unsigned int events)
-{
- struct da903x_chip *chip = dev_get_drvdata(dev);
-
- chip->ops->unmask_events(chip, events);
- return blocking_notifier_chain_register(&chip->notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(da903x_register_notifier);
-
-int da903x_unregister_notifier(struct device *dev, struct notifier_block *nb,
- unsigned int events)
-{
- struct da903x_chip *chip = dev_get_drvdata(dev);
-
- chip->ops->mask_events(chip, events);
- return blocking_notifier_chain_unregister(&chip->notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(da903x_unregister_notifier);
-
-int da903x_write(struct device *dev, int reg, uint8_t val)
-{
- return __da903x_write(to_i2c_client(dev), reg, val);
-}
-EXPORT_SYMBOL_GPL(da903x_write);
-
-int da903x_writes(struct device *dev, int reg, int len, uint8_t *val)
-{
- return __da903x_writes(to_i2c_client(dev), reg, len, val);
-}
-EXPORT_SYMBOL_GPL(da903x_writes);
-
-int da903x_read(struct device *dev, int reg, uint8_t *val)
-{
- return __da903x_read(to_i2c_client(dev), reg, val);
-}
-EXPORT_SYMBOL_GPL(da903x_read);
-
-int da903x_reads(struct device *dev, int reg, int len, uint8_t *val)
-{
- return __da903x_reads(to_i2c_client(dev), reg, len, val);
-}
-EXPORT_SYMBOL_GPL(da903x_reads);
-
-int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
-{
- struct da903x_chip *chip = dev_get_drvdata(dev);
- uint8_t reg_val;
- int ret = 0;
-
- mutex_lock(&chip->lock);
-
- ret = __da903x_read(chip->client, reg, ®_val);
- if (ret)
- goto out;
-
- if ((reg_val & bit_mask) != bit_mask) {
- reg_val |= bit_mask;
- ret = __da903x_write(chip->client, reg, reg_val);
- }
-out:
- mutex_unlock(&chip->lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(da903x_set_bits);
-
-int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
-{
- struct da903x_chip *chip = dev_get_drvdata(dev);
- uint8_t reg_val;
- int ret = 0;
-
- mutex_lock(&chip->lock);
-
- ret = __da903x_read(chip->client, reg, ®_val);
- if (ret)
- goto out;
-
- if (reg_val & bit_mask) {
- reg_val &= ~bit_mask;
- ret = __da903x_write(chip->client, reg, reg_val);
- }
-out:
- mutex_unlock(&chip->lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(da903x_clr_bits);
-
-int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
-{
- struct da903x_chip *chip = dev_get_drvdata(dev);
- uint8_t reg_val;
- int ret = 0;
-
- mutex_lock(&chip->lock);
-
- ret = __da903x_read(chip->client, reg, ®_val);
- if (ret)
- goto out;
-
- if ((reg_val & mask) != val) {
- reg_val = (reg_val & ~mask) | val;
- ret = __da903x_write(chip->client, reg, reg_val);
- }
-out:
- mutex_unlock(&chip->lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(da903x_update);
-
-int da903x_query_status(struct device *dev, unsigned int sbits)
-{
- struct da903x_chip *chip = dev_get_drvdata(dev);
- unsigned int status = 0;
-
- chip->ops->read_status(chip, &status);
- return ((status & sbits) == sbits);
-}
-EXPORT_SYMBOL(da903x_query_status);
-
-static int da9030_init_chip(struct da903x_chip *chip)
-{
- uint8_t chip_id;
- int err;
-
- err = __da903x_read(chip->client, DA9030_CHIP_ID, &chip_id);
- if (err)
- return err;
-
- err = __da903x_write(chip->client, DA9030_SYS_CTRL_A, 0xE8);
- if (err)
- return err;
-
- dev_info(chip->dev, "DA9030 (CHIP ID: 0x%02x) detected\n", chip_id);
- return 0;
-}
-
-static int da9030_unmask_events(struct da903x_chip *chip, unsigned int events)
-{
- uint8_t v[3];
-
- chip->events_mask &= ~events;
-
- v[0] = (chip->events_mask & 0xff);
- v[1] = (chip->events_mask >> 8) & 0xff;
- v[2] = (chip->events_mask >> 16) & 0xff;
-
- return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
-}
-
-static int da9030_mask_events(struct da903x_chip *chip, unsigned int events)
-{
- uint8_t v[3];
-
- chip->events_mask |= events;
-
- v[0] = (chip->events_mask & 0xff);
- v[1] = (chip->events_mask >> 8) & 0xff;
- v[2] = (chip->events_mask >> 16) & 0xff;
-
- return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
-}
-
-static int da9030_read_events(struct da903x_chip *chip, unsigned int *events)
-{
- uint8_t v[3] = {0, 0, 0};
- int ret;
-
- ret = __da903x_reads(chip->client, DA9030_EVENT_A, 3, v);
- if (ret < 0)
- return ret;
-
- *events = (v[2] << 16) | (v[1] << 8) | v[0];
- return 0;
-}
-
-static int da9030_read_status(struct da903x_chip *chip, unsigned int *status)
-{
- return __da903x_read(chip->client, DA9030_STATUS, (uint8_t *)status);
-}
-
-static int da9034_init_chip(struct da903x_chip *chip)
-{
- uint8_t chip_id;
- int err;
-
- err = __da903x_read(chip->client, DA9034_CHIP_ID, &chip_id);
- if (err)
- return err;
-
- err = __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0xE8);
- if (err)
- return err;
-
- /* avoid SRAM power off during sleep*/
- __da903x_write(chip->client, 0x10, 0x07);
- __da903x_write(chip->client, 0x11, 0xff);
- __da903x_write(chip->client, 0x12, 0xff);
-
- /* Enable the ONKEY power down functionality */
- __da903x_write(chip->client, DA9034_SYS_CTRL_B, 0x20);
- __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0x60);
-
- /* workaround to make LEDs work */
- __da903x_write(chip->client, 0x90, 0x01);
- __da903x_write(chip->client, 0xB0, 0x08);
-
- /* make ADTV1 and SDTV1 effective */
- __da903x_write(chip->client, 0x20, 0x00);
-
- dev_info(chip->dev, "DA9034 (CHIP ID: 0x%02x) detected\n", chip_id);
- return 0;
-}
-
-static int da9034_unmask_events(struct da903x_chip *chip, unsigned int events)
-{
- uint8_t v[4];
-
- chip->events_mask &= ~events;
-
- v[0] = (chip->events_mask & 0xff);
- v[1] = (chip->events_mask >> 8) & 0xff;
- v[2] = (chip->events_mask >> 16) & 0xff;
- v[3] = (chip->events_mask >> 24) & 0xff;
-
- return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
-}
-
-static int da9034_mask_events(struct da903x_chip *chip, unsigned int events)
-{
- uint8_t v[4];
-
- chip->events_mask |= events;
-
- v[0] = (chip->events_mask & 0xff);
- v[1] = (chip->events_mask >> 8) & 0xff;
- v[2] = (chip->events_mask >> 16) & 0xff;
- v[3] = (chip->events_mask >> 24) & 0xff;
-
- return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
-}
-
-static int da9034_read_events(struct da903x_chip *chip, unsigned int *events)
-{
- uint8_t v[4] = {0, 0, 0, 0};
- int ret;
-
- ret = __da903x_reads(chip->client, DA9034_EVENT_A, 4, v);
- if (ret < 0)
- return ret;
-
- *events = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0];
- return 0;
-}
-
-static int da9034_read_status(struct da903x_chip *chip, unsigned int *status)
-{
- uint8_t v[2] = {0, 0};
- int ret = 0;
-
- ret = __da903x_reads(chip->client, DA9034_STATUS_A, 2, v);
- if (ret)
- return ret;
-
- *status = (v[1] << 8) | v[0];
- return 0;
-}
-
-static void da903x_irq_work(struct work_struct *work)
-{
- struct da903x_chip *chip =
- container_of(work, struct da903x_chip, irq_work);
- unsigned int events = 0;
-
- while (1) {
- if (chip->ops->read_events(chip, &events))
- break;
-
- events &= ~chip->events_mask;
- if (events == 0)
- break;
-
- blocking_notifier_call_chain(
- &chip->notifier_list, events, NULL);
- }
- enable_irq(chip->client->irq);
-}
-
-static irqreturn_t da903x_irq_handler(int irq, void *data)
-{
- struct da903x_chip *chip = data;
-
- disable_irq_nosync(irq);
- (void)schedule_work(&chip->irq_work);
-
- return IRQ_HANDLED;
-}
-
-static const struct da903x_chip_ops da903x_ops[] = {
- [0] = {
- .init_chip = da9030_init_chip,
- .unmask_events = da9030_unmask_events,
- .mask_events = da9030_mask_events,
- .read_events = da9030_read_events,
- .read_status = da9030_read_status,
- },
- [1] = {
- .init_chip = da9034_init_chip,
- .unmask_events = da9034_unmask_events,
- .mask_events = da9034_mask_events,
- .read_events = da9034_read_events,
- .read_status = da9034_read_status,
- }
-};
-
-static const struct i2c_device_id da903x_id_table[] = {
- { "da9030", 0 },
- { "da9034", 1 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, da903x_id_table);
-
-static int __remove_subdev(struct device *dev, void *unused)
-{
- platform_device_unregister(to_platform_device(dev));
- return 0;
-}
-
-static int da903x_remove_subdevs(struct da903x_chip *chip)
-{
- return device_for_each_child(chip->dev, NULL, __remove_subdev);
-}
-
-static int da903x_add_subdevs(struct da903x_chip *chip,
- struct da903x_platform_data *pdata)
-{
- struct da903x_subdev_info *subdev;
- struct platform_device *pdev;
- int i, ret = 0;
-
- for (i = 0; i < pdata->num_subdevs; i++) {
- subdev = &pdata->subdevs[i];
-
- pdev = platform_device_alloc(subdev->name, subdev->id);
- if (!pdev) {
- ret = -ENOMEM;
- goto failed;
- }
-
- pdev->dev.parent = chip->dev;
- pdev->dev.platform_data = subdev->platform_data;
-
- ret = platform_device_add(pdev);
- if (ret) {
- platform_device_put(pdev);
- goto failed;
- }
- }
- return 0;
-
-failed:
- da903x_remove_subdevs(chip);
- return ret;
-}
-
-static int da903x_probe(struct i2c_client *client)
-{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
- struct da903x_platform_data *pdata = dev_get_platdata(&client->dev);
- struct da903x_chip *chip;
- unsigned int tmp;
- int ret;
-
- chip = devm_kzalloc(&client->dev, sizeof(struct da903x_chip),
- GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- chip->client = client;
- chip->dev = &client->dev;
- chip->ops = &da903x_ops[id->driver_data];
-
- mutex_init(&chip->lock);
- INIT_WORK(&chip->irq_work, da903x_irq_work);
- BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);
-
- i2c_set_clientdata(client, chip);
-
- ret = chip->ops->init_chip(chip);
- if (ret)
- return ret;
-
- /* mask and clear all IRQs */
- chip->events_mask = 0xffffffff;
- chip->ops->mask_events(chip, chip->events_mask);
- chip->ops->read_events(chip, &tmp);
-
- ret = devm_request_irq(&client->dev, client->irq, da903x_irq_handler,
- IRQF_TRIGGER_FALLING,
- "da903x", chip);
- if (ret) {
- dev_err(&client->dev, "failed to request irq %d\n",
- client->irq);
- return ret;
- }
-
- return da903x_add_subdevs(chip, pdata);
-}
-
-static void da903x_remove(struct i2c_client *client)
-{
- struct da903x_chip *chip = i2c_get_clientdata(client);
-
- da903x_remove_subdevs(chip);
-}
-
-static struct i2c_driver da903x_driver = {
- .driver = {
- .name = "da903x",
- },
- .probe = da903x_probe,
- .remove = da903x_remove,
- .id_table = da903x_id_table,
-};
-
-static int __init da903x_init(void)
-{
- return i2c_add_driver(&da903x_driver);
-}
-subsys_initcall(da903x_init);
-
-static void __exit da903x_exit(void)
-{
- i2c_del_driver(&da903x_driver);
-}
-module_exit(da903x_exit);
-
-MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
-MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index b89ef40df7f8..a492c86e879a 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -345,13 +345,6 @@ config BATTERY_BQ27XXX_DT_UPDATES_NVM
general-purpose kernels, as this can cause misconfiguration of a
smart battery with embedded NVM/flash.
-config BATTERY_DA9030
- tristate "DA9030 battery driver"
- depends on PMIC_DA903X
- help
- Say Y here to enable support for batteries charger integrated into
- DA9030 PMIC.
-
config BATTERY_DA9052
tristate "Dialog DA9052 Battery"
depends on PMIC_DA9052
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index f3c0d1006c1a..380546080112 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -52,7 +52,6 @@ obj-$(CONFIG_MANAGER_SBS) += sbs-manager.o
obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_battery.o
obj-$(CONFIG_BATTERY_BQ27XXX_I2C) += bq27xxx_battery_i2c.o
obj-$(CONFIG_BATTERY_BQ27XXX_HDQ) += bq27xxx_battery_hdq.o
-obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o
obj-$(CONFIG_BATTERY_DA9150) += da9150-fg.o
diff --git a/drivers/power/supply/da9030_battery.c b/drivers/power/supply/da9030_battery.c
deleted file mode 100644
index d25279c26030..000000000000
--- a/drivers/power/supply/da9030_battery.c
+++ /dev/null
@@ -1,581 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Battery charger driver for Dialog Semiconductor DA9030
- *
- * Copyright (C) 2008 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/workqueue.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/power_supply.h>
-#include <linux/string_choices.h>
-#include <linux/mfd/da903x.h>
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/notifier.h>
-
-#define DA9030_FAULT_LOG 0x0a
-#define DA9030_FAULT_LOG_OVER_TEMP (1 << 7)
-#define DA9030_FAULT_LOG_VBAT_OVER (1 << 4)
-
-#define DA9030_CHARGE_CONTROL 0x28
-#define DA9030_CHRG_CHARGER_ENABLE (1 << 7)
-
-#define DA9030_ADC_MAN_CONTROL 0x30
-#define DA9030_ADC_TBATREF_ENABLE (1 << 5)
-#define DA9030_ADC_LDO_INT_ENABLE (1 << 4)
-
-#define DA9030_ADC_AUTO_CONTROL 0x31
-#define DA9030_ADC_TBAT_ENABLE (1 << 5)
-#define DA9030_ADC_VBAT_IN_TXON (1 << 4)
-#define DA9030_ADC_VCH_ENABLE (1 << 3)
-#define DA9030_ADC_ICH_ENABLE (1 << 2)
-#define DA9030_ADC_VBAT_ENABLE (1 << 1)
-#define DA9030_ADC_AUTO_SLEEP_ENABLE (1 << 0)
-
-#define DA9030_VBATMON 0x32
-#define DA9030_VBATMONTXON 0x33
-#define DA9030_TBATHIGHP 0x34
-#define DA9030_TBATHIGHN 0x35
-#define DA9030_TBATLOW 0x36
-
-#define DA9030_VBAT_RES 0x41
-#define DA9030_VBATMIN_RES 0x42
-#define DA9030_VBATMINTXON_RES 0x43
-#define DA9030_ICHMAX_RES 0x44
-#define DA9030_ICHMIN_RES 0x45
-#define DA9030_ICHAVERAGE_RES 0x46
-#define DA9030_VCHMAX_RES 0x47
-#define DA9030_VCHMIN_RES 0x48
-#define DA9030_TBAT_RES 0x49
-
-struct da9030_adc_res {
- uint8_t vbat_res;
- uint8_t vbatmin_res;
- uint8_t vbatmintxon;
- uint8_t ichmax_res;
- uint8_t ichmin_res;
- uint8_t ichaverage_res;
- uint8_t vchmax_res;
- uint8_t vchmin_res;
- uint8_t tbat_res;
- uint8_t adc_in4_res;
- uint8_t adc_in5_res;
-};
-
-struct da9030_battery_thresholds {
- int tbat_low;
- int tbat_high;
- int tbat_restart;
-
- int vbat_low;
- int vbat_crit;
- int vbat_charge_start;
- int vbat_charge_stop;
- int vbat_charge_restart;
-
- int vcharge_min;
- int vcharge_max;
-};
-
-struct da9030_charger {
- struct power_supply *psy;
- struct power_supply_desc psy_desc;
-
- struct device *master;
-
- struct da9030_adc_res adc;
- struct delayed_work work;
- unsigned int interval;
-
- struct power_supply_info *battery_info;
-
- struct da9030_battery_thresholds thresholds;
-
- unsigned int charge_milliamp;
- unsigned int charge_millivolt;
-
- /* charger status */
- bool chdet;
- uint8_t fault;
- int mA;
- int mV;
- bool is_on;
-
- struct notifier_block nb;
-
- /* platform callbacks for battery low and critical events */
- void (*battery_low)(void);
- void (*battery_critical)(void);
-
- struct dentry *debug_file;
-};
-
-static inline int da9030_reg_to_mV(int reg)
-{
- return ((reg * 2650) >> 8) + 2650;
-}
-
-static inline int da9030_millivolt_to_reg(int mV)
-{
- return ((mV - 2650) << 8) / 2650;
-}
-
-static inline int da9030_reg_to_mA(int reg)
-{
- return ((reg * 24000) >> 8) / 15;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static int bat_debug_show(struct seq_file *s, void *data)
-{
- struct da9030_charger *charger = s->private;
-
- seq_printf(s, "charger is %s\n", str_on_off(charger->is_on));
- if (charger->chdet) {
- seq_printf(s, "iset = %dmA, vset = %dmV\n",
- charger->mA, charger->mV);
- }
-
- seq_printf(s, "vbat_res = %d (%dmV)\n",
- charger->adc.vbat_res,
- da9030_reg_to_mV(charger->adc.vbat_res));
- seq_printf(s, "vbatmin_res = %d (%dmV)\n",
- charger->adc.vbatmin_res,
- da9030_reg_to_mV(charger->adc.vbatmin_res));
- seq_printf(s, "vbatmintxon = %d (%dmV)\n",
- charger->adc.vbatmintxon,
- da9030_reg_to_mV(charger->adc.vbatmintxon));
- seq_printf(s, "ichmax_res = %d (%dmA)\n",
- charger->adc.ichmax_res,
- da9030_reg_to_mV(charger->adc.ichmax_res));
- seq_printf(s, "ichmin_res = %d (%dmA)\n",
- charger->adc.ichmin_res,
- da9030_reg_to_mA(charger->adc.ichmin_res));
- seq_printf(s, "ichaverage_res = %d (%dmA)\n",
- charger->adc.ichaverage_res,
- da9030_reg_to_mA(charger->adc.ichaverage_res));
- seq_printf(s, "vchmax_res = %d (%dmV)\n",
- charger->adc.vchmax_res,
- da9030_reg_to_mA(charger->adc.vchmax_res));
- seq_printf(s, "vchmin_res = %d (%dmV)\n",
- charger->adc.vchmin_res,
- da9030_reg_to_mV(charger->adc.vchmin_res));
-
- return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(bat_debug);
-
-static struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger)
-{
- charger->debug_file = debugfs_create_file("charger", 0666, NULL,
- charger, &bat_debug_fops);
- return charger->debug_file;
-}
-
-static void da9030_bat_remove_debugfs(struct da9030_charger *charger)
-{
- debugfs_remove(charger->debug_file);
-}
-#else
-static inline struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger)
-{
- return NULL;
-}
-static inline void da9030_bat_remove_debugfs(struct da9030_charger *charger)
-{
-}
-#endif
-
-static inline void da9030_read_adc(struct da9030_charger *charger,
- struct da9030_adc_res *adc)
-{
- da903x_reads(charger->master, DA9030_VBAT_RES,
- sizeof(*adc), (uint8_t *)adc);
-}
-
-static void da9030_charger_update_state(struct da9030_charger *charger)
-{
- uint8_t val;
-
- da903x_read(charger->master, DA9030_CHARGE_CONTROL, &val);
- charger->is_on = (val & DA9030_CHRG_CHARGER_ENABLE) ? 1 : 0;
- charger->mA = ((val >> 3) & 0xf) * 100;
- charger->mV = (val & 0x7) * 50 + 4000;
-
- da9030_read_adc(charger, &charger->adc);
- da903x_read(charger->master, DA9030_FAULT_LOG, &charger->fault);
- charger->chdet = da903x_query_status(charger->master,
- DA9030_STATUS_CHDET);
-}
-
-static void da9030_set_charge(struct da9030_charger *charger, int on)
-{
- uint8_t val;
-
- if (on) {
- val = DA9030_CHRG_CHARGER_ENABLE;
- val |= (charger->charge_milliamp / 100) << 3;
- val |= (charger->charge_millivolt - 4000) / 50;
- charger->is_on = 1;
- } else {
- val = 0;
- charger->is_on = 0;
- }
-
- da903x_write(charger->master, DA9030_CHARGE_CONTROL, val);
-
- power_supply_changed(charger->psy);
-}
-
-static void da9030_charger_check_state(struct da9030_charger *charger)
-{
- da9030_charger_update_state(charger);
-
- /* we wake or boot with external power on */
- if (!charger->is_on) {
- if ((charger->chdet) &&
- (charger->adc.vbat_res <
- charger->thresholds.vbat_charge_start)) {
- da9030_set_charge(charger, 1);
- }
- } else {
- /* Charger has been pulled out */
- if (!charger->chdet) {
- da9030_set_charge(charger, 0);
- return;
- }
-
- if (charger->adc.vbat_res >=
- charger->thresholds.vbat_charge_stop) {
- da9030_set_charge(charger, 0);
- da903x_write(charger->master, DA9030_VBATMON,
- charger->thresholds.vbat_charge_restart);
- } else if (charger->adc.vbat_res >
- charger->thresholds.vbat_low) {
- /* we are charging and passed LOW_THRESH,
- so upate DA9030 VBAT threshold
- */
- da903x_write(charger->master, DA9030_VBATMON,
- charger->thresholds.vbat_low);
- }
- if (charger->adc.vchmax_res > charger->thresholds.vcharge_max ||
- charger->adc.vchmin_res < charger->thresholds.vcharge_min ||
- /* Temperature readings are negative */
- charger->adc.tbat_res < charger->thresholds.tbat_high ||
- charger->adc.tbat_res > charger->thresholds.tbat_low) {
- /* disable charger */
- da9030_set_charge(charger, 0);
- }
- }
-}
-
-static void da9030_charging_monitor(struct work_struct *work)
-{
- struct da9030_charger *charger;
-
- charger = container_of(work, struct da9030_charger, work.work);
-
- da9030_charger_check_state(charger);
-
- /* reschedule for the next time */
- schedule_delayed_work(&charger->work, charger->interval);
-}
-
-static enum power_supply_property da9030_battery_props[] = {
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_AVG,
-};
-
-static void da9030_battery_check_status(struct da9030_charger *charger,
- union power_supply_propval *val)
-{
- if (charger->chdet) {
- if (charger->is_on)
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else
- val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
- } else {
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- }
-}
-
-static void da9030_battery_check_health(struct da9030_charger *charger,
- union power_supply_propval *val)
-{
- if (charger->fault & DA9030_FAULT_LOG_OVER_TEMP)
- val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
- else if (charger->fault & DA9030_FAULT_LOG_VBAT_OVER)
- val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
- else
- val->intval = POWER_SUPPLY_HEALTH_GOOD;
-}
-
-static int da9030_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct da9030_charger *charger = power_supply_get_drvdata(psy);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- da9030_battery_check_status(charger, val);
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- da9030_battery_check_health(charger, val);
- break;
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- val->intval = charger->battery_info->technology;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- val->intval = charger->battery_info->voltage_max_design;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- val->intval = charger->battery_info->voltage_min_design;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = da9030_reg_to_mV(charger->adc.vbat_res) * 1000;
- break;
- case POWER_SUPPLY_PROP_CURRENT_AVG:
- val->intval =
- da9030_reg_to_mA(charger->adc.ichaverage_res) * 1000;
- break;
- case POWER_SUPPLY_PROP_MODEL_NAME:
- val->strval = charger->battery_info->name;
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static void da9030_battery_vbat_event(struct da9030_charger *charger)
-{
- da9030_read_adc(charger, &charger->adc);
-
- if (charger->is_on)
- return;
-
- if (charger->adc.vbat_res < charger->thresholds.vbat_low) {
- /* set VBAT threshold for critical */
- da903x_write(charger->master, DA9030_VBATMON,
- charger->thresholds.vbat_crit);
- if (charger->battery_low)
- charger->battery_low();
- } else if (charger->adc.vbat_res <
- charger->thresholds.vbat_crit) {
- /* notify the system of battery critical */
- if (charger->battery_critical)
- charger->battery_critical();
- }
-}
-
-static int da9030_battery_event(struct notifier_block *nb, unsigned long event,
- void *data)
-{
- struct da9030_charger *charger =
- container_of(nb, struct da9030_charger, nb);
-
- switch (event) {
- case DA9030_EVENT_CHDET:
- cancel_delayed_work_sync(&charger->work);
- schedule_work(&charger->work.work);
- break;
- case DA9030_EVENT_VBATMON:
- da9030_battery_vbat_event(charger);
- break;
- case DA9030_EVENT_CHIOVER:
- case DA9030_EVENT_TBAT:
- da9030_set_charge(charger, 0);
- break;
- }
-
- return 0;
-}
-
-static void da9030_battery_convert_thresholds(struct da9030_charger *charger,
- struct da9030_battery_info *pdata)
-{
- charger->thresholds.tbat_low = pdata->tbat_low;
- charger->thresholds.tbat_high = pdata->tbat_high;
- charger->thresholds.tbat_restart = pdata->tbat_restart;
-
- charger->thresholds.vbat_low =
- da9030_millivolt_to_reg(pdata->vbat_low);
- charger->thresholds.vbat_crit =
- da9030_millivolt_to_reg(pdata->vbat_crit);
- charger->thresholds.vbat_charge_start =
- da9030_millivolt_to_reg(pdata->vbat_charge_start);
- charger->thresholds.vbat_charge_stop =
- da9030_millivolt_to_reg(pdata->vbat_charge_stop);
- charger->thresholds.vbat_charge_restart =
- da9030_millivolt_to_reg(pdata->vbat_charge_restart);
-
- charger->thresholds.vcharge_min =
- da9030_millivolt_to_reg(pdata->vcharge_min);
- charger->thresholds.vcharge_max =
- da9030_millivolt_to_reg(pdata->vcharge_max);
-}
-
-static void da9030_battery_setup_psy(struct da9030_charger *charger)
-{
- struct power_supply_desc *psy_desc = &charger->psy_desc;
- struct power_supply_info *info = charger->battery_info;
-
- psy_desc->name = info->name;
- psy_desc->use_for_apm = info->use_for_apm;
- psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
- psy_desc->get_property = da9030_battery_get_property;
-
- psy_desc->properties = da9030_battery_props;
- psy_desc->num_properties = ARRAY_SIZE(da9030_battery_props);
-};
-
-static int da9030_battery_charger_init(struct da9030_charger *charger)
-{
- char v[5];
- int ret;
-
- v[0] = v[1] = charger->thresholds.vbat_low;
- v[2] = charger->thresholds.tbat_high;
- v[3] = charger->thresholds.tbat_restart;
- v[4] = charger->thresholds.tbat_low;
-
- ret = da903x_writes(charger->master, DA9030_VBATMON, 5, v);
- if (ret)
- return ret;
-
- /*
- * Enable reference voltage supply for ADC from the LDO_INTERNAL
- * regulator. Must be set before ADC measurements can be made.
- */
- ret = da903x_write(charger->master, DA9030_ADC_MAN_CONTROL,
- DA9030_ADC_LDO_INT_ENABLE |
- DA9030_ADC_TBATREF_ENABLE);
- if (ret)
- return ret;
-
- /* enable auto ADC measurements */
- return da903x_write(charger->master, DA9030_ADC_AUTO_CONTROL,
- DA9030_ADC_TBAT_ENABLE | DA9030_ADC_VBAT_IN_TXON |
- DA9030_ADC_VCH_ENABLE | DA9030_ADC_ICH_ENABLE |
- DA9030_ADC_VBAT_ENABLE |
- DA9030_ADC_AUTO_SLEEP_ENABLE);
-}
-
-static int da9030_battery_probe(struct platform_device *pdev)
-{
- struct da9030_charger *charger;
- struct power_supply_config psy_cfg = {};
- struct da9030_battery_info *pdata = pdev->dev.platform_data;
- int ret;
-
- if (pdata == NULL)
- return -EINVAL;
-
- if (pdata->charge_milliamp >= 1500 ||
- pdata->charge_millivolt < 4000 ||
- pdata->charge_millivolt > 4350)
- return -EINVAL;
-
- charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
- if (charger == NULL)
- return -ENOMEM;
-
- charger->master = pdev->dev.parent;
-
- /* 10 seconds between monitor runs unless platform defines other
- interval */
- charger->interval = secs_to_jiffies(pdata->batmon_interval ? : 10);
-
- charger->charge_milliamp = pdata->charge_milliamp;
- charger->charge_millivolt = pdata->charge_millivolt;
- charger->battery_info = pdata->battery_info;
- charger->battery_low = pdata->battery_low;
- charger->battery_critical = pdata->battery_critical;
-
- da9030_battery_convert_thresholds(charger, pdata);
-
- ret = da9030_battery_charger_init(charger);
- if (ret)
- goto err_charger_init;
-
- INIT_DELAYED_WORK(&charger->work, da9030_charging_monitor);
- schedule_delayed_work(&charger->work, charger->interval);
-
- charger->nb.notifier_call = da9030_battery_event;
- ret = da903x_register_notifier(charger->master, &charger->nb,
- DA9030_EVENT_CHDET |
- DA9030_EVENT_VBATMON |
- DA9030_EVENT_CHIOVER |
- DA9030_EVENT_TBAT);
- if (ret)
- goto err_notifier;
-
- da9030_battery_setup_psy(charger);
- psy_cfg.drv_data = charger;
- charger->psy = devm_power_supply_register(&pdev->dev,
- &charger->psy_desc,
- &psy_cfg);
- if (IS_ERR(charger->psy)) {
- ret = PTR_ERR(charger->psy);
- goto err_ps_register;
- }
-
- charger->debug_file = da9030_bat_create_debugfs(charger);
- platform_set_drvdata(pdev, charger);
- return 0;
-
-err_ps_register:
- da903x_unregister_notifier(charger->master, &charger->nb,
- DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
- DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
-err_notifier:
- cancel_delayed_work(&charger->work);
-
-err_charger_init:
- return ret;
-}
-
-static void da9030_battery_remove(struct platform_device *dev)
-{
- struct da9030_charger *charger = platform_get_drvdata(dev);
-
- da9030_bat_remove_debugfs(charger);
-
- da903x_unregister_notifier(charger->master, &charger->nb,
- DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
- DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
- cancel_delayed_work_sync(&charger->work);
- da9030_set_charge(charger, 0);
-}
-
-static struct platform_driver da903x_battery_driver = {
- .driver = {
- .name = "da903x-battery",
- },
- .probe = da9030_battery_probe,
- .remove = da9030_battery_remove,
-};
-
-module_platform_driver(da903x_battery_driver);
-
-MODULE_DESCRIPTION("DA9030 battery charger driver");
-MODULE_AUTHOR("Mike Rapoport, CompuLab");
-MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 4869a1d5041b..7d587ffc0a89 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -312,14 +312,6 @@ config REGULATOR_CROS_EC
This driver can also be built as a module. If so, the module
will be called cros-ec-regulator.
-config REGULATOR_DA903X
- tristate "Dialog Semiconductor DA9030/DA9034 regulators"
- depends on PMIC_DA903X
- depends on !CC_IS_CLANG # https://llvm.org/pr38789
- help
- Say y here to support the BUCKs and LDOs regulators found on
- Dialog Semiconductor DA9030/DA9034 PMIC.
-
config REGULATOR_DA9052
tristate "Dialog Semiconductor DA9052/DA9053 regulators"
depends on PMIC_DA9052
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 86b5afcc974e..a1344d3c3fd3 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -38,7 +38,6 @@ obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
obj-$(CONFIG_REGULATOR_BD957XMUF) += bd9576-regulator.o
obj-$(CONFIG_REGULATOR_BQ257XX) += bq257xx-regulator.o
-obj-$(CONFIG_REGULATOR_DA903X) += da903x-regulator.o
obj-$(CONFIG_REGULATOR_BD96801) += bd96801-regulator.o
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
diff --git a/drivers/regulator/da903x-regulator.c b/drivers/regulator/da903x-regulator.c
deleted file mode 100644
index 2f85897183b3..000000000000
--- a/drivers/regulator/da903x-regulator.c
+++ /dev/null
@@ -1,495 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-//
-// Regulators driver for Dialog Semiconductor DA903x
-//
-// Copyright (C) 2006-2008 Marvell International Ltd.
-// Copyright (C) 2008 Compulab Ltd.
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/da903x.h>
-
-/* DA9030 Registers */
-#define DA9030_INVAL (-1)
-#define DA9030_LDO1011 (0x10)
-#define DA9030_LDO15 (0x11)
-#define DA9030_LDO1416 (0x12)
-#define DA9030_LDO1819 (0x13)
-#define DA9030_LDO17 (0x14)
-#define DA9030_BUCK2DVM1 (0x15)
-#define DA9030_BUCK2DVM2 (0x16)
-#define DA9030_RCTL11 (0x17)
-#define DA9030_RCTL21 (0x18)
-#define DA9030_LDO1 (0x90)
-#define DA9030_LDO23 (0x91)
-#define DA9030_LDO45 (0x92)
-#define DA9030_LDO6 (0x93)
-#define DA9030_LDO78 (0x94)
-#define DA9030_LDO912 (0x95)
-#define DA9030_BUCK (0x96)
-#define DA9030_RCTL12 (0x97)
-#define DA9030_RCTL22 (0x98)
-#define DA9030_LDO_UNLOCK (0xa0)
-#define DA9030_LDO_UNLOCK_MASK (0xe0)
-#define DA9034_OVER1 (0x10)
-
-/* DA9034 Registers */
-#define DA9034_INVAL (-1)
-#define DA9034_OVER2 (0x11)
-#define DA9034_OVER3 (0x12)
-#define DA9034_LDO643 (0x13)
-#define DA9034_LDO987 (0x14)
-#define DA9034_LDO1110 (0x15)
-#define DA9034_LDO1312 (0x16)
-#define DA9034_LDO1514 (0x17)
-#define DA9034_VCC1 (0x20)
-#define DA9034_ADTV1 (0x23)
-#define DA9034_ADTV2 (0x24)
-#define DA9034_AVRC (0x25)
-#define DA9034_CDTV1 (0x26)
-#define DA9034_CDTV2 (0x27)
-#define DA9034_CVRC (0x28)
-#define DA9034_SDTV1 (0x29)
-#define DA9034_SDTV2 (0x2a)
-#define DA9034_SVRC (0x2b)
-#define DA9034_MDTV1 (0x32)
-#define DA9034_MDTV2 (0x33)
-#define DA9034_MVRC (0x34)
-
-/* DA9035 Registers. DA9034 Registers are compatible to DA9035. */
-#define DA9035_OVER3 (0x12)
-#define DA9035_VCC2 (0x1f)
-#define DA9035_3DTV1 (0x2c)
-#define DA9035_3DTV2 (0x2d)
-#define DA9035_3VRC (0x2e)
-#define DA9035_AUTOSKIP (0x2f)
-
-struct da903x_regulator_info {
- struct regulator_desc desc;
-
- int max_uV;
- int vol_reg;
- int vol_shift;
- int vol_nbits;
- int update_reg;
- int update_bit;
- int enable_reg;
- int enable_bit;
-};
-
-static inline struct device *to_da903x_dev(struct regulator_dev *rdev)
-{
- return rdev_get_dev(rdev)->parent->parent;
-}
-
-static inline int check_range(struct da903x_regulator_info *info,
- int min_uV, int max_uV)
-{
- if (min_uV < info->desc.min_uV || min_uV > info->max_uV)
- return -EINVAL;
-
- return 0;
-}
-
-/* DA9030/DA9034 common operations */
-static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- struct device *da9034_dev = to_da903x_dev(rdev);
- uint8_t val, mask;
-
- if (rdev->desc->n_voltages == 1)
- return -EINVAL;
-
- val = selector << info->vol_shift;
- mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
-
- return da903x_update(da9034_dev, info->vol_reg, val, mask);
-}
-
-static int da903x_get_voltage_sel(struct regulator_dev *rdev)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- struct device *da9034_dev = to_da903x_dev(rdev);
- uint8_t val, mask;
- int ret;
-
- if (rdev->desc->n_voltages == 1)
- return 0;
-
- ret = da903x_read(da9034_dev, info->vol_reg, &val);
- if (ret)
- return ret;
-
- mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
- val = (val & mask) >> info->vol_shift;
-
- return val;
-}
-
-static int da903x_enable(struct regulator_dev *rdev)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- struct device *da9034_dev = to_da903x_dev(rdev);
-
- return da903x_set_bits(da9034_dev, info->enable_reg,
- 1 << info->enable_bit);
-}
-
-static int da903x_disable(struct regulator_dev *rdev)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- struct device *da9034_dev = to_da903x_dev(rdev);
-
- return da903x_clr_bits(da9034_dev, info->enable_reg,
- 1 << info->enable_bit);
-}
-
-static int da903x_is_enabled(struct regulator_dev *rdev)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- struct device *da9034_dev = to_da903x_dev(rdev);
- uint8_t reg_val;
- int ret;
-
- ret = da903x_read(da9034_dev, info->enable_reg, ®_val);
- if (ret)
- return ret;
-
- return !!(reg_val & (1 << info->enable_bit));
-}
-
-/* DA9030 specific operations */
-static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev,
- unsigned selector)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- struct device *da903x_dev = to_da903x_dev(rdev);
- uint8_t val, mask;
- int ret;
-
- val = selector << info->vol_shift;
- mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
- val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */
- mask |= DA9030_LDO_UNLOCK_MASK;
-
- /* write twice */
- ret = da903x_update(da903x_dev, info->vol_reg, val, mask);
- if (ret)
- return ret;
-
- return da903x_update(da903x_dev, info->vol_reg, val, mask);
-}
-
-static int da9030_map_ldo14_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- int thresh, sel;
-
- if (check_range(info, min_uV, max_uV)) {
- pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
- return -EINVAL;
- }
-
- thresh = (info->max_uV + info->desc.min_uV) / 2;
- if (min_uV < thresh) {
- sel = DIV_ROUND_UP(thresh - min_uV, info->desc.uV_step);
- sel |= 0x4;
- } else {
- sel = DIV_ROUND_UP(min_uV - thresh, info->desc.uV_step);
- }
-
- return sel;
-}
-
-static int da9030_list_ldo14_voltage(struct regulator_dev *rdev,
- unsigned selector)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- int volt;
-
- if (selector & 0x4)
- volt = rdev->desc->min_uV +
- rdev->desc->uV_step * (3 - (selector & ~0x4));
- else
- volt = (info->max_uV + rdev->desc->min_uV) / 2 +
- rdev->desc->uV_step * (selector & ~0x4);
-
- if (volt > info->max_uV)
- return -EINVAL;
-
- return volt;
-}
-
-/* DA9034 specific operations */
-static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
- unsigned selector)
-{
- struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
- struct device *da9034_dev = to_da903x_dev(rdev);
- uint8_t val, mask;
- int ret;
-
- val = selector << info->vol_shift;
- mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
-
- ret = da903x_update(da9034_dev, info->vol_reg, val, mask);
- if (ret)
- return ret;
-
- ret = da903x_set_bits(da9034_dev, info->update_reg,
- 1 << info->update_bit);
- return ret;
-}
-
-static const struct linear_range da9034_ldo12_ranges[] = {
- REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000),
- REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000),
-};
-
-static const struct regulator_ops da903x_regulator_ldo_ops = {
- .set_voltage_sel = da903x_set_voltage_sel,
- .get_voltage_sel = da903x_get_voltage_sel,
- .list_voltage = regulator_list_voltage_linear,
- .map_voltage = regulator_map_voltage_linear,
- .enable = da903x_enable,
- .disable = da903x_disable,
- .is_enabled = da903x_is_enabled,
-};
-
-/* NOTE: this is dedicated for the insane DA9030 LDO14 */
-static const struct regulator_ops da9030_regulator_ldo14_ops = {
- .set_voltage_sel = da903x_set_voltage_sel,
- .get_voltage_sel = da903x_get_voltage_sel,
- .list_voltage = da9030_list_ldo14_voltage,
- .map_voltage = da9030_map_ldo14_voltage,
- .enable = da903x_enable,
- .disable = da903x_disable,
- .is_enabled = da903x_is_enabled,
-};
-
-/* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks */
-static const struct regulator_ops da9030_regulator_ldo1_15_ops = {
- .set_voltage_sel = da9030_set_ldo1_15_voltage_sel,
- .get_voltage_sel = da903x_get_voltage_sel,
- .list_voltage = regulator_list_voltage_linear,
- .map_voltage = regulator_map_voltage_linear,
- .enable = da903x_enable,
- .disable = da903x_disable,
- .is_enabled = da903x_is_enabled,
-};
-
-static const struct regulator_ops da9034_regulator_dvc_ops = {
- .set_voltage_sel = da9034_set_dvc_voltage_sel,
- .get_voltage_sel = da903x_get_voltage_sel,
- .list_voltage = regulator_list_voltage_linear,
- .map_voltage = regulator_map_voltage_linear,
- .enable = da903x_enable,
- .disable = da903x_disable,
- .is_enabled = da903x_is_enabled,
-};
-
-/* NOTE: this is dedicated for the insane LDO12 */
-static const struct regulator_ops da9034_regulator_ldo12_ops = {
- .set_voltage_sel = da903x_set_voltage_sel,
- .get_voltage_sel = da903x_get_voltage_sel,
- .list_voltage = regulator_list_voltage_linear_range,
- .map_voltage = regulator_map_voltage_linear_range,
- .enable = da903x_enable,
- .disable = da903x_disable,
- .is_enabled = da903x_is_enabled,
-};
-
-#define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \
-{ \
- .desc = { \
- .name = "LDO" #_id, \
- .ops = &da903x_regulator_ldo_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = _pmic##_ID_LDO##_id, \
- .n_voltages = (step) ? ((max - min) / step + 1) : 1, \
- .owner = THIS_MODULE, \
- .min_uV = (min) * 1000, \
- .uV_step = (step) * 1000, \
- }, \
- .max_uV = (max) * 1000, \
- .vol_reg = _pmic##_##vreg, \
- .vol_shift = (shift), \
- .vol_nbits = (nbits), \
- .enable_reg = _pmic##_##ereg, \
- .enable_bit = (ebit), \
-}
-
-#define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
-{ \
- .desc = { \
- .name = #_id, \
- .ops = &da9034_regulator_dvc_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = _pmic##_ID_##_id, \
- .n_voltages = (step) ? ((max - min) / step + 1) : 1, \
- .owner = THIS_MODULE, \
- .min_uV = (min) * 1000, \
- .uV_step = (step) * 1000, \
- }, \
- .max_uV = (max) * 1000, \
- .vol_reg = _pmic##_##vreg, \
- .vol_shift = (0), \
- .vol_nbits = (nbits), \
- .update_reg = _pmic##_##ureg, \
- .update_bit = (ubit), \
- .enable_reg = _pmic##_##ereg, \
- .enable_bit = (ebit), \
-}
-
-#define DA9034_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
- DA903x_LDO(DA9034, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
-
-#define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
- DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
-
-#define DA9030_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
- DA903x_DVC(DA9030, _id, min, max, step, vreg, nbits, ureg, ubit, \
- ereg, ebit)
-
-#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
- DA903x_DVC(DA9034, _id, min, max, step, vreg, nbits, ureg, ubit, \
- ereg, ebit)
-
-#define DA9035_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
- DA903x_DVC(DA9035, _id, min, max, step, vreg, nbits, ureg, ubit, \
- ereg, ebit)
-
-static struct da903x_regulator_info da903x_regulator_info[] = {
- /* DA9030 */
- DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0),
-
- DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1),
- DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2),
- DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3),
- DA9030_LDO( 4, 1800, 3200, 100, LDO45, 0, 4, RCTL12, 4),
- DA9030_LDO( 5, 1800, 3200, 100, LDO45, 4, 4, RCTL12, 5),
- DA9030_LDO( 6, 1800, 3200, 100, LDO6, 0, 4, RCTL12, 6),
- DA9030_LDO( 7, 1800, 3200, 100, LDO78, 0, 4, RCTL12, 7),
- DA9030_LDO( 8, 1800, 3200, 100, LDO78, 4, 4, RCTL22, 0),
- DA9030_LDO( 9, 1800, 3200, 100, LDO912, 0, 4, RCTL22, 1),
- DA9030_LDO(10, 1800, 3200, 100, LDO1011, 0, 4, RCTL22, 2),
- DA9030_LDO(11, 1800, 3200, 100, LDO1011, 4, 4, RCTL22, 3),
- DA9030_LDO(12, 1800, 3200, 100, LDO912, 4, 4, RCTL22, 4),
- DA9030_LDO(14, 2760, 2940, 30, LDO1416, 0, 3, RCTL11, 4),
- DA9030_LDO(15, 1100, 2650, 50, LDO15, 0, 5, RCTL11, 5),
- DA9030_LDO(16, 1100, 2650, 50, LDO1416, 3, 5, RCTL11, 6),
- DA9030_LDO(17, 1800, 3200, 100, LDO17, 0, 4, RCTL11, 7),
- DA9030_LDO(18, 1800, 3200, 100, LDO1819, 0, 4, RCTL21, 2),
- DA9030_LDO(19, 1800, 3200, 100, LDO1819, 4, 4, RCTL21, 1),
- DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */
-
- /* DA9034 */
- DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0),
- DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1),
- DA9034_DVC(LDO2, 725, 1500, 25, SDTV2, 5, VCC1, 4, OVER1, 2),
- DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4),
-
- DA9034_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5),
- DA9034_LDO( 4, 1800, 2900,1100, LDO643, 4, 1, OVER3, 6),
- DA9034_LDO( 6, 2500, 2850, 50, LDO643, 5, 3, OVER2, 0),
- DA9034_LDO( 7, 2700, 3050, 50, LDO987, 0, 3, OVER2, 1),
- DA9034_LDO( 8, 2700, 2850, 50, LDO987, 3, 2, OVER2, 2),
- DA9034_LDO( 9, 2700, 3050, 50, LDO987, 5, 3, OVER2, 3),
- DA9034_LDO(10, 2700, 3050, 50, LDO1110, 0, 3, OVER2, 4),
- DA9034_LDO(11, 1800, 3300, 100, LDO1110, 4, 4, OVER2, 5),
- DA9034_LDO(12, 1700, 3050, 50, LDO1312, 0, 4, OVER3, 6),
- DA9034_LDO(13, 1800, 3300, 100, LDO1312, 4, 4, OVER2, 7),
- DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0),
- DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
- DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */
-
- /* DA9035 */
- DA9035_DVC(BUCK3, 1800, 2200, 100, 3DTV1, 3, VCC2, 0, OVER3, 3),
-};
-
-static inline struct da903x_regulator_info *find_regulator_info(int id)
-{
- struct da903x_regulator_info *ri;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(da903x_regulator_info); i++) {
- ri = &da903x_regulator_info[i];
- if (ri->desc.id == id)
- return ri;
- }
- return NULL;
-}
-
-static int da903x_regulator_probe(struct platform_device *pdev)
-{
- struct da903x_regulator_info *ri = NULL;
- struct regulator_dev *rdev;
- struct regulator_config config = { };
-
- ri = find_regulator_info(pdev->id);
- if (ri == NULL) {
- dev_err(&pdev->dev, "invalid regulator ID specified\n");
- return -EINVAL;
- }
-
- /* Workaround for the weird LDO12 voltage setting */
- if (ri->desc.id == DA9034_ID_LDO12) {
- ri->desc.ops = &da9034_regulator_ldo12_ops;
- ri->desc.n_voltages = 16;
- ri->desc.linear_ranges = da9034_ldo12_ranges;
- ri->desc.n_linear_ranges = ARRAY_SIZE(da9034_ldo12_ranges);
- }
-
- if (ri->desc.id == DA9030_ID_LDO14)
- ri->desc.ops = &da9030_regulator_ldo14_ops;
-
- if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
- ri->desc.ops = &da9030_regulator_ldo1_15_ops;
-
- config.dev = &pdev->dev;
- config.init_data = dev_get_platdata(&pdev->dev);
- config.driver_data = ri;
-
- rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
- if (IS_ERR(rdev)) {
- dev_err(&pdev->dev, "failed to register regulator %s\n",
- ri->desc.name);
- return PTR_ERR(rdev);
- }
-
- platform_set_drvdata(pdev, rdev);
- return 0;
-}
-
-static struct platform_driver da903x_regulator_driver = {
- .driver = {
- .name = "da903x-regulator",
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
- .probe = da903x_regulator_probe,
-};
-
-static int __init da903x_regulator_init(void)
-{
- return platform_driver_register(&da903x_regulator_driver);
-}
-subsys_initcall(da903x_regulator_init);
-
-static void __exit da903x_regulator_exit(void)
-{
- platform_driver_unregister(&da903x_regulator_driver);
-}
-module_exit(da903x_regulator_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
- "Mike Rapoport <mike@compulab.co.il>");
-MODULE_DESCRIPTION("Regulator Driver for Dialog Semiconductor DA903X PMIC");
-MODULE_ALIAS("platform:da903x-regulator");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 63e5059563b4..413ed6c38b53 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -277,13 +277,6 @@ config BACKLIGHT_CGBC
backlight subsystem. It communicates with the board controller to
adjust LCD backlight using PWM signals.
-config BACKLIGHT_DA903X
- tristate "Backlight Driver for DA9030/DA9034 using WLED"
- depends on PMIC_DA903X
- help
- If you have a LCD backlight connected to the WLED output of DA9030
- or DA9034 WLED output, say Y here to enable this driver.
-
config BACKLIGHT_DA9052
tristate "Dialog DA9052/DA9053 WLED"
depends on PMIC_DA9052
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 1a6bef13430b..3dc3580d82c7 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -28,7 +28,6 @@ obj-$(CONFIG_BACKLIGHT_AW99706) += aw99706.o
obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o
obj-$(CONFIG_BACKLIGHT_CGBC) += cgbc_bl.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
-obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o
obj-$(CONFIG_BACKLIGHT_GPIO) += gpio_backlight.o
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
deleted file mode 100644
index 81ff42bec0ad..000000000000
--- a/drivers/video/backlight/da903x_bl.c
+++ /dev/null
@@ -1,160 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Backlight driver for Dialog Semiconductor DA9030/DA9034
- *
- * Copyright (C) 2008 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
- *
- * Copyright (C) 2006-2008 Marvell International Ltd.
- * Eric Miao <eric.miao@marvell.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/backlight.h>
-#include <linux/mfd/da903x.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#define DA9030_WLED_CONTROL 0x25
-#define DA9030_WLED_CP_EN (1 << 6)
-#define DA9030_WLED_TRIM(x) ((x) & 0x7)
-
-#define DA9034_WLED_CONTROL1 0x3C
-#define DA9034_WLED_CONTROL2 0x3D
-#define DA9034_WLED_ISET(x) ((x) & 0x1f)
-
-#define DA9034_WLED_BOOST_EN (1 << 5)
-
-#define DA9030_MAX_BRIGHTNESS 7
-#define DA9034_MAX_BRIGHTNESS 0x7f
-
-struct da903x_backlight_data {
- struct device *da903x_dev;
- int id;
- int current_brightness;
-};
-
-static int da903x_backlight_set(struct backlight_device *bl, int brightness)
-{
- struct da903x_backlight_data *data = bl_get_data(bl);
- struct device *dev = data->da903x_dev;
- uint8_t val;
- int ret = 0;
-
- switch (data->id) {
- case DA9034_ID_WLED:
- ret = da903x_update(dev, DA9034_WLED_CONTROL1,
- brightness, 0x7f);
- if (ret)
- return ret;
-
- if (data->current_brightness && brightness == 0)
- ret = da903x_clr_bits(dev,
- DA9034_WLED_CONTROL2,
- DA9034_WLED_BOOST_EN);
-
- if (data->current_brightness == 0 && brightness)
- ret = da903x_set_bits(dev,
- DA9034_WLED_CONTROL2,
- DA9034_WLED_BOOST_EN);
- break;
- case DA9030_ID_WLED:
- val = DA9030_WLED_TRIM(brightness);
- val |= brightness ? DA9030_WLED_CP_EN : 0;
- ret = da903x_write(dev, DA9030_WLED_CONTROL, val);
- break;
- }
-
- if (ret)
- return ret;
-
- data->current_brightness = brightness;
- return 0;
-}
-
-static int da903x_backlight_update_status(struct backlight_device *bl)
-{
- return da903x_backlight_set(bl, backlight_get_brightness(bl));
-}
-
-static int da903x_backlight_get_brightness(struct backlight_device *bl)
-{
- struct da903x_backlight_data *data = bl_get_data(bl);
-
- return data->current_brightness;
-}
-
-static const struct backlight_ops da903x_backlight_ops = {
- .options = BL_CORE_SUSPENDRESUME,
- .update_status = da903x_backlight_update_status,
- .get_brightness = da903x_backlight_get_brightness,
-};
-
-static int da903x_backlight_probe(struct platform_device *pdev)
-{
- struct da9034_backlight_pdata *pdata = dev_get_platdata(&pdev->dev);
- struct da903x_backlight_data *data;
- struct backlight_device *bl;
- struct backlight_properties props;
- int max_brightness;
-
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- switch (pdev->id) {
- case DA9030_ID_WLED:
- max_brightness = DA9030_MAX_BRIGHTNESS;
- break;
- case DA9034_ID_WLED:
- max_brightness = DA9034_MAX_BRIGHTNESS;
- break;
- default:
- dev_err(&pdev->dev, "invalid backlight device ID(%d)\n",
- pdev->id);
- return -EINVAL;
- }
-
- data->id = pdev->id;
- data->da903x_dev = pdev->dev.parent;
- data->current_brightness = 0;
-
- /* adjust the WLED output current */
- if (pdata)
- da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
- DA9034_WLED_ISET(pdata->output_current));
-
- memset(&props, 0, sizeof(props));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = max_brightness;
- bl = devm_backlight_device_register(&pdev->dev, pdev->name,
- data->da903x_dev, data,
- &da903x_backlight_ops, &props);
- if (IS_ERR(bl)) {
- dev_err(&pdev->dev, "failed to register backlight\n");
- return PTR_ERR(bl);
- }
-
- bl->props.brightness = max_brightness;
-
- platform_set_drvdata(pdev, bl);
- backlight_update_status(bl);
- return 0;
-}
-
-static struct platform_driver da903x_backlight_driver = {
- .driver = {
- .name = "da903x-backlight",
- },
- .probe = da903x_backlight_probe,
-};
-
-module_platform_driver(da903x_backlight_driver);
-
-MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
-MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:da903x-backlight");
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* Re: [PATCH 06/14] mfd: remove unused da903x driver
2026-09-09 13:21 ` [PATCH 06/14] mfd: remove unused da903x driver Arnd Bergmann
@ 2026-09-09 15:46 ` Sebastian Reichel
0 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2026-09-09 15:46 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
[-- Attachment #1: Type: text/plain, Size: 1844 bytes --]
Hi,
On Wed, Sep 09, 2026 at 03:21:43PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver was used on a handful of ARM/PXA boards until those
> got removed a few years ago. Without devicetree support, there is
> no way to use them upstream.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> MAINTAINERS | 1 -
> drivers/input/touchscreen/Kconfig | 13 -
> drivers/input/touchscreen/Makefile | 1 -
> drivers/input/touchscreen/da9034-ts.c | 365 ----------------
> drivers/leds/Kconfig | 8 -
> drivers/leds/Makefile | 1 -
> drivers/leds/leds-da903x.c | 145 -------
> drivers/mfd/Kconfig | 11 -
> drivers/mfd/Makefile | 2 -
> drivers/mfd/da903x.c | 565 -------------------------
> drivers/power/supply/Kconfig | 7 -
> drivers/power/supply/Makefile | 1 -
> drivers/power/supply/da9030_battery.c | 581 --------------------------
> drivers/regulator/Kconfig | 8 -
> drivers/regulator/Makefile | 1 -
> drivers/regulator/da903x-regulator.c | 495 ----------------------
> drivers/video/backlight/Kconfig | 7 -
> drivers/video/backlight/Makefile | 1 -
> drivers/video/backlight/da903x_bl.c | 160 -------
> 19 files changed, 2373 deletions(-)
> delete mode 100644 drivers/input/touchscreen/da9034-ts.c
> delete mode 100644 drivers/leds/leds-da903x.c
> delete mode 100644 drivers/mfd/da903x.c
> delete mode 100644 drivers/power/supply/da9030_battery.c
> delete mode 100644 drivers/regulator/da903x-regulator.c
> delete mode 100644 drivers/video/backlight/da903x_bl.c
Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-- Sebastian
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 07/14] mfd: remove unused lp8788 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (3 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 06/14] mfd: remove unused da903x driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 15:46 ` Sebastian Reichel
2026-09-09 13:21 ` [PATCH 08/14] mfd: remove unused aat2870 driver Arnd Bergmann
` (9 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
This driver was apparently never used upstream, and without devicetree
support cannot be used by external board support.
The MAINTAINER entry was already removed in 2021 as the email address
bounced.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/iio/adc/Kconfig | 9 -
drivers/iio/adc/Makefile | 1 -
drivers/iio/adc/lp8788_adc.c | 219 --------
drivers/leds/Kconfig | 7 -
drivers/leds/Makefile | 1 -
drivers/leds/leds-lp8788.c | 171 ------
drivers/mfd/Kconfig | 10 -
drivers/mfd/Makefile | 1 -
drivers/mfd/lp8788-irq.c | 194 -------
drivers/mfd/lp8788.c | 246 ---------
drivers/power/supply/Kconfig | 8 -
drivers/power/supply/Makefile | 1 -
drivers/power/supply/lp8788-charger.c | 730 --------------------------
drivers/regulator/Kconfig | 6 -
drivers/regulator/Makefile | 2 -
drivers/regulator/lp8788-buck.c | 541 -------------------
drivers/regulator/lp8788-ldo.c | 640 ----------------------
drivers/rtc/Kconfig | 6 -
drivers/rtc/rtc-lp8788.c | 322 ------------
drivers/video/backlight/Kconfig | 6 -
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/lp8788_bl.c | 190 -------
include/linux/mfd/lp8788-isink.h | 48 --
include/linux/mfd/lp8788.h | 289 ----------
24 files changed, 3649 deletions(-)
delete mode 100644 drivers/iio/adc/lp8788_adc.c
delete mode 100644 drivers/leds/leds-lp8788.c
delete mode 100644 drivers/mfd/lp8788-irq.c
delete mode 100644 drivers/mfd/lp8788.c
delete mode 100644 drivers/power/supply/lp8788-charger.c
delete mode 100644 drivers/regulator/lp8788-buck.c
delete mode 100644 drivers/regulator/lp8788-ldo.c
delete mode 100644 drivers/rtc/rtc-lp8788.c
delete mode 100644 drivers/video/backlight/lp8788_bl.c
delete mode 100644 include/linux/mfd/lp8788-isink.h
delete mode 100644 include/linux/mfd/lp8788.h
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 415e519ad4eb..af9651003449 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -905,15 +905,6 @@ config IMX93_ADC
This driver can also be built as a module. If so, the module will be
called imx93_adc.
-config LP8788_ADC
- tristate "LP8788 ADC driver"
- depends on MFD_LP8788
- help
- Say yes here to build support for TI LP8788 ADC.
-
- To compile this driver as a module, choose M here: the module will be
- called lp8788_adc.
-
config LPC18XX_ADC
tristate "NXP LPC18xx ADC driver"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index dcec0abb03b7..845ddf628f22 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -77,7 +77,6 @@ obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
obj-$(CONFIG_INGENIC_ADC) += ingenic-adc.o
obj-$(CONFIG_INTEL_DC_TI_ADC) += intel_dc_ti_adc.o
obj-$(CONFIG_INTEL_MRFLD_ADC) += intel_mrfld_adc.o
-obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
obj-$(CONFIG_LTC2309) += ltc2309.o
diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c
deleted file mode 100644
index 33bf8aef79e3..000000000000
--- a/drivers/iio/adc/lp8788_adc.c
+++ /dev/null
@@ -1,219 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - ADC driver
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/delay.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/driver.h>
-#include <linux/iio/machine.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-/* register address */
-#define LP8788_ADC_CONF 0x60
-#define LP8788_ADC_RAW 0x61
-#define LP8788_ADC_DONE 0x63
-
-#define ADC_CONV_START 1
-
-struct lp8788_adc {
- struct lp8788 *lp;
- const struct iio_map *map;
- struct mutex lock;
-};
-
-static const int lp8788_scale[LPADC_MAX] = {
- [LPADC_VBATT_5P5] = 1343101,
- [LPADC_VIN_CHG] = 3052503,
- [LPADC_IBATT] = 610500,
- [LPADC_IC_TEMP] = 61050,
- [LPADC_VBATT_6P0] = 1465201,
- [LPADC_VBATT_5P0] = 1221001,
- [LPADC_ADC1] = 610500,
- [LPADC_ADC2] = 610500,
- [LPADC_VDD] = 1025641,
- [LPADC_VCOIN] = 757020,
- [LPADC_ADC3] = 610500,
- [LPADC_ADC4] = 610500,
-};
-
-static int lp8788_get_adc_result(struct lp8788_adc *adc, enum lp8788_adc_id id,
- int *val)
-{
- unsigned int msb;
- unsigned int lsb;
- unsigned int result;
- u8 data;
- u8 rawdata[2];
- int size = ARRAY_SIZE(rawdata);
- int retry = 5;
- int ret;
-
- data = (id << 1) | ADC_CONV_START;
- ret = lp8788_write_byte(adc->lp, LP8788_ADC_CONF, data);
- if (ret)
- goto err_io;
-
- /* retry until adc conversion is done */
- data = 0;
- while (retry--) {
- usleep_range(100, 200);
-
- ret = lp8788_read_byte(adc->lp, LP8788_ADC_DONE, &data);
- if (ret)
- goto err_io;
-
- /* conversion done */
- if (data)
- break;
- }
-
- ret = lp8788_read_multi_bytes(adc->lp, LP8788_ADC_RAW, rawdata, size);
- if (ret)
- goto err_io;
-
- msb = (rawdata[0] << 4) & 0x00000ff0;
- lsb = (rawdata[1] >> 4) & 0x0000000f;
- result = msb | lsb;
- *val = result;
-
- return 0;
-
-err_io:
- return ret;
-}
-
-static int lp8788_adc_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
-{
- struct lp8788_adc *adc = iio_priv(indio_dev);
- enum lp8788_adc_id id = chan->channel;
- int ret;
-
- mutex_lock(&adc->lock);
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- ret = lp8788_get_adc_result(adc, id, val) ? -EIO : IIO_VAL_INT;
- break;
- case IIO_CHAN_INFO_SCALE:
- *val = lp8788_scale[id] / 1000000;
- *val2 = lp8788_scale[id] % 1000000;
- ret = IIO_VAL_INT_PLUS_MICRO;
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- mutex_unlock(&adc->lock);
-
- return ret;
-}
-
-static const struct iio_info lp8788_adc_info = {
- .read_raw = &lp8788_adc_read_raw,
-};
-
-#define LP8788_CHAN(_id, _type) { \
- .type = _type, \
- .indexed = 1, \
- .channel = LPADC_##_id, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
- BIT(IIO_CHAN_INFO_SCALE), \
- .datasheet_name = #_id, \
-}
-
-static const struct iio_chan_spec lp8788_adc_channels[] = {
- [LPADC_VBATT_5P5] = LP8788_CHAN(VBATT_5P5, IIO_VOLTAGE),
- [LPADC_VIN_CHG] = LP8788_CHAN(VIN_CHG, IIO_VOLTAGE),
- [LPADC_IBATT] = LP8788_CHAN(IBATT, IIO_CURRENT),
- [LPADC_IC_TEMP] = LP8788_CHAN(IC_TEMP, IIO_TEMP),
- [LPADC_VBATT_6P0] = LP8788_CHAN(VBATT_6P0, IIO_VOLTAGE),
- [LPADC_VBATT_5P0] = LP8788_CHAN(VBATT_5P0, IIO_VOLTAGE),
- [LPADC_ADC1] = LP8788_CHAN(ADC1, IIO_VOLTAGE),
- [LPADC_ADC2] = LP8788_CHAN(ADC2, IIO_VOLTAGE),
- [LPADC_VDD] = LP8788_CHAN(VDD, IIO_VOLTAGE),
- [LPADC_VCOIN] = LP8788_CHAN(VCOIN, IIO_VOLTAGE),
- [LPADC_ADC3] = LP8788_CHAN(ADC3, IIO_VOLTAGE),
- [LPADC_ADC4] = LP8788_CHAN(ADC4, IIO_VOLTAGE),
-};
-
-/* default maps used by iio consumer (lp8788-charger driver) */
-static const struct iio_map lp8788_default_iio_maps[] = {
- IIO_MAP("VBATT_5P0", "lp8788-charger", "lp8788_vbatt_5p0"),
- IIO_MAP("ADC1", "lp8788-charger", "lp8788_adc1"),
- { }
-};
-
-static int lp8788_iio_map_register(struct device *dev,
- struct iio_dev *indio_dev,
- struct lp8788_platform_data *pdata,
- struct lp8788_adc *adc)
-{
- const struct iio_map *map;
- int ret;
-
- map = (!pdata || !pdata->adc_pdata) ?
- lp8788_default_iio_maps : pdata->adc_pdata;
-
- ret = devm_iio_map_array_register(dev, indio_dev, map);
- if (ret) {
- dev_err(&indio_dev->dev, "iio map err: %d\n", ret);
- return ret;
- }
-
- adc->map = map;
- return 0;
-}
-
-static int lp8788_adc_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- struct iio_dev *indio_dev;
- struct lp8788_adc *adc;
- int ret;
-
- indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
- if (!indio_dev)
- return -ENOMEM;
-
- adc = iio_priv(indio_dev);
- adc->lp = lp;
-
- ret = lp8788_iio_map_register(&pdev->dev, indio_dev, lp->pdata, adc);
- if (ret)
- return ret;
-
- mutex_init(&adc->lock);
-
- indio_dev->name = pdev->name;
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->info = &lp8788_adc_info;
- indio_dev->channels = lp8788_adc_channels;
- indio_dev->num_channels = ARRAY_SIZE(lp8788_adc_channels);
-
- return devm_iio_device_register(&pdev->dev, indio_dev);
-}
-
-static struct platform_driver lp8788_adc_driver = {
- .probe = lp8788_adc_probe,
- .driver = {
- .name = LP8788_DEV_ADC,
- },
-};
-module_platform_driver(lp8788_adc_driver);
-
-MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lp8788-adc");
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 5aab4765d6d7..f0cd10ad6279 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -511,13 +511,6 @@ config LEDS_LP8501
It is similar as LP5523, but output power selection is available.
And register layout and engine program schemes are different.
-config LEDS_LP8788
- tristate "LED support for the TI LP8788 PMIC"
- depends on LEDS_CLASS
- depends on MFD_LP8788
- help
- This option enables support for the Keyboard LEDs on the LP8788 PMIC.
-
config LEDS_LP8860
tristate "LED support for the TI LP8860 4 channel LED driver"
depends on LEDS_CLASS && I2C && OF
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 148301cf4865..63dc0b0c5a51 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -55,7 +55,6 @@ obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o
obj-$(CONFIG_LEDS_LP5569) += leds-lp5569.o
obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o
obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o
-obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
obj-$(CONFIG_LEDS_LP8860) += leds-lp8860.o
obj-$(CONFIG_LEDS_LP8864) += leds-lp8864.o
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
diff --git a/drivers/leds/leds-lp8788.c b/drivers/leds/leds-lp8788.c
deleted file mode 100644
index 9b9525ccca15..000000000000
--- a/drivers/leds/leds-lp8788.c
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - keyled driver
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/mutex.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/mfd/lp8788-isink.h>
-
-#define MAX_BRIGHTNESS LP8788_ISINK_MAX_PWM
-#define DEFAULT_LED_NAME "keyboard-backlight"
-
-struct lp8788_led {
- struct lp8788 *lp;
- struct mutex lock;
- struct led_classdev led_dev;
- enum lp8788_isink_number isink_num;
- int on;
-};
-
-struct lp8788_led_config {
- enum lp8788_isink_scale scale;
- enum lp8788_isink_number num;
- int iout;
-};
-
-static struct lp8788_led_config default_led_config = {
- .scale = LP8788_ISINK_SCALE_100mA,
- .num = LP8788_ISINK_3,
- .iout = 0,
-};
-
-static int lp8788_led_init_device(struct lp8788_led *led,
- struct lp8788_led_platform_data *pdata)
-{
- struct lp8788_led_config *cfg = &default_led_config;
- u8 addr, mask, val;
- int ret;
-
- if (pdata) {
- cfg->scale = pdata->scale;
- cfg->num = pdata->num;
- cfg->iout = pdata->iout_code;
- }
-
- led->isink_num = cfg->num;
-
- /* scale configuration */
- addr = LP8788_ISINK_CTRL;
- mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
- val = cfg->scale << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
- ret = lp8788_update_bits(led->lp, addr, mask, val);
- if (ret)
- return ret;
-
- /* current configuration */
- addr = lp8788_iout_addr[cfg->num];
- mask = lp8788_iout_mask[cfg->num];
- val = cfg->iout;
-
- return lp8788_update_bits(led->lp, addr, mask, val);
-}
-
-static int lp8788_led_enable(struct lp8788_led *led,
- enum lp8788_isink_number num, int on)
-{
- int ret;
-
- u8 mask = 1 << num;
- u8 val = on << num;
-
- ret = lp8788_update_bits(led->lp, LP8788_ISINK_CTRL, mask, val);
- if (ret == 0)
- led->on = on;
-
- return ret;
-}
-
-static int lp8788_brightness_set(struct led_classdev *led_cdev,
- enum led_brightness val)
-{
- struct lp8788_led *led =
- container_of(led_cdev, struct lp8788_led, led_dev);
-
- enum lp8788_isink_number num = led->isink_num;
- int enable, ret;
-
- mutex_lock(&led->lock);
-
- switch (num) {
- case LP8788_ISINK_1:
- case LP8788_ISINK_2:
- case LP8788_ISINK_3:
- ret = lp8788_write_byte(led->lp, lp8788_pwm_addr[num], val);
- if (ret < 0)
- goto unlock;
- break;
- default:
- mutex_unlock(&led->lock);
- return -EINVAL;
- }
-
- enable = (val > 0) ? 1 : 0;
- if (enable != led->on)
- ret = lp8788_led_enable(led, num, enable);
-unlock:
- mutex_unlock(&led->lock);
- return ret;
-}
-
-static int lp8788_led_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- struct lp8788_led_platform_data *led_pdata;
- struct lp8788_led *led;
- struct device *dev = &pdev->dev;
- int ret;
-
- led = devm_kzalloc(dev, sizeof(struct lp8788_led), GFP_KERNEL);
- if (!led)
- return -ENOMEM;
-
- led->lp = lp;
- led->led_dev.max_brightness = MAX_BRIGHTNESS;
- led->led_dev.brightness_set_blocking = lp8788_brightness_set;
-
- led_pdata = lp->pdata ? lp->pdata->led_pdata : NULL;
-
- if (!led_pdata || !led_pdata->name)
- led->led_dev.name = DEFAULT_LED_NAME;
- else
- led->led_dev.name = led_pdata->name;
-
- mutex_init(&led->lock);
-
- ret = lp8788_led_init_device(led, led_pdata);
- if (ret) {
- dev_err(dev, "led init device err: %d\n", ret);
- return ret;
- }
-
- ret = devm_led_classdev_register(dev, &led->led_dev);
- if (ret) {
- dev_err(dev, "led register err: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static struct platform_driver lp8788_led_driver = {
- .probe = lp8788_led_probe,
- .driver = {
- .name = LP8788_DEV_KEYLED,
- },
-};
-module_platform_driver(lp8788_led_driver);
-
-MODULE_DESCRIPTION("Texas Instruments LP8788 Keyboard LED Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lp8788-keyled");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fda9d7ad5743..09e400e1f4b0 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1603,16 +1603,6 @@ config MFD_LP3943
With these functionalities, it can be used for LED string control or
general usage such like a GPIO controller and a PWM controller.
-config MFD_LP8788
- bool "TI LP8788 Power Management Unit Driver"
- depends on I2C=y
- select MFD_CORE
- select REGMAP_I2C
- select IRQ_DOMAIN
- help
- TI LP8788 PMU supports regulators, battery charger, RTC,
- ADC, backlight driver and current sinks.
-
config MFD_TI_LMU
tristate "TI Lighting Management Unit driver"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 82795e65cbe7..e3fe998c3513 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -150,7 +150,6 @@ obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
obj-$(CONFIG_MFD_LP3943) += lp3943.o
-obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o
obj-$(CONFIG_MFD_TI_LMU) += ti-lmu.o
diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
deleted file mode 100644
index f62fa2d7f010..000000000000
--- a/drivers/mfd/lp8788-irq.c
+++ /dev/null
@@ -1,194 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - interrupt handler
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/device.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-/* register address */
-#define LP8788_INT_1 0x00
-#define LP8788_INTEN_1 0x03
-
-#define BASE_INTEN_ADDR LP8788_INTEN_1
-#define SIZE_REG 8
-#define NUM_REGS 3
-
-/*
- * struct lp8788_irq_data
- * @lp : used for accessing to lp8788 registers
- * @irq_lock : mutex for enabling/disabling the interrupt
- * @domain : IRQ domain for handling nested interrupt
- * @enabled : status of enabled interrupt
- */
-struct lp8788_irq_data {
- struct lp8788 *lp;
- struct mutex irq_lock;
- struct irq_domain *domain;
- int enabled[LP8788_INT_MAX];
-};
-
-static inline u8 _irq_to_addr(enum lp8788_int_id id)
-{
- return id / SIZE_REG;
-}
-
-static inline u8 _irq_to_enable_addr(enum lp8788_int_id id)
-{
- return _irq_to_addr(id) + BASE_INTEN_ADDR;
-}
-
-static inline u8 _irq_to_mask(enum lp8788_int_id id)
-{
- return 1 << (id % SIZE_REG);
-}
-
-static inline u8 _irq_to_val(enum lp8788_int_id id, int enable)
-{
- return enable << (id % SIZE_REG);
-}
-
-static void lp8788_irq_enable(struct irq_data *data)
-{
- struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
-
- irqd->enabled[data->hwirq] = 1;
-}
-
-static void lp8788_irq_disable(struct irq_data *data)
-{
- struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
-
- irqd->enabled[data->hwirq] = 0;
-}
-
-static void lp8788_irq_bus_lock(struct irq_data *data)
-{
- struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
-
- mutex_lock(&irqd->irq_lock);
-}
-
-static void lp8788_irq_bus_sync_unlock(struct irq_data *data)
-{
- struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
- enum lp8788_int_id irq = data->hwirq;
- u8 addr, mask, val;
-
- addr = _irq_to_enable_addr(irq);
- mask = _irq_to_mask(irq);
- val = _irq_to_val(irq, irqd->enabled[irq]);
-
- lp8788_update_bits(irqd->lp, addr, mask, val);
-
- mutex_unlock(&irqd->irq_lock);
-}
-
-static struct irq_chip lp8788_irq_chip = {
- .name = "lp8788",
- .irq_enable = lp8788_irq_enable,
- .irq_disable = lp8788_irq_disable,
- .irq_bus_lock = lp8788_irq_bus_lock,
- .irq_bus_sync_unlock = lp8788_irq_bus_sync_unlock,
-};
-
-static irqreturn_t lp8788_irq_handler(int irq, void *ptr)
-{
- struct lp8788_irq_data *irqd = ptr;
- struct lp8788 *lp = irqd->lp;
- u8 status[NUM_REGS], addr, mask;
- bool handled = false;
- int i;
-
- if (lp8788_read_multi_bytes(lp, LP8788_INT_1, status, NUM_REGS))
- return IRQ_NONE;
-
- for (i = 0 ; i < LP8788_INT_MAX ; i++) {
- addr = _irq_to_addr(i);
- mask = _irq_to_mask(i);
-
- /* reporting only if the irq is enabled */
- if (status[addr] & mask) {
- handle_nested_irq(irq_find_mapping(irqd->domain, i));
- handled = true;
- }
- }
-
- return handled ? IRQ_HANDLED : IRQ_NONE;
-}
-
-static int lp8788_irq_map(struct irq_domain *d, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- struct lp8788_irq_data *irqd = d->host_data;
- struct irq_chip *chip = &lp8788_irq_chip;
-
- irq_set_chip_data(virq, irqd);
- irq_set_chip_and_handler(virq, chip, handle_edge_irq);
- irq_set_nested_thread(virq, 1);
- irq_set_noprobe(virq);
-
- return 0;
-}
-
-static const struct irq_domain_ops lp8788_domain_ops = {
- .map = lp8788_irq_map,
-};
-
-int lp8788_irq_init(struct lp8788 *lp, int irq)
-{
- struct lp8788_irq_data *irqd;
- int ret;
-
- if (irq <= 0) {
- dev_warn(lp->dev, "invalid irq number: %d\n", irq);
- return 0;
- }
-
- irqd = devm_kzalloc(lp->dev, sizeof(*irqd), GFP_KERNEL);
- if (!irqd)
- return -ENOMEM;
-
- irqd->lp = lp;
- irqd->domain = irq_domain_create_linear(dev_fwnode(lp->dev), LP8788_INT_MAX,
- &lp8788_domain_ops, irqd);
- if (!irqd->domain) {
- dev_err(lp->dev, "failed to add irq domain err\n");
- return -EINVAL;
- }
-
- lp->irqdm = irqd->domain;
- mutex_init(&irqd->irq_lock);
-
- ret = request_threaded_irq(irq, NULL, lp8788_irq_handler,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "lp8788-irq", irqd);
- if (ret) {
- irq_domain_remove(lp->irqdm);
- dev_err(lp->dev, "failed to create a thread for IRQ_N\n");
- return ret;
- }
-
- lp->irq = irq;
-
- return 0;
-}
-
-void lp8788_irq_exit(struct lp8788 *lp)
-{
- if (lp->irq)
- free_irq(lp->irq, lp->irqdm);
- if (lp->irqdm)
- irq_domain_remove(lp->irqdm);
-}
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
deleted file mode 100644
index 32f255378f5a..000000000000
--- a/drivers/mfd/lp8788.c
+++ /dev/null
@@ -1,246 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - core interface
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#define MAX_LP8788_REGISTERS 0xA2
-
-#define MFD_DEV_SIMPLE(_name) \
-{ \
- .name = LP8788_DEV_##_name, \
-}
-
-#define MFD_DEV_WITH_ID(_name, _id) \
-{ \
- .name = LP8788_DEV_##_name, \
- .id = _id, \
-}
-
-#define MFD_DEV_WITH_RESOURCE(_name, _resource, num_resource) \
-{ \
- .name = LP8788_DEV_##_name, \
- .resources = _resource, \
- .num_resources = num_resource, \
-}
-
-static const struct resource chg_irqs[] = {
- /* Charger Interrupts */
- {
- .start = LP8788_INT_CHG_INPUT_STATE,
- .end = LP8788_INT_PRECHG_TIMEOUT,
- .name = LP8788_CHG_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- /* Power Routing Switch Interrupts */
- {
- .start = LP8788_INT_ENTER_SYS_SUPPORT,
- .end = LP8788_INT_EXIT_SYS_SUPPORT,
- .name = LP8788_PRSW_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- /* Battery Interrupts */
- {
- .start = LP8788_INT_BATT_LOW,
- .end = LP8788_INT_NO_BATT,
- .name = LP8788_BATT_IRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static const struct resource rtc_irqs[] = {
- {
- .start = LP8788_INT_RTC_ALARM1,
- .end = LP8788_INT_RTC_ALARM2,
- .name = LP8788_ALM_IRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static const struct mfd_cell lp8788_devs[] = {
- /* 4 bucks */
- MFD_DEV_WITH_ID(BUCK, 1),
- MFD_DEV_WITH_ID(BUCK, 2),
- MFD_DEV_WITH_ID(BUCK, 3),
- MFD_DEV_WITH_ID(BUCK, 4),
-
- /* 12 digital ldos */
- MFD_DEV_WITH_ID(DLDO, 1),
- MFD_DEV_WITH_ID(DLDO, 2),
- MFD_DEV_WITH_ID(DLDO, 3),
- MFD_DEV_WITH_ID(DLDO, 4),
- MFD_DEV_WITH_ID(DLDO, 5),
- MFD_DEV_WITH_ID(DLDO, 6),
- MFD_DEV_WITH_ID(DLDO, 7),
- MFD_DEV_WITH_ID(DLDO, 8),
- MFD_DEV_WITH_ID(DLDO, 9),
- MFD_DEV_WITH_ID(DLDO, 10),
- MFD_DEV_WITH_ID(DLDO, 11),
- MFD_DEV_WITH_ID(DLDO, 12),
-
- /* 10 analog ldos */
- MFD_DEV_WITH_ID(ALDO, 1),
- MFD_DEV_WITH_ID(ALDO, 2),
- MFD_DEV_WITH_ID(ALDO, 3),
- MFD_DEV_WITH_ID(ALDO, 4),
- MFD_DEV_WITH_ID(ALDO, 5),
- MFD_DEV_WITH_ID(ALDO, 6),
- MFD_DEV_WITH_ID(ALDO, 7),
- MFD_DEV_WITH_ID(ALDO, 8),
- MFD_DEV_WITH_ID(ALDO, 9),
- MFD_DEV_WITH_ID(ALDO, 10),
-
- /* ADC */
- MFD_DEV_SIMPLE(ADC),
-
- /* battery charger */
- MFD_DEV_WITH_RESOURCE(CHARGER, chg_irqs, ARRAY_SIZE(chg_irqs)),
-
- /* rtc */
- MFD_DEV_WITH_RESOURCE(RTC, rtc_irqs, ARRAY_SIZE(rtc_irqs)),
-
- /* backlight */
- MFD_DEV_SIMPLE(BACKLIGHT),
-
- /* current sink for vibrator */
- MFD_DEV_SIMPLE(VIBRATOR),
-
- /* current sink for keypad LED */
- MFD_DEV_SIMPLE(KEYLED),
-};
-
-int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data)
-{
- int ret;
- unsigned int val;
-
- ret = regmap_read(lp->regmap, reg, &val);
- if (ret < 0) {
- dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
- return ret;
- }
-
- *data = (u8)val;
- return 0;
-}
-EXPORT_SYMBOL_GPL(lp8788_read_byte);
-
-int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count)
-{
- return regmap_bulk_read(lp->regmap, reg, data, count);
-}
-EXPORT_SYMBOL_GPL(lp8788_read_multi_bytes);
-
-int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data)
-{
- return regmap_write(lp->regmap, reg, data);
-}
-EXPORT_SYMBOL_GPL(lp8788_write_byte);
-
-int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data)
-{
- return regmap_update_bits(lp->regmap, reg, mask, data);
-}
-EXPORT_SYMBOL_GPL(lp8788_update_bits);
-
-static int lp8788_platform_init(struct lp8788 *lp)
-{
- struct lp8788_platform_data *pdata = lp->pdata;
-
- return (pdata && pdata->init_func) ? pdata->init_func(lp) : 0;
-}
-
-static const struct regmap_config lp8788_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = MAX_LP8788_REGISTERS,
-};
-
-static int lp8788_probe(struct i2c_client *cl)
-{
- struct lp8788 *lp;
- struct lp8788_platform_data *pdata = dev_get_platdata(&cl->dev);
- int ret;
-
- lp = devm_kzalloc(&cl->dev, sizeof(struct lp8788), GFP_KERNEL);
- if (!lp)
- return -ENOMEM;
-
- lp->regmap = devm_regmap_init_i2c(cl, &lp8788_regmap_config);
- if (IS_ERR(lp->regmap)) {
- ret = PTR_ERR(lp->regmap);
- dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
- return ret;
- }
-
- lp->pdata = pdata;
- lp->dev = &cl->dev;
- i2c_set_clientdata(cl, lp);
-
- ret = lp8788_platform_init(lp);
- if (ret)
- return ret;
-
- ret = lp8788_irq_init(lp, cl->irq);
- if (ret)
- return ret;
-
- ret = mfd_add_devices(lp->dev, -1, lp8788_devs,
- ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
- if (ret)
- goto err_exit_irq;
-
- return 0;
-
-err_exit_irq:
- lp8788_irq_exit(lp);
- return ret;
-}
-
-static void lp8788_remove(struct i2c_client *cl)
-{
- struct lp8788 *lp = i2c_get_clientdata(cl);
-
- mfd_remove_devices(lp->dev);
- lp8788_irq_exit(lp);
-}
-
-static const struct i2c_device_id lp8788_ids[] = {
- { "lp8788" },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, lp8788_ids);
-
-static struct i2c_driver lp8788_driver = {
- .driver = {
- .name = "lp8788",
- },
- .probe = lp8788_probe,
- .remove = lp8788_remove,
- .id_table = lp8788_ids,
-};
-
-static int __init lp8788_init(void)
-{
- return i2c_add_driver(&lp8788_driver);
-}
-subsys_initcall(lp8788_init);
-
-static void __exit lp8788_exit(void)
-{
- i2c_del_driver(&lp8788_driver);
-}
-module_exit(lp8788_exit);
-
-MODULE_DESCRIPTION("TI LP8788 MFD Driver");
-MODULE_AUTHOR("Milo Kim");
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index a492c86e879a..9bb2ac78dca9 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -555,14 +555,6 @@ config CHARGER_LP8727
help
Say Y here to enable support for LP8727 Charger Driver.
-config CHARGER_LP8788
- tristate "TI LP8788 charger driver"
- depends on MFD_LP8788
- depends on LP8788_ADC
- depends on IIO
- help
- Say Y to enable support for the LP8788 linear charger.
-
config CHARGER_GPIO
tristate "GPIO charger"
depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 380546080112..76422bece94c 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -76,7 +76,6 @@ obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_TWL6030) += twl6030_charger.o
obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
-obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_LT3651) += lt3651-charger.o
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
deleted file mode 100644
index b8b74efc9671..000000000000
--- a/drivers/power/supply/lp8788-charger.c
+++ /dev/null
@@ -1,730 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - battery charger driver
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/err.h>
-#include <linux/iio/consumer.h>
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/power_supply.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-
-/* register address */
-#define LP8788_CHG_STATUS 0x07
-#define LP8788_CHG_IDCIN 0x13
-#define LP8788_CHG_IBATT 0x14
-#define LP8788_CHG_VTERM 0x15
-#define LP8788_CHG_EOC 0x16
-
-/* mask/shift bits */
-#define LP8788_CHG_INPUT_STATE_M 0x03 /* Addr 07h */
-#define LP8788_CHG_STATE_M 0x3C
-#define LP8788_CHG_STATE_S 2
-#define LP8788_NO_BATT_M BIT(6)
-#define LP8788_BAD_BATT_M BIT(7)
-#define LP8788_CHG_IBATT_M 0x1F /* Addr 14h */
-#define LP8788_CHG_VTERM_M 0x0F /* Addr 15h */
-#define LP8788_CHG_EOC_LEVEL_M 0x30 /* Addr 16h */
-#define LP8788_CHG_EOC_LEVEL_S 4
-#define LP8788_CHG_EOC_TIME_M 0x0E
-#define LP8788_CHG_EOC_TIME_S 1
-#define LP8788_CHG_EOC_MODE_M BIT(0)
-
-#define LP8788_CHARGER_NAME "charger"
-#define LP8788_BATTERY_NAME "main_batt"
-
-#define LP8788_CHG_START 0x11
-#define LP8788_CHG_END 0x1C
-
-#define LP8788_ISEL_MAX 23
-#define LP8788_ISEL_STEP 50
-#define LP8788_VTERM_MIN 4100
-#define LP8788_VTERM_STEP 25
-#define LP8788_MAX_BATT_CAPACITY 100
-#define LP8788_MAX_CHG_IRQS 11
-
-enum lp8788_charging_state {
- LP8788_OFF,
- LP8788_WARM_UP,
- LP8788_LOW_INPUT = 0x3,
- LP8788_PRECHARGE,
- LP8788_CC,
- LP8788_CV,
- LP8788_MAINTENANCE,
- LP8788_BATTERY_FAULT,
- LP8788_SYSTEM_SUPPORT = 0xC,
- LP8788_HIGH_CURRENT = 0xF,
- LP8788_MAX_CHG_STATE,
-};
-
-enum lp8788_charger_adc_sel {
- LP8788_VBATT,
- LP8788_BATT_TEMP,
- LP8788_NUM_CHG_ADC,
-};
-
-enum lp8788_charger_input_state {
- LP8788_SYSTEM_SUPPLY = 1,
- LP8788_FULL_FUNCTION,
-};
-
-/*
- * struct lp8788_chg_irq
- * @which : lp8788 interrupt id
- * @virq : Linux IRQ number from irq_domain
- */
-struct lp8788_chg_irq {
- enum lp8788_int_id which;
- int virq;
-};
-
-/*
- * struct lp8788_charger
- * @lp : used for accessing the registers of mfd lp8788 device
- * @charger : power supply driver for the battery charger
- * @battery : power supply driver for the battery
- * @charger_work : work queue for charger input interrupts
- * @chan : iio channels for getting adc values
- * eg) battery voltage, capacity and temperature
- * @irqs : charger dedicated interrupts
- * @num_irqs : total numbers of charger interrupts
- * @pdata : charger platform specific data
- */
-struct lp8788_charger {
- struct lp8788 *lp;
- struct power_supply *charger;
- struct power_supply *battery;
- struct work_struct charger_work;
- struct iio_channel *chan[LP8788_NUM_CHG_ADC];
- struct lp8788_chg_irq irqs[LP8788_MAX_CHG_IRQS];
- int num_irqs;
- struct lp8788_charger_platform_data *pdata;
-};
-
-static char *battery_supplied_to[] = {
- LP8788_BATTERY_NAME,
-};
-
-static enum power_supply_property lp8788_charger_prop[] = {
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_CURRENT_MAX,
-};
-
-static enum power_supply_property lp8788_battery_prop[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
- POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
- POWER_SUPPLY_PROP_TEMP,
-};
-
-static bool lp8788_is_charger_detected(struct lp8788_charger *pchg)
-{
- u8 data;
-
- lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
- data &= LP8788_CHG_INPUT_STATE_M;
-
- return data == LP8788_SYSTEM_SUPPLY || data == LP8788_FULL_FUNCTION;
-}
-
-static int lp8788_charger_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct lp8788_charger *pchg = dev_get_drvdata(psy->dev.parent);
- u8 read;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = lp8788_is_charger_detected(pchg);
- break;
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- lp8788_read_byte(pchg->lp, LP8788_CHG_IDCIN, &read);
- val->intval = LP8788_ISEL_STEP *
- (min_t(int, read, LP8788_ISEL_MAX) + 1);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int lp8788_get_battery_status(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- enum lp8788_charging_state state;
- u8 data;
- int ret;
-
- ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
- if (ret)
- return ret;
-
- state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S;
- switch (state) {
- case LP8788_OFF:
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- break;
- case LP8788_PRECHARGE:
- case LP8788_CC:
- case LP8788_CV:
- case LP8788_HIGH_CURRENT:
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- break;
- case LP8788_MAINTENANCE:
- val->intval = POWER_SUPPLY_STATUS_FULL;
- break;
- default:
- val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
- break;
- }
-
- return 0;
-}
-
-static int lp8788_get_battery_health(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- u8 data;
- int ret;
-
- ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
- if (ret)
- return ret;
-
- if (data & LP8788_NO_BATT_M)
- val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
- else if (data & LP8788_BAD_BATT_M)
- val->intval = POWER_SUPPLY_HEALTH_DEAD;
- else
- val->intval = POWER_SUPPLY_HEALTH_GOOD;
-
- return 0;
-}
-
-static int lp8788_get_battery_present(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- u8 data;
- int ret;
-
- ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
- if (ret)
- return ret;
-
- val->intval = !(data & LP8788_NO_BATT_M);
- return 0;
-}
-
-static int lp8788_get_vbatt_adc(struct lp8788_charger *pchg, int *result)
-{
- struct iio_channel *channel = pchg->chan[LP8788_VBATT];
-
- if (!channel)
- return -EINVAL;
-
- return iio_read_channel_processed(channel, result);
-}
-
-static int lp8788_get_battery_voltage(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- return lp8788_get_vbatt_adc(pchg, &val->intval);
-}
-
-static int lp8788_get_battery_capacity(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- struct lp8788 *lp = pchg->lp;
- struct lp8788_charger_platform_data *pdata = pchg->pdata;
- unsigned int max_vbatt;
- int vbatt;
- enum lp8788_charging_state state;
- u8 data;
- int ret;
-
- if (!pdata)
- return -EINVAL;
-
- max_vbatt = pdata->max_vbatt_mv;
- if (max_vbatt == 0)
- return -EINVAL;
-
- ret = lp8788_read_byte(lp, LP8788_CHG_STATUS, &data);
- if (ret)
- return ret;
-
- state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S;
-
- if (state == LP8788_MAINTENANCE) {
- val->intval = LP8788_MAX_BATT_CAPACITY;
- } else {
- ret = lp8788_get_vbatt_adc(pchg, &vbatt);
- if (ret)
- return ret;
-
- val->intval = (vbatt * LP8788_MAX_BATT_CAPACITY) / max_vbatt;
- val->intval = min(val->intval, LP8788_MAX_BATT_CAPACITY);
- }
-
- return 0;
-}
-
-static int lp8788_get_battery_temperature(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- struct iio_channel *channel = pchg->chan[LP8788_BATT_TEMP];
- int result;
- int ret;
-
- if (!channel)
- return -EINVAL;
-
- ret = iio_read_channel_processed(channel, &result);
- if (ret < 0)
- return -EINVAL;
-
- /* unit: 0.1 'C */
- val->intval = result * 10;
-
- return 0;
-}
-
-static int lp8788_get_battery_charging_current(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- u8 read;
-
- lp8788_read_byte(pchg->lp, LP8788_CHG_IBATT, &read);
- read &= LP8788_CHG_IBATT_M;
- val->intval = LP8788_ISEL_STEP *
- (min_t(int, read, LP8788_ISEL_MAX) + 1);
-
- return 0;
-}
-
-static int lp8788_get_charging_termination_voltage(struct lp8788_charger *pchg,
- union power_supply_propval *val)
-{
- u8 read;
-
- lp8788_read_byte(pchg->lp, LP8788_CHG_VTERM, &read);
- read &= LP8788_CHG_VTERM_M;
- val->intval = LP8788_VTERM_MIN + LP8788_VTERM_STEP * read;
-
- return 0;
-}
-
-static int lp8788_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct lp8788_charger *pchg = dev_get_drvdata(psy->dev.parent);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- return lp8788_get_battery_status(pchg, val);
- case POWER_SUPPLY_PROP_HEALTH:
- return lp8788_get_battery_health(pchg, val);
- case POWER_SUPPLY_PROP_PRESENT:
- return lp8788_get_battery_present(pchg, val);
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- return lp8788_get_battery_voltage(pchg, val);
- case POWER_SUPPLY_PROP_CAPACITY:
- return lp8788_get_battery_capacity(pchg, val);
- case POWER_SUPPLY_PROP_TEMP:
- return lp8788_get_battery_temperature(pchg, val);
- case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
- return lp8788_get_battery_charging_current(pchg, val);
- case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
- return lp8788_get_charging_termination_voltage(pchg, val);
- default:
- return -EINVAL;
- }
-}
-
-static inline bool lp8788_is_valid_charger_register(u8 addr)
-{
- return addr >= LP8788_CHG_START && addr <= LP8788_CHG_END;
-}
-
-static int lp8788_update_charger_params(struct platform_device *pdev,
- struct lp8788_charger *pchg)
-{
- struct lp8788 *lp = pchg->lp;
- struct lp8788_charger_platform_data *pdata = pchg->pdata;
- struct lp8788_chg_param *param;
- int i;
- int ret;
-
- if (!pdata || !pdata->chg_params) {
- dev_info(&pdev->dev, "skip updating charger parameters\n");
- return 0;
- }
-
- /* setting charging parameters */
- for (i = 0; i < pdata->num_chg_params; i++) {
- param = pdata->chg_params + i;
-
- if (lp8788_is_valid_charger_register(param->addr)) {
- ret = lp8788_write_byte(lp, param->addr, param->val);
- if (ret)
- return ret;
- }
- }
-
- return 0;
-}
-
-static const struct power_supply_desc lp8788_psy_charger_desc = {
- .name = LP8788_CHARGER_NAME,
- .type = POWER_SUPPLY_TYPE_MAINS,
- .properties = lp8788_charger_prop,
- .num_properties = ARRAY_SIZE(lp8788_charger_prop),
- .get_property = lp8788_charger_get_property,
-};
-
-static const struct power_supply_desc lp8788_psy_battery_desc = {
- .name = LP8788_BATTERY_NAME,
- .type = POWER_SUPPLY_TYPE_BATTERY,
- .properties = lp8788_battery_prop,
- .num_properties = ARRAY_SIZE(lp8788_battery_prop),
- .get_property = lp8788_battery_get_property,
-};
-
-static void lp8788_charger_event(struct work_struct *work)
-{
- struct lp8788_charger *pchg =
- container_of(work, struct lp8788_charger, charger_work);
- struct lp8788_charger_platform_data *pdata = pchg->pdata;
- enum lp8788_charger_event event = lp8788_is_charger_detected(pchg);
-
- pdata->charger_event(pchg->lp, event);
-}
-
-static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id)
-{
- bool found = false;
- int i;
-
- for (i = 0; i < pchg->num_irqs; i++) {
- if (pchg->irqs[i].virq == virq) {
- *id = pchg->irqs[i].which;
- found = true;
- break;
- }
- }
-
- return found;
-}
-
-static irqreturn_t lp8788_charger_irq_thread(int virq, void *ptr)
-{
- struct lp8788_charger *pchg = ptr;
- struct lp8788_charger_platform_data *pdata = pchg->pdata;
- int id = -1;
-
- if (!lp8788_find_irq_id(pchg, virq, &id))
- return IRQ_NONE;
-
- switch (id) {
- case LP8788_INT_CHG_INPUT_STATE:
- case LP8788_INT_CHG_STATE:
- case LP8788_INT_EOC:
- case LP8788_INT_BATT_LOW:
- case LP8788_INT_NO_BATT:
- power_supply_changed(pchg->charger);
- power_supply_changed(pchg->battery);
- break;
- default:
- break;
- }
-
- /* report charger dectection event if used */
- if (!pdata)
- goto irq_handled;
-
- if (pdata->charger_event && id == LP8788_INT_CHG_INPUT_STATE)
- schedule_work(&pchg->charger_work);
-
-irq_handled:
- return IRQ_HANDLED;
-}
-
-static int lp8788_set_irqs(struct platform_device *pdev,
- struct lp8788_charger *pchg, const char *name)
-{
- struct resource *r;
- struct irq_domain *irqdm = pchg->lp->irqdm;
- int irq_start;
- int irq_end;
- int virq;
- int nr_irq;
- int i;
- int ret;
-
- /* no error even if no irq resource */
- r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, name);
- if (!r)
- return 0;
-
- irq_start = r->start;
- irq_end = r->end;
-
- for (i = irq_start; i <= irq_end; i++) {
- nr_irq = pchg->num_irqs;
-
- virq = irq_create_mapping(irqdm, i);
- pchg->irqs[nr_irq].virq = virq;
- pchg->irqs[nr_irq].which = i;
- pchg->num_irqs++;
-
- ret = request_threaded_irq(virq, NULL,
- lp8788_charger_irq_thread,
- IRQF_ONESHOT, name, pchg);
- if (ret)
- break;
- }
-
- if (i <= irq_end)
- goto err_free_irq;
-
- return 0;
-
-err_free_irq:
- for (i = 0; i < pchg->num_irqs; i++)
- free_irq(pchg->irqs[i].virq, pchg);
- return ret;
-}
-
-static int lp8788_irq_register(struct platform_device *pdev,
- struct lp8788_charger *pchg)
-{
- static const char * const name[] = {
- LP8788_CHG_IRQ, LP8788_PRSW_IRQ, LP8788_BATT_IRQ
- };
- int i;
- int ret;
-
- INIT_WORK(&pchg->charger_work, lp8788_charger_event);
- pchg->num_irqs = 0;
-
- for (i = 0; i < ARRAY_SIZE(name); i++) {
- ret = lp8788_set_irqs(pdev, pchg, name[i]);
- if (ret) {
- dev_warn(&pdev->dev, "irq setup failed: %s\n", name[i]);
- return ret;
- }
- }
-
- if (pchg->num_irqs > LP8788_MAX_CHG_IRQS) {
- dev_err(&pdev->dev, "invalid total number of irqs: %d\n",
- pchg->num_irqs);
- return -EINVAL;
- }
-
-
- return 0;
-}
-
-static void lp8788_irq_unregister(struct platform_device *pdev,
- struct lp8788_charger *pchg)
-{
- int i;
- int irq;
-
- for (i = 0; i < pchg->num_irqs; i++) {
- irq = pchg->irqs[i].virq;
- if (!irq)
- continue;
-
- free_irq(irq, pchg);
- }
-}
-
-static void lp8788_setup_adc_channel(struct device *dev,
- struct lp8788_charger *pchg)
-{
- struct lp8788_charger_platform_data *pdata = pchg->pdata;
- struct iio_channel *chan;
-
- if (!pdata)
- return;
-
- /* ADC channel for battery voltage */
- chan = devm_iio_channel_get(dev, pdata->adc_vbatt);
- pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan;
-
- /* ADC channel for battery temperature */
- chan = devm_iio_channel_get(dev, pdata->adc_batt_temp);
- pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan;
-}
-
-static ssize_t lp8788_show_charger_status(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lp8788_charger *pchg = dev_get_drvdata(dev);
- enum lp8788_charging_state state;
- static const char * const desc[LP8788_MAX_CHG_STATE] = {
- [LP8788_OFF] = "CHARGER OFF",
- [LP8788_WARM_UP] = "WARM UP",
- [LP8788_LOW_INPUT] = "LOW INPUT STATE",
- [LP8788_PRECHARGE] = "CHARGING - PRECHARGE",
- [LP8788_CC] = "CHARGING - CC",
- [LP8788_CV] = "CHARGING - CV",
- [LP8788_MAINTENANCE] = "NO CHARGING - MAINTENANCE",
- [LP8788_BATTERY_FAULT] = "BATTERY FAULT",
- [LP8788_SYSTEM_SUPPORT] = "SYSTEM SUPPORT",
- [LP8788_HIGH_CURRENT] = "HIGH CURRENT",
- };
- u8 data;
-
- lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
- state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S;
-
- return sysfs_emit(buf, "%s\n", desc[state]);
-}
-
-static ssize_t lp8788_show_eoc_time(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lp8788_charger *pchg = dev_get_drvdata(dev);
- static const char * const stime[] = {
- "400ms", "5min", "10min", "15min",
- "20min", "25min", "30min", "No timeout"
- };
- u8 val;
-
- lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val);
- val = (val & LP8788_CHG_EOC_TIME_M) >> LP8788_CHG_EOC_TIME_S;
-
- return sysfs_emit(buf, "End Of Charge Time: %s\n", stime[val]);
-}
-
-static ssize_t lp8788_show_eoc_level(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lp8788_charger *pchg = dev_get_drvdata(dev);
- static const char * const abs_level[] = {
- "25mA", "49mA", "75mA", "98mA"
- };
- static const char * const relative_level[] = {
- "5%", "10%", "15%", "20%"
- };
- const char *level;
- u8 val;
- u8 mode;
-
- lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val);
-
- mode = val & LP8788_CHG_EOC_MODE_M;
- val = (val & LP8788_CHG_EOC_LEVEL_M) >> LP8788_CHG_EOC_LEVEL_S;
- level = mode ? abs_level[val] : relative_level[val];
-
- return sysfs_emit(buf, "End Of Charge Level: %s\n", level);
-}
-
-static DEVICE_ATTR(charger_status, S_IRUSR, lp8788_show_charger_status, NULL);
-static DEVICE_ATTR(eoc_time, S_IRUSR, lp8788_show_eoc_time, NULL);
-static DEVICE_ATTR(eoc_level, S_IRUSR, lp8788_show_eoc_level, NULL);
-
-static struct attribute *lp8788_charger_sysfs_attrs[] = {
- &dev_attr_charger_status.attr,
- &dev_attr_eoc_time.attr,
- &dev_attr_eoc_level.attr,
- NULL,
-};
-
-ATTRIBUTE_GROUPS(lp8788_charger_sysfs);
-
-static int lp8788_psy_register(struct platform_device *pdev,
- struct lp8788_charger *pchg)
-{
- struct power_supply_config charger_cfg = {};
-
- charger_cfg.attr_grp = lp8788_charger_sysfs_groups;
- charger_cfg.supplied_to = battery_supplied_to;
- charger_cfg.num_supplicants = ARRAY_SIZE(battery_supplied_to);
-
- pchg->charger = devm_power_supply_register(&pdev->dev,
- &lp8788_psy_charger_desc,
- &charger_cfg);
- if (IS_ERR(pchg->charger))
- return -EPERM;
-
- pchg->battery = devm_power_supply_register(&pdev->dev,
- &lp8788_psy_battery_desc, NULL);
- if (IS_ERR(pchg->battery))
- return -EPERM;
-
- return 0;
-}
-
-static int lp8788_charger_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- struct lp8788_charger *pchg;
- struct device *dev = &pdev->dev;
- int ret;
-
- pchg = devm_kzalloc(dev, sizeof(struct lp8788_charger), GFP_KERNEL);
- if (!pchg)
- return -ENOMEM;
-
- pchg->lp = lp;
- pchg->pdata = lp->pdata ? lp->pdata->chg_pdata : NULL;
- platform_set_drvdata(pdev, pchg);
-
- ret = lp8788_update_charger_params(pdev, pchg);
- if (ret)
- return ret;
-
- lp8788_setup_adc_channel(&pdev->dev, pchg);
-
- ret = lp8788_psy_register(pdev, pchg);
- if (ret)
- return ret;
-
- ret = lp8788_irq_register(pdev, pchg);
- if (ret)
- dev_warn(dev, "failed to register charger irq: %d\n", ret);
-
- return 0;
-}
-
-static void lp8788_charger_remove(struct platform_device *pdev)
-{
- struct lp8788_charger *pchg = platform_get_drvdata(pdev);
-
- lp8788_irq_unregister(pdev, pchg);
- cancel_work_sync(&pchg->charger_work);
-}
-
-static struct platform_driver lp8788_charger_driver = {
- .probe = lp8788_charger_probe,
- .remove = lp8788_charger_remove,
- .driver = {
- .name = LP8788_DEV_CHARGER,
- },
-};
-module_platform_driver(lp8788_charger_driver);
-
-MODULE_DESCRIPTION("TI LP8788 Charger Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lp8788-charger");
-MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7d587ffc0a89..4b90d1cb045c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -555,12 +555,6 @@ config REGULATOR_LP87565
provides four step-down converters. It supports software based
voltage control for different voltage domains
-config REGULATOR_LP8788
- tristate "TI LP8788 Power Regulators"
- depends on MFD_LP8788
- help
- This driver supports LP8788 voltage regulator chip.
-
config REGULATOR_LTC3589
tristate "LTC3589 8-output voltage regulator"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index a1344d3c3fd3..fe0f099c217b 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -65,8 +65,6 @@ obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o
obj-$(CONFIG_REGULATOR_LP873X) += lp873x-regulator.o
obj-$(CONFIG_REGULATOR_LP87565) += lp87565-regulator.o
-obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o
-obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c
deleted file mode 100644
index 2ade249ab6df..000000000000
--- a/drivers/regulator/lp8788-buck.c
+++ /dev/null
@@ -1,541 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - buck regulator driver
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/gpio/consumer.h>
-
-/* register address */
-#define LP8788_EN_BUCK 0x0C
-#define LP8788_BUCK_DVS_SEL 0x1D
-#define LP8788_BUCK1_VOUT0 0x1E
-#define LP8788_BUCK1_VOUT1 0x1F
-#define LP8788_BUCK1_VOUT2 0x20
-#define LP8788_BUCK1_VOUT3 0x21
-#define LP8788_BUCK2_VOUT0 0x22
-#define LP8788_BUCK2_VOUT1 0x23
-#define LP8788_BUCK2_VOUT2 0x24
-#define LP8788_BUCK2_VOUT3 0x25
-#define LP8788_BUCK3_VOUT 0x26
-#define LP8788_BUCK4_VOUT 0x27
-#define LP8788_BUCK1_TIMESTEP 0x28
-#define LP8788_BUCK_PWM 0x2D
-
-/* mask/shift bits */
-#define LP8788_EN_BUCK1_M BIT(0) /* Addr 0Ch */
-#define LP8788_EN_BUCK2_M BIT(1)
-#define LP8788_EN_BUCK3_M BIT(2)
-#define LP8788_EN_BUCK4_M BIT(3)
-#define LP8788_BUCK1_DVS_SEL_M 0x04 /* Addr 1Dh */
-#define LP8788_BUCK1_DVS_M 0x03
-#define LP8788_BUCK1_DVS_S 0
-#define LP8788_BUCK2_DVS_SEL_M 0x40
-#define LP8788_BUCK2_DVS_M 0x30
-#define LP8788_BUCK2_DVS_S 4
-#define LP8788_BUCK1_DVS_I2C BIT(2)
-#define LP8788_BUCK2_DVS_I2C BIT(6)
-#define LP8788_BUCK1_DVS_PIN (0 << 2)
-#define LP8788_BUCK2_DVS_PIN (0 << 6)
-#define LP8788_VOUT_M 0x1F /* Addr 1Eh ~ 27h */
-#define LP8788_STARTUP_TIME_M 0xF8 /* Addr 28h ~ 2Bh */
-#define LP8788_STARTUP_TIME_S 3
-#define LP8788_FPWM_BUCK1_M BIT(0) /* Addr 2Dh */
-#define LP8788_FPWM_BUCK1_S 0
-#define LP8788_FPWM_BUCK2_M BIT(1)
-#define LP8788_FPWM_BUCK2_S 1
-#define LP8788_FPWM_BUCK3_M BIT(2)
-#define LP8788_FPWM_BUCK3_S 2
-#define LP8788_FPWM_BUCK4_M BIT(3)
-#define LP8788_FPWM_BUCK4_S 3
-
-#define INVALID_ADDR 0xFF
-#define LP8788_FORCE_PWM 1
-#define LP8788_AUTO_PWM 0
-#define PIN_LOW 0
-#define PIN_HIGH 1
-#define ENABLE_TIME_USEC 32
-
-#define BUCK_FPWM_MASK(x) (1 << (x))
-#define BUCK_FPWM_SHIFT(x) (x)
-
-enum lp8788_dvs_state {
- DVS_LOW = 0,
- DVS_HIGH = 1,
-};
-
-enum lp8788_dvs_mode {
- REGISTER,
- EXTPIN,
-};
-
-enum lp8788_buck_id {
- BUCK1,
- BUCK2,
- BUCK3,
- BUCK4,
-};
-
-struct lp8788_buck {
- struct lp8788 *lp;
- struct regulator_dev *regulator;
- void *dvs;
- struct gpio_desc *gpio1;
- struct gpio_desc *gpio2; /* Only used on BUCK2 */
-};
-
-/* BUCK 1 ~ 4 voltage ranges */
-static const struct linear_range buck_volt_ranges[] = {
- REGULATOR_LINEAR_RANGE(500000, 0, 0, 0),
- REGULATOR_LINEAR_RANGE(800000, 1, 25, 50000),
-};
-
-static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
-{
- struct lp8788_buck1_dvs *dvs = (struct lp8788_buck1_dvs *)buck->dvs;
- enum lp8788_dvs_state pinstate;
-
- if (!dvs)
- return;
-
- pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH;
- gpiod_set_value(buck->gpio1, pinstate);
-}
-
-static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
-{
- struct lp8788_buck2_dvs *dvs = (struct lp8788_buck2_dvs *)buck->dvs;
- enum lp8788_dvs_state pin1, pin2;
-
- if (!dvs)
- return;
-
- switch (dvs->vsel) {
- case DVS_SEL_V0:
- pin1 = DVS_LOW;
- pin2 = DVS_LOW;
- break;
- case DVS_SEL_V1:
- pin1 = DVS_HIGH;
- pin2 = DVS_LOW;
- break;
- case DVS_SEL_V2:
- pin1 = DVS_LOW;
- pin2 = DVS_HIGH;
- break;
- case DVS_SEL_V3:
- pin1 = DVS_HIGH;
- pin2 = DVS_HIGH;
- break;
- default:
- return;
- }
-
- gpiod_set_value(buck->gpio1, pin1);
- gpiod_set_value(buck->gpio2, pin2);
-}
-
-static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
-{
- switch (id) {
- case BUCK1:
- lp8788_buck1_set_dvs(buck);
- break;
- case BUCK2:
- lp8788_buck2_set_dvs(buck);
- break;
- default:
- break;
- }
-}
-
-static enum lp8788_dvs_mode
-lp8788_get_buck_dvs_ctrl_mode(struct lp8788_buck *buck, enum lp8788_buck_id id)
-{
- u8 val, mask;
-
- switch (id) {
- case BUCK1:
- mask = LP8788_BUCK1_DVS_SEL_M;
- break;
- case BUCK2:
- mask = LP8788_BUCK2_DVS_SEL_M;
- break;
- default:
- return REGISTER;
- }
-
- lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
-
- return val & mask ? REGISTER : EXTPIN;
-}
-
-static bool lp8788_is_valid_buck_addr(u8 addr)
-{
- switch (addr) {
- case LP8788_BUCK1_VOUT0:
- case LP8788_BUCK1_VOUT1:
- case LP8788_BUCK1_VOUT2:
- case LP8788_BUCK1_VOUT3:
- case LP8788_BUCK2_VOUT0:
- case LP8788_BUCK2_VOUT1:
- case LP8788_BUCK2_VOUT2:
- case LP8788_BUCK2_VOUT3:
- return true;
- default:
- return false;
- }
-}
-
-static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
- enum lp8788_buck_id id)
-{
- enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id);
- u8 val, idx, addr;
- int pin1, pin2;
-
- switch (id) {
- case BUCK1:
- if (mode == EXTPIN) {
- idx = gpiod_get_value(buck->gpio1);
- } else {
- lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
- idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S;
- }
- addr = LP8788_BUCK1_VOUT0 + idx;
- break;
- case BUCK2:
- if (mode == EXTPIN) {
- pin1 = gpiod_get_value(buck->gpio1);
- pin2 = gpiod_get_value(buck->gpio2);
-
- if (pin1 == PIN_LOW && pin2 == PIN_LOW)
- idx = 0;
- else if (pin1 == PIN_LOW && pin2 == PIN_HIGH)
- idx = 2;
- else if (pin1 == PIN_HIGH && pin2 == PIN_LOW)
- idx = 1;
- else
- idx = 3;
- } else {
- lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
- idx = (val & LP8788_BUCK2_DVS_M) >> LP8788_BUCK2_DVS_S;
- }
- addr = LP8788_BUCK2_VOUT0 + idx;
- break;
- default:
- goto err;
- }
-
- return addr;
-err:
- return INVALID_ADDR;
-}
-
-static int lp8788_buck12_set_voltage_sel(struct regulator_dev *rdev,
- unsigned selector)
-{
- struct lp8788_buck *buck = rdev_get_drvdata(rdev);
- enum lp8788_buck_id id = rdev_get_id(rdev);
- u8 addr;
-
- if (buck->dvs)
- lp8788_set_dvs(buck, id);
-
- addr = lp8788_select_buck_vout_addr(buck, id);
- if (!lp8788_is_valid_buck_addr(addr))
- return -EINVAL;
-
- return lp8788_update_bits(buck->lp, addr, LP8788_VOUT_M, selector);
-}
-
-static int lp8788_buck12_get_voltage_sel(struct regulator_dev *rdev)
-{
- struct lp8788_buck *buck = rdev_get_drvdata(rdev);
- enum lp8788_buck_id id = rdev_get_id(rdev);
- int ret;
- u8 val, addr;
-
- addr = lp8788_select_buck_vout_addr(buck, id);
- if (!lp8788_is_valid_buck_addr(addr))
- return -EINVAL;
-
- ret = lp8788_read_byte(buck->lp, addr, &val);
- if (ret)
- return ret;
-
- return val & LP8788_VOUT_M;
-}
-
-static int lp8788_buck_enable_time(struct regulator_dev *rdev)
-{
- struct lp8788_buck *buck = rdev_get_drvdata(rdev);
- enum lp8788_buck_id id = rdev_get_id(rdev);
- u8 val, addr = LP8788_BUCK1_TIMESTEP + id;
-
- if (lp8788_read_byte(buck->lp, addr, &val))
- return -EINVAL;
-
- val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
-
- return ENABLE_TIME_USEC * val;
-}
-
-static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
-{
- struct lp8788_buck *buck = rdev_get_drvdata(rdev);
- enum lp8788_buck_id id = rdev_get_id(rdev);
- u8 mask, val;
-
- mask = BUCK_FPWM_MASK(id);
- switch (mode) {
- case REGULATOR_MODE_FAST:
- val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id);
- break;
- case REGULATOR_MODE_NORMAL:
- val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id);
- break;
- default:
- return -EINVAL;
- }
-
- return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val);
-}
-
-static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev)
-{
- struct lp8788_buck *buck = rdev_get_drvdata(rdev);
- enum lp8788_buck_id id = rdev_get_id(rdev);
- u8 val;
- int ret;
-
- ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val);
- if (ret)
- return ret;
-
- return val & BUCK_FPWM_MASK(id) ?
- REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
-}
-
-static const struct regulator_ops lp8788_buck12_ops = {
- .list_voltage = regulator_list_voltage_linear_range,
- .map_voltage = regulator_map_voltage_linear_range,
- .set_voltage_sel = lp8788_buck12_set_voltage_sel,
- .get_voltage_sel = lp8788_buck12_get_voltage_sel,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .enable_time = lp8788_buck_enable_time,
- .set_mode = lp8788_buck_set_mode,
- .get_mode = lp8788_buck_get_mode,
-};
-
-static const struct regulator_ops lp8788_buck34_ops = {
- .list_voltage = regulator_list_voltage_linear_range,
- .map_voltage = regulator_map_voltage_linear_range,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .enable_time = lp8788_buck_enable_time,
- .set_mode = lp8788_buck_set_mode,
- .get_mode = lp8788_buck_get_mode,
-};
-
-static const struct regulator_desc lp8788_buck_desc[] = {
- {
- .name = "buck1",
- .id = BUCK1,
- .ops = &lp8788_buck12_ops,
- .n_voltages = 26,
- .linear_ranges = buck_volt_ranges,
- .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_BUCK,
- .enable_mask = LP8788_EN_BUCK1_M,
- },
- {
- .name = "buck2",
- .id = BUCK2,
- .ops = &lp8788_buck12_ops,
- .n_voltages = 26,
- .linear_ranges = buck_volt_ranges,
- .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_BUCK,
- .enable_mask = LP8788_EN_BUCK2_M,
- },
- {
- .name = "buck3",
- .id = BUCK3,
- .ops = &lp8788_buck34_ops,
- .n_voltages = 26,
- .linear_ranges = buck_volt_ranges,
- .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_BUCK3_VOUT,
- .vsel_mask = LP8788_VOUT_M,
- .enable_reg = LP8788_EN_BUCK,
- .enable_mask = LP8788_EN_BUCK3_M,
- },
- {
- .name = "buck4",
- .id = BUCK4,
- .ops = &lp8788_buck34_ops,
- .n_voltages = 26,
- .linear_ranges = buck_volt_ranges,
- .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_BUCK4_VOUT,
- .vsel_mask = LP8788_VOUT_M,
- .enable_reg = LP8788_EN_BUCK,
- .enable_mask = LP8788_EN_BUCK4_M,
- },
-};
-
-static int lp8788_dvs_gpio_request(struct platform_device *pdev,
- struct lp8788_buck *buck,
- enum lp8788_buck_id id)
-{
- struct lp8788_platform_data *pdata = buck->lp->pdata;
- struct device *dev = &pdev->dev;
-
- switch (id) {
- case BUCK1:
- buck->gpio1 = devm_gpiod_get(dev, "dvs", GPIOD_OUT_LOW);
- if (IS_ERR(buck->gpio1))
- return PTR_ERR(buck->gpio1);
- gpiod_set_consumer_name(buck->gpio1, "LP8788_B1_DVS");
-
- buck->dvs = pdata->buck1_dvs;
- break;
- case BUCK2:
- buck->gpio1 = devm_gpiod_get_index(dev, "dvs", 0, GPIOD_OUT_LOW);
- if (IS_ERR(buck->gpio1))
- return PTR_ERR(buck->gpio1);
- gpiod_set_consumer_name(buck->gpio1, "LP8788_B2_DVS1");
-
- buck->gpio2 = devm_gpiod_get_index(dev, "dvs", 1, GPIOD_OUT_LOW);
- if (IS_ERR(buck->gpio2))
- return PTR_ERR(buck->gpio2);
- gpiod_set_consumer_name(buck->gpio2, "LP8788_B2_DVS2");
-
- buck->dvs = pdata->buck2_dvs;
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int lp8788_init_dvs(struct platform_device *pdev,
- struct lp8788_buck *buck, enum lp8788_buck_id id)
-{
- struct lp8788_platform_data *pdata = buck->lp->pdata;
- u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M };
- u8 val[] = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN };
- u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C };
-
- /* no dvs for buck3, 4 */
- if (id > BUCK2)
- return 0;
-
- /* no dvs platform data, then dvs will be selected by I2C registers */
- if (!pdata)
- goto set_default_dvs_mode;
-
- if ((id == BUCK1 && !pdata->buck1_dvs) ||
- (id == BUCK2 && !pdata->buck2_dvs))
- goto set_default_dvs_mode;
-
- if (lp8788_dvs_gpio_request(pdev, buck, id))
- goto set_default_dvs_mode;
-
- return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
- val[id]);
-
-set_default_dvs_mode:
- return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
- default_dvs_mode[id]);
-}
-
-static int lp8788_buck_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- int id = pdev->id;
- struct lp8788_buck *buck;
- struct regulator_config cfg = { };
- struct regulator_dev *rdev;
- int ret;
-
- if (id >= LP8788_NUM_BUCKS)
- return -EINVAL;
-
- buck = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_buck), GFP_KERNEL);
- if (!buck)
- return -ENOMEM;
-
- buck->lp = lp;
-
- ret = lp8788_init_dvs(pdev, buck, id);
- if (ret)
- return ret;
-
- cfg.dev = pdev->dev.parent;
- cfg.init_data = lp->pdata ? lp->pdata->buck_data[id] : NULL;
- cfg.driver_data = buck;
- cfg.regmap = lp->regmap;
-
- rdev = devm_regulator_register(&pdev->dev, &lp8788_buck_desc[id], &cfg);
- if (IS_ERR(rdev)) {
- ret = PTR_ERR(rdev);
- dev_err(&pdev->dev, "BUCK%d regulator register err = %d\n",
- id + 1, ret);
- return ret;
- }
-
- buck->regulator = rdev;
- platform_set_drvdata(pdev, buck);
-
- return 0;
-}
-
-static struct platform_driver lp8788_buck_driver = {
- .probe = lp8788_buck_probe,
- .driver = {
- .name = LP8788_DEV_BUCK,
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
-};
-
-static int __init lp8788_buck_init(void)
-{
- return platform_driver_register(&lp8788_buck_driver);
-}
-subsys_initcall(lp8788_buck_init);
-
-static void __exit lp8788_buck_exit(void)
-{
- platform_driver_unregister(&lp8788_buck_driver);
-}
-module_exit(lp8788_buck_exit);
-
-MODULE_DESCRIPTION("TI LP8788 BUCK Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lp8788-buck");
diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c
deleted file mode 100644
index 8e45b7b99556..000000000000
--- a/drivers/regulator/lp8788-ldo.c
+++ /dev/null
@@ -1,640 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - ldo regulator driver
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/gpio/consumer.h>
-#include <linux/mfd/lp8788.h>
-
-/* register address */
-#define LP8788_EN_LDO_A 0x0D /* DLDO 1 ~ 8 */
-#define LP8788_EN_LDO_B 0x0E /* DLDO 9 ~ 12, ALDO 1 ~ 4 */
-#define LP8788_EN_LDO_C 0x0F /* ALDO 5 ~ 10 */
-#define LP8788_EN_SEL 0x10
-#define LP8788_DLDO1_VOUT 0x2E
-#define LP8788_DLDO2_VOUT 0x2F
-#define LP8788_DLDO3_VOUT 0x30
-#define LP8788_DLDO4_VOUT 0x31
-#define LP8788_DLDO5_VOUT 0x32
-#define LP8788_DLDO6_VOUT 0x33
-#define LP8788_DLDO7_VOUT 0x34
-#define LP8788_DLDO8_VOUT 0x35
-#define LP8788_DLDO9_VOUT 0x36
-#define LP8788_DLDO10_VOUT 0x37
-#define LP8788_DLDO11_VOUT 0x38
-#define LP8788_DLDO12_VOUT 0x39
-#define LP8788_ALDO1_VOUT 0x3A
-#define LP8788_ALDO2_VOUT 0x3B
-#define LP8788_ALDO3_VOUT 0x3C
-#define LP8788_ALDO4_VOUT 0x3D
-#define LP8788_ALDO5_VOUT 0x3E
-#define LP8788_ALDO6_VOUT 0x3F
-#define LP8788_ALDO7_VOUT 0x40
-#define LP8788_ALDO8_VOUT 0x41
-#define LP8788_ALDO9_VOUT 0x42
-#define LP8788_ALDO10_VOUT 0x43
-#define LP8788_DLDO1_TIMESTEP 0x44
-
-/* mask/shift bits */
-#define LP8788_EN_DLDO1_M BIT(0) /* Addr 0Dh ~ 0Fh */
-#define LP8788_EN_DLDO2_M BIT(1)
-#define LP8788_EN_DLDO3_M BIT(2)
-#define LP8788_EN_DLDO4_M BIT(3)
-#define LP8788_EN_DLDO5_M BIT(4)
-#define LP8788_EN_DLDO6_M BIT(5)
-#define LP8788_EN_DLDO7_M BIT(6)
-#define LP8788_EN_DLDO8_M BIT(7)
-#define LP8788_EN_DLDO9_M BIT(0)
-#define LP8788_EN_DLDO10_M BIT(1)
-#define LP8788_EN_DLDO11_M BIT(2)
-#define LP8788_EN_DLDO12_M BIT(3)
-#define LP8788_EN_ALDO1_M BIT(4)
-#define LP8788_EN_ALDO2_M BIT(5)
-#define LP8788_EN_ALDO3_M BIT(6)
-#define LP8788_EN_ALDO4_M BIT(7)
-#define LP8788_EN_ALDO5_M BIT(0)
-#define LP8788_EN_ALDO6_M BIT(1)
-#define LP8788_EN_ALDO7_M BIT(2)
-#define LP8788_EN_ALDO8_M BIT(3)
-#define LP8788_EN_ALDO9_M BIT(4)
-#define LP8788_EN_ALDO10_M BIT(5)
-#define LP8788_EN_SEL_DLDO911_M BIT(0) /* Addr 10h */
-#define LP8788_EN_SEL_DLDO7_M BIT(1)
-#define LP8788_EN_SEL_ALDO7_M BIT(2)
-#define LP8788_EN_SEL_ALDO5_M BIT(3)
-#define LP8788_EN_SEL_ALDO234_M BIT(4)
-#define LP8788_EN_SEL_ALDO1_M BIT(5)
-#define LP8788_VOUT_5BIT_M 0x1F /* Addr 2Eh ~ 43h */
-#define LP8788_VOUT_4BIT_M 0x0F
-#define LP8788_VOUT_3BIT_M 0x07
-#define LP8788_VOUT_1BIT_M 0x01
-#define LP8788_STARTUP_TIME_M 0xF8 /* Addr 44h ~ 59h */
-#define LP8788_STARTUP_TIME_S 3
-
-#define ENABLE_TIME_USEC 32
-
-enum lp8788_ldo_id {
- DLDO1,
- DLDO2,
- DLDO3,
- DLDO4,
- DLDO5,
- DLDO6,
- DLDO7,
- DLDO8,
- DLDO9,
- DLDO10,
- DLDO11,
- DLDO12,
- ALDO1,
- ALDO2,
- ALDO3,
- ALDO4,
- ALDO5,
- ALDO6,
- ALDO7,
- ALDO8,
- ALDO9,
- ALDO10,
-};
-
-struct lp8788_ldo {
- struct lp8788 *lp;
- struct regulator_desc *desc;
- struct regulator_dev *regulator;
- struct gpio_desc *ena_gpiod;
-};
-
-/* DLDO 1, 2, 3, 9 voltage table */
-static const int lp8788_dldo1239_vtbl[] = {
- 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
- 2600000, 2700000, 2800000, 2900000, 3000000, 2850000, 2850000, 2850000,
- 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000,
- 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000,
-};
-
-/* DLDO 4 voltage table */
-static const int lp8788_dldo4_vtbl[] = { 1800000, 3000000 };
-
-/* DLDO 5, 7, 8 and ALDO 6 voltage table */
-static const int lp8788_dldo578_aldo6_vtbl[] = {
- 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
- 2600000, 2700000, 2800000, 2900000, 3000000, 3000000, 3000000, 3000000,
-};
-
-/* DLDO 6 voltage table */
-static const int lp8788_dldo6_vtbl[] = {
- 3000000, 3100000, 3200000, 3300000, 3400000, 3500000, 3600000, 3600000,
-};
-
-/* DLDO 10, 11 voltage table */
-static const int lp8788_dldo1011_vtbl[] = {
- 1100000, 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000,
- 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000,
-};
-
-/* ALDO 1 voltage table */
-static const int lp8788_aldo1_vtbl[] = { 1800000, 2850000 };
-
-/* ALDO 7 voltage table */
-static const int lp8788_aldo7_vtbl[] = {
- 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000,
-};
-
-static int lp8788_ldo_enable_time(struct regulator_dev *rdev)
-{
- struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
- enum lp8788_ldo_id id = rdev_get_id(rdev);
- u8 val, addr = LP8788_DLDO1_TIMESTEP + id;
-
- if (lp8788_read_byte(ldo->lp, addr, &val))
- return -EINVAL;
-
- val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
-
- return ENABLE_TIME_USEC * val;
-}
-
-static const struct regulator_ops lp8788_ldo_voltage_table_ops = {
- .list_voltage = regulator_list_voltage_table,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .enable_time = lp8788_ldo_enable_time,
-};
-
-static const struct regulator_ops lp8788_ldo_voltage_fixed_ops = {
- .list_voltage = regulator_list_voltage_linear,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .enable_time = lp8788_ldo_enable_time,
-};
-
-static const struct regulator_desc lp8788_dldo_desc[] = {
- {
- .name = "dldo1",
- .id = DLDO1,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
- .volt_table = lp8788_dldo1239_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO1_VOUT,
- .vsel_mask = LP8788_VOUT_5BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO1_M,
- },
- {
- .name = "dldo2",
- .id = DLDO2,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
- .volt_table = lp8788_dldo1239_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO2_VOUT,
- .vsel_mask = LP8788_VOUT_5BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO2_M,
- },
- {
- .name = "dldo3",
- .id = DLDO3,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
- .volt_table = lp8788_dldo1239_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO3_VOUT,
- .vsel_mask = LP8788_VOUT_5BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO3_M,
- },
- {
- .name = "dldo4",
- .id = DLDO4,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo4_vtbl),
- .volt_table = lp8788_dldo4_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO4_VOUT,
- .vsel_mask = LP8788_VOUT_1BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO4_M,
- },
- {
- .name = "dldo5",
- .id = DLDO5,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
- .volt_table = lp8788_dldo578_aldo6_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO5_VOUT,
- .vsel_mask = LP8788_VOUT_4BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO5_M,
- },
- {
- .name = "dldo6",
- .id = DLDO6,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo6_vtbl),
- .volt_table = lp8788_dldo6_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO6_VOUT,
- .vsel_mask = LP8788_VOUT_3BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO6_M,
- },
- {
- .name = "dldo7",
- .id = DLDO7,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
- .volt_table = lp8788_dldo578_aldo6_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO7_VOUT,
- .vsel_mask = LP8788_VOUT_4BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO7_M,
- },
- {
- .name = "dldo8",
- .id = DLDO8,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
- .volt_table = lp8788_dldo578_aldo6_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO8_VOUT,
- .vsel_mask = LP8788_VOUT_4BIT_M,
- .enable_reg = LP8788_EN_LDO_A,
- .enable_mask = LP8788_EN_DLDO8_M,
- },
- {
- .name = "dldo9",
- .id = DLDO9,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
- .volt_table = lp8788_dldo1239_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO9_VOUT,
- .vsel_mask = LP8788_VOUT_5BIT_M,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_DLDO9_M,
- },
- {
- .name = "dldo10",
- .id = DLDO10,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
- .volt_table = lp8788_dldo1011_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO10_VOUT,
- .vsel_mask = LP8788_VOUT_4BIT_M,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_DLDO10_M,
- },
- {
- .name = "dldo11",
- .id = DLDO11,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
- .volt_table = lp8788_dldo1011_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_DLDO11_VOUT,
- .vsel_mask = LP8788_VOUT_4BIT_M,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_DLDO11_M,
- },
- {
- .name = "dldo12",
- .id = DLDO12,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_DLDO12_M,
- .min_uV = 2500000,
- },
-};
-
-static const struct regulator_desc lp8788_aldo_desc[] = {
- {
- .name = "aldo1",
- .id = ALDO1,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_aldo1_vtbl),
- .volt_table = lp8788_aldo1_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_ALDO1_VOUT,
- .vsel_mask = LP8788_VOUT_1BIT_M,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_ALDO1_M,
- },
- {
- .name = "aldo2",
- .id = ALDO2,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_ALDO2_M,
- .min_uV = 2850000,
- },
- {
- .name = "aldo3",
- .id = ALDO3,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_ALDO3_M,
- .min_uV = 2850000,
- },
- {
- .name = "aldo4",
- .id = ALDO4,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_B,
- .enable_mask = LP8788_EN_ALDO4_M,
- .min_uV = 2850000,
- },
- {
- .name = "aldo5",
- .id = ALDO5,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_C,
- .enable_mask = LP8788_EN_ALDO5_M,
- .min_uV = 2850000,
- },
- {
- .name = "aldo6",
- .id = ALDO6,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
- .volt_table = lp8788_dldo578_aldo6_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_ALDO6_VOUT,
- .vsel_mask = LP8788_VOUT_4BIT_M,
- .enable_reg = LP8788_EN_LDO_C,
- .enable_mask = LP8788_EN_ALDO6_M,
- },
- {
- .name = "aldo7",
- .id = ALDO7,
- .ops = &lp8788_ldo_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lp8788_aldo7_vtbl),
- .volt_table = lp8788_aldo7_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LP8788_ALDO7_VOUT,
- .vsel_mask = LP8788_VOUT_3BIT_M,
- .enable_reg = LP8788_EN_LDO_C,
- .enable_mask = LP8788_EN_ALDO7_M,
- },
- {
- .name = "aldo8",
- .id = ALDO8,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_C,
- .enable_mask = LP8788_EN_ALDO8_M,
- .min_uV = 2500000,
- },
- {
- .name = "aldo9",
- .id = ALDO9,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_C,
- .enable_mask = LP8788_EN_ALDO9_M,
- .min_uV = 2500000,
- },
- {
- .name = "aldo10",
- .id = ALDO10,
- .ops = &lp8788_ldo_voltage_fixed_ops,
- .n_voltages = 1,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .enable_reg = LP8788_EN_LDO_C,
- .enable_mask = LP8788_EN_ALDO10_M,
- .min_uV = 1100000,
- },
-};
-
-static int lp8788_config_ldo_enable_mode(struct platform_device *pdev,
- struct lp8788_ldo *ldo,
- enum lp8788_ldo_id id)
-{
- struct lp8788 *lp = ldo->lp;
- enum lp8788_ext_ldo_en_id enable_id;
- static const u8 en_mask[] = {
- [EN_ALDO1] = LP8788_EN_SEL_ALDO1_M,
- [EN_ALDO234] = LP8788_EN_SEL_ALDO234_M,
- [EN_ALDO5] = LP8788_EN_SEL_ALDO5_M,
- [EN_ALDO7] = LP8788_EN_SEL_ALDO7_M,
- [EN_DLDO7] = LP8788_EN_SEL_DLDO7_M,
- [EN_DLDO911] = LP8788_EN_SEL_DLDO911_M,
- };
-
- switch (id) {
- case DLDO7:
- enable_id = EN_DLDO7;
- break;
- case DLDO9:
- case DLDO11:
- enable_id = EN_DLDO911;
- break;
- case ALDO1:
- enable_id = EN_ALDO1;
- break;
- case ALDO2 ... ALDO4:
- enable_id = EN_ALDO234;
- break;
- case ALDO5:
- enable_id = EN_ALDO5;
- break;
- case ALDO7:
- enable_id = EN_ALDO7;
- break;
- default:
- return 0;
- }
-
- /*
- * Do not use devm* here: the regulator core takes over the
- * lifecycle management of the GPIO descriptor.
- * FIXME: check default mode for GPIO here: high or low?
- */
- ldo->ena_gpiod = gpiod_get_index_optional(&pdev->dev,
- "enable",
- enable_id,
- GPIOD_OUT_HIGH |
- GPIOD_FLAGS_BIT_NONEXCLUSIVE);
- if (IS_ERR(ldo->ena_gpiod))
- return PTR_ERR(ldo->ena_gpiod);
-
- /* if no GPIO for ldo pin, then set default enable mode */
- if (!ldo->ena_gpiod)
- goto set_default_ldo_enable_mode;
-
- return 0;
-
-set_default_ldo_enable_mode:
- return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0);
-}
-
-static int lp8788_dldo_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- int id = pdev->id;
- struct lp8788_ldo *ldo;
- struct regulator_config cfg = { };
- struct regulator_dev *rdev;
- int ret;
-
- ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
- if (!ldo)
- return -ENOMEM;
-
- ldo->lp = lp;
- ret = lp8788_config_ldo_enable_mode(pdev, ldo, id);
- if (ret)
- return ret;
-
- if (ldo->ena_gpiod)
- cfg.ena_gpiod = ldo->ena_gpiod;
-
- cfg.dev = pdev->dev.parent;
- cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL;
- cfg.driver_data = ldo;
- cfg.regmap = lp->regmap;
-
- rdev = devm_regulator_register(&pdev->dev, &lp8788_dldo_desc[id], &cfg);
- if (IS_ERR(rdev)) {
- ret = PTR_ERR(rdev);
- dev_err(&pdev->dev, "DLDO%d regulator register err = %d\n",
- id + 1, ret);
- return ret;
- }
-
- ldo->regulator = rdev;
- platform_set_drvdata(pdev, ldo);
-
- return 0;
-}
-
-static struct platform_driver lp8788_dldo_driver = {
- .probe = lp8788_dldo_probe,
- .driver = {
- .name = LP8788_DEV_DLDO,
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
-};
-
-static int lp8788_aldo_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- int id = pdev->id;
- struct lp8788_ldo *ldo;
- struct regulator_config cfg = { };
- struct regulator_dev *rdev;
- int ret;
-
- ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
- if (!ldo)
- return -ENOMEM;
-
- ldo->lp = lp;
- ret = lp8788_config_ldo_enable_mode(pdev, ldo, id + ALDO1);
- if (ret)
- return ret;
-
- if (ldo->ena_gpiod)
- cfg.ena_gpiod = ldo->ena_gpiod;
-
- cfg.dev = pdev->dev.parent;
- cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL;
- cfg.driver_data = ldo;
- cfg.regmap = lp->regmap;
-
- rdev = devm_regulator_register(&pdev->dev, &lp8788_aldo_desc[id], &cfg);
- if (IS_ERR(rdev)) {
- ret = PTR_ERR(rdev);
- dev_err(&pdev->dev, "ALDO%d regulator register err = %d\n",
- id + 1, ret);
- return ret;
- }
-
- ldo->regulator = rdev;
- platform_set_drvdata(pdev, ldo);
-
- return 0;
-}
-
-static struct platform_driver lp8788_aldo_driver = {
- .probe = lp8788_aldo_probe,
- .driver = {
- .name = LP8788_DEV_ALDO,
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
-};
-
-static struct platform_driver * const drivers[] = {
- &lp8788_dldo_driver,
- &lp8788_aldo_driver,
-};
-
-static int __init lp8788_ldo_init(void)
-{
- return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
-}
-subsys_initcall(lp8788_ldo_init);
-
-static void __exit lp8788_ldo_exit(void)
-{
- platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
-}
-module_exit(lp8788_ldo_exit);
-
-MODULE_DESCRIPTION("TI LP8788 LDO Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lp8788-dldo");
-MODULE_ALIAS("platform:lp8788-aldo");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 5674211afe91..c201948b4d5b 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -317,12 +317,6 @@ config RTC_DRV_HYM8563
This driver can also be built as a module. If so, the module
will be called rtc-hym8563.
-config RTC_DRV_LP8788
- tristate "TI LP8788 RTC driver"
- depends on MFD_LP8788
- help
- Say Y to enable support for the LP8788 RTC/ALARM driver.
-
config RTC_DRV_MAX6900
tristate "Maxim MAX6900"
help
diff --git a/drivers/rtc/rtc-lp8788.c b/drivers/rtc/rtc-lp8788.c
deleted file mode 100644
index 0793d70507f7..000000000000
--- a/drivers/rtc/rtc-lp8788.c
+++ /dev/null
@@ -1,322 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - rtc driver
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/err.h>
-#include <linux/irqdomain.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/rtc.h>
-#include <linux/slab.h>
-
-/* register address */
-#define LP8788_INTEN_3 0x05
-#define LP8788_RTC_UNLOCK 0x64
-#define LP8788_RTC_SEC 0x70
-#define LP8788_ALM1_SEC 0x77
-#define LP8788_ALM1_EN 0x7D
-#define LP8788_ALM2_SEC 0x7E
-#define LP8788_ALM2_EN 0x84
-
-/* mask/shift bits */
-#define LP8788_INT_RTC_ALM1_M BIT(1) /* Addr 05h */
-#define LP8788_INT_RTC_ALM1_S 1
-#define LP8788_INT_RTC_ALM2_M BIT(2) /* Addr 05h */
-#define LP8788_INT_RTC_ALM2_S 2
-#define LP8788_ALM_EN_M BIT(7) /* Addr 7Dh or 84h */
-#define LP8788_ALM_EN_S 7
-
-#define DEFAULT_ALARM_SEL LP8788_ALARM_1
-#define LP8788_MONTH_OFFSET 1
-#define LP8788_BASE_YEAR 2000
-#define MAX_WDAY_BITS 7
-#define LP8788_WDAY_SET 1
-#define RTC_UNLOCK 0x1
-#define RTC_LATCH 0x2
-#define ALARM_IRQ_FLAG (RTC_IRQF | RTC_AF)
-
-enum lp8788_time {
- LPTIME_SEC,
- LPTIME_MIN,
- LPTIME_HOUR,
- LPTIME_MDAY,
- LPTIME_MON,
- LPTIME_YEAR,
- LPTIME_WDAY,
- LPTIME_MAX,
-};
-
-struct lp8788_rtc {
- struct lp8788 *lp;
- struct rtc_device *rdev;
- enum lp8788_alarm_sel alarm;
- int irq;
-};
-
-static const u8 addr_alarm_sec[LP8788_ALARM_MAX] = {
- LP8788_ALM1_SEC,
- LP8788_ALM2_SEC,
-};
-
-static const u8 addr_alarm_en[LP8788_ALARM_MAX] = {
- LP8788_ALM1_EN,
- LP8788_ALM2_EN,
-};
-
-static const u8 mask_alarm_en[LP8788_ALARM_MAX] = {
- LP8788_INT_RTC_ALM1_M,
- LP8788_INT_RTC_ALM2_M,
-};
-
-static const u8 shift_alarm_en[LP8788_ALARM_MAX] = {
- LP8788_INT_RTC_ALM1_S,
- LP8788_INT_RTC_ALM2_S,
-};
-
-static int _to_tm_wday(u8 lp8788_wday)
-{
- int i;
-
- if (lp8788_wday == 0)
- return 0;
-
- /* lookup defined weekday from read register value */
- for (i = 0; i < MAX_WDAY_BITS; i++) {
- if ((lp8788_wday >> i) == LP8788_WDAY_SET)
- break;
- }
-
- return i + 1;
-}
-
-static inline int _to_lp8788_wday(int tm_wday)
-{
- return LP8788_WDAY_SET << (tm_wday - 1);
-}
-
-static void lp8788_rtc_unlock(struct lp8788 *lp)
-{
- lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_UNLOCK);
- lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_LATCH);
-}
-
-static int lp8788_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- struct lp8788_rtc *rtc = dev_get_drvdata(dev);
- struct lp8788 *lp = rtc->lp;
- u8 data[LPTIME_MAX];
- int ret;
-
- lp8788_rtc_unlock(lp);
-
- ret = lp8788_read_multi_bytes(lp, LP8788_RTC_SEC, data, LPTIME_MAX);
- if (ret)
- return ret;
-
- tm->tm_sec = data[LPTIME_SEC];
- tm->tm_min = data[LPTIME_MIN];
- tm->tm_hour = data[LPTIME_HOUR];
- tm->tm_mday = data[LPTIME_MDAY];
- tm->tm_mon = data[LPTIME_MON] - LP8788_MONTH_OFFSET;
- tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900;
- tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]);
-
- return 0;
-}
-
-static int lp8788_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct lp8788_rtc *rtc = dev_get_drvdata(dev);
- struct lp8788 *lp = rtc->lp;
- u8 data[LPTIME_MAX - 1];
- int ret, i, year;
-
- year = tm->tm_year + 1900 - LP8788_BASE_YEAR;
- if (year < 0) {
- dev_err(lp->dev, "invalid year: %d\n", year);
- return -EINVAL;
- }
-
- /* because rtc weekday is a readonly register, do not update */
- data[LPTIME_SEC] = tm->tm_sec;
- data[LPTIME_MIN] = tm->tm_min;
- data[LPTIME_HOUR] = tm->tm_hour;
- data[LPTIME_MDAY] = tm->tm_mday;
- data[LPTIME_MON] = tm->tm_mon + LP8788_MONTH_OFFSET;
- data[LPTIME_YEAR] = year;
-
- for (i = 0; i < ARRAY_SIZE(data); i++) {
- ret = lp8788_write_byte(lp, LP8788_RTC_SEC + i, data[i]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int lp8788_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- struct lp8788_rtc *rtc = dev_get_drvdata(dev);
- struct lp8788 *lp = rtc->lp;
- struct rtc_time *tm = &alarm->time;
- u8 addr, data[LPTIME_MAX];
- int ret;
-
- addr = addr_alarm_sec[rtc->alarm];
- ret = lp8788_read_multi_bytes(lp, addr, data, LPTIME_MAX);
- if (ret)
- return ret;
-
- tm->tm_sec = data[LPTIME_SEC];
- tm->tm_min = data[LPTIME_MIN];
- tm->tm_hour = data[LPTIME_HOUR];
- tm->tm_mday = data[LPTIME_MDAY];
- tm->tm_mon = data[LPTIME_MON] - LP8788_MONTH_OFFSET;
- tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900;
- tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]);
- alarm->enabled = data[LPTIME_WDAY] & LP8788_ALM_EN_M;
-
- return 0;
-}
-
-static int lp8788_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- struct lp8788_rtc *rtc = dev_get_drvdata(dev);
- struct lp8788 *lp = rtc->lp;
- struct rtc_time *tm = &alarm->time;
- u8 addr, data[LPTIME_MAX];
- int ret, i, year;
-
- year = tm->tm_year + 1900 - LP8788_BASE_YEAR;
- if (year < 0) {
- dev_err(lp->dev, "invalid year: %d\n", year);
- return -EINVAL;
- }
-
- data[LPTIME_SEC] = tm->tm_sec;
- data[LPTIME_MIN] = tm->tm_min;
- data[LPTIME_HOUR] = tm->tm_hour;
- data[LPTIME_MDAY] = tm->tm_mday;
- data[LPTIME_MON] = tm->tm_mon + LP8788_MONTH_OFFSET;
- data[LPTIME_YEAR] = year;
- data[LPTIME_WDAY] = _to_lp8788_wday(tm->tm_wday);
-
- for (i = 0; i < ARRAY_SIZE(data); i++) {
- addr = addr_alarm_sec[rtc->alarm] + i;
- ret = lp8788_write_byte(lp, addr, data[i]);
- if (ret)
- return ret;
- }
-
- alarm->enabled = 1;
- addr = addr_alarm_en[rtc->alarm];
-
- return lp8788_update_bits(lp, addr, LP8788_ALM_EN_M,
- alarm->enabled << LP8788_ALM_EN_S);
-}
-
-static int lp8788_alarm_irq_enable(struct device *dev, unsigned int enable)
-{
- struct lp8788_rtc *rtc = dev_get_drvdata(dev);
- struct lp8788 *lp = rtc->lp;
- u8 mask, shift;
-
- if (!rtc->irq)
- return -EIO;
-
- mask = mask_alarm_en[rtc->alarm];
- shift = shift_alarm_en[rtc->alarm];
-
- return lp8788_update_bits(lp, LP8788_INTEN_3, mask, enable << shift);
-}
-
-static const struct rtc_class_ops lp8788_rtc_ops = {
- .read_time = lp8788_rtc_read_time,
- .set_time = lp8788_rtc_set_time,
- .read_alarm = lp8788_read_alarm,
- .set_alarm = lp8788_set_alarm,
- .alarm_irq_enable = lp8788_alarm_irq_enable,
-};
-
-static irqreturn_t lp8788_alarm_irq_handler(int irq, void *ptr)
-{
- struct lp8788_rtc *rtc = ptr;
-
- rtc_update_irq(rtc->rdev, 1, ALARM_IRQ_FLAG);
- return IRQ_HANDLED;
-}
-
-static int lp8788_alarm_irq_register(struct platform_device *pdev,
- struct lp8788_rtc *rtc)
-{
- struct resource *r;
- struct lp8788 *lp = rtc->lp;
- struct irq_domain *irqdm = lp->irqdm;
- int irq;
-
- rtc->irq = 0;
-
- /* even the alarm IRQ number is not specified, rtc time should work */
- r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, LP8788_ALM_IRQ);
- if (!r)
- return 0;
-
- if (rtc->alarm == LP8788_ALARM_1)
- irq = r->start;
- else
- irq = r->end;
-
- rtc->irq = irq_create_mapping(irqdm, irq);
-
- return devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
- lp8788_alarm_irq_handler,
- 0, LP8788_ALM_IRQ, rtc);
-}
-
-static int lp8788_rtc_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- struct lp8788_rtc *rtc;
- struct device *dev = &pdev->dev;
-
- rtc = devm_kzalloc(dev, sizeof(struct lp8788_rtc), GFP_KERNEL);
- if (!rtc)
- return -ENOMEM;
-
- rtc->lp = lp;
- rtc->alarm = lp->pdata ? lp->pdata->alarm_sel : DEFAULT_ALARM_SEL;
- platform_set_drvdata(pdev, rtc);
-
- device_init_wakeup(dev, true);
-
- rtc->rdev = devm_rtc_device_register(dev, "lp8788_rtc",
- &lp8788_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc->rdev)) {
- dev_err(dev, "can not register rtc device\n");
- return PTR_ERR(rtc->rdev);
- }
-
- if (lp8788_alarm_irq_register(pdev, rtc))
- dev_warn(lp->dev, "no rtc irq handler\n");
-
- return 0;
-}
-
-static struct platform_driver lp8788_rtc_driver = {
- .probe = lp8788_rtc_probe,
- .driver = {
- .name = LP8788_DEV_RTC,
- },
-};
-module_platform_driver(lp8788_rtc_driver);
-
-MODULE_DESCRIPTION("Texas Instruments LP8788 RTC Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lp8788-rtc");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 413ed6c38b53..2c206d2713e3 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -425,12 +425,6 @@ config BACKLIGHT_LP855X
This supports TI LP8550, LP8551, LP8552, LP8553, LP8555, LP8556 and
LP8557 backlight driver.
-config BACKLIGHT_LP8788
- tristate "Backlight driver for TI LP8788 MFD"
- depends on MFD_LP8788 && PWM
- help
- This supports TI LP8788 backlight driver.
-
config BACKLIGHT_MP3309C
tristate "Backlight Driver for MPS MP3309C"
depends on I2C && PWM
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 3dc3580d82c7..0497eaa639cd 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -43,7 +43,6 @@ obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o
obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
-obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o
obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o
obj-$(CONFIG_BACKLIGHT_MAX25014) += max25014.o
obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c
deleted file mode 100644
index f61a64905a02..000000000000
--- a/drivers/video/backlight/lp8788_bl.c
+++ /dev/null
@@ -1,190 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI LP8788 MFD - backlight driver
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#include <linux/backlight.h>
-#include <linux/err.h>
-#include <linux/mfd/lp8788.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-/* Register address */
-#define LP8788_BL_CONFIG 0x96
-#define LP8788_BL_EN BIT(0)
-#define LP8788_BL_PWM_INPUT_EN BIT(5)
-#define LP8788_BL_FULLSCALE_SHIFT 2
-#define LP8788_BL_DIM_MODE_SHIFT 1
-#define LP8788_BL_PWM_POLARITY_SHIFT 6
-
-#define LP8788_BL_BRIGHTNESS 0x97
-
-#define LP8788_BL_RAMP 0x98
-#define LP8788_BL_RAMP_RISE_SHIFT 4
-
-#define MAX_BRIGHTNESS 127
-#define DEFAULT_BL_NAME "lcd-backlight"
-
-struct lp8788_bl {
- struct lp8788 *lp;
- struct backlight_device *bl_dev;
-};
-
-static int lp8788_backlight_configure(struct lp8788_bl *bl)
-{
- int ret;
- u8 val;
-
- /* Brightness ramp up/down */
- val = (LP8788_RAMP_8192us << LP8788_BL_RAMP_RISE_SHIFT) | LP8788_RAMP_8192us;
- ret = lp8788_write_byte(bl->lp, LP8788_BL_RAMP, val);
- if (ret)
- return ret;
-
- /* Fullscale current setting */
- val = (LP8788_FULLSCALE_1900uA << LP8788_BL_FULLSCALE_SHIFT) |
- (LP8788_DIM_EXPONENTIAL << LP8788_BL_DIM_MODE_SHIFT);
-
- /* Brightness control mode */
- val |= LP8788_BL_EN;
-
- return lp8788_write_byte(bl->lp, LP8788_BL_CONFIG, val);
-}
-
-static int lp8788_bl_update_status(struct backlight_device *bl_dev)
-{
- struct lp8788_bl *bl = bl_get_data(bl_dev);
-
- if (bl_dev->props.state & BL_CORE_SUSPENDED)
- bl_dev->props.brightness = 0;
-
- lp8788_write_byte(bl->lp, LP8788_BL_BRIGHTNESS, bl_dev->props.brightness);
-
- return 0;
-}
-
-static const struct backlight_ops lp8788_bl_ops = {
- .options = BL_CORE_SUSPENDRESUME,
- .update_status = lp8788_bl_update_status,
-};
-
-static int lp8788_backlight_register(struct lp8788_bl *bl)
-{
- struct backlight_device *bl_dev;
- struct backlight_properties props;
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_PLATFORM;
- props.max_brightness = MAX_BRIGHTNESS;
-
- /* Initial brightness */
- props.brightness = 0;
-
- /* Backlight device name */
- bl_dev = backlight_device_register(DEFAULT_BL_NAME, bl->lp->dev, bl,
- &lp8788_bl_ops, &props);
- if (IS_ERR(bl_dev))
- return PTR_ERR(bl_dev);
-
- bl->bl_dev = bl_dev;
-
- return 0;
-}
-
-static void lp8788_backlight_unregister(struct lp8788_bl *bl)
-{
- struct backlight_device *bl_dev = bl->bl_dev;
-
- backlight_device_unregister(bl_dev);
-}
-
-static ssize_t lp8788_get_bl_ctl_mode(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- const char *strmode = "Register based";
-
- return scnprintf(buf, PAGE_SIZE, "%s\n", strmode);
-}
-
-static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp8788_get_bl_ctl_mode, NULL);
-
-static struct attribute *lp8788_attributes[] = {
- &dev_attr_bl_ctl_mode.attr,
- NULL,
-};
-
-static const struct attribute_group lp8788_attr_group = {
- .attrs = lp8788_attributes,
-};
-
-static int lp8788_backlight_probe(struct platform_device *pdev)
-{
- struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
- struct lp8788_bl *bl;
- int ret;
-
- bl = devm_kzalloc(lp->dev, sizeof(struct lp8788_bl), GFP_KERNEL);
- if (!bl)
- return -ENOMEM;
-
- bl->lp = lp;
-
- platform_set_drvdata(pdev, bl);
-
- ret = lp8788_backlight_configure(bl);
- if (ret) {
- dev_err(lp->dev, "backlight config err: %d\n", ret);
- goto err_dev;
- }
-
- ret = lp8788_backlight_register(bl);
- if (ret) {
- dev_err(lp->dev, "register backlight err: %d\n", ret);
- goto err_dev;
- }
-
- ret = sysfs_create_group(&pdev->dev.kobj, &lp8788_attr_group);
- if (ret) {
- dev_err(lp->dev, "register sysfs err: %d\n", ret);
- goto err_sysfs;
- }
-
- backlight_update_status(bl->bl_dev);
-
- return 0;
-
-err_sysfs:
- lp8788_backlight_unregister(bl);
-err_dev:
- return ret;
-}
-
-static void lp8788_backlight_remove(struct platform_device *pdev)
-{
- struct lp8788_bl *bl = platform_get_drvdata(pdev);
- struct backlight_device *bl_dev = bl->bl_dev;
-
- bl_dev->props.brightness = 0;
- backlight_update_status(bl_dev);
- sysfs_remove_group(&pdev->dev.kobj, &lp8788_attr_group);
- lp8788_backlight_unregister(bl);
-}
-
-static struct platform_driver lp8788_bl_driver = {
- .probe = lp8788_backlight_probe,
- .remove = lp8788_backlight_remove,
- .driver = {
- .name = LP8788_DEV_BACKLIGHT,
- },
-};
-module_platform_driver(lp8788_bl_driver);
-
-MODULE_DESCRIPTION("Texas Instruments LP8788 Backlight Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lp8788-backlight");
diff --git a/include/linux/mfd/lp8788-isink.h b/include/linux/mfd/lp8788-isink.h
deleted file mode 100644
index 464dc4c937e4..000000000000
--- a/include/linux/mfd/lp8788-isink.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * TI LP8788 MFD - common definitions for current sinks
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#ifndef __ISINK_LP8788_H__
-#define __ISINK_LP8788_H__
-
-/* register address */
-#define LP8788_ISINK_CTRL 0x99
-#define LP8788_ISINK12_IOUT 0x9A
-#define LP8788_ISINK3_IOUT 0x9B
-#define LP8788_ISINK1_PWM 0x9C
-#define LP8788_ISINK2_PWM 0x9D
-#define LP8788_ISINK3_PWM 0x9E
-
-/* mask bits */
-#define LP8788_ISINK1_IOUT_M 0x0F /* Addr 9Ah */
-#define LP8788_ISINK2_IOUT_M 0xF0
-#define LP8788_ISINK3_IOUT_M 0x0F /* Addr 9Bh */
-
-/* 6 bits used for PWM code : Addr 9C ~ 9Eh */
-#define LP8788_ISINK_MAX_PWM 63
-#define LP8788_ISINK_SCALE_OFFSET 3
-
-static const u8 lp8788_iout_addr[] = {
- LP8788_ISINK12_IOUT,
- LP8788_ISINK12_IOUT,
- LP8788_ISINK3_IOUT,
-};
-
-static const u8 lp8788_iout_mask[] = {
- LP8788_ISINK1_IOUT_M,
- LP8788_ISINK2_IOUT_M,
- LP8788_ISINK3_IOUT_M,
-};
-
-static const u8 lp8788_pwm_addr[] = {
- LP8788_ISINK1_PWM,
- LP8788_ISINK2_PWM,
- LP8788_ISINK3_PWM,
-};
-
-#endif
diff --git a/include/linux/mfd/lp8788.h b/include/linux/mfd/lp8788.h
deleted file mode 100644
index fd17bec2a33e..000000000000
--- a/include/linux/mfd/lp8788.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * TI LP8788 MFD Device
- *
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#ifndef __MFD_LP8788_H__
-#define __MFD_LP8788_H__
-
-#include <linux/irqdomain.h>
-#include <linux/regmap.h>
-
-#define LP8788_DEV_BUCK "lp8788-buck"
-#define LP8788_DEV_DLDO "lp8788-dldo"
-#define LP8788_DEV_ALDO "lp8788-aldo"
-#define LP8788_DEV_CHARGER "lp8788-charger"
-#define LP8788_DEV_RTC "lp8788-rtc"
-#define LP8788_DEV_BACKLIGHT "lp8788-backlight"
-#define LP8788_DEV_VIBRATOR "lp8788-vibrator"
-#define LP8788_DEV_KEYLED "lp8788-keyled"
-#define LP8788_DEV_ADC "lp8788-adc"
-
-#define LP8788_NUM_BUCKS 4
-#define LP8788_NUM_DLDOS 12
-#define LP8788_NUM_ALDOS 10
-#define LP8788_NUM_BUCK2_DVS 2
-
-#define LP8788_CHG_IRQ "CHG_IRQ"
-#define LP8788_PRSW_IRQ "PRSW_IRQ"
-#define LP8788_BATT_IRQ "BATT_IRQ"
-#define LP8788_ALM_IRQ "ALARM_IRQ"
-
-enum lp8788_int_id {
- /* interrup register 1 : Addr 00h */
- LP8788_INT_TSDL,
- LP8788_INT_TSDH,
- LP8788_INT_UVLO,
- LP8788_INT_FLAGMON,
- LP8788_INT_PWRON_TIME,
- LP8788_INT_PWRON,
- LP8788_INT_COMP1,
- LP8788_INT_COMP2,
-
- /* interrupt register 2 : Addr 01h */
- LP8788_INT_CHG_INPUT_STATE,
- LP8788_INT_CHG_STATE,
- LP8788_INT_EOC,
- LP8788_INT_CHG_RESTART,
- LP8788_INT_RESTART_TIMEOUT,
- LP8788_INT_FULLCHG_TIMEOUT,
- LP8788_INT_PRECHG_TIMEOUT,
-
- /* interrupt register 3 : Addr 02h */
- LP8788_INT_RTC_ALARM1 = 17,
- LP8788_INT_RTC_ALARM2,
- LP8788_INT_ENTER_SYS_SUPPORT,
- LP8788_INT_EXIT_SYS_SUPPORT,
- LP8788_INT_BATT_LOW,
- LP8788_INT_NO_BATT,
-
- LP8788_INT_MAX = 24,
-};
-
-enum lp8788_dvs_sel {
- DVS_SEL_V0,
- DVS_SEL_V1,
- DVS_SEL_V2,
- DVS_SEL_V3,
-};
-
-enum lp8788_ext_ldo_en_id {
- EN_ALDO1,
- EN_ALDO234,
- EN_ALDO5,
- EN_ALDO7,
- EN_DLDO7,
- EN_DLDO911,
- EN_LDOS_MAX,
-};
-
-enum lp8788_charger_event {
- NO_CHARGER,
- CHARGER_DETECTED,
-};
-
-enum lp8788_bl_dim_mode {
- LP8788_DIM_EXPONENTIAL,
- LP8788_DIM_LINEAR,
-};
-
-enum lp8788_bl_full_scale_current {
- LP8788_FULLSCALE_5000uA,
- LP8788_FULLSCALE_8500uA,
- LP8788_FULLSCALE_1200uA,
- LP8788_FULLSCALE_1550uA,
- LP8788_FULLSCALE_1900uA,
- LP8788_FULLSCALE_2250uA,
- LP8788_FULLSCALE_2600uA,
- LP8788_FULLSCALE_2950uA,
-};
-
-enum lp8788_bl_ramp_step {
- LP8788_RAMP_8us,
- LP8788_RAMP_1024us,
- LP8788_RAMP_2048us,
- LP8788_RAMP_4096us,
- LP8788_RAMP_8192us,
- LP8788_RAMP_16384us,
- LP8788_RAMP_32768us,
- LP8788_RAMP_65538us,
-};
-
-enum lp8788_isink_scale {
- LP8788_ISINK_SCALE_100mA,
- LP8788_ISINK_SCALE_120mA,
-};
-
-enum lp8788_isink_number {
- LP8788_ISINK_1,
- LP8788_ISINK_2,
- LP8788_ISINK_3,
-};
-
-enum lp8788_alarm_sel {
- LP8788_ALARM_1,
- LP8788_ALARM_2,
- LP8788_ALARM_MAX,
-};
-
-enum lp8788_adc_id {
- LPADC_VBATT_5P5,
- LPADC_VIN_CHG,
- LPADC_IBATT,
- LPADC_IC_TEMP,
- LPADC_VBATT_6P0,
- LPADC_VBATT_5P0,
- LPADC_ADC1,
- LPADC_ADC2,
- LPADC_VDD,
- LPADC_VCOIN,
- LPADC_VDD_LDO,
- LPADC_ADC3,
- LPADC_ADC4,
- LPADC_MAX,
-};
-
-struct lp8788;
-
-/*
- * lp8788_buck1_dvs
- * @vsel : dvs selector for buck v1 register
- */
-struct lp8788_buck1_dvs {
- enum lp8788_dvs_sel vsel;
-};
-
-/*
- * lp8788_buck2_dvs
- * @vsel : dvs selector for buck v2 register
- */
-struct lp8788_buck2_dvs {
- enum lp8788_dvs_sel vsel;
-};
-
-/*
- * struct lp8788_chg_param
- * @addr : charging control register address (range : 0x11 ~ 0x1C)
- * @val : charging parameter value
- */
-struct lp8788_chg_param {
- u8 addr;
- u8 val;
-};
-
-/*
- * struct lp8788_charger_platform_data
- * @adc_vbatt : adc channel name for battery voltage
- * @adc_batt_temp : adc channel name for battery temperature
- * @max_vbatt_mv : used for calculating battery capacity
- * @chg_params : initial charging parameters
- * @num_chg_params : numbers of charging parameters
- * @charger_event : the charger event can be reported to the platform side
- */
-struct lp8788_charger_platform_data {
- const char *adc_vbatt;
- const char *adc_batt_temp;
- unsigned int max_vbatt_mv;
- struct lp8788_chg_param *chg_params;
- int num_chg_params;
- void (*charger_event) (struct lp8788 *lp,
- enum lp8788_charger_event event);
-};
-
-/*
- * struct lp8788_led_platform_data
- * @name : led driver name. (default: "keyboard-backlight")
- * @scale : current scale
- * @num : current sink number
- * @iout_code : current output value (Addr 9Ah ~ 9Bh)
- */
-struct lp8788_led_platform_data {
- char *name;
- enum lp8788_isink_scale scale;
- enum lp8788_isink_number num;
- int iout_code;
-};
-
-/*
- * struct lp8788_vib_platform_data
- * @name : vibrator driver name
- * @scale : current scale
- * @num : current sink number
- * @iout_code : current output value (Addr 9Ah ~ 9Bh)
- * @pwm_code : PWM code value (Addr 9Ch ~ 9Eh)
- */
-struct lp8788_vib_platform_data {
- char *name;
- enum lp8788_isink_scale scale;
- enum lp8788_isink_number num;
- int iout_code;
- int pwm_code;
-};
-
-/*
- * struct lp8788_platform_data
- * @init_func : used for initializing registers
- * before mfd driver is registered
- * @buck_data : regulator initial data for buck
- * @dldo_data : regulator initial data for digital ldo
- * @aldo_data : regulator initial data for analog ldo
- * @buck1_dvs : configurations for buck1 dvs
- * @buck2_dvs : configurations for buck2 dvs
- * @chg_pdata : platform data for charger driver
- * @alarm_sel : rtc alarm selection (1 or 2)
- * @led_pdata : configurable data for led driver
- * @vib_pdata : configurable data for vibrator driver
- * @adc_pdata : iio map data for adc driver
- */
-struct lp8788_platform_data {
- /* general system information */
- int (*init_func) (struct lp8788 *lp);
-
- /* regulators */
- struct regulator_init_data *buck_data[LP8788_NUM_BUCKS];
- struct regulator_init_data *dldo_data[LP8788_NUM_DLDOS];
- struct regulator_init_data *aldo_data[LP8788_NUM_ALDOS];
- struct lp8788_buck1_dvs *buck1_dvs;
- struct lp8788_buck2_dvs *buck2_dvs;
-
- /* charger */
- struct lp8788_charger_platform_data *chg_pdata;
-
- /* rtc alarm */
- enum lp8788_alarm_sel alarm_sel;
-
- /* current sinks */
- struct lp8788_led_platform_data *led_pdata;
- struct lp8788_vib_platform_data *vib_pdata;
-
- /* adc iio map data */
- struct iio_map *adc_pdata;
-};
-
-/*
- * struct lp8788
- * @dev : parent device pointer
- * @regmap : used for i2c communcation on accessing registers
- * @irqdm : interrupt domain for handling nested interrupt
- * @irq : pin number of IRQ_N
- * @pdata : lp8788 platform specific data
- */
-struct lp8788 {
- struct device *dev;
- struct regmap *regmap;
- struct irq_domain *irqdm;
- int irq;
- struct lp8788_platform_data *pdata;
-};
-
-int lp8788_irq_init(struct lp8788 *lp, int chip_irq);
-void lp8788_irq_exit(struct lp8788 *lp);
-int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data);
-int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count);
-int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data);
-int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data);
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* Re: [PATCH 07/14] mfd: remove unused lp8788 driver
2026-09-09 13:21 ` [PATCH 07/14] mfd: remove unused lp8788 driver Arnd Bergmann
@ 2026-09-09 15:46 ` Sebastian Reichel
0 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2026-09-09 15:46 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
[-- Attachment #1: Type: text/plain, Size: 2404 bytes --]
Hi,
On Wed, Sep 09, 2026 at 03:21:44PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver was apparently never used upstream, and without devicetree
> support cannot be used by external board support.
>
> The MAINTAINER entry was already removed in 2021 as the email address
> bounced.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/iio/adc/Kconfig | 9 -
> drivers/iio/adc/Makefile | 1 -
> drivers/iio/adc/lp8788_adc.c | 219 --------
> drivers/leds/Kconfig | 7 -
> drivers/leds/Makefile | 1 -
> drivers/leds/leds-lp8788.c | 171 ------
> drivers/mfd/Kconfig | 10 -
> drivers/mfd/Makefile | 1 -
> drivers/mfd/lp8788-irq.c | 194 -------
> drivers/mfd/lp8788.c | 246 ---------
> drivers/power/supply/Kconfig | 8 -
> drivers/power/supply/Makefile | 1 -
> drivers/power/supply/lp8788-charger.c | 730 --------------------------
> drivers/regulator/Kconfig | 6 -
> drivers/regulator/Makefile | 2 -
> drivers/regulator/lp8788-buck.c | 541 -------------------
> drivers/regulator/lp8788-ldo.c | 640 ----------------------
> drivers/rtc/Kconfig | 6 -
> drivers/rtc/rtc-lp8788.c | 322 ------------
> drivers/video/backlight/Kconfig | 6 -
> drivers/video/backlight/Makefile | 1 -
> drivers/video/backlight/lp8788_bl.c | 190 -------
> include/linux/mfd/lp8788-isink.h | 48 --
> include/linux/mfd/lp8788.h | 289 ----------
> 24 files changed, 3649 deletions(-)
> delete mode 100644 drivers/iio/adc/lp8788_adc.c
> delete mode 100644 drivers/leds/leds-lp8788.c
> delete mode 100644 drivers/mfd/lp8788-irq.c
> delete mode 100644 drivers/mfd/lp8788.c
> delete mode 100644 drivers/power/supply/lp8788-charger.c
> delete mode 100644 drivers/regulator/lp8788-buck.c
> delete mode 100644 drivers/regulator/lp8788-ldo.c
> delete mode 100644 drivers/rtc/rtc-lp8788.c
> delete mode 100644 drivers/video/backlight/lp8788_bl.c
> delete mode 100644 include/linux/mfd/lp8788-isink.h
> delete mode 100644 include/linux/mfd/lp8788.h
Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-- Sebastian
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 08/14] mfd: remove unused aat2870 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (4 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 07/14] mfd: remove unused lp8788 driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:21 ` [PATCH 09/14] mfd: remove unused lm3533 driver Arnd Bergmann
` (8 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
This driver was apparently never used, as it has has no devicetree
support and never had corresponding platform_data definitions.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/mfd/Kconfig | 12 -
drivers/mfd/Makefile | 1 -
drivers/mfd/aat2870-core.c | 458 --------------------------
drivers/regulator/Kconfig | 7 -
drivers/regulator/Makefile | 1 -
drivers/regulator/aat2870-regulator.c | 201 -----------
drivers/video/backlight/Kconfig | 7 -
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/aat2870_bl.c | 206 ------------
include/linux/mfd/aat2870.h | 164 ---------
10 files changed, 1058 deletions(-)
delete mode 100644 drivers/mfd/aat2870-core.c
delete mode 100644 drivers/regulator/aat2870-regulator.c
delete mode 100644 drivers/video/backlight/aat2870_bl.c
delete mode 100644 include/linux/mfd/aat2870.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 09e400e1f4b0..b0c7df448445 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -115,18 +115,6 @@ config MFD_AS3722
controllers, 11 LDOs, RTC, automatic battery, temperature and
over current monitoring, GPIOs, ADC and a watchdog.
-config MFD_AAT2870_CORE
- bool "AnalogicTech AAT2870"
- select MFD_CORE
- depends on I2C=y
- depends on GPIOLIB || COMPILE_TEST
- depends on GPIOLIB_LEGACY
- help
- If you say yes here you get support for the AAT2870.
- This driver provides common support for accessing the device,
- additional drivers must be enabled in order to use the
- functionality of the device.
-
config MFD_AT91_USART
tristate "AT91 USART Driver"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e3fe998c3513..cf3c70364538 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -206,7 +206,6 @@ obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o
obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
-obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o
obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o
obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c
deleted file mode 100644
index 0d56cd6fbc6a..000000000000
--- a/drivers/mfd/aat2870-core.c
+++ /dev/null
@@ -1,458 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/mfd/aat2870-core.c
- *
- * Copyright (c) 2011, NVIDIA Corporation.
- * Author: Jin Park <jinyoungp@nvidia.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/gpio/legacy.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/aat2870.h>
-#include <linux/regulator/machine.h>
-
-static struct aat2870_register aat2870_regs[AAT2870_REG_NUM] = {
- /* readable, writeable, value */
- { 0, 1, 0x00 }, /* 0x00 AAT2870_BL_CH_EN */
- { 0, 1, 0x16 }, /* 0x01 AAT2870_BLM */
- { 0, 1, 0x16 }, /* 0x02 AAT2870_BLS */
- { 0, 1, 0x56 }, /* 0x03 AAT2870_BL1 */
- { 0, 1, 0x56 }, /* 0x04 AAT2870_BL2 */
- { 0, 1, 0x56 }, /* 0x05 AAT2870_BL3 */
- { 0, 1, 0x56 }, /* 0x06 AAT2870_BL4 */
- { 0, 1, 0x56 }, /* 0x07 AAT2870_BL5 */
- { 0, 1, 0x56 }, /* 0x08 AAT2870_BL6 */
- { 0, 1, 0x56 }, /* 0x09 AAT2870_BL7 */
- { 0, 1, 0x56 }, /* 0x0A AAT2870_BL8 */
- { 0, 1, 0x00 }, /* 0x0B AAT2870_FLR */
- { 0, 1, 0x03 }, /* 0x0C AAT2870_FM */
- { 0, 1, 0x03 }, /* 0x0D AAT2870_FS */
- { 0, 1, 0x10 }, /* 0x0E AAT2870_ALS_CFG0 */
- { 0, 1, 0x06 }, /* 0x0F AAT2870_ALS_CFG1 */
- { 0, 1, 0x00 }, /* 0x10 AAT2870_ALS_CFG2 */
- { 1, 0, 0x00 }, /* 0x11 AAT2870_AMB */
- { 0, 1, 0x00 }, /* 0x12 AAT2870_ALS0 */
- { 0, 1, 0x00 }, /* 0x13 AAT2870_ALS1 */
- { 0, 1, 0x00 }, /* 0x14 AAT2870_ALS2 */
- { 0, 1, 0x00 }, /* 0x15 AAT2870_ALS3 */
- { 0, 1, 0x00 }, /* 0x16 AAT2870_ALS4 */
- { 0, 1, 0x00 }, /* 0x17 AAT2870_ALS5 */
- { 0, 1, 0x00 }, /* 0x18 AAT2870_ALS6 */
- { 0, 1, 0x00 }, /* 0x19 AAT2870_ALS7 */
- { 0, 1, 0x00 }, /* 0x1A AAT2870_ALS8 */
- { 0, 1, 0x00 }, /* 0x1B AAT2870_ALS9 */
- { 0, 1, 0x00 }, /* 0x1C AAT2870_ALSA */
- { 0, 1, 0x00 }, /* 0x1D AAT2870_ALSB */
- { 0, 1, 0x00 }, /* 0x1E AAT2870_ALSC */
- { 0, 1, 0x00 }, /* 0x1F AAT2870_ALSD */
- { 0, 1, 0x00 }, /* 0x20 AAT2870_ALSE */
- { 0, 1, 0x00 }, /* 0x21 AAT2870_ALSF */
- { 0, 1, 0x00 }, /* 0x22 AAT2870_SUB_SET */
- { 0, 1, 0x00 }, /* 0x23 AAT2870_SUB_CTRL */
- { 0, 1, 0x00 }, /* 0x24 AAT2870_LDO_AB */
- { 0, 1, 0x00 }, /* 0x25 AAT2870_LDO_CD */
- { 0, 1, 0x00 }, /* 0x26 AAT2870_LDO_EN */
-};
-
-static struct mfd_cell aat2870_devs[] = {
- {
- .name = "aat2870-backlight",
- .id = AAT2870_ID_BL,
- .pdata_size = sizeof(struct aat2870_bl_platform_data),
- },
- {
- .name = "aat2870-regulator",
- .id = AAT2870_ID_LDOA,
- .pdata_size = sizeof(struct regulator_init_data),
- },
- {
- .name = "aat2870-regulator",
- .id = AAT2870_ID_LDOB,
- .pdata_size = sizeof(struct regulator_init_data),
- },
- {
- .name = "aat2870-regulator",
- .id = AAT2870_ID_LDOC,
- .pdata_size = sizeof(struct regulator_init_data),
- },
- {
- .name = "aat2870-regulator",
- .id = AAT2870_ID_LDOD,
- .pdata_size = sizeof(struct regulator_init_data),
- },
-};
-
-static int __aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val)
-{
- int ret;
-
- if (addr >= AAT2870_REG_NUM) {
- dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr);
- return -EINVAL;
- }
-
- if (!aat2870->reg_cache[addr].readable) {
- *val = aat2870->reg_cache[addr].value;
- goto out;
- }
-
- ret = i2c_master_send(aat2870->client, &addr, 1);
- if (ret < 0)
- return ret;
- if (ret != 1)
- return -EIO;
-
- ret = i2c_master_recv(aat2870->client, val, 1);
- if (ret < 0)
- return ret;
- if (ret != 1)
- return -EIO;
-
-out:
- dev_dbg(aat2870->dev, "read: addr=0x%02x, val=0x%02x\n", addr, *val);
- return 0;
-}
-
-static int __aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val)
-{
- u8 msg[2];
- int ret;
-
- if (addr >= AAT2870_REG_NUM) {
- dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr);
- return -EINVAL;
- }
-
- if (!aat2870->reg_cache[addr].writeable) {
- dev_err(aat2870->dev, "Address 0x%02x is not writeable\n",
- addr);
- return -EINVAL;
- }
-
- msg[0] = addr;
- msg[1] = val;
- ret = i2c_master_send(aat2870->client, msg, 2);
- if (ret < 0)
- return ret;
- if (ret != 2)
- return -EIO;
-
- aat2870->reg_cache[addr].value = val;
-
- dev_dbg(aat2870->dev, "write: addr=0x%02x, val=0x%02x\n", addr, val);
- return 0;
-}
-
-static int aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val)
-{
- int ret;
-
- mutex_lock(&aat2870->io_lock);
- ret = __aat2870_read(aat2870, addr, val);
- mutex_unlock(&aat2870->io_lock);
-
- return ret;
-}
-
-static int aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val)
-{
- int ret;
-
- mutex_lock(&aat2870->io_lock);
- ret = __aat2870_write(aat2870, addr, val);
- mutex_unlock(&aat2870->io_lock);
-
- return ret;
-}
-
-static int aat2870_update(struct aat2870_data *aat2870, u8 addr, u8 mask,
- u8 val)
-{
- int change;
- u8 old_val, new_val;
- int ret;
-
- mutex_lock(&aat2870->io_lock);
-
- ret = __aat2870_read(aat2870, addr, &old_val);
- if (ret)
- goto out_unlock;
-
- new_val = (old_val & ~mask) | (val & mask);
- change = old_val != new_val;
- if (change)
- ret = __aat2870_write(aat2870, addr, new_val);
-
-out_unlock:
- mutex_unlock(&aat2870->io_lock);
-
- return ret;
-}
-
-static inline void aat2870_enable(struct aat2870_data *aat2870)
-{
- if (aat2870->en_pin >= 0)
- gpio_set_value(aat2870->en_pin, 1);
-
- aat2870->is_enable = 1;
-}
-
-static inline void aat2870_disable(struct aat2870_data *aat2870)
-{
- if (aat2870->en_pin >= 0)
- gpio_set_value(aat2870->en_pin, 0);
-
- aat2870->is_enable = 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static ssize_t aat2870_dump_reg(struct aat2870_data *aat2870, char *buf)
-{
- u8 addr, val;
- ssize_t count = 0;
- int ret;
-
- count += sprintf(buf, "aat2870 registers\n");
- for (addr = 0; addr < AAT2870_REG_NUM; addr++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "0x%02x: ", addr);
- if (count >= PAGE_SIZE - 1)
- break;
-
- ret = aat2870->read(aat2870, addr, &val);
- if (ret == 0)
- count += snprintf(buf + count, PAGE_SIZE - count,
- "0x%02x", val);
- else
- count += snprintf(buf + count, PAGE_SIZE - count,
- "<read fail: %d>", ret);
-
- if (count >= PAGE_SIZE - 1)
- break;
-
- count += snprintf(buf + count, PAGE_SIZE - count, "\n");
- if (count >= PAGE_SIZE - 1)
- break;
- }
-
- /* Truncate count; min() would cause a warning */
- if (count >= PAGE_SIZE)
- count = PAGE_SIZE - 1;
-
- return count;
-}
-
-static ssize_t aat2870_reg_read_file(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct aat2870_data *aat2870 = file->private_data;
- char *buf;
- ssize_t ret;
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- ret = aat2870_dump_reg(aat2870, buf);
- if (ret >= 0)
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
- kfree(buf);
-
- return ret;
-}
-
-static ssize_t aat2870_reg_write_file(struct file *file,
- const char __user *user_buf, size_t count,
- loff_t *ppos)
-{
- struct aat2870_data *aat2870 = file->private_data;
- char buf[32];
- ssize_t buf_size;
- char *start = buf;
- unsigned long addr, val;
- int ret;
-
- buf_size = min(count, (size_t)(sizeof(buf)-1));
- if (copy_from_user(buf, user_buf, buf_size)) {
- dev_err(aat2870->dev, "Failed to copy from user\n");
- return -EFAULT;
- }
- buf[buf_size] = 0;
-
- while (*start == ' ')
- start++;
-
- ret = kstrtoul(start, 16, &addr);
- if (ret)
- return ret;
-
- if (addr >= AAT2870_REG_NUM) {
- dev_err(aat2870->dev, "Invalid address, 0x%lx\n", addr);
- return -EINVAL;
- }
-
- while (*start == ' ')
- start++;
-
- ret = kstrtoul(start, 16, &val);
- if (ret)
- return ret;
-
- ret = aat2870->write(aat2870, (u8)addr, (u8)val);
- if (ret)
- return ret;
-
- return buf_size;
-}
-
-static const struct file_operations aat2870_reg_fops = {
- .open = simple_open,
- .read = aat2870_reg_read_file,
- .write = aat2870_reg_write_file,
-};
-
-static void aat2870_init_debugfs(struct aat2870_data *aat2870)
-{
- debugfs_create_file("regs", 0644, aat2870->client->debugfs, aat2870,
- &aat2870_reg_fops);
-}
-
-#else
-static inline void aat2870_init_debugfs(struct aat2870_data *aat2870)
-{
-}
-#endif /* CONFIG_DEBUG_FS */
-
-static int aat2870_i2c_probe(struct i2c_client *client)
-{
- struct aat2870_platform_data *pdata = dev_get_platdata(&client->dev);
- struct aat2870_data *aat2870;
- int i, j;
- int ret = 0;
-
- aat2870 = devm_kzalloc(&client->dev, sizeof(struct aat2870_data),
- GFP_KERNEL);
- if (!aat2870)
- return -ENOMEM;
-
- aat2870->dev = &client->dev;
- aat2870->client = client;
- i2c_set_clientdata(client, aat2870);
-
- aat2870->reg_cache = aat2870_regs;
-
- if (pdata->en_pin < 0)
- aat2870->en_pin = -1;
- else
- aat2870->en_pin = pdata->en_pin;
-
- aat2870->init = pdata->init;
- aat2870->uninit = pdata->uninit;
- aat2870->read = aat2870_read;
- aat2870->write = aat2870_write;
- aat2870->update = aat2870_update;
-
- mutex_init(&aat2870->io_lock);
-
- if (aat2870->init)
- aat2870->init(aat2870);
-
- if (aat2870->en_pin >= 0) {
- ret = devm_gpio_request_one(&client->dev, aat2870->en_pin,
- GPIOF_OUT_INIT_HIGH, "aat2870-en");
- if (ret < 0) {
- dev_err(&client->dev,
- "Failed to request GPIO %d\n", aat2870->en_pin);
- return ret;
- }
- }
-
- aat2870_enable(aat2870);
-
- for (i = 0; i < pdata->num_subdevs; i++) {
- for (j = 0; j < ARRAY_SIZE(aat2870_devs); j++) {
- if ((pdata->subdevs[i].id == aat2870_devs[j].id) &&
- !strcmp(pdata->subdevs[i].name,
- aat2870_devs[j].name)) {
- aat2870_devs[j].platform_data =
- pdata->subdevs[i].platform_data;
- break;
- }
- }
- }
-
- ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs,
- ARRAY_SIZE(aat2870_devs), NULL, 0, NULL);
- if (ret != 0) {
- dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret);
- goto out_disable;
- }
-
- aat2870_init_debugfs(aat2870);
-
- return 0;
-
-out_disable:
- aat2870_disable(aat2870);
- return ret;
-}
-
-static int aat2870_i2c_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct aat2870_data *aat2870 = i2c_get_clientdata(client);
-
- aat2870_disable(aat2870);
-
- return 0;
-}
-
-static int aat2870_i2c_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct aat2870_data *aat2870 = i2c_get_clientdata(client);
- struct aat2870_register *reg = NULL;
- int i;
-
- aat2870_enable(aat2870);
-
- /* restore registers */
- for (i = 0; i < AAT2870_REG_NUM; i++) {
- reg = &aat2870->reg_cache[i];
- if (reg->writeable)
- aat2870->write(aat2870, i, reg->value);
- }
-
- return 0;
-}
-
-static DEFINE_SIMPLE_DEV_PM_OPS(aat2870_pm_ops, aat2870_i2c_suspend,
- aat2870_i2c_resume);
-
-static const struct i2c_device_id aat2870_i2c_id_table[] = {
- { "aat2870" },
- { }
-};
-
-static struct i2c_driver aat2870_i2c_driver = {
- .driver = {
- .name = "aat2870",
- .pm = pm_sleep_ptr(&aat2870_pm_ops),
- .suppress_bind_attrs = true,
- },
- .probe = aat2870_i2c_probe,
- .id_table = aat2870_i2c_id_table,
-};
-
-static int __init aat2870_init(void)
-{
- return i2c_add_driver(&aat2870_i2c_driver);
-}
-subsys_initcall(aat2870_init);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 4b90d1cb045c..12d883e729bc 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -132,13 +132,6 @@ config REGULATOR_ANATOP
regulators. It is recommended that this option be
enabled on i.MX6 platform.
-config REGULATOR_AAT2870
- tristate "AnalogicTech AAT2870 Regulators"
- depends on MFD_AAT2870_CORE
- help
- If you have a AnalogicTech AAT2870 say Y to enable the
- regulator driver.
-
config REGULATOR_AB8500
bool "ST-Ericsson AB8500 Power Regulators"
depends on AB8500_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index fe0f099c217b..321c6ea73ee0 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_88PM886) += 88pm886-regulator.o
obj-$(CONFIG_REGULATOR_CROS_EC) += cros-ec-regulator.o
obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o
-obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500-ext.o ab8500.o
obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o
obj-$(CONFIG_REGULATOR_ACT8945A) += act8945a-regulator.o
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c
deleted file mode 100644
index 970d86f2bbb8..000000000000
--- a/drivers/regulator/aat2870-regulator.c
+++ /dev/null
@@ -1,201 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/regulator/aat2870-regulator.c
- *
- * Copyright (c) 2011, NVIDIA Corporation.
- * Author: Jin Park <jinyoungp@nvidia.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/aat2870.h>
-
-struct aat2870_regulator {
- struct aat2870_data *aat2870;
- struct regulator_desc desc;
-
- u8 enable_addr;
- u8 enable_shift;
- u8 enable_mask;
-
- u8 voltage_addr;
- u8 voltage_shift;
- u8 voltage_mask;
-};
-
-static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev,
- unsigned selector)
-{
- struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
- struct aat2870_data *aat2870 = ri->aat2870;
-
- return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask,
- selector << ri->voltage_shift);
-}
-
-static int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev)
-{
- struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
- struct aat2870_data *aat2870 = ri->aat2870;
- u8 val;
- int ret;
-
- ret = aat2870->read(aat2870, ri->voltage_addr, &val);
- if (ret)
- return ret;
-
- return (val & ri->voltage_mask) >> ri->voltage_shift;
-}
-
-static int aat2870_ldo_enable(struct regulator_dev *rdev)
-{
- struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
- struct aat2870_data *aat2870 = ri->aat2870;
-
- return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask,
- ri->enable_mask);
-}
-
-static int aat2870_ldo_disable(struct regulator_dev *rdev)
-{
- struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
- struct aat2870_data *aat2870 = ri->aat2870;
-
- return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 0);
-}
-
-static int aat2870_ldo_is_enabled(struct regulator_dev *rdev)
-{
- struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
- struct aat2870_data *aat2870 = ri->aat2870;
- u8 val;
- int ret;
-
- ret = aat2870->read(aat2870, ri->enable_addr, &val);
- if (ret)
- return ret;
-
- return val & ri->enable_mask ? 1 : 0;
-}
-
-static const struct regulator_ops aat2870_ldo_ops = {
- .list_voltage = regulator_list_voltage_table,
- .map_voltage = regulator_map_voltage_ascend,
- .set_voltage_sel = aat2870_ldo_set_voltage_sel,
- .get_voltage_sel = aat2870_ldo_get_voltage_sel,
- .enable = aat2870_ldo_enable,
- .disable = aat2870_ldo_disable,
- .is_enabled = aat2870_ldo_is_enabled,
-};
-
-static const unsigned int aat2870_ldo_voltages[] = {
- 1200000, 1300000, 1500000, 1600000,
- 1800000, 2000000, 2200000, 2500000,
- 2600000, 2700000, 2800000, 2900000,
- 3000000, 3100000, 3200000, 3300000,
-};
-
-#define AAT2870_LDO(ids) \
- { \
- .desc = { \
- .name = #ids, \
- .id = AAT2870_ID_##ids, \
- .n_voltages = ARRAY_SIZE(aat2870_ldo_voltages), \
- .volt_table = aat2870_ldo_voltages, \
- .ops = &aat2870_ldo_ops, \
- .type = REGULATOR_VOLTAGE, \
- .owner = THIS_MODULE, \
- }, \
- }
-
-static struct aat2870_regulator aat2870_regulators[] = {
- AAT2870_LDO(LDOA),
- AAT2870_LDO(LDOB),
- AAT2870_LDO(LDOC),
- AAT2870_LDO(LDOD),
-};
-
-static struct aat2870_regulator *aat2870_get_regulator(int id)
-{
- struct aat2870_regulator *ri = NULL;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(aat2870_regulators); i++) {
- ri = &aat2870_regulators[i];
- if (ri->desc.id == id)
- break;
- }
-
- if (i == ARRAY_SIZE(aat2870_regulators))
- return NULL;
-
- ri->enable_addr = AAT2870_LDO_EN;
- ri->enable_shift = id - AAT2870_ID_LDOA;
- ri->enable_mask = 0x1 << ri->enable_shift;
-
- ri->voltage_addr = (id - AAT2870_ID_LDOA) / 2 ?
- AAT2870_LDO_CD : AAT2870_LDO_AB;
- ri->voltage_shift = (id - AAT2870_ID_LDOA) % 2 ? 0 : 4;
- ri->voltage_mask = 0xF << ri->voltage_shift;
-
- return ri;
-}
-
-static int aat2870_regulator_probe(struct platform_device *pdev)
-{
- struct aat2870_regulator *ri;
- struct regulator_config config = { };
- struct regulator_dev *rdev;
-
- ri = aat2870_get_regulator(pdev->id);
- if (!ri) {
- dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
- return -EINVAL;
- }
- ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
-
- config.dev = &pdev->dev;
- config.driver_data = ri;
- config.init_data = dev_get_platdata(&pdev->dev);
-
- rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
- if (IS_ERR(rdev)) {
- dev_err(&pdev->dev, "Failed to register regulator %s\n",
- ri->desc.name);
- return PTR_ERR(rdev);
- }
- platform_set_drvdata(pdev, rdev);
-
- return 0;
-}
-
-static struct platform_driver aat2870_regulator_driver = {
- .driver = {
- .name = "aat2870-regulator",
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
- .probe = aat2870_regulator_probe,
-};
-
-static int __init aat2870_regulator_init(void)
-{
- return platform_driver_register(&aat2870_regulator_driver);
-}
-subsys_initcall(aat2870_regulator_init);
-
-static void __exit aat2870_regulator_exit(void)
-{
- platform_driver_unregister(&aat2870_regulator_driver);
-}
-module_exit(aat2870_regulator_exit);
-
-MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
-MODULE_ALIAS("platform:aat2870-regulator");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 2c206d2713e3..4acbac1bbb9e 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -388,13 +388,6 @@ config BACKLIGHT_88PM860X
help
Say Y to enable the backlight driver for Marvell 88PM8606.
-config BACKLIGHT_AAT2870
- tristate "AnalogicTech AAT2870 Backlight"
- depends on MFD_AAT2870_CORE
- help
- If you have a AnalogicTech AAT2870 say Y to enable the
- backlight driver.
-
config BACKLIGHT_LM3509
tristate "Backlight Driver for LM3509"
depends on I2C
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 0497eaa639cd..e11175bdd500 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
-obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
deleted file mode 100644
index 8b790df1e842..000000000000
--- a/drivers/video/backlight/aat2870_bl.c
+++ /dev/null
@@ -1,206 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/video/backlight/aat2870_bl.c
- *
- * Copyright (c) 2011, NVIDIA Corporation.
- * Author: Jin Park <jinyoungp@nvidia.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/backlight.h>
-#include <linux/mfd/aat2870.h>
-
-struct aat2870_bl_driver_data {
- struct platform_device *pdev;
- struct backlight_device *bd;
-
- int channels;
- int max_current;
- int brightness; /* current brightness */
-};
-
-static inline int aat2870_brightness(struct aat2870_bl_driver_data *aat2870_bl,
- int brightness)
-{
- struct backlight_device *bd = aat2870_bl->bd;
- int val;
-
- val = brightness * (aat2870_bl->max_current - 1);
- val /= bd->props.max_brightness;
-
- return val;
-}
-
-static inline int aat2870_bl_enable(struct aat2870_bl_driver_data *aat2870_bl)
-{
- struct aat2870_data *aat2870
- = dev_get_drvdata(aat2870_bl->pdev->dev.parent);
-
- return aat2870->write(aat2870, AAT2870_BL_CH_EN,
- (u8)aat2870_bl->channels);
-}
-
-static inline int aat2870_bl_disable(struct aat2870_bl_driver_data *aat2870_bl)
-{
- struct aat2870_data *aat2870
- = dev_get_drvdata(aat2870_bl->pdev->dev.parent);
-
- return aat2870->write(aat2870, AAT2870_BL_CH_EN, 0x0);
-}
-
-static int aat2870_bl_update_status(struct backlight_device *bd)
-{
- struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd);
- struct aat2870_data *aat2870 =
- dev_get_drvdata(aat2870_bl->pdev->dev.parent);
- int brightness = backlight_get_brightness(bd);
- int ret;
-
- if ((brightness < 0) || (bd->props.max_brightness < brightness)) {
- dev_err(&bd->dev, "invalid brightness, %d\n", brightness);
- return -EINVAL;
- }
-
- dev_dbg(&bd->dev, "brightness=%d, power=%d, state=%d\n",
- bd->props.brightness, bd->props.power, bd->props.state);
-
- ret = aat2870->write(aat2870, AAT2870_BLM,
- (u8)aat2870_brightness(aat2870_bl, brightness));
- if (ret < 0)
- return ret;
-
- if (brightness == 0) {
- ret = aat2870_bl_disable(aat2870_bl);
- if (ret < 0)
- return ret;
- } else if (aat2870_bl->brightness == 0) {
- ret = aat2870_bl_enable(aat2870_bl);
- if (ret < 0)
- return ret;
- }
-
- aat2870_bl->brightness = brightness;
-
- return 0;
-}
-
-static const struct backlight_ops aat2870_bl_ops = {
- .options = BL_CORE_SUSPENDRESUME,
- .update_status = aat2870_bl_update_status,
-};
-
-static int aat2870_bl_probe(struct platform_device *pdev)
-{
- struct aat2870_bl_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct aat2870_bl_driver_data *aat2870_bl;
- struct backlight_device *bd;
- struct backlight_properties props;
- int ret = 0;
-
- if (!pdata) {
- dev_err(&pdev->dev, "No platform data\n");
- ret = -ENXIO;
- goto out;
- }
-
- if (pdev->id != AAT2870_ID_BL) {
- dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
- ret = -EINVAL;
- goto out;
- }
-
- aat2870_bl = devm_kzalloc(&pdev->dev,
- sizeof(struct aat2870_bl_driver_data),
- GFP_KERNEL);
- if (!aat2870_bl) {
- ret = -ENOMEM;
- goto out;
- }
-
- memset(&props, 0, sizeof(struct backlight_properties));
-
- props.type = BACKLIGHT_RAW;
- bd = devm_backlight_device_register(&pdev->dev, "aat2870-backlight",
- &pdev->dev, aat2870_bl, &aat2870_bl_ops,
- &props);
- if (IS_ERR(bd)) {
- dev_err(&pdev->dev,
- "Failed allocate memory for backlight device\n");
- ret = PTR_ERR(bd);
- goto out;
- }
-
- aat2870_bl->pdev = pdev;
- platform_set_drvdata(pdev, aat2870_bl);
-
- aat2870_bl->bd = bd;
-
- if (pdata->channels > 0)
- aat2870_bl->channels = pdata->channels;
- else
- aat2870_bl->channels = AAT2870_BL_CH_ALL;
-
- if (pdata->max_current > 0)
- aat2870_bl->max_current = pdata->max_current;
- else
- aat2870_bl->max_current = AAT2870_CURRENT_27_9;
-
- if (pdata->max_brightness > 0)
- bd->props.max_brightness = pdata->max_brightness;
- else
- bd->props.max_brightness = 255;
-
- aat2870_bl->brightness = 0;
- bd->props.power = BACKLIGHT_POWER_ON;
- bd->props.brightness = bd->props.max_brightness;
-
- ret = aat2870_bl_update_status(bd);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to initialize\n");
- return ret;
- }
-
- return 0;
-
-out:
- return ret;
-}
-
-static void aat2870_bl_remove(struct platform_device *pdev)
-{
- struct aat2870_bl_driver_data *aat2870_bl = platform_get_drvdata(pdev);
- struct backlight_device *bd = aat2870_bl->bd;
-
- bd->props.power = BACKLIGHT_POWER_OFF;
- bd->props.brightness = 0;
- backlight_update_status(bd);
-}
-
-static struct platform_driver aat2870_bl_driver = {
- .driver = {
- .name = "aat2870-backlight",
- },
- .probe = aat2870_bl_probe,
- .remove = aat2870_bl_remove,
-};
-
-static int __init aat2870_bl_init(void)
-{
- return platform_driver_register(&aat2870_bl_driver);
-}
-subsys_initcall(aat2870_bl_init);
-
-static void __exit aat2870_bl_exit(void)
-{
- platform_driver_unregister(&aat2870_bl_driver);
-}
-module_exit(aat2870_bl_exit);
-
-MODULE_DESCRIPTION("AnalogicTech AAT2870 Backlight");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
diff --git a/include/linux/mfd/aat2870.h b/include/linux/mfd/aat2870.h
deleted file mode 100644
index c7a3c53eba68..000000000000
--- a/include/linux/mfd/aat2870.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * linux/include/linux/mfd/aat2870.h
- *
- * Copyright (c) 2011, NVIDIA Corporation.
- * Author: Jin Park <jinyoungp@nvidia.com>
- */
-
-#ifndef __LINUX_MFD_AAT2870_H
-#define __LINUX_MFD_AAT2870_H
-
-#include <linux/debugfs.h>
-#include <linux/i2c.h>
-
-/* Register offsets */
-#define AAT2870_BL_CH_EN 0x00
-#define AAT2870_BLM 0x01
-#define AAT2870_BLS 0x02
-#define AAT2870_BL1 0x03
-#define AAT2870_BL2 0x04
-#define AAT2870_BL3 0x05
-#define AAT2870_BL4 0x06
-#define AAT2870_BL5 0x07
-#define AAT2870_BL6 0x08
-#define AAT2870_BL7 0x09
-#define AAT2870_BL8 0x0A
-#define AAT2870_FLR 0x0B
-#define AAT2870_FM 0x0C
-#define AAT2870_FS 0x0D
-#define AAT2870_ALS_CFG0 0x0E
-#define AAT2870_ALS_CFG1 0x0F
-#define AAT2870_ALS_CFG2 0x10
-#define AAT2870_AMB 0x11
-#define AAT2870_ALS0 0x12
-#define AAT2870_ALS1 0x13
-#define AAT2870_ALS2 0x14
-#define AAT2870_ALS3 0x15
-#define AAT2870_ALS4 0x16
-#define AAT2870_ALS5 0x17
-#define AAT2870_ALS6 0x18
-#define AAT2870_ALS7 0x19
-#define AAT2870_ALS8 0x1A
-#define AAT2870_ALS9 0x1B
-#define AAT2870_ALSA 0x1C
-#define AAT2870_ALSB 0x1D
-#define AAT2870_ALSC 0x1E
-#define AAT2870_ALSD 0x1F
-#define AAT2870_ALSE 0x20
-#define AAT2870_ALSF 0x21
-#define AAT2870_SUB_SET 0x22
-#define AAT2870_SUB_CTRL 0x23
-#define AAT2870_LDO_AB 0x24
-#define AAT2870_LDO_CD 0x25
-#define AAT2870_LDO_EN 0x26
-#define AAT2870_REG_NUM 0x27
-
-/* Device IDs */
-enum aat2870_id {
- AAT2870_ID_BL,
- AAT2870_ID_LDOA,
- AAT2870_ID_LDOB,
- AAT2870_ID_LDOC,
- AAT2870_ID_LDOD
-};
-
-/* Backlight channels */
-#define AAT2870_BL_CH1 0x01
-#define AAT2870_BL_CH2 0x02
-#define AAT2870_BL_CH3 0x04
-#define AAT2870_BL_CH4 0x08
-#define AAT2870_BL_CH5 0x10
-#define AAT2870_BL_CH6 0x20
-#define AAT2870_BL_CH7 0x40
-#define AAT2870_BL_CH8 0x80
-#define AAT2870_BL_CH_ALL 0xFF
-
-/* Backlight current magnitude (mA) */
-enum aat2870_current {
- AAT2870_CURRENT_0_45 = 1,
- AAT2870_CURRENT_0_90,
- AAT2870_CURRENT_1_80,
- AAT2870_CURRENT_2_70,
- AAT2870_CURRENT_3_60,
- AAT2870_CURRENT_4_50,
- AAT2870_CURRENT_5_40,
- AAT2870_CURRENT_6_30,
- AAT2870_CURRENT_7_20,
- AAT2870_CURRENT_8_10,
- AAT2870_CURRENT_9_00,
- AAT2870_CURRENT_9_90,
- AAT2870_CURRENT_10_8,
- AAT2870_CURRENT_11_7,
- AAT2870_CURRENT_12_6,
- AAT2870_CURRENT_13_5,
- AAT2870_CURRENT_14_4,
- AAT2870_CURRENT_15_3,
- AAT2870_CURRENT_16_2,
- AAT2870_CURRENT_17_1,
- AAT2870_CURRENT_18_0,
- AAT2870_CURRENT_18_9,
- AAT2870_CURRENT_19_8,
- AAT2870_CURRENT_20_7,
- AAT2870_CURRENT_21_6,
- AAT2870_CURRENT_22_5,
- AAT2870_CURRENT_23_4,
- AAT2870_CURRENT_24_3,
- AAT2870_CURRENT_25_2,
- AAT2870_CURRENT_26_1,
- AAT2870_CURRENT_27_0,
- AAT2870_CURRENT_27_9
-};
-
-struct aat2870_register {
- bool readable;
- bool writeable;
- u8 value;
-};
-
-struct aat2870_data {
- struct device *dev;
- struct i2c_client *client;
-
- struct mutex io_lock;
- struct aat2870_register *reg_cache; /* register cache */
- int en_pin; /* enable GPIO pin (if < 0, ignore this value) */
- bool is_enable;
-
- /* init and uninit for platform specified */
- int (*init)(struct aat2870_data *aat2870);
- void (*uninit)(struct aat2870_data *aat2870);
-
- /* i2c io funcntions */
- int (*read)(struct aat2870_data *aat2870, u8 addr, u8 *val);
- int (*write)(struct aat2870_data *aat2870, u8 addr, u8 val);
- int (*update)(struct aat2870_data *aat2870, u8 addr, u8 mask, u8 val);
-};
-
-struct aat2870_subdev_info {
- int id;
- const char *name;
- void *platform_data;
-};
-
-struct aat2870_platform_data {
- int en_pin; /* enable GPIO pin (if < 0, ignore this value) */
-
- struct aat2870_subdev_info *subdevs;
- int num_subdevs;
-
- /* init and uninit for platform specified */
- int (*init)(struct aat2870_data *aat2870);
- void (*uninit)(struct aat2870_data *aat2870);
-};
-
-struct aat2870_bl_platform_data {
- /* backlight channels, default is AAT2870_BL_CH_ALL */
- int channels;
- /* backlight current magnitude, default is AAT2870_CURRENT_27_9 */
- int max_current;
- /* maximum brightness, default is 255 */
- int max_brightness;
-};
-
-#endif /* __LINUX_MFD_AAT2870_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* [PATCH 09/14] mfd: remove unused lm3533 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (5 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 08/14] mfd: remove unused aat2870 driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:44 ` Johan Hovold
2026-09-09 13:21 ` [PATCH 10/14] mfd: remove unused rc5t583 driver Arnd Bergmann
` (7 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
This driver has apparently never had any users, as it does not support
devicetree probing, and no lm3533_platform_data definition ever
existed upstream.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/iio/light/Kconfig | 17 -
drivers/iio/light/Makefile | 1 -
drivers/iio/light/lm3533-als.c | 922 ----------------------------
drivers/leds/Kconfig | 13 -
drivers/leds/Makefile | 1 -
drivers/leds/leds-lm3533.c | 755 -----------------------
drivers/mfd/Kconfig | 13 -
drivers/mfd/Makefile | 1 -
drivers/mfd/lm3533-core.c | 635 -------------------
drivers/mfd/lm3533-ctrlbank.c | 162 -----
drivers/video/backlight/Kconfig | 11 -
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/lm3533_bl.c | 398 ------------
include/linux/mfd/lm3533.h | 99 ---
14 files changed, 3029 deletions(-)
delete mode 100644 drivers/iio/light/lm3533-als.c
delete mode 100644 drivers/leds/leds-lm3533.c
delete mode 100644 drivers/mfd/lm3533-core.c
delete mode 100644 drivers/mfd/lm3533-ctrlbank.c
delete mode 100644 drivers/video/backlight/lm3533_bl.c
delete mode 100644 include/linux/mfd/lm3533.h
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index f23bbce12c72..afef3d25e6ed 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -394,23 +394,6 @@ config RPR0521
To compile this driver as a module, choose M here:
the module will be called rpr0521.
-config SENSORS_LM3533
- tristate "LM3533 ambient light sensor"
- depends on MFD_LM3533
- help
- If you say yes here you get support for the ambient light sensor
- interface on National Semiconductor / TI LM3533 Lighting Power
- chips.
-
- The sensor interface can be used to control the LEDs and backlights
- of the chip through defining five light zones and three sets of
- corresponding output-current values.
-
- The driver provides raw and mean adc readings along with the current
- light zone through sysfs. A threshold event can be generated on zone
- changes. The ALS-control output values can be set per zone for the
- three current output channels.
-
config LTR390
tristate "LTR-390UV-01 ambient light and UV sensor"
depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 64e354c49ed8..7b9de7c83999 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -35,7 +35,6 @@ obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
obj-$(CONFIG_ISL29125) += isl29125.o
obj-$(CONFIG_ISL76682) += isl76682.o
obj-$(CONFIG_JSA1212) += jsa1212.o
-obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
obj-$(CONFIG_LTR390) += ltr390.o
obj-$(CONFIG_LTR501) += ltr501.o
obj-$(CONFIG_LTRF216A) += ltrf216a.o
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
deleted file mode 100644
index 99f0b903018c..000000000000
--- a/drivers/iio/light/lm3533-als.c
+++ /dev/null
@@ -1,922 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * lm3533-als.c -- LM3533 Ambient Light Sensor driver
- *
- * Copyright (C) 2011-2012 Texas Instruments
- *
- * Author: Johan Hovold <jhovold@gmail.com>
- */
-
-#include <linux/atomic.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/iio/events.h>
-#include <linux/iio/iio.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/mfd/core.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <linux/mfd/lm3533.h>
-
-
-#define LM3533_ALS_RESISTOR_MIN 1
-#define LM3533_ALS_RESISTOR_MAX 127
-#define LM3533_ALS_CHANNEL_CURRENT_MAX 2
-#define LM3533_ALS_THRESH_MAX 3
-#define LM3533_ALS_ZONE_MAX 4
-
-#define LM3533_REG_ALS_RESISTOR_SELECT 0x30
-#define LM3533_REG_ALS_CONF 0x31
-#define LM3533_REG_ALS_ZONE_INFO 0x34
-#define LM3533_REG_ALS_READ_ADC_RAW 0x37
-#define LM3533_REG_ALS_READ_ADC_AVERAGE 0x38
-#define LM3533_REG_ALS_BOUNDARY_BASE 0x50
-#define LM3533_REG_ALS_TARGET_BASE 0x60
-
-#define LM3533_ALS_ENABLE_MASK 0x01
-#define LM3533_ALS_INPUT_MODE_MASK 0x02
-#define LM3533_ALS_INT_ENABLE_MASK 0x01
-
-#define LM3533_ALS_ZONE_SHIFT 2
-#define LM3533_ALS_ZONE_MASK 0x1c
-
-#define LM3533_ALS_FLAG_INT_ENABLED 1
-
-
-struct lm3533_als {
- struct lm3533 *lm3533;
- struct platform_device *pdev;
-
- unsigned long flags;
- int irq;
-
- atomic_t zone;
- struct mutex thresh_mutex;
-};
-
-
-static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average,
- int *adc)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 reg;
- u8 val;
- int ret;
-
- if (average)
- reg = LM3533_REG_ALS_READ_ADC_AVERAGE;
- else
- reg = LM3533_REG_ALS_READ_ADC_RAW;
-
- ret = lm3533_read(als->lm3533, reg, &val);
- if (ret) {
- dev_err(&indio_dev->dev, "failed to read adc\n");
- return ret;
- }
-
- *adc = val;
-
- return 0;
-}
-
-static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 val;
- int ret;
-
- ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
- if (ret) {
- dev_err(&indio_dev->dev, "failed to read zone\n");
- return ret;
- }
-
- val = (val & LM3533_ALS_ZONE_MASK) >> LM3533_ALS_ZONE_SHIFT;
- *zone = min_t(u8, val, LM3533_ALS_ZONE_MAX);
-
- return 0;
-}
-
-static int lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- int ret;
-
- if (test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags)) {
- *zone = atomic_read(&als->zone);
- } else {
- ret = _lm3533_als_get_zone(indio_dev, zone);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/*
- * channel output channel 0..2
- * zone zone 0..4
- */
-static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone)
-{
- return LM3533_REG_ALS_TARGET_BASE + 5 * channel + zone;
-}
-
-static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel,
- unsigned zone, u8 *val)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 reg;
- int ret;
-
- if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
- return -EINVAL;
-
- if (zone > LM3533_ALS_ZONE_MAX)
- return -EINVAL;
-
- reg = lm3533_als_get_target_reg(channel, zone);
- ret = lm3533_read(als->lm3533, reg, val);
- if (ret)
- dev_err(&indio_dev->dev, "failed to get target current\n");
-
- return ret;
-}
-
-static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel,
- unsigned zone, u8 val)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 reg;
- int ret;
-
- if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
- return -EINVAL;
-
- if (zone > LM3533_ALS_ZONE_MAX)
- return -EINVAL;
-
- reg = lm3533_als_get_target_reg(channel, zone);
- ret = lm3533_write(als->lm3533, reg, val);
- if (ret)
- dev_err(&indio_dev->dev, "failed to set target current\n");
-
- return ret;
-}
-
-static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel,
- int *val)
-{
- u8 zone;
- u8 target;
- int ret;
-
- ret = lm3533_als_get_zone(indio_dev, &zone);
- if (ret)
- return ret;
-
- ret = lm3533_als_get_target(indio_dev, channel, zone, &target);
- if (ret)
- return ret;
-
- *val = target;
-
- return 0;
-}
-
-static int lm3533_als_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
-{
- int ret;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- switch (chan->type) {
- case IIO_LIGHT:
- ret = lm3533_als_get_adc(indio_dev, false, val);
- break;
- case IIO_CURRENT:
- ret = lm3533_als_get_current(indio_dev, chan->channel,
- val);
- break;
- default:
- return -EINVAL;
- }
- break;
- case IIO_CHAN_INFO_AVERAGE_RAW:
- ret = lm3533_als_get_adc(indio_dev, true, val);
- break;
- default:
- return -EINVAL;
- }
-
- if (ret)
- return ret;
-
- return IIO_VAL_INT;
-}
-
-#define CHANNEL_CURRENT(_channel) \
- { \
- .type = IIO_CURRENT, \
- .channel = _channel, \
- .indexed = true, \
- .output = true, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- }
-
-static const struct iio_chan_spec lm3533_als_channels[] = {
- {
- .type = IIO_LIGHT,
- .channel = 0,
- .indexed = true,
- .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) |
- BIT(IIO_CHAN_INFO_RAW),
- },
- CHANNEL_CURRENT(0),
- CHANNEL_CURRENT(1),
- CHANNEL_CURRENT(2),
-};
-
-static irqreturn_t lm3533_als_isr(int irq, void *dev_id)
-{
-
- struct iio_dev *indio_dev = dev_id;
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 zone;
- int ret;
-
- /* Clear interrupt by reading the ALS zone register. */
- ret = _lm3533_als_get_zone(indio_dev, &zone);
- if (ret)
- goto out;
-
- atomic_set(&als->zone, zone);
-
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
- 0,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_EITHER),
- iio_get_time_ns(indio_dev));
-out:
- return IRQ_HANDLED;
-}
-
-static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 mask = LM3533_ALS_INT_ENABLE_MASK;
- u8 val;
- int ret;
-
- if (enable)
- val = mask;
- else
- val = 0;
-
- ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask);
- if (ret) {
- dev_err(&indio_dev->dev, "failed to set int mode %d\n",
- enable);
- return ret;
- }
-
- return 0;
-}
-
-static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 mask = LM3533_ALS_INT_ENABLE_MASK;
- u8 val;
- int ret;
-
- ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
- if (ret) {
- dev_err(&indio_dev->dev, "failed to get int mode\n");
- return ret;
- }
-
- *enable = !!(val & mask);
-
- return 0;
-}
-
-static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising)
-{
- u8 offset = !raising;
-
- return LM3533_REG_ALS_BOUNDARY_BASE + 2 * nr + offset;
-}
-
-static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr,
- bool raising, u8 *val)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 reg;
- int ret;
-
- if (nr > LM3533_ALS_THRESH_MAX)
- return -EINVAL;
-
- reg = lm3533_als_get_threshold_reg(nr, raising);
- ret = lm3533_read(als->lm3533, reg, val);
- if (ret)
- dev_err(&indio_dev->dev, "failed to get threshold\n");
-
- return ret;
-}
-
-static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
- bool raising, u8 val)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 val2;
- u8 reg, reg2;
- int ret;
-
- if (nr > LM3533_ALS_THRESH_MAX)
- return -EINVAL;
-
- reg = lm3533_als_get_threshold_reg(nr, raising);
- reg2 = lm3533_als_get_threshold_reg(nr, !raising);
-
- mutex_lock(&als->thresh_mutex);
- ret = lm3533_read(als->lm3533, reg2, &val2);
- if (ret) {
- dev_err(&indio_dev->dev, "failed to get threshold\n");
- goto out;
- }
- /*
- * This device does not allow negative hysteresis (in fact, it uses
- * whichever value is smaller as the lower bound) so we need to make
- * sure that thresh_falling <= thresh_raising.
- */
- if ((raising && (val < val2)) || (!raising && (val > val2))) {
- ret = -EINVAL;
- goto out;
- }
-
- ret = lm3533_write(als->lm3533, reg, val);
- if (ret) {
- dev_err(&indio_dev->dev, "failed to set threshold\n");
- goto out;
- }
-out:
- mutex_unlock(&als->thresh_mutex);
-
- return ret;
-}
-
-static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr,
- u8 *val)
-{
- struct lm3533_als *als = iio_priv(indio_dev);
- u8 falling;
- u8 raising;
- int ret;
-
- if (nr > LM3533_ALS_THRESH_MAX)
- return -EINVAL;
-
- mutex_lock(&als->thresh_mutex);
- ret = lm3533_als_get_threshold(indio_dev, nr, false, &falling);
- if (ret)
- goto out;
- ret = lm3533_als_get_threshold(indio_dev, nr, true, &raising);
- if (ret)
- goto out;
-
- *val = raising - falling;
-out:
- mutex_unlock(&als->thresh_mutex);
-
- return ret;
-}
-
-static ssize_t show_thresh_either_en(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct lm3533_als *als = iio_priv(indio_dev);
- int enable;
- int ret;
-
- if (als->irq) {
- ret = lm3533_als_get_int_mode(indio_dev, &enable);
- if (ret)
- return ret;
- } else {
- enable = 0;
- }
-
- return sysfs_emit(buf, "%u\n", enable);
-}
-
-static ssize_t store_thresh_either_en(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct lm3533_als *als = iio_priv(indio_dev);
- unsigned long enable;
- bool int_enabled;
- u8 zone;
- int ret;
-
- if (!als->irq)
- return -EBUSY;
-
- if (kstrtoul(buf, 0, &enable))
- return -EINVAL;
-
- int_enabled = test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
-
- if (enable && !int_enabled) {
- ret = lm3533_als_get_zone(indio_dev, &zone);
- if (ret)
- return ret;
-
- atomic_set(&als->zone, zone);
-
- set_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
- }
-
- ret = lm3533_als_set_int_mode(indio_dev, enable);
- if (ret) {
- if (!int_enabled)
- clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
-
- return ret;
- }
-
- if (!enable)
- clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
-
- return len;
-}
-
-static ssize_t show_zone(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- u8 zone;
- int ret;
-
- ret = lm3533_als_get_zone(indio_dev, &zone);
- if (ret)
- return ret;
-
- return sysfs_emit(buf, "%u\n", zone);
-}
-
-enum lm3533_als_attribute_type {
- LM3533_ATTR_TYPE_HYSTERESIS,
- LM3533_ATTR_TYPE_TARGET,
- LM3533_ATTR_TYPE_THRESH_FALLING,
- LM3533_ATTR_TYPE_THRESH_RAISING,
-};
-
-struct lm3533_als_attribute {
- struct device_attribute dev_attr;
- enum lm3533_als_attribute_type type;
- u8 val1;
- u8 val2;
-};
-
-static inline struct lm3533_als_attribute *
-to_lm3533_als_attr(struct device_attribute *attr)
-{
- return container_of(attr, struct lm3533_als_attribute, dev_attr);
-}
-
-static ssize_t show_als_attr(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr);
- u8 val;
- int ret;
-
- switch (als_attr->type) {
- case LM3533_ATTR_TYPE_HYSTERESIS:
- ret = lm3533_als_get_hysteresis(indio_dev, als_attr->val1,
- &val);
- break;
- case LM3533_ATTR_TYPE_TARGET:
- ret = lm3533_als_get_target(indio_dev, als_attr->val1,
- als_attr->val2, &val);
- break;
- case LM3533_ATTR_TYPE_THRESH_FALLING:
- ret = lm3533_als_get_threshold(indio_dev, als_attr->val1,
- false, &val);
- break;
- case LM3533_ATTR_TYPE_THRESH_RAISING:
- ret = lm3533_als_get_threshold(indio_dev, als_attr->val1,
- true, &val);
- break;
- default:
- ret = -ENXIO;
- }
-
- if (ret)
- return ret;
-
- return sysfs_emit(buf, "%u\n", val);
-}
-
-static ssize_t store_als_attr(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr);
- u8 val;
- int ret;
-
- if (kstrtou8(buf, 0, &val))
- return -EINVAL;
-
- switch (als_attr->type) {
- case LM3533_ATTR_TYPE_TARGET:
- ret = lm3533_als_set_target(indio_dev, als_attr->val1,
- als_attr->val2, val);
- break;
- case LM3533_ATTR_TYPE_THRESH_FALLING:
- ret = lm3533_als_set_threshold(indio_dev, als_attr->val1,
- false, val);
- break;
- case LM3533_ATTR_TYPE_THRESH_RAISING:
- ret = lm3533_als_set_threshold(indio_dev, als_attr->val1,
- true, val);
- break;
- default:
- ret = -ENXIO;
- }
-
- if (ret)
- return ret;
-
- return len;
-}
-
-#define ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \
- { .dev_attr = __ATTR(_name, _mode, _show, _store), \
- .type = _type, \
- .val1 = _val1, \
- .val2 = _val2 }
-
-#define LM3533_ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \
- struct lm3533_als_attribute lm3533_als_attr_##_name = \
- ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2)
-
-#define ALS_TARGET_ATTR_RW(_channel, _zone) \
- LM3533_ALS_ATTR(out_current##_channel##_current##_zone##_raw, \
- S_IRUGO | S_IWUSR, \
- show_als_attr, store_als_attr, \
- LM3533_ATTR_TYPE_TARGET, _channel, _zone)
-/*
- * ALS output current values (ALS mapper targets)
- *
- * out_current[0-2]_current[0-4]_raw 0-255
- */
-static ALS_TARGET_ATTR_RW(0, 0);
-static ALS_TARGET_ATTR_RW(0, 1);
-static ALS_TARGET_ATTR_RW(0, 2);
-static ALS_TARGET_ATTR_RW(0, 3);
-static ALS_TARGET_ATTR_RW(0, 4);
-
-static ALS_TARGET_ATTR_RW(1, 0);
-static ALS_TARGET_ATTR_RW(1, 1);
-static ALS_TARGET_ATTR_RW(1, 2);
-static ALS_TARGET_ATTR_RW(1, 3);
-static ALS_TARGET_ATTR_RW(1, 4);
-
-static ALS_TARGET_ATTR_RW(2, 0);
-static ALS_TARGET_ATTR_RW(2, 1);
-static ALS_TARGET_ATTR_RW(2, 2);
-static ALS_TARGET_ATTR_RW(2, 3);
-static ALS_TARGET_ATTR_RW(2, 4);
-
-#define ALS_THRESH_FALLING_ATTR_RW(_nr) \
- LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_falling_value, \
- S_IRUGO | S_IWUSR, \
- show_als_attr, store_als_attr, \
- LM3533_ATTR_TYPE_THRESH_FALLING, _nr, 0)
-
-#define ALS_THRESH_RAISING_ATTR_RW(_nr) \
- LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_raising_value, \
- S_IRUGO | S_IWUSR, \
- show_als_attr, store_als_attr, \
- LM3533_ATTR_TYPE_THRESH_RAISING, _nr, 0)
-/*
- * ALS Zone thresholds (boundaries)
- *
- * in_illuminance0_thresh[0-3]_falling_value 0-255
- * in_illuminance0_thresh[0-3]_raising_value 0-255
- */
-static ALS_THRESH_FALLING_ATTR_RW(0);
-static ALS_THRESH_FALLING_ATTR_RW(1);
-static ALS_THRESH_FALLING_ATTR_RW(2);
-static ALS_THRESH_FALLING_ATTR_RW(3);
-
-static ALS_THRESH_RAISING_ATTR_RW(0);
-static ALS_THRESH_RAISING_ATTR_RW(1);
-static ALS_THRESH_RAISING_ATTR_RW(2);
-static ALS_THRESH_RAISING_ATTR_RW(3);
-
-#define ALS_HYSTERESIS_ATTR_RO(_nr) \
- LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_hysteresis, \
- S_IRUGO, show_als_attr, NULL, \
- LM3533_ATTR_TYPE_HYSTERESIS, _nr, 0)
-/*
- * ALS Zone threshold hysteresis
- *
- * threshY_hysteresis = threshY_raising - threshY_falling
- *
- * in_illuminance0_thresh[0-3]_hysteresis 0-255
- * in_illuminance0_thresh[0-3]_hysteresis 0-255
- */
-static ALS_HYSTERESIS_ATTR_RO(0);
-static ALS_HYSTERESIS_ATTR_RO(1);
-static ALS_HYSTERESIS_ATTR_RO(2);
-static ALS_HYSTERESIS_ATTR_RO(3);
-
-#define ILLUMINANCE_ATTR_RO(_name) \
- DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL)
-#define ILLUMINANCE_ATTR_RW(_name) \
- DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR, \
- show_##_name, store_##_name)
-/*
- * ALS Zone threshold-event enable
- *
- * in_illuminance0_thresh_either_en 0,1
- */
-static ILLUMINANCE_ATTR_RW(thresh_either_en);
-
-/*
- * ALS Current Zone
- *
- * in_illuminance0_zone 0-4
- */
-static ILLUMINANCE_ATTR_RO(zone);
-
-static struct attribute *lm3533_als_event_attributes[] = {
- &dev_attr_in_illuminance0_thresh_either_en.attr,
- &lm3533_als_attr_in_illuminance0_thresh0_falling_value.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh0_hysteresis.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh0_raising_value.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh1_falling_value.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh1_hysteresis.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh1_raising_value.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh2_falling_value.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh2_hysteresis.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh2_raising_value.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh3_falling_value.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh3_hysteresis.dev_attr.attr,
- &lm3533_als_attr_in_illuminance0_thresh3_raising_value.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group lm3533_als_event_attribute_group = {
- .attrs = lm3533_als_event_attributes
-};
-
-static struct attribute *lm3533_als_attributes[] = {
- &dev_attr_in_illuminance0_zone.attr,
- &lm3533_als_attr_out_current0_current0_raw.dev_attr.attr,
- &lm3533_als_attr_out_current0_current1_raw.dev_attr.attr,
- &lm3533_als_attr_out_current0_current2_raw.dev_attr.attr,
- &lm3533_als_attr_out_current0_current3_raw.dev_attr.attr,
- &lm3533_als_attr_out_current0_current4_raw.dev_attr.attr,
- &lm3533_als_attr_out_current1_current0_raw.dev_attr.attr,
- &lm3533_als_attr_out_current1_current1_raw.dev_attr.attr,
- &lm3533_als_attr_out_current1_current2_raw.dev_attr.attr,
- &lm3533_als_attr_out_current1_current3_raw.dev_attr.attr,
- &lm3533_als_attr_out_current1_current4_raw.dev_attr.attr,
- &lm3533_als_attr_out_current2_current0_raw.dev_attr.attr,
- &lm3533_als_attr_out_current2_current1_raw.dev_attr.attr,
- &lm3533_als_attr_out_current2_current2_raw.dev_attr.attr,
- &lm3533_als_attr_out_current2_current3_raw.dev_attr.attr,
- &lm3533_als_attr_out_current2_current4_raw.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group lm3533_als_attribute_group = {
- .attrs = lm3533_als_attributes
-};
-
-static int lm3533_als_set_input_mode(struct lm3533_als *als, bool pwm_mode)
-{
- u8 mask = LM3533_ALS_INPUT_MODE_MASK;
- u8 val;
- int ret;
-
- if (pwm_mode)
- val = mask; /* pwm input */
- else
- val = 0; /* analog input */
-
- ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask);
- if (ret) {
- dev_err(&als->pdev->dev, "failed to set input mode %d\n",
- pwm_mode);
- return ret;
- }
-
- return 0;
-}
-
-static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
-{
- int ret;
-
- if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) {
- dev_err(&als->pdev->dev, "invalid resistor value\n");
- return -EINVAL;
- }
-
- ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val);
- if (ret) {
- dev_err(&als->pdev->dev, "failed to set resistor\n");
- return ret;
- }
-
- return 0;
-}
-
-static int lm3533_als_setup(struct lm3533_als *als,
- const struct lm3533_als_platform_data *pdata)
-{
- int ret;
-
- ret = lm3533_als_set_input_mode(als, pdata->pwm_mode);
- if (ret)
- return ret;
-
- /* ALS input is always high impedance in PWM-mode. */
- if (!pdata->pwm_mode) {
- ret = lm3533_als_set_resistor(als, pdata->r_select);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev)
-{
- u8 mask = LM3533_ALS_INT_ENABLE_MASK;
- int ret;
-
- /* Make sure interrupts are disabled. */
- ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask);
- if (ret) {
- dev_err(&als->pdev->dev, "failed to disable interrupts\n");
- return ret;
- }
-
- ret = request_threaded_irq(als->irq, NULL, lm3533_als_isr,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- dev_name(&als->pdev->dev), dev);
- if (ret) {
- dev_err(&als->pdev->dev, "failed to request irq %d\n",
- als->irq);
- return ret;
- }
-
- return 0;
-}
-
-static int lm3533_als_enable(struct lm3533_als *als)
-{
- u8 mask = LM3533_ALS_ENABLE_MASK;
- int ret;
-
- ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask);
- if (ret)
- dev_err(&als->pdev->dev, "failed to enable ALS\n");
-
- return ret;
-}
-
-static int lm3533_als_disable(struct lm3533_als *als)
-{
- u8 mask = LM3533_ALS_ENABLE_MASK;
- int ret;
-
- ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask);
- if (ret)
- dev_err(&als->pdev->dev, "failed to disable ALS\n");
-
- return ret;
-}
-
-static const struct iio_info lm3533_als_info = {
- .attrs = &lm3533_als_attribute_group,
- .event_attrs = &lm3533_als_event_attribute_group,
- .read_raw = &lm3533_als_read_raw,
-};
-
-static int lm3533_als_probe(struct platform_device *pdev)
-{
- const struct lm3533_als_platform_data *pdata;
- struct lm3533 *lm3533;
- struct lm3533_als *als;
- struct iio_dev *indio_dev;
- int ret;
-
- lm3533 = dev_get_drvdata(pdev->dev.parent);
- if (!lm3533)
- return -EINVAL;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
- indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
- if (!indio_dev)
- return -ENOMEM;
-
- indio_dev->info = &lm3533_als_info;
- indio_dev->channels = lm3533_als_channels;
- indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels);
- indio_dev->name = dev_name(&pdev->dev);
- iio_device_set_parent(indio_dev, pdev->dev.parent);
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- als = iio_priv(indio_dev);
- als->lm3533 = lm3533;
- als->pdev = pdev;
- als->irq = lm3533->irq;
- atomic_set(&als->zone, 0);
- mutex_init(&als->thresh_mutex);
-
- platform_set_drvdata(pdev, indio_dev);
-
- if (als->irq) {
- ret = lm3533_als_setup_irq(als, indio_dev);
- if (ret)
- return ret;
- }
-
- ret = lm3533_als_setup(als, pdata);
- if (ret)
- goto err_free_irq;
-
- ret = lm3533_als_enable(als);
- if (ret)
- goto err_free_irq;
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "failed to register ALS\n");
- goto err_disable;
- }
-
- return 0;
-
-err_disable:
- lm3533_als_disable(als);
-err_free_irq:
- if (als->irq)
- free_irq(als->irq, indio_dev);
-
- return ret;
-}
-
-static void lm3533_als_remove(struct platform_device *pdev)
-{
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct lm3533_als *als = iio_priv(indio_dev);
-
- lm3533_als_set_int_mode(indio_dev, false);
- iio_device_unregister(indio_dev);
- lm3533_als_disable(als);
- if (als->irq)
- free_irq(als->irq, indio_dev);
-}
-
-static struct platform_driver lm3533_als_driver = {
- .driver = {
- .name = "lm3533-als",
- },
- .probe = lm3533_als_probe,
- .remove = lm3533_als_remove,
-};
-module_platform_driver(lm3533_als_driver);
-
-MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
-MODULE_DESCRIPTION("LM3533 Ambient Light Sensor driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lm3533-als");
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f0cd10ad6279..1a0663a6501c 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -262,19 +262,6 @@ config LEDS_LM3532
controlled manually or using PWM input or using ambient
light automatically.
-config LEDS_LM3533
- tristate "LED support for LM3533"
- depends on LEDS_CLASS
- depends on MFD_LM3533
- help
- This option enables support for the LEDs on National Semiconductor /
- TI LM3533 Lighting Power chips.
-
- The LEDs can be controlled directly, through PWM input, or by the
- ambient-light-sensor interface. The chip supports
- hardware-accelerated blinking with maximum on and off periods of 9.8
- and 77 seconds respectively.
-
config LEDS_LM3642
tristate "LED support for LM3642 Chip"
depends on LEDS_CLASS && I2C
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 63dc0b0c5a51..b989803bedb9 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -39,7 +39,6 @@ obj-$(CONFIG_LEDS_IS31FL319X) += leds-is31fl319x.o
obj-$(CONFIG_LEDS_IS31FL32XX) += leds-is31fl32xx.o
obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
obj-$(CONFIG_LEDS_LM3532) += leds-lm3532.o
-obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o
obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o
obj-$(CONFIG_LEDS_LM3642) += leds-lm3642.o
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
deleted file mode 100644
index 45795f2a1042..000000000000
--- a/drivers/leds/leds-lm3533.c
+++ /dev/null
@@ -1,755 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * leds-lm3533.c -- LM3533 LED driver
- *
- * Copyright (C) 2011-2012 Texas Instruments
- *
- * Author: Johan Hovold <jhovold@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/leds.h>
-#include <linux/mfd/core.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <linux/mfd/lm3533.h>
-
-
-#define LM3533_LVCTRLBANK_MIN 2
-#define LM3533_LVCTRLBANK_MAX 5
-#define LM3533_LVCTRLBANK_COUNT 4
-#define LM3533_RISEFALLTIME_MAX 7
-#define LM3533_ALS_CHANNEL_LV_MIN 1
-#define LM3533_ALS_CHANNEL_LV_MAX 2
-
-#define LM3533_REG_CTRLBANK_BCONF_BASE 0x1b
-#define LM3533_REG_PATTERN_ENABLE 0x28
-#define LM3533_REG_PATTERN_LOW_TIME_BASE 0x71
-#define LM3533_REG_PATTERN_HIGH_TIME_BASE 0x72
-#define LM3533_REG_PATTERN_RISETIME_BASE 0x74
-#define LM3533_REG_PATTERN_FALLTIME_BASE 0x75
-
-#define LM3533_REG_PATTERN_STEP 0x10
-
-#define LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK 0x04
-#define LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK 0x02
-#define LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK 0x01
-
-#define LM3533_LED_FLAG_PATTERN_ENABLE 1
-
-
-struct lm3533_led {
- struct lm3533 *lm3533;
- struct lm3533_ctrlbank cb;
- struct led_classdev cdev;
- int id;
-
- struct mutex mutex;
- unsigned long flags;
-};
-
-
-static inline struct lm3533_led *to_lm3533_led(struct led_classdev *cdev)
-{
- return container_of(cdev, struct lm3533_led, cdev);
-}
-
-static inline int lm3533_led_get_ctrlbank_id(struct lm3533_led *led)
-{
- return led->id + 2;
-}
-
-static inline u8 lm3533_led_get_lv_reg(struct lm3533_led *led, u8 base)
-{
- return base + led->id;
-}
-
-static inline u8 lm3533_led_get_pattern(struct lm3533_led *led)
-{
- return led->id;
-}
-
-static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led,
- u8 base)
-{
- return base + lm3533_led_get_pattern(led) * LM3533_REG_PATTERN_STEP;
-}
-
-static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable)
-{
- u8 mask;
- u8 val;
- int pattern;
- int state;
- int ret = 0;
-
- dev_dbg(led->cdev.dev, "%s - %d\n", __func__, enable);
-
- mutex_lock(&led->mutex);
-
- state = test_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
- if ((enable && state) || (!enable && !state))
- goto out;
-
- pattern = lm3533_led_get_pattern(led);
- mask = 1 << (2 * pattern);
-
- if (enable)
- val = mask;
- else
- val = 0;
-
- ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask);
- if (ret) {
- dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n",
- pattern, enable);
- goto out;
- }
-
- __change_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
-out:
- mutex_unlock(&led->mutex);
-
- return ret;
-}
-
-static int lm3533_led_set(struct led_classdev *cdev,
- enum led_brightness value)
-{
- struct lm3533_led *led = to_lm3533_led(cdev);
-
- dev_dbg(led->cdev.dev, "%s - %d\n", __func__, value);
-
- if (value == 0)
- lm3533_led_pattern_enable(led, 0); /* disable blink */
-
- return lm3533_ctrlbank_set_brightness(&led->cb, value);
-}
-
-static enum led_brightness lm3533_led_get(struct led_classdev *cdev)
-{
- struct lm3533_led *led = to_lm3533_led(cdev);
- u8 val;
- int ret;
-
- ret = lm3533_ctrlbank_get_brightness(&led->cb, &val);
- if (ret)
- return ret;
-
- dev_dbg(led->cdev.dev, "%s - %u\n", __func__, val);
-
- return val;
-}
-
-/* Pattern generator defines (delays in us). */
-#define LM3533_LED_DELAY1_VMIN 0x00
-#define LM3533_LED_DELAY2_VMIN 0x3d
-#define LM3533_LED_DELAY3_VMIN 0x80
-
-#define LM3533_LED_DELAY1_VMAX (LM3533_LED_DELAY2_VMIN - 1)
-#define LM3533_LED_DELAY2_VMAX (LM3533_LED_DELAY3_VMIN - 1)
-#define LM3533_LED_DELAY3_VMAX 0xff
-
-#define LM3533_LED_DELAY1_TMIN 16384U
-#define LM3533_LED_DELAY2_TMIN 1130496U
-#define LM3533_LED_DELAY3_TMIN 10305536U
-
-#define LM3533_LED_DELAY1_TMAX 999424U
-#define LM3533_LED_DELAY2_TMAX 9781248U
-#define LM3533_LED_DELAY3_TMAX 76890112U
-
-/* t_step = (t_max - t_min) / (v_max - v_min) */
-#define LM3533_LED_DELAY1_TSTEP 16384
-#define LM3533_LED_DELAY2_TSTEP 131072
-#define LM3533_LED_DELAY3_TSTEP 524288
-
-/* Delay limits for hardware accelerated blinking (in ms). */
-#define LM3533_LED_DELAY_ON_MAX \
- ((LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY2_TSTEP / 2) / 1000)
-#define LM3533_LED_DELAY_OFF_MAX \
- ((LM3533_LED_DELAY3_TMAX + LM3533_LED_DELAY3_TSTEP / 2) / 1000)
-
-/*
- * Returns linear map of *t from [t_min,t_max] to [v_min,v_max] with a step
- * size of t_step, where
- *
- * t_step = (t_max - t_min) / (v_max - v_min)
- *
- * and updates *t to reflect the mapped value.
- */
-static u8 time_to_val(unsigned *t, unsigned t_min, unsigned t_step,
- u8 v_min, u8 v_max)
-{
- unsigned val;
-
- val = (*t + t_step / 2 - t_min) / t_step + v_min;
-
- *t = t_step * (val - v_min) + t_min;
-
- return (u8)val;
-}
-
-/*
- * Returns time code corresponding to *delay (in ms) and updates *delay to
- * reflect actual hardware delay.
- *
- * Hardware supports 256 discrete delay times, divided into three groups with
- * the following ranges and step-sizes:
- *
- * [ 16, 999] [0x00, 0x3e] step 16 ms
- * [ 1130, 9781] [0x3d, 0x7f] step 131 ms
- * [10306, 76890] [0x80, 0xff] step 524 ms
- *
- * Note that delay group 3 is only available for delay_off.
- */
-static u8 lm3533_led_get_hw_delay(unsigned *delay)
-{
- unsigned t;
- u8 val;
-
- t = *delay * 1000;
-
- if (t >= (LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY3_TMIN) / 2) {
- t = clamp(t, LM3533_LED_DELAY3_TMIN, LM3533_LED_DELAY3_TMAX);
- val = time_to_val(&t, LM3533_LED_DELAY3_TMIN,
- LM3533_LED_DELAY3_TSTEP,
- LM3533_LED_DELAY3_VMIN,
- LM3533_LED_DELAY3_VMAX);
- } else if (t >= (LM3533_LED_DELAY1_TMAX + LM3533_LED_DELAY2_TMIN) / 2) {
- t = clamp(t, LM3533_LED_DELAY2_TMIN, LM3533_LED_DELAY2_TMAX);
- val = time_to_val(&t, LM3533_LED_DELAY2_TMIN,
- LM3533_LED_DELAY2_TSTEP,
- LM3533_LED_DELAY2_VMIN,
- LM3533_LED_DELAY2_VMAX);
- } else {
- t = clamp(t, LM3533_LED_DELAY1_TMIN, LM3533_LED_DELAY1_TMAX);
- val = time_to_val(&t, LM3533_LED_DELAY1_TMIN,
- LM3533_LED_DELAY1_TSTEP,
- LM3533_LED_DELAY1_VMIN,
- LM3533_LED_DELAY1_VMAX);
- }
-
- *delay = (t + 500) / 1000;
-
- return val;
-}
-
-/*
- * Set delay register base to *delay (in ms) and update *delay to reflect
- * actual hardware delay used.
- */
-static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base,
- unsigned long *delay)
-{
- unsigned t;
- u8 val;
- u8 reg;
- int ret;
-
- t = (unsigned)*delay;
-
- /* Delay group 3 is only available for low time (delay off). */
- if (base != LM3533_REG_PATTERN_LOW_TIME_BASE)
- t = min(t, LM3533_LED_DELAY2_TMAX / 1000);
-
- val = lm3533_led_get_hw_delay(&t);
-
- dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__,
- *delay, t, val);
- reg = lm3533_led_get_pattern_reg(led, base);
- ret = lm3533_write(led->lm3533, reg, val);
- if (ret)
- dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg);
-
- *delay = t;
-
- return ret;
-}
-
-static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t)
-{
- return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t);
-}
-
-static int lm3533_led_delay_off_set(struct lm3533_led *led, unsigned long *t)
-{
- return lm3533_led_delay_set(led, LM3533_REG_PATTERN_LOW_TIME_BASE, t);
-}
-
-static int lm3533_led_blink_set(struct led_classdev *cdev,
- unsigned long *delay_on,
- unsigned long *delay_off)
-{
- struct lm3533_led *led = to_lm3533_led(cdev);
- int ret;
-
- dev_dbg(led->cdev.dev, "%s - on = %lu, off = %lu\n", __func__,
- *delay_on, *delay_off);
-
- if (*delay_on > LM3533_LED_DELAY_ON_MAX ||
- *delay_off > LM3533_LED_DELAY_OFF_MAX)
- return -EINVAL;
-
- if (*delay_on == 0 && *delay_off == 0) {
- *delay_on = 500;
- *delay_off = 500;
- }
-
- ret = lm3533_led_delay_on_set(led, delay_on);
- if (ret)
- return ret;
-
- ret = lm3533_led_delay_off_set(led, delay_off);
- if (ret)
- return ret;
-
- return lm3533_led_pattern_enable(led, 1);
-}
-
-static ssize_t show_id(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
-
- return sysfs_emit(buf, "%d\n", led->id);
-}
-
-/*
- * Pattern generator rise/fall times:
- *
- * 0 - 2048 us (default)
- * 1 - 262 ms
- * 2 - 524 ms
- * 3 - 1.049 s
- * 4 - 2.097 s
- * 5 - 4.194 s
- * 6 - 8.389 s
- * 7 - 16.78 s
- */
-static ssize_t show_risefalltime(struct device *dev,
- struct device_attribute *attr,
- char *buf, u8 base)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- ssize_t ret;
- u8 reg;
- u8 val;
-
- reg = lm3533_led_get_pattern_reg(led, base);
- ret = lm3533_read(led->lm3533, reg, &val);
- if (ret)
- return ret;
-
- return sysfs_emit(buf, "%x\n", val);
-}
-
-static ssize_t show_risetime(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return show_risefalltime(dev, attr, buf,
- LM3533_REG_PATTERN_RISETIME_BASE);
-}
-
-static ssize_t show_falltime(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return show_risefalltime(dev, attr, buf,
- LM3533_REG_PATTERN_FALLTIME_BASE);
-}
-
-static ssize_t store_risefalltime(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len, u8 base)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- u8 val;
- u8 reg;
- int ret;
-
- if (kstrtou8(buf, 0, &val) || val > LM3533_RISEFALLTIME_MAX)
- return -EINVAL;
-
- reg = lm3533_led_get_pattern_reg(led, base);
- ret = lm3533_write(led->lm3533, reg, val);
- if (ret)
- return ret;
-
- return len;
-}
-
-static ssize_t store_risetime(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- return store_risefalltime(dev, attr, buf, len,
- LM3533_REG_PATTERN_RISETIME_BASE);
-}
-
-static ssize_t store_falltime(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- return store_risefalltime(dev, attr, buf, len,
- LM3533_REG_PATTERN_FALLTIME_BASE);
-}
-
-static ssize_t show_als_channel(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- unsigned channel;
- u8 reg;
- u8 val;
- int ret;
-
- reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
- ret = lm3533_read(led->lm3533, reg, &val);
- if (ret)
- return ret;
-
- channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
-
- return sysfs_emit(buf, "%u\n", channel);
-}
-
-static ssize_t store_als_channel(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- unsigned channel;
- u8 reg;
- u8 val;
- u8 mask;
- int ret;
-
- if (kstrtouint(buf, 0, &channel))
- return -EINVAL;
-
- if (channel < LM3533_ALS_CHANNEL_LV_MIN ||
- channel > LM3533_ALS_CHANNEL_LV_MAX)
- return -EINVAL;
-
- reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
- mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK;
- val = channel - 1;
-
- ret = lm3533_update(led->lm3533, reg, val, mask);
- if (ret)
- return ret;
-
- return len;
-}
-
-static ssize_t show_als_en(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- bool enable;
- u8 reg;
- u8 val;
- int ret;
-
- reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
- ret = lm3533_read(led->lm3533, reg, &val);
- if (ret)
- return ret;
-
- enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
-
- return sysfs_emit(buf, "%d\n", enable);
-}
-
-static ssize_t store_als_en(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- unsigned enable;
- u8 reg;
- u8 mask;
- u8 val;
- int ret;
-
- if (kstrtouint(buf, 0, &enable))
- return -EINVAL;
-
- reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
- mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
-
- if (enable)
- val = mask;
- else
- val = 0;
-
- ret = lm3533_update(led->lm3533, reg, val, mask);
- if (ret)
- return ret;
-
- return len;
-}
-
-static ssize_t show_linear(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- u8 reg;
- u8 val;
- int linear;
- int ret;
-
- reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
- ret = lm3533_read(led->lm3533, reg, &val);
- if (ret)
- return ret;
-
- if (val & LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK)
- linear = 1;
- else
- linear = 0;
-
- return sysfs_emit(buf, "%x\n", linear);
-}
-
-static ssize_t store_linear(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- unsigned long linear;
- u8 reg;
- u8 mask;
- u8 val;
- int ret;
-
- if (kstrtoul(buf, 0, &linear))
- return -EINVAL;
-
- reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
- mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK;
-
- if (linear)
- val = mask;
- else
- val = 0;
-
- ret = lm3533_update(led->lm3533, reg, val, mask);
- if (ret)
- return ret;
-
- return len;
-}
-
-static ssize_t show_pwm(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- u8 val;
- int ret;
-
- ret = lm3533_ctrlbank_get_pwm(&led->cb, &val);
- if (ret)
- return ret;
-
- return sysfs_emit(buf, "%u\n", val);
-}
-
-static ssize_t store_pwm(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- u8 val;
- int ret;
-
- if (kstrtou8(buf, 0, &val))
- return -EINVAL;
-
- ret = lm3533_ctrlbank_set_pwm(&led->cb, val);
- if (ret)
- return ret;
-
- return len;
-}
-
-static LM3533_ATTR_RW(als_channel);
-static LM3533_ATTR_RW(als_en);
-static LM3533_ATTR_RW(falltime);
-static LM3533_ATTR_RO(id);
-static LM3533_ATTR_RW(linear);
-static LM3533_ATTR_RW(pwm);
-static LM3533_ATTR_RW(risetime);
-
-static struct attribute *lm3533_led_attributes[] = {
- &dev_attr_als_channel.attr,
- &dev_attr_als_en.attr,
- &dev_attr_falltime.attr,
- &dev_attr_id.attr,
- &dev_attr_linear.attr,
- &dev_attr_pwm.attr,
- &dev_attr_risetime.attr,
- NULL,
-};
-
-static umode_t lm3533_led_attr_is_visible(struct kobject *kobj,
- struct attribute *attr, int n)
-{
- struct device *dev = kobj_to_dev(kobj);
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3533_led *led = to_lm3533_led(led_cdev);
- umode_t mode = attr->mode;
-
- if (attr == &dev_attr_als_channel.attr ||
- attr == &dev_attr_als_en.attr) {
- if (!led->lm3533->have_als)
- mode = 0;
- }
-
- return mode;
-};
-
-static const struct attribute_group lm3533_led_attribute_group = {
- .is_visible = lm3533_led_attr_is_visible,
- .attrs = lm3533_led_attributes
-};
-
-static const struct attribute_group *lm3533_led_attribute_groups[] = {
- &lm3533_led_attribute_group,
- NULL
-};
-
-static int lm3533_led_setup(struct lm3533_led *led,
- struct lm3533_led_platform_data *pdata)
-{
- int ret;
-
- ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current);
- if (ret)
- return ret;
-
- return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
-}
-
-static int lm3533_led_probe(struct platform_device *pdev)
-{
- struct lm3533 *lm3533;
- struct lm3533_led_platform_data *pdata;
- struct lm3533_led *led;
- int ret;
-
- dev_dbg(&pdev->dev, "%s\n", __func__);
-
- lm3533 = dev_get_drvdata(pdev->dev.parent);
- if (!lm3533)
- return -EINVAL;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
- if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) {
- dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id);
- return -EINVAL;
- }
-
- led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
- if (!led)
- return -ENOMEM;
-
- led->lm3533 = lm3533;
- led->cdev.name = pdata->name;
- led->cdev.default_trigger = pdata->default_trigger;
- led->cdev.brightness_set_blocking = lm3533_led_set;
- led->cdev.brightness_get = lm3533_led_get;
- led->cdev.blink_set = lm3533_led_blink_set;
- led->cdev.brightness = LED_OFF;
- led->cdev.groups = lm3533_led_attribute_groups;
- led->id = pdev->id;
-
- mutex_init(&led->mutex);
-
- /* The class framework makes a callback to get brightness during
- * registration so use parent device (for error reporting) until
- * registered.
- */
- led->cb.lm3533 = lm3533;
- led->cb.id = lm3533_led_get_ctrlbank_id(led);
- led->cb.dev = lm3533->dev;
-
- platform_set_drvdata(pdev, led);
-
- ret = led_classdev_register(pdev->dev.parent, &led->cdev);
- if (ret) {
- dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id);
- return ret;
- }
-
- led->cb.dev = led->cdev.dev;
-
- ret = lm3533_led_setup(led, pdata);
- if (ret)
- goto err_deregister;
-
- ret = lm3533_ctrlbank_enable(&led->cb);
- if (ret)
- goto err_deregister;
-
- return 0;
-
-err_deregister:
- led_classdev_unregister(&led->cdev);
-
- return ret;
-}
-
-static void lm3533_led_remove(struct platform_device *pdev)
-{
- struct lm3533_led *led = platform_get_drvdata(pdev);
-
- dev_dbg(&pdev->dev, "%s\n", __func__);
-
- lm3533_ctrlbank_disable(&led->cb);
- led_classdev_unregister(&led->cdev);
-}
-
-static void lm3533_led_shutdown(struct platform_device *pdev)
-{
-
- struct lm3533_led *led = platform_get_drvdata(pdev);
-
- dev_dbg(&pdev->dev, "%s\n", __func__);
-
- lm3533_ctrlbank_disable(&led->cb);
- lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */
-}
-
-static struct platform_driver lm3533_led_driver = {
- .driver = {
- .name = "lm3533-leds",
- },
- .probe = lm3533_led_probe,
- .remove = lm3533_led_remove,
- .shutdown = lm3533_led_shutdown,
-};
-module_platform_driver(lm3533_led_driver);
-
-MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
-MODULE_DESCRIPTION("LM3533 LED driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lm3533-leds");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b0c7df448445..2cb2efafa8a4 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1917,19 +1917,6 @@ config MENELAUS
and other features that are often used in portable devices like
cell phones and PDAs.
-config MFD_LM3533
- tristate "TI/National Semiconductor LM3533 Lighting Power chip"
- depends on I2C
- select MFD_CORE
- select REGMAP_I2C
- help
- Say yes here to enable support for National Semiconductor / TI
- LM3533 Lighting Power chips.
-
- This driver provides common support for accessing the device;
- additional drivers must be enabled in order to use the LED,
- backlight or ambient-light-sensor functionality of the device.
-
config MFD_TIMBERDALE
tristate "Timberdale FPGA"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index cf3c70364538..8bd4c3e218bb 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -227,7 +227,6 @@ obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o
obj-$(CONFIG_MFD_SEC_ACPM) += sec-acpm.o
obj-$(CONFIG_MFD_SEC_I2C) += sec-i2c.o
obj-$(CONFIG_MFD_SYSCON) += syscon.o
-obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
obj-$(CONFIG_MFD_VEXPRESS_SYSREG) += vexpress-sysreg.o
obj-$(CONFIG_MFD_RETU) += retu-mfd.o
obj-$(CONFIG_MFD_AS3711) += as3711.o
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
deleted file mode 100644
index 0a2409d00b2e..000000000000
--- a/drivers/mfd/lm3533-core.c
+++ /dev/null
@@ -1,635 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * lm3533-core.c -- LM3533 Core
- *
- * Copyright (C) 2011-2012 Texas Instruments
- *
- * Author: Johan Hovold <jhovold@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/gpio/consumer.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/regmap.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <linux/mfd/lm3533.h>
-
-
-#define LM3533_BOOST_OVP_MASK 0x06
-#define LM3533_BOOST_OVP_SHIFT 1
-
-#define LM3533_BOOST_FREQ_MASK 0x01
-#define LM3533_BOOST_FREQ_SHIFT 0
-
-#define LM3533_BL_ID_MASK 1
-#define LM3533_LED_ID_MASK 3
-#define LM3533_BL_ID_MAX 1
-#define LM3533_LED_ID_MAX 3
-
-#define LM3533_HVLED_ID_MAX 2
-#define LM3533_LVLED_ID_MAX 5
-
-#define LM3533_REG_OUTPUT_CONF1 0x10
-#define LM3533_REG_OUTPUT_CONF2 0x11
-#define LM3533_REG_BOOST_PWM 0x2c
-
-#define LM3533_REG_MAX 0xb2
-
-
-static struct mfd_cell lm3533_als_devs[] = {
- {
- .name = "lm3533-als",
- .id = -1,
- },
-};
-
-static struct mfd_cell lm3533_bl_devs[] = {
- {
- .name = "lm3533-backlight",
- .id = 0,
- },
- {
- .name = "lm3533-backlight",
- .id = 1,
- },
-};
-
-static struct mfd_cell lm3533_led_devs[] = {
- {
- .name = "lm3533-leds",
- .id = 0,
- },
- {
- .name = "lm3533-leds",
- .id = 1,
- },
- {
- .name = "lm3533-leds",
- .id = 2,
- },
- {
- .name = "lm3533-leds",
- .id = 3,
- },
-};
-
-int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val)
-{
- int tmp;
- int ret;
-
- ret = regmap_read(lm3533->regmap, reg, &tmp);
- if (ret < 0) {
- dev_err(lm3533->dev, "failed to read register %02x: %d\n",
- reg, ret);
- return ret;
- }
-
- *val = tmp;
-
- dev_dbg(lm3533->dev, "read [%02x]: %02x\n", reg, *val);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_read);
-
-int lm3533_write(struct lm3533 *lm3533, u8 reg, u8 val)
-{
- int ret;
-
- dev_dbg(lm3533->dev, "write [%02x]: %02x\n", reg, val);
-
- ret = regmap_write(lm3533->regmap, reg, val);
- if (ret < 0) {
- dev_err(lm3533->dev, "failed to write register %02x: %d\n",
- reg, ret);
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_write);
-
-int lm3533_update(struct lm3533 *lm3533, u8 reg, u8 val, u8 mask)
-{
- int ret;
-
- dev_dbg(lm3533->dev, "update [%02x]: %02x/%02x\n", reg, val, mask);
-
- ret = regmap_update_bits(lm3533->regmap, reg, mask, val);
- if (ret < 0) {
- dev_err(lm3533->dev, "failed to update register %02x: %d\n",
- reg, ret);
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_update);
-
-static int lm3533_set_boost_freq(struct lm3533 *lm3533,
- enum lm3533_boost_freq freq)
-{
- int ret;
-
- ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM,
- freq << LM3533_BOOST_FREQ_SHIFT,
- LM3533_BOOST_FREQ_MASK);
- if (ret)
- dev_err(lm3533->dev, "failed to set boost frequency\n");
-
- return ret;
-}
-
-
-static int lm3533_set_boost_ovp(struct lm3533 *lm3533,
- enum lm3533_boost_ovp ovp)
-{
- int ret;
-
- ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM,
- ovp << LM3533_BOOST_OVP_SHIFT,
- LM3533_BOOST_OVP_MASK);
- if (ret)
- dev_err(lm3533->dev, "failed to set boost ovp\n");
-
- return ret;
-}
-
-/*
- * HVLED output config -- output hvled controlled by backlight bl
- */
-static int lm3533_set_hvled_config(struct lm3533 *lm3533, u8 hvled, u8 bl)
-{
- u8 val;
- u8 mask;
- int shift;
- int ret;
-
- if (hvled == 0 || hvled > LM3533_HVLED_ID_MAX)
- return -EINVAL;
-
- if (bl > LM3533_BL_ID_MAX)
- return -EINVAL;
-
- shift = hvled - 1;
- mask = LM3533_BL_ID_MASK << shift;
- val = bl << shift;
-
- ret = lm3533_update(lm3533, LM3533_REG_OUTPUT_CONF1, val, mask);
- if (ret)
- dev_err(lm3533->dev, "failed to set hvled config\n");
-
- return ret;
-}
-
-/*
- * LVLED output config -- output lvled controlled by LED led
- */
-static int lm3533_set_lvled_config(struct lm3533 *lm3533, u8 lvled, u8 led)
-{
- u8 reg;
- u8 val;
- u8 mask;
- int shift;
- int ret;
-
- if (lvled == 0 || lvled > LM3533_LVLED_ID_MAX)
- return -EINVAL;
-
- if (led > LM3533_LED_ID_MAX)
- return -EINVAL;
-
- if (lvled < 4) {
- reg = LM3533_REG_OUTPUT_CONF1;
- shift = 2 * lvled;
- } else {
- reg = LM3533_REG_OUTPUT_CONF2;
- shift = 2 * (lvled - 4);
- }
-
- mask = LM3533_LED_ID_MASK << shift;
- val = led << shift;
-
- ret = lm3533_update(lm3533, reg, val, mask);
- if (ret)
- dev_err(lm3533->dev, "failed to set lvled config\n");
-
- return ret;
-}
-
-static void lm3533_enable(struct lm3533 *lm3533)
-{
- gpiod_set_value(lm3533->hwen, 1);
-}
-
-static void lm3533_disable(struct lm3533 *lm3533)
-{
- gpiod_set_value(lm3533->hwen, 0);
-}
-
-enum lm3533_attribute_type {
- LM3533_ATTR_TYPE_BACKLIGHT,
- LM3533_ATTR_TYPE_LED,
-};
-
-struct lm3533_device_attribute {
- struct device_attribute dev_attr;
- enum lm3533_attribute_type type;
- union {
- struct {
- u8 id;
- } output;
- } u;
-};
-
-#define to_lm3533_dev_attr(_attr) \
- container_of(_attr, struct lm3533_device_attribute, dev_attr)
-
-static ssize_t show_output(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lm3533 *lm3533 = dev_get_drvdata(dev);
- struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr);
- int id = lattr->u.output.id;
- u8 reg;
- u8 val;
- u8 mask;
- int shift;
- int ret;
-
- if (lattr->type == LM3533_ATTR_TYPE_BACKLIGHT) {
- reg = LM3533_REG_OUTPUT_CONF1;
- shift = id - 1;
- mask = LM3533_BL_ID_MASK << shift;
- } else {
- if (id < 4) {
- reg = LM3533_REG_OUTPUT_CONF1;
- shift = 2 * id;
- } else {
- reg = LM3533_REG_OUTPUT_CONF2;
- shift = 2 * (id - 4);
- }
- mask = LM3533_LED_ID_MASK << shift;
- }
-
- ret = lm3533_read(lm3533, reg, &val);
- if (ret)
- return ret;
-
- val = (val & mask) >> shift;
-
- return sysfs_emit(buf, "%u\n", val);
-}
-
-static ssize_t store_output(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct lm3533 *lm3533 = dev_get_drvdata(dev);
- struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr);
- int id = lattr->u.output.id;
- u8 val;
- int ret;
-
- if (kstrtou8(buf, 0, &val))
- return -EINVAL;
-
- if (lattr->type == LM3533_ATTR_TYPE_BACKLIGHT)
- ret = lm3533_set_hvled_config(lm3533, id, val);
- else
- ret = lm3533_set_lvled_config(lm3533, id, val);
-
- if (ret)
- return ret;
-
- return len;
-}
-
-#define LM3533_OUTPUT_ATTR(_name, _mode, _show, _store, _type, _id) \
- struct lm3533_device_attribute lm3533_dev_attr_##_name = \
- { .dev_attr = __ATTR(_name, _mode, _show, _store), \
- .type = _type, \
- .u.output = { .id = _id }, }
-
-#define LM3533_OUTPUT_ATTR_RW(_name, _type, _id) \
- LM3533_OUTPUT_ATTR(output_##_name, S_IRUGO | S_IWUSR, \
- show_output, store_output, _type, _id)
-
-#define LM3533_OUTPUT_HVLED_ATTR_RW(_nr) \
- LM3533_OUTPUT_ATTR_RW(hvled##_nr, LM3533_ATTR_TYPE_BACKLIGHT, _nr)
-#define LM3533_OUTPUT_LVLED_ATTR_RW(_nr) \
- LM3533_OUTPUT_ATTR_RW(lvled##_nr, LM3533_ATTR_TYPE_LED, _nr)
-/*
- * Output config:
- *
- * output_hvled<nr> 0-1
- * output_lvled<nr> 0-3
- */
-static LM3533_OUTPUT_HVLED_ATTR_RW(1);
-static LM3533_OUTPUT_HVLED_ATTR_RW(2);
-static LM3533_OUTPUT_LVLED_ATTR_RW(1);
-static LM3533_OUTPUT_LVLED_ATTR_RW(2);
-static LM3533_OUTPUT_LVLED_ATTR_RW(3);
-static LM3533_OUTPUT_LVLED_ATTR_RW(4);
-static LM3533_OUTPUT_LVLED_ATTR_RW(5);
-
-static struct attribute *lm3533_attributes[] = {
- &lm3533_dev_attr_output_hvled1.dev_attr.attr,
- &lm3533_dev_attr_output_hvled2.dev_attr.attr,
- &lm3533_dev_attr_output_lvled1.dev_attr.attr,
- &lm3533_dev_attr_output_lvled2.dev_attr.attr,
- &lm3533_dev_attr_output_lvled3.dev_attr.attr,
- &lm3533_dev_attr_output_lvled4.dev_attr.attr,
- &lm3533_dev_attr_output_lvled5.dev_attr.attr,
- NULL,
-};
-
-#define to_dev_attr(_attr) \
- container_of(_attr, struct device_attribute, attr)
-
-static umode_t lm3533_attr_is_visible(struct kobject *kobj,
- struct attribute *attr, int n)
-{
- struct device *dev = kobj_to_dev(kobj);
- struct lm3533 *lm3533 = dev_get_drvdata(dev);
- struct device_attribute *dattr = to_dev_attr(attr);
- struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(dattr);
- enum lm3533_attribute_type type = lattr->type;
- umode_t mode = attr->mode;
-
- if (!lm3533->have_backlights && type == LM3533_ATTR_TYPE_BACKLIGHT)
- mode = 0;
- else if (!lm3533->have_leds && type == LM3533_ATTR_TYPE_LED)
- mode = 0;
-
- return mode;
-};
-
-static struct attribute_group lm3533_attribute_group = {
- .is_visible = lm3533_attr_is_visible,
- .attrs = lm3533_attributes
-};
-
-static int lm3533_device_als_init(struct lm3533 *lm3533)
-{
- struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
- int ret;
-
- if (!pdata->als)
- return 0;
-
- lm3533_als_devs[0].platform_data = pdata->als;
- lm3533_als_devs[0].pdata_size = sizeof(*pdata->als);
-
- ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL,
- 0, NULL);
- if (ret) {
- dev_err(lm3533->dev, "failed to add ALS device\n");
- return ret;
- }
-
- lm3533->have_als = 1;
-
- return 0;
-}
-
-static int lm3533_device_bl_init(struct lm3533 *lm3533)
-{
- struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
- int i;
- int ret;
-
- if (!pdata->backlights || pdata->num_backlights == 0)
- return 0;
-
- if (pdata->num_backlights > ARRAY_SIZE(lm3533_bl_devs))
- pdata->num_backlights = ARRAY_SIZE(lm3533_bl_devs);
-
- for (i = 0; i < pdata->num_backlights; ++i) {
- lm3533_bl_devs[i].platform_data = &pdata->backlights[i];
- lm3533_bl_devs[i].pdata_size = sizeof(pdata->backlights[i]);
- }
-
- ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs,
- pdata->num_backlights, NULL, 0, NULL);
- if (ret) {
- dev_err(lm3533->dev, "failed to add backlight devices\n");
- return ret;
- }
-
- lm3533->have_backlights = 1;
-
- return 0;
-}
-
-static int lm3533_device_led_init(struct lm3533 *lm3533)
-{
- struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
- int i;
- int ret;
-
- if (!pdata->leds || pdata->num_leds == 0)
- return 0;
-
- if (pdata->num_leds > ARRAY_SIZE(lm3533_led_devs))
- pdata->num_leds = ARRAY_SIZE(lm3533_led_devs);
-
- for (i = 0; i < pdata->num_leds; ++i) {
- lm3533_led_devs[i].platform_data = &pdata->leds[i];
- lm3533_led_devs[i].pdata_size = sizeof(pdata->leds[i]);
- }
-
- ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs,
- pdata->num_leds, NULL, 0, NULL);
- if (ret) {
- dev_err(lm3533->dev, "failed to add LED devices\n");
- return ret;
- }
-
- lm3533->have_leds = 1;
-
- return 0;
-}
-
-static int lm3533_device_setup(struct lm3533 *lm3533,
- struct lm3533_platform_data *pdata)
-{
- int ret;
-
- ret = lm3533_set_boost_freq(lm3533, pdata->boost_freq);
- if (ret)
- return ret;
-
- return lm3533_set_boost_ovp(lm3533, pdata->boost_ovp);
-}
-
-static int lm3533_device_init(struct lm3533 *lm3533)
-{
- struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
- int ret;
-
- dev_dbg(lm3533->dev, "%s\n", __func__);
-
- if (!pdata) {
- dev_err(lm3533->dev, "no platform data\n");
- return -EINVAL;
- }
-
- lm3533->hwen = devm_gpiod_get(lm3533->dev, NULL, GPIOD_OUT_LOW);
- if (IS_ERR(lm3533->hwen))
- return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen), "failed to request HWEN GPIO\n");
- gpiod_set_consumer_name(lm3533->hwen, "lm3533-hwen");
-
- lm3533_enable(lm3533);
-
- ret = lm3533_device_setup(lm3533, pdata);
- if (ret)
- goto err_disable;
-
- lm3533_device_als_init(lm3533);
- lm3533_device_bl_init(lm3533);
- lm3533_device_led_init(lm3533);
-
- ret = sysfs_create_group(&lm3533->dev->kobj, &lm3533_attribute_group);
- if (ret < 0) {
- dev_err(lm3533->dev, "failed to create sysfs attributes\n");
- goto err_unregister;
- }
-
- return 0;
-
-err_unregister:
- mfd_remove_devices(lm3533->dev);
-err_disable:
- lm3533_disable(lm3533);
-
- return ret;
-}
-
-static void lm3533_device_exit(struct lm3533 *lm3533)
-{
- dev_dbg(lm3533->dev, "%s\n", __func__);
-
- sysfs_remove_group(&lm3533->dev->kobj, &lm3533_attribute_group);
-
- mfd_remove_devices(lm3533->dev);
- lm3533_disable(lm3533);
-}
-
-static bool lm3533_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case 0x10 ... 0x2c:
- case 0x30 ... 0x38:
- case 0x40 ... 0x45:
- case 0x50 ... 0x57:
- case 0x60 ... 0x6e:
- case 0x70 ... 0x75:
- case 0x80 ... 0x85:
- case 0x90 ... 0x95:
- case 0xa0 ... 0xa5:
- case 0xb0 ... 0xb2:
- return true;
- default:
- return false;
- }
-}
-
-static bool lm3533_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case 0x34 ... 0x36: /* zone */
- case 0x37 ... 0x38: /* adc */
- case 0xb0 ... 0xb1: /* fault */
- return true;
- default:
- return false;
- }
-}
-
-static bool lm3533_precious_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case 0x34: /* zone */
- return true;
- default:
- return false;
- }
-}
-
-static const struct regmap_config regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = LM3533_REG_MAX,
- .readable_reg = lm3533_readable_register,
- .volatile_reg = lm3533_volatile_register,
- .precious_reg = lm3533_precious_register,
-};
-
-static int lm3533_i2c_probe(struct i2c_client *i2c)
-{
- struct lm3533 *lm3533;
-
- dev_dbg(&i2c->dev, "%s\n", __func__);
-
- lm3533 = devm_kzalloc(&i2c->dev, sizeof(*lm3533), GFP_KERNEL);
- if (!lm3533)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, lm3533);
-
- lm3533->regmap = devm_regmap_init_i2c(i2c, ®map_config);
- if (IS_ERR(lm3533->regmap))
- return PTR_ERR(lm3533->regmap);
-
- lm3533->dev = &i2c->dev;
- lm3533->irq = i2c->irq;
-
- return lm3533_device_init(lm3533);
-}
-
-static void lm3533_i2c_remove(struct i2c_client *i2c)
-{
- struct lm3533 *lm3533 = i2c_get_clientdata(i2c);
-
- dev_dbg(&i2c->dev, "%s\n", __func__);
-
- lm3533_device_exit(lm3533);
-}
-
-static const struct i2c_device_id lm3533_i2c_ids[] = {
- { "lm3533" },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, lm3533_i2c_ids);
-
-static struct i2c_driver lm3533_i2c_driver = {
- .driver = {
- .name = "lm3533",
- },
- .id_table = lm3533_i2c_ids,
- .probe = lm3533_i2c_probe,
- .remove = lm3533_i2c_remove,
-};
-
-static int __init lm3533_i2c_init(void)
-{
- return i2c_add_driver(&lm3533_i2c_driver);
-}
-subsys_initcall(lm3533_i2c_init);
-
-static void __exit lm3533_i2c_exit(void)
-{
- i2c_del_driver(&lm3533_i2c_driver);
-}
-module_exit(lm3533_i2c_exit);
-
-MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
-MODULE_DESCRIPTION("LM3533 Core");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/lm3533-ctrlbank.c b/drivers/mfd/lm3533-ctrlbank.c
deleted file mode 100644
index 2537dfade51c..000000000000
--- a/drivers/mfd/lm3533-ctrlbank.c
+++ /dev/null
@@ -1,162 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * lm3533-ctrlbank.c -- LM3533 Generic Control Bank interface
- *
- * Copyright (C) 2011-2012 Texas Instruments
- *
- * Author: Johan Hovold <jhovold@gmail.com>
- */
-
-#include <linux/device.h>
-#include <linux/module.h>
-
-#include <linux/mfd/lm3533.h>
-
-
-#define LM3533_MAX_CURRENT_MIN 5000
-#define LM3533_MAX_CURRENT_MAX 29800
-#define LM3533_MAX_CURRENT_STEP 800
-
-#define LM3533_PWM_MAX 0x3f
-
-#define LM3533_REG_PWM_BASE 0x14
-#define LM3533_REG_MAX_CURRENT_BASE 0x1f
-#define LM3533_REG_CTRLBANK_ENABLE 0x27
-#define LM3533_REG_BRIGHTNESS_BASE 0x40
-
-
-static inline u8 lm3533_ctrlbank_get_reg(struct lm3533_ctrlbank *cb, u8 base)
-{
- return base + cb->id;
-}
-
-int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb)
-{
- u8 mask;
- int ret;
-
- dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
-
- mask = 1 << cb->id;
- ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE,
- mask, mask);
- if (ret)
- dev_err(cb->dev, "failed to enable ctrlbank %d\n", cb->id);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_enable);
-
-int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb)
-{
- u8 mask;
- int ret;
-
- dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
-
- mask = 1 << cb->id;
- ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, 0, mask);
- if (ret)
- dev_err(cb->dev, "failed to disable ctrlbank %d\n", cb->id);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable);
-
-/*
- * Full-scale current.
- *
- * imax 5000 - 29800 uA (800 uA step)
- */
-int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
-{
- u8 reg;
- u8 val;
- int ret;
-
- if (imax < LM3533_MAX_CURRENT_MIN || imax > LM3533_MAX_CURRENT_MAX)
- return -EINVAL;
-
- val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP;
-
- reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE);
- ret = lm3533_write(cb->lm3533, reg, val);
- if (ret)
- dev_err(cb->dev, "failed to set max current\n");
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current);
-
-int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val)
-{
- u8 reg;
- int ret;
-
- reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
- ret = lm3533_write(cb->lm3533, reg, val);
- if (ret)
- dev_err(cb->dev, "failed to set brightness\n");
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_brightness);
-
-int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val)
-{
- u8 reg;
- int ret;
-
- reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
- ret = lm3533_read(cb->lm3533, reg, val);
- if (ret)
- dev_err(cb->dev, "failed to get brightness\n");
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_brightness);
-
-/*
- * PWM-input control mask:
- *
- * bit 5 - PWM-input enabled in Zone 4
- * bit 4 - PWM-input enabled in Zone 3
- * bit 3 - PWM-input enabled in Zone 2
- * bit 2 - PWM-input enabled in Zone 1
- * bit 1 - PWM-input enabled in Zone 0
- * bit 0 - PWM-input enabled
- */
-int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val)
-{
- u8 reg;
- int ret;
-
- if (val > LM3533_PWM_MAX)
- return -EINVAL;
-
- reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
- ret = lm3533_write(cb->lm3533, reg, val);
- if (ret)
- dev_err(cb->dev, "failed to set PWM mask\n");
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_pwm);
-
-int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val)
-{
- u8 reg;
- int ret;
-
- reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
- ret = lm3533_read(cb->lm3533, reg, val);
- if (ret)
- dev_err(cb->dev, "failed to get PWM mask\n");
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_pwm);
-
-MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
-MODULE_DESCRIPTION("LM3533 Control Bank interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 4acbac1bbb9e..bd88c88d7cf2 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -215,17 +215,6 @@ config BACKLIGHT_SY7758
Say Y to enable the backlight driver for the Silergy SY7758
backlight controller found in Ayaneo Pocket S2.
-config BACKLIGHT_LM3533
- tristate "Backlight Driver for LM3533"
- depends on MFD_LM3533
- help
- Say Y to enable the backlight driver for National Semiconductor / TI
- LM3533 Lighting Power chips.
-
- The backlights can be controlled directly, through PWM input, or by
- the ambient-light-sensor interface. The chip supports 256 brightness
- levels.
-
config BACKLIGHT_LOCOMO
tristate "Sharp LOCOMO LCD/Backlight Driver"
depends on SHARP_LOCOMO
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index e11175bdd500..d98e60664af6 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -37,7 +37,6 @@ obj-$(CONFIG_BACKLIGHT_KTD253) += ktd253-backlight.o
obj-$(CONFIG_BACKLIGHT_KTD2801) += ktd2801-backlight.o
obj-$(CONFIG_BACKLIGHT_KTZ8866) += ktz8866.o
obj-$(CONFIG_BACKLIGHT_LM3509) += lm3509_bl.o
-obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o
obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
deleted file mode 100644
index babfd3ceec86..000000000000
--- a/drivers/video/backlight/lm3533_bl.c
+++ /dev/null
@@ -1,398 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * lm3533-bl.c -- LM3533 Backlight driver
- *
- * Copyright (C) 2011-2012 Texas Instruments
- *
- * Author: Johan Hovold <jhovold@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/backlight.h>
-#include <linux/slab.h>
-
-#include <linux/mfd/lm3533.h>
-
-
-#define LM3533_HVCTRLBANK_COUNT 2
-#define LM3533_BL_MAX_BRIGHTNESS 255
-
-#define LM3533_REG_CTRLBANK_AB_BCONF 0x1a
-
-
-struct lm3533_bl {
- struct lm3533 *lm3533;
- struct lm3533_ctrlbank cb;
- struct backlight_device *bd;
- int id;
-};
-
-
-static inline int lm3533_bl_get_ctrlbank_id(struct lm3533_bl *bl)
-{
- return bl->id;
-}
-
-static int lm3533_bl_update_status(struct backlight_device *bd)
-{
- struct lm3533_bl *bl = bl_get_data(bd);
-
- return lm3533_ctrlbank_set_brightness(&bl->cb, backlight_get_brightness(bd));
-}
-
-static int lm3533_bl_get_brightness(struct backlight_device *bd)
-{
- struct lm3533_bl *bl = bl_get_data(bd);
- u8 val;
- int ret;
-
- ret = lm3533_ctrlbank_get_brightness(&bl->cb, &val);
- if (ret)
- return ret;
-
- return val;
-}
-
-static const struct backlight_ops lm3533_bl_ops = {
- .get_brightness = lm3533_bl_get_brightness,
- .update_status = lm3533_bl_update_status,
-};
-
-static ssize_t show_id(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
-
- return scnprintf(buf, PAGE_SIZE, "%d\n", bl->id);
-}
-
-static ssize_t show_als_channel(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- unsigned channel = lm3533_bl_get_ctrlbank_id(bl);
-
- return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
-}
-
-static ssize_t show_als_en(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
- u8 val;
- u8 mask;
- bool enable;
- int ret;
-
- ret = lm3533_read(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, &val);
- if (ret)
- return ret;
-
- mask = 1 << (2 * ctrlbank);
- enable = val & mask;
-
- return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
-}
-
-static ssize_t store_als_en(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
- int enable;
- u8 val;
- u8 mask;
- int ret;
-
- if (kstrtoint(buf, 0, &enable))
- return -EINVAL;
-
- mask = 1 << (2 * ctrlbank);
-
- if (enable)
- val = mask;
- else
- val = 0;
-
- ret = lm3533_update(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, val,
- mask);
- if (ret)
- return ret;
-
- return len;
-}
-
-static ssize_t show_linear(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- u8 val;
- u8 mask;
- int linear;
- int ret;
-
- ret = lm3533_read(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, &val);
- if (ret)
- return ret;
-
- mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1);
-
- if (val & mask)
- linear = 1;
- else
- linear = 0;
-
- return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
-}
-
-static ssize_t store_linear(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- unsigned long linear;
- u8 mask;
- u8 val;
- int ret;
-
- if (kstrtoul(buf, 0, &linear))
- return -EINVAL;
-
- mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1);
-
- if (linear)
- val = mask;
- else
- val = 0;
-
- ret = lm3533_update(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, val,
- mask);
- if (ret)
- return ret;
-
- return len;
-}
-
-static ssize_t show_pwm(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- u8 val;
- int ret;
-
- ret = lm3533_ctrlbank_get_pwm(&bl->cb, &val);
- if (ret)
- return ret;
-
- return scnprintf(buf, PAGE_SIZE, "%u\n", val);
-}
-
-static ssize_t store_pwm(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- u8 val;
- int ret;
-
- if (kstrtou8(buf, 0, &val))
- return -EINVAL;
-
- ret = lm3533_ctrlbank_set_pwm(&bl->cb, val);
- if (ret)
- return ret;
-
- return len;
-}
-
-static LM3533_ATTR_RO(als_channel);
-static LM3533_ATTR_RW(als_en);
-static LM3533_ATTR_RO(id);
-static LM3533_ATTR_RW(linear);
-static LM3533_ATTR_RW(pwm);
-
-static struct attribute *lm3533_bl_attributes[] = {
- &dev_attr_als_channel.attr,
- &dev_attr_als_en.attr,
- &dev_attr_id.attr,
- &dev_attr_linear.attr,
- &dev_attr_pwm.attr,
- NULL,
-};
-
-static umode_t lm3533_bl_attr_is_visible(struct kobject *kobj,
- struct attribute *attr, int n)
-{
- struct device *dev = kobj_to_dev(kobj);
- struct lm3533_bl *bl = dev_get_drvdata(dev);
- umode_t mode = attr->mode;
-
- if (attr == &dev_attr_als_channel.attr ||
- attr == &dev_attr_als_en.attr) {
- if (!bl->lm3533->have_als)
- mode = 0;
- }
-
- return mode;
-};
-
-static struct attribute_group lm3533_bl_attribute_group = {
- .is_visible = lm3533_bl_attr_is_visible,
- .attrs = lm3533_bl_attributes
-};
-
-static int lm3533_bl_setup(struct lm3533_bl *bl,
- struct lm3533_bl_platform_data *pdata)
-{
- int ret;
-
- ret = lm3533_ctrlbank_set_max_current(&bl->cb, pdata->max_current);
- if (ret)
- return ret;
-
- return lm3533_ctrlbank_set_pwm(&bl->cb, pdata->pwm);
-}
-
-static int lm3533_bl_probe(struct platform_device *pdev)
-{
- struct lm3533 *lm3533;
- struct lm3533_bl_platform_data *pdata;
- struct lm3533_bl *bl;
- struct backlight_device *bd;
- struct backlight_properties props;
- int ret;
-
- dev_dbg(&pdev->dev, "%s\n", __func__);
-
- lm3533 = dev_get_drvdata(pdev->dev.parent);
- if (!lm3533)
- return -EINVAL;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
- if (pdev->id < 0 || pdev->id >= LM3533_HVCTRLBANK_COUNT) {
- dev_err(&pdev->dev, "illegal backlight id %d\n", pdev->id);
- return -EINVAL;
- }
-
- bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL);
- if (!bl)
- return -ENOMEM;
-
- bl->lm3533 = lm3533;
- bl->id = pdev->id;
-
- bl->cb.lm3533 = lm3533;
- bl->cb.id = lm3533_bl_get_ctrlbank_id(bl);
- bl->cb.dev = NULL; /* until registered */
-
- memset(&props, 0, sizeof(props));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = LM3533_BL_MAX_BRIGHTNESS;
- props.brightness = pdata->default_brightness;
- bd = devm_backlight_device_register(&pdev->dev, pdata->name,
- pdev->dev.parent, bl, &lm3533_bl_ops,
- &props);
- if (IS_ERR(bd)) {
- dev_err(&pdev->dev, "failed to register backlight device\n");
- return PTR_ERR(bd);
- }
-
- bl->bd = bd;
- bl->cb.dev = &bl->bd->dev;
-
- platform_set_drvdata(pdev, bl);
-
- ret = sysfs_create_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to create sysfs attributes\n");
- return ret;
- }
-
- backlight_update_status(bd);
-
- ret = lm3533_bl_setup(bl, pdata);
- if (ret)
- goto err_sysfs_remove;
-
- ret = lm3533_ctrlbank_enable(&bl->cb);
- if (ret)
- goto err_sysfs_remove;
-
- return 0;
-
-err_sysfs_remove:
- sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
-
- return ret;
-}
-
-static void lm3533_bl_remove(struct platform_device *pdev)
-{
- struct lm3533_bl *bl = platform_get_drvdata(pdev);
- struct backlight_device *bd = bl->bd;
-
- dev_dbg(&bd->dev, "%s\n", __func__);
-
- bd->props.power = BACKLIGHT_POWER_OFF;
- bd->props.brightness = 0;
-
- lm3533_ctrlbank_disable(&bl->cb);
- sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int lm3533_bl_suspend(struct device *dev)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
-
- dev_dbg(dev, "%s\n", __func__);
-
- return lm3533_ctrlbank_disable(&bl->cb);
-}
-
-static int lm3533_bl_resume(struct device *dev)
-{
- struct lm3533_bl *bl = dev_get_drvdata(dev);
-
- dev_dbg(dev, "%s\n", __func__);
-
- return lm3533_ctrlbank_enable(&bl->cb);
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(lm3533_bl_pm_ops, lm3533_bl_suspend, lm3533_bl_resume);
-
-static void lm3533_bl_shutdown(struct platform_device *pdev)
-{
- struct lm3533_bl *bl = platform_get_drvdata(pdev);
-
- dev_dbg(&pdev->dev, "%s\n", __func__);
-
- lm3533_ctrlbank_disable(&bl->cb);
-}
-
-static struct platform_driver lm3533_bl_driver = {
- .driver = {
- .name = "lm3533-backlight",
- .pm = &lm3533_bl_pm_ops,
- },
- .probe = lm3533_bl_probe,
- .remove = lm3533_bl_remove,
- .shutdown = lm3533_bl_shutdown,
-};
-module_platform_driver(lm3533_bl_driver);
-
-MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
-MODULE_DESCRIPTION("LM3533 Backlight driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lm3533-backlight");
diff --git a/include/linux/mfd/lm3533.h b/include/linux/mfd/lm3533.h
deleted file mode 100644
index 69059a7a2ce5..000000000000
--- a/include/linux/mfd/lm3533.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * lm3533.h -- LM3533 interface
- *
- * Copyright (C) 2011-2012 Texas Instruments
- *
- * Author: Johan Hovold <jhovold@gmail.com>
- */
-
-#ifndef __LINUX_MFD_LM3533_H
-#define __LINUX_MFD_LM3533_H
-
-#define LM3533_ATTR_RO(_name) \
- DEVICE_ATTR(_name, S_IRUGO, show_##_name, NULL)
-#define LM3533_ATTR_RW(_name) \
- DEVICE_ATTR(_name, S_IRUGO | S_IWUSR , show_##_name, store_##_name)
-
-struct device;
-struct gpio_desc;
-struct regmap;
-
-struct lm3533 {
- struct device *dev;
-
- struct regmap *regmap;
-
- struct gpio_desc *hwen;
- int irq;
-
- unsigned have_als:1;
- unsigned have_backlights:1;
- unsigned have_leds:1;
-};
-
-struct lm3533_ctrlbank {
- struct lm3533 *lm3533;
- struct device *dev;
- int id;
-};
-
-struct lm3533_als_platform_data {
- unsigned pwm_mode:1; /* PWM input mode (default analog) */
- u8 r_select; /* 1 - 127 (ignored in PWM-mode) */
-};
-
-struct lm3533_bl_platform_data {
- char *name;
- u16 max_current; /* 5000 - 29800 uA (800 uA step) */
- u8 default_brightness; /* 0 - 255 */
- u8 pwm; /* 0 - 0x3f */
-};
-
-struct lm3533_led_platform_data {
- char *name;
- const char *default_trigger;
- u16 max_current; /* 5000 - 29800 uA (800 uA step) */
- u8 pwm; /* 0 - 0x3f */
-};
-
-enum lm3533_boost_freq {
- LM3533_BOOST_FREQ_500KHZ,
- LM3533_BOOST_FREQ_1000KHZ,
-};
-
-enum lm3533_boost_ovp {
- LM3533_BOOST_OVP_16V,
- LM3533_BOOST_OVP_24V,
- LM3533_BOOST_OVP_32V,
- LM3533_BOOST_OVP_40V,
-};
-
-struct lm3533_platform_data {
- enum lm3533_boost_ovp boost_ovp;
- enum lm3533_boost_freq boost_freq;
-
- struct lm3533_als_platform_data *als;
-
- struct lm3533_bl_platform_data *backlights;
- int num_backlights;
-
- struct lm3533_led_platform_data *leds;
- int num_leds;
-};
-
-extern int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb);
-extern int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb);
-
-extern int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val);
-extern int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val);
-extern int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb,
- u16 imax);
-extern int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val);
-extern int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val);
-
-extern int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val);
-extern int lm3533_write(struct lm3533 *lm3533, u8 reg, u8 val);
-extern int lm3533_update(struct lm3533 *lm3533, u8 reg, u8 val, u8 mask);
-
-#endif /* __LINUX_MFD_LM3533_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* Re: [PATCH 09/14] mfd: remove unused lm3533 driver
2026-09-09 13:21 ` [PATCH 09/14] mfd: remove unused lm3533 driver Arnd Bergmann
@ 2026-09-09 13:44 ` Johan Hovold
2026-09-09 14:47 ` Arnd Bergmann
0 siblings, 1 reply; 36+ messages in thread
From: Johan Hovold @ 2026-09-09 13:44 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Sebastian Reichel,
Alexandre Belloni, Helge Deller, dri-devel, linux-doc,
linux-media, devicetree, linux-hwmon, patches, linux-watchdog,
linux-gpio, linux-iio, linux-input, linux-leds, linux-pm,
linux-rtc, linux-fbdev, linux-sound, linuxppc-dev, llvm
On Wed, Sep 09, 2026 at 03:21:46PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver has apparently never had any users, as it does not support
> devicetree probing, and no lm3533_platform_data definition ever
> existed upstream.
I don't believe we ever required board files to be upstreamed?
There's also on-going work to enable devicetree support for this one:
https://lore.kernel.org/lkml/20260617080031.99156-1-clamor95@gmail.com/
Johan
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 09/14] mfd: remove unused lm3533 driver
2026-09-09 13:44 ` Johan Hovold
@ 2026-09-09 14:47 ` Arnd Bergmann
0 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 14:47 UTC (permalink / raw)
To: Johan Hovold, Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, open list:GPIO SUBSYSTEM,
linux-iio, linux-input, linux-leds, linux-pm, linux-rtc,
linux-fbdev, linux-sound, linuxppc-dev, llvm
On Wed, Sep 9, 2026, at 15:44, Johan Hovold wrote:
> On Wed, Sep 09, 2026 at 03:21:46PM +0200, Arnd Bergmann wrote:
>> From: Arnd Bergmann <arnd@arndb.de>
>>
>> This driver has apparently never had any users, as it does not support
>> devicetree probing, and no lm3533_platform_data definition ever
>> existed upstream.
>
> I don't believe we ever required board files to be upstreamed?
No, but there is a general requirement that code must be usable.
With my series to drop almost all Arm board files, the use
of platform_data becomes so obscure that it becomes reasonable
to assume that any driver that requires platform_data and does
not already have an upstream definition for it is fundamentally
broken.
The only platforms that still use board files now are:
arm/omap1
arm/s3c
m68k/coldfire
mips/alchemy
mips/bcm63xx
mips/rb532
mips/txx9
sh/sh77xx
All of these are now over 20 years old, so I don't expect anyone
to add new board support or maintain boards for them except for
what is already upstream.
> There's also on-going work to enable devicetree support for this one:
>
> https://lore.kernel.org/lkml/20260617080031.99156-1-clamor95@gmail.com/
Ok, I've dropped this patch, thanks for pointing this one out!
Arnd
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 10/14] mfd: remove unused rc5t583 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (6 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 09/14] mfd: remove unused lm3533 driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:48 ` Alexandre Belloni
2026-09-09 13:21 ` [PATCH 12/14] mfd: remove unused mcp-sa11x0/ucb1x00 driver Arnd Bergmann
` (6 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
Ricoh RC5T583 support was added in 2012, but no upstream code ever
defined the corresponding platform_data, and there is no devicetree
support, so this is all dead code.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/mfd/Kconfig | 14 -
drivers/mfd/Makefile | 1 -
drivers/mfd/rc5t583-irq.c | 383 --------------------------
drivers/mfd/rc5t583.c | 299 --------------------
drivers/regulator/Kconfig | 10 -
drivers/regulator/Makefile | 1 -
drivers/regulator/rc5t583-regulator.c | 171 ------------
drivers/rtc/Kconfig | 10 -
drivers/rtc/Makefile | 1 -
drivers/rtc/rtc-rc5t583.c | 312 ---------------------
include/linux/mfd/rc5t583.h | 369 -------------------------
11 files changed, 1571 deletions(-)
delete mode 100644 drivers/mfd/rc5t583-irq.c
delete mode 100644 drivers/mfd/rc5t583.c
delete mode 100644 drivers/regulator/rc5t583-regulator.c
delete mode 100644 drivers/rtc/rtc-rc5t583.c
delete mode 100644 include/linux/mfd/rc5t583.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2cb2efafa8a4..fbcc45d2b0c4 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1291,20 +1291,6 @@ config MFD_RT5120
is targeted at providing the CPU voltage, memory, I/O and peripheral
power rails in home entertainment devices.
-config MFD_RC5T583
- bool "Ricoh RC5T583 Power Management system device"
- depends on I2C=y
- select MFD_CORE
- select REGMAP_I2C
- help
- Select this option to get support for the RICOH583 Power
- Management system device.
- This driver provides common support for accessing the device
- through i2c interface. The device supports multiple sub-devices
- like GPIO, interrupts, RTC, LDO and DCDC regulators, onkey.
- Additional drivers must be enabled in order to use the
- different functionality of the device.
-
config MFD_RK8XX
tristate
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8bd4c3e218bb..7aaad5855681 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -217,7 +217,6 @@ obj-$(CONFIG_MFD_INTEL_PMC_BXT) += intel_pmc_bxt.o
obj-$(CONFIG_MFD_PALMAS) += palmas.o
obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o
obj-$(CONFIG_MFD_NTXEC) += ntxec.o
-obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
obj-$(CONFIG_MFD_RK8XX) += rk8xx-core.o
obj-$(CONFIG_MFD_RK8XX_I2C) += rk8xx-i2c.o
obj-$(CONFIG_MFD_RK8XX_SPI) += rk8xx-spi.o
diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c
deleted file mode 100644
index 97f52b671520..000000000000
--- a/drivers/mfd/rc5t583-irq.c
+++ /dev/null
@@ -1,383 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Interrupt driver for RICOH583 power management chip.
- *
- * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
- * Author: Laxman dewangan <ldewangan@nvidia.com>
- *
- * based on code
- * Copyright (C) 2011 RICOH COMPANY,LTD
- */
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mfd/rc5t583.h>
-
-enum int_type {
- SYS_INT = 0x1,
- DCDC_INT = 0x2,
- RTC_INT = 0x4,
- ADC_INT = 0x8,
- GPIO_INT = 0x10,
-};
-
-static int gpedge_add[] = {
- RC5T583_GPIO_GPEDGE2,
- RC5T583_GPIO_GPEDGE2
-};
-
-static int irq_en_add[] = {
- RC5T583_INT_EN_SYS1,
- RC5T583_INT_EN_SYS2,
- RC5T583_INT_EN_DCDC,
- RC5T583_INT_EN_RTC,
- RC5T583_INT_EN_ADC1,
- RC5T583_INT_EN_ADC2,
- RC5T583_INT_EN_ADC3,
- RC5T583_GPIO_EN_INT
-};
-
-static int irq_mon_add[] = {
- RC5T583_INT_MON_SYS1,
- RC5T583_INT_MON_SYS2,
- RC5T583_INT_MON_DCDC,
- RC5T583_INT_MON_RTC,
- RC5T583_INT_IR_ADCL,
- RC5T583_INT_IR_ADCH,
- RC5T583_INT_IR_ADCEND,
- RC5T583_INT_IR_GPIOF,
- RC5T583_INT_IR_GPIOR
-};
-
-static int irq_clr_add[] = {
- RC5T583_INT_IR_SYS1,
- RC5T583_INT_IR_SYS2,
- RC5T583_INT_IR_DCDC,
- RC5T583_INT_IR_RTC,
- RC5T583_INT_IR_ADCL,
- RC5T583_INT_IR_ADCH,
- RC5T583_INT_IR_ADCEND,
- RC5T583_INT_IR_GPIOF,
- RC5T583_INT_IR_GPIOR
-};
-
-static int main_int_type[] = {
- SYS_INT,
- SYS_INT,
- DCDC_INT,
- RTC_INT,
- ADC_INT,
- ADC_INT,
- ADC_INT,
- GPIO_INT,
- GPIO_INT,
-};
-
-struct rc5t583_irq_data {
- u8 int_type;
- u8 master_bit;
- u8 int_en_bit;
- u8 mask_reg_index;
- int grp_index;
-};
-
-#define RC5T583_IRQ(_int_type, _master_bit, _grp_index, \
- _int_bit, _mask_ind) \
- { \
- .int_type = _int_type, \
- .master_bit = _master_bit, \
- .grp_index = _grp_index, \
- .int_en_bit = _int_bit, \
- .mask_reg_index = _mask_ind, \
- }
-
-static const struct rc5t583_irq_data rc5t583_irqs[RC5T583_MAX_IRQS] = {
- [RC5T583_IRQ_ONKEY] = RC5T583_IRQ(SYS_INT, 0, 0, 0, 0),
- [RC5T583_IRQ_ACOK] = RC5T583_IRQ(SYS_INT, 0, 1, 1, 0),
- [RC5T583_IRQ_LIDOPEN] = RC5T583_IRQ(SYS_INT, 0, 2, 2, 0),
- [RC5T583_IRQ_PREOT] = RC5T583_IRQ(SYS_INT, 0, 3, 3, 0),
- [RC5T583_IRQ_CLKSTP] = RC5T583_IRQ(SYS_INT, 0, 4, 4, 0),
- [RC5T583_IRQ_ONKEY_OFF] = RC5T583_IRQ(SYS_INT, 0, 5, 5, 0),
- [RC5T583_IRQ_WD] = RC5T583_IRQ(SYS_INT, 0, 7, 7, 0),
- [RC5T583_IRQ_EN_PWRREQ1] = RC5T583_IRQ(SYS_INT, 0, 8, 0, 1),
- [RC5T583_IRQ_EN_PWRREQ2] = RC5T583_IRQ(SYS_INT, 0, 9, 1, 1),
- [RC5T583_IRQ_PRE_VINDET] = RC5T583_IRQ(SYS_INT, 0, 10, 2, 1),
-
- [RC5T583_IRQ_DC0LIM] = RC5T583_IRQ(DCDC_INT, 1, 0, 0, 2),
- [RC5T583_IRQ_DC1LIM] = RC5T583_IRQ(DCDC_INT, 1, 1, 1, 2),
- [RC5T583_IRQ_DC2LIM] = RC5T583_IRQ(DCDC_INT, 1, 2, 2, 2),
- [RC5T583_IRQ_DC3LIM] = RC5T583_IRQ(DCDC_INT, 1, 3, 3, 2),
-
- [RC5T583_IRQ_CTC] = RC5T583_IRQ(RTC_INT, 2, 0, 0, 3),
- [RC5T583_IRQ_YALE] = RC5T583_IRQ(RTC_INT, 2, 5, 5, 3),
- [RC5T583_IRQ_DALE] = RC5T583_IRQ(RTC_INT, 2, 6, 6, 3),
- [RC5T583_IRQ_WALE] = RC5T583_IRQ(RTC_INT, 2, 7, 7, 3),
-
- [RC5T583_IRQ_AIN1L] = RC5T583_IRQ(ADC_INT, 3, 0, 0, 4),
- [RC5T583_IRQ_AIN2L] = RC5T583_IRQ(ADC_INT, 3, 1, 1, 4),
- [RC5T583_IRQ_AIN3L] = RC5T583_IRQ(ADC_INT, 3, 2, 2, 4),
- [RC5T583_IRQ_VBATL] = RC5T583_IRQ(ADC_INT, 3, 3, 3, 4),
- [RC5T583_IRQ_VIN3L] = RC5T583_IRQ(ADC_INT, 3, 4, 4, 4),
- [RC5T583_IRQ_VIN8L] = RC5T583_IRQ(ADC_INT, 3, 5, 5, 4),
- [RC5T583_IRQ_AIN1H] = RC5T583_IRQ(ADC_INT, 3, 6, 0, 5),
- [RC5T583_IRQ_AIN2H] = RC5T583_IRQ(ADC_INT, 3, 7, 1, 5),
- [RC5T583_IRQ_AIN3H] = RC5T583_IRQ(ADC_INT, 3, 8, 2, 5),
- [RC5T583_IRQ_VBATH] = RC5T583_IRQ(ADC_INT, 3, 9, 3, 5),
- [RC5T583_IRQ_VIN3H] = RC5T583_IRQ(ADC_INT, 3, 10, 4, 5),
- [RC5T583_IRQ_VIN8H] = RC5T583_IRQ(ADC_INT, 3, 11, 5, 5),
- [RC5T583_IRQ_ADCEND] = RC5T583_IRQ(ADC_INT, 3, 12, 0, 6),
-
- [RC5T583_IRQ_GPIO0] = RC5T583_IRQ(GPIO_INT, 4, 0, 0, 7),
- [RC5T583_IRQ_GPIO1] = RC5T583_IRQ(GPIO_INT, 4, 1, 1, 7),
- [RC5T583_IRQ_GPIO2] = RC5T583_IRQ(GPIO_INT, 4, 2, 2, 7),
- [RC5T583_IRQ_GPIO3] = RC5T583_IRQ(GPIO_INT, 4, 3, 3, 7),
- [RC5T583_IRQ_GPIO4] = RC5T583_IRQ(GPIO_INT, 4, 4, 4, 7),
- [RC5T583_IRQ_GPIO5] = RC5T583_IRQ(GPIO_INT, 4, 5, 5, 7),
- [RC5T583_IRQ_GPIO6] = RC5T583_IRQ(GPIO_INT, 4, 6, 6, 7),
- [RC5T583_IRQ_GPIO7] = RC5T583_IRQ(GPIO_INT, 4, 7, 7, 7),
-};
-
-static void rc5t583_irq_lock(struct irq_data *irq_data)
-{
- struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
- mutex_lock(&rc5t583->irq_lock);
-}
-
-static void rc5t583_irq_unmask(struct irq_data *irq_data)
-{
- struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
- unsigned int __irq = irq_data->irq - rc5t583->irq_base;
- const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq];
-
- rc5t583->group_irq_en[data->grp_index] |= 1 << data->grp_index;
- rc5t583->intc_inten_reg |= 1 << data->master_bit;
- rc5t583->irq_en_reg[data->mask_reg_index] |= 1 << data->int_en_bit;
-}
-
-static void rc5t583_irq_mask(struct irq_data *irq_data)
-{
- struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
- unsigned int __irq = irq_data->irq - rc5t583->irq_base;
- const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq];
-
- rc5t583->group_irq_en[data->grp_index] &= ~(1 << data->grp_index);
- if (!rc5t583->group_irq_en[data->grp_index])
- rc5t583->intc_inten_reg &= ~(1 << data->master_bit);
-
- rc5t583->irq_en_reg[data->mask_reg_index] &= ~(1 << data->int_en_bit);
-}
-
-static int rc5t583_irq_set_type(struct irq_data *irq_data, unsigned int type)
-{
- struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
- unsigned int __irq = irq_data->irq - rc5t583->irq_base;
- const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq];
- int val = 0;
- int gpedge_index;
- int gpedge_bit_pos;
-
- /* Supporting only trigger level inetrrupt */
- if ((data->int_type & GPIO_INT) && (type & IRQ_TYPE_EDGE_BOTH)) {
- gpedge_index = data->int_en_bit / 4;
- gpedge_bit_pos = data->int_en_bit % 4;
-
- if (type & IRQ_TYPE_EDGE_FALLING)
- val |= 0x2;
-
- if (type & IRQ_TYPE_EDGE_RISING)
- val |= 0x1;
-
- rc5t583->gpedge_reg[gpedge_index] &= ~(3 << gpedge_bit_pos);
- rc5t583->gpedge_reg[gpedge_index] |= (val << gpedge_bit_pos);
- rc5t583_irq_unmask(irq_data);
- return 0;
- }
- return -EINVAL;
-}
-
-static void rc5t583_irq_sync_unlock(struct irq_data *irq_data)
-{
- struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
- int i;
- int ret;
-
- for (i = 0; i < ARRAY_SIZE(rc5t583->gpedge_reg); i++) {
- ret = rc5t583_write(rc5t583->dev, gpedge_add[i],
- rc5t583->gpedge_reg[i]);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- gpedge_add[i], ret);
- }
-
- for (i = 0; i < ARRAY_SIZE(rc5t583->irq_en_reg); i++) {
- ret = rc5t583_write(rc5t583->dev, irq_en_add[i],
- rc5t583->irq_en_reg[i]);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- irq_en_add[i], ret);
- }
-
- ret = rc5t583_write(rc5t583->dev, RC5T583_INTC_INTEN,
- rc5t583->intc_inten_reg);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- RC5T583_INTC_INTEN, ret);
-
- mutex_unlock(&rc5t583->irq_lock);
-}
-
-static int rc5t583_irq_set_wake(struct irq_data *irq_data, unsigned int on)
-{
- struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
- return irq_set_irq_wake(rc5t583->chip_irq, on);
-}
-
-static irqreturn_t rc5t583_irq(int irq, void *data)
-{
- struct rc5t583 *rc5t583 = data;
- uint8_t int_sts[RC5T583_MAX_INTERRUPT_MASK_REGS];
- uint8_t master_int = 0;
- int i;
- int ret;
- unsigned int rtc_int_sts = 0;
-
- /* Clear the status */
- for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++)
- int_sts[i] = 0;
-
- ret = rc5t583_read(rc5t583->dev, RC5T583_INTC_INTMON, &master_int);
- if (ret < 0) {
- dev_err(rc5t583->dev,
- "Error in reading reg 0x%02x error: %d\n",
- RC5T583_INTC_INTMON, ret);
- return IRQ_HANDLED;
- }
-
- for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; ++i) {
- if (!(master_int & main_int_type[i]))
- continue;
-
- ret = rc5t583_read(rc5t583->dev, irq_mon_add[i], &int_sts[i]);
- if (ret < 0) {
- dev_warn(rc5t583->dev,
- "Error in reading reg 0x%02x error: %d\n",
- irq_mon_add[i], ret);
- int_sts[i] = 0;
- continue;
- }
-
- if (main_int_type[i] & RTC_INT) {
- rtc_int_sts = 0;
- if (int_sts[i] & 0x1)
- rtc_int_sts |= BIT(6);
- if (int_sts[i] & 0x2)
- rtc_int_sts |= BIT(7);
- if (int_sts[i] & 0x4)
- rtc_int_sts |= BIT(0);
- if (int_sts[i] & 0x8)
- rtc_int_sts |= BIT(5);
- }
-
- ret = rc5t583_write(rc5t583->dev, irq_clr_add[i],
- ~int_sts[i]);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in reading reg 0x%02x error: %d\n",
- irq_clr_add[i], ret);
-
- if (main_int_type[i] & RTC_INT)
- int_sts[i] = rtc_int_sts;
- }
-
- /* Merge gpio interrupts for rising and falling case*/
- int_sts[7] |= int_sts[8];
-
- /* Call interrupt handler if enabled */
- for (i = 0; i < RC5T583_MAX_IRQS; ++i) {
- const struct rc5t583_irq_data *data = &rc5t583_irqs[i];
- if ((int_sts[data->mask_reg_index] & (1 << data->int_en_bit)) &&
- (rc5t583->group_irq_en[data->master_bit] &
- (1 << data->grp_index)))
- handle_nested_irq(rc5t583->irq_base + i);
- }
-
- return IRQ_HANDLED;
-}
-
-static struct irq_chip rc5t583_irq_chip = {
- .name = "rc5t583-irq",
- .irq_mask = rc5t583_irq_mask,
- .irq_unmask = rc5t583_irq_unmask,
- .irq_bus_lock = rc5t583_irq_lock,
- .irq_bus_sync_unlock = rc5t583_irq_sync_unlock,
- .irq_set_type = rc5t583_irq_set_type,
- .irq_set_wake = pm_sleep_ptr(rc5t583_irq_set_wake),
-};
-
-int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base)
-{
- int i, ret;
-
- if (!irq_base) {
- dev_warn(rc5t583->dev, "No interrupt support on IRQ base\n");
- return -EINVAL;
- }
-
- mutex_init(&rc5t583->irq_lock);
-
- /* Initailize all int register to 0 */
- for (i = 0; i < RC5T583_MAX_INTERRUPT_EN_REGS; i++) {
- ret = rc5t583_write(rc5t583->dev, irq_en_add[i],
- rc5t583->irq_en_reg[i]);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- irq_en_add[i], ret);
- }
-
- for (i = 0; i < RC5T583_MAX_GPEDGE_REG; i++) {
- ret = rc5t583_write(rc5t583->dev, gpedge_add[i],
- rc5t583->gpedge_reg[i]);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- gpedge_add[i], ret);
- }
-
- ret = rc5t583_write(rc5t583->dev, RC5T583_INTC_INTEN, 0x0);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- RC5T583_INTC_INTEN, ret);
-
- /* Clear all interrupts in case they woke up active. */
- for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++) {
- ret = rc5t583_write(rc5t583->dev, irq_clr_add[i], 0);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- irq_clr_add[i], ret);
- }
-
- rc5t583->irq_base = irq_base;
- rc5t583->chip_irq = irq;
-
- for (i = 0; i < RC5T583_MAX_IRQS; i++) {
- int __irq = i + rc5t583->irq_base;
- irq_set_chip_data(__irq, rc5t583);
- irq_set_chip_and_handler(__irq, &rc5t583_irq_chip,
- handle_simple_irq);
- irq_set_nested_thread(__irq, 1);
- irq_clear_status_flags(__irq, IRQ_NOREQUEST);
- }
-
- ret = devm_request_threaded_irq(rc5t583->dev, irq, NULL, rc5t583_irq,
- IRQF_ONESHOT, "rc5t583", rc5t583);
- if (ret < 0)
- dev_err(rc5t583->dev,
- "Error in registering interrupt error: %d\n", ret);
- return ret;
-}
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
deleted file mode 100644
index 2c0e8e9630f7..000000000000
--- a/drivers/mfd/rc5t583.c
+++ /dev/null
@@ -1,299 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Core driver access RC5T583 power management chip.
- *
- * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
- * Author: Laxman dewangan <ldewangan@nvidia.com>
- *
- * Based on code
- * Copyright (C) 2011 RICOH COMPANY,LTD
- */
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/rc5t583.h>
-#include <linux/regmap.h>
-
-#define RICOH_ONOFFSEL_REG 0x10
-#define RICOH_SWCTL_REG 0x5E
-
-struct deepsleep_control_data {
- u8 reg_add;
- u8 ds_pos_bit;
-};
-
-#define DEEPSLEEP_INIT(_id, _reg, _pos) \
- { \
- .reg_add = RC5T583_##_reg, \
- .ds_pos_bit = _pos, \
- }
-
-static struct deepsleep_control_data deepsleep_data[] = {
- DEEPSLEEP_INIT(DC0, SLPSEQ1, 0),
- DEEPSLEEP_INIT(DC1, SLPSEQ1, 4),
- DEEPSLEEP_INIT(DC2, SLPSEQ2, 0),
- DEEPSLEEP_INIT(DC3, SLPSEQ2, 4),
- DEEPSLEEP_INIT(LDO0, SLPSEQ3, 0),
- DEEPSLEEP_INIT(LDO1, SLPSEQ3, 4),
- DEEPSLEEP_INIT(LDO2, SLPSEQ4, 0),
- DEEPSLEEP_INIT(LDO3, SLPSEQ4, 4),
- DEEPSLEEP_INIT(LDO4, SLPSEQ5, 0),
- DEEPSLEEP_INIT(LDO5, SLPSEQ5, 4),
- DEEPSLEEP_INIT(LDO6, SLPSEQ6, 0),
- DEEPSLEEP_INIT(LDO7, SLPSEQ6, 4),
- DEEPSLEEP_INIT(LDO8, SLPSEQ7, 0),
- DEEPSLEEP_INIT(LDO9, SLPSEQ7, 4),
- DEEPSLEEP_INIT(PSO0, SLPSEQ8, 0),
- DEEPSLEEP_INIT(PSO1, SLPSEQ8, 4),
- DEEPSLEEP_INIT(PSO2, SLPSEQ9, 0),
- DEEPSLEEP_INIT(PSO3, SLPSEQ9, 4),
- DEEPSLEEP_INIT(PSO4, SLPSEQ10, 0),
- DEEPSLEEP_INIT(PSO5, SLPSEQ10, 4),
- DEEPSLEEP_INIT(PSO6, SLPSEQ11, 0),
- DEEPSLEEP_INIT(PSO7, SLPSEQ11, 4),
-};
-
-#define EXT_PWR_REQ \
- (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL)
-
-static const struct mfd_cell rc5t583_subdevs[] = {
- {.name = "rc5t583-gpio",},
- {.name = "rc5t583-regulator",},
- {.name = "rc5t583-rtc", },
- {.name = "rc5t583-key", }
-};
-
-static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
- int id, int ext_pwr, int slots)
-{
- int ret;
- uint8_t sleepseq_val = 0;
- unsigned int en_bit;
- unsigned int slot_bit;
-
- if (id == RC5T583_DS_DC0) {
- dev_err(dev, "PWRREQ1 is invalid control for rail %d\n", id);
- return -EINVAL;
- }
-
- en_bit = deepsleep_data[id].ds_pos_bit;
- slot_bit = en_bit + 1;
- ret = rc5t583_read(dev, deepsleep_data[id].reg_add, &sleepseq_val);
- if (ret < 0) {
- dev_err(dev, "Error in reading reg 0x%x\n",
- deepsleep_data[id].reg_add);
- return ret;
- }
-
- sleepseq_val &= ~(0xF << en_bit);
- sleepseq_val |= BIT(en_bit);
- sleepseq_val |= ((slots & 0x7) << slot_bit);
- ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(1));
- if (ret < 0) {
- dev_err(dev, "Error in updating the 0x%02x register\n",
- RICOH_ONOFFSEL_REG);
- return ret;
- }
-
- ret = rc5t583_write(dev, deepsleep_data[id].reg_add, sleepseq_val);
- if (ret < 0) {
- dev_err(dev, "Error in writing reg 0x%x\n",
- deepsleep_data[id].reg_add);
- return ret;
- }
-
- if (id == RC5T583_DS_LDO4) {
- ret = rc5t583_write(dev, RICOH_SWCTL_REG, 0x1);
- if (ret < 0)
- dev_err(dev, "Error in writing reg 0x%x\n",
- RICOH_SWCTL_REG);
- }
- return ret;
-}
-
-static int __rc5t583_set_ext_pwrreq2_control(struct device *dev,
- int id, int ext_pwr)
-{
- int ret;
-
- if (id != RC5T583_DS_DC0) {
- dev_err(dev, "PWRREQ2 is invalid control for rail %d\n", id);
- return -EINVAL;
- }
-
- ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(2));
- if (ret < 0)
- dev_err(dev, "Error in updating the ONOFFSEL 0x10 register\n");
- return ret;
-}
-
-int rc5t583_ext_power_req_config(struct device *dev, int ds_id,
- int ext_pwr_req, int deepsleep_slot_nr)
-{
- if ((ext_pwr_req & EXT_PWR_REQ) == EXT_PWR_REQ)
- return -EINVAL;
-
- if (ext_pwr_req & RC5T583_EXT_PWRREQ1_CONTROL)
- return __rc5t583_set_ext_pwrreq1_control(dev, ds_id,
- ext_pwr_req, deepsleep_slot_nr);
-
- if (ext_pwr_req & RC5T583_EXT_PWRREQ2_CONTROL)
- return __rc5t583_set_ext_pwrreq2_control(dev,
- ds_id, ext_pwr_req);
- return 0;
-}
-EXPORT_SYMBOL(rc5t583_ext_power_req_config);
-
-static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,
- struct rc5t583_platform_data *pdata)
-{
- int ret;
- int i;
- uint8_t on_off_val = 0;
-
- /* Clear ONOFFSEL register */
- if (pdata->enable_shutdown)
- on_off_val = 0x1;
-
- ret = rc5t583_write(rc5t583->dev, RICOH_ONOFFSEL_REG, on_off_val);
- if (ret < 0)
- dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n",
- RICOH_ONOFFSEL_REG, ret);
-
- ret = rc5t583_write(rc5t583->dev, RICOH_SWCTL_REG, 0x0);
- if (ret < 0)
- dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n",
- RICOH_SWCTL_REG, ret);
-
- /* Clear sleep sequence register */
- for (i = RC5T583_SLPSEQ1; i <= RC5T583_SLPSEQ11; ++i) {
- ret = rc5t583_write(rc5t583->dev, i, 0x0);
- if (ret < 0)
- dev_warn(rc5t583->dev,
- "Error in writing reg 0x%02x error: %d\n",
- i, ret);
- }
- return 0;
-}
-
-static bool volatile_reg(struct device *dev, unsigned int reg)
-{
- /* Enable caching in interrupt registers */
- switch (reg) {
- case RC5T583_INT_EN_SYS1:
- case RC5T583_INT_EN_SYS2:
- case RC5T583_INT_EN_DCDC:
- case RC5T583_INT_EN_RTC:
- case RC5T583_INT_EN_ADC1:
- case RC5T583_INT_EN_ADC2:
- case RC5T583_INT_EN_ADC3:
- case RC5T583_GPIO_GPEDGE1:
- case RC5T583_GPIO_GPEDGE2:
- case RC5T583_GPIO_EN_INT:
- return false;
-
- case RC5T583_GPIO_MON_IOIN:
- /* This is gpio input register */
- return true;
-
- default:
- /* Enable caching in gpio registers */
- if ((reg >= RC5T583_GPIO_IOSEL) &&
- (reg <= RC5T583_GPIO_GPOFUNC))
- return false;
-
- /* Enable caching in sleep seq registers */
- if ((reg >= RC5T583_SLPSEQ1) && (reg <= RC5T583_SLPSEQ11))
- return false;
-
- /* Enable caching of regulator registers */
- if ((reg >= RC5T583_REG_DC0CTL) && (reg <= RC5T583_REG_SR3CTL))
- return false;
- if ((reg >= RC5T583_REG_LDOEN1) &&
- (reg <= RC5T583_REG_LDO9DAC_DS))
- return false;
-
- break;
- }
-
- return true;
-}
-
-static const struct regmap_config rc5t583_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .volatile_reg = volatile_reg,
- .max_register = RC5T583_MAX_REG,
- .num_reg_defaults_raw = RC5T583_NUM_REGS,
- .cache_type = REGCACHE_MAPLE,
-};
-
-static int rc5t583_i2c_probe(struct i2c_client *i2c)
-{
- struct rc5t583 *rc5t583;
- struct rc5t583_platform_data *pdata = dev_get_platdata(&i2c->dev);
- int ret;
-
- if (!pdata) {
- dev_err(&i2c->dev, "Err: Platform data not found\n");
- return -EINVAL;
- }
-
- rc5t583 = devm_kzalloc(&i2c->dev, sizeof(*rc5t583), GFP_KERNEL);
- if (!rc5t583)
- return -ENOMEM;
-
- rc5t583->dev = &i2c->dev;
- i2c_set_clientdata(i2c, rc5t583);
-
- rc5t583->regmap = devm_regmap_init_i2c(i2c, &rc5t583_regmap_config);
- if (IS_ERR(rc5t583->regmap)) {
- ret = PTR_ERR(rc5t583->regmap);
- dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
- return ret;
- }
-
- ret = rc5t583_clear_ext_power_req(rc5t583, pdata);
- if (ret < 0)
- return ret;
-
- if (i2c->irq) {
- ret = rc5t583_irq_init(rc5t583, i2c->irq, pdata->irq_base);
- /* Still continue with warning, if irq init fails */
- if (ret)
- dev_warn(&i2c->dev, "IRQ init failed: %d\n", ret);
- }
-
- ret = devm_mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs,
- ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL);
- if (ret) {
- dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static const struct i2c_device_id rc5t583_i2c_id[] = {
- {.name = "rc5t583", .driver_data = 0},
- {}
-};
-
-static struct i2c_driver rc5t583_i2c_driver = {
- .driver = {
- .name = "rc5t583",
- },
- .probe = rc5t583_i2c_probe,
- .id_table = rc5t583_i2c_id,
-};
-
-static int __init rc5t583_i2c_init(void)
-{
- return i2c_add_driver(&rc5t583_i2c_driver);
-}
-subsys_initcall(rc5t583_i2c_init);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 12d883e729bc..2d5eb954d122 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1214,16 +1214,6 @@ config REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2
unit. The regulator is used to enable power to the display and to
control backlight PWM.
-config REGULATOR_RC5T583
- tristate "RICOH RC5T583 Power regulators"
- depends on MFD_RC5T583
- help
- Select this option to enable the power regulator of RICOH
- PMIC RC5T583.
- This driver supports the control of different power rails of device
- through regulator interface. The device supports multiple DCDC/LDO
- outputs which can be controlled by i2c communication.
-
config REGULATOR_RK808
tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
depends on MFD_RK8XX
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 321c6ea73ee0..861f86c30c73 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -140,7 +140,6 @@ obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o
obj-$(CONFIG_REGULATOR_RAA215300) += raa215300.o
obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY) += rpi-panel-attiny-regulator.o
obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2) += rpi-panel-v2-regulator.o
-obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o
obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o
diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c
deleted file mode 100644
index a25a141e86c4..000000000000
--- a/drivers/regulator/rc5t583-regulator.c
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Regulator driver for RICOH RC5T583 power management chip.
- *
- * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
- * Author: Laxman dewangan <ldewangan@nvidia.com>
- *
- * based on code
- * Copyright (C) 2011 RICOH COMPANY,LTD
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/rc5t583.h>
-
-struct rc5t583_regulator_info {
- int deepsleep_id;
-
- /* Regulator register address.*/
- uint8_t reg_disc_reg;
- uint8_t disc_bit;
- uint8_t deepsleep_reg;
-
- /* Regulator specific turn-on delay and voltage settling time*/
- int enable_uv_per_us;
-
- /* Used by regulator core */
- struct regulator_desc desc;
-};
-
-static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
-{
- struct rc5t583_regulator_info *reg_info = rdev_get_drvdata(rdev);
- int vsel = regulator_get_voltage_sel_regmap(rdev);
- int curr_uV = regulator_list_voltage_linear(rdev, vsel);
-
- return DIV_ROUND_UP(curr_uV, reg_info->enable_uv_per_us);
-}
-
-static const struct regulator_ops rc5t583_ops = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .enable_time = rc5t583_regulator_enable_time,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .list_voltage = regulator_list_voltage_linear,
- .map_voltage = regulator_map_voltage_linear,
- .set_voltage_time_sel = regulator_set_voltage_time_sel,
-};
-
-#define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \
- _vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \
-{ \
- .reg_disc_reg = RC5T583_REG_##_disc_reg, \
- .disc_bit = _disc_bit, \
- .deepsleep_reg = RC5T583_REG_##_id##DAC_DS, \
- .enable_uv_per_us = _enable_mv * 1000, \
- .deepsleep_id = RC5T583_DS_##_id, \
- .desc = { \
- .name = "rc5t583-regulator-"#_id, \
- .id = RC5T583_REGULATOR_##_id, \
- .n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \
- .ops = &rc5t583_ops, \
- .type = REGULATOR_VOLTAGE, \
- .owner = THIS_MODULE, \
- .vsel_reg = RC5T583_REG_##_id##DAC, \
- .vsel_mask = _vout_mask, \
- .enable_reg = RC5T583_REG_##_en_reg, \
- .enable_mask = BIT(_en_bit), \
- .min_uV = _min_mv * 1000, \
- .uV_step = _step_uV, \
- .ramp_delay = 40 * 1000, \
- }, \
-}
-
-static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = {
- RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4),
- RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14),
- RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14),
- RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14),
- RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160),
- RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160),
- RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160),
- RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160),
- RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133),
- RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267),
- RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133),
- RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233),
- RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233),
- RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133),
-};
-
-static int rc5t583_regulator_probe(struct platform_device *pdev)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
- struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
- struct regulator_config config = { };
- struct regulator_dev *rdev;
- struct rc5t583_regulator_info *ri;
- int ret;
- int id;
-
- if (!pdata) {
- dev_err(&pdev->dev, "No platform data, exiting...\n");
- return -ENODEV;
- }
-
- for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) {
- ri = &rc5t583_reg_info[id];
-
- if (ri->deepsleep_id == RC5T583_DS_NONE)
- goto skip_ext_pwr_config;
-
- ret = rc5t583_ext_power_req_config(rc5t583->dev,
- ri->deepsleep_id,
- pdata->regulator_ext_pwr_control[id],
- pdata->regulator_deepsleep_slot[id]);
- /*
- * Configuring external control is not a major issue,
- * just give warning.
- */
- if (ret < 0)
- dev_warn(&pdev->dev,
- "Failed to configure ext control %d\n", id);
-
-skip_ext_pwr_config:
- config.dev = &pdev->dev;
- config.init_data = pdata->reg_init_data[id];
- config.driver_data = ri;
- config.regmap = rc5t583->regmap;
-
- rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
- if (IS_ERR(rdev)) {
- dev_err(&pdev->dev, "Failed to register regulator %s\n",
- ri->desc.name);
- return PTR_ERR(rdev);
- }
- }
- return 0;
-}
-
-static struct platform_driver rc5t583_regulator_driver = {
- .driver = {
- .name = "rc5t583-regulator",
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
- .probe = rc5t583_regulator_probe,
-};
-
-static int __init rc5t583_regulator_init(void)
-{
- return platform_driver_register(&rc5t583_regulator_driver);
-}
-subsys_initcall(rc5t583_regulator_init);
-
-static void __exit rc5t583_regulator_exit(void)
-{
- platform_driver_unregister(&rc5t583_regulator_driver);
-}
-module_exit(rc5t583_regulator_exit);
-
-MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
-MODULE_DESCRIPTION("RC5T583 regulator driver");
-MODULE_ALIAS("platform:rc5t583-regulator");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index c201948b4d5b..c71398368f6d 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -630,16 +630,6 @@ config RTC_DRV_TPS65910
This driver can also be built as a module. If so, the module
will be called rtc-tps65910.
-config RTC_DRV_RC5T583
- tristate "RICOH 5T583 RTC driver"
- depends on MFD_RC5T583
- help
- If you say yes here you get support for the RTC on the
- RICOH 5T583 chips.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-rc5t583.
-
config RTC_DRV_RC5T619
tristate "RICOH RC5T619 RTC driver"
depends on MFD_RN5T618
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 84bb2af5849e..b8fc1a17d27f 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -143,7 +143,6 @@ obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R7301) += rtc-r7301.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
-obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o
obj-$(CONFIG_RTC_DRV_RC5T619) += rtc-rc5t619.o
obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o
obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c
deleted file mode 100644
index 8ba9cda74acf..000000000000
--- a/drivers/rtc/rtc-rc5t583.c
+++ /dev/null
@@ -1,312 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * rtc-rc5t583.c -- RICOH RC5T583 Real Time Clock
- *
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
- * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/rc5t583.h>
-
-struct rc5t583_rtc {
- struct rtc_device *rtc;
- /* To store the list of enabled interrupts, during system suspend */
- u32 irqen;
-};
-
-/* Total number of RTC registers needed to set time*/
-#define NUM_TIME_REGS (RC5T583_RTC_YEAR - RC5T583_RTC_SEC + 1)
-
-/* Total number of RTC registers needed to set Y-Alarm*/
-#define NUM_YAL_REGS (RC5T583_RTC_AY_YEAR - RC5T583_RTC_AY_MIN + 1)
-
-/* Set Y-Alarm interrupt */
-#define SET_YAL BIT(5)
-
-/* Get Y-Alarm interrupt status*/
-#define GET_YAL_STATUS BIT(3)
-
-static int rc5t583_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- u8 val;
-
- /* Set Y-Alarm, based on 'enabled' */
- val = enabled ? SET_YAL : 0;
-
- return regmap_update_bits(rc5t583->regmap, RC5T583_RTC_CTL1, SET_YAL,
- val);
-}
-
-/*
- * Gets current rc5t583 RTC time and date parameters.
- *
- * The RTC's time/alarm representation is not what gmtime(3) requires
- * Linux to use:
- *
- * - Months are 1..12 vs Linux 0-11
- * - Years are 0..99 vs Linux 1900..N (we assume 21st century)
- */
-static int rc5t583_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- u8 rtc_data[NUM_TIME_REGS];
- int ret;
-
- ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data,
- NUM_TIME_REGS);
- if (ret < 0) {
- dev_err(dev, "RTC read time failed with err:%d\n", ret);
- return ret;
- }
-
- tm->tm_sec = bcd2bin(rtc_data[0]);
- tm->tm_min = bcd2bin(rtc_data[1]);
- tm->tm_hour = bcd2bin(rtc_data[2]);
- tm->tm_wday = bcd2bin(rtc_data[3]);
- tm->tm_mday = bcd2bin(rtc_data[4]);
- tm->tm_mon = bcd2bin(rtc_data[5]) - 1;
- tm->tm_year = bcd2bin(rtc_data[6]) + 100;
-
- return ret;
-}
-
-static int rc5t583_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- unsigned char rtc_data[NUM_TIME_REGS];
- int ret;
-
- rtc_data[0] = bin2bcd(tm->tm_sec);
- rtc_data[1] = bin2bcd(tm->tm_min);
- rtc_data[2] = bin2bcd(tm->tm_hour);
- rtc_data[3] = bin2bcd(tm->tm_wday);
- rtc_data[4] = bin2bcd(tm->tm_mday);
- rtc_data[5] = bin2bcd(tm->tm_mon + 1);
- rtc_data[6] = bin2bcd(tm->tm_year - 100);
-
- ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data,
- NUM_TIME_REGS);
- if (ret < 0) {
- dev_err(dev, "RTC set time failed with error %d\n", ret);
- return ret;
- }
-
- return ret;
-}
-
-static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- unsigned char alarm_data[NUM_YAL_REGS];
- u32 interrupt_enable;
- int ret;
-
- ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data,
- NUM_YAL_REGS);
- if (ret < 0) {
- dev_err(dev, "rtc_read_alarm error %d\n", ret);
- return ret;
- }
-
- alm->time.tm_sec = 0;
- alm->time.tm_min = bcd2bin(alarm_data[0]);
- alm->time.tm_hour = bcd2bin(alarm_data[1]);
- alm->time.tm_mday = bcd2bin(alarm_data[2]);
- alm->time.tm_mon = bcd2bin(alarm_data[3]) - 1;
- alm->time.tm_year = bcd2bin(alarm_data[4]) + 100;
-
- ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, &interrupt_enable);
- if (ret < 0)
- return ret;
-
- /* check if YALE is set */
- if (interrupt_enable & SET_YAL)
- alm->enabled = 1;
-
- return ret;
-}
-
-static int rc5t583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- unsigned char alarm_data[NUM_YAL_REGS];
- int ret;
-
- ret = rc5t583_rtc_alarm_irq_enable(dev, 0);
- if (ret)
- return ret;
-
- alarm_data[0] = bin2bcd(alm->time.tm_min);
- alarm_data[1] = bin2bcd(alm->time.tm_hour);
- alarm_data[2] = bin2bcd(alm->time.tm_mday);
- alarm_data[3] = bin2bcd(alm->time.tm_mon + 1);
- alarm_data[4] = bin2bcd(alm->time.tm_year - 100);
-
- ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data,
- NUM_YAL_REGS);
- if (ret) {
- dev_err(dev, "rtc_set_alarm error %d\n", ret);
- return ret;
- }
-
- if (alm->enabled)
- ret = rc5t583_rtc_alarm_irq_enable(dev, 1);
-
- return ret;
-}
-
-static irqreturn_t rc5t583_rtc_interrupt(int irq, void *rtc)
-{
- struct device *dev = rtc;
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
- unsigned long events = 0;
- int ret;
- u32 rtc_reg;
-
- ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL2, &rtc_reg);
- if (ret < 0)
- return IRQ_NONE;
-
- if (rtc_reg & GET_YAL_STATUS) {
- events = RTC_IRQF | RTC_AF;
- /* clear pending Y-alarm interrupt bit */
- rtc_reg &= ~GET_YAL_STATUS;
- }
-
- ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, rtc_reg);
- if (ret)
- return IRQ_NONE;
-
- /* Notify RTC core on event */
- rtc_update_irq(rc5t583_rtc->rtc, 1, events);
-
- return IRQ_HANDLED;
-}
-
-static const struct rtc_class_ops rc5t583_rtc_ops = {
- .read_time = rc5t583_rtc_read_time,
- .set_time = rc5t583_rtc_set_time,
- .read_alarm = rc5t583_rtc_read_alarm,
- .set_alarm = rc5t583_rtc_set_alarm,
- .alarm_irq_enable = rc5t583_rtc_alarm_irq_enable,
-};
-
-static int rc5t583_rtc_probe(struct platform_device *pdev)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
- struct rc5t583_rtc *ricoh_rtc;
- struct rc5t583_platform_data *pmic_plat_data;
- int ret;
- int irq;
-
- ricoh_rtc = devm_kzalloc(&pdev->dev, sizeof(struct rc5t583_rtc),
- GFP_KERNEL);
- if (!ricoh_rtc)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, ricoh_rtc);
-
- /* Clear pending interrupts */
- ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, 0);
- if (ret < 0)
- return ret;
-
- /* clear RTC Adjust register */
- ret = regmap_write(rc5t583->regmap, RC5T583_RTC_ADJ, 0);
- if (ret < 0) {
- dev_err(&pdev->dev, "unable to program rtc_adjust reg\n");
- return -EBUSY;
- }
-
- pmic_plat_data = dev_get_platdata(rc5t583->dev);
- irq = pmic_plat_data->irq_base;
- if (irq <= 0) {
- dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n",
- irq);
- return ret;
- }
-
- irq += RC5T583_IRQ_YALE;
- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
- rc5t583_rtc_interrupt, IRQF_TRIGGER_LOW,
- "rtc-rc5t583", &pdev->dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "IRQ is not free.\n");
- return ret;
- }
- device_init_wakeup(&pdev->dev, true);
-
- ricoh_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
- &rc5t583_rtc_ops, THIS_MODULE);
- if (IS_ERR(ricoh_rtc->rtc)) {
- ret = PTR_ERR(ricoh_rtc->rtc);
- dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * Disable rc5t583 RTC interrupts.
- * Sets status flag to free.
- */
-static void rc5t583_rtc_remove(struct platform_device *pdev)
-{
- struct rc5t583_rtc *rc5t583_rtc = platform_get_drvdata(pdev);
-
- rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int rc5t583_rtc_suspend(struct device *dev)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
- int ret;
-
- /* Store current list of enabled interrupts*/
- ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1,
- &rc5t583_rtc->irqen);
- return ret;
-}
-
-static int rc5t583_rtc_resume(struct device *dev)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
- struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
-
- /* Restore list of enabled interrupts before suspend */
- return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1,
- rc5t583_rtc->irqen);
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(rc5t583_rtc_pm_ops, rc5t583_rtc_suspend,
- rc5t583_rtc_resume);
-
-static struct platform_driver rc5t583_rtc_driver = {
- .probe = rc5t583_rtc_probe,
- .remove = rc5t583_rtc_remove,
- .driver = {
- .name = "rtc-rc5t583",
- .pm = &rc5t583_rtc_pm_ops,
- },
-};
-
-module_platform_driver(rc5t583_rtc_driver);
-MODULE_ALIAS("platform:rtc-rc5t583");
-MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
-MODULE_DESCRIPTION("RICOH 5T583 RTC driver");
-MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h
deleted file mode 100644
index 4f220146cc02..000000000000
--- a/include/linux/mfd/rc5t583.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Core driver interface to access RICOH_RC5T583 power management chip.
- *
- * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
- * Author: Laxman dewangan <ldewangan@nvidia.com>
- *
- * Based on code
- * Copyright (C) 2011 RICOH COMPANY,LTD
- */
-
-#ifndef __LINUX_MFD_RC5T583_H
-#define __LINUX_MFD_RC5T583_H
-
-#include <linux/mutex.h>
-#include <linux/types.h>
-#include <linux/regmap.h>
-
-/* Maximum number of main interrupts */
-#define MAX_MAIN_INTERRUPT 5
-#define RC5T583_MAX_GPEDGE_REG 2
-#define RC5T583_MAX_INTERRUPT_EN_REGS 8
-#define RC5T583_MAX_INTERRUPT_MASK_REGS 9
-
-/* Interrupt enable register */
-#define RC5T583_INT_EN_SYS1 0x19
-#define RC5T583_INT_EN_SYS2 0x1D
-#define RC5T583_INT_EN_DCDC 0x41
-#define RC5T583_INT_EN_RTC 0xED
-#define RC5T583_INT_EN_ADC1 0x90
-#define RC5T583_INT_EN_ADC2 0x91
-#define RC5T583_INT_EN_ADC3 0x92
-
-/* Interrupt status registers (monitor regs in Ricoh)*/
-#define RC5T583_INTC_INTPOL 0xAD
-#define RC5T583_INTC_INTEN 0xAE
-#define RC5T583_INTC_INTMON 0xAF
-
-#define RC5T583_INT_MON_GRP 0xAF
-#define RC5T583_INT_MON_SYS1 0x1B
-#define RC5T583_INT_MON_SYS2 0x1F
-#define RC5T583_INT_MON_DCDC 0x43
-#define RC5T583_INT_MON_RTC 0xEE
-
-/* Interrupt clearing registers */
-#define RC5T583_INT_IR_SYS1 0x1A
-#define RC5T583_INT_IR_SYS2 0x1E
-#define RC5T583_INT_IR_DCDC 0x42
-#define RC5T583_INT_IR_RTC 0xEE
-#define RC5T583_INT_IR_ADCL 0x94
-#define RC5T583_INT_IR_ADCH 0x95
-#define RC5T583_INT_IR_ADCEND 0x96
-#define RC5T583_INT_IR_GPIOR 0xA9
-#define RC5T583_INT_IR_GPIOF 0xAA
-
-/* Sleep sequence registers */
-#define RC5T583_SLPSEQ1 0x21
-#define RC5T583_SLPSEQ2 0x22
-#define RC5T583_SLPSEQ3 0x23
-#define RC5T583_SLPSEQ4 0x24
-#define RC5T583_SLPSEQ5 0x25
-#define RC5T583_SLPSEQ6 0x26
-#define RC5T583_SLPSEQ7 0x27
-#define RC5T583_SLPSEQ8 0x28
-#define RC5T583_SLPSEQ9 0x29
-#define RC5T583_SLPSEQ10 0x2A
-#define RC5T583_SLPSEQ11 0x2B
-
-/* Regulator registers */
-#define RC5T583_REG_DC0CTL 0x30
-#define RC5T583_REG_DC0DAC 0x31
-#define RC5T583_REG_DC0LATCTL 0x32
-#define RC5T583_REG_SR0CTL 0x33
-
-#define RC5T583_REG_DC1CTL 0x34
-#define RC5T583_REG_DC1DAC 0x35
-#define RC5T583_REG_DC1LATCTL 0x36
-#define RC5T583_REG_SR1CTL 0x37
-
-#define RC5T583_REG_DC2CTL 0x38
-#define RC5T583_REG_DC2DAC 0x39
-#define RC5T583_REG_DC2LATCTL 0x3A
-#define RC5T583_REG_SR2CTL 0x3B
-
-#define RC5T583_REG_DC3CTL 0x3C
-#define RC5T583_REG_DC3DAC 0x3D
-#define RC5T583_REG_DC3LATCTL 0x3E
-#define RC5T583_REG_SR3CTL 0x3F
-
-
-#define RC5T583_REG_LDOEN1 0x50
-#define RC5T583_REG_LDOEN2 0x51
-#define RC5T583_REG_LDODIS1 0x52
-#define RC5T583_REG_LDODIS2 0x53
-
-#define RC5T583_REG_LDO0DAC 0x54
-#define RC5T583_REG_LDO1DAC 0x55
-#define RC5T583_REG_LDO2DAC 0x56
-#define RC5T583_REG_LDO3DAC 0x57
-#define RC5T583_REG_LDO4DAC 0x58
-#define RC5T583_REG_LDO5DAC 0x59
-#define RC5T583_REG_LDO6DAC 0x5A
-#define RC5T583_REG_LDO7DAC 0x5B
-#define RC5T583_REG_LDO8DAC 0x5C
-#define RC5T583_REG_LDO9DAC 0x5D
-
-#define RC5T583_REG_DC0DAC_DS 0x60
-#define RC5T583_REG_DC1DAC_DS 0x61
-#define RC5T583_REG_DC2DAC_DS 0x62
-#define RC5T583_REG_DC3DAC_DS 0x63
-
-#define RC5T583_REG_LDO0DAC_DS 0x64
-#define RC5T583_REG_LDO1DAC_DS 0x65
-#define RC5T583_REG_LDO2DAC_DS 0x66
-#define RC5T583_REG_LDO3DAC_DS 0x67
-#define RC5T583_REG_LDO4DAC_DS 0x68
-#define RC5T583_REG_LDO5DAC_DS 0x69
-#define RC5T583_REG_LDO6DAC_DS 0x6A
-#define RC5T583_REG_LDO7DAC_DS 0x6B
-#define RC5T583_REG_LDO8DAC_DS 0x6C
-#define RC5T583_REG_LDO9DAC_DS 0x6D
-
-/* GPIO register base address */
-#define RC5T583_GPIO_IOSEL 0xA0
-#define RC5T583_GPIO_PDEN 0xA1
-#define RC5T583_GPIO_IOOUT 0xA2
-#define RC5T583_GPIO_PGSEL 0xA3
-#define RC5T583_GPIO_GPINV 0xA4
-#define RC5T583_GPIO_GPDEB 0xA5
-#define RC5T583_GPIO_GPEDGE1 0xA6
-#define RC5T583_GPIO_GPEDGE2 0xA7
-#define RC5T583_GPIO_EN_INT 0xA8
-#define RC5T583_GPIO_MON_IOIN 0xAB
-#define RC5T583_GPIO_GPOFUNC 0xAC
-
-/* RTC registers */
-#define RC5T583_RTC_SEC 0xE0
-#define RC5T583_RTC_MIN 0xE1
-#define RC5T583_RTC_HOUR 0xE2
-#define RC5T583_RTC_WDAY 0xE3
-#define RC5T583_RTC_DAY 0xE4
-#define RC5T583_RTC_MONTH 0xE5
-#define RC5T583_RTC_YEAR 0xE6
-#define RC5T583_RTC_ADJ 0xE7
-#define RC5T583_RTC_AW_MIN 0xE8
-#define RC5T583_RTC_AW_HOUR 0xE9
-#define RC5T583_RTC_AW_WEEK 0xEA
-#define RC5T583_RTC_AD_MIN 0xEB
-#define RC5T583_RTC_AD_HOUR 0xEC
-#define RC5T583_RTC_CTL1 0xED
-#define RC5T583_RTC_CTL2 0xEE
-#define RC5T583_RTC_AY_MIN 0xF0
-#define RC5T583_RTC_AY_HOUR 0xF1
-#define RC5T583_RTC_AY_DAY 0xF2
-#define RC5T583_RTC_AY_MONTH 0xF3
-#define RC5T583_RTC_AY_YEAR 0xF4
-
-#define RC5T583_MAX_REG 0xF7
-#define RC5T583_NUM_REGS (RC5T583_MAX_REG + 1)
-
-/* RICOH_RC5T583 IRQ definitions */
-enum {
- RC5T583_IRQ_ONKEY,
- RC5T583_IRQ_ACOK,
- RC5T583_IRQ_LIDOPEN,
- RC5T583_IRQ_PREOT,
- RC5T583_IRQ_CLKSTP,
- RC5T583_IRQ_ONKEY_OFF,
- RC5T583_IRQ_WD,
- RC5T583_IRQ_EN_PWRREQ1,
- RC5T583_IRQ_EN_PWRREQ2,
- RC5T583_IRQ_PRE_VINDET,
-
- RC5T583_IRQ_DC0LIM,
- RC5T583_IRQ_DC1LIM,
- RC5T583_IRQ_DC2LIM,
- RC5T583_IRQ_DC3LIM,
-
- RC5T583_IRQ_CTC,
- RC5T583_IRQ_YALE,
- RC5T583_IRQ_DALE,
- RC5T583_IRQ_WALE,
-
- RC5T583_IRQ_AIN1L,
- RC5T583_IRQ_AIN2L,
- RC5T583_IRQ_AIN3L,
- RC5T583_IRQ_VBATL,
- RC5T583_IRQ_VIN3L,
- RC5T583_IRQ_VIN8L,
- RC5T583_IRQ_AIN1H,
- RC5T583_IRQ_AIN2H,
- RC5T583_IRQ_AIN3H,
- RC5T583_IRQ_VBATH,
- RC5T583_IRQ_VIN3H,
- RC5T583_IRQ_VIN8H,
- RC5T583_IRQ_ADCEND,
-
- RC5T583_IRQ_GPIO0,
- RC5T583_IRQ_GPIO1,
- RC5T583_IRQ_GPIO2,
- RC5T583_IRQ_GPIO3,
- RC5T583_IRQ_GPIO4,
- RC5T583_IRQ_GPIO5,
- RC5T583_IRQ_GPIO6,
- RC5T583_IRQ_GPIO7,
-
- /* Should be last entry */
- RC5T583_MAX_IRQS,
-};
-
-/* Ricoh583 gpio definitions */
-enum {
- RC5T583_GPIO0,
- RC5T583_GPIO1,
- RC5T583_GPIO2,
- RC5T583_GPIO3,
- RC5T583_GPIO4,
- RC5T583_GPIO5,
- RC5T583_GPIO6,
- RC5T583_GPIO7,
-
- /* Should be last entry */
- RC5T583_MAX_GPIO,
-};
-
-enum {
- RC5T583_DS_NONE,
- RC5T583_DS_DC0,
- RC5T583_DS_DC1,
- RC5T583_DS_DC2,
- RC5T583_DS_DC3,
- RC5T583_DS_LDO0,
- RC5T583_DS_LDO1,
- RC5T583_DS_LDO2,
- RC5T583_DS_LDO3,
- RC5T583_DS_LDO4,
- RC5T583_DS_LDO5,
- RC5T583_DS_LDO6,
- RC5T583_DS_LDO7,
- RC5T583_DS_LDO8,
- RC5T583_DS_LDO9,
- RC5T583_DS_PSO0,
- RC5T583_DS_PSO1,
- RC5T583_DS_PSO2,
- RC5T583_DS_PSO3,
- RC5T583_DS_PSO4,
- RC5T583_DS_PSO5,
- RC5T583_DS_PSO6,
- RC5T583_DS_PSO7,
-
- /* Should be last entry */
- RC5T583_DS_MAX,
-};
-
-/*
- * Ricoh pmic RC5T583 supports sleep through two external controls.
- * The output of gpios and regulator can be enable/disable through
- * this external signals.
- */
-enum {
- RC5T583_EXT_PWRREQ1_CONTROL = 0x1,
- RC5T583_EXT_PWRREQ2_CONTROL = 0x2,
-};
-
-enum {
- RC5T583_REGULATOR_DC0,
- RC5T583_REGULATOR_DC1,
- RC5T583_REGULATOR_DC2,
- RC5T583_REGULATOR_DC3,
- RC5T583_REGULATOR_LDO0,
- RC5T583_REGULATOR_LDO1,
- RC5T583_REGULATOR_LDO2,
- RC5T583_REGULATOR_LDO3,
- RC5T583_REGULATOR_LDO4,
- RC5T583_REGULATOR_LDO5,
- RC5T583_REGULATOR_LDO6,
- RC5T583_REGULATOR_LDO7,
- RC5T583_REGULATOR_LDO8,
- RC5T583_REGULATOR_LDO9,
-
- /* Should be last entry */
- RC5T583_REGULATOR_MAX,
-};
-
-struct rc5t583 {
- struct device *dev;
- struct regmap *regmap;
- int chip_irq;
- int irq_base;
- struct mutex irq_lock;
- unsigned long group_irq_en[MAX_MAIN_INTERRUPT];
-
- /* For main interrupt bits in INTC */
- uint8_t intc_inten_reg;
-
- /* For group interrupt bits and address */
- uint8_t irq_en_reg[RC5T583_MAX_INTERRUPT_EN_REGS];
-
- /* For gpio edge */
- uint8_t gpedge_reg[RC5T583_MAX_GPEDGE_REG];
-};
-
-/*
- * rc5t583_platform_data: Platform data for ricoh rc5t583 pmu.
- * The board specific data is provided through this structure.
- * @irq_base: Irq base number on which this device registers their interrupts.
- * @gpio_base: GPIO base from which gpio of this device will start.
- * @enable_shutdown: Enable shutdown through the input pin "shutdown".
- * @regulator_deepsleep_slot: The slot number on which device goes to sleep
- * in device sleep mode.
- * @regulator_ext_pwr_control: External power request regulator control. The
- * regulator output enable/disable is controlled by the external
- * power request input state.
- * @reg_init_data: Regulator init data.
- */
-
-struct rc5t583_platform_data {
- int irq_base;
- int gpio_base;
- bool enable_shutdown;
- int regulator_deepsleep_slot[RC5T583_REGULATOR_MAX];
- unsigned long regulator_ext_pwr_control[RC5T583_REGULATOR_MAX];
- struct regulator_init_data *reg_init_data[RC5T583_REGULATOR_MAX];
-};
-
-static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_write(rc5t583->regmap, reg, val);
-}
-
-static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- unsigned int ival;
- int ret;
- ret = regmap_read(rc5t583->regmap, reg, &ival);
- if (!ret)
- *val = (uint8_t)ival;
- return ret;
-}
-
-static inline int rc5t583_set_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
-}
-
-static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
-}
-
-static inline int rc5t583_update(struct device *dev, unsigned int reg,
- unsigned int val, unsigned int mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, mask, val);
-}
-
-int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id,
- int ext_pwr_req, int deepsleep_slot_nr);
-int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base);
-int rc5t583_irq_exit(struct rc5t583 *rc5t583);
-
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* Re: [PATCH 10/14] mfd: remove unused rc5t583 driver
2026-09-09 13:21 ` [PATCH 10/14] mfd: remove unused rc5t583 driver Arnd Bergmann
@ 2026-09-09 13:48 ` Alexandre Belloni
0 siblings, 0 replies; 36+ messages in thread
From: Alexandre Belloni @ 2026-09-09 13:48 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Sebastian Reichel,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
On 09/09/2026 15:21:47+0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> Ricoh RC5T583 support was added in 2012, but no upstream code ever
> defined the corresponding platform_data, and there is no devicetree
> support, so this is all dead code.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 12/14] mfd: remove unused mcp-sa11x0/ucb1x00 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (7 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 10/14] mfd: remove unused rc5t583 driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:21 ` [PATCH 13/14] mfd: remove unused menelaus driver Arnd Bergmann
` (5 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
The sa1100 platform has been removed, so these drivers are no longer
used anywhere.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
Documentation/admin-guide/devices.txt | 1 -
drivers/mfd/Kconfig | 24 -
drivers/mfd/Makefile | 8 -
drivers/mfd/mcp-core.c | 235 ------
drivers/mfd/mcp-sa11x0.c | 304 -------
drivers/mfd/ucb1x00-assabet.c | 175 ----
drivers/mfd/ucb1x00-core.c | 795 -------------------
drivers/mfd/ucb1x00-ts.c | 445 -----------
include/linux/mfd/mcp.h | 63 --
include/linux/mfd/ucb1x00.h | 261 ------
include/linux/platform_data/mfd-mcp-sa11x0.h | 17 -
11 files changed, 2328 deletions(-)
delete mode 100644 drivers/mfd/mcp-core.c
delete mode 100644 drivers/mfd/mcp-sa11x0.c
delete mode 100644 drivers/mfd/ucb1x00-assabet.c
delete mode 100644 drivers/mfd/ucb1x00-core.c
delete mode 100644 drivers/mfd/ucb1x00-ts.c
delete mode 100644 include/linux/mfd/mcp.h
delete mode 100644 include/linux/mfd/ucb1x00.h
delete mode 100644 include/linux/platform_data/mfd-mcp-sa11x0.h
diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt
index f544399675fa..eaaa03118fc1 100644
--- a/Documentation/admin-guide/devices.txt
+++ b/Documentation/admin-guide/devices.txt
@@ -262,7 +262,6 @@
10 = /dev/adbmouse Apple Desktop Bus mouse
11 = /dev/vrtpanel Vr41xx embedded touch panel
13 = /dev/vpcmouse Connectix Virtual PC Mouse
- 14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen
15 = /dev/touchscreen/mk712 MK712 touchscreen
128 = /dev/beep Fancy beep device
129 =
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8a3bbb628693..0395af7270f9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2258,30 +2258,6 @@ config MFD_QCOM_PM8008
under it in the device tree. Additional drivers must be enabled in
order to use the functionality of the device.
-menu "Multimedia Capabilities Port drivers"
- depends on ARCH_SA1100
-
-config MCP
- tristate
-
-# Interface drivers
-config MCP_SA11X0
- tristate "Support SA11x0 MCP interface"
- depends on ARCH_SA1100
- select MCP
-
-# Chip drivers
-config MCP_UCB1200
- tristate "Support for UCB1200 / UCB1300"
- depends on MCP_SA11X0
- select MCP
-
-config MCP_UCB1200_TS
- tristate "Touchscreen interface support"
- depends on MCP_UCB1200 && INPUT
-
-endmenu
-
config MFD_VEXPRESS_SYSREG
tristate "Versatile Express System Registers"
depends on VEXPRESS_CONFIG && GPIOLIB
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 2cdbc693ee33..ff62e922209e 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -126,14 +126,6 @@ obj-$(CONFIG_MFD_OCELOT) += ocelot-soc.o
obj-$(CONFIG_MFD_CPCAP) += motorola-cpcap.o
-obj-$(CONFIG_MCP) += mcp-core.o
-obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
-obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
-obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
-
-ifeq ($(CONFIG_SA1100_ASSABET),y)
-obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
-endif
obj-$(CONFIG_PMIC_DA9052) += da9052-irq.o
obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
deleted file mode 100644
index be08eaee0a90..000000000000
--- a/drivers/mfd/mcp-core.c
+++ /dev/null
@@ -1,235 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/mfd/mcp-core.c
- *
- * Copyright (C) 2001 Russell King
- *
- * Generic MCP (Multimedia Communications Port) layer. All MCP locking
- * is solely held within this file.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/mfd/mcp.h>
-
-
-#define to_mcp(d) container_of(d, struct mcp, attached_device)
-#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
-
-static int mcp_bus_match(struct device *dev, const struct device_driver *drv)
-{
- return 1;
-}
-
-static int mcp_bus_probe(struct device *dev)
-{
- struct mcp *mcp = to_mcp(dev);
- struct mcp_driver *drv = to_mcp_driver(dev->driver);
-
- return drv->probe(mcp);
-}
-
-static void mcp_bus_remove(struct device *dev)
-{
- struct mcp *mcp = to_mcp(dev);
- struct mcp_driver *drv = to_mcp_driver(dev->driver);
-
- drv->remove(mcp);
-}
-
-static const struct bus_type mcp_bus_type = {
- .name = "mcp",
- .match = mcp_bus_match,
- .probe = mcp_bus_probe,
- .remove = mcp_bus_remove,
-};
-
-/**
- * mcp_set_telecom_divisor - set the telecom divisor
- * @mcp: MCP interface structure
- * @div: SIB clock divisor
- *
- * Set the telecom divisor on the MCP interface. The resulting
- * sample rate is SIBCLOCK/div.
- */
-void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mcp->lock, flags);
- mcp->ops->set_telecom_divisor(mcp, div);
- spin_unlock_irqrestore(&mcp->lock, flags);
-}
-EXPORT_SYMBOL(mcp_set_telecom_divisor);
-
-/**
- * mcp_set_audio_divisor - set the audio divisor
- * @mcp: MCP interface structure
- * @div: SIB clock divisor
- *
- * Set the audio divisor on the MCP interface.
- */
-void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mcp->lock, flags);
- mcp->ops->set_audio_divisor(mcp, div);
- spin_unlock_irqrestore(&mcp->lock, flags);
-}
-EXPORT_SYMBOL(mcp_set_audio_divisor);
-
-/**
- * mcp_reg_write - write a device register
- * @mcp: MCP interface structure
- * @reg: 4-bit register index
- * @val: 16-bit data value
- *
- * Write a device register. The MCP interface must be enabled
- * to prevent this function hanging.
- */
-void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mcp->lock, flags);
- mcp->ops->reg_write(mcp, reg, val);
- spin_unlock_irqrestore(&mcp->lock, flags);
-}
-EXPORT_SYMBOL(mcp_reg_write);
-
-/**
- * mcp_reg_read - read a device register
- * @mcp: MCP interface structure
- * @reg: 4-bit register index
- *
- * Read a device register and return its value. The MCP interface
- * must be enabled to prevent this function hanging.
- */
-unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
-{
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&mcp->lock, flags);
- val = mcp->ops->reg_read(mcp, reg);
- spin_unlock_irqrestore(&mcp->lock, flags);
-
- return val;
-}
-EXPORT_SYMBOL(mcp_reg_read);
-
-/**
- * mcp_enable - enable the MCP interface
- * @mcp: MCP interface to enable
- *
- * Enable the MCP interface. Each call to mcp_enable will need
- * a corresponding call to mcp_disable to disable the interface.
- */
-void mcp_enable(struct mcp *mcp)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mcp->lock, flags);
- if (mcp->use_count++ == 0)
- mcp->ops->enable(mcp);
- spin_unlock_irqrestore(&mcp->lock, flags);
-}
-EXPORT_SYMBOL(mcp_enable);
-
-/**
- * mcp_disable - disable the MCP interface
- * @mcp: MCP interface to disable
- *
- * Disable the MCP interface. The MCP interface will only be
- * disabled once the number of calls to mcp_enable matches the
- * number of calls to mcp_disable.
- */
-void mcp_disable(struct mcp *mcp)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mcp->lock, flags);
- if (--mcp->use_count == 0)
- mcp->ops->disable(mcp);
- spin_unlock_irqrestore(&mcp->lock, flags);
-}
-EXPORT_SYMBOL(mcp_disable);
-
-static void mcp_release(struct device *dev)
-{
- struct mcp *mcp = container_of(dev, struct mcp, attached_device);
-
- kfree(mcp);
-}
-
-struct mcp *mcp_host_alloc(struct device *parent, size_t size)
-{
- struct mcp *mcp;
-
- mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
- if (mcp) {
- spin_lock_init(&mcp->lock);
- device_initialize(&mcp->attached_device);
- mcp->attached_device.parent = parent;
- mcp->attached_device.bus = &mcp_bus_type;
- mcp->attached_device.dma_mask = parent->dma_mask;
- mcp->attached_device.release = mcp_release;
- }
- return mcp;
-}
-EXPORT_SYMBOL(mcp_host_alloc);
-
-int mcp_host_add(struct mcp *mcp, void *pdata)
-{
- mcp->attached_device.platform_data = pdata;
- dev_set_name(&mcp->attached_device, "mcp0");
- return device_add(&mcp->attached_device);
-}
-EXPORT_SYMBOL(mcp_host_add);
-
-void mcp_host_del(struct mcp *mcp)
-{
- device_del(&mcp->attached_device);
-}
-EXPORT_SYMBOL(mcp_host_del);
-
-void mcp_host_free(struct mcp *mcp)
-{
- put_device(&mcp->attached_device);
-}
-EXPORT_SYMBOL(mcp_host_free);
-
-int mcp_driver_register(struct mcp_driver *mcpdrv)
-{
- mcpdrv->drv.bus = &mcp_bus_type;
- return driver_register(&mcpdrv->drv);
-}
-EXPORT_SYMBOL(mcp_driver_register);
-
-void mcp_driver_unregister(struct mcp_driver *mcpdrv)
-{
- driver_unregister(&mcpdrv->drv);
-}
-EXPORT_SYMBOL(mcp_driver_unregister);
-
-static int __init mcp_init(void)
-{
- return bus_register(&mcp_bus_type);
-}
-
-static void __exit mcp_exit(void)
-{
- bus_unregister(&mcp_bus_type);
-}
-
-module_init(mcp_init);
-module_exit(mcp_exit);
-
-MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("Core multimedia communications port driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
deleted file mode 100644
index 228c4a2f4c1f..000000000000
--- a/drivers/mfd/mcp-sa11x0.c
+++ /dev/null
@@ -1,304 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/mfd/mcp-sa11x0.c
- *
- * Copyright (C) 2001-2005 Russell King
- *
- * SA11x0 MCP (Multimedia Communications Port) driver.
- *
- * MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
- */
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/pm.h>
-#include <linux/mfd/mcp.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <linux/platform_data/mfd-mcp-sa11x0.h>
-
-#define DRIVER_NAME "sa11x0-mcp"
-
-struct mcp_sa11x0 {
- void __iomem *base0;
- void __iomem *base1;
- u32 mccr0;
- u32 mccr1;
-};
-
-/* Register offsets */
-#define MCCR0(m) ((m)->base0 + 0x00)
-#define MCDR0(m) ((m)->base0 + 0x08)
-#define MCDR1(m) ((m)->base0 + 0x0c)
-#define MCDR2(m) ((m)->base0 + 0x10)
-#define MCSR(m) ((m)->base0 + 0x18)
-#define MCCR1(m) ((m)->base1 + 0x00)
-
-#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
-
-static void
-mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
-{
- struct mcp_sa11x0 *m = priv(mcp);
-
- divisor /= 32;
-
- m->mccr0 &= ~0x00007f00;
- m->mccr0 |= divisor << 8;
- writel_relaxed(m->mccr0, MCCR0(m));
-}
-
-static void
-mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
-{
- struct mcp_sa11x0 *m = priv(mcp);
-
- divisor /= 32;
-
- m->mccr0 &= ~0x0000007f;
- m->mccr0 |= divisor;
- writel_relaxed(m->mccr0, MCCR0(m));
-}
-
-/*
- * Write data to the device. The bit should be set after 3 subframe
- * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
- * We really should try doing something more productive while we
- * wait.
- */
-static void
-mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-{
- struct mcp_sa11x0 *m = priv(mcp);
- int ret = -ETIME;
- int i;
-
- writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m));
-
- for (i = 0; i < 2; i++) {
- udelay(mcp->rw_timeout);
- if (readl_relaxed(MCSR(m)) & MCSR_CWC) {
- ret = 0;
- break;
- }
- }
-
- if (ret < 0)
- printk(KERN_WARNING "mcp: write timed out\n");
-}
-
-/*
- * Read data from the device. The bit should be set after 3 subframe
- * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
- * We really should try doing something more productive while we
- * wait.
- */
-static unsigned int
-mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
-{
- struct mcp_sa11x0 *m = priv(mcp);
- int ret = -ETIME;
- int i;
-
- writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m));
-
- for (i = 0; i < 2; i++) {
- udelay(mcp->rw_timeout);
- if (readl_relaxed(MCSR(m)) & MCSR_CRC) {
- ret = readl_relaxed(MCDR2(m)) & 0xffff;
- break;
- }
- }
-
- if (ret < 0)
- printk(KERN_WARNING "mcp: read timed out\n");
-
- return ret;
-}
-
-static void mcp_sa11x0_enable(struct mcp *mcp)
-{
- struct mcp_sa11x0 *m = priv(mcp);
-
- writel(-1, MCSR(m));
- m->mccr0 |= MCCR0_MCE;
- writel_relaxed(m->mccr0, MCCR0(m));
-}
-
-static void mcp_sa11x0_disable(struct mcp *mcp)
-{
- struct mcp_sa11x0 *m = priv(mcp);
-
- m->mccr0 &= ~MCCR0_MCE;
- writel_relaxed(m->mccr0, MCCR0(m));
-}
-
-/*
- * Our methods.
- */
-static struct mcp_ops mcp_sa11x0 = {
- .set_telecom_divisor = mcp_sa11x0_set_telecom_divisor,
- .set_audio_divisor = mcp_sa11x0_set_audio_divisor,
- .reg_write = mcp_sa11x0_write,
- .reg_read = mcp_sa11x0_read,
- .enable = mcp_sa11x0_enable,
- .disable = mcp_sa11x0_disable,
-};
-
-static int mcp_sa11x0_probe(struct platform_device *dev)
-{
- struct mcp_plat_data *data = dev_get_platdata(&dev->dev);
- struct resource *mem0, *mem1;
- struct mcp_sa11x0 *m;
- struct mcp *mcp;
- int ret;
-
- if (!data)
- return -ENODEV;
-
- mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
- mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
- if (!mem0 || !mem1)
- return -ENXIO;
-
- if (!request_mem_region(mem0->start, resource_size(mem0),
- DRIVER_NAME)) {
- ret = -EBUSY;
- goto err_mem0;
- }
-
- if (!request_mem_region(mem1->start, resource_size(mem1),
- DRIVER_NAME)) {
- ret = -EBUSY;
- goto err_mem1;
- }
-
- mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0));
- if (!mcp) {
- ret = -ENOMEM;
- goto err_alloc;
- }
-
- mcp->owner = THIS_MODULE;
- mcp->ops = &mcp_sa11x0;
- mcp->sclk_rate = data->sclk_rate;
-
- m = priv(mcp);
- m->mccr0 = data->mccr0 | 0x7f7f;
- m->mccr1 = data->mccr1;
-
- m->base0 = ioremap(mem0->start, resource_size(mem0));
- m->base1 = ioremap(mem1->start, resource_size(mem1));
- if (!m->base0 || !m->base1) {
- ret = -ENOMEM;
- goto err_ioremap;
- }
-
- platform_set_drvdata(dev, mcp);
-
- /*
- * Initialise device. Note that we initially
- * set the sampling rate to minimum.
- */
- writel_relaxed(-1, MCSR(m));
- writel_relaxed(m->mccr1, MCCR1(m));
- writel_relaxed(m->mccr0, MCCR0(m));
-
- /*
- * Calculate the read/write timeout (us) from the bit clock
- * rate. This is the period for 3 64-bit frames. Always
- * round this time up.
- */
- mcp->rw_timeout = DIV_ROUND_UP(64 * 3 * 1000000, mcp->sclk_rate);
-
- ret = mcp_host_add(mcp, data->codec_pdata);
- if (ret == 0)
- return 0;
-
- err_ioremap:
- iounmap(m->base1);
- iounmap(m->base0);
- mcp_host_free(mcp);
- err_alloc:
- release_mem_region(mem1->start, resource_size(mem1));
- err_mem1:
- release_mem_region(mem0->start, resource_size(mem0));
- err_mem0:
- return ret;
-}
-
-static void mcp_sa11x0_remove(struct platform_device *dev)
-{
- struct mcp *mcp = platform_get_drvdata(dev);
- struct mcp_sa11x0 *m = priv(mcp);
- struct resource *mem0, *mem1;
-
- if (m->mccr0 & MCCR0_MCE)
- dev_warn(&dev->dev,
- "device left active (missing disable call?)\n");
-
- mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
- mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
-
- mcp_host_del(mcp);
- iounmap(m->base1);
- iounmap(m->base0);
- mcp_host_free(mcp);
- release_mem_region(mem1->start, resource_size(mem1));
- release_mem_region(mem0->start, resource_size(mem0));
-}
-
-static int mcp_sa11x0_suspend(struct device *dev)
-{
- struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
-
- if (m->mccr0 & MCCR0_MCE)
- dev_warn(dev, "device left active (missing disable call?)\n");
-
- writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m));
-
- return 0;
-}
-
-static int mcp_sa11x0_resume(struct device *dev)
-{
- struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
-
- writel_relaxed(m->mccr1, MCCR1(m));
- writel_relaxed(m->mccr0, MCCR0(m));
-
- return 0;
-}
-
-static const struct dev_pm_ops mcp_sa11x0_pm_ops = {
- .suspend = mcp_sa11x0_suspend,
- .freeze = mcp_sa11x0_suspend,
- .poweroff = mcp_sa11x0_suspend,
- .resume_noirq = mcp_sa11x0_resume,
- .thaw_noirq = mcp_sa11x0_resume,
- .restore_noirq = mcp_sa11x0_resume,
-};
-
-static struct platform_driver mcp_sa11x0_driver = {
- .probe = mcp_sa11x0_probe,
- .remove = mcp_sa11x0_remove,
- .driver = {
- .name = DRIVER_NAME,
- .pm = pm_sleep_ptr(&mcp_sa11x0_pm_ops),
- },
-};
-
-/*
- * This needs re-working
- */
-module_platform_driver(mcp_sa11x0_driver);
-
-MODULE_ALIAS("platform:" DRIVER_NAME);
-MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c
deleted file mode 100644
index 698f60aa9756..000000000000
--- a/drivers/mfd/ucb1x00-assabet.c
+++ /dev/null
@@ -1,175 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/mfd/ucb1x00-assabet.c
- *
- * Copyright (C) 2001-2003 Russell King, All Rights Reserved.
- *
- * We handle the machine-specific bits of the UCB1x00 driver here.
- */
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/fs.h>
-#include <linux/gpio/machine.h>
-#include <linux/gpio/property.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/proc_fs.h>
-#include <linux/property.h>
-#include <linux/slab.h>
-#include <linux/mfd/ucb1x00.h>
-
-#define UCB1X00_ATTR(name,input)\
-static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
- char *buf) \
-{ \
- struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
- int val; \
- ucb1x00_adc_enable(ucb); \
- val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \
- ucb1x00_adc_disable(ucb); \
- return sprintf(buf, "%d\n", val); \
-} \
-static DEVICE_ATTR_RO(name)
-
-UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1);
-UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0);
-UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
-
-static const struct property_entry ucb1x00_gpio_keys_props[] = {
- PROPERTY_ENTRY_STRING("label", "ucb1x00"),
- PROPERTY_ENTRY_U32("poll-interval", 50),
- { }
-};
-
-#define UCB1X00_BTN_PROPS(_idx) \
-struct property_entry ucb1x00_btn##_idx##_props[] = { \
- PROPERTY_ENTRY_U32("linux,code", BTN_0 + (_idx)), \
- PROPERTY_ENTRY_GPIO("gpios", &ucb1x00_gpiochip_node, \
- _idx, GPIO_ACTIVE_HIGH), \
- PROPERTY_ENTRY_STRING("label", "btn" #_idx), \
- PROPERTY_ENTRY_BOOL("linux,can-disable"), \
- { } \
-}
-
-static const UCB1X00_BTN_PROPS(0);
-static const UCB1X00_BTN_PROPS(1);
-static const UCB1X00_BTN_PROPS(2);
-static const UCB1X00_BTN_PROPS(3);
-static const UCB1X00_BTN_PROPS(4);
-static const UCB1X00_BTN_PROPS(5);
-
-static const struct property_entry * const ucb1x00_btn_props[] = {
- ucb1x00_btn0_props,
- ucb1x00_btn1_props,
- ucb1x00_btn2_props,
- ucb1x00_btn3_props,
- ucb1x00_btn4_props,
- ucb1x00_btn5_props,
-};
-
-struct ucb1x00_assabet_priv {
- struct platform_device *pdev;
- struct fwnode_handle *keys_node;
- struct fwnode_handle *button_nodes[ARRAY_SIZE(ucb1x00_btn_props)];
-};
-
-static void ucb1x00_assabet_remove_nodes(struct ucb1x00_assabet_priv *priv, int n)
-{
- while (--n >= 0)
- fwnode_remove_software_node(priv->button_nodes[n]);
-
- fwnode_remove_software_node(priv->keys_node);
-}
-
-static int ucb1x00_assabet_add(struct ucb1x00_dev *dev)
-{
- struct ucb1x00 *ucb = dev->ucb;
- struct platform_device_info pdevinfo = {
- .name = "gpio-keys",
- .id = PLATFORM_DEVID_NONE,
- .parent = &ucb->dev,
- };
- int ret;
- int i;
-
- struct ucb1x00_assabet_priv *priv;
-
- priv = kzalloc_obj(*priv);
- if (!priv)
- return -ENOMEM;
-
- priv->keys_node = fwnode_create_software_node(ucb1x00_gpio_keys_props, NULL);
- if (IS_ERR(priv->keys_node)) {
- ret = PTR_ERR(priv->keys_node);
- goto err_free_priv;
- }
-
- for (i = 0; i < ARRAY_SIZE(ucb1x00_btn_props); i++) {
- priv->button_nodes[i] = fwnode_create_software_node(ucb1x00_btn_props[i],
- priv->keys_node);
- if (IS_ERR(priv->button_nodes[i])) {
- ret = PTR_ERR(priv->button_nodes[i]);
- goto err_free_buttons;
- }
- }
-
- pdevinfo.fwnode = priv->keys_node;
-
- priv->pdev = platform_device_register_full(&pdevinfo);
- ret = PTR_ERR_OR_ZERO(priv->pdev);
- if (ret)
- goto err_free_buttons;
-
- device_create_file(&ucb->dev, &dev_attr_vbatt);
- device_create_file(&ucb->dev, &dev_attr_vcharger);
- device_create_file(&ucb->dev, &dev_attr_batt_temp);
-
- dev->priv = priv;
- return 0;
-
-err_free_buttons:
- ucb1x00_assabet_remove_nodes(priv, i);
-err_free_priv:
- kfree(priv);
- return ret;
-}
-
-static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev)
-{
- struct ucb1x00_assabet_priv *priv = dev->priv;
-
- if (!IS_ERR(priv->pdev))
- platform_device_unregister(priv->pdev);
-
- ucb1x00_assabet_remove_nodes(priv, ARRAY_SIZE(priv->button_nodes));
-
- device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp);
- device_remove_file(&dev->ucb->dev, &dev_attr_vcharger);
- device_remove_file(&dev->ucb->dev, &dev_attr_vbatt);
-
- kfree(priv);
-}
-
-static struct ucb1x00_driver ucb1x00_assabet_driver = {
- .add = ucb1x00_assabet_add,
- .remove = ucb1x00_assabet_remove,
-};
-
-static int __init ucb1x00_assabet_init(void)
-{
- return ucb1x00_register_driver(&ucb1x00_assabet_driver);
-}
-
-static void __exit ucb1x00_assabet_exit(void)
-{
- ucb1x00_unregister_driver(&ucb1x00_assabet_driver);
-}
-
-module_init(ucb1x00_assabet_init);
-module_exit(ucb1x00_assabet_exit);
-
-MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
deleted file mode 100644
index 90edf0352d05..000000000000
--- a/drivers/mfd/ucb1x00-core.c
+++ /dev/null
@@ -1,795 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/mfd/ucb1x00-core.c
- *
- * Copyright (C) 2001 Russell King, All Rights Reserved.
- *
- * The UCB1x00 core driver provides basic services for handling IO,
- * the ADC, interrupts, and accessing registers. It is designed
- * such that everything goes through this layer, thereby providing
- * a consistent locking methodology, as well as allowing the drivers
- * to be used on other non-MCP-enabled hardware platforms.
- *
- * Note that all locks are private to this file. Nothing else may
- * touch them.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/device.h>
-#include <linux/mutex.h>
-#include <linux/mfd/ucb1x00.h>
-#include <linux/pm.h>
-#include <linux/property.h>
-#include <linux/gpio/driver.h>
-
-static DEFINE_MUTEX(ucb1x00_mutex);
-static LIST_HEAD(ucb1x00_drivers);
-static LIST_HEAD(ucb1x00_devices);
-
-/**
- * ucb1x00_io_set_dir - set IO direction
- * @ucb: UCB1x00 structure describing chip
- * @in: bitfield of IO pins to be set as inputs
- * @out: bitfield of IO pins to be set as outputs
- *
- * Set the IO direction of the ten general purpose IO pins on
- * the UCB1x00 chip. The @in bitfield has priority over the
- * @out bitfield, in that if you specify a pin as both input
- * and output, it will end up as an input.
- *
- * ucb1x00_enable must have been called to enable the comms
- * before using this function.
- *
- * This function takes a spinlock, disabling interrupts.
- */
-void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ucb->io_lock, flags);
- ucb->io_dir |= out;
- ucb->io_dir &= ~in;
-
- ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
- spin_unlock_irqrestore(&ucb->io_lock, flags);
-}
-
-/**
- * ucb1x00_io_write - set or clear IO outputs
- * @ucb: UCB1x00 structure describing chip
- * @set: bitfield of IO pins to set to logic '1'
- * @clear: bitfield of IO pins to set to logic '0'
- *
- * Set the IO output state of the specified IO pins. The value
- * is retained if the pins are subsequently configured as inputs.
- * The @clear bitfield has priority over the @set bitfield -
- * outputs will be cleared.
- *
- * ucb1x00_enable must have been called to enable the comms
- * before using this function.
- *
- * This function takes a spinlock, disabling interrupts.
- */
-void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ucb->io_lock, flags);
- ucb->io_out |= set;
- ucb->io_out &= ~clear;
-
- ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
- spin_unlock_irqrestore(&ucb->io_lock, flags);
-}
-
-/**
- * ucb1x00_io_read - read the current state of the IO pins
- * @ucb: UCB1x00 structure describing chip
- *
- * Return a bitfield describing the logic state of the ten
- * general purpose IO pins.
- *
- * ucb1x00_enable must have been called to enable the comms
- * before using this function.
- *
- * This function does not take any mutexes or spinlocks.
- */
-unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
-{
- return ucb1x00_reg_read(ucb, UCB_IO_DATA);
-}
-
-static int ucb1x00_gpio_set(struct gpio_chip *chip, unsigned int offset,
- int value)
-{
- struct ucb1x00 *ucb = gpiochip_get_data(chip);
- unsigned long flags;
-
- spin_lock_irqsave(&ucb->io_lock, flags);
- if (value)
- ucb->io_out |= 1 << offset;
- else
- ucb->io_out &= ~(1 << offset);
-
- ucb1x00_enable(ucb);
- ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
- ucb1x00_disable(ucb);
- spin_unlock_irqrestore(&ucb->io_lock, flags);
-
- return 0;
-}
-
-static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct ucb1x00 *ucb = gpiochip_get_data(chip);
- unsigned val;
-
- ucb1x00_enable(ucb);
- val = ucb1x00_reg_read(ucb, UCB_IO_DATA);
- ucb1x00_disable(ucb);
-
- return !!(val & (1 << offset));
-}
-
-static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- struct ucb1x00 *ucb = gpiochip_get_data(chip);
- unsigned long flags;
-
- spin_lock_irqsave(&ucb->io_lock, flags);
- ucb->io_dir &= ~(1 << offset);
- ucb1x00_enable(ucb);
- ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
- ucb1x00_disable(ucb);
- spin_unlock_irqrestore(&ucb->io_lock, flags);
-
- return 0;
-}
-
-static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
- , int value)
-{
- struct ucb1x00 *ucb = gpiochip_get_data(chip);
- unsigned long flags;
- unsigned old, mask = 1 << offset;
-
- spin_lock_irqsave(&ucb->io_lock, flags);
- old = ucb->io_out;
- if (value)
- ucb->io_out |= mask;
- else
- ucb->io_out &= ~mask;
-
- ucb1x00_enable(ucb);
- if (old != ucb->io_out)
- ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
-
- if (!(ucb->io_dir & mask)) {
- ucb->io_dir |= mask;
- ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
- }
- ucb1x00_disable(ucb);
- spin_unlock_irqrestore(&ucb->io_lock, flags);
-
- return 0;
-}
-
-static int ucb1x00_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct ucb1x00 *ucb = gpiochip_get_data(chip);
-
- return ucb->irq_base > 0 ? ucb->irq_base + offset : -ENXIO;
-}
-
-/*
- * UCB1300 data sheet says we must:
- * 1. enable ADC => 5us (including reference startup time)
- * 2. select input => 51*tsibclk => 4.3us
- * 3. start conversion => 102*tsibclk => 8.5us
- * (tsibclk = 1/11981000)
- * Period between SIB 128-bit frames = 10.7us
- */
-
-/**
- * ucb1x00_adc_enable - enable the ADC converter
- * @ucb: UCB1x00 structure describing chip
- *
- * Enable the ucb1x00 and ADC converter on the UCB1x00 for use.
- * Any code wishing to use the ADC converter must call this
- * function prior to using it.
- *
- * This function takes the ADC mutex to prevent two or more
- * concurrent uses, and therefore may sleep. As a result, it
- * can only be called from process context, not interrupt
- * context.
- *
- * You should release the ADC as soon as possible using
- * ucb1x00_adc_disable.
- */
-void ucb1x00_adc_enable(struct ucb1x00 *ucb)
-{
- mutex_lock(&ucb->adc_mutex);
-
- ucb->adc_cr |= UCB_ADC_ENA;
-
- ucb1x00_enable(ucb);
- ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
-}
-
-/**
- * ucb1x00_adc_read - read the specified ADC channel
- * @ucb: UCB1x00 structure describing chip
- * @adc_channel: ADC channel mask
- * @sync: wait for syncronisation pulse.
- *
- * Start an ADC conversion and wait for the result. Note that
- * synchronised ADC conversions (via the ADCSYNC pin) must wait
- * until the trigger is asserted and the conversion is finished.
- *
- * This function currently spins waiting for the conversion to
- * complete (2 frames max without sync).
- *
- * If called for a synchronised ADC conversion, it may sleep
- * with the ADC mutex held.
- */
-unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
-{
- unsigned int val;
-
- if (sync)
- adc_channel |= UCB_ADC_SYNC_ENA;
-
- ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel);
- ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START);
-
- for (;;) {
- val = ucb1x00_reg_read(ucb, UCB_ADC_DATA);
- if (val & UCB_ADC_DAT_VAL)
- break;
- /* yield to other processes */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- return UCB_ADC_DAT(val);
-}
-
-/**
- * ucb1x00_adc_disable - disable the ADC converter
- * @ucb: UCB1x00 structure describing chip
- *
- * Disable the ADC converter and release the ADC mutex.
- */
-void ucb1x00_adc_disable(struct ucb1x00 *ucb)
-{
- ucb->adc_cr &= ~UCB_ADC_ENA;
- ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
- ucb1x00_disable(ucb);
-
- mutex_unlock(&ucb->adc_mutex);
-}
-
-/*
- * UCB1x00 Interrupt handling.
- *
- * The UCB1x00 can generate interrupts when the SIBCLK is stopped.
- * Since we need to read an internal register, we must re-enable
- * SIBCLK to talk to the chip. We leave the clock running until
- * we have finished processing all interrupts from the chip.
- */
-static void ucb1x00_irq(struct irq_desc *desc)
-{
- struct ucb1x00 *ucb = irq_desc_get_handler_data(desc);
- unsigned int isr, i;
-
- ucb1x00_enable(ucb);
- isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-
- for (i = 0; i < 16 && isr; i++, isr >>= 1)
- if (isr & 1)
- generic_handle_irq(ucb->irq_base + i);
- ucb1x00_disable(ucb);
-}
-
-static void ucb1x00_irq_update(struct ucb1x00 *ucb, unsigned mask)
-{
- ucb1x00_enable(ucb);
- if (ucb->irq_ris_enbl & mask)
- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
- ucb->irq_mask);
- if (ucb->irq_fal_enbl & mask)
- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
- ucb->irq_mask);
- ucb1x00_disable(ucb);
-}
-
-static void ucb1x00_irq_noop(struct irq_data *data)
-{
-}
-
-static void ucb1x00_irq_mask(struct irq_data *data)
-{
- struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
- unsigned mask = 1 << (data->irq - ucb->irq_base);
-
- raw_spin_lock(&ucb->irq_lock);
- ucb->irq_mask &= ~mask;
- ucb1x00_irq_update(ucb, mask);
- raw_spin_unlock(&ucb->irq_lock);
-}
-
-static void ucb1x00_irq_unmask(struct irq_data *data)
-{
- struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
- unsigned mask = 1 << (data->irq - ucb->irq_base);
-
- raw_spin_lock(&ucb->irq_lock);
- ucb->irq_mask |= mask;
- ucb1x00_irq_update(ucb, mask);
- raw_spin_unlock(&ucb->irq_lock);
-}
-
-static int ucb1x00_irq_set_type(struct irq_data *data, unsigned int type)
-{
- struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
- unsigned mask = 1 << (data->irq - ucb->irq_base);
-
- raw_spin_lock(&ucb->irq_lock);
- if (type & IRQ_TYPE_EDGE_RISING)
- ucb->irq_ris_enbl |= mask;
- else
- ucb->irq_ris_enbl &= ~mask;
-
- if (type & IRQ_TYPE_EDGE_FALLING)
- ucb->irq_fal_enbl |= mask;
- else
- ucb->irq_fal_enbl &= ~mask;
- if (ucb->irq_mask & mask) {
- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
- ucb->irq_mask);
- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
- ucb->irq_mask);
- }
- raw_spin_unlock(&ucb->irq_lock);
-
- return 0;
-}
-
-static int ucb1x00_irq_set_wake(struct irq_data *data, unsigned int on)
-{
- struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
- struct ucb1x00_plat_data *pdata = ucb->mcp->attached_device.platform_data;
- unsigned mask = 1 << (data->irq - ucb->irq_base);
-
- if (!pdata || !pdata->can_wakeup)
- return -EINVAL;
-
- raw_spin_lock(&ucb->irq_lock);
- if (on)
- ucb->irq_wake |= mask;
- else
- ucb->irq_wake &= ~mask;
- raw_spin_unlock(&ucb->irq_lock);
-
- return 0;
-}
-
-static struct irq_chip ucb1x00_irqchip = {
- .name = "ucb1x00",
- .irq_ack = ucb1x00_irq_noop,
- .irq_mask = ucb1x00_irq_mask,
- .irq_unmask = ucb1x00_irq_unmask,
- .irq_set_type = ucb1x00_irq_set_type,
- .irq_set_wake = ucb1x00_irq_set_wake,
-};
-
-static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
-{
- struct ucb1x00_dev *dev;
- int ret;
-
- dev = kmalloc_obj(struct ucb1x00_dev);
- if (!dev)
- return -ENOMEM;
-
- dev->ucb = ucb;
- dev->drv = drv;
-
- ret = drv->add(dev);
- if (ret) {
- kfree(dev);
- return ret;
- }
-
- list_add_tail(&dev->dev_node, &ucb->devs);
- list_add_tail(&dev->drv_node, &drv->devs);
-
- return ret;
-}
-
-static void ucb1x00_remove_dev(struct ucb1x00_dev *dev)
-{
- dev->drv->remove(dev);
- list_del(&dev->dev_node);
- list_del(&dev->drv_node);
- kfree(dev);
-}
-
-/*
- * Try to probe our interrupt, rather than relying on lots of
- * hard-coded machine dependencies. For reference, the expected
- * IRQ mappings are:
- *
- * Machine Default IRQ
- * adsbitsy IRQ_GPCIN4
- * cerf IRQ_GPIO_UCB1200_IRQ
- * flexanet IRQ_GPIO_GUI
- * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ
- * graphicsclient ADS_EXT_IRQ(8)
- * graphicsmaster ADS_EXT_IRQ(8)
- * lart LART_IRQ_UCB1200
- * omnimeter IRQ_GPIO23
- * pfs168 IRQ_GPIO_UCB1300_IRQ
- * simpad IRQ_GPIO_UCB1300_IRQ
- * shannon SHANNON_IRQ_GPIO_IRQ_CODEC
- * yopy IRQ_GPIO_UCB1200_IRQ
- */
-static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
-{
- unsigned long mask;
-
- mask = probe_irq_on();
-
- /*
- * Enable the ADC interrupt.
- */
- ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
- ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-
- /*
- * Cause an ADC interrupt.
- */
- ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
- ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
-
- /*
- * Wait for the conversion to complete.
- */
- while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0);
- ucb1x00_reg_write(ucb, UCB_ADC_CR, 0);
-
- /*
- * Disable and clear interrupt.
- */
- ucb1x00_reg_write(ucb, UCB_IE_RIS, 0);
- ucb1x00_reg_write(ucb, UCB_IE_FAL, 0);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-
- /*
- * Read triggered interrupt.
- */
- return probe_irq_off(mask);
-}
-
-static void ucb1x00_release(struct device *dev)
-{
- struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
- kfree(ucb);
-}
-
-static struct class ucb1x00_class = {
- .name = "ucb1x00",
- .dev_release = ucb1x00_release,
-};
-
-const struct software_node ucb1x00_gpiochip_node = {
- .name = "ucb1x00-gpio",
-};
-EXPORT_SYMBOL_GPL(ucb1x00_gpiochip_node);
-
-static int ucb1x00_probe(struct mcp *mcp)
-{
- struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
- struct ucb1x00_driver *drv;
- struct ucb1x00 *ucb;
- unsigned id, i, irq_base;
- int ret = -ENODEV;
-
- /* Tell the platform to deassert the UCB1x00 reset */
- if (pdata && pdata->reset)
- pdata->reset(UCB_RST_PROBE);
-
- mcp_enable(mcp);
- id = mcp_reg_read(mcp, UCB_ID);
- mcp_disable(mcp);
-
- if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
- printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
- goto out;
- }
-
- ucb = kzalloc_obj(struct ucb1x00);
- ret = -ENOMEM;
- if (!ucb)
- goto out;
-
- device_initialize(&ucb->dev);
- ucb->dev.class = &ucb1x00_class;
- ucb->dev.parent = &mcp->attached_device;
- dev_set_name(&ucb->dev, "ucb1x00");
-
- raw_spin_lock_init(&ucb->irq_lock);
- spin_lock_init(&ucb->io_lock);
- mutex_init(&ucb->adc_mutex);
-
- ucb->id = id;
- ucb->mcp = mcp;
-
- ret = device_add_software_node(&ucb->dev, &ucb1x00_gpiochip_node);
- if (ret)
- goto err_swnode_add;
-
- ret = device_add(&ucb->dev);
- if (ret)
- goto err_dev_add;
-
- ucb1x00_enable(ucb);
- ucb->irq = ucb1x00_detect_irq(ucb);
- ucb1x00_disable(ucb);
- if (!ucb->irq) {
- dev_err(&ucb->dev, "IRQ probe failed\n");
- ret = -ENODEV;
- goto err_no_irq;
- }
-
- ucb->gpio.base = -1;
- irq_base = pdata ? pdata->irq_base : 0;
- ucb->irq_base = irq_alloc_descs(-1, irq_base, 16, -1);
- if (ucb->irq_base < 0) {
- dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n",
- ucb->irq_base);
- ret = ucb->irq_base;
- goto err_irq_alloc;
- }
-
- for (i = 0; i < 16; i++) {
- unsigned irq = ucb->irq_base + i;
-
- irq_set_chip_and_handler(irq, &ucb1x00_irqchip, handle_edge_irq);
- irq_set_chip_data(irq, ucb);
- irq_clear_status_flags(irq, IRQ_NOREQUEST);
- }
-
- irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING);
- irq_set_chained_handler_and_data(ucb->irq, ucb1x00_irq, ucb);
-
- if (pdata && pdata->gpio_base) {
- ucb->gpio.label = dev_name(&ucb->dev);
- ucb->gpio.parent = &ucb->dev;
- ucb->gpio.owner = THIS_MODULE;
- ucb->gpio.base = pdata->gpio_base;
- ucb->gpio.ngpio = 10;
- ucb->gpio.set = ucb1x00_gpio_set;
- ucb->gpio.get = ucb1x00_gpio_get;
- ucb->gpio.direction_input = ucb1x00_gpio_direction_input;
- ucb->gpio.direction_output = ucb1x00_gpio_direction_output;
- ucb->gpio.to_irq = ucb1x00_to_irq;
- ret = gpiochip_add_data(&ucb->gpio, ucb);
- if (ret)
- goto err_gpio_add;
- } else
- dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
-
- mcp_set_drvdata(mcp, ucb);
-
- if (pdata)
- device_set_wakeup_capable(&ucb->dev, pdata->can_wakeup);
-
- INIT_LIST_HEAD(&ucb->devs);
- mutex_lock(&ucb1x00_mutex);
- list_add_tail(&ucb->node, &ucb1x00_devices);
- list_for_each_entry(drv, &ucb1x00_drivers, node) {
- ucb1x00_add_dev(ucb, drv);
- }
- mutex_unlock(&ucb1x00_mutex);
-
- return ret;
-
- err_gpio_add:
- irq_set_chained_handler(ucb->irq, NULL);
- err_irq_alloc:
- if (ucb->irq_base > 0)
- irq_free_descs(ucb->irq_base, 16);
- err_no_irq:
- device_del(&ucb->dev);
- err_dev_add:
- device_remove_software_node(&ucb->dev);
- err_swnode_add:
- put_device(&ucb->dev);
- out:
- if (pdata && pdata->reset)
- pdata->reset(UCB_RST_PROBE_FAIL);
- return ret;
-}
-
-static void ucb1x00_remove(struct mcp *mcp)
-{
- struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
- struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
- struct list_head *l, *n;
-
- mutex_lock(&ucb1x00_mutex);
- list_del(&ucb->node);
- list_for_each_safe(l, n, &ucb->devs) {
- struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node);
- ucb1x00_remove_dev(dev);
- }
- mutex_unlock(&ucb1x00_mutex);
-
- if (ucb->gpio.base != -1)
- gpiochip_remove(&ucb->gpio);
-
- irq_set_chained_handler(ucb->irq, NULL);
- irq_free_descs(ucb->irq_base, 16);
- device_del(&ucb->dev);
- device_remove_software_node(&ucb->dev);
- put_device(&ucb->dev);
-
- if (pdata && pdata->reset)
- pdata->reset(UCB_RST_REMOVE);
-}
-
-int ucb1x00_register_driver(struct ucb1x00_driver *drv)
-{
- struct ucb1x00 *ucb;
-
- INIT_LIST_HEAD(&drv->devs);
- mutex_lock(&ucb1x00_mutex);
- list_add_tail(&drv->node, &ucb1x00_drivers);
- list_for_each_entry(ucb, &ucb1x00_devices, node) {
- ucb1x00_add_dev(ucb, drv);
- }
- mutex_unlock(&ucb1x00_mutex);
- return 0;
-}
-
-void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
-{
- struct list_head *n, *l;
-
- mutex_lock(&ucb1x00_mutex);
- list_del(&drv->node);
- list_for_each_safe(l, n, &drv->devs) {
- struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node);
- ucb1x00_remove_dev(dev);
- }
- mutex_unlock(&ucb1x00_mutex);
-}
-
-static int ucb1x00_suspend(struct device *dev)
-{
- struct ucb1x00_plat_data *pdata = dev_get_platdata(dev);
- struct ucb1x00 *ucb = dev_get_drvdata(dev);
- struct ucb1x00_dev *udev;
-
- mutex_lock(&ucb1x00_mutex);
- list_for_each_entry(udev, &ucb->devs, dev_node) {
- if (udev->drv->suspend)
- udev->drv->suspend(udev);
- }
- mutex_unlock(&ucb1x00_mutex);
-
- if (ucb->irq_wake) {
- unsigned long flags;
-
- raw_spin_lock_irqsave(&ucb->irq_lock, flags);
- ucb1x00_enable(ucb);
- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
- ucb->irq_wake);
- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
- ucb->irq_wake);
- ucb1x00_disable(ucb);
- raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
-
- enable_irq_wake(ucb->irq);
- } else if (pdata && pdata->reset)
- pdata->reset(UCB_RST_SUSPEND);
-
- return 0;
-}
-
-static int ucb1x00_resume(struct device *dev)
-{
- struct ucb1x00_plat_data *pdata = dev_get_platdata(dev);
- struct ucb1x00 *ucb = dev_get_drvdata(dev);
- struct ucb1x00_dev *udev;
-
- if (!ucb->irq_wake && pdata && pdata->reset)
- pdata->reset(UCB_RST_RESUME);
-
- ucb1x00_enable(ucb);
- ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
- ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
-
- if (ucb->irq_wake) {
- unsigned long flags;
-
- raw_spin_lock_irqsave(&ucb->irq_lock, flags);
- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
- ucb->irq_mask);
- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
- ucb->irq_mask);
- raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
-
- disable_irq_wake(ucb->irq);
- }
- ucb1x00_disable(ucb);
-
- mutex_lock(&ucb1x00_mutex);
- list_for_each_entry(udev, &ucb->devs, dev_node) {
- if (udev->drv->resume)
- udev->drv->resume(udev);
- }
- mutex_unlock(&ucb1x00_mutex);
- return 0;
-}
-
-static DEFINE_SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops,
- ucb1x00_suspend, ucb1x00_resume);
-
-static struct mcp_driver ucb1x00_driver = {
- .drv = {
- .name = "ucb1x00",
- .owner = THIS_MODULE,
- .pm = pm_sleep_ptr(&ucb1x00_pm_ops),
- },
- .probe = ucb1x00_probe,
- .remove = ucb1x00_remove,
-};
-
-static int __init ucb1x00_init(void)
-{
- int ret = class_register(&ucb1x00_class);
- if (ret == 0) {
- ret = mcp_driver_register(&ucb1x00_driver);
- if (ret)
- class_unregister(&ucb1x00_class);
- }
- return ret;
-}
-
-static void __exit ucb1x00_exit(void)
-{
- mcp_driver_unregister(&ucb1x00_driver);
- class_unregister(&ucb1x00_class);
-}
-
-module_init(ucb1x00_init);
-module_exit(ucb1x00_exit);
-
-EXPORT_SYMBOL(ucb1x00_io_set_dir);
-EXPORT_SYMBOL(ucb1x00_io_write);
-EXPORT_SYMBOL(ucb1x00_io_read);
-
-EXPORT_SYMBOL(ucb1x00_adc_enable);
-EXPORT_SYMBOL(ucb1x00_adc_read);
-EXPORT_SYMBOL(ucb1x00_adc_disable);
-
-EXPORT_SYMBOL(ucb1x00_register_driver);
-EXPORT_SYMBOL(ucb1x00_unregister_driver);
-
-MODULE_ALIAS("mcp:ucb1x00");
-MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("UCB1x00 core driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
deleted file mode 100644
index 39fe187eea1f..000000000000
--- a/drivers/mfd/ucb1x00-ts.c
+++ /dev/null
@@ -1,445 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Touchscreen driver for UCB1x00-based touchscreens
- *
- * Copyright (C) 2001 Russell King, All Rights Reserved.
- * Copyright (C) 2005 Pavel Machek
- *
- * 21-Jan-2002 <jco@ict.es> :
- *
- * Added support for synchronous A/D mode. This mode is useful to
- * avoid noise induced in the touchpanel by the LCD, provided that
- * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
- * It is important to note that the signal connected to the ADCSYNC
- * pin should provide pulses even when the LCD is blanked, otherwise
- * a pen touch needed to unblank the LCD will never be read.
- */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/input.h>
-#include <linux/device.h>
-#include <linux/freezer.h>
-#include <linux/slab.h>
-#include <linux/kthread.h>
-#include <linux/mfd/ucb1x00.h>
-
-#include <mach/collie.h>
-#include <asm/mach-types.h>
-
-
-
-struct ucb1x00_ts {
- struct input_dev *idev;
- struct ucb1x00 *ucb;
-
- spinlock_t irq_lock;
- unsigned irq_disabled;
- wait_queue_head_t irq_wait;
- struct task_struct *rtask;
- u16 x_res;
- u16 y_res;
-
- unsigned int adcsync:1;
-};
-
-static int adcsync;
-
-static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
-{
- struct input_dev *idev = ts->idev;
-
- input_report_abs(idev, ABS_X, x);
- input_report_abs(idev, ABS_Y, y);
- input_report_abs(idev, ABS_PRESSURE, pressure);
- input_report_key(idev, BTN_TOUCH, 1);
- input_sync(idev);
-}
-
-static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
-{
- struct input_dev *idev = ts->idev;
-
- input_report_abs(idev, ABS_PRESSURE, 0);
- input_report_key(idev, BTN_TOUCH, 0);
- input_sync(idev);
-}
-
-/*
- * Switch to interrupt mode.
- */
-static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
-{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
- UCB_TS_CR_MODE_INT);
-}
-
-/*
- * Switch to pressure mode, and read pressure. We don't need to wait
- * here, since both plates are being driven.
- */
-static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
-{
- if (machine_is_collie()) {
- ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
- UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-
- udelay(55);
-
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
- } else {
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
- }
-}
-
-/*
- * Switch to X position mode and measure Y plate. We switch the plate
- * configuration in pressure mode, then switch to position mode. This
- * gives a faster response time. Even so, we need to wait about 55us
- * for things to stabilise.
- */
-static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
-{
- if (machine_is_collie())
- ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
- else {
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- }
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-
- udelay(55);
-
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
-}
-
-/*
- * Switch to Y position mode and measure X plate. We switch the plate
- * configuration in pressure mode, then switch to position mode. This
- * gives a faster response time. Even so, we need to wait about 55us
- * for things to stabilise.
- */
-static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
-{
- if (machine_is_collie())
- ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
- else {
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- }
-
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-
- udelay(55);
-
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
-}
-
-/*
- * Switch to X plate resistance mode. Set MX to ground, PX to
- * supply. Measure current.
- */
-static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
-{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
-}
-
-/*
- * Switch to Y plate resistance mode. Set MY to ground, PY to
- * supply. Measure current.
- */
-static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
-{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
-}
-
-static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
-{
- unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
-
- if (machine_is_collie())
- return (!(val & (UCB_TS_CR_TSPX_LOW)));
- else
- return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
-}
-
-/*
- * This is a RT kernel thread that handles the ADC accesses
- * (mainly so we can use semaphores in the UCB1200 core code
- * to serialise accesses to the ADC).
- */
-static int ucb1x00_thread(void *_ts)
-{
- struct ucb1x00_ts *ts = _ts;
- DECLARE_WAITQUEUE(wait, current);
- bool frozen, ignore = false;
- int valid = 0;
-
- set_freezable();
- add_wait_queue(&ts->irq_wait, &wait);
- while (!kthread_freezable_should_stop(&frozen)) {
- unsigned int x, y, p;
- signed long timeout;
-
- if (frozen)
- ignore = true;
-
- ucb1x00_adc_enable(ts->ucb);
-
- x = ucb1x00_ts_read_xpos(ts);
- y = ucb1x00_ts_read_ypos(ts);
- p = ucb1x00_ts_read_pressure(ts);
-
- /*
- * Switch back to interrupt mode.
- */
- ucb1x00_ts_mode_int(ts);
- ucb1x00_adc_disable(ts->ucb);
-
- msleep(10);
-
- ucb1x00_enable(ts->ucb);
-
-
- if (ucb1x00_ts_pen_down(ts)) {
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irq(&ts->irq_lock);
- if (ts->irq_disabled) {
- ts->irq_disabled = 0;
- enable_irq(ts->ucb->irq_base + UCB_IRQ_TSPX);
- }
- spin_unlock_irq(&ts->irq_lock);
- ucb1x00_disable(ts->ucb);
-
- /*
- * If we spat out a valid sample set last time,
- * spit out a "pen off" sample here.
- */
- if (valid) {
- ucb1x00_ts_event_release(ts);
- valid = 0;
- }
-
- timeout = MAX_SCHEDULE_TIMEOUT;
- } else {
- ucb1x00_disable(ts->ucb);
-
- /*
- * Filtering is policy. Policy belongs in user
- * space. We therefore leave it to user space
- * to do any filtering they please.
- */
- if (!ignore) {
- ucb1x00_ts_evt_add(ts, p, x, y);
- valid = 1;
- }
-
- set_current_state(TASK_INTERRUPTIBLE);
- timeout = HZ / 100;
- }
-
- schedule_timeout(timeout);
- }
-
- remove_wait_queue(&ts->irq_wait, &wait);
-
- ts->rtask = NULL;
- return 0;
-}
-
-/*
- * We only detect touch screen _touches_ with this interrupt
- * handler, and even then we just schedule our task.
- */
-static irqreturn_t ucb1x00_ts_irq(int irq, void *id)
-{
- struct ucb1x00_ts *ts = id;
-
- spin_lock(&ts->irq_lock);
- ts->irq_disabled = 1;
- disable_irq_nosync(ts->ucb->irq_base + UCB_IRQ_TSPX);
- spin_unlock(&ts->irq_lock);
- wake_up(&ts->irq_wait);
-
- return IRQ_HANDLED;
-}
-
-static int ucb1x00_ts_open(struct input_dev *idev)
-{
- struct ucb1x00_ts *ts = input_get_drvdata(idev);
- unsigned long flags = 0;
- int ret = 0;
-
- BUG_ON(ts->rtask);
-
- if (machine_is_collie())
- flags = IRQF_TRIGGER_RISING;
- else
- flags = IRQF_TRIGGER_FALLING;
-
- ts->irq_disabled = 0;
-
- init_waitqueue_head(&ts->irq_wait);
- ret = request_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ucb1x00_ts_irq,
- flags, "ucb1x00-ts", ts);
- if (ret < 0)
- goto out;
-
- /*
- * If we do this at all, we should allow the user to
- * measure and read the X and Y resistance at any time.
- */
- ucb1x00_adc_enable(ts->ucb);
- ts->x_res = ucb1x00_ts_read_xres(ts);
- ts->y_res = ucb1x00_ts_read_yres(ts);
- ucb1x00_adc_disable(ts->ucb);
-
- ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd");
- if (!IS_ERR(ts->rtask)) {
- ret = 0;
- } else {
- free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
- ts->rtask = NULL;
- ret = -EFAULT;
- }
-
- out:
- return ret;
-}
-
-/*
- * Release touchscreen resources. Disable IRQs.
- */
-static void ucb1x00_ts_close(struct input_dev *idev)
-{
- struct ucb1x00_ts *ts = input_get_drvdata(idev);
-
- if (ts->rtask)
- kthread_stop(ts->rtask);
-
- ucb1x00_enable(ts->ucb);
- free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
- ucb1x00_disable(ts->ucb);
-}
-
-
-/*
- * Initialisation.
- */
-static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
-{
- struct ucb1x00_ts *ts;
- struct input_dev *idev;
- int err;
-
- ts = kzalloc_obj(struct ucb1x00_ts);
- idev = input_allocate_device();
- if (!ts || !idev) {
- err = -ENOMEM;
- goto fail;
- }
-
- ts->ucb = dev->ucb;
- ts->idev = idev;
- ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
- spin_lock_init(&ts->irq_lock);
-
- idev->name = "Touchscreen panel";
- idev->id.product = ts->ucb->id;
- idev->open = ucb1x00_ts_open;
- idev->close = ucb1x00_ts_close;
- idev->dev.parent = &ts->ucb->dev;
-
- idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
- idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
- input_set_drvdata(idev, ts);
-
- ucb1x00_adc_enable(ts->ucb);
- ts->x_res = ucb1x00_ts_read_xres(ts);
- ts->y_res = ucb1x00_ts_read_yres(ts);
- ucb1x00_adc_disable(ts->ucb);
-
- input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0);
- input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0);
- input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0);
-
- err = input_register_device(idev);
- if (err)
- goto fail;
-
- dev->priv = ts;
-
- return 0;
-
- fail:
- input_free_device(idev);
- kfree(ts);
- return err;
-}
-
-static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
-{
- struct ucb1x00_ts *ts = dev->priv;
-
- input_unregister_device(ts->idev);
- kfree(ts);
-}
-
-static struct ucb1x00_driver ucb1x00_ts_driver = {
- .add = ucb1x00_ts_add,
- .remove = ucb1x00_ts_remove,
-};
-
-static int __init ucb1x00_ts_init(void)
-{
- return ucb1x00_register_driver(&ucb1x00_ts_driver);
-}
-
-static void __exit ucb1x00_ts_exit(void)
-{
- ucb1x00_unregister_driver(&ucb1x00_ts_driver);
-}
-
-module_param(adcsync, int, 0444);
-module_init(ucb1x00_ts_init);
-module_exit(ucb1x00_ts_exit);
-
-MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
-MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h
deleted file mode 100644
index fd5cafc77e8a..000000000000
--- a/include/linux/mfd/mcp.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * linux/drivers/mfd/mcp.h
- *
- * Copyright (C) 2001 Russell King, All Rights Reserved.
- */
-#ifndef MCP_H
-#define MCP_H
-
-#include <linux/device.h>
-
-struct mcp_ops;
-
-struct mcp {
- struct module *owner;
- struct mcp_ops *ops;
- spinlock_t lock;
- int use_count;
- unsigned int sclk_rate;
- unsigned int rw_timeout;
- struct device attached_device;
-};
-
-struct mcp_ops {
- void (*set_telecom_divisor)(struct mcp *, unsigned int);
- void (*set_audio_divisor)(struct mcp *, unsigned int);
- void (*reg_write)(struct mcp *, unsigned int, unsigned int);
- unsigned int (*reg_read)(struct mcp *, unsigned int);
- void (*enable)(struct mcp *);
- void (*disable)(struct mcp *);
-};
-
-void mcp_set_telecom_divisor(struct mcp *, unsigned int);
-void mcp_set_audio_divisor(struct mcp *, unsigned int);
-void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
-unsigned int mcp_reg_read(struct mcp *, unsigned int);
-void mcp_enable(struct mcp *);
-void mcp_disable(struct mcp *);
-#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
-
-struct mcp *mcp_host_alloc(struct device *, size_t);
-int mcp_host_add(struct mcp *, void *);
-void mcp_host_del(struct mcp *);
-void mcp_host_free(struct mcp *);
-
-struct mcp_driver {
- struct device_driver drv;
- int (*probe)(struct mcp *);
- void (*remove)(struct mcp *);
-};
-
-int mcp_driver_register(struct mcp_driver *);
-void mcp_driver_unregister(struct mcp_driver *);
-
-#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device)
-#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
-
-static inline void *mcp_priv(struct mcp *mcp)
-{
- return mcp + 1;
-}
-
-#endif
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h
deleted file mode 100644
index 66ecad4667c9..000000000000
--- a/include/linux/mfd/ucb1x00.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * linux/include/mfd/ucb1x00.h
- *
- * Copyright (C) 2001 Russell King, All Rights Reserved.
- */
-#ifndef UCB1200_H
-#define UCB1200_H
-
-#include <linux/device.h>
-#include <linux/mfd/mcp.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio/driver.h>
-#include <linux/mutex.h>
-
-#define UCB_IO_DATA 0x00
-#define UCB_IO_DIR 0x01
-
-#define UCB_IO_0 (1 << 0)
-#define UCB_IO_1 (1 << 1)
-#define UCB_IO_2 (1 << 2)
-#define UCB_IO_3 (1 << 3)
-#define UCB_IO_4 (1 << 4)
-#define UCB_IO_5 (1 << 5)
-#define UCB_IO_6 (1 << 6)
-#define UCB_IO_7 (1 << 7)
-#define UCB_IO_8 (1 << 8)
-#define UCB_IO_9 (1 << 9)
-
-#define UCB_IE_RIS 0x02
-#define UCB_IE_FAL 0x03
-#define UCB_IE_STATUS 0x04
-#define UCB_IE_CLEAR 0x04
-#define UCB_IE_ADC (1 << 11)
-#define UCB_IE_TSPX (1 << 12)
-#define UCB_IE_TSMX (1 << 13)
-#define UCB_IE_TCLIP (1 << 14)
-#define UCB_IE_ACLIP (1 << 15)
-
-#define UCB_IRQ_TSPX 12
-
-#define UCB_TC_A 0x05
-#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
-#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
-
-#define UCB_TC_B 0x06
-#define UCB_TC_B_VOICE_ENA (1 << 3)
-#define UCB_TC_B_CLIP (1 << 4)
-#define UCB_TC_B_ATT (1 << 6)
-#define UCB_TC_B_SIDE_ENA (1 << 11)
-#define UCB_TC_B_MUTE (1 << 13)
-#define UCB_TC_B_IN_ENA (1 << 14)
-#define UCB_TC_B_OUT_ENA (1 << 15)
-
-#define UCB_AC_A 0x07
-#define UCB_AC_B 0x08
-#define UCB_AC_B_LOOP (1 << 8)
-#define UCB_AC_B_MUTE (1 << 13)
-#define UCB_AC_B_IN_ENA (1 << 14)
-#define UCB_AC_B_OUT_ENA (1 << 15)
-
-#define UCB_TS_CR 0x09
-#define UCB_TS_CR_TSMX_POW (1 << 0)
-#define UCB_TS_CR_TSPX_POW (1 << 1)
-#define UCB_TS_CR_TSMY_POW (1 << 2)
-#define UCB_TS_CR_TSPY_POW (1 << 3)
-#define UCB_TS_CR_TSMX_GND (1 << 4)
-#define UCB_TS_CR_TSPX_GND (1 << 5)
-#define UCB_TS_CR_TSMY_GND (1 << 6)
-#define UCB_TS_CR_TSPY_GND (1 << 7)
-#define UCB_TS_CR_MODE_INT (0 << 8)
-#define UCB_TS_CR_MODE_PRES (1 << 8)
-#define UCB_TS_CR_MODE_POS (2 << 8)
-#define UCB_TS_CR_BIAS_ENA (1 << 11)
-#define UCB_TS_CR_TSPX_LOW (1 << 12)
-#define UCB_TS_CR_TSMX_LOW (1 << 13)
-
-#define UCB_ADC_CR 0x0a
-#define UCB_ADC_SYNC_ENA (1 << 0)
-#define UCB_ADC_VREFBYP_CON (1 << 1)
-#define UCB_ADC_INP_TSPX (0 << 2)
-#define UCB_ADC_INP_TSMX (1 << 2)
-#define UCB_ADC_INP_TSPY (2 << 2)
-#define UCB_ADC_INP_TSMY (3 << 2)
-#define UCB_ADC_INP_AD0 (4 << 2)
-#define UCB_ADC_INP_AD1 (5 << 2)
-#define UCB_ADC_INP_AD2 (6 << 2)
-#define UCB_ADC_INP_AD3 (7 << 2)
-#define UCB_ADC_EXT_REF (1 << 5)
-#define UCB_ADC_START (1 << 7)
-#define UCB_ADC_ENA (1 << 15)
-
-#define UCB_ADC_DATA 0x0b
-#define UCB_ADC_DAT_VAL (1 << 15)
-#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
-
-#define UCB_ID 0x0c
-#define UCB_ID_1200 0x1004
-#define UCB_ID_1300 0x1005
-#define UCB_ID_TC35143 0x9712
-
-#define UCB_MODE 0x0d
-#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
-#define UCB_MODE_AUD_OFF_CAN (1 << 13)
-
-struct software_node;
-extern const struct software_node ucb1x00_gpiochip_node;
-
-enum ucb1x00_reset {
- UCB_RST_PROBE,
- UCB_RST_RESUME,
- UCB_RST_SUSPEND,
- UCB_RST_REMOVE,
- UCB_RST_PROBE_FAIL,
-};
-
-struct ucb1x00_plat_data {
- void (*reset)(enum ucb1x00_reset);
- unsigned irq_base;
- int gpio_base;
- unsigned can_wakeup;
-};
-
-struct ucb1x00 {
- raw_spinlock_t irq_lock;
- struct mcp *mcp;
- unsigned int irq;
- int irq_base;
- struct mutex adc_mutex;
- spinlock_t io_lock;
- u16 id;
- u16 io_dir;
- u16 io_out;
- u16 adc_cr;
- u16 irq_fal_enbl;
- u16 irq_ris_enbl;
- u16 irq_mask;
- u16 irq_wake;
- struct device dev;
- struct list_head node;
- struct list_head devs;
- struct gpio_chip gpio;
-};
-
-struct ucb1x00_driver;
-
-struct ucb1x00_dev {
- struct list_head dev_node;
- struct list_head drv_node;
- struct ucb1x00 *ucb;
- struct ucb1x00_driver *drv;
- void *priv;
-};
-
-struct ucb1x00_driver {
- struct list_head node;
- struct list_head devs;
- int (*add)(struct ucb1x00_dev *dev);
- void (*remove)(struct ucb1x00_dev *dev);
- int (*suspend)(struct ucb1x00_dev *dev);
- int (*resume)(struct ucb1x00_dev *dev);
-};
-
-#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, dev)
-
-int ucb1x00_register_driver(struct ucb1x00_driver *);
-void ucb1x00_unregister_driver(struct ucb1x00_driver *);
-
-/**
- * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
- * @ucb: UCB1x00 structure describing chip
- *
- * Return the SIB clock rate in Hz.
- */
-static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
-{
- return mcp_get_sclk_rate(ucb->mcp);
-}
-
-/**
- * ucb1x00_enable - enable the UCB1x00 SIB clock
- * @ucb: UCB1x00 structure describing chip
- *
- * Enable the SIB clock. This can be called multiple times.
- */
-static inline void ucb1x00_enable(struct ucb1x00 *ucb)
-{
- mcp_enable(ucb->mcp);
-}
-
-/**
- * ucb1x00_disable - disable the UCB1x00 SIB clock
- * @ucb: UCB1x00 structure describing chip
- *
- * Disable the SIB clock. The SIB clock will only be disabled
- * when the number of ucb1x00_enable calls match the number of
- * ucb1x00_disable calls.
- */
-static inline void ucb1x00_disable(struct ucb1x00 *ucb)
-{
- mcp_disable(ucb->mcp);
-}
-
-/**
- * ucb1x00_reg_write - write a UCB1x00 register
- * @ucb: UCB1x00 structure describing chip
- * @reg: UCB1x00 4-bit register index to write
- * @val: UCB1x00 16-bit value to write
- *
- * Write the UCB1x00 register @reg with value @val. The SIB
- * clock must be running for this function to return.
- */
-static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
-{
- mcp_reg_write(ucb->mcp, reg, val);
-}
-
-/**
- * ucb1x00_reg_read - read a UCB1x00 register
- * @ucb: UCB1x00 structure describing chip
- * @reg: UCB1x00 4-bit register index to write
- *
- * Read the UCB1x00 register @reg and return its value. The SIB
- * clock must be running for this function to return.
- */
-static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
-{
- return mcp_reg_read(ucb->mcp, reg);
-}
-/**
- * ucb1x00_set_audio_divisor -
- * @ucb: UCB1x00 structure describing chip
- * @div: SIB clock divisor
- */
-static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
-{
- mcp_set_audio_divisor(ucb->mcp, div);
-}
-
-/**
- * ucb1x00_set_telecom_divisor -
- * @ucb: UCB1x00 structure describing chip
- * @div: SIB clock divisor
- */
-static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
-{
- mcp_set_telecom_divisor(ucb->mcp, div);
-}
-
-void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
-void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
-unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
-
-#define UCB_NOSYNC (0)
-#define UCB_SYNC (1)
-
-unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
-void ucb1x00_adc_enable(struct ucb1x00 *ucb);
-void ucb1x00_adc_disable(struct ucb1x00 *ucb);
-
-#endif
diff --git a/include/linux/platform_data/mfd-mcp-sa11x0.h b/include/linux/platform_data/mfd-mcp-sa11x0.h
deleted file mode 100644
index b589e61bbc2e..000000000000
--- a/include/linux/platform_data/mfd-mcp-sa11x0.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2005 Russell King.
- */
-#ifndef __MFD_MCP_SA11X0_H
-#define __MFD_MCP_SA11X0_H
-
-#include <linux/types.h>
-
-struct mcp_plat_data {
- u32 mccr0;
- u32 mccr1;
- unsigned int sclk_rate;
- void *codec_pdata;
-};
-
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* [PATCH 13/14] mfd: remove unused menelaus driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (8 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 12/14] mfd: remove unused mcp-sa11x0/ucb1x00 driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:51 ` Alexandre Belloni
2026-09-09 13:21 ` [PATCH 14/14] mfd: remove unused iPaq micro driver Arnd Bergmann
` (4 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
Menelaus was a companion chip for the omap24xx platform, which has
been remvoed from the kernel, so now the menelaus driver is unused
and can be removed.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/mfd/Kconfig | 10 -
drivers/mfd/Makefile | 1 -
drivers/mfd/menelaus.c | 1251 ----------------------------------
drivers/rtc/Kconfig | 9 -
include/linux/mfd/menelaus.h | 41 --
5 files changed, 1312 deletions(-)
delete mode 100644 drivers/mfd/menelaus.c
delete mode 100644 include/linux/mfd/menelaus.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 0395af7270f9..02e52398fcd2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1893,16 +1893,6 @@ config TWL6040_CORE
additional drivers must be enabled in order to use the
functionality of the device (audio, vibra).
-config MENELAUS
- bool "TI TWL92330/Menelaus PM chip"
- depends on I2C=y && ARCH_OMAP2
- help
- If you say yes here you get support for the Texas Instruments
- TWL92330/Menelaus Power Management chip. This include voltage
- regulators, Dual slot memory card transceivers, real-time clock
- and other features that are often used in portable devices like
- cell phones and PDAs.
-
config MFD_TIMBERDALE
tristate "Timberdale FPGA"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index ff62e922209e..a88a13c8bab8 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,7 +102,6 @@ obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o
obj-$(CONFIG_MFD_TPS6594) += tps6594-core.o
obj-$(CONFIG_MFD_TPS6594_I2C) += tps6594-i2c.o
obj-$(CONFIG_MFD_TPS6594_SPI) += tps6594-spi.o
-obj-$(CONFIG_MENELAUS) += menelaus.o
obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
deleted file mode 100644
index a125d40fa121..000000000000
--- a/drivers/mfd/menelaus.c
+++ /dev/null
@@ -1,1251 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2004 Texas Instruments, Inc.
- *
- * Some parts based tps65010.c:
- * Copyright (C) 2004 Texas Instruments and
- * Copyright (C) 2004-2005 David Brownell
- *
- * Some parts based on tlv320aic24.c:
- * Copyright (C) by Kai Svahn <kai.svahn@nokia.com>
- *
- * Changes for interrupt handling and clean-up by
- * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
- * Cleanup and generalized support for voltage setting by
- * Juha Yrjola
- * Added support for controlling VCORE and regulator sleep states,
- * Amit Kucheria <amit.kucheria@nokia.com>
- * Copyright (C) 2005, 2006 Nokia Corporation
- */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/slab.h>
-#include <linux/mfd/menelaus.h>
-
-#include <asm/mach/irq.h>
-
-
-#define DRIVER_NAME "menelaus"
-
-#define MENELAUS_I2C_ADDRESS 0x72
-
-#define MENELAUS_REV 0x01
-#define MENELAUS_VCORE_CTRL1 0x02
-#define MENELAUS_VCORE_CTRL2 0x03
-#define MENELAUS_VCORE_CTRL3 0x04
-#define MENELAUS_VCORE_CTRL4 0x05
-#define MENELAUS_VCORE_CTRL5 0x06
-#define MENELAUS_DCDC_CTRL1 0x07
-#define MENELAUS_DCDC_CTRL2 0x08
-#define MENELAUS_DCDC_CTRL3 0x09
-#define MENELAUS_LDO_CTRL1 0x0A
-#define MENELAUS_LDO_CTRL2 0x0B
-#define MENELAUS_LDO_CTRL3 0x0C
-#define MENELAUS_LDO_CTRL4 0x0D
-#define MENELAUS_LDO_CTRL5 0x0E
-#define MENELAUS_LDO_CTRL6 0x0F
-#define MENELAUS_LDO_CTRL7 0x10
-#define MENELAUS_LDO_CTRL8 0x11
-#define MENELAUS_SLEEP_CTRL1 0x12
-#define MENELAUS_SLEEP_CTRL2 0x13
-#define MENELAUS_DEVICE_OFF 0x14
-#define MENELAUS_OSC_CTRL 0x15
-#define MENELAUS_DETECT_CTRL 0x16
-#define MENELAUS_INT_MASK1 0x17
-#define MENELAUS_INT_MASK2 0x18
-#define MENELAUS_INT_STATUS1 0x19
-#define MENELAUS_INT_STATUS2 0x1A
-#define MENELAUS_INT_ACK1 0x1B
-#define MENELAUS_INT_ACK2 0x1C
-#define MENELAUS_GPIO_CTRL 0x1D
-#define MENELAUS_GPIO_IN 0x1E
-#define MENELAUS_GPIO_OUT 0x1F
-#define MENELAUS_BBSMS 0x20
-#define MENELAUS_RTC_CTRL 0x21
-#define MENELAUS_RTC_UPDATE 0x22
-#define MENELAUS_RTC_SEC 0x23
-#define MENELAUS_RTC_MIN 0x24
-#define MENELAUS_RTC_HR 0x25
-#define MENELAUS_RTC_DAY 0x26
-#define MENELAUS_RTC_MON 0x27
-#define MENELAUS_RTC_YR 0x28
-#define MENELAUS_RTC_WKDAY 0x29
-#define MENELAUS_RTC_AL_SEC 0x2A
-#define MENELAUS_RTC_AL_MIN 0x2B
-#define MENELAUS_RTC_AL_HR 0x2C
-#define MENELAUS_RTC_AL_DAY 0x2D
-#define MENELAUS_RTC_AL_MON 0x2E
-#define MENELAUS_RTC_AL_YR 0x2F
-#define MENELAUS_RTC_COMP_MSB 0x30
-#define MENELAUS_RTC_COMP_LSB 0x31
-#define MENELAUS_S1_PULL_EN 0x32
-#define MENELAUS_S1_PULL_DIR 0x33
-#define MENELAUS_S2_PULL_EN 0x34
-#define MENELAUS_S2_PULL_DIR 0x35
-#define MENELAUS_MCT_CTRL1 0x36
-#define MENELAUS_MCT_CTRL2 0x37
-#define MENELAUS_MCT_CTRL3 0x38
-#define MENELAUS_MCT_PIN_ST 0x39
-#define MENELAUS_DEBOUNCE1 0x3A
-
-#define IH_MENELAUS_IRQS 12
-#define MENELAUS_MMC_S1CD_IRQ 0 /* MMC slot 1 card change */
-#define MENELAUS_MMC_S2CD_IRQ 1 /* MMC slot 2 card change */
-#define MENELAUS_MMC_S1D1_IRQ 2 /* MMC DAT1 low in slot 1 */
-#define MENELAUS_MMC_S2D1_IRQ 3 /* MMC DAT1 low in slot 2 */
-#define MENELAUS_LOWBAT_IRQ 4 /* Low battery */
-#define MENELAUS_HOTDIE_IRQ 5 /* Hot die detect */
-#define MENELAUS_UVLO_IRQ 6 /* UVLO detect */
-#define MENELAUS_TSHUT_IRQ 7 /* Thermal shutdown */
-#define MENELAUS_RTCTMR_IRQ 8 /* RTC timer */
-#define MENELAUS_RTCALM_IRQ 9 /* RTC alarm */
-#define MENELAUS_RTCERR_IRQ 10 /* RTC error */
-#define MENELAUS_PSHBTN_IRQ 11 /* Push button */
-#define MENELAUS_RESERVED12_IRQ 12 /* Reserved */
-#define MENELAUS_RESERVED13_IRQ 13 /* Reserved */
-#define MENELAUS_RESERVED14_IRQ 14 /* Reserved */
-#define MENELAUS_RESERVED15_IRQ 15 /* Reserved */
-
-/* VCORE_CTRL1 register */
-#define VCORE_CTRL1_BYP_COMP (1 << 5)
-#define VCORE_CTRL1_HW_NSW (1 << 7)
-
-/* GPIO_CTRL register */
-#define GPIO_CTRL_SLOTSELEN (1 << 5)
-#define GPIO_CTRL_SLPCTLEN (1 << 6)
-#define GPIO1_DIR_INPUT (1 << 0)
-#define GPIO2_DIR_INPUT (1 << 1)
-#define GPIO3_DIR_INPUT (1 << 2)
-
-/* MCT_CTRL1 register */
-#define MCT_CTRL1_S1_CMD_OD (1 << 2)
-#define MCT_CTRL1_S2_CMD_OD (1 << 3)
-
-/* MCT_CTRL2 register */
-#define MCT_CTRL2_VS2_SEL_D0 (1 << 0)
-#define MCT_CTRL2_VS2_SEL_D1 (1 << 1)
-#define MCT_CTRL2_S1CD_BUFEN (1 << 4)
-#define MCT_CTRL2_S2CD_BUFEN (1 << 5)
-#define MCT_CTRL2_S1CD_DBEN (1 << 6)
-#define MCT_CTRL2_S2CD_BEN (1 << 7)
-
-/* MCT_CTRL3 register */
-#define MCT_CTRL3_SLOT1_EN (1 << 0)
-#define MCT_CTRL3_SLOT2_EN (1 << 1)
-#define MCT_CTRL3_S1_AUTO_EN (1 << 2)
-#define MCT_CTRL3_S2_AUTO_EN (1 << 3)
-
-/* MCT_PIN_ST register */
-#define MCT_PIN_ST_S1_CD_ST (1 << 0)
-#define MCT_PIN_ST_S2_CD_ST (1 << 1)
-
-static void menelaus_work(struct work_struct *_menelaus);
-
-struct menelaus_chip {
- struct mutex lock;
- struct i2c_client *client;
- struct work_struct work;
-#ifdef CONFIG_RTC_DRV_TWL92330
- struct rtc_device *rtc;
- u8 rtc_control;
- unsigned uie:1;
-#endif
- unsigned vcore_hw_mode:1;
- u8 mask1, mask2;
- void (*handlers[16])(struct menelaus_chip *);
- void (*mmc_callback)(void *data, u8 mask);
- void *mmc_callback_data;
-};
-
-static struct menelaus_chip *the_menelaus;
-
-static int menelaus_write_reg(int reg, u8 value)
-{
- int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
-
- if (val < 0) {
- pr_err(DRIVER_NAME ": write error");
- return val;
- }
-
- return 0;
-}
-
-static int menelaus_read_reg(int reg)
-{
- int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
-
- if (val < 0)
- pr_err(DRIVER_NAME ": read error");
-
- return val;
-}
-
-static int menelaus_enable_irq(int irq)
-{
- if (irq > 7) {
- irq -= 8;
- the_menelaus->mask2 &= ~(1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK2,
- the_menelaus->mask2);
- } else {
- the_menelaus->mask1 &= ~(1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK1,
- the_menelaus->mask1);
- }
-}
-
-static int menelaus_disable_irq(int irq)
-{
- if (irq > 7) {
- irq -= 8;
- the_menelaus->mask2 |= (1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK2,
- the_menelaus->mask2);
- } else {
- the_menelaus->mask1 |= (1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK1,
- the_menelaus->mask1);
- }
-}
-
-static int menelaus_ack_irq(int irq)
-{
- if (irq > 7)
- return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
- else
- return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq);
-}
-
-/* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(int irq,
- void (*handler)(struct menelaus_chip *))
-{
- int ret = 0;
-
- mutex_lock(&the_menelaus->lock);
- the_menelaus->handlers[irq] = handler;
- ret = menelaus_enable_irq(irq);
- mutex_unlock(&the_menelaus->lock);
-
- return ret;
-}
-
-/* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(int irq)
-{
- int ret = 0;
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_disable_irq(irq);
- the_menelaus->handlers[irq] = NULL;
- mutex_unlock(&the_menelaus->lock);
-
- return ret;
-}
-
-/*
- * Gets scheduled when a card detect interrupt happens. Note that in some cases
- * this line is wired to card cover switch rather than the card detect switch
- * in each slot. In this case the cards are not seen by menelaus.
- * FIXME: Add handling for D1 too
- */
-static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
-{
- int reg;
- unsigned char card_mask = 0;
-
- reg = menelaus_read_reg(MENELAUS_MCT_PIN_ST);
- if (reg < 0)
- return;
-
- if (!(reg & 0x1))
- card_mask |= MCT_PIN_ST_S1_CD_ST;
-
- if (!(reg & 0x2))
- card_mask |= MCT_PIN_ST_S2_CD_ST;
-
- if (menelaus_hw->mmc_callback)
- menelaus_hw->mmc_callback(menelaus_hw->mmc_callback_data,
- card_mask);
-}
-
-/*
- * Toggles the MMC slots between open-drain and push-pull mode.
- */
-int menelaus_set_mmc_opendrain(int slot, int enable)
-{
- int ret, val;
-
- if (slot != 1 && slot != 2)
- return -EINVAL;
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_read_reg(MENELAUS_MCT_CTRL1);
- if (ret < 0) {
- mutex_unlock(&the_menelaus->lock);
- return ret;
- }
- val = ret;
- if (slot == 1) {
- if (enable)
- val |= MCT_CTRL1_S1_CMD_OD;
- else
- val &= ~MCT_CTRL1_S1_CMD_OD;
- } else {
- if (enable)
- val |= MCT_CTRL1_S2_CMD_OD;
- else
- val &= ~MCT_CTRL1_S2_CMD_OD;
- }
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL1, val);
- mutex_unlock(&the_menelaus->lock);
-
- return ret;
-}
-EXPORT_SYMBOL(menelaus_set_mmc_opendrain);
-
-int menelaus_set_slot_sel(int enable)
-{
- int ret;
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
- if (ret < 0)
- goto out;
- ret |= GPIO2_DIR_INPUT;
- if (enable)
- ret |= GPIO_CTRL_SLOTSELEN;
- else
- ret &= ~GPIO_CTRL_SLOTSELEN;
- ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-EXPORT_SYMBOL(menelaus_set_slot_sel);
-
-int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
-{
- int ret, val;
-
- if (slot != 1 && slot != 2)
- return -EINVAL;
- if (power >= 3)
- return -EINVAL;
-
- mutex_lock(&the_menelaus->lock);
-
- ret = menelaus_read_reg(MENELAUS_MCT_CTRL2);
- if (ret < 0)
- goto out;
- val = ret;
- if (slot == 1) {
- if (cd_en)
- val |= MCT_CTRL2_S1CD_BUFEN | MCT_CTRL2_S1CD_DBEN;
- else
- val &= ~(MCT_CTRL2_S1CD_BUFEN | MCT_CTRL2_S1CD_DBEN);
- } else {
- if (cd_en)
- val |= MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN;
- else
- val &= ~(MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN);
- }
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, val);
- if (ret < 0)
- goto out;
-
- ret = menelaus_read_reg(MENELAUS_MCT_CTRL3);
- if (ret < 0)
- goto out;
- val = ret;
- if (slot == 1) {
- if (enable)
- val |= MCT_CTRL3_SLOT1_EN;
- else
- val &= ~MCT_CTRL3_SLOT1_EN;
- } else {
- int b;
-
- if (enable)
- val |= MCT_CTRL3_SLOT2_EN;
- else
- val &= ~MCT_CTRL3_SLOT2_EN;
- b = menelaus_read_reg(MENELAUS_MCT_CTRL2);
- b &= ~(MCT_CTRL2_VS2_SEL_D0 | MCT_CTRL2_VS2_SEL_D1);
- b |= power;
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, b);
- if (ret < 0)
- goto out;
- }
- /* Disable autonomous shutdown */
- val &= ~(MCT_CTRL3_S1_AUTO_EN | MCT_CTRL3_S2_AUTO_EN);
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL3, val);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-EXPORT_SYMBOL(menelaus_set_mmc_slot);
-
-int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
- void *data)
-{
- int ret = 0;
-
- the_menelaus->mmc_callback_data = data;
- the_menelaus->mmc_callback = callback;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S1CD_IRQ,
- menelaus_mmc_cd_work);
- if (ret < 0)
- return ret;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S2CD_IRQ,
- menelaus_mmc_cd_work);
- if (ret < 0)
- return ret;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S1D1_IRQ,
- menelaus_mmc_cd_work);
- if (ret < 0)
- return ret;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S2D1_IRQ,
- menelaus_mmc_cd_work);
-
- return ret;
-}
-EXPORT_SYMBOL(menelaus_register_mmc_callback);
-
-void menelaus_unregister_mmc_callback(void)
-{
- menelaus_remove_irq_work(MENELAUS_MMC_S1CD_IRQ);
- menelaus_remove_irq_work(MENELAUS_MMC_S2CD_IRQ);
- menelaus_remove_irq_work(MENELAUS_MMC_S1D1_IRQ);
- menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
-
- the_menelaus->mmc_callback = NULL;
- the_menelaus->mmc_callback_data = NULL;
-}
-EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
-
-struct menelaus_vtg {
- const char *name;
- u8 vtg_reg;
- u8 vtg_shift;
- u8 vtg_bits;
- u8 mode_reg;
-};
-
-struct menelaus_vtg_value {
- u16 vtg;
- u16 val;
-};
-
-static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
- int vtg_val, int mode)
-{
- int val, ret;
- struct i2c_client *c = the_menelaus->client;
-
- mutex_lock(&the_menelaus->lock);
-
- ret = menelaus_read_reg(vtg->vtg_reg);
- if (ret < 0)
- goto out;
- val = ret & ~(((1 << vtg->vtg_bits) - 1) << vtg->vtg_shift);
- val |= vtg_val << vtg->vtg_shift;
-
- dev_dbg(&c->dev, "Setting voltage '%s'"
- "to %d mV (reg 0x%02x, val 0x%02x)\n",
- vtg->name, mV, vtg->vtg_reg, val);
-
- ret = menelaus_write_reg(vtg->vtg_reg, val);
- if (ret < 0)
- goto out;
- ret = menelaus_write_reg(vtg->mode_reg, mode);
-out:
- mutex_unlock(&the_menelaus->lock);
- if (ret == 0) {
- /* Wait for voltage to stabilize */
- msleep(1);
- }
- return ret;
-}
-
-static int menelaus_get_vtg_value(int vtg, const struct menelaus_vtg_value *tbl,
- int n)
-{
- int i;
-
- for (i = 0; i < n; i++, tbl++)
- if (tbl->vtg == vtg)
- return tbl->val;
- return -EINVAL;
-}
-
-/*
- * Vcore can be programmed in two ways:
- * SW-controlled: Required voltage is programmed into VCORE_CTRL1
- * HW-controlled: Required range (roof-floor) is programmed into VCORE_CTRL3
- * and VCORE_CTRL4
- *
- * Call correct 'set' function accordingly
- */
-
-static const struct menelaus_vtg_value vcore_values[] = {
- { 1000, 0 },
- { 1025, 1 },
- { 1050, 2 },
- { 1075, 3 },
- { 1100, 4 },
- { 1125, 5 },
- { 1150, 6 },
- { 1175, 7 },
- { 1200, 8 },
- { 1225, 9 },
- { 1250, 10 },
- { 1275, 11 },
- { 1300, 12 },
- { 1325, 13 },
- { 1350, 14 },
- { 1375, 15 },
- { 1400, 16 },
- { 1425, 17 },
- { 1450, 18 },
-};
-
-int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
-{
- int fval, rval, val, ret;
- struct i2c_client *c = the_menelaus->client;
-
- rval = menelaus_get_vtg_value(roof_mV, vcore_values,
- ARRAY_SIZE(vcore_values));
- if (rval < 0)
- return -EINVAL;
- fval = menelaus_get_vtg_value(floor_mV, vcore_values,
- ARRAY_SIZE(vcore_values));
- if (fval < 0)
- return -EINVAL;
-
- dev_dbg(&c->dev, "Setting VCORE FLOOR to %d mV and ROOF to %d mV\n",
- floor_mV, roof_mV);
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_write_reg(MENELAUS_VCORE_CTRL3, fval);
- if (ret < 0)
- goto out;
- ret = menelaus_write_reg(MENELAUS_VCORE_CTRL4, rval);
- if (ret < 0)
- goto out;
- if (!the_menelaus->vcore_hw_mode) {
- val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
- /* HW mode, turn OFF byte comparator */
- val |= (VCORE_CTRL1_HW_NSW | VCORE_CTRL1_BYP_COMP);
- ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
- the_menelaus->vcore_hw_mode = 1;
- }
- msleep(1);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-
-static const struct menelaus_vtg vmem_vtg = {
- .name = "VMEM",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 0,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL3,
-};
-
-static const struct menelaus_vtg_value vmem_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 1900, 2 },
- { 2500, 3 },
-};
-
-int menelaus_set_vmem(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vmem_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vmem_values, ARRAY_SIZE(vmem_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vmem_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vmem);
-
-static const struct menelaus_vtg vio_vtg = {
- .name = "VIO",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 2,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL4,
-};
-
-static const struct menelaus_vtg_value vio_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 2500, 2 },
- { 2800, 3 },
-};
-
-int menelaus_set_vio(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vio_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vio_values, ARRAY_SIZE(vio_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vio_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vio);
-
-static const struct menelaus_vtg_value vdcdc_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 2000, 2 },
- { 2200, 3 },
- { 2400, 4 },
- { 2800, 5 },
- { 3000, 6 },
- { 3300, 7 },
-};
-
-static const struct menelaus_vtg vdcdc2_vtg = {
- .name = "VDCDC2",
- .vtg_reg = MENELAUS_DCDC_CTRL1,
- .vtg_shift = 0,
- .vtg_bits = 3,
- .mode_reg = MENELAUS_DCDC_CTRL2,
-};
-
-static const struct menelaus_vtg vdcdc3_vtg = {
- .name = "VDCDC3",
- .vtg_reg = MENELAUS_DCDC_CTRL1,
- .vtg_shift = 3,
- .vtg_bits = 3,
- .mode_reg = MENELAUS_DCDC_CTRL3,
-};
-
-int menelaus_set_vdcdc(int dcdc, unsigned int mV)
-{
- const struct menelaus_vtg *vtg;
- int val;
-
- if (dcdc != 2 && dcdc != 3)
- return -EINVAL;
- if (dcdc == 2)
- vtg = &vdcdc2_vtg;
- else
- vtg = &vdcdc3_vtg;
-
- if (mV == 0)
- return menelaus_set_voltage(vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vdcdc_values,
- ARRAY_SIZE(vdcdc_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(vtg, mV, val, 0x03);
-}
-
-static const struct menelaus_vtg_value vmmc_values[] = {
- { 1850, 0 },
- { 2800, 1 },
- { 3000, 2 },
- { 3100, 3 },
-};
-
-static const struct menelaus_vtg vmmc_vtg = {
- .name = "VMMC",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 6,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL7,
-};
-
-int menelaus_set_vmmc(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vmmc_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vmmc_values, ARRAY_SIZE(vmmc_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vmmc_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vmmc);
-
-
-static const struct menelaus_vtg_value vaux_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 2500, 2 },
- { 2800, 3 },
-};
-
-static const struct menelaus_vtg vaux_vtg = {
- .name = "VAUX",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 4,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL6,
-};
-
-int menelaus_set_vaux(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vaux_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vaux_values, ARRAY_SIZE(vaux_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vaux_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vaux);
-
-int menelaus_get_slot_pin_states(void)
-{
- return menelaus_read_reg(MENELAUS_MCT_PIN_ST);
-}
-EXPORT_SYMBOL(menelaus_get_slot_pin_states);
-
-int menelaus_set_regulator_sleep(int enable, u32 val)
-{
- int t, ret;
- struct i2c_client *c = the_menelaus->client;
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_write_reg(MENELAUS_SLEEP_CTRL2, val);
- if (ret < 0)
- goto out;
-
- dev_dbg(&c->dev, "regulator sleep configuration: %02x\n", val);
-
- ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
- if (ret < 0)
- goto out;
- t = (GPIO_CTRL_SLPCTLEN | GPIO3_DIR_INPUT);
- if (enable)
- ret |= t;
- else
- ret &= ~t;
- ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-
-/*-----------------------------------------------------------------------*/
-
-/* Handles Menelaus interrupts. Does not run in interrupt context */
-static void menelaus_work(struct work_struct *_menelaus)
-{
- struct menelaus_chip *menelaus =
- container_of(_menelaus, struct menelaus_chip, work);
- void (*handler)(struct menelaus_chip *menelaus);
-
- while (1) {
- unsigned isr;
-
- isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
- & ~menelaus->mask2) << 8;
- isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
- & ~menelaus->mask1;
- if (!isr)
- break;
-
- while (isr) {
- int irq = fls(isr) - 1;
- isr &= ~(1 << irq);
-
- mutex_lock(&menelaus->lock);
- menelaus_disable_irq(irq);
- menelaus_ack_irq(irq);
- handler = menelaus->handlers[irq];
- if (handler)
- handler(menelaus);
- menelaus_enable_irq(irq);
- mutex_unlock(&menelaus->lock);
- }
- }
- enable_irq(menelaus->client->irq);
-}
-
-/*
- * We cannot use I2C in interrupt context, so we just schedule work.
- */
-static irqreturn_t menelaus_irq(int irq, void *_menelaus)
-{
- struct menelaus_chip *menelaus = _menelaus;
-
- disable_irq_nosync(irq);
- (void)schedule_work(&menelaus->work);
-
- return IRQ_HANDLED;
-}
-
-/*-----------------------------------------------------------------------*/
-
-/*
- * The RTC needs to be set once, then it runs on backup battery power.
- * It supports alarms, including system wake alarms (from some modes);
- * and 1/second IRQs if requested.
- */
-#ifdef CONFIG_RTC_DRV_TWL92330
-
-#define RTC_CTRL_RTC_EN (1 << 0)
-#define RTC_CTRL_AL_EN (1 << 1)
-#define RTC_CTRL_MODE12 (1 << 2)
-#define RTC_CTRL_EVERY_MASK (3 << 3)
-#define RTC_CTRL_EVERY_SEC (0 << 3)
-#define RTC_CTRL_EVERY_MIN (1 << 3)
-#define RTC_CTRL_EVERY_HR (2 << 3)
-#define RTC_CTRL_EVERY_DAY (3 << 3)
-
-#define RTC_UPDATE_EVERY 0x08
-
-#define RTC_HR_PM (1 << 7)
-
-static void menelaus_to_time(char *regs, struct rtc_time *t)
-{
- t->tm_sec = bcd2bin(regs[0]);
- t->tm_min = bcd2bin(regs[1]);
- if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
- t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1;
- if (regs[2] & RTC_HR_PM)
- t->tm_hour += 12;
- } else
- t->tm_hour = bcd2bin(regs[2] & 0x3f);
- t->tm_mday = bcd2bin(regs[3]);
- t->tm_mon = bcd2bin(regs[4]) - 1;
- t->tm_year = bcd2bin(regs[5]) + 100;
-}
-
-static int time_to_menelaus(struct rtc_time *t, int regnum)
-{
- int hour, status;
-
- status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec));
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min));
- if (status < 0)
- goto fail;
-
- if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
- hour = t->tm_hour + 1;
- if (hour > 12)
- hour = RTC_HR_PM | bin2bcd(hour - 12);
- else
- hour = bin2bcd(hour);
- } else
- hour = bin2bcd(t->tm_hour);
- status = menelaus_write_reg(regnum++, hour);
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday));
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1));
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100));
- if (status < 0)
- goto fail;
-
- return 0;
-fail:
- dev_err(&the_menelaus->client->dev, "rtc write reg %02x, err %d\n",
- --regnum, status);
- return status;
-}
-
-static int menelaus_read_time(struct device *dev, struct rtc_time *t)
-{
- struct i2c_msg msg[2];
- char regs[7];
- int status;
-
- /* block read date and time registers */
- regs[0] = MENELAUS_RTC_SEC;
-
- msg[0].addr = MENELAUS_I2C_ADDRESS;
- msg[0].flags = 0;
- msg[0].len = 1;
- msg[0].buf = regs;
-
- msg[1].addr = MENELAUS_I2C_ADDRESS;
- msg[1].flags = I2C_M_RD;
- msg[1].len = sizeof(regs);
- msg[1].buf = regs;
-
- status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
- if (status != 2) {
- dev_err(dev, "%s error %d\n", "read", status);
- return -EIO;
- }
-
- menelaus_to_time(regs, t);
- t->tm_wday = bcd2bin(regs[6]);
-
- return 0;
-}
-
-static int menelaus_set_time(struct device *dev, struct rtc_time *t)
-{
- int status;
-
- /* write date and time registers */
- status = time_to_menelaus(t, MENELAUS_RTC_SEC);
- if (status < 0)
- return status;
- status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
- if (status < 0) {
- dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
- "err %d\n", MENELAUS_RTC_WKDAY, status);
- return status;
- }
-
- /* now commit the write */
- status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
- if (status < 0)
- dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n",
- status);
-
- return 0;
-}
-
-static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
-{
- struct i2c_msg msg[2];
- char regs[6];
- int status;
-
- /* block read alarm registers */
- regs[0] = MENELAUS_RTC_AL_SEC;
-
- msg[0].addr = MENELAUS_I2C_ADDRESS;
- msg[0].flags = 0;
- msg[0].len = 1;
- msg[0].buf = regs;
-
- msg[1].addr = MENELAUS_I2C_ADDRESS;
- msg[1].flags = I2C_M_RD;
- msg[1].len = sizeof(regs);
- msg[1].buf = regs;
-
- status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
- if (status != 2) {
- dev_err(dev, "%s error %d\n", "alarm read", status);
- return -EIO;
- }
-
- menelaus_to_time(regs, &w->time);
-
- w->enabled = !!(the_menelaus->rtc_control & RTC_CTRL_AL_EN);
-
- /* NOTE we *could* check if actually pending... */
- w->pending = 0;
-
- return 0;
-}
-
-static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
-{
- int status;
-
- if (the_menelaus->client->irq <= 0 && w->enabled)
- return -ENODEV;
-
- /* clear previous alarm enable */
- if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) {
- the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
- status = menelaus_write_reg(MENELAUS_RTC_CTRL,
- the_menelaus->rtc_control);
- if (status < 0)
- return status;
- }
-
- /* write alarm registers */
- status = time_to_menelaus(&w->time, MENELAUS_RTC_AL_SEC);
- if (status < 0)
- return status;
-
- /* enable alarm if requested */
- if (w->enabled) {
- the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
- status = menelaus_write_reg(MENELAUS_RTC_CTRL,
- the_menelaus->rtc_control);
- }
-
- return status;
-}
-
-#ifdef CONFIG_RTC_INTF_DEV
-
-static void menelaus_rtc_update_work(struct menelaus_chip *m)
-{
- /* report 1/sec update */
- rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF);
-}
-
-static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
-{
- int status;
-
- if (the_menelaus->client->irq <= 0)
- return -ENOIOCTLCMD;
-
- switch (cmd) {
- /* alarm IRQ */
- case RTC_AIE_ON:
- if (the_menelaus->rtc_control & RTC_CTRL_AL_EN)
- return 0;
- the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
- break;
- case RTC_AIE_OFF:
- if (!(the_menelaus->rtc_control & RTC_CTRL_AL_EN))
- return 0;
- the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
- break;
- /* 1/second "update" IRQ */
- case RTC_UIE_ON:
- if (the_menelaus->uie)
- return 0;
- status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
- status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
- menelaus_rtc_update_work);
- if (status == 0)
- the_menelaus->uie = 1;
- return status;
- case RTC_UIE_OFF:
- if (!the_menelaus->uie)
- return 0;
- status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
- if (status == 0)
- the_menelaus->uie = 0;
- return status;
- default:
- return -ENOIOCTLCMD;
- }
- return menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
-}
-
-#else
-#define menelaus_ioctl NULL
-#endif
-
-/* REVISIT no compensation register support ... */
-
-static const struct rtc_class_ops menelaus_rtc_ops = {
- .ioctl = menelaus_ioctl,
- .read_time = menelaus_read_time,
- .set_time = menelaus_set_time,
- .read_alarm = menelaus_read_alarm,
- .set_alarm = menelaus_set_alarm,
-};
-
-static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
-{
- /* report alarm */
- rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF);
-
- /* then disable it; alarms are oneshot */
- the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
- menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
-}
-
-static inline void menelaus_rtc_init(struct menelaus_chip *m)
-{
- int alarm = (m->client->irq > 0);
- int err;
-
- /* assume 32KDETEN pin is pulled high */
- if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
- dev_dbg(&m->client->dev, "no 32k oscillator\n");
- return;
- }
-
- m->rtc = devm_rtc_allocate_device(&m->client->dev);
- if (IS_ERR(m->rtc))
- return;
-
- m->rtc->ops = &menelaus_rtc_ops;
-
- /* support RTC alarm; it can issue wakeups */
- if (alarm) {
- if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
- menelaus_rtc_alarm_work) < 0) {
- dev_err(&m->client->dev, "can't handle RTC alarm\n");
- return;
- }
- device_init_wakeup(&m->client->dev, 1);
- }
-
- /* be sure RTC is enabled; allow 1/sec irqs; leave 12hr mode alone */
- m->rtc_control = menelaus_read_reg(MENELAUS_RTC_CTRL);
- if (!(m->rtc_control & RTC_CTRL_RTC_EN)
- || (m->rtc_control & RTC_CTRL_AL_EN)
- || (m->rtc_control & RTC_CTRL_EVERY_MASK)) {
- if (!(m->rtc_control & RTC_CTRL_RTC_EN)) {
- dev_warn(&m->client->dev, "rtc clock needs setting\n");
- m->rtc_control |= RTC_CTRL_RTC_EN;
- }
- m->rtc_control &= ~RTC_CTRL_EVERY_MASK;
- m->rtc_control &= ~RTC_CTRL_AL_EN;
- menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
- }
-
- err = devm_rtc_register_device(m->rtc);
- if (err) {
- if (alarm) {
- menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
- device_init_wakeup(&m->client->dev, 0);
- }
- the_menelaus->rtc = NULL;
- }
-}
-
-#else
-
-static inline void menelaus_rtc_init(struct menelaus_chip *m)
-{
- /* nothing */
-}
-
-#endif
-
-/*-----------------------------------------------------------------------*/
-
-static struct i2c_driver menelaus_i2c_driver;
-
-static int menelaus_probe(struct i2c_client *client)
-{
- struct menelaus_chip *menelaus;
- int rev = 0;
- int err = 0;
- struct menelaus_platform_data *menelaus_pdata =
- dev_get_platdata(&client->dev);
-
- if (the_menelaus) {
- dev_dbg(&client->dev, "only one %s for now\n",
- DRIVER_NAME);
- return -ENODEV;
- }
-
- menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL);
- if (!menelaus)
- return -ENOMEM;
-
- i2c_set_clientdata(client, menelaus);
-
- the_menelaus = menelaus;
- menelaus->client = client;
-
- /* If a true probe check the device */
- rev = menelaus_read_reg(MENELAUS_REV);
- if (rev < 0) {
- pr_err(DRIVER_NAME ": device not found");
- return -ENODEV;
- }
-
- /* Ack and disable all Menelaus interrupts */
- menelaus_write_reg(MENELAUS_INT_ACK1, 0xff);
- menelaus_write_reg(MENELAUS_INT_ACK2, 0xff);
- menelaus_write_reg(MENELAUS_INT_MASK1, 0xff);
- menelaus_write_reg(MENELAUS_INT_MASK2, 0xff);
- menelaus->mask1 = 0xff;
- menelaus->mask2 = 0xff;
-
- /* Set output buffer strengths */
- menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
-
- if (client->irq > 0) {
- err = request_irq(client->irq, menelaus_irq, 0,
- DRIVER_NAME, menelaus);
- if (err) {
- dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
- client->irq, err);
- return err;
- }
- }
-
- mutex_init(&menelaus->lock);
- INIT_WORK(&menelaus->work, menelaus_work);
-
- pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
-
- err = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
- if (err < 0)
- goto fail;
- if (err & VCORE_CTRL1_HW_NSW)
- menelaus->vcore_hw_mode = 1;
- else
- menelaus->vcore_hw_mode = 0;
-
- if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
- err = menelaus_pdata->late_init(&client->dev);
- if (err < 0)
- goto fail;
- }
-
- menelaus_rtc_init(menelaus);
-
- return 0;
-fail:
- free_irq(client->irq, menelaus);
- flush_work(&menelaus->work);
- return err;
-}
-
-static void menelaus_remove(struct i2c_client *client)
-{
- struct menelaus_chip *menelaus = i2c_get_clientdata(client);
-
- free_irq(client->irq, menelaus);
- flush_work(&menelaus->work);
- the_menelaus = NULL;
-}
-
-static const struct i2c_device_id menelaus_id[] = {
- { "menelaus" },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, menelaus_id);
-
-static struct i2c_driver menelaus_i2c_driver = {
- .driver = {
- .name = DRIVER_NAME,
- },
- .probe = menelaus_probe,
- .remove = menelaus_remove,
- .id_table = menelaus_id,
-};
-
-module_i2c_driver(menelaus_i2c_driver);
-
-MODULE_AUTHOR("Texas Instruments, Inc. (and others)");
-MODULE_DESCRIPTION("I2C interface for Menelaus.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4120ff2cebc3..52be691c62ac 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -570,15 +570,6 @@ config RTC_DRV_BQ32K
This driver can also be built as a module. If so, the module
will be called rtc-bq32k.
-config RTC_DRV_TWL92330
- bool "TI TWL92330/Menelaus"
- depends on MENELAUS
- help
- If you say yes here you get support for the RTC on the
- TWL92330 "Menelaus" power management chip, used with OMAP2
- platforms. The support is integrated with the rest of
- the Menelaus driver; it's not separate module.
-
config RTC_DRV_TWL4030
tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0"
depends on TWL4030_CORE
diff --git a/include/linux/mfd/menelaus.h b/include/linux/mfd/menelaus.h
deleted file mode 100644
index ce489aba88ec..000000000000
--- a/include/linux/mfd/menelaus.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Functions to access Menelaus power management chip
- */
-
-#ifndef __ASM_ARCH_MENELAUS_H
-#define __ASM_ARCH_MENELAUS_H
-
-struct device;
-
-struct menelaus_platform_data {
- int (* late_init)(struct device *dev);
-};
-
-extern int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
- void *data);
-extern void menelaus_unregister_mmc_callback(void);
-extern int menelaus_set_mmc_opendrain(int slot, int enable);
-extern int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_on);
-
-extern int menelaus_set_vmem(unsigned int mV);
-extern int menelaus_set_vio(unsigned int mV);
-extern int menelaus_set_vmmc(unsigned int mV);
-extern int menelaus_set_vaux(unsigned int mV);
-extern int menelaus_set_vdcdc(int dcdc, unsigned int mV);
-extern int menelaus_set_slot_sel(int enable);
-extern int menelaus_get_slot_pin_states(void);
-extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
-
-#define EN_VPLL_SLEEP (1 << 7)
-#define EN_VMMC_SLEEP (1 << 6)
-#define EN_VAUX_SLEEP (1 << 5)
-#define EN_VIO_SLEEP (1 << 4)
-#define EN_VMEM_SLEEP (1 << 3)
-#define EN_DC3_SLEEP (1 << 2)
-#define EN_DC2_SLEEP (1 << 1)
-#define EN_VC_SLEEP (1 << 0)
-
-extern int menelaus_set_regulator_sleep(int enable, u32 val);
-
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread* Re: [PATCH 13/14] mfd: remove unused menelaus driver
2026-09-09 13:21 ` [PATCH 13/14] mfd: remove unused menelaus driver Arnd Bergmann
@ 2026-09-09 13:51 ` Alexandre Belloni
0 siblings, 0 replies; 36+ messages in thread
From: Alexandre Belloni @ 2026-09-09 13:51 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Sebastian Reichel,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
On 09/09/2026 15:21:50+0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> Menelaus was a companion chip for the omap24xx platform, which has
> been remvoed from the kernel, so now the menelaus driver is unused
> and can be removed.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 14/14] mfd: remove unused iPaq micro driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (9 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 13/14] mfd: remove unused menelaus driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
[not found] ` <20260909132153.1596191-12-arnd@kernel.org>
` (3 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2026-09-09 13:21 UTC (permalink / raw)
To: Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
From: Arnd Bergmann <arnd@arndb.de>
The iPaq support has been removed from the kernel, this driver is
no longer used anywhere.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/mfd/Kconfig | 10 -
drivers/mfd/Makefile | 1 -
drivers/mfd/ipaq-micro.c | 442 ---------------------------------------
3 files changed, 453 deletions(-)
delete mode 100644 drivers/mfd/ipaq-micro.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 02e52398fcd2..6189bd7cc109 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -780,16 +780,6 @@ config MFD_INTEL_PMC_BXT
Register and P-unit access. In addition this creates devices
for iTCO watchdog and telemetry that are part of the PMC.
-config MFD_IPAQ_MICRO
- bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support"
- depends on SA1100_H3600
- select MFD_CORE
- help
- Select this to get support for the Microcontroller found in
- the Compaq iPAQ handheld computers. This is an Atmel
- AT90LS8535 microcontroller flashed with a special iPAQ
- firmware using the custom protocol implemented in this driver.
-
config MFD_IQS62X
tristate "Azoteq IQS620A/621/622/624/625 core support"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a88a13c8bab8..b56ff2e68d4a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -218,7 +218,6 @@ obj-$(CONFIG_MFD_RETU) += retu-mfd.o
obj-$(CONFIG_MFD_AS3711) += as3711.o
obj-$(CONFIG_MFD_AS3722) += as3722.o
obj-$(CONFIG_MFD_STW481X) += stw481x.o
-obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o
obj-$(CONFIG_MFD_IQS62X) += iqs62x.o
obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o
obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o
diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c
deleted file mode 100644
index 5146a6eb0e5a..000000000000
--- a/drivers/mfd/ipaq-micro.c
+++ /dev/null
@@ -1,442 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Compaq iPAQ h3xxx Atmel microcontroller companion support
- *
- * This is an Atmel AT90LS8535 with a special flashed-in firmware that
- * implements the special protocol used by this driver.
- *
- * based on previous kernel 2.4 version by Andrew Christian
- * Author : Alessandro Gardich <gremlin@gremlin.it>
- * Author : Dmitry Artamonow <mad_soft@inbox.ru>
- * Author : Linus Walleij <linus.walleij@linaro.org>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/ipaq-micro.h>
-#include <linux/string.h>
-#include <linux/string_choices.h>
-#include <linux/random.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-
-#include <mach/hardware.h>
-
-static void ipaq_micro_trigger_tx(struct ipaq_micro *micro)
-{
- struct ipaq_micro_txdev *tx = µ->tx;
- struct ipaq_micro_msg *msg = micro->msg;
- int i, bp;
- u8 checksum;
- u32 val;
-
- bp = 0;
- tx->buf[bp++] = CHAR_SOF;
-
- checksum = ((msg->id & 0x0f) << 4) | (msg->tx_len & 0x0f);
- tx->buf[bp++] = checksum;
-
- for (i = 0; i < msg->tx_len; i++) {
- tx->buf[bp++] = msg->tx_data[i];
- checksum += msg->tx_data[i];
- }
-
- tx->buf[bp++] = checksum;
- tx->len = bp;
- tx->index = 0;
-
- /* Enable interrupt */
- val = readl(micro->base + UTCR3);
- val |= UTCR3_TIE;
- writel(val, micro->base + UTCR3);
-}
-
-int ipaq_micro_tx_msg(struct ipaq_micro *micro, struct ipaq_micro_msg *msg)
-{
- unsigned long flags;
-
- dev_dbg(micro->dev, "TX msg: %02x, %d bytes\n", msg->id, msg->tx_len);
-
- spin_lock_irqsave(µ->lock, flags);
- if (micro->msg) {
- list_add_tail(&msg->node, µ->queue);
- spin_unlock_irqrestore(µ->lock, flags);
- return 0;
- }
- micro->msg = msg;
- ipaq_micro_trigger_tx(micro);
- spin_unlock_irqrestore(µ->lock, flags);
- return 0;
-}
-EXPORT_SYMBOL(ipaq_micro_tx_msg);
-
-static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data)
-{
- dev_dbg(micro->dev, "RX msg: %02x, %d bytes\n", id, len);
-
- spin_lock(µ->lock);
- switch (id) {
- case MSG_VERSION:
- case MSG_EEPROM_READ:
- case MSG_EEPROM_WRITE:
- case MSG_BACKLIGHT:
- case MSG_NOTIFY_LED:
- case MSG_THERMAL_SENSOR:
- case MSG_BATTERY:
- /* Handle synchronous messages */
- if (micro->msg && micro->msg->id == id) {
- struct ipaq_micro_msg *msg = micro->msg;
-
- memcpy(msg->rx_data, data, len);
- msg->rx_len = len;
- complete(µ->msg->ack);
- if (!list_empty(µ->queue)) {
- micro->msg = list_entry(micro->queue.next,
- struct ipaq_micro_msg,
- node);
- list_del_init(µ->msg->node);
- ipaq_micro_trigger_tx(micro);
- } else
- micro->msg = NULL;
- dev_dbg(micro->dev, "OK RX message 0x%02x\n", id);
- } else {
- dev_err(micro->dev,
- "out of band RX message 0x%02x\n", id);
- if (!micro->msg)
- dev_info(micro->dev, "no message queued\n");
- else
- dev_info(micro->dev, "expected message %02x\n",
- micro->msg->id);
- }
- break;
- case MSG_KEYBOARD:
- if (micro->key)
- micro->key(micro->key_data, len, data);
- else
- dev_dbg(micro->dev, "key message ignored, no handle\n");
- break;
- case MSG_TOUCHSCREEN:
- if (micro->ts)
- micro->ts(micro->ts_data, len, data);
- else
- dev_dbg(micro->dev, "touchscreen message ignored, no handle\n");
- break;
- default:
- dev_err(micro->dev,
- "unknown msg %d [%d] %*ph\n", id, len, len, data);
- break;
- }
- spin_unlock(µ->lock);
-}
-
-static void micro_process_char(struct ipaq_micro *micro, u8 ch)
-{
- struct ipaq_micro_rxdev *rx = µ->rx;
-
- switch (rx->state) {
- case STATE_SOF: /* Looking for SOF */
- if (ch == CHAR_SOF)
- rx->state = STATE_ID; /* Next byte is the id and len */
- break;
- case STATE_ID: /* Looking for id and len byte */
- rx->id = (ch & 0xf0) >> 4;
- rx->len = (ch & 0x0f);
- rx->index = 0;
- rx->chksum = ch;
- rx->state = (rx->len > 0) ? STATE_DATA : STATE_CHKSUM;
- break;
- case STATE_DATA: /* Looking for 'len' data bytes */
- rx->chksum += ch;
- rx->buf[rx->index] = ch;
- if (++rx->index == rx->len)
- rx->state = STATE_CHKSUM;
- break;
- case STATE_CHKSUM: /* Looking for the checksum */
- if (ch == rx->chksum)
- micro_rx_msg(micro, rx->id, rx->len, rx->buf);
- rx->state = STATE_SOF;
- break;
- }
-}
-
-static void micro_rx_chars(struct ipaq_micro *micro)
-{
- u32 status, ch;
-
- while ((status = readl(micro->base + UTSR1)) & UTSR1_RNE) {
- ch = readl(micro->base + UTDR);
- if (status & UTSR1_PRE)
- dev_err(micro->dev, "rx: parity error\n");
- else if (status & UTSR1_FRE)
- dev_err(micro->dev, "rx: framing error\n");
- else if (status & UTSR1_ROR)
- dev_err(micro->dev, "rx: overrun error\n");
- micro_process_char(micro, ch);
- }
-}
-
-static void ipaq_micro_get_version(struct ipaq_micro *micro)
-{
- struct ipaq_micro_msg msg = {
- .id = MSG_VERSION,
- };
-
- ipaq_micro_tx_msg_sync(micro, &msg);
- if (msg.rx_len == 4) {
- memcpy(micro->version, msg.rx_data, 4);
- micro->version[4] = '\0';
- } else if (msg.rx_len == 9) {
- memcpy(micro->version, msg.rx_data, 4);
- micro->version[4] = '\0';
- /* Bytes 4-7 are "pack", byte 8 is "boot type" */
- } else {
- dev_err(micro->dev,
- "illegal version message %d bytes\n", msg.rx_len);
- }
-}
-
-static void ipaq_micro_eeprom_read(struct ipaq_micro *micro,
- u8 address, u8 len, u8 *data)
-{
- struct ipaq_micro_msg msg = {
- .id = MSG_EEPROM_READ,
- };
- u8 i;
-
- for (i = 0; i < len; i++) {
- msg.tx_data[0] = address + i;
- msg.tx_data[1] = 1;
- msg.tx_len = 2;
- ipaq_micro_tx_msg_sync(micro, &msg);
- memcpy(data + (i * 2), msg.rx_data, 2);
- }
-}
-
-static char *ipaq_micro_str(u8 *wchar, u8 len)
-{
- char retstr[256] = { 0 };
- u8 i;
-
- for (i = 0; i < len / 2; i++)
- retstr[i] = wchar[i * 2];
- return kstrdup(retstr, GFP_KERNEL);
-}
-
-static u16 ipaq_micro_to_u16(u8 *data)
-{
- return data[1] << 8 | data[0];
-}
-
-static void __init ipaq_micro_eeprom_dump(struct ipaq_micro *micro)
-{
- u8 dump[256];
- char *str;
-
- ipaq_micro_eeprom_read(micro, 0, 128, dump);
- str = ipaq_micro_str(dump, 10);
- if (str) {
- dev_info(micro->dev, "HW version %s\n", str);
- kfree(str);
- }
- str = ipaq_micro_str(dump+10, 40);
- if (str) {
- dev_info(micro->dev, "serial number: %s\n", str);
- /* Feed the random pool with this */
- add_device_randomness(str, strlen(str));
- kfree(str);
- }
- str = ipaq_micro_str(dump+50, 20);
- if (str) {
- dev_info(micro->dev, "module ID: %s\n", str);
- kfree(str);
- }
- str = ipaq_micro_str(dump+70, 10);
- if (str) {
- dev_info(micro->dev, "product revision: %s\n", str);
- kfree(str);
- }
- dev_info(micro->dev, "product ID: %u\n", ipaq_micro_to_u16(dump+80));
- dev_info(micro->dev, "frame rate: %u fps\n",
- ipaq_micro_to_u16(dump+82));
- dev_info(micro->dev, "page mode: %u\n", ipaq_micro_to_u16(dump+84));
- dev_info(micro->dev, "country ID: %u\n", ipaq_micro_to_u16(dump+86));
- dev_info(micro->dev, "color display: %s\n",
- str_yes_no(ipaq_micro_to_u16(dump + 88)));
- dev_info(micro->dev, "ROM size: %u MiB\n", ipaq_micro_to_u16(dump+90));
- dev_info(micro->dev, "RAM size: %u KiB\n", ipaq_micro_to_u16(dump+92));
- dev_info(micro->dev, "screen: %u x %u\n",
- ipaq_micro_to_u16(dump+94), ipaq_micro_to_u16(dump+96));
-}
-
-static void micro_tx_chars(struct ipaq_micro *micro)
-{
- struct ipaq_micro_txdev *tx = µ->tx;
- u32 val;
-
- while ((tx->index < tx->len) &&
- (readl(micro->base + UTSR1) & UTSR1_TNF)) {
- writel(tx->buf[tx->index], micro->base + UTDR);
- tx->index++;
- }
-
- /* Stop interrupts */
- val = readl(micro->base + UTCR3);
- val &= ~UTCR3_TIE;
- writel(val, micro->base + UTCR3);
-}
-
-static void micro_reset_comm(struct ipaq_micro *micro)
-{
- struct ipaq_micro_rxdev *rx = µ->rx;
- u32 val;
-
- if (micro->msg)
- complete(µ->msg->ack);
-
- /* Initialize Serial channel protocol frame */
- rx->state = STATE_SOF; /* Reset the state machine */
-
- /* Set up interrupts */
- writel(0x01, micro->sdlc + 0x0); /* Select UART mode */
-
- /* Clean up CR3 */
- writel(0x0, micro->base + UTCR3);
-
- /* Format: 8N1 */
- writel(UTCR0_8BitData | UTCR0_1StpBit, micro->base + UTCR0);
-
- /* Baud rate: 115200 */
- writel(0x0, micro->base + UTCR1);
- writel(0x1, micro->base + UTCR2);
-
- /* Clear SR0 */
- writel(0xff, micro->base + UTSR0);
-
- /* Enable RX int, disable TX int */
- writel(UTCR3_TXE | UTCR3_RXE | UTCR3_RIE, micro->base + UTCR3);
- val = readl(micro->base + UTCR3);
- val &= ~UTCR3_TIE;
- writel(val, micro->base + UTCR3);
-}
-
-static irqreturn_t micro_serial_isr(int irq, void *dev_id)
-{
- struct ipaq_micro *micro = dev_id;
- struct ipaq_micro_txdev *tx = µ->tx;
- u32 status;
-
- status = readl(micro->base + UTSR0);
- do {
- if (status & (UTSR0_RID | UTSR0_RFS)) {
- if (status & UTSR0_RID)
- /* Clear the Receiver IDLE bit */
- writel(UTSR0_RID, micro->base + UTSR0);
- micro_rx_chars(micro);
- }
-
- /* Clear break bits */
- if (status & (UTSR0_RBB | UTSR0_REB))
- writel(status & (UTSR0_RBB | UTSR0_REB),
- micro->base + UTSR0);
-
- if (status & UTSR0_TFS)
- micro_tx_chars(micro);
-
- status = readl(micro->base + UTSR0);
-
- } while (((tx->index < tx->len) && (status & UTSR0_TFS)) ||
- (status & (UTSR0_RFS | UTSR0_RID)));
-
- return IRQ_HANDLED;
-}
-
-static const struct mfd_cell micro_cells[] = {
- { .name = "ipaq-micro-backlight", },
- { .name = "ipaq-micro-battery", },
- { .name = "ipaq-micro-keys", },
- { .name = "ipaq-micro-ts", },
- { .name = "ipaq-micro-leds", },
-};
-
-static int __maybe_unused micro_resume(struct device *dev)
-{
- struct ipaq_micro *micro = dev_get_drvdata(dev);
-
- micro_reset_comm(micro);
- mdelay(10);
-
- return 0;
-}
-
-static int __init micro_probe(struct platform_device *pdev)
-{
- struct ipaq_micro *micro;
- int ret;
- int irq;
-
- micro = devm_kzalloc(&pdev->dev, sizeof(*micro), GFP_KERNEL);
- if (!micro)
- return -ENOMEM;
-
- micro->dev = &pdev->dev;
-
- micro->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- if (IS_ERR(micro->base))
- return PTR_ERR(micro->base);
-
- micro->sdlc = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(micro->sdlc))
- return PTR_ERR(micro->sdlc);
-
- micro_reset_comm(micro);
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return -EINVAL;
- ret = devm_request_irq(&pdev->dev, irq, micro_serial_isr,
- IRQF_SHARED, "ipaq-micro",
- micro);
- if (ret) {
- dev_err(&pdev->dev, "unable to grab serial port IRQ\n");
- return ret;
- } else
- dev_info(&pdev->dev, "grabbed serial port IRQ\n");
-
- spin_lock_init(µ->lock);
- INIT_LIST_HEAD(µ->queue);
- platform_set_drvdata(pdev, micro);
-
- ret = mfd_add_devices(&pdev->dev, pdev->id, micro_cells,
- ARRAY_SIZE(micro_cells), NULL, 0, NULL);
- if (ret) {
- dev_err(&pdev->dev, "error adding MFD cells");
- return ret;
- }
-
- /* Check version */
- ipaq_micro_get_version(micro);
- dev_info(&pdev->dev, "Atmel micro ASIC version %s\n", micro->version);
- ipaq_micro_eeprom_dump(micro);
-
- return 0;
-}
-
-static const struct dev_pm_ops micro_dev_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(NULL, micro_resume)
-};
-
-static struct platform_driver micro_device_driver = {
- .driver = {
- .name = "ipaq-h3xxx-micro",
- .pm = µ_dev_pm_ops,
- .suppress_bind_attrs = true,
- },
-};
-builtin_platform_driver_probe(micro_device_driver, micro_probe);
--
2.53.0
^ permalink raw reply related [flat|nested] 36+ messages in thread[parent not found: <20260909132153.1596191-12-arnd@kernel.org>]
* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
[not found] ` <20260909132153.1596191-12-arnd@kernel.org>
@ 2026-09-09 13:26 ` Mark Brown
2026-09-09 14:12 ` Guenter Roeck
` (2 subsequent siblings)
3 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2026-09-09 13:26 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
[-- Attachment #1: Type: text/plain, Size: 599 bytes --]
On Wed, Sep 09, 2026 at 03:21:48PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver was used on the i.MX31 ADS reference board from Freescale
> and the smdk6410 reference board from Samsung. Both used platform_data
> based driver probing and are now gone from the kernel.
>
> Since probing with devicetree has never been supported by wm8350,
> it is clear that nothing can use the driver on an upstream kernel,
> and it is unlikely that anyone is still interested in a devicetree
> conversion, so remove it.
Acked-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
[not found] ` <20260909132153.1596191-12-arnd@kernel.org>
2026-09-09 13:26 ` [PATCH 11/14] mfd: remove unused wm8350 driver Mark Brown
@ 2026-09-09 14:12 ` Guenter Roeck
2026-09-09 14:39 ` Charles Keepax
2026-09-09 15:47 ` Sebastian Reichel
3 siblings, 0 replies; 36+ messages in thread
From: Guenter Roeck @ 2026-09-09 14:12 UTC (permalink / raw)
To: Arnd Bergmann, Lee Jones, mfd
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, linux-hwmon,
linux-watchdog
On 9/9/26 06:21, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver was used on the i.MX31 ADS reference board from Freescale
> and the smdk6410 reference board from Samsung. Both used platform_data
> based driver probing and are now gone from the kernel.
>
> Since probing with devicetree has never been supported by wm8350,
> it is clear that nothing can use the driver on an upstream kernel,
> and it is unlikely that anyone is still interested in a devicetree
> conversion, so remove it.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Guenter Roeck <linux@roeck-us.net>
^ permalink raw reply [flat|nested] 36+ messages in thread* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
[not found] ` <20260909132153.1596191-12-arnd@kernel.org>
2026-09-09 13:26 ` [PATCH 11/14] mfd: remove unused wm8350 driver Mark Brown
2026-09-09 14:12 ` Guenter Roeck
@ 2026-09-09 14:39 ` Charles Keepax
2026-09-09 15:47 ` Sebastian Reichel
3 siblings, 0 replies; 36+ messages in thread
From: Charles Keepax @ 2026-09-09 14:39 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Sebastian Reichel,
Alexandre Belloni, Helge Deller, dri-devel, linux-doc,
linux-media, devicetree, linux-hwmon, patches, linux-watchdog,
linux-gpio, linux-iio, linux-input, linux-leds, linux-pm,
linux-rtc, linux-fbdev, linux-sound, linuxppc-dev, llvm
On Wed, Sep 09, 2026 at 03:21:48PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver was used on the i.MX31 ADS reference board from Freescale
> and the smdk6410 reference board from Samsung. Both used platform_data
> based driver probing and are now gone from the kernel.
>
> Since probing with devicetree has never been supported by wm8350,
> it is clear that nothing can use the driver on an upstream kernel,
> and it is unlikely that anyone is still interested in a devicetree
> conversion, so remove it.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Thanks,
Charles
^ permalink raw reply [flat|nested] 36+ messages in thread* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
[not found] ` <20260909132153.1596191-12-arnd@kernel.org>
` (2 preceding siblings ...)
2026-09-09 14:39 ` Charles Keepax
@ 2026-09-09 15:47 ` Sebastian Reichel
3 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2026-09-09 15:47 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
[-- Attachment #1: Type: text/plain, Size: 4634 bytes --]
Hi,
On Wed, Sep 09, 2026 at 03:21:48PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver was used on the i.MX31 ADS reference board from Freescale
> and the smdk6410 reference board from Samsung. Both used platform_data
> based driver probing and are now gone from the kernel.
>
> Since probing with devicetree has never been supported by wm8350,
> it is clear that nothing can use the driver on an upstream kernel,
> and it is unlikely that anyone is still interested in a devicetree
> conversion, so remove it.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> Documentation/hwmon/index.rst | 1 -
> Documentation/hwmon/wm8350.rst | 30 -
> .../watchdog/watchdog-parameters.rst | 7 -
> MAINTAINERS | 1 -
> drivers/gpio/Kconfig | 7 -
> drivers/gpio/Makefile | 1 -
> drivers/gpio/gpio-wm8350.c | 144 --
> drivers/hwmon/Kconfig | 10 -
> drivers/hwmon/Makefile | 1 -
> drivers/hwmon/wm8350-hwmon.c | 92 -
> drivers/leds/Kconfig | 8 -
> drivers/leds/Makefile | 1 -
> drivers/leds/leds-wm8350.c | 267 ---
> drivers/mfd/Kconfig | 15 -
> drivers/mfd/Makefile | 4 -
> drivers/mfd/wm8350-core.c | 444 -----
> drivers/mfd/wm8350-gpio.c | 217 ---
> drivers/mfd/wm8350-i2c.c | 64 -
> drivers/mfd/wm8350-irq.c | 542 ------
> drivers/mfd/wm8350-regmap.c | 335 ----
> drivers/power/supply/Kconfig | 7 -
> drivers/power/supply/Makefile | 1 -
> drivers/power/supply/wm8350_power.c | 590 ------
> drivers/regulator/Kconfig | 7 -
> drivers/regulator/Makefile | 1 -
> drivers/regulator/wm8350-regulator.c | 1330 -------------
> drivers/rtc/Kconfig | 10 -
> drivers/rtc/Makefile | 1 -
> drivers/rtc/rtc-wm8350.c | 474 -----
> drivers/watchdog/Kconfig | 8 -
> drivers/watchdog/Makefile | 1 -
> drivers/watchdog/wm8350_wdt.c | 171 --
> include/linux/mfd/wm8350/audio.h | 620 -------
> include/linux/mfd/wm8350/comparator.h | 171 --
> include/linux/mfd/wm8350/core.h | 692 -------
> include/linux/mfd/wm8350/gpio.h | 356 ----
> include/linux/mfd/wm8350/pmic.h | 775 --------
> include/linux/mfd/wm8350/rtc.h | 265 ---
> include/linux/mfd/wm8350/supply.h | 129 --
> include/linux/mfd/wm8350/wdt.h | 24 -
> sound/soc/codecs/Kconfig | 5 -
> sound/soc/codecs/Makefile | 2 -
> sound/soc/codecs/wm8350.c | 1638 -----------------
> sound/soc/codecs/wm8350.h | 25 -
> 44 files changed, 9494 deletions(-)
> delete mode 100644 Documentation/hwmon/wm8350.rst
> delete mode 100644 drivers/gpio/gpio-wm8350.c
> delete mode 100644 drivers/hwmon/wm8350-hwmon.c
> delete mode 100644 drivers/leds/leds-wm8350.c
> delete mode 100644 drivers/mfd/wm8350-core.c
> delete mode 100644 drivers/mfd/wm8350-gpio.c
> delete mode 100644 drivers/mfd/wm8350-i2c.c
> delete mode 100644 drivers/mfd/wm8350-irq.c
> delete mode 100644 drivers/mfd/wm8350-regmap.c
> delete mode 100644 drivers/power/supply/wm8350_power.c
> delete mode 100644 drivers/regulator/wm8350-regulator.c
> delete mode 100644 drivers/rtc/rtc-wm8350.c
> delete mode 100644 drivers/watchdog/wm8350_wdt.c
> delete mode 100644 include/linux/mfd/wm8350/audio.h
> delete mode 100644 include/linux/mfd/wm8350/comparator.h
> delete mode 100644 include/linux/mfd/wm8350/core.h
> delete mode 100644 include/linux/mfd/wm8350/gpio.h
> delete mode 100644 include/linux/mfd/wm8350/pmic.h
> delete mode 100644 include/linux/mfd/wm8350/rtc.h
> delete mode 100644 include/linux/mfd/wm8350/supply.h
> delete mode 100644 include/linux/mfd/wm8350/wdt.h
> delete mode 100644 sound/soc/codecs/wm8350.c
> delete mode 100644 sound/soc/codecs/wm8350.h
Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-- Sebastian
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
[parent not found: <20260909132153.1596191-5-arnd@kernel.org>]
* Re: [PATCH 04/14] mfd: remove unused wm8400 driver
[not found] ` <20260909132153.1596191-5-arnd@kernel.org>
@ 2026-09-09 13:27 ` Mark Brown
2026-09-09 14:38 ` Charles Keepax
1 sibling, 0 replies; 36+ messages in thread
From: Mark Brown @ 2026-09-09 13:27 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
[-- Attachment #1: Type: text/plain, Size: 349 bytes --]
On Wed, Sep 09, 2026 at 03:21:41PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver requires a platform_data definition, which does not exist
> in the kernel.
>
> According to Mark Brown, the hardware supported by this driver was never
> shipped in production.
Acked-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread* Re: [PATCH 04/14] mfd: remove unused wm8400 driver
[not found] ` <20260909132153.1596191-5-arnd@kernel.org>
2026-09-09 13:27 ` [PATCH 04/14] mfd: remove unused wm8400 driver Mark Brown
@ 2026-09-09 14:38 ` Charles Keepax
1 sibling, 0 replies; 36+ messages in thread
From: Charles Keepax @ 2026-09-09 14:38 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Dmitry Torokhov, Pavel Machek,
Michael Hennerich, Support Opensource, Sebastian Reichel,
Alexandre Belloni, Helge Deller, dri-devel, linux-doc,
linux-media, devicetree, linux-hwmon, patches, linux-watchdog,
linux-gpio, linux-iio, linux-input, linux-leds, linux-pm,
linux-rtc, linux-fbdev, linux-sound, linuxppc-dev, llvm
On Wed, Sep 09, 2026 at 03:21:41PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> This driver requires a platform_data definition, which does not exist
> in the kernel.
>
> According to Mark Brown, the hardware supported by this driver was never
> shipped in production.
>
> Since this is clearly unused, remove it.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Thanks,
Charles
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 00/14] mfd: unused driver purge
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (12 preceding siblings ...)
[not found] ` <20260909132153.1596191-5-arnd@kernel.org>
@ 2026-09-09 14:03 ` Bartosz Golaszewski
2026-09-09 17:26 ` Dmitry Torokhov
14 siblings, 0 replies; 36+ messages in thread
From: Bartosz Golaszewski @ 2026-09-09 14:03 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, Arnd Bergmann, Daniel Thompson,
Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guenter Roeck,
Linus Walleij, Bartosz Golaszewski, Jonathan Cameron,
Dmitry Torokhov, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm, Lee Jones, mfd
On Wed, 9 Sep 2026 15:21:37 +0200, Arnd Bergmann <arnd@kernel.org> said:
> From: Arnd Bergmann <arnd@arndb.de>
>
> As part of my cleanup of old platforms, I had a look at all drivers that
> may have become unused because the last platform_data or DT definition
> was removed, or because of unmet Kconfig dependencies.
>
> These are all the mfd drivers I found. The first ten in the list
> actually turned out to have been unusable long before my series, and
> I have added explanations on how I determined this in each patch. The
> last four patches are still in use in linux-7.3 but become unused after
> my series [1] that I hope to get merged for 7.4.
>
> Somewhat unorthodox, I took a shortcut here and remove both the mfd drivers
> and the corresponding subsystem drivers (gpio, hwmon, iio, input, led,
> media, power, regulator, rtc, video, watchdog, asoc) in a combined patch,
> to simplify the interdependencies: removing just the mfd driver would
> leave unselectable or broken drivers in other subsystems. I also have
> additional patches for each of the other subsystems, currently a total
> of 300 patches, many of which still need better testing or proper
> changelog texts.
>
> Please let me know if you all think this approach is ok, or if I should
> explode this further and turn these 14 patches into 70 individual ones
> by splitting them per subsystem.
>
> See [2] for the current state of the overall series.
>
> Arnd
>
> [1] https://lore.kernel.org/lkml/20260908152808.3928630-1-arnd@kernel.org/
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/log/?h=board-remove-7.3
>
> Arnd Bergmann (14):
> mfd: remove unused 88pm80x driver
> mfd: remove unused rdc321x southbridge support
> mfd: remove unused si476x driver
> mfd: remove unused wm8400 driver
> mfd: remove unused adp5520 driver
> mfd: remove unused da903x driver
> mfd: remove unused lp8788 driver
> mfd: remove unused aat2870 driver
> mfd: remove unused lm3533 driver
> mfd: remove unused rc5t583 driver
> mfd: remove unused wm8350 driver
> mfd: remove unused mcp-sa11x0/ucb1x00 driver
> mfd: remove unused menelaus driver
> mfd: remove unused iPaq micro driver
>
> .../ABI/testing/sysfs-class-backlight | 11 -
> Documentation/admin-guide/devices.txt | 1 -
> .../admin-guide/media/radio-cardlist.rst | 1 -
> Documentation/admin-guide/media/si476x.rst | 160 --
> .../admin-guide/media/v4l-drivers.rst | 1 -
> .../devicetree/bindings/regulator/88pm800.txt | 38 -
> Documentation/hwmon/index.rst | 1 -
> Documentation/hwmon/wm8350.rst | 30 -
> .../watchdog/watchdog-parameters.rst | 7 -
> MAINTAINERS | 14 -
> drivers/gpio/Kconfig | 22 -
> drivers/gpio/Makefile | 3 -
> drivers/gpio/gpio-adp5520.c | 169 --
> drivers/gpio/gpio-rdc321x.c | 199 --
> drivers/gpio/gpio-wm8350.c | 144 --
For GPIO:
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 36+ messages in thread* Re: [PATCH 00/14] mfd: unused driver purge
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (13 preceding siblings ...)
2026-09-09 14:03 ` [PATCH 00/14] mfd: unused driver purge Bartosz Golaszewski
@ 2026-09-09 17:26 ` Dmitry Torokhov
14 siblings, 0 replies; 36+ messages in thread
From: Dmitry Torokhov @ 2026-09-09 17:26 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, mfd, linux-kernel, linux-arm-kernel, Arnd Bergmann,
Daniel Thompson, Jingoo Han, Mauro Carvalho Chehab, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Guenter Roeck, Linus Walleij, Bartosz Golaszewski,
Jonathan Cameron, Pavel Machek, Michael Hennerich,
Support Opensource, Sebastian Reichel, Alexandre Belloni,
Helge Deller, dri-devel, linux-doc, linux-media, devicetree,
linux-hwmon, patches, linux-watchdog, linux-gpio, linux-iio,
linux-input, linux-leds, linux-pm, linux-rtc, linux-fbdev,
linux-sound, linuxppc-dev, llvm
On Wed, Sep 09, 2026 at 03:21:37PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> As part of my cleanup of old platforms, I had a look at all drivers that
> may have become unused because the last platform_data or DT definition
> was removed, or because of unmet Kconfig dependencies.
>
> These are all the mfd drivers I found. The first ten in the list
> actually turned out to have been unusable long before my series, and
> I have added explanations on how I determined this in each patch. The
> last four patches are still in use in linux-7.3 but become unused after
> my series [1] that I hope to get merged for 7.4.
>
> Somewhat unorthodox, I took a shortcut here and remove both the mfd drivers
> and the corresponding subsystem drivers (gpio, hwmon, iio, input, led,
> media, power, regulator, rtc, video, watchdog, asoc) in a combined patch,
> to simplify the interdependencies: removing just the mfd driver would
> leave unselectable or broken drivers in other subsystems. I also have
> additional patches for each of the other subsystems, currently a total
> of 300 patches, many of which still need better testing or proper
> changelog texts.
>
> Please let me know if you all think this approach is ok, or if I should
> explode this further and turn these 14 patches into 70 individual ones
> by splitting them per subsystem.
Sounds good to me, especially if Lee makes an immutable branch from this
pull so we can all pull it in...
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 36+ messages in thread