1/* Moorestown PMIC GPIO (access through IPC) driver 2 * Copyright (c) 2008 - 2009, Intel Corporation. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 */ 17 18/* Supports: 19 * Moorestown platform PMIC chip 20 */ 21 22#include <linux/module.h> 23#include <linux/kernel.h> 24#include <linux/interrupt.h> 25#include <linux/delay.h> 26#include <linux/stddef.h> 27#include <linux/slab.h> 28#include <linux/ioport.h> 29#include <linux/init.h> 30#include <linux/io.h> 31#include <linux/gpio.h> 32#include <linux/interrupt.h> 33#include <asm/intel_scu_ipc.h> 34#include <linux/device.h> 35#include <linux/intel_pmic_gpio.h> 36#include <linux/platform_device.h> 37 38#define DRIVER_NAME "pmic_gpio" 39 40/* register offset that IPC driver should use 41 * 8 GPIO + 8 GPOSW (6 controllable) + 8GPO 42 */ 43enum pmic_gpio_register { 44 GPIO0 = 0xE0, 45 GPIO7 = 0xE7, 46 GPIOINT = 0xE8, 47 GPOSWCTL0 = 0xEC, 48 GPOSWCTL5 = 0xF1, 49 GPO = 0xF4, 50}; 51 52/* bits definition for GPIO & GPOSW */ 53#define GPIO_DRV 0x01 54#define GPIO_DIR 0x02 55#define GPIO_DIN 0x04 56#define GPIO_DOU 0x08 57#define GPIO_INTCTL 0x30 58#define GPIO_DBC 0xc0 59 60#define GPOSW_DRV 0x01 61#define GPOSW_DOU 0x08 62#define GPOSW_RDRV 0x30 63 64 65#define NUM_GPIO 24 66 67struct pmic_gpio_irq { 68 spinlock_t lock; 69 u32 trigger[NUM_GPIO]; 70 u32 dirty; 71 struct work_struct work; 72}; 73 74 75struct pmic_gpio { 76 struct gpio_chip chip; 77 struct pmic_gpio_irq irqtypes; 78 void *gpiointr; 79 int irq; 80 unsigned irq_base; 81}; 82 83static void pmic_program_irqtype(int gpio, int type) 84{ 85 if (type & IRQ_TYPE_EDGE_RISING) 86 intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20); 87 else 88 intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20); 89 90 if (type & IRQ_TYPE_EDGE_FALLING) 91 intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10); 92 else 93 intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10); 94}; 95 96static void pmic_irqtype_work(struct work_struct *work) 97{ 98 struct pmic_gpio_irq *t = 99 container_of(work, struct pmic_gpio_irq, work); 100 unsigned long flags; 101 int i; 102 u16 type; 103 104 spin_lock_irqsave(&t->lock, flags); 105 /* As we drop the lock, we may need multiple scans if we race the 106 pmic_irq_type function */ 107 while (t->dirty) { 108 /* 109 * For each pin that has the dirty bit set send an IPC 110 * message to configure the hardware via the PMIC 111 */ 112 for (i = 0; i < NUM_GPIO; i++) { 113 if (!(t->dirty & (1 << i))) 114 continue; 115 t->dirty &= ~(1 << i); 116 /* We can't trust the array entry or dirty 117 once the lock is dropped */ 118 type = t->trigger[i]; 119 spin_unlock_irqrestore(&t->lock, flags); 120 pmic_program_irqtype(i, type); 121 spin_lock_irqsave(&t->lock, flags); 122 } 123 } 124 spin_unlock_irqrestore(&t->lock, flags); 125} 126 127static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 128{ 129 if (offset > 8) { 130 printk(KERN_ERR 131 "%s: only pin 0-7 support input\n", __func__); 132 return -1;/* we only have 8 GPIO can use as input */ 133 } 134 return intel_scu_ipc_update_register(GPIO0 + offset, 135 GPIO_DIR, GPIO_DIR); 136} 137 138static int pmic_gpio_direction_output(struct gpio_chip *chip, 139 unsigned offset, int value) 140{ 141 int rc = 0; 142 143 if (offset < 8)/* it is GPIO */ 144 rc = intel_scu_ipc_update_register(GPIO0 + offset, 145 GPIO_DRV | GPIO_DOU | GPIO_DIR, 146 GPIO_DRV | (value ? GPIO_DOU : 0)); 147 else if (offset < 16)/* it is GPOSW */ 148 rc = intel_scu_ipc_update_register(GPOSWCTL0 + offset - 8, 149 GPOSW_DRV | GPOSW_DOU | GPOSW_RDRV, 150 GPOSW_DRV | (value ? GPOSW_DOU : 0)); 151 else if (offset > 15 && offset < 24)/* it is GPO */ 152 rc = intel_scu_ipc_update_register(GPO, 153 1 << (offset - 16), 154 value ? 1 << (offset - 16) : 0); 155 else { 156 printk(KERN_ERR 157 "%s: invalid PMIC GPIO pin %d!\n", __func__, offset); 158 WARN_ON(1); 159 } 160 161 return rc; 162} 163 164static int pmic_gpio_get(struct gpio_chip *chip, unsigned offset) 165{ 166 u8 r; 167 int ret; 168 169 /* we only have 8 GPIO pins we can use as input */ 170 if (offset > 8) 171 return -EOPNOTSUPP; 172 ret = intel_scu_ipc_ioread8(GPIO0 + offset, &r); 173 if (ret < 0) 174 return ret; 175 return r & GPIO_DIN; 176} 177 178static void pmic_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 179{ 180 if (offset < 8)/* it is GPIO */ 181 intel_scu_ipc_update_register(GPIO0 + offset, 182 GPIO_DRV | GPIO_DOU, 183 GPIO_DRV | (value ? GPIO_DOU : 0)); 184 else if (offset < 16)/* it is GPOSW */ 185 intel_scu_ipc_update_register(GPOSWCTL0 + offset - 8, 186 GPOSW_DRV | GPOSW_DOU | GPOSW_RDRV, 187 GPOSW_DRV | (value ? GPOSW_DOU : 0)); 188 else if (offset > 15 && offset < 24) /* it is GPO */ 189 intel_scu_ipc_update_register(GPO, 190 1 << (offset - 16), 191 value ? 1 << (offset - 16) : 0); 192} 193 194static int pmic_irq_type(unsigned irq, unsigned type) 195{ 196 struct pmic_gpio *pg = get_irq_chip_data(irq); 197 u32 gpio = irq - pg->irq_base; 198 unsigned long flags; 199 200 if (gpio > pg->chip.ngpio) 201 return -EINVAL; 202 203 spin_lock_irqsave(&pg->irqtypes.lock, flags); 204 pg->irqtypes.trigger[gpio] = type; 205 pg->irqtypes.dirty |= (1 << gpio); 206 spin_unlock_irqrestore(&pg->irqtypes.lock, flags); 207 schedule_work(&pg->irqtypes.work); 208 return 0; 209} 210 211 212 213static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 214{ 215 struct pmic_gpio *pg = container_of(chip, struct pmic_gpio, chip); 216 217 return pg->irq_base + offset; 218} 219 220/* the gpiointr register is read-clear, so just do nothing. */ 221static void pmic_irq_unmask(unsigned irq) 222{ 223}; 224 225static void pmic_irq_mask(unsigned irq) 226{ 227}; 228 229static struct irq_chip pmic_irqchip = { 230 .name = "PMIC-GPIO", 231 .mask = pmic_irq_mask, 232 .unmask = pmic_irq_unmask, 233 .set_type = pmic_irq_type, 234}; 235 236static void pmic_irq_handler(unsigned irq, struct irq_desc *desc) 237{ 238 struct pmic_gpio *pg = (struct pmic_gpio *)get_irq_data(irq); 239 u8 intsts = *((u8 *)pg->gpiointr + 4); 240 int gpio; 241 242 for (gpio = 0; gpio < 8; gpio++) { 243 if (intsts & (1 << gpio)) { 244 pr_debug("pmic pin %d triggered\n", gpio); 245 generic_handle_irq(pg->irq_base + gpio); 246 } 247 } 248 desc->chip->eoi(irq); 249} 250 251static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) 252{ 253 struct device *dev = &pdev->dev; 254 int irq = platform_get_irq(pdev, 0); 255 struct intel_pmic_gpio_platform_data *pdata = dev->platform_data; 256 257 struct pmic_gpio *pg; 258 int retval; 259 int i; 260 261 if (irq < 0) { 262 dev_dbg(dev, "no IRQ line\n"); 263 return -EINVAL; 264 } 265 266 if (!pdata || !pdata->gpio_base || !pdata->irq_base) { 267 dev_dbg(dev, "incorrect or missing platform data\n"); 268 return -EINVAL; 269 } 270 271 pg = kzalloc(sizeof(*pg), GFP_KERNEL); 272 if (!pg) 273 return -ENOMEM; 274 275 dev_set_drvdata(dev, pg); 276 277 pg->irq = irq; 278 /* setting up SRAM mapping for GPIOINT register */ 279 pg->gpiointr = ioremap_nocache(pdata->gpiointr, 8); 280 if (!pg->gpiointr) { 281 printk(KERN_ERR "%s: Can not map GPIOINT.\n", __func__); 282 retval = -EINVAL; 283 goto err2; 284 } 285 pg->irq_base = pdata->irq_base; 286 pg->chip.label = "intel_pmic"; 287 pg->chip.direction_input = pmic_gpio_direction_input; 288 pg->chip.direction_output = pmic_gpio_direction_output; 289 pg->chip.get = pmic_gpio_get; 290 pg->chip.set = pmic_gpio_set; 291 pg->chip.to_irq = pmic_gpio_to_irq; 292 pg->chip.base = pdata->gpio_base; 293 pg->chip.ngpio = NUM_GPIO; 294 pg->chip.can_sleep = 1; 295 pg->chip.dev = dev; 296 297 INIT_WORK(&pg->irqtypes.work, pmic_irqtype_work); 298 spin_lock_init(&pg->irqtypes.lock); 299 300 pg->chip.dev = dev; 301 retval = gpiochip_add(&pg->chip); 302 if (retval) { 303 printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__); 304 goto err; 305 } 306 set_irq_data(pg->irq, pg); 307 set_irq_chained_handler(pg->irq, pmic_irq_handler); 308 for (i = 0; i < 8; i++) { 309 set_irq_chip_and_handler_name(i + pg->irq_base, &pmic_irqchip, 310 handle_simple_irq, "demux"); 311 set_irq_chip_data(i + pg->irq_base, pg); 312 } 313 return 0; 314err: 315 iounmap(pg->gpiointr); 316err2: 317 kfree(pg); 318 return retval; 319} 320 321/* at the same time, register a platform driver 322 * this supports the sfi 0.81 fw */ 323static struct platform_driver platform_pmic_gpio_driver = { 324 .driver = { 325 .name = DRIVER_NAME, 326 .owner = THIS_MODULE, 327 }, 328 .probe = platform_pmic_gpio_probe, 329}; 330 331static int __init platform_pmic_gpio_init(void) 332{ 333 return platform_driver_register(&platform_pmic_gpio_driver); 334} 335 336subsys_initcall(platform_pmic_gpio_init); 337 338MODULE_AUTHOR("Alek Du <alek.du@intel.com>"); 339MODULE_DESCRIPTION("Intel Moorestown PMIC GPIO driver"); 340MODULE_LICENSE("GPL v2"); 341