aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/lirc
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2010-07-31 10:59:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-08 22:43:00 -0400
commit9ea53b74df9c4681f5bb2da6b2e10e37d87ea6d6 (patch)
tree7f3dc2e209bdcca8388e0aac88c0b7ea2022c6c8 /drivers/staging/lirc
parented4d3876d18d95406e0258a6421b1f4eda51d629 (diff)
V4L/DVB: STAGING: remove lirc_ene0100 driver
Add latest unported version of this driver to media/IR. Next patch will port it to ir core. Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging/lirc')
-rw-r--r--drivers/staging/lirc/Kconfig8
-rw-r--r--drivers/staging/lirc/Makefile1
-rw-r--r--drivers/staging/lirc/lirc_ene0100.c646
3 files changed, 0 insertions, 655 deletions
diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/lirc/Kconfig
index 7db8cb68ab5..100c4d4b812 100644
--- a/drivers/staging/lirc/Kconfig
+++ b/drivers/staging/lirc/Kconfig
@@ -18,14 +18,6 @@ config LIRC_BT829
18 help 18 help
19 Driver for the IR interface on BT829-based hardware 19 Driver for the IR interface on BT829-based hardware
20 20
21config LIRC_ENE0100
22 tristate "ENE KB3924/ENE0100 CIR Port Reciever"
23 depends on LIRC_STAGING && PNP
24 help
25 This is a driver for CIR port handled by ENE KB3924 embedded
26 controller found on some notebooks.
27 It appears on PNP list as ENE0100.
28
29config LIRC_I2C 21config LIRC_I2C
30 tristate "I2C Based IR Receivers" 22 tristate "I2C Based IR Receivers"
31 depends on LIRC_STAGING && I2C 23 depends on LIRC_STAGING && I2C
diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/lirc/Makefile
index bd789d8a017..4da1f3397a1 100644
--- a/drivers/staging/lirc/Makefile
+++ b/drivers/staging/lirc/Makefile
@@ -4,7 +4,6 @@
4# Each configuration option enables a list of files. 4# Each configuration option enables a list of files.
5 5
6obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o 6obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
7obj-$(CONFIG_LIRC_ENE0100) += lirc_ene0100.o
8obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o 7obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o
9obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o 8obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
10obj-$(CONFIG_LIRC_IMON) += lirc_imon.o 9obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
diff --git a/drivers/staging/lirc/lirc_ene0100.c b/drivers/staging/lirc/lirc_ene0100.c
deleted file mode 100644
index a152c52b074..00000000000
--- a/drivers/staging/lirc/lirc_ene0100.c
+++ /dev/null
@@ -1,646 +0,0 @@
1/*
2 * driver for ENE KB3926 B/C/D CIR (also known as ENE0100)
3 *
4 * Copyright (C) 2009 Maxim Levitsky <maximlevitsky@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/pnp.h>
25#include <linux/io.h>
26#include <linux/interrupt.h>
27#include <linux/sched.h>
28#include "lirc_ene0100.h"
29
30static int sample_period = 75;
31static int enable_idle = 1;
32static int enable_learning;
33
34static void ene_set_idle(struct ene_device *dev, int idle);
35static void ene_set_inputs(struct ene_device *dev, int enable);
36
37/* read a hardware register */
38static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg)
39{
40 outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
41 outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
42 return inb(dev->hw_io + ENE_IO);
43}
44
45/* write a hardware register */
46static void ene_hw_write_reg(struct ene_device *dev, u16 reg, u8 value)
47{
48 outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
49 outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
50 outb(value, dev->hw_io + ENE_IO);
51}
52
53/* change specific bits in hardware register */
54static void ene_hw_write_reg_mask(struct ene_device *dev,
55 u16 reg, u8 value, u8 mask)
56{
57 u8 regvalue;
58
59 outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
60 outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
61
62 regvalue = inb(dev->hw_io + ENE_IO) & ~mask;
63 regvalue |= (value & mask);
64 outb(regvalue, dev->hw_io + ENE_IO);
65}
66
67/* read irq status and ack it */
68static int ene_hw_irq_status(struct ene_device *dev, int *buffer_pointer)
69{
70 u8 irq_status;
71 u8 fw_flags1, fw_flags2;
72
73 fw_flags2 = ene_hw_read_reg(dev, ENE_FW2);
74
75 if (buffer_pointer)
76 *buffer_pointer = 4 * (fw_flags2 & ENE_FW2_BUF_HIGH);
77
78 if (dev->hw_revision < ENE_HW_C) {
79 irq_status = ene_hw_read_reg(dev, ENEB_IRQ_STATUS);
80
81 if (!(irq_status & ENEB_IRQ_STATUS_IR))
82 return 0;
83 ene_hw_write_reg(dev, ENEB_IRQ_STATUS,
84 irq_status & ~ENEB_IRQ_STATUS_IR);
85
86 /* rev B support only recieving */
87 return ENE_IRQ_RX;
88 }
89
90 irq_status = ene_hw_read_reg(dev, ENEC_IRQ);
91
92 if (!(irq_status & ENEC_IRQ_STATUS))
93 return 0;
94
95 /* original driver does that twice - a workaround ? */
96 ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS);
97 ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS);
98
99 /* clear unknown flag in F8F9 */
100 if (fw_flags2 & ENE_FW2_IRQ_CLR)
101 ene_hw_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_IRQ_CLR);
102
103 /* check if this is a TX interrupt */
104 fw_flags1 = ene_hw_read_reg(dev, ENE_FW1);
105
106 if (fw_flags1 & ENE_FW1_TXIRQ) {
107 ene_hw_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ);
108 return ENE_IRQ_TX;
109 } else
110 return ENE_IRQ_RX;
111}
112
113static int ene_hw_detect(struct ene_device *dev)
114{
115 u8 chip_major, chip_minor;
116 u8 hw_revision, old_ver;
117 u8 tmp;
118 u8 fw_capabilities;
119
120 tmp = ene_hw_read_reg(dev, ENE_HW_UNK);
121 ene_hw_write_reg(dev, ENE_HW_UNK, tmp & ~ENE_HW_UNK_CLR);
122
123 chip_major = ene_hw_read_reg(dev, ENE_HW_VER_MAJOR);
124 chip_minor = ene_hw_read_reg(dev, ENE_HW_VER_MINOR);
125
126 ene_hw_write_reg(dev, ENE_HW_UNK, tmp);
127 hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION);
128 old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD);
129
130 if (hw_revision == 0xFF) {
131
132 ene_printk(KERN_WARNING, "device seems to be disabled\n");
133 ene_printk(KERN_WARNING,
134 "send a mail to lirc-list@lists.sourceforge.net\n");
135 ene_printk(KERN_WARNING, "please attach output of acpidump\n");
136
137 return -ENODEV;
138 }
139
140 if (chip_major == 0x33) {
141 ene_printk(KERN_WARNING, "chips 0x33xx aren't supported yet\n");
142 return -ENODEV;
143 }
144
145 if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) {
146 dev->hw_revision = ENE_HW_C;
147 ene_printk(KERN_WARNING,
148 "KB3926C detected, driver support is not complete!\n");
149
150 } else if (old_ver == 0x24 && hw_revision == 0xC0) {
151 dev->hw_revision = ENE_HW_B;
152 ene_printk(KERN_NOTICE, "KB3926B detected\n");
153 } else {
154 dev->hw_revision = ENE_HW_D;
155 ene_printk(KERN_WARNING,
156 "unknown ENE chip detected, assuming KB3926D\n");
157 ene_printk(KERN_WARNING, "driver support incomplete");
158
159 }
160
161 ene_printk(KERN_DEBUG, "chip is 0x%02x%02x - 0x%02x, 0x%02x\n",
162 chip_major, chip_minor, old_ver, hw_revision);
163
164
165 /* detect features hardware supports */
166
167 if (dev->hw_revision < ENE_HW_C)
168 return 0;
169
170 fw_capabilities = ene_hw_read_reg(dev, ENE_FW2);
171
172 dev->hw_gpio40_learning = fw_capabilities & ENE_FW2_GP40_AS_LEARN;
173 dev->hw_learning_and_tx_capable = fw_capabilities & ENE_FW2_LEARNING;
174
175 dev->hw_fan_as_normal_input = dev->hw_learning_and_tx_capable &&
176 fw_capabilities & ENE_FW2_FAN_AS_NRML_IN;
177
178 ene_printk(KERN_NOTICE, "hardware features:\n");
179 ene_printk(KERN_NOTICE,
180 "learning and tx %s, gpio40_learn %s, fan_in %s\n",
181 dev->hw_learning_and_tx_capable ? "on" : "off",
182 dev->hw_gpio40_learning ? "on" : "off",
183 dev->hw_fan_as_normal_input ? "on" : "off");
184
185 if (!dev->hw_learning_and_tx_capable && enable_learning)
186 enable_learning = 0;
187
188 if (dev->hw_learning_and_tx_capable) {
189 ene_printk(KERN_WARNING,
190 "Device supports transmitting, but the driver doesn't\n");
191 ene_printk(KERN_WARNING,
192 "due to lack of hardware to test against.\n");
193 ene_printk(KERN_WARNING,
194 "Send a mail to: lirc-list@lists.sourceforge.net\n");
195 }
196 return 0;
197}
198
199/* hardware initialization */
200static int ene_hw_init(void *data)
201{
202 u8 reg_value;
203 struct ene_device *dev = (struct ene_device *)data;
204 dev->in_use = 1;
205
206 if (dev->hw_revision < ENE_HW_C) {
207 ene_hw_write_reg(dev, ENEB_IRQ, dev->irq << 1);
208 ene_hw_write_reg(dev, ENEB_IRQ_UNK1, 0x01);
209 } else {
210 reg_value = ene_hw_read_reg(dev, ENEC_IRQ) & 0xF0;
211 reg_value |= ENEC_IRQ_UNK_EN;
212 reg_value &= ~ENEC_IRQ_STATUS;
213 reg_value |= (dev->irq & ENEC_IRQ_MASK);
214 ene_hw_write_reg(dev, ENEC_IRQ, reg_value);
215 ene_hw_write_reg(dev, ENE_TX_UNK1, 0x63);
216 }
217
218 ene_hw_write_reg(dev, ENE_CIR_CONF2, 0x00);
219 ene_set_inputs(dev, enable_learning);
220
221 /* set sampling period */
222 ene_hw_write_reg(dev, ENE_CIR_SAMPLE_PERIOD, sample_period);
223
224 /* ack any pending irqs - just in case */
225 ene_hw_irq_status(dev, NULL);
226
227 /* enter idle mode */
228 ene_set_idle(dev, 1);
229
230 /* enable firmware bits */
231 ene_hw_write_reg_mask(dev, ENE_FW1,
232 ENE_FW1_ENABLE | ENE_FW1_IRQ,
233 ENE_FW1_ENABLE | ENE_FW1_IRQ);
234 /* clear stats */
235 dev->sample = 0;
236 return 0;
237}
238
239/* this enables gpio40 signal, used if connected to wide band input*/
240static void ene_enable_gpio40(struct ene_device *dev, int enable)
241{
242 ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, enable ?
243 0 : ENE_CIR_CONF2_GPIO40DIS,
244 ENE_CIR_CONF2_GPIO40DIS);
245}
246
247/* this enables the classic sampler */
248static void ene_enable_normal_recieve(struct ene_device *dev, int enable)
249{
250 ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_ADC_ON : 0);
251}
252
253/* this enables recieve via fan input */
254static void ene_enable_fan_recieve(struct ene_device *dev, int enable)
255{
256 if (!enable)
257 ene_hw_write_reg(dev, ENE_FAN_AS_IN1, 0);
258 else {
259 ene_hw_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN);
260 ene_hw_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN);
261 }
262 dev->fan_input_inuse = enable;
263}
264
265/* determine which input to use*/
266static void ene_set_inputs(struct ene_device *dev, int learning_enable)
267{
268 ene_enable_normal_recieve(dev, 1);
269
270 /* old hardware doesn't support learning mode for sure */
271 if (dev->hw_revision <= ENE_HW_B)
272 return;
273
274 /* reciever not learning capable, still set gpio40 correctly */
275 if (!dev->hw_learning_and_tx_capable) {
276 ene_enable_gpio40(dev, !dev->hw_gpio40_learning);
277 return;
278 }
279
280 /* enable learning mode */
281 if (learning_enable) {
282 ene_enable_gpio40(dev, dev->hw_gpio40_learning);
283
284 /* fan input is not used for learning */
285 if (dev->hw_fan_as_normal_input)
286 ene_enable_fan_recieve(dev, 0);
287
288 /* disable learning mode */
289 } else {
290 if (dev->hw_fan_as_normal_input) {
291 ene_enable_fan_recieve(dev, 1);
292 ene_enable_normal_recieve(dev, 0);
293 } else
294 ene_enable_gpio40(dev, !dev->hw_gpio40_learning);
295 }
296
297 /* set few additional settings for this mode */
298 ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, learning_enable ?
299 ENE_CIR_CONF1_LEARN1 : 0, ENE_CIR_CONF1_LEARN1);
300
301 ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, learning_enable ?
302 ENE_CIR_CONF2_LEARN2 : 0, ENE_CIR_CONF2_LEARN2);
303}
304
305/* deinitialization */
306static void ene_hw_deinit(void *data)
307{
308 struct ene_device *dev = (struct ene_device *)data;
309
310 /* disable samplers */
311 ene_enable_normal_recieve(dev, 0);
312
313 if (dev->hw_fan_as_normal_input)
314 ene_enable_fan_recieve(dev, 0);
315
316 /* disable hardware IRQ and firmware flag */
317 ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_ENABLE | ENE_FW1_IRQ);
318
319 ene_set_idle(dev, 1);
320 dev->in_use = 0;
321}
322
323/* sends current sample to userspace */
324static void send_sample(struct ene_device *dev)
325{
326 int value = abs(dev->sample) & PULSE_MASK;
327
328 if (dev->sample > 0)
329 value |= PULSE_BIT;
330
331 if (!lirc_buffer_full(dev->lirc_driver->rbuf)) {
332 lirc_buffer_write(dev->lirc_driver->rbuf, (void *)&value);
333 wake_up(&dev->lirc_driver->rbuf->wait_poll);
334 }
335 dev->sample = 0;
336}
337
338/* this updates current sample */
339static void update_sample(struct ene_device *dev, int sample)
340{
341 if (!dev->sample)
342 dev->sample = sample;
343 else if (same_sign(dev->sample, sample))
344 dev->sample += sample;
345 else {
346 send_sample(dev);
347 dev->sample = sample;
348 }
349}
350
351/* enable or disable idle mode */
352static void ene_set_idle(struct ene_device *dev, int idle)
353{
354 struct timeval now;
355 int disable = idle && enable_idle && (dev->hw_revision < ENE_HW_C);
356
357 ene_hw_write_reg_mask(dev, ENE_CIR_SAMPLE_PERIOD,
358 disable ? 0 : ENE_CIR_SAMPLE_OVERFLOW,
359 ENE_CIR_SAMPLE_OVERFLOW);
360 dev->idle = idle;
361
362 /* remember when we have entered the idle mode */
363 if (idle) {
364 do_gettimeofday(&dev->gap_start);
365 return;
366 }
367
368 /* send the gap between keypresses now */
369 do_gettimeofday(&now);
370
371 if (now.tv_sec - dev->gap_start.tv_sec > 16)
372 dev->sample = space(PULSE_MASK);
373 else
374 dev->sample = dev->sample +
375 space(1000000ull * (now.tv_sec - dev->gap_start.tv_sec))
376 + space(now.tv_usec - dev->gap_start.tv_usec);
377
378 if (abs(dev->sample) > PULSE_MASK)
379 dev->sample = space(PULSE_MASK);
380 send_sample(dev);
381}
382
383/* interrupt handler */
384static irqreturn_t ene_hw_irq(int irq, void *data)
385{
386 u16 hw_value;
387 int i, hw_sample;
388 int space;
389 int buffer_pointer;
390 int irq_status;
391
392 struct ene_device *dev = (struct ene_device *)data;
393 irq_status = ene_hw_irq_status(dev, &buffer_pointer);
394
395 if (!irq_status)
396 return IRQ_NONE;
397
398 /* TODO: only RX for now */
399 if (irq_status == ENE_IRQ_TX)
400 return IRQ_HANDLED;
401
402 for (i = 0; i < ENE_SAMPLES_SIZE; i++) {
403
404 hw_value = ene_hw_read_reg(dev,
405 ENE_SAMPLE_BUFFER + buffer_pointer + i);
406
407 if (dev->fan_input_inuse) {
408 /* read high part of the sample */
409 hw_value |= ene_hw_read_reg(dev,
410 ENE_SAMPLE_BUFFER_FAN + buffer_pointer + i) << 8;
411
412 /* test for _space_ bit */
413 space = !(hw_value & ENE_FAN_SMPL_PULS_MSK);
414
415 /* clear space bit, and other unused bits */
416 hw_value &= ENE_FAN_VALUE_MASK;
417 hw_sample = hw_value * ENE_SAMPLE_PERIOD_FAN;
418
419 } else {
420 space = hw_value & ENE_SAMPLE_SPC_MASK;
421 hw_value &= ENE_SAMPLE_VALUE_MASK;
422 hw_sample = hw_value * sample_period;
423 }
424
425 /* no more data */
426 if (!(hw_value))
427 break;
428
429 if (space)
430 hw_sample *= -1;
431
432 /* overflow sample recieved, handle it */
433
434 if (!dev->fan_input_inuse && hw_value == ENE_SAMPLE_OVERFLOW) {
435
436 if (dev->idle)
437 continue;
438
439 if (dev->sample > 0 || abs(dev->sample) <= ENE_MAXGAP)
440 update_sample(dev, hw_sample);
441 else
442 ene_set_idle(dev, 1);
443
444 continue;
445 }
446
447 /* normal first sample recieved */
448 if (!dev->fan_input_inuse && dev->idle) {
449 ene_set_idle(dev, 0);
450
451 /* discard first recieved value, its random
452 since its the time signal was off before
453 first pulse if idle mode is enabled, HW
454 does that for us */
455
456 if (!enable_idle)
457 continue;
458 }
459 update_sample(dev, hw_sample);
460 send_sample(dev);
461 }
462 return IRQ_HANDLED;
463}
464
465static int ene_probe(struct pnp_dev *pnp_dev,
466 const struct pnp_device_id *dev_id)
467{
468 struct ene_device *dev;
469 struct lirc_driver *lirc_driver;
470 int error = -ENOMEM;
471
472 dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
473
474 if (!dev)
475 goto err1;
476
477 dev->pnp_dev = pnp_dev;
478 pnp_set_drvdata(pnp_dev, dev);
479
480
481 /* prepare lirc interface */
482 error = -ENOMEM;
483 lirc_driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
484
485 if (!lirc_driver)
486 goto err2;
487
488 dev->lirc_driver = lirc_driver;
489
490 strcpy(lirc_driver->name, ENE_DRIVER_NAME);
491 lirc_driver->minor = -1;
492 lirc_driver->code_length = sizeof(int) * 8;
493 lirc_driver->features = LIRC_CAN_REC_MODE2;
494 lirc_driver->data = dev;
495 lirc_driver->set_use_inc = ene_hw_init;
496 lirc_driver->set_use_dec = ene_hw_deinit;
497 lirc_driver->dev = &pnp_dev->dev;
498 lirc_driver->owner = THIS_MODULE;
499
500 lirc_driver->rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
501
502 if (!lirc_driver->rbuf)
503 goto err3;
504
505 if (lirc_buffer_init(lirc_driver->rbuf, sizeof(int), sizeof(int) * 256))
506 goto err4;
507
508 error = -ENODEV;
509 if (lirc_register_driver(lirc_driver))
510 goto err5;
511
512 /* validate resources */
513 if (!pnp_port_valid(pnp_dev, 0) ||
514 pnp_port_len(pnp_dev, 0) < ENE_MAX_IO)
515 goto err6;
516
517 if (!pnp_irq_valid(pnp_dev, 0))
518 goto err6;
519
520 dev->hw_io = pnp_port_start(pnp_dev, 0);
521 dev->irq = pnp_irq(pnp_dev, 0);
522
523 /* claim the resources */
524 error = -EBUSY;
525 if (!request_region(dev->hw_io, ENE_MAX_IO, ENE_DRIVER_NAME))
526 goto err6;
527
528 if (request_irq(dev->irq, ene_hw_irq,
529 IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev))
530 goto err7;
531
532 /* detect hardware version and features */
533 error = ene_hw_detect(dev);
534 if (error)
535 goto err8;
536
537 ene_printk(KERN_NOTICE, "driver has been succesfully loaded\n");
538 return 0;
539
540err8:
541 free_irq(dev->irq, dev);
542err7:
543 release_region(dev->hw_io, ENE_MAX_IO);
544err6:
545 lirc_unregister_driver(lirc_driver->minor);
546err5:
547 lirc_buffer_free(lirc_driver->rbuf);
548err4:
549 kfree(lirc_driver->rbuf);
550err3:
551 kfree(lirc_driver);
552err2:
553 kfree(dev);
554err1:
555 return error;
556}
557
558static void ene_remove(struct pnp_dev *pnp_dev)
559{
560 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
561 ene_hw_deinit(dev);
562 free_irq(dev->irq, dev);
563 release_region(dev->hw_io, ENE_MAX_IO);
564 lirc_unregister_driver(dev->lirc_driver->minor);
565 lirc_buffer_free(dev->lirc_driver->rbuf);
566 kfree(dev->lirc_driver);
567 kfree(dev);
568}
569
570#ifdef CONFIG_PM
571
572/* TODO: make 'wake on IR' configurable and add .shutdown */
573/* currently impossible due to lack of kernel support */
574
575static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
576{
577 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
578 ene_hw_write_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, ENE_FW1_WAKE);
579 return 0;
580}
581
582static int ene_resume(struct pnp_dev *pnp_dev)
583{
584 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
585 if (dev->in_use)
586 ene_hw_init(dev);
587
588 ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_WAKE);
589 return 0;
590}
591
592#endif
593
594static const struct pnp_device_id ene_ids[] = {
595 {.id = "ENE0100",},
596 {},
597};
598
599static struct pnp_driver ene_driver = {
600 .name = ENE_DRIVER_NAME,
601 .id_table = ene_ids,
602 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
603
604 .probe = ene_probe,
605 .remove = __devexit_p(ene_remove),
606
607#ifdef CONFIG_PM
608 .suspend = ene_suspend,
609 .resume = ene_resume,
610#endif
611};
612
613static int __init ene_init(void)
614{
615 if (sample_period < 5) {
616 ene_printk(KERN_ERR, "sample period must be at\n");
617 ene_printk(KERN_ERR, "least 5 us, (at least 30 recommended)\n");
618 return -EINVAL;
619 }
620 return pnp_register_driver(&ene_driver);
621}
622
623static void ene_exit(void)
624{
625 pnp_unregister_driver(&ene_driver);
626}
627
628module_param(sample_period, int, S_IRUGO);
629MODULE_PARM_DESC(sample_period, "Hardware sample period (75 us default)");
630
631module_param(enable_idle, bool, S_IRUGO | S_IWUSR);
632MODULE_PARM_DESC(enable_idle,
633 "Enables turning off signal sampling after long inactivity time; "
634 "if disabled might help detecting input signal (default: enabled)");
635
636module_param(enable_learning, bool, S_IRUGO);
637MODULE_PARM_DESC(enable_learning, "Use wide band (learning) reciever");
638
639MODULE_DEVICE_TABLE(pnp, ene_ids);
640MODULE_DESCRIPTION
641 ("LIRC driver for KB3926B/KB3926C/KB3926D (aka ENE0100) CIR port");
642MODULE_AUTHOR("Maxim Levitsky");
643MODULE_LICENSE("GPL");
644
645module_init(ene_init);
646module_exit(ene_exit);