diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2010-07-31 10:59:26 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-08 22:43:00 -0400 |
commit | 931e39a13924f528754f07555689f77588e97763 (patch) | |
tree | bafac7e61db751e365a40af225eea91b74782528 /drivers/media | |
parent | 9ea53b74df9c4681f5bb2da6b2e10e37d87ea6d6 (diff) |
V4L/DVB: IR: Port ene driver to new IR subsystem and enable it
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/IR/Kconfig | 14 | ||||
-rw-r--r-- | drivers/media/IR/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/IR/ene_ir.c | 595 | ||||
-rw-r--r-- | drivers/media/IR/ene_ir.h | 49 |
4 files changed, 258 insertions, 401 deletions
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index 9e8f82d85cb3..30e04915a256 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig | |||
@@ -106,6 +106,20 @@ config IR_MCEUSB | |||
106 | To compile this driver as a module, choose M here: the | 106 | To compile this driver as a module, choose M here: the |
107 | module will be called mceusb. | 107 | module will be called mceusb. |
108 | 108 | ||
109 | config IR_ENE | ||
110 | tristate "ENE eHome Receiver/Transciever (pnp id: ENE0100/ENE02xxx)" | ||
111 | depends on PNP | ||
112 | depends on IR_CORE | ||
113 | ---help--- | ||
114 | Say Y here to enable support for integrated infrared receiver | ||
115 | /transciever made by ENE. | ||
116 | |||
117 | You can see if you have it by looking at lspnp output. | ||
118 | Output should include ENE0100 ENE0200 or something similiar. | ||
119 | |||
120 | To compile this driver as a module, choose M here: the | ||
121 | module will be called ene_ir. | ||
122 | |||
109 | config IR_STREAMZAP | 123 | config IR_STREAMZAP |
110 | tristate "Streamzap PC Remote IR Receiver" | 124 | tristate "Streamzap PC Remote IR Receiver" |
111 | depends on USB_ARCH_HAS_HCD | 125 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index 2566fb4f356e..53676838fe97 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile | |||
@@ -16,4 +16,5 @@ obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o | |||
16 | # stand-alone IR receivers/transmitters | 16 | # stand-alone IR receivers/transmitters |
17 | obj-$(CONFIG_IR_IMON) += imon.o | 17 | obj-$(CONFIG_IR_IMON) += imon.o |
18 | obj-$(CONFIG_IR_MCEUSB) += mceusb.o | 18 | obj-$(CONFIG_IR_MCEUSB) += mceusb.o |
19 | obj-$(CONFIG_IR_ENE) += ene_ir.o | ||
19 | obj-$(CONFIG_IR_STREAMZAP) += streamzap.o | 20 | obj-$(CONFIG_IR_STREAMZAP) += streamzap.o |
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c index 9d11caf55b03..5447750f5e38 100644 --- a/drivers/media/IR/ene_ir.c +++ b/drivers/media/IR/ene_ir.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * driver for ENE KB3926 B/C/D CIR (also known as ENE0100/ENE0200/ENE0201) | 2 | * driver for ENE KB3926 B/C/D CIR (pnp id: ENE0XXX) |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> | 4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> |
5 | * | 5 | * |
@@ -25,20 +25,20 @@ | |||
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/uaccess.h> | 28 | #include <linux/slab.h> |
29 | #include "lirc_ene0100.h" | 29 | #include <linux/input.h> |
30 | #include <media/ir-core.h> | ||
31 | #include <media/ir-common.h> | ||
32 | #include "ene_ir.h" | ||
30 | 33 | ||
31 | 34 | ||
32 | static int sample_period = -1; | 35 | static int sample_period = -1; |
33 | static int enable_idle = 1; | 36 | static int enable_idle = 1; |
34 | static int enable_duty_carrier; | ||
35 | static int input = 1; | 37 | static int input = 1; |
36 | static int debug; | 38 | static int debug; |
37 | static int txsim; | 39 | static int txsim; |
38 | 40 | ||
39 | static void ene_rx_set_idle(struct ene_device *dev, int idle); | ||
40 | static int ene_irq_status(struct ene_device *dev); | 41 | static int ene_irq_status(struct ene_device *dev); |
41 | static void ene_send_sample(struct ene_device *dev, unsigned long sample); | ||
42 | 42 | ||
43 | /* read a hardware register */ | 43 | /* read a hardware register */ |
44 | static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg) | 44 | static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg) |
@@ -85,6 +85,7 @@ static int ene_hw_detect(struct ene_device *dev) | |||
85 | u8 hw_revision, old_ver; | 85 | u8 hw_revision, old_ver; |
86 | u8 tmp; | 86 | u8 tmp; |
87 | u8 fw_capabilities; | 87 | u8 fw_capabilities; |
88 | int pll_freq; | ||
88 | 89 | ||
89 | tmp = ene_hw_read_reg(dev, ENE_HW_UNK); | 90 | tmp = ene_hw_read_reg(dev, ENE_HW_UNK); |
90 | ene_hw_write_reg(dev, ENE_HW_UNK, tmp & ~ENE_HW_UNK_CLR); | 91 | ene_hw_write_reg(dev, ENE_HW_UNK, tmp & ~ENE_HW_UNK_CLR); |
@@ -96,6 +97,17 @@ static int ene_hw_detect(struct ene_device *dev) | |||
96 | hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); | 97 | hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); |
97 | old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); | 98 | old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); |
98 | 99 | ||
100 | pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) << 4) + | ||
101 | (ene_hw_read_reg(dev, ENE_PLLFRL) >> 4); | ||
102 | |||
103 | if (pll_freq != 1000) | ||
104 | dev->rx_period_adjust = 4; | ||
105 | else | ||
106 | dev->rx_period_adjust = 2; | ||
107 | |||
108 | |||
109 | ene_printk(KERN_NOTICE, "PLL freq = %d\n", pll_freq); | ||
110 | |||
99 | if (hw_revision == 0xFF) { | 111 | if (hw_revision == 0xFF) { |
100 | 112 | ||
101 | ene_printk(KERN_WARNING, "device seems to be disabled\n"); | 113 | ene_printk(KERN_WARNING, "device seems to be disabled\n"); |
@@ -160,7 +172,7 @@ static int ene_hw_detect(struct ene_device *dev) | |||
160 | } | 172 | } |
161 | 173 | ||
162 | /* this enables/disables IR input via gpio40*/ | 174 | /* this enables/disables IR input via gpio40*/ |
163 | static void ene_enable_gpio40_recieve(struct ene_device *dev, int enable) | 175 | static void ene_enable_gpio40_receive(struct ene_device *dev, int enable) |
164 | { | 176 | { |
165 | ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, enable ? | 177 | ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, enable ? |
166 | 0 : ENE_CIR_CONF2_GPIO40DIS, | 178 | 0 : ENE_CIR_CONF2_GPIO40DIS, |
@@ -168,13 +180,13 @@ static void ene_enable_gpio40_recieve(struct ene_device *dev, int enable) | |||
168 | } | 180 | } |
169 | 181 | ||
170 | /* this enables/disables IR via standard input */ | 182 | /* this enables/disables IR via standard input */ |
171 | static void ene_enable_normal_recieve(struct ene_device *dev, int enable) | 183 | static void ene_enable_normal_receive(struct ene_device *dev, int enable) |
172 | { | 184 | { |
173 | ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_RX_ON : 0); | 185 | ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_RX_ON : 0); |
174 | } | 186 | } |
175 | 187 | ||
176 | /* this enables/disables IR input via unused fan tachtometer input */ | 188 | /* this enables/disables IR input via unused fan tachtometer input */ |
177 | static void ene_enable_fan_recieve(struct ene_device *dev, int enable) | 189 | static void ene_enable_fan_receive(struct ene_device *dev, int enable) |
178 | { | 190 | { |
179 | if (!enable) | 191 | if (!enable) |
180 | ene_hw_write_reg(dev, ENE_FAN_AS_IN1, 0); | 192 | ene_hw_write_reg(dev, ENE_FAN_AS_IN1, 0); |
@@ -186,7 +198,7 @@ static void ene_enable_fan_recieve(struct ene_device *dev, int enable) | |||
186 | } | 198 | } |
187 | 199 | ||
188 | 200 | ||
189 | /* Sense current recieved carrier */ | 201 | /* Sense current received carrier */ |
190 | static int ene_rx_sense_carrier(struct ene_device *dev) | 202 | static int ene_rx_sense_carrier(struct ene_device *dev) |
191 | { | 203 | { |
192 | int period = ene_hw_read_reg(dev, ENE_RX_CARRIER); | 204 | int period = ene_hw_read_reg(dev, ENE_RX_CARRIER); |
@@ -209,37 +221,37 @@ static int ene_rx_sense_carrier(struct ene_device *dev) | |||
209 | /* determine which input to use*/ | 221 | /* determine which input to use*/ |
210 | static void ene_rx_set_inputs(struct ene_device *dev) | 222 | static void ene_rx_set_inputs(struct ene_device *dev) |
211 | { | 223 | { |
212 | int learning_mode = dev->learning_enabled || dev->rx_carrier_sense; | 224 | int learning_mode = dev->learning_enabled; |
213 | 225 | ||
214 | ene_dbg("RX: setup reciever, learning mode = %d", learning_mode); | 226 | ene_dbg("RX: setup receiver, learning mode = %d", learning_mode); |
215 | 227 | ||
216 | ene_enable_normal_recieve(dev, 1); | 228 | ene_enable_normal_receive(dev, 1); |
217 | 229 | ||
218 | /* old hardware doesn't support learning mode for sure */ | 230 | /* old hardware doesn't support learning mode for sure */ |
219 | if (dev->hw_revision <= ENE_HW_B) | 231 | if (dev->hw_revision <= ENE_HW_B) |
220 | return; | 232 | return; |
221 | 233 | ||
222 | /* reciever not learning capable, still set gpio40 correctly */ | 234 | /* receiver not learning capable, still set gpio40 correctly */ |
223 | if (!dev->hw_learning_and_tx_capable) { | 235 | if (!dev->hw_learning_and_tx_capable) { |
224 | ene_enable_gpio40_recieve(dev, !dev->hw_gpio40_learning); | 236 | ene_enable_gpio40_receive(dev, !dev->hw_gpio40_learning); |
225 | return; | 237 | return; |
226 | } | 238 | } |
227 | 239 | ||
228 | /* enable learning mode */ | 240 | /* enable learning mode */ |
229 | if (learning_mode) { | 241 | if (learning_mode) { |
230 | ene_enable_gpio40_recieve(dev, dev->hw_gpio40_learning); | 242 | ene_enable_gpio40_receive(dev, dev->hw_gpio40_learning); |
231 | 243 | ||
232 | /* fan input is not used for learning */ | 244 | /* fan input is not used for learning */ |
233 | if (dev->hw_fan_as_normal_input) | 245 | if (dev->hw_fan_as_normal_input) |
234 | ene_enable_fan_recieve(dev, 0); | 246 | ene_enable_fan_receive(dev, 0); |
235 | 247 | ||
236 | /* disable learning mode */ | 248 | /* disable learning mode */ |
237 | } else { | 249 | } else { |
238 | if (dev->hw_fan_as_normal_input) { | 250 | if (dev->hw_fan_as_normal_input) { |
239 | ene_enable_fan_recieve(dev, 1); | 251 | ene_enable_fan_receive(dev, 1); |
240 | ene_enable_normal_recieve(dev, 0); | 252 | ene_enable_normal_receive(dev, 0); |
241 | } else | 253 | } else |
242 | ene_enable_gpio40_recieve(dev, | 254 | ene_enable_gpio40_receive(dev, |
243 | !dev->hw_gpio40_learning); | 255 | !dev->hw_gpio40_learning); |
244 | } | 256 | } |
245 | 257 | ||
@@ -249,6 +261,16 @@ static void ene_rx_set_inputs(struct ene_device *dev) | |||
249 | 261 | ||
250 | ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, learning_mode ? | 262 | ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, learning_mode ? |
251 | ENE_CIR_CONF2_LEARN2 : 0, ENE_CIR_CONF2_LEARN2); | 263 | ENE_CIR_CONF2_LEARN2 : 0, ENE_CIR_CONF2_LEARN2); |
264 | |||
265 | if (dev->rx_fan_input_inuse) { | ||
266 | dev->props->rx_resolution = ENE_SAMPLE_PERIOD_FAN * 1000; | ||
267 | |||
268 | dev->props->timeout = | ||
269 | ENE_FAN_VALUE_MASK * ENE_SAMPLE_PERIOD_FAN * 1000; | ||
270 | } else { | ||
271 | dev->props->rx_resolution = sample_period * 1000; | ||
272 | dev->props->timeout = ENE_MAXGAP * 1000; | ||
273 | } | ||
252 | } | 274 | } |
253 | 275 | ||
254 | /* Enable the device for receive */ | 276 | /* Enable the device for receive */ |
@@ -277,147 +299,33 @@ static void ene_rx_enable(struct ene_device *dev) | |||
277 | /* ack any pending irqs - just in case */ | 299 | /* ack any pending irqs - just in case */ |
278 | ene_irq_status(dev); | 300 | ene_irq_status(dev); |
279 | 301 | ||
280 | /* enter idle mode */ | ||
281 | ene_rx_set_idle(dev, 1); | ||
282 | |||
283 | /* enable firmware bits */ | 302 | /* enable firmware bits */ |
284 | ene_hw_write_reg_mask(dev, ENE_FW1, | 303 | ene_hw_write_reg_mask(dev, ENE_FW1, |
285 | ENE_FW1_ENABLE | ENE_FW1_IRQ, | 304 | ENE_FW1_ENABLE | ENE_FW1_IRQ, |
286 | ENE_FW1_ENABLE | ENE_FW1_IRQ); | 305 | ENE_FW1_ENABLE | ENE_FW1_IRQ); |
306 | |||
307 | /* enter idle mode */ | ||
308 | ir_raw_event_set_idle(dev->idev, 1); | ||
309 | ir_raw_event_reset(dev->idev); | ||
310 | |||
287 | } | 311 | } |
288 | 312 | ||
289 | /* Disable the device reciever */ | 313 | /* Disable the device receiver */ |
290 | static void ene_rx_disable(struct ene_device *dev) | 314 | static void ene_rx_disable(struct ene_device *dev) |
291 | { | 315 | { |
292 | /* disable inputs */ | 316 | /* disable inputs */ |
293 | ene_enable_normal_recieve(dev, 0); | 317 | ene_enable_normal_receive(dev, 0); |
294 | 318 | ||
295 | if (dev->hw_fan_as_normal_input) | 319 | if (dev->hw_fan_as_normal_input) |
296 | ene_enable_fan_recieve(dev, 0); | 320 | ene_enable_fan_receive(dev, 0); |
297 | 321 | ||
298 | /* disable hardware IRQ and firmware flag */ | 322 | /* disable hardware IRQ and firmware flag */ |
299 | ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_ENABLE | ENE_FW1_IRQ); | 323 | ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_ENABLE | ENE_FW1_IRQ); |
300 | 324 | ||
301 | ene_rx_set_idle(dev, 1); | 325 | ir_raw_event_set_idle(dev->idev, 1); |
302 | } | 326 | ir_raw_event_reset(dev->idev); |
303 | |||
304 | /* send current sample to the user */ | ||
305 | static void ene_rx_flush(struct ene_device *dev, int timeout) | ||
306 | { | ||
307 | unsigned long value; | ||
308 | |||
309 | value = dev->rx_sample_pulse ? LIRC_PULSE(dev->rx_sample) : | ||
310 | LIRC_SPACE(dev->rx_sample); | ||
311 | ene_send_sample(dev, value); | ||
312 | dev->rx_sample = 0; | ||
313 | dev->rx_sample_pulse = 0; | ||
314 | } | ||
315 | |||
316 | /* recieve new sample and process it */ | ||
317 | static void ene_rx_sample(struct ene_device *dev, int sample, int is_pulse) | ||
318 | { | ||
319 | ene_dbg("RX: sample %8d (%s)", sample, is_pulse ? "pulse" : "space"); | ||
320 | |||
321 | /* ignore spaces in idle mode, can get them on revC */ | ||
322 | /* also ignore a space in front of first pulse */ | ||
323 | if (dev->rx_idle && !is_pulse) | ||
324 | return; | ||
325 | |||
326 | /* get out of idle mode now */ | ||
327 | if (dev->rx_idle) | ||
328 | ene_rx_set_idle(dev, 0); | ||
329 | |||
330 | if (!dev->rx_sample) { | ||
331 | dev->rx_sample = sample; | ||
332 | dev->rx_sample_pulse = is_pulse; | ||
333 | } else if (is_pulse == dev->rx_sample_pulse) | ||
334 | dev->rx_sample += sample; | ||
335 | else { | ||
336 | ene_rx_flush(dev, 0); | ||
337 | dev->rx_sample = sample; | ||
338 | dev->rx_sample_pulse = is_pulse; | ||
339 | } | ||
340 | |||
341 | if (is_pulse) | ||
342 | return; | ||
343 | |||
344 | /* overflow sample from fan input recieved, enable idle mode */ | ||
345 | if (dev->rx_fan_input_inuse && | ||
346 | sample == ENE_FAN_VALUE_MASK * ENE_SAMPLE_PERIOD_FAN) { | ||
347 | ene_rx_set_idle(dev, 1); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | if (!dev->rx_fan_input_inuse) { | ||
352 | /* Report timeout if enabled */ | ||
353 | if (dev->rx_timeout && dev->rx_send_timeout_packet && | ||
354 | !dev->rx_timeout_sent && | ||
355 | dev->rx_sample > dev->rx_timeout) { | ||
356 | ene_dbg("RX: sending timeout sample"); | ||
357 | ene_send_sample(dev, LIRC_TIMEOUT(dev->rx_sample)); | ||
358 | dev->rx_timeout_sent = 1; | ||
359 | } | ||
360 | |||
361 | /* too large sample accumulated via normal input. | ||
362 | note that on revC, hardware idle mode turns on automaticly, | ||
363 | so max gap should be less that the gap after which | ||
364 | hw stops sending samples */ | ||
365 | if (dev->rx_sample > ENE_MAXGAP) { | ||
366 | ene_rx_set_idle(dev, 1); | ||
367 | return; | ||
368 | } | ||
369 | } | ||
370 | } | 327 | } |
371 | 328 | ||
372 | /* enable or disable idle mode */ | ||
373 | static void ene_rx_set_idle(struct ene_device *dev, int idle) | ||
374 | { | ||
375 | struct timeval now; | ||
376 | int disable_sampler = 0; | ||
377 | |||
378 | |||
379 | /* Also put hardware sampler in 'idle' mode on revB*/ | ||
380 | /* revC and higher do that automaticly (firmware does?) */ | ||
381 | if ((dev->hw_revision < ENE_HW_C) && enable_idle) | ||
382 | if (idle) | ||
383 | disable_sampler = 1; | ||
384 | |||
385 | ene_hw_write_reg_mask(dev, ENE_CIR_SAMPLE_PERIOD, | ||
386 | disable_sampler ? 0 : ENE_CIR_SAMPLE_OVERFLOW, | ||
387 | ENE_CIR_SAMPLE_OVERFLOW); | ||
388 | dev->rx_idle = idle; | ||
389 | |||
390 | /* remember when we have entered the idle mode */ | ||
391 | if (idle) { | ||
392 | ene_dbg("RX: going into idle mode"); | ||
393 | do_gettimeofday(&dev->rx_gap_start); | ||
394 | return; | ||
395 | } | ||
396 | |||
397 | ene_dbg("RX: back from idle mode"); | ||
398 | |||
399 | /* send the gap between keypresses now */ | ||
400 | do_gettimeofday(&now); | ||
401 | |||
402 | if (dev->rx_sample_pulse) { | ||
403 | ene_dbg("RX: somehow we recieved a pulse before idle mode???"); | ||
404 | return; | ||
405 | } | ||
406 | |||
407 | /* manually calculate and recieve the gap between keypresses */ | ||
408 | if (now.tv_sec - dev->rx_gap_start.tv_sec > 16) | ||
409 | dev->rx_sample = LIRC_SPACE(LIRC_VALUE_MASK); | ||
410 | else | ||
411 | dev->rx_sample += | ||
412 | 1000000ull * (now.tv_sec - dev->rx_gap_start.tv_sec) | ||
413 | + now.tv_usec - dev->rx_gap_start.tv_usec; | ||
414 | |||
415 | if (dev->rx_sample > LIRC_SPACE(LIRC_VALUE_MASK)) | ||
416 | dev->rx_sample = LIRC_SPACE(LIRC_VALUE_MASK); | ||
417 | |||
418 | ene_rx_flush(dev, 0); | ||
419 | dev->rx_timeout_sent = 0; | ||
420 | } | ||
421 | 329 | ||
422 | /* prepare transmission */ | 330 | /* prepare transmission */ |
423 | static void ene_tx_prepare(struct ene_device *dev) | 331 | static void ene_tx_prepare(struct ene_device *dev) |
@@ -436,6 +344,8 @@ static void ene_tx_prepare(struct ene_device *dev) | |||
436 | /* Set carrier */ | 344 | /* Set carrier */ |
437 | if (dev->tx_period) { | 345 | if (dev->tx_period) { |
438 | 346 | ||
347 | /* NOTE: duty cycle handling is just a guess, it might | ||
348 | not be aviable. Default values were tested */ | ||
439 | int tx_period_in500ns = dev->tx_period * 2; | 349 | int tx_period_in500ns = dev->tx_period * 2; |
440 | 350 | ||
441 | int tx_pulse_width_in_500ns = | 351 | int tx_pulse_width_in_500ns = |
@@ -459,7 +369,6 @@ static void ene_tx_prepare(struct ene_device *dev) | |||
459 | conf1 &= ~ENE_CIR_CONF1_TX_CARR; | 369 | conf1 &= ~ENE_CIR_CONF1_TX_CARR; |
460 | 370 | ||
461 | ene_hw_write_reg(dev, ENE_CIR_CONF1, conf1); | 371 | ene_hw_write_reg(dev, ENE_CIR_CONF1, conf1); |
462 | dev->tx_underway = 1; | ||
463 | 372 | ||
464 | } | 373 | } |
465 | 374 | ||
@@ -467,11 +376,11 @@ static void ene_tx_prepare(struct ene_device *dev) | |||
467 | static void ene_tx_complete(struct ene_device *dev) | 376 | static void ene_tx_complete(struct ene_device *dev) |
468 | { | 377 | { |
469 | ene_hw_write_reg(dev, ENE_CIR_CONF1, dev->saved_conf1); | 378 | ene_hw_write_reg(dev, ENE_CIR_CONF1, dev->saved_conf1); |
470 | dev->tx_underway = 0; | 379 | dev->tx_buffer = NULL; |
471 | } | 380 | } |
472 | 381 | ||
473 | /* set transmit mask */ | 382 | /* set transmit mask */ |
474 | static void ene_tx_set_transmiter_mask(struct ene_device *dev) | 383 | static void ene_tx_hw_set_transmiter_mask(struct ene_device *dev) |
475 | { | 384 | { |
476 | u8 txport1 = ene_hw_read_reg(dev, ENE_TX_PORT1) & ~ENE_TX_PORT1_EN; | 385 | u8 txport1 = ene_hw_read_reg(dev, ENE_TX_PORT1) & ~ENE_TX_PORT1_EN; |
477 | u8 txport2 = ene_hw_read_reg(dev, ENE_TX_PORT2) & ~ENE_TX_PORT2_EN; | 386 | u8 txport2 = ene_hw_read_reg(dev, ENE_TX_PORT2) & ~ENE_TX_PORT2_EN; |
@@ -492,8 +401,8 @@ static void ene_tx_sample(struct ene_device *dev) | |||
492 | u8 raw_tx; | 401 | u8 raw_tx; |
493 | u32 sample; | 402 | u32 sample; |
494 | 403 | ||
495 | if (!dev->tx_underway) { | 404 | if (!dev->tx_buffer) { |
496 | ene_dbg("TX: attempt to transmit while hw isn't setup"); | 405 | ene_dbg("TX: attempt to transmit NULL buffer"); |
497 | return; | 406 | return; |
498 | } | 407 | } |
499 | 408 | ||
@@ -623,6 +532,7 @@ static irqreturn_t ene_isr(int irq, void *data) | |||
623 | int carrier = 0; | 532 | int carrier = 0; |
624 | irqreturn_t retval = IRQ_NONE; | 533 | irqreturn_t retval = IRQ_NONE; |
625 | struct ene_device *dev = (struct ene_device *)data; | 534 | struct ene_device *dev = (struct ene_device *)data; |
535 | struct ir_raw_event ev; | ||
626 | 536 | ||
627 | 537 | ||
628 | spin_lock_irqsave(&dev->hw_lock, flags); | 538 | spin_lock_irqsave(&dev->hw_lock, flags); |
@@ -646,12 +556,13 @@ static irqreturn_t ene_isr(int irq, void *data) | |||
646 | goto unlock; | 556 | goto unlock; |
647 | 557 | ||
648 | 558 | ||
649 | if ((debug && dev->learning_enabled) || dev->rx_carrier_sense) | 559 | if (dev->carrier_detect_enabled || debug) |
650 | carrier = ene_rx_sense_carrier(dev); | 560 | carrier = ene_rx_sense_carrier(dev); |
651 | 561 | #if 0 | |
652 | if (dev->rx_carrier_sense && carrier) | 562 | /* TODO */ |
653 | ene_send_sample(dev, LIRC_FREQUENCY(carrier)); | 563 | if (dev->carrier_detect_enabled && carrier) |
654 | 564 | ir_raw_event_report_frequency(dev->idev, carrier); | |
565 | #endif | ||
655 | 566 | ||
656 | for (i = 0; i < ENE_SAMPLES_SIZE; i++) { | 567 | for (i = 0; i < ENE_SAMPLES_SIZE; i++) { |
657 | hw_value = ene_hw_read_reg(dev, | 568 | hw_value = ene_hw_read_reg(dev, |
@@ -672,13 +583,25 @@ static irqreturn_t ene_isr(int irq, void *data) | |||
672 | pulse = !(hw_value & ENE_SAMPLE_SPC_MASK); | 583 | pulse = !(hw_value & ENE_SAMPLE_SPC_MASK); |
673 | hw_value &= ENE_SAMPLE_VALUE_MASK; | 584 | hw_value &= ENE_SAMPLE_VALUE_MASK; |
674 | hw_sample = hw_value * sample_period; | 585 | hw_sample = hw_value * sample_period; |
586 | |||
587 | if (dev->rx_period_adjust) { | ||
588 | hw_sample *= (100 - dev->rx_period_adjust); | ||
589 | hw_sample /= 100; | ||
590 | } | ||
675 | } | 591 | } |
676 | /* no more data */ | 592 | /* no more data */ |
677 | if (!(hw_value)) | 593 | if (!(hw_value)) |
678 | break; | 594 | break; |
679 | 595 | ||
680 | ene_rx_sample(dev, hw_sample, pulse); | 596 | ene_dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space"); |
597 | |||
598 | |||
599 | ev.duration = hw_sample * 1000; | ||
600 | ev.pulse = pulse; | ||
601 | ir_raw_event_store_with_filter(dev->idev, &ev); | ||
681 | } | 602 | } |
603 | |||
604 | ir_raw_event_handle(dev->idev); | ||
682 | unlock: | 605 | unlock: |
683 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 606 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
684 | return retval; | 607 | return retval; |
@@ -687,8 +610,6 @@ unlock: | |||
687 | /* Initialize default settings */ | 610 | /* Initialize default settings */ |
688 | static void ene_setup_settings(struct ene_device *dev) | 611 | static void ene_setup_settings(struct ene_device *dev) |
689 | { | 612 | { |
690 | dev->rx_send_timeout_packet = 0; | ||
691 | dev->rx_timeout = ENE_MAXGAP; | ||
692 | dev->tx_period = 32; | 613 | dev->tx_period = 32; |
693 | dev->tx_duty_cycle = 25; /*%*/ | 614 | dev->tx_duty_cycle = 25; /*%*/ |
694 | dev->transmitter_mask = 3; | 615 | dev->transmitter_mask = 3; |
@@ -698,11 +619,7 @@ static void ene_setup_settings(struct ene_device *dev) | |||
698 | dev->learning_enabled = | 619 | dev->learning_enabled = |
699 | (input == 2 && dev->hw_learning_and_tx_capable); | 620 | (input == 2 && dev->hw_learning_and_tx_capable); |
700 | 621 | ||
701 | /* Clear accumulated sample bufer */ | ||
702 | dev->rx_sample = 0; | ||
703 | dev->rx_sample_pulse = 0; | ||
704 | dev->rx_pointer = -1; | 622 | dev->rx_pointer = -1; |
705 | dev->rx_carrier_sense = 0; | ||
706 | 623 | ||
707 | } | 624 | } |
708 | 625 | ||
@@ -732,144 +649,97 @@ static void ene_close(void *data) | |||
732 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 649 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
733 | } | 650 | } |
734 | 651 | ||
735 | /* outside interface for settings */ | 652 | /* outside interface: set transmitter mask */ |
736 | static int ene_ioctl(struct inode *node, struct file *file, | 653 | static int ene_set_tx_mask(void *data, u32 tx_mask) |
737 | unsigned int cmd, unsigned long arg) | ||
738 | { | 654 | { |
739 | int lvalue = 0, retval, tmp; | 655 | struct ene_device *dev = (struct ene_device *)data; |
740 | unsigned long flags; | 656 | unsigned long flags; |
741 | struct ene_device *dev = lirc_get_pdata(file); | 657 | ene_dbg("TX: attempt to set transmitter mask %02x", tx_mask); |
742 | 658 | ||
743 | 659 | /* invalid txmask */ | |
744 | switch (cmd) { | 660 | if (!tx_mask || tx_mask & ~0x3) { |
745 | case LIRC_SET_SEND_CARRIER: | 661 | ene_dbg("TX: invalid mask"); |
746 | case LIRC_SET_SEND_DUTY_CYCLE: | 662 | /* return count of transmitters */ |
747 | case LIRC_SET_TRANSMITTER_MASK: | 663 | return 2; |
748 | case LIRC_SET_MEASURE_CARRIER_MODE: | ||
749 | case LIRC_SET_REC_CARRIER: | ||
750 | /* All these aren't possible without this */ | ||
751 | if (!dev->hw_learning_and_tx_capable) | ||
752 | return -ENOSYS; | ||
753 | /* Fall through */ | ||
754 | case LIRC_SET_REC_TIMEOUT: | ||
755 | case LIRC_SET_REC_TIMEOUT_REPORTS: | ||
756 | retval = get_user(lvalue, (unsigned int *) arg); | ||
757 | if (retval) | ||
758 | return retval; | ||
759 | } | 664 | } |
760 | 665 | ||
761 | switch (cmd) { | 666 | spin_lock_irqsave(&dev->hw_lock, flags); |
762 | case LIRC_SET_SEND_CARRIER: | 667 | dev->transmitter_mask = tx_mask; |
763 | ene_dbg("TX: attempt to set tx carrier to %d kHz", lvalue); | 668 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
764 | tmp = 1000000 / lvalue; /* (1 / freq) (* # usec in 1 sec) */ | 669 | return 0; |
670 | } | ||
765 | 671 | ||
766 | if (tmp && (tmp > ENE_TX_PERIOD_MAX || | 672 | /* outside interface : set tx carrier */ |
767 | tmp < ENE_TX_PERIOD_MIN)) { | 673 | static int ene_set_tx_carrier(void *data, u32 carrier) |
674 | { | ||
675 | struct ene_device *dev = (struct ene_device *)data; | ||
676 | unsigned long flags; | ||
677 | u32 period = 1000000 / carrier; /* (1 / freq) (* # usec in 1 sec) */ | ||
768 | 678 | ||
769 | ene_dbg("TX: out of range %d-%d carrier, " | 679 | ene_dbg("TX: attempt to set tx carrier to %d kHz", carrier); |
770 | "falling back to 32 kHz", | ||
771 | 1000 / ENE_TX_PERIOD_MIN, | ||
772 | 1000 / ENE_TX_PERIOD_MAX); | ||
773 | 680 | ||
774 | tmp = 32; /* this is just a coincidence!!! */ | 681 | if (period && (period > ENE_TX_PERIOD_MAX || |
775 | } | 682 | period < ENE_TX_PERIOD_MIN)) { |
776 | ene_dbg("TX: set carrier to %d kHz", lvalue); | ||
777 | 683 | ||
778 | spin_lock_irqsave(&dev->hw_lock, flags); | 684 | ene_dbg("TX: out of range %d-%d carrier, " |
779 | dev->tx_period = tmp; | 685 | "falling back to 32 kHz", |
780 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 686 | 1000 / ENE_TX_PERIOD_MIN, |
781 | break; | 687 | 1000 / ENE_TX_PERIOD_MAX); |
782 | case LIRC_SET_SEND_DUTY_CYCLE: | ||
783 | ene_dbg("TX: attempt to set duty cycle to %d%%", lvalue); | ||
784 | 688 | ||
785 | if ((lvalue >= 100) || (lvalue <= 0)) { | 689 | period = 32; /* this is just a coincidence!!! */ |
786 | retval = -EINVAL; | ||
787 | break; | ||
788 | } | ||
789 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
790 | dev->tx_duty_cycle = lvalue; | ||
791 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
792 | break; | ||
793 | case LIRC_SET_TRANSMITTER_MASK: | ||
794 | ene_dbg("TX: attempt to set transmitter mask %02x", lvalue); | ||
795 | |||
796 | /* invalid txmask */ | ||
797 | if (!lvalue || lvalue & ~0x3) { | ||
798 | ene_dbg("TX: invalid mask"); | ||
799 | /* this supposed to return num of transmitters */ | ||
800 | retval = 2; | ||
801 | break; | ||
802 | } | ||
803 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
804 | dev->transmitter_mask = lvalue; | ||
805 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
806 | break; | ||
807 | case LIRC_SET_REC_CARRIER: | ||
808 | tmp = (lvalue > ENE_NORMAL_RX_HI || lvalue < ENE_NORMAL_RX_LOW); | ||
809 | |||
810 | if (tmp != dev->learning_enabled) { | ||
811 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
812 | dev->learning_enabled = tmp; | ||
813 | ene_rx_set_inputs(dev); | ||
814 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
815 | } | ||
816 | break; | ||
817 | case LIRC_SET_REC_TIMEOUT: | ||
818 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
819 | dev->rx_timeout = lvalue; | ||
820 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
821 | ene_dbg("RX: set rx report timeout to %d", dev->rx_timeout); | ||
822 | break; | ||
823 | case LIRC_SET_REC_TIMEOUT_REPORTS: | ||
824 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
825 | dev->rx_send_timeout_packet = lvalue; | ||
826 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
827 | ene_dbg("RX: %sable timeout reports", | ||
828 | dev->rx_send_timeout_packet ? "en" : "dis"); | ||
829 | break; | ||
830 | case LIRC_SET_MEASURE_CARRIER_MODE: | ||
831 | if (dev->rx_carrier_sense == lvalue) | ||
832 | break; | ||
833 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
834 | dev->rx_carrier_sense = lvalue; | ||
835 | ene_rx_set_inputs(dev); | ||
836 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
837 | break; | ||
838 | case LIRC_GET_REC_RESOLUTION: | ||
839 | tmp = dev->rx_fan_input_inuse ? | ||
840 | ENE_SAMPLE_PERIOD_FAN : sample_period; | ||
841 | retval = put_user(tmp, (unsigned long *) arg); | ||
842 | break; | ||
843 | default: | ||
844 | retval = -ENOIOCTLCMD; | ||
845 | break; | ||
846 | } | 690 | } |
691 | ene_dbg("TX: set carrier to %d kHz", carrier); | ||
847 | 692 | ||
848 | return retval; | 693 | spin_lock_irqsave(&dev->hw_lock, flags); |
694 | dev->tx_period = period; | ||
695 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
696 | return 0; | ||
849 | } | 697 | } |
850 | 698 | ||
851 | /* outside interface: transmit */ | 699 | |
852 | static ssize_t ene_transmit(struct file *file, const char *buf, | 700 | /* outside interface: enable learning mode */ |
853 | size_t n, loff_t *ppos) | 701 | static int ene_set_learning_mode(void *data, int enable) |
854 | { | 702 | { |
855 | struct ene_device *dev = lirc_get_pdata(file); | 703 | struct ene_device *dev = (struct ene_device *)data; |
856 | unsigned long flags; | 704 | unsigned long flags; |
705 | if (enable == dev->learning_enabled) | ||
706 | return 0; | ||
857 | 707 | ||
858 | if (!dev) | 708 | spin_lock_irqsave(&dev->hw_lock, flags); |
859 | return -EFAULT; | 709 | dev->learning_enabled = enable; |
710 | ene_rx_set_inputs(dev); | ||
711 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
712 | return 0; | ||
713 | } | ||
860 | 714 | ||
861 | if (!dev->hw_learning_and_tx_capable) | 715 | /* outside interface: set rec carrier */ |
862 | return -ENODEV; | 716 | static int ene_set_rec_carrier(void *data, u32 min, u32 max) |
717 | { | ||
718 | struct ene_device *dev = (struct ene_device *)data; | ||
719 | ene_set_learning_mode(dev, | ||
720 | max > ENE_NORMAL_RX_HI || min < ENE_NORMAL_RX_LOW); | ||
721 | return 0; | ||
722 | } | ||
863 | 723 | ||
864 | if (n % sizeof(int)) | 724 | /* outside interface: enable or disable idle mode */ |
865 | return -EINVAL; | 725 | static void ene_rx_set_idle(void *data, int idle) |
726 | { | ||
727 | struct ene_device *dev = (struct ene_device *)data; | ||
728 | ene_dbg("%sabling idle mode", idle ? "en" : "dis"); | ||
866 | 729 | ||
867 | if (n > ENE_TXBUF_SIZE * sizeof(int)) | 730 | ene_hw_write_reg_mask(dev, ENE_CIR_SAMPLE_PERIOD, |
868 | return -ENOMEM; | 731 | (enable_idle && idle) ? 0 : ENE_CIR_SAMPLE_OVERFLOW, |
732 | ENE_CIR_SAMPLE_OVERFLOW); | ||
733 | } | ||
869 | 734 | ||
870 | if (copy_from_user(dev->tx_buffer, buf, n)) | ||
871 | return -EFAULT; | ||
872 | 735 | ||
736 | /* outside interface: transmit */ | ||
737 | static int ene_transmit(void *data, int *buf, u32 n) | ||
738 | { | ||
739 | struct ene_device *dev = (struct ene_device *)data; | ||
740 | unsigned long flags; | ||
741 | |||
742 | dev->tx_buffer = buf; | ||
873 | dev->tx_len = n / sizeof(int); | 743 | dev->tx_len = n / sizeof(int); |
874 | dev->tx_pos = 0; | 744 | dev->tx_pos = 0; |
875 | dev->tx_reg = 0; | 745 | dev->tx_reg = 0; |
@@ -881,7 +751,7 @@ static ssize_t ene_transmit(struct file *file, const char *buf, | |||
881 | 751 | ||
882 | spin_lock_irqsave(&dev->hw_lock, flags); | 752 | spin_lock_irqsave(&dev->hw_lock, flags); |
883 | 753 | ||
884 | ene_tx_set_transmiter_mask(dev); | 754 | ene_tx_hw_set_transmiter_mask(dev); |
885 | ene_tx_prepare(dev); | 755 | ene_tx_prepare(dev); |
886 | 756 | ||
887 | /* Transmit first two samples */ | 757 | /* Transmit first two samples */ |
@@ -897,80 +767,35 @@ static ssize_t ene_transmit(struct file *file, const char *buf, | |||
897 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 767 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
898 | } else | 768 | } else |
899 | ene_dbg("TX: done"); | 769 | ene_dbg("TX: done"); |
900 | |||
901 | return n; | 770 | return n; |
902 | } | 771 | } |
903 | 772 | ||
904 | /* Sends one sample to the user */ | ||
905 | static void ene_send_sample(struct ene_device *dev, unsigned long sample) | ||
906 | { | ||
907 | if (!lirc_buffer_full(dev->lirc_driver->rbuf)) { | ||
908 | lirc_buffer_write(dev->lirc_driver->rbuf, (void *)&sample); | ||
909 | wake_up(&dev->lirc_driver->rbuf->wait_poll); | ||
910 | } | ||
911 | } | ||
912 | |||
913 | |||
914 | static const struct file_operations ene_fops = { | ||
915 | .owner = THIS_MODULE, | ||
916 | .write = ene_transmit, | ||
917 | .ioctl = ene_ioctl, | ||
918 | }; | ||
919 | 773 | ||
920 | /* main load function */ | 774 | /* probe entry */ |
921 | static int ene_probe(struct pnp_dev *pnp_dev, | 775 | static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) |
922 | const struct pnp_device_id *dev_id) | ||
923 | { | 776 | { |
924 | struct ene_device *dev; | ||
925 | struct lirc_driver *lirc_driver; | ||
926 | int error = -ENOMEM; | 777 | int error = -ENOMEM; |
778 | struct ir_dev_props *ir_props; | ||
779 | struct input_dev *input_dev; | ||
780 | struct ene_device *dev; | ||
927 | 781 | ||
782 | /* allocate memory */ | ||
783 | input_dev = input_allocate_device(); | ||
784 | ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); | ||
928 | dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); | 785 | dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); |
929 | 786 | ||
930 | if (!dev) | 787 | if (!input_dev || !ir_props || !dev) |
931 | goto err1; | 788 | goto error; |
932 | |||
933 | dev->pnp_dev = pnp_dev; | ||
934 | pnp_set_drvdata(pnp_dev, dev); | ||
935 | |||
936 | /* prepare lirc interface */ | ||
937 | error = -ENOMEM; | ||
938 | lirc_driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); | ||
939 | |||
940 | if (!lirc_driver) | ||
941 | goto err2; | ||
942 | |||
943 | dev->lirc_driver = lirc_driver; | ||
944 | |||
945 | strcpy(lirc_driver->name, ENE_DRIVER_NAME); | ||
946 | lirc_driver->minor = -1; | ||
947 | lirc_driver->code_length = sizeof(int) * 8; | ||
948 | lirc_driver->features = LIRC_CAN_REC_MODE2 | | ||
949 | LIRC_CAN_GET_REC_RESOLUTION | | ||
950 | LIRC_CAN_SET_REC_TIMEOUT; | ||
951 | lirc_driver->data = dev; | ||
952 | lirc_driver->set_use_inc = ene_open; | ||
953 | lirc_driver->set_use_dec = ene_close; | ||
954 | lirc_driver->dev = &pnp_dev->dev; | ||
955 | lirc_driver->owner = THIS_MODULE; | ||
956 | lirc_driver->fops = &ene_fops; | ||
957 | lirc_driver->min_timeout = ENE_MINGAP; | ||
958 | lirc_driver->max_timeout = ENE_MAXGAP; | ||
959 | lirc_driver->rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL); | ||
960 | |||
961 | if (!lirc_driver->rbuf) | ||
962 | goto err3; | ||
963 | |||
964 | if (lirc_buffer_init(lirc_driver->rbuf, sizeof(int), sizeof(int) * 512)) | ||
965 | goto err4; | ||
966 | 789 | ||
967 | /* validate resources */ | 790 | /* validate resources */ |
791 | error = -ENODEV; | ||
792 | |||
968 | if (!pnp_port_valid(pnp_dev, 0) || | 793 | if (!pnp_port_valid(pnp_dev, 0) || |
969 | pnp_port_len(pnp_dev, 0) < ENE_MAX_IO) | 794 | pnp_port_len(pnp_dev, 0) < ENE_MAX_IO) |
970 | goto err5; | 795 | goto error; |
971 | 796 | ||
972 | if (!pnp_irq_valid(pnp_dev, 0)) | 797 | if (!pnp_irq_valid(pnp_dev, 0)) |
973 | goto err5; | 798 | goto error; |
974 | 799 | ||
975 | dev->hw_io = pnp_port_start(pnp_dev, 0); | 800 | dev->hw_io = pnp_port_start(pnp_dev, 0); |
976 | dev->irq = pnp_irq(pnp_dev, 0); | 801 | dev->irq = pnp_irq(pnp_dev, 0); |
@@ -979,16 +804,19 @@ static int ene_probe(struct pnp_dev *pnp_dev, | |||
979 | /* claim the resources */ | 804 | /* claim the resources */ |
980 | error = -EBUSY; | 805 | error = -EBUSY; |
981 | if (!request_region(dev->hw_io, ENE_MAX_IO, ENE_DRIVER_NAME)) | 806 | if (!request_region(dev->hw_io, ENE_MAX_IO, ENE_DRIVER_NAME)) |
982 | goto err5; | 807 | goto error; |
983 | 808 | ||
984 | if (request_irq(dev->irq, ene_isr, | 809 | if (request_irq(dev->irq, ene_isr, |
985 | IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) | 810 | IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) |
986 | goto err6; | 811 | goto error; |
812 | |||
813 | pnp_set_drvdata(pnp_dev, dev); | ||
814 | dev->pnp_dev = pnp_dev; | ||
987 | 815 | ||
988 | /* detect hardware version and features */ | 816 | /* detect hardware version and features */ |
989 | error = ene_hw_detect(dev); | 817 | error = ene_hw_detect(dev); |
990 | if (error) | 818 | if (error) |
991 | goto err7; | 819 | goto error; |
992 | 820 | ||
993 | ene_setup_settings(dev); | 821 | ene_setup_settings(dev); |
994 | 822 | ||
@@ -1000,19 +828,21 @@ static int ene_probe(struct pnp_dev *pnp_dev, | |||
1000 | "Simulation of TX activated\n"); | 828 | "Simulation of TX activated\n"); |
1001 | } | 829 | } |
1002 | 830 | ||
1003 | if (dev->hw_learning_and_tx_capable) { | 831 | ir_props->driver_type = RC_DRIVER_IR_RAW; |
1004 | lirc_driver->features |= LIRC_CAN_SEND_PULSE | | 832 | ir_props->allowed_protos = IR_TYPE_ALL; |
1005 | LIRC_CAN_SET_SEND_CARRIER | | 833 | ir_props->priv = dev; |
1006 | LIRC_CAN_SET_TRANSMITTER_MASK; | 834 | ir_props->open = ene_open; |
835 | ir_props->close = ene_close; | ||
836 | ir_props->min_timeout = ENE_MINGAP * 1000; | ||
837 | ir_props->max_timeout = ENE_MAXGAP * 1000; | ||
838 | ir_props->timeout = ENE_MAXGAP * 1000; | ||
1007 | 839 | ||
1008 | if (enable_duty_carrier) | 840 | if (dev->hw_revision == ENE_HW_B) |
1009 | lirc_driver->features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; | 841 | ir_props->s_idle = ene_rx_set_idle; |
1010 | 842 | ||
1011 | if (input == 0) | ||
1012 | lirc_driver->features |= LIRC_CAN_SET_REC_CARRIER; | ||
1013 | 843 | ||
1014 | init_completion(&dev->tx_complete); | 844 | dev->props = ir_props; |
1015 | } | 845 | dev->idev = input_dev; |
1016 | 846 | ||
1017 | /* don't allow too short/long sample periods */ | 847 | /* don't allow too short/long sample periods */ |
1018 | if (sample_period < 5 || sample_period > 0x7F) | 848 | if (sample_period < 5 || sample_period > 0x7F) |
@@ -1029,29 +859,50 @@ static int ene_probe(struct pnp_dev *pnp_dev, | |||
1029 | sample_period = 75; | 859 | sample_period = 75; |
1030 | } | 860 | } |
1031 | 861 | ||
862 | ir_props->rx_resolution = sample_period * 1000; | ||
863 | |||
864 | if (dev->hw_learning_and_tx_capable) { | ||
865 | |||
866 | ir_props->s_learning_mode = ene_set_learning_mode; | ||
867 | |||
868 | if (input == 0) | ||
869 | ir_props->s_rx_carrier_range = ene_set_rec_carrier; | ||
870 | |||
871 | init_completion(&dev->tx_complete); | ||
872 | ir_props->tx_ir = ene_transmit; | ||
873 | ir_props->s_tx_mask = ene_set_tx_mask; | ||
874 | ir_props->s_tx_carrier = ene_set_tx_carrier; | ||
875 | ir_props->tx_resolution = ENE_TX_SMPL_PERIOD * 1000; | ||
876 | /* ir_props->s_carrier_report = ene_set_carrier_report; */ | ||
877 | } | ||
878 | |||
879 | |||
1032 | device_set_wakeup_capable(&pnp_dev->dev, 1); | 880 | device_set_wakeup_capable(&pnp_dev->dev, 1); |
1033 | device_set_wakeup_enable(&pnp_dev->dev, 1); | 881 | device_set_wakeup_enable(&pnp_dev->dev, 1); |
1034 | 882 | ||
883 | if (dev->hw_learning_and_tx_capable) | ||
884 | input_dev->name = "ENE eHome Infrared Remote Transceiver"; | ||
885 | else | ||
886 | input_dev->name = "ENE eHome Infrared Remote Receiver"; | ||
887 | |||
888 | |||
1035 | error = -ENODEV; | 889 | error = -ENODEV; |
1036 | if (lirc_register_driver(lirc_driver)) | 890 | if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props, |
1037 | goto err7; | 891 | ENE_DRIVER_NAME)) |
892 | goto error; | ||
893 | |||
1038 | 894 | ||
1039 | ene_printk(KERN_NOTICE, "driver has been succesfully loaded\n"); | 895 | ene_printk(KERN_NOTICE, "driver has been succesfully loaded\n"); |
1040 | return 0; | 896 | return 0; |
1041 | 897 | error: | |
1042 | err7: | 898 | if (dev->irq) |
1043 | free_irq(dev->irq, dev); | 899 | free_irq(dev->irq, dev); |
1044 | err6: | 900 | if (dev->hw_io) |
1045 | release_region(dev->hw_io, ENE_MAX_IO); | 901 | release_region(dev->hw_io, ENE_MAX_IO); |
1046 | err5: | 902 | |
1047 | lirc_buffer_free(lirc_driver->rbuf); | 903 | input_free_device(input_dev); |
1048 | err4: | 904 | kfree(ir_props); |
1049 | kfree(lirc_driver->rbuf); | ||
1050 | err3: | ||
1051 | kfree(lirc_driver); | ||
1052 | err2: | ||
1053 | kfree(dev); | 905 | kfree(dev); |
1054 | err1: | ||
1055 | return error; | 906 | return error; |
1056 | } | 907 | } |
1057 | 908 | ||
@@ -1067,9 +918,8 @@ static void ene_remove(struct pnp_dev *pnp_dev) | |||
1067 | 918 | ||
1068 | free_irq(dev->irq, dev); | 919 | free_irq(dev->irq, dev); |
1069 | release_region(dev->hw_io, ENE_MAX_IO); | 920 | release_region(dev->hw_io, ENE_MAX_IO); |
1070 | lirc_unregister_driver(dev->lirc_driver->minor); | 921 | ir_input_unregister(dev->idev); |
1071 | lirc_buffer_free(dev->lirc_driver->rbuf); | 922 | kfree(dev->props); |
1072 | kfree(dev->lirc_driver); | ||
1073 | kfree(dev); | 923 | kfree(dev); |
1074 | } | 924 | } |
1075 | 925 | ||
@@ -1113,6 +963,7 @@ static const struct pnp_device_id ene_ids[] = { | |||
1113 | {.id = "ENE0100",}, | 963 | {.id = "ENE0100",}, |
1114 | {.id = "ENE0200",}, | 964 | {.id = "ENE0200",}, |
1115 | {.id = "ENE0201",}, | 965 | {.id = "ENE0201",}, |
966 | {.id = "ENE0202",}, | ||
1116 | {}, | 967 | {}, |
1117 | }; | 968 | }; |
1118 | 969 | ||
@@ -1160,13 +1011,9 @@ module_param(txsim, bool, S_IRUGO); | |||
1160 | MODULE_PARM_DESC(txsim, | 1011 | MODULE_PARM_DESC(txsim, |
1161 | "Simulate TX features on unsupported hardware (dangerous)"); | 1012 | "Simulate TX features on unsupported hardware (dangerous)"); |
1162 | 1013 | ||
1163 | module_param(enable_duty_carrier, bool, S_IRUGO); | ||
1164 | MODULE_PARM_DESC(enable_duty_carrier, | ||
1165 | "Enable a code that might allow to to set TX carrier duty cycle"); | ||
1166 | |||
1167 | MODULE_DEVICE_TABLE(pnp, ene_ids); | 1014 | MODULE_DEVICE_TABLE(pnp, ene_ids); |
1168 | MODULE_DESCRIPTION | 1015 | MODULE_DESCRIPTION |
1169 | ("LIRC driver for KB3926B/KB3926C/KB3926D " | 1016 | ("Infrared input driver for KB3926B/KB3926C/KB3926D " |
1170 | "(aka ENE0100/ENE0200/ENE0201) CIR port"); | 1017 | "(aka ENE0100/ENE0200/ENE0201) CIR port"); |
1171 | 1018 | ||
1172 | MODULE_AUTHOR("Maxim Levitsky"); | 1019 | MODULE_AUTHOR("Maxim Levitsky"); |
diff --git a/drivers/media/IR/ene_ir.h b/drivers/media/IR/ene_ir.h index b464a680d8ae..54c76af0d033 100644 --- a/drivers/media/IR/ene_ir.h +++ b/drivers/media/IR/ene_ir.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * driver for ENE KB3926 B/C/D CIR (also known as ENE0100/ENE0200/ENE0201) | 2 | * driver for ENE KB3926 B/C/D CIR (also known as ENE0XXX) |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> | 4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> |
5 | * | 5 | * |
@@ -19,8 +19,7 @@ | |||
19 | * USA | 19 | * USA |
20 | */ | 20 | */ |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <media/lirc.h> | 22 | |
23 | #include <media/lirc_dev.h> | ||
24 | 23 | ||
25 | /* hardware address */ | 24 | /* hardware address */ |
26 | #define ENE_STATUS 0 /* hardware status - unused */ | 25 | #define ENE_STATUS 0 /* hardware status - unused */ |
@@ -88,7 +87,7 @@ | |||
88 | #define ENE_CIR_CONF1 0xFEC0 | 87 | #define ENE_CIR_CONF1 0xFEC0 |
89 | #define ENE_CIR_CONF1_TX_CLEAR 0x01 /* clear that on revC */ | 88 | #define ENE_CIR_CONF1_TX_CLEAR 0x01 /* clear that on revC */ |
90 | /* while transmitting */ | 89 | /* while transmitting */ |
91 | #define ENE_CIR_CONF1_RX_ON 0x07 /* normal reciever enabled */ | 90 | #define ENE_CIR_CONF1_RX_ON 0x07 /* normal receiver enabled */ |
92 | #define ENE_CIR_CONF1_LEARN1 0x08 /* enabled on learning mode */ | 91 | #define ENE_CIR_CONF1_LEARN1 0x08 /* enabled on learning mode */ |
93 | #define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */ | 92 | #define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */ |
94 | #define ENE_CIR_CONF1_TX_CARR 0x80 /* send TX carrier or not */ | 93 | #define ENE_CIR_CONF1_TX_CARR 0x80 /* send TX carrier or not */ |
@@ -112,7 +111,7 @@ | |||
112 | /* Unknown TX setting - TX sample period ??? */ | 111 | /* Unknown TX setting - TX sample period ??? */ |
113 | #define ENE_TX_UNK1 0xFECB /* set to 0x63 */ | 112 | #define ENE_TX_UNK1 0xFECB /* set to 0x63 */ |
114 | 113 | ||
115 | /* Current recieved carrier period */ | 114 | /* Current received carrier period */ |
116 | #define ENE_RX_CARRIER 0xFECC /* RX period (500 ns) */ | 115 | #define ENE_RX_CARRIER 0xFECC /* RX period (500 ns) */ |
117 | #define ENE_RX_CARRIER_VALID 0x80 /* Register content valid */ | 116 | #define ENE_RX_CARRIER_VALID 0x80 /* Register content valid */ |
118 | 117 | ||
@@ -124,6 +123,9 @@ | |||
124 | 123 | ||
125 | /* Hardware versions */ | 124 | /* Hardware versions */ |
126 | #define ENE_HW_VERSION 0xFF00 /* hardware revision */ | 125 | #define ENE_HW_VERSION 0xFF00 /* hardware revision */ |
126 | #define ENE_PLLFRH 0xFF16 | ||
127 | #define ENE_PLLFRL 0xFF17 | ||
128 | |||
127 | #define ENE_HW_UNK 0xFF1D | 129 | #define ENE_HW_UNK 0xFF1D |
128 | #define ENE_HW_UNK_CLR 0x04 | 130 | #define ENE_HW_UNK_CLR 0x04 |
129 | #define ENE_HW_VER_MAJOR 0xFF1E /* chip version */ | 131 | #define ENE_HW_VER_MAJOR 0xFF1E /* chip version */ |
@@ -162,8 +164,7 @@ | |||
162 | 164 | ||
163 | /******************************************************************************/ | 165 | /******************************************************************************/ |
164 | 166 | ||
165 | #define ENE_DRIVER_NAME "enecir" | 167 | #define ENE_DRIVER_NAME "ene_ir" |
166 | #define ENE_TXBUF_SIZE (500 * sizeof(int)) /* 500 samples (arbitary) */ | ||
167 | 168 | ||
168 | #define ENE_IRQ_RX 1 | 169 | #define ENE_IRQ_RX 1 |
169 | #define ENE_IRQ_TX 2 | 170 | #define ENE_IRQ_TX 2 |
@@ -188,7 +189,8 @@ | |||
188 | 189 | ||
189 | struct ene_device { | 190 | struct ene_device { |
190 | struct pnp_dev *pnp_dev; | 191 | struct pnp_dev *pnp_dev; |
191 | struct lirc_driver *lirc_driver; | 192 | struct input_dev *idev; |
193 | struct ir_dev_props *props; | ||
192 | int in_use; | 194 | int in_use; |
193 | 195 | ||
194 | /* hw IO settings */ | 196 | /* hw IO settings */ |
@@ -198,43 +200,36 @@ struct ene_device { | |||
198 | 200 | ||
199 | /* HW features */ | 201 | /* HW features */ |
200 | int hw_revision; /* hardware revision */ | 202 | int hw_revision; /* hardware revision */ |
201 | int hw_learning_and_tx_capable; /* learning capable */ | 203 | bool hw_learning_and_tx_capable; /* learning capable */ |
202 | int hw_gpio40_learning; /* gpio40 is learning */ | 204 | bool hw_gpio40_learning; /* gpio40 is learning */ |
203 | int hw_fan_as_normal_input; /* fan input is used as */ | 205 | bool hw_fan_as_normal_input; /* fan input is used as */ |
204 | /* regular input */ | 206 | /* regular input */ |
205 | /* HW state*/ | 207 | /* HW state*/ |
206 | int rx_pointer; /* hw pointer to rx buffer */ | 208 | int rx_pointer; /* hw pointer to rx buffer */ |
207 | int rx_fan_input_inuse; /* is fan input in use for rx*/ | 209 | bool rx_fan_input_inuse; /* is fan input in use for rx*/ |
208 | int tx_reg; /* current reg used for TX */ | 210 | int tx_reg; /* current reg used for TX */ |
209 | u8 saved_conf1; /* saved FEC0 reg */ | 211 | u8 saved_conf1; /* saved FEC0 reg */ |
210 | int learning_enabled; /* learning input enabled */ | ||
211 | |||
212 | /* RX sample handling */ | ||
213 | int rx_sample; /* current recieved sample */ | ||
214 | int rx_sample_pulse; /* recieved sample is pulse */ | ||
215 | int rx_idle; /* idle mode for RX activated */ | ||
216 | struct timeval rx_gap_start; /* time of start of idle */ | ||
217 | int rx_timeout; /* time in ms of RX timeout */ | ||
218 | int rx_send_timeout_packet; /* do we send RX timeout */ | ||
219 | int rx_timeout_sent; /* we sent the timeout packet */ | ||
220 | int rx_carrier_sense; /* sense carrier */ | ||
221 | 212 | ||
222 | /* TX sample handling */ | 213 | /* TX sample handling */ |
223 | unsigned int tx_sample; /* current sample for TX */ | 214 | unsigned int tx_sample; /* current sample for TX */ |
224 | int tx_sample_pulse; /* current sample is pulse */ | 215 | bool tx_sample_pulse; /* current sample is pulse */ |
225 | 216 | ||
226 | /* TX buffer */ | 217 | /* TX buffer */ |
227 | int tx_buffer[ENE_TXBUF_SIZE]; /* input samples buffer*/ | 218 | int *tx_buffer; /* input samples buffer*/ |
228 | int tx_pos; /* position in that bufer */ | 219 | int tx_pos; /* position in that bufer */ |
229 | int tx_len; /* current len of tx buffer */ | 220 | int tx_len; /* current len of tx buffer */ |
230 | int tx_underway; /* TX is under way*/ | ||
231 | int tx_done; /* done transmitting */ | 221 | int tx_done; /* done transmitting */ |
232 | /* one more sample pending*/ | 222 | /* one more sample pending*/ |
233 | struct completion tx_complete; /* TX completion */ | 223 | struct completion tx_complete; /* TX completion */ |
234 | struct timer_list tx_sim_timer; | 224 | struct timer_list tx_sim_timer; |
235 | 225 | ||
236 | /*TX settings */ | 226 | /* TX settings */ |
237 | int tx_period; | 227 | int tx_period; |
238 | int tx_duty_cycle; | 228 | int tx_duty_cycle; |
239 | int transmitter_mask; | 229 | int transmitter_mask; |
230 | |||
231 | /* RX settings */ | ||
232 | bool learning_enabled; /* learning input enabled */ | ||
233 | bool carrier_detect_enabled; /* carrier detect enabled */ | ||
234 | int rx_period_adjust; | ||
240 | }; | 235 | }; |