V4L/DVB: cx23885, cx25840: Change IR measurment records to use struct ir_raw_event
authorAndy Walls <awalls@md.metrocast.net>
Sun, 1 Aug 2010 05:18:13 +0000 (02:18 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 9 Aug 2010 02:42:56 +0000 (23:42 -0300)
The CX23885 and CX25840 modules were using their own simple
IR pulse width measurement record type which required conversion
when passing to the new IR core.  This change makes that record type
consistent with the new IR core and removes a data conversion.

Signed-off-by: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cx23885/cx23885-input.c
drivers/media/video/cx23885/cx23888-ir.c
drivers/media/video/cx25840/cx25840-ir.c

index 252817acc35bc1b8c14cfb77f1a78496f21bc7bb..bb61870b8d6ed39d25c11aa676b55bd0a94dc235 100644 (file)
 
 #define MODULE_NAME "cx23885"
 
-static void convert_measurement(u32 x, struct ir_raw_event *y)
-{
-       y->pulse = (x & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? true : false;
-       y->duration = x & V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
-}
-
 static void cx23885_input_process_measurements(struct cx23885_dev *dev,
                                               bool overrun)
 {
        struct cx23885_kernel_ir *kernel_ir = dev->kernel_ir;
-       struct ir_raw_event kernel_ir_event;
 
-       u32 sd_ir_data[64];
        ssize_t num;
        int count, i;
        bool handle = false;
+       struct ir_raw_event ir_core_event[64];
 
        do {
                num = 0;
-               v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) sd_ir_data,
-                                sizeof(sd_ir_data), &num);
+               v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ir_core_event,
+                                sizeof(ir_core_event), &num);
 
-               count = num / sizeof(u32);
+               count = num / sizeof(struct ir_raw_event);
 
                for (i = 0; i < count; i++) {
-                       convert_measurement(sd_ir_data[i], &kernel_ir_event);
                        ir_raw_event_store(kernel_ir->inp_dev,
-                                          &kernel_ir_event);
+                                          &ir_core_event[i]);
                        handle = true;
                }
        } while (num != 0);
index 684d23db98a70332e76cfcb43266bb7fc686b84e..2502a0a6709783b8c01d5de639d759d097f0f1cd 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
+#include <media/ir-core.h>
 
 #include "cx23885.h"
 
@@ -113,8 +114,18 @@ MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
 #define CX23888_VIDCLK_FREQ    108000000 /* 108 MHz, BT.656 */
 #define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2)
 
