]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'mfd-3.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 8 Sep 2013 03:14:19 +0000 (20:14 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 8 Sep 2013 03:14:19 +0000 (20:14 -0700)
Pull MFD (multi-function device) updates from Samuel Ortiz:
 "For the 3.12 merge window we have one new driver for the DA9063 PMIC
  from Dialog Semiconductor.

  Besides that driver we also have:

   - Device tree support for the s2mps11 driver

   - More devm_* conversion for the pm8921, max89xx, menelaus, tps65010,
     wl1273 and pcf50633-adc drivers.

   - A conversion to threaded IRQ and IRQ domain for the twl6030 driver.

   - A fairly big update for the rtsx driver: Better power saving
     support, better vendor settings handling, and a few fixes.

   - Support for a couple more boards (COMe-bHL6 and COMe-cTH6) for the
     Kontron driver.

   - A conversion to the dev_get_platdata() API for all MFD drivers.

   - A removal of non-DT (legacy) support for the twl6040 driver.

   - A few fixes and additions (Mic detect level) to the wm5110 register
     tables.

   - Regmap support for the davinci_voicecodec driver.

   - The usual bunch of minor cleanups and janitorial fixes"

* tag 'mfd-3.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next: (81 commits)
  mfd: ucb1x00-core: Rewrite ucb1x00_add_dev()
  mfd: ab8500-debugfs: Apply a check for -ENOMEM after allocating memory for event name
  mfd: ab8500-debugfs: Apply a check for -ENOMEM after allocating memory for sysfs
  mfd: timberdale: Use module_pci_driver
  mfd: timberdale: Remove redundant break
  mfd: timberdale: Staticize local variables
  mfd: ab8500-debugfs: Staticize local variables
  mfd: db8500-prcmu: Staticize clk_mgt
  mfd: db8500-prcmu: Use ANSI function declaration
  mfd: omap-usb-host: Staticize usbhs_driver_name
  mfd: 88pm805: Fix potential NULL pdata dereference
  mfd: 88pm800: Fix potential NULL pdata dereference
  mfd: twl6040: Use regmap for register cache
  mfd: davinci_voicecodec: Provide a regmap for register I/O
  mfd: davinci_voicecodec: Remove unused read and write functions
  mmc: memstick: rtsx: Modify copyright comments
  mmc: rtsx: Clear SD_CLK toggle enable bit if switching voltage fail
  mfd: mmc: rtsx: Change default tx phase
  mfd: pcf50633-adc: Use devm_*() functions
  mfd: rtsx: Copyright modifications
  ...

106 files changed:
Documentation/devicetree/bindings/mfd/palmas.txt
Documentation/devicetree/bindings/mfd/s2mps11.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/palmas-pmic.txt
drivers/memstick/host/rtsx_pci_ms.c
drivers/mfd/88pm800.c
drivers/mfd/88pm805.c
drivers/mfd/88pm860x-core.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/aat2870-core.c
drivers/mfd/ab3100-core.c
drivers/mfd/ab8500-debugfs.c
drivers/mfd/ab8500-gpadc.c
drivers/mfd/adp5520.c
drivers/mfd/arizona-core.c
drivers/mfd/as3711.c
drivers/mfd/asic3.c
drivers/mfd/da903x.c
drivers/mfd/da9052-core.c
drivers/mfd/da9055-core.c
drivers/mfd/da9055-i2c.c
drivers/mfd/da9063-core.c [new file with mode: 0644]
drivers/mfd/da9063-i2c.c [new file with mode: 0644]
drivers/mfd/da9063-irq.c [new file with mode: 0644]
drivers/mfd/davinci_voicecodec.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/dm355evm_msp.c
drivers/mfd/ezx-pcap.c
drivers/mfd/htc-egpio.c
drivers/mfd/htc-i2cpld.c
drivers/mfd/htc-pasic3.c
drivers/mfd/intel_msic.c
drivers/mfd/kempld-core.c
drivers/mfd/lm3533-core.c
drivers/mfd/lp8788.c
drivers/mfd/lpc_ich.c
drivers/mfd/max77686.c
drivers/mfd/max77693.c
drivers/mfd/max8925-i2c.c
drivers/mfd/max8997.c
drivers/mfd/max8998.c
drivers/mfd/mcp-sa11x0.c
drivers/mfd/menelaus.c
drivers/mfd/mfd-core.c
drivers/mfd/omap-usb-host.c
drivers/mfd/palmas.c
drivers/mfd/pcf50633-adc.c
drivers/mfd/pcf50633-core.c
drivers/mfd/pm8921-core.c
drivers/mfd/rc5t583.c
drivers/mfd/rtl8411.c
drivers/mfd/rts5209.c
drivers/mfd/rts5227.c
drivers/mfd/rts5229.c
drivers/mfd/rts5249.c
drivers/mfd/rtsx_pcr.c
drivers/mfd/rtsx_pcr.h
drivers/mfd/sec-core.c
drivers/mfd/si476x-i2c.c
drivers/mfd/sm501.c
drivers/mfd/sta2x11-mfd.c
drivers/mfd/stmpe.c
drivers/mfd/syscon.c
drivers/mfd/t7l66xb.c
drivers/mfd/tc3589x.c
drivers/mfd/tc6387xb.c
drivers/mfd/tc6393xb.c
drivers/mfd/ti-ssp.c
drivers/mfd/ti_am335x_tscadc.c
drivers/mfd/timberdale.c
drivers/mfd/tps6105x.c
drivers/mfd/tps65010.c
drivers/mfd/tps65090.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65912-core.c
drivers/mfd/tps80031.c
drivers/mfd/twl-core.c
drivers/mfd/twl4030-audio.c
drivers/mfd/twl4030-madc.c
drivers/mfd/twl4030-power.c
drivers/mfd/twl6030-irq.c
drivers/mfd/twl6040.c
drivers/mfd/ucb1400_core.c
drivers/mfd/ucb1x00-core.c
drivers/mfd/wl1273-core.c
drivers/mfd/wm5110-tables.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm831x-irq.c
drivers/mfd/wm831x-spi.c
drivers/mfd/wm8350-i2c.c
drivers/mfd/wm8400-core.c
drivers/mfd/wm8994-core.c
drivers/mfd/wm8994-irq.c
drivers/mmc/host/rtsx_pci_sdmmc.c
include/linux/mfd/da9063/core.h [new file with mode: 0644]
include/linux/mfd/da9063/pdata.h [new file with mode: 0644]
include/linux/mfd/da9063/registers.h [new file with mode: 0644]
include/linux/mfd/davinci_voicecodec.h
include/linux/mfd/mcp.h
include/linux/mfd/palmas.h
include/linux/mfd/rtsx_common.h
include/linux/mfd/rtsx_pci.h
include/linux/mfd/samsung/s2mps11.h
include/linux/mfd/ti_am335x_tscadc.h
include/linux/mfd/twl6040.h
include/linux/mfd/ucb1x00.h

index 892537d1a48f8fc394aa6c1330fa338c7a27bce7..e5f0f830346167e1a91f3430ecdbb0ca92ab1444 100644 (file)
@@ -5,6 +5,7 @@ twl6035 (palmas)
 twl6037 (palmas)
 tps65913 (palmas)
 tps65914 (palmas)
+tps659038
 
 Required properties:
 - compatible : Should be from the list
@@ -14,6 +15,7 @@ Required properties:
   ti,tps65913
   ti,tps65914
   ti,tps80036
+  ti,tps659038
 and also the generic series names
   ti,palmas
 - interrupt-controller : palmas has its own internal IRQs
diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
new file mode 100644 (file)
index 0000000..c9332c6
--- /dev/null
@@ -0,0 +1,109 @@
+
+* Samsung S2MPS11 Voltage and Current Regulator
+
+The Samsung S2MP211 is a multi-function device which includes voltage and
+current regulators, RTC, charger controller and other sub-blocks. It is
+interfaced to the host controller using a I2C interface. Each sub-block is
+addressed by the host system using different I2C slave address.
+
+Required properties:
+- compatible: Should be "samsung,s2mps11-pmic".
+- reg: Specifies the I2C slave address of the pmic block. It should be 0x66.
+
+Optional properties:
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the interrupts from s2mps11 are delivered to.
+- interrupts: Interrupt specifiers for interrupt sources.
+
+Optional nodes:
+- clocks: s2mps11 provides three(AP/CP/BT) buffered 32.768 KHz outputs, so to
+  register these as clocks with common clock framework instantiate a sub-node
+  named "clocks". It uses the common clock binding documented in :
+  [Documentation/devicetree/bindings/clock/clock-bindings.txt]
+  - #clock-cells: should be 1.
+
+  - The following is the list of clocks generated by the controller. Each clock
+    is assigned an identifier and client nodes use this identifier to specify
+    the clock which they consume.
+    Clock               ID
+    ----------------------
+    32KhzAP            0
+    32KhzCP            1
+    32KhzBT            2
+
+- regulators: The regulators of s2mps11 that have to be instantiated should be
+included in a sub-node named 'regulators'. Regulator nodes included in this
+sub-node should be of the format as listed below.
+
+       regulator_name {
+               [standard regulator constraints....];
+       };
+
+ regulator-ramp-delay for BUCKs = [6250/12500/25000(default)/50000] uV/us
+
+ BUCK[2/3/4/6] supports disabling ramp delay on hardware, so explictly
+ regulator-ramp-delay = <0> can be used for them to disable ramp delay.
+ In absence of regulator-ramp-delay property, default ramp delay will be used.
+
+NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set
+for a particular group of BUCKs. So provide same regulator-ramp-delay<value>.
+Grouping of BUCKs sharing ramp rate setting is as follow : BUCK[1, 6],
+BUCK[3, 4], and BUCK[7, 8, 10]
+
+The regulator constraints inside the regulator nodes use the standard regulator
+bindings which are documented elsewhere.
+
+The following are the names of the regulators that the s2mps11 pmic block
+supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
+as per the datasheet of s2mps11.
+
+       - LDOn
+                 - valid values for n are 1 to 28
+                 - Example: LDO0, LD01, LDO28
+       - BUCKn
+                 - valid values for n are 1 to 9.
+                 - Example: BUCK1, BUCK2, BUCK9
+
+Example:
+
+       s2mps11_pmic@66 {
+               compatible = "samsung,s2mps11-pmic";
+               reg = <0x66>;
+
+               s2m_osc: clocks{
+                       #clock-cells = 1;
+                       clock-output-names = "xx", "yy", "zz";
+               };
+
+               regulators {
+                       ldo1_reg: LDO1 {
+                               regulator-name = "VDD_ABB_3.3V";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       ldo2_reg: LDO2 {
+                               regulator-name = "VDD_ALIVE_1.1V";
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-always-on;
+                       };
+
+                       buck1_reg: BUCK1 {
+                               regulator-name = "vdd_mif";
+                               regulator-min-microvolt = <950000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       buck2_reg: BUCK2 {
+                               regulator-name = "vdd_arm";
+                               regulator-min-microvolt = <950000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <50000>;
+                       };
+               };
+       };
index a22e4c70db5cea846b3ee477822f6d73cb837668..875639ae0606e1e6637cacd9ef35dfde9ec0399a 100644 (file)
@@ -36,6 +36,9 @@ Optional nodes:
               ti,smps-range - OTP has the wrong range set for the hardware so override
               0 - low range, 1 - high range.
 
+- ti,system-power-controller: Telling whether or not this pmic is controlling
+                             the system power.
+
 Example:
 
 #include <dt-bindings/interrupt-controller/irq.h>
@@ -48,6 +51,8 @@ pmic {
 
        ti,ldo6-vibrator;
 
+       ti,system-power-controller;
+
        regulators {
                smps12_reg : smps12 {
                        regulator-name = "smps12";
index 64a779c58a74fd9346444c62663817010f5331d3..cf8bd727dfc774e58bec29ea9f6592c39682dcd5 100644 (file)
@@ -1,6 +1,6 @@
 /* Realtek PCI-Express Memstick Card Interface driver
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #include <linux/module.h>
index 6c954835d61ecb04dd0801ccae801033869f2b74..a65447d65605fe7d7539082322a70cceae9c18c7 100644 (file)
@@ -333,9 +333,11 @@ static int device_rtc_init(struct pm80x_chip *chip,
 {
        int ret;
 
-       rtc_devs[0].platform_data = pdata->rtc;
-       rtc_devs[0].pdata_size =
-                       pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
+       if (pdata) {
+               rtc_devs[0].platform_data = pdata->rtc;
+               rtc_devs[0].pdata_size =
+                               pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
+       }
        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
                              ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
        if (ret) {
@@ -541,7 +543,7 @@ static int pm800_probe(struct i2c_client *client,
 {
        int ret = 0;
        struct pm80x_chip *chip;
-       struct pm80x_platform_data *pdata = client->dev.platform_data;
+       struct pm80x_platform_data *pdata = dev_get_platdata(&client->dev);
        struct pm80x_subchip *subchip;
 
        ret = pm80x_init(client);
@@ -578,7 +580,7 @@ static int pm800_probe(struct i2c_client *client,
                goto err_device_init;
        }
 
-       if (pdata->plat_config)
+       if (pdata && pdata->plat_config)
                pdata->plat_config(chip, pdata);
 
        return 0;
index 521602231c7bc43c8ec007f078ae5c4d38bcaa7d..8a5b6ffb5afb6fbedbd8a1364a879890a6ebfba5 100644 (file)
@@ -227,7 +227,7 @@ static int pm805_probe(struct i2c_client *client,
 {
        int ret = 0;
        struct pm80x_chip *chip;
-       struct pm80x_platform_data *pdata = client->dev.platform_data;
+       struct pm80x_platform_data *pdata = dev_get_platdata(&client->dev);
 
        ret = pm80x_init(client);
        if (ret) {
@@ -243,7 +243,7 @@ static int pm805_probe(struct i2c_client *client,
                goto err_805_init;
        }
 
-       if (pdata->plat_config)
+       if (pdata && pdata->plat_config)
                pdata->plat_config(chip, pdata);
 
 err_805_init:
index eeb481d426b5df159264cc28e4bd56210c1ae1e0..7ebe9ef1eba663006399ec1b52f327e3fd3d0e47 100644 (file)
@@ -1130,7 +1130,7 @@ static int pm860x_dt_init(struct device_node *np,
 static int pm860x_probe(struct i2c_client *client,
                                  const struct i2c_device_id *id)
 {
-       struct pm860x_platform_data *pdata = client->dev.platform_data;
+       struct pm860x_platform_data *pdata = dev_get_platdata(&client->dev);
        struct device_node *node = client->dev.of_node;
        struct pm860x_chip *chip;
        int ret;
index aecd6ddcbbbf75699f1ddab73241ee21eb888687..e0e46f50f95d394642f740b111d91d5dce8431f6 100644 (file)
@@ -139,6 +139,18 @@ config MFD_DA9055
          This driver can be built as a module. If built as a module it will be
          called "da9055"
 
+config MFD_DA9063
+       bool "Dialog Semiconductor DA9063 PMIC Support"
+       select MFD_CORE
+       select REGMAP_I2C
+       select REGMAP_IRQ
+       depends on I2C=y && GENERIC_HARDIRQS
+       help
+         Say yes here for support for the Dialog Semiconductor DA9063 PMIC.
+         This includes the I2C driver and core APIs.
+         Additional drivers must be enabled in order to use the functionality
+         of the device.
+
 config MFD_MC13783
        tristate
 
@@ -1070,7 +1082,7 @@ config MFD_WM5110
          Support for Wolfson Microelectronics WM5110 low power audio SoC
 
 config MFD_WM8997
-       bool "Support Wolfson Microelectronics WM8997"
+       bool "Wolfson Microelectronics WM8997"
        depends on MFD_ARIZONA
        help
          Support for Wolfson Microelectronics WM8997 low power audio SoC
index 3c90051ffa5a390972a4d3cffb34f4b055ed3d8f..15b905c6553c07e7953b7cc4b57c63fcd5ad06a1 100644 (file)
@@ -107,6 +107,9 @@ obj-$(CONFIG_MFD_LP8788)    += lp8788.o lp8788-irq.o
 da9055-objs                    := da9055-core.o da9055-i2c.o
 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_MAX77686)     += max77686.o max77686-irq.o
 obj-$(CONFIG_MFD_MAX77693)     += max77693.o max77693-irq.o
 obj-$(CONFIG_MFD_MAX8907)      += max8907.o
index d4f594517521b30e5bc3344208b21d03801ef14d..6f68472e0ca633e9b0ec5f08db4f1389af93336e 100644 (file)
@@ -363,7 +363,7 @@ static inline void aat2870_uninit_debugfs(struct aat2870_data *aat2870)
 static int aat2870_i2c_probe(struct i2c_client *client,
                             const struct i2c_device_id *id)
 {
-       struct aat2870_platform_data *pdata = client->dev.platform_data;
+       struct aat2870_platform_data *pdata = dev_get_platdata(&client->dev);
        struct aat2870_data *aat2870;
        int i, j;
        int ret = 0;
index ddc669d19530ee7a171547b78983adab6b4b7e0d..b348ae5206297eb554e70decb2e21d216fd8a2f6 100644 (file)
@@ -854,7 +854,7 @@ static int ab3100_probe(struct i2c_client *client,
 {
        struct ab3100 *ab3100;
        struct ab3100_platform_data *ab3100_plf_data =
-               client->dev.platform_data;
+               dev_get_platdata(&client->dev);
        int err;
        int i;
 
index 7d1f1b08fc4be76c20310879b34b0a2394c3034f..e33e385af0a29e7930e4277984c640a1cf1db975 100644 (file)
@@ -159,7 +159,7 @@ static struct hwreg_cfg hwreg_cfg = {
 
 static struct ab8500_prcmu_ranges *debug_ranges;
 
-struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
+static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
        [0x0] = {
                .num_ranges = 0,
                .range = NULL,
@@ -488,7 +488,7 @@ struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
        },
 };
 
-struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
+static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
        [0x0] = {
                .num_ranges = 0,
                .range = NULL,
@@ -847,7 +847,7 @@ struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
        },
 };
 
-struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
+static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
        [AB8500_M_FSM_RANK] = {
                .num_ranges = 1,
                .range = (struct ab8500_reg_range[]) {
@@ -1377,7 +1377,7 @@ void ab8500_dump_all_banks(struct device *dev)
 
 /* Space for 500 registers. */
 #define DUMP_MAX_REGS 700
-struct ab8500_register_dump
+static struct ab8500_register_dump
 {
        u8 bank;
        u8 reg;
@@ -2800,7 +2800,13 @@ static ssize_t ab8500_subscribe_write(struct file *file,
         */
        dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute),
                GFP_KERNEL);
+       if (!dev_attr[irq_index])
+               return -ENOMEM;
+
        event_name[irq_index] = kmalloc(count, GFP_KERNEL);
+       if (!event_name[irq_index])
+               return -ENOMEM;
+
        sprintf(event_name[irq_index], "%lu", user_val);
        dev_attr[irq_index]->show = show_irq;
        dev_attr[irq_index]->store = NULL;
index 7623e91238287b4d04f6b5d28e994fd0e478117b..36000f920981b055195c1cd4b1dfd88954050655 100644 (file)
@@ -867,6 +867,7 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
                gpadc->cal_data[ADC_INPUT_VBAT].offset);
 }
 
+#ifdef CONFIG_PM_RUNTIME
 static int ab8500_gpadc_runtime_suspend(struct device *dev)
 {
        struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
@@ -885,7 +886,9 @@ static int ab8500_gpadc_runtime_resume(struct device *dev)
                dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret);
        return ret;
 }
+#endif
 
+#ifdef CONFIG_PM_SLEEP
 static int ab8500_gpadc_suspend(struct device *dev)
 {
        struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
@@ -913,6 +916,7 @@ static int ab8500_gpadc_resume(struct device *dev)
        mutex_unlock(&gpadc->ab8500_gpadc_lock);
        return ret;
 }
+#endif
 
 static int ab8500_gpadc_probe(struct platform_device *pdev)
 {
index 28346ad0b4a6da0eee7e5e6f09e025769d11b024..62501553d63c4f7c2b49da5c73d79141d964179e 100644 (file)
@@ -207,7 +207,7 @@ static int adp5520_remove_subdevs(struct adp5520_chip *chip)
 static int adp5520_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
 {
-       struct adp5520_platform_data *pdata = client->dev.platform_data;
+       struct adp5520_platform_data *pdata = dev_get_platdata(&client->dev);
        struct platform_device *pdev;
        struct adp5520_chip *chip;
        int ret;
index 89a115301a0cbea26adb9e4b1ffec8ef1cebe7f1..5ac3aa48473be0364d70eeae84a7a423b1a3be4d 100644 (file)
@@ -438,9 +438,9 @@ static int arizona_runtime_suspend(struct device *dev)
                }
        }
 
-       regulator_disable(arizona->dcvdd);
        regcache_cache_only(arizona->regmap, true);
        regcache_mark_dirty(arizona->regmap);
+       regulator_disable(arizona->dcvdd);
 
        return 0;
 }
index 01e414162702bcd1ccfcc8e73f099e8a95cf14b3..abd3ab7c0908ab6232f0e7d82a35361ca33c46c7 100644 (file)
@@ -129,7 +129,7 @@ static int as3711_i2c_probe(struct i2c_client *client,
        int ret;
 
        if (!client->dev.of_node) {
-               pdata = client->dev.platform_data;
+               pdata = dev_get_platdata(&client->dev);
                if (!pdata)
                        dev_dbg(&client->dev, "Platform data not found\n");
        } else {
index 9532f749412f6442f190d3ec34fff0c286b36e9d..fa22154c84e49cfb6be58930339ea180b8be77b6 100644 (file)
@@ -952,7 +952,7 @@ static void asic3_mfd_remove(struct platform_device *pdev)
 /* Core */
 static int __init asic3_probe(struct platform_device *pdev)
 {
-       struct asic3_platform_data *pdata = pdev->dev.platform_data;
+       struct asic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct asic3 *asic;
        struct resource *mem;
        unsigned long clksel;
index f1a316e0d6a68850e367d0455937be635148fa89..e0a2e0ee603be73a6d808efa2ce1673f9c32e7ae 100644 (file)
@@ -494,7 +494,7 @@ static int da903x_add_subdevs(struct da903x_chip *chip,
 static int da903x_probe(struct i2c_client *client,
                                  const struct i2c_device_id *id)
 {
-       struct da903x_platform_data *pdata = client->dev.platform_data;
+       struct da903x_platform_data *pdata = dev_get_platdata(&client->dev);
        struct da903x_chip *chip;
        unsigned int tmp;
        int ret;
index a3c9613f91664e87ae03f4496c3360df74c755ef..ea28a33576e45cd3c3df406a09264bd69a5c3298 100644 (file)
@@ -534,7 +534,7 @@ EXPORT_SYMBOL_GPL(da9052_regmap_config);
 
 int da9052_device_init(struct da9052 *da9052, u8 chip_id)
 {
-       struct da9052_pdata *pdata = da9052->dev->platform_data;
+       struct da9052_pdata *pdata = dev_get_platdata(da9052->dev);
        int ret;
 
        mutex_init(&da9052->auxadc_lock);
index 49cb23d37469153980f5b78ceb0126f1d46aa852..d3670cd3c3c6c0e025c80ec940851ee5599037b1 100644 (file)
@@ -379,8 +379,9 @@ static struct regmap_irq_chip da9055_regmap_irq_chip = {
 
 int da9055_device_init(struct da9055 *da9055)
 {
-       struct da9055_pdata *pdata = da9055->dev->platform_data;
+       struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
        int ret;
+       uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};
 
        if (pdata && pdata->init != NULL)
                pdata->init(da9055);
@@ -390,6 +391,10 @@ int da9055_device_init(struct da9055 *da9055)
        else
                da9055->irq_base = pdata->irq_base;
 
+       ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);
+       if (ret < 0)
+               return ret;
+
        ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
                                  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                  da9055->irq_base, &da9055_regmap_irq_chip,
index 607387ffe8caa85e6d0396facd62a094dc4523a7..13af7e50021eedd5767aa296cfe46118f55f49ac 100644 (file)
@@ -54,7 +54,7 @@ static int da9055_i2c_remove(struct i2c_client *i2c)
 }
 
 static struct i2c_device_id da9055_i2c_id[] = {
-       {"da9055-pmic", 0},
+       {"da9055", 0},
        { }
 };
 
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c
new file mode 100644 (file)
index 0000000..c9cf8d9
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * da9063-core.c: Device access for Dialog DA9063 modules
+ *
+ * Copyright 2012 Dialog Semiconductors Ltd.
+ * Copyright 2013 Philipp Zabel, Pengutronix
+ *
+ * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>,
+ *         Michal Hajduk <michal.hajduk@diasemi.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/mfd/core.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/da9063/core.h>
+#include <linux/mfd/da9063/pdata.h>
+#include <linux/mfd/da9063/registers.h>
+
+#include <linux/proc_fs.h>
+#include <linux/kthread.h>
+#include <linux/uaccess.h>
+
+
+static struct resource da9063_regulators_resources[] = {
+       {
+               .name   = "LDO_LIM",
+               .start  = DA9063_IRQ_LDO_LIM,
+               .end    = DA9063_IRQ_LDO_LIM,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource da9063_rtc_resources[] = {
+       {
+               .name   = "ALARM",
+               .start  = DA9063_IRQ_ALARM,
+               .end    = DA9063_IRQ_ALARM,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .name   = "TICK",
+               .start  = DA9063_IRQ_TICK,
+               .end    = DA9063_IRQ_TICK,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource da9063_onkey_resources[] = {
+       {
+               .start  = DA9063_IRQ_ONKEY,
+               .end    = DA9063_IRQ_ONKEY,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource da9063_hwmon_resources[] = {
+       {
+               .start  = DA9063_IRQ_ADC_RDY,
+               .end    = DA9063_IRQ_ADC_RDY,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+
+static struct mfd_cell da9063_devs[] = {
+       {
+               .name           = DA9063_DRVNAME_REGULATORS,
+               .num_resources  = ARRAY_SIZE(da9063_regulators_resources),
+               .resources      = da9063_regulators_resources,
+       },
+       {
+               .name           = DA9063_DRVNAME_LEDS,
+       },
+       {
+               .name           = DA9063_DRVNAME_WATCHDOG,
+       },
+       {
+               .name           = DA9063_DRVNAME_HWMON,
+               .num_resources  = ARRAY_SIZE(da9063_hwmon_resources),
+               .resources      = da9063_hwmon_resources,
+       },
+       {
+               .name           = DA9063_DRVNAME_ONKEY,
+               .num_resources  = ARRAY_SIZE(da9063_onkey_resources),
+               .resources      = da9063_onkey_resources,
+       },
+       {
+               .name           = DA9063_DRVNAME_RTC,
+               .num_resources  = ARRAY_SIZE(da9063_rtc_resources),
+               .resources      = da9063_rtc_resources,
+       },
+       {
+               .name           = DA9063_DRVNAME_VIBRATION,
+       },
+};
+
+int da9063_device_init(struct da9063 *da9063, unsigned int irq)
+{
+       struct da9063_pdata *pdata = da9063->dev->platform_data;
+       int model, revision;
+       int ret;
+
+       if (pdata) {
+               da9063->flags = pdata->flags;
+               da9063->irq_base = pdata->irq_base;
+       } else {
+               da9063->flags = 0;
+               da9063->irq_base = 0;
+       }
+       da9063->chip_irq = irq;
+
+       if (pdata && pdata->init != NULL) {
+               ret = pdata->init(da9063);
+               if (ret != 0) {
+                       dev_err(da9063->dev,
+                               "Platform initialization failed.\n");
+                       return ret;
+               }
+       }
+
+       ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model);
+       if (ret < 0) {
+               dev_err(da9063->dev, "Cannot read chip model id.\n");
+               return -EIO;
+       }
+       if (model != PMIC_DA9063) {
+               dev_err(da9063->dev, "Invalid chip model id: 0x%02x\n", model);
+               return -ENODEV;
+       }
+
+       ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &revision);
+       if (ret < 0) {
+               dev_err(da9063->dev, "Cannot read chip revision id.\n");
+               return -EIO;
+       }
+       revision >>= DA9063_CHIP_VARIANT_SHIFT;
+       if (revision != 3) {
+               dev_err(da9063->dev, "Unknown chip revision: %d\n", revision);
+               return -ENODEV;
+       }
+
+       da9063->model = model;
+       da9063->revision = revision;
+
+       dev_info(da9063->dev,
+                "Device detected (model-ID: 0x%02X  rev-ID: 0x%02X)\n",
+                model, revision);
+
+       ret = da9063_irq_init(da9063);
+       if (ret) {
+               dev_err(da9063->dev, "Cannot initialize interrupts.\n");
+               return ret;
+       }
+
+       ret = mfd_add_devices(da9063->dev, -1, da9063_devs,
+                             ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base,
+                             NULL);
+       if (ret)
+               dev_err(da9063->dev, "Cannot add MFD cells\n");
+
+       return ret;
+}
+
+void da9063_device_exit(struct da9063 *da9063)
+{
+       mfd_remove_devices(da9063->dev);
+       da9063_irq_exit(da9063);
+}
+
+MODULE_DESCRIPTION("PMIC driver for Dialog DA9063");
+MODULE_AUTHOR("Krystian Garbaciak <krystian.garbaciak@diasemi.com>, Michal Hajduk <michal.hajduk@diasemi.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
new file mode 100644 (file)
index 0000000..8db5c80
--- /dev/null
@@ -0,0 +1,182 @@
+/* da9063-i2c.c: Interrupt support for Dialog DA9063
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ * Copyright 2013 Philipp Zabel, Pengutronix
+ *
+ * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/da9063/core.h>
+#include <linux/mfd/da9063/pdata.h>
+#include <linux/mfd/da9063/registers.h>
+
+static const struct regmap_range da9063_readable_ranges[] = {
+       {
+               .range_min = DA9063_REG_PAGE_CON,
+               .range_max = DA9063_REG_SECOND_D,
+       }, {
+               .range_min = DA9063_REG_SEQ,
+               .range_max = DA9063_REG_ID_32_31,
+       }, {
+               .range_min = DA9063_REG_SEQ_A,
+               .range_max = DA9063_REG_AUTO3_LOW,
+       }, {
+               .range_min = DA9063_REG_T_OFFSET,
+               .range_max = DA9063_REG_GP_ID_19,
+       }, {
+               .range_min = DA9063_REG_CHIP_ID,
+               .range_max = DA9063_REG_CHIP_VARIANT,
+       },
+};
+
+static const struct regmap_range da9063_writeable_ranges[] = {
+       {
+               .range_min = DA9063_REG_PAGE_CON,
+               .range_max = DA9063_REG_PAGE_CON,
+       }, {
+               .range_min = DA9063_REG_FAULT_LOG,
+               .range_max = DA9063_REG_VSYS_MON,
+       }, {
+               .range_min = DA9063_REG_COUNT_S,
+               .range_max = DA9063_REG_ALARM_Y,
+       }, {
+               .range_min = DA9063_REG_SEQ,
+               .range_max = DA9063_REG_ID_32_31,
+       }, {
+               .range_min = DA9063_REG_SEQ_A,
+               .range_max = DA9063_REG_AUTO3_LOW,
+       }, {
+               .range_min = DA9063_REG_CONFIG_I,
+               .range_max = DA9063_REG_MON_REG_4,
+       }, {
+               .range_min = DA9063_REG_GP_ID_0,
+               .range_max = DA9063_REG_GP_ID_19,
+       },
+};
+
+static const struct regmap_range da9063_volatile_ranges[] = {
+       {
+               .range_min = DA9063_REG_STATUS_A,
+               .range_max = DA9063_REG_EVENT_D,
+       }, {
+               .range_min = DA9063_REG_CONTROL_F,
+               .range_max = DA9063_REG_CONTROL_F,
+       }, {
+               .range_min = DA9063_REG_ADC_MAN,
+               .range_max = DA9063_REG_ADC_MAN,
+       }, {
+               .range_min = DA9063_REG_ADC_RES_L,
+               .range_max = DA9063_REG_SECOND_D,
+       }, {
+               .range_min = DA9063_REG_MON_REG_5,
+               .range_max = DA9063_REG_MON_REG_6,
+       },
+};
+
+static const struct regmap_access_table da9063_readable_table = {
+       .yes_ranges = da9063_readable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063_readable_ranges),
+};
+
+static const struct regmap_access_table da9063_writeable_table = {
+       .yes_ranges = da9063_writeable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063_writeable_ranges),
+};
+
+static const struct regmap_access_table da9063_volatile_table = {
+       .yes_ranges = da9063_volatile_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063_volatile_ranges),
+};
+
+static const struct regmap_range_cfg da9063_range_cfg[] = {
+       {
+               .range_min = DA9063_REG_PAGE_CON,
+               .range_max = DA9063_REG_CHIP_VARIANT,
+               .selector_reg = DA9063_REG_PAGE_CON,
+               .selector_mask = 1 << DA9063_I2C_PAGE_SEL_SHIFT,
+               .selector_shift = DA9063_I2C_PAGE_SEL_SHIFT,
+               .window_start = 0,
+               .window_len = 256,
+       }
+};
+
+static struct regmap_config da9063_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .ranges = da9063_range_cfg,
+       .num_ranges = ARRAY_SIZE(da9063_range_cfg),
+       .max_register = DA9063_REG_CHIP_VARIANT,
+
+       .cache_type = REGCACHE_RBTREE,
+
+       .rd_table = &da9063_readable_table,
+       .wr_table = &da9063_writeable_table,
+       .volatile_table = &da9063_volatile_table,
+};
+
+static int da9063_i2c_probe(struct i2c_client *i2c,
+       const struct i2c_device_id *id)
+{
+       struct da9063 *da9063;
+       int ret;
+
+       da9063 = devm_kzalloc(&i2c->dev, sizeof(struct da9063), GFP_KERNEL);
+       if (da9063 == NULL)
+               return -ENOMEM;
+
+       i2c_set_clientdata(i2c, da9063);
+       da9063->dev = &i2c->dev;
+       da9063->chip_irq = i2c->irq;
+
+       da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config);
+       if (IS_ERR(da9063->regmap)) {
+               ret = PTR_ERR(da9063->regmap);
+               dev_err(da9063->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
+
+       return da9063_device_init(da9063, i2c->irq);
+}
+
+static int da9063_i2c_remove(struct i2c_client *i2c)
+{
+       struct da9063 *da9063 = i2c_get_clientdata(i2c);
+
+       da9063_device_exit(da9063);
+
+       return 0;
+}
+
+static const struct i2c_device_id da9063_i2c_id[] = {
+       {"da9063", PMIC_DA9063},
+       {},
+};
+MODULE_DEVICE_TABLE(i2c, da9063_i2c_id);
+
+static struct i2c_driver da9063_i2c_driver = {
+       .driver = {
+               .name = "da9063",
+               .owner = THIS_MODULE,
+       },
+       .probe    = da9063_i2c_probe,
+       .remove   = da9063_i2c_remove,
+       .id_table = da9063_i2c_id,
+};
+
+module_i2c_driver(da9063_i2c_driver);
diff --git a/drivers/mfd/da9063-irq.c b/drivers/mfd/da9063-irq.c
new file mode 100644 (file)
index 0000000..8229226
--- /dev/null
@@ -0,0 +1,193 @@
+/* da9063-irq.c: Interrupts support for Dialog DA9063
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ * Copyright 2013 Philipp Zabel, Pengutronix
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+#include <linux/mfd/da9063/core.h>
+#include <linux/mfd/da9063/pdata.h>
+
+#define        DA9063_REG_EVENT_A_OFFSET       0
+#define        DA9063_REG_EVENT_B_OFFSET       1
+#define        DA9063_REG_EVENT_C_OFFSET       2
+#define        DA9063_REG_EVENT_D_OFFSET       3
+#define EVENTS_BUF_LEN                 4
+
+static const u8 mask_events_buf[] = { [0 ... (EVENTS_BUF_LEN - 1)] = ~0 };
+
+struct da9063_irq_data {
+       u16 reg;
+       u8 mask;
+};
+
+static struct regmap_irq da9063_irqs[] = {
+       /* DA9063 event A register */
+       [DA9063_IRQ_ONKEY] = {
+               .reg_offset = DA9063_REG_EVENT_A_OFFSET,
+               .mask = DA9063_M_ONKEY,
+       },
+       [DA9063_IRQ_ALARM] = {
+               .reg_offset = DA9063_REG_EVENT_A_OFFSET,
+               .mask = DA9063_M_ALARM,
+       },
+       [DA9063_IRQ_TICK] = {
+               .reg_offset = DA9063_REG_EVENT_A_OFFSET,
+               .mask = DA9063_M_TICK,
+       },
+       [DA9063_IRQ_ADC_RDY] = {
+               .reg_offset = DA9063_REG_EVENT_A_OFFSET,
+               .mask = DA9063_M_ADC_RDY,
+       },
+       [DA9063_IRQ_SEQ_RDY] = {
+               .reg_offset = DA9063_REG_EVENT_A_OFFSET,
+               .mask = DA9063_M_SEQ_RDY,
+       },
+       /* DA9063 event B register */
+       [DA9063_IRQ_WAKE] = {
+               .reg_offset = DA9063_REG_EVENT_B_OFFSET,
+               .mask = DA9063_M_WAKE,
+       },
+       [DA9063_IRQ_TEMP] = {
+               .reg_offset = DA9063_REG_EVENT_B_OFFSET,
+               .mask = DA9063_M_TEMP,
+       },
+       [DA9063_IRQ_COMP_1V2] = {
+               .reg_offset = DA9063_REG_EVENT_B_OFFSET,
+               .mask = DA9063_M_COMP_1V2,
+       },
+       [DA9063_IRQ_LDO_LIM] = {
+               .reg_offset = DA9063_REG_EVENT_B_OFFSET,
+               .mask = DA9063_M_LDO_LIM,
+       },
+       [DA9063_IRQ_REG_UVOV] = {
+               .reg_offset = DA9063_REG_EVENT_B_OFFSET,
+               .mask = DA9063_M_UVOV,
+       },
+       [DA9063_IRQ_VDD_MON] = {
+               .reg_offset = DA9063_REG_EVENT_B_OFFSET,
+               .mask = DA9063_M_VDD_MON,
+       },
+       [DA9063_IRQ_WARN] = {
+               .reg_offset = DA9063_REG_EVENT_B_OFFSET,
+               .mask = DA9063_M_VDD_WARN,
+       },
+       /* DA9063 event C register */
+       [DA9063_IRQ_GPI0] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI0,
+       },
+       [DA9063_IRQ_GPI1] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI1,
+       },
+       [DA9063_IRQ_GPI2] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI2,
+       },
+       [DA9063_IRQ_GPI3] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI3,
+       },
+       [DA9063_IRQ_GPI4] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI4,
+       },
+       [DA9063_IRQ_GPI5] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI5,
+       },
+       [DA9063_IRQ_GPI6] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI6,
+       },
+       [DA9063_IRQ_GPI7] = {
+               .reg_offset = DA9063_REG_EVENT_C_OFFSET,
+               .mask = DA9063_M_GPI7,
+       },
+       /* DA9063 event D register */
+       [DA9063_IRQ_GPI8] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI8,
+       },
+       [DA9063_IRQ_GPI9] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI9,
+       },
+       [DA9063_IRQ_GPI10] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI10,
+       },
+       [DA9063_IRQ_GPI11] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI11,
+       },
+       [DA9063_IRQ_GPI12] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI12,
+       },
+       [DA9063_IRQ_GPI13] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI13,
+       },
+       [DA9063_IRQ_GPI14] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI14,
+       },
+       [DA9063_IRQ_GPI15] = {
+               .reg_offset = DA9063_REG_EVENT_D_OFFSET,
+               .mask = DA9063_M_GPI15,
+       },
+};
+
+static struct regmap_irq_chip da9063_irq_chip = {
+       .name = "da9063-irq",
+       .irqs = da9063_irqs,
+       .num_irqs = DA9063_NUM_IRQ,
+
+       .num_regs = 4,
+       .status_base = DA9063_REG_EVENT_A,
+       .mask_base = DA9063_REG_IRQ_MASK_A,
+       .ack_base = DA9063_REG_EVENT_A,
+       .init_ack_masked = true,
+};
+
+int da9063_irq_init(struct da9063 *da9063)
+{
+       int ret;
+
+       if (!da9063->chip_irq) {
+               dev_err(da9063->dev, "No IRQ configured\n");
+               return -EINVAL;
+       }
+
+       ret = regmap_add_irq_chip(da9063->regmap, da9063->chip_irq,
+                       IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
+                       da9063->irq_base, &da9063_irq_chip,
+                       &da9063->regmap_irq);
+       if (ret) {
+               dev_err(da9063->dev, "Failed to reguest IRQ %d: %d\n",
+                               da9063->chip_irq, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+void da9063_irq_exit(struct da9063 *da9063)
+{
+       regmap_del_irq_chip(da9063->chip_irq, da9063->regmap_irq);
+}
index fb64398506e9934725bba33d9b3dabe0e9b591fc..013ba8159dcda339a8f71729976afeffd9516873 100644 (file)
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/regmap.h>
 
 #include <sound/pcm.h>
 
 #include <linux/mfd/davinci_voicecodec.h>
 
-u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg)
-{
-       return __raw_readl(davinci_vc->base + reg);
-}
-
-void davinci_vc_write(struct davinci_vc *davinci_vc,
-                                          int reg, u32 val)
-{
-       __raw_writel(val, davinci_vc->base + reg);
-}
+static struct regmap_config davinci_vc_regmap = {
+       .reg_bits = 32,
+       .val_bits = 32,
+};
 
 static int __init davinci_vc_probe(struct platform_device *pdev)
 {
@@ -74,6 +69,14 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
                goto fail;
        }
 
+       davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev,
+                                                  davinci_vc->base,
+                                                  &davinci_vc_regmap);
+       if (IS_ERR(davinci_vc->regmap)) {
+               ret = PTR_ERR(davinci_vc->regmap);
+               goto fail;
+       }
+
        res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
        if (!res) {
                dev_err(&pdev->dev, "no DMA resource\n");
index 0d68eb1a5ec528924695959646a29a31d87ca1a8..53f371dcbb6e96550537b108fffbba1c00af3015 100644 (file)
@@ -465,7 +465,7 @@ static DEFINE_SPINLOCK(clk_mgt_lock);
 
 #define CLK_MGT_ENTRY(_name, _branch, _clk38div)[PRCMU_##_name] = \
        { (PRCM_##_name##_MGT), 0 , _branch, _clk38div}
-struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
+static struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
        CLK_MGT_ENTRY(SGACLK, PLL_DIV, false),
        CLK_MGT_ENTRY(UARTCLK, PLL_FIX, true),
        CLK_MGT_ENTRY(MSP02CLK, PLL_FIX, true),
@@ -2319,7 +2319,7 @@ int prcmu_ac_wake_req(void)
 /**
  * prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem
  */
-void prcmu_ac_sleep_req()
+void prcmu_ac_sleep_req(void)
 {
        u32 val;
 
index 7710227d284e82f3ea98bd6dcf307abd177f71e9..7a55c0071fa8e9840b47420277673120547df191 100644 (file)
@@ -315,8 +315,8 @@ static int add_children(struct i2c_client *client)
        }
 
        /* MMC/SD inputs -- right after the last config input */
-       if (client->dev.platform_data) {
-               void (*mmcsd_setup)(unsigned) = client->dev.platform_data;
+       if (dev_get_platdata(&client->dev)) {
+               void (*mmcsd_setup)(unsigned) = dev_get_platdata(&client->dev);
 
                mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5);
        }
index 5502106ad5157dcf8c3a2648c29e949c1b60b7b2..7245b0c5b794be489d1c5d250c196c92e028a48f 100644 (file)
@@ -177,7 +177,7 @@ static void pcap_msr_work(struct work_struct *work)
 static void pcap_isr_work(struct work_struct *work)
 {
        struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work);
-       struct pcap_platform_data *pdata = pcap->spi->dev.platform_data;
+       struct pcap_platform_data *pdata = dev_get_platdata(&pcap->spi->dev);
        u32 msr, isr, int_sel, service;
        int irq;
 
@@ -394,7 +394,7 @@ static int pcap_add_subdev(struct pcap_chip *pcap,
 static int ezx_pcap_remove(struct spi_device *spi)
 {
        struct pcap_chip *pcap = spi_get_drvdata(spi);
-       struct pcap_platform_data *pdata = spi->dev.platform_data;
+       struct pcap_platform_data *pdata = dev_get_platdata(&spi->dev);
        int i, adc_irq;
 
        /* remove all registered subdevs */
@@ -420,7 +420,7 @@ static int ezx_pcap_remove(struct spi_device *spi)
 
 static int ezx_pcap_probe(struct spi_device *spi)
 {
-       struct pcap_platform_data *pdata = spi->dev.platform_data;
+       struct pcap_platform_data *pdata = dev_get_platdata(&spi->dev);
        struct pcap_chip *pcap;
        int i, adc_irq;
        int ret = -ENODEV;
index 26aca545084b38bc6373b85998410bd28392b1f6..49f39feca7843e73bce9e906953ed5620936a193 100644 (file)
@@ -261,7 +261,7 @@ static void egpio_write_cache(struct egpio_info *ei)
 
 static int __init egpio_probe(struct platform_device *pdev)
 {
-       struct htc_egpio_platform_data *pdata = pdev->dev.platform_data;
+       struct htc_egpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct resource   *res;
        struct egpio_info *ei;
        struct gpio_chip  *chip;
index c9dfce6ae0c289229bf895adb92d7a27e440ec8e..d7b2a75aca3e5fcd9b38de98ceb4f5c3b16f013e 100644 (file)
@@ -340,7 +340,7 @@ static int htcpld_setup_chip_irq(
        int ret = 0;
 
        /* Get the platform and driver data */
-       pdata = dev->platform_data;
+       pdata = dev_get_platdata(dev);
        htcpld = platform_get_drvdata(pdev);
        chip = &htcpld->chip[chip_index];
        plat_chip_data = &pdata->chip[chip_index];
@@ -375,7 +375,7 @@ static int htcpld_register_chip_i2c(
        struct i2c_board_info info;
 
        /* Get the platform and driver data */
-       pdata = dev->platform_data;
+       pdata = dev_get_platdata(dev);
        htcpld = platform_get_drvdata(pdev);
        chip = &htcpld->chip[chip_index];
        plat_chip_data = &pdata->chip[chip_index];
@@ -447,7 +447,7 @@ static int htcpld_register_chip_gpio(
        int ret = 0;
 
        /* Get the platform and driver data */
-       pdata = dev->platform_data;
+       pdata = dev_get_platdata(dev);
        htcpld = platform_get_drvdata(pdev);
        chip = &htcpld->chip[chip_index];
        plat_chip_data = &pdata->chip[chip_index];
@@ -509,7 +509,7 @@ static int htcpld_setup_chips(struct platform_device *pdev)
        int i;
 
        /* Get the platform and driver data */
-       pdata = dev->platform_data;
+       pdata = dev_get_platdata(dev);
        htcpld = platform_get_drvdata(pdev);
 
        /* Setup each chip's output GPIOs */
@@ -574,7 +574,7 @@ static int htcpld_core_probe(struct platform_device *pdev)
        if (!dev)
                return -ENODEV;
 
-       pdata = dev->platform_data;
+       pdata = dev_get_platdata(dev);
        if (!pdata) {
                dev_warn(dev, "Platform data not found for htcpld core!\n");
                return -ENXIO;
index 0a5e85fd8517c145a952183349ee7fbc310ad85b..6bf92a507b9546b911e258037c2dba3ac391851b 100644 (file)
@@ -126,7 +126,7 @@ static struct mfd_cell ds1wm_cell __initdata = {
 
 static int __init pasic3_probe(struct platform_device *pdev)
 {
-       struct pasic3_platform_data *pdata = pdev->dev.platform_data;
+       struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct device *dev = &pdev->dev;
        struct pasic3_data *asic;
        struct resource *r;
index 4f2462f0963e6fac016f6cacbf917a012870eb46..9203d47cdbb1b4106e87ba91e4571cea54c55543 100644 (file)
@@ -310,7 +310,7 @@ EXPORT_SYMBOL_GPL(intel_msic_irq_read);
 static int intel_msic_init_devices(struct intel_msic *msic)
 {
        struct platform_device *pdev = msic->pdev;
-       struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
+       struct intel_msic_platform_data *pdata = dev_get_platdata(&pdev->dev);
        int ret, i;
 
        if (pdata->gpio) {
@@ -372,7 +372,7 @@ static void intel_msic_remove_devices(struct intel_msic *msic)
 
 static int intel_msic_probe(struct platform_device *pdev)
 {
-       struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
+       struct intel_msic_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct intel_msic *msic;
        struct resource *res;
        u8 id0, id1;
index 686a4565acb6a6c3b5b3620cb96720014cb6e089..d3e23278d299021f34bab4aacbb361d117f5a40b 100644 (file)
@@ -258,7 +258,7 @@ EXPORT_SYMBOL_GPL(kempld_write32);
  */
 void kempld_get_mutex(struct kempld_device_data *pld)
 {
-       struct kempld_platform_data *pdata = pld->dev->platform_data;
+       struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 
        mutex_lock(&pld->lock);
        pdata->get_hardware_mutex(pld);
@@ -271,7 +271,7 @@ EXPORT_SYMBOL_GPL(kempld_get_mutex);
  */
 void kempld_release_mutex(struct kempld_device_data *pld)
 {
-       struct kempld_platform_data *pdata = pld->dev->platform_data;
+       struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 
        pdata->release_hardware_mutex(pld);
        mutex_unlock(&pld->lock);
@@ -288,7 +288,7 @@ EXPORT_SYMBOL_GPL(kempld_release_mutex);
  */
 static int kempld_get_info(struct kempld_device_data *pld)
 {
-       struct kempld_platform_data *pdata = pld->dev->platform_data;
+       struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 
        return pdata->get_info(pld);
 }
@@ -302,7 +302,7 @@ static int kempld_get_info(struct kempld_device_data *pld)
  */
 static int kempld_register_cells(struct kempld_device_data *pld)
 {
-       struct kempld_platform_data *pdata = pld->dev->platform_data;
+       struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 
        return pdata->register_cells(pld);
 }
@@ -357,7 +357,7 @@ static int kempld_detect_device(struct kempld_device_data *pld)
 
 static int kempld_probe(struct platform_device *pdev)
 {
-       struct kempld_platform_data *pdata = pdev->dev.platform_data;
+       struct kempld_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct device *dev = &pdev->dev;
        struct kempld_device_data *pld;
        struct resource *ioport;
@@ -394,7 +394,7 @@ static int kempld_probe(struct platform_device *pdev)
 static int kempld_remove(struct platform_device *pdev)
 {
        struct kempld_device_data *pld = platform_get_drvdata(pdev);
-       struct kempld_platform_data *pdata = pld->dev->platform_data;
+       struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 
        mfd_remove_devices(&pdev->dev);
        pdata->release_hardware_mutex(pld);
@@ -412,6 +412,15 @@ static struct platform_driver kempld_driver = {
 };
 
 static struct dmi_system_id __initdata kempld_dmi_table[] = {
+       {
+               .ident = "BHL6",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+                       DMI_MATCH(DMI_BOARD_NAME, "COMe-bHL6"),
+               },
+               .driver_data = (void *)&kempld_platform_data_generic,
+               .callback = kempld_create_platform_device,
+       },
        {
                .ident = "CCR2",
                .matches = {
@@ -596,6 +605,15 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
                .driver_data = (void *)&kempld_platform_data_generic,
                .callback = kempld_create_platform_device,
        },
+       {
+               .ident = "UTH6",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+                       DMI_MATCH(DMI_BOARD_NAME, "COMe-cTH6"),
+               },
+               .driver_data = (void *)&kempld_platform_data_generic,
+               .callback = kempld_create_platform_device,
+       },
        {}
 };
 MODULE_DEVICE_TABLE(dmi, kempld_dmi_table);
index 4b7e6dac1de80ea22b556902d1f7896dbd7a6225..8c29f7b27324f4980e1b73f98b7186c10107120a 100644 (file)
@@ -384,7 +384,7 @@ static struct attribute_group lm3533_attribute_group = {
 
 static int lm3533_device_als_init(struct lm3533 *lm3533)
 {
-       struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+       struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
        int ret;
 
        if (!pdata->als)
@@ -407,7 +407,7 @@ static int lm3533_device_als_init(struct lm3533 *lm3533)
 
 static int lm3533_device_bl_init(struct lm3533 *lm3533)
 {
-       struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+       struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
        int i;
        int ret;
 
@@ -436,7 +436,7 @@ static int lm3533_device_bl_init(struct lm3533 *lm3533)
 
 static int lm3533_device_led_init(struct lm3533 *lm3533)
 {
-       struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+       struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
        int i;
        int ret;
 
@@ -481,7 +481,7 @@ static int lm3533_device_setup(struct lm3533 *lm3533,
 
 static int lm3533_device_init(struct lm3533 *lm3533)
 {
-       struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
+       struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
        int ret;
 
        dev_dbg(lm3533->dev, "%s\n", __func__);
index c3d3c9b4d3addedc53bc5b7450cd45a2e4707a72..0f1221911018b6d4fd4e558ff0df4996a4b70a10 100644 (file)
@@ -173,7 +173,7 @@ static const struct regmap_config lp8788_regmap_config = {
 static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
 {
        struct lp8788 *lp;
-       struct lp8788_platform_data *pdata = cl->dev.platform_data;
+       struct lp8788_platform_data *pdata = dev_get_platdata(&cl->dev);
        int ret;
 
        lp = devm_kzalloc(&cl->dev, sizeof(struct lp8788), GFP_KERNEL);
index 24033324c17a08437d3e62e3b1fa705c53f5de53..9483bc8472a51acbbc45a3f08b6072104a81e027 100644 (file)
@@ -213,7 +213,7 @@ enum lpc_chipsets {
        LPC_COLETO,     /* Coleto Creek */
 };
 
-struct lpc_ich_info lpc_chipset_info[] = {
+static struct lpc_ich_info lpc_chipset_info[] = {
        [LPC_ICH] = {
                .name = "ICH",
                .iTCO_version = 1,
index f27a21831583b2e94e06424384deee76f916e03a..522be67b2e682d743c36534005fb09737cfcf590 100644 (file)
@@ -77,7 +77,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
                              const struct i2c_device_id *id)
 {
        struct max77686_dev *max77686 = NULL;
-       struct max77686_platform_data *pdata = i2c->dev.platform_data;
+       struct max77686_platform_data *pdata = dev_get_platdata(&i2c->dev);
        unsigned int data;
        int ret = 0;
 
index 9e60fed5ff82a81dbf774c7d8af7547f12861516..c04723efc70709d4dd81db288be1fa11fc6deccb 100644 (file)
@@ -110,7 +110,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
                              const struct i2c_device_id *id)
 {
        struct max77693_dev *max77693;
-       struct max77693_platform_data *pdata = i2c->dev.platform_data;
+       struct max77693_platform_data *pdata = dev_get_platdata(&i2c->dev);
        u8 reg_data;
        int ret = 0;
 
index 8042b3205eaaf450b3a46b2e657bd5445350c8b1..de7fb80a60528e8f3bcbc2c45e934dcfa5a65181 100644 (file)
@@ -151,7 +151,7 @@ static int max8925_dt_init(struct device_node *np, struct device *dev,
 static int max8925_probe(struct i2c_client *client,
                                   const struct i2c_device_id *id)
 {
-       struct max8925_platform_data *pdata = client->dev.platform_data;
+       struct max8925_platform_data *pdata = dev_get_platdata(&client->dev);
        static struct max8925_chip *chip;
        struct device_node *node = client->dev.of_node;
 
index 14714058f2d2a673e5b678d950e6184454a189bf..cee098c0dae36ef4ef9baf9d3fb07ec11e24913f 100644 (file)
@@ -51,7 +51,7 @@ static struct mfd_cell max8997_devs[] = {
 
 #ifdef CONFIG_OF
 static struct of_device_id max8997_pmic_dt_match[] = {
-       { .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
+       { .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 },
        {},
 };
 #endif
@@ -188,10 +188,11 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct max8997_dev *max8997;
-       struct max8997_platform_data *pdata = i2c->dev.platform_data;
+       struct max8997_platform_data *pdata = dev_get_platdata(&i2c->dev);
        int ret = 0;
 
-       max8997 = kzalloc(sizeof(struct max8997_dev), GFP_KERNEL);
+       max8997 = devm_kzalloc(&i2c->dev, sizeof(struct max8997_dev),
+                               GFP_KERNEL);
        if (max8997 == NULL)
                return -ENOMEM;
 
@@ -203,14 +204,12 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 
        if (max8997->dev->of_node) {
                pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
-               if (IS_ERR(pdata)) {
-                       ret = PTR_ERR(pdata);
-                       goto err;
-               }
+               if (IS_ERR(pdata))
+                       return PTR_ERR(pdata);
        }
 
        if (!pdata)
-               goto err;
+               return ret;
 
        max8997->pdata = pdata;
        max8997->ono = pdata->ono;
@@ -250,8 +249,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
        i2c_unregister_device(max8997->muic);
        i2c_unregister_device(max8997->haptic);
        i2c_unregister_device(max8997->rtc);
-err:
-       kfree(max8997);
        return ret;
 }
 
@@ -263,7 +260,6 @@ static int max8997_i2c_remove(struct i2c_client *i2c)
        i2c_unregister_device(max8997->muic);
        i2c_unregister_device(max8997->haptic);
        i2c_unregister_device(max8997->rtc);
-       kfree(max8997);
 
        return 0;
 }
index 21af51a499f4af42f657a25a4f134437b4892b4e..fe6332dcabee891a27daed80e3ed2525e3b1caa8 100644 (file)
@@ -184,11 +184,12 @@ static inline int max8998_i2c_get_driver_data(struct i2c_client *i2c,
 static int max8998_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
-       struct max8998_platform_data *pdata = i2c->dev.platform_data;
+       struct max8998_platform_data *pdata = dev_get_platdata(&i2c->dev);
        struct max8998_dev *max8998;
        int ret = 0;
 
-       max8998 = kzalloc(sizeof(struct max8998_dev), GFP_KERNEL);
+       max8998 = devm_kzalloc(&i2c->dev, sizeof(struct max8998_dev),
+                               GFP_KERNEL);
        if (max8998 == NULL)
                return -ENOMEM;
 
@@ -246,7 +247,6 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
        mfd_remove_devices(max8998->dev);
        max8998_irq_exit(max8998);
        i2c_unregister_device(max8998->rtc);
-       kfree(max8998);
        return ret;
 }
 
@@ -257,7 +257,6 @@ static int max8998_i2c_remove(struct i2c_client *i2c)
        mfd_remove_devices(max8998->dev);
        max8998_irq_exit(max8998);
        i2c_unregister_device(max8998->rtc);
-       kfree(max8998);
 
        return 0;
 }
index 13198d937e3657ae63717c30ffe602519a92f2c5..41c31b3ac94059e4dacf21565d3d411cd37da371 100644 (file)
@@ -156,7 +156,7 @@ static struct mcp_ops mcp_sa11x0 = {
 
 static int mcp_sa11x0_probe(struct platform_device *dev)
 {
-       struct mcp_plat_data *data = dev->dev.platform_data;
+       struct mcp_plat_data *data = dev_get_platdata(&dev->dev);
        struct resource *mem0, *mem1;
        struct mcp_sa11x0 *m;
        struct mcp *mcp;
index 998ce8cb3065a5a68dc2c09289e13e68826c341b..ad25bfa3fb02cf76ee6c1afcbe3cd8fcecbd49e5 100644 (file)
@@ -442,7 +442,7 @@ void menelaus_unregister_mmc_callback(void)
        menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
 
        the_menelaus->mmc_callback = NULL;
-       the_menelaus->mmc_callback_data = 0;
+       the_menelaus->mmc_callback_data = NULL;
 }
 EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
 
@@ -466,7 +466,7 @@ static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
        struct i2c_client *c = the_menelaus->client;
 
        mutex_lock(&the_menelaus->lock);
-       if (vtg == 0)
+       if (!vtg)
                goto set_voltage;
 
        ret = menelaus_read_reg(vtg->vtg_reg);
@@ -1189,7 +1189,7 @@ static int menelaus_probe(struct i2c_client *client,
        int                     rev = 0, val;
        int                     err = 0;
        struct menelaus_platform_data *menelaus_pdata =
-                                       client->dev.platform_data;
+                                       dev_get_platdata(&client->dev);
 
        if (the_menelaus) {
                dev_dbg(&client->dev, "only one %s for now\n",
@@ -1197,7 +1197,7 @@ static int menelaus_probe(struct i2c_client *client,
                return -ENODEV;
        }
 
-       menelaus = kzalloc(sizeof *menelaus, GFP_KERNEL);
+       menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL);
        if (!menelaus)
                return -ENOMEM;
 
@@ -1210,8 +1210,7 @@ static int menelaus_probe(struct i2c_client *client,
        rev = menelaus_read_reg(MENELAUS_REV);
        if (rev < 0) {
                pr_err(DRIVER_NAME ": device not found");
-               err = -ENODEV;
-               goto fail1;
+               return -ENODEV;
        }
 
        /* Ack and disable all Menelaus interrupts */
@@ -1231,7 +1230,7 @@ static int menelaus_probe(struct i2c_client *client,
                if (err) {
                        dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
                                        client->irq, err);
-                       goto fail1;
+                       return err;
                }
        }
 
@@ -1242,7 +1241,7 @@ static int menelaus_probe(struct i2c_client *client,
 
        val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
        if (val < 0)
-               goto fail2;
+               goto fail;
        if (val & (1 << 7))
                menelaus->vcore_hw_mode = 1;
        else
@@ -1251,17 +1250,15 @@ static int menelaus_probe(struct i2c_client *client,
        if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
                err = menelaus_pdata->late_init(&client->dev);
                if (err < 0)
-                       goto fail2;
+                       goto fail;
        }
 
        menelaus_rtc_init(menelaus);
 
        return 0;
-fail2:
+fail:
        free_irq(client->irq, menelaus);
        flush_work(&menelaus->work);
-fail1:
-       kfree(menelaus);
        return err;
 }
 
@@ -1271,7 +1268,6 @@ static int __exit menelaus_remove(struct i2c_client *client)
 
        free_irq(client->irq, menelaus);
        flush_work(&menelaus->work);
-       kfree(menelaus);
        the_menelaus = NULL;
        return 0;
 }
index 7604f4e5df40a10e03693407da38cb82ea3de14b..f421586f29fb09b02644ee8b05aa6777fb353835 100644 (file)
@@ -96,6 +96,8 @@ static int mfd_add_device(struct device *parent, int id,
 
        pdev->dev.parent = parent;
        pdev->dev.type = &mfd_dev_type;
+       pdev->dev.dma_mask = parent->dma_mask;
+       pdev->dev.dma_parms = parent->dma_parms;
 
        if (parent->of_node && cell->of_compatible) {
                for_each_child_of_node(parent->of_node, np) {
index 759fae3ca7fb0dba592ab808d036f889bf96f922..29ee54d68512e3ce38dad4b5d6897f192b8295f8 100644 (file)
@@ -114,7 +114,7 @@ struct usbhs_hcd_omap {
 };
 /*-------------------------------------------------------------------------*/
 
-const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
+static const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
 static u64 usbhs_dmamask = DMA_BIT_MASK(32);
 
 /*-------------------------------------------------------------------------*/
@@ -232,7 +232,7 @@ static struct platform_device *omap_usbhs_alloc_child(const char *name,
 static int omap_usbhs_alloc_children(struct platform_device *pdev)
 {
        struct device                           *dev = &pdev->dev;
-       struct usbhs_omap_platform_data         *pdata = dev->platform_data;
+       struct usbhs_omap_platform_data         *pdata = dev_get_platdata(dev);
        struct platform_device                  *ehci;
        struct platform_device                  *ohci;
        struct resource                         *res;
@@ -571,7 +571,7 @@ static struct of_device_id usbhs_child_match_table[] = {
 static int usbhs_omap_probe(struct platform_device *pdev)
 {
        struct device                   *dev =  &pdev->dev;
-       struct usbhs_omap_platform_data *pdata = dev->platform_data;
+       struct usbhs_omap_platform_data *pdata = dev_get_platdata(dev);
        struct usbhs_hcd_omap           *omap;
        struct resource                 *res;
        int                             ret = 0;
index e4d1c706df8b9d1cf6a5f9f2f835cc652097789b..135afabe4ae2ae850a6897ddad06dc1969dba301 100644 (file)
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
 
+#define PALMAS_EXT_REQ (PALMAS_EXT_CONTROL_ENABLE1 |   \
+                       PALMAS_EXT_CONTROL_ENABLE2 |    \
+                       PALMAS_EXT_CONTROL_NSLEEP)
+
+struct palmas_sleep_requestor_info {
+       int id;
+       int reg_offset;
+       int bit_pos;
+};
+
+#define EXTERNAL_REQUESTOR(_id, _offset, _pos)         \
+       [PALMAS_EXTERNAL_REQSTR_ID_##_id] = {           \
+               .id = PALMAS_EXTERNAL_REQSTR_ID_##_id,  \
+               .reg_offset = _offset,                  \
+               .bit_pos = _pos,                        \
+       }
+
+static struct palmas_sleep_requestor_info sleep_req_info[] = {
+       EXTERNAL_REQUESTOR(REGEN1, 0, 0),
+       EXTERNAL_REQUESTOR(REGEN2, 0, 1),
+       EXTERNAL_REQUESTOR(SYSEN1, 0, 2),
+       EXTERNAL_REQUESTOR(SYSEN2, 0, 3),
+       EXTERNAL_REQUESTOR(CLK32KG, 0, 4),
+       EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5),
+       EXTERNAL_REQUESTOR(REGEN3, 0, 6),
+       EXTERNAL_REQUESTOR(SMPS12, 1, 0),
+       EXTERNAL_REQUESTOR(SMPS3, 1, 1),
+       EXTERNAL_REQUESTOR(SMPS45, 1, 2),
+       EXTERNAL_REQUESTOR(SMPS6, 1, 3),
+       EXTERNAL_REQUESTOR(SMPS7, 1, 4),
+       EXTERNAL_REQUESTOR(SMPS8, 1, 5),
+       EXTERNAL_REQUESTOR(SMPS9, 1, 6),
+       EXTERNAL_REQUESTOR(SMPS10, 1, 7),
+       EXTERNAL_REQUESTOR(LDO1, 2, 0),
+       EXTERNAL_REQUESTOR(LDO2, 2, 1),
+       EXTERNAL_REQUESTOR(LDO3, 2, 2),
+       EXTERNAL_REQUESTOR(LDO4, 2, 3),
+       EXTERNAL_REQUESTOR(LDO5, 2, 4),
+       EXTERNAL_REQUESTOR(LDO6, 2, 5),
+       EXTERNAL_REQUESTOR(LDO7, 2, 6),
+       EXTERNAL_REQUESTOR(LDO8, 2, 7),
+       EXTERNAL_REQUESTOR(LDO9, 3, 0),
+       EXTERNAL_REQUESTOR(LDOLN, 3, 1),
+       EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
+};
+
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
        {
                .reg_bits = 8,
@@ -186,6 +232,57 @@ static struct regmap_irq_chip palmas_irq_chip = {
                        PALMAS_INT1_MASK),
 };
 
+int palmas_ext_control_req_config(struct palmas *palmas,
+       enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
+{
+       int preq_mask_bit = 0;
+       int reg_add = 0;
+       int bit_pos;
+       int ret;
+
+       if (!(ext_ctrl & PALMAS_EXT_REQ))
+               return 0;
+
+       if (id >= PALMAS_EXTERNAL_REQSTR_ID_MAX)
+               return 0;
+
+       if (ext_ctrl & PALMAS_EXT_CONTROL_NSLEEP) {
+               reg_add = PALMAS_NSLEEP_RES_ASSIGN;
+               preq_mask_bit = 0;
+       } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE1) {
+               reg_add = PALMAS_ENABLE1_RES_ASSIGN;
+               preq_mask_bit = 1;
+       } else if (ext_ctrl & PALMAS_EXT_CONTROL_ENABLE2) {
+               reg_add = PALMAS_ENABLE2_RES_ASSIGN;
+               preq_mask_bit = 2;
+       }
+
+       bit_pos = sleep_req_info[id].bit_pos;
+       reg_add += sleep_req_info[id].reg_offset;
+       if (enable)
+               ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
+                               reg_add, BIT(bit_pos), BIT(bit_pos));
+       else
+               ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
+                               reg_add, BIT(bit_pos), 0);
+       if (ret < 0) {
+               dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n",
+                       reg_add, ret);
+               return ret;
+       }
+
+       /* Unmask the PREQ */
+       ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
+                       PALMAS_POWER_CTRL, BIT(preq_mask_bit), 0);
+       if (ret < 0) {
+               dev_err(palmas->dev, "POWER_CTRL register update failed %d\n",
+                       ret);
+               return ret;
+       }
+       return ret;
+}
+EXPORT_SYMBOL_GPL(palmas_ext_control_req_config);
+
 static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
                struct palmas_platform_data *pdata)
 {
@@ -229,6 +326,32 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
                                        PALMAS_POWER_CTRL_ENABLE2_MASK;
        if (i2c->irq)
                palmas_set_pdata_irq_flag(i2c, pdata);
+
+       pdata->pm_off = of_property_read_bool(node,
+                       "ti,system-power-controller");
+}
+
+static struct palmas *palmas_dev;
+static void palmas_power_off(void)
+{
+       unsigned int addr;
+       int ret, slave;
+
+       if (!palmas_dev)
+               return;
+
+       slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE);
+       addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_DEV_CTRL);
+
+       ret = regmap_update_bits(
+                       palmas_dev->regmap[slave],
+                       addr,
+                       PALMAS_DEV_CTRL_DEV_ON,
+                       0);
+
+       if (ret)
+               pr_err("%s: Unable to write to DEV_CTRL_DEV_ON: %d\n",
+                               __func__, ret);
 }
 
 static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST;
@@ -423,10 +546,13 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
         */
        if (node) {
                ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
-               if (ret < 0)
+               if (ret < 0) {
                        goto err_irq;
-               else
+               } else if (pdata->pm_off && !pm_power_off) {
+                       palmas_dev = palmas;
+                       pm_power_off = palmas_power_off;
                        return ret;
+               }
        }
 
        return ret;
index 18b53cb72feae4984b44b6cea94c2f6d68fc3e40..b8941a556d7195e884e1f85d3e7017e89275a3f5 100644 (file)
@@ -203,7 +203,7 @@ static int pcf50633_adc_probe(struct platform_device *pdev)
 {
        struct pcf50633_adc *adc;
 
-       adc = kzalloc(sizeof(*adc), GFP_KERNEL);
+       adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
        if (!adc)
                return -ENOMEM;
 
@@ -236,7 +236,6 @@ static int pcf50633_adc_remove(struct platform_device *pdev)
                kfree(adc->queue[i]);
 
        mutex_unlock(&adc->queue_mutex);
-       kfree(adc);
 
        return 0;
 }
index d11567307fbed6c930f955abf198de1157dfb237..6841d6805fd64a6aaab032ce121d4e3c63b36443 100644 (file)
@@ -195,7 +195,7 @@ static int pcf50633_probe(struct i2c_client *client,
                                const struct i2c_device_id *ids)
 {
        struct pcf50633 *pcf;
-       struct pcf50633_platform_data *pdata = client->dev.platform_data;
+       struct pcf50633_platform_data *pdata = dev_get_platdata(&client->dev);
        int i, ret;
        int version, variant;
 
index ecc137ffa8c3c6369592a5cea5ecd987f9deeed4..a6841f77aa5e709d472b120336e25e5572646cf8 100644 (file)
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/err.h>
@@ -106,7 +107,7 @@ static int pm8921_add_subdevices(const struct pm8921_platform_data
 
 static int pm8921_probe(struct platform_device *pdev)
 {
-       const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
+       const struct pm8921_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct pm8921 *pmic;
        int rc;
        u8 val;
@@ -117,7 +118,7 @@ static int pm8921_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       pmic = kzalloc(sizeof(struct pm8921), GFP_KERNEL);
+       pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL);
        if (!pmic) {
                pr_err("Cannot alloc pm8921 struct\n");
                return -ENOMEM;
@@ -127,7 +128,7 @@ static int pm8921_probe(struct platform_device *pdev)
        rc = ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
        if (rc) {
                pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
-               goto err_read_rev;
+               return rc;
        }
        pr_info("PMIC revision 1: %02X\n", val);
        rev = val;
@@ -137,7 +138,7 @@ static int pm8921_probe(struct platform_device *pdev)
        if (rc) {
                pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
                        REG_HWREV_2, rc);
-               goto err_read_rev;
+               return rc;
        }
        pr_info("PMIC revision 2: %02X\n", val);
        rev |= val << BITS_PER_BYTE;
@@ -159,9 +160,6 @@ static int pm8921_probe(struct platform_device *pdev)
 
 err:
        mfd_remove_devices(pmic->dev);
-       platform_set_drvdata(pdev, NULL);
-err_read_rev:
-       kfree(pmic);
        return rc;
 }
 
@@ -179,8 +177,6 @@ static int pm8921_remove(struct platform_device *pdev)
                pm8xxx_irq_exit(pmic->irq_chip);
                pmic->irq_chip = NULL;
        }
-       platform_set_drvdata(pdev, NULL);
-       kfree(pmic);
 
        return 0;
 }
index 14bdaccefbeca4da3099ab804e807da6f190843f..346330176afcd81ba9f6a294420db761e60ab908 100644 (file)
@@ -250,7 +250,7 @@ static int rc5t583_i2c_probe(struct i2c_client *i2c,
                              const struct i2c_device_id *id)
 {
        struct rc5t583 *rc5t583;
-       struct rc5t583_platform_data *pdata = i2c->dev.platform_data;
+       struct rc5t583_platform_data *pdata = dev_get_platdata(&i2c->dev);
        int ret;
        bool irq_init_success = false;
 
index c436bf27e78d232340825ad12bf9d493d9ae26a2..52801351864d684e094ec59b60ec797cf4ffcc27 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek PCI-Express card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,7 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ *   Roger Tseng <rogerable@realtek.com>
  */
 
 #include <linux/module.h>
@@ -47,19 +47,77 @@ static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr)
                return 0;
 }
 
+static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+       u32 reg1;
+       u8 reg3;
+
+       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);
+
+       if (!rtsx_vendor_setting_valid(reg1))
+               return;
+
+       pcr->aspm_en = rtsx_reg_to_aspm(reg1);
+       pcr->sd30_drive_sel_1v8 =
+               map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg1));
+       pcr->card_drive_sel &= 0x3F;
+       pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
+
+       rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, &reg3);
+       dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
+       pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
+}
+
+static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+       u32 reg;
+
+       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);
+
+       if (!rtsx_vendor_setting_valid(reg))
+               return;
+
+       pcr->aspm_en = rtsx_reg_to_aspm(reg);
+       pcr->sd30_drive_sel_1v8 =
+               map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
+       pcr->sd30_drive_sel_3v3 =
+               map_sd_drive(rtl8411b_reg_to_sd30_drive_sel_3v3(reg));
+}
+
+static void rtl8411_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+       rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
+}
+
 static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
 {
-       return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+       rtsx_pci_init_cmd(pcr);
+
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+                       0xFF, pcr->sd30_drive_sel_3v3);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
                        CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+
+       return rtsx_pci_send_cmd(pcr, 100);
 }
 
 static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr)
 {
-       if (rtl8411b_is_qfn48(pcr))
-               rtsx_pci_write_register(pcr, CARD_PULL_CTL3, 0xFF, 0xF5);
+       rtsx_pci_init_cmd(pcr);
 
-       return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+       if (rtl8411b_is_qfn48(pcr))
+               rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+                               CARD_PULL_CTL3, 0xFF, 0xF5);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+                       0xFF, pcr->sd30_drive_sel_3v3);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
                        CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, FUNC_FORCE_CTL,
+                       0x06, 0x00);
+
+       return rtsx_pci_send_cmd(pcr, 100);
 }
 
 static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
@@ -141,13 +199,13 @@ static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
        mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
        if (voltage == OUTPUT_3V3) {
                err = rtsx_pci_write_register(pcr,
-                               SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+                               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;
        } else if (voltage == OUTPUT_1V8) {
                err = rtsx_pci_write_register(pcr,
-                               SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+                               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;
@@ -222,6 +280,7 @@ static int rtl8411_conv_clk_and_div_n(int input, int dir)
 }
 
 static const struct pcr_ops rtl8411_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,
@@ -233,9 +292,11 @@ static const struct pcr_ops rtl8411_pcr_ops = {
        .switch_output_voltage = rtl8411_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,
        .optimize_phy = NULL,
        .turn_on_led = rtl8411_turn_on_led,
@@ -247,6 +308,7 @@ static const struct pcr_ops rtl8411b_pcr_ops = {
        .switch_output_voltage = rtl8411_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,
 };
 
 /* SD Pull Control Enable:
@@ -385,6 +447,14 @@ void rtl8411_init_params(struct rtsx_pcr *pcr)
        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;
+       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);
        pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl;
        pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl;
@@ -398,6 +468,14 @@ void rtl8411b_init_params(struct rtsx_pcr *pcr)
        pcr->num_slots = 2;
        pcr->ops = &rtl8411b_pcr_ops;
 
+       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)) {
index ec78d9fb08791a9975a825411b6d7a8049f5d801..cb04174a8924b0279fccb697706f9227b6869e15 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek PCI-Express card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #include <linux/module.h>
@@ -34,19 +33,34 @@ static u8 rts5209_get_ic_version(struct rtsx_pcr *pcr)
        return val & 0x0F;
 }
 
-static void rts5209_init_vendor_cfg(struct rtsx_pcr *pcr)
+static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr)
 {
-       u32 val;
+       u32 reg;
 
-       rtsx_pci_read_config_dword(pcr, 0x724, &val);
-       dev_dbg(&(pcr->pci->dev), "Cfg 0x724: 0x%x\n", val);
+       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);
 
-       if (!(val & 0x80)) {
-               if (val & 0x08)
-                       pcr->ms_pmos = false;
-               else
-                       pcr->ms_pmos = true;
+       if (rts5209_vendor_setting1_valid(reg)) {
+               if (rts5209_reg_check_ms_pmos(reg))
+                       pcr->flags |= PCR_MS_PMOS;
+               pcr->aspm_en = rts5209_reg_to_aspm(reg);
        }
+
+       rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
+       dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+
+       if (rts5209_vendor_setting2_valid(reg)) {
+               pcr->sd30_drive_sel_1v8 =
+                       rts5209_reg_to_sd30_drive_sel_1v8(reg);
+               pcr->sd30_drive_sel_3v3 =
+                       rts5209_reg_to_sd30_drive_sel_3v3(reg);
+               pcr->card_drive_sel = rts5209_reg_to_card_drive_sel(reg);
+       }
+}
+
+static void rts5209_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+       rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
 }
 
 static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
@@ -55,8 +69,15 @@ static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
 
        /* Turn off LED */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03);
+       /* Reset ASPM state to default value */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
+       /* Force CLKREQ# PIN to drive 0 to request clock */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
        /* Configure GPIO as output */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03);
+       /* Configure driving */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+                       0xFF, pcr->sd30_drive_sel_3v3);
 
        return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -95,7 +116,7 @@ static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card)
        partial_pwr_on = SD_PARTIAL_POWER_ON;
        pwr_on = SD_POWER_ON;
 
-       if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+       if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) {
                pwr_mask = MS_POWER_MASK;
                partial_pwr_on = MS_PARTIAL_POWER_ON;
                pwr_on = MS_POWER_ON;
@@ -131,7 +152,7 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
        pwr_mask = SD_POWER_MASK;
        pwr_off = SD_POWER_OFF;
 
-       if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+       if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) {
                pwr_mask = MS_POWER_MASK;
                pwr_off = MS_POWER_OFF;
        }
@@ -140,7 +161,7 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
                        pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
-                       LDO3318_PWR_MASK, 0X06);
+                       LDO3318_PWR_MASK, 0x06);
        return rtsx_pci_send_cmd(pcr, 100);
 }
 
@@ -150,7 +171,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 
        if (voltage == OUTPUT_3V3) {
                err = rtsx_pci_write_register(pcr,
-                               SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+                               SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
                if (err < 0)
                        return err;
                err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
@@ -158,7 +179,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
                        return err;
        } else if (voltage == OUTPUT_1V8) {
                err = rtsx_pci_write_register(pcr,
-                               SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+                               SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
                if (err < 0)
                        return err;
                err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
@@ -172,6 +193,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 }
 
 static const struct pcr_ops rts5209_pcr_ops = {
+       .fetch_vendor_settings = rts5209_fetch_vendor_settings,
        .extra_init_hw = rts5209_extra_init_hw,
        .optimize_phy = rts5209_optimize_phy,
        .turn_on_led = rts5209_turn_on_led,
@@ -183,6 +205,7 @@ static const struct pcr_ops rts5209_pcr_ops = {
        .switch_output_voltage = rts5209_switch_output_voltage,
        .cd_deglitch = NULL,
        .conv_clk_and_div_n = NULL,
+       .force_power_down = rts5209_force_power_down,
 };
 
 /* SD Pull Control Enable:
@@ -242,7 +265,13 @@ void rts5209_init_params(struct rtsx_pcr *pcr)
        pcr->num_slots = 2;
        pcr->ops = &rts5209_pcr_ops;
 
-       rts5209_init_vendor_cfg(pcr);
+       pcr->flags = 0;
+       pcr->card_drive_sel = RTS5209_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(27, 27, 16);
+       pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
 
        pcr->ic_version = rts5209_get_ic_version(pcr);
        pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl;
index 164b7faa70c9daf3f3cb69d1cf810d071b6ce8ee..9c8eec80ceed53bef339da4c9778ea224c1b9c99 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek PCI-Express card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- *
  *   Roger Tseng <rogerable@realtek.com>
- *   No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
  */
 
 #include <linux/module.h>
 
 #include "rtsx_pcr.h"
 
+static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
+{
+       u8 driving_3v3[4][3] = {
+               {0x13, 0x13, 0x13},
+               {0x96, 0x96, 0x96},
+               {0x7F, 0x7F, 0x7F},
+               {0x96, 0x96, 0x96},
+       };
+       u8 driving_1v8[4][3] = {
+               {0x99, 0x99, 0x99},
+               {0xAA, 0xAA, 0xAA},
+               {0xFE, 0xFE, 0xFE},
+               {0xB3, 0xB3, 0xB3},
+       };
+       u8 (*driving)[3], drive_sel;
+
+       if (voltage == OUTPUT_3V3) {
+               driving = driving_3v3;
+               drive_sel = pcr->sd30_drive_sel_3v3;
+       } else {
+               driving = driving_1v8;
+               drive_sel = pcr->sd30_drive_sel_1v8;
+       }
+
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
+                       0xFF, driving[drive_sel][0]);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
+                       0xFF, driving[drive_sel][1]);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
+                       0xFF, driving[drive_sel][2]);
+}
+
+static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+       u32 reg;
+
+       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);
+
+       if (!rtsx_vendor_setting_valid(reg))
+               return;
+
+       pcr->aspm_en = rtsx_reg_to_aspm(reg);
+       pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
+       pcr->card_drive_sel &= 0x3F;
+       pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
+
+       rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
+       dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+       pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
+       if (rtsx_reg_check_reverse_socket(reg))
+               pcr->flags |= PCR_REVERSE_SOCKET;
+}
+
+static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+       /* Set relink_time to 0 */
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
+
+       if (pm_state == HOST_ENTER_S3)
+               rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+
+       rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
 static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
 {
        u16 cap;
@@ -37,6 +101,8 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
 
        /* Configure GPIO as output */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+       /* Reset ASPM state to default value */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
        /* Switch LDO3318 source from DV33 to card_3v3 */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
@@ -48,17 +114,16 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3);
        /* Configure OBFF */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03);
-       /* Configure force_clock_req
-        * Maybe We should define 0xFF03 as some name
-        */
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
-       /* Correct driving */
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-                       SD30_CLK_DRIVE_SEL, 0xFF, 0x96);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-                       SD30_CMD_DRIVE_SEL, 0xFF, 0x96);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-                       SD30_DAT_DRIVE_SEL, 0xFF, 0x96);
+       /* Configure driving */
+       rts5227_fill_driving(pcr, OUTPUT_3V3);
+       /* Configure force_clock_req */
+       if (pcr->flags & PCR_REVERSE_SOCKET)
+               rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+                               AUTOLOAD_CFG_BASE + 3, 0xB8, 0xB8);
+       else
+               rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+                               AUTOLOAD_CFG_BASE + 3, 0xB8, 0x88);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
        return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -131,13 +196,11 @@ static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
 static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 {
        int err;
-       u8 drive_sel;
 
        if (voltage == OUTPUT_3V3) {
                err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
                if (err < 0)
                        return err;
-               drive_sel = 0x96;
        } else if (voltage == OUTPUT_1V8) {
                err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
                if (err < 0)
@@ -145,23 +208,18 @@ static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
                err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24);
                if (err < 0)
                        return err;
-               drive_sel = 0xB3;
        } else {
                return -EINVAL;
        }
 
        /* set pad drive */
        rtsx_pci_init_cmd(pcr);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
-                       0xFF, drive_sel);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
-                       0xFF, drive_sel);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
-                       0xFF, drive_sel);
+       rts5227_fill_driving(pcr, voltage);
        return rtsx_pci_send_cmd(pcr, 100);
 }
 
 static const struct pcr_ops rts5227_pcr_ops = {
+       .fetch_vendor_settings = rts5227_fetch_vendor_settings,
        .extra_init_hw = rts5227_extra_init_hw,
        .optimize_phy = rts5227_optimize_phy,
        .turn_on_led = rts5227_turn_on_led,
@@ -173,6 +231,7 @@ static const struct pcr_ops rts5227_pcr_ops = {
        .switch_output_voltage = rts5227_switch_output_voltage,
        .cd_deglitch = NULL,
        .conv_clk_and_div_n = NULL,
+       .force_power_down = rts5227_force_power_down,
 };
 
 /* SD Pull Control Enable:
@@ -227,6 +286,14 @@ void rts5227_init_params(struct rtsx_pcr *pcr)
        pcr->num_slots = 2;
        pcr->ops = &rts5227_pcr_ops;
 
+       pcr->flags = 0;
+       pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
+       pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
+       pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
+       pcr->aspm_en = ASPM_L1_EN;
+       pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
+       pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7);
+
        pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
        pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
        pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;
index 58af4dbe358623d2c45385ee5a5e6f31cb04344e..6353f5df087aa41bb11653b69593ea3eb56abd8b 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek PCI-Express card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #include <linux/module.h>
@@ -34,17 +33,51 @@ static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr)
        return val & 0x0F;
 }
 
+static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+       u32 reg;
+
+       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);
+
+       if (!rtsx_vendor_setting_valid(reg))
+               return;
+
+       pcr->aspm_en = rtsx_reg_to_aspm(reg);
+       pcr->sd30_drive_sel_1v8 =
+               map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
+       pcr->card_drive_sel &= 0x3F;
+       pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
+
+       rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
+       dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+       pcr->sd30_drive_sel_3v3 =
+               map_sd_drive(rtsx_reg_to_sd30_drive_sel_3v3(reg));
+}
+
+static void rts5229_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+       rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
 static int rts5229_extra_init_hw(struct rtsx_pcr *pcr)
 {
        rtsx_pci_init_cmd(pcr);
 
        /* Configure GPIO as output */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+       /* Reset ASPM state to default value */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
+       /* Force CLKREQ# PIN to drive 0 to request clock */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
        /* Switch LDO3318 source from DV33 to card_3v3 */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
        /* LED shine disabled, set initial shine cycle period */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+       /* Configure driving */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+                       0xFF, pcr->sd30_drive_sel_3v3);
 
        return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -110,7 +143,7 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)
                        SD_POWER_MASK | PMOS_STRG_MASK,
                        SD_POWER_OFF | PMOS_STRG_400mA);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
