Merge branch 'ib-mfd-io-3.15' into HEAD
authorLee Jones <lee.jones@linaro.org>
Wed, 19 Mar 2014 08:57:53 +0000 (08:57 +0000)
committerLee Jones <lee.jones@linaro.org>
Wed, 19 Mar 2014 08:57:53 +0000 (08:57 +0000)
21 files changed:
Documentation/devicetree/bindings/mfd/omap-usb-host.txt
Documentation/devicetree/bindings/mfd/omap-usb-tll.txt
Documentation/devicetree/bindings/mfd/s2mpa01.txt [new file with mode: 0644]
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/omap5.dtsi
arch/arm/mach-omap2/cclock3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
drivers/clk/ti/clk-3xxx.c
drivers/mfd/omap-usb-host.c
drivers/mfd/omap-usb-tll.c
drivers/mfd/sec-core.c
drivers/mfd/sec-irq.c
drivers/mfd/wm5102-tables.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/s2mpa01.c [new file with mode: 0644]
include/linux/mfd/samsung/core.h
include/linux/mfd/samsung/irq.h
include/linux/mfd/samsung/rtc.h
include/linux/mfd/samsung/s2mpa01.h [new file with mode: 0644]
include/linux/mfd/samsung/s2mps14.h [new file with mode: 0644]

index b381fa696bf95c7e35c5a850f2a9425d9f9e7fab..4721b2d521e4c62b51a06aff7bd34e3db9dda9f3 100644 (file)
@@ -32,6 +32,29 @@ Optional properties:
 - single-ulpi-bypass: Must be present if the controller contains a single
   ULPI bypass control bit. e.g. OMAP3 silicon <= ES2.1
 
+- clocks: a list of phandles and clock-specifier pairs, one for each entry in
+  clock-names.
+
+- clock-names: should include:
+  For OMAP3
+  * "usbhost_120m_fck" - 120MHz Functional clock.
+
+  For OMAP4+
+  * "refclk_60m_int" - 60MHz internal reference clock for UTMI clock mux
+  * "refclk_60m_ext_p1" - 60MHz external ref. clock for Port 1's UTMI clock mux.
+  * "refclk_60m_ext_p2" - 60MHz external ref. clock for Port 2's UTMI clock mux
+  * "utmi_p1_gfclk" - Port 1 UTMI clock mux.
+  * "utmi_p2_gfclk" - Port 2 UTMI clock mux.
+  * "usb_host_hs_utmi_p1_clk" - Port 1 UTMI clock gate.
+  * "usb_host_hs_utmi_p2_clk" - Port 2 UTMI clock gate.
+  * "usb_host_hs_utmi_p3_clk" - Port 3 UTMI clock gate.
+  * "usb_host_hs_hsic480m_p1_clk" - Port 1 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic480m_p2_clk" - Port 2 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic480m_p3_clk" - Port 3 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p1_clk" - Port 1 60MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p2_clk" - Port 2 60MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p3_clk" - Port 3 60MHz HSIC clock gate.
+
 Required properties if child node exists:
 
 - #address-cells: Must be 1
index 62fe69724e3b1da6a4b0b8f31c79f85e4dbdca93..c58d70437fce8b0dd11636a5a5f98946d8674d42 100644 (file)
@@ -7,6 +7,16 @@ Required properties:
 - interrupts : should contain the TLL module's interrupt
 - ti,hwmod : must contain "usb_tll_hs"
 
