xref: /openbmc/linux/drivers/media/rc/fintek-cir.c (revision 01cc2ec6)
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_reset(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);
669