- New Drivers
- Add new driver for MAXIM MAX77620/MAX20024 PMIC - Add new driver for Hisilicon HI665X PMIC - New Device Support - Add support for AXP809 in axp20x-rsb - Add support for Power Supply in axp20x - New core features - devm_mfd_* managed resources - Fix-ups - Remove unused code; da9063-irq, wm8400-core, tps6105x, smsc-ece1099, twl4030-power - Improve clean-up in error path; intel_quark_i2c_gpio - Explicitly include headers; syscon.h - Allow building as modules; max77693 - Use IS_ENABLED() instead of rolling your own; dm355evm_msp, wm8400-core - DT adaptions; axp20x, hi655x, arizona, max77620 - Remove CLK_IS_ROOT flag; intel-lpss, intel_quark - Move to gpiochip API; asic3, dm355evm_msp, htc-egpio, htc-i2cpld, sm501, tc6393xb, tps65010, ucb1x00, vexpress - Make use of devm_mfd_* calls; act8945a, as3711, atmel-hlcdc, bcm590xx, hi6421-pmic-core, lp3943, menf21bmc, mt6397, rdc321x, rk808, rn5t618, rt5033, sky81452, stw481x, tps6507x, tps65217, wm8400, - Bug Fixes - Fix ACPI child matching; mfd-core - Fix start-up ordering issues; mt6397-core, arizona-core - Fix forgotten register state on resume; intel-lpss - Fix Clock related issues; twl6040 - Fix scheduling whilst atomic; omap-usb-tll - Kconfig changes; vexpress -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJXPzwAAAoJEFGvii+H/HdhkPEP/iTvgiL+CpAk7UwAhCNolR5j l3vb49lOlmqx87zELdToJmySAd/byiZN0YQEmcn+t4BCs/8CeaWeNkb8vltJvuac Fmz88bhXfgFYk87nx/6tRMvuM3fKXlk/YYRZkklV7mkBjcPLiqBZSi/MG/SV53a9 A+vGW56B2/vHiUgTBkYs9UZNqkFCkmhuVYbHjtFwTfL84lwy9u4tNRrktss6g1lx Ak9uiDhaUP/vxKe/7/qCTZXgV/IYb2+tcNjMJ+Cztmyht8VTrhGSXbDPH7MyRYUI EBBWRXAQelR5qHxOYDSBNIemZe3AniCBp7tjqcwlN9cdE8q9pJxOk+0XStjC+XeW Qt1aIwQisk8jfII8BIGr2pAzc8Jh9/TtcK+wKMRQ2o5g2tvcG90hHIJWQlbdy4ST SX799w0KvTItdaMhTHThTOfJRj777v/H2cj8DBCCEeoBHOCHnzbJSIuKahPa9PM3 W0dyZOpsDXoegyksjBUYjdhGoggjEdirt+oXJe4rY7UxeEml+YZS54fseVzgNzNq //Nxk1GMNOVXgo3NrlO8JTs2G5gFPc8VOuPW60G1fm8DyNW13RbUG74QPpSd4U7S zZM/OZ3D0E4nrPjXf/GCS3QRwM7p1ubiOgSTTZkaLJYGBcHSezGXK8XpFSNReRop Un13GPM09Sl9VN9a2Ybi =FSmn -----END PGP SIGNATURE----- Merge tag 'mfd-for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Drivers: - Add new driver for MAXIM MAX77620/MAX20024 PMIC - Add new driver for Hisilicon HI665X PMIC New Device Support: - Add support for AXP809 in axp20x-rsb - Add support for Power Supply in axp20x New core features: - devm_mfd_* managed resources Fix-ups: - Remove unused code (da9063-irq, wm8400-core, tps6105x, smsc-ece1099, twl4030-power) - Improve clean-up in error path (intel_quark_i2c_gpio) - Explicitly include headers (syscon.h) - Allow building as modules (max77693) - Use IS_ENABLED() instead of rolling your own (dm355evm_msp, wm8400-core) - DT adaptions (axp20x, hi655x, arizona, max77620) - Remove CLK_IS_ROOT flag (intel-lpss, intel_quark) - Move to gpiochip API (asic3, dm355evm_msp, htc-egpio, htc-i2cpld, sm501, tc6393xb, tps65010, ucb1x00, vexpress) - Make use of devm_mfd_* calls (act8945a, as3711, atmel-hlcdc, bcm590xx, hi6421-pmic-core, lp3943, menf21bmc, mt6397, rdc321x, rk808, rn5t618, rt5033, sky81452, stw481x, tps6507x, tps65217, wm8400) Bug Fixes" - Fix ACPI child matching (mfd-core) - Fix start-up ordering issues (mt6397-core, arizona-core) - Fix forgotten register state on resume (intel-lpss) - Fix Clock related issues (twl6040) - Fix scheduling whilst atomic (omap-usb-tll) - Kconfig changes (vexpress)" * tag 'mfd-for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (73 commits) mfd: hi655x: Add MFD driver for hi655x mfd: ab8500-debugfs: Trivial fix of spelling mistake on "between" mfd: vexpress: Add !ARCH_USES_GETTIMEOFFSET dependency mfd: Add device-tree binding doc for PMIC MAX77620/MAX20024 mfd: max77620: Add core driver for MAX77620/MAX20024 mfd: arizona: Add defines for GPSW values that can be used from DT mfd: omap-usb-tll: Fix scheduling while atomic BUG mfd: wm5110: ARIZONA_CLOCK_CONTROL should be volatile mfd: axp20x: Add a cell for the ac power_supply part of the axp20x PMICs mfd: intel_soc_pmic_core: Terminate panel control GPIO lookup table correctly mfd: wl1273-core: Use devm_mfd_add_devices() for mfd_device registration mfd: tps65910: Use devm_mfd_add_devices and devm_regmap_add_irq_chip mfd: sec: Use devm_mfd_add_devices and devm_regmap_add_irq_chip mfd: rc5t583: Use devm_mfd_add_devices and devm_request_threaded_irq mfd: max77686: Use devm_mfd_add_devices and devm_regmap_add_irq_chip mfd: as3722: Use devm_mfd_add_devices and devm_regmap_add_irq_chip mfd: twl4030-power: Remove driver path in file comment MAINTAINERS: Add entry for X-Powers AXP family PMIC drivers mfd: smsc-ece1099: Remove unnecessarily remove callback mfd: Use IS_ENABLED(CONFIG_FOO) instead of checking FOO || FOO_MODULE ...
This commit is contained in:
Коммит
6eb59af580
|
@ -6,10 +6,11 @@ axp202 (X-Powers)
|
|||
axp209 (X-Powers)
|
||||
axp221 (X-Powers)
|
||||
axp223 (X-Powers)
|
||||
axp809 (X-Powers)
|
||||
|
||||
Required properties:
|
||||
- compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209",
|
||||
"x-powers,axp221", "x-powers,axp223"
|
||||
"x-powers,axp221", "x-powers,axp223", "x-powers,axp809"
|
||||
- reg: The I2C slave address or RSB hardware address for the AXP chip
|
||||
- interrupt-parent: The parent interrupt controller
|
||||
- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
|
||||
|
@ -18,7 +19,9 @@ Required properties:
|
|||
|
||||
Optional properties:
|
||||
- x-powers,dcdc-freq: defines the work frequency of DC-DC in KHz
|
||||
(range: 750-1875). Default: 1.5MHz
|
||||
AXP152/20X: range: 750-1875, Default: 1.5 MHz
|
||||
AXP22X/80X: range: 1800-4050, Default: 3 MHz
|
||||
|
||||
- <input>-supply: a phandle to the regulator supply node. May be omitted if
|
||||
inputs are unregulated, such as using the IPSOUT output
|
||||
from the PMIC.
|
||||
|
@ -77,6 +80,30 @@ LDO_IO0 : LDO : ips-supply : GPIO 0
|
|||
LDO_IO1 : LDO : ips-supply : GPIO 1
|
||||
RTC_LDO : LDO : ips-supply : always on
|
||||
|
||||
AXP809 regulators, type, and corresponding input supply names:
|
||||
|
||||
Regulator Type Supply Name Notes
|
||||
--------- ---- ----------- -----
|
||||
DCDC1 : DC-DC buck : vin1-supply
|
||||
DCDC2 : DC-DC buck : vin2-supply
|
||||
DCDC3 : DC-DC buck : vin3-supply
|
||||
DCDC4 : DC-DC buck : vin4-supply
|
||||
DCDC5 : DC-DC buck : vin5-supply
|
||||
DC1SW : On/Off Switch : : DCDC1 secondary output
|
||||
DC5LDO : LDO : : input from DCDC5
|
||||
ALDO1 : LDO : aldoin-supply : shared supply
|
||||
ALDO2 : LDO : aldoin-supply : shared supply
|
||||
ALDO3 : LDO : aldoin-supply : shared supply
|
||||
DLDO1 : LDO : dldoin-supply : shared supply
|
||||
DLDO2 : LDO : dldoin-supply : shared supply
|
||||
ELDO1 : LDO : eldoin-supply : shared supply
|
||||
ELDO2 : LDO : eldoin-supply : shared supply
|
||||
ELDO3 : LDO : eldoin-supply : shared supply
|
||||
LDO_IO0 : LDO : ips-supply : GPIO 0
|
||||
LDO_IO1 : LDO : ips-supply : GPIO 1
|
||||
RTC_LDO : LDO : ips-supply : always on
|
||||
SW : On/Off Switch : swin-supply
|
||||
|
||||
Example:
|
||||
|
||||
axp209: pmic@34 {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Hisilicon Hi655x Power Management Integrated Circuit (PMIC)
|
||||
|
||||
The hardware layout for access PMIC Hi655x from AP SoC Hi6220.
|
||||
Between PMIC Hi655x and Hi6220, the physical signal channel is SSI.
|
||||
We can use memory-mapped I/O to communicate.
|
||||
|
||||
+----------------+ +-------------+
|
||||
| | | |
|
||||
| Hi6220 | SSI bus | Hi655x |
|
||||
| |-------------| |
|
||||
| |(REGMAP_MMIO)| |
|
||||
+----------------+ +-------------+
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "hisilicon,hi655x-pmic".
|
||||
- reg: Base address of PMIC on Hi6220 SoC.
|
||||
- interrupt-controller: Hi655x has internal IRQs (has own IRQ domain).
|
||||
- pmic-gpios: The GPIO used by PMIC IRQ.
|
||||
|
||||
Example:
|
||||
pmic: pmic@f8000000 {
|
||||
compatible = "hisilicon,hi655x-pmic";
|
||||
reg = <0x0 0xf8000000 0x0 0x1000>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
pmic-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
MAX77620 Power management IC from Maxim Semiconductor.
|
||||
|
||||
Required properties:
|
||||
-------------------
|
||||
- compatible: Must be one of
|
||||
"maxim,max77620"
|
||||
"maxim,max20024".
|
||||
- reg: I2C device address.
|
||||
|
||||
Optional properties:
|
||||
-------------------
|
||||
- interrupts: The interrupt on the parent the controller is
|
||||
connected to.
|
||||
- interrupt-controller: Marks the device node as an interrupt controller.
|
||||
- #interrupt-cells: is <2> and their usage is compliant to the 2 cells
|
||||
variant of <../interrupt-controller/interrupts.txt>
|
||||
IRQ numbers for different interrupt source of MAX77620
|
||||
are defined at dt-bindings/mfd/max77620.h.
|
||||
|
||||
Optional subnodes and their properties:
|
||||
=======================================
|
||||
|
||||
Flexible power sequence configurations:
|
||||
--------------------------------------
|
||||
The Flexible Power Sequencer (FPS) allows each regulator to power up under
|
||||
hardware or software control. Additionally, each regulator can power on
|
||||
independently or among a group of other regulators with an adjustable power-up
|
||||
and power-down delays (sequencing). GPIO1, GPIO2, and GPIO3 can be programmed
|
||||
to be part of a sequence allowing external regulators to be sequenced along
|
||||
with internal regulators. 32KHz clock can be programmed to be part of a
|
||||
sequence.
|
||||
|
||||
The flexible sequencing structure consists of two hardware enable inputs
|
||||
(EN0, EN1), and 3 master sequencing timers called FPS0, FPS1 and FPS2.
|
||||
Each master sequencing timer is programmable through its configuration
|
||||
register to have a hardware enable source (EN1 or EN2) or a software enable
|
||||
source (SW). When enabled/disabled, the master sequencing timer generates
|
||||
eight sequencing events on different time periods called slots. The time
|
||||
period between each event is programmable within the configuration register.
|
||||
Each regulator, GPIO1, GPIO2, GPIO3, and 32KHz clock has a flexible power
|
||||
sequence slave register which allows its enable source to be specified as
|
||||
a flexible power sequencer timer or a software bit. When a FPS source of
|
||||
regulators, GPIOs and clocks specifies the enable source to be a flexible
|
||||
power sequencer, the power up and power down delays can be specified in
|
||||
the regulators, GPIOs and clocks flexible power sequencer configuration
|
||||
registers.
|
||||
|
||||
When FPS event cleared (set to LOW), regulators, GPIOs and 32KHz
|
||||
clock are set into following state at the sequencing event that
|
||||
corresponds to its flexible sequencer configuration register.
|
||||
Sleep state: In this state, regulators, GPIOs
|
||||
and 32KHz clock get disabled at
|
||||
the sequencing event.
|
||||
Global Low Power Mode (GLPM): In this state, regulators are set in
|
||||
low power mode at the sequencing event.
|
||||
|
||||
The configuration parameters of FPS is provided through sub-node "fps"
|
||||
and their child for FPS specific. The child node name for FPS are "fps0",
|
||||
"fps1", and "fps2" for FPS0, FPS1 and FPS2 respectively.
|
||||
|
||||
The FPS configurations like FPS source, power up and power down slots for
|
||||
regulators, GPIOs and 32kHz clocks are provided in their respective
|
||||
configuration nodes which is explained in respective sub-system DT
|
||||
binding document.
|
||||
|
||||
There is need for different FPS configuration parameters based on system
|
||||
state like when system state changed from active to suspend or active to
|
||||
power off (shutdown).
|
||||
|
||||
Optional properties:
|
||||
-------------------
|
||||
-maxim,fps-event-source: u32, FPS event source like external
|
||||
hardware input to PMIC i.e. EN0, EN1 or
|
||||
software (SW).
|
||||
The macros are defined on
|
||||
dt-bindings/mfd/max77620.h
|
||||
for different control source.
|
||||
- MAX77620_FPS_EVENT_SRC_EN0
|
||||
for hardware input pin EN0.
|
||||
- MAX77620_FPS_EVENT_SRC_EN1
|
||||
for hardware input pin EN1.
|
||||
- MAX77620_FPS_EVENT_SRC_SW
|
||||
for software control.
|
||||
|
||||
-maxim,shutdown-fps-time-period-us: u32, FPS time period in microseconds
|
||||
when system enters in to shutdown
|
||||
state.
|
||||
|
||||
-maxim,suspend-fps-time-period-us: u32, FPS time period in microseconds
|
||||
when system enters in to suspend state.
|
||||
|
||||
-maxim,device-state-on-disabled-event: u32, describe the PMIC state when FPS
|
||||
event cleared (set to LOW) whether it
|
||||
should go to sleep state or low-power
|
||||
state. Following are valid values:
|
||||
- MAX77620_FPS_INACTIVE_STATE_SLEEP
|
||||
to set the PMIC state to sleep.
|
||||
- MAX77620_FPS_INACTIVE_STATE_LOW_POWER
|
||||
to set the PMIC state to low
|
||||
power.
|
||||
Absence of this property or other value
|
||||
will not change device state when FPS
|
||||
event get cleared.
|
||||
|
||||
Here supported time periods by device in microseconds are as follows:
|
||||
MAX77620 supports 40, 80, 160, 320, 640, 1280, 2560 and 5120 microseconds.
|
||||
MAX20024 supports 20, 40, 80, 160, 320, 640, 1280 and 2540 microseconds.
|
||||
|
||||
For DT binding details of different sub modules like GPIO, pincontrol,
|
||||
regulator, power, please refer respective device-tree binding document
|
||||
under their respective sub-system directories.
|
||||
|
||||
Example:
|
||||
--------
|
||||
#include <dt-bindings/mfd/max77620.h>
|
||||
|
||||
max77620@3c {
|
||||
compatible = "maxim,max77620";
|
||||
reg = <0x3c>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 86 IRQ_TYPE_NONE>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
fps {
|
||||
fps0 {
|
||||
maxim,shutdown-fps-time-period-us = <1280>;
|
||||
maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
|
||||
};
|
||||
|
||||
fps1 {
|
||||
maxim,shutdown-fps-time-period-us = <1280>;
|
||||
maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
|
||||
};
|
||||
|
||||
fps2 {
|
||||
maxim,shutdown-fps-time-period-us = <1280>;
|
||||
maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_SW>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -320,6 +320,9 @@ MEM
|
|||
devm_kvasprintf()
|
||||
devm_kzalloc()
|
||||
|
||||
MFD
|
||||
devm_mfd_add_devices()
|
||||
|
||||
PCI
|
||||
pcim_enable_device() : after success, all PCI ops become managed
|
||||
pcim_pin_device() : keep PCI device enabled after release
|
||||
|
|
|
@ -12291,6 +12291,12 @@ F: include/linux/workqueue.h
|
|||
F: kernel/workqueue.c
|
||||
F: Documentation/workqueue.txt
|
||||
|
||||
X-POWERS MULTIFUNCTION PMIC DEVICE DRIVERS
|
||||
M: Chen-Yu Tsai <wens@csie.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
N: axp[128]
|
||||
|
||||
X.25 NETWORK LAYER
|
||||
M: Andrew Hendry <andrew.hendry@gmail.com>
|
||||
L: linux-x25@vger.kernel.org
|
||||
|
|
|
@ -134,7 +134,7 @@ config MFD_CROS_EC
|
|||
select MFD_CORE
|
||||
select CHROME_PLATFORMS
|
||||
select CROS_EC_PROTO
|
||||
depends on X86 || ARM || COMPILE_TEST
|
||||
depends on X86 || ARM || ARM64 || COMPILE_TEST
|
||||
help
|
||||
If you say Y here you get support for the ChromeOS Embedded
|
||||
Controller (EC) providing keyboard, battery and power services.
|
||||
|
@ -319,6 +319,16 @@ config MFD_HI6421_PMIC
|
|||
menus in order to enable them.
|
||||
We communicate with the Hi6421 via memory-mapped I/O.
|
||||
|
||||
config MFD_HI655X_PMIC
|
||||
tristate "HiSilicon Hi655X series PMU/Codec IC"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
depends on OF
|
||||
select MFD_CORE
|
||||
select REGMAP_MMIO
|
||||
select REGMAP_IRQ
|
||||
help
|
||||
Select this option to enable Hisilicon hi655x series pmic driver.
|
||||
|
||||
config HTC_EGPIO
|
||||
bool "HTC EGPIO support"
|
||||
depends on GPIOLIB && ARM
|
||||
|
@ -527,6 +537,21 @@ config MFD_MAX14577
|
|||
additional drivers must be enabled in order to use the functionality
|
||||
of the device.
|
||||
|
||||
config MFD_MAX77620
|
||||
bool "Maxim Semiconductor MAX77620 and MAX20024 PMIC Support"
|
||||
depends on I2C=y
|
||||
depends on OF
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select IRQ_DOMAIN
|
||||
help
|
||||
Say yes here to add support for Maxim Semiconductor MAX77620 and
|
||||
MAX20024 which are Power Management IC with General purpose pins,
|
||||
RTC, regulators, clock generator, watchdog etc. 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_MAX77686
|
||||
tristate "Maxim Semiconductor MAX77686/802 PMIC Support"
|
||||
depends on I2C
|
||||
|
@ -543,8 +568,8 @@ config MFD_MAX77686
|
|||
of the device.
|
||||
|
||||
config MFD_MAX77693
|
||||
bool "Maxim Semiconductor MAX77693 PMIC Support"
|
||||
depends on I2C=y
|
||||
tristate "Maxim Semiconductor MAX77693 PMIC Support"
|
||||
depends on I2C
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
|
@ -1568,7 +1593,7 @@ endmenu
|
|||
|
||||
config MFD_VEXPRESS_SYSREG
|
||||
bool "Versatile Express System Registers"
|
||||
depends on VEXPRESS_CONFIG && GPIOLIB
|
||||
depends on VEXPRESS_CONFIG && GPIOLIB && !ARCH_USES_GETTIMEOFFSET
|
||||
default y
|
||||
select CLKSRC_MMIO
|
||||
select GPIO_GENERIC_PLATFORM
|
||||
|
|
|
@ -128,6 +128,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o
|
|||
obj-$(CONFIG_MFD_DA9150) += da9150-core.o
|
||||
|
||||
obj-$(CONFIG_MFD_MAX14577) += max14577.o
|
||||
obj-$(CONFIG_MFD_MAX77620) += max77620.o
|
||||
obj-$(CONFIG_MFD_MAX77686) += max77686.o
|
||||
obj-$(CONFIG_MFD_MAX77693) += max77693.o
|
||||
obj-$(CONFIG_MFD_MAX77843) += max77843.o
|
||||
|
@ -195,6 +196,7 @@ obj-$(CONFIG_MFD_STW481X) += stw481x.o
|
|||
obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o
|
||||
obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o
|
||||
obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o
|
||||
obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o
|
||||
obj-$(CONFIG_MFD_DLN2) += dln2.o
|
||||
obj-$(CONFIG_MFD_RT5033) += rt5033.o
|
||||
obj-$(CONFIG_MFD_SKY81452) += sky81452.o
|
||||
|
|
|
@ -46,8 +46,9 @@ static int act8945a_i2c_probe(struct i2c_client *i2c,
|
|||
|
||||
i2c_set_clientdata(i2c, regmap);
|
||||
|
||||
ret = mfd_add_devices(&i2c->dev, PLATFORM_DEVID_NONE, act8945a_devs,
|
||||
ARRAY_SIZE(act8945a_devs), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_NONE,
|
||||
act8945a_devs, ARRAY_SIZE(act8945a_devs),
|
||||
NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Failed to add sub devices\n");
|
||||
return ret;
|
||||
|
@ -56,13 +57,6 @@ static int act8945a_i2c_probe(struct i2c_client *i2c,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int act8945a_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
mfd_remove_devices(&i2c->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id act8945a_i2c_id[] = {
|
||||
{ "act8945a", 0 },
|
||||
{}
|
||||
|
@ -81,7 +75,6 @@ static struct i2c_driver act8945a_i2c_driver = {
|
|||
.of_match_table = of_match_ptr(act8945a_of_match),
|
||||
},
|
||||
.probe = act8945a_i2c_probe,
|
||||
.remove = act8945a_i2c_remove,
|
||||
.id_table = act8945a_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -908,12 +908,12 @@ static const char * const wm5102_supplies[] = {
|
|||
|
||||
static const struct mfd_cell wm5102_devs[] = {
|
||||
{ .name = "arizona-micsupp" },
|
||||
{ .name = "arizona-gpio" },
|
||||
{
|
||||
.name = "arizona-extcon",
|
||||
.parent_supplies = wm5102_supplies,
|
||||
.num_parent_supplies = 1, /* We only need MICVDD */
|
||||
},
|
||||
{ .name = "arizona-gpio" },
|
||||
{ .name = "arizona-haptics" },
|
||||
{ .name = "arizona-pwm" },
|
||||
{
|
||||
|
@ -925,12 +925,12 @@ static const struct mfd_cell wm5102_devs[] = {
|
|||
|
||||
static const struct mfd_cell wm5110_devs[] = {
|
||||
{ .name = "arizona-micsupp" },
|
||||
{ .name = "arizona-gpio" },
|
||||
{
|
||||
.name = "arizona-extcon",
|
||||
.parent_supplies = wm5102_supplies,
|
||||
.num_parent_supplies = 1, /* We only need MICVDD */
|
||||
},
|
||||
{ .name = "arizona-gpio" },
|
||||
{ .name = "arizona-haptics" },
|
||||
{ .name = "arizona-pwm" },
|
||||
{
|
||||
|
@ -966,12 +966,12 @@ static const char * const wm8997_supplies[] = {
|
|||
|
||||
static const struct mfd_cell wm8997_devs[] = {
|
||||
{ .name = "arizona-micsupp" },
|
||||
{ .name = "arizona-gpio" },
|
||||
{
|
||||
.name = "arizona-extcon",
|
||||
.parent_supplies = wm8997_supplies,
|
||||
.num_parent_supplies = 1, /* We only need MICVDD */
|
||||
},
|
||||
{ .name = "arizona-gpio" },
|
||||
{ .name = "arizona-haptics" },
|
||||
{ .name = "arizona-pwm" },
|
||||
{
|
||||
|
@ -982,12 +982,13 @@ static const struct mfd_cell wm8997_devs[] = {
|
|||
};
|
||||
|
||||
static const struct mfd_cell wm8998_devs[] = {
|
||||
{ .name = "arizona-micsupp" },
|
||||
{ .name = "arizona-gpio" },
|
||||
{
|
||||
.name = "arizona-extcon",
|
||||
.parent_supplies = wm5102_supplies,
|
||||
.num_parent_supplies = 1, /* We only need MICVDD */
|
||||
},
|
||||
{ .name = "arizona-gpio" },
|
||||
{ .name = "arizona-haptics" },
|
||||
{ .name = "arizona-pwm" },
|
||||
{
|
||||
|
@ -995,7 +996,6 @@ static const struct mfd_cell wm8998_devs[] = {
|
|||
.parent_supplies = wm5102_supplies,
|
||||
.num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
|
||||
},
|
||||
{ .name = "arizona-micsupp" },
|
||||
};
|
||||
|
||||
int arizona_dev_init(struct arizona *arizona)
|
||||
|
|
|
@ -168,12 +168,15 @@ static struct irq_chip arizona_irq_chip = {
|
|||
.irq_set_wake = arizona_irq_set_wake,
|
||||
};
|
||||
|
||||
static struct lock_class_key arizona_irq_lock_class;
|
||||
|
||||
static int arizona_irq_map(struct irq_domain *h, unsigned int virq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
struct arizona *data = h->host_data;
|
||||
|
||||
irq_set_chip_data(virq, data);
|
||||
irq_set_lockdep_class(virq, &arizona_irq_lock_class);
|
||||
irq_set_chip_and_handler(virq, &arizona_irq_chip, handle_simple_irq);
|
||||
irq_set_nested_thread(virq, 1);
|
||||
irq_set_noprobe(virq);
|
||||
|
|
|
@ -189,22 +189,14 @@ static int as3711_i2c_probe(struct i2c_client *client,
|
|||
as3711_subdevs[AS3711_BACKLIGHT].pdata_size = 0;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(as3711->dev, -1, as3711_subdevs,
|
||||
ARRAY_SIZE(as3711_subdevs), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(as3711->dev, -1, as3711_subdevs,
|
||||
ARRAY_SIZE(as3711_subdevs), NULL, 0, NULL);
|
||||
if (ret < 0)
|
||||
dev_err(&client->dev, "add mfd devices failed: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as3711_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct as3711 *as3711 = i2c_get_clientdata(client);
|
||||
|
||||
mfd_remove_devices(as3711->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id as3711_i2c_id[] = {
|
||||
{.name = "as3711", .driver_data = 0},
|
||||
{}
|
||||
|
@ -218,7 +210,6 @@ static struct i2c_driver as3711_i2c_driver = {
|
|||
.of_match_table = of_match_ptr(as3711_of_match),
|
||||
},
|
||||
.probe = as3711_i2c_probe,
|
||||
.remove = as3711_i2c_remove,
|
||||
.id_table = as3711_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -385,9 +385,10 @@ static int as3722_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
|
||||
irq_flags = as3722->irq_flags | IRQF_ONESHOT;
|
||||
ret = regmap_add_irq_chip(as3722->regmap, as3722->chip_irq,
|
||||
irq_flags, -1, &as3722_irq_chip,
|
||||
&as3722->irq_data);
|
||||
ret = devm_regmap_add_irq_chip(as3722->dev, as3722->regmap,
|
||||
as3722->chip_irq,
|
||||
irq_flags, -1, &as3722_irq_chip,
|
||||
&as3722->irq_data);
|
||||
if (ret < 0) {
|
||||
dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -395,33 +396,20 @@ static int as3722_i2c_probe(struct i2c_client *i2c,
|
|||
|
||||
ret = as3722_configure_pullups(as3722);
|
||||
if (ret < 0)
|
||||
goto scrub;
|
||||
return ret;
|
||||
|
||||
ret = mfd_add_devices(&i2c->dev, -1, as3722_devs,
|
||||
ARRAY_SIZE(as3722_devs), NULL, 0,
|
||||
regmap_irq_get_domain(as3722->irq_data));
|
||||
ret = devm_mfd_add_devices(&i2c->dev, -1, as3722_devs,
|
||||
ARRAY_SIZE(as3722_devs), NULL, 0,
|
||||
regmap_irq_get_domain(as3722->irq_data));
|
||||
if (ret) {
|
||||
dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret);
|
||||
goto scrub;
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_init_wakeup(as3722->dev, true);
|
||||
|
||||
dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n");
|
||||
return 0;
|
||||
|
||||
scrub:
|
||||
regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as3722_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct as3722 *as3722 = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(as3722->dev);
|
||||
regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused as3722_i2c_suspend(struct device *dev)
|
||||
|
@ -470,7 +458,6 @@ static struct i2c_driver as3722_i2c_driver = {
|
|||
.pm = &as3722_pm_ops,
|
||||
},
|
||||
.probe = as3722_i2c_probe,
|
||||
.remove = as3722_i2c_remove,
|
||||
.id_table = as3722_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -446,7 +446,7 @@ static int asic3_gpio_direction(struct gpio_chip *chip,
|
|||
unsigned long flags;
|
||||
struct asic3 *asic;
|
||||
|
||||
asic = container_of(chip, struct asic3, gpio);
|
||||
asic = gpiochip_get_data(chip);
|
||||
gpio_base = ASIC3_GPIO_TO_BASE(offset);
|
||||
|
||||
if (gpio_base > ASIC3_GPIO_D_BASE) {
|
||||
|
@ -492,7 +492,7 @@ static int asic3_gpio_get(struct gpio_chip *chip,
|
|||
u32 mask = ASIC3_GPIO_TO_MASK(offset);
|
||||
struct asic3 *asic;
|
||||
|
||||
asic = container_of(chip, struct asic3, gpio);
|
||||
asic = gpiochip_get_data(chip);
|
||||
gpio_base = ASIC3_GPIO_TO_BASE(offset);
|
||||
|
||||
if (gpio_base > ASIC3_GPIO_D_BASE) {
|
||||
|
@ -513,7 +513,7 @@ static void asic3_gpio_set(struct gpio_chip *chip,
|
|||
unsigned long flags;
|
||||
struct asic3 *asic;
|
||||
|
||||
asic = container_of(chip, struct asic3, gpio);
|
||||
asic = gpiochip_get_data(chip);
|
||||
gpio_base = ASIC3_GPIO_TO_BASE(offset);
|
||||
|
||||
if (gpio_base > ASIC3_GPIO_D_BASE) {
|
||||
|
@ -540,7 +540,7 @@ static void asic3_gpio_set(struct gpio_chip *chip,
|
|||
|
||||
static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct asic3 *asic = container_of(chip, struct asic3, gpio);
|
||||
struct asic3 *asic = gpiochip_get_data(chip);
|
||||
|
||||
return asic->irq_base + offset;
|
||||
}
|
||||
|
@ -595,7 +595,7 @@ static __init int asic3_gpio_probe(struct platform_device *pdev,
|
|||
alt_reg[i]);
|
||||
}
|
||||
|
||||
return gpiochip_add(&asic->gpio);
|
||||
return gpiochip_add_data(&asic->gpio, asic);
|
||||
}
|
||||
|
||||
static int asic3_gpio_remove(struct platform_device *pdev)
|
||||
|
|
|
@ -128,16 +128,9 @@ static int atmel_hlcdc_probe(struct platform_device *pdev)
|
|||
|
||||
dev_set_drvdata(dev, hlcdc);
|
||||
|
||||
return mfd_add_devices(dev, -1, atmel_hlcdc_cells,
|
||||
ARRAY_SIZE(atmel_hlcdc_cells),
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static int atmel_hlcdc_remove(struct platform_device *pdev)
|
||||
{
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
return devm_mfd_add_devices(dev, -1, atmel_hlcdc_cells,
|
||||
ARRAY_SIZE(atmel_hlcdc_cells),
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id atmel_hlcdc_match[] = {
|
||||
|
@ -152,7 +145,6 @@ MODULE_DEVICE_TABLE(of, atmel_hlcdc_match);
|
|||
|
||||
static struct platform_driver atmel_hlcdc_driver = {
|
||||
.probe = atmel_hlcdc_probe,
|
||||
.remove = atmel_hlcdc_remove,
|
||||
.driver = {
|
||||
.name = "atmel-hlcdc",
|
||||
.of_match_table = atmel_hlcdc_match,
|
||||
|
|
|
@ -61,6 +61,7 @@ static int axp20x_rsb_remove(struct sunxi_rsb_device *rdev)
|
|||
|
||||
static const struct of_device_id axp20x_rsb_of_match[] = {
|
||||
{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
|
||||
{ .compatible = "x-powers,axp809", .data = (void *)AXP809_ID },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_rsb_of_match);
|
||||
|
|
|
@ -37,6 +37,7 @@ static const char * const axp20x_model_names[] = {
|
|||
"AXP221",
|
||||
"AXP223",
|
||||
"AXP288",
|
||||
"AXP809",
|
||||
};
|
||||
|
||||
static const struct regmap_range axp152_writeable_ranges[] = {
|
||||
|
@ -85,6 +86,7 @@ static const struct regmap_access_table axp20x_volatile_table = {
|
|||
.n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
|
||||
};
|
||||
|
||||
/* AXP22x ranges are shared with the AXP809, as they cover the same range */
|
||||
static const struct regmap_range axp22x_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
|
||||
regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
|
||||
|
@ -128,6 +130,12 @@ static struct resource axp152_pek_resources[] = {
|
|||
DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static struct resource axp20x_ac_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
|
||||
};
|
||||
|
||||
static struct resource axp20x_pek_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
|
@ -211,6 +219,20 @@ static struct resource axp288_fuel_gauge_resources[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct resource axp809_pek_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
.start = AXP809_IRQ_PEK_RIS_EDGE,
|
||||
.end = AXP809_IRQ_PEK_RIS_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.name = "PEK_DBF",
|
||||
.start = AXP809_IRQ_PEK_FAL_EDGE,
|
||||
.end = AXP809_IRQ_PEK_FAL_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_config axp152_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
@ -378,6 +400,41 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
|
|||
INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
|
||||
};
|
||||
|
||||
static const struct regmap_irq axp809_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V, 0, 7),
|
||||
INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN, 0, 6),
|
||||
INIT_REGMAP_IRQ(AXP809, ACIN_REMOVAL, 0, 5),
|
||||
INIT_REGMAP_IRQ(AXP809, VBUS_OVER_V, 0, 4),
|
||||
INIT_REGMAP_IRQ(AXP809, VBUS_PLUGIN, 0, 3),
|
||||
INIT_REGMAP_IRQ(AXP809, VBUS_REMOVAL, 0, 2),
|
||||
INIT_REGMAP_IRQ(AXP809, VBUS_V_LOW, 0, 1),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_PLUGIN, 1, 7),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_REMOVAL, 1, 6),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_ENT_ACT_MODE, 1, 5),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_EXIT_ACT_MODE, 1, 4),
|
||||
INIT_REGMAP_IRQ(AXP809, CHARG, 1, 3),
|
||||
INIT_REGMAP_IRQ(AXP809, CHARG_DONE, 1, 2),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH, 2, 7),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_HIGH_END, 2, 6),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW, 2, 5),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_CHG_TEMP_LOW_END, 2, 4),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH, 2, 3),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_HIGH_END, 2, 2),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW, 2, 1),
|
||||
INIT_REGMAP_IRQ(AXP809, BATT_ACT_TEMP_LOW_END, 2, 0),
|
||||
INIT_REGMAP_IRQ(AXP809, DIE_TEMP_HIGH, 3, 7),
|
||||
INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL1, 3, 1),
|
||||
INIT_REGMAP_IRQ(AXP809, LOW_PWR_LVL2, 3, 0),
|
||||
INIT_REGMAP_IRQ(AXP809, TIMER, 4, 7),
|
||||
INIT_REGMAP_IRQ(AXP809, PEK_RIS_EDGE, 4, 6),
|
||||
INIT_REGMAP_IRQ(AXP809, PEK_FAL_EDGE, 4, 5),
|
||||
INIT_REGMAP_IRQ(AXP809, PEK_SHORT, 4, 4),
|
||||
INIT_REGMAP_IRQ(AXP809, PEK_LONG, 4, 3),
|
||||
INIT_REGMAP_IRQ(AXP809, PEK_OVER_OFF, 4, 2),
|
||||
INIT_REGMAP_IRQ(AXP809, GPIO1_INPUT, 4, 1),
|
||||
INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp152_regmap_irq_chip = {
|
||||
.name = "axp152_irq_chip",
|
||||
.status_base = AXP152_IRQ1_STATE,
|
||||
|
@ -428,6 +485,18 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
|
|||
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp809_regmap_irq_chip = {
|
||||
.name = "axp809",
|
||||
.status_base = AXP20X_IRQ1_STATE,
|
||||
.ack_base = AXP20X_IRQ1_STATE,
|
||||
.mask_base = AXP20X_IRQ1_EN,
|
||||
.mask_invert = true,
|
||||
.init_ack_masked = true,
|
||||
.irqs = axp809_regmap_irqs,
|
||||
.num_irqs = ARRAY_SIZE(axp809_regmap_irqs),
|
||||
.num_regs = 5,
|
||||
};
|
||||
|
||||
static struct mfd_cell axp20x_cells[] = {
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
|
@ -435,6 +504,11 @@ static struct mfd_cell axp20x_cells[] = {
|
|||
.resources = axp20x_pek_resources,
|
||||
}, {
|
||||
.name = "axp20x-regulator",
|
||||
}, {
|
||||
.name = "axp20x-ac-power-supply",
|
||||
.of_compatible = "x-powers,axp202-ac-power-supply",
|
||||
.num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
|
||||
.resources = axp20x_ac_power_supply_resources,
|
||||
}, {
|
||||
.name = "axp20x-usb-power-supply",
|
||||
.of_compatible = "x-powers,axp202-usb-power-supply",
|
||||
|
@ -572,6 +646,16 @@ static struct mfd_cell axp288_cells[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp809_cells[] = {
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
.num_resources = ARRAY_SIZE(axp809_pek_resources),
|
||||
.resources = axp809_pek_resources,
|
||||
}, {
|
||||
.name = "axp20x-regulator",
|
||||
},
|
||||
};
|
||||
|
||||
static struct axp20x_dev *axp20x_pm_power_off;
|
||||
static void axp20x_power_off(void)
|
||||
{
|
||||
|
@ -631,6 +715,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
|
|||
axp20x->regmap_cfg = &axp288_regmap_config;
|
||||
axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
|
||||
break;
|
||||
case AXP809_ID:
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
|
||||
axp20x->cells = axp809_cells;
|
||||
axp20x->regmap_cfg = &axp22x_regmap_config;
|
||||
axp20x->regmap_irq_chip = &axp809_regmap_irq_chip;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -82,8 +82,8 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
|
|||
goto err;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
|
||||
ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
|
||||
ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_pri->dev, "failed to add sub-devices: %d\n", ret);
|
||||
goto err;
|
||||
|
@ -96,12 +96,6 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int bcm590xx_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
mfd_remove_devices(&i2c->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm590xx_of_match[] = {
|
||||
{ .compatible = "brcm,bcm59056" },
|
||||
{ }
|
||||
|
@ -120,7 +114,6 @@ static struct i2c_driver bcm590xx_i2c_driver = {
|
|||
.of_match_table = of_match_ptr(bcm590xx_of_match),
|
||||
},
|
||||
.probe = bcm590xx_i2c_probe,
|
||||
.remove = bcm590xx_i2c_remove,
|
||||
.id_table = bcm590xx_i2c_id,
|
||||
};
|
||||
module_i2c_driver(bcm590xx_i2c_driver);
|
||||
|
|
|
@ -25,14 +25,6 @@
|
|||
#define DA9063_REG_EVENT_B_OFFSET 1
|
||||
#define DA9063_REG_EVENT_C_OFFSET 2
|
||||
#define DA9063_REG_EVENT_D_OFFSET 3
|
||||
#define EVENTS_BUF_LEN 4
|
||||
|
||||
static const u8 mask_events_buf[] = { [0 ... (EVENTS_BUF_LEN - 1)] = ~0 };
|
||||
|
||||
struct da9063_irq_data {
|
||||
u16 reg;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
static const struct regmap_irq da9063_irqs[] = {
|
||||
/* DA9063 event A register */
|
||||
|
|
|
@ -33,25 +33,25 @@
|
|||
* This driver was tested with firmware revision A4.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_INPUT_DM355EVM) || defined(CONFIG_INPUT_DM355EVM_MODULE)
|
||||
#if IS_ENABLED(CONFIG_INPUT_DM355EVM)
|
||||
#define msp_has_keyboard() true
|
||||
#else
|
||||
#define msp_has_keyboard() false
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
|
||||
#if IS_ENABLED(CONFIG_LEDS_GPIO)
|
||||
#define msp_has_leds() true
|
||||
#else
|
||||
#define msp_has_leds() false
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RTC_DRV_DM355EVM) || defined(CONFIG_RTC_DRV_DM355EVM_MODULE)
|
||||
#if IS_ENABLED(CONFIG_RTC_DRV_DM355EVM)
|
||||
#define msp_has_rtc() true
|
||||
#else
|
||||
#define msp_has_rtc() false
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_VIDEO_TVP514X) || defined(CONFIG_VIDEO_TVP514X_MODULE)
|
||||
#if IS_ENABLED(CONFIG_VIDEO_TVP514X)
|
||||
#define msp_has_tvp() true
|
||||
#else
|
||||
#define msp_has_tvp() false
|
||||
|
@ -260,7 +260,7 @@ static int add_children(struct i2c_client *client)
|
|||
|
||||
/* GPIO-ish stuff */
|
||||
dm355evm_msp_gpio.parent = &client->dev;
|
||||
status = gpiochip_add(&dm355evm_msp_gpio);
|
||||
status = gpiochip_add_data(&dm355evm_msp_gpio, NULL);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -76,8 +76,8 @@ static int hi6421_pmic_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, pmic);
|
||||
|
||||
ret = mfd_add_devices(&pdev->dev, 0, hi6421_devs,
|
||||
ARRAY_SIZE(hi6421_devs), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&pdev->dev, 0, hi6421_devs,
|
||||
ARRAY_SIZE(hi6421_devs), NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "add mfd devices failed: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -86,13 +86,6 @@ static int hi6421_pmic_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hi6421_pmic_remove(struct platform_device *pdev)
|
||||
{
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_hi6421_pmic_match_tbl[] = {
|
||||
{ .compatible = "hisilicon,hi6421-pmic", },
|
||||
{ },
|
||||
|
@ -105,7 +98,6 @@ static struct platform_driver hi6421_pmic_driver = {
|
|||
.of_match_table = of_hi6421_pmic_match_tbl,
|
||||
},
|
||||
.probe = hi6421_pmic_probe,
|
||||
.remove = hi6421_pmic_remove,
|
||||
};
|
||||
module_platform_driver(hi6421_pmic_driver);
|
||||
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Device driver for MFD hi655x PMIC
|
||||
*
|
||||
* Copyright (c) 2016 Hisilicon.
|
||||
*
|
||||
* Authors:
|
||||
* Chen Feng <puck.chen@hisilicon.com>
|
||||
* Fei Wang <w.f@huawei.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/hi655x-pmic.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell hi655x_pmic_devs[] = {
|
||||
{ .name = "hi655x-regulator", },
|
||||
};
|
||||
|
||||
static const struct regmap_irq hi655x_irqs[] = {
|
||||
{ .reg_offset = 0, .mask = OTMP_D1R_INT },
|
||||
{ .reg_offset = 0, .mask = VSYS_2P5_R_INT },
|
||||
{ .reg_offset = 0, .mask = VSYS_UV_D3R_INT },
|
||||
{ .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT },
|
||||
{ .reg_offset = 0, .mask = PWRON_D4SR_INT },
|
||||
{ .reg_offset = 0, .mask = PWRON_D20F_INT },
|
||||
{ .reg_offset = 0, .mask = PWRON_D20R_INT },
|
||||
{ .reg_offset = 0, .mask = RESERVE_INT },
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip hi655x_irq_chip = {
|
||||
.name = "hi655x-pmic",
|
||||
.irqs = hi655x_irqs,
|
||||
.num_regs = 1,
|
||||
.num_irqs = ARRAY_SIZE(hi655x_irqs),
|
||||
.status_base = HI655X_IRQ_STAT_BASE,
|
||||
.mask_base = HI655X_IRQ_MASK_BASE,
|
||||
};
|
||||
|
||||
static struct regmap_config hi655x_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = HI655X_STRIDE,
|
||||
.val_bits = 8,
|
||||
.max_register = HI655X_BUS_ADDR(0xFFF),
|
||||
};
|
||||
|
||||
static void hi655x_local_irq_clear(struct regmap *map)
|
||||
{
|
||||
int i;
|
||||
|
||||
regmap_write(map, HI655X_ANA_IRQM_BASE, HI655X_IRQ_CLR);
|
||||
for (i = 0; i < HI655X_IRQ_ARRAY; i++) {
|
||||
regmap_write(map, HI655X_IRQ_STAT_BASE + i * HI655X_STRIDE,
|
||||
HI655X_IRQ_CLR);
|
||||
}
|
||||
}
|
||||
|
||||
static int hi655x_pmic_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct hi655x_pmic *pmic;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
void __iomem *base;
|
||||
|
||||
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
pmic->dev = dev;
|
||||
|
||||
pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!pmic->res)
|
||||
return -ENOENT;
|
||||
|
||||
base = devm_ioremap_resource(dev, pmic->res);
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
|
||||
pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
|
||||
&hi655x_regmap_config);
|
||||
|
||||
regmap_read(pmic->regmap, HI655X_BUS_ADDR(HI655X_VER_REG), &pmic->ver);
|
||||
if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) {
|
||||
dev_warn(dev, "PMU version %d unsupported\n", pmic->ver);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hi655x_local_irq_clear(pmic->regmap);
|
||||
|
||||
pmic->gpio = of_get_named_gpio(np, "pmic-gpios", 0);
|
||||
if (!gpio_is_valid(pmic->gpio)) {
|
||||
dev_err(dev, "Failed to get the pmic-gpios\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN,
|
||||
"hi655x_pmic_irq");
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to request gpio %d ret = %d\n",
|
||||
pmic->gpio, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(pmic->regmap, gpio_to_irq(pmic->gpio),
|
||||
IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, 0,
|
||||
&hi655x_irq_chip, &pmic->irq_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to obtain 'hi655x_pmic_irq' %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, pmic);
|
||||
|
||||
ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs,
|
||||
ARRAY_SIZE(hi655x_pmic_devs), NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register device %d\n", ret);
|
||||
regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hi655x_pmic_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct hi655x_pmic *pmic = platform_get_drvdata(pdev);
|
||||
|
||||
regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id hi655x_pmic_match[] = {
|
||||
{ .compatible = "hisilicon,hi655x-pmic", },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver hi655x_pmic_driver = {
|
||||
.driver = {
|
||||
.name = "hi655x-pmic",
|
||||
.of_match_table = of_match_ptr(hi655x_pmic_match),
|
||||
},
|
||||
.probe = hi655x_pmic_probe,
|
||||
.remove = hi655x_pmic_remove,
|
||||
};
|
||||
module_platform_driver(hi655x_pmic_driver);
|
||||
|
||||
MODULE_AUTHOR("Chen Feng <puck.chen@hisilicon.com>");
|
||||
MODULE_DESCRIPTION("Hisilicon hi655x PMIC driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -155,7 +155,7 @@ static int egpio_get(struct gpio_chip *chip, unsigned offset)
|
|||
|
||||
pr_debug("egpio_get_value(%d)\n", chip->base + offset);
|
||||
|
||||
egpio = container_of(chip, struct egpio_chip, chip);
|
||||
egpio = gpiochip_get_data(chip);
|
||||
ei = dev_get_drvdata(egpio->dev);
|
||||
bit = egpio_bit(ei, offset);
|
||||
reg = egpio->reg_start + egpio_pos(ei, offset);
|
||||
|
@ -170,7 +170,7 @@ static int egpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
|||
{
|
||||
struct egpio_chip *egpio;
|
||||
|
||||
egpio = container_of(chip, struct egpio_chip, chip);
|
||||
egpio = gpiochip_get_data(chip);
|
||||
return test_bit(offset, &egpio->is_out) ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ static void egpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|||
pr_debug("egpio_set(%s, %d(%d), %d)\n",
|
||||
chip->label, offset, offset+chip->base, value);
|
||||
|
||||
egpio = container_of(chip, struct egpio_chip, chip);
|
||||
egpio = gpiochip_get_data(chip);
|
||||
ei = dev_get_drvdata(egpio->dev);
|
||||
bit = egpio_bit(ei, offset);
|
||||
pos = egpio_pos(ei, offset);
|
||||
|
@ -216,7 +216,7 @@ static int egpio_direction_output(struct gpio_chip *chip,
|
|||
{
|
||||
struct egpio_chip *egpio;
|
||||
|
||||
egpio = container_of(chip, struct egpio_chip, chip);
|
||||
egpio = gpiochip_get_data(chip);
|
||||
if (test_bit(offset, &egpio->is_out)) {
|
||||
egpio_set(chip, offset, value);
|
||||
return 0;
|
||||
|
@ -330,7 +330,7 @@ static int __init egpio_probe(struct platform_device *pdev)
|
|||
chip->base = pdata->chip[i].gpio_base;
|
||||
chip->ngpio = pdata->chip[i].num_gpios;
|
||||
|
||||
gpiochip_add(chip);
|
||||
gpiochip_add_data(chip, &ei->chip[i]);
|
||||
}
|
||||
|
||||
/* Set initial pin values */
|
||||
|
|
|
@ -227,8 +227,7 @@ static irqreturn_t htcpld_handler(int irq, void *dev)
|
|||
static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val)
|
||||
{
|
||||
struct i2c_client *client;
|
||||
struct htcpld_chip *chip_data =
|
||||
container_of(chip, struct htcpld_chip, chip_out);
|
||||
struct htcpld_chip *chip_data = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
client = chip_data->client;
|
||||
|
@ -257,14 +256,12 @@ static void htcpld_chip_set_ni(struct work_struct *work)
|
|||
|
||||
static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct htcpld_chip *chip_data;
|
||||
struct htcpld_chip *chip_data = gpiochip_get_data(chip);
|
||||
u8 cache;
|
||||
|
||||
if (!strncmp(chip->label, "htcpld-out", 10)) {
|
||||
chip_data = container_of(chip, struct htcpld_chip, chip_out);
|
||||
cache = chip_data->cache_out;
|
||||
} else if (!strncmp(chip->label, "htcpld-in", 9)) {
|
||||
chip_data = container_of(chip, struct htcpld_chip, chip_in);
|
||||
cache = chip_data->cache_in;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
@ -291,9 +288,7 @@ static int htcpld_direction_input(struct gpio_chip *chip,
|
|||
|
||||
static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct htcpld_chip *chip_data;
|
||||
|
||||
chip_data = container_of(chip, struct htcpld_chip, chip_in);
|
||||
struct htcpld_chip *chip_data = gpiochip_get_data(chip);
|
||||
|
||||
if (offset < chip_data->nirqs)
|
||||
return chip_data->irq_start + offset;
|
||||
|
@ -451,14 +446,14 @@ static int htcpld_register_chip_gpio(
|
|||
gpio_chip->ngpio = plat_chip_data->num_gpios;
|
||||
|
||||
/* Add the GPIO chips */
|
||||
ret = gpiochip_add(&(chip->chip_out));
|
||||
ret = gpiochip_add_data(&(chip->chip_out), chip);
|
||||
if (ret) {
|
||||
dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n",
|
||||
plat_chip_data->addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpiochip_add(&(chip->chip_in));
|
||||
ret = gpiochip_add_data(&(chip->chip_in), chip);
|
||||
if (ret) {
|
||||
dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n",
|
||||
plat_chip_data->addr, ret);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#define LPSS_DEV_SIZE 0x200
|
||||
#define LPSS_PRIV_OFFSET 0x200
|
||||
#define LPSS_PRIV_SIZE 0x100
|
||||
#define LPSS_PRIV_REG_COUNT (LPSS_PRIV_SIZE / 4)
|
||||
#define LPSS_IDMA64_OFFSET 0x800
|
||||
#define LPSS_IDMA64_SIZE 0x800
|
||||
|
||||
|
@ -76,6 +77,7 @@ struct intel_lpss {
|
|||
struct mfd_cell *cell;
|
||||
struct device *dev;
|
||||
void __iomem *priv;
|
||||
u32 priv_ctx[LPSS_PRIV_REG_COUNT];
|
||||
int devid;
|
||||
u32 caps;
|
||||
u32 active_ltr;
|
||||
|
@ -336,8 +338,8 @@ static int intel_lpss_register_clock(struct intel_lpss *lpss)
|
|||
return 0;
|
||||
|
||||
/* Root clock */
|
||||
clk = clk_register_fixed_rate(NULL, dev_name(lpss->dev), NULL,
|
||||
CLK_IS_ROOT, lpss->info->clk_rate);
|
||||
clk = clk_register_fixed_rate(NULL, dev_name(lpss->dev), NULL, 0,
|
||||
lpss->info->clk_rate);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
|
@ -493,6 +495,16 @@ EXPORT_SYMBOL_GPL(intel_lpss_prepare);
|
|||
|
||||
int intel_lpss_suspend(struct device *dev)
|
||||
{
|
||||
struct intel_lpss *lpss = dev_get_drvdata(dev);
|
||||
unsigned int i;
|
||||
|
||||
/* Save device context */
|
||||
for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
|
||||
lpss->priv_ctx[i] = readl(lpss->priv + i * 4);
|
||||
|
||||
/* Put the device into reset state */
|
||||
writel(0, lpss->priv + LPSS_PRIV_RESETS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_lpss_suspend);
|
||||
|
@ -500,8 +512,13 @@ EXPORT_SYMBOL_GPL(intel_lpss_suspend);
|
|||
int intel_lpss_resume(struct device *dev)
|
||||
{
|
||||
struct intel_lpss *lpss = dev_get_drvdata(dev);
|
||||
unsigned int i;
|
||||
|
||||
intel_lpss_init_dev(lpss);
|
||||
intel_lpss_deassert_reset(lpss);
|
||||
|
||||
/* Restore device context */
|
||||
for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
|
||||
writel(lpss->priv_ctx[i], lpss->priv + i * 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#define INTEL_QUARK_I2C_CLK_HZ 33000000
|
||||
|
||||
struct intel_quark_mfd {
|
||||
struct pci_dev *pdev;
|
||||
struct device *dev;
|
||||
struct clk *i2c_clk;
|
||||
struct clk_lookup *i2c_clk_lookup;
|
||||
};
|
||||
|
@ -123,14 +123,14 @@ static const struct pci_device_id intel_quark_mfd_ids[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
|
||||
|
||||
static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
|
||||
static int intel_quark_register_i2c_clk(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = quark_mfd->pdev;
|
||||
struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
|
||||
struct clk *i2c_clk;
|
||||
|
||||
i2c_clk = clk_register_fixed_rate(&pdev->dev,
|
||||
i2c_clk = clk_register_fixed_rate(dev,
|
||||
INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
|
||||
CLK_IS_ROOT, INTEL_QUARK_I2C_CLK_HZ);
|
||||
0, INTEL_QUARK_I2C_CLK_HZ);
|
||||
if (IS_ERR(i2c_clk))
|
||||
return PTR_ERR(i2c_clk);
|
||||
|
||||
|
@ -139,18 +139,19 @@ static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
|
|||
INTEL_QUARK_I2C_CONTROLLER_CLK);
|
||||
|
||||
if (!quark_mfd->i2c_clk_lookup) {
|
||||
dev_err(&pdev->dev, "Fixed clk register failed\n");
|
||||
clk_unregister(quark_mfd->i2c_clk);
|
||||
dev_err(dev, "Fixed clk register failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
|
||||
static void intel_quark_unregister_i2c_clk(struct device *dev)
|
||||
{
|
||||
struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev);
|
||||
struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
|
||||
|
||||
if (!quark_mfd->i2c_clk || !quark_mfd->i2c_clk_lookup)
|
||||
if (!quark_mfd->i2c_clk_lookup)
|
||||
return;
|
||||
|
||||
clkdev_drop(quark_mfd->i2c_clk_lookup);
|
||||
|
@ -245,30 +246,38 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
|
|||
quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
|
||||
if (!quark_mfd)
|
||||
return -ENOMEM;
|
||||
quark_mfd->pdev = pdev;
|
||||
|
||||
ret = intel_quark_register_i2c_clk(quark_mfd);
|
||||
quark_mfd->dev = &pdev->dev;
|
||||
dev_set_drvdata(&pdev->dev, quark_mfd);
|
||||
|
||||
ret = intel_quark_register_i2c_clk(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, quark_mfd);
|
||||
|
||||
ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_unregister_i2c_clk;
|
||||
|
||||
ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_unregister_i2c_clk;
|
||||
|
||||
return mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
|
||||
ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
|
||||
NULL);
|
||||
ret = mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
|
||||
ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
|
||||
NULL);
|
||||
if (ret)
|
||||
goto err_unregister_i2c_clk;
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_i2c_clk:
|
||||
intel_quark_unregister_i2c_clk(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void intel_quark_mfd_remove(struct pci_dev *pdev)
|
||||
{
|
||||
intel_quark_unregister_i2c_clk(pdev);
|
||||
intel_quark_unregister_i2c_clk(&pdev->dev);
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ static struct gpiod_lookup_table panel_gpio_table = {
|
|||
.table = {
|
||||
/* Panel EN/DISABLE */
|
||||
GPIO_LOOKUP("gpio_crystalcove", 94, "panel", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -123,16 +123,9 @@ static int lp3943_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
|||
lp3943->mux_cfg = lp3943_mux_cfg;
|
||||
i2c_set_clientdata(cl, lp3943);
|
||||
|
||||
return mfd_add_devices(dev, -1, lp3943_devs, ARRAY_SIZE(lp3943_devs),
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static int lp3943_remove(struct i2c_client *cl)
|
||||
{
|
||||
struct lp3943 *lp3943 = i2c_get_clientdata(cl);
|
||||
|
||||
mfd_remove_devices(lp3943->dev);
|
||||
return 0;
|
||||
return devm_mfd_add_devices(dev, -1, lp3943_devs,
|
||||
ARRAY_SIZE(lp3943_devs),
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lp3943_ids[] = {
|
||||
|
@ -151,7 +144,6 @@ MODULE_DEVICE_TABLE(of, lp3943_of_match);
|
|||
|
||||
static struct i2c_driver lp3943_driver = {
|
||||
.probe = lp3943_probe,
|
||||
.remove = lp3943_remove,
|
||||
.driver = {
|
||||
.name = "lp3943",
|
||||
.of_match_table = of_match_ptr(lp3943_of_match),
|
||||
|
|
|
@ -112,7 +112,7 @@ 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;
|
||||
bool handled = false;
|
||||
int i;
|
||||
|
||||
if (lp8788_read_multi_bytes(lp, LP8788_INT_1, status, NUM_REGS))
|
||||
|
|
|
@ -0,0 +1,590 @@
|
|||
/*
|
||||
* Maxim MAX77620 MFD Driver
|
||||
*
|
||||
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author:
|
||||
* Laxman Dewangan <ldewangan@nvidia.com>
|
||||
* Chaitanya Bandi <bandik@nvidia.com>
|
||||
* Mallikarjun Kasoju <mkasoju@nvidia.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/****************** Teminology used in driver ********************
|
||||
* Here are some terminology used from datasheet for quick reference:
|
||||
* Flexible Power Sequence (FPS):
|
||||
* The Flexible Power Sequencer (FPS) allows each regulator to power up under
|
||||
* hardware or software control. Additionally, each regulator can power on
|
||||
* independently or among a group of other regulators with an adjustable
|
||||
* power-up and power-down delays (sequencing). GPIO1, GPIO2, and GPIO3 can
|
||||
* be programmed to be part of a sequence allowing external regulators to be
|
||||
* sequenced along with internal regulators. 32KHz clock can be programmed to
|
||||
* be part of a sequence.
|
||||
* There is 3 FPS confguration registers and all resources are configured to
|
||||
* any of these FPS or no FPS.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/max77620.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static struct resource gpio_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
|
||||
};
|
||||
|
||||
static struct resource power_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW),
|
||||
};
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC),
|
||||
};
|
||||
|
||||
static struct resource thermal_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1),
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2),
|
||||
};
|
||||
|
||||
static const struct regmap_irq max77620_top_irqs[] = {
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GLBL, 0, MAX77620_IRQ_TOP_GLBL_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_TOP_SD, 0, MAX77620_IRQ_TOP_SD_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_TOP_LDO, 0, MAX77620_IRQ_TOP_LDO_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GPIO, 0, MAX77620_IRQ_TOP_GPIO_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_TOP_RTC, 0, MAX77620_IRQ_TOP_RTC_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_TOP_32K, 0, MAX77620_IRQ_TOP_32K_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_TOP_ONOFF, 0, MAX77620_IRQ_TOP_ONOFF_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_LBT_MBATLOW, 1, MAX77620_IRQ_LBM_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM1, 1, MAX77620_IRQ_TJALRM1_MASK),
|
||||
REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM2, 1, MAX77620_IRQ_TJALRM2_MASK),
|
||||
};
|
||||
|
||||
static const struct mfd_cell max77620_children[] = {
|
||||
{ .name = "max77620-pinctrl", },
|
||||
{ .name = "max77620-clock", },
|
||||
{ .name = "max77620-pmic", },
|
||||
{ .name = "max77620-watchdog", },
|
||||
{
|
||||
.name = "max77620-gpio",
|
||||
.resources = gpio_resources,
|
||||
.num_resources = ARRAY_SIZE(gpio_resources),
|
||||
}, {
|
||||
.name = "max77620-rtc",
|
||||
.resources = rtc_resources,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
}, {
|
||||
.name = "max77620-power",
|
||||
.resources = power_resources,
|
||||
.num_resources = ARRAY_SIZE(power_resources),
|
||||
}, {
|
||||
.name = "max77620-thermal",
|
||||
.resources = thermal_resources,
|
||||
.num_resources = ARRAY_SIZE(thermal_resources),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell max20024_children[] = {
|
||||
{ .name = "max20024-pinctrl", },
|
||||
{ .name = "max77620-clock", },
|
||||
{ .name = "max20024-pmic", },
|
||||
{ .name = "max77620-watchdog", },
|
||||
{
|
||||
.name = "max77620-gpio",
|
||||
.resources = gpio_resources,
|
||||
.num_resources = ARRAY_SIZE(gpio_resources),
|
||||
}, {
|
||||
.name = "max77620-rtc",
|
||||
.resources = rtc_resources,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
}, {
|
||||
.name = "max20024-power",
|
||||
.resources = power_resources,
|
||||
.num_resources = ARRAY_SIZE(power_resources),
|
||||
},
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip max77620_top_irq_chip = {
|
||||
.name = "max77620-top",
|
||||
.irqs = max77620_top_irqs,
|
||||
.num_irqs = ARRAY_SIZE(max77620_top_irqs),
|
||||
.num_regs = 2,
|
||||
.status_base = MAX77620_REG_IRQTOP,
|
||||
.mask_base = MAX77620_REG_IRQTOPM,
|
||||
};
|
||||
|
||||
static const struct regmap_range max77620_readable_ranges[] = {
|
||||
regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table max77620_readable_table = {
|
||||
.yes_ranges = max77620_readable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(max77620_readable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range max20024_readable_ranges[] = {
|
||||
regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
|
||||
regmap_reg_range(MAX20024_REG_MAX_ADD, MAX20024_REG_MAX_ADD),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table max20024_readable_table = {
|
||||
.yes_ranges = max20024_readable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(max20024_readable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range max77620_writable_ranges[] = {
|
||||
regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table max77620_writable_table = {
|
||||
.yes_ranges = max77620_writable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(max77620_writable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range max77620_cacheable_ranges[] = {
|
||||
regmap_reg_range(MAX77620_REG_SD0_CFG, MAX77620_REG_LDO_CFG3),
|
||||
regmap_reg_range(MAX77620_REG_FPS_CFG0, MAX77620_REG_FPS_SD3),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table max77620_volatile_table = {
|
||||
.no_ranges = max77620_cacheable_ranges,
|
||||
.n_no_ranges = ARRAY_SIZE(max77620_cacheable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config max77620_regmap_config = {
|
||||
.name = "power-slave",
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MAX77620_REG_DVSSD4 + 1,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.rd_table = &max77620_readable_table,
|
||||
.wr_table = &max77620_writable_table,
|
||||
.volatile_table = &max77620_volatile_table,
|
||||
};
|
||||
|
||||
static const struct regmap_config max20024_regmap_config = {
|
||||
.name = "power-slave",
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MAX20024_REG_MAX_ADD + 1,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.rd_table = &max20024_readable_table,
|
||||
.wr_table = &max77620_writable_table,
|
||||
.volatile_table = &max77620_volatile_table,
|
||||
};
|
||||
|
||||
/* max77620_get_fps_period_reg_value: Get FPS bit field value from
|
||||
* requested periods.
|
||||
* MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
|
||||
* and 5120 microseconds. MAX20024 supports the FPS period of 20, 40, 80,
|
||||
* 160, 320, 540, 1280 and 2560 microseconds.
|
||||
* The FPS register has 3 bits field to set the FPS period as
|
||||
* bits max77620 max20024
|
||||
* 000 40 20
|
||||
* 001 80 40
|
||||
* :::
|
||||
*/
|
||||
static int max77620_get_fps_period_reg_value(struct max77620_chip *chip,
|
||||
int tperiod)
|
||||
{
|
||||
int fps_min_period;
|
||||
int i;
|
||||
|
||||
switch (chip->chip_id) {
|
||||
case MAX20024:
|
||||
fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
|
||||
break;
|
||||
case MAX77620:
|
||||
fps_min_period = MAX77620_FPS_PERIOD_MIN_US;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (fps_min_period >= tperiod)
|
||||
return i;
|
||||
fps_min_period *= 2;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* max77620_config_fps: Configure FPS configuration registers
|
||||
* based on platform specific information.
|
||||
*/
|
||||
static int max77620_config_fps(struct max77620_chip *chip,
|
||||
struct device_node *fps_np)
|
||||
{
|
||||
struct device *dev = chip->dev;
|
||||
unsigned int mask = 0, config = 0;
|
||||
u32 fps_max_period;
|
||||
u32 param_val;
|
||||
int tperiod, fps_id;
|
||||
int ret;
|
||||
char fps_name[10];
|
||||
|
||||
switch (chip->chip_id) {
|
||||
case MAX20024:
|
||||
fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
|
||||
break;
|
||||
case MAX77620:
|
||||
fps_max_period = MAX77620_FPS_PERIOD_MAX_US;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
|
||||
sprintf(fps_name, "fps%d", fps_id);
|
||||
if (!strcmp(fps_np->name, fps_name))
|
||||
break;
|
||||
}
|
||||
|
||||
if (fps_id == MAX77620_FPS_COUNT) {
|
||||
dev_err(dev, "FPS node name %s is not valid\n", fps_np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(fps_np, "maxim,shutdown-fps-time-period-us",
|
||||
¶m_val);
|
||||
if (!ret) {
|
||||
mask |= MAX77620_FPS_TIME_PERIOD_MASK;
|
||||
chip->shutdown_fps_period[fps_id] = min(param_val,
|
||||
fps_max_period);
|
||||
tperiod = max77620_get_fps_period_reg_value(chip,
|
||||
chip->shutdown_fps_period[fps_id]);
|
||||
config |= tperiod << MAX77620_FPS_TIME_PERIOD_SHIFT;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(fps_np, "maxim,suspend-fps-time-period-us",
|
||||
¶m_val);
|
||||
if (!ret)
|
||||
chip->suspend_fps_period[fps_id] = min(param_val,
|
||||
fps_max_period);
|
||||
|
||||
ret = of_property_read_u32(fps_np, "maxim,fps-event-source",
|
||||
¶m_val);
|
||||
if (!ret) {
|
||||
if (param_val > 2) {
|
||||
dev_err(dev, "FPS%d event-source invalid\n", fps_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
mask |= MAX77620_FPS_EN_SRC_MASK;
|
||||
config |= param_val << MAX77620_FPS_EN_SRC_SHIFT;
|
||||
if (param_val == 2) {
|
||||
mask |= MAX77620_FPS_ENFPS_SW_MASK;
|
||||
config |= MAX77620_FPS_ENFPS_SW;
|
||||
}
|
||||
}
|
||||
|
||||
if (!chip->sleep_enable && !chip->enable_global_lpm) {
|
||||
ret = of_property_read_u32(fps_np,
|
||||
"maxim,device-state-on-disabled-event",
|
||||
¶m_val);
|
||||
if (!ret) {
|
||||
if (param_val == 0)
|
||||
chip->sleep_enable = true;
|
||||
else if (param_val == 1)
|
||||
chip->enable_global_lpm = true;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
|
||||
mask, config);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to update FPS CFG: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77620_initialise_fps(struct max77620_chip *chip)
|
||||
{
|
||||
struct device *dev = chip->dev;
|
||||
struct device_node *fps_np, *fps_child;
|
||||
u8 config;
|
||||
int fps_id;
|
||||
int ret;
|
||||
|
||||
for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
|
||||
chip->shutdown_fps_period[fps_id] = -1;
|
||||
chip->suspend_fps_period[fps_id] = -1;
|
||||
}
|
||||
|
||||
fps_np = of_get_child_by_name(dev->of_node, "fps");
|
||||
if (!fps_np)
|
||||
goto skip_fps;
|
||||
|
||||
for_each_child_of_node(fps_np, fps_child) {
|
||||
ret = max77620_config_fps(chip, fps_child);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
|
||||
MAX77620_ONOFFCNFG2_SLP_LPM_MSK, config);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to update SLP_LPM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
skip_fps:
|
||||
/* Enable wake on EN0 pin */
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
|
||||
MAX77620_ONOFFCNFG2_WK_EN0,
|
||||
MAX77620_ONOFFCNFG2_WK_EN0);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to update WK_EN0: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* For MAX20024, SLPEN will be POR reset if CLRSE is b11 */
|
||||
if ((chip->chip_id == MAX20024) && chip->sleep_enable) {
|
||||
config = MAX77620_ONOFFCNFG1_SLPEN | MAX20024_ONOFFCNFG1_CLRSE;
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
|
||||
config, config);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to update SLPEN: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77620_read_es_version(struct max77620_chip *chip)
|
||||
{
|
||||
unsigned int val;
|
||||
u8 cid_val[6];
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
for (i = MAX77620_REG_CID0; i <= MAX77620_REG_CID5; i++) {
|
||||
ret = regmap_read(chip->rmap, i, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to read CID: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
dev_dbg(chip->dev, "CID%d: 0x%02x\n",
|
||||
i - MAX77620_REG_CID0, val);
|
||||
cid_val[i - MAX77620_REG_CID0] = val;
|
||||
}
|
||||
|
||||
/* CID4 is OTP Version and CID5 is ES version */
|
||||
dev_info(chip->dev, "PMIC Version OTP:0x%02X and ES:0x%X\n",
|
||||
cid_val[4], MAX77620_CID5_DIDM(cid_val[5]));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max77620_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
const struct regmap_config *rmap_config;
|
||||
struct max77620_chip *chip;
|
||||
const struct mfd_cell *mfd_cells;
|
||||
int n_mfd_cells;
|
||||
int ret;
|
||||
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, chip);
|
||||
chip->dev = &client->dev;
|
||||
chip->irq_base = -1;
|
||||
chip->chip_irq = client->irq;
|
||||
chip->chip_id = (enum max77620_chip_id)id->driver_data;
|
||||
|
||||
switch (chip->chip_id) {
|
||||
case MAX77620:
|
||||
mfd_cells = max77620_children;
|
||||
n_mfd_cells = ARRAY_SIZE(max77620_children);
|
||||
rmap_config = &max77620_regmap_config;
|
||||
break;
|
||||
case MAX20024:
|
||||
mfd_cells = max20024_children;
|
||||
n_mfd_cells = ARRAY_SIZE(max20024_children);
|
||||
rmap_config = &max20024_regmap_config;
|
||||
break;
|
||||
default:
|
||||
dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chip->rmap = devm_regmap_init_i2c(client, rmap_config);
|
||||
if (IS_ERR(chip->rmap)) {
|
||||
ret = PTR_ERR(chip->rmap);
|
||||
dev_err(chip->dev, "Failed to intialise regmap: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = max77620_read_es_version(chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
chip->irq_base, &max77620_top_irq_chip,
|
||||
&chip->top_irq_data);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = max77620_initialise_fps(chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE,
|
||||
mfd_cells, n_mfd_cells, NULL, 0,
|
||||
regmap_irq_get_domain(chip->top_irq_data));
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to add MFD children: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int max77620_set_fps_period(struct max77620_chip *chip,
|
||||
int fps_id, int time_period)
|
||||
{
|
||||
int period = max77620_get_fps_period_reg_value(chip, time_period);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
|
||||
MAX77620_FPS_TIME_PERIOD_MASK,
|
||||
period << MAX77620_FPS_TIME_PERIOD_SHIFT);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to update FPS period: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77620_i2c_suspend(struct device *dev)
|
||||
{
|
||||
struct max77620_chip *chip = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
unsigned int config;
|
||||
int fps;
|
||||
int ret;
|
||||
|
||||
for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
|
||||
if (chip->suspend_fps_period[fps] < 0)
|
||||
continue;
|
||||
|
||||
ret = max77620_set_fps_period(chip, fps,
|
||||
chip->suspend_fps_period[fps]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* For MAX20024: No need to configure SLPEN on suspend as
|
||||
* it will be configured on Init.
|
||||
*/
|
||||
if (chip->chip_id == MAX20024)
|
||||
goto out;
|
||||
|
||||
config = (chip->sleep_enable) ? MAX77620_ONOFFCNFG1_SLPEN : 0;
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
|
||||
MAX77620_ONOFFCNFG1_SLPEN,
|
||||
config);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to configure sleep in suspend: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable WK_EN0 */
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
|
||||
MAX77620_ONOFFCNFG2_WK_EN0, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to configure WK_EN in suspend: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
out:
|
||||
disable_irq(client->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77620_i2c_resume(struct device *dev)
|
||||
{
|
||||
struct max77620_chip *chip = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int ret;
|
||||
int fps;
|
||||
|
||||
for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
|
||||
if (chip->shutdown_fps_period[fps] < 0)
|
||||
continue;
|
||||
|
||||
ret = max77620_set_fps_period(chip, fps,
|
||||
chip->shutdown_fps_period[fps]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* For MAX20024: No need to configure WKEN0 on resume as
|
||||
* it is configured on Init.
|
||||
*/
|
||||
if (chip->chip_id == MAX20024)
|
||||
goto out;
|
||||
|
||||
/* Enable WK_EN0 */
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
|
||||
MAX77620_ONOFFCNFG2_WK_EN0,
|
||||
MAX77620_ONOFFCNFG2_WK_EN0);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to configure WK_EN0 n resume: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
out:
|
||||
enable_irq(client->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id max77620_id[] = {
|
||||
{"max77620", MAX77620},
|
||||
{"max20024", MAX20024},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max77620_id);
|
||||
|
||||
static const struct dev_pm_ops max77620_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
|
||||
};
|
||||
|
||||
static struct i2c_driver max77620_driver = {
|
||||
.driver = {
|
||||
.name = "max77620",
|
||||
.pm = &max77620_pm_ops,
|
||||
},
|
||||
.probe = max77620_probe,
|
||||
.id_table = max77620_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(max77620_driver);
|
||||
|
||||
MODULE_DESCRIPTION("MAX77620/MAX20024 Multi Function Device Core Driver");
|
||||
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
|
||||
MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>");
|
||||
MODULE_AUTHOR("Mallikarjun Kasoju <mkasoju@nvidia.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -2,7 +2,7 @@
|
|||
* max77686.c - mfd core driver for the Maxim 77686/802
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* Chiwoong Byun <woong.byun@smasung.com>
|
||||
* Chiwoong Byun <woong.byun@samsung.com>
|
||||
* Jonghwa Lee <jonghwa3.lee@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -230,37 +230,23 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(max77686->regmap, max77686->irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
|
||||
IRQF_SHARED, 0, irq_chip,
|
||||
&max77686->irq_data);
|
||||
ret = devm_regmap_add_irq_chip(&i2c->dev, max77686->regmap,
|
||||
max77686->irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
|
||||
IRQF_SHARED, 0, irq_chip,
|
||||
&max77686->irq_data);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "failed to add PMIC irq chip: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(max77686->dev, -1, cells, n_devs, NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(max77686->dev, -1, cells, n_devs, NULL,
|
||||
0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
|
||||
goto err_del_irqc;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_del_irqc:
|
||||
regmap_del_irq_chip(max77686->irq, max77686->irq_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max77686_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(max77686->dev);
|
||||
|
||||
regmap_del_irq_chip(max77686->irq, max77686->irq_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -317,22 +303,10 @@ static struct i2c_driver max77686_i2c_driver = {
|
|||
.of_match_table = of_match_ptr(max77686_pmic_dt_match),
|
||||
},
|
||||
.probe = max77686_i2c_probe,
|
||||
.remove = max77686_i2c_remove,
|
||||
.id_table = max77686_i2c_id,
|
||||
};
|
||||
|
||||
static int __init max77686_i2c_init(void)
|
||||
{
|
||||
return i2c_add_driver(&max77686_i2c_driver);
|
||||
}
|
||||
/* init early so consumer devices can complete system boot */
|
||||
subsys_initcall(max77686_i2c_init);
|
||||
|
||||
static void __exit max77686_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max77686_i2c_driver);
|
||||
}
|
||||
module_exit(max77686_i2c_exit);
|
||||
module_i2c_driver(max77686_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("MAXIM 77686/802 multi-function core driver");
|
||||
MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* max77693.c - mfd core driver for the MAX 77693
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* SangYoung Son <hello.son@smasung.com>
|
||||
* SangYoung Son <hello.son@samsung.com>
|
||||
*
|
||||
* This program is not provided / owned by Maxim Integrated Products.
|
||||
*
|
||||
|
@ -368,6 +368,7 @@ static const struct of_device_id max77693_dt_match[] = {
|
|||
{ .compatible = "maxim,max77693" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max77693_dt_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver max77693_i2c_driver = {
|
||||
|
@ -381,18 +382,7 @@ static struct i2c_driver max77693_i2c_driver = {
|
|||
.id_table = max77693_i2c_id,
|
||||
};
|
||||
|
||||
static int __init max77693_i2c_init(void)
|
||||
{
|
||||
return i2c_add_driver(&max77693_i2c_driver);
|
||||
}
|
||||
/* init early so consumer devices can complete system boot */
|
||||
subsys_initcall(max77693_i2c_init);
|
||||
|
||||
static void __exit max77693_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max77693_i2c_driver);
|
||||
}
|
||||
module_exit(max77693_i2c_exit);
|
||||
module_i2c_driver(max77693_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("MAXIM 77693 multi-function core driver");
|
||||
MODULE_AUTHOR("SangYoung, Son <hello.son@samsung.com>");
|
||||
|
|
|
@ -96,8 +96,8 @@ menf21bmc_probe(struct i2c_client *client, const struct i2c_device_id *ids)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&client->dev, 0, menf21bmc_cell,
|
||||
ARRAY_SIZE(menf21bmc_cell), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&client->dev, 0, menf21bmc_cell,
|
||||
ARRAY_SIZE(menf21bmc_cell), NULL, 0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "failed to add BMC sub-devices\n");
|
||||
return ret;
|
||||
|
@ -106,12 +106,6 @@ menf21bmc_probe(struct i2c_client *client, const struct i2c_device_id *ids)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int menf21bmc_remove(struct i2c_client *client)
|
||||
{
|
||||
mfd_remove_devices(&client->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id menf21bmc_id_table[] = {
|
||||
{ "menf21bmc" },
|
||||
{ }
|
||||
|
@ -122,7 +116,6 @@ static struct i2c_driver menf21bmc_driver = {
|
|||
.driver.name = "menf21bmc",
|
||||
.id_table = menf21bmc_id_table,
|
||||
.probe = menf21bmc_probe,
|
||||
.remove = menf21bmc_remove,
|
||||
};
|
||||
|
||||
module_i2c_driver(menf21bmc_driver);
|
||||
|
|
|
@ -107,7 +107,7 @@ static void mfd_acpi_add_device(const struct mfd_cell *cell,
|
|||
|
||||
strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id));
|
||||
list_for_each_entry(child, &parent->children, node) {
|
||||
if (acpi_match_device_ids(child, ids)) {
|
||||
if (!acpi_match_device_ids(child, ids)) {
|
||||
adev = child;
|
||||
break;
|
||||
}
|
||||
|
@ -334,6 +334,44 @@ void mfd_remove_devices(struct device *parent)
|
|||
}
|
||||
EXPORT_SYMBOL(mfd_remove_devices);
|
||||
|
||||
static void devm_mfd_dev_release(struct device *dev, void *res)
|
||||
{
|
||||
mfd_remove_devices(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_mfd_add_devices - Resource managed version of mfd_add_devices()
|
||||
*
|
||||
* Returns 0 on success or an appropriate negative error number on failure.
|
||||
* All child-devices of the MFD will automatically be removed when it gets
|
||||
* unbinded.
|
||||
*/
|
||||
int devm_mfd_add_devices(struct device *dev, int id,
|
||||
const struct mfd_cell *cells, int n_devs,
|
||||
struct resource *mem_base,
|
||||
int irq_base, struct irq_domain *domain)
|
||||
{
|
||||
struct device **ptr;
|
||||
int ret;
|
||||
|
||||
ptr = devres_alloc(devm_mfd_dev_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mfd_add_devices(dev, id, cells, n_devs, mem_base,
|
||||
irq_base, domain);
|
||||
if (ret < 0) {
|
||||
devres_free(ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*ptr = dev;
|
||||
devres_add(dev, ptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_mfd_add_devices);
|
||||
|
||||
int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
|
||||
{
|
||||
struct mfd_cell cell_entry;
|
||||
|
|
|
@ -267,17 +267,26 @@ static int mt6397_probe(struct platform_device *pdev)
|
|||
ret = regmap_read(pmic->regmap, MT6397_CID, &id);
|
||||
if (ret) {
|
||||
dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
|
||||
goto fail_irq;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pmic->irq = platform_get_irq(pdev, 0);
|
||||
if (pmic->irq <= 0)
|
||||
return pmic->irq;
|
||||
|
||||
switch (id & 0xff) {
|
||||
case MT6323_CID_CODE:
|
||||
pmic->int_con[0] = MT6323_INT_CON0;
|
||||
pmic->int_con[1] = MT6323_INT_CON1;
|
||||
pmic->int_status[0] = MT6323_INT_STATUS0;
|
||||
pmic->int_status[1] = MT6323_INT_STATUS1;
|
||||
ret = mfd_add_devices(&pdev->dev, -1, mt6323_devs,
|
||||
ARRAY_SIZE(mt6323_devs), NULL, 0, NULL);
|
||||
ret = mt6397_irq_init(pmic);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
|
||||
ARRAY_SIZE(mt6323_devs), NULL,
|
||||
0, NULL);
|
||||
break;
|
||||
|
||||
case MT6397_CID_CODE:
|
||||
|
@ -286,8 +295,13 @@ static int mt6397_probe(struct platform_device *pdev)
|
|||
pmic->int_con[1] = MT6397_INT_CON1;
|
||||
pmic->int_status[0] = MT6397_INT_STATUS0;
|
||||
pmic->int_status[1] = MT6397_INT_STATUS1;
|
||||
ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
||||
ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
|
||||
ret = mt6397_irq_init(pmic);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
||||
ARRAY_SIZE(mt6397_devs), NULL,
|
||||
0, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -296,14 +310,6 @@ static int mt6397_probe(struct platform_device *pdev)
|
|||
break;
|
||||
}
|
||||
|
||||
pmic->irq = platform_get_irq(pdev, 0);
|
||||
if (pmic->irq > 0) {
|
||||
ret = mt6397_irq_init(pmic);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
fail_irq:
|
||||
if (ret) {
|
||||
irq_domain_remove(pmic->irq_domain);
|
||||
dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
|
||||
|
@ -312,13 +318,6 @@ fail_irq:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int mt6397_remove(struct platform_device *pdev)
|
||||
{
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mt6397_of_match[] = {
|
||||
{ .compatible = "mediatek,mt6397" },
|
||||
{ .compatible = "mediatek,mt6323" },
|
||||
|
@ -334,7 +333,6 @@ MODULE_DEVICE_TABLE(platform, mt6397_id);
|
|||
|
||||
static struct platform_driver mt6397_driver = {
|
||||
.probe = mt6397_probe,
|
||||
.remove = mt6397_remove,
|
||||
.driver = {
|
||||
.name = "mt6397",
|
||||
.of_match_table = of_match_ptr(mt6397_of_match),
|
||||
|
|
|
@ -269,6 +269,8 @@ static int usbtll_omap_probe(struct platform_device *pdev)
|
|||
|
||||
if (IS_ERR(tll->ch_clk[i]))
|
||||
dev_dbg(dev, "can't get clock : %s\n", clkname);
|
||||
else
|
||||
clk_prepare(tll->ch_clk[i]);
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
|
@ -301,9 +303,12 @@ static int usbtll_omap_remove(struct platform_device *pdev)
|
|||
tll_dev = NULL;
|
||||
spin_unlock(&tll_lock);
|
||||
|
||||
for (i = 0; i < tll->nch; i++)
|
||||
if (!IS_ERR(tll->ch_clk[i]))
|
||||
for (i = 0; i < tll->nch; i++) {
|
||||
if (!IS_ERR(tll->ch_clk[i])) {
|
||||
clk_unprepare(tll->ch_clk[i]);
|
||||
clk_put(tll->ch_clk[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return 0;
|
||||
|
@ -420,7 +425,7 @@ int omap_tll_enable(struct usbhs_omap_platform_data *pdata)
|
|||
if (IS_ERR(tll->ch_clk[i]))
|
||||
continue;
|
||||
|
||||
r = clk_prepare_enable(tll->ch_clk[i]);
|
||||
r = clk_enable(tll->ch_clk[i]);
|
||||
if (r) {
|
||||
dev_err(tll_dev,
|
||||
"Error enabling ch %d clock: %d\n", i, r);
|
||||
|
@ -448,7 +453,7 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
|
|||
for (i = 0; i < tll->nch; i++) {
|
||||
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
|
||||
if (!IS_ERR(tll->ch_clk[i]))
|
||||
clk_disable_unprepare(tll->ch_clk[i]);
|
||||
clk_disable(tll->ch_clk[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -389,17 +389,10 @@ int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base)
|
|||
irq_clear_status_flags(__irq, IRQ_NOREQUEST);
|
||||
}
|
||||
|
||||
ret = request_threaded_irq(irq, NULL, rc5t583_irq, IRQF_ONESHOT,
|
||||
"rc5t583", rc5t583);
|
||||
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;
|
||||
}
|
||||
|
||||
int rc5t583_irq_exit(struct rc5t583 *rc5t583)
|
||||
{
|
||||
if (rc5t583->chip_irq)
|
||||
free_irq(rc5t583->chip_irq, rc5t583);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -252,7 +252,6 @@ static int rc5t583_i2c_probe(struct i2c_client *i2c,
|
|||
struct rc5t583 *rc5t583;
|
||||
struct rc5t583_platform_data *pdata = dev_get_platdata(&i2c->dev);
|
||||
int ret;
|
||||
bool irq_init_success = false;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&i2c->dev, "Err: Platform data not found\n");
|
||||
|
@ -284,32 +283,16 @@ static int rc5t583_i2c_probe(struct i2c_client *i2c,
|
|||
/* Still continue with warning, if irq init fails */
|
||||
if (ret)
|
||||
dev_warn(&i2c->dev, "IRQ init failed: %d\n", ret);
|
||||
else
|
||||
irq_init_success = true;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs,
|
||||
ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL);
|
||||
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);
|
||||
goto err_add_devs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_add_devs:
|
||||
if (irq_init_success)
|
||||
rc5t583_irq_exit(rc5t583);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rc5t583_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct rc5t583 *rc5t583 = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(rc5t583->dev);
|
||||
rc5t583_irq_exit(rc5t583);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id rc5t583_i2c_id[] = {
|
||||
|
@ -324,7 +307,6 @@ static struct i2c_driver rc5t583_i2c_driver = {
|
|||
.name = "rc5t583",
|
||||
},
|
||||
.probe = rc5t583_i2c_probe,
|
||||
.remove = rc5t583_i2c_remove,
|
||||
.id_table = rc5t583_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -85,14 +85,10 @@ static int rdc321x_sb_probe(struct pci_dev *pdev,
|
|||
rdc321x_gpio_pdata.sb_pdev = pdev;
|
||||
rdc321x_wdt_pdata.sb_pdev = pdev;
|
||||
|
||||
return mfd_add_devices(&pdev->dev, -1,
|
||||
rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells),
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static void rdc321x_sb_remove(struct pci_dev *pdev)
|
||||
{
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
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[] = {
|
||||
|
@ -105,7 +101,6 @@ static struct pci_driver rdc321x_sb_driver = {
|
|||
.name = "RDC321x Southbridge",
|
||||
.id_table = rdc321x_sb_table,
|
||||
.probe = rdc321x_sb_probe,
|
||||
.remove = rdc321x_sb_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(rdc321x_sb_driver);
|
||||
|
|
|
@ -213,9 +213,9 @@ static int rk808_probe(struct i2c_client *client,
|
|||
rk808->i2c = client;
|
||||
i2c_set_clientdata(client, rk808);
|
||||
|
||||
ret = mfd_add_devices(&client->dev, -1,
|
||||
rk808s, ARRAY_SIZE(rk808s),
|
||||
NULL, 0, regmap_irq_get_domain(rk808->irq_data));
|
||||
ret = devm_mfd_add_devices(&client->dev, -1,
|
||||
rk808s, ARRAY_SIZE(rk808s), NULL, 0,
|
||||
regmap_irq_get_domain(rk808->irq_data));
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
|
||||
goto err_irq;
|
||||
|
@ -240,7 +240,6 @@ static int rk808_remove(struct i2c_client *client)
|
|||
struct rk808 *rk808 = i2c_get_clientdata(client);
|
||||
|
||||
regmap_del_irq_chip(client->irq, rk808->irq_data);
|
||||
mfd_remove_devices(&client->dev);
|
||||
pm_power_off = NULL;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -78,8 +78,8 @@ static int rn5t618_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&i2c->dev, -1, rn5t618_cells,
|
||||
ARRAY_SIZE(rn5t618_cells), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&i2c->dev, -1, rn5t618_cells,
|
||||
ARRAY_SIZE(rn5t618_cells), NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -102,7 +102,6 @@ static int rn5t618_i2c_remove(struct i2c_client *i2c)
|
|||
pm_power_off = NULL;
|
||||
}
|
||||
|
||||
mfd_remove_devices(&i2c->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,9 +97,9 @@ static int rt5033_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(rt5033->dev, -1, rt5033_devs,
|
||||
ARRAY_SIZE(rt5033_devs), NULL, 0,
|
||||
regmap_irq_get_domain(rt5033->irq_data));
|
||||
ret = devm_mfd_add_devices(rt5033->dev, -1, rt5033_devs,
|
||||
ARRAY_SIZE(rt5033_devs), NULL, 0,
|
||||
regmap_irq_get_domain(rt5033->irq_data));
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "Failed to add RT5033 child devices.\n");
|
||||
return ret;
|
||||
|
@ -110,13 +110,6 @@ static int rt5033_i2c_probe(struct i2c_client *i2c,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rt5033_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
mfd_remove_devices(&i2c->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id rt5033_i2c_id[] = {
|
||||
{ "rt5033", },
|
||||
{ }
|
||||
|
@ -135,7 +128,6 @@ static struct i2c_driver rt5033_driver = {
|
|||
.of_match_table = of_match_ptr(rt5033_dt_match),
|
||||
},
|
||||
.probe = rt5033_i2c_probe,
|
||||
.remove = rt5033_i2c_remove,
|
||||
.id_table = rt5033_i2c_id,
|
||||
};
|
||||
module_i2c_driver(rt5033_driver);
|
||||
|
|
|
@ -481,29 +481,16 @@ static int sec_pmic_probe(struct i2c_client *i2c,
|
|||
/* If this happens the probe function is problem */
|
||||
BUG();
|
||||
}
|
||||
ret = mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, NULL,
|
||||
0, NULL);
|
||||
ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
goto err_mfd;
|
||||
return ret;
|
||||
|
||||
device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
|
||||
sec_pmic_configure(sec_pmic);
|
||||
sec_pmic_dump_rev(sec_pmic);
|
||||
|
||||
return ret;
|
||||
|
||||
err_mfd:
|
||||
sec_irq_exit(sec_pmic);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sec_pmic_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(sec_pmic->dev);
|
||||
sec_irq_exit(sec_pmic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sec_pmic_shutdown(struct i2c_client *i2c)
|
||||
|
@ -583,7 +570,6 @@ static struct i2c_driver sec_pmic_driver = {
|
|||
.of_match_table = of_match_ptr(sec_dt_match),
|
||||
},
|
||||
.probe = sec_pmic_probe,
|
||||
.remove = sec_pmic_remove,
|
||||
.shutdown = sec_pmic_shutdown,
|
||||
.id_table = sec_pmic_id,
|
||||
};
|
||||
|
|
|
@ -483,10 +483,11 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
sec_pmic->irq_base, sec_irq_chip,
|
||||
&sec_pmic->irq_data);
|
||||
ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
|
||||
sec_pmic->irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
sec_pmic->irq_base, sec_irq_chip,
|
||||
&sec_pmic->irq_data);
|
||||
if (ret != 0) {
|
||||
dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -500,8 +501,3 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
|
||||
}
|
||||
|
|
|
@ -64,19 +64,14 @@ static int sky81452_probe(struct i2c_client *client,
|
|||
cells[1].platform_data = pdata->regulator_init_data;
|
||||
cells[1].pdata_size = sizeof(*pdata->regulator_init_data);
|
||||
|
||||
ret = mfd_add_devices(dev, -1, cells, ARRAY_SIZE(cells), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(dev, -1, cells, ARRAY_SIZE(cells),
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
dev_err(dev, "failed to add child devices. err=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sky81452_remove(struct i2c_client *client)
|
||||
{
|
||||
mfd_remove_devices(&client->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id sky81452_ids[] = {
|
||||
{ "sky81452" },
|
||||
{ }
|
||||
|
@ -97,7 +92,6 @@ static struct i2c_driver sky81452_driver = {
|
|||
.of_match_table = of_match_ptr(sky81452_of_match),
|
||||
},
|
||||
.probe = sky81452_probe,
|
||||
.remove = sky81452_remove,
|
||||
.id_table = sky81452_ids,
|
||||
};
|
||||
|
||||
|
|
|
@ -879,11 +879,6 @@ static int sm501_register_display(struct sm501_devdata *sm,
|
|||
|
||||
#ifdef CONFIG_MFD_SM501_GPIO
|
||||
|
||||
static inline struct sm501_gpio_chip *to_sm501_gpio(struct gpio_chip *gc)
|
||||
{
|
||||
return container_of(gc, struct sm501_gpio_chip, gpio);
|
||||
}
|
||||
|
||||
static inline struct sm501_devdata *sm501_gpio_to_dev(struct sm501_gpio *gpio)
|
||||
{
|
||||
return container_of(gpio, struct sm501_devdata, gpio);
|
||||
|
@ -892,7 +887,7 @@ static inline struct sm501_devdata *sm501_gpio_to_dev(struct sm501_gpio *gpio)
|
|||
static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
|
||||
{
|
||||
struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip);
|
||||
struct sm501_gpio_chip *smgpio = gpiochip_get_data(chip);
|
||||
unsigned long result;
|
||||
|
||||
result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
|
||||
|
@ -923,7 +918,7 @@ static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
|
|||
static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
|
||||
{
|
||||
struct sm501_gpio_chip *smchip = to_sm501_gpio(chip);
|
||||
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
|
||||
struct sm501_gpio *smgpio = smchip->ourgpio;
|
||||
unsigned long bit = 1 << offset;
|
||||
void __iomem *regs = smchip->regbase;
|
||||
|
@ -948,7 +943,7 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|||
|
||||
static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct sm501_gpio_chip *smchip = to_sm501_gpio(chip);
|
||||
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
|
||||
struct sm501_gpio *smgpio = smchip->ourgpio;
|
||||
void __iomem *regs = smchip->regbase;
|
||||
unsigned long bit = 1 << offset;
|
||||
|
@ -974,7 +969,7 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
|
|||
static int sm501_gpio_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct sm501_gpio_chip *smchip = to_sm501_gpio(chip);
|
||||
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
|
||||
struct sm501_gpio *smgpio = smchip->ourgpio;
|
||||
unsigned long bit = 1 << offset;
|
||||
void __iomem *regs = smchip->regbase;
|
||||
|
@ -1039,7 +1034,7 @@ static int sm501_gpio_register_chip(struct sm501_devdata *sm,
|
|||
gchip->base = base;
|
||||
chip->ourgpio = gpio;
|
||||
|
||||
return gpiochip_add(gchip);
|
||||
return gpiochip_add_data(gchip, chip);
|
||||
}
|
||||
|
||||
static int sm501_register_gpio(struct sm501_devdata *sm)
|
||||
|
|
|
@ -80,15 +80,6 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int smsc_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct smsc *smsc = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(smsc->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id smsc_i2c_id[] = {
|
||||
{ "smscece1099", 0},
|
||||
{},
|
||||
|
@ -100,7 +91,6 @@ static struct i2c_driver smsc_i2c_driver = {
|
|||
.name = "smsc",
|
||||
},
|
||||
.probe = smsc_i2c_probe,
|
||||
.remove = smsc_i2c_remove,
|
||||
.id_table = smsc_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -206,8 +206,8 @@ static int stw481x_probe(struct i2c_client *client,
|
|||
stw481x_cells[i].pdata_size = sizeof(*stw481x);
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&client->dev, 0, stw481x_cells,
|
||||
ARRAY_SIZE(stw481x_cells), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&client->dev, 0, stw481x_cells,
|
||||
ARRAY_SIZE(stw481x_cells), NULL, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -216,12 +216,6 @@ static int stw481x_probe(struct i2c_client *client,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int stw481x_remove(struct i2c_client *client)
|
||||
{
|
||||
mfd_remove_devices(&client->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This ID table is completely unused, as this is a pure
|
||||
* device-tree probed driver, but it has to be here due to
|
||||
|
@ -246,7 +240,6 @@ static struct i2c_driver stw481x_driver = {
|
|||
.of_match_table = stw481x_match,
|
||||
},
|
||||
.probe = stw481x_probe,
|
||||
.remove = stw481x_remove,
|
||||
.id_table = stw481x_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/tmio.h>
|
||||
#include <linux/mfd/tc6393xb.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define SCR_REVID 0x08 /* b Revision ID */
|
||||
|
@ -434,7 +434,7 @@ static struct mfd_cell tc6393xb_cells[] = {
|
|||
static int tc6393xb_gpio_get(struct gpio_chip *chip,
|
||||
unsigned offset)
|
||||
{
|
||||
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||
struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
|
||||
|
||||
/* XXX: does dsr also represent inputs? */
|
||||
return !!(tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
|
||||
|
@ -444,7 +444,7 @@ static int tc6393xb_gpio_get(struct gpio_chip *chip,
|
|||
static void __tc6393xb_gpio_set(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||
struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
|
||||
u8 dsr;
|
||||
|
||||
dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
|
||||
|
@ -459,7 +459,7 @@ static void __tc6393xb_gpio_set(struct gpio_chip *chip,
|
|||
static void tc6393xb_gpio_set(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||
struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tc6393xb->lock, flags);
|
||||
|
@ -472,7 +472,7 @@ static void tc6393xb_gpio_set(struct gpio_chip *chip,
|
|||
static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
|
||||
unsigned offset)
|
||||
{
|
||||
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||
struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
u8 doecr;
|
||||
|
||||
|
@ -490,7 +490,7 @@ static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
|
|||
static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
|
||||
struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
u8 doecr;
|
||||
|
||||
|
@ -517,7 +517,7 @@ static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
|
|||
tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input;
|
||||
tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output;
|
||||
|
||||
return gpiochip_add(&tc6393xb->gpio);
|
||||
return gpiochip_add_data(&tc6393xb->gpio, tc6393xb);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/tps6105x.h>
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include <linux/i2c/tps65010.h>
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -477,7 +477,7 @@ tps65010_output(struct gpio_chip *chip, unsigned offset, int value)
|
|||
if (offset < 4) {
|
||||
struct tps65010 *tps;
|
||||
|
||||
tps = container_of(chip, struct tps65010, chip);
|
||||
tps = gpiochip_get_data(chip);
|
||||
if (!(tps->outmask & (1 << offset)))
|
||||
return -EINVAL;
|
||||
tps65010_set_gpio_out_value(offset + 1, value);
|
||||
|
@ -494,7 +494,7 @@ static int tps65010_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|||
int value;
|
||||
struct tps65010 *tps;
|
||||
|
||||
tps = container_of(chip, struct tps65010, chip);
|
||||
tps = gpiochip_get_data(chip);
|
||||
|
||||
if (offset < 4) {
|
||||
value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO);
|
||||
|
@ -651,7 +651,7 @@ static int tps65010_probe(struct i2c_client *client,
|
|||
tps->chip.ngpio = 7;
|
||||
tps->chip.can_sleep = 1;
|
||||
|
||||
status = gpiochip_add(&tps->chip);
|
||||
status = gpiochip_add_data(&tps->chip, tps);
|
||||
if (status < 0)
|
||||
dev_err(&client->dev, "can't add gpiochip, err %d\n",
|
||||
status);
|
||||
|
|
|
@ -100,16 +100,8 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c,
|
|||
tps6507x->read_dev = tps6507x_i2c_read_device;
|
||||
tps6507x->write_dev = tps6507x_i2c_write_device;
|
||||
|
||||
return mfd_add_devices(tps6507x->dev, -1, tps6507x_devs,
|
||||
ARRAY_SIZE(tps6507x_devs), NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static int tps6507x_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct tps6507x_dev *tps6507x = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(tps6507x->dev);
|
||||
return 0;
|
||||
return devm_mfd_add_devices(tps6507x->dev, -1, tps6507x_devs,
|
||||
ARRAY_SIZE(tps6507x_devs), NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps6507x_i2c_id[] = {
|
||||
|
@ -132,7 +124,6 @@ static struct i2c_driver tps6507x_i2c_driver = {
|
|||
.of_match_table = of_match_ptr(tps6507x_of_match),
|
||||
},
|
||||
.probe = tps6507x_i2c_probe,
|
||||
.remove = tps6507x_i2c_remove,
|
||||
.id_table = tps6507x_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -205,8 +205,8 @@ static int tps65217_probe(struct i2c_client *client,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(tps->dev, -1, tps65217s,
|
||||
ARRAY_SIZE(tps65217s), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(tps->dev, -1, tps65217s,
|
||||
ARRAY_SIZE(tps65217s), NULL, 0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -235,15 +235,6 @@ static int tps65217_probe(struct i2c_client *client,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tps65217_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tps65217 *tps = i2c_get_clientdata(client);
|
||||
|
||||
mfd_remove_devices(tps->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps65217_id_table[] = {
|
||||
{"tps65217", TPS65217},
|
||||
{ /* sentinel */ }
|
||||
|
@ -257,7 +248,6 @@ static struct i2c_driver tps65217_driver = {
|
|||
},
|
||||
.id_table = tps65217_id_table,
|
||||
.probe = tps65217_probe,
|
||||
.remove = tps65217_remove,
|
||||
};
|
||||
|
||||
static int __init tps65217_init(void)
|
||||
|
|
|
@ -252,9 +252,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
|
|||
}
|
||||
|
||||
tps65910->chip_irq = irq;
|
||||
ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
|
||||
IRQF_ONESHOT, pdata->irq_base,
|
||||
tps6591x_irqs_chip, &tps65910->irq_data);
|
||||
ret = devm_regmap_add_irq_chip(tps65910->dev, tps65910->regmap,
|
||||
tps65910->chip_irq,
|
||||
IRQF_ONESHOT, pdata->irq_base,
|
||||
tps6591x_irqs_chip, &tps65910->irq_data);
|
||||
if (ret < 0) {
|
||||
dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
|
||||
tps65910->chip_irq = 0;
|
||||
|
@ -262,13 +263,6 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int tps65910_irq_exit(struct tps65910 *tps65910)
|
||||
{
|
||||
if (tps65910->chip_irq > 0)
|
||||
regmap_del_irq_chip(tps65910->chip_irq, tps65910->irq_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
struct tps65910 *tps65910 = dev_get_drvdata(dev);
|
||||
|
@ -510,29 +504,18 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
|
|||
pm_power_off = tps65910_power_off;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(tps65910->dev, -1,
|
||||
tps65910s, ARRAY_SIZE(tps65910s),
|
||||
NULL, 0,
|
||||
regmap_irq_get_domain(tps65910->irq_data));
|
||||
ret = devm_mfd_add_devices(tps65910->dev, -1,
|
||||
tps65910s, ARRAY_SIZE(tps65910s),
|
||||
NULL, 0,
|
||||
regmap_irq_get_domain(tps65910->irq_data));
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
|
||||
tps65910_irq_exit(tps65910);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tps65910_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
|
||||
|
||||
tps65910_irq_exit(tps65910);
|
||||
mfd_remove_devices(tps65910->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps65910_i2c_id[] = {
|
||||
{ "tps65910", TPS65910 },
|
||||
{ "tps65911", TPS65911 },
|
||||
|
@ -547,7 +530,6 @@ static struct i2c_driver tps65910_i2c_driver = {
|
|||
.of_match_table = of_match_ptr(tps65910_of_match),
|
||||
},
|
||||
.probe = tps65910_i2c_probe,
|
||||
.remove = tps65910_i2c_remove,
|
||||
.id_table = tps65910_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/i2c/chips/twl4030-power.c
|
||||
*
|
||||
* Handle TWL4030 Power initialization
|
||||
*
|
||||
|
|
|
@ -291,7 +291,11 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
|||
if (twl6040->power_count++)
|
||||
goto out;
|
||||
|
||||
clk_prepare_enable(twl6040->clk32k);
|
||||
ret = clk_prepare_enable(twl6040->clk32k);
|
||||
if (ret) {
|
||||
twl6040->power_count = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Allow writes to the chip */
|
||||
regcache_cache_only(twl6040->regmap, false);
|
||||
|
@ -300,6 +304,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
|||
/* use automatic power-up sequence */
|
||||
ret = twl6040_power_up_automatic(twl6040);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(twl6040->clk32k);
|
||||
twl6040->power_count = 0;
|
||||
goto out;
|
||||
}
|
||||
|
@ -307,6 +312,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
|||
/* use manual power-up sequence */
|
||||
ret = twl6040_power_up_manual(twl6040);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(twl6040->clk32k);
|
||||
twl6040->power_count = 0;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/mfd/ucb1x00.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
static DEFINE_MUTEX(ucb1x00_mutex);
|
||||
static LIST_HEAD(ucb1x00_drivers);
|
||||
|
@ -109,7 +109,7 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
|
|||
|
||||
static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
|
||||
struct ucb1x00 *ucb = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ucb->io_lock, flags);
|
||||
|
@ -126,7 +126,7 @@ static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|||
|
||||
static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
|
||||
struct ucb1x00 *ucb = gpiochip_get_data(chip);
|
||||
unsigned val;
|
||||
|
||||
ucb1x00_enable(ucb);
|
||||
|
@ -138,7 +138,7 @@ static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|||
|
||||
static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
|
||||
struct ucb1x00 *ucb = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ucb->io_lock, flags);
|
||||
|
@ -154,7 +154,7 @@ static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
|||
static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
|
||||
, int value)
|
||||
{
|
||||
struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
|
||||
struct ucb1x00 *ucb = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
unsigned old, mask = 1 << offset;
|
||||
|
||||
|
@ -181,7 +181,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
|
|||
|
||||
static int ucb1x00_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
|
||||
struct ucb1x00 *ucb = gpiochip_get_data(chip);
|
||||
|
||||
return ucb->irq_base > 0 ? ucb->irq_base + offset : -ENXIO;
|
||||
}
|
||||
|
@ -579,7 +579,7 @@ static int ucb1x00_probe(struct mcp *mcp)
|
|||
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(&ucb->gpio);
|
||||
ret = gpiochip_add_data(&ucb->gpio, ucb);
|
||||
if (ret)
|
||||
goto err_gpio_add;
|
||||
} else
|
||||
|
|
|
@ -202,7 +202,7 @@ static int vexpress_sysreg_probe(struct platform_device *pdev)
|
|||
bgpio_init(mmc_gpio_chip, &pdev->dev, 0x4, base + SYS_MCI,
|
||||
NULL, NULL, NULL, NULL, 0);
|
||||
mmc_gpio_chip->ngpio = 2;
|
||||
gpiochip_add(mmc_gpio_chip);
|
||||
gpiochip_add_data(mmc_gpio_chip, NULL);
|
||||
|
||||
return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
|
||||
vexpress_sysreg_cells,
|
||||
|
|
|
@ -170,15 +170,6 @@ static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wl1273_core_remove(struct i2c_client *client)
|
||||
{
|
||||
dev_dbg(&client->dev, "%s\n", __func__);
|
||||
|
||||
mfd_remove_devices(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wl1273_core_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -237,8 +228,8 @@ static int wl1273_core_probe(struct i2c_client *client,
|
|||
dev_dbg(&client->dev, "%s: number of children: %d.\n",
|
||||
__func__, children);
|
||||
|
||||
r = mfd_add_devices(&client->dev, -1, core->cells,
|
||||
children, NULL, 0, NULL);
|
||||
r = devm_mfd_add_devices(&client->dev, -1, core->cells,
|
||||
children, NULL, 0, NULL);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
@ -258,7 +249,6 @@ static struct i2c_driver wl1273_core_driver = {
|
|||
},
|
||||
.probe = wl1273_core_probe,
|
||||
.id_table = wl1273_driver_id_table,
|
||||
.remove = wl1273_core_remove,
|
||||
};
|
||||
|
||||
static int __init wl1273_core_init(void)
|
||||
|
|
|
@ -3066,6 +3066,7 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
|
|||
case ARIZONA_AOD_IRQ_RAW_STATUS:
|
||||
case ARIZONA_FX_CTRL2:
|
||||
case ARIZONA_ASRC_STATUS:
|
||||
case ARIZONA_CLOCK_CONTROL:
|
||||
case ARIZONA_DSP_STATUS:
|
||||
case ARIZONA_DSP1_STATUS_1:
|
||||
case ARIZONA_DSP1_STATUS_2:
|
||||
|
|
|
@ -35,27 +35,6 @@ static bool wm8400_volatile(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wm8400_reg_read - Single register read
|
||||
*
|
||||
* @wm8400: Pointer to wm8400 control structure
|
||||
* @reg: Register to read
|
||||
*
|
||||
* @return Read value
|
||||
*/
|
||||
u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(wm8400->regmap, reg, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wm8400_reg_read);
|
||||
|
||||
int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data)
|
||||
{
|
||||
return regmap_bulk_read(wm8400->regmap, reg, data, count);
|
||||
|
@ -70,7 +49,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400)
|
|||
.pdata_size = sizeof(*wm8400),
|
||||
};
|
||||
|
||||
return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL);
|
||||
return devm_mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -111,7 +90,7 @@ static int wm8400_init(struct wm8400 *wm8400,
|
|||
ret = wm8400_register_codec(wm8400);
|
||||
if (ret != 0) {
|
||||
dev_err(wm8400->dev, "Failed to register codec\n");
|
||||
goto err_children;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pdata && pdata->platform_init) {
|
||||
|
@ -119,21 +98,12 @@ static int wm8400_init(struct wm8400 *wm8400,
|
|||
if (ret != 0) {
|
||||
dev_err(wm8400->dev, "Platform init failed: %d\n",
|
||||
ret);
|
||||
goto err_children;
|
||||
return ret;
|
||||
}
|
||||
} else
|
||||
dev_warn(wm8400->dev, "No platform initialisation supplied\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err_children:
|
||||
mfd_remove_devices(wm8400->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wm8400_release(struct wm8400 *wm8400)
|
||||
{
|
||||
mfd_remove_devices(wm8400->dev);
|
||||
}
|
||||
|
||||
static const struct regmap_config wm8400_regmap_config = {
|
||||
|
@ -156,7 +126,7 @@ void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache);
|
||||
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
#if IS_ENABLED(CONFIG_I2C)
|
||||
static int wm8400_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -176,15 +146,6 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
|
|||
return wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
|
||||
}
|
||||
|
||||
static int wm8400_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct wm8400 *wm8400 = i2c_get_clientdata(i2c);
|
||||
|
||||
wm8400_release(wm8400);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id wm8400_i2c_id[] = {
|
||||
{ "wm8400", 0 },
|
||||
{ }
|
||||
|
@ -196,7 +157,6 @@ static struct i2c_driver wm8400_i2c_driver = {
|
|||
.name = "WM8400",
|
||||
},
|
||||
.probe = wm8400_i2c_probe,
|
||||
.remove = wm8400_i2c_remove,
|
||||
.id_table = wm8400_i2c_id,
|
||||
};
|
||||
#endif
|
||||
|
@ -205,7 +165,7 @@ static int __init wm8400_module_init(void)
|
|||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
#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);
|
||||
|
@ -217,7 +177,7 @@ subsys_initcall(wm8400_module_init);
|
|||
|
||||
static void __exit wm8400_module_exit(void)
|
||||
{
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
#if IS_ENABLED(CONFIG_I2C)
|
||||
i2c_del_driver(&wm8400_i2c_driver);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -110,4 +110,9 @@
|
|||
#define ARIZONA_ACCDET_MODE_HPM 4
|
||||
#define ARIZONA_ACCDET_MODE_ADC 7
|
||||
|
||||
#define ARIZONA_GPSW_OPEN 0
|
||||
#define ARIZONA_GPSW_CLOSED 1
|
||||
#define ARIZONA_GPSW_CLAMP_ENABLED 2
|
||||
#define ARIZONA_GPSW_CLAMP_DISABLED 3
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This header provides macros for MAXIM MAX77620 device bindings.
|
||||
*
|
||||
* Copyright (c) 2016, NVIDIA Corporation.
|
||||
* Author: Laxman Dewangan <ldewangan@nvidia.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_MFD_MAX77620_H
|
||||
#define _DT_BINDINGS_MFD_MAX77620_H
|
||||
|
||||
/* MAX77620 interrupts */
|
||||
#define MAX77620_IRQ_TOP_GLBL 0 /* Low-Battery */
|
||||
#define MAX77620_IRQ_TOP_SD 1 /* SD power fail */
|
||||
#define MAX77620_IRQ_TOP_LDO 2 /* LDO power fail */
|
||||
#define MAX77620_IRQ_TOP_GPIO 3 /* GPIO internal int to MAX77620 */
|
||||
#define MAX77620_IRQ_TOP_RTC 4 /* RTC */
|
||||
#define MAX77620_IRQ_TOP_32K 5 /* 32kHz oscillator */
|
||||
#define MAX77620_IRQ_TOP_ONOFF 6 /* ON/OFF oscillator */
|
||||
#define MAX77620_IRQ_LBT_MBATLOW 7 /* Thermal alarm status, > 120C */
|
||||
#define MAX77620_IRQ_LBT_TJALRM1 8 /* Thermal alarm status, > 120C */
|
||||
#define MAX77620_IRQ_LBT_TJALRM2 9 /* Thermal alarm status, > 140C */
|
||||
|
||||
/* FPS event source */
|
||||
#define MAX77620_FPS_EVENT_SRC_EN0 0
|
||||
#define MAX77620_FPS_EVENT_SRC_EN1 1
|
||||
#define MAX77620_FPS_EVENT_SRC_SW 2
|
||||
|
||||
/* Device state when FPS event LOW */
|
||||
#define MAX77620_FPS_INACTIVE_STATE_SLEEP 0
|
||||
#define MAX77620_FPS_INACTIVE_STATE_LOW_POWER 1
|
||||
|
||||
/* FPS source */
|
||||
#define MAX77620_FPS_SRC_0 0
|
||||
#define MAX77620_FPS_SRC_1 1
|
||||
#define MAX77620_FPS_SRC_2 2
|
||||
#define MAX77620_FPS_SRC_NONE 3
|
||||
#define MAX77620_FPS_SRC_DEF 4
|
||||
|
||||
#endif
|
|
@ -20,6 +20,7 @@ enum {
|
|||
AXP221_ID,
|
||||
AXP223_ID,
|
||||
AXP288_ID,
|
||||
AXP809_ID,
|
||||
NR_AXP20X_VARIANTS,
|
||||
};
|
||||
|
||||
|
@ -264,6 +265,29 @@ enum {
|
|||
AXP22X_REG_ID_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AXP809_DCDC1 = 0,
|
||||
AXP809_DCDC2,
|
||||
AXP809_DCDC3,
|
||||
AXP809_DCDC4,
|
||||
AXP809_DCDC5,
|
||||
AXP809_DC1SW,
|
||||
AXP809_DC5LDO,
|
||||
AXP809_ALDO1,
|
||||
AXP809_ALDO2,
|
||||
AXP809_ALDO3,
|
||||
AXP809_ELDO1,
|
||||
AXP809_ELDO2,
|
||||
AXP809_ELDO3,
|
||||
AXP809_DLDO1,
|
||||
AXP809_DLDO2,
|
||||
AXP809_RTC_LDO,
|
||||
AXP809_LDO_IO0,
|
||||
AXP809_LDO_IO1,
|
||||
AXP809_SW,
|
||||
AXP809_REG_ID_MAX,
|
||||
};
|
||||
|
||||
/* IRQs */
|
||||
enum {
|
||||
AXP152_IRQ_LDO0IN_CONNECT = 1,
|
||||
|
@ -390,6 +414,41 @@ enum axp288_irqs {
|
|||
AXP288_IRQ_BC_USB_CHNG,
|
||||
};
|
||||
|
||||
enum axp809_irqs {
|
||||
AXP809_IRQ_ACIN_OVER_V = 1,
|
||||
AXP809_IRQ_ACIN_PLUGIN,
|
||||
AXP809_IRQ_ACIN_REMOVAL,
|
||||
AXP809_IRQ_VBUS_OVER_V,
|
||||
AXP809_IRQ_VBUS_PLUGIN,
|
||||
AXP809_IRQ_VBUS_REMOVAL,
|
||||
AXP809_IRQ_VBUS_V_LOW,
|
||||
AXP809_IRQ_BATT_PLUGIN,
|
||||
AXP809_IRQ_BATT_REMOVAL,
|
||||
AXP809_IRQ_BATT_ENT_ACT_MODE,
|
||||
AXP809_IRQ_BATT_EXIT_ACT_MODE,
|
||||
AXP809_IRQ_CHARG,
|
||||
AXP809_IRQ_CHARG_DONE,
|
||||
AXP809_IRQ_BATT_CHG_TEMP_HIGH,
|
||||
AXP809_IRQ_BATT_CHG_TEMP_HIGH_END,
|
||||
AXP809_IRQ_BATT_CHG_TEMP_LOW,
|
||||
AXP809_IRQ_BATT_CHG_TEMP_LOW_END,
|
||||
AXP809_IRQ_BATT_ACT_TEMP_HIGH,
|
||||
AXP809_IRQ_BATT_ACT_TEMP_HIGH_END,
|
||||
AXP809_IRQ_BATT_ACT_TEMP_LOW,
|
||||
AXP809_IRQ_BATT_ACT_TEMP_LOW_END,
|
||||
AXP809_IRQ_DIE_TEMP_HIGH,
|
||||
AXP809_IRQ_LOW_PWR_LVL1,
|
||||
AXP809_IRQ_LOW_PWR_LVL2,
|
||||
AXP809_IRQ_TIMER,
|
||||
AXP809_IRQ_PEK_RIS_EDGE,
|
||||
AXP809_IRQ_PEK_FAL_EDGE,
|
||||
AXP809_IRQ_PEK_SHORT,
|
||||
AXP809_IRQ_PEK_LONG,
|
||||
AXP809_IRQ_PEK_OVER_OFF,
|
||||
AXP809_IRQ_GPIO1_INPUT,
|
||||
AXP809_IRQ_GPIO0_INPUT,
|
||||
};
|
||||
|
||||
#define AXP288_TS_ADC_H 0x58
|
||||
#define AXP288_TS_ADC_L 0x59
|
||||
#define AXP288_GP_ADC_H 0x5a
|
||||
|
|
|
@ -131,4 +131,8 @@ static inline int mfd_add_hotplug_devices(struct device *parent,
|
|||
|
||||
extern void mfd_remove_devices(struct device *parent);
|
||||
|
||||
extern int devm_mfd_add_devices(struct device *dev, int id,
|
||||
const struct mfd_cell *cells, int n_devs,
|
||||
struct resource *mem_base,
|
||||
int irq_base, struct irq_domain *irq_domain);
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Device driver for regulators in hi655x IC
|
||||
*
|
||||
* Copyright (c) 2016 Hisilicon.
|
||||
*
|
||||
* Authors:
|
||||
* Chen Feng <puck.chen@hisilicon.com>
|
||||
* Fei Wang <w.f@huawei.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __HI655X_PMIC_H
|
||||
#define __HI655X_PMIC_H
|
||||
|
||||
/* Hi655x registers are mapped to memory bus in 4 bytes stride */
|
||||
#define HI655X_STRIDE 4
|
||||
#define HI655X_BUS_ADDR(x) ((x) << 2)
|
||||
|
||||
#define HI655X_BITS 8
|
||||
|
||||
#define HI655X_NR_IRQ 32
|
||||
|
||||
#define HI655X_IRQ_STAT_BASE (0x003 << 2)
|
||||
#define HI655X_IRQ_MASK_BASE (0x007 << 2)
|
||||
#define HI655X_ANA_IRQM_BASE (0x1b5 << 2)
|
||||
#define HI655X_IRQ_ARRAY 4
|
||||
#define HI655X_IRQ_MASK 0xFF
|
||||
#define HI655X_IRQ_CLR 0xFF
|
||||
#define HI655X_VER_REG 0x00
|
||||
|
||||
#define PMU_VER_START 0x10
|
||||
#define PMU_VER_END 0x38
|
||||
|
||||
#define RESERVE_INT BIT(7)
|
||||
#define PWRON_D20R_INT BIT(6)
|
||||
#define PWRON_D20F_INT BIT(5)
|
||||
#define PWRON_D4SR_INT BIT(4)
|
||||
#define VSYS_6P0_D200UR_INT BIT(3)
|
||||
#define VSYS_UV_D3R_INT BIT(2)
|
||||
#define VSYS_2P5_R_INT BIT(1)
|
||||
#define OTMP_D1R_INT BIT(0)
|
||||
|
||||
struct hi655x_pmic {
|
||||
struct resource *res;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
int gpio;
|
||||
unsigned int ver;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* Defining registers address and its bit definitions of MAX77620 and MAX20024
|
||||
*
|
||||
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _MFD_MAX77620_H_
|
||||
#define _MFD_MAX77620_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
|
||||
#define MAX77620_REG_CNFGGLBL1 0x00
|
||||
#define MAX77620_REG_CNFGGLBL2 0x01
|
||||
#define MAX77620_REG_CNFGGLBL3 0x02
|
||||
#define MAX77620_REG_CNFG1_32K 0x03
|
||||
#define MAX77620_REG_CNFGBBC 0x04
|
||||
#define MAX77620_REG_IRQTOP 0x05
|
||||
#define MAX77620_REG_INTLBT 0x06
|
||||
#define MAX77620_REG_IRQSD 0x07
|
||||
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
|
||||
#define MAX77620_REG_IRQ_LVL2_L8 0x09
|
||||
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
|
||||
#define MAX77620_REG_ONOFFIRQ 0x0B
|
||||
#define MAX77620_REG_NVERC 0x0C
|
||||
#define MAX77620_REG_IRQTOPM 0x0D
|
||||
#define MAX77620_REG_INTENLBT 0x0E
|
||||
#define MAX77620_REG_IRQMASKSD 0x0F
|
||||
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
|
||||
#define MAX77620_REG_IRQ_MSK_L8 0x11
|
||||
#define MAX77620_REG_ONOFFIRQM 0x12
|
||||
#define MAX77620_REG_STATLBT 0x13
|
||||
#define MAX77620_REG_STATSD 0x14
|
||||
#define MAX77620_REG_ONOFFSTAT 0x15
|
||||
|
||||
/* SD and LDO Registers */
|
||||
#define MAX77620_REG_SD0 0x16
|
||||
#define MAX77620_REG_SD1 0x17
|
||||
#define MAX77620_REG_SD2 0x18
|
||||
#define MAX77620_REG_SD3 0x19
|
||||
#define MAX77620_REG_SD4 0x1A
|
||||
#define MAX77620_REG_DVSSD0 0x1B
|
||||
#define MAX77620_REG_DVSSD1 0x1C
|
||||
#define MAX77620_REG_SD0_CFG 0x1D
|
||||
#define MAX77620_REG_SD1_CFG 0x1E
|
||||
#define MAX77620_REG_SD2_CFG 0x1F
|
||||
#define MAX77620_REG_SD3_CFG 0x20
|
||||
#define MAX77620_REG_SD4_CFG 0x21
|
||||
#define MAX77620_REG_SD_CFG2 0x22
|
||||
#define MAX77620_REG_LDO0_CFG 0x23
|
||||
#define MAX77620_REG_LDO0_CFG2 0x24
|
||||
#define MAX77620_REG_LDO1_CFG 0x25
|
||||
#define MAX77620_REG_LDO1_CFG2 0x26
|
||||
#define MAX77620_REG_LDO2_CFG 0x27
|
||||
#define MAX77620_REG_LDO2_CFG2 0x28
|
||||
#define MAX77620_REG_LDO3_CFG 0x29
|
||||
#define MAX77620_REG_LDO3_CFG2 0x2A
|
||||
#define MAX77620_REG_LDO4_CFG 0x2B
|
||||
#define MAX77620_REG_LDO4_CFG2 0x2C
|
||||
#define MAX77620_REG_LDO5_CFG 0x2D
|
||||
#define MAX77620_REG_LDO5_CFG2 0x2E
|
||||
#define MAX77620_REG_LDO6_CFG 0x2F
|
||||
#define MAX77620_REG_LDO6_CFG2 0x30
|
||||
#define MAX77620_REG_LDO7_CFG 0x31
|
||||
#define MAX77620_REG_LDO7_CFG2 0x32
|
||||
#define MAX77620_REG_LDO8_CFG 0x33
|
||||
#define MAX77620_REG_LDO8_CFG2 0x34
|
||||
#define MAX77620_REG_LDO_CFG3 0x35
|
||||
|
||||
#define MAX77620_LDO_SLEW_RATE_MASK 0x1
|
||||
|
||||
/* LDO Configuration 3 */
|
||||
#define MAX77620_TRACK4_MASK BIT(5)
|
||||
#define MAX77620_TRACK4_SHIFT 5
|
||||
|
||||
/* Voltage */
|
||||
#define MAX77620_SDX_VOLT_MASK 0xFF
|
||||
#define MAX77620_SD0_VOLT_MASK 0x3F
|
||||
#define MAX77620_SD1_VOLT_MASK 0x7F
|
||||
#define MAX77620_LDO_VOLT_MASK 0x3F
|
||||
|
||||
#define MAX77620_REG_GPIO0 0x36
|
||||
#define MAX77620_REG_GPIO1 0x37
|
||||
#define MAX77620_REG_GPIO2 0x38
|
||||
#define MAX77620_REG_GPIO3 0x39
|
||||
#define MAX77620_REG_GPIO4 0x3A
|
||||
#define MAX77620_REG_GPIO5 0x3B
|
||||
#define MAX77620_REG_GPIO6 0x3C
|
||||
#define MAX77620_REG_GPIO7 0x3D
|
||||
#define MAX77620_REG_PUE_GPIO 0x3E
|
||||
#define MAX77620_REG_PDE_GPIO 0x3F
|
||||
#define MAX77620_REG_AME_GPIO 0x40
|
||||
#define MAX77620_REG_ONOFFCNFG1 0x41
|
||||
#define MAX77620_REG_ONOFFCNFG2 0x42
|
||||
|
||||
/* FPS Registers */
|
||||
#define MAX77620_REG_FPS_CFG0 0x43
|
||||
#define MAX77620_REG_FPS_CFG1 0x44
|
||||
#define MAX77620_REG_FPS_CFG2 0x45
|
||||
#define MAX77620_REG_FPS_LDO0 0x46
|
||||
#define MAX77620_REG_FPS_LDO1 0x47
|
||||
#define MAX77620_REG_FPS_LDO2 0x48
|
||||
#define MAX77620_REG_FPS_LDO3 0x49
|
||||
#define MAX77620_REG_FPS_LDO4 0x4A
|
||||
#define MAX77620_REG_FPS_LDO5 0x4B
|
||||
#define MAX77620_REG_FPS_LDO6 0x4C
|
||||
#define MAX77620_REG_FPS_LDO7 0x4D
|
||||
#define MAX77620_REG_FPS_LDO8 0x4E
|
||||
#define MAX77620_REG_FPS_SD0 0x4F
|
||||
#define MAX77620_REG_FPS_SD1 0x50
|
||||
#define MAX77620_REG_FPS_SD2 0x51
|
||||
#define MAX77620_REG_FPS_SD3 0x52
|
||||
#define MAX77620_REG_FPS_SD4 0x53
|
||||
#define MAX77620_REG_FPS_NONE 0
|
||||
|
||||
#define MAX77620_FPS_SRC_MASK 0xC0
|
||||
#define MAX77620_FPS_SRC_SHIFT 6
|
||||
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
|
||||
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
|
||||
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_EN_SRC_MASK 0x06
|
||||
#define MAX77620_FPS_EN_SRC_SHIFT 1
|
||||
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
|
||||
#define MAX77620_FPS_ENFPS_SW 0x01
|
||||
|
||||
/* Minimum and maximum FPS period time (in microseconds) are
|
||||
* different for MAX77620 and Max20024.
|
||||
*/
|
||||
#define MAX77620_FPS_PERIOD_MIN_US 40
|
||||
#define MAX20024_FPS_PERIOD_MIN_US 20
|
||||
|
||||
#define MAX77620_FPS_PERIOD_MAX_US 2560
|
||||
#define MAX20024_FPS_PERIOD_MAX_US 5120
|
||||
|
||||
#define MAX77620_REG_FPS_GPIO1 0x54
|
||||
#define MAX77620_REG_FPS_GPIO2 0x55
|
||||
#define MAX77620_REG_FPS_GPIO3 0x56
|
||||
#define MAX77620_REG_FPS_RSO 0x57
|
||||
#define MAX77620_REG_CID0 0x58
|
||||
#define MAX77620_REG_CID1 0x59
|
||||
#define MAX77620_REG_CID2 0x5A
|
||||
#define MAX77620_REG_CID3 0x5B
|
||||
#define MAX77620_REG_CID4 0x5C
|
||||
#define MAX77620_REG_CID5 0x5D
|
||||
|
||||
#define MAX77620_REG_DVSSD4 0x5E
|
||||
#define MAX20024_REG_MAX_ADD 0x70
|
||||
|
||||
#define MAX77620_CID_DIDM_MASK 0xF0
|
||||
#define MAX77620_CID_DIDM_SHIFT 4
|
||||
|
||||
/* CNCG2SD */
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD1 BIT(1)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD0 BIT(2)
|
||||
|
||||
/* Device Identification Metal */
|
||||
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
|
||||
/* Device Indentification OTP */
|
||||
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
|
||||
|
||||
/* SD CNFG1 */
|
||||
#define MAX77620_SD_SR_MASK 0xC0
|
||||
#define MAX77620_SD_SR_SHIFT 6
|
||||
#define MAX77620_SD_POWER_MODE_MASK 0x30
|
||||
#define MAX77620_SD_POWER_MODE_SHIFT 4
|
||||
#define MAX77620_SD_CFG1_ADE_MASK BIT(3)
|
||||
#define MAX77620_SD_CFG1_ADE_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_ADE_ENABLE BIT(3)
|
||||
#define MAX77620_SD_FPWM_MASK 0x04
|
||||
#define MAX77620_SD_FPWM_SHIFT 2
|
||||
#define MAX77620_SD_FSRADE_MASK 0x01
|
||||
#define MAX77620_SD_FSRADE_SHIFT 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2)
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0)
|
||||
|
||||
/* LDO_CNFG2 */
|
||||
#define MAX77620_LDO_POWER_MODE_MASK 0xC0
|
||||
#define MAX77620_LDO_POWER_MODE_SHIFT 6
|
||||
#define MAX77620_LDO_CFG2_ADE_MASK BIT(1)
|
||||
#define MAX77620_LDO_CFG2_ADE_DISABLE 0
|
||||
#define MAX77620_LDO_CFG2_ADE_ENABLE BIT(1)
|
||||
#define MAX77620_LDO_CFG2_SS_MASK BIT(0)
|
||||
#define MAX77620_LDO_CFG2_SS_FAST BIT(0)
|
||||
#define MAX77620_LDO_CFG2_SS_SLOW 0
|
||||
|
||||
#define MAX77620_IRQ_TOP_GLBL_MASK BIT(7)
|
||||
#define MAX77620_IRQ_TOP_SD_MASK BIT(6)
|
||||
#define MAX77620_IRQ_TOP_LDO_MASK BIT(5)
|
||||
#define MAX77620_IRQ_TOP_GPIO_MASK BIT(4)
|
||||
#define MAX77620_IRQ_TOP_RTC_MASK BIT(3)
|
||||
#define MAX77620_IRQ_TOP_32K_MASK BIT(2)
|
||||
#define MAX77620_IRQ_TOP_ONOFF_MASK BIT(1)
|
||||
|
||||
#define MAX77620_IRQ_LBM_MASK BIT(3)
|
||||
#define MAX77620_IRQ_TJALRM1_MASK BIT(2)
|
||||
#define MAX77620_IRQ_TJALRM2_MASK BIT(1)
|
||||
|
||||
#define MAX77620_PWR_I2C_ADDR 0x3c
|
||||
#define MAX77620_RTC_I2C_ADDR 0x68
|
||||
|
||||
#define MAX77620_CNFG_GPIO_DRV_MASK BIT(0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL BIT(0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
|
||||
#define MAX77620_CNFG_GPIO_DIR_MASK BIT(1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_INPUT BIT(1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
|
||||
#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK BIT(2)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK BIT(3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH BIT(3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
|
||||
#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
|
||||
#define MAX77620_CNFG_GPIO_INT_FALLING BIT(4)
|
||||
#define MAX77620_CNFG_GPIO_INT_RISING BIT(5)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
|
||||
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 BIT(0)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 BIT(1)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE2 BIT(2)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE3 BIT(3)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE4 BIT(4)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE5 BIT(5)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE6 BIT(6)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE7 BIT(7)
|
||||
|
||||
#define MAX77620_CNFG1_32K_OUT0_EN BIT(2)
|
||||
|
||||
#define MAX77620_ONOFFCNFG1_SFT_RST BIT(7)
|
||||
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
|
||||
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
|
||||
#define MAX77620_ONOFFCNFG1_SLPEN BIT(2)
|
||||
#define MAX77620_ONOFFCNFG1_PWR_OFF BIT(1)
|
||||
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
|
||||
|
||||
#define MAX77620_ONOFFCNFG2_SFT_RST_WK BIT(7)
|
||||
#define MAX77620_ONOFFCNFG2_WD_RST_WK BIT(6)
|
||||
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK BIT(5)
|
||||
#define MAX77620_ONOFFCNFG2_WK_ALARM1 BIT(2)
|
||||
#define MAX77620_ONOFFCNFG2_WK_EN0 BIT(0)
|
||||
|
||||
#define MAX77620_GLBLM_MASK BIT(0)
|
||||
|
||||
#define MAX77620_WDTC_MASK 0x3
|
||||
#define MAX77620_WDTOFFC BIT(4)
|
||||
#define MAX77620_WDTSLPC BIT(3)
|
||||
#define MAX77620_WDTEN BIT(2)
|
||||
|
||||
#define MAX77620_TWD_MASK 0x3
|
||||
#define MAX77620_TWD_2s 0x0
|
||||
#define MAX77620_TWD_16s 0x1
|
||||
#define MAX77620_TWD_64s 0x2
|
||||
#define MAX77620_TWD_128s 0x3
|
||||
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_EN BIT(7)
|
||||
#define MAX77620_CNFGGLBL1_MPPLD BIT(6)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST (BIT(5) | BIT(4))
|
||||
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
|
||||
#define MAX77620_CNFGGLBL1_LBRSTEN BIT(0)
|
||||
|
||||
/* CNFG BBC registers */
|
||||
#define MAX77620_CNFGBBC_ENABLE BIT(0)
|
||||
#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
|
||||
#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
|
||||
#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE BIT(5)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
|
||||
#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
|
||||
|
||||
#define MAX77620_FPS_COUNT 3
|
||||
|
||||
/* Interrupts */
|
||||
enum {
|
||||
MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
|
||||
MAX77620_IRQ_TOP_SD, /* SD power fail */
|
||||
MAX77620_IRQ_TOP_LDO, /* LDO power fail */
|
||||
MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
|
||||
MAX77620_IRQ_TOP_RTC, /* RTC */
|
||||
MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
|
||||
MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
|
||||
MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
|
||||
MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
|
||||
MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
|
||||
};
|
||||
|
||||
/* GPIOs */
|
||||
enum {
|
||||
MAX77620_GPIO0,
|
||||
MAX77620_GPIO1,
|
||||
MAX77620_GPIO2,
|
||||
MAX77620_GPIO3,
|
||||
MAX77620_GPIO4,
|
||||
MAX77620_GPIO5,
|
||||
MAX77620_GPIO6,
|
||||
MAX77620_GPIO7,
|
||||
MAX77620_GPIO_NR,
|
||||
};
|
||||
|
||||
/* FPS Source */
|
||||
enum max77620_fps_src {
|
||||
MAX77620_FPS_SRC_0,
|
||||
MAX77620_FPS_SRC_1,
|
||||
MAX77620_FPS_SRC_2,
|
||||
MAX77620_FPS_SRC_NONE,
|
||||
MAX77620_FPS_SRC_DEF,
|
||||
};
|
||||
|
||||
enum max77620_chip_id {
|
||||
MAX77620,
|
||||
MAX20024,
|
||||
};
|
||||
|
||||
struct max77620_chip {
|
||||
struct device *dev;
|
||||
struct regmap *rmap;
|
||||
|
||||
int chip_irq;
|
||||
int irq_base;
|
||||
|
||||
/* chip id */
|
||||
enum max77620_chip_id chip_id;
|
||||
|
||||
bool sleep_enable;
|
||||
bool enable_global_lpm;
|
||||
int shutdown_fps_period[MAX77620_FPS_COUNT];
|
||||
int suspend_fps_period[MAX77620_FPS_COUNT];
|
||||
|
||||
struct regmap_irq_chip_data *top_irq_data;
|
||||
struct regmap_irq_chip_data *gpio_irq_data;
|
||||
};
|
||||
|
||||
#endif /* _MFD_MAX77620_H_ */
|
|
@ -16,6 +16,7 @@
|
|||
#define __LINUX_MFD_SYSCON_H__
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
struct device_node;
|
||||
|
||||
|
|
|
@ -923,7 +923,6 @@ struct wm8400 {
|
|||
#define WM8400_LINE_CMP_VTHD_SHIFT 0 /* LINE_CMP_VTHD - [3:0] */
|
||||
#define WM8400_LINE_CMP_VTHD_WIDTH 4 /* LINE_CMP_VTHD - [3:0] */
|
||||
|
||||
u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg);
|
||||
int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data);
|
||||
|
||||
static inline int wm8400_set_bits(struct wm8400 *wm8400, u8 reg,
|
||||
|
|
Загрузка…
Ссылка в новой задаче