]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/mfd/arizona-core.c
Merge tag 'nfsd-4.4' of git://linux-nfs.org/~bfields/linux
[karo-tx-linux.git] / drivers / mfd / arizona-core.c
index 29be2628352cc2d8210bc1894766f2290ab9cc1f..d474732cc65c80becb53ae93cb3b3699564d4cf0 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/machine.h>
 #include <linux/slab.h>
+#include <linux/platform_device.h>
 
 #include <linux/mfd/arizona/core.h>
 #include <linux/mfd/arizona/registers.h>
@@ -487,6 +488,23 @@ static int arizona_connect_dcvdd(struct arizona *arizona)
        return ret;
 }
 
+static int arizona_is_jack_det_active(struct arizona *arizona)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
+       if (ret) {
+               dev_err(arizona->dev,
+                       "Failed to check jack det status: %d\n", ret);
+               return ret;
+       } else if (val & ARIZONA_JD1_ENA) {
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
 static int arizona_runtime_resume(struct device *dev)
 {
        struct arizona *arizona = dev_get_drvdata(dev);
@@ -610,20 +628,18 @@ err:
 static int arizona_runtime_suspend(struct device *dev)
 {
        struct arizona *arizona = dev_get_drvdata(dev);
-       unsigned int val;
+       int jd_active = 0;
        int ret;
 
        dev_dbg(arizona->dev, "Entering AoD mode\n");
 
-       ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
-       if (ret) {
-               dev_err(dev, "Failed to check jack det status: %d\n", ret);
-               return ret;
-       }
-
        switch (arizona->type) {
        case WM5110:
        case WM8280:
+               jd_active = arizona_is_jack_det_active(arizona);
+               if (jd_active < 0)
+                       return jd_active;
+
                if (arizona->external_dcvdd) {
                        ret = arizona_isolate_dcvdd(arizona);
                        if (ret != 0)
@@ -645,13 +661,17 @@ static int arizona_runtime_suspend(struct device *dev)
                }
                break;
        case WM5102:
+               jd_active = arizona_is_jack_det_active(arizona);
+               if (jd_active < 0)
+                       return jd_active;
+
                if (arizona->external_dcvdd) {
                        ret = arizona_isolate_dcvdd(arizona);
                        if (ret != 0)
                                return ret;
                }
 
-               if (!(val & ARIZONA_JD1_ENA)) {
+               if (!jd_active) {
                        ret = regmap_write(arizona->regmap,
                                           ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
                        if (ret) {
@@ -663,6 +683,10 @@ static int arizona_runtime_suspend(struct device *dev)
                }
                break;
        default:
+               jd_active = arizona_is_jack_det_active(arizona);
+               if (jd_active < 0)
+                       return jd_active;
+
                if (arizona->external_dcvdd) {
                        ret = arizona_isolate_dcvdd(arizona);
                        if (ret != 0)
@@ -676,7 +700,7 @@ static int arizona_runtime_suspend(struct device *dev)
        regulator_disable(arizona->dcvdd);
 
        /* Allow us to completely power down if no jack detection */
-       if (!(val & ARIZONA_JD1_ENA)) {
+       if (!jd_active) {
                dev_dbg(arizona->dev, "Fully powering off\n");
 
                arizona->has_fully_powered_off = true;
@@ -942,7 +966,8 @@ int arizona_dev_init(struct arizona *arizona)
        const char *type_name;
        unsigned int reg, val, mask;
        int (*apply_patch)(struct arizona *) = NULL;
-       int ret, i;
+       const struct mfd_cell *subdevs = NULL;
+       int n_subdevs, ret, i;
 
        dev_set_drvdata(arizona->dev, arizona);
        mutex_init(&arizona->clk_lock);
@@ -1103,74 +1128,95 @@ int arizona_dev_init(struct arizona *arizona)
        arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
 
        switch (reg) {
-#ifdef CONFIG_MFD_WM5102
        case 0x5102:
-               type_name = "WM5102";
-               if (arizona->type != WM5102) {
-                       dev_err(arizona->dev, "WM5102 registered as %d\n",
-                               arizona->type);
-                       arizona->type = WM5102;
+               if (IS_ENABLED(CONFIG_MFD_WM5102)) {
+                       type_name = "WM5102";
+                       if (arizona->type != WM5102) {
+                               dev_warn(arizona->dev,
+                                        "WM5102 registered as %d\n",
+                                        arizona->type);
+                               arizona->type = WM5102;
+                       }
+
+                       apply_patch = wm5102_patch;
+                       arizona->rev &= 0x7;
+                       subdevs = wm5102_devs;
+                       n_subdevs = ARRAY_SIZE(wm5102_devs);
                }
-               apply_patch = wm5102_patch;
-               arizona->rev &= 0x7;
                break;
-#endif
-#ifdef CONFIG_MFD_WM5110
        case 0x5110:
-               switch (arizona->type) {
-               case WM5110:
-                       type_name = "WM5110";
-                       break;
-               case WM8280:
-                       type_name = "WM8280";
-                       break;
-               default:
-                       type_name = "WM5110";
-                       dev_err(arizona->dev, "WM5110 registered as %d\n",
-                               arizona->type);
-                       arizona->type = WM5110;
-                       break;
+               if (IS_ENABLED(CONFIG_MFD_WM5110)) {
+                       switch (arizona->type) {
+                       case WM5110:
+                               type_name = "WM5110";
+                               break;
+                       case WM8280:
+                               type_name = "WM8280";
+                               break;
+                       default:
+                               type_name = "WM5110";
+                               dev_warn(arizona->dev,
+                                        "WM5110 registered as %d\n",
+                                        arizona->type);
+                               arizona->type = WM5110;
+                               break;
+                       }
+
+                       apply_patch = wm5110_patch;
+                       subdevs = wm5110_devs;
+                       n_subdevs = ARRAY_SIZE(wm5110_devs);
                }
-               apply_patch = wm5110_patch;
                break;
-#endif
-#ifdef CONFIG_MFD_WM8997
        case 0x8997:
-               type_name = "WM8997";
-               if (arizona->type != WM8997) {
-                       dev_err(arizona->dev, "WM8997 registered as %d\n",
-                               arizona->type);
-                       arizona->type = WM8997;
+               if (IS_ENABLED(CONFIG_MFD_WM8997)) {
+                       type_name = "WM8997";
+                       if (arizona->type != WM8997) {
+                               dev_warn(arizona->dev,
+                                        "WM8997 registered as %d\n",
+                                        arizona->type);
+                               arizona->type = WM8997;
+                       }
+
+                       apply_patch = wm8997_patch;
+                       subdevs = wm8997_devs;
+                       n_subdevs = ARRAY_SIZE(wm8997_devs);
                }
-               apply_patch = wm8997_patch;
                break;
-#endif
-#ifdef CONFIG_MFD_WM8998
        case 0x6349:
-               switch (arizona->type) {
-               case WM8998:
-                       type_name = "WM8998";
-                       break;
-
-               case WM1814:
-                       type_name = "WM1814";
-                       break;
+               if (IS_ENABLED(CONFIG_MFD_WM8998)) {
+                       switch (arizona->type) {
+                       case WM8998:
+                               type_name = "WM8998";
+                               break;
+
+                       case WM1814:
+                               type_name = "WM1814";
+                               break;
+
+                       default:
+                               type_name = "WM8998";
+                               dev_warn(arizona->dev,
+                                        "WM8998 registered as %d\n",
+                                        arizona->type);
+                               arizona->type = WM8998;
+                       }
 
-               default:
-                       type_name = "WM8998";
-                       dev_err(arizona->dev, "WM8998 registered as %d\n",
-                               arizona->type);
-                       arizona->type = WM8998;
+                       apply_patch = wm8998_patch;
+                       subdevs = wm8998_devs;
+                       n_subdevs = ARRAY_SIZE(wm8998_devs);
                }
-
-               apply_patch = wm8998_patch;
                break;
-#endif
        default:
                dev_err(arizona->dev, "Unknown device ID %x\n", reg);
                goto err_reset;
        }
 
+       if (!subdevs) {
+               dev_err(arizona->dev,
+                       "No kernel support for device ID %x\n", reg);
+               goto err_reset;
+       }
+
        dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
 
        if (apply_patch) {
@@ -1356,28 +1402,10 @@ int arizona_dev_init(struct arizona *arizona)
        arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
                            arizona_underclocked, arizona);
 
-       switch (arizona->type) {
-       case WM5102:
-               ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
-                                     ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
-               break;
-       case WM5110:
-       case WM8280:
-               ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
-                                     ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
-               break;
-       case WM8997:
-               ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
-                                     ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
-               break;
-       case WM8998:
-       case WM1814:
-               ret = mfd_add_devices(arizona->dev, -1, wm8998_devs,
-                                     ARRAY_SIZE(wm8998_devs), NULL, 0, NULL);
-               break;
-       }
+       ret = mfd_add_devices(arizona->dev, PLATFORM_DEVID_NONE,
+                             subdevs, n_subdevs, NULL, 0, NULL);
 
-       if (ret != 0) {
+       if (ret) {
                dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
                goto err_irq;
        }