-                       LDO3318_PWR_MASK, 0X00);
+                       LDO3318_PWR_MASK, 0x00);
        return rtsx_pci_send_cmd(pcr, 100);
 }
 
@@ -120,7 +153,7 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 
        if (voltage == OUTPUT_3V3) {
                err = rtsx_pci_write_register(pcr,
-                               SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+                               SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
                if (err < 0)
                        return err;
                err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
@@ -128,7 +161,7 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
                        return err;
        } else if (voltage == OUTPUT_1V8) {
                err = rtsx_pci_write_register(pcr,
-                               SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+                               SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
                if (err < 0)
                        return err;
                err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
@@ -142,6 +175,7 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 }
 
 static const struct pcr_ops rts5229_pcr_ops = {
+       .fetch_vendor_settings = rts5229_fetch_vendor_settings,
        .extra_init_hw = rts5229_extra_init_hw,
        .optimize_phy = rts5229_optimize_phy,
        .turn_on_led = rts5229_turn_on_led,
@@ -153,6 +187,7 @@ static const struct pcr_ops rts5229_pcr_ops = {
        .switch_output_voltage = rts5229_switch_output_voltage,
        .cd_deglitch = NULL,
        .conv_clk_and_div_n = NULL,
+       .force_power_down = rts5229_force_power_down,
 };
 
 /* SD Pull Control Enable:
@@ -221,6 +256,14 @@ void rts5229_init_params(struct rtsx_pcr *pcr)
        pcr->num_slots = 2;
        pcr->ops = &rts5229_pcr_ops;
 
+       pcr->flags = 0;
+       pcr->card_drive_sel = RTSX_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(27, 27, 15);
+       pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 6, 6);
+
        pcr->ic_version = rts5229_get_ic_version(pcr);
        if (pcr->ic_version == IC_VER_C) {
                pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2;
index 15dc848bc0817bd6aafab9fa341e362e375f7944..3b835f593e35294a4666c25872eb911e9726b131 100644 (file)
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 128, West Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #include <linux/module.h>
@@ -34,24 +33,95 @@ static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
        return val & 0x0F;
 }
 
+static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
+{
+       u8 driving_3v3[4][3] = {
+               {0x11, 0x11, 0x11},
+               {0x55, 0x55, 0x5C},
+               {0x99, 0x99, 0x92},
+               {0x99, 0x99, 0x92},
+       };
+       u8 driving_1v8[4][3] = {
+               {0x3C, 0x3C, 0x3C},
+               {0xB3, 0xB3, 0xB3},
+               {0xFE, 0xFE, 0xFE},
+               {0xC4, 0xC4, 0xC4},
+       };
+       u8 (*driving)[3], drive_sel;
+
+       if (voltage == OUTPUT_3V3) {
+               driving = driving_3v3;
+               drive_sel = pcr->sd30_drive_sel_3v3;
+       } else {
+               driving = driving_1v8;
+               drive_sel = pcr->sd30_drive_sel_1v8;
+       }
+
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
+                       0xFF, driving[drive_sel][0]);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
+                       0xFF, driving[drive_sel][1]);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
+                       0xFF, driving[drive_sel][2]);
+}
+
+static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+       u32 reg;
+
+       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);
+
+       if (!rtsx_vendor_setting_valid(reg))
+               return;
+
+       pcr->aspm_en = rtsx_reg_to_aspm(reg);
+       pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
+       pcr->card_drive_sel &= 0x3F;
+       pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
+
+       rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
+       dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+       pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
+       if (rtsx_reg_check_reverse_socket(reg))
+               pcr->flags |= PCR_REVERSE_SOCKET;
+}
+
+static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+{
+       /* Set relink_time to 0 */
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
+
+       if (pm_state == HOST_ENTER_S3)
+               rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+
+       rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
 static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 {
        rtsx_pci_init_cmd(pcr);
 
        /* Configure GPIO as output */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+       /* Reset ASPM state to default value */
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
        /* Switch LDO3318 source from DV33 to card_3v3 */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
        /* LED shine disabled, set initial shine cycle period */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
-       /* Correct driving */
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-                       SD30_CLK_DRIVE_SEL, 0xFF, 0x99);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-                       SD30_CMD_DRIVE_SEL, 0xFF, 0x99);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-                       SD30_DAT_DRIVE_SEL, 0xFF, 0x92);
+       /* Configure driving */
+       rts5249_fill_driving(pcr, OUTPUT_3V3);
+       if (pcr->flags & PCR_REVERSE_SOCKET)
+               rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+                               AUTOLOAD_CFG_BASE + 3, 0xB0, 0xB0);
+       else
+               rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+                               AUTOLOAD_CFG_BASE + 3, 0xB0, 0x80);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
        return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -129,15 +199,11 @@ static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card)
 static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 {
        int err;
-       u8 clk_drive, cmd_drive, dat_drive;
 
        if (voltage == OUTPUT_3V3) {
                err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24);
                if (err < 0)
                        return err;
-               clk_drive = 0x99;
-               cmd_drive = 0x99;
-               dat_drive = 0x92;
        } else if (voltage == OUTPUT_1V8) {
                err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02);
                if (err < 0)
@@ -145,25 +211,18 @@ static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
                err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4C40 | 0x24);
                if (err < 0)
                        return err;
-               clk_drive = 0xb3;
-               cmd_drive = 0xb3;
-               dat_drive = 0xb3;
        } else {
                return -EINVAL;
        }
 
        /* set pad drive */
        rtsx_pci_init_cmd(pcr);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
