Changeset c637571 in mainline
- Timestamp:
- 2011-12-31T15:05:32Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c322fd6
- Parents:
- db9ef0c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/ps2mouse/ps2mouse.c
rdb9ef0c rc637571 45 45 #include "ps2mouse.h" 46 46 47 #define PS2_MOUSE_OUT_INIT 0xf4 48 #define PS2_MOUSE_ACK 0xfa 49 50 #define BUFSIZE 3 51 47 #define PS2_MOUSE_GET_DEVICE_ID 0xf2 48 #define PS2_MOUSE_SET_SAMPLE_RATE 0xf3 49 #define PS2_MOUSE_ENABLE_DATA_REPORT 0xf4 50 #define PS2_MOUSE_ACK 0xfa 51 52 #define PS2_BUFSIZE 3 53 #define INTELLIMOUSE_BUFSIZE 4 54 55 #define Z_SIGN (1 << 3) 52 56 #define X_SIGN (1 << 4) 53 57 #define Y_SIGN (1 << 5) … … 58 62 #define BUTTON_RIGHT 1 59 63 #define BUTTON_MIDDLE 2 60 #define BUTTON_COUNT 3 61 62 #define BUTTON_MASK(button) (1 << button) 63 64 #define PS2_BUTTON_COUNT 3 65 #define INTELLIMOUSE_BUTTON_COUNT 5 66 67 #define PS2_BUTTON_MASK(button) (1 << button) 68 69 #define MOUSE_READ_BYTE_TEST(sess, value) \ 70 do { \ 71 uint8_t data = 0; \ 72 const ssize_t size = char_dev_read(session, &data, 1); \ 73 if (size != 1) { \ 74 ddf_msg(LVL_ERROR, "Failed reading byte: %d)", size);\ 75 return size < 0 ? size : EIO; \ 76 } \ 77 if (data != value) { \ 78 ddf_msg(LVL_ERROR, "Failed testing byte: got %hhx vs. %hhx)", \ 79 data, value); \ 80 return EIO; \ 81 } \ 82 } while (0) 83 #define MOUSE_WRITE_BYTE(sess, value) \ 84 do { \ 85 uint8_t data = value; \ 86 const ssize_t size = char_dev_write(session, &data, 1); \ 87 if (size < 0 ) { \ 88 ddf_msg(LVL_ERROR, "Failed writing byte: %hhx", value); \ 89 return size; \ 90 } \ 91 } while (0) 64 92 /*----------------------------------------------------------------------------*/ 65 93 static int polling_ps2(void *); 94 static int polling_intellimouse(void *); 95 static int probe_intellimouse(async_sess_t *); 66 96 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 67 97 /*----------------------------------------------------------------------------*/ … … 111 141 return ENOMEM; 112 142 } 143 /* Probe IntelliMouse extensions. */ 144 int (*polling_f)(void*) = polling_ps2; 145 if (probe_intellimouse(mouse->parent_sess) == EOK) { 146 ddf_msg(LVL_NOTE, "Enabled IntelliMouse extensions"); 147 polling_f = polling_intellimouse; 148 } 113 149 /* Enable mouse data reporting. */ 114 uint8_t report = PS2_MOUSE_ OUT_INIT;150 uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT; 115 151 ssize_t size = char_dev_write(mouse->parent_sess, &report, 1); 116 152 if (size != 1) { 117 ddf_msg(LVL_ERROR, "Failed to write INIT.");153 ddf_msg(LVL_ERROR, "Failed to enable data reporting."); 118 154 async_hangup(mouse->parent_sess); 119 155 ddf_fun_unbind(mouse->mouse_fun); … … 125 161 size = char_dev_read(mouse->parent_sess, &report, 1); 126 162 if (size != 1 || report != PS2_MOUSE_ACK) { 127 ddf_msg(LVL_ERROR, "MOUSE FAILED TO ACK %hhx.", report); 163 ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.", 164 report); 128 165 async_hangup(mouse->parent_sess); 129 166 ddf_fun_unbind(mouse->mouse_fun); … … 133 170 } 134 171 135 mouse->polling_fibril = fibril_create(polling_ ps2, mouse);172 mouse->polling_fibril = fibril_create(polling_f, mouse); 136 173 if (!mouse->polling_fibril) { 137 174 async_hangup(mouse->parent_sess); … … 155 192 156 193 assert(mouse->parent_sess); 157 bool buttons[ BUTTON_COUNT] = {};194 bool buttons[PS2_BUTTON_COUNT] = {}; 158 195 while (1) { 159 196 160 uint8_t packet[ BUFSIZE] = {};197 uint8_t packet[PS2_BUFSIZE] = {}; 161 198 const ssize_t size = 162 char_dev_read(mouse->parent_sess, packet, BUFSIZE);163 164 if (size != 3) {199 char_dev_read(mouse->parent_sess, packet, PS2_BUFSIZE); 200 201 if (size != PS2_BUFSIZE) { 165 202 ddf_msg(LVL_WARN, "Incorrect packet size: %zd.", size); 166 203 continue; … … 178 215 179 216 /* Buttons */ 180 for (unsigned i = 0; i < BUTTON_COUNT; ++i) { 181 if (buttons[i] != (bool)(packet[0] & BUTTON_MASK(i))) { 182 buttons[i] = !buttons[i]; 217 for (unsigned i = 0; i < PS2_BUTTON_COUNT; ++i) { 218 const bool status = (packet[0] & PS2_BUTTON_MASK(i)); 219 if (buttons[i] != status) { 220 buttons[i] = status; 183 221 async_msg_2(exch, MOUSEEV_BUTTON_EVENT, i + 1, 184 222 buttons[i]); … … 197 235 async_exchange_end(exch); 198 236 } 237 } 238 /*----------------------------------------------------------------------------*/ 239 /** Get data and parse ps2 protocol with intellimouse extension packets. 240 * @param arg Pointer to ps2_mouse_t structure. 241 * @return Never. 242 */ 243 static int polling_intellimouse(void *arg) 244 { 245 assert(arg); 246 const ps2_mouse_t *mouse = arg; 247 248 assert(mouse->parent_sess); 249 bool buttons[INTELLIMOUSE_BUTTON_COUNT] = {}; 250 while (1) { 251 252 uint8_t packet[INTELLIMOUSE_BUFSIZE] = {}; 253 const ssize_t size = char_dev_read( 254 mouse->parent_sess, packet, INTELLIMOUSE_BUFSIZE); 255 256 if (size != INTELLIMOUSE_BUFSIZE) { 257 ddf_msg(LVL_WARN, "Incorrect packet size: %zd.", size); 258 continue; 259 } 260 ddf_msg(LVL_DEBUG2, "Got packet: %hhx:%hhx:%hhx:%hhx.", 261 packet[0], packet[1], packet[2], packet[3]); 262 263 async_exch_t *exch = 264 async_exchange_begin(mouse->input_sess); 265 if (!exch) { 266 ddf_msg(LVL_ERROR, 267 "Failed to create input exchange."); 268 continue; 269 } 270 /* ps/2 Buttons */ 271 for (unsigned i = 0; i < PS2_BUTTON_COUNT; ++i) { 272 const bool status = (packet[0] & PS2_BUTTON_MASK(i)); 273 if (buttons[i] != status) { 274 buttons[i] = status; 275 async_msg_2(exch, MOUSEEV_BUTTON_EVENT, i + 1, 276 buttons[i]); 277 } 278 } 279 280 /* Movement */ 281 const int16_t move_x = 282 ((packet[0] & X_SIGN) ? 0xff00 : 0) | packet[1]; 283 const int16_t move_y = 284 (((packet[0] & Y_SIGN) ? 0xff00 : 0) | packet[2]); 285 const int8_t move_z = 286 (((packet[3] & Z_SIGN) ? 0xf0 : 0) | (packet[3] & 0xf)); 287 ddf_msg(LVL_DEBUG2, "Parsed moves: %d:%d:%hhd", move_x, move_y, 288 move_z); 289 //TODO: Consider overflow bit 290 if (move_x != 0 || move_y != 0 || move_z != 0) { 291 async_msg_3(exch, MOUSEEV_MOVE_EVENT, 292 move_x, -move_y, -move_z); 293 } 294 async_exchange_end(exch); 295 } 296 } 297 /*----------------------------------------------------------------------------*/ 298 static int probe_intellimouse(async_sess_t *session) 299 { 300 assert(session); 301 302 MOUSE_WRITE_BYTE(session, PS2_MOUSE_SET_SAMPLE_RATE); 303 MOUSE_READ_BYTE_TEST(session, PS2_MOUSE_ACK); 304 MOUSE_WRITE_BYTE(session, 200); 305 MOUSE_READ_BYTE_TEST(session, PS2_MOUSE_ACK); 306 307 MOUSE_WRITE_BYTE(session, PS2_MOUSE_SET_SAMPLE_RATE); 308 MOUSE_READ_BYTE_TEST(session, PS2_MOUSE_ACK); 309 MOUSE_WRITE_BYTE(session, 100); 310 MOUSE_READ_BYTE_TEST(session, PS2_MOUSE_ACK); 311 312 MOUSE_WRITE_BYTE(session, PS2_MOUSE_SET_SAMPLE_RATE); 313 MOUSE_READ_BYTE_TEST(session, PS2_MOUSE_ACK); 314 MOUSE_WRITE_BYTE(session, 80); 315 MOUSE_READ_BYTE_TEST(session, PS2_MOUSE_ACK); 316 317 MOUSE_WRITE_BYTE(session, PS2_MOUSE_GET_DEVICE_ID); 318 MOUSE_READ_BYTE_TEST(session, PS2_MOUSE_ACK); 319 MOUSE_READ_BYTE_TEST(session, 3); 320 321 return EOK; 199 322 } 200 323 /*----------------------------------------------------------------------------*/
Note:
See TracChangeset
for help on using the changeset viewer.