/** * ir_input_register() - sets the IR keycode table and add the handlers * for keymap table get/set * @input_dev: the struct input_dev descriptor of the device * @rc_tab: the struct ir_scancode_table table of scancode/keymap * * This routine is used to initialize the input infrastructure to work with * an IR. * It should be called before registering the IR device. */ int ir_input_register(struct input_dev *input_dev, struct ir_scancode_table *rc_tab) { struct ir_input_dev *ir_dev; struct ir_scancode *keymap = rc_tab->scan; int i, rc; if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); if (!ir_dev) return -ENOMEM; spin_lock_init(&rc_tab->lock); ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size); ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size * sizeof(struct ir_scancode), GFP_KERNEL); if (!ir_dev->rc_tab.scan) return -ENOMEM; IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", ir_dev->rc_tab.size, ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan)); ir_copy_table(&ir_dev->rc_tab, rc_tab); /* set the bits for the keys */ IR_dprintk(1, "key map size: %d\n", rc_tab->size); for (i = 0; i < rc_tab->size; i++) { IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n", i, keymap[i].keycode); set_bit(keymap[i].keycode, input_dev->keybit); } clear_bit(0, input_dev->keybit); set_bit(EV_KEY, input_dev->evbit); input_dev->getkeycode = ir_getkeycode; input_dev->setkeycode = ir_setkeycode; input_set_drvdata(input_dev, ir_dev); rc = input_register_device(input_dev); if (rc < 0) { kfree(rc_tab->scan); kfree(ir_dev); input_set_drvdata(input_dev, NULL); } return rc; }
/** * ir_getkeycode() - get a keycode from the scancode->keycode table * @dev: the struct input_dev device descriptor * @scancode: the desired scancode * @keycode: used to return the keycode, if found, or KEY_RESERVED * @return: always returns zero. * * This routine is used to handle evdev EVIOCGKEY ioctl. */ static int ir_getkeycode(struct input_dev *dev, unsigned int scancode, unsigned int *keycode) { int start, end, mid; unsigned long flags; int key = KEY_RESERVED; struct ir_input_dev *ir_dev = input_get_drvdata(dev); struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; spin_lock_irqsave(&rc_tab->lock, flags); start = 0; end = rc_tab->len - 1; while (start <= end) { mid = (start + end) / 2; if (rc_tab->scan[mid].scancode < scancode) start = mid + 1; else if (rc_tab->scan[mid].scancode > scancode) end = mid - 1; else { key = rc_tab->scan[mid].keycode; break; } } spin_unlock_irqrestore(&rc_tab->lock, flags); if (key == KEY_RESERVED) IR_dprintk(1, "unknown key for scancode 0x%04x\n", scancode); *keycode = key; return 0; }
/** * ir_setkeytable() - sets several entries in the scancode->keycode table * @dev: the struct input_dev device descriptor * @to: the struct ir_scancode_table to copy entries to * @from: the struct ir_scancode_table to copy entries from * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. * * This routine is used to handle table initialization. */ static int ir_setkeytable(struct ir_input_dev *ir_dev, const struct ir_scancode_table *from) { struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; unsigned int i, index; int rc; rc = ir_create_table(&ir_dev->rc_tab, from->name, from->ir_type, from->size); if (rc) return rc; IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", rc_tab->size, rc_tab->alloc); for (i = 0; i < from->size; i++) { index = ir_establish_scancode(ir_dev, rc_tab, from->scan[i].scancode, false); if (index >= rc_tab->len) { rc = -ENOMEM; break; } ir_update_mapping(ir_dev->input_dev, rc_tab, index, from->scan[i].keycode); } if (rc) ir_free_table(rc_tab); return rc; }
/** * ir_input_unregister() - unregisters IR and frees resources * @input_dev: the struct input_dev descriptor of the device * This routine is used to free memory and de-register interfaces. */ void ir_input_unregister(struct input_dev *input_dev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); struct ir_scancode_table *rc_tab; if (!ir_dev) return; IR_dprintk(1, "Freed keycode table\n"); del_timer_sync(&ir_dev->timer_keyup); if (ir_dev->props) if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ir_raw_event_unregister(input_dev); rc_tab = &ir_dev->rc_tab; rc_tab->size = 0; kfree(rc_tab->scan); rc_tab->scan = NULL; ir_unregister_class(input_dev); kfree(ir_dev->driver_name); kfree(ir_dev); }
/** * store_protocol() - shows the current IR protocol * @d: the device descriptor * @mattr: the device attribute struct (unused) * @buf: a pointer to the input buffer * @len: length of the input buffer * * This routine is a callback routine for changing the IR protocol type. * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol. * It changes the IR the protocol name, if the IR type is recognized * by the driver. * If an unknown protocol name is used, returns -EINVAL. */ static ssize_t store_protocol(struct device *d, struct device_attribute *mattr, const char *data, size_t len) { struct ir_input_dev *ir_dev = dev_get_drvdata(d); u64 ir_type = IR_TYPE_UNKNOWN; int rc = -EINVAL; unsigned long flags; char *buf; buf = strsep((char **) &data, "\n"); if (!strcasecmp(buf, "rc-5")) ir_type = IR_TYPE_RC5; else if (!strcasecmp(buf, "pd")) ir_type = IR_TYPE_PD; else if (!strcasecmp(buf, "nec")) ir_type = IR_TYPE_NEC; if (ir_type == IR_TYPE_UNKNOWN) { IR_dprintk(1, "Error setting protocol to %lld\n", (long long)ir_type); return -EINVAL; } if (ir_dev->props && ir_dev->props->change_protocol) rc = ir_dev->props->change_protocol(ir_dev->props->priv, ir_type); if (rc < 0) { IR_dprintk(1, "Error setting protocol to %lld\n", (long long)ir_type); return -EINVAL; } spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); ir_dev->rc_tab.ir_type = ir_type; spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type); return len; }
/** * ir_keyup() - generates input event to cleanup a key press * @ir: the struct ir_input_dev descriptor of the device * * This routine is used to signal that a key has been released on the * remote control. It reports a keyup input event via input_report_key(). */ static void ir_keyup(struct ir_input_dev *ir) { if (!ir->keypressed) return; IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode); input_report_key(ir->input_dev, ir->last_keycode, 0); input_sync(ir->input_dev); ir->keypressed = false; }
/** * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode * @input_dev: the struct input_dev descriptor of the device * @scancode: the scancode that we're seeking * * This routine is used by the input routines when a key is pressed at the * IR. The scancode is received and needs to be converted into a keycode. * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the * corresponding keycode from the table. */ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) { int keycode; ir_getkeycode(dev, scancode, &keycode); if (keycode != KEY_RESERVED) IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", dev->name, scancode, keycode); return keycode; }
/** * ir_update_mapping() - set a keycode in the scancode->keycode table * @dev: the struct input_dev device descriptor * @rc_tab: scancode table to be adjusted * @index: index of the mapping that needs to be updated * @keycode: the desired keycode * @return: previous keycode assigned to the mapping * * This routine is used to update scancode->keycopde mapping at given * position. */ static unsigned int ir_update_mapping(struct input_dev *dev, struct ir_scancode_table *rc_tab, unsigned int index, unsigned int new_keycode) { int old_keycode = rc_tab->scan[index].keycode; int i; /* Did the user wish to remove the mapping? */ if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", index, rc_tab->scan[index].scancode); rc_tab->len--; memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1], (rc_tab->len - index) * sizeof(struct ir_scancode)); } else { IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", index, old_keycode == KEY_RESERVED ? "New" : "Replacing", rc_tab->scan[index].scancode, new_keycode); rc_tab->scan[index].keycode = new_keycode; __set_bit(new_keycode, dev->keybit); } if (old_keycode != KEY_RESERVED) { /* A previous mapping was updated... */ __clear_bit(old_keycode, dev->keybit); /* ... but another scancode might use the same keycode */ for (i = 0; i < rc_tab->len; i++) { if (rc_tab->scan[i].keycode == old_keycode) { __set_bit(old_keycode, dev->keybit); break; } } /* Possibly shrink the keytable, failure is not a problem */ ir_resize_table(rc_tab, GFP_ATOMIC); } return old_keycode; }
void ir_raw_event_set_idle(struct input_dev *input_dev, int idle) { struct ir_input_dev *ir = input_get_drvdata(input_dev); struct ir_raw_event_ctrl *raw = ir->raw; ktime_t now; u64 delta; if (!ir->props) return; if (!ir->raw) goto out; if (idle) { IR_dprintk(2, "enter idle mode\n"); raw->last_event = ktime_get(); } else { IR_dprintk(2, "exit idle mode\n"); now = ktime_get(); delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); WARN_ON(raw->this_ev.pulse); raw->this_ev.duration = min(raw->this_ev.duration + delta, (u64)IR_MAX_DURATION); ir_raw_event_store(input_dev, &raw->this_ev); if (raw->this_ev.duration == IR_MAX_DURATION) ir_raw_event_reset(input_dev); raw->this_ev.duration = 0; } out: if (ir->props->s_idle) ir->props->s_idle(ir->props->priv, idle); ir->idle = idle; }
/** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders * @dev: the struct rc_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a * pulse/space duration for the raw ir decoding state machines. Pulses are * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) { if (!dev->raw) return -EINVAL; IR_dprintk(2, "sample: (%05dus %s)\n", TO_US(ev->duration), TO_STR(ev->pulse)); if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) return -ENOMEM; return 0; }
/** * ir_resize_table() - resizes a scancode table if necessary * @rc_tab: the ir_scancode_table to resize * @return: zero on success or a negative error code * * This routine will shrink the ir_scancode_table if it has lots of * unused entries and grow it if it is full. */ static int ir_resize_table(struct ir_scancode_table *rc_tab) { unsigned int oldalloc = rc_tab->alloc; unsigned int newalloc = oldalloc; struct ir_scancode *oldscan = rc_tab->scan; struct ir_scancode *newscan; if (rc_tab->size == rc_tab->len) { /* All entries in use -> grow keytable */ if (rc_tab->alloc >= IR_TAB_MAX_SIZE) return -ENOMEM; newalloc *= 2; IR_dprintk(1, "Growing table to %u bytes\n", newalloc); } if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) { /* Less than 1/3 of entries in use -> shrink keytable */ newalloc /= 2; IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); } if (newalloc == oldalloc) return 0; newscan = kmalloc(newalloc, GFP_ATOMIC); if (!newscan) { IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); return -ENOMEM; } memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode)); rc_tab->scan = newscan; rc_tab->alloc = newalloc; rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); kfree(oldscan); return 0; }
/** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders * @dev: the struct rc_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a * pulse/space duration for the raw ir decoding state machines. Pulses are * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) { if (!dev->raw) return -EINVAL; IR_dprintk(2, "sample: (%05dus %s)\n", TO_US(ev->duration), TO_STR(ev->pulse)); if (!kfifo_put(&dev->raw->kfifo, *ev)) { dev_err(&dev->dev, "IR event FIFO is full!\n"); return -ENOSPC; } return 0; }
/** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders * @input_dev: the struct input_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a * pulse/space duration for the raw ir decoding state machines. Pulses are * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) { struct ir_input_dev *ir = input_get_drvdata(input_dev); if (!ir->raw) return -EINVAL; IR_dprintk(2, "sample: (05%dus %s)\n", TO_US(ev->duration), TO_STR(ev->pulse)); if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) return -ENOMEM; return 0; }
/** * ir_create_table() - initializes a scancode table * @rc_tab: the ir_scancode_table to initialize * @name: name to assign to the table * @ir_type: ir type to assign to the new table * @size: initial size of the table * @return: zero on success or a negative error code * * This routine will initialize the ir_scancode_table and will allocate * memory to hold at least the specified number elements. */ static int ir_create_table(struct ir_scancode_table *rc_tab, const char *name, u64 ir_type, size_t size) { rc_tab->name = name; rc_tab->ir_type = ir_type; rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); if (!rc_tab->scan) return -ENOMEM; IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", rc_tab->size, rc_tab->alloc); return 0; }
static void mce_kbd_rx_timeout(unsigned long data) { struct mce_kbd_dec *mce_kbd = (struct mce_kbd_dec *)data; int i; unsigned char maskcode; IR_dprintk(2, "timer callback clearing all keys\n"); for (i = 0; i < 7; i++) { maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; input_report_key(mce_kbd->idev, maskcode, 0); } for (i = 0; i < MCIR2_MASK_KEYS_START; i++) input_report_key(mce_kbd->idev, kbd_keycodes[i], 0); }
void ir_input_unregister(struct input_dev *dev) { struct ir_input_dev *ir_dev = input_get_drvdata(dev); struct ir_scancode_table *rc_tab; if (!ir_dev) return; IR_dprintk(1, "Freed keycode table\n"); rc_tab = &ir_dev->rc_tab; rc_tab->size = 0; kfree(rc_tab->scan); rc_tab->scan = NULL; kfree(ir_dev); input_unregister_device(dev); }
/** * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not * @dev: the struct rc_dev device descriptor * @idle: whether the device is idle or not */ void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) { if (!dev->raw) return; IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); if (idle) { dev->raw->this_ev.timeout = true; ir_raw_event_store(dev, &dev->raw->this_ev); init_ir_raw_event(&dev->raw->this_ev); } if (dev->s_idle) dev->s_idle(dev, idle); dev->idle = idle; }
int ir_copy_table(struct ir_scancode_table *destin, const struct ir_scancode_table *origin) { int i, j = 0; for (i = 0; i < origin->size; i++) { if (origin->scan[i].keycode == KEY_UNKNOWN || origin->scan[i].keycode == KEY_RESERVED) continue; memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode)); j++; } destin->size = j; IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size); return 0; }
/** * ir_keydown() - generates input event for a key press * @dev: the struct input_dev descriptor of the device * @scancode: the scancode that we're seeking * @toggle: the toggle value (protocol dependent, if the protocol doesn't * support toggle values, this should be set to zero) * * This routine is used by the input routines when a key is pressed at the * IR. It gets the keycode for a scancode and reports an input event via * input_report_key(). */ void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) { unsigned long flags; struct ir_input_dev *ir = input_get_drvdata(dev); u32 keycode = ir_g_keycode_from_table(dev, scancode); spin_lock_irqsave(&ir->keylock, flags); input_event(dev, EV_MSC, MSC_SCAN, scancode); /* Repeat event? */ if (ir->keypressed && ir->last_scancode == scancode && ir->last_toggle == toggle) goto set_timer; /* Release old keypress */ ir_keyup(ir); ir->last_scancode = scancode; ir->last_toggle = toggle; ir->last_keycode = keycode; if (keycode == KEY_RESERVED) goto out; /* Register a keypress */ ir->keypressed = true; IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", dev->name, keycode, scancode); input_report_key(dev, ir->last_keycode, 1); input_sync(dev); set_timer: ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); mod_timer(&ir->timer_keyup, ir->keyup_jiffies); out: spin_unlock_irqrestore(&ir->keylock, flags); }
/** * ir_getkeycode() - get a keycode from the scancode->keycode table * @dev: the struct input_dev device descriptor * @scancode: the desired scancode * @keycode: used to return the keycode, if found, or KEY_RESERVED * @return: always returns zero. * * This routine is used to handle evdev EVIOCGKEY ioctl. */ static int ir_getkeycode(struct input_dev *dev, struct input_keymap_entry *ke) { struct ir_input_dev *ir_dev = input_get_drvdata(dev); struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; struct ir_scancode *entry; unsigned long flags; unsigned int index; unsigned int scancode; int retval; spin_lock_irqsave(&rc_tab->lock, flags); if (ke->flags & INPUT_KEYMAP_BY_INDEX) { index = ke->index; } else { retval = input_scancode_to_scalar(ke, &scancode); if (retval) goto out; index = ir_lookup_by_scancode(rc_tab, scancode); } if (index >= rc_tab->len) { if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) IR_dprintk(1, "unknown key for scancode 0x%04x\n", scancode); retval = -EINVAL; goto out; } entry = &rc_tab->scan[index]; ke->index = index; ke->keycode = entry->keycode; ke->len = sizeof(entry->scancode); memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); out: spin_unlock_irqrestore(&rc_tab->lock, flags); return retval; }
/** * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode * @input_dev: the struct input_dev descriptor of the device * @scancode: the scancode that we're seeking * * This routine is used by the input routines when a key is pressed at the * IR. The scancode is received and needs to be converted into a keycode. * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the * corresponding keycode from the table. */ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) { struct ir_input_dev *ir_dev = input_get_drvdata(dev); struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; struct ir_scancode *keymap = rc_tab->scan; int elem; elem = ir_seek_table(rc_tab, scancode); if (elem >= 0) { IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", dev->name, scancode, keymap[elem].keycode); return rc_tab->scan[elem].keycode; } printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n", dev->name, scancode); /* Reports userspace that an unknown keycode were got */ return KEY_RESERVED; }
/** * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not * @dev: the struct rc_dev device descriptor * @idle: whether the device is idle or not */ void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) { if (!dev->raw) return; #ifdef CONFIG_DEBUG_PRINTK IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); #else IR_d; #endif if (idle) { dev->raw->this_ev.timeout = true; ir_raw_event_store(dev, &dev->raw->this_ev); init_ir_raw_event(&dev->raw->this_ev); } if (dev->s_idle) dev->s_idle(dev, idle); dev->idle = idle; }
/** * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode * @input_dev: the struct input_dev descriptor of the device * @scancode: the scancode that we're seeking * * This routine is used by the input routines when a key is pressed at the * IR. The scancode is received and needs to be converted into a keycode. * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the * corresponding keycode from the table. */ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) { struct ir_input_dev *ir_dev = input_get_drvdata(dev); struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; unsigned int keycode; unsigned int index; unsigned long flags; spin_lock_irqsave(&rc_tab->lock, flags); index = ir_lookup_by_scancode(rc_tab, scancode); keycode = index < rc_tab->len ? rc_tab->scan[index].keycode : KEY_RESERVED; spin_unlock_irqrestore(&rc_tab->lock, flags); if (keycode != KEY_RESERVED) IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", dev->name, scancode, keycode); return keycode; }
/** * show_protocol() - shows the current IR protocol * @d: the device descriptor * @mattr: the device attribute struct (unused) * @buf: a pointer to the output buffer * * This routine is a callback routine for input read the IR protocol type. * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol. * It returns the protocol name, as understood by the driver. */ static ssize_t show_protocol(struct device *d, struct device_attribute *mattr, char *buf) { char *s; struct ir_input_dev *ir_dev = dev_get_drvdata(d); u64 ir_type = ir_dev->rc_tab.ir_type; IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type); /* FIXME: doesn't support multiple protocols at the same time */ if (ir_type == IR_TYPE_UNKNOWN) s = "Unknown"; else if (ir_type == IR_TYPE_RC5) s = "RC-5"; else if (ir_type == IR_TYPE_PD) s = "Pulse/distance"; else if (ir_type == IR_TYPE_NEC) s = "NEC"; else s = "Other"; return sprintf(buf, "%s\n", s); }
/** * ir_insert_key() - insert a keycode at the table * @rc_tab: keycode table * @scancode: the desired scancode * @keycode: the keycode to be retorned. * */ static int ir_insert_key(struct ir_scancode_table *rc_tab, int scancode, int keycode) { unsigned long flags; int elem = rc_tab->size; int newsize = rc_tab->size + 1; int resize = ir_is_resize_needed(rc_tab, newsize); struct ir_scancode *oldkeymap = rc_tab->scan; struct ir_scancode *newkeymap; if (resize) { newkeymap = kzalloc(ir_roundup_tablesize(newsize) * sizeof(*newkeymap), GFP_ATOMIC); if (!newkeymap) return -ENOMEM; memcpy(newkeymap, oldkeymap, rc_tab->size * sizeof(*newkeymap)); } else newkeymap = oldkeymap; /* Stores the new code at the table */ IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n", rc_tab->size, scancode, keycode); spin_lock_irqsave(&rc_tab->lock, flags); rc_tab->size = newsize; if (resize) { rc_tab->scan = newkeymap; kfree(oldkeymap); } newkeymap[elem].scancode = scancode; newkeymap[elem].keycode = keycode; spin_unlock_irqrestore(&rc_tab->lock, flags); return 0; }
/** * ir_sanyo_decode() - Decode one SANYO pulse or space * @dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct sanyo_dec *data = &dev->raw->sanyo; u32 scancode; u8 address, command, not_command; if (!(dev->raw->enabled_protocols & RC_BIT_SANYO)) return 0; if (!is_timing_event(ev)) { if (ev.reset) { IR_dprintk(1, "SANYO event reset received. reset to state 0\n"); data->state = STATE_INACTIVE; } return 0; } IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) { data->count = 0; data->state = STATE_HEADER_SPACE; return 0; } break; case STATE_HEADER_SPACE: if (ev.pulse) break; if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } break; case STATE_BIT_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2)) break; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { if (!dev->keypressed) { IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n"); } else { rc_repeat(dev); IR_dprintk(1, "SANYO repeat last key\n"); data->state = STATE_INACTIVE; } return 0; } data->bits <<= 1; if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2)) break; data->count++; if (data->count == SANYO_NBITS) data->state = STATE_TRAILER_PULSE; else data->state = STATE_BIT_PULSE; return 0; case STATE_TRAILER_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2)) break; data->state = STATE_TRAILER_SPACE; return 0; case STATE_TRAILER_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2)) break; address = bitrev16((data->bits >> 29) & 0x1fff) >> 3; /* not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; */ command = bitrev8((data->bits >> 8) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff); if ((command ^ not_command) != 0xff) { IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n", data->bits); data->state = STATE_INACTIVE; return 0; } scancode = address << 8 | command; IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode); rc_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n", data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_rc6_decode() - Decode one RC6 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc6_dec *data = &dev->raw->rc6; u32 scancode; u8 toggle; enum rc_proto protocol; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) goto out; again: IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; /* Note: larger margin on first pulse since each RC6_UNIT is quite short and some hardware takes some time to adjust to the signal */ if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) break; data->state = STATE_PREFIX_SPACE; data->count = 0; return 0; case STATE_PREFIX_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2)) break; data->state = STATE_HEADER_BIT_START; data->header = 0; return 0; case STATE_HEADER_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->header <<= 1; if (ev.pulse) data->header |= 1; data->count++; data->state = STATE_HEADER_BIT_END; return 0; case STATE_HEADER_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == RC6_HEADER_NBITS) data->state = STATE_TOGGLE_START; else data->state = STATE_HEADER_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_TOGGLE_START: if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2)) break; data->toggle = ev.pulse; data->state = STATE_TOGGLE_END; return 0; case STATE_TOGGLE_END: if (!is_transition(&ev, &dev->raw->prev_ev) || !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) break; if (!(data->header & RC6_STARTBIT_MASK)) { IR_dprintk(1, "RC6 invalid start bit\n"); break; } data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_TOGGLE_END); data->count = 0; data->body = 0; switch (rc6_mode(data)) { case RC6_MODE_0: data->wanted_bits = RC6_0_NBITS; break; case RC6_MODE_6A: data->wanted_bits = RC6_6A_NBITS; break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } goto again; case STATE_BODY_BIT_START: if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) { /* Discard LSB's that won't fit in data->body */ if (data->count++ < CHAR_BIT * sizeof data->body) { data->body <<= 1; if (ev.pulse) data->body |= 1; } data->state = STATE_BODY_BIT_END; return 0; } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse && geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) { data->state = STATE_FINISHED; goto again; } break; case STATE_BODY_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_FINISHED: if (ev.pulse) break; switch (rc6_mode(data)) { case RC6_MODE_0: scancode = data->body; toggle = data->toggle; protocol = RC_PROTO_RC6_0; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; case RC6_MODE_6A: if (data->count > CHAR_BIT * sizeof data->body) { IR_dprintk(1, "RC6 too many (%u) data bits\n", data->count); goto out; } scancode = data->body; switch (data->count) { case 20: protocol = RC_PROTO_RC6_6A_20; toggle = 0; break; case 24: protocol = RC_PROTO_RC6_6A_24; toggle = 0; break; case 32: if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { protocol = RC_PROTO_RC6_MCE; toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); scancode &= ~RC6_6A_MCE_TOGGLE_MASK; } else { protocol = RC_PROTO_RC6_6A_32; toggle = 0; } break; default: IR_dprintk(1, "RC6(6A) unsupported length\n"); goto out; } IR_dprintk(1, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n", protocol, scancode, toggle); break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } rc_keydown(dev, protocol, scancode, toggle); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_rc5_decode() - Decode one RC-5 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc5_dec *data = &dev->raw->rc5; u8 toggle; u32 scancode; if (!(dev->raw->enabled_protocols & RC_TYPE_RC5)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) goto out; again: IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; data->state = STATE_BIT_START; data->count = 1; /* We just need enough bits to get to STATE_CHECK_RC5X */ data->wanted_bits = RC5X_NBITS; decrease_duration(&ev, RC5_BIT_START); goto again; case STATE_BIT_START: if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) break; data->bits <<= 1; if (!ev.pulse) data->bits |= 1; data->count++; data->state = STATE_BIT_END; return 0; case STATE_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else if (data->count == CHECK_RC5X_NBITS) data->state = STATE_CHECK_RC5X; else data->state = STATE_BIT_START; decrease_duration(&ev, RC5_BIT_END); goto again; case STATE_CHECK_RC5X: if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) { /* RC5X */ data->wanted_bits = RC5X_NBITS; decrease_duration(&ev, RC5X_SPACE); } else { /* RC5 */ data->wanted_bits = RC5_NBITS; } data->state = STATE_BIT_START; goto again; case STATE_FINISHED: if (ev.pulse) break; if (data->wanted_bits == RC5X_NBITS) { /* RC5X */ u8 xdata, command, system; xdata = (data->bits & 0x0003F) >> 0; command = (data->bits & 0x00FC0) >> 6; system = (data->bits & 0x1F000) >> 12; toggle = (data->bits & 0x20000) ? 1 : 0; command += (data->bits & 0x01000) ? 0 : 0x40; scancode = system << 16 | command << 8 | xdata; IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n", scancode, toggle); } else {
/** * ir_nec_decode() - Decode one NEC pulse or space * @input_dev: the struct input_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); struct nec_dec *data = &ir_dev->raw->nec; u32 scancode; u8 address, not_address, command, not_command; if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) return 0; if (IS_RESET(ev)) { data->state = STATE_INACTIVE; return 0; } IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2)) { data->is_nec_x = false; data->necx_repeat = false; } else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) data->is_nec_x = true; else break; data->count = 0; data->state = STATE_HEADER_SPACE; return 0; case STATE_HEADER_SPACE: if (ev.pulse) break; if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { ir_repeat(input_dev); IR_dprintk(1, "Repeat last key\n"); data->state = STATE_TRAILER_PULSE; return 0; } break; case STATE_BIT_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2)) break; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (data->necx_repeat && data->count == NECX_REPEAT_BITS && geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) { IR_dprintk(1, "Repeat last key\n"); ir_repeat(input_dev); data->state = STATE_INACTIVE; return 0; } else if (data->count > NECX_REPEAT_BITS) data->necx_repeat = false; data->bits <<= 1; if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2)) break; data->count++; if (data->count == NEC_NBITS) data->state = STATE_TRAILER_PULSE; else data->state = STATE_BIT_PULSE; return 0; case STATE_TRAILER_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2)) break; data->state = STATE_TRAILER_SPACE; return 0; case STATE_TRAILER_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) break; address = bitrev8((data->bits >> 24) & 0xff); not_address = bitrev8((data->bits >> 16) & 0xff); command = bitrev8((data->bits >> 8) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff); if ((command ^ not_command) != 0xff) { IR_dprintk(1, "NEC checksum error: received 0x%08x\n", data->bits); break; } if ((address ^ not_address) != 0xff) { /* Extended NEC */ scancode = address << 16 | not_address << 8 | command; IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); } else { /* Normal NEC */ scancode = address << 8 | command; IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); } if (data->is_nec_x) data->necx_repeat = true; ir_keydown(input_dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the * lircd userspace daemon for decoding. * @input_dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the lirc interfaces aren't wired up. */ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct lirc_codec *lirc = &dev->raw->lirc; int sample; if (!(dev->raw->enabled_protocols & RC_BIT_LIRC)) return 0; if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) return -EINVAL; /* Packet start */ if (ev.reset) return 0; /* Carrier reports */ if (ev.carrier_report) { sample = LIRC_FREQUENCY(ev.carrier); IR_dprintk(2, "carrier report (freq: %d)\n", sample); /* Packet end */ } else if (ev.timeout) { if (lirc->gap) return 0; lirc->gap_start = ktime_get(); lirc->gap = true; lirc->gap_duration = ev.duration; if (!lirc->send_timeout_reports) return 0; sample = LIRC_TIMEOUT(ev.duration / 1000); IR_dprintk(2, "timeout report (duration: %d)\n", sample); /* Normal sample */ } else { if (lirc->gap) { int gap_sample; lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), lirc->gap_start)); /* Convert to ms and cap by LIRC_VALUE_MASK */ do_div(lirc->gap_duration, 1000); lirc->gap_duration = min(lirc->gap_duration, (u64)LIRC_VALUE_MASK); gap_sample = LIRC_SPACE(lirc->gap_duration); lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &gap_sample); lirc->gap = false; } sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : LIRC_SPACE(ev.duration / 1000); IR_dprintk(2, "delivering %uus %s to lirc_dev\n", TO_US(ev.duration), TO_STR(ev.pulse)); } lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &sample); wake_up(&dev->raw->lirc.drv->rbuf->wait_poll); return 0; }