hw_krait.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Lowlevel hardware access for the
  3. * Razer Krait mouse
  4. *
  5. * Important notice:
  6. * This hardware driver is based on reverse engineering, only.
  7. *
  8. * Copyright (C) 2007-2011 Michael Buesch <m@bues.ch>
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. */
  20. #include "hw_krait.h"
  21. #include "razer_private.h"
  22. #include <errno.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <stdint.h>
  26. #include <string.h>
  27. struct krait_private {
  28. struct razer_mouse *m;
  29. struct razer_mouse_dpimapping *cur_dpimapping;
  30. struct razer_mouse_profile profile;
  31. struct razer_mouse_dpimapping dpimapping[2];
  32. bool commit_pending;
  33. };
  34. static int krait_usb_write(struct krait_private *priv,
  35. int request, int command,
  36. void *buf, size_t size)
  37. {
  38. int err;
  39. err = libusb_control_transfer(
  40. priv->m->usb_ctx->h,
  41. LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS |
  42. LIBUSB_RECIPIENT_INTERFACE,
  43. request, command, 0,
  44. buf, size,
  45. RAZER_USB_TIMEOUT);
  46. if (err < 0 || (size_t)err != size)
  47. return err;
  48. return 0;
  49. }
  50. #if 0
  51. static int krait_usb_read(struct krait_private *priv,
  52. int request, int command,
  53. char *buf, size_t size)
  54. {
  55. int err;
  56. err = libusb_control_transfer(
  57. priv->m->usb_ctx->h,
  58. LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS |
  59. LIBUSB_RECIPIENT_INTERFACE,
  60. request, command, 0,
  61. (unsigned char *)buf, size,
  62. RAZER_USB_TIMEOUT);
  63. if (err < 0 || (size_t)err != size)
  64. return err;
  65. return 0;
  66. }
  67. #endif
  68. static int krait_do_commit(struct krait_private *priv)
  69. {
  70. uint8_t value;
  71. int err;
  72. switch (priv->cur_dpimapping->res[RAZER_DIM_0]) {
  73. case RAZER_MOUSE_RES_400DPI:
  74. value = 6;
  75. break;
  76. case RAZER_MOUSE_RES_1600DPI:
  77. value = 4;
  78. break;
  79. default:
  80. return -EINVAL;
  81. }
  82. err = krait_usb_write(priv, LIBUSB_REQUEST_SET_CONFIGURATION,
  83. 0x02, &value, sizeof(value));
  84. if (err)
  85. return err;
  86. return 0;
  87. }
  88. static int krait_commit(struct razer_mouse *m, int force)
  89. {
  90. struct krait_private *priv = m->drv_data;
  91. int err = 0;
  92. if (!m->claim_count)
  93. return -EBUSY;
  94. if (priv->commit_pending || force) {
  95. err = krait_do_commit(priv);
  96. if (!err)
  97. priv->commit_pending = 0;
  98. }
  99. return err;
  100. }
  101. static int krait_supported_resolutions(struct razer_mouse *m,
  102. enum razer_mouse_res **res_list)
  103. {
  104. enum razer_mouse_res *list;
  105. const int count = 2;
  106. list = zalloc(sizeof(*list) * count);
  107. if (!list)
  108. return -ENOMEM;
  109. list[0] = RAZER_MOUSE_RES_400DPI;
  110. list[1] = RAZER_MOUSE_RES_1600DPI;
  111. *res_list = list;
  112. return count;
  113. }
  114. static struct razer_mouse_profile * krait_get_profiles(struct razer_mouse *m)
  115. {
  116. struct krait_private *priv = m->drv_data;
  117. return &priv->profile;
  118. }
  119. static int krait_supported_dpimappings(struct razer_mouse *m,
  120. struct razer_mouse_dpimapping **res_ptr)
  121. {
  122. struct krait_private *priv = m->drv_data;
  123. *res_ptr = &priv->dpimapping[0];
  124. return ARRAY_SIZE(priv->dpimapping);
  125. }
  126. static struct razer_mouse_dpimapping * krait_get_dpimapping(struct razer_mouse_profile *p,
  127. struct razer_axis *axis)
  128. {
  129. struct krait_private *priv = p->mouse->drv_data;
  130. return priv->cur_dpimapping;
  131. }
  132. static int krait_set_dpimapping(struct razer_mouse_profile *p,
  133. struct razer_axis *axis,
  134. struct razer_mouse_dpimapping *d)
  135. {
  136. struct krait_private *priv = p->mouse->drv_data;
  137. if (!priv->m->claim_count)
  138. return -EBUSY;
  139. priv->cur_dpimapping = d;
  140. priv->commit_pending = 1;
  141. return 0;
  142. }
  143. int razer_krait_init(struct razer_mouse *m,
  144. struct libusb_device *usbdev)
  145. {
  146. struct krait_private *priv;
  147. int err;
  148. priv = zalloc(sizeof(struct krait_private));
  149. if (!priv)
  150. return -ENOMEM;
  151. priv->m = m;
  152. m->drv_data = priv;
  153. err = razer_usb_add_used_interface(m->usb_ctx, 0, 0);
  154. if (err) {
  155. free(priv);
  156. return err;
  157. }
  158. priv->profile.nr = 0;
  159. priv->profile.get_dpimapping = krait_get_dpimapping;
  160. priv->profile.set_dpimapping = krait_set_dpimapping;
  161. priv->profile.mouse = m;
  162. priv->dpimapping[0].nr = 0;
  163. priv->dpimapping[0].res[RAZER_DIM_0] = RAZER_MOUSE_RES_400DPI;
  164. priv->dpimapping[0].dimension_mask = (1 << RAZER_DIM_0);
  165. priv->dpimapping[0].change = NULL;
  166. priv->dpimapping[0].mouse = m;
  167. priv->dpimapping[1].nr = 1;
  168. priv->dpimapping[1].res[RAZER_DIM_0] = RAZER_MOUSE_RES_1600DPI;
  169. priv->dpimapping[1].dimension_mask = (1 << RAZER_DIM_0);
  170. priv->dpimapping[1].change = NULL;
  171. priv->dpimapping[1].mouse = m;
  172. priv->cur_dpimapping = &priv->dpimapping[1];
  173. m->type = RAZER_MOUSETYPE_KRAIT;
  174. razer_generic_usb_gen_idstr(usbdev, NULL, "Krait", 1,
  175. NULL, m->idstr);
  176. m->commit = krait_commit;
  177. m->get_profiles = krait_get_profiles;
  178. m->supported_resolutions = krait_supported_resolutions;
  179. m->supported_dpimappings = krait_supported_dpimappings;
  180. return 0;
  181. }
  182. void razer_krait_release(struct razer_mouse *m)
  183. {
  184. struct krait_private *priv = m->drv_data;
  185. free(priv);
  186. }