For the 3.13 merge window we have a couple of new drivers for the AMS
AS3722 PMIC and for STMicroelectronics STw481x PMIC. Although this is a smaller update than usual, we also have: - Device tree support for the max77693 driver. - linux/of.h inclusion for all DT compatible MFD drivers, to avoid build breakage in the future. - Support for Intel Wildcat Point-LP PCH through the lpc_ich driver. - A small arizona update for new wm5110 DSP registers and a few fixes. - A small palmas update as well, including an of_device table addition and a few minor fixes. - Two small mfd-core changes, one including a memory leak fix for when mfd_add_device() fails. - Our usual round of minor cleanups and janitorial fixes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.15 (GNU/Linux) iQIcBAABAgAGBQJShjufAAoJEIqAPN1PVmxKRoEP/jKe0UgrNA6G4xHSPX1Xcktc /kaQdcwJcTTHMpkIyQPFayItCcBPyb8bN1SdrQs4sds4ut7xyjve2uHz0KpZI6JO F+Rh6UVNkUIbcEx3jfh0DDv3pHv0vryFPnerkOIr0TFmSF1Tj29dRORQzpEqZ2fZ rstxmxNTG0ggP0Ug4ivv/YWjhGmO9CvKePJzQyImrC8QWCRDiARu072bG8xhVyHZ PkJTzJr2kjkI3whIY7Z04Nx90AtpikM4G27JiCwsHyv4vCCOtTtC9lRYb/IBUHWJ UhJiPvTygsU63opGOyAodR9LJxta0UCWm2Qn71ZuBAJmQ4oFxdZ7iVkWePjeSF5U 2Jx9dUi1UWJQNCSB8HEpaUExybXdsNTwnSw8NIb6Gg2kygClj5KvzPMwz3ZHRKU/ Ef1TGpWTeuok0zOijhBDUqAhq4KQv/H9Xjbm8FIMSBVGQgRBT3dkYTRZv30deeg/ SIzoJGg7QiMDwlu/33k7aX7aIwJA2r6st/Q3OUKp/aBVqd6i24rL5+ZMykqcx5HJ x9GnvjrHgz+nAgF2yU6KQT1FrX1IQEM4F1tgMtroXQcCAGgoWoJRjW82gQqp6NE+ eVbvsE56z2MiSNbiYUL4hdC03b/z8LbzP1zEt95Xc+sOf7NewMHYln7XkByBxrPH tlR20ZV44W25s7DYg7xh =nQ/p -----END PGP SIGNATURE----- Merge tag 'mfd-3.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next Pull MFD updates from Samuel Ortiz: "For the 3.13 merge window we have a couple of new drivers for the AMS AS3722 PMIC and for STMicroelectronics STw481x PMIC. Although this is a smaller update than usual, we also have: - Device tree support for the max77693 driver - linux/of.h inclusion for all DT compatible MFD drivers, to avoid build breakage in the future - Support for Intel Wildcat Point-LP PCH through the lpc_ich driver - A small arizona update for new wm5110 DSP registers and a few fixes - A small palmas update as well, including an of_device table addition and a few minor fixes - Two small mfd-core changes, one including a memory leak fix for when mfd_add_device() fails - Our usual round of minor cleanups and janitorial fixes" * tag 'mfd-3.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next: (63 commits) Documentation: mfd: Update s2mps11.txt mfd: pm8921: Potential NULL dereference in pm8921_remove() mfd: Fix memory leak in mfd_add_devices() mfd: Stop setting refcounting pointers in original mfd_cell arrays mfd: wm5110: Enable micd clamp functionality mfd: lpc_ich: Add Device IDs for Intel Wildcat Point-LP PCH mfd: max77693: Fix up bug of wrong interrupt number mfd: as3722: Don't export the regmap config mfd: twl6040: Remove obsolete cleanup for i2c clientdata mfd: tps65910: Remove warning during dt node parsing mfd: lpc_sch: Ignore resource conflicts when adding mfd cells mfd: ti_am335x_tscadc: Avoid possible deadlock of reg_lock mfd: syscon: Return -ENOSYS if CONFIG_MFD_SYSCON is not enabled mfd: Add support for ams AS3722 PMIC mfd: max77693: Include linux/of.h header mfd: tc3589x: Detect the precise version mfd: omap-usb: prepare/unprepare clock while enable/disable mfd: max77686: Include linux/of.h header mfd: max8907: Include linux/of.h header mfd: max8997: Include linux/of.h header ...
This commit is contained in:
commit
db0b2d0116
57 changed files with 1869 additions and 233 deletions
194
Documentation/devicetree/bindings/mfd/as3722.txt
Normal file
194
Documentation/devicetree/bindings/mfd/as3722.txt
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
* ams AS3722 Power management IC.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
-------------------
|
||||||
|
- compatible: Must be "ams,as3722".
|
||||||
|
- reg: I2C device address.
|
||||||
|
- interrupt-controller: AS3722 has internal interrupt controller which takes the
|
||||||
|
interrupt request from internal sub-blocks like RTC, regulators, GPIOs as well
|
||||||
|
as external input.
|
||||||
|
- #interrupt-cells: Should be set to 2 for IRQ number and flags.
|
||||||
|
The first cell is the IRQ number. IRQ numbers for different interrupt source
|
||||||
|
of AS3722 are defined at dt-bindings/mfd/as3722.h
|
||||||
|
The second cell is the flags, encoded as the trigger masks from binding document
|
||||||
|
interrupts.txt, using dt-bindings/irq.
|
||||||
|
|
||||||
|
Optional submodule and their properties:
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
Pinmux and GPIO:
|
||||||
|
===============
|
||||||
|
Device has 8 GPIO pins which can be configured as GPIO as well as the special IO
|
||||||
|
functions.
|
||||||
|
|
||||||
|
Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||||
|
common pinctrl bindings used by client devices, including the meaning of the
|
||||||
|
phrase "pin configuration node".
|
||||||
|
|
||||||
|
Following are properties which is needed if GPIO and pinmux functionality
|
||||||
|
is required:
|
||||||
|
Required properties:
|
||||||
|
-------------------
|
||||||
|
- gpio-controller: Marks the device node as a GPIO controller.
|
||||||
|
- #gpio-cells: Number of GPIO cells. Refer to binding document
|
||||||
|
gpio/gpio.txt
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
--------------------
|
||||||
|
Following properties are require if pin control setting is required
|
||||||
|
at boot.
|
||||||
|
- pinctrl-names: A pinctrl state named "default" be defined, using the
|
||||||
|
bindings in pinctrl/pinctrl-binding.txt.
|
||||||
|
- pinctrl[0...n]: Properties to contain the phandle that refer to
|
||||||
|
different nodes of pin control settings. These nodes represents
|
||||||
|
the pin control setting of state 0 to state n. Each of these
|
||||||
|
nodes contains different subnodes to represents some desired
|
||||||
|
configuration for a list of pins. This configuration can
|
||||||
|
include the mux function to select on those pin(s), and
|
||||||
|
various pin configuration parameters, such as pull-up,
|
||||||
|
open drain.
|
||||||
|
|
||||||
|
Each subnode have following properties:
|
||||||
|
Required properties:
|
||||||
|
- pins: List of pins. Valid values of pins properties are:
|
||||||
|
gpio0, gpio1, gpio2, gpio3, gpio4, gpio5,
|
||||||
|
gpio6, gpio7
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
function, bias-disable, bias-pull-up, bias-pull-down,
|
||||||
|
bias-high-impedance, drive-open-drain.
|
||||||
|
|
||||||
|
Valid values for function properties are:
|
||||||
|
gpio, interrupt-out, gpio-in-interrupt,
|
||||||
|
vsup-vbat-low-undebounce-out,
|
||||||
|
vsup-vbat-low-debounce-out,
|
||||||
|
voltage-in-standby, oc-pg-sd0, oc-pg-sd6,
|
||||||
|
powergood-out, pwm-in, pwm-out, clk32k-out,
|
||||||
|
watchdog-in, soft-reset-in
|
||||||
|
|
||||||
|
Regulators:
|
||||||
|
===========
|
||||||
|
Device has multiple DCDC and LDOs. The node "regulators" is require if regulator
|
||||||
|
functionality is needed.
|
||||||
|
|
||||||
|
Following are properties of regulator subnode.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
-------------------
|
||||||
|
The input supply of regulators are the optional properties on the
|
||||||
|
regulator node. The input supply of these regulators are provided
|
||||||
|
through following properties:
|
||||||
|
vsup-sd2-supply: Input supply for SD2.
|
||||||
|
vsup-sd3-supply: Input supply for SD3.
|
||||||
|
vsup-sd4-supply: Input supply for SD4.
|
||||||
|
vsup-sd5-supply: Input supply for SD5.
|
||||||
|
vin-ldo0-supply: Input supply for LDO0.
|
||||||
|
vin-ldo1-6-supply: Input supply for LDO1 and LDO6.
|
||||||
|
vin-ldo2-5-7-supply: Input supply for LDO2, LDO5 and LDO7.
|
||||||
|
vin-ldo3-4-supply: Input supply for LDO3 and LDO4.
|
||||||
|
vin-ldo9-10-supply: Input supply for LDO9 and LDO10.
|
||||||
|
vin-ldo11-supply: Input supply for LDO11.
|
||||||
|
|
||||||
|
Optional sub nodes for regulators:
|
||||||
|
---------------------------------
|
||||||
|
The subnodes name is the name of regulator and it must be one of:
|
||||||
|
sd[0-6], ldo[0-7], ldo[9-11]
|
||||||
|
|
||||||
|
Each sub-node should contain the constraints and initialization
|
||||||
|
information for that regulator. See regulator.txt for a description
|
||||||
|
of standard properties for these sub-nodes.
|
||||||
|
Additional optional custom properties are listed below.
|
||||||
|
ams,ext-control: External control of the rail. The option of
|
||||||
|
this properties will tell which external input is
|
||||||
|
controlling this rail. Valid values are 0, 1, 2 ad 3.
|
||||||
|
0: There is no external control of this rail.
|
||||||
|
1: Rail is controlled by ENABLE1 input pin.
|
||||||
|
2: Rail is controlled by ENABLE2 input pin.
|
||||||
|
3: Rail is controlled by ENABLE3 input pin.
|
||||||
|
Missing this property on DT will be assume as no
|
||||||
|
external control. The external control pin macros
|
||||||
|
are defined @dt-bindings/mfd/as3722.h
|
||||||
|
|
||||||
|
ams,enable-tracking: Enable tracking with SD1, only supported
|
||||||
|
by LDO3.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
--------
|
||||||
|
#include <dt-bindings/mfd/as3722.h>
|
||||||
|
...
|
||||||
|
ams3722 {
|
||||||
|
compatible = "ams,as3722";
|
||||||
|
reg = <0x48>;
|
||||||
|
|
||||||
|
interrupt-parent = <&intc>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&as3722_default>;
|
||||||
|
|
||||||
|
as3722_default: pinmux {
|
||||||
|
gpio0 {
|
||||||
|
pins = "gpio0";
|
||||||
|
function = "gpio";
|
||||||
|
bias-pull-down;
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio1_2_4_7 {
|
||||||
|
pins = "gpio1", "gpio2", "gpio4", "gpio7";
|
||||||
|
function = "gpio";
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio5 {
|
||||||
|
pins = "gpio5";
|
||||||
|
function = "clk32k_out";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
regulators {
|
||||||
|
vsup-sd2-supply = <...>;
|
||||||
|
...
|
||||||
|
|
||||||
|
sd0 {
|
||||||
|
regulator-name = "vdd_cpu";
|
||||||
|
regulator-min-microvolt = <700000>;
|
||||||
|
regulator-max-microvolt = <1400000>;
|
||||||
|
regulator-always-on;
|
||||||
|
ams,ext-control = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
sd1 {
|
||||||
|
regulator-name = "vdd_core";
|
||||||
|
regulator-min-microvolt = <700000>;
|
||||||
|
regulator-max-microvolt = <1400000>;
|
||||||
|
regulator-always-on;
|
||||||
|
ams,ext-control = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
sd2 {
|
||||||
|
regulator-name = "vddio_ddr";
|
||||||
|
regulator-min-microvolt = <1350000>;
|
||||||
|
regulator-max-microvolt = <1350000>;
|
||||||
|
regulator-always-on;
|
||||||
|
};
|
||||||
|
|
||||||
|
sd4 {
|
||||||
|
regulator-name = "avdd-hdmi-pex";
|
||||||
|
regulator-min-microvolt = <1050000>;
|
||||||
|
regulator-max-microvolt = <1050000>;
|
||||||
|
regulator-always-on;
|
||||||
|
};
|
||||||
|
|
||||||
|
sd5 {
|
||||||
|
regulator-name = "vdd-1v8";
|
||||||
|
regulator-min-microvolt = <1800000>;
|
||||||
|
regulator-max-microvolt = <1800000>;
|
||||||
|
regulator-always-on;
|
||||||
|
};
|
||||||
|
....
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
* Samsung S2MPS11 Voltage and Current Regulator
|
* Samsung S2MPS11 Voltage and Current Regulator
|
||||||
|
|
||||||
The Samsung S2MP211 is a multi-function device which includes voltage and
|
The Samsung S2MPS11 is a multi-function device which includes voltage and
|
||||||
current regulators, RTC, charger controller and other sub-blocks. It is
|
current regulators, RTC, charger controller and other sub-blocks. It is
|
||||||
interfaced to the host controller using a I2C interface. Each sub-block is
|
interfaced to the host controller using an I2C interface. Each sub-block is
|
||||||
addressed by the host system using different I2C slave address.
|
addressed by the host system using different I2C slave addresses.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: Should be "samsung,s2mps11-pmic".
|
- compatible: Should be "samsung,s2mps11-pmic".
|
||||||
|
@ -43,7 +43,8 @@ sub-node should be of the format as listed below.
|
||||||
|
|
||||||
BUCK[2/3/4/6] supports disabling ramp delay on hardware, so explictly
|
BUCK[2/3/4/6] supports disabling ramp delay on hardware, so explictly
|
||||||
regulator-ramp-delay = <0> can be used for them to disable ramp delay.
|
regulator-ramp-delay = <0> can be used for them to disable ramp delay.
|
||||||
In absence of regulator-ramp-delay property, default ramp delay will be used.
|
In the absence of the regulator-ramp-delay property, the default ramp
|
||||||
|
delay will be used.
|
||||||
|
|
||||||
NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set
|
NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set
|
||||||
for a particular group of BUCKs. So provide same regulator-ramp-delay<value>.
|
for a particular group of BUCKs. So provide same regulator-ramp-delay<value>.
|
||||||
|
@ -58,10 +59,10 @@ supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
|
||||||
as per the datasheet of s2mps11.
|
as per the datasheet of s2mps11.
|
||||||
|
|
||||||
- LDOn
|
- LDOn
|
||||||
- valid values for n are 1 to 28
|
- valid values for n are 1 to 38
|
||||||
- Example: LDO0, LD01, LDO28
|
- Example: LDO0, LD01, LDO28
|
||||||
- BUCKn
|
- BUCKn
|
||||||
- valid values for n are 1 to 9.
|
- valid values for n are 1 to 10.
|
||||||
- Example: BUCK1, BUCK2, BUCK9
|
- Example: BUCK1, BUCK2, BUCK9
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
|
@ -1247,7 +1247,7 @@ static struct i2c_driver pm860x_driver = {
|
||||||
.name = "88PM860x",
|
.name = "88PM860x",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &pm860x_pm_ops,
|
.pm = &pm860x_pm_ops,
|
||||||
.of_match_table = of_match_ptr(pm860x_dt_ids),
|
.of_match_table = pm860x_dt_ids,
|
||||||
},
|
},
|
||||||
.probe = pm860x_probe,
|
.probe = pm860x_probe,
|
||||||
.remove = pm860x_remove,
|
.remove = pm860x_remove,
|
||||||
|
|
|
@ -27,6 +27,18 @@ config MFD_AS3711
|
||||||
help
|
help
|
||||||
Support for the AS3711 PMIC from AMS
|
Support for the AS3711 PMIC from AMS
|
||||||
|
|
||||||
|
config MFD_AS3722
|
||||||
|
bool "ams AS3722 Power Management IC"
|
||||||
|
select MFD_CORE
|
||||||
|
select REGMAP_I2C
|
||||||
|
select REGMAP_IRQ
|
||||||
|
depends on I2C && OF
|
||||||
|
help
|
||||||
|
The ams AS3722 is a compact system PMU suitable for mobile phones,
|
||||||
|
tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
|
||||||
|
controllers, 11 LDOs, RTC, automatic battery, temperature and
|
||||||
|
over current monitoring, GPIOs, ADC and a watchdog.
|
||||||
|
|
||||||
config PMIC_ADP5520
|
config PMIC_ADP5520
|
||||||
bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
|
bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
|
||||||
depends on I2C=y
|
depends on I2C=y
|
||||||
|
@ -1151,6 +1163,16 @@ config MFD_WM8994
|
||||||
core support for the WM8994, in order to use the actual
|
core support for the WM8994, in order to use the actual
|
||||||
functionaltiy of the device other drivers must be enabled.
|
functionaltiy of the device other drivers must be enabled.
|
||||||
|
|
||||||
|
config MFD_STW481X
|
||||||
|
bool "Support for ST Microelectronics STw481x"
|
||||||
|
depends on I2C && ARCH_NOMADIK
|
||||||
|
select REGMAP_I2C
|
||||||
|
select MFD_CORE
|
||||||
|
help
|
||||||
|
Select this option to enable the STw481x chip driver used
|
||||||
|
in various ST Microelectronics and ST-Ericsson embedded
|
||||||
|
Nomadik series.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -162,3 +162,5 @@ obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
|
||||||
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
|
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
|
||||||
obj-$(CONFIG_MFD_RETU) += retu-mfd.o
|
obj-$(CONFIG_MFD_RETU) += retu-mfd.o
|
||||||
obj-$(CONFIG_MFD_AS3711) += as3711.o
|
obj-$(CONFIG_MFD_AS3711) += as3711.o
|
||||||
|
obj-$(CONFIG_MFD_AS3722) += as3722.o
|
||||||
|
obj-$(CONFIG_MFD_STW481X) += stw481x.o
|
||||||
|
|
|
@ -293,7 +293,7 @@ static ssize_t aat2870_reg_write_file(struct file *file,
|
||||||
unsigned long addr, val;
|
unsigned long addr, val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
buf_size = min(count, (sizeof(buf)-1));
|
buf_size = min(count, (size_t)(sizeof(buf)-1));
|
||||||
if (copy_from_user(buf, user_buf, buf_size)) {
|
if (copy_from_user(buf, user_buf, buf_size)) {
|
||||||
dev_err(aat2870->dev, "Failed to copy from user\n");
|
dev_err(aat2870->dev, "Failed to copy from user\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
|
@ -540,7 +540,7 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||||
for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
|
for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
|
||||||
if (arizona->pdata.gpio_defaults[i] > 0xffff)
|
if (arizona->pdata.gpio_defaults[i] > 0xffff)
|
||||||
arizona->pdata.gpio_defaults[i] = 0;
|
arizona->pdata.gpio_defaults[i] = 0;
|
||||||
if (arizona->pdata.gpio_defaults[i] == 0)
|
else if (arizona->pdata.gpio_defaults[i] == 0)
|
||||||
arizona->pdata.gpio_defaults[i] = 0x10000;
|
arizona->pdata.gpio_defaults[i] = 0x10000;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -633,11 +633,11 @@ int arizona_dev_init(struct arizona *arizona)
|
||||||
dev_set_drvdata(arizona->dev, arizona);
|
dev_set_drvdata(arizona->dev, arizona);
|
||||||
mutex_init(&arizona->clk_lock);
|
mutex_init(&arizona->clk_lock);
|
||||||
|
|
||||||
arizona_of_get_core_pdata(arizona);
|
|
||||||
|
|
||||||
if (dev_get_platdata(arizona->dev))
|
if (dev_get_platdata(arizona->dev))
|
||||||
memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
|
memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
|
||||||
sizeof(arizona->pdata));
|
sizeof(arizona->pdata));
|
||||||
|
else
|
||||||
|
arizona_of_get_core_pdata(arizona);
|
||||||
|
|
||||||
regcache_cache_only(arizona->regmap, true);
|
regcache_cache_only(arizona->regmap, true);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <linux/mfd/arizona/core.h>
|
#include <linux/mfd/arizona/core.h>
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <linux/mfd/arizona/core.h>
|
#include <linux/mfd/arizona/core.h>
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/mfd/as3711.h>
|
#include <linux/mfd/as3711.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
|
449
drivers/mfd/as3722.c
Normal file
449
drivers/mfd/as3722.c
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
/*
|
||||||
|
* Core driver for ams AS3722 PMICs
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 AMS AG
|
||||||
|
* Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Author: Florian Lobmaier <florian.lobmaier@ams.com>
|
||||||
|
* Author: Laxman Dewangan <ldewangan@nvidia.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/mfd/core.h>
|
||||||
|
#include <linux/mfd/as3722.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#define AS3722_DEVICE_ID 0x0C
|
||||||
|
|
||||||
|
static const struct resource as3722_rtc_resource[] = {
|
||||||
|
{
|
||||||
|
.name = "as3722-rtc-alarm",
|
||||||
|
.start = AS3722_IRQ_RTC_ALARM,
|
||||||
|
.end = AS3722_IRQ_RTC_ALARM,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct resource as3722_adc_resource[] = {
|
||||||
|
{
|
||||||
|
.name = "as3722-adc",
|
||||||
|
.start = AS3722_IRQ_ADC,
|
||||||
|
.end = AS3722_IRQ_ADC,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mfd_cell as3722_devs[] = {
|
||||||
|
{
|
||||||
|
.name = "as3722-pinctrl",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "as3722-regulator",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "as3722-rtc",
|
||||||
|
.num_resources = ARRAY_SIZE(as3722_rtc_resource),
|
||||||
|
.resources = as3722_rtc_resource,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "as3722-adc",
|
||||||
|
.num_resources = ARRAY_SIZE(as3722_adc_resource),
|
||||||
|
.resources = as3722_adc_resource,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "as3722-power-off",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_irq as3722_irqs[] = {
|
||||||
|
/* INT1 IRQs */
|
||||||
|
[AS3722_IRQ_LID] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_LID,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_ACOK] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_ACOK,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_ENABLE1] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_ENABLE1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_OCCUR_ALARM_SD0] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_ONKEY_LONG_PRESS] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_ONKEY_LONG,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_ONKEY] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_ONKEY,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_OVTMP] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_OVTMP,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_LOWBAT] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK1_LOWBAT,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* INT2 IRQs */
|
||||||
|
[AS3722_IRQ_SD0_LV] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_SD0_LV,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_SD1_LV] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_SD1_LV,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_SD2_LV] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_SD2345_LV,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_PWM1_OV_PROT] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_PWM1_OV_PROT,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_PWM2_OV_PROT] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_PWM2_OV_PROT,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_ENABLE2] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_ENABLE2,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_SD6_LV] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_SD6_LV,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_RTC_REP] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK2_RTC_REP,
|
||||||
|
.reg_offset = 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* INT3 IRQs */
|
||||||
|
[AS3722_IRQ_RTC_ALARM] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_RTC_ALARM,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_GPIO1] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_GPIO1,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_GPIO2] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_GPIO2,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_GPIO3] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_GPIO3,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_GPIO4] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_GPIO4,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_GPIO5] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_GPIO5,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_WATCHDOG] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_WATCHDOG,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_ENABLE3] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK3_ENABLE3,
|
||||||
|
.reg_offset = 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* INT4 IRQs */
|
||||||
|
[AS3722_IRQ_TEMP_SD0_SHUTDOWN] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_TEMP_SD1_SHUTDOWN] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_TEMP_SD2_SHUTDOWN] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_TEMP_SD0_ALARM] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_TEMP_SD1_ALARM] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_TEMP_SD6_ALARM] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_OCCUR_ALARM_SD6] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
[AS3722_IRQ_ADC] = {
|
||||||
|
.mask = AS3722_INTERRUPT_MASK4_ADC,
|
||||||
|
.reg_offset = 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_irq_chip as3722_irq_chip = {
|
||||||
|
.name = "as3722",
|
||||||
|
.irqs = as3722_irqs,
|
||||||
|
.num_irqs = ARRAY_SIZE(as3722_irqs),
|
||||||
|
.num_regs = 4,
|
||||||
|
.status_base = AS3722_INTERRUPT_STATUS1_REG,
|
||||||
|
.mask_base = AS3722_INTERRUPT_MASK1_REG,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int as3722_check_device_id(struct as3722 *as3722)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Check that this is actually a AS3722 */
|
||||||
|
ret = as3722_read(as3722, AS3722_ASIC_ID1_REG, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(as3722->dev, "ASIC_ID1 read failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val != AS3722_DEVICE_ID) {
|
||||||
|
dev_err(as3722->dev, "Device is not AS3722, ID is 0x%x\n", val);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = as3722_read(as3722, AS3722_ASIC_ID2_REG, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(as3722->dev, "ASIC_ID2 read failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(as3722->dev, "AS3722 with revision 0x%x found\n", val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int as3722_configure_pullups(struct as3722 *as3722)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u32 val = 0;
|
||||||
|
|
||||||
|
if (as3722->en_intern_int_pullup)
|
||||||
|
val |= AS3722_INT_PULL_UP;
|
||||||
|
if (as3722->en_intern_i2c_pullup)
|
||||||
|
val |= AS3722_I2C_PULL_UP;
|
||||||
|
|
||||||
|
ret = as3722_update_bits(as3722, AS3722_IOVOLTAGE_REG,
|
||||||
|
AS3722_INT_PULL_UP | AS3722_I2C_PULL_UP, val);
|
||||||
|
if (ret < 0)
|
||||||
|
dev_err(as3722->dev, "IOVOLTAGE_REG update failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct regmap_range as3722_readable_ranges[] = {
|
||||||
|
regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
|
||||||
|
regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
|
||||||
|
regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_REG_SEQU_MOD3_REG),
|
||||||
|
regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
|
||||||
|
regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
|
||||||
|
regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
|
||||||
|
AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
|
||||||
|
regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
|
||||||
|
regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
|
||||||
|
regmap_reg_range(AS3722_RTC_ACCESS_REG, AS3722_RTC_ACCESS_REG),
|
||||||
|
regmap_reg_range(AS3722_RTC_STATUS_REG, AS3722_TEMP_STATUS_REG),
|
||||||
|
regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
|
||||||
|
regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
|
||||||
|
regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_access_table as3722_readable_table = {
|
||||||
|
.yes_ranges = as3722_readable_ranges,
|
||||||
|
.n_yes_ranges = ARRAY_SIZE(as3722_readable_ranges),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_range as3722_writable_ranges[] = {
|
||||||
|
regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
|
||||||
|
regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
|
||||||
|
regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_GPIO_SIGNAL_OUT_REG),
|
||||||
|
regmap_reg_range(AS3722_REG_SEQU_MOD1_REG, AS3722_REG_SEQU_MOD3_REG),
|
||||||
|
regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
|
||||||
|
regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
|
||||||
|
regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
|
||||||
|
AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
|
||||||
|
regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
|
||||||
|
regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
|
||||||
|
regmap_reg_range(AS3722_INTERRUPT_MASK1_REG, AS3722_TEMP_STATUS_REG),
|
||||||
|
regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC1_CONTROL_REG),
|
||||||
|
regmap_reg_range(AS3722_ADC1_THRESHOLD_HI_MSB_REG,
|
||||||
|
AS3722_ADC_CONFIGURATION_REG),
|
||||||
|
regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_access_table as3722_writable_table = {
|
||||||
|
.yes_ranges = as3722_writable_ranges,
|
||||||
|
.n_yes_ranges = ARRAY_SIZE(as3722_writable_ranges),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_range as3722_cacheable_ranges[] = {
|
||||||
|
regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_LDO11_VOLTAGE_REG),
|
||||||
|
regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_LDOCONTROL1_REG),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_access_table as3722_volatile_table = {
|
||||||
|
.no_ranges = as3722_cacheable_ranges,
|
||||||
|
.n_no_ranges = ARRAY_SIZE(as3722_cacheable_ranges),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_config as3722_regmap_config = {
|
||||||
|
.reg_bits = 8,
|
||||||
|
.val_bits = 8,
|
||||||
|
.max_register = AS3722_MAX_REGISTER,
|
||||||
|
.cache_type = REGCACHE_RBTREE,
|
||||||
|
.rd_table = &as3722_readable_table,
|
||||||
|
.wr_table = &as3722_writable_table,
|
||||||
|
.volatile_table = &as3722_volatile_table,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int as3722_i2c_of_probe(struct i2c_client *i2c,
|
||||||
|
struct as3722 *as3722)
|
||||||
|
{
|
||||||
|
struct device_node *np = i2c->dev.of_node;
|
||||||
|
struct irq_data *irq_data;
|
||||||
|
|
||||||
|
if (!np) {
|
||||||
|
dev_err(&i2c->dev, "Device Tree not found\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
irq_data = irq_get_irq_data(i2c->irq);
|
||||||
|
if (!irq_data) {
|
||||||
|
dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
as3722->en_intern_int_pullup = of_property_read_bool(np,
|
||||||
|
"ams,enable-internal-int-pullup");
|
||||||
|
as3722->en_intern_i2c_pullup = of_property_read_bool(np,
|
||||||
|
"ams,enable-internal-i2c-pullup");
|
||||||
|
as3722->irq_flags = irqd_get_trigger_type(irq_data);
|
||||||
|
dev_dbg(&i2c->dev, "IRQ flags are 0x%08lx\n", as3722->irq_flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int as3722_i2c_probe(struct i2c_client *i2c,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct as3722 *as3722;
|
||||||
|
unsigned long irq_flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL);
|
||||||
|
if (!as3722)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
as3722->dev = &i2c->dev;
|
||||||
|
as3722->chip_irq = i2c->irq;
|
||||||
|
i2c_set_clientdata(i2c, as3722);
|
||||||
|
|
||||||
|
ret = as3722_i2c_of_probe(i2c, as3722);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config);
|
||||||
|
if (IS_ERR(as3722->regmap)) {
|
||||||
|
ret = PTR_ERR(as3722->regmap);
|
||||||
|
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = as3722_check_device_id(as3722);
|
||||||
|
if (ret < 0)
|
||||||
|
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);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = as3722_configure_pullups(as3722);
|
||||||
|
if (ret < 0)
|
||||||
|
goto scrub;
|
||||||
|
|
||||||
|
ret = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 const struct of_device_id as3722_of_match[] = {
|
||||||
|
{ .compatible = "ams,as3722", },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, as3722_of_match);
|
||||||
|
|
||||||
|
static const struct i2c_device_id as3722_i2c_id[] = {
|
||||||
|
{ "as3722", 0 },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, as3722_i2c_id);
|
||||||
|
|
||||||
|
static struct i2c_driver as3722_i2c_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "as3722",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = as3722_of_match,
|
||||||
|
},
|
||||||
|
.probe = as3722_i2c_probe,
|
||||||
|
.remove = as3722_i2c_remove,
|
||||||
|
.id_table = as3722_i2c_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_i2c_driver(as3722_i2c_driver);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("I2C support for AS3722 PMICs");
|
||||||
|
MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
|
||||||
|
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -86,7 +86,11 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
|
/*
|
||||||
|
* According to errata item 24, multiwrite mode should be avoided
|
||||||
|
* in order to prevent register data corruption after power-down.
|
||||||
|
*/
|
||||||
|
static int da9052_i2c_disable_multiwrite(struct da9052 *da9052)
|
||||||
{
|
{
|
||||||
int reg_val, ret;
|
int reg_val, ret;
|
||||||
|
|
||||||
|
@ -94,8 +98,8 @@ static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (reg_val & DA9052_CONTROL_B_WRITEMODE) {
|
if (!(reg_val & DA9052_CONTROL_B_WRITEMODE)) {
|
||||||
reg_val &= ~DA9052_CONTROL_B_WRITEMODE;
|
reg_val |= DA9052_CONTROL_B_WRITEMODE;
|
||||||
ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG,
|
ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG,
|
||||||
reg_val);
|
reg_val);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -154,7 +158,7 @@ static int da9052_i2c_probe(struct i2c_client *client,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = da9052_i2c_enable_multiwrite(da9052);
|
ret = da9052_i2c_disable_multiwrite(da9052);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -394,16 +394,12 @@ static int pcap_add_subdev(struct pcap_chip *pcap,
|
||||||
static int ezx_pcap_remove(struct spi_device *spi)
|
static int ezx_pcap_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
struct pcap_chip *pcap = spi_get_drvdata(spi);
|
struct pcap_chip *pcap = spi_get_drvdata(spi);
|
||||||
struct pcap_platform_data *pdata = dev_get_platdata(&spi->dev);
|
int i;
|
||||||
int i, adc_irq;
|
|
||||||
|
|
||||||
/* remove all registered subdevs */
|
/* remove all registered subdevs */
|
||||||
device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
|
device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
|
||||||
|
|
||||||
/* cleanup ADC */
|
/* cleanup ADC */
|
||||||
adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
|
|
||||||
PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);
|
|
||||||
devm_free_irq(&spi->dev, adc_irq, pcap);
|
|
||||||
mutex_lock(&pcap->adc_mutex);
|
mutex_lock(&pcap->adc_mutex);
|
||||||
for (i = 0; i < PCAP_ADC_MAXQ; i++)
|
for (i = 0; i < PCAP_ADC_MAXQ; i++)
|
||||||
kfree(pcap->adc_queue[i]);
|
kfree(pcap->adc_queue[i]);
|
||||||
|
@ -509,8 +505,6 @@ static int ezx_pcap_probe(struct spi_device *spi)
|
||||||
|
|
||||||
remove_subdevs:
|
remove_subdevs:
|
||||||
device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
|
device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
|
||||||
/* free_adc: */
|
|
||||||
devm_free_irq(&spi->dev, adc_irq, pcap);
|
|
||||||
free_irqchip:
|
free_irqchip:
|
||||||
for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
|
for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
|
||||||
irq_set_chip_and_handler(i, NULL, NULL);
|
irq_set_chip_and_handler(i, NULL, NULL);
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
* document number TBD : Wellsburg
|
* document number TBD : Wellsburg
|
||||||
* document number TBD : Avoton SoC
|
* document number TBD : Avoton SoC
|
||||||
* document number TBD : Coleto Creek
|
* document number TBD : Coleto Creek
|
||||||
|
* document number TBD : Wildcat Point-LP
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
@ -211,6 +212,7 @@ enum lpc_chipsets {
|
||||||
LPC_WBG, /* Wellsburg */
|
LPC_WBG, /* Wellsburg */
|
||||||
LPC_AVN, /* Avoton SoC */
|
LPC_AVN, /* Avoton SoC */
|
||||||
LPC_COLETO, /* Coleto Creek */
|
LPC_COLETO, /* Coleto Creek */
|
||||||
|
LPC_WPT_LP, /* Wildcat Point-LP */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct lpc_ich_info lpc_chipset_info[] = {
|
static struct lpc_ich_info lpc_chipset_info[] = {
|
||||||
|
@ -503,6 +505,10 @@ static struct lpc_ich_info lpc_chipset_info[] = {
|
||||||
.name = "Coleto Creek",
|
.name = "Coleto Creek",
|
||||||
.iTCO_version = 2,
|
.iTCO_version = 2,
|
||||||
},
|
},
|
||||||
|
[LPC_WPT_LP] = {
|
||||||
|
.name = "Lynx Point_LP",
|
||||||
|
.iTCO_version = 2,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -721,6 +727,13 @@ static DEFINE_PCI_DEVICE_TABLE(lpc_ich_ids) = {
|
||||||
{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
|
{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
|
||||||
{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
|
{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
|
||||||
{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
|
{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP},
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP},
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x9cc3), LPC_WPT_LP},
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x9cc5), LPC_WPT_LP},
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP},
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP},
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP},
|
||||||
{ 0, }, /* End of list */
|
{ 0, }, /* End of list */
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
|
MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
|
||||||
|
@ -969,7 +982,6 @@ static int lpc_ich_probe(struct pci_dev *dev,
|
||||||
if (!cell_added) {
|
if (!cell_added) {
|
||||||
dev_warn(&dev->dev, "No MFD cells added\n");
|
dev_warn(&dev->dev, "No MFD cells added\n");
|
||||||
lpc_ich_restore_config_space(dev);
|
lpc_ich_restore_config_space(dev);
|
||||||
pci_set_drvdata(dev, NULL);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,7 +992,6 @@ static void lpc_ich_remove(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
mfd_remove_devices(&dev->dev);
|
mfd_remove_devices(&dev->dev);
|
||||||
lpc_ich_restore_config_space(dev);
|
lpc_ich_restore_config_space(dev);
|
||||||
pci_set_drvdata(dev, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_driver lpc_ich_driver = {
|
static struct pci_driver lpc_ich_driver = {
|
||||||
|
|
|
@ -59,18 +59,21 @@ static struct mfd_cell isch_smbus_cell = {
|
||||||
.name = "isch_smbus",
|
.name = "isch_smbus",
|
||||||
.num_resources = 1,
|
.num_resources = 1,
|
||||||
.resources = &smbus_sch_resource,
|
.resources = &smbus_sch_resource,
|
||||||
|
.ignore_resource_conflicts = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mfd_cell sch_gpio_cell = {
|
static struct mfd_cell sch_gpio_cell = {
|
||||||
.name = "sch_gpio",
|
.name = "sch_gpio",
|
||||||
.num_resources = 1,
|
.num_resources = 1,
|
||||||
.resources = &gpio_sch_resource,
|
.resources = &gpio_sch_resource,
|
||||||
|
.ignore_resource_conflicts = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mfd_cell wdt_sch_cell = {
|
static struct mfd_cell wdt_sch_cell = {
|
||||||
.name = "ie6xx_wdt",
|
.name = "ie6xx_wdt",
|
||||||
.num_resources = 1,
|
.num_resources = 1,
|
||||||
.resources = &wdt_sch_resource,
|
.resources = &wdt_sch_resource,
|
||||||
|
.ignore_resource_conflicts = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
|
static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <linux/mfd/max77686.h>
|
#include <linux/mfd/max77686.h>
|
||||||
#include <linux/mfd/max77686-private.h>
|
#include <linux/mfd/max77686-private.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#define I2C_ADDR_RTC (0x0C >> 1)
|
#define I2C_ADDR_RTC (0x0C >> 1)
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,8 @@ static void max77693_irq_sync_unlock(struct irq_data *data)
|
||||||
static const inline struct max77693_irq_data *
|
static const inline struct max77693_irq_data *
|
||||||
irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
|
irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
|
||||||
{
|
{
|
||||||
return &max77693_irqs[irq];
|
struct irq_data *data = irq_get_irq_data(irq);
|
||||||
|
return &max77693_irqs[data->hwirq];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void max77693_irq_mask(struct irq_data *data)
|
static void max77693_irq_mask(struct irq_data *data)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
|
@ -110,15 +111,9 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
struct max77693_dev *max77693;
|
struct max77693_dev *max77693;
|
||||||
struct max77693_platform_data *pdata = dev_get_platdata(&i2c->dev);
|
|
||||||
u8 reg_data;
|
u8 reg_data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!pdata) {
|
|
||||||
dev_err(&i2c->dev, "No platform data found.\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
max77693 = devm_kzalloc(&i2c->dev,
|
max77693 = devm_kzalloc(&i2c->dev,
|
||||||
sizeof(struct max77693_dev), GFP_KERNEL);
|
sizeof(struct max77693_dev), GFP_KERNEL);
|
||||||
if (max77693 == NULL)
|
if (max77693 == NULL)
|
||||||
|
@ -138,8 +133,6 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
max77693->wakeup = pdata->wakeup;
|
|
||||||
|
|
||||||
ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
|
ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
|
||||||
®_data);
|
®_data);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -179,8 +172,6 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_mfd;
|
goto err_mfd;
|
||||||
|
|
||||||
device_init_wakeup(max77693->dev, pdata->wakeup);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err_mfd:
|
err_mfd:
|
||||||
|
@ -235,11 +226,19 @@ static const struct dev_pm_ops max77693_pm = {
|
||||||
.resume = max77693_resume,
|
.resume = max77693_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static struct of_device_id max77693_dt_match[] = {
|
||||||
|
{ .compatible = "maxim,max77693" },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct i2c_driver max77693_i2c_driver = {
|
static struct i2c_driver max77693_i2c_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "max77693",
|
.name = "max77693",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &max77693_pm,
|
.pm = &max77693_pm,
|
||||||
|
.of_match_table = of_match_ptr(max77693_dt_match),
|
||||||
},
|
},
|
||||||
.probe = max77693_i2c_probe,
|
.probe = max77693_i2c_probe,
|
||||||
.remove = max77693_i2c_remove,
|
.remove = max77693_i2c_remove,
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/mfd/max8907.h>
|
#include <linux/mfd/max8907.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
|
@ -238,7 +238,7 @@ static struct i2c_driver max8925_driver = {
|
||||||
.name = "max8925",
|
.name = "max8925",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &max8925_pm_ops,
|
.pm = &max8925_pm_ops,
|
||||||
.of_match_table = of_match_ptr(max8925_dt_ids),
|
.of_match_table = max8925_dt_ids,
|
||||||
},
|
},
|
||||||
.probe = max8925_probe,
|
.probe = max8925_probe,
|
||||||
.remove = max8925_remove,
|
.remove = max8925_remove,
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
|
|
|
@ -78,7 +78,6 @@ static int mc13xxx_i2c_probe(struct i2c_client *client,
|
||||||
ret = PTR_ERR(mc13xxx->regmap);
|
ret = PTR_ERR(mc13xxx->regmap);
|
||||||
dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
|
dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
|
||||||
ret);
|
ret);
|
||||||
dev_set_drvdata(&client->dev, NULL);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,8 @@ int mfd_cell_disable(struct platform_device *pdev)
|
||||||
EXPORT_SYMBOL(mfd_cell_disable);
|
EXPORT_SYMBOL(mfd_cell_disable);
|
||||||
|
|
||||||
static int mfd_platform_add_cell(struct platform_device *pdev,
|
static int mfd_platform_add_cell(struct platform_device *pdev,
|
||||||
const struct mfd_cell *cell)
|
const struct mfd_cell *cell,
|
||||||
|
atomic_t *usage_count)
|
||||||
{
|
{
|
||||||
if (!cell)
|
if (!cell)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -73,11 +74,12 @@ static int mfd_platform_add_cell(struct platform_device *pdev,
|
||||||
if (!pdev->mfd_cell)
|
if (!pdev->mfd_cell)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
pdev->mfd_cell->usage_count = usage_count;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mfd_add_device(struct device *parent, int id,
|
static int mfd_add_device(struct device *parent, int id,
|
||||||
const struct mfd_cell *cell,
|
const struct mfd_cell *cell, atomic_t *usage_count,
|
||||||
struct resource *mem_base,
|
struct resource *mem_base,
|
||||||
int irq_base, struct irq_domain *domain)
|
int irq_base, struct irq_domain *domain)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +125,7 @@ static int mfd_add_device(struct device *parent, int id,
|
||||||
goto fail_alias;
|
goto fail_alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mfd_platform_add_cell(pdev, cell);
|
ret = mfd_platform_add_cell(pdev, cell, usage_count);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail_alias;
|
goto fail_alias;
|
||||||
|
|
||||||
|
@ -192,12 +194,12 @@ static int mfd_add_device(struct device *parent, int id,
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfd_add_devices(struct device *parent, int id,
|
int mfd_add_devices(struct device *parent, int id,
|
||||||
struct mfd_cell *cells, int n_devs,
|
const struct mfd_cell *cells, int n_devs,
|
||||||
struct resource *mem_base,
|
struct resource *mem_base,
|
||||||
int irq_base, struct irq_domain *domain)
|
int irq_base, struct irq_domain *domain)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret = 0;
|
int ret;
|
||||||
atomic_t *cnts;
|
atomic_t *cnts;
|
||||||
|
|
||||||
/* initialize reference counting for all cells */
|
/* initialize reference counting for all cells */
|
||||||
|
@ -207,16 +209,19 @@ int mfd_add_devices(struct device *parent, int id,
|
||||||
|
|
||||||
for (i = 0; i < n_devs; i++) {
|
for (i = 0; i < n_devs; i++) {
|
||||||
atomic_set(&cnts[i], 0);
|
atomic_set(&cnts[i], 0);
|
||||||
cells[i].usage_count = &cnts[i];
|
ret = mfd_add_device(parent, id, cells + i, cnts + i, mem_base,
|
||||||
ret = mfd_add_device(parent, id, cells + i, mem_base,
|
|
||||||
irq_base, domain);
|
irq_base, domain);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
return 0;
|
||||||
mfd_remove_devices(parent);
|
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (i)
|
||||||
|
mfd_remove_devices(parent);
|
||||||
|
else
|
||||||
|
kfree(cnts);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mfd_add_devices);
|
EXPORT_SYMBOL(mfd_add_devices);
|
||||||
|
@ -271,8 +276,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
|
||||||
for (i = 0; i < n_clones; i++) {
|
for (i = 0; i < n_clones; i++) {
|
||||||
cell_entry.name = clones[i];
|
cell_entry.name = clones[i];
|
||||||
/* don't give up if a single call fails; just report error */
|
/* don't give up if a single call fails; just report error */
|
||||||
if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0,
|
if (mfd_add_device(pdev->dev.parent, -1, &cell_entry,
|
||||||
NULL))
|
cell_entry.usage_count, NULL, 0, NULL))
|
||||||
dev_err(dev, "failed to create platform device '%s'\n",
|
dev_err(dev, "failed to create platform device '%s'\n",
|
||||||
clones[i]);
|
clones[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,13 +328,13 @@ static int usbhs_runtime_resume(struct device *dev)
|
||||||
omap_tll_enable(pdata);
|
omap_tll_enable(pdata);
|
||||||
|
|
||||||
if (!IS_ERR(omap->ehci_logic_fck))
|
if (!IS_ERR(omap->ehci_logic_fck))
|
||||||
clk_enable(omap->ehci_logic_fck);
|
clk_prepare_enable(omap->ehci_logic_fck);
|
||||||
|
|
||||||
for (i = 0; i < omap->nports; i++) {
|
for (i = 0; i < omap->nports; i++) {
|
||||||
switch (pdata->port_mode[i]) {
|
switch (pdata->port_mode[i]) {
|
||||||
case OMAP_EHCI_PORT_MODE_HSIC:
|
case OMAP_EHCI_PORT_MODE_HSIC:
|
||||||
if (!IS_ERR(omap->hsic60m_clk[i])) {
|
if (!IS_ERR(omap->hsic60m_clk[i])) {
|
||||||
r = clk_enable(omap->hsic60m_clk[i]);
|
r = clk_prepare_enable(omap->hsic60m_clk[i]);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"Can't enable port %d hsic60m clk:%d\n",
|
"Can't enable port %d hsic60m clk:%d\n",
|
||||||
|
@ -343,7 +343,7 @@ static int usbhs_runtime_resume(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_ERR(omap->hsic480m_clk[i])) {
|
if (!IS_ERR(omap->hsic480m_clk[i])) {
|
||||||
r = clk_enable(omap->hsic480m_clk[i]);
|
r = clk_prepare_enable(omap->hsic480m_clk[i]);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"Can't enable port %d hsic480m clk:%d\n",
|
"Can't enable port %d hsic480m clk:%d\n",
|
||||||
|
@ -354,7 +354,7 @@ static int usbhs_runtime_resume(struct device *dev)
|
||||||
|
|
||||||
case OMAP_EHCI_PORT_MODE_TLL:
|
case OMAP_EHCI_PORT_MODE_TLL:
|
||||||
if (!IS_ERR(omap->utmi_clk[i])) {
|
if (!IS_ERR(omap->utmi_clk[i])) {
|
||||||
r = clk_enable(omap->utmi_clk[i]);
|
r = clk_prepare_enable(omap->utmi_clk[i]);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"Can't enable port %d clk : %d\n",
|
"Can't enable port %d clk : %d\n",
|
||||||
|
@ -382,15 +382,15 @@ static int usbhs_runtime_suspend(struct device *dev)
|
||||||
switch (pdata->port_mode[i]) {
|
switch (pdata->port_mode[i]) {
|
||||||
case OMAP_EHCI_PORT_MODE_HSIC:
|
case OMAP_EHCI_PORT_MODE_HSIC:
|
||||||
if (!IS_ERR(omap->hsic60m_clk[i]))
|
if (!IS_ERR(omap->hsic60m_clk[i]))
|
||||||
clk_disable(omap->hsic60m_clk[i]);
|
clk_disable_unprepare(omap->hsic60m_clk[i]);
|
||||||
|
|
||||||
if (!IS_ERR(omap->hsic480m_clk[i]))
|
if (!IS_ERR(omap->hsic480m_clk[i]))
|
||||||
clk_disable(omap->hsic480m_clk[i]);
|
clk_disable_unprepare(omap->hsic480m_clk[i]);
|
||||||
/* Fall through as utmi_clks were used in HSIC mode */
|
/* Fall through as utmi_clks were used in HSIC mode */
|
||||||
|
|
||||||
case OMAP_EHCI_PORT_MODE_TLL:
|
case OMAP_EHCI_PORT_MODE_TLL:
|
||||||
if (!IS_ERR(omap->utmi_clk[i]))
|
if (!IS_ERR(omap->utmi_clk[i]))
|
||||||
clk_disable(omap->utmi_clk[i]);
|
clk_disable_unprepare(omap->utmi_clk[i]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -398,7 +398,7 @@ static int usbhs_runtime_suspend(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_ERR(omap->ehci_logic_fck))
|
if (!IS_ERR(omap->ehci_logic_fck))
|
||||||
clk_disable(omap->ehci_logic_fck);
|
clk_disable_unprepare(omap->ehci_logic_fck);
|
||||||
|
|
||||||
omap_tll_disable(pdata);
|
omap_tll_disable(pdata);
|
||||||
|
|
||||||
|
@ -893,7 +893,7 @@ static struct platform_driver usbhs_omap_driver = {
|
||||||
.name = (char *)usbhs_driver_name,
|
.name = (char *)usbhs_driver_name,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &usbhsomap_dev_pm_ops,
|
.pm = &usbhsomap_dev_pm_ops,
|
||||||
.of_match_table = of_match_ptr(usbhs_omap_dt_ids),
|
.of_match_table = usbhs_omap_dt_ids,
|
||||||
},
|
},
|
||||||
.remove = usbhs_omap_remove,
|
.remove = usbhs_omap_remove,
|
||||||
};
|
};
|
||||||
|
|
|
@ -320,7 +320,7 @@ static struct platform_driver usbtll_omap_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = (char *)usbtll_driver_name,
|
.name = (char *)usbtll_driver_name,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_match_table = of_match_ptr(usbtll_omap_dt_ids),
|
.of_match_table = usbtll_omap_dt_ids,
|
||||||
},
|
},
|
||||||
.probe = usbtll_omap_probe,
|
.probe = usbtll_omap_probe,
|
||||||
.remove = usbtll_omap_remove,
|
.remove = usbtll_omap_remove,
|
||||||
|
@ -429,7 +429,7 @@ int omap_tll_enable(struct usbhs_omap_platform_data *pdata)
|
||||||
if (IS_ERR(tll->ch_clk[i]))
|
if (IS_ERR(tll->ch_clk[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = clk_enable(tll->ch_clk[i]);
|
r = clk_prepare_enable(tll->ch_clk[i]);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(tll_dev,
|
dev_err(tll_dev,
|
||||||
"Error enabling ch %d clock: %d\n", i, r);
|
"Error enabling ch %d clock: %d\n", i, r);
|
||||||
|
@ -460,7 +460,7 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
|
||||||
for (i = 0; i < tll->nch; i++) {
|
for (i = 0; i < tll->nch; i++) {
|
||||||
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
|
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
|
||||||
if (!IS_ERR(tll->ch_clk[i]))
|
if (!IS_ERR(tll->ch_clk[i]))
|
||||||
clk_disable(tll->ch_clk[i]);
|
clk_disable_unprepare(tll->ch_clk[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -368,6 +368,7 @@ static const struct of_device_id of_palmas_match_tbl[] = {
|
||||||
},
|
},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
|
||||||
|
|
||||||
static int palmas_i2c_probe(struct i2c_client *i2c,
|
static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
|
@ -402,7 +403,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
palmas->dev = &i2c->dev;
|
palmas->dev = &i2c->dev;
|
||||||
palmas->irq = i2c->irq;
|
palmas->irq = i2c->irq;
|
||||||
|
|
||||||
match = of_match_device(of_match_ptr(of_palmas_match_tbl), &i2c->dev);
|
match = of_match_device(of_palmas_match_tbl, &i2c->dev);
|
||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
@ -421,7 +422,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
dev_err(palmas->dev,
|
dev_err(palmas->dev,
|
||||||
"can't attach client %d\n", i);
|
"can't attach client %d\n", i);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err;
|
goto err_i2c;
|
||||||
}
|
}
|
||||||
palmas->i2c_clients[i]->dev.of_node = of_node_get(node);
|
palmas->i2c_clients[i]->dev.of_node = of_node_get(node);
|
||||||
}
|
}
|
||||||
|
@ -432,7 +433,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
dev_err(palmas->dev,
|
dev_err(palmas->dev,
|
||||||
"Failed to allocate regmap %d, err: %d\n",
|
"Failed to allocate regmap %d, err: %d\n",
|
||||||
i, ret);
|
i, ret);
|
||||||
goto err;
|
goto err_i2c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +452,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
reg);
|
reg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret);
|
dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret);
|
||||||
goto err;
|
goto err_i2c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change IRQ into clear on read mode for efficiency */
|
/* Change IRQ into clear on read mode for efficiency */
|
||||||
|
@ -465,7 +466,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
|
IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
|
||||||
&palmas->irq_data);
|
&palmas->irq_data);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err_i2c;
|
||||||
|
|
||||||
no_irq:
|
no_irq:
|
||||||
slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
|
slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
|
||||||
|
@ -551,7 +552,6 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
} else if (pdata->pm_off && !pm_power_off) {
|
} else if (pdata->pm_off && !pm_power_off) {
|
||||||
palmas_dev = palmas;
|
palmas_dev = palmas;
|
||||||
pm_power_off = palmas_power_off;
|
pm_power_off = palmas_power_off;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,17 +559,31 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
|
||||||
|
|
||||||
err_irq:
|
err_irq:
|
||||||
regmap_del_irq_chip(palmas->irq, palmas->irq_data);
|
regmap_del_irq_chip(palmas->irq, palmas->irq_data);
|
||||||
err:
|
err_i2c:
|
||||||
|
for (i = 1; i < PALMAS_NUM_CLIENTS; i++) {
|
||||||
|
if (palmas->i2c_clients[i])
|
||||||
|
i2c_unregister_device(palmas->i2c_clients[i]);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int palmas_i2c_remove(struct i2c_client *i2c)
|
static int palmas_i2c_remove(struct i2c_client *i2c)
|
||||||
{
|
{
|
||||||
struct palmas *palmas = i2c_get_clientdata(i2c);
|
struct palmas *palmas = i2c_get_clientdata(i2c);
|
||||||
|
int i;
|
||||||
|
|
||||||
mfd_remove_devices(palmas->dev);
|
|
||||||
regmap_del_irq_chip(palmas->irq, palmas->irq_data);
|
regmap_del_irq_chip(palmas->irq, palmas->irq_data);
|
||||||
|
|
||||||
|
for (i = 1; i < PALMAS_NUM_CLIENTS; i++) {
|
||||||
|
if (palmas->i2c_clients[i])
|
||||||
|
i2c_unregister_device(palmas->i2c_clients[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (palmas == palmas_dev) {
|
||||||
|
pm_power_off = NULL;
|
||||||
|
palmas_dev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,11 +171,12 @@ static int pm8921_remove(struct platform_device *pdev)
|
||||||
drvdata = platform_get_drvdata(pdev);
|
drvdata = platform_get_drvdata(pdev);
|
||||||
if (drvdata)
|
if (drvdata)
|
||||||
pmic = drvdata->pm_chip_data;
|
pmic = drvdata->pm_chip_data;
|
||||||
if (pmic)
|
if (pmic) {
|
||||||
mfd_remove_devices(pmic->dev);
|
mfd_remove_devices(pmic->dev);
|
||||||
if (pmic->irq_chip) {
|
if (pmic->irq_chip) {
|
||||||
pm8xxx_irq_exit(pmic->irq_chip);
|
pm8xxx_irq_exit(pmic->irq_chip);
|
||||||
pmic->irq_chip = NULL;
|
pmic->irq_chip = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -130,13 +130,57 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV, 0xFE46);
|
err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV,
|
||||||
|
PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED |
|
||||||
|
PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN |
|
||||||
|
PHY_REG_REV_RX_PWST | PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 |
|
||||||
|
PHY_REG_REV_STOP_CLKRD | PHY_REG_REV_STOP_CLKWR);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
msleep(1);
|
msleep(1);
|
||||||
|
|
||||||
return rtsx_pci_write_phy_register(pcr, PHY_BPCR, 0x05C0);
|
err = rtsx_pci_write_phy_register(pcr, PHY_BPCR,
|
||||||
|
PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
|
||||||
|
PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = rtsx_pci_write_phy_register(pcr, PHY_PCR,
|
||||||
|
PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
|
||||||
|
PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
|
||||||
|
PHY_PCR_RSSI_EN);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
|
||||||
|
PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
|
||||||
|
PHY_RCR2_CDR_CP_10 | PHY_RCR2_CDR_SR_2 |
|
||||||
|
PHY_RCR2_FREQSEL_12 | PHY_RCR2_CPADJEN |
|
||||||
|
PHY_RCR2_CDR_SC_8 | PHY_RCR2_CALIB_LATE);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = rtsx_pci_write_phy_register(pcr, PHY_FLD4,
|
||||||
|
PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
|
||||||
|
PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
|
||||||
|
PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
|
||||||
|
PHY_FLD4_BER_CHK_EN);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = rtsx_pci_write_phy_register(pcr, PHY_RDR, PHY_RDR_RXDSEL_1_9);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = rtsx_pci_write_phy_register(pcr, PHY_RCR1,
|
||||||
|
PHY_RCR1_ADP_TIME | PHY_RCR1_VCO_COARSE);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = rtsx_pci_write_phy_register(pcr, PHY_FLD3,
|
||||||
|
PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
|
||||||
|
PHY_FLD3_RXDELINK);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
return rtsx_pci_write_phy_register(pcr, PHY_TUNE,
|
||||||
|
PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
|
||||||
|
PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
|
||||||
|
PHY_TUNE_TUNED12);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
|
static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
|
||||||
|
|
|
@ -1149,7 +1149,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
|
||||||
pcr->remap_addr = ioremap_nocache(base, len);
|
pcr->remap_addr = ioremap_nocache(base, len);
|
||||||
if (!pcr->remap_addr) {
|
if (!pcr->remap_addr) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto free_host;
|
goto free_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
|
pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
|
||||||
|
@ -1209,8 +1209,6 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
|
||||||
pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
|
pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
|
||||||
unmap:
|
unmap:
|
||||||
iounmap(pcr->remap_addr);
|
iounmap(pcr->remap_addr);
|
||||||
free_host:
|
|
||||||
dev_set_drvdata(&pcidev->dev, NULL);
|
|
||||||
free_handle:
|
free_handle:
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
free_pcr:
|
free_pcr:
|
||||||
|
@ -1242,7 +1240,6 @@ static void rtsx_pci_remove(struct pci_dev *pcidev)
|
||||||
pci_disable_msi(pcr->pci);
|
pci_disable_msi(pcr->pci);
|
||||||
iounmap(pcr->remap_addr);
|
iounmap(pcr->remap_addr);
|
||||||
|
|
||||||
dev_set_drvdata(&pcidev->dev, NULL);
|
|
||||||
pci_release_regions(pcidev);
|
pci_release_regions(pcidev);
|
||||||
pci_disable_device(pcidev);
|
pci_disable_device(pcidev);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
|
|
|
@ -1232,7 +1232,7 @@ static ssize_t sm501_dbg_regs(struct device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static DEVICE_ATTR(dbg_regs, 0666, sm501_dbg_regs, NULL);
|
static DEVICE_ATTR(dbg_regs, 0444, sm501_dbg_regs, NULL);
|
||||||
|
|
||||||
/* sm501_init_reg
|
/* sm501_init_reg
|
||||||
*
|
*
|
||||||
|
@ -1660,7 +1660,6 @@ static int sm501_pci_probe(struct pci_dev *dev,
|
||||||
err3:
|
err3:
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
err2:
|
err2:
|
||||||
pci_set_drvdata(dev, NULL);
|
|
||||||
kfree(sm);
|
kfree(sm);
|
||||||
err1:
|
err1:
|
||||||
return err;
|
return err;
|
||||||
|
@ -1695,7 +1694,6 @@ static void sm501_pci_remove(struct pci_dev *dev)
|
||||||
release_resource(sm->regs_claim);
|
release_resource(sm->regs_claim);
|
||||||
kfree(sm->regs_claim);
|
kfree(sm->regs_claim);
|
||||||
|
|
||||||
pci_set_drvdata(dev, NULL);
|
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
250
drivers/mfd/stw481x.c
Normal file
250
drivers/mfd/stw481x.c
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
* Core driver for STw4810/STw4811
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 ST-Ericsson SA
|
||||||
|
* Written on behalf of Linaro for ST-Ericsson
|
||||||
|
*
|
||||||
|
* Author: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
*
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/mfd/core.h>
|
||||||
|
#include <linux/mfd/stw481x.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This driver can only access the non-USB portions of STw4811, the register
|
||||||
|
* range 0x00-0x10 dealing with USB is bound to the two special I2C pins used
|
||||||
|
* for USB control.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Registers inside the power control address space */
|
||||||
|
#define STW_PC_VCORE_SEL 0x05U
|
||||||
|
#define STW_PC_VAUX_SEL 0x06U
|
||||||
|
#define STW_PC_VPLL_SEL 0x07U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stw481x_get_pctl_reg() - get a power control register
|
||||||
|
* @stw481x: handle to the stw481x chip
|
||||||
|
* @reg: power control register to fetch
|
||||||
|
*
|
||||||
|
* The power control registers is a set of one-time-programmable registers
|
||||||
|
* in its own register space, accessed by writing addess bits to these
|
||||||
|
* two registers: bits 7,6,5 of PCTL_REG_LO corresponds to the 3 LSBs of
|
||||||
|
* the address and bits 8,9 of PCTL_REG_HI corresponds to the 2 MSBs of
|
||||||
|
* the address, forming an address space of 5 bits, i.e. 32 registers
|
||||||
|
* 0x00 ... 0x1f can be obtained.
|
||||||
|
*/
|
||||||
|
static int stw481x_get_pctl_reg(struct stw481x *stw481x, u8 reg)
|
||||||
|
{
|
||||||
|
u8 msb = (reg >> 3) & 0x03;
|
||||||
|
u8 lsb = (reg << 5) & 0xe0;
|
||||||
|
unsigned int val;
|
||||||
|
u8 vrfy;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_write(stw481x->map, STW_PCTL_REG_HI, msb);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
ret = regmap_write(stw481x->map, STW_PCTL_REG_LO, lsb);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
ret = regmap_read(stw481x->map, STW_PCTL_REG_HI, &val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
vrfy = (val & 0x03) << 3;
|
||||||
|
ret = regmap_read(stw481x->map, STW_PCTL_REG_LO, &val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
vrfy |= ((val >> 5) & 0x07);
|
||||||
|
if (vrfy != reg)
|
||||||
|
return -EIO;
|
||||||
|
return (val >> 1) & 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stw481x_startup(struct stw481x *stw481x)
|
||||||
|
{
|
||||||
|
/* Voltages multiplied by 100 */
|
||||||
|
u8 vcore_val[] = { 100, 105, 110, 115, 120, 122, 124, 126, 128,
|
||||||
|
130, 132, 134, 136, 138, 140, 145 };
|
||||||
|
u8 vpll_val[] = { 105, 120, 130, 180 };
|
||||||
|
u8 vaux_val[] = { 15, 18, 25, 28 };
|
||||||
|
u8 vcore;
|
||||||
|
u8 vcore_slp;
|
||||||
|
u8 vpll;
|
||||||
|
u8 vaux;
|
||||||
|
bool vaux_en;
|
||||||
|
bool it_warn;
|
||||||
|
int ret;
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
ret = regmap_read(stw481x->map, STW_CONF1, &val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
vaux_en = !!(val & STW_CONF1_PDN_VAUX);
|
||||||
|
it_warn = !!(val & STW_CONF1_IT_WARN);
|
||||||
|
|
||||||
|
dev_info(&stw481x->client->dev, "voltages %s\n",
|
||||||
|
(val & STW_CONF1_V_MONITORING) ? "OK" : "LOW");
|
||||||
|
dev_info(&stw481x->client->dev, "MMC level shifter %s\n",
|
||||||
|
(val & STW_CONF1_MMC_LS_STATUS) ? "high impedance" : "ON");
|
||||||
|
dev_info(&stw481x->client->dev, "VMMC: %s\n",
|
||||||
|
(val & STW_CONF1_PDN_VMMC) ? "ON" : "disabled");
|
||||||
|
|
||||||
|
dev_info(&stw481x->client->dev, "STw481x power control registers:\n");
|
||||||
|
|
||||||
|
ret = stw481x_get_pctl_reg(stw481x, STW_PC_VCORE_SEL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
vcore = ret & 0x0f;
|
||||||
|
|
||||||
|
ret = stw481x_get_pctl_reg(stw481x, STW_PC_VAUX_SEL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
vaux = (ret >> 2) & 3;
|
||||||
|
vpll = (ret >> 4) & 1; /* Save bit 4 */
|
||||||
|
|
||||||
|
ret = stw481x_get_pctl_reg(stw481x, STW_PC_VPLL_SEL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
vpll |= (ret >> 1) & 2;
|
||||||
|
|
||||||
|
dev_info(&stw481x->client->dev, "VCORE: %u.%uV %s\n",
|
||||||
|
vcore_val[vcore] / 100, vcore_val[vcore] % 100,
|
||||||
|
(ret & 4) ? "ON" : "OFF");
|
||||||
|
|
||||||
|
dev_info(&stw481x->client->dev, "VPLL: %u.%uV %s\n",
|
||||||
|
vpll_val[vpll] / 100, vpll_val[vpll] % 100,
|
||||||
|
(ret & 0x10) ? "ON" : "OFF");
|
||||||
|
|
||||||
|
dev_info(&stw481x->client->dev, "VAUX: %u.%uV %s\n",
|
||||||
|
vaux_val[vaux] / 10, vaux_val[vaux] % 10,
|
||||||
|
vaux_en ? "ON" : "OFF");
|
||||||
|
|
||||||
|
ret = regmap_read(stw481x->map, STW_CONF2, &val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
dev_info(&stw481x->client->dev, "TWARN: %s threshold, %s\n",
|
||||||
|
it_warn ? "below" : "above",
|
||||||
|
(val & STW_CONF2_MASK_TWARN) ?
|
||||||
|
"enabled" : "mask through VDDOK");
|
||||||
|
dev_info(&stw481x->client->dev, "VMMC: %s\n",
|
||||||
|
(val & STW_CONF2_VMMC_EXT) ? "internal" : "external");
|
||||||
|
dev_info(&stw481x->client->dev, "IT WAKE UP: %s\n",
|
||||||
|
(val & STW_CONF2_MASK_IT_WAKE_UP) ? "enabled" : "masked");
|
||||||
|
dev_info(&stw481x->client->dev, "GPO1: %s\n",
|
||||||
|
(val & STW_CONF2_GPO1) ? "low" : "high impedance");
|
||||||
|
dev_info(&stw481x->client->dev, "GPO2: %s\n",
|
||||||
|
(val & STW_CONF2_GPO2) ? "low" : "high impedance");
|
||||||
|
|
||||||
|
ret = regmap_read(stw481x->map, STW_VCORE_SLEEP, &val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
vcore_slp = val & 0x0f;
|
||||||
|
dev_info(&stw481x->client->dev, "VCORE SLEEP: %u.%uV\n",
|
||||||
|
vcore_val[vcore_slp] / 100, vcore_val[vcore_slp] % 100);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MFD cells - we have one cell which is selected operation
|
||||||
|
* mode, and we always have a GPIO cell.
|
||||||
|
*/
|
||||||
|
static struct mfd_cell stw481x_cells[] = {
|
||||||
|
{
|
||||||
|
.of_compatible = "st,stw481x-vmmc",
|
||||||
|
.name = "stw481x-vmmc-regulator",
|
||||||
|
.id = -1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct regmap_config stw481x_regmap_config = {
|
||||||
|
.reg_bits = 8,
|
||||||
|
.val_bits = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int stw481x_probe(struct i2c_client *client,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct stw481x *stw481x;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
stw481x = devm_kzalloc(&client->dev, sizeof(*stw481x), GFP_KERNEL);
|
||||||
|
if (!stw481x)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
i2c_set_clientdata(client, stw481x);
|
||||||
|
stw481x->client = client;
|
||||||
|
stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config);
|
||||||
|
|
||||||
|
ret = stw481x_startup(stw481x);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&client->dev, "chip initialization failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up and register the platform devices. */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(stw481x_cells); i++) {
|
||||||
|
/* One state holder for all drivers, this is simple */
|
||||||
|
stw481x_cells[i].platform_data = stw481x;
|
||||||
|
stw481x_cells[i].pdata_size = sizeof(*stw481x);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mfd_add_devices(&client->dev, 0, stw481x_cells,
|
||||||
|
ARRAY_SIZE(stw481x_cells), NULL, 0, NULL);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
dev_info(&client->dev, "initialized STw481x device\n");
|
||||||
|
|
||||||
|
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
|
||||||
|
* the structure of the I2C core.
|
||||||
|
*/
|
||||||
|
static const struct i2c_device_id stw481x_id[] = {
|
||||||
|
{ "stw481x", 0 },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id stw481x_match[] = {
|
||||||
|
{ .compatible = "st,stw4810", },
|
||||||
|
{ .compatible = "st,stw4811", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, stw481x_match);
|
||||||
|
|
||||||
|
static struct i2c_driver stw481x_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "stw481x",
|
||||||
|
.of_match_table = stw481x_match,
|
||||||
|
},
|
||||||
|
.probe = stw481x_probe,
|
||||||
|
.remove = stw481x_remove,
|
||||||
|
.id_table = stw481x_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_i2c_driver(stw481x_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Linus Walleij");
|
||||||
|
MODULE_DESCRIPTION("STw481x PMIC driver");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
|
@ -16,6 +16,19 @@
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/mfd/tc3589x.h>
|
#include <linux/mfd/tc3589x.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum tc3589x_version - indicates the TC3589x version
|
||||||
|
*/
|
||||||
|
enum tc3589x_version {
|
||||||
|
TC3589X_TC35890,
|
||||||
|
TC3589X_TC35892,
|
||||||
|
TC3589X_TC35893,
|
||||||
|
TC3589X_TC35894,
|
||||||
|
TC3589X_TC35895,
|
||||||
|
TC3589X_TC35896,
|
||||||
|
TC3589X_UNKNOWN,
|
||||||
|
};
|
||||||
|
|
||||||
#define TC3589x_CLKMODE_MODCTL_SLEEP 0x0
|
#define TC3589x_CLKMODE_MODCTL_SLEEP 0x0
|
||||||
#define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0)
|
#define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0)
|
||||||
|
|
||||||
|
@ -361,7 +374,21 @@ static int tc3589x_probe(struct i2c_client *i2c,
|
||||||
tc3589x->i2c = i2c;
|
tc3589x->i2c = i2c;
|
||||||
tc3589x->pdata = pdata;
|
tc3589x->pdata = pdata;
|
||||||
tc3589x->irq_base = pdata->irq_base;
|
tc3589x->irq_base = pdata->irq_base;
|
||||||
tc3589x->num_gpio = id->driver_data;
|
|
||||||
|
switch (id->driver_data) {
|
||||||
|
case TC3589X_TC35893:
|
||||||
|
case TC3589X_TC35895:
|
||||||
|
case TC3589X_TC35896:
|
||||||
|
tc3589x->num_gpio = 20;
|
||||||
|
break;
|
||||||
|
case TC3589X_TC35890:
|
||||||
|
case TC3589X_TC35892:
|
||||||
|
case TC3589X_TC35894:
|
||||||
|
case TC3589X_UNKNOWN:
|
||||||
|
default:
|
||||||
|
tc3589x->num_gpio = 24;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
i2c_set_clientdata(i2c, tc3589x);
|
i2c_set_clientdata(i2c, tc3589x);
|
||||||
|
|
||||||
|
@ -432,7 +459,13 @@ static int tc3589x_resume(struct device *dev)
|
||||||
static SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, tc3589x_resume);
|
static SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, tc3589x_resume);
|
||||||
|
|
||||||
static const struct i2c_device_id tc3589x_id[] = {
|
static const struct i2c_device_id tc3589x_id[] = {
|
||||||
{ "tc3589x", 24 },
|
{ "tc35890", TC3589X_TC35890 },
|
||||||
|
{ "tc35892", TC3589X_TC35892 },
|
||||||
|
{ "tc35893", TC3589X_TC35893 },
|
||||||
|
{ "tc35894", TC3589X_TC35894 },
|
||||||
|
{ "tc35895", TC3589X_TC35895 },
|
||||||
|
{ "tc35896", TC3589X_TC35896 },
|
||||||
|
{ "tc3589x", TC3589X_UNKNOWN },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c, tc3589x_id);
|
MODULE_DEVICE_TABLE(i2c, tc3589x_id);
|
||||||
|
|
|
@ -445,7 +445,6 @@ static int ti_ssp_remove(struct platform_device *pdev)
|
||||||
iounmap(ssp->regs);
|
iounmap(ssp->regs);
|
||||||
release_mem_region(ssp->res->start, resource_size(ssp->res));
|
release_mem_region(ssp->res->start, resource_size(ssp->res));
|
||||||
kfree(ssp);
|
kfree(ssp);
|
||||||
dev_set_drvdata(dev, NULL);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,21 +56,25 @@ EXPORT_SYMBOL_GPL(am335x_tsc_se_update);
|
||||||
|
|
||||||
void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
|
void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
|
||||||
{
|
{
|
||||||
spin_lock(&tsadc->reg_lock);
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tsadc->reg_lock, flags);
|
||||||
tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
|
tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
|
||||||
tsadc->reg_se_cache |= val;
|
tsadc->reg_se_cache |= val;
|
||||||
am335x_tsc_se_update(tsadc);
|
am335x_tsc_se_update(tsadc);
|
||||||
spin_unlock(&tsadc->reg_lock);
|
spin_unlock_irqrestore(&tsadc->reg_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
|
EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
|
||||||
|
|
||||||
void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
|
void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
|
||||||
{
|
{
|
||||||
spin_lock(&tsadc->reg_lock);
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tsadc->reg_lock, flags);
|
||||||
tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
|
tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
|
||||||
tsadc->reg_se_cache &= ~val;
|
tsadc->reg_se_cache &= ~val;
|
||||||
am335x_tsc_se_update(tsadc);
|
am335x_tsc_se_update(tsadc);
|
||||||
spin_unlock(&tsadc->reg_lock);
|
spin_unlock_irqrestore(&tsadc->reg_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
|
EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
|
||||||
|
|
||||||
|
@ -95,7 +99,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||||
const __be32 *cur;
|
const __be32 *cur;
|
||||||
u32 val;
|
u32 val;
|
||||||
int err, ctrl;
|
int err, ctrl;
|
||||||
int clk_value, clock_rate;
|
int clock_rate;
|
||||||
int tsc_wires = 0, adc_channels = 0, total_channels;
|
int tsc_wires = 0, adc_channels = 0, total_channels;
|
||||||
int readouts = 0;
|
int readouts = 0;
|
||||||
|
|
||||||
|
@ -196,11 +200,11 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
clock_rate = clk_get_rate(clk);
|
clock_rate = clk_get_rate(clk);
|
||||||
clk_put(clk);
|
clk_put(clk);
|
||||||
clk_value = clock_rate / ADC_CLK;
|
tscadc->clk_div = clock_rate / ADC_CLK;
|
||||||
|
|
||||||
/* TSCADC_CLKDIV needs to be configured to the value minus 1 */
|
/* TSCADC_CLKDIV needs to be configured to the value minus 1 */
|
||||||
clk_value = clk_value - 1;
|
tscadc->clk_div--;
|
||||||
tscadc_writel(tscadc, REG_CLKDIV, clk_value);
|
tscadc_writel(tscadc, REG_CLKDIV, tscadc->clk_div);
|
||||||
|
|
||||||
/* Set the control register bits */
|
/* Set the control register bits */
|
||||||
ctrl = CNTRLREG_STEPCONFIGWRT |
|
ctrl = CNTRLREG_STEPCONFIGWRT |
|
||||||
|
@ -303,6 +307,8 @@ static int tscadc_resume(struct device *dev)
|
||||||
tscadc_writel(tscadc_dev, REG_CTRL,
|
tscadc_writel(tscadc_dev, REG_CTRL,
|
||||||
(restore | CNTRLREG_TSCSSENB));
|
(restore | CNTRLREG_TSCSSENB));
|
||||||
|
|
||||||
|
tscadc_writel(tscadc_dev, REG_CLKDIV, tscadc_dev->clk_div);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +332,7 @@ static struct platform_driver ti_tscadc_driver = {
|
||||||
.name = "ti_am3359-tscadc",
|
.name = "ti_am3359-tscadc",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = TSCADC_PM_OPS,
|
.pm = TSCADC_PM_OPS,
|
||||||
.of_match_table = of_match_ptr(ti_tscadc_dt_ids),
|
.of_match_table = ti_tscadc_dt_ids,
|
||||||
},
|
},
|
||||||
.probe = ti_tscadc_probe,
|
.probe = ti_tscadc_probe,
|
||||||
.remove = ti_tscadc_remove,
|
.remove = ti_tscadc_remove,
|
||||||
|
|
|
@ -678,7 +678,7 @@ static int timb_probe(struct pci_dev *dev,
|
||||||
priv->ctl_mapbase = mapbase + CHIPCTLOFFSET;
|
priv->ctl_mapbase = mapbase + CHIPCTLOFFSET;
|
||||||
if (!request_mem_region(priv->ctl_mapbase, CHIPCTLSIZE, "timb-ctl")) {
|
if (!request_mem_region(priv->ctl_mapbase, CHIPCTLSIZE, "timb-ctl")) {
|
||||||
dev_err(&dev->dev, "Failed to request ctl mem\n");
|
dev_err(&dev->dev, "Failed to request ctl mem\n");
|
||||||
goto err_request;
|
goto err_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->ctl_membase = ioremap(priv->ctl_mapbase, CHIPCTLSIZE);
|
priv->ctl_membase = ioremap(priv->ctl_mapbase, CHIPCTLSIZE);
|
||||||
|
@ -828,13 +828,10 @@ static int timb_probe(struct pci_dev *dev,
|
||||||
iounmap(priv->ctl_membase);
|
iounmap(priv->ctl_membase);
|
||||||
err_ioremap:
|
err_ioremap:
|
||||||
release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
|
release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
|
||||||
err_request:
|
|
||||||
pci_set_drvdata(dev, NULL);
|
|
||||||
err_start:
|
err_start:
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
err_enable:
|
err_enable:
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
pci_set_drvdata(dev, NULL);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,7 +848,6 @@ static void timb_remove(struct pci_dev *dev)
|
||||||
|
|
||||||
pci_disable_msix(dev);
|
pci_disable_msix(dev);
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
pci_set_drvdata(dev, NULL);
|
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/mfd/tps6507x.h>
|
#include <linux/mfd/tps6507x.h>
|
||||||
|
|
|
@ -245,7 +245,7 @@ static struct i2c_driver tps65217_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "tps65217",
|
.name = "tps65217",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_match_table = of_match_ptr(tps65217_of_match),
|
.of_match_table = tps65217_of_match,
|
||||||
},
|
},
|
||||||
.id_table = tps65217_id_table,
|
.id_table = tps65217_id_table,
|
||||||
.probe = tps65217_probe,
|
.probe = tps65217_probe,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/mfd/tps6586x.h>
|
#include <linux/mfd/tps6586x.h>
|
||||||
|
@ -124,6 +125,7 @@ struct tps6586x {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
|
|
||||||
|
int irq;
|
||||||
struct irq_chip irq_chip;
|
struct irq_chip irq_chip;
|
||||||
struct mutex irq_lock;
|
struct mutex irq_lock;
|
||||||
int irq_base;
|
int irq_base;
|
||||||
|
@ -261,12 +263,23 @@ static void tps6586x_irq_sync_unlock(struct irq_data *data)
|
||||||
mutex_unlock(&tps6586x->irq_lock);
|
mutex_unlock(&tps6586x->irq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
static int tps6586x_irq_set_wake(struct irq_data *irq_data, unsigned int on)
|
||||||
|
{
|
||||||
|
struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
|
||||||
|
return irq_set_irq_wake(tps6586x->irq, on);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define tps6586x_irq_set_wake NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct irq_chip tps6586x_irq_chip = {
|
static struct irq_chip tps6586x_irq_chip = {
|
||||||
.name = "tps6586x",
|
.name = "tps6586x",
|
||||||
.irq_bus_lock = tps6586x_irq_lock,
|
.irq_bus_lock = tps6586x_irq_lock,
|
||||||
.irq_bus_sync_unlock = tps6586x_irq_sync_unlock,
|
.irq_bus_sync_unlock = tps6586x_irq_sync_unlock,
|
||||||
.irq_disable = tps6586x_irq_disable,
|
.irq_disable = tps6586x_irq_disable,
|
||||||
.irq_enable = tps6586x_irq_enable,
|
.irq_enable = tps6586x_irq_enable,
|
||||||
|
.irq_set_wake = tps6586x_irq_set_wake,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,
|
static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,
|
||||||
|
@ -331,6 +344,8 @@ static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
|
||||||
int new_irq_base;
|
int new_irq_base;
|
||||||
int irq_num = ARRAY_SIZE(tps6586x_irqs);
|
int irq_num = ARRAY_SIZE(tps6586x_irqs);
|
||||||
|
|
||||||
|
tps6586x->irq = irq;
|
||||||
|
|
||||||
mutex_init(&tps6586x->irq_lock);
|
mutex_init(&tps6586x->irq_lock);
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
tps6586x->mask_reg[i] = 0xff;
|
tps6586x->mask_reg[i] = 0xff;
|
||||||
|
@ -360,10 +375,8 @@ static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
|
||||||
ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,
|
ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,
|
||||||
"tps6586x", tps6586x);
|
"tps6586x", tps6586x);
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret)
|
||||||
device_init_wakeup(tps6586x->dev, 1);
|
device_init_wakeup(tps6586x->dev, 1);
|
||||||
enable_irq_wake(irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/mfd/tps65910.h>
|
#include <linux/mfd/tps65910.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
|
||||||
static struct resource rtc_resources[] = {
|
static struct resource rtc_resources[] = {
|
||||||
|
@ -410,14 +411,10 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
|
||||||
ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop);
|
ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
board_info->vmbch_threshold = prop;
|
board_info->vmbch_threshold = prop;
|
||||||
else if (*chip_id == TPS65911)
|
|
||||||
dev_warn(&client->dev, "VMBCH-Threshold not specified");
|
|
||||||
|
|
||||||
ret = of_property_read_u32(np, "ti,vmbch2-threshold", &prop);
|
ret = of_property_read_u32(np, "ti,vmbch2-threshold", &prop);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
board_info->vmbch2_threshold = prop;
|
board_info->vmbch2_threshold = prop;
|
||||||
else if (*chip_id == TPS65911)
|
|
||||||
dev_warn(&client->dev, "VMBCH2-Threshold not specified");
|
|
||||||
|
|
||||||
prop = of_property_read_bool(np, "ti,en-ck32k-xtal");
|
prop = of_property_read_bool(np, "ti,en-ck32k-xtal");
|
||||||
board_info->en_ck32k_xtal = prop;
|
board_info->en_ck32k_xtal = prop;
|
||||||
|
|
|
@ -565,13 +565,13 @@ static int twl6040_probe(struct i2c_client *client,
|
||||||
twl6040->supplies);
|
twl6040->supplies);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
|
dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
|
||||||
goto regulator_get_err;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
|
ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
|
dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
|
||||||
goto regulator_get_err;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
twl6040->dev = &client->dev;
|
twl6040->dev = &client->dev;
|
||||||
|
@ -619,7 +619,7 @@ static int twl6040_probe(struct i2c_client *client,
|
||||||
"twl6040_irq_th", twl6040);
|
"twl6040_irq_th", twl6040);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
|
dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
|
||||||
goto thirq_err;
|
goto readyirq_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dual-access registers controlled by I2C only */
|
/* dual-access registers controlled by I2C only */
|
||||||
|
@ -659,21 +659,14 @@ static int twl6040_probe(struct i2c_client *client,
|
||||||
ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
|
ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
|
||||||
NULL, 0, NULL);
|
NULL, 0, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto mfd_err;
|
goto readyirq_err;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mfd_err:
|
|
||||||
devm_free_irq(&client->dev, twl6040->irq_th, twl6040);
|
|
||||||
thirq_err:
|
|
||||||
devm_free_irq(&client->dev, twl6040->irq_ready, twl6040);
|
|
||||||
readyirq_err:
|
readyirq_err:
|
||||||
regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
|
regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
|
||||||
gpio_err:
|
gpio_err:
|
||||||
regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
|
regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
|
||||||
regulator_get_err:
|
|
||||||
i2c_set_clientdata(client, NULL);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,12 +677,9 @@ static int twl6040_remove(struct i2c_client *client)
|
||||||
if (twl6040->power_count)
|
if (twl6040->power_count)
|
||||||
twl6040_power(twl6040, 0);
|
twl6040_power(twl6040, 0);
|
||||||
|
|
||||||
devm_free_irq(&client->dev, twl6040->irq_ready, twl6040);
|
|
||||||
devm_free_irq(&client->dev, twl6040->irq_th, twl6040);
|
|
||||||
regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
|
regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
|
||||||
|
|
||||||
mfd_remove_devices(&client->dev);
|
mfd_remove_devices(&client->dev);
|
||||||
i2c_set_clientdata(client, NULL);
|
|
||||||
|
|
||||||
regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
|
regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
|
||||||
|
|
||||||
|
|
|
@ -553,6 +553,7 @@ static int ucb1x00_probe(struct mcp *mcp)
|
||||||
if (ucb->irq_base < 0) {
|
if (ucb->irq_base < 0) {
|
||||||
dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n",
|
dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n",
|
||||||
ucb->irq_base);
|
ucb->irq_base);
|
||||||
|
ret = ucb->irq_base;
|
||||||
goto err_irq_alloc;
|
goto err_irq_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -903,7 +903,6 @@ static const struct reg_default wm5102_reg_default[] = {
|
||||||
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
|
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
|
||||||
{ 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */
|
{ 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */
|
||||||
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
|
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
|
||||||
{ 0x00000D50, 0x0000 }, /* R3408 - AOD wkup and trig */
|
|
||||||
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
|
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
|
||||||
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
|
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
|
||||||
{ 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */
|
{ 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */
|
||||||
|
|
|
@ -243,6 +243,12 @@ int wm5110_patch(struct arizona *arizona)
|
||||||
EXPORT_SYMBOL_GPL(wm5110_patch);
|
EXPORT_SYMBOL_GPL(wm5110_patch);
|
||||||
|
|
||||||
static const struct regmap_irq wm5110_aod_irqs[ARIZONA_NUM_IRQ] = {
|
static const struct regmap_irq wm5110_aod_irqs[ARIZONA_NUM_IRQ] = {
|
||||||
|
[ARIZONA_IRQ_MICD_CLAMP_FALL] = {
|
||||||
|
.mask = ARIZONA_MICD_CLAMP_FALL_EINT1
|
||||||
|
},
|
||||||
|
[ARIZONA_IRQ_MICD_CLAMP_RISE] = {
|
||||||
|
.mask = ARIZONA_MICD_CLAMP_RISE_EINT1
|
||||||
|
},
|
||||||
[ARIZONA_IRQ_GP5_FALL] = { .mask = ARIZONA_GP5_FALL_EINT1 },
|
[ARIZONA_IRQ_GP5_FALL] = { .mask = ARIZONA_GP5_FALL_EINT1 },
|
||||||
[ARIZONA_IRQ_GP5_RISE] = { .mask = ARIZONA_GP5_RISE_EINT1 },
|
[ARIZONA_IRQ_GP5_RISE] = { .mask = ARIZONA_GP5_RISE_EINT1 },
|
||||||
[ARIZONA_IRQ_JD_FALL] = { .mask = ARIZONA_JD1_FALL_EINT1 },
|
[ARIZONA_IRQ_JD_FALL] = { .mask = ARIZONA_JD1_FALL_EINT1 },
|
||||||
|
@ -505,6 +511,7 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||||
{ 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */
|
{ 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */
|
||||||
{ 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */
|
{ 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */
|
||||||
{ 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */
|
{ 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */
|
||||||
|
{ 0x000002A2, 0x0000 }, /* R674 - Micd clamp control */
|
||||||
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
|
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
|
||||||
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
|
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
|
||||||
{ 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */
|
{ 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */
|
||||||
|
@ -592,7 +599,7 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||||
{ 0x0000043E, 0x0080 }, /* R1086 - DAC Volume Limit 6R */
|
{ 0x0000043E, 0x0080 }, /* R1086 - DAC Volume Limit 6R */
|
||||||
{ 0x0000043F, 0x0800 }, /* R1087 - Noise Gate Select 6R */
|
{ 0x0000043F, 0x0800 }, /* R1087 - Noise Gate Select 6R */
|
||||||
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
|
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
|
||||||
{ 0x00000458, 0x0001 }, /* R1112 - Noise Gate Control */
|
{ 0x00000458, 0x0000 }, /* R1112 - Noise Gate Control */
|
||||||
{ 0x00000480, 0x0040 }, /* R1152 - Class W ANC Threshold 1 */
|
{ 0x00000480, 0x0040 }, /* R1152 - Class W ANC Threshold 1 */
|
||||||
{ 0x00000481, 0x0040 }, /* R1153 - Class W ANC Threshold 2 */
|
{ 0x00000481, 0x0040 }, /* R1153 - Class W ANC Threshold 2 */
|
||||||
{ 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */
|
{ 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */
|
||||||
|
@ -1204,7 +1211,6 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||||
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
|
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
|
||||||
{ 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */
|
{ 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */
|
||||||
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
|
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
|
||||||
{ 0x00000D50, 0x0000 }, /* R3408 - AOD wkup and trig */
|
|
||||||
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
|
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
|
||||||
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
|
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
|
||||||
{ 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */
|
{ 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */
|
||||||
|
@ -1440,6 +1446,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||||
case ARIZONA_ACCESSORY_DETECT_MODE_1:
|
case ARIZONA_ACCESSORY_DETECT_MODE_1:
|
||||||
case ARIZONA_HEADPHONE_DETECT_1:
|
case ARIZONA_HEADPHONE_DETECT_1:
|
||||||
case ARIZONA_HEADPHONE_DETECT_2:
|
case ARIZONA_HEADPHONE_DETECT_2:
|
||||||
|
case ARIZONA_MICD_CLAMP_CONTROL:
|
||||||
case ARIZONA_MIC_DETECT_1:
|
case ARIZONA_MIC_DETECT_1:
|
||||||
case ARIZONA_MIC_DETECT_2:
|
case ARIZONA_MIC_DETECT_2:
|
||||||
case ARIZONA_MIC_DETECT_3:
|
case ARIZONA_MIC_DETECT_3:
|
||||||
|
@ -2291,21 +2298,37 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||||
case ARIZONA_DSP1_STATUS_1:
|
case ARIZONA_DSP1_STATUS_1:
|
||||||
case ARIZONA_DSP1_STATUS_2:
|
case ARIZONA_DSP1_STATUS_2:
|
||||||
case ARIZONA_DSP1_STATUS_3:
|
case ARIZONA_DSP1_STATUS_3:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_3:
|
||||||
case ARIZONA_DSP2_CONTROL_1:
|
case ARIZONA_DSP2_CONTROL_1:
|
||||||
case ARIZONA_DSP2_CLOCKING_1:
|
case ARIZONA_DSP2_CLOCKING_1:
|
||||||
case ARIZONA_DSP2_STATUS_1:
|
case ARIZONA_DSP2_STATUS_1:
|
||||||
case ARIZONA_DSP2_STATUS_2:
|
case ARIZONA_DSP2_STATUS_2:
|
||||||
case ARIZONA_DSP2_STATUS_3:
|
case ARIZONA_DSP2_STATUS_3:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_3:
|
||||||
case ARIZONA_DSP3_CONTROL_1:
|
case ARIZONA_DSP3_CONTROL_1:
|
||||||
case ARIZONA_DSP3_CLOCKING_1:
|
case ARIZONA_DSP3_CLOCKING_1:
|
||||||
case ARIZONA_DSP3_STATUS_1:
|
case ARIZONA_DSP3_STATUS_1:
|
||||||
case ARIZONA_DSP3_STATUS_2:
|
case ARIZONA_DSP3_STATUS_2:
|
||||||
case ARIZONA_DSP3_STATUS_3:
|
case ARIZONA_DSP3_STATUS_3:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_3:
|
||||||
case ARIZONA_DSP4_CONTROL_1:
|
case ARIZONA_DSP4_CONTROL_1:
|
||||||
case ARIZONA_DSP4_CLOCKING_1:
|
case ARIZONA_DSP4_CLOCKING_1:
|
||||||
case ARIZONA_DSP4_STATUS_1:
|
case ARIZONA_DSP4_STATUS_1:
|
||||||
case ARIZONA_DSP4_STATUS_2:
|
case ARIZONA_DSP4_STATUS_2:
|
||||||
case ARIZONA_DSP4_STATUS_3:
|
case ARIZONA_DSP4_STATUS_3:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_3:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -2347,25 +2370,41 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
|
||||||
case ARIZONA_INTERRUPT_RAW_STATUS_7:
|
case ARIZONA_INTERRUPT_RAW_STATUS_7:
|
||||||
case ARIZONA_INTERRUPT_RAW_STATUS_8:
|
case ARIZONA_INTERRUPT_RAW_STATUS_8:
|
||||||
case ARIZONA_IRQ_PIN_STATUS:
|
case ARIZONA_IRQ_PIN_STATUS:
|
||||||
|
case ARIZONA_AOD_WKUP_AND_TRIG:
|
||||||
case ARIZONA_AOD_IRQ1:
|
case ARIZONA_AOD_IRQ1:
|
||||||
case ARIZONA_AOD_IRQ2:
|
case ARIZONA_AOD_IRQ2:
|
||||||
|
case ARIZONA_AOD_IRQ_RAW_STATUS:
|
||||||
case ARIZONA_FX_CTRL2:
|
case ARIZONA_FX_CTRL2:
|
||||||
case ARIZONA_ASRC_STATUS:
|
case ARIZONA_ASRC_STATUS:
|
||||||
case ARIZONA_DSP_STATUS:
|
case ARIZONA_DSP_STATUS:
|
||||||
case ARIZONA_DSP1_CONTROL_1:
|
|
||||||
case ARIZONA_DSP1_CLOCKING_1:
|
|
||||||
case ARIZONA_DSP1_STATUS_1:
|
case ARIZONA_DSP1_STATUS_1:
|
||||||
case ARIZONA_DSP1_STATUS_2:
|
case ARIZONA_DSP1_STATUS_2:
|
||||||
case ARIZONA_DSP1_STATUS_3:
|
case ARIZONA_DSP1_STATUS_3:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP1_SCRATCH_3:
|
||||||
case ARIZONA_DSP2_STATUS_1:
|
case ARIZONA_DSP2_STATUS_1:
|
||||||
case ARIZONA_DSP2_STATUS_2:
|
case ARIZONA_DSP2_STATUS_2:
|
||||||
case ARIZONA_DSP2_STATUS_3:
|
case ARIZONA_DSP2_STATUS_3:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP2_SCRATCH_3:
|
||||||
case ARIZONA_DSP3_STATUS_1:
|
case ARIZONA_DSP3_STATUS_1:
|
||||||
case ARIZONA_DSP3_STATUS_2:
|
case ARIZONA_DSP3_STATUS_2:
|
||||||
case ARIZONA_DSP3_STATUS_3:
|
case ARIZONA_DSP3_STATUS_3:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP3_SCRATCH_3:
|
||||||
case ARIZONA_DSP4_STATUS_1:
|
case ARIZONA_DSP4_STATUS_1:
|
||||||
case ARIZONA_DSP4_STATUS_2:
|
case ARIZONA_DSP4_STATUS_2:
|
||||||
case ARIZONA_DSP4_STATUS_3:
|
case ARIZONA_DSP4_STATUS_3:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_0:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_1:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_2:
|
||||||
|
case ARIZONA_DSP4_SCRATCH_3:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -33,84 +33,6 @@
|
||||||
|
|
||||||
#include "wm8994.h"
|
#include "wm8994.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* wm8994_reg_read: Read a single WM8994 register.
|
|
||||||
*
|
|
||||||
* @wm8994: Device to read from.
|
|
||||||
* @reg: Register to read.
|
|
||||||
*/
|
|
||||||
int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
|
|
||||||
{
|
|
||||||
unsigned int val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = regmap_read(wm8994->regmap, reg, &val);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
else
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(wm8994_reg_read);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wm8994_bulk_read: Read multiple WM8994 registers
|
|
||||||
*
|
|
||||||
* @wm8994: Device to read from
|
|
||||||
* @reg: First register
|
|
||||||
* @count: Number of registers
|
|
||||||
* @buf: Buffer to fill. The data will be returned big endian.
|
|
||||||
*/
|
|
||||||
int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
int count, u16 *buf)
|
|
||||||
{
|
|
||||||
return regmap_bulk_read(wm8994->regmap, reg, buf, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wm8994_reg_write: Write a single WM8994 register.
|
|
||||||
*
|
|
||||||
* @wm8994: Device to write to.
|
|
||||||
* @reg: Register to write to.
|
|
||||||
* @val: Value to write.
|
|
||||||
*/
|
|
||||||
int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
unsigned short val)
|
|
||||||
{
|
|
||||||
return regmap_write(wm8994->regmap, reg, val);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(wm8994_reg_write);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wm8994_bulk_write: Write multiple WM8994 registers
|
|
||||||
*
|
|
||||||
* @wm8994: Device to write to
|
|
||||||
* @reg: First register
|
|
||||||
* @count: Number of registers
|
|
||||||
* @buf: Buffer to write from. Data must be big-endian formatted.
|
|
||||||
*/
|
|
||||||
int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
int count, const u16 *buf)
|
|
||||||
{
|
|
||||||
return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16));
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(wm8994_bulk_write);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wm8994_set_bits: Set the value of a bitfield in a WM8994 register
|
|
||||||
*
|
|
||||||
* @wm8994: Device to write to.
|
|
||||||
* @reg: Register to write to.
|
|
||||||
* @mask: Mask of bits to set.
|
|
||||||
* @val: Value to set (unshifted)
|
|
||||||
*/
|
|
||||||
int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
unsigned short mask, unsigned short val)
|
|
||||||
{
|
|
||||||
return regmap_update_bits(wm8994->regmap, reg, mask, val);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(wm8994_set_bits);
|
|
||||||
|
|
||||||
static struct mfd_cell wm8994_regulator_devs[] = {
|
static struct mfd_cell wm8994_regulator_devs[] = {
|
||||||
{
|
{
|
||||||
.name = "wm8994-ldo",
|
.name = "wm8994-ldo",
|
||||||
|
|
52
include/dt-bindings/mfd/as3722.h
Normal file
52
include/dt-bindings/mfd/as3722.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* This header provides macros for ams AS3722 device bindings.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, NVIDIA Corporation.
|
||||||
|
*
|
||||||
|
* Author: Laxman Dewangan <ldewangan@nvidia.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DT_BINDINGS_AS3722_H__
|
||||||
|
#define __DT_BINDINGS_AS3722_H__
|
||||||
|
|
||||||
|
/* External control pins */
|
||||||
|
#define AS3722_EXT_CONTROL_PIN_ENABLE1 1
|
||||||
|
#define AS3722_EXT_CONTROL_PIN_ENABLE2 2
|
||||||
|
#define AS3722_EXT_CONTROL_PIN_ENABLE2 3
|
||||||
|
|
||||||
|
/* Interrupt numbers for AS3722 */
|
||||||
|
#define AS3722_IRQ_LID 0
|
||||||
|
#define AS3722_IRQ_ACOK 1
|
||||||
|
#define AS3722_IRQ_ENABLE1 2
|
||||||
|
#define AS3722_IRQ_OCCUR_ALARM_SD0 3
|
||||||
|
#define AS3722_IRQ_ONKEY_LONG_PRESS 4
|
||||||
|
#define AS3722_IRQ_ONKEY 5
|
||||||
|
#define AS3722_IRQ_OVTMP 6
|
||||||
|
#define AS3722_IRQ_LOWBAT 7
|
||||||
|
#define AS3722_IRQ_SD0_LV 8
|
||||||
|
#define AS3722_IRQ_SD1_LV 9
|
||||||
|
#define AS3722_IRQ_SD2_LV 10
|
||||||
|
#define AS3722_IRQ_PWM1_OV_PROT 11
|
||||||
|
#define AS3722_IRQ_PWM2_OV_PROT 12
|
||||||
|
#define AS3722_IRQ_ENABLE2 13
|
||||||
|
#define AS3722_IRQ_SD6_LV 14
|
||||||
|
#define AS3722_IRQ_RTC_REP 15
|
||||||
|
#define AS3722_IRQ_RTC_ALARM 16
|
||||||
|
#define AS3722_IRQ_GPIO1 17
|
||||||
|
#define AS3722_IRQ_GPIO2 18
|
||||||
|
#define AS3722_IRQ_GPIO3 19
|
||||||
|
#define AS3722_IRQ_GPIO4 20
|
||||||
|
#define AS3722_IRQ_GPIO5 21
|
||||||
|
#define AS3722_IRQ_WATCHDOG 22
|
||||||
|
#define AS3722_IRQ_ENABLE3 23
|
||||||
|
#define AS3722_IRQ_TEMP_SD0_SHUTDOWN 24
|
||||||
|
#define AS3722_IRQ_TEMP_SD1_SHUTDOWN 25
|
||||||
|
#define AS3722_IRQ_TEMP_SD2_SHUTDOWN 26
|
||||||
|
#define AS3722_IRQ_TEMP_SD0_ALARM 27
|
||||||
|
#define AS3722_IRQ_TEMP_SD1_ALARM 28
|
||||||
|
#define AS3722_IRQ_TEMP_SD6_ALARM 29
|
||||||
|
#define AS3722_IRQ_OCCUR_ALARM_SD6 30
|
||||||
|
#define AS3722_IRQ_ADC 31
|
||||||
|
|
||||||
|
#endif /* __DT_BINDINGS_AS3722_H__ */
|
|
@ -1908,7 +1908,7 @@
|
||||||
#define ARIZONA_FLL2_SYNC_GAIN_MASK 0x003c /* FLL2_SYNC_GAIN */
|
#define ARIZONA_FLL2_SYNC_GAIN_MASK 0x003c /* FLL2_SYNC_GAIN */
|
||||||
#define ARIZONA_FLL2_SYNC_GAIN_SHIFT 2 /* FLL2_SYNC_GAIN */
|
#define ARIZONA_FLL2_SYNC_GAIN_SHIFT 2 /* FLL2_SYNC_GAIN */
|
||||||
#define ARIZONA_FLL2_SYNC_GAIN_WIDTH 4 /* FLL2_SYNC_GAIN */
|
#define ARIZONA_FLL2_SYNC_GAIN_WIDTH 4 /* FLL2_SYNC_GAIN */
|
||||||
#define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */
|
#define ARIZONA_FLL2_SYNC_BW 0x0001 /* FLL2_SYNC_BW */
|
||||||
#define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */
|
#define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */
|
||||||
#define ARIZONA_FLL2_SYNC_BW_SHIFT 0 /* FLL2_SYNC_BW */
|
#define ARIZONA_FLL2_SYNC_BW_SHIFT 0 /* FLL2_SYNC_BW */
|
||||||
#define ARIZONA_FLL2_SYNC_BW_WIDTH 1 /* FLL2_SYNC_BW */
|
#define ARIZONA_FLL2_SYNC_BW_WIDTH 1 /* FLL2_SYNC_BW */
|
||||||
|
|
423
include/linux/mfd/as3722.h
Normal file
423
include/linux/mfd/as3722.h
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
/*
|
||||||
|
* as3722 definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 ams
|
||||||
|
* Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Author: Florian Lobmaier <florian.lobmaier@ams.com>
|
||||||
|
* Author: Laxman Dewangan <ldewangan@nvidia.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LINUX_MFD_AS3722_H__
|
||||||
|
#define __LINUX_MFD_AS3722_H__
|
||||||
|
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
|
/* AS3722 registers */
|
||||||
|
#define AS3722_SD0_VOLTAGE_REG 0x00
|
||||||
|
#define AS3722_SD1_VOLTAGE_REG 0x01
|
||||||
|
#define AS3722_SD2_VOLTAGE_REG 0x02
|
||||||
|
#define AS3722_SD3_VOLTAGE_REG 0x03
|
||||||
|
#define AS3722_SD4_VOLTAGE_REG 0x04
|
||||||
|
#define AS3722_SD5_VOLTAGE_REG 0x05
|
||||||
|
#define AS3722_SD6_VOLTAGE_REG 0x06
|
||||||
|
#define AS3722_GPIO0_CONTROL_REG 0x08
|
||||||
|
#define AS3722_GPIO1_CONTROL_REG 0x09
|
||||||
|
#define AS3722_GPIO2_CONTROL_REG 0x0A
|
||||||
|
#define AS3722_GPIO3_CONTROL_REG 0x0B
|
||||||
|
#define AS3722_GPIO4_CONTROL_REG 0x0C
|
||||||
|
#define AS3722_GPIO5_CONTROL_REG 0x0D
|
||||||
|
#define AS3722_GPIO6_CONTROL_REG 0x0E
|
||||||
|
#define AS3722_GPIO7_CONTROL_REG 0x0F
|
||||||
|
#define AS3722_LDO0_VOLTAGE_REG 0x10
|
||||||
|
#define AS3722_LDO1_VOLTAGE_REG 0x11
|
||||||
|
#define AS3722_LDO2_VOLTAGE_REG 0x12
|
||||||
|
#define AS3722_LDO3_VOLTAGE_REG 0x13
|
||||||
|
#define AS3722_LDO4_VOLTAGE_REG 0x14
|
||||||
|
#define AS3722_LDO5_VOLTAGE_REG 0x15
|
||||||
|
#define AS3722_LDO6_VOLTAGE_REG 0x16
|
||||||
|
#define AS3722_LDO7_VOLTAGE_REG 0x17
|
||||||
|
#define AS3722_LDO9_VOLTAGE_REG 0x19
|
||||||
|
#define AS3722_LDO10_VOLTAGE_REG 0x1A
|
||||||
|
#define AS3722_LDO11_VOLTAGE_REG 0x1B
|
||||||
|
#define AS3722_GPIO_DEB1_REG 0x1E
|
||||||
|
#define AS3722_GPIO_DEB2_REG 0x1F
|
||||||
|
#define AS3722_GPIO_SIGNAL_OUT_REG 0x20
|
||||||
|
#define AS3722_GPIO_SIGNAL_IN_REG 0x21
|
||||||
|
#define AS3722_REG_SEQU_MOD1_REG 0x22
|
||||||
|
#define AS3722_REG_SEQU_MOD2_REG 0x23
|
||||||
|
#define AS3722_REG_SEQU_MOD3_REG 0x24
|
||||||
|
#define AS3722_SD_PHSW_CTRL_REG 0x27
|
||||||
|
#define AS3722_SD_PHSW_STATUS 0x28
|
||||||
|
#define AS3722_SD0_CONTROL_REG 0x29
|
||||||
|
#define AS3722_SD1_CONTROL_REG 0x2A
|
||||||
|
#define AS3722_SDmph_CONTROL_REG 0x2B
|
||||||
|
#define AS3722_SD23_CONTROL_REG 0x2C
|
||||||
|
#define AS3722_SD4_CONTROL_REG 0x2D
|
||||||
|
#define AS3722_SD5_CONTROL_REG 0x2E
|
||||||
|
#define AS3722_SD6_CONTROL_REG 0x2F
|
||||||
|
#define AS3722_SD_DVM_REG 0x30
|
||||||
|
#define AS3722_RESET_REASON_REG 0x31
|
||||||
|
#define AS3722_BATTERY_VOLTAGE_MONITOR_REG 0x32
|
||||||
|
#define AS3722_STARTUP_CONTROL_REG 0x33
|
||||||
|
#define AS3722_RESET_TIMER_REG 0x34
|
||||||
|
#define AS3722_REFERENCE_CONTROL_REG 0x35
|
||||||
|
#define AS3722_RESET_CONTROL_REG 0x36
|
||||||
|
#define AS3722_OVER_TEMP_CONTROL_REG 0x37
|
||||||
|
#define AS3722_WATCHDOG_CONTROL_REG 0x38
|
||||||
|
#define AS3722_REG_STANDBY_MOD1_REG 0x39
|
||||||
|
#define AS3722_REG_STANDBY_MOD2_REG 0x3A
|
||||||
|
#define AS3722_REG_STANDBY_MOD3_REG 0x3B
|
||||||
|
#define AS3722_ENABLE_CTRL1_REG 0x3C
|
||||||
|
#define AS3722_ENABLE_CTRL2_REG 0x3D
|
||||||
|
#define AS3722_ENABLE_CTRL3_REG 0x3E
|
||||||
|
#define AS3722_ENABLE_CTRL4_REG 0x3F
|
||||||
|
#define AS3722_ENABLE_CTRL5_REG 0x40
|
||||||
|
#define AS3722_PWM_CONTROL_L_REG 0x41
|
||||||
|
#define AS3722_PWM_CONTROL_H_REG 0x42
|
||||||
|
#define AS3722_WATCHDOG_TIMER_REG 0x46
|
||||||
|
#define AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG 0x48
|
||||||
|
#define AS3722_IOVOLTAGE_REG 0x49
|
||||||
|
#define AS3722_BATTERY_VOLTAGE_MONITOR2_REG 0x4A
|
||||||
|
#define AS3722_SD_CONTROL_REG 0x4D
|
||||||
|
#define AS3722_LDOCONTROL0_REG 0x4E
|
||||||
|
#define AS3722_LDOCONTROL1_REG 0x4F
|
||||||
|
#define AS3722_SD0_PROTECT_REG 0x50
|
||||||
|
#define AS3722_SD6_PROTECT_REG 0x51
|
||||||
|
#define AS3722_PWM_VCONTROL1_REG 0x52
|
||||||
|
#define AS3722_PWM_VCONTROL2_REG 0x53
|
||||||
|
#define AS3722_PWM_VCONTROL3_REG 0x54
|
||||||
|
#define AS3722_PWM_VCONTROL4_REG 0x55
|
||||||
|
#define AS3722_BB_CHARGER_REG 0x57
|
||||||
|
#define AS3722_CTRL_SEQU1_REG 0x58
|
||||||
|
#define AS3722_CTRL_SEQU2_REG 0x59
|
||||||
|
#define AS3722_OVCURRENT_REG 0x5A
|
||||||
|
#define AS3722_OVCURRENT_DEB_REG 0x5B
|
||||||
|
#define AS3722_SDLV_DEB_REG 0x5C
|
||||||
|
#define AS3722_OC_PG_CTRL_REG 0x5D
|
||||||
|
#define AS3722_OC_PG_CTRL2_REG 0x5E
|
||||||
|
#define AS3722_CTRL_STATUS 0x5F
|
||||||
|
#define AS3722_RTC_CONTROL_REG 0x60
|
||||||
|
#define AS3722_RTC_SECOND_REG 0x61
|
||||||
|
#define AS3722_RTC_MINUTE_REG 0x62
|
||||||
|
#define AS3722_RTC_HOUR_REG 0x63
|
||||||
|
#define AS3722_RTC_DAY_REG 0x64
|
||||||
|
#define AS3722_RTC_MONTH_REG 0x65
|
||||||
|
#define AS3722_RTC_YEAR_REG 0x66
|
||||||
|
#define AS3722_RTC_ALARM_SECOND_REG 0x67
|
||||||
|
#define AS3722_RTC_ALARM_MINUTE_REG 0x68
|
||||||
|
#define AS3722_RTC_ALARM_HOUR_REG 0x69
|
||||||
|
#define AS3722_RTC_ALARM_DAY_REG 0x6A
|
||||||
|
#define AS3722_RTC_ALARM_MONTH_REG 0x6B
|
||||||
|
#define AS3722_RTC_ALARM_YEAR_REG 0x6C
|
||||||
|
#define AS3722_SRAM_REG 0x6D
|
||||||
|
#define AS3722_RTC_ACCESS_REG 0x6F
|
||||||
|
#define AS3722_RTC_STATUS_REG 0x73
|
||||||
|
#define AS3722_INTERRUPT_MASK1_REG 0x74
|
||||||
|
#define AS3722_INTERRUPT_MASK2_REG 0x75
|
||||||
|
#define AS3722_INTERRUPT_MASK3_REG 0x76
|
||||||
|
#define AS3722_INTERRUPT_MASK4_REG 0x77
|
||||||
|
#define AS3722_INTERRUPT_STATUS1_REG 0x78
|
||||||
|
#define AS3722_INTERRUPT_STATUS2_REG 0x79
|
||||||
|
#define AS3722_INTERRUPT_STATUS3_REG 0x7A
|
||||||
|
#define AS3722_INTERRUPT_STATUS4_REG 0x7B
|
||||||
|
#define AS3722_TEMP_STATUS_REG 0x7D
|
||||||
|
#define AS3722_ADC0_CONTROL_REG 0x80
|
||||||
|
#define AS3722_ADC1_CONTROL_REG 0x81
|
||||||
|
#define AS3722_ADC0_MSB_RESULT_REG 0x82
|
||||||
|
#define AS3722_ADC0_LSB_RESULT_REG 0x83
|
||||||
|
#define AS3722_ADC1_MSB_RESULT_REG 0x84
|
||||||
|
#define AS3722_ADC1_LSB_RESULT_REG 0x85
|
||||||
|
#define AS3722_ADC1_THRESHOLD_HI_MSB_REG 0x86
|
||||||
|
#define AS3722_ADC1_THRESHOLD_HI_LSB_REG 0x87
|
||||||
|
#define AS3722_ADC1_THRESHOLD_LO_MSB_REG 0x88
|
||||||
|
#define AS3722_ADC1_THRESHOLD_LO_LSB_REG 0x89
|
||||||
|
#define AS3722_ADC_CONFIGURATION_REG 0x8A
|
||||||
|
#define AS3722_ASIC_ID1_REG 0x90
|
||||||
|
#define AS3722_ASIC_ID2_REG 0x91
|
||||||
|
#define AS3722_LOCK_REG 0x9E
|
||||||
|
#define AS3722_MAX_REGISTER 0xF4
|
||||||
|
|
||||||
|
#define AS3722_SD0_EXT_ENABLE_MASK 0x03
|
||||||
|
#define AS3722_SD1_EXT_ENABLE_MASK 0x0C
|
||||||
|
#define AS3722_SD2_EXT_ENABLE_MASK 0x30
|
||||||
|
#define AS3722_SD3_EXT_ENABLE_MASK 0xC0
|
||||||
|
#define AS3722_SD4_EXT_ENABLE_MASK 0x03
|
||||||
|
#define AS3722_SD5_EXT_ENABLE_MASK 0x0C
|
||||||
|
#define AS3722_SD6_EXT_ENABLE_MASK 0x30
|
||||||
|
#define AS3722_LDO0_EXT_ENABLE_MASK 0x03
|
||||||
|
#define AS3722_LDO1_EXT_ENABLE_MASK 0x0C
|
||||||
|
#define AS3722_LDO2_EXT_ENABLE_MASK 0x30
|
||||||
|
#define AS3722_LDO3_EXT_ENABLE_MASK 0xC0
|
||||||
|
#define AS3722_LDO4_EXT_ENABLE_MASK 0x03
|
||||||
|
#define AS3722_LDO5_EXT_ENABLE_MASK 0x0C
|
||||||
|
#define AS3722_LDO6_EXT_ENABLE_MASK 0x30
|
||||||
|
#define AS3722_LDO7_EXT_ENABLE_MASK 0xC0
|
||||||
|
#define AS3722_LDO9_EXT_ENABLE_MASK 0x0C
|
||||||
|
#define AS3722_LDO10_EXT_ENABLE_MASK 0x30
|
||||||
|
#define AS3722_LDO11_EXT_ENABLE_MASK 0xC0
|
||||||
|
|
||||||
|
#define AS3722_OVCURRENT_SD0_ALARM_MASK 0x07
|
||||||
|
#define AS3722_OVCURRENT_SD0_ALARM_SHIFT 0x01
|
||||||
|
#define AS3722_OVCURRENT_SD0_TRIP_MASK 0x18
|
||||||
|
#define AS3722_OVCURRENT_SD0_TRIP_SHIFT 0x03
|
||||||
|
#define AS3722_OVCURRENT_SD1_TRIP_MASK 0x60
|
||||||
|
#define AS3722_OVCURRENT_SD1_TRIP_SHIFT 0x05
|
||||||
|
|
||||||
|
#define AS3722_OVCURRENT_SD6_ALARM_MASK 0x07
|
||||||
|
#define AS3722_OVCURRENT_SD6_ALARM_SHIFT 0x01
|
||||||
|
#define AS3722_OVCURRENT_SD6_TRIP_MASK 0x18
|
||||||
|
#define AS3722_OVCURRENT_SD6_TRIP_SHIFT 0x03
|
||||||
|
|
||||||
|
/* AS3722 register bits and bit masks */
|
||||||
|
#define AS3722_LDO_ILIMIT_MASK BIT(7)
|
||||||
|
#define AS3722_LDO_ILIMIT_BIT BIT(7)
|
||||||
|
#define AS3722_LDO0_VSEL_MASK 0x1F
|
||||||
|
#define AS3722_LDO0_VSEL_MIN 0x01
|
||||||
|
#define AS3722_LDO0_VSEL_MAX 0x12
|
||||||
|
#define AS3722_LDO0_NUM_VOLT 0x12
|
||||||
|
#define AS3722_LDO3_VSEL_MASK 0x3F
|
||||||
|
#define AS3722_LDO3_VSEL_MIN 0x01
|
||||||
|
#define AS3722_LDO3_VSEL_MAX 0x2D
|
||||||
|
#define AS3722_LDO3_NUM_VOLT 0x2D
|
||||||
|
#define AS3722_LDO_VSEL_MASK 0x7F
|
||||||
|
#define AS3722_LDO_VSEL_MIN 0x01
|
||||||
|
#define AS3722_LDO_VSEL_MAX 0x7F
|
||||||
|
#define AS3722_LDO_VSEL_DNU_MIN 0x25
|
||||||
|
#define AS3722_LDO_VSEL_DNU_MAX 0x3F
|
||||||
|
#define AS3722_LDO_NUM_VOLT 0x80
|
||||||
|
|
||||||
|
#define AS3722_LDO0_CTRL BIT(0)
|
||||||
|
#define AS3722_LDO1_CTRL BIT(1)
|
||||||
|
#define AS3722_LDO2_CTRL BIT(2)
|
||||||
|
#define AS3722_LDO3_CTRL BIT(3)
|
||||||
|
#define AS3722_LDO4_CTRL BIT(4)
|
||||||
|
#define AS3722_LDO5_CTRL BIT(5)
|
||||||
|
#define AS3722_LDO6_CTRL BIT(6)
|
||||||
|
#define AS3722_LDO7_CTRL BIT(7)
|
||||||
|
#define AS3722_LDO9_CTRL BIT(1)
|
||||||
|
#define AS3722_LDO10_CTRL BIT(2)
|
||||||
|
#define AS3722_LDO11_CTRL BIT(3)
|
||||||
|
|
||||||
|
#define AS3722_LDO3_MODE_MASK (3 << 6)
|
||||||
|
#define AS3722_LDO3_MODE_VAL(n) (((n) & 0x3) << 6)
|
||||||
|
#define AS3722_LDO3_MODE_PMOS AS3722_LDO3_MODE_VAL(0)
|
||||||
|
#define AS3722_LDO3_MODE_PMOS_TRACKING AS3722_LDO3_MODE_VAL(1)
|
||||||
|
#define AS3722_LDO3_MODE_NMOS AS3722_LDO3_MODE_VAL(2)
|
||||||
|
#define AS3722_LDO3_MODE_SWITCH AS3722_LDO3_MODE_VAL(3)
|
||||||
|
|
||||||
|
#define AS3722_SD_VSEL_MASK 0x7F
|
||||||
|
#define AS3722_SD0_VSEL_MIN 0x01
|
||||||
|
#define AS3722_SD0_VSEL_MAX 0x5A
|
||||||
|
#define AS3722_SD2_VSEL_MIN 0x01
|
||||||
|
#define AS3722_SD2_VSEL_MAX 0x7F
|
||||||
|
|
||||||
|
#define AS3722_SDn_CTRL(n) BIT(n)
|
||||||
|
|
||||||
|
#define AS3722_SD0_MODE_FAST BIT(4)
|
||||||
|
#define AS3722_SD1_MODE_FAST BIT(4)
|
||||||
|
#define AS3722_SD2_MODE_FAST BIT(2)
|
||||||
|
#define AS3722_SD3_MODE_FAST BIT(6)
|
||||||
|
#define AS3722_SD4_MODE_FAST BIT(2)
|
||||||
|
#define AS3722_SD5_MODE_FAST BIT(2)
|
||||||
|
#define AS3722_SD6_MODE_FAST BIT(4)
|
||||||
|
|
||||||
|
#define AS3722_POWER_OFF BIT(1)
|
||||||
|
|
||||||
|
#define AS3722_INTERRUPT_MASK1_LID BIT(0)
|
||||||
|
#define AS3722_INTERRUPT_MASK1_ACOK BIT(1)
|
||||||
|
#define AS3722_INTERRUPT_MASK1_ENABLE1 BIT(2)
|
||||||
|
#define AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0 BIT(3)
|
||||||
|
#define AS3722_INTERRUPT_MASK1_ONKEY_LONG BIT(4)
|
||||||
|
#define AS3722_INTERRUPT_MASK1_ONKEY BIT(5)
|
||||||
|
#define AS3722_INTERRUPT_MASK1_OVTMP BIT(6)
|
||||||
|
#define AS3722_INTERRUPT_MASK1_LOWBAT BIT(7)
|
||||||
|
|
||||||
|
#define AS3722_INTERRUPT_MASK2_SD0_LV BIT(0)
|
||||||
|
#define AS3722_INTERRUPT_MASK2_SD1_LV BIT(1)
|
||||||
|
#define AS3722_INTERRUPT_MASK2_SD2345_LV BIT(2)
|
||||||
|
#define AS3722_INTERRUPT_MASK2_PWM1_OV_PROT BIT(3)
|
||||||
|
#define AS3722_INTERRUPT_MASK2_PWM2_OV_PROT BIT(4)
|
||||||
|
#define AS3722_INTERRUPT_MASK2_ENABLE2 BIT(5)
|
||||||
|
#define AS3722_INTERRUPT_MASK2_SD6_LV BIT(6)
|
||||||
|
#define AS3722_INTERRUPT_MASK2_RTC_REP BIT(7)
|
||||||
|
|
||||||
|
#define AS3722_INTERRUPT_MASK3_RTC_ALARM BIT(0)
|
||||||
|
#define AS3722_INTERRUPT_MASK3_GPIO1 BIT(1)
|
||||||
|
#define AS3722_INTERRUPT_MASK3_GPIO2 BIT(2)
|
||||||
|
#define AS3722_INTERRUPT_MASK3_GPIO3 BIT(3)
|
||||||
|
#define AS3722_INTERRUPT_MASK3_GPIO4 BIT(4)
|
||||||
|
#define AS3722_INTERRUPT_MASK3_GPIO5 BIT(5)
|
||||||
|
#define AS3722_INTERRUPT_MASK3_WATCHDOG BIT(6)
|
||||||
|
#define AS3722_INTERRUPT_MASK3_ENABLE3 BIT(7)
|
||||||
|
|
||||||
|
#define AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN BIT(0)
|
||||||
|
#define AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN BIT(1)
|
||||||
|
#define AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN BIT(2)
|
||||||
|
#define AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM BIT(3)
|
||||||
|
#define AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM BIT(4)
|
||||||
|
#define AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM BIT(5)
|
||||||
|
#define AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6 BIT(6)
|
||||||
|
#define AS3722_INTERRUPT_MASK4_ADC BIT(7)
|
||||||
|
|
||||||
|
#define AS3722_ADC1_INTERVAL_TIME BIT(0)
|
||||||
|
#define AS3722_ADC1_INT_MODE_ON BIT(1)
|
||||||
|
#define AS3722_ADC_BUF_ON BIT(2)
|
||||||
|
#define AS3722_ADC1_LOW_VOLTAGE_RANGE BIT(5)
|
||||||
|
#define AS3722_ADC1_INTEVAL_SCAN BIT(6)
|
||||||
|
#define AS3722_ADC1_INT_MASK BIT(7)
|
||||||
|
|
||||||
|
#define AS3722_ADC_MSB_VAL_MASK 0x7F
|
||||||
|
#define AS3722_ADC_LSB_VAL_MASK 0x07
|
||||||
|
|
||||||
|
#define AS3722_ADC0_CONV_START BIT(7)
|
||||||
|
#define AS3722_ADC0_CONV_NOTREADY BIT(7)
|
||||||
|
#define AS3722_ADC0_SOURCE_SELECT_MASK 0x1F
|
||||||
|
|
||||||
|
#define AS3722_ADC1_CONV_START BIT(7)
|
||||||
|
#define AS3722_ADC1_CONV_NOTREADY BIT(7)
|
||||||
|
#define AS3722_ADC1_SOURCE_SELECT_MASK 0x1F
|
||||||
|
|
||||||
|
/* GPIO modes */
|
||||||
|
#define AS3722_GPIO_MODE_MASK 0x07
|
||||||
|
#define AS3722_GPIO_MODE_INPUT 0x00
|
||||||
|
#define AS3722_GPIO_MODE_OUTPUT_VDDH 0x01
|
||||||
|
#define AS3722_GPIO_MODE_IO_OPEN_DRAIN 0x02
|
||||||
|
#define AS3722_GPIO_MODE_ADC_IN 0x03
|
||||||
|
#define AS3722_GPIO_MODE_INPUT_PULL_UP 0x04
|
||||||
|
#define AS3722_GPIO_MODE_INPUT_PULL_DOWN 0x05
|
||||||
|
#define AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP 0x06
|
||||||
|
#define AS3722_GPIO_MODE_OUTPUT_VDDL 0x07
|
||||||
|
#define AS3722_GPIO_MODE_VAL(n) ((n) & AS3722_GPIO_MODE_MASK)
|
||||||
|
|
||||||
|
#define AS3722_GPIO_INV BIT(7)
|
||||||
|
#define AS3722_GPIO_IOSF_MASK 0x78
|
||||||
|
#define AS3722_GPIO_IOSF_VAL(n) (((n) & 0xF) << 3)
|
||||||
|
#define AS3722_GPIO_IOSF_NORMAL AS3722_GPIO_IOSF_VAL(0)
|
||||||
|
#define AS3722_GPIO_IOSF_INTERRUPT_OUT AS3722_GPIO_IOSF_VAL(1)
|
||||||
|
#define AS3722_GPIO_IOSF_VSUP_LOW_OUT AS3722_GPIO_IOSF_VAL(2)
|
||||||
|
#define AS3722_GPIO_IOSF_GPIO_INTERRUPT_IN AS3722_GPIO_IOSF_VAL(3)
|
||||||
|
#define AS3722_GPIO_IOSF_ISINK_PWM_IN AS3722_GPIO_IOSF_VAL(4)
|
||||||
|
#define AS3722_GPIO_IOSF_VOLTAGE_STBY AS3722_GPIO_IOSF_VAL(5)
|
||||||
|
#define AS3722_GPIO_IOSF_PWR_GOOD_OUT AS3722_GPIO_IOSF_VAL(7)
|
||||||
|
#define AS3722_GPIO_IOSF_Q32K_OUT AS3722_GPIO_IOSF_VAL(8)
|
||||||
|
#define AS3722_GPIO_IOSF_WATCHDOG_IN AS3722_GPIO_IOSF_VAL(9)
|
||||||
|
#define AS3722_GPIO_IOSF_SOFT_RESET_IN AS3722_GPIO_IOSF_VAL(11)
|
||||||
|
#define AS3722_GPIO_IOSF_PWM_OUT AS3722_GPIO_IOSF_VAL(12)
|
||||||
|
#define AS3722_GPIO_IOSF_VSUP_LOW_DEB_OUT AS3722_GPIO_IOSF_VAL(13)
|
||||||
|
#define AS3722_GPIO_IOSF_SD6_LOW_VOLT_LOW AS3722_GPIO_IOSF_VAL(14)
|
||||||
|
|
||||||
|
#define AS3722_GPIOn_SIGNAL(n) BIT(n)
|
||||||
|
#define AS3722_GPIOn_CONTROL_REG(n) (AS3722_GPIO0_CONTROL_REG + n)
|
||||||
|
#define AS3722_I2C_PULL_UP BIT(4)
|
||||||
|
#define AS3722_INT_PULL_UP BIT(5)
|
||||||
|
|
||||||
|
#define AS3722_RTC_REP_WAKEUP_EN BIT(0)
|
||||||
|
#define AS3722_RTC_ALARM_WAKEUP_EN BIT(1)
|
||||||
|
#define AS3722_RTC_ON BIT(2)
|
||||||
|
#define AS3722_RTC_IRQMODE BIT(3)
|
||||||
|
#define AS3722_RTC_CLK32K_OUT_EN BIT(5)
|
||||||
|
|
||||||
|
#define AS3722_WATCHDOG_TIMER_MAX 0x7F
|
||||||
|
#define AS3722_WATCHDOG_ON BIT(0)
|
||||||
|
#define AS3722_WATCHDOG_SW_SIG BIT(0)
|
||||||
|
|
||||||
|
#define AS3722_EXT_CONTROL_ENABLE1 0x1
|
||||||
|
#define AS3722_EXT_CONTROL_ENABLE2 0x2
|
||||||
|
#define AS3722_EXT_CONTROL_ENABLE3 0x3
|
||||||
|
|
||||||
|
/* Interrupt IDs */
|
||||||
|
enum as3722_irq {
|
||||||
|
AS3722_IRQ_LID,
|
||||||
|
AS3722_IRQ_ACOK,
|
||||||
|
AS3722_IRQ_ENABLE1,
|
||||||
|
AS3722_IRQ_OCCUR_ALARM_SD0,
|
||||||
|
AS3722_IRQ_ONKEY_LONG_PRESS,
|
||||||
|
AS3722_IRQ_ONKEY,
|
||||||
|
AS3722_IRQ_OVTMP,
|
||||||
|
AS3722_IRQ_LOWBAT,
|
||||||
|
AS3722_IRQ_SD0_LV,
|
||||||
|
AS3722_IRQ_SD1_LV,
|
||||||
|
AS3722_IRQ_SD2_LV,
|
||||||
|
AS3722_IRQ_PWM1_OV_PROT,
|
||||||
|
AS3722_IRQ_PWM2_OV_PROT,
|
||||||
|
AS3722_IRQ_ENABLE2,
|
||||||
|
AS3722_IRQ_SD6_LV,
|
||||||
|
AS3722_IRQ_RTC_REP,
|
||||||
|
AS3722_IRQ_RTC_ALARM,
|
||||||
|
AS3722_IRQ_GPIO1,
|
||||||
|
AS3722_IRQ_GPIO2,
|
||||||
|
AS3722_IRQ_GPIO3,
|
||||||
|
AS3722_IRQ_GPIO4,
|
||||||
|
AS3722_IRQ_GPIO5,
|
||||||
|
AS3722_IRQ_WATCHDOG,
|
||||||
|
AS3722_IRQ_ENABLE3,
|
||||||
|
AS3722_IRQ_TEMP_SD0_SHUTDOWN,
|
||||||
|
AS3722_IRQ_TEMP_SD1_SHUTDOWN,
|
||||||
|
AS3722_IRQ_TEMP_SD2_SHUTDOWN,
|
||||||
|
AS3722_IRQ_TEMP_SD0_ALARM,
|
||||||
|
AS3722_IRQ_TEMP_SD1_ALARM,
|
||||||
|
AS3722_IRQ_TEMP_SD6_ALARM,
|
||||||
|
AS3722_IRQ_OCCUR_ALARM_SD6,
|
||||||
|
AS3722_IRQ_ADC,
|
||||||
|
AS3722_IRQ_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct as3722 {
|
||||||
|
struct device *dev;
|
||||||
|
struct regmap *regmap;
|
||||||
|
int chip_irq;
|
||||||
|
unsigned long irq_flags;
|
||||||
|
bool en_intern_int_pullup;
|
||||||
|
bool en_intern_i2c_pullup;
|
||||||
|
struct regmap_irq_chip_data *irq_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int as3722_read(struct as3722 *as3722, u32 reg, u32 *dest)
|
||||||
|
{
|
||||||
|
return regmap_read(as3722->regmap, reg, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int as3722_write(struct as3722 *as3722, u32 reg, u32 value)
|
||||||
|
{
|
||||||
|
return regmap_write(as3722->regmap, reg, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int as3722_block_read(struct as3722 *as3722, u32 reg,
|
||||||
|
int count, u8 *buf)
|
||||||
|
{
|
||||||
|
return regmap_bulk_read(as3722->regmap, reg, buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int as3722_block_write(struct as3722 *as3722, u32 reg,
|
||||||
|
int count, u8 *data)
|
||||||
|
{
|
||||||
|
return regmap_bulk_write(as3722->regmap, reg, data, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int as3722_update_bits(struct as3722 *as3722, u32 reg,
|
||||||
|
u32 mask, u8 val)
|
||||||
|
{
|
||||||
|
return regmap_update_bits(as3722->regmap, reg, mask, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int as3722_irq_get_virq(struct as3722 *as3722, int irq)
|
||||||
|
{
|
||||||
|
return regmap_irq_get_virq(as3722->irq_data, irq);
|
||||||
|
}
|
||||||
|
#endif /* __LINUX_MFD_AS3722_H__ */
|
|
@ -104,7 +104,7 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int mfd_add_devices(struct device *parent, int id,
|
extern int mfd_add_devices(struct device *parent, int id,
|
||||||
struct mfd_cell *cells, int n_devs,
|
const struct mfd_cell *cells, int n_devs,
|
||||||
struct resource *mem_base,
|
struct resource *mem_base,
|
||||||
int irq_base, struct irq_domain *irq_domain);
|
int irq_base, struct irq_domain *irq_domain);
|
||||||
|
|
||||||
|
|
|
@ -148,10 +148,15 @@ static inline int da9052_group_read(struct da9052 *da9052, unsigned char reg,
|
||||||
unsigned reg_cnt, unsigned char *val)
|
unsigned reg_cnt, unsigned char *val)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
unsigned int tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
ret = regmap_bulk_read(da9052->regmap, reg, val, reg_cnt);
|
for (i = 0; i < reg_cnt; i++) {
|
||||||
if (ret < 0)
|
ret = regmap_read(da9052->regmap, reg + i, &tmp);
|
||||||
return ret;
|
val[i] = (unsigned char)tmp;
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (da9052->fix_io) {
|
if (da9052->fix_io) {
|
||||||
ret = da9052->fix_io(da9052, reg);
|
ret = da9052->fix_io(da9052, reg);
|
||||||
|
@ -166,10 +171,13 @@ static inline int da9052_group_write(struct da9052 *da9052, unsigned char reg,
|
||||||
unsigned reg_cnt, unsigned char *val)
|
unsigned reg_cnt, unsigned char *val)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
ret = regmap_raw_write(da9052->regmap, reg, val, reg_cnt);
|
for (i = 0; i < reg_cnt; i++) {
|
||||||
if (ret < 0)
|
ret = regmap_write(da9052->regmap, reg + i, val[i]);
|
||||||
return ret;
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (da9052->fix_io) {
|
if (da9052->fix_io) {
|
||||||
ret = da9052->fix_io(da9052, reg);
|
ret = da9052->fix_io(da9052, reg);
|
||||||
|
|
|
@ -323,7 +323,6 @@ struct max77693_dev {
|
||||||
|
|
||||||
int irq;
|
int irq;
|
||||||
int irq_gpio;
|
int irq_gpio;
|
||||||
bool wakeup;
|
|
||||||
struct mutex irqlock;
|
struct mutex irqlock;
|
||||||
int irq_masks_cur[MAX77693_IRQ_GROUP_NR];
|
int irq_masks_cur[MAX77693_IRQ_GROUP_NR];
|
||||||
int irq_masks_cache[MAX77693_IRQ_GROUP_NR];
|
int irq_masks_cache[MAX77693_IRQ_GROUP_NR];
|
||||||
|
|
|
@ -64,8 +64,6 @@ struct max77693_muic_platform_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct max77693_platform_data {
|
struct max77693_platform_data {
|
||||||
int wakeup;
|
|
||||||
|
|
||||||
/* regulator data */
|
/* regulator data */
|
||||||
struct max77693_regulator_data *regulators;
|
struct max77693_regulator_data *regulators;
|
||||||
int num_regulators;
|
int num_regulators;
|
||||||
|
|
|
@ -756,6 +756,59 @@
|
||||||
#define PCR_SETTING_REG2 0x814
|
#define PCR_SETTING_REG2 0x814
|
||||||
#define PCR_SETTING_REG3 0x747
|
#define PCR_SETTING_REG3 0x747
|
||||||
|
|
||||||
|
/* Phy bits */
|
||||||
|
#define PHY_PCR_FORCE_CODE 0xB000
|
||||||
|
#define PHY_PCR_OOBS_CALI_50 0x0800
|
||||||
|
#define PHY_PCR_OOBS_VCM_08 0x0200
|
||||||
|
#define PHY_PCR_OOBS_SEN_90 0x0040
|
||||||
|
#define PHY_PCR_RSSI_EN 0x0002
|
||||||
|
|
||||||
|
#define PHY_RCR1_ADP_TIME 0x0100
|
||||||
|
#define PHY_RCR1_VCO_COARSE 0x001F
|
||||||
|
|
||||||
|
#define PHY_RCR2_EMPHASE_EN 0x8000
|
||||||
|
#define PHY_RCR2_NADJR 0x4000
|
||||||
|
#define PHY_RCR2_CDR_CP_10 0x0400
|
||||||
|
#define PHY_RCR2_CDR_SR_2 0x0100
|
||||||
|
#define PHY_RCR2_FREQSEL_12 0x0040
|
||||||
|
#define PHY_RCR2_CPADJEN 0x0020
|
||||||
|
#define PHY_RCR2_CDR_SC_8 0x0008
|
||||||
|
#define PHY_RCR2_CALIB_LATE 0x0002
|
||||||
|
|
||||||
|
#define PHY_RDR_RXDSEL_1_9 0x4000
|
||||||
|
|
||||||
|
#define PHY_TUNE_TUNEREF_1_0 0x4000
|
||||||
|
#define PHY_TUNE_VBGSEL_1252 0x0C00
|
||||||
|
#define PHY_TUNE_SDBUS_33 0x0200
|
||||||
|
#define PHY_TUNE_TUNED18 0x01C0
|
||||||
|
#define PHY_TUNE_TUNED12 0X0020
|
||||||
|
|
||||||
|
#define PHY_BPCR_IBRXSEL 0x0400
|
||||||
|
#define PHY_BPCR_IBTXSEL 0x0100
|
||||||
|
#define PHY_BPCR_IB_FILTER 0x0080
|
||||||
|
#define PHY_BPCR_CMIRROR_EN 0x0040
|
||||||
|
|
||||||
|
#define PHY_REG_REV_RESV 0xE000
|
||||||
|
#define PHY_REG_REV_RXIDLE_LATCHED 0x1000
|
||||||
|
#define PHY_REG_REV_P1_EN 0x0800
|
||||||
|
#define PHY_REG_REV_RXIDLE_EN 0x0400
|
||||||
|
#define PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 0x0040
|
||||||
|
#define PHY_REG_REV_STOP_CLKRD 0x0020
|
||||||
|
#define PHY_REG_REV_RX_PWST 0x0008
|
||||||
|
#define PHY_REG_REV_STOP_CLKWR 0x0004
|
||||||
|
|
||||||
|
#define PHY_FLD3_TIMER_4 0x7800
|
||||||
|
#define PHY_FLD3_TIMER_6 0x00E0
|
||||||
|
#define PHY_FLD3_RXDELINK 0x0004
|
||||||
|
|
||||||
|
#define PHY_FLD4_FLDEN_SEL 0x4000
|
||||||
|
#define PHY_FLD4_REQ_REF 0x2000
|
||||||
|
#define PHY_FLD4_RXAMP_OFF 0x1000
|
||||||
|
#define PHY_FLD4_REQ_ADDA 0x0800
|
||||||
|
#define PHY_FLD4_BER_COUNT 0x00E0
|
||||||
|
#define PHY_FLD4_BER_TIMER 0x000A
|
||||||
|
#define PHY_FLD4_BER_CHK_EN 0x0001
|
||||||
|
|
||||||
#define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0)
|
#define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0)
|
||||||
|
|
||||||
struct rtsx_pcr;
|
struct rtsx_pcr;
|
||||||
|
|
56
include/linux/mfd/stw481x.h
Normal file
56
include/linux/mfd/stw481x.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 ST-Ericsson SA
|
||||||
|
* Written on behalf of Linaro for ST-Ericsson
|
||||||
|
*
|
||||||
|
* Author: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
*
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
*/
|
||||||
|
#ifndef MFD_STW481X_H
|
||||||
|
#define MFD_STW481X_H
|
||||||
|
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/regulator/machine.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
|
/* These registers are accessed from more than one driver */
|
||||||
|
#define STW_CONF1 0x11U
|
||||||
|
#define STW_CONF1_PDN_VMMC 0x01U
|
||||||
|
#define STW_CONF1_VMMC_MASK 0x0eU
|
||||||
|
#define STW_CONF1_VMMC_1_8V 0x02U
|
||||||
|
#define STW_CONF1_VMMC_2_85V 0x04U
|
||||||
|
#define STW_CONF1_VMMC_3V 0x06U
|
||||||
|
#define STW_CONF1_VMMC_1_85V 0x08U
|
||||||
|
#define STW_CONF1_VMMC_2_6V 0x0aU
|
||||||
|
#define STW_CONF1_VMMC_2_7V 0x0cU
|
||||||
|
#define STW_CONF1_VMMC_3_3V 0x0eU
|
||||||
|
#define STW_CONF1_MMC_LS_STATUS 0x10U
|
||||||
|
#define STW_PCTL_REG_LO 0x1eU
|
||||||
|
#define STW_PCTL_REG_HI 0x1fU
|
||||||
|
#define STW_CONF1_V_MONITORING 0x20U
|
||||||
|
#define STW_CONF1_IT_WARN 0x40U
|
||||||
|
#define STW_CONF1_PDN_VAUX 0x80U
|
||||||
|
#define STW_CONF2 0x20U
|
||||||
|
#define STW_CONF2_MASK_TWARN 0x01U
|
||||||
|
#define STW_CONF2_VMMC_EXT 0x02U
|
||||||
|
#define STW_CONF2_MASK_IT_WAKE_UP 0x04U
|
||||||
|
#define STW_CONF2_GPO1 0x08U
|
||||||
|
#define STW_CONF2_GPO2 0x10U
|
||||||
|
#define STW_VCORE_SLEEP 0x21U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct stw481x - state holder for the Stw481x drivers
|
||||||
|
* @mutex: mutex to serialize I2C accesses
|
||||||
|
* @i2c_client: corresponding I2C client
|
||||||
|
* @regulator: regulator device for regulator children
|
||||||
|
* @map: regmap handle to access device registers
|
||||||
|
*/
|
||||||
|
struct stw481x {
|
||||||
|
struct mutex lock;
|
||||||
|
struct i2c_client *client;
|
||||||
|
struct regulator_dev *vmmc_regulator;
|
||||||
|
struct regmap *map;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,10 +17,35 @@
|
||||||
|
|
||||||
struct device_node;
|
struct device_node;
|
||||||
|
|
||||||
|
#ifdef CONFIG_MFD_SYSCON
|
||||||
extern struct regmap *syscon_node_to_regmap(struct device_node *np);
|
extern struct regmap *syscon_node_to_regmap(struct device_node *np);
|
||||||
extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
|
extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
|
||||||
extern struct regmap *syscon_regmap_lookup_by_pdevname(const char *s);
|
extern struct regmap *syscon_regmap_lookup_by_pdevname(const char *s);
|
||||||
extern struct regmap *syscon_regmap_lookup_by_phandle(
|
extern struct regmap *syscon_regmap_lookup_by_phandle(
|
||||||
struct device_node *np,
|
struct device_node *np,
|
||||||
const char *property);
|
const char *property);
|
||||||
|
#else
|
||||||
|
static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
|
||||||
|
{
|
||||||
|
return ERR_PTR(-ENOSYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
|
||||||
|
{
|
||||||
|
return ERR_PTR(-ENOSYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct regmap *syscon_regmap_lookup_by_pdevname(const char *s)
|
||||||
|
{
|
||||||
|
return ERR_PTR(-ENOSYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct regmap *syscon_regmap_lookup_by_phandle(
|
||||||
|
struct device_node *np,
|
||||||
|
const char *property)
|
||||||
|
{
|
||||||
|
return ERR_PTR(-ENOSYS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __LINUX_MFD_SYSCON_H__ */
|
#endif /* __LINUX_MFD_SYSCON_H__ */
|
||||||
|
|
|
@ -134,13 +134,18 @@
|
||||||
#define FIFO1_THRESHOLD 19
|
#define FIFO1_THRESHOLD 19
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC runs at 3MHz, and it takes
|
* time in us for processing a single channel, calculated as follows:
|
||||||
* 15 cycles to latch one data output.
|
*
|
||||||
* Hence the idle time for ADC to
|
* num cycles = open delay + (sample delay + conv time) * averaging
|
||||||
* process one sample data would be
|
*
|
||||||
* around 5 micro seconds.
|
* num cycles: 152 + (1 + 13) * 16 = 376
|
||||||
*/
|
*
|
||||||
#define IDLE_TIMEOUT 5 /* microsec */
|
* clock frequency: 26MHz / 8 = 3.25MHz
|
||||||
|
* clock period: 1 / 3.25MHz = 308ns
|
||||||
|
*
|
||||||
|
* processing time: 376 * 308ns = 116us
|
||||||
|
*/
|
||||||
|
#define IDLE_TIMEOUT 116 /* microsec */
|
||||||
|
|
||||||
#define TSCADC_CELLS 2
|
#define TSCADC_CELLS 2
|
||||||
|
|
||||||
|
@ -155,6 +160,7 @@ struct ti_tscadc_dev {
|
||||||
struct mfd_cell cells[TSCADC_CELLS];
|
struct mfd_cell cells[TSCADC_CELLS];
|
||||||
u32 reg_se_cache;
|
u32 reg_se_cache;
|
||||||
spinlock_t reg_lock;
|
spinlock_t reg_lock;
|
||||||
|
unsigned int clk_div;
|
||||||
|
|
||||||
/* tsc device */
|
/* tsc device */
|
||||||
struct titsc *tsc;
|
struct titsc *tsc;
|
||||||
|
|
|
@ -56,8 +56,6 @@ struct irq_domain;
|
||||||
#define WM8994_IRQ_GPIO(x) (x + WM8994_IRQ_TEMP_WARN)
|
#define WM8994_IRQ_GPIO(x) (x + WM8994_IRQ_TEMP_WARN)
|
||||||
|
|
||||||
struct wm8994 {
|
struct wm8994 {
|
||||||
struct mutex irq_lock;
|
|
||||||
|
|
||||||
struct wm8994_pdata pdata;
|
struct wm8994_pdata pdata;
|
||||||
|
|
||||||
enum wm8994_type type;
|
enum wm8994_type type;
|
||||||
|
@ -85,16 +83,43 @@ struct wm8994 {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Device I/O API */
|
/* Device I/O API */
|
||||||
int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg);
|
|
||||||
int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
unsigned short val);
|
|
||||||
int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
unsigned short mask, unsigned short val);
|
|
||||||
int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
int count, u16 *buf);
|
|
||||||
int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
|
|
||||||
int count, const u16 *buf);
|
|
||||||
|
|
||||||
|
static inline int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_read(wm8994->regmap, reg, &val);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
|
||||||
|
unsigned short val)
|
||||||
|
{
|
||||||
|
return regmap_write(wm8994->regmap, reg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
|
||||||
|
int count, u16 *buf)
|
||||||
|
{
|
||||||
|
return regmap_bulk_read(wm8994->regmap, reg, buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
|
||||||
|
int count, const u16 *buf)
|
||||||
|
{
|
||||||
|
return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
|
||||||
|
unsigned short mask, unsigned short val)
|
||||||
|
{
|
||||||
|
return regmap_update_bits(wm8994->regmap, reg, mask, val);
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper to save on boilerplate */
|
/* Helper to save on boilerplate */
|
||||||
static inline int wm8994_request_irq(struct wm8994 *wm8994, int irq,
|
static inline int wm8994_request_irq(struct wm8994 *wm8994, int irq,
|
||||||
|
|
Loading…
Reference in a new issue