1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * Driver for Nuvoton Technology Corporation w83667hg/w83677hg-i CIR |
4 | * |
5 | * Copyright (C) 2010 Jarod Wilson <jarod@redhat.com> |
6 | * Copyright (C) 2009 Nuvoton PS Team |
7 | * |
8 | * Special thanks to Nuvoton for providing hardware, spec sheets and |
9 | * sample code upon which portions of this driver are based. Indirect |
10 | * thanks also to Maxim Levitsky, whose ene_ir driver this driver is |
11 | * modeled after. |
12 | */ |
13 | |
14 | #include <linux/spinlock.h> |
15 | #include <linux/ioctl.h> |
16 | |
17 | /* platform driver name to register */ |
18 | #define NVT_DRIVER_NAME "nuvoton-cir" |
19 | |
20 | /* debugging module parameter */ |
21 | static int debug; |
22 | |
23 | |
24 | #define nvt_dbg(text, ...) \ |
25 | if (debug) \ |
26 | printk(KERN_DEBUG \ |
27 | KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) |
28 | |
29 | #define nvt_dbg_verbose(text, ...) \ |
30 | if (debug > 1) \ |
31 | printk(KERN_DEBUG \ |
32 | KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) |
33 | |
34 | #define nvt_dbg_wake(text, ...) \ |
35 | if (debug > 2) \ |
36 | printk(KERN_DEBUG \ |
37 | KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) |
38 | |
39 | |
40 | #define RX_BUF_LEN 32 |
41 | |
42 | #define SIO_ID_MASK 0xfff0 |
43 | |
44 | enum nvt_chip_ver { |
45 | NVT_UNKNOWN = 0, |
46 | NVT_W83667HG = 0xa510, |
47 | NVT_6775F = 0xb470, |
48 | NVT_6776F = 0xc330, |
49 | NVT_6779D = 0xc560, |
50 | NVT_INVALID = 0xffff, |
51 | }; |
52 | |
53 | struct nvt_chip { |
54 | const char *name; |
55 | enum nvt_chip_ver chip_ver; |
56 | }; |
57 | |
58 | struct nvt_dev { |
59 | struct rc_dev *rdev; |
60 | |
61 | spinlock_t lock; |
62 | |
63 | /* for rx */ |
64 | u8 buf[RX_BUF_LEN]; |
65 | unsigned int pkts; |
66 | |
67 | /* EFER Config register index/data pair */ |
68 | u32 cr_efir; |
69 | u32 cr_efdr; |
70 | |
71 | /* hardware I/O settings */ |
72 | unsigned long cir_addr; |
73 | unsigned long cir_wake_addr; |
74 | int cir_irq; |
75 | |
76 | enum nvt_chip_ver chip_ver; |
77 | /* hardware id */ |
78 | u8 chip_major; |
79 | u8 chip_minor; |
80 | |
81 | /* carrier period = 1 / frequency */ |
82 | u32 carrier; |
83 | }; |
84 | |
85 | /* buffer packet constants */ |
86 | #define BUF_PULSE_BIT 0x80 |
87 | #define BUF_LEN_MASK 0x7f |
88 | #define BUF_REPEAT_BYTE 0x70 |
89 | #define BUF_REPEAT_MASK 0xf0 |
90 | |
91 | /* CIR settings */ |
92 | |
93 | /* total length of CIR and CIR WAKE */ |
94 | #define CIR_IOREG_LENGTH 0x0f |
95 | |
96 | /* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL */ |
97 | #define CIR_RX_LIMIT_COUNT (IR_DEFAULT_TIMEOUT / SAMPLE_PERIOD) |
98 | |
99 | /* CIR Regs */ |
100 | #define CIR_IRCON 0x00 |
101 | #define CIR_IRSTS 0x01 |
102 | #define CIR_IREN 0x02 |
103 | #define CIR_RXFCONT 0x03 |
104 | #define CIR_CP 0x04 |
105 | #define CIR_CC 0x05 |
106 | #define CIR_SLCH 0x06 |
107 | #define CIR_SLCL 0x07 |
108 | #define CIR_FIFOCON 0x08 |
109 | #define CIR_IRFIFOSTS 0x09 |
110 | #define CIR_SRXFIFO 0x0a |
111 | #define CIR_TXFCONT 0x0b |
112 | #define CIR_STXFIFO 0x0c |
113 | #define CIR_FCCH 0x0d |
114 | #define CIR_FCCL 0x0e |
115 | #define CIR_IRFSM 0x0f |
116 | |
117 | /* CIR IRCON settings */ |
118 | #define CIR_IRCON_RECV 0x80 |
119 | #define CIR_IRCON_WIREN 0x40 |
120 | #define CIR_IRCON_TXEN 0x20 |
121 | #define CIR_IRCON_RXEN 0x10 |
122 | #define CIR_IRCON_WRXINV 0x08 |
123 | #define CIR_IRCON_RXINV 0x04 |
124 | |
125 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_1 0x00 |
126 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_25 0x01 |
127 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_50 0x02 |
128 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_100 0x03 |
129 | |
130 | /* FIXME: make this a runtime option */ |
131 | /* select sample period as 50us */ |
132 | #define CIR_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 |
133 | |
134 | /* CIR IRSTS settings */ |
135 | #define CIR_IRSTS_RDR 0x80 |
136 | #define CIR_IRSTS_RTR 0x40 |
137 | #define CIR_IRSTS_PE 0x20 |
138 | #define CIR_IRSTS_RFO 0x10 |
139 | #define CIR_IRSTS_TE 0x08 |
140 | #define CIR_IRSTS_TTR 0x04 |
141 | #define CIR_IRSTS_TFU 0x02 |
142 | #define CIR_IRSTS_GH 0x01 |
143 | |
144 | /* CIR IREN settings */ |
145 | #define CIR_IREN_RDR 0x80 |
146 | #define CIR_IREN_RTR 0x40 |
147 | #define CIR_IREN_PE 0x20 |
148 | #define CIR_IREN_RFO 0x10 |
149 | #define CIR_IREN_TE 0x08 |
150 | #define CIR_IREN_TTR 0x04 |
151 | #define CIR_IREN_TFU 0x02 |
152 | #define CIR_IREN_GH 0x01 |
153 | |
154 | /* CIR FIFOCON settings */ |
155 | #define CIR_FIFOCON_TXFIFOCLR 0x80 |
156 | |
157 | #define CIR_FIFOCON_TX_TRIGGER_LEV_31 0x00 |
158 | #define CIR_FIFOCON_TX_TRIGGER_LEV_24 0x10 |
159 | #define CIR_FIFOCON_TX_TRIGGER_LEV_16 0x20 |
160 | #define CIR_FIFOCON_TX_TRIGGER_LEV_8 0x30 |
161 | |
162 | /* FIXME: make this a runtime option */ |
163 | /* select TX trigger level as 16 */ |
164 | #define CIR_FIFOCON_TX_TRIGGER_LEV CIR_FIFOCON_TX_TRIGGER_LEV_16 |
165 | |
166 | #define CIR_FIFOCON_RXFIFOCLR 0x08 |
167 | |
168 | #define CIR_FIFOCON_RX_TRIGGER_LEV_1 0x00 |
169 | #define CIR_FIFOCON_RX_TRIGGER_LEV_8 0x01 |
170 | #define CIR_FIFOCON_RX_TRIGGER_LEV_16 0x02 |
171 | #define CIR_FIFOCON_RX_TRIGGER_LEV_24 0x03 |
172 | |
173 | /* FIXME: make this a runtime option */ |
174 | /* select RX trigger level as 24 */ |
175 | #define CIR_FIFOCON_RX_TRIGGER_LEV CIR_FIFOCON_RX_TRIGGER_LEV_24 |
176 | |
177 | /* CIR IRFIFOSTS settings */ |
178 | #define CIR_IRFIFOSTS_IR_PENDING 0x80 |
179 | #define CIR_IRFIFOSTS_RX_GS 0x40 |
180 | #define CIR_IRFIFOSTS_RX_FTA 0x20 |
181 | #define CIR_IRFIFOSTS_RX_EMPTY 0x10 |
182 | #define CIR_IRFIFOSTS_RX_FULL 0x08 |
183 | #define CIR_IRFIFOSTS_TX_FTA 0x04 |
184 | #define CIR_IRFIFOSTS_TX_EMPTY 0x02 |
185 | #define CIR_IRFIFOSTS_TX_FULL 0x01 |
186 | |
187 | |
188 | /* CIR WAKE UP Regs */ |
189 | #define CIR_WAKE_IRCON 0x00 |
190 | #define CIR_WAKE_IRSTS 0x01 |
191 | #define CIR_WAKE_IREN 0x02 |
192 | #define CIR_WAKE_FIFO_CMP_DEEP 0x03 |
193 | #define CIR_WAKE_FIFO_CMP_TOL 0x04 |
194 | #define CIR_WAKE_FIFO_COUNT 0x05 |
195 | #define CIR_WAKE_SLCH 0x06 |
196 | #define CIR_WAKE_SLCL 0x07 |
197 | #define CIR_WAKE_FIFOCON 0x08 |
198 | #define CIR_WAKE_SRXFSTS 0x09 |
199 | #define CIR_WAKE_SAMPLE_RX_FIFO 0x0a |
200 | #define CIR_WAKE_WR_FIFO_DATA 0x0b |
201 | #define CIR_WAKE_RD_FIFO_ONLY 0x0c |
202 | #define CIR_WAKE_RD_FIFO_ONLY_IDX 0x0d |
203 | #define CIR_WAKE_FIFO_IGNORE 0x0e |
204 | #define CIR_WAKE_IRFSM 0x0f |
205 | |
206 | /* CIR WAKE UP IRCON settings */ |
207 | #define CIR_WAKE_IRCON_DEC_RST 0x80 |
208 | #define CIR_WAKE_IRCON_MODE1 0x40 |
209 | #define CIR_WAKE_IRCON_MODE0 0x20 |
210 | #define CIR_WAKE_IRCON_RXEN 0x10 |
211 | #define CIR_WAKE_IRCON_R 0x08 |
212 | #define CIR_WAKE_IRCON_RXINV 0x04 |
213 | |
214 | /* FIXME/jarod: make this a runtime option */ |
215 | /* select a same sample period like cir register */ |
216 | #define CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 |
217 | |
218 | /* CIR WAKE IRSTS Bits */ |
219 | #define CIR_WAKE_IRSTS_RDR 0x80 |
220 | #define CIR_WAKE_IRSTS_RTR 0x40 |
221 | #define CIR_WAKE_IRSTS_PE 0x20 |
222 | #define CIR_WAKE_IRSTS_RFO 0x10 |
223 | #define CIR_WAKE_IRSTS_GH 0x08 |
224 | #define CIR_WAKE_IRSTS_IR_PENDING 0x01 |
225 | |
226 | /* CIR WAKE UP IREN Bits */ |
227 | #define CIR_WAKE_IREN_RDR 0x80 |
228 | #define CIR_WAKE_IREN_RTR 0x40 |
229 | #define CIR_WAKE_IREN_PE 0x20 |
230 | #define CIR_WAKE_IREN_RFO 0x10 |
231 | #define CIR_WAKE_IREN_GH 0x08 |
232 | |
233 | /* CIR WAKE FIFOCON settings */ |
234 | #define CIR_WAKE_FIFOCON_RXFIFOCLR 0x08 |
235 | |
236 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 0x00 |
237 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_66 0x01 |
238 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_65 0x02 |
239 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_64 0x03 |
240 | |
241 | /* FIXME: make this a runtime option */ |
242 | /* select WAKE UP RX trigger level as 67 */ |
243 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 |
244 | |
245 | /* CIR WAKE SRXFSTS settings */ |
246 | #define CIR_WAKE_IRFIFOSTS_RX_GS 0x80 |
247 | #define CIR_WAKE_IRFIFOSTS_RX_FTA 0x40 |
248 | #define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20 |
249 | #define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 |
250 | |
251 | /* |
252 | * The CIR Wake FIFO buffer is 67 bytes long, but the stock remote wakes |
253 | * the system comparing only 65 bytes (fails with this set to 67) |
254 | */ |
255 | #define CIR_WAKE_FIFO_CMP_BYTES 65 |
256 | /* CIR Wake byte comparison tolerance */ |
257 | #define CIR_WAKE_CMP_TOLERANCE 5 |
258 | |
259 | /* |
260 | * Extended Function Enable Registers: |
261 | * Extended Function Index Register |
262 | * Extended Function Data Register |
263 | */ |
264 | #define CR_EFIR 0x2e |
265 | #define CR_EFDR 0x2f |
266 | |
267 | /* Possible alternate EFER values, depends on how the chip is wired */ |
268 | #define CR_EFIR2 0x4e |
269 | #define CR_EFDR2 0x4f |
270 | |
271 | /* Extended Function Mode enable/disable magic values */ |
272 | #define EFER_EFM_ENABLE 0x87 |
273 | #define EFER_EFM_DISABLE 0xaa |
274 | |
275 | /* Config regs we need to care about */ |
276 | #define CR_SOFTWARE_RESET 0x02 |
277 | #define CR_LOGICAL_DEV_SEL 0x07 |
278 | #define CR_CHIP_ID_HI 0x20 |
279 | #define CR_CHIP_ID_LO 0x21 |
280 | #define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */ |
281 | #define CR_OUTPUT_PIN_SEL 0x27 |
282 | #define CR_MULTIFUNC_PIN_SEL 0x2c |
283 | #define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */ |
284 | /* next three regs valid for both the CIR and CIR_WAKE logical devices */ |
285 | #define CR_CIR_BASE_ADDR_HI 0x60 |
286 | #define CR_CIR_BASE_ADDR_LO 0x61 |
287 | #define CR_CIR_IRQ_RSRC 0x70 |
288 | /* next three regs valid only for ACPI logical dev */ |
289 | #define CR_ACPI_CIR_WAKE 0xe0 |
290 | #define CR_ACPI_IRQ_EVENTS 0xf6 |
291 | #define CR_ACPI_IRQ_EVENTS2 0xf7 |
292 | |
293 | /* Logical devices that we need to care about */ |
294 | #define LOGICAL_DEV_LPT 0x01 |
295 | #define LOGICAL_DEV_CIR 0x06 |
296 | #define LOGICAL_DEV_ACPI 0x0a |
297 | #define LOGICAL_DEV_CIR_WAKE 0x0e |
298 | |
299 | #define LOGICAL_DEV_DISABLE 0x00 |
300 | #define LOGICAL_DEV_ENABLE 0x01 |
301 | |
302 | #define CIR_WAKE_ENABLE_BIT 0x08 |
303 | #define PME_INTR_CIR_PASS_BIT 0x08 |
304 | |
305 | /* w83677hg CIR pin config */ |
306 | #define OUTPUT_PIN_SEL_MASK 0xbc |
307 | #define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */ |
308 | #define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */ |
309 | |
310 | /* w83667hg CIR pin config */ |
311 | #define MULTIFUNC_PIN_SEL_MASK 0x1f |
312 | #define MULTIFUNC_ENABLE_CIR 0x80 /* Pin75=CIRRX, Pin76=CIRTX1 */ |
313 | #define MULTIFUNC_ENABLE_CIRWB 0x20 /* enable wide-band sensor */ |
314 | |
315 | /* MCE CIR signal length, related on sample period */ |
316 | |
317 | /* MCE CIR controller signal length: about 43ms |
318 | * 43ms / 50us (sample period) * 0.85 (inaccuracy) |
319 | */ |
320 | #define CONTROLLER_BUF_LEN_MIN 830 |
321 | |
322 | /* MCE CIR keyboard signal length: about 26ms |
323 | * 26ms / 50us (sample period) * 0.85 (inaccuracy) |
324 | */ |
325 | #define KEYBOARD_BUF_LEN_MAX 650 |
326 | #define KEYBOARD_BUF_LEN_MIN 610 |
327 | |
328 | /* MCE CIR mouse signal length: about 24ms |
329 | * 24ms / 50us (sample period) * 0.85 (inaccuracy) |
330 | */ |
331 | #define MOUSE_BUF_LEN_MIN 565 |
332 | |
333 | #define CIR_SAMPLE_PERIOD 50 |
334 | #define CIR_SAMPLE_LOW_INACCURACY 0.85 |
335 | |
336 | /* MAX silence time that driver will sent to lirc */ |
337 | #define MAX_SILENCE_TIME 60000 |
338 | |
339 | #if CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_100 |
340 | #define SAMPLE_PERIOD 100 |
341 | |
342 | #elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_50 |
343 | #define SAMPLE_PERIOD 50 |
344 | |
345 | #elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_25 |
346 | #define SAMPLE_PERIOD 25 |
347 | |
348 | #else |
349 | #define SAMPLE_PERIOD 1 |
350 | #endif |
351 | |
352 | /* as VISTA MCE definition, valid carrier value */ |
353 | #define MAX_CARRIER 60000 |
354 | #define MIN_CARRIER 30000 |
355 | |
356 | /* max wakeup sequence length */ |
357 | #define WAKEUP_MAX_SIZE 65 |
358 | |