aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2011-04-28 11:13:22 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-05-20 08:29:51 -0400
commitc829f2672f312f2c19dc021b233a45d3dd850a4f (patch)
tree3d74712f745ea3061c947bc9f00d4f9eef42be6b /drivers/media/rc
parent67cdd42e0630eff3673808aa57007501353c73b6 (diff)
[media] rc-core: add TX support to the winbond-cir driver
This patch adds preliminary IR TX capabilities to the winbond-cir driver. Signed-off-by: David Härdeman <david@hardeman.nu> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/winbond-cir.c432
1 files changed, 357 insertions, 75 deletions
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index c7686ca81a6b..c42a8ed36c92 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -19,11 +19,12 @@
19 * o DSDT dumps 19 * o DSDT dumps
20 * 20 *
21 * Supported features: 21 * Supported features:
22 * o IR Receive
23 * o IR Transmit
22 * o Wake-On-CIR functionality 24 * o Wake-On-CIR functionality
23 * 25 *
24 * To do: 26 * To do:
25 * o Learning 27 * o Learning
26 * o IR Transmit
27 * 28 *
28 * This program is free software; you can redistribute it and/or modify 29 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by 30 * it under the terms of the GNU General Public License as published by
@@ -50,6 +51,8 @@
50#include <linux/io.h> 51#include <linux/io.h>
51#include <linux/bitrev.h> 52#include <linux/bitrev.h>
52#include <linux/slab.h> 53#include <linux/slab.h>
54#include <linux/wait.h>
55#include <linux/sched.h>
53#include <media/rc-core.h> 56#include <media/rc-core.h>
54 57
55#define DRVNAME "winbond-cir" 58#define DRVNAME "winbond-cir"
@@ -118,14 +121,24 @@
118#define WBCIR_IRQ_NONE 0x00 121#define WBCIR_IRQ_NONE 0x00
119/* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ 122/* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
120#define WBCIR_IRQ_RX 0x01 123#define WBCIR_IRQ_RX 0x01
124/* TX data low bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
125#define WBCIR_IRQ_TX_LOW 0x02
121/* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ 126/* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
122#define WBCIR_IRQ_ERR 0x04 127#define WBCIR_IRQ_ERR 0x04
128/* TX data empty bit for WBCEIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
129#define WBCIR_IRQ_TX_EMPTY 0x20
123/* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */ 130/* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */
124#define WBCIR_LED_ENABLE 0x80 131#define WBCIR_LED_ENABLE 0x80
125/* RX data available bit for WBCIR_REG_SP3_LSR */ 132/* RX data available bit for WBCIR_REG_SP3_LSR */
126#define WBCIR_RX_AVAIL 0x01 133#define WBCIR_RX_AVAIL 0x01
134/* RX data overrun error bit for WBCIR_REG_SP3_LSR */
135#define WBCIR_RX_OVERRUN 0x02
136/* TX End-Of-Transmission bit for WBCIR_REG_SP3_ASCR */
137#define WBCIR_TX_EOT 0x04
127/* RX disable bit for WBCIR_REG_SP3_ASCR */ 138/* RX disable bit for WBCIR_REG_SP3_ASCR */
128#define WBCIR_RX_DISABLE 0x20 139#define WBCIR_RX_DISABLE 0x20
140/* TX data underrun error bit for WBCIR_REG_SP3_ASCR */
141#define WBCIR_TX_UNDERRUN 0x40
129/* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */ 142/* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */
130#define WBCIR_EXT_ENABLE 0x01 143#define WBCIR_EXT_ENABLE 0x01
131/* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ 144/* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */
@@ -154,6 +167,21 @@ enum wbcir_protocol {
154 IR_PROTOCOL_RC6 = 0x2, 167 IR_PROTOCOL_RC6 = 0x2,
155}; 168};
156 169
170/* Possible states for IR reception */
171enum wbcir_rxstate {
172 WBCIR_RXSTATE_INACTIVE = 0,
173 WBCIR_RXSTATE_ACTIVE,
174 WBCIR_RXSTATE_ERROR
175};
176
177/* Possible states for IR transmission */
178enum wbcir_txstate {
179 WBCIR_TXSTATE_INACTIVE = 0,
180 WBCIR_TXSTATE_ACTIVE,
181 WBCIR_TXSTATE_DONE,
182 WBCIR_TXSTATE_ERROR
183};
184
157/* Misc */ 185/* Misc */
158#define WBCIR_NAME "Winbond CIR" 186#define WBCIR_NAME "Winbond CIR"
159#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */ 187#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */
@@ -166,22 +194,29 @@ enum wbcir_protocol {
166/* Per-device data */ 194/* Per-device data */
167struct wbcir_data { 195struct wbcir_data {
168 spinlock_t spinlock; 196 spinlock_t spinlock;
197 struct rc_dev *dev;
198 struct led_classdev led;
169 199
170 unsigned long wbase; /* Wake-Up Baseaddr */ 200 unsigned long wbase; /* Wake-Up Baseaddr */
171 unsigned long ebase; /* Enhanced Func. Baseaddr */ 201 unsigned long ebase; /* Enhanced Func. Baseaddr */
172 unsigned long sbase; /* Serial Port Baseaddr */ 202 unsigned long sbase; /* Serial Port Baseaddr */
173 unsigned int irq; /* Serial Port IRQ */ 203 unsigned int irq; /* Serial Port IRQ */
204 u8 irqmask;
174 205
175 struct rc_dev *dev; 206 /* RX state */
176 207 enum wbcir_rxstate rxstate;
177 struct led_trigger *rxtrigger; 208 struct led_trigger *rxtrigger;
178 struct led_trigger *txtrigger; 209 struct ir_raw_event rxev;
179 struct led_classdev led;
180 210
181 /* RX irdata state */ 211 /* TX state */
182 bool irdata_active; 212 enum wbcir_txstate txstate;
183 bool irdata_error; 213 struct led_trigger *txtrigger;
184 struct ir_raw_event ev; 214 u32 txlen;
215 u32 txoff;
216 u32 *txbuf;
217 wait_queue_head_t txwaitq;
218 u8 txmask;
219 u32 txcarrier;
185}; 220};
186 221
187static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; 222static enum wbcir_protocol protocol = IR_PROTOCOL_RC6;
@@ -193,6 +228,10 @@ static int invert; /* default = 0 */
193module_param(invert, bool, 0444); 228module_param(invert, bool, 0444);
194MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver"); 229MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver");
195 230
231static int txandrx; /* default = 0 */
232module_param(txandrx, bool, 0444);
233MODULE_PARM_DESC(invert, "Allow simultaneous TX and RX");
234
196static unsigned int wake_sc = 0x800F040C; 235static unsigned int wake_sc = 0x800F040C;
197module_param(wake_sc, uint, 0644); 236module_param(wake_sc, uint, 0644);
198MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command"); 237MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command");
@@ -228,6 +267,17 @@ wbcir_select_bank(struct wbcir_data *data, enum wbcir_bank bank)
228 outb(bank, data->sbase + WBCIR_REG_SP3_BSR); 267 outb(bank, data->sbase + WBCIR_REG_SP3_BSR);
229} 268}
230 269
270static inline void
271wbcir_set_irqmask(struct wbcir_data *data, u8 irqmask)
272{
273 if (data->irqmask == irqmask)
274 return;
275
276 wbcir_select_bank(data, WBCIR_BANK_0);
277 outb(irqmask, data->sbase + WBCIR_REG_SP3_IER);
278 data->irqmask = irqmask;
279}
280
231static enum led_brightness 281static enum led_brightness
232wbcir_led_brightness_get(struct led_classdev *led_cdev) 282wbcir_led_brightness_get(struct led_classdev *led_cdev)
233{ 283{
@@ -279,39 +329,15 @@ wbcir_to_rc6cells(u8 val)
279 * 329 *
280 *****************************************************************************/ 330 *****************************************************************************/
281 331
282static irqreturn_t 332static void
283wbcir_irq_handler(int irqno, void *cookie) 333wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device)
284{ 334{
285 struct pnp_dev *device = cookie;
286 struct wbcir_data *data = pnp_get_drvdata(device);
287 unsigned long flags;
288 u8 irdata[8]; 335 u8 irdata[8];
289 u8 disable = true; 336 bool disable = true;
290 u8 status; 337 unsigned int i;
291 int i;
292
293 spin_lock_irqsave(&data->spinlock, flags);
294
295 wbcir_select_bank(data, WBCIR_BANK_0);
296
297 status = inb(data->sbase + WBCIR_REG_SP3_EIR);
298
299 if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) {
300 spin_unlock_irqrestore(&data->spinlock, flags);
301 return IRQ_NONE;
302 }
303
304 /* Check for e.g. buffer overflow */
305 if (status & WBCIR_IRQ_ERR) {
306 data->irdata_error = true;
307 ir_raw_event_reset(data->dev);
308 }
309
310 if (!(status & WBCIR_IRQ_RX))
311 goto out;
312 338
313 if (!data->irdata_active) { 339 if (data->rxstate == WBCIR_RXSTATE_INACTIVE) {
314 data->irdata_active = true; 340 data->rxstate = WBCIR_RXSTATE_ACTIVE;
315 led_trigger_event(data->rxtrigger, LED_FULL); 341 led_trigger_event(data->rxtrigger, LED_FULL);
316 } 342 }
317 343
@@ -325,28 +351,29 @@ wbcir_irq_handler(int irqno, void *cookie)
325 if (irdata[i] != 0xFF && irdata[i] != 0x00) 351 if (irdata[i] != 0xFF && irdata[i] != 0x00)
326 disable = false; 352 disable = false;
327 353
328 if (data->irdata_error) 354 if (data->rxstate == WBCIR_RXSTATE_ERROR)
329 continue; 355 continue;
330 356
331 pulse = irdata[i] & 0x80 ? false : true; 357 pulse = irdata[i] & 0x80 ? false : true;
332 duration = (irdata[i] & 0x7F) * 10000; /* ns */ 358 duration = (irdata[i] & 0x7F) * 10000; /* ns */
333 359
334 if (data->ev.pulse != pulse) { 360 if (data->rxev.pulse != pulse) {
335 if (data->ev.duration != 0) { 361 if (data->rxev.duration != 0) {
336 ir_raw_event_store(data->dev, &data->ev); 362 ir_raw_event_store(data->dev, &data->rxev);
337 data->ev.duration = 0; 363 data->rxev.duration = 0;
338 } 364 }
339 365
340 data->ev.pulse = pulse; 366 data->rxev.pulse = pulse;
341 } 367 }
342 368
343 data->ev.duration += duration; 369 data->rxev.duration += duration;
344 } 370 }
345 371
346 if (disable) { 372 if (disable) {
347 if (data->ev.duration != 0 && !data->irdata_error) { 373 if (data->rxev.duration != 0 &&
348 ir_raw_event_store(data->dev, &data->ev); 374 data->rxstate != WBCIR_RXSTATE_ERROR) {
349 data->ev.duration = 0; 375 ir_raw_event_store(data->dev, &data->rxev);
376 data->rxev.duration = 0;
350 } 377 }
351 378
352 /* Set RXINACTIVE */ 379 /* Set RXINACTIVE */
@@ -357,19 +384,264 @@ wbcir_irq_handler(int irqno, void *cookie)
357 inb(data->sbase + WBCIR_REG_SP3_RXDATA); 384 inb(data->sbase + WBCIR_REG_SP3_RXDATA);
358 385
359 ir_raw_event_reset(data->dev); 386 ir_raw_event_reset(data->dev);
360 data->irdata_error = false;
361 data->irdata_active = false;
362 led_trigger_event(data->rxtrigger, LED_OFF); 387 led_trigger_event(data->rxtrigger, LED_OFF);
388 data->rxstate = WBCIR_RXSTATE_INACTIVE;
363 } 389 }
364 390
365 ir_raw_event_handle(data->dev); 391 ir_raw_event_handle(data->dev);
392}
393
394static void
395wbcir_irq_tx(struct wbcir_data *data)
396{
397 unsigned int space;
398 unsigned int used;
399 u8 bytes[16];
400 u8 byte;
401
402 if (!data->txbuf)
403 return;
404
405 switch (data->txstate) {
406 case WBCIR_TXSTATE_INACTIVE:
407 /* TX FIFO empty */
408 space = 16;
409 led_trigger_event(data->txtrigger, LED_FULL);
410 break;
411 case WBCIR_TXSTATE_ACTIVE:
412 /* TX FIFO low (3 bytes or less) */
413 space = 13;
414 break;
415 case WBCIR_TXSTATE_ERROR:
416 space = 0;
417 break;
418 default:
419 return;
420 }
421
422 /*
423 * TX data is run-length coded in bytes: YXXXXXXX
424 * Y = space (1) or pulse (0)
425 * X = duration, encoded as (X + 1) * 10us (i.e 10 to 1280 us)
426 */
427 for (used = 0; used < space && data->txoff != data->txlen; used++) {
428 if (data->txbuf[data->txoff] == 0) {
429 data->txoff++;
430 continue;
431 }
432 byte = min((u32)0x80, data->txbuf[data->txoff]);
433 data->txbuf[data->txoff] -= byte;
434 byte--;
435 byte |= (data->txoff % 2 ? 0x80 : 0x00); /* pulse/space */
436 bytes[used] = byte;
437 }
438
439 while (data->txbuf[data->txoff] == 0 && data->txoff != data->txlen)
440 data->txoff++;
441
442 if (used == 0) {
443 /* Finished */
444 if (data->txstate == WBCIR_TXSTATE_ERROR)
445 /* Clear TX underrun bit */
446 outb(WBCIR_TX_UNDERRUN, data->sbase + WBCIR_REG_SP3_ASCR);
447 else
448 data->txstate = WBCIR_TXSTATE_DONE;
449 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
450 led_trigger_event(data->txtrigger, LED_OFF);
451 wake_up(&data->txwaitq);
452 } else if (data->txoff == data->txlen) {
453 /* At the end of transmission, tell the hw before last byte */
454 outsb(data->sbase + WBCIR_REG_SP3_TXDATA, bytes, used - 1);
455 outb(WBCIR_TX_EOT, data->sbase + WBCIR_REG_SP3_ASCR);
456 outb(bytes[used - 1], data->sbase + WBCIR_REG_SP3_TXDATA);
457 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
458 WBCIR_IRQ_TX_EMPTY);
459 } else {
460 /* More data to follow... */
461 outsb(data->sbase + WBCIR_REG_SP3_RXDATA, bytes, used);
462 if (data->txstate == WBCIR_TXSTATE_INACTIVE) {
463 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
464 WBCIR_IRQ_TX_LOW);
465 data->txstate = WBCIR_TXSTATE_ACTIVE;
466 }
467 }
468}
469
470static irqreturn_t
471wbcir_irq_handler(int irqno, void *cookie)
472{
473 struct pnp_dev *device = cookie;
474 struct wbcir_data *data = pnp_get_drvdata(device);
475 unsigned long flags;
476 u8 status;
477
478 spin_lock_irqsave(&data->spinlock, flags);
479 wbcir_select_bank(data, WBCIR_BANK_0);
480 status = inb(data->sbase + WBCIR_REG_SP3_EIR);
481 status &= data->irqmask;
482
483 if (!status) {
484 spin_unlock_irqrestore(&data->spinlock, flags);
485 return IRQ_NONE;
486 }
487
488 if (status & WBCIR_IRQ_ERR) {
489 /* RX overflow? (read clears bit) */
490 if (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_OVERRUN) {
491 data->rxstate = WBCIR_RXSTATE_ERROR;
492 ir_raw_event_reset(data->dev);
493 }
494
495 /* TX underflow? */
496 if (inb(data->sbase + WBCIR_REG_SP3_ASCR) & WBCIR_TX_UNDERRUN)
497 data->txstate = WBCIR_TXSTATE_ERROR;
498 }
499
500 if (status & WBCIR_IRQ_RX)
501 wbcir_irq_rx(data, device);
502
503 if (status & (WBCIR_IRQ_TX_LOW | WBCIR_IRQ_TX_EMPTY))
504 wbcir_irq_tx(data);
366 505
367out:
368 spin_unlock_irqrestore(&data->spinlock, flags); 506 spin_unlock_irqrestore(&data->spinlock, flags);
369 return IRQ_HANDLED; 507 return IRQ_HANDLED;
370} 508}
371 509
510/*****************************************************************************
511 *
512 * RC-CORE INTERFACE FUNCTIONS
513 *
514 *****************************************************************************/
515
516static int
517wbcir_txcarrier(struct rc_dev *dev, u32 carrier)
518{
519 struct wbcir_data *data = dev->priv;
520 unsigned long flags;
521 u8 val;
522 u32 freq;
523
524 freq = DIV_ROUND_CLOSEST(carrier, 1000);
525 if (freq < 30 || freq > 60)
526 return -EINVAL;
527
528 switch (freq) {
529 case 58:
530 case 59:
531 case 60:
532 val = freq - 58;
533 freq *= 1000;
534 break;
535 case 57:
536 val = freq - 27;
537 freq = 56900;
538 break;
539 default:
540 val = freq - 27;
541 freq *= 1000;
542 break;
543 }
544
545 spin_lock_irqsave(&data->spinlock, flags);
546 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
547 spin_unlock_irqrestore(&data->spinlock, flags);
548 return -EBUSY;
549 }
550
551 if (data->txcarrier != freq) {
552 wbcir_select_bank(data, WBCIR_BANK_7);
553 wbcir_set_bits(data->sbase + WBCIR_REG_SP3_IRTXMC, val, 0x1F);
554 data->txcarrier = freq;
555 }
556
557 spin_unlock_irqrestore(&data->spinlock, flags);
558 return 0;
559}
560
561static int
562wbcir_txmask(struct rc_dev *dev, u32 mask)
563{
564 struct wbcir_data *data = dev->priv;
565 unsigned long flags;
566 u8 val;
567
568 /* Four outputs, only one output can be enabled at a time */
569 switch (mask) {
570 case 0x1:
571 val = 0x0;
572 break;
573 case 0x2:
574 val = 0x1;
575 break;
576 case 0x4:
577 val = 0x2;
578 break;
579 case 0x8:
580 val = 0x3;
581 break;
582 default:
583 return -EINVAL;
584 }
585
586 spin_lock_irqsave(&data->spinlock, flags);
587 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
588 spin_unlock_irqrestore(&data->spinlock, flags);
589 return -EBUSY;
590 }
591
592 if (data->txmask != mask) {
593 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, val, 0x0c);
594 data->txmask = mask;
595 }
596
597 spin_unlock_irqrestore(&data->spinlock, flags);
598 return 0;
599}
600
601static int
602wbcir_tx(struct rc_dev *dev, int *buf, u32 bufsize)
603{
604 struct wbcir_data *data = dev->priv;
605 u32 count;
606 unsigned i;
607 unsigned long flags;
608
609 /* bufsize has been sanity checked by the caller */
610 count = bufsize / sizeof(int);
611
612 /* Not sure if this is possible, but better safe than sorry */
613 spin_lock_irqsave(&data->spinlock, flags);
614 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
615 spin_unlock_irqrestore(&data->spinlock, flags);
616 return -EBUSY;
617 }
618
619 /* Convert values to multiples of 10us */
620 for (i = 0; i < count; i++)
621 buf[i] = DIV_ROUND_CLOSEST(buf[i], 10);
622
623 /* Fill the TX fifo once, the irq handler will do the rest */
624 data->txbuf = buf;
625 data->txlen = count;
626 data->txoff = 0;
627 wbcir_irq_tx(data);
628
629 /* Wait for the TX to complete */
630 while (data->txstate == WBCIR_TXSTATE_ACTIVE) {
631 spin_unlock_irqrestore(&data->spinlock, flags);
632 wait_event(data->txwaitq, data->txstate != WBCIR_TXSTATE_ACTIVE);
633 spin_lock_irqsave(&data->spinlock, flags);
634 }
635
636 /* We're done */
637 if (data->txstate == WBCIR_TXSTATE_ERROR)
638 count = -EAGAIN;
639 data->txstate = WBCIR_TXSTATE_INACTIVE;
640 data->txbuf = NULL;
641 spin_unlock_irqrestore(&data->spinlock, flags);
372 642
643 return count;
644}
373 645
374/***************************************************************************** 646/*****************************************************************************
375 * 647 *
@@ -551,21 +823,18 @@ finish:
551 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); 823 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
552 } 824 }
553 825
554 /* Disable interrupts */
555 wbcir_select_bank(data, WBCIR_BANK_0);
556 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
557
558 /* Disable LED */
559 data->irdata_active = false;
560 led_trigger_event(data->rxtrigger, LED_OFF);
561
562 /* 826 /*
563 * ACPI will set the HW disable bit for SP3 which means that the 827 * ACPI will set the HW disable bit for SP3 which means that the
564 * output signals are left in an undefined state which may cause 828 * output signals are left in an undefined state which may cause
565 * spurious interrupts which we need to ignore until the hardware 829 * spurious interrupts which we need to ignore until the hardware
566 * is reinitialized. 830 * is reinitialized.
567 */ 831 */
832 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
568 disable_irq(data->irq); 833 disable_irq(data->irq);
834
835 /* Disable LED */
836 led_trigger_event(data->rxtrigger, LED_OFF);
837 led_trigger_event(data->txtrigger, LED_OFF);
569} 838}
570 839
571static int 840static int
@@ -581,8 +850,7 @@ wbcir_init_hw(struct wbcir_data *data)
581 u8 tmp; 850 u8 tmp;
582 851
583 /* Disable interrupts */ 852 /* Disable interrupts */
584 wbcir_select_bank(data, WBCIR_BANK_0); 853 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
585 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
586 854
587 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ 855 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
588 tmp = protocol << 4; 856 tmp = protocol << 4;
@@ -606,10 +874,11 @@ wbcir_init_hw(struct wbcir_data *data)
606 outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL); 874 outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL);
607 875
608 /* 876 /*
609 * Clear IR LED, set SP3 clock to 24Mhz 877 * Clear IR LED, set SP3 clock to 24Mhz, set TX mask to IRTX1,
610 * set SP3_IRRX_SW to binary 01, helpfully not documented 878 * set SP3_IRRX_SW to binary 01, helpfully not documented
611 */ 879 */
612 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); 880 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
881 data->txmask = 0x1;
613 882
614 /* Enable extended mode */ 883 /* Enable extended mode */
615 wbcir_select_bank(data, WBCIR_BANK_2); 884 wbcir_select_bank(data, WBCIR_BANK_2);
@@ -657,18 +926,21 @@ wbcir_init_hw(struct wbcir_data *data)
657 wbcir_select_bank(data, WBCIR_BANK_4); 926 wbcir_select_bank(data, WBCIR_BANK_4);
658 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); 927 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
659 928
660 /* Enable MSR interrupt, Clear AUX_IRX */ 929 /* Disable MSR interrupt, clear AUX_IRX, mask RX during TX? */
661 wbcir_select_bank(data, WBCIR_BANK_5); 930 wbcir_select_bank(data, WBCIR_BANK_5);
662 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); 931 outb(txandrx ? 0x03 : 0x02, data->sbase + WBCIR_REG_SP3_IRCR2);
663 932
664 /* Disable CRC */ 933 /* Disable CRC */
665 wbcir_select_bank(data, WBCIR_BANK_6); 934 wbcir_select_bank(data, WBCIR_BANK_6);
666 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); 935 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
667 936
668 /* Set RX/TX (de)modulation freq, not really used */ 937 /* Set RX demodulation freq, not really used */
669 wbcir_select_bank(data, WBCIR_BANK_7); 938 wbcir_select_bank(data, WBCIR_BANK_7);
670 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); 939 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
940
941 /* Set TX modulation, 36kHz, 7us pulse width */
671 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); 942 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
943 data->txcarrier = 36000;
672 944
673 /* Set invert and pin direction */ 945 /* Set invert and pin direction */
674 if (invert) 946 if (invert)
@@ -683,16 +955,23 @@ wbcir_init_hw(struct wbcir_data *data)
683 /* Clear AUX status bits */ 955 /* Clear AUX status bits */
684 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); 956 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
685 957
686 /* Clear IR decoding state */ 958 /* Clear RX state */
687 data->irdata_active = false; 959 data->rxstate = WBCIR_RXSTATE_INACTIVE;
688 led_trigger_event(data->rxtrigger, LED_OFF); 960 data->rxev.duration = 0;
689 data->irdata_error = false;
690 data->ev.duration = 0;
691 ir_raw_event_reset(data->dev); 961 ir_raw_event_reset(data->dev);
692 ir_raw_event_handle(data->dev); 962 ir_raw_event_handle(data->dev);
693 963
964 /*
965 * Check TX state, if we did a suspend/resume cycle while TX was
966 * active, we will have a process waiting in txwaitq.
967 */
968 if (data->txstate == WBCIR_TXSTATE_ACTIVE) {
969 data->txstate = WBCIR_TXSTATE_ERROR;
970 wake_up(&data->txwaitq);
971 }
972
694 /* Enable interrupts */ 973 /* Enable interrupts */
695 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); 974 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
696} 975}
697 976
698static int 977static int
@@ -729,6 +1008,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
729 pnp_set_drvdata(device, data); 1008 pnp_set_drvdata(device, data);
730 1009
731 spin_lock_init(&data->spinlock); 1010 spin_lock_init(&data->spinlock);
1011 init_waitqueue_head(&data->txwaitq);
732 data->ebase = pnp_port_start(device, 0); 1012 data->ebase = pnp_port_start(device, 0);
733 data->wbase = pnp_port_start(device, 1); 1013 data->wbase = pnp_port_start(device, 1);
734 data->sbase = pnp_port_start(device, 2); 1014 data->sbase = pnp_port_start(device, 2);
@@ -807,6 +1087,10 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
807 data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND; 1087 data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND;
808 data->dev->input_id.product = WBCIR_ID_FAMILY; 1088 data->dev->input_id.product = WBCIR_ID_FAMILY;
809 data->dev->input_id.version = WBCIR_ID_CHIP; 1089 data->dev->input_id.version = WBCIR_ID_CHIP;
1090 data->dev->map_name = RC_MAP_RC6_MCE;
1091 data->dev->s_tx_mask = wbcir_txmask;
1092 data->dev->s_tx_carrier = wbcir_txcarrier;
1093 data->dev->tx_ir = wbcir_tx;
810 data->dev->priv = data; 1094 data->dev->priv = data;
811 data->dev->dev.parent = &device->dev; 1095 data->dev->dev.parent = &device->dev;
812 1096
@@ -849,9 +1133,7 @@ wbcir_remove(struct pnp_dev *device)
849 struct wbcir_data *data = pnp_get_drvdata(device); 1133 struct wbcir_data *data = pnp_get_drvdata(device);
850 1134
851 /* Disable interrupts */ 1135 /* Disable interrupts */
852 wbcir_select_bank(data, WBCIR_BANK_0); 1136 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
853 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
854
855 free_irq(data->irq, device); 1137 free_irq(data->irq, device);
856 1138
857 /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ 1139 /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */