aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2010-07-31 10:59:23 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-08 22:43:00 -0400
commite589333f346b58f8da5bb8152e1219c52d375ccc (patch)
tree4ff05f4f9c5a06c532084ed46b3612ebeec1e21c
parent4a702ebf61120906696f8366dd2be0653b1643e3 (diff)
V4L/DVB: IR: extend interfaces to support more device settings
LIRC: add new IOCTL that enables learning mode (wide band receiver) Still missing features: carrier report & timeout reports. Will need to pack these into ir_raw_event Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--Documentation/DocBook/v4l/lirc_device_interface.xml16
-rw-r--r--drivers/media/IR/ir-core-priv.h1
-rw-r--r--drivers/media/IR/ir-lirc-codec.c112
-rw-r--r--include/media/ir-core.h12
-rw-r--r--include/media/lirc.h5
5 files changed, 125 insertions, 21 deletions
diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml b/Documentation/DocBook/v4l/lirc_device_interface.xml
index 0413234023d4..68134c0ab4d1 100644
--- a/Documentation/DocBook/v4l/lirc_device_interface.xml
+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml
@@ -229,6 +229,22 @@ on working with the default settings initially.</para>
229 and LIRC_SETUP_END. Drivers can also choose to ignore these ioctls.</para> 229 and LIRC_SETUP_END. Drivers can also choose to ignore these ioctls.</para>
230 </listitem> 230 </listitem>
231 </varlistentry> 231 </varlistentry>
232 <varlistentry>
233 <term>LIRC_SET_WIDEBAND_RECEIVER</term>
234 <listitem>
235 <para>Some receivers are equipped with special wide band receiver which is intended
236 to be used to learn output of existing remote.
237 Calling that ioctl with (1) will enable it, and with (0) disable it.
238 This might be useful of receivers that have otherwise narrow band receiver
239 that prevents them to be used with some remotes.
240 Wide band receiver might also be more precise
241 On the other hand its disadvantage it usually reduced range of reception.
242 Note: wide band receiver might be implictly enabled if you enable
243 carrier reports. In that case it will be disabled as soon as you disable
244 carrier reports. Trying to disable wide band receiver while carrier
245 reports are active will do nothing.</para>
246 </listitem>
247 </varlistentry>
232</variablelist> 248</variablelist>
233 249
234</section> 250</section>
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index 8053e3b84272..a85a8c7c905a 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -79,6 +79,7 @@ struct ir_raw_event_ctrl {
79 struct lirc_codec { 79 struct lirc_codec {
80 struct ir_input_dev *ir_dev; 80 struct ir_input_dev *ir_dev;
81 struct lirc_driver *drv; 81 struct lirc_driver *drv;
82 int carrier_low;
82 } lirc; 83 } lirc;
83}; 84};
84 85
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
index 8ca01fd67139..77b5946413c0 100644
--- a/drivers/media/IR/ir-lirc-codec.c
+++ b/drivers/media/IR/ir-lirc-codec.c
@@ -46,7 +46,6 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
46 IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", 46 IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
47 TO_US(ev.duration), TO_STR(ev.pulse)); 47 TO_US(ev.duration), TO_STR(ev.pulse));
48 48
49
50 sample = ev.duration / 1000; 49 sample = ev.duration / 1000;
51 if (ev.pulse) 50 if (ev.pulse)
52 sample |= PULSE_BIT; 51 sample |= PULSE_BIT;
@@ -96,13 +95,14 @@ out:
96 return ret; 95 return ret;
97} 96}
98 97
99static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) 98static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
99 unsigned long __user arg)
100{ 100{
101 struct lirc_codec *lirc; 101 struct lirc_codec *lirc;
102 struct ir_input_dev *ir_dev; 102 struct ir_input_dev *ir_dev;
103 int ret = 0; 103 int ret = 0;
104 void *drv_data; 104 void *drv_data;
105 unsigned long val; 105 unsigned long val = 0;
106 106
107 lirc = lirc_get_pdata(filep); 107 lirc = lirc_get_pdata(filep);
108 if (!lirc) 108 if (!lirc)
@@ -114,47 +114,106 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long ar
114 114
115 drv_data = ir_dev->props->priv; 115 drv_data = ir_dev->props->priv;
116 116
117 switch (cmd) { 117 if (_IOC_DIR(cmd) & _IOC_WRITE) {
118 case LIRC_SET_TRANSMITTER_MASK:
119 ret = get_user(val, (unsigned long *)arg); 118 ret = get_user(val, (unsigned long *)arg);
120 if (ret) 119 if (ret)
121 return ret; 120 return ret;
121 }
122
123 switch (cmd) {
124
125 /* legacy support */
126 case LIRC_GET_SEND_MODE:
127 val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
128 break;
129
130 case LIRC_SET_SEND_MODE:
131 if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
132 return -EINVAL;
133 break;
122 134
123 if (ir_dev->props && ir_dev->props->s_tx_mask) 135 /* TX settings */
136 case LIRC_SET_TRANSMITTER_MASK:
137 if (ir_dev->props->s_tx_mask)
124 ret = ir_dev->props->s_tx_mask(drv_data, (u32)val); 138 ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
125 else 139 else
126 return -EINVAL; 140 return -EINVAL;
127 break; 141 break;
128 142
129 case LIRC_SET_SEND_CARRIER: 143 case LIRC_SET_SEND_CARRIER:
130 ret = get_user(val, (unsigned long *)arg); 144 if (ir_dev->props->s_tx_carrier)
131 if (ret)
132 return ret;
133
134 if (ir_dev->props && ir_dev->props->s_tx_carrier)
135 ir_dev->props->s_tx_carrier(drv_data, (u32)val); 145 ir_dev->props->s_tx_carrier(drv_data, (u32)val);
136 else 146 else
137 return -EINVAL; 147 return -EINVAL;
138 break; 148 break;
139 149
140 case LIRC_GET_SEND_MODE: 150 case LIRC_SET_SEND_DUTY_CYCLE:
141 val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK; 151 if (!ir_dev->props->s_tx_duty_cycle)
142 ret = put_user(val, (unsigned long *)arg); 152 return -ENOSYS;
153
154 if (val <= 0 || val >= 100)
155 return -EINVAL;
156
157 ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val);
143 break; 158 break;
144 159
145 case LIRC_SET_SEND_MODE: 160 /* RX settings */
146 ret = get_user(val, (unsigned long *)arg); 161 case LIRC_SET_REC_CARRIER:
147 if (ret) 162 if (ir_dev->props->s_rx_carrier_range)
148 return ret; 163 ret = ir_dev->props->s_rx_carrier_range(
164 ir_dev->props->priv,
165 ir_dev->raw->lirc.carrier_low, val);
166 else
167 return -ENOSYS;
149 168
150 if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) 169 if (!ret)
170 ir_dev->raw->lirc.carrier_low = 0;
171 break;
172
173 case LIRC_SET_REC_CARRIER_RANGE:
174 if (val >= 0)
175 ir_dev->raw->lirc.carrier_low = val;
176 break;
177
178
179 case LIRC_GET_REC_RESOLUTION:
180 val = ir_dev->props->rx_resolution;
181 break;
182
183 case LIRC_SET_WIDEBAND_RECEIVER:
184 if (ir_dev->props->s_learning_mode)
185 return ir_dev->props->s_learning_mode(
186 ir_dev->props->priv, !!val);
187 else
188 return -ENOSYS;
189
190 /* Generic timeout support */
191 case LIRC_GET_MIN_TIMEOUT:
192 if (!ir_dev->props->max_timeout)
193 return -ENOSYS;
194 val = ir_dev->props->min_timeout / 1000;
195 break;
196
197 case LIRC_GET_MAX_TIMEOUT:
198 if (!ir_dev->props->max_timeout)
199 return -ENOSYS;
200 val = ir_dev->props->max_timeout / 1000;
201 break;
202
203 case LIRC_SET_REC_TIMEOUT:
204 if (val < ir_dev->props->min_timeout ||
205 val > ir_dev->props->max_timeout)
151 return -EINVAL; 206 return -EINVAL;
207 ir_dev->props->timeout = val * 1000;
152 break; 208 break;
153 209
154 default: 210 default:
155 return lirc_dev_fop_ioctl(filep, cmd, arg); 211 return lirc_dev_fop_ioctl(filep, cmd, arg);
156 } 212 }
157 213
214 if (_IOC_DIR(cmd) & _IOC_READ)
215 ret = put_user(val, (unsigned long *)arg);
216
158 return ret; 217 return ret;
159} 218}
160 219
@@ -200,13 +259,28 @@ static int ir_lirc_register(struct input_dev *input_dev)
200 259
201 features = LIRC_CAN_REC_MODE2; 260 features = LIRC_CAN_REC_MODE2;
202 if (ir_dev->props->tx_ir) { 261 if (ir_dev->props->tx_ir) {
262
203 features |= LIRC_CAN_SEND_PULSE; 263 features |= LIRC_CAN_SEND_PULSE;
204 if (ir_dev->props->s_tx_mask) 264 if (ir_dev->props->s_tx_mask)
205 features |= LIRC_CAN_SET_TRANSMITTER_MASK; 265 features |= LIRC_CAN_SET_TRANSMITTER_MASK;
206 if (ir_dev->props->s_tx_carrier) 266 if (ir_dev->props->s_tx_carrier)
207 features |= LIRC_CAN_SET_SEND_CARRIER; 267 features |= LIRC_CAN_SET_SEND_CARRIER;
268
269 if (ir_dev->props->s_tx_duty_cycle)
270 features |= LIRC_CAN_SET_REC_DUTY_CYCLE;
208 } 271 }
209 272
273 if (ir_dev->props->s_rx_carrier_range)
274 features |= LIRC_CAN_SET_REC_CARRIER |
275 LIRC_CAN_SET_REC_CARRIER_RANGE;
276
277 if (ir_dev->props->s_learning_mode)
278 features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
279
280 if (ir_dev->props->max_timeout)
281 features |= LIRC_CAN_SET_REC_TIMEOUT;
282
283
210 snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", 284 snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
211 ir_dev->driver_name); 285 ir_dev->driver_name);
212 drv->minor = -1; 286 drv->minor = -1;
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index a781045aeed5..eb7fddf8f607 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -44,6 +44,8 @@ enum rc_driver_type {
44 * @timeout: optional time after which device stops sending data 44 * @timeout: optional time after which device stops sending data
45 * @min_timeout: minimum timeout supported by device 45 * @min_timeout: minimum timeout supported by device
46 * @max_timeout: maximum timeout supported by device 46 * @max_timeout: maximum timeout supported by device
47 * @rx_resolution : resolution (in ns) of input sampler
48 * @tx_resolution: resolution (in ns) of output sampler
47 * @priv: driver-specific data, to be used on the callbacks 49 * @priv: driver-specific data, to be used on the callbacks
48 * @change_protocol: allow changing the protocol used on hardware decoders 50 * @change_protocol: allow changing the protocol used on hardware decoders
49 * @open: callback to allow drivers to enable polling/irq when IR input device 51 * @open: callback to allow drivers to enable polling/irq when IR input device
@@ -52,9 +54,12 @@ enum rc_driver_type {
52 * is opened. 54 * is opened.
53 * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs) 55 * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
54 * @s_tx_carrier: set transmit carrier frequency 56 * @s_tx_carrier: set transmit carrier frequency
57 * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
58 * @s_rx_carrier: inform driver about carrier it is expected to handle
55 * @tx_ir: transmit IR 59 * @tx_ir: transmit IR
56 * @s_idle: optional: enable/disable hardware idle mode, upon which, 60 * @s_idle: optional: enable/disable hardware idle mode, upon which,
57 * device doesn't interrupt host untill it sees IR data 61 device doesn't interrupt host until it sees IR pulses
62 * @s_learning_mode: enable wide band receiver used for learning
58 */ 63 */
59struct ir_dev_props { 64struct ir_dev_props {
60 enum rc_driver_type driver_type; 65 enum rc_driver_type driver_type;
@@ -65,6 +70,8 @@ struct ir_dev_props {
65 u32 min_timeout; 70 u32 min_timeout;
66 u32 max_timeout; 71 u32 max_timeout;
67 72
73 u32 rx_resolution;
74 u32 tx_resolution;
68 75
69 void *priv; 76 void *priv;
70 int (*change_protocol)(void *priv, u64 ir_type); 77 int (*change_protocol)(void *priv, u64 ir_type);
@@ -72,8 +79,11 @@ struct ir_dev_props {
72 void (*close)(void *priv); 79 void (*close)(void *priv);
73 int (*s_tx_mask)(void *priv, u32 mask); 80 int (*s_tx_mask)(void *priv, u32 mask);
74 int (*s_tx_carrier)(void *priv, u32 carrier); 81 int (*s_tx_carrier)(void *priv, u32 carrier);
82 int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle);
83 int (*s_rx_carrier_range)(void *priv, u32 min, u32 max);
75 int (*tx_ir)(void *priv, int *txbuf, u32 n); 84 int (*tx_ir)(void *priv, int *txbuf, u32 n);
76 void (*s_idle)(void *priv, int enable); 85 void (*s_idle)(void *priv, int enable);
86 int (*s_learning_mode)(void *priv, int enable);
77}; 87};
78 88
79struct ir_input_dev { 89struct ir_input_dev {
diff --git a/include/media/lirc.h b/include/media/lirc.h
index 42c467c50519..6678a169fd9e 100644
--- a/include/media/lirc.h
+++ b/include/media/lirc.h
@@ -77,6 +77,7 @@
77#define LIRC_CAN_SET_REC_FILTER 0x08000000 77#define LIRC_CAN_SET_REC_FILTER 0x08000000
78 78
79#define LIRC_CAN_MEASURE_CARRIER 0x02000000 79#define LIRC_CAN_MEASURE_CARRIER 0x02000000
80#define LIRC_CAN_USE_WIDEBAND_RECEIVER 0x04000000
80 81
81#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) 82#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
82#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) 83#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
@@ -145,7 +146,7 @@
145 * if enabled from the next key press on the driver will send 146 * if enabled from the next key press on the driver will send
146 * LIRC_MODE2_FREQUENCY packets 147 * LIRC_MODE2_FREQUENCY packets
147 */ 148 */
148#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32) 149#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32)
149 150
150/* 151/*
151 * to set a range use 152 * to set a range use
@@ -162,4 +163,6 @@
162#define LIRC_SETUP_START _IO('i', 0x00000021) 163#define LIRC_SETUP_START _IO('i', 0x00000021)
163#define LIRC_SETUP_END _IO('i', 0x00000022) 164#define LIRC_SETUP_END _IO('i', 0x00000022)
164 165
166#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32)
167
165#endif 168#endif