-                       0xFF, clk_drive);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
-                       0xFF, cmd_drive);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
-                       0xFF, dat_drive);
+       rts5249_fill_driving(pcr, voltage);
        return rtsx_pci_send_cmd(pcr, 100);
 }
 
 static const struct pcr_ops rts5249_pcr_ops = {
+       .fetch_vendor_settings = rts5249_fetch_vendor_settings,
        .extra_init_hw = rts5249_extra_init_hw,
        .optimize_phy = rts5249_optimize_phy,
        .turn_on_led = rts5249_turn_on_led,
@@ -173,6 +232,7 @@ static const struct pcr_ops rts5249_pcr_ops = {
        .card_power_on = rts5249_card_power_on,
        .card_power_off = rts5249_card_power_off,
        .switch_output_voltage = rts5249_switch_output_voltage,
+       .force_power_down = rts5249_force_power_down,
 };
 
 /* SD Pull Control Enable:
@@ -233,6 +293,14 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
        pcr->num_slots = 2;
        pcr->ops = &rts5249_pcr_ops;
 
+       pcr->flags = 0;
+       pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
+       pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_C;
+       pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
+       pcr->aspm_en = ASPM_L1_EN;
+       pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
+       pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
+
        pcr->ic_version = rts5249_get_ic_version(pcr);
        pcr->sd_pull_ctl_enable_tbl = rts5249_sd_pull_ctl_enable_tbl;
        pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl;
index dd186c4103c1e4f6ad9dc690879fa161489a8b2c..e6ae7720f9e15bd546362509bca185c7a64eb86f 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek PCI-Express card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #include <linux/pci.h>
@@ -73,6 +72,9 @@ void rtsx_pci_start_run(struct rtsx_pcr *pcr)
                pcr->state = PDEV_STAT_RUN;
                if (pcr->ops->enable_auto_blink)
                        pcr->ops->enable_auto_blink(pcr);
+
+               if (pcr->aspm_en)
+                       rtsx_pci_write_config_byte(pcr, LCTLR, 0);
        }
 
        mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200));
@@ -717,7 +719,7 @@ int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card)
                [RTSX_MS_CARD] = MS_EXIST
        };
 
-       if (!pcr->ms_pmos) {
+       if (!(pcr->flags & PCR_MS_PMOS)) {
                /* When using single PMOS, accessing card is not permitted
                 * if the existing card is not the designated one.
                 */
@@ -918,9 +920,27 @@ static void rtsx_pci_idle_work(struct work_struct *work)
        if (pcr->ops->turn_off_led)
                pcr->ops->turn_off_led(pcr);
 
+       if (pcr->aspm_en)
+               rtsx_pci_write_config_byte(pcr, LCTLR, pcr->aspm_en);
+
        mutex_unlock(&pcr->pcr_mutex);
 }
 
+static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
+{
+       if (pcr->ops->turn_off_led)
+               pcr->ops->turn_off_led(pcr);
+
+       rtsx_pci_writel(pcr, RTSX_BIER, 0);
+       pcr->bier = 0;
+
+       rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
+       rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, pm_state);
+
+       if (pcr->ops->force_power_down)
+               pcr->ops->force_power_down(pcr, pm_state);
+}
+
 static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
 {
        int err;
@@ -951,13 +971,11 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, HOST_SLEEP_STATE, 0x03, 0x00);
        /* Disable card clock */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, 0x1E, 0);
-       /* Reset ASPM state to default value */
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
        /* Reset delink mode */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x0A, 0);
        /* Card driving select */
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
-                       0x07, DRIVER_TYPE_D);
+       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DRIVE_SEL,
+                       0xFF, pcr->card_drive_sel);
        /* Enable SSC Clock */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1,
                        0xFF, SSC_8X_EN | SSC_SEL_4M);
@@ -982,13 +1000,13 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
         *      0: ELBI interrupt flag[31:22] & [7:0] only can be write clear
         */
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, NFTS_TX_CTRL, 0x02, 0);
-       /* Force CLKREQ# PIN to drive 0 to request clock */
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
 
        err = rtsx_pci_send_cmd(pcr, 100);
        if (err < 0)
                return err;
 
+       rtsx_pci_write_config_byte(pcr, LCTLR, 0);
+
        /* Enable clk_request_n to enable clock power management */
        rtsx_pci_write_config_byte(pcr, 0x81, 1);
        /* Enter L1 when host tx idle */
@@ -1053,6 +1071,18 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
        if (!pcr->slots)
                return -ENOMEM;
 
+       if (pcr->ops->fetch_vendor_settings)
+               pcr->ops->fetch_vendor_settings(pcr);
+
+       dev_dbg(&(pcr->pci->dev), "pcr->aspm_en = 0x%x\n", pcr->aspm_en);
+       dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_1v8 = 0x%x\n",
+                       pcr->sd30_drive_sel_1v8);
+       dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_3v3 = 0x%x\n",
+                       pcr->sd30_drive_sel_3v3);
+       dev_dbg(&(pcr->pci->dev), "pcr->card_drive_sel = 0x%x\n",
+                       pcr->card_drive_sel);
+       dev_dbg(&(pcr->pci->dev), "pcr->flags = 0x%x\n", pcr->flags);
+
        pcr->state = PDEV_STAT_IDLE;
        err = rtsx_pci_init_hw(pcr);
        if (err < 0) {
@@ -1235,7 +1265,6 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
 {
        struct pcr_handle *handle;
        struct rtsx_pcr *pcr;
-       int ret = 0;
 
        dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
 
@@ -1247,14 +1276,7 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
 
        mutex_lock(&pcr->pcr_mutex);
 
-       if (pcr->ops->turn_off_led)
-               pcr->ops->turn_off_led(pcr);
-
-       rtsx_pci_writel(pcr, RTSX_BIER, 0);
-       pcr->bier = 0;
-
-       rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
-       rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02);
+       rtsx_pci_power_off(pcr, HOST_ENTER_S3);
 
        pci_save_state(pcidev);
        pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0);
@@ -1262,7 +1284,7 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
        pci_set_power_state(pcidev, pci_choose_state(pcidev, state));
 
        mutex_unlock(&pcr->pcr_mutex);
-       return ret;
+       return 0;
 }
 
 static int rtsx_pci_resume(struct pci_dev *pcidev)
@@ -1300,10 +1322,25 @@ static int rtsx_pci_resume(struct pci_dev *pcidev)
        return ret;
 }
 
+static void rtsx_pci_shutdown(struct pci_dev *pcidev)
+{
+       struct pcr_handle *handle;
+       struct rtsx_pcr *pcr;
+
+       dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
+
+       handle = pci_get_drvdata(pcidev);
+       pcr = handle->pcr;
+       rtsx_pci_power_off(pcr, HOST_ENTER_S1);
+
+       pci_disable_device(pcidev);
+}
+
 #else /* CONFIG_PM */
 
 #define rtsx_pci_suspend NULL
 #define rtsx_pci_resume NULL
+#define rtsx_pci_shutdown NULL
 
 #endif /* CONFIG_PM */
 
@@ -1314,6 +1351,7 @@ static struct pci_driver rtsx_pci_driver = {
        .remove = rtsx_pci_remove,
        .suspend = rtsx_pci_suspend,
        .resume = rtsx_pci_resume,
+       .shutdown = rtsx_pci_shutdown,
 };
 module_pci_driver(rtsx_pci_driver);
 
index c0cac7e8972f6327571e9558eb3026aab4b6fa8a..947e79b05cebfd211590c93a53cec7f58182f907 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek PCI-Express card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #ifndef __RTSX_PCR_H
@@ -35,4 +34,33 @@ void rts5227_init_params(struct rtsx_pcr *pcr);
 void rts5249_init_params(struct rtsx_pcr *pcr);
 void rtl8411b_init_params(struct rtsx_pcr *pcr);
 
+static inline u8 map_sd_drive(int idx)
+{
+       u8 sd_drive[4] = {
+               0x01,   /* Type D */
+               0x02,   /* Type C */
+               0x05,   /* Type A */
+               0x03    /* Type B */
+       };
+
+       return sd_drive[idx];
+}
+
+#define rtsx_vendor_setting_valid(reg)         (!((reg) & 0x1000000))
+#define rts5209_vendor_setting1_valid(reg)     (!((reg) & 0x80))
+#define rts5209_vendor_setting2_valid(reg)     ((reg) & 0x80)
+
+#define rtsx_reg_to_aspm(reg)                  (((reg) >> 28) & 0x03)
+#define rtsx_reg_to_sd30_drive_sel_1v8(reg)    (((reg) >> 26) & 0x03)
+#define rtsx_reg_to_sd30_drive_sel_3v3(reg)    (((reg) >> 5) & 0x03)
+#define rtsx_reg_to_card_drive_sel(reg)                ((((reg) >> 25) & 0x01) << 6)
+#define rtsx_reg_check_reverse_socket(reg)     ((reg) & 0x4000)
+#define rts5209_reg_to_aspm(reg)               (((reg) >> 5) & 0x03)
+#define rts5209_reg_check_ms_pmos(reg)         (!((reg) & 0x08))
+#define rts5209_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 3) & 0x07)
+#define rts5209_reg_to_sd30_drive_sel_3v3(reg) ((reg) & 0x07)
+#define rts5209_reg_to_card_drive_sel(reg)     ((reg) >> 8)
+#define rtl8411_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x07)
+#define rtl8411b_reg_to_sd30_drive_sel_3v3(reg)        ((reg) & 0x03)
+
 #endif
index 79767681483a65b78804e44263bfbba4ef135d2e..f530e4b73f19abd63fe42ba7f18230dba79c088f 100644 (file)
@@ -61,7 +61,9 @@ static struct mfd_cell s5m8767_devs[] = {
 static struct mfd_cell s2mps11_devs[] = {
        {
                .name = "s2mps11-pmic",
-       },
+       }, {
+               .name = "s2mps11-clk",
+       }
 };
 
 #ifdef CONFIG_OF
@@ -69,6 +71,9 @@ static struct of_device_id sec_dt_match[] = {
        {       .compatible = "samsung,s5m8767-pmic",
                .data = (void *)S5M8767X,
        },
+       {       .compatible = "samsung,s2mps11-pmic",
+               .data = (void *)S2MPS11X,
+       },
        {},
 };
 #endif
@@ -103,6 +108,31 @@ int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask)
 }
 EXPORT_SYMBOL_GPL(sec_reg_update);
 
+static bool s2mps11_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S2MPS11_REG_INT1M:
+       case S2MPS11_REG_INT2M:
+       case S2MPS11_REG_INT3M:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static bool s5m8763_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S5M8763_REG_IRQM1:
+       case S5M8763_REG_IRQM2:
+       case S5M8763_REG_IRQM3:
+       case S5M8763_REG_IRQM4:
+               return false;
+       default:
+               return true;
+       }
+}
+
 static struct regmap_config sec_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
