[PATCH] v4l: 643: use key media instead of key videomodeswitch since
[powerpc.git] / drivers / media / video / ir-kbd-gpio.c
index a565823..28b5897 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $
  *
  * Copyright (c) 2003 Gerd Knorr
  * Copyright (c) 2003 Pavel Machek
@@ -157,9 +156,74 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
 
 /* ---------------------------------------------------------------------- */
 
+/* Ricardo Cerqueira <v4l@cerqueira.org> */
+/* Weird matching, since the remote has "uncommon" keys */
+
+static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
+
+       [ 30 ] = KEY_POWER,       // power
+       [ 7  ] = KEY_MEDIA,       // source
+       [ 28 ] = KEY_SEARCH,      // scan
+
+/* FIXME: duplicate keycodes?
+ *
+ * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
+ * The GPIO values are
+ * 6397fb for both "Scan <" and "CH -",
+ * 639ffb for "Scan >" and "CH+",
+ * 6384fb for "Tune <" and "<<<",
+ * 638cfb for "Tune >" and ">>>", regardless of the mask.
+ *
+ *     [ 23 ] = KEY_BACK,        // fm scan <<
+ *     [ 31 ] = KEY_FORWARD,     // fm scan >>
+ *
+ *     [ 4  ] = KEY_LEFT,        // fm tuning <
+ *     [ 12 ] = KEY_RIGHT,       // fm tuning >
+ *
+ * For now, these four keys are disabled. Pressing them will generate
+ * the CH+/CH-/<<</>>> events
+ */
+
+       [ 3  ] = KEY_TUNER,       // TV/FM
+
+       [ 0  ] = KEY_RECORD,
+       [ 8  ] = KEY_STOP,
+       [ 17 ] = KEY_PLAY,
+
+       [ 26 ] = KEY_PLAYPAUSE,   // freeze
+       [ 25 ] = KEY_ZOOM,        // zoom
+       [ 15 ] = KEY_TEXT,        // min
+
+       [ 1  ] = KEY_KP1,
+       [ 11 ] = KEY_KP2,
+       [ 27 ] = KEY_KP3,
+       [ 5  ] = KEY_KP4,
+       [ 9  ] = KEY_KP5,
+       [ 21 ] = KEY_KP6,
+       [ 6  ] = KEY_KP7,
+       [ 10 ] = KEY_KP8,
+       [ 18 ] = KEY_KP9,
+       [ 2  ] = KEY_KP0,
+       [ 16 ] = KEY_LAST,        // +100
+       [ 19 ] = KEY_LIST,        // recall
+
+       [ 31 ] = KEY_CHANNELUP,   // chn down
+       [ 23 ] = KEY_CHANNELDOWN, // chn up
+       [ 22 ] = KEY_VOLUMEUP,    // vol down
+       [ 20 ] = KEY_VOLUMEDOWN,  // vol up
+
+       [ 4  ] = KEY_KPMINUS,     // <<<
+       [ 14 ] = KEY_SETUP,       // function
+       [ 12 ] = KEY_KPPLUS,      // >>>
+
+       [ 13 ] = KEY_GOTO,        // mts
+       [ 29 ] = KEY_REFRESH,     // reset
+       [ 24 ] = KEY_MUTE         // mute/unmute
+};
+
 struct IR {
        struct bttv_sub_device  *sub;
-       struct input_dev        input;
+       struct input_dev        *input;
        struct ir_input_state   ir;
        char                    name[32];
        char                    phys[32];
@@ -218,23 +282,23 @@ static void ir_handle_key(struct IR *ir)
        if (ir->mask_keydown) {
                /* bit set on keydown */
                if (gpio & ir->mask_keydown) {
-                       ir_input_keydown(&ir->input,&ir->ir,data,data);
+                       ir_input_keydown(ir->input, &ir->ir, data, data);
                } else {
-                       ir_input_nokey(&ir->input,&ir->ir);
+                       ir_input_nokey(ir->input, &ir->ir);
                }
 
        } else if (ir->mask_keyup) {
                /* bit cleared on keydown */
                if (0 == (gpio & ir->mask_keyup)) {
-                       ir_input_keydown(&ir->input,&ir->ir,data,data);
+                       ir_input_keydown(ir->input, &ir->ir, data, data);
                } else {
-                       ir_input_nokey(&ir->input,&ir->ir);
+                       ir_input_nokey(ir->input, &ir->ir);
                }
 
        } else {
                /* can't disturgissh keydown/up :-/ */
-               ir_input_keydown(&ir->input,&ir->ir,data,data);
-               ir_input_nokey(&ir->input,&ir->ir);
+               ir_input_keydown(ir->input, &ir->ir, data, data);
+               ir_input_nokey(ir->input, &ir->ir);
        }
 }
 
