1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
|
/*
* Driver for ITE Tech Inc. IT8712F/IT8512F CIR
*
* Copyright (C) 2010 Juan Jesús García de Soria <skandalfo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
/* platform driver name to register */
#define ITE_DRIVER_NAME "ite-cir"
/* logging macros */
#define ite_pr(level, text, ...) \
printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
#define ite_dbg(text, ...) do { \
if (debug) \
printk(KERN_DEBUG \
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
} while (0)
#define ite_dbg_verbose(text, ...) do {\
if (debug > 1) \
printk(KERN_DEBUG \
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
} while (0)
/* FIFO sizes */
#define ITE_TX_FIFO_LEN 32
#define ITE_RX_FIFO_LEN 32
/* interrupt types */
#define ITE_IRQ_TX_FIFO 1
#define ITE_IRQ_RX_FIFO 2
#define ITE_IRQ_RX_FIFO_OVERRUN 4
/* forward declaration */
struct ite_dev;
/* struct for storing the parameters of different recognized devices */
struct ite_dev_params {
/* model of the device */
const char *model;
/* size of the I/O region */
int io_region_size;
/* IR pnp I/O resource number */
int io_rsrc_no;
/* true if the hardware supports transmission */
bool hw_tx_capable;
/* base sampling period, in ns */
u32 sample_period;
/* rx low carrier frequency, in Hz, 0 means no demodulation */
unsigned int rx_low_carrier_freq;
/* tx high carrier frequency, in Hz, 0 means no demodulation */
unsigned int rx_high_carrier_freq;
/* tx carrier frequency, in Hz */
unsigned int tx_carrier_freq;
/* duty cycle, 0-100 */
int tx_duty_cycle;
/* hw-specific operation function pointers; most of these must be
* called while holding the spin lock, except for the TX FIFO length
* one */
/* get pending interrupt causes */
int (*get_irq_causes) (struct ite_dev *dev);
/* enable rx */
void (*enable_rx) (struct ite_dev *dev);
/* make rx enter the idle state; keep listening for a pulse, but stop
* streaming space bytes */
void (*idle_rx) (struct ite_dev *dev);
/* disable rx completely */
void (*disable_rx) (struct ite_dev *dev);
/* read bytes from RX FIFO; return read count */
int (*get_rx_bytes) (struct ite_dev *dev, u8 *buf, int buf_size);
/* enable tx FIFO space available interrupt */
void (*enable_tx_interrupt) (struct ite_dev *dev);
/* disable tx FIFO space available interrupt */
void (*disable_tx_interrupt) (struct ite_dev *dev);
/* get number of full TX FIFO slots */
int (*get_tx_used_slots) (struct ite_dev *dev);
/* put a byte to the TX FIFO */
void (*put_tx_byte) (struct ite_dev *dev, u8 value);
/* disable hardware completely */
void (*disable) (struct ite_dev *dev);
/* initialize the hardware */
void (*init_hardware) (struct ite_dev *dev);
/* set the carrier parameters */
void (*set_carrier_params) (struct ite_dev *dev, bool high_freq,
bool use_demodulator, u8 carrier_freq_bits,
u8 allowance_bits, u8 pulse_width_bits);
};
/* ITE CIR device structure */
struct ite_dev {
struct pnp_dev *pdev;
struct rc_dev *rdev;
struct ir_raw_event rawir;
/* sync data */
spinlock_t lock;
bool in_use, transmitting;
/* transmit support */
int tx_fifo_allowance;
wait_queue_head_t tx_queue, tx_ended;
/* hardware I/O settings */
unsigned long cir_addr;
int cir_irq;
/* overridable copy of model parameters */
struct ite_dev_params params;
};
/* common values for all kinds of hardware */
/* baud rate divisor default */
#define ITE_BAUDRATE_DIVISOR 1
/* low-speed carrier frequency limits (Hz) */
#define ITE_LCF_MIN_CARRIER_FREQ 27000
#define ITE_LCF_MAX_CARRIER_FREQ 58000
/* high-speed carrier frequency limits (Hz) */
#define ITE_HCF_MIN_CARRIER_FREQ 400000
#define ITE_HCF_MAX_CARRIER_FREQ 500000
/* default carrier freq for when demodulator is off (Hz) */
#define ITE_DEFAULT_CARRIER_FREQ 38000
/* default idling timeout in ns (0.2 seconds) */
#define ITE_IDLE_TIMEOUT 200000000UL
/* limit timeout values */
#define ITE_MIN_IDLE_TIMEOUT 100000000UL
#define ITE_MAX_IDLE_TIMEOUT 1000000000UL
/* convert bits to us */
#define ITE_BITS_TO_NS(bits, sample_period) \
((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period))
/*
* n in RDCR produces a tolerance of +/- n * 6.25% around the center
* carrier frequency...
*
* From two limit frequencies, L (low) and H (high), we can get both the
* center frequency F = (L + H) / 2 and the variation from the center
* frequency A = (H - L) / (H + L). We can use this in order to honor the
* s_rx_carrier_range() call in ir-core. We'll suppose that any request
* setting L=0 means we must shut down the demodulator.
*/
#define ITE_RXDCR_PER_10000_STEP 625
/* high speed carrier freq values */
#define ITE_CFQ_400 0x03
#define ITE_CFQ_450 0x08
#define ITE_CFQ_480 0x0b
#define ITE_CFQ_500 0x0d
/* values for pulse widths */
#define ITE_TXMPW_A 0x02
#define ITE_TXMPW_B 0x03
#define ITE_TXMPW_C 0x04
#define ITE_TXMPW_D 0x05
#define ITE_TXMPW_E 0x06
/* values for demodulator carrier range allowance */
#define ITE_RXDCR_DEFAULT 0x01 /* default carrier range */
#define ITE_RXDCR_MAX 0x07 /* default carrier range */
/* DR TX bits */
#define ITE_TX_PULSE 0x00
#define ITE_TX_SPACE 0x80
#define ITE_TX_MAX_RLE 0x80
#define ITE_TX_RLE_MASK 0x7f
/*
* IT8712F
*
* hardware data obtained from:
*
* IT8712F
* Environment Control – Low Pin Count Input / Output
* (EC - LPC I/O)
* Preliminary Specification V0. 81
*/
/* register offsets */
#define IT87_DR 0x00 /* data register */
#define IT87_IER 0x01 /* interrupt enable register */
#define IT87_RCR 0x02 /* receiver control register */
#define IT87_TCR1 0x03 /* transmitter control register 1 */
#define IT87_TCR2 0x04 /* transmitter control register 2 */
#define IT87_TSR 0x05 /* transmitter status register */
#define IT87_RSR 0x06 /* receiver status register */
#define IT87_BDLR 0x05 /* baud rate divisor low byte register */
#define IT87_BDHR 0x06 /* baud rate divisor high byte register */
#define IT87_IIR 0x07 /* interrupt identification register */
#define IT87_IOREG_LENGTH 0x08 /* length of register file */
/* IER bits */
#define IT87_TLDLIE 0x01 /* transmitter low data interrupt enable */
#define IT87_RDAIE 0x02 /* receiver data available interrupt enable */
#define IT87_RFOIE 0x04 /* receiver FIFO overrun interrupt enable */
#define IT87_IEC 0x08 /* interrupt enable control */
#define IT87_BR 0x10 /* baud rate register enable */
#define IT87_RESET 0x20 /* reset */
/* RCR bits */
#define IT87_RXDCR 0x07 /* receiver demodulation carrier range mask */
#define IT87_RXACT 0x08 /* receiver active */
#define IT87_RXEND 0x10 /* receiver demodulation enable */
#define IT87_RXEN 0x20 /* receiver enable */
#define IT87_HCFS 0x40 /* high-speed carrier frequency select */
#define IT87_RDWOS 0x80 /* receiver data without sync */
/* TCR1 bits */
#define IT87_TXMPM 0x03 /* transmitter modulation pulse mode mask */
#define IT87_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
#define IT87_TXENDF 0x04 /* transmitter deferral */
#define IT87_TXRLE 0x08 /* transmitter run length enable */
#define IT87_FIFOTL 0x30 /* FIFO level threshold mask */
#define IT87_FIFOTL_DEFAULT 0x20 /* FIFO level threshold default
* 0x00 -> 1, 0x10 -> 7, 0x20 -> 17,
* 0x30 -> 25 */
#define IT87_ILE 0x40 /* internal loopback enable */
#define IT87_FIFOCLR 0x80 /* FIFO clear bit */
/* TCR2 bits */
#define IT87_TXMPW 0x07 /* transmitter modulation pulse width mask */
#define IT87_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
#define IT87_CFQ 0xf8 /* carrier frequency mask */
#define IT87_CFQ_SHIFT 3 /* carrier frequency bit shift */
/* TSR bits */
#define IT87_TXFBC 0x3f /* transmitter FIFO byte count mask */
/* RSR bits */
#define IT87_RXFBC 0x3f /* receiver FIFO byte count mask */
#define IT87_RXFTO 0x80 /* receiver FIFO time-out */
/* IIR bits */
#define IT87_IP 0x01 /* interrupt pending */
#define IT87_II 0x06 /* interrupt identification mask */
#define IT87_II_NOINT 0x00 /* no interrupt */
#define IT87_II_TXLDL 0x02 /* transmitter low data level */
#define IT87_II_RXDS 0x04 /* receiver data stored */
#define IT87_II_RXFO 0x06 /* receiver FIFO overrun */
/*
* IT8512E/F
*
* Hardware data obtained from:
*
* IT8512E/F
* Embedded Controller
* Preliminary Specification V0.4.1
*
* Note that the CIR registers are not directly available to the host, because
* they only are accessible to the integrated microcontroller. Thus, in order
* use it, some kind of bridging is required. As the bridging may depend on
* the controller firmware in use, we are going to use the PNP ID in order to
* determine the strategy and ports available. See after these generic
* IT8512E/F register definitions for register definitions for those
* strategies.
*/
/* register offsets */
#define IT85_C0DR 0x00 /* data register */
#define IT85_C0MSTCR 0x01 /* master control register */
#define IT85_C0IER 0x02 /* interrupt enable register */
#define IT85_C0IIR 0x03 /* interrupt identification register */
#define IT85_C0CFR 0x04 /* carrier frequency register */
#define IT85_C0RCR 0x05 /* receiver control register */
#define IT85_C0TCR 0x06 /* transmitter control register */
#define IT85_C0SCK 0x07 /* slow clock control register */
#define IT85_C0BDLR 0x08 /* baud rate divisor low byte register */
#define IT85_C0BDHR 0x09 /* baud rate divisor high byte register */
#define IT85_C0TFSR 0x0a /* transmitter FIFO status register */
#define IT85_C0RFSR 0x0b /* receiver FIFO status register */
#define IT85_C0WCL 0x0d /* wakeup code length register */
#define IT85_C0WCR 0x0e /* wakeup code read/write register */
#define IT85_C0WPS 0x0f /* wakeup power control/status register */
#define IT85_IOREG_LENGTH 0x10 /* length of register file */
/* C0MSTCR bits */
#define IT85_RESET 0x01 /* reset */
#define IT85_FIFOCLR 0x02 /* FIFO clear bit */
#define IT85_FIFOTL 0x0c /* FIFO level threshold mask */
#define IT85_FIFOTL_DEFAULT 0x08 /* FIFO level threshold default
* 0x00 -> 1, 0x04 -> 7, 0x08 -> 17,
* 0x0c -> 25 */
#define IT85_ILE 0x10 /* internal loopback enable */
#define IT85_ILSEL 0x20 /* internal loopback select */
/* C0IER bits */
#define IT85_TLDLIE 0x01 /* TX low data level interrupt enable */
#define IT85_RDAIE 0x02 /* RX data available interrupt enable */
#define IT85_RFOIE 0x04 /* RX FIFO overrun interrupt enable */
#define IT85_IEC 0x80 /* interrupt enable function control */
/* C0IIR bits */
#define IT85_TLDLI 0x01 /* transmitter low data level interrupt */
#define IT85_RDAI 0x02 /* receiver data available interrupt */
#define IT85_RFOI 0x04 /* receiver FIFO overrun interrupt */
#define IT85_NIP 0x80 /* no interrupt pending */
/* C0CFR bits */
#define IT85_CFQ 0x1f /* carrier frequency mask */
#define IT85_HCFS 0x20 /* high speed carrier frequency select */
/* C0RCR bits */
#define IT85_RXDCR 0x07 /* receiver demodulation carrier range mask */
#define IT85_RXACT 0x08 /* receiver active */
#define IT85_RXEND 0x10 /* receiver demodulation enable */
#define IT85_RDWOS 0x20 /* receiver data without sync */
#define IT85_RXEN 0x80 /* receiver enable */
/* C0TCR bits */
#define IT85_TXMPW 0x07 /* transmitter modulation pulse width mask */
#define IT85_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
#define IT85_TXMPM 0x18 /* transmitter modulation pulse mode mask */
#define IT85_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
#define IT85_TXENDF 0x20 /* transmitter deferral */
#define IT85_TXRLE 0x40 /* transmitter run length enable */
/* C0SCK bits */
#define IT85_SCKS 0x01 /* slow clock select */
#define IT85_TXDCKG 0x02 /* TXD clock gating */
#define IT85_DLL1P8E 0x04 /* DLL 1.8432M enable */
#define IT85_DLLTE 0x08 /* DLL test enable */
#define IT85_BRCM 0x70 /* baud rate count mode */
#define IT85_DLLOCK 0x80 /* DLL lock */
/* C0TFSR bits */
#define IT85_TXFBC 0x3f /* transmitter FIFO count mask */
/* C0RFSR bits */
#define IT85_RXFBC 0x3f /* receiver FIFO count mask */
#define IT85_RXFTO 0x80 /* receiver FIFO time-out */
/* C0WCL bits */
#define IT85_WCL 0x3f /* wakeup code length mask */
/* C0WPS bits */
#define IT85_CIRPOSIE 0x01 /* power on/off status interrupt enable */
#define IT85_CIRPOIS 0x02 /* power on/off interrupt status */
#define IT85_CIRPOII 0x04 /* power on/off interrupt identification */
#define IT85_RCRST 0x10 /* wakeup code reading counter reset bit */
#define IT85_WCRST 0x20 /* wakeup code writing counter reset bit */
/*
* ITE8708
*
* Hardware data obtained from hacked driver for IT8512 in this forum post:
*
* http://ubuntuforums.org/showthread.php?t=1028640
*
* Although there's no official documentation for that driver, analysis would
* suggest that it maps the 16 registers of IT8512 onto two 8-register banks,
* selectable by a single bank-select bit that's mapped onto both banks. The
* IT8512 registers are mapped in a different order, so that the first bank
* maps the ones that are used more often, and two registers that share a
* reserved high-order bit are placed at the same offset in both banks in
* order to reuse the reserved bit as the bank select bit.
*/
/* register offsets */
/* mapped onto both banks */
#define IT8708_BANKSEL 0x07 /* bank select register */
#define IT8708_HRAE 0x80 /* high registers access enable */
/* mapped onto the low bank */
#define IT8708_C0DR 0x00 /* data register */
#define IT8708_C0MSTCR 0x01 /* master control register */
#define IT8708_C0IER 0x02 /* interrupt enable register */
#define IT8708_C0IIR 0x03 /* interrupt identification register */
#define IT8708_C0RFSR 0x04 /* receiver FIFO status register */
#define IT8708_C0RCR 0x05 /* receiver control register */
#define IT8708_C0TFSR 0x06 /* transmitter FIFO status register */
#define IT8708_C0TCR 0x07 /* transmitter control register */
/* mapped onto the high bank */
#define IT8708_C0BDLR 0x01 /* baud rate divisor low byte register */
#define IT8708_C0BDHR 0x02 /* baud rate divisor high byte register */
#define IT8708_C0CFR 0x04 /* carrier frequency register */
/* registers whose bank mapping we don't know, since they weren't being used
* in the hacked driver... most probably they belong to the high bank too,
* since they fit in the holes the other registers leave */
#define IT8708_C0SCK 0x03 /* slow clock control register */
#define IT8708_C0WCL 0x05 /* wakeup code length register */
#define IT8708_C0WCR 0x06 /* wakeup code read/write register */
#define IT8708_C0WPS 0x07 /* wakeup power control/status register */
#define IT8708_IOREG_LENGTH 0x08 /* length of register file */
/* two more registers that are defined in the hacked driver, but can't be
* found in the data sheets; no idea what they are or how they are accessed,
* since the hacked driver doesn't seem to use them */
#define IT8708_CSCRR 0x00
#define IT8708_CGPINTR 0x01
/* CSCRR bits */
#define IT8708_CSCRR_SCRB 0x3f
#define IT8708_CSCRR_PM 0x80
/* CGPINTR bits */
#define IT8708_CGPINT 0x01
/*
* ITE8709
*
* Hardware interfacing data obtained from the original lirc_ite8709 driver.
* Verbatim from its sources:
*
* The ITE8709 device seems to be the combination of IT8512 superIO chip and
* a specific firmware running on the IT8512's embedded micro-controller.
* In addition of the embedded micro-controller, the IT8512 chip contains a
* CIR module and several other modules. A few modules are directly accessible
* by the host CPU, but most of them are only accessible by the
* micro-controller. The CIR module is only accessible by the
* micro-controller.
*
* The battery-backed SRAM module is accessible by the host CPU and the
* micro-controller. So one of the MC's firmware role is to act as a bridge
* between the host CPU and the CIR module. The firmware implements a kind of
* communication protocol using the SRAM module as a shared memory. The IT8512
* specification is publicly available on ITE's web site, but the
* communication protocol is not, so it was reverse-engineered.
*/
/* register offsets */
#define IT8709_RAM_IDX 0x00 /* index into the SRAM module bytes */
#define IT8709_RAM_VAL 0x01 /* read/write data to the indexed byte */
#define IT8709_IOREG_LENGTH 0x02 /* length of register file */
/* register offsets inside the SRAM module */
#define IT8709_MODE 0x1a /* request/ack byte */
#define IT8709_REG_IDX 0x1b /* index of the CIR register to access */
#define IT8709_REG_VAL 0x1c /* value read/to be written */
#define IT8709_IIR 0x1e /* interrupt identification register */
#define IT8709_RFSR 0x1f /* receiver FIFO status register */
#define IT8709_FIFO 0x20 /* start of in RAM RX FIFO copy */
/* MODE values */
#define IT8709_IDLE 0x00
#define IT8709_WRITE 0x01
#define IT8709_READ 0x02
|