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