linux/drivers/mfd/stmfx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Driver for STMicroelectronics Multi-Function eXpander (STMFX) core
   4 *
   5 * Copyright (C) 2019 STMicroelectronics
   6 * Author(s): Amelie Delaunay <amelie.delaunay@st.com>.
   7 */
   8#include <linux/bitfield.h>
   9#include <linux/i2c.h>
  10#include <linux/interrupt.h>
  11#include <linux/irq.h>
  12#include <linux/mfd/core.h>
  13#include <linux/mfd/stmfx.h>
  14#include <linux/module.h>
  15#include <linux/regulator/consumer.h>
  16
  17static bool stmfx_reg_volatile(struct device *dev, unsigned int reg)
  18{
  19        switch (reg) {
  20        case STMFX_REG_SYS_CTRL:
  21        case STMFX_REG_IRQ_SRC_EN:
  22        case STMFX_REG_IRQ_PENDING:
  23        case STMFX_REG_IRQ_GPI_PENDING1:
  24        case STMFX_REG_IRQ_GPI_PENDING2:
  25        case STMFX_REG_IRQ_GPI_PENDING3:
  26        case STMFX_REG_GPIO_STATE1:
  27        case STMFX_REG_GPIO_STATE2:
  28        case STMFX_REG_GPIO_STATE3:
  29        case STMFX_REG_IRQ_GPI_SRC1:
  30        case STMFX_REG_IRQ_GPI_SRC2:
  31        case STMFX_REG_IRQ_GPI_SRC3:
  32        case STMFX_REG_GPO_SET1:
  33        case STMFX_REG_GPO_SET2:
  34        case STMFX_REG_GPO_SET3:
  35        case STMFX_REG_GPO_CLR1:
  36        case STMFX_REG_GPO_CLR2:
  37        case STMFX_REG_GPO_CLR3:
  38                return true;
  39        default:
  40                return false;
  41        }
  42}
  43
  44static bool stmfx_reg_writeable(struct device *dev, unsigned int reg)
  45{
  46        return (reg >= STMFX_REG_SYS_CTRL);
  47}
  48
  49static const struct regmap_config stmfx_regmap_config = {
  50        .reg_bits       = 8,
  51        .reg_stride     = 1,
  52        .val_bits       = 8,
  53        .max_register   = STMFX_REG_MAX,
  54        .volatile_reg   = stmfx_reg_volatile,
  55        .writeable_reg  = stmfx_reg_writeable,
  56        .cache_type     = REGCACHE_RBTREE,
  57};
  58
  59static const struct resource stmfx_pinctrl_resources[] = {
  60        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_GPIO),
  61};
  62
  63static const struct resource stmfx_idd_resources[] = {
  64        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_IDD),
  65        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_ERROR),
  66};
  67
  68static const struct resource stmfx_ts_resources[] = {
  69        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_DET),
  70        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_NE),
  71        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_TH),
  72        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_FULL),
  73        DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_OVF),
  74};
  75
  76static struct mfd_cell stmfx_cells[] = {
  77        {
  78                .of_compatible = "st,stmfx-0300-pinctrl",
  79                .name = "stmfx-pinctrl",
  80                .resources = stmfx_pinctrl_resources,
  81                .num_resources = ARRAY_SIZE(stmfx_pinctrl_resources),
  82        },
  83        {
  84                .of_compatible = "st,stmfx-0300-idd",
  85                .name = "stmfx-idd",
  86                .resources = stmfx_idd_resources,
  87                .num_resources = ARRAY_SIZE(stmfx_idd_resources),
  88        },
  89        {
  90                .of_compatible = "st,stmfx-0300-ts",
  91                .name = "stmfx-ts",
  92                .resources = stmfx_ts_resources,
  93                .num_resources = ARRAY_SIZE(stmfx_ts_resources),
  94        },
  95};
  96
  97static u8 stmfx_func_to_mask(u32 func)
  98{
  99        u8 mask = 0;
 100
 101        if (func & STMFX_FUNC_GPIO)
 102                mask |= STMFX_REG_SYS_CTRL_GPIO_EN;
 103
 104        if ((func & STMFX_FUNC_ALTGPIO_LOW) || (func & STMFX_FUNC_ALTGPIO_HIGH))
 105                mask |= STMFX_REG_SYS_CTRL_ALTGPIO_EN;
 106
 107        if (func & STMFX_FUNC_TS)
 108                mask |= STMFX_REG_SYS_CTRL_TS_EN;
 109
 110        if (func & STMFX_FUNC_IDD)
 111                mask |= STMFX_REG_SYS_CTRL_IDD_EN;
 112
 113        return mask;
 114}
 115
 116int stmfx_function_enable(struct stmfx *stmfx, u32 func)
 117{
 118        u32 sys_ctrl;
 119        u8 mask;
 120        int ret;
 121
 122        ret = regmap_read(stmfx->map, STMFX_REG_SYS_CTRL, &sys_ctrl);
 123        if (ret)
 124                return ret;
 125
 126        /*
 127         * IDD and TS have priority in STMFX FW, so if IDD and TS are enabled,
 128         * ALTGPIO function is disabled by STMFX FW. If IDD or TS is enabled,
 129         * the number of aGPIO available decreases. To avoid GPIO management
 130         * disturbance, abort IDD or TS function enable in this case.
 131         */
 132        if (((func & STMFX_FUNC_IDD) || (func & STMFX_FUNC_TS)) &&
 133            (sys_ctrl & STMFX_REG_SYS_CTRL_ALTGPIO_EN)) {
 134                dev_err(stmfx->dev, "ALTGPIO function already enabled\n");
 135                return -EBUSY;
 136        }
 137
 138        /* If TS is enabled, aGPIO[3:0] cannot be used */
 139        if ((func & STMFX_FUNC_ALTGPIO_LOW) &&
 140            (sys_ctrl & STMFX_REG_SYS_CTRL_TS_EN)) {
 141                dev_err(stmfx->dev, "TS in use, aGPIO[3:0] unavailable\n");
 142                return -EBUSY;
 143        }
 144
 145        /* If IDD is enabled, aGPIO[7:4] cannot be used */
 146        if ((func & STMFX_FUNC_ALTGPIO_HIGH) &&
 147            (sys_ctrl & STMFX_REG_SYS_CTRL_IDD_EN)) {
 148                dev_err(stmfx->dev, "IDD in use, aGPIO[7:4] unavailable\n");
 149                return -EBUSY;
 150        }
 151
 152        mask = stmfx_func_to_mask(func);
 153
 154        return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, mask);
 155}
 156EXPORT_SYMBOL_GPL(stmfx_function_enable);
 157
 158int stmfx_function_disable(struct stmfx *stmfx, u32 func)
 159{
 160        u8 mask = stmfx_func_to_mask(func);
 161
 162        return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, 0);
 163}
 164EXPORT_SYMBOL_GPL(stmfx_function_disable);
 165
 166static void stmfx_irq_bus_lock(struct irq_data *data)
 167{
 168        struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
 169
 170        mutex_lock(&stmfx->lock);
 171}
 172
 173static void stmfx_irq_bus_sync_unlock(struct irq_data *data)
 174{
 175        struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
 176
 177        regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, stmfx->irq_src);
 178
 179        mutex_unlock(&stmfx->lock);
 180}
 181
 182static void stmfx_irq_mask(struct irq_data *data)
 183{
 184        struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
 185
 186        stmfx->irq_src &= ~BIT(data->hwirq % 8);
 187}
 188
 189static void stmfx_irq_unmask(struct irq_data *data)
 190{
 191        struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
 192
 193        stmfx->irq_src |= BIT(data->hwirq % 8);
 194}
 195
 196static struct irq_chip stmfx_irq_chip = {
 197        .name                   = "stmfx-core",
 198        .irq_bus_lock           = stmfx_irq_bus_lock,
 199        .irq_bus_sync_unlock    = stmfx_irq_bus_sync_unlock,
 200        .irq_mask               = stmfx_irq_mask,
 201        .irq_unmask             = stmfx_irq_unmask,
 202};
 203
 204static irqreturn_t stmfx_irq_handler(int irq, void *data)
 205{
 206        struct stmfx *stmfx = data;
 207        unsigned long bits;
 208        u32 pending, ack;
 209        int n, ret;
 210
 211        ret = regmap_read(stmfx->map, STMFX_REG_IRQ_PENDING, &pending);
 212        if (ret)
 213                return IRQ_NONE;
 214
 215        /*
 216         * There is no ACK for GPIO, MFX_REG_IRQ_PENDING_GPIO is a logical OR
 217         * of MFX_REG_IRQ_GPI _PENDING1/_PENDING2/_PENDING3
 218         */
 219        ack = pending & ~BIT(STMFX_REG_IRQ_SRC_EN_GPIO);
 220        if (ack) {
 221                ret = regmap_write(stmfx->map, STMFX_REG_IRQ_ACK, ack);
 222                if (ret)
 223                        return IRQ_NONE;
 224        }
 225
 226        bits = pending;
 227        for_each_set_bit(n, &bits, STMFX_REG_IRQ_SRC_MAX)
 228                handle_nested_irq(irq_find_mapping(stmfx->irq_domain, n));
 229
 230        return IRQ_HANDLED;
 231}
 232
 233static int stmfx_irq_map(struct irq_domain *d, unsigned int virq,
 234                         irq_hw_number_t hwirq)
 235{
 236        irq_set_chip_data(virq, d->host_data);
 237        irq_set_chip_and_handler(virq, &stmfx_irq_chip, handle_simple_irq);
 238        irq_set_nested_thread(virq, 1);
 239        irq_set_noprobe(virq);
 240
 241        return 0;
 242}
 243
 244static void stmfx_irq_unmap(struct irq_domain *d, unsigned int virq)
 245{
 246        irq_set_chip_and_handler(virq, NULL, NULL);
 247        irq_set_chip_data(virq, NULL);
 248}
 249
 250static const struct irq_domain_ops stmfx_irq_ops = {
 251        .map    = stmfx_irq_map,
 252        .unmap  = stmfx_irq_unmap,
 253};
 254
 255static void stmfx_irq_exit(struct i2c_client *client)
 256{
 257        struct stmfx *stmfx = i2c_get_clientdata(client);
 258        int hwirq;
 259
 260        for (hwirq = 0; hwirq < STMFX_REG_IRQ_SRC_MAX; hwirq++)
 261                irq_dispose_mapping(irq_find_mapping(stmfx->irq_domain, hwirq));
 262
 263        irq_domain_remove(stmfx->irq_domain);
 264}
 265
 266static int stmfx_irq_init(struct i2c_client *client)
 267{
 268        struct stmfx *stmfx = i2c_get_clientdata(client);
 269        u32 irqoutpin = 0, irqtrigger;
 270        int ret;
 271
 272        stmfx->irq_domain = irq_domain_add_simple(stmfx->dev->of_node,
 273                                                  STMFX_REG_IRQ_SRC_MAX, 0,
 274                                                  &stmfx_irq_ops, stmfx);
 275        if (!stmfx->irq_domain) {
 276                dev_err(stmfx->dev, "Failed to create IRQ domain\n");
 277                return -EINVAL;
 278        }
 279
 280        if (!of_property_read_bool(stmfx->dev->of_node, "drive-open-drain"))
 281                irqoutpin |= STMFX_REG_IRQ_OUT_PIN_TYPE;
 282
 283        irqtrigger = irq_get_trigger_type(client->irq);
 284        if ((irqtrigger & IRQ_TYPE_EDGE_RISING) ||
 285            (irqtrigger & IRQ_TYPE_LEVEL_HIGH))
 286                irqoutpin |= STMFX_REG_IRQ_OUT_PIN_POL;
 287
 288        ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin);
 289        if (ret)
 290                return ret;
 291
 292        ret = devm_request_threaded_irq(stmfx->dev, client->irq,
 293                                        NULL, stmfx_irq_handler,
 294                                        irqtrigger | IRQF_ONESHOT,
 295                                        "stmfx", stmfx);
 296        if (ret)
 297                stmfx_irq_exit(client);
 298
 299        return ret;
 300}
 301
 302static int stmfx_chip_reset(struct stmfx *stmfx)
 303{
 304        int ret;
 305
 306        ret = regmap_write(stmfx->map, STMFX_REG_SYS_CTRL,
 307                           STMFX_REG_SYS_CTRL_SWRST);
 308        if (ret)
 309                return ret;
 310
 311        msleep(STMFX_BOOT_TIME_MS);
 312
 313        return ret;
 314}
 315
 316static int stmfx_chip_init(struct i2c_client *client)
 317{
 318        struct stmfx *stmfx = i2c_get_clientdata(client);
 319        u32 id;
 320        u8 version[2];
 321        int ret;
 322
 323        stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd");
 324        ret = PTR_ERR_OR_ZERO(stmfx->vdd);
 325        if (ret == -ENODEV) {
 326                stmfx->vdd = NULL;
 327        } else if (ret == -EPROBE_DEFER) {
 328                return ret;
 329        } else if (ret) {
 330                dev_err(&client->dev, "Failed to get VDD regulator: %d\n", ret);
 331                return ret;
 332        }
 333
 334        if (stmfx->vdd) {
 335                ret = regulator_enable(stmfx->vdd);
 336                if (ret) {
 337                        dev_err(&client->dev, "VDD enable failed: %d\n", ret);
 338                        return ret;
 339                }
 340        }
 341
 342        ret = regmap_read(stmfx->map, STMFX_REG_CHIP_ID, &id);
 343        if (ret) {
 344                dev_err(&client->dev, "Error reading chip ID: %d\n", ret);
 345                goto err;
 346        }
 347
 348        /*
 349         * Check that ID is the complement of the I2C address:
 350         * STMFX I2C address follows the 7-bit format (MSB), that's why
 351         * client->addr is shifted.
 352         *
 353         * STMFX_I2C_ADDR|       STMFX         |        Linux
 354         *   input pin   | I2C device address  | I2C device address
 355         *---------------------------------------------------------
 356         *       0       | b: 1000 010x h:0x84 |       0x42
 357         *       1       | b: 1000 011x h:0x86 |       0x43
 358         */
 359        if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (client->addr << 1)) {
 360                dev_err(&client->dev, "Unknown chip ID: %#x\n", id);
 361                ret = -EINVAL;
 362                goto err;
 363        }
 364
 365        ret = regmap_bulk_read(stmfx->map, STMFX_REG_FW_VERSION_MSB,
 366                               version, ARRAY_SIZE(version));
 367        if (ret) {
 368                dev_err(&client->dev, "Error reading FW version: %d\n", ret);
 369                goto err;
 370        }
 371
 372        dev_info(&client->dev, "STMFX id: %#x, fw version: %x.%02x\n",
 373                 id, version[0], version[1]);
 374
 375        ret = stmfx_chip_reset(stmfx);
 376        if (ret) {
 377                dev_err(&client->dev, "Failed to reset chip: %d\n", ret);
 378                goto err;
 379        }
 380
 381        return 0;
 382
 383err:
 384        if (stmfx->vdd)
 385                return regulator_disable(stmfx->vdd);
 386
 387        return ret;
 388}
 389
 390static int stmfx_chip_exit(struct i2c_client *client)
 391{
 392        struct stmfx *stmfx = i2c_get_clientdata(client);
 393
 394        regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0);
 395        regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0);
 396
 397        if (stmfx->vdd)
 398                return regulator_disable(stmfx->vdd);
 399
 400        return 0;
 401}
 402
 403static int stmfx_probe(struct i2c_client *client,
 404                       const struct i2c_device_id *id)
 405{
 406        struct device *dev = &client->dev;
 407        struct stmfx *stmfx;
 408        int ret;
 409
 410        stmfx = devm_kzalloc(dev, sizeof(*stmfx), GFP_KERNEL);
 411        if (!stmfx)
 412                return -ENOMEM;
 413
 414        i2c_set_clientdata(client, stmfx);
 415
 416        stmfx->dev = dev;
 417
 418        stmfx->map = devm_regmap_init_i2c(client, &stmfx_regmap_config);
 419        if (IS_ERR(stmfx->map)) {
 420                ret = PTR_ERR(stmfx->map);
 421                dev_err(dev, "Failed to allocate register map: %d\n", ret);
 422                return ret;
 423        }
 424
 425        mutex_init(&stmfx->lock);
 426
 427        ret = stmfx_chip_init(client);
 428        if (ret) {
 429                if (ret == -ETIMEDOUT)
 430                        return -EPROBE_DEFER;
 431                return ret;
 432        }
 433
 434        if (client->irq < 0) {
 435                dev_err(dev, "Failed to get IRQ: %d\n", client->irq);
 436                ret = client->irq;
 437                goto err_chip_exit;
 438        }
 439
 440        ret = stmfx_irq_init(client);
 441        if (ret)
 442                goto err_chip_exit;
 443
 444        ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
 445                                   stmfx_cells, ARRAY_SIZE(stmfx_cells), NULL,
 446                                   0, stmfx->irq_domain);
 447        if (ret)
 448                goto err_irq_exit;
 449
 450        return 0;
 451
 452err_irq_exit:
 453        stmfx_irq_exit(client);
 454err_chip_exit:
 455        stmfx_chip_exit(client);
 456
 457        return ret;
 458}
 459
 460static int stmfx_remove(struct i2c_client *client)
 461{
 462        stmfx_irq_exit(client);
 463
 464        return stmfx_chip_exit(client);
 465}
 466
 467#ifdef CONFIG_PM_SLEEP
 468static int stmfx_suspend(struct device *dev)
 469{
 470        struct stmfx *stmfx = dev_get_drvdata(dev);
 471        int ret;
 472
 473        ret = regmap_raw_read(stmfx->map, STMFX_REG_SYS_CTRL,
 474                              &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl));
 475        if (ret)
 476                return ret;
 477
 478        ret = regmap_raw_read(stmfx->map, STMFX_REG_IRQ_OUT_PIN,
 479                              &stmfx->bkp_irqoutpin,
 480                              sizeof(stmfx->bkp_irqoutpin));
 481        if (ret)
 482                return ret;
 483
 484        if (stmfx->vdd)
 485                return regulator_disable(stmfx->vdd);
 486
 487        return 0;
 488}
 489
 490static int stmfx_resume(struct device *dev)
 491{
 492        struct stmfx *stmfx = dev_get_drvdata(dev);
 493        int ret;
 494
 495        if (stmfx->vdd) {
 496                ret = regulator_enable(stmfx->vdd);
 497                if (ret) {
 498                        dev_err(stmfx->dev,
 499                                "VDD enable failed: %d\n", ret);
 500                        return ret;
 501                }
 502        }
 503
 504        ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL,
 505                               &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl));
 506        if (ret)
 507                return ret;
 508
 509        ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN,
 510                               &stmfx->bkp_irqoutpin,
 511                               sizeof(stmfx->bkp_irqoutpin));
 512        if (ret)
 513                return ret;
 514
 515        ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_SRC_EN,
 516                               &stmfx->irq_src, sizeof(stmfx->irq_src));
 517        if (ret)
 518                return ret;
 519
 520        return 0;
 521}
 522#endif
 523
 524static SIMPLE_DEV_PM_OPS(stmfx_dev_pm_ops, stmfx_suspend, stmfx_resume);
 525
 526static const struct of_device_id stmfx_of_match[] = {
 527        { .compatible = "st,stmfx-0300", },
 528        {},
 529};
 530MODULE_DEVICE_TABLE(of, stmfx_of_match);
 531
 532static struct i2c_driver stmfx_driver = {
 533        .driver = {
 534                .name = "stmfx-core",
 535                .of_match_table = of_match_ptr(stmfx_of_match),
 536                .pm = &stmfx_dev_pm_ops,
 537        },
 538        .probe = stmfx_probe,
 539        .remove = stmfx_remove,
 540};
 541module_i2c_driver(stmfx_driver);
 542
 543MODULE_DESCRIPTION("STMFX core driver");
 544MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay@st.com>");
 545MODULE_LICENSE("GPL v2");
 546