From d10d634143780931f92a265e2aa992428ff1af59 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Mon, 26 Jul 2010 20:26:53 -0300 Subject: V4L/DVB: staging/lirc: add lirc_bt829 driver Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/lirc/lirc_bt829.c | 383 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 383 insertions(+) create mode 100644 drivers/staging/lirc/lirc_bt829.c (limited to 'drivers/staging/lirc/lirc_bt829.c') diff --git a/drivers/staging/lirc/lirc_bt829.c b/drivers/staging/lirc/lirc_bt829.c new file mode 100644 index 000000000000..d0f34b51f5b0 --- /dev/null +++ b/drivers/staging/lirc/lirc_bt829.c @@ -0,0 +1,383 @@ +/* + * Remote control driver for the TV-card based on bt829 + * + * by Leonid Froenchenko + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static int poll_main(void); +static int atir_init_start(void); + +static void write_index(unsigned char index, unsigned int value); +static unsigned int read_index(unsigned char index); + +static void do_i2c_start(void); +static void do_i2c_stop(void); + +static void seems_wr_byte(unsigned char al); +static unsigned char seems_rd_byte(void); + +static unsigned int read_index(unsigned char al); +static void write_index(unsigned char ah, unsigned int edx); + +static void cycle_delay(int cycle); + +static void do_set_bits(unsigned char bl); +static unsigned char do_get_bits(void); + +#define DATA_PCI_OFF 0x7FFC00 +#define WAIT_CYCLE 20 + +#define DRIVER_NAME "lirc_bt829" + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG DRIVER_NAME ": "fmt, ## args); \ + } while (0) + +static int atir_minor; +static unsigned long pci_addr_phys; +static unsigned char *pci_addr_lin; + +static struct lirc_driver atir_driver; + +static struct pci_dev *do_pci_probe(void) +{ + struct pci_dev *my_dev; + my_dev = pci_get_device(PCI_VENDOR_ID_ATI, + PCI_DEVICE_ID_ATI_264VT, NULL); + if (my_dev) { + printk(KERN_ERR DRIVER_NAME ": Using device: %s\n", + pci_name(my_dev)); + pci_addr_phys = 0; + if (my_dev->resource[0].flags & IORESOURCE_MEM) { + pci_addr_phys = my_dev->resource[0].start; + printk(KERN_INFO DRIVER_NAME ": memory at 0x%08X \n", + (unsigned int)pci_addr_phys); + } + if (pci_addr_phys == 0) { + printk(KERN_ERR DRIVER_NAME ": no memory resource ?\n"); + return NULL; + } + } else { + printk(KERN_ERR DRIVER_NAME ": pci_probe failed\n"); + return NULL; + } + return my_dev; +} + +static int atir_add_to_buf(void *data, struct lirc_buffer *buf) +{ + unsigned char key; + int status; + status = poll_main(); + key = (status >> 8) & 0xFF; + if (status & 0xFF) { + dprintk("reading key %02X\n", key); + lirc_buffer_write(buf, &key); + return 0; + } + return -ENODATA; +} + +static int atir_set_use_inc(void *data) +{ + dprintk("driver is opened\n"); + return 0; +} + +static void atir_set_use_dec(void *data) +{ + dprintk("driver is closed\n"); +} + +int init_module(void) +{ + struct pci_dev *pdev; + + pdev = do_pci_probe(); + if (pdev == NULL) + return 1; + + if (!atir_init_start()) + return 1; + + strcpy(atir_driver.name, "ATIR"); + atir_driver.minor = -1; + atir_driver.code_length = 8; + atir_driver.sample_rate = 10; + atir_driver.data = 0; + atir_driver.add_to_buf = atir_add_to_buf; + atir_driver.set_use_inc = atir_set_use_inc; + atir_driver.set_use_dec = atir_set_use_dec; + atir_driver.dev = &pdev->dev; + atir_driver.owner = THIS_MODULE; + + atir_minor = lirc_register_driver(&atir_driver); + if (atir_minor < 0) { + printk(KERN_ERR DRIVER_NAME ": failed to register driver!\n"); + return atir_minor; + } + dprintk("driver is registered on minor %d\n", atir_minor); + + return 0; +} + + +void cleanup_module(void) +{ + lirc_unregister_driver(atir_minor); +} + + +static int atir_init_start(void) +{ + pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400); + if (pci_addr_lin == 0) { + printk(KERN_INFO DRIVER_NAME ": pci mem must be mapped\n"); + return 0; + } + return 1; +} + +static void cycle_delay(int cycle) +{ + udelay(WAIT_CYCLE*cycle); +} + + +static int poll_main() +{ + unsigned char status_high, status_low; + + do_i2c_start(); + + seems_wr_byte(0xAA); + seems_wr_byte(0x01); + + do_i2c_start(); + + seems_wr_byte(0xAB); + + status_low = seems_rd_byte(); + status_high = seems_rd_byte(); + + do_i2c_stop(); + + return (status_high << 8) | status_low; +} + +static void do_i2c_start(void) +{ + do_set_bits(3); + cycle_delay(4); + + do_set_bits(1); + cycle_delay(7); + + do_set_bits(0); + cycle_delay(2); +} + +static void do_i2c_stop(void) +{ + unsigned char bits; + bits = do_get_bits() & 0xFD; + do_set_bits(bits); + cycle_delay(1); + + bits |= 1; + do_set_bits(bits); + cycle_delay(2); + + bits |= 2; + do_set_bits(bits); + bits = 3; + do_set_bits(bits); + cycle_delay(2); +} + +static void seems_wr_byte(unsigned char value) +{ + int i; + unsigned char reg; + + reg = do_get_bits(); + for (i = 0; i < 8; i++) { + if (value & 0x80) + reg |= 0x02; + else + reg &= 0xFD; + + do_set_bits(reg); + cycle_delay(1); + + reg |= 1; + do_set_bits(reg); + cycle_delay(1); + + reg &= 0xFE; + do_set_bits(reg); + cycle_delay(1); + value <<= 1; + } + cycle_delay(2); + + reg |= 2; + do_set_bits(reg); + + reg |= 1; + do_set_bits(reg); + + cycle_delay(1); + do_get_bits(); + + reg &= 0xFE; + do_set_bits(reg); + cycle_delay(3); +} + +static unsigned char seems_rd_byte(void) +{ + int i; + int rd_byte; + unsigned char bits_2, bits_1; + + bits_1 = do_get_bits() | 2; + do_set_bits(bits_1); + + rd_byte = 0; + for (i = 0; i < 8; i++) { + bits_1 &= 0xFE; + do_set_bits(bits_1); + cycle_delay(2); + + bits_1 |= 1; + do_set_bits(bits_1); + cycle_delay(1); + + bits_2 = do_get_bits(); + if (bits_2 & 2) + rd_byte |= 1; + + rd_byte <<= 1; + } + + bits_1 = 0; + if (bits_2 == 0) + bits_1 |= 2; + + do_set_bits(bits_1); + cycle_delay(2); + + bits_1 |= 1; + do_set_bits(bits_1); + cycle_delay(3); + + bits_1 &= 0xFE; + do_set_bits(bits_1); + cycle_delay(2); + + rd_byte >>= 1; + rd_byte &= 0xFF; + return rd_byte; +} + +static void do_set_bits(unsigned char new_bits) +{ + int reg_val; + reg_val = read_index(0x34); + if (new_bits & 2) { + reg_val &= 0xFFFFFFDF; + reg_val |= 1; + } else { + reg_val &= 0xFFFFFFFE; + reg_val |= 0x20; + } + reg_val |= 0x10; + write_index(0x34, reg_val); + + reg_val = read_index(0x31); + if (new_bits & 1) + reg_val |= 0x1000000; + else + reg_val &= 0xFEFFFFFF; + + reg_val |= 0x8000000; + write_index(0x31, reg_val); +} + +static unsigned char do_get_bits(void) +{ + unsigned char bits; + int reg_val; + + reg_val = read_index(0x34); + reg_val |= 0x10; + reg_val &= 0xFFFFFFDF; + write_index(0x34, reg_val); + + reg_val = read_index(0x34); + bits = 0; + if (reg_val & 8) + bits |= 2; + else + bits &= 0xFD; + + reg_val = read_index(0x31); + if (reg_val & 0x1000000) + bits |= 1; + else + bits &= 0xFE; + + return bits; +} + +static unsigned int read_index(unsigned char index) +{ + unsigned char *addr; + unsigned int value; + /* addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2); */ + addr = pci_addr_lin + ((index & 0xFF) << 2); + value = readl(addr); + return value; +} + +static void write_index(unsigned char index, unsigned int reg_val) +{ + unsigned char *addr; + addr = pci_addr_lin + ((index & 0xFF) << 2); + writel(reg_val, addr); +} + +MODULE_AUTHOR("Froenchenko Leonid"); +MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards"); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); -- cgit v1.2.3-59-g8ed1b From 0f9313ad068af4156109661fb8e94ee7fcb79001 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Jul 2010 18:44:45 -0300 Subject: V4L/DVB: staging/lirc: CodingStyle cleanups Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/lirc/lirc_bt829.c | 2 +- drivers/staging/lirc/lirc_imon.c | 2 +- drivers/staging/lirc/lirc_it87.c | 2 +- drivers/staging/lirc/lirc_parallel.c | 2 +- drivers/staging/lirc/lirc_sasem.c | 2 +- drivers/staging/lirc/lirc_serial.c | 2 +- drivers/staging/lirc/lirc_sir.c | 2 +- drivers/staging/lirc/lirc_streamzap.c | 2 +- drivers/staging/lirc/lirc_ttusbir.c | 3 +-- drivers/staging/lirc/lirc_zilog.c | 2 +- 10 files changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/staging/lirc/lirc_bt829.c') diff --git a/drivers/staging/lirc/lirc_bt829.c b/drivers/staging/lirc/lirc_bt829.c index d0f34b51f5b0..33881025426b 100644 --- a/drivers/staging/lirc/lirc_bt829.c +++ b/drivers/staging/lirc/lirc_bt829.c @@ -77,7 +77,7 @@ static struct pci_dev *do_pci_probe(void) pci_addr_phys = 0; if (my_dev->resource[0].flags & IORESOURCE_MEM) { pci_addr_phys = my_dev->resource[0].start; - printk(KERN_INFO DRIVER_NAME ": memory at 0x%08X \n", + printk(KERN_INFO DRIVER_NAME ": memory at 0x%08X\n", (unsigned int)pci_addr_phys); } if (pci_addr_phys == 0) { diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c index 43856d6818dd..66493253042e 100644 --- a/drivers/staging/lirc/lirc_imon.c +++ b/drivers/staging/lirc/lirc_imon.c @@ -111,7 +111,7 @@ struct imon_context { } tx; }; -static struct file_operations display_fops = { +static const struct file_operations display_fops = { .owner = THIS_MODULE, .open = &display_open, .write = &vfd_write, diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c index 781abc306c27..09f36961c6d2 100644 --- a/drivers/staging/lirc/lirc_it87.c +++ b/drivers/staging/lirc/lirc_it87.c @@ -329,7 +329,7 @@ static void add_read_queue(int flag, unsigned long val) } -static struct file_operations lirc_fops = { +static const struct file_operations lirc_fops = { .owner = THIS_MODULE, .read = lirc_read, .write = lirc_write, diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/lirc/lirc_parallel.c index df12e7bd3f96..a1ebd071640f 100644 --- a/drivers/staging/lirc/lirc_parallel.c +++ b/drivers/staging/lirc/lirc_parallel.c @@ -539,7 +539,7 @@ static int lirc_close(struct inode *node, struct file *filep) return 0; } -static struct file_operations lirc_fops = { +static const struct file_operations lirc_fops = { .owner = THIS_MODULE, .llseek = lirc_lseek, .read = lirc_read, diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c index 9e516a112c29..73166c3f581f 100644 --- a/drivers/staging/lirc/lirc_sasem.c +++ b/drivers/staging/lirc/lirc_sasem.c @@ -119,7 +119,7 @@ struct sasem_context { }; /* VFD file operations */ -static struct file_operations vfd_fops = { +static const struct file_operations vfd_fops = { .owner = THIS_MODULE, .open = &vfd_open, .write = &vfd_write, diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/lirc/lirc_serial.c index d2ea3f0bd71d..9456f8e3f9ef 100644 --- a/drivers/staging/lirc/lirc_serial.c +++ b/drivers/staging/lirc/lirc_serial.c @@ -1050,7 +1050,7 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) return 0; } -static struct file_operations lirc_fops = { +static const struct file_operations lirc_fops = { .owner = THIS_MODULE, .write = lirc_write, .unlocked_ioctl = lirc_ioctl, diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/lirc/lirc_sir.c index 97146d1ee79f..eb08fa7138ba 100644 --- a/drivers/staging/lirc/lirc_sir.c +++ b/drivers/staging/lirc/lirc_sir.c @@ -451,7 +451,7 @@ static void add_read_queue(int flag, unsigned long val) wake_up_interruptible(&lirc_read_queue); } -static struct file_operations lirc_fops = { +static const struct file_operations lirc_fops = { .owner = THIS_MODULE, .read = lirc_read, .write = lirc_write, diff --git a/drivers/staging/lirc/lirc_streamzap.c b/drivers/staging/lirc/lirc_streamzap.c index 5b46ac4dda78..be09c103f0c9 100644 --- a/drivers/staging/lirc/lirc_streamzap.c +++ b/drivers/staging/lirc/lirc_streamzap.c @@ -431,7 +431,7 @@ static void usb_streamzap_irq(struct urb *urb) return; } -static struct file_operations streamzap_fops = { +static const struct file_operations streamzap_fops = { .owner = THIS_MODULE, .unlocked_ioctl = streamzap_ioctl, .read = lirc_dev_fop_read, diff --git a/drivers/staging/lirc/lirc_ttusbir.c b/drivers/staging/lirc/lirc_ttusbir.c index 1f1da471491e..e345ab9a004c 100644 --- a/drivers/staging/lirc/lirc_ttusbir.c +++ b/drivers/staging/lirc/lirc_ttusbir.c @@ -141,8 +141,7 @@ static void set_use_dec(void *data) * still have about 14 samples per pulse/space, i.e. we sample with 14 * times higher frequency than the signal frequency */ -const unsigned char map_table[] = -{ +const unsigned char map_table[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c index 1b013bf33899..100caab10451 100644 --- a/drivers/staging/lirc/lirc_zilog.c +++ b/drivers/staging/lirc/lirc_zilog.c @@ -1132,7 +1132,7 @@ static struct i2c_driver driver = { .id_table = ir_transceiver_id, }; -static struct file_operations lirc_fops = { +static const struct file_operations lirc_fops = { .owner = THIS_MODULE, .llseek = lseek, .read = read, -- cgit v1.2.3-59-g8ed1b