@@ -113,6 +143,8 @@ static struct regmap_config s2mps11_regmap_config = {
        .val_bits = 8,
 
        .max_register = S2MPS11_REG_L38CTRL,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static struct regmap_config s5m8763_regmap_config = {
@@ -120,6 +152,8 @@ static struct regmap_config s5m8763_regmap_config = {
        .val_bits = 8,
 
        .max_register = S5M8763_REG_LBCNFG2,
+       .volatile_reg = s5m8763_volatile,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static struct regmap_config s5m8767_regmap_config = {
@@ -127,6 +161,8 @@ static struct regmap_config s5m8767_regmap_config = {
        .val_bits = 8,
 
        .max_register = S5M8767_REG_LDO28CTRL,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
 };
 
 #ifdef CONFIG_OF
@@ -182,7 +218,7 @@ static inline int sec_i2c_get_driver_data(struct i2c_client *i2c,
 static int sec_pmic_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
-       struct sec_platform_data *pdata = i2c->dev.platform_data;
+       struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev);
        const struct regmap_config *regmap;
        struct sec_pmic_dev *sec_pmic;
        int ret;
index f5bc8e4bd4bf631b3266091a3af6212be07138cf..0e4a76daf18789b37e84163f2a83bb45afb642ea 100644 (file)
@@ -718,7 +718,7 @@ static int si476x_core_probe(struct i2c_client *client,
        atomic_set(&core->is_alive, 0);
        core->power_state = SI476X_POWER_DOWN;
 
-       pdata = client->dev.platform_data;
+       pdata = dev_get_platdata(&client->dev);
        if (pdata) {
                memcpy(&core->power_up_parameters,
                       &pdata->power_up_parameters,
index 9816c232e58331c202f8622e87657c90ccb1f972..33f040c558d090aca5887356bdd1cd2bbb11f461 100644 (file)
@@ -840,7 +840,7 @@ static int sm501_register_uart(struct sm501_devdata *sm, int devices)
        if (!pdev)
                return -ENOMEM;
 
-       uart_data = pdev->dev.platform_data;
+       uart_data = dev_get_platdata(&pdev->dev);
 
        if (devices & SM501_USE_UART0) {
                sm501_setup_uart_data(sm, uart_data++, 0x30000);
@@ -1167,7 +1167,7 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm,
        if (!pdev)
                return -ENOMEM;
 
-       icd = pdev->dev.platform_data;
+       icd = dev_get_platdata(&pdev->dev);
 
        /* We keep the pin_sda and pin_scl fields relative in case the
         * same platform data is passed to >1 SM501.
@@ -1403,7 +1403,7 @@ static int sm501_plat_probe(struct platform_device *dev)
 
        sm->dev = &dev->dev;
        sm->pdev_id = dev->id;
-       sm->platdata = dev->dev.platform_data;
+       sm->platdata = dev_get_platdata(&dev->dev);
 
        ret = platform_get_irq(dev, 0);
        if (ret < 0) {
index d70a343078fd5934ab1fff9732caed67a32b095c..65c6fa671acb27a67496b3b9277aa4919942dc89 100644 (file)
@@ -133,7 +133,7 @@ int sta2x11_mfd_get_regs_data(struct platform_device *dev,
                              void __iomem **regs,
                              spinlock_t **lock)
 {
-       struct pci_dev *pdev = *(struct pci_dev **)(dev->dev.platform_data);
+       struct pci_dev *pdev = *(struct pci_dev **)dev_get_platdata(&dev->dev);
        struct sta2x11_mfd *mfd;
 
        if (!pdev)
@@ -312,7 +312,7 @@ static int sta2x11_mfd_platform_probe(struct platform_device *dev,
        const char *name = sta2x11_mfd_names[index];
        struct regmap_config *regmap_config = sta2x11_mfd_regmap_configs[index];
 
-       pdev = dev->dev.platform_data;
+       pdev = dev_get_platdata(&dev->dev);
        mfd = sta2x11_mfd_find(*pdev);
        if (!mfd)
                return -ENODEV;
index 5d5e6f90424aa981653e0e3a609845d4de5a935f..fff63a41862cf6bbb4acfac38496447a4137ad0a 100644 (file)
@@ -1106,7 +1106,8 @@ static int stmpe_devices_init(struct stmpe *stmpe)
        return ret;
 }
 
-void stmpe_of_probe(struct stmpe_platform_data *pdata, struct device_node *np)
+static void stmpe_of_probe(struct stmpe_platform_data *pdata,
+                          struct device_node *np)
 {
        struct device_node *child;
 
index 962a6e17a01a1f75a3e783a94f4eb0d126273b60..71841f9181bd19f4ae6b832898353bc442999c2e 100644 (file)
@@ -25,7 +25,6 @@
 static struct platform_driver syscon_driver;
 
 struct syscon {
-       void __iomem *base;
        struct regmap *regmap;
 };
 
@@ -129,6 +128,7 @@ static int syscon_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct syscon *syscon;
        struct resource *res;
+       void __iomem *base;
 
        syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
        if (!syscon)
@@ -138,12 +138,12 @@ static int syscon_probe(struct platform_device *pdev)
        if (!res)
                return -ENOENT;
 
-       syscon->base = devm_ioremap(dev, res->start, resource_size(res));
-       if (!syscon->base)
+       base = devm_ioremap(dev, res->start, resource_size(res));
+       if (!base)
                return -ENOMEM;
 
        syscon_regmap_config.max_register = res->end - res->start - 3;
-       syscon->regmap = devm_regmap_init_mmio(dev, syscon->base,
+       syscon->regmap = devm_regmap_init_mmio(dev, base,
                                        &syscon_regmap_config);
        if (IS_ERR(syscon->regmap)) {
                dev_err(dev, "regmap init failed\n");
index a21bff283a98fa7d5637e2f9ebc9ba6e94a602c7..9e04a74859818bd0016dfd6a60bbcd94669a4248 100644 (file)
@@ -281,7 +281,7 @@ static void t7l66xb_detach_irq(struct platform_device *dev)
 static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state)
 {
        struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
-       struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+       struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
 
        if (pdata && pdata->suspend)
                pdata->suspend(dev);
@@ -293,7 +293,7 @@ static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state)
 static int t7l66xb_resume(struct platform_device *dev)
 {
        struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
-       struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+       struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
 
        clk_enable(t7l66xb->clk48m);
        if (pdata && pdata->resume)
@@ -313,7 +313,7 @@ static int t7l66xb_resume(struct platform_device *dev)
 
 static int t7l66xb_probe(struct platform_device *dev)
 {
-       struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+       struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
        struct t7l66xb *t7l66xb;
        struct resource *iomem, *rscr;
        int ret;
@@ -409,7 +409,7 @@ static int t7l66xb_probe(struct platform_device *dev)
 
 static int t7l66xb_remove(struct platform_device *dev)
 {
-       struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+       struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
        struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
        int ret;
 
index 4cb92bb2aea2f27ad2a1cf4177890b7488ae7dc9..70f4909fee13b8d30a632029a9639b41b81cb051 100644 (file)
@@ -325,7 +325,7 @@ static int tc3589x_of_probe(struct device_node *np,
 static int tc3589x_probe(struct i2c_client *i2c,
                                   const struct i2c_device_id *id)
 {
-       struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
+       struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
        struct device_node *np = i2c->dev.of_node;
        struct tc3589x *tc3589x;
        int ret;
index 65c425a517c50ec94836a7edb1e7cdf496e04481..acd0f3a41044a5171cc0cfde9d03ad693fa9f48c 100644 (file)
@@ -48,7 +48,7 @@ static struct resource tc6387xb_mmc_resources[] = {
 static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
 {
        struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
-       struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
+       struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev);
 
        if (pdata && pdata->suspend)
                pdata->suspend(dev);
@@ -60,7 +60,7 @@ static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
 static int tc6387xb_resume(struct platform_device *dev)
 {
        struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
-       struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
+       struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev);
 
        clk_enable(tc6387xb->clk32k);
        if (pdata && pdata->resume)
@@ -140,7 +140,7 @@ static struct mfd_cell tc6387xb_cells[] = {
 
 static int tc6387xb_probe(struct platform_device *dev)
 {
-       struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
+       struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev);
        struct resource *iomem, *rscr;
        struct clk *clk32k;
        struct tc6387xb *tc6387xb;
index a563dfa3cf87434706ab8f464d1538329fa5b4f0..11c19e5385510ccf8d8272e709e7b95264b66afc 100644 (file)
@@ -604,7 +604,7 @@ static void tc6393xb_detach_irq(struct platform_device *dev)
 
 static int tc6393xb_probe(struct platform_device *dev)
 {
-       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
        struct tc6393xb *tc6393xb;
        struct resource *iomem, *rscr;
        int ret, temp;
@@ -733,7 +733,7 @@ static int tc6393xb_probe(struct platform_device *dev)
 
 static int tc6393xb_remove(struct platform_device *dev)
 {
-       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
        struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
        int ret;
 
@@ -765,7 +765,7 @@ static int tc6393xb_remove(struct platform_device *dev)
 #ifdef CONFIG_PM
 static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
 {
-       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
        struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
        int i, ret;
 
@@ -788,7 +788,7 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
 
 static int tc6393xb_resume(struct platform_device *dev)
 {
-       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
        struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
        int ret;
        int i;
index 09a14cec351ba4b0d3c606fcf8ad112684ee1a2b..1c2b994e1f6c0b0ce1e4bd346a4ff6e1e1c77e3d 100644 (file)
@@ -318,7 +318,7 @@ static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data)
 static int ti_ssp_probe(struct platform_device *pdev)
 {
        static struct ti_ssp *ssp;
-       const struct ti_ssp_data *pdata = pdev->dev.platform_data;
+       const struct ti_ssp_data *pdata = dev_get_platdata(&pdev->dev);
        int error = 0, prediv = 0xff, id;
        unsigned long sysclk;
        struct device *dev = &pdev->dev;
index b003a16ba227384d8deddb861d89515a0f29b525..baaf5a8123bb8eba1aadffda901238acce2a9a98 100644 (file)
@@ -57,20 +57,20 @@ EXPORT_SYMBOL_GPL(am335x_tsc_se_update);
 void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
 {
        spin_lock(&tsadc->reg_lock);
+       tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
        tsadc->reg_se_cache |= val;
-       spin_unlock(&tsadc->reg_lock);
-
        am335x_tsc_se_update(tsadc);
+       spin_unlock(&tsadc->reg_lock);
 }
 EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
 
 void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
 {
        spin_lock(&tsadc->reg_lock);
+       tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
        tsadc->reg_se_cache &= ~val;
-       spin_unlock(&tsadc->reg_lock);
-
        am335x_tsc_se_update(tsadc);
+       spin_unlock(&tsadc->reg_lock);
 }
 EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
 
@@ -197,24 +197,21 @@ static    int ti_tscadc_probe(struct platform_device *pdev)
        clock_rate = clk_get_rate(clk);
        clk_put(clk);
        clk_value = clock_rate / ADC_CLK;
-       if (clk_value < MAX_CLK_DIV) {
-               dev_err(&pdev->dev, "clock input less than min clock requirement\n");
-               err = -EINVAL;
-               goto err_disable_clk;
-       }
+
        /* TSCADC_CLKDIV needs to be configured to the value minus 1 */
        clk_value = clk_value - 1;
        tscadc_writel(tscadc, REG_CLKDIV, clk_value);
 
        /* Set the control register bits */
        ctrl = CNTRLREG_STEPCONFIGWRT |
-                       CNTRLREG_TSCENB |
-                       CNTRLREG_STEPID |
-                       CNTRLREG_4WIRE;
+                       CNTRLREG_STEPID;
+       if (tsc_wires > 0)
+               ctrl |= CNTRLREG_4WIRE | CNTRLREG_TSCENB;
        tscadc_writel(tscadc, REG_CTRL, ctrl);
 
        /* Set register bits for Idle Config Mode */
-       tscadc_idle_config(tscadc);
+       if (tsc_wires > 0)
+               tscadc_idle_config(tscadc);
 
        /* Enable the TSC module enable bit */
        ctrl = tscadc_readl(tscadc, REG_CTRL);
@@ -294,10 +291,13 @@ static int tscadc_resume(struct device *dev)
        pm_runtime_get_sync(dev);
 
        /* context restore */
-       ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
-                       CNTRLREG_STEPID | CNTRLREG_4WIRE;
+       ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID;
+       if (tscadc_dev->tsc_cell != -1)
+               ctrl |= CNTRLREG_TSCENB | CNTRLREG_4WIRE;
        tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
-       tscadc_idle_config(tscadc_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,
index 0c1fcbc23d045652ba224a0871a05f1769d2114a..a6755ec7bd6ac55a1a8675a2d0382330f6863f54 100644 (file)
@@ -115,11 +115,11 @@ static const struct resource timberdale_ocores_resources[] = {
        },
 };
 
-const struct max7301_platform_data timberdale_max7301_platform_data = {
+static const struct max7301_platform_data timberdale_max7301_platform_data = {
        .base = 200
 };
 
-const struct mc33880_platform_data timberdale_mc33880_platform_data = {
+static const struct mc33880_platform_data timberdale_mc33880_platform_data = {
        .base = 100
 };
 
@@ -781,7 +781,6 @@ static int timb_probe(struct pci_dev *dev,
                        priv->fw.major, priv->fw.minor, ip_setup);
                err = -ENODEV;
                goto err_mfd;
-               break;
        }
 
        if (err) {
@@ -869,34 +868,7 @@ static struct pci_driver timberdale_pci_driver = {
        .remove = timb_remove,
 };
 
-static int __init timberdale_init(void)
-{
-       int err;
-
-       err = pci_register_driver(&timberdale_pci_driver);
-       if (err < 0) {
-               printk(KERN_ERR
-                       "Failed to register PCI driver for %s device.\n",
-                       timberdale_pci_driver.name);
-               return -ENODEV;
-       }
-
-       printk(KERN_INFO "Driver for %s has been successfully registered.\n",
-               timberdale_pci_driver.name);
-
-       return 0;
-}
-
-static void __exit timberdale_exit(void)
-{
-       pci_unregister_driver(&timberdale_pci_driver);
-
-       printk(KERN_INFO "Driver for %s has been successfully unregistered.\n",
-               timberdale_pci_driver.name);
-}
-
-module_init(timberdale_init);
-module_exit(timberdale_exit);
+module_pci_driver(timberdale_pci_driver);
 
 MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
 MODULE_VERSION(DRV_VERSION);
index 1d302f583adf2c3b2633164daa4c9fe253563476..b5dfa6e4e692968f80bc31f85be7757db4c80e69 100644 (file)
@@ -147,7 +147,7 @@ static int tps6105x_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, tps6105x);
        tps6105x->client = client;
-       pdata = client->dev.platform_data;
+       pdata = dev_get_platdata(&client->dev);
        tps6105x->pdata = pdata;
        mutex_init(&tps6105x->lock);
 
index da2691f22e114390f3f40817473f24a12c302f8f..743fb524fc8ae96f58cfaa6ea635317b621878cb 100644 (file)
@@ -242,8 +242,8 @@ static int dbg_show(struct seq_file *s, void *_)
        seq_printf(s, "mask2     %s\n", buf);
        /* ignore ackint2 */
 
-       schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
-
+       queue_delayed_work(system_power_efficient_wq, &tps->work,
+                          POWER_POLL_DELAY);
 
        /* VMAIN voltage, enable lowpower, etc */
        value = i2c_smbus_read_byte_data(tps->client, TPS_VDCDC1);
@@ -400,7 +400,8 @@ static void tps65010_interrupt(struct tps65010 *tps)
                        && (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC)))
                poll = 1;
        if (poll)
-               schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
+               queue_delayed_work(system_power_efficient_wq, &tps->work,
+                                  POWER_POLL_DELAY);
 
        /* also potentially gpio-in rise or fall */
 }
@@ -448,7 +449,7 @@ static irqreturn_t tps65010_irq(int irq, void *_tps)
 
        disable_irq_nosync(irq);
        set_bit(FLAG_IRQ_ENABLE, &tps->flags);
-       schedule_delayed_work(&tps->work, 0);
+       queue_delayed_work(system_power_efficient_wq, &tps->work, 0);
        return IRQ_HANDLED;
 }
 
@@ -517,7 +518,7 @@ static struct tps65010 *the_tps;
 static int __exit tps65010_remove(struct i2c_client *client)
 {
        struct tps65010         *tps = i2c_get_clientdata(client);
-       struct tps65010_board   *board = client->dev.platform_data;
+       struct tps65010_board   *board = dev_get_platdata(&client->dev);
 
        if (board && board->teardown) {
                int status = board->teardown(client, board->context);
@@ -529,7 +530,6 @@ static int __exit tps65010_remove(struct i2c_client *client)
                free_irq(client->irq, tps);
        cancel_delayed_work_sync(&tps->work);
        debugfs_remove(tps->file);
-       kfree(tps);
        the_tps = NULL;
        return 0;
 }
@@ -539,7 +539,7 @@ static int tps65010_probe(struct i2c_client *client,
 {
        struct tps65010         *tps;
        int                     status;
-       struct tps65010_board   *board = client->dev.platform_data;
+       struct tps65010_board   *board = dev_get_platdata(&client->dev);
 
        if (the_tps) {
                dev_dbg(&client->dev, "only one tps6501x chip allowed\n");
@@ -549,7 +549,7 @@ static int tps65010_probe(struct i2c_client *client,
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -EINVAL;
 
-       tps = kzalloc(sizeof *tps, GFP_KERNEL);
+       tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
        if (!tps)
                return -ENOMEM;
 
@@ -567,7 +567,7 @@ static int tps65010_probe(struct i2c_client *client,
                if (status < 0) {
                        dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
                                        client->irq, status);
-                       goto fail1;
+                       return status;
                }
                /* annoying race here, ideally we'd have an option
                 * to claim the irq now and enable it later.
@@ -667,9 +667,6 @@ static int tps65010_probe(struct i2c_client *client,
        }
 
        return 0;
-fail1:
-       kfree(tps);
-       return status;
 }
 
 static const struct i2c_device_id tps65010_id[] = {
@@ -718,7 +715,8 @@ int tps65010_set_vbus_draw(unsigned mA)
                        && test_and_set_bit(
                                FLAG_VBUS_CHANGED, &the_tps->flags)) {
                /* gadget drivers call this in_irq() */
-               schedule_delayed_work(&the_tps->work, 0);
+               queue_delayed_work(system_power_efficient_wq, &the_tps->work,
+                                  0);
        }
        local_irq_restore(flags);
 
index fbd6ee67b5a511317c02fe45d5d039b881987d8d..e6f03a733879b063d670ecc2bd074ea28063ec18 100644 (file)
@@ -172,7 +172,7 @@ MODULE_DEVICE_TABLE(of, tps65090_of_match);
 static int tps65090_i2c_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
 {
-       struct tps65090_platform_data *pdata = client->dev.platform_data;
+       struct tps65090_platform_data *pdata = dev_get_platdata(&client->dev);
        int irq_base = 0;
        struct tps65090 *tps65090;
        int ret;
index 4b93ed4d5cd6a3649efdaa2c0eedc191792ab7c0..f54fe4d4f77b34a7ecbcef449635dbdbccf036d8 100644 (file)
@@ -462,7 +462,7 @@ static void tps6586x_power_off(void)
 static int tps6586x_i2c_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
 {
-       struct tps6586x_platform_data *pdata = client->dev.platform_data;
+       struct tps6586x_platform_data *pdata = dev_get_platdata(&client->dev);
        struct tps6586x *tps6586x;
        int ret;
 
index 479886a4cf8054b60750303cc092c88128331c9d..925a044cbdf61740e3c54e0a481a9774587c652b 100644 (file)
@@ -123,7 +123,7 @@ EXPORT_SYMBOL_GPL(tps65912_reg_write);
 
 int tps65912_device_init(struct tps65912 *tps65912)
 {
-       struct tps65912_board *pmic_plat_data = tps65912->dev->platform_data;
+       struct tps65912_board *pmic_plat_data = dev_get_platdata(tps65912->dev);
        struct tps65912_platform_data *init_data;
        int ret, dcdc_avs, value;
 
index c90a2c450f5113c44536eac3b82315be92e9e89d..f15ee6d5cfbf96fb97ef6f169528c624b09a2aba 100644 (file)
@@ -418,7 +418,7 @@ static const struct regmap_config tps80031_regmap_configs[] = {
 static int tps80031_probe(struct i2c_client *client,
                          const struct i2c_device_id *id)
 {
-       struct tps80031_platform_data *pdata = client->dev.platform_data;
+       struct tps80031_platform_data *pdata = dev_get_platdata(&client->dev);
        struct tps80031 *tps80031;
        int ret;
        uint8_t es_version;
index 7f150d94d295146fc58b9c07481d06eb950b8604..29473c2c95ae0d92aa75184199486f70bdf5fc53 100644 (file)
@@ -1137,7 +1137,7 @@ static int twl_remove(struct i2c_client *client)
 static int
 twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-       struct twl4030_platform_data    *pdata = client->dev.platform_data;
+       struct twl4030_platform_data    *pdata = dev_get_platdata(&client->dev);
        struct device_node              *node = client->dev.of_node;
        struct platform_device          *pdev;
        struct regmap_config            *twl_regmap_config;
index a31fba96ef438f745d0966d1c0e7828a8e0c930b..07fe542e6fc008a48995dc6191b73b758a20dcf6 100644 (file)
@@ -187,7 +187,7 @@ static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
 static int twl4030_audio_probe(struct platform_device *pdev)
 {
        struct twl4030_audio *audio;
-       struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+       struct twl4030_audio_data *pdata = dev_get_platdata(&pdev->dev);
        struct device_node *node = pdev->dev.of_node;
        struct mfd_cell *cell = NULL;
        int ret, childs = 0;
index 1ea54d4d003aeb84c87c7af509dc13052a4bfc3f..4c583e47133993b59dd512f1e3ec7316fb68c7fb 100644 (file)
@@ -701,7 +701,7 @@ static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
 static int twl4030_madc_probe(struct platform_device *pdev)
 {
        struct twl4030_madc_data *madc;
-       struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
+       struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
        int ret;
        u8 regval;
 
index a5fd3c7382110d7298ea4ddf72ab644dcf1c6ed5..96162b62f3c0897df3f923ee0d4befcebfcb9048 100644 (file)
@@ -493,7 +493,7 @@ int twl4030_remove_script(u8 flags)
        return err;
 }
 
-int twl4030_power_configure_scripts(struct twl4030_power_data *pdata)
+static int twl4030_power_configure_scripts(struct twl4030_power_data *pdata)
 {
        int err;
        int i;
@@ -509,7 +509,7 @@ int twl4030_power_configure_scripts(struct twl4030_power_data *pdata)
        return 0;
 }
 
-int twl4030_power_configure_resources(struct twl4030_power_data *pdata)
+static int twl4030_power_configure_resources(struct twl4030_power_data *pdata)
 {
        struct twl4030_resconfig *resconfig = pdata->resource_config;
        int err;
@@ -553,9 +553,9 @@ static bool twl4030_power_use_poweroff(struct twl4030_power_data *pdata,
        return false;
 }
 
-int twl4030_power_probe(struct platform_device *pdev)
+static int twl4030_power_probe(struct platform_device *pdev)
 {
-       struct twl4030_power_data *pdata = pdev->dev.platform_data;
+       struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
        struct device_node *node = pdev->dev.of_node;
        int err = 0;
        int err2 = 0;
index 277a8dba42d5742903863e1bfc325297e0f671aa..517eda832f79978ac772c94b3bcf111643ec8835 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/suspend.h>
 #include <linux/of.h>
 #include <linux/irqdomain.h>
+#include <linux/of_device.h>
 
 #include "twl-core.h"
 
@@ -84,39 +85,77 @@ static int twl6030_interrupt_mapping[24] = {
        CHARGERFAULT_INTR_OFFSET,       /* Bit 22       INT_CHRG        */
        RSV_INTR_OFFSET,        /* Bit 23       Reserved                */
 };
+
+static int twl6032_interrupt_mapping[24] = {
+       PWR_INTR_OFFSET,        /* Bit 0        PWRON                   */
+       PWR_INTR_OFFSET,        /* Bit 1        RPWRON                  */
+       PWR_INTR_OFFSET,        /* Bit 2        SYS_VLOW                */
+       RTC_INTR_OFFSET,        /* Bit 3        RTC_ALARM               */
+       RTC_INTR_OFFSET,        /* Bit 4        RTC_PERIOD              */
+       HOTDIE_INTR_OFFSET,     /* Bit 5        HOT_DIE                 */
+       SMPSLDO_INTR_OFFSET,    /* Bit 6        VXXX_SHORT              */
+       PWR_INTR_OFFSET,        /* Bit 7        SPDURATION              */
+
+       PWR_INTR_OFFSET,        /* Bit 8        WATCHDOG                */
+       BATDETECT_INTR_OFFSET,  /* Bit 9        BAT                     */
+       SIMDETECT_INTR_OFFSET,  /* Bit 10       SIM                     */
+       MMCDETECT_INTR_OFFSET,  /* Bit 11       MMC                     */
+       MADC_INTR_OFFSET,       /* Bit 12       GPADC_RT_EOC            */
+       MADC_INTR_OFFSET,       /* Bit 13       GPADC_SW_EOC            */
+       GASGAUGE_INTR_OFFSET,   /* Bit 14       CC_EOC                  */
+       GASGAUGE_INTR_OFFSET,   /* Bit 15       CC_AUTOCAL              */
+
+       USBOTG_INTR_OFFSET,     /* Bit 16       ID_WKUP                 */
+       USBOTG_INTR_OFFSET,     /* Bit 17       VBUS_WKUP               */
+       USBOTG_INTR_OFFSET,     /* Bit 18       ID                      */
+       USB_PRES_INTR_OFFSET,   /* Bit 19       VBUS                    */
+       CHARGER_INTR_OFFSET,    /* Bit 20       CHRG_CTRL               */
+       CHARGERFAULT_INTR_OFFSET,       /* Bit 21       EXT_CHRG        */
+       CHARGERFAULT_INTR_OFFSET,       /* Bit 22       INT_CHRG        */
+       RSV_INTR_OFFSET,        /* Bit 23       Reserved                */
+};
+
 /*----------------------------------------------------------------------*/
 
-static unsigned twl6030_irq_base;
-static int twl_irq;
-static bool twl_irq_wake_enabled;
+struct twl6030_irq {
+       unsigned int            irq_base;
+       int                     twl_irq;
+       bool                    irq_wake_enabled;
+       atomic_t                wakeirqs;
+       struct notifier_block   pm_nb;
+       struct irq_chip         irq_chip;
+       struct irq_domain       *irq_domain;
+       const int               *irq_mapping_tbl;
+};
 
-static struct completion irq_event;
-static atomic_t twl6030_wakeirqs = ATOMIC_INIT(0);
+static struct twl6030_irq *twl6030_irq;
 
 static int twl6030_irq_pm_notifier(struct notifier_block *notifier,
                                   unsigned long pm_event, void *unused)
 {
        int chained_wakeups;
+       struct twl6030_irq *pdata = container_of(notifier, struct twl6030_irq,
+                                                 pm_nb);
 
        switch (pm_event) {
        case PM_SUSPEND_PREPARE:
-               chained_wakeups = atomic_read(&twl6030_wakeirqs);
+               chained_wakeups = atomic_read(&pdata->wakeirqs);
 
-               if (chained_wakeups && !twl_irq_wake_enabled) {
-                       if (enable_irq_wake(twl_irq))
+               if (chained_wakeups && !pdata->irq_wake_enabled) {
+                       if (enable_irq_wake(pdata->twl_irq))
                                pr_err("twl6030 IRQ wake enable failed\n");
                        else
-                               twl_irq_wake_enabled = true;
-               } else if (!chained_wakeups && twl_irq_wake_enabled) {
-                       disable_irq_wake(twl_irq);
-                       twl_irq_wake_enabled = false;
+                               pdata->irq_wake_enabled = true;
+               } else if (!chained_wakeups && pdata->irq_wake_enabled) {
+                       disable_irq_wake(pdata->twl_irq);
+                       pdata->irq_wake_enabled = false;
                }
 
-               disable_irq(twl_irq);
+               disable_irq(pdata->twl_irq);
                break;
 
        case PM_POST_SUSPEND:
-               enable_irq(twl_irq);
+               enable_irq(pdata->twl_irq);
                break;
 
        default:
@@ -126,124 +165,77 @@ static int twl6030_irq_pm_notifier(struct notifier_block *notifier,
        return NOTIFY_DONE;
 }
 
-static struct notifier_block twl6030_irq_pm_notifier_block = {
-       .notifier_call = twl6030_irq_pm_notifier,
-};
-
 /*
- * This thread processes interrupts reported by the Primary Interrupt Handler.
- */
-static int twl6030_irq_thread(void *data)
+* Threaded irq handler for the twl6030 interrupt.
+* We query the interrupt controller in the twl6030 to determine
+* which module is generating the interrupt request and call
+* handle_nested_irq for that module.
+*/
+static irqreturn_t twl6030_irq_thread(int irq, void *data)
 {
-       long irq = (long)data;
-       static unsigned i2c_errors;
-       static const unsigned max_i2c_errors = 100;
-       int ret;
-
-       while (!kthread_should_stop()) {
-               int i;
-               union {
+       int i, ret;
+       union {
                u8 bytes[4];
                u32 int_sts;
-               } sts;
-
-               /* Wait for IRQ, then read PIH irq status (also blocking) */
-               wait_for_completion_interruptible(&irq_event);
-
-               /* read INT_STS_A, B and C in one shot using a burst read */
-               ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes,
-                               REG_INT_STS_A, 3);
-               if (ret) {
-                       pr_warning("twl6030: I2C error %d reading PIH ISR\n",
-                                       ret);
-                       if (++i2c_errors >= max_i2c_errors) {
-                               printk(KERN_ERR "Maximum I2C error count"
-                                               " exceeded.  Terminating %s.\n",
-                                               __func__);
-                               break;
-                       }
-                       complete(&irq_event);
-                       continue;
-               }
-
-
+       } sts;
+       struct twl6030_irq *pdata = data;
+
+       /* read INT_STS_A, B and C in one shot using a burst read */
+       ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes, REG_INT_STS_A, 3);
+       if (ret) {
+               pr_warn("twl6030_irq: I2C error %d reading PIH ISR\n", ret);
+               return IRQ_HANDLED;
+       }
 
-               sts.bytes[3] = 0; /* Only 24 bits are valid*/
+       sts.bytes[3] = 0; /* Only 24 bits are valid*/
 
-               /*
-                * Since VBUS status bit is not reliable for VBUS disconnect
-                * use CHARGER VBUS detection status bit instead.
-                */
-               if (sts.bytes[2] & 0x10)
-                       sts.bytes[2] |= 0x08;
-
-               for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) {
-                       local_irq_disable();
-                       if (sts.int_sts & 0x1) {
-                               int module_irq = twl6030_irq_base +
-                                       twl6030_interrupt_mapping[i];
-                               generic_handle_irq(module_irq);
-
-                       }
-               local_irq_enable();
+       /*
+        * Since VBUS status bit is not reliable for VBUS disconnect
+        * use CHARGER VBUS detection status bit instead.
+        */
+       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 module_irq =
+                               irq_find_mapping(pdata->irq_domain,
+                                                pdata->irq_mapping_tbl[i]);
+                       if (module_irq)
+                               handle_nested_irq(module_irq);
+                       else
+                               pr_err("twl6030_irq: Unmapped PIH ISR %u detected\n",
+                                      i);
+                       pr_debug("twl6030_irq: PIH ISR %u, virq%u\n",
+                                i, module_irq);
                }
 
-               /*
-                * NOTE:
-                * Simulation confirms that documentation is wrong w.r.t the
-                * interrupt status clear operation. A single *byte* write to
-                * any one of STS_A to STS_C register results in all three
-                * STS registers being reset. Since it does not matter which
-                * value is written, all three registers are cleared on a
-                * single byte write, so we just use 0x0 to clear.
-                */
-               ret = twl_i2c_write_u8(TWL_MODULE_PIH, 0x00, REG_INT_STS_A);
-               if (ret)
-                       pr_warning("twl6030: I2C error in clearing PIH ISR\n");
-
-               enable_irq(irq);
-       }
-
-       return 0;
-}
+       /*
+        * NOTE:
+        * Simulation confirms that documentation is wrong w.r.t the
+        * interrupt status clear operation. A single *byte* write to
+        * any one of STS_A to STS_C register results in all three
+        * STS registers being reset. Since it does not matter which
+        * value is written, all three registers are cleared on a
+        * single byte write, so we just use 0x0 to clear.
+        */
+       ret = twl_i2c_write_u8(TWL_MODULE_PIH, 0x00, REG_INT_STS_A);
+       if (ret)
+               pr_warn("twl6030_irq: I2C error in clearing PIH ISR\n");
 
-/*
- * handle_twl6030_int() is the desc->handle method for the twl6030 interrupt.
- * This is a chained interrupt, so there is no desc->action method for it.
- * Now we need to query the interrupt controller in the twl6030 to determine
- * which module is generating the interrupt request.  However, we can't do i2c
- * transactions in interrupt context, so we must defer that work to a kernel
- * thread.  All we do here is acknowledge and mask the interrupt and wakeup
- * the kernel thread.
- */
-static irqreturn_t handle_twl6030_pih(int irq, void *devid)
-{
-       disable_irq_nosync(irq);
-       complete(devid);
        return IRQ_HANDLED;
 }
 
 /*----------------------------------------------------------------------*/
 
-static inline void activate_irq(int irq)
-{
-#ifdef CONFIG_ARM
-       /* ARM requires an extra step to clear IRQ_NOREQUEST, which it
-        * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
-        */
-       set_irq_flags(irq, IRQF_VALID);
-#else
-       /* same effect on other architectures */
-       irq_set_noprobe(irq);
-#endif
-}
-
 static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on)
 {
+       struct twl6030_irq *pdata = irq_get_chip_data(d->irq);
+
        if (on)
-               atomic_inc(&twl6030_wakeirqs);
+               atomic_inc(&pdata->wakeirqs);
        else
-               atomic_dec(&twl6030_wakeirqs);
+               atomic_dec(&pdata->wakeirqs);
 
        return 0;
 }
@@ -318,7 +310,8 @@ int twl6030_mmc_card_detect_config(void)
                return ret;
        }
 
-       return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
+       return irq_find_mapping(twl6030_irq->irq_domain,
+                                MMCDETECT_INTR_OFFSET);
 }
 EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
 
@@ -347,99 +340,143 @@ int twl6030_mmc_card_detect(struct device *dev, int slot)
 }
 EXPORT_SYMBOL(twl6030_mmc_card_detect);
 
+static int twl6030_irq_map(struct irq_domain *d, unsigned int virq,
+                             irq_hw_number_t hwirq)
+{
+       struct twl6030_irq *pdata = d->host_data;
+
+       irq_set_chip_data(virq, pdata);
+       irq_set_chip_and_handler(virq,  &pdata->irq_chip, handle_simple_irq);
+       irq_set_nested_thread(virq, true);
+       irq_set_parent(virq, pdata->twl_irq);
+
+#ifdef CONFIG_ARM
+       /*
+        * ARM requires an extra step to clear IRQ_NOREQUEST, which it
+        * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
+        */
+       set_irq_flags(virq, IRQF_VALID);
+#else
+       /* same effect on other architectures */
+       irq_set_noprobe(virq);
+#endif
+
+       return 0;
+}
+
+static void twl6030_irq_unmap(struct irq_domain *d, unsigned int virq)
+{
+#ifdef CONFIG_ARM
+       set_irq_flags(virq, 0);
+#endif
+       irq_set_chip_and_handler(virq, NULL, NULL);
+       irq_set_chip_data(virq, NULL);
+}
+
+static struct irq_domain_ops twl6030_irq_domain_ops = {
+       .map    = twl6030_irq_map,
+       .unmap  = twl6030_irq_unmap,
+       .xlate  = irq_domain_xlate_onetwocell,
+};
+
+static const struct of_device_id twl6030_of_match[] = {
+       {.compatible = "ti,twl6030", &twl6030_interrupt_mapping},
+       {.compatible = "ti,twl6032", &twl6032_interrupt_mapping},
+       { },
+};
+
 int twl6030_init_irq(struct device *dev, int irq_num)
 {
        struct                  device_node *node = dev->of_node;
-       int                     nr_irqs, irq_base, irq_end;
-       struct task_struct      *task;
-       static struct irq_chip  twl6030_irq_chip;
-       int                     status = 0;
-       int                     i;
+       int                     nr_irqs;
+       int                     status;
        u8                      mask[3];
+       const struct of_device_id *of_id;
 
-       nr_irqs = TWL6030_NR_IRQS;
-
-       irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
-       if (IS_ERR_VALUE(irq_base)) {
-               dev_err(dev, "Fail to allocate IRQ descs\n");
-               return irq_base;
+       of_id = of_match_device(twl6030_of_match, dev);
+       if (!of_id || !of_id->data) {
+               dev_err(dev, "Unknown TWL device model\n");
+               return -EINVAL;
        }
 
-       irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
-                             &irq_domain_simple_ops, NULL);
+       nr_irqs = TWL6030_NR_IRQS;
 
-       irq_end = irq_base + nr_irqs;
+       twl6030_irq = devm_kzalloc(dev, sizeof(*twl6030_irq), GFP_KERNEL);
+       if (!twl6030_irq) {
+               dev_err(dev, "twl6030_irq: Memory allocation failed\n");
+               return -ENOMEM;
+       }
 
        mask[0] = 0xFF;
        mask[1] = 0xFF;
        mask[2] = 0xFF;
 
        /* mask all int lines */
-       twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3);
+       status = twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3);
        /* mask all int sts */
-       twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3);
+       status |= twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3);
        /* clear INT_STS_A,B,C */
-       twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3);
+       status |= twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3);
 
-       twl6030_irq_base = irq_base;
+       if (status < 0) {
+               dev_err(dev, "I2C err writing TWL_MODULE_PIH: %d\n", status);
+               return status;
+       }
 
        /*
         * install an irq handler for each of the modules;
         * clone dummy irq_chip since PIH can't *do* anything
         */
-       twl6030_irq_chip = dummy_irq_chip;
-       twl6030_irq_chip.name = "twl6030";
-       twl6030_irq_chip.irq_set_type = NULL;
-       twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake;
-
-       for (i = irq_base; i < irq_end; i++) {
-               irq_set_chip_and_handler(i, &twl6030_irq_chip,
-                                        handle_simple_irq);
-               irq_set_chip_data(i, (void *)irq_num);
-               activate_irq(i);
+       twl6030_irq->irq_chip = dummy_irq_chip;
+       twl6030_irq->irq_chip.name = "twl6030";
+       twl6030_irq->irq_chip.irq_set_type = NULL;
+       twl6030_irq->irq_chip.irq_set_wake = twl6030_irq_set_wake;
+
+       twl6030_irq->pm_nb.notifier_call = twl6030_irq_pm_notifier;
+       atomic_set(&twl6030_irq->wakeirqs, 0);
+       twl6030_irq->irq_mapping_tbl = of_id->data;
+
+       twl6030_irq->irq_domain =
+               irq_domain_add_linear(node, nr_irqs,
+                                     &twl6030_irq_domain_ops, twl6030_irq);
+       if (!twl6030_irq->irq_domain) {
+               dev_err(dev, "Can't add irq_domain\n");
+               return -ENOMEM;
        }
 
-       dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n",
-                       irq_num, irq_base, irq_end);
+       dev_info(dev, "PIH (irq %d) nested IRQs\n", irq_num);
 
        /* install an irq handler to demultiplex the TWL6030 interrupt */
-       init_completion(&irq_event);
-
-       status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH",
-                            &irq_event);
+       status = request_threaded_irq(irq_num, NULL, twl6030_irq_thread,
+                                     IRQF_ONESHOT, "TWL6030-PIH", twl6030_irq);
        if (status < 0) {
                dev_err(dev, "could not claim irq %d: %d\n", irq_num, status);
                goto fail_irq;
        }
 
-       task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
-       if (IS_ERR(task)) {
-               dev_err(dev, "could not create irq %d thread!\n", irq_num);
-               status = PTR_ERR(task);
-               goto fail_kthread;
-       }
-
-       twl_irq = irq_num;
-       register_pm_notifier(&twl6030_irq_pm_notifier_block);
-       return irq_base;
-
-fail_kthread:
-       free_irq(irq_num, &irq_event);
+       twl6030_irq->twl_irq = irq_num;
+       register_pm_notifier(&twl6030_irq->pm_nb);
+       return 0;
 
 fail_irq:
-       for (i = irq_base; i < irq_end; i++)
-               irq_set_chip_and_handler(i, NULL, NULL);
-
+       irq_domain_remove(twl6030_irq->irq_domain);
        return status;
 }
 
 int twl6030_exit_irq(void)
 {
-       unregister_pm_notifier(&twl6030_irq_pm_notifier_block);
-
-       if (twl6030_irq_base) {
-               pr_err("twl6030: can't yet clean up IRQs?\n");
-               return -ENOSYS;
+       if (twl6030_irq && twl6030_irq->twl_irq) {
+               unregister_pm_notifier(&twl6030_irq->pm_nb);
+               free_irq(twl6030_irq->twl_irq, NULL);
+               /*
+                * TODO: IRQ domain and allocated nested IRQ descriptors
+                * should be freed somehow here. Now It can't be done, because
+                * child devices will not be deleted during removing of
+                * TWL Core driver and they will still contain allocated
+                * virt IRQs in their Resources tables.
+                * The same prevents us from using devm_request_threaded_irq()
+                * in this module.
+                */
        }
        return 0;
 }
index 492ee2cd3400cf7b24863900137b740fbea6a72e..daf66942071c9084779497f6b40ac7bc2c8c916d 100644 (file)
 #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
 #define TWL6040_NUM_SUPPLIES   (2)
 
-static bool twl6040_has_vibra(struct twl6040_platform_data *pdata,
-                             struct device_node *node)
+static bool twl6040_has_vibra(struct device_node *node)
 {
-       if (pdata && pdata->vibra)
-               return true;
-
 #ifdef CONFIG_OF
        if (of_find_node_by_name(node, "vibra"))
                return true;
 #endif
-
        return false;
 }
 
@@ -63,15 +58,9 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
        int ret;
        unsigned int val;
 
-       /* Vibra control registers from cache */
-       if (unlikely(reg == TWL6040_REG_VIBCTLL ||
-                    reg == TWL6040_REG_VIBCTLR)) {
-               val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
-       } else {
-               ret = regmap_read(twl6040->regmap, reg, &val);
-               if (ret < 0)
-                       return ret;
-       }
+       ret = regmap_read(twl6040->regmap, reg, &val);
+       if (ret < 0)
+               return ret;
 
        return val;
 }
@@ -82,9 +71,6 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
        int ret;
 
        ret = regmap_write(twl6040->regmap, reg, val);
-       /* Cache the vibra control registers */
-       if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
-               twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
 
        return ret;
 }
@@ -461,9 +447,20 @@ EXPORT_SYMBOL(twl6040_get_sysclk);
 /* Get the combined status of the vibra control register */
 int twl6040_get_vibralr_status(struct twl6040 *twl6040)
 {
+       unsigned int reg;
+       int ret;
        u8 status;
 
-       status = twl6040->vibra_ctrl_cache[0] | twl6040->vibra_ctrl_cache[1];
+       ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLL, &reg);
+       if (ret != 0)
+               return ret;
+       status = reg;
+
+       ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLR, &reg);
+       if (ret != 0)
+               return ret;
+       status |= reg;
+
        status &= (TWL6040_VIBENA | TWL6040_VIBSEL);
 
        return status;
@@ -490,12 +487,27 @@ static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
        return true;
 }
 
+static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case TWL6040_REG_VIBCTLL:
+       case TWL6040_REG_VIBCTLR:
+       case TWL6040_REG_INTMR:
+               return false;
+       default:
+               return true;
+       }
+}
+
 static struct regmap_config twl6040_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
        .max_register = TWL6040_REG_STATUS, /* 0x2e */
 
        .readable_reg = twl6040_readable_reg,
+       .volatile_reg = twl6040_volatile_reg,
+
+       .cache_type = REGCACHE_RBTREE,
 };
 
 static const struct regmap_irq twl6040_irqs[] = {
@@ -520,14 +532,13 @@ static struct regmap_irq_chip twl6040_irq_chip = {
 static int twl6040_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
-       struct twl6040_platform_data *pdata = client->dev.platform_data;
        struct device_node *node = client->dev.of_node;
        struct twl6040 *twl6040;
        struct mfd_cell *cell = NULL;
        int irq, ret, children = 0;
 
-       if (!pdata && !node) {
-               dev_err(&client->dev, "Platform data is missing\n");
+       if (!node) {
+               dev_err(&client->dev, "of node is missing\n");
                return -EINVAL;
        }
 
@@ -539,23 +550,19 @@ static int twl6040_probe(struct i2c_client *client,
 
        twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
                               GFP_KERNEL);
-       if (!twl6040) {
-               ret = -ENOMEM;
-               goto err;
-       }
+       if (!twl6040)
+               return -ENOMEM;
 
        twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config);
-       if (IS_ERR(twl6040->regmap)) {
-               ret = PTR_ERR(twl6040->regmap);
-               goto err;
-       }
+       if (IS_ERR(twl6040->regmap))
+               return PTR_ERR(twl6040->regmap);
 
        i2c_set_clientdata(client, twl6040);
 
        twl6040->supplies[0].supply = "vio";
        twl6040->supplies[1].supply = "v2v1";
        ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES,
-                                twl6040->supplies);
+                                     twl6040->supplies);
        if (ret != 0) {
                dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
                goto regulator_get_err;
@@ -576,44 +583,40 @@ static int twl6040_probe(struct i2c_client *client,
        twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
 
        /* ERRATA: Automatic power-up is not possible in ES1.0 */
-       if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) {
-               if (pdata)
-                       twl6040->audpwron = pdata->audpwron_gpio;
-               else
-                       twl6040->audpwron = of_get_named_gpio(node,
-                                               "ti,audpwron-gpio", 0);
-       } else
+       if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
+               twl6040->audpwron = of_get_named_gpio(node,
+                                                     "ti,audpwron-gpio", 0);
+       else
                twl6040->audpwron = -EINVAL;
 
        if (gpio_is_valid(twl6040->audpwron)) {
                ret = devm_gpio_request_one(&client->dev, twl6040->audpwron,
-                                       GPIOF_OUT_INIT_LOW, "audpwron");
+                                           GPIOF_OUT_INIT_LOW, "audpwron");
                if (ret)
                        goto gpio_err;
        }
 
-       ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq,
-                       IRQF_ONESHOT, 0, &twl6040_irq_chip,
-                       &twl6040->irq_data);
+       ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT,
+                                 0, &twl6040_irq_chip,&twl6040->irq_data);
        if (ret < 0)
                goto gpio_err;
 
        twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data,
-                                              TWL6040_IRQ_READY);
+                                                TWL6040_IRQ_READY);
        twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data,
-                                              TWL6040_IRQ_TH);
+                                             TWL6040_IRQ_TH);
 
        ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL,
-                                  twl6040_readyint_handler, IRQF_ONESHOT,
-                                  "twl6040_irq_ready", twl6040);
+                                       twl6040_readyint_handler, IRQF_ONESHOT,
+                                       "twl6040_irq_ready", twl6040);
        if (ret) {
                dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret);
                goto readyirq_err;
        }
 
        ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL,
-                                  twl6040_thint_handler, IRQF_ONESHOT,
-                                  "twl6040_irq_th", twl6040);
+                                       twl6040_thint_handler, IRQF_ONESHOT,
+                                       "twl6040_irq_th", twl6040);
        if (ret) {
                dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
                goto thirq_err;
@@ -625,8 +628,6 @@ static int twl6040_probe(struct i2c_client *client,
        /*
         * The main functionality of twl6040 to provide audio on OMAP4+ systems.
         * We can add the ASoC codec child whenever this driver has been loaded.
-        * The ASoC codec can work without pdata, pass the platform_data only if
-        * it has been provided.
         */
        irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG);
        cell = &twl6040->cells[children];
@@ -635,13 +636,10 @@ static int twl6040_probe(struct i2c_client *client,
        twl6040_codec_rsrc[0].end = irq;
        cell->resources = twl6040_codec_rsrc;
        cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc);
-       if (pdata && pdata->codec) {
-               cell->platform_data = pdata->codec;
-               cell->pdata_size = sizeof(*pdata->codec);
-       }
        children++;
 
-       if (twl6040_has_vibra(pdata, node)) {
+       /* Vibra input driver support */
+       if (twl6040_has_vibra(node)) {
                irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB);
 
                cell = &twl6040->cells[children];
@@ -650,28 +648,13 @@ static int twl6040_probe(struct i2c_client *client,
                twl6040_vibra_rsrc[0].end = irq;
                cell->resources = twl6040_vibra_rsrc;
                cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc);
-
-               if (pdata && pdata->vibra) {
-                       cell->platform_data = pdata->vibra;
-                       cell->pdata_size = sizeof(*pdata->vibra);
-               }
                children++;
        }
 
-       /*
-        * Enable the GPO driver in the following cases:
-        * DT booted kernel or legacy boot with valid gpo platform_data
-        */
-       if (!pdata || (pdata && pdata->gpo)) {
-               cell = &twl6040->cells[children];
-               cell->name = "twl6040-gpo";
-
-               if (pdata) {
-                       cell->platform_data = pdata->gpo;
-                       cell->pdata_size = sizeof(*pdata->gpo);
-               }
-               children++;
-       }
+       /* GPO support */
+       cell = &twl6040->cells[children];
+       cell->name = "twl6040-gpo";
+       children++;
 
        ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
                              NULL, 0, NULL);
@@ -690,7 +673,7 @@ static int twl6040_probe(struct i2c_client *client,
        regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
 regulator_get_err:
        i2c_set_clientdata(client, NULL);
-err:
+
        return ret;
 }
 
index e9031fa9d53d1983e0dfe5ee5307bf8d24f79857..ebb20edf9c1758a7d6e58ddce9f856dd89bbd860 100644 (file)
@@ -52,7 +52,7 @@ static int ucb1400_core_probe(struct device *dev)
        struct ucb1400_ts ucb_ts;
        struct ucb1400_gpio ucb_gpio;
        struct snd_ac97 *ac97;
-       struct ucb1400_pdata *pdata = dev->platform_data;
+       struct ucb1400_pdata *pdata = dev_get_platdata(dev);
 
        memset(&ucb_ts, 0, sizeof(ucb_ts));
        memset(&ucb_gpio, 0, sizeof(ucb_gpio));
