linux/drivers/media/video/bt8xx/bttv-input.c
<<
>>
Prefs
   1/*
   2 *
   3 * Copyright (c) 2003 Gerd Knorr
   4 * Copyright (c) 2003 Pavel Machek
   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#include <linux/module.h>
  22#include <linux/init.h>
  23#include <linux/delay.h>
  24#include <linux/interrupt.h>
  25#include <linux/input.h>
  26
  27#include "bttv.h"
  28#include "bttvp.h"
  29
  30
  31static int ir_debug;
  32module_param(ir_debug, int, 0644);
  33static int repeat_delay = 500;
  34module_param(repeat_delay, int, 0644);
  35static int repeat_period = 33;
  36module_param(repeat_period, int, 0644);
  37
  38static int ir_rc5_remote_gap = 885;
  39module_param(ir_rc5_remote_gap, int, 0644);
  40static int ir_rc5_key_timeout = 200;
  41module_param(ir_rc5_key_timeout, int, 0644);
  42
  43#undef dprintk
  44#define dprintk(arg...) do {    \
  45        if (ir_debug >= 1)      \
  46                printk(arg);    \
  47} while (0)
  48
  49#define DEVNAME "bttv-input"
  50
  51/* ---------------------------------------------------------------------- */
  52
  53static void ir_handle_key(struct bttv *btv)
  54{
  55        struct card_ir *ir = btv->remote;
  56        u32 gpio,data;
  57
  58        /* read gpio value */
  59        gpio = bttv_gpio_read(&btv->c);
  60        if (ir->polling) {
  61                if (ir->last_gpio == gpio)
  62                        return;
  63                ir->last_gpio = gpio;
  64        }
  65
  66        /* extract data */
  67        data = ir_extract_bits(gpio, ir->mask_keycode);
  68        dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
  69                gpio, data,
  70                ir->polling               ? "poll"  : "irq",
  71                (gpio & ir->mask_keydown) ? " down" : "",
  72                (gpio & ir->mask_keyup)   ? " up"   : "");
  73
  74        if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
  75            (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
  76                ir_input_keydown(ir->dev,&ir->ir,data,data);
  77        } else {
  78                /* HACK: Probably, ir->mask_keydown is missing
  79                   for this board */
  80                if (btv->c.type == BTTV_BOARD_WINFAST2000)
  81                        ir_input_keydown(ir->dev, &ir->ir, data, data);
  82
  83                ir_input_nokey(ir->dev,&ir->ir);
  84        }
  85
  86}
  87
  88static void ir_enltv_handle_key(struct bttv *btv)
  89{
  90        struct card_ir *ir = btv->remote;
  91        u32 gpio, data, keyup;
  92
  93        /* read gpio value */
  94        gpio = bttv_gpio_read(&btv->c);
  95
  96        /* extract data */
  97        data = ir_extract_bits(gpio, ir->mask_keycode);
  98
  99        /* Check if it is keyup */
 100        keyup = (gpio & ir->mask_keyup) ? 1 << 31 : 0;
 101
 102        if ((ir->last_gpio & 0x7f) != data) {
 103                dprintk(KERN_INFO DEVNAME ": gpio=0x%x code=%d | %s\n",
 104                        gpio, data,
 105                        (gpio & ir->mask_keyup) ? " up" : "up/down");
 106
 107                ir_input_keydown(ir->dev, &ir->ir, data, data);
 108                if (keyup)
 109                        ir_input_nokey(ir->dev, &ir->ir);
 110        } else {
 111                if ((ir->last_gpio & 1 << 31) == keyup)
 112                        return;
 113
 114                dprintk(KERN_INFO DEVNAME ":(cnt) gpio=0x%x code=%d | %s\n",
 115                        gpio, data,
 116                        (gpio & ir->mask_keyup) ? " up" : "down");
 117
 118                if (keyup)
 119                        ir_input_nokey(ir->dev, &ir->ir);
 120                else
 121                        ir_input_keydown(ir->dev, &ir->ir, data, data);
 122        }
 123
 124        ir->last_gpio = data | keyup;
 125}
 126
 127void bttv_input_irq(struct bttv *btv)
 128{
 129        struct card_ir *ir = btv->remote;
 130
 131        if (!ir->polling)
 132                ir_handle_key(btv);
 133}
 134
 135static void bttv_input_timer(unsigned long data)
 136{
 137        struct bttv *btv = (struct bttv*)data;
 138        struct card_ir *ir = btv->remote;
 139
 140        if (btv->c.type == BTTV_BOARD_ENLTV_FM_2)
 141                ir_enltv_handle_key(btv);
 142        else
 143                ir_handle_key(btv);
 144        mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
 145}
 146
 147/* ---------------------------------------------------------------*/
 148
 149static int bttv_rc5_irq(struct bttv *btv)
 150{
 151        struct card_ir *ir = btv->remote;
 152        struct timeval tv;
 153        u32 gpio;
 154        u32 gap;
 155        unsigned long current_jiffies;
 156
 157        /* read gpio port */
 158        gpio = bttv_gpio_read(&btv->c);
 159
 160        /* remote IRQ? */
 161        if (!(gpio & 0x20))
 162                return 0;
 163
 164        /* get time of bit */
 165        current_jiffies = jiffies;
 166        do_gettimeofday(&tv);
 167
 168        /* avoid overflow with gap >1s */
 169        if (tv.tv_sec - ir->base_time.tv_sec > 1) {
 170                gap = 200000;
 171        } else {
 172                gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
 173                    tv.tv_usec - ir->base_time.tv_usec;
 174        }
 175
 176        /* active code => add bit */
 177        if (ir->active) {
 178                /* only if in the code (otherwise spurious IRQ or timer
 179                   late) */
 180                if (ir->last_bit < 28) {
 181                        ir->last_bit = (gap - ir_rc5_remote_gap / 2) /
 182                            ir_rc5_remote_gap;
 183                        ir->code |= 1 << ir->last_bit;
 184                }
 185                /* starting new code */
 186        } else {
 187                ir->active = 1;
 188                ir->code = 0;
 189                ir->base_time = tv;
 190                ir->last_bit = 0;
 191
 192                mod_timer(&ir->timer_end,
 193                          current_jiffies + msecs_to_jiffies(30));
 194        }
 195
 196        /* toggle GPIO pin 4 to reset the irq */
 197        bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
 198        bttv_gpio_write(&btv->c, gpio | (1 << 4));
 199        return 1;
 200}
 201
 202/* ---------------------------------------------------------------------- */
 203
 204static void bttv_ir_start(struct bttv *btv, struct card_ir *ir)
 205{
 206        if (ir->polling) {
 207                setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv);
 208                ir->timer.expires  = jiffies + msecs_to_jiffies(1000);
 209                add_timer(&ir->timer);
 210        } else if (ir->rc5_gpio) {
 211                /* set timer_end for code completion */
 212                init_timer(&ir->timer_end);
 213                ir->timer_end.function = ir_rc5_timer_end;
 214                ir->timer_end.data = (unsigned long)ir;
 215
 216                init_timer(&ir->timer_keyup);
 217                ir->timer_keyup.function = ir_rc5_timer_keyup;
 218                ir->timer_keyup.data = (unsigned long)ir;
 219                ir->shift_by = 1;
 220                ir->start = 3;
 221                ir->addr = 0x0;
 222                ir->rc5_key_timeout = ir_rc5_key_timeout;
 223                ir->rc5_remote_gap = ir_rc5_remote_gap;
 224        }
 225}
 226
 227static void bttv_ir_stop(struct bttv *btv)
 228{
 229        if (btv->remote->polling) {
 230                del_timer_sync(&btv->remote->timer);
 231                flush_scheduled_work();
 232        }
 233
 234        if (btv->remote->rc5_gpio) {
 235                u32 gpio;
 236
 237                del_timer_sync(&btv->remote->timer_end);
 238                flush_scheduled_work();
 239
 240                gpio = bttv_gpio_read(&btv->c);
 241                bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
 242        }
 243}
 244
 245int bttv_input_init(struct bttv *btv)
 246{
 247        struct card_ir *ir;
 248        struct ir_scancode_table *ir_codes = NULL;
 249        struct input_dev *input_dev;
 250        int ir_type = IR_TYPE_OTHER;
 251        int err = -ENOMEM;
 252
 253        if (!btv->has_remote)
 254                return -ENODEV;
 255
 256        ir = kzalloc(sizeof(*ir),GFP_KERNEL);
 257        input_dev = input_allocate_device();
 258        if (!ir || !input_dev)
 259                goto err_out_free;
 260
 261        /* detect & configure */
 262        switch (btv->c.type) {
 263        case BTTV_BOARD_AVERMEDIA:
 264        case BTTV_BOARD_AVPHONE98:
 265        case BTTV_BOARD_AVERMEDIA98:
 266                ir_codes         = &ir_codes_avermedia_table;
 267                ir->mask_keycode = 0xf88000;
 268                ir->mask_keydown = 0x010000;
 269                ir->polling      = 50; // ms
 270                break;
 271
 272        case BTTV_BOARD_AVDVBT_761:
 273        case BTTV_BOARD_AVDVBT_771:
 274                ir_codes         = &ir_codes_avermedia_dvbt_table;
 275                ir->mask_keycode = 0x0f00c0;
 276                ir->mask_keydown = 0x000020;
 277                ir->polling      = 50; // ms
 278                break;
 279
 280        case BTTV_BOARD_PXELVWPLTVPAK:
 281                ir_codes         = &ir_codes_pixelview_table;
 282                ir->mask_keycode = 0x003e00;
 283                ir->mask_keyup   = 0x010000;
 284                ir->polling      = 50; // ms
 285                break;
 286        case BTTV_BOARD_PV_M4900:
 287        case BTTV_BOARD_PV_BT878P_9B:
 288        case BTTV_BOARD_PV_BT878P_PLUS:
 289                ir_codes         = &ir_codes_pixelview_table;
 290                ir->mask_keycode = 0x001f00;
 291                ir->mask_keyup   = 0x008000;
 292                ir->polling      = 50; // ms
 293                break;
 294
 295        case BTTV_BOARD_WINFAST2000:
 296                ir_codes         = &ir_codes_winfast_table;
 297                ir->mask_keycode = 0x1f8;
 298                break;
 299        case BTTV_BOARD_MAGICTVIEW061:
 300        case BTTV_BOARD_MAGICTVIEW063:
 301                ir_codes         = &ir_codes_winfast_table;
 302                ir->mask_keycode = 0x0008e000;
 303                ir->mask_keydown = 0x00200000;
 304                break;
 305        case BTTV_BOARD_APAC_VIEWCOMP:
 306                ir_codes         = &ir_codes_apac_viewcomp_table;
 307                ir->mask_keycode = 0x001f00;
 308                ir->mask_keyup   = 0x008000;
 309                ir->polling      = 50; // ms
 310                break;
 311        case BTTV_BOARD_ASKEY_CPH03X:
 312        case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
 313        case BTTV_BOARD_CONTVFMI:
 314                ir_codes         = &ir_codes_pixelview_table;
 315                ir->mask_keycode = 0x001F00;
 316                ir->mask_keyup   = 0x006000;
 317                ir->polling      = 50; // ms
 318                break;
 319        case BTTV_BOARD_NEBULA_DIGITV:
 320                ir_codes = &ir_codes_nebula_table;
 321                btv->custom_irq = bttv_rc5_irq;
 322                ir->rc5_gpio = 1;
 323                break;
 324        case BTTV_BOARD_MACHTV_MAGICTV:
 325                ir_codes         = &ir_codes_apac_viewcomp_table;
 326                ir->mask_keycode = 0x001F00;
 327                ir->mask_keyup   = 0x004000;
 328                ir->polling      = 50; /* ms */
 329                break;
 330        case BTTV_BOARD_KOZUMI_KTV_01C:
 331                ir_codes         = &ir_codes_pctv_sedna_table;
 332                ir->mask_keycode = 0x001f00;
 333                ir->mask_keyup   = 0x006000;
 334                ir->polling      = 50; /* ms */
 335                break;
 336        case BTTV_BOARD_ENLTV_FM_2:
 337                ir_codes         = &ir_codes_encore_enltv2_table;
 338                ir->mask_keycode = 0x00fd00;
 339                ir->mask_keyup   = 0x000080;
 340                ir->polling      = 1; /* ms */
 341                ir->last_gpio    = ir_extract_bits(bttv_gpio_read(&btv->c),
 342                                                   ir->mask_keycode);
 343                break;
 344        }
 345        if (NULL == ir_codes) {
 346                dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type);
 347                err = -ENODEV;
 348                goto err_out_free;
 349        }
 350
 351        if (ir->rc5_gpio) {
 352                u32 gpio;
 353                /* enable remote irq */
 354                bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
 355                gpio = bttv_gpio_read(&btv->c);
 356                bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
 357                bttv_gpio_write(&btv->c, gpio | (1 << 4));
 358        } else {
 359                /* init hardware-specific stuff */
 360                bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0);
 361        }
 362
 363        /* init input device */
 364        ir->dev = input_dev;
 365
 366        snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
 367                 btv->c.type);
 368        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 369                 pci_name(btv->c.pci));
 370
 371        ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
 372        input_dev->name = ir->name;
 373        input_dev->phys = ir->phys;
 374        input_dev->id.bustype = BUS_PCI;
 375        input_dev->id.version = 1;
 376        if (btv->c.pci->subsystem_vendor) {
 377                input_dev->id.vendor  = btv->c.pci->subsystem_vendor;
 378                input_dev->id.product = btv->c.pci->subsystem_device;
 379        } else {
 380                input_dev->id.vendor  = btv->c.pci->vendor;
 381                input_dev->id.product = btv->c.pci->device;
 382        }
 383        input_dev->dev.parent = &btv->c.pci->dev;
 384
 385        btv->remote = ir;
 386        bttv_ir_start(btv, ir);
 387
 388        /* all done */
 389        err = input_register_device(btv->remote->dev);
 390        if (err)
 391                goto err_out_stop;
 392
 393        /* the remote isn't as bouncy as a keyboard */
 394        ir->dev->rep[REP_DELAY] = repeat_delay;
 395        ir->dev->rep[REP_PERIOD] = repeat_period;
 396
 397        return 0;
 398
 399 err_out_stop:
 400        bttv_ir_stop(btv);
 401        btv->remote = NULL;
 402 err_out_free:
 403        input_free_device(input_dev);
 404        kfree(ir);
 405        return err;
 406}
 407
 408void bttv_input_fini(struct bttv *btv)
 409{
 410        if (btv->remote == NULL)
 411                return;
 412
 413        bttv_ir_stop(btv);
 414        input_unregister_device(btv->remote->dev);
 415        kfree(btv->remote);
 416        btv->remote = NULL;
 417}
 418
 419
 420/*
 421 * Local variables:
 422 * c-basic-offset: 8
 423 * End:
 424 */
 425