Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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