]> Pileus Git - ~andy/linux/commitdiff
Merge tag 'mfd-3.14-1' of git://git.linaro.org/people/ljones/mfd
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 21 Jan 2014 18:58:17 +0000 (10:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 21 Jan 2014 18:58:17 +0000 (10:58 -0800)
Pull MFD changes from Lee Jones:
 "New drivers
   - Samsung Maxim 14577; Micro USB, Regulator, IRQ Controller and
     Battery Charger
   - TI/National Semiconductor LP3943 I2C GPIO Expander and PWM
     Generator

  Existing driver adaptions
   - Expansion of Wolfson Arizona DSP and High-Pass filter controls
   - TI TWL6040 default Regmap support and Regcache addition/bypass
   - Some nice Smatch catch fixes
   - Conversion of TI OMAP-USB and TI TWL6030 to endian neutralness
   - ChromeOS EC timing (delay) adaptions and added dependency on OF
   - Many constifications of 'struct {mfd_cell,regmap_irq,et.al}'
   - Watchdog support added for NVIDIA AS3722
   - Convert functions to static in TI AM335x
   - Realigned previously defeated functionality in TI AM335x
   - IIO ADC-TSC concurrency dead-lock/timeout resolution
   - Addition of Power Management and Clock support for Samsung core
   - DEFINE_PCI_DEVICE_TABLE macro removal from MFD Subsystem
   - Greater use of irqdomain functionality in ST-E AB8500
   - Removal of 'include/linux/mfd/abx500/ab8500-gpio.h'
   - Wolfson WM831x PMIC Power Management changes s/poweroff/shutdown/
   - Device Tree documentation added for TI/Nat Semi LP3943
   - Version detection and voltage tables for TI TPS6586x PMIC devices
   - Simplification of Freescale MC13XXX (de-)initialisation routines
   - Clean-up and simplification of the Realtek parent driver
   - Added support for RTL8402 Realtek PCI-Express card reader
   - Resource leak fix for Maxim 77686
   - Possible suspend BUG() fix in OMAP USB TLL
   - Support for new Wolfson WM5110 Revision (D)
   - Testing of automatic assignment of of_node in mfd_add_device()
   - Reversion of the above when it started to cause issues
   - Remove legacy Platform Data from;
              TI TWL Core, Qualcomm SSBI and ST-E ABx500 Pinctrl
   - Clean-ups; tabbing issues, function name changes, 'drvdata = NULL'
              removal, unused uninitialised warning mitigation, error
              message clarity, removal of redundant/duplicate checks,
              licensing (GPL -> GPL2), coding consistency, duplicate
              function declaration, ret checks, commit corrections,
              redundant of_match_ptr() helper removal, spelling,
              #if-deffery removal and header guards name changes"

* tag 'mfd-3.14-1' of git://git.linaro.org/people/ljones/mfd: (78 commits)
  mfd: wm5110: Add register patch for rev D chip
  mfd: omap-usb-tll: Don't hold lock during pm_runtime_get/put_sync()
  gpio: lp3943: Remove redundant of_match_ptr helper
  mfd: sta2x11-mfd: Use named constants for pci_power_t values
  Documentation: mfd: Fix LDO index in s2mps11.txt
  mfd: Cleanup mfd-mcp-sa11x0.h header
  mfd: max8997: Use "IS_ENABLED(CONFIG_OF)" for DT code.
  mfd: twl6030: Fix endianness problem in IRQ handler
  mfd: sec-core: Add cells for S5M8767-clocks
  mfd: max14577: Remove redundant of_match_ptr helper
  mfd: twl6040: Fix sparse non static symbol warning
  mfd: Revert "mfd: Always assign of_node in mfd_add_device()"
  mfd: rtsx: Fix sparse non static symbol warning
  mfd: max77693: Set proper maximum register for MUIC regmap
  mfd: max77686: Fix regmap resource leak on driver remove
  mfd: Represent correct filenames in file headers
  mfd: rtsx: Add support for card reader rtl8402
  mfd: rtsx: Add set pull control macro and simplify rtl8411
  mfd: max8997: Enforce mfd_add_devices() return value check
  mfd: mc13xxx: Simplify probe() & remove()
  ...

106 files changed:
Documentation/devicetree/bindings/gpio/gpio-lp3943.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/cros-ec.txt
Documentation/devicetree/bindings/mfd/lp3943.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/s2mps11.txt
Documentation/devicetree/bindings/pwm/pwm-lp3943.txt [new file with mode: 0644]
arch/arm/boot/dts/tegra20-colibri-512.dtsi
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-lp3943.c [new file with mode: 0644]
drivers/iio/adc/ti_am335x_adc.c
drivers/input/misc/Kconfig
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/mfd/88pm800.c
drivers/mfd/88pm805.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ab8500-core.c
drivers/mfd/ab8500-debugfs.c
drivers/mfd/arizona-core.c
drivers/mfd/as3722.c
drivers/mfd/asic3.c
drivers/mfd/cros_ec.c
drivers/mfd/cros_ec_i2c.c
drivers/mfd/cros_ec_spi.c
drivers/mfd/cs5535-mfd.c
drivers/mfd/da9052-core.c
drivers/mfd/da9055-core.c
drivers/mfd/da9063-core.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/htc-pasic3.c
drivers/mfd/intel_msic.c
drivers/mfd/janz-cmodio.c
drivers/mfd/jz4740-adc.c
drivers/mfd/lp3943.c [new file with mode: 0644]
drivers/mfd/lp8788.c
drivers/mfd/lpc_ich.c
drivers/mfd/lpc_sch.c
drivers/mfd/max14577.c [new file with mode: 0644]
drivers/mfd/max77686.c
drivers/mfd/max77693.c
drivers/mfd/max8907.c
drivers/mfd/max8925-core.c
drivers/mfd/max8997.c
drivers/mfd/max8998.c
drivers/mfd/mc13xxx-core.c
drivers/mfd/mc13xxx-i2c.c
drivers/mfd/mc13xxx-spi.c
drivers/mfd/mc13xxx.h
drivers/mfd/omap-usb-host.c
drivers/mfd/omap-usb-tll.c
drivers/mfd/rc5t583.c
drivers/mfd/rdc321x-southbridge.c
drivers/mfd/retu-mfd.c
drivers/mfd/rtl8411.c
drivers/mfd/rtsx_pcr.c
drivers/mfd/rtsx_pcr.h
drivers/mfd/sec-core.c
drivers/mfd/sec-irq.c
drivers/mfd/sm501.c
drivers/mfd/ssbi.c
drivers/mfd/sta2x11-mfd.c
drivers/mfd/stmpe.c
drivers/mfd/stmpe.h
drivers/mfd/tc3589x.c
drivers/mfd/tc6387xb.c
drivers/mfd/ti_am335x_tscadc.c
drivers/mfd/timberdale.c
drivers/mfd/tps6507x.c
drivers/mfd/tps65090.c
drivers/mfd/tps65217.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65910.c
drivers/mfd/tps65912-core.c
drivers/mfd/tps80031.c
drivers/mfd/twl-core.c
drivers/mfd/twl6030-irq.c
drivers/mfd/twl6040.c
drivers/mfd/viperboard.c
drivers/mfd/vx855.c
drivers/mfd/wm5110-tables.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm831x-i2c.c
drivers/mfd/wm831x-spi.c
drivers/mfd/wm8994-core.c
drivers/pinctrl/pinctrl-abx500.c
drivers/pinctrl/pinctrl-abx500.h
drivers/pwm/Kconfig
drivers/pwm/Makefile
drivers/pwm/pwm-lp3943.c [new file with mode: 0644]
drivers/regulator/Kconfig
drivers/regulator/tps6586x-regulator.c
include/linux/mfd/abx500/ab8500-gpio.h [deleted file]
include/linux/mfd/abx500/ab8500.h
include/linux/mfd/lp3943.h [new file with mode: 0644]
include/linux/mfd/max14577-private.h [new file with mode: 0644]
include/linux/mfd/max14577.h [new file with mode: 0644]
include/linux/mfd/max77686-private.h
include/linux/mfd/max8997-private.h
include/linux/mfd/max8998-private.h
include/linux/mfd/mc13xxx.h
include/linux/mfd/ti_am335x_tscadc.h
include/linux/mfd/tps6586x.h
include/linux/platform_data/mfd-mcp-sa11x0.h
include/linux/ssbi.h
sound/soc/fsl/Kconfig

diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
new file mode 100644 (file)
index 0000000..80fcb7d
--- /dev/null
@@ -0,0 +1,37 @@
+TI/National Semiconductor LP3943 GPIO controller
+
+Required properties:
+  - compatible: "ti,lp3943-gpio"
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2. See gpio.txt in this directory for a
+                 description of the cells format.
+
+Example:
+Simple LED controls with LP3943 GPIO controller
+
+&i2c4 {
+       lp3943@60 {
+               compatible = "ti,lp3943";
+               reg = <0x60>;
+
+               gpioex: gpio {
+                       compatible = "ti,lp3943-gpio";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+       };
+};
+
+leds {
+       compatible = "gpio-leds";
+       indicator1 {
+               label = "indi1";
+               gpios = <&gpioex 9 GPIO_ACTIVE_LOW>;
+       };
+
+       indicator2 {
+               label = "indi2";
+               gpios = <&gpioex 10 GPIO_ACTIVE_LOW>;
+               default-state = "off";
+       };
+};
index 5f229c5f6da96c09d011fe5bec75eda2ab2ba56d..8009c3d87f333548467bbefc8cb28db9fcd36c69 100644 (file)
@@ -17,6 +17,15 @@ Required properties (SPI):
 - compatible: "google,cros-ec-spi"
 - reg: SPI chip select
 
+Optional properties (SPI):
+- google,cros-ec-spi-msg-delay: Some implementations of the EC require some
+  additional processing time in order to accept new transactions. If the delay
+  between transactions is not long enough the EC may not be able to respond
+  properly to subsequent transactions and cause them to hang. This property
+  specifies the delay, in usecs, introduced between transactions to account
+  for the time required by the EC to get back into a state in which new data
+  can be accepted.
+
 Required properties (LPC):
 - compatible: "google,cros-ec-lpc"
 - reg: List of (IO address, size) pairs defining the interface uses
diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt b/Documentation/devicetree/bindings/mfd/lp3943.txt
new file mode 100644 (file)
index 0000000..e8591d6
--- /dev/null
@@ -0,0 +1,33 @@
+TI/National Semiconductor LP3943 MFD driver
+
+Required properties:
+  - compatible: "ti,lp3943"
+  - reg: I2C slave address. From 0x60 to 0x67.
+
+LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
+
+For the LP3943 GPIO properties please refer to:
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+
+For the LP3943 PWM properties please refer to:
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
+
+Example:
+
+lp3943@60 {
+       compatible = "ti,lp3943";
+       reg = <0x60>;
+
+       gpioex: gpio {
+               compatible = "ti,lp3943-gpio";
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       pwm3943: pwm {
+               compatible = "ti,lp3943-pwm";
+               #pwm-cells = <2>;
+               ti,pwm0 = <8 9 10>;
+               ti,pwm1 = <15>;
+       };
+};
index 78a840d7510d27ab51eb892542318e01a6bc3774..15ee89c3cc7b3406451c91038c3c4cb312ec5488 100644 (file)
@@ -60,7 +60,7 @@ as per the datasheet of s2mps11.
 
        - LDOn
                  - valid values for n are 1 to 38
-                 - Example: LDO0, LD01, LDO28
+                 - Example: LDO1, LD02, LDO28
        - BUCKn
                  - valid values for n are 1 to 10.
                  - Example: BUCK1, BUCK2, BUCK9
diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
new file mode 100644 (file)
index 0000000..7bd9d3b
--- /dev/null
@@ -0,0 +1,58 @@
+TI/National Semiconductor LP3943 PWM controller
+
+Required properties:
+  - compatible: "ti,lp3943-pwm"
+  - #pwm-cells: Should be 2. See pwm.txt in this directory for a
+                description of the cells format.
+                Note that this hardware limits the period length to the
+                range 6250~1600000.
+  - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
+    0 = output 0
+    1 = output 1
+    .
+    .
+    15 = output 15
+
+Example:
+PWM 0 is for RGB LED brightness control
+PWM 1 is for brightness control of LP8557 backlight device
+
+&i2c3 {
+       lp3943@60 {
+               compatible = "ti,lp3943";
+               reg = <0x60>;
+
+               /*
+                * PWM 0 : output 8, 9 and 10
+                * PWM 1 : output 15
+                */
+               pwm3943: pwm {
+                       compatible = "ti,lp3943-pwm";
+                       #pwm-cells = <2>;
+                       ti,pwm0 = <8 9 10>;
+                       ti,pwm1 = <15>;
+               };
+       };
+
+};
+
+/* LEDs control with PWM 0 of LP3943 */
+pwmleds {
+       compatible = "pwm-leds";
+       rgb {
+               label = "indi::rgb";
+               pwms = <&pwm3943 0 10000>;
+               max-brightness = <255>;
+       };
+};
+
+&i2c4 {
+       /* Backlight control with PWM 1 of LP3943 */
+       backlight@2c {
+               compatible = "ti,lp8557";
+               reg = <0x2c>;
+
+               pwms = <&pwm3943 1 10000>;
+               pwm-names = "lp8557";
+       };
+};
index d5c9bca01232fe40516b2dcd67a2561ebbfa7d50..cbe89ff10686b15e008cb4bfc42ac385038b6a4a 100644 (file)
                                        reg = <3>;
                                        regulator-compatible = "sm2";
                                        regulator-name = "vdd_sm2,vin_ldo*";
-                                       regulator-min-microvolt = <3700000>;
-                                       regulator-max-microvolt = <3700000>;
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
                                        regulator-always-on;
                                };
 
index 25ce03eff6ab356b236bac063c3a32a862014841..50cc557abe414799bfc0eca354852d6e6027793c 100644 (file)
@@ -406,6 +406,14 @@ config GPIO_ARIZONA
        help
          Support for GPIOs on Wolfson Arizona class devices.
 
+config GPIO_LP3943
+       tristate "TI/National Semiconductor LP3943 GPIO expander"
+       depends on MFD_LP3943
+       help
+         GPIO driver for LP3943 MFD.
+         LP3943 can be used as a GPIO expander which provides up to 16 GPIOs.
+         Open drain outputs are required for this usage.
+
 config GPIO_MAX7300
        tristate "Maxim MAX7300 GPIO expander"
        depends on I2C
index c44fffac9519d2b9c3ffebf146a51d7aa3d66215..0248471402e486d7cb3afc00724f27cc3bcea638 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)   += gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)      += gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)      += gpio-ks8695.o
 obj-$(CONFIG_GPIO_INTEL_MID)   += gpio-intel-mid.o
+obj-$(CONFIG_GPIO_LP3943)      += gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX)     += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LYNXPOINT)   += gpio-lynxpoint.o
 obj-$(CONFIG_GPIO_MAX730X)     += gpio-max730x.o
diff --git a/drivers/gpio/gpio-lp3943.c b/drivers/gpio/gpio-lp3943.c
new file mode 100644 (file)
index 0000000..a0341c9
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * TI/National Semiconductor LP3943 GPIO driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim <milo.kim@ti.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; version 2.
+ */
+
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/mfd/lp3943.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+enum lp3943_gpios {
+       LP3943_GPIO1,
+       LP3943_GPIO2,
+       LP3943_GPIO3,
+       LP3943_GPIO4,
+       LP3943_GPIO5,
+       LP3943_GPIO6,
+       LP3943_GPIO7,
+       LP3943_GPIO8,
+       LP3943_GPIO9,
+       LP3943_GPIO10,
+       LP3943_GPIO11,
+       LP3943_GPIO12,
+       LP3943_GPIO13,
+       LP3943_GPIO14,
+       LP3943_GPIO15,
+       LP3943_GPIO16,
+       LP3943_MAX_GPIO,
+};
+
+struct lp3943_gpio {
+       struct gpio_chip chip;
+       struct lp3943 *lp3943;
+       u16 input_mask;         /* 1 = GPIO is input direction, 0 = output */
+};
+
+static inline struct lp3943_gpio *to_lp3943_gpio(struct gpio_chip *_chip)
+{
+       return container_of(_chip, struct lp3943_gpio, chip);
+}
+
+static int lp3943_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+       struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+       /* Return an error if the pin is already assigned */
+       if (test_and_set_bit(offset, &lp3943->pin_used))
+               return -EBUSY;
+
+       return 0;
+}
+
+static void lp3943_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+       struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+       clear_bit(offset, &lp3943->pin_used);
+}
+
+static int lp3943_gpio_set_mode(struct lp3943_gpio *lp3943_gpio, u8 offset,
+                               u8 val)
+{
+       struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+       const struct lp3943_reg_cfg *mux = lp3943->mux_cfg;
+
+       return lp3943_update_bits(lp3943, mux[offset].reg, mux[offset].mask,
+                                 val << mux[offset].shift);
+}
+
+static int lp3943_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+
+       lp3943_gpio->input_mask |= BIT(offset);
+
+       return lp3943_gpio_set_mode(lp3943_gpio, offset, LP3943_GPIO_IN);
+}
+
+static int lp3943_get_gpio_in_status(struct lp3943_gpio *lp3943_gpio,
+                                    struct gpio_chip *chip, unsigned offset)
+{
+       u8 addr, read;
+       int err;
+
+       switch (offset) {
+       case LP3943_GPIO1 ... LP3943_GPIO8:
+               addr = LP3943_REG_GPIO_A;
+               break;
+       case LP3943_GPIO9 ... LP3943_GPIO16:
+               addr = LP3943_REG_GPIO_B;
+               offset = offset - 8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       err = lp3943_read_byte(lp3943_gpio->lp3943, addr, &read);
+       if (err)
+               return err;
+
+       return !!(read & BIT(offset));
+}
+
+static int lp3943_get_gpio_out_status(struct lp3943_gpio *lp3943_gpio,
+                                     struct gpio_chip *chip, unsigned offset)
+{
+       struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+       const struct lp3943_reg_cfg *mux = lp3943->mux_cfg;
+       u8 read;
+       int err;
+
+       err = lp3943_read_byte(lp3943, mux[offset].reg, &read);
+       if (err)
+               return err;
+
+       read = (read & mux[offset].mask) >> mux[offset].shift;
+
+       if (read == LP3943_GPIO_OUT_HIGH)
+               return 1;
+       else if (read == LP3943_GPIO_OUT_LOW)
+               return 0;
+       else
+               return -EINVAL;
+}
+
+static int lp3943_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+
+       /*
+        * Limitation:
+        *   LP3943 doesn't have the GPIO direction register. It provides
+        *   only input and output status registers.
+        *   So, direction info is required to handle the 'get' operation.
+        *   This variable is updated whenever the direction is changed and
+        *   it is used here.
+        */
+
+       if (lp3943_gpio->input_mask & BIT(offset))
+               return lp3943_get_gpio_in_status(lp3943_gpio, chip, offset);
+       else
+               return lp3943_get_gpio_out_status(lp3943_gpio, chip, offset);
+}
+
+static void lp3943_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+       u8 data;
+
+       if (value)
+               data = LP3943_GPIO_OUT_HIGH;
+       else
+               data = LP3943_GPIO_OUT_LOW;
+
+       lp3943_gpio_set_mode(lp3943_gpio, offset, data);
+}
+
+static int lp3943_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+                                       int value)
+{
+       struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+
+       lp3943_gpio_set(chip, offset, value);
+       lp3943_gpio->input_mask &= ~BIT(offset);
+
+       return 0;
+}
+
+static const struct gpio_chip lp3943_gpio_chip = {
+       .label                  = "lp3943",
+       .owner                  = THIS_MODULE,
+       .request                = lp3943_gpio_request,
+       .free                   = lp3943_gpio_free,
+       .direction_input        = lp3943_gpio_direction_input,
+       .get                    = lp3943_gpio_get,
+       .direction_output       = lp3943_gpio_direction_output,
+       .set                    = lp3943_gpio_set,
+       .base                   = -1,
+       .ngpio                  = LP3943_MAX_GPIO,
+       .can_sleep              = 1,
+};
+
+static int lp3943_gpio_probe(struct platform_device *pdev)
+{
+       struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent);
+       struct lp3943_gpio *lp3943_gpio;
+
+       lp3943_gpio = devm_kzalloc(&pdev->dev, sizeof(*lp3943_gpio),
+                               GFP_KERNEL);
+       if (!lp3943_gpio)
+               return -ENOMEM;
+
+       lp3943_gpio->lp3943 = lp3943;
+       lp3943_gpio->chip = lp3943_gpio_chip;
+       lp3943_gpio->chip.dev = &pdev->dev;
+
+       platform_set_drvdata(pdev, lp3943_gpio);
+
+       return gpiochip_add(&lp3943_gpio->chip);
+}
+
+static int lp3943_gpio_remove(struct platform_device *pdev)
+{
+       struct lp3943_gpio *lp3943_gpio = platform_get_drvdata(pdev);
+
+       return gpiochip_remove(&lp3943_gpio->chip);
+}
+
+static const struct of_device_id lp3943_gpio_of_match[] = {
+       { .compatible = "ti,lp3943-gpio", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, lp3943_gpio_of_match);
+
+static struct platform_driver lp3943_gpio_driver = {
+       .probe = lp3943_gpio_probe,
+       .remove = lp3943_gpio_remove,
+       .driver = {
+               .name = "lp3943-gpio",
+               .owner = THIS_MODULE,
+               .of_match_table = lp3943_gpio_of_match,
+       },
+};
+module_platform_driver(lp3943_gpio_driver);
+
+MODULE_DESCRIPTION("LP3943 GPIO driver");
+MODULE_ALIAS("platform:lp3943-gpio");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
index d4d748214e4b364dc716889d2b66363353c2ee56..31e786e3999b128ac8e53629db48290086162f5c 100644 (file)
@@ -60,6 +60,24 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
        return step_en;
 }
 
