Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 208143
b: refs/heads/master
c: c02e0d1
h: refs/heads/master
i:
  208141: 4889477
  208139: a5412b1
  208135: ee4b20c
  208127: f2c2be7
v: v3
  • Loading branch information
Andy Walls authored and Mauro Carvalho Chehab committed Aug 9, 2010
1 parent 4537660 commit 2a25ed5
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 72 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2560d94e330f35776e944b54256a526a19259429
refs/heads/master: c02e0d12a9a0a913dee5efd695603b73ee4b729a
18 changes: 5 additions & 13 deletions trunk/drivers/media/video/cx23885/cx23885-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,34 +44,26 @@

#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);
Expand Down
73 changes: 44 additions & 29 deletions trunk/drivers/media/video/cx23885/cx23888-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/ir-core.h>

#include "cx23885.h"

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -660,39 +672,40 @@ 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;
}

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");
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
71 changes: 42 additions & 29 deletions trunk/drivers/media/video/cx25840/cx25840-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -655,16 +667,17 @@ 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;

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;
Expand All @@ -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");
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 2a25ed5

Please sign in to comment.