pxa27x_keypad.c (1814db69698479eec2c000a43c83b5f263f6fbb6) pxa27x_keypad.c (d7416f9eaa5427f47648973aac3a65e7a0eeda04)
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 *

--- 23 unchanged lines hidden (view full) ---

32
33#include <asm/arch/hardware.h>
34#include <asm/arch/pxa-regs.h>
35#include <asm/arch/irqs.h>
36#include <asm/arch/pxa27x_keypad.h>
37
38#define DRIVER_NAME "pxa27x-keypad"
39
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 *

--- 23 unchanged lines hidden (view full) ---

32
33#include <asm/arch/hardware.h>
34#include <asm/arch/pxa-regs.h>
35#include <asm/arch/irqs.h>
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
40#define KPAS_MUKP(n) (((n) >> 26) & 0x1f)
41#define KPAS_RP(n) (((n) >> 4) & 0xf)
42#define KPAS_CP(n) ((n) & 0xf)
43
44#define KPASMKP_MKC_MASK (0xff)
45
46#define MAX_MATRIX_KEY_NUM (8 * 8)
47

--- 92 unchanged lines hidden (view full) ---

140 lookup_matrix_keycode(keypad, row, col),
141 new_state[col] & (1 << row));
142 }
143 }
144 input_sync(keypad->input_dev);
145 memcpy(keypad->matrix_key_state, new_state, sizeof(new_state));
146}
147
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

--- 92 unchanged lines hidden (view full) ---

144 lookup_matrix_keycode(keypad, row, col),
145 new_state[col] & (1 << row));
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
148static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
149{
150 struct pxa27x_keypad *keypad = dev_id;
151 struct input_dev *input_dev = keypad->input_dev;
152 unsigned long kpc = KPC;
153 int rel;
154
155 if (kpc & KPC_DI) {

--- 20 unchanged lines hidden (view full) ---

176 }
177
178 if (kpc & KPC_MI)
179 pxa27x_keypad_scan_matrix(keypad);
180
181 return IRQ_HANDLED;
182}
183
154static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
155{
156 struct pxa27x_keypad *keypad = dev_id;
157 struct input_dev *input_dev = keypad->input_dev;
158 unsigned long kpc = KPC;
159 int rel;
160
161 if (kpc & KPC_DI) {

--- 20 unchanged lines hidden (view full) ---

182 }
183
184 if (kpc & KPC_MI)
185 pxa27x_keypad_scan_matrix(keypad);
186
187 return IRQ_HANDLED;
188}
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 */
189 KPC |= (KPC_ASACT |
190 KPC_MS_ALL |
191 (2 << 6) | KPC_REE0 | KPC_DK_DEB_SEL |
192 KPC_ME | KPC_MIE | KPC_DE | KPC_DIE);
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 }
193
201
194 KPC &= ~KPC_AS; /* disable automatic scan */
195 KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */
202 /* FIXME: hardcoded to enable rotary 0 _only_ */
203 kpc |= KPC_DKN(2) | KPC_REE0 | KPC_DI | KPC_DIE;
196
204
197 /* Set rotary count to mid-point value */
198 KPREC = 0x7F;
205 KPC = kpc;
206 KPREC = DEFAULT_KPREC;
207}
199
208
209static int pxa27x_keypad_open(struct input_dev *dev)
210{
211 struct pxa27x_keypad *keypad = input_get_drvdata(dev);
212
200 /* Enable unit clock */
201 clk_enable(keypad->clk);
213 /* Enable unit clock */
214 clk_enable(keypad->clk);
215 pxa27x_keypad_config(keypad);
202
203 return 0;
204}
205
206static void pxa27x_keypad_close(struct input_dev *dev)
207{
208 struct pxa27x_keypad *keypad = input_get_drvdata(dev);
209
210 /* Disable clock unit */
211 clk_disable(keypad->clk);
212}
213
214#ifdef CONFIG_PM
215static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state)
216{
217 struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
216
217 return 0;
218}
219
220static void pxa27x_keypad_close(struct input_dev *dev)
221{
222 struct pxa27x_keypad *keypad = input_get_drvdata(dev);
223
224 /* Disable clock unit */
225 clk_disable(keypad->clk);
226}
227
228#ifdef CONFIG_PM
229static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state)
230{
231 struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
218 struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
219
232
220 /* Save controller status */
221 pdata->reg_kpc = KPC;
222 pdata->reg_kprec = KPREC;
223
233 clk_disable(keypad->clk);
224 return 0;
225}
226
227static int pxa27x_keypad_resume(struct platform_device *pdev)
228{
229 struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
234 return 0;
235}
236
237static int pxa27x_keypad_resume(struct platform_device *pdev)
238{
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;
232
233 mutex_lock(&input_dev->mutex);
234
235 if (input_dev->users) {
240 struct input_dev *input_dev = keypad->input_dev;
241
242 mutex_lock(&input_dev->mutex);
243
244 if (input_dev->users) {
236 /* Restore controller status */
237 KPC = pdata->reg_kpc;
238 KPREC = pdata->reg_kprec;
239
240 /* Enable unit clock */
241 clk_enable(keypad->clk);
245 /* Enable unit clock */
246 clk_enable(keypad->clk);
247 pxa27x_keypad_config(keypad);
242 }
243
244 mutex_unlock(&input_dev->mutex);
245
246 return 0;
247}
248#else
249#define pxa27x_keypad_suspend NULL
250#define pxa27x_keypad_resume NULL
251#endif
252
253static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
254{
255 struct pxa27x_keypad *keypad;
256 struct input_dev *input_dev;
248 }
249
250 mutex_unlock(&input_dev->mutex);
251
252 return 0;
253}
254#else
255#define pxa27x_keypad_suspend NULL
256#define pxa27x_keypad_resume NULL
257#endif
258
259static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
260{
261 struct pxa27x_keypad *keypad;
262 struct input_dev *input_dev;
257 int col, error;
263 int error;
258
259 keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
260 if (keypad == NULL) {
261 dev_err(&pdev->dev, "failed to allocate driver data\n");
262 return -ENOMEM;
263 }
264
265 keypad->pdata = pdev->dev.platform_data;

--- 42 unchanged lines hidden (view full) ---

308
309 platform_set_drvdata(pdev, keypad);
310
311 /* Register the input device */
312 error = input_register_device(input_dev);
313 if (error)
314 goto err_free_irq;
315
264
265 keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
266 if (keypad == NULL) {
267 dev_err(&pdev->dev, "failed to allocate driver data\n");
268 return -ENOMEM;
269 }
270
271 keypad->pdata = pdev->dev.platform_data;

--- 42 unchanged lines hidden (view full) ---

314
315 platform_set_drvdata(pdev, keypad);
316
317 /* Register the input device */
318 error = input_register_device(input_dev);
319 if (error)
320 goto err_free_irq;
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;
327
328 err_free_irq:
329 platform_set_drvdata(pdev, NULL);
330 free_irq(IRQ_KEYPAD, pdev);
331 err_free_dev:
332 input_free_device(input_dev);
333failed_put_clk:

--- 47 unchanged lines hidden ---
322 return 0;
323
324 err_free_irq:
325 platform_set_drvdata(pdev, NULL);
326 free_irq(IRQ_KEYPAD, pdev);
327 err_free_dev:
328 input_free_device(input_dev);
329failed_put_clk:

--- 47 unchanged lines hidden ---