diff options
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 7e66d83fe0ce..fba30a40e9c6 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -150,12 +150,11 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
150 | return 1; | 150 | return 1; |
151 | } | 151 | } |
152 | 152 | ||
153 | /* The new pinnacle PCTV remote (with the colored buttons) | 153 | /* Common (grey or coloured) pinnacle PCTV remote handling |
154 | * | 154 | * |
155 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
156 | */ | 155 | */ |
157 | 156 | static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |
158 | int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 157 | int parity_offset, int marker, int code_modulo) |
159 | { | 158 | { |
160 | unsigned char b[4]; | 159 | unsigned char b[4]; |
161 | unsigned int start = 0,parity = 0,code = 0; | 160 | unsigned int start = 0,parity = 0,code = 0; |
@@ -167,9 +166,9 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
167 | } | 166 | } |
168 | 167 | ||
169 | for (start = 0; start<4; start++) { | 168 | for (start = 0; start<4; start++) { |
170 | if (b[start] == 0x80) { | 169 | if (b[start] == marker) { |
171 | code=b[(start+3)%4]; | 170 | code=b[(start+parity_offset+1)%4]; |
172 | parity=b[(start+2)%4]; | 171 | parity=b[(start+parity_offset)%4]; |
173 | } | 172 | } |
174 | } | 173 | } |
175 | 174 | ||
@@ -181,16 +180,14 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
181 | if (ir->old == parity) | 180 | if (ir->old == parity) |
182 | return 0; | 181 | return 0; |
183 | 182 | ||
184 | |||
185 | ir->old = parity; | 183 | ir->old = parity; |
186 | 184 | ||
187 | /* Reduce code value to fit inside IR_KEYTAB_SIZE | 185 | /* drop special codes when a key is held down a long time for the grey controller |
188 | * | 186 | In this case, the second bit of the code is asserted */ |
189 | * this is the only value that results in 42 unique | 187 | if (marker == 0xfe && (code & 0x40)) |
190 | * codes < 128 | 188 | return 0; |
191 | */ | ||
192 | 189 | ||
193 | code %= 0x88; | 190 | code %= code_modulo; |
194 | 191 | ||
195 | *ir_raw = code; | 192 | *ir_raw = code; |
196 | *ir_key = code; | 193 | *ir_key = code; |
@@ -200,7 +197,40 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
200 | return 1; | 197 | return 1; |
201 | } | 198 | } |
202 | 199 | ||
203 | EXPORT_SYMBOL_GPL(get_key_pinnacle); | 200 | /* The grey pinnacle PCTV remote |
201 | * | ||
202 | * There are one issue with this remote: | ||
203 | * - I2c packet does not change when the same key is pressed quickly. The workaround | ||
204 | * is to hold down each key for about half a second, so that another code is generated | ||
205 | * in the i2c packet, and the function can distinguish key presses. | ||
206 | * | ||
207 | * Sylvain Pasche <sylvain.pasche@gmail.com> | ||
208 | */ | ||
209 | int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
210 | { | ||
211 | |||
212 | return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); | ||
213 | } | ||
214 | |||
215 | EXPORT_SYMBOL_GPL(get_key_pinnacle_grey); | ||
216 | |||
217 | |||
218 | /* The new pinnacle PCTV remote (with the colored buttons) | ||
219 | * | ||
220 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
221 | */ | ||
222 | int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
223 | { | ||
224 | /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE | ||
225 | * | ||
226 | * this is the only value that results in 42 unique | ||
227 | * codes < 128 | ||
228 | */ | ||
229 | |||
230 | return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); | ||
231 | } | ||
232 | |||
233 | EXPORT_SYMBOL_GPL(get_key_pinnacle_color); | ||
204 | 234 | ||
205 | /* ----------------------------------------------------------------------- */ | 235 | /* ----------------------------------------------------------------------- */ |
206 | 236 | ||