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 --- |