diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 13:38:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 13:38:08 -0400 |
commit | f63b759c44b0561c76a67894c734157df3313b42 (patch) | |
tree | 4e9638f6c1aa5c0faa62ad4213282cc7cb39772a /drivers/media/IR/ir-rc6-decoder.c | |
parent | 4a35cee066df1b1958e25e71595b3845d06b192e (diff) | |
parent | 844a9e93d7fcd910cd94f6eb262e2cc43cacbe56 (diff) |
Merge branch 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (243 commits)
V4L/DVB: sms: Convert IR support to use the Remote Controller core
V4L/DVB: sms: properly initialize IR phys and IR name
V4L/DVB: standardize names at rc-dib0700 tables
V4L/DVB: smsusb: enable IR port for Hauppauge WinTV MiniStick
V4L/DVB: dib0700: Fix RC protocol logic to properly handle NEC/NECx and RC-5
V4L/DVB: dib0700: properly implement IR change_protocol
V4L/DVB: dib0700: break keytable into NEC and RC-5 variants
V4L/DVB: dib0700: avoid bad repeat
V4L/DVB: Port dib0700 to rc-core
V4L/DVB: Add a keymap file with dib0700 table
V4L/DVB: dvb-usb: add support for rc-core mode
V4L/DVB: dvb-usb: prepare drivers for using rc-core
V4L/DVB: dvb-usb: get rid of struct dvb_usb_rc_key
V4L/DVB: rj54n1cb0c: fix a comment in the driver
V4L/DVB: V4L2: sh_vou: VOU does support the full PAL resolution too
V4L/DVB: V4L2: sh_mobile_camera_ceu: add support for CSI2
V4L/DVB: V4L2: soc-camera: add a MIPI CSI-2 driver for SH-Mobile platforms
V4L/DVB: V4L2: soc-camera: export soc-camera bus type for notifications
V4L/DVB: V4L2: mediabus: add 12-bit Bayer and YUV420 pixel formats
V4L/DVB: mediabus: fix ambiguous pixel code names
...
Diffstat (limited to 'drivers/media/IR/ir-rc6-decoder.c')
-rw-r--r-- | drivers/media/IR/ir-rc6-decoder.c | 153 |
1 files changed, 7 insertions, 146 deletions
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c index 2bf479f4f1bc..f1624b8279bc 100644 --- a/drivers/media/IR/ir-rc6-decoder.c +++ b/drivers/media/IR/ir-rc6-decoder.c | |||
@@ -36,10 +36,6 @@ | |||
36 | #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ | 36 | #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ |
37 | #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ | 37 | #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ |
38 | 38 | ||
39 | /* Used to register rc6_decoder clients */ | ||
40 | static LIST_HEAD(decoder_list); | ||
41 | static DEFINE_SPINLOCK(decoder_lock); | ||
42 | |||
43 | enum rc6_mode { | 39 | enum rc6_mode { |
44 | RC6_MODE_0, | 40 | RC6_MODE_0, |
45 | RC6_MODE_6A, | 41 | RC6_MODE_6A, |
@@ -58,89 +54,8 @@ enum rc6_state { | |||
58 | STATE_FINISHED, | 54 | STATE_FINISHED, |
59 | }; | 55 | }; |
60 | 56 | ||
61 | struct decoder_data { | 57 | static enum rc6_mode rc6_mode(struct rc6_dec *data) |
62 | struct list_head list; | ||
63 | struct ir_input_dev *ir_dev; | ||
64 | int enabled:1; | ||
65 | |||
66 | /* State machine control */ | ||
67 | enum rc6_state state; | ||
68 | u8 header; | ||
69 | u32 body; | ||
70 | struct ir_raw_event prev_ev; | ||
71 | bool toggle; | ||
72 | unsigned count; | ||
73 | unsigned wanted_bits; | ||
74 | }; | ||
75 | |||
76 | |||
77 | /** | ||
78 | * get_decoder_data() - gets decoder data | ||
79 | * @input_dev: input device | ||
80 | * | ||
81 | * Returns the struct decoder_data that corresponds to a device | ||
82 | */ | ||
83 | static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | ||
84 | { | ||
85 | struct decoder_data *data = NULL; | ||
86 | |||
87 | spin_lock(&decoder_lock); | ||
88 | list_for_each_entry(data, &decoder_list, list) { | ||
89 | if (data->ir_dev == ir_dev) | ||
90 | break; | ||
91 | } | ||
92 | spin_unlock(&decoder_lock); | ||
93 | return data; | ||
94 | } | ||
95 | |||
96 | static ssize_t store_enabled(struct device *d, | ||
97 | struct device_attribute *mattr, | ||
98 | const char *buf, | ||
99 | size_t len) | ||
100 | { | 58 | { |
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) { | ||
144 | switch (data->header & RC6_MODE_MASK) { | 59 | switch (data->header & RC6_MODE_MASK) { |
145 | case 0: | 60 | case 0: |
146 | return RC6_MODE_0; | 61 | return RC6_MODE_0; |
@@ -162,16 +77,12 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) { | |||
162 | */ | 77 | */ |
163 | static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) | 78 | static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) |
164 | { | 79 | { |
165 | struct decoder_data *data; | ||
166 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 80 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
81 | struct rc6_dec *data = &ir_dev->raw->rc6; | ||
167 | u32 scancode; | 82 | u32 scancode; |
168 | u8 toggle; | 83 | u8 toggle; |
169 | 84 | ||
170 | data = get_decoder_data(ir_dev); | 85 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) |
171 | if (!data) | ||
172 | return -EINVAL; | ||
173 | |||
174 | if (!data->enabled) | ||
175 | return 0; | 86 | return 0; |
176 | 87 | ||
177 | if (IS_RESET(ev)) { | 88 | if (IS_RESET(ev)) { |
@@ -223,12 +134,11 @@ again: | |||
223 | if (ev.pulse) | 134 | if (ev.pulse) |
224 | data->header |= 1; | 135 | data->header |= 1; |
225 | data->count++; | 136 | data->count++; |
226 | data->prev_ev = ev; | ||
227 | data->state = STATE_HEADER_BIT_END; | 137 | data->state = STATE_HEADER_BIT_END; |
228 | return 0; | 138 | return 0; |
229 | 139 | ||
230 | case STATE_HEADER_BIT_END: | 140 | case STATE_HEADER_BIT_END: |
231 | if (!is_transition(&ev, &data->prev_ev)) | 141 | if (!is_transition(&ev, &ir_dev->raw->prev_ev)) |
232 | break; | 142 | break; |
233 | 143 | ||
234 | if (data->count == RC6_HEADER_NBITS) | 144 | if (data->count == RC6_HEADER_NBITS) |
@@ -244,12 +154,11 @@ again: | |||
244 | break; | 154 | break; |
245 | 155 | ||
246 | data->toggle = ev.pulse; | 156 | data->toggle = ev.pulse; |
247 | data->prev_ev = ev; | ||
248 | data->state = STATE_TOGGLE_END; | 157 | data->state = STATE_TOGGLE_END; |
249 | return 0; | 158 | return 0; |
250 | 159 | ||
251 | case STATE_TOGGLE_END: | 160 | case STATE_TOGGLE_END: |
252 | if (!is_transition(&ev, &data->prev_ev) || | 161 | if (!is_transition(&ev, &ir_dev->raw->prev_ev) || |
253 | !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) | 162 | !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) |
254 | break; | 163 | break; |
255 | 164 | ||
@@ -259,7 +168,6 @@ again: | |||
259 | } | 168 | } |
260 | 169 | ||
261 | data->state = STATE_BODY_BIT_START; | 170 | data->state = STATE_BODY_BIT_START; |
262 | data->prev_ev = ev; | ||
263 | decrease_duration(&ev, RC6_TOGGLE_END); | 171 | decrease_duration(&ev, RC6_TOGGLE_END); |
264 | data->count = 0; | 172 | data->count = 0; |
265 | 173 | ||
@@ -291,13 +199,11 @@ again: | |||
291 | if (ev.pulse) | 199 | if (ev.pulse) |
292 | data->body |= 1; | 200 | data->body |= 1; |
293 | data->count++; | 201 | data->count++; |
294 | data->prev_ev = ev; | ||
295 | |||
296 | data->state = STATE_BODY_BIT_END; | 202 | data->state = STATE_BODY_BIT_END; |
297 | return 0; | 203 | return 0; |
298 | 204 | ||
299 | case STATE_BODY_BIT_END: | 205 | case STATE_BODY_BIT_END: |
300 | if (!is_transition(&ev, &data->prev_ev)) | 206 | if (!is_transition(&ev, &ir_dev->raw->prev_ev)) |
301 | break; | 207 | break; |
302 | 208 | ||
303 | if (data->count == data->wanted_bits) | 209 | if (data->count == data->wanted_bits) |
@@ -348,54 +254,9 @@ out: | |||
348 | return -EINVAL; | 254 | return -EINVAL; |
349 | } | 255 | } |
350 | 256 | ||
351 | static int ir_rc6_register(struct input_dev *input_dev) | ||
352 | { | ||
353 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
354 | struct decoder_data *data; | ||
355 | int rc; | ||
356 | |||
357 | rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
358 | if (rc < 0) | ||
359 | return rc; | ||
360 | |||
361 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
362 | if (!data) { | ||
363 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
364 | return -ENOMEM; | ||
365 | } | ||
366 | |||
367 | data->ir_dev = ir_dev; | ||
368 | data->enabled = 1; | ||
369 | |||
370 | spin_lock(&decoder_lock); | ||
371 | list_add_tail(&data->list, &decoder_list); | ||
372 | spin_unlock(&decoder_lock); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static int ir_rc6_unregister(struct input_dev *input_dev) | ||
378 | { | ||
379 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
380 | static struct decoder_data *data; | ||
381 | |||
382 | data = get_decoder_data(ir_dev); | ||
383 | if (!data) | ||
384 | return 0; | ||
385 | |||
386 | sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group); | ||
387 | |||
388 | spin_lock(&decoder_lock); | ||
389 | list_del(&data->list); | ||
390 | spin_unlock(&decoder_lock); | ||
391 | |||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static struct ir_raw_handler rc6_handler = { | 257 | static struct ir_raw_handler rc6_handler = { |
258 | .protocols = IR_TYPE_RC6, | ||
396 | .decode = ir_rc6_decode, | 259 | .decode = ir_rc6_decode, |
397 | .raw_register = ir_rc6_register, | ||
398 | .raw_unregister = ir_rc6_unregister, | ||
399 | }; | 260 | }; |
400 | 261 | ||
401 | static int __init ir_rc6_decode_init(void) | 262 | static int __init ir_rc6_decode_init(void) |