0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/interrupt.h>
0011 #include <linux/kernel.h>
0012 #include <linux/mutex.h>
0013 #include <linux/export.h>
0014 #include <linux/slab.h>
0015
0016 #include <linux/mfd/pcf50633/core.h>
0017 #include <linux/mfd/pcf50633/mbc.h>
0018
0019 int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
0020 void (*handler) (int, void *), void *data)
0021 {
0022 if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler)
0023 return -EINVAL;
0024
0025 if (WARN_ON(pcf->irq_handler[irq].handler))
0026 return -EBUSY;
0027
0028 mutex_lock(&pcf->lock);
0029 pcf->irq_handler[irq].handler = handler;
0030 pcf->irq_handler[irq].data = data;
0031 mutex_unlock(&pcf->lock);
0032
0033 return 0;
0034 }
0035 EXPORT_SYMBOL_GPL(pcf50633_register_irq);
0036
0037 int pcf50633_free_irq(struct pcf50633 *pcf, int irq)
0038 {
0039 if (irq < 0 || irq >= PCF50633_NUM_IRQ)
0040 return -EINVAL;
0041
0042 mutex_lock(&pcf->lock);
0043 pcf->irq_handler[irq].handler = NULL;
0044 mutex_unlock(&pcf->lock);
0045
0046 return 0;
0047 }
0048 EXPORT_SYMBOL_GPL(pcf50633_free_irq);
0049
0050 static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
0051 {
0052 u8 reg, bit;
0053 int idx;
0054
0055 idx = irq >> 3;
0056 reg = PCF50633_REG_INT1M + idx;
0057 bit = 1 << (irq & 0x07);
0058
0059 pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0);
0060
0061 mutex_lock(&pcf->lock);
0062
0063 if (mask)
0064 pcf->mask_regs[idx] |= bit;
0065 else
0066 pcf->mask_regs[idx] &= ~bit;
0067
0068 mutex_unlock(&pcf->lock);
0069
0070 return 0;
0071 }
0072
0073 int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
0074 {
0075 dev_dbg(pcf->dev, "Masking IRQ %d\n", irq);
0076
0077 return __pcf50633_irq_mask_set(pcf, irq, 1);
0078 }
0079 EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
0080
0081 int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
0082 {
0083 dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq);
0084
0085 return __pcf50633_irq_mask_set(pcf, irq, 0);
0086 }
0087 EXPORT_SYMBOL_GPL(pcf50633_irq_unmask);
0088
0089 int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq)
0090 {
0091 u8 reg, bits;
0092
0093 reg = irq >> 3;
0094 bits = 1 << (irq & 0x07);
0095
0096 return pcf->mask_regs[reg] & bits;
0097 }
0098 EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get);
0099
0100 static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq)
0101 {
0102 if (pcf->irq_handler[irq].handler)
0103 pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data);
0104 }
0105
0106
0107 #define PCF50633_ONKEY1S_TIMEOUT 8
0108
0109 static irqreturn_t pcf50633_irq(int irq, void *data)
0110 {
0111 struct pcf50633 *pcf = data;
0112 int ret, i, j;
0113 u8 pcf_int[5], chgstat;
0114
0115
0116 ret = pcf50633_read_block(pcf, PCF50633_REG_INT1,
0117 ARRAY_SIZE(pcf_int), pcf_int);
0118 if (ret != ARRAY_SIZE(pcf_int)) {
0119 dev_err(pcf->dev, "Error reading INT registers\n");
0120
0121
0122
0123
0124
0125 goto out;
0126 }
0127
0128
0129 pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04);
0130
0131
0132
0133 if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
0134 chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
0135 if (chgstat & (0x3 << 4))
0136 pcf_int[0] &= ~PCF50633_INT1_USBREM;
0137 else
0138 pcf_int[0] &= ~PCF50633_INT1_USBINS;
0139 }
0140
0141
0142 if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
0143 chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
0144 if (chgstat & (0x3 << 4))
0145 pcf_int[0] &= ~PCF50633_INT1_ADPREM;
0146 else
0147 pcf_int[0] &= ~PCF50633_INT1_ADPINS;
0148 }
0149
0150 dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
0151 "INT4=0x%02x INT5=0x%02x\n", pcf_int[0],
0152 pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]);
0153
0154
0155
0156 if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) {
0157 dev_info(pcf->dev, "ONKEY1S held for %d secs\n",
0158 pcf->onkey1s_held);
0159 if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT)
0160 if (pcf->pdata->force_shutdown)
0161 pcf->pdata->force_shutdown(pcf);
0162 }
0163
0164 if (pcf_int[2] & PCF50633_INT3_ONKEY1S) {
0165 dev_info(pcf->dev, "ONKEY1S held\n");
0166 pcf->onkey1s_held = 1 ;
0167
0168
0169 pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M,
0170 PCF50633_INT1_SECOND);
0171
0172
0173 pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M,
0174 PCF50633_INT2_ONKEYR);
0175 }
0176
0177 if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) {
0178 pcf->onkey1s_held = 0;
0179
0180
0181 if (pcf->mask_regs[0] & PCF50633_INT1_SECOND)
0182 pcf50633_reg_set_bit_mask(pcf,
0183 PCF50633_REG_INT1M,
0184 PCF50633_INT1_SECOND,
0185 PCF50633_INT1_SECOND);
0186
0187 if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR)
0188 pcf50633_reg_set_bit_mask(pcf,
0189 PCF50633_REG_INT2M,
0190 PCF50633_INT2_ONKEYR,
0191 PCF50633_INT2_ONKEYR);
0192 }
0193
0194
0195 if (pcf->is_suspended) {
0196 pcf->is_suspended = 0;
0197
0198
0199 for (i = 0; i < ARRAY_SIZE(pcf_int); i++)
0200 pcf->resume_reason[i] = pcf_int[i] &
0201 pcf->pdata->resumers[i];
0202
0203
0204
0205 pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF);
0206 }
0207
0208 for (i = 0; i < ARRAY_SIZE(pcf_int); i++) {
0209
0210 pcf_int[i] &= ~pcf->mask_regs[i];
0211
0212 for (j = 0; j < 8 ; j++)
0213 if (pcf_int[i] & (1 << j))
0214 pcf50633_irq_call_handler(pcf, (i * 8) + j);
0215 }
0216
0217 out:
0218 return IRQ_HANDLED;
0219 }
0220
0221 #ifdef CONFIG_PM
0222
0223 int pcf50633_irq_suspend(struct pcf50633 *pcf)
0224 {
0225 int ret;
0226 int i;
0227 u8 res[5];
0228
0229
0230
0231
0232 disable_irq(pcf->irq);
0233
0234
0235 ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
0236 ARRAY_SIZE(pcf->suspend_irq_masks),
0237 pcf->suspend_irq_masks);
0238 if (ret < 0) {
0239 dev_err(pcf->dev, "error saving irq masks\n");
0240 goto out;
0241 }
0242
0243
0244 for (i = 0; i < ARRAY_SIZE(res); i++)
0245 res[i] = ~pcf->pdata->resumers[i];
0246
0247 ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
0248 ARRAY_SIZE(res), &res[0]);
0249 if (ret < 0) {
0250 dev_err(pcf->dev, "error writing wakeup irq masks\n");
0251 goto out;
0252 }
0253
0254 pcf->is_suspended = 1;
0255
0256 out:
0257 return ret;
0258 }
0259
0260 int pcf50633_irq_resume(struct pcf50633 *pcf)
0261 {
0262 int ret;
0263
0264
0265 ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
0266 ARRAY_SIZE(pcf->suspend_irq_masks),
0267 pcf->suspend_irq_masks);
0268 if (ret < 0)
0269 dev_err(pcf->dev, "Error restoring saved suspend masks\n");
0270
0271 enable_irq(pcf->irq);
0272
0273 return ret;
0274 }
0275
0276 #endif
0277
0278 int pcf50633_irq_init(struct pcf50633 *pcf, int irq)
0279 {
0280 int ret;
0281
0282 pcf->irq = irq;
0283
0284
0285 pcf->mask_regs[0] = 0x80;
0286 pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]);
0287 pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00);
0288 pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00);
0289 pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
0290 pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
0291
0292 ret = request_threaded_irq(irq, NULL, pcf50633_irq,
0293 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0294 "pcf50633", pcf);
0295
0296 if (ret)
0297 dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
0298
0299 if (enable_irq_wake(irq) < 0)
0300 dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
0301 "in this hardware revision", irq);
0302
0303 return ret;
0304 }
0305
0306 void pcf50633_irq_free(struct pcf50633 *pcf)
0307 {
0308 free_irq(pcf->irq, pcf);
0309 }