diff options
author | Sylvain Pasche <sylvain.pasche@gmail.com> | 2006-03-25 21:14:42 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-25 01:00:28 -0400 |
commit | b93eedb62e358588c5e595b07fb85efa1f597a9f (patch) | |
tree | ec3ffd9ccd6136d752efa1dbea9235dbd85ed7f8 /drivers/media/video/ir-kbd-i2c.c | |
parent | e48a9c6283c1ca2565167f0b4bce4d0be7f49fae (diff) |
V4L/DVB (4023): Subject: Pinnacle PCTV grey remote control support
This adds support for the older (?) Pinnacle PCTV remotes (with all buttons
colored in grey). There's no autodetection for the type of remote, though;
saa7134 defaults to the colored one, to use the grey remote the
"pinnacle_remote=1" option must be passed to the saa7134 module
Signed-off-by: Sylvain Pasche <sylvain.pasche@gmail.com>
Signed-off-by: Ricardo Cerqueira <v4l@cerqueira.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
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 | ||