root/drivers/gpio/gpio-crystalcove.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_reg
  2. crystalcove_update_irq_mask
  3. crystalcove_update_irq_ctrl
  4. crystalcove_gpio_dir_in
  5. crystalcove_gpio_dir_out
  6. crystalcove_gpio_get
  7. crystalcove_gpio_set
  8. crystalcove_irq_type
  9. crystalcove_bus_lock
  10. crystalcove_bus_sync_unlock
  11. crystalcove_irq_unmask
  12. crystalcove_irq_mask
  13. crystalcove_gpio_irq_handler
  14. crystalcove_gpio_dbg_show
  15. crystalcove_gpio_probe
  16. crystalcove_gpio_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Intel Crystal Cove GPIO Driver
   4  *
   5  * Copyright (C) 2012, 2014 Intel Corporation. All rights reserved.
   6  *
   7  * Author: Yang, Bin <bin.yang@intel.com>
   8  */
   9 
  10 #include <linux/bitops.h>
  11 #include <linux/gpio/driver.h>
  12 #include <linux/interrupt.h>
  13 #include <linux/mfd/intel_soc_pmic.h>
  14 #include <linux/module.h>
  15 #include <linux/platform_device.h>
  16 #include <linux/regmap.h>
  17 #include <linux/seq_file.h>
  18 
  19 #define CRYSTALCOVE_GPIO_NUM    16
  20 #define CRYSTALCOVE_VGPIO_NUM   95
  21 
  22 #define UPDATE_IRQ_TYPE         BIT(0)
  23 #define UPDATE_IRQ_MASK         BIT(1)
  24 
  25 #define GPIO0IRQ                0x0b
  26 #define GPIO1IRQ                0x0c
  27 #define MGPIO0IRQS0             0x19
  28 #define MGPIO1IRQS0             0x1a
  29 #define MGPIO0IRQSX             0x1b
  30 #define MGPIO1IRQSX             0x1c
  31 #define GPIO0P0CTLO             0x2b
  32 #define GPIO0P0CTLI             0x33
  33 #define GPIO1P0CTLO             0x3b
  34 #define GPIO1P0CTLI             0x43
  35 #define GPIOPANELCTL            0x52
  36 
  37 #define CTLI_INTCNT_DIS         (0)
  38 #define CTLI_INTCNT_NE          (1 << 1)
  39 #define CTLI_INTCNT_PE          (2 << 1)
  40 #define CTLI_INTCNT_BE          (3 << 1)
  41 
  42 #define CTLO_DIR_IN             (0)
  43 #define CTLO_DIR_OUT            (1 << 5)
  44 
  45 #define CTLO_DRV_CMOS           (0)
  46 #define CTLO_DRV_OD             (1 << 4)
  47 
  48 #define CTLO_DRV_REN            (1 << 3)
  49 
  50 #define CTLO_RVAL_2KDW          (0)
  51 #define CTLO_RVAL_2KUP          (1 << 1)
  52 #define CTLO_RVAL_50KDW         (2 << 1)
  53 #define CTLO_RVAL_50KUP         (3 << 1)
  54 
  55 #define CTLO_INPUT_SET  (CTLO_DRV_CMOS | CTLO_DRV_REN | CTLO_RVAL_2KUP)
  56 #define CTLO_OUTPUT_SET (CTLO_DIR_OUT | CTLO_INPUT_SET)
  57 
  58 enum ctrl_register {
  59         CTRL_IN,
  60         CTRL_OUT,
  61 };
  62 
  63 /**
  64  * struct crystalcove_gpio - Crystal Cove GPIO controller
  65  * @buslock: for bus lock/sync and unlock.
  66  * @chip: the abstract gpio_chip structure.
  67  * @regmap: the regmap from the parent device.
  68  * @update: pending IRQ setting update, to be written to the chip upon unlock.
  69  * @intcnt_value: the Interrupt Detect value to be written.
  70  * @set_irq_mask: true if the IRQ mask needs to be set, false to clear.
  71  */
  72 struct crystalcove_gpio {
  73         struct mutex buslock; /* irq_bus_lock */
  74         struct gpio_chip chip;
  75         struct regmap *regmap;
  76         int update;
  77         int intcnt_value;
  78         bool set_irq_mask;
  79 };
  80 
  81 static inline int to_reg(int gpio, enum ctrl_register reg_type)
  82 {
  83         int reg;
  84 
  85         if (gpio >= CRYSTALCOVE_GPIO_NUM) {
  86                 /*
  87                  * Virtual GPIO called from ACPI, for now we only support
  88                  * the panel ctl.
  89                  */
  90                 switch (gpio) {
  91                 case 0x5e:
  92                         return GPIOPANELCTL;
  93                 default:
  94                         return -EOPNOTSUPP;
  95                 }
  96         }
  97 
  98         if (reg_type == CTRL_IN) {
  99                 if (gpio < 8)
 100                         reg = GPIO0P0CTLI;
 101                 else
 102                         reg = GPIO1P0CTLI;
 103         } else {
 104                 if (gpio < 8)
 105                         reg = GPIO0P0CTLO;
 106                 else
 107                         reg = GPIO1P0CTLO;
 108         }
 109 
 110         return reg + gpio % 8;
 111 }
 112 
 113 static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg,
 114                                         int gpio)
 115 {
 116         u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0;
 117         int mask = BIT(gpio % 8);
 118 
 119         if (cg->set_irq_mask)
 120                 regmap_update_bits(cg->regmap, mirqs0, mask, mask);
 121         else
 122                 regmap_update_bits(cg->regmap, mirqs0, mask, 0);
 123 }
 124 
 125 static void crystalcove_update_irq_ctrl(struct crystalcove_gpio *cg, int gpio)
 126 {
 127         int reg = to_reg(gpio, CTRL_IN);
 128 
 129         regmap_update_bits(cg->regmap, reg, CTLI_INTCNT_BE, cg->intcnt_value);
 130 }
 131 
 132 static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio)
 133 {
 134         struct crystalcove_gpio *cg = gpiochip_get_data(chip);
 135         int reg = to_reg(gpio, CTRL_OUT);
 136 
 137         if (reg < 0)
 138                 return 0;
 139 
 140         return regmap_write(cg->regmap, reg, CTLO_INPUT_SET);
 141 }
 142 
 143 static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio,
 144                                     int value)
 145 {
 146         struct crystalcove_gpio *cg = gpiochip_get_data(chip);
 147         int reg = to_reg(gpio, CTRL_OUT);
 148 
 149         if (reg < 0)
 150                 return 0;
 151 
 152         return regmap_write(cg->regmap, reg, CTLO_OUTPUT_SET | value);
 153 }
 154 
 155 static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio)
 156 {
 157         struct crystalcove_gpio *cg = gpiochip_get_data(chip);
 158         unsigned int val;
 159         int ret, reg = to_reg(gpio, CTRL_IN);
 160 
 161         if (reg < 0)
 162                 return 0;
 163 
 164         ret = regmap_read(cg->regmap, reg, &val);
 165         if (ret)
 166                 return ret;
 167 
 168         return val & 0x1;
 169 }
 170 
 171 static void crystalcove_gpio_set(struct gpio_chip *chip,
 172                                  unsigned gpio, int value)
 173 {
 174         struct crystalcove_gpio *cg = gpiochip_get_data(chip);
 175         int reg = to_reg(gpio, CTRL_OUT);
 176 
 177         if (reg < 0)
 178                 return;
 179 
 180         if (value)
 181                 regmap_update_bits(cg->regmap, reg, 1, 1);
 182         else
 183                 regmap_update_bits(cg->regmap, reg, 1, 0);
 184 }
 185 
 186 static int crystalcove_irq_type(struct irq_data *data, unsigned type)
 187 {
 188         struct crystalcove_gpio *cg =
 189                 gpiochip_get_data(irq_data_get_irq_chip_data(data));
 190 
 191         if (data->hwirq >= CRYSTALCOVE_GPIO_NUM)
 192                 return 0;
 193 
 194         switch (type) {
 195         case IRQ_TYPE_NONE:
 196                 cg->intcnt_value = CTLI_INTCNT_DIS;
 197                 break;
 198         case IRQ_TYPE_EDGE_BOTH:
 199                 cg->intcnt_value = CTLI_INTCNT_BE;
 200                 break;
 201         case IRQ_TYPE_EDGE_RISING:
 202                 cg->intcnt_value = CTLI_INTCNT_PE;
 203                 break;
 204         case IRQ_TYPE_EDGE_FALLING:
 205                 cg->intcnt_value = CTLI_INTCNT_NE;
 206                 break;
 207         default:
 208                 return -EINVAL;
 209         }
 210 
 211         cg->update |= UPDATE_IRQ_TYPE;
 212 
 213         return 0;
 214 }
 215 
 216 static void crystalcove_bus_lock(struct irq_data *data)
 217 {
 218         struct crystalcove_gpio *cg =
 219                 gpiochip_get_data(irq_data_get_irq_chip_data(data));
 220 
 221         mutex_lock(&cg->buslock);
 222 }
 223 
 224 static void crystalcove_bus_sync_unlock(struct irq_data *data)
 225 {
 226         struct crystalcove_gpio *cg =
 227                 gpiochip_get_data(irq_data_get_irq_chip_data(data));
 228         int gpio = data->hwirq;
 229 
 230         if (cg->update & UPDATE_IRQ_TYPE)
 231                 crystalcove_update_irq_ctrl(cg, gpio);
 232         if (cg->update & UPDATE_IRQ_MASK)
 233                 crystalcove_update_irq_mask(cg, gpio);
 234         cg->update = 0;
 235 
 236         mutex_unlock(&cg->buslock);
 237 }
 238 
 239 static void crystalcove_irq_unmask(struct irq_data *data)
 240 {
 241         struct crystalcove_gpio *cg =
 242                 gpiochip_get_data(irq_data_get_irq_chip_data(data));
 243 
 244         if (data->hwirq < CRYSTALCOVE_GPIO_NUM) {
 245                 cg->set_irq_mask = false;
 246                 cg->update |= UPDATE_IRQ_MASK;
 247         }
 248 }
 249 
 250 static void crystalcove_irq_mask(struct irq_data *data)
 251 {
 252         struct crystalcove_gpio *cg =
 253                 gpiochip_get_data(irq_data_get_irq_chip_data(data));
 254 
 255         if (data->hwirq < CRYSTALCOVE_GPIO_NUM) {
 256                 cg->set_irq_mask = true;
 257                 cg->update |= UPDATE_IRQ_MASK;
 258         }
 259 }
 260 
 261 static struct irq_chip crystalcove_irqchip = {
 262         .name                   = "Crystal Cove",
 263         .irq_mask               = crystalcove_irq_mask,
 264         .irq_unmask             = crystalcove_irq_unmask,
 265         .irq_set_type           = crystalcove_irq_type,
 266         .irq_bus_lock           = crystalcove_bus_lock,
 267         .irq_bus_sync_unlock    = crystalcove_bus_sync_unlock,
 268         .flags                  = IRQCHIP_SKIP_SET_WAKE,
 269 };
 270 
 271 static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
 272 {
 273         struct crystalcove_gpio *cg = data;
 274         unsigned long pending;
 275         unsigned int p0, p1;
 276         int gpio;
 277         unsigned int virq;
 278 
 279         if (regmap_read(cg->regmap, GPIO0IRQ, &p0) ||
 280             regmap_read(cg->regmap, GPIO1IRQ, &p1))
 281                 return IRQ_NONE;
 282 
 283         regmap_write(cg->regmap, GPIO0IRQ, p0);
 284         regmap_write(cg->regmap, GPIO1IRQ, p1);
 285 
 286         pending = p0 | p1 << 8;
 287 
 288         for_each_set_bit(gpio, &pending, CRYSTALCOVE_GPIO_NUM) {
 289                 virq = irq_find_mapping(cg->chip.irq.domain, gpio);
 290                 handle_nested_irq(virq);
 291         }
 292 
 293         return IRQ_HANDLED;
 294 }
 295 
 296 static void crystalcove_gpio_dbg_show(struct seq_file *s,
 297                                       struct gpio_chip *chip)
 298 {
 299         struct crystalcove_gpio *cg = gpiochip_get_data(chip);
 300         int gpio, offset;
 301         unsigned int ctlo, ctli, mirqs0, mirqsx, irq;
 302 
 303         for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) {
 304                 regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo);
 305                 regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli);
 306                 regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0,
 307                             &mirqs0);
 308                 regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQSX : MGPIO1IRQSX,
 309                             &mirqsx);
 310                 regmap_read(cg->regmap, gpio < 8 ? GPIO0IRQ : GPIO1IRQ,
 311                             &irq);
 312 
 313                 offset = gpio % 8;
 314                 seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s %s\n",
 315                            gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ",
 316                            ctli & 0x1 ? "hi" : "lo",
 317                            ctli & CTLI_INTCNT_NE ? "fall" : "    ",
 318                            ctli & CTLI_INTCNT_PE ? "rise" : "    ",
 319                            ctlo,
 320                            mirqs0 & BIT(offset) ? "s0 mask  " : "s0 unmask",
 321                            mirqsx & BIT(offset) ? "sx mask  " : "sx unmask",
 322                            irq & BIT(offset) ? "pending" : "       ");
 323         }
 324 }
 325 
 326 static int crystalcove_gpio_probe(struct platform_device *pdev)
 327 {
 328         int irq = platform_get_irq(pdev, 0);
 329         struct crystalcove_gpio *cg;
 330         int retval;
 331         struct device *dev = pdev->dev.parent;
 332         struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
 333 
 334         if (irq < 0)
 335                 return irq;
 336 
 337         cg = devm_kzalloc(&pdev->dev, sizeof(*cg), GFP_KERNEL);
 338         if (!cg)
 339                 return -ENOMEM;
 340 
 341         platform_set_drvdata(pdev, cg);
 342 
 343         mutex_init(&cg->buslock);
 344         cg->chip.label = KBUILD_MODNAME;
 345         cg->chip.direction_input = crystalcove_gpio_dir_in;
 346         cg->chip.direction_output = crystalcove_gpio_dir_out;
 347         cg->chip.get = crystalcove_gpio_get;
 348         cg->chip.set = crystalcove_gpio_set;
 349         cg->chip.base = -1;
 350         cg->chip.ngpio = CRYSTALCOVE_VGPIO_NUM;
 351         cg->chip.can_sleep = true;
 352         cg->chip.parent = dev;
 353         cg->chip.dbg_show = crystalcove_gpio_dbg_show;
 354         cg->regmap = pmic->regmap;
 355 
 356         retval = devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg);
 357         if (retval) {
 358                 dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval);
 359                 return retval;
 360         }
 361 
 362         gpiochip_irqchip_add_nested(&cg->chip, &crystalcove_irqchip, 0,
 363                                     handle_simple_irq, IRQ_TYPE_NONE);
 364 
 365         retval = request_threaded_irq(irq, NULL, crystalcove_gpio_irq_handler,
 366                                       IRQF_ONESHOT, KBUILD_MODNAME, cg);
 367 
 368         if (retval) {
 369                 dev_warn(&pdev->dev, "request irq failed: %d\n", retval);
 370                 return retval;
 371         }
 372 
 373         gpiochip_set_nested_irqchip(&cg->chip, &crystalcove_irqchip, irq);
 374 
 375         return 0;
 376 }
 377 
 378 static int crystalcove_gpio_remove(struct platform_device *pdev)
 379 {
 380         struct crystalcove_gpio *cg = platform_get_drvdata(pdev);
 381         int irq = platform_get_irq(pdev, 0);
 382 
 383         if (irq >= 0)
 384                 free_irq(irq, cg);
 385         return 0;
 386 }
 387 
 388 static struct platform_driver crystalcove_gpio_driver = {
 389         .probe = crystalcove_gpio_probe,
 390         .remove = crystalcove_gpio_remove,
 391         .driver = {
 392                 .name = "crystal_cove_gpio",
 393         },
 394 };
 395 
 396 module_platform_driver(crystalcove_gpio_driver);
 397 
 398 MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>");
 399 MODULE_DESCRIPTION("Intel Crystal Cove GPIO Driver");
 400 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */