diff options
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/pxa27x_keypad.c | 60 |
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 | |||
148 | static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) | 154 | static 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 | ||
184 | static int pxa27x_keypad_open(struct input_dev *dev) | 190 | static 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 | |||
209 | static 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) | |||
215 | static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state) | 229 | static 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 | ||
227 | static int pxa27x_keypad_resume(struct platform_device *pdev) | 237 | static 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: |