aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx23885/cx23888-ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx23885/cx23888-ir.c')
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
index 684d23db98a7..2502a0a67097 100644
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -26,6 +26,7 @@
26 26
27#include <media/v4l2-device.h> 27#include <media/v4l2-device.h>
28#include <media/v4l2-chip-ident.h> 28#include <media/v4l2-chip-ident.h>
29#include <media/ir-core.h>
29 30
30#include "cx23885.h" 31#include "cx23885.h"
31 32
@@ -113,8 +114,18 @@ MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
113#define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */ 114#define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */
114#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2) 115#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2)
115 116
116#define CX23888_IR_RX_KFIFO_SIZE (512 * sizeof(u32)) 117/*
117#define CX23888_IR_TX_KFIFO_SIZE (512 * sizeof(u32)) 118 * We use this union internally for convenience, but callers to tx_write
119 * and rx_read will be expecting records of type struct ir_raw_event.
120 * Always ensure the size of this union is dictated by struct ir_raw_event.
121 */
122union cx23888_ir_fifo_rec {
123 u32 hw_fifo_data;
124 struct ir_raw_event ir_core_data;
125};
126
127#define CX23888_IR_RX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec))
128#define CX23888_IR_TX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec))
118 129
119struct cx23888_ir_state { 130struct cx23888_ir_state {
120 struct v4l2_subdev sd; 131 struct v4l2_subdev sd;
@@ -458,8 +469,8 @@ static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
458{ 469{
459 u64 pulse_clocks; 470 u64 pulse_clocks;
460 471
461 if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS) 472 if (ns > IR_MAX_DURATION)
462 ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS; 473 ns = IR_MAX_DURATION;
463 pulse_clocks = ns_to_pulse_clocks(ns); 474 pulse_clocks = ns_to_pulse_clocks(ns);
464 *divider = pulse_clocks_to_clock_divider(pulse_clocks); 475 *divider = pulse_clocks_to_clock_divider(pulse_clocks);
465 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider); 476 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
@@ -471,8 +482,8 @@ static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
471{ 482{
472 u64 pulse_clocks; 483 u64 pulse_clocks;
473 484
474 if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS) 485 if (ns > IR_MAX_DURATION)
475 ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS; 486 ns = IR_MAX_DURATION;
476 pulse_clocks = ns_to_pulse_clocks(ns); 487 pulse_clocks = ns_to_pulse_clocks(ns);
477 *divider = pulse_clocks_to_clock_divider(pulse_clocks); 488 *divider = pulse_clocks_to_clock_divider(pulse_clocks);
478 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider); 489 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
@@ -535,8 +546,8 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
535 u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); 546 u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
536 u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG); 547 u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
537 548
538 u32 rx_data[FIFO_RX_DEPTH]; 549 union cx23888_ir_fifo_rec rx_data[FIFO_RX_DEPTH];
539 int i, j, k; 550 unsigned int i, j, k;
540 u32 events, v; 551 u32 events, v;
541 int tsr, rsr, rto, ror, tse, rse, rte, roe, kror; 552 int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
542 553
@@ -597,11 +608,12 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
597 for (j = 0; 608 for (j = 0;
598 (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) { 609 (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
599 v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG); 610 v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
600 rx_data[i++] = v & ~FIFO_RX_NDV; 611 rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV;
612 i++;
601 } 613 }
602 if (i == 0) 614 if (i == 0)
603 break; 615 break;
604 j = i * sizeof(u32); 616 j = i * sizeof(union cx23888_ir_fifo_rec);
605 k = kfifo_in_locked(&state->rx_kfifo, 617 k = kfifo_in_locked(&state->rx_kfifo,
606 (unsigned char *) rx_data, j, 618 (unsigned char *) rx_data, j,
607 &state->rx_kfifo_lock); 619 &state->rx_kfifo_lock);
@@ -660,10 +672,11 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
660 u16 divider = (u16) atomic_read(&state->rxclk_divider); 672 u16 divider = (u16) atomic_read(&state->rxclk_divider);
661 673
662 unsigned int i, n; 674 unsigned int i, n;
663 u32 *p; 675 union cx23888_ir_fifo_rec *p;
664 u32 u, v; 676 unsigned u, v;
665 677
666 n = count / sizeof(u32) * sizeof(u32); 678 n = count / sizeof(union cx23888_ir_fifo_rec)
679 * sizeof(union cx23888_ir_fifo_rec);
667 if (n == 0) { 680 if (n == 0) {
668 *num = 0; 681 *num = 0;
669 return 0; 682 return 0;
@@ -671,28 +684,28 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
671 684
672 n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock); 685 n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock);
673 686
674 n /= sizeof(u32); 687 n /= sizeof(union cx23888_ir_fifo_rec);
675 *num = n * sizeof(u32); 688 *num = n * sizeof(union cx23888_ir_fifo_rec);
676 689
677 for (p = (u32 *) buf, i = 0; i < n; p++, i++) { 690 for (p = (union cx23888_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) {
678 691
679 if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) { 692 if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
680 /* Assume RTO was because of no IR light input */ 693 /* Assume RTO was because of no IR light input */
681 u = 0; 694 u = 0;
682 v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n"); 695 v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
683 } else { 696 } else {
684 u = (*p & FIFO_RXTX_LVL) 697 u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0;
685 ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
686 if (invert) 698 if (invert)
687 u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK; 699 u = u ? 0 : 1;
688 } 700 }
689 701
690 v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX), 702 v = (unsigned) pulse_width_count_to_ns(
691 divider); 703 (u16) (p->hw_fifo_data & FIFO_RXTX), divider);
692 if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS) 704 if (v > IR_MAX_DURATION)
693 v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1; 705 v = IR_MAX_DURATION;
694 706
695 *p = u | v; 707 p->ir_core_data.pulse = u;
708 p->ir_core_data.duration = v;
696 709
697 v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s\n", 710 v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s\n",
698 v, u ? "mark" : "space"); 711 v, u ? "mark" : "space");
@@ -751,7 +764,8 @@ static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
751 764
752 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; 765 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
753 766
754 o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32); 767 o->bytes_per_data_element = p->bytes_per_data_element
768 = sizeof(union cx23888_ir_fifo_rec);
755 769
756 /* Before we tweak the hardware, we have to disable the receiver */ 770 /* Before we tweak the hardware, we have to disable the receiver */
757 irqenable_rx(dev, 0); 771 irqenable_rx(dev, 0);
@@ -878,7 +892,8 @@ static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
878 892
879 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; 893 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
880 894
881 o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32); 895 o->bytes_per_data_element = p->bytes_per_data_element
896 = sizeof(union cx23888_ir_fifo_rec);
882 897
883 /* Before we tweak the hardware, we have to disable the transmitter */ 898 /* Before we tweak the hardware, we have to disable the transmitter */
884 irqenable_tx(dev, 0); 899 irqenable_tx(dev, 0);
@@ -1149,7 +1164,7 @@ static const struct v4l2_subdev_ops cx23888_ir_controller_ops = {
1149}; 1164};
1150 1165
1151static const struct v4l2_subdev_ir_parameters default_rx_params = { 1166static const struct v4l2_subdev_ir_parameters default_rx_params = {
1152 .bytes_per_data_element = sizeof(u32), 1167 .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec),
1153 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, 1168 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
1154 1169
1155 .enable = false, 1170 .enable = false,
@@ -1168,7 +1183,7 @@ static const struct v4l2_subdev_ir_parameters default_rx_params = {
1168}; 1183};
1169 1184
1170static const struct v4l2_subdev_ir_parameters default_tx_params = { 1185static const struct v4l2_subdev_ir_parameters default_tx_params = {
1171 .bytes_per_data_element = sizeof(u32), 1186 .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec),
1172 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, 1187 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
1173 1188
1174 .enable = false, 1189 .enable = false,