diff options
-rw-r--r-- | drivers/media/IR/ir-core-priv.h | 3 | ||||
-rw-r--r-- | drivers/media/IR/ir-jvc-decoder.c | 65 | ||||
-rw-r--r-- | drivers/media/IR/ir-nec-decoder.c | 65 | ||||
-rw-r--r-- | drivers/media/IR/ir-raw-event.c | 112 | ||||
-rw-r--r-- | drivers/media/IR/ir-rc5-decoder.c | 67 | ||||
-rw-r--r-- | drivers/media/IR/ir-rc6-decoder.c | 65 | ||||
-rw-r--r-- | drivers/media/IR/ir-sony-decoder.c | 65 | ||||
-rw-r--r-- | drivers/media/IR/ir-sysfs.c | 252 |
8 files changed, 232 insertions, 462 deletions
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index 9a5e65a471a5..5111dc23909a 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h | |||
@@ -22,6 +22,7 @@ | |||
22 | struct ir_raw_handler { | 22 | struct ir_raw_handler { |
23 | struct list_head list; | 23 | struct list_head list; |
24 | 24 | ||
25 | u64 protocols; /* which are handled by this handler */ | ||
25 | int (*decode)(struct input_dev *input_dev, struct ir_raw_event event); | 26 | int (*decode)(struct input_dev *input_dev, struct ir_raw_event event); |
26 | int (*raw_register)(struct input_dev *input_dev); | 27 | int (*raw_register)(struct input_dev *input_dev); |
27 | int (*raw_unregister)(struct input_dev *input_dev); | 28 | int (*raw_unregister)(struct input_dev *input_dev); |
@@ -33,6 +34,7 @@ struct ir_raw_event_ctrl { | |||
33 | ktime_t last_event; /* when last event occurred */ | 34 | ktime_t last_event; /* when last event occurred */ |
34 | enum raw_event_type last_type; /* last event type */ | 35 | enum raw_event_type last_type; /* last event type */ |
35 | struct input_dev *input_dev; /* pointer to the parent input_dev */ | 36 | struct input_dev *input_dev; /* pointer to the parent input_dev */ |
37 | u64 enabled_protocols; /* enabled raw protocol decoders */ | ||
36 | }; | 38 | }; |
37 | 39 | ||
38 | /* macros for IR decoders */ | 40 | /* macros for IR decoders */ |
@@ -74,6 +76,7 @@ void ir_unregister_class(struct input_dev *input_dev); | |||
74 | /* | 76 | /* |
75 | * Routines from ir-raw-event.c to be used internally and by decoders | 77 | * Routines from ir-raw-event.c to be used internally and by decoders |
76 | */ | 78 | */ |
79 | u64 ir_raw_get_allowed_protocols(void); | ||
77 | int ir_raw_event_register(struct input_dev *input_dev); | 80 | int ir_raw_event_register(struct input_dev *input_dev); |
78 | void ir_raw_event_unregister(struct input_dev *input_dev); | 81 | void ir_raw_event_unregister(struct input_dev *input_dev); |
79 | int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); | 82 | int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); |
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c index b02e8013b9bb..b1f935884d30 100644 --- a/drivers/media/IR/ir-jvc-decoder.c +++ b/drivers/media/IR/ir-jvc-decoder.c | |||
@@ -41,7 +41,6 @@ enum jvc_state { | |||
41 | struct decoder_data { | 41 | struct decoder_data { |
42 | struct list_head list; | 42 | struct list_head list; |
43 | struct ir_input_dev *ir_dev; | 43 | struct ir_input_dev *ir_dev; |
44 | int enabled:1; | ||
45 | 44 | ||
46 | /* State machine control */ | 45 | /* State machine control */ |
47 | enum jvc_state state; | 46 | enum jvc_state state; |
@@ -72,53 +71,6 @@ static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | |||
72 | return data; | 71 | return data; |
73 | } | 72 | } |
74 | 73 | ||
75 | static ssize_t store_enabled(struct device *d, | ||
76 | struct device_attribute *mattr, | ||
77 | const char *buf, | ||
78 | size_t len) | ||
79 | { | ||
80 | unsigned long value; | ||
81 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
82 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
83 | |||
84 | if (!data) | ||
85 | return -EINVAL; | ||
86 | |||
87 | if (strict_strtoul(buf, 10, &value) || value > 1) | ||
88 | return -EINVAL; | ||
89 | |||
90 | data->enabled = value; | ||
91 | |||
92 | return len; | ||
93 | } | ||
94 | |||
95 | static ssize_t show_enabled(struct device *d, | ||
96 | struct device_attribute *mattr, char *buf) | ||
97 | { | ||
98 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
99 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
100 | |||
101 | if (!data) | ||
102 | return -EINVAL; | ||
103 | |||
104 | if (data->enabled) | ||
105 | return sprintf(buf, "1\n"); | ||
106 | else | ||
107 | return sprintf(buf, "0\n"); | ||
108 | } | ||
109 | |||
110 | static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled); | ||
111 | |||
112 | static struct attribute *decoder_attributes[] = { | ||
113 | &dev_attr_enabled.attr, | ||
114 | NULL | ||
115 | }; | ||
116 | |||
117 | static struct attribute_group decoder_attribute_group = { | ||
118 | .name = "jvc_decoder", | ||
119 | .attrs = decoder_attributes, | ||
120 | }; | ||
121 | |||
122 | /** | 74 | /** |
123 | * ir_jvc_decode() - Decode one JVC pulse or space | 75 | * ir_jvc_decode() - Decode one JVC pulse or space |
124 | * @input_dev: the struct input_dev descriptor of the device | 76 | * @input_dev: the struct input_dev descriptor of the device |
@@ -135,7 +87,7 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
135 | if (!data) | 87 | if (!data) |
136 | return -EINVAL; | 88 | return -EINVAL; |
137 | 89 | ||
138 | if (!data->enabled) | 90 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) |
139 | return 0; | 91 | return 0; |
140 | 92 | ||
141 | if (IS_RESET(ev)) { | 93 | if (IS_RESET(ev)) { |
@@ -253,22 +205,12 @@ static int ir_jvc_register(struct input_dev *input_dev) | |||
253 | { | 205 | { |
254 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 206 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
255 | struct decoder_data *data; | 207 | struct decoder_data *data; |
256 | u64 ir_type = ir_dev->rc_tab.ir_type; | ||
257 | int rc; | ||
258 | |||
259 | rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
260 | if (rc < 0) | ||
261 | return rc; | ||
262 | 208 | ||
263 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 209 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
264 | if (!data) { | 210 | if (!data) |
265 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
266 | return -ENOMEM; | 211 | return -ENOMEM; |
267 | } | ||
268 | 212 | ||
269 | data->ir_dev = ir_dev; | 213 | data->ir_dev = ir_dev; |
270 | if (ir_type == IR_TYPE_JVC || ir_type == IR_TYPE_UNKNOWN) | ||
271 | data->enabled = 1; | ||
272 | 214 | ||
273 | spin_lock(&decoder_lock); | 215 | spin_lock(&decoder_lock); |
274 | list_add_tail(&data->list, &decoder_list); | 216 | list_add_tail(&data->list, &decoder_list); |
@@ -286,8 +228,6 @@ static int ir_jvc_unregister(struct input_dev *input_dev) | |||
286 | if (!data) | 228 | if (!data) |
287 | return 0; | 229 | return 0; |
288 | 230 | ||
289 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
290 | |||
291 | spin_lock(&decoder_lock); | 231 | spin_lock(&decoder_lock); |
292 | list_del(&data->list); | 232 | list_del(&data->list); |
293 | spin_unlock(&decoder_lock); | 233 | spin_unlock(&decoder_lock); |
@@ -296,6 +236,7 @@ static int ir_jvc_unregister(struct input_dev *input_dev) | |||
296 | } | 236 | } |
297 | 237 | ||
298 | static struct ir_raw_handler jvc_handler = { | 238 | static struct ir_raw_handler jvc_handler = { |
239 | .protocols = IR_TYPE_JVC, | ||
299 | .decode = ir_jvc_decode, | 240 | .decode = ir_jvc_decode, |
300 | .raw_register = ir_jvc_register, | 241 | .raw_register = ir_jvc_register, |
301 | .raw_unregister = ir_jvc_unregister, | 242 | .raw_unregister = ir_jvc_unregister, |
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 6059a1f1e151..db62c652dfc5 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c | |||
@@ -43,7 +43,6 @@ enum nec_state { | |||
43 | struct decoder_data { | 43 | struct decoder_data { |
44 | struct list_head list; | 44 | struct list_head list; |
45 | struct ir_input_dev *ir_dev; | 45 | struct ir_input_dev *ir_dev; |
46 | int enabled:1; | ||
47 | 46 | ||
48 | /* State machine control */ | 47 | /* State machine control */ |
49 | enum nec_state state; | 48 | enum nec_state state; |
@@ -71,53 +70,6 @@ static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | |||
71 | return data; | 70 | return data; |
72 | } | 71 | } |
73 | 72 | ||
74 | static ssize_t store_enabled(struct device *d, | ||
75 | struct device_attribute *mattr, | ||
76 | const char *buf, | ||
77 | size_t len) | ||
78 | { | ||
79 | unsigned long value; | ||
80 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
81 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
82 | |||
83 | if (!data) | ||
84 | return -EINVAL; | ||
85 | |||
86 | if (strict_strtoul(buf, 10, &value) || value > 1) | ||
87 | return -EINVAL; | ||
88 | |||
89 | data->enabled = value; | ||
90 | |||
91 | return len; | ||
92 | } | ||
93 | |||
94 | static ssize_t show_enabled(struct device *d, | ||
95 | struct device_attribute *mattr, char *buf) | ||
96 | { | ||
97 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
98 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
99 | |||
100 | if (!data) | ||
101 | return -EINVAL; | ||
102 | |||
103 | if (data->enabled) | ||
104 | return sprintf(buf, "1\n"); | ||
105 | else | ||
106 | return sprintf(buf, "0\n"); | ||
107 | } | ||
108 | |||
109 | static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled); | ||
110 | |||
111 | static struct attribute *decoder_attributes[] = { | ||
112 | &dev_attr_enabled.attr, | ||
113 | NULL | ||
114 | }; | ||
115 | |||
116 | static struct attribute_group decoder_attribute_group = { | ||
117 | .name = "nec_decoder", | ||
118 | .attrs = decoder_attributes, | ||
119 | }; | ||
120 | |||
121 | /** | 73 | /** |
122 | * ir_nec_decode() - Decode one NEC pulse or space | 74 | * ir_nec_decode() - Decode one NEC pulse or space |
123 | * @input_dev: the struct input_dev descriptor of the device | 75 | * @input_dev: the struct input_dev descriptor of the device |
@@ -136,7 +88,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
136 | if (!data) | 88 | if (!data) |
137 | return -EINVAL; | 89 | return -EINVAL; |
138 | 90 | ||
139 | if (!data->enabled) | 91 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) |
140 | return 0; | 92 | return 0; |
141 | 93 | ||
142 | if (IS_RESET(ev)) { | 94 | if (IS_RESET(ev)) { |
@@ -260,22 +212,12 @@ static int ir_nec_register(struct input_dev *input_dev) | |||
260 | { | 212 | { |
261 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 213 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
262 | struct decoder_data *data; | 214 | struct decoder_data *data; |
263 | u64 ir_type = ir_dev->rc_tab.ir_type; | ||
264 | int rc; | ||
265 | |||
266 | rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
267 | if (rc < 0) | ||
268 | return rc; | ||
269 | 215 | ||
270 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 216 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
271 | if (!data) { | 217 | if (!data) |
272 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
273 | return -ENOMEM; | 218 | return -ENOMEM; |
274 | } | ||
275 | 219 | ||
276 | data->ir_dev = ir_dev; | 220 | data->ir_dev = ir_dev; |
277 | if (ir_type == IR_TYPE_NEC || ir_type == IR_TYPE_UNKNOWN) | ||
278 | data->enabled = 1; | ||
279 | 221 | ||
280 | spin_lock(&decoder_lock); | 222 | spin_lock(&decoder_lock); |
281 | list_add_tail(&data->list, &decoder_list); | 223 | list_add_tail(&data->list, &decoder_list); |
@@ -293,8 +235,6 @@ static int ir_nec_unregister(struct input_dev *input_dev) | |||
293 | if (!data) | 235 | if (!data) |
294 | return 0; | 236 | return 0; |
295 | 237 | ||
296 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
297 | |||
298 | spin_lock(&decoder_lock); | 238 | spin_lock(&decoder_lock); |
299 | list_del(&data->list); | 239 | list_del(&data->list); |
300 | spin_unlock(&decoder_lock); | 240 | spin_unlock(&decoder_lock); |
@@ -303,6 +243,7 @@ static int ir_nec_unregister(struct input_dev *input_dev) | |||
303 | } | 243 | } |
304 | 244 | ||
305 | static struct ir_raw_handler nec_handler = { | 245 | static struct ir_raw_handler nec_handler = { |
246 | .protocols = IR_TYPE_NEC, | ||
306 | .decode = ir_nec_decode, | 247 | .decode = ir_nec_decode, |
307 | .raw_register = ir_nec_register, | 248 | .raw_register = ir_nec_register, |
308 | .raw_unregister = ir_nec_unregister, | 249 | .raw_unregister = ir_nec_unregister, |
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index d3bd3f98e008..fb3336c37191 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -21,8 +21,9 @@ | |||
21 | #define MAX_IR_EVENT_SIZE 512 | 21 | #define MAX_IR_EVENT_SIZE 512 |
22 | 22 | ||
23 | /* Used to handle IR raw handler extensions */ | 23 | /* Used to handle IR raw handler extensions */ |
24 | static LIST_HEAD(ir_raw_handler_list); | ||
25 | static DEFINE_SPINLOCK(ir_raw_handler_lock); | 24 | static DEFINE_SPINLOCK(ir_raw_handler_lock); |
25 | static LIST_HEAD(ir_raw_handler_list); | ||
26 | static u64 available_protocols; | ||
26 | 27 | ||
27 | /** | 28 | /** |
28 | * RUN_DECODER() - runs an operation on all IR decoders | 29 | * RUN_DECODER() - runs an operation on all IR decoders |
@@ -64,52 +65,6 @@ static void ir_raw_event_work(struct work_struct *work) | |||
64 | RUN_DECODER(decode, raw->input_dev, ev); | 65 | RUN_DECODER(decode, raw->input_dev, ev); |
65 | } | 66 | } |
66 | 67 | ||
67 | int ir_raw_event_register(struct input_dev *input_dev) | ||
68 | { | ||
69 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
70 | int rc; | ||
71 | |||
72 | ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); | ||
73 | if (!ir->raw) | ||
74 | return -ENOMEM; | ||
75 | |||
76 | ir->raw->input_dev = input_dev; | ||
77 | INIT_WORK(&ir->raw->rx_work, ir_raw_event_work); | ||
78 | |||
79 | rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, | ||
80 | GFP_KERNEL); | ||
81 | if (rc < 0) { | ||
82 | kfree(ir->raw); | ||
83 | ir->raw = NULL; | ||
84 | return rc; | ||
85 | } | ||
86 | |||
87 | rc = RUN_DECODER(raw_register, input_dev); | ||
88 | if (rc < 0) { | ||
89 | kfifo_free(&ir->raw->kfifo); | ||
90 | kfree(ir->raw); | ||
91 | ir->raw = NULL; | ||
92 | return rc; | ||
93 | } | ||
94 | |||
95 | return rc; | ||
96 | } | ||
97 | |||
98 | void ir_raw_event_unregister(struct input_dev *input_dev) | ||
99 | { | ||
100 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
101 | |||
102 | if (!ir->raw) | ||
103 | return; | ||
104 | |||
105 | cancel_work_sync(&ir->raw->rx_work); | ||
106 | RUN_DECODER(raw_unregister, input_dev); | ||
107 | |||
108 | kfifo_free(&ir->raw->kfifo); | ||
109 | kfree(ir->raw); | ||
110 | ir->raw = NULL; | ||
111 | } | ||
112 | |||
113 | /** | 68 | /** |
114 | * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders | 69 | * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders |
115 | * @input_dev: the struct input_dev device descriptor | 70 | * @input_dev: the struct input_dev device descriptor |
@@ -203,6 +158,66 @@ void ir_raw_event_handle(struct input_dev *input_dev) | |||
203 | } | 158 | } |
204 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); | 159 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); |
205 | 160 | ||
161 | /* used internally by the sysfs interface */ | ||
162 | u64 | ||
163 | ir_raw_get_allowed_protocols() | ||
164 | { | ||
165 | u64 protocols; | ||
166 | spin_lock(&ir_raw_handler_lock); | ||
167 | protocols = available_protocols; | ||
168 | spin_unlock(&ir_raw_handler_lock); | ||
169 | return protocols; | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * Used to (un)register raw event clients | ||
174 | */ | ||
175 | int ir_raw_event_register(struct input_dev *input_dev) | ||
176 | { | ||
177 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
178 | int rc; | ||
179 | |||
180 | ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); | ||
181 | if (!ir->raw) | ||
182 | return -ENOMEM; | ||
183 | |||
184 | ir->raw->input_dev = input_dev; | ||
185 | INIT_WORK(&ir->raw->rx_work, ir_raw_event_work); | ||
186 | ir->raw->enabled_protocols = ~0; | ||
187 | rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, | ||
188 | GFP_KERNEL); | ||
189 | if (rc < 0) { | ||
190 | kfree(ir->raw); | ||
191 | ir->raw = NULL; | ||
192 | return rc; | ||
193 | } | ||
194 | |||
195 | rc = RUN_DECODER(raw_register, input_dev); | ||
196 | if (rc < 0) { | ||
197 | kfifo_free(&ir->raw->kfifo); | ||
198 | kfree(ir->raw); | ||
199 | ir->raw = NULL; | ||
200 | return rc; | ||
201 | } | ||
202 | |||
203 | return rc; | ||
204 | } | ||
205 | |||
206 | void ir_raw_event_unregister(struct input_dev *input_dev) | ||
207 | { | ||
208 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
209 | |||
210 | if (!ir->raw) | ||
211 | return; | ||
212 | |||
213 | cancel_work_sync(&ir->raw->rx_work); | ||
214 | RUN_DECODER(raw_unregister, input_dev); | ||
215 | |||
216 | kfifo_free(&ir->raw->kfifo); | ||
217 | kfree(ir->raw); | ||
218 | ir->raw = NULL; | ||
219 | } | ||
220 | |||
206 | /* | 221 | /* |
207 | * Extension interface - used to register the IR decoders | 222 | * Extension interface - used to register the IR decoders |
208 | */ | 223 | */ |
@@ -211,7 +226,9 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) | |||
211 | { | 226 | { |
212 | spin_lock(&ir_raw_handler_lock); | 227 | spin_lock(&ir_raw_handler_lock); |
213 | list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); | 228 | list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); |
229 | available_protocols |= ir_raw_handler->protocols; | ||
214 | spin_unlock(&ir_raw_handler_lock); | 230 | spin_unlock(&ir_raw_handler_lock); |
231 | |||
215 | return 0; | 232 | return 0; |
216 | } | 233 | } |
217 | EXPORT_SYMBOL(ir_raw_handler_register); | 234 | EXPORT_SYMBOL(ir_raw_handler_register); |
@@ -220,6 +237,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) | |||
220 | { | 237 | { |
221 | spin_lock(&ir_raw_handler_lock); | 238 | spin_lock(&ir_raw_handler_lock); |
222 | list_del(&ir_raw_handler->list); | 239 | list_del(&ir_raw_handler->list); |
240 | available_protocols &= ~ir_raw_handler->protocols; | ||
223 | spin_unlock(&ir_raw_handler_lock); | 241 | spin_unlock(&ir_raw_handler_lock); |
224 | } | 242 | } |
225 | EXPORT_SYMBOL(ir_raw_handler_unregister); | 243 | EXPORT_SYMBOL(ir_raw_handler_unregister); |
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c index 4aa797bc69fd..bdfa404a6537 100644 --- a/drivers/media/IR/ir-rc5-decoder.c +++ b/drivers/media/IR/ir-rc5-decoder.c | |||
@@ -45,7 +45,6 @@ enum rc5_state { | |||
45 | struct decoder_data { | 45 | struct decoder_data { |
46 | struct list_head list; | 46 | struct list_head list; |
47 | struct ir_input_dev *ir_dev; | 47 | struct ir_input_dev *ir_dev; |
48 | int enabled:1; | ||
49 | 48 | ||
50 | /* State machine control */ | 49 | /* State machine control */ |
51 | enum rc5_state state; | 50 | enum rc5_state state; |
@@ -76,53 +75,6 @@ static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | |||
76 | return data; | 75 | return data; |
77 | } | 76 | } |
78 | 77 | ||
79 | static ssize_t store_enabled(struct device *d, | ||
80 | struct device_attribute *mattr, | ||
81 | const char *buf, | ||
82 | size_t len) | ||
83 | { | ||
84 | unsigned long value; | ||
85 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
86 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
87 | |||
88 | if (!data) | ||
89 | return -EINVAL; | ||
90 | |||
91 | if (strict_strtoul(buf, 10, &value) || value > 1) | ||
92 | return -EINVAL; | ||
93 | |||
94 | data->enabled = value; | ||
95 | |||
96 | return len; | ||
97 | } | ||
98 | |||
99 | static ssize_t show_enabled(struct device *d, | ||
100 | struct device_attribute *mattr, char *buf) | ||
101 | { | ||
102 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
103 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
104 | |||
105 | if (!data) | ||
106 | return -EINVAL; | ||
107 | |||
108 | if (data->enabled) | ||
109 | return sprintf(buf, "1\n"); | ||
110 | else | ||
111 | return sprintf(buf, "0\n"); | ||
112 | } | ||
113 | |||
114 | static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled); | ||
115 | |||
116 | static struct attribute *decoder_attributes[] = { | ||
117 | &dev_attr_enabled.attr, | ||
118 | NULL | ||
119 | }; | ||
120 | |||
121 | static struct attribute_group decoder_attribute_group = { | ||
122 | .name = "rc5_decoder", | ||
123 | .attrs = decoder_attributes, | ||
124 | }; | ||
125 | |||
126 | /** | 78 | /** |
127 | * ir_rc5_decode() - Decode one RC-5 pulse or space | 79 | * ir_rc5_decode() - Decode one RC-5 pulse or space |
128 | * @input_dev: the struct input_dev descriptor of the device | 80 | * @input_dev: the struct input_dev descriptor of the device |
@@ -141,8 +93,8 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
141 | if (!data) | 93 | if (!data) |
142 | return -EINVAL; | 94 | return -EINVAL; |
143 | 95 | ||
144 | if (!data->enabled) | 96 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) |
145 | return 0; | 97 | return 0; |
146 | 98 | ||
147 | if (IS_RESET(ev)) { | 99 | if (IS_RESET(ev)) { |
148 | data->state = STATE_INACTIVE; | 100 | data->state = STATE_INACTIVE; |
@@ -256,22 +208,12 @@ static int ir_rc5_register(struct input_dev *input_dev) | |||
256 | { | 208 | { |
257 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 209 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
258 | struct decoder_data *data; | 210 | struct decoder_data *data; |
259 | u64 ir_type = ir_dev->rc_tab.ir_type; | ||
260 | int rc; | ||
261 | |||
262 | rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
263 | if (rc < 0) | ||
264 | return rc; | ||
265 | 211 | ||
266 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 212 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
267 | if (!data) { | 213 | if (!data) |
268 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
269 | return -ENOMEM; | 214 | return -ENOMEM; |
270 | } | ||
271 | 215 | ||
272 | data->ir_dev = ir_dev; | 216 | data->ir_dev = ir_dev; |
273 | if (ir_type == IR_TYPE_RC5 || ir_type == IR_TYPE_UNKNOWN) | ||
274 | data->enabled = 1; | ||
275 | 217 | ||
276 | spin_lock(&decoder_lock); | 218 | spin_lock(&decoder_lock); |
277 | list_add_tail(&data->list, &decoder_list); | 219 | list_add_tail(&data->list, &decoder_list); |
@@ -289,8 +231,6 @@ static int ir_rc5_unregister(struct input_dev *input_dev) | |||
289 | if (!data) | 231 | if (!data) |
290 | return 0; | 232 | return 0; |
291 | 233 | ||
292 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
293 | |||
294 | spin_lock(&decoder_lock); | 234 | spin_lock(&decoder_lock); |
295 | list_del(&data->list); | 235 | list_del(&data->list); |
296 | spin_unlock(&decoder_lock); | 236 | spin_unlock(&decoder_lock); |
@@ -299,6 +239,7 @@ static int ir_rc5_unregister(struct input_dev *input_dev) | |||
299 | } | 239 | } |
300 | 240 | ||
301 | static struct ir_raw_handler rc5_handler = { | 241 | static struct ir_raw_handler rc5_handler = { |
242 | .protocols = IR_TYPE_RC5, | ||
302 | .decode = ir_rc5_decode, | 243 | .decode = ir_rc5_decode, |
303 | .raw_register = ir_rc5_register, | 244 | .raw_register = ir_rc5_register, |
304 | .raw_unregister = ir_rc5_unregister, | 245 | .raw_unregister = ir_rc5_unregister, |
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c index 9f61da29face..2ebd4ea69538 100644 --- a/drivers/media/IR/ir-rc6-decoder.c +++ b/drivers/media/IR/ir-rc6-decoder.c | |||
@@ -61,7 +61,6 @@ enum rc6_state { | |||
61 | struct decoder_data { | 61 | struct decoder_data { |
62 | struct list_head list; | 62 | struct list_head list; |
63 | struct ir_input_dev *ir_dev; | 63 | struct ir_input_dev *ir_dev; |
64 | int enabled:1; | ||
65 | 64 | ||
66 | /* State machine control */ | 65 | /* State machine control */ |
67 | enum rc6_state state; | 66 | enum rc6_state state; |
@@ -93,53 +92,6 @@ static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | |||
93 | return data; | 92 | return data; |
94 | } | 93 | } |
95 | 94 | ||
96 | static ssize_t store_enabled(struct device *d, | ||
97 | struct device_attribute *mattr, | ||
98 | const char *buf, | ||
99 | size_t len) | ||
100 | { | ||
101 | unsigned long value; | ||
102 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
103 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
104 | |||
105 | if (!data) | ||
106 | return -EINVAL; | ||
107 | |||
108 | if (strict_strtoul(buf, 10, &value) || value > 1) | ||
109 | return -EINVAL; | ||
110 | |||
111 | data->enabled = value; | ||
112 | |||
113 | return len; | ||
114 | } | ||
115 | |||
116 | static ssize_t show_enabled(struct device *d, | ||
117 | struct device_attribute *mattr, char *buf) | ||
118 | { | ||
119 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
120 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
121 | |||
122 | if (!data) | ||
123 | return -EINVAL; | ||
124 | |||
125 | if (data->enabled) | ||
126 | return sprintf(buf, "1\n"); | ||
127 | else | ||
128 | return sprintf(buf, "0\n"); | ||
129 | } | ||
130 | |||
131 | static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled); | ||
132 | |||
133 | static struct attribute *decoder_attributes[] = { | ||
134 | &dev_attr_enabled.attr, | ||
135 | NULL | ||
136 | }; | ||
137 | |||
138 | static struct attribute_group decoder_attribute_group = { | ||
139 | .name = "rc6_decoder", | ||
140 | .attrs = decoder_attributes, | ||
141 | }; | ||
142 | |||
143 | static enum rc6_mode rc6_mode(struct decoder_data *data) { | 95 | static enum rc6_mode rc6_mode(struct decoder_data *data) { |
144 | switch (data->header & RC6_MODE_MASK) { | 96 | switch (data->header & RC6_MODE_MASK) { |
145 | case 0: | 97 | case 0: |
@@ -171,7 +123,7 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
171 | if (!data) | 123 | if (!data) |
172 | return -EINVAL; | 124 | return -EINVAL; |
173 | 125 | ||
174 | if (!data->enabled) | 126 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) |
175 | return 0; | 127 | return 0; |
176 | 128 | ||
177 | if (IS_RESET(ev)) { | 129 | if (IS_RESET(ev)) { |
@@ -352,22 +304,12 @@ static int ir_rc6_register(struct input_dev *input_dev) | |||
352 | { | 304 | { |
353 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 305 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
354 | struct decoder_data *data; | 306 | struct decoder_data *data; |
355 | u64 ir_type = ir_dev->rc_tab.ir_type; | ||
356 | int rc; | ||
357 | |||
358 | rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
359 | if (rc < 0) | ||
360 | return rc; | ||
361 | 307 | ||
362 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 308 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
363 | if (!data) { | 309 | if (!data) |
364 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
365 | return -ENOMEM; | 310 | return -ENOMEM; |
366 | } | ||
367 | 311 | ||
368 | data->ir_dev = ir_dev; | 312 | data->ir_dev = ir_dev; |
369 | if (ir_type == IR_TYPE_RC6 || ir_type == IR_TYPE_UNKNOWN) | ||
370 | data->enabled = 1; | ||
371 | 313 | ||
372 | spin_lock(&decoder_lock); | 314 | spin_lock(&decoder_lock); |
373 | list_add_tail(&data->list, &decoder_list); | 315 | list_add_tail(&data->list, &decoder_list); |
@@ -385,8 +327,6 @@ static int ir_rc6_unregister(struct input_dev *input_dev) | |||
385 | if (!data) | 327 | if (!data) |
386 | return 0; | 328 | return 0; |
387 | 329 | ||
388 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
389 | |||
390 | spin_lock(&decoder_lock); | 330 | spin_lock(&decoder_lock); |
391 | list_del(&data->list); | 331 | list_del(&data->list); |
392 | spin_unlock(&decoder_lock); | 332 | spin_unlock(&decoder_lock); |
@@ -395,6 +335,7 @@ static int ir_rc6_unregister(struct input_dev *input_dev) | |||
395 | } | 335 | } |
396 | 336 | ||
397 | static struct ir_raw_handler rc6_handler = { | 337 | static struct ir_raw_handler rc6_handler = { |
338 | .protocols = IR_TYPE_RC6, | ||
398 | .decode = ir_rc6_decode, | 339 | .decode = ir_rc6_decode, |
399 | .raw_register = ir_rc6_register, | 340 | .raw_register = ir_rc6_register, |
400 | .raw_unregister = ir_rc6_unregister, | 341 | .raw_unregister = ir_rc6_unregister, |
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c index 219075ffd6b7..e15db3334998 100644 --- a/drivers/media/IR/ir-sony-decoder.c +++ b/drivers/media/IR/ir-sony-decoder.c | |||
@@ -38,7 +38,6 @@ enum sony_state { | |||
38 | struct decoder_data { | 38 | struct decoder_data { |
39 | struct list_head list; | 39 | struct list_head list; |
40 | struct ir_input_dev *ir_dev; | 40 | struct ir_input_dev *ir_dev; |
41 | int enabled:1; | ||
42 | 41 | ||
43 | /* State machine control */ | 42 | /* State machine control */ |
44 | enum sony_state state; | 43 | enum sony_state state; |
@@ -66,53 +65,6 @@ static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | |||
66 | return data; | 65 | return data; |
67 | } | 66 | } |
68 | 67 | ||
69 | static ssize_t store_enabled(struct device *d, | ||
70 | struct device_attribute *mattr, | ||
71 | const char *buf, | ||
72 | size_t len) | ||
73 | { | ||
74 | unsigned long value; | ||
75 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
76 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
77 | |||
78 | if (!data) | ||
79 | return -EINVAL; | ||
80 | |||
81 | if (strict_strtoul(buf, 10, &value) || value > 1) | ||
82 | return -EINVAL; | ||
83 | |||
84 | data->enabled = value; | ||
85 | |||
86 | return len; | ||
87 | } | ||
88 | |||
89 | static ssize_t show_enabled(struct device *d, | ||
90 | struct device_attribute *mattr, char *buf) | ||
91 | { | ||
92 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | ||
93 | struct decoder_data *data = get_decoder_data(ir_dev); | ||
94 | |||
95 | if (!data) | ||
96 | return -EINVAL; | ||
97 | |||
98 | if (data->enabled) | ||
99 | return sprintf(buf, "1\n"); | ||
100 | else | ||
101 | return sprintf(buf, "0\n"); | ||
102 | } | ||
103 | |||
104 | static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled); | ||
105 | |||
106 | static struct attribute *decoder_attributes[] = { | ||
107 | &dev_attr_enabled.attr, | ||
108 | NULL | ||
109 | }; | ||
110 | |||
111 | static struct attribute_group decoder_attribute_group = { | ||
112 | .name = "sony_decoder", | ||
113 | .attrs = decoder_attributes, | ||
114 | }; | ||
115 | |||
116 | /** | 68 | /** |
117 | * ir_sony_decode() - Decode one Sony pulse or space | 69 | * ir_sony_decode() - Decode one Sony pulse or space |
118 | * @input_dev: the struct input_dev descriptor of the device | 70 | * @input_dev: the struct input_dev descriptor of the device |
@@ -131,7 +83,7 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
131 | if (!data) | 83 | if (!data) |
132 | return -EINVAL; | 84 | return -EINVAL; |
133 | 85 | ||
134 | if (!data->enabled) | 86 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) |
135 | return 0; | 87 | return 0; |
136 | 88 | ||
137 | if (IS_RESET(ev)) { | 89 | if (IS_RESET(ev)) { |
@@ -245,22 +197,12 @@ static int ir_sony_register(struct input_dev *input_dev) | |||
245 | { | 197 | { |
246 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 198 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
247 | struct decoder_data *data; | 199 | struct decoder_data *data; |
248 | u64 ir_type = ir_dev->rc_tab.ir_type; | ||
249 | int rc; | ||
250 | |||
251 | rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
252 | if (rc < 0) | ||
253 | return rc; | ||
254 | 200 | ||
255 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 201 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
256 | if (!data) { | 202 | if (!data) |
257 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
258 | return -ENOMEM; | 203 | return -ENOMEM; |
259 | } | ||
260 | 204 | ||
261 | data->ir_dev = ir_dev; | 205 | data->ir_dev = ir_dev; |
262 | if (ir_type == IR_TYPE_SONY || ir_type == IR_TYPE_UNKNOWN) | ||
263 | data->enabled = 1; | ||
264 | 206 | ||
265 | spin_lock(&decoder_lock); | 207 | spin_lock(&decoder_lock); |
266 | list_add_tail(&data->list, &decoder_list); | 208 | list_add_tail(&data->list, &decoder_list); |
@@ -278,8 +220,6 @@ static int ir_sony_unregister(struct input_dev *input_dev) | |||
278 | if (!data) | 220 | if (!data) |
279 | return 0; | 221 | return 0; |
280 | 222 | ||
281 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
282 | |||
283 | spin_lock(&decoder_lock); | 223 | spin_lock(&decoder_lock); |
284 | list_del(&data->list); | 224 | list_del(&data->list); |
285 | spin_unlock(&decoder_lock); | 225 | spin_unlock(&decoder_lock); |
@@ -288,6 +228,7 @@ static int ir_sony_unregister(struct input_dev *input_dev) | |||
288 | } | 228 | } |
289 | 229 | ||
290 | static struct ir_raw_handler sony_handler = { | 230 | static struct ir_raw_handler sony_handler = { |
231 | .protocols = IR_TYPE_SONY, | ||
291 | .decode = ir_sony_decode, | 232 | .decode = ir_sony_decode, |
292 | .raw_register = ir_sony_register, | 233 | .raw_register = ir_sony_register, |
293 | .raw_unregister = ir_sony_unregister, | 234 | .raw_unregister = ir_sony_unregister, |
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 2098dd1488e0..005621d067f0 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -34,122 +34,178 @@ static struct class ir_input_class = { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * show_protocol() - shows the current IR protocol | 37 | * show_protocols() - shows the current IR protocol(s) |
38 | * @d: the device descriptor | 38 | * @d: the device descriptor |
39 | * @mattr: the device attribute struct (unused) | 39 | * @mattr: the device attribute struct (unused) |
40 | * @buf: a pointer to the output buffer | 40 | * @buf: a pointer to the output buffer |
41 | * | 41 | * |
42 | * This routine is a callback routine for input read the IR protocol type. | 42 | * This routine is a callback routine for input read the IR protocol type(s). |
43 | * it is trigged by reading /sys/class/rc/rc?/current_protocol. | 43 | * it is trigged by reading /sys/class/rc/rc?/protocols. |
44 | * It returns the protocol name, as understood by the driver. | 44 | * It returns the protocol names of supported protocols. |
45 | * Enabled protocols are printed in brackets. | ||
45 | */ | 46 | */ |
46 | static ssize_t show_protocol(struct device *d, | 47 | static ssize_t show_protocols(struct device *d, |
47 | struct device_attribute *mattr, char *buf) | 48 | struct device_attribute *mattr, char *buf) |
48 | { | 49 | { |
49 | char *s; | ||
50 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | 50 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); |
51 | u64 ir_type = ir_dev->rc_tab.ir_type; | 51 | u64 allowed, enabled; |
52 | 52 | char *tmp = buf; | |
53 | IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type); | 53 | |
54 | 54 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { | |
55 | /* FIXME: doesn't support multiple protocols at the same time */ | 55 | enabled = ir_dev->rc_tab.ir_type; |
56 | if (ir_type == IR_TYPE_UNKNOWN) | 56 | allowed = ir_dev->props->allowed_protos; |
57 | s = "Unknown"; | 57 | } else { |
58 | else if (ir_type == IR_TYPE_RC5) | 58 | enabled = ir_dev->raw->enabled_protocols; |
59 | s = "rc-5"; | 59 | allowed = ir_raw_get_allowed_protocols(); |
60 | else if (ir_type == IR_TYPE_NEC) | 60 | } |
61 | s = "nec"; | ||
62 | else if (ir_type == IR_TYPE_RC6) | ||
63 | s = "rc6"; | ||
64 | else if (ir_type == IR_TYPE_JVC) | ||
65 | s = "jvc"; | ||
66 | else if (ir_type == IR_TYPE_SONY) | ||
67 | s = "sony"; | ||
68 | else | ||
69 | s = "other"; | ||
70 | 61 | ||
71 | return sprintf(buf, "%s\n", s); | 62 | IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", |
63 | (long long)allowed, | ||
64 | (long long)enabled); | ||
65 | |||
66 | if (allowed & enabled & IR_TYPE_UNKNOWN) | ||
67 | tmp += sprintf(tmp, "[unknown] "); | ||
68 | else if (allowed & IR_TYPE_UNKNOWN) | ||
69 | tmp += sprintf(tmp, "unknown "); | ||
70 | |||
71 | if (allowed & enabled & IR_TYPE_RC5) | ||
72 | tmp += sprintf(tmp, "[rc5] "); | ||
73 | else if (allowed & IR_TYPE_RC5) | ||
74 | tmp += sprintf(tmp, "rc5 "); | ||
75 | |||
76 | if (allowed & enabled & IR_TYPE_NEC) | ||
77 | tmp += sprintf(tmp, "[nec] "); | ||
78 | else if (allowed & IR_TYPE_NEC) | ||
79 | tmp += sprintf(tmp, "nec "); | ||
80 | |||
81 | if (allowed & enabled & IR_TYPE_RC6) | ||
82 | tmp += sprintf(tmp, "[rc6] "); | ||
83 | else if (allowed & IR_TYPE_RC6) | ||
84 | tmp += sprintf(tmp, "rc6 "); | ||
85 | |||
86 | if (allowed & enabled & IR_TYPE_JVC) | ||
87 | tmp += sprintf(tmp, "[jvc] "); | ||
88 | else if (allowed & IR_TYPE_JVC) | ||
89 | tmp += sprintf(tmp, "jvc "); | ||
90 | |||
91 | if (allowed & enabled & IR_TYPE_SONY) | ||
92 | tmp += sprintf(tmp, "[sony] "); | ||
93 | else if (allowed & IR_TYPE_SONY) | ||
94 | tmp += sprintf(tmp, "sony "); | ||
95 | |||
96 | if (tmp != buf) | ||
97 | tmp--; | ||
98 | *tmp = '\n'; | ||
99 | return tmp + 1 - buf; | ||
72 | } | 100 | } |
73 | 101 | ||
74 | /** | 102 | /** |
75 | * store_protocol() - shows the current IR protocol | 103 | * store_protocols() - changes the current IR protocol(s) |
76 | * @d: the device descriptor | 104 | * @d: the device descriptor |
77 | * @mattr: the device attribute struct (unused) | 105 | * @mattr: the device attribute struct (unused) |
78 | * @buf: a pointer to the input buffer | 106 | * @buf: a pointer to the input buffer |
79 | * @len: length of the input buffer | 107 | * @len: length of the input buffer |
80 | * | 108 | * |
81 | * This routine is a callback routine for changing the IR protocol type. | 109 | * This routine is a callback routine for changing the IR protocol type. |
82 | * it is trigged by reading /sys/class/rc/rc?/current_protocol. | 110 | * It is trigged by writing to /sys/class/rc/rc?/protocols. |
83 | * It changes the IR the protocol name, if the IR type is recognized | 111 | * Writing "+proto" will add a protocol to the list of enabled protocols. |
84 | * by the driver. | 112 | * Writing "-proto" will remove a protocol from the list of enabled protocols. |
85 | * If an unknown protocol name is used, returns -EINVAL. | 113 | * Writing "proto" will enable only "proto". |
114 | * Returns -EINVAL if an invalid protocol combination or unknown protocol name | ||
115 | * is used, otherwise @len. | ||
86 | */ | 116 | */ |
87 | static ssize_t store_protocol(struct device *d, | 117 | static ssize_t store_protocols(struct device *d, |
88 | struct device_attribute *mattr, | 118 | struct device_attribute *mattr, |
89 | const char *data, | 119 | const char *data, |
90 | size_t len) | 120 | size_t len) |
91 | { | 121 | { |
92 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | 122 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); |
93 | u64 ir_type = 0; | 123 | bool enable, disable; |
94 | int rc = -EINVAL; | 124 | const char *tmp; |
125 | u64 type; | ||
126 | u64 mask; | ||
127 | int rc; | ||
95 | unsigned long flags; | 128 | unsigned long flags; |
96 | char *buf; | 129 | |
97 | 130 | tmp = skip_spaces(data); | |
98 | while ((buf = strsep((char **) &data, " \n")) != NULL) { | 131 | |
99 | if (!strcasecmp(buf, "rc-5") || !strcasecmp(buf, "rc5")) | 132 | if (*tmp == '+') { |
100 | ir_type |= IR_TYPE_RC5; | 133 | enable = true; |
101 | if (!strcasecmp(buf, "nec")) | 134 | disable = false; |
102 | ir_type |= IR_TYPE_NEC; | 135 | tmp++; |
103 | if (!strcasecmp(buf, "jvc")) | 136 | } else if (*tmp == '-') { |
104 | ir_type |= IR_TYPE_JVC; | 137 | enable = false; |
105 | if (!strcasecmp(buf, "sony")) | 138 | disable = true; |
106 | ir_type |= IR_TYPE_SONY; | 139 | tmp++; |
140 | } else { | ||
141 | enable = false; | ||
142 | disable = false; | ||
107 | } | 143 | } |
108 | 144 | ||
109 | if (!ir_type) { | 145 | if (!strncasecmp(tmp, "unknown", 7)) { |
146 | tmp += 7; | ||
147 | mask = IR_TYPE_UNKNOWN; | ||
148 | } else if (!strncasecmp(tmp, "rc5", 3)) { | ||
149 | tmp += 3; | ||
150 | mask = IR_TYPE_RC5; | ||
151 | } else if (!strncasecmp(tmp, "nec", 3)) { | ||
152 | tmp += 3; | ||
153 | mask = IR_TYPE_NEC; | ||
154 | } else if (!strncasecmp(tmp, "rc6", 3)) { | ||
155 | tmp += 3; | ||
156 | mask = IR_TYPE_RC6; | ||
157 | } else if (!strncasecmp(tmp, "jvc", 3)) { | ||
158 | tmp += 3; | ||
159 | mask = IR_TYPE_JVC; | ||
160 | } else if (!strncasecmp(tmp, "sony", 4)) { | ||
161 | tmp += 4; | ||
162 | mask = IR_TYPE_SONY; | ||
163 | } else { | ||
110 | IR_dprintk(1, "Unknown protocol\n"); | 164 | IR_dprintk(1, "Unknown protocol\n"); |
111 | return -EINVAL; | 165 | return -EINVAL; |
112 | } | 166 | } |
113 | 167 | ||
114 | if (ir_dev->props && ir_dev->props->change_protocol) | 168 | tmp = skip_spaces(tmp); |
115 | rc = ir_dev->props->change_protocol(ir_dev->props->priv, | 169 | if (*tmp != '\0') { |
116 | ir_type); | 170 | IR_dprintk(1, "Invalid trailing characters\n"); |
117 | |||
118 | if (rc < 0) { | ||
119 | IR_dprintk(1, "Error setting protocol to %lld\n", | ||
120 | (long long)ir_type); | ||
121 | return -EINVAL; | 171 | return -EINVAL; |
122 | } | 172 | } |
123 | 173 | ||
124 | spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); | 174 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) |
125 | ir_dev->rc_tab.ir_type = ir_type; | 175 | type = ir_dev->rc_tab.ir_type; |
126 | spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); | 176 | else |
177 | type = ir_dev->raw->enabled_protocols; | ||
127 | 178 | ||
128 | IR_dprintk(1, "Current protocol(s) is(are) %lld\n", | 179 | if (enable) |
129 | (long long)ir_type); | 180 | type |= mask; |
181 | else if (disable) | ||
182 | type &= ~mask; | ||
183 | else | ||
184 | type = mask; | ||
130 | 185 | ||
131 | return len; | 186 | if (ir_dev->props && ir_dev->props->change_protocol) { |
132 | } | 187 | rc = ir_dev->props->change_protocol(ir_dev->props->priv, |
188 | type); | ||
189 | if (rc < 0) { | ||
190 | IR_dprintk(1, "Error setting protocols to 0x%llx\n", | ||
191 | (long long)type); | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | } | ||
133 | 195 | ||
134 | static ssize_t show_supported_protocols(struct device *d, | 196 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { |
135 | struct device_attribute *mattr, char *buf) | 197 | spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); |
136 | { | 198 | ir_dev->rc_tab.ir_type = type; |
137 | char *orgbuf = buf; | 199 | spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); |
138 | struct ir_input_dev *ir_dev = dev_get_drvdata(d); | 200 | } else { |
201 | ir_dev->raw->enabled_protocols = type; | ||
202 | } | ||
139 | 203 | ||
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 "); | ||
147 | if (buf == orgbuf) | ||
148 | buf += sprintf(buf, "other "); | ||
149 | 204 | ||
150 | buf += sprintf(buf - 1, "\n"); | 205 | IR_dprintk(1, "Current protocol(s): 0x%llx\n", |
206 | (long long)type); | ||
151 | 207 | ||
152 | return buf - orgbuf; | 208 | return len; |
153 | } | 209 | } |
154 | 210 | ||
155 | #define ADD_HOTPLUG_VAR(fmt, val...) \ | 211 | #define ADD_HOTPLUG_VAR(fmt, val...) \ |
@@ -159,7 +215,7 @@ static ssize_t show_supported_protocols(struct device *d, | |||
159 | return err; \ | 215 | return err; \ |
160 | } while (0) | 216 | } while (0) |
161 | 217 | ||
162 | static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env) | 218 | static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) |
163 | { | 219 | { |
164 | struct ir_input_dev *ir_dev = dev_get_drvdata(device); | 220 | struct ir_input_dev *ir_dev = dev_get_drvdata(device); |
165 | 221 | ||
@@ -174,34 +230,26 @@ static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
174 | /* | 230 | /* |
175 | * Static device attribute struct with the sysfs attributes for IR's | 231 | * Static device attribute struct with the sysfs attributes for IR's |
176 | */ | 232 | */ |
177 | static DEVICE_ATTR(protocol, S_IRUGO | S_IWUSR, | 233 | static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, |
178 | show_protocol, store_protocol); | 234 | show_protocols, store_protocols); |
179 | |||
180 | static DEVICE_ATTR(supported_protocols, S_IRUGO | S_IWUSR, | ||
181 | show_supported_protocols, NULL); | ||
182 | 235 | ||
183 | static struct attribute *ir_hw_dev_attrs[] = { | 236 | static struct attribute *rc_dev_attrs[] = { |
184 | &dev_attr_protocol.attr, | 237 | &dev_attr_protocols.attr, |
185 | &dev_attr_supported_protocols.attr, | ||
186 | NULL, | 238 | NULL, |
187 | }; | 239 | }; |
188 | 240 | ||
189 | static struct attribute_group ir_hw_dev_attr_grp = { | 241 | static struct attribute_group rc_dev_attr_grp = { |
190 | .attrs = ir_hw_dev_attrs, | 242 | .attrs = rc_dev_attrs, |
191 | }; | 243 | }; |
192 | 244 | ||
193 | static const struct attribute_group *ir_hw_dev_attr_groups[] = { | 245 | static const struct attribute_group *rc_dev_attr_groups[] = { |
194 | &ir_hw_dev_attr_grp, | 246 | &rc_dev_attr_grp, |
195 | NULL | 247 | NULL |
196 | }; | 248 | }; |
197 | 249 | ||
198 | static struct device_type rc_dev_type = { | 250 | static struct device_type rc_dev_type = { |
199 | .groups = ir_hw_dev_attr_groups, | 251 | .groups = rc_dev_attr_groups, |
200 | .uevent = ir_dev_uevent, | 252 | .uevent = rc_dev_uevent, |
201 | }; | ||
202 | |||
203 | static struct device_type ir_raw_dev_type = { | ||
204 | .uevent = ir_dev_uevent, | ||
205 | }; | 253 | }; |
206 | 254 | ||
207 | /** | 255 | /** |
@@ -221,11 +269,7 @@ int ir_register_class(struct input_dev *input_dev) | |||
221 | if (unlikely(devno < 0)) | 269 | if (unlikely(devno < 0)) |
222 | return devno; | 270 | return devno; |
223 | 271 | ||
224 | if (ir_dev->props) { | 272 | ir_dev->dev.type = &rc_dev_type; |
225 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) | ||
226 | ir_dev->dev.type = &rc_dev_type; | ||
227 | } else | ||
228 | ir_dev->dev.type = &ir_raw_dev_type; | ||
229 | 273 | ||
230 | ir_dev->dev.class = &ir_input_class; | 274 | ir_dev->dev.class = &ir_input_class; |
231 | ir_dev->dev.parent = input_dev->dev.parent; | 275 | ir_dev->dev.parent = input_dev->dev.parent; |