linux/drivers/gpio/gpio-msic.c
<<
>>
Prefs
   1/*
   2 * Intel Medfield MSIC GPIO driver>
   3 * Copyright (c) 2011, Intel Corporation.
   4 *
   5 * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
   6 * Based on intel_pmic_gpio.c
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms and conditions of the GNU General Public License,
  10 * version 2, as published by the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope it will be useful, but WITHOUT
  13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  15 * more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along with
  18 * this program; if not, write to the Free Software Foundation, Inc.,
  19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  20 *
  21 */
  22
  23#include <linux/kernel.h>
  24#include <linux/slab.h>
  25#include <linux/interrupt.h>
  26#include <linux/init.h>
  27#include <linux/gpio/driver.h>
  28#include <linux/platform_device.h>
  29#include <linux/mfd/intel_msic.h>
  30
  31/* the offset for the mapping of global gpio pin to irq */
  32#define MSIC_GPIO_IRQ_OFFSET    0x100
  33
  34#define MSIC_GPIO_DIR_IN        0
  35#define MSIC_GPIO_DIR_OUT       BIT(5)
  36#define MSIC_GPIO_TRIG_FALL     BIT(1)
  37#define MSIC_GPIO_TRIG_RISE     BIT(2)
  38
  39/* masks for msic gpio output GPIOxxxxCTLO registers */
  40#define MSIC_GPIO_DIR_MASK      BIT(5)
  41#define MSIC_GPIO_DRV_MASK      BIT(4)
  42#define MSIC_GPIO_REN_MASK      BIT(3)
  43#define MSIC_GPIO_RVAL_MASK     (BIT(2) | BIT(1))
  44#define MSIC_GPIO_DOUT_MASK     BIT(0)
  45
  46/* masks for msic gpio input GPIOxxxxCTLI registers */
  47#define MSIC_GPIO_GLBYP_MASK    BIT(5)
  48#define MSIC_GPIO_DBNC_MASK     (BIT(4) | BIT(3))
  49#define MSIC_GPIO_INTCNT_MASK   (BIT(2) | BIT(1))
  50#define MSIC_GPIO_DIN_MASK      BIT(0)
  51
  52#define MSIC_NUM_GPIO           24
  53
  54struct msic_gpio {
  55        struct platform_device  *pdev;
  56        struct mutex            buslock;
  57        struct gpio_chip        chip;
  58        int                     irq;
  59        unsigned                irq_base;
  60        unsigned long           trig_change_mask;
  61        unsigned                trig_type;
  62};
  63
  64/*
  65 * MSIC has 24 gpios, 16 low voltage (1.2-1.8v) and 8 high voltage (3v).
  66 * Both the high and low voltage gpios are divided in two banks.
  67 * GPIOs are numbered with GPIO0LV0 as gpio_base in the following order:
  68 * GPIO0LV0..GPIO0LV7: low voltage, bank 0, gpio_base
  69 * GPIO1LV0..GPIO1LV7: low voltage, bank 1,  gpio_base + 8
  70 * GPIO0HV0..GPIO0HV3: high voltage, bank 0, gpio_base + 16
  71 * GPIO1HV0..GPIO1HV3: high voltage, bank 1, gpio_base + 20
  72 */
  73
  74static int msic_gpio_to_ireg(unsigned offset)
  75{
  76        if (offset >= MSIC_NUM_GPIO)
  77                return -EINVAL;
  78
  79        if (offset < 8)
  80                return INTEL_MSIC_GPIO0LV0CTLI - offset;
  81        if (offset < 16)
  82                return INTEL_MSIC_GPIO1LV0CTLI - offset + 8;
  83        if (offset < 20)
  84                return INTEL_MSIC_GPIO0HV0CTLI - offset + 16;
  85
  86        return INTEL_MSIC_GPIO1HV0CTLI - offset + 20;
  87}
  88
  89static int msic_gpio_to_oreg(unsigned offset)
  90{
  91        if (offset >= MSIC_NUM_GPIO)
  92                return -EINVAL;
  93
  94        if (offset < 8)
  95                return INTEL_MSIC_GPIO0LV0CTLO - offset;
  96        if (offset < 16)
  97                return INTEL_MSIC_GPIO1LV0CTLO - offset + 8;
  98        if (offset < 20)
  99                return INTEL_MSIC_GPIO0HV0CTLO - offset + 16;
 100
 101        return INTEL_MSIC_GPIO1HV0CTLO - offset + 20;
 102}
 103
 104static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 105{
 106        int reg;
 107
 108        reg = msic_gpio_to_oreg(offset);
 109        if (reg < 0)
 110                return reg;
 111
 112        return intel_msic_reg_update(reg, MSIC_GPIO_DIR_IN, MSIC_GPIO_DIR_MASK);
 113}
 114
 115static int msic_gpio_direction_output(struct gpio_chip *chip,
 116                        unsigned offset, int value)
 117{
 118        int reg;
 119        unsigned mask;
 120
 121        value = (!!value) | MSIC_GPIO_DIR_OUT;
 122        mask = MSIC_GPIO_DIR_MASK | MSIC_GPIO_DOUT_MASK;
 123
 124        reg = msic_gpio_to_oreg(offset);
 125        if (reg < 0)
 126                return reg;
 127
 128        return intel_msic_reg_update(reg, value, mask);
 129}
 130
 131static int msic_gpio_get(struct gpio_chip *chip, unsigned offset)
 132{
 133        u8 r;
 134        int ret;
 135        int reg;
 136
 137        reg = msic_gpio_to_ireg(offset);
 138        if (reg < 0)
 139                return reg;
 140
 141        ret = intel_msic_reg_read(reg, &r);
 142        if (ret < 0)
 143                return ret;
 144
 145        return !!(r & MSIC_GPIO_DIN_MASK);
 146}
 147
 148static void msic_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 149{
 150        int reg;
 151
 152        reg = msic_gpio_to_oreg(offset);
 153        if (reg < 0)
 154                return;
 155
 156        intel_msic_reg_update(reg, !!value , MSIC_GPIO_DOUT_MASK);
 157}
 158
 159/*
 160 * This is called from genirq with mg->buslock locked and
 161 * irq_desc->lock held. We can not access the scu bus here, so we
 162 * store the change and update in the bus_sync_unlock() function below
 163 */
 164static int msic_irq_type(struct irq_data *data, unsigned type)
 165{
 166        struct msic_gpio *mg = irq_data_get_irq_chip_data(data);
 167        u32 gpio = data->irq - mg->irq_base;
 168
 169        if (gpio >= mg->chip.ngpio)
 170                return -EINVAL;
 171
 172        /* mark for which gpio the trigger changed, protected by buslock */
 173        mg->trig_change_mask |= (1 << gpio);
 174        mg->trig_type = type;
 175
 176        return 0;
 177}
 178
 179static int msic_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 180{
 181        struct msic_gpio *mg = gpiochip_get_data(chip);
 182        return mg->irq_base + offset;
 183}
 184
 185static void msic_bus_lock(struct irq_data *data)
 186{
 187        struct msic_gpio *mg = irq_data_get_irq_chip_data(data);
 188        mutex_lock(&mg->buslock);
 189}
 190
 191static void msic_bus_sync_unlock(struct irq_data *data)
 192{
 193        struct msic_gpio *mg = irq_data_get_irq_chip_data(data);
 194        int offset;
 195        int reg;
 196        u8 trig = 0;
 197
 198        /* We can only get one change at a time as the buslock covers the
 199           entire transaction. The irq_desc->lock is dropped before we are
 200           called but that is fine */
 201        if (mg->trig_change_mask) {
 202                offset = __ffs(mg->trig_change_mask);
 203
 204                reg = msic_gpio_to_ireg(offset);
 205                if (reg < 0)
 206                        goto out;
 207
 208                if (mg->trig_type & IRQ_TYPE_EDGE_RISING)
 209                        trig |= MSIC_GPIO_TRIG_RISE;
 210                if (mg->trig_type & IRQ_TYPE_EDGE_FALLING)
 211                        trig |= MSIC_GPIO_TRIG_FALL;
 212
 213                intel_msic_reg_update(reg, trig, MSIC_GPIO_INTCNT_MASK);
 214                mg->trig_change_mask = 0;
 215        }
 216out:
 217        mutex_unlock(&mg->buslock);
 218}
 219
 220/* Firmware does all the masking and unmasking for us, no masking here. */
 221static void msic_irq_unmask(struct irq_data *data) { }
 222
 223static void msic_irq_mask(struct irq_data *data) { }
 224
 225static struct irq_chip msic_irqchip = {
 226        .name                   = "MSIC-GPIO",
 227        .irq_mask               = msic_irq_mask,
 228        .irq_unmask             = msic_irq_unmask,
 229        .irq_set_type           = msic_irq_type,
 230        .irq_bus_lock           = msic_bus_lock,
 231        .irq_bus_sync_unlock    = msic_bus_sync_unlock,
 232};
 233
 234static void msic_gpio_irq_handler(struct irq_desc *desc)
 235{
 236        struct irq_data *data = irq_desc_get_irq_data(desc);
 237        struct msic_gpio *mg = irq_data_get_irq_handler_data(data);
 238        struct irq_chip *chip = irq_data_get_irq_chip(data);
 239        struct intel_msic *msic = pdev_to_intel_msic(mg->pdev);
 240        int i;
 241        int bitnr;
 242        u8 pin;
 243        unsigned long pending = 0;
 244
 245        for (i = 0; i < (mg->chip.ngpio / BITS_PER_BYTE); i++) {
 246                intel_msic_irq_read(msic, INTEL_MSIC_GPIO0LVIRQ + i, &pin);
 247                pending = pin;
 248
 249                if (pending) {
 250                        for_each_set_bit(bitnr, &pending, BITS_PER_BYTE)
 251                                generic_handle_irq(mg->irq_base +
 252                                                   (i * BITS_PER_BYTE) + bitnr);
 253                }
 254        }
 255        chip->irq_eoi(data);
 256}
 257
 258static int platform_msic_gpio_probe(struct platform_device *pdev)
 259{
 260        struct device *dev = &pdev->dev;
 261        struct intel_msic_gpio_pdata *pdata = dev_get_platdata(dev);
 262        struct msic_gpio *mg;
 263        int irq = platform_get_irq(pdev, 0);
 264        int retval;
 265        int i;
 266
 267        if (irq < 0) {
 268                dev_err(dev, "no IRQ line: %d\n", irq);
 269                return irq;
 270        }
 271
 272        if (!pdata || !pdata->gpio_base) {
 273                dev_err(dev, "incorrect or missing platform data\n");
 274                return -EINVAL;
 275        }
 276
 277        mg = kzalloc(sizeof(*mg), GFP_KERNEL);
 278        if (!mg)
 279                return -ENOMEM;
 280
 281        dev_set_drvdata(dev, mg);
 282
 283        mg->pdev = pdev;
 284        mg->irq = irq;
 285        mg->irq_base = pdata->gpio_base + MSIC_GPIO_IRQ_OFFSET;
 286        mg->chip.label = "msic_gpio";
 287        mg->chip.direction_input = msic_gpio_direction_input;
 288        mg->chip.direction_output = msic_gpio_direction_output;
 289        mg->chip.get = msic_gpio_get;
 290        mg->chip.set = msic_gpio_set;
 291        mg->chip.to_irq = msic_gpio_to_irq;
 292        mg->chip.base = pdata->gpio_base;
 293        mg->chip.ngpio = MSIC_NUM_GPIO;
 294        mg->chip.can_sleep = true;
 295        mg->chip.parent = dev;
 296
 297        mutex_init(&mg->buslock);
 298
 299        retval = gpiochip_add_data(&mg->chip, mg);
 300        if (retval) {
 301                dev_err(dev, "Adding MSIC gpio chip failed\n");
 302                goto err;
 303        }
 304
 305        for (i = 0; i < mg->chip.ngpio; i++) {
 306                irq_set_chip_data(i + mg->irq_base, mg);
 307                irq_set_chip_and_handler(i + mg->irq_base,
 308                                         &msic_irqchip,
 309                                         handle_simple_irq);
 310        }
 311        irq_set_chained_handler_and_data(mg->irq, msic_gpio_irq_handler, mg);
 312
 313        return 0;
 314err:
 315        kfree(mg);
 316        return retval;
 317}
 318
 319static struct platform_driver platform_msic_gpio_driver = {
 320        .driver = {
 321                .name           = "msic_gpio",
 322        },
 323        .probe          = platform_msic_gpio_probe,
 324};
 325
 326static int __init platform_msic_gpio_init(void)
 327{
 328        return platform_driver_register(&platform_msic_gpio_driver);
 329}
 330subsys_initcall(platform_msic_gpio_init);
 331