+static u32 get_adc_chan_step_mask(struct tiadc_device *adc_dev,
+               struct iio_chan_spec const *chan)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
+               if (chan->channel == adc_dev->channel_line[i]) {
+                       u32 step;
+
+                       step = adc_dev->channel_step[i];
+                       /* +1 for the charger */
+                       return 1 << (step + 1);
+               }
+       }
+       WARN_ON(1);
+       return 0;
+}
+
 static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
 {
        return 1 << adc_dev->channel_step[chan];
@@ -181,7 +199,7 @@ static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
                enb |= (get_adc_step_bit(adc_dev, bit) << 1);
        adc_dev->buffer_en_ch_steps = enb;
 
-       am335x_tsc_se_set(adc_dev->mfd_tscadc, enb);
+       am335x_tsc_se_set_cache(adc_dev->mfd_tscadc, enb);
 
        tiadc_writel(adc_dev,  REG_IRQSTATUS, IRQENB_FIFO1THRES
                                | IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
@@ -199,6 +217,7 @@ static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
        tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
                                IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
        am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
+       adc_dev->buffer_en_ch_steps = 0;
 
        /* Flush FIFO of leftover data in the time it takes to disable adc */
        fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
@@ -328,34 +347,43 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
        unsigned int fifo1count, read, stepid;
        bool found = false;
        u32 step_en;
-       unsigned long timeout = jiffies + usecs_to_jiffies
-                               (IDLE_TIMEOUT * adc_dev->channels);
+       unsigned long timeout;
 
        if (iio_buffer_enabled(indio_dev))
                return -EBUSY;
 
-       step_en = get_adc_step_mask(adc_dev);
-       am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+       step_en = get_adc_chan_step_mask(adc_dev, chan);
+       if (!step_en)
+               return -EINVAL;
+
+       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+       while (fifo1count--)
+               tiadc_readl(adc_dev, REG_FIFO1);
+
+       am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en);
 
-       /* Wait for ADC sequencer to complete sampling */
-       while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) {
-               if (time_after(jiffies, timeout))
+       timeout = jiffies + usecs_to_jiffies
+                               (IDLE_TIMEOUT * adc_dev->channels);
+       /* Wait for Fifo threshold interrupt */
+       while (1) {
+               fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+               if (fifo1count)
+                       break;
+
+               if (time_after(jiffies, timeout)) {
+                       am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
                        return -EAGAIN;
                }
+       }
        map_val = chan->channel + TOTAL_CHANNELS;
 
        /*
-        * When the sub-system is first enabled,
-        * the sequencer will always start with the
-        * lowest step (1) and continue until step (16).
-        * For ex: If we have enabled 4 ADC channels and
-        * currently use only 1 out of them, the
-        * sequencer still configures all the 4 steps,
-        * leading to 3 unwanted data.
-        * Hence we need to flush out this data.
+        * We check the complete FIFO. We programmed just one entry but in case
+        * something went wrong we left empty handed (-EAGAIN previously) and
+        * then the value apeared somehow in the FIFO we would have two entries.
+        * Therefore we read every item and keep only the latest version of the
+        * requested channel.
         */
-
-       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
        for (i = 0; i < fifo1count; i++) {
                read = tiadc_readl(adc_dev, REG_FIFO1);
                stepid = read & FIFOREAD_CHNLID_MASK;
@@ -367,6 +395,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
                        *val = (u16) read;
                }
        }
+       am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
 
        if (found == false)
                return -EBUSY;
@@ -494,7 +523,8 @@ static int tiadc_resume(struct device *dev)
        tiadc_writel(adc_dev, REG_CTRL, restore);
 
        tiadc_step_config(indio_dev);
-
+       am335x_tsc_se_set_cache(adc_dev->mfd_tscadc,
+                       adc_dev->buffer_en_ch_steps);
        return 0;
 }
 
index 5f4967d01bc36a621655f64eea7e2c1408ef43b7..e2413acbbb1678af621f50ce7d22cd96a2de6da6 100644 (file)
@@ -168,7 +168,7 @@ config INPUT_MAX8997_HAPTIC
 
 config INPUT_MC13783_PWRBUTTON
        tristate "MC13783 ON buttons"
-       depends on MFD_MC13783
+       depends on MFD_MC13XXX
        help
          Support the ON buttons of MC13783 PMIC as an input device
          reporting power button status.
index 961d58d3264769fb3daec51182effd8742bd1b5e..07e9e82029d190ac164cd4114833e365dcfc21fe 100644 (file)
@@ -717,7 +717,7 @@ config TOUCHSCREEN_USB_COMPOSITE
 
 config TOUCHSCREEN_MC13783
        tristate "Freescale MC13783 touchscreen input driver"
-       depends on MFD_MC13783
+       depends on MFD_MC13XXX
        help
          Say Y here if you have an Freescale MC13783 PMIC on your
          board and want to use its touchscreen
index 68beadaabcebb134adc4ad1e9a9a8fdc6ec590d6..2ca5a7bee04e45c3b5661df8a54ed97fdefbd1fa 100644 (file)
@@ -198,7 +198,7 @@ static void titsc_step_config(struct titsc *ts_dev)
        /* The steps1 â€¦ end and bit 0 for TS_Charge */
        stepenable = (1 << (end_step + 2)) - 1;
        ts_dev->step_mask = stepenable;
-       am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
+       am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
 }
 
 static void titsc_read_coordinates(struct titsc *ts_dev,
@@ -322,7 +322,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
 
        if (irqclr) {
                titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
-               am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
+               am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
                return IRQ_HANDLED;
        }
        return IRQ_NONE;
index a65447d65605fe7d7539082322a70cceae9c18c7..7dca1e640970a0dfb7f28ad8909c1f3e4d7d26e4 100644 (file)
@@ -148,7 +148,7 @@ static struct resource onkey_resources[] = {
         },
 };
 
