Merge tag 'mfd-3.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 16 Nov 2013 00:37:40 +0000 (16:37 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 16 Nov 2013 00:37:40 +0000 (16:37 -0800)
Pull MFD updates from Samuel Ortiz:
 "For the 3.13 merge window we have a couple of new drivers for the AMS
  AS3722 PMIC and for STMicroelectronics STw481x PMIC.

  Although this is a smaller update than usual, we also have:

   - Device tree support for the max77693 driver

   - linux/of.h inclusion for all DT compatible MFD drivers, to avoid
     build breakage in the future

   - Support for Intel Wildcat Point-LP PCH through the lpc_ich driver

   - A small arizona update for new wm5110 DSP registers and a few fixes

   - A small palmas update as well, including an of_device table
     addition and a few minor fixes

   - Two small mfd-core changes, one including a memory leak fix for
     when mfd_add_device() fails

   - Our usual round of minor cleanups and janitorial fixes"

* tag 'mfd-3.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next: (63 commits)
  Documentation: mfd: Update s2mps11.txt
  mfd: pm8921: Potential NULL dereference in pm8921_remove()
  mfd: Fix memory leak in mfd_add_devices()
  mfd: Stop setting refcounting pointers in original mfd_cell arrays
  mfd: wm5110: Enable micd clamp functionality
  mfd: lpc_ich: Add Device IDs for Intel Wildcat Point-LP PCH
  mfd: max77693: Fix up bug of wrong interrupt number
  mfd: as3722: Don't export the regmap config
  mfd: twl6040: Remove obsolete cleanup for i2c clientdata
  mfd: tps65910: Remove warning during dt node parsing
  mfd: lpc_sch: Ignore resource conflicts when adding mfd cells
  mfd: ti_am335x_tscadc: Avoid possible deadlock of reg_lock
  mfd: syscon: Return -ENOSYS if CONFIG_MFD_SYSCON is not enabled
  mfd: Add support for ams AS3722 PMIC
  mfd: max77693: Include linux/of.h header
  mfd: tc3589x: Detect the precise version
  mfd: omap-usb: prepare/unprepare clock while enable/disable
  mfd: max77686: Include linux/of.h header
  mfd: max8907: Include linux/of.h header
  mfd: max8997: Include linux/of.h header
  ...

57 files changed:
Documentation/devicetree/bindings/mfd/as3722.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/s2mps11.txt
drivers/mfd/88pm860x-core.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/aat2870-core.c
drivers/mfd/arizona-core.c
drivers/mfd/arizona-i2c.c
drivers/mfd/arizona-spi.c
drivers/mfd/as3711.c
drivers/mfd/as3722.c [new file with mode: 0644]
drivers/mfd/da9052-i2c.c
drivers/mfd/ezx-pcap.c
drivers/mfd/lpc_ich.c
drivers/mfd/lpc_sch.c
drivers/mfd/max77686.c
drivers/mfd/max77693-irq.c
drivers/mfd/max77693.c
drivers/mfd/max8907.c
drivers/mfd/max8925-i2c.c
drivers/mfd/max8997.c
drivers/mfd/mc13xxx-i2c.c
drivers/mfd/mfd-core.c
drivers/mfd/omap-usb-host.c
drivers/mfd/omap-usb-tll.c
drivers/mfd/palmas.c
drivers/mfd/pm8921-core.c
drivers/mfd/rts5249.c
drivers/mfd/rtsx_pcr.c
drivers/mfd/sec-core.c
drivers/mfd/sm501.c
drivers/mfd/stw481x.c [new file with mode: 0644]
drivers/mfd/tc3589x.c
drivers/mfd/ti-ssp.c
drivers/mfd/ti_am335x_tscadc.c
drivers/mfd/timberdale.c
drivers/mfd/tps6507x.c
drivers/mfd/tps65217.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65910.c
drivers/mfd/twl6040.c
drivers/mfd/ucb1x00-core.c
drivers/mfd/wm5102-tables.c
drivers/mfd/wm5110-tables.c
drivers/mfd/wm8994-core.c
include/dt-bindings/mfd/as3722.h [new file with mode: 0644]
include/linux/mfd/arizona/registers.h
include/linux/mfd/as3722.h [new file with mode: 0644]
include/linux/mfd/core.h
include/linux/mfd/da9052/da9052.h
include/linux/mfd/max77693-private.h
include/linux/mfd/max77693.h
include/linux/mfd/rtsx_pci.h
include/linux/mfd/stw481x.h [new file with mode: 0644]
include/linux/mfd/syscon.h
include/linux/mfd/ti_am335x_tscadc.h
include/linux/mfd/wm8994/core.h

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