linux/drivers/mfd/sec-core.c
<<
>>
Prefs
   1/*
   2 * sec-core.c
   3 *
   4 * Copyright (c) 2012 Samsung Electronics Co., Ltd
   5 *              http://www.samsung.com
   6 *
   7 *  This program is free software; you can redistribute  it and/or modify it
   8 *  under  the terms of  the GNU General  Public License as published by the
   9 *  Free Software Foundation;  either version 2 of the  License, or (at your
  10 *  option) any later version.
  11 *
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/moduleparam.h>
  16#include <linux/init.h>
  17#include <linux/err.h>
  18#include <linux/slab.h>
  19#include <linux/i2c.h>
  20#include <linux/of.h>
  21#include <linux/of_irq.h>
  22#include <linux/interrupt.h>
  23#include <linux/pm_runtime.h>
  24#include <linux/mutex.h>
  25#include <linux/mfd/core.h>
  26#include <linux/mfd/samsung/core.h>
  27#include <linux/mfd/samsung/irq.h>
  28#include <linux/mfd/samsung/s2mpa01.h>
  29#include <linux/mfd/samsung/s2mps11.h>
  30#include <linux/mfd/samsung/s2mps13.h>
  31#include <linux/mfd/samsung/s2mps14.h>
  32#include <linux/mfd/samsung/s2mps15.h>
  33#include <linux/mfd/samsung/s2mpu02.h>
  34#include <linux/mfd/samsung/s5m8763.h>
  35#include <linux/mfd/samsung/s5m8767.h>
  36#include <linux/regmap.h>
  37
  38static const struct mfd_cell s5m8751_devs[] = {
  39        {
  40                .name = "s5m8751-pmic",
  41        }, {
  42                .name = "s5m-charger",
  43        }, {
  44                .name = "s5m8751-codec",
  45        },
  46};
  47
  48static const struct mfd_cell s5m8763_devs[] = {
  49        {
  50                .name = "s5m8763-pmic",
  51        }, {
  52                .name = "s5m-rtc",
  53        }, {
  54                .name = "s5m-charger",
  55        },
  56};
  57
  58static const struct mfd_cell s5m8767_devs[] = {
  59        {
  60                .name = "s5m8767-pmic",
  61        }, {
  62                .name = "s5m-rtc",
  63        }, {
  64                .name = "s5m8767-clk",
  65                .of_compatible = "samsung,s5m8767-clk",
  66        }
  67};
  68
  69static const struct mfd_cell s2mps11_devs[] = {
  70        {
  71                .name = "s2mps11-regulator",
  72        }, {
  73                .name = "s2mps14-rtc",
  74        }, {
  75                .name = "s2mps11-clk",
  76                .of_compatible = "samsung,s2mps11-clk",
  77        }
  78};
  79
  80static const struct mfd_cell s2mps13_devs[] = {
  81        { .name = "s2mps13-regulator", },
  82        { .name = "s2mps13-rtc", },
  83        {
  84                .name = "s2mps13-clk",
  85                .of_compatible = "samsung,s2mps13-clk",
  86        },
  87};
  88
  89static const struct mfd_cell s2mps14_devs[] = {
  90        {
  91                .name = "s2mps14-regulator",
  92        }, {
  93                .name = "s2mps14-rtc",
  94        }, {
  95                .name = "s2mps14-clk",
  96                .of_compatible = "samsung,s2mps14-clk",
  97        }
  98};
  99
 100static const struct mfd_cell s2mps15_devs[] = {
 101        {
 102                .name = "s2mps15-regulator",
 103        }, {
 104                .name = "s2mps15-rtc",
 105        }, {
 106                .name = "s2mps13-clk",
 107                .of_compatible = "samsung,s2mps13-clk",
 108        },
 109};
 110
 111static const struct mfd_cell s2mpa01_devs[] = {
 112        {
 113                .name = "s2mpa01-pmic",
 114        },
 115};
 116
 117static const struct mfd_cell s2mpu02_devs[] = {
 118        {
 119                .name = "s2mpu02-regulator",
 120        },
 121};
 122
 123#ifdef CONFIG_OF
 124static const struct of_device_id sec_dt_match[] = {
 125        {       .compatible = "samsung,s5m8767-pmic",
 126                .data = (void *)S5M8767X,
 127        }, {
 128                .compatible = "samsung,s2mps11-pmic",
 129                .data = (void *)S2MPS11X,
 130        }, {
 131                .compatible = "samsung,s2mps13-pmic",
 132                .data = (void *)S2MPS13X,
 133        }, {
 134                .compatible = "samsung,s2mps14-pmic",
 135                .data = (void *)S2MPS14X,
 136        }, {
 137                .compatible = "samsung,s2mps15-pmic",
 138                .data = (void *)S2MPS15X,
 139        }, {
 140                .compatible = "samsung,s2mpa01-pmic",
 141                .data = (void *)S2MPA01,
 142        }, {
 143                .compatible = "samsung,s2mpu02-pmic",
 144                .data = (void *)S2MPU02,
 145        }, {
 146                /* Sentinel */
 147        },
 148};
 149#endif
 150
 151static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
 152{
 153        switch (reg) {
 154        case S2MPA01_REG_INT1M:
 155        case S2MPA01_REG_INT2M:
 156        case S2MPA01_REG_INT3M:
 157                return false;
 158        default:
 159                return true;
 160        }
 161}
 162
 163static bool s2mps11_volatile(struct device *dev, unsigned int reg)
 164{
 165        switch (reg) {
 166        case S2MPS11_REG_INT1M:
 167        case S2MPS11_REG_INT2M:
 168        case S2MPS11_REG_INT3M:
 169                return false;
 170        default:
 171                return true;
 172        }
 173}
 174
 175static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
 176{
 177        switch (reg) {
 178        case S2MPU02_REG_INT1M:
 179        case S2MPU02_REG_INT2M:
 180        case S2MPU02_REG_INT3M:
 181                return false;
 182        default:
 183                return true;
 184        }
 185}
 186
 187static bool s5m8763_volatile(struct device *dev, unsigned int reg)
 188{
 189        switch (reg) {
 190        case S5M8763_REG_IRQM1:
 191        case S5M8763_REG_IRQM2:
 192        case S5M8763_REG_IRQM3:
 193        case S5M8763_REG_IRQM4:
 194                return false;
 195        default:
 196                return true;
 197        }
 198}
 199
 200static const struct regmap_config sec_regmap_config = {
 201        .reg_bits = 8,
 202        .val_bits = 8,
 203};
 204
 205static const struct regmap_config s2mpa01_regmap_config = {
 206        .reg_bits = 8,
 207        .val_bits = 8,
 208
 209        .max_register = S2MPA01_REG_LDO_OVCB4,
 210        .volatile_reg = s2mpa01_volatile,
 211        .cache_type = REGCACHE_FLAT,
 212};
 213
 214static const struct regmap_config s2mps11_regmap_config = {
 215        .reg_bits = 8,
 216        .val_bits = 8,
 217
 218        .max_register = S2MPS11_REG_L38CTRL,
 219        .volatile_reg = s2mps11_volatile,
 220        .cache_type = REGCACHE_FLAT,
 221};
 222
 223static const struct regmap_config s2mps13_regmap_config = {
 224        .reg_bits = 8,
 225        .val_bits = 8,
 226
 227        .max_register = S2MPS13_REG_LDODSCH5,
 228        .volatile_reg = s2mps11_volatile,
 229        .cache_type = REGCACHE_FLAT,
 230};
 231
 232static const struct regmap_config s2mps14_regmap_config = {
 233        .reg_bits = 8,
 234        .val_bits = 8,
 235
 236        .max_register = S2MPS14_REG_LDODSCH3,
 237        .volatile_reg = s2mps11_volatile,
 238        .cache_type = REGCACHE_FLAT,
 239};
 240
 241static const struct regmap_config s2mps15_regmap_config = {
 242        .reg_bits = 8,
 243        .val_bits = 8,
 244
 245        .max_register = S2MPS15_REG_LDODSCH4,
 246        .volatile_reg = s2mps11_volatile,
 247        .cache_type = REGCACHE_FLAT,
 248};
 249
 250static const struct regmap_config s2mpu02_regmap_config = {
 251        .reg_bits = 8,
 252        .val_bits = 8,
 253
 254        .max_register = S2MPU02_REG_DVSDATA,
 255        .volatile_reg = s2mpu02_volatile,
 256        .cache_type = REGCACHE_FLAT,
 257};
 258
 259static const struct regmap_config s5m8763_regmap_config = {
 260        .reg_bits = 8,
 261        .val_bits = 8,
 262
 263        .max_register = S5M8763_REG_LBCNFG2,
 264        .volatile_reg = s5m8763_volatile,
 265        .cache_type = REGCACHE_FLAT,
 266};
 267
 268static const struct regmap_config s5m8767_regmap_config = {
 269        .reg_bits = 8,
 270        .val_bits = 8,
 271
 272        .max_register = S5M8767_REG_LDO28CTRL,
 273        .volatile_reg = s2mps11_volatile,
 274        .cache_type = REGCACHE_FLAT,
 275};
 276
 277static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
 278{
 279        unsigned int val;
 280
 281        /* For each device type, the REG_ID is always the first register */
 282        if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
 283                dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
 284}
 285
 286static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
 287{
 288        int err;
 289
 290        if (sec_pmic->device_type != S2MPS13X)
 291                return;
 292
 293        if (sec_pmic->pdata->disable_wrstbi) {
 294                /*
 295                 * If WRSTBI pin is pulled down this feature must be disabled
 296                 * because each Suspend to RAM will trigger buck voltage reset
 297                 * to default values.
 298                 */
 299                err = regmap_update_bits(sec_pmic->regmap_pmic,
 300                                         S2MPS13_REG_WRSTBI,
 301                                         S2MPS13_REG_WRSTBI_MASK, 0x0);
 302                if (err)
 303                        dev_warn(sec_pmic->dev,
 304                                 "Cannot initialize WRSTBI config: %d\n",
 305                                 err);
 306        }
 307}
 308
 309#ifdef CONFIG_OF
 310/*
 311 * Only the common platform data elements for s5m8767 are parsed here from the
 312 * device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and
 313 * others have to parse their own platform data elements from device tree.
 314 *
 315 * The s5m8767 platform data structure is instantiated here and the drivers for
 316 * the sub-modules need not instantiate another instance while parsing their
 317 * platform data.
 318 */
 319static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
 320                                        struct device *dev)
 321{
 322        struct sec_platform_data *pd;
 323
 324        pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
 325        if (!pd)
 326                return ERR_PTR(-ENOMEM);
 327
 328        /*
 329         * ToDo: the 'wakeup' member in the platform data is more of a linux
 330         * specfic information. Hence, there is no binding for that yet and
 331         * not parsed here.
 332         */
 333
 334        pd->manual_poweroff = of_property_read_bool(dev->of_node,
 335                                                "samsung,s2mps11-acokb-ground");
 336        pd->disable_wrstbi = of_property_read_bool(dev->of_node,
 337                                                "samsung,s2mps11-wrstbi-ground");
 338        return pd;
 339}
 340#else
 341static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
 342                                        struct device *dev)
 343{
 344        return NULL;
 345}
 346#endif
 347
 348static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c,
 349                                                const struct i2c_device_id *id)
 350{
 351#ifdef CONFIG_OF
 352        if (i2c->dev.of_node) {
 353                const struct of_device_id *match;
 354
 355                match = of_match_node(sec_dt_match, i2c->dev.of_node);
 356                return (unsigned long)match->data;
 357        }
 358#endif
 359        return id->driver_data;
 360}
 361
 362static int sec_pmic_probe(struct i2c_client *i2c,
 363                            const struct i2c_device_id *id)
 364{
 365        struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev);
 366        const struct regmap_config *regmap;
 367        const struct mfd_cell *sec_devs;
 368        struct sec_pmic_dev *sec_pmic;
 369        unsigned long device_type;
 370        int ret, num_sec_devs;
 371
 372        sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev),
 373                                GFP_KERNEL);
 374        if (sec_pmic == NULL)
 375                return -ENOMEM;
 376
 377        i2c_set_clientdata(i2c, sec_pmic);
 378        sec_pmic->dev = &i2c->dev;
 379        sec_pmic->i2c = i2c;
 380        sec_pmic->irq = i2c->irq;
 381        device_type = sec_i2c_get_driver_data(i2c, id);
 382
 383        if (sec_pmic->dev->of_node) {
 384                pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev);
 385                if (IS_ERR(pdata)) {
 386                        ret = PTR_ERR(pdata);
 387                        return ret;
 388                }
 389                pdata->device_type = device_type;
 390        }
 391        if (pdata) {
 392                sec_pmic->device_type = pdata->device_type;
 393                sec_pmic->irq_base = pdata->irq_base;
 394                sec_pmic->wakeup = pdata->wakeup;
 395                sec_pmic->pdata = pdata;
 396        }
 397
 398        switch (sec_pmic->device_type) {
 399        case S2MPA01:
 400                regmap = &s2mpa01_regmap_config;
 401                break;
 402        case S2MPS11X:
 403                regmap = &s2mps11_regmap_config;
 404                break;
 405        case S2MPS13X:
 406                regmap = &s2mps13_regmap_config;
 407                break;
 408        case S2MPS14X:
 409                regmap = &s2mps14_regmap_config;
 410                break;
 411        case S2MPS15X:
 412                regmap = &s2mps15_regmap_config;
 413                break;
 414        case S5M8763X:
 415                regmap = &s5m8763_regmap_config;
 416                break;
 417        case S5M8767X:
 418                regmap = &s5m8767_regmap_config;
 419                break;
 420        case S2MPU02:
 421                regmap = &s2mpu02_regmap_config;
 422                break;
 423        default:
 424                regmap = &sec_regmap_config;
 425                break;
 426        }
 427
 428        sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
 429        if (IS_ERR(sec_pmic->regmap_pmic)) {
 430                ret = PTR_ERR(sec_pmic->regmap_pmic);
 431                dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
 432                        ret);
 433                return ret;
 434        }
 435
 436        if (pdata && pdata->cfg_pmic_irq)
 437                pdata->cfg_pmic_irq();
 438
 439        sec_irq_init(sec_pmic);
 440
 441        pm_runtime_set_active(sec_pmic->dev);
 442
 443        switch (sec_pmic->device_type) {
 444        case S5M8751X:
 445                sec_devs = s5m8751_devs;
 446                num_sec_devs = ARRAY_SIZE(s5m8751_devs);
 447                break;
 448        case S5M8763X:
 449                sec_devs = s5m8763_devs;
 450                num_sec_devs = ARRAY_SIZE(s5m8763_devs);
 451                break;
 452        case S5M8767X:
 453                sec_devs = s5m8767_devs;
 454                num_sec_devs = ARRAY_SIZE(s5m8767_devs);
 455                break;
 456        case S2MPA01:
 457                sec_devs = s2mpa01_devs;
 458                num_sec_devs = ARRAY_SIZE(s2mpa01_devs);
 459                break;
 460        case S2MPS11X:
 461                sec_devs = s2mps11_devs;
 462                num_sec_devs = ARRAY_SIZE(s2mps11_devs);
 463                break;
 464        case S2MPS13X:
 465                sec_devs = s2mps13_devs;
 466                num_sec_devs = ARRAY_SIZE(s2mps13_devs);
 467                break;
 468        case S2MPS14X:
 469                sec_devs = s2mps14_devs;
 470                num_sec_devs = ARRAY_SIZE(s2mps14_devs);
 471                break;
 472        case S2MPS15X:
 473                sec_devs = s2mps15_devs;
 474                num_sec_devs = ARRAY_SIZE(s2mps15_devs);
 475                break;
 476        case S2MPU02:
 477                sec_devs = s2mpu02_devs;
 478                num_sec_devs = ARRAY_SIZE(s2mpu02_devs);
 479                break;
 480        default:
 481                /* If this happens the probe function is problem */
 482                BUG();
 483        }
 484        ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
 485                                   NULL, 0, NULL);
 486        if (ret)
 487                return ret;
 488
 489        device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
 490        sec_pmic_configure(sec_pmic);
 491        sec_pmic_dump_rev(sec_pmic);
 492
 493        return ret;
 494}
 495
 496static void sec_pmic_shutdown(struct i2c_client *i2c)
 497{
 498        struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
 499        unsigned int reg, mask;
 500
 501        if (!sec_pmic->pdata->manual_poweroff)
 502                return;
 503
 504        switch (sec_pmic->device_type) {
 505        case S2MPS11X:
 506                reg = S2MPS11_REG_CTRL1;
 507                mask = S2MPS11_CTRL1_PWRHOLD_MASK;
 508                break;
 509        default:
 510                /*
 511                 * Currently only one board with S2MPS11 needs this, so just
 512                 * ignore the rest.
 513                 */
 514                dev_warn(sec_pmic->dev,
 515                        "Unsupported device %lu for manual power off\n",
 516                        sec_pmic->device_type);
 517                return;
 518        }
 519
 520        regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
 521}
 522
 523#ifdef CONFIG_PM_SLEEP
 524static int sec_pmic_suspend(struct device *dev)
 525{
 526        struct i2c_client *i2c = to_i2c_client(dev);
 527        struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
 528
 529        if (device_may_wakeup(dev))
 530                enable_irq_wake(sec_pmic->irq);
 531        /*
 532         * PMIC IRQ must be disabled during suspend for RTC alarm
 533         * to work properly.
 534         * When device is woken up from suspend, an
 535         * interrupt occurs before resuming I2C bus controller.
 536         * The interrupt is handled by regmap_irq_thread which tries
 537         * to read RTC registers. This read fails (I2C is still
 538         * suspended) and RTC Alarm interrupt is disabled.
 539         */
 540        disable_irq(sec_pmic->irq);
 541
 542        return 0;
 543}
 544
 545static int sec_pmic_resume(struct device *dev)
 546{
 547        struct i2c_client *i2c = to_i2c_client(dev);
 548        struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
 549
 550        if (device_may_wakeup(dev))
 551                disable_irq_wake(sec_pmic->irq);
 552        enable_irq(sec_pmic->irq);
 553
 554        return 0;
 555}
 556#endif /* CONFIG_PM_SLEEP */
 557
 558static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
 559
 560static const struct i2c_device_id sec_pmic_id[] = {
 561        { "sec_pmic", 0 },
 562        { }
 563};
 564MODULE_DEVICE_TABLE(i2c, sec_pmic_id);
 565
 566static struct i2c_driver sec_pmic_driver = {
 567        .driver = {
 568                   .name = "sec_pmic",
 569                   .pm = &sec_pmic_pm_ops,
 570                   .of_match_table = of_match_ptr(sec_dt_match),
 571        },
 572        .probe = sec_pmic_probe,
 573        .shutdown = sec_pmic_shutdown,
 574        .id_table = sec_pmic_id,
 575};
 576
 577static int __init sec_pmic_init(void)
 578{
 579        return i2c_add_driver(&sec_pmic_driver);
 580}
 581
 582subsys_initcall(sec_pmic_init);
 583
 584static void __exit sec_pmic_exit(void)
 585{
 586        i2c_del_driver(&sec_pmic_driver);
 587}
 588module_exit(sec_pmic_exit);
 589
 590MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
 591MODULE_DESCRIPTION("Core support for the S5M MFD");
 592MODULE_LICENSE("GPL");
 593