0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0031
0032 #include <linux/module.h>
0033 #include <linux/pnp.h>
0034 #include <linux/interrupt.h>
0035 #include <linux/timer.h>
0036 #include <linux/leds.h>
0037 #include <linux/spinlock.h>
0038 #include <linux/pci_ids.h>
0039 #include <linux/io.h>
0040 #include <linux/bitrev.h>
0041 #include <linux/slab.h>
0042 #include <linux/wait.h>
0043 #include <linux/sched.h>
0044 #include <media/rc-core.h>
0045
0046 #define DRVNAME "winbond-cir"
0047
0048
0049 #define WBCIR_REG_WCEIR_CTL 0x03
0050 #define WBCIR_REG_WCEIR_STS 0x04
0051 #define WBCIR_REG_WCEIR_EV_EN 0x05
0052 #define WBCIR_REG_WCEIR_CNTL 0x06
0053 #define WBCIR_REG_WCEIR_CNTH 0x07
0054 #define WBCIR_REG_WCEIR_INDEX 0x08
0055 #define WBCIR_REG_WCEIR_DATA 0x09
0056 #define WBCIR_REG_WCEIR_CSL 0x0A
0057 #define WBCIR_REG_WCEIR_CFG1 0x0B
0058 #define WBCIR_REG_WCEIR_CFG2 0x0C
0059
0060
0061 #define WBCIR_REG_ECEIR_CTS 0x00
0062 #define WBCIR_REG_ECEIR_CCTL 0x01
0063 #define WBCIR_REG_ECEIR_CNT_LO 0x02
0064 #define WBCIR_REG_ECEIR_CNT_HI 0x03
0065 #define WBCIR_REG_ECEIR_IREM 0x04
0066
0067
0068 #define WBCIR_REG_SP3_BSR 0x03
0069
0070 #define WBCIR_REG_SP3_RXDATA 0x00
0071 #define WBCIR_REG_SP3_TXDATA 0x00
0072 #define WBCIR_REG_SP3_IER 0x01
0073 #define WBCIR_REG_SP3_EIR 0x02
0074 #define WBCIR_REG_SP3_FCR 0x02
0075 #define WBCIR_REG_SP3_MCR 0x04
0076 #define WBCIR_REG_SP3_LSR 0x05
0077 #define WBCIR_REG_SP3_MSR 0x06
0078 #define WBCIR_REG_SP3_ASCR 0x07
0079
0080 #define WBCIR_REG_SP3_BGDL 0x00
0081 #define WBCIR_REG_SP3_BGDH 0x01
0082 #define WBCIR_REG_SP3_EXCR1 0x02
0083 #define WBCIR_REG_SP3_EXCR2 0x04
0084 #define WBCIR_REG_SP3_TXFLV 0x06
0085 #define WBCIR_REG_SP3_RXFLV 0x07
0086
0087 #define WBCIR_REG_SP3_MRID 0x00
0088 #define WBCIR_REG_SP3_SH_LCR 0x01
0089 #define WBCIR_REG_SP3_SH_FCR 0x02
0090
0091 #define WBCIR_REG_SP3_IRCR1 0x02
0092
0093 #define WBCIR_REG_SP3_IRCR2 0x04
0094
0095 #define WBCIR_REG_SP3_IRCR3 0x00
0096 #define WBCIR_REG_SP3_SIR_PW 0x02
0097
0098 #define WBCIR_REG_SP3_IRRXDC 0x00
0099 #define WBCIR_REG_SP3_IRTXMC 0x01
0100 #define WBCIR_REG_SP3_RCCFG 0x02
0101 #define WBCIR_REG_SP3_IRCFG1 0x04
0102 #define WBCIR_REG_SP3_IRCFG4 0x07
0103
0104
0105
0106
0107
0108
0109 #define WBCIR_IRQ_NONE 0x00
0110
0111 #define WBCIR_IRQ_RX 0x01
0112
0113 #define WBCIR_IRQ_TX_LOW 0x02
0114
0115 #define WBCIR_IRQ_ERR 0x04
0116
0117 #define WBCIR_IRQ_TX_EMPTY 0x20
0118
0119 #define WBCIR_LED_ENABLE 0x80
0120
0121 #define WBCIR_RX_AVAIL 0x01
0122
0123 #define WBCIR_RX_OVERRUN 0x02
0124
0125 #define WBCIR_TX_EOT 0x04
0126
0127 #define WBCIR_RX_DISABLE 0x20
0128
0129 #define WBCIR_TX_UNDERRUN 0x40
0130
0131 #define WBCIR_EXT_ENABLE 0x01
0132
0133 #define WBCIR_REGSEL_COMPARE 0x10
0134
0135 #define WBCIR_REGSEL_MASK 0x20
0136
0137 #define WBCIR_REG_ADDR0 0x00
0138
0139 #define WBCIR_CNTR_EN 0x01
0140
0141 #define WBCIR_CNTR_R 0x02
0142
0143 #define WBCIR_IRTX_INV 0x04
0144
0145 #define WBCIR_RX_T_OV 0x40
0146
0147
0148 enum wbcir_bank {
0149 WBCIR_BANK_0 = 0x00,
0150 WBCIR_BANK_1 = 0x80,
0151 WBCIR_BANK_2 = 0xE0,
0152 WBCIR_BANK_3 = 0xE4,
0153 WBCIR_BANK_4 = 0xE8,
0154 WBCIR_BANK_5 = 0xEC,
0155 WBCIR_BANK_6 = 0xF0,
0156 WBCIR_BANK_7 = 0xF4,
0157 };
0158
0159
0160 enum wbcir_protocol {
0161 IR_PROTOCOL_RC5 = 0x0,
0162 IR_PROTOCOL_NEC = 0x1,
0163 IR_PROTOCOL_RC6 = 0x2,
0164 };
0165
0166
0167 enum wbcir_rxstate {
0168 WBCIR_RXSTATE_INACTIVE = 0,
0169 WBCIR_RXSTATE_ACTIVE,
0170 WBCIR_RXSTATE_ERROR
0171 };
0172
0173
0174 enum wbcir_txstate {
0175 WBCIR_TXSTATE_INACTIVE = 0,
0176 WBCIR_TXSTATE_ACTIVE,
0177 WBCIR_TXSTATE_ERROR
0178 };
0179
0180
0181 #define WBCIR_NAME "Winbond CIR"
0182 #define WBCIR_ID_FAMILY 0xF1
0183 #define WBCIR_ID_CHIP 0x04
0184 #define WAKEUP_IOMEM_LEN 0x10
0185 #define EHFUNC_IOMEM_LEN 0x10
0186 #define SP_IOMEM_LEN 0x08
0187
0188
0189 struct wbcir_data {
0190 spinlock_t spinlock;
0191 struct rc_dev *dev;
0192 struct led_classdev led;
0193
0194 unsigned long wbase;
0195 unsigned long ebase;
0196 unsigned long sbase;
0197 unsigned int irq;
0198 u8 irqmask;
0199
0200
0201 enum wbcir_rxstate rxstate;
0202 int carrier_report_enabled;
0203 u32 pulse_duration;
0204
0205
0206 enum wbcir_txstate txstate;
0207 u32 txlen;
0208 u32 txoff;
0209 u32 *txbuf;
0210 u8 txmask;
0211 u32 txcarrier;
0212 };
0213
0214 static bool invert;
0215 module_param(invert, bool, 0444);
0216 MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver");
0217
0218 static bool txandrx;
0219 module_param(txandrx, bool, 0444);
0220 MODULE_PARM_DESC(txandrx, "Allow simultaneous TX and RX");
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 static void
0231 wbcir_set_bits(unsigned long addr, u8 bits, u8 mask)
0232 {
0233 u8 val;
0234
0235 val = inb(addr);
0236 val = ((val & ~mask) | (bits & mask));
0237 outb(val, addr);
0238 }
0239
0240
0241 static inline void
0242 wbcir_select_bank(struct wbcir_data *data, enum wbcir_bank bank)
0243 {
0244 outb(bank, data->sbase + WBCIR_REG_SP3_BSR);
0245 }
0246
0247 static inline void
0248 wbcir_set_irqmask(struct wbcir_data *data, u8 irqmask)
0249 {
0250 if (data->irqmask == irqmask)
0251 return;
0252
0253 wbcir_select_bank(data, WBCIR_BANK_0);
0254 outb(irqmask, data->sbase + WBCIR_REG_SP3_IER);
0255 data->irqmask = irqmask;
0256 }
0257
0258 static enum led_brightness
0259 wbcir_led_brightness_get(struct led_classdev *led_cdev)
0260 {
0261 struct wbcir_data *data = container_of(led_cdev,
0262 struct wbcir_data,
0263 led);
0264
0265 if (inb(data->ebase + WBCIR_REG_ECEIR_CTS) & WBCIR_LED_ENABLE)
0266 return LED_FULL;
0267 else
0268 return LED_OFF;
0269 }
0270
0271 static void
0272 wbcir_led_brightness_set(struct led_classdev *led_cdev,
0273 enum led_brightness brightness)
0274 {
0275 struct wbcir_data *data = container_of(led_cdev,
0276 struct wbcir_data,
0277 led);
0278
0279 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS,
0280 brightness == LED_OFF ? 0x00 : WBCIR_LED_ENABLE,
0281 WBCIR_LED_ENABLE);
0282 }
0283
0284
0285 static u8
0286 wbcir_to_rc6cells(u8 val)
0287 {
0288 u8 coded = 0x00;
0289 int i;
0290
0291 val &= 0x0F;
0292 for (i = 0; i < 4; i++) {
0293 if (val & 0x01)
0294 coded |= 0x02 << (i * 2);
0295 else
0296 coded |= 0x01 << (i * 2);
0297 val >>= 1;
0298 }
0299
0300 return coded;
0301 }
0302
0303
0304
0305
0306
0307
0308
0309 static void
0310 wbcir_carrier_report(struct wbcir_data *data)
0311 {
0312 unsigned counter = inb(data->ebase + WBCIR_REG_ECEIR_CNT_LO) |
0313 inb(data->ebase + WBCIR_REG_ECEIR_CNT_HI) << 8;
0314
0315 if (counter > 0 && counter < 0xffff) {
0316 struct ir_raw_event ev = {
0317 .carrier_report = 1,
0318 .carrier = DIV_ROUND_CLOSEST(counter * 1000000u,
0319 data->pulse_duration)
0320 };
0321
0322 ir_raw_event_store(data->dev, &ev);
0323 }
0324
0325
0326 data->pulse_duration = 0;
0327 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R,
0328 WBCIR_CNTR_EN | WBCIR_CNTR_R);
0329 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_EN,
0330 WBCIR_CNTR_EN | WBCIR_CNTR_R);
0331 }
0332
0333 static void
0334 wbcir_idle_rx(struct rc_dev *dev, bool idle)
0335 {
0336 struct wbcir_data *data = dev->priv;
0337
0338 if (!idle && data->rxstate == WBCIR_RXSTATE_INACTIVE)
0339 data->rxstate = WBCIR_RXSTATE_ACTIVE;
0340
0341 if (idle && data->rxstate != WBCIR_RXSTATE_INACTIVE) {
0342 data->rxstate = WBCIR_RXSTATE_INACTIVE;
0343
0344 if (data->carrier_report_enabled)
0345 wbcir_carrier_report(data);
0346
0347
0348 outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR);
0349 }
0350 }
0351
0352 static void
0353 wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device)
0354 {
0355 u8 irdata;
0356 struct ir_raw_event rawir = {};
0357
0358
0359 while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) {
0360 irdata = inb(data->sbase + WBCIR_REG_SP3_RXDATA);
0361 if (data->rxstate == WBCIR_RXSTATE_ERROR)
0362 continue;
0363
0364 rawir.duration = ((irdata & 0x7F) + 1) *
0365 (data->carrier_report_enabled ? 2 : 10);
0366 rawir.pulse = irdata & 0x80 ? false : true;
0367
0368 if (rawir.pulse)
0369 data->pulse_duration += rawir.duration;
0370
0371 ir_raw_event_store_with_filter(data->dev, &rawir);
0372 }
0373
0374 ir_raw_event_handle(data->dev);
0375 }
0376
0377 static void
0378 wbcir_irq_tx(struct wbcir_data *data)
0379 {
0380 unsigned int space;
0381 unsigned int used;
0382 u8 bytes[16];
0383 u8 byte;
0384
0385 if (!data->txbuf)
0386 return;
0387
0388 switch (data->txstate) {
0389 case WBCIR_TXSTATE_INACTIVE:
0390
0391 space = 16;
0392 break;
0393 case WBCIR_TXSTATE_ACTIVE:
0394
0395 space = 13;
0396 break;
0397 case WBCIR_TXSTATE_ERROR:
0398 space = 0;
0399 break;
0400 default:
0401 return;
0402 }
0403
0404
0405
0406
0407
0408
0409 for (used = 0; used < space && data->txoff != data->txlen; used++) {
0410 if (data->txbuf[data->txoff] == 0) {
0411 data->txoff++;
0412 continue;
0413 }
0414 byte = min((u32)0x80, data->txbuf[data->txoff]);
0415 data->txbuf[data->txoff] -= byte;
0416 byte--;
0417 byte |= (data->txoff % 2 ? 0x80 : 0x00);
0418 bytes[used] = byte;
0419 }
0420
0421 while (data->txoff != data->txlen && data->txbuf[data->txoff] == 0)
0422 data->txoff++;
0423
0424 if (used == 0) {
0425
0426 if (data->txstate == WBCIR_TXSTATE_ERROR)
0427
0428 outb(WBCIR_TX_UNDERRUN, data->sbase + WBCIR_REG_SP3_ASCR);
0429 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
0430 kfree(data->txbuf);
0431 data->txbuf = NULL;
0432 data->txstate = WBCIR_TXSTATE_INACTIVE;
0433 } else if (data->txoff == data->txlen) {
0434
0435 outsb(data->sbase + WBCIR_REG_SP3_TXDATA, bytes, used - 1);
0436 outb(WBCIR_TX_EOT, data->sbase + WBCIR_REG_SP3_ASCR);
0437 outb(bytes[used - 1], data->sbase + WBCIR_REG_SP3_TXDATA);
0438 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
0439 WBCIR_IRQ_TX_EMPTY);
0440 } else {
0441
0442 outsb(data->sbase + WBCIR_REG_SP3_RXDATA, bytes, used);
0443 if (data->txstate == WBCIR_TXSTATE_INACTIVE) {
0444 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
0445 WBCIR_IRQ_TX_LOW);
0446 data->txstate = WBCIR_TXSTATE_ACTIVE;
0447 }
0448 }
0449 }
0450
0451 static irqreturn_t
0452 wbcir_irq_handler(int irqno, void *cookie)
0453 {
0454 struct pnp_dev *device = cookie;
0455 struct wbcir_data *data = pnp_get_drvdata(device);
0456 unsigned long flags;
0457 u8 status;
0458
0459 spin_lock_irqsave(&data->spinlock, flags);
0460 wbcir_select_bank(data, WBCIR_BANK_0);
0461 status = inb(data->sbase + WBCIR_REG_SP3_EIR);
0462 status &= data->irqmask;
0463
0464 if (!status) {
0465 spin_unlock_irqrestore(&data->spinlock, flags);
0466 return IRQ_NONE;
0467 }
0468
0469 if (status & WBCIR_IRQ_ERR) {
0470
0471 if (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_OVERRUN) {
0472 data->rxstate = WBCIR_RXSTATE_ERROR;
0473 ir_raw_event_overflow(data->dev);
0474 }
0475
0476
0477 if (inb(data->sbase + WBCIR_REG_SP3_ASCR) & WBCIR_TX_UNDERRUN)
0478 data->txstate = WBCIR_TXSTATE_ERROR;
0479 }
0480
0481 if (status & WBCIR_IRQ_RX)
0482 wbcir_irq_rx(data, device);
0483
0484 if (status & (WBCIR_IRQ_TX_LOW | WBCIR_IRQ_TX_EMPTY))
0485 wbcir_irq_tx(data);
0486
0487 spin_unlock_irqrestore(&data->spinlock, flags);
0488 return IRQ_HANDLED;
0489 }
0490
0491
0492
0493
0494
0495
0496
0497 static int
0498 wbcir_set_carrier_report(struct rc_dev *dev, int enable)
0499 {
0500 struct wbcir_data *data = dev->priv;
0501 unsigned long flags;
0502
0503 spin_lock_irqsave(&data->spinlock, flags);
0504
0505 if (data->carrier_report_enabled == enable) {
0506 spin_unlock_irqrestore(&data->spinlock, flags);
0507 return 0;
0508 }
0509
0510 data->pulse_duration = 0;
0511 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R,
0512 WBCIR_CNTR_EN | WBCIR_CNTR_R);
0513
0514 if (enable && data->dev->idle)
0515 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL,
0516 WBCIR_CNTR_EN, WBCIR_CNTR_EN | WBCIR_CNTR_R);
0517
0518
0519 wbcir_select_bank(data, WBCIR_BANK_2);
0520 data->dev->rx_resolution = enable ? 2 : 10;
0521 outb(enable ? 0x03 : 0x0f, data->sbase + WBCIR_REG_SP3_BGDL);
0522 outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
0523
0524
0525 wbcir_select_bank(data, WBCIR_BANK_7);
0526 wbcir_set_bits(data->sbase + WBCIR_REG_SP3_RCCFG,
0527 enable ? WBCIR_RX_T_OV : 0, WBCIR_RX_T_OV);
0528
0529 data->carrier_report_enabled = enable;
0530 spin_unlock_irqrestore(&data->spinlock, flags);
0531
0532 return 0;
0533 }
0534
0535 static int
0536 wbcir_txcarrier(struct rc_dev *dev, u32 carrier)
0537 {
0538 struct wbcir_data *data = dev->priv;
0539 unsigned long flags;
0540 u8 val;
0541 u32 freq;
0542
0543 freq = DIV_ROUND_CLOSEST(carrier, 1000);
0544 if (freq < 30 || freq > 60)
0545 return -EINVAL;
0546
0547 switch (freq) {
0548 case 58:
0549 case 59:
0550 case 60:
0551 val = freq - 58;
0552 freq *= 1000;
0553 break;
0554 case 57:
0555 val = freq - 27;
0556 freq = 56900;
0557 break;
0558 default:
0559 val = freq - 27;
0560 freq *= 1000;
0561 break;
0562 }
0563
0564 spin_lock_irqsave(&data->spinlock, flags);
0565 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
0566 spin_unlock_irqrestore(&data->spinlock, flags);
0567 return -EBUSY;
0568 }
0569
0570 if (data->txcarrier != freq) {
0571 wbcir_select_bank(data, WBCIR_BANK_7);
0572 wbcir_set_bits(data->sbase + WBCIR_REG_SP3_IRTXMC, val, 0x1F);
0573 data->txcarrier = freq;
0574 }
0575
0576 spin_unlock_irqrestore(&data->spinlock, flags);
0577 return 0;
0578 }
0579
0580 static int
0581 wbcir_txmask(struct rc_dev *dev, u32 mask)
0582 {
0583 struct wbcir_data *data = dev->priv;
0584 unsigned long flags;
0585 u8 val;
0586
0587
0588 if (mask > 15)
0589 return 4;
0590
0591
0592 switch (mask) {
0593 case 0x1:
0594 val = 0x0;
0595 break;
0596 case 0x2:
0597 val = 0x1;
0598 break;
0599 case 0x4:
0600 val = 0x2;
0601 break;
0602 case 0x8:
0603 val = 0x3;
0604 break;
0605 default:
0606 return -EINVAL;
0607 }
0608
0609 spin_lock_irqsave(&data->spinlock, flags);
0610 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
0611 spin_unlock_irqrestore(&data->spinlock, flags);
0612 return -EBUSY;
0613 }
0614
0615 if (data->txmask != mask) {
0616 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, val, 0x0c);
0617 data->txmask = mask;
0618 }
0619
0620 spin_unlock_irqrestore(&data->spinlock, flags);
0621 return 0;
0622 }
0623
0624 static int
0625 wbcir_tx(struct rc_dev *dev, unsigned *b, unsigned count)
0626 {
0627 struct wbcir_data *data = dev->priv;
0628 unsigned *buf;
0629 unsigned i;
0630 unsigned long flags;
0631
0632 buf = kmalloc_array(count, sizeof(*b), GFP_KERNEL);
0633 if (!buf)
0634 return -ENOMEM;
0635
0636
0637 for (i = 0; i < count; i++)
0638 buf[i] = DIV_ROUND_CLOSEST(b[i], 10);
0639
0640
0641 spin_lock_irqsave(&data->spinlock, flags);
0642 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
0643 spin_unlock_irqrestore(&data->spinlock, flags);
0644 kfree(buf);
0645 return -EBUSY;
0646 }
0647
0648
0649 data->txbuf = buf;
0650 data->txlen = count;
0651 data->txoff = 0;
0652 wbcir_irq_tx(data);
0653
0654
0655 spin_unlock_irqrestore(&data->spinlock, flags);
0656 return count;
0657 }
0658
0659
0660
0661
0662
0663
0664
0665 static void
0666 wbcir_shutdown(struct pnp_dev *device)
0667 {
0668 struct device *dev = &device->dev;
0669 struct wbcir_data *data = pnp_get_drvdata(device);
0670 struct rc_dev *rc = data->dev;
0671 bool do_wake = true;
0672 u8 match[11];
0673 u8 mask[11];
0674 u8 rc6_csl = 0;
0675 u8 proto;
0676 u32 wake_sc = rc->scancode_wakeup_filter.data;
0677 u32 mask_sc = rc->scancode_wakeup_filter.mask;
0678 int i;
0679
0680 memset(match, 0, sizeof(match));
0681 memset(mask, 0, sizeof(mask));
0682
0683 if (!mask_sc || !device_may_wakeup(dev)) {
0684 do_wake = false;
0685 goto finish;
0686 }
0687
0688 switch (rc->wakeup_protocol) {
0689 case RC_PROTO_RC5:
0690
0691 mask[0] = (mask_sc & 0x003f);
0692 mask[0] |= (mask_sc & 0x0300) >> 2;
0693 mask[1] = (mask_sc & 0x1c00) >> 10;
0694 if (mask_sc & 0x0040)
0695 match[1] |= 0x10;
0696
0697 match[0] = (wake_sc & 0x003F);
0698 match[0] |= (wake_sc & 0x0300) >> 2;
0699 match[1] = (wake_sc & 0x1c00) >> 10;
0700 if (!(wake_sc & 0x0040))
0701 match[1] |= 0x10;
0702
0703 proto = IR_PROTOCOL_RC5;
0704 break;
0705
0706 case RC_PROTO_NEC:
0707 mask[1] = bitrev8(mask_sc);
0708 mask[0] = mask[1];
0709 mask[3] = bitrev8(mask_sc >> 8);
0710 mask[2] = mask[3];
0711
0712 match[1] = bitrev8(wake_sc);
0713 match[0] = ~match[1];
0714 match[3] = bitrev8(wake_sc >> 8);
0715 match[2] = ~match[3];
0716
0717 proto = IR_PROTOCOL_NEC;
0718 break;
0719
0720 case RC_PROTO_NECX:
0721 mask[1] = bitrev8(mask_sc);
0722 mask[0] = mask[1];
0723 mask[2] = bitrev8(mask_sc >> 8);
0724 mask[3] = bitrev8(mask_sc >> 16);
0725
0726 match[1] = bitrev8(wake_sc);
0727 match[0] = ~match[1];
0728 match[2] = bitrev8(wake_sc >> 8);
0729 match[3] = bitrev8(wake_sc >> 16);
0730
0731 proto = IR_PROTOCOL_NEC;
0732 break;
0733
0734 case RC_PROTO_NEC32:
0735 mask[0] = bitrev8(mask_sc);
0736 mask[1] = bitrev8(mask_sc >> 8);
0737 mask[2] = bitrev8(mask_sc >> 16);
0738 mask[3] = bitrev8(mask_sc >> 24);
0739
0740 match[0] = bitrev8(wake_sc);
0741 match[1] = bitrev8(wake_sc >> 8);
0742 match[2] = bitrev8(wake_sc >> 16);
0743 match[3] = bitrev8(wake_sc >> 24);
0744
0745 proto = IR_PROTOCOL_NEC;
0746 break;
0747
0748 case RC_PROTO_RC6_0:
0749
0750 match[0] = wbcir_to_rc6cells(wake_sc >> 0);
0751 mask[0] = wbcir_to_rc6cells(mask_sc >> 0);
0752 match[1] = wbcir_to_rc6cells(wake_sc >> 4);
0753 mask[1] = wbcir_to_rc6cells(mask_sc >> 4);
0754
0755
0756 match[2] = wbcir_to_rc6cells(wake_sc >> 8);
0757 mask[2] = wbcir_to_rc6cells(mask_sc >> 8);
0758 match[3] = wbcir_to_rc6cells(wake_sc >> 12);
0759 mask[3] = wbcir_to_rc6cells(mask_sc >> 12);
0760
0761
0762 match[4] = 0x50;
0763 mask[4] = 0xF0;
0764 match[5] = 0x09;
0765 mask[5] = 0x0F;
0766
0767 rc6_csl = 44;
0768 proto = IR_PROTOCOL_RC6;
0769 break;
0770
0771 case RC_PROTO_RC6_6A_24:
0772 case RC_PROTO_RC6_6A_32:
0773 case RC_PROTO_RC6_MCE:
0774 i = 0;
0775
0776
0777 match[i] = wbcir_to_rc6cells(wake_sc >> 0);
0778 mask[i++] = wbcir_to_rc6cells(mask_sc >> 0);
0779 match[i] = wbcir_to_rc6cells(wake_sc >> 4);
0780 mask[i++] = wbcir_to_rc6cells(mask_sc >> 4);
0781
0782
0783 match[i] = wbcir_to_rc6cells(wake_sc >> 8);
0784 mask[i++] = wbcir_to_rc6cells(mask_sc >> 8);
0785 match[i] = wbcir_to_rc6cells(wake_sc >> 12);
0786 mask[i++] = wbcir_to_rc6cells(mask_sc >> 12);
0787
0788
0789 match[i] = wbcir_to_rc6cells(wake_sc >> 16);
0790 mask[i++] = wbcir_to_rc6cells(mask_sc >> 16);
0791
0792 if (rc->wakeup_protocol == RC_PROTO_RC6_6A_20) {
0793 rc6_csl = 52;
0794 } else {
0795 match[i] = wbcir_to_rc6cells(wake_sc >> 20);
0796 mask[i++] = wbcir_to_rc6cells(mask_sc >> 20);
0797
0798 if (rc->wakeup_protocol == RC_PROTO_RC6_6A_24) {
0799 rc6_csl = 60;
0800 } else {
0801
0802 match[i] = wbcir_to_rc6cells(wake_sc >> 24);
0803 mask[i++] = wbcir_to_rc6cells(mask_sc >> 24);
0804 match[i] = wbcir_to_rc6cells(wake_sc >> 28);
0805 mask[i++] = wbcir_to_rc6cells(mask_sc >> 28);
0806 rc6_csl = 76;
0807 }
0808 }
0809
0810
0811 match[i] = 0x93;
0812 mask[i++] = 0xFF;
0813 match[i] = 0x0A;
0814 mask[i++] = 0x0F;
0815 proto = IR_PROTOCOL_RC6;
0816 break;
0817 default:
0818 do_wake = false;
0819 break;
0820 }
0821
0822 finish:
0823 if (do_wake) {
0824
0825 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX,
0826 WBCIR_REGSEL_COMPARE | WBCIR_REG_ADDR0,
0827 0x3F);
0828 outsb(data->wbase + WBCIR_REG_WCEIR_DATA, match, 11);
0829 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX,
0830 WBCIR_REGSEL_MASK | WBCIR_REG_ADDR0,
0831 0x3F);
0832 outsb(data->wbase + WBCIR_REG_WCEIR_DATA, mask, 11);
0833
0834
0835 outb(rc6_csl, data->wbase + WBCIR_REG_WCEIR_CSL);
0836
0837
0838 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17);
0839
0840
0841 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x01, 0x07);
0842
0843
0844 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL,
0845 (proto << 4) | 0x01, 0x31);
0846
0847 } else {
0848
0849 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
0850
0851
0852 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
0853 }
0854
0855
0856
0857
0858
0859
0860
0861 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
0862 disable_irq(data->irq);
0863 }
0864
0865
0866
0867
0868 static int
0869 wbcir_set_wakeup_filter(struct rc_dev *rc, struct rc_scancode_filter *filter)
0870 {
0871 return 0;
0872 }
0873
0874 static int
0875 wbcir_suspend(struct pnp_dev *device, pm_message_t state)
0876 {
0877 struct wbcir_data *data = pnp_get_drvdata(device);
0878 led_classdev_suspend(&data->led);
0879 wbcir_shutdown(device);
0880 return 0;
0881 }
0882
0883 static void
0884 wbcir_init_hw(struct wbcir_data *data)
0885 {
0886
0887 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
0888
0889
0890 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, invert ? 8 : 0, 0x09);
0891
0892
0893 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17);
0894
0895
0896 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
0897
0898
0899 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CFG1, 0x4A, 0x7F);
0900
0901
0902 if (invert)
0903 outb(WBCIR_IRTX_INV, data->ebase + WBCIR_REG_ECEIR_CCTL);
0904 else
0905 outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL);
0906
0907
0908
0909
0910
0911 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
0912 data->txmask = 0x1;
0913
0914
0915 wbcir_select_bank(data, WBCIR_BANK_2);
0916 outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930 outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
0931
0932
0933 outb(0x0f, data->sbase + WBCIR_REG_SP3_BGDL);
0934 outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
0935
0936
0937 wbcir_select_bank(data, WBCIR_BANK_0);
0938 outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
0939 inb(data->sbase + WBCIR_REG_SP3_LSR);
0940 inb(data->sbase + WBCIR_REG_SP3_MSR);
0941
0942
0943 wbcir_select_bank(data, WBCIR_BANK_7);
0944 outb(0x90, data->sbase + WBCIR_REG_SP3_RCCFG);
0945
0946
0947 wbcir_select_bank(data, WBCIR_BANK_4);
0948 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
0949
0950
0951 wbcir_select_bank(data, WBCIR_BANK_5);
0952 outb(txandrx ? 0x03 : 0x02, data->sbase + WBCIR_REG_SP3_IRCR2);
0953
0954
0955 wbcir_select_bank(data, WBCIR_BANK_6);
0956 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
0957
0958
0959 wbcir_select_bank(data, WBCIR_BANK_7);
0960 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
0961
0962
0963 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
0964 data->txcarrier = 36000;
0965
0966
0967 if (invert)
0968 outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
0969 else
0970 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
0971
0972
0973 wbcir_select_bank(data, WBCIR_BANK_0);
0974 outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
0975
0976
0977 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
0978
0979
0980 data->rxstate = WBCIR_RXSTATE_INACTIVE;
0981 wbcir_idle_rx(data->dev, true);
0982
0983
0984 if (data->txstate == WBCIR_TXSTATE_ACTIVE) {
0985 kfree(data->txbuf);
0986 data->txbuf = NULL;
0987 data->txstate = WBCIR_TXSTATE_INACTIVE;
0988 }
0989
0990
0991 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
0992 }
0993
0994 static int
0995 wbcir_resume(struct pnp_dev *device)
0996 {
0997 struct wbcir_data *data = pnp_get_drvdata(device);
0998
0999 wbcir_init_hw(data);
1000 enable_irq(data->irq);
1001 led_classdev_resume(&data->led);
1002
1003 return 0;
1004 }
1005
1006 static int
1007 wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
1008 {
1009 struct device *dev = &device->dev;
1010 struct wbcir_data *data;
1011 int err;
1012
1013 if (!(pnp_port_len(device, 0) == EHFUNC_IOMEM_LEN &&
1014 pnp_port_len(device, 1) == WAKEUP_IOMEM_LEN &&
1015 pnp_port_len(device, 2) == SP_IOMEM_LEN)) {
1016 dev_err(dev, "Invalid resources\n");
1017 return -ENODEV;
1018 }
1019
1020 data = kzalloc(sizeof(*data), GFP_KERNEL);
1021 if (!data) {
1022 err = -ENOMEM;
1023 goto exit;
1024 }
1025
1026 pnp_set_drvdata(device, data);
1027
1028 spin_lock_init(&data->spinlock);
1029 data->ebase = pnp_port_start(device, 0);
1030 data->wbase = pnp_port_start(device, 1);
1031 data->sbase = pnp_port_start(device, 2);
1032 data->irq = pnp_irq(device, 0);
1033
1034 if (data->wbase == 0 || data->ebase == 0 ||
1035 data->sbase == 0 || data->irq == -1) {
1036 err = -ENODEV;
1037 dev_err(dev, "Invalid resources\n");
1038 goto exit_free_data;
1039 }
1040
1041 dev_dbg(&device->dev, "Found device (w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n",
1042 data->wbase, data->ebase, data->sbase, data->irq);
1043
1044 data->led.name = "cir::activity";
1045 data->led.default_trigger = "rc-feedback";
1046 data->led.brightness_set = wbcir_led_brightness_set;
1047 data->led.brightness_get = wbcir_led_brightness_get;
1048 err = led_classdev_register(&device->dev, &data->led);
1049 if (err)
1050 goto exit_free_data;
1051
1052 data->dev = rc_allocate_device(RC_DRIVER_IR_RAW);
1053 if (!data->dev) {
1054 err = -ENOMEM;
1055 goto exit_unregister_led;
1056 }
1057
1058 data->dev->driver_name = DRVNAME;
1059 data->dev->device_name = WBCIR_NAME;
1060 data->dev->input_phys = "wbcir/cir0";
1061 data->dev->input_id.bustype = BUS_HOST;
1062 data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND;
1063 data->dev->input_id.product = WBCIR_ID_FAMILY;
1064 data->dev->input_id.version = WBCIR_ID_CHIP;
1065 data->dev->map_name = RC_MAP_RC6_MCE;
1066 data->dev->s_idle = wbcir_idle_rx;
1067 data->dev->s_carrier_report = wbcir_set_carrier_report;
1068 data->dev->s_tx_mask = wbcir_txmask;
1069 data->dev->s_tx_carrier = wbcir_txcarrier;
1070 data->dev->tx_ir = wbcir_tx;
1071 data->dev->priv = data;
1072 data->dev->dev.parent = &device->dev;
1073 data->dev->min_timeout = 1;
1074 data->dev->timeout = IR_DEFAULT_TIMEOUT;
1075 data->dev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
1076 data->dev->rx_resolution = 2;
1077 data->dev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
1078 data->dev->allowed_wakeup_protocols = RC_PROTO_BIT_NEC |
1079 RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC5 |
1080 RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 |
1081 RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 |
1082 RC_PROTO_BIT_RC6_MCE;
1083 data->dev->wakeup_protocol = RC_PROTO_RC6_MCE;
1084 data->dev->scancode_wakeup_filter.data = 0x800f040c;
1085 data->dev->scancode_wakeup_filter.mask = 0xffff7fff;
1086 data->dev->s_wakeup_filter = wbcir_set_wakeup_filter;
1087
1088 err = rc_register_device(data->dev);
1089 if (err)
1090 goto exit_free_rc;
1091
1092 if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) {
1093 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1094 data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1);
1095 err = -EBUSY;
1096 goto exit_unregister_device;
1097 }
1098
1099 if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) {
1100 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1101 data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1);
1102 err = -EBUSY;
1103 goto exit_release_wbase;
1104 }
1105
1106 if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) {
1107 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1108 data->sbase, data->sbase + SP_IOMEM_LEN - 1);
1109 err = -EBUSY;
1110 goto exit_release_ebase;
1111 }
1112
1113 err = request_irq(data->irq, wbcir_irq_handler,
1114 0, DRVNAME, device);
1115 if (err) {
1116 dev_err(dev, "Failed to claim IRQ %u\n", data->irq);
1117 err = -EBUSY;
1118 goto exit_release_sbase;
1119 }
1120
1121 device_init_wakeup(&device->dev, 1);
1122
1123 wbcir_init_hw(data);
1124
1125 return 0;
1126
1127 exit_release_sbase:
1128 release_region(data->sbase, SP_IOMEM_LEN);
1129 exit_release_ebase:
1130 release_region(data->ebase, EHFUNC_IOMEM_LEN);
1131 exit_release_wbase:
1132 release_region(data->wbase, WAKEUP_IOMEM_LEN);
1133 exit_unregister_device:
1134 rc_unregister_device(data->dev);
1135 data->dev = NULL;
1136 exit_free_rc:
1137 rc_free_device(data->dev);
1138 exit_unregister_led:
1139 led_classdev_unregister(&data->led);
1140 exit_free_data:
1141 kfree(data);
1142 pnp_set_drvdata(device, NULL);
1143 exit:
1144 return err;
1145 }
1146
1147 static void
1148 wbcir_remove(struct pnp_dev *device)
1149 {
1150 struct wbcir_data *data = pnp_get_drvdata(device);
1151
1152
1153 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
1154 free_irq(data->irq, device);
1155
1156
1157 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17);
1158
1159
1160 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
1161
1162
1163 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
1164
1165 rc_unregister_device(data->dev);
1166
1167 led_classdev_unregister(&data->led);
1168
1169
1170 wbcir_led_brightness_set(&data->led, LED_OFF);
1171
1172 release_region(data->wbase, WAKEUP_IOMEM_LEN);
1173 release_region(data->ebase, EHFUNC_IOMEM_LEN);
1174 release_region(data->sbase, SP_IOMEM_LEN);
1175
1176 kfree(data);
1177
1178 pnp_set_drvdata(device, NULL);
1179 }
1180
1181 static const struct pnp_device_id wbcir_ids[] = {
1182 { "WEC1022", 0 },
1183 { "", 0 }
1184 };
1185 MODULE_DEVICE_TABLE(pnp, wbcir_ids);
1186
1187 static struct pnp_driver wbcir_driver = {
1188 .name = DRVNAME,
1189 .id_table = wbcir_ids,
1190 .probe = wbcir_probe,
1191 .remove = wbcir_remove,
1192 .suspend = wbcir_suspend,
1193 .resume = wbcir_resume,
1194 .shutdown = wbcir_shutdown
1195 };
1196
1197 static int __init
1198 wbcir_init(void)
1199 {
1200 int ret;
1201
1202 ret = pnp_register_driver(&wbcir_driver);
1203 if (ret)
1204 pr_err("Unable to register driver\n");
1205
1206 return ret;
1207 }
1208
1209 static void __exit
1210 wbcir_exit(void)
1211 {
1212 pnp_unregister_driver(&wbcir_driver);
1213 }
1214
1215 module_init(wbcir_init);
1216 module_exit(wbcir_exit);
1217
1218 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
1219 MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver");
1220 MODULE_LICENSE("GPL");