+Optional properties:
+
+- clocks: a list of phandles and clock-specifier pairs, one for each entry in
+  clock-names.
+
+- clock-names: should include:
+  * "usb_tll_hs_usb_ch0_clk" - USB TLL channel 0 clock
+  * "usb_tll_hs_usb_ch1_clk" - USB TLL channel 1 clock
+  * "usb_tll_hs_usb_ch2_clk" - USB TLL channel 2 clock
+
 Example:
 
        usbhstll: usbhstll@4a062000 {
diff --git a/Documentation/devicetree/bindings/mfd/s2mpa01.txt b/Documentation/devicetree/bindings/mfd/s2mpa01.txt
new file mode 100644 (file)
index 0000000..c13d3d8
--- /dev/null
@@ -0,0 +1,90 @@
+
+* Samsung S2MPA01 Voltage and Current Regulator
+
+The Samsung S2MPA01 is a multi-function device which includes high
+efficiency buck converters including Dual-Phase buck converter, various LDOs,
+and an RTC. It is interfaced to the host controller using an I2C interface.
+Each sub-block is addressed by the host system using different I2C slave
+addresses.
+
+Required properties:
+- compatible: Should be "samsung,s2mpa01-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 s2mpa01 are delivered to.
+- interrupts: An interrupt specifier for the sole interrupt generated by the
+  device.
+
+Optional nodes:
+- regulators: The regulators of s2mpa01 that have to be instantiated should be
+  included in a sub-node named 'regulators'. Regulator nodes and constraints
+  included in this sub-node use the standard regulator bindings which are
+  documented elsewhere.
+
+Properties for BUCK regulator nodes:
+- regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500
+  (default), 25000, or 50000. May be 0 for disabling the ramp delay on
+  BUCK{1,2,3,4}.
+
+ In the absence of the regulator-ramp-delay property, the default ramp
+ delay will be used.
+
+  NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set
+  for a particular group of BUCKs. So provide same regulator-ramp-delay=<value>.
+
+  The following BUCKs share ramp settings:
+  * 1 and 6
+  * 2 and 4
+  * 8, 9, and 10
+
+The following are the names of the regulators that the s2mpa01 PMIC block
+supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
+as per the datasheet of s2mpa01.
+
+       - LDOn
+                 - valid values for n are 1 to 26
+                 - Example: LDO1, LD02, LDO26
+       - BUCKn
+                 - valid values for n are 1 to 10.
+                 - Example: BUCK1, BUCK2, BUCK9
+
+Example:
+
+       s2mpa01_pmic@66 {
+               compatible = "samsung,s2mpa01-pmic";
+               reg = <0x66>;
+
+               regulators {
+                       ldo1_reg: LDO1 {
+                               regulator-name = "VDD_ALIVE";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                       };
+
+                       ldo2_reg: LDO2 {
+                               regulator-name = "VDDQ_MMC2";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               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 d3f8a6e8ca205ef1585c279c1ce50dc8703fa6b5..39a05ce52e9cfa819ae873087a0450a828e49883 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges;
+                       clocks = <&init_60m_fclk>,
+                                <&xclk60mhsp1_ck>,
+                                <&xclk60mhsp2_ck>;
+                       clock-names = "refclk_60m_int",
+                                     "refclk_60m_ext_p1",
+                                     "refclk_60m_ext_p2";
 
                        usbhsohci: ohci@4a064800 {
                                compatible = "ti,ohci-omap3", "usb-ohci";
index a72813a9663eccd7075b185489cbda4694fd0003..d4dae488deccc07fcf4c1770af3efa100c29fee3 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges;
+                       clocks = <&l3init_60m_fclk>,
+                                <&xclk60mhsp1_ck>,
+                                <&xclk60mhsp2_ck>;
+                       clock-names = "refclk_60m_int",
+                                     "refclk_60m_ext_p1",
+                                     "refclk_60m_ext_p2";
 
                        usbhsohci: ohci@4a064800 {
                                compatible = "ti,ohci-omap3", "usb-ohci";
index 3b05aea56d1f5636d5ff2e154513cf22349b3eec..4299a559ebcada8abe69e3cfefdde1a02e9110cf 100644 (file)
@@ -3495,10 +3495,6 @@ static struct omap_clk omap3xxx_clks[] = {
        CLK(NULL,       "dss_tv_fck",   &dss_tv_fck),
        CLK(NULL,       "dss_96m_fck",  &dss_96m_fck),
        CLK(NULL,       "dss2_alwon_fck",       &dss2_alwon_fck),
-       CLK(NULL,       "utmi_p1_gfclk",        &dummy_ck),
-       CLK(NULL,       "utmi_p2_gfclk",        &dummy_ck),
-       CLK(NULL,       "xclk60mhsp1_ck",       &dummy_ck),
-       CLK(NULL,       "xclk60mhsp2_ck",       &dummy_ck),
        CLK(NULL,       "init_60m_fclk",        &dummy_ck),
        CLK(NULL,       "gpt1_fck",     &gpt1_fck),
        CLK(NULL,       "aes2_ick",     &aes2_ick),
index 4c3b1e6df50806700cbcfc3c4f582650b36cc3a3..ad87f46eb7f04825b9c4bca3c32d4161a755aebf 100644 (file)
@@ -1955,10 +1955,6 @@ static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
        .sysc = &omap3xxx_usb_host_hs_sysc,
 };
 
-static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = {
-         { .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", },
-};
-
 static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
        { .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
        { .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
@@ -1981,8 +1977,6 @@ static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
                        .idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
                },
        },
-       .opt_clks       = omap3xxx_usb_host_hs_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks),
 
        /*
         * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
index d3230234f07b980e7de341d2ff8f2b4912a8d010..0d1750a8aea40db16a470c697418d1dbd8b6bb45 100644 (file)
@@ -130,10 +130,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
        DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
        DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
        DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"),
-       DT_CLK(NULL, "utmi_p1_gfclk", "dummy_ck"),
-       DT_CLK(NULL, "utmi_p2_gfclk", "dummy_ck"),
-       DT_CLK(NULL, "xclk60mhsp1_ck", "dummy_ck"),
-       DT_CLK(NULL, "xclk60mhsp2_ck", "dummy_ck"),
        DT_CLK(NULL, "init_60m_fclk", "dummy_ck"),
        DT_CLK(NULL, "gpt1_fck", "gpt1_fck"),
        DT_CLK(NULL, "aes2_ick", "aes2_ick"),
index 90b630ccc8bc65fa7381439cd190274834c50153..651e249287dc4292a127d30de326323b989c3b17 100644 (file)
@@ -665,55 +665,78 @@ static int usbhs_omap_probe(struct platform_device *pdev)
                goto err_mem;
        }
 
-       need_logic_fck = false;
+       /* Set all clocks as invalid to begin with */
+       omap->ehci_logic_fck = ERR_PTR(-ENODEV);
+       omap->init_60m_fclk = ERR_PTR(-ENODEV);
+       omap->utmi_p1_gfclk = ERR_PTR(-ENODEV);
+       omap->utmi_p2_gfclk = ERR_PTR(-ENODEV);
+       omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV);
+       omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV);
+
        for (i = 0; i < omap->nports; i++) {
-               if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
-                       is_ehci_hsic_mode(i))
-                               need_logic_fck |= true;
+               omap->utmi_clk[i] = ERR_PTR(-ENODEV);
+               omap->hsic480m_clk[i] = ERR_PTR(-ENODEV);
+               omap->hsic60m_clk[i] = ERR_PTR(-ENODEV);
        }
 
-       omap->ehci_logic_fck = ERR_PTR(-EINVAL);
-       if (need_logic_fck) {
-               omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
-               if (IS_ERR(omap->ehci_logic_fck)) {
-                       ret = PTR_ERR(omap->ehci_logic_fck);
-                       dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
+       /* for OMAP3 i.e. USBHS REV1 */
+       if (omap->usbhs_rev == OMAP_USBHS_REV1) {
+               need_logic_fck = false;
+               for (i = 0; i < omap->nports; i++) {
+                       if (is_ehci_phy_mode(pdata->port_mode[i]) ||
+                           is_ehci_tll_mode(pdata->port_mode[i]) ||
+                           is_ehci_hsic_mode(pdata->port_mode[i]))
+
+                               need_logic_fck |= true;
                }
+
+               if (need_logic_fck) {
+                       omap->ehci_logic_fck = devm_clk_get(dev,
+                                                           "usbhost_120m_fck");
+                       if (IS_ERR(omap->ehci_logic_fck)) {
+                               ret = PTR_ERR(omap->ehci_logic_fck);
+                               dev_err(dev, "usbhost_120m_fck failed:%d\n",
+                                       ret);
+                               goto err_mem;
+                       }
+               }
+               goto initialize;
        }
 
-       omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk");
+       /* for OMAP4+ i.e. USBHS REV2+ */
+       omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk");
        if (IS_ERR(omap->utmi_p1_gfclk)) {
                ret = PTR_ERR(omap->utmi_p1_gfclk);
                dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
-               goto err_p1_gfclk;
+               goto err_mem;
        }
 
-       omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk");
+       omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk");
        if (IS_ERR(omap->utmi_p2_gfclk)) {
                ret = PTR_ERR(omap->utmi_p2_gfclk);
                dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
-               goto err_p2_gfclk;
+               goto err_mem;
        }
 
-       omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
+       omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
        if (IS_ERR(omap->xclk60mhsp1_ck)) {
                ret = PTR_ERR(omap->xclk60mhsp1_ck);
-               dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
-               goto err_xclk60mhsp1;
+               dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret);
+               goto err_mem;
        }
 
-       omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
+       omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
        if (IS_ERR(omap->xclk60mhsp2_ck)) {
                ret = PTR_ERR(omap->xclk60mhsp2_ck);
-               dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
-               goto err_xclk60mhsp2;
+               dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret);
+               goto err_mem;
        }
 
-       omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
+       omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
        if (IS_ERR(omap->init_60m_fclk)) {
                ret = PTR_ERR(omap->init_60m_fclk);
-               dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-               goto err_init60m;
+               dev_err(dev, "refclk_60m_int failed error:%d\n", ret);
+               goto err_mem;
        }
 
        for (i = 0; i < omap->nports; i++) {
@@ -727,55 +750,72 @@ static int usbhs_omap_probe(struct platform_device *pdev)
                 * platforms have all clocks and we can function without
                 * them
                 */
-               omap->utmi_clk[i] = clk_get(dev, clkname);
-               if (IS_ERR(omap->utmi_clk[i]))
-                       dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-                               clkname, PTR_ERR(omap->utmi_clk[i]));
+               omap->utmi_clk[i] = devm_clk_get(dev, clkname);
+               if (IS_ERR(omap->utmi_clk[i])) {
+                       ret = PTR_ERR(omap->utmi_clk[i]);
+                       dev_err(dev, "Failed to get clock : %s : %d\n",
+                               clkname, ret);
+                       goto err_mem;
+               }
 
                snprintf(clkname, sizeof(clkname),
                                "usb_host_hs_hsic480m_p%d_clk", i + 1);
-               omap->hsic480m_clk[i] = clk_get(dev, clkname);
-               if (IS_ERR(omap->hsic480m_clk[i]))
-                       dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-                               clkname, PTR_ERR(omap->hsic480m_clk[i]));
+               omap->hsic480m_clk[i] = devm_clk_get(dev, clkname);
+               if (IS_ERR(omap->hsic480m_clk[i])) {
+                       ret = PTR_ERR(omap->hsic480m_clk[i]);
+                       dev_err(dev, "Failed to get clock : %s : %d\n",
+                               clkname, ret);
+                       goto err_mem;
+               }
 
                snprintf(clkname, sizeof(clkname),
                                "usb_host_hs_hsic60m_p%d_clk", i + 1);
-               omap->hsic60m_clk[i] = clk_get(dev, clkname);
-               if (IS_ERR(omap->hsic60m_clk[i]))
-                       dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-                               clkname, PTR_ERR(omap->hsic60m_clk[i]));
+               omap->hsic60m_clk[i] = devm_clk_get(dev, clkname);
+               if (IS_ERR(omap->hsic60m_clk[i])) {
+                       ret = PTR_ERR(omap->hsic60m_clk[i]);
+                       dev_err(dev, "Failed to get clock : %s : %d\n",
+                               clkname, ret);
+                       goto err_mem;
+               }
        }
 
        if (is_ehci_phy_mode(pdata->port_mode[0])) {
-               /* for OMAP3, clk_set_parent fails */
                ret = clk_set_parent(omap->utmi_p1_gfclk,
                                        omap->xclk60mhsp1_ck);
-               if (ret != 0)
-                       dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
                ret = clk_set_parent(omap->utmi_p1_gfclk,
                                        omap->init_60m_fclk);
-               if (ret != 0)
-                       dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        }
 
        if (is_ehci_phy_mode(pdata->port_mode[1])) {
                ret = clk_set_parent(omap->utmi_p2_gfclk,
                                        omap->xclk60mhsp2_ck);
-               if (ret != 0)
-                       dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
                ret = clk_set_parent(omap->utmi_p2_gfclk,
                                                omap->init_60m_fclk);
-               if (ret != 0)
-                       dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        }
 
+initialize:
        omap_usbhs_init(dev);
 
        if (dev->of_node) {
@@ -784,7 +824,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
                if (ret) {
                        dev_err(dev, "Failed to create DT children: %d\n", ret);
-                       goto err_alloc;
+                       goto err_mem;
                }
 
        } else {
@@ -792,40 +832,12 @@ static int usbhs_omap_probe(struct platform_device *pdev)
                if (ret) {
                        dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
                                                ret);
-                       goto err_alloc;
+                       goto err_mem;
                }
        }
 
        return 0;
 
-err_alloc:
-       for (i = 0; i < omap->nports; i++) {
-               if (!IS_ERR(omap->utmi_clk[i]))
-                       clk_put(omap->utmi_clk[i]);
-               if (!IS_ERR(omap->hsic60m_clk[i]))
-                       clk_put(omap->hsic60m_clk[i]);
-               if (!IS_ERR(omap->hsic480m_clk[i]))
-                       clk_put(omap->hsic480m_clk[i]);
-       }
-
-       clk_put(omap->init_60m_fclk);
-
-err_init60m:
-       clk_put(omap->xclk60mhsp2_ck);
-
-err_xclk60mhsp2:
-       clk_put(omap->xclk60mhsp1_ck);
-
-err_xclk60mhsp1:
-       clk_put(omap->utmi_p2_gfclk);
-
-err_p2_gfclk:
-       clk_put(omap->utmi_p1_gfclk);
-
-err_p1_gfclk:
-       if (!IS_ERR(omap->ehci_logic_fck))
-               clk_put(omap->ehci_logic_fck);
-
 err_mem:
        pm_runtime_disable(dev);
 