index 70f02daeb22a884da64297f26bc3f43e4e365aa8..d5966e6b5a7d8058a9ff37f15a86204ffe6ffe6c 100644 (file)
@@ -393,22 +393,24 @@ static struct irq_chip ucb1x00_irqchip = {
 static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
 {
        struct ucb1x00_dev *dev;
-       int ret = -ENOMEM;
+       int ret;
 
        dev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL);
-       if (dev) {
-               dev->ucb = ucb;
-               dev->drv = drv;
-
-               ret = drv->add(dev);
-
-               if (ret == 0) {
-                       list_add_tail(&dev->dev_node, &ucb->devs);
-                       list_add_tail(&dev->drv_node, &drv->devs);
-               } else {
-                       kfree(dev);
-               }
+       if (!dev)
+               return -ENOMEM;
+
+       dev->ucb = ucb;
+       dev->drv = drv;
+
+       ret = drv->add(dev);
+       if (ret) {
+               kfree(dev);
+               return ret;
        }
+
+       list_add_tail(&dev->dev_node, &ucb->devs);
+       list_add_tail(&dev->drv_node, &drv->devs);
+
        return ret;
 }
 
@@ -669,9 +671,10 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
        mutex_unlock(&ucb1x00_mutex);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int ucb1x00_suspend(struct device *dev)
 {
-       struct ucb1x00_plat_data *pdata = dev->platform_data;
+       struct ucb1x00_plat_data *pdata = dev_get_platdata(dev);
        struct ucb1x00 *ucb = dev_get_drvdata(dev);
        struct ucb1x00_dev *udev;
 
@@ -703,7 +706,7 @@ static int ucb1x00_suspend(struct device *dev)
 
 static int ucb1x00_resume(struct device *dev)
 {
-       struct ucb1x00_plat_data *pdata = dev->platform_data;
+       struct ucb1x00_plat_data *pdata = dev_get_platdata(dev);
        struct ucb1x00 *ucb = dev_get_drvdata(dev);
        struct ucb1x00_dev *udev;
 
@@ -736,6 +739,7 @@ static int ucb1x00_resume(struct device *dev)
        mutex_unlock(&ucb1x00_mutex);
        return 0;
 }
+#endif
 
 static const struct dev_pm_ops ucb1x00_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
index edbe6c1b755a75a467c933a10323860089a33595..f7c52d901040cc5b14f00ebb86a8678ee7918e6d 100644 (file)
@@ -172,12 +172,9 @@ static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
 
 static int wl1273_core_remove(struct i2c_client *client)
 {
-       struct wl1273_core *core = i2c_get_clientdata(client);
-
        dev_dbg(&client->dev, "%s\n", __func__);
 
        mfd_remove_devices(&client->dev);
-       kfree(core);
 
        return 0;
 }
@@ -185,7 +182,7 @@ static int wl1273_core_remove(struct i2c_client *client)
 static int wl1273_core_probe(struct i2c_client *client,
                                       const struct i2c_device_id *id)
 {
-       struct wl1273_fm_platform_data *pdata = client->dev.platform_data;
+       struct wl1273_fm_platform_data *pdata = dev_get_platdata(&client->dev);
        struct wl1273_core *core;
        struct mfd_cell *cell;
        int children = 0;
@@ -203,7 +200,7 @@ static int wl1273_core_probe(struct i2c_client *client,
                return -EINVAL;
        }
 
-       core = kzalloc(sizeof(*core), GFP_KERNEL);
+       core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
        if (!core)
                return -ENOMEM;
 
@@ -249,7 +246,6 @@ static int wl1273_core_probe(struct i2c_client *client,
 
 err:
        pdata->free_resources();
-       kfree(core);
 
        dev_dbg(&client->dev, "%s\n", __func__);
 
index 2a7972349159fb91f27e802addf7790be81c341a..3113e39b318e27a7aa2e74b7433e601edae2da72 100644 (file)
@@ -468,12 +468,14 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x00000176, 0x0000 },    /* R374   - FLL1 Control 6 */
        { 0x00000177, 0x0281 },    /* R375   - FLL1 Loop Filter Test 1 */
        { 0x00000178, 0x0000 },    /* R376   - FLL1 NCO Test 0 */
+       { 0x00000179, 0x0000 },    /* R376   - FLL1 Control 7 */
        { 0x00000181, 0x0000 },    /* R385   - FLL1 Synchroniser 1 */
        { 0x00000182, 0x0000 },    /* R386   - FLL1 Synchroniser 2 */
        { 0x00000183, 0x0000 },    /* R387   - FLL1 Synchroniser 3 */
        { 0x00000184, 0x0000 },    /* R388   - FLL1 Synchroniser 4 */
        { 0x00000185, 0x0000 },    /* R389   - FLL1 Synchroniser 5 */
        { 0x00000186, 0x0000 },    /* R390   - FLL1 Synchroniser 6 */
+       { 0x00000187, 0x0001 },    /* R390   - FLL1 Synchroniser 7 */
        { 0x00000189, 0x0000 },    /* R393   - FLL1 Spread Spectrum */
        { 0x0000018A, 0x0004 },    /* R394   - FLL1 GPIO Clock */
        { 0x00000191, 0x0000 },    /* R401   - FLL2 Control 1 */
@@ -484,12 +486,14 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x00000196, 0x0000 },    /* R406   - FLL2 Control 6 */
        { 0x00000197, 0x0000 },    /* R407   - FLL2 Loop Filter Test 1 */
        { 0x00000198, 0x0000 },    /* R408   - FLL2 NCO Test 0 */
+       { 0x00000199, 0x0000 },    /* R408   - FLL2 Control 7 */
        { 0x000001A1, 0x0000 },    /* R417   - FLL2 Synchroniser 1 */
        { 0x000001A2, 0x0000 },    /* R418   - FLL2 Synchroniser 2 */
        { 0x000001A3, 0x0000 },    /* R419   - FLL2 Synchroniser 3 */
        { 0x000001A4, 0x0000 },    /* R420   - FLL2 Synchroniser 4 */
        { 0x000001A5, 0x0000 },    /* R421   - FLL2 Synchroniser 5 */
        { 0x000001A6, 0x0000 },    /* R422   - FLL2 Synchroniser 6 */
+       { 0x000001A7, 0x0001 },    /* R422   - FLL2 Synchroniser 7 */
        { 0x000001A9, 0x0000 },    /* R425   - FLL2 Spread Spectrum */
        { 0x000001AA, 0x0004 },    /* R426   - FLL2 GPIO Clock */
        { 0x00000200, 0x0006 },    /* R512   - Mic Charge Pump 1 */
@@ -503,6 +507,11 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x0000029C, 0x0000 },    /* R668   - Headphone Detect 2 */
        { 0x000002A3, 0x1102 },    /* R675   - Mic Detect 1 */
        { 0x000002A4, 0x009F },    /* R676   - Mic Detect 2 */
+       { 0x000002A5, 0x0000 },    /* R677   - Mic Detect 3 */
+       { 0x000002A6, 0x3737 },    /* R678   - Mic Detect Level 1 */
+       { 0x000002A7, 0x372C },    /* R679   - Mic Detect Level 2 */
+       { 0x000002A8, 0x1422 },    /* R680   - Mic Detect Level 3 */
+       { 0x000002A9, 0x300A },    /* R681   - Mic Detect Level 4 */
        { 0x000002C3, 0x0000 },    /* R707   - Mic noise mix control 1 */
        { 0x000002D3, 0x0000 },    /* R723   - Jack detect analogue */
        { 0x00000300, 0x0000 },    /* R768   - Input Enables */
@@ -1392,6 +1401,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_FLL1_CONTROL_4:
        case ARIZONA_FLL1_CONTROL_5:
        case ARIZONA_FLL1_CONTROL_6:
+       case ARIZONA_FLL1_CONTROL_7:
        case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
        case ARIZONA_FLL1_NCO_TEST_0:
        case ARIZONA_FLL1_SYNCHRONISER_1:
@@ -1400,6 +1410,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_FLL1_SYNCHRONISER_4:
        case ARIZONA_FLL1_SYNCHRONISER_5:
        case ARIZONA_FLL1_SYNCHRONISER_6:
+       case ARIZONA_FLL1_SYNCHRONISER_7:
        case ARIZONA_FLL1_SPREAD_SPECTRUM:
        case ARIZONA_FLL1_GPIO_CLOCK:
        case ARIZONA_FLL2_CONTROL_1:
@@ -1408,6 +1419,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_FLL2_CONTROL_4:
        case ARIZONA_FLL2_CONTROL_5:
        case ARIZONA_FLL2_CONTROL_6:
+       case ARIZONA_FLL2_CONTROL_7:
        case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
        case ARIZONA_FLL2_NCO_TEST_0:
        case ARIZONA_FLL2_SYNCHRONISER_1:
@@ -1416,6 +1428,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_FLL2_SYNCHRONISER_4:
        case ARIZONA_FLL2_SYNCHRONISER_5:
        case ARIZONA_FLL2_SYNCHRONISER_6:
+       case ARIZONA_FLL2_SYNCHRONISER_7:
        case ARIZONA_FLL2_SPREAD_SPECTRUM:
        case ARIZONA_FLL2_GPIO_CLOCK:
        case ARIZONA_MIC_CHARGE_PUMP_1:
@@ -1430,6 +1443,10 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_MIC_DETECT_1:
        case ARIZONA_MIC_DETECT_2:
        case ARIZONA_MIC_DETECT_3:
+       case ARIZONA_MIC_DETECT_LEVEL_1:
+       case ARIZONA_MIC_DETECT_LEVEL_2:
+       case ARIZONA_MIC_DETECT_LEVEL_3:
+       case ARIZONA_MIC_DETECT_LEVEL_4:
        case ARIZONA_MIC_NOISE_MIX_CONTROL_1:
        case ARIZONA_JACK_DETECT_ANALOGUE:
        case ARIZONA_INPUT_ENABLES:
@@ -2332,6 +2349,7 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
        case ARIZONA_IRQ_PIN_STATUS:
        case ARIZONA_AOD_IRQ1:
        case ARIZONA_AOD_IRQ2:
+       case ARIZONA_FX_CTRL2:
        case ARIZONA_ASRC_STATUS:
        case ARIZONA_DSP_STATUS:
        case ARIZONA_DSP1_CONTROL_1:
index 521340a708d3a76d9ae6ef8241f085bcd623439a..5c459f469224a61719d3258e948c0f0f3ecef856 100644 (file)
@@ -1618,7 +1618,7 @@ EXPORT_SYMBOL_GPL(wm831x_regmap_config);
  */
 int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 {
-       struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
        int rev, wm831x_num;
        enum wm831x_parent parent;
        int ret, i;
index 804e56ec99eb284f4c32e1f44f8b7a143d4f340c..64e512eadf1718de932218ba2c3f60b7c216e257 100644 (file)
@@ -571,7 +571,7 @@ static struct irq_domain_ops wm831x_irq_domain_ops = {
 
 int wm831x_irq_init(struct wm831x *wm831x, int irq)
 {
-       struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
        struct irq_domain *domain;
        int i, ret, irq_base;
 
index e7ed14f661d8eb1360d7974ae0bf64ec90ea0401..07de3cc5a0d91db385a8ef755e8bf89d3817477b 100644 (file)
@@ -34,7 +34,6 @@ static int wm831x_spi_probe(struct spi_device *spi)
        if (wm831x == NULL)
                return -ENOMEM;
 
-       spi->bits_per_word = 16;
        spi->mode = SPI_MODE_0;
 
        spi_set_drvdata(spi, wm831x);
index 2e57101c8d3dabfc395f2bf764bddc23a411bbe5..f919def05e24778e53678385075b6fef440e1cf7 100644 (file)
@@ -27,6 +27,7 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct wm8350 *wm8350;
+       struct wm8350_platform_data *pdata = dev_get_platdata(&i2c->dev);
        int ret = 0;
 
        wm8350 = devm_kzalloc(&i2c->dev, sizeof(struct wm8350), GFP_KERNEL);
@@ -44,7 +45,7 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
        i2c_set_clientdata(i2c, wm8350);
        wm8350->dev = &i2c->dev;
 
-       return wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data);
+       return wm8350_device_init(wm8350, i2c->irq, pdata);
 }
 
 static int wm8350_i2c_remove(struct i2c_client *i2c)
index 639ca359242f849cebfe407333e6107c0bca4bbb..d66d256551fb77768fc9d458d5493c976ec25f30 100644 (file)
@@ -178,7 +178,7 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
        wm8400->dev = &i2c->dev;
        i2c_set_clientdata(i2c, wm8400);
 
-       ret = wm8400_init(wm8400, i2c->dev.platform_data);
+       ret = wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
        if (ret != 0)
                goto err;
 
index 781115e8dca90823bbae297ab4eadc9ff63fa791..e1c283e6d4e54eca7e88e1404ed9d1ec72497cf9 100644 (file)
@@ -201,35 +201,7 @@ static int wm8994_suspend(struct device *dev)
        int ret;
 
        /* Don't actually go through with the suspend if the CODEC is
-        * still active (eg, for audio passthrough from CP. */
-       ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read power status: %d\n", ret);
-       } else if (ret & WM8994_VMID_SEL_MASK) {
-               dev_dbg(dev, "CODEC still active, ignoring suspend\n");
-               return 0;
-       }
-
-       ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read power status: %d\n", ret);
-       } else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA |
-                         WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA |
-                         WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) {
-               dev_dbg(dev, "CODEC still active, ignoring suspend\n");
-               return 0;
-       }
-
-       ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read power status: %d\n", ret);
-       } else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
-                         WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA |
-                         WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) {
-               dev_dbg(dev, "CODEC still active, ignoring suspend\n");
-               return 0;
-       }
-
+        * still active for accessory detect. */
        switch (wm8994->type) {
        case WM8958:
        case WM1811:
@@ -245,20 +217,6 @@ static int wm8994_suspend(struct device *dev)
                break;
        }
 
-       switch (wm8994->type) {
-       case WM1811:
-               ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
-               if (ret < 0) {
-                       dev_err(dev, "Failed to read jackdet: %d\n", ret);
-               } else if (ret & WM1811_JACKDET_MODE_MASK) {
-                       dev_dbg(dev, "CODEC still active, ignoring suspend\n");
-                       return 0;
-               }
-               break;
-       default:
-               break;
-       }
-
        /* Disable LDO pulldowns while the device is suspended if we
         * don't know that something will be driving them. */
        if (!wm8994->ldo_ena_always_driven)
