diff options
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/corgikbd.c | 61 |
1 files changed, 28 insertions, 33 deletions
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 43d6edb3cf09..767e853dd766 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -33,7 +33,6 @@ | |||
33 | /* zero code, 124 scancodes + 3 hinge combinations */ | 33 | /* zero code, 124 scancodes + 3 hinge combinations */ |
34 | #define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 +3 ) | 34 | #define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 +3 ) |
35 | #define SCAN_INTERVAL (HZ/10) | 35 | #define SCAN_INTERVAL (HZ/10) |
36 | #define CORGIKBD_PRESSED 1 | ||
37 | 36 | ||
38 | #define HINGE_SCAN_INTERVAL (HZ/4) | 37 | #define HINGE_SCAN_INTERVAL (HZ/4) |
39 | 38 | ||
@@ -74,9 +73,7 @@ struct corgikbd { | |||
74 | struct input_dev input; | 73 | struct input_dev input; |
75 | char phys[32]; | 74 | char phys[32]; |
76 | 75 | ||
77 | unsigned char state[ARRAY_SIZE(corgikbd_keycode)]; | ||
78 | spinlock_t lock; | 76 | spinlock_t lock; |
79 | |||
80 | struct timer_list timer; | 77 | struct timer_list timer; |
81 | struct timer_list htimer; | 78 | struct timer_list htimer; |
82 | 79 | ||
@@ -84,22 +81,6 @@ struct corgikbd { | |||
84 | unsigned long suspend_jiffies; | 81 | unsigned long suspend_jiffies; |
85 | }; | 82 | }; |
86 | 83 | ||
87 | static void handle_scancode(unsigned int pressed,unsigned int scancode, struct corgikbd *corgikbd_data) | ||
88 | { | ||
89 | if (pressed && !(corgikbd_data->state[scancode] & CORGIKBD_PRESSED)) { | ||
90 | corgikbd_data->state[scancode] |= CORGIKBD_PRESSED; | ||
91 | input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 1); | ||
92 | if ((corgikbd_data->keycode[scancode] == CORGI_KEY_OFF) | ||
93 | && time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) { | ||
94 | input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1); | ||
95 | corgikbd_data->suspend_jiffies=jiffies; | ||
96 | } | ||
97 | } else if (!pressed && corgikbd_data->state[scancode] & CORGIKBD_PRESSED) { | ||
98 | corgikbd_data->state[scancode] &= ~CORGIKBD_PRESSED; | ||
99 | input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 0); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | #define KB_DISCHARGE_DELAY 10 | 84 | #define KB_DISCHARGE_DELAY 10 |
104 | #define KB_ACTIVATE_DELAY 10 | 85 | #define KB_ACTIVATE_DELAY 10 |
105 | 86 | ||
@@ -112,36 +93,36 @@ static void handle_scancode(unsigned int pressed,unsigned int scancode, struct c | |||
112 | */ | 93 | */ |
113 | static inline void corgikbd_discharge_all(void) | 94 | static inline void corgikbd_discharge_all(void) |
114 | { | 95 | { |
115 | // STROBE All HiZ | 96 | /* STROBE All HiZ */ |
116 | GPCR2 = CORGI_GPIO_ALL_STROBE_BIT; | 97 | GPCR2 = CORGI_GPIO_ALL_STROBE_BIT; |
117 | GPDR2 &= ~CORGI_GPIO_ALL_STROBE_BIT; | 98 | GPDR2 &= ~CORGI_GPIO_ALL_STROBE_BIT; |
118 | } | 99 | } |
119 | 100 | ||
120 | static inline void corgikbd_activate_all(void) | 101 | static inline void corgikbd_activate_all(void) |
121 | { | 102 | { |
122 | // STROBE ALL -> High | 103 | /* STROBE ALL -> High */ |
123 | GPSR2 = CORGI_GPIO_ALL_STROBE_BIT; | 104 | GPSR2 = CORGI_GPIO_ALL_STROBE_BIT; |
124 | GPDR2 |= CORGI_GPIO_ALL_STROBE_BIT; | 105 | GPDR2 |= CORGI_GPIO_ALL_STROBE_BIT; |
125 | 106 | ||
126 | udelay(KB_DISCHARGE_DELAY); | 107 | udelay(KB_DISCHARGE_DELAY); |
127 | 108 | ||
128 | // Clear any interrupts we may have triggered when altering the GPIO lines | 109 | /* Clear any interrupts we may have triggered when altering the GPIO lines */ |
129 | GEDR1 = CORGI_GPIO_HIGH_SENSE_BIT; | 110 | GEDR1 = CORGI_GPIO_HIGH_SENSE_BIT; |
130 | GEDR2 = CORGI_GPIO_LOW_SENSE_BIT; | 111 | GEDR2 = CORGI_GPIO_LOW_SENSE_BIT; |
131 | } | 112 | } |
132 | 113 | ||
133 | static inline void corgikbd_activate_col(int col) | 114 | static inline void corgikbd_activate_col(int col) |
134 | { | 115 | { |
135 | // STROBE col -> High, not col -> HiZ | 116 | /* STROBE col -> High, not col -> HiZ */ |
136 | GPSR2 = CORGI_GPIO_STROBE_BIT(col); | 117 | GPSR2 = CORGI_GPIO_STROBE_BIT(col); |
137 | GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col); | 118 | GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col); |
138 | } | 119 | } |
139 | 120 | ||
140 | static inline void corgikbd_reset_col(int col) | 121 | static inline void corgikbd_reset_col(int col) |
141 | { | 122 | { |
142 | // STROBE col -> Low | 123 | /* STROBE col -> Low */ |
143 | GPCR2 = CORGI_GPIO_STROBE_BIT(col); | 124 | GPCR2 = CORGI_GPIO_STROBE_BIT(col); |
144 | // STROBE col -> out, not col -> HiZ | 125 | /* STROBE col -> out, not col -> HiZ */ |
145 | GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col); | 126 | GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col); |
146 | } | 127 | } |
147 | 128 | ||
@@ -156,7 +137,7 @@ static inline void corgikbd_reset_col(int col) | |||
156 | /* Scan the hardware keyboard and push any changes up through the input layer */ | 137 | /* Scan the hardware keyboard and push any changes up through the input layer */ |
157 | static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs *regs) | 138 | static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs *regs) |
158 | { | 139 | { |
159 | unsigned int row, col, rowd, scancode; | 140 | unsigned int row, col, rowd; |
160 | unsigned long flags; | 141 | unsigned long flags; |
161 | unsigned int num_pressed; | 142 | unsigned int num_pressed; |
162 | 143 | ||
@@ -183,10 +164,21 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs | |||
183 | 164 | ||
184 | rowd = GET_ROWS_STATUS(col); | 165 | rowd = GET_ROWS_STATUS(col); |
185 | for (row = 0; row < KB_ROWS; row++) { | 166 | for (row = 0; row < KB_ROWS; row++) { |
167 | unsigned int scancode, pressed; | ||
168 | |||
186 | scancode = SCANCODE(row, col); | 169 | scancode = SCANCODE(row, col); |
187 | handle_scancode((rowd & KB_ROWMASK(row)), scancode, corgikbd_data); | 170 | pressed = rowd & KB_ROWMASK(row); |
188 | if (rowd & KB_ROWMASK(row)) | 171 | |
172 | input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], pressed); | ||
173 | |||
174 | if (pressed) | ||
189 | num_pressed++; | 175 | num_pressed++; |
176 | |||
177 | if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF) | ||
178 | && time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) { | ||
179 | input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1); | ||
180 | corgikbd_data->suspend_jiffies=jiffies; | ||
181 | } | ||
190 | } | 182 | } |
191 | corgikbd_reset_col(col); | 183 | corgikbd_reset_col(col); |
192 | } | 184 | } |
@@ -231,8 +223,11 @@ static void corgikbd_timer_callback(unsigned long data) | |||
231 | * The hinge switches generate no interrupt so they need to be | 223 | * The hinge switches generate no interrupt so they need to be |
232 | * monitored by a timer. | 224 | * monitored by a timer. |
233 | * | 225 | * |
234 | * When we detect changes, we debounce it and then pass the three | 226 | * We debounce the switches and pass them to the input system. |
235 | * positions the system can take as keypresses to the input system. | 227 | * |
228 | * gprr == 0x00 - Keyboard with Landscape Screen | ||
229 | * 0x08 - No Keyboard with Portrait Screen | ||
230 | * 0x0c - Keyboard and Screen Closed | ||
236 | */ | 231 | */ |
237 | 232 | ||
238 | #define HINGE_STABLE_COUNT 2 | 233 | #define HINGE_STABLE_COUNT 2 |
@@ -254,9 +249,9 @@ static void corgikbd_hinge_timer(unsigned long data) | |||
254 | if (hinge_count >= HINGE_STABLE_COUNT) { | 249 | if (hinge_count >= HINGE_STABLE_COUNT) { |
255 | spin_lock_irqsave(&corgikbd_data->lock, flags); | 250 | spin_lock_irqsave(&corgikbd_data->lock, flags); |
256 | 251 | ||
257 | handle_scancode((sharpsl_hinge_state == 0x00), 125, corgikbd_data); /* Keyboard with Landscape Screen */ | 252 | input_report_key(&corgikbd_data->input, corgikbd_data->keycode[125], (sharpsl_hinge_state == 0x00)); |
258 | handle_scancode((sharpsl_hinge_state == 0x08), 126, corgikbd_data); /* No Keyboard with Portrait Screen */ | 253 | input_report_key(&corgikbd_data->input, corgikbd_data->keycode[126], (sharpsl_hinge_state == 0x08)); |
259 | handle_scancode((sharpsl_hinge_state == 0x0c), 127, corgikbd_data); /* Keyboard and Screen Closed */ | 254 | input_report_key(&corgikbd_data->input, corgikbd_data->keycode[127], (sharpsl_hinge_state == 0x0c)); |
260 | input_sync(&corgikbd_data->input); | 255 | input_sync(&corgikbd_data->input); |
261 | 256 | ||
262 | spin_unlock_irqrestore(&corgikbd_data->lock, flags); | 257 | spin_unlock_irqrestore(&corgikbd_data->lock, flags); |