Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

input: add a driver for the Winbond WPCD376I Consumer IR hardware

Add a driver for the the Consumer IR (CIR) functionality of the Winbond
WPCD376I chipset (found on e.g. Intel DG45FC motherboards).

Signed-off-by: David Härdeman <david@hardeman.nu>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Härdeman and committed by
Linus Torvalds
e258b80e abd6633c

+1637
+6
MAINTAINERS
··· 5640 5640 S: Maintained 5641 5641 F: drivers/scsi/wd7000.c 5642 5642 5643 + WINBOND CIR DRIVER 5644 + P: David H�rdeman 5645 + M: david@hardeman.nu 5646 + S: Maintained 5647 + F: drivers/input/misc/winbond-cir.c 5648 + 5643 5649 WIMAX STACK 5644 5650 M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 5645 5651 M: linux-wimax@intel.com
+16
drivers/input/misc/Kconfig
··· 222 222 To compile this driver as a module, choose M here: the 223 223 module will be called sgi_btns. 224 224 225 + config INPUT_WINBOND_CIR 226 + tristate "Winbond IR remote control" 227 + depends on X86 && PNP 228 + select LEDS_CLASS 229 + select BITREVERSE 230 + help 231 + Say Y here if you want to use the IR remote functionality found 232 + in some Winbond SuperI/O chips. Currently only the WPCD376I 233 + chip is supported (included in some Intel Media series motherboards). 234 + 235 + IR Receive and wake-on-IR from suspend and power-off is currently 236 + supported. 237 + 238 + To compile this driver as a module, choose M here: the module will be 239 + called winbond_cir. 240 + 225 241 config HP_SDC_RTC 226 242 tristate "HP SDC Real Time Clock" 227 243 depends on (GSC || HP300) && SERIO
+1
drivers/input/misc/Makefile
··· 26 26 obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o 27 27 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o 28 28 obj-$(CONFIG_INPUT_UINPUT) += uinput.o 29 + obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o 29 30 obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o 30 31 obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o 31 32 obj-$(CONFIG_INPUT_YEALINK) += yealink.o
+1614
drivers/input/misc/winbond-cir.c
··· 1 + /* 2 + * winbond-cir.c - Driver for the Consumer IR functionality of Winbond 3 + * SuperI/O chips. 4 + * 5 + * Currently supports the Winbond WPCD376i chip (PNP id WEC1022), but 6 + * could probably support others (Winbond WEC102X, NatSemi, etc) 7 + * with minor modifications. 8 + * 9 + * Original Author: David H�rdeman <david@hardeman.nu> 10 + * Copyright (C) 2009 David H�rdeman <david@hardeman.nu> 11 + * 12 + * Dedicated to Matilda, my newborn daughter, without whose loving attention 13 + * this driver would have been finished in half the time and with a fraction 14 + * of the bugs. 15 + * 16 + * Written using: 17 + * o Winbond WPCD376I datasheet helpfully provided by Jesse Barnes at Intel 18 + * o NatSemi PC87338/PC97338 datasheet (for the serial port stuff) 19 + * o DSDT dumps 20 + * 21 + * Supported features: 22 + * o RC6 23 + * o Wake-On-CIR functionality 24 + * 25 + * To do: 26 + * o Test NEC and RC5 27 + * 28 + * Left as an exercise for the reader: 29 + * o Learning (I have neither the hardware, nor the need) 30 + * o IR Transmit (ibid) 31 + * 32 + * This program is free software; you can redistribute it and/or modify 33 + * it under the terms of the GNU General Public License as published by 34 + * the Free Software Foundation; either version 2 of the License, or 35 + * (at your option) any later version. 36 + * 37 + * This program is distributed in the hope that it will be useful, 38 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 + * GNU General Public License for more details. 41 + * 42 + * You should have received a copy of the GNU General Public License 43 + * along with this program; if not, write to the Free Software 44 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 45 + */ 46 + 47 + #include <linux/module.h> 48 + #include <linux/pnp.h> 49 + #include <linux/interrupt.h> 50 + #include <linux/timer.h> 51 + #include <linux/input.h> 52 + #include <linux/leds.h> 53 + #include <linux/list.h> 54 + #include <linux/spinlock.h> 55 + #include <linux/pci_ids.h> 56 + #include <linux/io.h> 57 + #include <linux/bitrev.h> 58 + #include <linux/bitops.h> 59 + 60 + #define DRVNAME "winbond-cir" 61 + 62 + /* CEIR Wake-Up Registers, relative to data->wbase */ 63 + #define WBCIR_REG_WCEIR_CTL 0x03 /* CEIR Receiver Control */ 64 + #define WBCIR_REG_WCEIR_STS 0x04 /* CEIR Receiver Status */ 65 + #define WBCIR_REG_WCEIR_EV_EN 0x05 /* CEIR Receiver Event Enable */ 66 + #define WBCIR_REG_WCEIR_CNTL 0x06 /* CEIR Receiver Counter Low */ 67 + #define WBCIR_REG_WCEIR_CNTH 0x07 /* CEIR Receiver Counter High */ 68 + #define WBCIR_REG_WCEIR_INDEX 0x08 /* CEIR Receiver Index */ 69 + #define WBCIR_REG_WCEIR_DATA 0x09 /* CEIR Receiver Data */ 70 + #define WBCIR_REG_WCEIR_CSL 0x0A /* CEIR Re. Compare Strlen */ 71 + #define WBCIR_REG_WCEIR_CFG1 0x0B /* CEIR Re. Configuration 1 */ 72 + #define WBCIR_REG_WCEIR_CFG2 0x0C /* CEIR Re. Configuration 2 */ 73 + 74 + /* CEIR Enhanced Functionality Registers, relative to data->ebase */ 75 + #define WBCIR_REG_ECEIR_CTS 0x00 /* Enhanced IR Control Status */ 76 + #define WBCIR_REG_ECEIR_CCTL 0x01 /* Infrared Counter Control */ 77 + #define WBCIR_REG_ECEIR_CNT_LO 0x02 /* Infrared Counter LSB */ 78 + #define WBCIR_REG_ECEIR_CNT_HI 0x03 /* Infrared Counter MSB */ 79 + #define WBCIR_REG_ECEIR_IREM 0x04 /* Infrared Emitter Status */ 80 + 81 + /* SP3 Banked Registers, relative to data->sbase */ 82 + #define WBCIR_REG_SP3_BSR 0x03 /* Bank Select, all banks */ 83 + /* Bank 0 */ 84 + #define WBCIR_REG_SP3_RXDATA 0x00 /* FIFO RX data (r) */ 85 + #define WBCIR_REG_SP3_TXDATA 0x00 /* FIFO TX data (w) */ 86 + #define WBCIR_REG_SP3_IER 0x01 /* Interrupt Enable */ 87 + #define WBCIR_REG_SP3_EIR 0x02 /* Event Identification (r) */ 88 + #define WBCIR_REG_SP3_FCR 0x02 /* FIFO Control (w) */ 89 + #define WBCIR_REG_SP3_MCR 0x04 /* Mode Control */ 90 + #define WBCIR_REG_SP3_LSR 0x05 /* Link Status */ 91 + #define WBCIR_REG_SP3_MSR 0x06 /* Modem Status */ 92 + #define WBCIR_REG_SP3_ASCR 0x07 /* Aux Status and Control */ 93 + /* Bank 2 */ 94 + #define WBCIR_REG_SP3_BGDL 0x00 /* Baud Divisor LSB */ 95 + #define WBCIR_REG_SP3_BGDH 0x01 /* Baud Divisor MSB */ 96 + #define WBCIR_REG_SP3_EXCR1 0x02 /* Extended Control 1 */ 97 + #define WBCIR_REG_SP3_EXCR2 0x04 /* Extended Control 2 */ 98 + #define WBCIR_REG_SP3_TXFLV 0x06 /* TX FIFO Level */ 99 + #define WBCIR_REG_SP3_RXFLV 0x07 /* RX FIFO Level */ 100 + /* Bank 3 */ 101 + #define WBCIR_REG_SP3_MRID 0x00 /* Module Identification */ 102 + #define WBCIR_REG_SP3_SH_LCR 0x01 /* LCR Shadow */ 103 + #define WBCIR_REG_SP3_SH_FCR 0x02 /* FCR Shadow */ 104 + /* Bank 4 */ 105 + #define WBCIR_REG_SP3_IRCR1 0x02 /* Infrared Control 1 */ 106 + /* Bank 5 */ 107 + #define WBCIR_REG_SP3_IRCR2 0x04 /* Infrared Control 2 */ 108 + /* Bank 6 */ 109 + #define WBCIR_REG_SP3_IRCR3 0x00 /* Infrared Control 3 */ 110 + #define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */ 111 + /* Bank 7 */ 112 + #define WBCIR_REG_SP3_IRRXDC 0x00 /* IR RX Demod Control */ 113 + #define WBCIR_REG_SP3_IRTXMC 0x01 /* IR TX Mod Control */ 114 + #define WBCIR_REG_SP3_RCCFG 0x02 /* CEIR Config */ 115 + #define WBCIR_REG_SP3_IRCFG1 0x04 /* Infrared Config 1 */ 116 + #define WBCIR_REG_SP3_IRCFG4 0x07 /* Infrared Config 4 */ 117 + 118 + /* 119 + * Magic values follow 120 + */ 121 + 122 + /* No interrupts for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ 123 + #define WBCIR_IRQ_NONE 0x00 124 + /* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ 125 + #define WBCIR_IRQ_RX 0x01 126 + /* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ 127 + #define WBCIR_IRQ_ERR 0x04 128 + /* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */ 129 + #define WBCIR_LED_ENABLE 0x80 130 + /* RX data available bit for WBCIR_REG_SP3_LSR */ 131 + #define WBCIR_RX_AVAIL 0x01 132 + /* RX disable bit for WBCIR_REG_SP3_ASCR */ 133 + #define WBCIR_RX_DISABLE 0x20 134 + /* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */ 135 + #define WBCIR_EXT_ENABLE 0x01 136 + /* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ 137 + #define WBCIR_REGSEL_COMPARE 0x10 138 + /* Select mask register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ 139 + #define WBCIR_REGSEL_MASK 0x20 140 + /* Starting address of selected register in WBCIR_REG_WCEIR_INDEX */ 141 + #define WBCIR_REG_ADDR0 0x00 142 + 143 + /* Valid banks for the SP3 UART */ 144 + enum wbcir_bank { 145 + WBCIR_BANK_0 = 0x00, 146 + WBCIR_BANK_1 = 0x80, 147 + WBCIR_BANK_2 = 0xE0, 148 + WBCIR_BANK_3 = 0xE4, 149 + WBCIR_BANK_4 = 0xE8, 150 + WBCIR_BANK_5 = 0xEC, 151 + WBCIR_BANK_6 = 0xF0, 152 + WBCIR_BANK_7 = 0xF4, 153 + }; 154 + 155 + /* Supported IR Protocols */ 156 + enum wbcir_protocol { 157 + IR_PROTOCOL_RC5 = 0x0, 158 + IR_PROTOCOL_NEC = 0x1, 159 + IR_PROTOCOL_RC6 = 0x2, 160 + }; 161 + 162 + /* Misc */ 163 + #define WBCIR_NAME "Winbond CIR" 164 + #define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */ 165 + #define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */ 166 + #define IR_KEYPRESS_TIMEOUT 250 /* FIXME: should be per-protocol? */ 167 + #define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */ 168 + #define WAKEUP_IOMEM_LEN 0x10 /* Wake-Up I/O Reg Len */ 169 + #define EHFUNC_IOMEM_LEN 0x10 /* Enhanced Func I/O Reg Len */ 170 + #define SP_IOMEM_LEN 0x08 /* Serial Port 3 (IR) Reg Len */ 171 + #define WBCIR_MAX_IDLE_BYTES 10 172 + 173 + static DEFINE_SPINLOCK(wbcir_lock); 174 + static DEFINE_RWLOCK(keytable_lock); 175 + 176 + struct wbcir_key { 177 + u32 scancode; 178 + unsigned int keycode; 179 + }; 180 + 181 + struct wbcir_keyentry { 182 + struct wbcir_key key; 183 + struct list_head list; 184 + }; 185 + 186 + static struct wbcir_key rc6_def_keymap[] = { 187 + { 0x800F0400, KEY_NUMERIC_0 }, 188 + { 0x800F0401, KEY_NUMERIC_1 }, 189 + { 0x800F0402, KEY_NUMERIC_2 }, 190 + { 0x800F0403, KEY_NUMERIC_3 }, 191 + { 0x800F0404, KEY_NUMERIC_4 }, 192 + { 0x800F0405, KEY_NUMERIC_5 }, 193 + { 0x800F0406, KEY_NUMERIC_6 }, 194 + { 0x800F0407, KEY_NUMERIC_7 }, 195 + { 0x800F0408, KEY_NUMERIC_8 }, 196 + { 0x800F0409, KEY_NUMERIC_9 }, 197 + { 0x800F041D, KEY_NUMERIC_STAR }, 198 + { 0x800F041C, KEY_NUMERIC_POUND }, 199 + { 0x800F0410, KEY_VOLUMEUP }, 200 + { 0x800F0411, KEY_VOLUMEDOWN }, 201 + { 0x800F0412, KEY_CHANNELUP }, 202 + { 0x800F0413, KEY_CHANNELDOWN }, 203 + { 0x800F040E, KEY_MUTE }, 204 + { 0x800F040D, KEY_VENDOR }, /* Vista Logo Key */ 205 + { 0x800F041E, KEY_UP }, 206 + { 0x800F041F, KEY_DOWN }, 207 + { 0x800F0420, KEY_LEFT }, 208 + { 0x800F0421, KEY_RIGHT }, 209 + { 0x800F0422, KEY_OK }, 210 + { 0x800F0423, KEY_ESC }, 211 + { 0x800F040F, KEY_INFO }, 212 + { 0x800F040A, KEY_CLEAR }, 213 + { 0x800F040B, KEY_ENTER }, 214 + { 0x800F045B, KEY_RED }, 215 + { 0x800F045C, KEY_GREEN }, 216 + { 0x800F045D, KEY_YELLOW }, 217 + { 0x800F045E, KEY_BLUE }, 218 + { 0x800F045A, KEY_TEXT }, 219 + { 0x800F0427, KEY_SWITCHVIDEOMODE }, 220 + { 0x800F040C, KEY_POWER }, 221 + { 0x800F0450, KEY_RADIO }, 222 + { 0x800F0448, KEY_PVR }, 223 + { 0x800F0447, KEY_AUDIO }, 224 + { 0x800F0426, KEY_EPG }, 225 + { 0x800F0449, KEY_CAMERA }, 226 + { 0x800F0425, KEY_TV }, 227 + { 0x800F044A, KEY_VIDEO }, 228 + { 0x800F0424, KEY_DVD }, 229 + { 0x800F0416, KEY_PLAY }, 230 + { 0x800F0418, KEY_PAUSE }, 231 + { 0x800F0419, KEY_STOP }, 232 + { 0x800F0414, KEY_FASTFORWARD }, 233 + { 0x800F041A, KEY_NEXT }, 234 + { 0x800F041B, KEY_PREVIOUS }, 235 + { 0x800F0415, KEY_REWIND }, 236 + { 0x800F0417, KEY_RECORD }, 237 + }; 238 + 239 + /* Registers and other state is protected by wbcir_lock */ 240 + struct wbcir_data { 241 + unsigned long wbase; /* Wake-Up Baseaddr */ 242 + unsigned long ebase; /* Enhanced Func. Baseaddr */ 243 + unsigned long sbase; /* Serial Port Baseaddr */ 244 + unsigned int irq; /* Serial Port IRQ */ 245 + 246 + struct input_dev *input_dev; 247 + struct timer_list timer_keyup; 248 + struct led_trigger *rxtrigger; 249 + struct led_trigger *txtrigger; 250 + struct led_classdev led; 251 + 252 + u32 last_scancode; 253 + unsigned int last_keycode; 254 + u8 last_toggle; 255 + u8 keypressed; 256 + unsigned long keyup_jiffies; 257 + unsigned int idle_count; 258 + 259 + /* RX irdata and parsing state */ 260 + unsigned long irdata[30]; 261 + unsigned int irdata_count; 262 + unsigned int irdata_idle; 263 + unsigned int irdata_off; 264 + unsigned int irdata_error; 265 + 266 + /* Protected by keytable_lock */ 267 + struct list_head keytable; 268 + }; 269 + 270 + static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; 271 + module_param(protocol, uint, 0444); 272 + MODULE_PARM_DESC(protocol, "IR protocol to use " 273 + "(0 = RC5, 1 = NEC, 2 = RC6A, default)"); 274 + 275 + static int invert; /* default = 0 */ 276 + module_param(invert, bool, 0444); 277 + MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver"); 278 + 279 + static unsigned int wake_sc = 0x800F040C; 280 + module_param(wake_sc, uint, 0644); 281 + MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command"); 282 + 283 + static unsigned int wake_rc6mode = 6; 284 + module_param(wake_rc6mode, uint, 0644); 285 + MODULE_PARM_DESC(wake_rc6mode, "RC6 mode for the power-on command " 286 + "(0 = 0, 6 = 6A, default)"); 287 + 288 + 289 + 290 + /***************************************************************************** 291 + * 292 + * UTILITY FUNCTIONS 293 + * 294 + *****************************************************************************/ 295 + 296 + /* Caller needs to hold wbcir_lock */ 297 + static void 298 + wbcir_set_bits(unsigned long addr, u8 bits, u8 mask) 299 + { 300 + u8 val; 301 + 302 + val = inb(addr); 303 + val = ((val & ~mask) | (bits & mask)); 304 + outb(val, addr); 305 + } 306 + 307 + /* Selects the register bank for the serial port */ 308 + static inline void 309 + wbcir_select_bank(struct wbcir_data *data, enum wbcir_bank bank) 310 + { 311 + outb(bank, data->sbase + WBCIR_REG_SP3_BSR); 312 + } 313 + 314 + static enum led_brightness 315 + wbcir_led_brightness_get(struct led_classdev *led_cdev) 316 + { 317 + struct wbcir_data *data = container_of(led_cdev, 318 + struct wbcir_data, 319 + led); 320 + 321 + if (inb(data->ebase + WBCIR_REG_ECEIR_CTS) & WBCIR_LED_ENABLE) 322 + return LED_FULL; 323 + else 324 + return LED_OFF; 325 + } 326 + 327 + static void 328 + wbcir_led_brightness_set(struct led_classdev *led_cdev, 329 + enum led_brightness brightness) 330 + { 331 + struct wbcir_data *data = container_of(led_cdev, 332 + struct wbcir_data, 333 + led); 334 + 335 + wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, 336 + brightness == LED_OFF ? 0x00 : WBCIR_LED_ENABLE, 337 + WBCIR_LED_ENABLE); 338 + } 339 + 340 + /* Manchester encodes bits to RC6 message cells (see wbcir_parse_rc6) */ 341 + static u8 342 + wbcir_to_rc6cells(u8 val) 343 + { 344 + u8 coded = 0x00; 345 + int i; 346 + 347 + val &= 0x0F; 348 + for (i = 0; i < 4; i++) { 349 + if (val & 0x01) 350 + coded |= 0x02 << (i * 2); 351 + else 352 + coded |= 0x01 << (i * 2); 353 + val >>= 1; 354 + } 355 + 356 + return coded; 357 + } 358 + 359 + 360 + 361 + /***************************************************************************** 362 + * 363 + * INPUT FUNCTIONS 364 + * 365 + *****************************************************************************/ 366 + 367 + static unsigned int 368 + wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) 369 + { 370 + struct wbcir_keyentry *keyentry; 371 + unsigned int keycode = KEY_RESERVED; 372 + unsigned long flags; 373 + 374 + read_lock_irqsave(&keytable_lock, flags); 375 + 376 + list_for_each_entry(keyentry, &data->keytable, list) { 377 + if (keyentry->key.scancode == scancode) { 378 + keycode = keyentry->key.keycode; 379 + break; 380 + } 381 + } 382 + 383 + read_unlock_irqrestore(&keytable_lock, flags); 384 + return keycode; 385 + } 386 + 387 + static int 388 + wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode) 389 + { 390 + struct wbcir_data *data = input_get_drvdata(dev); 391 + 392 + *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode); 393 + return 0; 394 + } 395 + 396 + static int 397 + wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode) 398 + { 399 + struct wbcir_data *data = input_get_drvdata(dev); 400 + struct wbcir_keyentry *keyentry; 401 + struct wbcir_keyentry *new_keyentry; 402 + unsigned long flags; 403 + unsigned int old_keycode = KEY_RESERVED; 404 + u32 scancode = (u32)sscancode; 405 + 406 + if (keycode < 0 || keycode > KEY_MAX) 407 + return -EINVAL; 408 + 409 + new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); 410 + if (!new_keyentry) 411 + return -ENOMEM; 412 + 413 + write_lock_irqsave(&keytable_lock, flags); 414 + 415 + list_for_each_entry(keyentry, &data->keytable, list) { 416 + if (keyentry->key.scancode != scancode) 417 + continue; 418 + 419 + old_keycode = keyentry->key.keycode; 420 + keyentry->key.keycode = keycode; 421 + 422 + if (keyentry->key.keycode == KEY_RESERVED) { 423 + list_del(&keyentry->list); 424 + kfree(keyentry); 425 + } 426 + 427 + break; 428 + } 429 + 430 + set_bit(keycode, dev->keybit); 431 + 432 + if (old_keycode == KEY_RESERVED) { 433 + new_keyentry->key.scancode = scancode; 434 + new_keyentry->key.keycode = keycode; 435 + list_add(&new_keyentry->list, &data->keytable); 436 + } else { 437 + kfree(new_keyentry); 438 + clear_bit(old_keycode, dev->keybit); 439 + list_for_each_entry(keyentry, &data->keytable, list) { 440 + if (keyentry->key.keycode == old_keycode) { 441 + set_bit(old_keycode, dev->keybit); 442 + break; 443 + } 444 + } 445 + } 446 + 447 + write_unlock_irqrestore(&keytable_lock, flags); 448 + return 0; 449 + } 450 + 451 + /* 452 + * Timer function to report keyup event some time after keydown is 453 + * reported by the ISR. 454 + */ 455 + static void 456 + wbcir_keyup(unsigned long cookie) 457 + { 458 + struct wbcir_data *data = (struct wbcir_data *)cookie; 459 + unsigned long flags; 460 + 461 + /* 462 + * data->keyup_jiffies is used to prevent a race condition if a 463 + * hardware interrupt occurs at this point and the keyup timer 464 + * event is moved further into the future as a result. 465 + * 466 + * The timer will then be reactivated and this function called 467 + * again in the future. We need to exit gracefully in that case 468 + * to allow the input subsystem to do its auto-repeat magic or 469 + * a keyup event might follow immediately after the keydown. 470 + */ 471 + 472 + spin_lock_irqsave(&wbcir_lock, flags); 473 + 474 + if (time_is_after_eq_jiffies(data->keyup_jiffies) && data->keypressed) { 475 + data->keypressed = 0; 476 + led_trigger_event(data->rxtrigger, LED_OFF); 477 + input_report_key(data->input_dev, data->last_keycode, 0); 478 + input_sync(data->input_dev); 479 + } 480 + 481 + spin_unlock_irqrestore(&wbcir_lock, flags); 482 + } 483 + 484 + static void 485 + wbcir_keydown(struct wbcir_data *data, u32 scancode, u8 toggle) 486 + { 487 + unsigned int keycode; 488 + 489 + /* Repeat? */ 490 + if (data->last_scancode == scancode && 491 + data->last_toggle == toggle && 492 + data->keypressed) 493 + goto set_timer; 494 + data->last_scancode = scancode; 495 + 496 + /* Do we need to release an old keypress? */ 497 + if (data->keypressed) { 498 + input_report_key(data->input_dev, data->last_keycode, 0); 499 + input_sync(data->input_dev); 500 + data->keypressed = 0; 501 + } 502 + 503 + /* Report scancode */ 504 + input_event(data->input_dev, EV_MSC, MSC_SCAN, (int)scancode); 505 + 506 + /* Do we know this scancode? */ 507 + keycode = wbcir_do_getkeycode(data, scancode); 508 + if (keycode == KEY_RESERVED) 509 + goto set_timer; 510 + 511 + /* Register a keypress */ 512 + input_report_key(data->input_dev, keycode, 1); 513 + data->keypressed = 1; 514 + data->last_keycode = keycode; 515 + data->last_toggle = toggle; 516 + 517 + set_timer: 518 + input_sync(data->input_dev); 519 + led_trigger_event(data->rxtrigger, 520 + data->keypressed ? LED_FULL : LED_OFF); 521 + data->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); 522 + mod_timer(&data->timer_keyup, data->keyup_jiffies); 523 + } 524 + 525 + 526 + 527 + /***************************************************************************** 528 + * 529 + * IR PARSING FUNCTIONS 530 + * 531 + *****************************************************************************/ 532 + 533 + /* Resets all irdata */ 534 + static void 535 + wbcir_reset_irdata(struct wbcir_data *data) 536 + { 537 + memset(data->irdata, 0, sizeof(data->irdata)); 538 + data->irdata_count = 0; 539 + data->irdata_off = 0; 540 + data->irdata_error = 0; 541 + } 542 + 543 + /* Adds one bit of irdata */ 544 + static void 545 + add_irdata_bit(struct wbcir_data *data, int set) 546 + { 547 + if (data->irdata_count >= sizeof(data->irdata) * 8) { 548 + data->irdata_error = 1; 549 + return; 550 + } 551 + 552 + if (set) 553 + __set_bit(data->irdata_count, data->irdata); 554 + data->irdata_count++; 555 + } 556 + 557 + /* Gets count bits of irdata */ 558 + static u16 559 + get_bits(struct wbcir_data *data, int count) 560 + { 561 + u16 val = 0x0; 562 + 563 + if (data->irdata_count - data->irdata_off < count) { 564 + data->irdata_error = 1; 565 + return 0x0; 566 + } 567 + 568 + while (count > 0) { 569 + val <<= 1; 570 + if (test_bit(data->irdata_off, data->irdata)) 571 + val |= 0x1; 572 + count--; 573 + data->irdata_off++; 574 + } 575 + 576 + return val; 577 + } 578 + 579 + /* Reads 16 cells and converts them to a byte */ 580 + static u8 581 + wbcir_rc6cells_to_byte(struct wbcir_data *data) 582 + { 583 + u16 raw = get_bits(data, 16); 584 + u8 val = 0x00; 585 + int bit; 586 + 587 + for (bit = 0; bit < 8; bit++) { 588 + switch (raw & 0x03) { 589 + case 0x01: 590 + break; 591 + case 0x02: 592 + val |= (0x01 << bit); 593 + break; 594 + default: 595 + data->irdata_error = 1; 596 + break; 597 + } 598 + raw >>= 2; 599 + } 600 + 601 + return val; 602 + } 603 + 604 + /* Decodes a number of bits from raw RC5 data */ 605 + static u8 606 + wbcir_get_rc5bits(struct wbcir_data *data, unsigned int count) 607 + { 608 + u16 raw = get_bits(data, count * 2); 609 + u8 val = 0x00; 610 + int bit; 611 + 612 + for (bit = 0; bit < count; bit++) { 613 + switch (raw & 0x03) { 614 + case 0x01: 615 + val |= (0x01 << bit); 616 + break; 617 + case 0x02: 618 + break; 619 + default: 620 + data->irdata_error = 1; 621 + break; 622 + } 623 + raw >>= 2; 624 + } 625 + 626 + return val; 627 + } 628 + 629 + static void 630 + wbcir_parse_rc6(struct device *dev, struct wbcir_data *data) 631 + { 632 + /* 633 + * Normal bits are manchester coded as follows: 634 + * cell0 + cell1 = logic "0" 635 + * cell1 + cell0 = logic "1" 636 + * 637 + * The IR pulse has the following components: 638 + * 639 + * Leader - 6 * cell1 - discarded 640 + * Gap - 2 * cell0 - discarded 641 + * Start bit - Normal Coding - always "1" 642 + * Mode Bit 2 - 0 - Normal Coding 643 + * Toggle bit - Normal Coding with double bit time, 644 + * e.g. cell0 + cell0 + cell1 + cell1 645 + * means logic "0". 646 + * 647 + * The rest depends on the mode, the following modes are known: 648 + * 649 + * MODE 0: 650 + * Address Bit 7 - 0 - Normal Coding 651 + * Command Bit 7 - 0 - Normal Coding 652 + * 653 + * MODE 6: 654 + * The above Toggle Bit is used as a submode bit, 0 = A, 1 = B. 655 + * Submode B is for pointing devices, only remotes using submode A 656 + * are supported. 657 + * 658 + * Customer range bit - 0 => Customer = 7 bits, 0...127 659 + * 1 => Customer = 15 bits, 32768...65535 660 + * Customer Bits - Normal Coding 661 + * 662 + * Customer codes are allocated by Philips. The rest of the bits 663 + * are customer dependent. The following is commonly used (and the 664 + * only supported config): 665 + * 666 + * Toggle Bit - Normal Coding 667 + * Address Bit 6 - 0 - Normal Coding 668 + * Command Bit 7 - 0 - Normal Coding 669 + * 670 + * All modes are followed by at least 6 * cell0. 671 + * 672 + * MODE 0 msglen: 673 + * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (toggle) + 674 + * 8 * 2 (address) + 8 * 2 (command) = 675 + * 44 cells 676 + * 677 + * MODE 6A msglen: 678 + * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (submode) + 679 + * 1 * 2 (customer range bit) + 7/15 * 2 (customer bits) + 680 + * 1 * 2 (toggle bit) + 7 * 2 (address) + 8 * 2 (command) = 681 + * 60 - 76 cells 682 + */ 683 + u8 mode; 684 + u8 toggle; 685 + u16 customer = 0x0; 686 + u8 address; 687 + u8 command; 688 + u32 scancode; 689 + 690 + /* Leader mark */ 691 + while (get_bits(data, 1) && !data->irdata_error) 692 + /* Do nothing */; 693 + 694 + /* Leader space */ 695 + if (get_bits(data, 1)) { 696 + dev_dbg(dev, "RC6 - Invalid leader space\n"); 697 + return; 698 + } 699 + 700 + /* Start bit */ 701 + if (get_bits(data, 2) != 0x02) { 702 + dev_dbg(dev, "RC6 - Invalid start bit\n"); 703 + return; 704 + } 705 + 706 + /* Mode */ 707 + mode = get_bits(data, 6); 708 + switch (mode) { 709 + case 0x15: /* 010101 = b000 */ 710 + mode = 0; 711 + break; 712 + case 0x29: /* 101001 = b110 */ 713 + mode = 6; 714 + break; 715 + default: 716 + dev_dbg(dev, "RC6 - Invalid mode\n"); 717 + return; 718 + } 719 + 720 + /* Toggle bit / Submode bit */ 721 + toggle = get_bits(data, 4); 722 + switch (toggle) { 723 + case 0x03: 724 + toggle = 0; 725 + break; 726 + case 0x0C: 727 + toggle = 1; 728 + break; 729 + default: 730 + dev_dbg(dev, "RC6 - Toggle bit error\n"); 731 + break; 732 + } 733 + 734 + /* Customer */ 735 + if (mode == 6) { 736 + if (toggle != 0) { 737 + dev_dbg(dev, "RC6B - Not Supported\n"); 738 + return; 739 + } 740 + 741 + customer = wbcir_rc6cells_to_byte(data); 742 + 743 + if (customer & 0x80) { 744 + /* 15 bit customer value */ 745 + customer <<= 8; 746 + customer |= wbcir_rc6cells_to_byte(data); 747 + } 748 + } 749 + 750 + /* Address */ 751 + address = wbcir_rc6cells_to_byte(data); 752 + if (mode == 6) { 753 + toggle = address >> 7; 754 + address &= 0x7F; 755 + } 756 + 757 + /* Command */ 758 + command = wbcir_rc6cells_to_byte(data); 759 + 760 + /* Create scancode */ 761 + scancode = command; 762 + scancode |= address << 8; 763 + scancode |= customer << 16; 764 + 765 + /* Last sanity check */ 766 + if (data->irdata_error) { 767 + dev_dbg(dev, "RC6 - Cell error(s)\n"); 768 + return; 769 + } 770 + 771 + dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " 772 + "toggle %u mode %u scan 0x%08X\n", 773 + address, 774 + command, 775 + customer, 776 + (unsigned int)toggle, 777 + (unsigned int)mode, 778 + scancode); 779 + 780 + wbcir_keydown(data, scancode, toggle); 781 + } 782 + 783 + static void 784 + wbcir_parse_rc5(struct device *dev, struct wbcir_data *data) 785 + { 786 + /* 787 + * Bits are manchester coded as follows: 788 + * cell1 + cell0 = logic "0" 789 + * cell0 + cell1 = logic "1" 790 + * (i.e. the reverse of RC6) 791 + * 792 + * Start bit 1 - "1" - discarded 793 + * Start bit 2 - Must be inverted to get command bit 6 794 + * Toggle bit 795 + * Address Bit 4 - 0 796 + * Command Bit 5 - 0 797 + */ 798 + u8 toggle; 799 + u8 address; 800 + u8 command; 801 + u32 scancode; 802 + 803 + /* Start bit 1 */ 804 + if (!get_bits(data, 1)) { 805 + dev_dbg(dev, "RC5 - Invalid start bit\n"); 806 + return; 807 + } 808 + 809 + /* Start bit 2 */ 810 + if (!wbcir_get_rc5bits(data, 1)) 811 + command = 0x40; 812 + else 813 + command = 0x00; 814 + 815 + toggle = wbcir_get_rc5bits(data, 1); 816 + address = wbcir_get_rc5bits(data, 5); 817 + command |= wbcir_get_rc5bits(data, 6); 818 + scancode = address << 7 | command; 819 + 820 + /* Last sanity check */ 821 + if (data->irdata_error) { 822 + dev_dbg(dev, "RC5 - Invalid message\n"); 823 + return; 824 + } 825 + 826 + dev_dbg(dev, "IR-RC5 ad %u cm %u t %u s %u\n", 827 + (unsigned int)address, 828 + (unsigned int)command, 829 + (unsigned int)toggle, 830 + (unsigned int)scancode); 831 + 832 + wbcir_keydown(data, scancode, toggle); 833 + } 834 + 835 + static void 836 + wbcir_parse_nec(struct device *dev, struct wbcir_data *data) 837 + { 838 + /* 839 + * Each bit represents 560 us. 840 + * 841 + * Leader - 9 ms burst 842 + * Gap - 4.5 ms silence 843 + * Address1 bit 0 - 7 - Address 1 844 + * Address2 bit 0 - 7 - Address 2 845 + * Command1 bit 0 - 7 - Command 1 846 + * Command2 bit 0 - 7 - Command 2 847 + * 848 + * Note the bit order! 849 + * 850 + * With the old NEC protocol, Address2 was the inverse of Address1 851 + * and Command2 was the inverse of Command1 and were used as 852 + * an error check. 853 + * 854 + * With NEC extended, Address1 is the LSB of the Address and 855 + * Address2 is the MSB, Command parsing remains unchanged. 856 + * 857 + * A repeat message is coded as: 858 + * Leader - 9 ms burst 859 + * Gap - 2.25 ms silence 860 + * Repeat - 560 us active 861 + */ 862 + u8 address1; 863 + u8 address2; 864 + u8 command1; 865 + u8 command2; 866 + u16 address; 867 + u32 scancode; 868 + 869 + /* Leader mark */ 870 + while (get_bits(data, 1) && !data->irdata_error) 871 + /* Do nothing */; 872 + 873 + /* Leader space */ 874 + if (get_bits(data, 4)) { 875 + dev_dbg(dev, "NEC - Invalid leader space\n"); 876 + return; 877 + } 878 + 879 + /* Repeat? */ 880 + if (get_bits(data, 1)) { 881 + if (!data->keypressed) { 882 + dev_dbg(dev, "NEC - Stray repeat message\n"); 883 + return; 884 + } 885 + 886 + dev_dbg(dev, "IR-NEC repeat s %u\n", 887 + (unsigned int)data->last_scancode); 888 + 889 + wbcir_keydown(data, data->last_scancode, data->last_toggle); 890 + return; 891 + } 892 + 893 + /* Remaining leader space */ 894 + if (get_bits(data, 3)) { 895 + dev_dbg(dev, "NEC - Invalid leader space\n"); 896 + return; 897 + } 898 + 899 + address1 = bitrev8(get_bits(data, 8)); 900 + address2 = bitrev8(get_bits(data, 8)); 901 + command1 = bitrev8(get_bits(data, 8)); 902 + command2 = bitrev8(get_bits(data, 8)); 903 + 904 + /* Sanity check */ 905 + if (data->irdata_error) { 906 + dev_dbg(dev, "NEC - Invalid message\n"); 907 + return; 908 + } 909 + 910 + /* Check command validity */ 911 + if (command1 != ~command2) { 912 + dev_dbg(dev, "NEC - Command bytes mismatch\n"); 913 + return; 914 + } 915 + 916 + /* Check for extended NEC protocol */ 917 + address = address1; 918 + if (address1 != ~address2) 919 + address |= address2 << 8; 920 + 921 + scancode = address << 8 | command1; 922 + 923 + dev_dbg(dev, "IR-NEC ad %u cm %u s %u\n", 924 + (unsigned int)address, 925 + (unsigned int)command1, 926 + (unsigned int)scancode); 927 + 928 + wbcir_keydown(data, scancode, !data->last_toggle); 929 + } 930 + 931 + 932 + 933 + /***************************************************************************** 934 + * 935 + * INTERRUPT FUNCTIONS 936 + * 937 + *****************************************************************************/ 938 + 939 + static irqreturn_t 940 + wbcir_irq_handler(int irqno, void *cookie) 941 + { 942 + struct pnp_dev *device = cookie; 943 + struct wbcir_data *data = pnp_get_drvdata(device); 944 + struct device *dev = &device->dev; 945 + u8 status; 946 + unsigned long flags; 947 + u8 irdata[8]; 948 + int i; 949 + unsigned int hw; 950 + 951 + spin_lock_irqsave(&wbcir_lock, flags); 952 + 953 + wbcir_select_bank(data, WBCIR_BANK_0); 954 + 955 + status = inb(data->sbase + WBCIR_REG_SP3_EIR); 956 + 957 + if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) { 958 + spin_unlock_irqrestore(&wbcir_lock, flags); 959 + return IRQ_NONE; 960 + } 961 + 962 + if (status & WBCIR_IRQ_ERR) 963 + data->irdata_error = 1; 964 + 965 + if (!(status & WBCIR_IRQ_RX)) 966 + goto out; 967 + 968 + /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ 969 + insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8); 970 + 971 + for (i = 0; i < sizeof(irdata); i++) { 972 + hw = hweight8(irdata[i]); 973 + if (hw > 4) 974 + add_irdata_bit(data, 0); 975 + else 976 + add_irdata_bit(data, 1); 977 + 978 + if (hw == 8) 979 + data->idle_count++; 980 + else 981 + data->idle_count = 0; 982 + } 983 + 984 + if (data->idle_count > WBCIR_MAX_IDLE_BYTES) { 985 + /* Set RXINACTIVE... */ 986 + outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); 987 + 988 + /* ...and drain the FIFO */ 989 + while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) 990 + inb(data->sbase + WBCIR_REG_SP3_RXDATA); 991 + 992 + dev_dbg(dev, "IRDATA:\n"); 993 + for (i = 0; i < data->irdata_count; i += BITS_PER_LONG) 994 + dev_dbg(dev, "0x%08lX\n", data->irdata[i/BITS_PER_LONG]); 995 + 996 + switch (protocol) { 997 + case IR_PROTOCOL_RC5: 998 + wbcir_parse_rc5(dev, data); 999 + break; 1000 + case IR_PROTOCOL_RC6: 1001 + wbcir_parse_rc6(dev, data); 1002 + break; 1003 + case IR_PROTOCOL_NEC: 1004 + wbcir_parse_nec(dev, data); 1005 + break; 1006 + } 1007 + 1008 + wbcir_reset_irdata(data); 1009 + data->idle_count = 0; 1010 + } 1011 + 1012 + out: 1013 + spin_unlock_irqrestore(&wbcir_lock, flags); 1014 + return IRQ_HANDLED; 1015 + } 1016 + 1017 + 1018 + 1019 + /***************************************************************************** 1020 + * 1021 + * SUSPEND/RESUME FUNCTIONS 1022 + * 1023 + *****************************************************************************/ 1024 + 1025 + static void 1026 + wbcir_shutdown(struct pnp_dev *device) 1027 + { 1028 + struct device *dev = &device->dev; 1029 + struct wbcir_data *data = pnp_get_drvdata(device); 1030 + int do_wake = 1; 1031 + u8 match[11]; 1032 + u8 mask[11]; 1033 + u8 rc6_csl = 0; 1034 + int i; 1035 + 1036 + memset(match, 0, sizeof(match)); 1037 + memset(mask, 0, sizeof(mask)); 1038 + 1039 + if (wake_sc == INVALID_SCANCODE || !device_may_wakeup(dev)) { 1040 + do_wake = 0; 1041 + goto finish; 1042 + } 1043 + 1044 + switch (protocol) { 1045 + case IR_PROTOCOL_RC5: 1046 + if (wake_sc > 0xFFF) { 1047 + do_wake = 0; 1048 + dev_err(dev, "RC5 - Invalid wake scancode\n"); 1049 + break; 1050 + } 1051 + 1052 + /* Mask = 13 bits, ex toggle */ 1053 + mask[0] = 0xFF; 1054 + mask[1] = 0x17; 1055 + 1056 + match[0] = (wake_sc & 0x003F); /* 6 command bits */ 1057 + match[0] |= (wake_sc & 0x0180) >> 1; /* 2 address bits */ 1058 + match[1] = (wake_sc & 0x0E00) >> 9; /* 3 address bits */ 1059 + if (!(wake_sc & 0x0040)) /* 2nd start bit */ 1060 + match[1] |= 0x10; 1061 + 1062 + break; 1063 + 1064 + case IR_PROTOCOL_NEC: 1065 + if (wake_sc > 0xFFFFFF) { 1066 + do_wake = 0; 1067 + dev_err(dev, "NEC - Invalid wake scancode\n"); 1068 + break; 1069 + } 1070 + 1071 + mask[0] = mask[1] = mask[2] = mask[3] = 0xFF; 1072 + 1073 + match[1] = bitrev8((wake_sc & 0xFF)); 1074 + match[0] = ~match[1]; 1075 + 1076 + match[3] = bitrev8((wake_sc & 0xFF00) >> 8); 1077 + if (wake_sc > 0xFFFF) 1078 + match[2] = bitrev8((wake_sc & 0xFF0000) >> 16); 1079 + else 1080 + match[2] = ~match[3]; 1081 + 1082 + break; 1083 + 1084 + case IR_PROTOCOL_RC6: 1085 + 1086 + if (wake_rc6mode == 0) { 1087 + if (wake_sc > 0xFFFF) { 1088 + do_wake = 0; 1089 + dev_err(dev, "RC6 - Invalid wake scancode\n"); 1090 + break; 1091 + } 1092 + 1093 + /* Command */ 1094 + match[0] = wbcir_to_rc6cells(wake_sc >> 0); 1095 + mask[0] = 0xFF; 1096 + match[1] = wbcir_to_rc6cells(wake_sc >> 4); 1097 + mask[1] = 0xFF; 1098 + 1099 + /* Address */ 1100 + match[2] = wbcir_to_rc6cells(wake_sc >> 8); 1101 + mask[2] = 0xFF; 1102 + match[3] = wbcir_to_rc6cells(wake_sc >> 12); 1103 + mask[3] = 0xFF; 1104 + 1105 + /* Header */ 1106 + match[4] = 0x50; /* mode1 = mode0 = 0, ignore toggle */ 1107 + mask[4] = 0xF0; 1108 + match[5] = 0x09; /* start bit = 1, mode2 = 0 */ 1109 + mask[5] = 0x0F; 1110 + 1111 + rc6_csl = 44; 1112 + 1113 + } else if (wake_rc6mode == 6) { 1114 + i = 0; 1115 + 1116 + /* Command */ 1117 + match[i] = wbcir_to_rc6cells(wake_sc >> 0); 1118 + mask[i++] = 0xFF; 1119 + match[i] = wbcir_to_rc6cells(wake_sc >> 4); 1120 + mask[i++] = 0xFF; 1121 + 1122 + /* Address + Toggle */ 1123 + match[i] = wbcir_to_rc6cells(wake_sc >> 8); 1124 + mask[i++] = 0xFF; 1125 + match[i] = wbcir_to_rc6cells(wake_sc >> 12); 1126 + mask[i++] = 0x3F; 1127 + 1128 + /* Customer bits 7 - 0 */ 1129 + match[i] = wbcir_to_rc6cells(wake_sc >> 16); 1130 + mask[i++] = 0xFF; 1131 + match[i] = wbcir_to_rc6cells(wake_sc >> 20); 1132 + mask[i++] = 0xFF; 1133 + 1134 + if (wake_sc & 0x80000000) { 1135 + /* Customer range bit and bits 15 - 8 */ 1136 + match[i] = wbcir_to_rc6cells(wake_sc >> 24); 1137 + mask[i++] = 0xFF; 1138 + match[i] = wbcir_to_rc6cells(wake_sc >> 28); 1139 + mask[i++] = 0xFF; 1140 + rc6_csl = 76; 1141 + } else if (wake_sc <= 0x007FFFFF) { 1142 + rc6_csl = 60; 1143 + } else { 1144 + do_wake = 0; 1145 + dev_err(dev, "RC6 - Invalid wake scancode\n"); 1146 + break; 1147 + } 1148 + 1149 + /* Header */ 1150 + match[i] = 0x93; /* mode1 = mode0 = 1, submode = 0 */ 1151 + mask[i++] = 0xFF; 1152 + match[i] = 0x0A; /* start bit = 1, mode2 = 1 */ 1153 + mask[i++] = 0x0F; 1154 + 1155 + } else { 1156 + do_wake = 0; 1157 + dev_err(dev, "RC6 - Invalid wake mode\n"); 1158 + } 1159 + 1160 + break; 1161 + 1162 + default: 1163 + do_wake = 0; 1164 + break; 1165 + } 1166 + 1167 + finish: 1168 + if (do_wake) { 1169 + /* Set compare and compare mask */ 1170 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX, 1171 + WBCIR_REGSEL_COMPARE | WBCIR_REG_ADDR0, 1172 + 0x3F); 1173 + outsb(data->wbase + WBCIR_REG_WCEIR_DATA, match, 11); 1174 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX, 1175 + WBCIR_REGSEL_MASK | WBCIR_REG_ADDR0, 1176 + 0x3F); 1177 + outsb(data->wbase + WBCIR_REG_WCEIR_DATA, mask, 11); 1178 + 1179 + /* RC6 Compare String Len */ 1180 + outb(rc6_csl, data->wbase + WBCIR_REG_WCEIR_CSL); 1181 + 1182 + /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ 1183 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); 1184 + 1185 + /* Clear BUFF_EN, Clear END_EN, Set MATCH_EN */ 1186 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x01, 0x07); 1187 + 1188 + /* Set CEIR_EN */ 1189 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x01, 0x01); 1190 + 1191 + } else { 1192 + /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ 1193 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); 1194 + 1195 + /* Clear CEIR_EN */ 1196 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); 1197 + } 1198 + 1199 + /* Disable interrupts */ 1200 + outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); 1201 + } 1202 + 1203 + static int 1204 + wbcir_suspend(struct pnp_dev *device, pm_message_t state) 1205 + { 1206 + wbcir_shutdown(device); 1207 + return 0; 1208 + } 1209 + 1210 + static int 1211 + wbcir_resume(struct pnp_dev *device) 1212 + { 1213 + struct wbcir_data *data = pnp_get_drvdata(device); 1214 + 1215 + /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ 1216 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); 1217 + 1218 + /* Clear CEIR_EN */ 1219 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); 1220 + 1221 + /* Enable interrupts */ 1222 + wbcir_reset_irdata(data); 1223 + outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); 1224 + 1225 + return 0; 1226 + } 1227 + 1228 + 1229 + 1230 + /***************************************************************************** 1231 + * 1232 + * SETUP/INIT FUNCTIONS 1233 + * 1234 + *****************************************************************************/ 1235 + 1236 + static void 1237 + wbcir_cfg_ceir(struct wbcir_data *data) 1238 + { 1239 + u8 tmp; 1240 + 1241 + /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ 1242 + tmp = protocol << 4; 1243 + if (invert) 1244 + tmp |= 0x08; 1245 + outb(tmp, data->wbase + WBCIR_REG_WCEIR_CTL); 1246 + 1247 + /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ 1248 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); 1249 + 1250 + /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ 1251 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); 1252 + 1253 + /* Set RC5 cell time to correspond to 36 kHz */ 1254 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CFG1, 0x4A, 0x7F); 1255 + 1256 + /* Set IRTX_INV */ 1257 + if (invert) 1258 + outb(0x04, data->ebase + WBCIR_REG_ECEIR_CCTL); 1259 + else 1260 + outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL); 1261 + 1262 + /* 1263 + * Clear IR LED, set SP3 clock to 24Mhz 1264 + * set SP3_IRRX_SW to binary 01, helpfully not documented 1265 + */ 1266 + outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); 1267 + } 1268 + 1269 + static int __devinit 1270 + wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) 1271 + { 1272 + struct device *dev = &device->dev; 1273 + struct wbcir_data *data; 1274 + int err; 1275 + 1276 + if (!(pnp_port_len(device, 0) == EHFUNC_IOMEM_LEN && 1277 + pnp_port_len(device, 1) == WAKEUP_IOMEM_LEN && 1278 + pnp_port_len(device, 2) == SP_IOMEM_LEN)) { 1279 + dev_err(dev, "Invalid resources\n"); 1280 + return -ENODEV; 1281 + } 1282 + 1283 + data = kzalloc(sizeof(*data), GFP_KERNEL); 1284 + if (!data) { 1285 + err = -ENOMEM; 1286 + goto exit; 1287 + } 1288 + 1289 + pnp_set_drvdata(device, data); 1290 + 1291 + data->ebase = pnp_port_start(device, 0); 1292 + data->wbase = pnp_port_start(device, 1); 1293 + data->sbase = pnp_port_start(device, 2); 1294 + data->irq = pnp_irq(device, 0); 1295 + 1296 + if (data->wbase == 0 || data->ebase == 0 || 1297 + data->sbase == 0 || data->irq == 0) { 1298 + err = -ENODEV; 1299 + dev_err(dev, "Invalid resources\n"); 1300 + goto exit_free_data; 1301 + } 1302 + 1303 + dev_dbg(&device->dev, "Found device " 1304 + "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", 1305 + data->wbase, data->ebase, data->sbase, data->irq); 1306 + 1307 + if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { 1308 + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", 1309 + data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); 1310 + err = -EBUSY; 1311 + goto exit_free_data; 1312 + } 1313 + 1314 + if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { 1315 + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", 1316 + data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); 1317 + err = -EBUSY; 1318 + goto exit_release_wbase; 1319 + } 1320 + 1321 + if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { 1322 + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", 1323 + data->sbase, data->sbase + SP_IOMEM_LEN - 1); 1324 + err = -EBUSY; 1325 + goto exit_release_ebase; 1326 + } 1327 + 1328 + err = request_irq(data->irq, wbcir_irq_handler, 1329 + IRQF_DISABLED, DRVNAME, device); 1330 + if (err) { 1331 + dev_err(dev, "Failed to claim IRQ %u\n", data->irq); 1332 + err = -EBUSY; 1333 + goto exit_release_sbase; 1334 + } 1335 + 1336 + led_trigger_register_simple("cir-tx", &data->txtrigger); 1337 + if (!data->txtrigger) { 1338 + err = -ENOMEM; 1339 + goto exit_free_irq; 1340 + } 1341 + 1342 + led_trigger_register_simple("cir-rx", &data->rxtrigger); 1343 + if (!data->rxtrigger) { 1344 + err = -ENOMEM; 1345 + goto exit_unregister_txtrigger; 1346 + } 1347 + 1348 + data->led.name = "cir::activity"; 1349 + data->led.default_trigger = "cir-rx"; 1350 + data->led.brightness_set = wbcir_led_brightness_set; 1351 + data->led.brightness_get = wbcir_led_brightness_get; 1352 + err = led_classdev_register(&device->dev, &data->led); 1353 + if (err) 1354 + goto exit_unregister_rxtrigger; 1355 + 1356 + data->input_dev = input_allocate_device(); 1357 + if (!data->input_dev) { 1358 + err = -ENOMEM; 1359 + goto exit_unregister_led; 1360 + } 1361 + 1362 + data->input_dev->evbit[0] = BIT(EV_KEY); 1363 + data->input_dev->name = WBCIR_NAME; 1364 + data->input_dev->phys = "wbcir/cir0"; 1365 + data->input_dev->id.bustype = BUS_HOST; 1366 + data->input_dev->id.vendor = PCI_VENDOR_ID_WINBOND; 1367 + data->input_dev->id.product = WBCIR_ID_FAMILY; 1368 + data->input_dev->id.version = WBCIR_ID_CHIP; 1369 + data->input_dev->getkeycode = wbcir_getkeycode; 1370 + data->input_dev->setkeycode = wbcir_setkeycode; 1371 + input_set_capability(data->input_dev, EV_MSC, MSC_SCAN); 1372 + input_set_drvdata(data->input_dev, data); 1373 + 1374 + err = input_register_device(data->input_dev); 1375 + if (err) 1376 + goto exit_free_input; 1377 + 1378 + data->last_scancode = INVALID_SCANCODE; 1379 + INIT_LIST_HEAD(&data->keytable); 1380 + setup_timer(&data->timer_keyup, wbcir_keyup, (unsigned long)data); 1381 + 1382 + /* Load default keymaps */ 1383 + if (protocol == IR_PROTOCOL_RC6) { 1384 + int i; 1385 + for (i = 0; i < ARRAY_SIZE(rc6_def_keymap); i++) { 1386 + err = wbcir_setkeycode(data->input_dev, 1387 + (int)rc6_def_keymap[i].scancode, 1388 + (int)rc6_def_keymap[i].keycode); 1389 + if (err) 1390 + goto exit_unregister_keys; 1391 + } 1392 + } 1393 + 1394 + device_init_wakeup(&device->dev, 1); 1395 + 1396 + wbcir_cfg_ceir(data); 1397 + 1398 + /* Disable interrupts */ 1399 + wbcir_select_bank(data, WBCIR_BANK_0); 1400 + outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); 1401 + 1402 + /* Enable extended mode */ 1403 + wbcir_select_bank(data, WBCIR_BANK_2); 1404 + outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); 1405 + 1406 + /* 1407 + * Configure baud generator, IR data will be sampled at 1408 + * a bitrate of: (24Mhz * prescaler) / (divisor * 16). 1409 + * 1410 + * The ECIR registers include a flag to change the 1411 + * 24Mhz clock freq to 48Mhz. 1412 + * 1413 + * It's not documented in the specs, but fifo levels 1414 + * other than 16 seems to be unsupported. 1415 + */ 1416 + 1417 + /* prescaler 1.0, tx/rx fifo lvl 16 */ 1418 + outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); 1419 + 1420 + /* Set baud divisor to generate one byte per bit/cell */ 1421 + switch (protocol) { 1422 + case IR_PROTOCOL_RC5: 1423 + outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); 1424 + break; 1425 + case IR_PROTOCOL_RC6: 1426 + outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); 1427 + break; 1428 + case IR_PROTOCOL_NEC: 1429 + outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); 1430 + break; 1431 + } 1432 + outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); 1433 + 1434 + /* Set CEIR mode */ 1435 + wbcir_select_bank(data, WBCIR_BANK_0); 1436 + outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); 1437 + inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ 1438 + inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ 1439 + 1440 + /* Disable RX demod, run-length encoding/decoding, set freq span */ 1441 + wbcir_select_bank(data, WBCIR_BANK_7); 1442 + outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); 1443 + 1444 + /* Disable timer */ 1445 + wbcir_select_bank(data, WBCIR_BANK_4); 1446 + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); 1447 + 1448 + /* Enable MSR interrupt, Clear AUX_IRX */ 1449 + wbcir_select_bank(data, WBCIR_BANK_5); 1450 + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); 1451 + 1452 + /* Disable CRC */ 1453 + wbcir_select_bank(data, WBCIR_BANK_6); 1454 + outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); 1455 + 1456 + /* Set RX/TX (de)modulation freq, not really used */ 1457 + wbcir_select_bank(data, WBCIR_BANK_7); 1458 + outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); 1459 + outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); 1460 + 1461 + /* Set invert and pin direction */ 1462 + if (invert) 1463 + outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); 1464 + else 1465 + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); 1466 + 1467 + /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ 1468 + wbcir_select_bank(data, WBCIR_BANK_0); 1469 + outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); 1470 + 1471 + /* Clear AUX status bits */ 1472 + outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); 1473 + 1474 + /* Enable interrupts */ 1475 + outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); 1476 + 1477 + return 0; 1478 + 1479 + exit_unregister_keys: 1480 + if (!list_empty(&data->keytable)) { 1481 + struct wbcir_keyentry *key; 1482 + struct wbcir_keyentry *keytmp; 1483 + 1484 + list_for_each_entry_safe(key, keytmp, &data->keytable, list) { 1485 + list_del(&key->list); 1486 + kfree(key); 1487 + } 1488 + } 1489 + input_unregister_device(data->input_dev); 1490 + /* Can't call input_free_device on an unregistered device */ 1491 + data->input_dev = NULL; 1492 + exit_free_input: 1493 + input_free_device(data->input_dev); 1494 + exit_unregister_led: 1495 + led_classdev_unregister(&data->led); 1496 + exit_unregister_rxtrigger: 1497 + led_trigger_unregister_simple(data->rxtrigger); 1498 + exit_unregister_txtrigger: 1499 + led_trigger_unregister_simple(data->txtrigger); 1500 + exit_free_irq: 1501 + free_irq(data->irq, device); 1502 + exit_release_sbase: 1503 + release_region(data->sbase, SP_IOMEM_LEN); 1504 + exit_release_ebase: 1505 + release_region(data->ebase, EHFUNC_IOMEM_LEN); 1506 + exit_release_wbase: 1507 + release_region(data->wbase, WAKEUP_IOMEM_LEN); 1508 + exit_free_data: 1509 + kfree(data); 1510 + pnp_set_drvdata(device, NULL); 1511 + exit: 1512 + return err; 1513 + } 1514 + 1515 + static void __devexit 1516 + wbcir_remove(struct pnp_dev *device) 1517 + { 1518 + struct wbcir_data *data = pnp_get_drvdata(device); 1519 + struct wbcir_keyentry *key; 1520 + struct wbcir_keyentry *keytmp; 1521 + 1522 + /* Disable interrupts */ 1523 + wbcir_select_bank(data, WBCIR_BANK_0); 1524 + outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); 1525 + 1526 + del_timer_sync(&data->timer_keyup); 1527 + 1528 + free_irq(data->irq, device); 1529 + 1530 + /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ 1531 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); 1532 + 1533 + /* Clear CEIR_EN */ 1534 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); 1535 + 1536 + /* Clear BUFF_EN, END_EN, MATCH_EN */ 1537 + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); 1538 + 1539 + /* This will generate a keyup event if necessary */ 1540 + input_unregister_device(data->input_dev); 1541 + 1542 + led_trigger_unregister_simple(data->rxtrigger); 1543 + led_trigger_unregister_simple(data->txtrigger); 1544 + led_classdev_unregister(&data->led); 1545 + 1546 + /* This is ok since &data->led isn't actually used */ 1547 + wbcir_led_brightness_set(&data->led, LED_OFF); 1548 + 1549 + release_region(data->wbase, WAKEUP_IOMEM_LEN); 1550 + release_region(data->ebase, EHFUNC_IOMEM_LEN); 1551 + release_region(data->sbase, SP_IOMEM_LEN); 1552 + 1553 + list_for_each_entry_safe(key, keytmp, &data->keytable, list) { 1554 + list_del(&key->list); 1555 + kfree(key); 1556 + } 1557 + 1558 + kfree(data); 1559 + 1560 + pnp_set_drvdata(device, NULL); 1561 + } 1562 + 1563 + static const struct pnp_device_id wbcir_ids[] = { 1564 + { "WEC1022", 0 }, 1565 + { "", 0 } 1566 + }; 1567 + MODULE_DEVICE_TABLE(pnp, wbcir_ids); 1568 + 1569 + static struct pnp_driver wbcir_driver = { 1570 + .name = WBCIR_NAME, 1571 + .id_table = wbcir_ids, 1572 + .probe = wbcir_probe, 1573 + .remove = __devexit_p(wbcir_remove), 1574 + .suspend = wbcir_suspend, 1575 + .resume = wbcir_resume, 1576 + .shutdown = wbcir_shutdown 1577 + }; 1578 + 1579 + static int __init 1580 + wbcir_init(void) 1581 + { 1582 + int ret; 1583 + 1584 + switch (protocol) { 1585 + case IR_PROTOCOL_RC5: 1586 + case IR_PROTOCOL_NEC: 1587 + case IR_PROTOCOL_RC6: 1588 + break; 1589 + default: 1590 + printk(KERN_ERR DRVNAME ": Invalid protocol argument\n"); 1591 + return -EINVAL; 1592 + } 1593 + 1594 + ret = pnp_register_driver(&wbcir_driver); 1595 + if (ret) 1596 + printk(KERN_ERR DRVNAME ": Unable to register driver\n"); 1597 + 1598 + return ret; 1599 + } 1600 + 1601 + static void __exit 1602 + wbcir_exit(void) 1603 + { 1604 + pnp_unregister_driver(&wbcir_driver); 1605 + } 1606 + 1607 + MODULE_AUTHOR("David H�rdeman <david@hardeman.nu>"); 1608 + MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver"); 1609 + MODULE_LICENSE("GPL"); 1610 + 1611 + module_init(wbcir_init); 1612 + module_exit(wbcir_exit); 1613 + 1614 +