index d3a184a240f5e0a7cb683bb330b82d01c15eaeaf..e74dedda5b557caabedf38b045414e7ec7830bd6 100644 (file)
@@ -193,7 +193,7 @@ int wm8994_irq_init(struct wm8994 *wm8994)
 {
        int ret;
        unsigned long irqflags;
-       struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+       struct wm8994_pdata *pdata = dev_get_platdata(wm8994->dev);
 
        if (!wm8994->irq) {
                dev_warn(wm8994->dev,
index 82a35b91cdbc874da2fb9227f30a056be2de233a..375a880e0c5fb899efa5a2de9b77543fcf66d12d 100644 (file)
@@ -1,6 +1,6 @@
 /* Realtek PCI-Express SD/MMC Card Interface driver
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #include <linux/module.h>
@@ -56,7 +55,6 @@ struct realtek_pci_sdmmc {
        bool                    double_clk;
        bool                    eject;
        bool                    initial_mode;
-       bool                    ddr_mode;
        int                     power_state;
 #define SDMMC_POWER_ON         1
 #define SDMMC_POWER_OFF                0
@@ -228,6 +226,7 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
        int stat_idx = 0;
        u8 rsp_type;
        int rsp_len = 5;
+       bool clock_toggled = false;
 
        dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
                        __func__, cmd_idx, arg);
@@ -271,6 +270,8 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
                                0xFF, SD_CLK_TOGGLE_EN);
                if (err < 0)
                        goto out;
+
+               clock_toggled = true;
        }
 
        rtsx_pci_init_cmd(pcr);
@@ -351,6 +352,10 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
 
 out:
        cmd->error = err;
+
+       if (err && clock_toggled)
+               rtsx_pci_write_register(pcr, SD_BUS_STAT,
+                               SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
 }
 
 static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
@@ -475,18 +480,24 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host,
        kfree(buf);
 }
 
-static int sd_change_phase(struct realtek_pci_sdmmc *host, u8 sample_point)
+static int sd_change_phase(struct realtek_pci_sdmmc *host,
+               u8 sample_point, bool rx)
 {
        struct rtsx_pcr *pcr = host->pcr;
        int err;
 
-       dev_dbg(sdmmc_dev(host), "%s: sample_point = %d\n",
-                       __func__, sample_point);
+       dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n",
+                       __func__, rx ? "RX" : "TX", sample_point);
 
        rtsx_pci_init_cmd(pcr);
 
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
-       rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPRX_CTL, 0x1F, sample_point);
+       if (rx)
+               rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+                               SD_VPRX_CTL, 0x1F, sample_point);
+       else
+               rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+                               SD_VPTX_CTL, 0x1F, sample_point);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
                        PHASE_NOT_RESET, PHASE_NOT_RESET);
@@ -602,7 +613,7 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host,
        int err;
        u8 cmd[5] = {0};
 
-       err = sd_change_phase(host, sample_point);
+       err = sd_change_phase(host, sample_point, true);
        if (err < 0)
                return err;
 
@@ -664,7 +675,7 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode)
                if (final_phase == 0xFF)
                        return -EINVAL;
 
-               err = sd_change_phase(host, final_phase);
+               err = sd_change_phase(host, final_phase, true);
                if (err < 0)
                        return err;
        } else {
@@ -833,14 +844,11 @@ static int sd_set_power_mode(struct realtek_pci_sdmmc *host,
        return err;
 }
 
-static int sd_set_timing(struct realtek_pci_sdmmc *host,
-               unsigned char timing, bool *ddr_mode)
+static int sd_set_timing(struct realtek_pci_sdmmc *host, unsigned char timing)
 {
        struct rtsx_pcr *pcr = host->pcr;
        int err = 0;
 
-       *ddr_mode = false;
-
        rtsx_pci_init_cmd(pcr);
 
        switch (timing) {
@@ -857,8 +865,6 @@ static int sd_set_timing(struct realtek_pci_sdmmc *host,
                break;
 
        case MMC_TIMING_UHS_DDR50:
-               *ddr_mode = true;
-
                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
                                0x0C | SD_ASYNC_FIFO_NOT_RST,
                                SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST);
@@ -926,7 +932,7 @@ static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        sd_set_bus_width(host, ios->bus_width);
        sd_set_power_mode(host, ios->power_mode);
-       sd_set_timing(host, ios->timing, &host->ddr_mode);
+       sd_set_timing(host, ios->timing);
 
        host->vpclk = false;
        host->double_clk = true;
@@ -1121,11 +1127,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
                        goto out;
        }
 
+out:
        /* Stop toggle SD clock in idle */
        err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
                        SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
 
-out:
        mutex_unlock(&pcr->pcr_mutex);
 
        return err;
@@ -1148,9 +1154,35 @@ static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
        rtsx_pci_start_run(pcr);
 
-       if (!host->ddr_mode)
-               err = sd_tuning_rx(host, MMC_SEND_TUNING_BLOCK);
+       /* Set initial TX phase */
+       switch (mmc->ios.timing) {
+       case MMC_TIMING_UHS_SDR104:
+               err = sd_change_phase(host, SDR104_TX_PHASE(pcr), false);
+               break;
+
+       case MMC_TIMING_UHS_SDR50:
+               err = sd_change_phase(host, SDR50_TX_PHASE(pcr), false);
+               break;
+
+       case MMC_TIMING_UHS_DDR50:
+               err = sd_change_phase(host, DDR50_TX_PHASE(pcr), false);
+               break;
+
+       default:
+               err = 0;
+       }
 
+       if (err)
+               goto out;
+
+       /* Tuning RX phase */
+       if ((mmc->ios.timing == MMC_TIMING_UHS_SDR104) ||
+                       (mmc->ios.timing == MMC_TIMING_UHS_SDR50))
+               err = sd_tuning_rx(host, opcode);
+       else if (mmc->ios.timing == MMC_TIMING_UHS_DDR50)
+               err = sd_change_phase(host, DDR50_RX_PHASE(pcr), true);
+
+out:
        mutex_unlock(&pcr->pcr_mutex);
 
        return err;
diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h
new file mode 100644 (file)
index 0000000..2d2a0af
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Definitions for DA9063 MFD driver
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ *        Krystian Garbaciak <krystian.garbaciak@diasemi.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.
+ *
+ */
+
+#ifndef __MFD_DA9063_CORE_H__
+#define __MFD_DA9063_CORE_H__
+
+#include <linux/interrupt.h>
+#include <linux/mfd/da9063/registers.h>
+
+/* DA9063 modules */
+#define DA9063_DRVNAME_CORE            "da9063-core"
+#define DA9063_DRVNAME_REGULATORS      "da9063-regulators"
+#define DA9063_DRVNAME_LEDS            "da9063-leds"
+#define DA9063_DRVNAME_WATCHDOG                "da9063-watchdog"
+#define DA9063_DRVNAME_HWMON           "da9063-hwmon"
+#define DA9063_DRVNAME_ONKEY           "da9063-onkey"
+#define DA9063_DRVNAME_RTC             "da9063-rtc"
+#define DA9063_DRVNAME_VIBRATION       "da9063-vibration"
+
+enum da9063_models {
+       PMIC_DA9063 = 0x61,
+};
+
+/* Interrupts */
+enum da9063_irqs {
+       DA9063_IRQ_ONKEY = 0,
+       DA9063_IRQ_ALARM,
+       DA9063_IRQ_TICK,
+       DA9063_IRQ_ADC_RDY,
+       DA9063_IRQ_SEQ_RDY,
+       DA9063_IRQ_WAKE,
+       DA9063_IRQ_TEMP,
+       DA9063_IRQ_COMP_1V2,
+       DA9063_IRQ_LDO_LIM,
+       DA9063_IRQ_REG_UVOV,
+       DA9063_IRQ_VDD_MON,
+       DA9063_IRQ_WARN,
+       DA9063_IRQ_GPI0,
+       DA9063_IRQ_GPI1,
+       DA9063_IRQ_GPI2,
+       DA9063_IRQ_GPI3,
+       DA9063_IRQ_GPI4,
+       DA9063_IRQ_GPI5,
+       DA9063_IRQ_GPI6,
+       DA9063_IRQ_GPI7,
+       DA9063_IRQ_GPI8,
+       DA9063_IRQ_GPI9,
+       DA9063_IRQ_GPI10,
+       DA9063_IRQ_GPI11,
+       DA9063_IRQ_GPI12,
+       DA9063_IRQ_GPI13,
+       DA9063_IRQ_GPI14,
+       DA9063_IRQ_GPI15,
+};
+
+#define DA9063_IRQ_BASE_OFFSET 0
+#define DA9063_NUM_IRQ         (DA9063_IRQ_GPI15 + 1 - DA9063_IRQ_BASE_OFFSET)
+
+struct da9063 {
+       /* Device */
+       struct device   *dev;
+       unsigned short  model;
+       unsigned short  revision;
+       unsigned int    flags;
+
+       /* Control interface */
+       struct regmap   *regmap;
+
+       /* Interrupts */
+       int             chip_irq;
+       unsigned int    irq_base;
+       struct regmap_irq_chip_data *regmap_irq;
+};
+
+int da9063_device_init(struct da9063 *da9063, unsigned int irq);
+int da9063_irq_init(struct da9063 *da9063);
+
+void da9063_device_exit(struct da9063 *da9063);
+void da9063_irq_exit(struct da9063 *da9063);
+
+#endif /* __MFD_DA9063_CORE_H__ */
diff --git a/include/linux/mfd/da9063/pdata.h b/include/linux/mfd/da9063/pdata.h
new file mode 100644 (file)
index 0000000..95c8742
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Platform configuration options for DA9063
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.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.
+ *
+ */
+
+#ifndef __MFD_DA9063_PDATA_H__
+#define __MFD_DA9063_PDATA_H__
+
+#include <linux/regulator/machine.h>
+
+/*
+ * Regulator configuration
+ */
+/* DA9063 regulator IDs */
+enum {
+       /* BUCKs */
+       DA9063_ID_BCORE1,
+       DA9063_ID_BCORE2,
+       DA9063_ID_BPRO,
+       DA9063_ID_BMEM,
+       DA9063_ID_BIO,
+       DA9063_ID_BPERI,
+
+       /* BCORE1 and BCORE2 in merged mode */
+       DA9063_ID_BCORES_MERGED,
+       /* BMEM and BIO in merged mode */
+       DA9063_ID_BMEM_BIO_MERGED,
+       /* When two BUCKs are merged, they cannot be reused separately */
+
+       /* LDOs */
+       DA9063_ID_LDO1,
+       DA9063_ID_LDO2,
+       DA9063_ID_LDO3,
+       DA9063_ID_LDO4,
+       DA9063_ID_LDO5,
+       DA9063_ID_LDO6,
+       DA9063_ID_LDO7,
+       DA9063_ID_LDO8,
+       DA9063_ID_LDO9,
+       DA9063_ID_LDO10,
+       DA9063_ID_LDO11,
+};
+
+/* Regulators platform data */
+struct da9063_regulator_data {
+       int                             id;
+       struct regulator_init_data      *initdata;
+};
+
+struct da9063_regulators_pdata {
+       unsigned                        n_regulators;
+       struct da9063_regulator_data    *regulator_data;
+};
+
+
+/*
+ * RGB LED configuration
+ */
+/* LED IDs for flags in struct led_info. */
+enum {
+       DA9063_GPIO11_LED,
+       DA9063_GPIO14_LED,
+       DA9063_GPIO15_LED,
+
+       DA9063_LED_NUM
+};
+#define DA9063_LED_ID_MASK             0x3
+
+/* LED polarity for flags in struct led_info. */
+#define DA9063_LED_HIGH_LEVEL_ACTIVE   0x0
+#define DA9063_LED_LOW_LEVEL_ACTIVE    0x4
+
+
+/*
+ * General PMIC configuration
+ */
+/* HWMON ADC channels configuration */
+#define DA9063_FLG_FORCE_IN0_MANUAL_MODE       0x0010
+#define DA9063_FLG_FORCE_IN0_AUTO_MODE         0x0020
+#define DA9063_FLG_FORCE_IN1_MANUAL_MODE       0x0040
+#define DA9063_FLG_FORCE_IN1_AUTO_MODE         0x0080
+#define DA9063_FLG_FORCE_IN2_MANUAL_MODE       0x0100
+#define DA9063_FLG_FORCE_IN2_AUTO_MODE         0x0200
+#define DA9063_FLG_FORCE_IN3_MANUAL_MODE       0x0400
+#define DA9063_FLG_FORCE_IN3_AUTO_MODE         0x0800
+
+/* Disable register caching. */
+#define DA9063_FLG_NO_CACHE                    0x0008
+
+struct da9063;
+
+/* DA9063 platform data */
+struct da9063_pdata {
+       int                             (*init)(struct da9063 *da9063);
+       int                             irq_base;
+       unsigned                        flags;
+       struct da9063_regulators_pdata  *regulators_pdata;
+       struct led_platform_data        *leds_pdata;
+};
+
+#endif /* __MFD_DA9063_PDATA_H__ */
diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h
new file mode 100644 (file)
index 0000000..5834813
--- /dev/null
@@ -0,0 +1,1028 @@
+/*
+ * Registers definition for DA9063 modules
+ *
+ * Copyright 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Michal Hajduk <michal.hajduk@diasemi.com>
+ *        Krystian Garbaciak <krystian.garbaciak@diasemi.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.
+ *
+ */
+
+#ifndef _DA9063_REG_H
+#define        _DA9063_REG_H
+
+#define DA9063_I2C_PAGE_SEL_SHIFT      1
+
+#define        DA9063_EVENT_REG_NUM            4
+#define        DA9210_EVENT_REG_NUM            2
+#define        DA9063_EXT_EVENT_REG_NUM        (DA9063_EVENT_REG_NUM + \
+                                               DA9210_EVENT_REG_NUM)
+
+/* Page selection I2C or SPI always in the begining of any page. */
+/* Page 0 : I2C access 0x000 - 0x0FF   SPI access 0x000 - 0x07F */
+/* Page 1 :                            SPI access 0x080 - 0x0FF */
+/* Page 2 : I2C access 0x100 - 0x1FF   SPI access 0x100 - 0x17F */
+/* Page 3 :                            SPI access 0x180 - 0x1FF */
+#define        DA9063_REG_PAGE_CON             0x00
+
+/* System Control and Event Registers */
+#define        DA9063_REG_STATUS_A             0x01
+#define        DA9063_REG_STATUS_B             0x02
+#define        DA9063_REG_STATUS_C             0x03
+#define        DA9063_REG_STATUS_D             0x04
+#define        DA9063_REG_FAULT_LOG            0x05
+#define        DA9063_REG_EVENT_A              0x06
+#define        DA9063_REG_EVENT_B              0x07
+#define        DA9063_REG_EVENT_C              0x08
+#define        DA9063_REG_EVENT_D              0x09
+#define        DA9063_REG_IRQ_MASK_A           0x0A
+#define        DA9063_REG_IRQ_MASK_B           0x0B
+#define        DA9063_REG_IRQ_MASK_C           0x0C
+#define        DA9063_REG_IRQ_MASK_D           0x0D
+#define        DA9063_REG_CONTROL_A            0x0E
+#define        DA9063_REG_CONTROL_B            0x0F
+#define        DA9063_REG_CONTROL_C            0x10
+#define        DA9063_REG_CONTROL_D            0x11
+#define        DA9063_REG_CONTROL_E            0x12
+#define        DA9063_REG_CONTROL_F            0x13
+#define        DA9063_REG_PD_DIS               0x14
+
+/* GPIO Control Registers */
+#define        DA9063_REG_GPIO_0_1             0x15
+#define        DA9063_REG_GPIO_2_3             0x16
+#define        DA9063_REG_GPIO_4_5             0x17
+#define        DA9063_REG_GPIO_6_7             0x18
+#define        DA9063_REG_GPIO_8_9             0x19
+#define        DA9063_REG_GPIO_10_11           0x1A
+#define        DA9063_REG_GPIO_12_13           0x1B
+#define        DA9063_REG_GPIO_14_15           0x1C
+#define        DA9063_REG_GPIO_MODE_0_7        0x1D
+#define        DA9063_REG_GPIO_MODE_8_15       0x1E
+#define        DA9063_REG_GPIO_SWITCH_CONT     0x1F
+
+/* Regulator Control Registers */
+#define        DA9063_REG_BCORE2_CONT          0x20
+#define        DA9063_REG_BCORE1_CONT          0x21
+#define        DA9063_REG_BPRO_CONT            0x22
+#define        DA9063_REG_BMEM_CONT            0x23
+#define        DA9063_REG_BIO_CONT             0x24
+#define        DA9063_REG_BPERI_CONT           0x25
+#define        DA9063_REG_LDO1_CONT            0x26
+#define        DA9063_REG_LDO2_CONT            0x27
+#define        DA9063_REG_LDO3_CONT            0x28
+#define        DA9063_REG_LDO4_CONT            0x29
+#define        DA9063_REG_LDO5_CONT            0x2A
+#define        DA9063_REG_LDO6_CONT            0x2B
+#define        DA9063_REG_LDO7_CONT            0x2C
+#define        DA9063_REG_LDO8_CONT            0x2D
+#define        DA9063_REG_LDO9_CONT            0x2E
+#define        DA9063_REG_LDO10_CONT           0x2F
+#define        DA9063_REG_LDO11_CONT           0x30
+#define        DA9063_REG_VIB                  0x31
+#define        DA9063_REG_DVC_1                0x32
+#define        DA9063_REG_DVC_2                0x33
+
+/* GP-ADC Control Registers */
+#define        DA9063_REG_ADC_MAN              0x34
+#define        DA9063_REG_ADC_CONT             0x35
+#define        DA9063_REG_VSYS_MON             0x36
+#define        DA9063_REG_ADC_RES_L            0x37
+#define        DA9063_REG_ADC_RES_H            0x38
+#define        DA9063_REG_VSYS_RES             0x39
+#define        DA9063_REG_ADCIN1_RES           0x3A
+#define        DA9063_REG_ADCIN2_RES           0x3B
+#define        DA9063_REG_ADCIN3_RES           0x3C
+#define        DA9063_REG_MON1_RES             0x3D
+#define        DA9063_REG_MON2_RES             0x3E
+#define        DA9063_REG_MON3_RES             0x3F
+
+/* RTC Calendar and Alarm Registers */
+#define        DA9063_REG_COUNT_S              0x40
+#define        DA9063_REG_COUNT_MI             0x41
+#define        DA9063_REG_COUNT_H              0x42
+#define        DA9063_REG_COUNT_D              0x43
+#define        DA9063_REG_COUNT_MO             0x44
+#define        DA9063_REG_COUNT_Y              0x45
+#define        DA9063_REG_ALARM_MI             0x46
+#define        DA9063_REG_ALARM_H              0x47
+#define        DA9063_REG_ALARM_D              0x48
+#define        DA9063_REG_ALARM_MO             0x49
+#define        DA9063_REG_ALARM_Y              0x4A
+#define        DA9063_REG_SECOND_A             0x4B
+#define        DA9063_REG_SECOND_B             0x4C
+#define        DA9063_REG_SECOND_C             0x4D
+#define        DA9063_REG_SECOND_D             0x4E
+
+/* Sequencer Control Registers */
+#define        DA9063_REG_SEQ                  0x81
+#define        DA9063_REG_SEQ_TIMER            0x82
+#define        DA9063_REG_ID_2_1               0x83
+#define        DA9063_REG_ID_4_3               0x84
+#define        DA9063_REG_ID_6_5               0x85
+#define        DA9063_REG_ID_8_7               0x86
+#define        DA9063_REG_ID_10_9              0x87
+#define        DA9063_REG_ID_12_11             0x88
+#define        DA9063_REG_ID_14_13             0x89
+#define        DA9063_REG_ID_16_15             0x8A
+#define        DA9063_REG_ID_18_17             0x8B
+#define        DA9063_REG_ID_20_19             0x8C
+#define        DA9063_REG_ID_22_21             0x8D
+#define        DA9063_REG_ID_24_23             0x8E
+#define        DA9063_REG_ID_26_25             0x8F
+#define        DA9063_REG_ID_28_27             0x90
+#define        DA9063_REG_ID_30_29             0x91
+#define        DA9063_REG_ID_32_31             0x92
+#define        DA9063_REG_SEQ_A                0x95
+#define        DA9063_REG_SEQ_B                0x96
+#define        DA9063_REG_WAIT                 0x97
+#define        DA9063_REG_EN_32K               0x98
+#define        DA9063_REG_RESET                0x99
+
+/* Regulator Setting Registers */
+#define        DA9063_REG_BUCK_ILIM_A          0x9A
+#define        DA9063_REG_BUCK_ILIM_B          0x9B
+#define        DA9063_REG_BUCK_ILIM_C          0x9C
+#define        DA9063_REG_BCORE2_CFG           0x9D
+#define        DA9063_REG_BCORE1_CFG           0x9E
+#define        DA9063_REG_BPRO_CFG             0x9F
+#define        DA9063_REG_BIO_CFG              0xA0
+#define        DA9063_REG_BMEM_CFG             0xA1
+#define        DA9063_REG_BPERI_CFG            0xA2
+#define        DA9063_REG_VBCORE2_A            0xA3
+#define        DA9063_REG_VBCORE1_A            0xA4
+#define        DA9063_REG_VBPRO_A              0xA5
+#define        DA9063_REG_VBMEM_A              0xA6
+#define        DA9063_REG_VBIO_A               0xA7
+#define        DA9063_REG_VBPERI_A             0xA8
+#define        DA9063_REG_VLDO1_A              0xA9
+#define        DA9063_REG_VLDO2_A              0xAA
+#define        DA9063_REG_VLDO3_A              0xAB
+#define        DA9063_REG_VLDO4_A              0xAC
+#define        DA9063_REG_VLDO5_A              0xAD
+#define        DA9063_REG_VLDO6_A              0xAE
+#define        DA9063_REG_VLDO7_A              0xAF
+#define        DA9063_REG_VLDO8_A              0xB0
+#define        DA9063_REG_VLDO9_A              0xB1
+#define        DA9063_REG_VLDO10_A             0xB2
+#define        DA9063_REG_VLDO11_A             0xB3
+#define        DA9063_REG_VBCORE2_B            0xB4
+#define        DA9063_REG_VBCORE1_B            0xB5
+#define        DA9063_REG_VBPRO_B              0xB6
+#define        DA9063_REG_VBMEM_B              0xB7
+#define        DA9063_REG_VBIO_B               0xB8
+#define        DA9063_REG_VBPERI_B             0xB9
+#define        DA9063_REG_VLDO1_B              0xBA
+#define        DA9063_REG_VLDO2_B              0xBB
+#define        DA9063_REG_VLDO3_B              0xBC
+#define        DA9063_REG_VLDO4_B              0xBD
+#define        DA9063_REG_VLDO5_B              0xBE
+#define        DA9063_REG_VLDO6_B              0xBF
+#define        DA9063_REG_VLDO7_B              0xC0
+#define        DA9063_REG_VLDO8_B              0xC1
+#define        DA9063_REG_VLDO9_B              0xC2
+#define        DA9063_REG_VLDO10_B             0xC3
+#define        DA9063_REG_VLDO11_B             0xC4
+
+/* Backup Battery Charger Control Register */
+#define        DA9063_REG_BBAT_CONT            0xC5
+
+/* GPIO PWM (LED) */
+#define        DA9063_REG_GPO11_LED            0xC6
+#define        DA9063_REG_GPO14_LED            0xC7
+#define        DA9063_REG_GPO15_LED            0xC8
+
+/* GP-ADC Threshold Registers */
+#define        DA9063_REG_ADC_CFG              0xC9
+#define        DA9063_REG_AUTO1_HIGH           0xCA
+#define        DA9063_REG_AUTO1_LOW            0xCB
+#define        DA9063_REG_AUTO2_HIGH           0xCC
+#define        DA9063_REG_AUTO2_LOW            0xCD
+#define        DA9063_REG_AUTO3_HIGH           0xCE
+#define        DA9063_REG_AUTO3_LOW            0xCF
+
+/* DA9063 Configuration registers */
+/* OTP */
+#define        DA9063_REG_OPT_COUNT            0x101
+#define        DA9063_REG_OPT_ADDR             0x102
+#define        DA9063_REG_OPT_DATA             0x103
+
+/* Customer Trim and Configuration */
+#define        DA9063_REG_T_OFFSET             0x104
+#define        DA9063_REG_INTERFACE            0x105
+#define        DA9063_REG_CONFIG_A             0x106
+#define        DA9063_REG_CONFIG_B             0x107
+#define        DA9063_REG_CONFIG_C             0x108
+#define        DA9063_REG_CONFIG_D             0x109
+#define        DA9063_REG_CONFIG_E             0x10A
+#define        DA9063_REG_CONFIG_F             0x10B
+#define        DA9063_REG_CONFIG_G             0x10C
+#define        DA9063_REG_CONFIG_H             0x10D
+#define        DA9063_REG_CONFIG_I             0x10E
+#define        DA9063_REG_CONFIG_J             0x10F
+#define        DA9063_REG_CONFIG_K             0x110
+#define        DA9063_REG_CONFIG_L             0x111
+#define        DA9063_REG_MON_REG_1            0x112
+#define        DA9063_REG_MON_REG_2            0x113
+#define        DA9063_REG_MON_REG_3            0x114
+#define        DA9063_REG_MON_REG_4            0x115
+#define        DA9063_REG_MON_REG_5            0x116
+#define        DA9063_REG_MON_REG_6            0x117
+#define        DA9063_REG_TRIM_CLDR            0x118
+
+/* General Purpose Registers */
+#define        DA9063_REG_GP_ID_0              0x119
+#define        DA9063_REG_GP_ID_1              0x11A
+#define        DA9063_REG_GP_ID_2              0x11B
+#define        DA9063_REG_GP_ID_3              0x11C
+#define        DA9063_REG_GP_ID_4              0x11D
+#define        DA9063_REG_GP_ID_5              0x11E
+#define        DA9063_REG_GP_ID_6              0x11F
+#define        DA9063_REG_GP_ID_7              0x120
+#define        DA9063_REG_GP_ID_8              0x121
+#define        DA9063_REG_GP_ID_9              0x122
+#define        DA9063_REG_GP_ID_10             0x123
+#define        DA9063_REG_GP_ID_11             0x124
+#define        DA9063_REG_GP_ID_12             0x125
+#define        DA9063_REG_GP_ID_13             0x126
+#define        DA9063_REG_GP_ID_14             0x127
+#define        DA9063_REG_GP_ID_15             0x128
+#define        DA9063_REG_GP_ID_16             0x129
+#define        DA9063_REG_GP_ID_17             0x12A
+#define        DA9063_REG_GP_ID_18             0x12B
+#define        DA9063_REG_GP_ID_19             0x12C
+
+/* Chip ID and variant */
+#define        DA9063_REG_CHIP_ID              0x181
+#define        DA9063_REG_CHIP_VARIANT         0x182
+
+/*
+ * PMIC registers bits
+ */
+/* DA9063_REG_PAGE_CON (addr=0x00) */
+#define        DA9063_PEG_PAGE_SHIFT                   0
+#define        DA9063_REG_PAGE_MASK                    0x07
+#define                DA9063_REG_PAGE0                0x00
+#define                DA9063_REG_PAGE2                0x02
+#define        DA9063_PAGE_WRITE_MODE                  0x00
+#define        DA9063_REPEAT_WRITE_MODE                0x40
+#define        DA9063_PAGE_REVERT                      0x80
+
+/* DA9063_REG_STATUS_A (addr=0x01) */
+#define        DA9063_NONKEY                           0x01
+#define        DA9063_WAKE                             0x02
+#define        DA9063_DVC_BUSY                         0x04
+#define        DA9063_COMP_1V2                         0x08
+
+/* DA9063_REG_STATUS_B (addr=0x02) */
+#define        DA9063_GPI0                             0x01
+#define        DA9063_GPI1                             0x02
+#define        DA9063_GPI2                             0x04
+#define        DA9063_GPI3                             0x08
+#define        DA9063_GPI4                             0x10
+#define        DA9063_GPI5                             0x20
+#define        DA9063_GPI6                             0x40
+#define        DA9063_GPI7                             0x80
+
+/* DA9063_REG_STATUS_C (addr=0x03) */
+#define        DA9063_GPI8                             0x01
+#define        DA9063_GPI9                             0x02
+#define        DA9063_GPI10                            0x04
+#define        DA9063_GPI11                            0x08
+#define        DA9063_GPI12                            0x10
+#define        DA9063_GPI13                            0x20
+#define        DA9063_GPI14                            0x40
+#define        DA9063_GPI15                            0x80
+
+/* DA9063_REG_STATUS_D (addr=0x04) */
+#define        DA9063_LDO3_LIM                         0x08
+#define        DA9063_LDO4_LIM                         0x10
+#define        DA9063_LDO7_LIM                         0x20
+#define        DA9063_LDO8_LIM                         0x40
+#define        DA9063_LDO11_LIM                        0x80
+
+/* DA9063_REG_FAULT_LOG (addr=0x05) */
+#define        DA9063_TWD_ERROR                        0x01
+#define        DA9063_POR                              0x02
+#define        DA9063_VDD_FAULT                        0x04
+#define        DA9063_VDD_START                        0x08
+#define        DA9063_TEMP_CRIT                        0x10
+#define        DA9063_KEY_RESET                        0x20
+#define        DA9063_NSHUTDOWN                        0x40
+#define        DA9063_WAIT_SHUT                        0x80
+
+/* DA9063_REG_EVENT_A (addr=0x06) */
+#define        DA9063_E_NONKEY                         0x01
+#define        DA9063_E_ALARM                          0x02
+#define        DA9063_E_TICK                           0x04
+#define        DA9063_E_ADC_RDY                        0x08
+#define        DA9063_E_SEQ_RDY                        0x10
+#define        DA9063_EVENTS_B                         0x20
+#define        DA9063_EVENTS_C                         0x40
+#define        DA9063_EVENTS_D                         0x80
+
+/* DA9063_REG_EVENT_B (addr=0x07) */
+#define        DA9063_E_WAKE                           0x01
+#define        DA9063_E_TEMP                           0x02
+#define        DA9063_E_COMP_1V2                       0x04
+#define        DA9063_E_LDO_LIM                        0x08
+#define        DA9063_E_REG_UVOV                       0x10
+#define        DA9063_E_DVC_RDY                        0x20
+#define        DA9063_E_VDD_MON                        0x40
+#define        DA9063_E_VDD_WARN                       0x80
+
+/* DA9063_REG_EVENT_C (addr=0x08) */
+#define        DA9063_E_GPI0                           0x01
+#define        DA9063_E_GPI1                           0x02
+#define        DA9063_E_GPI2                           0x04
+#define        DA9063_E_GPI3                           0x08
+#define        DA9063_E_GPI4                           0x10
+#define        DA9063_E_GPI5                           0x20
+#define        DA9063_E_GPI6                           0x40
+#define        DA9063_E_GPI7                           0x80
+
+/* DA9063_REG_EVENT_D (addr=0x09) */
+#define        DA9063_E_GPI8                           0x01
+#define        DA9063_E_GPI9                           0x02
+#define        DA9063_E_GPI10                          0x04
+#define        DA9063_E_GPI11                          0x08
+#define        DA9063_E_GPI12                          0x10
+#define        DA9063_E_GPI13                          0x20
+#define        DA9063_E_GPI14                          0x40
+#define        DA9063_E_GPI15                          0x80
+
+/* DA9063_REG_IRQ_MASK_A (addr=0x0A) */
+#define        DA9063_M_ONKEY                          0x01
+#define        DA9063_M_ALARM                          0x02
+#define        DA9063_M_TICK                           0x04
+#define        DA9063_M_ADC_RDY                        0x08
+#define        DA9063_M_SEQ_RDY                        0x10
+
+/* DA9063_REG_IRQ_MASK_B (addr=0x0B) */
+#define        DA9063_M_WAKE                           0x01
+#define        DA9063_M_TEMP                           0x02
+#define        DA9063_M_COMP_1V2                       0x04
+#define        DA9063_M_LDO_LIM                        0x08
+#define        DA9063_M_UVOV                           0x10
+#define        DA9063_M_DVC_RDY                        0x20
+#define        DA9063_M_VDD_MON                        0x40
+#define        DA9063_M_VDD_WARN                       0x80
+
+/* DA9063_REG_IRQ_MASK_C (addr=0x0C) */
+#define        DA9063_M_GPI0                           0x01
+#define        DA9063_M_GPI1                           0x02
+#define        DA9063_M_GPI2                           0x04
+#define        DA9063_M_GPI3                           0x08
+#define        DA9063_M_GPI4                           0x10
+#define        DA9063_M_GPI5                           0x20
+#define        DA9063_M_GPI6                           0x40
+#define        DA9063_M_GPI7                           0x80
+
+/* DA9063_REG_IRQ_MASK_D (addr=0x0D) */
+#define        DA9063_M_GPI8                           0x01
+#define        DA9063_M_GPI9                           0x02
+#define        DA9063_M_GPI10                          0x04
+#define        DA9063_M_GPI11                          0x08
+#define        DA9063_M_GPI12                          0x10
+#define        DA9063_M_GPI13                          0x20
+#define        DA9063_M_GPI14                          0x40
+#define        DA9063_M_GPI15                          0x80
+
+/* DA9063_REG_CONTROL_A (addr=0x0E) */
+#define        DA9063_SYSTEM_EN                        0x01
+#define        DA9063_POWER_EN                         0x02
+#define        DA9063_POWER1_EN                        0x04
+#define        DA9063_STANDBY                          0x08
+#define        DA9063_M_SYSTEM_EN                      0x10
+#define        DA9063_M_POWER_EN                       0x20
+#define        DA9063_M_POWER1_EN                      0x40
+#define        DA9063_CP_EN                            0x80
+
+/* DA9063_REG_CONTROL_B (addr=0x0F) */
+#define        DA9063_CHG_SEL                          0x01
+#define        DA9063_WATCHDOG_PD                      0x02
+#define        DA9063_NRES_MODE                        0x08
+#define        DA9063_NONKEY_LOCK                      0x10
+
+/* DA9063_REG_CONTROL_C (addr=0x10) */
+#define        DA9063_DEBOUNCING_MASK                  0x07
+#define                DA9063_DEBOUNCING_OFF           0x0
+#define                DA9063_DEBOUNCING_0MS1          0x1
+#define                DA9063_DEBOUNCING_1MS           0x2
+#define                DA9063_DEBOUNCING_10MS24        0x3
+#define                DA9063_DEBOUNCING_51MS2         0x4
+#define                DA9063_DEBOUNCING_256MS         0x5
+#define                DA9063_DEBOUNCING_512MS         0x6
+#define                DA9063_DEBOUNCING_1024MS        0x7
+
+#define        DA9063_AUTO_BOOT                        0x08
+#define        DA9063_OTPREAD_EN                       0x10
+#define        DA9063_SLEW_RATE_MASK                   0x60
+#define                DA9063_SLEW_RATE_4US            0x00
+#define                DA9063_SLEW_RATE_3US            0x20
+#define                DA9063_SLEW_RATE_1US            0x40
+#define                DA9063_SLEW_RATE_0US5           0x60
+#define        DA9063_DEF_SUPPLY                       0x80
+
+/* DA9063_REG_CONTROL_D (addr=0x11) */
+#define        DA9063_TWDSCALE_MASK                    0x07
+#define        DA9063_BLINK_FRQ_MASK                   0x38
+#define                DA9063_BLINK_FRQ_OFF            0x00
+#define                DA9063_BLINK_FRQ_1S0            0x08
+#define                DA9063_BLINK_FRQ_2S0            0x10
+#define                DA9063_BLINK_FRQ_4S0            0x18
+#define                DA9063_BLINK_FRQ_0S18           0x20
+#define                DA9063_BLINK_FRQ_2S0_VDD        0x28
+#define                DA9063_BLINK_FRQ_4S0_VDD        0x30
+#define                DA9063_BLINK_FRQ_0S18_VDD       0x38
+
+#define        DA9063_BLINK_DUR_MASK                   0xC0
+#define                DA9063_BLINK_DUR_10MS           0x00
+#define                DA9063_BLINK_DUR_20MS           0x40
+#define                DA9063_BLINK_DUR_40MS           0x80
+#define                DA9063_BLINK_DUR_20MSDBL        0xC0
+
+/* DA9063_REG_CONTROL_E (addr=0x12) */
+#define        DA9063_RTC_MODE_PD                      0x01
+#define        DA9063_RTC_MODE_SD                      0x02
+#define        DA9063_RTC_EN                           0x04
+#define        DA9063_ECO_MODE                         0x08
+#define        DA9063_PM_FB1_PIN                       0x10
+#define        DA9063_PM_FB2_PIN                       0x20
+#define        DA9063_PM_FB3_PIN                       0x40
+#define        DA9063_V_LOCK                           0x80
+
+/* DA9063_REG_CONTROL_F (addr=0x13) */
+#define        DA9063_WATCHDOG                         0x01
+#define        DA9063_SHUTDOWN                         0x02
+#define        DA9063_WAKE_UP                          0x04
+
+/* DA9063_REG_PD_DIS (addr=0x14) */
+#define        DA9063_GPI_DIS                          0x01
+#define        DA9063_GPADC_PAUSE                      0x02
+#define        DA9063_PMIF_DIS                         0x04
+#define        DA9063_HS2WIRE_DIS                      0x08
+#define        DA9063_BBAT_DIS                         0x20
+#define        DA9063_OUT_32K_PAUSE                    0x40
+#define        DA9063_PMCONT_DIS                       0x80
+
+/* DA9063_REG_GPIO_0_1 (addr=0x15) */
+#define        DA9063_GPIO0_PIN_MASK                   0x03
+#define                DA9063_GPIO0_PIN_ADCIN1         0x00
+#define                DA9063_GPIO0_PIN_GPI            0x01
+#define                DA9063_GPIO0_PIN_GPO_OD         0x02
+#define                DA9063_GPIO0_PIN_GPO            0x03
+#define        DA9063_GPIO0_TYPE                       0x04
+#define                DA9063_GPIO0_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO0_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO0_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO0_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO0_NO_WAKEUP                  0x08
+#define        DA9063_GPIO1_PIN_MASK                   0x30
+#define                DA9063_GPIO1_PIN_ADCIN2_COMP    0x00
+#define                DA9063_GPIO1_PIN_GPI            0x10
+#define                DA9063_GPIO1_PIN_GPO_OD         0x20
+#define                DA9063_GPIO1_PIN_GPO            0x30
+#define        DA9063_GPIO1_TYPE                       0x40
+#define                DA9063_GPIO1_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO1_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO1_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO1_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO1_NO_WAKEUP                  0x80
+
+/* DA9063_REG_GPIO_2_3 (addr=0x16) */
+#define        DA9063_GPIO2_PIN_MASK                   0x03
+#define                DA9063_GPIO2_PIN_ADCIN3         0x00
+#define                DA9063_GPIO2_PIN_GPI            0x01
+#define                DA9063_GPIO2_PIN_GPO_PSS        0x02
+#define                DA9063_GPIO2_PIN_GPO            0x03
+#define        DA9063_GPIO2_TYPE                       0x04
+#define                DA9063_GPIO2_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO2_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO2_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO2_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO2_NO_WAKEUP                  0x08
+#define        DA9063_GPIO3_PIN_MASK                   0x30
+#define                DA9063_GPIO3_PIN_CORE_SW_G      0x00
+#define                DA9063_GPIO3_PIN_GPI            0x10
+#define                DA9063_GPIO3_PIN_GPO_OD         0x20
+#define                DA9063_GPIO3_PIN_GPO            0x30
+#define        DA9063_GPIO3_TYPE                       0x40
+#define                DA9063_GPIO3_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO3_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO3_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO3_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO3_NO_WAKEUP                  0x80
+
+/* DA9063_REG_GPIO_4_5 (addr=0x17) */
+#define        DA9063_GPIO4_PIN_MASK                   0x03
+#define                DA9063_GPIO4_PIN_CORE_SW_S      0x00
+#define                DA9063_GPIO4_PIN_GPI            0x01
+#define                DA9063_GPIO4_PIN_GPO_OD         0x02
+#define                DA9063_GPIO4_PIN_GPO            0x03
+#define        DA9063_GPIO4_TYPE                       0x04
+#define                DA9063_GPIO4_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO4_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO4_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO4_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO4_NO_WAKEUP                  0x08
+#define        DA9063_GPIO5_PIN_MASK                   0x30
+#define                DA9063_GPIO5_PIN_PERI_SW_G      0x00
+#define                DA9063_GPIO5_PIN_GPI            0x10
+#define                DA9063_GPIO5_PIN_GPO_OD         0x20
+#define                DA9063_GPIO5_PIN_GPO            0x30
+#define        DA9063_GPIO5_TYPE                       0x40
+#define                DA9063_GPIO5_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO5_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO5_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO5_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO5_NO_WAKEUP                  0x80
+
+/* DA9063_REG_GPIO_6_7 (addr=0x18) */
+#define        DA9063_GPIO6_PIN_MASK                   0x03
+#define                DA9063_GPIO6_PIN_PERI_SW_S      0x00
+#define                DA9063_GPIO6_PIN_GPI            0x01
+#define                DA9063_GPIO6_PIN_GPO_OD         0x02
+#define                DA9063_GPIO6_PIN_GPO            0x03
+#define        DA9063_GPIO6_TYPE                       0x04
+#define                DA9063_GPIO6_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO6_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO6_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO6_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO6_NO_WAKEUP                  0x08
+#define        DA9063_GPIO7_PIN_MASK                   0x30
+#define                DA9063_GPIO7_PIN_GPI            0x10
+#define                DA9063_GPIO7_PIN_GPO_PSS        0x20
+#define                DA9063_GPIO7_PIN_GPO            0x30
+#define        DA9063_GPIO7_TYPE                       0x40
+#define                DA9063_GPIO7_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO7_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO7_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO7_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO7_NO_WAKEUP                  0x80
+
+/* DA9063_REG_GPIO_8_9 (addr=0x19) */
+#define        DA9063_GPIO8_PIN_MASK                   0x03
+#define                DA9063_GPIO8_PIN_GPI_SYS_EN     0x00
+#define                DA9063_GPIO8_PIN_GPI            0x01
+#define                DA9063_GPIO8_PIN_GPO_PSS        0x02
+#define                DA9063_GPIO8_PIN_GPO            0x03
+#define        DA9063_GPIO8_TYPE                       0x04
+#define                DA9063_GPIO8_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO8_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO8_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO8_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO8_NO_WAKEUP                  0x08
+#define        DA9063_GPIO9_PIN_MASK                   0x30
+#define                DA9063_GPIO9_PIN_GPI_PWR_EN     0x00
+#define                DA9063_GPIO9_PIN_GPI            0x10
+#define                DA9063_GPIO9_PIN_GPO_PSS        0x20
+#define                DA9063_GPIO9_PIN_GPO            0x30
+#define        DA9063_GPIO9_TYPE                       0x40
+#define                DA9063_GPIO9_TYPE_GPI_ACT_LOW   0x00
+#define                DA9063_GPIO9_TYPE_GPO_VDD_IO1   0x00
+#define                DA9063_GPIO9_TYPE_GPI_ACT_HIGH  0x04
+#define                DA9063_GPIO9_TYPE_GPO_VDD_IO2   0x04
+#define        DA9063_GPIO9_NO_WAKEUP                  0x80
+
+/* DA9063_REG_GPIO_10_11 (addr=0x1A) */
+#define        DA9063_GPIO10_PIN_MASK                  0x03
+#define                DA9063_GPIO10_PIN_GPI_PWR1_EN   0x00
+#define                DA9063_GPIO10_PIN_GPI           0x01
+#define                DA9063_GPIO10_PIN_GPO_OD        0x02
+#define                DA9063_GPIO10_PIN_GPO           0x03
+#define        DA9063_GPIO10_TYPE                      0x04
+#define                DA9063_GPIO10_TYPE_GPI_ACT_LOW  0x00
+#define                DA9063_GPIO10_TYPE_GPO_VDD_IO1  0x00
+#define                DA9063_GPIO10_TYPE_GPI_ACT_HIGH 0x04
+#define                DA9063_GPIO10_TYPE_GPO_VDD_IO2  0x04
+#define        DA9063_GPIO10_NO_WAKEUP                 0x08
+#define        DA9063_GPIO11_PIN_MASK                  0x30
+#define                DA9063_GPIO11_PIN_GPO_OD        0x00
+#define                DA9063_GPIO11_PIN_GPI           0x10
+#define                DA9063_GPIO11_PIN_GPO_PSS       0x20
+#define                DA9063_GPIO11_PIN_GPO           0x30
+#define        DA9063_GPIO11_TYPE                      0x40
+#define                DA9063_GPIO11_TYPE_GPI_ACT_LOW  0x00
+#define                DA9063_GPIO11_TYPE_GPO_VDD_IO1  0x00
+#define                DA9063_GPIO11_TYPE_GPI_ACT_HIGH 0x04
+#define                DA9063_GPIO11_TYPE_GPO_VDD_IO2  0x04
+#define        DA9063_GPIO11_NO_WAKEUP                 0x80
+
+/* DA9063_REG_GPIO_12_13 (addr=0x1B) */
+#define        DA9063_GPIO12_PIN_MASK                  0x03
+#define                DA9063_GPIO12_PIN_NVDDFLT_OUT   0x00
+#define                DA9063_GPIO12_PIN_GPI           0x01
+#define                DA9063_GPIO12_PIN_VSYSMON_OUT   0x02
+#define                DA9063_GPIO12_PIN_GPO           0x03
+#define        DA9063_GPIO12_TYPE                      0x04
+#define                DA9063_GPIO12_TYPE_GPI_ACT_LOW  0x00
+#define                DA9063_GPIO12_TYPE_GPO_VDD_IO1  0x00
+#define                DA9063_GPIO12_TYPE_GPI_ACT_HIGH 0x04
+#define                DA9063_GPIO12_TYPE_GPO_VDD_IO2  0x04
+#define        DA9063_GPIO12_NO_WAKEUP                 0x08
+#define        DA9063_GPIO13_PIN_MASK                  0x30
+#define                DA9063_GPIO13_PIN_GPFB1_OUT     0x00
+#define                DA9063_GPIO13_PIN_GPI           0x10
+#define                DA9063_GPIO13_PIN_GPFB1_OUTOD   0x20
+#define                DA9063_GPIO13_PIN_GPO           0x30
+#define        DA9063_GPIO13_TYPE                      0x40
+#define                DA9063_GPIO13_TYPE_GPFB1_OUT    0x00
+#define                DA9063_GPIO13_TYPE_GPI          0x00
+#define                DA9063_GPIO13_TYPE_GPFB1_OUTOD  0x04
+#define                DA9063_GPIO13_TYPE_GPO          0x04
+#define        DA9063_GPIO13_NO_WAKEUP                 0x80
+
+/* DA9063_REG_GPIO_14_15 (addr=0x1C) */
+#define        DA9063_GPIO14_PIN_MASK                  0x03
+#define                DA9063_GPIO14_PIN_GPO_OD        0x00
+#define                DA9063_GPIO14_PIN_GPI           0x01
+#define                DA9063_GPIO14_PIN_HS2DATA       0x02
+#define                DA9063_GPIO14_PIN_GPO           0x03
+#define        DA9063_GPIO14_TYPE                      0x04
+#define                DA9063_GPIO14_TYPE_GPI_ACT_LOW  0x00
+#define                DA9063_GPIO14_TYPE_GPO_VDD_IO1  0x00
+#define                DA9063_GPIO14_TYPE_GPI_ACT_HIGH 0x04
+#define                DA9063_GPIO14_TYPE_GPO_VDD_IO2  0x04
+#define        DA9063_GPIO14_NO_WAKEUP                 0x08
+#define        DA9063_GPIO15_PIN_MASK                  0x30
+#define                DA9063_GPIO15_PIN_GPO_OD        0x00
+#define                DA9063_GPIO15_PIN_GPI           0x10
+#define                DA9063_GPIO15_PIN_GPO           0x30
+#define        DA9063_GPIO15_TYPE                      0x40
+#define                DA9063_GPIO15_TYPE_GPFB1_OUT    0x00
+#define                DA9063_GPIO15_TYPE_GPI          0x00
+#define                DA9063_GPIO15_TYPE_GPFB1_OUTOD  0x04
+#define                DA9063_GPIO15_TYPE_GPO          0x04
+#define        DA9063_GPIO15_NO_WAKEUP                 0x80
+
+/* DA9063_REG_GPIO_MODE_0_7 (addr=0x1D) */
+#define        DA9063_GPIO0_MODE                       0x01
+#define        DA9063_GPIO1_MODE                       0x02
+#define        DA9063_GPIO2_MODE                       0x04
+#define        DA9063_GPIO3_MODE                       0x08
+#define        DA9063_GPIO4_MODE                       0x10
+#define        DA9063_GPIO5_MODE                       0x20
+#define        DA9063_GPIO6_MODE                       0x40
+#define        DA9063_GPIO7_MODE                       0x80
+
+/* DA9063_REG_GPIO_MODE_8_15 (addr=0x1E) */
+#define        DA9063_GPIO8_MODE                       0x01
+#define        DA9063_GPIO9_MODE                       0x02
+#define        DA9063_GPIO10_MODE                      0x04
+#define        DA9063_GPIO11_MODE                      0x08
+#define                DA9063_GPIO11_MODE_LED_ACT_HIGH 0x00
+#define                DA9063_GPIO11_MODE_LED_ACT_LOW  0x08
+#define        DA9063_GPIO12_MODE                      0x10
+#define        DA9063_GPIO13_MODE                      0x20
+#define        DA9063_GPIO14_MODE                      0x40
+#define                DA9063_GPIO14_MODE_LED_ACT_HIGH 0x00
+#define                DA9063_GPIO14_MODE_LED_ACT_LOW  0x40
+#define        DA9063_GPIO15_MODE                      0x80
+#define                DA9063_GPIO15_MODE_LED_ACT_HIGH 0x00
+#define                DA9063_GPIO15_MODE_LED_ACT_LOW  0x80
+
+/* DA9063_REG_SWITCH_CONT (addr=0x1F) */
+#define        DA9063_CORE_SW_GPI_MASK                 0x03
+#define                DA9063_CORE_SW_GPI_OFF          0x00
+#define                DA9063_CORE_SW_GPI_GPIO1        0x01
+#define                DA9063_CORE_SW_GPI_GPIO2        0x02
+#define                DA9063_CORE_SW_GPI_GPIO13       0x03
+#define        DA9063_PERI_SW_GPI_MASK                 0x0C
+#define                DA9063_PERI_SW_GPI_OFF          0x00
+#define                DA9063_PERI_SW_GPI_GPIO1        0x04
+#define                DA9063_PERI_SW_GPI_GPIO2        0x08
+#define                DA9063_PERI_SW_GPI_GPIO13       0x0C
+#define        DA9063_SWITCH_SR_MASK                   0x30
+#define                DA9063_SWITCH_SR_1MV            0x00
+#define                DA9063_SWITCH_SR_5MV            0x10
+#define                DA9063_SWITCH_SR_10MV           0x20
+#define                DA9063_SWITCH_SR_50MV           0x30
+#define        DA9063_SWITCH_SR_DIS                    0x40
+#define        DA9063_CP_EN_MODE                       0x80
+
+/* DA9063_REGL_Bxxxx_CONT common bits (addr=0x20-0x25) */
+#define        DA9063_BUCK_EN                          0x01
+#define DA9063_BUCK_GPI_MASK                   0x06
+#define                DA9063_BUCK_GPI_OFF             0x00
+#define                DA9063_BUCK_GPI_GPIO1           0x02
+#define                DA9063_BUCK_GPI_GPIO2           0x04
+#define                DA9063_BUCK_GPI_GPIO13          0x06
+#define        DA9063_BUCK_CONF                        0x08
+#define        DA9063_VBUCK_GPI_MASK                   0x60
+#define                DA9063_VBUCK_GPI_OFF            0x00
+#define                DA9063_VBUCK_GPI_GPIO1          0x20
+#define                DA9063_VBUCK_GPI_GPIO2          0x40
+#define                DA9063_VBUCK_GPI_GPIO13         0x60
+
+/* DA9063_REG_BCORE1_CONT specific bits (addr=0x21) */
+#define        DA9063_CORE_SW_EN                       0x10
+#define        DA9063_CORE_SW_CONF                     0x80
+
+/* DA9063_REG_BPERI_CONT specific bits (addr=0x25) */
+#define        DA9063_PERI_SW_EN                       0x10
+#define        DA9063_PERI_SW_CONF                     0x80
+
+/* DA9063_REG_LDOx_CONT common bits (addr=0x26-0x30) */
+#define        DA9063_LDO_EN                           0x01
+#define DA9063_LDO_GPI_MASK                    0x06
+#define                DA9063_LDO_GPI_OFF              0x00
+#define                DA9063_LDO_GPI_GPIO1            0x02
+#define                DA9063_LDO_GPI_GPIO2            0x04
+#define                DA9063_LDO_GPI_GPIO13           0x06
+#define        DA9063_LDO_PD_DIS                       0x08
+#define        DA9063_VLDO_GPI_MASK                    0x60
+#define                DA9063_VLDO_GPI_OFF             0x00
+#define                DA9063_VLDO_GPI_GPIO1           0x20
+#define                DA9063_VLDO_GPI_GPIO2           0x40
+#define                DA9063_VLDO_GPI_GPIO13          0x60
+#define        DA9063_LDO_CONF                         0x80
+
+/* DA9063_REG_LDO5_CONT specific bits (addr=0x2A) */
+#define        DA9063_VLDO5_SEL                        0x10
+
+/* DA9063_REG_LDO6_CONT specific bits (addr=0x2B) */
+#define        DA9063_VLDO6_SEL                        0x10
+
+/* DA9063_REG_LDO7_CONT specific bits (addr=0x2C) */
+#define        DA9063_VLDO7_SEL                        0x10
+
+/* DA9063_REG_LDO8_CONT specific bits (addr=0x2D) */
+#define        DA9063_VLDO8_SEL                        0x10
+
+/* DA9063_REG_LDO9_CONT specific bits (addr=0x2E) */
+#define        DA9063_VLDO9_SEL                        0x10
+
+/* DA9063_REG_LDO10_CONT specific bits (addr=0x2F) */
+#define        DA9063_VLDO10_SEL                       0x10
+
+/* DA9063_REG_LDO11_CONT specific bits (addr=0x30) */
+#define        DA9063_VLDO11_SEL                       0x10
+
+/* DA9063_REG_VIB (addr=0x31) */
+#define DA9063_VIB_SET_MASK                    0x3F
+#define                DA9063_VIB_SET_OFF              0
+#define                DA9063_VIB_SET_MAX              0x3F
+
+/* DA9063_REG_DVC_1 (addr=0x32) */
+#define        DA9063_VBCORE1_SEL                      0x01
+#define        DA9063_VBCORE2_SEL                      0x02
+#define        DA9063_VBPRO_SEL                        0x04
+#define        DA9063_VBMEM_SEL                        0x08
+#define        DA9063_VBPERI_SEL                       0x10
+#define        DA9063_VLDO1_SEL                        0x20
+#define        DA9063_VLDO2_SEL                        0x40
+#define        DA9063_VLDO3_SEL                        0x80
+
+/* DA9063_REG_DVC_2 (addr=0x33) */
+#define        DA9063_VBIO_SEL                         0x01
+#define        DA9063_VLDO4_SEL                        0x80
+
+/* DA9063_REG_ADC_MAN (addr=0x34) */
+#define        DA9063_ADC_MUX_MASK                     0x0F
+#define                DA9063_ADC_MUX_VSYS             0x00
+#define                DA9063_ADC_MUX_ADCIN1           0x01
+#define                DA9063_ADC_MUX_ADCIN2           0x02
+#define                DA9063_ADC_MUX_ADCIN3           0x03
+#define                DA9063_ADC_MUX_T_SENSE          0x04
+#define                DA9063_ADC_MUX_VBBAT            0x05
+#define                DA9063_ADC_MUX_LDO_G1           0x08
+#define                DA9063_ADC_MUX_LDO_G2           0x09
+#define                DA9063_ADC_MUX_LDO_G3           0x0A
+#define        DA9063_ADC_MAN                          0x10
+#define        DA9063_ADC_MODE                         0x20
+
+/* DA9063_REG_ADC_CONT (addr=0x35) */
+#define        DA9063_ADC_AUTO_VSYS_EN                 0x01
+#define        DA9063_ADC_AUTO_AD1_EN                  0x02
+#define        DA9063_ADC_AUTO_AD2_EN                  0x04
+#define        DA9063_ADC_AUTO_AD3_EN                  0x08
+#define        DA9063_ADC_AD1_ISRC_EN                  0x10
+#define        DA9063_ADC_AD2_ISRC_EN                  0x20
+#define        DA9063_ADC_AD3_ISRC_EN                  0x40
+#define        DA9063_COMP1V2_EN                       0x80
+
+/* DA9063_REG_VSYS_MON (addr=0x36) */
+#define        DA9063_VSYS_VAL_MASK                    0xFF
+#define        DA9063_VSYS_VAL_BASE                    0x00
+
+/* DA9063_REG_ADC_RES_L (addr=0x37) */
+#define        DA9063_ADC_RES_L_BITS                   2
+#define        DA9063_ADC_RES_L_MASK                   0xC0
+
+/* DA9063_REG_ADC_RES_H (addr=0x38) */
+#define        DA9063_ADC_RES_M_BITS                   8
+#define        DA9063_ADC_RES_M_MASK                   0xFF
+
+/* DA9063_REG_(xxx_RES/ADC_RES_H) (addr=0x39-0x3F) */
+#define        DA9063_ADC_VAL_MASK                     0xFF
+
+/* DA9063_REG_COUNT_S (addr=0x40) */
+#define DA9063_RTC_READ                                0x80
+#define DA9063_COUNT_SEC_MASK                  0x3F
+
+/* DA9063_REG_COUNT_MI (addr=0x41) */
+#define DA9063_COUNT_MIN_MASK                  0x3F
+
+/* DA9063_REG_COUNT_H (addr=0x42) */
+#define DA9063_COUNT_HOUR_MASK                 0x1F
+
+/* DA9063_REG_COUNT_D (addr=0x43) */
+#define DA9063_COUNT_DAY_MASK                  0x1F
+
+/* DA9063_REG_COUNT_MO (addr=0x44) */
+#define DA9063_COUNT_MONTH_MASK                        0x0F
+
+/* DA9063_REG_COUNT_Y (addr=0x45) */
+#define DA9063_COUNT_YEAR_MASK                 0x3F
+#define DA9063_MONITOR                         0x40
+
+/* DA9063_REG_ALARM_MI (addr=0x46) */
+#define DA9063_ALARM_STATUS_ALARM              0x80
+#define DA9063_ALARM_STATUS_TICK               0x40
+#define DA9063_ALARM_MIN_MASK                  0x3F
+
+/* DA9063_REG_ALARM_H (addr=0x47) */
+#define DA9063_ALARM_HOUR_MASK                 0x1F
+
+/* DA9063_REG_ALARM_D (addr=0x48) */
+#define DA9063_ALARM_DAY_MASK                  0x1F
+
+/* DA9063_REG_ALARM_MO (addr=0x49) */
+#define DA9063_TICK_WAKE                       0x20
+#define DA9063_TICK_TYPE                       0x10
+#define                DA9063_TICK_TYPE_SEC            0x00
+#define                DA9063_TICK_TYPE_MIN            0x10
+#define DA9063_ALARM_MONTH_MASK                        0x0F
+
+/* DA9063_REG_ALARM_Y (addr=0x4A) */
+#define DA9063_TICK_ON                         0x80
+#define DA9063_ALARM_ON                                0x40
+#define DA9063_ALARM_YEAR_MASK                 0x3F
+
+/* DA9063_REG_WAIT (addr=0x97)*/
+#define        DA9063_REG_WAIT_TIME_MASK               0xF
+#define        DA9063_WAIT_TIME_0_US                   0x0
+#define        DA9063_WAIT_TIME_512_US                 0x1
+#define        DA9063_WAIT_TIME_1_MS                   0x2
+#define        DA9063_WAIT_TIME_2_MS                   0x3
+#define        DA9063_WAIT_TIME_4_1_MS                 0x4
+#define        DA9063_WAIT_TIME_8_2_MS                 0x5
+#define        DA9063_WAIT_TIME_16_4_MS                0x6
+#define        DA9063_WAIT_TIME_32_8_MS                0x7
+#define        DA9063_WAIT_TIME_65_5_MS                0x8
+#define        DA9063_WAIT_TIME_128_MS                 0x9
+#define        DA9063_WAIT_TIME_256_MS                 0xA
+#define        DA9063_WAIT_TIME_512_MS                 0xB
+#define        DA9063_WAIT_TIME_1_S                    0xC
+#define        DA9063_WAIT_TIME_2_1_S                  0xD
+
+/* DA9063_REG_EN_32K  (addr=0x98)*/
+#define        DA9063_STABILIZ_TIME_MASK               0x7
+#define        DA9063_CRYSTAL                          0x08
+#define        DA9063_DELAY_MODE                       0x10
+#define        DA9063_OUT_CLOCK                        0x20
+#define        DA9063_RTC_CLOCK                        0x40
+#define        DA9063_OUT_32K_EN                       0x80
+
+/* DA9063_REG_CHIP_VARIANT */
+#define        DA9063_CHIP_VARIANT_SHIFT               4
+
+/* DA9063_REG_BUCK_ILIM_A (addr=0x9A) */
+#define DA9063_BIO_ILIM_MASK                   0x0F
+#define DA9063_BMEM_ILIM_MASK                  0xF0
+
+/* DA9063_REG_BUCK_ILIM_B (addr=0x9B) */
+#define DA9063_BPRO_ILIM_MASK                  0x0F
+#define DA9063_BPERI_ILIM_MASK                 0xF0
+
+/* DA9063_REG_BUCK_ILIM_C (addr=0x9C) */
+#define DA9063_BCORE1_ILIM_MASK                        0x0F
+#define DA9063_BCORE2_ILIM_MASK                        0xF0
+
+/* DA9063_REG_Bxxxx_CFG common bits (addr=0x9D-0xA2) */
+#define DA9063_BUCK_FB_MASK                    0x07
+#define DA9063_BUCK_PD_DIS_SHIFT               5
+#define DA9063_BUCK_MODE_MASK                  0xC0
+#define                DA9063_BUCK_MODE_MANUAL         0x00
+#define                DA9063_BUCK_MODE_SLEEP          0x40
+#define                DA9063_BUCK_MODE_SYNC           0x80
+#define                DA9063_BUCK_MODE_AUTO           0xC0
+
+/* DA9063_REG_BPRO_CFG (addr=0x9F) */
+#define        DA9063_BPRO_VTTR_EN                     0x08
+#define        DA9063_BPRO_VTT_EN                      0x10
+
+/* DA9063_REG_VBxxxx_A/B (addr=0xA3-0xA8, 0xB4-0xB9) */
+#define DA9063_VBUCK_MASK                      0x7F
+#define DA9063_VBUCK_BIAS                      0
+#define DA9063_BUCK_SL                         0x80
+
+/* DA9063_REG_VLDOx_A/B (addr=0xA9-0x3, 0xBA-0xC4) */
+#define DA9063_LDO_SL                          0x80
+
+/* DA9063_REG_VLDO1_A/B (addr=0xA9, 0xBA) */
+#define DA9063_VLDO1_MASK                      0x3F
+#define DA9063_VLDO1_BIAS                      0
+
+/* DA9063_REG_VLDO2_A/B (addr=0xAA, 0xBB) */
+#define DA9063_VLDO2_MASK                      0x3F
+#define DA9063_VLDO2_BIAS                      0
+
+/* DA9063_REG_VLDO3_A/B (addr=0xAB, 0xBC) */
+#define DA9063_VLDO3_MASK                      0x7F
+#define DA9063_VLDO3_BIAS                      0
+
+/* DA9063_REG_VLDO4_A/B (addr=0xAC, 0xBD) */
+#define DA9063_VLDO4_MASK                      0x7F
+#define DA9063_VLDO4_BIAS                      0
+
+/* DA9063_REG_VLDO5_A/B (addr=0xAD, 0xBE) */
+#define DA9063_VLDO5_MASK                      0x3F
+#define DA9063_VLDO5_BIAS                      2
+
+/* DA9063_REG_VLDO6_A/B (addr=0xAE, 0xBF) */
+#define DA9063_VLDO6_MASK                      0x3F
+#define DA9063_VLDO6_BIAS                      2
+
+/* DA9063_REG_VLDO7_A/B (addr=0xAF, 0xC0) */
+#define DA9063_VLDO7_MASK                      0x3F
+#define DA9063_VLDO7_BIAS                      2
+
+/* DA9063_REG_VLDO8_A/B (addr=0xB0, 0xC1) */
+#define DA9063_VLDO8_MASK                      0x3F
+#define DA9063_VLDO8_BIAS                      2
+
+/* DA9063_REG_VLDO9_A/B (addr=0xB1, 0xC2) */
+#define DA9063_VLDO9_MASK                      0x3F
+#define DA9063_VLDO9_BIAS                      3
+
+/* DA9063_REG_VLDO10_A/B (addr=0xB2, 0xC3) */
+#define DA9063_VLDO10_MASK                     0x3F
+#define DA9063_VLDO10_BIAS                     2
+
+/* DA9063_REG_VLDO11_A/B (addr=0xB3, 0xC4) */
+#define DA9063_VLDO11_MASK                     0x3F
+#define DA9063_VLDO11_BIAS                     2
+
+/* DA9063_REG_GPO11_LED (addr=0xC6) */
+/* DA9063_REG_GPO14_LED (addr=0xC7) */
+/* DA9063_REG_GPO15_LED (addr=0xC8) */
+#define DA9063_GPIO_DIM                                0x80
+#define DA9063_GPIO_PWM_MASK                   0x7F
+
+/* DA9063_REG_CONFIG_H (addr=0x10D) */
+#define DA9063_PWM_CLK_MASK                    0x01
+#define                DA9063_PWM_CLK_PWM2MHZ          0x00
+#define                DA9063_PWM_CLK_PWM1MHZ          0x01
+#define DA9063_LDO8_MODE_MASK                  0x02
+#define                DA9063_LDO8_MODE_LDO            0
+#define                DA9063_LDO8_MODE_VIBR           0x02
+#define DA9063_MERGE_SENSE_MASK                        0x04
+#define                DA9063_MERGE_SENSE_GP_FB2       0x00
+#define                DA9063_MERGE_SENSE_GPIO4        0x04
+#define DA9063_BCORE_MERGE                     0x08
+#define DA9063_BPRO_OD                         0x10
+#define DA9063_BCORE2_OD                       0x20
+#define DA9063_BCORE1_OD                       0x40
+#define DA9063_BUCK_MERGE                      0x80
+
+/* DA9063_REG_CONFIG_I (addr=0x10E) */
+#define DA9063_NONKEY_PIN_MASK                 0x03
+#define                DA9063_NONKEY_PIN_PORT          0x00
+#define                DA9063_NONKEY_PIN_SWDOWN        0x01
+#define                DA9063_NONKEY_PIN_AUTODOWN      0x02
+#define                DA9063_NONKEY_PIN_AUTOFLPRT     0x03
+
+/* DA9063_REG_MON_REG_5 (addr=0x116) */
+#define DA9063_MON_A8_IDX_MASK                 0x07
+#define                DA9063_MON_A8_IDX_NONE          0x00
+#define                DA9063_MON_A8_IDX_BCORE1        0x01
+#define                DA9063_MON_A8_IDX_BCORE2        0x02
+#define                DA9063_MON_A8_IDX_BPRO          0x03
+#define                DA9063_MON_A8_IDX_LDO3          0x04
+#define                DA9063_MON_A8_IDX_LDO4          0x05
+#define                DA9063_MON_A8_IDX_LDO11         0x06
+#define DA9063_MON_A9_IDX_MASK                 0x70
+#define                DA9063_MON_A9_IDX_NONE          0x00
+#define                DA9063_MON_A9_IDX_BIO           0x01
+#define                DA9063_MON_A9_IDX_BMEM          0x02
+#define                DA9063_MON_A9_IDX_BPERI         0x03
+#define                DA9063_MON_A9_IDX_LDO1          0x04
+#define                DA9063_MON_A9_IDX_LDO2          0x05
+#define                DA9063_MON_A9_IDX_LDO5          0x06
+
+/* DA9063_REG_MON_REG_6 (addr=0x117) */
+#define DA9063_MON_A10_IDX_MASK                        0x07
+#define                DA9063_MON_A10_IDX_NONE         0x00
+#define                DA9063_MON_A10_IDX_LDO6         0x01
+#define                DA9063_MON_A10_IDX_LDO7         0x02
+#define                DA9063_MON_A10_IDX_LDO8         0x03
+#define                DA9063_MON_A10_IDX_LDO9         0x04
+#define                DA9063_MON_A10_IDX_LDO10        0x05
+
+#endif /* _DA9063_REG_H */
index 13a1ee95a2334bdda6fed40c3e8dbf36a9784012..5166935ce66df46748e1b173ad8cfc2b6379b011 100644 (file)
@@ -30,6 +30,8 @@
 
 #include <mach/hardware.h>
 
+struct regmap;
+
 /*
  * Register values.
  */
@@ -113,6 +115,7 @@ struct davinci_vc {
 
        /* Memory resources */
        void __iomem *base;
+       struct regmap *regmap;
 
        /* MFD cells */
        struct mfd_cell cells[DAVINCI_VC_CELLS];
index a9e8bd157673a475ebfb5d78e81f0b8d6d621ed6..f682953043ba9c81686ef35293d0274d402b5326 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef MCP_H
 #define MCP_H
 
+#include <linux/device.h>
+
 struct mcp_ops;
 
 struct mcp {
index 37e48c9577914b6de786ce20b9009c5f2a998f46..9974e387e483001746e680e8a1129680f8af45f3 100644 (file)
@@ -184,6 +184,50 @@ enum palmas_regulators {
        PALMAS_NUM_REGS,
 };
 
+/* External controll signal name */
+enum {
+       PALMAS_EXT_CONTROL_ENABLE1      = 0x1,
+       PALMAS_EXT_CONTROL_ENABLE2      = 0x2,
+       PALMAS_EXT_CONTROL_NSLEEP       = 0x4,
+};
+
+/*
+ * Palmas device resources can be controlled externally for
+ * enabling/disabling it rather than register write through i2c.
+ * Add the external controlled requestor ID for different resources.
+ */
+enum palmas_external_requestor_id {
+       PALMAS_EXTERNAL_REQSTR_ID_REGEN1,
+       PALMAS_EXTERNAL_REQSTR_ID_REGEN2,
+       PALMAS_EXTERNAL_REQSTR_ID_SYSEN1,
+       PALMAS_EXTERNAL_REQSTR_ID_SYSEN2,
+       PALMAS_EXTERNAL_REQSTR_ID_CLK32KG,
+       PALMAS_EXTERNAL_REQSTR_ID_CLK32KGAUDIO,
+       PALMAS_EXTERNAL_REQSTR_ID_REGEN3,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS12,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS3,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS45,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS6,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS7,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS8,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS9,
+       PALMAS_EXTERNAL_REQSTR_ID_SMPS10,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO1,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO2,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO3,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO4,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO5,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO6,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO7,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO8,
+       PALMAS_EXTERNAL_REQSTR_ID_LDO9,
+       PALMAS_EXTERNAL_REQSTR_ID_LDOLN,
+       PALMAS_EXTERNAL_REQSTR_ID_LDOUSB,
+
+       /* Last entry */
+       PALMAS_EXTERNAL_REQSTR_ID_MAX,
+};
+
 struct palmas_pmic_platform_data {
        /* An array of pointers to regulator init data indexed by regulator
         * ID
@@ -259,6 +303,7 @@ struct palmas_platform_data {
         */
        int mux_from_pdata;
        u8 pad1, pad2;
+       bool pm_off;
 
        struct palmas_pmic_platform_data *pmic_pdata;
        struct palmas_gpadc_platform_data *gpadc_pdata;
@@ -2878,4 +2923,9 @@ static inline int palmas_irq_get_virq(struct palmas *palmas, int irq)
        return regmap_irq_get_virq(palmas->irq_data, irq);
 }
 
+
+int palmas_ext_control_req_config(struct palmas *palmas,
+       enum palmas_external_requestor_id ext_control_req_id,
+       int ext_ctrl, bool enable);
+
 #endif /*  __LINUX_MFD_PALMAS_H */
index 2b13970596f53732cda07a6fd3b270cc9e933e5b..443176ee1ab04e1f9d2788b51d700eb2a913610c 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek driver-based card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #ifndef __RTSX_COMMON_H
index 7a9f7089435dcb21d50c7ff902c14f6c76bd3317..d1382dfbeff022b5f91dfcf6789ece80874eea5b 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for Realtek PCI-Express card reader
  *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  *
  * 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
@@ -17,7 +17,6 @@
  *
  * Author:
  *   Wei WANG <wei_wang@realsil.com.cn>
- *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
  */
 
 #ifndef __RTSX_PCI_H
@@ -25,8 +24,7 @@
 
 #include <linux/sched.h>
 #include <linux/pci.h>
-
-#include "rtsx_common.h"
+#include <linux/mfd/rtsx_common.h>
 
 #define MAX_RW_REG_CNT                 1024
 
 #define CARD_SHARE_BAROSSA_SD          0x01
 #define CARD_SHARE_BAROSSA_MS          0x02
 
+/* CARD_DRIVE_SEL */
+#define MS_DRIVE_8mA                   (0x01 << 6)
+#define MMC_DRIVE_8mA                  (0x01 << 4)
+#define XD_DRIVE_8mA                   (0x01 << 2)
+#define GPIO_DRIVE_8mA                 0x01
+#define RTS5209_CARD_DRIVE_DEFAULT     (MS_DRIVE_8mA | MMC_DRIVE_8mA |\
+                                               XD_DRIVE_8mA | GPIO_DRIVE_8mA)
+#define RTL8411_CARD_DRIVE_DEFAULT     (MS_DRIVE_8mA | MMC_DRIVE_8mA |\
+                                               XD_DRIVE_8mA)
+#define RTSX_CARD_DRIVE_DEFAULT                (MS_DRIVE_8mA | GPIO_DRIVE_8mA)
+
 /* SD30_DRIVE_SEL */
 #define DRIVER_TYPE_A                  0x05
 #define DRIVER_TYPE_B                  0x03
 #define DRIVER_TYPE_C                  0x02
 #define DRIVER_TYPE_D                  0x01
+#define CFG_DRIVER_TYPE_A              0x02
+#define CFG_DRIVER_TYPE_B              0x03
+#define CFG_DRIVER_TYPE_C              0x01
+#define CFG_DRIVER_TYPE_D              0x00
 
 /* FPDCTL */
 #define SSC_POWER_DOWN                 0x01
 #define SAMPLE_VAR_CLK0                        (0x01 << 4)
 #define SAMPLE_VAR_CLK1                        (0x02 << 4)
 
+/* HOST_SLEEP_STATE */
+#define HOST_ENTER_S1                  1
+#define HOST_ENTER_S3                  2
+
 #define MS_CFG                         0xFD40
 #define MS_TPC                         0xFD41
 #define MS_TRANS_CFG                   0xFD42
 #define PME_FORCE_CTL                  0xFE56
 #define ASPM_FORCE_CTL                 0xFE57
 #define PM_CLK_FORCE_CTL               0xFE58
+#define FUNC_FORCE_CTL                 0xFE59
 #define PERST_GLITCH_WIDTH             0xFE5C
 #define CHANGE_LINK_STATE              0xFE5B
 #define RESET_LOAD_REG                 0xFE5E
 
 #define DUMMY_REG_RESET_0              0xFE90
 
+#define AUTOLOAD_CFG_BASE              0xFF00
+
+#define PM_CTRL1                       0xFF44
+#define PM_CTRL2                       0xFF45
+#define PM_CTRL3                       0xFF46
+#define PM_CTRL4                       0xFF47
+
 /* Memory mapping */
 #define SRAM_BASE                      0xE600
 #define RBUF_BASE                      0xF400
 #define PHY_FLD4                       0x1E
 #define PHY_DUM_REG                    0x1F
 
+#define LCTLR                          0x80
+#define PCR_SETTING_REG1               0x724
+#define PCR_SETTING_REG2               0x814
+#define PCR_SETTING_REG3               0x747
+
 #define rtsx_pci_init_cmd(pcr)         ((pcr)->ci = 0)
 
 struct rtsx_pcr;
@@ -747,6 +777,8 @@ struct pcr_ops {
                                                u8 voltage);
        unsigned int    (*cd_deglitch)(struct rtsx_pcr *pcr);
        int             (*conv_clk_and_div_n)(int clk, int dir);
+       void            (*fetch_vendor_settings)(struct rtsx_pcr *pcr);
+       void            (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state);
 };
 
 enum PDEV_STAT  {PDEV_STAT_IDLE, PDEV_STAT_RUN};
@@ -788,7 +820,6 @@ struct rtsx_pcr {
        struct completion               *finish_me;
 
        unsigned int                    cur_clock;
-       bool                            ms_pmos;
        bool                            remove_pci;
        bool                            msi_en;
 
@@ -806,6 +837,19 @@ struct rtsx_pcr {
 #define IC_VER_D                       3
        u8                              ic_version;
 
+       u8                              sd30_drive_sel_1v8;
+       u8                              sd30_drive_sel_3v3;
+       u8                              card_drive_sel;
+#define ASPM_L1_EN                     0x02
+       u8                              aspm_en;
+
+#define PCR_MS_PMOS                    (1 << 0)
+#define PCR_REVERSE_SOCKET             (1 << 1)
+       u32                             flags;
+
+       u32                             tx_initial_phase;
+       u32                             rx_initial_phase;
+
        const u32                       *sd_pull_ctl_enable_tbl;
        const u32                       *sd_pull_ctl_disable_tbl;
        const u32                       *ms_pull_ctl_enable_tbl;
@@ -822,6 +866,18 @@ struct rtsx_pcr {
 #define PCI_VID(pcr)                   ((pcr)->pci->vendor)
 #define PCI_PID(pcr)                   ((pcr)->pci->device)
 
+#define SDR104_PHASE(val)              ((val) & 0xFF)
+#define SDR50_PHASE(val)               (((val) >> 8) & 0xFF)
+#define DDR50_PHASE(val)               (((val) >> 16) & 0xFF)
+#define SDR104_TX_PHASE(pcr)           SDR104_PHASE((pcr)->tx_initial_phase)
+#define SDR50_TX_PHASE(pcr)            SDR50_PHASE((pcr)->tx_initial_phase)
+#define DDR50_TX_PHASE(pcr)            DDR50_PHASE((pcr)->tx_initial_phase)
+#define SDR104_RX_PHASE(pcr)           SDR104_PHASE((pcr)->rx_initial_phase)
+#define SDR50_RX_PHASE(pcr)            SDR50_PHASE((pcr)->rx_initial_phase)
+#define DDR50_RX_PHASE(pcr)            DDR50_PHASE((pcr)->rx_initial_phase)
+#define SET_CLOCK_PHASE(sdr104, sdr50, ddr50)  \
+                               (((ddr50) << 16) | ((sdr50) << 8) | (sdr104))
+
 void rtsx_pci_start_run(struct rtsx_pcr *pcr);
 int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data);
 int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data);
index d0d52ea6007439c18c3cf17bb71961187da72026..b3ddf98dec3734ea7c4fc483a2efacc8cd7dfcad 100644 (file)
@@ -167,11 +167,8 @@ enum s2mps11_regulators {
        S2MPS11_BUCK8,
        S2MPS11_BUCK9,
        S2MPS11_BUCK10,
-       S2MPS11_AP_EN32KHZ,
-       S2MPS11_CP_EN32KHZ,
-       S2MPS11_BT_EN32KHZ,
 
-       S2MPS11_REG_MAX,
+       S2MPS11_REGULATOR_MAX,
 };
 
 #define S2MPS11_BUCK_MIN1      600000
@@ -203,6 +200,5 @@ enum s2mps11_regulators {
 #define S2MPS11_BUCK4_RAMP_EN_SHIFT    1
 #define S2MPS11_BUCK6_RAMP_EN_SHIFT    0
 #define S2MPS11_PMIC_EN_SHIFT  6
-#define S2MPS11_REGULATOR_MAX (S2MPS11_REG_MAX - 3)
 
 #endif /*  __LINUX_MFD_S2MPS11_H */
index db1791bb997ae495d65637e506b6f13ab4945b6d..25f2c611ab013db8e3a4135a00c129b3d556e7d5 100644 (file)
 #define SEQ_STATUS BIT(5)
 
 #define ADC_CLK                        3000000
-#define        MAX_CLK_DIV             7
 #define TOTAL_STEPS            16
 #define TOTAL_CHANNELS         8
 
index 7e7fbce7a30874ddca4c06bc37359042902c983b..81f639bc1ae671c3e8d6671c4a16004977387704 100644 (file)
 
 #define TWL6040_GPO_MAX        3
 
+/* TODO: All platform data struct can be removed */
 struct twl6040_codec_data {
        u16 hs_left_step;
        u16 hs_right_step;
@@ -229,7 +230,6 @@ struct twl6040 {
        int audpwron;
        int power_count;
        int rev;
-       u8 vibra_ctrl_cache[2];
 
        /* PLL configuration */
        int pll;
index 28af417563609b50bbff851bea7e0fb4692c966d..88f90cbf8e6a0a2588aea4e023a5594cb19528a4 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef UCB1200_H
 #define UCB1200_H
 
+#include <linux/device.h>
 #include <linux/mfd/mcp.h>
 #include <linux/gpio.h>
 #include <linux/mutex.h>