aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/pxa27x_keypad.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 8de35b0500f3..e9d4e227a009 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -37,6 +37,10 @@
37 37
38#define DRIVER_NAME "pxa27x-keypad" 38#define DRIVER_NAME "pxa27x-keypad"
39 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
40#define KPAS_MUKP(n) (((n) >> 26) & 0x1f) 44#define KPAS_MUKP(n) (((n) >> 26) & 0x1f)
41#define KPAS_RP(n) (((n) >> 4) & 0xf) 45#define KPAS_RP(n) (((n) >> 4) & 0xf)
42#define KPAS_CP(n) ((n) & 0xf) 46#define KPAS_CP(n) ((n) & 0xf)
@@ -145,6 +149,8 @@ scan:
145 memcpy(keypad->matrix_key_state, new_state, sizeof(new_state)); 149 memcpy(keypad->matrix_key_state, new_state, sizeof(new_state));
146} 150}
147 151
152#define DEFAULT_KPREC (0x007f007f)
153
148static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) 154static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
149{ 155{
150 struct pxa27x_keypad *keypad = dev_id; 156 struct pxa27x_keypad *keypad = dev_id;
@@ -181,24 +187,32 @@ static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
181 return IRQ_HANDLED; 187 return IRQ_HANDLED;
182} 188}
183 189
184static int pxa27x_keypad_open(struct input_dev *dev) 190static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
185{ 191{
186 struct pxa27x_keypad *keypad = input_get_drvdata(dev); 192 struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
193 unsigned long kpc = 0;
187 194
188 /* Set keypad control register */ 195 /* enable matrix keys with automatic scan */
189 KPC |= (KPC_ASACT | 196 if (pdata->matrix_key_rows && pdata->matrix_key_cols) {
190 KPC_MS_ALL | 197 kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL;
191 (2 << 6) | KPC_REE0 | KPC_DK_DEB_SEL | 198 kpc |= KPC_MKRN(pdata->matrix_key_rows) |
192 KPC_ME | KPC_MIE | KPC_DE | KPC_DIE); 199 KPC_MKCN(pdata->matrix_key_cols);
200 }
193 201
194 KPC &= ~KPC_AS; /* disable automatic scan */ 202 /* FIXME: hardcoded to enable rotary 0 _only_ */
195 KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */ 203 kpc |= KPC_DKN(2) | KPC_REE0 | KPC_DI | KPC_DIE;
196 204
197 /* Set rotary count to mid-point value */ 205 KPC = kpc;
198 KPREC = 0x7F; 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);
199 212
200 /* Enable unit clock */ 213 /* Enable unit clock */
201 clk_enable(keypad->clk); 214 clk_enable(keypad->clk);
215 pxa27x_keypad_config(keypad);
202 216
203 return 0; 217 return 0;
204} 218}
@@ -215,30 +229,22 @@ static void pxa27x_keypad_close(struct input_dev *dev)
215static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state) 229static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state)
216{ 230{
217 struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); 231 struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
218 struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
219
220 /* Save controller status */
221 pdata->reg_kpc = KPC;
222 pdata->reg_kprec = KPREC;
223 232
233 clk_disable(keypad->clk);
224 return 0; 234 return 0;
225} 235}
226 236
227static int pxa27x_keypad_resume(struct platform_device *pdev) 237static int pxa27x_keypad_resume(struct platform_device *pdev)
228{ 238{
229 struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); 239 struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
230 struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
231 struct input_dev *input_dev = keypad->input_dev; 240 struct input_dev *input_dev = keypad->input_dev;
232 241
233 mutex_lock(&input_dev->mutex); 242 mutex_lock(&input_dev->mutex);
234 243
235 if (input_dev->users) { 244 if (input_dev->users) {
236 /* Restore controller status */
237 KPC = pdata->reg_kpc;
238 KPREC = pdata->reg_kprec;
239
240 /* Enable unit clock */ 245 /* Enable unit clock */
241 clk_enable(keypad->clk); 246 clk_enable(keypad->clk);
247 pxa27x_keypad_config(keypad);
242 } 248 }
243 249
244 mutex_unlock(&input_dev->mutex); 250 mutex_unlock(&input_dev->mutex);
@@ -254,7 +260,7 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
254{ 260{
255 struct pxa27x_keypad *keypad; 261 struct pxa27x_keypad *keypad;
256 struct input_dev *input_dev; 262 struct input_dev *input_dev;
257 int col, error; 263 int error;
258 264
259 keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); 265 keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
260 if (keypad == NULL) { 266 if (keypad == NULL) {
@@ -313,16 +319,6 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
313 if (error) 319 if (error)
314 goto err_free_irq; 320 goto err_free_irq;
315 321
316 /*
317 * Store rows/cols info into keyboard registers.
318 */
319
320 KPC |= (keypad->pdata->matrix_key_rows - 1) << 26;
321 KPC |= (keypad->pdata->matrix_key_cols - 1) << 23;
322
323 for (col = 0; col < keypad->pdata->matrix_key_cols; col++)
324 KPC |= KPC_MS0 << col;
325
326 return 0; 322 return 0;
327 323
328 err_free_irq: 324 err_free_irq: