[media] IR: extend ir_raw_event and do refactoring
Add new event types for timeout & carrier report Move timeout handling from ir_raw_event_store_with_filter to ir-lirc-codec, where it is really needed. Now lirc bridge ensures proper gap handling. Extend lirc bridge for carrier & timeout reports Note: all new ir_raw_event variables now should be initialized like that: DEFINE_IR_RAW_EVENT(ev); To clean an existing event, use init_ir_raw_event(&ev); Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Acked-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
fb249ca61d
commit
4651918a4a
14 changed files with 181 additions and 93 deletions
|
@ -697,7 +697,7 @@ static irqreturn_t ene_isr(int irq, void *data)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
irqreturn_t retval = IRQ_NONE;
|
irqreturn_t retval = IRQ_NONE;
|
||||||
struct ene_device *dev = (struct ene_device *)data;
|
struct ene_device *dev = (struct ene_device *)data;
|
||||||
struct ir_raw_event ev;
|
DEFINE_IR_RAW_EVENT(ev);
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->hw_lock, flags);
|
spin_lock_irqsave(&dev->hw_lock, flags);
|
||||||
|
|
||||||
|
@ -898,7 +898,7 @@ static int ene_set_learning_mode(void *data, int enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* outside interface: enable or disable idle mode */
|
/* outside interface: enable or disable idle mode */
|
||||||
static void ene_rx_set_idle(void *data, int idle)
|
static void ene_rx_set_idle(void *data, bool idle)
|
||||||
{
|
{
|
||||||
struct ene_device *dev = (struct ene_device *)data;
|
struct ene_device *dev = (struct ene_device *)data;
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,12 @@ struct ir_raw_event_ctrl {
|
||||||
struct ir_input_dev *ir_dev;
|
struct ir_input_dev *ir_dev;
|
||||||
struct lirc_driver *drv;
|
struct lirc_driver *drv;
|
||||||
int carrier_low;
|
int carrier_low;
|
||||||
|
|
||||||
|
ktime_t gap_start;
|
||||||
|
u64 gap_duration;
|
||||||
|
bool gap;
|
||||||
|
bool send_timeout_reports;
|
||||||
|
|
||||||
} lirc;
|
} lirc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,9 +121,14 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration)
|
||||||
ev->duration -= duration;
|
ev->duration -= duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if event is normal pulse/space event */
|
||||||
|
static inline bool is_timing_event(struct ir_raw_event ev)
|
||||||
|
{
|
||||||
|
return !ev.carrier_report && !ev.reset;
|
||||||
|
}
|
||||||
|
|
||||||
#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
|
#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
|
||||||
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
|
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
|
||||||
#define IS_RESET(ev) (ev.duration == 0)
|
|
||||||
/*
|
/*
|
||||||
* Routines from ir-sysfs.c - Meant to be called only internally inside
|
* Routines from ir-sysfs.c - Meant to be called only internally inside
|
||||||
* ir-core
|
* ir-core
|
||||||
|
|
|
@ -50,7 +50,8 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
|
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (IS_RESET(ev)) {
|
if (!is_timing_event(ev)) {
|
||||||
|
if (ev.reset)
|
||||||
data->state = STATE_INACTIVE;
|
data->state = STATE_INACTIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
{
|
{
|
||||||
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
||||||
|
struct lirc_codec *lirc = &ir_dev->raw->lirc;
|
||||||
int sample;
|
int sample;
|
||||||
|
|
||||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
|
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
|
||||||
|
@ -40,21 +41,57 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
|
if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (IS_RESET(ev))
|
/* Packet start */
|
||||||
|
if (ev.reset)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
|
/* Carrier reports */
|
||||||
TO_US(ev.duration), TO_STR(ev.pulse));
|
if (ev.carrier_report) {
|
||||||
|
sample = LIRC_FREQUENCY(ev.carrier);
|
||||||
|
|
||||||
sample = ev.duration / 1000;
|
/* Packet end */
|
||||||
if (ev.pulse)
|
} else if (ev.timeout) {
|
||||||
sample |= PULSE_BIT;
|
|
||||||
|
if (lirc->gap)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lirc->gap_start = ktime_get();
|
||||||
|
lirc->gap = true;
|
||||||
|
lirc->gap_duration = ev.duration;
|
||||||
|
|
||||||
|
if (!lirc->send_timeout_reports)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sample = LIRC_TIMEOUT(ev.duration / 1000);
|
||||||
|
|
||||||
|
/* Normal sample */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (lirc->gap) {
|
||||||
|
int gap_sample;
|
||||||
|
|
||||||
|
lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
|
||||||
|
lirc->gap_start));
|
||||||
|
|
||||||
|
/* Convert to ms and cap by LIRC_VALUE_MASK */
|
||||||
|
do_div(lirc->gap_duration, 1000);
|
||||||
|
lirc->gap_duration = min(lirc->gap_duration,
|
||||||
|
(u64)LIRC_VALUE_MASK);
|
||||||
|
|
||||||
|
gap_sample = LIRC_SPACE(lirc->gap_duration);
|
||||||
|
lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
|
||||||
|
(unsigned char *) &gap_sample);
|
||||||
|
lirc->gap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
|
||||||
|
LIRC_SPACE(ev.duration / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
|
lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
|
||||||
(unsigned char *) &sample);
|
(unsigned char *) &sample);
|
||||||
wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
|
wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||||
struct ir_input_dev *ir_dev;
|
struct ir_input_dev *ir_dev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
void *drv_data;
|
void *drv_data;
|
||||||
__u32 val = 0;
|
__u32 val = 0, tmp;
|
||||||
|
|
||||||
lirc = lirc_get_pdata(filep);
|
lirc = lirc_get_pdata(filep);
|
||||||
if (!lirc)
|
if (!lirc)
|
||||||
|
@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||||
case LIRC_SET_SEND_MODE:
|
case LIRC_SET_SEND_MODE:
|
||||||
if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
|
if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
return 0;
|
||||||
|
|
||||||
/* TX settings */
|
/* TX settings */
|
||||||
case LIRC_SET_TRANSMITTER_MASK:
|
case LIRC_SET_TRANSMITTER_MASK:
|
||||||
if (ir_dev->props->s_tx_mask)
|
if (!ir_dev->props->s_tx_mask)
|
||||||
ret = ir_dev->props->s_tx_mask(drv_data, val);
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
|
return ir_dev->props->s_tx_mask(drv_data, val);
|
||||||
|
|
||||||
case LIRC_SET_SEND_CARRIER:
|
case LIRC_SET_SEND_CARRIER:
|
||||||
if (ir_dev->props->s_tx_carrier)
|
if (!ir_dev->props->s_tx_carrier)
|
||||||
ir_dev->props->s_tx_carrier(drv_data, val);
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
|
return ir_dev->props->s_tx_carrier(drv_data, val);
|
||||||
|
|
||||||
case LIRC_SET_SEND_DUTY_CYCLE:
|
case LIRC_SET_SEND_DUTY_CYCLE:
|
||||||
if (!ir_dev->props->s_tx_duty_cycle)
|
if (!ir_dev->props->s_tx_duty_cycle)
|
||||||
|
@ -154,39 +189,42 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||||
if (val <= 0 || val >= 100)
|
if (val <= 0 || val >= 100)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val);
|
return ir_dev->props->s_tx_duty_cycle(drv_data, val);
|
||||||
break;
|
|
||||||
|
|
||||||
/* RX settings */
|
/* RX settings */
|
||||||
case LIRC_SET_REC_CARRIER:
|
case LIRC_SET_REC_CARRIER:
|
||||||
if (ir_dev->props->s_rx_carrier_range)
|
if (!ir_dev->props->s_rx_carrier_range)
|
||||||
ret = ir_dev->props->s_rx_carrier_range(
|
|
||||||
ir_dev->props->priv,
|
|
||||||
ir_dev->raw->lirc.carrier_low, val);
|
|
||||||
else
|
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
if (!ret)
|
if (val <= 0)
|
||||||
ir_dev->raw->lirc.carrier_low = 0;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
|
return ir_dev->props->s_rx_carrier_range(drv_data,
|
||||||
|
ir_dev->raw->lirc.carrier_low, val);
|
||||||
|
|
||||||
case LIRC_SET_REC_CARRIER_RANGE:
|
case LIRC_SET_REC_CARRIER_RANGE:
|
||||||
if (val >= 0)
|
if (val <= 0)
|
||||||
ir_dev->raw->lirc.carrier_low = val;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
|
|
||||||
|
ir_dev->raw->lirc.carrier_low = val;
|
||||||
|
return 0;
|
||||||
|
|
||||||
case LIRC_GET_REC_RESOLUTION:
|
case LIRC_GET_REC_RESOLUTION:
|
||||||
val = ir_dev->props->rx_resolution;
|
val = ir_dev->props->rx_resolution;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIRC_SET_WIDEBAND_RECEIVER:
|
case LIRC_SET_WIDEBAND_RECEIVER:
|
||||||
if (ir_dev->props->s_learning_mode)
|
if (!ir_dev->props->s_learning_mode)
|
||||||
return ir_dev->props->s_learning_mode(
|
|
||||||
ir_dev->props->priv, !!val);
|
|
||||||
else
|
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
|
return ir_dev->props->s_learning_mode(drv_data, !!val);
|
||||||
|
|
||||||
|
case LIRC_SET_MEASURE_CARRIER_MODE:
|
||||||
|
if (!ir_dev->props->s_carrier_report)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
return ir_dev->props->s_carrier_report(drv_data, !!val);
|
||||||
|
|
||||||
/* Generic timeout support */
|
/* Generic timeout support */
|
||||||
case LIRC_GET_MIN_TIMEOUT:
|
case LIRC_GET_MIN_TIMEOUT:
|
||||||
if (!ir_dev->props->max_timeout)
|
if (!ir_dev->props->max_timeout)
|
||||||
|
@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIRC_SET_REC_TIMEOUT:
|
case LIRC_SET_REC_TIMEOUT:
|
||||||
if (val < ir_dev->props->min_timeout ||
|
if (!ir_dev->props->max_timeout)
|
||||||
val > ir_dev->props->max_timeout)
|
return -ENOSYS;
|
||||||
|
|
||||||
|
tmp = val * 1000;
|
||||||
|
|
||||||
|
if (tmp < ir_dev->props->min_timeout ||
|
||||||
|
tmp > ir_dev->props->max_timeout)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
ir_dev->props->timeout = val * 1000;
|
|
||||||
|
ir_dev->props->timeout = tmp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIRC_SET_REC_TIMEOUT_REPORTS:
|
||||||
|
lirc->send_timeout_reports = !!val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -280,6 +328,10 @@ static int ir_lirc_register(struct input_dev *input_dev)
|
||||||
if (ir_dev->props->s_learning_mode)
|
if (ir_dev->props->s_learning_mode)
|
||||||
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
|
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
|
||||||
|
|
||||||
|
if (ir_dev->props->s_carrier_report)
|
||||||
|
features |= LIRC_CAN_MEASURE_CARRIER;
|
||||||
|
|
||||||
|
|
||||||
if (ir_dev->props->max_timeout)
|
if (ir_dev->props->max_timeout)
|
||||||
features |= LIRC_CAN_SET_REC_TIMEOUT;
|
features |= LIRC_CAN_SET_REC_TIMEOUT;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
|
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (IS_RESET(ev)) {
|
if (!is_timing_event(ev)) {
|
||||||
|
if (ev.reset)
|
||||||
data->state = STATE_INACTIVE;
|
data->state = STATE_INACTIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
|
||||||
if (ir->idle && !ev->pulse)
|
if (ir->idle && !ev->pulse)
|
||||||
return 0;
|
return 0;
|
||||||
else if (ir->idle)
|
else if (ir->idle)
|
||||||
ir_raw_event_set_idle(input_dev, 0);
|
ir_raw_event_set_idle(input_dev, false);
|
||||||
|
|
||||||
if (!raw->this_ev.duration) {
|
if (!raw->this_ev.duration) {
|
||||||
raw->this_ev = *ev;
|
raw->this_ev = *ev;
|
||||||
|
@ -187,48 +187,35 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
|
||||||
|
|
||||||
/* Enter idle mode if nessesary */
|
/* Enter idle mode if nessesary */
|
||||||
if (!ev->pulse && ir->props->timeout &&
|
if (!ev->pulse && ir->props->timeout &&
|
||||||
raw->this_ev.duration >= ir->props->timeout)
|
raw->this_ev.duration >= ir->props->timeout) {
|
||||||
ir_raw_event_set_idle(input_dev, 1);
|
ir_raw_event_set_idle(input_dev, true);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
|
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
|
||||||
|
|
||||||
void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
|
/**
|
||||||
|
* ir_raw_event_set_idle() - hint the ir core if device is receiving
|
||||||
|
* IR data or not
|
||||||
|
* @input_dev: the struct input_dev device descriptor
|
||||||
|
* @idle: the hint value
|
||||||
|
*/
|
||||||
|
void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle)
|
||||||
{
|
{
|
||||||
struct ir_input_dev *ir = input_get_drvdata(input_dev);
|
struct ir_input_dev *ir = input_get_drvdata(input_dev);
|
||||||
struct ir_raw_event_ctrl *raw = ir->raw;
|
struct ir_raw_event_ctrl *raw = ir->raw;
|
||||||
ktime_t now;
|
|
||||||
u64 delta;
|
|
||||||
|
|
||||||
if (!ir->props)
|
if (!ir->props || !ir->raw)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!ir->raw)
|
IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (idle) {
|
if (idle) {
|
||||||
IR_dprintk(2, "enter idle mode\n");
|
raw->this_ev.timeout = true;
|
||||||
raw->last_event = ktime_get();
|
|
||||||
} else {
|
|
||||||
IR_dprintk(2, "exit idle mode\n");
|
|
||||||
|
|
||||||
now = ktime_get();
|
|
||||||
delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
|
|
||||||
|
|
||||||
WARN_ON(raw->this_ev.pulse);
|
|
||||||
|
|
||||||
raw->this_ev.duration =
|
|
||||||
min(raw->this_ev.duration + delta,
|
|
||||||
(u64)IR_MAX_DURATION);
|
|
||||||
|
|
||||||
ir_raw_event_store(input_dev, &raw->this_ev);
|
ir_raw_event_store(input_dev, &raw->this_ev);
|
||||||
|
init_ir_raw_event(&raw->this_ev);
|
||||||
if (raw->this_ev.duration == IR_MAX_DURATION)
|
|
||||||
ir_raw_event_reset(input_dev);
|
|
||||||
|
|
||||||
raw->this_ev.duration = 0;
|
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
if (ir->props->s_idle)
|
if (ir->props->s_idle)
|
||||||
ir->props->s_idle(ir->props->priv, idle);
|
ir->props->s_idle(ir->props->priv, idle);
|
||||||
ir->idle = idle;
|
ir->idle = idle;
|
||||||
|
|
|
@ -55,7 +55,8 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
|
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (IS_RESET(ev)) {
|
if (!is_timing_event(ev)) {
|
||||||
|
if (ev.reset)
|
||||||
data->state = STATE_INACTIVE;
|
data->state = STATE_INACTIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,8 @@ static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
|
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (IS_RESET(ev)) {
|
if (!is_timing_event(ev)) {
|
||||||
|
if (ev.reset)
|
||||||
data->state = STATE_INACTIVE;
|
data->state = STATE_INACTIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,8 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
|
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (IS_RESET(ev)) {
|
if (!is_timing_event(ev)) {
|
||||||
|
if (ev.reset)
|
||||||
data->state = STATE_INACTIVE;
|
data->state = STATE_INACTIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,8 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
|
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (IS_RESET(ev)) {
|
if (!is_timing_event(ev)) {
|
||||||
|
if (ev.reset)
|
||||||
data->state = STATE_INACTIVE;
|
data->state = STATE_INACTIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -660,7 +660,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
|
||||||
|
|
||||||
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
||||||
{
|
{
|
||||||
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
|
DEFINE_IR_RAW_EVENT(rawir);
|
||||||
int i, start_index = 0;
|
int i, start_index = 0;
|
||||||
u8 hdr = MCE_CONTROL_HEADER;
|
u8 hdr = MCE_CONTROL_HEADER;
|
||||||
|
|
||||||
|
@ -997,6 +997,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
||||||
ir->len_in = maxp;
|
ir->len_in = maxp;
|
||||||
ir->flags.microsoft_gen1 = is_microsoft_gen1;
|
ir->flags.microsoft_gen1 = is_microsoft_gen1;
|
||||||
ir->flags.tx_mask_inverted = tx_mask_inverted;
|
ir->flags.tx_mask_inverted = tx_mask_inverted;
|
||||||
|
init_ir_raw_event(&ir->rawir);
|
||||||
|
|
||||||
/* Saving usb interface data for use by the transmitter routine */
|
/* Saving usb interface data for use by the transmitter routine */
|
||||||
ir->usb_ep_in = ep_in;
|
ir->usb_ep_in = ep_in;
|
||||||
|
|
|
@ -586,7 +586,7 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt)
|
||||||
*/
|
*/
|
||||||
static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
||||||
{
|
{
|
||||||
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
|
DEFINE_IR_RAW_EVENT(rawir);
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
u32 carrier;
|
u32 carrier;
|
||||||
u8 sample;
|
u8 sample;
|
||||||
|
@ -622,6 +622,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
||||||
}
|
}
|
||||||
|
|
||||||
rawir.duration += nvt->rawir.duration;
|
rawir.duration += nvt->rawir.duration;
|
||||||
|
|
||||||
|
init_ir_raw_event(&nvt->rawir);
|
||||||
nvt->rawir.duration = 0;
|
nvt->rawir.duration = 0;
|
||||||
nvt->rawir.pulse = rawir.pulse;
|
nvt->rawir.pulse = rawir.pulse;
|
||||||
|
|
||||||
|
@ -1016,6 +1018,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
|
||||||
|
|
||||||
spin_lock_init(&nvt->nvt_lock);
|
spin_lock_init(&nvt->nvt_lock);
|
||||||
spin_lock_init(&nvt->tx.lock);
|
spin_lock_init(&nvt->tx.lock);
|
||||||
|
init_ir_raw_event(&nvt->rawir);
|
||||||
|
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
/* now claim resources */
|
/* now claim resources */
|
||||||
|
|
|
@ -146,7 +146,7 @@ static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
|
||||||
static void sz_push_full_pulse(struct streamzap_ir *sz,
|
static void sz_push_full_pulse(struct streamzap_ir *sz,
|
||||||
unsigned char value)
|
unsigned char value)
|
||||||
{
|
{
|
||||||
struct ir_raw_event rawir;
|
DEFINE_IR_RAW_EVENT(rawir);
|
||||||
|
|
||||||
if (sz->idle) {
|
if (sz->idle) {
|
||||||
long deltv;
|
long deltv;
|
||||||
|
@ -193,7 +193,7 @@ static void sz_push_half_pulse(struct streamzap_ir *sz,
|
||||||
static void sz_push_full_space(struct streamzap_ir *sz,
|
static void sz_push_full_space(struct streamzap_ir *sz,
|
||||||
unsigned char value)
|
unsigned char value)
|
||||||
{
|
{
|
||||||
struct ir_raw_event rawir;
|
DEFINE_IR_RAW_EVENT(rawir);
|
||||||
|
|
||||||
rawir.pulse = false;
|
rawir.pulse = false;
|
||||||
rawir.duration = ((int) value) * SZ_RESOLUTION;
|
rawir.duration = ((int) value) * SZ_RESOLUTION;
|
||||||
|
@ -270,7 +270,7 @@ static void streamzap_callback(struct urb *urb)
|
||||||
break;
|
break;
|
||||||
case FullSpace:
|
case FullSpace:
|
||||||
if (sz->buf_in[i] == SZ_TIMEOUT) {
|
if (sz->buf_in[i] == SZ_TIMEOUT) {
|
||||||
struct ir_raw_event rawir;
|
DEFINE_IR_RAW_EVENT(rawir);
|
||||||
|
|
||||||
rawir.pulse = false;
|
rawir.pulse = false;
|
||||||
rawir.duration = timeout;
|
rawir.duration = timeout;
|
||||||
|
|
|
@ -60,6 +60,7 @@ enum rc_driver_type {
|
||||||
* @s_idle: optional: enable/disable hardware idle mode, upon which,
|
* @s_idle: optional: enable/disable hardware idle mode, upon which,
|
||||||
device doesn't interrupt host until it sees IR pulses
|
device doesn't interrupt host until it sees IR pulses
|
||||||
* @s_learning_mode: enable wide band receiver used for learning
|
* @s_learning_mode: enable wide band receiver used for learning
|
||||||
|
* @s_carrier_report: enable carrier reports
|
||||||
*/
|
*/
|
||||||
struct ir_dev_props {
|
struct ir_dev_props {
|
||||||
enum rc_driver_type driver_type;
|
enum rc_driver_type driver_type;
|
||||||
|
@ -82,8 +83,9 @@ struct ir_dev_props {
|
||||||
int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle);
|
int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle);
|
||||||
int (*s_rx_carrier_range)(void *priv, u32 min, u32 max);
|
int (*s_rx_carrier_range)(void *priv, u32 min, u32 max);
|
||||||
int (*tx_ir)(void *priv, int *txbuf, u32 n);
|
int (*tx_ir)(void *priv, int *txbuf, u32 n);
|
||||||
void (*s_idle)(void *priv, int enable);
|
void (*s_idle)(void *priv, bool enable);
|
||||||
int (*s_learning_mode)(void *priv, int enable);
|
int (*s_learning_mode)(void *priv, int enable);
|
||||||
|
int (*s_carrier_report) (void *priv, int enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ir_input_dev {
|
struct ir_input_dev {
|
||||||
|
@ -163,22 +165,48 @@ u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode);
|
||||||
/* From ir-raw-event.c */
|
/* From ir-raw-event.c */
|
||||||
|
|
||||||
struct ir_raw_event {
|
struct ir_raw_event {
|
||||||
|
union {
|
||||||
|
u32 duration;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 carrier;
|
||||||
|
u8 duty_cycle;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
unsigned pulse:1;
|
unsigned pulse:1;
|
||||||
unsigned duration:31;
|
unsigned reset:1;
|
||||||
|
unsigned timeout:1;
|
||||||
|
unsigned carrier_report:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IR_MAX_DURATION 0x7FFFFFFF /* a bit more than 2 seconds */
|
#define DEFINE_IR_RAW_EVENT(event) \
|
||||||
|
struct ir_raw_event event = { \
|
||||||
|
{ .duration = 0 } , \
|
||||||
|
.pulse = 0, \
|
||||||
|
.reset = 0, \
|
||||||
|
.timeout = 0, \
|
||||||
|
.carrier_report = 0 }
|
||||||
|
|
||||||
|
static inline void init_ir_raw_event(struct ir_raw_event *ev)
|
||||||
|
{
|
||||||
|
memset(ev, 0, sizeof(*ev));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */
|
||||||
|
|
||||||
void ir_raw_event_handle(struct input_dev *input_dev);
|
void ir_raw_event_handle(struct input_dev *input_dev);
|
||||||
int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
|
int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
|
||||||
int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
|
int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
|
||||||
int ir_raw_event_store_with_filter(struct input_dev *input_dev,
|
int ir_raw_event_store_with_filter(struct input_dev *input_dev,
|
||||||
struct ir_raw_event *ev);
|
struct ir_raw_event *ev);
|
||||||
void ir_raw_event_set_idle(struct input_dev *input_dev, int idle);
|
void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle);
|
||||||
|
|
||||||
static inline void ir_raw_event_reset(struct input_dev *input_dev)
|
static inline void ir_raw_event_reset(struct input_dev *input_dev)
|
||||||
{
|
{
|
||||||
struct ir_raw_event ev = { .pulse = false, .duration = 0 };
|
DEFINE_IR_RAW_EVENT(ev);
|
||||||
|
ev.reset = true;
|
||||||
|
|
||||||
ir_raw_event_store(input_dev, &ev);
|
ir_raw_event_store(input_dev, &ev);
|
||||||
ir_raw_event_handle(input_dev);
|
ir_raw_event_handle(input_dev);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue