aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-03-25 22:49:46 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:53:01 -0400
commit20d5f116ec777c9c7ce5b74f0d17ee1d01a0d833 (patch)
treeb25e179adb667c18e14dbd7088c3a850150f0c68 /drivers
parent93c312ff21b0a53e701a45741887208297646a1a (diff)
V4L/DVB: ir-nec-decoder: Add sysfs node to enable/disable per irrcv
With the help of raw_register/raw_unregister, adds a sysfs group associated with the decoder, inside the corresponding irrcv node. Writing 1 to nec_decoder/enabled enables the decoder, while writing 0 disables it. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/IR/ir-nec-decoder.c133
-rw-r--r--drivers/media/IR/ir-raw-event.c2
2 files changed, 133 insertions, 2 deletions
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index cb57cc287734..83a9912722f4 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -39,6 +39,85 @@
39 39
40#define REPEAT_TIME 240 /* ms */ 40#define REPEAT_TIME 240 /* ms */
41 41
42/* Used to register nec_decoder clients */
43static LIST_HEAD(decoder_list);
44static spinlock_t decoder_lock;
45
46struct decoder_data {
47 struct list_head list;
48 struct ir_input_dev *ir_dev;
49 int enabled:1;
50};
51
52
53/**
54 * get_decoder_data() - gets decoder data
55 * @input_dev: input device
56 *
57 * Returns the struct decoder_data that corresponds to a device
58 */
59
60static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
61{
62 struct decoder_data *data = NULL;
63
64 spin_lock(&decoder_lock);
65 list_for_each_entry(data, &decoder_list, list) {
66 if (data->ir_dev == ir_dev)
67 break;
68 }
69 spin_unlock(&decoder_lock);
70 return data;
71}
72
73static ssize_t store_enabled(struct device *d,
74 struct device_attribute *mattr,
75 const char *buf,
76 size_t len)
77{
78 unsigned long value;
79 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
80 struct decoder_data *data = get_decoder_data(ir_dev);
81
82 if (!data)
83 return -EINVAL;
84
85 if (strict_strtoul(buf, 10, &value) || value > 1)
86 return -EINVAL;
87
88 data->enabled = value;
89
90 return len;
91}
92
93static ssize_t show_enabled(struct device *d,
94 struct device_attribute *mattr, char *buf)
95{
96 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
97 struct decoder_data *data = get_decoder_data(ir_dev);
98
99 if (!data)
100 return -EINVAL;
101
102 if (data->enabled)
103 return sprintf(buf, "1\n");
104 else
105 return sprintf(buf, "0\n");
106}
107
108static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
109
110static struct attribute *decoder_attributes[] = {
111 &dev_attr_enabled.attr,
112 NULL
113};
114
115static struct attribute_group decoder_attribute_group = {
116 .name = "nec_decoder",
117 .attrs = decoder_attributes,
118};
119
120
42/** is_repeat - Check if it is a NEC repeat event 121/** is_repeat - Check if it is a NEC repeat event
43 * @input_dev: the struct input_dev descriptor of the device 122 * @input_dev: the struct input_dev descriptor of the device
44 * @pos: the position of the first event 123 * @pos: the position of the first event
@@ -184,9 +263,15 @@ static int ir_nec_decode(struct input_dev *input_dev,
184 struct ir_raw_event *evs, 263 struct ir_raw_event *evs,
185 int len) 264 int len)
186{ 265{
266 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
267 struct decoder_data *data;
187 int pos = 0; 268 int pos = 0;
188 int rc = 0; 269 int rc = 0;
189 270
271 data = get_decoder_data(ir_dev);
272 if (!data || !data->enabled)
273 return 0;
274
190 while (pos < len) { 275 while (pos < len) {
191 if (__ir_nec_decode(input_dev, evs, len, &pos) > 0) 276 if (__ir_nec_decode(input_dev, evs, len, &pos) > 0)
192 rc++; 277 rc++;
@@ -194,8 +279,54 @@ static int ir_nec_decode(struct input_dev *input_dev,
194 return rc; 279 return rc;
195} 280}
196 281
282static int ir_nec_register(struct input_dev *input_dev)
283{
284 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
285 struct decoder_data *data;
286 int rc;
287
288 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
289 if (rc < 0)
290 return rc;
291
292 data = kzalloc(sizeof(*data), GFP_KERNEL);
293 if (!data) {
294 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
295 return -ENOMEM;
296 }
297
298 data->ir_dev = ir_dev;
299 data->enabled = 1;
300
301 spin_lock(&decoder_lock);
302 list_add_tail(&data->list, &decoder_list);
303 spin_unlock(&decoder_lock);
304
305 return 0;
306}
307
308static int ir_nec_unregister(struct input_dev *input_dev)
309{
310 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
311 static struct decoder_data *data;
312
313 data = get_decoder_data(ir_dev);
314 if (!data)
315 return 0;
316
317 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
318
319 spin_lock(&decoder_lock);
320 list_del(&data->list);
321 spin_unlock(&decoder_lock);
322
323 return 0;
324}
325
197static struct ir_raw_handler nec_handler = { 326static struct ir_raw_handler nec_handler = {
198 .decode = ir_nec_decode, 327 .decode = ir_nec_decode,
328 .raw_register = ir_nec_register,
329 .raw_unregister = ir_nec_unregister,
199}; 330};
200 331
201static int __init ir_nec_decode_init(void) 332static int __init ir_nec_decode_init(void)
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 11f23f4491b2..371d88e5a586 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -223,7 +223,7 @@ static void init_decoders(struct work_struct *work)
223void ir_raw_init(void) 223void ir_raw_init(void)
224{ 224{
225 spin_lock_init(&ir_raw_handler_lock); 225 spin_lock_init(&ir_raw_handler_lock);
226 226
227#ifdef MODULE 227#ifdef MODULE
228 INIT_WORK(&wq_load, init_decoders); 228 INIT_WORK(&wq_load, init_decoders);
229 schedule_work(&wq_load); 229 schedule_work(&wq_load);