Merge tag 'mips_5.18_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
[linux-2.6-microblaze.git] / drivers / media / rc / fintek-cir.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Driver for Feature Integration Technology Inc. (aka Fintek) LPC CIR
4  *
5  * Copyright (C) 2011 Jarod Wilson <jarod@redhat.com>
6  *
7  * Special thanks to Fintek for providing hardware and spec sheets.
8  * This driver is based upon the nuvoton, ite and ene drivers for
9  * similar hardware.
10  */
11
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/pnp.h>
17 #include <linux/io.h>
18 #include <linux/interrupt.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
21 #include <media/rc-core.h>
22
23 #include "fintek-cir.h"
24
25 /* write val to config reg */
26 static inline void fintek_cr_write(struct fintek_dev *fintek, u8 val, u8 reg)
27 {
28         fit_dbg("%s: reg 0x%02x, val 0x%02x  (ip/dp: %02x/%02x)",
29                 __func__, reg, val, fintek->cr_ip, fintek->cr_dp);
30         outb(reg, fintek->cr_ip);
31         outb(val, fintek->cr_dp);
32 }
33
34 /* read val from config reg */
35 static inline u8 fintek_cr_read(struct fintek_dev *fintek, u8 reg)
36 {
37         u8 val;
38
39         outb(reg, fintek->cr_ip);
40         val = inb(fintek->cr_dp);
41
42         fit_dbg("%s: reg 0x%02x, val 0x%02x  (ip/dp: %02x/%02x)",
43                 __func__, reg, val, fintek->cr_ip, fintek->cr_dp);
44         return val;
45 }
46
47 /* update config register bit without changing other bits */
48 static inline void fintek_set_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg)
49 {
50         u8 tmp = fintek_cr_read(fintek, reg) | val;
51         fintek_cr_write(fintek, tmp, reg);
52 }
53
54 /* enter config mode */
55 static inline void fintek_config_mode_enable(struct fintek_dev *fintek)
56 {
57         /* Enabling Config Mode explicitly requires writing 2x */
58         outb(CONFIG_REG_ENABLE, fintek->cr_ip);
59         outb(CONFIG_REG_ENABLE, fintek->cr_ip);
60 }
61
62 /* exit config mode */
63 static inline void fintek_config_mode_disable(struct fintek_dev *fintek)
64 {
65         outb(CONFIG_REG_DISABLE, fintek->cr_ip);
66 }
67
68 /*
69  * When you want to address a specific logical device, write its logical
70  * device number to GCR_LOGICAL_DEV_NO
71  */
72 static inline void fintek_select_logical_dev(struct fintek_dev *fintek, u8 ldev)
73 {
74         fintek_cr_write(fintek, ldev, GCR_LOGICAL_DEV_NO);
75 }
76
77 /* write val to cir config register */
78 static inline void fintek_cir_reg_write(struct fintek_dev *fintek, u8 val, u8 offset)
79 {
80         outb(val, fintek->cir_addr + offset);
81 }
82
83 /* read val from cir config register */
84 static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset)
85 {
86         return inb(fintek->cir_addr + offset);
87 }
88
89 /* dump current cir register contents */
90 static void cir_dump_regs(struct fintek_dev *fintek)
91 {
92         fintek_config_mode_enable(fintek);
93         fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
94
95         pr_info("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME);
96         pr_info(" * CR CIR BASE ADDR: 0x%x\n",
97                 (fintek_cr_read(fintek, CIR_CR_BASE_ADDR_HI) << 8) |
98                 fintek_cr_read(fintek, CIR_CR_BASE_ADDR_LO));
99         pr_info(" * CR CIR IRQ NUM:   0x%x\n",
100                 fintek_cr_read(fintek, CIR_CR_IRQ_SEL));
101
102         fintek_config_mode_disable(fintek);
103
104         pr_info("%s: Dump CIR registers:\n", FINTEK_DRIVER_NAME);
105         pr_info(" * STATUS:     0x%x\n",
106                 fintek_cir_reg_read(fintek, CIR_STATUS));
107         pr_info(" * CONTROL:    0x%x\n",
108                 fintek_cir_reg_read(fintek, CIR_CONTROL));
109         pr_info(" * RX_DATA:    0x%x\n",
110                 fintek_cir_reg_read(fintek, CIR_RX_DATA));
111         pr_info(" * TX_CONTROL: 0x%x\n",
112                 fintek_cir_reg_read(fintek, CIR_TX_CONTROL));
113         pr_info(" * TX_DATA:    0x%x\n",
114                 fintek_cir_reg_read(fintek, CIR_TX_DATA));
115 }
116
117 /* detect hardware features */
118 static int fintek_hw_detect(struct fintek_dev *fintek)
119 {
120         unsigned long flags;
121         u8 chip_major, chip_minor;
122         u8 vendor_major, vendor_minor;
123         u8 portsel, ir_class;
124         u16 vendor, chip;
125
126         fintek_config_mode_enable(fintek);
127
128         /* Check if we're using config port 0x4e or 0x2e */
129         portsel = fintek_cr_read(fintek, GCR_CONFIG_PORT_SEL);
130         if (portsel == 0xff) {
131                 fit_pr(KERN_INFO, "first portsel read was bunk, trying alt");
132                 fintek_config_mode_disable(fintek);
133                 fintek->cr_ip = CR_INDEX_PORT2;
134                 fintek->cr_dp = CR_DATA_PORT2;
135                 fintek_config_mode_enable(fintek);
136                 portsel = fintek_cr_read(fintek, GCR_CONFIG_PORT_SEL);
137         }
138         fit_dbg("portsel reg: 0x%02x", portsel);
139
140         ir_class = fintek_cir_reg_read(fintek, CIR_CR_CLASS);
141         fit_dbg("ir_class reg: 0x%02x", ir_class);
142
143         switch (ir_class) {
144         case CLASS_RX_2TX:
145         case CLASS_RX_1TX:
146                 fintek->hw_tx_capable = true;
147                 break;
148         case CLASS_RX_ONLY:
149         default:
150                 fintek->hw_tx_capable = false;
151                 break;
152         }
153
154         chip_major = fintek_cr_read(fintek, GCR_CHIP_ID_HI);
155         chip_minor = fintek_cr_read(fintek, GCR_CHIP_ID_LO);
156         chip  = chip_major << 8 | chip_minor;
157
158         vendor_major = fintek_cr_read(fintek, GCR_VENDOR_ID_HI);
159         vendor_minor = fintek_cr_read(fintek, GCR_VENDOR_ID_LO);
160         vendor = vendor_major << 8 | vendor_minor;
161
162         if (vendor != VENDOR_ID_FINTEK)
163                 fit_pr(KERN_WARNING, "Unknown vendor ID: 0x%04x", vendor);
164         else
165                 fit_dbg("Read Fintek vendor ID from chip");
166
167         fintek_config_mode_disable(fintek);
168
169         spin_lock_irqsave(&fintek->fintek_lock, flags);
170         fintek->chip_major  = chip_major;
171         fintek->chip_minor  = chip_minor;
172         fintek->chip_vendor = vendor;
173
174         /*
175          * Newer reviews of this chipset uses port 8 instead of 5
176          */
177         if ((chip != 0x0408) && (chip != 0x0804))
178                 fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV2;
179         else
180                 fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV1;
181
182         spin_unlock_irqrestore(&fintek->fintek_lock, flags);
183
184         return 0;
185 }
186
187 static void fintek_cir_ldev_init(struct fintek_dev *fintek)
188 {
189         /* Select CIR logical device and enable */
190         fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
191         fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
192
193         /* Write allocated CIR address and IRQ information to hardware */
194         fintek_cr_write(fintek, fintek->cir_addr >> 8, CIR_CR_BASE_ADDR_HI);
195         fintek_cr_write(fintek, fintek->cir_addr & 0xff, CIR_CR_BASE_ADDR_LO);
196
197         fintek_cr_write(fintek, fintek->cir_irq, CIR_CR_IRQ_SEL);
198
199         fit_dbg("CIR initialized, base io address: 0x%lx, irq: %d (len: %d)",
200                 fintek->cir_addr, fintek->cir_irq, fintek->cir_port_len);
201 }
202
203 /* enable CIR interrupts */
204 static void fintek_enable_cir_irq(struct fintek_dev *fintek)
205 {
206         fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_EN, CIR_STATUS);
207 }
208
209 static void fintek_cir_regs_init(struct fintek_dev *fintek)
210 {
211         /* clear any and all stray interrupts */
212         fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
213
214         /* and finally, enable interrupts */
215         fintek_enable_cir_irq(fintek);
216 }
217
218 static void fintek_enable_wake(struct fintek_dev *fintek)
219 {
220         fintek_config_mode_enable(fintek);
221         fintek_select_logical_dev(fintek, LOGICAL_DEV_ACPI);
222
223         /* Allow CIR PME's to wake system */
224         fintek_set_reg_bit(fintek, ACPI_WAKE_EN_CIR_BIT, LDEV_ACPI_WAKE_EN_REG);
225         /* Enable CIR PME's */
226         fintek_set_reg_bit(fintek, ACPI_PME_CIR_BIT, LDEV_ACPI_PME_EN_REG);
227         /* Clear CIR PME status register */
228         fintek_set_reg_bit(fintek, ACPI_PME_CIR_BIT, LDEV_ACPI_PME_CLR_REG);
229         /* Save state */
230         fintek_set_reg_bit(fintek, ACPI_STATE_CIR_BIT, LDEV_ACPI_STATE_REG);
231
232         fintek_config_mode_disable(fintek);
233 }
234
235 static int fintek_cmdsize(u8 cmd, u8 subcmd)
236 {
237         int datasize = 0;
238
239         switch (cmd) {
240         case BUF_COMMAND_NULL:
241                 if (subcmd == BUF_HW_CMD_HEADER)
242                         datasize = 1;
243                 break;
244         case BUF_HW_CMD_HEADER:
245                 if (subcmd == BUF_CMD_G_REVISION)
246                         datasize = 2;
247                 break;
248         case BUF_COMMAND_HEADER:
249                 switch (subcmd) {
250                 case BUF_CMD_S_CARRIER:
251                 case BUF_CMD_S_TIMEOUT:
252                 case BUF_RSP_PULSE_COUNT:
253                         datasize = 2;
254                         break;
255                 case BUF_CMD_SIG_END:
256                 case BUF_CMD_S_TXMASK:
257                 case BUF_CMD_S_RXSENSOR:
258                         datasize = 1;
259                         break;
260                 }
261         }
262
263         return datasize;
264 }
265
266 /* process ir data stored in driver buffer */
267 static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
268 {
269         struct ir_raw_event rawir = {};
270         u8 sample;
271         bool event = false;
272         int i;
273
274         for (i = 0; i < fintek->pkts; i++) {
275                 sample = fintek->buf[i];
276                 switch (fintek->parser_state) {
277                 case CMD_HEADER:
278                         fintek->cmd = sample;
279                         if ((fintek->cmd == BUF_COMMAND_HEADER) ||
280                             ((fintek->cmd & BUF_COMMAND_MASK) !=
281                              BUF_PULSE_BIT)) {
282                                 fintek->parser_state = SUBCMD;
283                                 continue;
284                         }
285                         fintek->rem = (fintek->cmd & BUF_LEN_MASK);
286                         fit_dbg("%s: rem: 0x%02x", __func__, fintek->rem);
287                         if (fintek->rem)
288                                 fintek->parser_state = PARSE_IRDATA;
289                         else
290                                 ir_raw_event_overflow(fintek->rdev);
291                         break;
292                 case SUBCMD:
293                         fintek->rem = fintek_cmdsize(fintek->cmd, sample);
294                         fintek->parser_state = CMD_DATA;
295                         break;
296                 case CMD_DATA:
297                         fintek->rem--;
298                         break;
299                 case PARSE_IRDATA:
300                         fintek->rem--;
301                         rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
302                         rawir.duration = (sample & BUF_SAMPLE_MASK)
303                                           * CIR_SAMPLE_PERIOD;
304
305                         fit_dbg("Storing %s with duration %d",
306                                 rawir.pulse ? "pulse" : "space",
307                                 rawir.duration);
308                         if (ir_raw_event_store_with_filter(fintek->rdev,
309                                                                         &rawir))
310                                 event = true;
311                         break;
312                 }
313
314                 if ((fintek->parser_state != CMD_HEADER) && !fintek->rem)
315                         fintek->parser_state = CMD_HEADER;
316         }
317
318         fintek->pkts = 0;
319
320         if (event) {
321                 fit_dbg("Calling ir_raw_event_handle");
322                 ir_raw_event_handle(fintek->rdev);
323         }
324 }
325
326 /* copy data from hardware rx register into driver buffer */
327 static void fintek_get_rx_ir_data(struct fintek_dev *fintek, u8 rx_irqs)
328 {
329         unsigned long flags;
330         u8 sample, status;
331
332         spin_lock_irqsave(&fintek->fintek_lock, flags);
333
334         /*
335          * We must read data from CIR_RX_DATA until the hardware IR buffer
336          * is empty and clears the RX_TIMEOUT and/or RX_RECEIVE flags in
337          * the CIR_STATUS register
338          */
339         do {
340                 sample = fintek_cir_reg_read(fintek, CIR_RX_DATA);
341                 fit_dbg("%s: sample: 0x%02x", __func__, sample);
342
343                 fintek->buf[fintek->pkts] = sample;
344                 fintek->pkts++;
345
346                 status = fintek_cir_reg_read(fintek, CIR_STATUS);
347                 if (!(status & CIR_STATUS_IRQ_EN))
348                         break;
349         } while (status & rx_irqs);
350
351         fintek_process_rx_ir_data(fintek);
352
353         spin_unlock_irqrestore(&fintek->fintek_lock, flags);
354 }
355
356 static void fintek_cir_log_irqs(u8 status)
357 {
358         fit_pr(KERN_INFO, "IRQ 0x%02x:%s%s%s%s%s", status,
359                 status & CIR_STATUS_IRQ_EN      ? " IRQEN"      : "",
360                 status & CIR_STATUS_TX_FINISH   ? " TXF"        : "",
361                 status & CIR_STATUS_TX_UNDERRUN ? " TXU"        : "",
362                 status & CIR_STATUS_RX_TIMEOUT  ? " RXTO"       : "",
363                 status & CIR_STATUS_RX_RECEIVE  ? " RXOK"       : "");
364 }
365
366 /* interrupt service routine for incoming and outgoing CIR data */
367 static irqreturn_t fintek_cir_isr(int irq, void *data)
368 {
369         struct fintek_dev *fintek = data;
370         u8 status, rx_irqs;
371
372         fit_dbg_verbose("%s firing", __func__);
373
374         fintek_config_mode_enable(fintek);
375         fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
376         fintek_config_mode_disable(fintek);
377
378         /*
379          * Get IR Status register contents. Write 1 to ack/clear
380          *
381          * bit: reg name    - description
382          *   3: TX_FINISH   - TX is finished
383          *   2: TX_UNDERRUN - TX underrun
384          *   1: RX_TIMEOUT  - RX data timeout
385          *   0: RX_RECEIVE  - RX data received
386          */
387         status = fintek_cir_reg_read(fintek, CIR_STATUS);
388         if (!(status & CIR_STATUS_IRQ_MASK) || status == 0xff) {
389                 fit_dbg_verbose("%s exiting, IRSTS 0x%02x", __func__, status);
390                 fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
391                 return IRQ_RETVAL(IRQ_NONE);
392         }
393
394         if (debug)
395                 fintek_cir_log_irqs(status);
396
397         rx_irqs = status & (CIR_STATUS_RX_RECEIVE | CIR_STATUS_RX_TIMEOUT);
398         if (rx_irqs)
399                 fintek_get_rx_ir_data(fintek, rx_irqs);
400
401         /* ack/clear all irq flags we've got */
402         fintek_cir_reg_write(fintek, status, CIR_STATUS);
403
404         fit_dbg_verbose("%s done", __func__);
405         return IRQ_RETVAL(IRQ_HANDLED);
406 }
407
408 static void fintek_enable_cir(struct fintek_dev *fintek)
409 {
410         /* set IRQ enabled */
411         fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_EN, CIR_STATUS);
412
413         fintek_config_mode_enable(fintek);
414
415         /* enable the CIR logical device */
416         fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
417         fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
418
419         fintek_config_mode_disable(fintek);
420
421         /* clear all pending interrupts */
422         fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
423
424         /* enable interrupts */
425         fintek_enable_cir_irq(fintek);
426 }
427
428 static void fintek_disable_cir(struct fintek_dev *fintek)
429 {
430         fintek_config_mode_enable(fintek);
431
432         /* disable the CIR logical device */
433         fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
434         fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
435
436         fintek_config_mode_disable(fintek);
437 }
438
439 static int fintek_open(struct rc_dev *dev)
440 {
441         struct fintek_dev *fintek = dev->priv;
442         unsigned long flags;
443
444         spin_lock_irqsave(&fintek->fintek_lock, flags);
445         fintek_enable_cir(fintek);
446         spin_unlock_irqrestore(&fintek->fintek_lock, flags);
447
448         return 0;
449 }
450
451 static void fintek_close(struct rc_dev *dev)
452 {
453         struct fintek_dev *fintek = dev->priv;
454         unsigned long flags;
455
456         spin_lock_irqsave(&fintek->fintek_lock, flags);
457         fintek_disable_cir(fintek);
458         spin_unlock_irqrestore(&fintek->fintek_lock, flags);
459 }
460
461 /* Allocate memory, probe hardware, and initialize everything */
462 static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
463 {
464         struct fintek_dev *fintek;
465         struct rc_dev *rdev;
466         int ret = -ENOMEM;
467
468         fintek = kzalloc(sizeof(struct fintek_dev), GFP_KERNEL);
469         if (!fintek)
470                 return ret;
471
472         /* input device for IR remote (and tx) */
473         rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
474         if (!rdev)
475                 goto exit_free_dev_rdev;
476
477         ret = -ENODEV;
478         /* validate pnp resources */
479         if (!pnp_port_valid(pdev, 0)) {
480                 dev_err(&pdev->dev, "IR PNP Port not valid!\n");
481                 goto exit_free_dev_rdev;
482         }
483
484         if (!pnp_irq_valid(pdev, 0)) {
485                 dev_err(&pdev->dev, "IR PNP IRQ not valid!\n");
486                 goto exit_free_dev_rdev;
487         }
488
489         fintek->cir_addr = pnp_port_start(pdev, 0);
490         fintek->cir_irq  = pnp_irq(pdev, 0);
491         fintek->cir_port_len = pnp_port_len(pdev, 0);
492
493         fintek->cr_ip = CR_INDEX_PORT;
494         fintek->cr_dp = CR_DATA_PORT;
495
496         spin_lock_init(&fintek->fintek_lock);
497
498         pnp_set_drvdata(pdev, fintek);
499         fintek->pdev = pdev;
500
501         ret = fintek_hw_detect(fintek);
502         if (ret)
503                 goto exit_free_dev_rdev;
504
505         /* Initialize CIR & CIR Wake Logical Devices */
506         fintek_config_mode_enable(fintek);
507         fintek_cir_ldev_init(fintek);
508         fintek_config_mode_disable(fintek);
509
510         /* Initialize CIR & CIR Wake Config Registers */
511         fintek_cir_regs_init(fintek);
512
513         /* Set up the rc device */
514         rdev->priv = fintek;
515         rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
516         rdev->open = fintek_open;
517         rdev->close = fintek_close;
518         rdev->device_name = FINTEK_DESCRIPTION;
519         rdev->input_phys = "fintek/cir0";
520         rdev->input_id.bustype = BUS_HOST;
521         rdev->input_id.vendor = VENDOR_ID_FINTEK;
522         rdev->input_id.product = fintek->chip_major;
523         rdev->input_id.version = fintek->chip_minor;
524         rdev->dev.parent = &pdev->dev;
525         rdev->driver_name = FINTEK_DRIVER_NAME;
526         rdev->map_name = RC_MAP_RC6_MCE;
527         rdev->timeout = 1000;
528         /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
529         rdev->rx_resolution = CIR_SAMPLE_PERIOD;
530
531         fintek->rdev = rdev;
532
533         ret = -EBUSY;
534         /* now claim resources */
535         if (!request_region(fintek->cir_addr,
536                             fintek->cir_port_len, FINTEK_DRIVER_NAME))
537                 goto exit_free_dev_rdev;
538
539         if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
540                         FINTEK_DRIVER_NAME, (void *)fintek))
541                 goto exit_free_cir_addr;
542
543         ret = rc_register_device(rdev);
544         if (ret)
545                 goto exit_free_irq;
546
547         device_init_wakeup(&pdev->dev, true);
548
549         fit_pr(KERN_NOTICE, "driver has been successfully loaded\n");
550         if (debug)
551                 cir_dump_regs(fintek);
552
553         return 0;
554
555 exit_free_irq:
556         free_irq(fintek->cir_irq, fintek);
557 exit_free_cir_addr:
558         release_region(fintek->cir_addr, fintek->cir_port_len);
559 exit_free_dev_rdev:
560         rc_free_device(rdev);
561         kfree(fintek);
562
563         return ret;
564 }
565
566 static void fintek_remove(struct pnp_dev *pdev)
567 {
568         struct fintek_dev *fintek = pnp_get_drvdata(pdev);
569         unsigned long flags;
570
571         spin_lock_irqsave(&fintek->fintek_lock, flags);
572         /* disable CIR */
573         fintek_disable_cir(fintek);
574         fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
575         /* enable CIR Wake (for IR power-on) */
576         fintek_enable_wake(fintek);
577         spin_unlock_irqrestore(&fintek->fintek_lock, flags);
578
579         /* free resources */
580         free_irq(fintek->cir_irq, fintek);
581         release_region(fintek->cir_addr, fintek->cir_port_len);
582
583         rc_unregister_device(fintek->rdev);
584
585         kfree(fintek);
586 }
587
588 static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state)
589 {
590         struct fintek_dev *fintek = pnp_get_drvdata(pdev);
591         unsigned long flags;
592
593         fit_dbg("%s called", __func__);
594
595         spin_lock_irqsave(&fintek->fintek_lock, flags);
596
597         /* disable all CIR interrupts */
598         fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
599
600         spin_unlock_irqrestore(&fintek->fintek_lock, flags);
601
602         fintek_config_mode_enable(fintek);
603
604         /* disable cir logical dev */
605         fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
606         fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
607
608         fintek_config_mode_disable(fintek);
609
610         /* make sure wake is enabled */
611         fintek_enable_wake(fintek);
612
613         return 0;
614 }
615
616 static int fintek_resume(struct pnp_dev *pdev)
617 {
618         struct fintek_dev *fintek = pnp_get_drvdata(pdev);
619
620         fit_dbg("%s called", __func__);
621
622         /* open interrupt */
623         fintek_enable_cir_irq(fintek);
624
625         /* Enable CIR logical device */
626         fintek_config_mode_enable(fintek);
627         fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
628         fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
629
630         fintek_config_mode_disable(fintek);
631
632         fintek_cir_regs_init(fintek);
633
634         return 0;
635 }
636
637 static void fintek_shutdown(struct pnp_dev *pdev)
638 {
639         struct fintek_dev *fintek = pnp_get_drvdata(pdev);
640         fintek_enable_wake(fintek);
641 }
642
643 static const struct pnp_device_id fintek_ids[] = {
644         { "FIT0002", 0 },   /* CIR */
645         { "", 0 },
646 };
647
648 static struct pnp_driver fintek_driver = {
649         .name           = FINTEK_DRIVER_NAME,
650         .id_table       = fintek_ids,
651         .flags          = PNP_DRIVER_RES_DO_NOT_CHANGE,
652         .probe          = fintek_probe,
653         .remove         = fintek_remove,
654         .suspend        = fintek_suspend,
655         .resume         = fintek_resume,
656         .shutdown       = fintek_shutdown,
657 };
658
659 module_param(debug, int, S_IRUGO | S_IWUSR);
660 MODULE_PARM_DESC(debug, "Enable debugging output");
661
662 MODULE_DEVICE_TABLE(pnp, fintek_ids);
663 MODULE_DESCRIPTION(FINTEK_DESCRIPTION " driver");
664
665 MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
666 MODULE_LICENSE("GPL");
667
668 module_pnp_driver(fintek_driver);