@@ -847,27 +859,6 @@ static int usbhs_omap_remove_child(struct device *dev, void *data)
  */
 static int usbhs_omap_remove(struct platform_device *pdev)
 {
-       struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
-       int i;
-
-       for (i = 0; i < omap->nports; i++) {
-               if (!IS_ERR(omap->utmi_clk[i]))
-                       clk_put(omap->utmi_clk[i]);
-               if (!IS_ERR(omap->hsic60m_clk[i]))
-                       clk_put(omap->hsic60m_clk[i]);
-               if (!IS_ERR(omap->hsic480m_clk[i]))
-                       clk_put(omap->hsic480m_clk[i]);
-       }
-
-       clk_put(omap->init_60m_fclk);
-       clk_put(omap->utmi_p1_gfclk);
-       clk_put(omap->utmi_p2_gfclk);
-       clk_put(omap->xclk60mhsp2_ck);
-       clk_put(omap->xclk60mhsp1_ck);
-
-       if (!IS_ERR(omap->ehci_logic_fck))
-               clk_put(omap->ehci_logic_fck);
-
        pm_runtime_disable(&pdev->dev);
 
        /* remove children */
index 5ee50f779ef60a86c1ab5e07782186e228054024..532eacab6b46ab78c69c9a73079db89bd462a0c8 100644 (file)
@@ -252,7 +252,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
                break;
        }
 
-       tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
+       tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch,
                                                GFP_KERNEL);
        if (!tll->ch_clk) {
                ret = -ENOMEM;
index 714e2135210ec2ddc989efcd44f3e800b80f5bcf..281a827472754ad9b79939e67eb11820d70e3eaa 100644 (file)
@@ -26,7 +26,9 @@
 #include <linux/mfd/samsung/core.h>
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/rtc.h>
+#include <linux/mfd/samsung/s2mpa01.h>
 #include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s2mps14.h>
 #include <linux/mfd/samsung/s5m8763.h>
 #include <linux/mfd/samsung/s5m8767.h>
 #include <linux/regmap.h>
@@ -69,18 +71,53 @@ static const struct mfd_cell s2mps11_devs[] = {
        }
 };
 
+static const struct mfd_cell s2mps14_devs[] = {
+       {
+               .name = "s2mps14-pmic",
+       }, {
+               .name = "s2mps14-rtc",
+       }, {
+               .name = "s2mps14-clk",
+       }
+};
+
+static const struct mfd_cell s2mpa01_devs[] = {
+       {
+               .name = "s2mpa01-pmic",
+       },
+};
+
 #ifdef CONFIG_OF
 static struct of_device_id sec_dt_match[] = {
        {       .compatible = "samsung,s5m8767-pmic",
                .data = (void *)S5M8767X,
-       },
-       {       .compatible = "samsung,s2mps11-pmic",
+       }, {
+               .compatible = "samsung,s2mps11-pmic",
                .data = (void *)S2MPS11X,
+       }, {
+               .compatible = "samsung,s2mps14-pmic",
+               .data = (void *)S2MPS14X,
+       }, {
+               .compatible = "samsung,s2mpa01-pmic",
+               .data = (void *)S2MPA01,
+       }, {
+               /* Sentinel */
        },
-       {},
 };
 #endif
 
+static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S2MPA01_REG_INT1M:
+       case S2MPA01_REG_INT2M:
+       case S2MPA01_REG_INT3M:
+               return false;
+       default:
+               return true;
+       }
+}
+
 static bool s2mps11_volatile(struct device *dev, unsigned int reg)
 {
        switch (reg) {
@@ -111,6 +148,15 @@ static const struct regmap_config sec_regmap_config = {
        .val_bits = 8,
 };
 
+static const struct regmap_config s2mpa01_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPA01_REG_LDO_OVCB4,
+       .volatile_reg = s2mpa01_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
 static const struct regmap_config s2mps11_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
@@ -120,6 +166,15 @@ static const struct regmap_config s2mps11_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
+static const struct regmap_config s2mps14_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPS14_REG_LDODSCH3,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
 static const struct regmap_config s5m8763_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
@@ -138,9 +193,18 @@ static const struct regmap_config s5m8767_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
-static const struct regmap_config sec_rtc_regmap_config = {
+static const struct regmap_config s5m_rtc_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = SEC_RTC_REG_MAX,
+};
+
+static const struct regmap_config s2mps14_rtc_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
+
+       .max_register = S2MPS_RTC_REG_MAX,
 };
 
 #ifdef CONFIG_OF
@@ -180,24 +244,24 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
 }
 #endif
 
-static inline int sec_i2c_get_driver_data(struct i2c_client *i2c,
+static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c,
                                                const struct i2c_device_id *id)
 {
 #ifdef CONFIG_OF
        if (i2c->dev.of_node) {
                const struct of_device_id *match;
                match = of_match_node(sec_dt_match, i2c->dev.of_node);
-               return (int)match->data;
+               return (unsigned long)match->data;
        }
 #endif
-       return (int)id->driver_data;
+       return id->driver_data;
 }
 
 static int sec_pmic_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev);
-       const struct regmap_config *regmap;
+       const struct regmap_config *regmap, *regmap_rtc;
        struct sec_pmic_dev *sec_pmic;
        int ret;
 
@@ -229,17 +293,34 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        }
 
        switch (sec_pmic->device_type) {
+       case S2MPA01:
+               regmap = &s2mpa01_regmap_config;
+               break;
        case S2MPS11X:
                regmap = &s2mps11_regmap_config;
+               /*
+                * The rtc-s5m driver does not support S2MPS11 and there
+                * is no mfd_cell for S2MPS11 RTC device.
+                * However we must pass something to devm_regmap_init_i2c()
+                * so use S5M-like regmap config even though it wouldn't work.
+                */
+               regmap_rtc = &s5m_rtc_regmap_config;
+               break;
+       case S2MPS14X:
+               regmap = &s2mps14_regmap_config;
+               regmap_rtc = &s2mps14_rtc_regmap_config;
                break;
        case S5M8763X:
                regmap = &s5m8763_regmap_config;
+               regmap_rtc = &s5m_rtc_regmap_config;
                break;
        case S5M8767X:
                regmap = &s5m8767_regmap_config;
+               regmap_rtc = &s5m_rtc_regmap_config;
                break;
        default:
                regmap = &sec_regmap_config;
+               regmap_rtc = &s5m_rtc_regmap_config;
                break;
        }
 
@@ -252,10 +333,13 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        }
 
        sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+       if (!sec_pmic->rtc) {
+               dev_err(&i2c->dev, "Failed to allocate I2C for RTC\n");
+               return -ENODEV;
+       }
        i2c_set_clientdata(sec_pmic->rtc, sec_pmic);
 
-       sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc,
-                       &sec_rtc_regmap_config);
+       sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, regmap_rtc);
        if (IS_ERR(sec_pmic->regmap_rtc)) {
                ret = PTR_ERR(sec_pmic->regmap_rtc);
                dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
@@ -283,10 +367,18 @@ static int sec_pmic_probe(struct i2c_client *i2c,
                ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs,
                                      ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL);
                break;
+       case S2MPA01:
+               ret = mfd_add_devices(sec_pmic->dev, -1, s2mpa01_devs,
+                                     ARRAY_SIZE(s2mpa01_devs), NULL, 0, NULL);
+               break;
        case S2MPS11X:
                ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs,
                                      ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL);
                break;
+       case S2MPS14X:
+               ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs,
+                                     ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL);
+               break;
        default:
                /* If this happens the probe function is problem */
                BUG();
index 4de494f51d401b3d85544633621091d9e7cceff6..64e7913aadc6cf3fbe68389edd8ba986e7a1ec8c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sec-irq.c
  *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
  *              http://www.samsung.com
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -19,6 +19,7 @@
 #include <linux/mfd/samsung/core.h>
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s2mps14.h>
 #include <linux/mfd/samsung/s5m8763.h>
 #include <linux/mfd/samsung/s5m8767.h>
 
@@ -59,13 +60,13 @@ static const struct regmap_irq s2mps11_irqs[] = {
                .reg_offset = 1,
                .mask = S2MPS11_IRQ_RTC60S_MASK,
        },