@@ -269,13 +333,17 @@ static int ir_probe(struct device *dev)
 {
        struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
        struct IR *ir;
+       struct input_dev *input_dev;
        IR_KEYTAB_TYPE *ir_codes = NULL;
        int ir_type = IR_TYPE_OTHER;
 
-       ir = kmalloc(sizeof(*ir),GFP_KERNEL);
-       if (NULL == ir)
+       ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!ir || !input_dev) {
+               kfree(ir);
+               input_free_device(input_dev);
                return -ENOMEM;
-       memset(ir,0,sizeof(*ir));
+       }
 
        /* detect & configure */
        switch (sub->core->type) {
@@ -326,9 +394,16 @@ static int ir_probe(struct device *dev)
                ir->mask_keyup   = 0x008000;
                ir->polling      = 50; // ms
                break;
+       case BTTV_CONCEPTRONIC_CTVFMI2:
+               ir_codes         = ir_codes_conceptronic;
+               ir->mask_keycode = 0x001F00;
+               ir->mask_keyup   = 0x006000;
+               ir->polling      = 50; // ms
+               break;
        }
        if (NULL == ir_codes) {
                kfree(ir);
+               input_free_device(input_dev);
                return -ENODEV;
        }
 
@@ -342,18 +417,19 @@ static int ir_probe(struct device *dev)
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
                 pci_name(sub->core->pci));
 
-       ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
-       ir->input.name = ir->name;
-       ir->input.phys = ir->phys;
-       ir->input.id.bustype = BUS_PCI;
-       ir->input.id.version = 1;
+       ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+       input_dev->name = ir->name;
+       input_dev->phys = ir->phys;
+       input_dev->id.bustype = BUS_PCI;
+       input_dev->id.version = 1;
        if (sub->core->pci->subsystem_vendor) {
-               ir->input.id.vendor  = sub->core->pci->subsystem_vendor;
-               ir->input.id.product = sub->core->pci->subsystem_device;
+               input_dev->id.vendor  = sub->core->pci->subsystem_vendor;
+               input_dev->id.product = sub->core->pci->subsystem_device;
        } else {
-               ir->input.id.vendor  = sub->core->pci->vendor;
-               ir->input.id.product = sub->core->pci->device;
+               input_dev->id.vendor  = sub->core->pci->vendor;
+               input_dev->id.product = sub->core->pci->device;
        }
+       input_dev->cdev.dev = &sub->core->pci->dev;
 
        if (ir->polling) {
                INIT_WORK(&ir->work, ir_work, ir);
@@ -364,9 +440,8 @@ static int ir_probe(struct device *dev)
        }
 
        /* all done */
-       dev_set_drvdata(dev,ir);
-       input_register_device(&ir->input);
-       printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
+       dev_set_drvdata(dev, ir);
+       input_register_device(ir->input);
 
        return 0;
 }
@@ -380,7 +455,7 @@ static int ir_remove(struct device *dev)
                flush_scheduled_work();
        }
 
-       input_unregister_device(&ir->input);
+       input_unregister_device(ir->input);
        kfree(ir);
        return 0;
 }