map = seek_rc_map(name); #ifdef CONFIG_MODULES if (!map) { int rc = request_module("%s", name); if (rc < 0) {
pr_err("Couldn't load IR keymap %s\n", name); return NULL;
}
msleep(20); /* Give some time for IR to register */
map = seek_rc_map(name);
} #endif if (!map) {
pr_err("IR keymap %s not found\n", name); return NULL;
}
printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
/** * scancode_to_u64() - converts scancode in &struct input_keymap_entry * @ke: keymap entry containing scancode to be converted. * @scancode: pointer to the location where converted scancode should * be stored. * * This function is a version of input_scancode_to_scalar specialized for * rc-core.
*/ staticint scancode_to_u64(conststruct input_keymap_entry *ke, u64 *scancode)
{ switch (ke->len) { case 1:
*scancode = *((u8 *)ke->scancode); break;
case 2:
*scancode = *((u16 *)ke->scancode); break;
case 4:
*scancode = *((u32 *)ke->scancode); break;
case 8:
*scancode = *((u64 *)ke->scancode); break;
default: return -EINVAL;
}
return 0;
}
/** * ir_create_table() - initializes a scancode table * @dev: the rc_dev device * @rc_map: the rc_map to initialize * @name: name to assign to the table * @rc_proto: ir type to assign to the new table * @size: initial size of the table * * This routine will initialize the rc_map and will allocate * memory to hold at least the specified number of elements. * * return: zero on success or a negative error code
*/ staticint ir_create_table(struct rc_dev *dev, struct rc_map *rc_map, constchar *name, u64 rc_proto, size_t size)
{
rc_map->name = kstrdup(name, GFP_KERNEL); if (!rc_map->name) return -ENOMEM;
rc_map->rc_proto = rc_proto;
rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table));
rc_map->size = rc_map->alloc / sizeof(struct rc_map_table);
rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL); if (!rc_map->scan) {
kfree(rc_map->name);
rc_map->name = NULL; return -ENOMEM;
}
dev_dbg(&dev->dev, "Allocated space for %u keycode entries (%u bytes)\n",
rc_map->size, rc_map->alloc); return 0;
}
/** * ir_free_table() - frees memory allocated by a scancode table * @rc_map: the table whose mappings need to be freed * * This routine will free memory alloctaed for key mappings used by given * scancode table.
*/ staticvoid ir_free_table(struct rc_map *rc_map)
{
rc_map->size = 0;
kfree(rc_map->name);
rc_map->name = NULL;
kfree(rc_map->scan);
rc_map->scan = NULL;
}
/** * ir_resize_table() - resizes a scancode table if necessary * @dev: the rc_dev device * @rc_map: the rc_map to resize * @gfp_flags: gfp flags to use when allocating memory * * This routine will shrink the rc_map if it has lots of * unused entries and grow it if it is full. * * return: zero on success or a negative error code
*/ staticint ir_resize_table(struct rc_dev *dev, struct rc_map *rc_map,
gfp_t gfp_flags)
{ unsignedint oldalloc = rc_map->alloc; unsignedint newalloc = oldalloc; struct rc_map_table *oldscan = rc_map->scan; struct rc_map_table *newscan;
if (rc_map->size == rc_map->len) { /* All entries in use -> grow keytable */ if (rc_map->alloc >= IR_TAB_MAX_SIZE) return -ENOMEM;
if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) { /* Less than 1/3 of entries in use -> shrink keytable */
newalloc /= 2;
dev_dbg(&dev->dev, "Shrinking table to %u bytes\n", newalloc);
}
if (newalloc == oldalloc) return 0;
newscan = kmalloc(newalloc, gfp_flags); if (!newscan) return -ENOMEM;
/** * ir_update_mapping() - set a keycode in the scancode->keycode table * @dev: the struct rc_dev device descriptor * @rc_map: scancode table to be adjusted * @index: index of the mapping that needs to be updated * @new_keycode: the desired keycode * * This routine is used to update scancode->keycode mapping at given * position. * * return: previous keycode assigned to the mapping *
*/ staticunsignedint ir_update_mapping(struct rc_dev *dev, struct rc_map *rc_map, unsignedint index, unsignedint new_keycode)
{ int old_keycode = rc_map->scan[index].keycode; int i;
/* Did the user wish to remove the mapping? */ if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\n",
index, rc_map->scan[index].scancode);
rc_map->len--;
memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
(rc_map->len - index) * sizeof(struct rc_map_table));
} else {
dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n",
index,
old_keycode == KEY_RESERVED ? "New" : "Replacing",
rc_map->scan[index].scancode, new_keycode);
rc_map->scan[index].keycode = new_keycode;
__set_bit(new_keycode, dev->input_dev->keybit);
}
if (old_keycode != KEY_RESERVED) { /* A previous mapping was updated... */
__clear_bit(old_keycode, dev->input_dev->keybit); /* ... but another scancode might use the same keycode */ for (i = 0; i < rc_map->len; i++) { if (rc_map->scan[i].keycode == old_keycode) {
__set_bit(old_keycode, dev->input_dev->keybit); break;
}
}
/* Possibly shrink the keytable, failure is not a problem */
ir_resize_table(dev, rc_map, GFP_ATOMIC);
}
return old_keycode;
}
/** * ir_establish_scancode() - set a keycode in the scancode->keycode table * @dev: the struct rc_dev device descriptor * @rc_map: scancode table to be searched * @scancode: the desired scancode * @resize: controls whether we allowed to resize the table to * accommodate not yet present scancodes * * This routine is used to locate given scancode in rc_map. * If scancode is not yet present the routine will allocate a new slot * for it. * * return: index of the mapping containing scancode in question * or -1U in case of failure.
*/ staticunsignedint ir_establish_scancode(struct rc_dev *dev, struct rc_map *rc_map,
u64 scancode, bool resize)
{ unsignedint i;
/* * Unfortunately, some hardware-based IR decoders don't provide * all bits for the complete IR code. In general, they provide only * the command part of the IR code. Yet, as it is possible to replace * the provided IR with another one, it is needed to allow loading * IR tables from other remotes. So, we support specifying a mask to * indicate the valid bits of the scancodes.
*/ if (dev->scancode_mask)
scancode &= dev->scancode_mask;
/* First check if we already have a mapping for this ir command */ for (i = 0; i < rc_map->len; i++) { if (rc_map->scan[i].scancode == scancode) return i;
/* Keytable is sorted from lowest to highest scancode */ if (rc_map->scan[i].scancode >= scancode) break;
}
/* No previous mapping found, we might need to grow the table */ if (rc_map->size == rc_map->len) { if (!resize || ir_resize_table(dev, rc_map, GFP_ATOMIC)) return -1U;
}
/* i is the proper index to insert our new keycode */ if (i < rc_map->len)
memmove(&rc_map->scan[i + 1], &rc_map->scan[i],
(rc_map->len - i) * sizeof(struct rc_map_table));
rc_map->scan[i].scancode = scancode;
rc_map->scan[i].keycode = KEY_RESERVED;
rc_map->len++;
return i;
}
/** * ir_setkeycode() - set a keycode in the scancode->keycode table * @idev: the struct input_dev device descriptor * @ke: Input keymap entry * @old_keycode: result * * This routine is used to handle evdev EVIOCSKEY ioctl. * * return: -EINVAL if the keycode could not be inserted, otherwise zero.
*/ staticint ir_setkeycode(struct input_dev *idev, conststruct input_keymap_entry *ke, unsignedint *old_keycode)
{ struct rc_dev *rdev = input_get_drvdata(idev); struct rc_map *rc_map = &rdev->rc_map; unsignedint index;
u64 scancode; int retval = 0; unsignedlong flags;
spin_lock_irqsave(&rc_map->lock, flags);
if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
index = ke->index; if (index >= rc_map->len) {
retval = -EINVAL; goto out;
}
} else {
retval = scancode_to_u64(ke, &scancode); if (retval) goto out;
index = ir_establish_scancode(rdev, rc_map, scancode, true); if (index >= rc_map->len) {
retval = -ENOMEM; goto out;
}
}
/** * ir_setkeytable() - sets several entries in the scancode->keycode table * @dev: the struct rc_dev device descriptor * @from: the struct rc_map to copy entries from * * This routine is used to handle table initialization. * * return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
*/ staticint ir_setkeytable(struct rc_dev *dev, conststruct rc_map *from)
{ struct rc_map *rc_map = &dev->rc_map; unsignedint i, index; int rc;
for (i = 0; i < from->size; i++) {
index = ir_establish_scancode(dev, rc_map,
from->scan[i].scancode, false); if (index >= rc_map->len) {
rc = -ENOMEM; break;
}
/** * ir_lookup_by_scancode() - locate mapping by scancode * @rc_map: the struct rc_map to search * @scancode: scancode to look for in the table * * This routine performs binary search in RC keykeymap table for * given scancode. * * return: index in the table, -1U if not found
*/ staticunsignedint ir_lookup_by_scancode(conststruct rc_map *rc_map,
u64 scancode)
{ struct rc_map_table *res;
res = bsearch(&scancode, rc_map->scan, rc_map->len, sizeof(struct rc_map_table), rc_map_cmp); if (!res) return -1U; else return res - rc_map->scan;
}
/** * ir_getkeycode() - get a keycode from the scancode->keycode table * @idev: the struct input_dev device descriptor * @ke: Input keymap entry * * This routine is used to handle evdev EVIOCGKEY ioctl. * * return: always returns zero.
*/ staticint ir_getkeycode(struct input_dev *idev, struct input_keymap_entry *ke)
{ struct rc_dev *rdev = input_get_drvdata(idev); struct rc_map *rc_map = &rdev->rc_map; struct rc_map_table *entry; unsignedlong flags; unsignedint index;
u64 scancode; int retval;
spin_lock_irqsave(&rc_map->lock, flags);
if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
index = ke->index;
} else {
retval = scancode_to_u64(ke, &scancode); if (retval) goto out;
index = ir_lookup_by_scancode(rc_map, scancode);
}
if (index < rc_map->len) {
entry = &rc_map->scan[index];
ke->index = index;
ke->keycode = entry->keycode;
ke->len = sizeof(entry->scancode);
memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
} elseif (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) { /* * We do not really know the valid range of scancodes * so let's respond with KEY_RESERVED to anything we * do not have mapping for [yet].
*/
ke->index = index;
ke->keycode = KEY_RESERVED;
} else {
retval = -EINVAL; goto out;
}
/** * rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode * @dev: the struct rc_dev descriptor of the device * @scancode: the scancode to look for * * This routine is used by drivers which need to convert a scancode to a * keycode. Normally it should not be used since drivers should have no * interest in keycodes. * * return: the corresponding keycode, or KEY_RESERVED
*/
u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode)
{ struct rc_map *rc_map = &dev->rc_map; unsignedint keycode; unsignedint index; unsignedlong flags;
spin_lock_irqsave(&rc_map->lock, flags);
index = ir_lookup_by_scancode(rc_map, scancode);
keycode = index < rc_map->len ?
rc_map->scan[index].keycode : KEY_RESERVED;
/** * ir_do_keyup() - internal function to signal the release of a keypress * @dev: the struct rc_dev descriptor of the device * @sync: whether or not to call input_sync * * This function is used internally to release a keypress, it must be * called with keylock held.
*/ staticvoid ir_do_keyup(struct rc_dev *dev, bool sync)
{ if (!dev->keypressed) return;
/** * rc_keyup() - signals the release of a keypress * @dev: the struct rc_dev descriptor of the device * * This routine is used to signal that a key has been released on the * remote control.
*/ void rc_keyup(struct rc_dev *dev)
{ unsignedlong flags;
/** * ir_timer_keyup() - generates a keyup event after a timeout * * @t: a pointer to the struct timer_list * * This routine will generate a keyup event some time after a keydown event * is generated when no further activity has been detected.
*/ staticvoid ir_timer_keyup(struct timer_list *t)
{ struct rc_dev *dev = timer_container_of(dev, t, timer_keyup); unsignedlong flags;
/* * ir->keyup_jiffies is used to prevent a race condition if a * hardware interrupt occurs at this point and the keyup timer * event is moved further into the future as a result. * * The timer will then be reactivated and this function called * again in the future. We need to exit gracefully in that case * to allow the input subsystem to do its auto-repeat magic or * a keyup event might follow immediately after the keydown.
*/
spin_lock_irqsave(&dev->keylock, flags); if (time_is_before_eq_jiffies(dev->keyup_jiffies))
ir_do_keyup(dev, true);
spin_unlock_irqrestore(&dev->keylock, flags);
}
/** * ir_timer_repeat() - generates a repeat event after a timeout * * @t: a pointer to the struct timer_list * * This routine will generate a soft repeat event every REP_PERIOD * milliseconds.
*/ staticvoid ir_timer_repeat(struct timer_list *t)
{ struct rc_dev *dev = timer_container_of(dev, t, timer_repeat); struct input_dev *input = dev->input_dev; unsignedlong flags;
spin_lock_irqsave(&dev->keylock, flags); if (dev->keypressed) {
input_event(input, EV_KEY, dev->last_keycode, 2);
input_sync(input); if (input->rep[REP_PERIOD])
mod_timer(&dev->timer_repeat, jiffies +
msecs_to_jiffies(input->rep[REP_PERIOD]));
}
spin_unlock_irqrestore(&dev->keylock, flags);
}
staticunsignedint repeat_period(int protocol)
{ if (protocol >= ARRAY_SIZE(protocols)) return 100;
return protocols[protocol].repeat_period;
}
/** * rc_repeat() - signals that a key is still pressed * @dev: the struct rc_dev descriptor of the device * * This routine is used by IR decoders when a repeat message which does * not include the necessary bits to reproduce the scancode has been * received.
*/ void rc_repeat(struct rc_dev *dev)
{ unsignedlong flags; unsignedint timeout = usecs_to_jiffies(dev->timeout) +
msecs_to_jiffies(repeat_period(dev->last_protocol)); struct lirc_scancode sc = {
.scancode = dev->last_scancode, .rc_proto = dev->last_protocol,
.keycode = dev->keypressed ? dev->last_keycode : KEY_RESERVED,
.flags = LIRC_SCANCODE_FLAG_REPEAT |
(dev->last_toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0)
};
if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
lirc_scancode_event(dev, &sc);
/** * ir_do_keydown() - internal function to process a keypress * @dev: the struct rc_dev descriptor of the device * @protocol: the protocol of the keypress * @scancode: the scancode of the keypress * @keycode: the keycode of the keypress * @toggle: the toggle value of the keypress * * This function is used internally to register a keypress, it must be * called with keylock held.
*/ staticvoid ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
u64 scancode, u32 keycode, u8 toggle)
{ bool new_event = (!dev->keypressed ||
dev->last_protocol != protocol ||
dev->last_scancode != scancode ||
dev->last_toggle != toggle); struct lirc_scancode sc = {
.scancode = scancode, .rc_proto = protocol,
.flags = (toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0) |
(!new_event ? LIRC_SCANCODE_FLAG_REPEAT : 0),
.keycode = keycode
};
if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
lirc_scancode_event(dev, &sc);
if (new_event && dev->keypressed)
ir_do_keyup(dev, false);
if (scancode <= U32_MAX)
input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
/* * For CEC, start sending repeat messages as soon as the first * repeated message is sent, as long as REP_DELAY = 0 and REP_PERIOD * is non-zero. Otherwise, the input layer will generate repeat * messages.
*/ if (!new_event && keycode != KEY_RESERVED &&
dev->allowed_protocols == RC_PROTO_BIT_CEC &&
!timer_pending(&dev->timer_repeat) &&
dev->input_dev->rep[REP_PERIOD] &&
!dev->input_dev->rep[REP_DELAY]) {
input_event(dev->input_dev, EV_KEY, keycode, 2);
mod_timer(&dev->timer_repeat, jiffies +
msecs_to_jiffies(dev->input_dev->rep[REP_PERIOD]));
}
input_sync(dev->input_dev);
}
/** * rc_keydown() - generates input event for a key press * @dev: the struct rc_dev descriptor of the device * @protocol: the protocol for the keypress * @scancode: the scancode for the keypress * @toggle: the toggle value (protocol dependent, if the protocol doesn't * support toggle values, this should be set to zero) * * This routine is used to signal that a key has been pressed on the * remote control.
*/ void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
u8 toggle)
{ unsignedlong flags;
u32 keycode = rc_g_keycode_from_table(dev, scancode);
/** * rc_keydown_notimeout() - generates input event for a key press without * an automatic keyup event at a later time * @dev: the struct rc_dev descriptor of the device * @protocol: the protocol for the keypress * @scancode: the scancode for the keypress * @toggle: the toggle value (protocol dependent, if the protocol doesn't * support toggle values, this should be set to zero) * * This routine is used to signal that a key has been pressed on the * remote control. The driver must manually call rc_keyup() at a later stage.
*/ void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
u64 scancode, u8 toggle)
{ unsignedlong flags;
u32 keycode = rc_g_keycode_from_table(dev, scancode);
/** * rc_validate_scancode() - checks that a scancode is valid for a protocol. * For nec, it should do the opposite of ir_nec_bytes_to_scancode() * @proto: protocol * @scancode: scancode
*/ bool rc_validate_scancode(enum rc_proto proto, u32 scancode)
{ switch (proto) { /* * NECX has a 16-bit address; if the lower 8 bits match the upper * 8 bits inverted, then the address would match regular nec.
*/ case RC_PROTO_NECX: if ((((scancode >> 16) ^ ~(scancode >> 8)) & 0xff) == 0) returnfalse; break; /* * NEC32 has a 16 bit address and 16 bit command. If the lower 8 bits * of the command match the upper 8 bits inverted, then it would * be either NEC or NECX.
*/ case RC_PROTO_NEC32: if ((((scancode >> 8) ^ ~scancode) & 0xff) == 0) returnfalse; break; /* * If the customer code (top 32-bit) is 0x800f, it is MCE else it * is regular mode-6a 32 bit
*/ case RC_PROTO_RC6_MCE: if ((scancode & 0xffff0000) != 0x800f0000) returnfalse; break; case RC_PROTO_RC6_6A_32: if ((scancode & 0xffff0000) == 0x800f0000) returnfalse; break; default: break;
}
returntrue;
}
/** * rc_validate_filter() - checks that the scancode and mask are valid and * provides sensible defaults * @dev: the struct rc_dev descriptor of the device * @filter: the scancode and mask * * return: 0 or -EINVAL if the filter is not valid
*/ staticint rc_validate_filter(struct rc_dev *dev, struct rc_scancode_filter *filter)
{
u32 mask, s = filter->data; enum rc_proto protocol = dev->wakeup_protocol;
if (protocol >= ARRAY_SIZE(protocols)) return -EINVAL;
mask = protocols[protocol].scancode_bits;
if (!rc_validate_scancode(protocol, s)) return -EINVAL;
filter->data &= mask;
filter->mask &= mask;
/* * If we have to raw encode the IR for wakeup, we cannot have a mask
*/ if (dev->encode_wakeup && filter->mask != 0 && filter->mask != mask) return -EINVAL;
return 0;
}
int rc_open(struct rc_dev *rdev)
{ int rval = 0;
if (!rdev) return -EINVAL;
mutex_lock(&rdev->lock);
if (!rdev->registered) {
rval = -ENODEV;
} else { if (!rdev->users++ && rdev->open)
rval = rdev->open(rdev);
/** * show_protocols() - shows the current IR protocol(s) * @device: the device descriptor * @mattr: the device attribute struct * @buf: a pointer to the output buffer * * This routine is a callback routine for input read the IR protocol type(s). * it is triggered by reading /sys/class/rc/rc?/protocols. * It returns the protocol names of supported protocols. * Enabled protocols are printed in brackets. * * dev->lock is taken to guard against races between * store_protocols and show_protocols.
*/ static ssize_t show_protocols(struct device *device, struct device_attribute *mattr, char *buf)
{ struct rc_dev *dev = to_rc_dev(device);
u64 allowed, enabled; char *tmp = buf; int i;
/** * parse_protocol_change() - parses a protocol change request * @dev: rc_dev device * @protocols: pointer to the bitmask of current protocols * @buf: pointer to the buffer with a list of changes * * Writing "+proto" will add a protocol to the protocol mask. * Writing "-proto" will remove a protocol from protocol mask. * Writing "proto" will enable only "proto". * Writing "none" will disable all protocols. * Returns the number of changes performed or a negative error code.
*/ staticint parse_protocol_change(struct rc_dev *dev, u64 *protocols, constchar *buf)
{ constchar *tmp; unsigned count = 0; bool enable, disable;
u64 mask; int i;
while ((tmp = strsep((char **)&buf, " \n")) != NULL) { if (!*tmp) break;
if (!count) {
dev_dbg(&dev->dev, "Protocol not specified\n"); return -EINVAL;
}
return count;
}
void ir_raw_load_modules(u64 *protocols)
{
u64 available; int i, ret;
for (i = 0; i < ARRAY_SIZE(proto_names); i++) { if (proto_names[i].type == RC_PROTO_BIT_NONE ||
proto_names[i].type & (RC_PROTO_BIT_OTHER |
RC_PROTO_BIT_UNKNOWN)) continue;
available = ir_raw_get_allowed_protocols(); if (!(*protocols & proto_names[i].type & ~available)) continue;
if (!proto_names[i].module_name) {
pr_err("Can't enable IR protocol %s\n",
proto_names[i].name);
*protocols &= ~proto_names[i].type; continue;
}
ret = request_module("%s", proto_names[i].module_name); if (ret < 0) {
pr_err("Couldn't load IR protocol module %s\n",
proto_names[i].module_name);
*protocols &= ~proto_names[i].type; continue;
}
msleep(20);
available = ir_raw_get_allowed_protocols(); if (!(*protocols & proto_names[i].type & ~available)) continue;
pr_err("Loaded IR protocol module %s, but protocol %s still not available\n",
proto_names[i].module_name,
proto_names[i].name);
*protocols &= ~proto_names[i].type;
}
}
/** * store_protocols() - changes the current/wakeup IR protocol(s) * @device: the device descriptor * @mattr: the device attribute struct * @buf: a pointer to the input buffer * @len: length of the input buffer * * This routine is for changing the IR protocol type. * It is triggered by writing to /sys/class/rc/rc?/[wakeup_]protocols. * See parse_protocol_change() for the valid commands. * Returns @len on success or a negative error code. * * dev->lock is taken to guard against races between * store_protocols and show_protocols.
*/ static ssize_t store_protocols(struct device *device, struct device_attribute *mattr, constchar *buf, size_t len)
{ struct rc_dev *dev = to_rc_dev(device);
u64 *current_protocols; struct rc_scancode_filter *filter;
u64 old_protocols, new_protocols;
ssize_t rc;
if (dev->driver_type == RC_DRIVER_IR_RAW)
ir_raw_load_modules(&new_protocols);
rc = dev->change_protocol(dev, &new_protocols); if (rc < 0) {
dev_dbg(&dev->dev, "Error setting protocols to 0x%llx\n",
(longlong)new_protocols); goto out;
}
if (new_protocols != old_protocols) {
*current_protocols = new_protocols;
dev_dbg(&dev->dev, "Protocols changed to 0x%llx\n",
(longlong)new_protocols);
}
/* * If a protocol change was attempted the filter may need updating, even * if the actual protocol mask hasn't changed (since the driver may have * cleared the filter). * Try setting the same filter with the new protocol (if any). * Fall back to clearing the filter.
*/ if (dev->s_filter && filter->mask) { if (new_protocols)
rc = dev->s_filter(dev, filter); else
rc = -1;
/** * show_filter() - shows the current scancode filter value or mask * @device: the device descriptor * @attr: the device attribute struct * @buf: a pointer to the output buffer * * This routine is a callback routine to read a scancode filter value or mask. * It is triggered by reading /sys/class/rc/rc?/[wakeup_]filter[_mask]. * It prints the current scancode filter value or mask of the appropriate filter * type in hexadecimal into @buf and returns the size of the buffer. * * Bits of the filter value corresponding to set bits in the filter mask are * compared against input scancodes and non-matching scancodes are discarded. * * dev->lock is taken to guard against races between * store_filter and show_filter.
*/ static ssize_t show_filter(struct device *device, struct device_attribute *attr, char *buf)
{ struct rc_dev *dev = to_rc_dev(device); struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); struct rc_scancode_filter *filter;
u32 val;
if (fattr->mask)
val = filter->mask; else
val = filter->data;
mutex_unlock(&dev->lock);
return sprintf(buf, "%#x\n", val);
}
/** * store_filter() - changes the scancode filter value * @device: the device descriptor * @attr: the device attribute struct * @buf: a pointer to the input buffer * @len: length of the input buffer * * This routine is for changing a scancode filter value or mask. * It is triggered by writing to /sys/class/rc/rc?/[wakeup_]filter[_mask]. * Returns -EINVAL if an invalid filter value for the current protocol was * specified or if scancode filtering is not supported by the driver, otherwise * returns @len. * * Bits of the filter value corresponding to set bits in the filter mask are * compared against input scancodes and non-matching scancodes are discarded. * * dev->lock is taken to guard against races between * store_filter and show_filter.
*/ static ssize_t store_filter(struct device *device, struct device_attribute *attr, constchar *buf, size_t len)
{ struct rc_dev *dev = to_rc_dev(device); struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); struct rc_scancode_filter new_filter, *filter; int ret; unsignedlong val; int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);
ret = kstrtoul(buf, 0, &val); if (ret < 0) return ret;
if (fattr->type == RC_FILTER_WAKEUP) { /* * Refuse to set a filter unless a protocol is enabled * and the filter is valid for that protocol
*/ if (dev->wakeup_protocol != RC_PROTO_UNKNOWN)
ret = rc_validate_filter(dev, &new_filter); else
ret = -EINVAL;
if (ret != 0) goto unlock;
}
if (fattr->type == RC_FILTER_NORMAL && !dev->enabled_protocols &&
val) { /* refuse to set a filter unless a protocol is enabled */
ret = -EINVAL; goto unlock;
}
ret = set_filter(dev, &new_filter); if (ret < 0) goto unlock;
/** * show_wakeup_protocols() - shows the wakeup IR protocol * @device: the device descriptor * @mattr: the device attribute struct * @buf: a pointer to the output buffer * * This routine is a callback routine for input read the IR protocol type(s). * it is triggered by reading /sys/class/rc/rc?/wakeup_protocols. * It returns the protocol names of supported protocols. * The enabled protocols are printed in brackets. * * dev->lock is taken to guard against races between * store_wakeup_protocols and show_wakeup_protocols.
*/ static ssize_t show_wakeup_protocols(struct device *device, struct device_attribute *mattr, char *buf)
{ struct rc_dev *dev = to_rc_dev(device);
u64 allowed; enum rc_proto enabled; char *tmp = buf; int i;
for (i = 0; i < ARRAY_SIZE(protocols); i++) { if (allowed & (1ULL << i)) { if (i == enabled)
tmp += sprintf(tmp, "[%s] ", protocols[i].name); else
tmp += sprintf(tmp, "%s ", protocols[i].name);
}
}
if (tmp != buf)
tmp--;
*tmp = '\n';
return tmp + 1 - buf;
}
/** * store_wakeup_protocols() - changes the wakeup IR protocol(s) * @device: the device descriptor * @mattr: the device attribute struct * @buf: a pointer to the input buffer * @len: length of the input buffer * * This routine is for changing the IR protocol type. * It is triggered by writing to /sys/class/rc/rc?/wakeup_protocols. * Returns @len on success or a negative error code. * * dev->lock is taken to guard against races between * store_wakeup_protocols and show_wakeup_protocols.
*/ static ssize_t store_wakeup_protocols(struct device *device, struct device_attribute *mattr, constchar *buf, size_t len)
{ struct rc_dev *dev = to_rc_dev(device); enum rc_proto protocol = RC_PROTO_UNKNOWN;
ssize_t rc;
u64 allowed; int i;
mutex_lock(&dev->lock); if (!dev->registered) {
mutex_unlock(&dev->lock); return -ENODEV;
}
allowed = dev->allowed_wakeup_protocols;
if (!sysfs_streq(buf, "none")) { for (i = 0; i < ARRAY_SIZE(protocols); i++) { if ((allowed & (1ULL << i)) &&
sysfs_streq(buf, protocols[i].name)) {
protocol = i; break;
}
}
if (i == ARRAY_SIZE(protocols)) {
rc = -EINVAL; goto out;
}
if (dev->encode_wakeup) {
u64 mask = 1ULL << protocol;
staticint rc_dev_uevent(conststruct device *device, struct kobj_uevent_env *env)
{ struct rc_dev *dev = to_rc_dev(device); int ret = 0;
mutex_lock(&dev->lock);
if (!dev->registered)
ret = -ENODEV; if (ret == 0 && dev->rc_map.name)
ret = add_uevent_var(env, "NAME=%s", dev->rc_map.name); if (ret == 0 && dev->driver_name)
ret = add_uevent_var(env, "DRV_NAME=%s", dev->driver_name); if (ret == 0 && dev->device_name)
ret = add_uevent_var(env, "DEV_NAME=%s", dev->device_name);
staticint rc_setup_rx_device(struct rc_dev *dev)
{ int rc;
/* rc_open will be called here */
rc = input_register_device(dev->input_dev); if (rc) return rc;
/* * Default delay of 250ms is too short for some protocols, especially * since the timeout is currently set to 250ms. Increase it to 500ms, * to avoid wrong repetition of the keycodes. Note that this must be * set after the call to input_register_device().
*/ if (dev->allowed_protocols == RC_PROTO_BIT_CEC)
dev->input_dev->rep[REP_DELAY] = 0; else
dev->input_dev->rep[REP_DELAY] = 500;
/* * As a repeat event on protocols like RC-5 and NEC take as long as * 110/114ms, using 33ms as a repeat period is not the right thing * to do.
*/
dev->input_dev->rep[REP_PERIOD] = 125;
return 0;
}
staticvoid rc_free_rx_device(struct rc_dev *dev)
{ if (!dev) return;
if (dev->input_dev) {
input_unregister_device(dev->input_dev);
dev->input_dev = NULL;
}
ir_free_table(&dev->rc_map);
}
int rc_register_device(struct rc_dev *dev)
{ constchar *path; int attr = 0; int minor; int rc;
if (!dev) return -EINVAL;
minor = ida_alloc_max(&rc_ida, RC_DEV_MAX - 1, GFP_KERNEL); if (minor < 0) return minor;
/* * once the input device is registered in rc_setup_rx_device, * userspace can open the input device and rc_open() will be called * as a result. This results in driver code being allowed to submit * keycodes with rc_keydown, so lirc must be registered first.
*/ if (dev->allowed_protocols != RC_PROTO_BIT_CEC) {
rc = lirc_register(dev); if (rc < 0) goto out_dev;
}
if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
rc = rc_setup_rx_device(dev); if (rc) goto out_lirc;
}
if (dev->driver_type == RC_DRIVER_IR_RAW) {
rc = ir_raw_event_register(dev); if (rc < 0) goto out_rx;
}
mutex_lock(&dev->lock); if (dev->users && dev->close)
dev->close(dev);
dev->registered = false;
mutex_unlock(&dev->lock);
rc_free_rx_device(dev);
/* * lirc device should be freed with dev->registered = false, so * that userspace polling will get notified.
*/ if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
lirc_unregister(dev);
device_del(&dev->dev);
ida_free(&rc_ida, dev->minor);
if (!dev->managed_alloc)
rc_free_device(dev);
}
EXPORT_SYMBOL_GPL(rc_unregister_device);
/* * Init/exit code for the module. Basically, creates/removes /sys/class/rc
*/
staticint __init rc_core_init(void)
{ int rc = class_register(&rc_class); if (rc) {
pr_err("rc_core: unable to register rc class\n"); return rc;
}
rc = lirc_dev_init(); if (rc) {
pr_err("rc_core: unable to init lirc\n");
class_unregister(&rc_class); return rc;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.