diff options
| -rw-r--r-- | drivers/input/keyboard/pxa27x_keypad.c | 60 | ||||
| -rw-r--r-- | include/asm-arm/arch-pxa/pxa27x_keypad.h | 5 |
2 files changed, 28 insertions, 37 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: |
diff --git a/include/asm-arm/arch-pxa/pxa27x_keypad.h b/include/asm-arm/arch-pxa/pxa27x_keypad.h index 1b1bf9fe6d81..23f4ebc4102d 100644 --- a/include/asm-arm/arch-pxa/pxa27x_keypad.h +++ b/include/asm-arm/arch-pxa/pxa27x_keypad.h | |||
| @@ -13,11 +13,6 @@ struct pxa27x_keypad_platform_data { | |||
| 13 | unsigned int matrix_key_cols; | 13 | unsigned int matrix_key_cols; |
| 14 | unsigned int *matrix_key_map; | 14 | unsigned int *matrix_key_map; |
| 15 | int matrix_key_map_size; | 15 | int matrix_key_map_size; |
| 16 | |||
| 17 | #ifdef CONFIG_PM | ||
| 18 | u32 reg_kpc; | ||
| 19 | u32 reg_kprec; | ||
| 20 | #endif | ||
| 21 | }; | 16 | }; |
| 22 | 17 | ||
| 23 | #define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val)) | 18 | #define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val)) |
