pxa27x_keypad.c (d7416f9eaa5427f47648973aac3a65e7a0eeda04) | pxa27x_keypad.c (62059d9e912717abbfb875440621d935d091f289) |
---|---|
1/* 2 * linux/drivers/input/keyboard/pxa27x_keypad.c 3 * 4 * Driver for the pxa27x matrix keyboard controller. 5 * 6 * Created: Feb 22, 2007 7 * Author: Rodolfo Giometti <giometti@linux.it> 8 * --- 27 unchanged lines hidden (view full) --- 36#include <asm/arch/pxa27x_keypad.h> 37 38#define DRIVER_NAME "pxa27x-keypad" 39 40#define KPC_MKRN(n) ((((n) & 0x7) - 1) << 26) /* matrix key row number */ 41#define KPC_MKCN(n) ((((n) & 0x7) - 1) << 23) /* matrix key column number */ 42#define KPC_DKN(n) ((((n) & 0x7) - 1) << 6) /* direct key number */ 43 | 1/* 2 * linux/drivers/input/keyboard/pxa27x_keypad.c 3 * 4 * Driver for the pxa27x matrix keyboard controller. 5 * 6 * Created: Feb 22, 2007 7 * Author: Rodolfo Giometti <giometti@linux.it> 8 * --- 27 unchanged lines hidden (view full) --- 36#include <asm/arch/pxa27x_keypad.h> 37 38#define DRIVER_NAME "pxa27x-keypad" 39 40#define KPC_MKRN(n) ((((n) & 0x7) - 1) << 26) /* matrix key row number */ 41#define KPC_MKCN(n) ((((n) & 0x7) - 1) << 23) /* matrix key column number */ 42#define KPC_DKN(n) ((((n) & 0x7) - 1) << 6) /* direct key number */ 43 |
44#define KPDK_DKP (0x1 << 31) 45#define KPDK_DK(n) ((n) & 0xff) 46 |
|
44#define KPAS_MUKP(n) (((n) >> 26) & 0x1f) 45#define KPAS_RP(n) (((n) >> 4) & 0xf) 46#define KPAS_CP(n) ((n) & 0xf) 47 48#define KPASMKP_MKC_MASK (0xff) 49 50#define MAX_MATRIX_KEY_NUM (8 * 8) 51 52struct pxa27x_keypad { 53 struct pxa27x_keypad_platform_data *pdata; 54 55 struct clk *clk; 56 struct input_dev *input_dev; 57 58 /* matrix key code map */ 59 unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; 60 61 /* state row bits of each column scan */ 62 uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; | 47#define KPAS_MUKP(n) (((n) >> 26) & 0x1f) 48#define KPAS_RP(n) (((n) >> 4) & 0xf) 49#define KPAS_CP(n) ((n) & 0xf) 50 51#define KPASMKP_MKC_MASK (0xff) 52 53#define MAX_MATRIX_KEY_NUM (8 * 8) 54 55struct pxa27x_keypad { 56 struct pxa27x_keypad_platform_data *pdata; 57 58 struct clk *clk; 59 struct input_dev *input_dev; 60 61 /* matrix key code map */ 62 unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; 63 64 /* state row bits of each column scan */ 65 uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; |
66 uint32_t direct_key_state; 67 68 unsigned int direct_key_mask; 69 70 int rotary_rel_code[2]; 71 int rotary_up_key[2]; 72 int rotary_down_key[2]; |
|
63}; 64 65static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) 66{ 67 struct pxa27x_keypad_platform_data *pdata = keypad->pdata; 68 struct input_dev *input_dev = keypad->input_dev; 69 unsigned int *key; 70 int i; 71 72 key = &pdata->matrix_key_map[0]; 73 for (i = 0; i < pdata->matrix_key_map_size; i++, key++) { 74 int row = ((*key) >> 28) & 0xf; 75 int col = ((*key) >> 24) & 0xf; 76 int code = (*key) & 0xffffff; 77 78 keypad->matrix_keycodes[(row << 3) + col] = code; 79 set_bit(code, input_dev->keybit); 80 } | 73}; 74 75static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) 76{ 77 struct pxa27x_keypad_platform_data *pdata = keypad->pdata; 78 struct input_dev *input_dev = keypad->input_dev; 79 unsigned int *key; 80 int i; 81 82 key = &pdata->matrix_key_map[0]; 83 for (i = 0; i < pdata->matrix_key_map_size; i++, key++) { 84 int row = ((*key) >> 28) & 0xf; 85 int col = ((*key) >> 24) & 0xf; 86 int code = (*key) & 0xffffff; 87 88 keypad->matrix_keycodes[(row << 3) + col] = code; 89 set_bit(code, input_dev->keybit); 90 } |
91 92 keypad->rotary_up_key[0] = pdata->rotary0_up_key; 93 keypad->rotary_up_key[1] = pdata->rotary1_up_key; 94 keypad->rotary_down_key[0] = pdata->rotary0_down_key; 95 keypad->rotary_down_key[1] = pdata->rotary1_down_key; 96 keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; 97 keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; 98 99 if (pdata->rotary0_up_key && pdata->rotary0_down_key) { 100 set_bit(pdata->rotary0_up_key, input_dev->keybit); 101 set_bit(pdata->rotary0_down_key, input_dev->keybit); 102 } else 103 set_bit(pdata->rotary0_rel_code, input_dev->relbit); 104 105 if (pdata->rotary1_up_key && pdata->rotary1_down_key) { 106 set_bit(pdata->rotary1_up_key, input_dev->keybit); 107 set_bit(pdata->rotary1_down_key, input_dev->keybit); 108 } else 109 set_bit(pdata->rotary1_rel_code, input_dev->relbit); |
|
81} 82 83static inline unsigned int lookup_matrix_keycode( 84 struct pxa27x_keypad *keypad, int row, int col) 85{ 86 return keypad->matrix_keycodes[(row << 3) + col]; 87} 88 --- 57 unchanged lines hidden (view full) --- 146 } 147 } 148 input_sync(keypad->input_dev); 149 memcpy(keypad->matrix_key_state, new_state, sizeof(new_state)); 150} 151 152#define DEFAULT_KPREC (0x007f007f) 153 | 110} 111 112static inline unsigned int lookup_matrix_keycode( 113 struct pxa27x_keypad *keypad, int row, int col) 114{ 115 return keypad->matrix_keycodes[(row << 3) + col]; 116} 117 --- 57 unchanged lines hidden (view full) --- 175 } 176 } 177 input_sync(keypad->input_dev); 178 memcpy(keypad->matrix_key_state, new_state, sizeof(new_state)); 179} 180 181#define DEFAULT_KPREC (0x007f007f) 182 |
154static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) | 183static inline int rotary_delta(uint32_t kprec) |
155{ | 184{ |
156 struct pxa27x_keypad *keypad = dev_id; 157 struct input_dev *input_dev = keypad->input_dev; 158 unsigned long kpc = KPC; 159 int rel; | 185 if (kprec & KPREC_OF0) 186 return (kprec & 0xff) + 0x7f; 187 else if (kprec & KPREC_UF0) 188 return (kprec & 0xff) - 0x7f - 0xff; 189 else 190 return (kprec & 0xff) - 0x7f; 191} |
160 | 192 |
161 if (kpc & KPC_DI) { 162 unsigned long kpdk = KPDK; | 193static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta) 194{ 195 struct input_dev *dev = keypad->input_dev; |
163 | 196 |
164 if (!(kpdk & KPDK_DKP)) { 165 /* better luck next time */ 166 } else if (kpc & KPC_REE0) { 167 unsigned long kprec = KPREC; 168 KPREC = 0x7f; | 197 if (delta == 0) 198 return; |
169 | 199 |
170 if (kprec & KPREC_OF0) 171 rel = (kprec & 0xff) + 0x7f; 172 else if (kprec & KPREC_UF0) 173 rel = (kprec & 0xff) - 0x7f - 0xff; 174 else 175 rel = (kprec & 0xff) - 0x7f; | 200 if (keypad->rotary_up_key[r] && keypad->rotary_down_key[r]) { 201 int keycode = (delta > 0) ? keypad->rotary_up_key[r] : 202 keypad->rotary_down_key[r]; |
176 | 203 |
177 if (rel) { 178 input_report_rel(input_dev, REL_WHEEL, rel); 179 input_sync(input_dev); 180 } 181 } | 204 /* simulate a press-n-release */ 205 input_report_key(dev, keycode, 1); 206 input_sync(dev); 207 input_report_key(dev, keycode, 0); 208 input_sync(dev); 209 } else { 210 input_report_rel(dev, keypad->rotary_rel_code[r], delta); 211 input_sync(dev); |
182 } | 212 } |
213} |
|
183 | 214 |
215static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad) 216{ 217 struct pxa27x_keypad_platform_data *pdata = keypad->pdata; 218 uint32_t kprec; 219 220 /* read and reset to default count value */ 221 kprec = KPREC; 222 KPREC = DEFAULT_KPREC; 223 224 if (pdata->enable_rotary0) 225 report_rotary_event(keypad, 0, rotary_delta(kprec)); 226 227 if (pdata->enable_rotary1) 228 report_rotary_event(keypad, 1, rotary_delta(kprec >> 16)); 229} 230 231static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) 232{ 233 struct pxa27x_keypad_platform_data *pdata = keypad->pdata; 234 unsigned int new_state; 235 uint32_t kpdk, bits_changed; 236 int i; 237 238 kpdk = KPDK; 239 240 if (pdata->enable_rotary0 || pdata->enable_rotary1) 241 pxa27x_keypad_scan_rotary(keypad); 242 243 if (pdata->direct_key_map == NULL) 244 return; 245 246 new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; 247 bits_changed = keypad->direct_key_state ^ new_state; 248 249 if (bits_changed == 0) 250 return; 251 252 for (i = 0; i < pdata->direct_key_num; i++) { 253 if (bits_changed & (1 << i)) 254 input_report_key(keypad->input_dev, 255 pdata->direct_key_map[i], 256 (new_state & (1 << i))); 257 } 258 input_sync(keypad->input_dev); 259 keypad->direct_key_state = new_state; 260} 261 262static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) 263{ 264 struct pxa27x_keypad *keypad = dev_id; 265 unsigned long kpc = KPC; 266 267 if (kpc & KPC_DI) 268 pxa27x_keypad_scan_direct(keypad); 269 |
|
184 if (kpc & KPC_MI) 185 pxa27x_keypad_scan_matrix(keypad); 186 187 return IRQ_HANDLED; 188} 189 190static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) 191{ 192 struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 270 if (kpc & KPC_MI) 271 pxa27x_keypad_scan_matrix(keypad); 272 273 return IRQ_HANDLED; 274} 275 276static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) 277{ 278 struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
279 unsigned int mask = 0, direct_key_num = 0; |
|
193 unsigned long kpc = 0; 194 195 /* enable matrix keys with automatic scan */ 196 if (pdata->matrix_key_rows && pdata->matrix_key_cols) { 197 kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; 198 kpc |= KPC_MKRN(pdata->matrix_key_rows) | 199 KPC_MKCN(pdata->matrix_key_cols); 200 } 201 | 280 unsigned long kpc = 0; 281 282 /* enable matrix keys with automatic scan */ 283 if (pdata->matrix_key_rows && pdata->matrix_key_cols) { 284 kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; 285 kpc |= KPC_MKRN(pdata->matrix_key_rows) | 286 KPC_MKCN(pdata->matrix_key_cols); 287 } 288 |
202 /* FIXME: hardcoded to enable rotary 0 _only_ */ 203 kpc |= KPC_DKN(2) | KPC_REE0 | KPC_DI | KPC_DIE; | 289 /* enable rotary key, debounce interval same as direct keys */ 290 if (pdata->enable_rotary0) { 291 mask |= 0x03; 292 direct_key_num = 2; 293 kpc |= KPC_REE0; 294 } |
204 | 295 |
205 KPC = kpc; | 296 if (pdata->enable_rotary1) { 297 mask |= 0x0c; 298 direct_key_num = 4; 299 kpc |= KPC_REE1; 300 } 301 302 if (pdata->direct_key_num > direct_key_num) 303 direct_key_num = pdata->direct_key_num; 304 305 keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask; 306 307 /* enable direct key */ 308 if (direct_key_num) 309 kpc |= KPC_DE | KPC_DIE | KPC_DKN(direct_key_num); 310 311 KPC = kpc | KPC_RE_ZERO_DEB; |
206 KPREC = DEFAULT_KPREC; 207} 208 209static int pxa27x_keypad_open(struct input_dev *dev) 210{ 211 struct pxa27x_keypad *keypad = input_get_drvdata(dev); 212 213 /* Enable unit clock */ --- 82 unchanged lines hidden (view full) --- 296 input_dev->close = pxa27x_keypad_close; 297 input_dev->dev.parent = &pdev->dev; 298 299 keypad->input_dev = input_dev; 300 input_set_drvdata(input_dev, keypad); 301 302 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | 303 BIT_MASK(EV_REL); | 312 KPREC = DEFAULT_KPREC; 313} 314 315static int pxa27x_keypad_open(struct input_dev *dev) 316{ 317 struct pxa27x_keypad *keypad = input_get_drvdata(dev); 318 319 /* Enable unit clock */ --- 82 unchanged lines hidden (view full) --- 402 input_dev->close = pxa27x_keypad_close; 403 input_dev->dev.parent = &pdev->dev; 404 405 keypad->input_dev = input_dev; 406 input_set_drvdata(input_dev, keypad); 407 408 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | 409 BIT_MASK(EV_REL); |
304 input_dev->relbit[BIT_WORD(REL_WHEEL)] = BIT_MASK(REL_WHEEL); | |
305 306 pxa27x_keypad_build_keycode(keypad); 307 308 error = request_irq(IRQ_KEYPAD, pxa27x_keypad_irq_handler, IRQF_DISABLED, 309 DRIVER_NAME, keypad); 310 if (error) { 311 printk(KERN_ERR "Cannot request keypad IRQ\n"); 312 goto err_free_dev; --- 64 unchanged lines hidden --- | 410 411 pxa27x_keypad_build_keycode(keypad); 412 413 error = request_irq(IRQ_KEYPAD, pxa27x_keypad_irq_handler, IRQF_DISABLED, 414 DRIVER_NAME, keypad); 415 if (error) { 416 printk(KERN_ERR "Cannot request keypad IRQ\n"); 417 goto err_free_dev; --- 64 unchanged lines hidden --- |