-static struct mfd_cell onkey_devs[] = {
+static const struct mfd_cell onkey_devs[] = {
        {
         .name = "88pm80x-onkey",
         .num_resources = 1,
@@ -157,7 +157,7 @@ static struct mfd_cell onkey_devs[] = {
         },
 };
 
-static struct mfd_cell regulator_devs[] = {
+static const struct mfd_cell regulator_devs[] = {
        {
         .name = "88pm80x-regulator",
         .id = -1,
index 8a5b6ffb5afb6fbedbd8a1364a879890a6ebfba5..64751c2a1ace8fc2f90e59c1a1ca404776aa04d0 100644 (file)
@@ -77,7 +77,7 @@ static struct resource codec_resources[] = {
         },
 };
 
-static struct mfd_cell codec_devs[] = {
+static const struct mfd_cell codec_devs[] = {
        {
         .name = "88pm80x-codec",
         .num_resources = ARRAY_SIZE(codec_resources),
index dd671582c9a1b2dcf8286b2a798a65e6621752ba..49bb445d846aa76e206dfe7fb7d30ad5f24b6b97 100644 (file)
@@ -80,7 +80,7 @@ config MFD_CROS_EC_I2C
 
 config MFD_CROS_EC_SPI
        tristate "ChromeOS Embedded Controller (SPI)"
-       depends on MFD_CROS_EC && SPI
+       depends on MFD_CROS_EC && SPI && OF
 
        ---help---
          If you say Y here, you get support for talking to the ChromeOS EC
@@ -163,14 +163,10 @@ config MFD_DA9063
          Additional drivers must be enabled in order to use the functionality
          of the device.
 
-config MFD_MC13783
-       tristate
-
 config MFD_MC13XXX
        tristate
        depends on (SPI_MASTER || I2C)
        select MFD_CORE
-       select MFD_MC13783
        help
          Enable support for the Freescale MC13783 and MC13892 PMICs.
          This driver provides common support for accessing the device,
@@ -321,6 +317,19 @@ config MFD_88PM860X
          select individual components like voltage regulators, RTC and
          battery-charger under the corresponding menus.
 
+config MFD_MAX14577
+       bool "Maxim Semiconductor MAX14577 MUIC + Charger Support"
+       depends on I2C=y
+       select MFD_CORE
+       select REGMAP_I2C
+       select IRQ_DOMAIN
+       help
+         Say yes here to support for Maxim Semiconductor MAX14577.
+         This is a Micro-USB IC with Charger controls on chip.
+         This driver provides common support for accessing the device;
+         additional drivers must be enabled in order to use the functionality
+         of the device.
+
 config MFD_MAX77686
        bool "Maxim Semiconductor MAX77686 PMIC Support"
        depends on I2C=y
@@ -725,6 +734,17 @@ config MFD_DM355EVM_MSP
          boards.  MSP430 firmware manages resets and power sequencing,
          inputs from buttons and the IR remote, LEDs, an RTC, and more.
 
+config MFD_LP3943
+       tristate "TI/National Semiconductor LP3943 MFD Driver"
+       depends on I2C
+       select MFD_CORE
+       select REGMAP_I2C
+       help
+         Support for the TI/National Semiconductor LP3943.
+         This driver consists of GPIO and PWM drivers.
+         With these functionalities, it can be used for LED string control or
+         general usage such like a GPIO controller and a PWM controller.
+
 config MFD_LP8788
        bool "TI LP8788 Power Management Unit Driver"
        depends on I2C=y
index 8a28dc90fe785033452a1740973f34883abbe0de..5aea5ef0a62f51eff03a14404569c68a7700262f 100644 (file)
@@ -102,6 +102,7 @@ obj-$(CONFIG_PMIC_DA9052)   += da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)   += da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)   += da9052-i2c.o
 
+obj-$(CONFIG_MFD_LP3943)       += lp3943.o
 obj-$(CONFIG_MFD_LP8788)       += lp8788.o lp8788-irq.o
 
 da9055-objs                    := da9055-core.o da9055-i2c.o
@@ -110,6 +111,7 @@ obj-$(CONFIG_MFD_DA9055)    += da9055.o
 da9063-objs                    := da9063-core.o da9063-irq.o da9063-i2c.o
 obj-$(CONFIG_MFD_DA9063)       += da9063.o
 
+obj-$(CONFIG_MFD_MAX14577)     += max14577.o
 obj-$(CONFIG_MFD_MAX77686)     += max77686.o max77686-irq.o
 obj-$(CONFIG_MFD_MAX77693)     += max77693.o max77693-irq.o
 obj-$(CONFIG_MFD_MAX8907)      += max8907.o
index b6c2cdc76091aa2ff78b8d1d17e3c7b6e6d1dbd0..aaff683cd37d43809bb8da6b1cd5c085f1bf664a 100644 (file)
@@ -491,7 +491,7 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500,
                if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F)
                        line += 1;
 
-               handle_nested_irq(ab8500->irq_base + line);
+               handle_nested_irq(irq_create_mapping(ab8500->domain, line));
        }
 
        return 0;
@@ -1017,7 +1017,7 @@ static struct resource ab8500_temp_resources[] = {
        },
 };
 
-static struct mfd_cell ab8500_bm_devs[] = {
+static const struct mfd_cell ab8500_bm_devs[] = {
        {
                .name = "ab8500-charger",
                .of_compatible = "stericsson,ab8500-charger",
@@ -1052,7 +1052,7 @@ static struct mfd_cell ab8500_bm_devs[] = {
        },
 };
 
-static struct mfd_cell ab8500_devs[] = {
+static const struct mfd_cell ab8500_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1143,7 +1143,7 @@ static struct mfd_cell ab8500_devs[] = {
        },
 };
 
-static struct mfd_cell ab9540_devs[] = {
+static const struct mfd_cell ab9540_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1214,7 +1214,7 @@ static struct mfd_cell ab9540_devs[] = {
 };
 
 /* Device list for ab8505  */
-static struct mfd_cell ab8505_devs[] = {
+static const struct mfd_cell ab8505_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1275,7 +1275,7 @@ static struct mfd_cell ab8505_devs[] = {
        },
 };
 
-static struct mfd_cell ab8540_devs[] = {
+static const struct mfd_cell ab8540_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1339,7 +1339,7 @@ static struct mfd_cell ab8540_devs[] = {
        },
 };
 
-static struct mfd_cell ab8540_cut1_devs[] = {
+static const struct mfd_cell ab8540_cut1_devs[] = {
        {
                .name = "ab8500-rtc",
                .of_compatible = "stericsson,ab8500-rtc",
@@ -1348,7 +1348,7 @@ static struct mfd_cell ab8540_cut1_devs[] = {
        },
 };
 
-static struct mfd_cell ab8540_cut2_devs[] = {
+static const struct mfd_cell ab8540_cut2_devs[] = {
        {
                .name = "ab8540-rtc",
                .of_compatible = "stericsson,ab8540-rtc",
index e33e385af0a29e7930e4277984c640a1cf1db975..d1a22aae2df51cda0936a52dc58e9df66c493f7d 100644 (file)
@@ -1600,7 +1600,6 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p)
 
        for (line = 0; line < num_interrupt_lines; line++) {
                struct irq_desc *desc = irq_to_desc(line + irq_first);
-               struct irqaction *action = desc->action;
 
                seq_printf(s, "%3i:  %6i %4i", line,
                           num_interrupts[line],
@@ -1608,7 +1607,9 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p)
 
                if (desc && desc->name)
                        seq_printf(s, "-%-8s", desc->name);
-               if (action) {
+               if (desc && desc->action) {
+                       struct irqaction *action = desc->action;
+
                        seq_printf(s, "  %s", action->name);
                        while ((action = action->next) != NULL)
                                seq_printf(s, ", %s", action->name);
index 75e180ceecf3fac16f9a432ada482130624dfe01..a45aab9f6bb135e64c0f0a420f75ed2508e17e92 100644 (file)
@@ -565,7 +565,7 @@ static inline int arizona_of_get_core_pdata(struct arizona *arizona)
 }
 #endif
 
-static struct mfd_cell early_devs[] = {
+static const struct mfd_cell early_devs[] = {
        { .name = "arizona-ldo1" },
 };
 
@@ -577,7 +577,7 @@ static const char *wm5102_supplies[] = {
        "SPKVDDR",
 };
 
-static struct mfd_cell wm5102_devs[] = {
+static const struct mfd_cell wm5102_devs[] = {
        { .name = "arizona-micsupp" },
        { .name = "arizona-extcon" },
        { .name = "arizona-gpio" },
@@ -590,7 +590,7 @@ static struct mfd_cell wm5102_devs[] = {
        },
 };
 
-static struct mfd_cell wm5110_devs[] = {
+static const struct mfd_cell wm5110_devs[] = {
        { .name = "arizona-micsupp" },
        { .name = "arizona-extcon" },
        { .name = "arizona-gpio" },
@@ -609,7 +609,7 @@ static const char *wm8997_supplies[] = {
        "SPKVDD",
 };
 
-static struct mfd_cell wm8997_devs[] = {
+static const struct mfd_cell wm8997_devs[] = {
        { .name = "arizona-micsupp" },
        { .name = "arizona-extcon" },
        { .name = "arizona-gpio" },
index f161f2e00df7434ee8970584e76392af68304179..c71ff0af1547e573aacf17c6317e2e02224813f7 100644 (file)
@@ -54,7 +54,7 @@ static const struct resource as3722_adc_resource[] = {
        },
 };
 
-static struct mfd_cell as3722_devs[] = {
+static const struct mfd_cell as3722_devs[] = {
        {
                .name = "as3722-pinctrl",
        },
@@ -74,6 +74,9 @@ static struct mfd_cell as3722_devs[] = {
        {
                .name = "as3722-power-off",
        },
+       {
+               .name = "as3722-wdt",
+       },
 };
 
 static const struct regmap_irq as3722_irqs[] = {
index fa22154c84e49cfb6be58930339ea180b8be77b6..9f6294f2a0708ab6be063d4bfbc0f98ad1062fa5 100644 (file)
@@ -695,7 +695,7 @@ static int ds1wm_disable(struct platform_device *pdev)
        return 0;
 }
 
-static struct mfd_cell asic3_cell_ds1wm = {
+static const struct mfd_cell asic3_cell_ds1wm = {
        .name          = "ds1wm",
        .enable        = ds1wm_enable,
        .disable       = ds1wm_disable,
@@ -797,7 +797,7 @@ static int asic3_mmc_disable(struct platform_device *pdev)
        return 0;
 }
 
-static struct mfd_cell asic3_cell_mmc = {
+static const struct mfd_cell asic3_cell_mmc = {
        .name          = "tmio-mmc",
        .enable        = asic3_mmc_enable,
        .disable       = asic3_mmc_disable,
index 1f36885d674b07741a4f0374089f2cb04ed839e4..783fe2e73e1edd43344d3bb4c3b1fb09daf9cf3d 100644 (file)
@@ -84,7 +84,7 @@ static irqreturn_t ec_irq_thread(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static struct mfd_cell cros_devs[] = {
+static const struct mfd_cell cros_devs[] = {
        {
                .name = "cros-ec-keyb",
                .id = 1,
index 123044608b63dc5997f9cf921003814f9ac53f84..4f71be99a183713810c5d00e7f4eac480e006a58 100644 (file)
@@ -120,7 +120,7 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev,
        return ret;
 }
 
-static int cros_ec_probe_i2c(struct i2c_client *client,
+static int cros_ec_i2c_probe(struct i2c_client *client,
                             const struct i2c_device_id *dev_id)
 {
        struct device *dev = &client->dev;
@@ -150,7 +150,7 @@ static int cros_ec_probe_i2c(struct i2c_client *client,
        return 0;
 }
 
-static int cros_ec_remove_i2c(struct i2c_client *client)
+static int cros_ec_i2c_remove(struct i2c_client *client)
 {
        struct cros_ec_device *ec_dev = i2c_get_clientdata(client);
 
@@ -190,8 +190,8 @@ static struct i2c_driver cros_ec_driver = {
                .owner  = THIS_MODULE,
                .pm     = &cros_ec_i2c_pm_ops,
        },
-       .probe          = cros_ec_probe_i2c,
-       .remove         = cros_ec_remove_i2c,
+       .probe          = cros_ec_i2c_probe,
+       .remove         = cros_ec_i2c_remove,
        .id_table       = cros_ec_i2c_id,
 };
 
index 367ccb58ecb15a1954cf39e936c46bc5a4bf3498..84af8d7a429544e7369daf66d2dbedb578cb12a1 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/mfd/cros_ec.h>
 #include <linux/mfd/cros_ec_commands.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 /*
   * Time between raising the SPI chip select (for the end of a
   * transaction) and dropping it again (for the next transaction).
-  * If we go too fast, the EC will miss the transaction. It seems
-  * that 50us is enough with the 16MHz STM32 EC.
+  * If we go too fast, the EC will miss the transaction. We know that we
+  * need at least 70 us with the 16 MHz STM32 EC, so go with 200 us to be
+  * safe.
   */
-#define EC_SPI_RECOVERY_TIME_NS        (50 * 1000)
+#define EC_SPI_RECOVERY_TIME_NS        (200 * 1000)
 
 /**
  * struct cros_ec_spi - information about a SPI-connected EC
  * @spi: SPI device we are connected to
  * @last_transfer_ns: time that we last finished a transfer, or 0 if there
  *     if no record
+ * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
+ *      is sent when we want to turn off CS at the end of a transaction.
  */
 struct cros_ec_spi {
        struct spi_device *spi;
        s64 last_transfer_ns;
+       unsigned int end_of_msg_delay;
 };
 
 static void debug_packet(struct device *dev, const char *name, u8 *ptr,
@@ -75,7 +80,9 @@ static void debug_packet(struct device *dev, const char *name, u8 *ptr,
 
        dev_dbg(dev, "%s: ", name);
        for (i = 0; i < len; i++)
-               dev_cont(dev, " %02x", ptr[i]);
+               pr_cont(" %02x", ptr[i]);
+
+       pr_cont("\n");
 #endif
 }
 
@@ -105,7 +112,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
        /* Receive data until we see the header byte */
        deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
        do {
-               memset(&trans, '\0', sizeof(trans));
+               memset(&trans, 0, sizeof(trans));
                trans.cs_change = 1;
                trans.rx_buf = ptr = ec_dev->din;
                trans.len = EC_MSG_PREAMBLE_COUNT;
@@ -157,7 +164,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
                dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
                        todo, need_len, ptr - ec_dev->din);
 
-               memset(&trans, '\0', sizeof(trans));
+               memset(&trans, 0, sizeof(trans));
                trans.cs_change = 1;
                trans.rx_buf = ptr;
                trans.len = todo;
@@ -217,7 +224,7 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
 
        /* Transmit phase - send our message */
        debug_packet(ec_dev->dev, "out", ec_dev->dout, len);
-       memset(&trans, '\0', sizeof(trans));
+       memset(&trans, 0, sizeof(trans));
        trans.tx_buf = ec_dev->dout;
        trans.len = len;
        trans.cs_change = 1;
@@ -235,6 +242,17 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
 
        /* turn off CS */
        spi_message_init(&msg);
+
+       if (ec_spi->end_of_msg_delay) {
+               /*
+                * Add delay for last transaction, to ensure the rising edge
+                * doesn't come too soon after the end of the data.
+                */
+               memset(&trans, 0, sizeof(trans));
+               trans.delay_usecs = ec_spi->end_of_msg_delay;
+               spi_message_add_tail(&trans, &msg);
+       }
+
        final_ret = spi_sync(ec_spi->spi, &msg);
        ktime_get_ts(&ts);
        ec_spi->last_transfer_ns = timespec_to_ns(&ts);
@@ -281,7 +299,18 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
        return 0;
 }
 
-static int cros_ec_probe_spi(struct spi_device *spi)
+static void cros_ec_spi_dt_probe(struct cros_ec_spi *ec_spi, struct device *dev)
+{
+       struct device_node *np = dev->of_node;
+       u32 val;
+       int ret;
+
+       ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val);
+       if (!ret)
+               ec_spi->end_of_msg_delay = val;
+}
+
+static int cros_ec_spi_probe(struct spi_device *spi)
 {
        struct device *dev = &spi->dev;
        struct cros_ec_device *ec_dev;
@@ -302,6 +331,9 @@ static int cros_ec_probe_spi(struct spi_device *spi)
        if (!ec_dev)
                return -ENOMEM;
 
+       /* Check for any DT properties */
+       cros_ec_spi_dt_probe(ec_spi, dev);
+
        spi_set_drvdata(spi, ec_dev);
        ec_dev->name = "SPI";
        ec_dev->dev = dev;
@@ -323,7 +355,7 @@ static int cros_ec_probe_spi(struct spi_device *spi)
        return 0;
 }
 
-static int cros_ec_remove_spi(struct spi_device *spi)
+static int cros_ec_spi_remove(struct spi_device *spi)
 {
        struct cros_ec_device *ec_dev;
 
@@ -364,12 +396,12 @@ static struct spi_driver cros_ec_driver_spi = {
                .owner  = THIS_MODULE,
                .pm     = &cros_ec_spi_pm_ops,
        },
-       .probe          = cros_ec_probe_spi,
-       .remove         = cros_ec_remove_spi,
+       .probe          = cros_ec_spi_probe,
+       .remove         = cros_ec_spi_remove,
        .id_table       = cros_ec_spi_id,
 };
 
 module_spi_driver(cros_ec_driver_spi);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("ChromeOS EC multi function device (SPI)");
index 2e4752a9220a92808e98e52a0dc6c50ecccf0068..17c13012686af663ba970f4c423a4262aa602b58 100644 (file)
@@ -172,7 +172,7 @@ static void cs5535_mfd_remove(struct pci_dev *pdev)
        pci_disable_device(pdev);
 }
 
-static DEFINE_PCI_DEVICE_TABLE(cs5535_mfd_pci_tbl) = {
+static const struct pci_device_id cs5535_mfd_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
        { 0, }
index ea28a33576e45cd3c3df406a09264bd69a5c3298..25838f10b35b2d08c295e18b27ecf4155bb5f4ce 100644 (file)
@@ -427,7 +427,7 @@ int da9052_adc_read_temp(struct da9052 *da9052)
 }
 EXPORT_SYMBOL_GPL(da9052_adc_read_temp);
 
-static struct mfd_cell da9052_subdev_info[] = {
+static const struct mfd_cell da9052_subdev_info[] = {
        {
                .name = "da9052-regulator",
                .id = 1,
index d3670cd3c3c6c0e025c80ec940851ee5599037b1..caf8dcffd0ad403d6b239f9f0c3442ac1651aa2c 100644 (file)
@@ -294,7 +294,7 @@ static struct resource da9055_ld05_6_resource = {
        .flags = IORESOURCE_IRQ,
 };
 
-static struct mfd_cell da9055_devs[] = {
+static const struct mfd_cell da9055_devs[] = {
        {
                .of_compatible = "dialog,da9055-gpio",
                .name = "da9055-gpio",
index c9cf8d988406ff8ed4d01c23d5acd6793e3d06e4..26937cd010714b7c1c9e98877603616390b6e952 100644 (file)
@@ -75,7 +75,7 @@ static struct resource da9063_hwmon_resources[] = {
 };
 
 
-static struct mfd_cell da9063_devs[] = {
+static const struct mfd_cell da9063_devs[] = {
        {
                .name           = DA9063_DRVNAME_REGULATORS,
                .num_resources  = ARRAY_SIZE(da9063_regulators_resources),
index b9ce60c301de026bba38daf276e83773c44379ec..e43e6e821117a01aac56b8e4086fe783056977cd 100644 (file)
@@ -3070,7 +3070,7 @@ static struct db8500_thsens_platform_data db8500_thsens_data = {
        .num_trips = 4,
 };
 
-static struct mfd_cell common_prcmu_devs[] = {
+static const struct mfd_cell common_prcmu_devs[] = {
        {
                .name = "ux500_wdt",
                .platform_data = &db8500_wdt_pdata,
@@ -3079,7 +3079,7 @@ static struct mfd_cell common_prcmu_devs[] = {
        },
 };
 
-static struct mfd_cell db8500_prcmu_devs[] = {
+static const struct mfd_cell db8500_prcmu_devs[] = {
        {
                .name = "db8500-prcmu-regulators",
                .of_compatible = "stericsson,db8500-prcmu-regulator",
index 6bf92a507b9546b911e258037c2dba3ac391851b..e88d4f6fef4cb80b76bdea85498056e6b272874a 100644 (file)
@@ -114,7 +114,7 @@ static struct resource ds1wm_resources[] __initdata = {
        },
 };
 
-static struct mfd_cell ds1wm_cell __initdata = {
+static const struct mfd_cell ds1wm_cell __initconst = {
        .name          = "ds1wm",
        .enable        = ds1wm_enable,
        .disable       = ds1wm_disable,
index 9203d47cdbb1b4106e87ba91e4571cea54c55543..049fd23af54a58f85a51ae564ae2bdc49e3bcdd0 100644 (file)
@@ -178,7 +178,7 @@ static struct mfd_cell msic_devs[] = {
  * These devices appear only after the MSIC driver itself is initialized so
  * we can guarantee that the SCU IPC interface is ready.
  */
-static struct mfd_cell msic_other_devs[] = {
+static const struct mfd_cell msic_other_devs[] = {
        /* Audio codec in the MSIC */
        {
                .id                     = -1,
index fcbb2e9dfd3706af3d6dd0cccfaa6f45693d7328..81b7d88af3135cc7d26bd0e3afb842497b58024c 100644 (file)
@@ -265,7 +265,7 @@ static void cmodio_pci_remove(struct pci_dev *dev)
 #define PCI_VENDOR_ID_JANZ             0x13c3
 
 /* The list of devices that this module will support */
-static DEFINE_PCI_DEVICE_TABLE(cmodio_pci_ids) = {
+static const struct pci_device_id cmodio_pci_ids[] = {
        { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0101 },
        { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0100 },
        { 0, }
index 3c0e8cf6916bd0f9cdb040548b7b7919d3f49753..7a51c0d0d4f1f5ec23b323550424cec4ff6386a7 100644 (file)
@@ -181,7 +181,7 @@ static struct resource jz4740_battery_resources[] = {
        },
 };
 
-static struct mfd_cell jz4740_adc_cells[] = {
+static const struct mfd_cell jz4740_adc_cells[] = {
        {
                .id = 0,
                .name = "jz4740-hwmon",
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c
new file mode 100644 (file)
index 0000000..e322268
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * TI/National Semiconductor LP3943 MFD Core Driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver structure:
+ *   LP3943 is an integrated device capable of driving 16 output channels.
+ *   It can be used for a GPIO expander and PWM generators.
+ *
+ *                                   LED control    General usage for a device
+ *                                   ___________   ____________________________
+ *
+ *   LP3943 MFD ---- GPIO expander    leds-gpio        eg) HW enable pin
+ *               |
+ *               --- PWM generator    leds-pwm         eg) PWM input
+ *
+ *   Internal two PWM channels are used for LED dimming effect.
+ *   And each output pin can be used as a GPIO as well.
+ *   The LED functionality can work with GPIOs or PWMs.
+ *   LEDs can be controlled with legacy leds-gpio(static brightness) or
+ *   leds-pwm drivers(dynamic brightness control).
+ *   Alternatively, it can be used for generic GPIO and PWM controller.
+ *   For example, a GPIO is HW enable pin of a device.
+ *   A PWM is input pin of a backlight device.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/lp3943.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#define LP3943_MAX_REGISTERS           0x09
+
+/* Register configuration for pin MUX */
+static const struct lp3943_reg_cfg lp3943_mux_cfg[] = {
+       /* address, mask, shift */
+       { LP3943_REG_MUX0, 0x03, 0 },
+       { LP3943_REG_MUX0, 0x0C, 2 },
+       { LP3943_REG_MUX0, 0x30, 4 },
+       { LP3943_REG_MUX0, 0xC0, 6 },
+       { LP3943_REG_MUX1, 0x03, 0 },
+       { LP3943_REG_MUX1, 0x0C, 2 },
+       { LP3943_REG_MUX1, 0x30, 4 },
+       { LP3943_REG_MUX1, 0xC0, 6 },
+       { LP3943_REG_MUX2, 0x03, 0 },
+       { LP3943_REG_MUX2, 0x0C, 2 },
+       { LP3943_REG_MUX2, 0x30, 4 },
+       { LP3943_REG_MUX2, 0xC0, 6 },
+       { LP3943_REG_MUX3, 0x03, 0 },
+       { LP3943_REG_MUX3, 0x0C, 2 },
+       { LP3943_REG_MUX3, 0x30, 4 },
+       { LP3943_REG_MUX3, 0xC0, 6 },
+};
+
+static struct mfd_cell lp3943_devs[] = {
+       {
+               .name = "lp3943-pwm",
+               .of_compatible = "ti,lp3943-pwm",
+       },
+       {
+               .name = "lp3943-gpio",
+               .of_compatible = "ti,lp3943-gpio",
+       },
+};
+
+int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read)
+{
+       int ret;
+       unsigned int val;
+
+       ret = regmap_read(lp3943->regmap, reg, &val);
+       if (ret < 0)
+               return ret;
+
+       *read = (u8)val;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lp3943_read_byte);
+
+int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data)
+{
+       return regmap_write(lp3943->regmap, reg, data);
+}
+EXPORT_SYMBOL_GPL(lp3943_write_byte);
+
+int lp3943_update_bits(struct lp3943 *lp3943, u8 reg, u8 mask, u8 data)
+{
+       return regmap_update_bits(lp3943->regmap, reg, mask, data);
+}
+EXPORT_SYMBOL_GPL(lp3943_update_bits);
+
+static const struct regmap_config lp3943_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = LP3943_MAX_REGISTERS,
+};
+
+static int lp3943_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+       struct lp3943 *lp3943;
+       struct device *dev = &cl->dev;
+
+       lp3943 = devm_kzalloc(dev, sizeof(*lp3943), GFP_KERNEL);
+       if (!lp3943)
+               return -ENOMEM;
+
+       lp3943->regmap = devm_regmap_init_i2c(cl, &lp3943_regmap_config);
+       if (IS_ERR(lp3943->regmap))
+               return PTR_ERR(lp3943->regmap);
+
+       lp3943->pdata = dev_get_platdata(dev);
+       lp3943->dev = dev;
+       lp3943->mux_cfg = lp3943_mux_cfg;
+       i2c_set_clientdata(cl, lp3943);
+
+       return mfd_add_devices(dev, -1, lp3943_devs, ARRAY_SIZE(lp3943_devs),
+                              NULL, 0, NULL);
+}
+
+static int lp3943_remove(struct i2c_client *cl)
+{
+       struct lp3943 *lp3943 = i2c_get_clientdata(cl);
+
+       mfd_remove_devices(lp3943->dev);
+       return 0;
+}
+
+static const struct i2c_device_id lp3943_ids[] = {
+       { "lp3943", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, lp3943_ids);
+
+#ifdef CONFIG_OF
+static const struct of_device_id lp3943_of_match[] = {
+       { .compatible = "ti,lp3943", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, lp3943_of_match);
+#endif
+
+static struct i2c_driver lp3943_driver = {
+       .probe = lp3943_probe,
+       .remove = lp3943_remove,
+       .driver = {
+               .name = "lp3943",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(lp3943_of_match),
+       },
+       .id_table = lp3943_ids,
+};
+
+module_i2c_driver(lp3943_driver);
+
+MODULE_DESCRIPTION("LP3943 MFD Core Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
index 0f1221911018b6d4fd4e558ff0df4996a4b70a10..a30bc15fe5ba5ac6a5b2a04a23a3a518ae2d2ba5 100644 (file)
@@ -71,7 +71,7 @@ static struct resource rtc_irqs[] = {
        },
 };
 
-static struct mfd_cell lp8788_devs[] = {
+static const struct mfd_cell lp8788_devs[] = {
        /* 4 bucks */
        MFD_DEV_WITH_ID(BUCK, 1),
        MFD_DEV_WITH_ID(BUCK, 2),
index 37edf9e989b066cbb1a8a667001ce4e655ac7c1c..be93fa261dedb4c808955c1830932f84a48b7524 100644 (file)
@@ -517,7 +517,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
  * pci_driver, because the I/O Controller Hub has also other
  * functions that probably will be registered by other drivers.
  */
-static DEFINE_PCI_DEVICE_TABLE(lpc_ich_ids) = {
+static const struct pci_device_id lpc_ich_ids[] = {
        { PCI_VDEVICE(INTEL, 0x2410), LPC_ICH},
        { PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0},
        { PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2},
index fbfbf0b7f97ac1cfad5d8964a7436fa05122a89f..3bb05c03c68ded9f3e6c807a1c3559ec66830a94 100644 (file)
@@ -76,7 +76,7 @@ static struct mfd_cell wdt_sch_cell = {
        .ignore_resource_conflicts = true,
 };
 
-static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
+static const struct pci_device_id lpc_sch_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CENTERTON_ILB) },
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
new file mode 100644 (file)
index 0000000..ac514fb
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * max14577.c - mfd core driver for the Maxim 14577
+ *
+ * Copyright (C) 2013 Samsung Electrnoics
+ * Chanwoo Choi <cw00.choi@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski@samsung.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.
+ *
+ * This driver is based on max8997.c
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max14577.h>
+#include <linux/mfd/max14577-private.h>
+
+static struct mfd_cell max14577_devs[] = {
+       { .name = "max14577-muic", },
+       {
+               .name = "max14577-regulator",
+               .of_compatible = "maxim,max14577-regulator",
+       },
+       { .name = "max14577-charger", },
+};
+
+static bool max14577_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case MAX14577_REG_INT1 ... MAX14577_REG_STATUS3:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
+
+static const struct regmap_config max14577_regmap_config = {
+       .reg_bits       = 8,
+       .val_bits       = 8,
+       .volatile_reg   = max14577_volatile_reg,
+       .max_register   = MAX14577_REG_END,
+};
+
+static const struct regmap_irq max14577_irqs[] = {
+       /* INT1 interrupts */
+       { .reg_offset = 0, .mask = INT1_ADC_MASK, },
+       { .reg_offset = 0, .mask = INT1_ADCLOW_MASK, },
+       { .reg_offset = 0, .mask = INT1_ADCERR_MASK, },
+       /* INT2 interrupts */
+       { .reg_offset = 1, .mask = INT2_CHGTYP_MASK, },
+       { .reg_offset = 1, .mask = INT2_CHGDETRUN_MASK, },
+       { .reg_offset = 1, .mask = INT2_DCDTMR_MASK, },
+       { .reg_offset = 1, .mask = INT2_DBCHG_MASK, },
+       { .reg_offset = 1, .mask = INT2_VBVOLT_MASK, },
+       /* INT3 interrupts */
+       { .reg_offset = 2, .mask = INT3_EOC_MASK, },
+       { .reg_offset = 2, .mask = INT3_CGMBC_MASK, },
+       { .reg_offset = 2, .mask = INT3_OVP_MASK, },
+       { .reg_offset = 2, .mask = INT3_MBCCHGERR_MASK, },
+};
+
+static const struct regmap_irq_chip max14577_irq_chip = {
+       .name                   = "max14577",
+       .status_base            = MAX14577_REG_INT1,
+       .mask_base              = MAX14577_REG_INTMASK1,
+       .mask_invert            = 1,
+       .num_regs               = 3,
+       .irqs                   = max14577_irqs,
+       .num_irqs               = ARRAY_SIZE(max14577_irqs),
+};
+
+static int max14577_i2c_probe(struct i2c_client *i2c,
+                             const struct i2c_device_id *id)
+{
+       struct max14577 *max14577;
+       struct max14577_platform_data *pdata = dev_get_platdata(&i2c->dev);
+       struct device_node *np = i2c->dev.of_node;
+       u8 reg_data;
+       int ret = 0;
+
+       if (np) {
+               pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+               i2c->dev.platform_data = pdata;
+       }
+
+       if (!pdata) {
+               dev_err(&i2c->dev, "No platform data found.\n");
+               return -EINVAL;
+       }
+
+       max14577 = devm_kzalloc(&i2c->dev, sizeof(*max14577), GFP_KERNEL);
+       if (!max14577)
+               return -ENOMEM;
+
+       i2c_set_clientdata(i2c, max14577);
+       max14577->dev = &i2c->dev;
+       max14577->i2c = i2c;
+       max14577->irq = i2c->irq;
+
+       max14577->regmap = devm_regmap_init_i2c(i2c, &max14577_regmap_config);
+       if (IS_ERR(max14577->regmap)) {
+               ret = PTR_ERR(max14577->regmap);
+               dev_err(max14577->dev, "Failed to allocate register map: %d\n",
+                               ret);
+               return ret;
+       }
+
+       ret = max14577_read_reg(max14577->regmap, MAX14577_REG_DEVICEID,
+                       &reg_data);
+       if (ret) {
+               dev_err(max14577->dev, "Device not found on this channel: %d\n",
+                               ret);
+               return ret;
+       }
+       max14577->vendor_id = ((reg_data & DEVID_VENDORID_MASK) >>
+                               DEVID_VENDORID_SHIFT);
+       max14577->device_id = ((reg_data & DEVID_DEVICEID_MASK) >>
+                               DEVID_DEVICEID_SHIFT);
+       dev_info(max14577->dev, "Device ID: 0x%x, vendor: 0x%x\n",
+                       max14577->device_id, max14577->vendor_id);
+
+       ret = regmap_add_irq_chip(max14577->regmap, max14577->irq,
+                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0,
+                                 &max14577_irq_chip,
+                                 &max14577->irq_data);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+                               max14577->irq, ret);
+               return ret;
+       }
+
+       ret = mfd_add_devices(max14577->dev, -1, max14577_devs,
+                       ARRAY_SIZE(max14577_devs), NULL, 0,
+                       regmap_irq_get_domain(max14577->irq_data));
+       if (ret < 0)
+               goto err_mfd;
+
+       device_init_wakeup(max14577->dev, 1);
+
+       return 0;
+
+err_mfd:
+       regmap_del_irq_chip(max14577->irq, max14577->irq_data);
+
+       return ret;
+}
+
+static int max14577_i2c_remove(struct i2c_client *i2c)
+{
+       struct max14577 *max14577 = i2c_get_clientdata(i2c);
+
+       mfd_remove_devices(max14577->dev);
+       regmap_del_irq_chip(max14577->irq, max14577->irq_data);
+
+       return 0;
+}
+
+static const struct i2c_device_id max14577_i2c_id[] = {
+       { "max14577", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max14577_i2c_id);
+
+static int max14577_suspend(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct max14577 *max14577 = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               enable_irq_wake(max14577->irq);
+               /*
+                * MUIC IRQ must be disabled during suspend if this is
+                * a wake up source because it will be handled before
+                * resuming I2C.
+                *
+                * When device is woken up from suspend (e.g. by ADC change),
+                * an interrupt occurs before resuming I2C bus controller.
+                * Interrupt handler tries to read registers but this read
+                * will fail because I2C is still suspended.
+                */
+               disable_irq(max14577->irq);
+       }
+
+       return 0;
+}
+
+static int max14577_resume(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct max14577 *max14577 = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               disable_irq_wake(max14577->irq);
+               enable_irq(max14577->irq);
+       }
+
+       return 0;
+}
+
+static struct of_device_id max14577_dt_match[] = {
+       { .compatible = "maxim,max14577", },
+       {},
+};
+
+static SIMPLE_DEV_PM_OPS(max14577_pm, max14577_suspend, max14577_resume);
+
+static struct i2c_driver max14577_i2c_driver = {
+       .driver = {
+               .name = "max14577",
+               .owner = THIS_MODULE,
+               .pm = &max14577_pm,
+               .of_match_table = max14577_dt_match,
+       },
+       .probe = max14577_i2c_probe,
+       .remove = max14577_i2c_remove,
+       .id_table = max14577_i2c_id,
+};
+
+static int __init max14577_i2c_init(void)
+{
+       return i2c_add_driver(&max14577_i2c_driver);
+}
+subsys_initcall(max14577_i2c_init);
+
+static void __exit max14577_i2c_exit(void)
+{
+       i2c_del_driver(&max14577_i2c_driver);
+}
+module_exit(max14577_i2c_exit);
+
+MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <k.kozlowski@samsung.com>");
+MODULE_DESCRIPTION("MAXIM 14577 multi-function core driver");
+MODULE_LICENSE("GPL");
index 34520cbe8afbd6e9f0daca77f4bbde41b93697a6..f53d5823a3f73f47001cb5e6633e0b76028a8607 100644 (file)
@@ -35,7 +35,7 @@
 
 #define I2C_ADDR_RTC   (0x0C >> 1)
 
-static struct mfd_cell max77686_devs[] = {
+static const struct mfd_cell max77686_devs[] = {
        { .name = "max77686-pmic", },
        { .name = "max77686-rtc", },
        { .name = "max77686-clk", },
@@ -104,7 +104,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
        max77686->irq_gpio = pdata->irq_gpio;
        max77686->irq = i2c->irq;
 
-       max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config);
+       max77686->regmap = devm_regmap_init_i2c(i2c, &max77686_regmap_config);
        if (IS_ERR(max77686->regmap)) {
                ret = PTR_ERR(max77686->regmap);
                dev_err(max77686->dev, "Failed to allocate register map: %d\n",
index 9f92463f4f7ecaca1b005a14e6cd59f7d38deb4a..e0859987ab6bc5c078c81f3ce937170bfc8a2bee 100644 (file)
@@ -41,7 +41,7 @@
 #define I2C_ADDR_MUIC  (0x4A >> 1)
 #define I2C_ADDR_HAPTIC        (0x90 >> 1)
 
-static struct mfd_cell max77693_devs[] = {
+static const struct mfd_cell max77693_devs[] = {
        { .name = "max77693-pmic", },
        { .name = "max77693-charger", },
        { .name = "max77693-flash", },
@@ -107,6 +107,12 @@ static const struct regmap_config max77693_regmap_config = {
        .max_register = MAX77693_PMIC_REG_END,
 };
 
+static const struct regmap_config max77693_regmap_muic_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = MAX77693_MUIC_REG_END,
+};
+
 static int max77693_i2c_probe(struct i2c_client *i2c,
                              const struct i2c_device_id *id)
 {
@@ -153,7 +159,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
         * before call max77693-muic probe() function.
         */
        max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic,
-                                        &max77693_regmap_config);
+                                        &max77693_regmap_muic_config);
        if (IS_ERR(max77693->regmap_muic)) {
                ret = PTR_ERR(max77693->regmap_muic);
                dev_err(max77693->dev,
index 3bbfedc07f41c8e24d866120b64423374c629fa3..07740314b29d03acc8068dcc56addd989abca5d1 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-static struct mfd_cell max8907_cells[] = {
+static const struct mfd_cell max8907_cells[] = {
        { .name = "max8907-regulator", },
        { .name = "max8907-rtc", },
 };
index f0cc40296d8ccc50fab35f0805023bdab6ebc54f..f3faf0c45dddf36d09d4b2d05641145a7ebe13f6 100644 (file)
@@ -45,7 +45,7 @@ static struct resource touch_resources[] = {
        },
 };
 
-static struct mfd_cell touch_devs[] = {
+static const struct mfd_cell touch_devs[] = {
        {
                .name           = "max8925-touch",
                .num_resources  = 1,
@@ -63,7 +63,7 @@ static struct resource power_supply_resources[] = {
        },
 };
 
-static struct mfd_cell power_devs[] = {
+static const struct mfd_cell power_devs[] = {
        {
                .name           = "max8925-power",
                .num_resources  = 1,
@@ -81,7 +81,7 @@ static struct resource rtc_resources[] = {
        },
 };
 
-static struct mfd_cell rtc_devs[] = {
+static const struct mfd_cell rtc_devs[] = {
        {
                .name           = "max8925-rtc",
                .num_resources  = 1,
@@ -104,7 +104,7 @@ static struct resource onkey_resources[] = {
        },
 };
 
-static struct mfd_cell onkey_devs[] = {
+static const struct mfd_cell onkey_devs[] = {
        {
                .name           = "max8925-onkey",
                .num_resources  = 2,
index 791aea3e96ce27622032a0c0fd1bc52ecd69203e..be88a3bf7b857a5b19f7e9d95b1be42c7e58b2d3 100644 (file)
@@ -40,7 +40,7 @@
 #define I2C_ADDR_RTC   (0x0C >> 1)
 #define I2C_ADDR_HAPTIC        (0x90 >> 1)
 
-static struct mfd_cell max8997_devs[] = {
+static const struct mfd_cell max8997_devs[] = {
        { .name = "max8997-pmic", },
        { .name = "max8997-rtc", },
        { .name = "max8997-battery", },
@@ -133,7 +133,6 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
 }
 EXPORT_SYMBOL_GPL(max8997_update_reg);
 
-#ifdef CONFIG_OF
 /*
  * Only the common platform data elements for max8997 are parsed here from the
  * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
@@ -164,24 +163,15 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
 
        return pd;
 }
-#else
-static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
-                                       struct device *dev)
-{
-       return 0;
-}
-#endif
 
 static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
                                                const struct i2c_device_id *id)
 {
-#ifdef CONFIG_OF
-       if (i2c->dev.of_node) {
+       if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
                const struct of_device_id *match;
                match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
                return (int)match->data;
        }
-#endif
        return (int)id->driver_data;
 }
 
@@ -203,7 +193,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
        max8997->type = max8997_i2c_get_driver_data(i2c, id);
        max8997->irq = i2c->irq;
 
-       if (max8997->dev->of_node) {
+       if (IS_ENABLED(CONFIG_OF) && max8997->dev->of_node) {
                pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
                if (IS_ERR(pdata))
                        return PTR_ERR(pdata);
@@ -228,18 +218,19 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 
        max8997_irq_init(max8997);
 
-       mfd_add_devices(max8997->dev, -1, max8997_devs,
+       ret = mfd_add_devices(max8997->dev, -1, max8997_devs,
                        ARRAY_SIZE(max8997_devs),
                        NULL, 0, NULL);
+       if (ret < 0) {
+               dev_err(max8997->dev, "failed to add MFD devices %d\n", ret);
+               goto err_mfd;
+       }
 
        /*
         * TODO: enable others (flash, muic, rtc, battery, ...) and
         * check the return value
         */
 
-       if (ret < 0)
-               goto err_mfd;
-
        /* MAX8997 has a power button input. */
        device_init_wakeup(max8997->dev, pdata->wakeup);
 
index fe6332dcabee891a27daed80e3ed2525e3b1caa8..f47eaa70eae076f172f4e72977f98dfe26e680da 100644 (file)
@@ -37,7 +37,7 @@
 
 #define RTC_I2C_ADDR           (0x0c >> 1)
 
-static struct mfd_cell max8998_devs[] = {
+static const struct mfd_cell max8998_devs[] = {
        {
                .name = "max8998-pmic",
        }, {
@@ -47,7 +47,7 @@ static struct mfd_cell max8998_devs[] = {
        },
 };
 
-static struct mfd_cell lp3974_devs[] = {
+static const struct mfd_cell lp3974_devs[] = {
        {
                .name = "lp3974-pmic",
        }, {
index dbbf8ee3f592369fdd5aa968148e7aa307246580..06e64b6fcb89d66aaa7299bb1384acc26b47884b 100644 (file)
@@ -158,9 +158,6 @@ int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val)
 {
        int ret;
 
-       if (offset > MC13XXX_NUMREGS)
-               return -EINVAL;
-
        ret = regmap_read(mc13xxx->regmap, offset, val);
        dev_vdbg(mc13xxx->dev, "[0x%02x] -> 0x%06x\n", offset, *val);
 
@@ -172,7 +169,7 @@ int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val)
 {
        dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x\n", offset, val);
 
-       if (offset > MC13XXX_NUMREGS || val > 0xffffff)
+       if (val >= BIT(24))
                return -EINVAL;
 
        return regmap_write(mc13xxx->regmap, offset, val);
@@ -639,42 +636,36 @@ static inline int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx)
 }
 #endif
 
-int mc13xxx_common_init(struct mc13xxx *mc13xxx,
-               struct mc13xxx_platform_data *pdata, int irq)
+int mc13xxx_common_init(struct device *dev)
 {
+       struct mc13xxx_platform_data *pdata = dev_get_platdata(dev);
+       struct mc13xxx *mc13xxx = dev_get_drvdata(dev);
        int ret;
        u32 revision;
 
-       mc13xxx_lock(mc13xxx);
+       mc13xxx->dev = dev;
 
        ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision);
        if (ret)
-               goto err_revision;
+               return ret;
 
        mc13xxx->variant->print_revision(mc13xxx, revision);
 
        /* mask all irqs */
        ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK0, 0x00ffffff);
        if (ret)
-               goto err_mask;
+               return ret;
 
        ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK1, 0x00ffffff);
        if (ret)
-               goto err_mask;
+               return ret;
 
-       ret = request_threaded_irq(irq, NULL, mc13xxx_irq_thread,
+       ret = request_threaded_irq(mc13xxx->irq, NULL, mc13xxx_irq_thread,
                        IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx);
-
-       if (ret) {
-err_mask:
-err_revision:
-               mc13xxx_unlock(mc13xxx);
+       if (ret)
                return ret;
-       }
 
-       mc13xxx->irq = irq;
-
-       mc13xxx_unlock(mc13xxx);
+       mutex_init(&mc13xxx->lock);
 
        if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata)
                mc13xxx->flags = pdata->flags;
@@ -710,13 +701,17 @@ err_revision:
 }
 EXPORT_SYMBOL_GPL(mc13xxx_common_init);
 
-void mc13xxx_common_cleanup(struct mc13xxx *mc13xxx)
+int mc13xxx_common_exit(struct device *dev)
 {
+       struct mc13xxx *mc13xxx = dev_get_drvdata(dev);
+
        free_irq(mc13xxx->irq, mc13xxx);
+       mfd_remove_devices(dev);
+       mutex_destroy(&mc13xxx->lock);
 
-       mfd_remove_devices(mc13xxx->dev);
+       return 0;
 }
-EXPORT_SYMBOL_GPL(mc13xxx_common_cleanup);
+EXPORT_SYMBOL_GPL(mc13xxx_common_exit);
 
 MODULE_DESCRIPTION("Core driver for Freescale MC13XXX PMIC");
 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
index 898bd335cd8ee99d7d8a2c233ef455801941ff30..ae3addb153a2e825f260959e1a52c93cc42051ef 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/mutex.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/mc13xxx.h>
 #include <linux/of.h>
@@ -60,7 +59,6 @@ static int mc13xxx_i2c_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
 {
        struct mc13xxx *mc13xxx;
-       struct mc13xxx_platform_data *pdata = dev_get_platdata(&client->dev);
        int ret;
 
        mc13xxx = devm_kzalloc(&client->dev, sizeof(*mc13xxx), GFP_KERNEL);
@@ -69,15 +67,13 @@ static int mc13xxx_i2c_probe(struct i2c_client *client,
 
        dev_set_drvdata(&client->dev, mc13xxx);
 
-       mc13xxx->dev = &client->dev;
-       mutex_init(&mc13xxx->lock);
+       mc13xxx->irq = client->irq;
 
        mc13xxx->regmap = devm_regmap_init_i2c(client,
                                               &mc13xxx_regmap_i2c_config);
        if (IS_ERR(mc13xxx->regmap)) {
                ret = PTR_ERR(mc13xxx->regmap);
-               dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
-                               ret);
+               dev_err(&client->dev, "Failed to initialize regmap: %d\n", ret);
                return ret;
        }
 
@@ -89,18 +85,12 @@ static int mc13xxx_i2c_probe(struct i2c_client *client,
                mc13xxx->variant = (void *)id->driver_data;
        }
 
-       ret = mc13xxx_common_init(mc13xxx, pdata, client->irq);
-
-       return ret;
+       return mc13xxx_common_init(&client->dev);
 }
 
 static int mc13xxx_i2c_remove(struct i2c_client *client)
 {
-       struct mc13xxx *mc13xxx = dev_get_drvdata(&client->dev);
-
-       mc13xxx_common_cleanup(mc13xxx);
-
-       return 0;
+       return mc13xxx_common_exit(&client->dev);
 }
 
 static struct i2c_driver mc13xxx_i2c_driver = {
index 5f14ef6693c22abd073b62ea6114dab2b09d76b8..38ab67829791b1b8d7b5c2d33d24ac66999f2a3f 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/mutex.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/mc13xxx.h>
@@ -129,27 +128,24 @@ static struct regmap_bus regmap_mc13xxx_bus = {
 static int mc13xxx_spi_probe(struct spi_device *spi)
 {
        struct mc13xxx *mc13xxx;
-       struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev);
        int ret;
 
        mc13xxx = devm_kzalloc(&spi->dev, sizeof(*mc13xxx), GFP_KERNEL);
        if (!mc13xxx)
                return -ENOMEM;
 
-       spi_set_drvdata(spi, mc13xxx);
+       dev_set_drvdata(&spi->dev, mc13xxx);
+
        spi->mode = SPI_MODE_0 | SPI_CS_HIGH;
 
-       mc13xxx->dev = &spi->dev;
-       mutex_init(&mc13xxx->lock);
+       mc13xxx->irq = spi->irq;
 
        mc13xxx->regmap = devm_regmap_init(&spi->dev, &regmap_mc13xxx_bus,
                                           &spi->dev,
                                           &mc13xxx_regmap_spi_config);
        if (IS_ERR(mc13xxx->regmap)) {
                ret = PTR_ERR(mc13xxx->regmap);
-               dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
-                               ret);
-               spi_set_drvdata(spi, NULL);
+               dev_err(&spi->dev, "Failed to initialize regmap: %d\n", ret);
                return ret;
        }
 
@@ -164,16 +160,12 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
                mc13xxx->variant = (void *)id_entry->driver_data;
        }
 
-       return mc13xxx_common_init(mc13xxx, pdata, spi->irq);
+       return mc13xxx_common_init(&spi->dev);
 }
 
 static int mc13xxx_spi_remove(struct spi_device *spi)
 {
-       struct mc13xxx *mc13xxx = spi_get_drvdata(spi);
-
-       mc13xxx_common_cleanup(mc13xxx);
-
-       return 0;
+       return mc13xxx_common_exit(&spi->dev);
 }
 
 static struct spi_driver mc13xxx_spi_driver = {
index 460ec5c7b18c1f14597244fbfad68efb2f716fe5..ae7f1659f5d1efedd82bd68af21faab44b4c0fa0 100644 (file)
@@ -43,9 +43,7 @@ struct mc13xxx {
        int adcflags;
 };
 
-int mc13xxx_common_init(struct mc13xxx *mc13xxx,
-               struct mc13xxx_platform_data *pdata, int irq);
-
-void mc13xxx_common_cleanup(struct mc13xxx *mc13xxx);
+int mc13xxx_common_init(struct device *dev);
+int mc13xxx_common_exit(struct device *dev);
 
 #endif /* __DRIVERS_MFD_MC13XXX_H */
index 142650fdc0582e1d25f99480e4a2fb13e1e9bd23..90b630ccc8bc65fa7381439cd190274834c50153 100644 (file)
@@ -121,22 +121,22 @@ static u64 usbhs_dmamask = DMA_BIT_MASK(32);
 
 static inline void usbhs_write(void __iomem *base, u32 reg, u32 val)
 {
-       __raw_writel(val, base + reg);
+       writel_relaxed(val, base + reg);
 }
 
 static inline u32 usbhs_read(void __iomem *base, u32 reg)
 {
-       return __raw_readl(base + reg);
+       return readl_relaxed(base + reg);
 }
 
 static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val)
 {
-       __raw_writeb(val, base + reg);
+       writeb_relaxed(val, base + reg);
 }
 
 static inline u8 usbhs_readb(void __iomem *base, u8 reg)
 {
-       return __raw_readb(base + reg);
+       return readb_relaxed(base + reg);
 }
 
 /*-------------------------------------------------------------------------*/
index 0d946ae14453380e4abca019a09519627309c5b6..5ee50f779ef60a86c1ab5e07782186e228054024 100644 (file)
@@ -121,22 +121,22 @@ static DEFINE_SPINLOCK(tll_lock); /* serialize access to tll_dev */
 
 static inline void usbtll_write(void __iomem *base, u32 reg, u32 val)
 {
-       __raw_writel(val, base + reg);
+       writel_relaxed(val, base + reg);
 }
 
 static inline u32 usbtll_read(void __iomem *base, u32 reg)
 {
-       return __raw_readl(base + reg);
+       return readl_relaxed(base + reg);
 }
 
 static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val)
 {
-       __raw_writeb(val, base + reg);
+       writeb_relaxed(val, base + reg);
 }
 
 static inline u8 usbtll_readb(void __iomem *base, u8 reg)
 {
-       return __raw_readb(base + reg);
+       return readb_relaxed(base + reg);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -333,21 +333,17 @@ int omap_tll_init(struct usbhs_omap_platform_data *pdata)
        unsigned reg;
        struct usbtll_omap *tll;
 
-       spin_lock(&tll_lock);
-
-       if (!tll_dev) {
-               spin_unlock(&tll_lock);
+       if (!tll_dev)
                return -ENODEV;
-       }
 
-       tll = dev_get_drvdata(tll_dev);
+       pm_runtime_get_sync(tll_dev);
 
+       spin_lock(&tll_lock);
+       tll = dev_get_drvdata(tll_dev);
        needs_tll = false;
        for (i = 0; i < tll->nch; i++)
                needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]);
 
-       pm_runtime_get_sync(tll_dev);
-
        if (needs_tll) {
                void __iomem *base = tll->base;
 
@@ -398,9 +394,8 @@ int omap_tll_init(struct usbhs_omap_platform_data *pdata)
                }
        }
 
-       pm_runtime_put_sync(tll_dev);
-
        spin_unlock(&tll_lock);
+       pm_runtime_put_sync(tll_dev);
 
        return 0;
 }
@@ -411,17 +406,14 @@ int omap_tll_enable(struct usbhs_omap_platform_data *pdata)
        int i;
        struct usbtll_omap *tll;
 
-       spin_lock(&tll_lock);
-
-       if (!tll_dev) {
-               spin_unlock(&tll_lock);
+       if (!tll_dev)
                return -ENODEV;
-       }
-
-       tll = dev_get_drvdata(tll_dev);
 
        pm_runtime_get_sync(tll_dev);
 
+       spin_lock(&tll_lock);
+       tll = dev_get_drvdata(tll_dev);
+
        for (i = 0; i < tll->nch; i++) {
                if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
                        int r;
@@ -448,13 +440,10 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
        int i;
        struct usbtll_omap *tll;
 
-       spin_lock(&tll_lock);
-
-       if (!tll_dev) {
-               spin_unlock(&tll_lock);
+       if (!tll_dev)
                return -ENODEV;
-       }
 
+       spin_lock(&tll_lock);
        tll = dev_get_drvdata(tll_dev);
 
        for (i = 0; i < tll->nch; i++) {
@@ -464,9 +453,8 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
                }
        }
 
-       pm_runtime_put_sync(tll_dev);
-
        spin_unlock(&tll_lock);
+       pm_runtime_put_sync(tll_dev);
 
        return 0;
 }
index 346330176afcd81ba9f6a294420db761e60ab908..df276ad9f40bfb32639c78b28ad7f2155e1f749f 100644 (file)
@@ -74,7 +74,7 @@ static struct deepsleep_control_data deepsleep_data[] = {
 #define EXT_PWR_REQ            \
        (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL)
 
-static struct mfd_cell rc5t583_subdevs[] = {
+static const struct mfd_cell rc5t583_subdevs[] = {
        {.name = "rc5t583-gpio",},
        {.name = "rc5t583-regulator",},
        {.name = "rc5t583-rtc",      },
index 21b7bef73507cc969ae49074873f47b64b3ebe99..d346146249a2d387dbb5485c8517b5e662fac72a 100644 (file)
@@ -56,7 +56,7 @@ static struct resource rdc321x_gpio_resources[] = {
        }
 };
 
-static struct mfd_cell rdc321x_sb_cells[] = {
+static const struct mfd_cell rdc321x_sb_cells[] = {
        {
                .name           = "rdc321x-wdt",
                .resources      = rdc321x_wdt_resource,
@@ -96,7 +96,7 @@ static void rdc321x_sb_remove(struct pci_dev *pdev)
        mfd_remove_devices(&pdev->dev);
 }
 
-static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = {
+static const struct pci_device_id rdc321x_sb_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
        {}
 };
index a1830986eeb71006b9c693e0aab1bb5e25d98e81..c8f345f7e9a2b574c69d5c2d47fa3dbcf1390993 100644 (file)
@@ -55,7 +55,7 @@ static struct resource retu_pwrbutton_res[] = {
        },
 };
 
-static struct mfd_cell retu_devs[] = {
+static const struct mfd_cell retu_devs[] = {
        {
                .name           = "retu-wdt"
        },
@@ -94,7 +94,7 @@ static struct resource tahvo_usb_res[] = {
        },
 };
 
-static struct mfd_cell tahvo_devs[] = {
+static const struct mfd_cell tahvo_devs[] = {
        {
                .name           = "tahvo-usb",
                .resources      = tahvo_usb_res,
@@ -122,7 +122,7 @@ static const struct retu_data {
        char                    *chip_name;
        char                    *companion_name;
        struct regmap_irq_chip  *irq_chip;
-       struct mfd_cell         *children;
+       const struct mfd_cell   *children;
        int                     nchildren;
 } retu_data[] = {
        [0] = {
index 52801351864d684e094ec59b60ec797cf4ffcc27..fdd34c883d868b96df11064b86933ab9c0172c35 100644 (file)
@@ -49,8 +49,8 @@ static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr)
 
 static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
 {
-       u32 reg1;
-       u8 reg3;
+       u32 reg1 = 0;
+       u8 reg3 = 0;
 
        rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg1);
        dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
@@ -71,7 +71,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
 
 static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
 {
-       u32 reg;
+       u32 reg = 0;
 
        rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
        dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
@@ -191,24 +191,25 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)
                        BPP_LDO_POWB, BPP_LDO_SUSPEND);
 }
 
-static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+static int rtl8411_do_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage,
+               int bpp_tuned18_shift, int bpp_asic_1v8)
 {
        u8 mask, val;
        int err;
 
-       mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
+       mask = (BPP_REG_TUNED18 << bpp_tuned18_shift) | BPP_PAD_MASK;
        if (voltage == OUTPUT_3V3) {
                err = rtsx_pci_write_register(pcr,
                                SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
                if (err < 0)
                        return err;
-               val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3;
+               val = (BPP_ASIC_3V3 << bpp_tuned18_shift) | BPP_PAD_3V3;
        } else if (voltage == OUTPUT_1V8) {
                err = rtsx_pci_write_register(pcr,
                                SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
                if (err < 0)
                        return err;
-               val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8;
+               val = (bpp_asic_1v8 << bpp_tuned18_shift) | BPP_PAD_1V8;
        } else {
                return -EINVAL;
        }
@@ -216,6 +217,18 @@ static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
        return rtsx_pci_write_register(pcr, LDO_CTL, mask, val);
 }
 
+static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+       return rtl8411_do_switch_output_voltage(pcr, voltage,
+                       BPP_TUNED18_SHIFT_8411, BPP_ASIC_1V8);
+}
+
+static int rtl8402_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+       return rtl8411_do_switch_output_voltage(pcr, voltage,
+                       BPP_TUNED18_SHIFT_8402, BPP_ASIC_2V0);
+}
+
 static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
 {
        unsigned int card_exist;
@@ -295,6 +308,22 @@ static const struct pcr_ops rtl8411_pcr_ops = {
        .force_power_down = rtl8411_force_power_down,
 };
 
+static const struct pcr_ops rtl8402_pcr_ops = {
+       .fetch_vendor_settings = rtl8411_fetch_vendor_settings,
+       .extra_init_hw = rtl8411_extra_init_hw,
+       .optimize_phy = NULL,
+       .turn_on_led = rtl8411_turn_on_led,
+       .turn_off_led = rtl8411_turn_off_led,
+       .enable_auto_blink = rtl8411_enable_auto_blink,
+       .disable_auto_blink = rtl8411_disable_auto_blink,
+       .card_power_on = rtl8411_card_power_on,
+       .card_power_off = rtl8411_card_power_off,
+       .switch_output_voltage = rtl8402_switch_output_voltage,
+       .cd_deglitch = rtl8411_cd_deglitch,
+       .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
+       .force_power_down = rtl8411_force_power_down,
+};
+
 static const struct pcr_ops rtl8411b_pcr_ops = {
        .fetch_vendor_settings = rtl8411b_fetch_vendor_settings,
        .extra_init_hw = rtl8411b_extra_init_hw,
@@ -441,12 +470,10 @@ static const u32 rtl8411b_qfn48_ms_pull_ctl_disable_tbl[] = {
        0,
 };
 
-void rtl8411_init_params(struct rtsx_pcr *pcr)
+static void rtl8411_init_common_params(struct rtsx_pcr *pcr)
 {
        pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
        pcr->num_slots = 2;
-       pcr->ops = &rtl8411_pcr_ops;
-
        pcr->flags = 0;
        pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
        pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
@@ -454,47 +481,29 @@ void rtl8411_init_params(struct rtsx_pcr *pcr)
        pcr->aspm_en = ASPM_L1_EN;
        pcr->tx_initial_phase = SET_CLOCK_PHASE(23, 7, 14);
        pcr->rx_initial_phase = SET_CLOCK_PHASE(4, 3, 10);
-
        pcr->ic_version = rtl8411_get_ic_version(pcr);
-       pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl;
-       pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl;
-       pcr->ms_pull_ctl_enable_tbl = rtl8411_ms_pull_ctl_enable_tbl;
-       pcr->ms_pull_ctl_disable_tbl = rtl8411_ms_pull_ctl_disable_tbl;
+}
+
+void rtl8411_init_params(struct rtsx_pcr *pcr)
+{
+       rtl8411_init_common_params(pcr);
+       pcr->ops = &rtl8411_pcr_ops;
+       set_pull_ctrl_tables(pcr, rtl8411);
 }
 
 void rtl8411b_init_params(struct rtsx_pcr *pcr)
 {
-       pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
-       pcr->num_slots = 2;
+       rtl8411_init_common_params(pcr);
        pcr->ops = &rtl8411b_pcr_ops;
+       if (rtl8411b_is_qfn48(pcr))
+               set_pull_ctrl_tables(pcr, rtl8411b_qfn48);
+       else
+               set_pull_ctrl_tables(pcr, rtl8411b_qfn64);
+}
 
-       pcr->flags = 0;
-       pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
-       pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
-       pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
-       pcr->aspm_en = ASPM_L1_EN;
-       pcr->tx_initial_phase = SET_CLOCK_PHASE(23, 7, 14);
-       pcr->rx_initial_phase = SET_CLOCK_PHASE(4, 3, 10);
-
-       pcr->ic_version = rtl8411_get_ic_version(pcr);
-
-       if (rtl8411b_is_qfn48(pcr)) {
-               pcr->sd_pull_ctl_enable_tbl =
-                       rtl8411b_qfn48_sd_pull_ctl_enable_tbl;
-               pcr->sd_pull_ctl_disable_tbl =
-                       rtl8411b_qfn48_sd_pull_ctl_disable_tbl;
-               pcr->ms_pull_ctl_enable_tbl =
-                       rtl8411b_qfn48_ms_pull_ctl_enable_tbl;
-               pcr->ms_pull_ctl_disable_tbl =
-                       rtl8411b_qfn48_ms_pull_ctl_disable_tbl;
-       } else {
-               pcr->sd_pull_ctl_enable_tbl =
-                       rtl8411b_qfn64_sd_pull_ctl_enable_tbl;
-               pcr->sd_pull_ctl_disable_tbl =
-                       rtl8411b_qfn64_sd_pull_ctl_disable_tbl;
-               pcr->ms_pull_ctl_enable_tbl =
-                       rtl8411b_qfn64_ms_pull_ctl_enable_tbl;
-               pcr->ms_pull_ctl_disable_tbl =
-                       rtl8411b_qfn64_ms_pull_ctl_disable_tbl;
-       }
+void rtl8402_init_params(struct rtsx_pcr *pcr)
+{
+       rtl8411_init_common_params(pcr);
+       pcr->ops = &rtl8402_pcr_ops;
+       set_pull_ctrl_tables(pcr, rtl8411);
 }
index 705698fd2c7ed0f8f5e4fcada7b060627352be05..1d15735f9ef930ed18e384b1c63b7deb1fd42981 100644 (file)
@@ -50,13 +50,14 @@ static struct mfd_cell rtsx_pcr_cells[] = {
        },
 };
 
-static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_ids) = {
+static const struct pci_device_id rtsx_pci_ids[] = {
        { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 },
        { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 },
        { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 },
        { PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 },
        { PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 },
        { PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+       { PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
        { 0, }
 };
 
@@ -1061,6 +1062,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
        case 0x5287:
                rtl8411b_init_params(pcr);
                break;
+
+       case 0x5286:
+               rtl8402_init_params(pcr);
+               break;
        }
 
        dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n",
index 947e79b05cebfd211590c93a53cec7f58182f907..07e4c2ebf05a23dbd5543ce220d41a00eccf3956 100644 (file)
@@ -30,6 +30,7 @@
 void rts5209_init_params(struct rtsx_pcr *pcr);
 void rts5229_init_params(struct rtsx_pcr *pcr);
 void rtl8411_init_params(struct rtsx_pcr *pcr);
+void rtl8402_init_params(struct rtsx_pcr *pcr);
 void rts5227_init_params(struct rtsx_pcr *pcr);
 void rts5249_init_params(struct rtsx_pcr *pcr);
 void rtl8411b_init_params(struct rtsx_pcr *pcr);
@@ -63,4 +64,12 @@ static inline u8 map_sd_drive(int idx)
 #define rtl8411_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x07)
 #define rtl8411b_reg_to_sd30_drive_sel_3v3(reg)        ((reg) & 0x03)
 
+#define set_pull_ctrl_tables(pcr, __device)                            \
+do {                                                                   \
+       pcr->sd_pull_ctl_enable_tbl  = __device##_sd_pull_ctl_enable_tbl;  \
+       pcr->sd_pull_ctl_disable_tbl = __device##_sd_pull_ctl_disable_tbl; \
+       pcr->ms_pull_ctl_enable_tbl  = __device##_ms_pull_ctl_enable_tbl;  \
+       pcr->ms_pull_ctl_disable_tbl = __device##_ms_pull_ctl_disable_tbl; \
+} while (0)
+
 #endif
index 54cc25546592c7c7a1ba113104ca96fa5cacab83..e4671088f075ab0d65c2431c20eedec1acf2c281 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/mfd/samsung/s5m8767.h>
 #include <linux/regmap.h>
 
-static struct mfd_cell s5m8751_devs[] = {
+static const struct mfd_cell s5m8751_devs[] = {
        {
                .name = "s5m8751-pmic",
        }, {
@@ -41,7 +41,7 @@ static struct mfd_cell s5m8751_devs[] = {
        },
 };
 
-static struct mfd_cell s5m8763_devs[] = {
+static const struct mfd_cell s5m8763_devs[] = {
        {
                .name = "s5m8763-pmic",
        }, {
@@ -51,15 +51,17 @@ static struct mfd_cell s5m8763_devs[] = {
        },
 };
 
-static struct mfd_cell s5m8767_devs[] = {
+static const struct mfd_cell s5m8767_devs[] = {
        {
                .name = "s5m8767-pmic",
        }, {
                .name = "s5m-rtc",
-       },
+       }, {
+               .name = "s5m8767-clk",
+       }
 };
 
-static struct mfd_cell s2mps11_devs[] = {
+static const struct mfd_cell s2mps11_devs[] = {
        {
                .name = "s2mps11-pmic",
        }, {
@@ -134,12 +136,12 @@ static bool s5m8763_volatile(struct device *dev, unsigned int reg)
        }
 }
 
-static struct regmap_config sec_regmap_config = {
+static const struct regmap_config sec_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 };
 
-static struct regmap_config s2mps11_regmap_config = {
+static const struct regmap_config s2mps11_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 
@@ -148,7 +150,7 @@ static struct regmap_config s2mps11_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
-static struct regmap_config s5m8763_regmap_config = {
+static const struct regmap_config s5m8763_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 
@@ -157,7 +159,7 @@ static struct regmap_config s5m8763_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
-static struct regmap_config s5m8767_regmap_config = {
+static const struct regmap_config s5m8767_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 
@@ -204,7 +206,7 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
 static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
                                        struct device *dev)
 {
-       return 0;
+       return NULL;
 }
 #endif
 
@@ -323,6 +325,8 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        if (ret)
                goto err;
 
+       device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
+
        return ret;
 
 err:
@@ -341,6 +345,43 @@ static int sec_pmic_remove(struct i2c_client *i2c)
        return 0;
 }
 
+static int sec_pmic_suspend(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               enable_irq_wake(sec_pmic->irq);
+               /*
+                * PMIC IRQ must be disabled during suspend for RTC alarm
+                * to work properly.
+                * When device is woken up from suspend by RTC Alarm, an
+                * interrupt occurs before resuming I2C bus controller.
+                * The interrupt is handled by regmap_irq_thread which tries
+                * to read RTC registers. This read fails (I2C is still
+                * suspended) and RTC Alarm interrupt is disabled.
+                */
+               disable_irq(sec_pmic->irq);
+       }
+
+       return 0;
+}
+
+static int sec_pmic_resume(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               disable_irq_wake(sec_pmic->irq);
+               enable_irq(sec_pmic->irq);
+       }
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
+
 static const struct i2c_device_id sec_pmic_id[] = {
        { "sec_pmic", 0 },
        { }
@@ -351,6 +392,7 @@ static struct i2c_driver sec_pmic_driver = {
        .driver = {
                   .name = "sec_pmic",
                   .owner = THIS_MODULE,
+                  .pm = &sec_pmic_pm_ops,
                   .of_match_table = of_match_ptr(sec_dt_match),
        },
        .probe = sec_pmic_probe,
index b441b1be27cbe9165bd66f94e26c9f750125e665..4de494f51d401b3d85544633621091d9e7cceff6 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/mfd/samsung/s5m8763.h>
 #include <linux/mfd/samsung/s5m8767.h>
 
-static struct regmap_irq s2mps11_irqs[] = {
+static const struct regmap_irq s2mps11_irqs[] = {
        [S2MPS11_IRQ_PWRONF] = {
                .reg_offset = 0,
                .mask = S2MPS11_IRQ_PWRONF_MASK,
@@ -90,7 +90,7 @@ static struct regmap_irq s2mps11_irqs[] = {
 };
 
 
-static struct regmap_irq s5m8767_irqs[] = {
+static const struct regmap_irq s5m8767_irqs[] = {
        [S5M8767_IRQ_PWRR] = {
                .reg_offset = 0,
                .mask = S5M8767_IRQ_PWRR_MASK,
@@ -161,7 +161,7 @@ static struct regmap_irq s5m8767_irqs[] = {
        },
 };
 
-static struct regmap_irq s5m8763_irqs[] = {
+static const struct regmap_irq s5m8763_irqs[] = {
        [S5M8763_IRQ_DCINF] = {
                .reg_offset = 0,
                .mask = S5M8763_IRQ_DCINF_MASK,
@@ -236,7 +236,7 @@ static struct regmap_irq s5m8763_irqs[] = {
        },
 };
 
-static struct regmap_irq_chip s2mps11_irq_chip = {
+static const struct regmap_irq_chip s2mps11_irq_chip = {
        .name = "s2mps11",
        .irqs = s2mps11_irqs,
        .num_irqs = ARRAY_SIZE(s2mps11_irqs),
@@ -246,7 +246,7 @@ static struct regmap_irq_chip s2mps11_irq_chip = {
        .ack_base = S2MPS11_REG_INT1,
 };
 
-static struct regmap_irq_chip s5m8767_irq_chip = {
+static const struct regmap_irq_chip s5m8767_irq_chip = {
        .name = "s5m8767",
        .irqs = s5m8767_irqs,
        .num_irqs = ARRAY_SIZE(s5m8767_irqs),
@@ -256,7 +256,7 @@ static struct regmap_irq_chip s5m8767_irq_chip = {
        .ack_base = S5M8767_REG_INT1,
 };
 
-static struct regmap_irq_chip s5m8763_irq_chip = {
+static const struct regmap_irq_chip s5m8763_irq_chip = {
        .name = "s5m8763",
        .irqs = s5m8763_irqs,
        .num_irqs = ARRAY_SIZE(s5m8763_irqs),
index c2c8c91c6c7b3188180301e85c6a4ce5ffff0c77..e7dc441a8f8ac057392de6b565fc815fd9ad22f4 100644 (file)
@@ -1710,7 +1710,7 @@ static int sm501_plat_remove(struct platform_device *dev)
        return 0;
 }
 
-static DEFINE_PCI_DEVICE_TABLE(sm501_pci_tbl) = {
+static const struct pci_device_id sm501_pci_tbl[] = {
        { 0x126f, 0x0501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
        { 0, },
 };
index 102a228442979abcaf18d2de2e2293914c0082b1..b78942ed4c6785d50b632bb9d0ad36638dea1c23 100644 (file)
 
 #define SSBI_TIMEOUT_US                        100
 
+enum ssbi_controller_type {
+       MSM_SBI_CTRL_SSBI = 0,
+       MSM_SBI_CTRL_SSBI2,
+       MSM_SBI_CTRL_PMIC_ARBITER,
+};
+
 struct ssbi {
        struct device           *slave;
        void __iomem            *base;
        spinlock_t              lock;
        enum ssbi_controller_type controller_type;
        int (*read)(struct ssbi *, u16 addr, u8 *buf, int len);
-       int (*write)(struct ssbi *, u16 addr, u8 *buf, int len);
+       int (*write)(struct ssbi *, u16 addr, const u8 *buf, int len);
 };
 
 #define to_ssbi(dev)   platform_get_drvdata(to_platform_device(dev))
@@ -140,7 +146,7 @@ err:
 }
 
 static int
-ssbi_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
+ssbi_write_bytes(struct ssbi *ssbi, u16 addr, const u8 *buf, int len)
 {
        int ret = 0;
 
@@ -217,7 +223,7 @@ err:
 }
 
 static int
-ssbi_pa_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
+ssbi_pa_write_bytes(struct ssbi *ssbi, u16 addr, const u8 *buf, int len)
 {
        u32 cmd;
        int ret = 0;
@@ -249,7 +255,7 @@ int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
 }
 EXPORT_SYMBOL_GPL(ssbi_read);
 
-int ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
+int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len)
 {
        struct ssbi *ssbi = to_ssbi(dev);
        unsigned long flags;
@@ -311,7 +317,7 @@ static int ssbi_probe(struct platform_device *pdev)
        return of_platform_populate(np, NULL, NULL, &pdev->dev);
 }
 
-static struct of_device_id ssbi_match_table[] = {
+static const struct of_device_id ssbi_match_table[] = {
        { .compatible = "qcom,ssbi" },
        {}
 };
index 65c6fa671acb27a67496b3b9277aa4919942dc89..5b72db07d9dea274f78af6604420252305205974 100644 (file)
@@ -339,7 +339,7 @@ static int sta2x11_mfd_platform_probe(struct platform_device *dev,
        regmap_config->cache_type = REGCACHE_NONE;
        mfd->regmap[index] = devm_regmap_init_mmio(&dev->dev, mfd->regs[index],
                                                   regmap_config);
-       WARN_ON(!mfd->regmap[index]);
+       WARN_ON(IS_ERR(mfd->regmap[index]));
 
        return 0;
 }
@@ -529,7 +529,7 @@ static int sta2x11_mfd_resume(struct pci_dev *pdev)
 {
        int err;
 
-       pci_set_power_state(pdev, 0);
+       pci_set_power_state(pdev, PCI_D0);
        err = pci_enable_device(pdev);
        if (err)
                return err;
@@ -642,7 +642,7 @@ err_disable:
        return err;
 }
 
-static DEFINE_PCI_DEVICE_TABLE(sta2x11_mfd_tbl) = {
+static const struct pci_device_id sta2x11_mfd_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)},
        {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIC)},
        {0,},
index fff63a41862cf6bbb4acfac38496447a4137ad0a..42ccd05445133444e52be15c4d380de7b4915539 100644 (file)
@@ -297,14 +297,14 @@ static struct resource stmpe_gpio_resources[] = {
        },
 };
 
-static struct mfd_cell stmpe_gpio_cell = {
+static const struct mfd_cell stmpe_gpio_cell = {
        .name           = "stmpe-gpio",
        .of_compatible  = "st,stmpe-gpio",
        .resources      = stmpe_gpio_resources,
        .num_resources  = ARRAY_SIZE(stmpe_gpio_resources),
 };
 
-static struct mfd_cell stmpe_gpio_cell_noirq = {
+static const struct mfd_cell stmpe_gpio_cell_noirq = {
        .name           = "stmpe-gpio",
        .of_compatible  = "st,stmpe-gpio",
        /* gpio cell resources consist of an irq only so no resources here */
@@ -325,7 +325,7 @@ static struct resource stmpe_keypad_resources[] = {
        },
 };
 
-static struct mfd_cell stmpe_keypad_cell = {
+static const struct mfd_cell stmpe_keypad_cell = {
        .name           = "stmpe-keypad",
        .of_compatible  = "st,stmpe-keypad",
        .resources      = stmpe_keypad_resources,
@@ -409,7 +409,7 @@ static struct resource stmpe_ts_resources[] = {
        },
 };
 
-static struct mfd_cell stmpe_ts_cell = {
+static const struct mfd_cell stmpe_ts_cell = {
        .name           = "stmpe-ts",
        .of_compatible  = "st,stmpe-ts",
        .resources      = stmpe_ts_resources,
@@ -1064,7 +1064,7 @@ static int stmpe_chip_init(struct stmpe *stmpe)
        return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
 }
 
-static int stmpe_add_device(struct stmpe *stmpe, struct mfd_cell *cell)
+static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell)
 {
        return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
                               NULL, stmpe->irq_base, stmpe->domain);
index ff2b09ba8797cfc214d36fada42efe1f1b64a807..6639f1b0fef50525a6292a9cce9984dd7c05c836 100644 (file)
@@ -38,7 +38,7 @@ static inline void stmpe_dump_bytes(const char *str, const void *buf,
  *             enable and altfunc callbacks
  */
 struct stmpe_variant_block {
-       struct mfd_cell         *cell;
+       const struct mfd_cell   *cell;
        int                     irq;
        enum stmpe_block        block;
 };
index 87ea51dc6234a243021bce1682a213856c49128b..2cf636c267d9413f77e39d787b6a47496ce1859e 100644 (file)
@@ -155,7 +155,7 @@ static struct resource keypad_resources[] = {
        },
 };
 
-static struct mfd_cell tc3589x_dev_gpio[] = {
+static const struct mfd_cell tc3589x_dev_gpio[] = {
        {
                .name           = "tc3589x-gpio",
                .num_resources  = ARRAY_SIZE(gpio_resources),
@@ -164,7 +164,7 @@ static struct mfd_cell tc3589x_dev_gpio[] = {
        },
 };
 
-static struct mfd_cell tc3589x_dev_keypad[] = {
+static const struct mfd_cell tc3589x_dev_keypad[] = {
        {
                .name           = "tc3589x-keypad",
                .num_resources  = ARRAY_SIZE(keypad_resources),
index acd0f3a41044a5171cc0cfde9d03ad693fa9f48c..591a331d8d83b147fbc10fa23351d61a05aeaf9e 100644 (file)
@@ -126,7 +126,7 @@ static struct tmio_mmc_data tc6387xb_mmc_data = {
 
 /*--------------------------------------------------------------------------*/
 
-static struct mfd_cell tc6387xb_cells[] = {
+static const struct mfd_cell tc6387xb_cells[] = {
        [TC6387XB_CELL_MMC] = {
                .name = "tmio-mmc",
                .enable = tc6387xb_mmc_enable,
index 88718abfb9ba0169090201e8fc04037ea4f32854..d4e860413bb54e1af55409dd7c8dc29e47747b02 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/sched.h>
 
 #include <linux/mfd/ti_am335x_tscadc.h>
 
@@ -48,32 +49,79 @@ static const struct regmap_config tscadc_regmap_config = {
        .val_bits = 32,
 };
 
-void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc)
+void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val)
 {
-       tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
+       unsigned long flags;
+
+       spin_lock_irqsave(&tsadc->reg_lock, flags);
+       tsadc->reg_se_cache = val;
+       if (tsadc->adc_waiting)
+               wake_up(&tsadc->reg_se_wait);
+       else if (!tsadc->adc_in_use)
+               tscadc_writel(tsadc, REG_SE, val);
+
+       spin_unlock_irqrestore(&tsadc->reg_lock, flags);
+}
+EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache);
+
+static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tsadc)
+{
+       DEFINE_WAIT(wait);
+       u32 reg;
+
+       /*
+        * disable TSC steps so it does not run while the ADC is using it. If
+        * write 0 while it is running (it just started or was already running)
+        * then it completes all steps that were enabled and stops then.
+        */
+       tscadc_writel(tsadc, REG_SE, 0);
+       reg = tscadc_readl(tsadc, REG_ADCFSM);
+       if (reg & SEQ_STATUS) {
+               tsadc->adc_waiting = true;
+               prepare_to_wait(&tsadc->reg_se_wait, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               spin_unlock_irq(&tsadc->reg_lock);
+
+               schedule();
+
+               spin_lock_irq(&tsadc->reg_lock);
+               finish_wait(&tsadc->reg_se_wait, &wait);
+
+               reg = tscadc_readl(tsadc, REG_ADCFSM);
+               WARN_ON(reg & SEQ_STATUS);
+               tsadc->adc_waiting = false;
+       }
+       tsadc->adc_in_use = true;
+}
+
+void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val)
+{
+       spin_lock_irq(&tsadc->reg_lock);
+       am335x_tscadc_need_adc(tsadc);
+
+       tscadc_writel(tsadc, REG_SE, val);
+       spin_unlock_irq(&tsadc->reg_lock);
 }
-EXPORT_SYMBOL_GPL(am335x_tsc_se_update);
+EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once);
 
-void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
+void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tsadc)
 {
        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);
+       tsadc->adc_in_use = false;
+       tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
        spin_unlock_irqrestore(&tsadc->reg_lock, flags);
 }
-EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
+EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done);
 
 void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
 {
        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);
+       tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
        spin_unlock_irqrestore(&tsadc->reg_lock, flags);
 }
 EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
@@ -181,6 +229,8 @@ static      int ti_tscadc_probe(struct platform_device *pdev)
        }
 
        spin_lock_init(&tscadc->reg_lock);
+       init_waitqueue_head(&tscadc->reg_se_wait);
+
        pm_runtime_enable(&pdev->dev);
        pm_runtime_get_sync(&pdev->dev);
 
@@ -302,7 +352,6 @@ static int tscadc_resume(struct device *dev)
 
        if (tscadc_dev->tsc_cell != -1)
                tscadc_idle_config(tscadc_dev);
-       am335x_tsc_se_update(tscadc_dev);
        restore = tscadc_readl(tscadc_dev, REG_CTRL);
        tscadc_writel(tscadc_dev, REG_CTRL,
                        (restore | CNTRLREG_TSCSSENB));
index dbb34f94e5e3fce2e0df7f18097930558069af2f..2bc5cfb852042cd5e41e240cb5ce0662ebd0698f 100644 (file)
@@ -374,7 +374,7 @@ static const struct resource timberdale_dma_resources[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg0[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg0[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -431,7 +431,7 @@ static struct mfd_cell timberdale_cells_bar0_cfg0[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg1[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg1[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -498,7 +498,7 @@ static struct mfd_cell timberdale_cells_bar0_cfg1[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg2[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg2[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -548,7 +548,7 @@ static struct mfd_cell timberdale_cells_bar0_cfg2[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg3[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg3[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -619,7 +619,7 @@ static const struct resource timberdale_sdhc_resources[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar1[] = {
+static const struct mfd_cell timberdale_cells_bar1[] = {
        {
                .name = "sdhci",
                .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
@@ -627,7 +627,7 @@ static struct mfd_cell timberdale_cells_bar1[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar2[] = {
+static const struct mfd_cell timberdale_cells_bar2[] = {
        {
                .name = "sdhci",
                .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
@@ -851,7 +851,7 @@ static void timb_remove(struct pci_dev *dev)
        kfree(priv);
 }
 
-static DEFINE_PCI_DEVICE_TABLE(timberdale_pci_tbl) = {
+static const struct pci_device_id timberdale_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) },
        { 0 }
 };
index a081b925d10b2debf94e28ea2c5c500081262309..3b27482a174fd14bae949ee284f76f4ac504a6fe 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps6507x.h>
 
-static struct mfd_cell tps6507x_devs[] = {
+static const struct mfd_cell tps6507x_devs[] = {
        {
                .name = "tps6507x-pmic",
        },
index e6f03a733879b063d670ecc2bd074ea28063ec18..ba1a25d758c12ed61d82aaea82501272fc34081a 100644 (file)
@@ -64,7 +64,7 @@ static struct resource charger_resources[] = {
        }
 };
 
-static struct mfd_cell tps65090s[] = {
+static const struct mfd_cell tps65090s[] = {
        {
                .name = "tps65090-pmic",
        },
index b7be0b29557599ab94c30ba4f16534c88eff030b..6939ae56c2e168d390a504af22767198b222b9f1 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps65217.h>
 
-static struct mfd_cell tps65217s[] = {
+static const struct mfd_cell tps65217s[] = {
        {
                .name = "tps65217-pmic",
        },
index ee61fd7c198da714c2dd56ba7be2bfe6da5a068d..bbd54414a75da5f99edbc70375c717c4ecd41267 100644 (file)
@@ -103,7 +103,7 @@ static struct resource tps6586x_rtc_resources[] = {
        },
 };
 
-static struct mfd_cell tps6586x_cell[] = {
+static const struct mfd_cell tps6586x_cell[] = {
        {
                .name = "tps6586x-gpio",
        },
@@ -124,6 +124,7 @@ struct tps6586x {
        struct device           *dev;
        struct i2c_client       *client;
        struct regmap           *regmap;
+       int                     version;
 
        int                     irq;
        struct irq_chip         irq_chip;
@@ -208,6 +209,14 @@ int tps6586x_irq_get_virq(struct device *dev, int irq)
 }
 EXPORT_SYMBOL_GPL(tps6586x_irq_get_virq);
 
+int tps6586x_get_version(struct device *dev)
+{
+       struct tps6586x *tps6586x = dev_get_drvdata(dev);
+
+       return tps6586x->version;
+}
+EXPORT_SYMBOL_GPL(tps6586x_get_version);
+
 static int __remove_subdev(struct device *dev, void *unused)
 {
        platform_device_unregister(to_platform_device(dev));
@@ -472,12 +481,38 @@ static void tps6586x_power_off(void)
        tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
 }
 
+static void tps6586x_print_version(struct i2c_client *client, int version)
+{
+       const char *name;
+
+       switch (version) {
+       case TPS658621A:
+               name = "TPS658621A";
+               break;
+       case TPS658621CD:
+               name = "TPS658621C/D";
+               break;
+       case TPS658623:
+               name = "TPS658623";
+               break;
+       case TPS658643:
+               name = "TPS658643";
+               break;
+       default:
+               name = "TPS6586X";
+               break;
+       }
+
+       dev_info(&client->dev, "Found %s, VERSIONCRC is %02x\n", name, version);
+}
+
 static int tps6586x_i2c_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
 {
        struct tps6586x_platform_data *pdata = dev_get_platdata(&client->dev);
        struct tps6586x *tps6586x;
        int ret;
+       int version;
 
        if (!pdata && client->dev.of_node)
                pdata = tps6586x_parse_dt(client);
@@ -487,19 +522,18 @@ static int tps6586x_i2c_probe(struct i2c_client *client,
                return -ENOTSUPP;
        }
 
-       ret = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC);
-       if (ret < 0) {
-               dev_err(&client->dev, "Chip ID read failed: %d\n", ret);
+       version = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC);
+       if (version < 0) {
+               dev_err(&client->dev, "Chip ID read failed: %d\n", version);
                return -EIO;
        }
 
-       dev_info(&client->dev, "VERSIONCRC is %02x\n", ret);
-
        tps6586x = devm_kzalloc(&client->dev, sizeof(*tps6586x), GFP_KERNEL);
-       if (tps6586x == NULL) {
-               dev_err(&client->dev, "memory for tps6586x alloc failed\n");
+       if (!tps6586x)
                return -ENOMEM;
-       }
+
+       tps6586x->version = version;
+       tps6586x_print_version(client, tps6586x->version);
 
        tps6586x->client = client;
        tps6586x->dev = &client->dev;
index c0f608e3ca9e5fc1fc0706666b8fcc4f89778567..1f142d76cbbc6fc03f44ead367c01a9b75f24c86 100644 (file)
@@ -36,7 +36,7 @@ static struct resource rtc_resources[] = {
        }
 };
 
-static struct mfd_cell tps65910s[] = {
+static const struct mfd_cell tps65910s[] = {
        {
                .name = "tps65910-gpio",
        },
index 925a044cbdf61740e3c54e0a481a9774587c652b..27a518e0eec6d04db1310e86f7ed678b4a762065 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps65912.h>
 
-static struct mfd_cell tps65912s[] = {
+static const struct mfd_cell tps65912s[] = {
        {
                .name = "tps65912-pmic",
        },
index f15ee6d5cfbf96fb97ef6f169528c624b09a2aba..ed6c5b0956e2387f09b213eba64879e2fc656fc7 100644 (file)
@@ -44,7 +44,7 @@ static struct resource tps80031_rtc_resources[] = {
 };
 
 /* TPS80031 sub mfd devices */
-static struct mfd_cell tps80031_cell[] = {
+static const struct mfd_cell tps80031_cell[] = {
        {
                .name = "tps80031-pmic",
        },
index 6ef7685a4cf8b346c129403c8155ada7f144d237..ed718328eff1a52f1fff6a8e132f4ba905084422 100644 (file)
@@ -837,62 +837,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
                        usb3v1[0].dev_name = dev_name(child);
                }
        }
-       if (IS_ENABLED(CONFIG_TWL6030_USB) && pdata->usb &&
-           twl_class_is_6030()) {
-
-               static struct regulator_consumer_supply usb3v3;
-               int regulator;
-
-               if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
-                       /* this is a template that gets copied */
-                       struct regulator_init_data usb_fixed = {
-                               .constraints.valid_modes_mask =
-                                       REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-                               .constraints.valid_ops_mask =
-                                       REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-                       };
-
-                       if (features & TWL6032_SUBCLASS) {
-                               usb3v3.supply = "ldousb";
-                               regulator = TWL6032_REG_LDOUSB;
-                       } else {
-                               usb3v3.supply = "vusb";
-                               regulator = TWL6030_REG_VUSB;
-                       }
-                       child = add_regulator_linked(regulator, &usb_fixed,
-                                                       &usb3v3, 1,
-                                                       features);
-                       if (IS_ERR(child))
-                               return PTR_ERR(child);
-               }
-
-               pdata->usb->features = features;
-
-               child = add_child(TWL_MODULE_USB, "twl6030_usb",
-                       pdata->usb, sizeof(*pdata->usb), true,
-                       /* irq1 = VBUS_PRES, irq0 = USB ID */
-                       irq_base + USBOTG_INTR_OFFSET,
-                       irq_base + USB_PRES_INTR_OFFSET);
-
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-               /* we need to connect regulators to this transceiver */
-               if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child)
-                       usb3v3.dev_name = dev_name(child);
-       } else if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) &&
-                  twl_class_is_6030()) {
-               if (features & TWL6032_SUBCLASS)
-                       child = add_regulator(TWL6032_REG_LDOUSB,
-                                               pdata->ldousb, features);
-               else
-                       child = add_regulator(TWL6030_REG_VUSB,
-                                               pdata->vusb, features);
-
-                       if (IS_ERR(child))
-                                       return PTR_ERR(child);
-       }
 
        if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) {
                child = add_child(TWL_MODULE_PM_RECEIVER, "twl4030_wdt", NULL,
@@ -1006,148 +950,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
                        return PTR_ERR(child);
        }
 
-       /* twl6030 regulators */
-       if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
-                       !(features & TWL6032_SUBCLASS)) {
-               child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VDD2, pdata->vdd2,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VDD3, pdata->vdd3,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_V1V8, pdata->v1v8,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_V2V1, pdata->v2v1,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VPP, pdata->vpp,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VDAC, pdata->vdac,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       /* 6030 and 6025 share this regulator */
-       if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030()) {
-               child = add_regulator(TWL6030_REG_VANA, pdata->vana,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       /* twl6032 regulators */
-       if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
-                       (features & TWL6032_SUBCLASS)) {
-               child = add_regulator(TWL6032_REG_LDO5, pdata->ldo5,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_LDO1, pdata->ldo1,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_LDO7, pdata->ldo7,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_LDO6, pdata->ldo6,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_LDOLN, pdata->ldoln,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_LDO2, pdata->ldo2,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_LDO4, pdata->ldo4,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_LDO3, pdata->ldo3,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_SMPS3, pdata->smps3,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_SMPS4, pdata->smps4,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL6032_REG_VIO, pdata->vio6025,
-                                       features);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-       }
-
        if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci &&
                        !(features & (TPS_SUBSET | TWL5031))) {
                child = add_child(TWL_MODULE_MAIN_CHARGE, "twl4030_bci",
@@ -1269,6 +1071,11 @@ static int twl_remove(struct i2c_client *client)
        return 0;
 }
 
+static struct of_dev_auxdata twl_auxdata_lookup[] = {
+       OF_DEV_AUXDATA("ti,twl4030-gpio", 0, "twl4030-gpio", NULL),
+       { /* sentinel */ },
+};
+
 /* NOTE: This driver only handles a single twl4030/tps659x0 chip */
 static int
 twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -1407,10 +1214,14 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
                twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
        }
 
-       if (node)
-               status = of_platform_populate(node, NULL, NULL, &client->dev);
-       else
+       if (node) {
+               if (pdata)
+                       twl_auxdata_lookup[0].platform_data = pdata->gpio;
+               status = of_platform_populate(node, NULL, twl_auxdata_lookup,
+                                             &client->dev);
+       } else {
                status = add_children(pdata, irq_base, id->driver_data);
+       }
 
 fail:
        if (status < 0)
index 517eda832f79978ac772c94b3bcf111643ec8835..18a607e2ca0607d5fb80c765a53f5f8c13352b6f 100644 (file)
@@ -176,8 +176,9 @@ static irqreturn_t twl6030_irq_thread(int irq, void *data)
        int i, ret;
        union {
                u8 bytes[4];
-               u32 int_sts;
+               __le32 int_sts;
        } sts;
+       u32 int_sts; /* sts.int_sts converted to CPU endianness */
        struct twl6030_irq *pdata = data;
 
        /* read INT_STS_A, B and C in one shot using a burst read */
@@ -196,8 +197,9 @@ static irqreturn_t twl6030_irq_thread(int irq, void *data)
        if (sts.bytes[2] & 0x10)
                sts.bytes[2] |= 0x08;
 
-       for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++)
-               if (sts.int_sts & 0x1) {
+       int_sts = le32_to_cpu(sts.int_sts);
+       for (i = 0; int_sts; int_sts >>= 1, i++)
+               if (int_sts & 0x1) {
                        int module_irq =
                                irq_find_mapping(pdata->irq_domain,
                                                 pdata->irq_mapping_tbl[i]);
index 51b6df1a794974664f03471aa94bc00e9837b330..75316fb33448d6041d13e91f1c02c9321cd03818 100644 (file)
@@ -86,7 +86,7 @@ static struct reg_default twl6040_defaults[] = {
        { 0x2E, 0x00 }, /* REG_STATUS   (ro) */
 };
 
-struct reg_default twl6040_patch[] = {
+static struct reg_default twl6040_patch[] = {
        /* Select I2C bus access to dual access registers */
        { TWL6040_REG_ACCCTL, 0x09 },
 };
index af2a6703f34fa89d6a6c68397c91104ab768f6fe..e00f5340ed872089d31998ff39d6bb57842e731a 100644 (file)
@@ -37,7 +37,7 @@ static const struct usb_device_id vprbrd_table[] = {
 
 MODULE_DEVICE_TABLE(usb, vprbrd_table);
 
-static struct mfd_cell vprbrd_devs[] = {
+static const struct mfd_cell vprbrd_devs[] = {
        {
                .name = "viperboard-gpio",
        },
index 757ecc63338c19a7d7d75c85e4a185459fb3d3a0..84f01da4875eb39a064e56b8612138a93afb3fbd 100644 (file)
@@ -60,7 +60,7 @@ static struct resource vx855_gpio_resources[] = {
        },
 };
 
-static struct mfd_cell vx855_cells[] = {
+static const struct mfd_cell vx855_cells[] = {
        {
                .name = "vx855_gpio",
                .num_resources = ARRAY_SIZE(vx855_gpio_resources),
@@ -118,7 +118,7 @@ static void vx855_remove(struct pci_dev *pdev)
        pci_disable_device(pdev);
 }
 
-static DEFINE_PCI_DEVICE_TABLE(vx855_pci_tbl) = {
+static const struct pci_device_id vx855_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
        { 0, }
 };
index 4a4432eb499cac6debaf6c09685ffc670dda90dd..11632f135e8c8d7a6f57206b4d09cd8b097815c7 100644 (file)
@@ -224,6 +224,31 @@ static const struct reg_default wm5110_revb_patch[] = {
        { 0x80, 0x0 },
 };
 
+static const struct reg_default wm5110_revd_patch[] = {
+       { 0x80, 0x3 },
+       { 0x80, 0x3 },
+       { 0x393, 0x27 },
+       { 0x394, 0x27 },
+       { 0x395, 0x27 },
+       { 0x396, 0x27 },
+       { 0x397, 0x27 },
+       { 0x398, 0x26 },
+       { 0x221, 0x90 },
+       { 0x211, 0x8 },
+       { 0x36c, 0x1fb },
+       { 0x26e, 0x64 },
+       { 0x26f, 0xea },
+       { 0x270, 0x1f16 },
+       { 0x51b, 0x1 },
+       { 0x55b, 0x1 },
+       { 0x59b, 0x1 },
+       { 0x4f0, 0x633 },
+       { 0x441, 0xc059 },
+       { 0x209, 0x27 },
+       { 0x80, 0x0 },
+       { 0x80, 0x0 },
+};
+
 /* We use a function so we can use ARRAY_SIZE() */
 int wm5110_patch(struct arizona *arizona)
 {
@@ -236,7 +261,10 @@ int wm5110_patch(struct arizona *arizona)
                return regmap_register_patch(arizona->regmap,
                                             wm5110_revb_patch,
                                             ARRAY_SIZE(wm5110_revb_patch));
-
+       case 3:
+               return regmap_register_patch(arizona->regmap,
+                                            wm5110_revd_patch,
+                                            ARRAY_SIZE(wm5110_revd_patch));
        default:
                return 0;
        }
@@ -505,7 +533,7 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x000001AA, 0x0004 },    /* R426   - FLL2 GPIO Clock */
        { 0x00000200, 0x0006 },    /* R512   - Mic Charge Pump 1 */
        { 0x00000210, 0x0184 },    /* R528   - LDO1 Control 1 */
-       { 0x00000213, 0x0344 },    /* R531   - LDO2 Control 1 */
+       { 0x00000213, 0x03E4 },    /* R531   - LDO2 Control 1 */
        { 0x00000218, 0x01A6 },    /* R536   - Mic Bias Ctrl 1 */
        { 0x00000219, 0x01A6 },    /* R537   - Mic Bias Ctrl 2 */
        { 0x0000021A, 0x01A6 },    /* R538   - Mic Bias Ctrl 3 */
index 5c459f469224a61719d3258e948c0f0f3ecef856..28366a90e1adfbec14b5679244676b1077c9926e 100644 (file)
@@ -1011,7 +1011,7 @@ static struct resource wm831x_wdt_resources[] = {
        },
 };
 
-static struct mfd_cell wm8310_devs[] = {
+static const struct mfd_cell wm8310_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1165,7 +1165,7 @@ static struct mfd_cell wm8310_devs[] = {
        },
 };
 
-static struct mfd_cell wm8311_devs[] = {
+static const struct mfd_cell wm8311_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1295,7 +1295,7 @@ static struct mfd_cell wm8311_devs[] = {
        },
 };
 
-static struct mfd_cell wm8312_devs[] = {
+static const struct mfd_cell wm8312_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1449,7 +1449,7 @@ static struct mfd_cell wm8312_devs[] = {
        },
 };
 
-static struct mfd_cell wm8320_devs[] = {
+static const struct mfd_cell wm8320_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1578,7 +1578,7 @@ static struct mfd_cell wm8320_devs[] = {
        },
 };
 
-static struct mfd_cell touch_devs[] = {
+static const struct mfd_cell touch_devs[] = {
        {
                .name = "wm831x-touch",
                .num_resources = ARRAY_SIZE(wm831x_touch_resources),
@@ -1586,7 +1586,7 @@ static struct mfd_cell touch_devs[] = {
        },
 };
 
-static struct mfd_cell rtc_devs[] = {
+static const struct mfd_cell rtc_devs[] = {
        {
                .name = "wm831x-rtc",
                .num_resources = ARRAY_SIZE(wm831x_rtc_resources),
@@ -1594,7 +1594,7 @@ static struct mfd_cell rtc_devs[] = {
        },
 };
 
-static struct mfd_cell backlight_devs[] = {
+static const struct mfd_cell backlight_devs[] = {
        {
                .name = "wm831x-backlight",
        },
index 2b29caebc9cf77818094a142324fcfc059cac471..a4cbefe5430f340c93a567f603e5f79431136855 100644 (file)
@@ -64,11 +64,13 @@ static int wm831x_i2c_suspend(struct device *dev)
        return wm831x_device_suspend(wm831x);
 }
 
-static void wm831x_i2c_shutdown(struct i2c_client *i2c)
+static int wm831x_i2c_poweroff(struct device *dev)
 {
-       struct wm831x *wm831x = i2c_get_clientdata(i2c);
+       struct wm831x *wm831x = dev_get_drvdata(dev);
 
        wm831x_device_shutdown(wm831x);
+
+       return 0;
 }
 
 static const struct i2c_device_id wm831x_i2c_id[] = {
@@ -85,6 +87,7 @@ MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
 
 static const struct dev_pm_ops wm831x_pm_ops = {
        .suspend = wm831x_i2c_suspend,
+       .poweroff = wm831x_i2c_poweroff,
 };
 
 static struct i2c_driver wm831x_i2c_driver = {
@@ -95,7 +98,6 @@ static struct i2c_driver wm831x_i2c_driver = {
        },
        .probe = wm831x_i2c_probe,
        .remove = wm831x_i2c_remove,
-       .shutdown = wm831x_i2c_shutdown,
        .id_table = wm831x_i2c_id,
 };
 
index 07de3cc5a0d91db385a8ef755e8bf89d3817477b..b8a5e3b34ec78448abea9eef2cc79b56871733f6 100644 (file)
@@ -66,16 +66,19 @@ static int wm831x_spi_suspend(struct device *dev)
        return wm831x_device_suspend(wm831x);
 }
 
-static void wm831x_spi_shutdown(struct spi_device *spi)
+static int wm831x_spi_poweroff(struct device *dev)
 {
-       struct wm831x *wm831x = spi_get_drvdata(spi);
+       struct wm831x *wm831x = dev_get_drvdata(dev);
 
        wm831x_device_shutdown(wm831x);
+
+       return 0;
 }
 
 static const struct dev_pm_ops wm831x_spi_pm = {
        .freeze = wm831x_spi_suspend,
        .suspend = wm831x_spi_suspend,
+       .poweroff = wm831x_spi_poweroff,
 };
 
 static const struct spi_device_id wm831x_spi_ids[] = {
@@ -99,7 +102,6 @@ static struct spi_driver wm831x_spi_driver = {
        .id_table       = wm831x_spi_ids,
        .probe          = wm831x_spi_probe,
        .remove         = wm831x_spi_remove,
-       .shutdown       = wm831x_spi_shutdown,
 };
 
 static int __init wm831x_spi_init(void)
index 0308275116672c2b15ab2d91b334c561dadbcf46..ba04f1bc70eb52988ce27b5f4e45195e8b216b82 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "wm8994.h"
 
-static struct mfd_cell wm8994_regulator_devs[] = {
+static const struct mfd_cell wm8994_regulator_devs[] = {
        {
                .name = "wm8994-ldo",
                .id = 1,
@@ -62,7 +62,7 @@ static struct resource wm8994_gpio_resources[] = {
        },
 };
 
-static struct mfd_cell wm8994_devs[] = {
+static const struct mfd_cell wm8994_devs[] = {
        {
                .name = "wm8994-codec",
                .num_resources = ARRAY_SIZE(wm8994_codec_resources),
index 5183e7bb8de33632618b360c2c607009539c73b8..163da9c3ea0e164c228bff771ed8b41347632fa7 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/bitops.h>
 #include <linux/mfd/abx500.h>
 #include <linux/mfd/abx500/ab8500.h>
-#include <linux/mfd/abx500/ab8500-gpio.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinmux.h>
@@ -1218,21 +1217,15 @@ static const struct of_device_id abx500_gpio_match[] = {
 
 static int abx500_gpio_probe(struct platform_device *pdev)
 {
-       struct ab8500_platform_data *abx500_pdata =
-                               dev_get_platdata(pdev->dev.parent);
-       struct abx500_gpio_platform_data *pdata = NULL;
        struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *match;
        struct abx500_pinctrl *pct;
-       const struct platform_device_id *platid = platform_get_device_id(pdev);
        unsigned int id = -1;
        int ret, err;
        int i;
 
-       if (abx500_pdata)
-               pdata = abx500_pdata->gpio;
-
-       if (!(pdata || np)) {
-               dev_err(&pdev->dev, "gpio dt and platform data missing\n");
+       if (!np) {
+               dev_err(&pdev->dev, "gpio dt node missing\n");
                return -ENODEV;
        }
 
@@ -1248,17 +1241,14 @@ static int abx500_gpio_probe(struct platform_device *pdev)
        pct->parent = dev_get_drvdata(pdev->dev.parent);
        pct->chip = abx500gpio_chip;
        pct->chip.dev = &pdev->dev;
-       pct->chip.base = (np) ? -1 : pdata->gpio_base;
-
-       if (platid)
-               id = platid->driver_data;
-       else if (np) {
-               const struct of_device_id *match;
+       pct->chip.base = -1; /* Dynamic allocation */
 
-               match = of_match_device(abx500_gpio_match, &pdev->dev);
-               if (match)
-                       id = (unsigned long)match->data;
+       match = of_match_device(abx500_gpio_match, &pdev->dev);
+       if (!match) {
+               dev_err(&pdev->dev, "gpio dt not matching\n");
+               return -ENODEV;
        }
+       id = (unsigned long)match->data;
 
        /* Poke in other ASIC variants here */
        switch (id) {
@@ -1349,14 +1339,6 @@ static int abx500_gpio_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct platform_device_id abx500_pinctrl_id[] = {
-       { "pinctrl-ab8500", PINCTRL_AB8500 },
-       { "pinctrl-ab8540", PINCTRL_AB8540 },
-       { "pinctrl-ab9540", PINCTRL_AB9540 },
-       { "pinctrl-ab8505", PINCTRL_AB8505 },
-       { },
-};
-
 static struct platform_driver abx500_gpio_driver = {
        .driver = {
                .name = "abx500-gpio",
@@ -1365,7 +1347,6 @@ static struct platform_driver abx500_gpio_driver = {
        },
        .probe = abx500_gpio_probe,
        .remove = abx500_gpio_remove,
-       .id_table = abx500_pinctrl_id,
 };
 
 static int __init abx500_gpio_init(void)
index 82293806e842c1b86b55c1b8f229da1aec1c58d5..2beef3bfe9ca93f3857361a879e76e38ee7161ac 100644 (file)
@@ -15,6 +15,18 @@ enum abx500_pin_func {
        ABX500_ALT_C,
 };
 
+enum abx500_gpio_pull_updown {
+       ABX500_GPIO_PULL_DOWN = 0x0,
+       ABX500_GPIO_PULL_NONE = 0x1,
+       ABX500_GPIO_PULL_UP = 0x3,
+};
+
+enum abx500_gpio_vinsel {
+       ABX500_GPIO_VINSEL_VBAT = 0x0,
+       ABX500_GPIO_VINSEL_VIN_1V8 = 0x1,
+       ABX500_GPIO_VINSEL_VDD_BIF = 0x2,
+};
+
 /**
  * struct abx500_function - ABx500 pinctrl mux function
  * @name: The name of the function, exported to pinctrl core.
index eece329d78729049c4dd7b2e49668217309a5668..7acab93d5a47effcb69a94062efb33fe16ffda24 100644 (file)
@@ -90,6 +90,16 @@ config PWM_JZ4740
          To compile this driver as a module, choose M here: the module
          will be called pwm-jz4740.
 
+config PWM_LP3943
+       tristate "TI/National Semiconductor LP3943 PWM support"
+       depends on MFD_LP3943
+       help
+         Generic PWM framework driver for LP3943 which supports two PWM
+         channels.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-lp3943.
+
 config PWM_LPC32XX
        tristate "LPC32XX PWM support"
        depends on ARCH_LPC32XX
index 8b754e4dba4aae03cc36562d5e0c079e6327c4d2..4abf337dcd0231759d0450943516b3d45026c02b 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_PWM_BFIN)          += pwm-bfin.o
 obj-$(CONFIG_PWM_EP93XX)       += pwm-ep93xx.o
 obj-$(CONFIG_PWM_IMX)          += pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)       += pwm-jz4740.o
+obj-$(CONFIG_PWM_LP3943)       += pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC32XX)      += pwm-lpc32xx.o
 obj-$(CONFIG_PWM_MXS)          += pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)      += pwm-pca9685.o
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c
new file mode 100644 (file)
index 0000000..8a843a0
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * TI/National Semiconductor LP3943 PWM driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim <milo.kim@ti.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; version 2.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/mfd/lp3943.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define LP3943_MAX_DUTY                        255
+#define LP3943_MIN_PERIOD              6250
+#define LP3943_MAX_PERIOD              1600000
+
+struct lp3943_pwm {
+       struct pwm_chip chip;
+       struct lp3943 *lp3943;
+       struct lp3943_platform_data *pdata;
+};
+
+static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip)
+{
+       return container_of(_chip, struct lp3943_pwm, chip);
+}
+
+static struct lp3943_pwm_map *
+lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
+{
+       struct lp3943_platform_data *pdata = lp3943_pwm->pdata;
+       struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+       struct lp3943_pwm_map *pwm_map;
+       int i, offset;
+
+       pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL);
+       if (!pwm_map)
+               return ERR_PTR(-ENOMEM);
+
+       pwm_map->output = pdata->pwms[hwpwm]->output;
+       pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
+
+       for (i = 0; i < pwm_map->num_outputs; i++) {
+               offset = pwm_map->output[i];
+
+               /* Return an error if the pin is already assigned */
+               if (test_and_set_bit(offset, &lp3943->pin_used))
+                       return ERR_PTR(-EBUSY);
+       }
+
+       return pwm_map;
+}
+
+static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+       struct lp3943_pwm_map *pwm_map;
+
+       pwm_map = lp3943_pwm_request_map(lp3943_pwm, pwm->hwpwm);
+       if (IS_ERR(pwm_map))
+               return PTR_ERR(pwm_map);
+
+       return pwm_set_chip_data(pwm, pwm_map);
+}
+
+static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
+                               struct lp3943_pwm_map *pwm_map)
+{
+       struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+       int i, offset;
+
+       for (i = 0; i < pwm_map->num_outputs; i++) {
+               offset = pwm_map->output[i];
+               clear_bit(offset, &lp3943->pin_used);
+       }
+
+       kfree(pwm_map);
+}
+
+static void lp3943_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+       struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
+
+       lp3943_pwm_free_map(lp3943_pwm, pwm_map);
+}
+
+static int lp3943_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                            int duty_ns, int period_ns)
+{
+       struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+       struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+       u8 val, reg_duty, reg_prescale;
+       int err;
+
+       /*
+        * How to configure the LP3943 PWMs
+        *
+        * 1) Period = 6250 ~ 1600000
+        * 2) Prescale = period / 6250 -1
+        * 3) Duty = input duty
+        *
+        * Prescale and duty are register values
+        */
+
+       if (pwm->hwpwm == 0) {
+               reg_prescale = LP3943_REG_PRESCALE0;
+               reg_duty     = LP3943_REG_PWM0;
+       } else {
+               reg_prescale = LP3943_REG_PRESCALE1;
+               reg_duty     = LP3943_REG_PWM1;
+       }
+
+       period_ns = clamp(period_ns, LP3943_MIN_PERIOD, LP3943_MAX_PERIOD);
+       val       = (u8)(period_ns / LP3943_MIN_PERIOD - 1);
+
+       err = lp3943_write_byte(lp3943, reg_prescale, val);
+       if (err)
+               return err;
+
+       val = (u8)(duty_ns * LP3943_MAX_DUTY / period_ns);
+
+       return lp3943_write_byte(lp3943, reg_duty, val);
+}
+
+static int lp3943_pwm_set_mode(struct lp3943_pwm *lp3943_pwm,
+                              struct lp3943_pwm_map *pwm_map,
+                              u8 val)
+{
+       struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+       const struct lp3943_reg_cfg *mux = lp3943->mux_cfg;
+       int i, index, err;
+
+       for (i = 0; i < pwm_map->num_outputs; i++) {
+               index = pwm_map->output[i];
+               err = lp3943_update_bits(lp3943, mux[index].reg,
+                                        mux[index].mask,
+                                        val << mux[index].shift);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int lp3943_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+       struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
+       u8 val;
+
+       if (pwm->hwpwm == 0)
+               val = LP3943_DIM_PWM0;
+       else
+               val = LP3943_DIM_PWM1;
+
+       /*
+        * Each PWM generator is set to control any of outputs of LP3943.
+        * To enable/disable the PWM, these output pins should be configured.
+        */
+
+       return lp3943_pwm_set_mode(lp3943_pwm, pwm_map, val);
+}
+
+static void lp3943_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+       struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
+
+       /*
+        * LP3943 outputs are open-drain, so the pin should be configured
+        * when the PWM is disabled.
+        */
+
+       lp3943_pwm_set_mode(lp3943_pwm, pwm_map, LP3943_GPIO_OUT_HIGH);
+}
+
+static const struct pwm_ops lp3943_pwm_ops = {
+       .request        = lp3943_pwm_request,
+       .free           = lp3943_pwm_free,
+       .config         = lp3943_pwm_config,
+       .enable         = lp3943_pwm_enable,
+       .disable        = lp3943_pwm_disable,
+       .owner          = THIS_MODULE,
+};
+
+static int lp3943_pwm_parse_dt(struct device *dev,
+                              struct lp3943_pwm *lp3943_pwm)
+{
+       static const char * const name[] = { "ti,pwm0", "ti,pwm1", };
+       struct device_node *node = dev->of_node;
+       struct lp3943_platform_data *pdata;
+       struct lp3943_pwm_map *pwm_map;
+       enum lp3943_pwm_output *output;
+       int i, err, proplen, count = 0;
+       u32 num_outputs;
+
+       if (!node)
+               return -EINVAL;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       /*
+        * Read the output map configuration from the device tree.
+        * Each of the two PWM generators can drive zero or more outputs.
+        */
+
+       for (i = 0; i < LP3943_NUM_PWMS; i++) {
+               if (!of_get_property(node, name[i], &proplen))
+                       continue;
+
+               num_outputs = proplen / sizeof(u32);
+               if (num_outputs == 0)
+                       continue;
+
+               output = devm_kzalloc(dev, sizeof(*output) * num_outputs,
+                                     GFP_KERNEL);
+               if (!output)
+                       return -ENOMEM;
+
+               err = of_property_read_u32_array(node, name[i], output,
+                                                num_outputs);
+               if (err)
+                       return err;
+
+               pwm_map = devm_kzalloc(dev, sizeof(*pwm_map), GFP_KERNEL);
+               if (!pwm_map)
+                       return -ENOMEM;
+
+               pwm_map->output = output;
+               pwm_map->num_outputs = num_outputs;
+               pdata->pwms[i] = pwm_map;
+
+               count++;
+       }
+
+       if (count == 0)
+               return -ENODATA;
+
+       lp3943_pwm->pdata = pdata;
+       return 0;
+}
+
+static int lp3943_pwm_probe(struct platform_device *pdev)
+{
+       struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent);
+       struct lp3943_pwm *lp3943_pwm;
+       int ret;
+
+       lp3943_pwm = devm_kzalloc(&pdev->dev, sizeof(*lp3943_pwm), GFP_KERNEL);
+       if (!lp3943_pwm)
+               return -ENOMEM;
+
+       lp3943_pwm->pdata = lp3943->pdata;
+       if (!lp3943_pwm->pdata) {
+               if (IS_ENABLED(CONFIG_OF))
+                       ret = lp3943_pwm_parse_dt(&pdev->dev, lp3943_pwm);
+               else
+                       ret = -ENODEV;
+
+               if (ret)
+                       return ret;
+       }
+
+       lp3943_pwm->lp3943 = lp3943;
+       lp3943_pwm->chip.dev = &pdev->dev;
+       lp3943_pwm->chip.ops = &lp3943_pwm_ops;
+       lp3943_pwm->chip.npwm = LP3943_NUM_PWMS;
+
+       platform_set_drvdata(pdev, lp3943_pwm);
+
+       return pwmchip_add(&lp3943_pwm->chip);
+}
+
+static int lp3943_pwm_remove(struct platform_device *pdev)
+{
+       struct lp3943_pwm *lp3943_pwm = platform_get_drvdata(pdev);
+
+       return pwmchip_remove(&lp3943_pwm->chip);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id lp3943_pwm_of_match[] = {
+       { .compatible = "ti,lp3943-pwm", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, lp3943_pwm_of_match);
+#endif
+
+static struct platform_driver lp3943_pwm_driver = {
+       .probe = lp3943_pwm_probe,
+       .remove = lp3943_pwm_remove,
+       .driver = {
+               .name = "lp3943-pwm",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(lp3943_pwm_of_match),
+       },
+};
+module_platform_driver(lp3943_pwm_driver);
+
+MODULE_DESCRIPTION("LP3943 PWM driver");
+MODULE_ALIAS("platform:lp3943-pwm");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
index ce785f481281d2532dca6514e07a304ccfcb7b04..db9ae6fa2404627eae63801eed68b8c7afc31b5b 100644 (file)
@@ -343,7 +343,7 @@ config REGULATOR_MC13XXX_CORE
 
 config REGULATOR_MC13783
        tristate "Freescale MC13783 regulator driver"
-       depends on MFD_MC13783
+       depends on MFD_MC13XXX
        select REGULATOR_MC13XXX_CORE
        help
          Say y here to support the regulators found on the Freescale MC13783
index e8e3a8afd3e279be7c524b3599316be05f9606a9..0485d47f0d8a82d9de595a8df5bd73c16111d4f2 100644 (file)
@@ -93,6 +93,8 @@ static const unsigned int tps6586x_ldo4_voltages[] = {
        2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000,
 };
 
+#define tps658623_sm2_voltages tps6586x_ldo4_voltages
+
 static const unsigned int tps6586x_ldo_voltages[] = {
        1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
 };
@@ -104,6 +106,13 @@ static const unsigned int tps6586x_sm2_voltages[] = {
        4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000,
 };
 
+static const unsigned int tps658643_sm2_voltages[] = {
+       1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000,
+       1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000,
+       1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000, 1600000,
+       1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000, 1800000,
+};
+
 static const unsigned int tps6586x_dvm_voltages[] = {
         725000,  750000,  775000,  800000,  825000,  850000,  875000,  900000,
         925000,  950000,  975000, 1000000, 1025000, 1050000, 1075000, 1100000,
@@ -119,8 +128,8 @@ static const unsigned int tps6586x_dvm_voltages[] = {
                .ops    = &tps6586x_regulator_ops,                      \
                .type   = REGULATOR_VOLTAGE,                            \
                .id     = TPS6586X_ID_##_id,                            \
-               .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages),  \
-               .volt_table = tps6586x_##vdata##_voltages,              \
+               .n_voltages = ARRAY_SIZE(vdata##_voltages),             \
+               .volt_table = vdata##_voltages,                         \
                .owner  = THIS_MODULE,                                  \
                .enable_reg = TPS6586X_SUPPLY##ereg0,                   \
                .enable_mask = 1 << (ebit0),                            \
@@ -162,27 +171,47 @@ static const unsigned int tps6586x_dvm_voltages[] = {
 
 static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_SYS_REGULATOR(),
-       TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0),
-       TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2),
-       TPS6586X_LDO(LDO_5, "REG-SYS", ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
-       TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
-       TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
-       TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
-       TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
-       TPS6586X_LDO(LDO_RTC, "REG-SYS", ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
-       TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
-       TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
-
-       TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3,
+       TPS6586X_LDO(LDO_0, "vinldo01", tps6586x_ldo0, SUPPLYV1, 5, 3, ENC, 0,
+                                       END, 0),
+       TPS6586X_LDO(LDO_3, "vinldo23", tps6586x_ldo, SUPPLYV4, 0, 3, ENC, 2,
+                                       END, 2),
+       TPS6586X_LDO(LDO_5, "REG-SYS", tps6586x_ldo, SUPPLYV6, 0, 3, ENE, 6,
+                                       ENE, 6),
+       TPS6586X_LDO(LDO_6, "vinldo678", tps6586x_ldo, SUPPLYV3, 0, 3, ENC, 4,
+                                       END, 4),
+       TPS6586X_LDO(LDO_7, "vinldo678", tps6586x_ldo, SUPPLYV3, 3, 3, ENC, 5,
+                                       END, 5),
+       TPS6586X_LDO(LDO_8, "vinldo678", tps6586x_ldo, SUPPLYV2, 5, 3, ENC, 6,
+                                       END, 6),
+       TPS6586X_LDO(LDO_9, "vinldo9", tps6586x_ldo, SUPPLYV6, 3, 3, ENE, 7,
+                                       ENE, 7),
+       TPS6586X_LDO(LDO_RTC, "REG-SYS", tps6586x_ldo, SUPPLYV4, 3, 3, V4, 7,
+                                       V4, 7),
+       TPS6586X_LDO(LDO_1, "vinldo01", tps6586x_dvm, SUPPLYV1, 0, 5, ENC, 1,
+                                       END, 1),
+       TPS6586X_LDO(SM_2, "vin-sm2", tps6586x_sm2, SUPPLYV2, 0, 5, ENC, 7,
+                                       END, 7),
+
+       TPS6586X_DVM(LDO_2, "vinldo23", tps6586x_dvm, LDO2BV1, 0, 5, ENA, 3,
                                        ENB, 3, TPS6586X_VCC2, BIT(6)),
-       TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3,
+       TPS6586X_DVM(LDO_4, "vinldo4", tps6586x_ldo4, LDO4V1, 0, 5, ENC, 3,
                                        END, 3, TPS6586X_VCC1, BIT(6)),
-       TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1,
+       TPS6586X_DVM(SM_0, "vin-sm0", tps6586x_dvm, SM0V1, 0, 5, ENA, 1,
                                        ENB, 1, TPS6586X_VCC1, BIT(2)),
-       TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0,
+       TPS6586X_DVM(SM_1, "vin-sm1", tps6586x_dvm, SM1V1, 0, 5, ENA, 0,
                                        ENB, 0, TPS6586X_VCC1, BIT(0)),
 };
 
+static struct tps6586x_regulator tps658623_regulator[] = {
+       TPS6586X_LDO(SM_2, "vin-sm2", tps658623_sm2, SUPPLYV2, 0, 5, ENC, 7,
+                                       END, 7),
+};
+
+static struct tps6586x_regulator tps658643_regulator[] = {
+       TPS6586X_LDO(SM_2, "vin-sm2", tps658643_sm2, SUPPLYV2, 0, 5, ENC, 7,
+                                       END, 7),
+};
+
 /*
  * TPS6586X has 2 enable bits that are OR'ed to determine the actual
  * regulator state. Clearing one of this bits allows switching
@@ -254,11 +283,33 @@ static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev,
                        setting->slew_rate & TPS6586X_SLEW_RATE_MASK);
 }
 
-static inline struct tps6586x_regulator *find_regulator_info(int id)
+static struct tps6586x_regulator *find_regulator_info(int id, int version)
 {
        struct tps6586x_regulator *ri;
+       struct tps6586x_regulator *table = NULL;
+       int num;
        int i;
 
+       switch (version) {
+       case TPS658623:
+               table = tps658623_regulator;
+               num = ARRAY_SIZE(tps658623_regulator);
+               break;
+       case TPS658643:
+               table = tps658643_regulator;
+               num = ARRAY_SIZE(tps658643_regulator);
+               break;
+       }
+
+       /* Search version specific table first */
+       if (table) {
+               for (i = 0; i < num; i++) {
+                       ri = &table[i];
+                       if (ri->desc.id == id)
+                               return ri;
+               }
+       }
+
        for (i = 0; i < ARRAY_SIZE(tps6586x_regulator); i++) {
                ri = &tps6586x_regulator[i];
                if (ri->desc.id == id)
@@ -351,6 +402,7 @@ static int tps6586x_regulator_probe(struct platform_device *pdev)
        struct regulator_init_data *reg_data;
        struct tps6586x_platform_data *pdata;
        struct of_regulator_match *tps6586x_reg_matches = NULL;
+       int version;
        int id;
        int err;
 
@@ -373,10 +425,13 @@ static int tps6586x_regulator_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       version = tps6586x_get_version(pdev->dev.parent);
+
        for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) {
                reg_data = pdata->reg_init_data[id];
 
-               ri = find_regulator_info(id);
+               ri = find_regulator_info(id, version);
+
                if (!ri) {
                        dev_err(&pdev->dev, "invalid regulator ID specified\n");
                        return -EINVAL;
diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h
deleted file mode 100644 (file)
index 172b2f2..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright ST-Ericsson 2010.
- *
- * Author: Bibek Basu <bibek.basu@stericsson.com>
- * Licensed under GPLv2.
- */
-
-#ifndef _AB8500_GPIO_H
-#define _AB8500_GPIO_H
-
-/*
- * Platform data to register a block: only the initial gpio/irq number.
- * Array sizes are large enough to contain all AB8500 and AB9540 GPIO
- * registers.
- */
-
-struct abx500_gpio_platform_data {
-       int gpio_base;
-};
-
-enum abx500_gpio_pull_updown {
-       ABX500_GPIO_PULL_DOWN = 0x0,
-       ABX500_GPIO_PULL_NONE = 0x1,
-       ABX500_GPIO_PULL_UP = 0x3,
-};
-
-enum abx500_gpio_vinsel {
-       ABX500_GPIO_VINSEL_VBAT = 0x0,
-       ABX500_GPIO_VINSEL_VIN_1V8 = 0x1,
-       ABX500_GPIO_VINSEL_VDD_BIF = 0x2,
-};
-
-#endif /* _AB8500_GPIO_H */
index f4acd898dac974e40ef8ee2f71972a91009d2277..a86ca1406fb87ca11a656c72047b073a22c23e1b 100644 (file)
@@ -368,7 +368,6 @@ struct ab8500 {
 };
 
 struct ab8500_regulator_platform_data;
-struct ab8500_gpio_platform_data;
 struct ab8500_codec_platform_data;
 struct ab8500_sysctrl_platform_data;
 
@@ -382,7 +381,6 @@ struct ab8500_platform_data {
        int irq_base;
        void (*init) (struct ab8500 *);
        struct ab8500_regulator_platform_data *regulator;
-       struct abx500_gpio_platform_data *gpio;
        struct ab8500_codec_platform_data *codec;
        struct ab8500_sysctrl_platform_data *sysctrl;
 };
diff --git a/include/linux/mfd/lp3943.h b/include/linux/mfd/lp3943.h
new file mode 100644 (file)
index 0000000..3490db7
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * TI/National Semiconductor LP3943 Device
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __MFD_LP3943_H__
+#define __MFD_LP3943_H__
+
+#include <linux/gpio.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+
+/* Registers */
+#define LP3943_REG_GPIO_A              0x00
+#define LP3943_REG_GPIO_B              0x01
+#define LP3943_REG_PRESCALE0           0x02
+#define LP3943_REG_PWM0                        0x03
+#define LP3943_REG_PRESCALE1           0x04
+#define LP3943_REG_PWM1                        0x05
+#define LP3943_REG_MUX0                        0x06
+#define LP3943_REG_MUX1                        0x07
+#define LP3943_REG_MUX2                        0x08
+#define LP3943_REG_MUX3                        0x09
+
+/* Bit description for LP3943_REG_MUX0 ~ 3 */
+#define LP3943_GPIO_IN                 0x00
+#define LP3943_GPIO_OUT_HIGH           0x00
+#define LP3943_GPIO_OUT_LOW            0x01
+#define LP3943_DIM_PWM0                        0x02
+#define LP3943_DIM_PWM1                        0x03
+
+#define LP3943_NUM_PWMS                        2
+
+enum lp3943_pwm_output {
+       LP3943_PWM_OUT0,
+       LP3943_PWM_OUT1,
+       LP3943_PWM_OUT2,
+       LP3943_PWM_OUT3,
+       LP3943_PWM_OUT4,
+       LP3943_PWM_OUT5,
+       LP3943_PWM_OUT6,
+       LP3943_PWM_OUT7,
+       LP3943_PWM_OUT8,
+       LP3943_PWM_OUT9,
+       LP3943_PWM_OUT10,
+       LP3943_PWM_OUT11,
+       LP3943_PWM_OUT12,
+       LP3943_PWM_OUT13,
+       LP3943_PWM_OUT14,
+       LP3943_PWM_OUT15,
+};
+
+/*
+ * struct lp3943_pwm_map
+ * @output: Output pins which are mapped to each PWM channel
+ * @num_outputs: Number of outputs
+ */
+struct lp3943_pwm_map {
+       enum lp3943_pwm_output *output;
+       int num_outputs;
+};
+
+/*
+ * struct lp3943_platform_data
+ * @pwms: Output channel definitions for PWM channel 0 and 1
+ */
+struct lp3943_platform_data {
+       struct lp3943_pwm_map *pwms[LP3943_NUM_PWMS];
+};
+
+/*
+ * struct lp3943_reg_cfg
+ * @reg: Register address
+ * @mask: Register bit mask to be updated
+ * @shift: Register bit shift
+ */
+struct lp3943_reg_cfg {
+       u8 reg;
+       u8 mask;
+       u8 shift;
+};
+
+/*
+ * struct lp3943
+ * @dev: Parent device pointer
+ * @regmap: Used for I2C communication on accessing registers
+ * @pdata: LP3943 platform specific data
+ * @mux_cfg: Register configuration for pin MUX
+ * @pin_used: Bit mask for output pin used.
+ *           This bitmask is used for pin assignment management.
+ *           1 = pin used, 0 = available.
+ *           Only LSB 16 bits are used, but it is unsigned long type
+ *           for atomic bitwise operations.
+ */
+struct lp3943 {
+       struct device *dev;
+       struct regmap *regmap;
+       struct lp3943_platform_data *pdata;
+       const struct lp3943_reg_cfg *mux_cfg;
+       unsigned long pin_used;
+};
+
+int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read);
+int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data);
+int lp3943_update_bits(struct lp3943 *lp3943, u8 reg, u8 mask, u8 data);
+#endif
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
new file mode 100644 (file)
index 0000000..a3d0185
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * max14577-private.h - Common API for the Maxim 14577 internal sub chip
+ *
+ * Copyright (C) 2013 Samsung Electrnoics
+ * Chanwoo Choi <cw00.choi@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski@samsung.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.
+ */
+
+#ifndef __MAX14577_PRIVATE_H__
+#define __MAX14577_PRIVATE_H__
+
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+
+#define MAX14577_REG_INVALID           (0xff)
+
+/* Slave addr = 0x4A: Interrupt */
+enum max14577_reg {
+       MAX14577_REG_DEVICEID           = 0x00,
+       MAX14577_REG_INT1               = 0x01,
+       MAX14577_REG_INT2               = 0x02,
+       MAX14577_REG_INT3               = 0x03,
+       MAX14577_REG_STATUS1            = 0x04,
+       MAX14577_REG_STATUS2            = 0x05,
+       MAX14577_REG_STATUS3            = 0x06,
+       MAX14577_REG_INTMASK1           = 0x07,
+       MAX14577_REG_INTMASK2           = 0x08,
+       MAX14577_REG_INTMASK3           = 0x09,
+       MAX14577_REG_CDETCTRL1          = 0x0A,
+       MAX14577_REG_RFU                = 0x0B,
+       MAX14577_REG_CONTROL1           = 0x0C,
+       MAX14577_REG_CONTROL2           = 0x0D,
+       MAX14577_REG_CONTROL3           = 0x0E,
+       MAX14577_REG_CHGCTRL1           = 0x0F,
+       MAX14577_REG_CHGCTRL2           = 0x10,
+       MAX14577_REG_CHGCTRL3           = 0x11,
+       MAX14577_REG_CHGCTRL4           = 0x12,
+       MAX14577_REG_CHGCTRL5           = 0x13,
+       MAX14577_REG_CHGCTRL6           = 0x14,
+       MAX14577_REG_CHGCTRL7           = 0x15,
+
+       MAX14577_REG_END,
+};
+
+/* Slave addr = 0x4A: MUIC */
+enum max14577_muic_reg {
+       MAX14577_MUIC_REG_STATUS1       = 0x04,
+       MAX14577_MUIC_REG_STATUS2       = 0x05,
+       MAX14577_MUIC_REG_CONTROL1      = 0x0C,
+       MAX14577_MUIC_REG_CONTROL3      = 0x0E,
+
+       MAX14577_MUIC_REG_END,
+};
+
+enum max14577_muic_charger_type {
+       MAX14577_CHARGER_TYPE_NONE = 0,
+       MAX14577_CHARGER_TYPE_USB,
+       MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT,
+       MAX14577_CHARGER_TYPE_DEDICATED_CHG,
+       MAX14577_CHARGER_TYPE_SPECIAL_500MA,
+       MAX14577_CHARGER_TYPE_SPECIAL_1A,
+       MAX14577_CHARGER_TYPE_RESERVED,
+       MAX14577_CHARGER_TYPE_DEAD_BATTERY = 7,
+};
+
+/* MAX14577 interrupts */
+#define INT1_ADC_MASK                  (0x1 << 0)
+#define INT1_ADCLOW_MASK               (0x1 << 1)
+#define INT1_ADCERR_MASK               (0x1 << 2)
+
+#define INT2_CHGTYP_MASK               (0x1 << 0)
+#define INT2_CHGDETRUN_MASK            (0x1 << 1)
+#define INT2_DCDTMR_MASK               (0x1 << 2)
+#define INT2_DBCHG_MASK                        (0x1 << 3)
+#define INT2_VBVOLT_MASK               (0x1 << 4)
+
+#define INT3_EOC_MASK                  (0x1 << 0)
+#define INT3_CGMBC_MASK                        (0x1 << 1)
+#define INT3_OVP_MASK                  (0x1 << 2)
+#define INT3_MBCCHGERR_MASK            (0x1 << 3)
+
+/* MAX14577 DEVICE ID register */
+#define DEVID_VENDORID_SHIFT           0
+#define DEVID_DEVICEID_SHIFT           3
+#define DEVID_VENDORID_MASK            (0x07 << DEVID_VENDORID_SHIFT)
+#define DEVID_DEVICEID_MASK            (0x1f << DEVID_DEVICEID_SHIFT)
+
+/* MAX14577 STATUS1 register */
+#define STATUS1_ADC_SHIFT              0
+#define STATUS1_ADCLOW_SHIFT           5
+#define STATUS1_ADCERR_SHIFT           6
+#define STATUS1_ADC_MASK               (0x1f << STATUS1_ADC_SHIFT)
+#define STATUS1_ADCLOW_MASK            (0x1 << STATUS1_ADCLOW_SHIFT)
+#define STATUS1_ADCERR_MASK            (0x1 << STATUS1_ADCERR_SHIFT)
+
+/* MAX14577 STATUS2 register */
+#define STATUS2_CHGTYP_SHIFT           0
+#define STATUS2_CHGDETRUN_SHIFT                3
+#define STATUS2_DCDTMR_SHIFT           4
+#define STATUS2_DBCHG_SHIFT            5
+#define STATUS2_VBVOLT_SHIFT           6
+#define STATUS2_CHGTYP_MASK            (0x7 << STATUS2_CHGTYP_SHIFT)
+#define STATUS2_CHGDETRUN_MASK         (0x1 << STATUS2_CHGDETRUN_SHIFT)
+#define STATUS2_DCDTMR_MASK            (0x1 << STATUS2_DCDTMR_SHIFT)
+#define STATUS2_DBCHG_MASK             (0x1 << STATUS2_DBCHG_SHIFT)
+#define STATUS2_VBVOLT_MASK            (0x1 << STATUS2_VBVOLT_SHIFT)
+
+/* MAX14577 CONTROL1 register */
+#define COMN1SW_SHIFT                  0
+#define COMP2SW_SHIFT                  3
+#define MICEN_SHIFT                    6
+#define IDBEN_SHIFT                    7
+#define COMN1SW_MASK                   (0x7 << COMN1SW_SHIFT)
+#define COMP2SW_MASK                   (0x7 << COMP2SW_SHIFT)
+#define MICEN_MASK                     (0x1 << MICEN_SHIFT)
+#define IDBEN_MASK                     (0x1 << IDBEN_SHIFT)
+#define CLEAR_IDBEN_MICEN_MASK         (COMN1SW_MASK | COMP2SW_MASK)
+#define CTRL1_SW_USB                   ((1 << COMP2SW_SHIFT) \
+                                               | (1 << COMN1SW_SHIFT))
+#define CTRL1_SW_AUDIO                 ((2 << COMP2SW_SHIFT) \
+                                               | (2 << COMN1SW_SHIFT))
+#define CTRL1_SW_UART                  ((3 << COMP2SW_SHIFT) \
+                                               | (3 << COMN1SW_SHIFT))
+#define CTRL1_SW_OPEN                  ((0 << COMP2SW_SHIFT) \
+                                               | (0 << COMN1SW_SHIFT))
+
+/* MAX14577 CONTROL2 register */
+#define CTRL2_LOWPWR_SHIFT             (0)
+#define CTRL2_ADCEN_SHIFT              (1)
+#define CTRL2_CPEN_SHIFT               (2)
+#define CTRL2_SFOUTASRT_SHIFT          (3)
+#define CTRL2_SFOUTORD_SHIFT           (4)
+#define CTRL2_ACCDET_SHIFT             (5)
+#define CTRL2_USBCPINT_SHIFT           (6)
+#define CTRL2_RCPS_SHIFT               (7)
+#define CTRL2_LOWPWR_MASK              (0x1 << CTRL2_LOWPWR_SHIFT)
+#define CTRL2_ADCEN_MASK               (0x1 << CTRL2_ADCEN_SHIFT)
+#define CTRL2_CPEN_MASK                        (0x1 << CTRL2_CPEN_SHIFT)
+#define CTRL2_SFOUTASRT_MASK           (0x1 << CTRL2_SFOUTASRT_SHIFT)
+#define CTRL2_SFOUTORD_MASK            (0x1 << CTRL2_SFOUTORD_SHIFT)
+#define CTRL2_ACCDET_MASK              (0x1 << CTRL2_ACCDET_SHIFT)
+#define CTRL2_USBCPINT_MASK            (0x1 << CTRL2_USBCPINT_SHIFT)
+#define CTRL2_RCPS_MASK                        (0x1 << CTR2_RCPS_SHIFT)
+
+#define CTRL2_CPEN1_LOWPWR0 ((1 << CTRL2_CPEN_SHIFT) | \
+                               (0 << CTRL2_LOWPWR_SHIFT))
+#define CTRL2_CPEN0_LOWPWR1 ((0 << CTRL2_CPEN_SHIFT) | \
+                               (1 << CTRL2_LOWPWR_SHIFT))
+
+/* MAX14577 CONTROL3 register */
+#define CTRL3_JIGSET_SHIFT             0
+#define CTRL3_BOOTSET_SHIFT            2
+#define CTRL3_ADCDBSET_SHIFT           4
+#define CTRL3_JIGSET_MASK              (0x3 << CTRL3_JIGSET_SHIFT)
+#define CTRL3_BOOTSET_MASK             (0x3 << CTRL3_BOOTSET_SHIFT)
+#define CTRL3_ADCDBSET_MASK            (0x3 << CTRL3_ADCDBSET_SHIFT)
+
+/* Slave addr = 0x4A: Charger */
+enum max14577_charger_reg {
+       MAX14577_CHG_REG_STATUS3        = 0x06,
+       MAX14577_CHG_REG_CHG_CTRL1      = 0x0F,
+       MAX14577_CHG_REG_CHG_CTRL2      = 0x10,
+       MAX14577_CHG_REG_CHG_CTRL3      = 0x11,
+       MAX14577_CHG_REG_CHG_CTRL4      = 0x12,
+       MAX14577_CHG_REG_CHG_CTRL5      = 0x13,
+       MAX14577_CHG_REG_CHG_CTRL6      = 0x14,
+       MAX14577_CHG_REG_CHG_CTRL7      = 0x15,
+
+       MAX14577_CHG_REG_END,
+};
+
+/* MAX14577 STATUS3 register */
+#define STATUS3_EOC_SHIFT              0
+#define STATUS3_CGMBC_SHIFT            1
+#define STATUS3_OVP_SHIFT              2
+#define STATUS3_MBCCHGERR_SHIFT                3
+#define STATUS3_EOC_MASK               (0x1 << STATUS3_EOC_SHIFT)
+#define STATUS3_CGMBC_MASK             (0x1 << STATUS3_CGMBC_SHIFT)
+#define STATUS3_OVP_MASK               (0x1 << STATUS3_OVP_SHIFT)
+#define STATUS3_MBCCHGERR_MASK         (0x1 << STATUS3_MBCCHGERR_SHIFT)
+
+/* MAX14577 CDETCTRL1 register */
+#define CDETCTRL1_CHGDETEN_SHIFT       0
+#define CDETCTRL1_CHGTYPMAN_SHIFT      1
+#define CDETCTRL1_DCDEN_SHIFT          2
+#define CDETCTRL1_DCD2SCT_SHIFT                3
+#define CDETCTRL1_DCHKTM_SHIFT         4
+#define CDETCTRL1_DBEXIT_SHIFT         5
+#define CDETCTRL1_DBIDLE_SHIFT         6
+#define CDETCTRL1_CDPDET_SHIFT         7
+#define CDETCTRL1_CHGDETEN_MASK                (0x1 << CDETCTRL1_CHGDETEN_SHIFT)
+#define CDETCTRL1_CHGTYPMAN_MASK       (0x1 << CDETCTRL1_CHGTYPMAN_SHIFT)
+#define CDETCTRL1_DCDEN_MASK           (0x1 << CDETCTRL1_DCDEN_SHIFT)
+#define CDETCTRL1_DCD2SCT_MASK         (0x1 << CDETCTRL1_DCD2SCT_SHIFT)
+#define CDETCTRL1_DCHKTM_MASK          (0x1 << CDETCTRL1_DCHKTM_SHIFT)
+#define CDETCTRL1_DBEXIT_MASK          (0x1 << CDETCTRL1_DBEXIT_SHIFT)
+#define CDETCTRL1_DBIDLE_MASK          (0x1 << CDETCTRL1_DBIDLE_SHIFT)
+#define CDETCTRL1_CDPDET_MASK          (0x1 << CDETCTRL1_CDPDET_SHIFT)
+
+/* MAX14577 CHGCTRL1 register */
+#define CHGCTRL1_TCHW_SHIFT            4
+#define CHGCTRL1_TCHW_MASK             (0x7 << CHGCTRL1_TCHW_SHIFT)
+
+/* MAX14577 CHGCTRL2 register */
+#define CHGCTRL2_MBCHOSTEN_SHIFT       6
+#define CHGCTRL2_MBCHOSTEN_MASK                (0x1 << CHGCTRL2_MBCHOSTEN_SHIFT)
+#define CHGCTRL2_VCHGR_RC_SHIFT                7
+#define CHGCTRL2_VCHGR_RC_MASK         (0x1 << CHGCTRL2_VCHGR_RC_SHIFT)
+
+/* MAX14577 CHGCTRL3 register */
+#define CHGCTRL3_MBCCVWRC_SHIFT                0
+#define CHGCTRL3_MBCCVWRC_MASK         (0xf << CHGCTRL3_MBCCVWRC_SHIFT)
+
+/* MAX14577 CHGCTRL4 register */
+#define CHGCTRL4_MBCICHWRCH_SHIFT      0
+#define CHGCTRL4_MBCICHWRCH_MASK       (0xf << CHGCTRL4_MBCICHWRCH_SHIFT)
+#define CHGCTRL4_MBCICHWRCL_SHIFT      4
+#define CHGCTRL4_MBCICHWRCL_MASK       (0x1 << CHGCTRL4_MBCICHWRCL_SHIFT)
+
+/* MAX14577 CHGCTRL5 register */
+#define CHGCTRL5_EOCS_SHIFT            0
+#define CHGCTRL5_EOCS_MASK             (0xf << CHGCTRL5_EOCS_SHIFT)
+
+/* MAX14577 CHGCTRL6 register */
+#define CHGCTRL6_AUTOSTOP_SHIFT                5
+#define CHGCTRL6_AUTOSTOP_MASK         (0x1 << CHGCTRL6_AUTOSTOP_SHIFT)
+
+/* MAX14577 CHGCTRL7 register */
+#define CHGCTRL7_OTPCGHCVS_SHIFT       0
+#define CHGCTRL7_OTPCGHCVS_MASK                (0x3 << CHGCTRL7_OTPCGHCVS_SHIFT)
+
+/* MAX14577 regulator current limits (as in CHGCTRL4 register), uA */
+#define MAX14577_REGULATOR_CURRENT_LIMIT_MIN            90000
+#define MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START    200000
+#define MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP      50000
+#define MAX14577_REGULATOR_CURRENT_LIMIT_MAX           950000
+
+/* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
+#define MAX14577_REGULATOR_SAFEOUT_VOLTAGE             4900000
+
+enum max14577_irq_source {
+       MAX14577_IRQ_INT1 = 0,
+       MAX14577_IRQ_INT2,
+       MAX14577_IRQ_INT3,
+
+       MAX14577_IRQ_REGS_NUM,
+};
+
+enum max14577_irq {
+       /* INT1 */
+       MAX14577_IRQ_INT1_ADC,
+       MAX14577_IRQ_INT1_ADCLOW,
+       MAX14577_IRQ_INT1_ADCERR,
+
+       /* INT2 */
+       MAX14577_IRQ_INT2_CHGTYP,
+       MAX14577_IRQ_INT2_CHGDETRUN,
+       MAX14577_IRQ_INT2_DCDTMR,
+       MAX14577_IRQ_INT2_DBCHG,
+       MAX14577_IRQ_INT2_VBVOLT,
+
+       /* INT3 */
+       MAX14577_IRQ_INT3_EOC,
+       MAX14577_IRQ_INT3_CGMBC,
+       MAX14577_IRQ_INT3_OVP,
+       MAX14577_IRQ_INT3_MBCCHGERR,
+
+       MAX14577_IRQ_NUM,
+};
+
+struct max14577 {
+       struct device *dev;
+       struct i2c_client *i2c; /* Slave addr = 0x4A */
+
+       struct regmap *regmap;
+
+       struct regmap_irq_chip_data *irq_data;
+       int irq;
+
+       /* Device ID */
+       u8 vendor_id;   /* Vendor Identification */
+       u8 device_id;   /* Chip Version */
+};
+
+/* MAX14577 shared regmap API function */
+static inline int max14577_read_reg(struct regmap *map, u8 reg, u8 *dest)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(map, reg, &val);
+       *dest = val;
+
+       return ret;
+}
+
+static inline int max14577_bulk_read(struct regmap *map, u8 reg, u8 *buf,
+               int count)
+{
+       return regmap_bulk_read(map, reg, buf, count);
+}
+
+static inline int max14577_write_reg(struct regmap *map, u8 reg, u8 value)
+{
+       return regmap_write(map, reg, value);
+}
+
+static inline int max14577_bulk_write(struct regmap *map, u8 reg, u8 *buf,
+               int count)
+{
+       return regmap_bulk_write(map, reg, buf, count);
+}
+
+static inline int max14577_update_reg(struct regmap *map, u8 reg, u8 mask,
+               u8 val)
+{
+       return regmap_update_bits(map, reg, mask, val);
+}
+
+#endif /* __MAX14577_PRIVATE_H__ */
diff --git a/include/linux/mfd/max14577.h b/include/linux/mfd/max14577.h
new file mode 100644 (file)
index 0000000..247b021
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * max14577.h - Driver for the Maxim 14577
+ *
+ * Copyright (C) 2013 Samsung Electrnoics
+ * Chanwoo Choi <cw00.choi@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski@samsung.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.
+ *
+ * This driver is based on max8997.h
+ *
+ * MAX14577 has MUIC, Charger devices.
+ * The devices share the same I2C bus and interrupt line
+ * included in this mfd driver.
+ */
+
+#ifndef __MAX14577_H__
+#define __MAX14577_H__
+
+#include <linux/mfd/max14577-private.h>
+#include <linux/regulator/consumer.h>
+
+/*
+ * MAX14577 Regulator
+ */
+
+/* MAX14577 regulator IDs */
+enum max14577_regulators {
+       MAX14577_SAFEOUT = 0,
+       MAX14577_CHARGER,
+
+       MAX14577_REG_MAX,
+};
+
+struct max14577_regulator_platform_data {
+       int id;
+       struct regulator_init_data *initdata;
+       struct device_node *of_node;
+};
+
+/*
+ * MAX14577 MFD platform data
+ */
+struct max14577_platform_data {
+       /* IRQ */
+       int irq_base;
+
+       /* current control GPIOs */
+       int gpio_pogo_vbatt_en;
+       int gpio_pogo_vbus_en;
+
+       /* current control GPIO control function */
+       int (*set_gpio_pogo_vbatt_en) (int gpio_val);
+       int (*set_gpio_pogo_vbus_en) (int gpio_val);
+
+       int (*set_gpio_pogo_cb) (int new_dev);
+
+       struct max14577_regulator_platform_data *regulators;
+};
+
+#endif /* __MAX14577_H__ */
index d327d4971e4f6a89dea4556c13af4d44d6b9059a..8c75a9c8dfab30085d9190c3283a6b56d7fc30b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * max77686.h - Voltage regulator driver for the Maxim 77686
+ * max77686-private.h - Voltage regulator driver for the Maxim 77686
  *
  *  Copyright (C) 2012 Samsung Electrnoics
  *  Chiwoong Byun <woong.byun@samsung.com>
index fb465dfbb59e1eadea1a2058dfb92853982edcf1..ad1ae7f345ad9482df4a47c0ddc4ab11bd34e2ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * max8997.h - Voltage regulator driver for the Maxim 8997
+ * max8997-private.h - Voltage regulator driver for the Maxim 8997
  *
  *  Copyright (C) 2010 Samsung Electrnoics
  *  MyungJoo Ham <myungjoo.ham@samsung.com>
index 84844e0a570449d2c6efc76f74d4d72df7c4183a..4ecb24b4b863be4158263466ce919e78b42714d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * max8998.h - Voltage regulator driver for the Maxim 8998
+ * max8998-private.h - Voltage regulator driver for the Maxim 8998
  *
  *  Copyright (C) 2009-2010 Samsung Electrnoics
  *  Kyungmin Park <kyungmin.park@samsung.com>
index 67c17b5a6f449cc760a28a621daf5f5ef0529586..6156686bf108f38b91fcfb09766f73012dac20ea 100644 (file)
@@ -21,8 +21,6 @@ int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val);
 int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset,
                u32 mask, u32 val);
 
-int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
-
 int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
                irq_handler_t handler, const char *name, void *dev);
 int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq,
index d498d98f0c2cbfd3c9076aa439433a23caa80899..fb96c84dada50c0f425681e71fff1ca5702aa342 100644 (file)
@@ -159,6 +159,9 @@ struct ti_tscadc_dev {
        int adc_cell;   /* -1 if not used */
        struct mfd_cell cells[TSCADC_CELLS];
        u32 reg_se_cache;
+       bool adc_waiting;
+       bool adc_in_use;
+       wait_queue_head_t reg_se_wait;
        spinlock_t reg_lock;
        unsigned int clk_div;
 
@@ -176,8 +179,9 @@ static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
        return *tscadc_dev;
 }
 
-void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc);
-void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val);
+void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val);
+void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val);
 void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val);
+void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tsadc);
 
 #endif
index 87994542573ba713580b4e6e518a76b39243b78b..cbecec2e353a3df0d931da2c86d5c206c84ea3eb 100644 (file)
 #define TPS6586X_SLEW_RATE_SET         0x08
 #define TPS6586X_SLEW_RATE_MASK         0x07
 
+/* VERSION CRC */
+#define TPS658621A     0x15
+#define TPS658621CD    0x2c
+#define TPS658623      0x1b
+#define TPS658643      0x03
+
 enum {
        TPS6586X_ID_SYS,
        TPS6586X_ID_SM_0,
@@ -97,5 +103,6 @@ extern int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask);
 extern int tps6586x_update(struct device *dev, int reg, uint8_t val,
                           uint8_t mask);
 extern int tps6586x_irq_get_virq(struct device *dev, int irq);
+extern int tps6586x_get_version(struct device *dev);
 
 #endif /*__LINUX_MFD_TPS6586X_H */
index 4b2860ae3828ef7ab6b5e934de636626a64fcb55..747cd6baf711a41783201ddfeeb95aaca49a7b88 100644 (file)
@@ -1,14 +1,12 @@
 /*
- *  arch/arm/mach-sa1100/include/mach/mcp.h
- *
  *  Copyright (C) 2005 Russell King.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#ifndef __ASM_ARM_ARCH_MCP_H
-#define __ASM_ARM_ARCH_MCP_H
+#ifndef __MFD_MCP_SA11X0_H
+#define __MFD_MCP_SA11X0_H
 
 #include <linux/types.h>
 
index 44ef5da214705a1990256d574a2f6edc53b08c48..bcbb642a7641d936c441e8c2211e9dc287513b6b 100644 (file)
 
 #include <linux/types.h>
 
-struct ssbi_slave_info {
-       const char      *name;
-       void            *platform_data;
-};
-
-enum ssbi_controller_type {
-       MSM_SBI_CTRL_SSBI = 0,
-       MSM_SBI_CTRL_SSBI2,
-       MSM_SBI_CTRL_PMIC_ARBITER,
-};
-
-struct ssbi_platform_data {
-       struct ssbi_slave_info  slave;
-       enum ssbi_controller_type controller_type;
-};
-
-int ssbi_write(struct device *dev, u16 addr, u8 *buf, int len);
+int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len);
 int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len);
+
 #endif
index 324988dea4bd31bd8ad8f6d416c701c2f874966f..07f8f141727d99c19403f2994ac42ce63ff6f23a 100644 (file)
@@ -212,7 +212,7 @@ config SND_SOC_IMX_SPDIF
 
 config SND_SOC_IMX_MC13783
        tristate "SoC Audio support for I.MX boards with mc13783"
-       depends on MFD_MC13783 && ARM
+       depends on MFD_MC13XXX && ARM
        select SND_SOC_IMX_SSI
        select SND_SOC_IMX_AUDMUX
        select SND_SOC_MC13783