1/* NXP PCF50633 Power Management Unit (PMU) driver 2 * 3 * (C) 2006-2008 by Openmoko, Inc. 4 * Author: Harald Welte <laforge@openmoko.org> 5 * Balaji Rao <balajirrao@openmoko.org> 6 * All rights reserved. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 15#include <linux/interrupt.h> 16#include <linux/kernel.h> 17#include <linux/mutex.h> 18#include <linux/export.h> 19#include <linux/slab.h> 20 21#include <linux/mfd/pcf50633/core.h> 22#include <linux/mfd/pcf50633/mbc.h> 23 24int pcf50633_register_irq(struct pcf50633 *pcf, int irq, 25 void (*handler) (int, void *), void *data) 26{ 27 if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler) 28 return -EINVAL; 29 30 if (WARN_ON(pcf->irq_handler[irq].handler)) 31 return -EBUSY; 32 33 mutex_lock(&pcf->lock); 34 pcf->irq_handler[irq].handler = handler; 35 pcf->irq_handler[irq].data = data; 36 mutex_unlock(&pcf->lock); 37 38 return 0; 39} 40EXPORT_SYMBOL_GPL(pcf50633_register_irq); 41 42int pcf50633_free_irq(struct pcf50633 *pcf, int irq) 43{ 44 if (irq < 0 || irq >= PCF50633_NUM_IRQ) 45 return -EINVAL; 46 47 mutex_lock(&pcf->lock); 48 pcf->irq_handler[irq].handler = NULL; 49 mutex_unlock(&pcf->lock); 50 51 return 0; 52} 53EXPORT_SYMBOL_GPL(pcf50633_free_irq); 54 55static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask) 56{ 57 u8 reg, bit; 58 int ret = 0, idx; 59 60 idx = irq >> 3; 61 reg = PCF50633_REG_INT1M + idx; 62 bit = 1 << (irq & 0x07); 63 64 pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0); 65 66 mutex_lock(&pcf->lock); 67 68 if (mask) 69 pcf->mask_regs[idx] |= bit; 70 else 71 pcf->mask_regs[idx] &= ~bit; 72 73 mutex_unlock(&pcf->lock); 74 75 return ret; 76} 77 78int pcf50633_irq_mask(struct pcf50633 *pcf, int irq) 79{ 80 dev_dbg(pcf->dev, "Masking IRQ %d\n", irq); 81 82 return __pcf50633_irq_mask_set(pcf, irq, 1); 83} 84EXPORT_SYMBOL_GPL(pcf50633_irq_mask); 85 86int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq) 87{ 88 dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq); 89 90 return __pcf50633_irq_mask_set(pcf, irq, 0); 91} 92EXPORT_SYMBOL_GPL(pcf50633_irq_unmask); 93 94int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq) 95{ 96 u8 reg, bits; 97 98 reg = irq >> 3; 99 bits = 1 << (irq & 0x07); 100 101 return pcf->mask_regs[reg] & bits; 102} 103EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get); 104 105static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq) 106{ 107 if (pcf->irq_handler[irq].handler) 108 pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data); 109} 110 111/* Maximum amount of time ONKEY is held before emergency action is taken */ 112#define PCF50633_ONKEY1S_TIMEOUT 8 113 114static irqreturn_t pcf50633_irq(int irq, void *data) 115{ 116 struct pcf50633 *pcf = data; 117 int ret, i, j; 118 u8 pcf_int[5], chgstat; 119 120 /* Read the 5 INT regs in one transaction */ 121 ret = pcf50633_read_block(pcf, PCF50633_REG_INT1, 122 ARRAY_SIZE(pcf_int), pcf_int); 123 if (ret != ARRAY_SIZE(pcf_int)) { 124 dev_err(pcf->dev, "Error reading INT registers\n"); 125 126 /* 127 * If this doesn't ACK the interrupt to the chip, we'll be 128 * called once again as we're level triggered. 129 */ 130 goto out; 131 } 132 133 /* defeat 8s death from lowsys on A5 */ 134 pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04); 135 136 /* We immediately read the usb and adapter status. We thus make sure 137 * only of USBINS/USBREM IRQ handlers are called */ 138 if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) { 139 chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); 140 if (chgstat & (0x3 << 4)) 141 pcf_int[0] &= ~PCF50633_INT1_USBREM; 142 else 143 pcf_int[0] &= ~PCF50633_INT1_USBINS; 144 } 145 146 /* Make sure only one of ADPINS or ADPREM is set */ 147 if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) { 148 chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); 149 if (chgstat & (0x3 << 4)) 150 pcf_int[0] &= ~PCF50633_INT1_ADPREM; 151 else 152 pcf_int[0] &= ~PCF50633_INT1_ADPINS; 153 } 154 155 dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x " 156 "INT4=0x%02x INT5=0x%02x\n", pcf_int[0], 157 pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]); 158 159 /* Some revisions of the chip don't have a 8s standby mode on 160 * ONKEY1S press. We try to manually do it in such cases. */ 161 if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) { 162 dev_info(pcf->dev, "ONKEY1S held for %d secs\n", 163 pcf->onkey1s_held); 164 if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT) 165 if (pcf->pdata->force_shutdown) 166 pcf->pdata->force_shutdown(pcf); 167 } 168 169 if (pcf_int[2] & PCF50633_INT3_ONKEY1S) { 170 dev_info(pcf->dev, "ONKEY1S held\n"); 171 pcf->onkey1s_held = 1 ; 172 173 /* Unmask IRQ_SECOND */ 174 pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, 175 PCF50633_INT1_SECOND); 176 177 /* Unmask IRQ_ONKEYR */ 178 pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M, 179 PCF50633_INT2_ONKEYR); 180 } 181 182 if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) { 183 pcf->onkey1s_held = 0; 184 185 /* Mask SECOND and ONKEYR interrupts */ 186 if (pcf->mask_regs[0] & PCF50633_INT1_SECOND) 187 pcf50633_reg_set_bit_mask(pcf, 188 PCF50633_REG_INT1M, 189 PCF50633_INT1_SECOND, 190 PCF50633_INT1_SECOND); 191 192 if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR) 193 pcf50633_reg_set_bit_mask(pcf, 194 PCF50633_REG_INT2M, 195 PCF50633_INT2_ONKEYR, 196 PCF50633_INT2_ONKEYR); 197 } 198 199 /* Have we just resumed ? */ 200 if (pcf->is_suspended) { 201 pcf->is_suspended = 0; 202 203 /* Set the resume reason filtering out non resumers */ 204 for (i = 0; i < ARRAY_SIZE(pcf_int); i++) 205 pcf->resume_reason[i] = pcf_int[i] & 206 pcf->pdata->resumers[i]; 207 208 /* Make sure we don't pass on any ONKEY events to 209 * userspace now */ 210 pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF); 211 } 212 213 for (i = 0; i < ARRAY_SIZE(pcf_int); i++) { 214 /* Unset masked interrupts */ 215 pcf_int[i] &= ~pcf->mask_regs[i]; 216 217 for (j = 0; j < 8 ; j++) 218 if (pcf_int[i] & (1 << j)) 219 pcf50633_irq_call_handler(pcf, (i * 8) + j); 220 } 221 222out: 223 return IRQ_HANDLED; 224} 225 226#ifdef CONFIG_PM 227 228int pcf50633_irq_suspend(struct pcf50633 *pcf) 229{ 230 int ret; 231 int i; 232 u8 res[5]; 233 234 235 /* Make sure our interrupt handlers are not called 236 * henceforth */ 237 disable_irq(pcf->irq); 238 239 /* Save the masks */ 240 ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, 241 ARRAY_SIZE(pcf->suspend_irq_masks), 242 pcf->suspend_irq_masks); 243 if (ret < 0) { 244 dev_err(pcf->dev, "error saving irq masks\n"); 245 goto out; 246 } 247 248 /* Write wakeup irq masks */ 249 for (i = 0; i < ARRAY_SIZE(res); i++) 250 res[i] = ~pcf->pdata->resumers[i]; 251 252 ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, 253 ARRAY_SIZE(res), &res[0]); 254 if (ret < 0) { 255 dev_err(pcf->dev, "error writing wakeup irq masks\n"); 256 goto out; 257 } 258 259 pcf->is_suspended = 1; 260 261out: 262 return ret; 263} 264 265int pcf50633_irq_resume(struct pcf50633 *pcf) 266{ 267 int ret; 268 269 /* Write the saved mask registers */ 270 ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, 271 ARRAY_SIZE(pcf->suspend_irq_masks), 272 pcf->suspend_irq_masks); 273 if (ret < 0) 274 dev_err(pcf->dev, "Error restoring saved suspend masks\n"); 275 276 enable_irq(pcf->irq); 277 278 return ret; 279} 280 281#endif 282 283int pcf50633_irq_init(struct pcf50633 *pcf, int irq) 284{ 285 int ret; 286 287 pcf->irq = irq; 288 289 /* Enable all interrupts except RTC SECOND */ 290 pcf->mask_regs[0] = 0x80; 291 pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]); 292 pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00); 293 pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00); 294 pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00); 295 pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00); 296 297 ret = request_threaded_irq(irq, NULL, pcf50633_irq, 298 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 299 "pcf50633", pcf); 300 301 if (ret) 302 dev_err(pcf->dev, "Failed to request IRQ %d\n", ret); 303 304 if (enable_irq_wake(irq) < 0) 305 dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source" 306 "in this hardware revision", irq); 307 308 return ret; 309} 310 311void pcf50633_irq_free(struct pcf50633 *pcf) 312{ 313 free_irq(pcf->irq, pcf); 314} 315