^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);