Changeset 15c5418 in mainline for uspace/drv/hid/ps2mouse/ps2mouse.c
- Timestamp:
- 2017-11-18T20:06:15Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 75fcf9b
- Parents:
- efb9fd08
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/hid/ps2mouse/ps2mouse.c
refb9fd08 r15c5418 1 1 /* 2 2 * Copyright (c) 2011 Jan Vesely 3 * Copyright (c) 2017 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 30 31 */ 31 32 /** @file 32 * @brief ps2 mouse driver.33 * @brief PS/2 mouse driver. 33 34 */ 34 35 … … 70 71 #define PS2_BUTTON_MASK(button) (1 << button) 71 72 72 #define MOUSE_READ_BYTE_TEST( sess, value_) \73 #define MOUSE_READ_BYTE_TEST(mouse, value_) \ 73 74 do { \ 74 75 uint8_t value = (value_); \ 75 76 uint8_t data = 0; \ 76 const ssize_t size = chardev_read( sess, &data, 1); \77 const ssize_t size = chardev_read((mouse)->chardev, &data, 1); \ 77 78 if (size != 1) { \ 78 79 ddf_msg(LVL_ERROR, "Failed reading byte: %zd)", size);\ … … 86 87 } while (0) 87 88 88 #define MOUSE_WRITE_BYTE( sess, value_) \89 #define MOUSE_WRITE_BYTE(mouse, value_) \ 89 90 do { \ 90 91 uint8_t value = (value_); \ 91 92 uint8_t data = (value); \ 92 const ssize_t size = chardev_write( sess, &data, 1); \93 const ssize_t size = chardev_write((mouse)->chardev, &data, 1); \ 93 94 if (size < 0 ) { \ 94 95 ddf_msg(LVL_ERROR, "Failed writing byte: %hhx", value); \ … … 99 100 static int polling_ps2(void *); 100 101 static int polling_intellimouse(void *); 101 static int probe_intellimouse( async_exch_t *, bool);102 static int probe_intellimouse(ps2_mouse_t *, bool); 102 103 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 103 104 … … 108 109 109 110 /** Initialize mouse driver structure. 111 * 112 * Connects to parent, creates keyboard function, starts polling fibril. 113 * 110 114 * @param kbd Mouse driver structure to initialize. 111 115 * @param dev DDF device structure. 112 116 * 113 * Connects to parent, creates keyboard function, starts polling fibril.117 * @return EOK on success or non-zero error code 114 118 */ 115 119 int ps2_mouse_init(ps2_mouse_t *mouse, ddf_dev_t *dev) 116 120 { 121 async_sess_t *parent_sess; 122 bool bound = false; 123 int rc; 124 117 125 mouse->client_sess = NULL; 118 mouse->parent_sess = ddf_dev_parent_sess_get(dev); 119 if (!mouse->parent_sess) 120 return ENOMEM; 126 127 parent_sess = ddf_dev_parent_sess_get(dev); 128 if (parent_sess == NULL) { 129 ddf_msg(LVL_ERROR, "Failed getting parent session."); 130 rc = ENOMEM; 131 goto error; 132 } 133 134 rc = chardev_open(parent_sess, &mouse->chardev); 135 if (rc != EOK) { 136 ddf_msg(LVL_ERROR, "Failed opening character device."); 137 goto error; 138 } 121 139 122 140 mouse->mouse_fun = ddf_fun_create(dev, fun_exposed, "mouse"); 123 if (!mouse->mouse_fun) { 124 return ENOMEM; 125 } 141 if (mouse->mouse_fun == NULL) { 142 ddf_msg(LVL_ERROR, "Error creating mouse function."); 143 rc = ENOMEM; 144 goto error; 145 } 146 126 147 ddf_fun_set_ops(mouse->mouse_fun, &mouse_ops); 127 148 128 int ret = ddf_fun_bind(mouse->mouse_fun); 129 if (ret != EOK) { 130 ddf_fun_destroy(mouse->mouse_fun); 131 return ENOMEM; 132 } 133 134 ret = ddf_fun_add_to_category(mouse->mouse_fun, "mouse"); 135 if (ret != EOK) { 136 ddf_fun_unbind(mouse->mouse_fun); 137 ddf_fun_destroy(mouse->mouse_fun); 138 return ENOMEM; 139 } 149 rc = ddf_fun_bind(mouse->mouse_fun); 150 if (rc != EOK) { 151 ddf_msg(LVL_ERROR, "Failed binding mouse function."); 152 goto error; 153 } 154 155 bound = true; 156 157 rc = ddf_fun_add_to_category(mouse->mouse_fun, "mouse"); 158 if (rc != EOK) { 159 ddf_msg(LVL_ERROR, "Failed adding mouse function to category."); 160 goto error; 161 } 162 140 163 /* Probe IntelliMouse extensions. */ 141 164 int (*polling_f)(void*) = polling_ps2; 142 async_exch_t *exch = async_exchange_begin(mouse->parent_sess); 143 if (probe_intellimouse(exch, false) == EOK) { 165 if (probe_intellimouse(mouse, false) == EOK) { 144 166 ddf_msg(LVL_NOTE, "Enabled IntelliMouse extensions"); 145 167 polling_f = polling_intellimouse; 146 if (probe_intellimouse( exch, true) == EOK)168 if (probe_intellimouse(mouse, true) == EOK) 147 169 ddf_msg(LVL_NOTE, "Enabled 4th and 5th button."); 148 170 } 171 149 172 /* Enable mouse data reporting. */ 150 173 uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT; 151 ssize_t size = chardev_write( exch, &report, 1);174 ssize_t size = chardev_write(mouse->chardev, &report, 1); 152 175 if (size != 1) { 153 176 ddf_msg(LVL_ERROR, "Failed to enable data reporting."); 154 async_exchange_end(exch); 155 ddf_fun_unbind(mouse->mouse_fun); 156 ddf_fun_destroy(mouse->mouse_fun); 157 return EIO; 158 } 159 160 size = chardev_read(exch, &report, 1); 161 async_exchange_end(exch); 177 rc = EIO; 178 goto error; 179 } 180 181 size = chardev_read(mouse->chardev, &report, 1); 162 182 if (size != 1 || report != PS2_MOUSE_ACK) { 163 183 ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.", 164 184 report); 165 ddf_fun_unbind(mouse->mouse_fun); 166 ddf_fun_destroy(mouse->mouse_fun); 167 return EIO; 185 rc = EIO; 186 goto error; 168 187 } 169 188 170 189 mouse->polling_fibril = fibril_create(polling_f, mouse); 171 if ( !mouse->polling_fibril) {172 ddf_fun_unbind(mouse->mouse_fun);173 ddf_fun_destroy(mouse->mouse_fun);174 return ENOMEM;175 } 190 if (mouse->polling_fibril == 0) { 191 rc = ENOMEM; 192 goto error; 193 } 194 176 195 fibril_add_ready(mouse->polling_fibril); 177 196 return EOK; 197 error: 198 if (bound) 199 ddf_fun_unbind(mouse->mouse_fun); 200 if (mouse->mouse_fun != NULL) { 201 ddf_fun_destroy(mouse->mouse_fun); 202 mouse->mouse_fun = NULL; 203 } 204 205 chardev_close(mouse->chardev); 206 mouse->chardev = NULL; 207 return rc; 178 208 } 179 209 … … 184 214 int polling_ps2(void *arg) 185 215 { 186 assert(arg); 187 const ps2_mouse_t *mouse = arg; 188 189 assert(mouse->parent_sess); 216 ps2_mouse_t *mouse = (ps2_mouse_t *) arg; 217 190 218 bool buttons[PS2_BUTTON_COUNT] = {}; 191 async_exch_t *parent_exch = async_exchange_begin(mouse->parent_sess);192 219 while (1) { 193 194 220 uint8_t packet[PS2_BUFSIZE] = {}; 195 221 const ssize_t size = 196 chardev_read( parent_exch, packet, PS2_BUFSIZE);222 chardev_read(mouse->chardev, packet, PS2_BUFSIZE); 197 223 198 224 if (size != PS2_BUFSIZE) { … … 232 258 async_exchange_end(exch); 233 259 } 234 async_exchange_end(parent_exch); 260 261 return 0; 235 262 } 236 263 … … 241 268 static int polling_intellimouse(void *arg) 242 269 { 243 assert(arg); 244 const ps2_mouse_t *mouse = arg; 245 246 assert(mouse->parent_sess); 270 ps2_mouse_t *mouse = (ps2_mouse_t *) arg; 271 247 272 bool buttons[INTELLIMOUSE_BUTTON_COUNT] = {}; 248 async_exch_t *parent_exch = NULL;249 273 while (1) { 250 if (!parent_exch)251 parent_exch = async_exchange_begin(mouse->parent_sess);252 253 274 uint8_t packet[INTELLIMOUSE_BUFSIZE] = {}; 254 275 const ssize_t size = chardev_read( 255 parent_exch, packet, INTELLIMOUSE_BUFSIZE);276 mouse->chardev, packet, INTELLIMOUSE_BUFSIZE); 256 277 257 278 if (size != INTELLIMOUSE_BUFSIZE) { … … 310 331 async_exchange_end(exch); 311 332 } 312 async_exchange_end(parent_exch); 333 334 return 0; 313 335 } 314 336 … … 319 341 * See http://www.computer-engineering.org/ps2mouse/ for details. 320 342 */ 321 static int probe_intellimouse( async_exch_t *exch, bool buttons)343 static int probe_intellimouse(ps2_mouse_t *mouse, bool buttons) 322 344 { 323 assert(exch); 324 325 MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE); 326 MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK); 327 MOUSE_WRITE_BYTE(exch, 200); 328 MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK); 329 330 MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE); 331 MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK); 332 MOUSE_WRITE_BYTE(exch, buttons ? 200 : 100); 333 MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK); 334 335 MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE); 336 MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK); 337 MOUSE_WRITE_BYTE(exch, 80); 338 MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK); 339 340 MOUSE_WRITE_BYTE(exch, PS2_MOUSE_GET_DEVICE_ID); 341 MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK); 342 MOUSE_READ_BYTE_TEST(exch, buttons ? 4 : 3); 345 MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE); 346 MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK); 347 MOUSE_WRITE_BYTE(mouse, 200); 348 MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK); 349 350 MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE); 351 MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK); 352 MOUSE_WRITE_BYTE(mouse, buttons ? 200 : 100); 353 MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK); 354 355 MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE); 356 MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK); 357 MOUSE_WRITE_BYTE(mouse, 80); 358 MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK); 359 360 MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_GET_DEVICE_ID); 361 MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK); 362 MOUSE_READ_BYTE_TEST(mouse, buttons ? 4 : 3); 343 363 344 364 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.