* [PATCH 00/14] mfd: unused driver purge
@ 2026-09-09 13:21 Arnd Bergmann
2026-09-09 13:21 ` [PATCH 01/14] mfd: remove unused 88pm80x driver Arnd Bergmann
` (15 more replies)
0 siblings, 16 replies; 31+ 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>
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 --
drivers/hwmon/Kconfig | 10 -
drivers/hwmon/Makefile | 1 -
drivers/hwmon/wm8350-hwmon.c | 92 -
drivers/iio/adc/Kconfig | 9 -
drivers/iio/adc/Makefile | 1 -
drivers/iio/adc/lp8788_adc.c | 219 ---
drivers/iio/light/Kconfig | 17 -
drivers/iio/light/Makefile | 1 -
drivers/iio/light/lm3533-als.c | 922 ----------
drivers/input/keyboard/Kconfig | 10 -
drivers/input/keyboard/Makefile | 1 -
drivers/input/keyboard/adp5520-keys.c | 191 --
drivers/input/misc/88pm80x_onkey.c | 152 --
drivers/input/misc/Kconfig | 10 -
drivers/input/misc/Makefile | 1 -
drivers/input/touchscreen/Kconfig | 13 -
drivers/input/touchscreen/Makefile | 1 -
drivers/input/touchscreen/da9034-ts.c | 365 ----
drivers/leds/Kconfig | 47 -
drivers/leds/Makefile | 5 -
drivers/leds/leds-adp5520.c | 195 --
drivers/leds/leds-da903x.c | 145 --
drivers/leds/leds-lm3533.c | 755 --------
drivers/leds/leds-lp8788.c | 171 --
drivers/leds/leds-wm8350.c | 267 ---
drivers/media/radio/Kconfig | 17 -
drivers/media/radio/Makefile | 1 -
drivers/media/radio/radio-si476x.c | 1523 ---------------
drivers/mfd/88pm800.c | 619 -------
drivers/mfd/88pm805.c | 275 ---
drivers/mfd/88pm80x.c | 159 --
drivers/mfd/Kconfig | 186 --
drivers/mfd/Makefile | 28 -
drivers/mfd/aat2870-core.c | 458 -----
drivers/mfd/adp5520.c | 346 ----
drivers/mfd/da903x.c | 565 ------
drivers/mfd/ipaq-micro.c | 442 -----
drivers/mfd/lm3533-core.c | 635 -------
drivers/mfd/lm3533-ctrlbank.c | 162 --
drivers/mfd/lp8788-irq.c | 194 --
drivers/mfd/lp8788.c | 246 ---
drivers/mfd/mcp-core.c | 235 ---
drivers/mfd/mcp-sa11x0.c | 304 ---
drivers/mfd/menelaus.c | 1251 -------------
drivers/mfd/rc5t583-irq.c | 383 ----
drivers/mfd/rc5t583.c | 299 ---
drivers/mfd/rdc321x-southbridge.c | 96 -
drivers/mfd/si476x-cmd.c | 1543 ----------------
drivers/mfd/si476x-i2c.c | 861 ---------
drivers/mfd/si476x-prop.c | 233 ---
drivers/mfd/ucb1x00-assabet.c | 175 --
drivers/mfd/ucb1x00-core.c | 795 --------
drivers/mfd/ucb1x00-ts.c | 445 -----
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/mfd/wm8400-core.c | 163 --
drivers/power/supply/Kconfig | 22 -
drivers/power/supply/Makefile | 3 -
drivers/power/supply/da9030_battery.c | 581 ------
drivers/power/supply/lp8788-charger.c | 730 --------
drivers/power/supply/wm8350_power.c | 590 ------
drivers/regulator/88pm800-regulator.c | 287 ---
drivers/regulator/Kconfig | 55 -
drivers/regulator/Makefile | 8 -
drivers/regulator/aat2870-regulator.c | 201 --
drivers/regulator/da903x-regulator.c | 495 -----
drivers/regulator/lp8788-buck.c | 541 ------
drivers/regulator/lp8788-ldo.c | 640 -------
drivers/regulator/rc5t583-regulator.c | 171 --
drivers/regulator/wm8350-regulator.c | 1330 -------------
drivers/regulator/wm8400-regulator.c | 276 ---
drivers/rtc/Kconfig | 45 -
drivers/rtc/Makefile | 3 -
drivers/rtc/rtc-88pm80x.c | 340 ----
drivers/rtc/rtc-lp8788.c | 322 ----
drivers/rtc/rtc-rc5t583.c | 312 ----
drivers/rtc/rtc-wm8350.c | 474 -----
drivers/video/backlight/Kconfig | 41 -
drivers/video/backlight/Makefile | 5 -
drivers/video/backlight/aat2870_bl.c | 206 ---
drivers/video/backlight/adp5520_bl.c | 385 ----
drivers/video/backlight/da903x_bl.c | 160 --
drivers/video/backlight/lm3533_bl.c | 398 ----
drivers/video/backlight/lp8788_bl.c | 190 --
drivers/watchdog/Kconfig | 19 -
drivers/watchdog/Makefile | 2 -
drivers/watchdog/rdc321x_wdt.c | 281 ---
drivers/watchdog/wm8350_wdt.c | 171 --
include/linux/mfd/88pm80x.h | 370 ----
include/linux/mfd/aat2870.h | 164 --
include/linux/mfd/adp5520.h | 298 ---
include/linux/mfd/lm3533.h | 99 -
include/linux/mfd/lp8788-isink.h | 48 -
include/linux/mfd/lp8788.h | 289 ---
include/linux/mfd/mcp.h | 63 -
include/linux/mfd/menelaus.h | 41 -
include/linux/mfd/rc5t583.h | 369 ----
include/linux/mfd/rdc321x.h | 27 -
include/linux/mfd/si476x-core.h | 532 ------
include/linux/mfd/si476x-platform.h | 256 ---
include/linux/mfd/si476x-reports.h | 154 --
include/linux/mfd/ucb1x00.h | 261 ---
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 -
include/linux/mfd/wm8400-audio.h | 1174 ------------
include/linux/mfd/wm8400-private.h | 913 ---------
include/linux/mfd/wm8400.h | 27 -
include/linux/platform_data/mfd-mcp-sa11x0.h | 17 -
include/media/drv-intf/si476x.h | 28 -
include/uapi/linux/v4l2-controls.h | 4 +-
sound/soc/codecs/Kconfig | 16 -
sound/soc/codecs/Makefile | 6 -
sound/soc/codecs/si476x.c | 263 ---
sound/soc/codecs/wm8350.c | 1638 -----------------
sound/soc/codecs/wm8350.h | 25 -
sound/soc/codecs/wm8400.c | 1348 --------------
sound/soc/codecs/wm8400.h | 54 -
sound/soc/fsl/fsl-asoc-card.c | 8 -
142 files changed, 2 insertions(+), 39449 deletions(-)
delete mode 100644 Documentation/admin-guide/media/si476x.rst
delete mode 100644 Documentation/devicetree/bindings/regulator/88pm800.txt
delete mode 100644 Documentation/hwmon/wm8350.rst
delete mode 100644 drivers/gpio/gpio-adp5520.c
delete mode 100644 drivers/gpio/gpio-rdc321x.c
delete mode 100644 drivers/gpio/gpio-wm8350.c
delete mode 100644 drivers/hwmon/wm8350-hwmon.c
delete mode 100644 drivers/iio/adc/lp8788_adc.c
delete mode 100644 drivers/iio/light/lm3533-als.c
delete mode 100644 drivers/input/keyboard/adp5520-keys.c
delete mode 100644 drivers/input/misc/88pm80x_onkey.c
delete mode 100644 drivers/input/touchscreen/da9034-ts.c
delete mode 100644 drivers/leds/leds-adp5520.c
delete mode 100644 drivers/leds/leds-da903x.c
delete mode 100644 drivers/leds/leds-lm3533.c
delete mode 100644 drivers/leds/leds-lp8788.c
delete mode 100644 drivers/leds/leds-wm8350.c
delete mode 100644 drivers/media/radio/radio-si476x.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/mfd/aat2870-core.c
delete mode 100644 drivers/mfd/adp5520.c
delete mode 100644 drivers/mfd/da903x.c
delete mode 100644 drivers/mfd/ipaq-micro.c
delete mode 100644 drivers/mfd/lm3533-core.c
delete mode 100644 drivers/mfd/lm3533-ctrlbank.c
delete mode 100644 drivers/mfd/lp8788-irq.c
delete mode 100644 drivers/mfd/lp8788.c
delete mode 100644 drivers/mfd/mcp-core.c
delete mode 100644 drivers/mfd/mcp-sa11x0.c
delete mode 100644 drivers/mfd/menelaus.c
delete mode 100644 drivers/mfd/rc5t583-irq.c
delete mode 100644 drivers/mfd/rc5t583.c
delete mode 100644 drivers/mfd/rdc321x-southbridge.c
delete mode 100644 drivers/mfd/si476x-cmd.c
delete mode 100644 drivers/mfd/si476x-i2c.c
delete mode 100644 drivers/mfd/si476x-prop.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 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/mfd/wm8400-core.c
delete mode 100644 drivers/power/supply/da9030_battery.c
delete mode 100644 drivers/power/supply/lp8788-charger.c
delete mode 100644 drivers/power/supply/wm8350_power.c
delete mode 100644 drivers/regulator/88pm800-regulator.c
delete mode 100644 drivers/regulator/aat2870-regulator.c
delete mode 100644 drivers/regulator/da903x-regulator.c
delete mode 100644 drivers/regulator/lp8788-buck.c
delete mode 100644 drivers/regulator/lp8788-ldo.c
delete mode 100644 drivers/regulator/rc5t583-regulator.c
delete mode 100644 drivers/regulator/wm8350-regulator.c
delete mode 100644 drivers/regulator/wm8400-regulator.c
delete mode 100644 drivers/rtc/rtc-88pm80x.c
delete mode 100644 drivers/rtc/rtc-lp8788.c
delete mode 100644 drivers/rtc/rtc-rc5t583.c
delete mode 100644 drivers/rtc/rtc-wm8350.c
delete mode 100644 drivers/video/backlight/aat2870_bl.c
delete mode 100644 drivers/video/backlight/adp5520_bl.c
delete mode 100644 drivers/video/backlight/da903x_bl.c
delete mode 100644 drivers/video/backlight/lm3533_bl.c
delete mode 100644 drivers/video/backlight/lp8788_bl.c
delete mode 100644 drivers/watchdog/rdc321x_wdt.c
delete mode 100644 drivers/watchdog/wm8350_wdt.c
delete mode 100644 include/linux/mfd/88pm80x.h
delete mode 100644 include/linux/mfd/aat2870.h
delete mode 100644 include/linux/mfd/adp5520.h
delete mode 100644 include/linux/mfd/lm3533.h
delete mode 100644 include/linux/mfd/lp8788-isink.h
delete mode 100644 include/linux/mfd/lp8788.h
delete mode 100644 include/linux/mfd/mcp.h
delete mode 100644 include/linux/mfd/menelaus.h
delete mode 100644 include/linux/mfd/rc5t583.h
delete mode 100644 include/linux/mfd/rdc321x.h
delete mode 100644 include/linux/mfd/si476x-core.h
delete mode 100644 include/linux/mfd/si476x-platform.h
delete mode 100644 include/linux/mfd/si476x-reports.h
delete mode 100644 include/linux/mfd/ucb1x00.h
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 include/linux/mfd/wm8400-audio.h
delete mode 100644 include/linux/mfd/wm8400-private.h
delete mode 100644 include/linux/mfd/wm8400.h
delete mode 100644 include/linux/platform_data/mfd-mcp-sa11x0.h
delete mode 100644 include/media/drv-intf/si476x.h
delete mode 100644 sound/soc/codecs/si476x.c
delete mode 100644 sound/soc/codecs/wm8350.c
delete mode 100644 sound/soc/codecs/wm8350.h
delete mode 100644 sound/soc/codecs/wm8400.c
delete mode 100644 sound/soc/codecs/wm8400.h
--
2.53.0
Cc: Lee Jones <lee@kernel.org>
Cc: Daniel Thompson <danielt@kernel.org>
Cc: Jingoo Han <jingoohan1@gmail.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Bartosz Golaszewski <brgl@kernel.org>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Pavel Machek <pavel@kernel.org>
Cc: Michael Hennerich <michael.hennerich@analog.com>
Cc: Support Opensource <support.opensource@diasemi.com>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Helge Deller <deller@gmx.de>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-media@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-hwmon@vger.kernel.org
Cc: patches@opensource.cirrus.com
Cc: linux-watchdog@vger.kernel.org
Cc: linux-gpio@vger.kernel.org
Cc: linux-iio@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-leds@vger.kernel.org
Cc: mfd@lists.linux.dev
Cc: linux-pm@vger.kernel.org
Cc: linux-rtc@vger.kernel.org
Cc: linux-fbdev@vger.kernel.org
Cc: linux-sound@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: llvm@lists.linux.dev
^ permalink raw reply [flat|nested] 31+ messages in thread
* [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-09 13:44 ` Alexandre Belloni
2026-09-11 7:24 ` Krzysztof Kozlowski
2026-09-09 13:21 ` [PATCH 02/14] mfd: remove unused rdc321x southbridge support Arnd Bergmann
` (14 subsequent siblings)
15 siblings, 2 replies; 31+ 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 [flat|nested] 31+ 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 03/14] mfd: remove unused si476x driver Arnd Bergmann
` (13 subsequent siblings)
15 siblings, 1 reply; 31+ 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 [flat|nested] 31+ messages in thread
* [PATCH 03/14] mfd: remove unused si476x 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 04/14] mfd: remove unused wm8400 driver Arnd Bergmann
` (12 subsequent siblings)
15 siblings, 0 replies; 31+ 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 si476x driver was added in linux-3.9 without devicetree
support, and has always failed the probe function in the
absence of a si476x_platform_data definition.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
.../admin-guide/media/radio-cardlist.rst | 1 -
Documentation/admin-guide/media/si476x.rst | 160 --
.../admin-guide/media/v4l-drivers.rst | 1 -
drivers/media/radio/Kconfig | 17 -
drivers/media/radio/Makefile | 1 -
drivers/media/radio/radio-si476x.c | 1523 ----------------
drivers/mfd/Kconfig | 13 -
drivers/mfd/Makefile | 3 -
drivers/mfd/si476x-cmd.c | 1543 -----------------
drivers/mfd/si476x-i2c.c | 861 ---------
drivers/mfd/si476x-prop.c | 233 ---
include/linux/mfd/si476x-core.h | 532 ------
include/linux/mfd/si476x-platform.h | 256 ---
include/linux/mfd/si476x-reports.h | 154 --
include/media/drv-intf/si476x.h | 28 -
include/uapi/linux/v4l2-controls.h | 4 +-
sound/soc/codecs/Kconfig | 5 -
sound/soc/codecs/Makefile | 2 -
sound/soc/codecs/si476x.c | 263 ---
sound/soc/fsl/fsl-asoc-card.c | 8 -
20 files changed, 2 insertions(+), 5606 deletions(-)
delete mode 100644 Documentation/admin-guide/media/si476x.rst
delete mode 100644 drivers/media/radio/radio-si476x.c
delete mode 100644 drivers/mfd/si476x-cmd.c
delete mode 100644 drivers/mfd/si476x-i2c.c
delete mode 100644 drivers/mfd/si476x-prop.c
delete mode 100644 include/linux/mfd/si476x-core.h
delete mode 100644 include/linux/mfd/si476x-platform.h
delete mode 100644 include/linux/mfd/si476x-reports.h
delete mode 100644 include/media/drv-intf/si476x.h
delete mode 100644 sound/soc/codecs/si476x.c
diff --git a/Documentation/admin-guide/media/radio-cardlist.rst b/Documentation/admin-guide/media/radio-cardlist.rst
index cec724256812..244ff59fb6b2 100644
--- a/Documentation/admin-guide/media/radio-cardlist.rst
+++ b/Documentation/admin-guide/media/radio-cardlist.rst
@@ -23,7 +23,6 @@ radio-sf16fmr2 SF16-FMR2/SF16-FMD2 Radio
radio-shark Griffin radioSHARK USB radio receiver
shark2 Griffin radioSHARK2 USB radio receiver
radio-si470x-common Silicon Labs Si470x FM Radio Receiver
-radio-si476x Silicon Laboratories Si476x I2C FM Radio
radio-tea5764 TEA5764 I2C FM radio
tef6862 TEF6862 Car Radio Enhanced Selectivity Tuner
radio-terratec TerraTec ActiveRadio ISA Standalone
diff --git a/Documentation/admin-guide/media/si476x.rst b/Documentation/admin-guide/media/si476x.rst
deleted file mode 100644
index c8882ee9f208..000000000000
--- a/Documentation/admin-guide/media/si476x.rst
+++ /dev/null
@@ -1,160 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-
-The SI476x Driver
-=================
-
-Copyright |copy| 2013 Andrey Smirnov <andrew.smirnov@gmail.com>
-
-TODO for the driver
--------------------
-
-- According to the SiLabs' datasheet it is possible to update the
- firmware of the radio chip in the run-time, thus bringing it to the
- most recent version. Unfortunately I couldn't find any mentioning of
- the said firmware update for the old chips that I tested the driver
- against, so for chips like that the driver only exposes the old
- functionality.
-
-
-Parameters exposed over debugfs
--------------------------------
-SI476x allow user to get multiple characteristics that can be very
-useful for EoL testing/RF performance estimation, parameters that have
-very little to do with V4L2 subsystem. Such parameters are exposed via
-debugfs and can be accessed via regular file I/O operations.
-
-The drivers exposes following files:
-
-* /sys/kernel/debug/<device-name>/acf
- This file contains ACF(Automatically Controlled Features) status
- information. The contents of the file is binary data of the
- following layout:
-
- .. tabularcolumns:: |p{7ex}|p{12ex}|L|
-
- ============= ============== ====================================
- Offset Name Description
- ============= ============== ====================================
- 0x00 blend_int Flag, set when stereo separation has
- crossed below the blend threshold
- 0x01 hblend_int Flag, set when HiBlend cutoff
- frequency is lower than threshold
- 0x02 hicut_int Flag, set when HiCut cutoff
- frequency is lower than threshold
- 0x03 chbw_int Flag, set when channel filter
- bandwidth is less than threshold
- 0x04 softmute_int Flag indicating that softmute
- attenuation has increased above
- softmute threshold
- 0x05 smute 0 - Audio is not soft muted
- 1 - Audio is soft muted
- 0x06 smattn Soft mute attenuation level in dB
- 0x07 chbw Channel filter bandwidth in kHz
- 0x08 hicut HiCut cutoff frequency in units of
- 100Hz
- 0x09 hiblend HiBlend cutoff frequency in units
- of 100 Hz
- 0x10 pilot 0 - Stereo pilot is not present
- 1 - Stereo pilot is present
- 0x11 stblend Stereo blend in %
- ============= ============== ====================================
-
-
-* /sys/kernel/debug/<device-name>/rds_blckcnt
- This file contains statistics about RDS receptions. It's binary data
- has the following layout:
-
- .. tabularcolumns:: |p{7ex}|p{12ex}|L|
-
- ============= ============== ====================================
- Offset Name Description
- ============= ============== ====================================
- 0x00 expected Number of expected RDS blocks
- 0x02 received Number of received RDS blocks
- 0x04 uncorrectable Number of uncorrectable RDS blocks
- ============= ============== ====================================
-
-* /sys/kernel/debug/<device-name>/agc
- This file contains information about parameters pertaining to
- AGC(Automatic Gain Control)
-
- The layout is:
-
- .. tabularcolumns:: |p{7ex}|p{12ex}|L|
-
- ============= ============== ====================================
- Offset Name Description
- ============= ============== ====================================
- 0x00 mxhi 0 - FM Mixer PD high threshold is
- not tripped
- 1 - FM Mixer PD high threshold is
- tripped
- 0x01 mxlo ditto for FM Mixer PD low
- 0x02 lnahi ditto for FM LNA PD high
- 0x03 lnalo ditto for FM LNA PD low
- 0x04 fmagc1 FMAGC1 attenuator resistance
- (see datasheet for more detail)
- 0x05 fmagc2 ditto for FMAGC2
- 0x06 pgagain PGA gain in dB
- 0x07 fmwblang FM/WB LNA Gain in dB
- ============= ============== ====================================
-
-* /sys/kernel/debug/<device-name>/rsq
- This file contains information about parameters pertaining to
- RSQ(Received Signal Quality)
-
- The layout is:
-
- .. tabularcolumns:: |p{7ex}|p{12ex}|p{60ex}|
-
- ============= ============== ====================================
- Offset Name Description
- ============= ============== ====================================
- 0x00 multhint 0 - multipath value has not crossed
- the Multipath high threshold
- 1 - multipath value has crossed
- the Multipath high threshold
- 0x01 multlint ditto for Multipath low threshold
- 0x02 snrhint 0 - received signal's SNR has not
- crossed high threshold
- 1 - received signal's SNR has
- crossed high threshold
- 0x03 snrlint ditto for low threshold
- 0x04 rssihint ditto for RSSI high threshold
- 0x05 rssilint ditto for RSSI low threshold
- 0x06 bltf Flag indicating if seek command
- reached/wrapped seek band limit
- 0x07 snr_ready Indicates that SNR metrics is ready
- 0x08 rssiready ditto for RSSI metrics
- 0x09 injside 0 - Low-side injection is being used
- 1 - High-side injection is used
- 0x10 afcrl Flag indicating if AFC rails
- 0x11 valid Flag indicating if channel is valid
- 0x12 readfreq Current tuned frequency
- 0x14 freqoff Signed frequency offset in units of
- 2ppm
- 0x15 rssi Signed value of RSSI in dBuV
- 0x16 snr Signed RF SNR in dB
- 0x17 issi Signed Image Strength Signal
- indicator
- 0x18 lassi Signed Low side adjacent Channel
- Strength indicator
- 0x19 hassi ditto for High side
- 0x20 mult Multipath indicator
- 0x21 dev Frequency deviation
- 0x24 assi Adjacent channel SSI
- 0x25 usn Ultrasonic noise indicator
- 0x26 pilotdev Pilot deviation in units of 100 Hz
- 0x27 rdsdev ditto for RDS
- 0x28 assidev ditto for ASSI
- 0x29 strongdev Frequency deviation
- 0x30 rdspi RDS PI code
- ============= ============== ====================================
-
-* /sys/kernel/debug/<device-name>/rsq_primary
- This file contains information about parameters pertaining to
- RSQ(Received Signal Quality) for primary tuner only. Layout is as
- the one above.
diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst
index 4621eae9fa1e..d131146f5869 100644
--- a/Documentation/admin-guide/media/v4l-drivers.rst
+++ b/Documentation/admin-guide/media/v4l-drivers.rst
@@ -33,7 +33,6 @@ Video4Linux (V4L) driver-specific documentation
saa7134
si470x
si4713
- si476x
vimc
visl
vivid
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index bbbdd054ba64..7b757f34463e 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -79,23 +79,6 @@ config RADIO_SHARK2
config RADIO_SI4713
tristate "Silicon Labs Si4713 FM Radio with RDS Transmitter support"
-config RADIO_SI476X
- tristate "Silicon Laboratories Si476x I2C FM Radio"
- depends on I2C
- depends on MFD_SI476X_CORE
- depends on SND_SOC
- select SND_SOC_SI476X
- help
- Choose Y here if you have this FM radio chip.
-
- In order to control your radio card, you will need to use programs
- that are compatible with the Video For Linux 2 API. Information on
- this API and pointers to "v4l2" programs may be found at
- <file:Documentation/userspace-api/media/index.rst>.
-
- To compile this driver as a module, choose M here: the
- module will be called radio-si476x.
-
config RADIO_TEA575X
tristate
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index f54693ebdb30..ea948520382d 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_RADIO_SHARK2) += shark2.o
obj-$(CONFIG_RADIO_SHARK) += radio-shark.o
obj-$(CONFIG_RADIO_SI470X) += si470x/
obj-$(CONFIG_RADIO_SI4713) += si4713/
-obj-$(CONFIG_RADIO_SI476X) += radio-si476x.o
obj-$(CONFIG_RADIO_TEA575X) += tea575x.o
obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
deleted file mode 100644
index bfe89782dce4..000000000000
--- a/drivers/media/radio/radio-si476x.c
+++ /dev/null
@@ -1,1523 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * drivers/media/radio/radio-si476x.c -- V4L2 driver for SI476X chips
- *
- * Copyright (C) 2012 Innovative Converged Devices(ICD)
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/atomic.h>
-#include <linux/videodev2.h>
-#include <linux/mutex.h>
-#include <linux/debugfs.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-device.h>
-
-#include <media/drv-intf/si476x.h>
-#include <linux/mfd/si476x-core.h>
-
-#define FM_FREQ_RANGE_LOW 64000000
-#define FM_FREQ_RANGE_HIGH 108000000
-
-#define AM_FREQ_RANGE_LOW 520000
-#define AM_FREQ_RANGE_HIGH 30000000
-
-#define PWRLINEFLTR (1 << 8)
-
-#define FREQ_MUL (10000000 / 625)
-
-#define SI476X_PHDIV_STATUS_LINK_LOCKED(status) (0x80 & (status))
-
-#define DRIVER_NAME "si476x-radio"
-#define DRIVER_CARD "SI476x AM/FM Receiver"
-
-enum si476x_freq_bands {
- SI476X_BAND_FM,
- SI476X_BAND_AM,
-};
-
-static const struct v4l2_frequency_band si476x_bands[] = {
- [SI476X_BAND_FM] = {
- .type = V4L2_TUNER_RADIO,
- .index = SI476X_BAND_FM,
- .capability = V4L2_TUNER_CAP_LOW
- | V4L2_TUNER_CAP_STEREO
- | V4L2_TUNER_CAP_RDS
- | V4L2_TUNER_CAP_RDS_BLOCK_IO
- | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 64 * FREQ_MUL,
- .rangehigh = 108 * FREQ_MUL,
- .modulation = V4L2_BAND_MODULATION_FM,
- },
- [SI476X_BAND_AM] = {
- .type = V4L2_TUNER_RADIO,
- .index = SI476X_BAND_AM,
- .capability = V4L2_TUNER_CAP_LOW
- | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 0.52 * FREQ_MUL,
- .rangehigh = 30 * FREQ_MUL,
- .modulation = V4L2_BAND_MODULATION_AM,
- },
-};
-
-static inline bool si476x_radio_freq_is_inside_of_the_band(u32 freq, int band)
-{
- return freq >= si476x_bands[band].rangelow &&
- freq <= si476x_bands[band].rangehigh;
-}
-
-static inline bool si476x_radio_range_is_inside_of_the_band(u32 low, u32 high,
- int band)
-{
- return low >= si476x_bands[band].rangelow &&
- high <= si476x_bands[band].rangehigh;
-}
-
-static int si476x_radio_s_ctrl(struct v4l2_ctrl *ctrl);
-static int si476x_radio_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
-
-enum phase_diversity_modes_idx {
- SI476X_IDX_PHDIV_DISABLED,
- SI476X_IDX_PHDIV_PRIMARY_COMBINING,
- SI476X_IDX_PHDIV_PRIMARY_ANTENNA,
- SI476X_IDX_PHDIV_SECONDARY_ANTENNA,
- SI476X_IDX_PHDIV_SECONDARY_COMBINING,
-};
-
-static const char * const phase_diversity_modes[] = {
- [SI476X_IDX_PHDIV_DISABLED] = "Disabled",
- [SI476X_IDX_PHDIV_PRIMARY_COMBINING] = "Primary with Secondary",
- [SI476X_IDX_PHDIV_PRIMARY_ANTENNA] = "Primary Antenna",
- [SI476X_IDX_PHDIV_SECONDARY_ANTENNA] = "Secondary Antenna",
- [SI476X_IDX_PHDIV_SECONDARY_COMBINING] = "Secondary with Primary",
-};
-
-static inline enum phase_diversity_modes_idx
-si476x_phase_diversity_mode_to_idx(enum si476x_phase_diversity_mode mode)
-{
- switch (mode) {
- default:
- fallthrough;
- case SI476X_PHDIV_DISABLED:
- return SI476X_IDX_PHDIV_DISABLED;
- case SI476X_PHDIV_PRIMARY_COMBINING:
- return SI476X_IDX_PHDIV_PRIMARY_COMBINING;
- case SI476X_PHDIV_PRIMARY_ANTENNA:
- return SI476X_IDX_PHDIV_PRIMARY_ANTENNA;
- case SI476X_PHDIV_SECONDARY_ANTENNA:
- return SI476X_IDX_PHDIV_SECONDARY_ANTENNA;
- case SI476X_PHDIV_SECONDARY_COMBINING:
- return SI476X_IDX_PHDIV_SECONDARY_COMBINING;
- }
-}
-
-static inline enum si476x_phase_diversity_mode
-si476x_phase_diversity_idx_to_mode(enum phase_diversity_modes_idx idx)
-{
- static const int idx_to_value[] = {
- [SI476X_IDX_PHDIV_DISABLED] = SI476X_PHDIV_DISABLED,
- [SI476X_IDX_PHDIV_PRIMARY_COMBINING] = SI476X_PHDIV_PRIMARY_COMBINING,
- [SI476X_IDX_PHDIV_PRIMARY_ANTENNA] = SI476X_PHDIV_PRIMARY_ANTENNA,
- [SI476X_IDX_PHDIV_SECONDARY_ANTENNA] = SI476X_PHDIV_SECONDARY_ANTENNA,
- [SI476X_IDX_PHDIV_SECONDARY_COMBINING] = SI476X_PHDIV_SECONDARY_COMBINING,
- };
-
- return idx_to_value[idx];
-}
-
-static const struct v4l2_ctrl_ops si476x_ctrl_ops = {
- .g_volatile_ctrl = si476x_radio_g_volatile_ctrl,
- .s_ctrl = si476x_radio_s_ctrl,
-};
-
-
-enum si476x_ctrl_idx {
- SI476X_IDX_RSSI_THRESHOLD,
- SI476X_IDX_SNR_THRESHOLD,
- SI476X_IDX_MAX_TUNE_ERROR,
- SI476X_IDX_HARMONICS_COUNT,
- SI476X_IDX_DIVERSITY_MODE,
- SI476X_IDX_INTERCHIP_LINK,
-};
-static struct v4l2_ctrl_config si476x_ctrls[] = {
-
- /*
- * SI476X during its station seeking(or tuning) process uses several
- * parameters to determine if "the station" is valid:
- *
- * - Signal's SNR(in dBuV) must be lower than
- * #V4L2_CID_SI476X_SNR_THRESHOLD
- * - Signal's RSSI(in dBuV) must be greater than
- * #V4L2_CID_SI476X_RSSI_THRESHOLD
- * - Signal's frequency deviation(in units of 2ppm) must not be
- * more than #V4L2_CID_SI476X_MAX_TUNE_ERROR
- */
- [SI476X_IDX_RSSI_THRESHOLD] = {
- .ops = &si476x_ctrl_ops,
- .id = V4L2_CID_SI476X_RSSI_THRESHOLD,
- .name = "Valid RSSI Threshold",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .min = -128,
- .max = 127,
- .step = 1,
- },
- [SI476X_IDX_SNR_THRESHOLD] = {
- .ops = &si476x_ctrl_ops,
- .id = V4L2_CID_SI476X_SNR_THRESHOLD,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Valid SNR Threshold",
- .min = -128,
- .max = 127,
- .step = 1,
- },
- [SI476X_IDX_MAX_TUNE_ERROR] = {
- .ops = &si476x_ctrl_ops,
- .id = V4L2_CID_SI476X_MAX_TUNE_ERROR,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Max Tune Errors",
- .min = 0,
- .max = 126 * 2,
- .step = 2,
- },
-
- /*
- * #V4L2_CID_SI476X_HARMONICS_COUNT -- number of harmonics
- * built-in power-line noise supression filter is to reject
- * during AM-mode operation.
- */
- [SI476X_IDX_HARMONICS_COUNT] = {
- .ops = &si476x_ctrl_ops,
- .id = V4L2_CID_SI476X_HARMONICS_COUNT,
- .type = V4L2_CTRL_TYPE_INTEGER,
-
- .name = "Count of Harmonics to Reject",
- .min = 0,
- .max = 20,
- .step = 1,
- },
-
- /*
- * #V4L2_CID_SI476X_DIVERSITY_MODE -- configuration which
- * two tuners working in diversity mode are to work in.
- *
- * - #SI476X_IDX_PHDIV_DISABLED diversity mode disabled
- * - #SI476X_IDX_PHDIV_PRIMARY_COMBINING diversity mode is
- * on, primary tuner's antenna is the main one.
- * - #SI476X_IDX_PHDIV_PRIMARY_ANTENNA diversity mode is
- * off, primary tuner's antenna is the main one.
- * - #SI476X_IDX_PHDIV_SECONDARY_ANTENNA diversity mode is
- * off, secondary tuner's antenna is the main one.
- * - #SI476X_IDX_PHDIV_SECONDARY_COMBINING diversity mode is
- * on, secondary tuner's antenna is the main one.
- */
- [SI476X_IDX_DIVERSITY_MODE] = {
- .ops = &si476x_ctrl_ops,
- .id = V4L2_CID_SI476X_DIVERSITY_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Phase Diversity Mode",
- .qmenu = phase_diversity_modes,
- .min = 0,
- .max = ARRAY_SIZE(phase_diversity_modes) - 1,
- },
-
- /*
- * #V4L2_CID_SI476X_INTERCHIP_LINK -- inter-chip link in
- * diversity mode indicator. Allows user to determine if two
- * chips working in diversity mode have established a link
- * between each other and if the system as a whole uses
- * signals from both antennas to receive FM radio.
- */
- [SI476X_IDX_INTERCHIP_LINK] = {
- .ops = &si476x_ctrl_ops,
- .id = V4L2_CID_SI476X_INTERCHIP_LINK,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE,
- .name = "Inter-Chip Link",
- .min = 0,
- .max = 1,
- .step = 1,
- },
-};
-
-struct si476x_radio;
-
-/**
- * struct si476x_radio_ops - vtable of tuner functions
- *
- * This table holds pointers to functions implementing particular
- * operations depending on the mode in which the tuner chip was
- * configured to start. If the function is not supported
- * corresponding element is set to #NULL.
- *
- * @tune_freq: Tune chip to a specific frequency
- * @seek_start: Star station seeking
- * @rsq_status: Get Received Signal Quality(RSQ) status
- * @rds_blckcnt: Get received RDS blocks count
- * @phase_diversity: Change phase diversity mode of the tuner
- * @phase_div_status: Get phase diversity mode status
- * @acf_status: Get the status of Automatically Controlled
- * Features(ACF)
- * @agc_status: Get Automatic Gain Control(AGC) status
- */
-struct si476x_radio_ops {
- int (*tune_freq)(struct si476x_core *, struct si476x_tune_freq_args *);
- int (*seek_start)(struct si476x_core *, bool, bool);
- int (*rsq_status)(struct si476x_core *, struct si476x_rsq_status_args *,
- struct si476x_rsq_status_report *);
- int (*rds_blckcnt)(struct si476x_core *, bool,
- struct si476x_rds_blockcount_report *);
-
- int (*phase_diversity)(struct si476x_core *,
- enum si476x_phase_diversity_mode);
- int (*phase_div_status)(struct si476x_core *);
- int (*acf_status)(struct si476x_core *,
- struct si476x_acf_status_report *);
- int (*agc_status)(struct si476x_core *,
- struct si476x_agc_status_report *);
-};
-
-/**
- * struct si476x_radio - radio device
- *
- * @v4l2dev: Pointer to V4L2 device created by V4L2 subsystem
- * @videodev: Pointer to video device created by V4L2 subsystem
- * @ctrl_handler: V4L2 controls handler
- * @core: Pointer to underlying core device
- * @ops: Vtable of functions. See struct si476x_radio_ops for details
- * @debugfs: pointer to &strucd dentry for debugfs
- * @audmode: audio mode, as defined for the rxsubchans field
- * at videodev2.h
- *
- * core structure is the radio device is being used
- */
-struct si476x_radio {
- struct v4l2_device v4l2dev;
- struct video_device videodev;
- struct v4l2_ctrl_handler ctrl_handler;
-
- struct si476x_core *core;
- /* This field should not be accesses unless core lock is held */
- const struct si476x_radio_ops *ops;
-
- struct dentry *debugfs;
- u32 audmode;
-};
-
-static inline struct si476x_radio *
-v4l2_ctrl_handler_to_radio(struct v4l2_ctrl_handler *d)
-{
- return container_of(d, struct si476x_radio, ctrl_handler);
-}
-
-/*
- * si476x_vidioc_querycap - query device capabilities
- */
-static int si476x_radio_querycap(struct file *file, void *priv,
- struct v4l2_capability *capability)
-{
- struct si476x_radio *radio = video_drvdata(file);
-
- strscpy(capability->driver, radio->v4l2dev.name,
- sizeof(capability->driver));
- strscpy(capability->card, DRIVER_CARD, sizeof(capability->card));
- return 0;
-}
-
-static int si476x_radio_enum_freq_bands(struct file *file, void *priv,
- struct v4l2_frequency_band *band)
-{
- int err;
- struct si476x_radio *radio = video_drvdata(file);
-
- if (band->tuner != 0)
- return -EINVAL;
-
- switch (radio->core->chip_id) {
- /* AM/FM tuners -- all bands are supported */
- case SI476X_CHIP_SI4761:
- case SI476X_CHIP_SI4764:
- if (band->index < ARRAY_SIZE(si476x_bands)) {
- *band = si476x_bands[band->index];
- err = 0;
- } else {
- err = -EINVAL;
- }
- break;
- /* FM companion tuner chips -- only FM bands are
- * supported */
- case SI476X_CHIP_SI4768:
- if (band->index == SI476X_BAND_FM) {
- *band = si476x_bands[band->index];
- err = 0;
- } else {
- err = -EINVAL;
- }
- break;
- default:
- err = -EINVAL;
- }
-
- return err;
-}
-
-static int si476x_radio_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *tuner)
-{
- int err;
- struct si476x_rsq_status_report report;
- struct si476x_radio *radio = video_drvdata(file);
-
- struct si476x_rsq_status_args args = {
- .primary = false,
- .rsqack = false,
- .attune = false,
- .cancel = false,
- .stcack = false,
- };
-
- if (tuner->index != 0)
- return -EINVAL;
-
- tuner->type = V4L2_TUNER_RADIO;
- tuner->capability = V4L2_TUNER_CAP_LOW /* Measure frequencies
- * in multiples of
- * 62.5 Hz */
- | V4L2_TUNER_CAP_STEREO
- | V4L2_TUNER_CAP_HWSEEK_BOUNDED
- | V4L2_TUNER_CAP_HWSEEK_WRAP
- | V4L2_TUNER_CAP_HWSEEK_PROG_LIM;
-
- si476x_core_lock(radio->core);
-
- if (si476x_core_is_a_secondary_tuner(radio->core)) {
- strscpy(tuner->name, "FM (secondary)", sizeof(tuner->name));
- tuner->rxsubchans = 0;
- tuner->rangelow = si476x_bands[SI476X_BAND_FM].rangelow;
- } else if (si476x_core_has_am(radio->core)) {
- if (si476x_core_is_a_primary_tuner(radio->core))
- strscpy(tuner->name, "AM/FM (primary)",
- sizeof(tuner->name));
- else
- strscpy(tuner->name, "AM/FM", sizeof(tuner->name));
-
- tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO
- | V4L2_TUNER_SUB_RDS;
- tuner->capability |= V4L2_TUNER_CAP_RDS
- | V4L2_TUNER_CAP_RDS_BLOCK_IO
- | V4L2_TUNER_CAP_FREQ_BANDS;
-
- tuner->rangelow = si476x_bands[SI476X_BAND_AM].rangelow;
- } else {
- strscpy(tuner->name, "FM", sizeof(tuner->name));
- tuner->rxsubchans = V4L2_TUNER_SUB_RDS;
- tuner->capability |= V4L2_TUNER_CAP_RDS
- | V4L2_TUNER_CAP_RDS_BLOCK_IO
- | V4L2_TUNER_CAP_FREQ_BANDS;
- tuner->rangelow = si476x_bands[SI476X_BAND_FM].rangelow;
- }
-
- tuner->audmode = radio->audmode;
-
- tuner->afc = 1;
- tuner->rangehigh = si476x_bands[SI476X_BAND_FM].rangehigh;
-
- err = radio->ops->rsq_status(radio->core,
- &args, &report);
- if (err < 0) {
- tuner->signal = 0;
- } else {
- /*
- * tuner->signal value range: 0x0000 .. 0xFFFF,
- * report.rssi: -128 .. 127
- */
- tuner->signal = (report.rssi + 128) * 257;
- }
- si476x_core_unlock(radio->core);
-
- return err;
-}
-
-static int si476x_radio_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *tuner)
-{
- struct si476x_radio *radio = video_drvdata(file);
-
- if (tuner->index != 0)
- return -EINVAL;
-
- if (tuner->audmode == V4L2_TUNER_MODE_MONO ||
- tuner->audmode == V4L2_TUNER_MODE_STEREO)
- radio->audmode = tuner->audmode;
- else
- radio->audmode = V4L2_TUNER_MODE_STEREO;
-
- return 0;
-}
-
-static int si476x_radio_init_vtable(struct si476x_radio *radio,
- enum si476x_func func)
-{
- static const struct si476x_radio_ops fm_ops = {
- .tune_freq = si476x_core_cmd_fm_tune_freq,
- .seek_start = si476x_core_cmd_fm_seek_start,
- .rsq_status = si476x_core_cmd_fm_rsq_status,
- .rds_blckcnt = si476x_core_cmd_fm_rds_blockcount,
- .phase_diversity = si476x_core_cmd_fm_phase_diversity,
- .phase_div_status = si476x_core_cmd_fm_phase_div_status,
- .acf_status = si476x_core_cmd_fm_acf_status,
- .agc_status = si476x_core_cmd_agc_status,
- };
-
- static const struct si476x_radio_ops am_ops = {
- .tune_freq = si476x_core_cmd_am_tune_freq,
- .seek_start = si476x_core_cmd_am_seek_start,
- .rsq_status = si476x_core_cmd_am_rsq_status,
- .rds_blckcnt = NULL,
- .phase_diversity = NULL,
- .phase_div_status = NULL,
- .acf_status = si476x_core_cmd_am_acf_status,
- .agc_status = NULL,
- };
-
- switch (func) {
- case SI476X_FUNC_FM_RECEIVER:
- radio->ops = &fm_ops;
- return 0;
-
- case SI476X_FUNC_AM_RECEIVER:
- radio->ops = &am_ops;
- return 0;
- default:
- WARN(1, "Unexpected tuner function value\n");
- return -EINVAL;
- }
-}
-
-static int si476x_radio_pretune(struct si476x_radio *radio,
- enum si476x_func func)
-{
- int retval;
-
- struct si476x_tune_freq_args args = {
- .zifsr = false,
- .hd = false,
- .injside = SI476X_INJSIDE_AUTO,
- .tunemode = SI476X_TM_VALIDATED_NORMAL_TUNE,
- .smoothmetrics = SI476X_SM_INITIALIZE_AUDIO,
- .antcap = 0,
- };
-
- switch (func) {
- case SI476X_FUNC_FM_RECEIVER:
- args.freq = v4l2_to_si476x(radio->core,
- 92 * FREQ_MUL);
- retval = radio->ops->tune_freq(radio->core, &args);
- break;
- case SI476X_FUNC_AM_RECEIVER:
- args.freq = v4l2_to_si476x(radio->core,
- 0.6 * FREQ_MUL);
- retval = radio->ops->tune_freq(radio->core, &args);
- break;
- default:
- WARN(1, "Unexpected tuner function value\n");
- retval = -EINVAL;
- }
-
- return retval;
-}
-static int si476x_radio_do_post_powerup_init(struct si476x_radio *radio,
- enum si476x_func func)
-{
- int err;
-
- /* regcache_mark_dirty(radio->core->regmap); */
- err = regcache_sync_region(radio->core->regmap,
- SI476X_PROP_DIGITAL_IO_INPUT_SAMPLE_RATE,
- SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT);
- if (err < 0)
- return err;
-
- err = regcache_sync_region(radio->core->regmap,
- SI476X_PROP_AUDIO_DEEMPHASIS,
- SI476X_PROP_AUDIO_PWR_LINE_FILTER);
- if (err < 0)
- return err;
-
- err = regcache_sync_region(radio->core->regmap,
- SI476X_PROP_INT_CTL_ENABLE,
- SI476X_PROP_INT_CTL_ENABLE);
- if (err < 0)
- return err;
-
- /*
- * Is there any point in restoring SNR and the like
- * when switching between AM/FM?
- */
- err = regcache_sync_region(radio->core->regmap,
- SI476X_PROP_VALID_MAX_TUNE_ERROR,
- SI476X_PROP_VALID_MAX_TUNE_ERROR);
- if (err < 0)
- return err;
-
- err = regcache_sync_region(radio->core->regmap,
- SI476X_PROP_VALID_SNR_THRESHOLD,
- SI476X_PROP_VALID_RSSI_THRESHOLD);
- if (err < 0)
- return err;
-
- if (func == SI476X_FUNC_FM_RECEIVER) {
- if (si476x_core_has_diversity(radio->core)) {
- err = si476x_core_cmd_fm_phase_diversity(radio->core,
- radio->core->diversity_mode);
- if (err < 0)
- return err;
- }
-
- err = regcache_sync_region(radio->core->regmap,
- SI476X_PROP_FM_RDS_INTERRUPT_SOURCE,
- SI476X_PROP_FM_RDS_CONFIG);
- if (err < 0)
- return err;
- }
-
- return si476x_radio_init_vtable(radio, func);
-
-}
-
-static int si476x_radio_change_func(struct si476x_radio *radio,
- enum si476x_func func)
-{
- int err;
- bool soft;
- /*
- * Since power/up down is a very time consuming operation,
- * try to avoid doing it if the requested mode matches the one
- * the tuner is in
- */
- if (func == radio->core->power_up_parameters.func)
- return 0;
-
- soft = true;
- err = si476x_core_stop(radio->core, soft);
- if (err < 0) {
- /*
- * OK, if the chip does not want to play nice let's
- * try to reset it in more brutal way
- */
- soft = false;
- err = si476x_core_stop(radio->core, soft);
- if (err < 0)
- return err;
- }
- /*
- Set the desired radio tuner function
- */
- radio->core->power_up_parameters.func = func;
-
- err = si476x_core_start(radio->core, soft);
- if (err < 0)
- return err;
-
- /*
- * No need to do the rest of manipulations for the bootlader
- * mode
- */
- if (func != SI476X_FUNC_FM_RECEIVER &&
- func != SI476X_FUNC_AM_RECEIVER)
- return err;
-
- return si476x_radio_do_post_powerup_init(radio, func);
-}
-
-static int si476x_radio_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- int err;
- struct si476x_radio *radio = video_drvdata(file);
-
- if (f->tuner != 0 ||
- f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
-
- si476x_core_lock(radio->core);
-
- if (radio->ops->rsq_status) {
- struct si476x_rsq_status_report report;
- struct si476x_rsq_status_args args = {
- .primary = false,
- .rsqack = false,
- .attune = true,
- .cancel = false,
- .stcack = false,
- };
-
- err = radio->ops->rsq_status(radio->core, &args, &report);
- if (!err)
- f->frequency = si476x_to_v4l2(radio->core,
- report.readfreq);
- } else {
- err = -EINVAL;
- }
-
- si476x_core_unlock(radio->core);
-
- return err;
-}
-
-static int si476x_radio_s_frequency(struct file *file, void *priv,
- const struct v4l2_frequency *f)
-{
- int err;
- u32 freq = f->frequency;
- struct si476x_tune_freq_args args;
- struct si476x_radio *radio = video_drvdata(file);
-
- const u32 midrange = (si476x_bands[SI476X_BAND_AM].rangehigh +
- si476x_bands[SI476X_BAND_FM].rangelow) / 2;
- const int band = (freq > midrange) ?
- SI476X_BAND_FM : SI476X_BAND_AM;
- const enum si476x_func func = (band == SI476X_BAND_AM) ?
- SI476X_FUNC_AM_RECEIVER : SI476X_FUNC_FM_RECEIVER;
-
- if (f->tuner != 0 ||
- f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
-
- si476x_core_lock(radio->core);
-
- freq = clamp(freq,
- si476x_bands[band].rangelow,
- si476x_bands[band].rangehigh);
-
- if (si476x_radio_freq_is_inside_of_the_band(freq,
- SI476X_BAND_AM) &&
- (!si476x_core_has_am(radio->core) ||
- si476x_core_is_a_secondary_tuner(radio->core))) {
- err = -EINVAL;
- goto unlock;
- }
-
- err = si476x_radio_change_func(radio, func);
- if (err < 0)
- goto unlock;
-
- args.zifsr = false;
- args.hd = false;
- args.injside = SI476X_INJSIDE_AUTO;
- args.freq = v4l2_to_si476x(radio->core, freq);
- args.tunemode = SI476X_TM_VALIDATED_NORMAL_TUNE;
- args.smoothmetrics = SI476X_SM_INITIALIZE_AUDIO;
- args.antcap = 0;
-
- err = radio->ops->tune_freq(radio->core, &args);
-
-unlock:
- si476x_core_unlock(radio->core);
- return err;
-}
-
-static int si476x_radio_s_hw_freq_seek(struct file *file, void *priv,
- const struct v4l2_hw_freq_seek *seek)
-{
- int err;
- enum si476x_func func;
- u32 rangelow = seek->rangelow, rangehigh = seek->rangehigh;
- struct si476x_radio *radio = video_drvdata(file);
-
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
-
- if (seek->tuner != 0 ||
- seek->type != V4L2_TUNER_RADIO)
- return -EINVAL;
-
- si476x_core_lock(radio->core);
-
- if (!rangelow) {
- err = regmap_read(radio->core->regmap,
- SI476X_PROP_SEEK_BAND_BOTTOM,
- &rangelow);
- if (err)
- goto unlock;
- rangelow = si476x_to_v4l2(radio->core, rangelow);
- }
- if (!rangehigh) {
- err = regmap_read(radio->core->regmap,
- SI476X_PROP_SEEK_BAND_TOP,
- &rangehigh);
- if (err)
- goto unlock;
- rangehigh = si476x_to_v4l2(radio->core, rangehigh);
- }
-
- if (rangelow > rangehigh) {
- err = -EINVAL;
- goto unlock;
- }
-
- if (si476x_radio_range_is_inside_of_the_band(rangelow, rangehigh,
- SI476X_BAND_FM)) {
- func = SI476X_FUNC_FM_RECEIVER;
-
- } else if (si476x_core_has_am(radio->core) &&
- si476x_radio_range_is_inside_of_the_band(rangelow, rangehigh,
- SI476X_BAND_AM)) {
- func = SI476X_FUNC_AM_RECEIVER;
- } else {
- err = -EINVAL;
- goto unlock;
- }
-
- err = si476x_radio_change_func(radio, func);
- if (err < 0)
- goto unlock;
-
- if (seek->rangehigh) {
- err = regmap_write(radio->core->regmap,
- SI476X_PROP_SEEK_BAND_TOP,
- v4l2_to_si476x(radio->core,
- seek->rangehigh));
- if (err)
- goto unlock;
- }
- if (seek->rangelow) {
- err = regmap_write(radio->core->regmap,
- SI476X_PROP_SEEK_BAND_BOTTOM,
- v4l2_to_si476x(radio->core,
- seek->rangelow));
- if (err)
- goto unlock;
- }
- if (seek->spacing) {
- err = regmap_write(radio->core->regmap,
- SI476X_PROP_SEEK_FREQUENCY_SPACING,
- v4l2_to_si476x(radio->core,
- seek->spacing));
- if (err)
- goto unlock;
- }
-
- err = radio->ops->seek_start(radio->core,
- seek->seek_upward,
- seek->wrap_around);
-unlock:
- si476x_core_unlock(radio->core);
-
-
-
- return err;
-}
-
-static int si476x_radio_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- int retval;
- struct si476x_radio *radio = v4l2_ctrl_handler_to_radio(ctrl->handler);
-
- si476x_core_lock(radio->core);
-
- switch (ctrl->id) {
- case V4L2_CID_SI476X_INTERCHIP_LINK:
- if (si476x_core_has_diversity(radio->core)) {
- if (radio->ops->phase_diversity) {
- retval = radio->ops->phase_div_status(radio->core);
- if (retval < 0)
- break;
-
- ctrl->val = !!SI476X_PHDIV_STATUS_LINK_LOCKED(retval);
- retval = 0;
- break;
- } else {
- retval = -ENOTTY;
- break;
- }
- }
- retval = -EINVAL;
- break;
- default:
- retval = -EINVAL;
- break;
- }
- si476x_core_unlock(radio->core);
- return retval;
-
-}
-
-static int si476x_radio_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- int retval;
- enum si476x_phase_diversity_mode mode;
- struct si476x_radio *radio = v4l2_ctrl_handler_to_radio(ctrl->handler);
-
- si476x_core_lock(radio->core);
-
- switch (ctrl->id) {
- case V4L2_CID_SI476X_HARMONICS_COUNT:
- retval = regmap_update_bits(radio->core->regmap,
- SI476X_PROP_AUDIO_PWR_LINE_FILTER,
- SI476X_PROP_PWR_HARMONICS_MASK,
- ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- switch (ctrl->val) {
- case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
- retval = regmap_update_bits(radio->core->regmap,
- SI476X_PROP_AUDIO_PWR_LINE_FILTER,
- SI476X_PROP_PWR_ENABLE_MASK,
- 0);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
- retval = regmap_update_bits(radio->core->regmap,
- SI476X_PROP_AUDIO_PWR_LINE_FILTER,
- SI476X_PROP_PWR_GRID_MASK,
- SI476X_PROP_PWR_GRID_50HZ);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
- retval = regmap_update_bits(radio->core->regmap,
- SI476X_PROP_AUDIO_PWR_LINE_FILTER,
- SI476X_PROP_PWR_GRID_MASK,
- SI476X_PROP_PWR_GRID_60HZ);
- break;
- default:
- retval = -EINVAL;
- break;
- }
- break;
- case V4L2_CID_SI476X_RSSI_THRESHOLD:
- retval = regmap_write(radio->core->regmap,
- SI476X_PROP_VALID_RSSI_THRESHOLD,
- ctrl->val);
- break;
- case V4L2_CID_SI476X_SNR_THRESHOLD:
- retval = regmap_write(radio->core->regmap,
- SI476X_PROP_VALID_SNR_THRESHOLD,
- ctrl->val);
- break;
- case V4L2_CID_SI476X_MAX_TUNE_ERROR:
- retval = regmap_write(radio->core->regmap,
- SI476X_PROP_VALID_MAX_TUNE_ERROR,
- ctrl->val);
- break;
- case V4L2_CID_RDS_RECEPTION:
- /*
- * It looks like RDS related properties are
- * inaccessible when tuner is in AM mode, so cache the
- * changes
- */
- if (si476x_core_is_in_am_receiver_mode(radio->core))
- regcache_cache_only(radio->core->regmap, true);
-
- if (ctrl->val) {
- retval = regmap_write(radio->core->regmap,
- SI476X_PROP_FM_RDS_INTERRUPT_FIFO_COUNT,
- radio->core->rds_fifo_depth);
- if (retval < 0)
- break;
-
- if (radio->core->client->irq) {
- retval = regmap_write(radio->core->regmap,
- SI476X_PROP_FM_RDS_INTERRUPT_SOURCE,
- SI476X_RDSRECV);
- if (retval < 0)
- break;
- }
-
- /* Drain RDS FIFO before enabling RDS processing */
- retval = si476x_core_cmd_fm_rds_status(radio->core,
- false,
- true,
- true,
- NULL);
- if (retval < 0)
- break;
-
- retval = regmap_update_bits(radio->core->regmap,
- SI476X_PROP_FM_RDS_CONFIG,
- SI476X_PROP_RDSEN_MASK,
- SI476X_PROP_RDSEN);
- } else {
- retval = regmap_update_bits(radio->core->regmap,
- SI476X_PROP_FM_RDS_CONFIG,
- SI476X_PROP_RDSEN_MASK,
- !SI476X_PROP_RDSEN);
- }
-
- if (si476x_core_is_in_am_receiver_mode(radio->core))
- regcache_cache_only(radio->core->regmap, false);
- break;
- case V4L2_CID_TUNE_DEEMPHASIS:
- retval = regmap_write(radio->core->regmap,
- SI476X_PROP_AUDIO_DEEMPHASIS,
- ctrl->val);
- break;
-
- case V4L2_CID_SI476X_DIVERSITY_MODE:
- mode = si476x_phase_diversity_idx_to_mode(ctrl->val);
-
- if (mode == radio->core->diversity_mode) {
- retval = 0;
- break;
- }
-
- if (si476x_core_is_in_am_receiver_mode(radio->core)) {
- /*
- * Diversity cannot be configured while tuner
- * is in AM mode so save the changes and carry on.
- */
- radio->core->diversity_mode = mode;
- retval = 0;
- } else {
- retval = radio->ops->phase_diversity(radio->core, mode);
- if (!retval)
- radio->core->diversity_mode = mode;
- }
- break;
-
- default:
- retval = -EINVAL;
- break;
- }
-
- si476x_core_unlock(radio->core);
-
- return retval;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int si476x_radio_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- int err;
- unsigned int value;
- struct si476x_radio *radio = video_drvdata(file);
-
- si476x_core_lock(radio->core);
- reg->size = 2;
- err = regmap_read(radio->core->regmap,
- (unsigned int)reg->reg, &value);
- reg->val = value;
- si476x_core_unlock(radio->core);
-
- return err;
-}
-static int si476x_radio_s_register(struct file *file, void *fh,
- const struct v4l2_dbg_register *reg)
-{
-
- int err;
- struct si476x_radio *radio = video_drvdata(file);
-
- si476x_core_lock(radio->core);
- err = regmap_write(radio->core->regmap,
- (unsigned int)reg->reg,
- (unsigned int)reg->val);
- si476x_core_unlock(radio->core);
-
- return err;
-}
-#endif
-
-static int si476x_radio_fops_open(struct file *file)
-{
- struct si476x_radio *radio = video_drvdata(file);
- int err;
-
- err = v4l2_fh_open(file);
- if (err)
- return err;
-
- if (v4l2_fh_is_singular_file(file)) {
- si476x_core_lock(radio->core);
- err = si476x_core_set_power_state(radio->core,
- SI476X_POWER_UP_FULL);
- if (err < 0)
- goto done;
-
- err = si476x_radio_do_post_powerup_init(radio,
- radio->core->power_up_parameters.func);
- if (err < 0)
- goto power_down;
-
- err = si476x_radio_pretune(radio,
- radio->core->power_up_parameters.func);
- if (err < 0)
- goto power_down;
-
- si476x_core_unlock(radio->core);
- /*Must be done after si476x_core_unlock to prevent a deadlock*/
- v4l2_ctrl_handler_setup(&radio->ctrl_handler);
- }
-
- return err;
-
-power_down:
- si476x_core_set_power_state(radio->core,
- SI476X_POWER_DOWN);
-done:
- si476x_core_unlock(radio->core);
- v4l2_fh_release(file);
-
- return err;
-}
-
-static int si476x_radio_fops_release(struct file *file)
-{
- struct si476x_radio *radio = video_drvdata(file);
-
- if (v4l2_fh_is_singular_file(file) &&
- atomic_read(&radio->core->is_alive))
- si476x_core_set_power_state(radio->core,
- SI476X_POWER_DOWN);
-
- return v4l2_fh_release(file);
-}
-
-static ssize_t si476x_radio_fops_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- ssize_t rval;
- size_t fifo_len;
- unsigned int copied;
-
- struct si476x_radio *radio = video_drvdata(file);
-
- /* block if no new data available */
- if (kfifo_is_empty(&radio->core->rds_fifo)) {
- if (file->f_flags & O_NONBLOCK)
- return -EWOULDBLOCK;
-
- rval = wait_event_interruptible(radio->core->rds_read_queue,
- (!kfifo_is_empty(&radio->core->rds_fifo) ||
- !atomic_read(&radio->core->is_alive)));
- if (rval < 0)
- return -EINTR;
-
- if (!atomic_read(&radio->core->is_alive))
- return -ENODEV;
- }
-
- fifo_len = kfifo_len(&radio->core->rds_fifo);
-
- if (kfifo_to_user(&radio->core->rds_fifo, buf,
- min(fifo_len, count),
- &copied) != 0) {
- dev_warn(&radio->videodev.dev,
- "Error during FIFO to userspace copy\n");
- rval = -EIO;
- } else {
- rval = (ssize_t)copied;
- }
-
- return rval;
-}
-
-static __poll_t si476x_radio_fops_poll(struct file *file,
- struct poll_table_struct *pts)
-{
- struct si476x_radio *radio = video_drvdata(file);
- __poll_t req_events = poll_requested_events(pts);
- __poll_t err = v4l2_ctrl_poll(file, pts);
-
- if (req_events & (EPOLLIN | EPOLLRDNORM)) {
- if (atomic_read(&radio->core->is_alive))
- poll_wait(file, &radio->core->rds_read_queue, pts);
-
- if (!atomic_read(&radio->core->is_alive))
- err = EPOLLHUP;
-
- if (!kfifo_is_empty(&radio->core->rds_fifo))
- err = EPOLLIN | EPOLLRDNORM;
- }
-
- return err;
-}
-
-static const struct v4l2_file_operations si476x_fops = {
- .owner = THIS_MODULE,
- .read = si476x_radio_fops_read,
- .poll = si476x_radio_fops_poll,
- .unlocked_ioctl = video_ioctl2,
- .open = si476x_radio_fops_open,
- .release = si476x_radio_fops_release,
-};
-
-
-static const struct v4l2_ioctl_ops si4761_ioctl_ops = {
- .vidioc_querycap = si476x_radio_querycap,
- .vidioc_g_tuner = si476x_radio_g_tuner,
- .vidioc_s_tuner = si476x_radio_s_tuner,
-
- .vidioc_g_frequency = si476x_radio_g_frequency,
- .vidioc_s_frequency = si476x_radio_s_frequency,
- .vidioc_s_hw_freq_seek = si476x_radio_s_hw_freq_seek,
- .vidioc_enum_freq_bands = si476x_radio_enum_freq_bands,
-
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = si476x_radio_g_register,
- .vidioc_s_register = si476x_radio_s_register,
-#endif
-};
-
-
-static const struct video_device si476x_viddev_template = {
- .fops = &si476x_fops,
- .name = DRIVER_NAME,
- .release = video_device_release_empty,
-};
-
-
-
-static ssize_t si476x_radio_read_acf_blob(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- int err;
- struct si476x_radio *radio = file->private_data;
- struct si476x_acf_status_report report;
-
- si476x_core_lock(radio->core);
- if (radio->ops->acf_status)
- err = radio->ops->acf_status(radio->core, &report);
- else
- err = -ENOENT;
- si476x_core_unlock(radio->core);
-
- if (err < 0)
- return err;
-
- return simple_read_from_buffer(user_buf, count, ppos, &report,
- sizeof(report));
-}
-
-static const struct file_operations radio_acf_fops = {
- .open = simple_open,
- .llseek = default_llseek,
- .read = si476x_radio_read_acf_blob,
-};
-
-static ssize_t si476x_radio_read_rds_blckcnt_blob(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- int err;
- struct si476x_radio *radio = file->private_data;
- struct si476x_rds_blockcount_report report;
-
- si476x_core_lock(radio->core);
- if (radio->ops->rds_blckcnt)
- err = radio->ops->rds_blckcnt(radio->core, true,
- &report);
- else
- err = -ENOENT;
- si476x_core_unlock(radio->core);
-
- if (err < 0)
- return err;
-
- return simple_read_from_buffer(user_buf, count, ppos, &report,
- sizeof(report));
-}
-
-static const struct file_operations radio_rds_blckcnt_fops = {
- .open = simple_open,
- .llseek = default_llseek,
- .read = si476x_radio_read_rds_blckcnt_blob,
-};
-
-static ssize_t si476x_radio_read_agc_blob(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- int err;
- struct si476x_radio *radio = file->private_data;
- struct si476x_agc_status_report report;
-
- si476x_core_lock(radio->core);
- if (radio->ops->rds_blckcnt)
- err = radio->ops->agc_status(radio->core, &report);
- else
- err = -ENOENT;
- si476x_core_unlock(radio->core);
-
- if (err < 0)
- return err;
-
- return simple_read_from_buffer(user_buf, count, ppos, &report,
- sizeof(report));
-}
-
-static const struct file_operations radio_agc_fops = {
- .open = simple_open,
- .llseek = default_llseek,
- .read = si476x_radio_read_agc_blob,
-};
-
-static ssize_t si476x_radio_read_rsq_blob(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- int err;
- struct si476x_radio *radio = file->private_data;
- struct si476x_rsq_status_report report;
- struct si476x_rsq_status_args args = {
- .primary = false,
- .rsqack = false,
- .attune = false,
- .cancel = false,
- .stcack = false,
- };
-
- si476x_core_lock(radio->core);
- if (radio->ops->rds_blckcnt)
- err = radio->ops->rsq_status(radio->core, &args, &report);
- else
- err = -ENOENT;
- si476x_core_unlock(radio->core);
-
- if (err < 0)
- return err;
-
- return simple_read_from_buffer(user_buf, count, ppos, &report,
- sizeof(report));
-}
-
-static const struct file_operations radio_rsq_fops = {
- .open = simple_open,
- .llseek = default_llseek,
- .read = si476x_radio_read_rsq_blob,
-};
-
-static ssize_t si476x_radio_read_rsq_primary_blob(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- int err;
- struct si476x_radio *radio = file->private_data;
- struct si476x_rsq_status_report report;
- struct si476x_rsq_status_args args = {
- .primary = true,
- .rsqack = false,
- .attune = false,
- .cancel = false,
- .stcack = false,
- };
-
- si476x_core_lock(radio->core);
- if (radio->ops->rds_blckcnt)
- err = radio->ops->rsq_status(radio->core, &args, &report);
- else
- err = -ENOENT;
- si476x_core_unlock(radio->core);
-
- if (err < 0)
- return err;
-
- return simple_read_from_buffer(user_buf, count, ppos, &report,
- sizeof(report));
-}
-
-static const struct file_operations radio_rsq_primary_fops = {
- .open = simple_open,
- .llseek = default_llseek,
- .read = si476x_radio_read_rsq_primary_blob,
-};
-
-
-static void si476x_radio_init_debugfs(struct si476x_radio *radio)
-{
- radio->debugfs = debugfs_create_dir(dev_name(radio->v4l2dev.dev), NULL);
-
- debugfs_create_file("acf", S_IRUGO, radio->debugfs, radio,
- &radio_acf_fops);
-
- debugfs_create_file("rds_blckcnt", S_IRUGO, radio->debugfs, radio,
- &radio_rds_blckcnt_fops);
-
- debugfs_create_file("agc", S_IRUGO, radio->debugfs, radio,
- &radio_agc_fops);
-
- debugfs_create_file("rsq", S_IRUGO, radio->debugfs, radio,
- &radio_rsq_fops);
-
- debugfs_create_file("rsq_primary", S_IRUGO, radio->debugfs, radio,
- &radio_rsq_primary_fops);
-}
-
-
-static int si476x_radio_add_new_custom(struct si476x_radio *radio,
- enum si476x_ctrl_idx idx)
-{
- int rval;
- struct v4l2_ctrl *ctrl;
-
- ctrl = v4l2_ctrl_new_custom(&radio->ctrl_handler,
- &si476x_ctrls[idx],
- NULL);
- rval = radio->ctrl_handler.error;
- if (ctrl == NULL && rval)
- dev_err(radio->v4l2dev.dev,
- "Could not initialize '%s' control %d\n",
- si476x_ctrls[idx].name, rval);
-
- return rval;
-}
-
-static int si476x_radio_probe(struct platform_device *pdev)
-{
- int rval;
- struct si476x_radio *radio;
- struct v4l2_ctrl *ctrl;
-
- static atomic_t instance = ATOMIC_INIT(0);
-
- radio = devm_kzalloc(&pdev->dev, sizeof(*radio), GFP_KERNEL);
- if (!radio)
- return -ENOMEM;
-
- radio->core = i2c_mfd_cell_to_core(&pdev->dev);
-
- v4l2_device_set_name(&radio->v4l2dev, DRIVER_NAME, &instance);
-
- rval = v4l2_device_register(&pdev->dev, &radio->v4l2dev);
- if (rval) {
- dev_err(&pdev->dev, "Cannot register v4l2_device.\n");
- return rval;
- }
-
- memcpy(&radio->videodev, &si476x_viddev_template,
- sizeof(struct video_device));
-
- radio->videodev.v4l2_dev = &radio->v4l2dev;
- radio->videodev.ioctl_ops = &si4761_ioctl_ops;
- radio->videodev.device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
- V4L2_CAP_HW_FREQ_SEEK;
-
- si476x_core_lock(radio->core);
- if (!si476x_core_is_a_secondary_tuner(radio->core))
- radio->videodev.device_caps |= V4L2_CAP_RDS_CAPTURE |
- V4L2_CAP_READWRITE;
- si476x_core_unlock(radio->core);
-
- video_set_drvdata(&radio->videodev, radio);
- platform_set_drvdata(pdev, radio);
-
-
- radio->v4l2dev.ctrl_handler = &radio->ctrl_handler;
- v4l2_ctrl_handler_init(&radio->ctrl_handler,
- 1 + ARRAY_SIZE(si476x_ctrls));
-
- if (si476x_core_has_am(radio->core)) {
- ctrl = v4l2_ctrl_new_std_menu(&radio->ctrl_handler,
- &si476x_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ,
- 0, 0);
- rval = radio->ctrl_handler.error;
- if (ctrl == NULL && rval) {
- dev_err(&pdev->dev, "Could not initialize V4L2_CID_POWER_LINE_FREQUENCY control %d\n",
- rval);
- goto exit;
- }
-
- rval = si476x_radio_add_new_custom(radio,
- SI476X_IDX_HARMONICS_COUNT);
- if (rval < 0)
- goto exit;
- }
-
- rval = si476x_radio_add_new_custom(radio, SI476X_IDX_RSSI_THRESHOLD);
- if (rval < 0)
- goto exit;
-
- rval = si476x_radio_add_new_custom(radio, SI476X_IDX_SNR_THRESHOLD);
- if (rval < 0)
- goto exit;
-
- rval = si476x_radio_add_new_custom(radio, SI476X_IDX_MAX_TUNE_ERROR);
- if (rval < 0)
- goto exit;
-
- ctrl = v4l2_ctrl_new_std_menu(&radio->ctrl_handler,
- &si476x_ctrl_ops,
- V4L2_CID_TUNE_DEEMPHASIS,
- V4L2_DEEMPHASIS_75_uS, 0, 0);
- rval = radio->ctrl_handler.error;
- if (ctrl == NULL && rval) {
- dev_err(&pdev->dev, "Could not initialize V4L2_CID_TUNE_DEEMPHASIS control %d\n",
- rval);
- goto exit;
- }
-
- ctrl = v4l2_ctrl_new_std(&radio->ctrl_handler, &si476x_ctrl_ops,
- V4L2_CID_RDS_RECEPTION,
- 0, 1, 1, 1);
- rval = radio->ctrl_handler.error;
- if (ctrl == NULL && rval) {
- dev_err(&pdev->dev, "Could not initialize V4L2_CID_RDS_RECEPTION control %d\n",
- rval);
- goto exit;
- }
-
- if (si476x_core_has_diversity(radio->core)) {
- si476x_ctrls[SI476X_IDX_DIVERSITY_MODE].def =
- si476x_phase_diversity_mode_to_idx(radio->core->diversity_mode);
- rval = si476x_radio_add_new_custom(radio, SI476X_IDX_DIVERSITY_MODE);
- if (rval < 0)
- goto exit;
-
- rval = si476x_radio_add_new_custom(radio, SI476X_IDX_INTERCHIP_LINK);
- if (rval < 0)
- goto exit;
- }
-
- /* register video device */
- rval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, -1);
- if (rval < 0) {
- dev_err(&pdev->dev, "Could not register video device\n");
- goto exit;
- }
-
- si476x_radio_init_debugfs(radio);
-
- return 0;
-exit:
- v4l2_ctrl_handler_free(radio->videodev.ctrl_handler);
- v4l2_device_unregister(&radio->v4l2dev);
- return rval;
-}
-
-static void si476x_radio_remove(struct platform_device *pdev)
-{
- struct si476x_radio *radio = platform_get_drvdata(pdev);
-
- v4l2_ctrl_handler_free(radio->videodev.ctrl_handler);
- video_unregister_device(&radio->videodev);
- v4l2_device_unregister(&radio->v4l2dev);
- debugfs_remove_recursive(radio->debugfs);
-}
-
-MODULE_ALIAS("platform:si476x-radio");
-
-static struct platform_driver si476x_radio_driver = {
- .driver = {
- .name = DRIVER_NAME,
- },
- .probe = si476x_radio_probe,
- .remove = si476x_radio_remove,
-};
-module_platform_driver(si476x_radio_driver);
-
-MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
-MODULE_DESCRIPTION("Driver for Si4761/64/68 AM/FM Radio MFD Cell");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ce0c39b50af7..b271c9f0c5fc 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1425,19 +1425,6 @@ config MFD_SEC_I2C
on this driver so building this as a module might require proper
initial ramdisk or might not boot up as well in certain scenarios.
-config MFD_SI476X_CORE
- tristate "Silicon Laboratories 4761/64/68 AM/FM radio."
- depends on I2C
- select MFD_CORE
- select REGMAP_I2C
- help
- This is the core driver for the SI476x series of AM/FM
- radio. This MFD driver connects the radio-si476x V4L2 module
- and the si476x audio codec.
-
- To compile this driver as a module, choose M here: the
- module will be called si476x-core.
-
config MFD_SIMPLE_MFD_I2C
tristate
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a54eb18af56a..649262eb0f5c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -204,9 +204,6 @@ obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
-si476x-core-y := si476x-cmd.o si476x-prop.o si476x-i2c.o
-obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o
-
obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
obj-$(CONFIG_MFD_PM8XXX) += qcom-pm8xxx.o ssbi.o
diff --git a/drivers/mfd/si476x-cmd.c b/drivers/mfd/si476x-cmd.c
deleted file mode 100644
index 58e9bea7e90a..000000000000
--- a/drivers/mfd/si476x-cmd.c
+++ /dev/null
@@ -1,1543 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * drivers/mfd/si476x-cmd.c -- Subroutines implementing command
- * protocol of si476x series of chips
- *
- * Copyright (C) 2012 Innovative Converged Devices(ICD)
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/atomic.h>
-#include <linux/i2c.h>
-#include <linux/device.h>
-#include <linux/videodev2.h>
-
-#include <linux/mfd/si476x-core.h>
-
-#include <linux/unaligned.h>
-
-#define msb(x) ((u8)((u16) x >> 8))
-#define lsb(x) ((u8)((u16) x & 0x00FF))
-
-
-
-#define CMD_POWER_UP 0x01
-#define CMD_POWER_UP_A10_NRESP 1
-#define CMD_POWER_UP_A10_NARGS 5
-
-#define CMD_POWER_UP_A20_NRESP 1
-#define CMD_POWER_UP_A20_NARGS 5
-
-#define POWER_UP_DELAY_MS 110
-
-#define CMD_POWER_DOWN 0x11
-#define CMD_POWER_DOWN_A10_NRESP 1
-
-#define CMD_POWER_DOWN_A20_NRESP 1
-#define CMD_POWER_DOWN_A20_NARGS 1
-
-#define CMD_FUNC_INFO 0x12
-#define CMD_FUNC_INFO_NRESP 7
-
-#define CMD_SET_PROPERTY 0x13
-#define CMD_SET_PROPERTY_NARGS 5
-#define CMD_SET_PROPERTY_NRESP 1
-
-#define CMD_GET_PROPERTY 0x14
-#define CMD_GET_PROPERTY_NARGS 3
-#define CMD_GET_PROPERTY_NRESP 4
-
-#define CMD_AGC_STATUS 0x17
-#define CMD_AGC_STATUS_NRESP_A10 2
-#define CMD_AGC_STATUS_NRESP_A20 6
-
-#define PIN_CFG_BYTE(x) (0x7F & (x))
-#define CMD_DIG_AUDIO_PIN_CFG 0x18
-#define CMD_DIG_AUDIO_PIN_CFG_NARGS 4
-#define CMD_DIG_AUDIO_PIN_CFG_NRESP 5
-
-#define CMD_ZIF_PIN_CFG 0x19
-#define CMD_ZIF_PIN_CFG_NARGS 4
-#define CMD_ZIF_PIN_CFG_NRESP 5
-
-#define CMD_IC_LINK_GPO_CTL_PIN_CFG 0x1A
-#define CMD_IC_LINK_GPO_CTL_PIN_CFG_NARGS 4
-#define CMD_IC_LINK_GPO_CTL_PIN_CFG_NRESP 5
-
-#define CMD_ANA_AUDIO_PIN_CFG 0x1B
-#define CMD_ANA_AUDIO_PIN_CFG_NARGS 1
-#define CMD_ANA_AUDIO_PIN_CFG_NRESP 2
-
-#define CMD_INTB_PIN_CFG 0x1C
-#define CMD_INTB_PIN_CFG_NARGS 2
-#define CMD_INTB_PIN_CFG_A10_NRESP 6
-#define CMD_INTB_PIN_CFG_A20_NRESP 3
-
-#define CMD_FM_TUNE_FREQ 0x30
-#define CMD_FM_TUNE_FREQ_A10_NARGS 5
-#define CMD_FM_TUNE_FREQ_A20_NARGS 3
-#define CMD_FM_TUNE_FREQ_NRESP 1
-
-#define CMD_FM_RSQ_STATUS 0x32
-
-#define CMD_FM_RSQ_STATUS_A10_NARGS 1
-#define CMD_FM_RSQ_STATUS_A10_NRESP 17
-#define CMD_FM_RSQ_STATUS_A30_NARGS 1
-#define CMD_FM_RSQ_STATUS_A30_NRESP 23
-
-
-#define CMD_FM_SEEK_START 0x31
-#define CMD_FM_SEEK_START_NARGS 1
-#define CMD_FM_SEEK_START_NRESP 1
-
-#define CMD_FM_RDS_STATUS 0x36
-#define CMD_FM_RDS_STATUS_NARGS 1
-#define CMD_FM_RDS_STATUS_NRESP 16
-
-#define CMD_FM_RDS_BLOCKCOUNT 0x37
-#define CMD_FM_RDS_BLOCKCOUNT_NARGS 1
-#define CMD_FM_RDS_BLOCKCOUNT_NRESP 8
-
-#define CMD_FM_PHASE_DIVERSITY 0x38
-#define CMD_FM_PHASE_DIVERSITY_NARGS 1
-#define CMD_FM_PHASE_DIVERSITY_NRESP 1
-
-#define CMD_FM_PHASE_DIV_STATUS 0x39
-#define CMD_FM_PHASE_DIV_STATUS_NRESP 2
-
-#define CMD_AM_TUNE_FREQ 0x40
-#define CMD_AM_TUNE_FREQ_NARGS 3
-#define CMD_AM_TUNE_FREQ_NRESP 1
-
-#define CMD_AM_RSQ_STATUS 0x42
-#define CMD_AM_RSQ_STATUS_NARGS 1
-#define CMD_AM_RSQ_STATUS_NRESP 13
-
-#define CMD_AM_SEEK_START 0x41
-#define CMD_AM_SEEK_START_NARGS 1
-#define CMD_AM_SEEK_START_NRESP 1
-
-
-#define CMD_AM_ACF_STATUS 0x45
-#define CMD_AM_ACF_STATUS_NRESP 6
-#define CMD_AM_ACF_STATUS_NARGS 1
-
-#define CMD_FM_ACF_STATUS 0x35
-#define CMD_FM_ACF_STATUS_NRESP 8
-#define CMD_FM_ACF_STATUS_NARGS 1
-
-#define CMD_MAX_ARGS_COUNT (10)
-
-
-enum si476x_acf_status_report_bits {
- SI476X_ACF_BLEND_INT = (1 << 4),
- SI476X_ACF_HIBLEND_INT = (1 << 3),
- SI476X_ACF_HICUT_INT = (1 << 2),
- SI476X_ACF_CHBW_INT = (1 << 1),
- SI476X_ACF_SOFTMUTE_INT = (1 << 0),
-
- SI476X_ACF_SMUTE = (1 << 0),
- SI476X_ACF_SMATTN = 0x1f,
- SI476X_ACF_PILOT = (1 << 7),
- SI476X_ACF_STBLEND = ~SI476X_ACF_PILOT,
-};
-
-enum si476x_agc_status_report_bits {
- SI476X_AGC_MXHI = (1 << 5),
- SI476X_AGC_MXLO = (1 << 4),
- SI476X_AGC_LNAHI = (1 << 3),
- SI476X_AGC_LNALO = (1 << 2),
-};
-
-enum si476x_errors {
- SI476X_ERR_BAD_COMMAND = 0x10,
- SI476X_ERR_BAD_ARG1 = 0x11,
- SI476X_ERR_BAD_ARG2 = 0x12,
- SI476X_ERR_BAD_ARG3 = 0x13,
- SI476X_ERR_BAD_ARG4 = 0x14,
- SI476X_ERR_BUSY = 0x18,
- SI476X_ERR_BAD_INTERNAL_MEMORY = 0x20,
- SI476X_ERR_BAD_PATCH = 0x30,
- SI476X_ERR_BAD_BOOT_MODE = 0x31,
- SI476X_ERR_BAD_PROPERTY = 0x40,
-};
-
-static int si476x_core_parse_and_nag_about_error(struct si476x_core *core)
-{
- int err;
- char *cause;
- u8 buffer[2];
-
- if (core->revision != SI476X_REVISION_A10) {
- err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV,
- buffer, sizeof(buffer));
- if (err == sizeof(buffer)) {
- switch (buffer[1]) {
- case SI476X_ERR_BAD_COMMAND:
- cause = "Bad command";
- err = -EINVAL;
- break;
- case SI476X_ERR_BAD_ARG1:
- cause = "Bad argument #1";
- err = -EINVAL;
- break;
- case SI476X_ERR_BAD_ARG2:
- cause = "Bad argument #2";
- err = -EINVAL;
- break;
- case SI476X_ERR_BAD_ARG3:
- cause = "Bad argument #3";
- err = -EINVAL;
- break;
- case SI476X_ERR_BAD_ARG4:
- cause = "Bad argument #4";
- err = -EINVAL;
- break;
- case SI476X_ERR_BUSY:
- cause = "Chip is busy";
- err = -EBUSY;
- break;
- case SI476X_ERR_BAD_INTERNAL_MEMORY:
- cause = "Bad internal memory";
- err = -EIO;
- break;
- case SI476X_ERR_BAD_PATCH:
- cause = "Bad patch";
- err = -EINVAL;
- break;
- case SI476X_ERR_BAD_BOOT_MODE:
- cause = "Bad boot mode";
- err = -EINVAL;
- break;
- case SI476X_ERR_BAD_PROPERTY:
- cause = "Bad property";
- err = -EINVAL;
- break;
- default:
- cause = "Unknown";
- err = -EIO;
- }
-
- dev_err(&core->client->dev,
- "[Chip error status]: %s\n", cause);
- } else {
- dev_err(&core->client->dev,
- "Failed to fetch error code\n");
- err = (err >= 0) ? -EIO : err;
- }
- } else {
- err = -EIO;
- }
-
- return err;
-}
-
-/**
- * si476x_core_send_command() - sends a command to si476x and waits its
- * response
- * @core: si476x_device structure for the device we are
- * communicating with
- * @command: command id
- * @args: command arguments we are sending
- * @argn: actual size of @args
- * @resp: buffer to place the expected response from the device
- * @respn: actual size of @resp
- * @usecs: amount of time to wait before reading the response (in
- * usecs)
- *
- * Function returns 0 on success and negative error code on
- * failure
- */
-static int si476x_core_send_command(struct si476x_core *core,
- const u8 command,
- const u8 args[],
- const int argn,
- u8 resp[],
- const int respn,
- const int usecs)
-{
- struct i2c_client *client = core->client;
- int err;
- u8 data[CMD_MAX_ARGS_COUNT + 1];
-
- if (argn > CMD_MAX_ARGS_COUNT) {
- err = -ENOMEM;
- goto exit;
- }
-
- if (!client->adapter) {
- err = -ENODEV;
- goto exit;
- }
-
- /* First send the command and its arguments */
- data[0] = command;
- memcpy(&data[1], args, argn);
- dev_dbg(&client->dev, "Command:\n %*ph\n", argn + 1, data);
-
- err = si476x_core_i2c_xfer(core, SI476X_I2C_SEND,
- (char *) data, argn + 1);
- if (err != argn + 1) {
- dev_err(&core->client->dev,
- "Error while sending command 0x%02x\n",
- command);
- err = (err >= 0) ? -EIO : err;
- goto exit;
- }
- /* Set CTS to zero only after the command is send to avoid
- * possible racing conditions when working in polling mode */
- atomic_set(&core->cts, 0);
-
- /* if (unlikely(command == CMD_POWER_DOWN) */
- if (!wait_event_timeout(core->command,
- atomic_read(&core->cts),
- usecs_to_jiffies(usecs) + 1))
- dev_warn(&core->client->dev,
- "(%s) [CMD 0x%02x] Answer timeout.\n",
- __func__, command);
-
- /*
- When working in polling mode, for some reason the tuner will
- report CTS bit as being set in the first status byte read,
- but all the consequtive ones will return zeros until the
- tuner is actually completed the POWER_UP command. To
- workaround that we wait for second CTS to be reported
- */
- if (unlikely(!core->client->irq && command == CMD_POWER_UP)) {
- if (!wait_event_timeout(core->command,
- atomic_read(&core->cts),
- usecs_to_jiffies(usecs) + 1))
- dev_warn(&core->client->dev,
- "(%s) Power up took too much time.\n",
- __func__);
- }
-
- /* Then get the response */
- err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV, resp, respn);
- if (err != respn) {
- dev_err(&core->client->dev,
- "Error while reading response for command 0x%02x\n",
- command);
- err = (err >= 0) ? -EIO : err;
- goto exit;
- }
- dev_dbg(&client->dev, "Response:\n %*ph\n", respn, resp);
-
- err = 0;
-
- if (resp[0] & SI476X_ERR) {
- dev_err(&core->client->dev,
- "[CMD 0x%02x] Chip set error flag\n", command);
- err = si476x_core_parse_and_nag_about_error(core);
- goto exit;
- }
-
- if (!(resp[0] & SI476X_CTS))
- err = -EBUSY;
-exit:
- return err;
-}
-
-static int si476x_cmd_clear_stc(struct si476x_core *core)
-{
- int err;
- struct si476x_rsq_status_args args = {
- .primary = false,
- .rsqack = false,
- .attune = false,
- .cancel = false,
- .stcack = true,
- };
-
- switch (core->power_up_parameters.func) {
- case SI476X_FUNC_FM_RECEIVER:
- err = si476x_core_cmd_fm_rsq_status(core, &args, NULL);
- break;
- case SI476X_FUNC_AM_RECEIVER:
- err = si476x_core_cmd_am_rsq_status(core, &args, NULL);
- break;
- default:
- err = -EINVAL;
- }
-
- return err;
-}
-
-static int si476x_cmd_tune_seek_freq(struct si476x_core *core,
- uint8_t cmd,
- const uint8_t args[], size_t argn,
- uint8_t *resp, size_t respn)
-{
- int err;
-
-
- atomic_set(&core->stc, 0);
- err = si476x_core_send_command(core, cmd, args, argn, resp, respn,
- SI476X_TIMEOUT_TUNE);
- if (!err) {
- wait_event_killable(core->tuning,
- atomic_read(&core->stc));
- si476x_cmd_clear_stc(core);
- }
-
- return err;
-}
-
-/**
- * si476x_core_cmd_func_info() - send 'FUNC_INFO' command to the device
- * @core: device to send the command to
- * @info: struct si476x_func_info to fill all the information
- * returned by the command
- *
- * The command requests the firmware and patch version for currently
- * loaded firmware (dependent on the function of the device FM/AM/WB)
- *
- * Function returns 0 on success and negative error code on
- * failure
- */
-int si476x_core_cmd_func_info(struct si476x_core *core,
- struct si476x_func_info *info)
-{
- int err;
- u8 resp[CMD_FUNC_INFO_NRESP];
-
- err = si476x_core_send_command(core, CMD_FUNC_INFO,
- NULL, 0,
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-
- info->firmware.major = resp[1];
- info->firmware.minor[0] = resp[2];
- info->firmware.minor[1] = resp[3];
-
- info->patch_id = ((u16) resp[4] << 8) | resp[5];
- info->func = resp[6];
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_func_info);
-
-/**
- * si476x_core_cmd_set_property() - send 'SET_PROPERTY' command to the device
- * @core: device to send the command to
- * @property: property address
- * @value: property value
- *
- * Function returns 0 on success and negative error code on
- * failure
- */
-int si476x_core_cmd_set_property(struct si476x_core *core,
- u16 property, u16 value)
-{
- u8 resp[CMD_SET_PROPERTY_NRESP];
- const u8 args[CMD_SET_PROPERTY_NARGS] = {
- 0x00,
- msb(property),
- lsb(property),
- msb(value),
- lsb(value),
- };
-
- return si476x_core_send_command(core, CMD_SET_PROPERTY,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_set_property);
-
-/**
- * si476x_core_cmd_get_property() - send 'GET_PROPERTY' command to the device
- * @core: device to send the command to
- * @property: property address
- *
- * Function return the value of property as u16 on success or a
- * negative error on failure
- */
-int si476x_core_cmd_get_property(struct si476x_core *core, u16 property)
-{
- int err;
- u8 resp[CMD_GET_PROPERTY_NRESP];
- const u8 args[CMD_GET_PROPERTY_NARGS] = {
- 0x00,
- msb(property),
- lsb(property),
- };
-
- err = si476x_core_send_command(core, CMD_GET_PROPERTY,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- if (err < 0)
- return err;
- else
- return get_unaligned_be16(resp + 2);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property);
-
-/**
- * si476x_core_cmd_dig_audio_pin_cfg() - send 'DIG_AUDIO_PIN_CFG' command to
- * the device
- * @core: device to send the command to
- * @dclk: DCLK pin function configuration:
- * #SI476X_DCLK_NOOP - do not modify the behaviour
- * #SI476X_DCLK_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * #SI476X_DCLK_DAUDIO - set the pin to be a part of digital
- * audio interface
- * @dfs: DFS pin function configuration:
- * #SI476X_DFS_NOOP - do not modify the behaviour
- * #SI476X_DFS_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_DFS_DAUDIO - set the pin to be a part of digital
- * audio interface
- * @dout: - DOUT pin function configuration:
- * SI476X_DOUT_NOOP - do not modify the behaviour
- * SI476X_DOUT_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_DOUT_I2S_OUTPUT - set this pin to be digital out on I2S
- * port 1
- * SI476X_DOUT_I2S_INPUT - set this pin to be digital in on I2S
- * port 1
- * @xout: - XOUT pin function configuration:
- * SI476X_XOUT_NOOP - do not modify the behaviour
- * SI476X_XOUT_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_XOUT_I2S_INPUT - set this pin to be digital in on I2S
- * port 1
- * SI476X_XOUT_MODE_SELECT - set this pin to be the input that
- * selects the mode of the I2S audio
- * combiner (analog or HD)
- * [SI4761/63/65/67 Only]
- *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_dig_audio_pin_cfg(struct si476x_core *core,
- enum si476x_dclk_config dclk,
- enum si476x_dfs_config dfs,
- enum si476x_dout_config dout,
- enum si476x_xout_config xout)
-{
- u8 resp[CMD_DIG_AUDIO_PIN_CFG_NRESP];
- const u8 args[CMD_DIG_AUDIO_PIN_CFG_NARGS] = {
- PIN_CFG_BYTE(dclk),
- PIN_CFG_BYTE(dfs),
- PIN_CFG_BYTE(dout),
- PIN_CFG_BYTE(xout),
- };
-
- return si476x_core_send_command(core, CMD_DIG_AUDIO_PIN_CFG,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_dig_audio_pin_cfg);
-
-/**
- * si476x_core_cmd_zif_pin_cfg - send 'ZIF_PIN_CFG_COMMAND'
- * @core: - device to send the command to
- * @iqclk: - IQCL pin function configuration:
- * SI476X_IQCLK_NOOP - do not modify the behaviour
- * SI476X_IQCLK_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_IQCLK_IQ - set pin to be a part of I/Q interface
- * in master mode
- * @iqfs: - IQFS pin function configuration:
- * SI476X_IQFS_NOOP - do not modify the behaviour
- * SI476X_IQFS_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_IQFS_IQ - set pin to be a part of I/Q interface
- * in master mode
- * @iout: - IOUT pin function configuration:
- * SI476X_IOUT_NOOP - do not modify the behaviour
- * SI476X_IOUT_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_IOUT_OUTPUT - set pin to be I out
- * @qout: - QOUT pin function configuration:
- * SI476X_QOUT_NOOP - do not modify the behaviour
- * SI476X_QOUT_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_QOUT_OUTPUT - set pin to be Q out
- *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_zif_pin_cfg(struct si476x_core *core,
- enum si476x_iqclk_config iqclk,
- enum si476x_iqfs_config iqfs,
- enum si476x_iout_config iout,
- enum si476x_qout_config qout)
-{
- u8 resp[CMD_ZIF_PIN_CFG_NRESP];
- const u8 args[CMD_ZIF_PIN_CFG_NARGS] = {
- PIN_CFG_BYTE(iqclk),
- PIN_CFG_BYTE(iqfs),
- PIN_CFG_BYTE(iout),
- PIN_CFG_BYTE(qout),
- };
-
- return si476x_core_send_command(core, CMD_ZIF_PIN_CFG,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_zif_pin_cfg);
-
-/**
- * si476x_core_cmd_ic_link_gpo_ctl_pin_cfg - send
- * 'IC_LINK_GPIO_CTL_PIN_CFG' command to the device
- * @core: - device to send the command to
- * @icin: - ICIN pin function configuration:
- * SI476X_ICIN_NOOP - do not modify the behaviour
- * SI476X_ICIN_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_ICIN_GPO1_HIGH - set pin to be an output, drive it high
- * SI476X_ICIN_GPO1_LOW - set pin to be an output, drive it low
- * SI476X_ICIN_IC_LINK - set the pin to be a part of Inter-Chip link
- * @icip: - ICIP pin function configuration:
- * SI476X_ICIP_NOOP - do not modify the behaviour
- * SI476X_ICIP_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_ICIP_GPO1_HIGH - set pin to be an output, drive it high
- * SI476X_ICIP_GPO1_LOW - set pin to be an output, drive it low
- * SI476X_ICIP_IC_LINK - set the pin to be a part of Inter-Chip link
- * @icon: - ICON pin function configuration:
- * SI476X_ICON_NOOP - do not modify the behaviour
- * SI476X_ICON_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_ICON_I2S - set the pin to be a part of audio
- * interface in slave mode (DCLK)
- * SI476X_ICON_IC_LINK - set the pin to be a part of Inter-Chip link
- * @icop: - ICOP pin function configuration:
- * SI476X_ICOP_NOOP - do not modify the behaviour
- * SI476X_ICOP_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_ICOP_I2S - set the pin to be a part of audio
- * interface in slave mode (DOUT)
- * [Si4761/63/65/67 Only]
- * SI476X_ICOP_IC_LINK - set the pin to be a part of Inter-Chip link
- *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(struct si476x_core *core,
- enum si476x_icin_config icin,
- enum si476x_icip_config icip,
- enum si476x_icon_config icon,
- enum si476x_icop_config icop)
-{
- u8 resp[CMD_IC_LINK_GPO_CTL_PIN_CFG_NRESP];
- const u8 args[CMD_IC_LINK_GPO_CTL_PIN_CFG_NARGS] = {
- PIN_CFG_BYTE(icin),
- PIN_CFG_BYTE(icip),
- PIN_CFG_BYTE(icon),
- PIN_CFG_BYTE(icop),
- };
-
- return si476x_core_send_command(core, CMD_IC_LINK_GPO_CTL_PIN_CFG,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_ic_link_gpo_ctl_pin_cfg);
-
-/**
- * si476x_core_cmd_ana_audio_pin_cfg - send 'ANA_AUDIO_PIN_CFG' to the
- * device
- * @core: - device to send the command to
- * @lrout: - LROUT pin function configuration:
- * SI476X_LROUT_NOOP - do not modify the behaviour
- * SI476X_LROUT_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_LROUT_AUDIO - set pin to be audio output
- * SI476X_LROUT_MPX - set pin to be MPX output
- *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_ana_audio_pin_cfg(struct si476x_core *core,
- enum si476x_lrout_config lrout)
-{
- u8 resp[CMD_ANA_AUDIO_PIN_CFG_NRESP];
- const u8 args[CMD_ANA_AUDIO_PIN_CFG_NARGS] = {
- PIN_CFG_BYTE(lrout),
- };
-
- return si476x_core_send_command(core, CMD_ANA_AUDIO_PIN_CFG,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_ana_audio_pin_cfg);
-
-
-/**
- * si476x_core_cmd_intb_pin_cfg_a10 - send 'INTB_PIN_CFG' command to the device
- * @core: - device to send the command to
- * @intb: - INTB pin function configuration:
- * SI476X_INTB_NOOP - do not modify the behaviour
- * SI476X_INTB_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_INTB_DAUDIO - set pin to be a part of digital
- * audio interface in slave mode
- * SI476X_INTB_IRQ - set pin to be an interrupt request line
- * @a1: - A1 pin function configuration:
- * SI476X_A1_NOOP - do not modify the behaviour
- * SI476X_A1_TRISTATE - put the pin in tristate condition,
- * enable 1MOhm pulldown
- * SI476X_A1_IRQ - set pin to be an interrupt request line
- *
- * Function returns 0 on success and negative error code on failure
- */
-static int si476x_core_cmd_intb_pin_cfg_a10(struct si476x_core *core,
- enum si476x_intb_config intb,
- enum si476x_a1_config a1)
-{
- u8 resp[CMD_INTB_PIN_CFG_A10_NRESP];
- const u8 args[CMD_INTB_PIN_CFG_NARGS] = {
- PIN_CFG_BYTE(intb),
- PIN_CFG_BYTE(a1),
- };
-
- return si476x_core_send_command(core, CMD_INTB_PIN_CFG,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-
-static int si476x_core_cmd_intb_pin_cfg_a20(struct si476x_core *core,
- enum si476x_intb_config intb,
- enum si476x_a1_config a1)
-{
- u8 resp[CMD_INTB_PIN_CFG_A20_NRESP];
- const u8 args[CMD_INTB_PIN_CFG_NARGS] = {
- PIN_CFG_BYTE(intb),
- PIN_CFG_BYTE(a1),
- };
-
- return si476x_core_send_command(core, CMD_INTB_PIN_CFG,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-
-
-
-/**
- * si476x_core_cmd_am_rsq_status - send 'AM_RSQ_STATUS' command to the
- * device
- * @core: - device to send the command to
- * @rsqargs: - pointer to a structure containing a group of sub-args
- * relevant to sending the RSQ status command
- * @report: - all signal quality information returned by the command
- * (if NULL then the output of the command is ignored)
- *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_am_rsq_status(struct si476x_core *core,
- struct si476x_rsq_status_args *rsqargs,
- struct si476x_rsq_status_report *report)
-{
- int err;
- u8 resp[CMD_AM_RSQ_STATUS_NRESP];
- const u8 args[CMD_AM_RSQ_STATUS_NARGS] = {
- rsqargs->rsqack << 3 | rsqargs->attune << 2 |
- rsqargs->cancel << 1 | rsqargs->stcack,
- };
-
- err = si476x_core_send_command(core, CMD_AM_RSQ_STATUS,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- /*
- * Besides getting received signal quality information this
- * command can be used to just acknowledge different interrupt
- * flags in those cases it is useless to copy and parse
- * received data so user can pass NULL, and thus avoid
- * unnecessary copying.
- */
- if (!report)
- return err;
-
- report->snrhint = 0x08 & resp[1];
- report->snrlint = 0x04 & resp[1];
- report->rssihint = 0x02 & resp[1];
- report->rssilint = 0x01 & resp[1];
-
- report->bltf = 0x80 & resp[2];
- report->snr_ready = 0x20 & resp[2];
- report->rssiready = 0x08 & resp[2];
- report->afcrl = 0x02 & resp[2];
- report->valid = 0x01 & resp[2];
-
- report->readfreq = get_unaligned_be16(resp + 3);
- report->freqoff = resp[5];
- report->rssi = resp[6];
- report->snr = resp[7];
- report->lassi = resp[9];
- report->hassi = resp[10];
- report->mult = resp[11];
- report->dev = resp[12];
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_am_rsq_status);
-
-int si476x_core_cmd_fm_acf_status(struct si476x_core *core,
- struct si476x_acf_status_report *report)
-{
- int err;
- u8 resp[CMD_FM_ACF_STATUS_NRESP];
- const u8 args[CMD_FM_ACF_STATUS_NARGS] = {
- 0x0,
- };
-
- if (!report)
- return -EINVAL;
-
- err = si476x_core_send_command(core, CMD_FM_ACF_STATUS,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- if (err < 0)
- return err;
-
- report->blend_int = resp[1] & SI476X_ACF_BLEND_INT;
- report->hblend_int = resp[1] & SI476X_ACF_HIBLEND_INT;
- report->hicut_int = resp[1] & SI476X_ACF_HICUT_INT;
- report->chbw_int = resp[1] & SI476X_ACF_CHBW_INT;
- report->softmute_int = resp[1] & SI476X_ACF_SOFTMUTE_INT;
- report->smute = resp[2] & SI476X_ACF_SMUTE;
- report->smattn = resp[3] & SI476X_ACF_SMATTN;
- report->chbw = resp[4];
- report->hicut = resp[5];
- report->hiblend = resp[6];
- report->pilot = resp[7] & SI476X_ACF_PILOT;
- report->stblend = resp[7] & SI476X_ACF_STBLEND;
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_acf_status);
-
-int si476x_core_cmd_am_acf_status(struct si476x_core *core,
- struct si476x_acf_status_report *report)
-{
- int err;
- u8 resp[CMD_AM_ACF_STATUS_NRESP];
- const u8 args[CMD_AM_ACF_STATUS_NARGS] = {
- 0x0,
- };
-
- if (!report)
- return -EINVAL;
-
- err = si476x_core_send_command(core, CMD_AM_ACF_STATUS,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- if (err < 0)
- return err;
-
- report->blend_int = resp[1] & SI476X_ACF_BLEND_INT;
- report->hblend_int = resp[1] & SI476X_ACF_HIBLEND_INT;
- report->hicut_int = resp[1] & SI476X_ACF_HICUT_INT;
- report->chbw_int = resp[1] & SI476X_ACF_CHBW_INT;
- report->softmute_int = resp[1] & SI476X_ACF_SOFTMUTE_INT;
- report->smute = resp[2] & SI476X_ACF_SMUTE;
- report->smattn = resp[3] & SI476X_ACF_SMATTN;
- report->chbw = resp[4];
- report->hicut = resp[5];
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_am_acf_status);
-
-
-/**
- * si476x_core_cmd_fm_seek_start - send 'FM_SEEK_START' command to the
- * device
- * @core: - device to send the command to
- * @seekup: - if set the direction of the search is 'up'
- * @wrap: - if set seek wraps when hitting band limit
- *
- * This function begins search for a valid station. The station is
- * considered valid when 'FM_VALID_SNR_THRESHOLD' and
- * 'FM_VALID_RSSI_THRESHOLD' and 'FM_VALID_MAX_TUNE_ERROR' criteria
- * are met.
-} *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_fm_seek_start(struct si476x_core *core,
- bool seekup, bool wrap)
-{
- u8 resp[CMD_FM_SEEK_START_NRESP];
- const u8 args[CMD_FM_SEEK_START_NARGS] = {
- seekup << 3 | wrap << 2,
- };
-
- return si476x_cmd_tune_seek_freq(core, CMD_FM_SEEK_START,
- args, sizeof(args),
- resp, sizeof(resp));
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_seek_start);
-
-/**
- * si476x_core_cmd_fm_rds_status - send 'FM_RDS_STATUS' command to the
- * device
- * @core: - device to send the command to
- * @status_only: - if set the data is not removed from RDSFIFO,
- * RDSFIFOUSED is not decremented and data in all the
- * rest RDS data contains the last valid info received
- * @mtfifo: if set the command clears RDS receive FIFO
- * @intack: if set the command clards the RDSINT bit.
- * @report: - all signal quality information returned by the command
- * (if NULL then the output of the command is ignored)
- *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_fm_rds_status(struct si476x_core *core,
- bool status_only,
- bool mtfifo,
- bool intack,
- struct si476x_rds_status_report *report)
-{
- int err;
- u8 resp[CMD_FM_RDS_STATUS_NRESP];
- const u8 args[CMD_FM_RDS_STATUS_NARGS] = {
- status_only << 2 | mtfifo << 1 | intack,
- };
-
- err = si476x_core_send_command(core, CMD_FM_RDS_STATUS,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- /*
- * Besides getting RDS status information this command can be
- * used to just acknowledge different interrupt flags in those
- * cases it is useless to copy and parse received data so user
- * can pass NULL, and thus avoid unnecessary copying.
- */
- if (err < 0 || report == NULL)
- return err;
-
- report->rdstpptyint = 0x10 & resp[1];
- report->rdspiint = 0x08 & resp[1];
- report->rdssyncint = 0x02 & resp[1];
- report->rdsfifoint = 0x01 & resp[1];
-
- report->tpptyvalid = 0x10 & resp[2];
- report->pivalid = 0x08 & resp[2];
- report->rdssync = 0x02 & resp[2];
- report->rdsfifolost = 0x01 & resp[2];
-
- report->tp = 0x20 & resp[3];
- report->pty = 0x1f & resp[3];
-
- report->pi = get_unaligned_be16(resp + 4);
- report->rdsfifoused = resp[6];
-
- report->ble[V4L2_RDS_BLOCK_A] = 0xc0 & resp[7];
- report->ble[V4L2_RDS_BLOCK_B] = 0x30 & resp[7];
- report->ble[V4L2_RDS_BLOCK_C] = 0x0c & resp[7];
- report->ble[V4L2_RDS_BLOCK_D] = 0x03 & resp[7];
-
- report->rds[V4L2_RDS_BLOCK_A].block = V4L2_RDS_BLOCK_A;
- report->rds[V4L2_RDS_BLOCK_A].msb = resp[8];
- report->rds[V4L2_RDS_BLOCK_A].lsb = resp[9];
-
- report->rds[V4L2_RDS_BLOCK_B].block = V4L2_RDS_BLOCK_B;
- report->rds[V4L2_RDS_BLOCK_B].msb = resp[10];
- report->rds[V4L2_RDS_BLOCK_B].lsb = resp[11];
-
- report->rds[V4L2_RDS_BLOCK_C].block = V4L2_RDS_BLOCK_C;
- report->rds[V4L2_RDS_BLOCK_C].msb = resp[12];
- report->rds[V4L2_RDS_BLOCK_C].lsb = resp[13];
-
- report->rds[V4L2_RDS_BLOCK_D].block = V4L2_RDS_BLOCK_D;
- report->rds[V4L2_RDS_BLOCK_D].msb = resp[14];
- report->rds[V4L2_RDS_BLOCK_D].lsb = resp[15];
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_rds_status);
-
-int si476x_core_cmd_fm_rds_blockcount(struct si476x_core *core,
- bool clear,
- struct si476x_rds_blockcount_report *report)
-{
- int err;
- u8 resp[CMD_FM_RDS_BLOCKCOUNT_NRESP];
- const u8 args[CMD_FM_RDS_BLOCKCOUNT_NARGS] = {
- clear,
- };
-
- if (!report)
- return -EINVAL;
-
- err = si476x_core_send_command(core, CMD_FM_RDS_BLOCKCOUNT,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-
- if (!err) {
- report->expected = get_unaligned_be16(resp + 2);
- report->received = get_unaligned_be16(resp + 4);
- report->uncorrectable = get_unaligned_be16(resp + 6);
- }
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_rds_blockcount);
-
-int si476x_core_cmd_fm_phase_diversity(struct si476x_core *core,
- enum si476x_phase_diversity_mode mode)
-{
- u8 resp[CMD_FM_PHASE_DIVERSITY_NRESP];
- const u8 args[CMD_FM_PHASE_DIVERSITY_NARGS] = {
- mode & 0x07,
- };
-
- return si476x_core_send_command(core, CMD_FM_PHASE_DIVERSITY,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_phase_diversity);
-/**
- * si476x_core_cmd_fm_phase_div_status() - get the phase diversity
- * status
- *
- * @core: si476x device
- *
- * NOTE caller must hold core lock
- *
- * Function returns the value of the status bit in case of success and
- * negative error code in case of failure.
- */
-int si476x_core_cmd_fm_phase_div_status(struct si476x_core *core)
-{
- int err;
- u8 resp[CMD_FM_PHASE_DIV_STATUS_NRESP];
-
- err = si476x_core_send_command(core, CMD_FM_PHASE_DIV_STATUS,
- NULL, 0,
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-
- return (err < 0) ? err : resp[1];
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_phase_div_status);
-
-
-/**
- * si476x_core_cmd_am_seek_start - send 'FM_SEEK_START' command to the
- * device
- * @core: - device to send the command to
- * @seekup: - if set the direction of the search is 'up'
- * @wrap: - if set seek wraps when hitting band limit
- *
- * This function begins search for a valid station. The station is
- * considered valid when 'FM_VALID_SNR_THRESHOLD' and
- * 'FM_VALID_RSSI_THRESHOLD' and 'FM_VALID_MAX_TUNE_ERROR' criteria
- * are met.
- *
- * Function returns 0 on success and negative error code on failure
- */
-int si476x_core_cmd_am_seek_start(struct si476x_core *core,
- bool seekup, bool wrap)
-{
- u8 resp[CMD_AM_SEEK_START_NRESP];
- const u8 args[CMD_AM_SEEK_START_NARGS] = {
- seekup << 3 | wrap << 2,
- };
-
- return si476x_cmd_tune_seek_freq(core, CMD_AM_SEEK_START,
- args, sizeof(args),
- resp, sizeof(resp));
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_am_seek_start);
-
-
-
-static int si476x_core_cmd_power_up_a10(struct si476x_core *core,
- struct si476x_power_up_args *puargs)
-{
- u8 resp[CMD_POWER_UP_A10_NRESP];
- const bool intsel = (core->pinmux.a1 == SI476X_A1_IRQ);
- const bool ctsen = (core->client->irq != 0);
- const u8 args[CMD_POWER_UP_A10_NARGS] = {
- 0xF7, /* Reserved, always 0xF7 */
- 0x3F & puargs->xcload, /* First two bits are reserved to be
- * zeros */
- ctsen << 7 | intsel << 6 | 0x07, /* Last five bits
- * are reserved to
- * be written as 0x7 */
- puargs->func << 4 | puargs->freq,
- 0x11, /* Reserved, always 0x11 */
- };
-
- return si476x_core_send_command(core, CMD_POWER_UP,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_TIMEOUT_POWER_UP);
-}
-
-static int si476x_core_cmd_power_up_a20(struct si476x_core *core,
- struct si476x_power_up_args *puargs)
-{
- u8 resp[CMD_POWER_UP_A20_NRESP];
- const bool intsel = (core->pinmux.a1 == SI476X_A1_IRQ);
- const bool ctsen = (core->client->irq != 0);
- const u8 args[CMD_POWER_UP_A20_NARGS] = {
- puargs->ibias6x << 7 | puargs->xstart,
- 0x3F & puargs->xcload, /* First two bits are reserved to be
- * zeros */
- ctsen << 7 | intsel << 6 | puargs->fastboot << 5 |
- puargs->xbiashc << 3 | puargs->xbias,
- puargs->func << 4 | puargs->freq,
- 0x10 | puargs->xmode,
- };
-
- return si476x_core_send_command(core, CMD_POWER_UP,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_TIMEOUT_POWER_UP);
-}
-
-static int si476x_core_cmd_power_down_a10(struct si476x_core *core,
- struct si476x_power_down_args *pdargs)
-{
- u8 resp[CMD_POWER_DOWN_A10_NRESP];
-
- return si476x_core_send_command(core, CMD_POWER_DOWN,
- NULL, 0,
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-
-static int si476x_core_cmd_power_down_a20(struct si476x_core *core,
- struct si476x_power_down_args *pdargs)
-{
- u8 resp[CMD_POWER_DOWN_A20_NRESP];
- const u8 args[CMD_POWER_DOWN_A20_NARGS] = {
- pdargs->xosc,
- };
- return si476x_core_send_command(core, CMD_POWER_DOWN,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
-}
-
-static int si476x_core_cmd_am_tune_freq_a10(struct si476x_core *core,
- struct si476x_tune_freq_args *tuneargs)
-{
-
- const int am_freq = tuneargs->freq;
- u8 resp[CMD_AM_TUNE_FREQ_NRESP];
- const u8 args[CMD_AM_TUNE_FREQ_NARGS] = {
- (tuneargs->hd << 6),
- msb(am_freq),
- lsb(am_freq),
- };
-
- return si476x_cmd_tune_seek_freq(core, CMD_AM_TUNE_FREQ, args,
- sizeof(args),
- resp, sizeof(resp));
-}
-
-static int si476x_core_cmd_am_tune_freq_a20(struct si476x_core *core,
- struct si476x_tune_freq_args *tuneargs)
-{
- const int am_freq = tuneargs->freq;
- u8 resp[CMD_AM_TUNE_FREQ_NRESP];
- const u8 args[CMD_AM_TUNE_FREQ_NARGS] = {
- (tuneargs->zifsr << 6) | (tuneargs->injside & 0x03),
- msb(am_freq),
- lsb(am_freq),
- };
-
- return si476x_cmd_tune_seek_freq(core, CMD_AM_TUNE_FREQ,
- args, sizeof(args),
- resp, sizeof(resp));
-}
-
-static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core,
- struct si476x_rsq_status_args *rsqargs,
- struct si476x_rsq_status_report *report)
-{
- int err;
- u8 resp[CMD_FM_RSQ_STATUS_A10_NRESP];
- const u8 args[CMD_FM_RSQ_STATUS_A10_NARGS] = {
- rsqargs->rsqack << 3 | rsqargs->attune << 2 |
- rsqargs->cancel << 1 | rsqargs->stcack,
- };
-
- err = si476x_core_send_command(core, CMD_FM_RSQ_STATUS,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- /*
- * Besides getting received signal quality information this
- * command can be used to just acknowledge different interrupt
- * flags in those cases it is useless to copy and parse
- * received data so user can pass NULL, and thus avoid
- * unnecessary copying.
- */
- if (err < 0 || report == NULL)
- return err;
-
- report->multhint = 0x80 & resp[1];
- report->multlint = 0x40 & resp[1];
- report->snrhint = 0x08 & resp[1];
- report->snrlint = 0x04 & resp[1];
- report->rssihint = 0x02 & resp[1];
- report->rssilint = 0x01 & resp[1];
-
- report->bltf = 0x80 & resp[2];
- report->snr_ready = 0x20 & resp[2];
- report->rssiready = 0x08 & resp[2];
- report->afcrl = 0x02 & resp[2];
- report->valid = 0x01 & resp[2];
-
- report->readfreq = get_unaligned_be16(resp + 3);
- report->freqoff = resp[5];
- report->rssi = resp[6];
- report->snr = resp[7];
- report->lassi = resp[9];
- report->hassi = resp[10];
- report->mult = resp[11];
- report->dev = resp[12];
- report->readantcap = get_unaligned_be16(resp + 13);
- report->assi = resp[15];
- report->usn = resp[16];
-
- return err;
-}
-
-static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core,
- struct si476x_rsq_status_args *rsqargs,
- struct si476x_rsq_status_report *report)
-{
- int err;
- u8 resp[CMD_FM_RSQ_STATUS_A10_NRESP];
- const u8 args[CMD_FM_RSQ_STATUS_A30_NARGS] = {
- rsqargs->primary << 4 | rsqargs->rsqack << 3 |
- rsqargs->attune << 2 | rsqargs->cancel << 1 |
- rsqargs->stcack,
- };
-
- err = si476x_core_send_command(core, CMD_FM_RSQ_STATUS,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- /*
- * Besides getting received signal quality information this
- * command can be used to just acknowledge different interrupt
- * flags in those cases it is useless to copy and parse
- * received data so user can pass NULL, and thus avoid
- * unnecessary copying.
- */
- if (err < 0 || report == NULL)
- return err;
-
- report->multhint = 0x80 & resp[1];
- report->multlint = 0x40 & resp[1];
- report->snrhint = 0x08 & resp[1];
- report->snrlint = 0x04 & resp[1];
- report->rssihint = 0x02 & resp[1];
- report->rssilint = 0x01 & resp[1];
-
- report->bltf = 0x80 & resp[2];
- report->snr_ready = 0x20 & resp[2];
- report->rssiready = 0x08 & resp[2];
- report->afcrl = 0x02 & resp[2];
- report->valid = 0x01 & resp[2];
-
- report->readfreq = get_unaligned_be16(resp + 3);
- report->freqoff = resp[5];
- report->rssi = resp[6];
- report->snr = resp[7];
- report->lassi = resp[9];
- report->hassi = resp[10];
- report->mult = resp[11];
- report->dev = resp[12];
- report->readantcap = get_unaligned_be16(resp + 13);
- report->assi = resp[15];
- report->usn = resp[16];
-
- return err;
-}
-
-
-static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
- struct si476x_rsq_status_args *rsqargs,
- struct si476x_rsq_status_report *report)
-{
- int err;
- u8 resp[CMD_FM_RSQ_STATUS_A30_NRESP];
- const u8 args[CMD_FM_RSQ_STATUS_A30_NARGS] = {
- rsqargs->primary << 4 | rsqargs->rsqack << 3 |
- rsqargs->attune << 2 | rsqargs->cancel << 1 |
- rsqargs->stcack,
- };
-
- err = si476x_core_send_command(core, CMD_FM_RSQ_STATUS,
- args, ARRAY_SIZE(args),
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- /*
- * Besides getting received signal quality information this
- * command can be used to just acknowledge different interrupt
- * flags in those cases it is useless to copy and parse
- * received data so user can pass NULL, and thus avoid
- * unnecessary copying.
- */
- if (err < 0 || report == NULL)
- return err;
-
- report->multhint = 0x80 & resp[1];
- report->multlint = 0x40 & resp[1];
- report->snrhint = 0x08 & resp[1];
- report->snrlint = 0x04 & resp[1];
- report->rssihint = 0x02 & resp[1];
- report->rssilint = 0x01 & resp[1];
-
- report->bltf = 0x80 & resp[2];
- report->snr_ready = 0x20 & resp[2];
- report->rssiready = 0x08 & resp[2];
- report->injside = 0x04 & resp[2];
- report->afcrl = 0x02 & resp[2];
- report->valid = 0x01 & resp[2];
-
- report->readfreq = get_unaligned_be16(resp + 3);
- report->freqoff = resp[5];
- report->rssi = resp[6];
- report->snr = resp[7];
- report->issi = resp[8];
- report->lassi = resp[9];
- report->hassi = resp[10];
- report->mult = resp[11];
- report->dev = resp[12];
- report->readantcap = get_unaligned_be16(resp + 13);
- report->assi = resp[15];
- report->usn = resp[16];
-
- report->pilotdev = resp[17];
- report->rdsdev = resp[18];
- report->assidev = resp[19];
- report->strongdev = resp[20];
- report->rdspi = get_unaligned_be16(resp + 21);
-
- return err;
-}
-
-static int si476x_core_cmd_fm_tune_freq_a10(struct si476x_core *core,
- struct si476x_tune_freq_args *tuneargs)
-{
- u8 resp[CMD_FM_TUNE_FREQ_NRESP];
- const u8 args[CMD_FM_TUNE_FREQ_A10_NARGS] = {
- (tuneargs->hd << 6) | (tuneargs->tunemode << 4)
- | (tuneargs->smoothmetrics << 2),
- msb(tuneargs->freq),
- lsb(tuneargs->freq),
- msb(tuneargs->antcap),
- lsb(tuneargs->antcap)
- };
-
- return si476x_cmd_tune_seek_freq(core, CMD_FM_TUNE_FREQ,
- args, sizeof(args),
- resp, sizeof(resp));
-}
-
-static int si476x_core_cmd_fm_tune_freq_a20(struct si476x_core *core,
- struct si476x_tune_freq_args *tuneargs)
-{
- u8 resp[CMD_FM_TUNE_FREQ_NRESP];
- const u8 args[CMD_FM_TUNE_FREQ_A20_NARGS] = {
- (tuneargs->hd << 6) | (tuneargs->tunemode << 4)
- | (tuneargs->smoothmetrics << 2) | (tuneargs->injside),
- msb(tuneargs->freq),
- lsb(tuneargs->freq),
- };
-
- return si476x_cmd_tune_seek_freq(core, CMD_FM_TUNE_FREQ,
- args, sizeof(args),
- resp, sizeof(resp));
-}
-
-static int si476x_core_cmd_agc_status_a20(struct si476x_core *core,
- struct si476x_agc_status_report *report)
-{
- int err;
- u8 resp[CMD_AGC_STATUS_NRESP_A20];
-
- if (!report)
- return -EINVAL;
-
- err = si476x_core_send_command(core, CMD_AGC_STATUS,
- NULL, 0,
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- if (err < 0)
- return err;
-
- report->mxhi = resp[1] & SI476X_AGC_MXHI;
- report->mxlo = resp[1] & SI476X_AGC_MXLO;
- report->lnahi = resp[1] & SI476X_AGC_LNAHI;
- report->lnalo = resp[1] & SI476X_AGC_LNALO;
- report->fmagc1 = resp[2];
- report->fmagc2 = resp[3];
- report->pgagain = resp[4];
- report->fmwblang = resp[5];
-
- return err;
-}
-
-static int si476x_core_cmd_agc_status_a10(struct si476x_core *core,
- struct si476x_agc_status_report *report)
-{
- int err;
- u8 resp[CMD_AGC_STATUS_NRESP_A10];
-
- if (!report)
- return -EINVAL;
-
- err = si476x_core_send_command(core, CMD_AGC_STATUS,
- NULL, 0,
- resp, ARRAY_SIZE(resp),
- SI476X_DEFAULT_TIMEOUT);
- if (err < 0)
- return err;
-
- report->mxhi = resp[1] & SI476X_AGC_MXHI;
- report->mxlo = resp[1] & SI476X_AGC_MXLO;
- report->lnahi = resp[1] & SI476X_AGC_LNAHI;
- report->lnalo = resp[1] & SI476X_AGC_LNALO;
-
- return err;
-}
-
-typedef int (*tune_freq_func_t) (struct si476x_core *core,
- struct si476x_tune_freq_args *tuneargs);
-
-static struct {
- int (*power_up)(struct si476x_core *,
- struct si476x_power_up_args *);
- int (*power_down)(struct si476x_core *,
- struct si476x_power_down_args *);
-
- tune_freq_func_t fm_tune_freq;
- tune_freq_func_t am_tune_freq;
-
- int (*fm_rsq_status)(struct si476x_core *,
- struct si476x_rsq_status_args *,
- struct si476x_rsq_status_report *);
-
- int (*agc_status)(struct si476x_core *,
- struct si476x_agc_status_report *);
- int (*intb_pin_cfg)(struct si476x_core *core,
- enum si476x_intb_config intb,
- enum si476x_a1_config a1);
-} si476x_cmds_vtable[] = {
- [SI476X_REVISION_A10] = {
- .power_up = si476x_core_cmd_power_up_a10,
- .power_down = si476x_core_cmd_power_down_a10,
- .fm_tune_freq = si476x_core_cmd_fm_tune_freq_a10,
- .am_tune_freq = si476x_core_cmd_am_tune_freq_a10,
- .fm_rsq_status = si476x_core_cmd_fm_rsq_status_a10,
- .agc_status = si476x_core_cmd_agc_status_a10,
- .intb_pin_cfg = si476x_core_cmd_intb_pin_cfg_a10,
- },
- [SI476X_REVISION_A20] = {
- .power_up = si476x_core_cmd_power_up_a20,
- .power_down = si476x_core_cmd_power_down_a20,
- .fm_tune_freq = si476x_core_cmd_fm_tune_freq_a20,
- .am_tune_freq = si476x_core_cmd_am_tune_freq_a20,
- .fm_rsq_status = si476x_core_cmd_fm_rsq_status_a20,
- .agc_status = si476x_core_cmd_agc_status_a20,
- .intb_pin_cfg = si476x_core_cmd_intb_pin_cfg_a20,
- },
- [SI476X_REVISION_A30] = {
- .power_up = si476x_core_cmd_power_up_a20,
- .power_down = si476x_core_cmd_power_down_a20,
- .fm_tune_freq = si476x_core_cmd_fm_tune_freq_a20,
- .am_tune_freq = si476x_core_cmd_am_tune_freq_a20,
- .fm_rsq_status = si476x_core_cmd_fm_rsq_status_a30,
- .agc_status = si476x_core_cmd_agc_status_a20,
- .intb_pin_cfg = si476x_core_cmd_intb_pin_cfg_a20,
- },
-};
-
-int si476x_core_cmd_power_up(struct si476x_core *core,
- struct si476x_power_up_args *args)
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
- return si476x_cmds_vtable[core->revision].power_up(core, args);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_power_up);
-
-int si476x_core_cmd_power_down(struct si476x_core *core,
- struct si476x_power_down_args *args)
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
- return si476x_cmds_vtable[core->revision].power_down(core, args);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_power_down);
-
-int si476x_core_cmd_fm_tune_freq(struct si476x_core *core,
- struct si476x_tune_freq_args *args)
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
- return si476x_cmds_vtable[core->revision].fm_tune_freq(core, args);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_tune_freq);
-
-int si476x_core_cmd_am_tune_freq(struct si476x_core *core,
- struct si476x_tune_freq_args *args)
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
- return si476x_cmds_vtable[core->revision].am_tune_freq(core, args);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_am_tune_freq);
-
-int si476x_core_cmd_fm_rsq_status(struct si476x_core *core,
- struct si476x_rsq_status_args *args,
- struct si476x_rsq_status_report *report)
-
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
- return si476x_cmds_vtable[core->revision].fm_rsq_status(core, args,
- report);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_rsq_status);
-
-int si476x_core_cmd_agc_status(struct si476x_core *core,
- struct si476x_agc_status_report *report)
-
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
- return si476x_cmds_vtable[core->revision].agc_status(core, report);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_agc_status);
-
-int si476x_core_cmd_intb_pin_cfg(struct si476x_core *core,
- enum si476x_intb_config intb,
- enum si476x_a1_config a1)
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
-
- return si476x_cmds_vtable[core->revision].intb_pin_cfg(core, intb, a1);
-}
-EXPORT_SYMBOL_GPL(si476x_core_cmd_intb_pin_cfg);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
-MODULE_DESCRIPTION("API for command exchange for si476x");
diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c
deleted file mode 100644
index 9bce720a0a08..000000000000
--- a/drivers/mfd/si476x-i2c.c
+++ /dev/null
@@ -1,861 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * drivers/mfd/si476x-i2c.c -- Core device driver for si476x MFD
- * device
- *
- * Copyright (C) 2012 Innovative Converged Devices(ICD)
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/gpio/consumer.h>
-#include <linux/regulator/consumer.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-
-#include <linux/mfd/si476x-core.h>
-
-#define SI476X_MAX_IO_ERRORS 10
-#define SI476X_DRIVER_RDS_FIFO_DEPTH 128
-
-/**
- * si476x_core_config_pinmux() - pin function configuration function
- *
- * @core: Core device structure
- *
- * Configure the functions of the pins of the radio chip.
- *
- * The function returns zero in case of success or negative error code
- * otherwise.
- */
-static int si476x_core_config_pinmux(struct si476x_core *core)
-{
- int err;
- dev_dbg(&core->client->dev, "Configuring pinmux\n");
- err = si476x_core_cmd_dig_audio_pin_cfg(core,
- core->pinmux.dclk,
- core->pinmux.dfs,
- core->pinmux.dout,
- core->pinmux.xout);
- if (err < 0) {
- dev_err(&core->client->dev,
- "Failed to configure digital audio pins(err = %d)\n",
- err);
- return err;
- }
-
- err = si476x_core_cmd_zif_pin_cfg(core,
- core->pinmux.iqclk,
- core->pinmux.iqfs,
- core->pinmux.iout,
- core->pinmux.qout);
- if (err < 0) {
- dev_err(&core->client->dev,
- "Failed to configure ZIF pins(err = %d)\n",
- err);
- return err;
- }
-
- err = si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(core,
- core->pinmux.icin,
- core->pinmux.icip,
- core->pinmux.icon,
- core->pinmux.icop);
- if (err < 0) {
- dev_err(&core->client->dev,
- "Failed to configure IC-Link/GPO pins(err = %d)\n",
- err);
- return err;
- }
-
- err = si476x_core_cmd_ana_audio_pin_cfg(core,
- core->pinmux.lrout);
- if (err < 0) {
- dev_err(&core->client->dev,
- "Failed to configure analog audio pins(err = %d)\n",
- err);
- return err;
- }
-
- err = si476x_core_cmd_intb_pin_cfg(core,
- core->pinmux.intb,
- core->pinmux.a1);
- if (err < 0) {
- dev_err(&core->client->dev,
- "Failed to configure interrupt pins(err = %d)\n",
- err);
- return err;
- }
-
- return 0;
-}
-
-static inline void si476x_core_schedule_polling_work(struct si476x_core *core)
-{
- schedule_delayed_work(&core->status_monitor,
- usecs_to_jiffies(SI476X_STATUS_POLL_US));
-}
-
-/**
- * si476x_core_start() - early chip startup function
- * @core: Core device structure
- * @soft: When set, this flag forces "soft" startup, where "soft"
- * power down is the one done by sending appropriate command instead
- * of using reset pin of the tuner
- *
- * Perform required startup sequence to correctly power
- * up the chip and perform initial configuration. It does the
- * following sequence of actions:
- * 1. Claims and enables the power supplies VD and VIO1 required
- * for I2C interface of the chip operation.
- * 2. Waits for 100us, pulls the reset line up, enables irq,
- * waits for another 100us as it is specified by the
- * datasheet.
- * 3. Sends 'POWER_UP' command to the device with all provided
- * information about power-up parameters.
- * 4. Configures, pin multiplexor, disables digital audio and
- * configures interrupt sources.
- *
- * The function returns zero in case of success or negative error code
- * otherwise.
- */
-int si476x_core_start(struct si476x_core *core, bool soft)
-{
- struct i2c_client *client = core->client;
- int err;
-
- if (!soft) {
- gpiod_set_value_cansleep(core->reset, 0);
-
- if (client->irq)
- enable_irq(client->irq);
-
- udelay(100);
-
- if (!client->irq) {
- atomic_set(&core->is_alive, 1);
- si476x_core_schedule_polling_work(core);
- }
- } else {
- if (client->irq)
- enable_irq(client->irq);
- else {
- atomic_set(&core->is_alive, 1);
- si476x_core_schedule_polling_work(core);
- }
- }
-
- err = si476x_core_cmd_power_up(core,
- &core->power_up_parameters);
-
- if (err < 0) {
- dev_err(&core->client->dev,
- "Power up failure(err = %d)\n",
- err);
- goto disable_irq;
- }
-
- if (client->irq)
- atomic_set(&core->is_alive, 1);
-
- err = si476x_core_config_pinmux(core);
- if (err < 0) {
- dev_err(&core->client->dev,
- "Failed to configure pinmux(err = %d)\n",
- err);
- goto disable_irq;
- }
-
- if (client->irq) {
- err = regmap_write(core->regmap,
- SI476X_PROP_INT_CTL_ENABLE,
- SI476X_RDSIEN |
- SI476X_STCIEN |
- SI476X_CTSIEN);
- if (err < 0) {
- dev_err(&core->client->dev,
- "Failed to configure interrupt sources"
- "(err = %d)\n", err);
- goto disable_irq;
- }
- }
-
- return 0;
-
-disable_irq:
- if (err == -ENODEV)
- atomic_set(&core->is_alive, 0);
-
- if (client->irq)
- disable_irq(client->irq);
- else
- cancel_delayed_work_sync(&core->status_monitor);
-
- gpiod_set_value_cansleep(core->reset, 1);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_start);
-
-/**
- * si476x_core_stop() - chip power-down function
- * @core: Core device structure
- * @soft: When set, function sends a POWER_DOWN command instead of
- * bringing reset line low
- *
- * Power down the chip by performing following actions:
- * 1. Disable IRQ or stop the polling worker
- * 2. Send the POWER_DOWN command if the power down is soft or bring
- * reset line low if not.
- *
- * The function returns zero in case of success or negative error code
- * otherwise.
- */
-int si476x_core_stop(struct si476x_core *core, bool soft)
-{
- int err = 0;
- atomic_set(&core->is_alive, 0);
-
- if (soft) {
- /* TODO: This probably shoud be a configurable option,
- * so it is possible to have the chips keep their
- * oscillators running
- */
- struct si476x_power_down_args args = {
- .xosc = false,
- };
- err = si476x_core_cmd_power_down(core, &args);
- }
-
- /* We couldn't disable those before
- * 'si476x_core_cmd_power_down' since we expect to get CTS
- * interrupt */
- if (core->client->irq)
- disable_irq(core->client->irq);
- else
- cancel_delayed_work_sync(&core->status_monitor);
-
- if (!soft)
- gpiod_set_value_cansleep(core->reset, 1);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_stop);
-
-/**
- * si476x_core_set_power_state() - set the level at which the power is
- * supplied for the chip.
- * @core: Core device structure
- * @next_state: enum si476x_power_state describing power state to
- * switch to.
- *
- * Switch on all the required power supplies
- *
- * This function returns 0 in case of suvccess and negative error code
- * otherwise.
- */
-int si476x_core_set_power_state(struct si476x_core *core,
- enum si476x_power_state next_state)
-{
- /*
- It is not clear form the datasheet if it is possible to
- work with device if not all power domains are operational.
- So for now the power-up policy is "power-up all the things!"
- */
- int err = 0;
-
- if (core->power_state == SI476X_POWER_INCONSISTENT) {
- dev_err(&core->client->dev,
- "The device in inconsistent power state\n");
- return -EINVAL;
- }
-
- if (next_state != core->power_state) {
- switch (next_state) {
- case SI476X_POWER_UP_FULL:
- err = regulator_bulk_enable(ARRAY_SIZE(core->supplies),
- core->supplies);
- if (err < 0) {
- core->power_state = SI476X_POWER_INCONSISTENT;
- break;
- }
- /*
- * Startup timing diagram recommends to have a
- * 100 us delay between enabling of the power
- * supplies and turning the tuner on.
- */
- udelay(100);
-
- err = si476x_core_start(core, false);
- if (err < 0)
- goto disable_regulators;
-
- core->power_state = next_state;
- break;
-
- case SI476X_POWER_DOWN:
- core->power_state = next_state;
- err = si476x_core_stop(core, false);
- if (err < 0)
- core->power_state = SI476X_POWER_INCONSISTENT;
-disable_regulators:
- err = regulator_bulk_disable(ARRAY_SIZE(core->supplies),
- core->supplies);
- if (err < 0)
- core->power_state = SI476X_POWER_INCONSISTENT;
- break;
- default:
- BUG();
- }
- }
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_set_power_state);
-
-/**
- * si476x_core_report_drainer_stop() - mark the completion of the RDS
- * buffer drain porcess by the worker.
- *
- * @core: Core device structure
- */
-static inline void si476x_core_report_drainer_stop(struct si476x_core *core)
-{
- mutex_lock(&core->rds_drainer_status_lock);
- core->rds_drainer_is_working = false;
- mutex_unlock(&core->rds_drainer_status_lock);
-}
-
-/**
- * si476x_core_start_rds_drainer_once() - start RDS drainer worker if
- * ther is none working, do nothing otherwise
- *
- * @core: Datastructure corresponding to the chip.
- */
-static inline void si476x_core_start_rds_drainer_once(struct si476x_core *core)
-{
- mutex_lock(&core->rds_drainer_status_lock);
- if (!core->rds_drainer_is_working) {
- core->rds_drainer_is_working = true;
- schedule_work(&core->rds_fifo_drainer);
- }
- mutex_unlock(&core->rds_drainer_status_lock);
-}
-/**
- * si476x_core_drain_rds_fifo() - RDS buffer drainer.
- * @work: struct work_struct being ppassed to the function by the
- * kernel.
- *
- * Drain the contents of the RDS FIFO of
- */
-static void si476x_core_drain_rds_fifo(struct work_struct *work)
-{
- int err;
-
- struct si476x_core *core = container_of(work, struct si476x_core,
- rds_fifo_drainer);
-
- struct si476x_rds_status_report report;
-
- si476x_core_lock(core);
- err = si476x_core_cmd_fm_rds_status(core, true, false, false, &report);
- if (!err) {
- int i = report.rdsfifoused;
- dev_dbg(&core->client->dev,
- "%d elements in RDS FIFO. Draining.\n", i);
- for (; i > 0; --i) {
- err = si476x_core_cmd_fm_rds_status(core, false, false,
- (i == 1), &report);
- if (err < 0)
- goto unlock;
-
- kfifo_in(&core->rds_fifo, report.rds,
- sizeof(report.rds));
- dev_dbg(&core->client->dev, "RDS data:\n %*ph\n",
- (int)sizeof(report.rds), report.rds);
- }
- dev_dbg(&core->client->dev, "Drrrrained!\n");
- wake_up_interruptible(&core->rds_read_queue);
- }
-
-unlock:
- si476x_core_unlock(core);
- si476x_core_report_drainer_stop(core);
-}
-
-/**
- * si476x_core_pronounce_dead()
- *
- * @core: Core device structure
- *
- * Mark the device as being dead and wake up all potentially waiting
- * threads of execution.
- *
- */
-static void si476x_core_pronounce_dead(struct si476x_core *core)
-{
- dev_info(&core->client->dev, "Core device is dead.\n");
-
- atomic_set(&core->is_alive, 0);
-
- /* Wake up al possible waiting processes */
- wake_up_interruptible(&core->rds_read_queue);
-
- atomic_set(&core->cts, 1);
- wake_up(&core->command);
-
- atomic_set(&core->stc, 1);
- wake_up(&core->tuning);
-}
-
-/**
- * si476x_core_i2c_xfer()
- *
- * @core: Core device structure
- * @type: Transfer type
- * @buf: Transfer buffer for/with data
- * @count: Transfer buffer size
- *
- * Perfrom and I2C transfer(either read or write) and keep a counter
- * of I/O errors. If the error counter rises above the threshold
- * pronounce device dead.
- *
- * The function returns zero on success or negative error code on
- * failure.
- */
-int si476x_core_i2c_xfer(struct si476x_core *core,
- enum si476x_i2c_type type,
- char *buf, int count)
-{
- static int io_errors_count;
- int err;
- if (type == SI476X_I2C_SEND)
- err = i2c_master_send(core->client, buf, count);
- else
- err = i2c_master_recv(core->client, buf, count);
-
- if (err < 0) {
- if (io_errors_count++ > SI476X_MAX_IO_ERRORS)
- si476x_core_pronounce_dead(core);
- } else {
- io_errors_count = 0;
- }
-
- return err;
-}
-EXPORT_SYMBOL_GPL(si476x_core_i2c_xfer);
-
-/**
- * si476x_core_get_status()
- * @core: Core device structure
- *
- * Get the status byte of the core device by berforming one byte I2C
- * read.
- *
- * The function returns a status value or a negative error code on
- * error.
- */
-static int si476x_core_get_status(struct si476x_core *core)
-{
- u8 response;
- int err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV,
- &response, sizeof(response));
-
- return (err < 0) ? err : response;
-}
-
-/**
- * si476x_core_get_and_signal_status() - IRQ dispatcher
- * @core: Core device structure
- *
- * Dispatch the arrived interrupt request based on the value of the
- * status byte reported by the tuner.
- *
- */
-static void si476x_core_get_and_signal_status(struct si476x_core *core)
-{
- int status = si476x_core_get_status(core);
- if (status < 0) {
- dev_err(&core->client->dev, "Failed to get status\n");
- return;
- }
-
- if (status & SI476X_CTS) {
- /* Unfortunately completions could not be used for
- * signalling CTS since this flag cannot be cleared
- * in status byte, and therefore once it becomes true
- * multiple calls to 'complete' would cause the
- * commands following the current one to be completed
- * before they actually are */
- dev_dbg(&core->client->dev, "[interrupt] CTSINT\n");
- atomic_set(&core->cts, 1);
- wake_up(&core->command);
- }
-
- if (status & SI476X_FM_RDS_INT) {
- dev_dbg(&core->client->dev, "[interrupt] RDSINT\n");
- si476x_core_start_rds_drainer_once(core);
- }
-
- if (status & SI476X_STC_INT) {
- dev_dbg(&core->client->dev, "[interrupt] STCINT\n");
- atomic_set(&core->stc, 1);
- wake_up(&core->tuning);
- }
-}
-
-static void si476x_core_poll_loop(struct work_struct *work)
-{
- struct si476x_core *core = SI476X_WORK_TO_CORE(work);
-
- si476x_core_get_and_signal_status(core);
-
- if (atomic_read(&core->is_alive))
- si476x_core_schedule_polling_work(core);
-}
-
-static irqreturn_t si476x_core_interrupt(int irq, void *dev)
-{
- struct si476x_core *core = dev;
-
- si476x_core_get_and_signal_status(core);
-
- return IRQ_HANDLED;
-}
-
-/**
- * si476x_core_fwver_to_revision()
- * @core: Core device structure
- * @func: Selects the boot function of the device:
- * *_BOOTLOADER - Boot loader
- * *_FM_RECEIVER - FM receiver
- * *_AM_RECEIVER - AM receiver
- * *_WB_RECEIVER - Weatherband receiver
- * @major: Firmware major number
- * @minor1: Firmware first minor number
- * @minor2: Firmware second minor number
- *
- * Convert a chip's firmware version number into an offset that later
- * will be used to as offset in "vtable" of tuner functions
- *
- * This function returns a positive offset in case of success and a -1
- * in case of failure.
- */
-static int si476x_core_fwver_to_revision(struct si476x_core *core,
- int func, int major,
- int minor1, int minor2)
-{
- switch (func) {
- case SI476X_FUNC_FM_RECEIVER:
- switch (major) {
- case 5:
- return SI476X_REVISION_A10;
- case 8:
- return SI476X_REVISION_A20;
- case 10:
- return SI476X_REVISION_A30;
- default:
- goto unknown_revision;
- }
- case SI476X_FUNC_AM_RECEIVER:
- switch (major) {
- case 5:
- return SI476X_REVISION_A10;
- case 7:
- return SI476X_REVISION_A20;
- case 9:
- return SI476X_REVISION_A30;
- default:
- goto unknown_revision;
- }
- case SI476X_FUNC_WB_RECEIVER:
- switch (major) {
- case 3:
- return SI476X_REVISION_A10;
- case 5:
- return SI476X_REVISION_A20;
- case 7:
- return SI476X_REVISION_A30;
- default:
- goto unknown_revision;
- }
- case SI476X_FUNC_BOOTLOADER:
- default: /* FALLTHROUGH */
- BUG();
- return -1;
- }
-
-unknown_revision:
- dev_err(&core->client->dev,
- "Unsupported version of the firmware: %d.%d.%d, "
- "reverting to A10 compatible functions\n",
- major, minor1, minor2);
-
- return SI476X_REVISION_A10;
-}
-
-/**
- * si476x_core_get_revision_info()
- * @core: Core device structure
- *
- * Get the firmware version number of the device. It is done in
- * following three steps:
- * 1. Power-up the device
- * 2. Send the 'FUNC_INFO' command
- * 3. Powering the device down.
- *
- * The function return zero on success and a negative error code on
- * failure.
- */
-static int si476x_core_get_revision_info(struct si476x_core *core)
-{
- int rval;
- struct si476x_func_info info;
-
- si476x_core_lock(core);
- rval = si476x_core_set_power_state(core, SI476X_POWER_UP_FULL);
- if (rval < 0)
- goto exit;
-
- rval = si476x_core_cmd_func_info(core, &info);
- if (rval < 0)
- goto power_down;
-
- core->revision = si476x_core_fwver_to_revision(core, info.func,
- info.firmware.major,
- info.firmware.minor[0],
- info.firmware.minor[1]);
-power_down:
- si476x_core_set_power_state(core, SI476X_POWER_DOWN);
-exit:
- si476x_core_unlock(core);
-
- return rval;
-}
-
-bool si476x_core_has_am(struct si476x_core *core)
-{
- return core->chip_id == SI476X_CHIP_SI4761 ||
- core->chip_id == SI476X_CHIP_SI4764;
-}
-EXPORT_SYMBOL_GPL(si476x_core_has_am);
-
-bool si476x_core_has_diversity(struct si476x_core *core)
-{
- return core->chip_id == SI476X_CHIP_SI4764;
-}
-EXPORT_SYMBOL_GPL(si476x_core_has_diversity);
-
-bool si476x_core_is_a_secondary_tuner(struct si476x_core *core)
-{
- return si476x_core_has_diversity(core) &&
- (core->diversity_mode == SI476X_PHDIV_SECONDARY_ANTENNA ||
- core->diversity_mode == SI476X_PHDIV_SECONDARY_COMBINING);
-}
-EXPORT_SYMBOL_GPL(si476x_core_is_a_secondary_tuner);
-
-bool si476x_core_is_a_primary_tuner(struct si476x_core *core)
-{
- return si476x_core_has_diversity(core) &&
- (core->diversity_mode == SI476X_PHDIV_PRIMARY_ANTENNA ||
- core->diversity_mode == SI476X_PHDIV_PRIMARY_COMBINING);
-}
-EXPORT_SYMBOL_GPL(si476x_core_is_a_primary_tuner);
-
-bool si476x_core_is_in_am_receiver_mode(struct si476x_core *core)
-{
- return si476x_core_has_am(core) &&
- (core->power_up_parameters.func == SI476X_FUNC_AM_RECEIVER);
-}
-EXPORT_SYMBOL_GPL(si476x_core_is_in_am_receiver_mode);
-
-bool si476x_core_is_powered_up(struct si476x_core *core)
-{
- return core->power_state == SI476X_POWER_UP_FULL;
-}
-EXPORT_SYMBOL_GPL(si476x_core_is_powered_up);
-
-static int si476x_core_probe(struct i2c_client *client)
-{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
- int rval;
- struct si476x_core *core;
- struct si476x_platform_data *pdata;
- struct mfd_cell *cell;
- int cell_num;
-
- core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
- if (!core)
- return -ENOMEM;
-
- core->client = client;
-
- core->regmap = devm_regmap_init_si476x(core);
- if (IS_ERR(core->regmap)) {
- rval = PTR_ERR(core->regmap);
- dev_err(&client->dev,
- "Failed to allocate register map: %d\n",
- rval);
- return rval;
- }
-
- i2c_set_clientdata(client, core);
-
- atomic_set(&core->is_alive, 0);
- core->power_state = SI476X_POWER_DOWN;
-
- core->reset = devm_gpiod_get_optional(&client->dev, "reset",
- GPIOD_OUT_HIGH);
- if (IS_ERR(core->reset))
- return dev_err_probe(&client->dev, PTR_ERR(core->reset),
- "error getting reset GPIO\n");
- gpiod_set_consumer_name(core->reset, "si476x reset");
-
- pdata = dev_get_platdata(&client->dev);
- if (pdata) {
- memcpy(&core->power_up_parameters,
- &pdata->power_up_parameters,
- sizeof(core->power_up_parameters));
- core->diversity_mode = pdata->diversity_mode;
- memcpy(&core->pinmux, &pdata->pinmux,
- sizeof(struct si476x_pinmux));
- } else {
- dev_err(&client->dev, "No platform data provided\n");
- return -EINVAL;
- }
-
- core->supplies[0].supply = "vd";
- core->supplies[1].supply = "va";
- core->supplies[2].supply = "vio1";
- core->supplies[3].supply = "vio2";
-
- rval = devm_regulator_bulk_get(&client->dev,
- ARRAY_SIZE(core->supplies),
- core->supplies);
- if (rval) {
- dev_err(&client->dev, "Failed to get all of the regulators\n");
- return rval;
- }
-
- mutex_init(&core->cmd_lock);
- init_waitqueue_head(&core->command);
- init_waitqueue_head(&core->tuning);
-
- rval = kfifo_alloc(&core->rds_fifo,
- SI476X_DRIVER_RDS_FIFO_DEPTH *
- sizeof(struct v4l2_rds_data),
- GFP_KERNEL);
- if (rval) {
- dev_err(&client->dev, "Could not allocate the FIFO\n");
- return rval;
- }
- mutex_init(&core->rds_drainer_status_lock);
- init_waitqueue_head(&core->rds_read_queue);
- INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo);
-
- if (client->irq) {
- rval = devm_request_threaded_irq(&client->dev,
- client->irq, NULL,
- si476x_core_interrupt,
- IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT,
- client->name, core);
- if (rval < 0) {
- dev_err(&client->dev, "Could not request IRQ %d\n",
- client->irq);
- goto free_kfifo;
- }
- disable_irq(client->irq);
- dev_dbg(&client->dev, "IRQ requested.\n");
-
- core->rds_fifo_depth = 20;
- } else {
- INIT_DELAYED_WORK(&core->status_monitor,
- si476x_core_poll_loop);
- dev_info(&client->dev,
- "No IRQ number specified, will use polling\n");
-
- core->rds_fifo_depth = 5;
- }
-
- core->chip_id = id->driver_data;
-
- rval = si476x_core_get_revision_info(core);
- if (rval < 0) {
- rval = -ENODEV;
- goto free_kfifo;
- }
-
- cell_num = 0;
-
- cell = &core->cells[SI476X_RADIO_CELL];
- cell->name = "si476x-radio";
- cell_num++;
-
-#ifdef CONFIG_SND_SOC_SI476X
- if ((core->chip_id == SI476X_CHIP_SI4761 ||
- core->chip_id == SI476X_CHIP_SI4764) &&
- core->pinmux.dclk == SI476X_DCLK_DAUDIO &&
- core->pinmux.dfs == SI476X_DFS_DAUDIO &&
- core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT &&
- core->pinmux.xout == SI476X_XOUT_TRISTATE) {
- cell = &core->cells[SI476X_CODEC_CELL];
- cell->name = "si476x-codec";
- cell_num++;
- }
-#endif
- rval = mfd_add_devices(&client->dev,
- (client->adapter->nr << 8) + client->addr,
- core->cells, cell_num,
- NULL, 0, NULL);
- if (!rval)
- return 0;
-
-free_kfifo:
- kfifo_free(&core->rds_fifo);
- return rval;
-}
-
-static void si476x_core_remove(struct i2c_client *client)
-{
- struct si476x_core *core = i2c_get_clientdata(client);
-
- si476x_core_pronounce_dead(core);
- mfd_remove_devices(&client->dev);
-
- if (client->irq)
- disable_irq(client->irq);
- else
- cancel_delayed_work_sync(&core->status_monitor);
-
- kfifo_free(&core->rds_fifo);
-}
-
-
-static const struct i2c_device_id si476x_id[] = {
- { "si4761", SI476X_CHIP_SI4761 },
- { "si4764", SI476X_CHIP_SI4764 },
- { "si4768", SI476X_CHIP_SI4768 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, si476x_id);
-
-static struct i2c_driver si476x_core_driver = {
- .driver = {
- .name = "si476x-core",
- },
- .probe = si476x_core_probe,
- .remove = si476x_core_remove,
- .id_table = si476x_id,
-};
-module_i2c_driver(si476x_core_driver);
-
-
-MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
-MODULE_DESCRIPTION("Si4761/64/68 AM/FM MFD core device driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/si476x-prop.c b/drivers/mfd/si476x-prop.c
deleted file mode 100644
index 3d5c118888b2..000000000000
--- a/drivers/mfd/si476x-prop.c
+++ /dev/null
@@ -1,233 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * drivers/mfd/si476x-prop.c -- Subroutines to access
- * properties of si476x chips
- *
- * Copyright (C) 2012 Innovative Converged Devices(ICD)
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-#include <linux/module.h>
-
-#include <linux/mfd/si476x-core.h>
-
-struct si476x_property_range {
- u16 low, high;
-};
-
-static bool si476x_core_element_is_in_array(u16 element,
- const u16 array[],
- size_t size)
-{
- int i;
-
- for (i = 0; i < size; i++)
- if (element == array[i])
- return true;
-
- return false;
-}
-
-static bool si476x_core_element_is_in_range(u16 element,
- const struct si476x_property_range range[],
- size_t size)
-{
- int i;
-
- for (i = 0; i < size; i++)
- if (element <= range[i].high && element >= range[i].low)
- return true;
-
- return false;
-}
-
-static bool si476x_core_is_valid_property_a10(struct si476x_core *core,
- u16 property)
-{
- static const u16 valid_properties[] = {
- 0x0000,
- 0x0500, 0x0501,
- 0x0600,
- 0x0709, 0x070C, 0x070D, 0x70E, 0x710,
- 0x0718,
- 0x1207, 0x1208,
- 0x2007,
- 0x2300,
- };
-
- static const struct si476x_property_range valid_ranges[] = {
- { 0x0200, 0x0203 },
- { 0x0300, 0x0303 },
- { 0x0400, 0x0404 },
- { 0x0700, 0x0707 },
- { 0x1100, 0x1102 },
- { 0x1200, 0x1204 },
- { 0x1300, 0x1306 },
- { 0x2000, 0x2005 },
- { 0x2100, 0x2104 },
- { 0x2106, 0x2106 },
- { 0x2200, 0x220E },
- { 0x3100, 0x3104 },
- { 0x3207, 0x320F },
- { 0x3300, 0x3304 },
- { 0x3500, 0x3517 },
- { 0x3600, 0x3617 },
- { 0x3700, 0x3717 },
- { 0x4000, 0x4003 },
- };
-
- return si476x_core_element_is_in_range(property, valid_ranges,
- ARRAY_SIZE(valid_ranges)) ||
- si476x_core_element_is_in_array(property, valid_properties,
- ARRAY_SIZE(valid_properties));
-}
-
-static bool si476x_core_is_valid_property_a20(struct si476x_core *core,
- u16 property)
-{
- static const u16 valid_properties[] = {
- 0x071B,
- 0x1006,
- 0x2210,
- 0x3401,
- };
-
- static const struct si476x_property_range valid_ranges[] = {
- { 0x2215, 0x2219 },
- };
-
- return si476x_core_is_valid_property_a10(core, property) ||
- si476x_core_element_is_in_range(property, valid_ranges,
- ARRAY_SIZE(valid_ranges)) ||
- si476x_core_element_is_in_array(property, valid_properties,
- ARRAY_SIZE(valid_properties));
-}
-
-static bool si476x_core_is_valid_property_a30(struct si476x_core *core,
- u16 property)
-{
- static const u16 valid_properties[] = {
- 0x071C, 0x071D,
- 0x1007, 0x1008,
- 0x220F, 0x2214,
- 0x2301,
- 0x3105, 0x3106,
- 0x3402,
- };
-
- static const struct si476x_property_range valid_ranges[] = {
- { 0x0405, 0x0411 },
- { 0x2008, 0x200B },
- { 0x2220, 0x2223 },
- { 0x3100, 0x3106 },
- };
-
- return si476x_core_is_valid_property_a20(core, property) ||
- si476x_core_element_is_in_range(property, valid_ranges,
- ARRAY_SIZE(valid_ranges)) ||
- si476x_core_element_is_in_array(property, valid_properties,
- ARRAY_SIZE(valid_properties));
-}
-
-typedef bool (*valid_property_pred_t) (struct si476x_core *, u16);
-
-static bool si476x_core_is_valid_property(struct si476x_core *core,
- u16 property)
-{
- static const valid_property_pred_t is_valid_property[] = {
- [SI476X_REVISION_A10] = si476x_core_is_valid_property_a10,
- [SI476X_REVISION_A20] = si476x_core_is_valid_property_a20,
- [SI476X_REVISION_A30] = si476x_core_is_valid_property_a30,
- };
-
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
- return is_valid_property[core->revision](core, property);
-}
-
-
-static bool si476x_core_is_readonly_property(struct si476x_core *core,
- u16 property)
-{
- BUG_ON(core->revision > SI476X_REVISION_A30 ||
- core->revision == -1);
-
- switch (core->revision) {
- case SI476X_REVISION_A10:
- return (property == 0x3200);
- case SI476X_REVISION_A20:
- return (property == 0x1006 ||
- property == 0x2210 ||
- property == 0x3200);
- case SI476X_REVISION_A30:
- return false;
- }
-
- return false;
-}
-
-static bool si476x_core_regmap_readable_register(struct device *dev,
- unsigned int reg)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct si476x_core *core = i2c_get_clientdata(client);
-
- return si476x_core_is_valid_property(core, (u16) reg);
-
-}
-
-static bool si476x_core_regmap_writable_register(struct device *dev,
- unsigned int reg)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct si476x_core *core = i2c_get_clientdata(client);
-
- return si476x_core_is_valid_property(core, (u16) reg) &&
- !si476x_core_is_readonly_property(core, (u16) reg);
-}
-
-
-static int si476x_core_regmap_write(void *context, unsigned int reg,
- unsigned int val)
-{
- return si476x_core_cmd_set_property(context, reg, val);
-}
-
-static int si476x_core_regmap_read(void *context, unsigned int reg,
- unsigned *val)
-{
- struct si476x_core *core = context;
- int err;
-
- err = si476x_core_cmd_get_property(core, reg);
- if (err < 0)
- return err;
-
- *val = err;
-
- return 0;
-}
-
-
-static const struct regmap_config si476x_regmap_config = {
- .reg_bits = 16,
- .val_bits = 16,
-
- .max_register = 0x4003,
-
- .writeable_reg = si476x_core_regmap_writable_register,
- .readable_reg = si476x_core_regmap_readable_register,
-
- .reg_read = si476x_core_regmap_read,
- .reg_write = si476x_core_regmap_write,
-
- .cache_type = REGCACHE_MAPLE,
-};
-
-struct regmap *devm_regmap_init_si476x(struct si476x_core *core)
-{
- return devm_regmap_init(&core->client->dev, NULL,
- core, &si476x_regmap_config);
-}
-EXPORT_SYMBOL_GPL(devm_regmap_init_si476x);
diff --git a/include/linux/mfd/si476x-core.h b/include/linux/mfd/si476x-core.h
deleted file mode 100644
index d9e3a322134c..000000000000
--- a/include/linux/mfd/si476x-core.h
+++ /dev/null
@@ -1,532 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * include/media/si476x-core.h -- Common definitions for si476x core
- * device
- *
- * Copyright (C) 2012 Innovative Converged Devices(ICD)
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-
-#ifndef SI476X_CORE_H
-#define SI476X_CORE_H
-
-#include <linux/kfifo.h>
-#include <linux/atomic.h>
-#include <linux/gpio/consumer.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/mutex.h>
-#include <linux/mfd/core.h>
-#include <linux/videodev2.h>
-#include <linux/regulator/consumer.h>
-
-#include <linux/mfd/si476x-platform.h>
-#include <linux/mfd/si476x-reports.h>
-
-/* Command Timeouts */
-#define SI476X_DEFAULT_TIMEOUT 100000
-#define SI476X_TIMEOUT_TUNE 700000
-#define SI476X_TIMEOUT_POWER_UP 330000
-#define SI476X_STATUS_POLL_US 0
-
-/* -------------------- si476x-i2c.c ----------------------- */
-
-enum si476x_freq_supported_chips {
- SI476X_CHIP_SI4761 = 1,
- SI476X_CHIP_SI4764,
- SI476X_CHIP_SI4768,
-};
-
-enum si476x_part_revisions {
- SI476X_REVISION_A10 = 0,
- SI476X_REVISION_A20 = 1,
- SI476X_REVISION_A30 = 2,
-};
-
-enum si476x_mfd_cells {
- SI476X_RADIO_CELL = 0,
- SI476X_CODEC_CELL,
- SI476X_MFD_CELLS,
-};
-
-/**
- * enum si476x_power_state - possible power state of the si476x
- * device.
- *
- * @SI476X_POWER_DOWN: In this state all regulators are turned off
- * and the reset line is pulled low. The device is completely
- * inactive.
- * @SI476X_POWER_UP_FULL: In this state all the power regulators are
- * turned on, reset line pulled high, IRQ line is enabled(polling is
- * active for polling use scenario) and device is turned on with
- * POWER_UP command. The device is ready to be used.
- * @SI476X_POWER_INCONSISTENT: This state indicates that previous
- * power down was inconsistent, meaning some of the regulators were
- * not turned down and thus use of the device, without power-cycling
- * is impossible.
- */
-enum si476x_power_state {
- SI476X_POWER_DOWN = 0,
- SI476X_POWER_UP_FULL = 1,
- SI476X_POWER_INCONSISTENT = 2,
-};
-
-/**
- * struct si476x_core - internal data structure representing the
- * underlying "core" device which all the MFD cell-devices use.
- *
- * @client: Actual I2C client used to transfer commands to the chip.
- * @regmap: Regmap for accessing the device registers
- * @chip_id: Last digit of the chip model(E.g. "1" for SI4761)
- * @cells: MFD cell devices created by this driver.
- * @cmd_lock: Mutex used to serialize all the requests to the core
- * device. This filed should not be used directly. Instead
- * si476x_core_lock()/si476x_core_unlock() should be used to get
- * exclusive access to the "core" device.
- * @users: Active users counter(Used by the radio cell)
- * @rds_read_queue: Wait queue used to wait for RDS data.
- * @rds_fifo: FIFO in which all the RDS data received from the chip is
- * placed.
- * @rds_fifo_drainer: Worker that drains on-chip RDS FIFO.
- * @rds_drainer_is_working: Flag used for launching only one instance
- * of the @rds_fifo_drainer.
- * @rds_drainer_status_lock: Lock used to guard access to the
- * @rds_drainer_is_working variable.
- * @command: Wait queue for wainting on the command comapletion.
- * @cts: Clear To Send flag set upon receiving first status with CTS
- * set.
- * @tuning: Wait queue used for wainting for tune/seek comand
- * completion.
- * @stc: Similar to @cts, but for the STC bit of the status value.
- * @power_up_parameters: Parameters used as argument for POWER_UP
- * command when the device is started.
- * @power_state: Current power state of the device.
- * @supplies: Structure containing handles to all power supplies used
- * by the device (NULL ones are ignored).
- * @reset: GPIO connected to the RSTB pin of the chip.
- * @pinmux: Chip's configurable pins configuration.
- * @diversity_mode: Chips role when functioning in diversity mode.
- * @is_alive: Chip is initialized and active.
- * @status_monitor: Polling worker used in polling use case scenarion
- * (when IRQ is not avalible).
- * @revision: Chip's running firmware revision number(Used for correct
- * command set support).
- * @rds_fifo_depth: RDS FIFO size: 20 for IRQ mode or 5 for polling mode.
- */
-
-struct si476x_core {
- struct i2c_client *client;
- struct regmap *regmap;
- int chip_id;
- struct mfd_cell cells[SI476X_MFD_CELLS];
-
- struct mutex cmd_lock; /* for serializing fm radio operations */
- atomic_t users;
-
- wait_queue_head_t rds_read_queue;
- struct kfifo rds_fifo;
- struct work_struct rds_fifo_drainer;
- bool rds_drainer_is_working;
- struct mutex rds_drainer_status_lock;
-
- wait_queue_head_t command;
- atomic_t cts;
-
- wait_queue_head_t tuning;
- atomic_t stc;
-
- struct si476x_power_up_args power_up_parameters;
-
- enum si476x_power_state power_state;
-
- struct regulator_bulk_data supplies[4];
-
- struct gpio_desc *reset;
-
- struct si476x_pinmux pinmux;
- enum si476x_phase_diversity_mode diversity_mode;
-
- atomic_t is_alive;
-
- struct delayed_work status_monitor;
-#define SI476X_WORK_TO_CORE(w) container_of(to_delayed_work(w), \
- struct si476x_core, \
- status_monitor)
-
- int revision;
-
- int rds_fifo_depth;
-};
-
-static inline struct si476x_core *i2c_mfd_cell_to_core(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev->parent);
- return i2c_get_clientdata(client);
-}
-
-
-/**
- * si476x_core_lock() - lock the core device to get an exclusive access
- * to it.
- * @core: Core device structure
- */
-static inline void si476x_core_lock(struct si476x_core *core)
-{
- mutex_lock(&core->cmd_lock);
-}
-
-/**
- * si476x_core_unlock() - unlock the core device to relinquish an
- * exclusive access to it.
- * @core: Core device structure
- */
-static inline void si476x_core_unlock(struct si476x_core *core)
-{
- mutex_unlock(&core->cmd_lock);
-}
-
-/* *_TUNE_FREQ family of commands accept frequency in multiples of
- 10kHz */
-static inline u16 hz_to_si476x(struct si476x_core *core, int freq)
-{
- u16 result;
-
- switch (core->power_up_parameters.func) {
- default:
- case SI476X_FUNC_FM_RECEIVER:
- result = freq / 10000;
- break;
- case SI476X_FUNC_AM_RECEIVER:
- result = freq / 1000;
- break;
- }
-
- return result;
-}
-
-static inline int si476x_to_hz(struct si476x_core *core, u16 freq)
-{
- int result;
-
- switch (core->power_up_parameters.func) {
- default:
- case SI476X_FUNC_FM_RECEIVER:
- result = freq * 10000;
- break;
- case SI476X_FUNC_AM_RECEIVER:
- result = freq * 1000;
- break;
- }
-
- return result;
-}
-
-/* Since the V4L2_TUNER_CAP_LOW flag is supplied, V4L2 subsystem
- * mesures frequency in 62.5 Hz units */
-
-static inline int hz_to_v4l2(int freq)
-{
- return (freq * 10) / 625;
-}
-
-static inline int v4l2_to_hz(int freq)
-{
- return (freq * 625) / 10;
-}
-
-static inline u16 v4l2_to_si476x(struct si476x_core *core, int freq)
-{
- return hz_to_si476x(core, v4l2_to_hz(freq));
-}
-
-static inline int si476x_to_v4l2(struct si476x_core *core, u16 freq)
-{
- return hz_to_v4l2(si476x_to_hz(core, freq));
-}
-
-
-
-/**
- * struct si476x_func_info - structure containing result of the
- * FUNC_INFO command.
- *
- * @firmware: Firmware version numbers.
- * @firmware.major: Firmware major number.
- * @firmware.minor[...]: Firmware minor numbers.
- * @patch_id: Firmware patch level.
- * @func: Mode tuner is working in.
- */
-struct si476x_func_info {
- struct {
- u8 major, minor[2];
- } firmware;
- u16 patch_id;
- enum si476x_func func;
-};
-
-/**
- * struct si476x_power_down_args - structure used to pass parameters
- * to POWER_DOWN command
- *
- * @xosc: true - Power down, but leav oscillator running.
- * false - Full power down.
- */
-struct si476x_power_down_args {
- bool xosc;
-};
-
-/**
- * enum si476x_tunemode - enum representing possible tune modes for
- * the chip.
- * @SI476X_TM_VALIDATED_NORMAL_TUNE: Unconditionally stay on the new
- * channel after tune, tune status is valid.
- * @SI476X_TM_INVALIDATED_FAST_TUNE: Unconditionally stay in the new
- * channel after tune, tune status invalid.
- * @SI476X_TM_VALIDATED_AF_TUNE: Jump back to previous channel if
- * metric thresholds are not met.
- * @SI476X_TM_VALIDATED_AF_CHECK: Unconditionally jump back to the
- * previous channel.
- */
-enum si476x_tunemode {
- SI476X_TM_VALIDATED_NORMAL_TUNE = 0,
- SI476X_TM_INVALIDATED_FAST_TUNE = 1,
- SI476X_TM_VALIDATED_AF_TUNE = 2,
- SI476X_TM_VALIDATED_AF_CHECK = 3,
-};
-
-/**
- * enum si476x_smoothmetrics - enum containing the possible setting fo
- * audio transitioning of the chip
- * @SI476X_SM_INITIALIZE_AUDIO: Initialize audio state to match this
- * new channel
- * @SI476X_SM_TRANSITION_AUDIO: Transition audio state from previous
- * channel values to the new values
- */
-enum si476x_smoothmetrics {
- SI476X_SM_INITIALIZE_AUDIO = 0,
- SI476X_SM_TRANSITION_AUDIO = 1,
-};
-
-/**
- * struct si476x_rds_status_report - the structure representing the
- * response to 'FM_RD_STATUS' command
- * @rdstpptyint: Traffic program flag(TP) and/or program type(PTY)
- * code has changed.
- * @rdspiint: Program identification(PI) code has changed.
- * @rdssyncint: RDS synchronization has changed.
- * @rdsfifoint: RDS was received and the RDS FIFO has at least
- * 'FM_RDS_INTERRUPT_FIFO_COUNT' elements in it.
- * @tpptyvalid: TP flag and PTY code are valid falg.
- * @pivalid: PI code is valid flag.
- * @rdssync: RDS is currently synchronized.
- * @rdsfifolost: On or more RDS groups have been lost/discarded flag.
- * @tp: Current channel's TP flag.
- * @pty: Current channel's PTY code.
- * @pi: Current channel's PI code.
- * @rdsfifoused: Number of blocks remaining in the RDS FIFO (0 if empty).
- * @ble:
- * @rds: RDS data descriptor
- */
-struct si476x_rds_status_report {
- bool rdstpptyint, rdspiint, rdssyncint, rdsfifoint;
- bool tpptyvalid, pivalid, rdssync, rdsfifolost;
- bool tp;
-
- u8 pty;
- u16 pi;
-
- u8 rdsfifoused;
- u8 ble[4];
-
- struct v4l2_rds_data rds[4];
-};
-
-struct si476x_rsq_status_args {
- bool primary;
- bool rsqack;
- bool attune;
- bool cancel;
- bool stcack;
-};
-
-enum si476x_injside {
- SI476X_INJSIDE_AUTO = 0,
- SI476X_INJSIDE_LOW = 1,
- SI476X_INJSIDE_HIGH = 2,
-};
-
-struct si476x_tune_freq_args {
- bool zifsr;
- bool hd;
- enum si476x_injside injside;
- int freq;
- enum si476x_tunemode tunemode;
- enum si476x_smoothmetrics smoothmetrics;
- int antcap;
-};
-
-int si476x_core_stop(struct si476x_core *, bool);
-int si476x_core_start(struct si476x_core *, bool);
-int si476x_core_set_power_state(struct si476x_core *, enum si476x_power_state);
-bool si476x_core_has_am(struct si476x_core *);
-bool si476x_core_has_diversity(struct si476x_core *);
-bool si476x_core_is_a_secondary_tuner(struct si476x_core *);
-bool si476x_core_is_a_primary_tuner(struct si476x_core *);
-bool si476x_core_is_in_am_receiver_mode(struct si476x_core *core);
-bool si476x_core_is_powered_up(struct si476x_core *core);
-
-enum si476x_i2c_type {
- SI476X_I2C_SEND,
- SI476X_I2C_RECV
-};
-
-int si476x_core_i2c_xfer(struct si476x_core *,
- enum si476x_i2c_type,
- char *, int);
-
-
-/* -------------------- si476x-cmd.c ----------------------- */
-
-int si476x_core_cmd_func_info(struct si476x_core *, struct si476x_func_info *);
-int si476x_core_cmd_set_property(struct si476x_core *, u16, u16);
-int si476x_core_cmd_get_property(struct si476x_core *, u16);
-int si476x_core_cmd_dig_audio_pin_cfg(struct si476x_core *,
- enum si476x_dclk_config,
- enum si476x_dfs_config,
- enum si476x_dout_config,
- enum si476x_xout_config);
-int si476x_core_cmd_zif_pin_cfg(struct si476x_core *,
- enum si476x_iqclk_config,
- enum si476x_iqfs_config,
- enum si476x_iout_config,
- enum si476x_qout_config);
-int si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(struct si476x_core *,
- enum si476x_icin_config,
- enum si476x_icip_config,
- enum si476x_icon_config,
- enum si476x_icop_config);
-int si476x_core_cmd_ana_audio_pin_cfg(struct si476x_core *,
- enum si476x_lrout_config);
-int si476x_core_cmd_intb_pin_cfg(struct si476x_core *, enum si476x_intb_config,
- enum si476x_a1_config);
-int si476x_core_cmd_fm_seek_start(struct si476x_core *, bool, bool);
-int si476x_core_cmd_am_seek_start(struct si476x_core *, bool, bool);
-int si476x_core_cmd_fm_rds_status(struct si476x_core *, bool, bool, bool,
- struct si476x_rds_status_report *);
-int si476x_core_cmd_fm_rds_blockcount(struct si476x_core *, bool,
- struct si476x_rds_blockcount_report *);
-int si476x_core_cmd_fm_tune_freq(struct si476x_core *,
- struct si476x_tune_freq_args *);
-int si476x_core_cmd_am_tune_freq(struct si476x_core *,
- struct si476x_tune_freq_args *);
-int si476x_core_cmd_am_rsq_status(struct si476x_core *,
- struct si476x_rsq_status_args *,
- struct si476x_rsq_status_report *);
-int si476x_core_cmd_fm_rsq_status(struct si476x_core *,
- struct si476x_rsq_status_args *,
- struct si476x_rsq_status_report *);
-int si476x_core_cmd_power_up(struct si476x_core *,
- struct si476x_power_up_args *);
-int si476x_core_cmd_power_down(struct si476x_core *,
- struct si476x_power_down_args *);
-int si476x_core_cmd_fm_phase_div_status(struct si476x_core *);
-int si476x_core_cmd_fm_phase_diversity(struct si476x_core *,
- enum si476x_phase_diversity_mode);
-
-int si476x_core_cmd_fm_acf_status(struct si476x_core *,
- struct si476x_acf_status_report *);
-int si476x_core_cmd_am_acf_status(struct si476x_core *,
- struct si476x_acf_status_report *);
-int si476x_core_cmd_agc_status(struct si476x_core *,
- struct si476x_agc_status_report *);
-
-enum si476x_power_grid_type {
- SI476X_POWER_GRID_50HZ = 0,
- SI476X_POWER_GRID_60HZ,
-};
-
-/* Properties */
-
-enum si476x_interrupt_flags {
- SI476X_STCIEN = (1 << 0),
- SI476X_ACFIEN = (1 << 1),
- SI476X_RDSIEN = (1 << 2),
- SI476X_RSQIEN = (1 << 3),
-
- SI476X_ERRIEN = (1 << 6),
- SI476X_CTSIEN = (1 << 7),
-
- SI476X_STCREP = (1 << 8),
- SI476X_ACFREP = (1 << 9),
- SI476X_RDSREP = (1 << 10),
- SI476X_RSQREP = (1 << 11),
-};
-
-enum si476x_rdsint_sources {
- SI476X_RDSTPPTY = (1 << 4),
- SI476X_RDSPI = (1 << 3),
- SI476X_RDSSYNC = (1 << 1),
- SI476X_RDSRECV = (1 << 0),
-};
-
-enum si476x_status_response_bits {
- SI476X_CTS = (1 << 7),
- SI476X_ERR = (1 << 6),
- /* Status response for WB receiver */
- SI476X_WB_ASQ_INT = (1 << 4),
- SI476X_RSQ_INT = (1 << 3),
- /* Status response for FM receiver */
- SI476X_FM_RDS_INT = (1 << 2),
- SI476X_ACF_INT = (1 << 1),
- SI476X_STC_INT = (1 << 0),
-};
-
-/* -------------------- si476x-prop.c ----------------------- */
-
-enum si476x_common_receiver_properties {
- SI476X_PROP_INT_CTL_ENABLE = 0x0000,
- SI476X_PROP_DIGITAL_IO_INPUT_SAMPLE_RATE = 0x0200,
- SI476X_PROP_DIGITAL_IO_INPUT_FORMAT = 0x0201,
- SI476X_PROP_DIGITAL_IO_OUTPUT_SAMPLE_RATE = 0x0202,
- SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT = 0x0203,
-
- SI476X_PROP_SEEK_BAND_BOTTOM = 0x1100,
- SI476X_PROP_SEEK_BAND_TOP = 0x1101,
- SI476X_PROP_SEEK_FREQUENCY_SPACING = 0x1102,
-
- SI476X_PROP_VALID_MAX_TUNE_ERROR = 0x2000,
- SI476X_PROP_VALID_SNR_THRESHOLD = 0x2003,
- SI476X_PROP_VALID_RSSI_THRESHOLD = 0x2004,
-};
-
-enum si476x_am_receiver_properties {
- SI476X_PROP_AUDIO_PWR_LINE_FILTER = 0x0303,
-};
-
-enum si476x_fm_receiver_properties {
- SI476X_PROP_AUDIO_DEEMPHASIS = 0x0302,
-
- SI476X_PROP_FM_RDS_INTERRUPT_SOURCE = 0x4000,
- SI476X_PROP_FM_RDS_INTERRUPT_FIFO_COUNT = 0x4001,
- SI476X_PROP_FM_RDS_CONFIG = 0x4002,
-};
-
-enum si476x_prop_audio_pwr_line_filter_bits {
- SI476X_PROP_PWR_HARMONICS_MASK = 0x001f,
- SI476X_PROP_PWR_GRID_MASK = 0x0100,
- SI476X_PROP_PWR_ENABLE_MASK = 0x0200,
- SI476X_PROP_PWR_GRID_50HZ = 0x0000,
- SI476X_PROP_PWR_GRID_60HZ = 0x0100,
-};
-
-enum si476x_prop_fm_rds_config_bits {
- SI476X_PROP_RDSEN_MASK = 0x1,
- SI476X_PROP_RDSEN = 0x1,
-};
-
-
-struct regmap *devm_regmap_init_si476x(struct si476x_core *);
-
-#endif /* SI476X_CORE_H */
diff --git a/include/linux/mfd/si476x-platform.h b/include/linux/mfd/si476x-platform.h
deleted file mode 100644
index f9e1f6b27277..000000000000
--- a/include/linux/mfd/si476x-platform.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * include/media/si476x-platform.h -- Platform data specific definitions
- *
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-
-#ifndef __SI476X_PLATFORM_H__
-#define __SI476X_PLATFORM_H__
-
-/* It is possible to select one of the four addresses using pins A0
- * and A1 on SI476x */
-#define SI476X_I2C_ADDR_1 0x60
-#define SI476X_I2C_ADDR_2 0x61
-#define SI476X_I2C_ADDR_3 0x62
-#define SI476X_I2C_ADDR_4 0x63
-
-enum si476x_iqclk_config {
- SI476X_IQCLK_NOOP = 0,
- SI476X_IQCLK_TRISTATE = 1,
- SI476X_IQCLK_IQ = 21,
-};
-enum si476x_iqfs_config {
- SI476X_IQFS_NOOP = 0,
- SI476X_IQFS_TRISTATE = 1,
- SI476X_IQFS_IQ = 21,
-};
-enum si476x_iout_config {
- SI476X_IOUT_NOOP = 0,
- SI476X_IOUT_TRISTATE = 1,
- SI476X_IOUT_OUTPUT = 22,
-};
-enum si476x_qout_config {
- SI476X_QOUT_NOOP = 0,
- SI476X_QOUT_TRISTATE = 1,
- SI476X_QOUT_OUTPUT = 22,
-};
-
-enum si476x_dclk_config {
- SI476X_DCLK_NOOP = 0,
- SI476X_DCLK_TRISTATE = 1,
- SI476X_DCLK_DAUDIO = 10,
-};
-
-enum si476x_dfs_config {
- SI476X_DFS_NOOP = 0,
- SI476X_DFS_TRISTATE = 1,
- SI476X_DFS_DAUDIO = 10,
-};
-
-enum si476x_dout_config {
- SI476X_DOUT_NOOP = 0,
- SI476X_DOUT_TRISTATE = 1,
- SI476X_DOUT_I2S_OUTPUT = 12,
- SI476X_DOUT_I2S_INPUT = 13,
-};
-
-enum si476x_xout_config {
- SI476X_XOUT_NOOP = 0,
- SI476X_XOUT_TRISTATE = 1,
- SI476X_XOUT_I2S_INPUT = 13,
- SI476X_XOUT_MODE_SELECT = 23,
-};
-
-enum si476x_icin_config {
- SI476X_ICIN_NOOP = 0,
- SI476X_ICIN_TRISTATE = 1,
- SI476X_ICIN_GPO1_HIGH = 2,
- SI476X_ICIN_GPO1_LOW = 3,
- SI476X_ICIN_IC_LINK = 30,
-};
-
-enum si476x_icip_config {
- SI476X_ICIP_NOOP = 0,
- SI476X_ICIP_TRISTATE = 1,
- SI476X_ICIP_GPO2_HIGH = 2,
- SI476X_ICIP_GPO2_LOW = 3,
- SI476X_ICIP_IC_LINK = 30,
-};
-
-enum si476x_icon_config {
- SI476X_ICON_NOOP = 0,
- SI476X_ICON_TRISTATE = 1,
- SI476X_ICON_I2S = 10,
- SI476X_ICON_IC_LINK = 30,
-};
-
-enum si476x_icop_config {
- SI476X_ICOP_NOOP = 0,
- SI476X_ICOP_TRISTATE = 1,
- SI476X_ICOP_I2S = 10,
- SI476X_ICOP_IC_LINK = 30,
-};
-
-
-enum si476x_lrout_config {
- SI476X_LROUT_NOOP = 0,
- SI476X_LROUT_TRISTATE = 1,
- SI476X_LROUT_AUDIO = 2,
- SI476X_LROUT_MPX = 3,
-};
-
-
-enum si476x_intb_config {
- SI476X_INTB_NOOP = 0,
- SI476X_INTB_TRISTATE = 1,
- SI476X_INTB_DAUDIO = 10,
- SI476X_INTB_IRQ = 40,
-};
-
-enum si476x_a1_config {
- SI476X_A1_NOOP = 0,
- SI476X_A1_TRISTATE = 1,
- SI476X_A1_IRQ = 40,
-};
-
-
-struct si476x_pinmux {
- enum si476x_dclk_config dclk;
- enum si476x_dfs_config dfs;
- enum si476x_dout_config dout;
- enum si476x_xout_config xout;
-
- enum si476x_iqclk_config iqclk;
- enum si476x_iqfs_config iqfs;
- enum si476x_iout_config iout;
- enum si476x_qout_config qout;
-
- enum si476x_icin_config icin;
- enum si476x_icip_config icip;
- enum si476x_icon_config icon;
- enum si476x_icop_config icop;
-
- enum si476x_lrout_config lrout;
-
- enum si476x_intb_config intb;
- enum si476x_a1_config a1;
-};
-
-enum si476x_ibias6x {
- SI476X_IBIAS6X_OTHER = 0,
- SI476X_IBIAS6X_RCVR1_NON_4MHZ_CLK = 1,
-};
-
-enum si476x_xstart {
- SI476X_XSTART_MULTIPLE_TUNER = 0x11,
- SI476X_XSTART_NORMAL = 0x77,
-};
-
-enum si476x_freq {
- SI476X_FREQ_4_MHZ = 0,
- SI476X_FREQ_37P209375_MHZ = 1,
- SI476X_FREQ_36P4_MHZ = 2,
- SI476X_FREQ_37P8_MHZ = 3,
-};
-
-enum si476x_xmode {
- SI476X_XMODE_CRYSTAL_RCVR1 = 1,
- SI476X_XMODE_EXT_CLOCK = 2,
- SI476X_XMODE_CRYSTAL_RCVR2_3 = 3,
-};
-
-enum si476x_xbiashc {
- SI476X_XBIASHC_SINGLE_RECEIVER = 0,
- SI476X_XBIASHC_MULTIPLE_RECEIVER = 1,
-};
-
-enum si476x_xbias {
- SI476X_XBIAS_RCVR2_3 = 0,
- SI476X_XBIAS_4MHZ_RCVR1 = 3,
- SI476X_XBIAS_RCVR1 = 7,
-};
-
-enum si476x_func {
- SI476X_FUNC_BOOTLOADER = 0,
- SI476X_FUNC_FM_RECEIVER = 1,
- SI476X_FUNC_AM_RECEIVER = 2,
- SI476X_FUNC_WB_RECEIVER = 3,
-};
-
-
-/**
- * @xcload: Selects the amount of additional on-chip capacitance to
- * be connected between XTAL1 and gnd and between XTAL2 and
- * GND. One half of the capacitance value shown here is the
- * additional load capacitance presented to the xtal. The
- * minimum step size is 0.277 pF. Recommended value is 0x28
- * but it will be layout dependent. Range is 0–0x3F i.e.
- * (0–16.33 pF)
- * @ctsien: enable CTSINT(interrupt request when CTS condition
- * arises) when set
- * @intsel: when set A1 pin becomes the interrupt pin; otherwise,
- * INTB is the interrupt pin
- * @func: selects the boot function of the device. I.e.
- * SI476X_BOOTLOADER - Boot loader
- * SI476X_FM_RECEIVER - FM receiver
- * SI476X_AM_RECEIVER - AM receiver
- * SI476X_WB_RECEIVER - Weatherband receiver
- * @freq: oscillator's crystal frequency:
- * SI476X_XTAL_37P209375_MHZ - 37.209375 Mhz
- * SI476X_XTAL_36P4_MHZ - 36.4 Mhz
- * SI476X_XTAL_37P8_MHZ - 37.8 Mhz
- */
-struct si476x_power_up_args {
- enum si476x_ibias6x ibias6x;
- enum si476x_xstart xstart;
- u8 xcload;
- bool fastboot;
- enum si476x_xbiashc xbiashc;
- enum si476x_xbias xbias;
- enum si476x_func func;
- enum si476x_freq freq;
- enum si476x_xmode xmode;
-};
-
-
-/**
- * enum si476x_phase_diversity_mode - possbile phase diversity modes
- * for SI4764/5/6/7 chips.
- *
- * @SI476X_PHDIV_DISABLED: Phase diversity feature is
- * disabled.
- * @SI476X_PHDIV_PRIMARY_COMBINING: Tuner works as a primary tuner
- * in combination with a
- * secondary one.
- * @SI476X_PHDIV_PRIMARY_ANTENNA: Tuner works as a primary tuner
- * using only its own antenna.
- * @SI476X_PHDIV_SECONDARY_ANTENNA: Tuner works as a primary tuner
- * usning seconary tuner's antenna.
- * @SI476X_PHDIV_SECONDARY_COMBINING: Tuner works as a secondary
- * tuner in combination with the
- * primary one.
- */
-enum si476x_phase_diversity_mode {
- SI476X_PHDIV_DISABLED = 0,
- SI476X_PHDIV_PRIMARY_COMBINING = 1,
- SI476X_PHDIV_PRIMARY_ANTENNA = 2,
- SI476X_PHDIV_SECONDARY_ANTENNA = 3,
- SI476X_PHDIV_SECONDARY_COMBINING = 5,
-};
-
-
-/*
- * Platform dependent definition
- */
-struct si476x_platform_data {
- struct si476x_power_up_args power_up_parameters;
- enum si476x_phase_diversity_mode diversity_mode;
-
- struct si476x_pinmux pinmux;
-};
-
-
-#endif /* __SI476X_PLATFORM_H__ */
diff --git a/include/linux/mfd/si476x-reports.h b/include/linux/mfd/si476x-reports.h
deleted file mode 100644
index 93b34184699d..000000000000
--- a/include/linux/mfd/si476x-reports.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * include/media/si476x-platform.h -- Definitions of the data formats
- * returned by debugfs hooks
- *
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-
-#ifndef __SI476X_REPORTS_H__
-#define __SI476X_REPORTS_H__
-
-/**
- * struct si476x_rsq_status - structure containing received signal
- * quality
- * @multhint: Multipath Detect High.
- * true - Indicatedes that the value is below
- * FM_RSQ_MULTIPATH_HIGH_THRESHOLD
- * false - Indicatedes that the value is above
- * FM_RSQ_MULTIPATH_HIGH_THRESHOLD
- * @multlint: Multipath Detect Low.
- * true - Indicatedes that the value is below
- * FM_RSQ_MULTIPATH_LOW_THRESHOLD
- * false - Indicatedes that the value is above
- * FM_RSQ_MULTIPATH_LOW_THRESHOLD
- * @snrhint: SNR Detect High.
- * true - Indicatedes that the value is below
- * FM_RSQ_SNR_HIGH_THRESHOLD
- * false - Indicatedes that the value is above
- * FM_RSQ_SNR_HIGH_THRESHOLD
- * @snrlint: SNR Detect Low.
- * true - Indicatedes that the value is below
- * FM_RSQ_SNR_LOW_THRESHOLD
- * false - Indicatedes that the value is above
- * FM_RSQ_SNR_LOW_THRESHOLD
- * @rssihint: RSSI Detect High.
- * true - Indicatedes that the value is below
- * FM_RSQ_RSSI_HIGH_THRESHOLD
- * false - Indicatedes that the value is above
- * FM_RSQ_RSSI_HIGH_THRESHOLD
- * @rssilint: RSSI Detect Low.
- * true - Indicatedes that the value is below
- * FM_RSQ_RSSI_LOW_THRESHOLD
- * false - Indicatedes that the value is above
- * FM_RSQ_RSSI_LOW_THRESHOLD
- * @bltf: Band Limit.
- * Set if seek command hits the band limit or wrapped to
- * the original frequency.
- * @snr_ready: SNR measurement in progress.
- * @rssiready: RSSI measurement in progress.
- * @afcrl: Set if FREQOFF >= MAX_TUNE_ERROR
- * @valid: Set if the channel is valid
- * rssi < FM_VALID_RSSI_THRESHOLD
- * snr < FM_VALID_SNR_THRESHOLD
- * tune_error < FM_VALID_MAX_TUNE_ERROR
- * @readfreq: Current tuned frequency.
- * @freqoff: Signed frequency offset.
- * @rssi: Received Signal Strength Indicator(dBuV).
- * @snr: RF SNR Indicator(dB).
- * @lassi:
- * @hassi: Low/High side Adjacent(100 kHz) Channel Strength Indicator
- * @mult: Multipath indicator
- * @dev: Who knows? But values may vary.
- * @readantcap: Antenna tuning capacity value.
- * @assi: Adjacent Channel(+/- 200kHz) Strength Indicator
- * @usn: Ultrasonic Noise Inticator in -DBFS
- */
-struct si476x_rsq_status_report {
- __u8 multhint, multlint;
- __u8 snrhint, snrlint;
- __u8 rssihint, rssilint;
- __u8 bltf;
- __u8 snr_ready;
- __u8 rssiready;
- __u8 injside;
- __u8 afcrl;
- __u8 valid;
-
- __u16 readfreq;
- __s8 freqoff;
- __s8 rssi;
- __s8 snr;
- __s8 issi;
- __s8 lassi, hassi;
- __s8 mult;
- __u8 dev;
- __u16 readantcap;
- __s8 assi;
- __s8 usn;
-
- __u8 pilotdev;
- __u8 rdsdev;
- __u8 assidev;
- __u8 strongdev;
- __u16 rdspi;
-} __packed;
-
-/**
- * si476x_acf_status_report - ACF report results
- *
- * @blend_int: If set, indicates that stereo separation has crossed
- * below the blend threshold as set by FM_ACF_BLEND_THRESHOLD
- * @hblend_int: If set, indicates that HiBlend cutoff frequency is
- * lower than threshold as set by FM_ACF_HBLEND_THRESHOLD
- * @hicut_int: If set, indicates that HiCut cutoff frequency is lower
- * than the threshold set by ACF_
-
- */
-struct si476x_acf_status_report {
- __u8 blend_int;
- __u8 hblend_int;
- __u8 hicut_int;
- __u8 chbw_int;
- __u8 softmute_int;
- __u8 smute;
- __u8 smattn;
- __u8 chbw;
- __u8 hicut;
- __u8 hiblend;
- __u8 pilot;
- __u8 stblend;
-} __packed;
-
-enum si476x_fmagc {
- SI476X_FMAGC_10K_OHM = 0,
- SI476X_FMAGC_800_OHM = 1,
- SI476X_FMAGC_400_OHM = 2,
- SI476X_FMAGC_200_OHM = 4,
- SI476X_FMAGC_100_OHM = 8,
- SI476X_FMAGC_50_OHM = 16,
- SI476X_FMAGC_25_OHM = 32,
- SI476X_FMAGC_12P5_OHM = 64,
- SI476X_FMAGC_6P25_OHM = 128,
-};
-
-struct si476x_agc_status_report {
- __u8 mxhi;
- __u8 mxlo;
- __u8 lnahi;
- __u8 lnalo;
- __u8 fmagc1;
- __u8 fmagc2;
- __u8 pgagain;
- __u8 fmwblang;
-} __packed;
-
-struct si476x_rds_blockcount_report {
- __u16 expected;
- __u16 received;
- __u16 uncorrectable;
-} __packed;
-
-#endif /* __SI476X_REPORTS_H__ */
diff --git a/include/media/drv-intf/si476x.h b/include/media/drv-intf/si476x.h
deleted file mode 100644
index 07f291d50b77..000000000000
--- a/include/media/drv-intf/si476x.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * include/media/drv-intf/si476x.h -- Common definitions for si476x driver
- *
- * Copyright (C) 2012 Innovative Converged Devices(ICD)
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-
-#ifndef SI476X_H
-#define SI476X_H
-
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <linux/mfd/si476x-reports.h>
-
-enum si476x_ctrl_id {
- V4L2_CID_SI476X_RSSI_THRESHOLD = (V4L2_CID_USER_SI476X_BASE + 1),
- V4L2_CID_SI476X_SNR_THRESHOLD = (V4L2_CID_USER_SI476X_BASE + 2),
- V4L2_CID_SI476X_MAX_TUNE_ERROR = (V4L2_CID_USER_SI476X_BASE + 3),
- V4L2_CID_SI476X_HARMONICS_COUNT = (V4L2_CID_USER_SI476X_BASE + 4),
- V4L2_CID_SI476X_DIVERSITY_MODE = (V4L2_CID_USER_SI476X_BASE + 5),
- V4L2_CID_SI476X_INTERCHIP_LINK = (V4L2_CID_USER_SI476X_BASE + 6),
-};
-
-#endif /* SI476X_H*/
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index affec0ab4781..40680bf5558d 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -133,8 +133,8 @@ enum v4l2_colorfx {
#define V4L2_CID_USER_S2255_BASE (V4L2_CID_USER_BASE + 0x1030)
/*
- * The base for the si476x driver controls. See include/media/drv-intf/si476x.h
- * for the list of controls. Total of 16 controls is reserved for this driver
+ * Previously the base for the si476x driver controls, now removed.
+ * Total of 16 controls is reserved for this driver
*/
#define V4L2_CID_USER_SI476X_BASE (V4L2_CID_USER_BASE + 0x1040)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f9a47e262a77..1f7dc2c7e338 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -250,7 +250,6 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_RTQ9128
imply SND_SOC_SDW_MOCKUP
imply SND_SOC_SGTL5000
- imply SND_SOC_SI476X
imply SND_SOC_SIMPLE_AMPLIFIER
imply SND_SOC_SIMPLE_MUX
imply SND_SOC_SMA1303
@@ -2061,10 +2060,6 @@ config SND_SOC_SGTL5000
tristate "Freescale SGTL5000 CODEC"
depends on I2C
-config SND_SOC_SI476X
- tristate
- depends on MFD_SI476X_CORE
-
config SND_SOC_SIGMADSP
tristate
select CRC32
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 3d122ace75ad..f4f20a8e112e 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -298,7 +298,6 @@ snd-soc-alc5632-y := alc5632.o
snd-soc-sigmadsp-y := sigmadsp.o
snd-soc-sigmadsp-i2c-y := sigmadsp-i2c.o
snd-soc-sigmadsp-regmap-y := sigmadsp-regmap.o
-snd-soc-si476x-y := si476x.o
snd-soc-sma1303-y := sma1303.o
snd-soc-sma1307-y := sma1307.o
snd-soc-spdif-tx-y := spdif_transmitter.o
@@ -739,7 +738,6 @@ obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
-obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
obj-$(CONFIG_SND_SOC_SMA1303) += snd-soc-sma1303.o
obj-$(CONFIG_SND_SOC_SMA1307) += snd-soc-sma1307.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
deleted file mode 100644
index d87141ba8438..000000000000
--- a/sound/soc/codecs/si476x.c
+++ /dev/null
@@ -1,263 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * sound/soc/codecs/si476x.c -- Codec driver for SI476X chips
- *
- * Copyright (C) 2012 Innovative Converged Devices(ICD)
- * Copyright (C) 2013 Andrey Smirnov
- *
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <linux/regmap.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include <linux/i2c.h>
-
-#include <linux/mfd/si476x-core.h>
-
-enum si476x_audio_registers {
- SI476X_DIGITAL_IO_OUTPUT_FORMAT = 0x0203,
- SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE = 0x0202,
-};
-
-enum si476x_digital_io_output_format {
- SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT = 11,
- SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT = 8,
-};
-
-#define SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK ((0x7 << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | \
- (0x7 << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT))
-#define SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK (0x7e)
-
-enum si476x_daudio_formats {
- SI476X_DAUDIO_MODE_I2S = (0x0 << 1),
- SI476X_DAUDIO_MODE_DSP_A = (0x6 << 1),
- SI476X_DAUDIO_MODE_DSP_B = (0x7 << 1),
- SI476X_DAUDIO_MODE_LEFT_J = (0x8 << 1),
- SI476X_DAUDIO_MODE_RIGHT_J = (0x9 << 1),
-
- SI476X_DAUDIO_MODE_IB = (1 << 5),
- SI476X_DAUDIO_MODE_IF = (1 << 6),
-};
-
-enum si476x_pcm_format {
- SI476X_PCM_FORMAT_S8 = 2,
- SI476X_PCM_FORMAT_S16_LE = 4,
- SI476X_PCM_FORMAT_S20_3LE = 5,
- SI476X_PCM_FORMAT_S24_LE = 6,
-};
-
-static const struct snd_soc_dapm_widget si476x_dapm_widgets[] = {
-SND_SOC_DAPM_OUTPUT("LOUT"),
-SND_SOC_DAPM_OUTPUT("ROUT"),
-};
-
-static const struct snd_soc_dapm_route si476x_dapm_routes[] = {
- { "Capture", NULL, "LOUT" },
- { "Capture", NULL, "ROUT" },
-};
-
-static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct si476x_core *core = i2c_mfd_cell_to_core(codec_dai->dev);
- int err;
- u16 format = 0;
-
- if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC)
- return -EINVAL;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- format |= SI476X_DAUDIO_MODE_DSP_A;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- format |= SI476X_DAUDIO_MODE_DSP_B;
- break;
- case SND_SOC_DAIFMT_I2S:
- format |= SI476X_DAUDIO_MODE_I2S;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- format |= SI476X_DAUDIO_MODE_RIGHT_J;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- format |= SI476X_DAUDIO_MODE_LEFT_J;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- format |= SI476X_DAUDIO_MODE_IB;
- break;
- default:
- return -EINVAL;
- }
- break;
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- format |= SI476X_DAUDIO_MODE_IB |
- SI476X_DAUDIO_MODE_IF;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- format |= SI476X_DAUDIO_MODE_IB;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- format |= SI476X_DAUDIO_MODE_IF;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- si476x_core_lock(core);
-
- err = snd_soc_component_update_bits(codec_dai->component, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
- SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK,
- format);
-
- si476x_core_unlock(core);
-
- if (err < 0) {
- dev_err(codec_dai->component->dev, "Failed to set output format\n");
- return err;
- }
-
- return 0;
-}
-
-static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct si476x_core *core = i2c_mfd_cell_to_core(dai->dev);
- int rate, width, err;
-
- rate = params_rate(params);
- if (rate < 32000 || rate > 48000) {
- dev_err(dai->component->dev, "Rate: %d is not supported\n", rate);
- return -EINVAL;
- }
-
- switch (params_width(params)) {
- case 8:
- width = SI476X_PCM_FORMAT_S8;
- break;
- case 16:
- width = SI476X_PCM_FORMAT_S16_LE;
- break;
- case 20:
- width = SI476X_PCM_FORMAT_S20_3LE;
- break;
- case 24:
- width = SI476X_PCM_FORMAT_S24_LE;
- break;
- default:
- return -EINVAL;
- }
-
- si476x_core_lock(core);
-
- err = snd_soc_component_write(dai->component, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
- rate);
- if (err < 0) {
- dev_err(dai->component->dev, "Failed to set sample rate\n");
- goto out;
- }
-
- err = snd_soc_component_update_bits(dai->component, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
- SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK,
- (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) |
- (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT));
- if (err < 0) {
- dev_err(dai->component->dev, "Failed to set output width\n");
- goto out;
- }
-
-out:
- si476x_core_unlock(core);
-
- return err;
-}
-
-static const struct snd_soc_dai_ops si476x_dai_ops = {
- .hw_params = si476x_codec_hw_params,
- .set_fmt = si476x_codec_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver si476x_dai = {
- .name = "si476x-codec",
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
-
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S20_3LE |
- SNDRV_PCM_FMTBIT_S24_LE
- },
- .ops = &si476x_dai_ops,
-};
-
-static int si476x_probe(struct snd_soc_component *component)
-{
- snd_soc_component_init_regmap(component,
- dev_get_regmap(component->dev->parent, NULL));
-
- return 0;
-}
-
-static const struct snd_soc_component_driver soc_component_dev_si476x = {
- .probe = si476x_probe,
- .dapm_widgets = si476x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets),
- .dapm_routes = si476x_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes),
- .idle_bias_on = 1,
- .use_pmdown_time = 1,
- .endianness = 1,
-};
-
-static int si476x_platform_probe(struct platform_device *pdev)
-{
- return devm_snd_soc_register_component(&pdev->dev,
- &soc_component_dev_si476x,
- &si476x_dai, 1);
-}
-
-MODULE_ALIAS("platform:si476x-codec");
-
-static struct platform_driver si476x_platform_driver = {
- .driver = {
- .name = "si476x-codec",
- },
- .probe = si476x_platform_probe,
-};
-module_platform_driver(si476x_platform_driver);
-
-MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
-MODULE_DESCRIPTION("ASoC Si4761/64 codec driver");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 310ee4c282a1..ff8ae6e514ea 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -794,13 +794,6 @@ static const struct fsl_asoc_card_pdata fsl_asoc_wm8524_pdata = {
.num_dapm_routes = ARRAY_SIZE(audio_map_tx),
};
-static const struct fsl_asoc_card_pdata fsl_asoc_si476x_pdata = {
- .codec_dai_name = "si476x-codec",
- .dai_fmt = DAI_FMT_BASE | SND_SOC_DAIFMT_CBC_CFC,
- .dapm_routes = audio_map_rx,
- .num_dapm_routes = ARRAY_SIZE(audio_map_rx),
-};
-
static const struct fsl_asoc_card_pdata fsl_asoc_wm8958_pdata = {
.codec_dai_name = "wm8994-aif1",
.dai_fmt = DAI_FMT_BASE | SND_SOC_DAIFMT_CBP_CFP,
@@ -1398,7 +1391,6 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
{ .compatible = "fsl,imx-audio-wm8960", .data = &fsl_asoc_wm8960_pdata },
{ .compatible = "fsl,imx-audio-mqs", .data = &fsl_asoc_mqs_pdata },
{ .compatible = "fsl,imx-audio-wm8524", .data = &fsl_asoc_wm8524_pdata },
- { .compatible = "fsl,imx-audio-si476x", .data = &fsl_asoc_si476x_pdata },
{ .compatible = "fsl,imx-audio-wm8958", .data = &fsl_asoc_wm8958_pdata },
{ .compatible = "fsl,imx-audio-nau8822", .data = &fsl_asoc_nau8822_pdata },
{ .compatible = "fsl,imx-audio-wm8904", .data = &fsl_asoc_wm8904_pdata },
--
2.53.0
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 04/14] mfd: remove unused wm8400 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (2 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 03/14] mfd: remove unused si476x driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:27 ` Mark Brown
2026-09-09 14:38 ` Charles Keepax
2026-09-09 13:21 ` [PATCH 05/14] mfd: remove unused adp5520 driver Arnd Bergmann
` (11 subsequent siblings)
15 siblings, 2 replies; 31+ 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 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>
---
MAINTAINERS | 1 -
drivers/mfd/Kconfig | 11 -
drivers/mfd/Makefile | 1 -
drivers/mfd/wm8400-core.c | 163 ----
drivers/regulator/Kconfig | 7 -
drivers/regulator/Makefile | 1 -
drivers/regulator/wm8400-regulator.c | 276 ------
include/linux/mfd/wm8400-audio.h | 1174 ----------------------
include/linux/mfd/wm8400-private.h | 913 -----------------
include/linux/mfd/wm8400.h | 27 -
sound/soc/codecs/Kconfig | 6 -
sound/soc/codecs/Makefile | 2 -
sound/soc/codecs/wm8400.c | 1348 --------------------------
sound/soc/codecs/wm8400.h | 54 --
14 files changed, 3984 deletions(-)
delete mode 100644 drivers/mfd/wm8400-core.c
delete mode 100644 drivers/regulator/wm8400-regulator.c
delete mode 100644 include/linux/mfd/wm8400-audio.h
delete mode 100644 include/linux/mfd/wm8400-private.h
delete mode 100644 include/linux/mfd/wm8400.h
delete mode 100644 sound/soc/codecs/wm8400.c
delete mode 100644 sound/soc/codecs/wm8400.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 2f5a5c053439..c5e2140cdac0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29398,7 +29398,6 @@ F: drivers/watchdog/wm83*_wdt.c
F: include/linux/mfd/arizona/
F: include/linux/mfd/wm831x/
F: include/linux/mfd/wm8350/
-F: include/linux/mfd/wm8400*
F: include/linux/regulator/arizona*
F: include/linux/wm97xx.h
F: include/sound/wm????.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b271c9f0c5fc..2b621a77619c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2068,17 +2068,6 @@ config MFD_WM8998
help
Support for Wolfson Microelectronics WM8998 low power audio SoC
-config MFD_WM8400
- bool "Wolfson Microelectronics WM8400"
- select MFD_CORE
- depends on I2C=y
- select REGMAP_I2C
- help
- Support for the Wolfson Microelecronics WM8400 PMIC and audio
- CODEC. 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_WM831X
bool
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 649262eb0f5c..36f0ab039b77 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -55,7 +55,6 @@ ifeq ($(CONFIG_MFD_CS47L24),y)
arizona-objs += cs47l24-tables.o
endif
obj-$(CONFIG_MFD_WCD934X) += wcd934x.o
-obj-$(CONFIG_MFD_WM8400) += wm8400-core.o
wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o
wm831x-objs += wm831x-auxadc.o
obj-$(CONFIG_MFD_WM831X) += wm831x.o
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
deleted file mode 100644
index 8ecfe878a5ba..000000000000
--- a/drivers/mfd/wm8400-core.c
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Core driver for WM8400.
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- */
-
-#include <linux/init.h>
-#include <linux/bug.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/wm8400-private.h>
-#include <linux/mfd/wm8400-audio.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-
-static bool wm8400_volatile(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8400_INTERRUPT_STATUS_1:
- case WM8400_INTERRUPT_LEVELS:
- case WM8400_SHUTDOWN_REASON:
- return true;
- default:
- return false;
- }
-}
-
-static int wm8400_register_codec(struct wm8400 *wm8400)
-{
- const struct mfd_cell cell = {
- .name = "wm8400-codec",
- .platform_data = wm8400,
- .pdata_size = sizeof(*wm8400),
- };
-
- return devm_mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL);
-}
-
-/*
- * wm8400_init - Generic initialisation
- *
- * The WM8400 can be configured as either an I2C or SPI device. Probe
- * functions for each bus set up the accessors then call into this to
- * set up the device itself.
- */
-static int wm8400_init(struct wm8400 *wm8400,
- struct wm8400_platform_data *pdata)
-{
- unsigned int reg;
- int ret;
-
- /* Check that this is actually a WM8400 */
- ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, ®);
- if (ret != 0) {
- dev_err(wm8400->dev, "Chip ID register read failed\n");
- return -EIO;
- }
- if (reg != 0x6172) {
- dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n",
- reg);
- return -ENODEV;
- }
-
- ret = regmap_read(wm8400->regmap, WM8400_ID, ®);
- if (ret != 0) {
- dev_err(wm8400->dev, "ID register read failed: %d\n", ret);
- return ret;
- }
- reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT;
- dev_info(wm8400->dev, "WM8400 revision %x\n", reg);
-
- ret = wm8400_register_codec(wm8400);
- if (ret != 0) {
- dev_err(wm8400->dev, "Failed to register codec\n");
- return ret;
- }
-
- if (pdata && pdata->platform_init) {
- ret = pdata->platform_init(wm8400->dev);
- if (ret != 0) {
- dev_err(wm8400->dev, "Platform init failed: %d\n",
- ret);
- return ret;
- }
- } else
- dev_warn(wm8400->dev, "No platform initialisation supplied\n");
-
- return 0;
-}
-
-static const struct regmap_config wm8400_regmap_config = {
- .reg_bits = 8,
- .val_bits = 16,
- .max_register = WM8400_REGISTER_COUNT - 1,
-
- .volatile_reg = wm8400_volatile,
-
- .cache_type = REGCACHE_MAPLE,
-};
-
-/**
- * wm8400_reset_codec_reg_cache - Reset cached codec registers to
- * their default values.
- *
- * @wm8400: pointer to local driver data structure
- */
-void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400)
-{
- regmap_reinit_cache(wm8400->regmap, &wm8400_regmap_config);
-}
-EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache);
-
-#if IS_ENABLED(CONFIG_I2C)
-static int wm8400_i2c_probe(struct i2c_client *i2c)
-{
- struct wm8400 *wm8400;
-
- wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL);
- if (!wm8400)
- return -ENOMEM;
-
- wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config);
- if (IS_ERR(wm8400->regmap))
- return PTR_ERR(wm8400->regmap);
-
- wm8400->dev = &i2c->dev;
- i2c_set_clientdata(i2c, wm8400);
-
- return wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
-}
-
-static const struct i2c_device_id wm8400_i2c_id[] = {
- { "wm8400" },
- { }
-};
-
-static struct i2c_driver wm8400_i2c_driver = {
- .driver = {
- .name = "WM8400",
- },
- .probe = wm8400_i2c_probe,
- .id_table = wm8400_i2c_id,
-};
-#endif
-
-static int __init wm8400_driver_init(void)
-{
- int ret = -ENODEV;
-
-#if IS_ENABLED(CONFIG_I2C)
- ret = i2c_add_driver(&wm8400_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register I2C driver: %d\n", ret);
-#endif
-
- return ret;
-}
-subsys_initcall(wm8400_driver_init);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 73b43dc1b3be..4869a1d5041b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1862,13 +1862,6 @@ config REGULATOR_WM8350
This driver provides support for the voltage and current regulators
of the WM8350 AudioPlus PMIC.
-config REGULATOR_WM8400
- tristate "Wolfson Microelectronics WM8400 AudioPlus PMIC"
- depends on MFD_WM8400
- help
- This driver provides support for the voltage regulators of the
- WM8400 AudioPlus PMIC.
-
config REGULATOR_WM8994
tristate "Wolfson Microelectronics WM8994 CODEC"
depends on MFD_WM8994
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 972f105567b5..86b5afcc974e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -215,7 +215,6 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
-obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
deleted file mode 100644
index fb3ca7956d00..000000000000
--- a/drivers/regulator/wm8400-regulator.c
+++ /dev/null
@@ -1,276 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-//
-// Regulator support for WM8400
-//
-// Copyright 2008 Wolfson Microelectronics PLC.
-//
-// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
-
-#include <linux/bug.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/regulator/driver.h>
-#include <linux/mfd/wm8400-private.h>
-
-static const struct linear_range wm8400_ldo_ranges[] = {
- REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000),
- REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000),
-};
-
-static const struct regulator_ops wm8400_ldo_ops = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .list_voltage = regulator_list_voltage_linear_range,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .map_voltage = regulator_map_voltage_linear_range,
-};
-
-static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev)
-{
- struct regmap *rmap = rdev_get_regmap(dev);
- int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
- u16 data[2];
- int ret;
-
- ret = regmap_bulk_read(rmap, WM8400_DCDC1_CONTROL_1 + offset, data, 2);
- if (ret != 0)
- return 0;
-
- /* Datasheet: hibernate */
- if (data[0] & WM8400_DC1_SLEEP)
- return REGULATOR_MODE_STANDBY;
-
- /* Datasheet: standby */
- if (!(data[0] & WM8400_DC1_ACTIVE))
- return REGULATOR_MODE_IDLE;
-
- /* Datasheet: active with or without force PWM */
- if (data[1] & WM8400_DC1_FRC_PWM)
- return REGULATOR_MODE_FAST;
- else
- return REGULATOR_MODE_NORMAL;
-}
-
-static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
-{
- struct regmap *rmap = rdev_get_regmap(dev);
- int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
- int ret;
-
- switch (mode) {
- case REGULATOR_MODE_FAST:
- /* Datasheet: active with force PWM */
- ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset,
- WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM);
- if (ret != 0)
- return ret;
-
- return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
- WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
- WM8400_DC1_ACTIVE);
-
- case REGULATOR_MODE_NORMAL:
- /* Datasheet: active */
- ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset,
- WM8400_DC1_FRC_PWM, 0);
- if (ret != 0)
- return ret;
-
- return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
- WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
- WM8400_DC1_ACTIVE);
-
- case REGULATOR_MODE_IDLE:
- /* Datasheet: standby */
- return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
- WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 0);
- default:
- return -EINVAL;
- }
-}
-
-static unsigned int wm8400_dcdc_get_optimum_mode(struct regulator_dev *dev,
- int input_uV, int output_uV,
- int load_uA)
-{
- return REGULATOR_MODE_NORMAL;
-}
-
-static const struct regulator_ops wm8400_dcdc_ops = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .list_voltage = regulator_list_voltage_linear,
- .map_voltage = regulator_map_voltage_linear,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_mode = wm8400_dcdc_get_mode,
- .set_mode = wm8400_dcdc_set_mode,
- .get_optimum_mode = wm8400_dcdc_get_optimum_mode,
-};
-
-static const struct regulator_desc regulators[] = {
- {
- .name = "LDO1",
- .id = WM8400_LDO1,
- .ops = &wm8400_ldo_ops,
- .enable_reg = WM8400_LDO1_CONTROL,
- .enable_mask = WM8400_LDO1_ENA,
- .n_voltages = WM8400_LDO1_VSEL_MASK + 1,
- .linear_ranges = wm8400_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
- .vsel_reg = WM8400_LDO1_CONTROL,
- .vsel_mask = WM8400_LDO1_VSEL_MASK,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO2",
- .id = WM8400_LDO2,
- .ops = &wm8400_ldo_ops,
- .enable_reg = WM8400_LDO2_CONTROL,
- .enable_mask = WM8400_LDO2_ENA,
- .n_voltages = WM8400_LDO2_VSEL_MASK + 1,
- .linear_ranges = wm8400_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
- .type = REGULATOR_VOLTAGE,
- .vsel_reg = WM8400_LDO2_CONTROL,
- .vsel_mask = WM8400_LDO2_VSEL_MASK,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO3",
- .id = WM8400_LDO3,
- .ops = &wm8400_ldo_ops,
- .enable_reg = WM8400_LDO3_CONTROL,
- .enable_mask = WM8400_LDO3_ENA,
- .n_voltages = WM8400_LDO3_VSEL_MASK + 1,
- .linear_ranges = wm8400_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
- .vsel_reg = WM8400_LDO3_CONTROL,
- .vsel_mask = WM8400_LDO3_VSEL_MASK,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO4",
- .id = WM8400_LDO4,
- .ops = &wm8400_ldo_ops,
- .enable_reg = WM8400_LDO4_CONTROL,
- .enable_mask = WM8400_LDO4_ENA,
- .n_voltages = WM8400_LDO4_VSEL_MASK + 1,
- .linear_ranges = wm8400_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
- .vsel_reg = WM8400_LDO4_CONTROL,
- .vsel_mask = WM8400_LDO4_VSEL_MASK,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC1",
- .id = WM8400_DCDC1,
- .ops = &wm8400_dcdc_ops,
- .enable_reg = WM8400_DCDC1_CONTROL_1,
- .enable_mask = WM8400_DC1_ENA_MASK,
- .n_voltages = WM8400_DC1_VSEL_MASK + 1,
- .vsel_reg = WM8400_DCDC1_CONTROL_1,
- .vsel_mask = WM8400_DC1_VSEL_MASK,
- .min_uV = 850000,
- .uV_step = 25000,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC2",
- .id = WM8400_DCDC2,
- .ops = &wm8400_dcdc_ops,
- .enable_reg = WM8400_DCDC2_CONTROL_1,
- .enable_mask = WM8400_DC2_ENA_MASK,
- .n_voltages = WM8400_DC2_VSEL_MASK + 1,
- .vsel_reg = WM8400_DCDC2_CONTROL_1,
- .vsel_mask = WM8400_DC2_VSEL_MASK,
- .min_uV = 850000,
- .uV_step = 25000,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- },
-};
-
-static int wm8400_regulator_probe(struct platform_device *pdev)
-{
- struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
- struct regulator_config config = { };
- struct regulator_dev *rdev;
-
- config.dev = &pdev->dev;
- config.init_data = dev_get_platdata(&pdev->dev);
- config.driver_data = wm8400;
- config.regmap = wm8400->regmap;
-
- rdev = devm_regulator_register(&pdev->dev, ®ulators[pdev->id],
- &config);
- if (IS_ERR(rdev))
- return PTR_ERR(rdev);
-
- platform_set_drvdata(pdev, rdev);
-
- return 0;
-}
-
-static struct platform_driver wm8400_regulator_driver = {
- .driver = {
- .name = "wm8400-regulator",
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
- .probe = wm8400_regulator_probe,
-};
-
-/**
- * wm8400_register_regulator - enable software control of a WM8400 regulator
- *
- * This function enables software control of a WM8400 regulator via
- * the regulator API. It is intended to be called from the
- * platform_init() callback of the WM8400 MFD driver.
- *
- * @dev: The WM8400 device to operate on.
- * @reg: The regulator to control.
- * @initdata: Regulator initdata for the regulator.
- */
-int wm8400_register_regulator(struct device *dev, int reg,
- struct regulator_init_data *initdata)
-{
- struct wm8400 *wm8400 = dev_get_drvdata(dev);
-
- if (wm8400->regulators[reg].name)
- return -EBUSY;
-
- initdata->driver_data = wm8400;
-
- wm8400->regulators[reg].name = "wm8400-regulator";
- wm8400->regulators[reg].id = reg;
- wm8400->regulators[reg].dev.parent = dev;
- wm8400->regulators[reg].dev.platform_data = initdata;
-
- return platform_device_register(&wm8400->regulators[reg]);
-}
-EXPORT_SYMBOL_GPL(wm8400_register_regulator);
-
-static int __init wm8400_regulator_init(void)
-{
- return platform_driver_register(&wm8400_regulator_driver);
-}
-subsys_initcall(wm8400_regulator_init);
-
-static void __exit wm8400_regulator_exit(void)
-{
- platform_driver_unregister(&wm8400_regulator_driver);
-}
-module_exit(wm8400_regulator_exit);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("WM8400 regulator driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8400-regulator");
diff --git a/include/linux/mfd/wm8400-audio.h b/include/linux/mfd/wm8400-audio.h
deleted file mode 100644
index d47bdcc7a765..000000000000
--- a/include/linux/mfd/wm8400-audio.h
+++ /dev/null
@@ -1,1174 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * wm8400 private definitions for audio
- *
- * Copyright 2008 Wolfson Microelectronics plc
- */
-
-#ifndef __LINUX_MFD_WM8400_AUDIO_H
-#define __LINUX_MFD_WM8400_AUDIO_H
-
-#include <linux/mfd/wm8400-audio.h>
-
-/*
- * R2 (0x02) - Power Management (1)
- */
-#define WM8400_CODEC_ENA 0x8000 /* CODEC_ENA */
-#define WM8400_CODEC_ENA_MASK 0x8000 /* CODEC_ENA */
-#define WM8400_CODEC_ENA_SHIFT 15 /* CODEC_ENA */
-#define WM8400_CODEC_ENA_WIDTH 1 /* CODEC_ENA */
-#define WM8400_SYSCLK_ENA 0x4000 /* SYSCLK_ENA */
-#define WM8400_SYSCLK_ENA_MASK 0x4000 /* SYSCLK_ENA */
-#define WM8400_SYSCLK_ENA_SHIFT 14 /* SYSCLK_ENA */
-#define WM8400_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
-#define WM8400_SPK_MIX_ENA 0x2000 /* SPK_MIX_ENA */
-#define WM8400_SPK_MIX_ENA_MASK 0x2000 /* SPK_MIX_ENA */
-#define WM8400_SPK_MIX_ENA_SHIFT 13 /* SPK_MIX_ENA */
-#define WM8400_SPK_MIX_ENA_WIDTH 1 /* SPK_MIX_ENA */
-#define WM8400_SPK_ENA 0x1000 /* SPK_ENA */
-#define WM8400_SPK_ENA_MASK 0x1000 /* SPK_ENA */
-#define WM8400_SPK_ENA_SHIFT 12 /* SPK_ENA */
-#define WM8400_SPK_ENA_WIDTH 1 /* SPK_ENA */
-#define WM8400_OUT3_ENA 0x0800 /* OUT3_ENA */
-#define WM8400_OUT3_ENA_MASK 0x0800 /* OUT3_ENA */
-#define WM8400_OUT3_ENA_SHIFT 11 /* OUT3_ENA */
-#define WM8400_OUT3_ENA_WIDTH 1 /* OUT3_ENA */
-#define WM8400_OUT4_ENA 0x0400 /* OUT4_ENA */
-#define WM8400_OUT4_ENA_MASK 0x0400 /* OUT4_ENA */
-#define WM8400_OUT4_ENA_SHIFT 10 /* OUT4_ENA */
-#define WM8400_OUT4_ENA_WIDTH 1 /* OUT4_ENA */
-#define WM8400_LOUT_ENA 0x0200 /* LOUT_ENA */
-#define WM8400_LOUT_ENA_MASK 0x0200 /* LOUT_ENA */
-#define WM8400_LOUT_ENA_SHIFT 9 /* LOUT_ENA */
-#define WM8400_LOUT_ENA_WIDTH 1 /* LOUT_ENA */
-#define WM8400_ROUT_ENA 0x0100 /* ROUT_ENA */
-#define WM8400_ROUT_ENA_MASK 0x0100 /* ROUT_ENA */
-#define WM8400_ROUT_ENA_SHIFT 8 /* ROUT_ENA */
-#define WM8400_ROUT_ENA_WIDTH 1 /* ROUT_ENA */
-#define WM8400_MIC1BIAS_ENA 0x0010 /* MIC1BIAS_ENA */
-#define WM8400_MIC1BIAS_ENA_MASK 0x0010 /* MIC1BIAS_ENA */
-#define WM8400_MIC1BIAS_ENA_SHIFT 4 /* MIC1BIAS_ENA */
-#define WM8400_MIC1BIAS_ENA_WIDTH 1 /* MIC1BIAS_ENA */
-#define WM8400_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */
-#define WM8400_VMID_MODE_SHIFT 1 /* VMID_MODE - [2:1] */
-#define WM8400_VMID_MODE_WIDTH 2 /* VMID_MODE - [2:1] */
-#define WM8400_VREF_ENA 0x0001 /* VREF_ENA */
-#define WM8400_VREF_ENA_MASK 0x0001 /* VREF_ENA */
-#define WM8400_VREF_ENA_SHIFT 0 /* VREF_ENA */
-#define WM8400_VREF_ENA_WIDTH 1 /* VREF_ENA */
-
-/*
- * R3 (0x03) - Power Management (2)
- */
-#define WM8400_FLL_ENA 0x8000 /* FLL_ENA */
-#define WM8400_FLL_ENA_MASK 0x8000 /* FLL_ENA */
-#define WM8400_FLL_ENA_SHIFT 15 /* FLL_ENA */
-#define WM8400_FLL_ENA_WIDTH 1 /* FLL_ENA */
-#define WM8400_TSHUT_ENA 0x4000 /* TSHUT_ENA */
-#define WM8400_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
-#define WM8400_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
-#define WM8400_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
-#define WM8400_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
-#define WM8400_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
-#define WM8400_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
-#define WM8400_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
-#define WM8400_OPCLK_ENA 0x0800 /* OPCLK_ENA */
-#define WM8400_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
-#define WM8400_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
-#define WM8400_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
-#define WM8400_AINL_ENA 0x0200 /* AINL_ENA */
-#define WM8400_AINL_ENA_MASK 0x0200 /* AINL_ENA */
-#define WM8400_AINL_ENA_SHIFT 9 /* AINL_ENA */
-#define WM8400_AINL_ENA_WIDTH 1 /* AINL_ENA */
-#define WM8400_AINR_ENA 0x0100 /* AINR_ENA */
-#define WM8400_AINR_ENA_MASK 0x0100 /* AINR_ENA */
-#define WM8400_AINR_ENA_SHIFT 8 /* AINR_ENA */
-#define WM8400_AINR_ENA_WIDTH 1 /* AINR_ENA */
-#define WM8400_LIN34_ENA 0x0080 /* LIN34_ENA */
-#define WM8400_LIN34_ENA_MASK 0x0080 /* LIN34_ENA */
-#define WM8400_LIN34_ENA_SHIFT 7 /* LIN34_ENA */
-#define WM8400_LIN34_ENA_WIDTH 1 /* LIN34_ENA */
-#define WM8400_LIN12_ENA 0x0040 /* LIN12_ENA */
-#define WM8400_LIN12_ENA_MASK 0x0040 /* LIN12_ENA */
-#define WM8400_LIN12_ENA_SHIFT 6 /* LIN12_ENA */
-#define WM8400_LIN12_ENA_WIDTH 1 /* LIN12_ENA */
-#define WM8400_RIN34_ENA 0x0020 /* RIN34_ENA */
-#define WM8400_RIN34_ENA_MASK 0x0020 /* RIN34_ENA */
-#define WM8400_RIN34_ENA_SHIFT 5 /* RIN34_ENA */
-#define WM8400_RIN34_ENA_WIDTH 1 /* RIN34_ENA */
-#define WM8400_RIN12_ENA 0x0010 /* RIN12_ENA */
-#define WM8400_RIN12_ENA_MASK 0x0010 /* RIN12_ENA */
-#define WM8400_RIN12_ENA_SHIFT 4 /* RIN12_ENA */
-#define WM8400_RIN12_ENA_WIDTH 1 /* RIN12_ENA */
-#define WM8400_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8400_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
-#define WM8400_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
-#define WM8400_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8400_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8400_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
-#define WM8400_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
-#define WM8400_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-
-/*
- * R4 (0x04) - Power Management (3)
- */
-#define WM8400_LON_ENA 0x2000 /* LON_ENA */
-#define WM8400_LON_ENA_MASK 0x2000 /* LON_ENA */
-#define WM8400_LON_ENA_SHIFT 13 /* LON_ENA */
-#define WM8400_LON_ENA_WIDTH 1 /* LON_ENA */
-#define WM8400_LOP_ENA 0x1000 /* LOP_ENA */
-#define WM8400_LOP_ENA_MASK 0x1000 /* LOP_ENA */
-#define WM8400_LOP_ENA_SHIFT 12 /* LOP_ENA */
-#define WM8400_LOP_ENA_WIDTH 1 /* LOP_ENA */
-#define WM8400_RON_ENA 0x0800 /* RON_ENA */
-#define WM8400_RON_ENA_MASK 0x0800 /* RON_ENA */
-#define WM8400_RON_ENA_SHIFT 11 /* RON_ENA */
-#define WM8400_RON_ENA_WIDTH 1 /* RON_ENA */
-#define WM8400_ROP_ENA 0x0400 /* ROP_ENA */
-#define WM8400_ROP_ENA_MASK 0x0400 /* ROP_ENA */
-#define WM8400_ROP_ENA_SHIFT 10 /* ROP_ENA */
-#define WM8400_ROP_ENA_WIDTH 1 /* ROP_ENA */
-#define WM8400_LOPGA_ENA 0x0080 /* LOPGA_ENA */
-#define WM8400_LOPGA_ENA_MASK 0x0080 /* LOPGA_ENA */
-#define WM8400_LOPGA_ENA_SHIFT 7 /* LOPGA_ENA */
-#define WM8400_LOPGA_ENA_WIDTH 1 /* LOPGA_ENA */
-#define WM8400_ROPGA_ENA 0x0040 /* ROPGA_ENA */
-#define WM8400_ROPGA_ENA_MASK 0x0040 /* ROPGA_ENA */
-#define WM8400_ROPGA_ENA_SHIFT 6 /* ROPGA_ENA */
-#define WM8400_ROPGA_ENA_WIDTH 1 /* ROPGA_ENA */
-#define WM8400_LOMIX_ENA 0x0020 /* LOMIX_ENA */
-#define WM8400_LOMIX_ENA_MASK 0x0020 /* LOMIX_ENA */
-#define WM8400_LOMIX_ENA_SHIFT 5 /* LOMIX_ENA */
-#define WM8400_LOMIX_ENA_WIDTH 1 /* LOMIX_ENA */
-#define WM8400_ROMIX_ENA 0x0010 /* ROMIX_ENA */
-#define WM8400_ROMIX_ENA_MASK 0x0010 /* ROMIX_ENA */
-#define WM8400_ROMIX_ENA_SHIFT 4 /* ROMIX_ENA */
-#define WM8400_ROMIX_ENA_WIDTH 1 /* ROMIX_ENA */
-#define WM8400_DACL_ENA 0x0002 /* DACL_ENA */
-#define WM8400_DACL_ENA_MASK 0x0002 /* DACL_ENA */
-#define WM8400_DACL_ENA_SHIFT 1 /* DACL_ENA */
-#define WM8400_DACL_ENA_WIDTH 1 /* DACL_ENA */
-#define WM8400_DACR_ENA 0x0001 /* DACR_ENA */
-#define WM8400_DACR_ENA_MASK 0x0001 /* DACR_ENA */
-#define WM8400_DACR_ENA_SHIFT 0 /* DACR_ENA */
-#define WM8400_DACR_ENA_WIDTH 1 /* DACR_ENA */
-
-/*
- * R5 (0x05) - Audio Interface (1)
- */
-#define WM8400_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
-#define WM8400_AIFADCL_SRC_MASK 0x8000 /* AIFADCL_SRC */
-#define WM8400_AIFADCL_SRC_SHIFT 15 /* AIFADCL_SRC */
-#define WM8400_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
-#define WM8400_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
-#define WM8400_AIFADCR_SRC_MASK 0x4000 /* AIFADCR_SRC */
-#define WM8400_AIFADCR_SRC_SHIFT 14 /* AIFADCR_SRC */
-#define WM8400_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
-#define WM8400_AIFADC_TDM 0x2000 /* AIFADC_TDM */
-#define WM8400_AIFADC_TDM_MASK 0x2000 /* AIFADC_TDM */
-#define WM8400_AIFADC_TDM_SHIFT 13 /* AIFADC_TDM */
-#define WM8400_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
-#define WM8400_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
-#define WM8400_AIFADC_TDM_CHAN_MASK 0x1000 /* AIFADC_TDM_CHAN */
-#define WM8400_AIFADC_TDM_CHAN_SHIFT 12 /* AIFADC_TDM_CHAN */
-#define WM8400_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
-#define WM8400_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
-#define WM8400_AIF_BCLK_INV_MASK 0x0100 /* AIF_BCLK_INV */
-#define WM8400_AIF_BCLK_INV_SHIFT 8 /* AIF_BCLK_INV */
-#define WM8400_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
-#define WM8400_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
-#define WM8400_AIF_LRCLK_INV_MASK 0x0080 /* AIF_LRCLK_INV */
-#define WM8400_AIF_LRCLK_INV_SHIFT 7 /* AIF_LRCLK_INV */
-#define WM8400_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
-#define WM8400_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
-#define WM8400_AIF_WL_SHIFT 5 /* AIF_WL - [6:5] */
-#define WM8400_AIF_WL_WIDTH 2 /* AIF_WL - [6:5] */
-#define WM8400_AIF_WL_16BITS (0 << 5)
-#define WM8400_AIF_WL_20BITS (1 << 5)
-#define WM8400_AIF_WL_24BITS (2 << 5)
-#define WM8400_AIF_WL_32BITS (3 << 5)
-#define WM8400_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
-#define WM8400_AIF_FMT_SHIFT 3 /* AIF_FMT - [4:3] */
-#define WM8400_AIF_FMT_WIDTH 2 /* AIF_FMT - [4:3] */
-#define WM8400_AIF_FMT_RIGHTJ (0 << 3)
-#define WM8400_AIF_FMT_LEFTJ (1 << 3)
-#define WM8400_AIF_FMT_I2S (2 << 3)
-#define WM8400_AIF_FMT_DSP (3 << 3)
-
-/*
- * R6 (0x06) - Audio Interface (2)
- */
-#define WM8400_DACL_SRC 0x8000 /* DACL_SRC */
-#define WM8400_DACL_SRC_MASK 0x8000 /* DACL_SRC */
-#define WM8400_DACL_SRC_SHIFT 15 /* DACL_SRC */
-#define WM8400_DACL_SRC_WIDTH 1 /* DACL_SRC */
-#define WM8400_DACR_SRC 0x4000 /* DACR_SRC */
-#define WM8400_DACR_SRC_MASK 0x4000 /* DACR_SRC */
-#define WM8400_DACR_SRC_SHIFT 14 /* DACR_SRC */
-#define WM8400_DACR_SRC_WIDTH 1 /* DACR_SRC */
-#define WM8400_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
-#define WM8400_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
-#define WM8400_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
-#define WM8400_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
-#define WM8400_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8400_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8400_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
-#define WM8400_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
-#define WM8400_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
-#define WM8400_DAC_BOOST_SHIFT 10 /* DAC_BOOST - [11:10] */
-#define WM8400_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [11:10] */
-#define WM8400_DAC_COMP 0x0010 /* DAC_COMP */
-#define WM8400_DAC_COMP_MASK 0x0010 /* DAC_COMP */
-#define WM8400_DAC_COMP_SHIFT 4 /* DAC_COMP */
-#define WM8400_DAC_COMP_WIDTH 1 /* DAC_COMP */
-#define WM8400_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
-#define WM8400_DAC_COMPMODE_MASK 0x0008 /* DAC_COMPMODE */
-#define WM8400_DAC_COMPMODE_SHIFT 3 /* DAC_COMPMODE */
-#define WM8400_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
-#define WM8400_ADC_COMP 0x0004 /* ADC_COMP */
-#define WM8400_ADC_COMP_MASK 0x0004 /* ADC_COMP */
-#define WM8400_ADC_COMP_SHIFT 2 /* ADC_COMP */
-#define WM8400_ADC_COMP_WIDTH 1 /* ADC_COMP */
-#define WM8400_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
-#define WM8400_ADC_COMPMODE_MASK 0x0002 /* ADC_COMPMODE */
-#define WM8400_ADC_COMPMODE_SHIFT 1 /* ADC_COMPMODE */
-#define WM8400_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
-#define WM8400_LOOPBACK 0x0001 /* LOOPBACK */
-#define WM8400_LOOPBACK_MASK 0x0001 /* LOOPBACK */
-#define WM8400_LOOPBACK_SHIFT 0 /* LOOPBACK */
-#define WM8400_LOOPBACK_WIDTH 1 /* LOOPBACK */
-
-/*
- * R7 (0x07) - Clocking (1)
- */
-#define WM8400_TOCLK_RATE 0x8000 /* TOCLK_RATE */
-#define WM8400_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */
-#define WM8400_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */
-#define WM8400_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
-#define WM8400_TOCLK_ENA 0x4000 /* TOCLK_ENA */
-#define WM8400_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */
-#define WM8400_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */
-#define WM8400_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-#define WM8400_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */
-#define WM8400_OPCLKDIV_SHIFT 9 /* OPCLKDIV - [12:9] */
-#define WM8400_OPCLKDIV_WIDTH 4 /* OPCLKDIV - [12:9] */
-#define WM8400_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
-#define WM8400_DCLKDIV_SHIFT 6 /* DCLKDIV - [8:6] */
-#define WM8400_DCLKDIV_WIDTH 3 /* DCLKDIV - [8:6] */
-#define WM8400_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
-#define WM8400_BCLK_DIV_SHIFT 1 /* BCLK_DIV - [4:1] */
-#define WM8400_BCLK_DIV_WIDTH 4 /* BCLK_DIV - [4:1] */
-
-/*
- * R8 (0x08) - Clocking (2)
- */
-#define WM8400_MCLK_SRC 0x8000 /* MCLK_SRC */
-#define WM8400_MCLK_SRC_MASK 0x8000 /* MCLK_SRC */
-#define WM8400_MCLK_SRC_SHIFT 15 /* MCLK_SRC */
-#define WM8400_MCLK_SRC_WIDTH 1 /* MCLK_SRC */
-#define WM8400_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
-#define WM8400_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
-#define WM8400_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
-#define WM8400_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
-#define WM8400_CLK_FORCE 0x2000 /* CLK_FORCE */
-#define WM8400_CLK_FORCE_MASK 0x2000 /* CLK_FORCE */
-#define WM8400_CLK_FORCE_SHIFT 13 /* CLK_FORCE */
-#define WM8400_CLK_FORCE_WIDTH 1 /* CLK_FORCE */
-#define WM8400_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */
-#define WM8400_MCLK_DIV_SHIFT 11 /* MCLK_DIV - [12:11] */
-#define WM8400_MCLK_DIV_WIDTH 2 /* MCLK_DIV - [12:11] */
-#define WM8400_MCLK_INV 0x0400 /* MCLK_INV */
-#define WM8400_MCLK_INV_MASK 0x0400 /* MCLK_INV */
-#define WM8400_MCLK_INV_SHIFT 10 /* MCLK_INV */
-#define WM8400_MCLK_INV_WIDTH 1 /* MCLK_INV */
-#define WM8400_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV - [7:5] */
-#define WM8400_ADC_CLKDIV_SHIFT 5 /* ADC_CLKDIV - [7:5] */
-#define WM8400_ADC_CLKDIV_WIDTH 3 /* ADC_CLKDIV - [7:5] */
-#define WM8400_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */
-#define WM8400_DAC_CLKDIV_SHIFT 2 /* DAC_CLKDIV - [4:2] */
-#define WM8400_DAC_CLKDIV_WIDTH 3 /* DAC_CLKDIV - [4:2] */
-
-/*
- * R9 (0x09) - Audio Interface (3)
- */
-#define WM8400_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
-#define WM8400_AIF_MSTR1_MASK 0x8000 /* AIF_MSTR1 */
-#define WM8400_AIF_MSTR1_SHIFT 15 /* AIF_MSTR1 */
-#define WM8400_AIF_MSTR1_WIDTH 1 /* AIF_MSTR1 */
-#define WM8400_AIF_MSTR2 0x4000 /* AIF_MSTR2 */
-#define WM8400_AIF_MSTR2_MASK 0x4000 /* AIF_MSTR2 */
-#define WM8400_AIF_MSTR2_SHIFT 14 /* AIF_MSTR2 */
-#define WM8400_AIF_MSTR2_WIDTH 1 /* AIF_MSTR2 */
-#define WM8400_AIF_SEL 0x2000 /* AIF_SEL */
-#define WM8400_AIF_SEL_MASK 0x2000 /* AIF_SEL */
-#define WM8400_AIF_SEL_SHIFT 13 /* AIF_SEL */
-#define WM8400_AIF_SEL_WIDTH 1 /* AIF_SEL */
-#define WM8400_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */
-#define WM8400_ADCLRC_DIR_MASK 0x0800 /* ADCLRC_DIR */
-#define WM8400_ADCLRC_DIR_SHIFT 11 /* ADCLRC_DIR */
-#define WM8400_ADCLRC_DIR_WIDTH 1 /* ADCLRC_DIR */
-#define WM8400_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE - [10:0] */
-#define WM8400_ADCLRC_RATE_SHIFT 0 /* ADCLRC_RATE - [10:0] */
-#define WM8400_ADCLRC_RATE_WIDTH 11 /* ADCLRC_RATE - [10:0] */
-
-/*
- * R10 (0x0A) - Audio Interface (4)
- */
-#define WM8400_ALRCGPIO1 0x8000 /* ALRCGPIO1 */
-#define WM8400_ALRCGPIO1_MASK 0x8000 /* ALRCGPIO1 */
-#define WM8400_ALRCGPIO1_SHIFT 15 /* ALRCGPIO1 */
-#define WM8400_ALRCGPIO1_WIDTH 1 /* ALRCGPIO1 */
-#define WM8400_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */
-#define WM8400_ALRCBGPIO6_MASK 0x4000 /* ALRCBGPIO6 */
-#define WM8400_ALRCBGPIO6_SHIFT 14 /* ALRCBGPIO6 */
-#define WM8400_ALRCBGPIO6_WIDTH 1 /* ALRCBGPIO6 */
-#define WM8400_AIF_TRIS 0x2000 /* AIF_TRIS */
-#define WM8400_AIF_TRIS_MASK 0x2000 /* AIF_TRIS */
-#define WM8400_AIF_TRIS_SHIFT 13 /* AIF_TRIS */
-#define WM8400_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
-#define WM8400_DACLRC_DIR 0x0800 /* DACLRC_DIR */
-#define WM8400_DACLRC_DIR_MASK 0x0800 /* DACLRC_DIR */
-#define WM8400_DACLRC_DIR_SHIFT 11 /* DACLRC_DIR */
-#define WM8400_DACLRC_DIR_WIDTH 1 /* DACLRC_DIR */
-#define WM8400_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE - [10:0] */
-#define WM8400_DACLRC_RATE_SHIFT 0 /* DACLRC_RATE - [10:0] */
-#define WM8400_DACLRC_RATE_WIDTH 11 /* DACLRC_RATE - [10:0] */
-
-/*
- * R11 (0x0B) - DAC CTRL
- */
-#define WM8400_DAC_SDMCLK_RATE 0x2000 /* DAC_SDMCLK_RATE */
-#define WM8400_DAC_SDMCLK_RATE_MASK 0x2000 /* DAC_SDMCLK_RATE */
-#define WM8400_DAC_SDMCLK_RATE_SHIFT 13 /* DAC_SDMCLK_RATE */
-#define WM8400_DAC_SDMCLK_RATE_WIDTH 1 /* DAC_SDMCLK_RATE */
-#define WM8400_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */
-#define WM8400_AIF_LRCLKRATE_MASK 0x0400 /* AIF_LRCLKRATE */
-#define WM8400_AIF_LRCLKRATE_SHIFT 10 /* AIF_LRCLKRATE */
-#define WM8400_AIF_LRCLKRATE_WIDTH 1 /* AIF_LRCLKRATE */
-#define WM8400_DAC_MONO 0x0200 /* DAC_MONO */
-#define WM8400_DAC_MONO_MASK 0x0200 /* DAC_MONO */
-#define WM8400_DAC_MONO_SHIFT 9 /* DAC_MONO */
-#define WM8400_DAC_MONO_WIDTH 1 /* DAC_MONO */
-#define WM8400_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
-#define WM8400_DAC_SB_FILT_MASK 0x0100 /* DAC_SB_FILT */
-#define WM8400_DAC_SB_FILT_SHIFT 8 /* DAC_SB_FILT */
-#define WM8400_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
-#define WM8400_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
-#define WM8400_DAC_MUTERATE_MASK 0x0080 /* DAC_MUTERATE */
-#define WM8400_DAC_MUTERATE_SHIFT 7 /* DAC_MUTERATE */
-#define WM8400_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-#define WM8400_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */
-#define WM8400_DAC_MUTEMODE_MASK 0x0040 /* DAC_MUTEMODE */
-#define WM8400_DAC_MUTEMODE_SHIFT 6 /* DAC_MUTEMODE */
-#define WM8400_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */
-#define WM8400_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */
-#define WM8400_DEEMP_SHIFT 4 /* DEEMP - [5:4] */
-#define WM8400_DEEMP_WIDTH 2 /* DEEMP - [5:4] */
-#define WM8400_DAC_MUTE 0x0004 /* DAC_MUTE */
-#define WM8400_DAC_MUTE_MASK 0x0004 /* DAC_MUTE */
-#define WM8400_DAC_MUTE_SHIFT 2 /* DAC_MUTE */
-#define WM8400_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
-#define WM8400_DACL_DATINV 0x0002 /* DACL_DATINV */
-#define WM8400_DACL_DATINV_MASK 0x0002 /* DACL_DATINV */
-#define WM8400_DACL_DATINV_SHIFT 1 /* DACL_DATINV */
-#define WM8400_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
-#define WM8400_DACR_DATINV 0x0001 /* DACR_DATINV */
-#define WM8400_DACR_DATINV_MASK 0x0001 /* DACR_DATINV */
-#define WM8400_DACR_DATINV_SHIFT 0 /* DACR_DATINV */
-#define WM8400_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
-
-/*
- * R12 (0x0C) - Left DAC Digital Volume
- */
-#define WM8400_DAC_VU 0x0100 /* DAC_VU */
-#define WM8400_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8400_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8400_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8400_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
-#define WM8400_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
-#define WM8400_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
-
-/*
- * R13 (0x0D) - Right DAC Digital Volume
- */
-#define WM8400_DAC_VU 0x0100 /* DAC_VU */
-#define WM8400_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8400_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8400_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8400_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
-#define WM8400_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
-#define WM8400_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
-
-/*
- * R14 (0x0E) - Digital Side Tone
- */
-#define WM8400_ADCL_DAC_SVOL_MASK 0x1E00 /* ADCL_DAC_SVOL - [12:9] */
-#define WM8400_ADCL_DAC_SVOL_SHIFT 9 /* ADCL_DAC_SVOL - [12:9] */
-#define WM8400_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [12:9] */
-#define WM8400_ADCR_DAC_SVOL_MASK 0x01E0 /* ADCR_DAC_SVOL - [8:5] */
-#define WM8400_ADCR_DAC_SVOL_SHIFT 5 /* ADCR_DAC_SVOL - [8:5] */
-#define WM8400_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [8:5] */
-#define WM8400_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
-#define WM8400_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
-#define WM8400_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
-#define WM8400_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
-#define WM8400_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
-#define WM8400_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
-
-/*
- * R15 (0x0F) - ADC CTRL
- */
-#define WM8400_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */
-#define WM8400_ADC_HPF_ENA_MASK 0x0100 /* ADC_HPF_ENA */
-#define WM8400_ADC_HPF_ENA_SHIFT 8 /* ADC_HPF_ENA */
-#define WM8400_ADC_HPF_ENA_WIDTH 1 /* ADC_HPF_ENA */
-#define WM8400_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
-#define WM8400_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
-#define WM8400_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
-#define WM8400_ADCL_DATINV 0x0002 /* ADCL_DATINV */
-#define WM8400_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
-#define WM8400_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
-#define WM8400_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
-#define WM8400_ADCR_DATINV 0x0001 /* ADCR_DATINV */
-#define WM8400_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
-#define WM8400_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
-#define WM8400_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
-
-/*
- * R16 (0x10) - Left ADC Digital Volume
- */
-#define WM8400_ADC_VU 0x0100 /* ADC_VU */
-#define WM8400_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8400_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8400_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8400_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
-#define WM8400_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
-#define WM8400_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
-
-/*
- * R17 (0x11) - Right ADC Digital Volume
- */
-#define WM8400_ADC_VU 0x0100 /* ADC_VU */
-#define WM8400_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8400_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8400_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8400_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
-#define WM8400_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
-#define WM8400_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
-
-/*
- * R24 (0x18) - Left Line Input 1&2 Volume
- */
-#define WM8400_IPVU 0x0100 /* IPVU */
-#define WM8400_IPVU_MASK 0x0100 /* IPVU */
-#define WM8400_IPVU_SHIFT 8 /* IPVU */
-#define WM8400_IPVU_WIDTH 1 /* IPVU */
-#define WM8400_LI12MUTE 0x0080 /* LI12MUTE */
-#define WM8400_LI12MUTE_MASK 0x0080 /* LI12MUTE */
-#define WM8400_LI12MUTE_SHIFT 7 /* LI12MUTE */
-#define WM8400_LI12MUTE_WIDTH 1 /* LI12MUTE */
-#define WM8400_LI12ZC 0x0040 /* LI12ZC */
-#define WM8400_LI12ZC_MASK 0x0040 /* LI12ZC */
-#define WM8400_LI12ZC_SHIFT 6 /* LI12ZC */
-#define WM8400_LI12ZC_WIDTH 1 /* LI12ZC */
-#define WM8400_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */
-#define WM8400_LIN12VOL_SHIFT 0 /* LIN12VOL - [4:0] */
-#define WM8400_LIN12VOL_WIDTH 5 /* LIN12VOL - [4:0] */
-
-/*
- * R25 (0x19) - Left Line Input 3&4 Volume
- */
-#define WM8400_IPVU 0x0100 /* IPVU */
-#define WM8400_IPVU_MASK 0x0100 /* IPVU */
-#define WM8400_IPVU_SHIFT 8 /* IPVU */
-#define WM8400_IPVU_WIDTH 1 /* IPVU */
-#define WM8400_LI34MUTE 0x0080 /* LI34MUTE */
-#define WM8400_LI34MUTE_MASK 0x0080 /* LI34MUTE */
-#define WM8400_LI34MUTE_SHIFT 7 /* LI34MUTE */
-#define WM8400_LI34MUTE_WIDTH 1 /* LI34MUTE */
-#define WM8400_LI34ZC 0x0040 /* LI34ZC */
-#define WM8400_LI34ZC_MASK 0x0040 /* LI34ZC */
-#define WM8400_LI34ZC_SHIFT 6 /* LI34ZC */
-#define WM8400_LI34ZC_WIDTH 1 /* LI34ZC */
-#define WM8400_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */
-#define WM8400_LIN34VOL_SHIFT 0 /* LIN34VOL - [4:0] */
-#define WM8400_LIN34VOL_WIDTH 5 /* LIN34VOL - [4:0] */
-
-/*
- * R26 (0x1A) - Right Line Input 1&2 Volume
- */
-#define WM8400_IPVU 0x0100 /* IPVU */
-#define WM8400_IPVU_MASK 0x0100 /* IPVU */
-#define WM8400_IPVU_SHIFT 8 /* IPVU */
-#define WM8400_IPVU_WIDTH 1 /* IPVU */
-#define WM8400_RI12MUTE 0x0080 /* RI12MUTE */
-#define WM8400_RI12MUTE_MASK 0x0080 /* RI12MUTE */
-#define WM8400_RI12MUTE_SHIFT 7 /* RI12MUTE */
-#define WM8400_RI12MUTE_WIDTH 1 /* RI12MUTE */
-#define WM8400_RI12ZC 0x0040 /* RI12ZC */
-#define WM8400_RI12ZC_MASK 0x0040 /* RI12ZC */
-#define WM8400_RI12ZC_SHIFT 6 /* RI12ZC */
-#define WM8400_RI12ZC_WIDTH 1 /* RI12ZC */
-#define WM8400_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */
-#define WM8400_RIN12VOL_SHIFT 0 /* RIN12VOL - [4:0] */
-#define WM8400_RIN12VOL_WIDTH 5 /* RIN12VOL - [4:0] */
-
-/*
- * R27 (0x1B) - Right Line Input 3&4 Volume
- */
-#define WM8400_IPVU 0x0100 /* IPVU */
-#define WM8400_IPVU_MASK 0x0100 /* IPVU */
-#define WM8400_IPVU_SHIFT 8 /* IPVU */
-#define WM8400_IPVU_WIDTH 1 /* IPVU */
-#define WM8400_RI34MUTE 0x0080 /* RI34MUTE */
-#define WM8400_RI34MUTE_MASK 0x0080 /* RI34MUTE */
-#define WM8400_RI34MUTE_SHIFT 7 /* RI34MUTE */
-#define WM8400_RI34MUTE_WIDTH 1 /* RI34MUTE */
-#define WM8400_RI34ZC 0x0040 /* RI34ZC */
-#define WM8400_RI34ZC_MASK 0x0040 /* RI34ZC */
-#define WM8400_RI34ZC_SHIFT 6 /* RI34ZC */
-#define WM8400_RI34ZC_WIDTH 1 /* RI34ZC */
-#define WM8400_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */
-#define WM8400_RIN34VOL_SHIFT 0 /* RIN34VOL - [4:0] */
-#define WM8400_RIN34VOL_WIDTH 5 /* RIN34VOL - [4:0] */
-
-/*
- * R28 (0x1C) - Left Output Volume
- */
-#define WM8400_OPVU 0x0100 /* OPVU */
-#define WM8400_OPVU_MASK 0x0100 /* OPVU */
-#define WM8400_OPVU_SHIFT 8 /* OPVU */
-#define WM8400_OPVU_WIDTH 1 /* OPVU */
-#define WM8400_LOZC 0x0080 /* LOZC */
-#define WM8400_LOZC_MASK 0x0080 /* LOZC */
-#define WM8400_LOZC_SHIFT 7 /* LOZC */
-#define WM8400_LOZC_WIDTH 1 /* LOZC */
-#define WM8400_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
-#define WM8400_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */
-#define WM8400_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */
-
-/*
- * R29 (0x1D) - Right Output Volume
- */
-#define WM8400_OPVU 0x0100 /* OPVU */
-#define WM8400_OPVU_MASK 0x0100 /* OPVU */
-#define WM8400_OPVU_SHIFT 8 /* OPVU */
-#define WM8400_OPVU_WIDTH 1 /* OPVU */
-#define WM8400_ROZC 0x0080 /* ROZC */
-#define WM8400_ROZC_MASK 0x0080 /* ROZC */
-#define WM8400_ROZC_SHIFT 7 /* ROZC */
-#define WM8400_ROZC_WIDTH 1 /* ROZC */
-#define WM8400_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
-#define WM8400_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */
-#define WM8400_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */
-
-/*
- * R30 (0x1E) - Line Outputs Volume
- */
-#define WM8400_LONMUTE 0x0040 /* LONMUTE */
-#define WM8400_LONMUTE_MASK 0x0040 /* LONMUTE */
-#define WM8400_LONMUTE_SHIFT 6 /* LONMUTE */
-#define WM8400_LONMUTE_WIDTH 1 /* LONMUTE */
-#define WM8400_LOPMUTE 0x0020 /* LOPMUTE */
-#define WM8400_LOPMUTE_MASK 0x0020 /* LOPMUTE */
-#define WM8400_LOPMUTE_SHIFT 5 /* LOPMUTE */
-#define WM8400_LOPMUTE_WIDTH 1 /* LOPMUTE */
-#define WM8400_LOATTN 0x0010 /* LOATTN */
-#define WM8400_LOATTN_MASK 0x0010 /* LOATTN */
-#define WM8400_LOATTN_SHIFT 4 /* LOATTN */
-#define WM8400_LOATTN_WIDTH 1 /* LOATTN */
-#define WM8400_RONMUTE 0x0004 /* RONMUTE */
-#define WM8400_RONMUTE_MASK 0x0004 /* RONMUTE */
-#define WM8400_RONMUTE_SHIFT 2 /* RONMUTE */
-#define WM8400_RONMUTE_WIDTH 1 /* RONMUTE */
-#define WM8400_ROPMUTE 0x0002 /* ROPMUTE */
-#define WM8400_ROPMUTE_MASK 0x0002 /* ROPMUTE */
-#define WM8400_ROPMUTE_SHIFT 1 /* ROPMUTE */
-#define WM8400_ROPMUTE_WIDTH 1 /* ROPMUTE */
-#define WM8400_ROATTN 0x0001 /* ROATTN */
-#define WM8400_ROATTN_MASK 0x0001 /* ROATTN */
-#define WM8400_ROATTN_SHIFT 0 /* ROATTN */
-#define WM8400_ROATTN_WIDTH 1 /* ROATTN */
-
-/*
- * R31 (0x1F) - Out3/4 Volume
- */
-#define WM8400_OUT3MUTE 0x0020 /* OUT3MUTE */
-#define WM8400_OUT3MUTE_MASK 0x0020 /* OUT3MUTE */
-#define WM8400_OUT3MUTE_SHIFT 5 /* OUT3MUTE */
-#define WM8400_OUT3MUTE_WIDTH 1 /* OUT3MUTE */
-#define WM8400_OUT3ATTN 0x0010 /* OUT3ATTN */
-#define WM8400_OUT3ATTN_MASK 0x0010 /* OUT3ATTN */
-#define WM8400_OUT3ATTN_SHIFT 4 /* OUT3ATTN */
-#define WM8400_OUT3ATTN_WIDTH 1 /* OUT3ATTN */
-#define WM8400_OUT4MUTE 0x0002 /* OUT4MUTE */
-#define WM8400_OUT4MUTE_MASK 0x0002 /* OUT4MUTE */
-#define WM8400_OUT4MUTE_SHIFT 1 /* OUT4MUTE */
-#define WM8400_OUT4MUTE_WIDTH 1 /* OUT4MUTE */
-#define WM8400_OUT4ATTN 0x0001 /* OUT4ATTN */
-#define WM8400_OUT4ATTN_MASK 0x0001 /* OUT4ATTN */
-#define WM8400_OUT4ATTN_SHIFT 0 /* OUT4ATTN */
-#define WM8400_OUT4ATTN_WIDTH 1 /* OUT4ATTN */
-
-/*
- * R32 (0x20) - Left OPGA Volume
- */
-#define WM8400_OPVU 0x0100 /* OPVU */
-#define WM8400_OPVU_MASK 0x0100 /* OPVU */
-#define WM8400_OPVU_SHIFT 8 /* OPVU */
-#define WM8400_OPVU_WIDTH 1 /* OPVU */
-#define WM8400_LOPGAZC 0x0080 /* LOPGAZC */
-#define WM8400_LOPGAZC_MASK 0x0080 /* LOPGAZC */
-#define WM8400_LOPGAZC_SHIFT 7 /* LOPGAZC */
-#define WM8400_LOPGAZC_WIDTH 1 /* LOPGAZC */
-#define WM8400_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */
-#define WM8400_LOPGAVOL_SHIFT 0 /* LOPGAVOL - [6:0] */
-#define WM8400_LOPGAVOL_WIDTH 7 /* LOPGAVOL - [6:0] */
-
-/*
- * R33 (0x21) - Right OPGA Volume
- */
-#define WM8400_OPVU 0x0100 /* OPVU */
-#define WM8400_OPVU_MASK 0x0100 /* OPVU */
-#define WM8400_OPVU_SHIFT 8 /* OPVU */
-#define WM8400_OPVU_WIDTH 1 /* OPVU */
-#define WM8400_ROPGAZC 0x0080 /* ROPGAZC */
-#define WM8400_ROPGAZC_MASK 0x0080 /* ROPGAZC */
-#define WM8400_ROPGAZC_SHIFT 7 /* ROPGAZC */
-#define WM8400_ROPGAZC_WIDTH 1 /* ROPGAZC */
-#define WM8400_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */
-#define WM8400_ROPGAVOL_SHIFT 0 /* ROPGAVOL - [6:0] */
-#define WM8400_ROPGAVOL_WIDTH 7 /* ROPGAVOL - [6:0] */
-
-/*
- * R34 (0x22) - Speaker Volume
- */
-#define WM8400_SPKATTN_MASK 0x0003 /* SPKATTN - [1:0] */
-#define WM8400_SPKATTN_SHIFT 0 /* SPKATTN - [1:0] */
-#define WM8400_SPKATTN_WIDTH 2 /* SPKATTN - [1:0] */
-
-/*
- * R35 (0x23) - ClassD1
- */
-#define WM8400_CDMODE 0x0100 /* CDMODE */
-#define WM8400_CDMODE_MASK 0x0100 /* CDMODE */
-#define WM8400_CDMODE_SHIFT 8 /* CDMODE */
-#define WM8400_CDMODE_WIDTH 1 /* CDMODE */
-#define WM8400_CLASSD_CLK_SEL 0x0080 /* CLASSD_CLK_SEL */
-#define WM8400_CLASSD_CLK_SEL_MASK 0x0080 /* CLASSD_CLK_SEL */
-#define WM8400_CLASSD_CLK_SEL_SHIFT 7 /* CLASSD_CLK_SEL */
-#define WM8400_CLASSD_CLK_SEL_WIDTH 1 /* CLASSD_CLK_SEL */
-#define WM8400_CD_SRCTRL 0x0040 /* CD_SRCTRL */
-#define WM8400_CD_SRCTRL_MASK 0x0040 /* CD_SRCTRL */
-#define WM8400_CD_SRCTRL_SHIFT 6 /* CD_SRCTRL */
-#define WM8400_CD_SRCTRL_WIDTH 1 /* CD_SRCTRL */
-#define WM8400_SPKNOPOP 0x0020 /* SPKNOPOP */
-#define WM8400_SPKNOPOP_MASK 0x0020 /* SPKNOPOP */
-#define WM8400_SPKNOPOP_SHIFT 5 /* SPKNOPOP */
-#define WM8400_SPKNOPOP_WIDTH 1 /* SPKNOPOP */
-#define WM8400_DBLERATE 0x0010 /* DBLERATE */
-#define WM8400_DBLERATE_MASK 0x0010 /* DBLERATE */
-#define WM8400_DBLERATE_SHIFT 4 /* DBLERATE */
-#define WM8400_DBLERATE_WIDTH 1 /* DBLERATE */
-#define WM8400_LOOPTEST 0x0008 /* LOOPTEST */
-#define WM8400_LOOPTEST_MASK 0x0008 /* LOOPTEST */
-#define WM8400_LOOPTEST_SHIFT 3 /* LOOPTEST */
-#define WM8400_LOOPTEST_WIDTH 1 /* LOOPTEST */
-#define WM8400_HALFABBIAS 0x0004 /* HALFABBIAS */
-#define WM8400_HALFABBIAS_MASK 0x0004 /* HALFABBIAS */
-#define WM8400_HALFABBIAS_SHIFT 2 /* HALFABBIAS */
-#define WM8400_HALFABBIAS_WIDTH 1 /* HALFABBIAS */
-#define WM8400_TRIDEL_MASK 0x0003 /* TRIDEL - [1:0] */
-#define WM8400_TRIDEL_SHIFT 0 /* TRIDEL - [1:0] */
-#define WM8400_TRIDEL_WIDTH 2 /* TRIDEL - [1:0] */
-
-/*
- * R37 (0x25) - ClassD3
- */
-#define WM8400_DCGAIN_MASK 0x0038 /* DCGAIN - [5:3] */
-#define WM8400_DCGAIN_SHIFT 3 /* DCGAIN - [5:3] */
-#define WM8400_DCGAIN_WIDTH 3 /* DCGAIN - [5:3] */
-#define WM8400_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
-#define WM8400_ACGAIN_SHIFT 0 /* ACGAIN - [2:0] */
-#define WM8400_ACGAIN_WIDTH 3 /* ACGAIN - [2:0] */
-
-/*
- * R39 (0x27) - Input Mixer1
- */
-#define WM8400_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */
-#define WM8400_AINLMODE_SHIFT 2 /* AINLMODE - [3:2] */
-#define WM8400_AINLMODE_WIDTH 2 /* AINLMODE - [3:2] */
-#define WM8400_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */
-#define WM8400_AINRMODE_SHIFT 0 /* AINRMODE - [1:0] */
-#define WM8400_AINRMODE_WIDTH 2 /* AINRMODE - [1:0] */
-
-/*
- * R40 (0x28) - Input Mixer2
- */
-#define WM8400_LMP4 0x0080 /* LMP4 */
-#define WM8400_LMP4_MASK 0x0080 /* LMP4 */
-#define WM8400_LMP4_SHIFT 7 /* LMP4 */
-#define WM8400_LMP4_WIDTH 1 /* LMP4 */
-#define WM8400_LMN3 0x0040 /* LMN3 */
-#define WM8400_LMN3_MASK 0x0040 /* LMN3 */
-#define WM8400_LMN3_SHIFT 6 /* LMN3 */
-#define WM8400_LMN3_WIDTH 1 /* LMN3 */
-#define WM8400_LMP2 0x0020 /* LMP2 */
-#define WM8400_LMP2_MASK 0x0020 /* LMP2 */
-#define WM8400_LMP2_SHIFT 5 /* LMP2 */
-#define WM8400_LMP2_WIDTH 1 /* LMP2 */
-#define WM8400_LMN1 0x0010 /* LMN1 */
-#define WM8400_LMN1_MASK 0x0010 /* LMN1 */
-#define WM8400_LMN1_SHIFT 4 /* LMN1 */
-#define WM8400_LMN1_WIDTH 1 /* LMN1 */
-#define WM8400_RMP4 0x0008 /* RMP4 */
-#define WM8400_RMP4_MASK 0x0008 /* RMP4 */
-#define WM8400_RMP4_SHIFT 3 /* RMP4 */
-#define WM8400_RMP4_WIDTH 1 /* RMP4 */
-#define WM8400_RMN3 0x0004 /* RMN3 */
-#define WM8400_RMN3_MASK 0x0004 /* RMN3 */
-#define WM8400_RMN3_SHIFT 2 /* RMN3 */
-#define WM8400_RMN3_WIDTH 1 /* RMN3 */
-#define WM8400_RMP2 0x0002 /* RMP2 */
-#define WM8400_RMP2_MASK 0x0002 /* RMP2 */
-#define WM8400_RMP2_SHIFT 1 /* RMP2 */
-#define WM8400_RMP2_WIDTH 1 /* RMP2 */
-#define WM8400_RMN1 0x0001 /* RMN1 */
-#define WM8400_RMN1_MASK 0x0001 /* RMN1 */
-#define WM8400_RMN1_SHIFT 0 /* RMN1 */
-#define WM8400_RMN1_WIDTH 1 /* RMN1 */
-
-/*
- * R41 (0x29) - Input Mixer3
- */
-#define WM8400_L34MNB 0x0100 /* L34MNB */
-#define WM8400_L34MNB_MASK 0x0100 /* L34MNB */
-#define WM8400_L34MNB_SHIFT 8 /* L34MNB */
-#define WM8400_L34MNB_WIDTH 1 /* L34MNB */
-#define WM8400_L34MNBST 0x0080 /* L34MNBST */
-#define WM8400_L34MNBST_MASK 0x0080 /* L34MNBST */
-#define WM8400_L34MNBST_SHIFT 7 /* L34MNBST */
-#define WM8400_L34MNBST_WIDTH 1 /* L34MNBST */
-#define WM8400_L12MNB 0x0020 /* L12MNB */
-#define WM8400_L12MNB_MASK 0x0020 /* L12MNB */
-#define WM8400_L12MNB_SHIFT 5 /* L12MNB */
-#define WM8400_L12MNB_WIDTH 1 /* L12MNB */
-#define WM8400_L12MNBST 0x0010 /* L12MNBST */
-#define WM8400_L12MNBST_MASK 0x0010 /* L12MNBST */
-#define WM8400_L12MNBST_SHIFT 4 /* L12MNBST */
-#define WM8400_L12MNBST_WIDTH 1 /* L12MNBST */
-#define WM8400_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */
-#define WM8400_LDBVOL_SHIFT 0 /* LDBVOL - [2:0] */
-#define WM8400_LDBVOL_WIDTH 3 /* LDBVOL - [2:0] */
-
-/*
- * R42 (0x2A) - Input Mixer4
- */
-#define WM8400_R34MNB 0x0100 /* R34MNB */
-#define WM8400_R34MNB_MASK 0x0100 /* R34MNB */
-#define WM8400_R34MNB_SHIFT 8 /* R34MNB */
-#define WM8400_R34MNB_WIDTH 1 /* R34MNB */
-#define WM8400_R34MNBST 0x0080 /* R34MNBST */
-#define WM8400_R34MNBST_MASK 0x0080 /* R34MNBST */
-#define WM8400_R34MNBST_SHIFT 7 /* R34MNBST */
-#define WM8400_R34MNBST_WIDTH 1 /* R34MNBST */
-#define WM8400_R12MNB 0x0020 /* R12MNB */
-#define WM8400_R12MNB_MASK 0x0020 /* R12MNB */
-#define WM8400_R12MNB_SHIFT 5 /* R12MNB */
-#define WM8400_R12MNB_WIDTH 1 /* R12MNB */
-#define WM8400_R12MNBST 0x0010 /* R12MNBST */
-#define WM8400_R12MNBST_MASK 0x0010 /* R12MNBST */
-#define WM8400_R12MNBST_SHIFT 4 /* R12MNBST */
-#define WM8400_R12MNBST_WIDTH 1 /* R12MNBST */
-#define WM8400_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */
-#define WM8400_RDBVOL_SHIFT 0 /* RDBVOL - [2:0] */
-#define WM8400_RDBVOL_WIDTH 3 /* RDBVOL - [2:0] */
-
-/*
- * R43 (0x2B) - Input Mixer5
- */
-#define WM8400_LI2BVOL_MASK 0x01C0 /* LI2BVOL - [8:6] */
-#define WM8400_LI2BVOL_SHIFT 6 /* LI2BVOL - [8:6] */
-#define WM8400_LI2BVOL_WIDTH 3 /* LI2BVOL - [8:6] */
-#define WM8400_LR4BVOL_MASK 0x0038 /* LR4BVOL - [5:3] */
-#define WM8400_LR4BVOL_SHIFT 3 /* LR4BVOL - [5:3] */
-#define WM8400_LR4BVOL_WIDTH 3 /* LR4BVOL - [5:3] */
-#define WM8400_LL4BVOL_MASK 0x0007 /* LL4BVOL - [2:0] */
-#define WM8400_LL4BVOL_SHIFT 0 /* LL4BVOL - [2:0] */
-#define WM8400_LL4BVOL_WIDTH 3 /* LL4BVOL - [2:0] */
-
-/*
- * R44 (0x2C) - Input Mixer6
- */
-#define WM8400_RI2BVOL_MASK 0x01C0 /* RI2BVOL - [8:6] */
-#define WM8400_RI2BVOL_SHIFT 6 /* RI2BVOL - [8:6] */
-#define WM8400_RI2BVOL_WIDTH 3 /* RI2BVOL - [8:6] */
-#define WM8400_RL4BVOL_MASK 0x0038 /* RL4BVOL - [5:3] */
-#define WM8400_RL4BVOL_SHIFT 3 /* RL4BVOL - [5:3] */
-#define WM8400_RL4BVOL_WIDTH 3 /* RL4BVOL - [5:3] */
-#define WM8400_RR4BVOL_MASK 0x0007 /* RR4BVOL - [2:0] */
-#define WM8400_RR4BVOL_SHIFT 0 /* RR4BVOL - [2:0] */
-#define WM8400_RR4BVOL_WIDTH 3 /* RR4BVOL - [2:0] */
-
-/*
- * R45 (0x2D) - Output Mixer1
- */
-#define WM8400_LRBLO 0x0080 /* LRBLO */
-#define WM8400_LRBLO_MASK 0x0080 /* LRBLO */
-#define WM8400_LRBLO_SHIFT 7 /* LRBLO */
-#define WM8400_LRBLO_WIDTH 1 /* LRBLO */
-#define WM8400_LLBLO 0x0040 /* LLBLO */
-#define WM8400_LLBLO_MASK 0x0040 /* LLBLO */
-#define WM8400_LLBLO_SHIFT 6 /* LLBLO */
-#define WM8400_LLBLO_WIDTH 1 /* LLBLO */
-#define WM8400_LRI3LO 0x0020 /* LRI3LO */
-#define WM8400_LRI3LO_MASK 0x0020 /* LRI3LO */
-#define WM8400_LRI3LO_SHIFT 5 /* LRI3LO */
-#define WM8400_LRI3LO_WIDTH 1 /* LRI3LO */
-#define WM8400_LLI3LO 0x0010 /* LLI3LO */
-#define WM8400_LLI3LO_MASK 0x0010 /* LLI3LO */
-#define WM8400_LLI3LO_SHIFT 4 /* LLI3LO */
-#define WM8400_LLI3LO_WIDTH 1 /* LLI3LO */
-#define WM8400_LR12LO 0x0008 /* LR12LO */
-#define WM8400_LR12LO_MASK 0x0008 /* LR12LO */
-#define WM8400_LR12LO_SHIFT 3 /* LR12LO */
-#define WM8400_LR12LO_WIDTH 1 /* LR12LO */
-#define WM8400_LL12LO 0x0004 /* LL12LO */
-#define WM8400_LL12LO_MASK 0x0004 /* LL12LO */
-#define WM8400_LL12LO_SHIFT 2 /* LL12LO */
-#define WM8400_LL12LO_WIDTH 1 /* LL12LO */
-#define WM8400_LDLO 0x0001 /* LDLO */
-#define WM8400_LDLO_MASK 0x0001 /* LDLO */
-#define WM8400_LDLO_SHIFT 0 /* LDLO */
-#define WM8400_LDLO_WIDTH 1 /* LDLO */
-
-/*
- * R46 (0x2E) - Output Mixer2
- */
-#define WM8400_RLBRO 0x0080 /* RLBRO */
-#define WM8400_RLBRO_MASK 0x0080 /* RLBRO */
-#define WM8400_RLBRO_SHIFT 7 /* RLBRO */
-#define WM8400_RLBRO_WIDTH 1 /* RLBRO */
-#define WM8400_RRBRO 0x0040 /* RRBRO */
-#define WM8400_RRBRO_MASK 0x0040 /* RRBRO */
-#define WM8400_RRBRO_SHIFT 6 /* RRBRO */
-#define WM8400_RRBRO_WIDTH 1 /* RRBRO */
-#define WM8400_RLI3RO 0x0020 /* RLI3RO */
-#define WM8400_RLI3RO_MASK 0x0020 /* RLI3RO */
-#define WM8400_RLI3RO_SHIFT 5 /* RLI3RO */
-#define WM8400_RLI3RO_WIDTH 1 /* RLI3RO */
-#define WM8400_RRI3RO 0x0010 /* RRI3RO */
-#define WM8400_RRI3RO_MASK 0x0010 /* RRI3RO */
-#define WM8400_RRI3RO_SHIFT 4 /* RRI3RO */
-#define WM8400_RRI3RO_WIDTH 1 /* RRI3RO */
-#define WM8400_RL12RO 0x0008 /* RL12RO */
-#define WM8400_RL12RO_MASK 0x0008 /* RL12RO */
-#define WM8400_RL12RO_SHIFT 3 /* RL12RO */
-#define WM8400_RL12RO_WIDTH 1 /* RL12RO */
-#define WM8400_RR12RO 0x0004 /* RR12RO */
-#define WM8400_RR12RO_MASK 0x0004 /* RR12RO */
-#define WM8400_RR12RO_SHIFT 2 /* RR12RO */
-#define WM8400_RR12RO_WIDTH 1 /* RR12RO */
-#define WM8400_RDRO 0x0001 /* RDRO */
-#define WM8400_RDRO_MASK 0x0001 /* RDRO */
-#define WM8400_RDRO_SHIFT 0 /* RDRO */
-#define WM8400_RDRO_WIDTH 1 /* RDRO */
-
-/*
- * R47 (0x2F) - Output Mixer3
- */
-#define WM8400_LLI3LOVOL_MASK 0x01C0 /* LLI3LOVOL - [8:6] */
-#define WM8400_LLI3LOVOL_SHIFT 6 /* LLI3LOVOL - [8:6] */
-#define WM8400_LLI3LOVOL_WIDTH 3 /* LLI3LOVOL - [8:6] */
-#define WM8400_LR12LOVOL_MASK 0x0038 /* LR12LOVOL - [5:3] */
-#define WM8400_LR12LOVOL_SHIFT 3 /* LR12LOVOL - [5:3] */
-#define WM8400_LR12LOVOL_WIDTH 3 /* LR12LOVOL - [5:3] */
-#define WM8400_LL12LOVOL_MASK 0x0007 /* LL12LOVOL - [2:0] */
-#define WM8400_LL12LOVOL_SHIFT 0 /* LL12LOVOL - [2:0] */
-#define WM8400_LL12LOVOL_WIDTH 3 /* LL12LOVOL - [2:0] */
-
-/*
- * R48 (0x30) - Output Mixer4
- */
-#define WM8400_RRI3ROVOL_MASK 0x01C0 /* RRI3ROVOL - [8:6] */
-#define WM8400_RRI3ROVOL_SHIFT 6 /* RRI3ROVOL - [8:6] */
-#define WM8400_RRI3ROVOL_WIDTH 3 /* RRI3ROVOL - [8:6] */
-#define WM8400_RL12ROVOL_MASK 0x0038 /* RL12ROVOL - [5:3] */
-#define WM8400_RL12ROVOL_SHIFT 3 /* RL12ROVOL - [5:3] */
-#define WM8400_RL12ROVOL_WIDTH 3 /* RL12ROVOL - [5:3] */
-#define WM8400_RR12ROVOL_MASK 0x0007 /* RR12ROVOL - [2:0] */
-#define WM8400_RR12ROVOL_SHIFT 0 /* RR12ROVOL - [2:0] */
-#define WM8400_RR12ROVOL_WIDTH 3 /* RR12ROVOL - [2:0] */
-
-/*
- * R49 (0x31) - Output Mixer5
- */
-#define WM8400_LRI3LOVOL_MASK 0x01C0 /* LRI3LOVOL - [8:6] */
-#define WM8400_LRI3LOVOL_SHIFT 6 /* LRI3LOVOL - [8:6] */
-#define WM8400_LRI3LOVOL_WIDTH 3 /* LRI3LOVOL - [8:6] */
-#define WM8400_LRBLOVOL_MASK 0x0038 /* LRBLOVOL - [5:3] */
-#define WM8400_LRBLOVOL_SHIFT 3 /* LRBLOVOL - [5:3] */
-#define WM8400_LRBLOVOL_WIDTH 3 /* LRBLOVOL - [5:3] */
-#define WM8400_LLBLOVOL_MASK 0x0007 /* LLBLOVOL - [2:0] */
-#define WM8400_LLBLOVOL_SHIFT 0 /* LLBLOVOL - [2:0] */
-#define WM8400_LLBLOVOL_WIDTH 3 /* LLBLOVOL - [2:0] */
-
-/*
- * R50 (0x32) - Output Mixer6
- */
-#define WM8400_RLI3ROVOL_MASK 0x01C0 /* RLI3ROVOL - [8:6] */
-#define WM8400_RLI3ROVOL_SHIFT 6 /* RLI3ROVOL - [8:6] */
-#define WM8400_RLI3ROVOL_WIDTH 3 /* RLI3ROVOL - [8:6] */
-#define WM8400_RLBROVOL_MASK 0x0038 /* RLBROVOL - [5:3] */
-#define WM8400_RLBROVOL_SHIFT 3 /* RLBROVOL - [5:3] */
-#define WM8400_RLBROVOL_WIDTH 3 /* RLBROVOL - [5:3] */
-#define WM8400_RRBROVOL_MASK 0x0007 /* RRBROVOL - [2:0] */
-#define WM8400_RRBROVOL_SHIFT 0 /* RRBROVOL - [2:0] */
-#define WM8400_RRBROVOL_WIDTH 3 /* RRBROVOL - [2:0] */
-
-/*
- * R51 (0x33) - Out3/4 Mixer
- */
-#define WM8400_VSEL_MASK 0x0180 /* VSEL - [8:7] */
-#define WM8400_VSEL_SHIFT 7 /* VSEL - [8:7] */
-#define WM8400_VSEL_WIDTH 2 /* VSEL - [8:7] */
-#define WM8400_LI4O3 0x0020 /* LI4O3 */
-#define WM8400_LI4O3_MASK 0x0020 /* LI4O3 */
-#define WM8400_LI4O3_SHIFT 5 /* LI4O3 */
-#define WM8400_LI4O3_WIDTH 1 /* LI4O3 */
-#define WM8400_LPGAO3 0x0010 /* LPGAO3 */
-#define WM8400_LPGAO3_MASK 0x0010 /* LPGAO3 */
-#define WM8400_LPGAO3_SHIFT 4 /* LPGAO3 */
-#define WM8400_LPGAO3_WIDTH 1 /* LPGAO3 */
-#define WM8400_RI4O4 0x0002 /* RI4O4 */
-#define WM8400_RI4O4_MASK 0x0002 /* RI4O4 */
-#define WM8400_RI4O4_SHIFT 1 /* RI4O4 */
-#define WM8400_RI4O4_WIDTH 1 /* RI4O4 */
-#define WM8400_RPGAO4 0x0001 /* RPGAO4 */
-#define WM8400_RPGAO4_MASK 0x0001 /* RPGAO4 */
-#define WM8400_RPGAO4_SHIFT 0 /* RPGAO4 */
-#define WM8400_RPGAO4_WIDTH 1 /* RPGAO4 */
-
-/*
- * R52 (0x34) - Line Mixer1
- */
-#define WM8400_LLOPGALON 0x0040 /* LLOPGALON */
-#define WM8400_LLOPGALON_MASK 0x0040 /* LLOPGALON */
-#define WM8400_LLOPGALON_SHIFT 6 /* LLOPGALON */
-#define WM8400_LLOPGALON_WIDTH 1 /* LLOPGALON */
-#define WM8400_LROPGALON 0x0020 /* LROPGALON */
-#define WM8400_LROPGALON_MASK 0x0020 /* LROPGALON */
-#define WM8400_LROPGALON_SHIFT 5 /* LROPGALON */
-#define WM8400_LROPGALON_WIDTH 1 /* LROPGALON */
-#define WM8400_LOPLON 0x0010 /* LOPLON */
-#define WM8400_LOPLON_MASK 0x0010 /* LOPLON */
-#define WM8400_LOPLON_SHIFT 4 /* LOPLON */
-#define WM8400_LOPLON_WIDTH 1 /* LOPLON */
-#define WM8400_LR12LOP 0x0004 /* LR12LOP */
-#define WM8400_LR12LOP_MASK 0x0004 /* LR12LOP */
-#define WM8400_LR12LOP_SHIFT 2 /* LR12LOP */
-#define WM8400_LR12LOP_WIDTH 1 /* LR12LOP */
-#define WM8400_LL12LOP 0x0002 /* LL12LOP */
-#define WM8400_LL12LOP_MASK 0x0002 /* LL12LOP */
-#define WM8400_LL12LOP_SHIFT 1 /* LL12LOP */
-#define WM8400_LL12LOP_WIDTH 1 /* LL12LOP */
-#define WM8400_LLOPGALOP 0x0001 /* LLOPGALOP */
-#define WM8400_LLOPGALOP_MASK 0x0001 /* LLOPGALOP */
-#define WM8400_LLOPGALOP_SHIFT 0 /* LLOPGALOP */
-#define WM8400_LLOPGALOP_WIDTH 1 /* LLOPGALOP */
-
-/*
- * R53 (0x35) - Line Mixer2
- */
-#define WM8400_RROPGARON 0x0040 /* RROPGARON */
-#define WM8400_RROPGARON_MASK 0x0040 /* RROPGARON */
-#define WM8400_RROPGARON_SHIFT 6 /* RROPGARON */
-#define WM8400_RROPGARON_WIDTH 1 /* RROPGARON */
-#define WM8400_RLOPGARON 0x0020 /* RLOPGARON */
-#define WM8400_RLOPGARON_MASK 0x0020 /* RLOPGARON */
-#define WM8400_RLOPGARON_SHIFT 5 /* RLOPGARON */
-#define WM8400_RLOPGARON_WIDTH 1 /* RLOPGARON */
-#define WM8400_ROPRON 0x0010 /* ROPRON */
-#define WM8400_ROPRON_MASK 0x0010 /* ROPRON */
-#define WM8400_ROPRON_SHIFT 4 /* ROPRON */
-#define WM8400_ROPRON_WIDTH 1 /* ROPRON */
-#define WM8400_RL12ROP 0x0004 /* RL12ROP */
-#define WM8400_RL12ROP_MASK 0x0004 /* RL12ROP */
-#define WM8400_RL12ROP_SHIFT 2 /* RL12ROP */
-#define WM8400_RL12ROP_WIDTH 1 /* RL12ROP */
-#define WM8400_RR12ROP 0x0002 /* RR12ROP */
-#define WM8400_RR12ROP_MASK 0x0002 /* RR12ROP */
-#define WM8400_RR12ROP_SHIFT 1 /* RR12ROP */
-#define WM8400_RR12ROP_WIDTH 1 /* RR12ROP */
-#define WM8400_RROPGAROP 0x0001 /* RROPGAROP */
-#define WM8400_RROPGAROP_MASK 0x0001 /* RROPGAROP */
-#define WM8400_RROPGAROP_SHIFT 0 /* RROPGAROP */
-#define WM8400_RROPGAROP_WIDTH 1 /* RROPGAROP */
-
-/*
- * R54 (0x36) - Speaker Mixer
- */
-#define WM8400_LB2SPK 0x0080 /* LB2SPK */
-#define WM8400_LB2SPK_MASK 0x0080 /* LB2SPK */
-#define WM8400_LB2SPK_SHIFT 7 /* LB2SPK */
-#define WM8400_LB2SPK_WIDTH 1 /* LB2SPK */
-#define WM8400_RB2SPK 0x0040 /* RB2SPK */
-#define WM8400_RB2SPK_MASK 0x0040 /* RB2SPK */
-#define WM8400_RB2SPK_SHIFT 6 /* RB2SPK */
-#define WM8400_RB2SPK_WIDTH 1 /* RB2SPK */
-#define WM8400_LI2SPK 0x0020 /* LI2SPK */
-#define WM8400_LI2SPK_MASK 0x0020 /* LI2SPK */
-#define WM8400_LI2SPK_SHIFT 5 /* LI2SPK */
-#define WM8400_LI2SPK_WIDTH 1 /* LI2SPK */
-#define WM8400_RI2SPK 0x0010 /* RI2SPK */
-#define WM8400_RI2SPK_MASK 0x0010 /* RI2SPK */
-#define WM8400_RI2SPK_SHIFT 4 /* RI2SPK */
-#define WM8400_RI2SPK_WIDTH 1 /* RI2SPK */
-#define WM8400_LOPGASPK 0x0008 /* LOPGASPK */
-#define WM8400_LOPGASPK_MASK 0x0008 /* LOPGASPK */
-#define WM8400_LOPGASPK_SHIFT 3 /* LOPGASPK */
-#define WM8400_LOPGASPK_WIDTH 1 /* LOPGASPK */
-#define WM8400_ROPGASPK 0x0004 /* ROPGASPK */
-#define WM8400_ROPGASPK_MASK 0x0004 /* ROPGASPK */
-#define WM8400_ROPGASPK_SHIFT 2 /* ROPGASPK */
-#define WM8400_ROPGASPK_WIDTH 1 /* ROPGASPK */
-#define WM8400_LDSPK 0x0002 /* LDSPK */
-#define WM8400_LDSPK_MASK 0x0002 /* LDSPK */
-#define WM8400_LDSPK_SHIFT 1 /* LDSPK */
-#define WM8400_LDSPK_WIDTH 1 /* LDSPK */
-#define WM8400_RDSPK 0x0001 /* RDSPK */
-#define WM8400_RDSPK_MASK 0x0001 /* RDSPK */
-#define WM8400_RDSPK_SHIFT 0 /* RDSPK */
-#define WM8400_RDSPK_WIDTH 1 /* RDSPK */
-
-/*
- * R55 (0x37) - Additional Control
- */
-#define WM8400_VROI 0x0001 /* VROI */
-#define WM8400_VROI_MASK 0x0001 /* VROI */
-#define WM8400_VROI_SHIFT 0 /* VROI */
-#define WM8400_VROI_WIDTH 1 /* VROI */
-
-/*
- * R56 (0x38) - AntiPOP1
- */
-#define WM8400_DIS_LLINE 0x0020 /* DIS_LLINE */
-#define WM8400_DIS_LLINE_MASK 0x0020 /* DIS_LLINE */
-#define WM8400_DIS_LLINE_SHIFT 5 /* DIS_LLINE */
-#define WM8400_DIS_LLINE_WIDTH 1 /* DIS_LLINE */
-#define WM8400_DIS_RLINE 0x0010 /* DIS_RLINE */
-#define WM8400_DIS_RLINE_MASK 0x0010 /* DIS_RLINE */
-#define WM8400_DIS_RLINE_SHIFT 4 /* DIS_RLINE */
-#define WM8400_DIS_RLINE_WIDTH 1 /* DIS_RLINE */
-#define WM8400_DIS_OUT3 0x0008 /* DIS_OUT3 */
-#define WM8400_DIS_OUT3_MASK 0x0008 /* DIS_OUT3 */
-#define WM8400_DIS_OUT3_SHIFT 3 /* DIS_OUT3 */
-#define WM8400_DIS_OUT3_WIDTH 1 /* DIS_OUT3 */
-#define WM8400_DIS_OUT4 0x0004 /* DIS_OUT4 */
-#define WM8400_DIS_OUT4_MASK 0x0004 /* DIS_OUT4 */
-#define WM8400_DIS_OUT4_SHIFT 2 /* DIS_OUT4 */
-#define WM8400_DIS_OUT4_WIDTH 1 /* DIS_OUT4 */
-#define WM8400_DIS_LOUT 0x0002 /* DIS_LOUT */
-#define WM8400_DIS_LOUT_MASK 0x0002 /* DIS_LOUT */
-#define WM8400_DIS_LOUT_SHIFT 1 /* DIS_LOUT */
-#define WM8400_DIS_LOUT_WIDTH 1 /* DIS_LOUT */
-#define WM8400_DIS_ROUT 0x0001 /* DIS_ROUT */
-#define WM8400_DIS_ROUT_MASK 0x0001 /* DIS_ROUT */
-#define WM8400_DIS_ROUT_SHIFT 0 /* DIS_ROUT */
-#define WM8400_DIS_ROUT_WIDTH 1 /* DIS_ROUT */
-
-/*
- * R57 (0x39) - AntiPOP2
- */
-#define WM8400_SOFTST 0x0040 /* SOFTST */
-#define WM8400_SOFTST_MASK 0x0040 /* SOFTST */
-#define WM8400_SOFTST_SHIFT 6 /* SOFTST */
-#define WM8400_SOFTST_WIDTH 1 /* SOFTST */
-#define WM8400_BUFIOEN 0x0008 /* BUFIOEN */
-#define WM8400_BUFIOEN_MASK 0x0008 /* BUFIOEN */
-#define WM8400_BUFIOEN_SHIFT 3 /* BUFIOEN */
-#define WM8400_BUFIOEN_WIDTH 1 /* BUFIOEN */
-#define WM8400_BUFDCOPEN 0x0004 /* BUFDCOPEN */
-#define WM8400_BUFDCOPEN_MASK 0x0004 /* BUFDCOPEN */
-#define WM8400_BUFDCOPEN_SHIFT 2 /* BUFDCOPEN */
-#define WM8400_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */
-#define WM8400_POBCTRL 0x0002 /* POBCTRL */
-#define WM8400_POBCTRL_MASK 0x0002 /* POBCTRL */
-#define WM8400_POBCTRL_SHIFT 1 /* POBCTRL */
-#define WM8400_POBCTRL_WIDTH 1 /* POBCTRL */
-#define WM8400_VMIDTOG 0x0001 /* VMIDTOG */
-#define WM8400_VMIDTOG_MASK 0x0001 /* VMIDTOG */
-#define WM8400_VMIDTOG_SHIFT 0 /* VMIDTOG */
-#define WM8400_VMIDTOG_WIDTH 1 /* VMIDTOG */
-
-/*
- * R58 (0x3A) - MICBIAS
- */
-#define WM8400_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */
-#define WM8400_MCDSCTH_SHIFT 6 /* MCDSCTH - [7:6] */
-#define WM8400_MCDSCTH_WIDTH 2 /* MCDSCTH - [7:6] */
-#define WM8400_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */
-#define WM8400_MCDTHR_SHIFT 3 /* MCDTHR - [5:3] */
-#define WM8400_MCDTHR_WIDTH 3 /* MCDTHR - [5:3] */
-#define WM8400_MCD 0x0004 /* MCD */
-#define WM8400_MCD_MASK 0x0004 /* MCD */
-#define WM8400_MCD_SHIFT 2 /* MCD */
-#define WM8400_MCD_WIDTH 1 /* MCD */
-#define WM8400_MBSEL 0x0001 /* MBSEL */
-#define WM8400_MBSEL_MASK 0x0001 /* MBSEL */
-#define WM8400_MBSEL_SHIFT 0 /* MBSEL */
-#define WM8400_MBSEL_WIDTH 1 /* MBSEL */
-
-/*
- * R60 (0x3C) - FLL Control 1
- */
-#define WM8400_FLL_REF_FREQ 0x1000 /* FLL_REF_FREQ */
-#define WM8400_FLL_REF_FREQ_MASK 0x1000 /* FLL_REF_FREQ */
-#define WM8400_FLL_REF_FREQ_SHIFT 12 /* FLL_REF_FREQ */
-#define WM8400_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
-#define WM8400_FLL_CLK_SRC_MASK 0x0C00 /* FLL_CLK_SRC - [11:10] */
-#define WM8400_FLL_CLK_SRC_SHIFT 10 /* FLL_CLK_SRC - [11:10] */
-#define WM8400_FLL_CLK_SRC_WIDTH 2 /* FLL_CLK_SRC - [11:10] */
-#define WM8400_FLL_FRAC 0x0200 /* FLL_FRAC */
-#define WM8400_FLL_FRAC_MASK 0x0200 /* FLL_FRAC */
-#define WM8400_FLL_FRAC_SHIFT 9 /* FLL_FRAC */
-#define WM8400_FLL_FRAC_WIDTH 1 /* FLL_FRAC */
-#define WM8400_FLL_OSC_ENA 0x0100 /* FLL_OSC_ENA */
-#define WM8400_FLL_OSC_ENA_MASK 0x0100 /* FLL_OSC_ENA */
-#define WM8400_FLL_OSC_ENA_SHIFT 8 /* FLL_OSC_ENA */
-#define WM8400_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
-#define WM8400_FLL_CTRL_RATE_MASK 0x00E0 /* FLL_CTRL_RATE - [7:5] */
-#define WM8400_FLL_CTRL_RATE_SHIFT 5 /* FLL_CTRL_RATE - [7:5] */
-#define WM8400_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [7:5] */
-#define WM8400_FLL_FRATIO_MASK 0x001F /* FLL_FRATIO - [4:0] */
-#define WM8400_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [4:0] */
-#define WM8400_FLL_FRATIO_WIDTH 5 /* FLL_FRATIO - [4:0] */
-
-/*
- * R61 (0x3D) - FLL Control 2
- */
-#define WM8400_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
-#define WM8400_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
-#define WM8400_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
-
-/*
- * R62 (0x3E) - FLL Control 3
- */
-#define WM8400_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */
-#define WM8400_FLL_N_SHIFT 0 /* FLL_N - [9:0] */
-#define WM8400_FLL_N_WIDTH 10 /* FLL_N - [9:0] */
-
-/*
- * R63 (0x3F) - FLL Control 4
- */
-#define WM8400_FLL_TRK_GAIN_MASK 0x0078 /* FLL_TRK_GAIN - [6:3] */
-#define WM8400_FLL_TRK_GAIN_SHIFT 3 /* FLL_TRK_GAIN - [6:3] */
-#define WM8400_FLL_TRK_GAIN_WIDTH 4 /* FLL_TRK_GAIN - [6:3] */
-#define WM8400_FLL_OUTDIV_MASK 0x0007 /* FLL_OUTDIV - [2:0] */
-#define WM8400_FLL_OUTDIV_SHIFT 0 /* FLL_OUTDIV - [2:0] */
-#define WM8400_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [2:0] */
-
-struct wm8400;
-void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400);
-
-#endif
diff --git a/include/linux/mfd/wm8400-private.h b/include/linux/mfd/wm8400-private.h
deleted file mode 100644
index bc8c2ca6dc70..000000000000
--- a/include/linux/mfd/wm8400-private.h
+++ /dev/null
@@ -1,913 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * wm8400 private definitions.
- *
- * Copyright 2008 Wolfson Microelectronics plc
- */
-
-#ifndef __LINUX_MFD_WM8400_PRIV_H
-#define __LINUX_MFD_WM8400_PRIV_H
-
-#include <linux/mfd/wm8400.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-
-#define WM8400_REGISTER_COUNT 0x55
-
-struct wm8400 {
- struct device *dev;
- struct regmap *regmap;
-
- struct platform_device regulators[6];
-};
-
-/*
- * Register values.
- */
-#define WM8400_RESET_ID 0x00
-#define WM8400_ID 0x01
-#define WM8400_POWER_MANAGEMENT_1 0x02
-#define WM8400_POWER_MANAGEMENT_2 0x03
-#define WM8400_POWER_MANAGEMENT_3 0x04
-#define WM8400_AUDIO_INTERFACE_1 0x05
-#define WM8400_AUDIO_INTERFACE_2 0x06
-#define WM8400_CLOCKING_1 0x07
-#define WM8400_CLOCKING_2 0x08
-#define WM8400_AUDIO_INTERFACE_3 0x09
-#define WM8400_AUDIO_INTERFACE_4 0x0A
-#define WM8400_DAC_CTRL 0x0B
-#define WM8400_LEFT_DAC_DIGITAL_VOLUME 0x0C
-#define WM8400_RIGHT_DAC_DIGITAL_VOLUME 0x0D
-#define WM8400_DIGITAL_SIDE_TONE 0x0E
-#define WM8400_ADC_CTRL 0x0F
-#define WM8400_LEFT_ADC_DIGITAL_VOLUME 0x10
-#define WM8400_RIGHT_ADC_DIGITAL_VOLUME 0x11
-#define WM8400_GPIO_CTRL_1 0x12
-#define WM8400_GPIO1_GPIO2 0x13
-#define WM8400_GPIO3_GPIO4 0x14
-#define WM8400_GPIO5_GPIO6 0x15
-#define WM8400_GPIOCTRL_2 0x16
-#define WM8400_GPIO_POL 0x17
-#define WM8400_LEFT_LINE_INPUT_1_2_VOLUME 0x18
-#define WM8400_LEFT_LINE_INPUT_3_4_VOLUME 0x19
-#define WM8400_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
-#define WM8400_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
-#define WM8400_LEFT_OUTPUT_VOLUME 0x1C
-#define WM8400_RIGHT_OUTPUT_VOLUME 0x1D
-#define WM8400_LINE_OUTPUTS_VOLUME 0x1E
-#define WM8400_OUT3_4_VOLUME 0x1F
-#define WM8400_LEFT_OPGA_VOLUME 0x20
-#define WM8400_RIGHT_OPGA_VOLUME 0x21
-#define WM8400_SPEAKER_VOLUME 0x22
-#define WM8400_CLASSD1 0x23
-#define WM8400_CLASSD3 0x25
-#define WM8400_INPUT_MIXER1 0x27
-#define WM8400_INPUT_MIXER2 0x28
-#define WM8400_INPUT_MIXER3 0x29
-#define WM8400_INPUT_MIXER4 0x2A
-#define WM8400_INPUT_MIXER5 0x2B
-#define WM8400_INPUT_MIXER6 0x2C
-#define WM8400_OUTPUT_MIXER1 0x2D
-#define WM8400_OUTPUT_MIXER2 0x2E
-#define WM8400_OUTPUT_MIXER3 0x2F
-#define WM8400_OUTPUT_MIXER4 0x30
-#define WM8400_OUTPUT_MIXER5 0x31
-#define WM8400_OUTPUT_MIXER6 0x32
-#define WM8400_OUT3_4_MIXER 0x33
-#define WM8400_LINE_MIXER1 0x34
-#define WM8400_LINE_MIXER2 0x35
-#define WM8400_SPEAKER_MIXER 0x36
-#define WM8400_ADDITIONAL_CONTROL 0x37
-#define WM8400_ANTIPOP1 0x38
-#define WM8400_ANTIPOP2 0x39
-#define WM8400_MICBIAS 0x3A
-#define WM8400_FLL_CONTROL_1 0x3C
-#define WM8400_FLL_CONTROL_2 0x3D
-#define WM8400_FLL_CONTROL_3 0x3E
-#define WM8400_FLL_CONTROL_4 0x3F
-#define WM8400_LDO1_CONTROL 0x41
-#define WM8400_LDO2_CONTROL 0x42
-#define WM8400_LDO3_CONTROL 0x43
-#define WM8400_LDO4_CONTROL 0x44
-#define WM8400_DCDC1_CONTROL_1 0x46
-#define WM8400_DCDC1_CONTROL_2 0x47
-#define WM8400_DCDC2_CONTROL_1 0x48
-#define WM8400_DCDC2_CONTROL_2 0x49
-#define WM8400_INTERFACE 0x4B
-#define WM8400_PM_GENERAL 0x4C
-#define WM8400_PM_SHUTDOWN_CONTROL 0x4E
-#define WM8400_INTERRUPT_STATUS_1 0x4F
-#define WM8400_INTERRUPT_STATUS_1_MASK 0x50
-#define WM8400_INTERRUPT_LEVELS 0x51
-#define WM8400_SHUTDOWN_REASON 0x52
-#define WM8400_LINE_CIRCUITS 0x54
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Reset/ID
- */
-#define WM8400_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET/CHIP_ID - [15:0] */
-#define WM8400_SW_RESET_CHIP_ID_SHIFT 0 /* SW_RESET/CHIP_ID - [15:0] */
-#define WM8400_SW_RESET_CHIP_ID_WIDTH 16 /* SW_RESET/CHIP_ID - [15:0] */
-
-/*
- * R1 (0x01) - ID
- */
-#define WM8400_CHIP_REV_MASK 0x7000 /* CHIP_REV - [14:12] */
-#define WM8400_CHIP_REV_SHIFT 12 /* CHIP_REV - [14:12] */
-#define WM8400_CHIP_REV_WIDTH 3 /* CHIP_REV - [14:12] */
-
-/*
- * R18 (0x12) - GPIO CTRL 1
- */
-#define WM8400_IRQ 0x1000 /* IRQ */
-#define WM8400_IRQ_MASK 0x1000 /* IRQ */
-#define WM8400_IRQ_SHIFT 12 /* IRQ */
-#define WM8400_IRQ_WIDTH 1 /* IRQ */
-#define WM8400_TEMPOK 0x0800 /* TEMPOK */
-#define WM8400_TEMPOK_MASK 0x0800 /* TEMPOK */
-#define WM8400_TEMPOK_SHIFT 11 /* TEMPOK */
-#define WM8400_TEMPOK_WIDTH 1 /* TEMPOK */
-#define WM8400_MIC1SHRT 0x0400 /* MIC1SHRT */
-#define WM8400_MIC1SHRT_MASK 0x0400 /* MIC1SHRT */
-#define WM8400_MIC1SHRT_SHIFT 10 /* MIC1SHRT */
-#define WM8400_MIC1SHRT_WIDTH 1 /* MIC1SHRT */
-#define WM8400_MIC1DET 0x0200 /* MIC1DET */
-#define WM8400_MIC1DET_MASK 0x0200 /* MIC1DET */
-#define WM8400_MIC1DET_SHIFT 9 /* MIC1DET */
-#define WM8400_MIC1DET_WIDTH 1 /* MIC1DET */
-#define WM8400_FLL_LCK 0x0100 /* FLL_LCK */
-#define WM8400_FLL_LCK_MASK 0x0100 /* FLL_LCK */
-#define WM8400_FLL_LCK_SHIFT 8 /* FLL_LCK */
-#define WM8400_FLL_LCK_WIDTH 1 /* FLL_LCK */
-#define WM8400_GPIO_STATUS_MASK 0x00FF /* GPIO_STATUS - [7:0] */
-#define WM8400_GPIO_STATUS_SHIFT 0 /* GPIO_STATUS - [7:0] */
-#define WM8400_GPIO_STATUS_WIDTH 8 /* GPIO_STATUS - [7:0] */
-
-/*
- * R19 (0x13) - GPIO1 & GPIO2
- */
-#define WM8400_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */
-#define WM8400_GPIO2_DEB_ENA_MASK 0x8000 /* GPIO2_DEB_ENA */
-#define WM8400_GPIO2_DEB_ENA_SHIFT 15 /* GPIO2_DEB_ENA */
-#define WM8400_GPIO2_DEB_ENA_WIDTH 1 /* GPIO2_DEB_ENA */
-#define WM8400_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */
-#define WM8400_GPIO2_IRQ_ENA_MASK 0x4000 /* GPIO2_IRQ_ENA */
-#define WM8400_GPIO2_IRQ_ENA_SHIFT 14 /* GPIO2_IRQ_ENA */
-#define WM8400_GPIO2_IRQ_ENA_WIDTH 1 /* GPIO2_IRQ_ENA */
-#define WM8400_GPIO2_PU 0x2000 /* GPIO2_PU */
-#define WM8400_GPIO2_PU_MASK 0x2000 /* GPIO2_PU */
-#define WM8400_GPIO2_PU_SHIFT 13 /* GPIO2_PU */
-#define WM8400_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
-#define WM8400_GPIO2_PD 0x1000 /* GPIO2_PD */
-#define WM8400_GPIO2_PD_MASK 0x1000 /* GPIO2_PD */
-#define WM8400_GPIO2_PD_SHIFT 12 /* GPIO2_PD */
-#define WM8400_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
-#define WM8400_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */
-#define WM8400_GPIO2_SEL_SHIFT 8 /* GPIO2_SEL - [11:8] */
-#define WM8400_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [11:8] */
-#define WM8400_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */
-#define WM8400_GPIO1_DEB_ENA_MASK 0x0080 /* GPIO1_DEB_ENA */
-#define WM8400_GPIO1_DEB_ENA_SHIFT 7 /* GPIO1_DEB_ENA */
-#define WM8400_GPIO1_DEB_ENA_WIDTH 1 /* GPIO1_DEB_ENA */
-#define WM8400_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */
-#define WM8400_GPIO1_IRQ_ENA_MASK 0x0040 /* GPIO1_IRQ_ENA */
-#define WM8400_GPIO1_IRQ_ENA_SHIFT 6 /* GPIO1_IRQ_ENA */
-#define WM8400_GPIO1_IRQ_ENA_WIDTH 1 /* GPIO1_IRQ_ENA */
-#define WM8400_GPIO1_PU 0x0020 /* GPIO1_PU */
-#define WM8400_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
-#define WM8400_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
-#define WM8400_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
-#define WM8400_GPIO1_PD 0x0010 /* GPIO1_PD */
-#define WM8400_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
-#define WM8400_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
-#define WM8400_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
-#define WM8400_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
-#define WM8400_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
-#define WM8400_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
-
-/*
- * R20 (0x14) - GPIO3 & GPIO4
- */
-#define WM8400_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */
-#define WM8400_GPIO4_DEB_ENA_MASK 0x8000 /* GPIO4_DEB_ENA */
-#define WM8400_GPIO4_DEB_ENA_SHIFT 15 /* GPIO4_DEB_ENA */
-#define WM8400_GPIO4_DEB_ENA_WIDTH 1 /* GPIO4_DEB_ENA */
-#define WM8400_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */
-#define WM8400_GPIO4_IRQ_ENA_MASK 0x4000 /* GPIO4_IRQ_ENA */
-#define WM8400_GPIO4_IRQ_ENA_SHIFT 14 /* GPIO4_IRQ_ENA */
-#define WM8400_GPIO4_IRQ_ENA_WIDTH 1 /* GPIO4_IRQ_ENA */
-#define WM8400_GPIO4_PU 0x2000 /* GPIO4_PU */
-#define WM8400_GPIO4_PU_MASK 0x2000 /* GPIO4_PU */
-#define WM8400_GPIO4_PU_SHIFT 13 /* GPIO4_PU */
-#define WM8400_GPIO4_PU_WIDTH 1 /* GPIO4_PU */
-#define WM8400_GPIO4_PD 0x1000 /* GPIO4_PD */
-#define WM8400_GPIO4_PD_MASK 0x1000 /* GPIO4_PD */
-#define WM8400_GPIO4_PD_SHIFT 12 /* GPIO4_PD */
-#define WM8400_GPIO4_PD_WIDTH 1 /* GPIO4_PD */
-#define WM8400_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */
-#define WM8400_GPIO4_SEL_SHIFT 8 /* GPIO4_SEL - [11:8] */
-#define WM8400_GPIO4_SEL_WIDTH 4 /* GPIO4_SEL - [11:8] */
-#define WM8400_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */
-#define WM8400_GPIO3_DEB_ENA_MASK 0x0080 /* GPIO3_DEB_ENA */
-#define WM8400_GPIO3_DEB_ENA_SHIFT 7 /* GPIO3_DEB_ENA */
-#define WM8400_GPIO3_DEB_ENA_WIDTH 1 /* GPIO3_DEB_ENA */
-#define WM8400_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */
-#define WM8400_GPIO3_IRQ_ENA_MASK 0x0040 /* GPIO3_IRQ_ENA */
-#define WM8400_GPIO3_IRQ_ENA_SHIFT 6 /* GPIO3_IRQ_ENA */
-#define WM8400_GPIO3_IRQ_ENA_WIDTH 1 /* GPIO3_IRQ_ENA */
-#define WM8400_GPIO3_PU 0x0020 /* GPIO3_PU */
-#define WM8400_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
-#define WM8400_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
-#define WM8400_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
-#define WM8400_GPIO3_PD 0x0010 /* GPIO3_PD */
-#define WM8400_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
-#define WM8400_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
-#define WM8400_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
-#define WM8400_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
-#define WM8400_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
-#define WM8400_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
-
-/*
- * R21 (0x15) - GPIO5 & GPIO6
- */
-#define WM8400_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */
-#define WM8400_GPIO6_DEB_ENA_MASK 0x8000 /* GPIO6_DEB_ENA */
-#define WM8400_GPIO6_DEB_ENA_SHIFT 15 /* GPIO6_DEB_ENA */
-#define WM8400_GPIO6_DEB_ENA_WIDTH 1 /* GPIO6_DEB_ENA */
-#define WM8400_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */
-#define WM8400_GPIO6_IRQ_ENA_MASK 0x4000 /* GPIO6_IRQ_ENA */
-#define WM8400_GPIO6_IRQ_ENA_SHIFT 14 /* GPIO6_IRQ_ENA */
-#define WM8400_GPIO6_IRQ_ENA_WIDTH 1 /* GPIO6_IRQ_ENA */
-#define WM8400_GPIO6_PU 0x2000 /* GPIO6_PU */
-#define WM8400_GPIO6_PU_MASK 0x2000 /* GPIO6_PU */
-#define WM8400_GPIO6_PU_SHIFT 13 /* GPIO6_PU */
-#define WM8400_GPIO6_PU_WIDTH 1 /* GPIO6_PU */
-#define WM8400_GPIO6_PD 0x1000 /* GPIO6_PD */
-#define WM8400_GPIO6_PD_MASK 0x1000 /* GPIO6_PD */
-#define WM8400_GPIO6_PD_SHIFT 12 /* GPIO6_PD */
-#define WM8400_GPIO6_PD_WIDTH 1 /* GPIO6_PD */
-#define WM8400_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */
-#define WM8400_GPIO6_SEL_SHIFT 8 /* GPIO6_SEL - [11:8] */
-#define WM8400_GPIO6_SEL_WIDTH 4 /* GPIO6_SEL - [11:8] */
-#define WM8400_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */
-#define WM8400_GPIO5_DEB_ENA_MASK 0x0080 /* GPIO5_DEB_ENA */
-#define WM8400_GPIO5_DEB_ENA_SHIFT 7 /* GPIO5_DEB_ENA */
-#define WM8400_GPIO5_DEB_ENA_WIDTH 1 /* GPIO5_DEB_ENA */
-#define WM8400_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */
-#define WM8400_GPIO5_IRQ_ENA_MASK 0x0040 /* GPIO5_IRQ_ENA */
-#define WM8400_GPIO5_IRQ_ENA_SHIFT 6 /* GPIO5_IRQ_ENA */
-#define WM8400_GPIO5_IRQ_ENA_WIDTH 1 /* GPIO5_IRQ_ENA */
-#define WM8400_GPIO5_PU 0x0020 /* GPIO5_PU */
-#define WM8400_GPIO5_PU_MASK 0x0020 /* GPIO5_PU */
-#define WM8400_GPIO5_PU_SHIFT 5 /* GPIO5_PU */
-#define WM8400_GPIO5_PU_WIDTH 1 /* GPIO5_PU */
-#define WM8400_GPIO5_PD 0x0010 /* GPIO5_PD */
-#define WM8400_GPIO5_PD_MASK 0x0010 /* GPIO5_PD */
-#define WM8400_GPIO5_PD_SHIFT 4 /* GPIO5_PD */
-#define WM8400_GPIO5_PD_WIDTH 1 /* GPIO5_PD */
-#define WM8400_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */
-#define WM8400_GPIO5_SEL_SHIFT 0 /* GPIO5_SEL - [3:0] */
-#define WM8400_GPIO5_SEL_WIDTH 4 /* GPIO5_SEL - [3:0] */
-
-/*
- * R22 (0x16) - GPIOCTRL 2
- */
-#define WM8400_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */
-#define WM8400_TEMPOK_IRQ_ENA_MASK 0x0800 /* TEMPOK_IRQ_ENA */
-#define WM8400_TEMPOK_IRQ_ENA_SHIFT 11 /* TEMPOK_IRQ_ENA */
-#define WM8400_TEMPOK_IRQ_ENA_WIDTH 1 /* TEMPOK_IRQ_ENA */
-#define WM8400_MIC1SHRT_IRQ_ENA 0x0400 /* MIC1SHRT_IRQ_ENA */
-#define WM8400_MIC1SHRT_IRQ_ENA_MASK 0x0400 /* MIC1SHRT_IRQ_ENA */
-#define WM8400_MIC1SHRT_IRQ_ENA_SHIFT 10 /* MIC1SHRT_IRQ_ENA */
-#define WM8400_MIC1SHRT_IRQ_ENA_WIDTH 1 /* MIC1SHRT_IRQ_ENA */
-#define WM8400_MIC1DET_IRQ_ENA 0x0200 /* MIC1DET_IRQ_ENA */
-#define WM8400_MIC1DET_IRQ_ENA_MASK 0x0200 /* MIC1DET_IRQ_ENA */
-#define WM8400_MIC1DET_IRQ_ENA_SHIFT 9 /* MIC1DET_IRQ_ENA */
-#define WM8400_MIC1DET_IRQ_ENA_WIDTH 1 /* MIC1DET_IRQ_ENA */
-#define WM8400_FLL_LCK_IRQ_ENA 0x0100 /* FLL_LCK_IRQ_ENA */
-#define WM8400_FLL_LCK_IRQ_ENA_MASK 0x0100 /* FLL_LCK_IRQ_ENA */
-#define WM8400_FLL_LCK_IRQ_ENA_SHIFT 8 /* FLL_LCK_IRQ_ENA */
-#define WM8400_FLL_LCK_IRQ_ENA_WIDTH 1 /* FLL_LCK_IRQ_ENA */
-#define WM8400_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */
-#define WM8400_GPI8_DEB_ENA_MASK 0x0080 /* GPI8_DEB_ENA */
-#define WM8400_GPI8_DEB_ENA_SHIFT 7 /* GPI8_DEB_ENA */
-#define WM8400_GPI8_DEB_ENA_WIDTH 1 /* GPI8_DEB_ENA */
-#define WM8400_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */
-#define WM8400_GPI8_IRQ_ENA_MASK 0x0040 /* GPI8_IRQ_ENA */
-#define WM8400_GPI8_IRQ_ENA_SHIFT 6 /* GPI8_IRQ_ENA */
-#define WM8400_GPI8_IRQ_ENA_WIDTH 1 /* GPI8_IRQ_ENA */
-#define WM8400_GPI8_ENA 0x0010 /* GPI8_ENA */
-#define WM8400_GPI8_ENA_MASK 0x0010 /* GPI8_ENA */
-#define WM8400_GPI8_ENA_SHIFT 4 /* GPI8_ENA */
-#define WM8400_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
-#define WM8400_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */
-#define WM8400_GPI7_DEB_ENA_MASK 0x0008 /* GPI7_DEB_ENA */
-#define WM8400_GPI7_DEB_ENA_SHIFT 3 /* GPI7_DEB_ENA */
-#define WM8400_GPI7_DEB_ENA_WIDTH 1 /* GPI7_DEB_ENA */
-#define WM8400_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */
-#define WM8400_GPI7_IRQ_ENA_MASK 0x0004 /* GPI7_IRQ_ENA */
-#define WM8400_GPI7_IRQ_ENA_SHIFT 2 /* GPI7_IRQ_ENA */
-#define WM8400_GPI7_IRQ_ENA_WIDTH 1 /* GPI7_IRQ_ENA */
-#define WM8400_GPI7_ENA 0x0001 /* GPI7_ENA */
-#define WM8400_GPI7_ENA_MASK 0x0001 /* GPI7_ENA */
-#define WM8400_GPI7_ENA_SHIFT 0 /* GPI7_ENA */
-#define WM8400_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
-
-/*
- * R23 (0x17) - GPIO_POL
- */
-#define WM8400_IRQ_INV 0x1000 /* IRQ_INV */
-#define WM8400_IRQ_INV_MASK 0x1000 /* IRQ_INV */
-#define WM8400_IRQ_INV_SHIFT 12 /* IRQ_INV */
-#define WM8400_IRQ_INV_WIDTH 1 /* IRQ_INV */
-#define WM8400_TEMPOK_POL 0x0800 /* TEMPOK_POL */
-#define WM8400_TEMPOK_POL_MASK 0x0800 /* TEMPOK_POL */
-#define WM8400_TEMPOK_POL_SHIFT 11 /* TEMPOK_POL */
-#define WM8400_TEMPOK_POL_WIDTH 1 /* TEMPOK_POL */
-#define WM8400_MIC1SHRT_POL 0x0400 /* MIC1SHRT_POL */
-#define WM8400_MIC1SHRT_POL_MASK 0x0400 /* MIC1SHRT_POL */
-#define WM8400_MIC1SHRT_POL_SHIFT 10 /* MIC1SHRT_POL */
-#define WM8400_MIC1SHRT_POL_WIDTH 1 /* MIC1SHRT_POL */
-#define WM8400_MIC1DET_POL 0x0200 /* MIC1DET_POL */
-#define WM8400_MIC1DET_POL_MASK 0x0200 /* MIC1DET_POL */
-#define WM8400_MIC1DET_POL_SHIFT 9 /* MIC1DET_POL */
-#define WM8400_MIC1DET_POL_WIDTH 1 /* MIC1DET_POL */
-#define WM8400_FLL_LCK_POL 0x0100 /* FLL_LCK_POL */
-#define WM8400_FLL_LCK_POL_MASK 0x0100 /* FLL_LCK_POL */
-#define WM8400_FLL_LCK_POL_SHIFT 8 /* FLL_LCK_POL */
-#define WM8400_FLL_LCK_POL_WIDTH 1 /* FLL_LCK_POL */
-#define WM8400_GPIO_POL_MASK 0x00FF /* GPIO_POL - [7:0] */
-#define WM8400_GPIO_POL_SHIFT 0 /* GPIO_POL - [7:0] */
-#define WM8400_GPIO_POL_WIDTH 8 /* GPIO_POL - [7:0] */
-
-/*
- * R65 (0x41) - LDO 1 Control
- */
-#define WM8400_LDO1_ENA 0x8000 /* LDO1_ENA */
-#define WM8400_LDO1_ENA_MASK 0x8000 /* LDO1_ENA */
-#define WM8400_LDO1_ENA_SHIFT 15 /* LDO1_ENA */
-#define WM8400_LDO1_ENA_WIDTH 1 /* LDO1_ENA */
-#define WM8400_LDO1_SWI 0x4000 /* LDO1_SWI */
-#define WM8400_LDO1_SWI_MASK 0x4000 /* LDO1_SWI */
-#define WM8400_LDO1_SWI_SHIFT 14 /* LDO1_SWI */
-#define WM8400_LDO1_SWI_WIDTH 1 /* LDO1_SWI */
-#define WM8400_LDO1_OPFLT 0x1000 /* LDO1_OPFLT */
-#define WM8400_LDO1_OPFLT_MASK 0x1000 /* LDO1_OPFLT */
-#define WM8400_LDO1_OPFLT_SHIFT 12 /* LDO1_OPFLT */
-#define WM8400_LDO1_OPFLT_WIDTH 1 /* LDO1_OPFLT */
-#define WM8400_LDO1_ERRACT 0x0800 /* LDO1_ERRACT */
-#define WM8400_LDO1_ERRACT_MASK 0x0800 /* LDO1_ERRACT */
-#define WM8400_LDO1_ERRACT_SHIFT 11 /* LDO1_ERRACT */
-#define WM8400_LDO1_ERRACT_WIDTH 1 /* LDO1_ERRACT */
-#define WM8400_LDO1_HIB_MODE 0x0400 /* LDO1_HIB_MODE */
-#define WM8400_LDO1_HIB_MODE_MASK 0x0400 /* LDO1_HIB_MODE */
-#define WM8400_LDO1_HIB_MODE_SHIFT 10 /* LDO1_HIB_MODE */
-#define WM8400_LDO1_HIB_MODE_WIDTH 1 /* LDO1_HIB_MODE */
-#define WM8400_LDO1_VIMG_MASK 0x03E0 /* LDO1_VIMG - [9:5] */
-#define WM8400_LDO1_VIMG_SHIFT 5 /* LDO1_VIMG - [9:5] */
-#define WM8400_LDO1_VIMG_WIDTH 5 /* LDO1_VIMG - [9:5] */
-#define WM8400_LDO1_VSEL_MASK 0x001F /* LDO1_VSEL - [4:0] */
-#define WM8400_LDO1_VSEL_SHIFT 0 /* LDO1_VSEL - [4:0] */
-#define WM8400_LDO1_VSEL_WIDTH 5 /* LDO1_VSEL - [4:0] */
-
-/*
- * R66 (0x42) - LDO 2 Control
- */
-#define WM8400_LDO2_ENA 0x8000 /* LDO2_ENA */
-#define WM8400_LDO2_ENA_MASK 0x8000 /* LDO2_ENA */
-#define WM8400_LDO2_ENA_SHIFT 15 /* LDO2_ENA */
-#define WM8400_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
-#define WM8400_LDO2_SWI 0x4000 /* LDO2_SWI */
-#define WM8400_LDO2_SWI_MASK 0x4000 /* LDO2_SWI */
-#define WM8400_LDO2_SWI_SHIFT 14 /* LDO2_SWI */
-#define WM8400_LDO2_SWI_WIDTH 1 /* LDO2_SWI */
-#define WM8400_LDO2_OPFLT 0x1000 /* LDO2_OPFLT */
-#define WM8400_LDO2_OPFLT_MASK 0x1000 /* LDO2_OPFLT */
-#define WM8400_LDO2_OPFLT_SHIFT 12 /* LDO2_OPFLT */
-#define WM8400_LDO2_OPFLT_WIDTH 1 /* LDO2_OPFLT */
-#define WM8400_LDO2_ERRACT 0x0800 /* LDO2_ERRACT */
-#define WM8400_LDO2_ERRACT_MASK 0x0800 /* LDO2_ERRACT */
-#define WM8400_LDO2_ERRACT_SHIFT 11 /* LDO2_ERRACT */
-#define WM8400_LDO2_ERRACT_WIDTH 1 /* LDO2_ERRACT */
-#define WM8400_LDO2_HIB_MODE 0x0400 /* LDO2_HIB_MODE */
-#define WM8400_LDO2_HIB_MODE_MASK 0x0400 /* LDO2_HIB_MODE */
-#define WM8400_LDO2_HIB_MODE_SHIFT 10 /* LDO2_HIB_MODE */
-#define WM8400_LDO2_HIB_MODE_WIDTH 1 /* LDO2_HIB_MODE */
-#define WM8400_LDO2_VIMG_MASK 0x03E0 /* LDO2_VIMG - [9:5] */
-#define WM8400_LDO2_VIMG_SHIFT 5 /* LDO2_VIMG - [9:5] */
-#define WM8400_LDO2_VIMG_WIDTH 5 /* LDO2_VIMG - [9:5] */
-#define WM8400_LDO2_VSEL_MASK 0x001F /* LDO2_VSEL - [4:0] */
-#define WM8400_LDO2_VSEL_SHIFT 0 /* LDO2_VSEL - [4:0] */
-#define WM8400_LDO2_VSEL_WIDTH 5 /* LDO2_VSEL - [4:0] */
-
-/*
- * R67 (0x43) - LDO 3 Control
- */
-#define WM8400_LDO3_ENA 0x8000 /* LDO3_ENA */
-#define WM8400_LDO3_ENA_MASK 0x8000 /* LDO3_ENA */
-#define WM8400_LDO3_ENA_SHIFT 15 /* LDO3_ENA */
-#define WM8400_LDO3_ENA_WIDTH 1 /* LDO3_ENA */
-#define WM8400_LDO3_SWI 0x4000 /* LDO3_SWI */
-#define WM8400_LDO3_SWI_MASK 0x4000 /* LDO3_SWI */
-#define WM8400_LDO3_SWI_SHIFT 14 /* LDO3_SWI */
-#define WM8400_LDO3_SWI_WIDTH 1 /* LDO3_SWI */
-#define WM8400_LDO3_OPFLT 0x1000 /* LDO3_OPFLT */
-#define WM8400_LDO3_OPFLT_MASK 0x1000 /* LDO3_OPFLT */
-#define WM8400_LDO3_OPFLT_SHIFT 12 /* LDO3_OPFLT */
-#define WM8400_LDO3_OPFLT_WIDTH 1 /* LDO3_OPFLT */
-#define WM8400_LDO3_ERRACT 0x0800 /* LDO3_ERRACT */
-#define WM8400_LDO3_ERRACT_MASK 0x0800 /* LDO3_ERRACT */
-#define WM8400_LDO3_ERRACT_SHIFT 11 /* LDO3_ERRACT */
-#define WM8400_LDO3_ERRACT_WIDTH 1 /* LDO3_ERRACT */
-#define WM8400_LDO3_HIB_MODE 0x0400 /* LDO3_HIB_MODE */
-#define WM8400_LDO3_HIB_MODE_MASK 0x0400 /* LDO3_HIB_MODE */
-#define WM8400_LDO3_HIB_MODE_SHIFT 10 /* LDO3_HIB_MODE */
-#define WM8400_LDO3_HIB_MODE_WIDTH 1 /* LDO3_HIB_MODE */
-#define WM8400_LDO3_VIMG_MASK 0x03E0 /* LDO3_VIMG - [9:5] */
-#define WM8400_LDO3_VIMG_SHIFT 5 /* LDO3_VIMG - [9:5] */
-#define WM8400_LDO3_VIMG_WIDTH 5 /* LDO3_VIMG - [9:5] */
-#define WM8400_LDO3_VSEL_MASK 0x001F /* LDO3_VSEL - [4:0] */
-#define WM8400_LDO3_VSEL_SHIFT 0 /* LDO3_VSEL - [4:0] */
-#define WM8400_LDO3_VSEL_WIDTH 5 /* LDO3_VSEL - [4:0] */
-
-/*
- * R68 (0x44) - LDO 4 Control
- */
-#define WM8400_LDO4_ENA 0x8000 /* LDO4_ENA */
-#define WM8400_LDO4_ENA_MASK 0x8000 /* LDO4_ENA */
-#define WM8400_LDO4_ENA_SHIFT 15 /* LDO4_ENA */
-#define WM8400_LDO4_ENA_WIDTH 1 /* LDO4_ENA */
-#define WM8400_LDO4_SWI 0x4000 /* LDO4_SWI */
-#define WM8400_LDO4_SWI_MASK 0x4000 /* LDO4_SWI */
-#define WM8400_LDO4_SWI_SHIFT 14 /* LDO4_SWI */
-#define WM8400_LDO4_SWI_WIDTH 1 /* LDO4_SWI */
-#define WM8400_LDO4_OPFLT 0x1000 /* LDO4_OPFLT */
-#define WM8400_LDO4_OPFLT_MASK 0x1000 /* LDO4_OPFLT */
-#define WM8400_LDO4_OPFLT_SHIFT 12 /* LDO4_OPFLT */
-#define WM8400_LDO4_OPFLT_WIDTH 1 /* LDO4_OPFLT */
-#define WM8400_LDO4_ERRACT 0x0800 /* LDO4_ERRACT */
-#define WM8400_LDO4_ERRACT_MASK 0x0800 /* LDO4_ERRACT */
-#define WM8400_LDO4_ERRACT_SHIFT 11 /* LDO4_ERRACT */
-#define WM8400_LDO4_ERRACT_WIDTH 1 /* LDO4_ERRACT */
-#define WM8400_LDO4_HIB_MODE 0x0400 /* LDO4_HIB_MODE */
-#define WM8400_LDO4_HIB_MODE_MASK 0x0400 /* LDO4_HIB_MODE */
-#define WM8400_LDO4_HIB_MODE_SHIFT 10 /* LDO4_HIB_MODE */
-#define WM8400_LDO4_HIB_MODE_WIDTH 1 /* LDO4_HIB_MODE */
-#define WM8400_LDO4_VIMG_MASK 0x03E0 /* LDO4_VIMG - [9:5] */
-#define WM8400_LDO4_VIMG_SHIFT 5 /* LDO4_VIMG - [9:5] */
-#define WM8400_LDO4_VIMG_WIDTH 5 /* LDO4_VIMG - [9:5] */
-#define WM8400_LDO4_VSEL_MASK 0x001F /* LDO4_VSEL - [4:0] */
-#define WM8400_LDO4_VSEL_SHIFT 0 /* LDO4_VSEL - [4:0] */
-#define WM8400_LDO4_VSEL_WIDTH 5 /* LDO4_VSEL - [4:0] */
-
-/*
- * R70 (0x46) - DCDC1 Control 1
- */
-#define WM8400_DC1_ENA 0x8000 /* DC1_ENA */
-#define WM8400_DC1_ENA_MASK 0x8000 /* DC1_ENA */
-#define WM8400_DC1_ENA_SHIFT 15 /* DC1_ENA */
-#define WM8400_DC1_ENA_WIDTH 1 /* DC1_ENA */
-#define WM8400_DC1_ACTIVE 0x4000 /* DC1_ACTIVE */
-#define WM8400_DC1_ACTIVE_MASK 0x4000 /* DC1_ACTIVE */
-#define WM8400_DC1_ACTIVE_SHIFT 14 /* DC1_ACTIVE */
-#define WM8400_DC1_ACTIVE_WIDTH 1 /* DC1_ACTIVE */
-#define WM8400_DC1_SLEEP 0x2000 /* DC1_SLEEP */
-#define WM8400_DC1_SLEEP_MASK 0x2000 /* DC1_SLEEP */
-#define WM8400_DC1_SLEEP_SHIFT 13 /* DC1_SLEEP */
-#define WM8400_DC1_SLEEP_WIDTH 1 /* DC1_SLEEP */
-#define WM8400_DC1_OPFLT 0x1000 /* DC1_OPFLT */
-#define WM8400_DC1_OPFLT_MASK 0x1000 /* DC1_OPFLT */
-#define WM8400_DC1_OPFLT_SHIFT 12 /* DC1_OPFLT */
-#define WM8400_DC1_OPFLT_WIDTH 1 /* DC1_OPFLT */
-#define WM8400_DC1_ERRACT 0x0800 /* DC1_ERRACT */
-#define WM8400_DC1_ERRACT_MASK 0x0800 /* DC1_ERRACT */
-#define WM8400_DC1_ERRACT_SHIFT 11 /* DC1_ERRACT */
-#define WM8400_DC1_ERRACT_WIDTH 1 /* DC1_ERRACT */
-#define WM8400_DC1_HIB_MODE 0x0400 /* DC1_HIB_MODE */
-#define WM8400_DC1_HIB_MODE_MASK 0x0400 /* DC1_HIB_MODE */
-#define WM8400_DC1_HIB_MODE_SHIFT 10 /* DC1_HIB_MODE */
-#define WM8400_DC1_HIB_MODE_WIDTH 1 /* DC1_HIB_MODE */
-#define WM8400_DC1_SOFTST_MASK 0x0300 /* DC1_SOFTST - [9:8] */
-#define WM8400_DC1_SOFTST_SHIFT 8 /* DC1_SOFTST - [9:8] */
-#define WM8400_DC1_SOFTST_WIDTH 2 /* DC1_SOFTST - [9:8] */
-#define WM8400_DC1_OV_PROT 0x0080 /* DC1_OV_PROT */
-#define WM8400_DC1_OV_PROT_MASK 0x0080 /* DC1_OV_PROT */
-#define WM8400_DC1_OV_PROT_SHIFT 7 /* DC1_OV_PROT */
-#define WM8400_DC1_OV_PROT_WIDTH 1 /* DC1_OV_PROT */
-#define WM8400_DC1_VSEL_MASK 0x007F /* DC1_VSEL - [6:0] */
-#define WM8400_DC1_VSEL_SHIFT 0 /* DC1_VSEL - [6:0] */
-#define WM8400_DC1_VSEL_WIDTH 7 /* DC1_VSEL - [6:0] */
-
-/*
- * R71 (0x47) - DCDC1 Control 2
- */
-#define WM8400_DC1_FRC_PWM 0x2000 /* DC1_FRC_PWM */
-#define WM8400_DC1_FRC_PWM_MASK 0x2000 /* DC1_FRC_PWM */
-#define WM8400_DC1_FRC_PWM_SHIFT 13 /* DC1_FRC_PWM */
-#define WM8400_DC1_FRC_PWM_WIDTH 1 /* DC1_FRC_PWM */
-#define WM8400_DC1_STBY_LIM_MASK 0x0300 /* DC1_STBY_LIM - [9:8] */
-#define WM8400_DC1_STBY_LIM_SHIFT 8 /* DC1_STBY_LIM - [9:8] */
-#define WM8400_DC1_STBY_LIM_WIDTH 2 /* DC1_STBY_LIM - [9:8] */
-#define WM8400_DC1_ACT_LIM 0x0080 /* DC1_ACT_LIM */
-#define WM8400_DC1_ACT_LIM_MASK 0x0080 /* DC1_ACT_LIM */
-#define WM8400_DC1_ACT_LIM_SHIFT 7 /* DC1_ACT_LIM */
-#define WM8400_DC1_ACT_LIM_WIDTH 1 /* DC1_ACT_LIM */
-#define WM8400_DC1_VIMG_MASK 0x007F /* DC1_VIMG - [6:0] */
-#define WM8400_DC1_VIMG_SHIFT 0 /* DC1_VIMG - [6:0] */
-#define WM8400_DC1_VIMG_WIDTH 7 /* DC1_VIMG - [6:0] */
-
-/*
- * R72 (0x48) - DCDC2 Control 1
- */
-#define WM8400_DC2_ENA 0x8000 /* DC2_ENA */
-#define WM8400_DC2_ENA_MASK 0x8000 /* DC2_ENA */
-#define WM8400_DC2_ENA_SHIFT 15 /* DC2_ENA */
-#define WM8400_DC2_ENA_WIDTH 1 /* DC2_ENA */
-#define WM8400_DC2_ACTIVE 0x4000 /* DC2_ACTIVE */
-#define WM8400_DC2_ACTIVE_MASK 0x4000 /* DC2_ACTIVE */
-#define WM8400_DC2_ACTIVE_SHIFT 14 /* DC2_ACTIVE */
-#define WM8400_DC2_ACTIVE_WIDTH 1 /* DC2_ACTIVE */
-#define WM8400_DC2_SLEEP 0x2000 /* DC2_SLEEP */
-#define WM8400_DC2_SLEEP_MASK 0x2000 /* DC2_SLEEP */
-#define WM8400_DC2_SLEEP_SHIFT 13 /* DC2_SLEEP */
-#define WM8400_DC2_SLEEP_WIDTH 1 /* DC2_SLEEP */
-#define WM8400_DC2_OPFLT 0x1000 /* DC2_OPFLT */
-#define WM8400_DC2_OPFLT_MASK 0x1000 /* DC2_OPFLT */
-#define WM8400_DC2_OPFLT_SHIFT 12 /* DC2_OPFLT */
-#define WM8400_DC2_OPFLT_WIDTH 1 /* DC2_OPFLT */
-#define WM8400_DC2_ERRACT 0x0800 /* DC2_ERRACT */
-#define WM8400_DC2_ERRACT_MASK 0x0800 /* DC2_ERRACT */
-#define WM8400_DC2_ERRACT_SHIFT 11 /* DC2_ERRACT */
-#define WM8400_DC2_ERRACT_WIDTH 1 /* DC2_ERRACT */
-#define WM8400_DC2_HIB_MODE 0x0400 /* DC2_HIB_MODE */
-#define WM8400_DC2_HIB_MODE_MASK 0x0400 /* DC2_HIB_MODE */
-#define WM8400_DC2_HIB_MODE_SHIFT 10 /* DC2_HIB_MODE */
-#define WM8400_DC2_HIB_MODE_WIDTH 1 /* DC2_HIB_MODE */
-#define WM8400_DC2_SOFTST_MASK 0x0300 /* DC2_SOFTST - [9:8] */
-#define WM8400_DC2_SOFTST_SHIFT 8 /* DC2_SOFTST - [9:8] */
-#define WM8400_DC2_SOFTST_WIDTH 2 /* DC2_SOFTST - [9:8] */
-#define WM8400_DC2_OV_PROT 0x0080 /* DC2_OV_PROT */
-#define WM8400_DC2_OV_PROT_MASK 0x0080 /* DC2_OV_PROT */
-#define WM8400_DC2_OV_PROT_SHIFT 7 /* DC2_OV_PROT */
-#define WM8400_DC2_OV_PROT_WIDTH 1 /* DC2_OV_PROT */
-#define WM8400_DC2_VSEL_MASK 0x007F /* DC2_VSEL - [6:0] */
-#define WM8400_DC2_VSEL_SHIFT 0 /* DC2_VSEL - [6:0] */
-#define WM8400_DC2_VSEL_WIDTH 7 /* DC2_VSEL - [6:0] */
-
-/*
- * R73 (0x49) - DCDC2 Control 2
- */
-#define WM8400_DC2_FRC_PWM 0x2000 /* DC2_FRC_PWM */
-#define WM8400_DC2_FRC_PWM_MASK 0x2000 /* DC2_FRC_PWM */
-#define WM8400_DC2_FRC_PWM_SHIFT 13 /* DC2_FRC_PWM */
-#define WM8400_DC2_FRC_PWM_WIDTH 1 /* DC2_FRC_PWM */
-#define WM8400_DC2_STBY_LIM_MASK 0x0300 /* DC2_STBY_LIM - [9:8] */
-#define WM8400_DC2_STBY_LIM_SHIFT 8 /* DC2_STBY_LIM - [9:8] */
-#define WM8400_DC2_STBY_LIM_WIDTH 2 /* DC2_STBY_LIM - [9:8] */
-#define WM8400_DC2_ACT_LIM 0x0080 /* DC2_ACT_LIM */
-#define WM8400_DC2_ACT_LIM_MASK 0x0080 /* DC2_ACT_LIM */
-#define WM8400_DC2_ACT_LIM_SHIFT 7 /* DC2_ACT_LIM */
-#define WM8400_DC2_ACT_LIM_WIDTH 1 /* DC2_ACT_LIM */
-#define WM8400_DC2_VIMG_MASK 0x007F /* DC2_VIMG - [6:0] */
-#define WM8400_DC2_VIMG_SHIFT 0 /* DC2_VIMG - [6:0] */
-#define WM8400_DC2_VIMG_WIDTH 7 /* DC2_VIMG - [6:0] */
-
-/*
- * R75 (0x4B) - Interface
- */
-#define WM8400_AUTOINC 0x0008 /* AUTOINC */
-#define WM8400_AUTOINC_MASK 0x0008 /* AUTOINC */
-#define WM8400_AUTOINC_SHIFT 3 /* AUTOINC */
-#define WM8400_AUTOINC_WIDTH 1 /* AUTOINC */
-#define WM8400_ARA_ENA 0x0004 /* ARA_ENA */
-#define WM8400_ARA_ENA_MASK 0x0004 /* ARA_ENA */
-#define WM8400_ARA_ENA_SHIFT 2 /* ARA_ENA */
-#define WM8400_ARA_ENA_WIDTH 1 /* ARA_ENA */
-#define WM8400_SPI_CFG 0x0002 /* SPI_CFG */
-#define WM8400_SPI_CFG_MASK 0x0002 /* SPI_CFG */
-#define WM8400_SPI_CFG_SHIFT 1 /* SPI_CFG */
-#define WM8400_SPI_CFG_WIDTH 1 /* SPI_CFG */
-
-/*
- * R76 (0x4C) - PM GENERAL
- */
-#define WM8400_CODEC_SOFTST 0x8000 /* CODEC_SOFTST */
-#define WM8400_CODEC_SOFTST_MASK 0x8000 /* CODEC_SOFTST */
-#define WM8400_CODEC_SOFTST_SHIFT 15 /* CODEC_SOFTST */
-#define WM8400_CODEC_SOFTST_WIDTH 1 /* CODEC_SOFTST */
-#define WM8400_CODEC_SOFTSD 0x4000 /* CODEC_SOFTSD */
-#define WM8400_CODEC_SOFTSD_MASK 0x4000 /* CODEC_SOFTSD */
-#define WM8400_CODEC_SOFTSD_SHIFT 14 /* CODEC_SOFTSD */
-#define WM8400_CODEC_SOFTSD_WIDTH 1 /* CODEC_SOFTSD */
-#define WM8400_CHIP_SOFTSD 0x2000 /* CHIP_SOFTSD */
-#define WM8400_CHIP_SOFTSD_MASK 0x2000 /* CHIP_SOFTSD */
-#define WM8400_CHIP_SOFTSD_SHIFT 13 /* CHIP_SOFTSD */
-#define WM8400_CHIP_SOFTSD_WIDTH 1 /* CHIP_SOFTSD */
-#define WM8400_DSLEEP1_POL 0x0008 /* DSLEEP1_POL */
-#define WM8400_DSLEEP1_POL_MASK 0x0008 /* DSLEEP1_POL */
-#define WM8400_DSLEEP1_POL_SHIFT 3 /* DSLEEP1_POL */
-#define WM8400_DSLEEP1_POL_WIDTH 1 /* DSLEEP1_POL */
-#define WM8400_DSLEEP2_POL 0x0004 /* DSLEEP2_POL */
-#define WM8400_DSLEEP2_POL_MASK 0x0004 /* DSLEEP2_POL */
-#define WM8400_DSLEEP2_POL_SHIFT 2 /* DSLEEP2_POL */
-#define WM8400_DSLEEP2_POL_WIDTH 1 /* DSLEEP2_POL */
-#define WM8400_PWR_STATE_MASK 0x0003 /* PWR_STATE - [1:0] */
-#define WM8400_PWR_STATE_SHIFT 0 /* PWR_STATE - [1:0] */
-#define WM8400_PWR_STATE_WIDTH 2 /* PWR_STATE - [1:0] */
-
-/*
- * R78 (0x4E) - PM Shutdown Control
- */
-#define WM8400_CHIP_GT150_ERRACT 0x0200 /* CHIP_GT150_ERRACT */
-#define WM8400_CHIP_GT150_ERRACT_MASK 0x0200 /* CHIP_GT150_ERRACT */
-#define WM8400_CHIP_GT150_ERRACT_SHIFT 9 /* CHIP_GT150_ERRACT */
-#define WM8400_CHIP_GT150_ERRACT_WIDTH 1 /* CHIP_GT150_ERRACT */
-#define WM8400_CHIP_GT115_ERRACT 0x0100 /* CHIP_GT115_ERRACT */
-#define WM8400_CHIP_GT115_ERRACT_MASK 0x0100 /* CHIP_GT115_ERRACT */
-#define WM8400_CHIP_GT115_ERRACT_SHIFT 8 /* CHIP_GT115_ERRACT */
-#define WM8400_CHIP_GT115_ERRACT_WIDTH 1 /* CHIP_GT115_ERRACT */
-#define WM8400_LINE_CMP_ERRACT 0x0080 /* LINE_CMP_ERRACT */
-#define WM8400_LINE_CMP_ERRACT_MASK 0x0080 /* LINE_CMP_ERRACT */
-#define WM8400_LINE_CMP_ERRACT_SHIFT 7 /* LINE_CMP_ERRACT */
-#define WM8400_LINE_CMP_ERRACT_WIDTH 1 /* LINE_CMP_ERRACT */
-#define WM8400_UVLO_ERRACT 0x0040 /* UVLO_ERRACT */
-#define WM8400_UVLO_ERRACT_MASK 0x0040 /* UVLO_ERRACT */
-#define WM8400_UVLO_ERRACT_SHIFT 6 /* UVLO_ERRACT */
-#define WM8400_UVLO_ERRACT_WIDTH 1 /* UVLO_ERRACT */
-
-/*
- * R79 (0x4F) - Interrupt Status 1
- */
-#define WM8400_MICD_CINT 0x8000 /* MICD_CINT */
-#define WM8400_MICD_CINT_MASK 0x8000 /* MICD_CINT */
-#define WM8400_MICD_CINT_SHIFT 15 /* MICD_CINT */
-#define WM8400_MICD_CINT_WIDTH 1 /* MICD_CINT */
-#define WM8400_MICSCD_CINT 0x4000 /* MICSCD_CINT */
-#define WM8400_MICSCD_CINT_MASK 0x4000 /* MICSCD_CINT */
-#define WM8400_MICSCD_CINT_SHIFT 14 /* MICSCD_CINT */
-#define WM8400_MICSCD_CINT_WIDTH 1 /* MICSCD_CINT */
-#define WM8400_JDL_CINT 0x2000 /* JDL_CINT */
-#define WM8400_JDL_CINT_MASK 0x2000 /* JDL_CINT */
-#define WM8400_JDL_CINT_SHIFT 13 /* JDL_CINT */
-#define WM8400_JDL_CINT_WIDTH 1 /* JDL_CINT */
-#define WM8400_JDR_CINT 0x1000 /* JDR_CINT */
-#define WM8400_JDR_CINT_MASK 0x1000 /* JDR_CINT */
-#define WM8400_JDR_CINT_SHIFT 12 /* JDR_CINT */
-#define WM8400_JDR_CINT_WIDTH 1 /* JDR_CINT */
-#define WM8400_CODEC_SEQ_END_EINT 0x0800 /* CODEC_SEQ_END_EINT */
-#define WM8400_CODEC_SEQ_END_EINT_MASK 0x0800 /* CODEC_SEQ_END_EINT */
-#define WM8400_CODEC_SEQ_END_EINT_SHIFT 11 /* CODEC_SEQ_END_EINT */
-#define WM8400_CODEC_SEQ_END_EINT_WIDTH 1 /* CODEC_SEQ_END_EINT */
-#define WM8400_CDEL_TO_EINT 0x0400 /* CDEL_TO_EINT */
-#define WM8400_CDEL_TO_EINT_MASK 0x0400 /* CDEL_TO_EINT */
-#define WM8400_CDEL_TO_EINT_SHIFT 10 /* CDEL_TO_EINT */
-#define WM8400_CDEL_TO_EINT_WIDTH 1 /* CDEL_TO_EINT */
-#define WM8400_CHIP_GT150_EINT 0x0200 /* CHIP_GT150_EINT */
-#define WM8400_CHIP_GT150_EINT_MASK 0x0200 /* CHIP_GT150_EINT */
-#define WM8400_CHIP_GT150_EINT_SHIFT 9 /* CHIP_GT150_EINT */
-#define WM8400_CHIP_GT150_EINT_WIDTH 1 /* CHIP_GT150_EINT */
-#define WM8400_CHIP_GT115_EINT 0x0100 /* CHIP_GT115_EINT */
-#define WM8400_CHIP_GT115_EINT_MASK 0x0100 /* CHIP_GT115_EINT */
-#define WM8400_CHIP_GT115_EINT_SHIFT 8 /* CHIP_GT115_EINT */
-#define WM8400_CHIP_GT115_EINT_WIDTH 1 /* CHIP_GT115_EINT */
-#define WM8400_LINE_CMP_EINT 0x0080 /* LINE_CMP_EINT */
-#define WM8400_LINE_CMP_EINT_MASK 0x0080 /* LINE_CMP_EINT */
-#define WM8400_LINE_CMP_EINT_SHIFT 7 /* LINE_CMP_EINT */
-#define WM8400_LINE_CMP_EINT_WIDTH 1 /* LINE_CMP_EINT */
-#define WM8400_UVLO_EINT 0x0040 /* UVLO_EINT */
-#define WM8400_UVLO_EINT_MASK 0x0040 /* UVLO_EINT */
-#define WM8400_UVLO_EINT_SHIFT 6 /* UVLO_EINT */
-#define WM8400_UVLO_EINT_WIDTH 1 /* UVLO_EINT */
-#define WM8400_DC2_UV_EINT 0x0020 /* DC2_UV_EINT */
-#define WM8400_DC2_UV_EINT_MASK 0x0020 /* DC2_UV_EINT */
-#define WM8400_DC2_UV_EINT_SHIFT 5 /* DC2_UV_EINT */
-#define WM8400_DC2_UV_EINT_WIDTH 1 /* DC2_UV_EINT */
-#define WM8400_DC1_UV_EINT 0x0010 /* DC1_UV_EINT */
-#define WM8400_DC1_UV_EINT_MASK 0x0010 /* DC1_UV_EINT */
-#define WM8400_DC1_UV_EINT_SHIFT 4 /* DC1_UV_EINT */
-#define WM8400_DC1_UV_EINT_WIDTH 1 /* DC1_UV_EINT */
-#define WM8400_LDO4_UV_EINT 0x0008 /* LDO4_UV_EINT */
-#define WM8400_LDO4_UV_EINT_MASK 0x0008 /* LDO4_UV_EINT */
-#define WM8400_LDO4_UV_EINT_SHIFT 3 /* LDO4_UV_EINT */
-#define WM8400_LDO4_UV_EINT_WIDTH 1 /* LDO4_UV_EINT */
-#define WM8400_LDO3_UV_EINT 0x0004 /* LDO3_UV_EINT */
-#define WM8400_LDO3_UV_EINT_MASK 0x0004 /* LDO3_UV_EINT */
-#define WM8400_LDO3_UV_EINT_SHIFT 2 /* LDO3_UV_EINT */
-#define WM8400_LDO3_UV_EINT_WIDTH 1 /* LDO3_UV_EINT */
-#define WM8400_LDO2_UV_EINT 0x0002 /* LDO2_UV_EINT */
-#define WM8400_LDO2_UV_EINT_MASK 0x0002 /* LDO2_UV_EINT */
-#define WM8400_LDO2_UV_EINT_SHIFT 1 /* LDO2_UV_EINT */
-#define WM8400_LDO2_UV_EINT_WIDTH 1 /* LDO2_UV_EINT */
-#define WM8400_LDO1_UV_EINT 0x0001 /* LDO1_UV_EINT */
-#define WM8400_LDO1_UV_EINT_MASK 0x0001 /* LDO1_UV_EINT */
-#define WM8400_LDO1_UV_EINT_SHIFT 0 /* LDO1_UV_EINT */
-#define WM8400_LDO1_UV_EINT_WIDTH 1 /* LDO1_UV_EINT */
-
-/*
- * R80 (0x50) - Interrupt Status 1 Mask
- */
-#define WM8400_IM_MICD_CINT 0x8000 /* IM_MICD_CINT */
-#define WM8400_IM_MICD_CINT_MASK 0x8000 /* IM_MICD_CINT */
-#define WM8400_IM_MICD_CINT_SHIFT 15 /* IM_MICD_CINT */
-#define WM8400_IM_MICD_CINT_WIDTH 1 /* IM_MICD_CINT */
-#define WM8400_IM_MICSCD_CINT 0x4000 /* IM_MICSCD_CINT */
-#define WM8400_IM_MICSCD_CINT_MASK 0x4000 /* IM_MICSCD_CINT */
-#define WM8400_IM_MICSCD_CINT_SHIFT 14 /* IM_MICSCD_CINT */
-#define WM8400_IM_MICSCD_CINT_WIDTH 1 /* IM_MICSCD_CINT */
-#define WM8400_IM_JDL_CINT 0x2000 /* IM_JDL_CINT */
-#define WM8400_IM_JDL_CINT_MASK 0x2000 /* IM_JDL_CINT */
-#define WM8400_IM_JDL_CINT_SHIFT 13 /* IM_JDL_CINT */
-#define WM8400_IM_JDL_CINT_WIDTH 1 /* IM_JDL_CINT */
-#define WM8400_IM_JDR_CINT 0x1000 /* IM_JDR_CINT */
-#define WM8400_IM_JDR_CINT_MASK 0x1000 /* IM_JDR_CINT */
-#define WM8400_IM_JDR_CINT_SHIFT 12 /* IM_JDR_CINT */
-#define WM8400_IM_JDR_CINT_WIDTH 1 /* IM_JDR_CINT */
-#define WM8400_IM_CODEC_SEQ_END_EINT 0x0800 /* IM_CODEC_SEQ_END_EINT */
-#define WM8400_IM_CODEC_SEQ_END_EINT_MASK 0x0800 /* IM_CODEC_SEQ_END_EINT */
-#define WM8400_IM_CODEC_SEQ_END_EINT_SHIFT 11 /* IM_CODEC_SEQ_END_EINT */
-#define WM8400_IM_CODEC_SEQ_END_EINT_WIDTH 1 /* IM_CODEC_SEQ_END_EINT */
-#define WM8400_IM_CDEL_TO_EINT 0x0400 /* IM_CDEL_TO_EINT */
-#define WM8400_IM_CDEL_TO_EINT_MASK 0x0400 /* IM_CDEL_TO_EINT */
-#define WM8400_IM_CDEL_TO_EINT_SHIFT 10 /* IM_CDEL_TO_EINT */
-#define WM8400_IM_CDEL_TO_EINT_WIDTH 1 /* IM_CDEL_TO_EINT */
-#define WM8400_IM_CHIP_GT150_EINT 0x0200 /* IM_CHIP_GT150_EINT */
-#define WM8400_IM_CHIP_GT150_EINT_MASK 0x0200 /* IM_CHIP_GT150_EINT */
-#define WM8400_IM_CHIP_GT150_EINT_SHIFT 9 /* IM_CHIP_GT150_EINT */
-#define WM8400_IM_CHIP_GT150_EINT_WIDTH 1 /* IM_CHIP_GT150_EINT */
-#define WM8400_IM_CHIP_GT115_EINT 0x0100 /* IM_CHIP_GT115_EINT */
-#define WM8400_IM_CHIP_GT115_EINT_MASK 0x0100 /* IM_CHIP_GT115_EINT */
-#define WM8400_IM_CHIP_GT115_EINT_SHIFT 8 /* IM_CHIP_GT115_EINT */
-#define WM8400_IM_CHIP_GT115_EINT_WIDTH 1 /* IM_CHIP_GT115_EINT */
-#define WM8400_IM_LINE_CMP_EINT 0x0080 /* IM_LINE_CMP_EINT */
-#define WM8400_IM_LINE_CMP_EINT_MASK 0x0080 /* IM_LINE_CMP_EINT */
-#define WM8400_IM_LINE_CMP_EINT_SHIFT 7 /* IM_LINE_CMP_EINT */
-#define WM8400_IM_LINE_CMP_EINT_WIDTH 1 /* IM_LINE_CMP_EINT */
-#define WM8400_IM_UVLO_EINT 0x0040 /* IM_UVLO_EINT */
-#define WM8400_IM_UVLO_EINT_MASK 0x0040 /* IM_UVLO_EINT */
-#define WM8400_IM_UVLO_EINT_SHIFT 6 /* IM_UVLO_EINT */
-#define WM8400_IM_UVLO_EINT_WIDTH 1 /* IM_UVLO_EINT */
-#define WM8400_IM_DC2_UV_EINT 0x0020 /* IM_DC2_UV_EINT */
-#define WM8400_IM_DC2_UV_EINT_MASK 0x0020 /* IM_DC2_UV_EINT */
-#define WM8400_IM_DC2_UV_EINT_SHIFT 5 /* IM_DC2_UV_EINT */
-#define WM8400_IM_DC2_UV_EINT_WIDTH 1 /* IM_DC2_UV_EINT */
-#define WM8400_IM_DC1_UV_EINT 0x0010 /* IM_DC1_UV_EINT */
-#define WM8400_IM_DC1_UV_EINT_MASK 0x0010 /* IM_DC1_UV_EINT */
-#define WM8400_IM_DC1_UV_EINT_SHIFT 4 /* IM_DC1_UV_EINT */
-#define WM8400_IM_DC1_UV_EINT_WIDTH 1 /* IM_DC1_UV_EINT */
-#define WM8400_IM_LDO4_UV_EINT 0x0008 /* IM_LDO4_UV_EINT */
-#define WM8400_IM_LDO4_UV_EINT_MASK 0x0008 /* IM_LDO4_UV_EINT */
-#define WM8400_IM_LDO4_UV_EINT_SHIFT 3 /* IM_LDO4_UV_EINT */
-#define WM8400_IM_LDO4_UV_EINT_WIDTH 1 /* IM_LDO4_UV_EINT */
-#define WM8400_IM_LDO3_UV_EINT 0x0004 /* IM_LDO3_UV_EINT */
-#define WM8400_IM_LDO3_UV_EINT_MASK 0x0004 /* IM_LDO3_UV_EINT */
-#define WM8400_IM_LDO3_UV_EINT_SHIFT 2 /* IM_LDO3_UV_EINT */
-#define WM8400_IM_LDO3_UV_EINT_WIDTH 1 /* IM_LDO3_UV_EINT */
-#define WM8400_IM_LDO2_UV_EINT 0x0002 /* IM_LDO2_UV_EINT */
-#define WM8400_IM_LDO2_UV_EINT_MASK 0x0002 /* IM_LDO2_UV_EINT */
-#define WM8400_IM_LDO2_UV_EINT_SHIFT 1 /* IM_LDO2_UV_EINT */
-#define WM8400_IM_LDO2_UV_EINT_WIDTH 1 /* IM_LDO2_UV_EINT */
-#define WM8400_IM_LDO1_UV_EINT 0x0001 /* IM_LDO1_UV_EINT */
-#define WM8400_IM_LDO1_UV_EINT_MASK 0x0001 /* IM_LDO1_UV_EINT */
-#define WM8400_IM_LDO1_UV_EINT_SHIFT 0 /* IM_LDO1_UV_EINT */
-#define WM8400_IM_LDO1_UV_EINT_WIDTH 1 /* IM_LDO1_UV_EINT */
-
-/*
- * R81 (0x51) - Interrupt Levels
- */
-#define WM8400_MICD_LVL 0x8000 /* MICD_LVL */
-#define WM8400_MICD_LVL_MASK 0x8000 /* MICD_LVL */
-#define WM8400_MICD_LVL_SHIFT 15 /* MICD_LVL */
-#define WM8400_MICD_LVL_WIDTH 1 /* MICD_LVL */
-#define WM8400_MICSCD_LVL 0x4000 /* MICSCD_LVL */
-#define WM8400_MICSCD_LVL_MASK 0x4000 /* MICSCD_LVL */
-#define WM8400_MICSCD_LVL_SHIFT 14 /* MICSCD_LVL */
-#define WM8400_MICSCD_LVL_WIDTH 1 /* MICSCD_LVL */
-#define WM8400_JDL_LVL 0x2000 /* JDL_LVL */
-#define WM8400_JDL_LVL_MASK 0x2000 /* JDL_LVL */
-#define WM8400_JDL_LVL_SHIFT 13 /* JDL_LVL */
-#define WM8400_JDL_LVL_WIDTH 1 /* JDL_LVL */
-#define WM8400_JDR_LVL 0x1000 /* JDR_LVL */
-#define WM8400_JDR_LVL_MASK 0x1000 /* JDR_LVL */
-#define WM8400_JDR_LVL_SHIFT 12 /* JDR_LVL */
-#define WM8400_JDR_LVL_WIDTH 1 /* JDR_LVL */
-#define WM8400_CODEC_SEQ_END_LVL 0x0800 /* CODEC_SEQ_END_LVL */
-#define WM8400_CODEC_SEQ_END_LVL_MASK 0x0800 /* CODEC_SEQ_END_LVL */
-#define WM8400_CODEC_SEQ_END_LVL_SHIFT 11 /* CODEC_SEQ_END_LVL */
-#define WM8400_CODEC_SEQ_END_LVL_WIDTH 1 /* CODEC_SEQ_END_LVL */
-#define WM8400_CDEL_TO_LVL 0x0400 /* CDEL_TO_LVL */
-#define WM8400_CDEL_TO_LVL_MASK 0x0400 /* CDEL_TO_LVL */
-#define WM8400_CDEL_TO_LVL_SHIFT 10 /* CDEL_TO_LVL */
-#define WM8400_CDEL_TO_LVL_WIDTH 1 /* CDEL_TO_LVL */
-#define WM8400_CHIP_GT150_LVL 0x0200 /* CHIP_GT150_LVL */
-#define WM8400_CHIP_GT150_LVL_MASK 0x0200 /* CHIP_GT150_LVL */
-#define WM8400_CHIP_GT150_LVL_SHIFT 9 /* CHIP_GT150_LVL */
-#define WM8400_CHIP_GT150_LVL_WIDTH 1 /* CHIP_GT150_LVL */
-#define WM8400_CHIP_GT115_LVL 0x0100 /* CHIP_GT115_LVL */
-#define WM8400_CHIP_GT115_LVL_MASK 0x0100 /* CHIP_GT115_LVL */
-#define WM8400_CHIP_GT115_LVL_SHIFT 8 /* CHIP_GT115_LVL */
-#define WM8400_CHIP_GT115_LVL_WIDTH 1 /* CHIP_GT115_LVL */
-#define WM8400_LINE_CMP_LVL 0x0080 /* LINE_CMP_LVL */
-#define WM8400_LINE_CMP_LVL_MASK 0x0080 /* LINE_CMP_LVL */
-#define WM8400_LINE_CMP_LVL_SHIFT 7 /* LINE_CMP_LVL */
-#define WM8400_LINE_CMP_LVL_WIDTH 1 /* LINE_CMP_LVL */
-#define WM8400_UVLO_LVL 0x0040 /* UVLO_LVL */
-#define WM8400_UVLO_LVL_MASK 0x0040 /* UVLO_LVL */
-#define WM8400_UVLO_LVL_SHIFT 6 /* UVLO_LVL */
-#define WM8400_UVLO_LVL_WIDTH 1 /* UVLO_LVL */
-#define WM8400_DC2_UV_LVL 0x0020 /* DC2_UV_LVL */
-#define WM8400_DC2_UV_LVL_MASK 0x0020 /* DC2_UV_LVL */
-#define WM8400_DC2_UV_LVL_SHIFT 5 /* DC2_UV_LVL */
-#define WM8400_DC2_UV_LVL_WIDTH 1 /* DC2_UV_LVL */
-#define WM8400_DC1_UV_LVL 0x0010 /* DC1_UV_LVL */
-#define WM8400_DC1_UV_LVL_MASK 0x0010 /* DC1_UV_LVL */
-#define WM8400_DC1_UV_LVL_SHIFT 4 /* DC1_UV_LVL */
-#define WM8400_DC1_UV_LVL_WIDTH 1 /* DC1_UV_LVL */
-#define WM8400_LDO4_UV_LVL 0x0008 /* LDO4_UV_LVL */
-#define WM8400_LDO4_UV_LVL_MASK 0x0008 /* LDO4_UV_LVL */
-#define WM8400_LDO4_UV_LVL_SHIFT 3 /* LDO4_UV_LVL */
-#define WM8400_LDO4_UV_LVL_WIDTH 1 /* LDO4_UV_LVL */
-#define WM8400_LDO3_UV_LVL 0x0004 /* LDO3_UV_LVL */
-#define WM8400_LDO3_UV_LVL_MASK 0x0004 /* LDO3_UV_LVL */
-#define WM8400_LDO3_UV_LVL_SHIFT 2 /* LDO3_UV_LVL */
-#define WM8400_LDO3_UV_LVL_WIDTH 1 /* LDO3_UV_LVL */
-#define WM8400_LDO2_UV_LVL 0x0002 /* LDO2_UV_LVL */
-#define WM8400_LDO2_UV_LVL_MASK 0x0002 /* LDO2_UV_LVL */
-#define WM8400_LDO2_UV_LVL_SHIFT 1 /* LDO2_UV_LVL */
-#define WM8400_LDO2_UV_LVL_WIDTH 1 /* LDO2_UV_LVL */
-#define WM8400_LDO1_UV_LVL 0x0001 /* LDO1_UV_LVL */
-#define WM8400_LDO1_UV_LVL_MASK 0x0001 /* LDO1_UV_LVL */
-#define WM8400_LDO1_UV_LVL_SHIFT 0 /* LDO1_UV_LVL */
-#define WM8400_LDO1_UV_LVL_WIDTH 1 /* LDO1_UV_LVL */
-
-/*
- * R82 (0x52) - Shutdown Reason
- */
-#define WM8400_SDR_CHIP_SOFTSD 0x2000 /* SDR_CHIP_SOFTSD */
-#define WM8400_SDR_CHIP_SOFTSD_MASK 0x2000 /* SDR_CHIP_SOFTSD */
-#define WM8400_SDR_CHIP_SOFTSD_SHIFT 13 /* SDR_CHIP_SOFTSD */
-#define WM8400_SDR_CHIP_SOFTSD_WIDTH 1 /* SDR_CHIP_SOFTSD */
-#define WM8400_SDR_NPDN 0x0800 /* SDR_NPDN */
-#define WM8400_SDR_NPDN_MASK 0x0800 /* SDR_NPDN */
-#define WM8400_SDR_NPDN_SHIFT 11 /* SDR_NPDN */
-#define WM8400_SDR_NPDN_WIDTH 1 /* SDR_NPDN */
-#define WM8400_SDR_CHIP_GT150 0x0200 /* SDR_CHIP_GT150 */
-#define WM8400_SDR_CHIP_GT150_MASK 0x0200 /* SDR_CHIP_GT150 */
-#define WM8400_SDR_CHIP_GT150_SHIFT 9 /* SDR_CHIP_GT150 */
-#define WM8400_SDR_CHIP_GT150_WIDTH 1 /* SDR_CHIP_GT150 */
-#define WM8400_SDR_CHIP_GT115 0x0100 /* SDR_CHIP_GT115 */
-#define WM8400_SDR_CHIP_GT115_MASK 0x0100 /* SDR_CHIP_GT115 */
-#define WM8400_SDR_CHIP_GT115_SHIFT 8 /* SDR_CHIP_GT115 */
-#define WM8400_SDR_CHIP_GT115_WIDTH 1 /* SDR_CHIP_GT115 */
-#define WM8400_SDR_LINE_CMP 0x0080 /* SDR_LINE_CMP */
-#define WM8400_SDR_LINE_CMP_MASK 0x0080 /* SDR_LINE_CMP */
-#define WM8400_SDR_LINE_CMP_SHIFT 7 /* SDR_LINE_CMP */
-#define WM8400_SDR_LINE_CMP_WIDTH 1 /* SDR_LINE_CMP */
-#define WM8400_SDR_UVLO 0x0040 /* SDR_UVLO */
-#define WM8400_SDR_UVLO_MASK 0x0040 /* SDR_UVLO */
-#define WM8400_SDR_UVLO_SHIFT 6 /* SDR_UVLO */
-#define WM8400_SDR_UVLO_WIDTH 1 /* SDR_UVLO */
-#define WM8400_SDR_DC2_UV 0x0020 /* SDR_DC2_UV */
-#define WM8400_SDR_DC2_UV_MASK 0x0020 /* SDR_DC2_UV */
-#define WM8400_SDR_DC2_UV_SHIFT 5 /* SDR_DC2_UV */
-#define WM8400_SDR_DC2_UV_WIDTH 1 /* SDR_DC2_UV */
-#define WM8400_SDR_DC1_UV 0x0010 /* SDR_DC1_UV */
-#define WM8400_SDR_DC1_UV_MASK 0x0010 /* SDR_DC1_UV */
-#define WM8400_SDR_DC1_UV_SHIFT 4 /* SDR_DC1_UV */
-#define WM8400_SDR_DC1_UV_WIDTH 1 /* SDR_DC1_UV */
-#define WM8400_SDR_LDO4_UV 0x0008 /* SDR_LDO4_UV */
-#define WM8400_SDR_LDO4_UV_MASK 0x0008 /* SDR_LDO4_UV */
-#define WM8400_SDR_LDO4_UV_SHIFT 3 /* SDR_LDO4_UV */
-#define WM8400_SDR_LDO4_UV_WIDTH 1 /* SDR_LDO4_UV */
-#define WM8400_SDR_LDO3_UV 0x0004 /* SDR_LDO3_UV */
-#define WM8400_SDR_LDO3_UV_MASK 0x0004 /* SDR_LDO3_UV */
-#define WM8400_SDR_LDO3_UV_SHIFT 2 /* SDR_LDO3_UV */
-#define WM8400_SDR_LDO3_UV_WIDTH 1 /* SDR_LDO3_UV */
-#define WM8400_SDR_LDO2_UV 0x0002 /* SDR_LDO2_UV */
-#define WM8400_SDR_LDO2_UV_MASK 0x0002 /* SDR_LDO2_UV */
-#define WM8400_SDR_LDO2_UV_SHIFT 1 /* SDR_LDO2_UV */
-#define WM8400_SDR_LDO2_UV_WIDTH 1 /* SDR_LDO2_UV */
-#define WM8400_SDR_LDO1_UV 0x0001 /* SDR_LDO1_UV */
-#define WM8400_SDR_LDO1_UV_MASK 0x0001 /* SDR_LDO1_UV */
-#define WM8400_SDR_LDO1_UV_SHIFT 0 /* SDR_LDO1_UV */
-#define WM8400_SDR_LDO1_UV_WIDTH 1 /* SDR_LDO1_UV */
-
-/*
- * R84 (0x54) - Line Circuits
- */
-#define WM8400_BG_LINE_COMP 0x8000 /* BG_LINE_COMP */
-#define WM8400_BG_LINE_COMP_MASK 0x8000 /* BG_LINE_COMP */
-#define WM8400_BG_LINE_COMP_SHIFT 15 /* BG_LINE_COMP */
-#define WM8400_BG_LINE_COMP_WIDTH 1 /* BG_LINE_COMP */
-#define WM8400_LINE_CMP_VTHI_MASK 0x00F0 /* LINE_CMP_VTHI - [7:4] */
-#define WM8400_LINE_CMP_VTHI_SHIFT 4 /* LINE_CMP_VTHI - [7:4] */
-#define WM8400_LINE_CMP_VTHI_WIDTH 4 /* LINE_CMP_VTHI - [7:4] */
-#define WM8400_LINE_CMP_VTHD_MASK 0x000F /* LINE_CMP_VTHD - [3:0] */
-#define WM8400_LINE_CMP_VTHD_SHIFT 0 /* LINE_CMP_VTHD - [3:0] */
-#define WM8400_LINE_CMP_VTHD_WIDTH 4 /* LINE_CMP_VTHD - [3:0] */
-
-#endif
diff --git a/include/linux/mfd/wm8400.h b/include/linux/mfd/wm8400.h
deleted file mode 100644
index a812d89e7cb3..000000000000
--- a/include/linux/mfd/wm8400.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * wm8400 client interface
- *
- * Copyright 2008 Wolfson Microelectronics plc
- */
-
-#ifndef __LINUX_MFD_WM8400_H
-#define __LINUX_MFD_WM8400_H
-
-#include <linux/regulator/machine.h>
-
-#define WM8400_LDO1 0
-#define WM8400_LDO2 1
-#define WM8400_LDO3 2
-#define WM8400_LDO4 3
-#define WM8400_DCDC1 4
-#define WM8400_DCDC2 5
-
-struct wm8400_platform_data {
- int (*platform_init)(struct device *dev);
-};
-
-int wm8400_register_regulator(struct device *dev, int reg,
- struct regulator_init_data *initdata);
-
-#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1f7dc2c7e338..422e50ee0560 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -318,7 +318,6 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_WM5102
imply SND_SOC_WM5110
imply SND_SOC_WM8350
- imply SND_SOC_WM8400
imply SND_SOC_WM8510
imply SND_SOC_WM8523
imply SND_SOC_WM8524
@@ -2556,11 +2555,6 @@ config SND_SOC_WM8350
tristate
depends on MFD_WM8350
-config SND_SOC_WM8400
- tristate
- # FIXME nothing selects SND_SOC_WM8400??
- depends on MFD_WM8400
-
config SND_SOC_WM8510
tristate "Wolfson Microelectronics WM8510 CODEC"
depends on SND_SOC_I2C_AND_SPI
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f4f20a8e112e..3fc78f3b44ba 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -375,7 +375,6 @@ snd-soc-wm5100-y := wm5100.o wm5100-tables.o
snd-soc-wm5102-y := wm5102.o
snd-soc-wm5110-y := wm5110.o
snd-soc-wm8350-y := wm8350.o
-snd-soc-wm8400-y := wm8400.o
snd-soc-wm8510-y := wm8510.o
snd-soc-wm8523-y := wm8523.o
snd-soc-wm8524-y := wm8524.o
@@ -825,7 +824,6 @@ obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
obj-$(CONFIG_SND_SOC_WM5102) += snd-soc-wm5102.o
obj-$(CONFIG_SND_SOC_WM5110) += snd-soc-wm5110.o
obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
-obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
obj-$(CONFIG_SND_SOC_WM8524) += snd-soc-wm8524.o
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
deleted file mode 100644
index 0eecc8657a38..000000000000
--- a/sound/soc/codecs/wm8400.c
+++ /dev/null
@@ -1,1348 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * wm8400.c -- WM8400 ALSA Soc Audio driver
- *
- * Copyright 2008-11 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/mfd/wm8400-audio.h>
-#include <linux/mfd/wm8400-private.h>
-#include <linux/mfd/core.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8400.h"
-
-static struct regulator_bulk_data power[] = {
- {
- .supply = "I2S1VDD",
- },
- {
- .supply = "I2S2VDD",
- },
- {
- .supply = "DCVDD",
- },
- {
- .supply = "AVDD",
- },
- {
- .supply = "FLLVDD",
- },
- {
- .supply = "HPVDD",
- },
- {
- .supply = "SPKVDD",
- },
-};
-
-/* codec private data */
-struct wm8400_priv {
- struct wm8400 *wm8400;
- u16 fake_register;
- unsigned int sysclk;
- unsigned int pcmclk;
- int fll_in, fll_out;
-};
-
-static void wm8400_component_reset(struct snd_soc_component *component)
-{
- struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
-
- wm8400_reset_codec_reg_cache(wm8400->wm8400);
-}
-
-static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0);
-
-static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int reg = mc->reg;
- int ret;
- u16 val;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- /* now hit the volume update bits (always bit 8) */
- val = snd_soc_component_read(component, reg);
- return snd_soc_component_write(component, reg, val | 0x0100);
-}
-
-#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
- SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
- snd_soc_get_volsw, wm8400_outpga_put_volsw_vu, tlv_array)
-
-
-static const char *wm8400_digital_sidetone[] =
- {"None", "Left ADC", "Right ADC", "Reserved"};
-
-static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum,
- WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADC_TO_DACL_SHIFT,
- wm8400_digital_sidetone);
-
-static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum,
- WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADC_TO_DACR_SHIFT,
- wm8400_digital_sidetone);
-
-static const char *wm8400_adcmode[] =
- {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
-
-static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum,
- WM8400_ADC_CTRL,
- WM8400_ADC_HPF_CUT_SHIFT,
- wm8400_adcmode);
-
-static const struct snd_kcontrol_new wm8400_snd_controls[] = {
-/* INMIXL */
-SOC_SINGLE("LIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L12MNBST_SHIFT,
- 1, 0),
-SOC_SINGLE("LIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L34MNBST_SHIFT,
- 1, 0),
-/* INMIXR */
-SOC_SINGLE("RIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R12MNBST_SHIFT,
- 1, 0),
-SOC_SINGLE("RIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R34MNBST_SHIFT,
- 1, 0),
-
-/* LOMIX */
-SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER3,
- WM8400_LLI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
- WM8400_LR12LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
- WM8400_LL12LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER5,
- WM8400_LRI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
- WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
- WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
-
-/* ROMIX */
-SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER4,
- WM8400_RRI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
- WM8400_RL12ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
- WM8400_RR12ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER6,
- WM8400_RLI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
- WM8400_RLBROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
- WM8400_RRBROVOL_SHIFT, 7, 0, out_mix_tlv),
-
-/* LOUT */
-WM8400_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8400_LEFT_OUTPUT_VOLUME,
- WM8400_LOUTVOL_SHIFT, WM8400_LOUTVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("LOUT ZC", WM8400_LEFT_OUTPUT_VOLUME, WM8400_LOZC_SHIFT, 1, 0),
-
-/* ROUT */
-WM8400_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8400_RIGHT_OUTPUT_VOLUME,
- WM8400_ROUTVOL_SHIFT, WM8400_ROUTVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("ROUT ZC", WM8400_RIGHT_OUTPUT_VOLUME, WM8400_ROZC_SHIFT, 1, 0),
-
-/* LOPGA */
-WM8400_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8400_LEFT_OPGA_VOLUME,
- WM8400_LOPGAVOL_SHIFT, WM8400_LOPGAVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("LOPGA ZC Switch", WM8400_LEFT_OPGA_VOLUME,
- WM8400_LOPGAZC_SHIFT, 1, 0),
-
-/* ROPGA */
-WM8400_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8400_RIGHT_OPGA_VOLUME,
- WM8400_ROPGAVOL_SHIFT, WM8400_ROPGAVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("ROPGA ZC Switch", WM8400_RIGHT_OPGA_VOLUME,
- WM8400_ROPGAZC_SHIFT, 1, 0),
-
-SOC_SINGLE("LON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_LONMUTE_SHIFT, 1, 0),
-SOC_SINGLE("LOP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_LOPMUTE_SHIFT, 1, 0),
-SOC_SINGLE("LOP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_LOATTN_SHIFT, 1, 0),
-SOC_SINGLE("RON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_RONMUTE_SHIFT, 1, 0),
-SOC_SINGLE("ROP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_ROPMUTE_SHIFT, 1, 0),
-SOC_SINGLE("ROP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_ROATTN_SHIFT, 1, 0),
-
-SOC_SINGLE("OUT3 Mute Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT3MUTE_SHIFT, 1, 0),
-SOC_SINGLE("OUT3 Attenuation Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT3ATTN_SHIFT, 1, 0),
-
-SOC_SINGLE("OUT4 Mute Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT4MUTE_SHIFT, 1, 0),
-SOC_SINGLE("OUT4 Attenuation Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT4ATTN_SHIFT, 1, 0),
-
-SOC_SINGLE("Speaker Mode Switch", WM8400_CLASSD1,
- WM8400_CDMODE_SHIFT, 1, 0),
-
-SOC_SINGLE("Speaker Output Attenuation Volume", WM8400_SPEAKER_VOLUME,
- WM8400_SPKATTN_SHIFT, WM8400_SPKATTN_MASK, 0),
-SOC_SINGLE("Speaker DC Boost Volume", WM8400_CLASSD3,
- WM8400_DCGAIN_SHIFT, 6, 0),
-SOC_SINGLE("Speaker AC Boost Volume", WM8400_CLASSD3,
- WM8400_ACGAIN_SHIFT, 6, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
- WM8400_LEFT_DAC_DIGITAL_VOLUME, WM8400_DACL_VOL_SHIFT,
- 127, 0, out_dac_tlv),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
- WM8400_RIGHT_DAC_DIGITAL_VOLUME, WM8400_DACR_VOL_SHIFT,
- 127, 0, out_dac_tlv),
-
-SOC_ENUM("Left Digital Sidetone", wm8400_left_digital_sidetone_enum),
-SOC_ENUM("Right Digital Sidetone", wm8400_right_digital_sidetone_enum),
-
-SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADCL_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
-SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADCR_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
-
-SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8400_ADC_CTRL,
- WM8400_ADC_HPF_ENA_SHIFT, 1, 0),
-
-SOC_ENUM("ADC HPF Mode", wm8400_right_adcmode_enum),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
- WM8400_LEFT_ADC_DIGITAL_VOLUME,
- WM8400_ADCL_VOL_SHIFT,
- WM8400_ADCL_VOL_MASK,
- 0,
- in_adc_tlv),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
- WM8400_RIGHT_ADC_DIGITAL_VOLUME,
- WM8400_ADCR_VOL_SHIFT,
- WM8400_ADCR_VOL_MASK,
- 0,
- in_adc_tlv),
-
-WM8400_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
- WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8400_LIN12VOL_SHIFT,
- WM8400_LIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("LIN12 ZC Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8400_LI12ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("LIN12 Mute Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8400_LI12MUTE_SHIFT, 1, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
- WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8400_LIN34VOL_SHIFT,
- WM8400_LIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("LIN34 ZC Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8400_LI34ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("LIN34 Mute Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8400_LI34MUTE_SHIFT, 1, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
- WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8400_RIN12VOL_SHIFT,
- WM8400_RIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("RIN12 ZC Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8400_RI12ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("RIN12 Mute Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8400_RI12MUTE_SHIFT, 1, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
- WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8400_RIN34VOL_SHIFT,
- WM8400_RIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("RIN34 ZC Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8400_RI34ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8400_RI34MUTE_SHIFT, 1, 0),
-
-};
-
-/*
- * _DAPM_ Controls
- */
-
-static int outmixer_event (struct snd_soc_dapm_widget *w,
- struct snd_kcontrol * kcontrol, int event)
-{
- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
- u32 reg_shift = mc->shift;
- int ret = 0;
- u16 reg;
-
- switch (reg_shift) {
- case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
- reg = snd_soc_component_read(component, WM8400_OUTPUT_MIXER1);
- if (reg & WM8400_LDLO) {
- dev_warn(wm8400->wm8400->dev,
- "Cannot set as Output Mixer 1 LDLO Set\n");
- ret = -1;
- }
- break;
- case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
- reg = snd_soc_component_read(component, WM8400_OUTPUT_MIXER2);
- if (reg & WM8400_RDRO) {
- dev_warn(wm8400->wm8400->dev,
- "Cannot set as Output Mixer 2 RDRO Set\n");
- ret = -1;
- }
- break;
- case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
- reg = snd_soc_component_read(component, WM8400_SPEAKER_MIXER);
- if (reg & WM8400_LDSPK) {
- dev_warn(wm8400->wm8400->dev,
- "Cannot set as Speaker Mixer LDSPK Set\n");
- ret = -1;
- }
- break;
- case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
- reg = snd_soc_component_read(component, WM8400_SPEAKER_MIXER);
- if (reg & WM8400_RDSPK) {
- dev_warn(wm8400->wm8400->dev,
- "Cannot set as Speaker Mixer RDSPK Set\n");
- ret = -1;
- }
- break;
- }
-
- return ret;
-}
-
-/* INMIX dB values */
-static const DECLARE_TLV_DB_SCALE(in_mix_tlv, -1200, 600, 0);
-
-/* Left In PGA Connections */
-static const struct snd_kcontrol_new wm8400_dapm_lin12_pga_controls[] = {
-SOC_DAPM_SINGLE("LIN1 Switch", WM8400_INPUT_MIXER2, WM8400_LMN1_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LIN2 Switch", WM8400_INPUT_MIXER2, WM8400_LMP2_SHIFT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8400_dapm_lin34_pga_controls[] = {
-SOC_DAPM_SINGLE("LIN3 Switch", WM8400_INPUT_MIXER2, WM8400_LMN3_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LIN4 Switch", WM8400_INPUT_MIXER2, WM8400_LMP4_SHIFT, 1, 0),
-};
-
-/* Right In PGA Connections */
-static const struct snd_kcontrol_new wm8400_dapm_rin12_pga_controls[] = {
-SOC_DAPM_SINGLE("RIN1 Switch", WM8400_INPUT_MIXER2, WM8400_RMN1_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RIN2 Switch", WM8400_INPUT_MIXER2, WM8400_RMP2_SHIFT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8400_dapm_rin34_pga_controls[] = {
-SOC_DAPM_SINGLE("RIN3 Switch", WM8400_INPUT_MIXER2, WM8400_RMN3_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RIN4 Switch", WM8400_INPUT_MIXER2, WM8400_RMP4_SHIFT, 1, 0),
-};
-
-/* INMIXL */
-static const struct snd_kcontrol_new wm8400_dapm_inmixl_controls[] = {
-SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8400_INPUT_MIXER3,
- WM8400_LDBVOL_SHIFT, WM8400_LDBVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8400_INPUT_MIXER5, WM8400_LI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
-SOC_DAPM_SINGLE("LINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
- 1, 0),
-SOC_DAPM_SINGLE("LINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
- 1, 0),
-};
-
-/* INMIXR */
-static const struct snd_kcontrol_new wm8400_dapm_inmixr_controls[] = {
-SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8400_INPUT_MIXER4,
- WM8400_RDBVOL_SHIFT, WM8400_RDBVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8400_INPUT_MIXER6, WM8400_RI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
-SOC_DAPM_SINGLE("RINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
- 1, 0),
-SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
- 1, 0),
-};
-
-/* AINLMUX */
-static const char *wm8400_ainlmux[] =
- {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
-
-static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum,
- WM8400_INPUT_MIXER1,
- WM8400_AINLMODE_SHIFT,
- wm8400_ainlmux);
-
-static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls =
-SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
-
-/* DIFFINL */
-
-/* AINRMUX */
-static const char *wm8400_ainrmux[] =
- {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
-
-static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum,
- WM8400_INPUT_MIXER1,
- WM8400_AINRMODE_SHIFT,
- wm8400_ainrmux);
-
-static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls =
-SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum);
-
-/* LOMIX */
-static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = {
-SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LRBLO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LLBLO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LRI3LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LLI3LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LR12LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LL12LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LDLO_SHIFT, 1, 0),
-};
-
-/* ROMIX */
-static const struct snd_kcontrol_new wm8400_dapm_romix_controls[] = {
-SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RLBRO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RRBRO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RLI3RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RRI3RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RL12RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RR12RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RDRO_SHIFT, 1, 0),
-};
-
-/* LONMIX */
-static const struct snd_kcontrol_new wm8400_dapm_lonmix_controls[] = {
-SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
- WM8400_LLOPGALON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER1,
- WM8400_LROPGALON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8400_LINE_MIXER1,
- WM8400_LOPLON_SHIFT, 1, 0),
-};
-
-/* LOPMIX */
-static const struct snd_kcontrol_new wm8400_dapm_lopmix_controls[] = {
-SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER1,
- WM8400_LR12LOP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER1,
- WM8400_LL12LOP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
- WM8400_LLOPGALOP_SHIFT, 1, 0),
-};
-
-/* RONMIX */
-static const struct snd_kcontrol_new wm8400_dapm_ronmix_controls[] = {
-SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
- WM8400_RROPGARON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER2,
- WM8400_RLOPGARON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8400_LINE_MIXER2,
- WM8400_ROPRON_SHIFT, 1, 0),
-};
-
-/* ROPMIX */
-static const struct snd_kcontrol_new wm8400_dapm_ropmix_controls[] = {
-SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER2,
- WM8400_RL12ROP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER2,
- WM8400_RR12ROP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
- WM8400_RROPGAROP_SHIFT, 1, 0),
-};
-
-/* OUT3MIX */
-static const struct snd_kcontrol_new wm8400_dapm_out3mix_controls[] = {
-SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
- WM8400_LI4O3_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8400_OUT3_4_MIXER,
- WM8400_LPGAO3_SHIFT, 1, 0),
-};
-
-/* OUT4MIX */
-static const struct snd_kcontrol_new wm8400_dapm_out4mix_controls[] = {
-SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8400_OUT3_4_MIXER,
- WM8400_RPGAO4_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
- WM8400_RI4O4_SHIFT, 1, 0),
-};
-
-/* SPKMIX */
-static const struct snd_kcontrol_new wm8400_dapm_spkmix_controls[] = {
-SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_LI2SPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_LB2SPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8400_SPEAKER_MIXER,
- WM8400_LOPGASPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8400_SPEAKER_MIXER,
- WM8400_LDSPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8400_SPEAKER_MIXER,
- WM8400_RDSPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8400_SPEAKER_MIXER,
- WM8400_ROPGASPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_RL12ROP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_RI2SPK_SHIFT, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8400_dapm_widgets[] = {
-/* Input Side */
-/* Input Lines */
-SND_SOC_DAPM_INPUT("LIN1"),
-SND_SOC_DAPM_INPUT("LIN2"),
-SND_SOC_DAPM_INPUT("LIN3"),
-SND_SOC_DAPM_INPUT("LIN4/RXN"),
-SND_SOC_DAPM_INPUT("RIN3"),
-SND_SOC_DAPM_INPUT("RIN4/RXP"),
-SND_SOC_DAPM_INPUT("RIN1"),
-SND_SOC_DAPM_INPUT("RIN2"),
-SND_SOC_DAPM_INPUT("Internal ADC Source"),
-
-/* DACs */
-SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8400_POWER_MANAGEMENT_2,
- WM8400_ADCL_ENA_SHIFT, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8400_POWER_MANAGEMENT_2,
- WM8400_ADCR_ENA_SHIFT, 0),
-
-/* Input PGAs */
-SND_SOC_DAPM_MIXER("LIN12 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_LIN12_ENA_SHIFT,
- 0, &wm8400_dapm_lin12_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_lin12_pga_controls)),
-SND_SOC_DAPM_MIXER("LIN34 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_LIN34_ENA_SHIFT,
- 0, &wm8400_dapm_lin34_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_lin34_pga_controls)),
-SND_SOC_DAPM_MIXER("RIN12 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_RIN12_ENA_SHIFT,
- 0, &wm8400_dapm_rin12_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_rin12_pga_controls)),
-SND_SOC_DAPM_MIXER("RIN34 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_RIN34_ENA_SHIFT,
- 0, &wm8400_dapm_rin34_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_rin34_pga_controls)),
-
-SND_SOC_DAPM_SUPPLY("INL", WM8400_POWER_MANAGEMENT_2, WM8400_AINL_ENA_SHIFT,
- 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("INR", WM8400_POWER_MANAGEMENT_2, WM8400_AINR_ENA_SHIFT,
- 0, NULL, 0),
-
-/* INMIXL */
-SND_SOC_DAPM_MIXER("INMIXL", SND_SOC_NOPM, 0, 0,
- &wm8400_dapm_inmixl_controls[0],
- ARRAY_SIZE(wm8400_dapm_inmixl_controls)),
-
-/* AINLMUX */
-SND_SOC_DAPM_MUX("AILNMUX", SND_SOC_NOPM, 0, 0, &wm8400_dapm_ainlmux_controls),
-
-/* INMIXR */
-SND_SOC_DAPM_MIXER("INMIXR", SND_SOC_NOPM, 0, 0,
- &wm8400_dapm_inmixr_controls[0],
- ARRAY_SIZE(wm8400_dapm_inmixr_controls)),
-
-/* AINRMUX */
-SND_SOC_DAPM_MUX("AIRNMUX", SND_SOC_NOPM, 0, 0, &wm8400_dapm_ainrmux_controls),
-
-/* Output Side */
-/* DACs */
-SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8400_POWER_MANAGEMENT_3,
- WM8400_DACL_ENA_SHIFT, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8400_POWER_MANAGEMENT_3,
- WM8400_DACR_ENA_SHIFT, 0),
-
-/* LOMIX */
-SND_SOC_DAPM_MIXER_E("LOMIX", WM8400_POWER_MANAGEMENT_3,
- WM8400_LOMIX_ENA_SHIFT,
- 0, &wm8400_dapm_lomix_controls[0],
- ARRAY_SIZE(wm8400_dapm_lomix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
-/* LONMIX */
-SND_SOC_DAPM_MIXER("LONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LON_ENA_SHIFT,
- 0, &wm8400_dapm_lonmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_lonmix_controls)),
-
-/* LOPMIX */
-SND_SOC_DAPM_MIXER("LOPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LOP_ENA_SHIFT,
- 0, &wm8400_dapm_lopmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_lopmix_controls)),
-
-/* OUT3MIX */
-SND_SOC_DAPM_MIXER("OUT3MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT3_ENA_SHIFT,
- 0, &wm8400_dapm_out3mix_controls[0],
- ARRAY_SIZE(wm8400_dapm_out3mix_controls)),
-
-/* SPKMIX */
-SND_SOC_DAPM_MIXER_E("SPKMIX", WM8400_POWER_MANAGEMENT_1, WM8400_SPK_ENA_SHIFT,
- 0, &wm8400_dapm_spkmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_spkmix_controls), outmixer_event,
- SND_SOC_DAPM_PRE_REG),
-
-/* OUT4MIX */
-SND_SOC_DAPM_MIXER("OUT4MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT4_ENA_SHIFT,
- 0, &wm8400_dapm_out4mix_controls[0],
- ARRAY_SIZE(wm8400_dapm_out4mix_controls)),
-
-/* ROPMIX */
-SND_SOC_DAPM_MIXER("ROPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_ROP_ENA_SHIFT,
- 0, &wm8400_dapm_ropmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_ropmix_controls)),
-
-/* RONMIX */
-SND_SOC_DAPM_MIXER("RONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_RON_ENA_SHIFT,
- 0, &wm8400_dapm_ronmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_ronmix_controls)),
-
-/* ROMIX */
-SND_SOC_DAPM_MIXER_E("ROMIX", WM8400_POWER_MANAGEMENT_3,
- WM8400_ROMIX_ENA_SHIFT,
- 0, &wm8400_dapm_romix_controls[0],
- ARRAY_SIZE(wm8400_dapm_romix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
-/* LOUT PGA */
-SND_SOC_DAPM_PGA("LOUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_LOUT_ENA_SHIFT,
- 0, NULL, 0),
-
-/* ROUT PGA */
-SND_SOC_DAPM_PGA("ROUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_ROUT_ENA_SHIFT,
- 0, NULL, 0),
-
-/* LOPGA */
-SND_SOC_DAPM_PGA("LOPGA", WM8400_POWER_MANAGEMENT_3, WM8400_LOPGA_ENA_SHIFT, 0,
- NULL, 0),
-
-/* ROPGA */
-SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0,
- NULL, 0),
-
-/* MICBIAS */
-SND_SOC_DAPM_SUPPLY("MICBIAS", WM8400_POWER_MANAGEMENT_1,
- WM8400_MIC1BIAS_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("LON"),
-SND_SOC_DAPM_OUTPUT("LOP"),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-SND_SOC_DAPM_OUTPUT("LOUT"),
-SND_SOC_DAPM_OUTPUT("SPKN"),
-SND_SOC_DAPM_OUTPUT("SPKP"),
-SND_SOC_DAPM_OUTPUT("ROUT"),
-SND_SOC_DAPM_OUTPUT("OUT4"),
-SND_SOC_DAPM_OUTPUT("ROP"),
-SND_SOC_DAPM_OUTPUT("RON"),
-
-SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
-};
-
-static const struct snd_soc_dapm_route wm8400_dapm_routes[] = {
- /* Make DACs turn on when playing even if not mixed into any outputs */
- {"Internal DAC Sink", NULL, "Left DAC"},
- {"Internal DAC Sink", NULL, "Right DAC"},
-
- /* Make ADCs turn on when recording
- * even if not mixed from any inputs */
- {"Left ADC", NULL, "Internal ADC Source"},
- {"Right ADC", NULL, "Internal ADC Source"},
-
- /* Input Side */
- /* LIN12 PGA */
- {"LIN12 PGA", "LIN1 Switch", "LIN1"},
- {"LIN12 PGA", "LIN2 Switch", "LIN2"},
- /* LIN34 PGA */
- {"LIN34 PGA", "LIN3 Switch", "LIN3"},
- {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
- /* INMIXL */
- {"INMIXL", NULL, "INL"},
- {"INMIXL", "Record Left Volume", "LOMIX"},
- {"INMIXL", "LIN2 Volume", "LIN2"},
- {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
- {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
- /* AILNMUX */
- {"AILNMUX", NULL, "INL"},
- {"AILNMUX", "INMIXL Mix", "INMIXL"},
- {"AILNMUX", "DIFFINL Mix", "LIN12 PGA"},
- {"AILNMUX", "DIFFINL Mix", "LIN34 PGA"},
- {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"},
- /* ADC */
- {"Left ADC", NULL, "AILNMUX"},
-
- /* RIN12 PGA */
- {"RIN12 PGA", "RIN1 Switch", "RIN1"},
- {"RIN12 PGA", "RIN2 Switch", "RIN2"},
- /* RIN34 PGA */
- {"RIN34 PGA", "RIN3 Switch", "RIN3"},
- {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
- /* INMIXR */
- {"INMIXR", NULL, "INR"},
- {"INMIXR", "Record Right Volume", "ROMIX"},
- {"INMIXR", "RIN2 Volume", "RIN2"},
- {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
- {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
- /* AIRNMUX */
- {"AIRNMUX", NULL, "INR"},
- {"AIRNMUX", "INMIXR Mix", "INMIXR"},
- {"AIRNMUX", "DIFFINR Mix", "RIN12 PGA"},
- {"AIRNMUX", "DIFFINR Mix", "RIN34 PGA"},
- {"AIRNMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"},
- /* ADC */
- {"Right ADC", NULL, "AIRNMUX"},
-
- /* LOMIX */
- {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
- {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
- {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"LOMIX", "LOMIX Right ADC Bypass Switch", "AIRNMUX"},
- {"LOMIX", "LOMIX Left ADC Bypass Switch", "AILNMUX"},
- {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
-
- /* ROMIX */
- {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
- {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
- {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"ROMIX", "ROMIX Right ADC Bypass Switch", "AIRNMUX"},
- {"ROMIX", "ROMIX Left ADC Bypass Switch", "AILNMUX"},
- {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
-
- /* SPKMIX */
- {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
- {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
- {"SPKMIX", "SPKMIX LADC Bypass Switch", "AILNMUX"},
- {"SPKMIX", "SPKMIX RADC Bypass Switch", "AIRNMUX"},
- {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
- {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
- {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
- {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
-
- /* LONMIX */
- {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
- {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
- {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
-
- /* LOPMIX */
- {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
-
- /* OUT3MIX */
- {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
- {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
-
- /* OUT4MIX */
- {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
- {"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"},
-
- /* RONMIX */
- {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
- {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
- {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
-
- /* ROPMIX */
- {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
-
- /* Out Mixer PGAs */
- {"LOPGA", NULL, "LOMIX"},
- {"ROPGA", NULL, "ROMIX"},
-
- {"LOUT PGA", NULL, "LOMIX"},
- {"ROUT PGA", NULL, "ROMIX"},
-
- /* Output Pins */
- {"LON", NULL, "LONMIX"},
- {"LOP", NULL, "LOPMIX"},
- {"OUT3", NULL, "OUT3MIX"},
- {"LOUT", NULL, "LOUT PGA"},
- {"SPKN", NULL, "SPKMIX"},
- {"ROUT", NULL, "ROUT PGA"},
- {"OUT4", NULL, "OUT4MIX"},
- {"ROP", NULL, "ROPMIX"},
- {"RON", NULL, "RONMIX"},
-};
-
-/*
- * Clock after FLL and dividers
- */
-static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_component *component = codec_dai->component;
- struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
-
- wm8400->sysclk = freq;
- return 0;
-}
-
-struct fll_factors {
- u16 n;
- u16 k;
- u16 outdiv;
- u16 fratio;
- u16 freq_ref;
-};
-
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
- unsigned int Fref, unsigned int Fout)
-{
- u64 Kpart;
- unsigned int K, Nmod, target;
-
- factors->outdiv = 2;
- while (Fout * factors->outdiv < 90000000 ||
- Fout * factors->outdiv > 100000000) {
- factors->outdiv *= 2;
- if (factors->outdiv > 32) {
- dev_err(wm8400->wm8400->dev,
- "Unsupported FLL output frequency %uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- target = Fout * factors->outdiv;
- factors->outdiv = factors->outdiv >> 2;
-
- if (Fref < 48000)
- factors->freq_ref = 1;
- else
- factors->freq_ref = 0;
-
- if (Fref < 1000000)
- factors->fratio = 9;
- else
- factors->fratio = 0;
-
- /* Ensure we have a fractional part */
- do {
- if (Fref < 1000000)
- factors->fratio--;
- else
- factors->fratio++;
-
- if (factors->fratio < 1 || factors->fratio > 8) {
- dev_err(wm8400->wm8400->dev,
- "Unable to calculate FRATIO\n");
- return -EINVAL;
- }
-
- factors->n = target / (Fref * factors->fratio);
- Nmod = target % (Fref * factors->fratio);
- } while (Nmod == 0);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, (Fref * factors->fratio));
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- factors->k = K / 10;
-
- dev_dbg(wm8400->wm8400->dev,
- "FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
- Fref, Fout,
- factors->n, factors->k, factors->fratio, factors->outdiv);
-
- return 0;
-}
-
-static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in,
- unsigned int freq_out)
-{
- struct snd_soc_component *component = codec_dai->component;
- struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
- struct fll_factors factors;
- int ret;
- u16 reg;
-
- if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out)
- return 0;
-
- if (freq_out) {
- ret = fll_factors(wm8400, &factors, freq_in, freq_out);
- if (ret != 0)
- return ret;
- } else {
- /* Bodge GCC 4.4.0 uninitialised variable warning - it
- * doesn't seem capable of working out that we exit if
- * freq_out is 0 before any of the uses. */
- memset(&factors, 0, sizeof(factors));
- }
-
- wm8400->fll_out = freq_out;
- wm8400->fll_in = freq_in;
-
- /* We *must* disable the FLL before any changes */
- reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_2);
- reg &= ~WM8400_FLL_ENA;
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_2, reg);
-
- reg = snd_soc_component_read(component, WM8400_FLL_CONTROL_1);
- reg &= ~WM8400_FLL_OSC_ENA;
- snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
-
- if (!freq_out)
- return 0;
-
- reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
- reg |= WM8400_FLL_FRAC | factors.fratio;
- reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
- snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
-
- snd_soc_component_write(component, WM8400_FLL_CONTROL_2, factors.k);
- snd_soc_component_write(component, WM8400_FLL_CONTROL_3, factors.n);
-
- reg = snd_soc_component_read(component, WM8400_FLL_CONTROL_4);
- reg &= ~WM8400_FLL_OUTDIV_MASK;
- reg |= factors.outdiv;
- snd_soc_component_write(component, WM8400_FLL_CONTROL_4, reg);
-
- return 0;
-}
-
-/*
- * Sets ADC and Voice DAC format.
- */
-static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_component *component = codec_dai->component;
- u16 audio1, audio3;
-
- audio1 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_1);
- audio3 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_3);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBC_CFC:
- audio3 &= ~WM8400_AIF_MSTR1;
- break;
- case SND_SOC_DAIFMT_CBP_CFP:
- audio3 |= WM8400_AIF_MSTR1;
- break;
- default:
- return -EINVAL;
- }
-
- audio1 &= ~WM8400_AIF_FMT_MASK;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- audio1 |= WM8400_AIF_FMT_I2S;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- audio1 |= WM8400_AIF_FMT_RIGHTJ;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- audio1 |= WM8400_AIF_FMT_LEFTJ;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- audio1 |= WM8400_AIF_FMT_DSP;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- audio1 |= WM8400_AIF_FMT_DSP | WM8400_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
- snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_3, audio3);
- return 0;
-}
-
-static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_component *component = codec_dai->component;
- u16 reg;
-
- switch (div_id) {
- case WM8400_MCLK_DIV:
- reg = snd_soc_component_read(component, WM8400_CLOCKING_2) &
- ~WM8400_MCLK_DIV_MASK;
- snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
- break;
- case WM8400_DACCLK_DIV:
- reg = snd_soc_component_read(component, WM8400_CLOCKING_2) &
- ~WM8400_DAC_CLKDIV_MASK;
- snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
- break;
- case WM8400_ADCCLK_DIV:
- reg = snd_soc_component_read(component, WM8400_CLOCKING_2) &
- ~WM8400_ADC_CLKDIV_MASK;
- snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
- break;
- case WM8400_BCLK_DIV:
- reg = snd_soc_component_read(component, WM8400_CLOCKING_1) &
- ~WM8400_BCLK_DIV_MASK;
- snd_soc_component_write(component, WM8400_CLOCKING_1, reg | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8400_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_component *component = dai->component;
- u16 audio1 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_1);
-
- audio1 &= ~WM8400_AIF_WL_MASK;
- /* bit size */
- switch (params_width(params)) {
- case 16:
- break;
- case 20:
- audio1 |= WM8400_AIF_WL_20BITS;
- break;
- case 24:
- audio1 |= WM8400_AIF_WL_24BITS;
- break;
- case 32:
- audio1 |= WM8400_AIF_WL_32BITS;
- break;
- }
-
- snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
- return 0;
-}
-
-static int wm8400_mute(struct snd_soc_dai *dai, int mute, int direction)
-{
- struct snd_soc_component *component = dai->component;
- u16 val = snd_soc_component_read(component, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
-
- if (mute)
- snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
- else
- snd_soc_component_write(component, WM8400_DAC_CTRL, val);
-
- return 0;
-}
-
-/* TODO: set bias for best performance at standby */
-static int wm8400_set_bias_level(struct snd_soc_component *component,
- enum snd_soc_bias_level level)
-{
- struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
- struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
- u16 val;
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID=2*50k */
- val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1) &
- ~WM8400_VMID_MODE_MASK;
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x2);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(power),
- &power[0]);
- if (ret != 0) {
- dev_err(wm8400->wm8400->dev,
- "Failed to enable regulators: %d\n",
- ret);
- return ret;
- }
-
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
- WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
-
- /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
- snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_BUFDCOPEN | WM8400_POBCTRL);
-
- msleep(50);
-
- /* Enable VREF & VMID at 2x50k */
- val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
- val |= 0x2 | WM8400_VREF_ENA;
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
-
- /* Enable BUFIOEN */
- snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_BUFDCOPEN | WM8400_POBCTRL |
- WM8400_BUFIOEN);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_BUFIOEN);
- }
-
- /* VMID=2*300k */
- val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1) &
- ~WM8400_VMID_MODE_MASK;
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x4);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Enable POBCTRL and SOFT_ST */
- snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_POBCTRL | WM8400_BUFIOEN);
-
- /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_BUFDCOPEN | WM8400_POBCTRL |
- WM8400_BUFIOEN);
-
- /* mute DAC */
- val = snd_soc_component_read(component, WM8400_DAC_CTRL);
- snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
-
- /* Enable any disabled outputs */
- val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
- val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
- WM8400_OUT4_ENA | WM8400_LOUT_ENA |
- WM8400_ROUT_ENA;
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
-
- /* Disable VMID */
- val &= ~WM8400_VMID_MODE_MASK;
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
-
- msleep(300);
-
- /* Enable all output discharge bits */
- snd_soc_component_write(component, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
- WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
- WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
- WM8400_DIS_ROUT);
-
- /* Disable VREF */
- val &= ~WM8400_VREF_ENA;
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_component_write(component, WM8400_ANTIPOP2, 0x0);
-
- ret = regulator_bulk_disable(ARRAY_SIZE(power),
- &power[0]);
- if (ret != 0)
- return ret;
-
- break;
- }
-
- return 0;
-}
-
-#define WM8400_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8400_dai_ops = {
- .hw_params = wm8400_hw_params,
- .mute_stream = wm8400_mute,
- .set_fmt = wm8400_set_dai_fmt,
- .set_clkdiv = wm8400_set_dai_clkdiv,
- .set_sysclk = wm8400_set_dai_sysclk,
- .set_pll = wm8400_set_dai_pll,
- .no_capture_mute = 1,
-};
-
-/*
- * The WM8400 supports 2 different and mutually exclusive DAI
- * configurations.
- *
- * 1. ADC/DAC on Primary Interface
- * 2. ADC on Primary Interface/DAC on secondary
- */
-static struct snd_soc_dai_driver wm8400_dai = {
-/* ADC/DAC on primary */
- .name = "wm8400-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8400_RATES,
- .formats = WM8400_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8400_RATES,
- .formats = WM8400_FORMATS,
- },
- .ops = &wm8400_dai_ops,
-};
-
-static int wm8400_component_probe(struct snd_soc_component *component)
-{
- struct wm8400 *wm8400 = dev_get_platdata(component->dev);
- struct wm8400_priv *priv;
- int ret;
- u16 reg;
-
- priv = devm_kzalloc(component->dev, sizeof(struct wm8400_priv),
- GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
-
- snd_soc_component_init_regmap(component, wm8400->regmap);
- snd_soc_component_set_drvdata(component, priv);
- priv->wm8400 = wm8400;
-
- ret = devm_regulator_bulk_get(wm8400->dev,
- ARRAY_SIZE(power), &power[0]);
- if (ret != 0) {
- dev_err(component->dev, "Failed to get regulators: %d\n", ret);
- return ret;
- }
-
- wm8400_component_reset(component);
-
- reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
-
- /* Latch volume update bits */
- reg = snd_soc_component_read(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
- snd_soc_component_write(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- reg & WM8400_IPVU);
- reg = snd_soc_component_read(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
- snd_soc_component_write(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- reg & WM8400_IPVU);
-
- snd_soc_component_write(component, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
- snd_soc_component_write(component, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
-
- return 0;
-}
-
-static void wm8400_component_remove(struct snd_soc_component *component)
-{
- u16 reg;
-
- reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
- snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
- reg & (~WM8400_CODEC_ENA));
-}
-
-static const struct snd_soc_component_driver soc_component_dev_wm8400 = {
- .probe = wm8400_component_probe,
- .remove = wm8400_component_remove,
- .set_bias_level = wm8400_set_bias_level,
- .controls = wm8400_snd_controls,
- .num_controls = ARRAY_SIZE(wm8400_snd_controls),
- .dapm_widgets = wm8400_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets),
- .dapm_routes = wm8400_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes),
- .suspend_bias_off = 1,
- .idle_bias_on = 1,
- .use_pmdown_time = 1,
- .endianness = 1,
-};
-
-static int wm8400_probe(struct platform_device *pdev)
-{
- return devm_snd_soc_register_component(&pdev->dev,
- &soc_component_dev_wm8400,
- &wm8400_dai, 1);
-}
-
-static struct platform_driver wm8400_codec_driver = {
- .driver = {
- .name = "wm8400-codec",
- },
- .probe = wm8400_probe,
-};
-
-module_platform_driver(wm8400_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM8400 driver");
-MODULE_AUTHOR("Mark Brown");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8400-codec");
diff --git a/sound/soc/codecs/wm8400.h b/sound/soc/codecs/wm8400.h
deleted file mode 100644
index 9e7bd4f767e7..000000000000
--- a/sound/soc/codecs/wm8400.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * wm8400.h -- audio driver for WM8400
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- */
-
-#ifndef _WM8400_CODEC_H
-#define _WM8400_CODEC_H
-
-#define WM8400_MCLK_DIV 0
-#define WM8400_DACCLK_DIV 1
-#define WM8400_ADCCLK_DIV 2
-#define WM8400_BCLK_DIV 3
-
-#define WM8400_MCLK_DIV_1 0x400
-#define WM8400_MCLK_DIV_2 0x800
-
-#define WM8400_DAC_CLKDIV_1 0x00
-#define WM8400_DAC_CLKDIV_1_5 0x04
-#define WM8400_DAC_CLKDIV_2 0x08
-#define WM8400_DAC_CLKDIV_3 0x0c
-#define WM8400_DAC_CLKDIV_4 0x10
-#define WM8400_DAC_CLKDIV_5_5 0x14
-#define WM8400_DAC_CLKDIV_6 0x18
-
-#define WM8400_ADC_CLKDIV_1 0x00
-#define WM8400_ADC_CLKDIV_1_5 0x20
-#define WM8400_ADC_CLKDIV_2 0x40
-#define WM8400_ADC_CLKDIV_3 0x60
-#define WM8400_ADC_CLKDIV_4 0x80
-#define WM8400_ADC_CLKDIV_5_5 0xa0
-#define WM8400_ADC_CLKDIV_6 0xc0
-
-
-#define WM8400_BCLK_DIV_1 (0x0 << 1)
-#define WM8400_BCLK_DIV_1_5 (0x1 << 1)
-#define WM8400_BCLK_DIV_2 (0x2 << 1)
-#define WM8400_BCLK_DIV_3 (0x3 << 1)
-#define WM8400_BCLK_DIV_4 (0x4 << 1)
-#define WM8400_BCLK_DIV_5_5 (0x5 << 1)
-#define WM8400_BCLK_DIV_6 (0x6 << 1)
-#define WM8400_BCLK_DIV_8 (0x7 << 1)
-#define WM8400_BCLK_DIV_11 (0x8 << 1)
-#define WM8400_BCLK_DIV_12 (0x9 << 1)
-#define WM8400_BCLK_DIV_16 (0xA << 1)
-#define WM8400_BCLK_DIV_22 (0xB << 1)
-#define WM8400_BCLK_DIV_24 (0xC << 1)
-#define WM8400_BCLK_DIV_32 (0xD << 1)
-#define WM8400_BCLK_DIV_44 (0xE << 1)
-#define WM8400_BCLK_DIV_48 (0xF << 1)
-
-#endif
--
2.53.0
^ permalink raw reply [flat|nested] 31+ 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
` (3 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 04/14] mfd: remove unused wm8400 driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 13:21 ` [PATCH 06/14] mfd: remove unused da903x driver Arnd Bergmann
` (10 subsequent siblings)
15 siblings, 0 replies; 31+ 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 [flat|nested] 31+ 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
` (4 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
` (9 subsequent siblings)
15 siblings, 1 reply; 31+ 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 [flat|nested] 31+ 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
` (5 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 13:47 ` Alexandre Belloni
2026-09-09 15:46 ` Sebastian Reichel
2026-09-09 13:21 ` [PATCH 08/14] mfd: remove unused aat2870 driver Arnd Bergmann
` (8 subsequent siblings)
15 siblings, 2 replies; 31+ 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 [flat|nested] 31+ 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
` (6 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
` (7 subsequent siblings)
15 siblings, 0 replies; 31+ 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 [flat|nested] 31+ 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
` (7 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
` (6 subsequent siblings)
15 siblings, 1 reply; 31+ 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 [flat|nested] 31+ 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
` (8 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:21 ` [PATCH 11/14] mfd: remove unused wm8350 driver Arnd Bergmann
` (5 subsequent siblings)
15 siblings, 0 replies; 31+ 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 [flat|nested] 31+ messages in thread
* [PATCH 11/14] mfd: remove unused wm8350 driver
2026-09-09 13:21 [PATCH 00/14] mfd: unused driver purge Arnd Bergmann
` (9 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:26 ` Mark Brown
` (3 more replies)
2026-09-09 13:21 ` [PATCH 12/14] mfd: remove unused mcp-sa11x0/ucb1x00 driver Arnd Bergmann
` (4 subsequent siblings)
15 siblings, 4 replies; 31+ 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 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
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 9955a525436a..263fbad189c7 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -296,7 +296,6 @@ Hardware Monitoring Kernel Drivers
w83l785ts
w83l786ng
wm831x
- wm8350
xgene-hwmon
xdp710
xdpe12284
diff --git a/Documentation/hwmon/wm8350.rst b/Documentation/hwmon/wm8350.rst
deleted file mode 100644
index cec044ca5900..000000000000
--- a/Documentation/hwmon/wm8350.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-Kernel driver wm8350-hwmon
-==========================
-
-Supported chips:
-
- * Wolfson Microelectronics WM835x PMICs
-
- Prefix: 'wm8350'
-
- Datasheet:
-
- - http://www.wolfsonmicro.com/products/WM8350
- - http://www.wolfsonmicro.com/products/WM8351
- - http://www.wolfsonmicro.com/products/WM8352
-
-Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
-
-Description
------------
-
-The WM835x series of PMICs include an AUXADC which can be used to
-monitor a range of system operating parameters, including the voltages
-of the major supplies within the system. Currently the driver provides
-simple access to these major supplies.
-
-Voltage Monitoring
-------------------
-
-Voltages are sampled by a 12 bit ADC. For the internal supplies the ADC
-is referenced to the system VRTC.
diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst
index 502cb6adbeda..8299d6e8d070 100644
--- a/Documentation/watchdog/watchdog-parameters.rst
+++ b/Documentation/watchdog/watchdog-parameters.rst
@@ -699,13 +699,6 @@ wm831x_wdt:
-------------------------------------------------
-wm8350_wdt:
- nowayout:
- Watchdog cannot be stopped once started
- (default=kernel config parameter)
-
--------------------------------------------------
-
sun4v_wdt:
timeout_ms:
Watchdog timeout in milliseconds 1..180000, default=60000)
diff --git a/MAINTAINERS b/MAINTAINERS
index 360655cce7d1..fa15f7f72454 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29385,7 +29385,6 @@ F: drivers/video/backlight/wm83*_bl.c
F: drivers/watchdog/wm83*_wdt.c
F: include/linux/mfd/arizona/
F: include/linux/mfd/wm831x/
-F: include/linux/mfd/wm8350/
F: include/linux/regulator/arizona*
F: include/linux/wm97xx.h
F: include/sound/wm????.h
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 98b9931c59ff..b64dcc0aa9af 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1792,13 +1792,6 @@ config GPIO_WM831X
Say yes here to access the GPIO signals of WM831x power management
chips from Wolfson Microelectronics.
-config GPIO_WM8350
- tristate "WM8350 GPIOs"
- depends on MFD_WM8350
- help
- Say yes here to access the GPIO signals of WM8350 power management
- chips from Wolfson Microelectronics.
-
config GPIO_WM8994
tristate "WM8994 GPIOs"
depends on MFD_WM8994
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 1fafd15d3fa6..2663a9cb435d 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -211,7 +211,6 @@ obj-$(CONFIG_GPIO_WCD934X) += gpio-wcd934x.o
obj-$(CONFIG_GPIO_WHISKEY_COVE) += gpio-wcove.o
obj-$(CONFIG_GPIO_WINBOND) += gpio-winbond.o
obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
-obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
obj-$(CONFIG_GPIO_WS16C48) += gpio-ws16c48.o
obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o
diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/gpio-wm8350.c
deleted file mode 100644
index 46923b23a72e..000000000000
--- a/drivers/gpio/gpio-wm8350.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * gpiolib support for Wolfson WM835x PMICs
- *
- * Copyright 2009 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- */
-
-#include <linux/gpio/driver.h>
-#include <linux/kernel.h>
-#include <linux/mfd/core.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/gpio.h>
-
-struct wm8350_gpio_data {
- struct wm8350 *wm8350;
- struct gpio_chip gpio_chip;
-};
-
-static int wm8350_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8350_gpio_data *wm8350_gpio = gpiochip_get_data(chip);
- struct wm8350 *wm8350 = wm8350_gpio->wm8350;
-
- return wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
- 1 << offset);
-}
-
-static int wm8350_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8350_gpio_data *wm8350_gpio = gpiochip_get_data(chip);
- struct wm8350 *wm8350 = wm8350_gpio->wm8350;
- int ret;
-
- ret = wm8350_reg_read(wm8350, WM8350_GPIO_LEVEL);
- if (ret < 0)
- return ret;
-
- if (ret & (1 << offset))
- return 1;
- else
- return 0;
-}
-
-static int wm8350_gpio_set(struct gpio_chip *chip, unsigned int offset,
- int value)
-{
- struct wm8350_gpio_data *wm8350_gpio = gpiochip_get_data(chip);
- struct wm8350 *wm8350 = wm8350_gpio->wm8350;
-
- if (value)
- return wm8350_set_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
-
- return wm8350_clear_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
-}
-
-static int wm8350_gpio_direction_out(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct wm8350_gpio_data *wm8350_gpio = gpiochip_get_data(chip);
- struct wm8350 *wm8350 = wm8350_gpio->wm8350;
- int ret;
-
- ret = wm8350_clear_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
- 1 << offset);
- if (ret < 0)
- return ret;
-
- /* Don't have an atomic direction/value setup */
- return wm8350_gpio_set(chip, offset, value);
-}
-
-static int wm8350_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8350_gpio_data *wm8350_gpio = gpiochip_get_data(chip);
- struct wm8350 *wm8350 = wm8350_gpio->wm8350;
-
- if (!wm8350->irq_base)
- return -EINVAL;
-
- return wm8350->irq_base + WM8350_IRQ_GPIO(offset);
-}
-
-static const struct gpio_chip template_chip = {
- .label = "wm8350",
- .owner = THIS_MODULE,
- .direction_input = wm8350_gpio_direction_in,
- .get = wm8350_gpio_get,
- .direction_output = wm8350_gpio_direction_out,
- .set = wm8350_gpio_set,
- .to_irq = wm8350_gpio_to_irq,
- .can_sleep = true,
-};
-
-static int wm8350_gpio_probe(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
- struct wm8350_platform_data *pdata = dev_get_platdata(wm8350->dev);
- struct wm8350_gpio_data *wm8350_gpio;
-
- wm8350_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8350_gpio),
- GFP_KERNEL);
- if (wm8350_gpio == NULL)
- return -ENOMEM;
-
- wm8350_gpio->wm8350 = wm8350;
- wm8350_gpio->gpio_chip = template_chip;
- wm8350_gpio->gpio_chip.ngpio = 13;
- wm8350_gpio->gpio_chip.parent = &pdev->dev;
- if (pdata && pdata->gpio_base)
- wm8350_gpio->gpio_chip.base = pdata->gpio_base;
- else
- wm8350_gpio->gpio_chip.base = -1;
-
- return devm_gpiochip_add_data(&pdev->dev, &wm8350_gpio->gpio_chip, wm8350_gpio);
-}
-
-static struct platform_driver wm8350_gpio_driver = {
- .driver.name = "wm8350-gpio",
- .probe = wm8350_gpio_probe,
-};
-
-static int __init wm8350_gpio_init(void)
-{
- return platform_driver_register(&wm8350_gpio_driver);
-}
-subsys_initcall(wm8350_gpio_init);
-
-static void __exit wm8350_gpio_exit(void)
-{
- platform_driver_unregister(&wm8350_gpio_driver);
-}
-module_exit(wm8350_gpio_exit);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("GPIO interface for WM8350 PMICs");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-gpio");
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index fecff8610ea8..74e82fa1b099 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2728,16 +2728,6 @@ config SENSORS_WM831X
This driver can also be built as a module. If so, the module
will be called wm831x-hwmon.
-config SENSORS_WM8350
- tristate "Wolfson Microelectronics WM835x"
- depends on MFD_WM8350
- help
- If you say yes here you get support for the hardware
- monitoring features of the WM835x series of PMICs.
-
- This driver can also be built as a module. If so, the module
- will be called wm8350-hwmon.
-
config SENSORS_ULTRA45
tristate "Sun Ultra45 PIC16F747"
depends on SPARC64
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 1229b6b3996d..64c97f337e40 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -251,7 +251,6 @@ obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
-obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
obj-$(CONFIG_SENSORS_XGENE) += xgene-hwmon.o
obj-$(CONFIG_SENSORS_YOGAFAN) += yogafan.o
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c
deleted file mode 100644
index 10e17bb79895..000000000000
--- a/drivers/hwmon/wm8350-hwmon.c
+++ /dev/null
@@ -1,92 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * drivers/hwmon/wm8350-hwmon.c - Wolfson Microelectronics WM8350 PMIC
- * hardware monitoring features.
- *
- * Copyright (C) 2009 Wolfson Microelectronics plc
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/comparator.h>
-
-static const char * const input_names[] = {
- [WM8350_AUXADC_USB] = "USB",
- [WM8350_AUXADC_LINE] = "Line",
- [WM8350_AUXADC_BATT] = "Battery",
-};
-
-static ssize_t show_voltage(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- int channel = to_sensor_dev_attr(attr)->index;
- int val;
-
- val = wm8350_read_auxadc(wm8350, channel, 0, 0) * WM8350_AUX_COEFF;
- val = DIV_ROUND_CLOSEST(val, 1000);
-
- return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t show_label(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int channel = to_sensor_dev_attr(attr)->index;
-
- return sprintf(buf, "%s\n", input_names[channel]);
-}
-
-#define WM8350_NAMED_VOLTAGE(id, name) \
- static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage,\
- NULL, name); \
- static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \
- NULL, name)
-
-WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB);
-WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT);
-WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE);
-
-static struct attribute *wm8350_attrs[] = {
- &sensor_dev_attr_in0_input.dev_attr.attr,
- &sensor_dev_attr_in0_label.dev_attr.attr,
- &sensor_dev_attr_in1_input.dev_attr.attr,
- &sensor_dev_attr_in1_label.dev_attr.attr,
- &sensor_dev_attr_in2_input.dev_attr.attr,
- &sensor_dev_attr_in2_label.dev_attr.attr,
-
- NULL,
-};
-
-ATTRIBUTE_GROUPS(wm8350);
-
-static int wm8350_hwmon_probe(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- struct device *hwmon_dev;
-
- hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "wm8350",
- wm8350,
- wm8350_groups);
- return PTR_ERR_OR_ZERO(hwmon_dev);
-}
-
-static struct platform_driver wm8350_hwmon_driver = {
- .probe = wm8350_hwmon_probe,
- .driver = {
- .name = "wm8350-hwmon",
- },
-};
-
-module_platform_driver(wm8350_hwmon_driver);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("WM8350 Hardware Monitoring");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-hwmon");
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 1a0663a6501c..7afcf00dea49 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -610,14 +610,6 @@ config LEDS_WM831X_STATUS
This option enables support for the status LEDs of the WM831x
series of PMICs.
-config LEDS_WM8350
- tristate "LED Support for WM8350 AudioPlus PMIC"
- depends on LEDS_CLASS
- depends on MFD_WM8350
- help
- This option enables support for LEDs driven by the Wolfson
- Microelectronics WM8350 AudioPlus PMIC.
-
config LEDS_DA9052
tristate "Dialog DA9052/DA9053 LEDS"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index b989803bedb9..8de413d714d0 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -94,7 +94,6 @@ obj-$(CONFIG_LEDS_TPS6105X) += leds-tps6105x.o
obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds-turris-omnia.o
obj-$(CONFIG_LEDS_UPBOARD) += leds-upboard.o
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
-obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
# Kinetic ExpressWire Protocol
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
deleted file mode 100644
index 87e60ea927b9..000000000000
--- a/drivers/leds/leds-wm8350.c
+++ /dev/null
@@ -1,267 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * LED driver for WM8350 driven LEDS.
- *
- * Copyright(C) 2007, 2008 Wolfson Microelectronics PLC.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/err.h>
-#include <linux/mfd/wm8350/pmic.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-/* Microamps */
-static const int isink_cur[] = {
- 4,
- 5,
- 6,
- 7,
- 8,
- 10,
- 11,
- 14,
- 16,
- 19,
- 23,
- 27,
- 32,
- 39,
- 46,
- 54,
- 65,
- 77,
- 92,
- 109,
- 130,
- 154,
- 183,
- 218,
- 259,
- 308,
- 367,
- 436,
- 518,
- 616,
- 733,
- 872,
- 1037,
- 1233,
- 1466,
- 1744,
- 2073,
- 2466,
- 2933,
- 3487,
- 4147,
- 4932,
- 5865,
- 6975,
- 8294,
- 9864,
- 11730,
- 13949,
- 16589,
- 19728,
- 23460,
- 27899,
- 33178,
- 39455,
- 46920,
- 55798,
- 66355,
- 78910,
- 93840,
- 111596,
- 132710,
- 157820,
- 187681,
- 223191
-};
-
-#define to_wm8350_led(led_cdev) \
- container_of(led_cdev, struct wm8350_led, cdev)
-
-static int wm8350_led_enable(struct wm8350_led *led)
-{
- int ret = 0;
-
- if (led->enabled)
- return ret;
-
- ret = regulator_enable(led->isink);
- if (ret != 0) {
- dev_err(led->cdev.dev, "Failed to enable ISINK: %d\n", ret);
- return ret;
- }
-
- ret = regulator_enable(led->dcdc);
- if (ret != 0) {
- dev_err(led->cdev.dev, "Failed to enable DCDC: %d\n", ret);
- regulator_disable(led->isink);
- return ret;
- }
-
- led->enabled = 1;
-
- return ret;
-}
-
-static int wm8350_led_disable(struct wm8350_led *led)
-{
- int ret = 0;
-
- if (!led->enabled)
- return ret;
-
- ret = regulator_disable(led->dcdc);
- if (ret != 0) {
- dev_err(led->cdev.dev, "Failed to disable DCDC: %d\n", ret);
- return ret;
- }
-
- ret = regulator_disable(led->isink);
- if (ret != 0) {
- dev_err(led->cdev.dev, "Failed to disable ISINK: %d\n", ret);
- ret = regulator_enable(led->dcdc);
- if (ret != 0)
- dev_err(led->cdev.dev, "Failed to reenable DCDC: %d\n",
- ret);
- return ret;
- }
-
- led->enabled = 0;
-
- return ret;
-}
-
-static int wm8350_led_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct wm8350_led *led = to_wm8350_led(led_cdev);
- unsigned long flags;
- int ret;
- int uA;
-
- led->value = value;
-
- spin_lock_irqsave(&led->value_lock, flags);
-
- if (led->value == LED_OFF) {
- spin_unlock_irqrestore(&led->value_lock, flags);
- return wm8350_led_disable(led);
- }
-
- /* This scales linearly into the index of valid current
- * settings which results in a linear scaling of perceived
- * brightness due to the non-linear current settings provided
- * by the hardware.
- */
- uA = (led->max_uA_index * led->value) / LED_FULL;
- spin_unlock_irqrestore(&led->value_lock, flags);
- BUG_ON(uA >= ARRAY_SIZE(isink_cur));
-
- ret = regulator_set_current_limit(led->isink, isink_cur[uA],
- isink_cur[uA]);
- if (ret != 0) {
- dev_err(led->cdev.dev, "Failed to set %duA: %d\n",
- isink_cur[uA], ret);
- return ret;
- }
-
- return wm8350_led_enable(led);
-}
-
-static void wm8350_led_shutdown(struct platform_device *pdev)
-{
- struct wm8350_led *led = platform_get_drvdata(pdev);
-
- led->value = LED_OFF;
- wm8350_led_disable(led);
-}
-
-static int wm8350_led_probe(struct platform_device *pdev)
-{
- struct regulator *isink, *dcdc;
- struct wm8350_led *led;
- struct wm8350_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
- int i;
-
- if (pdata == NULL) {
- dev_err(&pdev->dev, "no platform data\n");
- return -ENODEV;
- }
-
- if (pdata->max_uA < isink_cur[0]) {
- dev_err(&pdev->dev, "Invalid maximum current %duA\n",
- pdata->max_uA);
- return -EINVAL;
- }
-
- isink = devm_regulator_get(&pdev->dev, "led_isink");
- if (IS_ERR(isink)) {
- dev_err(&pdev->dev, "%s: can't get ISINK\n", __func__);
- return PTR_ERR(isink);
- }
-
- dcdc = devm_regulator_get(&pdev->dev, "led_vcc");
- if (IS_ERR(dcdc)) {
- dev_err(&pdev->dev, "%s: can't get DCDC\n", __func__);
- return PTR_ERR(dcdc);
- }
-
- led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
- if (led == NULL)
- return -ENOMEM;
-
- led->cdev.brightness_set_blocking = wm8350_led_set;
- led->cdev.default_trigger = pdata->default_trigger;
- led->cdev.name = pdata->name;
- led->cdev.flags |= LED_CORE_SUSPENDRESUME;
- led->enabled = regulator_is_enabled(isink);
- led->isink = isink;
- led->dcdc = dcdc;
-
- for (i = 0; i < ARRAY_SIZE(isink_cur) - 1; i++)
- if (isink_cur[i] >= pdata->max_uA)
- break;
- led->max_uA_index = i;
- if (pdata->max_uA != isink_cur[i])
- dev_warn(&pdev->dev,
- "Maximum current %duA is not directly supported,"
- " check platform data\n",
- pdata->max_uA);
-
- spin_lock_init(&led->value_lock);
- led->value = LED_OFF;
- platform_set_drvdata(pdev, led);
-
- return led_classdev_register(&pdev->dev, &led->cdev);
-}
-
-static void wm8350_led_remove(struct platform_device *pdev)
-{
- struct wm8350_led *led = platform_get_drvdata(pdev);
-
- led_classdev_unregister(&led->cdev);
- wm8350_led_disable(led);
-}
-
-static struct platform_driver wm8350_led_driver = {
- .driver = {
- .name = "wm8350-led",
- },
- .probe = wm8350_led_probe,
- .remove = wm8350_led_remove,
- .shutdown = wm8350_led_shutdown,
-};
-
-module_platform_driver(wm8350_led_driver);
-
-MODULE_AUTHOR("Mark Brown");
-MODULE_DESCRIPTION("WM8350 LED driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-led");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fbcc45d2b0c4..8a3bbb628693 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2027,21 +2027,6 @@ config MFD_WM831X_SPI
for accessing the device, additional drivers must be enabled in
order to use the functionality of the device.
-config MFD_WM8350
- bool
-
-config MFD_WM8350_I2C
- bool "Wolfson Microelectronics WM8350 with I2C"
- select MFD_WM8350
- select REGMAP_I2C
- depends on I2C=y
- help
- The WM8350 is an integrated audio and power management
- subsystem with watchdog and RTC functionality for embedded
- systems. This option enables core support for the WM8350 with
- I2C as the control interface. Additional options must be
- selected to enable support for the functionality of the chip.
-
config MFD_WM8994
tristate "Wolfson Microelectronics WM8994"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 7aaad5855681..2cdbc693ee33 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -60,10 +60,6 @@ wm831x-objs += wm831x-auxadc.o
obj-$(CONFIG_MFD_WM831X) += wm831x.o
obj-$(CONFIG_MFD_WM831X_I2C) += wm831x-i2c.o
obj-$(CONFIG_MFD_WM831X_SPI) += wm831x-spi.o
-wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
-wm8350-objs += wm8350-irq.o
-obj-$(CONFIG_MFD_WM8350) += wm8350.o
-obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
wm8994-objs := wm8994-core.o wm8994-irq.o wm8994-regmap.o
obj-$(CONFIG_MFD_WM8994) += wm8994.o
obj-$(CONFIG_MFD_WM97xx) += wm97xx-core.o
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
deleted file mode 100644
index fbc77b218215..000000000000
--- a/drivers/mfd/wm8350-core.c
+++ /dev/null
@@ -1,444 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * wm8350-core.c -- Device access for Wolfson WM8350
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood, Mark Brown
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/regmap.h>
-#include <linux/workqueue.h>
-
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/audio.h>
-#include <linux/mfd/wm8350/comparator.h>
-#include <linux/mfd/wm8350/gpio.h>
-#include <linux/mfd/wm8350/pmic.h>
-#include <linux/mfd/wm8350/rtc.h>
-#include <linux/mfd/wm8350/supply.h>
-#include <linux/mfd/wm8350/wdt.h>
-
-#define WM8350_CLOCK_CONTROL_1 0x28
-#define WM8350_AIF_TEST 0x74
-
-/* debug */
-#define WM8350_BUS_DEBUG 0
-#if WM8350_BUS_DEBUG
-#define dump(regs, src) do { \
- int i_; \
- u16 *src_ = src; \
- printk(KERN_DEBUG); \
- for (i_ = 0; i_ < regs; i_++) \
- printk(" 0x%4.4x", *src_++); \
- printk("\n"); \
-} while (0);
-#else
-#define dump(bytes, src)
-#endif
-
-#define WM8350_LOCK_DEBUG 0
-#if WM8350_LOCK_DEBUG
-#define ldbg(format, arg...) printk(format, ## arg)
-#else
-#define ldbg(format, arg...)
-#endif
-
-/*
- * WM8350 Device IO
- */
-static DEFINE_MUTEX(reg_lock_mutex);
-
-/*
- * Safe read, modify, write methods
- */
-int wm8350_clear_bits(struct wm8350 *wm8350, u16 reg, u16 mask)
-{
- return regmap_update_bits(wm8350->regmap, reg, mask, 0);
-}
-EXPORT_SYMBOL_GPL(wm8350_clear_bits);
-
-int wm8350_set_bits(struct wm8350 *wm8350, u16 reg, u16 mask)
-{
- return regmap_update_bits(wm8350->regmap, reg, mask, mask);
-}
-EXPORT_SYMBOL_GPL(wm8350_set_bits);
-
-u16 wm8350_reg_read(struct wm8350 *wm8350, int reg)
-{
- unsigned int data;
- int err;
-
- err = regmap_read(wm8350->regmap, reg, &data);
- if (err)
- dev_err(wm8350->dev, "read from reg R%d failed\n", reg);
-
- return data;
-}
-EXPORT_SYMBOL_GPL(wm8350_reg_read);
-
-int wm8350_reg_write(struct wm8350 *wm8350, int reg, u16 val)
-{
- int ret;
-
- ret = regmap_write(wm8350->regmap, reg, val);
-
- if (ret)
- dev_err(wm8350->dev, "write to reg R%d failed\n", reg);
- return ret;
-}
-EXPORT_SYMBOL_GPL(wm8350_reg_write);
-
-int wm8350_block_read(struct wm8350 *wm8350, int start_reg, int regs,
- u16 *dest)
-{
- int err = 0;
-
- err = regmap_bulk_read(wm8350->regmap, start_reg, dest, regs);
- if (err)
- dev_err(wm8350->dev, "block read starting from R%d failed\n",
- start_reg);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(wm8350_block_read);
-
-int wm8350_block_write(struct wm8350 *wm8350, int start_reg, int regs,
- u16 *src)
-{
- int ret = 0;
-
- ret = regmap_bulk_write(wm8350->regmap, start_reg, src, regs);
- if (ret)
- dev_err(wm8350->dev, "block write starting at R%d failed\n",
- start_reg);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(wm8350_block_write);
-
-/**
- * wm8350_reg_lock()
- *
- * The WM8350 has a hardware lock which can be used to prevent writes to
- * some registers (generally those which can cause particularly serious
- * problems if misused). This function enables that lock.
- *
- * @wm8350: pointer to local driver data structure
- */
-int wm8350_reg_lock(struct wm8350 *wm8350)
-{
- int ret;
-
- mutex_lock(®_lock_mutex);
-
- ldbg(__func__);
-
- ret = wm8350_reg_write(wm8350, WM8350_SECURITY, WM8350_LOCK_KEY);
- if (ret)
- dev_err(wm8350->dev, "lock failed\n");
-
- wm8350->unlocked = false;
-
- mutex_unlock(®_lock_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(wm8350_reg_lock);
-
-/**
- * wm8350_reg_unlock()
- *
- * The WM8350 has a hardware lock which can be used to prevent writes to
- * some registers (generally those which can cause particularly serious
- * problems if misused). This function disables that lock so updates
- * can be performed. For maximum safety this should be done only when
- * required.
- *
- * @wm8350: pointer to local driver data structure
- */
-int wm8350_reg_unlock(struct wm8350 *wm8350)
-{
- int ret;
-
- mutex_lock(®_lock_mutex);
-
- ldbg(__func__);
-
- ret = wm8350_reg_write(wm8350, WM8350_SECURITY, WM8350_UNLOCK_KEY);
- if (ret)
- dev_err(wm8350->dev, "unlock failed\n");
-
- wm8350->unlocked = true;
-
- mutex_unlock(®_lock_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
-
-int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
-{
- u16 reg, result = 0;
-
- if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
- return -EINVAL;
- if (channel >= WM8350_AUXADC_USB && channel <= WM8350_AUXADC_TEMP
- && (scale != 0 || vref != 0))
- return -EINVAL;
-
- mutex_lock(&wm8350->auxadc_mutex);
-
- /* Turn on the ADC */
- reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_5, reg | WM8350_AUXADC_ENA);
-
- if (scale || vref) {
- reg = scale << 13;
- reg |= vref << 12;
- wm8350_reg_write(wm8350, WM8350_AUX1_READBACK + channel, reg);
- }
-
- reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- reg |= 1 << channel | WM8350_AUXADC_POLL;
- wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
-
- /* If a late IRQ left the completion signalled then consume
- * the completion. */
- try_wait_for_completion(&wm8350->auxadc_done);
-
- /* We ignore the result of the completion and just check for a
- * conversion result, allowing us to soldier on if the IRQ
- * infrastructure is not set up for the chip. */
- wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5));
-
- reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- if (reg & WM8350_AUXADC_POLL)
- dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
- else
- result = wm8350_reg_read(wm8350,
- WM8350_AUX1_READBACK + channel);
-
- /* Turn off the ADC */
- reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_5,
- reg & ~WM8350_AUXADC_ENA);
-
- mutex_unlock(&wm8350->auxadc_mutex);
-
- return result & WM8350_AUXADC_DATA1_MASK;
-}
-EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
-
-static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data)
-{
- struct wm8350 *wm8350 = irq_data;
-
- complete(&wm8350->auxadc_done);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Register a client device. This is non-fatal since there is no need to
- * fail the entire device init due to a single platform device failing.
- */
-static void wm8350_client_dev_register(struct wm8350 *wm8350,
- const char *name,
- struct platform_device **pdev)
-{
- int ret;
-
- *pdev = platform_device_alloc(name, -1);
- if (*pdev == NULL) {
- dev_err(wm8350->dev, "Failed to allocate %s\n", name);
- return;
- }
-
- (*pdev)->dev.parent = wm8350->dev;
- platform_set_drvdata(*pdev, wm8350);
- ret = platform_device_add(*pdev);
- if (ret != 0) {
- dev_err(wm8350->dev, "Failed to register %s: %d\n", name, ret);
- platform_device_put(*pdev);
- *pdev = NULL;
- }
-}
-
-int wm8350_device_init(struct wm8350 *wm8350, int irq,
- struct wm8350_platform_data *pdata)
-{
- int ret;
- unsigned int id1, id2, mask_rev;
- unsigned int cust_id, mode, chip_rev;
-
- dev_set_drvdata(wm8350->dev, wm8350);
-
- /* get WM8350 revision and config mode */
- ret = regmap_read(wm8350->regmap, WM8350_RESET_ID, &id1);
- if (ret != 0) {
- dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
- goto err;
- }
-
- ret = regmap_read(wm8350->regmap, WM8350_ID, &id2);
- if (ret != 0) {
- dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
- goto err;
- }
-
- ret = regmap_read(wm8350->regmap, WM8350_REVISION, &mask_rev);
- if (ret != 0) {
- dev_err(wm8350->dev, "Failed to read revision: %d\n", ret);
- goto err;
- }
-
- if (id1 != 0x6143) {
- dev_err(wm8350->dev,
- "Device with ID %x is not a WM8350\n", id1);
- ret = -ENODEV;
- goto err;
- }
-
- mode = (id2 & WM8350_CONF_STS_MASK) >> 10;
- cust_id = id2 & WM8350_CUST_ID_MASK;
- chip_rev = (id2 & WM8350_CHIP_REV_MASK) >> 12;
- dev_info(wm8350->dev,
- "CONF_STS %d, CUST_ID %d, MASK_REV %d, CHIP_REV %d\n",
- mode, cust_id, mask_rev, chip_rev);
-
- if (cust_id != 0) {
- dev_err(wm8350->dev, "Unsupported CUST_ID\n");
- ret = -ENODEV;
- goto err;
- }
-
- switch (mask_rev) {
- case 0:
- wm8350->pmic.max_dcdc = WM8350_DCDC_6;
- wm8350->pmic.max_isink = WM8350_ISINK_B;
-
- switch (chip_rev) {
- case WM8350_REV_E:
- dev_info(wm8350->dev, "WM8350 Rev E\n");
- break;
- case WM8350_REV_F:
- dev_info(wm8350->dev, "WM8350 Rev F\n");
- break;
- case WM8350_REV_G:
- dev_info(wm8350->dev, "WM8350 Rev G\n");
- wm8350->power.rev_g_coeff = 1;
- break;
- case WM8350_REV_H:
- dev_info(wm8350->dev, "WM8350 Rev H\n");
- wm8350->power.rev_g_coeff = 1;
- break;
- default:
- /* For safety we refuse to run on unknown hardware */
- dev_err(wm8350->dev, "Unknown WM8350 CHIP_REV\n");
- ret = -ENODEV;
- goto err;
- }
- break;
-
- case 1:
- wm8350->pmic.max_dcdc = WM8350_DCDC_4;
- wm8350->pmic.max_isink = WM8350_ISINK_A;
-
- switch (chip_rev) {
- case 0:
- dev_info(wm8350->dev, "WM8351 Rev A\n");
- wm8350->power.rev_g_coeff = 1;
- break;
-
- case 1:
- dev_info(wm8350->dev, "WM8351 Rev B\n");
- wm8350->power.rev_g_coeff = 1;
- break;
-
- default:
- dev_err(wm8350->dev, "Unknown WM8351 CHIP_REV\n");
- ret = -ENODEV;
- goto err;
- }
- break;
-
- case 2:
- wm8350->pmic.max_dcdc = WM8350_DCDC_6;
- wm8350->pmic.max_isink = WM8350_ISINK_B;
-
- switch (chip_rev) {
- case 0:
- dev_info(wm8350->dev, "WM8352 Rev A\n");
- wm8350->power.rev_g_coeff = 1;
- break;
-
- default:
- dev_err(wm8350->dev, "Unknown WM8352 CHIP_REV\n");
- ret = -ENODEV;
- goto err;
- }
- break;
-
- default:
- dev_err(wm8350->dev, "Unknown MASK_REV\n");
- ret = -ENODEV;
- goto err;
- }
-
- mutex_init(&wm8350->auxadc_mutex);
- init_completion(&wm8350->auxadc_done);
-
- ret = wm8350_irq_init(wm8350, irq, pdata);
- if (ret < 0)
- goto err;
-
- if (wm8350->irq_base) {
- ret = request_threaded_irq(wm8350->irq_base +
- WM8350_IRQ_AUXADC_DATARDY,
- NULL, wm8350_auxadc_irq,
- IRQF_ONESHOT,
- "auxadc", wm8350);
- if (ret < 0)
- dev_warn(wm8350->dev,
- "Failed to request AUXADC IRQ: %d\n", ret);
- }
-
- if (pdata && pdata->init) {
- ret = pdata->init(wm8350);
- if (ret != 0) {
- dev_err(wm8350->dev, "Platform init() failed: %d\n",
- ret);
- goto err_irq;
- }
- }
-
- wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0);
-
- wm8350_client_dev_register(wm8350, "wm8350-codec",
- &(wm8350->codec.pdev));
- wm8350_client_dev_register(wm8350, "wm8350-gpio",
- &(wm8350->gpio.pdev));
- wm8350_client_dev_register(wm8350, "wm8350-hwmon",
- &(wm8350->hwmon.pdev));
- wm8350_client_dev_register(wm8350, "wm8350-power",
- &(wm8350->power.pdev));
- wm8350_client_dev_register(wm8350, "wm8350-rtc", &(wm8350->rtc.pdev));
- wm8350_client_dev_register(wm8350, "wm8350-wdt", &(wm8350->wdt.pdev));
-
- return 0;
-
-err_irq:
- wm8350_irq_exit(wm8350);
-err:
- return ret;
-}
-EXPORT_SYMBOL_GPL(wm8350_device_init);
diff --git a/drivers/mfd/wm8350-gpio.c b/drivers/mfd/wm8350-gpio.c
deleted file mode 100644
index a653da69e3cc..000000000000
--- a/drivers/mfd/wm8350-gpio.c
+++ /dev/null
@@ -1,217 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * wm8350-core.c -- Device access for Wolfson WM8350
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/gpio.h>
-#include <linux/mfd/wm8350/pmic.h>
-
-static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
-{
- int ret;
-
- wm8350_reg_unlock(wm8350);
- if (dir == WM8350_GPIO_DIR_OUT)
- ret = wm8350_clear_bits(wm8350,
- WM8350_GPIO_CONFIGURATION_I_O,
- 1 << gpio);
- else
- ret = wm8350_set_bits(wm8350,
- WM8350_GPIO_CONFIGURATION_I_O,
- 1 << gpio);
- wm8350_reg_lock(wm8350);
- return ret;
-}
-
-static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
-{
- if (db == WM8350_GPIO_DEBOUNCE_ON)
- return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_DEBOUNCE, 1 << gpio);
-}
-
-static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func)
-{
- u16 reg;
-
- wm8350_reg_unlock(wm8350);
- switch (gpio) {
- case 0:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP0_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 0));
- break;
- case 1:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP1_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 4));
- break;
- case 2:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP2_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 8));
- break;
- case 3:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP3_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 12));
- break;
- case 4:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP4_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 0));
- break;
- case 5:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP5_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 4));
- break;
- case 6:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP6_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 8));
- break;
- case 7:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP7_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 12));
- break;
- case 8:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP8_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 0));
- break;
- case 9:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP9_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 4));
- break;
- case 10:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP10_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 8));
- break;
- case 11:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP11_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 12));
- break;
- case 12:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4)
- & ~WM8350_GP12_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4,
- reg | ((func & 0xf) << 0));
- break;
- default:
- wm8350_reg_lock(wm8350);
- return -EINVAL;
- }
-
- wm8350_reg_lock(wm8350);
- return 0;
-}
-
-static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)
-{
- if (up)
- return wm8350_set_bits(wm8350,
- WM8350_GPIO_PIN_PULL_UP_CONTROL,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_PIN_PULL_UP_CONTROL,
- 1 << gpio);
-}
-
-static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)
-{
- if (down)
- return wm8350_set_bits(wm8350,
- WM8350_GPIO_PULL_DOWN_CONTROL,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_PULL_DOWN_CONTROL,
- 1 << gpio);
-}
-
-static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol)
-{
- if (pol == WM8350_GPIO_ACTIVE_HIGH)
- return wm8350_set_bits(wm8350,
- WM8350_GPIO_PIN_POLARITY_TYPE,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_PIN_POLARITY_TYPE,
- 1 << gpio);
-}
-
-static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert)
-{
- if (invert == WM8350_GPIO_INVERT_ON)
- return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_INT_MODE, 1 << gpio);
-}
-
-int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
- int pol, int pull, int invert, int debounce)
-{
- /* make sure we never pull up and down at the same time */
- if (pull == WM8350_GPIO_PULL_NONE) {
- if (gpio_set_pull_up(wm8350, gpio, 0))
- goto err;
- if (gpio_set_pull_down(wm8350, gpio, 0))
- goto err;
- } else if (pull == WM8350_GPIO_PULL_UP) {
- if (gpio_set_pull_down(wm8350, gpio, 0))
- goto err;
- if (gpio_set_pull_up(wm8350, gpio, 1))
- goto err;
- } else if (pull == WM8350_GPIO_PULL_DOWN) {
- if (gpio_set_pull_up(wm8350, gpio, 0))
- goto err;
- if (gpio_set_pull_down(wm8350, gpio, 1))
- goto err;
- }
-
- if (gpio_set_invert(wm8350, gpio, invert))
- goto err;
- if (gpio_set_polarity(wm8350, gpio, pol))
- goto err;
- if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
- goto err;
- if (gpio_set_dir(wm8350, gpio, dir))
- goto err;
- return gpio_set_func(wm8350, gpio, func);
-
-err:
- return -EIO;
-}
-EXPORT_SYMBOL_GPL(wm8350_gpio_config);
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
deleted file mode 100644
index 767c176b12a7..000000000000
--- a/drivers/mfd/wm8350-i2c.c
+++ /dev/null
@@ -1,64 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * wm8350-i2c.c -- Generic I2C driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood
- * linux@wolfsonmicro.com
- */
-
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/wm8350/core.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-
-static int wm8350_i2c_probe(struct i2c_client *i2c)
-{
- struct wm8350 *wm8350;
- struct wm8350_platform_data *pdata = dev_get_platdata(&i2c->dev);
- int ret = 0;
-
- wm8350 = devm_kzalloc(&i2c->dev, sizeof(struct wm8350), GFP_KERNEL);
- if (wm8350 == NULL)
- return -ENOMEM;
-
- wm8350->regmap = devm_regmap_init_i2c(i2c, &wm8350_regmap);
- if (IS_ERR(wm8350->regmap)) {
- ret = PTR_ERR(wm8350->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- return ret;
- }
-
- i2c_set_clientdata(i2c, wm8350);
- wm8350->dev = &i2c->dev;
-
- return wm8350_device_init(wm8350, i2c->irq, pdata);
-}
-
-static const struct i2c_device_id wm8350_i2c_id[] = {
- { "wm8350" },
- { "wm8351" },
- { "wm8352" },
- { }
-};
-
-static struct i2c_driver wm8350_i2c_driver = {
- .driver = {
- .name = "wm8350",
- .suppress_bind_attrs = true,
- },
- .probe = wm8350_i2c_probe,
- .id_table = wm8350_i2c_id,
-};
-
-static int __init wm8350_i2c_init(void)
-{
- return i2c_add_driver(&wm8350_i2c_driver);
-}
-/* init early so consumer devices can complete system boot */
-subsys_initcall(wm8350_i2c_init);
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
deleted file mode 100644
index 3709ba3088c0..000000000000
--- a/drivers/mfd/wm8350-irq.c
+++ /dev/null
@@ -1,542 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * wm8350-irq.c -- IRQ support for Wolfson WM8350
- *
- * Copyright 2007, 2008, 2009 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood, Mark Brown
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/audio.h>
-#include <linux/mfd/wm8350/comparator.h>
-#include <linux/mfd/wm8350/gpio.h>
-#include <linux/mfd/wm8350/pmic.h>
-#include <linux/mfd/wm8350/rtc.h>
-#include <linux/mfd/wm8350/supply.h>
-#include <linux/mfd/wm8350/wdt.h>
-
-#define WM8350_INT_OFFSET_1 0
-#define WM8350_INT_OFFSET_2 1
-#define WM8350_POWER_UP_INT_OFFSET 2
-#define WM8350_UNDER_VOLTAGE_INT_OFFSET 3
-#define WM8350_OVER_CURRENT_INT_OFFSET 4
-#define WM8350_GPIO_INT_OFFSET 5
-#define WM8350_COMPARATOR_INT_OFFSET 6
-
-struct wm8350_irq_data {
- int primary;
- int reg;
- int mask;
- int primary_only;
-};
-
-static struct wm8350_irq_data wm8350_irqs[] = {
- [WM8350_IRQ_OC_LS] = {
- .primary = WM8350_OC_INT,
- .reg = WM8350_OVER_CURRENT_INT_OFFSET,
- .mask = WM8350_OC_LS_EINT,
- .primary_only = 1,
- },
- [WM8350_IRQ_UV_DC1] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_DC1_EINT,
- },
- [WM8350_IRQ_UV_DC2] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_DC2_EINT,
- },
- [WM8350_IRQ_UV_DC3] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_DC3_EINT,
- },
- [WM8350_IRQ_UV_DC4] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_DC4_EINT,
- },
- [WM8350_IRQ_UV_DC5] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_DC5_EINT,
- },
- [WM8350_IRQ_UV_DC6] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_DC6_EINT,
- },
- [WM8350_IRQ_UV_LDO1] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_LDO1_EINT,
- },
- [WM8350_IRQ_UV_LDO2] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_LDO2_EINT,
- },
- [WM8350_IRQ_UV_LDO3] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_LDO3_EINT,
- },
- [WM8350_IRQ_UV_LDO4] = {
- .primary = WM8350_UV_INT,
- .reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
- .mask = WM8350_UV_LDO4_EINT,
- },
- [WM8350_IRQ_CHG_BAT_HOT] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_BAT_HOT_EINT,
- },
- [WM8350_IRQ_CHG_BAT_COLD] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_BAT_COLD_EINT,
- },
- [WM8350_IRQ_CHG_BAT_FAIL] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_BAT_FAIL_EINT,
- },
- [WM8350_IRQ_CHG_TO] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_TO_EINT,
- },
- [WM8350_IRQ_CHG_END] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_END_EINT,
- },
- [WM8350_IRQ_CHG_START] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_START_EINT,
- },
- [WM8350_IRQ_CHG_FAST_RDY] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_FAST_RDY_EINT,
- },
- [WM8350_IRQ_CHG_VBATT_LT_3P9] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_VBATT_LT_3P9_EINT,
- },
- [WM8350_IRQ_CHG_VBATT_LT_3P1] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_VBATT_LT_3P1_EINT,
- },
- [WM8350_IRQ_CHG_VBATT_LT_2P85] = {
- .primary = WM8350_CHG_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_CHG_VBATT_LT_2P85_EINT,
- },
- [WM8350_IRQ_RTC_ALM] = {
- .primary = WM8350_RTC_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_RTC_ALM_EINT,
- },
- [WM8350_IRQ_RTC_SEC] = {
- .primary = WM8350_RTC_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_RTC_SEC_EINT,
- },
- [WM8350_IRQ_RTC_PER] = {
- .primary = WM8350_RTC_INT,
- .reg = WM8350_INT_OFFSET_1,
- .mask = WM8350_RTC_PER_EINT,
- },
- [WM8350_IRQ_CS1] = {
- .primary = WM8350_CS_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_CS1_EINT,
- },
- [WM8350_IRQ_CS2] = {
- .primary = WM8350_CS_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_CS2_EINT,
- },
- [WM8350_IRQ_SYS_HYST_COMP_FAIL] = {
- .primary = WM8350_SYS_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_SYS_HYST_COMP_FAIL_EINT,
- },
- [WM8350_IRQ_SYS_CHIP_GT115] = {
- .primary = WM8350_SYS_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_SYS_CHIP_GT115_EINT,
- },
- [WM8350_IRQ_SYS_CHIP_GT140] = {
- .primary = WM8350_SYS_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_SYS_CHIP_GT140_EINT,
- },
- [WM8350_IRQ_SYS_WDOG_TO] = {
- .primary = WM8350_SYS_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_SYS_WDOG_TO_EINT,
- },
- [WM8350_IRQ_AUXADC_DATARDY] = {
- .primary = WM8350_AUXADC_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_AUXADC_DATARDY_EINT,
- },
- [WM8350_IRQ_AUXADC_DCOMP4] = {
- .primary = WM8350_AUXADC_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_AUXADC_DCOMP4_EINT,
- },
- [WM8350_IRQ_AUXADC_DCOMP3] = {
- .primary = WM8350_AUXADC_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_AUXADC_DCOMP3_EINT,
- },
- [WM8350_IRQ_AUXADC_DCOMP2] = {
- .primary = WM8350_AUXADC_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_AUXADC_DCOMP2_EINT,
- },
- [WM8350_IRQ_AUXADC_DCOMP1] = {
- .primary = WM8350_AUXADC_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_AUXADC_DCOMP1_EINT,
- },
- [WM8350_IRQ_USB_LIMIT] = {
- .primary = WM8350_USB_INT,
- .reg = WM8350_INT_OFFSET_2,
- .mask = WM8350_USB_LIMIT_EINT,
- .primary_only = 1,
- },
- [WM8350_IRQ_WKUP_OFF_STATE] = {
- .primary = WM8350_WKUP_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_WKUP_OFF_STATE_EINT,
- },
- [WM8350_IRQ_WKUP_HIB_STATE] = {
- .primary = WM8350_WKUP_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_WKUP_HIB_STATE_EINT,
- },
- [WM8350_IRQ_WKUP_CONV_FAULT] = {
- .primary = WM8350_WKUP_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_WKUP_CONV_FAULT_EINT,
- },
- [WM8350_IRQ_WKUP_WDOG_RST] = {
- .primary = WM8350_WKUP_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_WKUP_WDOG_RST_EINT,
- },
- [WM8350_IRQ_WKUP_GP_PWR_ON] = {
- .primary = WM8350_WKUP_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_WKUP_GP_PWR_ON_EINT,
- },
- [WM8350_IRQ_WKUP_ONKEY] = {
- .primary = WM8350_WKUP_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_WKUP_ONKEY_EINT,
- },
- [WM8350_IRQ_WKUP_GP_WAKEUP] = {
- .primary = WM8350_WKUP_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_WKUP_GP_WAKEUP_EINT,
- },
- [WM8350_IRQ_CODEC_JCK_DET_L] = {
- .primary = WM8350_CODEC_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_CODEC_JCK_DET_L_EINT,
- },
- [WM8350_IRQ_CODEC_JCK_DET_R] = {
- .primary = WM8350_CODEC_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_CODEC_JCK_DET_R_EINT,
- },
- [WM8350_IRQ_CODEC_MICSCD] = {
- .primary = WM8350_CODEC_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_CODEC_MICSCD_EINT,
- },
- [WM8350_IRQ_CODEC_MICD] = {
- .primary = WM8350_CODEC_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_CODEC_MICD_EINT,
- },
- [WM8350_IRQ_EXT_USB_FB] = {
- .primary = WM8350_EXT_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_EXT_USB_FB_EINT,
- },
- [WM8350_IRQ_EXT_WALL_FB] = {
- .primary = WM8350_EXT_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_EXT_WALL_FB_EINT,
- },
- [WM8350_IRQ_EXT_BAT_FB] = {
- .primary = WM8350_EXT_INT,
- .reg = WM8350_COMPARATOR_INT_OFFSET,
- .mask = WM8350_EXT_BAT_FB_EINT,
- },
- [WM8350_IRQ_GPIO(0)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP0_EINT,
- },
- [WM8350_IRQ_GPIO(1)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP1_EINT,
- },
- [WM8350_IRQ_GPIO(2)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP2_EINT,
- },
- [WM8350_IRQ_GPIO(3)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP3_EINT,
- },
- [WM8350_IRQ_GPIO(4)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP4_EINT,
- },
- [WM8350_IRQ_GPIO(5)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP5_EINT,
- },
- [WM8350_IRQ_GPIO(6)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP6_EINT,
- },
- [WM8350_IRQ_GPIO(7)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP7_EINT,
- },
- [WM8350_IRQ_GPIO(8)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP8_EINT,
- },
- [WM8350_IRQ_GPIO(9)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP9_EINT,
- },
- [WM8350_IRQ_GPIO(10)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP10_EINT,
- },
- [WM8350_IRQ_GPIO(11)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP11_EINT,
- },
- [WM8350_IRQ_GPIO(12)] = {
- .primary = WM8350_GP_INT,
- .reg = WM8350_GPIO_INT_OFFSET,
- .mask = WM8350_GP12_EINT,
- },
-};
-
-static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
- int irq)
-{
- return &wm8350_irqs[irq - wm8350->irq_base];
-}
-
-/*
- * This is a threaded IRQ handler so can access I2C/SPI. Since all
- * interrupts are clear on read the IRQ line will be reasserted and
- * the physical IRQ will be handled again if another interrupt is
- * asserted while we run - in the normal course of events this is a
- * rare occurrence so we save I2C/SPI reads. We're also assuming that
- * it's rare to get lots of interrupts firing simultaneously so try to
- * minimise I/O.
- */
-static irqreturn_t wm8350_irq(int irq, void *irq_data)
-{
- struct wm8350 *wm8350 = irq_data;
- u16 level_one;
- u16 sub_reg[WM8350_NUM_IRQ_REGS];
- int read_done[WM8350_NUM_IRQ_REGS];
- struct wm8350_irq_data *data;
- int i;
-
- level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
- & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
-
- if (!level_one)
- return IRQ_NONE;
-
- memset(&read_done, 0, sizeof(read_done));
-
- for (i = 0; i < ARRAY_SIZE(wm8350_irqs); i++) {
- data = &wm8350_irqs[i];
-
- if (!(level_one & data->primary))
- continue;
-
- if (!read_done[data->reg]) {
- sub_reg[data->reg] =
- wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
- data->reg);
- sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
- read_done[data->reg] = 1;
- }
-
- if (sub_reg[data->reg] & data->mask)
- handle_nested_irq(wm8350->irq_base + i);
- }
-
- return IRQ_HANDLED;
-}
-
-static void wm8350_irq_lock(struct irq_data *data)
-{
- struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
-
- mutex_lock(&wm8350->irq_lock);
-}
-
-static void wm8350_irq_sync_unlock(struct irq_data *data)
-{
- struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
- /* If there's been a change in the mask write it back
- * to the hardware. */
- WARN_ON(regmap_update_bits(wm8350->regmap,
- WM8350_INT_STATUS_1_MASK + i,
- 0xffff, wm8350->irq_masks[i]));
- }
-
- mutex_unlock(&wm8350->irq_lock);
-}
-
-static void wm8350_irq_enable(struct irq_data *data)
-{
- struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
- struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
- data->irq);
-
- wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
-}
-
-static void wm8350_irq_disable(struct irq_data *data)
-{
- struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
- struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
- data->irq);
-
- wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
-}
-
-static struct irq_chip wm8350_irq_chip = {
- .name = "wm8350",
- .irq_bus_lock = wm8350_irq_lock,
- .irq_bus_sync_unlock = wm8350_irq_sync_unlock,
- .irq_disable = wm8350_irq_disable,
- .irq_enable = wm8350_irq_enable,
-};
-
-int wm8350_irq_init(struct wm8350 *wm8350, int irq,
- struct wm8350_platform_data *pdata)
-{
- int ret, cur_irq, i;
- int flags = IRQF_ONESHOT;
- int irq_base = -1;
-
- if (!irq) {
- dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
- return 0;
- }
-
- /* Mask top level interrupts */
- wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
-
- /* Mask all individual interrupts by default and cache the
- * masks. We read the masks back since there are unwritable
- * bits in the mask registers. */
- for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
- wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i,
- 0xFFFF);
- wm8350->irq_masks[i] =
- wm8350_reg_read(wm8350,
- WM8350_INT_STATUS_1_MASK + i);
- }
-
- mutex_init(&wm8350->irq_lock);
- wm8350->chip_irq = irq;
-
- if (pdata && pdata->irq_base > 0)
- irq_base = pdata->irq_base;
-
- wm8350->irq_base =
- irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0);
- if (wm8350->irq_base < 0) {
- dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
- wm8350->irq_base);
- return 0;
- }
-
- if (pdata && pdata->irq_high) {
- flags |= IRQF_TRIGGER_HIGH;
-
- wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
- WM8350_IRQ_POL);
- } else {
- flags |= IRQF_TRIGGER_LOW;
-
- wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
- WM8350_IRQ_POL);
- }
-
- /* Register with genirq */
- for (cur_irq = wm8350->irq_base;
- cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
- cur_irq++) {
- irq_set_chip_data(cur_irq, wm8350);
- irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip,
- handle_edge_irq);
- irq_set_nested_thread(cur_irq, 1);
-
- irq_clear_status_flags(cur_irq, IRQ_NOREQUEST | IRQ_NOPROBE);
- }
-
- ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
- "wm8350", wm8350);
- if (ret != 0)
- dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
-
- /* Allow interrupts to fire */
- wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0);
-
- return ret;
-}
-
-int wm8350_irq_exit(struct wm8350 *wm8350)
-{
- free_irq(wm8350->chip_irq, wm8350);
- return 0;
-}
diff --git a/drivers/mfd/wm8350-regmap.c b/drivers/mfd/wm8350-regmap.c
deleted file mode 100644
index 3d0ebb004dbf..000000000000
--- a/drivers/mfd/wm8350-regmap.c
+++ /dev/null
@@ -1,335 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * wm8350-regmap.c -- Wolfson Microelectronics WM8350 register map
- *
- * This file splits out the tables describing the defaults and access
- * status of the WM8350 registers since they are rather large.
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- */
-
-#include <linux/mfd/wm8350/core.h>
-
-/*
- * Access masks.
- */
-
-static const struct wm8350_reg_access {
- u16 readable; /* Mask of readable bits */
- u16 writable; /* Mask of writable bits */
- u16 vol; /* Mask of volatile bits */
-} wm8350_reg_io_map[] = {
- /* read write volatile */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Reset/ID */
- { 0x7CFF, 0x0C00, 0x0000 }, /* R1 - ID */
- { 0x007F, 0x0000, 0x0000 }, /* R2 - ROM Mask ID */
- { 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */
- { 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */
- { 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */
- { 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */
- { 0x0000, 0x0000, 0x0000 }, /* R7 */
- { 0xE537, 0xE537, 0xFFFF }, /* R8 - Power mgmt (1) */
- { 0x0FF3, 0x0FF3, 0xFFFF }, /* R9 - Power mgmt (2) */
- { 0x008F, 0x008F, 0xFFFF }, /* R10 - Power mgmt (3) */
- { 0x6D3C, 0x6D3C, 0xFFFF }, /* R11 - Power mgmt (4) */
- { 0x1F8F, 0x1F8F, 0xFFFF }, /* R12 - Power mgmt (5) */
- { 0x8F3F, 0x8F3F, 0xFFFF }, /* R13 - Power mgmt (6) */
- { 0x0003, 0x0003, 0xFFFF }, /* R14 - Power mgmt (7) */
- { 0x0000, 0x0000, 0x0000 }, /* R15 */
- { 0x7F7F, 0x7F7F, 0xFFFF }, /* R16 - RTC Seconds/Minutes */
- { 0x073F, 0x073F, 0xFFFF }, /* R17 - RTC Hours/Day */
- { 0x1F3F, 0x1F3F, 0xFFFF }, /* R18 - RTC Date/Month */
- { 0x3FFF, 0x00FF, 0xFFFF }, /* R19 - RTC Year */
- { 0x7F7F, 0x7F7F, 0x0000 }, /* R20 - Alarm Seconds/Minutes */
- { 0x0F3F, 0x0F3F, 0x0000 }, /* R21 - Alarm Hours/Day */
- { 0x1F3F, 0x1F3F, 0x0000 }, /* R22 - Alarm Date/Month */
- { 0xEF7F, 0xEA7F, 0xFFFF }, /* R23 - RTC Time Control */
- { 0x3BFF, 0x0000, 0xFFFF }, /* R24 - System Interrupts */
- { 0xFEE7, 0x0000, 0xFFFF }, /* R25 - Interrupt Status 1 */
- { 0x35FF, 0x0000, 0xFFFF }, /* R26 - Interrupt Status 2 */
- { 0x0F3F, 0x0000, 0xFFFF }, /* R27 - Power Up Interrupt Status */
- { 0x0F3F, 0x0000, 0xFFFF }, /* R28 - Under Voltage Interrupt status */
- { 0x8000, 0x0000, 0xFFFF }, /* R29 - Over Current Interrupt status */
- { 0x1FFF, 0x0000, 0xFFFF }, /* R30 - GPIO Interrupt Status */
- { 0xEF7F, 0x0000, 0xFFFF }, /* R31 - Comparator Interrupt Status */
- { 0x3FFF, 0x3FFF, 0x0000 }, /* R32 - System Interrupts Mask */
- { 0xFEE7, 0xFEE7, 0x0000 }, /* R33 - Interrupt Status 1 Mask */
- { 0xF5FF, 0xF5FF, 0x0000 }, /* R34 - Interrupt Status 2 Mask */
- { 0x0F3F, 0x0F3F, 0x0000 }, /* R35 - Power Up Interrupt Status Mask */
- { 0x0F3F, 0x0F3F, 0x0000 }, /* R36 - Under Voltage Int status Mask */
- { 0x8000, 0x8000, 0x0000 }, /* R37 - Over Current Int status Mask */
- { 0x1FFF, 0x1FFF, 0x0000 }, /* R38 - GPIO Interrupt Status Mask */
- { 0xEF7F, 0xEF7F, 0x0000 }, /* R39 - Comparator IntStatus Mask */
- { 0xC9F7, 0xC9F7, 0xFFFF }, /* R40 - Clock Control 1 */
- { 0x8001, 0x8001, 0x0000 }, /* R41 - Clock Control 2 */
- { 0xFFF7, 0xFFF7, 0xFFFF }, /* R42 - FLL Control 1 */
- { 0xFBFF, 0xFBFF, 0x0000 }, /* R43 - FLL Control 2 */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R44 - FLL Control 3 */
- { 0x0033, 0x0033, 0x0000 }, /* R45 - FLL Control 4 */
- { 0x0000, 0x0000, 0x0000 }, /* R46 */
- { 0x0000, 0x0000, 0x0000 }, /* R47 */
- { 0x3033, 0x3033, 0x0000 }, /* R48 - DAC Control */
- { 0x0000, 0x0000, 0x0000 }, /* R49 */
- { 0x81FF, 0x81FF, 0xFFFF }, /* R50 - DAC Digital Volume L */
- { 0x81FF, 0x81FF, 0xFFFF }, /* R51 - DAC Digital Volume R */
- { 0x0000, 0x0000, 0x0000 }, /* R52 */
- { 0x0FFF, 0x0FFF, 0xFFFF }, /* R53 - DAC LR Rate */
- { 0x0017, 0x0017, 0x0000 }, /* R54 - DAC Clock Control */
- { 0x0000, 0x0000, 0x0000 }, /* R55 */
- { 0x0000, 0x0000, 0x0000 }, /* R56 */
- { 0x0000, 0x0000, 0x0000 }, /* R57 */
- { 0x4000, 0x4000, 0x0000 }, /* R58 - DAC Mute */
- { 0x7000, 0x7000, 0x0000 }, /* R59 - DAC Mute Volume */
- { 0x3C00, 0x3C00, 0x0000 }, /* R60 - DAC Side */
- { 0x0000, 0x0000, 0x0000 }, /* R61 */
- { 0x0000, 0x0000, 0x0000 }, /* R62 */
- { 0x0000, 0x0000, 0x0000 }, /* R63 */
- { 0x8303, 0x8303, 0xFFFF }, /* R64 - ADC Control */
- { 0x0000, 0x0000, 0x0000 }, /* R65 */
- { 0x81FF, 0x81FF, 0xFFFF }, /* R66 - ADC Digital Volume L */
- { 0x81FF, 0x81FF, 0xFFFF }, /* R67 - ADC Digital Volume R */
- { 0x0FFF, 0x0FFF, 0x0000 }, /* R68 - ADC Divider */
- { 0x0000, 0x0000, 0x0000 }, /* R69 */
- { 0x0FFF, 0x0FFF, 0xFFFF }, /* R70 - ADC LR Rate */
- { 0x0000, 0x0000, 0x0000 }, /* R71 */
- { 0x0707, 0x0707, 0xFFFF }, /* R72 - Input Control */
- { 0xC0C0, 0xC0C0, 0xFFFF }, /* R73 - IN3 Input Control */
- { 0xC09F, 0xC09F, 0xFFFF }, /* R74 - Mic Bias Control */
- { 0x0000, 0x0000, 0x0000 }, /* R75 */
- { 0x0F15, 0x0F15, 0xFFFF }, /* R76 - Output Control */
- { 0xC000, 0xC000, 0xFFFF }, /* R77 - Jack Detect */
- { 0x03FF, 0x03FF, 0x0000 }, /* R78 - Anti Pop Control */
- { 0x0000, 0x0000, 0x0000 }, /* R79 */
- { 0xE1FC, 0xE1FC, 0x8000 }, /* R80 - Left Input Volume */
- { 0xE1FC, 0xE1FC, 0x8000 }, /* R81 - Right Input Volume */
- { 0x0000, 0x0000, 0x0000 }, /* R82 */
- { 0x0000, 0x0000, 0x0000 }, /* R83 */
- { 0x0000, 0x0000, 0x0000 }, /* R84 */
- { 0x0000, 0x0000, 0x0000 }, /* R85 */
- { 0x0000, 0x0000, 0x0000 }, /* R86 */
- { 0x0000, 0x0000, 0x0000 }, /* R87 */
- { 0x9807, 0x9807, 0xFFFF }, /* R88 - Left Mixer Control */
- { 0x980B, 0x980B, 0xFFFF }, /* R89 - Right Mixer Control */
- { 0x0000, 0x0000, 0x0000 }, /* R90 */
- { 0x0000, 0x0000, 0x0000 }, /* R91 */
- { 0x8909, 0x8909, 0xFFFF }, /* R92 - OUT3 Mixer Control */
- { 0x9E07, 0x9E07, 0xFFFF }, /* R93 - OUT4 Mixer Control */
- { 0x0000, 0x0000, 0x0000 }, /* R94 */
- { 0x0000, 0x0000, 0x0000 }, /* R95 */
- { 0x0EEE, 0x0EEE, 0x0000 }, /* R96 - Output Left Mixer Volume */
- { 0xE0EE, 0xE0EE, 0x0000 }, /* R97 - Output Right Mixer Volume */
- { 0x0E0F, 0x0E0F, 0x0000 }, /* R98 - Input Mixer Volume L */
- { 0xE0E1, 0xE0E1, 0x0000 }, /* R99 - Input Mixer Volume R */
- { 0x800E, 0x800E, 0x0000 }, /* R100 - Input Mixer Volume */
- { 0x0000, 0x0000, 0x0000 }, /* R101 */
- { 0x0000, 0x0000, 0x0000 }, /* R102 */
- { 0x0000, 0x0000, 0x0000 }, /* R103 */
- { 0xE1FC, 0xE1FC, 0xFFFF }, /* R104 - LOUT1 Volume */
- { 0xE1FC, 0xE1FC, 0xFFFF }, /* R105 - ROUT1 Volume */
- { 0xE1FC, 0xE1FC, 0xFFFF }, /* R106 - LOUT2 Volume */
- { 0xE7FC, 0xE7FC, 0xFFFF }, /* R107 - ROUT2 Volume */
- { 0x0000, 0x0000, 0x0000 }, /* R108 */
- { 0x0000, 0x0000, 0x0000 }, /* R109 */
- { 0x0000, 0x0000, 0x0000 }, /* R110 */
- { 0x80E0, 0x80E0, 0xFFFF }, /* R111 - BEEP Volume */
- { 0xBF00, 0xBF00, 0x0000 }, /* R112 - AI Formating */
- { 0x00F1, 0x00F1, 0x0000 }, /* R113 - ADC DAC COMP */
- { 0x00F8, 0x00F8, 0x0000 }, /* R114 - AI ADC Control */
- { 0x40FB, 0x40FB, 0x0000 }, /* R115 - AI DAC Control */
- { 0x7C30, 0x7C30, 0x0000 }, /* R116 - AIF Test */
- { 0x0000, 0x0000, 0x0000 }, /* R117 */
- { 0x0000, 0x0000, 0x0000 }, /* R118 */
- { 0x0000, 0x0000, 0x0000 }, /* R119 */
- { 0x0000, 0x0000, 0x0000 }, /* R120 */
- { 0x0000, 0x0000, 0x0000 }, /* R121 */
- { 0x0000, 0x0000, 0x0000 }, /* R122 */
- { 0x0000, 0x0000, 0x0000 }, /* R123 */
- { 0x0000, 0x0000, 0x0000 }, /* R124 */
- { 0x0000, 0x0000, 0x0000 }, /* R125 */
- { 0x0000, 0x0000, 0x0000 }, /* R126 */
- { 0x0000, 0x0000, 0x0000 }, /* R127 */
- { 0x1FFF, 0x1FFF, 0x0000 }, /* R128 - GPIO Debounce */
- { 0x1FFF, 0x1FFF, 0x0000 }, /* R129 - GPIO Pin pull up Control */
- { 0x1FFF, 0x1FFF, 0x0000 }, /* R130 - GPIO Pull down Control */
- { 0x1FFF, 0x1FFF, 0x0000 }, /* R131 - GPIO Interrupt Mode */
- { 0x0000, 0x0000, 0x0000 }, /* R132 */
- { 0x00C0, 0x00C0, 0x0000 }, /* R133 - GPIO Control */
- { 0x1FFF, 0x1FFF, 0x0000 }, /* R134 - GPIO Configuration (i/o) */
- { 0x1FFF, 0x1FFF, 0x0000 }, /* R135 - GPIO Pin Polarity / Type */
- { 0x0000, 0x0000, 0x0000 }, /* R136 */
- { 0x0000, 0x0000, 0x0000 }, /* R137 */
- { 0x0000, 0x0000, 0x0000 }, /* R138 */
- { 0x0000, 0x0000, 0x0000 }, /* R139 */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R140 - GPIO Function Select 1 */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R141 - GPIO Function Select 2 */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R142 - GPIO Function Select 3 */
- { 0x000F, 0x000F, 0x0000 }, /* R143 - GPIO Function Select 4 */
- { 0xF0FF, 0xF0FF, 0xA000 }, /* R144 - Digitiser Control (1) */
- { 0x3707, 0x3707, 0x0000 }, /* R145 - Digitiser Control (2) */
- { 0x0000, 0x0000, 0x0000 }, /* R146 */
- { 0x0000, 0x0000, 0x0000 }, /* R147 */
- { 0x0000, 0x0000, 0x0000 }, /* R148 */
- { 0x0000, 0x0000, 0x0000 }, /* R149 */
- { 0x0000, 0x0000, 0x0000 }, /* R150 */
- { 0x0000, 0x0000, 0x0000 }, /* R151 */
- { 0x7FFF, 0x7000, 0xFFFF }, /* R152 - AUX1 Readback */
- { 0x7FFF, 0x7000, 0xFFFF }, /* R153 - AUX2 Readback */
- { 0x7FFF, 0x7000, 0xFFFF }, /* R154 - AUX3 Readback */
- { 0x7FFF, 0x7000, 0xFFFF }, /* R155 - AUX4 Readback */
- { 0x0FFF, 0x0000, 0xFFFF }, /* R156 - USB Voltage Readback */
- { 0x0FFF, 0x0000, 0xFFFF }, /* R157 - LINE Voltage Readback */
- { 0x0FFF, 0x0000, 0xFFFF }, /* R158 - BATT Voltage Readback */
- { 0x0FFF, 0x0000, 0xFFFF }, /* R159 - Chip Temp Readback */
- { 0x0000, 0x0000, 0x0000 }, /* R160 */
- { 0x0000, 0x0000, 0x0000 }, /* R161 */
- { 0x0000, 0x0000, 0x0000 }, /* R162 */
- { 0x000F, 0x000F, 0x0000 }, /* R163 - Generic Comparator Control */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R164 - Generic comparator 1 */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R165 - Generic comparator 2 */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R166 - Generic comparator 3 */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R167 - Generic comparator 4 */
- { 0xBFFF, 0xBFFF, 0x8000 }, /* R168 - Battery Charger Control 1 */
- { 0xFFFF, 0x4FFF, 0xB000 }, /* R169 - Battery Charger Control 2 */
- { 0x007F, 0x007F, 0x0000 }, /* R170 - Battery Charger Control 3 */
- { 0x0000, 0x0000, 0x0000 }, /* R171 */
- { 0x903F, 0x903F, 0xFFFF }, /* R172 - Current Sink Driver A */
- { 0xE333, 0xE333, 0xFFFF }, /* R173 - CSA Flash control */
- { 0x903F, 0x903F, 0xFFFF }, /* R174 - Current Sink Driver B */
- { 0xE333, 0xE333, 0xFFFF }, /* R175 - CSB Flash control */
- { 0x8F3F, 0x8F3F, 0xFFFF }, /* R176 - DCDC/LDO requested */
- { 0x332D, 0x332D, 0x0000 }, /* R177 - DCDC Active options */
- { 0x002D, 0x002D, 0x0000 }, /* R178 - DCDC Sleep options */
- { 0x5177, 0x5177, 0x8000 }, /* R179 - Power-check comparator */
- { 0x047F, 0x047F, 0x0000 }, /* R180 - DCDC1 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R181 - DCDC1 Timeouts */
- { 0x737F, 0x737F, 0x0000 }, /* R182 - DCDC1 Low Power */
- { 0x535B, 0x535B, 0x0000 }, /* R183 - DCDC2 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R184 - DCDC2 Timeouts */
- { 0x0000, 0x0000, 0x0000 }, /* R185 */
- { 0x047F, 0x047F, 0x0000 }, /* R186 - DCDC3 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R187 - DCDC3 Timeouts */
- { 0x737F, 0x737F, 0x0000 }, /* R188 - DCDC3 Low Power */
- { 0x047F, 0x047F, 0x0000 }, /* R189 - DCDC4 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R190 - DCDC4 Timeouts */
- { 0x737F, 0x737F, 0x0000 }, /* R191 - DCDC4 Low Power */
- { 0x535B, 0x535B, 0x0000 }, /* R192 - DCDC5 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R193 - DCDC5 Timeouts */
- { 0x0000, 0x0000, 0x0000 }, /* R194 */
- { 0x047F, 0x047F, 0x0000 }, /* R195 - DCDC6 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R196 - DCDC6 Timeouts */
- { 0x737F, 0x737F, 0x0000 }, /* R197 - DCDC6 Low Power */
- { 0x0000, 0x0000, 0x0000 }, /* R198 */
- { 0xFFD3, 0xFFD3, 0x0000 }, /* R199 - Limit Switch Control */
- { 0x441F, 0x441F, 0x0000 }, /* R200 - LDO1 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R201 - LDO1 Timeouts */
- { 0x331F, 0x331F, 0x0000 }, /* R202 - LDO1 Low Power */
- { 0x441F, 0x441F, 0x0000 }, /* R203 - LDO2 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R204 - LDO2 Timeouts */
- { 0x331F, 0x331F, 0x0000 }, /* R205 - LDO2 Low Power */
- { 0x441F, 0x441F, 0x0000 }, /* R206 - LDO3 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R207 - LDO3 Timeouts */
- { 0x331F, 0x331F, 0x0000 }, /* R208 - LDO3 Low Power */
- { 0x441F, 0x441F, 0x0000 }, /* R209 - LDO4 Control */
- { 0xFFC0, 0xFFC0, 0x0000 }, /* R210 - LDO4 Timeouts */
- { 0x331F, 0x331F, 0x0000 }, /* R211 - LDO4 Low Power */
- { 0x0000, 0x0000, 0x0000 }, /* R212 */
- { 0x0000, 0x0000, 0x0000 }, /* R213 */
- { 0x0000, 0x0000, 0x0000 }, /* R214 */
- { 0x8F3F, 0x8F3F, 0x0000 }, /* R215 - VCC_FAULT Masks */
- { 0xFF3F, 0xE03F, 0x0000 }, /* R216 - Main Bandgap Control */
- { 0xEF2F, 0xE02F, 0x0000 }, /* R217 - OSC Control */
- { 0xF3FF, 0xB3FF, 0xc000 }, /* R218 - RTC Tick Control */
- { 0xFFFF, 0xFFFF, 0x0000 }, /* R219 - Security */
- { 0x09FF, 0x01FF, 0x0000 }, /* R220 - RAM BIST 1 */
- { 0x0000, 0x0000, 0x0000 }, /* R221 */
- { 0xFFFF, 0xFFFF, 0xFFFF }, /* R222 */
- { 0xFFFF, 0xFFFF, 0xFFFF }, /* R223 */
- { 0x0000, 0x0000, 0x0000 }, /* R224 */
- { 0x8F3F, 0x0000, 0xFFFF }, /* R225 - DCDC/LDO status */
- { 0x0000, 0x0000, 0xFFFF }, /* R226 - Charger status */
- { 0x34FE, 0x0000, 0xFFFF }, /* R227 */
- { 0x0000, 0x0000, 0x0000 }, /* R228 */
- { 0x0000, 0x0000, 0x0000 }, /* R229 */
- { 0xFFFF, 0x1FFF, 0xFFFF }, /* R230 - GPIO Pin Status */
- { 0xFFFF, 0x1FFF, 0xFFFF }, /* R231 */
- { 0xFFFF, 0x1FFF, 0xFFFF }, /* R232 */
- { 0xFFFF, 0x1FFF, 0xFFFF }, /* R233 */
- { 0x0000, 0x0000, 0x0000 }, /* R234 */
- { 0x0000, 0x0000, 0x0000 }, /* R235 */
- { 0x0000, 0x0000, 0x0000 }, /* R236 */
- { 0x0000, 0x0000, 0x0000 }, /* R237 */
- { 0x0000, 0x0000, 0x0000 }, /* R238 */
- { 0x0000, 0x0000, 0x0000 }, /* R239 */
- { 0x0000, 0x0000, 0x0000 }, /* R240 */
- { 0x0000, 0x0000, 0x0000 }, /* R241 */
- { 0x0000, 0x0000, 0x0000 }, /* R242 */
- { 0x0000, 0x0000, 0x0000 }, /* R243 */
- { 0x0000, 0x0000, 0x0000 }, /* R244 */
- { 0x0000, 0x0000, 0x0000 }, /* R245 */
- { 0x0000, 0x0000, 0x0000 }, /* R246 */
- { 0x0000, 0x0000, 0x0000 }, /* R247 */
- { 0xFFFF, 0x0010, 0xFFFF }, /* R248 */
- { 0x0000, 0x0000, 0x0000 }, /* R249 */
- { 0xFFFF, 0x0010, 0xFFFF }, /* R250 */
- { 0xFFFF, 0x0010, 0xFFFF }, /* R251 */
- { 0x0000, 0x0000, 0x0000 }, /* R252 */
- { 0xFFFF, 0x0010, 0xFFFF }, /* R253 */
- { 0x0000, 0x0000, 0x0000 }, /* R254 */
- { 0x0000, 0x0000, 0x0000 }, /* R255 */
-};
-
-static bool wm8350_readable(struct device *dev, unsigned int reg)
-{
- return wm8350_reg_io_map[reg].readable;
-}
-
-static bool wm8350_writeable(struct device *dev, unsigned int reg)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
-
- if (!wm8350->unlocked) {
- if ((reg >= WM8350_GPIO_FUNCTION_SELECT_1 &&
- reg <= WM8350_GPIO_FUNCTION_SELECT_4) ||
- (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 &&
- reg <= WM8350_BATTERY_CHARGER_CONTROL_3))
- return false;
- }
-
- return wm8350_reg_io_map[reg].writable;
-}
-
-static bool wm8350_volatile(struct device *dev, unsigned int reg)
-{
- return wm8350_reg_io_map[reg].vol;
-}
-
-static bool wm8350_precious(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8350_SYSTEM_INTERRUPTS:
- case WM8350_INT_STATUS_1:
- case WM8350_INT_STATUS_2:
- case WM8350_POWER_UP_INT_STATUS:
- case WM8350_UNDER_VOLTAGE_INT_STATUS:
- case WM8350_OVER_CURRENT_INT_STATUS:
- case WM8350_GPIO_INT_STATUS:
- case WM8350_COMPARATOR_INT_STATUS:
- return true;
-
- default:
- return false;
- }
-}
-
-const struct regmap_config wm8350_regmap = {
- .reg_bits = 8,
- .val_bits = 16,
-
- .cache_type = REGCACHE_MAPLE,
-
- .max_register = WM8350_MAX_REGISTER,
- .readable_reg = wm8350_readable,
- .writeable_reg = wm8350_writeable,
- .volatile_reg = wm8350_volatile,
- .precious_reg = wm8350_precious,
-};
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 9bb2ac78dca9..d0b291db3f00 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -74,13 +74,6 @@ config WM831X_POWER
Say Y here to enable support for the power management unit
provided by Wolfson Microelectronics WM831x PMICs.
-config WM8350_POWER
- tristate "WM8350 PMU support"
- depends on MFD_WM8350
- help
- Say Y here to enable support for the power management unit
- provided by the Wolfson Microelectronics WM8350 PMIC.
-
config TEST_POWER
tristate "Test power driver"
help
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 76422bece94c..22d5f32966f6 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_IP5XXX_POWER) += ip5xxx_power.o
obj-$(CONFIG_MAX8925_POWER) += max8925_power.o
obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o
obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
-obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
obj-$(CONFIG_TEST_POWER) += test_power.o
obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
diff --git a/drivers/power/supply/wm8350_power.c b/drivers/power/supply/wm8350_power.c
deleted file mode 100644
index b0eb6e0ce8bc..000000000000
--- a/drivers/power/supply/wm8350_power.c
+++ /dev/null
@@ -1,590 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Battery driver for wm8350 PMIC
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Based on OLPC Battery Driver
- *
- * Copyright 2006 David Woodhouse <dwmw2@infradead.org>
- */
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/power_supply.h>
-#include <linux/mfd/wm8350/supply.h>
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/comparator.h>
-
-static int wm8350_read_battery_uvolts(struct wm8350 *wm8350)
-{
- return wm8350_read_auxadc(wm8350, WM8350_AUXADC_BATT, 0, 0)
- * WM8350_AUX_COEFF;
-}
-
-static int wm8350_read_line_uvolts(struct wm8350 *wm8350)
-{
- return wm8350_read_auxadc(wm8350, WM8350_AUXADC_LINE, 0, 0)
- * WM8350_AUX_COEFF;
-}
-
-static int wm8350_read_usb_uvolts(struct wm8350 *wm8350)
-{
- return wm8350_read_auxadc(wm8350, WM8350_AUXADC_USB, 0, 0)
- * WM8350_AUX_COEFF;
-}
-
-#define WM8350_BATT_SUPPLY 1
-#define WM8350_USB_SUPPLY 2
-#define WM8350_LINE_SUPPLY 4
-
-static inline int wm8350_charge_time_min(struct wm8350 *wm8350, int min)
-{
- if (!wm8350->power.rev_g_coeff)
- return (((min - 30) / 15) & 0xf) << 8;
- else
- return (((min - 30) / 30) & 0xf) << 8;
-}
-
-static int wm8350_get_supplies(struct wm8350 *wm8350)
-{
- u16 sm, ov, co, chrg;
- int supplies = 0;
-
- sm = wm8350_reg_read(wm8350, WM8350_STATE_MACHINE_STATUS);
- ov = wm8350_reg_read(wm8350, WM8350_MISC_OVERRIDES);
- co = wm8350_reg_read(wm8350, WM8350_COMPARATOR_OVERRIDES);
- chrg = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2);
-
- /* USB_SM */
- sm = (sm & WM8350_USB_SM_MASK) >> WM8350_USB_SM_SHIFT;
-
- /* CHG_ISEL */
- chrg &= WM8350_CHG_ISEL_MASK;
-
- /* If the USB state machine is active then we're using that with or
- * without battery, otherwise check for wall supply */
- if (((sm == WM8350_USB_SM_100_SLV) ||
- (sm == WM8350_USB_SM_500_SLV) ||
- (sm == WM8350_USB_SM_STDBY_SLV))
- && !(ov & WM8350_USB_LIMIT_OVRDE))
- supplies = WM8350_USB_SUPPLY;
- else if (((sm == WM8350_USB_SM_100_SLV) ||
- (sm == WM8350_USB_SM_500_SLV) ||
- (sm == WM8350_USB_SM_STDBY_SLV))
- && (ov & WM8350_USB_LIMIT_OVRDE) && (chrg == 0))
- supplies = WM8350_USB_SUPPLY | WM8350_BATT_SUPPLY;
- else if (co & WM8350_WALL_FB_OVRDE)
- supplies = WM8350_LINE_SUPPLY;
- else
- supplies = WM8350_BATT_SUPPLY;
-
- return supplies;
-}
-
-static int wm8350_charger_config(struct wm8350 *wm8350,
- struct wm8350_charger_policy *policy)
-{
- u16 reg, eoc_mA, fast_limit_mA;
-
- if (!policy) {
- dev_warn(wm8350->dev,
- "No charger policy, charger not configured.\n");
- return -EINVAL;
- }
-
- /* make sure USB fast charge current is not > 500mA */
- if (policy->fast_limit_USB_mA > 500) {
- dev_err(wm8350->dev, "USB fast charge > 500mA\n");
- return -EINVAL;
- }
-
- eoc_mA = WM8350_CHG_EOC_mA(policy->eoc_mA);
-
- wm8350_reg_unlock(wm8350);
-
- reg = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1)
- & WM8350_CHG_ENA_R168;
- wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1,
- reg | eoc_mA | policy->trickle_start_mV |
- WM8350_CHG_TRICKLE_TEMP_CHOKE |
- WM8350_CHG_TRICKLE_USB_CHOKE |
- WM8350_CHG_FAST_USB_THROTTLE);
-
- if (wm8350_get_supplies(wm8350) & WM8350_USB_SUPPLY) {
- fast_limit_mA =
- WM8350_CHG_FAST_LIMIT_mA(policy->fast_limit_USB_mA);
- wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2,
- policy->charge_mV | policy->trickle_charge_USB_mA |
- fast_limit_mA | wm8350_charge_time_min(wm8350,
- policy->charge_timeout));
-
- } else {
- fast_limit_mA =
- WM8350_CHG_FAST_LIMIT_mA(policy->fast_limit_mA);
- wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2,
- policy->charge_mV | policy->trickle_charge_mA |
- fast_limit_mA | wm8350_charge_time_min(wm8350,
- policy->charge_timeout));
- }
-
- wm8350_reg_lock(wm8350);
- return 0;
-}
-
-static int wm8350_batt_status(struct wm8350 *wm8350)
-{
- u16 state;
-
- state = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2);
- state &= WM8350_CHG_STS_MASK;
-
- switch (state) {
- case WM8350_CHG_STS_OFF:
- return POWER_SUPPLY_STATUS_DISCHARGING;
-
- case WM8350_CHG_STS_TRICKLE:
- case WM8350_CHG_STS_FAST:
- return POWER_SUPPLY_STATUS_CHARGING;
-
- default:
- return POWER_SUPPLY_STATUS_UNKNOWN;
- }
-}
-
-static ssize_t charger_state_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- char *charge;
- int state;
-
- state = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2) &
- WM8350_CHG_STS_MASK;
- switch (state) {
- case WM8350_CHG_STS_OFF:
- charge = "Charger Off";
- break;
- case WM8350_CHG_STS_TRICKLE:
- charge = "Trickle Charging";
- break;
- case WM8350_CHG_STS_FAST:
- charge = "Fast Charging";
- break;
- default:
- return 0;
- }
-
- return sysfs_emit(buf, "%s\n", charge);
-}
-
-static DEVICE_ATTR_RO(charger_state);
-
-static irqreturn_t wm8350_charger_handler(int irq, void *data)
-{
- struct wm8350 *wm8350 = data;
- struct wm8350_power *power = &wm8350->power;
- struct wm8350_charger_policy *policy = power->policy;
-
- switch (irq - wm8350->irq_base) {
- case WM8350_IRQ_CHG_BAT_FAIL:
- dev_err(wm8350->dev, "battery failed\n");
- break;
- case WM8350_IRQ_CHG_TO:
- dev_err(wm8350->dev, "charger timeout\n");
- power_supply_changed(power->battery);
- break;
-
- case WM8350_IRQ_CHG_BAT_HOT:
- case WM8350_IRQ_CHG_BAT_COLD:
- case WM8350_IRQ_CHG_START:
- case WM8350_IRQ_CHG_END:
- power_supply_changed(power->battery);
- break;
-
- case WM8350_IRQ_CHG_FAST_RDY:
- dev_dbg(wm8350->dev, "fast charger ready\n");
- wm8350_charger_config(wm8350, policy);
- wm8350_reg_unlock(wm8350);
- wm8350_set_bits(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1,
- WM8350_CHG_FAST);
- wm8350_reg_lock(wm8350);
- break;
-
- case WM8350_IRQ_CHG_VBATT_LT_3P9:
- dev_warn(wm8350->dev, "battery < 3.9V\n");
- break;
- case WM8350_IRQ_CHG_VBATT_LT_3P1:
- dev_warn(wm8350->dev, "battery < 3.1V\n");
- break;
- case WM8350_IRQ_CHG_VBATT_LT_2P85:
- dev_warn(wm8350->dev, "battery < 2.85V\n");
- break;
-
- /* Supply change. We will overnotify but it should do
- * no harm. */
- case WM8350_IRQ_EXT_USB_FB:
- case WM8350_IRQ_EXT_WALL_FB:
- wm8350_charger_config(wm8350, policy);
- fallthrough;
- case WM8350_IRQ_EXT_BAT_FB:
- power_supply_changed(power->battery);
- power_supply_changed(power->usb);
- power_supply_changed(power->ac);
- break;
-
- default:
- dev_err(wm8350->dev, "Unknown interrupt %d\n", irq);
- }
-
- return IRQ_HANDLED;
-}
-
-/*********************************************************************
- * AC Power
- *********************************************************************/
-static int wm8350_ac_get_prop(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(psy->dev.parent);
- int ret = 0;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = !!(wm8350_get_supplies(wm8350) &
- WM8350_LINE_SUPPLY);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = wm8350_read_line_uvolts(wm8350);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static enum power_supply_property wm8350_ac_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
-};
-
-/*********************************************************************
- * USB Power
- *********************************************************************/
-static int wm8350_usb_get_prop(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(psy->dev.parent);
- int ret = 0;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = !!(wm8350_get_supplies(wm8350) &
- WM8350_USB_SUPPLY);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = wm8350_read_usb_uvolts(wm8350);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static enum power_supply_property wm8350_usb_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
-};
-
-/*********************************************************************
- * Battery properties
- *********************************************************************/
-
-static int wm8350_bat_check_health(struct wm8350 *wm8350)
-{
- u16 reg;
-
- if (wm8350_read_battery_uvolts(wm8350) < 2850000)
- return POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
-
- reg = wm8350_reg_read(wm8350, WM8350_CHARGER_OVERRIDES);
- if (reg & WM8350_CHG_BATT_HOT_OVRDE)
- return POWER_SUPPLY_HEALTH_OVERHEAT;
-
- if (reg & WM8350_CHG_BATT_COLD_OVRDE)
- return POWER_SUPPLY_HEALTH_COLD;
-
- return POWER_SUPPLY_HEALTH_GOOD;
-}
-
-static int wm8350_bat_get_charge_type(struct wm8350 *wm8350)
-{
- int state;
-
- state = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2) &
- WM8350_CHG_STS_MASK;
- switch (state) {
- case WM8350_CHG_STS_OFF:
- return POWER_SUPPLY_CHARGE_TYPE_NONE;
- case WM8350_CHG_STS_TRICKLE:
- return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
- case WM8350_CHG_STS_FAST:
- return POWER_SUPPLY_CHARGE_TYPE_FAST;
- default:
- return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
- }
-}
-
-static int wm8350_bat_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(psy->dev.parent);
- int ret = 0;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- val->intval = wm8350_batt_status(wm8350);
- break;
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = !!(wm8350_get_supplies(wm8350) &
- WM8350_BATT_SUPPLY);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = wm8350_read_battery_uvolts(wm8350);
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- val->intval = wm8350_bat_check_health(wm8350);
- break;
- case POWER_SUPPLY_PROP_CHARGE_TYPE:
- val->intval = wm8350_bat_get_charge_type(wm8350);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static enum power_supply_property wm8350_bat_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_CHARGE_TYPE,
-};
-
-static const struct power_supply_desc wm8350_ac_desc = {
- .name = "wm8350-ac",
- .type = POWER_SUPPLY_TYPE_MAINS,
- .properties = wm8350_ac_props,
- .num_properties = ARRAY_SIZE(wm8350_ac_props),
- .get_property = wm8350_ac_get_prop,
-};
-
-static const struct power_supply_desc wm8350_battery_desc = {
- .name = "wm8350-battery",
- .properties = wm8350_bat_props,
- .num_properties = ARRAY_SIZE(wm8350_bat_props),
- .get_property = wm8350_bat_get_property,
- .use_for_apm = 1,
-};
-
-static const struct power_supply_desc wm8350_usb_desc = {
- .name = "wm8350-usb",
- .type = POWER_SUPPLY_TYPE_USB,
- .properties = wm8350_usb_props,
- .num_properties = ARRAY_SIZE(wm8350_usb_props),
- .get_property = wm8350_usb_get_prop,
-};
-
-/*********************************************************************
- * Initialisation
- *********************************************************************/
-
-static int wm8350_init_charger(struct wm8350 *wm8350)
-{
- int ret;
-
- /* register our interest in charger events */
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT,
- wm8350_charger_handler, 0, "Battery hot", wm8350);
- if (ret)
- goto err;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD,
- wm8350_charger_handler, 0, "Battery cold", wm8350);
- if (ret)
- goto free_chg_bat_hot;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL,
- wm8350_charger_handler, 0, "Battery fail", wm8350);
- if (ret)
- goto free_chg_bat_cold;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_TO,
- wm8350_charger_handler, 0,
- "Charger timeout", wm8350);
- if (ret)
- goto free_chg_bat_fail;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_END,
- wm8350_charger_handler, 0,
- "Charge end", wm8350);
- if (ret)
- goto free_chg_to;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_START,
- wm8350_charger_handler, 0,
- "Charge start", wm8350);
- if (ret)
- goto free_chg_end;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY,
- wm8350_charger_handler, 0,
- "Fast charge ready", wm8350);
- if (ret)
- goto free_chg_start;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9,
- wm8350_charger_handler, 0,
- "Battery <3.9V", wm8350);
- if (ret)
- goto free_chg_fast_rdy;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1,
- wm8350_charger_handler, 0,
- "Battery <3.1V", wm8350);
- if (ret)
- goto free_chg_vbatt_lt_3p9;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85,
- wm8350_charger_handler, 0,
- "Battery <2.85V", wm8350);
- if (ret)
- goto free_chg_vbatt_lt_3p1;
-
- /* and supply change events */
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_EXT_USB_FB,
- wm8350_charger_handler, 0, "USB", wm8350);
- if (ret)
- goto free_chg_vbatt_lt_2p85;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_EXT_WALL_FB,
- wm8350_charger_handler, 0, "Wall", wm8350);
- if (ret)
- goto free_ext_usb_fb;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_EXT_BAT_FB,
- wm8350_charger_handler, 0, "Battery", wm8350);
- if (ret)
- goto free_ext_wall_fb;
-
- return 0;
-
-free_ext_wall_fb:
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350);
-free_ext_usb_fb:
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350);
-free_chg_vbatt_lt_2p85:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350);
-free_chg_vbatt_lt_3p1:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350);
-free_chg_vbatt_lt_3p9:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350);
-free_chg_fast_rdy:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, wm8350);
-free_chg_start:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350);
-free_chg_end:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350);
-free_chg_to:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350);
-free_chg_bat_fail:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350);
-free_chg_bat_cold:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350);
-free_chg_bat_hot:
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350);
-err:
- return ret;
-}
-
-static void free_charger_irq(struct wm8350 *wm8350)
-{
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350);
-}
-
-static int wm8350_power_probe(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- struct wm8350_power *power = &wm8350->power;
- struct wm8350_charger_policy *policy = power->policy;
- int ret;
-
- power->ac = devm_power_supply_register(&pdev->dev, &wm8350_ac_desc, NULL);
- if (IS_ERR(power->ac))
- return PTR_ERR(power->ac);
-
- power->battery = devm_power_supply_register(&pdev->dev, &wm8350_battery_desc, NULL);
- if (IS_ERR(power->battery))
- return PTR_ERR(power->battery);
-
- power->usb = devm_power_supply_register(&pdev->dev, &wm8350_usb_desc, NULL);
- if (IS_ERR(power->usb))
- return PTR_ERR(power->usb);
-
- ret = device_create_file(&pdev->dev, &dev_attr_charger_state);
- if (ret < 0)
- dev_warn(wm8350->dev, "failed to add charge sysfs: %d\n", ret);
- ret = 0;
-
- wm8350_init_charger(wm8350);
- if (wm8350_charger_config(wm8350, policy) == 0) {
- wm8350_reg_unlock(wm8350);
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CHG_ENA);
- wm8350_reg_lock(wm8350);
- }
-
- return ret;
-}
-
-static void wm8350_power_remove(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
-
- free_charger_irq(wm8350);
- device_remove_file(&pdev->dev, &dev_attr_charger_state);
-}
-
-static struct platform_driver wm8350_power_driver = {
- .probe = wm8350_power_probe,
- .remove = wm8350_power_remove,
- .driver = {
- .name = "wm8350-power",
- },
-};
-
-module_platform_driver(wm8350_power_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Power supply driver for WM8350");
-MODULE_ALIAS("platform:wm8350-power");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 2d5eb954d122..940456a62b0b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1824,13 +1824,6 @@ config REGULATOR_WM831X
Support the voltage and current regulators of the WM831x series
of PMIC devices.
-config REGULATOR_WM8350
- tristate "Wolfson Microelectronics WM8350 AudioPlus PMIC"
- depends on MFD_WM8350
- help
- This driver provides support for the voltage and current regulators
- of the WM8350 AudioPlus PMIC.
-
config REGULATOR_WM8994
tristate "Wolfson Microelectronics WM8994 CODEC"
depends on MFD_WM8994
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 861f86c30c73..da4c6b3b21c8 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -209,7 +209,6 @@ obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
-obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
deleted file mode 100644
index d09864bae5ef..000000000000
--- a/drivers/regulator/wm8350-regulator.c
+++ /dev/null
@@ -1,1330 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-//
-// wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC
-//
-// Copyright 2007, 2008 Wolfson Microelectronics PLC.
-//
-// Author: Liam Girdwood
-// linux@wolfsonmicro.com
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/pmic.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-
-/* Maximum value possible for VSEL */
-#define WM8350_DCDC_MAX_VSEL 0x66
-
-/* Microamps */
-static const unsigned int isink_cur[] = {
- 4,
- 5,
- 6,
- 7,
- 8,
- 10,
- 11,
- 14,
- 16,
- 19,
- 23,
- 27,
- 32,
- 39,
- 46,
- 54,
- 65,
- 77,
- 92,
- 109,
- 130,
- 154,
- 183,
- 218,
- 259,
- 308,
- 367,
- 436,
- 518,
- 616,
- 733,
- 872,
- 1037,
- 1233,
- 1466,
- 1744,
- 2073,
- 2466,
- 2933,
- 3487,
- 4147,
- 4932,
- 5865,
- 6975,
- 8294,
- 9864,
- 11730,
- 13949,
- 16589,
- 19728,
- 23460,
- 27899,
- 33178,
- 39455,
- 46920,
- 55798,
- 66355,
- 78910,
- 93840,
- 111596,
- 132710,
- 157820,
- 187681,
- 223191
-};
-
-/* turn on ISINK followed by DCDC */
-static int wm8350_isink_enable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int isink = rdev_get_id(rdev);
-
- switch (isink) {
- case WM8350_ISINK_A:
- switch (wm8350->pmic.isink_A_dcdc) {
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
- WM8350_CS1_ENA);
- wm8350_set_bits(wm8350, WM8350_CSA_FLASH_CONTROL,
- WM8350_CS1_DRIVE);
- wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
- 1 << (wm8350->pmic.isink_A_dcdc -
- WM8350_DCDC_1));
- break;
- default:
- return -EINVAL;
- }
- break;
- case WM8350_ISINK_B:
- switch (wm8350->pmic.isink_B_dcdc) {
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
- WM8350_CS2_ENA);
- wm8350_set_bits(wm8350, WM8350_CSB_FLASH_CONTROL,
- WM8350_CS2_DRIVE);
- wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
- 1 << (wm8350->pmic.isink_B_dcdc -
- WM8350_DCDC_1));
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int wm8350_isink_disable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int isink = rdev_get_id(rdev);
-
- switch (isink) {
- case WM8350_ISINK_A:
- switch (wm8350->pmic.isink_A_dcdc) {
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
- 1 << (wm8350->pmic.isink_A_dcdc -
- WM8350_DCDC_1));
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,
- WM8350_CS1_ENA);
- break;
- default:
- return -EINVAL;
- }
- break;
- case WM8350_ISINK_B:
- switch (wm8350->pmic.isink_B_dcdc) {
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
- 1 << (wm8350->pmic.isink_B_dcdc -
- WM8350_DCDC_1));
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,
- WM8350_CS2_ENA);
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int wm8350_isink_is_enabled(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int isink = rdev_get_id(rdev);
-
- switch (isink) {
- case WM8350_ISINK_A:
- return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) &
- 0x8000;
- case WM8350_ISINK_B:
- return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) &
- 0x8000;
- }
- return -EINVAL;
-}
-
-static int wm8350_isink_enable_time(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int isink = rdev_get_id(rdev);
- int reg;
-
- switch (isink) {
- case WM8350_ISINK_A:
- reg = wm8350_reg_read(wm8350, WM8350_CSA_FLASH_CONTROL);
- break;
- case WM8350_ISINK_B:
- reg = wm8350_reg_read(wm8350, WM8350_CSB_FLASH_CONTROL);
- break;
- default:
- return -EINVAL;
- }
-
- if (reg & WM8350_CS1_FLASH_MODE) {
- switch (reg & WM8350_CS1_ON_RAMP_MASK) {
- case 0:
- return 0;
- case 1:
- return 1950;
- case 2:
- return 3910;
- case 3:
- return 7800;
- }
- } else {
- switch (reg & WM8350_CS1_ON_RAMP_MASK) {
- case 0:
- return 0;
- case 1:
- return 250000;
- case 2:
- return 500000;
- case 3:
- return 1000000;
- }
- }
-
- return -EINVAL;
-}
-
-
-int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode,
- u16 trigger, u16 duration, u16 on_ramp, u16 off_ramp,
- u16 drive)
-{
- switch (isink) {
- case WM8350_ISINK_A:
- wm8350_reg_write(wm8350, WM8350_CSA_FLASH_CONTROL,
- (mode ? WM8350_CS1_FLASH_MODE : 0) |
- (trigger ? WM8350_CS1_TRIGSRC : 0) |
- duration | on_ramp | off_ramp | drive);
- break;
- case WM8350_ISINK_B:
- wm8350_reg_write(wm8350, WM8350_CSB_FLASH_CONTROL,
- (mode ? WM8350_CS2_FLASH_MODE : 0) |
- (trigger ? WM8350_CS2_TRIGSRC : 0) |
- duration | on_ramp | off_ramp | drive);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_isink_set_flash);
-
-static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int sel, volt_reg, dcdc = rdev_get_id(rdev);
- u16 val;
-
- dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, uV / 1000);
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- volt_reg = WM8350_DCDC1_LOW_POWER;
- break;
- case WM8350_DCDC_3:
- volt_reg = WM8350_DCDC3_LOW_POWER;
- break;
- case WM8350_DCDC_4:
- volt_reg = WM8350_DCDC4_LOW_POWER;
- break;
- case WM8350_DCDC_6:
- volt_reg = WM8350_DCDC6_LOW_POWER;
- break;
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- default:
- return -EINVAL;
- }
-
- sel = regulator_map_voltage_linear(rdev, uV, uV);
- if (sel < 0)
- return sel;
-
- /* all DCDCs have same mV bits */
- val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK;
- wm8350_reg_write(wm8350, volt_reg, val | sel);
- return 0;
-}
-
-static int wm8350_dcdc_set_suspend_enable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int dcdc = rdev_get_id(rdev);
- u16 val;
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER)
- & ~WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,
- val | wm8350->pmic.dcdc1_hib_mode);
- break;
- case WM8350_DCDC_3:
- val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER)
- & ~WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,
- val | wm8350->pmic.dcdc3_hib_mode);
- break;
- case WM8350_DCDC_4:
- val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER)
- & ~WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,
- val | wm8350->pmic.dcdc4_hib_mode);
- break;
- case WM8350_DCDC_6:
- val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER)
- & ~WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,
- val | wm8350->pmic.dcdc6_hib_mode);
- break;
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8350_dcdc_set_suspend_disable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int dcdc = rdev_get_id(rdev);
- u16 val;
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);
- wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,
- val | WM8350_DCDC_HIB_MODE_DIS);
- break;
- case WM8350_DCDC_3:
- val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);
- wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,
- val | WM8350_DCDC_HIB_MODE_DIS);
- break;
- case WM8350_DCDC_4:
- val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);
- wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,
- val | WM8350_DCDC_HIB_MODE_DIS);
- break;
- case WM8350_DCDC_6:
- val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);
- wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,
- val | WM8350_DCDC_HIB_MODE_DIS);
- break;
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8350_dcdc25_set_suspend_enable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int dcdc = rdev_get_id(rdev);
- u16 val;
-
- switch (dcdc) {
- case WM8350_DCDC_2:
- val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
- & ~WM8350_DC2_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
- (WM8350_DC2_HIB_MODE_ACTIVE << WM8350_DC2_HIB_MODE_SHIFT));
- break;
- case WM8350_DCDC_5:
- val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
- & ~WM8350_DC5_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
- (WM8350_DC5_HIB_MODE_ACTIVE << WM8350_DC5_HIB_MODE_SHIFT));
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int wm8350_dcdc25_set_suspend_disable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int dcdc = rdev_get_id(rdev);
- u16 val;
-
- switch (dcdc) {
- case WM8350_DCDC_2:
- val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
- & ~WM8350_DC2_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
- (WM8350_DC2_HIB_MODE_DISABLE << WM8350_DC2_HIB_MODE_SHIFT));
- break;
- case WM8350_DCDC_5:
- val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
- & ~WM8350_DC5_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
- (WM8350_DC5_HIB_MODE_DISABLE << WM8350_DC5_HIB_MODE_SHIFT));
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,
- unsigned int mode)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int dcdc = rdev_get_id(rdev);
- u16 *hib_mode;
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- hib_mode = &wm8350->pmic.dcdc1_hib_mode;
- break;
- case WM8350_DCDC_3:
- hib_mode = &wm8350->pmic.dcdc3_hib_mode;
- break;
- case WM8350_DCDC_4:
- hib_mode = &wm8350->pmic.dcdc4_hib_mode;
- break;
- case WM8350_DCDC_6:
- hib_mode = &wm8350->pmic.dcdc6_hib_mode;
- break;
- case WM8350_DCDC_2:
- case WM8350_DCDC_5:
- default:
- return -EINVAL;
- }
-
- switch (mode) {
- case REGULATOR_MODE_NORMAL:
- *hib_mode = WM8350_DCDC_HIB_MODE_IMAGE;
- break;
- case REGULATOR_MODE_IDLE:
- *hib_mode = WM8350_DCDC_HIB_MODE_STANDBY;
- break;
- case REGULATOR_MODE_STANDBY:
- *hib_mode = WM8350_DCDC_HIB_MODE_LDO_IM;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct linear_range wm8350_ldo_ranges[] = {
- REGULATOR_LINEAR_RANGE(900000, 0, 15, 50000),
- REGULATOR_LINEAR_RANGE(1800000, 16, 31, 100000),
-};
-
-static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int sel, volt_reg, ldo = rdev_get_id(rdev);
- u16 val;
-
- dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, uV / 1000);
-
- switch (ldo) {
- case WM8350_LDO_1:
- volt_reg = WM8350_LDO1_LOW_POWER;
- break;
- case WM8350_LDO_2:
- volt_reg = WM8350_LDO2_LOW_POWER;
- break;
- case WM8350_LDO_3:
- volt_reg = WM8350_LDO3_LOW_POWER;
- break;
- case WM8350_LDO_4:
- volt_reg = WM8350_LDO4_LOW_POWER;
- break;
- default:
- return -EINVAL;
- }
-
- sel = regulator_map_voltage_linear_range(rdev, uV, uV);
- if (sel < 0)
- return sel;
-
- /* all LDOs have same mV bits */
- val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK;
- wm8350_reg_write(wm8350, volt_reg, val | sel);
- return 0;
-}
-
-static int wm8350_ldo_set_suspend_enable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int volt_reg, ldo = rdev_get_id(rdev);
- u16 val;
-
- switch (ldo) {
- case WM8350_LDO_1:
- volt_reg = WM8350_LDO1_LOW_POWER;
- break;
- case WM8350_LDO_2:
- volt_reg = WM8350_LDO2_LOW_POWER;
- break;
- case WM8350_LDO_3:
- volt_reg = WM8350_LDO3_LOW_POWER;
- break;
- case WM8350_LDO_4:
- volt_reg = WM8350_LDO4_LOW_POWER;
- break;
- default:
- return -EINVAL;
- }
-
- /* all LDOs have same mV bits */
- val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, volt_reg, val);
- return 0;
-}
-
-static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int volt_reg, ldo = rdev_get_id(rdev);
- u16 val;
-
- switch (ldo) {
- case WM8350_LDO_1:
- volt_reg = WM8350_LDO1_LOW_POWER;
- break;
- case WM8350_LDO_2:
- volt_reg = WM8350_LDO2_LOW_POWER;
- break;
- case WM8350_LDO_3:
- volt_reg = WM8350_LDO3_LOW_POWER;
- break;
- case WM8350_LDO_4:
- volt_reg = WM8350_LDO4_LOW_POWER;
- break;
- default:
- return -EINVAL;
- }
-
- /* all LDOs have same mV bits */
- val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;
- wm8350_reg_write(wm8350, volt_reg, val | WM8350_LDO1_HIB_MODE_DIS);
- return 0;
-}
-
-int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
- u16 stop, u16 fault)
-{
- int slot_reg;
- u16 val;
-
- dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",
- __func__, dcdc, start, stop);
-
- /* slot valid ? */
- if (start > 15 || stop > 15)
- return -EINVAL;
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- slot_reg = WM8350_DCDC1_TIMEOUTS;
- break;
- case WM8350_DCDC_2:
- slot_reg = WM8350_DCDC2_TIMEOUTS;
- break;
- case WM8350_DCDC_3:
- slot_reg = WM8350_DCDC3_TIMEOUTS;
- break;
- case WM8350_DCDC_4:
- slot_reg = WM8350_DCDC4_TIMEOUTS;
- break;
- case WM8350_DCDC_5:
- slot_reg = WM8350_DCDC5_TIMEOUTS;
- break;
- case WM8350_DCDC_6:
- slot_reg = WM8350_DCDC6_TIMEOUTS;
- break;
- default:
- return -EINVAL;
- }
-
- val = wm8350_reg_read(wm8350, slot_reg) &
- ~(WM8350_DC1_ENSLOT_MASK | WM8350_DC1_SDSLOT_MASK |
- WM8350_DC1_ERRACT_MASK);
- wm8350_reg_write(wm8350, slot_reg,
- val | (start << WM8350_DC1_ENSLOT_SHIFT) |
- (stop << WM8350_DC1_SDSLOT_SHIFT) |
- (fault << WM8350_DC1_ERRACT_SHIFT));
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_dcdc_set_slot);
-
-int wm8350_ldo_set_slot(struct wm8350 *wm8350, int ldo, u16 start, u16 stop)
-{
- int slot_reg;
- u16 val;
-
- dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",
- __func__, ldo, start, stop);
-
- /* slot valid ? */
- if (start > 15 || stop > 15)
- return -EINVAL;
-
- switch (ldo) {
- case WM8350_LDO_1:
- slot_reg = WM8350_LDO1_TIMEOUTS;
- break;
- case WM8350_LDO_2:
- slot_reg = WM8350_LDO2_TIMEOUTS;
- break;
- case WM8350_LDO_3:
- slot_reg = WM8350_LDO3_TIMEOUTS;
- break;
- case WM8350_LDO_4:
- slot_reg = WM8350_LDO4_TIMEOUTS;
- break;
- default:
- return -EINVAL;
- }
-
- val = wm8350_reg_read(wm8350, slot_reg) & ~WM8350_LDO1_SDSLOT_MASK;
- wm8350_reg_write(wm8350, slot_reg, val | ((start << 10) | (stop << 6)));
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_ldo_set_slot);
-
-int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode,
- u16 ilim, u16 ramp, u16 feedback)
-{
- u16 val;
-
- dev_dbg(wm8350->dev, "%s %d mode: %s %s\n", __func__, dcdc,
- mode ? "normal" : "boost", ilim ? "low" : "normal");
-
- switch (dcdc) {
- case WM8350_DCDC_2:
- val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
- & ~(WM8350_DC2_MODE_MASK | WM8350_DC2_ILIM_MASK |
- WM8350_DC2_RMP_MASK | WM8350_DC2_FBSRC_MASK);
- wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
- (mode << WM8350_DC2_MODE_SHIFT) |
- (ilim << WM8350_DC2_ILIM_SHIFT) |
- (ramp << WM8350_DC2_RMP_SHIFT) |
- (feedback << WM8350_DC2_FBSRC_SHIFT));
- break;
- case WM8350_DCDC_5:
- val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
- & ~(WM8350_DC5_MODE_MASK | WM8350_DC5_ILIM_MASK |
- WM8350_DC5_RMP_MASK | WM8350_DC5_FBSRC_MASK);
- wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
- (mode << WM8350_DC5_MODE_SHIFT) |
- (ilim << WM8350_DC5_ILIM_SHIFT) |
- (ramp << WM8350_DC5_RMP_SHIFT) |
- (feedback << WM8350_DC5_FBSRC_SHIFT));
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_dcdc25_set_mode);
-
-static int force_continuous_enable(struct wm8350 *wm8350, int dcdc, int enable)
-{
- int reg = 0, ret;
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- reg = WM8350_DCDC1_FORCE_PWM;
- break;
- case WM8350_DCDC_3:
- reg = WM8350_DCDC3_FORCE_PWM;
- break;
- case WM8350_DCDC_4:
- reg = WM8350_DCDC4_FORCE_PWM;
- break;
- case WM8350_DCDC_6:
- reg = WM8350_DCDC6_FORCE_PWM;
- break;
- default:
- return -EINVAL;
- }
-
- if (enable)
- ret = wm8350_set_bits(wm8350, reg,
- WM8350_DCDC1_FORCE_PWM_ENA);
- else
- ret = wm8350_clear_bits(wm8350, reg,
- WM8350_DCDC1_FORCE_PWM_ENA);
- return ret;
-}
-
-static int wm8350_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int dcdc = rdev_get_id(rdev);
- u16 val;
-
- if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
- return -EINVAL;
-
- if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
- return -EINVAL;
-
- val = 1 << (dcdc - WM8350_DCDC_1);
-
- switch (mode) {
- case REGULATOR_MODE_FAST:
- /* force continuous mode */
- wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
- wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
- force_continuous_enable(wm8350, dcdc, 1);
- break;
- case REGULATOR_MODE_NORMAL:
- /* active / pulse skipping */
- wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
- wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
- force_continuous_enable(wm8350, dcdc, 0);
- break;
- case REGULATOR_MODE_IDLE:
- /* standby mode */
- force_continuous_enable(wm8350, dcdc, 0);
- wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
- wm8350_clear_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
- break;
- case REGULATOR_MODE_STANDBY:
- /* LDO mode */
- force_continuous_enable(wm8350, dcdc, 0);
- wm8350_set_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
- break;
- }
-
- return 0;
-}
-
-static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
-{
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- int dcdc = rdev_get_id(rdev);
- u16 mask, sleep, active, force;
- int mode = REGULATOR_MODE_NORMAL;
- int reg;
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- reg = WM8350_DCDC1_FORCE_PWM;
- break;
- case WM8350_DCDC_3:
- reg = WM8350_DCDC3_FORCE_PWM;
- break;
- case WM8350_DCDC_4:
- reg = WM8350_DCDC4_FORCE_PWM;
- break;
- case WM8350_DCDC_6:
- reg = WM8350_DCDC6_FORCE_PWM;
- break;
- default:
- return -EINVAL;
- }
-
- mask = 1 << (dcdc - WM8350_DCDC_1);
- active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
- force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
- sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
-
- dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
- mask, active, sleep, force);
-
- if (active && !sleep) {
- if (force)
- mode = REGULATOR_MODE_FAST;
- else
- mode = REGULATOR_MODE_NORMAL;
- } else if (!active && !sleep)
- mode = REGULATOR_MODE_IDLE;
- else if (sleep)
- mode = REGULATOR_MODE_STANDBY;
-
- return mode;
-}
-
-static unsigned int wm8350_ldo_get_mode(struct regulator_dev *rdev)
-{
- return REGULATOR_MODE_NORMAL;
-}
-
-struct wm8350_dcdc_efficiency {
- int uA_load_min;
- int uA_load_max;
- unsigned int mode;
-};
-
-static const struct wm8350_dcdc_efficiency dcdc1_6_efficiency[] = {
- {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */
- {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */
- {100000, 1000000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */
- {-1, -1, REGULATOR_MODE_NORMAL},
-};
-
-static const struct wm8350_dcdc_efficiency dcdc3_4_efficiency[] = {
- {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */
- {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */
- {100000, 800000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */
- {-1, -1, REGULATOR_MODE_NORMAL},
-};
-
-static unsigned int get_mode(int uA, const struct wm8350_dcdc_efficiency *eff)
-{
- int i = 0;
-
- while (eff[i].uA_load_min != -1) {
- if (uA >= eff[i].uA_load_min && uA <= eff[i].uA_load_max)
- return eff[i].mode;
- i++;
- }
- return REGULATOR_MODE_NORMAL;
-}
-
-/* Query the regulator for it's most efficient mode @ uV,uA
- * WM8350 regulator efficiency is pretty similar over
- * different input and output uV.
- */
-static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev,
- int input_uV, int output_uV,
- int output_uA)
-{
- int dcdc = rdev_get_id(rdev), mode;
-
- switch (dcdc) {
- case WM8350_DCDC_1:
- case WM8350_DCDC_6:
- mode = get_mode(output_uA, dcdc1_6_efficiency);
- break;
- case WM8350_DCDC_3:
- case WM8350_DCDC_4:
- mode = get_mode(output_uA, dcdc3_4_efficiency);
- break;
- default:
- mode = REGULATOR_MODE_NORMAL;
- break;
- }
- return mode;
-}
-
-static const struct regulator_ops wm8350_dcdc_ops = {
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .list_voltage = regulator_list_voltage_linear,
- .map_voltage = regulator_map_voltage_linear,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_mode = wm8350_dcdc_get_mode,
- .set_mode = wm8350_dcdc_set_mode,
- .get_optimum_mode = wm8350_dcdc_get_optimum_mode,
- .set_suspend_voltage = wm8350_dcdc_set_suspend_voltage,
- .set_suspend_enable = wm8350_dcdc_set_suspend_enable,
- .set_suspend_disable = wm8350_dcdc_set_suspend_disable,
- .set_suspend_mode = wm8350_dcdc_set_suspend_mode,
-};
-
-static const struct regulator_ops wm8350_dcdc2_5_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .set_suspend_enable = wm8350_dcdc25_set_suspend_enable,
- .set_suspend_disable = wm8350_dcdc25_set_suspend_disable,
-};
-
-static const struct regulator_ops wm8350_ldo_ops = {
- .map_voltage = regulator_map_voltage_linear_range,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .list_voltage = regulator_list_voltage_linear_range,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_mode = wm8350_ldo_get_mode,
- .set_suspend_voltage = wm8350_ldo_set_suspend_voltage,
- .set_suspend_enable = wm8350_ldo_set_suspend_enable,
- .set_suspend_disable = wm8350_ldo_set_suspend_disable,
-};
-
-static const struct regulator_ops wm8350_isink_ops = {
- .set_current_limit = regulator_set_current_limit_regmap,
- .get_current_limit = regulator_get_current_limit_regmap,
- .enable = wm8350_isink_enable,
- .disable = wm8350_isink_disable,
- .is_enabled = wm8350_isink_is_enabled,
- .enable_time = wm8350_isink_enable_time,
-};
-
-static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
- {
- .name = "DCDC1",
- .id = WM8350_DCDC_1,
- .ops = &wm8350_dcdc_ops,
- .irq = WM8350_IRQ_UV_DC1,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
- .min_uV = 850000,
- .uV_step = 25000,
- .vsel_reg = WM8350_DCDC1_CONTROL,
- .vsel_mask = WM8350_DC1_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_DC1_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC2",
- .id = WM8350_DCDC_2,
- .ops = &wm8350_dcdc2_5_ops,
- .irq = WM8350_IRQ_UV_DC2,
- .type = REGULATOR_VOLTAGE,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_DC2_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC3",
- .id = WM8350_DCDC_3,
- .ops = &wm8350_dcdc_ops,
- .irq = WM8350_IRQ_UV_DC3,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
- .min_uV = 850000,
- .uV_step = 25000,
- .vsel_reg = WM8350_DCDC3_CONTROL,
- .vsel_mask = WM8350_DC3_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_DC3_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC4",
- .id = WM8350_DCDC_4,
- .ops = &wm8350_dcdc_ops,
- .irq = WM8350_IRQ_UV_DC4,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
- .min_uV = 850000,
- .uV_step = 25000,
- .vsel_reg = WM8350_DCDC4_CONTROL,
- .vsel_mask = WM8350_DC4_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_DC4_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC5",
- .id = WM8350_DCDC_5,
- .ops = &wm8350_dcdc2_5_ops,
- .irq = WM8350_IRQ_UV_DC5,
- .type = REGULATOR_VOLTAGE,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_DC5_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC6",
- .id = WM8350_DCDC_6,
- .ops = &wm8350_dcdc_ops,
- .irq = WM8350_IRQ_UV_DC6,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
- .min_uV = 850000,
- .uV_step = 25000,
- .vsel_reg = WM8350_DCDC6_CONTROL,
- .vsel_mask = WM8350_DC6_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_DC6_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO1",
- .id = WM8350_LDO_1,
- .ops = &wm8350_ldo_ops,
- .irq = WM8350_IRQ_UV_LDO1,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_LDO1_VSEL_MASK + 1,
- .linear_ranges = wm8350_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
- .vsel_reg = WM8350_LDO1_CONTROL,
- .vsel_mask = WM8350_LDO1_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_LDO1_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO2",
- .id = WM8350_LDO_2,
- .ops = &wm8350_ldo_ops,
- .irq = WM8350_IRQ_UV_LDO2,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_LDO2_VSEL_MASK + 1,
- .linear_ranges = wm8350_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
- .vsel_reg = WM8350_LDO2_CONTROL,
- .vsel_mask = WM8350_LDO2_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_LDO2_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO3",
- .id = WM8350_LDO_3,
- .ops = &wm8350_ldo_ops,
- .irq = WM8350_IRQ_UV_LDO3,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_LDO3_VSEL_MASK + 1,
- .linear_ranges = wm8350_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
- .vsel_reg = WM8350_LDO3_CONTROL,
- .vsel_mask = WM8350_LDO3_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_LDO3_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO4",
- .id = WM8350_LDO_4,
- .ops = &wm8350_ldo_ops,
- .irq = WM8350_IRQ_UV_LDO4,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = WM8350_LDO4_VSEL_MASK + 1,
- .linear_ranges = wm8350_ldo_ranges,
- .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
- .vsel_reg = WM8350_LDO4_CONTROL,
- .vsel_mask = WM8350_LDO4_VSEL_MASK,
- .enable_reg = WM8350_DCDC_LDO_REQUESTED,
- .enable_mask = WM8350_LDO4_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "ISINKA",
- .id = WM8350_ISINK_A,
- .ops = &wm8350_isink_ops,
- .irq = WM8350_IRQ_CS1,
- .type = REGULATOR_CURRENT,
- .owner = THIS_MODULE,
- .curr_table = isink_cur,
- .n_current_limits = ARRAY_SIZE(isink_cur),
- .csel_reg = WM8350_CURRENT_SINK_DRIVER_A,
- .csel_mask = WM8350_CS1_ISEL_MASK,
- },
- {
- .name = "ISINKB",
- .id = WM8350_ISINK_B,
- .ops = &wm8350_isink_ops,
- .irq = WM8350_IRQ_CS2,
- .type = REGULATOR_CURRENT,
- .owner = THIS_MODULE,
- .curr_table = isink_cur,
- .n_current_limits = ARRAY_SIZE(isink_cur),
- .csel_reg = WM8350_CURRENT_SINK_DRIVER_B,
- .csel_mask = WM8350_CS2_ISEL_MASK,
- },
-};
-
-static irqreturn_t pmic_uv_handler(int irq, void *data)
-{
- struct regulator_dev *rdev = (struct regulator_dev *)data;
-
- if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
- regulator_notifier_call_chain(rdev,
- REGULATOR_EVENT_REGULATION_OUT,
- NULL);
- else
- regulator_notifier_call_chain(rdev,
- REGULATOR_EVENT_UNDER_VOLTAGE,
- NULL);
-
- return IRQ_HANDLED;
-}
-
-static int wm8350_regulator_probe(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
- struct regulator_config config = { };
- struct regulator_dev *rdev;
- int ret;
- u16 val;
-
- if (pdev->id < WM8350_DCDC_1 || pdev->id > WM8350_ISINK_B)
- return -ENODEV;
-
- /* do any regulator specific init */
- switch (pdev->id) {
- case WM8350_DCDC_1:
- val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);
- wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- break;
- case WM8350_DCDC_3:
- val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);
- wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- break;
- case WM8350_DCDC_4:
- val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);
- wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- break;
- case WM8350_DCDC_6:
- val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);
- wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
- break;
- }
-
- config.dev = &pdev->dev;
- config.init_data = dev_get_platdata(&pdev->dev);
- config.driver_data = dev_get_drvdata(&pdev->dev);
- config.regmap = wm8350->regmap;
-
- /* register regulator */
- rdev = devm_regulator_register(&pdev->dev, &wm8350_reg[pdev->id],
- &config);
- if (IS_ERR(rdev)) {
- dev_err(&pdev->dev, "failed to register %s\n",
- wm8350_reg[pdev->id].name);
- return PTR_ERR(rdev);
- }
-
- /* register regulator IRQ */
- ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq,
- pmic_uv_handler, 0, "UV", rdev);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to register regulator %s IRQ\n",
- wm8350_reg[pdev->id].name);
- return ret;
- }
-
- return 0;
-}
-
-static void wm8350_regulator_remove(struct platform_device *pdev)
-{
- struct regulator_dev *rdev = platform_get_drvdata(pdev);
- struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
-
- wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
-}
-
-int wm8350_register_regulator(struct wm8350 *wm8350, int reg,
- struct regulator_init_data *initdata)
-{
- struct platform_device *pdev;
- int ret;
- if (reg < 0 || reg >= NUM_WM8350_REGULATORS)
- return -EINVAL;
-
- if (wm8350->pmic.pdev[reg])
- return -EBUSY;
-
- if (reg >= WM8350_DCDC_1 && reg <= WM8350_DCDC_6 &&
- reg > wm8350->pmic.max_dcdc)
- return -ENODEV;
- if (reg >= WM8350_ISINK_A && reg <= WM8350_ISINK_B &&
- reg > wm8350->pmic.max_isink)
- return -ENODEV;
-
- pdev = platform_device_alloc("wm8350-regulator", reg);
- if (!pdev)
- return -ENOMEM;
-
- wm8350->pmic.pdev[reg] = pdev;
-
- initdata->driver_data = wm8350;
-
- pdev->dev.platform_data = initdata;
- pdev->dev.parent = wm8350->dev;
- platform_set_drvdata(pdev, wm8350);
-
- ret = platform_device_add(pdev);
-
- if (ret != 0) {
- dev_err(wm8350->dev, "Failed to register regulator %d: %d\n",
- reg, ret);
- platform_device_put(pdev);
- wm8350->pmic.pdev[reg] = NULL;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(wm8350_register_regulator);
-
-/**
- * wm8350_register_led - Register a WM8350 LED output
- *
- * @wm8350: The WM8350 device to configure.
- * @lednum: LED device index to create.
- * @dcdc: The DCDC to use for the LED.
- * @isink: The ISINK to use for the LED.
- * @pdata: Configuration for the LED.
- *
- * The WM8350 supports the use of an ISINK together with a DCDC to
- * provide a power-efficient LED driver. This function registers the
- * regulators and instantiates the platform device for a LED. The
- * operating modes for the LED regulators must be configured using
- * wm8350_isink_set_flash(), wm8350_dcdc25_set_mode() and
- * wm8350_dcdc_set_slot() prior to calling this function.
- */
-int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
- struct wm8350_led_platform_data *pdata)
-{
- struct wm8350_led *led;
- struct platform_device *pdev;
- int ret;
-
- if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
- dev_err(wm8350->dev, "Invalid LED index %d\n", lednum);
- return -ENODEV;
- }
-
- led = &wm8350->pmic.led[lednum];
-
- if (led->pdev) {
- dev_err(wm8350->dev, "LED %d already allocated\n", lednum);
- return -EINVAL;
- }
-
- pdev = platform_device_alloc("wm8350-led", lednum);
- if (pdev == NULL) {
- dev_err(wm8350->dev, "Failed to allocate LED %d\n", lednum);
- return -ENOMEM;
- }
-
- led->isink_consumer.dev_name = dev_name(&pdev->dev);
- led->isink_consumer.supply = "led_isink";
- led->isink_init.num_consumer_supplies = 1;
- led->isink_init.consumer_supplies = &led->isink_consumer;
- led->isink_init.constraints.min_uA = 0;
- led->isink_init.constraints.max_uA = pdata->max_uA;
- led->isink_init.constraints.valid_ops_mask
- = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS;
- led->isink_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
- ret = wm8350_register_regulator(wm8350, isink, &led->isink_init);
- if (ret != 0) {
- platform_device_put(pdev);
- return ret;
- }
-
- led->dcdc_consumer.dev_name = dev_name(&pdev->dev);
- led->dcdc_consumer.supply = "led_vcc";
- led->dcdc_init.num_consumer_supplies = 1;
- led->dcdc_init.consumer_supplies = &led->dcdc_consumer;
- led->dcdc_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
- led->dcdc_init.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
- ret = wm8350_register_regulator(wm8350, dcdc, &led->dcdc_init);
- if (ret != 0) {
- platform_device_put(pdev);
- return ret;
- }
-
- switch (isink) {
- case WM8350_ISINK_A:
- wm8350->pmic.isink_A_dcdc = dcdc;
- break;
- case WM8350_ISINK_B:
- wm8350->pmic.isink_B_dcdc = dcdc;
- break;
- }
-
- pdev->dev.platform_data = pdata;
- pdev->dev.parent = wm8350->dev;
- ret = platform_device_add(pdev);
- if (ret != 0) {
- dev_err(wm8350->dev, "Failed to register LED %d: %d\n",
- lednum, ret);
- platform_device_put(pdev);
- return ret;
- }
-
- led->pdev = pdev;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_register_led);
-
-static struct platform_driver wm8350_regulator_driver = {
- .probe = wm8350_regulator_probe,
- .remove = wm8350_regulator_remove,
- .driver = {
- .name = "wm8350-regulator",
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- },
-};
-
-static int __init wm8350_regulator_init(void)
-{
- return platform_driver_register(&wm8350_regulator_driver);
-}
-subsys_initcall(wm8350_regulator_init);
-
-static void __exit wm8350_regulator_exit(void)
-{
- platform_driver_unregister(&wm8350_regulator_driver);
-}
-module_exit(wm8350_regulator_exit);
-
-/* Module information */
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-regulator");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index c71398368f6d..4120ff2cebc3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1315,16 +1315,6 @@ config RTC_DRV_WM831X
This driver can also be built as a module. If so, the module
will be called "rtc-wm831x".
-config RTC_DRV_WM8350
- tristate "Wolfson Microelectronics WM8350 RTC"
- depends on MFD_WM8350
- help
- If you say yes here you will get support for the RTC subsystem
- of the Wolfson Microelectronics WM8350.
-
- This driver can also be built as a module. If so, the module
- will be called "rtc-wm8350".
-
config RTC_DRV_SC27XX
tristate "Spreadtrum SC27xx RTC"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index b8fc1a17d27f..0c805fe59608 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -193,7 +193,6 @@ obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o
obj-$(CONFIG_RTC_DRV_WILCO_EC) += rtc-wilco-ec.o
obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o
-obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o
obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
deleted file mode 100644
index 3bd60d067a5e..000000000000
--- a/drivers/rtc/rtc-wm8350.c
+++ /dev/null
@@ -1,474 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Real Time Clock driver for Wolfson Microelectronics WM8350
- *
- * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood
- * linux@wolfsonmicro.com
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/interrupt.h>
-#include <linux/ioctl.h>
-#include <linux/completion.h>
-#include <linux/mfd/wm8350/rtc.h>
-#include <linux/mfd/wm8350/core.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-
-#define WM8350_SET_ALM_RETRIES 5
-#define WM8350_SET_TIME_RETRIES 5
-#define WM8350_GET_TIME_RETRIES 5
-
-/*
- * Read current time and date in RTC
- */
-static int wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- u16 time1[4], time2[4];
- int retries = WM8350_GET_TIME_RETRIES, ret;
-
- /*
- * Read the time twice and compare.
- * If time1 == time2, then time is valid else retry.
- */
- do {
- ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
- 4, time1);
- if (ret < 0)
- return ret;
- ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
- 4, time2);
- if (ret < 0)
- return ret;
-
- if (memcmp(time1, time2, sizeof(time1)) == 0) {
- tm->tm_sec = time1[0] & WM8350_RTC_SECS_MASK;
-
- tm->tm_min = (time1[0] & WM8350_RTC_MINS_MASK)
- >> WM8350_RTC_MINS_SHIFT;
-
- tm->tm_hour = time1[1] & WM8350_RTC_HRS_MASK;
-
- tm->tm_wday = ((time1[1] >> WM8350_RTC_DAY_SHIFT)
- & 0x7) - 1;
-
- tm->tm_mon = ((time1[2] & WM8350_RTC_MTH_MASK)
- >> WM8350_RTC_MTH_SHIFT) - 1;
-
- tm->tm_mday = (time1[2] & WM8350_RTC_DATE_MASK);
-
- tm->tm_year = ((time1[3] & WM8350_RTC_YHUNDREDS_MASK)
- >> WM8350_RTC_YHUNDREDS_SHIFT) * 100;
- tm->tm_year += time1[3] & WM8350_RTC_YUNITS_MASK;
-
- tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon,
- tm->tm_year);
- tm->tm_year -= 1900;
-
- dev_dbg(dev, "Read (%d left): %04x %04x %04x %04x\n",
- retries,
- time1[0], time1[1], time1[2], time1[3]);
-
- return 0;
- }
- } while (retries--);
-
- dev_err(dev, "timed out reading RTC time\n");
- return -EIO;
-}
-
-/*
- * Set current time and date in RTC
- */
-static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- u16 time[4];
- u16 rtc_ctrl;
- int ret, retries = WM8350_SET_TIME_RETRIES;
-
- time[0] = tm->tm_sec;
- time[0] |= tm->tm_min << WM8350_RTC_MINS_SHIFT;
- time[1] = tm->tm_hour;
- time[1] |= (tm->tm_wday + 1) << WM8350_RTC_DAY_SHIFT;
- time[2] = tm->tm_mday;
- time[2] |= (tm->tm_mon + 1) << WM8350_RTC_MTH_SHIFT;
- time[3] = ((tm->tm_year + 1900) / 100) << WM8350_RTC_YHUNDREDS_SHIFT;
- time[3] |= (tm->tm_year + 1900) % 100;
-
- dev_dbg(dev, "Setting: %04x %04x %04x %04x\n",
- time[0], time[1], time[2], time[3]);
-
- /* Set RTC_SET to stop the clock */
- ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, WM8350_RTC_SET);
- if (ret < 0)
- return ret;
-
- /* Wait until confirmation of stopping */
- do {
- rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
- schedule_timeout_uninterruptible(msecs_to_jiffies(1));
- } while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
-
- if (!retries) {
- dev_err(dev, "timed out on set confirmation\n");
- return -EIO;
- }
-
- /* Write time to RTC */
- ret = wm8350_block_write(wm8350, WM8350_RTC_SECONDS_MINUTES, 4, time);
- if (ret < 0)
- return ret;
-
- /* Clear RTC_SET to start the clock */
- ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
- WM8350_RTC_SET);
- return ret;
-}
-
-/*
- * Read alarm time and date in RTC
- */
-static int wm8350_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- struct rtc_time *tm = &alrm->time;
- u16 time[4];
- int ret;
-
- ret = wm8350_block_read(wm8350, WM8350_ALARM_SECONDS_MINUTES, 4, time);
- if (ret < 0)
- return ret;
-
- tm->tm_sec = time[0] & WM8350_RTC_ALMSECS_MASK;
- if (tm->tm_sec == WM8350_RTC_ALMSECS_MASK)
- tm->tm_sec = -1;
-
- tm->tm_min = time[0] & WM8350_RTC_ALMMINS_MASK;
- if (tm->tm_min == WM8350_RTC_ALMMINS_MASK)
- tm->tm_min = -1;
- else
- tm->tm_min >>= WM8350_RTC_ALMMINS_SHIFT;
-
- tm->tm_hour = time[1] & WM8350_RTC_ALMHRS_MASK;
- if (tm->tm_hour == WM8350_RTC_ALMHRS_MASK)
- tm->tm_hour = -1;
-
- tm->tm_wday = ((time[1] >> WM8350_RTC_ALMDAY_SHIFT) & 0x7) - 1;
- if (tm->tm_wday > 7)
- tm->tm_wday = -1;
-
- tm->tm_mon = time[2] & WM8350_RTC_ALMMTH_MASK;
- if (tm->tm_mon == WM8350_RTC_ALMMTH_MASK)
- tm->tm_mon = -1;
- else
- tm->tm_mon = (tm->tm_mon >> WM8350_RTC_ALMMTH_SHIFT) - 1;
-
- tm->tm_mday = (time[2] & WM8350_RTC_ALMDATE_MASK);
- if (tm->tm_mday == WM8350_RTC_ALMDATE_MASK)
- tm->tm_mday = -1;
-
- tm->tm_year = -1;
-
- alrm->enabled = !(time[3] & WM8350_RTC_ALMSTS);
-
- return 0;
-}
-
-static int wm8350_rtc_stop_alarm(struct wm8350 *wm8350)
-{
- int retries = WM8350_SET_ALM_RETRIES;
- u16 rtc_ctrl;
- int ret;
-
- /* Set RTC_SET to stop the clock */
- ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL,
- WM8350_RTC_ALMSET);
- if (ret < 0)
- return ret;
-
- /* Wait until confirmation of stopping */
- do {
- rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
- schedule_timeout_uninterruptible(msecs_to_jiffies(1));
- } while (retries-- && !(rtc_ctrl & WM8350_RTC_ALMSTS));
-
- if (!(rtc_ctrl & WM8350_RTC_ALMSTS))
- return -ETIMEDOUT;
-
- return 0;
-}
-
-static int wm8350_rtc_start_alarm(struct wm8350 *wm8350)
-{
- int ret;
- int retries = WM8350_SET_ALM_RETRIES;
- u16 rtc_ctrl;
-
- ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
- WM8350_RTC_ALMSET);
- if (ret < 0)
- return ret;
-
- /* Wait until confirmation */
- do {
- rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
- schedule_timeout_uninterruptible(msecs_to_jiffies(1));
- } while (retries-- && rtc_ctrl & WM8350_RTC_ALMSTS);
-
- if (rtc_ctrl & WM8350_RTC_ALMSTS)
- return -ETIMEDOUT;
-
- return 0;
-}
-
-static int wm8350_rtc_alarm_irq_enable(struct device *dev,
- unsigned int enabled)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
-
- if (enabled)
- return wm8350_rtc_start_alarm(wm8350);
- else
- return wm8350_rtc_stop_alarm(wm8350);
-}
-
-static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- struct rtc_time *tm = &alrm->time;
- u16 time[3];
- int ret;
-
- memset(time, 0, sizeof(time));
-
- if (tm->tm_sec != -1)
- time[0] |= tm->tm_sec;
- else
- time[0] |= WM8350_RTC_ALMSECS_MASK;
-
- if (tm->tm_min != -1)
- time[0] |= tm->tm_min << WM8350_RTC_ALMMINS_SHIFT;
- else
- time[0] |= WM8350_RTC_ALMMINS_MASK;
-
- if (tm->tm_hour != -1)
- time[1] |= tm->tm_hour;
- else
- time[1] |= WM8350_RTC_ALMHRS_MASK;
-
- if (tm->tm_wday != -1)
- time[1] |= (tm->tm_wday + 1) << WM8350_RTC_ALMDAY_SHIFT;
- else
- time[1] |= WM8350_RTC_ALMDAY_MASK;
-
- if (tm->tm_mday != -1)
- time[2] |= tm->tm_mday;
- else
- time[2] |= WM8350_RTC_ALMDATE_MASK;
-
- if (tm->tm_mon != -1)
- time[2] |= (tm->tm_mon + 1) << WM8350_RTC_ALMMTH_SHIFT;
- else
- time[2] |= WM8350_RTC_ALMMTH_MASK;
-
- ret = wm8350_rtc_stop_alarm(wm8350);
- if (ret < 0)
- return ret;
-
- /* Write time to RTC */
- ret = wm8350_block_write(wm8350, WM8350_ALARM_SECONDS_MINUTES,
- 3, time);
- if (ret < 0)
- return ret;
-
- if (alrm->enabled)
- ret = wm8350_rtc_start_alarm(wm8350);
-
- return ret;
-}
-
-static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data)
-{
- struct wm8350 *wm8350 = data;
- struct rtc_device *rtc = wm8350->rtc.rtc;
- int ret;
-
- rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
-
- /* Make it one shot */
- ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL,
- WM8350_RTC_ALMSET);
- if (ret != 0) {
- dev_err(&(wm8350->rtc.pdev->dev),
- "Failed to disable alarm: %d\n", ret);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t wm8350_rtc_update_handler(int irq, void *data)
-{
- struct wm8350 *wm8350 = data;
- struct rtc_device *rtc = wm8350->rtc.rtc;
-
- rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF);
-
- return IRQ_HANDLED;
-}
-
-static const struct rtc_class_ops wm8350_rtc_ops = {
- .read_time = wm8350_rtc_readtime,
- .set_time = wm8350_rtc_settime,
- .read_alarm = wm8350_rtc_readalarm,
- .set_alarm = wm8350_rtc_setalarm,
- .alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int wm8350_rtc_suspend(struct device *dev)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- int ret = 0;
- u16 reg;
-
- reg = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
-
- if (device_may_wakeup(&wm8350->rtc.pdev->dev) &&
- reg & WM8350_RTC_ALMSTS) {
- ret = wm8350_rtc_stop_alarm(wm8350);
- if (ret != 0)
- dev_err(dev, "Failed to stop RTC alarm: %d\n", ret);
- }
-
- return ret;
-}
-
-static int wm8350_rtc_resume(struct device *dev)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
- int ret;
-
- if (wm8350->rtc.alarm_enabled) {
- ret = wm8350_rtc_start_alarm(wm8350);
- if (ret != 0)
- dev_err(dev, "Failed to restart RTC alarm: %d\n", ret);
- }
-
- return 0;
-}
-#endif
-
-static int wm8350_rtc_probe(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- struct wm8350_rtc *wm_rtc = &wm8350->rtc;
- int ret = 0;
- u16 timectl, power5;
-
- timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
- if (timectl & WM8350_RTC_BCD) {
- dev_err(&pdev->dev, "RTC BCD mode not supported\n");
- return -EINVAL;
- }
- if (timectl & WM8350_RTC_12HR) {
- dev_err(&pdev->dev, "RTC 12 hour mode not supported\n");
- return -EINVAL;
- }
-
- /* enable the RTC if it's not already enabled */
- power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
- if (!(power5 & WM8350_RTC_TICK_ENA)) {
- wm8350_reg_unlock(wm8350);
-
- ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5,
- WM8350_RTC_TICK_ENA);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret);
- return ret;
- }
-
- wm8350_reg_lock(wm8350);
- }
-
- if (timectl & WM8350_RTC_STS) {
- int retries;
-
- ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
- WM8350_RTC_SET);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to start: %d\n", ret);
- return ret;
- }
-
- retries = WM8350_SET_TIME_RETRIES;
- do {
- timectl = wm8350_reg_read(wm8350,
- WM8350_RTC_TIME_CONTROL);
- } while (timectl & WM8350_RTC_STS && --retries);
-
- if (retries == 0) {
- dev_err(&pdev->dev, "failed to start: timeout\n");
- return -ENODEV;
- }
- }
-
- device_init_wakeup(&pdev->dev, true);
-
- wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350",
- &wm8350_rtc_ops, THIS_MODULE);
- if (IS_ERR(wm_rtc->rtc))
- return PTR_ERR(wm_rtc->rtc);
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
- wm8350_rtc_update_handler, 0,
- "RTC Seconds", wm8350);
- if (ret)
- return ret;
-
- wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
- wm8350_rtc_alarm_handler, 0,
- "RTC Alarm", wm8350);
- if (ret) {
- wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
- return ret;
- }
-
- return 0;
-}
-
-static void wm8350_rtc_remove(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
-
- wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
- wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
-}
-
-static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend,
- wm8350_rtc_resume);
-
-static struct platform_driver wm8350_rtc_driver = {
- .probe = wm8350_rtc_probe,
- .remove = wm8350_rtc_remove,
- .driver = {
- .name = "wm8350-rtc",
- .pm = &wm8350_rtc_pm_ops,
- },
-};
-
-module_platform_driver(wm8350_rtc_driver);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("RTC driver for the WM8350");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-rtc");
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7832cb8b2e7a..0327e36fc86a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -363,14 +363,6 @@ config WM831X_WATCHDOG
Support for the watchdog in the WM831x AudioPlus PMICs. When
the watchdog triggers the system will be reset.
-config WM8350_WATCHDOG
- tristate "WM8350 watchdog"
- depends on MFD_WM8350
- select WATCHDOG_CORE
- help
- Support for the watchdog in the WM8350 AudioPlus PMIC. When
- the watchdog triggers the system will be reset.
-
config XILINX_WATCHDOG
tristate "Xilinx Watchdog timer"
depends on HAS_IOMEM
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 460be2a566c4..8626f812c657 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -232,7 +232,6 @@ obj-$(CONFIG_DA9063_WATCHDOG) += da9063_wdt.o
obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o
obj-$(CONFIG_WDAT_WDT) += wdat_wdt.o
obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
-obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
obj-$(CONFIG_MAX77620_WATCHDOG) += max77620_wdt.o
obj-$(CONFIG_NCT6694_WATCHDOG) += nct6694_wdt.o
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
deleted file mode 100644
index c82c1b77d91b..000000000000
--- a/drivers/watchdog/wm8350_wdt.c
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Watchdog driver for the wm8350
- *
- * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/watchdog.h>
-#include <linux/uaccess.h>
-#include <linux/mfd/wm8350/core.h>
-
-static bool nowayout = WATCHDOG_NOWAYOUT;
-module_param(nowayout, bool, 0);
-MODULE_PARM_DESC(nowayout,
- "Watchdog cannot be stopped once started (default="
- __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-
-static DEFINE_MUTEX(wdt_mutex);
-
-static struct {
- unsigned int time; /* Seconds */
- u16 val; /* To be set in WM8350_SYSTEM_CONTROL_2 */
-} wm8350_wdt_cfgs[] = {
- { 1, 0x02 },
- { 2, 0x04 },
- { 4, 0x05 },
-};
-
-static int wm8350_wdt_set_timeout(struct watchdog_device *wdt_dev,
- unsigned int timeout)
-{
- struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
- int ret, i;
- u16 reg;
-
- for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++)
- if (wm8350_wdt_cfgs[i].time == timeout)
- break;
- if (i == ARRAY_SIZE(wm8350_wdt_cfgs))
- return -EINVAL;
-
- mutex_lock(&wdt_mutex);
- wm8350_reg_unlock(wm8350);
-
- reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
- reg &= ~WM8350_WDOG_TO_MASK;
- reg |= wm8350_wdt_cfgs[i].val;
- ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
-
- wm8350_reg_lock(wm8350);
- mutex_unlock(&wdt_mutex);
-
- wdt_dev->timeout = timeout;
- return ret;
-}
-
-static int wm8350_wdt_start(struct watchdog_device *wdt_dev)
-{
- struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
- int ret;
- u16 reg;
-
- mutex_lock(&wdt_mutex);
- wm8350_reg_unlock(wm8350);
-
- reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
- reg &= ~WM8350_WDOG_MODE_MASK;
- reg |= 0x20;
- ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
-
- wm8350_reg_lock(wm8350);
- mutex_unlock(&wdt_mutex);
-
- return ret;
-}
-
-static int wm8350_wdt_stop(struct watchdog_device *wdt_dev)
-{
- struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
- int ret;
- u16 reg;
-
- mutex_lock(&wdt_mutex);
- wm8350_reg_unlock(wm8350);
-
- reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
- reg &= ~WM8350_WDOG_MODE_MASK;
- ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
-
- wm8350_reg_lock(wm8350);
- mutex_unlock(&wdt_mutex);
-
- return ret;
-}
-
-static int wm8350_wdt_ping(struct watchdog_device *wdt_dev)
-{
- struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
- int ret;
- u16 reg;
-
- mutex_lock(&wdt_mutex);
-
- reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
- ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
-
- mutex_unlock(&wdt_mutex);
-
- return ret;
-}
-
-static const struct watchdog_info wm8350_wdt_info = {
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
- .identity = "WM8350 Watchdog",
-};
-
-static const struct watchdog_ops wm8350_wdt_ops = {
- .owner = THIS_MODULE,
- .start = wm8350_wdt_start,
- .stop = wm8350_wdt_stop,
- .ping = wm8350_wdt_ping,
- .set_timeout = wm8350_wdt_set_timeout,
-};
-
-static struct watchdog_device wm8350_wdt = {
- .info = &wm8350_wdt_info,
- .ops = &wm8350_wdt_ops,
- .timeout = 4,
- .min_timeout = 1,
- .max_timeout = 4,
-};
-
-static int wm8350_wdt_probe(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
-
- if (!wm8350) {
- pr_err("No driver data supplied\n");
- return -ENODEV;
- }
-
- watchdog_set_nowayout(&wm8350_wdt, nowayout);
- watchdog_set_drvdata(&wm8350_wdt, wm8350);
- wm8350_wdt.parent = &pdev->dev;
-
- /* Default to 4s timeout */
- wm8350_wdt_set_timeout(&wm8350_wdt, 4);
-
- return devm_watchdog_register_device(&pdev->dev, &wm8350_wdt);
-}
-
-static struct platform_driver wm8350_wdt_driver = {
- .probe = wm8350_wdt_probe,
- .driver = {
- .name = "wm8350-wdt",
- },
-};
-
-module_platform_driver(wm8350_wdt_driver);
-
-MODULE_AUTHOR("Mark Brown");
-MODULE_DESCRIPTION("WM8350 Watchdog");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-wdt");
diff --git a/include/linux/mfd/wm8350/audio.h b/include/linux/mfd/wm8350/audio.h
deleted file mode 100644
index ec01ec84d495..000000000000
--- a/include/linux/mfd/wm8350/audio.h
+++ /dev/null
@@ -1,620 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * audio.h -- Audio Driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_AUDIO_H_
-#define __LINUX_MFD_WM8350_AUDIO_H_
-
-#include <linux/platform_device.h>
-
-#define WM8350_CLOCK_CONTROL_1 0x28
-#define WM8350_CLOCK_CONTROL_2 0x29
-#define WM8350_FLL_CONTROL_1 0x2A
-#define WM8350_FLL_CONTROL_2 0x2B
-#define WM8350_FLL_CONTROL_3 0x2C
-#define WM8350_FLL_CONTROL_4 0x2D
-#define WM8350_DAC_CONTROL 0x30
-#define WM8350_DAC_DIGITAL_VOLUME_L 0x32
-#define WM8350_DAC_DIGITAL_VOLUME_R 0x33
-#define WM8350_DAC_LR_RATE 0x35
-#define WM8350_DAC_CLOCK_CONTROL 0x36
-#define WM8350_DAC_MUTE 0x3A
-#define WM8350_DAC_MUTE_VOLUME 0x3B
-#define WM8350_DAC_SIDE 0x3C
-#define WM8350_ADC_CONTROL 0x40
-#define WM8350_ADC_DIGITAL_VOLUME_L 0x42
-#define WM8350_ADC_DIGITAL_VOLUME_R 0x43
-#define WM8350_ADC_DIVIDER 0x44
-#define WM8350_ADC_LR_RATE 0x46
-#define WM8350_INPUT_CONTROL 0x48
-#define WM8350_IN3_INPUT_CONTROL 0x49
-#define WM8350_MIC_BIAS_CONTROL 0x4A
-#define WM8350_OUTPUT_CONTROL 0x4C
-#define WM8350_JACK_DETECT 0x4D
-#define WM8350_ANTI_POP_CONTROL 0x4E
-#define WM8350_LEFT_INPUT_VOLUME 0x50
-#define WM8350_RIGHT_INPUT_VOLUME 0x51
-#define WM8350_LEFT_MIXER_CONTROL 0x58
-#define WM8350_RIGHT_MIXER_CONTROL 0x59
-#define WM8350_OUT3_MIXER_CONTROL 0x5C
-#define WM8350_OUT4_MIXER_CONTROL 0x5D
-#define WM8350_OUTPUT_LEFT_MIXER_VOLUME 0x60
-#define WM8350_OUTPUT_RIGHT_MIXER_VOLUME 0x61
-#define WM8350_INPUT_MIXER_VOLUME_L 0x62
-#define WM8350_INPUT_MIXER_VOLUME_R 0x63
-#define WM8350_INPUT_MIXER_VOLUME 0x64
-#define WM8350_LOUT1_VOLUME 0x68
-#define WM8350_ROUT1_VOLUME 0x69
-#define WM8350_LOUT2_VOLUME 0x6A
-#define WM8350_ROUT2_VOLUME 0x6B
-#define WM8350_BEEP_VOLUME 0x6F
-#define WM8350_AI_FORMATING 0x70
-#define WM8350_ADC_DAC_COMP 0x71
-#define WM8350_AI_ADC_CONTROL 0x72
-#define WM8350_AI_DAC_CONTROL 0x73
-#define WM8350_AIF_TEST 0x74
-#define WM8350_JACK_PIN_STATUS 0xE7
-
-/* Bit values for R08 (0x08) */
-#define WM8350_CODEC_ISEL_1_5 0 /* x1.5 */
-#define WM8350_CODEC_ISEL_1_0 1 /* x1.0 */
-#define WM8350_CODEC_ISEL_0_75 2 /* x0.75 */
-#define WM8350_CODEC_ISEL_0_5 3 /* x0.5 */
-
-#define WM8350_VMID_OFF 0
-#define WM8350_VMID_300K 1
-#define WM8350_VMID_50K 2
-#define WM8350_VMID_5K 3
-
-/*
- * R40 (0x28) - Clock Control 1
- */
-#define WM8350_TOCLK_RATE 0x4000
-#define WM8350_MCLK_SEL 0x0800
-#define WM8350_MCLK_DIV_MASK 0x0100
-#define WM8350_BCLK_DIV_MASK 0x00F0
-#define WM8350_OPCLK_DIV_MASK 0x0007
-
-/*
- * R41 (0x29) - Clock Control 2
- */
-#define WM8350_LRC_ADC_SEL 0x8000
-#define WM8350_MCLK_DIR 0x0001
-
-/*
- * R42 (0x2A) - FLL Control 1
- */
-#define WM8350_FLL_DITHER_WIDTH_MASK 0x3000
-#define WM8350_FLL_DITHER_HP 0x0800
-#define WM8350_FLL_OUTDIV_MASK 0x0700
-#define WM8350_FLL_RSP_RATE_MASK 0x00F0
-#define WM8350_FLL_RATE_MASK 0x0007
-
-/*
- * R43 (0x2B) - FLL Control 2
- */
-#define WM8350_FLL_RATIO_MASK 0xF800
-#define WM8350_FLL_N_MASK 0x03FF
-
-/*
- * R44 (0x2C) - FLL Control 3
- */
-#define WM8350_FLL_K_MASK 0xFFFF
-
-/*
- * R45 (0x2D) - FLL Control 4
- */
-#define WM8350_FLL_FRAC 0x0020
-#define WM8350_FLL_SLOW_LOCK_REF 0x0010
-#define WM8350_FLL_CLK_SRC_MASK 0x0003
-
-/*
- * R48 (0x30) - DAC Control
- */
-#define WM8350_DAC_MONO 0x2000
-#define WM8350_AIF_LRCLKRATE 0x1000
-#define WM8350_DEEMP_MASK 0x0030
-#define WM8350_DACL_DATINV 0x0002
-#define WM8350_DACR_DATINV 0x0001
-
-/*
- * R50 (0x32) - DAC Digital Volume L
- */
-#define WM8350_DAC_VU 0x0100
-#define WM8350_DACL_VOL_MASK 0x00FF
-
-/*
- * R51 (0x33) - DAC Digital Volume R
- */
-#define WM8350_DAC_VU 0x0100
-#define WM8350_DACR_VOL_MASK 0x00FF
-
-/*
- * R53 (0x35) - DAC LR Rate
- */
-#define WM8350_DACLRC_ENA 0x0800
-#define WM8350_DACLRC_RATE_MASK 0x07FF
-
-/*
- * R54 (0x36) - DAC Clock Control
- */
-#define WM8350_DACCLK_POL 0x0010
-#define WM8350_DAC_CLKDIV_MASK 0x0007
-
-/*
- * R58 (0x3A) - DAC Mute
- */
-#define WM8350_DAC_MUTE_ENA 0x4000
-
-/*
- * R59 (0x3B) - DAC Mute Volume
- */
-#define WM8350_DAC_MUTEMODE 0x4000
-#define WM8350_DAC_MUTERATE 0x2000
-#define WM8350_DAC_SB_FILT 0x1000
-
-/*
- * R60 (0x3C) - DAC Side
- */
-#define WM8350_ADC_TO_DACL_MASK 0x3000
-#define WM8350_ADC_TO_DACR_MASK 0x0C00
-
-/*
- * R64 (0x40) - ADC Control
- */
-#define WM8350_ADC_HPF_CUT_MASK 0x0300
-#define WM8350_ADCL_DATINV 0x0002
-#define WM8350_ADCR_DATINV 0x0001
-
-/*
- * R66 (0x42) - ADC Digital Volume L
- */
-#define WM8350_ADC_VU 0x0100
-#define WM8350_ADCL_VOL_MASK 0x00FF
-
-/*
- * R67 (0x43) - ADC Digital Volume R
- */
-#define WM8350_ADC_VU 0x0100
-#define WM8350_ADCR_VOL_MASK 0x00FF
-
-/*
- * R68 (0x44) - ADC Divider
- */
-#define WM8350_ADCL_DAC_SVOL_MASK 0x0F00
-#define WM8350_ADCR_DAC_SVOL_MASK 0x00F0
-#define WM8350_ADCCLK_POL 0x0008
-#define WM8350_ADC_CLKDIV_MASK 0x0007
-
-/*
- * R70 (0x46) - ADC LR Rate
- */
-#define WM8350_ADCLRC_ENA 0x0800
-#define WM8350_ADCLRC_RATE_MASK 0x07FF
-
-/*
- * R72 (0x48) - Input Control
- */
-#define WM8350_IN2R_ENA 0x0400
-#define WM8350_IN1RN_ENA 0x0200
-#define WM8350_IN1RP_ENA 0x0100
-#define WM8350_IN2L_ENA 0x0004
-#define WM8350_IN1LN_ENA 0x0002
-#define WM8350_IN1LP_ENA 0x0001
-
-/*
- * R73 (0x49) - IN3 Input Control
- */
-#define WM8350_IN3R_SHORT 0x4000
-#define WM8350_IN3L_SHORT 0x0040
-
-/*
- * R74 (0x4A) - Mic Bias Control
- */
-#define WM8350_MICBSEL 0x4000
-#define WM8350_MCDTHR_MASK 0x001C
-#define WM8350_MCDSCTHR_MASK 0x0003
-
-/*
- * R76 (0x4C) - Output Control
- */
-#define WM8350_OUT4_VROI 0x0800
-#define WM8350_OUT3_VROI 0x0400
-#define WM8350_OUT2_VROI 0x0200
-#define WM8350_OUT1_VROI 0x0100
-#define WM8350_OUT2_FB 0x0004
-#define WM8350_OUT1_FB 0x0001
-
-/*
- * R77 (0x4D) - Jack Detect
- */
-#define WM8350_JDL_ENA 0x8000
-#define WM8350_JDR_ENA 0x4000
-
-/*
- * R78 (0x4E) - Anti Pop Control
- */
-#define WM8350_ANTI_POP_MASK 0x0300
-#define WM8350_DIS_OP_LN4_MASK 0x00C0
-#define WM8350_DIS_OP_LN3_MASK 0x0030
-#define WM8350_DIS_OP_OUT2_MASK 0x000C
-#define WM8350_DIS_OP_OUT1_MASK 0x0003
-
-/*
- * R80 (0x50) - Left Input Volume
- */
-#define WM8350_INL_MUTE 0x4000
-#define WM8350_INL_ZC 0x2000
-#define WM8350_IN_VU 0x0100
-#define WM8350_INL_VOL_MASK 0x00FC
-
-/*
- * R81 (0x51) - Right Input Volume
- */
-#define WM8350_INR_MUTE 0x4000
-#define WM8350_INR_ZC 0x2000
-#define WM8350_IN_VU 0x0100
-#define WM8350_INR_VOL_MASK 0x00FC
-
-/*
- * R88 (0x58) - Left Mixer Control
- */
-#define WM8350_DACR_TO_MIXOUTL 0x1000
-#define WM8350_DACL_TO_MIXOUTL 0x0800
-#define WM8350_IN3L_TO_MIXOUTL 0x0004
-#define WM8350_INR_TO_MIXOUTL 0x0002
-#define WM8350_INL_TO_MIXOUTL 0x0001
-
-/*
- * R89 (0x59) - Right Mixer Control
- */
-#define WM8350_DACR_TO_MIXOUTR 0x1000
-#define WM8350_DACL_TO_MIXOUTR 0x0800
-#define WM8350_IN3R_TO_MIXOUTR 0x0008
-#define WM8350_INR_TO_MIXOUTR 0x0002
-#define WM8350_INL_TO_MIXOUTR 0x0001
-
-/*
- * R92 (0x5C) - OUT3 Mixer Control
- */
-#define WM8350_DACL_TO_OUT3 0x0800
-#define WM8350_MIXINL_TO_OUT3 0x0100
-#define WM8350_OUT4_TO_OUT3 0x0008
-#define WM8350_MIXOUTL_TO_OUT3 0x0001
-
-/*
- * R93 (0x5D) - OUT4 Mixer Control
- */
-#define WM8350_DACR_TO_OUT4 0x1000
-#define WM8350_DACL_TO_OUT4 0x0800
-#define WM8350_OUT4_ATTN 0x0400
-#define WM8350_MIXINR_TO_OUT4 0x0200
-#define WM8350_OUT3_TO_OUT4 0x0004
-#define WM8350_MIXOUTR_TO_OUT4 0x0002
-#define WM8350_MIXOUTL_TO_OUT4 0x0001
-
-/*
- * R96 (0x60) - Output Left Mixer Volume
- */
-#define WM8350_IN3L_MIXOUTL_VOL_MASK 0x0E00
-#define WM8350_IN3L_MIXOUTL_VOL_SHIFT 9
-#define WM8350_INR_MIXOUTL_VOL_MASK 0x00E0
-#define WM8350_INR_MIXOUTL_VOL_SHIFT 5
-#define WM8350_INL_MIXOUTL_VOL_MASK 0x000E
-#define WM8350_INL_MIXOUTL_VOL_SHIFT 1
-
-/* Bit values for R96 (0x60) */
-#define WM8350_IN3L_MIXOUTL_VOL_OFF 0
-#define WM8350_IN3L_MIXOUTL_VOL_M12DB 1
-#define WM8350_IN3L_MIXOUTL_VOL_M9DB 2
-#define WM8350_IN3L_MIXOUTL_VOL_M6DB 3
-#define WM8350_IN3L_MIXOUTL_VOL_M3DB 4
-#define WM8350_IN3L_MIXOUTL_VOL_0DB 5
-#define WM8350_IN3L_MIXOUTL_VOL_3DB 6
-#define WM8350_IN3L_MIXOUTL_VOL_6DB 7
-
-#define WM8350_INR_MIXOUTL_VOL_OFF 0
-#define WM8350_INR_MIXOUTL_VOL_M12DB 1
-#define WM8350_INR_MIXOUTL_VOL_M9DB 2
-#define WM8350_INR_MIXOUTL_VOL_M6DB 3
-#define WM8350_INR_MIXOUTL_VOL_M3DB 4
-#define WM8350_INR_MIXOUTL_VOL_0DB 5
-#define WM8350_INR_MIXOUTL_VOL_3DB 6
-#define WM8350_INR_MIXOUTL_VOL_6DB 7
-
-#define WM8350_INL_MIXOUTL_VOL_OFF 0
-#define WM8350_INL_MIXOUTL_VOL_M12DB 1
-#define WM8350_INL_MIXOUTL_VOL_M9DB 2
-#define WM8350_INL_MIXOUTL_VOL_M6DB 3
-#define WM8350_INL_MIXOUTL_VOL_M3DB 4
-#define WM8350_INL_MIXOUTL_VOL_0DB 5
-#define WM8350_INL_MIXOUTL_VOL_3DB 6
-#define WM8350_INL_MIXOUTL_VOL_6DB 7
-
-/*
- * R97 (0x61) - Output Right Mixer Volume
- */
-#define WM8350_IN3R_MIXOUTR_VOL_MASK 0xE000
-#define WM8350_IN3R_MIXOUTR_VOL_SHIFT 13
-#define WM8350_INR_MIXOUTR_VOL_MASK 0x00E0
-#define WM8350_INR_MIXOUTR_VOL_SHIFT 5
-#define WM8350_INL_MIXOUTR_VOL_MASK 0x000E
-#define WM8350_INL_MIXOUTR_VOL_SHIFT 1
-
-/* Bit values for R96 (0x60) */
-#define WM8350_IN3R_MIXOUTR_VOL_OFF 0
-#define WM8350_IN3R_MIXOUTR_VOL_M12DB 1
-#define WM8350_IN3R_MIXOUTR_VOL_M9DB 2
-#define WM8350_IN3R_MIXOUTR_VOL_M6DB 3
-#define WM8350_IN3R_MIXOUTR_VOL_M3DB 4
-#define WM8350_IN3R_MIXOUTR_VOL_0DB 5
-#define WM8350_IN3R_MIXOUTR_VOL_3DB 6
-#define WM8350_IN3R_MIXOUTR_VOL_6DB 7
-
-#define WM8350_INR_MIXOUTR_VOL_OFF 0
-#define WM8350_INR_MIXOUTR_VOL_M12DB 1
-#define WM8350_INR_MIXOUTR_VOL_M9DB 2
-#define WM8350_INR_MIXOUTR_VOL_M6DB 3
-#define WM8350_INR_MIXOUTR_VOL_M3DB 4
-#define WM8350_INR_MIXOUTR_VOL_0DB 5
-#define WM8350_INR_MIXOUTR_VOL_3DB 6
-#define WM8350_INR_MIXOUTR_VOL_6DB 7
-
-#define WM8350_INL_MIXOUTR_VOL_OFF 0
-#define WM8350_INL_MIXOUTR_VOL_M12DB 1
-#define WM8350_INL_MIXOUTR_VOL_M9DB 2
-#define WM8350_INL_MIXOUTR_VOL_M6DB 3
-#define WM8350_INL_MIXOUTR_VOL_M3DB 4
-#define WM8350_INL_MIXOUTR_VOL_0DB 5
-#define WM8350_INL_MIXOUTR_VOL_3DB 6
-#define WM8350_INL_MIXOUTR_VOL_6DB 7
-
-/*
- * R98 (0x62) - Input Mixer Volume L
- */
-#define WM8350_IN3L_MIXINL_VOL_MASK 0x0E00
-#define WM8350_IN2L_MIXINL_VOL_MASK 0x000E
-#define WM8350_INL_MIXINL_VOL 0x0001
-
-/*
- * R99 (0x63) - Input Mixer Volume R
- */
-#define WM8350_IN3R_MIXINR_VOL_MASK 0xE000
-#define WM8350_IN2R_MIXINR_VOL_MASK 0x00E0
-#define WM8350_INR_MIXINR_VOL 0x0001
-
-/*
- * R100 (0x64) - Input Mixer Volume
- */
-#define WM8350_OUT4_MIXIN_DST 0x8000
-#define WM8350_OUT4_MIXIN_VOL_MASK 0x000E
-
-/*
- * R104 (0x68) - LOUT1 Volume
- */
-#define WM8350_OUT1L_MUTE 0x4000
-#define WM8350_OUT1L_ZC 0x2000
-#define WM8350_OUT1_VU 0x0100
-#define WM8350_OUT1L_VOL_MASK 0x00FC
-#define WM8350_OUT1L_VOL_SHIFT 2
-
-/*
- * R105 (0x69) - ROUT1 Volume
- */
-#define WM8350_OUT1R_MUTE 0x4000
-#define WM8350_OUT1R_ZC 0x2000
-#define WM8350_OUT1_VU 0x0100
-#define WM8350_OUT1R_VOL_MASK 0x00FC
-#define WM8350_OUT1R_VOL_SHIFT 2
-
-/*
- * R106 (0x6A) - LOUT2 Volume
- */
-#define WM8350_OUT2L_MUTE 0x4000
-#define WM8350_OUT2L_ZC 0x2000
-#define WM8350_OUT2_VU 0x0100
-#define WM8350_OUT2L_VOL_MASK 0x00FC
-
-/*
- * R107 (0x6B) - ROUT2 Volume
- */
-#define WM8350_OUT2R_MUTE 0x4000
-#define WM8350_OUT2R_ZC 0x2000
-#define WM8350_OUT2R_INV 0x0400
-#define WM8350_OUT2R_INV_MUTE 0x0200
-#define WM8350_OUT2_VU 0x0100
-#define WM8350_OUT2R_VOL_MASK 0x00FC
-
-/*
- * R111 (0x6F) - BEEP Volume
- */
-#define WM8350_IN3R_OUT2R_VOL_MASK 0x00E0
-
-/*
- * R112 (0x70) - AI Formating
- */
-#define WM8350_AIF_BCLK_INV 0x8000
-#define WM8350_AIF_TRI 0x2000
-#define WM8350_AIF_LRCLK_INV 0x1000
-#define WM8350_AIF_WL_MASK 0x0C00
-#define WM8350_AIF_FMT_MASK 0x0300
-
-/*
- * R113 (0x71) - ADC DAC COMP
- */
-#define WM8350_DAC_COMP 0x0080
-#define WM8350_DAC_COMPMODE 0x0040
-#define WM8350_ADC_COMP 0x0020
-#define WM8350_ADC_COMPMODE 0x0010
-#define WM8350_LOOPBACK 0x0001
-
-/*
- * R114 (0x72) - AI ADC Control
- */
-#define WM8350_AIFADC_PD 0x0080
-#define WM8350_AIFADCL_SRC 0x0040
-#define WM8350_AIFADCR_SRC 0x0020
-#define WM8350_AIFADC_TDM_CHAN 0x0010
-#define WM8350_AIFADC_TDM 0x0008
-
-/*
- * R115 (0x73) - AI DAC Control
- */
-#define WM8350_BCLK_MSTR 0x4000
-#define WM8350_AIFDAC_PD 0x0080
-#define WM8350_DACL_SRC 0x0040
-#define WM8350_DACR_SRC 0x0020
-#define WM8350_AIFDAC_TDM_CHAN 0x0010
-#define WM8350_AIFDAC_TDM 0x0008
-#define WM8350_DAC_BOOST_MASK 0x0003
-
-/*
- * R116 (0x74) - AIF Test
- */
-#define WM8350_CODEC_BYP 0x4000
-#define WM8350_AIFADC_WR_TST 0x2000
-#define WM8350_AIFADC_RD_TST 0x1000
-#define WM8350_AIFDAC_WR_TST 0x0800
-#define WM8350_AIFDAC_RD_TST 0x0400
-#define WM8350_AIFADC_ASYN 0x0020
-#define WM8350_AIFDAC_ASYN 0x0010
-
-/*
- * R231 (0xE7) - Jack Status
- */
-#define WM8350_JACK_L_LVL 0x0800
-#define WM8350_JACK_R_LVL 0x0400
-#define WM8350_JACK_MICSCD_LVL 0x0200
-#define WM8350_JACK_MICSD_LVL 0x0100
-
-/*
- * WM8350 Platform setup
- */
-#define WM8350_S_CURVE_NONE 0x0
-#define WM8350_S_CURVE_FAST 0x1
-#define WM8350_S_CURVE_MEDIUM 0x2
-#define WM8350_S_CURVE_SLOW 0x3
-
-#define WM8350_DISCHARGE_OFF 0x0
-#define WM8350_DISCHARGE_FAST 0x1
-#define WM8350_DISCHARGE_MEDIUM 0x2
-#define WM8350_DISCHARGE_SLOW 0x3
-
-#define WM8350_TIE_OFF_500R 0x0
-#define WM8350_TIE_OFF_30K 0x1
-
-/*
- * Clock sources & directions
- */
-#define WM8350_SYSCLK 0
-
-#define WM8350_MCLK_SEL_PLL_MCLK 0
-#define WM8350_MCLK_SEL_PLL_DAC 1
-#define WM8350_MCLK_SEL_PLL_ADC 2
-#define WM8350_MCLK_SEL_PLL_32K 3
-#define WM8350_MCLK_SEL_MCLK 5
-
-/* clock divider id's */
-#define WM8350_ADC_CLKDIV 0
-#define WM8350_DAC_CLKDIV 1
-#define WM8350_BCLK_CLKDIV 2
-#define WM8350_OPCLK_CLKDIV 3
-#define WM8350_TO_CLKDIV 4
-#define WM8350_SYS_CLKDIV 5
-#define WM8350_DACLR_CLKDIV 6
-#define WM8350_ADCLR_CLKDIV 7
-
-/* ADC clock dividers */
-#define WM8350_ADCDIV_1 0x0
-#define WM8350_ADCDIV_1_5 0x1
-#define WM8350_ADCDIV_2 0x2
-#define WM8350_ADCDIV_3 0x3
-#define WM8350_ADCDIV_4 0x4
-#define WM8350_ADCDIV_5_5 0x5
-#define WM8350_ADCDIV_6 0x6
-
-/* ADC clock dividers */
-#define WM8350_DACDIV_1 0x0
-#define WM8350_DACDIV_1_5 0x1
-#define WM8350_DACDIV_2 0x2
-#define WM8350_DACDIV_3 0x3
-#define WM8350_DACDIV_4 0x4
-#define WM8350_DACDIV_5_5 0x5
-#define WM8350_DACDIV_6 0x6
-
-/* BCLK clock dividers */
-#define WM8350_BCLK_DIV_1 (0x0 << 4)
-#define WM8350_BCLK_DIV_1_5 (0x1 << 4)
-#define WM8350_BCLK_DIV_2 (0x2 << 4)
-#define WM8350_BCLK_DIV_3 (0x3 << 4)
-#define WM8350_BCLK_DIV_4 (0x4 << 4)
-#define WM8350_BCLK_DIV_5_5 (0x5 << 4)
-#define WM8350_BCLK_DIV_6 (0x6 << 4)
-#define WM8350_BCLK_DIV_8 (0x7 << 4)
-#define WM8350_BCLK_DIV_11 (0x8 << 4)
-#define WM8350_BCLK_DIV_12 (0x9 << 4)
-#define WM8350_BCLK_DIV_16 (0xa << 4)
-#define WM8350_BCLK_DIV_22 (0xb << 4)
-#define WM8350_BCLK_DIV_24 (0xc << 4)
-#define WM8350_BCLK_DIV_32 (0xd << 4)
-#define WM8350_BCLK_DIV_44 (0xe << 4)
-#define WM8350_BCLK_DIV_48 (0xf << 4)
-
-/* Sys (MCLK) clock dividers */
-#define WM8350_MCLK_DIV_1 (0x0 << 8)
-#define WM8350_MCLK_DIV_2 (0x1 << 8)
-
-/* OP clock dividers */
-#define WM8350_OPCLK_DIV_1 0x0
-#define WM8350_OPCLK_DIV_2 0x1
-#define WM8350_OPCLK_DIV_3 0x2
-#define WM8350_OPCLK_DIV_4 0x3
-#define WM8350_OPCLK_DIV_5_5 0x4
-#define WM8350_OPCLK_DIV_6 0x5
-
-/* DAI ID */
-#define WM8350_HIFI_DAI 0
-
-/*
- * Audio interrupts.
- */
-#define WM8350_IRQ_CODEC_JCK_DET_L 39
-#define WM8350_IRQ_CODEC_JCK_DET_R 40
-#define WM8350_IRQ_CODEC_MICSCD 41
-#define WM8350_IRQ_CODEC_MICD 42
-
-/*
- * WM8350 Platform data.
- *
- * This must be initialised per platform for best audio performance.
- * Please see WM8350 datasheet for information.
- */
-struct wm8350_audio_platform_data {
- int vmid_discharge_msecs; /* VMID --> OFF discharge time */
- int drain_msecs; /* OFF drain time */
- int cap_discharge_msecs; /* Cap ON (from OFF) discharge time */
- int vmid_charge_msecs; /* vmid power up time */
- u32 vmid_s_curve:2; /* vmid enable s curve speed */
- u32 dis_out4:2; /* out4 discharge speed */
- u32 dis_out3:2; /* out3 discharge speed */
- u32 dis_out2:2; /* out2 discharge speed */
- u32 dis_out1:2; /* out1 discharge speed */
- u32 vroi_out4:1; /* out4 tie off */
- u32 vroi_out3:1; /* out3 tie off */
- u32 vroi_out2:1; /* out2 tie off */
- u32 vroi_out1:1; /* out1 tie off */
- u32 vroi_enable:1; /* enable tie off */
- u32 codec_current_on:2; /* current level ON */
- u32 codec_current_standby:2; /* current level STANDBY */
- u32 codec_current_charge:2; /* codec current @ vmid charge */
-};
-
-struct wm8350_codec {
- struct platform_device *pdev;
- struct wm8350_audio_platform_data *platform_data;
-};
-
-#endif
diff --git a/include/linux/mfd/wm8350/comparator.h b/include/linux/mfd/wm8350/comparator.h
deleted file mode 100644
index 250d89239528..000000000000
--- a/include/linux/mfd/wm8350/comparator.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * comparator.h -- Comparator Aux ADC for Wolfson WM8350 PMIC
- *
- * Copyright 2007 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_COMPARATOR_H_
-#define __LINUX_MFD_WM8350_COMPARATOR_H_
-
-/*
- * Registers
- */
-
-#define WM8350_DIGITISER_CONTROL_1 0x90
-#define WM8350_DIGITISER_CONTROL_2 0x91
-#define WM8350_AUX1_READBACK 0x98
-#define WM8350_AUX2_READBACK 0x99
-#define WM8350_AUX3_READBACK 0x9A
-#define WM8350_AUX4_READBACK 0x9B
-#define WM8350_CHIP_TEMP_READBACK 0x9F
-#define WM8350_GENERIC_COMPARATOR_CONTROL 0xA3
-#define WM8350_GENERIC_COMPARATOR_1 0xA4
-#define WM8350_GENERIC_COMPARATOR_2 0xA5
-#define WM8350_GENERIC_COMPARATOR_3 0xA6
-#define WM8350_GENERIC_COMPARATOR_4 0xA7
-
-/*
- * R144 (0x90) - Digitiser Control (1)
- */
-#define WM8350_AUXADC_CTC 0x4000
-#define WM8350_AUXADC_POLL 0x2000
-#define WM8350_AUXADC_HIB_MODE 0x1000
-#define WM8350_AUXADC_SEL8 0x0080
-#define WM8350_AUXADC_SEL7 0x0040
-#define WM8350_AUXADC_SEL6 0x0020
-#define WM8350_AUXADC_SEL5 0x0010
-#define WM8350_AUXADC_SEL4 0x0008
-#define WM8350_AUXADC_SEL3 0x0004
-#define WM8350_AUXADC_SEL2 0x0002
-#define WM8350_AUXADC_SEL1 0x0001
-
-/*
- * R145 (0x91) - Digitiser Control (2)
- */
-#define WM8350_AUXADC_MASKMODE_MASK 0x3000
-#define WM8350_AUXADC_CRATE_MASK 0x0700
-#define WM8350_AUXADC_CAL 0x0004
-#define WM8350_AUX_RBMODE 0x0002
-#define WM8350_AUXADC_WAIT 0x0001
-
-/*
- * R152 (0x98) - AUX1 Readback
- */
-#define WM8350_AUXADC_SCALE1_MASK 0x6000
-#define WM8350_AUXADC_REF1 0x1000
-#define WM8350_AUXADC_DATA1_MASK 0x0FFF
-
-/*
- * R153 (0x99) - AUX2 Readback
- */
-#define WM8350_AUXADC_SCALE2_MASK 0x6000
-#define WM8350_AUXADC_REF2 0x1000
-#define WM8350_AUXADC_DATA2_MASK 0x0FFF
-
-/*
- * R154 (0x9A) - AUX3 Readback
- */
-#define WM8350_AUXADC_SCALE3_MASK 0x6000
-#define WM8350_AUXADC_REF3 0x1000
-#define WM8350_AUXADC_DATA3_MASK 0x0FFF
-
-/*
- * R155 (0x9B) - AUX4 Readback
- */
-#define WM8350_AUXADC_SCALE4_MASK 0x6000
-#define WM8350_AUXADC_REF4 0x1000
-#define WM8350_AUXADC_DATA4_MASK 0x0FFF
-
-/*
- * R156 (0x9C) - USB Voltage Readback
- */
-#define WM8350_AUXADC_DATA_USB_MASK 0x0FFF
-
-/*
- * R157 (0x9D) - LINE Voltage Readback
- */
-#define WM8350_AUXADC_DATA_LINE_MASK 0x0FFF
-
-/*
- * R158 (0x9E) - BATT Voltage Readback
- */
-#define WM8350_AUXADC_DATA_BATT_MASK 0x0FFF
-
-/*
- * R159 (0x9F) - Chip Temp Readback
- */
-#define WM8350_AUXADC_DATA_CHIPTEMP_MASK 0x0FFF
-
-/*
- * R163 (0xA3) - Generic Comparator Control
- */
-#define WM8350_DCMP4_ENA 0x0008
-#define WM8350_DCMP3_ENA 0x0004
-#define WM8350_DCMP2_ENA 0x0002
-#define WM8350_DCMP1_ENA 0x0001
-
-/*
- * R164 (0xA4) - Generic comparator 1
- */
-#define WM8350_DCMP1_SRCSEL_MASK 0xE000
-#define WM8350_DCMP1_GT 0x1000
-#define WM8350_DCMP1_THR_MASK 0x0FFF
-
-/*
- * R165 (0xA5) - Generic comparator 2
- */
-#define WM8350_DCMP2_SRCSEL_MASK 0xE000
-#define WM8350_DCMP2_GT 0x1000
-#define WM8350_DCMP2_THR_MASK 0x0FFF
-
-/*
- * R166 (0xA6) - Generic comparator 3
- */
-#define WM8350_DCMP3_SRCSEL_MASK 0xE000
-#define WM8350_DCMP3_GT 0x1000
-#define WM8350_DCMP3_THR_MASK 0x0FFF
-
-/*
- * R167 (0xA7) - Generic comparator 4
- */
-#define WM8350_DCMP4_SRCSEL_MASK 0xE000
-#define WM8350_DCMP4_GT 0x1000
-#define WM8350_DCMP4_THR_MASK 0x0FFF
-
-/*
- * Interrupts.
- */
-#define WM8350_IRQ_AUXADC_DATARDY 16
-#define WM8350_IRQ_AUXADC_DCOMP4 17
-#define WM8350_IRQ_AUXADC_DCOMP3 18
-#define WM8350_IRQ_AUXADC_DCOMP2 19
-#define WM8350_IRQ_AUXADC_DCOMP1 20
-#define WM8350_IRQ_SYS_HYST_COMP_FAIL 21
-#define WM8350_IRQ_SYS_CHIP_GT115 22
-#define WM8350_IRQ_SYS_CHIP_GT140 23
-
-/*
- * USB/2, LINE & BATT = ((VRTC * 2) / 4095)) * 10e6 uV
- * Where VRTC = 2.7 V
- */
-#define WM8350_AUX_COEFF 1319
-
-#define WM8350_AUXADC_AUX1 0
-#define WM8350_AUXADC_AUX2 1
-#define WM8350_AUXADC_AUX3 2
-#define WM8350_AUXADC_AUX4 3
-#define WM8350_AUXADC_USB 4
-#define WM8350_AUXADC_LINE 5
-#define WM8350_AUXADC_BATT 6
-#define WM8350_AUXADC_TEMP 7
-
-struct wm8350;
-
-/*
- * AUX ADC Readback
- */
-int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale,
- int vref);
-
-#endif
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
deleted file mode 100644
index 097ef4dfcdac..000000000000
--- a/include/linux/mfd/wm8350/core.h
+++ /dev/null
@@ -1,692 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * core.h -- Core Driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_CORE_H_
-#define __LINUX_MFD_WM8350_CORE_H_
-
-#include <linux/completion.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/regmap.h>
-#include <linux/types.h>
-
-#include <linux/mfd/wm8350/audio.h>
-#include <linux/mfd/wm8350/gpio.h>
-#include <linux/mfd/wm8350/pmic.h>
-#include <linux/mfd/wm8350/rtc.h>
-#include <linux/mfd/wm8350/supply.h>
-#include <linux/mfd/wm8350/wdt.h>
-
-struct device;
-struct platform_device;
-
-/*
- * Register values.
- */
-#define WM8350_RESET_ID 0x00
-#define WM8350_ID 0x01
-#define WM8350_REVISION 0x02
-#define WM8350_SYSTEM_CONTROL_1 0x03
-#define WM8350_SYSTEM_CONTROL_2 0x04
-#define WM8350_SYSTEM_HIBERNATE 0x05
-#define WM8350_INTERFACE_CONTROL 0x06
-#define WM8350_POWER_MGMT_1 0x08
-#define WM8350_POWER_MGMT_2 0x09
-#define WM8350_POWER_MGMT_3 0x0A
-#define WM8350_POWER_MGMT_4 0x0B
-#define WM8350_POWER_MGMT_5 0x0C
-#define WM8350_POWER_MGMT_6 0x0D
-#define WM8350_POWER_MGMT_7 0x0E
-
-#define WM8350_SYSTEM_INTERRUPTS 0x18
-#define WM8350_INT_STATUS_1 0x19
-#define WM8350_INT_STATUS_2 0x1A
-#define WM8350_POWER_UP_INT_STATUS 0x1B
-#define WM8350_UNDER_VOLTAGE_INT_STATUS 0x1C
-#define WM8350_OVER_CURRENT_INT_STATUS 0x1D
-#define WM8350_GPIO_INT_STATUS 0x1E
-#define WM8350_COMPARATOR_INT_STATUS 0x1F
-#define WM8350_SYSTEM_INTERRUPTS_MASK 0x20
-#define WM8350_INT_STATUS_1_MASK 0x21
-#define WM8350_INT_STATUS_2_MASK 0x22
-#define WM8350_POWER_UP_INT_STATUS_MASK 0x23
-#define WM8350_UNDER_VOLTAGE_INT_STATUS_MASK 0x24
-#define WM8350_OVER_CURRENT_INT_STATUS_MASK 0x25
-#define WM8350_GPIO_INT_STATUS_MASK 0x26
-#define WM8350_COMPARATOR_INT_STATUS_MASK 0x27
-#define WM8350_CHARGER_OVERRIDES 0xE2
-#define WM8350_MISC_OVERRIDES 0xE3
-#define WM8350_COMPARATOR_OVERRIDES 0xE7
-#define WM8350_STATE_MACHINE_STATUS 0xE9
-
-#define WM8350_MAX_REGISTER 0xFF
-
-#define WM8350_UNLOCK_KEY 0x0013
-#define WM8350_LOCK_KEY 0x0000
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Reset/ID
- */
-#define WM8350_SW_RESET_CHIP_ID_MASK 0xFFFF
-
-/*
- * R1 (0x01) - ID
- */
-#define WM8350_CHIP_REV_MASK 0x7000
-#define WM8350_CONF_STS_MASK 0x0C00
-#define WM8350_CUST_ID_MASK 0x00FF
-
-/*
- * R2 (0x02) - Revision
- */
-#define WM8350_MASK_REV_MASK 0x00FF
-
-/*
- * R3 (0x03) - System Control 1
- */
-#define WM8350_CHIP_ON 0x8000
-#define WM8350_POWERCYCLE 0x2000
-#define WM8350_VCC_FAULT_OV 0x1000
-#define WM8350_REG_RSTB_TIME_MASK 0x0C00
-#define WM8350_BG_SLEEP 0x0200
-#define WM8350_MEM_VALID 0x0020
-#define WM8350_CHIP_SET_UP 0x0010
-#define WM8350_ON_DEB_T 0x0008
-#define WM8350_ON_POL 0x0002
-#define WM8350_IRQ_POL 0x0001
-
-/*
- * R4 (0x04) - System Control 2
- */
-#define WM8350_USB_SUSPEND_8MA 0x8000
-#define WM8350_USB_SUSPEND 0x4000
-#define WM8350_USB_MSTR 0x2000
-#define WM8350_USB_MSTR_SRC 0x1000
-#define WM8350_USB_500MA 0x0800
-#define WM8350_USB_NOLIM 0x0400
-
-/*
- * R5 (0x05) - System Hibernate
- */
-#define WM8350_HIBERNATE 0x8000
-#define WM8350_WDOG_HIB_MODE 0x0080
-#define WM8350_REG_HIB_STARTUP_SEQ 0x0040
-#define WM8350_REG_RESET_HIB_MODE 0x0020
-#define WM8350_RST_HIB_MODE 0x0010
-#define WM8350_IRQ_HIB_MODE 0x0008
-#define WM8350_MEMRST_HIB_MODE 0x0004
-#define WM8350_PCCOMP_HIB_MODE 0x0002
-#define WM8350_TEMPMON_HIB_MODE 0x0001
-
-/*
- * R6 (0x06) - Interface Control
- */
-#define WM8350_USE_DEV_PINS 0x8000
-#define WM8350_USE_DEV_PINS_MASK 0x8000
-#define WM8350_USE_DEV_PINS_SHIFT 15
-#define WM8350_DEV_ADDR_MASK 0x6000
-#define WM8350_DEV_ADDR_SHIFT 13
-#define WM8350_CONFIG_DONE 0x1000
-#define WM8350_CONFIG_DONE_MASK 0x1000
-#define WM8350_CONFIG_DONE_SHIFT 12
-#define WM8350_RECONFIG_AT_ON 0x0800
-#define WM8350_RECONFIG_AT_ON_MASK 0x0800
-#define WM8350_RECONFIG_AT_ON_SHIFT 11
-#define WM8350_AUTOINC 0x0200
-#define WM8350_AUTOINC_MASK 0x0200
-#define WM8350_AUTOINC_SHIFT 9
-#define WM8350_ARA 0x0100
-#define WM8350_ARA_MASK 0x0100
-#define WM8350_ARA_SHIFT 8
-#define WM8350_SPI_CFG 0x0008
-#define WM8350_SPI_CFG_MASK 0x0008
-#define WM8350_SPI_CFG_SHIFT 3
-#define WM8350_SPI_4WIRE 0x0004
-#define WM8350_SPI_4WIRE_MASK 0x0004
-#define WM8350_SPI_4WIRE_SHIFT 2
-#define WM8350_SPI_3WIRE 0x0002
-#define WM8350_SPI_3WIRE_MASK 0x0002
-#define WM8350_SPI_3WIRE_SHIFT 1
-
-/* Bit values for R06 (0x06) */
-#define WM8350_USE_DEV_PINS_PRIMARY 0
-#define WM8350_USE_DEV_PINS_DEV 1
-
-#define WM8350_DEV_ADDR_34 0
-#define WM8350_DEV_ADDR_36 1
-#define WM8350_DEV_ADDR_3C 2
-#define WM8350_DEV_ADDR_3E 3
-
-#define WM8350_CONFIG_DONE_OFF 0
-#define WM8350_CONFIG_DONE_DONE 1
-
-#define WM8350_RECONFIG_AT_ON_OFF 0
-#define WM8350_RECONFIG_AT_ON_ON 1
-
-#define WM8350_AUTOINC_OFF 0
-#define WM8350_AUTOINC_ON 1
-
-#define WM8350_ARA_OFF 0
-#define WM8350_ARA_ON 1
-
-#define WM8350_SPI_CFG_CMOS 0
-#define WM8350_SPI_CFG_OD 1
-
-#define WM8350_SPI_4WIRE_3WIRE 0
-#define WM8350_SPI_4WIRE_4WIRE 1
-
-#define WM8350_SPI_3WIRE_I2C 0
-#define WM8350_SPI_3WIRE_SPI 1
-
-/*
- * R8 (0x08) - Power mgmt (1)
- */
-#define WM8350_CODEC_ISEL_MASK 0xC000
-#define WM8350_VBUFEN 0x2000
-#define WM8350_OUTPUT_DRAIN_EN 0x0400
-#define WM8350_MIC_DET_ENA 0x0100
-#define WM8350_BIASEN 0x0020
-#define WM8350_MICBEN 0x0010
-#define WM8350_VMIDEN 0x0004
-#define WM8350_VMID_MASK 0x0003
-#define WM8350_VMID_SHIFT 0
-
-/*
- * R9 (0x09) - Power mgmt (2)
- */
-#define WM8350_IN3R_ENA 0x0800
-#define WM8350_IN3L_ENA 0x0400
-#define WM8350_INR_ENA 0x0200
-#define WM8350_INL_ENA 0x0100
-#define WM8350_MIXINR_ENA 0x0080
-#define WM8350_MIXINL_ENA 0x0040
-#define WM8350_OUT4_ENA 0x0020
-#define WM8350_OUT3_ENA 0x0010
-#define WM8350_MIXOUTR_ENA 0x0002
-#define WM8350_MIXOUTL_ENA 0x0001
-
-/*
- * R10 (0x0A) - Power mgmt (3)
- */
-#define WM8350_IN3R_TO_OUT2R 0x0080
-#define WM8350_OUT2R_ENA 0x0008
-#define WM8350_OUT2L_ENA 0x0004
-#define WM8350_OUT1R_ENA 0x0002
-#define WM8350_OUT1L_ENA 0x0001
-
-/*
- * R11 (0x0B) - Power mgmt (4)
- */
-#define WM8350_SYSCLK_ENA 0x4000
-#define WM8350_ADC_HPF_ENA 0x2000
-#define WM8350_FLL_ENA 0x0800
-#define WM8350_FLL_OSC_ENA 0x0400
-#define WM8350_TOCLK_ENA 0x0100
-#define WM8350_DACR_ENA 0x0020
-#define WM8350_DACL_ENA 0x0010
-#define WM8350_ADCR_ENA 0x0008
-#define WM8350_ADCL_ENA 0x0004
-
-/*
- * R12 (0x0C) - Power mgmt (5)
- */
-#define WM8350_CODEC_ENA 0x1000
-#define WM8350_RTC_TICK_ENA 0x0800
-#define WM8350_OSC32K_ENA 0x0400
-#define WM8350_CHG_ENA 0x0200
-#define WM8350_ACC_DET_ENA 0x0100
-#define WM8350_AUXADC_ENA 0x0080
-#define WM8350_DCMP4_ENA 0x0008
-#define WM8350_DCMP3_ENA 0x0004
-#define WM8350_DCMP2_ENA 0x0002
-#define WM8350_DCMP1_ENA 0x0001
-
-/*
- * R13 (0x0D) - Power mgmt (6)
- */
-#define WM8350_LS_ENA 0x8000
-#define WM8350_LDO4_ENA 0x0800
-#define WM8350_LDO3_ENA 0x0400
-#define WM8350_LDO2_ENA 0x0200
-#define WM8350_LDO1_ENA 0x0100
-#define WM8350_DC6_ENA 0x0020
-#define WM8350_DC5_ENA 0x0010
-#define WM8350_DC4_ENA 0x0008
-#define WM8350_DC3_ENA 0x0004
-#define WM8350_DC2_ENA 0x0002
-#define WM8350_DC1_ENA 0x0001
-
-/*
- * R14 (0x0E) - Power mgmt (7)
- */
-#define WM8350_CS2_ENA 0x0002
-#define WM8350_CS1_ENA 0x0001
-
-/*
- * R24 (0x18) - System Interrupts
- */
-#define WM8350_OC_INT 0x2000
-#define WM8350_UV_INT 0x1000
-#define WM8350_PUTO_INT 0x0800
-#define WM8350_CS_INT 0x0200
-#define WM8350_EXT_INT 0x0100
-#define WM8350_CODEC_INT 0x0080
-#define WM8350_GP_INT 0x0040
-#define WM8350_AUXADC_INT 0x0020
-#define WM8350_RTC_INT 0x0010
-#define WM8350_SYS_INT 0x0008
-#define WM8350_CHG_INT 0x0004
-#define WM8350_USB_INT 0x0002
-#define WM8350_WKUP_INT 0x0001
-
-/*
- * R25 (0x19) - Interrupt Status 1
- */
-#define WM8350_CHG_BAT_HOT_EINT 0x8000
-#define WM8350_CHG_BAT_COLD_EINT 0x4000
-#define WM8350_CHG_BAT_FAIL_EINT 0x2000
-#define WM8350_CHG_TO_EINT 0x1000
-#define WM8350_CHG_END_EINT 0x0800
-#define WM8350_CHG_START_EINT 0x0400
-#define WM8350_CHG_FAST_RDY_EINT 0x0200
-#define WM8350_RTC_PER_EINT 0x0080
-#define WM8350_RTC_SEC_EINT 0x0040
-#define WM8350_RTC_ALM_EINT 0x0020
-#define WM8350_CHG_VBATT_LT_3P9_EINT 0x0004
-#define WM8350_CHG_VBATT_LT_3P1_EINT 0x0002
-#define WM8350_CHG_VBATT_LT_2P85_EINT 0x0001
-
-/*
- * R26 (0x1A) - Interrupt Status 2
- */
-#define WM8350_CS1_EINT 0x2000
-#define WM8350_CS2_EINT 0x1000
-#define WM8350_USB_LIMIT_EINT 0x0400
-#define WM8350_AUXADC_DATARDY_EINT 0x0100
-#define WM8350_AUXADC_DCOMP4_EINT 0x0080
-#define WM8350_AUXADC_DCOMP3_EINT 0x0040
-#define WM8350_AUXADC_DCOMP2_EINT 0x0020
-#define WM8350_AUXADC_DCOMP1_EINT 0x0010
-#define WM8350_SYS_HYST_COMP_FAIL_EINT 0x0008
-#define WM8350_SYS_CHIP_GT115_EINT 0x0004
-#define WM8350_SYS_CHIP_GT140_EINT 0x0002
-#define WM8350_SYS_WDOG_TO_EINT 0x0001
-
-/*
- * R27 (0x1B) - Power Up Interrupt Status
- */
-#define WM8350_PUTO_LDO4_EINT 0x0800
-#define WM8350_PUTO_LDO3_EINT 0x0400
-#define WM8350_PUTO_LDO2_EINT 0x0200
-#define WM8350_PUTO_LDO1_EINT 0x0100
-#define WM8350_PUTO_DC6_EINT 0x0020
-#define WM8350_PUTO_DC5_EINT 0x0010
-#define WM8350_PUTO_DC4_EINT 0x0008
-#define WM8350_PUTO_DC3_EINT 0x0004
-#define WM8350_PUTO_DC2_EINT 0x0002
-#define WM8350_PUTO_DC1_EINT 0x0001
-
-/*
- * R28 (0x1C) - Under Voltage Interrupt status
- */
-#define WM8350_UV_LDO4_EINT 0x0800
-#define WM8350_UV_LDO3_EINT 0x0400
-#define WM8350_UV_LDO2_EINT 0x0200
-#define WM8350_UV_LDO1_EINT 0x0100
-#define WM8350_UV_DC6_EINT 0x0020
-#define WM8350_UV_DC5_EINT 0x0010
-#define WM8350_UV_DC4_EINT 0x0008
-#define WM8350_UV_DC3_EINT 0x0004
-#define WM8350_UV_DC2_EINT 0x0002
-#define WM8350_UV_DC1_EINT 0x0001
-
-/*
- * R29 (0x1D) - Over Current Interrupt status
- */
-#define WM8350_OC_LS_EINT 0x8000
-
-/*
- * R30 (0x1E) - GPIO Interrupt Status
- */
-#define WM8350_GP12_EINT 0x1000
-#define WM8350_GP11_EINT 0x0800
-#define WM8350_GP10_EINT 0x0400
-#define WM8350_GP9_EINT 0x0200
-#define WM8350_GP8_EINT 0x0100
-#define WM8350_GP7_EINT 0x0080
-#define WM8350_GP6_EINT 0x0040
-#define WM8350_GP5_EINT 0x0020
-#define WM8350_GP4_EINT 0x0010
-#define WM8350_GP3_EINT 0x0008
-#define WM8350_GP2_EINT 0x0004
-#define WM8350_GP1_EINT 0x0002
-#define WM8350_GP0_EINT 0x0001
-
-/*
- * R31 (0x1F) - Comparator Interrupt Status
- */
-#define WM8350_EXT_USB_FB_EINT 0x8000
-#define WM8350_EXT_WALL_FB_EINT 0x4000
-#define WM8350_EXT_BAT_FB_EINT 0x2000
-#define WM8350_CODEC_JCK_DET_L_EINT 0x0800
-#define WM8350_CODEC_JCK_DET_R_EINT 0x0400
-#define WM8350_CODEC_MICSCD_EINT 0x0200
-#define WM8350_CODEC_MICD_EINT 0x0100
-#define WM8350_WKUP_OFF_STATE_EINT 0x0040
-#define WM8350_WKUP_HIB_STATE_EINT 0x0020
-#define WM8350_WKUP_CONV_FAULT_EINT 0x0010
-#define WM8350_WKUP_WDOG_RST_EINT 0x0008
-#define WM8350_WKUP_GP_PWR_ON_EINT 0x0004
-#define WM8350_WKUP_ONKEY_EINT 0x0002
-#define WM8350_WKUP_GP_WAKEUP_EINT 0x0001
-
-/*
- * R32 (0x20) - System Interrupts Mask
- */
-#define WM8350_IM_OC_INT 0x2000
-#define WM8350_IM_UV_INT 0x1000
-#define WM8350_IM_PUTO_INT 0x0800
-#define WM8350_IM_SPARE_INT 0x0400
-#define WM8350_IM_CS_INT 0x0200
-#define WM8350_IM_EXT_INT 0x0100
-#define WM8350_IM_CODEC_INT 0x0080
-#define WM8350_IM_GP_INT 0x0040
-#define WM8350_IM_AUXADC_INT 0x0020
-#define WM8350_IM_RTC_INT 0x0010
-#define WM8350_IM_SYS_INT 0x0008
-#define WM8350_IM_CHG_INT 0x0004
-#define WM8350_IM_USB_INT 0x0002
-#define WM8350_IM_WKUP_INT 0x0001
-
-/*
- * R33 (0x21) - Interrupt Status 1 Mask
- */
-#define WM8350_IM_CHG_BAT_HOT_EINT 0x8000
-#define WM8350_IM_CHG_BAT_COLD_EINT 0x4000
-#define WM8350_IM_CHG_BAT_FAIL_EINT 0x2000
-#define WM8350_IM_CHG_TO_EINT 0x1000
-#define WM8350_IM_CHG_END_EINT 0x0800
-#define WM8350_IM_CHG_START_EINT 0x0400
-#define WM8350_IM_CHG_FAST_RDY_EINT 0x0200
-#define WM8350_IM_RTC_PER_EINT 0x0080
-#define WM8350_IM_RTC_SEC_EINT 0x0040
-#define WM8350_IM_RTC_ALM_EINT 0x0020
-#define WM8350_IM_CHG_VBATT_LT_3P9_EINT 0x0004
-#define WM8350_IM_CHG_VBATT_LT_3P1_EINT 0x0002
-#define WM8350_IM_CHG_VBATT_LT_2P85_EINT 0x0001
-
-/*
- * R34 (0x22) - Interrupt Status 2 Mask
- */
-#define WM8350_IM_SPARE2_EINT 0x8000
-#define WM8350_IM_SPARE1_EINT 0x4000
-#define WM8350_IM_CS1_EINT 0x2000
-#define WM8350_IM_CS2_EINT 0x1000
-#define WM8350_IM_USB_LIMIT_EINT 0x0400
-#define WM8350_IM_AUXADC_DATARDY_EINT 0x0100
-#define WM8350_IM_AUXADC_DCOMP4_EINT 0x0080
-#define WM8350_IM_AUXADC_DCOMP3_EINT 0x0040
-#define WM8350_IM_AUXADC_DCOMP2_EINT 0x0020
-#define WM8350_IM_AUXADC_DCOMP1_EINT 0x0010
-#define WM8350_IM_SYS_HYST_COMP_FAIL_EINT 0x0008
-#define WM8350_IM_SYS_CHIP_GT115_EINT 0x0004
-#define WM8350_IM_SYS_CHIP_GT140_EINT 0x0002
-#define WM8350_IM_SYS_WDOG_TO_EINT 0x0001
-
-/*
- * R35 (0x23) - Power Up Interrupt Status Mask
- */
-#define WM8350_IM_PUTO_LDO4_EINT 0x0800
-#define WM8350_IM_PUTO_LDO3_EINT 0x0400
-#define WM8350_IM_PUTO_LDO2_EINT 0x0200
-#define WM8350_IM_PUTO_LDO1_EINT 0x0100
-#define WM8350_IM_PUTO_DC6_EINT 0x0020
-#define WM8350_IM_PUTO_DC5_EINT 0x0010
-#define WM8350_IM_PUTO_DC4_EINT 0x0008
-#define WM8350_IM_PUTO_DC3_EINT 0x0004
-#define WM8350_IM_PUTO_DC2_EINT 0x0002
-#define WM8350_IM_PUTO_DC1_EINT 0x0001
-
-/*
- * R36 (0x24) - Under Voltage Interrupt status Mask
- */
-#define WM8350_IM_UV_LDO4_EINT 0x0800
-#define WM8350_IM_UV_LDO3_EINT 0x0400
-#define WM8350_IM_UV_LDO2_EINT 0x0200
-#define WM8350_IM_UV_LDO1_EINT 0x0100
-#define WM8350_IM_UV_DC6_EINT 0x0020
-#define WM8350_IM_UV_DC5_EINT 0x0010
-#define WM8350_IM_UV_DC4_EINT 0x0008
-#define WM8350_IM_UV_DC3_EINT 0x0004
-#define WM8350_IM_UV_DC2_EINT 0x0002
-#define WM8350_IM_UV_DC1_EINT 0x0001
-
-/*
- * R37 (0x25) - Over Current Interrupt status Mask
- */
-#define WM8350_IM_OC_LS_EINT 0x8000
-
-/*
- * R38 (0x26) - GPIO Interrupt Status Mask
- */
-#define WM8350_IM_GP12_EINT 0x1000
-#define WM8350_IM_GP11_EINT 0x0800
-#define WM8350_IM_GP10_EINT 0x0400
-#define WM8350_IM_GP9_EINT 0x0200
-#define WM8350_IM_GP8_EINT 0x0100
-#define WM8350_IM_GP7_EINT 0x0080
-#define WM8350_IM_GP6_EINT 0x0040
-#define WM8350_IM_GP5_EINT 0x0020
-#define WM8350_IM_GP4_EINT 0x0010
-#define WM8350_IM_GP3_EINT 0x0008
-#define WM8350_IM_GP2_EINT 0x0004
-#define WM8350_IM_GP1_EINT 0x0002
-#define WM8350_IM_GP0_EINT 0x0001
-
-/*
- * R39 (0x27) - Comparator Interrupt Status Mask
- */
-#define WM8350_IM_EXT_USB_FB_EINT 0x8000
-#define WM8350_IM_EXT_WALL_FB_EINT 0x4000
-#define WM8350_IM_EXT_BAT_FB_EINT 0x2000
-#define WM8350_IM_CODEC_JCK_DET_L_EINT 0x0800
-#define WM8350_IM_CODEC_JCK_DET_R_EINT 0x0400
-#define WM8350_IM_CODEC_MICSCD_EINT 0x0200
-#define WM8350_IM_CODEC_MICD_EINT 0x0100
-#define WM8350_IM_WKUP_OFF_STATE_EINT 0x0040
-#define WM8350_IM_WKUP_HIB_STATE_EINT 0x0020
-#define WM8350_IM_WKUP_CONV_FAULT_EINT 0x0010
-#define WM8350_IM_WKUP_WDOG_RST_EINT 0x0008
-#define WM8350_IM_WKUP_GP_PWR_ON_EINT 0x0004
-#define WM8350_IM_WKUP_ONKEY_EINT 0x0002
-#define WM8350_IM_WKUP_GP_WAKEUP_EINT 0x0001
-
-/*
- * R220 (0xDC) - RAM BIST 1
- */
-#define WM8350_READ_STATUS 0x0800
-#define WM8350_TSTRAM_CLK 0x0100
-#define WM8350_TSTRAM_CLK_ENA 0x0080
-#define WM8350_STARTSEQ 0x0040
-#define WM8350_READ_SRC 0x0020
-#define WM8350_COUNT_DIR 0x0010
-#define WM8350_TSTRAM_MODE_MASK 0x000E
-#define WM8350_TSTRAM_ENA 0x0001
-
-/*
- * R225 (0xE1) - DCDC/LDO status
- */
-#define WM8350_LS_STS 0x8000
-#define WM8350_LDO4_STS 0x0800
-#define WM8350_LDO3_STS 0x0400
-#define WM8350_LDO2_STS 0x0200
-#define WM8350_LDO1_STS 0x0100
-#define WM8350_DC6_STS 0x0020
-#define WM8350_DC5_STS 0x0010
-#define WM8350_DC4_STS 0x0008
-#define WM8350_DC3_STS 0x0004
-#define WM8350_DC2_STS 0x0002
-#define WM8350_DC1_STS 0x0001
-
-/*
- * R226 (0xE2) - Charger status
- */
-#define WM8350_CHG_BATT_HOT_OVRDE 0x8000
-#define WM8350_CHG_BATT_COLD_OVRDE 0x4000
-
-/*
- * R227 (0xE3) - Misc Overrides
- */
-#define WM8350_USB_LIMIT_OVRDE 0x0400
-
-/*
- * R227 (0xE7) - Comparator Overrides
- */
-#define WM8350_USB_FB_OVRDE 0x8000
-#define WM8350_WALL_FB_OVRDE 0x4000
-#define WM8350_BATT_FB_OVRDE 0x2000
-
-
-/*
- * R233 (0xE9) - State Machinine Status
- */
-#define WM8350_USB_SM_MASK 0x0700
-#define WM8350_USB_SM_SHIFT 8
-
-#define WM8350_USB_SM_100_SLV 1
-#define WM8350_USB_SM_500_SLV 5
-#define WM8350_USB_SM_STDBY_SLV 7
-
-/* WM8350 wake up conditions */
-#define WM8350_IRQ_WKUP_OFF_STATE 43
-#define WM8350_IRQ_WKUP_HIB_STATE 44
-#define WM8350_IRQ_WKUP_CONV_FAULT 45
-#define WM8350_IRQ_WKUP_WDOG_RST 46
-#define WM8350_IRQ_WKUP_GP_PWR_ON 47
-#define WM8350_IRQ_WKUP_ONKEY 48
-#define WM8350_IRQ_WKUP_GP_WAKEUP 49
-
-/* wm8350 chip revisions */
-#define WM8350_REV_E 0x4
-#define WM8350_REV_F 0x5
-#define WM8350_REV_G 0x6
-#define WM8350_REV_H 0x7
-
-#define WM8350_NUM_IRQ 63
-
-#define WM8350_NUM_IRQ_REGS 7
-
-extern const struct regmap_config wm8350_regmap;
-
-struct wm8350;
-
-struct wm8350_hwmon {
- struct platform_device *pdev;
- struct device *classdev;
-};
-
-struct wm8350 {
- struct device *dev;
-
- /* device IO */
- struct regmap *regmap;
- bool unlocked;
-
- struct mutex auxadc_mutex;
- struct completion auxadc_done;
-
- /* Interrupt handling */
- struct mutex irq_lock;
- int chip_irq;
- int irq_base;
- u16 irq_masks[WM8350_NUM_IRQ_REGS];
-
- /* Client devices */
- struct wm8350_codec codec;
- struct wm8350_gpio gpio;
- struct wm8350_hwmon hwmon;
- struct wm8350_pmic pmic;
- struct wm8350_power power;
- struct wm8350_rtc rtc;
- struct wm8350_wdt wdt;
-};
-
-/**
- * Data to be supplied by the platform to initialise the WM8350.
- *
- * @init: Function called during driver initialisation. Should be
- * used by the platform to configure GPIO functions and similar.
- * @irq_high: Set if WM8350 IRQ is active high.
- * @irq_base: Base IRQ for genirq (not currently used).
- * @gpio_base: Base for gpiolib.
- */
-struct wm8350_platform_data {
- int (*init)(struct wm8350 *wm8350);
- int irq_high;
- int irq_base;
- int gpio_base;
-};
-
-
-/*
- * WM8350 device initialisation and exit.
- */
-int wm8350_device_init(struct wm8350 *wm8350, int irq,
- struct wm8350_platform_data *pdata);
-
-/*
- * WM8350 device IO
- */
-int wm8350_clear_bits(struct wm8350 *wm8350, u16 reg, u16 mask);
-int wm8350_set_bits(struct wm8350 *wm8350, u16 reg, u16 mask);
-u16 wm8350_reg_read(struct wm8350 *wm8350, int reg);
-int wm8350_reg_write(struct wm8350 *wm8350, int reg, u16 val);
-int wm8350_reg_lock(struct wm8350 *wm8350);
-int wm8350_reg_unlock(struct wm8350 *wm8350);
-int wm8350_block_read(struct wm8350 *wm8350, int reg, int size, u16 *dest);
-int wm8350_block_write(struct wm8350 *wm8350, int reg, int size, u16 *src);
-
-/*
- * WM8350 internal interrupts
- */
-static inline int wm8350_register_irq(struct wm8350 *wm8350, int irq,
- irq_handler_t handler,
- unsigned long flags,
- const char *name, void *data)
-{
- if (!wm8350->irq_base)
- return -ENODEV;
-
- return request_threaded_irq(irq + wm8350->irq_base, NULL,
- handler, flags | IRQF_ONESHOT, name, data);
-}
-
-static inline void wm8350_free_irq(struct wm8350 *wm8350, int irq, void *data)
-{
- free_irq(irq + wm8350->irq_base, data);
-}
-
-static inline void wm8350_mask_irq(struct wm8350 *wm8350, int irq)
-{
- disable_irq(irq + wm8350->irq_base);
-}
-
-static inline void wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
-{
- enable_irq(irq + wm8350->irq_base);
-}
-
-int wm8350_irq_init(struct wm8350 *wm8350, int irq,
- struct wm8350_platform_data *pdata);
-int wm8350_irq_exit(struct wm8350 *wm8350);
-
-#endif
diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h
deleted file mode 100644
index e831b30dde3e..000000000000
--- a/include/linux/mfd/wm8350/gpio.h
+++ /dev/null
@@ -1,356 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * gpio.h -- GPIO Driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_GPIO_H_
-#define __LINUX_MFD_WM8350_GPIO_H_
-
-#include <linux/platform_device.h>
-
-/*
- * GPIO Registers.
- */
-#define WM8350_GPIO_DEBOUNCE 0x80
-#define WM8350_GPIO_PIN_PULL_UP_CONTROL 0x81
-#define WM8350_GPIO_PULL_DOWN_CONTROL 0x82
-#define WM8350_GPIO_INT_MODE 0x83
-#define WM8350_GPIO_CONTROL 0x85
-#define WM8350_GPIO_CONFIGURATION_I_O 0x86
-#define WM8350_GPIO_PIN_POLARITY_TYPE 0x87
-#define WM8350_GPIO_FUNCTION_SELECT_1 0x8C
-#define WM8350_GPIO_FUNCTION_SELECT_2 0x8D
-#define WM8350_GPIO_FUNCTION_SELECT_3 0x8E
-#define WM8350_GPIO_FUNCTION_SELECT_4 0x8F
-#define WM8350_GPIO_LEVEL 0xE6
-
-/*
- * GPIO Functions
- */
-#define WM8350_GPIO0_GPIO_IN 0x0
-#define WM8350_GPIO0_GPIO_OUT 0x0
-#define WM8350_GPIO0_PWR_ON_IN 0x1
-#define WM8350_GPIO0_PWR_ON_OUT 0x1
-#define WM8350_GPIO0_LDO_EN_IN 0x2
-#define WM8350_GPIO0_VRTC_OUT 0x2
-#define WM8350_GPIO0_LPWR1_IN 0x3
-#define WM8350_GPIO0_POR_B_OUT 0x3
-
-#define WM8350_GPIO1_GPIO_IN 0x0
-#define WM8350_GPIO1_GPIO_OUT 0x0
-#define WM8350_GPIO1_PWR_ON_IN 0x1
-#define WM8350_GPIO1_DO_CONF_OUT 0x1
-#define WM8350_GPIO1_LDO_EN_IN 0x2
-#define WM8350_GPIO1_RESET_OUT 0x2
-#define WM8350_GPIO1_LPWR2_IN 0x3
-#define WM8350_GPIO1_MEMRST_OUT 0x3
-
-#define WM8350_GPIO2_GPIO_IN 0x0
-#define WM8350_GPIO2_GPIO_OUT 0x0
-#define WM8350_GPIO2_PWR_ON_IN 0x1
-#define WM8350_GPIO2_PWR_ON_OUT 0x1
-#define WM8350_GPIO2_WAKE_UP_IN 0x2
-#define WM8350_GPIO2_VRTC_OUT 0x2
-#define WM8350_GPIO2_32KHZ_IN 0x3
-#define WM8350_GPIO2_32KHZ_OUT 0x3
-
-#define WM8350_GPIO3_GPIO_IN 0x0
-#define WM8350_GPIO3_GPIO_OUT 0x0
-#define WM8350_GPIO3_PWR_ON_IN 0x1
-#define WM8350_GPIO3_P_CLK_OUT 0x1
-#define WM8350_GPIO3_LDO_EN_IN 0x2
-#define WM8350_GPIO3_VRTC_OUT 0x2
-#define WM8350_GPIO3_PWR_OFF_IN 0x3
-#define WM8350_GPIO3_32KHZ_OUT 0x3
-
-#define WM8350_GPIO4_GPIO_IN 0x0
-#define WM8350_GPIO4_GPIO_OUT 0x0
-#define WM8350_GPIO4_MR_IN 0x1
-#define WM8350_GPIO4_MEM_RST_OUT 0x1
-#define WM8350_GPIO4_FLASH_IN 0x2
-#define WM8350_GPIO4_ADA_OUT 0x2
-#define WM8350_GPIO4_HIBERNATE_IN 0x3
-#define WM8350_GPIO4_FLASH_OUT 0x3
-#define WM8350_GPIO4_MICDET_OUT 0x4
-#define WM8350_GPIO4_MICSHT_OUT 0x5
-
-#define WM8350_GPIO5_GPIO_IN 0x0
-#define WM8350_GPIO5_GPIO_OUT 0x0
-#define WM8350_GPIO5_LPWR1_IN 0x1
-#define WM8350_GPIO5_P_CLK_OUT 0x1
-#define WM8350_GPIO5_ADCLRCLK_IN 0x2
-#define WM8350_GPIO5_ADCLRCLK_OUT 0x2
-#define WM8350_GPIO5_HIBERNATE_IN 0x3
-#define WM8350_GPIO5_32KHZ_OUT 0x3
-#define WM8350_GPIO5_MICDET_OUT 0x4
-#define WM8350_GPIO5_MICSHT_OUT 0x5
-#define WM8350_GPIO5_ADA_OUT 0x6
-#define WM8350_GPIO5_OPCLK_OUT 0x7
-
-#define WM8350_GPIO6_GPIO_IN 0x0
-#define WM8350_GPIO6_GPIO_OUT 0x0
-#define WM8350_GPIO6_LPWR2_IN 0x1
-#define WM8350_GPIO6_MEMRST_OUT 0x1
-#define WM8350_GPIO6_FLASH_IN 0x2
-#define WM8350_GPIO6_ADA_OUT 0x2
-#define WM8350_GPIO6_HIBERNATE_IN 0x3
-#define WM8350_GPIO6_RTC_OUT 0x3
-#define WM8350_GPIO6_MICDET_OUT 0x4
-#define WM8350_GPIO6_MICSHT_OUT 0x5
-#define WM8350_GPIO6_ADCLRCLKB_OUT 0x6
-#define WM8350_GPIO6_SDOUT_OUT 0x7
-
-#define WM8350_GPIO7_GPIO_IN 0x0
-#define WM8350_GPIO7_GPIO_OUT 0x0
-#define WM8350_GPIO7_LPWR3_IN 0x1
-#define WM8350_GPIO7_P_CLK_OUT 0x1
-#define WM8350_GPIO7_MASK_IN 0x2
-#define WM8350_GPIO7_VCC_FAULT_OUT 0x2
-#define WM8350_GPIO7_HIBERNATE_IN 0x3
-#define WM8350_GPIO7_BATT_FAULT_OUT 0x3
-#define WM8350_GPIO7_MICDET_OUT 0x4
-#define WM8350_GPIO7_MICSHT_OUT 0x5
-#define WM8350_GPIO7_ADA_OUT 0x6
-#define WM8350_GPIO7_CSB_IN 0x7
-
-#define WM8350_GPIO8_GPIO_IN 0x0
-#define WM8350_GPIO8_GPIO_OUT 0x0
-#define WM8350_GPIO8_MR_IN 0x1
-#define WM8350_GPIO8_VCC_FAULT_OUT 0x1
-#define WM8350_GPIO8_ADCBCLK_IN 0x2
-#define WM8350_GPIO8_ADCBCLK_OUT 0x2
-#define WM8350_GPIO8_PWR_OFF_IN 0x3
-#define WM8350_GPIO8_BATT_FAULT_OUT 0x3
-#define WM8350_GPIO8_ALTSCL_IN 0xf
-
-#define WM8350_GPIO9_GPIO_IN 0x0
-#define WM8350_GPIO9_GPIO_OUT 0x0
-#define WM8350_GPIO9_HEARTBEAT_IN 0x1
-#define WM8350_GPIO9_VCC_FAULT_OUT 0x1
-#define WM8350_GPIO9_MASK_IN 0x2
-#define WM8350_GPIO9_LINE_GT_BATT_OUT 0x2
-#define WM8350_GPIO9_PWR_OFF_IN 0x3
-#define WM8350_GPIO9_BATT_FAULT_OUT 0x3
-#define WM8350_GPIO9_ALTSDA_OUT 0xf
-
-#define WM8350_GPIO10_GPIO_IN 0x0
-#define WM8350_GPIO10_GPIO_OUT 0x0
-#define WM8350_GPIO10_ISINKC_OUT 0x1
-#define WM8350_GPIO10_PWR_OFF_IN 0x2
-#define WM8350_GPIO10_LINE_GT_BATT_OUT 0x2
-#define WM8350_GPIO10_CHD_IND_IN 0x3
-
-#define WM8350_GPIO11_GPIO_IN 0x0
-#define WM8350_GPIO11_GPIO_OUT 0x0
-#define WM8350_GPIO11_ISINKD_OUT 0x1
-#define WM8350_GPIO11_WAKEUP_IN 0x2
-#define WM8350_GPIO11_LINE_GT_BATT_OUT 0x2
-#define WM8350_GPIO11_CHD_IND_IN 0x3
-
-#define WM8350_GPIO12_GPIO_IN 0x0
-#define WM8350_GPIO12_GPIO_OUT 0x0
-#define WM8350_GPIO12_ISINKE_OUT 0x1
-#define WM8350_GPIO12_LINE_GT_BATT_OUT 0x2
-#define WM8350_GPIO12_LINE_EN_OUT 0x3
-#define WM8350_GPIO12_32KHZ_OUT 0x4
-
-#define WM8350_GPIO_DIR_IN 0
-#define WM8350_GPIO_DIR_OUT 1
-#define WM8350_GPIO_ACTIVE_LOW 0
-#define WM8350_GPIO_ACTIVE_HIGH 1
-#define WM8350_GPIO_PULL_NONE 0
-#define WM8350_GPIO_PULL_UP 1
-#define WM8350_GPIO_PULL_DOWN 2
-#define WM8350_GPIO_INVERT_OFF 0
-#define WM8350_GPIO_INVERT_ON 1
-#define WM8350_GPIO_DEBOUNCE_OFF 0
-#define WM8350_GPIO_DEBOUNCE_ON 1
-
-/*
- * R30 (0x1E) - GPIO Interrupt Status
- */
-#define WM8350_GP12_EINT 0x1000
-#define WM8350_GP11_EINT 0x0800
-#define WM8350_GP10_EINT 0x0400
-#define WM8350_GP9_EINT 0x0200
-#define WM8350_GP8_EINT 0x0100
-#define WM8350_GP7_EINT 0x0080
-#define WM8350_GP6_EINT 0x0040
-#define WM8350_GP5_EINT 0x0020
-#define WM8350_GP4_EINT 0x0010
-#define WM8350_GP3_EINT 0x0008
-#define WM8350_GP2_EINT 0x0004
-#define WM8350_GP1_EINT 0x0002
-#define WM8350_GP0_EINT 0x0001
-
-
-/*
- * R128 (0x80) - GPIO Debounce
- */
-#define WM8350_GP12_DB 0x1000
-#define WM8350_GP11_DB 0x0800
-#define WM8350_GP10_DB 0x0400
-#define WM8350_GP9_DB 0x0200
-#define WM8350_GP8_DB 0x0100
-#define WM8350_GP7_DB 0x0080
-#define WM8350_GP6_DB 0x0040
-#define WM8350_GP5_DB 0x0020
-#define WM8350_GP4_DB 0x0010
-#define WM8350_GP3_DB 0x0008
-#define WM8350_GP2_DB 0x0004
-#define WM8350_GP1_DB 0x0002
-#define WM8350_GP0_DB 0x0001
-
-/*
- * R129 (0x81) - GPIO Pin pull up Control
- */
-#define WM8350_GP12_PU 0x1000
-#define WM8350_GP11_PU 0x0800
-#define WM8350_GP10_PU 0x0400
-#define WM8350_GP9_PU 0x0200
-#define WM8350_GP8_PU 0x0100
-#define WM8350_GP7_PU 0x0080
-#define WM8350_GP6_PU 0x0040
-#define WM8350_GP5_PU 0x0020
-#define WM8350_GP4_PU 0x0010
-#define WM8350_GP3_PU 0x0008
-#define WM8350_GP2_PU 0x0004
-#define WM8350_GP1_PU 0x0002
-#define WM8350_GP0_PU 0x0001
-
-/*
- * R130 (0x82) - GPIO Pull down Control
- */
-#define WM8350_GP12_PD 0x1000
-#define WM8350_GP11_PD 0x0800
-#define WM8350_GP10_PD 0x0400
-#define WM8350_GP9_PD 0x0200
-#define WM8350_GP8_PD 0x0100
-#define WM8350_GP7_PD 0x0080
-#define WM8350_GP6_PD 0x0040
-#define WM8350_GP5_PD 0x0020
-#define WM8350_GP4_PD 0x0010
-#define WM8350_GP3_PD 0x0008
-#define WM8350_GP2_PD 0x0004
-#define WM8350_GP1_PD 0x0002
-#define WM8350_GP0_PD 0x0001
-
-/*
- * R131 (0x83) - GPIO Interrupt Mode
- */
-#define WM8350_GP12_INTMODE 0x1000
-#define WM8350_GP11_INTMODE 0x0800
-#define WM8350_GP10_INTMODE 0x0400
-#define WM8350_GP9_INTMODE 0x0200
-#define WM8350_GP8_INTMODE 0x0100
-#define WM8350_GP7_INTMODE 0x0080
-#define WM8350_GP6_INTMODE 0x0040
-#define WM8350_GP5_INTMODE 0x0020
-#define WM8350_GP4_INTMODE 0x0010
-#define WM8350_GP3_INTMODE 0x0008
-#define WM8350_GP2_INTMODE 0x0004
-#define WM8350_GP1_INTMODE 0x0002
-#define WM8350_GP0_INTMODE 0x0001
-
-/*
- * R133 (0x85) - GPIO Control
- */
-#define WM8350_GP_DBTIME_MASK 0x00C0
-
-/*
- * R134 (0x86) - GPIO Configuration (i/o)
- */
-#define WM8350_GP12_DIR 0x1000
-#define WM8350_GP11_DIR 0x0800
-#define WM8350_GP10_DIR 0x0400
-#define WM8350_GP9_DIR 0x0200
-#define WM8350_GP8_DIR 0x0100
-#define WM8350_GP7_DIR 0x0080
-#define WM8350_GP6_DIR 0x0040
-#define WM8350_GP5_DIR 0x0020
-#define WM8350_GP4_DIR 0x0010
-#define WM8350_GP3_DIR 0x0008
-#define WM8350_GP2_DIR 0x0004
-#define WM8350_GP1_DIR 0x0002
-#define WM8350_GP0_DIR 0x0001
-
-/*
- * R135 (0x87) - GPIO Pin Polarity / Type
- */
-#define WM8350_GP12_CFG 0x1000
-#define WM8350_GP11_CFG 0x0800
-#define WM8350_GP10_CFG 0x0400
-#define WM8350_GP9_CFG 0x0200
-#define WM8350_GP8_CFG 0x0100
-#define WM8350_GP7_CFG 0x0080
-#define WM8350_GP6_CFG 0x0040
-#define WM8350_GP5_CFG 0x0020
-#define WM8350_GP4_CFG 0x0010
-#define WM8350_GP3_CFG 0x0008
-#define WM8350_GP2_CFG 0x0004
-#define WM8350_GP1_CFG 0x0002
-#define WM8350_GP0_CFG 0x0001
-
-/*
- * R140 (0x8C) - GPIO Function Select 1
- */
-#define WM8350_GP3_FN_MASK 0xF000
-#define WM8350_GP2_FN_MASK 0x0F00
-#define WM8350_GP1_FN_MASK 0x00F0
-#define WM8350_GP0_FN_MASK 0x000F
-
-/*
- * R141 (0x8D) - GPIO Function Select 2
- */
-#define WM8350_GP7_FN_MASK 0xF000
-#define WM8350_GP6_FN_MASK 0x0F00
-#define WM8350_GP5_FN_MASK 0x00F0
-#define WM8350_GP4_FN_MASK 0x000F
-
-/*
- * R142 (0x8E) - GPIO Function Select 3
- */
-#define WM8350_GP11_FN_MASK 0xF000
-#define WM8350_GP10_FN_MASK 0x0F00
-#define WM8350_GP9_FN_MASK 0x00F0
-#define WM8350_GP8_FN_MASK 0x000F
-
-/*
- * R143 (0x8F) - GPIO Function Select 4
- */
-#define WM8350_GP12_FN_MASK 0x000F
-
-/*
- * R230 (0xE6) - GPIO Pin Status
- */
-#define WM8350_GP12_LVL 0x1000
-#define WM8350_GP11_LVL 0x0800
-#define WM8350_GP10_LVL 0x0400
-#define WM8350_GP9_LVL 0x0200
-#define WM8350_GP8_LVL 0x0100
-#define WM8350_GP7_LVL 0x0080
-#define WM8350_GP6_LVL 0x0040
-#define WM8350_GP5_LVL 0x0020
-#define WM8350_GP4_LVL 0x0010
-#define WM8350_GP3_LVL 0x0008
-#define WM8350_GP2_LVL 0x0004
-#define WM8350_GP1_LVL 0x0002
-#define WM8350_GP0_LVL 0x0001
-
-struct wm8350;
-
-int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
- int pol, int pull, int invert, int debounce);
-
-struct wm8350_gpio {
- struct platform_device *pdev;
-};
-
-/*
- * GPIO Interrupts
- */
-#define WM8350_IRQ_GPIO(x) (50 + x)
-
-#endif
diff --git a/include/linux/mfd/wm8350/pmic.h b/include/linux/mfd/wm8350/pmic.h
deleted file mode 100644
index 04b09a2ddb28..000000000000
--- a/include/linux/mfd/wm8350/pmic.h
+++ /dev/null
@@ -1,775 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * pmic.h -- Power Management Driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_PMIC_H
-#define __LINUX_MFD_WM8350_PMIC_H
-
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/regulator/machine.h>
-
-/*
- * Register values.
- */
-
-#define WM8350_CURRENT_SINK_DRIVER_A 0xAC
-#define WM8350_CSA_FLASH_CONTROL 0xAD
-#define WM8350_CURRENT_SINK_DRIVER_B 0xAE
-#define WM8350_CSB_FLASH_CONTROL 0xAF
-#define WM8350_DCDC_LDO_REQUESTED 0xB0
-#define WM8350_DCDC_ACTIVE_OPTIONS 0xB1
-#define WM8350_DCDC_SLEEP_OPTIONS 0xB2
-#define WM8350_POWER_CHECK_COMPARATOR 0xB3
-#define WM8350_DCDC1_CONTROL 0xB4
-#define WM8350_DCDC1_TIMEOUTS 0xB5
-#define WM8350_DCDC1_LOW_POWER 0xB6
-#define WM8350_DCDC2_CONTROL 0xB7
-#define WM8350_DCDC2_TIMEOUTS 0xB8
-#define WM8350_DCDC3_CONTROL 0xBA
-#define WM8350_DCDC3_TIMEOUTS 0xBB
-#define WM8350_DCDC3_LOW_POWER 0xBC
-#define WM8350_DCDC4_CONTROL 0xBD
-#define WM8350_DCDC4_TIMEOUTS 0xBE
-#define WM8350_DCDC4_LOW_POWER 0xBF
-#define WM8350_DCDC5_CONTROL 0xC0
-#define WM8350_DCDC5_TIMEOUTS 0xC1
-#define WM8350_DCDC6_CONTROL 0xC3
-#define WM8350_DCDC6_TIMEOUTS 0xC4
-#define WM8350_DCDC6_LOW_POWER 0xC5
-#define WM8350_LIMIT_SWITCH_CONTROL 0xC7
-#define WM8350_LDO1_CONTROL 0xC8
-#define WM8350_LDO1_TIMEOUTS 0xC9
-#define WM8350_LDO1_LOW_POWER 0xCA
-#define WM8350_LDO2_CONTROL 0xCB
-#define WM8350_LDO2_TIMEOUTS 0xCC
-#define WM8350_LDO2_LOW_POWER 0xCD
-#define WM8350_LDO3_CONTROL 0xCE
-#define WM8350_LDO3_TIMEOUTS 0xCF
-#define WM8350_LDO3_LOW_POWER 0xD0
-#define WM8350_LDO4_CONTROL 0xD1
-#define WM8350_LDO4_TIMEOUTS 0xD2
-#define WM8350_LDO4_LOW_POWER 0xD3
-#define WM8350_VCC_FAULT_MASKS 0xD7
-#define WM8350_MAIN_BANDGAP_CONTROL 0xD8
-#define WM8350_OSC_CONTROL 0xD9
-#define WM8350_RTC_TICK_CONTROL 0xDA
-#define WM8350_SECURITY 0xDB
-#define WM8350_RAM_BIST_1 0xDC
-#define WM8350_DCDC_LDO_STATUS 0xE1
-#define WM8350_GPIO_PIN_STATUS 0xE6
-
-#define WM8350_DCDC1_FORCE_PWM 0xF8
-#define WM8350_DCDC3_FORCE_PWM 0xFA
-#define WM8350_DCDC4_FORCE_PWM 0xFB
-#define WM8350_DCDC6_FORCE_PWM 0xFD
-
-/*
- * R172 (0xAC) - Current Sink Driver A
- */
-#define WM8350_CS1_HIB_MODE 0x1000
-#define WM8350_CS1_HIB_MODE_MASK 0x1000
-#define WM8350_CS1_HIB_MODE_SHIFT 12
-#define WM8350_CS1_ISEL_MASK 0x003F
-#define WM8350_CS1_ISEL_SHIFT 0
-
-/* Bit values for R172 (0xAC) */
-#define WM8350_CS1_HIB_MODE_DISABLE 0
-#define WM8350_CS1_HIB_MODE_LEAVE 1
-
-#define WM8350_CS1_ISEL_220M 0x3F
-
-/*
- * R173 (0xAD) - CSA Flash control
- */
-#define WM8350_CS1_FLASH_MODE 0x8000
-#define WM8350_CS1_TRIGSRC 0x4000
-#define WM8350_CS1_DRIVE 0x2000
-#define WM8350_CS1_FLASH_DUR_MASK 0x0300
-#define WM8350_CS1_OFF_RAMP_MASK 0x0030
-#define WM8350_CS1_ON_RAMP_MASK 0x0003
-
-/*
- * R174 (0xAE) - Current Sink Driver B
- */
-#define WM8350_CS2_HIB_MODE 0x1000
-#define WM8350_CS2_ISEL_MASK 0x003F
-
-/*
- * R175 (0xAF) - CSB Flash control
- */
-#define WM8350_CS2_FLASH_MODE 0x8000
-#define WM8350_CS2_TRIGSRC 0x4000
-#define WM8350_CS2_DRIVE 0x2000
-#define WM8350_CS2_FLASH_DUR_MASK 0x0300
-#define WM8350_CS2_OFF_RAMP_MASK 0x0030
-#define WM8350_CS2_ON_RAMP_MASK 0x0003
-
-/*
- * R176 (0xB0) - DCDC/LDO requested
- */
-#define WM8350_LS_ENA 0x8000
-#define WM8350_LDO4_ENA 0x0800
-#define WM8350_LDO3_ENA 0x0400
-#define WM8350_LDO2_ENA 0x0200
-#define WM8350_LDO1_ENA 0x0100
-#define WM8350_DC6_ENA 0x0020
-#define WM8350_DC5_ENA 0x0010
-#define WM8350_DC4_ENA 0x0008
-#define WM8350_DC3_ENA 0x0004
-#define WM8350_DC2_ENA 0x0002
-#define WM8350_DC1_ENA 0x0001
-
-/*
- * R177 (0xB1) - DCDC Active options
- */
-#define WM8350_PUTO_MASK 0x3000
-#define WM8350_PWRUP_DELAY_MASK 0x0300
-#define WM8350_DC6_ACTIVE 0x0020
-#define WM8350_DC4_ACTIVE 0x0008
-#define WM8350_DC3_ACTIVE 0x0004
-#define WM8350_DC1_ACTIVE 0x0001
-
-/*
- * R178 (0xB2) - DCDC Sleep options
- */
-#define WM8350_DC6_SLEEP 0x0020
-#define WM8350_DC4_SLEEP 0x0008
-#define WM8350_DC3_SLEEP 0x0004
-#define WM8350_DC1_SLEEP 0x0001
-
-/*
- * R179 (0xB3) - Power-check comparator
- */
-#define WM8350_PCCMP_ERRACT 0x4000
-#define WM8350_PCCMP_RAIL 0x0100
-#define WM8350_PCCMP_OFF_THR_MASK 0x0070
-#define WM8350_PCCMP_ON_THR_MASK 0x0007
-
-/*
- * R180 (0xB4) - DCDC1 Control
- */
-#define WM8350_DC1_OPFLT 0x0400
-#define WM8350_DC1_VSEL_MASK 0x007F
-#define WM8350_DC1_VSEL_SHIFT 0
-
-/*
- * R181 (0xB5) - DCDC1 Timeouts
- */
-#define WM8350_DC1_ERRACT_MASK 0xC000
-#define WM8350_DC1_ERRACT_SHIFT 14
-#define WM8350_DC1_ENSLOT_MASK 0x3C00
-#define WM8350_DC1_ENSLOT_SHIFT 10
-#define WM8350_DC1_SDSLOT_MASK 0x03C0
-#define WM8350_DC1_UVTO_MASK 0x0030
-#define WM8350_DC1_SDSLOT_SHIFT 6
-
-/* Bit values for R181 (0xB5) */
-#define WM8350_DC1_ERRACT_NONE 0
-#define WM8350_DC1_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_DC1_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R182 (0xB6) - DCDC1 Low Power
- */
-#define WM8350_DC1_HIB_MODE_MASK 0x7000
-#define WM8350_DC1_HIB_TRIG_MASK 0x0300
-#define WM8350_DC1_VIMG_MASK 0x007F
-
-/*
- * R183 (0xB7) - DCDC2 Control
- */
-#define WM8350_DC2_MODE 0x4000
-#define WM8350_DC2_MODE_MASK 0x4000
-#define WM8350_DC2_MODE_SHIFT 14
-#define WM8350_DC2_HIB_MODE 0x1000
-#define WM8350_DC2_HIB_MODE_MASK 0x1000
-#define WM8350_DC2_HIB_MODE_SHIFT 12
-#define WM8350_DC2_HIB_TRIG_MASK 0x0300
-#define WM8350_DC2_HIB_TRIG_SHIFT 8
-#define WM8350_DC2_ILIM 0x0040
-#define WM8350_DC2_ILIM_MASK 0x0040
-#define WM8350_DC2_ILIM_SHIFT 6
-#define WM8350_DC2_RMP_MASK 0x0018
-#define WM8350_DC2_RMP_SHIFT 3
-#define WM8350_DC2_FBSRC_MASK 0x0003
-#define WM8350_DC2_FBSRC_SHIFT 0
-
-/* Bit values for R183 (0xB7) */
-#define WM8350_DC2_MODE_BOOST 0
-#define WM8350_DC2_MODE_SWITCH 1
-
-#define WM8350_DC2_HIB_MODE_ACTIVE 1
-#define WM8350_DC2_HIB_MODE_DISABLE 0
-
-#define WM8350_DC2_HIB_TRIG_NONE 0
-#define WM8350_DC2_HIB_TRIG_LPWR1 1
-#define WM8350_DC2_HIB_TRIG_LPWR2 2
-#define WM8350_DC2_HIB_TRIG_LPWR3 3
-
-#define WM8350_DC2_ILIM_HIGH 0
-#define WM8350_DC2_ILIM_LOW 1
-
-#define WM8350_DC2_RMP_30V 0
-#define WM8350_DC2_RMP_20V 1
-#define WM8350_DC2_RMP_10V 2
-#define WM8350_DC2_RMP_5V 3
-
-#define WM8350_DC2_FBSRC_FB2 0
-#define WM8350_DC2_FBSRC_ISINKA 1
-#define WM8350_DC2_FBSRC_ISINKB 2
-#define WM8350_DC2_FBSRC_USB 3
-
-/*
- * R184 (0xB8) - DCDC2 Timeouts
- */
-#define WM8350_DC2_ERRACT_MASK 0xC000
-#define WM8350_DC2_ERRACT_SHIFT 14
-#define WM8350_DC2_ENSLOT_MASK 0x3C00
-#define WM8350_DC2_ENSLOT_SHIFT 10
-#define WM8350_DC2_SDSLOT_MASK 0x03C0
-#define WM8350_DC2_UVTO_MASK 0x0030
-
-/* Bit values for R184 (0xB8) */
-#define WM8350_DC2_ERRACT_NONE 0
-#define WM8350_DC2_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_DC2_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R186 (0xBA) - DCDC3 Control
- */
-#define WM8350_DC3_OPFLT 0x0400
-#define WM8350_DC3_VSEL_MASK 0x007F
-#define WM8350_DC3_VSEL_SHIFT 0
-
-/*
- * R187 (0xBB) - DCDC3 Timeouts
- */
-#define WM8350_DC3_ERRACT_MASK 0xC000
-#define WM8350_DC3_ERRACT_SHIFT 14
-#define WM8350_DC3_ENSLOT_MASK 0x3C00
-#define WM8350_DC3_ENSLOT_SHIFT 10
-#define WM8350_DC3_SDSLOT_MASK 0x03C0
-#define WM8350_DC3_UVTO_MASK 0x0030
-#define WM8350_DC3_SDSLOT_SHIFT 6
-
-/* Bit values for R187 (0xBB) */
-#define WM8350_DC3_ERRACT_NONE 0
-#define WM8350_DC3_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_DC3_ERRACT_SHUTDOWN_SYS 2
-/*
- * R188 (0xBC) - DCDC3 Low Power
- */
-#define WM8350_DC3_HIB_MODE_MASK 0x7000
-#define WM8350_DC3_HIB_TRIG_MASK 0x0300
-#define WM8350_DC3_VIMG_MASK 0x007F
-
-/*
- * R189 (0xBD) - DCDC4 Control
- */
-#define WM8350_DC4_OPFLT 0x0400
-#define WM8350_DC4_VSEL_MASK 0x007F
-#define WM8350_DC4_VSEL_SHIFT 0
-
-/*
- * R190 (0xBE) - DCDC4 Timeouts
- */
-#define WM8350_DC4_ERRACT_MASK 0xC000
-#define WM8350_DC4_ERRACT_SHIFT 14
-#define WM8350_DC4_ENSLOT_MASK 0x3C00
-#define WM8350_DC4_ENSLOT_SHIFT 10
-#define WM8350_DC4_SDSLOT_MASK 0x03C0
-#define WM8350_DC4_UVTO_MASK 0x0030
-#define WM8350_DC4_SDSLOT_SHIFT 6
-
-/* Bit values for R190 (0xBE) */
-#define WM8350_DC4_ERRACT_NONE 0
-#define WM8350_DC4_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_DC4_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R191 (0xBF) - DCDC4 Low Power
- */
-#define WM8350_DC4_HIB_MODE_MASK 0x7000
-#define WM8350_DC4_HIB_TRIG_MASK 0x0300
-#define WM8350_DC4_VIMG_MASK 0x007F
-
-/*
- * R192 (0xC0) - DCDC5 Control
- */
-#define WM8350_DC5_MODE 0x4000
-#define WM8350_DC5_MODE_MASK 0x4000
-#define WM8350_DC5_MODE_SHIFT 14
-#define WM8350_DC5_HIB_MODE 0x1000
-#define WM8350_DC5_HIB_MODE_MASK 0x1000
-#define WM8350_DC5_HIB_MODE_SHIFT 12
-#define WM8350_DC5_HIB_TRIG_MASK 0x0300
-#define WM8350_DC5_HIB_TRIG_SHIFT 8
-#define WM8350_DC5_ILIM 0x0040
-#define WM8350_DC5_ILIM_MASK 0x0040
-#define WM8350_DC5_ILIM_SHIFT 6
-#define WM8350_DC5_RMP_MASK 0x0018
-#define WM8350_DC5_RMP_SHIFT 3
-#define WM8350_DC5_FBSRC_MASK 0x0003
-#define WM8350_DC5_FBSRC_SHIFT 0
-
-/* Bit values for R192 (0xC0) */
-#define WM8350_DC5_MODE_BOOST 0
-#define WM8350_DC5_MODE_SWITCH 1
-
-#define WM8350_DC5_HIB_MODE_ACTIVE 1
-#define WM8350_DC5_HIB_MODE_DISABLE 0
-
-#define WM8350_DC5_HIB_TRIG_NONE 0
-#define WM8350_DC5_HIB_TRIG_LPWR1 1
-#define WM8350_DC5_HIB_TRIG_LPWR2 2
-#define WM8350_DC5_HIB_TRIG_LPWR3 3
-
-#define WM8350_DC5_ILIM_HIGH 0
-#define WM8350_DC5_ILIM_LOW 1
-
-#define WM8350_DC5_RMP_30V 0
-#define WM8350_DC5_RMP_20V 1
-#define WM8350_DC5_RMP_10V 2
-#define WM8350_DC5_RMP_5V 3
-
-#define WM8350_DC5_FBSRC_FB2 0
-#define WM8350_DC5_FBSRC_ISINKA 1
-#define WM8350_DC5_FBSRC_ISINKB 2
-#define WM8350_DC5_FBSRC_USB 3
-
-/*
- * R193 (0xC1) - DCDC5 Timeouts
- */
-#define WM8350_DC5_ERRACT_MASK 0xC000
-#define WM8350_DC5_ERRACT_SHIFT 14
-#define WM8350_DC5_ENSLOT_MASK 0x3C00
-#define WM8350_DC5_ENSLOT_SHIFT 10
-#define WM8350_DC5_SDSLOT_MASK 0x03C0
-#define WM8350_DC5_UVTO_MASK 0x0030
-#define WM8350_DC5_SDSLOT_SHIFT 6
-
-/* Bit values for R193 (0xC1) */
-#define WM8350_DC5_ERRACT_NONE 0
-#define WM8350_DC5_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_DC5_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R195 (0xC3) - DCDC6 Control
- */
-#define WM8350_DC6_OPFLT 0x0400
-#define WM8350_DC6_VSEL_MASK 0x007F
-#define WM8350_DC6_VSEL_SHIFT 0
-
-/*
- * R196 (0xC4) - DCDC6 Timeouts
- */
-#define WM8350_DC6_ERRACT_MASK 0xC000
-#define WM8350_DC6_ERRACT_SHIFT 14
-#define WM8350_DC6_ENSLOT_MASK 0x3C00
-#define WM8350_DC6_ENSLOT_SHIFT 10
-#define WM8350_DC6_SDSLOT_MASK 0x03C0
-#define WM8350_DC6_UVTO_MASK 0x0030
-#define WM8350_DC6_SDSLOT_SHIFT 6
-
-/* Bit values for R196 (0xC4) */
-#define WM8350_DC6_ERRACT_NONE 0
-#define WM8350_DC6_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_DC6_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R197 (0xC5) - DCDC6 Low Power
- */
-#define WM8350_DC6_HIB_MODE_MASK 0x7000
-#define WM8350_DC6_HIB_TRIG_MASK 0x0300
-#define WM8350_DC6_VIMG_MASK 0x007F
-
-/*
- * R199 (0xC7) - Limit Switch Control
- */
-#define WM8350_LS_ERRACT_MASK 0xC000
-#define WM8350_LS_ERRACT_SHIFT 14
-#define WM8350_LS_ENSLOT_MASK 0x3C00
-#define WM8350_LS_ENSLOT_SHIFT 10
-#define WM8350_LS_SDSLOT_MASK 0x03C0
-#define WM8350_LS_SDSLOT_SHIFT 6
-#define WM8350_LS_HIB_MODE 0x0010
-#define WM8350_LS_HIB_MODE_MASK 0x0010
-#define WM8350_LS_HIB_MODE_SHIFT 4
-#define WM8350_LS_HIB_PROT 0x0002
-#define WM8350_LS_HIB_PROT_MASK 0x0002
-#define WM8350_LS_HIB_PROT_SHIFT 1
-#define WM8350_LS_PROT 0x0001
-#define WM8350_LS_PROT_MASK 0x0001
-#define WM8350_LS_PROT_SHIFT 0
-
-/* Bit values for R199 (0xC7) */
-#define WM8350_LS_ERRACT_NONE 0
-#define WM8350_LS_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_LS_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R200 (0xC8) - LDO1 Control
- */
-#define WM8350_LDO1_SWI 0x4000
-#define WM8350_LDO1_OPFLT 0x0400
-#define WM8350_LDO1_VSEL_MASK 0x001F
-#define WM8350_LDO1_VSEL_SHIFT 0
-
-/*
- * R201 (0xC9) - LDO1 Timeouts
- */
-#define WM8350_LDO1_ERRACT_MASK 0xC000
-#define WM8350_LDO1_ERRACT_SHIFT 14
-#define WM8350_LDO1_ENSLOT_MASK 0x3C00
-#define WM8350_LDO1_ENSLOT_SHIFT 10
-#define WM8350_LDO1_SDSLOT_MASK 0x03C0
-#define WM8350_LDO1_UVTO_MASK 0x0030
-#define WM8350_LDO1_SDSLOT_SHIFT 6
-
-/* Bit values for R201 (0xC9) */
-#define WM8350_LDO1_ERRACT_NONE 0
-#define WM8350_LDO1_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_LDO1_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R202 (0xCA) - LDO1 Low Power
- */
-#define WM8350_LDO1_HIB_MODE_MASK 0x3000
-#define WM8350_LDO1_HIB_TRIG_MASK 0x0300
-#define WM8350_LDO1_VIMG_MASK 0x001F
-#define WM8350_LDO1_HIB_MODE_DIS (0x1 << 12)
-
-
-/*
- * R203 (0xCB) - LDO2 Control
- */
-#define WM8350_LDO2_SWI 0x4000
-#define WM8350_LDO2_OPFLT 0x0400
-#define WM8350_LDO2_VSEL_MASK 0x001F
-#define WM8350_LDO2_VSEL_SHIFT 0
-
-/*
- * R204 (0xCC) - LDO2 Timeouts
- */
-#define WM8350_LDO2_ERRACT_MASK 0xC000
-#define WM8350_LDO2_ERRACT_SHIFT 14
-#define WM8350_LDO2_ENSLOT_MASK 0x3C00
-#define WM8350_LDO2_ENSLOT_SHIFT 10
-#define WM8350_LDO2_SDSLOT_MASK 0x03C0
-#define WM8350_LDO2_SDSLOT_SHIFT 6
-
-/* Bit values for R204 (0xCC) */
-#define WM8350_LDO2_ERRACT_NONE 0
-#define WM8350_LDO2_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_LDO2_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R205 (0xCD) - LDO2 Low Power
- */
-#define WM8350_LDO2_HIB_MODE_MASK 0x3000
-#define WM8350_LDO2_HIB_TRIG_MASK 0x0300
-#define WM8350_LDO2_VIMG_MASK 0x001F
-
-/*
- * R206 (0xCE) - LDO3 Control
- */
-#define WM8350_LDO3_SWI 0x4000
-#define WM8350_LDO3_OPFLT 0x0400
-#define WM8350_LDO3_VSEL_MASK 0x001F
-#define WM8350_LDO3_VSEL_SHIFT 0
-
-/*
- * R207 (0xCF) - LDO3 Timeouts
- */
-#define WM8350_LDO3_ERRACT_MASK 0xC000
-#define WM8350_LDO3_ERRACT_SHIFT 14
-#define WM8350_LDO3_ENSLOT_MASK 0x3C00
-#define WM8350_LDO3_ENSLOT_SHIFT 10
-#define WM8350_LDO3_SDSLOT_MASK 0x03C0
-#define WM8350_LDO3_UVTO_MASK 0x0030
-#define WM8350_LDO3_SDSLOT_SHIFT 6
-
-/* Bit values for R207 (0xCF) */
-#define WM8350_LDO3_ERRACT_NONE 0
-#define WM8350_LDO3_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_LDO3_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R208 (0xD0) - LDO3 Low Power
- */
-#define WM8350_LDO3_HIB_MODE_MASK 0x3000
-#define WM8350_LDO3_HIB_TRIG_MASK 0x0300
-#define WM8350_LDO3_VIMG_MASK 0x001F
-
-/*
- * R209 (0xD1) - LDO4 Control
- */
-#define WM8350_LDO4_SWI 0x4000
-#define WM8350_LDO4_OPFLT 0x0400
-#define WM8350_LDO4_VSEL_MASK 0x001F
-#define WM8350_LDO4_VSEL_SHIFT 0
-
-/*
- * R210 (0xD2) - LDO4 Timeouts
- */
-#define WM8350_LDO4_ERRACT_MASK 0xC000
-#define WM8350_LDO4_ERRACT_SHIFT 14
-#define WM8350_LDO4_ENSLOT_MASK 0x3C00
-#define WM8350_LDO4_ENSLOT_SHIFT 10
-#define WM8350_LDO4_SDSLOT_MASK 0x03C0
-#define WM8350_LDO4_UVTO_MASK 0x0030
-#define WM8350_LDO4_SDSLOT_SHIFT 6
-
-/* Bit values for R210 (0xD2) */
-#define WM8350_LDO4_ERRACT_NONE 0
-#define WM8350_LDO4_ERRACT_SHUTDOWN_CONV 1
-#define WM8350_LDO4_ERRACT_SHUTDOWN_SYS 2
-
-/*
- * R211 (0xD3) - LDO4 Low Power
- */
-#define WM8350_LDO4_HIB_MODE_MASK 0x3000
-#define WM8350_LDO4_HIB_TRIG_MASK 0x0300
-#define WM8350_LDO4_VIMG_MASK 0x001F
-
-/*
- * R215 (0xD7) - VCC_FAULT Masks
- */
-#define WM8350_LS_FAULT 0x8000
-#define WM8350_LDO4_FAULT 0x0800
-#define WM8350_LDO3_FAULT 0x0400
-#define WM8350_LDO2_FAULT 0x0200
-#define WM8350_LDO1_FAULT 0x0100
-#define WM8350_DC6_FAULT 0x0020
-#define WM8350_DC5_FAULT 0x0010
-#define WM8350_DC4_FAULT 0x0008
-#define WM8350_DC3_FAULT 0x0004
-#define WM8350_DC2_FAULT 0x0002
-#define WM8350_DC1_FAULT 0x0001
-
-/*
- * R216 (0xD8) - Main Bandgap Control
- */
-#define WM8350_MBG_LOAD_FUSES 0x8000
-#define WM8350_MBG_FUSE_WPREP 0x4000
-#define WM8350_MBG_FUSE_WRITE 0x2000
-#define WM8350_MBG_FUSE_TRIM_MASK 0x1F00
-#define WM8350_MBG_TRIM_SRC 0x0020
-#define WM8350_MBG_USER_TRIM_MASK 0x001F
-
-/*
- * R217 (0xD9) - OSC Control
- */
-#define WM8350_OSC_LOAD_FUSES 0x8000
-#define WM8350_OSC_FUSE_WPREP 0x4000
-#define WM8350_OSC_FUSE_WRITE 0x2000
-#define WM8350_OSC_FUSE_TRIM_MASK 0x0F00
-#define WM8350_OSC_TRIM_SRC 0x0020
-#define WM8350_OSC_USER_TRIM_MASK 0x000F
-
-/*
- * R248 (0xF8) - DCDC1 Force PWM
- */
-#define WM8350_DCDC1_FORCE_PWM_ENA 0x0010
-
-/*
- * R250 (0xFA) - DCDC3 Force PWM
- */
-#define WM8350_DCDC3_FORCE_PWM_ENA 0x0010
-
-/*
- * R251 (0xFB) - DCDC4 Force PWM
- */
-#define WM8350_DCDC4_FORCE_PWM_ENA 0x0010
-
-/*
- * R253 (0xFD) - DCDC1 Force PWM
- */
-#define WM8350_DCDC6_FORCE_PWM_ENA 0x0010
-
-/*
- * DCDC's
- */
-#define WM8350_DCDC_1 0
-#define WM8350_DCDC_2 1
-#define WM8350_DCDC_3 2
-#define WM8350_DCDC_4 3
-#define WM8350_DCDC_5 4
-#define WM8350_DCDC_6 5
-
-/* DCDC modes */
-#define WM8350_DCDC_ACTIVE_STANDBY 0
-#define WM8350_DCDC_ACTIVE_PULSE 1
-#define WM8350_DCDC_SLEEP_NORMAL 0
-#define WM8350_DCDC_SLEEP_LOW 1
-
-/* DCDC Low power (Hibernate) mode */
-#define WM8350_DCDC_HIB_MODE_CUR (0 << 12)
-#define WM8350_DCDC_HIB_MODE_IMAGE (1 << 12)
-#define WM8350_DCDC_HIB_MODE_STANDBY (2 << 12)
-#define WM8350_DCDC_HIB_MODE_LDO (4 << 12)
-#define WM8350_DCDC_HIB_MODE_LDO_IM (5 << 12)
-#define WM8350_DCDC_HIB_MODE_DIS (7 << 12)
-#define WM8350_DCDC_HIB_MODE_MASK (7 << 12)
-
-/* DCDC Low Power (Hibernate) signal */
-#define WM8350_DCDC_HIB_SIG_REG (0 << 8)
-#define WM8350_DCDC_HIB_SIG_LPWR1 (1 << 8)
-#define WM8350_DCDC_HIB_SIG_LPWR2 (2 << 8)
-#define WM8350_DCDC_HIB_SIG_LPWR3 (3 << 8)
-
-/* LDO Low power (Hibernate) mode */
-#define WM8350_LDO_HIB_MODE_IMAGE (0 << 0)
-#define WM8350_LDO_HIB_MODE_DIS (1 << 0)
-
-/* LDO Low Power (Hibernate) signal */
-#define WM8350_LDO_HIB_SIG_REG (0 << 8)
-#define WM8350_LDO_HIB_SIG_LPWR1 (1 << 8)
-#define WM8350_LDO_HIB_SIG_LPWR2 (2 << 8)
-#define WM8350_LDO_HIB_SIG_LPWR3 (3 << 8)
-
-/*
- * LDOs
- */
-#define WM8350_LDO_1 6
-#define WM8350_LDO_2 7
-#define WM8350_LDO_3 8
-#define WM8350_LDO_4 9
-
-/*
- * ISINKs
- */
-#define WM8350_ISINK_A 10
-#define WM8350_ISINK_B 11
-
-#define WM8350_ISINK_MODE_BOOST 0
-#define WM8350_ISINK_MODE_SWITCH 1
-#define WM8350_ISINK_ILIM_NORMAL 0
-#define WM8350_ISINK_ILIM_LOW 1
-
-#define WM8350_ISINK_FLASH_DISABLE 0
-#define WM8350_ISINK_FLASH_ENABLE 1
-#define WM8350_ISINK_FLASH_TRIG_BIT 0
-#define WM8350_ISINK_FLASH_TRIG_GPIO 1
-#define WM8350_ISINK_FLASH_MODE_EN (1 << 13)
-#define WM8350_ISINK_FLASH_MODE_DIS (0 << 13)
-#define WM8350_ISINK_FLASH_DUR_32MS (0 << 8)
-#define WM8350_ISINK_FLASH_DUR_64MS (1 << 8)
-#define WM8350_ISINK_FLASH_DUR_96MS (2 << 8)
-#define WM8350_ISINK_FLASH_DUR_1024MS (3 << 8)
-#define WM8350_ISINK_FLASH_ON_INSTANT (0 << 0)
-#define WM8350_ISINK_FLASH_ON_0_25S (1 << 0)
-#define WM8350_ISINK_FLASH_ON_0_50S (2 << 0)
-#define WM8350_ISINK_FLASH_ON_1_00S (3 << 0)
-#define WM8350_ISINK_FLASH_ON_1_95S (1 << 0)
-#define WM8350_ISINK_FLASH_ON_3_91S (2 << 0)
-#define WM8350_ISINK_FLASH_ON_7_80S (3 << 0)
-#define WM8350_ISINK_FLASH_OFF_INSTANT (0 << 4)
-#define WM8350_ISINK_FLASH_OFF_0_25S (1 << 4)
-#define WM8350_ISINK_FLASH_OFF_0_50S (2 << 4)
-#define WM8350_ISINK_FLASH_OFF_1_00S (3 << 4)
-#define WM8350_ISINK_FLASH_OFF_1_95S (1 << 4)
-#define WM8350_ISINK_FLASH_OFF_3_91S (2 << 4)
-#define WM8350_ISINK_FLASH_OFF_7_80S (3 << 4)
-
-/*
- * Regulator Interrupts.
- */
-#define WM8350_IRQ_CS1 13
-#define WM8350_IRQ_CS2 14
-#define WM8350_IRQ_UV_LDO4 25
-#define WM8350_IRQ_UV_LDO3 26
-#define WM8350_IRQ_UV_LDO2 27
-#define WM8350_IRQ_UV_LDO1 28
-#define WM8350_IRQ_UV_DC6 29
-#define WM8350_IRQ_UV_DC5 30
-#define WM8350_IRQ_UV_DC4 31
-#define WM8350_IRQ_UV_DC3 32
-#define WM8350_IRQ_UV_DC2 33
-#define WM8350_IRQ_UV_DC1 34
-#define WM8350_IRQ_OC_LS 35
-
-#define NUM_WM8350_REGULATORS 12
-
-struct wm8350;
-struct platform_device;
-struct regulator_init_data;
-
-/*
- * WM8350 LED platform data
- */
-struct wm8350_led_platform_data {
- const char *name;
- const char *default_trigger;
- int max_uA;
-};
-
-struct wm8350_led {
- struct platform_device *pdev;
- struct work_struct work;
- spinlock_t value_lock;
- enum led_brightness value;
- struct led_classdev cdev;
- int max_uA_index;
- int enabled;
-
- struct regulator *isink;
- struct regulator_consumer_supply isink_consumer;
- struct regulator_init_data isink_init;
- struct regulator *dcdc;
- struct regulator_consumer_supply dcdc_consumer;
- struct regulator_init_data dcdc_init;
-};
-
-struct wm8350_pmic {
- /* Number of regulators of each type on this device */
- int max_dcdc;
- int max_isink;
-
- /* ISINK to DCDC mapping */
- int isink_A_dcdc;
- int isink_B_dcdc;
-
- /* hibernate configs */
- u16 dcdc1_hib_mode;
- u16 dcdc3_hib_mode;
- u16 dcdc4_hib_mode;
- u16 dcdc6_hib_mode;
-
- /* regulator devices */
- struct platform_device *pdev[NUM_WM8350_REGULATORS];
-
- /* LED devices */
- struct wm8350_led led[2];
-};
-
-int wm8350_register_regulator(struct wm8350 *wm8350, int reg,
- struct regulator_init_data *initdata);
-int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
- struct wm8350_led_platform_data *pdata);
-
-/*
- * Additional DCDC control not supported via regulator API
- */
-int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
- u16 stop, u16 fault);
-int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode,
- u16 ilim, u16 ramp, u16 feedback);
-
-/*
- * Additional LDO control not supported via regulator API
- */
-int wm8350_ldo_set_slot(struct wm8350 *wm8350, int ldo, u16 start, u16 stop);
-
-/*
- * Additional ISINK control not supported via regulator API
- */
-int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode,
- u16 trigger, u16 duration, u16 on_ramp,
- u16 off_ramp, u16 drive);
-
-#endif
diff --git a/include/linux/mfd/wm8350/rtc.h b/include/linux/mfd/wm8350/rtc.h
deleted file mode 100644
index b2f58359b2eb..000000000000
--- a/include/linux/mfd/wm8350/rtc.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * rtc.h -- RTC driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_RTC_H
-#define __LINUX_MFD_WM8350_RTC_H
-
-#include <linux/platform_device.h>
-
-/*
- * Register values.
- */
-#define WM8350_RTC_SECONDS_MINUTES 0x10
-#define WM8350_RTC_HOURS_DAY 0x11
-#define WM8350_RTC_DATE_MONTH 0x12
-#define WM8350_RTC_YEAR 0x13
-#define WM8350_ALARM_SECONDS_MINUTES 0x14
-#define WM8350_ALARM_HOURS_DAY 0x15
-#define WM8350_ALARM_DATE_MONTH 0x16
-#define WM8350_RTC_TIME_CONTROL 0x17
-
-/*
- * R16 (0x10) - RTC Seconds/Minutes
- */
-#define WM8350_RTC_MINS_MASK 0x7F00
-#define WM8350_RTC_MINS_SHIFT 8
-#define WM8350_RTC_SECS_MASK 0x007F
-#define WM8350_RTC_SECS_SHIFT 0
-
-/*
- * R17 (0x11) - RTC Hours/Day
- */
-#define WM8350_RTC_DAY_MASK 0x0700
-#define WM8350_RTC_DAY_SHIFT 8
-#define WM8350_RTC_HPM_MASK 0x0020
-#define WM8350_RTC_HPM_SHIFT 5
-#define WM8350_RTC_HRS_MASK 0x001F
-#define WM8350_RTC_HRS_SHIFT 0
-
-/* Bit values for R21 (0x15) */
-#define WM8350_RTC_DAY_SUN 1
-#define WM8350_RTC_DAY_MON 2
-#define WM8350_RTC_DAY_TUE 3
-#define WM8350_RTC_DAY_WED 4
-#define WM8350_RTC_DAY_THU 5
-#define WM8350_RTC_DAY_FRI 6
-#define WM8350_RTC_DAY_SAT 7
-
-#define WM8350_RTC_HPM_AM 0
-#define WM8350_RTC_HPM_PM 1
-
-/*
- * R18 (0x12) - RTC Date/Month
- */
-#define WM8350_RTC_MTH_MASK 0x1F00
-#define WM8350_RTC_MTH_SHIFT 8
-#define WM8350_RTC_DATE_MASK 0x003F
-#define WM8350_RTC_DATE_SHIFT 0
-
-/* Bit values for R22 (0x16) */
-#define WM8350_RTC_MTH_JAN 1
-#define WM8350_RTC_MTH_FEB 2
-#define WM8350_RTC_MTH_MAR 3
-#define WM8350_RTC_MTH_APR 4
-#define WM8350_RTC_MTH_MAY 5
-#define WM8350_RTC_MTH_JUN 6
-#define WM8350_RTC_MTH_JUL 7
-#define WM8350_RTC_MTH_AUG 8
-#define WM8350_RTC_MTH_SEP 9
-#define WM8350_RTC_MTH_OCT 10
-#define WM8350_RTC_MTH_NOV 11
-#define WM8350_RTC_MTH_DEC 12
-#define WM8350_RTC_MTH_JAN_BCD 0x01
-#define WM8350_RTC_MTH_FEB_BCD 0x02
-#define WM8350_RTC_MTH_MAR_BCD 0x03
-#define WM8350_RTC_MTH_APR_BCD 0x04
-#define WM8350_RTC_MTH_MAY_BCD 0x05
-#define WM8350_RTC_MTH_JUN_BCD 0x06
-#define WM8350_RTC_MTH_JUL_BCD 0x07
-#define WM8350_RTC_MTH_AUG_BCD 0x08
-#define WM8350_RTC_MTH_SEP_BCD 0x09
-#define WM8350_RTC_MTH_OCT_BCD 0x10
-#define WM8350_RTC_MTH_NOV_BCD 0x11
-#define WM8350_RTC_MTH_DEC_BCD 0x12
-
-/*
- * R19 (0x13) - RTC Year
- */
-#define WM8350_RTC_YHUNDREDS_MASK 0x3F00
-#define WM8350_RTC_YHUNDREDS_SHIFT 8
-#define WM8350_RTC_YUNITS_MASK 0x00FF
-#define WM8350_RTC_YUNITS_SHIFT 0
-
-/*
- * R20 (0x14) - Alarm Seconds/Minutes
- */
-#define WM8350_RTC_ALMMINS_MASK 0x7F00
-#define WM8350_RTC_ALMMINS_SHIFT 8
-#define WM8350_RTC_ALMSECS_MASK 0x007F
-#define WM8350_RTC_ALMSECS_SHIFT 0
-
-/* Bit values for R20 (0x14) */
-#define WM8350_RTC_ALMMINS_DONT_CARE -1
-#define WM8350_RTC_ALMSECS_DONT_CARE -1
-
-/*
- * R21 (0x15) - Alarm Hours/Day
- */
-#define WM8350_RTC_ALMDAY_MASK 0x0F00
-#define WM8350_RTC_ALMDAY_SHIFT 8
-#define WM8350_RTC_ALMHPM_MASK 0x0020
-#define WM8350_RTC_ALMHPM_SHIFT 5
-#define WM8350_RTC_ALMHRS_MASK 0x001F
-#define WM8350_RTC_ALMHRS_SHIFT 0
-
-/* Bit values for R21 (0x15) */
-#define WM8350_RTC_ALMDAY_DONT_CARE -1
-#define WM8350_RTC_ALMDAY_SUN 1
-#define WM8350_RTC_ALMDAY_MON 2
-#define WM8350_RTC_ALMDAY_TUE 3
-#define WM8350_RTC_ALMDAY_WED 4
-#define WM8350_RTC_ALMDAY_THU 5
-#define WM8350_RTC_ALMDAY_FRI 6
-#define WM8350_RTC_ALMDAY_SAT 7
-
-#define WM8350_RTC_ALMHPM_AM 0
-#define WM8350_RTC_ALMHPM_PM 1
-
-#define WM8350_RTC_ALMHRS_DONT_CARE -1
-
-/*
- * R22 (0x16) - Alarm Date/Month
- */
-#define WM8350_RTC_ALMMTH_MASK 0x1F00
-#define WM8350_RTC_ALMMTH_SHIFT 8
-#define WM8350_RTC_ALMDATE_MASK 0x003F
-#define WM8350_RTC_ALMDATE_SHIFT 0
-
-/* Bit values for R22 (0x16) */
-#define WM8350_RTC_ALMDATE_DONT_CARE -1
-
-#define WM8350_RTC_ALMMTH_DONT_CARE -1
-#define WM8350_RTC_ALMMTH_JAN 1
-#define WM8350_RTC_ALMMTH_FEB 2
-#define WM8350_RTC_ALMMTH_MAR 3
-#define WM8350_RTC_ALMMTH_APR 4
-#define WM8350_RTC_ALMMTH_MAY 5
-#define WM8350_RTC_ALMMTH_JUN 6
-#define WM8350_RTC_ALMMTH_JUL 7
-#define WM8350_RTC_ALMMTH_AUG 8
-#define WM8350_RTC_ALMMTH_SEP 9
-#define WM8350_RTC_ALMMTH_OCT 10
-#define WM8350_RTC_ALMMTH_NOV 11
-#define WM8350_RTC_ALMMTH_DEC 12
-#define WM8350_RTC_ALMMTH_JAN_BCD 0x01
-#define WM8350_RTC_ALMMTH_FEB_BCD 0x02
-#define WM8350_RTC_ALMMTH_MAR_BCD 0x03
-#define WM8350_RTC_ALMMTH_APR_BCD 0x04
-#define WM8350_RTC_ALMMTH_MAY_BCD 0x05
-#define WM8350_RTC_ALMMTH_JUN_BCD 0x06
-#define WM8350_RTC_ALMMTH_JUL_BCD 0x07
-#define WM8350_RTC_ALMMTH_AUG_BCD 0x08
-#define WM8350_RTC_ALMMTH_SEP_BCD 0x09
-#define WM8350_RTC_ALMMTH_OCT_BCD 0x10
-#define WM8350_RTC_ALMMTH_NOV_BCD 0x11
-#define WM8350_RTC_ALMMTH_DEC_BCD 0x12
-
-/*
- * R23 (0x17) - RTC Time Control
- */
-#define WM8350_RTC_BCD 0x8000
-#define WM8350_RTC_BCD_MASK 0x8000
-#define WM8350_RTC_BCD_SHIFT 15
-#define WM8350_RTC_12HR 0x4000
-#define WM8350_RTC_12HR_MASK 0x4000
-#define WM8350_RTC_12HR_SHIFT 14
-#define WM8350_RTC_DST 0x2000
-#define WM8350_RTC_DST_MASK 0x2000
-#define WM8350_RTC_DST_SHIFT 13
-#define WM8350_RTC_SET 0x0800
-#define WM8350_RTC_SET_MASK 0x0800
-#define WM8350_RTC_SET_SHIFT 11
-#define WM8350_RTC_STS 0x0400
-#define WM8350_RTC_STS_MASK 0x0400
-#define WM8350_RTC_STS_SHIFT 10
-#define WM8350_RTC_ALMSET 0x0200
-#define WM8350_RTC_ALMSET_MASK 0x0200
-#define WM8350_RTC_ALMSET_SHIFT 9
-#define WM8350_RTC_ALMSTS 0x0100
-#define WM8350_RTC_ALMSTS_MASK 0x0100
-#define WM8350_RTC_ALMSTS_SHIFT 8
-#define WM8350_RTC_PINT 0x0070
-#define WM8350_RTC_PINT_MASK 0x0070
-#define WM8350_RTC_PINT_SHIFT 4
-#define WM8350_RTC_DSW 0x000F
-#define WM8350_RTC_DSW_MASK 0x000F
-#define WM8350_RTC_DSW_SHIFT 0
-
-/* Bit values for R23 (0x17) */
-#define WM8350_RTC_BCD_BINARY 0
-#define WM8350_RTC_BCD_BCD 1
-
-#define WM8350_RTC_12HR_24HR 0
-#define WM8350_RTC_12HR_12HR 1
-
-#define WM8350_RTC_DST_DISABLED 0
-#define WM8350_RTC_DST_ENABLED 1
-
-#define WM8350_RTC_SET_RUN 0
-#define WM8350_RTC_SET_SET 1
-
-#define WM8350_RTC_STS_RUNNING 0
-#define WM8350_RTC_STS_STOPPED 1
-
-#define WM8350_RTC_ALMSET_RUN 0
-#define WM8350_RTC_ALMSET_SET 1
-
-#define WM8350_RTC_ALMSTS_RUNNING 0
-#define WM8350_RTC_ALMSTS_STOPPED 1
-
-#define WM8350_RTC_PINT_DISABLED 0
-#define WM8350_RTC_PINT_SECS 1
-#define WM8350_RTC_PINT_MINS 2
-#define WM8350_RTC_PINT_HRS 3
-#define WM8350_RTC_PINT_DAYS 4
-#define WM8350_RTC_PINT_MTHS 5
-
-#define WM8350_RTC_DSW_DISABLED 0
-#define WM8350_RTC_DSW_1HZ 1
-#define WM8350_RTC_DSW_2HZ 2
-#define WM8350_RTC_DSW_4HZ 3
-#define WM8350_RTC_DSW_8HZ 4
-#define WM8350_RTC_DSW_16HZ 5
-#define WM8350_RTC_DSW_32HZ 6
-#define WM8350_RTC_DSW_64HZ 7
-#define WM8350_RTC_DSW_128HZ 8
-#define WM8350_RTC_DSW_256HZ 9
-#define WM8350_RTC_DSW_512HZ 10
-#define WM8350_RTC_DSW_1024HZ 11
-
-/*
- * R218 (0xDA) - RTC Tick Control
- */
-#define WM8350_RTC_TICKSTS 0x4000
-#define WM8350_RTC_CLKSRC 0x2000
-#define WM8350_RTC_TRIM_MASK 0x03FF
-
-/*
- * RTC Interrupts.
- */
-#define WM8350_IRQ_RTC_PER 7
-#define WM8350_IRQ_RTC_SEC 8
-#define WM8350_IRQ_RTC_ALM 9
-
-struct wm8350_rtc {
- struct platform_device *pdev;
- struct rtc_device *rtc;
- int alarm_enabled; /* used over suspend/resume */
- int update_enabled;
-};
-
-#endif
diff --git a/include/linux/mfd/wm8350/supply.h b/include/linux/mfd/wm8350/supply.h
deleted file mode 100644
index d7a91e26177c..000000000000
--- a/include/linux/mfd/wm8350/supply.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * supply.h -- Power Supply Driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_SUPPLY_H_
-#define __LINUX_MFD_WM8350_SUPPLY_H_
-
-#include <linux/mutex.h>
-#include <linux/power_supply.h>
-
-/*
- * Charger registers
- */
-#define WM8350_BATTERY_CHARGER_CONTROL_1 0xA8
-#define WM8350_BATTERY_CHARGER_CONTROL_2 0xA9
-#define WM8350_BATTERY_CHARGER_CONTROL_3 0xAA
-
-/*
- * R168 (0xA8) - Battery Charger Control 1
- */
-#define WM8350_CHG_ENA_R168 0x8000
-#define WM8350_CHG_THR 0x2000
-#define WM8350_CHG_EOC_SEL_MASK 0x1C00
-#define WM8350_CHG_TRICKLE_TEMP_CHOKE 0x0200
-#define WM8350_CHG_TRICKLE_USB_CHOKE 0x0100
-#define WM8350_CHG_RECOVER_T 0x0080
-#define WM8350_CHG_END_ACT 0x0040
-#define WM8350_CHG_FAST 0x0020
-#define WM8350_CHG_FAST_USB_THROTTLE 0x0010
-#define WM8350_CHG_NTC_MON 0x0008
-#define WM8350_CHG_BATT_HOT_MON 0x0004
-#define WM8350_CHG_BATT_COLD_MON 0x0002
-#define WM8350_CHG_CHIP_TEMP_MON 0x0001
-
-/*
- * R169 (0xA9) - Battery Charger Control 2
- */
-#define WM8350_CHG_ACTIVE 0x8000
-#define WM8350_CHG_PAUSE 0x4000
-#define WM8350_CHG_STS_MASK 0x3000
-#define WM8350_CHG_TIME_MASK 0x0F00
-#define WM8350_CHG_MASK_WALL_FB 0x0080
-#define WM8350_CHG_TRICKLE_SEL 0x0040
-#define WM8350_CHG_VSEL_MASK 0x0030
-#define WM8350_CHG_ISEL_MASK 0x000F
-#define WM8350_CHG_STS_OFF 0x0000
-#define WM8350_CHG_STS_TRICKLE 0x1000
-#define WM8350_CHG_STS_FAST 0x2000
-
-/*
- * R170 (0xAA) - Battery Charger Control 3
- */
-#define WM8350_CHG_THROTTLE_T_MASK 0x0060
-#define WM8350_CHG_SMART 0x0010
-#define WM8350_CHG_TIMER_ADJT_MASK 0x000F
-
-/*
- * Charger Interrupts
- */
-#define WM8350_IRQ_CHG_BAT_HOT 0
-#define WM8350_IRQ_CHG_BAT_COLD 1
-#define WM8350_IRQ_CHG_BAT_FAIL 2
-#define WM8350_IRQ_CHG_TO 3
-#define WM8350_IRQ_CHG_END 4
-#define WM8350_IRQ_CHG_START 5
-#define WM8350_IRQ_CHG_FAST_RDY 6
-#define WM8350_IRQ_CHG_VBATT_LT_3P9 10
-#define WM8350_IRQ_CHG_VBATT_LT_3P1 11
-#define WM8350_IRQ_CHG_VBATT_LT_2P85 12
-
-/*
- * Charger Policy
- */
-#define WM8350_CHG_TRICKLE_50mA (0 << 6)
-#define WM8350_CHG_TRICKLE_100mA (1 << 6)
-#define WM8350_CHG_4_05V (0 << 4)
-#define WM8350_CHG_4_10V (1 << 4)
-#define WM8350_CHG_4_15V (2 << 4)
-#define WM8350_CHG_4_20V (3 << 4)
-#define WM8350_CHG_FAST_LIMIT_mA(x) ((x / 50) & 0xf)
-#define WM8350_CHG_EOC_mA(x) (((x - 10) & 0x7) << 10)
-#define WM8350_CHG_TRICKLE_3_1V (0 << 13)
-#define WM8350_CHG_TRICKLE_3_9V (1 << 13)
-
-/*
- * Supply Registers.
- */
-#define WM8350_USB_VOLTAGE_READBACK 0x9C
-#define WM8350_LINE_VOLTAGE_READBACK 0x9D
-#define WM8350_BATT_VOLTAGE_READBACK 0x9E
-
-/*
- * Supply Interrupts.
- */
-#define WM8350_IRQ_USB_LIMIT 15
-#define WM8350_IRQ_EXT_USB_FB 36
-#define WM8350_IRQ_EXT_WALL_FB 37
-#define WM8350_IRQ_EXT_BAT_FB 38
-
-/*
- * Policy to control charger state machine.
- */
-struct wm8350_charger_policy {
-
- /* charger state machine policy - set in machine driver */
- int eoc_mA; /* end of charge current (mA) */
- int charge_mV; /* charge voltage */
- int fast_limit_mA; /* fast charge current limit */
- int fast_limit_USB_mA; /* USB fast charge current limit */
- int charge_timeout; /* charge timeout (mins) */
- int trickle_start_mV; /* trickle charge starts at mV */
- int trickle_charge_mA; /* trickle charge current */
- int trickle_charge_USB_mA; /* USB trickle charge current */
-};
-
-struct wm8350_power {
- struct platform_device *pdev;
- struct power_supply *battery;
- struct power_supply *usb;
- struct power_supply *ac;
- struct wm8350_charger_policy *policy;
-
- int rev_g_coeff;
-};
-
-#endif
diff --git a/include/linux/mfd/wm8350/wdt.h b/include/linux/mfd/wm8350/wdt.h
deleted file mode 100644
index 97454aa8c436..000000000000
--- a/include/linux/mfd/wm8350/wdt.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * wdt.h -- Watchdog Driver for Wolfson WM8350 PMIC
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC
- */
-
-#ifndef __LINUX_MFD_WM8350_WDT_H_
-#define __LINUX_MFD_WM8350_WDT_H_
-
-#include <linux/platform_device.h>
-
-#define WM8350_WDOG_HIB_MODE 0x0080
-#define WM8350_WDOG_DEBUG 0x0040
-#define WM8350_WDOG_MODE_MASK 0x0030
-#define WM8350_WDOG_TO_MASK 0x0007
-
-#define WM8350_IRQ_SYS_WDOG_TO 24
-
-struct wm8350_wdt {
- struct platform_device *pdev;
-};
-
-#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 422e50ee0560..ff3a6e9c26c7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -317,7 +317,6 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_WM5100
imply SND_SOC_WM5102
imply SND_SOC_WM5110
- imply SND_SOC_WM8350
imply SND_SOC_WM8510
imply SND_SOC_WM8523
imply SND_SOC_WM8524
@@ -2551,10 +2550,6 @@ config SND_SOC_WM5110
depends on MFD_WM5110 && MFD_ARIZONA
select SND_SOC_WM_ADSP
-config SND_SOC_WM8350
- tristate
- depends on MFD_WM8350
-
config SND_SOC_WM8510
tristate "Wolfson Microelectronics WM8510 CODEC"
depends on SND_SOC_I2C_AND_SPI
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 3fc78f3b44ba..633c1bf8dd32 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -374,7 +374,6 @@ snd-soc-wm2200-y := wm2200.o
snd-soc-wm5100-y := wm5100.o wm5100-tables.o
snd-soc-wm5102-y := wm5102.o
snd-soc-wm5110-y := wm5110.o
-snd-soc-wm8350-y := wm8350.o
snd-soc-wm8510-y := wm8510.o
snd-soc-wm8523-y := wm8523.o
snd-soc-wm8524-y := wm8524.o
@@ -823,7 +822,6 @@ obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
obj-$(CONFIG_SND_SOC_WM5102) += snd-soc-wm5102.o
obj-$(CONFIG_SND_SOC_WM5110) += snd-soc-wm5110.o
-obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
obj-$(CONFIG_SND_SOC_WM8524) += snd-soc-wm8524.o
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
deleted file mode 100644
index ad68ff1790e0..000000000000
--- a/sound/soc/codecs/wm8350.c
+++ /dev/null
@@ -1,1638 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * wm8350.c -- WM8350 ALSA SoC audio driver
- *
- * Copyright (C) 2007-12 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/wm8350/audio.h>
-#include <linux/mfd/wm8350/core.h>
-#include <linux/regulator/consumer.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <trace/events/asoc.h>
-
-#include "wm8350.h"
-
-#define WM8350_OUTn_0dB 0x39
-
-#define WM8350_RAMP_NONE 0
-#define WM8350_RAMP_UP 1
-#define WM8350_RAMP_DOWN 2
-
-/* We only include the analogue supplies here; the digital supplies
- * need to be available well before this driver can be probed.
- */
-static const char *supply_names[] = {
- "AVDD",
- "HPVDD",
-};
-
-struct wm8350_output {
- u16 active;
- u16 left_vol;
- u16 right_vol;
- u16 ramp;
- u16 mute;
-};
-
-struct wm8350_jack_data {
- struct snd_soc_jack *jack;
- struct delayed_work work;
- int report;
- int short_report;
-};
-
-struct wm8350_data {
- struct wm8350 *wm8350;
- struct wm8350_output out1;
- struct wm8350_output out2;
- struct wm8350_jack_data hpl;
- struct wm8350_jack_data hpr;
- struct wm8350_jack_data mic;
- struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
- int fll_freq_out;
- int fll_freq_in;
- struct delayed_work pga_work;
-};
-
-/*
- * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
- */
-static inline int wm8350_out1_ramp_step(struct wm8350_data *wm8350_data)
-{
- struct wm8350_output *out1 = &wm8350_data->out1;
- struct wm8350 *wm8350 = wm8350_data->wm8350;
- int left_complete = 0, right_complete = 0;
- u16 reg, val;
-
- /* left channel */
- reg = wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME);
- val = (reg & WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
-
- if (out1->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out1->left_vol) {
- val++;
- reg &= ~WM8350_OUT1L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else if (out1->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT1L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else
- return 1;
-
- /* right channel */
- reg = wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME);
- val = (reg & WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- if (out1->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out1->right_vol) {
- val++;
- reg &= ~WM8350_OUT1R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- } else if (out1->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT1R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- }
-
- /* only hit the update bit if either volume has changed this step */
- if (!left_complete || !right_complete)
- wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME, WM8350_OUT1_VU);
-
- return left_complete & right_complete;
-}
-
-/*
- * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
- */
-static inline int wm8350_out2_ramp_step(struct wm8350_data *wm8350_data)
-{
- struct wm8350_output *out2 = &wm8350_data->out2;
- struct wm8350 *wm8350 = wm8350_data->wm8350;
- int left_complete = 0, right_complete = 0;
- u16 reg, val;
-
- /* left channel */
- reg = wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME);
- val = (reg & WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
- if (out2->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out2->left_vol) {
- val++;
- reg &= ~WM8350_OUT2L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else if (out2->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT2L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else
- return 1;
-
- /* right channel */
- reg = wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME);
- val = (reg & WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- if (out2->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out2->right_vol) {
- val++;
- reg &= ~WM8350_OUT2R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- } else if (out2->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT2R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- }
-
- /* only hit the update bit if either volume has changed this step */
- if (!left_complete || !right_complete)
- wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME, WM8350_OUT2_VU);
-
- return left_complete & right_complete;
-}
-
-/*
- * This work ramps both output PGAs at stream start/stop time to
- * minimise pop associated with DAPM power switching.
- * It's best to enable Zero Cross when ramping occurs to minimise any
- * zipper noises.
- */
-static void wm8350_pga_work(struct work_struct *work)
-{
- struct wm8350_data *wm8350_data =
- container_of(work, struct wm8350_data, pga_work.work);
- struct wm8350_output *out1 = &wm8350_data->out1,
- *out2 = &wm8350_data->out2;
- int i, out1_complete, out2_complete;
-
- /* do we need to ramp at all ? */
- if (out1->ramp == WM8350_RAMP_NONE && out2->ramp == WM8350_RAMP_NONE)
- return;
-
- /* PGA volumes have 6 bits of resolution to ramp */
- for (i = 0; i <= 63; i++) {
- out1_complete = 1;
- out2_complete = 1;
- if (out1->ramp != WM8350_RAMP_NONE)
- out1_complete = wm8350_out1_ramp_step(wm8350_data);
- if (out2->ramp != WM8350_RAMP_NONE)
- out2_complete = wm8350_out2_ramp_step(wm8350_data);
-
- /* ramp finished ? */
- if (out1_complete && out2_complete)
- break;
-
- /* we need to delay longer on the up ramp */
- if (out1->ramp == WM8350_RAMP_UP ||
- out2->ramp == WM8350_RAMP_UP) {
- /* delay is longer over 0dB as increases are larger */
- if (i >= WM8350_OUTn_0dB)
- schedule_timeout_interruptible(msecs_to_jiffies
- (2));
- else
- schedule_timeout_interruptible(msecs_to_jiffies
- (1));
- } else
- udelay(50); /* doesn't matter if we delay longer */
- }
-
- out1->ramp = WM8350_RAMP_NONE;
- out2->ramp = WM8350_RAMP_NONE;
-}
-
-/*
- * WM8350 Controls
- */
-
-static int pga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
- struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
- struct wm8350_output *out;
-
- switch (w->shift) {
- case 0:
- case 1:
- out = &wm8350_data->out1;
- break;
- case 2:
- case 3:
- out = &wm8350_data->out2;
- break;
-
- default:
- WARN(1, "Invalid shift %d\n", w->shift);
- return -1;
- }
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- out->ramp = WM8350_RAMP_UP;
- out->active = 1;
-
- schedule_delayed_work(&wm8350_data->pga_work,
- msecs_to_jiffies(1));
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- out->ramp = WM8350_RAMP_DOWN;
- out->active = 0;
-
- schedule_delayed_work(&wm8350_data->pga_work,
- msecs_to_jiffies(1));
- break;
- }
-
- return 0;
-}
-
-static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct wm8350_data *wm8350_priv = snd_soc_component_get_drvdata(component);
- struct wm8350_output *out = NULL;
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int ret;
- unsigned int reg = mc->reg;
- u16 val;
-
- /* For OUT1 and OUT2 we shadow the values and only actually write
- * them out when active in order to ensure the amplifier comes on
- * as quietly as possible. */
- switch (reg) {
- case WM8350_LOUT1_VOLUME:
- out = &wm8350_priv->out1;
- break;
- case WM8350_LOUT2_VOLUME:
- out = &wm8350_priv->out2;
- break;
- default:
- break;
- }
-
- if (out) {
- out->left_vol = ucontrol->value.integer.value[0];
- out->right_vol = ucontrol->value.integer.value[1];
- if (!out->active)
- return 1;
- }
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- /* now hit the volume update bits (always bit 8) */
- val = snd_soc_component_read(component, reg);
- snd_soc_component_write(component, reg, val | WM8350_OUT1_VU);
- return 1;
-}
-
-static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct wm8350_data *wm8350_priv = snd_soc_component_get_drvdata(component);
- struct wm8350_output *out1 = &wm8350_priv->out1;
- struct wm8350_output *out2 = &wm8350_priv->out2;
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
-
- /* If these are cached registers use the cache */
- switch (reg) {
- case WM8350_LOUT1_VOLUME:
- ucontrol->value.integer.value[0] = out1->left_vol;
- ucontrol->value.integer.value[1] = out1->right_vol;
- return 0;
-
- case WM8350_LOUT2_VOLUME:
- ucontrol->value.integer.value[0] = out2->left_vol;
- ucontrol->value.integer.value[1] = out2->right_vol;
- return 0;
-
- default:
- break;
- }
-
- return snd_soc_get_volsw(kcontrol, ucontrol);
-}
-
-static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
-static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
-static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
-static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
-static const char *wm8350_adcfilter[] = { "None", "High Pass" };
-static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
-static const char *wm8350_lr[] = { "Left", "Right" };
-
-static const struct soc_enum wm8350_enum[] = {
- SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 4, 4, wm8350_deemp),
- SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
- SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
- SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
- SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
- SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
- SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
- SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr),
-};
-
-static DECLARE_TLV_DB_SCALE(pre_amp_tlv, -1200, 3525, 0);
-static DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 600, 0);
-static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1);
-static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1);
-static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1);
-
-static const DECLARE_TLV_DB_RANGE(capture_sd_tlv,
- 0, 12, TLV_DB_SCALE_ITEM(-3600, 300, 1),
- 13, 15, TLV_DB_SCALE_ITEM(0, 0, 0)
-);
-
-static const struct snd_kcontrol_new wm8350_snd_controls[] = {
- SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
- SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
- SOC_DOUBLE_R_EXT_TLV("Playback PCM Volume",
- WM8350_DAC_DIGITAL_VOLUME_L,
- WM8350_DAC_DIGITAL_VOLUME_R,
- 0, 255, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, dac_pcm_tlv),
- SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
- SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
- SOC_ENUM("Capture PCM Filter", wm8350_enum[4]),
- SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]),
- SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]),
- SOC_DOUBLE_R_EXT_TLV("Capture PCM Volume",
- WM8350_ADC_DIGITAL_VOLUME_L,
- WM8350_ADC_DIGITAL_VOLUME_R,
- 0, 255, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, adc_pcm_tlv),
- SOC_DOUBLE_TLV("Capture Sidetone Volume",
- WM8350_ADC_DIVIDER,
- 8, 4, 15, 1, capture_sd_tlv),
- SOC_DOUBLE_R_EXT_TLV("Capture Volume",
- WM8350_LEFT_INPUT_VOLUME,
- WM8350_RIGHT_INPUT_VOLUME,
- 2, 63, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, pre_amp_tlv),
- SOC_DOUBLE_R("Capture ZC Switch",
- WM8350_LEFT_INPUT_VOLUME,
- WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
- SOC_SINGLE_TLV("Left Input Left Sidetone Volume",
- WM8350_OUTPUT_LEFT_MIXER_VOLUME, 1, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Left Input Right Sidetone Volume",
- WM8350_OUTPUT_LEFT_MIXER_VOLUME,
- 5, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Left Input Bypass Volume",
- WM8350_OUTPUT_LEFT_MIXER_VOLUME,
- 9, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Right Input Left Sidetone Volume",
- WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
- 1, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Right Input Right Sidetone Volume",
- WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
- 5, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Right Input Bypass Volume",
- WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
- 13, 7, 0, out_mix_tlv),
- SOC_SINGLE("Left Input Mixer +20dB Switch",
- WM8350_INPUT_MIXER_VOLUME_L, 0, 1, 0),
- SOC_SINGLE("Right Input Mixer +20dB Switch",
- WM8350_INPUT_MIXER_VOLUME_R, 0, 1, 0),
- SOC_SINGLE_TLV("Out4 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME,
- 1, 7, 0, out_mix_tlv),
- SOC_DOUBLE_R_EXT_TLV("Out1 Playback Volume",
- WM8350_LOUT1_VOLUME,
- WM8350_ROUT1_VOLUME,
- 2, 63, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, out_pga_tlv),
- SOC_DOUBLE_R("Out1 Playback ZC Switch",
- WM8350_LOUT1_VOLUME,
- WM8350_ROUT1_VOLUME, 13, 1, 0),
- SOC_DOUBLE_R_EXT_TLV("Out2 Playback Volume",
- WM8350_LOUT2_VOLUME,
- WM8350_ROUT2_VOLUME,
- 2, 63, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, out_pga_tlv),
- SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
- WM8350_ROUT2_VOLUME, 13, 1, 0),
- SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
- SOC_SINGLE_TLV("Out2 Beep Volume", WM8350_BEEP_VOLUME,
- 5, 7, 0, out_mix_tlv),
-
- SOC_DOUBLE_R("Out1 Playback Switch",
- WM8350_LOUT1_VOLUME,
- WM8350_ROUT1_VOLUME,
- 14, 1, 1),
- SOC_DOUBLE_R("Out2 Playback Switch",
- WM8350_LOUT2_VOLUME,
- WM8350_ROUT2_VOLUME,
- 14, 1, 1),
-};
-
-/*
- * DAPM Controls
- */
-
-/* Left Playback Mixer */
-static const struct snd_kcontrol_new wm8350_left_play_mixer_controls[] = {
- SOC_DAPM_SINGLE("Playback Switch",
- WM8350_LEFT_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Left Bypass Switch",
- WM8350_LEFT_MIXER_CONTROL, 2, 1, 0),
- SOC_DAPM_SINGLE("Right Playback Switch",
- WM8350_LEFT_MIXER_CONTROL, 12, 1, 0),
- SOC_DAPM_SINGLE("Left Sidetone Switch",
- WM8350_LEFT_MIXER_CONTROL, 0, 1, 0),
- SOC_DAPM_SINGLE("Right Sidetone Switch",
- WM8350_LEFT_MIXER_CONTROL, 1, 1, 0),
-};
-
-/* Right Playback Mixer */
-static const struct snd_kcontrol_new wm8350_right_play_mixer_controls[] = {
- SOC_DAPM_SINGLE("Playback Switch",
- WM8350_RIGHT_MIXER_CONTROL, 12, 1, 0),
- SOC_DAPM_SINGLE("Right Bypass Switch",
- WM8350_RIGHT_MIXER_CONTROL, 3, 1, 0),
- SOC_DAPM_SINGLE("Left Playback Switch",
- WM8350_RIGHT_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Left Sidetone Switch",
- WM8350_RIGHT_MIXER_CONTROL, 0, 1, 0),
- SOC_DAPM_SINGLE("Right Sidetone Switch",
- WM8350_RIGHT_MIXER_CONTROL, 1, 1, 0),
-};
-
-/* Out4 Mixer */
-static const struct snd_kcontrol_new wm8350_out4_mixer_controls[] = {
- SOC_DAPM_SINGLE("Right Playback Switch",
- WM8350_OUT4_MIXER_CONTROL, 12, 1, 0),
- SOC_DAPM_SINGLE("Left Playback Switch",
- WM8350_OUT4_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Right Capture Switch",
- WM8350_OUT4_MIXER_CONTROL, 9, 1, 0),
- SOC_DAPM_SINGLE("Out3 Playback Switch",
- WM8350_OUT4_MIXER_CONTROL, 2, 1, 0),
- SOC_DAPM_SINGLE("Right Mixer Switch",
- WM8350_OUT4_MIXER_CONTROL, 1, 1, 0),
- SOC_DAPM_SINGLE("Left Mixer Switch",
- WM8350_OUT4_MIXER_CONTROL, 0, 1, 0),
-};
-
-/* Out3 Mixer */
-static const struct snd_kcontrol_new wm8350_out3_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left Playback Switch",
- WM8350_OUT3_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Left Capture Switch",
- WM8350_OUT3_MIXER_CONTROL, 8, 1, 0),
- SOC_DAPM_SINGLE("Out4 Playback Switch",
- WM8350_OUT3_MIXER_CONTROL, 3, 1, 0),
- SOC_DAPM_SINGLE("Left Mixer Switch",
- WM8350_OUT3_MIXER_CONTROL, 0, 1, 0),
-};
-
-/* Left Input Mixer */
-static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
- SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_L, 1, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_LEFT_INPUT_VOLUME, 14, 1, 1),
-};
-
-/* Right Input Mixer */
-static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
- SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_R, 5, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_RIGHT_INPUT_VOLUME, 14, 1, 1),
-};
-
-/* Left Mic Mixer */
-static const struct snd_kcontrol_new wm8350_left_mic_mixer_controls[] = {
- SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 1, 1, 0),
- SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 0, 1, 0),
- SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 2, 1, 0),
-};
-
-/* Right Mic Mixer */
-static const struct snd_kcontrol_new wm8350_right_mic_mixer_controls[] = {
- SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 9, 1, 0),
- SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 8, 1, 0),
- SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 10, 1, 0),
-};
-
-/* Beep Switch */
-static const struct snd_kcontrol_new wm8350_beep_switch_controls =
-SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
-
-/* Out4 Capture Mux */
-static const struct snd_kcontrol_new wm8350_out4_capture_controls =
-SOC_DAPM_ENUM("Route", wm8350_enum[7]);
-
-static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
-
- SND_SOC_DAPM_PGA("IN3R PGA", WM8350_POWER_MGMT_2, 11, 0, NULL, 0),
- SND_SOC_DAPM_PGA("IN3L PGA", WM8350_POWER_MGMT_2, 10, 0, NULL, 0),
- SND_SOC_DAPM_PGA_E("Right Out2 PGA", WM8350_POWER_MGMT_3, 3, 0, NULL,
- 0, pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("Left Out2 PGA", WM8350_POWER_MGMT_3, 2, 0, NULL, 0,
- pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("Right Out1 PGA", WM8350_POWER_MGMT_3, 1, 0, NULL,
- 0, pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("Left Out1 PGA", WM8350_POWER_MGMT_3, 0, 0, NULL, 0,
- pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_MIXER("Right Capture Mixer", WM8350_POWER_MGMT_2,
- 7, 0, &wm8350_right_capt_mixer_controls[0],
- ARRAY_SIZE(wm8350_right_capt_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Capture Mixer", WM8350_POWER_MGMT_2,
- 6, 0, &wm8350_left_capt_mixer_controls[0],
- ARRAY_SIZE(wm8350_left_capt_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Out4 Mixer", WM8350_POWER_MGMT_2, 5, 0,
- &wm8350_out4_mixer_controls[0],
- ARRAY_SIZE(wm8350_out4_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Out3 Mixer", WM8350_POWER_MGMT_2, 4, 0,
- &wm8350_out3_mixer_controls[0],
- ARRAY_SIZE(wm8350_out3_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right Playback Mixer", WM8350_POWER_MGMT_2, 1, 0,
- &wm8350_right_play_mixer_controls[0],
- ARRAY_SIZE(wm8350_right_play_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Playback Mixer", WM8350_POWER_MGMT_2, 0, 0,
- &wm8350_left_play_mixer_controls[0],
- ARRAY_SIZE(wm8350_left_play_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Mic Mixer", WM8350_POWER_MGMT_2, 8, 0,
- &wm8350_left_mic_mixer_controls[0],
- ARRAY_SIZE(wm8350_left_mic_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right Mic Mixer", WM8350_POWER_MGMT_2, 9, 0,
- &wm8350_right_mic_mixer_controls[0],
- ARRAY_SIZE(wm8350_right_mic_mixer_controls)),
-
- /* virtual mixer for Beep and Out2R */
- SND_SOC_DAPM_MIXER("Out2 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_SWITCH("Beep", WM8350_POWER_MGMT_3, 7, 0,
- &wm8350_beep_switch_controls),
-
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
- WM8350_POWER_MGMT_4, 3, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture",
- WM8350_POWER_MGMT_4, 2, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback",
- WM8350_POWER_MGMT_4, 5, 0),
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback",
- WM8350_POWER_MGMT_4, 4, 0),
-
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8350_POWER_MGMT_1, 4, 0),
-
- SND_SOC_DAPM_MUX("Out4 Capture Channel", SND_SOC_NOPM, 0, 0,
- &wm8350_out4_capture_controls),
-
- SND_SOC_DAPM_OUTPUT("OUT1R"),
- SND_SOC_DAPM_OUTPUT("OUT1L"),
- SND_SOC_DAPM_OUTPUT("OUT2R"),
- SND_SOC_DAPM_OUTPUT("OUT2L"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_OUTPUT("OUT4"),
-
- SND_SOC_DAPM_INPUT("IN1RN"),
- SND_SOC_DAPM_INPUT("IN1RP"),
- SND_SOC_DAPM_INPUT("IN2R"),
- SND_SOC_DAPM_INPUT("IN1LP"),
- SND_SOC_DAPM_INPUT("IN1LN"),
- SND_SOC_DAPM_INPUT("IN2L"),
- SND_SOC_DAPM_INPUT("IN3R"),
- SND_SOC_DAPM_INPUT("IN3L"),
-};
-
-static const struct snd_soc_dapm_route wm8350_dapm_routes[] = {
-
- /* left playback mixer */
- {"Left Playback Mixer", "Playback Switch", "Left DAC"},
- {"Left Playback Mixer", "Left Bypass Switch", "IN3L PGA"},
- {"Left Playback Mixer", "Right Playback Switch", "Right DAC"},
- {"Left Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
- {"Left Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
-
- /* right playback mixer */
- {"Right Playback Mixer", "Playback Switch", "Right DAC"},
- {"Right Playback Mixer", "Right Bypass Switch", "IN3R PGA"},
- {"Right Playback Mixer", "Left Playback Switch", "Left DAC"},
- {"Right Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
- {"Right Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
-
- /* out4 playback mixer */
- {"Out4 Mixer", "Right Playback Switch", "Right DAC"},
- {"Out4 Mixer", "Left Playback Switch", "Left DAC"},
- {"Out4 Mixer", "Right Capture Switch", "Right Capture Mixer"},
- {"Out4 Mixer", "Out3 Playback Switch", "Out3 Mixer"},
- {"Out4 Mixer", "Right Mixer Switch", "Right Playback Mixer"},
- {"Out4 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
- {"OUT4", NULL, "Out4 Mixer"},
-
- /* out3 playback mixer */
- {"Out3 Mixer", "Left Playback Switch", "Left DAC"},
- {"Out3 Mixer", "Left Capture Switch", "Left Capture Mixer"},
- {"Out3 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
- {"Out3 Mixer", "Out4 Playback Switch", "Out4 Mixer"},
- {"OUT3", NULL, "Out3 Mixer"},
-
- /* out2 */
- {"Right Out2 PGA", NULL, "Right Playback Mixer"},
- {"Left Out2 PGA", NULL, "Left Playback Mixer"},
- {"OUT2L", NULL, "Left Out2 PGA"},
- {"OUT2R", NULL, "Right Out2 PGA"},
-
- /* out1 */
- {"Right Out1 PGA", NULL, "Right Playback Mixer"},
- {"Left Out1 PGA", NULL, "Left Playback Mixer"},
- {"OUT1L", NULL, "Left Out1 PGA"},
- {"OUT1R", NULL, "Right Out1 PGA"},
-
- /* ADCs */
- {"Left ADC", NULL, "Left Capture Mixer"},
- {"Right ADC", NULL, "Right Capture Mixer"},
-
- /* Left capture mixer */
- {"Left Capture Mixer", "L2 Capture Volume", "IN2L"},
- {"Left Capture Mixer", "L3 Capture Volume", "IN3L PGA"},
- {"Left Capture Mixer", "PGA Capture Switch", "Left Mic Mixer"},
- {"Left Capture Mixer", NULL, "Out4 Capture Channel"},
-
- /* Right capture mixer */
- {"Right Capture Mixer", "L2 Capture Volume", "IN2R"},
- {"Right Capture Mixer", "L3 Capture Volume", "IN3R PGA"},
- {"Right Capture Mixer", "PGA Capture Switch", "Right Mic Mixer"},
- {"Right Capture Mixer", NULL, "Out4 Capture Channel"},
-
- /* L3 Inputs */
- {"IN3L PGA", NULL, "IN3L"},
- {"IN3R PGA", NULL, "IN3R"},
-
- /* Left Mic mixer */
- {"Left Mic Mixer", "INN Capture Switch", "IN1LN"},
- {"Left Mic Mixer", "INP Capture Switch", "IN1LP"},
- {"Left Mic Mixer", "IN2 Capture Switch", "IN2L"},
-
- /* Right Mic mixer */
- {"Right Mic Mixer", "INN Capture Switch", "IN1RN"},
- {"Right Mic Mixer", "INP Capture Switch", "IN1RP"},
- {"Right Mic Mixer", "IN2 Capture Switch", "IN2R"},
-
- /* out 4 capture */
- {"Out4 Capture Channel", NULL, "Out4 Mixer"},
-
- /* Beep */
- {"Beep", NULL, "IN3R PGA"},
-};
-
-static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_component *component = codec_dai->component;
- struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
- struct wm8350 *wm8350 = wm8350_data->wm8350;
- u16 fll_4;
-
- switch (clk_id) {
- case WM8350_MCLK_SEL_MCLK:
- wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_1,
- WM8350_MCLK_SEL);
- break;
- case WM8350_MCLK_SEL_PLL_MCLK:
- case WM8350_MCLK_SEL_PLL_DAC:
- case WM8350_MCLK_SEL_PLL_ADC:
- case WM8350_MCLK_SEL_PLL_32K:
- wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
- WM8350_MCLK_SEL);
- fll_4 = snd_soc_component_read(component, WM8350_FLL_CONTROL_4) &
- ~WM8350_FLL_CLK_SRC_MASK;
- snd_soc_component_write(component, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
- break;
- }
-
- /* MCLK direction */
- if (dir == SND_SOC_CLOCK_OUT)
- wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
- WM8350_MCLK_DIR);
- else
- wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
- WM8350_MCLK_DIR);
-
- return 0;
-}
-
-static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
-{
- struct snd_soc_component *component = codec_dai->component;
- u16 val;
-
- switch (div_id) {
- case WM8350_ADC_CLKDIV:
- val = snd_soc_component_read(component, WM8350_ADC_DIVIDER) &
- ~WM8350_ADC_CLKDIV_MASK;
- snd_soc_component_write(component, WM8350_ADC_DIVIDER, val | div);
- break;
- case WM8350_DAC_CLKDIV:
- val = snd_soc_component_read(component, WM8350_DAC_CLOCK_CONTROL) &
- ~WM8350_DAC_CLKDIV_MASK;
- snd_soc_component_write(component, WM8350_DAC_CLOCK_CONTROL, val | div);
- break;
- case WM8350_BCLK_CLKDIV:
- val = snd_soc_component_read(component, WM8350_CLOCK_CONTROL_1) &
- ~WM8350_BCLK_DIV_MASK;
- snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
- break;
- case WM8350_OPCLK_CLKDIV:
- val = snd_soc_component_read(component, WM8350_CLOCK_CONTROL_1) &
- ~WM8350_OPCLK_DIV_MASK;
- snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
- break;
- case WM8350_SYS_CLKDIV:
- val = snd_soc_component_read(component, WM8350_CLOCK_CONTROL_1) &
- ~WM8350_MCLK_DIV_MASK;
- snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
- break;
- case WM8350_DACLR_CLKDIV:
- val = snd_soc_component_read(component, WM8350_DAC_LR_RATE) &
- ~WM8350_DACLRC_RATE_MASK;
- snd_soc_component_write(component, WM8350_DAC_LR_RATE, val | div);
- break;
- case WM8350_ADCLR_CLKDIV:
- val = snd_soc_component_read(component, WM8350_ADC_LR_RATE) &
- ~WM8350_ADCLRC_RATE_MASK;
- snd_soc_component_write(component, WM8350_ADC_LR_RATE, val | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_component *component = codec_dai->component;
- u16 iface = snd_soc_component_read(component, WM8350_AI_FORMATING) &
- ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
- u16 master = snd_soc_component_read(component, WM8350_AI_DAC_CONTROL) &
- ~WM8350_BCLK_MSTR;
- u16 dac_lrc = snd_soc_component_read(component, WM8350_DAC_LR_RATE) &
- ~WM8350_DACLRC_ENA;
- u16 adc_lrc = snd_soc_component_read(component, WM8350_ADC_LR_RATE) &
- ~WM8350_ADCLRC_ENA;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBP_CFP:
- master |= WM8350_BCLK_MSTR;
- dac_lrc |= WM8350_DACLRC_ENA;
- adc_lrc |= WM8350_ADCLRC_ENA;
- break;
- case SND_SOC_DAIFMT_CBC_CFC:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x2 << 8;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x1 << 8;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x3 << 8;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= WM8350_AIF_LRCLK_INV | WM8350_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= WM8350_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= WM8350_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_component_write(component, WM8350_AI_FORMATING, iface);
- snd_soc_component_write(component, WM8350_AI_DAC_CONTROL, master);
- snd_soc_component_write(component, WM8350_DAC_LR_RATE, dac_lrc);
- snd_soc_component_write(component, WM8350_ADC_LR_RATE, adc_lrc);
- return 0;
-}
-
-static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *codec_dai)
-{
- struct snd_soc_component *component = codec_dai->component;
- struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
- struct wm8350 *wm8350 = wm8350_data->wm8350;
- u16 iface = snd_soc_component_read(component, WM8350_AI_FORMATING) &
- ~WM8350_AIF_WL_MASK;
-
- /* bit size */
- switch (params_width(params)) {
- case 16:
- break;
- case 20:
- iface |= 0x1 << 10;
- break;
- case 24:
- iface |= 0x2 << 10;
- break;
- case 32:
- iface |= 0x3 << 10;
- break;
- }
-
- snd_soc_component_write(component, WM8350_AI_FORMATING, iface);
-
- /* The sloping stopband filter is recommended for use with
- * lower sample rates to improve performance.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (params_rate(params) < 24000)
- wm8350_set_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
- WM8350_DAC_SB_FILT);
- else
- wm8350_clear_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
- WM8350_DAC_SB_FILT);
- }
-
- return 0;
-}
-
-static int wm8350_mute(struct snd_soc_dai *dai, int mute, int direction)
-{
- struct snd_soc_component *component = dai->component;
- unsigned int val;
-
- if (mute)
- val = WM8350_DAC_MUTE_ENA;
- else
- val = 0;
-
- snd_soc_component_update_bits(component, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA, val);
-
- return 0;
-}
-
-/* FLL divisors */
-struct _fll_div {
- int div; /* FLL_OUTDIV */
- int n;
- int k;
- int ratio; /* FLL_FRATIO */
-};
-
-/* The size in bits of the fll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
- unsigned int output)
-{
- u64 Kpart;
- unsigned int t1, t2, K, Nmod;
-
- if (output >= 2815250 && output <= 3125000)
- fll_div->div = 0x4;
- else if (output >= 5625000 && output <= 6250000)
- fll_div->div = 0x3;
- else if (output >= 11250000 && output <= 12500000)
- fll_div->div = 0x2;
- else if (output >= 22500000 && output <= 25000000)
- fll_div->div = 0x1;
- else {
- printk(KERN_ERR "wm8350: fll freq %d out of range\n", output);
- return -EINVAL;
- }
-
- if (input > 48000)
- fll_div->ratio = 1;
- else
- fll_div->ratio = 8;
-
- t1 = output * (1 << (fll_div->div + 1));
- t2 = input * fll_div->ratio;
-
- fll_div->n = t1 / t2;
- Nmod = t1 % t2;
-
- if (Nmod) {
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
- do_div(Kpart, t2);
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
- fll_div->k = K;
- } else
- fll_div->k = 0;
-
- return 0;
-}
-
-static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
- int pll_id, int source, unsigned int freq_in,
- unsigned int freq_out)
-{
- struct snd_soc_component *component = codec_dai->component;
- struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
- struct wm8350 *wm8350 = priv->wm8350;
- struct _fll_div fll_div;
- int ret = 0;
- u16 fll_1, fll_4;
-
- if (freq_in == priv->fll_freq_in && freq_out == priv->fll_freq_out)
- return 0;
-
- /* power down FLL - we need to do this for reconfiguration */
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
- WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
-
- if (freq_out == 0 || freq_in == 0)
- return ret;
-
- ret = fll_factors(&fll_div, freq_in, freq_out);
- if (ret < 0)
- return ret;
- dev_dbg(wm8350->dev,
- "FLL in %u FLL out %u N 0x%x K 0x%x div %d ratio %d",
- freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
- fll_div.ratio);
-
- /* set up N.K & dividers */
- fll_1 = snd_soc_component_read(component, WM8350_FLL_CONTROL_1) &
- ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
- snd_soc_component_write(component, WM8350_FLL_CONTROL_1,
- fll_1 | (fll_div.div << 8) | 0x50);
- snd_soc_component_write(component, WM8350_FLL_CONTROL_2,
- (fll_div.ratio << 11) | (fll_div.
- n & WM8350_FLL_N_MASK));
- snd_soc_component_write(component, WM8350_FLL_CONTROL_3, fll_div.k);
- fll_4 = snd_soc_component_read(component, WM8350_FLL_CONTROL_4) &
- ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
- snd_soc_component_write(component, WM8350_FLL_CONTROL_4,
- fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
- (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
-
- /* power FLL on */
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
-
- priv->fll_freq_out = freq_out;
- priv->fll_freq_in = freq_in;
-
- return 0;
-}
-
-static int wm8350_set_bias_level(struct snd_soc_component *component,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
- struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
- struct wm8350 *wm8350 = priv->wm8350;
- struct wm8350_audio_platform_data *platform =
- wm8350->codec.platform_data;
- u16 pm1;
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_VMID_50K |
- platform->codec_current_on << 14);
- break;
-
- case SND_SOC_BIAS_PREPARE:
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1);
- pm1 &= ~WM8350_VMID_MASK;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_VMID_50K);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
- priv->supplies);
- if (ret != 0)
- return ret;
-
- /* Enable the system clock */
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4,
- WM8350_SYSCLK_ENA);
-
- /* mute DAC & outputs */
- wm8350_set_bits(wm8350, WM8350_DAC_MUTE,
- WM8350_DAC_MUTE_ENA);
-
- /* discharge cap memory */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- platform->dis_out1 |
- (platform->dis_out2 << 2) |
- (platform->dis_out3 << 4) |
- (platform->dis_out4 << 6));
-
- /* wait for discharge */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->
- cap_discharge_msecs));
-
- /* enable antipop */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- (platform->vmid_s_curve << 8));
-
- /* ramp up vmid */
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- (platform->
- codec_current_charge << 14) |
- WM8350_VMID_5K | WM8350_VMIDEN |
- WM8350_VBUFEN);
-
- /* wait for vmid */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->
- vmid_charge_msecs));
-
- /* turn on vmid 300k */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
- pm1 |= WM8350_VMID_300K |
- (platform->codec_current_standby << 14);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1);
-
-
- /* enable analogue bias */
- pm1 |= WM8350_BIASEN;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
-
- /* disable antipop */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
-
- } else {
- /* turn on vmid 300k and reduce current */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_VMID_300K |
- (platform->
- codec_current_standby << 14));
-
- }
- break;
-
- case SND_SOC_BIAS_OFF:
-
- /* mute DAC & enable outputs */
- wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
-
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_3,
- WM8350_OUT1L_ENA | WM8350_OUT1R_ENA |
- WM8350_OUT2L_ENA | WM8350_OUT2R_ENA);
-
- /* enable anti pop S curve */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- (platform->vmid_s_curve << 8));
-
- /* turn off vmid */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~WM8350_VMIDEN;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
-
- /* wait */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->
- vmid_discharge_msecs));
-
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- (platform->vmid_s_curve << 8) |
- platform->dis_out1 |
- (platform->dis_out2 << 2) |
- (platform->dis_out3 << 4) |
- (platform->dis_out4 << 6));
-
- /* turn off VBuf and drain */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VBUFEN | WM8350_VMID_MASK);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_OUTPUT_DRAIN_EN);
-
- /* wait */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->drain_msecs));
-
- pm1 &= ~WM8350_BIASEN;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
-
- /* disable anti-pop */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
-
- wm8350_clear_bits(wm8350, WM8350_LOUT1_VOLUME,
- WM8350_OUT1L_ENA);
- wm8350_clear_bits(wm8350, WM8350_ROUT1_VOLUME,
- WM8350_OUT1R_ENA);
- wm8350_clear_bits(wm8350, WM8350_LOUT2_VOLUME,
- WM8350_OUT2L_ENA);
- wm8350_clear_bits(wm8350, WM8350_ROUT2_VOLUME,
- WM8350_OUT2R_ENA);
-
- /* disable clock gen */
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
- WM8350_SYSCLK_ENA);
-
- regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
- priv->supplies);
- break;
- }
- return 0;
-}
-
-static void wm8350_hp_work(struct wm8350_data *priv,
- struct wm8350_jack_data *jack,
- u16 mask)
-{
- struct wm8350 *wm8350 = priv->wm8350;
- u16 reg;
- int report;
-
- reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
- if (reg & mask)
- report = jack->report;
- else
- report = 0;
-
- snd_soc_jack_report(jack->jack, report, jack->report);
-
-}
-
-static void wm8350_hpl_work(struct work_struct *work)
-{
- struct wm8350_data *priv =
- container_of(work, struct wm8350_data, hpl.work.work);
-
- wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL);
-}
-
-static void wm8350_hpr_work(struct work_struct *work)
-{
- struct wm8350_data *priv =
- container_of(work, struct wm8350_data, hpr.work.work);
-
- wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL);
-}
-
-static irqreturn_t wm8350_hpl_jack_handler(int irq, void *data)
-{
- struct wm8350_data *priv = data;
- struct wm8350 *wm8350 = priv->wm8350;
-
-#ifndef CONFIG_SND_SOC_WM8350_MODULE
- trace_snd_soc_jack_irq("WM8350 HPL");
-#endif
-
- if (device_may_wakeup(wm8350->dev))
- pm_wakeup_event(wm8350->dev, 250);
-
- queue_delayed_work(system_power_efficient_wq,
- &priv->hpl.work, msecs_to_jiffies(200));
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
-{
- struct wm8350_data *priv = data;
- struct wm8350 *wm8350 = priv->wm8350;
-
-#ifndef CONFIG_SND_SOC_WM8350_MODULE
- trace_snd_soc_jack_irq("WM8350 HPR");
-#endif
-
- if (device_may_wakeup(wm8350->dev))
- pm_wakeup_event(wm8350->dev, 250);
-
- queue_delayed_work(system_power_efficient_wq,
- &priv->hpr.work, msecs_to_jiffies(200));
-
- return IRQ_HANDLED;
-}
-
-/**
- * wm8350_hp_jack_detect - Enable headphone jack detection.
- *
- * @component: WM8350 component
- * @which: left or right jack detect signal
- * @jack: jack to report detection events on
- * @report: value to report
- *
- * Enables the headphone jack detection of the WM8350. If no report
- * is specified then detection is disabled.
- */
-int wm8350_hp_jack_detect(struct snd_soc_component *component, enum wm8350_jack which,
- struct snd_soc_jack *jack, int report)
-{
- struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
- struct wm8350 *wm8350 = priv->wm8350;
- int ena;
-
- switch (which) {
- case WM8350_JDL:
- priv->hpl.jack = jack;
- priv->hpl.report = report;
- ena = WM8350_JDL_ENA;
- break;
-
- case WM8350_JDR:
- priv->hpr.jack = jack;
- priv->hpr.report = report;
- ena = WM8350_JDR_ENA;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (report) {
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
- wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
- } else {
- wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, ena);
- }
-
- /* Sync status */
- switch (which) {
- case WM8350_JDL:
- wm8350_hpl_jack_handler(0, priv);
- break;
- case WM8350_JDR:
- wm8350_hpr_jack_handler(0, priv);
- break;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect);
-
-static irqreturn_t wm8350_mic_handler(int irq, void *data)
-{
- struct wm8350_data *priv = data;
- struct wm8350 *wm8350 = priv->wm8350;
- u16 reg;
- int report = 0;
-
-#ifndef CONFIG_SND_SOC_WM8350_MODULE
- trace_snd_soc_jack_irq("WM8350 mic");
-#endif
-
- reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
- if (reg & WM8350_JACK_MICSCD_LVL)
- report |= priv->mic.short_report;
- if (reg & WM8350_JACK_MICSD_LVL)
- report |= priv->mic.report;
-
- snd_soc_jack_report(priv->mic.jack, report,
- priv->mic.report | priv->mic.short_report);
-
- return IRQ_HANDLED;
-}
-
-/**
- * wm8350_mic_jack_detect - Enable microphone jack detection.
- *
- * @component: WM8350 component
- * @jack: jack to report detection events on
- * @detect_report: value to report when presence detected
- * @short_report: value to report when microphone short detected
- *
- * Enables the microphone jack detection of the WM8350. If both reports
- * are specified as zero then detection is disabled.
- */
-int wm8350_mic_jack_detect(struct snd_soc_component *component,
- struct snd_soc_jack *jack,
- int detect_report, int short_report)
-{
- struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
- struct wm8350 *wm8350 = priv->wm8350;
-
- priv->mic.jack = jack;
- priv->mic.report = detect_report;
- priv->mic.short_report = short_report;
-
- if (detect_report || short_report) {
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_1,
- WM8350_MIC_DET_ENA);
- } else {
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_1,
- WM8350_MIC_DET_ENA);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
-
-#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
-
-#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8350_dai_ops = {
- .hw_params = wm8350_pcm_hw_params,
- .mute_stream = wm8350_mute,
- .set_fmt = wm8350_set_dai_fmt,
- .set_sysclk = wm8350_set_dai_sysclk,
- .set_pll = wm8350_set_fll,
- .set_clkdiv = wm8350_set_clkdiv,
- .no_capture_mute = 1,
-};
-
-static struct snd_soc_dai_driver wm8350_dai = {
- .name = "wm8350-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8350_RATES,
- .formats = WM8350_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8350_RATES,
- .formats = WM8350_FORMATS,
- },
- .ops = &wm8350_dai_ops,
-};
-
-static int wm8350_component_probe(struct snd_soc_component *component)
-{
- struct wm8350 *wm8350 = dev_get_platdata(component->dev);
- struct wm8350_data *priv;
- struct wm8350_output *out1;
- struct wm8350_output *out2;
- int ret, i;
-
- if (wm8350->codec.platform_data == NULL) {
- dev_err(component->dev, "No audio platform data supplied\n");
- return -EINVAL;
- }
-
- priv = devm_kzalloc(component->dev, sizeof(struct wm8350_data),
- GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
-
- snd_soc_component_init_regmap(component, wm8350->regmap);
- snd_soc_component_set_drvdata(component, priv);
-
- priv->wm8350 = wm8350;
-
- for (i = 0; i < ARRAY_SIZE(supply_names); i++)
- priv->supplies[i].supply = supply_names[i];
-
- ret = devm_regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
- priv->supplies);
- if (ret != 0)
- return ret;
-
- /* Put the codec into reset if it wasn't already */
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
- INIT_DELAYED_WORK(&priv->pga_work, wm8350_pga_work);
- INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
- INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
-
- /* Enable the codec */
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
- /* Enable robust clocking mode in ADC */
- snd_soc_component_write(component, WM8350_SECURITY, 0xa7);
- snd_soc_component_write(component, 0xde, 0x13);
- snd_soc_component_write(component, WM8350_SECURITY, 0);
-
- /* read OUT1 & OUT2 volumes */
- out1 = &priv->out1;
- out2 = &priv->out2;
- out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) &
- WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
- out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) &
- WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) &
- WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
- out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) &
- WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME, 0);
- wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME, 0);
- wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME, 0);
- wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME, 0);
-
- /* Latch VU bits & mute */
- wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME,
- WM8350_OUT1_VU | WM8350_OUT1L_MUTE);
- wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME,
- WM8350_OUT2_VU | WM8350_OUT2L_MUTE);
- wm8350_set_bits(wm8350, WM8350_ROUT1_VOLUME,
- WM8350_OUT1_VU | WM8350_OUT1R_MUTE);
- wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
- WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
-
- /* Make sure AIF tristating is disabled by default */
- wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
-
- /* Make sure we've got a sane companding setup too */
- wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
- WM8350_DAC_COMP | WM8350_LOOPBACK);
-
- /* Make sure jack detect is disabled to start off with */
- wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
- WM8350_JDL_ENA | WM8350_JDR_ENA);
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L,
- wm8350_hpl_jack_handler, 0, "Left jack detect",
- priv);
- if (ret != 0)
- goto err;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
- wm8350_hpr_jack_handler, 0, "Right jack detect",
- priv);
- if (ret != 0)
- goto free_jck_det_l;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD,
- wm8350_mic_handler, 0, "Microphone short", priv);
- if (ret != 0)
- goto free_jck_det_r;
-
- ret = wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
- wm8350_mic_handler, 0, "Microphone detect", priv);
- if (ret != 0)
- goto free_micscd;
-
- return 0;
-
-free_micscd:
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv);
-free_jck_det_r:
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
-free_jck_det_l:
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
-err:
- return ret;
-}
-
-static void wm8350_component_remove(struct snd_soc_component *component)
-{
- struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
- struct wm8350 *wm8350 = dev_get_platdata(component->dev);
-
- wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
- WM8350_JDL_ENA | WM8350_JDR_ENA);
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
-
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICD, priv);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
-
- priv->hpl.jack = NULL;
- priv->hpr.jack = NULL;
- priv->mic.jack = NULL;
-
- cancel_delayed_work_sync(&priv->hpl.work);
- cancel_delayed_work_sync(&priv->hpr.work);
-
- /* if there was any work waiting then we run it now and
- * wait for its completion */
- flush_delayed_work(&priv->pga_work);
-
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-}
-
-static const struct snd_soc_component_driver soc_component_dev_wm8350 = {
- .probe = wm8350_component_probe,
- .remove = wm8350_component_remove,
- .set_bias_level = wm8350_set_bias_level,
- .controls = wm8350_snd_controls,
- .num_controls = ARRAY_SIZE(wm8350_snd_controls),
- .dapm_widgets = wm8350_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets),
- .dapm_routes = wm8350_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes),
- .suspend_bias_off = 1,
- .idle_bias_on = 1,
- .use_pmdown_time = 1,
- .endianness = 1,
-};
-
-static int wm8350_probe(struct platform_device *pdev)
-{
- return devm_snd_soc_register_component(&pdev->dev,
- &soc_component_dev_wm8350,
- &wm8350_dai, 1);
-}
-
-static struct platform_driver wm8350_codec_driver = {
- .driver = {
- .name = "wm8350-codec",
- },
- .probe = wm8350_probe,
-};
-
-module_platform_driver(wm8350_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM8350 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-codec");
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
deleted file mode 100644
index a13d18c92d4b..000000000000
--- a/sound/soc/codecs/wm8350.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * wm8350.h - WM8903 audio codec interface
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- */
-
-#ifndef _WM8350_H
-#define _WM8350_H
-
-#include <sound/soc.h>
-#include <linux/mfd/wm8350/audio.h>
-
-enum wm8350_jack {
- WM8350_JDL = 1,
- WM8350_JDR = 2,
-};
-
-int wm8350_hp_jack_detect(struct snd_soc_component *component, enum wm8350_jack which,
- struct snd_soc_jack *jack, int report);
-int wm8350_mic_jack_detect(struct snd_soc_component *component,
- struct snd_soc_jack *jack,
- int detect_report, int short_report);
-
-#endif
--
2.53.0
^ permalink raw reply [flat|nested] 31+ 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
` (10 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 11/14] mfd: remove unused wm8350 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
` (3 subsequent siblings)
15 siblings, 0 replies; 31+ 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 [flat|nested] 31+ 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
` (11 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:21 ` [PATCH 14/14] mfd: remove unused iPaq micro driver Arnd Bergmann
` (2 subsequent siblings)
15 siblings, 0 replies; 31+ 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 [flat|nested] 31+ 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
` (12 preceding siblings ...)
2026-09-09 13:21 ` [PATCH 13/14] mfd: remove unused menelaus driver Arnd Bergmann
@ 2026-09-09 13:21 ` Arnd Bergmann
2026-09-09 14:03 ` [PATCH 00/14] mfd: unused driver purge Bartosz Golaszewski
2026-09-09 17:26 ` Dmitry Torokhov
15 siblings, 0 replies; 31+ 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 [flat|nested] 31+ messages in thread
* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
2026-09-09 13:21 ` [PATCH 11/14] mfd: remove unused wm8350 driver Arnd Bergmann
@ 2026-09-09 13:26 ` Mark Brown
2026-09-09 14:12 ` Guenter Roeck
` (2 subsequent siblings)
3 siblings, 0 replies; 31+ 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] 31+ messages in thread
* Re: [PATCH 04/14] mfd: remove unused wm8400 driver
2026-09-09 13:21 ` [PATCH 04/14] mfd: remove unused wm8400 driver Arnd Bergmann
@ 2026-09-09 13:27 ` Mark Brown
2026-09-09 14:38 ` Charles Keepax
1 sibling, 0 replies; 31+ 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] 31+ 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-09 13:44 ` Alexandre Belloni
2026-09-11 7:24 ` Krzysztof Kozlowski
1 sibling, 0 replies; 31+ messages in thread
From: Alexandre Belloni @ 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,
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:38+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>
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] 31+ 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; 31+ 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] 31+ 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 13:47 ` Alexandre Belloni
2026-09-09 15:46 ` Sebastian Reichel
1 sibling, 0 replies; 31+ messages in thread
From: Alexandre Belloni @ 2026-09-09 13: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, 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:44+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>
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] 31+ 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 13:21 ` [PATCH 14/14] mfd: remove unused iPaq micro driver Arnd Bergmann
@ 2026-09-09 14:03 ` Bartosz Golaszewski
2026-09-09 17:26 ` Dmitry Torokhov
15 siblings, 0 replies; 31+ 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] 31+ 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; 31+ 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] 31+ messages in thread
* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
2026-09-09 13:21 ` [PATCH 11/14] mfd: remove unused wm8350 driver Arnd Bergmann
2026-09-09 13:26 ` 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; 31+ 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] 31+ messages in thread
* Re: [PATCH 04/14] mfd: remove unused wm8400 driver
2026-09-09 13:21 ` [PATCH 04/14] mfd: remove unused wm8400 driver Arnd Bergmann
2026-09-09 13:27 ` Mark Brown
@ 2026-09-09 14:38 ` Charles Keepax
1 sibling, 0 replies; 31+ 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] 31+ messages in thread
* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
2026-09-09 13:21 ` [PATCH 11/14] mfd: remove unused wm8350 driver Arnd Bergmann
2026-09-09 13:26 ` 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; 31+ 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] 31+ 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; 31+ 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] 31+ 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; 31+ 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] 31+ 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 13:47 ` Alexandre Belloni
@ 2026-09-09 15:46 ` Sebastian Reichel
1 sibling, 0 replies; 31+ 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] 31+ messages in thread
* Re: [PATCH 11/14] mfd: remove unused wm8350 driver
2026-09-09 13:21 ` [PATCH 11/14] mfd: remove unused wm8350 driver Arnd Bergmann
` (2 preceding siblings ...)
2026-09-09 14:39 ` Charles Keepax
@ 2026-09-09 15:47 ` Sebastian Reichel
3 siblings, 0 replies; 31+ 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] 31+ 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
` (14 preceding siblings ...)
2026-09-09 14:03 ` [PATCH 00/14] mfd: unused driver purge Bartosz Golaszewski
@ 2026-09-09 17:26 ` Dmitry Torokhov
15 siblings, 0 replies; 31+ 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] 31+ 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-09 13:44 ` Alexandre Belloni
@ 2026-09-11 7:24 ` Krzysztof Kozlowski
1 sibling, 0 replies; 31+ 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] 31+ messages in thread
end of thread, other threads:[~2026-09-11 7:25 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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:44 ` Alexandre Belloni
2026-09-11 7:24 ` Krzysztof Kozlowski
2026-09-09 13:21 ` [PATCH 02/14] mfd: remove unused rdc321x southbridge support Arnd Bergmann
2026-09-09 14:09 ` Guenter Roeck
2026-09-09 13:21 ` [PATCH 03/14] mfd: remove unused si476x driver Arnd Bergmann
2026-09-09 13:21 ` [PATCH 04/14] mfd: remove unused wm8400 driver Arnd Bergmann
2026-09-09 13:27 ` Mark Brown
2026-09-09 14:38 ` Charles Keepax
2026-09-09 13:21 ` [PATCH 05/14] mfd: remove unused adp5520 driver Arnd Bergmann
2026-09-09 13:21 ` [PATCH 06/14] mfd: remove unused da903x driver Arnd Bergmann
2026-09-09 15:46 ` Sebastian Reichel
2026-09-09 13:21 ` [PATCH 07/14] mfd: remove unused lp8788 driver Arnd Bergmann
2026-09-09 13:47 ` Alexandre Belloni
2026-09-09 15:46 ` Sebastian Reichel
2026-09-09 13:21 ` [PATCH 08/14] mfd: remove unused aat2870 driver Arnd Bergmann
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
2026-09-09 13:21 ` [PATCH 10/14] mfd: remove unused rc5t583 driver Arnd Bergmann
2026-09-09 13:21 ` [PATCH 11/14] mfd: remove unused wm8350 driver Arnd Bergmann
2026-09-09 13:26 ` Mark Brown
2026-09-09 14:12 ` Guenter Roeck
2026-09-09 14:39 ` Charles Keepax
2026-09-09 15:47 ` Sebastian Reichel
2026-09-09 13:21 ` [PATCH 12/14] mfd: remove unused mcp-sa11x0/ucb1x00 driver Arnd Bergmann
2026-09-09 13:21 ` [PATCH 13/14] mfd: remove unused menelaus driver Arnd Bergmann
2026-09-09 13:21 ` [PATCH 14/14] mfd: remove unused iPaq micro driver Arnd Bergmann
2026-09-09 14:03 ` [PATCH 00/14] mfd: unused driver purge Bartosz Golaszewski
2026-09-09 17:26 ` Dmitry Torokhov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®