summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-18 20:15:11 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-18 20:15:11 +0300
commit12e7b0a62752234497de51356903f5f4e6bd2f77 (patch)
tree700601b833bf3e4097eb9307ed3fcc5d32d8d117
parent021f163d696caed5a336fa1569efdd22216da340 (diff)
parent0343b2f4e4a52c907d7676ce3159e0b5e7f0301c (diff)
downloadlinux-12e7b0a62752234497de51356903f5f4e6bd2f77.tar.xz
Merge tag 'mfd-for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "New Drivers: - Freescale Touch Screen ADC - X-Powers AXP PMIC with RSB - TI TPS65086 Power Management IC (PMIC) New Device Support: - Supply device PCI IDs for Intel Broxton Fix-ups: - Move to clkdev_create() API; intel_quark_i2c_gpio - Complete re-write of TI's TPS65912 Power Management IC (PMIC) - Remove unnecessary function argument; axp20x - Separate out bus related code; axp20x - Coding Style changes; axp20x - Allow more drivers to be compiled as modules - Work around false positive 'used uninitialised' warning; db8500-prcmu Bug Fixes: - Remove do_div(); fsl-imx25-gcq - Fix driver init when built-in; tps65010 - Fix clock-unregister leak; intel-lpss" * tag 'mfd-for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (53 commits) mfd: intel-lpss: Pass I2C configuration via properties on BXT mfd: imx6sx: Add PCIe register definitions for iomuxc gpr mfd: ipaq-micro: Use __maybe_unused to hide pm functions mfd: max77686: Add max77802 to I2C device ID table mfd: max77686: Export OF module alias information mfd: max77686: Allow driver to be built as a module mfd: stmpe: Add the proper PWM resources mfd: tps65090: Set regmap config reg counts properly mfd: syscon: Return ENOTSUPP instead of ENOSYS when disabled mfd: as3711: Set regmap config reg counts properly mfd: rc5t583: Set regmap config reg counts properly gpio: tps65086: Add GPO driver for the TPS65086 PMIC mfd: mt6397: Add platform device ID table mfd: da9063: Fix missing volatile registers in the core regmap_range volatile lists mfd: mt6397: Add MT6323 support to MT6397 driver mfd: mt6397: Add support for different Slave types mfd: mt6397: int_con and int_status may vary in location dt-bindings: mfd: Add bindings for the MediaTek MT6323 PMIC mfd: da9062: Fix missing volatile registers in the core regmap_range volatile lists mfd: Add documentation for ACT8945A DT bindings ...
-rw-r--r--Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt58
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/fsl-mx25-tcq.txt35
-rw-r--r--Documentation/devicetree/bindings/mfd/act8945a.txt76
-rw-r--r--Documentation/devicetree/bindings/mfd/axp20x.txt7
-rw-r--r--Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt47
-rw-r--r--Documentation/devicetree/bindings/mfd/mt6397.txt10
-rw-r--r--Documentation/devicetree/bindings/mfd/tps65086.txt55
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-tps65086.c139
-rw-r--r--drivers/iio/adc/Kconfig7
-rw-r--r--drivers/iio/adc/Makefile1
-rw-r--r--drivers/iio/adc/fsl-imx25-gcq.c417
-rw-r--r--drivers/input/touchscreen/Kconfig9
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/fsl-imx25-tcq.c596
-rw-r--r--drivers/mfd/Kconfig80
-rw-r--r--drivers/mfd/Makefile6
-rw-r--r--drivers/mfd/act8945a.c102
-rw-r--r--drivers/mfd/as3711.c4
-rw-r--r--drivers/mfd/axp20x-i2c.c104
-rw-r--r--drivers/mfd/axp20x-rsb.c80
-rw-r--r--drivers/mfd/axp20x.c105
-rw-r--r--drivers/mfd/cs47l24-tables.c10
-rw-r--r--drivers/mfd/da9062-core.c23
-rw-r--r--drivers/mfd/da9063-i2c.c36
-rw-r--r--drivers/mfd/db8500-prcmu.c7
-rw-r--r--drivers/mfd/fsl-imx25-tsadc.c203
-rw-r--r--drivers/mfd/intel-lpss-acpi.c12
-rw-r--r--drivers/mfd/intel-lpss-pci.c31
-rw-r--r--drivers/mfd/intel-lpss.c1
-rw-r--r--drivers/mfd/intel_quark_i2c_gpio.c26
-rw-r--r--drivers/mfd/ipaq-micro.c2
-rw-r--r--drivers/mfd/max77686.c2
-rw-r--r--drivers/mfd/mt6397-core.c105
-rw-r--r--drivers/mfd/rc5t583.c4
-rw-r--r--drivers/mfd/stmpe.c35
-rw-r--r--drivers/mfd/syscon.c19
-rw-r--r--drivers/mfd/tps65010.c21
-rw-r--r--drivers/mfd/tps65086.c149
-rw-r--r--drivers/mfd/tps65090.c5
-rw-r--r--drivers/mfd/wm5102-tables.c16
-rw-r--r--drivers/mfd/wm5110-tables.c82
-rw-r--r--drivers/mfd/wm8998-tables.c12
-rw-r--r--drivers/regulator/axp20x-regulator.c3
-rw-r--r--include/dt-bindings/iio/adc/fsl-imx25-gcq.h18
-rw-r--r--include/linux/mfd/as3711.h3
-rw-r--r--include/linux/mfd/axp20x.h34
-rw-r--r--include/linux/mfd/cros_ec.h2
-rw-r--r--include/linux/mfd/imx25-tsadc.h140
-rw-r--r--include/linux/mfd/mt6323/core.h36
-rw-r--r--include/linux/mfd/mt6323/registers.h408
-rw-r--r--include/linux/mfd/mt6397/core.h2
-rw-r--r--include/linux/mfd/rc5t583.h5
-rw-r--r--include/linux/mfd/syscon.h8
-rw-r--r--include/linux/mfd/syscon/imx6q-iomuxc-gpr.h5
-rw-r--r--include/linux/mfd/tps65086.h117
-rw-r--r--include/linux/mfd/tps65090.h5
58 files changed, 3256 insertions, 277 deletions
diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt
new file mode 100644
index 000000000000..b0866d36a307
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt
@@ -0,0 +1,58 @@
+Freescale i.MX25 ADC GCQ device
+
+This is a generic conversion queue device that can convert any of the
+analog inputs using the ADC unit of the i.MX25.
+
+Required properties:
+ - compatible: Should be "fsl,imx25-gcq".
+ - reg: Should be the register range of the module.
+ - interrupts: Should be the interrupt number of the module.
+ Typically this is <1>.
+ - interrupt-parent: phandle to the tsadc module of the i.MX25.
+ - #address-cells: Should be <1> (setting for the subnodes)
+ - #size-cells: Should be <0> (setting for the subnodes)
+
+Optional properties:
+ - vref-ext-supply: The regulator supplying the ADC reference voltage.
+ Required when at least one subnode uses the this reference.
+ - vref-xp-supply: The regulator supplying the ADC reference voltage on pin XP.
+ Required when at least one subnode uses this reference.
+ - vref-yp-supply: The regulator supplying the ADC reference voltage on pin YP.
+ Required when at least one subnode uses this reference.
+
+Sub-nodes:
+Optionally you can define subnodes which define the reference voltage
+for the analog inputs.
+
+Required properties for subnodes:
+ - reg: Should be the number of the analog input.
+ 0: xp
+ 1: yp
+ 2: xn
+ 3: yn
+ 4: wiper
+ 5: inaux0
+ 6: inaux1
+ 7: inaux2
+Optional properties for subnodes:
+ - fsl,adc-refp: specifies the positive reference input as defined in
+ <dt-bindings/iio/adc/fsl-imx25-gcq.h>
+ - fsl,adc-refn: specifies the negative reference input as defined in
+ <dt-bindings/iio/adc/fsl-imx25-gcq.h>
+
+Example:
+
+ adc: adc@50030800 {
+ compatible = "fsl,imx25-gcq";
+ reg = <0x50030800 0x60>;
+ interrupt-parent = <&tscadc>;
+ interrupts = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ inaux@5 {
+ reg = <5>;
+ fsl,adc-refp = <MX25_ADC_REFP_INT>;
+ fsl,adc-refn = <MX25_ADC_REFN_NGND>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/fsl-mx25-tcq.txt b/Documentation/devicetree/bindings/input/touchscreen/fsl-mx25-tcq.txt
new file mode 100644
index 000000000000..cdf05f9b2329
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/fsl-mx25-tcq.txt
@@ -0,0 +1,35 @@
+Freescale mx25 TS conversion queue module
+
+mx25 touchscreen conversion queue module which controls the ADC unit of the
+mx25 for attached touchscreens.
+
+Required properties:
+ - compatible: Should be "fsl,imx25-tcq".
+ - reg: Memory range of the device.
+ - interrupts: Should be the interrupt number associated with this module within
+ the tscadc unit (<0>).
+ - interrupt-parent: Should be a phandle to the tscadc unit.
+ - fsl,wires: Should be '<4>' or '<5>'
+
+Optional properties:
+ - fsl,pen-debounce-ns: Pen debounce time in nanoseconds.
+ - fsl,pen-threshold: Pen-down threshold for the touchscreen. This is a value
+ between 1 and 4096. It is the ratio between the internal reference voltage
+ and the measured voltage after the plate was precharged. Resistence between
+ plates and therefore the voltage decreases with pressure so that a smaller
+ value is equivalent to a higher pressure.
+ - fsl,settling-time-ns: Settling time in nanoseconds. The settling time is before
+ the actual touch detection to wait for an even charge distribution in the
+ plate.
+
+This device includes two conversion queues which can be added as subnodes.
+The first queue is for the touchscreen, the second for general purpose ADC.
+
+Example:
+ tsc: tcq@50030400 {
+ compatible = "fsl,imx25-tcq";
+ reg = <0x50030400 0x60>;
+ interrupt-parent = <&tscadc>;
+ interrupts = <0>;
+ fsl,wires = <4>;
+ };
diff --git a/Documentation/devicetree/bindings/mfd/act8945a.txt b/Documentation/devicetree/bindings/mfd/act8945a.txt
new file mode 100644
index 000000000000..f71283055685
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/act8945a.txt
@@ -0,0 +1,76 @@
+Device-Tree bindings for Active-semi ACT8945A MFD driver
+
+Required properties:
+ - compatible: "active-semi,act8945a".
+ - reg: the I2C slave address for the ACT8945A chip
+
+The chip exposes two subdevices:
+ - a regulators: see ../regulator/act8945a-regulator.txt
+ - a charger: see ../power/act8945a-charger.txt
+
+Example:
+ pmic@5b {
+ compatible = "active-semi,act8945a";
+ reg = <0x5b>;
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_charger_chglev>;
+ active-semi,chglev-gpio = <&pioA 12 GPIO_ACTIVE_HIGH>;
+ active-semi,input-voltage-threshold-microvolt = <6600>;
+ active-semi,precondition-timeout = <40>;
+ active-semi,total-timeout = <3>;
+
+ active-semi,vsel-high;
+
+ regulators {
+ vdd_1v35_reg: REG_DCDC1 {
+ regulator-name = "VDD_1V35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ vdd_1v2_reg: REG_DCDC2 {
+ regulator-name = "VDD_1V2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: REG_DCDC3 {
+ regulator-name = "VDD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_fuse_reg: REG_LDO1 {
+ regulator-name = "VDD_FUSE";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_lp_reg: REG_LDO2 {
+ regulator-name = "VDD_3V3_LP";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_led_reg: REG_LDO3 {
+ regulator-name = "VDD_LED";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_sdhc_1v8_reg: REG_LDO4 {
+ regulator-name = "VDD_SDHC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
index a474359dd206..fd39fa54571b 100644
--- a/Documentation/devicetree/bindings/mfd/axp20x.txt
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
@@ -5,11 +5,12 @@ axp152 (X-Powers)
axp202 (X-Powers)
axp209 (X-Powers)
axp221 (X-Powers)
+axp223 (X-Powers)
Required properties:
- compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209",
- "x-powers,axp221"
-- reg: The I2C slave address for the AXP chip
+ "x-powers,axp221", "x-powers,axp223"
+- reg: The I2C slave address or RSB hardware address for the AXP chip
- interrupt-parent: The parent interrupt controller
- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
- interrupt-controller: The PMIC has its own internal IRQs
@@ -51,7 +52,7 @@ LDO3 : LDO : ldo3in-supply
LDO4 : LDO : ldo24in-supply : shared supply
LDO5 : LDO : ldo5in-supply
-AXP221 regulators, type, and corresponding input supply names:
+AXP221/AXP223 regulators, type, and corresponding input supply names:
Regulator Type Supply Name Notes
--------- ---- ----------- -----
diff --git a/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt b/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt
new file mode 100644
index 000000000000..b03505286997
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt
@@ -0,0 +1,47 @@
+Freescale MX25 ADC/TSC MultiFunction Device (MFD)
+
+This device combines two general purpose conversion queues one used for general
+ADC and the other used for touchscreens.
+
+Required properties:
+ - compatible: Should be "fsl,imx25-tsadc".
+ - reg: Start address and size of the memory area of
+ the device
+ - interrupts: Interrupt for this device
+ (See: ../interrupt-controller/interrupts.txt)
+ - clocks: An 'ipg' clock (See: ../clock/clock-bindings.txt)
+ - interrupt-controller: This device is an interrupt controller. It
+ controls the interrupts of both
+ conversion queues.
+ - #interrupt-cells: Should be '<1>'.
+ - #address-cells: Should be '<1>'.
+ - #size-cells: Should be '<1>'.
+
+This device includes two conversion queues which can be added as subnodes.
+The first queue is for the touchscreen, the second for general purpose ADC.
+
+Example:
+ tscadc: tscadc@50030000 {
+ compatible = "fsl,imx25-tsadc";
+ reg = <0x50030000 0xc>;
+ interrupts = <46>;
+ clocks = <&clks 119>;
+ clock-names = "ipg";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ tsc: tcq@50030400 {
+ compatible = "fsl,imx25-tcq";
+ reg = <0x50030400 0x60>;
+ ...
+ };
+
+ adc: gcq@50030800 {
+ compatible = "fsl,imx25-gcq";
+ reg = <0x50030800 0x60>;
+ ...
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 15043e652699..949c85f8d02c 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -1,6 +1,6 @@
-MediaTek MT6397 Multifunction Device Driver
+MediaTek MT6397/MT6323 Multifunction Device Driver
-MT6397 is a multifunction device with the following sub modules:
+MT6397/MT6323 is a multifunction device with the following sub modules:
- Regulator
- RTC
- Audio codec
@@ -8,14 +8,14 @@ MT6397 is a multifunction device with the following sub modules:
- Clock
It is interfaced to host controller using SPI interface by a proprietary hardware
-called PMIC wrapper or pwrap. MT6397 MFD is a child device of pwrap.
+called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
See the following for pwarp node definitions:
Documentation/devicetree/bindings/soc/pwrap.txt
This document describes the binding for MFD device and its sub module.
Required properties:
-compatible: "mediatek,mt6397"
+compatible: "mediatek,mt6397" or "mediatek,mt6323"
Optional subnodes:
@@ -26,6 +26,8 @@ Optional subnodes:
Required properties:
- compatible: "mediatek,mt6397-regulator"
see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
+ - compatible: "mediatek,mt6323-regulator"
+ see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
- codec
Required properties:
- compatible: "mediatek,mt6397-codec"
diff --git a/Documentation/devicetree/bindings/mfd/tps65086.txt b/Documentation/devicetree/bindings/mfd/tps65086.txt
new file mode 100644
index 000000000000..d3705612a846
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/tps65086.txt
@@ -0,0 +1,55 @@
+* TPS65086 Power Management Integrated Circuit (PMIC) bindings
+
+Required properties:
+ - compatible : Should be "ti,tps65086".
+ - reg : I2C slave address.
+ - interrupt-parent : Phandle to the parent interrupt controller.
+ - interrupts : The interrupt line the device is connected to.
+ - interrupt-controller : Marks the device node as an interrupt controller.
+ - #interrupt-cells : The number of cells to describe an IRQ, should be 2.
+ The first cell is the IRQ number.
+ The second cell is the flags, encoded as trigger
+ masks from ../interrupt-controller/interrupts.txt.
+ - gpio-controller : Marks the device node as a GPIO Controller.
+ - #gpio-cells : Should be two. The first cell is the pin number and
+ the second cell is used to specify flags.
+ See ../gpio/gpio.txt for more information.
+ - regulators: : List of child nodes that specify the regulator
+ initialization data. Child nodes must be named
+ after their hardware counterparts: buck[1-6],
+ ldoa[1-3], swa1, swb[1-2], and vtt. Each child
+ node is defined using the standard binding for
+ regulators and the optional regulator properties
+ defined below.
+
+Optional regulator properties:
+ - ti,regulator-step-size-25mv : This is applicable for buck[1,2,6], set this
+ if the regulator is factory set with a 25mv
+ step voltage mapping.
+ - ti,regulator-decay : This is applicable for buck[1-6], set this if
+ the output needs to decay, default is for
+ the output to slew down.
+
+Example:
+
+ pmic: tps65086@5e {
+ compatible = "ti,tps65086";
+ reg = <0x5e>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ regulators {
+ buck1 {
+ regulator-name = "vcc1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1600000>;
+ regulator-boot-on;
+ ti,regulator-decay;
+ ti,regulator-step-size-25mv;
+ };
+ };
+ };
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 4808e4657de5..5f3429f0bf46 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -898,6 +898,12 @@ config GPIO_TIMBERDALE
---help---
Add support for the GPIO IP in the timberdale FPGA.
+config GPIO_TPS65086
+ tristate "TI TPS65086 GPO"
+ depends on MFD_TPS65086
+ help
+ This driver supports the GPO on TI TPS65086x PMICs.
+
config GPIO_TPS65218
tristate "TPS65218 GPIO"
depends on MFD_TPS65218
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 25decedba943..1e0b74f3b1ed 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o
+obj-$(CONFIG_GPIO_TPS65086) += gpio-tps65086.o
obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
diff --git a/drivers/gpio/gpio-tps65086.c b/drivers/gpio/gpio-tps65086.c
new file mode 100644
index 000000000000..8e25f01ac314
--- /dev/null
+++ b/drivers/gpio/gpio-tps65086.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65912 driver
+ */
+
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/tps65086.h>
+
+struct tps65086_gpio {
+ struct gpio_chip chip;
+ struct tps65086 *tps;
+};
+
+static int tps65086_gpio_get_direction(struct gpio_chip *chip,
+ unsigned offset)
+{
+ /* This device is output only */
+ return 0;
+}
+
+static int tps65086_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ /* This device is output only */
+ return -EINVAL;
+}
+
+static int tps65086_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct tps65086_gpio *gpio = gpiochip_get_data(chip);
+
+ /* Set the initial value */
+ regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL,
+ BIT(4 + offset), value ? BIT(4 + offset) : 0);
+
+ return 0;
+}
+
+static int tps65086_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct tps65086_gpio *gpio = gpiochip_get_data(chip);
+ int ret, val;
+
+ ret = regmap_read(gpio->tps->regmap, TPS65086_GPOCTRL, &val);
+ if (ret < 0)
+ return ret;
+
+ return val & BIT(4 + offset);
+}
+
+static void tps65086_gpio_set(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct tps65086_gpio *gpio = gpiochip_get_data(chip);
+
+ regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL,
+ BIT(4 + offset), value ? BIT(4 + offset) : 0);
+}
+
+static struct gpio_chip template_chip = {
+ .label = "tps65086-gpio",
+ .owner = THIS_MODULE,
+ .get_direction = tps65086_gpio_get_direction,
+ .direction_input = tps65086_gpio_direction_input,
+ .direction_output = tps65086_gpio_direction_output,
+ .get = tps65086_gpio_get,
+ .set = tps65086_gpio_set,
+ .base = -1,
+ .ngpio = 4,
+ .can_sleep = true,
+};
+
+static int tps65086_gpio_probe(struct platform_device *pdev)
+{
+ struct tps65086_gpio *gpio;
+ int ret;
+
+ gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+ if (!gpio)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, gpio);
+
+ gpio->tps = dev_get_drvdata(pdev->dev.parent);
+ gpio->chip = template_chip;
+ gpio->chip.parent = gpio->tps->dev;
+
+ ret = gpiochip_add_data(&gpio->chip, gpio);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int tps65086_gpio_remove(struct platform_device *pdev)
+{
+ struct tps65086_gpio *gpio = platform_get_drvdata(pdev);
+
+ gpiochip_remove(&gpio->chip);
+
+ return 0;
+}
+
+static const struct platform_device_id tps65086_gpio_id_table[] = {
+ { "tps65086-gpio", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, tps65086_gpio_id_table);
+
+static struct platform_driver tps65086_gpio_driver = {
+ .driver = {
+ .name = "tps65086-gpio",
+ },
+ .probe = tps65086_gpio_probe,
+ .remove = tps65086_gpio_remove,
+ .id_table = tps65086_gpio_id_table,
+};
+module_platform_driver(tps65086_gpio_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65086 GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 932de1f9d1e7..af4aea7b20f9 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -194,6 +194,13 @@ config EXYNOS_ADC
To compile this driver as a module, choose M here: the module will be
called exynos_adc.
+config FSL_MX25_ADC
+ tristate "Freescale MX25 ADC driver"
+ depends on MFD_MX25_TSADC
+ help
+ Generic Conversion Queue driver used for general purpose ADC in the
+ MX25. This driver supports single measurements using the MX25 ADC.
+
config HI8435
tristate "Holt Integrated Circuits HI-8435 threshold detector"
select IIO_TRIGGERED_EVENT
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index b1aa456e6af3..0cb79210a4b0 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o
obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
+obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
obj-$(CONFIG_HI8435) += hi8435.o
obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
new file mode 100644
index 000000000000..72b32c1ab257
--- /dev/null
+++ b/drivers/iio/adc/fsl-imx25-gcq.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ *
+ * This is the driver for the imx25 GCQ (Generic Conversion Queue)
+ * connected to the imx25 ADC.
+ */
+
+#include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
+#include <linux/clk.h>
+#include <linux/iio/iio.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/imx25-tsadc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#define MX25_GCQ_TIMEOUT (msecs_to_jiffies(2000))
+
+static const char * const driver_name = "mx25-gcq";
+
+enum mx25_gcq_cfgs {
+ MX25_CFG_XP = 0,
+ MX25_CFG_YP,
+ MX25_CFG_XN,
+ MX25_CFG_YN,
+ MX25_CFG_WIPER,
+ MX25_CFG_INAUX0,
+ MX25_CFG_INAUX1,
+ MX25_CFG_INAUX2,
+ MX25_NUM_CFGS,
+};
+
+struct mx25_gcq_priv {
+ struct regmap *regs;
+ struct completion completed;
+ struct clk *clk;
+ int irq;
+ struct regulator *vref[4];
+ u32 channel_vref_mv[MX25_NUM_CFGS];
+};
+
+#define MX25_CQG_CHAN(chan, id) {\
+ .type = IIO_VOLTAGE,\
+ .indexed = 1,\
+ .channel = chan,\
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE),\
+ .datasheet_name = id,\
+}
+
+static const struct iio_chan_spec mx25_gcq_channels[MX25_NUM_CFGS] = {
+ MX25_CQG_CHAN(MX25_CFG_XP, "xp"),
+ MX25_CQG_CHAN(MX25_CFG_YP, "yp"),
+ MX25_CQG_CHAN(MX25_CFG_XN, "xn"),
+ MX25_CQG_CHAN(MX25_CFG_YN, "yn"),
+ MX25_CQG_CHAN(MX25_CFG_WIPER, "wiper"),
+ MX25_CQG_CHAN(MX25_CFG_INAUX0, "inaux0"),
+ MX25_CQG_CHAN(MX25_CFG_INAUX1, "inaux1"),
+ MX25_CQG_CHAN(MX25_CFG_INAUX2, "inaux2"),
+};
+
+static const char * const mx25_gcq_refp_names[] = {
+ [MX25_ADC_REFP_YP] = "yp",
+ [MX25_ADC_REFP_XP] = "xp",
+ [MX25_ADC_REFP_INT] = "int",
+ [MX25_ADC_REFP_EXT] = "ext",
+};
+
+static irqreturn_t mx25_gcq_irq(int irq, void *data)
+{
+ struct mx25_gcq_priv *priv = data;
+ u32 stats;
+
+ regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
+
+ if (stats & MX25_ADCQ_SR_EOQ) {
+ regmap_update_bits(priv->regs, MX25_ADCQ_MR,
+ MX25_ADCQ_MR_EOQ_IRQ, MX25_ADCQ_MR_EOQ_IRQ);
+ complete(&priv->completed);
+ }
+
+ /* Disable conversion queue run */
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS, 0);
+
+ /* Acknowledge all possible irqs */
+ regmap_write(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
+ MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
+ MX25_ADCQ_SR_EOQ | MX25_ADCQ_SR_PD);
+
+ return IRQ_HANDLED;
+}
+
+static int mx25_gcq_get_raw_value(struct device *dev,
+ struct iio_chan_spec const *chan,
+ struct mx25_gcq_priv *priv,
+ int *val)
+{
+ long timeout;
+ u32 data;
+
+ /* Setup the configuration we want to use */
+ regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
+ MX25_ADCQ_ITEM(0, chan->channel));
+
+ regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_EOQ_IRQ, 0);
+
+ /* Trigger queue for one run */
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FQS,
+ MX25_ADCQ_CR_FQS);
+
+ timeout = wait_for_completion_interruptible_timeout(
+ &priv->completed, MX25_GCQ_TIMEOUT);
+ if (timeout < 0) {
+ dev_err(dev, "ADC wait for measurement failed\n");
+ return timeout;
+ } else if (timeout == 0) {
+ dev_err(dev, "ADC timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ regmap_read(priv->regs, MX25_ADCQ_FIFO, &data);
+
+ *val = MX25_ADCQ_FIFO_DATA(data);
+
+ return IIO_VAL_INT;
+}
+
+static int mx25_gcq_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val,
+ int *val2, long mask)
+{
+ struct mx25_gcq_priv *priv = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&indio_dev->mlock);
+ ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val);
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+
+ case IIO_CHAN_INFO_SCALE:
+ *val = priv->channel_vref_mv[chan->channel];
+ *val2 = 12;
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info mx25_gcq_iio_info = {
+ .read_raw = mx25_gcq_read_raw,
+};
+
+static const struct regmap_config mx25_gcq_regconfig = {
+ .max_register = 0x5c,
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
+ struct mx25_gcq_priv *priv)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *child;
+ struct device *dev = &pdev->dev;
+ unsigned int refp_used[4] = {};
+ int ret, i;
+
+ /*
+ * Setup all configurations registers with a default conversion
+ * configuration for each input
+ */
+ for (i = 0; i < MX25_NUM_CFGS; ++i)
+ regmap_write(priv->regs, MX25_ADCQ_CFG(i),
+ MX25_ADCQ_CFG_YPLL_OFF |
+ MX25_ADCQ_CFG_XNUR_OFF |
+ MX25_ADCQ_CFG_XPUL_OFF |
+ MX25_ADCQ_CFG_REFP_INT |
+ MX25_ADCQ_CFG_IN(i) |
+ MX25_ADCQ_CFG_REFN_NGND2);
+
+ /*
+ * First get all regulators to store them in channel_vref_mv if
+ * necessary. Later we use that information for proper IIO scale
+ * information.
+ */
+ priv->vref[MX25_ADC_REFP_INT] = NULL;
+ priv->vref[MX25_ADC_REFP_EXT] =
+ devm_regulator_get_optional(&pdev->dev, "vref-ext");
+ priv->vref[MX25_ADC_REFP_XP] =
+ devm_regulator_get_optional(&pdev->dev, "vref-xp");
+ priv->vref[MX25_ADC_REFP_YP] =
+ devm_regulator_get_optional(&pdev->dev, "vref-yp");
+
+ for_each_child_of_node(np, child) {
+ u32 reg;
+ u32 refp = MX25_ADCQ_CFG_REFP_INT;
+ u32 refn = MX25_ADCQ_CFG_REFN_NGND2;
+
+ ret = of_property_read_u32(child, "reg", &reg);
+ if (ret) {
+ dev_err(dev, "Failed to get reg property\n");
+ return ret;
+ }
+
+ if (reg >= MX25_NUM_CFGS) {
+ dev_err(dev,
+ "reg value is greater than the number of available configuration registers\n");
+ return -EINVAL;
+ }
+
+ of_property_read_u32(child, "fsl,adc-refp", &refp);
+ of_property_read_u32(child, "fsl,adc-refn", &refn);
+
+ switch (refp) {
+ case MX25_ADC_REFP_EXT:
+ case MX25_ADC_REFP_XP:
+ case MX25_ADC_REFP_YP:
+ if (IS_ERR(priv->vref[refp])) {
+ dev_err(dev, "Error, trying to use external voltage reference without a vref-%s regulator.",
+ mx25_gcq_refp_names[refp]);
+ return PTR_ERR(priv->vref[refp]);
+ }
+ priv->channel_vref_mv[reg] =
+ regulator_get_voltage(priv->vref[refp]);
+ /* Conversion from uV to mV */
+ priv->channel_vref_mv[reg] /= 1000;
+ break;
+ case MX25_ADC_REFP_INT:
+ priv->channel_vref_mv[reg] = 2500;
+ break;
+ default:
+ dev_err(dev, "Invalid positive reference %d\n", refp);
+ return -EINVAL;
+ }
+
+ ++refp_used[refp];
+
+ /*
+ * Shift the read values to the correct positions within the
+ * register.
+ */
+ refp = MX25_ADCQ_CFG_REFP(refp);
+ refn = MX25_ADCQ_CFG_REFN(refn);
+
+ if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
+ dev_err(dev, "Invalid fsl,adc-refp property value\n");
+ return -EINVAL;
+ }
+ if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
+ dev_err(dev, "Invalid fsl,adc-refn property value\n");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(priv->regs, MX25_ADCQ_CFG(reg),
+ MX25_ADCQ_CFG_REFP_MASK |
+ MX25_ADCQ_CFG_REFN_MASK,
+ refp | refn);
+ }
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST,
+ MX25_ADCQ_CR_FRST | MX25_ADCQ_CR_QRST);
+
+ regmap_write(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_PDMSK | MX25_ADCQ_CR_QSM_FQS);
+
+ /* Remove unused regulators */
+ for (i = 0; i != 4; ++i) {
+ if (!refp_used[i]) {
+ if (!IS_ERR_OR_NULL(priv->vref[i]))
+ devm_regulator_put(priv->vref[i]);
+ priv->vref[i] = NULL;
+ }
+ }
+
+ return 0;
+}
+
+static int mx25_gcq_probe(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev;
+ struct mx25_gcq_priv *priv;
+ struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ void __iomem *mem;
+ int ret;
+ int i;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ priv = iio_priv(indio_dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mem = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mem))
+ return PTR_ERR(mem);
+
+ priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_gcq_regconfig);
+ if (IS_ERR(priv->regs)) {
+ dev_err(dev, "Failed to initialize regmap\n");
+ return PTR_ERR(priv->regs);
+ }
+
+ init_completion(&priv->completed);
+
+ ret = mx25_gcq_setup_cfgs(pdev, priv);
+ if (ret)
+ return ret;
+
+ for (i = 0; i != 4; ++i) {
+ if (!priv->vref[i])
+ continue;
+
+ ret = regulator_enable(priv->vref[i]);
+ if (ret)
+ goto err_regulator_disable;
+ }
+
+ priv->clk = tsadc->clk;
+ ret = clk_prepare_enable(priv->clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable clock\n");
+ goto err_vref_disable;
+ }
+
+ priv->irq = platform_get_irq(pdev, 0);
+ if (priv->irq <= 0) {
+ dev_err(dev, "Failed to get IRQ\n");
+ ret = priv->irq;
+ if (!ret)
+ ret = -ENXIO;
+ goto err_clk_unprepare;
+ }
+
+ ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
+ if (ret) {
+ dev_err(dev, "Failed requesting IRQ\n");
+ goto err_clk_unprepare;
+ }
+
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->channels = mx25_gcq_channels;
+ indio_dev->num_channels = ARRAY_SIZE(mx25_gcq_channels);
+ indio_dev->info = &mx25_gcq_iio_info;
+ indio_dev->name = driver_name;
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(dev, "Failed to register iio device\n");
+ goto err_irq_free;
+ }
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ return 0;
+
+err_irq_free:
+ free_irq(priv->irq, priv);
+err_clk_unprepare:
+ clk_disable_unprepare(priv->clk);
+err_vref_disable:
+ i = 4;
+err_regulator_disable:
+ for (; i-- > 0;) {
+ if (priv->vref[i])
+ regulator_disable(priv->vref[i]);
+ }
+ return ret;
+}
+
+static int mx25_gcq_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct mx25_gcq_priv *priv = iio_priv(indio_dev);
+ int i;
+
+ iio_device_unregister(indio_dev);
+ free_irq(priv->irq, priv);
+ clk_disable_unprepare(priv->clk);
+ for (i = 4; i-- > 0;) {
+ if (priv->vref[i])
+ regulator_disable(priv->vref[i]);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id mx25_gcq_ids[] = {
+ { .compatible = "fsl,imx25-gcq", },
+ { /* Sentinel */ }
+};
+
+static struct platform_driver mx25_gcq_driver = {
+ .driver = {
+ .name = "mx25-gcq",
+ .of_match_table = mx25_gcq_ids,
+ },
+ .probe = mx25_gcq_probe,
+ .remove = mx25_gcq_remove,
+};
+module_platform_driver(mx25_gcq_driver);
+
+MODULE_DESCRIPTION("ADC driver for Freescale mx25");
+MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 1f99e7f30e27..8ecdc38fd489 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -833,6 +833,15 @@ config TOUCHSCREEN_USB_COMPOSITE
To compile this driver as a module, choose M here: the
module will be called usbtouchscreen.
+config TOUCHSCREEN_MX25
+ tristate "Freescale i.MX25 touchscreen input driver"
+ depends on MFD_MX25_TSADC
+ help
+ Enable support for touchscreen connected to your i.MX25.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fsl-imx25-tcq.
+
config TOUCHSCREEN_MC13783
tristate "Freescale MC13783 touchscreen input driver"
depends on MFD_MC13XXX
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 4b518c76e0d7..f42975e719e0 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o
obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o
obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o
+obj-$(CONFIG_TOUCHSCREEN_MX25) += fsl-imx25-tcq.o
obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o
obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o
obj-$(CONFIG_TOUCHSCREEN_MELFAS_MIP4) += melfas_mip4.o
diff --git a/drivers/input/touchscreen/fsl-imx25-tcq.c b/drivers/input/touchscreen/fsl-imx25-tcq.c
new file mode 100644
index 000000000000..fe9877a6af9e
--- /dev/null
+++ b/drivers/input/touchscreen/fsl-imx25-tcq.c
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ *
+ * Based on driver from 2011:
+ * Juergen Beisert, Pengutronix <kernel@pengutronix.de>
+ *
+ * This is the driver for the imx25 TCQ (Touchscreen Conversion Queue)
+ * connected to the imx25 ADC.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/imx25-tsadc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static const char mx25_tcq_name[] = "mx25-tcq";
+
+enum mx25_tcq_mode {
+ MX25_TS_4WIRE,
+};
+
+struct mx25_tcq_priv {
+ struct regmap *regs;
+ struct regmap *core_regs;
+ struct input_dev *idev;
+ enum mx25_tcq_mode mode;
+ unsigned int pen_threshold;
+ unsigned int sample_count;
+ unsigned int expected_samples;
+ unsigned int pen_debounce;
+ unsigned int settling_time;
+ struct clk *clk;
+ int irq;
+ struct device *dev;
+};
+
+static struct regmap_config mx25_tcq_regconfig = {
+ .fast_io = true,
+ .max_register = 0x5c,
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static const struct of_device_id mx25_tcq_ids[] = {
+ { .compatible = "fsl,imx25-tcq", },
+ { /* Sentinel */ }
+};
+
+#define TSC_4WIRE_PRE_INDEX 0
+#define TSC_4WIRE_X_INDEX 1
+#define TSC_4WIRE_Y_INDEX 2
+#define TSC_4WIRE_POST_INDEX 3
+#define TSC_4WIRE_LEAVE 4
+
+#define MX25_TSC_DEF_THRESHOLD 80
+#define TSC_MAX_SAMPLES 16
+
+#define MX25_TSC_REPEAT_WAIT 14
+
+enum mx25_adc_configurations {
+ MX25_CFG_PRECHARGE = 0,
+ MX25_CFG_TOUCH_DETECT,
+ MX25_CFG_X_MEASUREMENT,
+ MX25_CFG_Y_MEASUREMENT,
+};
+
+#define MX25_PRECHARGE_VALUE (\
+ MX25_ADCQ_CFG_YPLL_OFF | \
+ MX25_ADCQ_CFG_XNUR_OFF | \
+ MX25_ADCQ_CFG_XPUL_HIGH | \
+ MX25_ADCQ_CFG_REFP_INT | \
+ MX25_ADCQ_CFG_IN_XP | \
+ MX25_ADCQ_CFG_REFN_NGND2 | \
+ MX25_ADCQ_CFG_IGS)
+
+#define MX25_TOUCH_DETECT_VALUE (\
+ MX25_ADCQ_CFG_YNLR | \
+ MX25_ADCQ_CFG_YPLL_OFF | \
+ MX25_ADCQ_CFG_XNUR_OFF | \
+ MX25_ADCQ_CFG_XPUL_OFF | \
+ MX25_ADCQ_CFG_REFP_INT | \
+ MX25_ADCQ_CFG_IN_XP | \
+ MX25_ADCQ_CFG_REFN_NGND2 | \
+ MX25_ADCQ_CFG_PENIACK)
+
+static void imx25_setup_queue_cfgs(struct mx25_tcq_priv *priv,
+ unsigned int settling_cnt)
+{
+ u32 precharge_cfg =
+ MX25_PRECHARGE_VALUE |
+ MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
+ u32 touch_detect_cfg =
+ MX25_TOUCH_DETECT_VALUE |
+ MX25_ADCQ_CFG_NOS(1) |
+ MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
+
+ regmap_write(priv->core_regs, MX25_TSC_TICR, precharge_cfg);
+
+ /* PRECHARGE */
+ regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_PRECHARGE),
+ precharge_cfg);
+
+ /* TOUCH_DETECT */
+ regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_TOUCH_DETECT),
+ touch_detect_cfg);
+
+ /* X Measurement */
+ regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_X_MEASUREMENT),
+ MX25_ADCQ_CFG_YPLL_OFF |
+ MX25_ADCQ_CFG_XNUR_LOW |
+ MX25_ADCQ_CFG_XPUL_HIGH |
+ MX25_ADCQ_CFG_REFP_XP |
+ MX25_ADCQ_CFG_IN_YP |
+ MX25_ADCQ_CFG_REFN_XN |
+ MX25_ADCQ_CFG_NOS(priv->sample_count) |
+ MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
+
+ /* Y Measurement */
+ regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_Y_MEASUREMENT),
+ MX25_ADCQ_CFG_YNLR |
+ MX25_ADCQ_CFG_YPLL_HIGH |
+ MX25_ADCQ_CFG_XNUR_OFF |
+ MX25_ADCQ_CFG_XPUL_OFF |
+ MX25_ADCQ_CFG_REFP_YP |
+ MX25_ADCQ_CFG_IN_XP |
+ MX25_ADCQ_CFG_REFN_YN |
+ MX25_ADCQ_CFG_NOS(priv->sample_count) |
+ MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
+
+ /* Enable the touch detection right now */
+ regmap_write(priv->core_regs, MX25_TSC_TICR, touch_detect_cfg |
+ MX25_ADCQ_CFG_IGS);
+}
+
+static int imx25_setup_queue_4wire(struct mx25_tcq_priv *priv,
+ unsigned settling_cnt, int *items)
+{
+ imx25_setup_queue_cfgs(priv, settling_cnt);
+
+ /* Setup the conversion queue */
+ regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
+ MX25_ADCQ_ITEM(0, MX25_CFG_PRECHARGE) |
+ MX25_ADCQ_ITEM(1, MX25_CFG_TOUCH_DETECT) |
+ MX25_ADCQ_ITEM(2, MX25_CFG_X_MEASUREMENT) |
+ MX25_ADCQ_ITEM(3, MX25_CFG_Y_MEASUREMENT) |
+ MX25_ADCQ_ITEM(4, MX25_CFG_PRECHARGE) |
+ MX25_ADCQ_ITEM(5, MX25_CFG_TOUCH_DETECT));
+
+ /*
+ * We measure X/Y with 'sample_count' number of samples and execute a
+ * touch detection twice, with 1 sample each
+ */
+ priv->expected_samples = priv->sample_count * 2 + 2;
+ *items = 6;
+
+ return 0;
+}
+
+static void mx25_tcq_disable_touch_irq(struct mx25_tcq_priv *priv)
+{
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK,
+ MX25_ADCQ_CR_PDMSK);
+}
+
+static void mx25_tcq_enable_touch_irq(struct mx25_tcq_priv *priv)
+{
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK, 0);
+}
+
+static void mx25_tcq_disable_fifo_irq(struct mx25_tcq_priv *priv)
+{
+ regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ,
+ MX25_ADCQ_MR_FDRY_IRQ);
+}
+
+static void mx25_tcq_enable_fifo_irq(struct mx25_tcq_priv *priv)
+{
+ regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ, 0);
+}
+
+static void mx25_tcq_force_queue_start(struct mx25_tcq_priv *priv)
+{
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_FQS,
+ MX25_ADCQ_CR_FQS);
+}
+
+static void mx25_tcq_force_queue_stop(struct mx25_tcq_priv *priv)
+{
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_FQS, 0);
+}
+
+static void mx25_tcq_fifo_reset(struct mx25_tcq_priv *priv)
+{
+ u32 tcqcr;
+
+ regmap_read(priv->regs, MX25_ADCQ_CR, &tcqcr);
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST,
+ MX25_ADCQ_CR_FRST);
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST, 0);
+ regmap_write(priv->regs, MX25_ADCQ_CR, tcqcr);
+}
+
+static void mx25_tcq_re_enable_touch_detection(struct mx25_tcq_priv *priv)
+{
+ /* stop the queue from looping */
+ mx25_tcq_force_queue_stop(priv);
+
+ /* for a clean touch detection, preload the X plane */
+ regmap_write(priv->core_regs, MX25_TSC_TICR, MX25_PRECHARGE_VALUE);
+
+ /* waste some time now to pre-load the X plate to high voltage */
+ mx25_tcq_fifo_reset(priv);
+
+ /* re-enable the detection right now */
+ regmap_write(priv->core_regs, MX25_TSC_TICR,
+ MX25_TOUCH_DETECT_VALUE | MX25_ADCQ_CFG_IGS);
+
+ regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_PD,
+ MX25_ADCQ_SR_PD);
+
+ /* enable the pen down event to be a source for the interrupt */
+ regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_PD_IRQ, 0);
+
+ /* lets fire the next IRQ if someone touches the touchscreen */
+ mx25_tcq_enable_touch_irq(priv);
+}
+
+static void mx25_tcq_create_event_for_4wire(struct mx25_tcq_priv *priv,
+ u32 *sample_buf,
+ unsigned int samples)
+{
+ unsigned int x_pos = 0;
+ unsigned int y_pos = 0;
+ unsigned int touch_pre = 0;
+ unsigned int touch_post = 0;
+ unsigned int i;
+
+ for (i = 0; i < samples; i++) {
+ unsigned int index = MX25_ADCQ_FIFO_ID(sample_buf[i]);
+ unsigned int val = MX25_ADCQ_FIFO_DATA(sample_buf[i]);
+
+ switch (index) {
+ case 1:
+ touch_pre = val;
+ break;
+ case 2:
+ x_pos = val;
+ break;
+ case 3:
+ y_pos = val;
+ break;
+ case 5:
+ touch_post = val;
+ break;
+ default:
+ dev_dbg(priv->dev, "Dropped samples because of invalid index %d\n",
+ index);
+ return;
+ }
+ }
+
+ if (samples != 0) {
+ /*
+ * only if both touch measures are below a threshold,
+ * the position is valid
+ */
+ if (touch_pre < priv->pen_threshold &&
+ touch_post < priv->pen_threshold) {
+ /* valid samples, generate a report */
+ x_pos /= priv->sample_count;
+ y_pos /= priv->sample_count;
+ input_report_abs(priv->idev, ABS_X, x_pos);
+ input_report_abs(priv->idev, ABS_Y, y_pos);
+ input_report_key(priv->idev, BTN_TOUCH, 1);
+ input_sync(priv->idev);
+
+ /* get next sample */
+ mx25_tcq_enable_fifo_irq(priv);
+ } else if (touch_pre >= priv->pen_threshold &&
+ touch_post >= priv->pen_threshold) {
+ /*
+ * if both samples are invalid,
+ * generate a release report
+ */
+ input_report_key(priv->idev, BTN_TOUCH, 0);
+ input_sync(priv->idev);
+ mx25_tcq_re_enable_touch_detection(priv);
+ } else {
+ /*
+ * if only one of both touch measurements are
+ * below the threshold, still some bouncing
+ * happens. Take additional samples in this
+ * case to be sure
+ */
+ mx25_tcq_enable_fifo_irq(priv);
+ }
+ }
+}
+
+static irqreturn_t mx25_tcq_irq_thread(int irq, void *dev_id)
+{
+ struct mx25_tcq_priv *priv = dev_id;
+ u32 sample_buf[TSC_MAX_SAMPLES];
+ unsigned int samples;
+ u32 stats;
+ unsigned int i;
+
+ /*
+ * Check how many samples are available. We always have to read exactly
+ * sample_count samples from the fifo, or a multiple of sample_count.
+ * Otherwise we mixup samples into different touch events.
+ */
+ regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
+ samples = MX25_ADCQ_SR_FDN(stats);
+ samples -= samples % priv->sample_count;
+
+ if (!samples)
+ return IRQ_HANDLED;
+
+ for (i = 0; i != samples; ++i)
+ regmap_read(priv->regs, MX25_ADCQ_FIFO, &sample_buf[i]);
+
+ mx25_tcq_create_event_for_4wire(priv, sample_buf, samples);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mx25_tcq_irq(int irq, void *dev_id)
+{
+ struct mx25_tcq_priv *priv = dev_id;
+ u32 stat;
+ int ret = IRQ_HANDLED;
+
+ regmap_read(priv->regs, MX25_ADCQ_SR, &stat);
+
+ if (stat & (MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR))
+ mx25_tcq_re_enable_touch_detection(priv);
+
+ if (stat & MX25_ADCQ_SR_PD) {
+ mx25_tcq_disable_touch_irq(priv);
+ mx25_tcq_force_queue_start(priv);
+ mx25_tcq_enable_fifo_irq(priv);
+ }
+
+ if (stat & MX25_ADCQ_SR_FDRY) {
+ mx25_tcq_disable_fifo_irq(priv);
+ ret = IRQ_WAKE_THREAD;
+ }
+
+ regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
+ MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
+ MX25_ADCQ_SR_PD,
+ MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR |
+ MX25_ADCQ_SR_FOR | MX25_ADCQ_SR_PD);
+
+ return ret;
+}
+
+/* configure the state machine for a 4-wire touchscreen */
+static int mx25_tcq_init(struct mx25_tcq_priv *priv)
+{
+ u32 tgcr;
+ unsigned int ipg_div;
+ unsigned int adc_period;
+ unsigned int debounce_cnt;
+ unsigned int settling_cnt;
+ int itemct;
+ int error;
+
+ regmap_read(priv->core_regs, MX25_TSC_TGCR, &tgcr);
+ ipg_div = max_t(unsigned int, 4, MX25_TGCR_GET_ADCCLK(tgcr));
+ adc_period = USEC_PER_SEC * ipg_div * 2 + 2;
+ adc_period /= clk_get_rate(priv->clk) / 1000 + 1;
+ debounce_cnt = DIV_ROUND_UP(priv->pen_debounce, adc_period * 8) - 1;
+ settling_cnt = DIV_ROUND_UP(priv->settling_time, adc_period * 8) - 1;
+
+ /* Reset */
+ regmap_write(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST);
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST, 0);
+
+ /* up to 128 * 8 ADC clocks are possible */
+ if (debounce_cnt > 127)
+ debounce_cnt = 127;
+
+ /* up to 255 * 8 ADC clocks are possible */
+ if (settling_cnt > 255)
+ settling_cnt = 255;
+
+ error = imx25_setup_queue_4wire(priv, settling_cnt, &itemct);
+ if (error)
+ return error;
+
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_LITEMID_MASK | MX25_ADCQ_CR_WMRK_MASK,
+ MX25_ADCQ_CR_LITEMID(itemct - 1) |
+ MX25_ADCQ_CR_WMRK(priv->expected_samples - 1));
+
+ /* setup debounce count */
+ regmap_update_bits(priv->core_regs, MX25_TSC_TGCR,
+ MX25_TGCR_PDBTIME_MASK,
+ MX25_TGCR_PDBTIME(debounce_cnt));
+
+ /* enable debounce */
+ regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDBEN,
+ MX25_TGCR_PDBEN);
+ regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDEN,
+ MX25_TGCR_PDEN);
+
+ /* enable the engine on demand */
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_QSM_MASK,
+ MX25_ADCQ_CR_QSM_FQS);
+
+ /* Enable repeat and repeat wait */
+ regmap_update_bits(priv->regs, MX25_ADCQ_CR,
+ MX25_ADCQ_CR_RPT | MX25_ADCQ_CR_RWAIT_MASK,
+ MX25_ADCQ_CR_RPT |
+ MX25_ADCQ_CR_RWAIT(MX25_TSC_REPEAT_WAIT));
+
+ return 0;
+}
+
+static int mx25_tcq_parse_dt(struct platform_device *pdev,
+ struct mx25_tcq_priv *priv)
+{
+ struct device_node *np = pdev->dev.of_node;
+ u32 wires;
+ int error;
+
+ /* Setup defaults */
+ priv->pen_threshold = 500;
+ priv->sample_count = 3;
+ priv->pen_debounce = 1000000;
+ priv->settling_time = 250000;
+
+ error = of_property_read_u32(np, "fsl,wires", &wires);
+ if (error) {
+ dev_err(&pdev->dev, "Failed to find fsl,wires properties\n");
+ return error;
+ }
+
+ if (wires == 4) {
+ priv->mode = MX25_TS_4WIRE;
+ } else {
+ dev_err(&pdev->dev, "%u-wire mode not supported\n", wires);
+ return -EINVAL;
+ }
+
+ /* These are optional, we don't care about the return values */
+ of_property_read_u32(np, "fsl,pen-threshold", &priv->pen_threshold);
+ of_property_read_u32(np, "fsl,settling-time-ns", &priv->settling_time);
+ of_property_read_u32(np, "fsl,pen-debounce-ns", &priv->pen_debounce);
+
+ return 0;
+}
+
+static int mx25_tcq_open(struct input_dev *idev)
+{
+ struct device *dev = &idev->dev;
+ struct mx25_tcq_priv *priv = dev_get_drvdata(dev);
+ int error;
+
+ error = clk_prepare_enable(priv->clk);
+ if (error) {
+ dev_err(dev, "Failed to enable ipg clock\n");
+ return error;
+ }
+
+ error = mx25_tcq_init(priv);
+ if (error) {
+ dev_err(dev, "Failed to init tcq\n");
+ clk_disable_unprepare(priv->clk);
+ return error;
+ }
+
+ mx25_tcq_re_enable_touch_detection(priv);
+
+ return 0;
+}
+
+static void mx25_tcq_close(struct input_dev *idev)
+{
+ struct mx25_tcq_priv *priv = input_get_drvdata(idev);
+
+ mx25_tcq_force_queue_stop(priv);
+ mx25_tcq_disable_touch_irq(priv);
+ mx25_tcq_disable_fifo_irq(priv);
+ clk_disable_unprepare(priv->clk);
+}
+
+static int mx25_tcq_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct input_dev *idev;
+ struct mx25_tcq_priv *priv;
+ struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
+ struct resource *res;
+ void __iomem *mem;
+ int error;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mem = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mem))
+ return PTR_ERR(mem);
+
+ error = mx25_tcq_parse_dt(pdev, priv);
+ if (error)
+ return error;
+
+ priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_tcq_regconfig);
+ if (IS_ERR(priv->regs)) {
+ dev_err(dev, "Failed to initialize regmap\n");
+ return PTR_ERR(priv->regs);
+ }
+
+ priv->irq = platform_get_irq(pdev, 0);
+ if (priv->irq <= 0) {
+ dev_err(dev, "Failed to get IRQ\n");
+ return priv->irq;
+ }
+
+ idev = devm_input_allocate_device(dev);
+ if (!idev) {
+ dev_err(dev, "Failed to allocate input device\n");
+ return -ENOMEM;
+ }
+
+ idev->name = mx25_tcq_name;
+ input_set_capability(idev, EV_KEY, BTN_TOUCH);
+ input_set_abs_params(idev, ABS_X, 0, 0xfff, 0, 0);
+ input_set_abs_params(idev, ABS_Y, 0, 0xfff, 0, 0);
+
+ idev->id.bustype = BUS_HOST;
+ idev->open = mx25_tcq_open;
+ idev->close = mx25_tcq_close;
+
+ priv->idev = idev;
+ input_set_drvdata(idev, priv);
+
+ priv->core_regs = tsadc->regs;
+ if (!priv->core_regs)
+ return -EINVAL;
+
+ priv->clk = tsadc->clk;
+ if (!priv->clk)
+ return -EINVAL;
+
+ platform_set_drvdata(pdev, priv);
+
+ error = devm_request_threaded_irq(dev, priv->irq, mx25_tcq_irq,
+ mx25_tcq_irq_thread, 0, pdev->name,
+ priv);
+ if (error) {
+ dev_err(dev, "Failed requesting IRQ\n");
+ return error;
+ }
+
+ error = input_register_device(idev);
+ if (error) {
+ dev_err(dev, "Failed to register input device\n");
+ return error;
+ }
+
+ return 0;
+}
+
+static struct platform_driver mx25_tcq_driver = {
+ .driver = {
+ .name = "mx25-tcq",
+ .of_match_table = mx25_tcq_ids,
+ },
+ .probe = mx25_tcq_probe,
+};
+module_platform_driver(mx25_tcq_driver);
+
+MODULE_DESCRIPTION("TS input driver for Freescale mx25");
+MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 1bc97c2761e4..eea61e349e26 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -18,6 +18,17 @@ config MFD_CS5535
This is the core driver for CS5535/CS5536 MFD functions. This is
necessary for using the board's GPIO and MFGPT functionality.
+config MFD_ACT8945A
+ tristate "Active-semi ACT8945A"
+ select MFD_CORE
+ select REGMAP_I2C
+ depends on I2C && OF
+ help
+ Support for the ACT8945A PMIC from Active-semi. This device
+ features three step-down DC/DC converters and four low-dropout
+ linear regulators, along with a complete ActivePath battery
+ charger.
+
config MFD_AS3711
bool "AMS AS3711"
select MFD_CORE
@@ -91,14 +102,29 @@ config MFD_BCM590XX
Support for the BCM590xx PMUs from Broadcom
config MFD_AXP20X
- bool "X-Powers AXP20X"
+ tristate
select MFD_CORE
- select REGMAP_I2C
select REGMAP_IRQ
- depends on I2C=y
+
+config MFD_AXP20X_I2C
+ tristate "X-Powers AXP series PMICs with I2C"
+ select MFD_AXP20X
+ select REGMAP_I2C
+ depends on I2C
+ help
+ If you say Y here you get support for the X-Powers AXP series power
+ management ICs (PMICs) controlled with I2C.
+ This driver include only the core APIs. You have to select individual
+ components like regulators or the PEK (Power Enable Key) under the
+ corresponding menus.
+
+config MFD_AXP20X_RSB
+ tristate "X-Powers AXP series PMICs with RSB"
+ select MFD_AXP20X
+ depends on SUNXI_RSB
help
- If you say Y here you get support for the X-Powers AXP202, AXP209 and
- AXP288 power management IC (PMIC).
+ If you say Y here you get support for the X-Powers AXP series power
+ management ICs (PMICs) controlled with RSB.
This driver include only the core APIs. You have to select individual
components like regulators or the PEK (Power Enable Key) under the
corresponding menus.
@@ -203,7 +229,7 @@ config MFD_DA9062
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
- depends on I2C=y
+ depends on I2C
help
Say yes here for support for the Dialog Semiconductor DA9062 PMIC.
This includes the I2C driver and core APIs.
@@ -215,7 +241,7 @@ config MFD_DA9063
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
- depends on I2C=y
+ depends on I2C
help
Say yes here for support for the Dialog Semiconductor DA9063 PMIC.
This includes the I2C driver and core APIs.
@@ -224,7 +250,7 @@ config MFD_DA9063
config MFD_DA9150
tristate "Dialog Semiconductor DA9150 Charger Fuel-Gauge chip"
- depends on I2C=y
+ depends on I2C
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -271,6 +297,15 @@ config MFD_MC13XXX_I2C
help
Select this if your MC13xxx is connected via an I2C bus.
+config MFD_MX25_TSADC
+ tristate "Freescale i.MX25 integrated Touchscreen and ADC unit"
+ select REGMAP_MMIO
+ depends on (SOC_IMX25 && OF) || COMPILE_TEST
+ help
+ Enable support for the integrated Touchscreen and ADC unit of the
+ i.MX25 processors. They consist of a conversion queue for general
+ purpose ADC and a queue for Touchscreens.
+
config MFD_HI6421_PMIC
tristate "HiSilicon Hi6421 PMU/Codec IC"
depends on OF
@@ -445,7 +480,7 @@ config MFD_KEMPLD
config MFD_88PM800
tristate "Marvell 88PM800"
- depends on I2C=y
+ depends on I2C
select REGMAP_I2C
select REGMAP_IRQ
select MFD_CORE
@@ -457,7 +492,7 @@ config MFD_88PM800
config MFD_88PM805
tristate "Marvell 88PM805"
- depends on I2C=y
+ depends on I2C
select REGMAP_I2C
select REGMAP_IRQ
select MFD_CORE
@@ -493,8 +528,8 @@ config MFD_MAX14577
of the device.
config MFD_MAX77686
- bool "Maxim Semiconductor MAX77686/802 PMIC Support"
- depends on I2C=y
+ tristate "Maxim Semiconductor MAX77686/802 PMIC Support"
+ depends on I2C
depends on OF
select MFD_CORE
select REGMAP_I2C
@@ -538,7 +573,7 @@ config MFD_MAX77843
config MFD_MAX8907
tristate "Maxim Semiconductor MAX8907 PMIC Support"
select MFD_CORE
- depends on I2C=y
+ depends on I2C
select REGMAP_I2C
select REGMAP_IRQ
help
@@ -743,7 +778,7 @@ config MFD_RTSX_PCI
config MFD_RT5033
tristate "Richtek RT5033 Power Management IC"
- depends on I2C=y
+ depends on I2C
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -1106,6 +1141,19 @@ config TPS6507X
This driver can also be built as a module. If so, the module
will be called tps6507x.
+config MFD_TPS65086
+ tristate "TI TPS65086 Power Management Integrated Chips (PMICs)"
+ select REGMAP
+ select REGMAP_IRQ
+ select REGMAP_I2C
+ depends on I2C
+ help
+ If you say yes here you get support for the TPS65086 series of
+ Power Management chips.
+ This driver provides common support for accessing the device,
+ additional drivers must be enabled in order to use the
+ functionality of the device.
+
config TPS65911_COMPARATOR
tristate
@@ -1370,7 +1418,6 @@ config MFD_ARIZONA
config MFD_ARIZONA_I2C
tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with I2C"
select MFD_ARIZONA
- select MFD_CORE
select REGMAP_I2C
depends on I2C
help
@@ -1380,12 +1427,11 @@ config MFD_ARIZONA_I2C
config MFD_ARIZONA_SPI
tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with SPI"
select MFD_ARIZONA
- select MFD_CORE
select REGMAP_SPI
depends on SPI_MASTER
help
Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
- audio SoC core functionality controlled via I2C.
+ audio SoC core functionality controlled via SPI.
config MFD_CS47L24
bool "Cirrus Logic CS47L24 and WM1831"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 1811202cee19..5eaa6465d0a6 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -6,6 +6,7 @@
obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o
obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
+obj-$(CONFIG_MFD_ACT8945A) += act8945a.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
@@ -70,6 +71,7 @@ obj-$(CONFIG_MFD_WM8994) += wm8994.o
obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o
obj-$(CONFIG_TPS6507X) += tps6507x.o
+obj-$(CONFIG_MFD_TPS65086) += tps65086.o
obj-$(CONFIG_MFD_TPS65217) += tps65217.o
obj-$(CONFIG_MFD_TPS65218) += tps65218.o
obj-$(CONFIG_MFD_TPS65910) += tps65910.o
@@ -84,6 +86,8 @@ obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o
obj-$(CONFIG_TWL6040_CORE) += twl6040.o
+obj-$(CONFIG_MFD_MX25_TSADC) += fsl-imx25-tsadc.o
+
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
@@ -110,6 +114,8 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
obj-$(CONFIG_MFD_AXP20X) += axp20x.o
+obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
+obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
obj-$(CONFIG_MFD_LP3943) += lp3943.o
obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o
diff --git a/drivers/mfd/act8945a.c b/drivers/mfd/act8945a.c
new file mode 100644
index 000000000000..525b546ba42f
--- /dev/null
+++ b/drivers/mfd/act8945a.c
@@ -0,0 +1,102 @@
+/*
+ * MFD driver for Active-semi ACT8945a PMIC
+ *
+ * Copyright (C) 2015 Atmel Corporation.
+ *
+ * Author: Wenyou Yang <wenyou.yang@atmel.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.
+ */
+
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell act8945a_devs[] = {
+ {
+ .name = "act8945a-regulator",
+ },
+ {
+ .name = "act8945a-charger",
+ },
+};
+
+static const struct regmap_config act8945a_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int act8945a_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_i2c(i2c, &act8945a_regmap_config);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
+ return ret;
+ }
+
+ i2c_set_clientdata(i2c, regmap);
+
+ ret = mfd_add_devices(&i2c->dev, PLATFORM_DEVID_NONE, act8945a_devs,
+ ARRAY_SIZE(act8945a_devs), NULL, 0, NULL);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to add sub devices\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int act8945a_i2c_remove(struct i2c_client *i2c)
+{
+ mfd_remove_devices(&i2c->dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id act8945a_i2c_id[] = {
+ { "act8945a", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, act8945a_i2c_id);
+
+static const struct of_device_id act8945a_of_match[] = {
+ { .compatible = "active-semi,act8945a", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, act8945a_of_match);
+
+static struct i2c_driver act8945a_i2c_driver = {
+ .driver = {
+ .name = "act8945a",
+ .of_match_table = of_match_ptr(act8945a_of_match),
+ },
+ .probe = act8945a_i2c_probe,
+ .remove = act8945a_i2c_remove,
+ .id_table = act8945a_i2c_id,
+};
+
+static int __init act8945a_i2c_init(void)
+{
+ return i2c_add_driver(&act8945a_i2c_driver);
+}
+subsys_initcall(act8945a_i2c_init);
+
+static void __exit act8945a_i2c_exit(void)
+{
+ i2c_del_driver(&act8945a_i2c_driver);
+}
+module_exit(act8945a_i2c_exit);
+
+MODULE_DESCRIPTION("ACT8945A PMIC multi-function driver");
+MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c
index 94d67a6e1eb7..09e1483b99bc 100644
--- a/drivers/mfd/as3711.c
+++ b/drivers/mfd/as3711.c
@@ -108,8 +108,8 @@ static const struct regmap_config as3711_regmap_config = {
.volatile_reg = as3711_volatile_reg,
.readable_reg = as3711_readable_reg,
.precious_reg = as3711_precious_reg,
- .max_register = AS3711_MAX_REGS,
- .num_reg_defaults_raw = AS3711_MAX_REGS,
+ .max_register = AS3711_MAX_REG,
+ .num_reg_defaults_raw = AS3711_NUM_REGS,
.cache_type = REGCACHE_RBTREE,
};
diff --git a/drivers/mfd/axp20x-i2c.c b/drivers/mfd/axp20x-i2c.c
new file mode 100644
index 000000000000..b1b865822c07
--- /dev/null
+++ b/drivers/mfd/axp20x-i2c.c
@@ -0,0 +1,104 @@
+/*
+ * I2C driver for the X-Powers' Power Management ICs
+ *
+ * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
+ * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
+ * as well as configurable GPIOs.
+ *
+ * This driver supports the I2C variants.
+ *
+ * Copyright (C) 2014 Carlo Caione
+ *
+ * Author: Carlo Caione <carlo@caione.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+static int axp20x_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct axp20x_dev *axp20x;
+ int ret;
+
+ axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
+ if (!axp20x)
+ return -ENOMEM;
+
+ axp20x->dev = &i2c->dev;
+ axp20x->irq = i2c->irq;
+ dev_set_drvdata(axp20x->dev, axp20x);
+
+ ret = axp20x_match_device(axp20x);
+ if (ret)
+ return ret;
+
+ axp20x->regmap = devm_regmap_init_i2c(i2c, axp20x->regmap_cfg);
+ if (IS_ERR(axp20x->regmap)) {
+ ret = PTR_ERR(axp20x->regmap);
+ dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
+ return ret;
+ }
+
+ return axp20x_device_probe(axp20x);
+}
+
+static int axp20x_i2c_remove(struct i2c_client *i2c)
+{
+ struct axp20x_dev *axp20x = i2c_get_clientdata(i2c);
+
+ return axp20x_device_remove(axp20x);
+}
+
+static const struct of_device_id axp20x_i2c_of_match[] = {
+ { .compatible = "x-powers,axp152", .data = (void *)AXP152_ID },
+ { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
+ { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
+ { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
+ { },
+};
+MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
+
+/*
+ * This is useless for OF-enabled devices, but it is needed by I2C subsystem
+ */
+static const struct i2c_device_id axp20x_i2c_id[] = {
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
+
+static const struct acpi_device_id axp20x_i2c_acpi_match[] = {
+ {
+ .id = "INT33F4",
+ .driver_data = AXP288_ID,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, axp20x_i2c_acpi_match);
+
+static struct i2c_driver axp20x_i2c_driver = {
+ .driver = {
+ .name = "axp20x-i2c",
+ .of_match_table = of_match_ptr(axp20x_i2c_of_match),
+ .acpi_match_table = ACPI_PTR(axp20x_i2c_acpi_match),
+ },
+ .probe = axp20x_i2c_probe,
+ .remove = axp20x_i2c_remove,
+ .id_table = axp20x_i2c_id,
+};
+
+module_i2c_driver(axp20x_i2c_driver);
+
+MODULE_DESCRIPTION("PMIC MFD I2C driver for AXP20X");
+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/axp20x-rsb.c b/drivers/mfd/axp20x-rsb.c
new file mode 100644
index 000000000000..28c20247c112
--- /dev/null
+++ b/drivers/mfd/axp20x-rsb.c
@@ -0,0 +1,80 @@
+/*
+ * RSB driver for the X-Powers' Power Management ICs
+ *
+ * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
+ * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
+ * as well as configurable GPIOs.
+ *
+ * This driver supports the RSB variants.
+ *
+ * Copyright (C) 2015 Chen-Yu Tsai
+ *
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/err.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/sunxi-rsb.h>
+
+static int axp20x_rsb_probe(struct sunxi_rsb_device *rdev)
+{
+ struct axp20x_dev *axp20x;
+ int ret;
+
+ axp20x = devm_kzalloc(&rdev->dev, sizeof(*axp20x), GFP_KERNEL);
+ if (!axp20x)
+ return -ENOMEM;
+
+ axp20x->dev = &rdev->dev;
+ axp20x->irq = rdev->irq;
+ dev_set_drvdata(&rdev->dev, axp20x);
+
+ ret = axp20x_match_device(axp20x);
+ if (ret)
+ return ret;
+
+ axp20x->regmap = devm_regmap_init_sunxi_rsb(rdev, axp20x->regmap_cfg);
+ if (IS_ERR(axp20x->regmap)) {
+ ret = PTR_ERR(axp20x->regmap);
+ dev_err(&rdev->dev, "regmap init failed: %d\n", ret);
+ return ret;
+ }
+
+ return axp20x_device_probe(axp20x);
+}
+
+static int axp20x_rsb_remove(struct sunxi_rsb_device *rdev)
+{
+ struct axp20x_dev *axp20x = sunxi_rsb_device_get_drvdata(rdev);
+
+ return axp20x_device_remove(axp20x);
+}
+
+static const struct of_device_id axp20x_rsb_of_match[] = {
+ { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
+ { },
+};
+MODULE_DEVICE_TABLE(of, axp20x_rsb_of_match);
+
+static struct sunxi_rsb_driver axp20x_rsb_driver = {
+ .driver = {
+ .name = "axp20x-rsb",
+ .of_match_table = of_match_ptr(axp20x_rsb_of_match),
+ },
+ .probe = axp20x_rsb_probe,
+ .remove = axp20x_rsb_remove,
+};
+module_sunxi_rsb_driver(axp20x_rsb_driver);
+
+MODULE_DESCRIPTION("PMIC MFD sunXi RSB driver for AXP20X");
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 9842199e2e6c..a57d6e940610 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -1,10 +1,14 @@
/*
- * axp20x.c - MFD core driver for the X-Powers' Power Management ICs
+ * MFD core driver for the X-Powers' Power Management ICs
*
* AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC
* converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature
* as well as configurable GPIOs.
*
+ * This file contains the interface independent core functions.
+ *
+ * Copyright (C) 2014 Carlo Caione
+ *
* Author: Carlo Caione <carlo@caione.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,18 +17,15 @@
*/
#include <linux/err.h>
-#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
-#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/axp20x.h>
#include <linux/mfd/core.h>
#include <linux/of_device.h>
-#include <linux/of_irq.h>
#include <linux/acpi.h>
#define AXP20X_OFF 0x80
@@ -34,6 +35,7 @@ static const char * const axp20x_model_names[] = {
"AXP202",
"AXP209",
"AXP221",
+ "AXP223",
"AXP288",
};
@@ -376,32 +378,6 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
};
-static const struct of_device_id axp20x_of_match[] = {
- { .compatible = "x-powers,axp152", .data = (void *) AXP152_ID },
- { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
- { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
- { .compatible = "x-powers,axp221", .data = (void *) AXP221_ID },
- { },
-};
-MODULE_DEVICE_TABLE(of, axp20x_of_match);
-
-/*
- * This is useless for OF-enabled devices, but it is needed by I2C subsystem
- */
-static const struct i2c_device_id axp20x_i2c_id[] = {
- { },
-};
-MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
-
-static const struct acpi_device_id axp20x_acpi_match[] = {
- {
- .id = "INT33F4",
- .driver_data = AXP288_ID,
- },
- { },
-};
-MODULE_DEVICE_TABLE(acpi, axp20x_acpi_match);
-
static const struct regmap_irq_chip axp152_regmap_irq_chip = {
.name = "axp152_irq_chip",
.status_base = AXP152_IRQ1_STATE,
@@ -606,25 +582,26 @@ static void axp20x_power_off(void)
AXP20X_OFF);
}
-static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
+int axp20x_match_device(struct axp20x_dev *axp20x)
{
+ struct device *dev = axp20x->dev;
const struct acpi_device_id *acpi_id;
const struct of_device_id *of_id;
if (dev->of_node) {
- of_id = of_match_device(axp20x_of_match, dev);
+ of_id = of_match_device(dev->driver->of_match_table, dev);
if (!of_id) {
dev_err(dev, "Unable to match OF ID\n");
return -ENODEV;
}
- axp20x->variant = (long) of_id->data;
+ axp20x->variant = (long)of_id->data;
} else {
acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!acpi_id || !acpi_id->driver_data) {
dev_err(dev, "Unable to match ACPI ID and data\n");
return -ENODEV;
}
- axp20x->variant = (long) acpi_id->driver_data;
+ axp20x->variant = (long)acpi_id->driver_data;
}
switch (axp20x->variant) {
@@ -642,6 +619,7 @@ static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
break;
case AXP221_ID:
+ case AXP223_ID:
axp20x->nr_cells = ARRAY_SIZE(axp22x_cells);
axp20x->cells = axp22x_cells;
axp20x->regmap_cfg = &axp22x_regmap_config;
@@ -658,51 +636,31 @@ static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
return -EINVAL;
}
dev_info(dev, "AXP20x variant %s found\n",
- axp20x_model_names[axp20x->variant]);
+ axp20x_model_names[axp20x->variant]);
return 0;
}
+EXPORT_SYMBOL(axp20x_match_device);
-static int axp20x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+int axp20x_device_probe(struct axp20x_dev *axp20x)
{
- struct axp20x_dev *axp20x;
int ret;
- axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
- if (!axp20x)
- return -ENOMEM;
-
- ret = axp20x_match_device(axp20x, &i2c->dev);
- if (ret)
- return ret;
-
- axp20x->i2c_client = i2c;
- axp20x->dev = &i2c->dev;
- dev_set_drvdata(axp20x->dev, axp20x);
-
- axp20x->regmap = devm_regmap_init_i2c(i2c, axp20x->regmap_cfg);
- if (IS_ERR(axp20x->regmap)) {
- ret = PTR_ERR(axp20x->regmap);
- dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
- return ret;
- }
-
- ret = regmap_add_irq_chip(axp20x->regmap, i2c->irq,
+ ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
IRQF_ONESHOT | IRQF_SHARED, -1,
axp20x->regmap_irq_chip,
&axp20x->regmap_irqc);
if (ret) {
- dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret);
+ dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret);
return ret;
}
ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
- axp20x->nr_cells, NULL, 0, NULL);
+ axp20x->nr_cells, NULL, 0, NULL);
if (ret) {
- dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
- regmap_del_irq_chip(i2c->irq, axp20x->regmap_irqc);
+ dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
+ regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
return ret;
}
@@ -711,38 +669,25 @@ static int axp20x_i2c_probe(struct i2c_client *i2c,
pm_power_off = axp20x_power_off;
}
- dev_info(&i2c->dev, "AXP20X driver loaded\n");
+ dev_info(axp20x->dev, "AXP20X driver loaded\n");
return 0;
}
+EXPORT_SYMBOL(axp20x_device_probe);
-static int axp20x_i2c_remove(struct i2c_client *i2c)
+int axp20x_device_remove(struct axp20x_dev *axp20x)
{
- struct axp20x_dev *axp20x = i2c_get_clientdata(i2c);
-
if (axp20x == axp20x_pm_power_off) {
axp20x_pm_power_off = NULL;
pm_power_off = NULL;
}
mfd_remove_devices(axp20x->dev);
- regmap_del_irq_chip(axp20x->i2c_client->irq, axp20x->regmap_irqc);
+ regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
return 0;
}
-
-static struct i2c_driver axp20x_i2c_driver = {
- .driver = {
- .name = "axp20x",
- .of_match_table = of_match_ptr(axp20x_of_match),
- .acpi_match_table = ACPI_PTR(axp20x_acpi_match),
- },
- .probe = axp20x_i2c_probe,
- .remove = axp20x_i2c_remove,
- .id_table = axp20x_i2c_id,
-};
-
-module_i2c_driver(axp20x_i2c_driver);
+EXPORT_SYMBOL(axp20x_device_remove);
MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
diff --git a/drivers/mfd/cs47l24-tables.c b/drivers/mfd/cs47l24-tables.c
index 870800657594..f6b78aafdb55 100644
--- a/drivers/mfd/cs47l24-tables.c
+++ b/drivers/mfd/cs47l24-tables.c
@@ -227,8 +227,6 @@ static const struct reg_default cs47l24_reg_default[] = {
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
{ 0x00000175, 0x0006 }, /* R373 - FLL1 Control 5 */
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
- { 0x00000177, 0x0281 }, /* R375 - FLL1 Loop Filter Test 1 */
- { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
{ 0x00000179, 0x0000 }, /* R376 - FLL1 Control 7 */
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
@@ -245,8 +243,6 @@ static const struct reg_default cs47l24_reg_default[] = {
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
{ 0x00000195, 0x000C }, /* R405 - FLL2 Control 5 */
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
- { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
- { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
{ 0x00000199, 0x0000 }, /* R408 - FLL2 Control 7 */
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
@@ -678,7 +674,7 @@ static const struct reg_default cs47l24_reg_default[] = {
{ 0x00000C0F, 0x0400 }, /* R3087 - IRQ CTRL 1 */
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
{ 0x00000C20, 0x0002 }, /* R3104 - Misc Pad Ctrl 1 */
- { 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
+ { 0x00000C21, 0x0000 }, /* R3105 - Misc Pad Ctrl 2 */
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
@@ -858,8 +854,6 @@ static bool cs47l24_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL1_CONTROL_5:
case ARIZONA_FLL1_CONTROL_6:
case ARIZONA_FLL1_CONTROL_7:
- case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL1_NCO_TEST_0:
case ARIZONA_FLL1_SYNCHRONISER_1:
case ARIZONA_FLL1_SYNCHRONISER_2:
case ARIZONA_FLL1_SYNCHRONISER_3:
@@ -876,8 +870,6 @@ static bool cs47l24_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL2_CONTROL_5:
case ARIZONA_FLL2_CONTROL_6:
case ARIZONA_FLL2_CONTROL_7:
- case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL2_NCO_TEST_0:
case ARIZONA_FLL2_SYNCHRONISER_1:
case ARIZONA_FLL2_SYNCHRONISER_2:
case ARIZONA_FLL2_SYNCHRONISER_3:
diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
index a9ad024ec6b0..8f873866ea60 100644
--- a/drivers/mfd/da9062-core.c
+++ b/drivers/mfd/da9062-core.c
@@ -388,11 +388,32 @@ static const struct regmap_range da9062_aa_volatile_ranges[] = {
.range_min = DA9062AA_STATUS_D,
.range_max = DA9062AA_EVENT_C,
}, {
- .range_min = DA9062AA_CONTROL_F,
+ .range_min = DA9062AA_CONTROL_A,
+ .range_max = DA9062AA_CONTROL_B,
+ }, {
+ .range_min = DA9062AA_CONTROL_E,
.range_max = DA9062AA_CONTROL_F,
}, {
+ .range_min = DA9062AA_BUCK2_CONT,
+ .range_max = DA9062AA_BUCK4_CONT,
+ }, {
+ .range_min = DA9062AA_BUCK3_CONT,
+ .range_max = DA9062AA_BUCK3_CONT,
+ }, {
+ .range_min = DA9062AA_LDO1_CONT,
+ .range_max = DA9062AA_LDO4_CONT,
+ }, {
+ .range_min = DA9062AA_DVC_1,
+ .range_max = DA9062AA_DVC_1,
+ }, {
.range_min = DA9062AA_COUNT_S,
.range_max = DA9062AA_SECOND_D,
+ }, {
+ .range_min = DA9062AA_SEQ,
+ .range_max = DA9062AA_SEQ,
+ }, {
+ .range_min = DA9062AA_EN_32K,
+ .range_max = DA9062AA_EN_32K,
},
};
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index 2d4e3e0f4e94..73901084945f 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -74,18 +74,30 @@ static const struct regmap_range da9063_ad_writeable_ranges[] = {
static const struct regmap_range da9063_ad_volatile_ranges[] = {
{
- .range_min = DA9063_REG_STATUS_A,
+ .range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_REG_EVENT_D,
}, {
- .range_min = DA9063_REG_CONTROL_F,
+ .range_min = DA9063_REG_CONTROL_A,
+ .range_max = DA9063_REG_CONTROL_B,
+ }, {
+ .range_min = DA9063_REG_CONTROL_E,
.range_max = DA9063_REG_CONTROL_F,
}, {
- .range_min = DA9063_REG_ADC_MAN,
+ .range_min = DA9063_REG_BCORE2_CONT,
+ .range_max = DA9063_REG_LDO11_CONT,
+ }, {
+ .range_min = DA9063_REG_DVC_1,
.range_max = DA9063_REG_ADC_MAN,
}, {
.range_min = DA9063_REG_ADC_RES_L,
.range_max = DA9063_AD_REG_SECOND_D,
}, {
+ .range_min = DA9063_REG_SEQ,
+ .range_max = DA9063_REG_SEQ,
+ }, {
+ .range_min = DA9063_REG_EN_32K,
+ .range_max = DA9063_REG_EN_32K,
+ }, {
.range_min = DA9063_AD_REG_MON_REG_5,
.range_max = DA9063_AD_REG_MON_REG_6,
},
@@ -152,18 +164,30 @@ static const struct regmap_range da9063_bb_writeable_ranges[] = {
static const struct regmap_range da9063_bb_volatile_ranges[] = {
{
- .range_min = DA9063_REG_STATUS_A,
+ .range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_REG_EVENT_D,
}, {
- .range_min = DA9063_REG_CONTROL_F,
+ .range_min = DA9063_REG_CONTROL_A,
+ .range_max = DA9063_REG_CONTROL_B,
+ }, {
+ .range_min = DA9063_REG_CONTROL_E,
.range_max = DA9063_REG_CONTROL_F,
}, {
- .range_min = DA9063_REG_ADC_MAN,
+ .range_min = DA9063_REG_BCORE2_CONT,
+ .range_max = DA9063_REG_LDO11_CONT,
+ }, {
+ .range_min = DA9063_REG_DVC_1,
.range_max = DA9063_REG_ADC_MAN,
}, {
.range_min = DA9063_REG_ADC_RES_L,
.range_max = DA9063_BB_REG_SECOND_D,
}, {
+ .range_min = DA9063_REG_SEQ,
+ .range_max = DA9063_REG_SEQ,
+ }, {
+ .range_min = DA9063_REG_EN_32K,
+ .range_max = DA9063_REG_EN_32K,
+ }, {
.range_min = DA9063_BB_REG_MON_REG_5,
.range_max = DA9063_BB_REG_MON_REG_6,
},
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 12099b09a9a7..c0a86aeb1733 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -739,20 +739,17 @@ int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
if (!div && !requests[clkout])
return -EINVAL;
- switch (clkout) {
- case 0:
+ if (clkout == 0) {
div_mask = PRCM_CLKOCR_CLKODIV0_MASK;
mask = (PRCM_CLKOCR_CLKODIV0_MASK | PRCM_CLKOCR_CLKOSEL0_MASK);
bits = ((source << PRCM_CLKOCR_CLKOSEL0_SHIFT) |
(div << PRCM_CLKOCR_CLKODIV0_SHIFT));
- break;
- case 1:
+ } else {
div_mask = PRCM_CLKOCR_CLKODIV1_MASK;
mask = (PRCM_CLKOCR_CLKODIV1_MASK | PRCM_CLKOCR_CLKOSEL1_MASK |
PRCM_CLKOCR_CLK1TYPE);
bits = ((source << PRCM_CLKOCR_CLKOSEL1_SHIFT) |
(div << PRCM_CLKOCR_CLKODIV1_SHIFT));
- break;
}
bits &= mask;
diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c
new file mode 100644
index 000000000000..77b2675cf8f5
--- /dev/null
+++ b/drivers/mfd/fsl-imx25-tsadc.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdesc.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/mfd/imx25-tsadc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static struct regmap_config mx25_tsadc_regmap_config = {
+ .fast_io = true,
+ .max_register = 8,
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static void mx25_tsadc_irq_handler(struct irq_desc *desc)
+{
+ struct mx25_tsadc *tsadc = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ u32 status;
+
+ chained_irq_enter(chip, desc);
+
+ regmap_read(tsadc->regs, MX25_TSC_TGSR, &status);
+
+ if (status & MX25_TGSR_GCQ_INT)
+ generic_handle_irq(irq_find_mapping(tsadc->domain, 1));
+
+ if (status & MX25_TGSR_TCQ_INT)
+ generic_handle_irq(irq_find_mapping(tsadc->domain, 0));
+
+ chained_irq_exit(chip, desc);
+}
+
+static int mx25_tsadc_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct mx25_tsadc *tsadc = d->host_data;
+
+ irq_set_chip_data(irq, tsadc);
+ irq_set_chip_and_handler(irq, &dummy_irq_chip,
+ handle_level_irq);
+ irq_modify_status(irq, IRQ_NOREQUEST, IRQ_NOPROBE);
+
+ return 0;
+}
+
+static struct irq_domain_ops mx25_tsadc_domain_ops = {
+ .map = mx25_tsadc_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static int mx25_tsadc_setup_irq(struct platform_device *pdev,
+ struct mx25_tsadc *tsadc)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ int irq;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(dev, "Failed to get irq\n");
+ return irq;
+ }
+
+ tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
+ tsadc);
+ if (!tsadc->domain) {
+ dev_err(dev, "Failed to add irq domain\n");
+ return -ENOMEM;
+ }
+
+ irq_set_chained_handler(irq, mx25_tsadc_irq_handler);
+ irq_set_handler_data(irq, tsadc);
+
+ return 0;
+}
+
+static void mx25_tsadc_setup_clk(struct platform_device *pdev,
+ struct mx25_tsadc *tsadc)
+{
+ unsigned clk_div;
+
+ /*
+ * According to the datasheet the ADC clock should never
+ * exceed 1,75 MHz. Base clock is the IPG and the ADC unit uses
+ * a funny clock divider. To keep the ADC conversion time constant
+ * adapt the ADC internal clock divider to the IPG clock rate.
+ */
+
+ dev_dbg(&pdev->dev, "Found master clock at %lu Hz\n",
+ clk_get_rate(tsadc->clk));
+
+ clk_div = DIV_ROUND_UP(clk_get_rate(tsadc->clk), 1750000);
+ dev_dbg(&pdev->dev, "Setting up ADC clock divider to %u\n", clk_div);
+
+ /* adc clock = IPG clock / (2 * div + 2) */
+ clk_div -= 2;
+ clk_div /= 2;
+
+ /*
+ * the ADC clock divider changes its behaviour when values below 4
+ * are used: it is fixed to "/ 10" in this case
+ */
+ clk_div = max_t(unsigned, 4, clk_div);
+
+ dev_dbg(&pdev->dev, "Resulting ADC conversion clock at %lu Hz\n",
+ clk_get_rate(tsadc->clk) / (2 * clk_div + 2));
+
+ regmap_update_bits(tsadc->regs, MX25_TSC_TGCR,
+ MX25_TGCR_ADCCLKCFG(0x1f),
+ MX25_TGCR_ADCCLKCFG(clk_div));
+}
+
+static int mx25_tsadc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct mx25_tsadc *tsadc;
+ struct resource *res;
+ int ret;
+ void __iomem *iomem;
+
+ tsadc = devm_kzalloc(dev, sizeof(*tsadc), GFP_KERNEL);
+ if (!tsadc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ iomem = devm_ioremap_resource(dev, res);
+ if (IS_ERR(iomem))
+ return PTR_ERR(iomem);
+
+ tsadc->regs = devm_regmap_init_mmio(dev, iomem,
+ &mx25_tsadc_regmap_config);
+ if (IS_ERR(tsadc->regs)) {
+ dev_err(dev, "Failed to initialize regmap\n");
+ return PTR_ERR(tsadc->regs);
+ }
+
+ tsadc->clk = devm_clk_get(dev, "ipg");
+ if (IS_ERR(tsadc->clk)) {
+ dev_err(dev, "Failed to get ipg clock\n");
+ return PTR_ERR(tsadc->clk);
+ }
+
+ /* setup clock according to the datasheet */
+ mx25_tsadc_setup_clk(pdev, tsadc);
+
+ /* Enable clock and reset the component */
+ regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_CLK_EN,
+ MX25_TGCR_CLK_EN);
+ regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_TSC_RST,
+ MX25_TGCR_TSC_RST);
+
+ /* Setup powersaving mode, but enable internal reference voltage */
+ regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_POWERMODE_MASK,
+ MX25_TGCR_POWERMODE_SAVE);
+ regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_INTREFEN,
+ MX25_TGCR_INTREFEN);
+
+ ret = mx25_tsadc_setup_irq(pdev, tsadc);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, tsadc);
+
+ of_platform_populate(np, NULL, NULL, dev);
+
+ return 0;
+}
+
+static const struct of_device_id mx25_tsadc_ids[] = {
+ { .compatible = "fsl,imx25-tsadc" },
+ { /* Sentinel */ }
+};
+
+static struct platform_driver mx25_tsadc_driver = {
+ .driver = {
+ .name = "mx25-tsadc",
+ .of_match_table = of_match_ptr(mx25_tsadc_ids),
+ },
+ .probe = mx25_tsadc_probe,
+};
+module_platform_driver(mx25_tsadc_driver);
+
+MODULE_DESCRIPTION("MFD for ADC/TSC for Freescale mx25");
+MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:mx25-tsadc");
diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c
index 06f00d60be46..5a8d9c766633 100644
--- a/drivers/mfd/intel-lpss-acpi.c
+++ b/drivers/mfd/intel-lpss-acpi.c
@@ -44,8 +44,20 @@ static const struct intel_lpss_platform_info bxt_info = {
.clk_rate = 100000000,
};
+static struct property_entry bxt_i2c_properties[] = {
+ PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
+ PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
+ PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
+ { },
+};
+
+static struct property_set bxt_i2c_pset = {
+ .properties = bxt_i2c_properties,
+};
+
static const struct intel_lpss_platform_info bxt_i2c_info = {
.clk_rate = 133000000,
+ .pset = &bxt_i2c_pset,
};
static const struct acpi_device_id intel_lpss_acpi_ids[] = {
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c
index a7136c7ae9fb..a19e57118641 100644
--- a/drivers/mfd/intel-lpss-pci.c
+++ b/drivers/mfd/intel-lpss-pci.c
@@ -107,12 +107,24 @@ static const struct intel_lpss_platform_info bxt_uart_info = {
.pset = &uart_pset,
};
+static struct property_entry bxt_i2c_properties[] = {
+ PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
+ PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
+ PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
+ { },
+};
+
+static struct property_set bxt_i2c_pset = {
+ .properties = bxt_i2c_properties,
+};
+
static const struct intel_lpss_platform_info bxt_i2c_info = {
.clk_rate = 133000000,
+ .pset = &bxt_i2c_pset,
};
static const struct pci_device_id intel_lpss_pci_ids[] = {
- /* BXT */
+ /* BXT A-Step */
{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0ab0), (kernel_ulong_t)&bxt_i2c_info },
@@ -128,6 +140,23 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x0ac4), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x0ac6), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x0aee), (kernel_ulong_t)&bxt_uart_info },
+ /* BXT B-Step */
+ { PCI_VDEVICE(INTEL, 0x1aac), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1aae), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1ab0), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1ab2), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1ab4), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1ab6), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1ab8), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1aba), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x1abc), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x1abe), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x1ac0), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x1ac2), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
+
/* APL */
{ PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&bxt_i2c_info },
diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
index 1743788f1595..1bbbe877ba7e 100644
--- a/drivers/mfd/intel-lpss.c
+++ b/drivers/mfd/intel-lpss.c
@@ -453,6 +453,7 @@ int intel_lpss_probe(struct device *dev,
err_remove_ltr:
intel_lpss_debugfs_remove(lpss);
intel_lpss_ltr_hide(lpss);
+ intel_lpss_unregister_clock(lpss);
err_clk_register:
ida_simple_remove(&intel_lpss_devid_ida, lpss->devid);
diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index 042137465300..bdc5e27222c0 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -52,8 +52,6 @@
/* The Quark I2C controller source clock */
#define INTEL_QUARK_I2C_CLK_HZ 33000000
-#define INTEL_QUARK_I2C_NCLK 1
-
struct intel_quark_mfd {
struct pci_dev *pdev;
struct clk *i2c_clk;
@@ -128,30 +126,24 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
{
struct pci_dev *pdev = quark_mfd->pdev;
- struct clk_lookup *i2c_clk_lookup;
struct clk *i2c_clk;
- int ret;
-
- i2c_clk_lookup = devm_kcalloc(&pdev->dev, INTEL_QUARK_I2C_NCLK,
- sizeof(*i2c_clk_lookup), GFP_KERNEL);
- if (!i2c_clk_lookup)
- return -ENOMEM;
-
- i2c_clk_lookup[0].dev_id = INTEL_QUARK_I2C_CONTROLLER_CLK;
i2c_clk = clk_register_fixed_rate(&pdev->dev,
INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
CLK_IS_ROOT, INTEL_QUARK_I2C_CLK_HZ);
+ if (IS_ERR(i2c_clk))
+ return PTR_ERR(i2c_clk);
- quark_mfd->i2c_clk_lookup = i2c_clk_lookup;
quark_mfd->i2c_clk = i2c_clk;
+ quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
+ INTEL_QUARK_I2C_CONTROLLER_CLK);
- ret = clk_register_clkdevs(i2c_clk, i2c_clk_lookup,
- INTEL_QUARK_I2C_NCLK);
- if (ret)
- dev_err(&pdev->dev, "Fixed clk register failed: %d\n", ret);
+ if (!quark_mfd->i2c_clk_lookup) {
+ dev_err(&pdev->dev, "Fixed clk register failed\n");
+ return -ENOMEM;
+ }
- return ret;
+ return 0;
}
static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c
index a41859c55bda..df16fd1df68b 100644
--- a/drivers/mfd/ipaq-micro.c
+++ b/drivers/mfd/ipaq-micro.c
@@ -376,7 +376,7 @@ static const struct mfd_cell micro_cells[] = {
{ .name = "ipaq-micro-leds", },
};
-static int micro_resume(struct device *dev)
+static int __maybe_unused micro_resume(struct device *dev)
{
struct ipaq_micro *micro = dev_get_drvdata(dev);
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index 98ecd136a21b..c1aff46e89d9 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -169,6 +169,7 @@ static const struct of_device_id max77686_pmic_dt_match[] = {
},
{ },
};
+MODULE_DEVICE_TABLE(of, max77686_pmic_dt_match);
static int max77686_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
@@ -265,6 +266,7 @@ static int max77686_i2c_remove(struct i2c_client *i2c)
static const struct i2c_device_id max77686_i2c_id[] = {
{ "max77686", TYPE_MAX77686 },
+ { "max77802", TYPE_MAX77802 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77686_i2c_id);
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 1749c1c9f405..8e8d93249c09 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -19,11 +19,17 @@
#include <linux/regmap.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6397/registers.h>
+#include <linux/mfd/mt6323/registers.h>
#define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e
+#define MT6323_CID_CODE 0x23
+#define MT6391_CID_CODE 0x91
+#define MT6397_CID_CODE 0x97
+
static const struct resource mt6397_rtc_resources[] = {
{
.start = MT6397_RTC_BASE,
@@ -37,6 +43,13 @@ static const struct resource mt6397_rtc_resources[] = {
},
};
+static const struct mfd_cell mt6323_devs[] = {
+ {
+ .name = "mt6323-regulator",
+ .of_compatible = "mediatek,mt6323-regulator"
+ },
+};
+
static const struct mfd_cell mt6397_devs[] = {
{
.name = "mt6397-rtc",
@@ -69,8 +82,10 @@ static void mt6397_irq_sync_unlock(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
- regmap_write(mt6397->regmap, MT6397_INT_CON0, mt6397->irq_masks_cur[0]);
- regmap_write(mt6397->regmap, MT6397_INT_CON1, mt6397->irq_masks_cur[1]);
+ regmap_write(mt6397->regmap, mt6397->int_con[0],
+ mt6397->irq_masks_cur[0]);
+ regmap_write(mt6397->regmap, mt6397->int_con[1],
+ mt6397->irq_masks_cur[1]);
mutex_unlock(&mt6397->irqlock);
}
@@ -147,8 +162,8 @@ static irqreturn_t mt6397_irq_thread(int irq, void *data)
{
struct mt6397_chip *mt6397 = data;
- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS0, 0);
- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS1, 16);
+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
return IRQ_HANDLED;
}
@@ -177,8 +192,8 @@ static int mt6397_irq_init(struct mt6397_chip *mt6397)
mutex_init(&mt6397->irqlock);
/* Mask all interrupt sources */
- regmap_write(mt6397->regmap, MT6397_INT_CON0, 0x0);
- regmap_write(mt6397->regmap, MT6397_INT_CON1, 0x0);
+ regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
+ regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
@@ -203,8 +218,8 @@ static int mt6397_irq_suspend(struct device *dev)
{
struct mt6397_chip *chip = dev_get_drvdata(dev);
- regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]);
- regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]);
+ regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
+ regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
enable_irq_wake(chip->irq);
@@ -215,8 +230,8 @@ static int mt6397_irq_resume(struct device *dev)
{
struct mt6397_chip *chip = dev_get_drvdata(dev);
- regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]);
- regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]);
+ regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
+ regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
disable_irq_wake(chip->irq);
@@ -230,34 +245,69 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
static int mt6397_probe(struct platform_device *pdev)
{
int ret;
- struct mt6397_chip *mt6397;
+ unsigned int id;
+ struct mt6397_chip *pmic;
- mt6397 = devm_kzalloc(&pdev->dev, sizeof(*mt6397), GFP_KERNEL);
- if (!mt6397)
+ pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
+ if (!pmic)
return -ENOMEM;
- mt6397->dev = &pdev->dev;
+ pmic->dev = &pdev->dev;
+
/*
* mt6397 MFD is child device of soc pmic wrapper.
* Regmap is set from its parent.
*/
- mt6397->regmap = dev_get_regmap(pdev->dev.parent, NULL);
- if (!mt6397->regmap)
+ pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!pmic->regmap)
return -ENODEV;
- platform_set_drvdata(pdev, mt6397);
+ platform_set_drvdata(pdev, pmic);
- mt6397->irq = platform_get_irq(pdev, 0);
- if (mt6397->irq > 0) {
- ret = mt6397_irq_init(mt6397);
+ ret = regmap_read(pmic->regmap, MT6397_CID, &id);
+ if (ret) {
+ dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
+ goto fail_irq;
+ }
+
+ switch (id & 0xff) {
+ case MT6323_CID_CODE:
+ pmic->int_con[0] = MT6323_INT_CON0;
+ pmic->int_con[1] = MT6323_INT_CON1;
+ pmic->int_status[0] = MT6323_INT_STATUS0;
+ pmic->int_status[1] = MT6323_INT_STATUS1;
+ ret = mfd_add_devices(&pdev->dev, -1, mt6323_devs,
+ ARRAY_SIZE(mt6323_devs), NULL, 0, NULL);
+ break;
+
+ case MT6397_CID_CODE:
+ case MT6391_CID_CODE:
+ pmic->int_con[0] = MT6397_INT_CON0;
+ pmic->int_con[1] = MT6397_INT_CON1;
+ pmic->int_status[0] = MT6397_INT_STATUS0;
+ pmic->int_status[1] = MT6397_INT_STATUS1;
+ ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
+ ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "unsupported chip: %d\n", id);
+ ret = -ENODEV;
+ break;
+ }
+
+ pmic->irq = platform_get_irq(pdev, 0);
+ if (pmic->irq > 0) {
+ ret = mt6397_irq_init(pmic);
if (ret)
return ret;
}
- ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
- ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
- if (ret)
+fail_irq:
+ if (ret) {
+ irq_domain_remove(pmic->irq_domain);
dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
+ }
return ret;
}
@@ -271,10 +321,17 @@ static int mt6397_remove(struct platform_device *pdev)
static const struct of_device_id mt6397_of_match[] = {
{ .compatible = "mediatek,mt6397" },
+ { .compatible = "mediatek,mt6323" },
{ }
};
MODULE_DEVICE_TABLE(of, mt6397_of_match);
+static const struct platform_device_id mt6397_id[] = {
+ { "mt6397", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, mt6397_id);
+
static struct platform_driver mt6397_driver = {
.probe = mt6397_probe,
.remove = mt6397_remove,
@@ -283,6 +340,7 @@ static struct platform_driver mt6397_driver = {
.of_match_table = of_match_ptr(mt6397_of_match),
.pm = &mt6397_pm_ops,
},
+ .id_table = mt6397_id,
};
module_platform_driver(mt6397_driver);
@@ -290,4 +348,3 @@ module_platform_driver(mt6397_driver);
MODULE_AUTHOR("Flora Fu, MediaTek");
MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mt6397");
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index e10f02f5d551..fc2b2d93f354 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -241,8 +241,8 @@ static const struct regmap_config rc5t583_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.volatile_reg = volatile_reg,
- .max_register = RC5T583_MAX_REGS,
- .num_reg_defaults_raw = RC5T583_MAX_REGS,
+ .max_register = RC5T583_MAX_REG,
+ .num_reg_defaults_raw = RC5T583_NUM_REGS,
.cache_type = REGCACHE_RBTREE,
};
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 8222e374e4b1..fb8f9e8b75df 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -334,6 +334,31 @@ static const struct mfd_cell stmpe_keypad_cell = {
};
/*
+ * PWM (1601, 2401, 2403)
+ */
+static struct resource stmpe_pwm_resources[] = {
+ {
+ .name = "PWM0",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "PWM1",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "PWM2",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct mfd_cell stmpe_pwm_cell = {
+ .name = "stmpe-pwm",
+ .of_compatible = "st,stmpe-pwm",
+ .resources = stmpe_pwm_resources,
+ .num_resources = ARRAY_SIZE(stmpe_pwm_resources),
+};
+
+/*
* STMPE801
*/
static const u8 stmpe801_regs[] = {
@@ -537,6 +562,11 @@ static struct stmpe_variant_block stmpe1601_blocks[] = {
.irq = STMPE1601_IRQ_KEYPAD,
.block = STMPE_BLOCK_KEYPAD,
},
+ {
+ .cell = &stmpe_pwm_cell,
+ .irq = STMPE1601_IRQ_PWM0,
+ .block = STMPE_BLOCK_PWM,
+ },
};
/* supported autosleep timeout delay (in msecs) */
@@ -771,6 +801,11 @@ static struct stmpe_variant_block stmpe24xx_blocks[] = {
.irq = STMPE24XX_IRQ_KEYPAD,
.block = STMPE_BLOCK_KEYPAD,
},
+ {
+ .cell = &stmpe_pwm_cell,
+ .irq = STMPE24XX_IRQ_PWM0,
+ .block = STMPE_BLOCK_PWM,
+ },
};
static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index b7aabeefab07..2f2225e845ef 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -36,7 +36,7 @@ struct syscon {
struct list_head list;
};
-static struct regmap_config syscon_regmap_config = {
+static const struct regmap_config syscon_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
@@ -50,6 +50,7 @@ static struct syscon *of_syscon_register(struct device_node *np)
u32 reg_io_width;
int ret;
struct regmap_config syscon_config = syscon_regmap_config;
+ struct resource res;
if (!of_device_is_compatible(np, "syscon"))
return ERR_PTR(-EINVAL);
@@ -58,7 +59,12 @@ static struct syscon *of_syscon_register(struct device_node *np)
if (!syscon)
return ERR_PTR(-ENOMEM);
- base = of_iomap(np, 0);
+ if (of_address_to_resource(np, 0, &res)) {
+ ret = -ENOMEM;
+ goto err_map;
+ }
+
+ base = ioremap(res.start, resource_size(&res));
if (!base) {
ret = -ENOMEM;
goto err_map;
@@ -81,6 +87,7 @@ static struct syscon *of_syscon_register(struct device_node *np)
syscon_config.reg_stride = reg_io_width;
syscon_config.val_bits = reg_io_width * 8;
+ syscon_config.max_register = resource_size(&res) - reg_io_width;
regmap = regmap_init_mmio(NULL, base, &syscon_config);
if (IS_ERR(regmap)) {
@@ -192,6 +199,7 @@ static int syscon_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct syscon_platform_data *pdata = dev_get_platdata(dev);
struct syscon *syscon;
+ struct regmap_config syscon_config = syscon_regmap_config;
struct resource *res;
void __iomem *base;
@@ -207,11 +215,10 @@ static int syscon_probe(struct platform_device *pdev)
if (!base)
return -ENOMEM;
- syscon_regmap_config.max_register = res->end - res->start - 3;
+ syscon_config.max_register = res->end - res->start - 3;
if (pdata)
- syscon_regmap_config.name = pdata->label;
- syscon->regmap = devm_regmap_init_mmio(dev, base,
- &syscon_regmap_config);
+ syscon_config.name = pdata->label;
+ syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
if (IS_ERR(syscon->regmap)) {
dev_err(dev, "regmap init failed\n");
return PTR_ERR(syscon->regmap);
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c
index 83e615ed100a..495e4518fc29 100644
--- a/drivers/mfd/tps65010.c
+++ b/drivers/mfd/tps65010.c
@@ -1059,26 +1059,7 @@ EXPORT_SYMBOL(tps65013_set_low_pwr);
static int __init tps_init(void)
{
- u32 tries = 3;
- int status = -ENODEV;
-
- printk(KERN_INFO "%s: version %s\n", DRIVER_NAME, DRIVER_VERSION);
-
- /* some boards have startup glitches */
- while (tries--) {
- status = i2c_add_driver(&tps65010_driver);
- if (the_tps)
- break;
- i2c_del_driver(&tps65010_driver);
- if (!tries) {
- printk(KERN_ERR "%s: no chip?\n", DRIVER_NAME);
- return -ENODEV;
- }
- pr_debug("%s: re-probe ...\n", DRIVER_NAME);
- msleep(10);
- }
-
- return status;
+ return i2c_add_driver(&tps65010_driver);
}
/* NOTE: this MUST be initialized before the other parts of the system
* that rely on it ... but after the i2c bus on which this relies.
diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
new file mode 100644
index 000000000000..43119a6867fe
--- /dev/null
+++ b/drivers/mfd/tps65086.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65912 driver
+ */
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+
+#include <linux/mfd/tps65086.h>
+
+static const struct mfd_cell tps65086_cells[] = {
+ { .name = "tps65086-regulator", },
+ { .name = "tps65086-gpio", },
+};
+
+static const struct regmap_range tps65086_yes_ranges[] = {
+ regmap_reg_range(TPS65086_IRQ, TPS65086_IRQ),
+ regmap_reg_range(TPS65086_PMICSTAT, TPS65086_SHUTDNSRC),
+ regmap_reg_range(TPS65086_GPOCTRL, TPS65086_GPOCTRL),
+ regmap_reg_range(TPS65086_PG_STATUS1, TPS65086_OC_STATUS),
+};
+
+static const struct regmap_access_table tps65086_volatile_table = {
+ .yes_ranges = tps65086_yes_ranges,
+ .n_yes_ranges = ARRAY_SIZE(tps65086_yes_ranges),
+};
+
+static const struct regmap_config tps65086_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .cache_type = REGCACHE_RBTREE,
+ .volatile_table = &tps65086_volatile_table,
+};
+
+static const struct regmap_irq tps65086_irqs[] = {
+ REGMAP_IRQ_REG(TPS65086_IRQ_DIETEMP, 0, TPS65086_IRQ_DIETEMP_MASK),
+ REGMAP_IRQ_REG(TPS65086_IRQ_SHUTDN, 0, TPS65086_IRQ_SHUTDN_MASK),
+ REGMAP_IRQ_REG(TPS65086_IRQ_FAULT, 0, TPS65086_IRQ_FAULT_MASK),
+};
+
+static struct regmap_irq_chip tps65086_irq_chip = {
+ .name = "tps65086",
+ .status_base = TPS65086_IRQ,
+ .mask_base = TPS65086_IRQ_MASK,
+ .ack_base = TPS65086_IRQ,
+ .init_ack_masked = true,
+ .num_regs = 1,
+ .irqs = tps65086_irqs,
+ .num_irqs = ARRAY_SIZE(tps65086_irqs),
+};
+
+static const struct of_device_id tps65086_of_match_table[] = {
+ { .compatible = "ti,tps65086", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
+
+static int tps65086_probe(struct i2c_client *client,
+ const struct i2c_device_id *ids)
+{
+ struct tps65086 *tps;
+ unsigned int version;
+ int ret;
+
+ tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+ if (!tps)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, tps);
+ tps->dev = &client->dev;
+ tps->irq = client->irq;
+
+ tps->regmap = devm_regmap_init_i2c(client, &tps65086_regmap_config);
+ if (IS_ERR(tps->regmap)) {
+ dev_err(tps->dev, "Failed to initialize register map\n");
+ return PTR_ERR(tps->regmap);
+ }
+
+ ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
+ if (ret) {
+ dev_err(tps->dev, "Failed to read revision register\n");
+ return ret;
+ }
+
+ dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
+ (version & TPS65086_DEVICEID_PART_MASK),
+ (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
+ (version & TPS65086_DEVICEID_REV_MASK) >> 6);
+
+ ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
+ &tps65086_irq_chip, &tps->irq_data);
+ if (ret) {
+ dev_err(tps->dev, "Failed to register IRQ chip\n");
+ return ret;
+ }
+
+ ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65086_cells,
+ ARRAY_SIZE(tps65086_cells), NULL, 0,
+ regmap_irq_get_domain(tps->irq_data));
+ if (ret) {
+ regmap_del_irq_chip(tps->irq, tps->irq_data);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int tps65086_remove(struct i2c_client *client)
+{
+ struct tps65086 *tps = i2c_get_clientdata(client);
+
+ regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+ return 0;
+}
+
+static const struct i2c_device_id tps65086_id_table[] = {
+ { "tps65086", 0 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, tps65086_id_table);
+
+static struct i2c_driver tps65086_driver = {
+ .driver = {
+ .name = "tps65086",
+ .of_match_table = tps65086_of_match_table,
+ },
+ .probe = tps65086_probe,
+ .remove = tps65086_remove,
+ .id_table = tps65086_id_table,
+};
+module_i2c_driver(tps65086_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65086 PMIC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index f88085ad9772..d7ec318c40c3 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -30,7 +30,6 @@
#include <linux/err.h>
#define NUM_INT_REG 2
-#define TOTAL_NUM_REG 0x18
#define TPS65090_INT1_MASK_VAC_STATUS_CHANGE 1
#define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE 2
@@ -161,8 +160,8 @@ static bool is_volatile_reg(struct device *dev, unsigned int reg)
static const struct regmap_config tps65090_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .max_register = TOTAL_NUM_REG,
- .num_reg_defaults_raw = TOTAL_NUM_REG,
+ .max_register = TPS65090_MAX_REG,
+ .num_reg_defaults_raw = TPS65090_NUM_REGS,
.cache_type = REGCACHE_RBTREE,
.volatile_reg = is_volatile_reg,
};
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 0386eaf6be32..ab8b23b5bd22 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -297,7 +297,6 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
{ 0x00000175, 0x0004 }, /* R373 - FLL1 Control 5 */
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
- { 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */
{ 0x00000179, 0x0000 }, /* R377 - FLL1 Control 7 */
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
@@ -314,7 +313,6 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
{ 0x00000195, 0x0004 }, /* R405 - FLL2 Control 5 */
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
- { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
{ 0x00000199, 0x0000 }, /* R409 - FLL2 Control 7 */
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
@@ -338,7 +336,7 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
{ 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */
- { 0x000002A7, 0x372C }, /* R679 - Mic Detect Level 2 */
+ { 0x000002A7, 0x2C37 }, /* R679 - Mic Detect Level 2 */
{ 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */
{ 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */
{ 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */
@@ -402,7 +400,7 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */
{ 0x00000436, 0x0081 }, /* R1078 - DAC Volume Limit 5R */
{ 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */
- { 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
+ { 0x00000440, 0x0FFF }, /* R1088 - DRE Enable */
{ 0x00000442, 0x3F0A }, /* R1090 - DRE Control 2 */
{ 0x00000443, 0xDC1F }, /* R1090 - DRE Control 3 */
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
@@ -863,7 +861,7 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x00000C0F, 0x0400 }, /* R3087 - IRQ CTRL 1 */
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
{ 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */
- { 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
+ { 0x00000C21, 0x0001 }, /* R3105 - Misc Pad Ctrl 2 */
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
@@ -984,7 +982,7 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x00000ECD, 0x0000 }, /* R3789 - HPLPF4_2 */
{ 0x00000EE0, 0x0000 }, /* R3808 - ASRC_ENABLE */
{ 0x00000EE2, 0x0000 }, /* R3810 - ASRC_RATE1 */
- { 0x00000EE3, 0x0400 }, /* R3811 - ASRC_RATE2 */
+ { 0x00000EE3, 0x4000 }, /* R3811 - ASRC_RATE2 */
{ 0x00000EF0, 0x0000 }, /* R3824 - ISRC 1 CTRL 1 */
{ 0x00000EF1, 0x0000 }, /* R3825 - ISRC 1 CTRL 2 */
{ 0x00000EF2, 0x0000 }, /* R3826 - ISRC 1 CTRL 3 */
@@ -1062,8 +1060,6 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL1_CONTROL_4:
case ARIZONA_FLL1_CONTROL_5:
case ARIZONA_FLL1_CONTROL_6:
- case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL1_NCO_TEST_0:
case ARIZONA_FLL1_CONTROL_7:
case ARIZONA_FLL1_SYNCHRONISER_1:
case ARIZONA_FLL1_SYNCHRONISER_2:
@@ -1080,8 +1076,6 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL2_CONTROL_4:
case ARIZONA_FLL2_CONTROL_5:
case ARIZONA_FLL2_CONTROL_6:
- case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL2_NCO_TEST_0:
case ARIZONA_FLL2_CONTROL_7:
case ARIZONA_FLL2_SYNCHRONISER_1:
case ARIZONA_FLL2_SYNCHRONISER_2:
@@ -1849,8 +1843,6 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_HAPTICS_STATUS:
case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS:
case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS:
- case ARIZONA_FLL1_NCO_TEST_0:
- case ARIZONA_FLL2_NCO_TEST_0:
case ARIZONA_DAC_COMP_1:
case ARIZONA_DAC_COMP_2:
case ARIZONA_DAC_COMP_3:
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index c18e11f42b3f..8e74e71507e7 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -676,8 +676,8 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */
{ 0x00000009, 0x0001 }, /* R9 - Ctrl IF I2C1 CFG 1 */
{ 0x0000000A, 0x0001 }, /* R10 - Ctrl IF I2C2 CFG 1 */
- { 0x0000000B, 0x0036 }, /* R11 - Ctrl IF I2C1 CFG 2 */
- { 0x0000000C, 0x0036 }, /* R12 - Ctrl IF I2C2 CFG 2 */
+ { 0x0000000B, 0x001A }, /* R11 - Ctrl IF I2C1 CFG 2 */
+ { 0x0000000C, 0x001A }, /* R12 - Ctrl IF I2C2 CFG 2 */
{ 0x00000020, 0x0000 }, /* R32 - Tone Generator 1 */
{ 0x00000021, 0x1000 }, /* R33 - Tone Generator 2 */
{ 0x00000022, 0x0000 }, /* R34 - Tone Generator 3 */
@@ -723,14 +723,12 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */
{ 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */
{ 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */
- { 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */
+ { 0x00000171, 0x0002 }, /* R369 - FLL1 Control 1 */
{ 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */
{ 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
{ 0x00000175, 0x0006 }, /* R373 - FLL1 Control 5 */
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
- { 0x00000177, 0x0281 }, /* R375 - FLL1 Loop Filter Test 1 */
- { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
{ 0x00000179, 0x0000 }, /* R376 - FLL1 Control 7 */
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
@@ -740,15 +738,13 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */
{ 0x00000187, 0x0001 }, /* R390 - FLL1 Synchroniser 7 */
{ 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */
- { 0x0000018A, 0x0004 }, /* R394 - FLL1 GPIO Clock */
- { 0x00000191, 0x0000 }, /* R401 - FLL2 Control 1 */
+ { 0x0000018A, 0x000C }, /* R394 - FLL1 GPIO Clock */
+ { 0x00000191, 0x0002 }, /* R401 - FLL2 Control 1 */
{ 0x00000192, 0x0008 }, /* R402 - FLL2 Control 2 */
{ 0x00000193, 0x0018 }, /* R403 - FLL2 Control 3 */
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
{ 0x00000195, 0x000C }, /* R405 - FLL2 Control 5 */
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
- { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
- { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
{ 0x00000199, 0x0000 }, /* R408 - FLL2 Control 7 */
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
@@ -758,7 +754,7 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */
{ 0x000001A7, 0x0001 }, /* R422 - FLL2 Synchroniser 7 */
{ 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */
- { 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */
+ { 0x000001AA, 0x000C }, /* R426 - FLL2 GPIO Clock */
{ 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */
{ 0x00000210, 0x0184 }, /* R528 - LDO1 Control 1 */
{ 0x00000213, 0x03E4 }, /* R531 - LDO2 Control 1 */
@@ -771,9 +767,9 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
{ 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */
- { 0x000002A7, 0x372C }, /* R679 - Mic Detect Level 2 */
+ { 0x000002A7, 0x2C37 }, /* R679 - Mic Detect Level 2 */
{ 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */
- { 0x000002A9, 0x300A }, /* R681 - Mic Detect Level 4 */
+ { 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */
{ 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */
{ 0x000002CB, 0x0000 }, /* R715 - Isolation control */
{ 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */
@@ -810,53 +806,53 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000409, 0x0022 }, /* R1033 - Output Volume Ramp */
{ 0x00000410, 0x0080 }, /* R1040 - Output Path Config 1L */
{ 0x00000411, 0x0180 }, /* R1041 - DAC Digital Volume 1L */
- { 0x00000412, 0x0080 }, /* R1042 - DAC Volume Limit 1L */
+ { 0x00000412, 0x0081 }, /* R1042 - DAC Volume Limit 1L */
{ 0x00000413, 0x0001 }, /* R1043 - Noise Gate Select 1L */
{ 0x00000414, 0x0080 }, /* R1044 - Output Path Config 1R */
{ 0x00000415, 0x0180 }, /* R1045 - DAC Digital Volume 1R */
- { 0x00000416, 0x0080 }, /* R1046 - DAC Volume Limit 1R */
+ { 0x00000416, 0x0081 }, /* R1046 - DAC Volume Limit 1R */
{ 0x00000417, 0x0002 }, /* R1047 - Noise Gate Select 1R */
{ 0x00000418, 0x0080 }, /* R1048 - Output Path Config 2L */
{ 0x00000419, 0x0180 }, /* R1049 - DAC Digital Volume 2L */
- { 0x0000041A, 0x0080 }, /* R1050 - DAC Volume Limit 2L */
+ { 0x0000041A, 0x0081 }, /* R1050 - DAC Volume Limit 2L */
{ 0x0000041B, 0x0004 }, /* R1051 - Noise Gate Select 2L */
{ 0x0000041C, 0x0080 }, /* R1052 - Output Path Config 2R */
{ 0x0000041D, 0x0180 }, /* R1053 - DAC Digital Volume 2R */
- { 0x0000041E, 0x0080 }, /* R1054 - DAC Volume Limit 2R */
+ { 0x0000041E, 0x0081 }, /* R1054 - DAC Volume Limit 2R */
{ 0x0000041F, 0x0008 }, /* R1055 - Noise Gate Select 2R */
{ 0x00000420, 0x0080 }, /* R1056 - Output Path Config 3L */
{ 0x00000421, 0x0180 }, /* R1057 - DAC Digital Volume 3L */
- { 0x00000422, 0x0080 }, /* R1058 - DAC Volume Limit 3L */
+ { 0x00000422, 0x0081 }, /* R1058 - DAC Volume Limit 3L */
{ 0x00000423, 0x0010 }, /* R1059 - Noise Gate Select 3L */
{ 0x00000424, 0x0080 }, /* R1060 - Output Path Config 3R */
{ 0x00000425, 0x0180 }, /* R1061 - DAC Digital Volume 3R */
- { 0x00000426, 0x0080 }, /* R1062 - DAC Volume Limit 3R */
+ { 0x00000426, 0x0081 }, /* R1062 - DAC Volume Limit 3R */
{ 0x00000427, 0x0020 }, /* R1063 - Noise Gate Select 3R */
{ 0x00000428, 0x0000 }, /* R1064 - Output Path Config 4L */
{ 0x00000429, 0x0180 }, /* R1065 - DAC Digital Volume 4L */
- { 0x0000042A, 0x0080 }, /* R1066 - Out Volume 4L */
+ { 0x0000042A, 0x0081 }, /* R1066 - Out Volume 4L */
{ 0x0000042B, 0x0040 }, /* R1067 - Noise Gate Select 4L */
{ 0x0000042C, 0x0000 }, /* R1068 - Output Path Config 4R */
{ 0x0000042D, 0x0180 }, /* R1069 - DAC Digital Volume 4R */
- { 0x0000042E, 0x0080 }, /* R1070 - Out Volume 4R */
+ { 0x0000042E, 0x0081 }, /* R1070 - Out Volume 4R */
{ 0x0000042F, 0x0080 }, /* R1071 - Noise Gate Select 4R */
{ 0x00000430, 0x0000 }, /* R1072 - Output Path Config 5L */
{ 0x00000431, 0x0180 }, /* R1073 - DAC Digital Volume 5L */
- { 0x00000432, 0x0080 }, /* R1074 - DAC Volume Limit 5L */
+ { 0x00000432, 0x0081 }, /* R1074 - DAC Volume Limit 5L */
{ 0x00000433, 0x0100 }, /* R1075 - Noise Gate Select 5L */
{ 0x00000434, 0x0000 }, /* R1076 - Output Path Config 5R */
{ 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */
- { 0x00000436, 0x0080 }, /* R1078 - DAC Volume Limit 5R */
+ { 0x00000436, 0x0081 }, /* R1078 - DAC Volume Limit 5R */
{ 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */
{ 0x00000438, 0x0000 }, /* R1080 - Output Path Config 6L */
{ 0x00000439, 0x0180 }, /* R1081 - DAC Digital Volume 6L */
- { 0x0000043A, 0x0080 }, /* R1082 - DAC Volume Limit 6L */
+ { 0x0000043A, 0x0081 }, /* R1082 - DAC Volume Limit 6L */
{ 0x0000043B, 0x0400 }, /* R1083 - Noise Gate Select 6L */
{ 0x0000043C, 0x0000 }, /* R1084 - Output Path Config 6R */
{ 0x0000043D, 0x0180 }, /* R1085 - DAC Digital Volume 6R */
- { 0x0000043E, 0x0080 }, /* R1086 - DAC Volume Limit 6R */
+ { 0x0000043E, 0x0081 }, /* R1086 - DAC Volume Limit 6R */
{ 0x0000043F, 0x0800 }, /* R1087 - Noise Gate Select 6R */
- { 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
+ { 0x00000440, 0x003F }, /* R1088 - DRE Enable */
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
{ 0x00000458, 0x0000 }, /* R1112 - Noise Gate Control */
{ 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */
@@ -864,8 +860,8 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000492, 0x0069 }, /* R1170 - PDM SPK2 CTRL 1 */
{ 0x00000493, 0x0000 }, /* R1171 - PDM SPK2 CTRL 2 */
{ 0x000004A0, 0x3480 }, /* R1184 - HP1 Short Circuit Ctrl */
- { 0x000004A1, 0x3480 }, /* R1185 - HP2 Short Circuit Ctrl */
- { 0x000004A2, 0x3480 }, /* R1186 - HP3 Short Circuit Ctrl */
+ { 0x000004A1, 0x3400 }, /* R1185 - HP2 Short Circuit Ctrl */
+ { 0x000004A2, 0x3400 }, /* R1186 - HP3 Short Circuit Ctrl */
{ 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */
{ 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */
{ 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */
@@ -1483,23 +1479,23 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
{ 0x00000C18, 0x0000 }, /* R3096 - GP Switch 1 */
{ 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */
- { 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
+ { 0x00000C21, 0x0001 }, /* R3105 - Misc Pad Ctrl 2 */
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
{ 0x00000C25, 0x0000 }, /* R3109 - Misc Pad Ctrl 6 */
- { 0x00000C30, 0x8282 }, /* R3120 - Misc Pad Ctrl 7 */
- { 0x00000C31, 0x0082 }, /* R3121 - Misc Pad Ctrl 8 */
- { 0x00000C32, 0x8282 }, /* R3122 - Misc Pad Ctrl 9 */
- { 0x00000C33, 0x8282 }, /* R3123 - Misc Pad Ctrl 10 */
- { 0x00000C34, 0x8282 }, /* R3124 - Misc Pad Ctrl 11 */
- { 0x00000C35, 0x8282 }, /* R3125 - Misc Pad Ctrl 12 */
- { 0x00000C36, 0x8282 }, /* R3126 - Misc Pad Ctrl 13 */
- { 0x00000C37, 0x8282 }, /* R3127 - Misc Pad Ctrl 14 */
- { 0x00000C38, 0x8282 }, /* R3128 - Misc Pad Ctrl 15 */
- { 0x00000C39, 0x8282 }, /* R3129 - Misc Pad Ctrl 16 */
- { 0x00000C3A, 0x8282 }, /* R3130 - Misc Pad Ctrl 17 */
- { 0x00000C3B, 0x8282 }, /* R3131 - Misc Pad Ctrl 18 */
+ { 0x00000C30, 0x0404 }, /* R3120 - Misc Pad Ctrl 7 */
+ { 0x00000C31, 0x0004 }, /* R3121 - Misc Pad Ctrl 8 */
+ { 0x00000C32, 0x0404 }, /* R3122 - Misc Pad Ctrl 9 */
+ { 0x00000C33, 0x0404 }, /* R3123 - Misc Pad Ctrl 10 */
+ { 0x00000C34, 0x0404 }, /* R3124 - Misc Pad Ctrl 11 */
+ { 0x00000C35, 0x0404 }, /* R3125 - Misc Pad Ctrl 12 */
+ { 0x00000C36, 0x0404 }, /* R3126 - Misc Pad Ctrl 13 */
+ { 0x00000C37, 0x0404 }, /* R3127 - Misc Pad Ctrl 14 */
+ { 0x00000C38, 0x0004 }, /* R3128 - Misc Pad Ctrl 15 */
+ { 0x00000C39, 0x0404 }, /* R3129 - Misc Pad Ctrl 16 */
+ { 0x00000C3A, 0x0404 }, /* R3130 - Misc Pad Ctrl 17 */
+ { 0x00000C3B, 0x0404 }, /* R3131 - Misc Pad Ctrl 18 */
{ 0x00000D08, 0xFFFF }, /* R3336 - Interrupt Status 1 Mask */
{ 0x00000D09, 0xFFFF }, /* R3337 - Interrupt Status 2 Mask */
{ 0x00000D0A, 0xFFFF }, /* R3338 - Interrupt Status 3 Mask */
@@ -1641,7 +1637,7 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000F0D, 0x0000 }, /* R3853 - ANC Coefficient */
{ 0x00000F0E, 0x0000 }, /* R3854 - ANC Coefficient */
{ 0x00000F0F, 0x0000 }, /* R3855 - ANC Coefficient */
- { 0x00000F10, 0x0000 }, /* R3856 - ANC Coefficient */
+ { 0x00000F10, 0x0001 }, /* R3856 - ANC Coefficient */
{ 0x00000F11, 0x0000 }, /* R3857 - ANC Coefficient */
{ 0x00000F12, 0x0000 }, /* R3858 - ANC Coefficient */
{ 0x00000F15, 0x0000 }, /* R3861 - FCL Filter Control */
@@ -1947,8 +1943,6 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL1_CONTROL_5:
case ARIZONA_FLL1_CONTROL_6:
case ARIZONA_FLL1_CONTROL_7:
- case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL1_NCO_TEST_0:
case ARIZONA_FLL1_SYNCHRONISER_1:
case ARIZONA_FLL1_SYNCHRONISER_2:
case ARIZONA_FLL1_SYNCHRONISER_3:
@@ -1965,8 +1959,6 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL2_CONTROL_5:
case ARIZONA_FLL2_CONTROL_6:
case ARIZONA_FLL2_CONTROL_7:
- case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL2_NCO_TEST_0:
case ARIZONA_FLL2_SYNCHRONISER_1:
case ARIZONA_FLL2_SYNCHRONISER_2:
case ARIZONA_FLL2_SYNCHRONISER_3:
diff --git a/drivers/mfd/wm8998-tables.c b/drivers/mfd/wm8998-tables.c
index 4c2dce77cdfc..a0de3002cdad 100644
--- a/drivers/mfd/wm8998-tables.c
+++ b/drivers/mfd/wm8998-tables.c
@@ -229,8 +229,6 @@ static const struct reg_default wm8998_reg_default[] = {
{ 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */
{ 0x00000175, 0x0004 }, /* R373 - FLL1 Control 5 */
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
- { 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */
- { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
{ 0x00000179, 0x0000 }, /* R377 - FLL1 Control 7 */
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
@@ -247,8 +245,6 @@ static const struct reg_default wm8998_reg_default[] = {
{ 0x00000194, 0x007D }, /* R404 - FLL2 Control 4 */
{ 0x00000195, 0x0004 }, /* R405 - FLL2 Control 5 */
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
- { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
- { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
{ 0x00000199, 0x0000 }, /* R409 - FLL2 Control 7 */
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
@@ -320,7 +316,7 @@ static const struct reg_default wm8998_reg_default[] = {
{ 0x00000434, 0x0000 }, /* R1076 - Output Path Config 5R */
{ 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */
{ 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */
- { 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
+ { 0x00000440, 0x002F }, /* R1088 - DRE Enable */
{ 0x00000441, 0xC759 }, /* R1089 - DRE Control 1 */
{ 0x00000442, 0x2A08 }, /* R1089 - DRE Control 2 */
{ 0x00000443, 0x5CFA }, /* R1089 - DRE Control 3 */
@@ -686,7 +682,7 @@ static const struct reg_default wm8998_reg_default[] = {
{ 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */
{ 0x00000C18, 0x0000 }, /* R3096 - GP Switch 1 */
{ 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */
- { 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */
+ { 0x00000C21, 0x0001 }, /* R3105 - Misc Pad Ctrl 2 */
{ 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */
{ 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */
{ 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */
@@ -888,8 +884,6 @@ static bool wm8998_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL1_CONTROL_5:
case ARIZONA_FLL1_CONTROL_6:
case ARIZONA_FLL1_CONTROL_7:
- case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL1_NCO_TEST_0:
case ARIZONA_FLL1_SYNCHRONISER_1:
case ARIZONA_FLL1_SYNCHRONISER_2:
case ARIZONA_FLL1_SYNCHRONISER_3:
@@ -906,8 +900,6 @@ static bool wm8998_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL2_CONTROL_5:
case ARIZONA_FLL2_CONTROL_6:
case ARIZONA_FLL2_CONTROL_7:
- case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
- case ARIZONA_FLL2_NCO_TEST_0:
case ARIZONA_FLL2_SYNCHRONISER_1:
case ARIZONA_FLL2_SYNCHRONISER_2:
case ARIZONA_FLL2_SYNCHRONISER_3:
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 214e815e98eb..40cd894e4df5 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -238,6 +238,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
step = 75;
break;
case AXP221_ID:
+ case AXP223_ID:
min = 1800;
max = 4050;
def = 3000;
@@ -316,6 +317,7 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
break;
case AXP221_ID:
+ case AXP223_ID:
if (id < AXP22X_DCDC1 || id > AXP22X_DCDC5)
return -EINVAL;
@@ -354,6 +356,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
nregulators = AXP20X_REG_ID_MAX;
break;
case AXP221_ID:
+ case AXP223_ID:
regulators = axp22x_regulators;
nregulators = AXP22X_REG_ID_MAX;
break;
diff --git a/include/dt-bindings/iio/adc/fsl-imx25-gcq.h b/include/dt-bindings/iio/adc/fsl-imx25-gcq.h
new file mode 100644
index 000000000000..87abdd4a7674
--- /dev/null
+++ b/include/dt-bindings/iio/adc/fsl-imx25-gcq.h
@@ -0,0 +1,18 @@
+/*
+ * This header provides constants for configuring the I.MX25 ADC
+ */
+
+#ifndef _DT_BINDINGS_IIO_ADC_FS_IMX25_GCQ_H
+#define _DT_BINDINGS_IIO_ADC_FS_IMX25_GCQ_H
+
+#define MX25_ADC_REFP_YP 0 /* YP voltage reference */
+#define MX25_ADC_REFP_XP 1 /* XP voltage reference */
+#define MX25_ADC_REFP_EXT 2 /* External voltage reference */
+#define MX25_ADC_REFP_INT 3 /* Internal voltage reference */
+
+#define MX25_ADC_REFN_XN 0 /* XN ground reference */
+#define MX25_ADC_REFN_YN 1 /* YN ground reference */
+#define MX25_ADC_REFN_NGND 2 /* Internal ground reference */
+#define MX25_ADC_REFN_NGND2 3 /* External ground reference */
+
+#endif
diff --git a/include/linux/mfd/as3711.h b/include/linux/mfd/as3711.h
index 38452ce1e892..34cc85864be5 100644
--- a/include/linux/mfd/as3711.h
+++ b/include/linux/mfd/as3711.h
@@ -51,7 +51,8 @@
#define AS3711_ASIC_ID_1 0x90
#define AS3711_ASIC_ID_2 0x91
-#define AS3711_MAX_REGS 0x92
+#define AS3711_MAX_REG AS3711_ASIC_ID_2
+#define AS3711_NUM_REGS (AS3711_MAX_REG + 1)
/* Regulators */
enum {
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index b24c771cebd5..d82e7d51372b 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -18,6 +18,7 @@ enum {
AXP202_ID,
AXP209_ID,
AXP221_ID,
+ AXP223_ID,
AXP288_ID,
NR_AXP20X_VARIANTS,
};
@@ -396,7 +397,7 @@ enum axp288_irqs {
struct axp20x_dev {
struct device *dev;
- struct i2c_client *i2c_client;
+ int irq;
struct regmap *regmap;
struct regmap_irq_chip_data *regmap_irqc;
long variant;
@@ -462,4 +463,35 @@ static inline int axp20x_read_variable_width(struct regmap *regmap,
return result;
}
+/**
+ * axp20x_match_device(): Setup axp20x variant related fields
+ *
+ * @axp20x: axp20x device to setup (.dev field must be set)
+ * @dev: device associated with this axp20x device
+ *
+ * This lets the axp20x core configure the mfd cells and register maps
+ * for later use.
+ */
+int axp20x_match_device(struct axp20x_dev *axp20x);
+
+/**
+ * axp20x_device_probe(): Probe a configured axp20x device
+ *
+ * @axp20x: axp20x device to probe (must be configured)
+ *
+ * This function lets the axp20x core register the axp20x mfd devices
+ * and irqchip. The axp20x device passed in must be fully configured
+ * with axp20x_match_device, its irq set, and regmap created.
+ */
+int axp20x_device_probe(struct axp20x_dev *axp20x);
+
+/**
+ * axp20x_device_probe(): Remove a axp20x device
+ *
+ * @axp20x: axp20x device to remove
+ *
+ * This tells the axp20x core to remove the associated mfd devices
+ */
+int axp20x_device_remove(struct axp20x_dev *axp20x);
+
#endif /* __LINUX_MFD_AXP20X_H */
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index 494682ce4bf3..a677c2bd485c 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -245,7 +245,7 @@ int cros_ec_remove(struct cros_ec_device *ec_dev);
int cros_ec_register(struct cros_ec_device *ec_dev);
/**
- * cros_ec_register - Query the protocol version supported by the ChromeOS EC
+ * cros_ec_query_all - Query the protocol version supported by the ChromeOS EC
*
* @ec_dev: Device to register
* @return 0 if ok, -ve on error
diff --git a/include/linux/mfd/imx25-tsadc.h b/include/linux/mfd/imx25-tsadc.h
new file mode 100644
index 000000000000..7fe4b8c3baac
--- /dev/null
+++ b/include/linux/mfd/imx25-tsadc.h
@@ -0,0 +1,140 @@
+#ifndef _LINUX_INCLUDE_MFD_IMX25_TSADC_H_
+#define _LINUX_INCLUDE_MFD_IMX25_TSADC_H_
+
+struct regmap;
+struct clk;
+
+struct mx25_tsadc {
+ struct regmap *regs;
+ struct irq_domain *domain;
+ struct clk *clk;
+};
+
+#define MX25_TSC_TGCR 0x00
+#define MX25_TSC_TGSR 0x04
+#define MX25_TSC_TICR 0x08
+
+/* The same register layout for TC and GC queue */
+#define MX25_ADCQ_FIFO 0x00
+#define MX25_ADCQ_CR 0x04
+#define MX25_ADCQ_SR 0x08
+#define MX25_ADCQ_MR 0x0c
+#define MX25_ADCQ_ITEM_7_0 0x20
+#define MX25_ADCQ_ITEM_15_8 0x24
+#define MX25_ADCQ_CFG(n) (0x40 + ((n) * 0x4))
+
+#define MX25_ADCQ_MR_MASK 0xffffffff
+
+/* TGCR */
+#define MX25_TGCR_PDBTIME(x) ((x) << 25)
+#define MX25_TGCR_PDBTIME_MASK GENMASK(31, 25)
+#define MX25_TGCR_PDBEN BIT(24)
+#define MX25_TGCR_PDEN BIT(23)
+#define MX25_TGCR_ADCCLKCFG(x) ((x) << 16)
+#define MX25_TGCR_GET_ADCCLK(x) (((x) >> 16) & 0x1f)
+#define MX25_TGCR_INTREFEN BIT(10)
+#define MX25_TGCR_POWERMODE_MASK GENMASK(9, 8)
+#define MX25_TGCR_POWERMODE_SAVE (1 << 8)
+#define MX25_TGCR_POWERMODE_ON (2 << 8)
+#define MX25_TGCR_STLC BIT(5)
+#define MX25_TGCR_SLPC BIT(4)
+#define MX25_TGCR_FUNC_RST BIT(2)
+#define MX25_TGCR_TSC_RST BIT(1)
+#define MX25_TGCR_CLK_EN BIT(0)
+
+/* TGSR */
+#define MX25_TGSR_SLP_INT BIT(2)
+#define MX25_TGSR_GCQ_INT BIT(1)
+#define MX25_TGSR_TCQ_INT BIT(0)
+
+/* ADCQ_ITEM_* */
+#define _MX25_ADCQ_ITEM(item, x) ((x) << ((item) * 4))
+#define MX25_ADCQ_ITEM(item, x) ((item) >= 8 ? \
+ _MX25_ADCQ_ITEM((item) - 8, (x)) : _MX25_ADCQ_ITEM((item), (x)))
+
+/* ADCQ_FIFO (TCQFIFO and GCQFIFO) */
+#define MX25_ADCQ_FIFO_DATA(x) (((x) >> 4) & 0xfff)
+#define MX25_ADCQ_FIFO_ID(x) ((x) & 0xf)
+
+/* ADCQ_CR (TCQR and GCQR) */
+#define MX25_ADCQ_CR_PDCFG_LEVEL BIT(19)
+#define MX25_ADCQ_CR_PDMSK BIT(18)
+#define MX25_ADCQ_CR_FRST BIT(17)
+#define MX25_ADCQ_CR_QRST BIT(16)
+#define MX25_ADCQ_CR_RWAIT_MASK GENMASK(15, 12)
+#define MX25_ADCQ_CR_RWAIT(x) ((x) << 12)
+#define MX25_ADCQ_CR_WMRK_MASK GENMASK(11, 8)
+#define MX25_ADCQ_CR_WMRK(x) ((x) << 8)
+#define MX25_ADCQ_CR_LITEMID_MASK (0xf << 4)
+#define MX25_ADCQ_CR_LITEMID(x) ((x) << 4)
+#define MX25_ADCQ_CR_RPT BIT(3)
+#define MX25_ADCQ_CR_FQS BIT(2)
+#define MX25_ADCQ_CR_QSM_MASK GENMASK(1, 0)
+#define MX25_ADCQ_CR_QSM_PD 0x1
+#define MX25_ADCQ_CR_QSM_FQS 0x2
+#define MX25_ADCQ_CR_QSM_FQS_PD 0x3
+
+/* ADCQ_SR (TCQSR and GCQSR) */
+#define MX25_ADCQ_SR_FDRY BIT(15)
+#define MX25_ADCQ_SR_FULL BIT(14)
+#define MX25_ADCQ_SR_EMPT BIT(13)
+#define MX25_ADCQ_SR_FDN(x) (((x) >> 8) & 0x1f)
+#define MX25_ADCQ_SR_FRR BIT(6)
+#define MX25_ADCQ_SR_FUR BIT(5)
+#define MX25_ADCQ_SR_FOR BIT(4)
+#define MX25_ADCQ_SR_EOQ BIT(1)
+#define MX25_ADCQ_SR_PD BIT(0)
+
+/* ADCQ_MR (TCQMR and GCQMR) */
+#define MX25_ADCQ_MR_FDRY_DMA BIT(31)
+#define MX25_ADCQ_MR_FER_DMA BIT(22)
+#define MX25_ADCQ_MR_FUR_DMA BIT(21)
+#define MX25_ADCQ_MR_FOR_DMA BIT(20)
+#define MX25_ADCQ_MR_EOQ_DMA BIT(17)
+#define MX25_ADCQ_MR_PD_DMA BIT(16)
+#define MX25_ADCQ_MR_FDRY_IRQ BIT(15)
+#define MX25_ADCQ_MR_FER_IRQ BIT(6)
+#define MX25_ADCQ_MR_FUR_IRQ BIT(5)
+#define MX25_ADCQ_MR_FOR_IRQ BIT(4)
+#define MX25_ADCQ_MR_EOQ_IRQ BIT(1)
+#define MX25_ADCQ_MR_PD_IRQ BIT(0)
+
+/* ADCQ_CFG (TICR, TCC0-7,GCC0-7) */
+#define MX25_ADCQ_CFG_SETTLING_TIME(x) ((x) << 24)
+#define MX25_ADCQ_CFG_IGS (1 << 20)
+#define MX25_ADCQ_CFG_NOS_MASK GENMASK(19, 16)
+#define MX25_ADCQ_CFG_NOS(x) (((x) - 1) << 16)
+#define MX25_ADCQ_CFG_WIPER (1 << 15)
+#define MX25_ADCQ_CFG_YNLR (1 << 14)
+#define MX25_ADCQ_CFG_YPLL_HIGH (0 << 12)
+#define MX25_ADCQ_CFG_YPLL_OFF (1 << 12)
+#define MX25_ADCQ_CFG_YPLL_LOW (3 << 12)
+#define MX25_ADCQ_CFG_XNUR_HIGH (0 << 10)
+#define MX25_ADCQ_CFG_XNUR_OFF (1 << 10)
+#define MX25_ADCQ_CFG_XNUR_LOW (3 << 10)
+#define MX25_ADCQ_CFG_XPUL_HIGH (0 << 9)
+#define MX25_ADCQ_CFG_XPUL_OFF (1 << 9)
+#define MX25_ADCQ_CFG_REFP(sel) ((sel) << 7)
+#define MX25_ADCQ_CFG_REFP_YP MX25_ADCQ_CFG_REFP(0)
+#define MX25_ADCQ_CFG_REFP_XP MX25_ADCQ_CFG_REFP(1)
+#define MX25_ADCQ_CFG_REFP_EXT MX25_ADCQ_CFG_REFP(2)
+#define MX25_ADCQ_CFG_REFP_INT MX25_ADCQ_CFG_REFP(3)
+#define MX25_ADCQ_CFG_REFP_MASK GENMASK(8, 7)
+#define MX25_ADCQ_CFG_IN(sel) ((sel) << 4)
+#define MX25_ADCQ_CFG_IN_XP MX25_ADCQ_CFG_IN(0)
+#define MX25_ADCQ_CFG_IN_YP MX25_ADCQ_CFG_IN(1)
+#define MX25_ADCQ_CFG_IN_XN MX25_ADCQ_CFG_IN(2)
+#define MX25_ADCQ_CFG_IN_YN MX25_ADCQ_CFG_IN(3)
+#define MX25_ADCQ_CFG_IN_WIPER MX25_ADCQ_CFG_IN(4)
+#define MX25_ADCQ_CFG_IN_AUX0 MX25_ADCQ_CFG_IN(5)
+#define MX25_ADCQ_CFG_IN_AUX1 MX25_ADCQ_CFG_IN(6)
+#define MX25_ADCQ_CFG_IN_AUX2 MX25_ADCQ_CFG_IN(7)
+#define MX25_ADCQ_CFG_REFN(sel) ((sel) << 2)
+#define MX25_ADCQ_CFG_REFN_XN MX25_ADCQ_CFG_REFN(0)
+#define MX25_ADCQ_CFG_REFN_YN MX25_ADCQ_CFG_REFN(1)
+#define MX25_ADCQ_CFG_REFN_NGND MX25_ADCQ_CFG_REFN(2)
+#define MX25_ADCQ_CFG_REFN_NGND2 MX25_ADCQ_CFG_REFN(3)
+#define MX25_ADCQ_CFG_REFN_MASK GENMASK(3, 2)
+#define MX25_ADCQ_CFG_PENIACK (1 << 1)
+
+#endif /* _LINUX_INCLUDE_MFD_IMX25_TSADC_H_ */
diff --git a/include/linux/mfd/mt6323/core.h b/include/linux/mfd/mt6323/core.h
new file mode 100644
index 000000000000..06d0ec3b1f8f
--- /dev/null
+++ b/include/linux/mfd/mt6323/core.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MFD_MT6323_CORE_H__
+#define __MFD_MT6323_CORE_H__
+
+enum MT6323_IRQ_STATUS_numbers {
+ MT6323_IRQ_STATUS_SPKL_AB = 0,
+ MT6323_IRQ_STATUS_SPKL,
+ MT6323_IRQ_STATUS_BAT_L,
+ MT6323_IRQ_STATUS_BAT_H,
+ MT6323_IRQ_STATUS_WATCHDOG,
+ MT6323_IRQ_STATUS_PWRKEY,
+ MT6323_IRQ_STATUS_THR_L,
+ MT6323_IRQ_STATUS_THR_H,
+ MT6323_IRQ_STATUS_VBATON_UNDET,
+ MT6323_IRQ_STATUS_BVALID_DET,
+ MT6323_IRQ_STATUS_CHRDET,
+ MT6323_IRQ_STATUS_OV,
+ MT6323_IRQ_STATUS_LDO = 16,
+ MT6323_IRQ_STATUS_FCHRKEY,
+ MT6323_IRQ_STATUS_ACCDET,
+ MT6323_IRQ_STATUS_AUDIO,
+ MT6323_IRQ_STATUS_RTC,
+ MT6323_IRQ_STATUS_VPROC,
+ MT6323_IRQ_STATUS_VSYS,
+ MT6323_IRQ_STATUS_VPA,
+ MT6323_IRQ_STATUS_NR,
+};
+
+#endif /* __MFD_MT6323_CORE_H__ */
diff --git a/include/linux/mfd/mt6323/registers.h b/include/linux/mfd/mt6323/registers.h
new file mode 100644
index 000000000000..160f3c0e2589
--- /dev/null
+++ b/include/linux/mfd/mt6323/registers.h
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MFD_MT6323_REGISTERS_H__
+#define __MFD_MT6323_REGISTERS_H__
+
+/* PMIC Registers */
+#define MT6323_CHR_CON0 0x0000
+#define MT6323_CHR_CON1 0x0002
+#define MT6323_CHR_CON2 0x0004
+#define MT6323_CHR_CON3 0x0006
+#define MT6323_CHR_CON4 0x0008
+#define MT6323_CHR_CON5 0x000A
+#define MT6323_CHR_CON6 0x000C
+#define MT6323_CHR_CON7 0x000E
+#define MT6323_CHR_CON8 0x0010
+#define MT6323_CHR_CON9 0x0012
+#define MT6323_CHR_CON10 0x0014
+#define MT6323_CHR_CON11 0x0016
+#define MT6323_CHR_CON12 0x0018
+#define MT6323_CHR_CON13 0x001A
+#define MT6323_CHR_CON14 0x001C
+#define MT6323_CHR_CON15 0x001E
+#define MT6323_CHR_CON16 0x0020
+#define MT6323_CHR_CON17 0x0022
+#define MT6323_CHR_CON18 0x0024
+#define MT6323_CHR_CON19 0x0026
+#define MT6323_CHR_CON20 0x0028
+#define MT6323_CHR_CON21 0x002A
+#define MT6323_CHR_CON22 0x002C
+#define MT6323_CHR_CON23 0x002E
+#define MT6323_CHR_CON24 0x0030
+#define MT6323_CHR_CON25 0x0032
+#define MT6323_CHR_CON26 0x0034
+#define MT6323_CHR_CON27 0x0036
+#define MT6323_CHR_CON28 0x0038
+#define MT6323_CHR_CON29 0x003A
+#define MT6323_STRUP_CON0 0x003C
+#define MT6323_STRUP_CON2 0x003E
+#define MT6323_STRUP_CON3 0x0040
+#define MT6323_STRUP_CON4 0x0042
+#define MT6323_STRUP_CON5 0x0044
+#define MT6323_STRUP_CON6 0x0046
+#define MT6323_STRUP_CON7 0x0048
+#define MT6323_STRUP_CON8 0x004A
+#define MT6323_STRUP_CON9 0x004C
+#define MT6323_STRUP_CON10 0x004E
+#define MT6323_STRUP_CON11 0x0050
+#define MT6323_SPK_CON0 0x0052
+#define MT6323_SPK_CON1 0x0054
+#define MT6323_SPK_CON2 0x0056
+#define MT6323_SPK_CON6 0x005E
+#define MT6323_SPK_CON7 0x0060
+#define MT6323_SPK_CON8 0x0062
+#define MT6323_SPK_CON9 0x0064
+#define MT6323_SPK_CON10 0x0066
+#define MT6323_SPK_CON11 0x0068
+#define MT6323_SPK_CON12 0x006A
+#define MT6323_CID 0x0100
+#define MT6323_TOP_CKPDN0 0x0102
+#define MT6323_TOP_CKPDN0_SET 0x0104
+#define MT6323_TOP_CKPDN0_CLR 0x0106
+#define MT6323_TOP_CKPDN1 0x0108
+#define MT6323_TOP_CKPDN1_SET 0x010A
+#define MT6323_TOP_CKPDN1_CLR 0x010C
+#define MT6323_TOP_CKPDN2 0x010E
+#define MT6323_TOP_CKPDN2_SET 0x0110
+#define MT6323_TOP_CKPDN2_CLR 0x0112
+#define MT6323_TOP_RST_CON 0x0114
+#define MT6323_TOP_RST_CON_SET 0x0116
+#define MT6323_TOP_RST_CON_CLR 0x0118
+#define MT6323_TOP_RST_MISC 0x011A
+#define MT6323_TOP_RST_MISC_SET 0x011C
+#define MT6323_TOP_RST_MISC_CLR 0x011E
+#define MT6323_TOP_CKCON0 0x0120
+#define MT6323_TOP_CKCON0_SET 0x0122
+#define MT6323_TOP_CKCON0_CLR 0x0124
+#define MT6323_TOP_CKCON1 0x0126
+#define MT6323_TOP_CKCON1_SET 0x0128
+#define MT6323_TOP_CKCON1_CLR 0x012A
+#define MT6323_TOP_CKTST0 0x012C
+#define MT6323_TOP_CKTST1 0x012E
+#define MT6323_TOP_CKTST2 0x0130
+#define MT6323_TEST_OUT 0x0132
+#define MT6323_TEST_CON0 0x0134
+#define MT6323_TEST_CON1 0x0136
+#define MT6323_EN_STATUS0 0x0138
+#define MT6323_EN_STATUS1 0x013A
+#define MT6323_OCSTATUS0 0x013C
+#define MT6323_OCSTATUS1 0x013E
+#define MT6323_PGSTATUS 0x0140
+#define MT6323_CHRSTATUS 0x0142
+#define MT6323_TDSEL_CON 0x0144
+#define MT6323_RDSEL_CON 0x0146
+#define MT6323_SMT_CON0 0x0148
+#define MT6323_SMT_CON1 0x014A
+#define MT6323_SMT_CON2 0x014C
+#define MT6323_SMT_CON3 0x014E
+#define MT6323_SMT_CON4 0x0150
+#define MT6323_DRV_CON0 0x0152
+#define MT6323_DRV_CON1 0x0154
+#define MT6323_DRV_CON2 0x0156
+#define MT6323_DRV_CON3 0x0158
+#define MT6323_DRV_CON4 0x015A
+#define MT6323_SIMLS1_CON 0x015C
+#define MT6323_SIMLS2_CON 0x015E
+#define MT6323_INT_CON0 0x0160
+#define MT6323_INT_CON0_SET 0x0162
+#define MT6323_INT_CON0_CLR 0x0164
+#define MT6323_INT_CON1 0x0166
+#define MT6323_INT_CON1_SET 0x0168
+#define MT6323_INT_CON1_CLR 0x016A
+#define MT6323_INT_MISC_CON 0x016C
+#define MT6323_INT_MISC_CON_SET 0x016E
+#define MT6323_INT_MISC_CON_CLR 0x0170
+#define MT6323_INT_STATUS0 0x0172
+#define MT6323_INT_STATUS1 0x0174
+#define MT6323_OC_GEAR_0 0x0176
+#define MT6323_OC_GEAR_1 0x0178
+#define MT6323_OC_GEAR_2 0x017A
+#define MT6323_OC_CTL_VPROC 0x017C
+#define MT6323_OC_CTL_VSYS 0x017E
+#define MT6323_OC_CTL_VPA 0x0180
+#define MT6323_FQMTR_CON0 0x0182
+#define MT6323_FQMTR_CON1 0x0184
+#define MT6323_FQMTR_CON2 0x0186
+#define MT6323_RG_SPI_CON 0x0188
+#define MT6323_DEW_DIO_EN 0x018A
+#define MT6323_DEW_READ_TEST 0x018C
+#define MT6323_DEW_WRITE_TEST 0x018E
+#define MT6323_DEW_CRC_SWRST 0x0190
+#define MT6323_DEW_CRC_EN 0x0192
+#define MT6323_DEW_CRC_VAL 0x0194
+#define MT6323_DEW_DBG_MON_SEL 0x0196
+#define MT6323_DEW_CIPHER_KEY_SEL 0x0198
+#define MT6323_DEW_CIPHER_IV_SEL 0x019A
+#define MT6323_DEW_CIPHER_EN 0x019C
+#define MT6323_DEW_CIPHER_RDY 0x019E
+#define MT6323_DEW_CIPHER_MODE 0x01A0
+#define MT6323_DEW_CIPHER_SWRST 0x01A2
+#define MT6323_DEW_RDDMY_NO 0x01A4
+#define MT6323_DEW_RDATA_DLY_SEL 0x01A6
+#define MT6323_BUCK_CON0 0x0200
+#define MT6323_BUCK_CON1 0x0202
+#define MT6323_BUCK_CON2 0x0204
+#define MT6323_BUCK_CON3 0x0206
+#define MT6323_BUCK_CON4 0x0208
+#define MT6323_BUCK_CON5 0x020A
+#define MT6323_VPROC_CON0 0x020C
+#define MT6323_VPROC_CON1 0x020E
+#define MT6323_VPROC_CON2 0x0210
+#define MT6323_VPROC_CON3 0x0212
+#define MT6323_VPROC_CON4 0x0214
+#define MT6323_VPROC_CON5 0x0216
+#define MT6323_VPROC_CON7 0x021A
+#define MT6323_VPROC_CON8 0x021C
+#define MT6323_VPROC_CON9 0x021E
+#define MT6323_VPROC_CON10 0x0220
+#define MT6323_VPROC_CON11 0x0222
+#define MT6323_VPROC_CON12 0x0224
+#define MT6323_VPROC_CON13 0x0226
+#define MT6323_VPROC_CON14 0x0228
+#define MT6323_VPROC_CON15 0x022A
+#define MT6323_VPROC_CON18 0x0230
+#define MT6323_VSYS_CON0 0x0232
+#define MT6323_VSYS_CON1 0x0234
+#define MT6323_VSYS_CON2 0x0236
+#define MT6323_VSYS_CON3 0x0238
+#define MT6323_VSYS_CON4 0x023A
+#define MT6323_VSYS_CON5 0x023C
+#define MT6323_VSYS_CON7 0x0240
+#define MT6323_VSYS_CON8 0x0242
+#define MT6323_VSYS_CON9 0x0244
+#define MT6323_VSYS_CON10 0x0246
+#define MT6323_VSYS_CON11 0x0248
+#define MT6323_VSYS_CON12 0x024A
+#define MT6323_VSYS_CON13 0x024C
+#define MT6323_VSYS_CON14 0x024E
+#define MT6323_VSYS_CON15 0x0250
+#define MT6323_VSYS_CON18 0x0256
+#define MT6323_VPA_CON0 0x0300
+#define MT6323_VPA_CON1 0x0302
+#define MT6323_VPA_CON2 0x0304
+#define MT6323_VPA_CON3 0x0306
+#define MT6323_VPA_CON4 0x0308
+#define MT6323_VPA_CON5 0x030A
+#define MT6323_VPA_CON7 0x030E
+#define MT6323_VPA_CON8 0x0310
+#define MT6323_VPA_CON9 0x0312
+#define MT6323_VPA_CON10 0x0314
+#define MT6323_VPA_CON11 0x0316
+#define MT6323_VPA_CON12 0x0318
+#define MT6323_VPA_CON14 0x031C
+#define MT6323_VPA_CON16 0x0320
+#define MT6323_VPA_CON17 0x0322
+#define MT6323_VPA_CON18 0x0324
+#define MT6323_VPA_CON19 0x0326
+#define MT6323_VPA_CON20 0x0328
+#define MT6323_BUCK_K_CON0 0x032A
+#define MT6323_BUCK_K_CON1 0x032C
+#define MT6323_BUCK_K_CON2 0x032E
+#define MT6323_ISINK0_CON0 0x0330
+#define MT6323_ISINK0_CON1 0x0332
+#define MT6323_ISINK0_CON2 0x0334
+#define MT6323_ISINK0_CON3 0x0336
+#define MT6323_ISINK1_CON0 0x0338
+#define MT6323_ISINK1_CON1 0x033A
+#define MT6323_ISINK1_CON2 0x033C
+#define MT6323_ISINK1_CON3 0x033E
+#define MT6323_ISINK2_CON0 0x0340
+#define MT6323_ISINK2_CON1 0x0342
+#define MT6323_ISINK2_CON2 0x0344
+#define MT6323_ISINK2_CON3 0x0346
+#define MT6323_ISINK3_CON0 0x0348
+#define MT6323_ISINK3_CON1 0x034A
+#define MT6323_ISINK3_CON2 0x034C
+#define MT6323_ISINK3_CON3 0x034E
+#define MT6323_ISINK_ANA0 0x0350
+#define MT6323_ISINK_ANA1 0x0352
+#define MT6323_ISINK_PHASE_DLY 0x0354
+#define MT6323_ISINK_EN_CTRL 0x0356
+#define MT6323_ANALDO_CON0 0x0400
+#define MT6323_ANALDO_CON1 0x0402
+#define MT6323_ANALDO_CON2 0x0404
+#define MT6323_ANALDO_CON3 0x0406
+#define MT6323_ANALDO_CON4 0x0408
+#define MT6323_ANALDO_CON5 0x040A
+#define MT6323_ANALDO_CON6 0x040C
+#define MT6323_ANALDO_CON7 0x040E
+#define MT6323_ANALDO_CON8 0x0410
+#define MT6323_ANALDO_CON10 0x0412
+#define MT6323_ANALDO_CON15 0x0414
+#define MT6323_ANALDO_CON16 0x0416
+#define MT6323_ANALDO_CON17 0x0418
+#define MT6323_ANALDO_CON18 0x041A
+#define MT6323_ANALDO_CON19 0x041C
+#define MT6323_ANALDO_CON20 0x041E
+#define MT6323_ANALDO_CON21 0x0420
+#define MT6323_DIGLDO_CON0 0x0500
+#define MT6323_DIGLDO_CON2 0x0502
+#define MT6323_DIGLDO_CON3 0x0504
+#define MT6323_DIGLDO_CON5 0x0506
+#define MT6323_DIGLDO_CON6 0x0508
+#define MT6323_DIGLDO_CON7 0x050A
+#define MT6323_DIGLDO_CON8 0x050C
+#define MT6323_DIGLDO_CON9 0x050E
+#define MT6323_DIGLDO_CON10 0x0510
+#define MT6323_DIGLDO_CON11 0x0512
+#define MT6323_DIGLDO_CON12 0x0514
+#define MT6323_DIGLDO_CON13 0x0516
+#define MT6323_DIGLDO_CON14 0x0518
+#define MT6323_DIGLDO_CON15 0x051A
+#define MT6323_DIGLDO_CON16 0x051C
+#define MT6323_DIGLDO_CON17 0x051E
+#define MT6323_DIGLDO_CON18 0x0520
+#define MT6323_DIGLDO_CON19 0x0522
+#define MT6323_DIGLDO_CON20 0x0524
+#define MT6323_DIGLDO_CON21 0x0526
+#define MT6323_DIGLDO_CON23 0x0528
+#define MT6323_DIGLDO_CON24 0x052A
+#define MT6323_DIGLDO_CON26 0x052C
+#define MT6323_DIGLDO_CON27 0x052E
+#define MT6323_DIGLDO_CON28 0x0530
+#define MT6323_DIGLDO_CON29 0x0532
+#define MT6323_DIGLDO_CON30 0x0534
+#define MT6323_DIGLDO_CON31 0x0536
+#define MT6323_DIGLDO_CON32 0x0538
+#define MT6323_DIGLDO_CON33 0x053A
+#define MT6323_DIGLDO_CON34 0x053C
+#define MT6323_DIGLDO_CON35 0x053E
+#define MT6323_DIGLDO_CON36 0x0540
+#define MT6323_DIGLDO_CON39 0x0542
+#define MT6323_DIGLDO_CON40 0x0544
+#define MT6323_DIGLDO_CON41 0x0546
+#define MT6323_DIGLDO_CON42 0x0548
+#define MT6323_DIGLDO_CON43 0x054A
+#define MT6323_DIGLDO_CON44 0x054C
+#define MT6323_DIGLDO_CON45 0x054E
+#define MT6323_DIGLDO_CON46 0x0550
+#define MT6323_DIGLDO_CON47 0x0552
+#define MT6323_DIGLDO_CON48 0x0554
+#define MT6323_DIGLDO_CON49 0x0556
+#define MT6323_DIGLDO_CON50 0x0558
+#define MT6323_DIGLDO_CON51 0x055A
+#define MT6323_DIGLDO_CON52 0x055C
+#define MT6323_DIGLDO_CON53 0x055E
+#define MT6323_DIGLDO_CON54 0x0560
+#define MT6323_EFUSE_CON0 0x0600
+#define MT6323_EFUSE_CON1 0x0602
+#define MT6323_EFUSE_CON2 0x0604
+#define MT6323_EFUSE_CON3 0x0606
+#define MT6323_EFUSE_CON4 0x0608
+#define MT6323_EFUSE_CON5 0x060A
+#define MT6323_EFUSE_CON6 0x060C
+#define MT6323_EFUSE_VAL_0_15 0x060E
+#define MT6323_EFUSE_VAL_16_31 0x0610
+#define MT6323_EFUSE_VAL_32_47 0x0612
+#define MT6323_EFUSE_VAL_48_63 0x0614
+#define MT6323_EFUSE_VAL_64_79 0x0616
+#define MT6323_EFUSE_VAL_80_95 0x0618
+#define MT6323_EFUSE_VAL_96_111 0x061A
+#define MT6323_EFUSE_VAL_112_127 0x061C
+#define MT6323_EFUSE_VAL_128_143 0x061E
+#define MT6323_EFUSE_VAL_144_159 0x0620
+#define MT6323_EFUSE_VAL_160_175 0x0622
+#define MT6323_EFUSE_VAL_176_191 0x0624
+#define MT6323_EFUSE_DOUT_0_15 0x0626
+#define MT6323_EFUSE_DOUT_16_31 0x0628
+#define MT6323_EFUSE_DOUT_32_47 0x062A
+#define MT6323_EFUSE_DOUT_48_63 0x062C
+#define MT6323_EFUSE_DOUT_64_79 0x062E
+#define MT6323_EFUSE_DOUT_80_95 0x0630
+#define MT6323_EFUSE_DOUT_96_111 0x0632
+#define MT6323_EFUSE_DOUT_112_127 0x0634
+#define MT6323_EFUSE_DOUT_128_143 0x0636
+#define MT6323_EFUSE_DOUT_144_159 0x0638
+#define MT6323_EFUSE_DOUT_160_175 0x063A
+#define MT6323_EFUSE_DOUT_176_191 0x063C
+#define MT6323_EFUSE_CON7 0x063E
+#define MT6323_EFUSE_CON8 0x0640
+#define MT6323_EFUSE_CON9 0x0642
+#define MT6323_RTC_MIX_CON0 0x0644
+#define MT6323_RTC_MIX_CON1 0x0646
+#define MT6323_AUDTOP_CON0 0x0700
+#define MT6323_AUDTOP_CON1 0x0702
+#define MT6323_AUDTOP_CON2 0x0704
+#define MT6323_AUDTOP_CON3 0x0706
+#define MT6323_AUDTOP_CON4 0x0708
+#define MT6323_AUDTOP_CON5 0x070A
+#define MT6323_AUDTOP_CON6 0x070C
+#define MT6323_AUDTOP_CON7 0x070E
+#define MT6323_AUDTOP_CON8 0x0710
+#define MT6323_AUDTOP_CON9 0x0712
+#define MT6323_AUXADC_ADC0 0x0714
+#define MT6323_AUXADC_ADC1 0x0716
+#define MT6323_AUXADC_ADC2 0x0718
+#define MT6323_AUXADC_ADC3 0x071A
+#define MT6323_AUXADC_ADC4 0x071C
+#define MT6323_AUXADC_ADC5 0x071E
+#define MT6323_AUXADC_ADC6 0x0720
+#define MT6323_AUXADC_ADC7 0x0722
+#define MT6323_AUXADC_ADC8 0x0724
+#define MT6323_AUXADC_ADC9 0x0726
+#define MT6323_AUXADC_ADC10 0x0728
+#define MT6323_AUXADC_ADC11 0x072A
+#define MT6323_AUXADC_ADC12 0x072C
+#define MT6323_AUXADC_ADC13 0x072E
+#define MT6323_AUXADC_ADC14 0x0730
+#define MT6323_AUXADC_ADC15 0x0732
+#define MT6323_AUXADC_ADC16 0x0734
+#define MT6323_AUXADC_ADC17 0x0736
+#define MT6323_AUXADC_ADC18 0x0738
+#define MT6323_AUXADC_ADC19 0x073A
+#define MT6323_AUXADC_ADC20 0x073C
+#define MT6323_AUXADC_RSV1 0x073E
+#define MT6323_AUXADC_RSV2 0x0740
+#define MT6323_AUXADC_CON0 0x0742
+#define MT6323_AUXADC_CON1 0x0744
+#define MT6323_AUXADC_CON2 0x0746
+#define MT6323_AUXADC_CON3 0x0748
+#define MT6323_AUXADC_CON4 0x074A
+#define MT6323_AUXADC_CON5 0x074C
+#define MT6323_AUXADC_CON6 0x074E
+#define MT6323_AUXADC_CON7 0x0750
+#define MT6323_AUXADC_CON8 0x0752
+#define MT6323_AUXADC_CON9 0x0754
+#define MT6323_AUXADC_CON10 0x0756
+#define MT6323_AUXADC_CON11 0x0758
+#define MT6323_AUXADC_CON12 0x075A
+#define MT6323_AUXADC_CON13 0x075C
+#define MT6323_AUXADC_CON14 0x075E
+#define MT6323_AUXADC_CON15 0x0760
+#define MT6323_AUXADC_CON16 0x0762
+#define MT6323_AUXADC_CON17 0x0764
+#define MT6323_AUXADC_CON18 0x0766
+#define MT6323_AUXADC_CON19 0x0768
+#define MT6323_AUXADC_CON20 0x076A
+#define MT6323_AUXADC_CON21 0x076C
+#define MT6323_AUXADC_CON22 0x076E
+#define MT6323_AUXADC_CON23 0x0770
+#define MT6323_AUXADC_CON24 0x0772
+#define MT6323_AUXADC_CON25 0x0774
+#define MT6323_AUXADC_CON26 0x0776
+#define MT6323_AUXADC_CON27 0x0778
+#define MT6323_ACCDET_CON0 0x077A
+#define MT6323_ACCDET_CON1 0x077C
+#define MT6323_ACCDET_CON2 0x077E
+#define MT6323_ACCDET_CON3 0x0780
+#define MT6323_ACCDET_CON4 0x0782
+#define MT6323_ACCDET_CON5 0x0784
+#define MT6323_ACCDET_CON6 0x0786
+#define MT6323_ACCDET_CON7 0x0788
+#define MT6323_ACCDET_CON8 0x078A
+#define MT6323_ACCDET_CON9 0x078C
+#define MT6323_ACCDET_CON10 0x078E
+#define MT6323_ACCDET_CON11 0x0790
+#define MT6323_ACCDET_CON12 0x0792
+#define MT6323_ACCDET_CON13 0x0794
+#define MT6323_ACCDET_CON14 0x0796
+#define MT6323_ACCDET_CON15 0x0798
+#define MT6323_ACCDET_CON16 0x079A
+
+#endif /* __MFD_MT6323_REGISTERS_H__ */
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index 45b8e8aa1fbf..d678f526e498 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -60,6 +60,8 @@ struct mt6397_chip {
u16 wake_mask[2];
u16 irq_masks_cur[2];
u16 irq_masks_cache[2];
+ u16 int_con[2];
+ u16 int_status[2];
};
#endif /* __MFD_MT6397_CORE_H__ */
diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h
index fd413ccab915..8d0a392e0a7f 100644
--- a/include/linux/mfd/rc5t583.h
+++ b/include/linux/mfd/rc5t583.h
@@ -28,8 +28,6 @@
#include <linux/types.h>
#include <linux/regmap.h>
-#define RC5T583_MAX_REGS 0xF8
-
/* Maximum number of main interrupts */
#define MAX_MAIN_INTERRUPT 5
#define RC5T583_MAX_GPEDGE_REG 2
@@ -169,6 +167,9 @@
#define RC5T583_RTC_AY_MONTH 0xF3
#define RC5T583_RTC_AY_YEAR 0xF4
+#define RC5T583_MAX_REG 0xF7
+#define RC5T583_NUM_REGS (RC5T583_MAX_REG + 1)
+
/* RICOH_RC5T583 IRQ definitions */
enum {
RC5T583_IRQ_ONKEY,
diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
index 75e543b78f53..1088149be0c9 100644
--- a/include/linux/mfd/syscon.h
+++ b/include/linux/mfd/syscon.h
@@ -29,24 +29,24 @@ extern struct regmap *syscon_regmap_lookup_by_phandle(
#else
static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
{
- return ERR_PTR(-ENOSYS);
+ return ERR_PTR(-ENOTSUPP);
}
static inline struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
{
- return ERR_PTR(-ENOSYS);
+ return ERR_PTR(-ENOTSUPP);
}
static inline struct regmap *syscon_regmap_lookup_by_pdevname(const char *s)
{
- return ERR_PTR(-ENOSYS);
+ return ERR_PTR(-ENOTSUPP);
}
static inline struct regmap *syscon_regmap_lookup_by_phandle(
struct device_node *np,
const char *property)
{
- return ERR_PTR(-ENOSYS);
+ return ERR_PTR(-ENOTSUPP);
}
#endif
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
index 558a485d03ab..238c8db953eb 100644
--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -422,6 +422,7 @@
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_MASK (0x1 << 26)
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_ENABLE (0x1 << 26)
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_DISABLE (0x0 << 26)
+#define IMX6SX_GPR5_PCIE_BTNRST_RESET BIT(19)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_MASK (0x3 << 4)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_EXT_PIN (0x0 << 4)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_CVD (0x1 << 4)
@@ -435,6 +436,10 @@
#define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS (0x1 << 1)
#define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1)
+#define IMX6SX_GPR12_PCIE_TEST_POWERDOWN BIT(30)
+#define IMX6SX_GPR12_PCIE_RX_EQ_MASK (0x7 << 0)
+#define IMX6SX_GPR12_PCIE_RX_EQ_2 (0x2 << 0)
+
/* For imx6ul iomux gpr register field define */
#define IMX6UL_GPR1_ENET1_CLK_DIR (0x1 << 17)
#define IMX6UL_GPR1_ENET2_CLK_DIR (0x1 << 18)
diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h
new file mode 100644
index 000000000000..a228ae4c88d9
--- /dev/null
+++ b/include/linux/mfd/tps65086.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65912 driver
+ */
+
+#ifndef __LINUX_MFD_TPS65086_H
+#define __LINUX_MFD_TPS65086_H
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+/* List of registers for TPS65086 */
+#define TPS65086_DEVICEID 0x01
+#define TPS65086_IRQ 0x02
+#define TPS65086_IRQ_MASK 0x03
+#define TPS65086_PMICSTAT 0x04
+#define TPS65086_SHUTDNSRC 0x05
+#define TPS65086_BUCK1CTRL 0x20
+#define TPS65086_BUCK2CTRL 0x21
+#define TPS65086_BUCK3DECAY 0x22
+#define TPS65086_BUCK3VID 0x23
+#define TPS65086_BUCK3SLPCTRL 0x24
+#define TPS65086_BUCK4CTRL 0x25
+#define TPS65086_BUCK5CTRL 0x26
+#define TPS65086_BUCK6CTRL 0x27
+#define TPS65086_LDOA2CTRL 0x28
+#define TPS65086_LDOA3CTRL 0x29
+#define TPS65086_DISCHCTRL1 0x40
+#define TPS65086_DISCHCTRL2 0x41
+#define TPS65086_DISCHCTRL3 0x42
+#define TPS65086_PG_DELAY1 0x43
+#define TPS65086_FORCESHUTDN 0x91
+#define TPS65086_BUCK1SLPCTRL 0x92
+#define TPS65086_BUCK2SLPCTRL 0x93
+#define TPS65086_BUCK4VID 0x94
+#define TPS65086_BUCK4SLPVID 0x95
+#define TPS65086_BUCK5VID 0x96
+#define TPS65086_BUCK5SLPVID 0x97
+#define TPS65086_BUCK6VID 0x98
+#define TPS65086_BUCK6SLPVID 0x99
+#define TPS65086_LDOA2VID 0x9A
+#define TPS65086_LDOA3VID 0x9B
+#define TPS65086_BUCK123CTRL 0x9C
+#define TPS65086_PG_DELAY2 0x9D
+#define TPS65086_PIN_EN_MASK1 0x9E
+#define TPS65086_PIN_EN_MASK2 0x9F
+#define TPS65086_SWVTT_EN 0x9F
+#define TPS65086_PIN_EN_OVR1 0xA0
+#define TPS65086_PIN_EN_OVR2 0xA1
+#define TPS65086_GPOCTRL 0xA1
+#define TPS65086_PWR_FAULT_MASK1 0xA2
+#define TPS65086_PWR_FAULT_MASK2 0xA3
+#define TPS65086_GPO1PG_CTRL1 0xA4
+#define TPS65086_GPO1PG_CTRL2 0xA5
+#define TPS65086_GPO4PG_CTRL1 0xA6
+#define TPS65086_GPO4PG_CTRL2 0xA7
+#define TPS65086_GPO2PG_CTRL1 0xA8
+#define TPS65086_GPO2PG_CTRL2 0xA9
+#define TPS65086_GPO3PG_CTRL1 0xAA
+#define TPS65086_GPO3PG_CTRL2 0xAB
+#define TPS65086_LDOA1CTRL 0xAE
+#define TPS65086_PG_STATUS1 0xB0
+#define TPS65086_PG_STATUS2 0xB1
+#define TPS65086_PWR_FAULT_STATUS1 0xB2
+#define TPS65086_PWR_FAULT_STATUS2 0xB3
+#define TPS65086_TEMPCRIT 0xB4
+#define TPS65086_TEMPHOT 0xB5
+#define TPS65086_OC_STATUS 0xB6
+
+/* IRQ Register field definitions */
+#define TPS65086_IRQ_DIETEMP_MASK BIT(0)
+#define TPS65086_IRQ_SHUTDN_MASK BIT(3)
+#define TPS65086_IRQ_FAULT_MASK BIT(7)
+
+/* DEVICEID Register field definitions */
+#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0)
+#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4)
+#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6)
+
+/* VID Masks */
+#define BUCK_VID_MASK GENMASK(7, 1)
+#define VDOA1_VID_MASK GENMASK(4, 1)
+#define VDOA23_VID_MASK GENMASK(3, 0)
+
+/* Define the TPS65086 IRQ numbers */
+enum tps65086_irqs {
+ TPS65086_IRQ_DIETEMP,
+ TPS65086_IRQ_SHUTDN,
+ TPS65086_IRQ_FAULT,
+};
+
+/**
+ * struct tps65086 - state holder for the tps65086 driver
+ *
+ * Device data may be used to access the TPS65086 chip
+ */
+struct tps65086 {
+ struct device *dev;
+ struct regmap *regmap;
+
+ /* IRQ Data */
+ int irq;
+ struct regmap_irq_chip_data *irq_data;
+};
+
+#endif /* __LINUX_MFD_TPS65086_H */
diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h
index 0bf2708df150..67d144b3b8f9 100644
--- a/include/linux/mfd/tps65090.h
+++ b/include/linux/mfd/tps65090.h
@@ -77,6 +77,11 @@ enum {
#define TPS65090_REG_CG_CTRL5 0x09
#define TPS65090_REG_CG_STATUS1 0x0a
#define TPS65090_REG_CG_STATUS2 0x0b
+#define TPS65090_REG_AD_OUT1 0x17
+#define TPS65090_REG_AD_OUT2 0x18
+
+#define TPS65090_MAX_REG TPS65090_REG_AD_OUT2
+#define TPS65090_NUM_REGS (TPS65090_MAX_REG + 1)
struct tps65090 {
struct device *dev;