-#define CX23888_IR_RX_KFIFO_SIZE       (512 * sizeof(u32))
-#define CX23888_IR_TX_KFIFO_SIZE       (512 * sizeof(u32))
+/*
+ * We use this union internally for convenience, but callers to tx_write
+ * and rx_read will be expecting records of type struct ir_raw_event.
+ * Always ensure the size of this union is dictated by struct ir_raw_event.
+ */
+union cx23888_ir_fifo_rec {
+       u32 hw_fifo_data;
+       struct ir_raw_event ir_core_data;
+};
+
+#define CX23888_IR_RX_KFIFO_SIZE    (256 * sizeof(union cx23888_ir_fifo_rec))
+#define CX23888_IR_TX_KFIFO_SIZE    (256 * sizeof(union cx23888_ir_fifo_rec))
 
 struct cx23888_ir_state {
        struct v4l2_subdev sd;
@@ -458,8 +469,8 @@ static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
 {
        u64 pulse_clocks;
 
-       if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
-               ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+       if (ns > IR_MAX_DURATION)
+               ns = IR_MAX_DURATION;
        pulse_clocks = ns_to_pulse_clocks(ns);
        *divider = pulse_clocks_to_clock_divider(pulse_clocks);
        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,
 {
        u64 pulse_clocks;
 
-       if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
-               ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+       if (ns > IR_MAX_DURATION)
+               ns = IR_MAX_DURATION;
        pulse_clocks = ns_to_pulse_clocks(ns);
        *divider = pulse_clocks_to_clock_divider(pulse_clocks);
        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,
        u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
        u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
 
-       u32 rx_data[FIFO_RX_DEPTH];
-       int i, j, k;
+       union cx23888_ir_fifo_rec rx_data[FIFO_RX_DEPTH];
+       unsigned int i, j, k;
        u32 events, v;
        int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
 
@@ -597,11 +608,12 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
                        for (j = 0;
                             (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
                                v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
-                               rx_data[i++] = v & ~FIFO_RX_NDV;
+                               rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV;
+                               i++;
                        }
                        if (i == 0)
                                break;
-                       j = i * sizeof(u32);
+                       j = i * sizeof(union cx23888_ir_fifo_rec);
                        k = kfifo_in_locked(&state->rx_kfifo,
                                      (unsigned char *) rx_data, j,
                                      &state->rx_kfifo_lock);
@@ -660,10 +672,11 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
        u16 divider = (u16) atomic_read(&state->rxclk_divider);
 
        unsigned int i, n;
-       u32 *p;
-       u32 u, v;
+       union cx23888_ir_fifo_rec *p;
+       unsigned u, v;
 
-       n = count / sizeof(u32) * sizeof(u32);
+       n = count / sizeof(union cx23888_ir_fifo_rec)
+               * sizeof(union cx23888_ir_fifo_rec);
        if (n == 0) {
                *num = 0;
                return 0;
@@ -671,28 +684,28 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
 
        n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock);
 
-       n /= sizeof(u32);
-       *num = n * sizeof(u32);
+       n /= sizeof(union cx23888_ir_fifo_rec);
+       *num = n * sizeof(union cx23888_ir_fifo_rec);
 
-       for (p = (u32 *) buf, i = 0; i < n; p++, i++) {
+       for (p = (union cx23888_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) {
 
-               if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
+               if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
                        /* Assume RTO was because of no IR light input */
                        u = 0;
                        v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
                } else {
-                       u = (*p & FIFO_RXTX_LVL)
-                                         ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
+                       u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0;
                        if (invert)
-                               u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK;
+                               u = u ? 0 : 1;
                }
 
-               v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX),
-                                                 divider);
-               if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
-                       v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1;
+               v = (unsigned) pulse_width_count_to_ns(
+                                 (u16) (p->hw_fifo_data & FIFO_RXTX), divider);
+               if (v > IR_MAX_DURATION)
+                       v = IR_MAX_DURATION;
 
-               *p = u | v;
+               p->ir_core_data.pulse = u;
+               p->ir_core_data.duration = v;
 
                v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns  %s\n",
                         v, u ? "mark" : "space");
@@ -751,7 +764,8 @@ static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
 
        o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
 
-       o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
+       o->bytes_per_data_element = p->bytes_per_data_element
+                                 = sizeof(union cx23888_ir_fifo_rec);
 
        /* Before we tweak the hardware, we have to disable the receiver */
        irqenable_rx(dev, 0);
@@ -878,7 +892,8 @@ static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
 
        o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
 
-       o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
+       o->bytes_per_data_element = p->bytes_per_data_element
+                                 = sizeof(union cx23888_ir_fifo_rec);
 
        /* Before we tweak the hardware, we have to disable the transmitter */
        irqenable_tx(dev, 0);
@@ -1149,7 +1164,7 @@ static const struct v4l2_subdev_ops cx23888_ir_controller_ops = {
 };
 
 static const struct v4l2_subdev_ir_parameters default_rx_params = {
-       .bytes_per_data_element = sizeof(u32),
+       .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec),
        .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
 
        .enable = false,
@@ -1168,7 +1183,7 @@ static const struct v4l2_subdev_ir_parameters default_rx_params = {
 };
 
 static const struct v4l2_subdev_ir_parameters default_tx_params = {
-       .bytes_per_data_element = sizeof(u32),
+       .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec),
        .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
 
        .enable = false,
index be23c5b37a2f3ab37df3ce3b8e6350bf881e9bda..34e284b06dfa12675cd1a1685e1ac998a67a8cc2 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/kfifo.h>
 #include <media/cx25840.h>
+#include <media/ir-core.h>
 
 #include "cx25840-core.h"
 
@@ -94,8 +95,18 @@ MODULE_PARM_DESC(ir_debug, "enable integrated IR debug messages");
 #define CX25840_VIDCLK_FREQ    108000000 /* 108 MHz, BT.656 */
 #define CX25840_IR_REFCLK_FREQ (CX25840_VIDCLK_FREQ / 2)
 
-#define CX25840_IR_RX_KFIFO_SIZE       (512 * sizeof(u32))
-#define CX25840_IR_TX_KFIFO_SIZE       (512 * sizeof(u32))
+/*
+ * We use this union internally for convenience, but callers to tx_write
+ * and rx_read will be expecting records of type struct ir_raw_event.
+ * Always ensure the size of this union is dictated by struct ir_raw_event.
+ */
+union cx25840_ir_fifo_rec {
+       u32 hw_fifo_data;
+       struct ir_raw_event ir_core_data;
+};
+
+#define CX25840_IR_RX_KFIFO_SIZE    (256 * sizeof(union cx25840_ir_fifo_rec))
+#define CX25840_IR_TX_KFIFO_SIZE    (256 * sizeof(union cx25840_ir_fifo_rec))
 
 struct cx25840_ir_state {
        struct i2c_client *c;
@@ -435,8 +446,8 @@ static u32 txclk_tx_s_max_pulse_width(struct i2c_client *c, u32 ns,
 {
        u64 pulse_clocks;
 
-       if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
-               ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+       if (ns > IR_MAX_DURATION)
+               ns = IR_MAX_DURATION;
        pulse_clocks = ns_to_pulse_clocks(ns);
        *divider = pulse_clocks_to_clock_divider(pulse_clocks);
        cx25840_write4(c, CX25840_IR_TXCLK_REG, *divider);
@@ -448,8 +459,8 @@ static u32 rxclk_rx_s_max_pulse_width(struct i2c_client *c, u32 ns,
 {
        u64 pulse_clocks;
 
-       if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
-               ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+       if (ns > IR_MAX_DURATION)
+               ns = IR_MAX_DURATION;
        pulse_clocks = ns_to_pulse_clocks(ns);
        *divider = pulse_clocks_to_clock_divider(pulse_clocks);
        cx25840_write4(c, CX25840_IR_RXCLK_REG, *divider);
@@ -516,8 +527,8 @@ int cx25840_ir_irq_handler(struct v4l2_subdev *sd, u32 status, bool *handled)
        struct i2c_client *c = NULL;
        unsigned long flags;
 
-       u32 rx_data[FIFO_RX_DEPTH];
-       int i, j, k;
+       union cx25840_ir_fifo_rec rx_data[FIFO_RX_DEPTH];
+       unsigned int i, j, k;
        u32 events, v;
        int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
        u32 cntrl, irqen, stats;
@@ -594,11 +605,12 @@ int cx25840_ir_irq_handler(struct v4l2_subdev *sd, u32 status, bool *handled)
                        for (j = 0;
                             (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
                                v = cx25840_read4(c, CX25840_IR_FIFO_REG);
-                               rx_data[i++] = v & ~FIFO_RX_NDV;
+                               rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV;
+                               i++;
                        }
                        if (i == 0)
                                break;
-                       j = i * sizeof(u32);
+                       j = i * sizeof(union cx25840_ir_fifo_rec);
                        k = kfifo_in_locked(&ir_state->rx_kfifo,
                                            (unsigned char *) rx_data, j,
                                            &ir_state->rx_kfifo_lock);
@@ -655,8 +667,8 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
        bool invert;
        u16 divider;
        unsigned int i, n;
-       u32 *p;
-       u32 u, v;
+       union cx25840_ir_fifo_rec *p;
+       unsigned u, v;
 
        if (ir_state == NULL)
                return -ENODEV;
@@ -664,7 +676,8 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
        invert = (bool) atomic_read(&ir_state->rx_invert);
        divider = (u16) atomic_read(&ir_state->rxclk_divider);
 
-       n = count / sizeof(u32) * sizeof(u32);
+       n = count / sizeof(union cx25840_ir_fifo_rec)
+               * sizeof(union cx25840_ir_fifo_rec);
        if (n == 0) {
                *num = 0;
                return 0;
@@ -673,28 +686,28 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
        n = kfifo_out_locked(&ir_state->rx_kfifo, buf, n,
                             &ir_state->rx_kfifo_lock);
 
-       n /= sizeof(u32);
-       *num = n * sizeof(u32);
+       n /= sizeof(union cx25840_ir_fifo_rec);
+       *num = n * sizeof(union cx25840_ir_fifo_rec);
 
-       for (p = (u32 *) buf, i = 0; i < n; p++, i++) {
+       for (p = (union cx25840_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) {
 
-               if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
+               if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
                        /* Assume RTO was because of no IR light input */
                        u = 0;
                        v4l2_dbg(2, ir_debug, sd, "rx read: end of rx\n");
                } else {
-                       u = (*p & FIFO_RXTX_LVL)
-                                         ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
+                       u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0;
                        if (invert)
-                               u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK;
+                               u = u ? 0 : 1;
                }
 
-               v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX),
-                                                 divider);
-               if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
-                       v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1;
+               v = (unsigned) pulse_width_count_to_ns(
+                                 (u16) (p->hw_fifo_data & FIFO_RXTX), divider);
+               if (v > IR_MAX_DURATION)
+                       v = IR_MAX_DURATION;
 
-               *p = u | v;
+               p->ir_core_data.pulse = u;
+               p->ir_core_data.duration = v;
 
                v4l2_dbg(2, ir_debug, sd, "rx read: %10u ns  %s\n",
                         v, u ? "mark" : "space");
@@ -769,7 +782,7 @@ static int cx25840_ir_rx_s_parameters(struct v4l2_subdev *sd,
        p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
        o->mode = p->mode;
 
-       p->bytes_per_data_element = sizeof(u32);
+       p->bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec);
        o->bytes_per_data_element = p->bytes_per_data_element;
 
        /* Before we tweak the hardware, we have to disable the receiver */
@@ -958,7 +971,7 @@ static int cx25840_ir_tx_s_parameters(struct v4l2_subdev *sd,
        p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
        o->mode = p->mode;
 
-       p->bytes_per_data_element = sizeof(u32);
+       p->bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec);
        o->bytes_per_data_element = p->bytes_per_data_element;
 
        /* Before we tweak the hardware, we have to disable the transmitter */
@@ -1172,7 +1185,7 @@ const struct v4l2_subdev_ir_ops cx25840_ir_ops = {
 
 
 static const struct v4l2_subdev_ir_parameters default_rx_params = {
-       .bytes_per_data_element = sizeof(u32),
+       .bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec),
        .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
 
        .enable = false,
@@ -1191,7 +1204,7 @@ static const struct v4l2_subdev_ir_parameters default_rx_params = {
 };
 
 static const struct v4l2_subdev_ir_parameters default_tx_params = {
-       .bytes_per_data_element = sizeof(u32),
+       .bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec),
        .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
 
        .enable = false,