-       [S2MPS11_IRQ_RTCA1] = {
+       [S2MPS11_IRQ_RTCA0] = {
                .reg_offset = 1,
-               .mask = S2MPS11_IRQ_RTCA1_MASK,
+               .mask = S2MPS11_IRQ_RTCA0_MASK,
        },
-       [S2MPS11_IRQ_RTCA2] = {
+       [S2MPS11_IRQ_RTCA1] = {
                .reg_offset = 1,
-               .mask = S2MPS11_IRQ_RTCA2_MASK,
+               .mask = S2MPS11_IRQ_RTCA1_MASK,
        },
        [S2MPS11_IRQ_SMPL] = {
                .reg_offset = 1,
@@ -89,6 +90,76 @@ static const struct regmap_irq s2mps11_irqs[] = {
        },
 };
 
+static const struct regmap_irq s2mps14_irqs[] = {
+       [S2MPS14_IRQ_PWRONF] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_PWRONF_MASK,
+       },
+       [S2MPS14_IRQ_PWRONR] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_PWRONR_MASK,
+       },
+       [S2MPS14_IRQ_JIGONBF] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_JIGONBF_MASK,
+       },
+       [S2MPS14_IRQ_JIGONBR] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_JIGONBR_MASK,
+       },
+       [S2MPS14_IRQ_ACOKBF] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_ACOKBF_MASK,
+       },
+       [S2MPS14_IRQ_ACOKBR] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_ACOKBR_MASK,
+       },
+       [S2MPS14_IRQ_PWRON1S] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_PWRON1S_MASK,
+       },
+       [S2MPS14_IRQ_MRB] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_MRB_MASK,
+       },
+       [S2MPS14_IRQ_RTC60S] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTC60S_MASK,
+       },
+       [S2MPS14_IRQ_RTCA1] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTCA1_MASK,
+       },
+       [S2MPS14_IRQ_RTCA0] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTCA0_MASK,
+       },
+       [S2MPS14_IRQ_SMPL] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_SMPL_MASK,
+       },
+       [S2MPS14_IRQ_RTC1S] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTC1S_MASK,
+       },
+       [S2MPS14_IRQ_WTSR] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_WTSR_MASK,
+       },
+       [S2MPS14_IRQ_INT120C] = {
+               .reg_offset = 2,
+               .mask = S2MPS11_IRQ_INT120C_MASK,
+       },
+       [S2MPS14_IRQ_INT140C] = {
+               .reg_offset = 2,
+               .mask = S2MPS11_IRQ_INT140C_MASK,
+       },
+       [S2MPS14_IRQ_TSD] = {
+               .reg_offset = 2,
+               .mask = S2MPS14_IRQ_TSD_MASK,
+       },
+};
 
 static const struct regmap_irq s5m8767_irqs[] = {
        [S5M8767_IRQ_PWRR] = {
@@ -246,6 +317,16 @@ static const struct regmap_irq_chip s2mps11_irq_chip = {
        .ack_base = S2MPS11_REG_INT1,
 };
 
+static const struct regmap_irq_chip s2mps14_irq_chip = {
+       .name = "s2mps14",
+       .irqs = s2mps14_irqs,
+       .num_irqs = ARRAY_SIZE(s2mps14_irqs),
+       .num_regs = 3,
+       .status_base = S2MPS14_REG_INT1,
+       .mask_base = S2MPS14_REG_INT1M,
+       .ack_base = S2MPS14_REG_INT1,
+};
+
 static const struct regmap_irq_chip s5m8767_irq_chip = {
        .name = "s5m8767",
        .irqs = s5m8767_irqs,
@@ -297,6 +378,12 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
                                  sec_pmic->irq_base, &s2mps11_irq_chip,
                                  &sec_pmic->irq_data);
                break;
+       case S2MPS14X:
+               ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
+                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                 sec_pmic->irq_base, &s2mps14_irq_chip,
+                                 &sec_pmic->irq_data);
+               break;
        default:
                dev_err(sec_pmic->dev, "Unknown device type %d\n",
                        sec_pmic->device_type);
index 1e9a4b2102f9d89c9549e3d226cf7ef0c91866ef..f9b1e96660132421d7e7e1709629081ba75a55c9 100644 (file)
@@ -73,6 +73,7 @@ static const struct reg_default wm5102_revb_patch[] = {
        { 0x171, 0x0000 },
        { 0x35E, 0x000C },
        { 0x2D4, 0x0000 },
+       { 0x4DC, 0x0900 },
        { 0x80, 0x0000 },
 };
 
index 6a7932822e373317caba9c5c799c9439f5444927..8f8e6710bb456952ae2715bf5f4ed62aa8c5834c 100644 (file)
@@ -416,6 +416,13 @@ config REGULATOR_RC5T583
          through regulator interface. The device supports multiple DCDC/LDO
          outputs which can be controlled by i2c communication.
 
+config REGULATOR_S2MPA01
+       tristate "Samsung S2MPA01 voltage regulator"
+       depends on MFD_SEC_CORE
+       help
+        This driver controls Samsung S2MPA01 voltage output regulator
+        via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs.
+
 config REGULATOR_S2MPS11
        tristate "Samsung S2MPS11 voltage regulator"
        depends on MFD_SEC_CORE
index 979f9ddcf259bd5a82b6b5d91f81981902e6185c..b3ece84289cf4cf598c2bfa33cffeb9a2ece5035 100644 (file)
@@ -57,6 +57,7 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o
 obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
+obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c
new file mode 100644 (file)
index 0000000..808b3aa
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd
+ *             http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/mfd/samsung/core.h>
+#include <linux/mfd/samsung/s2mpa01.h>
+
+#define S2MPA01_REGULATOR_CNT ARRAY_SIZE(regulators)
+
+struct s2mpa01_info {
+       int ramp_delay24;
+       int ramp_delay3;
+       int ramp_delay5;
+       int ramp_delay16;
+       int ramp_delay7;
+       int ramp_delay8910;
+};
+
+static int get_ramp_delay(int ramp_delay)
+{
+       unsigned char cnt = 0;
+
+       ramp_delay /= 6250;
+
+       while (true) {
+               ramp_delay = ramp_delay >> 1;
+               if (ramp_delay == 0)
+                       break;
+               cnt++;
+       }
+
+       if (cnt > 3)
+               cnt = 3;
+
+       return cnt;
+}
+
+static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
+                                  unsigned int old_selector,
+                                  unsigned int new_selector)
+{
+       struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
+       unsigned int ramp_delay = 0;
+       int old_volt, new_volt;
+
+       switch (rdev->desc->id) {
+       case S2MPA01_BUCK2:
+       case S2MPA01_BUCK4:
+               ramp_delay = s2mpa01->ramp_delay24;
+               break;
+       case S2MPA01_BUCK3:
+               ramp_delay = s2mpa01->ramp_delay3;
+               break;
+       case S2MPA01_BUCK5:
+               ramp_delay = s2mpa01->ramp_delay5;
+               break;
+       case S2MPA01_BUCK1:
+       case S2MPA01_BUCK6:
+               ramp_delay = s2mpa01->ramp_delay16;
+               break;
+       case S2MPA01_BUCK7:
+               ramp_delay = s2mpa01->ramp_delay7;
+               break;
+       case S2MPA01_BUCK8:
+       case S2MPA01_BUCK9:
+       case S2MPA01_BUCK10:
+               ramp_delay = s2mpa01->ramp_delay8910;
+               break;
+       }
+
+       if (ramp_delay == 0)
+               ramp_delay = rdev->desc->ramp_delay;
+
+       old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector);
+       new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector);
+
+       return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);
+}
+
+static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+       struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
+       unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2;
+       unsigned int ramp_enable = 1, enable_shift = 0;
+       int ret;
+
+       switch (rdev->desc->id) {
+       case S2MPA01_BUCK1:
+               enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT;
+               if (!ramp_delay) {
+                       ramp_enable = 0;
+                       break;
+               }
+
+               if (ramp_delay > s2mpa01->ramp_delay16)
+                       s2mpa01->ramp_delay16 = ramp_delay;
+               else
+                       ramp_delay = s2mpa01->ramp_delay16;
+
+               ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
+               ramp_reg = S2MPA01_REG_RAMP1;
+               break;
+       case S2MPA01_BUCK2:
+               enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT;
+               if (!ramp_delay) {
+                       ramp_enable = 0;
+                       break;
+               }
+
+               if (ramp_delay > s2mpa01->ramp_delay24)
+                       s2mpa01->ramp_delay24 = ramp_delay;
+               else
+                       ramp_delay = s2mpa01->ramp_delay24;
+
+               ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
+               ramp_reg = S2MPA01_REG_RAMP1;
+               break;
+       case S2MPA01_BUCK3:
+               enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT;
+               if (!ramp_delay) {
+                       ramp_enable = 0;
+                       break;
+               }
+
+               s2mpa01->ramp_delay3 = ramp_delay;
+               ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT;
+               ramp_reg = S2MPA01_REG_RAMP1;
+               break;
+       case S2MPA01_BUCK4:
+               enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT;
+               if (!ramp_delay) {
+                       ramp_enable = 0;
+                       break;
+               }
+
+               if (ramp_delay > s2mpa01->ramp_delay24)
+                       s2mpa01->ramp_delay24 = ramp_delay;
+               else
+                       ramp_delay = s2mpa01->ramp_delay24;
+
+               ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
+               ramp_reg = S2MPA01_REG_RAMP1;
+               break;
+       case S2MPA01_BUCK5:
+               s2mpa01->ramp_delay5 = ramp_delay;
+               ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT;
+               break;
+       case S2MPA01_BUCK6:
+               if (ramp_delay > s2mpa01->ramp_delay16)
+                       s2mpa01->ramp_delay16 = ramp_delay;
+               else
+                       ramp_delay = s2mpa01->ramp_delay16;
+
+               ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
+               break;
+       case S2MPA01_BUCK7:
+               s2mpa01->ramp_delay7 = ramp_delay;
+               ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT;
+               break;
+       case S2MPA01_BUCK8:
+       case S2MPA01_BUCK9:
+       case S2MPA01_BUCK10:
+               if (ramp_delay > s2mpa01->ramp_delay8910)
+                       s2mpa01->ramp_delay8910 = ramp_delay;
+               else
+                       ramp_delay = s2mpa01->ramp_delay8910;
+
+               ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT;
+               break;
+       default:
+               return 0;
+       }
+
+       if (!ramp_enable)
+               goto ramp_disable;
+
+       if (enable_shift) {
+               ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
+                                       1 << enable_shift, 1 << enable_shift);
+               if (ret) {
+                       dev_err(&rdev->dev, "failed to enable ramp rate\n");
+                       return ret;
+               }
+       }
+
+       ramp_val = get_ramp_delay(ramp_delay);
+
+       return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift,
+                                 ramp_val << ramp_shift);
+
+ramp_disable:
+       return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
+                                 1 << enable_shift, 0);
+}
+
+static struct regulator_ops s2mpa01_ldo_ops = {
+       .list_voltage           = regulator_list_voltage_linear,
+       .map_voltage            = regulator_map_voltage_linear,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops s2mpa01_buck_ops = {
+       .list_voltage           = regulator_list_voltage_linear,
+       .map_voltage            = regulator_map_voltage_linear,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .set_voltage_time_sel   = s2mpa01_regulator_set_voltage_time_sel,
+       .set_ramp_delay         = s2mpa01_set_ramp_delay,
+};
+
+#define regulator_desc_ldo1(num)       {               \
+       .name           = "LDO"#num,                    \
+       .id             = S2MPA01_LDO##num,             \
+       .ops            = &s2mpa01_ldo_ops,             \
+       .type           = REGULATOR_VOLTAGE,            \
+       .owner          = THIS_MODULE,                  \
+       .min_uV         = S2MPA01_LDO_MIN,              \
+       .uV_step        = S2MPA01_LDO_STEP1,            \
+       .n_voltages     = S2MPA01_LDO_N_VOLTAGES,       \
+       .vsel_reg       = S2MPA01_REG_L1CTRL + num - 1, \
+       .vsel_mask      = S2MPA01_LDO_VSEL_MASK,        \
+       .enable_reg     = S2MPA01_REG_L1CTRL + num - 1, \
+       .enable_mask    = S2MPA01_ENABLE_MASK           \
+}
+#define regulator_desc_ldo2(num)       {               \
+       .name           = "LDO"#num,                    \
+       .id             = S2MPA01_LDO##num,             \
+       .ops            = &s2mpa01_ldo_ops,             \
+       .type           = REGULATOR_VOLTAGE,            \
+       .owner          = THIS_MODULE,                  \
+       .min_uV         = S2MPA01_LDO_MIN,              \
+       .uV_step        = S2MPA01_LDO_STEP2,            \
+       .n_voltages     = S2MPA01_LDO_N_VOLTAGES,       \
+       .vsel_reg       = S2MPA01_REG_L1CTRL + num - 1, \
+       .vsel_mask      = S2MPA01_LDO_VSEL_MASK,        \
+       .enable_reg     = S2MPA01_REG_L1CTRL + num - 1, \
+       .enable_mask    = S2MPA01_ENABLE_MASK           \
+}
+
+#define regulator_desc_buck1_4(num)    {                       \
+       .name           = "BUCK"#num,                           \
+       .id             = S2MPA01_BUCK##num,                    \
+       .ops            = &s2mpa01_buck_ops,                    \
+       .type           = REGULATOR_VOLTAGE,                    \
+       .owner          = THIS_MODULE,                          \
+       .min_uV         = S2MPA01_BUCK_MIN1,                    \
+       .uV_step        = S2MPA01_BUCK_STEP1,                   \
+       .n_voltages     = S2MPA01_BUCK_N_VOLTAGES,              \
+       .ramp_delay     = S2MPA01_RAMP_DELAY,                   \
+       .vsel_reg       = S2MPA01_REG_B1CTRL2 + (num - 1) * 2,  \
+       .vsel_mask      = S2MPA01_BUCK_VSEL_MASK,               \
+       .enable_reg     = S2MPA01_REG_B1CTRL1 + (num - 1) * 2,  \
+       .enable_mask    = S2MPA01_ENABLE_MASK                   \
+}
+
+#define regulator_desc_buck5   {                               \
+       .name           = "BUCK5",                              \
+       .id             = S2MPA01_BUCK5,                        \
+       .ops            = &s2mpa01_buck_ops,                    \
+       .type           = REGULATOR_VOLTAGE,                    \
+       .owner          = THIS_MODULE,                          \
+       .min_uV         = S2MPA01_BUCK_MIN2,                    \
+       .uV_step        = S2MPA01_BUCK_STEP1,                   \
+       .n_voltages     = S2MPA01_BUCK_N_VOLTAGES,              \
+       .ramp_delay     = S2MPA01_RAMP_DELAY,                   \
+       .vsel_reg       = S2MPA01_REG_B5CTRL2,                  \
+       .vsel_mask      = S2MPA01_BUCK_VSEL_MASK,               \
+       .enable_reg     = S2MPA01_REG_B5CTRL1,                  \
+       .enable_mask    = S2MPA01_ENABLE_MASK                   \
+}
+
+#define regulator_desc_buck6_7(num)    {                       \
+       .name           = "BUCK"#num,                           \
+       .id             = S2MPA01_BUCK##num,                    \
+       .ops            = &s2mpa01_buck_ops,                    \
+       .type           = REGULATOR_VOLTAGE,                    \
+       .owner          = THIS_MODULE,                          \
+       .min_uV         = S2MPA01_BUCK_MIN1,                    \
+       .uV_step        = S2MPA01_BUCK_STEP1,                   \
+       .n_voltages     = S2MPA01_BUCK_N_VOLTAGES,              \
+       .ramp_delay     = S2MPA01_RAMP_DELAY,                   \
+       .vsel_reg       = S2MPA01_REG_B6CTRL2 + (num - 6) * 2,  \
+       .vsel_mask      = S2MPA01_BUCK_VSEL_MASK,               \
+       .enable_reg     = S2MPA01_REG_B6CTRL1 + (num - 6) * 2,  \
+       .enable_mask    = S2MPA01_ENABLE_MASK                   \
+}
+
+#define regulator_desc_buck8   {                               \
+       .name           = "BUCK8",                              \
+       .id             = S2MPA01_BUCK8,                        \
+       .ops            = &s2mpa01_buck_ops,                    \
+       .type           = REGULATOR_VOLTAGE,                    \
+       .owner          = THIS_MODULE,                          \
+       .min_uV         = S2MPA01_BUCK_MIN2,                    \
+       .uV_step        = S2MPA01_BUCK_STEP2,                   \
+       .n_voltages     = S2MPA01_BUCK_N_VOLTAGES,              \
+       .ramp_delay     = S2MPA01_RAMP_DELAY,                   \
+       .vsel_reg       = S2MPA01_REG_B8CTRL2,                  \
+       .vsel_mask      = S2MPA01_BUCK_VSEL_MASK,               \
+       .enable_reg     = S2MPA01_REG_B8CTRL1,                  \
+       .enable_mask    = S2MPA01_ENABLE_MASK                   \
+}
+
+#define regulator_desc_buck9   {                               \
+       .name           = "BUCK9",                              \
+       .id             = S2MPA01_BUCK9,                        \
+       .ops            = &s2mpa01_buck_ops,                    \
+       .type           = REGULATOR_VOLTAGE,                    \
+       .owner          = THIS_MODULE,                          \
+       .min_uV         = S2MPA01_BUCK_MIN4,                    \
+       .uV_step        = S2MPA01_BUCK_STEP2,                   \
+       .n_voltages     = S2MPA01_BUCK_N_VOLTAGES,              \
+       .ramp_delay     = S2MPA01_RAMP_DELAY,                   \
+       .vsel_reg       = S2MPA01_REG_B9CTRL2,                  \
+       .vsel_mask      = S2MPA01_BUCK_VSEL_MASK,               \
+       .enable_reg     = S2MPA01_REG_B9CTRL1,                  \
+       .enable_mask    = S2MPA01_ENABLE_MASK                   \
+}
+
+#define regulator_desc_buck10  {                               \
+       .name           = "BUCK10",                             \
+       .id             = S2MPA01_BUCK10,                       \
+       .ops            = &s2mpa01_buck_ops,                    \
+       .type           = REGULATOR_VOLTAGE,                    \
+       .owner          = THIS_MODULE,                          \
+       .min_uV         = S2MPA01_BUCK_MIN3,                    \
+       .uV_step        = S2MPA01_BUCK_STEP2,                   \
+       .n_voltages     = S2MPA01_BUCK_N_VOLTAGES,              \
+       .ramp_delay     = S2MPA01_RAMP_DELAY,                   \
+       .vsel_reg       = S2MPA01_REG_B10CTRL2,                 \
+       .vsel_mask      = S2MPA01_BUCK_VSEL_MASK,               \
+       .enable_reg     = S2MPA01_REG_B10CTRL1,                 \
+       .enable_mask    = S2MPA01_ENABLE_MASK                   \
+}
+
+static struct regulator_desc regulators[] = {
+       regulator_desc_ldo2(1),
+       regulator_desc_ldo1(2),
+       regulator_desc_ldo1(3),
+       regulator_desc_ldo1(4),
+       regulator_desc_ldo1(5),
+       regulator_desc_ldo2(6),
+       regulator_desc_ldo1(7),
+       regulator_desc_ldo1(8),
+       regulator_desc_ldo1(9),
+       regulator_desc_ldo1(10),
+       regulator_desc_ldo2(11),
+       regulator_desc_ldo1(12),
+       regulator_desc_ldo1(13),
+       regulator_desc_ldo1(14),
+       regulator_desc_ldo1(15),
+       regulator_desc_ldo1(16),
+       regulator_desc_ldo1(17),
+       regulator_desc_ldo1(18),
+       regulator_desc_ldo1(19),
+       regulator_desc_ldo1(20),
+       regulator_desc_ldo1(21),
+       regulator_desc_ldo2(22),
+       regulator_desc_ldo2(23),
+       regulator_desc_ldo1(24),
+       regulator_desc_ldo1(25),
+       regulator_desc_ldo1(26),
+       regulator_desc_buck1_4(1),
+       regulator_desc_buck1_4(2),
+       regulator_desc_buck1_4(3),
+       regulator_desc_buck1_4(4),
+       regulator_desc_buck5,
+       regulator_desc_buck6_7(6),
+       regulator_desc_buck6_7(7),
+       regulator_desc_buck8,
+       regulator_desc_buck9,
+       regulator_desc_buck10,
+};
+
+static int s2mpa01_pmic_probe(struct platform_device *pdev)
+{
+       struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+       struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
+       struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX];
+       struct device_node *reg_np = NULL;
+       struct regulator_config config = { };
+       struct s2mpa01_info *s2mpa01;
+       int i;
+
+       s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL);
+       if (!s2mpa01)
+               return -ENOMEM;
+
+       for (i = 0; i < S2MPA01_REGULATOR_CNT; i++)
+               rdata[i].name = regulators[i].name;
+
+       if (iodev->dev->of_node) {
+               reg_np = of_get_child_by_name(iodev->dev->of_node,
+                                                       "regulators");
+                       if (!reg_np) {
+                               dev_err(&pdev->dev,
+                                       "could not find regulators sub-node\n");
+                               return -EINVAL;
+                       }
+
+               of_regulator_match(&pdev->dev, reg_np, rdata,
+                                               S2MPA01_REGULATOR_MAX);
+               of_node_put(reg_np);
+       }
+
+       platform_set_drvdata(pdev, s2mpa01);
+
+       config.dev = &pdev->dev;
+       config.regmap = iodev->regmap_pmic;
+       config.driver_data = s2mpa01;
+
+       for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) {
+               struct regulator_dev *rdev;
+               if (pdata)
+                       config.init_data = pdata->regulators[i].initdata;
+               else
+                       config.init_data = rdata[i].init_data;
+
+               if (reg_np)
+                       config.of_node = rdata[i].of_node;
+
+               rdev = devm_regulator_register(&pdev->dev,
+                                               &regulators[i], &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(&pdev->dev, "regulator init failed for %d\n",
+                               i);
+                       return PTR_ERR(rdev);
+               }
+       }
+
+       return 0;
+}
+
+static const struct platform_device_id s2mpa01_pmic_id[] = {
+       { "s2mpa01-pmic", 0},
+       { },
+};
+MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id);
+
+static struct platform_driver s2mpa01_pmic_driver = {
+       .driver = {
+               .name = "s2mpa01-pmic",
+               .owner = THIS_MODULE,
+       },
+       .probe = s2mpa01_pmic_probe,
+       .id_table = s2mpa01_pmic_id,
+};
+
+module_platform_driver(s2mpa01_pmic_driver);
+
+/* Module information */
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");
+MODULE_DESCRIPTION("SAMSUNG S2MPA01 Regulator Driver");
+MODULE_LICENSE("GPL");
index 41c9bde410c5b31f0bcdfb61de557ca0fe5353ce..900bc9e1888b1d369c3caff0d5c05bbd8c9f14c1 100644 (file)
@@ -18,7 +18,9 @@ enum sec_device_type {
        S5M8751X,
        S5M8763X,
        S5M8767X,
+       S2MPA01,
        S2MPS11X,
+       S2MPS14X,
 };
 
 /**
@@ -50,7 +52,7 @@ struct sec_pmic_dev {
        struct regmap_irq_chip_data *irq_data;
 
        int ono;
-       int type;
+       unsigned long type;
        bool wakeup;
        bool wtsr_smpl;
 };
@@ -92,7 +94,7 @@ struct sec_platform_data {
        int                             buck3_default_idx;
        int                             buck4_default_idx;
 
-       int                             buck_ramp_delay;
+       int                             buck_ramp_delay;
 
        int                             buck2_ramp_delay;
        int                             buck34_ramp_delay;
@@ -100,10 +102,15 @@ struct sec_platform_data {
        int                             buck16_ramp_delay;
        int                             buck7810_ramp_delay;
        int                             buck9_ramp_delay;
-
-       bool                            buck2_ramp_enable;
-       bool                            buck3_ramp_enable;
-       bool                            buck4_ramp_enable;
+       int                             buck24_ramp_delay;
+       int                             buck3_ramp_delay;
+       int                             buck7_ramp_delay;
+       int                             buck8910_ramp_delay;
+
+       bool                            buck1_ramp_enable;
+       bool                            buck2_ramp_enable;
+       bool                            buck3_ramp_enable;
+       bool                            buck4_ramp_enable;
        bool                            buck6_ramp_enable;
 
        int                             buck2_init;
index d43b4f9e7fb27ab4b5014592fe363d3a97ba153e..1224f447356b90a5601fbc1826eb0a67606aeefe 100644 (file)
 #ifndef __LINUX_MFD_SEC_IRQ_H
 #define __LINUX_MFD_SEC_IRQ_H
 
+enum s2mpa01_irq {
+       S2MPA01_IRQ_PWRONF,
+       S2MPA01_IRQ_PWRONR,
+       S2MPA01_IRQ_JIGONBF,
+       S2MPA01_IRQ_JIGONBR,
+       S2MPA01_IRQ_ACOKBF,
+       S2MPA01_IRQ_ACOKBR,
+       S2MPA01_IRQ_PWRON1S,
+       S2MPA01_IRQ_MRB,
+
+       S2MPA01_IRQ_RTC60S,
+       S2MPA01_IRQ_RTCA1,
+       S2MPA01_IRQ_RTCA0,
+       S2MPA01_IRQ_SMPL,
+       S2MPA01_IRQ_RTC1S,
+       S2MPA01_IRQ_WTSR,
+
+       S2MPA01_IRQ_INT120C,
+       S2MPA01_IRQ_INT140C,
+       S2MPA01_IRQ_LDO3_TSD,
+       S2MPA01_IRQ_B16_TSD,
+       S2MPA01_IRQ_B24_TSD,
+       S2MPA01_IRQ_B35_TSD,
+
+       S2MPA01_IRQ_NR,
+};
+
+#define S2MPA01_IRQ_PWRONF_MASK                (1 << 0)
+#define S2MPA01_IRQ_PWRONR_MASK                (1 << 1)
+#define S2MPA01_IRQ_JIGONBF_MASK       (1 << 2)
+#define S2MPA01_IRQ_JIGONBR_MASK       (1 << 3)
+#define S2MPA01_IRQ_ACOKBF_MASK                (1 << 4)
+#define S2MPA01_IRQ_ACOKBR_MASK                (1 << 5)
+#define S2MPA01_IRQ_PWRON1S_MASK       (1 << 6)
+#define S2MPA01_IRQ_MRB_MASK           (1 << 7)
+
+#define S2MPA01_IRQ_RTC60S_MASK                (1 << 0)
+#define S2MPA01_IRQ_RTCA1_MASK         (1 << 1)
+#define S2MPA01_IRQ_RTCA0_MASK         (1 << 2)
+#define S2MPA01_IRQ_SMPL_MASK          (1 << 3)
+#define S2MPA01_IRQ_RTC1S_MASK         (1 << 4)
+#define S2MPA01_IRQ_WTSR_MASK          (1 << 5)
+
+#define S2MPA01_IRQ_INT120C_MASK       (1 << 0)
+#define S2MPA01_IRQ_INT140C_MASK       (1 << 1)
+#define S2MPA01_IRQ_LDO3_TSD_MASK      (1 << 2)
+#define S2MPA01_IRQ_B16_TSD_MASK       (1 << 3)
+#define S2MPA01_IRQ_B24_TSD_MASK       (1 << 4)
+#define S2MPA01_IRQ_B35_TSD_MASK       (1 << 5)
+
 enum s2mps11_irq {
        S2MPS11_IRQ_PWRONF,
        S2MPS11_IRQ_PWRONR,
@@ -24,8 +74,8 @@ enum s2mps11_irq {
        S2MPS11_IRQ_MRB,
 
        S2MPS11_IRQ_RTC60S,
+       S2MPS11_IRQ_RTCA0,
        S2MPS11_IRQ_RTCA1,
-       S2MPS11_IRQ_RTCA2,
        S2MPS11_IRQ_SMPL,
        S2MPS11_IRQ_RTC1S,
        S2MPS11_IRQ_WTSR,
@@ -47,7 +97,7 @@ enum s2mps11_irq {
 
 #define S2MPS11_IRQ_RTC60S_MASK                (1 << 0)
 #define S2MPS11_IRQ_RTCA1_MASK         (1 << 1)
-#define S2MPS11_IRQ_RTCA2_MASK         (1 << 2)
+#define S2MPS11_IRQ_RTCA0_MASK         (1 << 2)
 #define S2MPS11_IRQ_SMPL_MASK          (1 << 3)
 #define S2MPS11_IRQ_RTC1S_MASK         (1 << 4)
 #define S2MPS11_IRQ_WTSR_MASK          (1 << 5)
@@ -55,6 +105,33 @@ enum s2mps11_irq {
 #define S2MPS11_IRQ_INT120C_MASK       (1 << 0)
 #define S2MPS11_IRQ_INT140C_MASK       (1 << 1)
 
+enum s2mps14_irq {
+       S2MPS14_IRQ_PWRONF,
+       S2MPS14_IRQ_PWRONR,
+       S2MPS14_IRQ_JIGONBF,
+       S2MPS14_IRQ_JIGONBR,
+       S2MPS14_IRQ_ACOKBF,
+       S2MPS14_IRQ_ACOKBR,
+       S2MPS14_IRQ_PWRON1S,
+       S2MPS14_IRQ_MRB,
+
+       S2MPS14_IRQ_RTC60S,
+       S2MPS14_IRQ_RTCA1,
+       S2MPS14_IRQ_RTCA0,
+       S2MPS14_IRQ_SMPL,
+       S2MPS14_IRQ_RTC1S,
+       S2MPS14_IRQ_WTSR,
+
+       S2MPS14_IRQ_INT120C,
+       S2MPS14_IRQ_INT140C,
+       S2MPS14_IRQ_TSD,
+
+       S2MPS14_IRQ_NR,
+};
+
+/* Masks for interrupts are the same as in s2mps11 */
+#define S2MPS14_IRQ_TSD_MASK           (1 << 2)
+
 enum s5m8767_irq {
        S5M8767_IRQ_PWRR,
        S5M8767_IRQ_PWRF,
index 94b7cd6d889185f9df10b611099bf06038365b83..3e02b768d53704968a76e27af9cece0f455de6bc 100644 (file)
@@ -1,12 +1,17 @@
-/*  rtc.h
+/* rtc.h
  *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
  *              http://www.samsung.com
  *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
@@ -43,6 +48,39 @@ enum sec_rtc_reg {
        SEC_RTC_STATUS,
        SEC_WTSR_SMPL_CNTL,
        SEC_RTC_UDR_CON,
+
+       SEC_RTC_REG_MAX,
+};
+
+enum s2mps_rtc_reg {
+       S2MPS_RTC_CTRL,
+       S2MPS_WTSR_SMPL_CNTL,
+       S2MPS_RTC_UDR_CON,
+       S2MPS_RSVD,
+       S2MPS_RTC_SEC,
+       S2MPS_RTC_MIN,
+       S2MPS_RTC_HOUR,
+       S2MPS_RTC_WEEKDAY,
+       S2MPS_RTC_DATE,
+       S2MPS_RTC_MONTH,
+       S2MPS_RTC_YEAR,
+       S2MPS_ALARM0_SEC,
+       S2MPS_ALARM0_MIN,
+       S2MPS_ALARM0_HOUR,
+       S2MPS_ALARM0_WEEKDAY,
+       S2MPS_ALARM0_DATE,
+       S2MPS_ALARM0_MONTH,
+       S2MPS_ALARM0_YEAR,
+       S2MPS_ALARM1_SEC,
+       S2MPS_ALARM1_MIN,
+       S2MPS_ALARM1_HOUR,
+       S2MPS_ALARM1_WEEKDAY,
+       S2MPS_ALARM1_DATE,
+       S2MPS_ALARM1_MONTH,
+       S2MPS_ALARM1_YEAR,
+       S2MPS_OFFSRC,
+
+       S2MPS_RTC_REG_MAX,
 };
 
 #define RTC_I2C_ADDR           (0x0C >> 1)
@@ -54,6 +92,9 @@ enum sec_rtc_reg {
 #define ALARM1_STATUS          (1 << 2)
 #define UPDATE_AD              (1 << 0)
 
+#define S2MPS_ALARM0_STATUS    (1 << 2)
+#define S2MPS_ALARM1_STATUS    (1 << 1)
+
 /* RTC Control Register */
 #define BCD_EN_SHIFT           0
 #define BCD_EN_MASK            (1 << BCD_EN_SHIFT)
@@ -62,6 +103,10 @@ enum sec_rtc_reg {
 /* RTC Update Register1 */
 #define RTC_UDR_SHIFT          0
 #define RTC_UDR_MASK           (1 << RTC_UDR_SHIFT)
+#define S2MPS_RTC_WUDR_SHIFT   4
+#define S2MPS_RTC_WUDR_MASK    (1 << S2MPS_RTC_WUDR_SHIFT)
+#define S2MPS_RTC_RUDR_SHIFT   0
+#define S2MPS_RTC_RUDR_MASK    (1 << S2MPS_RTC_RUDR_SHIFT)
 #define RTC_TCON_SHIFT         1
 #define RTC_TCON_MASK          (1 << RTC_TCON_SHIFT)
 #define RTC_TIME_EN_SHIFT      3
diff --git a/include/linux/mfd/samsung/s2mpa01.h b/include/linux/mfd/samsung/s2mpa01.h
new file mode 100644 (file)
index 0000000..fbc63bc
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd
+ *             http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S2MPA01_H
+#define __LINUX_MFD_S2MPA01_H
+
+/* S2MPA01 registers */
+enum s2mpa01_reg {
+       S2MPA01_REG_ID,
+       S2MPA01_REG_INT1,
+       S2MPA01_REG_INT2,
+       S2MPA01_REG_INT3,
+       S2MPA01_REG_INT1M,
+       S2MPA01_REG_INT2M,
+       S2MPA01_REG_INT3M,
+       S2MPA01_REG_ST1,
+       S2MPA01_REG_ST2,
+       S2MPA01_REG_PWRONSRC,
+       S2MPA01_REG_OFFSRC,
+       S2MPA01_REG_RTC_BUF,
+       S2MPA01_REG_CTRL1,
+       S2MPA01_REG_ETC_TEST,
+       S2MPA01_REG_RSVD1,
+       S2MPA01_REG_BU_CHG,
+       S2MPA01_REG_RAMP1,
+       S2MPA01_REG_RAMP2,
+       S2MPA01_REG_LDO_DSCH1,
+       S2MPA01_REG_LDO_DSCH2,
+       S2MPA01_REG_LDO_DSCH3,
+       S2MPA01_REG_LDO_DSCH4,
+       S2MPA01_REG_OTP_ADRL,
+       S2MPA01_REG_OTP_ADRH,
+       S2MPA01_REG_OTP_DATA,
+       S2MPA01_REG_MON1SEL,
+       S2MPA01_REG_MON2SEL,
+       S2MPA01_REG_LEE,
+       S2MPA01_REG_RSVD2,
+       S2MPA01_REG_RSVD3,
+       S2MPA01_REG_RSVD4,
+       S2MPA01_REG_RSVD5,
+       S2MPA01_REG_RSVD6,
+       S2MPA01_REG_TOP_RSVD,
+       S2MPA01_REG_DVS_SEL,
+       S2MPA01_REG_DVS_PTR,
+       S2MPA01_REG_DVS_DATA,
+       S2MPA01_REG_RSVD_NO,
+       S2MPA01_REG_UVLO,
+       S2MPA01_REG_LEE_NO,
+       S2MPA01_REG_B1CTRL1,
+       S2MPA01_REG_B1CTRL2,
+       S2MPA01_REG_B2CTRL1,
+       S2MPA01_REG_B2CTRL2,
+       S2MPA01_REG_B3CTRL1,
+       S2MPA01_REG_B3CTRL2,
+       S2MPA01_REG_B4CTRL1,
+       S2MPA01_REG_B4CTRL2,
+       S2MPA01_REG_B5CTRL1,
+       S2MPA01_REG_B5CTRL2,
+       S2MPA01_REG_B5CTRL3,
+       S2MPA01_REG_B5CTRL4,
+       S2MPA01_REG_B5CTRL5,
+       S2MPA01_REG_B5CTRL6,
+       S2MPA01_REG_B6CTRL1,
+       S2MPA01_REG_B6CTRL2,
+       S2MPA01_REG_B7CTRL1,
+       S2MPA01_REG_B7CTRL2,
+       S2MPA01_REG_B8CTRL1,
+       S2MPA01_REG_B8CTRL2,
+       S2MPA01_REG_B9CTRL1,
+       S2MPA01_REG_B9CTRL2,
+       S2MPA01_REG_B10CTRL1,
+       S2MPA01_REG_B10CTRL2,
+       S2MPA01_REG_L1CTRL,
+       S2MPA01_REG_L2CTRL,
+       S2MPA01_REG_L3CTRL,
+       S2MPA01_REG_L4CTRL,
+       S2MPA01_REG_L5CTRL,
+       S2MPA01_REG_L6CTRL,
+       S2MPA01_REG_L7CTRL,
+       S2MPA01_REG_L8CTRL,
+       S2MPA01_REG_L9CTRL,
+       S2MPA01_REG_L10CTRL,
+       S2MPA01_REG_L11CTRL,
+       S2MPA01_REG_L12CTRL,
+       S2MPA01_REG_L13CTRL,
+       S2MPA01_REG_L14CTRL,
+       S2MPA01_REG_L15CTRL,
+       S2MPA01_REG_L16CTRL,
+       S2MPA01_REG_L17CTRL,
+       S2MPA01_REG_L18CTRL,
+       S2MPA01_REG_L19CTRL,
+       S2MPA01_REG_L20CTRL,
+       S2MPA01_REG_L21CTRL,
+       S2MPA01_REG_L22CTRL,
+       S2MPA01_REG_L23CTRL,
+       S2MPA01_REG_L24CTRL,
+       S2MPA01_REG_L25CTRL,
+       S2MPA01_REG_L26CTRL,
+
+       S2MPA01_REG_LDO_OVCB1,
+       S2MPA01_REG_LDO_OVCB2,
+       S2MPA01_REG_LDO_OVCB3,
+       S2MPA01_REG_LDO_OVCB4,
+
+};
+
+/* S2MPA01 regulator ids */
+enum s2mpa01_regulators {
+       S2MPA01_LDO1,
+       S2MPA01_LDO2,
+       S2MPA01_LDO3,
+       S2MPA01_LDO4,
+       S2MPA01_LDO5,
+       S2MPA01_LDO6,
+       S2MPA01_LDO7,
+       S2MPA01_LDO8,
+       S2MPA01_LDO9,
+       S2MPA01_LDO10,
+       S2MPA01_LDO11,
+       S2MPA01_LDO12,
+       S2MPA01_LDO13,
+       S2MPA01_LDO14,
+       S2MPA01_LDO15,
+       S2MPA01_LDO16,
+       S2MPA01_LDO17,
+       S2MPA01_LDO18,
+       S2MPA01_LDO19,
+       S2MPA01_LDO20,
+       S2MPA01_LDO21,
+       S2MPA01_LDO22,
+       S2MPA01_LDO23,
+       S2MPA01_LDO24,
+       S2MPA01_LDO25,
+       S2MPA01_LDO26,
+
+       S2MPA01_BUCK1,
+       S2MPA01_BUCK2,
+       S2MPA01_BUCK3,
+       S2MPA01_BUCK4,
+       S2MPA01_BUCK5,
+       S2MPA01_BUCK6,
+       S2MPA01_BUCK7,
+       S2MPA01_BUCK8,
+       S2MPA01_BUCK9,
+       S2MPA01_BUCK10,
+
+       S2MPA01_REGULATOR_MAX,
+};
+
+#define S2MPA01_BUCK_MIN1      600000
+#define S2MPA01_BUCK_MIN2      800000
+#define S2MPA01_BUCK_MIN3      1000000
+#define S2MPA01_BUCK_MIN4      1500000
+#define S2MPA01_LDO_MIN                800000
+
+#define S2MPA01_BUCK_STEP1     6250
+#define S2MPA01_BUCK_STEP2     12500
+
+#define S2MPA01_LDO_STEP1      50000
+#define S2MPA01_LDO_STEP2      25000
+
+#define S2MPA01_LDO_VSEL_MASK  0x3F
+#define S2MPA01_BUCK_VSEL_MASK 0xFF
+#define S2MPA01_ENABLE_MASK    (0x03 << S2MPA01_ENABLE_SHIFT)
+#define S2MPA01_ENABLE_SHIFT   0x06
+#define S2MPA01_LDO_N_VOLTAGES (S2MPA01_LDO_VSEL_MASK + 1)
+#define S2MPA01_BUCK_N_VOLTAGES (S2MPA01_BUCK_VSEL_MASK + 1)
+
+#define S2MPA01_RAMP_DELAY     12500   /* uV/us */
+
+#define S2MPA01_BUCK16_RAMP_SHIFT      4
+#define S2MPA01_BUCK24_RAMP_SHIFT      6
+#define S2MPA01_BUCK3_RAMP_SHIFT       4
+#define S2MPA01_BUCK5_RAMP_SHIFT       6
+#define S2MPA01_BUCK7_RAMP_SHIFT       2
+#define S2MPA01_BUCK8910_RAMP_SHIFT    0
+
+#define S2MPA01_BUCK1_RAMP_EN_SHIFT    3
+#define S2MPA01_BUCK2_RAMP_EN_SHIFT    2
+#define S2MPA01_BUCK3_RAMP_EN_SHIFT    1
+#define S2MPA01_BUCK4_RAMP_EN_SHIFT    0
+#define S2MPA01_PMIC_EN_SHIFT  6
+
+#endif /*__LINUX_MFD_S2MPA01_H */
diff --git a/include/linux/mfd/samsung/s2mps14.h b/include/linux/mfd/samsung/s2mps14.h
new file mode 100644 (file)
index 0000000..ec1e085
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * s2mps14.h
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LINUX_MFD_S2MPS14_H
+#define __LINUX_MFD_S2MPS14_H
+
+/* S2MPS14 registers */
+enum s2mps14_reg {
+       S2MPS14_REG_ID,
+       S2MPS14_REG_INT1,
+       S2MPS14_REG_INT2,
+       S2MPS14_REG_INT3,
+       S2MPS14_REG_INT1M,
+       S2MPS14_REG_INT2M,
+       S2MPS14_REG_INT3M,
+       S2MPS14_REG_ST1,
+       S2MPS14_REG_ST2,
+       S2MPS14_REG_PWRONSRC,
+       S2MPS14_REG_OFFSRC,
+       S2MPS14_REG_BU_CHG,
+       S2MPS14_REG_RTCCTRL,
+       S2MPS14_REG_CTRL1,
+       S2MPS14_REG_CTRL2,
+       S2MPS14_REG_RSVD1,
+       S2MPS14_REG_RSVD2,
+       S2MPS14_REG_RSVD3,
+       S2MPS14_REG_RSVD4,
+       S2MPS14_REG_RSVD5,
+       S2MPS14_REG_RSVD6,
+       S2MPS14_REG_CTRL3,
+       S2MPS14_REG_RSVD7,
+       S2MPS14_REG_RSVD8,
+       S2MPS14_REG_WRSTBI,
+       S2MPS14_REG_B1CTRL1,
+       S2MPS14_REG_B1CTRL2,
+       S2MPS14_REG_B2CTRL1,
+       S2MPS14_REG_B2CTRL2,
+       S2MPS14_REG_B3CTRL1,
+       S2MPS14_REG_B3CTRL2,
+       S2MPS14_REG_B4CTRL1,
+       S2MPS14_REG_B4CTRL2,
+       S2MPS14_REG_B5CTRL1,
+       S2MPS14_REG_B5CTRL2,
+       S2MPS14_REG_L1CTRL,
+       S2MPS14_REG_L2CTRL,
+       S2MPS14_REG_L3CTRL,
+       S2MPS14_REG_L4CTRL,
+       S2MPS14_REG_L5CTRL,
+       S2MPS14_REG_L6CTRL,
+       S2MPS14_REG_L7CTRL,
+       S2MPS14_REG_L8CTRL,
+       S2MPS14_REG_L9CTRL,
+       S2MPS14_REG_L10CTRL,
+       S2MPS14_REG_L11CTRL,
+       S2MPS14_REG_L12CTRL,
+       S2MPS14_REG_L13CTRL,
+       S2MPS14_REG_L14CTRL,
+       S2MPS14_REG_L15CTRL,
+       S2MPS14_REG_L16CTRL,
+       S2MPS14_REG_L17CTRL,
+       S2MPS14_REG_L18CTRL,
+       S2MPS14_REG_L19CTRL,
+       S2MPS14_REG_L20CTRL,
+       S2MPS14_REG_L21CTRL,
+       S2MPS14_REG_L22CTRL,
+       S2MPS14_REG_L23CTRL,
+       S2MPS14_REG_L24CTRL,
+       S2MPS14_REG_L25CTRL,
+       S2MPS14_REG_LDODSCH1,
+       S2MPS14_REG_LDODSCH2,
+       S2MPS14_REG_LDODSCH3,
+};
+
+/* S2MPS14 regulator ids */
+enum s2mps14_regulators {
+       S2MPS14_LDO1,
+       S2MPS14_LDO2,
+       S2MPS14_LDO3,
+       S2MPS14_LDO4,
+       S2MPS14_LDO5,
+       S2MPS14_LDO6,
+       S2MPS14_LDO7,
+       S2MPS14_LDO8,
+       S2MPS14_LDO9,
+       S2MPS14_LDO10,
+       S2MPS14_LDO11,
+       S2MPS14_LDO12,
+       S2MPS14_LDO13,
+       S2MPS14_LDO14,
+       S2MPS14_LDO15,
+       S2MPS14_LDO16,
+       S2MPS14_LDO17,
+       S2MPS14_LDO18,
+       S2MPS14_LDO19,
+       S2MPS14_LDO20,
+       S2MPS14_LDO21,
+       S2MPS14_LDO22,
+       S2MPS14_LDO23,
+       S2MPS14_LDO24,
+       S2MPS14_LDO25,
+       S2MPS14_BUCK1,
+       S2MPS14_BUCK2,
+       S2MPS14_BUCK3,
+       S2MPS14_BUCK4,
+       S2MPS14_BUCK5,
+
+       S2MPS14_REGULATOR_MAX,
+};
+
+/* Regulator constraints for BUCKx */
+#define S2MPS14_BUCK1235_MIN_600MV     600000
+#define S2MPS14_BUCK4_MIN_1400MV       1400000
+#define S2MPS14_BUCK1235_STEP_6_25MV   6250
+#define S2MPS14_BUCK4_STEP_12_5MV      12500
+#define S2MPS14_BUCK1235_START_SEL     0x20
+#define S2MPS14_BUCK4_START_SEL                0x40
+/*
+ * Default ramp delay in uv/us. Datasheet says that ramp delay can be
+ * controlled however it does not specify which register is used for that.
+ * Let's assume that default value will be set.
+ */
+#define S2MPS14_BUCK_RAMP_DELAY                12500
+
+/* Regulator constraints for different types of LDOx */
+#define S2MPS14_LDO_MIN_800MV          800000
+#define S2MPS14_LDO_MIN_1800MV         1800000
+#define S2MPS14_LDO_STEP_12_5MV                12500
+#define S2MPS14_LDO_STEP_25MV          25000
+
+#define S2MPS14_LDO_VSEL_MASK          0x3F
+#define S2MPS14_BUCK_VSEL_MASK         0xFF
+#define S2MPS14_ENABLE_MASK            (0x03 << S2MPS14_ENABLE_SHIFT)
+#define S2MPS14_ENABLE_SHIFT           6
+#define S2MPS14_LDO_N_VOLTAGES         (S2MPS14_LDO_VSEL_MASK + 1)
+#define S2MPS14_BUCK_N_VOLTAGES                (S2MPS14_BUCK_VSEL_MASK + 1)
+
+#endif /*  __LINUX_MFD_S2MPS14_H */