1 /* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
3 * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/slab.h>
16 #include <linux/input.h>
17 #include <linux/device.h>
18 #include "ir-core-priv.h"
20 #define IRRCV_NUM_DEVICES 256
22 /* bit array to represent IR sysfs device number */
23 static unsigned long ir_core_dev_number
;
25 /* class for /sys/class/rc */
26 static char *ir_devnode(struct device
*dev
, mode_t
*mode
)
28 return kasprintf(GFP_KERNEL
, "rc/%s", dev_name(dev
));
31 static struct class ir_input_class
= {
33 .devnode
= ir_devnode
,
37 * show_protocol() - shows the current IR protocol
38 * @d: the device descriptor
39 * @mattr: the device attribute struct (unused)
40 * @buf: a pointer to the output buffer
42 * This routine is a callback routine for input read the IR protocol type.
43 * it is trigged by reading /sys/class/rc/rc?/current_protocol.
44 * It returns the protocol name, as understood by the driver.
46 static ssize_t
show_protocol(struct device
*d
,
47 struct device_attribute
*mattr
, char *buf
)
50 struct ir_input_dev
*ir_dev
= dev_get_drvdata(d
);
51 u64 ir_type
= ir_dev
->rc_tab
.ir_type
;
53 IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type
);
55 /* FIXME: doesn't support multiple protocols at the same time */
56 if (ir_type
== IR_TYPE_UNKNOWN
)
58 else if (ir_type
== IR_TYPE_RC5
)
60 else if (ir_type
== IR_TYPE_NEC
)
62 else if (ir_type
== IR_TYPE_RC6
)
64 else if (ir_type
== IR_TYPE_JVC
)
66 else if (ir_type
== IR_TYPE_SONY
)
71 return sprintf(buf
, "%s\n", s
);
75 * store_protocol() - shows the current IR protocol
76 * @d: the device descriptor
77 * @mattr: the device attribute struct (unused)
78 * @buf: a pointer to the input buffer
79 * @len: length of the input buffer
81 * This routine is a callback routine for changing the IR protocol type.
82 * it is trigged by reading /sys/class/rc/rc?/current_protocol.
83 * It changes the IR the protocol name, if the IR type is recognized
85 * If an unknown protocol name is used, returns -EINVAL.
87 static ssize_t
store_protocol(struct device
*d
,
88 struct device_attribute
*mattr
,
92 struct ir_input_dev
*ir_dev
= dev_get_drvdata(d
);
98 while ((buf
= strsep((char **) &data
, " \n")) != NULL
) {
99 if (!strcasecmp(buf
, "rc-5") || !strcasecmp(buf
, "rc5"))
100 ir_type
|= IR_TYPE_RC5
;
101 if (!strcasecmp(buf
, "nec"))
102 ir_type
|= IR_TYPE_NEC
;
103 if (!strcasecmp(buf
, "jvc"))
104 ir_type
|= IR_TYPE_JVC
;
105 if (!strcasecmp(buf
, "sony"))
106 ir_type
|= IR_TYPE_SONY
;
110 IR_dprintk(1, "Unknown protocol\n");
114 if (ir_dev
->props
&& ir_dev
->props
->change_protocol
)
115 rc
= ir_dev
->props
->change_protocol(ir_dev
->props
->priv
,
119 IR_dprintk(1, "Error setting protocol to %lld\n",
124 spin_lock_irqsave(&ir_dev
->rc_tab
.lock
, flags
);
125 ir_dev
->rc_tab
.ir_type
= ir_type
;
126 spin_unlock_irqrestore(&ir_dev
->rc_tab
.lock
, flags
);
128 IR_dprintk(1, "Current protocol(s) is(are) %lld\n",
134 static ssize_t
show_supported_protocols(struct device
*d
,
135 struct device_attribute
*mattr
, char *buf
)
138 struct ir_input_dev
*ir_dev
= dev_get_drvdata(d
);
140 /* FIXME: doesn't support multiple protocols at the same time */
141 if (ir_dev
->props
->allowed_protos
== IR_TYPE_UNKNOWN
)
142 buf
+= sprintf(buf
, "unknown ");
143 if (ir_dev
->props
->allowed_protos
& IR_TYPE_RC5
)
144 buf
+= sprintf(buf
, "rc-5 ");
145 if (ir_dev
->props
->allowed_protos
& IR_TYPE_NEC
)
146 buf
+= sprintf(buf
, "nec ");
148 buf
+= sprintf(buf
, "other ");
150 buf
+= sprintf(buf
- 1, "\n");
155 #define ADD_HOTPLUG_VAR(fmt, val...) \
157 int err = add_uevent_var(env, fmt, val); \
162 static int ir_dev_uevent(struct device
*device
, struct kobj_uevent_env
*env
)
164 struct ir_input_dev
*ir_dev
= dev_get_drvdata(device
);
166 if (ir_dev
->rc_tab
.name
)
167 ADD_HOTPLUG_VAR("NAME=%s", ir_dev
->rc_tab
.name
);
168 if (ir_dev
->driver_name
)
169 ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev
->driver_name
);
175 * Static device attribute struct with the sysfs attributes for IR's
177 static DEVICE_ATTR(protocol
, S_IRUGO
| S_IWUSR
,
178 show_protocol
, store_protocol
);
180 static DEVICE_ATTR(supported_protocols
, S_IRUGO
| S_IWUSR
,
181 show_supported_protocols
, NULL
);
183 static struct attribute
*ir_hw_dev_attrs
[] = {
184 &dev_attr_protocol
.attr
,
185 &dev_attr_supported_protocols
.attr
,
189 static struct attribute_group ir_hw_dev_attr_grp
= {
190 .attrs
= ir_hw_dev_attrs
,
193 static const struct attribute_group
*ir_hw_dev_attr_groups
[] = {
198 static struct device_type rc_dev_type
= {
199 .groups
= ir_hw_dev_attr_groups
,
200 .uevent
= ir_dev_uevent
,
203 static struct device_type ir_raw_dev_type
= {
204 .uevent
= ir_dev_uevent
,
208 * ir_register_class() - creates the sysfs for /sys/class/rc/rc?
209 * @input_dev: the struct input_dev descriptor of the device
211 * This routine is used to register the syfs code for IR class
213 int ir_register_class(struct input_dev
*input_dev
)
217 struct ir_input_dev
*ir_dev
= input_get_drvdata(input_dev
);
218 int devno
= find_first_zero_bit(&ir_core_dev_number
,
221 if (unlikely(devno
< 0))
225 if (ir_dev
->props
->driver_type
== RC_DRIVER_SCANCODE
)
226 ir_dev
->dev
.type
= &rc_dev_type
;
228 ir_dev
->dev
.type
= &ir_raw_dev_type
;
230 ir_dev
->dev
.class = &ir_input_class
;
231 ir_dev
->dev
.parent
= input_dev
->dev
.parent
;
232 dev_set_name(&ir_dev
->dev
, "rc%d", devno
);
233 dev_set_drvdata(&ir_dev
->dev
, ir_dev
);
234 rc
= device_register(&ir_dev
->dev
);
239 input_dev
->dev
.parent
= &ir_dev
->dev
;
240 rc
= input_register_device(input_dev
);
242 device_del(&ir_dev
->dev
);
246 __module_get(THIS_MODULE
);
248 path
= kobject_get_path(&ir_dev
->dev
.kobj
, GFP_KERNEL
);
249 printk(KERN_INFO
"%s: %s as %s\n",
250 dev_name(&ir_dev
->dev
),
251 input_dev
->name
? input_dev
->name
: "Unspecified device",
252 path
? path
: "N/A");
255 ir_dev
->devno
= devno
;
256 set_bit(devno
, &ir_core_dev_number
);
262 * ir_unregister_class() - removes the sysfs for sysfs for
264 * @input_dev: the struct input_dev descriptor of the device
266 * This routine is used to unregister the syfs code for IR class
268 void ir_unregister_class(struct input_dev
*input_dev
)
270 struct ir_input_dev
*ir_dev
= input_get_drvdata(input_dev
);
272 clear_bit(ir_dev
->devno
, &ir_core_dev_number
);
273 input_unregister_device(input_dev
);
274 device_del(&ir_dev
->dev
);
276 module_put(THIS_MODULE
);
280 * Init/exit code for the module. Basically, creates/removes /sys/class/rc
283 static int __init
ir_core_init(void)
285 int rc
= class_register(&ir_input_class
);
287 printk(KERN_ERR
"ir_core: unable to register rc class\n");
291 /* Initialize/load the decoders/keymap code that will be used */
297 static void __exit
ir_core_exit(void)
299 class_unregister(&ir_input_class
);
302 module_init(ir_core_init
);
303 module_exit(ir_core_exit
);