* [PATCH 1/5] IR: extend and sort the MCE keymap
[not found] ` <1287158799-21486-1-git-send-email-maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2010-10-15 16:06 ` Maxim Levitsky
2010-10-15 19:48 ` Jarod Wilson
2010-10-15 16:06 ` [PATCH 2/5] IR: extend ir_raw_event and do refactoring Maxim Levitsky
` (3 subsequent siblings)
4 siblings, 1 reply; 15+ messages in thread
From: Maxim Levitsky @ 2010-10-15 16:06 UTC (permalink / raw)
To: lirc-list-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Cc: mchehab-wEGCiKHe2LqWVfeAwA7xHQ,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
Add new keys, found on:
Toshiba Qosmio F50-10q.
Toshiba Qosmio X300
Toshiba A500-141
Also sort the keytable by scancode number as that makes sense
and alows easily to add new keycodes.
Thanks to:
Sami R <maesesami-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Alexander Skiba <ghostlyrics-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Jordi Pelegrin <pelegrin.jordi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
For reports and testing.
Signed-off-by: Maxim Levitsky <maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/media/IR/keymaps/rc-rc6-mce.c | 88 +++++++++++++++++----------------
1 files changed, 45 insertions(+), 43 deletions(-)
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c
index 39557ad..1b7adab 100644
--- a/drivers/media/IR/keymaps/rc-rc6-mce.c
+++ b/drivers/media/IR/keymaps/rc-rc6-mce.c
@@ -12,76 +12,78 @@
#include <media/rc-map.h>
static struct ir_scancode rc6_mce[] = {
- { 0x800f0415, KEY_REWIND },
- { 0x800f0414, KEY_FASTFORWARD },
- { 0x800f041b, KEY_PREVIOUS },
- { 0x800f041a, KEY_NEXT },
+ { 0x800f0400, KEY_NUMERIC_0 },
+ { 0x800f0401, KEY_NUMERIC_1 },
+ { 0x800f0402, KEY_NUMERIC_2 },
+ { 0x800f0403, KEY_NUMERIC_3 },
+ { 0x800f0404, KEY_NUMERIC_4 },
+ { 0x800f0405, KEY_NUMERIC_5 },
+ { 0x800f0406, KEY_NUMERIC_6 },
+ { 0x800f0407, KEY_NUMERIC_7 },
+ { 0x800f0408, KEY_NUMERIC_8 },
+ { 0x800f0409, KEY_NUMERIC_9 },
+
+ { 0x800f040a, KEY_DELETE },
+ { 0x800f040b, KEY_ENTER },
+ { 0x800f040c, KEY_POWER },
+ { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
+ { 0x800f040e, KEY_MUTE },
+ { 0x800f040f, KEY_INFO },
+
+ { 0x800f0410, KEY_VOLUMEUP },
+ { 0x800f0411, KEY_VOLUMEDOWN },
+ { 0x800f0412, KEY_CHANNELUP },
+ { 0x800f0413, KEY_CHANNELDOWN },
+
+ { 0x800f0414, KEY_FASTFORWARD },
+ { 0x800f0415, KEY_REWIND },
{ 0x800f0416, KEY_PLAY },
+ { 0x800f0417, KEY_RECORD },
{ 0x800f0418, KEY_PAUSE },
{ 0x800f046e, KEY_PLAYPAUSE },
{ 0x800f0419, KEY_STOP },
- { 0x800f0417, KEY_RECORD },
+ { 0x800f041a, KEY_NEXT },
+ { 0x800f041b, KEY_PREVIOUS },
+ { 0x800f041c, KEY_NUMERIC_POUND },
+ { 0x800f041d, KEY_NUMERIC_STAR },
{ 0x800f041e, KEY_UP },
{ 0x800f041f, KEY_DOWN },
{ 0x800f0420, KEY_LEFT },
{ 0x800f0421, KEY_RIGHT },
- { 0x800f040b, KEY_ENTER },
{ 0x800f0422, KEY_OK },
{ 0x800f0423, KEY_EXIT },
- { 0x800f040a, KEY_DELETE },
+ { 0x800f0424, KEY_DVD },
+ { 0x800f0425, KEY_TUNER }, /* LiveTV */
+ { 0x800f0426, KEY_EPG }, /* Guide */
+ { 0x800f0427, KEY_ZOOM }, /* Aspect */
- { 0x800f040e, KEY_MUTE },
- { 0x800f0410, KEY_VOLUMEUP },
- { 0x800f0411, KEY_VOLUMEDOWN },
- { 0x800f0412, KEY_CHANNELUP },
- { 0x800f0413, KEY_CHANNELDOWN },
{ 0x800f043a, KEY_BRIGHTNESSUP },
- { 0x800f0480, KEY_BRIGHTNESSDOWN },
-
- { 0x800f0401, KEY_NUMERIC_1 },
- { 0x800f0402, KEY_NUMERIC_2 },
- { 0x800f0403, KEY_NUMERIC_3 },
- { 0x800f0404, KEY_NUMERIC_4 },
- { 0x800f0405, KEY_NUMERIC_5 },
- { 0x800f0406, KEY_NUMERIC_6 },
- { 0x800f0407, KEY_NUMERIC_7 },
- { 0x800f0408, KEY_NUMERIC_8 },
- { 0x800f0409, KEY_NUMERIC_9 },
- { 0x800f0400, KEY_NUMERIC_0 },
-
- { 0x800f041d, KEY_NUMERIC_STAR },
- { 0x800f041c, KEY_NUMERIC_POUND },
{ 0x800f0446, KEY_TV },
- { 0x800f0447, KEY_AUDIO }, /* My Music */
- { 0x800f0448, KEY_PVR }, /* RecordedTV */
+ { 0x800f0447, KEY_AUDIO }, /* My Music */
+ { 0x800f0448, KEY_PVR }, /* RecordedTV */
{ 0x800f0449, KEY_CAMERA },
{ 0x800f044a, KEY_VIDEO },
- { 0x800f0424, KEY_DVD },
- { 0x800f0425, KEY_TUNER }, /* LiveTV */
- { 0x800f0450, KEY_RADIO },
-
{ 0x800f044c, KEY_LANGUAGE },
- { 0x800f0427, KEY_ZOOM }, /* Aspect */
+ { 0x800f044d, KEY_TITLE },
+ { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
+ { 0x800f0450, KEY_RADIO },
+
+ { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
{ 0x800f045b, KEY_RED },
{ 0x800f045c, KEY_GREEN },
{ 0x800f045d, KEY_YELLOW },
{ 0x800f045e, KEY_BLUE },
- { 0x800f040f, KEY_INFO },
- { 0x800f0426, KEY_EPG }, /* Guide */
- { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
- { 0x800f044d, KEY_TITLE },
-
- { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
-
- { 0x800f040c, KEY_POWER },
- { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
+ { 0x800f046e, KEY_PLAYPAUSE },
+ { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
+ { 0x800f0480, KEY_BRIGHTNESSDOWN },
+ { 0x800f0481, KEY_PLAYPAUSE },
};
static struct rc_keymap rc6_mce_map = {
--
1.7.1
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 1/5] IR: extend and sort the MCE keymap
2010-10-15 16:06 ` [PATCH 1/5] IR: extend and sort the MCE keymap Maxim Levitsky
@ 2010-10-15 19:48 ` Jarod Wilson
0 siblings, 0 replies; 15+ messages in thread
From: Jarod Wilson @ 2010-10-15 19:48 UTC (permalink / raw)
To: Maxim Levitsky
Cc: lirc-list, Jarod Wilson, David Härdeman, mchehab,
linux-input, linux-media
On Fri, Oct 15, 2010 at 06:06:35PM +0200, Maxim Levitsky wrote:
> Add new keys, found on:
>
> Toshiba Qosmio F50-10q.
> Toshiba Qosmio X300
> Toshiba A500-141
>
> Also sort the keytable by scancode number as that makes sense
> and alows easily to add new keycodes.
>
> Thanks to:
> Sami R <maesesami@gmail.com>
> Alexander Skiba <ghostlyrics@gmail.com>
> Jordi Pelegrin <pelegrin.jordi@gmail.com>
>
> For reports and testing.
>
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Acked-by: Jarod Wilson <jarod@redhat.com>
--
Jarod Wilson
jarod@redhat.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 2/5] IR: extend ir_raw_event and do refactoring
[not found] ` <1287158799-21486-1-git-send-email-maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-10-15 16:06 ` [PATCH 1/5] IR: extend and sort the MCE keymap Maxim Levitsky
@ 2010-10-15 16:06 ` Maxim Levitsky
2010-10-16 3:29 ` Mauro Carvalho Chehab
2010-10-15 16:06 ` [PATCH 3/5] IR: ene_ir: few bugfixes Maxim Levitsky
` (2 subsequent siblings)
4 siblings, 1 reply; 15+ messages in thread
From: Maxim Levitsky @ 2010-10-15 16:06 UTC (permalink / raw)
To: lirc-list-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Cc: mchehab-wEGCiKHe2LqWVfeAwA7xHQ,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
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-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Acked-by: Jarod Wilson <jarod-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/media/IR/ene_ir.c | 4 +-
drivers/media/IR/ir-core-priv.h | 13 ++++-
drivers/media/IR/ir-jvc-decoder.c | 5 +-
drivers/media/IR/ir-lirc-codec.c | 128 +++++++++++++++++++++++++-----------
drivers/media/IR/ir-nec-decoder.c | 5 +-
drivers/media/IR/ir-raw-event.c | 45 +++++--------
drivers/media/IR/ir-rc5-decoder.c | 5 +-
drivers/media/IR/ir-rc6-decoder.c | 5 +-
drivers/media/IR/ir-sony-decoder.c | 5 +-
drivers/media/IR/mceusb.c | 3 +-
drivers/media/IR/streamzap.c | 8 ++-
include/media/ir-core.h | 40 ++++++++++--
12 files changed, 176 insertions(+), 90 deletions(-)
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
index 7880d9c..dc32509 100644
--- a/drivers/media/IR/ene_ir.c
+++ b/drivers/media/IR/ene_ir.c
@@ -701,7 +701,7 @@ static irqreturn_t ene_isr(int irq, void *data)
unsigned long flags;
irqreturn_t retval = IRQ_NONE;
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);
@@ -904,7 +904,7 @@ static int ene_set_learning_mode(void *data, int enable)
}
/* 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;
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index 5d7e08f..2559e72 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -82,6 +82,12 @@ struct ir_raw_event_ctrl {
struct ir_input_dev *ir_dev;
struct lirc_driver *drv;
int carrier_low;
+
+ ktime_t gap_start;
+ u64 gap_duration;
+ bool gap;
+ bool send_timeout_reports;
+
} lirc;
};
@@ -109,9 +115,14 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned 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_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
* ir-core
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
index 77a89c4..63dca6e 100644
--- a/drivers/media/IR/ir-jvc-decoder.c
+++ b/drivers/media/IR/ir-jvc-decoder.c
@@ -50,8 +50,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
return 0;
- if (IS_RESET(ev)) {
- data->state = STATE_INACTIVE;
+ if (!is_timing_event(ev)) {
+ if (ev.reset)
+ data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
index e63f757..9317be8 100644
--- a/drivers/media/IR/ir-lirc-codec.c
+++ b/drivers/media/IR/ir-lirc-codec.c
@@ -32,6 +32,7 @@
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 lirc_codec *lirc = &ir_dev->raw->lirc;
int sample;
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)
return -EINVAL;
- if (IS_RESET(ev))
+ /* Packet start */
+ if (ev.reset)
return 0;
- IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
- TO_US(ev.duration), TO_STR(ev.pulse));
+ /* Carrier reports */
+ if (ev.carrier_report) {
+ sample = LIRC_FREQUENCY(ev.carrier);
+
+ /* Packet end */
+ } else if (ev.timeout) {
+
+ 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);
- sample = ev.duration / 1000;
- if (ev.pulse)
- sample |= PULSE_BIT;
+ /* 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,
(unsigned char *) &sample);
wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
-
return 0;
}
@@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
struct ir_input_dev *ir_dev;
int ret = 0;
void *drv_data;
- unsigned long val = 0;
+ u32 tmp, val = 0;
lirc = lirc_get_pdata(filep);
if (!lirc)
@@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
case LIRC_SET_SEND_MODE:
if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
return -EINVAL;
- break;
+ return 0;
/* TX settings */
case LIRC_SET_TRANSMITTER_MASK:
- if (ir_dev->props->s_tx_mask)
- ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
- else
+ if (!ir_dev->props->s_tx_mask)
return -EINVAL;
- break;
+
+ return ir_dev->props->s_tx_mask(drv_data, (u32)val);
case LIRC_SET_SEND_CARRIER:
- if (ir_dev->props->s_tx_carrier)
- ir_dev->props->s_tx_carrier(drv_data, (u32)val);
- else
+ if (!ir_dev->props->s_tx_carrier)
return -EINVAL;
- break;
+
+ return ir_dev->props->s_tx_carrier(drv_data, (u32)val);
case LIRC_SET_SEND_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)
return -EINVAL;
- ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val);
- break;
+ return ir_dev->props->s_tx_duty_cycle(drv_data, val);
/* RX settings */
case LIRC_SET_REC_CARRIER:
- 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
+ if (!ir_dev->props->s_rx_carrier_range)
return -ENOSYS;
- if (!ret)
- ir_dev->raw->lirc.carrier_low = 0;
- break;
+ if (val <= 0)
+ return -EINVAL;
+
+ return ir_dev->props->s_rx_carrier_range(drv_data,
+ ir_dev->raw->lirc.carrier_low, val);
case LIRC_SET_REC_CARRIER_RANGE:
- if (val >= 0)
- ir_dev->raw->lirc.carrier_low = val;
- break;
+ if (val <= 0)
+ return -EINVAL;
+ ir_dev->raw->lirc.carrier_low = val;
+ return 0;
case LIRC_GET_REC_RESOLUTION:
val = ir_dev->props->rx_resolution;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
- if (ir_dev->props->s_learning_mode)
- return ir_dev->props->s_learning_mode(
- ir_dev->props->priv, !!val);
- else
+ if (!ir_dev->props->s_learning_mode)
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 */
case LIRC_GET_MIN_TIMEOUT:
if (!ir_dev->props->max_timeout)
@@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
break;
case LIRC_SET_REC_TIMEOUT:
- if (val < ir_dev->props->min_timeout ||
- val > ir_dev->props->max_timeout)
- return -EINVAL;
- ir_dev->props->timeout = val * 1000;
+ if (!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;
+
+ ir_dev->props->timeout = tmp;
+ break;
+
+ case LIRC_SET_REC_TIMEOUT_REPORTS:
+ lirc->send_timeout_reports = !!val;
break;
default:
@@ -277,6 +325,10 @@ static int ir_lirc_register(struct input_dev *input_dev)
if (ir_dev->props->s_learning_mode)
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
+ if (ir_dev->props->s_carrier_report)
+ features |= LIRC_CAN_MEASURE_CARRIER;
+
+
if (ir_dev->props->max_timeout)
features |= LIRC_CAN_SET_REC_TIMEOUT;
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index d597421..70993f7 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -54,8 +54,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
return 0;
- if (IS_RESET(ev)) {
- data->state = STATE_INACTIVE;
+ if (!is_timing_event(ev)) {
+ if (ev.reset)
+ data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 119b567..0d59ef7 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -174,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
if (ir->idle && !ev->pulse)
return 0;
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) {
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 */
if (!ev->pulse && ir->props->timeout &&
- raw->this_ev.duration >= ir->props->timeout)
- ir_raw_event_set_idle(input_dev, 1);
+ raw->this_ev.duration >= ir->props->timeout) {
+ ir_raw_event_set_idle(input_dev, true);
+ }
return 0;
}
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_raw_event_ctrl *raw = ir->raw;
- ktime_t now;
- u64 delta;
- if (!ir->props)
+ if (!ir->props || !ir->raw)
return;
- if (!ir->raw)
- goto out;
+ IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
if (idle) {
- IR_dprintk(2, "enter idle mode\n");
- 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);
-
+ raw->this_ev.timeout = true;
ir_raw_event_store(input_dev, &raw->this_ev);
-
- if (raw->this_ev.duration == IR_MAX_DURATION)
- ir_raw_event_reset(input_dev);
-
- raw->this_ev.duration = 0;
+ init_ir_raw_event(&raw->this_ev);
}
-out:
+
if (ir->props->s_idle)
ir->props->s_idle(ir->props->priv, idle);
ir->idle = idle;
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
index df4770d..572ed4c 100644
--- a/drivers/media/IR/ir-rc5-decoder.c
+++ b/drivers/media/IR/ir-rc5-decoder.c
@@ -55,8 +55,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
return 0;
- if (IS_RESET(ev)) {
- data->state = STATE_INACTIVE;
+ if (!is_timing_event(ev)) {
+ if (ev.reset)
+ data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
index f1624b8..d25da91 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -85,8 +85,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
return 0;
- if (IS_RESET(ev)) {
- data->state = STATE_INACTIVE;
+ if (!is_timing_event(ev)) {
+ if (ev.reset)
+ data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
index b9074f0..2d15730 100644
--- a/drivers/media/IR/ir-sony-decoder.c
+++ b/drivers/media/IR/ir-sony-decoder.c
@@ -48,8 +48,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
return 0;
- if (IS_RESET(ev)) {
- data->state = STATE_INACTIVE;
+ if (!is_timing_event(ev)) {
+ if (ev.reset)
+ data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
index bc620e1..6825da5 100644
--- a/drivers/media/IR/mceusb.c
+++ b/drivers/media/IR/mceusb.c
@@ -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)
{
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
+ DEFINE_IR_RAW_EVENT(rawir);
int i, start_index = 0;
u8 hdr = MCE_CONTROL_HEADER;
@@ -997,6 +997,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ir->len_in = maxp;
ir->flags.microsoft_gen1 = is_microsoft_gen1;
ir->flags.tx_mask_inverted = tx_mask_inverted;
+ init_ir_raw_event(&ir->rawir);
/* Saving usb interface data for use by the transmitter routine */
ir->usb_ep_in = ep_in;
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c
index 058e29f..18be3d5 100644
--- a/drivers/media/IR/streamzap.c
+++ b/drivers/media/IR/streamzap.c
@@ -170,7 +170,7 @@ static void streamzap_flush_timeout(unsigned long arg)
static void streamzap_delay_timeout(unsigned long arg)
{
struct streamzap_ir *sz = (struct streamzap_ir *)arg;
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
+ DEFINE_IR_RAW_EVENT(rawir);
unsigned long flags;
int len, ret;
static unsigned long delay;
@@ -215,7 +215,7 @@ static void streamzap_delay_timeout(unsigned long arg)
static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
{
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
+ DEFINE_IR_RAW_EVENT(rawir);
bool wake = false;
int ret;
@@ -233,7 +233,7 @@ static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
static void sz_push(struct streamzap_ir *sz)
{
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
+ DEFINE_IR_RAW_EVENT(rawir);
unsigned long flags;
int ret;
@@ -512,6 +512,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
if (!sz)
return -ENOMEM;
+ init_ir_raw_event(&sz->rawir);
+
sz->usbdev = usbdev;
sz->interface = intf;
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index eb7fddf..d88ce2b 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -60,6 +60,7 @@ enum rc_driver_type {
* @s_idle: optional: enable/disable hardware idle mode, upon which,
device doesn't interrupt host until it sees IR pulses
* @s_learning_mode: enable wide band receiver used for learning
+ * @s_carrier_report: enable carrier reports
*/
struct ir_dev_props {
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_rx_carrier_range)(void *priv, u32 min, u32 max);
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_carrier_report) (void *priv, int enable);
};
struct ir_input_dev {
@@ -162,22 +164,48 @@ u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode);
/* From ir-raw-event.c */
struct ir_raw_event {
- unsigned pulse:1;
- unsigned duration:31;
+ union {
+ u32 duration;
+
+ struct {
+ u32 carrier;
+ u8 duty_cycle;
+ };
+ };
+
+ unsigned pulse:1;
+ 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);
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_with_filter(struct input_dev *input_dev,
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)
{
- 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_handle(input_dev);
}
--
1.7.1
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 2/5] IR: extend ir_raw_event and do refactoring
2010-10-15 16:06 ` [PATCH 2/5] IR: extend ir_raw_event and do refactoring Maxim Levitsky
@ 2010-10-16 3:29 ` Mauro Carvalho Chehab
2010-10-16 4:11 ` Maxim Levitsky
0 siblings, 1 reply; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2010-10-16 3:29 UTC (permalink / raw)
To: Maxim Levitsky
Cc: lirc-list, Jarod Wilson, David Härdeman, linux-input,
linux-media
Em 15-10-2010 13:06, Maxim Levitsky escreveu:
> 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>
Applying patch patches/lmml_257371_2_5_ir_extend_ir_raw_event_and_do_refactoring.patch
patching file drivers/media/IR/ene_ir.c
patching file drivers/media/IR/ir-core-priv.h
Hunk #1 succeeded at 88 (offset 6 lines).
Hunk #2 succeeded at 121 (offset 6 lines).
patching file drivers/media/IR/ir-jvc-decoder.c
patching file drivers/media/IR/ir-lirc-codec.c
Hunk #3 FAILED at 139.
Hunk #4 FAILED at 167.
Hunk #7 succeeded at 330 (offset 3 lines).
2 out of 7 hunks FAILED -- rejects in file drivers/media/IR/ir-lirc-codec.c
patching file drivers/media/IR/ir-nec-decoder.c
patching file drivers/media/IR/ir-raw-event.c
patching file drivers/media/IR/ir-rc5-decoder.c
patching file drivers/media/IR/ir-rc6-decoder.c
patching file drivers/media/IR/ir-sony-decoder.c
patching file drivers/media/IR/mceusb.c
patching file drivers/media/IR/streamzap.c
Hunk #1 FAILED at 170.
Hunk #2 FAILED at 215.
Hunk #3 FAILED at 233.
Hunk #4 succeeded at 373 (offset -139 lines).
3 out of 4 hunks FAILED -- rejects in file drivers/media/IR/streamzap.c
patching file include/media/ir-core.h
Hunk #3 succeeded at 165 (offset 1 line).
Patch patches/lmml_257371_2_5_ir_extend_ir_raw_event_and_do_refactoring.patch does not apply (enforce with -f)
Patch didn't apply. Aborting
Too much fails for me... -EABORTING...
I won't apply this patch... there are two copies of it, and it has several broken hunks.
Please fix.
> ---
> drivers/media/IR/ene_ir.c | 4 +-
> drivers/media/IR/ir-core-priv.h | 13 ++++-
> drivers/media/IR/ir-jvc-decoder.c | 5 +-
> drivers/media/IR/ir-lirc-codec.c | 128 +++++++++++++++++++++++++-----------
> drivers/media/IR/ir-nec-decoder.c | 5 +-
> drivers/media/IR/ir-raw-event.c | 45 +++++--------
> drivers/media/IR/ir-rc5-decoder.c | 5 +-
> drivers/media/IR/ir-rc6-decoder.c | 5 +-
> drivers/media/IR/ir-sony-decoder.c | 5 +-
> drivers/media/IR/mceusb.c | 3 +-
> drivers/media/IR/streamzap.c | 8 ++-
> include/media/ir-core.h | 40 ++++++++++--
> 12 files changed, 176 insertions(+), 90 deletions(-)
>
> diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
> index 7880d9c..dc32509 100644
> --- a/drivers/media/IR/ene_ir.c
> +++ b/drivers/media/IR/ene_ir.c
> @@ -701,7 +701,7 @@ static irqreturn_t ene_isr(int irq, void *data)
> unsigned long flags;
> irqreturn_t retval = IRQ_NONE;
> 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);
>
> @@ -904,7 +904,7 @@ static int ene_set_learning_mode(void *data, int enable)
> }
>
> /* 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;
>
> diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
> index 5d7e08f..2559e72 100644
> --- a/drivers/media/IR/ir-core-priv.h
> +++ b/drivers/media/IR/ir-core-priv.h
> @@ -82,6 +82,12 @@ struct ir_raw_event_ctrl {
> struct ir_input_dev *ir_dev;
> struct lirc_driver *drv;
> int carrier_low;
> +
> + ktime_t gap_start;
> + u64 gap_duration;
> + bool gap;
> + bool send_timeout_reports;
> +
> } lirc;
> };
>
> @@ -109,9 +115,14 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned 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_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
> * ir-core
> diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
> index 77a89c4..63dca6e 100644
> --- a/drivers/media/IR/ir-jvc-decoder.c
> +++ b/drivers/media/IR/ir-jvc-decoder.c
> @@ -50,8 +50,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
> if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
> return 0;
>
> - if (IS_RESET(ev)) {
> - data->state = STATE_INACTIVE;
> + if (!is_timing_event(ev)) {
> + if (ev.reset)
> + data->state = STATE_INACTIVE;
> return 0;
> }
>
> diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
> index e63f757..9317be8 100644
> --- a/drivers/media/IR/ir-lirc-codec.c
> +++ b/drivers/media/IR/ir-lirc-codec.c
> @@ -32,6 +32,7 @@
> 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 lirc_codec *lirc = &ir_dev->raw->lirc;
> int sample;
>
> 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)
> return -EINVAL;
>
> - if (IS_RESET(ev))
> + /* Packet start */
> + if (ev.reset)
> return 0;
>
> - IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
> - TO_US(ev.duration), TO_STR(ev.pulse));
> + /* Carrier reports */
> + if (ev.carrier_report) {
> + sample = LIRC_FREQUENCY(ev.carrier);
> +
> + /* Packet end */
> + } else if (ev.timeout) {
> +
> + 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);
>
> - sample = ev.duration / 1000;
> - if (ev.pulse)
> - sample |= PULSE_BIT;
> + /* 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,
> (unsigned char *) &sample);
> wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
>
> -
> return 0;
> }
>
> @@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
> struct ir_input_dev *ir_dev;
> int ret = 0;
> void *drv_data;
> - unsigned long val = 0;
> + u32 tmp, val = 0;
>
> lirc = lirc_get_pdata(filep);
> if (!lirc)
> @@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
> case LIRC_SET_SEND_MODE:
> if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
> return -EINVAL;
> - break;
> + return 0;
>
> /* TX settings */
> case LIRC_SET_TRANSMITTER_MASK:
> - if (ir_dev->props->s_tx_mask)
> - ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
> - else
> + if (!ir_dev->props->s_tx_mask)
> return -EINVAL;
> - break;
> +
> + return ir_dev->props->s_tx_mask(drv_data, (u32)val);
>
> case LIRC_SET_SEND_CARRIER:
> - if (ir_dev->props->s_tx_carrier)
> - ir_dev->props->s_tx_carrier(drv_data, (u32)val);
> - else
> + if (!ir_dev->props->s_tx_carrier)
> return -EINVAL;
> - break;
> +
> + return ir_dev->props->s_tx_carrier(drv_data, (u32)val);
>
> case LIRC_SET_SEND_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)
> return -EINVAL;
>
> - ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val);
> - break;
> + return ir_dev->props->s_tx_duty_cycle(drv_data, val);
>
> /* RX settings */
> case LIRC_SET_REC_CARRIER:
> - 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
> + if (!ir_dev->props->s_rx_carrier_range)
> return -ENOSYS;
>
> - if (!ret)
> - ir_dev->raw->lirc.carrier_low = 0;
> - break;
> + if (val <= 0)
> + return -EINVAL;
> +
> + return ir_dev->props->s_rx_carrier_range(drv_data,
> + ir_dev->raw->lirc.carrier_low, val);
>
> case LIRC_SET_REC_CARRIER_RANGE:
> - if (val >= 0)
> - ir_dev->raw->lirc.carrier_low = val;
> - break;
> + if (val <= 0)
> + return -EINVAL;
>
> + ir_dev->raw->lirc.carrier_low = val;
> + return 0;
>
> case LIRC_GET_REC_RESOLUTION:
> val = ir_dev->props->rx_resolution;
> break;
>
> case LIRC_SET_WIDEBAND_RECEIVER:
> - if (ir_dev->props->s_learning_mode)
> - return ir_dev->props->s_learning_mode(
> - ir_dev->props->priv, !!val);
> - else
> + if (!ir_dev->props->s_learning_mode)
> 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 */
> case LIRC_GET_MIN_TIMEOUT:
> if (!ir_dev->props->max_timeout)
> @@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
> break;
>
> case LIRC_SET_REC_TIMEOUT:
> - if (val < ir_dev->props->min_timeout ||
> - val > ir_dev->props->max_timeout)
> - return -EINVAL;
> - ir_dev->props->timeout = val * 1000;
> + if (!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;
> +
> + ir_dev->props->timeout = tmp;
> + break;
> +
> + case LIRC_SET_REC_TIMEOUT_REPORTS:
> + lirc->send_timeout_reports = !!val;
> break;
>
> default:
> @@ -277,6 +325,10 @@ static int ir_lirc_register(struct input_dev *input_dev)
> if (ir_dev->props->s_learning_mode)
> features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
>
> + if (ir_dev->props->s_carrier_report)
> + features |= LIRC_CAN_MEASURE_CARRIER;
> +
> +
> if (ir_dev->props->max_timeout)
> features |= LIRC_CAN_SET_REC_TIMEOUT;
>
> diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
> index d597421..70993f7 100644
> --- a/drivers/media/IR/ir-nec-decoder.c
> +++ b/drivers/media/IR/ir-nec-decoder.c
> @@ -54,8 +54,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
> if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
> return 0;
>
> - if (IS_RESET(ev)) {
> - data->state = STATE_INACTIVE;
> + if (!is_timing_event(ev)) {
> + if (ev.reset)
> + data->state = STATE_INACTIVE;
> return 0;
> }
>
> diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
> index 119b567..0d59ef7 100644
> --- a/drivers/media/IR/ir-raw-event.c
> +++ b/drivers/media/IR/ir-raw-event.c
> @@ -174,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
> if (ir->idle && !ev->pulse)
> return 0;
> 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) {
> 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 */
> if (!ev->pulse && ir->props->timeout &&
> - raw->this_ev.duration >= ir->props->timeout)
> - ir_raw_event_set_idle(input_dev, 1);
> + raw->this_ev.duration >= ir->props->timeout) {
> + ir_raw_event_set_idle(input_dev, true);
> + }
> return 0;
> }
> 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_raw_event_ctrl *raw = ir->raw;
> - ktime_t now;
> - u64 delta;
>
> - if (!ir->props)
> + if (!ir->props || !ir->raw)
> return;
>
> - if (!ir->raw)
> - goto out;
> + IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
>
> if (idle) {
> - IR_dprintk(2, "enter idle mode\n");
> - 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);
> -
> + raw->this_ev.timeout = true;
> ir_raw_event_store(input_dev, &raw->this_ev);
> -
> - if (raw->this_ev.duration == IR_MAX_DURATION)
> - ir_raw_event_reset(input_dev);
> -
> - raw->this_ev.duration = 0;
> + init_ir_raw_event(&raw->this_ev);
> }
> -out:
> +
> if (ir->props->s_idle)
> ir->props->s_idle(ir->props->priv, idle);
> ir->idle = idle;
> diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
> index df4770d..572ed4c 100644
> --- a/drivers/media/IR/ir-rc5-decoder.c
> +++ b/drivers/media/IR/ir-rc5-decoder.c
> @@ -55,8 +55,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
> if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
> return 0;
>
> - if (IS_RESET(ev)) {
> - data->state = STATE_INACTIVE;
> + if (!is_timing_event(ev)) {
> + if (ev.reset)
> + data->state = STATE_INACTIVE;
> return 0;
> }
>
> diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
> index f1624b8..d25da91 100644
> --- a/drivers/media/IR/ir-rc6-decoder.c
> +++ b/drivers/media/IR/ir-rc6-decoder.c
> @@ -85,8 +85,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
> if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
> return 0;
>
> - if (IS_RESET(ev)) {
> - data->state = STATE_INACTIVE;
> + if (!is_timing_event(ev)) {
> + if (ev.reset)
> + data->state = STATE_INACTIVE;
> return 0;
> }
>
> diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
> index b9074f0..2d15730 100644
> --- a/drivers/media/IR/ir-sony-decoder.c
> +++ b/drivers/media/IR/ir-sony-decoder.c
> @@ -48,8 +48,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
> if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
> return 0;
>
> - if (IS_RESET(ev)) {
> - data->state = STATE_INACTIVE;
> + if (!is_timing_event(ev)) {
> + if (ev.reset)
> + data->state = STATE_INACTIVE;
> return 0;
> }
>
> diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
> index bc620e1..6825da5 100644
> --- a/drivers/media/IR/mceusb.c
> +++ b/drivers/media/IR/mceusb.c
> @@ -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)
> {
> - struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
> + DEFINE_IR_RAW_EVENT(rawir);
> int i, start_index = 0;
> u8 hdr = MCE_CONTROL_HEADER;
>
> @@ -997,6 +997,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
> ir->len_in = maxp;
> ir->flags.microsoft_gen1 = is_microsoft_gen1;
> ir->flags.tx_mask_inverted = tx_mask_inverted;
> + init_ir_raw_event(&ir->rawir);
>
> /* Saving usb interface data for use by the transmitter routine */
> ir->usb_ep_in = ep_in;
> diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c
> index 058e29f..18be3d5 100644
> --- a/drivers/media/IR/streamzap.c
> +++ b/drivers/media/IR/streamzap.c
> @@ -170,7 +170,7 @@ static void streamzap_flush_timeout(unsigned long arg)
> static void streamzap_delay_timeout(unsigned long arg)
> {
> struct streamzap_ir *sz = (struct streamzap_ir *)arg;
> - struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
> + DEFINE_IR_RAW_EVENT(rawir);
> unsigned long flags;
> int len, ret;
> static unsigned long delay;
> @@ -215,7 +215,7 @@ static void streamzap_delay_timeout(unsigned long arg)
>
> static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
> {
> - struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
> + DEFINE_IR_RAW_EVENT(rawir);
> bool wake = false;
> int ret;
>
> @@ -233,7 +233,7 @@ static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
>
> static void sz_push(struct streamzap_ir *sz)
> {
> - struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
> + DEFINE_IR_RAW_EVENT(rawir);
> unsigned long flags;
> int ret;
>
> @@ -512,6 +512,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
> if (!sz)
> return -ENOMEM;
>
> + init_ir_raw_event(&sz->rawir);
> +
> sz->usbdev = usbdev;
> sz->interface = intf;
>
> diff --git a/include/media/ir-core.h b/include/media/ir-core.h
> index eb7fddf..d88ce2b 100644
> --- a/include/media/ir-core.h
> +++ b/include/media/ir-core.h
> @@ -60,6 +60,7 @@ enum rc_driver_type {
> * @s_idle: optional: enable/disable hardware idle mode, upon which,
> device doesn't interrupt host until it sees IR pulses
> * @s_learning_mode: enable wide band receiver used for learning
> + * @s_carrier_report: enable carrier reports
> */
> struct ir_dev_props {
> 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_rx_carrier_range)(void *priv, u32 min, u32 max);
> 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_carrier_report) (void *priv, int enable);
> };
>
> struct ir_input_dev {
> @@ -162,22 +164,48 @@ u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode);
> /* From ir-raw-event.c */
>
> struct ir_raw_event {
> - unsigned pulse:1;
> - unsigned duration:31;
> + union {
> + u32 duration;
> +
> + struct {
> + u32 carrier;
> + u8 duty_cycle;
> + };
> + };
> +
> + unsigned pulse:1;
> + 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);
> 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_with_filter(struct input_dev *input_dev,
> 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)
> {
> - 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_handle(input_dev);
> }
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/5] IR: extend ir_raw_event and do refactoring
2010-10-16 3:29 ` Mauro Carvalho Chehab
@ 2010-10-16 4:11 ` Maxim Levitsky
0 siblings, 0 replies; 15+ messages in thread
From: Maxim Levitsky @ 2010-10-16 4:11 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: lirc-list, Jarod Wilson, David Härdeman, linux-input,
linux-media
On Sat, 2010-10-16 at 00:29 -0300, Mauro Carvalho Chehab wrote:
> Em 15-10-2010 13:06, Maxim Levitsky escreveu:
> > 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>
>
>
> Applying patch patches/lmml_257371_2_5_ir_extend_ir_raw_event_and_do_refactoring.patch
> patching file drivers/media/IR/ene_ir.c
> patching file drivers/media/IR/ir-core-priv.h
> Hunk #1 succeeded at 88 (offset 6 lines).
> Hunk #2 succeeded at 121 (offset 6 lines).
> patching file drivers/media/IR/ir-jvc-decoder.c
> patching file drivers/media/IR/ir-lirc-codec.c
> Hunk #3 FAILED at 139.
> Hunk #4 FAILED at 167.
> Hunk #7 succeeded at 330 (offset 3 lines).
> 2 out of 7 hunks FAILED -- rejects in file drivers/media/IR/ir-lirc-codec.c
> patching file drivers/media/IR/ir-nec-decoder.c
> patching file drivers/media/IR/ir-raw-event.c
> patching file drivers/media/IR/ir-rc5-decoder.c
> patching file drivers/media/IR/ir-rc6-decoder.c
> patching file drivers/media/IR/ir-sony-decoder.c
> patching file drivers/media/IR/mceusb.c
> patching file drivers/media/IR/streamzap.c
> Hunk #1 FAILED at 170.
> Hunk #2 FAILED at 215.
> Hunk #3 FAILED at 233.
> Hunk #4 succeeded at 373 (offset -139 lines).
> 3 out of 4 hunks FAILED -- rejects in file drivers/media/IR/streamzap.c
> patching file include/media/ir-core.h
> Hunk #3 succeeded at 165 (offset 1 line).
> Patch patches/lmml_257371_2_5_ir_extend_ir_raw_event_and_do_refactoring.patch does not apply (enforce with -f)
> Patch didn't apply. Aborting
>
> Too much fails for me... -EABORTING...
>
> I won't apply this patch... there are two copies of it, and it has several broken hunks.
>
>
> Please fix.
Not surprising as v4l tree got many changes and that patch touches many
places.
Will redo that really against the media_tree :-)
Sorry!
Best regards,
Maxim Levitsky
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 3/5] IR: ene_ir: few bugfixes
[not found] ` <1287158799-21486-1-git-send-email-maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-10-15 16:06 ` [PATCH 1/5] IR: extend and sort the MCE keymap Maxim Levitsky
2010-10-15 16:06 ` [PATCH 2/5] IR: extend ir_raw_event and do refactoring Maxim Levitsky
@ 2010-10-15 16:06 ` Maxim Levitsky
2010-10-15 20:02 ` Jarod Wilson
2010-10-15 16:06 ` [PATCH 4/5] IR: ene_ir: add support for carrier reports Maxim Levitsky
2010-10-15 16:06 ` [PATCH 5/5] IR: ene_ir: don't upload all settings on each TX packet Maxim Levitsky
4 siblings, 1 reply; 15+ messages in thread
From: Maxim Levitsky @ 2010-10-15 16:06 UTC (permalink / raw)
To: lirc-list-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Cc: mchehab-wEGCiKHe2LqWVfeAwA7xHQ,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
This is a result of last round of debug with
Sami R <maesesami-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>.
Thank you Sami very much!
The biggest bug I fixed is that,
I was clobbering the CIRCFG register after it is setup
That wasn't a good idea really
And some small refactoring, etc.
Signed-off-by: Maxim Levitsky <maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/media/IR/ene_ir.c | 43 ++++++++++++++++++++-----------------------
1 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
index dc32509..8639621 100644
--- a/drivers/media/IR/ene_ir.c
+++ b/drivers/media/IR/ene_ir.c
@@ -156,11 +156,12 @@ static int ene_hw_detect(struct ene_device *dev)
ene_notice("Firmware regs: %02x %02x", fw_reg1, fw_reg2);
- dev->hw_use_gpio_0a = fw_reg2 & ENE_FW2_GP0A;
- dev->hw_learning_and_tx_capable = fw_reg2 & ENE_FW2_LEARNING;
- dev->hw_extra_buffer = fw_reg1 & ENE_FW1_HAS_EXTRA_BUF;
- dev->hw_fan_input = dev->hw_learning_and_tx_capable &&
- (fw_reg2 & ENE_FW2_FAN_INPUT);
+ dev->hw_use_gpio_0a = !!(fw_reg2 & ENE_FW2_GP0A);
+ dev->hw_learning_and_tx_capable = !!(fw_reg2 & ENE_FW2_LEARNING);
+ dev->hw_extra_buffer = !!(fw_reg1 & ENE_FW1_HAS_EXTRA_BUF);
+
+ if (dev->hw_learning_and_tx_capable)
+ dev->hw_fan_input = !!(fw_reg2 & ENE_FW2_FAN_INPUT);
ene_notice("Hardware features:");
@@ -255,6 +256,8 @@ static void ene_rx_setup(struct ene_device *dev)
dev->carrier_detect_enabled;
int sample_period_adjust = 0;
+ /* This selects RLC input and clears CFG2 settings */
+ ene_write_reg(dev, ENE_CIRCFG2, 0x00);
/* set sample period*/
if (sample_period == ENE_DEFAULT_SAMPLE_PERIOD)
@@ -268,7 +271,9 @@ static void ene_rx_setup(struct ene_device *dev)
if (dev->hw_revision < ENE_HW_C)
goto select_timeout;
- if (learning_mode && dev->hw_learning_and_tx_capable) {
+ if (learning_mode) {
+
+ WARN_ON(!dev->hw_learning_and_tx_capable);
/* Enable the opposite of the normal input
That means that if GPIO40 is normally used, use GPIO0A
@@ -282,6 +287,7 @@ static void ene_rx_setup(struct ene_device *dev)
ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
/* Enable carrier detection */
+ ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63);
ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT,
dev->carrier_detect_enabled || debug);
} else {
@@ -343,19 +349,9 @@ static void ene_rx_enable(struct ene_device *dev)
ene_write_reg(dev, ENE_IRQ, reg_value);
}
- if (dev->hw_revision >= ENE_HW_C)
- ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63);
-
- /* Enable the inputs */
- ene_write_reg(dev, ENE_CIRCFG2, 0x00);
-
- if (dev->rx_fan_input_inuse) {
- ene_enable_cir_engine(dev, false);
- ene_enable_fan_input(dev, true);
- } else {
- ene_enable_cir_engine(dev, true);
- ene_enable_fan_input(dev, false);
- }
+ /* Enable inputs */
+ ene_enable_fan_input(dev, dev->rx_fan_input_inuse);
+ ene_enable_cir_engine(dev, !dev->rx_fan_input_inuse);
/* ack any pending irqs - just in case */
ene_irq_status(dev);
@@ -793,12 +789,10 @@ static void ene_setup_settings(struct ene_device *dev)
dev->tx_period = 32;
dev->tx_duty_cycle = 50; /*%*/
dev->transmitter_mask = 0x03;
-
- dev->learning_enabled =
- (learning_mode && dev->hw_learning_and_tx_capable);
+ dev->learning_enabled = learning_mode;
/* Set reasonable default timeout */
- dev->props->timeout = MS_TO_NS(15000);
+ dev->props->timeout = MS_TO_NS(150000);
}
/* outside interface: called on first open*/
@@ -1015,6 +1009,9 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
ene_warn("Simulation of TX activated");
}
+ if (!dev->hw_learning_and_tx_capable)
+ learning_mode = false;
+
ir_props->driver_type = RC_DRIVER_IR_RAW;
ir_props->allowed_protos = IR_TYPE_ALL;
ir_props->priv = dev;
--
1.7.1
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 3/5] IR: ene_ir: few bugfixes
2010-10-15 16:06 ` [PATCH 3/5] IR: ene_ir: few bugfixes Maxim Levitsky
@ 2010-10-15 20:02 ` Jarod Wilson
[not found] ` <20101015200212.GK9658-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 15+ messages in thread
From: Jarod Wilson @ 2010-10-15 20:02 UTC (permalink / raw)
To: Maxim Levitsky
Cc: lirc-list, Jarod Wilson, David Härdeman, mchehab,
linux-input, linux-media
On Fri, Oct 15, 2010 at 06:06:37PM +0200, Maxim Levitsky wrote:
> This is a result of last round of debug with
> Sami R <maesesami@gmail.com>.
>
> Thank you Sami very much!
>
> The biggest bug I fixed is that,
> I was clobbering the CIRCFG register after it is setup
> That wasn't a good idea really
>
> And some small refactoring, etc.
>
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> ---
> drivers/media/IR/ene_ir.c | 43 ++++++++++++++++++++-----------------------
> 1 files changed, 20 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
> index dc32509..8639621 100644
> --- a/drivers/media/IR/ene_ir.c
> +++ b/drivers/media/IR/ene_ir.c
...
> @@ -282,6 +287,7 @@ static void ene_rx_setup(struct ene_device *dev)
> ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
>
> /* Enable carrier detection */
> + ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63);
Looks sane, though I'd prefer to see symbolic bit names or some such thing
here instead of 0x63. Not something to hold up the patch though.
Acked-by: Jarod Wilson <jarod@redhat.com>
--
Jarod Wilson
jarod@redhat.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 4/5] IR: ene_ir: add support for carrier reports
[not found] ` <1287158799-21486-1-git-send-email-maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (2 preceding siblings ...)
2010-10-15 16:06 ` [PATCH 3/5] IR: ene_ir: few bugfixes Maxim Levitsky
@ 2010-10-15 16:06 ` Maxim Levitsky
2010-10-15 20:16 ` Jarod Wilson
2010-10-16 3:31 ` Mauro Carvalho Chehab
2010-10-15 16:06 ` [PATCH 5/5] IR: ene_ir: don't upload all settings on each TX packet Maxim Levitsky
4 siblings, 2 replies; 15+ messages in thread
From: Maxim Levitsky @ 2010-10-15 16:06 UTC (permalink / raw)
To: lirc-list-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Cc: mchehab-wEGCiKHe2LqWVfeAwA7xHQ,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Maxim Levitsky <maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/media/IR/ene_ir.c | 37 +++++++++++++++++++++++++++++--------
1 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
index 8639621..1962652 100644
--- a/drivers/media/IR/ene_ir.c
+++ b/drivers/media/IR/ene_ir.c
@@ -193,10 +193,11 @@ static int ene_hw_detect(struct ene_device *dev)
/* Sense current received carrier */
void ene_rx_sense_carrier(struct ene_device *dev)
{
+ DEFINE_IR_RAW_EVENT(ev);
+
+ int carrier, duty_cycle;
int period = ene_read_reg(dev, ENE_CIRCAR_PRD);
int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD);
- int carrier, duty_cycle;
-
if (!(period & ENE_CIRCAR_PRD_VALID))
return;
@@ -209,13 +210,16 @@ void ene_rx_sense_carrier(struct ene_device *dev)
dbg("RX: hardware carrier period = %02x", period);
dbg("RX: hardware carrier pulse period = %02x", hperiod);
-
carrier = 2000000 / period;
duty_cycle = (hperiod * 100) / period;
dbg("RX: sensed carrier = %d Hz, duty cycle %d%%",
- carrier, duty_cycle);
-
- /* TODO: Send carrier & duty cycle to IR layer */
+ carrier, duty_cycle);
+ if (dev->carrier_detect_enabled) {
+ ev.carrier_report = true;
+ ev.carrier = carrier;
+ ev.duty_cycle = duty_cycle;
+ ir_raw_event_store(dev->idev, &ev);
+ }
}
/* this enables/disables the CIR RX engine */
@@ -724,7 +728,7 @@ static irqreturn_t ene_isr(int irq, void *data)
dbg_verbose("RX interrupt");
- if (dev->carrier_detect_enabled || debug)
+ if (dev->hw_learning_and_tx_capable)
ene_rx_sense_carrier(dev);
/* On hardware that don't support extra buffer we need to trust
@@ -897,6 +901,23 @@ static int ene_set_learning_mode(void *data, int enable)
return 0;
}
+static int ene_set_carrier_report(void *data, int enable)
+{
+ struct ene_device *dev = (struct ene_device *)data;
+ unsigned long flags;
+
+ if (enable == dev->carrier_detect_enabled)
+ return 0;
+
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ dev->carrier_detect_enabled = enable;
+ ene_rx_disable(dev);
+ ene_rx_setup(dev);
+ ene_rx_enable(dev);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
+ return 0;
+}
+
/* outside interface: enable or disable idle mode */
static void ene_rx_set_idle(void *data, bool idle)
{
@@ -1029,7 +1050,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
ir_props->s_tx_mask = ene_set_tx_mask;
ir_props->s_tx_carrier = ene_set_tx_carrier;
ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
- /* ir_props->s_carrier_report = ene_set_carrier_report; */
+ ir_props->s_carrier_report = ene_set_carrier_report;
}
ene_setup_hw_buffer(dev);
--
1.7.1
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 4/5] IR: ene_ir: add support for carrier reports
2010-10-15 16:06 ` [PATCH 4/5] IR: ene_ir: add support for carrier reports Maxim Levitsky
@ 2010-10-15 20:16 ` Jarod Wilson
2010-10-16 3:31 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 15+ messages in thread
From: Jarod Wilson @ 2010-10-15 20:16 UTC (permalink / raw)
To: Maxim Levitsky
Cc: lirc-list, Jarod Wilson, David Härdeman, mchehab,
linux-input, linux-media
On Fri, Oct 15, 2010 at 06:06:38PM +0200, Maxim Levitsky wrote:
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> ---
> drivers/media/IR/ene_ir.c | 37 +++++++++++++++++++++++++++++--------
> 1 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
> index 8639621..1962652 100644
> --- a/drivers/media/IR/ene_ir.c
> +++ b/drivers/media/IR/ene_ir.c
...
> @@ -209,13 +210,16 @@ void ene_rx_sense_carrier(struct ene_device *dev)
> dbg("RX: hardware carrier period = %02x", period);
> dbg("RX: hardware carrier pulse period = %02x", hperiod);
>
> -
> carrier = 2000000 / period;
> duty_cycle = (hperiod * 100) / period;
> dbg("RX: sensed carrier = %d Hz, duty cycle %d%%",
> - carrier, duty_cycle);
> -
> - /* TODO: Send carrier & duty cycle to IR layer */
> + carrier, duty_cycle);
Spacing is a bit odd here (random indent, no newline), but meh, looks sane
otherwise.
> + if (dev->carrier_detect_enabled) {
> + ev.carrier_report = true;
> + ev.carrier = carrier;
> + ev.duty_cycle = duty_cycle;
> + ir_raw_event_store(dev->idev, &ev);
> + }
> }
>
> /* this enables/disables the CIR RX engine */
Acked-by: Jarod Wilson <jarod@redhat.com>
--
Jarod Wilson
jarod@redhat.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 4/5] IR: ene_ir: add support for carrier reports
2010-10-15 16:06 ` [PATCH 4/5] IR: ene_ir: add support for carrier reports Maxim Levitsky
2010-10-15 20:16 ` Jarod Wilson
@ 2010-10-16 3:31 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2010-10-16 3:31 UTC (permalink / raw)
To: Maxim Levitsky
Cc: lirc-list, Jarod Wilson, David Härdeman, linux-input,
linux-media
Em 15-10-2010 13:06, Maxim Levitsky escreveu:
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> ---
> drivers/media/IR/ene_ir.c | 37 +++++++++++++++++++++++++++++--------
> 1 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
> index 8639621..1962652 100644
> --- a/drivers/media/IR/ene_ir.c
> +++ b/drivers/media/IR/ene_ir.c
> @@ -193,10 +193,11 @@ static int ene_hw_detect(struct ene_device *dev)
> /* Sense current received carrier */
> void ene_rx_sense_carrier(struct ene_device *dev)
> {
> + DEFINE_IR_RAW_EVENT(ev);
> +
Hmm... shouldn't it be in the patch that adds DEFINE_IR_RAW_EVENT(ev) ?
This way, it will likely break git bisect.
Anyway, as patch 2/5 weren't applied, I can't apply this one either.
the other 2 patches were applied.
> + int carrier, duty_cycle;
> int period = ene_read_reg(dev, ENE_CIRCAR_PRD);
> int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD);
> - int carrier, duty_cycle;
> -
>
> if (!(period & ENE_CIRCAR_PRD_VALID))
> return;
> @@ -209,13 +210,16 @@ void ene_rx_sense_carrier(struct ene_device *dev)
> dbg("RX: hardware carrier period = %02x", period);
> dbg("RX: hardware carrier pulse period = %02x", hperiod);
>
> -
> carrier = 2000000 / period;
> duty_cycle = (hperiod * 100) / period;
> dbg("RX: sensed carrier = %d Hz, duty cycle %d%%",
> - carrier, duty_cycle);
> -
> - /* TODO: Send carrier & duty cycle to IR layer */
> + carrier, duty_cycle);
> + if (dev->carrier_detect_enabled) {
> + ev.carrier_report = true;
> + ev.carrier = carrier;
> + ev.duty_cycle = duty_cycle;
> + ir_raw_event_store(dev->idev, &ev);
> + }
> }
>
> /* this enables/disables the CIR RX engine */
> @@ -724,7 +728,7 @@ static irqreturn_t ene_isr(int irq, void *data)
>
> dbg_verbose("RX interrupt");
>
> - if (dev->carrier_detect_enabled || debug)
> + if (dev->hw_learning_and_tx_capable)
> ene_rx_sense_carrier(dev);
>
> /* On hardware that don't support extra buffer we need to trust
> @@ -897,6 +901,23 @@ static int ene_set_learning_mode(void *data, int enable)
> return 0;
> }
>
> +static int ene_set_carrier_report(void *data, int enable)
> +{
> + struct ene_device *dev = (struct ene_device *)data;
> + unsigned long flags;
> +
> + if (enable == dev->carrier_detect_enabled)
> + return 0;
> +
> + spin_lock_irqsave(&dev->hw_lock, flags);
> + dev->carrier_detect_enabled = enable;
> + ene_rx_disable(dev);
> + ene_rx_setup(dev);
> + ene_rx_enable(dev);
> + spin_unlock_irqrestore(&dev->hw_lock, flags);
> + return 0;
> +}
> +
> /* outside interface: enable or disable idle mode */
> static void ene_rx_set_idle(void *data, bool idle)
> {
> @@ -1029,7 +1050,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
> ir_props->s_tx_mask = ene_set_tx_mask;
> ir_props->s_tx_carrier = ene_set_tx_carrier;
> ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
> - /* ir_props->s_carrier_report = ene_set_carrier_report; */
> + ir_props->s_carrier_report = ene_set_carrier_report;
> }
>
> ene_setup_hw_buffer(dev);
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 5/5] IR: ene_ir: don't upload all settings on each TX packet.
[not found] ` <1287158799-21486-1-git-send-email-maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (3 preceding siblings ...)
2010-10-15 16:06 ` [PATCH 4/5] IR: ene_ir: add support for carrier reports Maxim Levitsky
@ 2010-10-15 16:06 ` Maxim Levitsky
4 siblings, 0 replies; 15+ messages in thread
From: Maxim Levitsky @ 2010-10-15 16:06 UTC (permalink / raw)
To: lirc-list-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Cc: mchehab-wEGCiKHe2LqWVfeAwA7xHQ,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
This is just unnessesary, and now more logical
Also lot of refactoring
Signed-off-by: Maxim Levitsky <maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/media/IR/ene_ir.c | 474 +++++++++++++++++++++++---------------------
drivers/media/IR/ene_ir.h | 6 +-
2 files changed, 251 insertions(+), 229 deletions(-)
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c
index 1962652..685db83 100644
--- a/drivers/media/IR/ene_ir.c
+++ b/drivers/media/IR/ene_ir.c
@@ -43,7 +43,7 @@
#include "ene_ir.h"
static int sample_period;
-static bool learning_mode;
+static bool learning_mode_force;
static int debug;
static bool txsim;
@@ -190,6 +190,145 @@ static int ene_hw_detect(struct ene_device *dev)
return 0;
}
+/* Read properities of hw sample buffer */
+static void ene_rx_setup_hw_buffer(struct ene_device *dev)
+{
+ u16 tmp;
+
+ ene_rx_read_hw_pointer(dev);
+ dev->r_pointer = dev->w_pointer;
+
+ if (!dev->hw_extra_buffer) {
+ dev->buffer_len = ENE_FW_PACKET_SIZE * 2;
+ return;
+ }
+
+ tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER);
+ tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER+1) << 8;
+ dev->extra_buf1_address = tmp;
+
+ dev->extra_buf1_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 2);
+
+ tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 3);
+ tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 4) << 8;
+ dev->extra_buf2_address = tmp;
+
+ dev->extra_buf2_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 5);
+
+ dev->buffer_len = dev->extra_buf1_len + dev->extra_buf2_len + 8;
+
+ ene_notice("Hardware uses 2 extended buffers:");
+ ene_notice(" 0x%04x - len : %d", dev->extra_buf1_address,
+ dev->extra_buf1_len);
+ ene_notice(" 0x%04x - len : %d", dev->extra_buf2_address,
+ dev->extra_buf2_len);
+
+ ene_notice("Total buffer len = %d", dev->buffer_len);
+
+ if (dev->buffer_len > 64 || dev->buffer_len < 16)
+ goto error;
+
+ if (dev->extra_buf1_address > 0xFBFC ||
+ dev->extra_buf1_address < 0xEC00)
+ goto error;
+
+ if (dev->extra_buf2_address > 0xFBFC ||
+ dev->extra_buf2_address < 0xEC00)
+ goto error;
+
+ if (dev->r_pointer > dev->buffer_len)
+ goto error;
+
+ ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
+ return;
+error:
+ ene_warn("Error validating extra buffers, device probably won't work");
+ dev->hw_extra_buffer = false;
+ ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
+}
+
+
+/* Restore the pointers to extra buffers - to make module reload work*/
+static void ene_rx_restore_hw_buffer(struct ene_device *dev)
+{
+ if (!dev->hw_extra_buffer)
+ return;
+
+ ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 0,
+ dev->extra_buf1_address & 0xFF);
+ ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 1,
+ dev->extra_buf1_address >> 8);
+ ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 2, dev->extra_buf1_len);
+
+ ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 3,
+ dev->extra_buf2_address & 0xFF);
+ ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 4,
+ dev->extra_buf2_address >> 8);
+ ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 5,
+ dev->extra_buf2_len);
+ ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
+}
+
+/* Read hardware write pointer */
+static void ene_rx_read_hw_pointer(struct ene_device *dev)
+{
+ if (dev->hw_extra_buffer)
+ dev->w_pointer = ene_read_reg(dev, ENE_FW_RX_POINTER);
+ else
+ dev->w_pointer = ene_read_reg(dev, ENE_FW2)
+ & ENE_FW2_BUF_WPTR ? 0 : ENE_FW_PACKET_SIZE;
+
+ dbg_verbose("RB: HW write pointer: %02x, driver read pointer: %02x",
+ dev->w_pointer, dev->r_pointer);
+}
+
+/* Gets address of next sample from HW ring buffer */
+static int ene_rx_get_sample_reg(struct ene_device *dev)
+{
+ int r_pointer;
+
+ if (dev->r_pointer == dev->w_pointer) {
+ dbg_verbose("RB: hit end, try update w_pointer");
+ ene_rx_read_hw_pointer(dev);
+ }
+
+ if (dev->r_pointer == dev->w_pointer) {
+ dbg_verbose("RB: end of data at %d", dev->r_pointer);
+ return 0;
+ }
+
+ dbg_verbose("RB: reading at offset %d", dev->r_pointer);
+ r_pointer = dev->r_pointer;
+
+ dev->r_pointer++;
+ if (dev->r_pointer == dev->buffer_len)
+ dev->r_pointer = 0;
+
+ dbg_verbose("RB: next read will be from offset %d", dev->r_pointer);
+
+ if (r_pointer < 8) {
+ dbg_verbose("RB: read at main buffer at %d", r_pointer);
+ return ENE_FW_SAMPLE_BUFFER + r_pointer;
+ }
+
+ r_pointer -= 8;
+
+ if (r_pointer < dev->extra_buf1_len) {
+ dbg_verbose("RB: read at 1st extra buffer at %d", r_pointer);
+ return dev->extra_buf1_address + r_pointer;
+ }
+
+ r_pointer -= dev->extra_buf1_len;
+
+ if (r_pointer < dev->extra_buf2_len) {
+ dbg_verbose("RB: read at 2nd extra buffer at %d", r_pointer);
+ return dev->extra_buf2_address + r_pointer;
+ }
+
+ dbg("attempt to read beyong ring bufer end");
+ return 0;
+}
+
/* Sense current received carrier */
void ene_rx_sense_carrier(struct ene_device *dev)
{
@@ -223,14 +362,14 @@ void ene_rx_sense_carrier(struct ene_device *dev)
}
/* this enables/disables the CIR RX engine */
-static void ene_enable_cir_engine(struct ene_device *dev, bool enable)
+static void ene_rx_enable_cir_engine(struct ene_device *dev, bool enable)
{
ene_set_clear_reg_mask(dev, ENE_CIRCFG,
ENE_CIRCFG_RX_EN | ENE_CIRCFG_RX_IRQ, enable);
}
/* this selects input for CIR engine. Ether GPIO 0A or GPIO40*/
-static void ene_select_rx_input(struct ene_device *dev, bool gpio_0a)
+static void ene_rx_select_input(struct ene_device *dev, bool gpio_0a)
{
ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_GPIO0A, gpio_0a);
}
@@ -239,7 +378,7 @@ static void ene_select_rx_input(struct ene_device *dev, bool gpio_0a)
* this enables alternative input via fan tachometer sensor and bypasses
* the hw CIR engine
*/
-static void ene_enable_fan_input(struct ene_device *dev, bool enable)
+static void ene_rx_enable_fan_input(struct ene_device *dev, bool enable)
{
if (!dev->hw_fan_input)
return;
@@ -250,16 +389,18 @@ static void ene_enable_fan_input(struct ene_device *dev, bool enable)
ene_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN);
ene_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN);
}
- dev->rx_fan_input_inuse = enable;
}
/* setup the receiver for RX*/
static void ene_rx_setup(struct ene_device *dev)
{
- bool learning_mode = dev->learning_enabled ||
+ bool learning_mode = dev->learning_mode_enabled ||
dev->carrier_detect_enabled;
int sample_period_adjust = 0;
+ dbg("RX: setup receiver, learning mode = %d", learning_mode);
+
+
/* This selects RLC input and clears CFG2 settings */
ene_write_reg(dev, ENE_CIRCFG2, 0x00);
@@ -284,7 +425,7 @@ static void ene_rx_setup(struct ene_device *dev)
and vice versa.
This input will carry non demodulated
signal, and we will tell the hw to demodulate it itself */
- ene_select_rx_input(dev, !dev->hw_use_gpio_0a);
+ ene_rx_select_input(dev, !dev->hw_use_gpio_0a);
dev->rx_fan_input_inuse = false;
/* Enable carrier demodulation */
@@ -298,7 +439,7 @@ static void ene_rx_setup(struct ene_device *dev)
if (dev->hw_fan_input)
dev->rx_fan_input_inuse = true;
else
- ene_select_rx_input(dev, dev->hw_use_gpio_0a);
+ ene_rx_select_input(dev, dev->hw_use_gpio_0a);
/* Disable carrier detection & demodulation */
ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
@@ -339,7 +480,6 @@ select_timeout:
static void ene_rx_enable(struct ene_device *dev)
{
u8 reg_value;
- dbg("RX: setup receiver, learning mode = %d", learning_mode);
/* Enable system interrupt */
if (dev->hw_revision < ENE_HW_C) {
@@ -354,8 +494,8 @@ static void ene_rx_enable(struct ene_device *dev)
}
/* Enable inputs */
- ene_enable_fan_input(dev, dev->rx_fan_input_inuse);
- ene_enable_cir_engine(dev, !dev->rx_fan_input_inuse);
+ ene_rx_enable_fan_input(dev, dev->rx_fan_input_inuse);
+ ene_rx_enable_cir_engine(dev, !dev->rx_fan_input_inuse);
/* ack any pending irqs - just in case */
ene_irq_status(dev);
@@ -372,8 +512,8 @@ static void ene_rx_enable(struct ene_device *dev)
static void ene_rx_disable(struct ene_device *dev)
{
/* disable inputs */
- ene_enable_cir_engine(dev, false);
- ene_enable_fan_input(dev, false);
+ ene_rx_enable_cir_engine(dev, false);
+ ene_rx_enable_fan_input(dev, false);
/* disable hardware IRQ and firmware flag */
ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
@@ -382,8 +522,60 @@ static void ene_rx_disable(struct ene_device *dev)
dev->rx_enabled = false;
}
+/* This resets the receiver. Usefull to stop stream of spaces at end of
+ * transmission
+ */
+static void ene_rx_reset(struct ene_device *dev)
+{
+ ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
+ ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
+}
+
+/* Set up the TX carrier frequency and duty cycle */
+static void ene_tx_set_carrier(struct ene_device *dev)
+{
+ u8 tx_puls_width;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->hw_lock, flags);
+
+ ene_set_clear_reg_mask(dev, ENE_CIRCFG,
+ ENE_CIRCFG_TX_CARR, dev->tx_period > 0);
+
+ if (!dev->tx_period)
+ goto unlock;
+
+ BUG_ON(dev->tx_duty_cycle >= 100 || dev->tx_duty_cycle <= 0);
+
+ tx_puls_width = dev->tx_period / (100 / dev->tx_duty_cycle);
+
+ if (!tx_puls_width)
+ tx_puls_width = 1;
+
+ dbg("TX: pulse distance = %d * 500 ns", dev->tx_period);
+ dbg("TX: pulse width = %d * 500 ns", tx_puls_width);
+
+ ene_write_reg(dev, ENE_CIRMOD_PRD, dev->tx_period | ENE_CIRMOD_PRD_POL);
+ ene_write_reg(dev, ENE_CIRMOD_HPRD, tx_puls_width);
+unlock:
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
+}
+
+/* Enable/disable transmitters */
+static void ene_tx_set_transmitters(struct ene_device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ ene_set_clear_reg_mask(dev, ENE_GPIOFS8, ENE_GPIOFS8_GPIO41,
+ !!(dev->transmitter_mask & 0x01));
+ ene_set_clear_reg_mask(dev, ENE_GPIOFS1, ENE_GPIOFS1_GPIO0D,
+ !!(dev->transmitter_mask & 0x02));
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
+}
+
/* prepare transmission */
-static void ene_tx_prepare(struct ene_device *dev)
+static void ene_tx_enable(struct ene_device *dev)
{
u8 conf1 = ene_read_reg(dev, ENE_CIRCFG);
u8 fwreg2 = ene_read_reg(dev, ENE_FW2);
@@ -400,32 +592,6 @@ static void ene_tx_prepare(struct ene_device *dev)
if (!(fwreg2 & (ENE_FW2_EMMITER1_CONN | ENE_FW2_EMMITER2_CONN)))
ene_warn("TX: transmitter cable isn't connected!");
- /* Set transmitter mask */
- ene_set_clear_reg_mask(dev, ENE_GPIOFS8, ENE_GPIOFS8_GPIO41,
- !!(dev->transmitter_mask & 0x01));
- ene_set_clear_reg_mask(dev, ENE_GPIOFS1, ENE_GPIOFS1_GPIO0D,
- !!(dev->transmitter_mask & 0x02));
-
- /* Set the carrier period && duty cycle */
- if (dev->tx_period) {
-
- int tx_puls_width = dev->tx_period / (100 / dev->tx_duty_cycle);
-
- if (!tx_puls_width)
- tx_puls_width = 1;
-
- dbg("TX: pulse distance = %d * 500 ns", dev->tx_period);
- dbg("TX: pulse width = %d * 500 ns", tx_puls_width);
-
- ene_write_reg(dev, ENE_CIRMOD_PRD, ENE_CIRMOD_PRD_POL |
- dev->tx_period);
-
- ene_write_reg(dev, ENE_CIRMOD_HPRD, tx_puls_width);
-
- conf1 |= ENE_CIRCFG_TX_CARR;
- } else
- conf1 &= ~ENE_CIRCFG_TX_CARR;
-
/* disable receive on revc */
if (dev->hw_revision == ENE_HW_C)
conf1 &= ~ENE_CIRCFG_RX_EN;
@@ -436,7 +602,7 @@ static void ene_tx_prepare(struct ene_device *dev)
}
/* end transmission */
-static void ene_tx_complete(struct ene_device *dev)
+static void ene_tx_disable(struct ene_device *dev)
{
ene_write_reg(dev, ENE_CIRCFG, dev->saved_conf1);
dev->tx_buffer = NULL;
@@ -465,7 +631,7 @@ static void ene_tx_sample(struct ene_device *dev)
goto exit;
} else {
dbg("TX: last sample sent by hardware");
- ene_tx_complete(dev);
+ ene_tx_disable(dev);
complete(&dev->tx_complete);
return;
}
@@ -509,85 +675,6 @@ static void ene_tx_irqsim(unsigned long data)
spin_unlock_irqrestore(&dev->hw_lock, flags);
}
-/* Read properities of hw sample buffer */
-static void ene_setup_hw_buffer(struct ene_device *dev)
-{
- u16 tmp;
-
- ene_read_hw_pointer(dev);
- dev->r_pointer = dev->w_pointer;
-
- if (!dev->hw_extra_buffer) {
- dev->buffer_len = ENE_FW_PACKET_SIZE * 2;
- return;
- }
-
- tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER);
- tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER+1) << 8;
- dev->extra_buf1_address = tmp;
-
- dev->extra_buf1_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 2);
-
- tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 3);
- tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 4) << 8;
- dev->extra_buf2_address = tmp;
-
- dev->extra_buf2_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 5);
-
- dev->buffer_len = dev->extra_buf1_len + dev->extra_buf2_len + 8;
-
- ene_notice("Hardware uses 2 extended buffers:");
- ene_notice(" 0x%04x - len : %d", dev->extra_buf1_address,
- dev->extra_buf1_len);
- ene_notice(" 0x%04x - len : %d", dev->extra_buf2_address,
- dev->extra_buf2_len);
-
- ene_notice("Total buffer len = %d", dev->buffer_len);
-
- if (dev->buffer_len > 64 || dev->buffer_len < 16)
- goto error;
-
- if (dev->extra_buf1_address > 0xFBFC ||
- dev->extra_buf1_address < 0xEC00)
- goto error;
-
- if (dev->extra_buf2_address > 0xFBFC ||
- dev->extra_buf2_address < 0xEC00)
- goto error;
-
- if (dev->r_pointer > dev->buffer_len)
- goto error;
-
- ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
- return;
-error:
- ene_warn("Error validating extra buffers, device probably won't work");
- dev->hw_extra_buffer = false;
- ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
-}
-
-
-/* Restore the pointers to extra buffers - to make module reload work*/
-static void ene_restore_extra_buffer(struct ene_device *dev)
-{
- if (!dev->hw_extra_buffer)
- return;
-
- ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 0,
- dev->extra_buf1_address & 0xFF);
- ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 1,
- dev->extra_buf1_address >> 8);
- ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 2, dev->extra_buf1_len);
-
- ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 3,
- dev->extra_buf2_address & 0xFF);
- ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 4,
- dev->extra_buf2_address >> 8);
- ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 5,
- dev->extra_buf2_len);
- ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
-}
-
/* read irq status and ack it */
static int ene_irq_status(struct ene_device *dev)
@@ -632,66 +719,6 @@ static int ene_irq_status(struct ene_device *dev)
return retval;
}
-/* Read hardware write pointer */
-static void ene_read_hw_pointer(struct ene_device *dev)
-{
- if (dev->hw_extra_buffer)
- dev->w_pointer = ene_read_reg(dev, ENE_FW_RX_POINTER);
- else
- dev->w_pointer = ene_read_reg(dev, ENE_FW2)
- & ENE_FW2_BUF_WPTR ? 0 : ENE_FW_PACKET_SIZE;
-
- dbg_verbose("RB: HW write pointer: %02x, driver read pointer: %02x",
- dev->w_pointer, dev->r_pointer);
-}
-
-/* Gets address of next sample from HW ring buffer */
-static int ene_get_sample_reg(struct ene_device *dev)
-{
- int r_pointer;
-
- if (dev->r_pointer == dev->w_pointer) {
- dbg_verbose("RB: hit end, try update w_pointer");
- ene_read_hw_pointer(dev);
- }
-
- if (dev->r_pointer == dev->w_pointer) {
- dbg_verbose("RB: end of data at %d", dev->r_pointer);
- return 0;
- }
-
- dbg_verbose("RB: reading at offset %d", dev->r_pointer);
- r_pointer = dev->r_pointer;
-
- dev->r_pointer++;
- if (dev->r_pointer == dev->buffer_len)
- dev->r_pointer = 0;
-
- dbg_verbose("RB: next read will be from offset %d", dev->r_pointer);
-
- if (r_pointer < 8) {
- dbg_verbose("RB: read at main buffer at %d", r_pointer);
- return ENE_FW_SAMPLE_BUFFER + r_pointer;
- }
-
- r_pointer -= 8;
-
- if (r_pointer < dev->extra_buf1_len) {
- dbg_verbose("RB: read at 1st extra buffer at %d", r_pointer);
- return dev->extra_buf1_address + r_pointer;
- }
-
- r_pointer -= dev->extra_buf1_len;
-
- if (r_pointer < dev->extra_buf2_len) {
- dbg_verbose("RB: read at 2nd extra buffer at %d", r_pointer);
- return dev->extra_buf2_address + r_pointer;
- }
-
- dbg("attempt to read beyong ring bufer end");
- return 0;
-}
-
/* interrupt handler */
static irqreturn_t ene_isr(int irq, void *data)
{
@@ -706,7 +733,7 @@ static irqreturn_t ene_isr(int irq, void *data)
spin_lock_irqsave(&dev->hw_lock, flags);
dbg_verbose("ISR called");
- ene_read_hw_pointer(dev);
+ ene_rx_read_hw_pointer(dev);
irq_status = ene_irq_status(dev);
if (!irq_status)
@@ -738,7 +765,7 @@ static irqreturn_t ene_isr(int irq, void *data)
while (1) {
- reg = ene_get_sample_reg(dev);
+ reg = ene_rx_get_sample_reg(dev);
dbg_verbose("next sample to read at: %04x", reg);
if (!reg)
@@ -788,17 +815,28 @@ unlock:
}
/* Initialize default settings */
-static void ene_setup_settings(struct ene_device *dev)
+static void ene_setup_default_settings(struct ene_device *dev)
{
dev->tx_period = 32;
dev->tx_duty_cycle = 50; /*%*/
dev->transmitter_mask = 0x03;
- dev->learning_enabled = learning_mode;
+ dev->learning_mode_enabled = learning_mode_force;
/* Set reasonable default timeout */
dev->props->timeout = MS_TO_NS(150000);
}
+/* Upload all hardware settings at once. Used at load and resume time */
+static void ene_setup_hw_settings(struct ene_device *dev)
+{
+ if (dev->hw_learning_and_tx_capable) {
+ ene_tx_set_carrier(dev);
+ ene_tx_set_transmitters(dev);
+ }
+
+ ene_rx_setup(dev);
+}
+
/* outside interface: called on first open*/
static int ene_open(void *data)
{
@@ -826,7 +864,6 @@ static void ene_close(void *data)
static int ene_set_tx_mask(void *data, u32 tx_mask)
{
struct ene_device *dev = (struct ene_device *)data;
- unsigned long flags;
dbg("TX: attempt to set transmitter mask %02x", tx_mask);
/* invalid txmask */
@@ -836,9 +873,8 @@ static int ene_set_tx_mask(void *data, u32 tx_mask)
return 2;
}
- spin_lock_irqsave(&dev->hw_lock, flags);
dev->transmitter_mask = tx_mask;
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ ene_tx_set_transmitters(dev);
return 0;
}
@@ -846,7 +882,6 @@ static int ene_set_tx_mask(void *data, u32 tx_mask)
static int ene_set_tx_carrier(void *data, u32 carrier)
{
struct ene_device *dev = (struct ene_device *)data;
- unsigned long flags;
u32 period = 2000000 / carrier;
dbg("TX: attempt to set tx carrier to %d kHz", carrier);
@@ -855,16 +890,12 @@ static int ene_set_tx_carrier(void *data, u32 carrier)
period < ENE_CIRMOD_PRD_MIN)) {
dbg("TX: out of range %d-%d kHz carrier",
- 2000 / ENE_CIRMOD_PRD_MIN,
- 2000 / ENE_CIRMOD_PRD_MAX);
-
+ 2000 / ENE_CIRMOD_PRD_MIN, 2000 / ENE_CIRMOD_PRD_MAX);
return -1;
}
- dbg("TX: set carrier to %d kHz", carrier);
- spin_lock_irqsave(&dev->hw_lock, flags);
dev->tx_period = period;
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ ene_tx_set_carrier(dev);
return 0;
}
@@ -872,15 +903,9 @@ static int ene_set_tx_carrier(void *data, u32 carrier)
static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
{
struct ene_device *dev = (struct ene_device *)data;
- unsigned long flags;
-
dbg("TX: setting duty cycle to %d%%", duty_cycle);
-
- BUG_ON(!duty_cycle || duty_cycle >= 100);
-
- spin_lock_irqsave(&dev->hw_lock, flags);
dev->tx_duty_cycle = duty_cycle;
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ ene_tx_set_carrier(dev);
return 0;
}
@@ -889,11 +914,11 @@ static int ene_set_learning_mode(void *data, int enable)
{
struct ene_device *dev = (struct ene_device *)data;
unsigned long flags;
- if (enable == dev->learning_enabled)
+ if (enable == dev->learning_mode_enabled)
return 0;
spin_lock_irqsave(&dev->hw_lock, flags);
- dev->learning_enabled = enable;
+ dev->learning_mode_enabled = enable;
ene_rx_disable(dev);
ene_rx_setup(dev);
ene_rx_enable(dev);
@@ -919,16 +944,12 @@ static int ene_set_carrier_report(void *data, int enable)
}
/* outside interface: enable or disable idle mode */
-static void ene_rx_set_idle(void *data, bool idle)
+static void ene_set_idle(void *data, bool idle)
{
- struct ene_device *dev = (struct ene_device *)data;
-
- if (!idle)
- return;
-
- dbg("RX: stopping the receiver");
- ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
- ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
+ if (idle) {
+ ene_rx_reset((struct ene_device *)data);
+ dbg("RX: end of data");
+ }
}
/* outside interface: transmit */
@@ -949,7 +970,7 @@ static int ene_transmit(void *data, int *buf, u32 n)
spin_lock_irqsave(&dev->hw_lock, flags);
- ene_tx_prepare(dev);
+ ene_tx_enable(dev);
/* Transmit first two samples */
ene_tx_sample(dev);
@@ -960,7 +981,7 @@ static int ene_transmit(void *data, int *buf, u32 n)
if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) {
dbg("TX: timeout");
spin_lock_irqsave(&dev->hw_lock, flags);
- ene_tx_complete(dev);
+ ene_tx_disable(dev);
spin_unlock_irqrestore(&dev->hw_lock, flags);
} else
dbg("TX: done");
@@ -1031,14 +1052,14 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
}
if (!dev->hw_learning_and_tx_capable)
- learning_mode = false;
+ learning_mode_force = false;
ir_props->driver_type = RC_DRIVER_IR_RAW;
ir_props->allowed_protos = IR_TYPE_ALL;
ir_props->priv = dev;
ir_props->open = ene_open;
ir_props->close = ene_close;
- ir_props->s_idle = ene_rx_set_idle;
+ ir_props->s_idle = ene_set_idle;
dev->props = ir_props;
dev->idev = input_dev;
@@ -1053,9 +1074,9 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
ir_props->s_carrier_report = ene_set_carrier_report;
}
- ene_setup_hw_buffer(dev);
- ene_setup_settings(dev);
- ene_rx_setup(dev);
+ ene_rx_setup_hw_buffer(dev);
+ ene_setup_default_settings(dev);
+ ene_setup_hw_settings(dev);
device_set_wakeup_capable(&pnp_dev->dev, true);
device_set_wakeup_enable(&pnp_dev->dev, true);
@@ -1092,7 +1113,7 @@ static void ene_remove(struct pnp_dev *pnp_dev)
spin_lock_irqsave(&dev->hw_lock, flags);
ene_rx_disable(dev);
- ene_restore_extra_buffer(dev);
+ ene_rx_restore_hw_buffer(dev);
spin_unlock_irqrestore(&dev->hw_lock, flags);
free_irq(dev->irq, dev);
@@ -1123,10 +1144,11 @@ static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
static int ene_resume(struct pnp_dev *pnp_dev)
{
struct ene_device *dev = pnp_get_drvdata(pnp_dev);
- if (dev->rx_enabled) {
- ene_rx_setup(dev);
+ ene_setup_hw_settings(dev);
+
+ if (dev->rx_enabled)
ene_rx_enable(dev);
- }
+
ene_enable_wake(dev, false);
return 0;
}
@@ -1173,8 +1195,8 @@ static void ene_exit(void)
module_param(sample_period, int, S_IRUGO);
MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)");
-module_param(learning_mode, bool, S_IRUGO);
-MODULE_PARM_DESC(learning_mode, "Enable learning mode by default");
+module_param(learning_mode_force, bool, S_IRUGO);
+MODULE_PARM_DESC(learning_mode_force, "Enable learning mode by default");
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level");
diff --git a/drivers/media/IR/ene_ir.h b/drivers/media/IR/ene_ir.h
index 39c707b..f587066 100644
--- a/drivers/media/IR/ene_ir.h
+++ b/drivers/media/IR/ene_ir.h
@@ -215,7 +215,7 @@ struct ene_device {
/* HW features */
int hw_revision; /* hardware revision */
- bool hw_use_gpio_0a; /* gpio40 is demodulated input*/
+ bool hw_use_gpio_0a; /* gpio0a is demodulated input*/
bool hw_extra_buffer; /* hardware has 'extra buffer' */
bool hw_fan_input; /* fan input is IR data source */
bool hw_learning_and_tx_capable; /* learning & tx capable */
@@ -252,11 +252,11 @@ struct ene_device {
int transmitter_mask;
/* RX settings */
- bool learning_enabled; /* learning input enabled */
+ bool learning_mode_enabled; /* learning input enabled */
bool carrier_detect_enabled; /* carrier detect enabled */
int rx_period_adjust;
bool rx_enabled;
};
static int ene_irq_status(struct ene_device *dev);
-static void ene_read_hw_pointer(struct ene_device *dev);
+static void ene_rx_read_hw_pointer(struct ene_device *dev);
--
1.7.1
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
^ permalink raw reply related [flat|nested] 15+ messages in thread