Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: w90p910_keypad - adjust to use definitions from matrix_keypad.h

Also have the driver send MSC_SCAN events as most keyboards do to aid
in updating keymap from userspace.

Tested-by: Wan ZongShun <mcuos.com@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

+64 -81
+1 -4
arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
··· 6 6 extern void mfp_set_groupi(struct device *dev); 7 7 8 8 struct w90p910_keypad_platform_data { 9 + const struct matrix_keymap_data *keymap_data; 9 10 10 11 unsigned int prescale; 11 12 unsigned int debounce; 12 - unsigned int matrix_key_rows; 13 - unsigned int matrix_key_cols; 14 - unsigned int *matrix_key_map; 15 - int matrix_key_map_size; 16 13 }; 17 14 18 15 #endif /* __ASM_ARCH_W90P910_KEYPAD_H */
+63 -77
drivers/input/keyboard/w90p910_keypad.c
··· 41 41 #define KGET_RAW(n) (((n) & KEY0R) >> 3) 42 42 #define KGET_COLUMN(n) ((n) & KEY0C) 43 43 44 - #define MAX_MATRIX_KEY_NUM (8 * 8) 44 + #define W90P910_MAX_KEY_NUM (8 * 8) 45 + #define W90P910_ROW_SHIFT 3 45 46 46 47 struct w90p910_keypad { 47 - struct w90p910_keypad_platform_data *pdata; 48 + const struct w90p910_keypad_platform_data *pdata; 48 49 struct clk *clk; 49 50 struct input_dev *input_dev; 50 51 void __iomem *mmio_base; 51 52 int irq; 52 - unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; 53 + unsigned short keymap[W90P910_MAX_KEY_NUM]; 53 54 }; 54 - 55 - static void w90p910_keypad_build_keycode(struct w90p910_keypad *keypad) 56 - { 57 - struct w90p910_keypad_platform_data *pdata = keypad->pdata; 58 - struct input_dev *input_dev = keypad->input_dev; 59 - unsigned int *key; 60 - int i; 61 - 62 - key = &pdata->matrix_key_map[0]; 63 - for (i = 0; i < pdata->matrix_key_map_size; i++, key++) { 64 - int row = KEY_ROW(*key); 65 - int col = KEY_COL(*key); 66 - int code = KEY_VAL(*key); 67 - 68 - keypad->matrix_keycodes[(row << 3) + col] = code; 69 - __set_bit(code, input_dev->keybit); 70 - } 71 - } 72 - 73 - static inline unsigned int lookup_matrix_keycode( 74 - struct w90p910_keypad *keypad, int row, int col) 75 - { 76 - return keypad->matrix_keycodes[(row << 3) + col]; 77 - } 78 55 79 56 static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, 80 57 unsigned int status) 81 58 { 82 - unsigned int row, col, val; 59 + struct input_dev *input_dev = keypad->input_dev; 60 + unsigned int row = KGET_RAW(status); 61 + unsigned int col = KGET_COLUMN(status); 62 + unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT); 63 + unsigned int key = keypad->keymap[code]; 83 64 84 - row = KGET_RAW(status); 85 - col = KGET_COLUMN(status); 65 + input_event(input_dev, EV_MSC, MSC_SCAN, code); 66 + input_report_key(input_dev, key, 1); 67 + input_sync(input_dev); 86 68 87 - val = lookup_matrix_keycode(keypad, row, col); 88 - 89 - input_report_key(keypad->input_dev, val, 1); 90 - 91 - input_sync(keypad->input_dev); 92 - 93 - input_report_key(keypad->input_dev, val, 0); 94 - 95 - input_sync(keypad->input_dev); 69 + input_event(input_dev, EV_MSC, MSC_SCAN, code); 70 + input_report_key(input_dev, key, 0); 71 + input_sync(input_dev); 96 72 } 97 73 98 74 static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id) ··· 89 113 static int w90p910_keypad_open(struct input_dev *dev) 90 114 { 91 115 struct w90p910_keypad *keypad = input_get_drvdata(dev); 92 - struct w90p910_keypad_platform_data *pdata = keypad->pdata; 116 + const struct w90p910_keypad_platform_data *pdata = keypad->pdata; 93 117 unsigned int val, config; 94 118 95 119 /* Enable unit clock */ ··· 118 142 119 143 static int __devinit w90p910_keypad_probe(struct platform_device *pdev) 120 144 { 145 + const struct w90p910_keypad_platform_data *pdata = 146 + pdev->dev.platform_data; 147 + const struct matrix_keymap_data *keymap_data = pdata->keymap_data; 121 148 struct w90p910_keypad *keypad; 122 149 struct input_dev *input_dev; 123 150 struct resource *res; 124 - int irq, error; 151 + int irq; 152 + int error; 153 + int i; 125 154 126 - keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL); 127 - if (keypad == NULL) { 128 - dev_err(&pdev->dev, "failed to allocate driver data\n"); 129 - return -ENOMEM; 130 - } 131 - 132 - keypad->pdata = pdev->dev.platform_data; 133 - if (keypad->pdata == NULL) { 155 + if (!pdata) { 134 156 dev_err(&pdev->dev, "no platform data defined\n"); 135 - error = -EINVAL; 136 - goto failed_free; 157 + return -EINVAL; 137 158 } 138 159 139 160 irq = platform_get_irq(pdev, 0); 140 161 if (irq < 0) { 141 162 dev_err(&pdev->dev, "failed to get keypad irq\n"); 142 - error = -ENXIO; 163 + return -ENXIO; 164 + } 165 + 166 + keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL); 167 + input_dev = input_allocate_device(); 168 + if (!keypad || !input_dev) { 169 + dev_err(&pdev->dev, "failed to allocate driver data\n"); 170 + error = -ENOMEM; 143 171 goto failed_free; 144 172 } 173 + 174 + keypad->pdata = pdata; 175 + keypad->input_dev = input_dev; 176 + keypad->irq = irq; 145 177 146 178 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 147 179 if (res == NULL) { ··· 169 185 if (keypad->mmio_base == NULL) { 170 186 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 171 187 error = -ENXIO; 172 - goto failed_free_mem; 188 + goto failed_free_res; 173 189 } 174 190 175 191 keypad->clk = clk_get(&pdev->dev, NULL); ··· 177 193 dev_err(&pdev->dev, "failed to get keypad clock\n"); 178 194 error = PTR_ERR(keypad->clk); 179 195 goto failed_free_io; 180 - } 181 - 182 - /* Create and register the input driver. */ 183 - input_dev = input_allocate_device(); 184 - if (!input_dev) { 185 - dev_err(&pdev->dev, "failed to allocate input device\n"); 186 - error = -ENOMEM; 187 - goto failed_put_clk; 188 196 } 189 197 190 198 /* set multi-function pin for w90p910 kpi. */ ··· 187 211 input_dev->open = w90p910_keypad_open; 188 212 input_dev->close = w90p910_keypad_close; 189 213 input_dev->dev.parent = &pdev->dev; 190 - input_dev->keycode = keypad->matrix_keycodes; 191 - input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); 192 - input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); 193 214 194 - keypad->input_dev = input_dev; 215 + input_dev->keycode = keypad->keymap; 216 + input_dev->keycodesize = sizeof(keypad->keymap[0]); 217 + input_dev->keycodemax = ARRAY_SIZE(keypad->keymap); 218 + 195 219 input_set_drvdata(input_dev, keypad); 196 220 197 221 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); 198 - w90p910_keypad_build_keycode(keypad); 199 - platform_set_drvdata(pdev, keypad); 222 + input_set_capability(input_dev, EV_MSC, MSC_SCAN); 200 223 201 - error = request_irq(irq, w90p910_keypad_irq_handler, IRQF_DISABLED, 202 - pdev->name, keypad); 224 + for (i = 0; i < keymap_data->keymap_size; i++) { 225 + unsigned int key = keymap_data->keymap[i]; 226 + unsigned int row = KEY_ROW(key); 227 + unsigned int col = KEY_COL(key); 228 + unsigned short keycode = KEY_VAL(key); 229 + unsigned int scancode = MATRIX_SCAN_CODE(row, col, 230 + W90P910_ROW_SHIFT); 231 + 232 + keypad->keymap[scancode] = keycode; 233 + __set_bit(keycode, input_dev->keybit); 234 + } 235 + __clear_bit(KEY_RESERVED, input_dev->keybit); 236 + 237 + 238 + error = request_irq(keypad->irq, w90p910_keypad_irq_handler, 239 + IRQF_DISABLED, pdev->name, keypad); 203 240 if (error) { 204 241 dev_err(&pdev->dev, "failed to request IRQ\n"); 205 - goto failed_free_dev; 242 + goto failed_put_clk; 206 243 } 207 - 208 - keypad->irq = irq; 209 244 210 245 /* Register the input device */ 211 246 error = input_register_device(input_dev); ··· 225 238 goto failed_free_irq; 226 239 } 227 240 241 + platform_set_drvdata(pdev, keypad); 228 242 return 0; 229 243 230 244 failed_free_irq: 231 245 free_irq(irq, pdev); 232 - platform_set_drvdata(pdev, NULL); 233 - failed_free_dev: 234 - input_free_device(input_dev); 235 246 failed_put_clk: 236 247 clk_put(keypad->clk); 237 248 failed_free_io: 238 249 iounmap(keypad->mmio_base); 239 - failed_free_mem: 250 + failed_free_res: 240 251 release_mem_region(res->start, resource_size(res)); 241 252 failed_free: 253 + input_free_device(input_dev); 242 254 kfree(keypad); 243 255 return error; 244 256 } ··· 254 268 input_unregister_device(keypad->input_dev); 255 269 256 270 iounmap(keypad->mmio_base); 257 - 258 271 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 259 272 release_mem_region(res->start, resource_size(res)); 260 273 261 274 platform_set_drvdata(pdev, NULL); 262 275 kfree(keypad); 276 + 263 277 return 0; 264 278 } 265 279