Added lirc.
[irreco.git] / lirc-0.8.4a / drivers / lirc_bt829 / lirc_bt829.c
blobd008c3151fa95f21a95a44a5b7ebd64a5274cdd7
1 /*
2 * Remote control driver for the TV-card based on bt829
4 * by Leonid Froenchenko <lfroen@galileo.co.il>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/version.h>
22 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
23 #error "This driver needs kernel version 2.4.0 or higher"
24 #endif
26 #include <linux/autoconf.h>
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/threads.h>
30 #include <linux/sched.h>
31 #include <linux/ioport.h>
32 #include <linux/pci.h>
33 #include <linux/delay.h>
35 #include "drivers/kcompat.h"
36 #include "drivers/lirc_dev/lirc_dev.h"
38 static int poll_main(void);
39 static int atir_init_start(void);
41 static void write_index(unsigned char index, unsigned int value);
42 static unsigned int read_index(unsigned char index);
44 static void do_i2c_start(void);
45 static void do_i2c_stop(void);
47 static void seems_wr_byte(unsigned char al);
48 static unsigned char seems_rd_byte(void);
50 static unsigned int read_index(unsigned char al);
51 static void write_index(unsigned char ah, unsigned int edx);
53 static void cycle_delay(int cycle);
55 static void do_set_bits(unsigned char bl);
56 static unsigned char do_get_bits(void);
58 #define DATA_PCI_OFF 0x7FFC00
59 #define WAIT_CYCLE 20
61 static int debug;
62 #define dprintk(fmt, args...) \
63 do { \
64 if (debug) \
65 printk(KERN_DEBUG fmt, ## args); \
66 } while (0)
68 static int atir_minor;
69 static unsigned long pci_addr_phys;
70 static unsigned char *pci_addr_lin;
72 static struct lirc_plugin atir_plugin;
74 static struct pci_dev *do_pci_probe(void)
76 struct pci_dev *my_dev;
77 #ifndef KERNEL_2_5
78 /* unnecessary with recent kernels */
79 if (!pci_present())
80 printk(KERN_ERR "ATIR: no pci in this kernel\n");
81 #endif
82 my_dev = pci_get_device(PCI_VENDOR_ID_ATI,
83 PCI_DEVICE_ID_ATI_264VT, NULL);
84 if (my_dev) {
85 printk(KERN_ERR "ATIR: Using device: %s\n",
86 pci_name(my_dev));
87 pci_addr_phys = 0;
88 if (my_dev->resource[0].flags & IORESOURCE_MEM) {
89 pci_addr_phys = my_dev->resource[0].start;
90 printk(KERN_INFO "ATIR memory at 0x%08X \n",
91 (unsigned int)pci_addr_phys);
93 if (pci_addr_phys == 0) {
94 printk(KERN_ERR "ATIR no memory resource ?\n");
95 return NULL;
97 } else {
98 printk(KERN_ERR "ATIR: pci_prob failed\n");
99 return NULL;
101 return my_dev;
104 static int atir_add_to_buf(void *data, struct lirc_buffer *buf)
106 unsigned char key;
107 int status;
108 status = poll_main();
109 key = (status >> 8) & 0xFF;
110 if (status & 0xFF) {
111 dprintk("ATIR reading key %02X\n", key);
112 lirc_buffer_write_1(buf, &key);
113 return 0;
115 return -ENODATA;
118 static int atir_set_use_inc(void *data)
120 MOD_INC_USE_COUNT;
121 dprintk("ATIR driver is opened\n");
122 return 0;
125 static void atir_set_use_dec(void *data)
127 MOD_DEC_USE_COUNT;
128 dprintk("ATIR driver is closed\n");
131 int init_module(void)
133 struct pci_dev *pdev;
135 pdev = do_pci_probe();
136 if (pdev == NULL)
137 return 1;
139 if (!atir_init_start())
140 return 1;
142 strcpy(atir_plugin.name, "ATIR");
143 atir_plugin.minor = -1;
144 atir_plugin.code_length = 8;
145 atir_plugin.sample_rate = 10;
146 atir_plugin.data = 0;
147 atir_plugin.add_to_buf = atir_add_to_buf;
148 atir_plugin.set_use_inc = atir_set_use_inc;
149 atir_plugin.set_use_dec = atir_set_use_dec;
150 #ifdef LIRC_HAVE_SYSFS
151 atir_plugin.dev = &pdev->dev;
152 #endif
153 atir_plugin.owner = THIS_MODULE;
155 atir_minor = lirc_register_plugin(&atir_plugin);
156 dprintk("ATIR driver is registered on minor %d\n", atir_minor);
158 return 0;
162 void cleanup_module(void)
164 lirc_unregister_plugin(atir_minor);
168 static int atir_init_start(void)
170 pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400);
171 if (pci_addr_lin == 0) {
172 printk(KERN_INFO "atir: pci mem must be mapped\n");
173 return 0;
175 return 1;
178 static void cycle_delay(int cycle)
180 udelay(WAIT_CYCLE*cycle);
184 static int poll_main()
186 unsigned char status_high, status_low;
188 do_i2c_start();
190 seems_wr_byte(0xAA);
191 seems_wr_byte(0x01);
193 do_i2c_start();
195 seems_wr_byte(0xAB);
197 status_low = seems_rd_byte();
198 status_high = seems_rd_byte();
200 do_i2c_stop();
202 return (status_high << 8) | status_low;
205 static void do_i2c_start(void)
207 do_set_bits(3);
208 cycle_delay(4);
210 do_set_bits(1);
211 cycle_delay(7);
213 do_set_bits(0);
214 cycle_delay(2);
217 static void do_i2c_stop(void)
219 unsigned char bits;
220 bits = do_get_bits() & 0xFD;
221 do_set_bits(bits);
222 cycle_delay(1);
224 bits |= 1;
225 do_set_bits(bits);
226 cycle_delay(2);
228 bits |= 2;
229 do_set_bits(bits);
230 bits = 3;
231 do_set_bits(bits);
232 cycle_delay(2);
235 static void seems_wr_byte(unsigned char value)
237 int i;
238 unsigned char reg;
240 reg = do_get_bits();
241 for (i = 0; i < 8; i++) {
242 if (value & 0x80)
243 reg |= 0x02;
244 else
245 reg &= 0xFD;
247 do_set_bits(reg);
248 cycle_delay(1);
250 reg |= 1;
251 do_set_bits(reg);
252 cycle_delay(1);
254 reg &= 0xFE;
255 do_set_bits(reg);
256 cycle_delay(1);
257 value <<= 1;
259 cycle_delay(2);
261 reg |= 2;
262 do_set_bits(reg);
264 reg |= 1;
265 do_set_bits(reg);
267 cycle_delay(1);
268 do_get_bits();
270 reg &= 0xFE;
271 do_set_bits(reg);
272 cycle_delay(3);
275 static unsigned char seems_rd_byte(void)
277 int i;
278 int rd_byte;
279 unsigned char bits_2, bits_1;
281 bits_1 = do_get_bits() | 2;
282 do_set_bits(bits_1);
284 rd_byte = 0;
285 for (i = 0; i < 8; i++) {
286 bits_1 &= 0xFE;
287 do_set_bits(bits_1);
288 cycle_delay(2);
290 bits_1 |= 1;
291 do_set_bits(bits_1);
292 cycle_delay(1);
294 bits_2 = do_get_bits();
295 if (bits_2 & 2)
296 rd_byte |= 1;
298 rd_byte <<= 1;
301 bits_1 = 0;
302 if (bits_2 == 0)
303 bits_1 |= 2;
305 do_set_bits(bits_1);
306 cycle_delay(2);
308 bits_1 |= 1;
309 do_set_bits(bits_1);
310 cycle_delay(3);
312 bits_1 &= 0xFE;
313 do_set_bits(bits_1);
314 cycle_delay(2);
316 rd_byte >>= 1;
317 rd_byte &= 0xFF;
318 return rd_byte;
321 static void do_set_bits(unsigned char new_bits)
323 int reg_val;
324 reg_val = read_index(0x34);
325 if (new_bits & 2) {
326 reg_val &= 0xFFFFFFDF;
327 reg_val |= 1;
328 } else {
329 reg_val &= 0xFFFFFFFE;
330 reg_val |= 0x20;
332 reg_val |= 0x10;
333 write_index(0x34, reg_val);
335 reg_val = read_index(0x31);
336 if (new_bits & 1) {
337 reg_val |= 0x1000000;
338 } else {
339 reg_val &= 0xFEFFFFFF;
341 reg_val |= 0x8000000;
342 write_index(0x31, reg_val);
345 static unsigned char do_get_bits(void)
347 unsigned char bits;
348 int reg_val;
350 reg_val = read_index(0x34);
351 reg_val |= 0x10;
352 reg_val &= 0xFFFFFFDF;
353 write_index(0x34, reg_val);
355 reg_val = read_index(0x34);
356 bits = 0;
357 if (reg_val & 8) {
358 bits |= 2;
359 } else {
360 bits &= 0xFD;
362 reg_val = read_index(0x31);
363 if (reg_val & 0x1000000) {
364 bits |= 1;
365 } else {
366 bits &= 0xFE;
368 return bits;
371 static unsigned int read_index(unsigned char index)
373 unsigned char *addr;
374 unsigned int value;
375 /* addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2); */
376 addr = pci_addr_lin + ((index & 0xFF) << 2);
377 value = readl(addr);
378 return value;
381 static void write_index(unsigned char index, unsigned int reg_val)
383 unsigned char *addr;
384 addr = pci_addr_lin + ((index & 0xFF) << 2);
385 writel(reg_val, addr);
388 MODULE_AUTHOR("Froenchenko Leonid");
389 MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards");
390 MODULE_LICENSE("GPL");
392 module_param(debug, bool, 0644);
393 MODULE_PARM_DESC(debug, "Debug enabled or not");
395 EXPORT_NO_SYMBOLS;
398 * Overrides for Emacs so that we follow Linus's tabbing style.
399 * ---------------------------------------------------------------------------
400 * Local variables:
401 * c-basic-offset: 8
402 * End: