[go: nahoru, domu]

1/*
2 * Remote control driver for the TV-card based on bt829
3 *
4 *  by Leonid Froenchenko <lfroen@galileo.co.il>
5 *
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.
10 *
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.
15 *
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
19*/
20
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/threads.h>
26#include <linux/sched.h>
27#include <linux/ioport.h>
28#include <linux/pci.h>
29#include <linux/delay.h>
30
31#include <media/lirc_dev.h>
32
33static int poll_main(void);
34static int atir_init_start(void);
35
36static void write_index(unsigned char index, unsigned int value);
37static unsigned int read_index(unsigned char index);
38
39static void do_i2c_start(void);
40static void do_i2c_stop(void);
41
42static void seems_wr_byte(unsigned char al);
43static unsigned char seems_rd_byte(void);
44
45static unsigned int read_index(unsigned char al);
46static void write_index(unsigned char ah, unsigned int edx);
47
48static void cycle_delay(int cycle);
49
50static void do_set_bits(unsigned char bl);
51static unsigned char do_get_bits(void);
52
53#define DATA_PCI_OFF 0x7FFC00
54#define WAIT_CYCLE   20
55
56#define DRIVER_NAME "lirc_bt829"
57
58static bool debug;
59#define dprintk(fmt, args...)						 \
60	do {								 \
61		if (debug)						 \
62			printk(KERN_DEBUG DRIVER_NAME ": "fmt, ## args); \
63	} while (0)
64
65static int atir_minor;
66static phys_addr_t pci_addr_phys;
67static unsigned char __iomem *pci_addr_lin;
68
69static struct lirc_driver atir_driver;
70
71static struct pci_dev *do_pci_probe(void)
72{
73	struct pci_dev *my_dev;
74
75	my_dev = pci_get_device(PCI_VENDOR_ID_ATI,
76				PCI_DEVICE_ID_ATI_264VT, NULL);
77	if (my_dev) {
78		pr_err("Using device: %s\n", pci_name(my_dev));
79		pci_addr_phys = 0;
80		if (my_dev->resource[0].flags & IORESOURCE_MEM) {
81			pci_addr_phys = my_dev->resource[0].start;
82			pr_info("memory at %pa\n", &pci_addr_phys);
83		}
84		if (pci_addr_phys == 0) {
85			pr_err("no memory resource ?\n");
86			pci_dev_put(my_dev);
87			return NULL;
88		}
89	} else {
90		pr_err("pci_probe failed\n");
91		return NULL;
92	}
93	return my_dev;
94}
95
96static int atir_add_to_buf(void *data, struct lirc_buffer *buf)
97{
98	unsigned char key;
99	int status;
100
101	status = poll_main();
102	key = (status >> 8) & 0xFF;
103	if (status & 0xFF) {
104		dprintk("reading key %02X\n", key);
105		lirc_buffer_write(buf, &key);
106		return 0;
107	}
108	return -ENODATA;
109}
110
111static int atir_set_use_inc(void *data)
112{
113	dprintk("driver is opened\n");
114	return 0;
115}
116
117static void atir_set_use_dec(void *data)
118{
119	dprintk("driver is closed\n");
120}
121
122int init_module(void)
123{
124	struct pci_dev *pdev;
125	int rc;
126
127	pdev = do_pci_probe();
128	if (pdev == NULL)
129		return -ENODEV;
130
131	rc = pci_enable_device(pdev);
132	if (rc)
133		goto err_put_dev;
134
135	if (!atir_init_start()) {
136		rc = -ENODEV;
137		goto err_disable;
138	}
139
140	strcpy(atir_driver.name, "ATIR");
141	atir_driver.minor       = -1;
142	atir_driver.code_length = 8;
143	atir_driver.sample_rate = 10;
144	atir_driver.data        = NULL;
145	atir_driver.add_to_buf  = atir_add_to_buf;
146	atir_driver.set_use_inc = atir_set_use_inc;
147	atir_driver.set_use_dec = atir_set_use_dec;
148	atir_driver.dev         = &pdev->dev;
149	atir_driver.owner       = THIS_MODULE;
150
151	atir_minor = lirc_register_driver(&atir_driver);
152	if (atir_minor < 0) {
153		pr_err("failed to register driver!\n");
154		rc = atir_minor;
155		goto err_unmap;
156	}
157	dprintk("driver is registered on minor %d\n", atir_minor);
158
159	return 0;
160
161err_unmap:
162	iounmap(pci_addr_lin);
163err_disable:
164	pci_disable_device(pdev);
165err_put_dev:
166	pci_dev_put(pdev);
167	return rc;
168}
169
170
171void cleanup_module(void)
172{
173	struct pci_dev *pdev = to_pci_dev(atir_driver.dev);
174
175	lirc_unregister_driver(atir_minor);
176	iounmap(pci_addr_lin);
177	pci_disable_device(pdev);
178	pci_dev_put(pdev);
179}
180
181
182static int atir_init_start(void)
183{
184	pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400);
185	if (!pci_addr_lin) {
186		pr_info("pci mem must be mapped\n");
187		return 0;
188	}
189	return 1;
190}
191
192static void cycle_delay(int cycle)
193{
194	udelay(WAIT_CYCLE*cycle);
195}
196
197
198static int poll_main(void)
199{
200	unsigned char status_high, status_low;
201
202	do_i2c_start();
203
204	seems_wr_byte(0xAA);
205	seems_wr_byte(0x01);
206
207	do_i2c_start();
208
209	seems_wr_byte(0xAB);
210
211	status_low = seems_rd_byte();
212	status_high = seems_rd_byte();
213
214	do_i2c_stop();
215
216	return (status_high << 8) | status_low;
217}
218
219static void do_i2c_start(void)
220{
221	do_set_bits(3);
222	cycle_delay(4);
223
224	do_set_bits(1);
225	cycle_delay(7);
226
227	do_set_bits(0);
228	cycle_delay(2);
229}
230
231static void do_i2c_stop(void)
232{
233	unsigned char bits;
234
235	bits =  do_get_bits() & 0xFD;
236	do_set_bits(bits);
237	cycle_delay(1);
238
239	bits |= 1;
240	do_set_bits(bits);
241	cycle_delay(2);
242
243	bits |= 2;
244	do_set_bits(bits);
245	bits = 3;
246	do_set_bits(bits);
247	cycle_delay(2);
248}
249
250static void seems_wr_byte(unsigned char value)
251{
252	int i;
253	unsigned char reg;
254
255	reg = do_get_bits();
256	for (i = 0; i < 8; i++) {
257		if (value & 0x80)
258			reg |= 0x02;
259		else
260			reg &= 0xFD;
261
262		do_set_bits(reg);
263		cycle_delay(1);
264
265		reg |= 1;
266		do_set_bits(reg);
267		cycle_delay(1);
268
269		reg &= 0xFE;
270		do_set_bits(reg);
271		cycle_delay(1);
272		value <<= 1;
273	}
274	cycle_delay(2);
275
276	reg |= 2;
277	do_set_bits(reg);
278
279	reg |= 1;
280	do_set_bits(reg);
281
282	cycle_delay(1);
283	do_get_bits();
284
285	reg &= 0xFE;
286	do_set_bits(reg);
287	cycle_delay(3);
288}
289
290static unsigned char seems_rd_byte(void)
291{
292	int i;
293	int rd_byte;
294	unsigned char bits_2, bits_1;
295
296	bits_1 = do_get_bits() | 2;
297	do_set_bits(bits_1);
298
299	rd_byte = 0;
300	for (i = 0; i < 8; i++) {
301		bits_1 &= 0xFE;
302		do_set_bits(bits_1);
303		cycle_delay(2);
304
305		bits_1 |= 1;
306		do_set_bits(bits_1);
307		cycle_delay(1);
308
309		bits_2 = do_get_bits();
310		if (bits_2 & 2)
311			rd_byte |= 1;
312
313		rd_byte <<= 1;
314	}
315
316	bits_1 = 0;
317	if (bits_2 == 0)
318		bits_1 |= 2;
319
320	do_set_bits(bits_1);
321	cycle_delay(2);
322
323	bits_1 |= 1;
324	do_set_bits(bits_1);
325	cycle_delay(3);
326
327	bits_1 &= 0xFE;
328	do_set_bits(bits_1);
329	cycle_delay(2);
330
331	rd_byte >>= 1;
332	rd_byte &= 0xFF;
333	return rd_byte;
334}
335
336static void do_set_bits(unsigned char new_bits)
337{
338	int reg_val;
339
340	reg_val = read_index(0x34);
341	if (new_bits & 2) {
342		reg_val &= 0xFFFFFFDF;
343		reg_val |= 1;
344	} else {
345		reg_val &= 0xFFFFFFFE;
346		reg_val |= 0x20;
347	}
348	reg_val |= 0x10;
349	write_index(0x34, reg_val);
350
351	reg_val = read_index(0x31);
352	if (new_bits & 1)
353		reg_val |= 0x1000000;
354	else
355		reg_val &= 0xFEFFFFFF;
356
357	reg_val |= 0x8000000;
358	write_index(0x31, reg_val);
359}
360
361static unsigned char do_get_bits(void)
362{
363	unsigned char bits;
364	int reg_val;
365
366	reg_val = read_index(0x34);
367	reg_val |= 0x10;
368	reg_val &= 0xFFFFFFDF;
369	write_index(0x34, reg_val);
370
371	reg_val = read_index(0x34);
372	bits = 0;
373	if (reg_val & 8)
374		bits |= 2;
375	else
376		bits &= 0xFD;
377
378	reg_val = read_index(0x31);
379	if (reg_val & 0x1000000)
380		bits |= 1;
381	else
382		bits &= 0xFE;
383
384	return bits;
385}
386
387static unsigned int read_index(unsigned char index)
388{
389	unsigned char __iomem *addr;
390	/*  addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2); */
391	addr = pci_addr_lin + ((index & 0xFF) << 2);
392	return readl(addr);
393}
394
395static void write_index(unsigned char index, unsigned int reg_val)
396{
397	unsigned char __iomem *addr;
398
399	addr = pci_addr_lin + ((index & 0xFF) << 2);
400	writel(reg_val, addr);
401}
402
403MODULE_AUTHOR("Froenchenko Leonid");
404MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards");
405MODULE_LICENSE("GPL");
406
407module_param(debug, bool, S_IRUGO | S_IWUSR);
408MODULE_PARM_DESC(debug, "Debug enabled or not");
409