Merge branch 'master' into upstream
[pandora-kernel.git] / drivers / media / video / saa7134 / saa7134-input.c
index 7c59549..e425268 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 
@@ -112,6 +111,27 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
        return 1;
 }
 
+static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+       unsigned char buf[5], cod4, code3, code4;
+
+       /* poll IR chip */
+       if (5 != i2c_master_recv(&ir->c,buf,5))
+               return -EIO;
+
+       cod4    = buf[4];
+       code4   = (cod4 >> 2);
+       code3   = buf[3];
+       if (code3 == 0)
+               /* no key pressed */
+               return 0;
+
+       /* return key */
+       *ir_key = code4;
+       *ir_raw = code4;
+       return 1;
+}
+
 void saa7134_input_irq(struct saa7134_dev *dev)
 {
        struct saa7134_ir *ir = dev->remote;
@@ -131,6 +151,23 @@ static void saa7134_input_timer(unsigned long data)
        mod_timer(&ir->timer, timeout);
 }
 
+static void saa7134_ir_start(struct saa7134_dev *dev, struct saa7134_ir *ir)
+{
+       if (ir->polling) {
+               init_timer(&ir->timer);
+               ir->timer.function = saa7134_input_timer;
+               ir->timer.data     = (unsigned long)dev;
+               ir->timer.expires  = jiffies + HZ;
+               add_timer(&ir->timer);
+       }
+}
+
+static void saa7134_ir_stop(struct saa7134_dev *dev)
+{
+       if (dev->remote->polling)
+               del_timer_sync(&dev->remote->timer);
+}
+
 int saa7134_input_init1(struct saa7134_dev *dev)
 {
        struct saa7134_ir *ir;
@@ -141,6 +178,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        u32 mask_keyup   = 0;
        int polling      = 0;
        int ir_type      = IR_TYPE_OTHER;
+       int err;
 
        if (dev->has_remote != SAA7134_REMOTE_GPIO)
                return -ENODEV;
@@ -184,6 +222,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_AVERMEDIA_307:
        case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
        case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
+       case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
        case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
                ir_codes     = ir_codes_avermedia;
                mask_keycode = 0x0007C8;
@@ -193,6 +232,16 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
                saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
                break;
+       case SAA7134_BOARD_AVERMEDIA_777:
+       case SAA7134_BOARD_AVERMEDIA_A16AR:
+               ir_codes     = ir_codes_avermedia;
+               mask_keycode = 0x02F200;
+               mask_keydown = 0x000400;
+               polling      = 50; // ms
+               /* Without this we won't receive key up events */
+               saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
+               saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
+               break;
        case SAA7134_BOARD_KWORLD_TERMINATOR:
                ir_codes     = ir_codes_pixelview;
                mask_keycode = 0x00001f;
@@ -228,6 +277,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                mask_keyup   = 0x400000;
                polling      = 50; // ms
                break;
+       case SAA7134_BOARD_PROTEUS_2309:
+               ir_codes     = ir_codes_proteus_2309;
+               mask_keycode = 0x00007F;
+               mask_keyup   = 0x000080;
+               polling      = 50; // ms
+               break;
        case SAA7134_BOARD_VIDEOMATE_DVBT_300:
        case SAA7134_BOARD_VIDEOMATE_DVBT_200:
                ir_codes     = ir_codes_videomate_tv_pvr;
@@ -250,9 +305,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!ir || !input_dev) {
-               kfree(ir);
-               input_free_device(input_dev);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_out_free;
        }
 
        ir->dev = input_dev;
@@ -283,18 +337,22 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        }
        input_dev->cdev.dev = &dev->pci->dev;
 
-       /* all done */
        dev->remote = ir;
-       if (ir->polling) {
-               init_timer(&ir->timer);
-               ir->timer.function = saa7134_input_timer;
-               ir->timer.data     = (unsigned long)dev;
-               ir->timer.expires  = jiffies + HZ;
-               add_timer(&ir->timer);
-       }
+       saa7134_ir_start(dev, ir);
+
+       err = input_register_device(ir->dev);
+       if (err)
+               goto err_out_stop;
 
-       input_register_device(ir->dev);
        return 0;
+
+ err_out_stop:
+       saa7134_ir_stop(dev);
+       dev->remote = NULL;
+ err_out_free:
+       input_free_device(input_dev);
+       kfree(ir);
+       return err;
 }
 
 void saa7134_input_fini(struct saa7134_dev *dev)
@@ -302,8 +360,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
        if (NULL == dev->remote)
                return;
 
-       if (dev->remote->polling)
-               del_timer_sync(&dev->remote->timer);
+       saa7134_ir_stop(dev);
        input_unregister_device(dev->remote->dev);
        kfree(dev->remote);
        dev->remote = NULL;
@@ -319,6 +376,7 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
 
        switch (dev->board) {
        case SAA7134_BOARD_PINNACLE_PCTV_110i:
+       case SAA7134_BOARD_PINNACLE_PCTV_310i:
                snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
                if (pinnacle_remote == 0) {
                        ir->get_key   = get_key_pinnacle_color;
@@ -333,6 +391,11 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
                ir->get_key   = get_key_purpletv;
                ir->ir_codes  = ir_codes_purpletv;
                break;
+       case SAA7134_BOARD_HAUPPAUGE_HVR1110:
+               snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110");
+               ir->get_key   = get_key_hvr1110;
+               ir->ir_codes  = ir_codes_hauppauge_new;
+               break;
        default:
                dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
                break;