synapse.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. /*
  2. * Lowlevel hardware access for the
  3. * Razer Synapse wire protocol
  4. *
  5. * Important notice:
  6. * This hardware driver is based on reverse engineering, only.
  7. *
  8. * Copyright (C) 2012 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 "librazer.h"
  21. #include "synapse.h"
  22. #include "razer_private.h"
  23. #include "util.h"
  24. #include "buttonmapping.h"
  25. enum synapse_constants {
  26. SYNAPSE_NR_PROFILES = 5,
  27. SYNAPSE_NR_DPIMAPPINGS = 5,
  28. SYNAPSE_NR_AXES = 3,
  29. SYNAPSE_NR_LEDS = 2,
  30. SYNAPSE_SERIAL_MAX_LEN = 32,
  31. SYNAPSE_PROFNAME_MAX_LEN = 20,
  32. };
  33. enum synapse_phys_button {
  34. /* Physical button IDs */
  35. SYNAPSE_PHYSBUT_LEFT = 0x01, /* Left button */
  36. SYNAPSE_PHYSBUT_RIGHT, /* Right button */
  37. SYNAPSE_PHYSBUT_MIDDLE, /* Middle button */
  38. SYNAPSE_PHYSBUT_LFRONT, /* Left side, front button */
  39. SYNAPSE_PHYSBUT_LREAR, /* Left side, rear button */
  40. SYNAPSE_PHYSBUT_RFRONT, /* Right side, front button */
  41. SYNAPSE_PHYSBUT_RREAR, /* Right side, rear button */
  42. SYNAPSE_PHYSBUT_TFRONT, /* Top side, front button */
  43. SYNAPSE_PHYSBUT_TREAR, /* Top side, rear button */
  44. SYNAPSE_PHYSBUT_SCROLLUP, /* Scroll wheel up */
  45. SYNAPSE_PHYSBUT_SCROLLDWN, /* Scroll wheel down */
  46. NR_SYNAPSE_PHYSBUT = 11, /* Number of physical buttons */
  47. };
  48. struct synapse_request {
  49. uint8_t magic;
  50. uint8_t flags;
  51. uint8_t rw;
  52. uint8_t command;
  53. uint8_t request;
  54. uint8_t _padding[3];
  55. uint8_t payload[80];
  56. le16_t checksum;
  57. } _packed;
  58. #define SYNAPSE_REQ_MAGIC 0x01
  59. #define SYNAPSE_REQ_FLG_TRANSOK 0x02
  60. #define SYNAPSE_REQ_READ 0x01
  61. #define SYNAPSE_REQ_WRITE 0x00
  62. struct synapse_request_devinfo {
  63. uint8_t serial[SYNAPSE_SERIAL_MAX_LEN];
  64. uint8_t fwver[2];
  65. } _packed;
  66. struct synapse_request_globconfig {
  67. uint8_t profile;
  68. uint8_t freq;
  69. uint8_t dpisel;
  70. uint8_t dpival0;
  71. uint8_t dpival1;
  72. } _packed;
  73. struct synapse_request_profname {
  74. uint8_t profile;
  75. union {
  76. uint8_t name_raw[SYNAPSE_PROFNAME_MAX_LEN * 2]; /* UTF-16-LE */
  77. le16_t name_le16[SYNAPSE_PROFNAME_MAX_LEN];
  78. } _packed;
  79. } _packed;
  80. struct synapse_one_dpimapping {
  81. uint8_t dpival0;
  82. uint8_t dpival1;
  83. } _packed;
  84. struct synapse_led_color {
  85. uint8_t r;
  86. uint8_t g;
  87. uint8_t b;
  88. uint8_t padding;
  89. } _packed;
  90. #define SYNAPSE_LED_COLOR_PADDING 0xFF
  91. struct synapse_request_hwconfig {
  92. uint8_t profile;
  93. uint8_t leds;
  94. uint8_t dpisel;
  95. uint8_t nr_dpimappings;
  96. struct synapse_one_dpimapping dpimappings[SYNAPSE_NR_DPIMAPPINGS];
  97. uint8_t _padding[6];
  98. uint8_t buttonmap[4 * NR_SYNAPSE_PHYSBUT];
  99. struct synapse_led_color led_colors[SYNAPSE_NR_LEDS];
  100. } _packed;
  101. struct synapse_buttons {
  102. struct razer_buttonmapping mapping[NR_SYNAPSE_PHYSBUT];
  103. };
  104. struct synapse_prof_name {
  105. razer_utf16_t name[SYNAPSE_PROFNAME_MAX_LEN + 1];
  106. };
  107. struct synapse_led_name {
  108. char name[32];
  109. };
  110. struct razer_synapse {
  111. struct razer_mouse *m;
  112. void *drv_data;
  113. /* Feature selection bits */
  114. unsigned int features;
  115. /* Firmware version */
  116. uint16_t fw_version;
  117. /* Device serial number */
  118. char serial[SYNAPSE_SERIAL_MAX_LEN + 1];
  119. /* LED names */
  120. struct synapse_led_name led_names[SYNAPSE_NR_LEDS];
  121. /* The currently set LED states. */
  122. enum razer_led_state led_states[SYNAPSE_NR_PROFILES][SYNAPSE_NR_LEDS];
  123. /* LED colors */
  124. struct razer_rgb_color led_colors[SYNAPSE_NR_PROFILES][SYNAPSE_NR_LEDS];
  125. /* The active profile. */
  126. struct razer_mouse_profile *cur_profile;
  127. /* Profile configuration (one per profile). */
  128. struct razer_mouse_profile profiles[SYNAPSE_NR_PROFILES];
  129. /* Profile names */
  130. struct synapse_prof_name profile_names[SYNAPSE_NR_PROFILES];
  131. /* Supported mouse axes */
  132. struct razer_axis axes[SYNAPSE_NR_AXES];
  133. /* The active DPI mapping; per profile. */
  134. struct razer_mouse_dpimapping *cur_dpimapping[SYNAPSE_NR_PROFILES];
  135. /* The possible DPI mappings. */
  136. struct razer_mouse_dpimapping dpimappings[SYNAPSE_NR_PROFILES][SYNAPSE_NR_DPIMAPPINGS];
  137. /* The active scan frequency. */
  138. enum razer_mouse_freq cur_freq;
  139. /* The active button mapping; per profile. */
  140. struct synapse_buttons buttons[SYNAPSE_NR_PROFILES];
  141. bool commit_pending;
  142. };
  143. /* A list of physical buttons on the device. */
  144. static struct razer_button synapse_physical_buttons[] = {
  145. { .id = SYNAPSE_PHYSBUT_LEFT, .name = "Leftclick", },
  146. { .id = SYNAPSE_PHYSBUT_RIGHT, .name = "Rightclick", },
  147. { .id = SYNAPSE_PHYSBUT_MIDDLE, .name = "Middleclick", },
  148. { .id = SYNAPSE_PHYSBUT_LFRONT, .name = "Leftside front", },
  149. { .id = SYNAPSE_PHYSBUT_LREAR, .name = "Leftside rear", },
  150. { .id = SYNAPSE_PHYSBUT_RFRONT, .name = "Rightside front", },
  151. { .id = SYNAPSE_PHYSBUT_RREAR, .name = "Rightside rear", },
  152. { .id = SYNAPSE_PHYSBUT_TFRONT, .name = "Top front", },
  153. { .id = SYNAPSE_PHYSBUT_TREAR, .name = "Top rear", },
  154. { .id = SYNAPSE_PHYSBUT_SCROLLUP, .name = "Scroll up", },
  155. { .id = SYNAPSE_PHYSBUT_SCROLLDWN, .name = "Scroll down", },
  156. };
  157. /* A list of possible button functions. */
  158. static struct razer_button_function synapse_button_functions[] = {
  159. BUTTONFUNC_LEFT,
  160. BUTTONFUNC_RIGHT,
  161. BUTTONFUNC_MIDDLE,
  162. BUTTONFUNC_PROFDOWN,
  163. BUTTONFUNC_PROFUP,
  164. BUTTONFUNC_DPIUP,
  165. BUTTONFUNC_DPIDOWN,
  166. BUTTONFUNC_DPI1,
  167. BUTTONFUNC_DPI2,
  168. BUTTONFUNC_DPI3,
  169. BUTTONFUNC_DPI4,
  170. BUTTONFUNC_DPI5,
  171. BUTTONFUNC_WIN5,
  172. BUTTONFUNC_WIN4,
  173. BUTTONFUNC_SCROLLUP,
  174. BUTTONFUNC_SCROLLDWN,
  175. };
  176. /* requests:
  177. * description: command, request / payload
  178. * ==================================================
  179. *
  180. * get device info: 02, 01
  181. * ->reply: 02, 22 / struct synapse_request_devinfo
  182. *
  183. * get global config: 05, 01 or
  184. * 05, 00
  185. * ->reply: 05, 05 / struct synapse_request_globconfig
  186. *
  187. * set global config: 05, 05
  188. *
  189. * get prof name: 22, 01 / profnr
  190. * ->reply: 22, 29 / struct synapse_request_profname
  191. *
  192. * set prof name: 22, 29 / struct synapse_request_profile
  193. *
  194. * get hwconfig: 06, 01 / profnr
  195. * ->reply: 06, 38 / struct synapse_request_hwconfig
  196. *
  197. * set hwconfig: 06, 48 / struct synapse_request_hwconfig
  198. *
  199. * get ???: 08, 00
  200. * ->reply: 08, 04 / all zero
  201. */
  202. static le16_t synapse_checksum(const struct synapse_request *req)
  203. {
  204. uint16_t checksum;
  205. checksum = razer_xor8_checksum((const uint8_t *)req + 2,
  206. sizeof(*req) - 4);
  207. if (!(req->flags & SYNAPSE_REQ_FLG_TRANSOK))
  208. checksum |= 0x100;
  209. return cpu_to_le16(checksum);
  210. }
  211. static int synapse_usb_write(struct razer_synapse *s,
  212. int request, int command, int index,
  213. void *buf, size_t size)
  214. {
  215. int err;
  216. err = libusb_control_transfer(
  217. s->m->usb_ctx->h,
  218. LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS |
  219. LIBUSB_RECIPIENT_INTERFACE,
  220. request, command, index,
  221. buf, size,
  222. RAZER_USB_TIMEOUT);
  223. if (err < 0 || (size_t)err != size) {
  224. razer_error("synapse: usb_write failed\n");
  225. return -EIO;
  226. }
  227. razer_msleep(5);
  228. return 0;
  229. }
  230. static int synapse_usb_read(struct razer_synapse *s,
  231. int request, int command, int index,
  232. void *buf, size_t size)
  233. {
  234. int err;
  235. err = libusb_control_transfer(
  236. s->m->usb_ctx->h,
  237. LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS |
  238. LIBUSB_RECIPIENT_INTERFACE,
  239. request, command, index,
  240. buf, size,
  241. RAZER_USB_TIMEOUT);
  242. if (err < 0 || (size_t)err != size) {
  243. razer_error("synapse: usb_read failed\n");
  244. return -EIO;
  245. }
  246. razer_msleep(5);
  247. return 0;
  248. }
  249. static int synapse_request_send(struct razer_synapse *s,
  250. const struct synapse_request *_req)
  251. {
  252. struct synapse_request req = *_req;
  253. req.magic = SYNAPSE_REQ_MAGIC;
  254. req.checksum = synapse_checksum(&req);
  255. // razer_dump("WR", &req, sizeof(req));
  256. return synapse_usb_write(s, LIBUSB_REQUEST_SET_CONFIGURATION,
  257. 0x300, 0, &req, sizeof(req));
  258. }
  259. static int synapse_request_receive(struct razer_synapse *s,
  260. struct synapse_request *req,
  261. bool do_checksum)
  262. {
  263. le16_t checksum;
  264. int err;
  265. memset(req, 0, sizeof(*req));
  266. err = synapse_usb_read(s, LIBUSB_REQUEST_CLEAR_FEATURE,
  267. 0x300, 0, req, sizeof(*req));
  268. if (err)
  269. return err;
  270. // razer_dump("RD", req, sizeof(*req));
  271. if (do_checksum) {
  272. checksum = synapse_checksum(req);
  273. if (req->checksum != checksum) {
  274. razer_error("synapse: Received request with invalid "
  275. "checksum (was 0x%04X, expected 0x%04X)\n",
  276. le16_to_cpu(req->checksum),
  277. le16_to_cpu(checksum));
  278. return -EIO;
  279. }
  280. }
  281. return 0;
  282. }
  283. static int synapse_request_write(struct razer_synapse *s,
  284. uint8_t command, uint8_t request,
  285. const void *payload, size_t payload_len)
  286. {
  287. struct synapse_request req, nullreq;
  288. int err;
  289. if (WARN_ON(payload_len > sizeof(req.payload)))
  290. return -EINVAL;
  291. memset(&req, 0, sizeof(req));
  292. req.rw = SYNAPSE_REQ_WRITE;
  293. req.command = command;
  294. req.request = request;
  295. if (payload)
  296. memcpy(req.payload, payload, payload_len);
  297. err = synapse_request_send(s, &req);
  298. if (err)
  299. return err;
  300. err = synapse_request_receive(s, &req, 0);
  301. if (err)
  302. return err;
  303. memset(&nullreq, 0, sizeof(nullreq));
  304. err = synapse_request_send(s, &nullreq);
  305. if (err)
  306. return err;
  307. if (req.magic != SYNAPSE_REQ_MAGIC) {
  308. razer_error("synapse: Invalid magic on sent request\n");
  309. return -EIO;
  310. }
  311. if (req.rw != SYNAPSE_REQ_WRITE) {
  312. razer_error("synapse: Invalid rw flag on sent request\n");
  313. return -EIO;
  314. }
  315. if (req.command != command || req.request != request) {
  316. razer_error("synapse: Invalid command on sent request\n");
  317. return -EIO;
  318. }
  319. return 0;
  320. }
  321. static int synapse_request_read(struct razer_synapse *s,
  322. uint8_t command, uint8_t request,
  323. void *payload, size_t payload_len)
  324. {
  325. struct synapse_request req, nullreq;
  326. int err;
  327. if (WARN_ON(payload_len > sizeof(req.payload)))
  328. return -EINVAL;
  329. memset(&req, 0, sizeof(req));
  330. req.rw = SYNAPSE_REQ_READ;
  331. req.command = command;
  332. req.request = request;
  333. if (payload)
  334. memcpy(req.payload, payload, payload_len);
  335. err = synapse_request_send(s, &req);
  336. if (err)
  337. return err;
  338. err = synapse_request_receive(s, &req, 0);
  339. if (err)
  340. return err;
  341. memset(&nullreq, 0, sizeof(nullreq));
  342. err = synapse_request_send(s, &nullreq);
  343. if (err)
  344. return err;
  345. if (payload)
  346. memcpy(payload, req.payload, payload_len);
  347. if (req.magic != SYNAPSE_REQ_MAGIC) {
  348. razer_error("synapse: Invalid magic on received request\n");
  349. return -EIO;
  350. }
  351. if (!(req.flags & SYNAPSE_REQ_FLG_TRANSOK)) {
  352. razer_error("synapse: Failed to receive request. (TRANSOK flag)\n");
  353. return -EIO;
  354. }
  355. if (req.rw != SYNAPSE_REQ_READ) {
  356. razer_error("synapse: Invalid rw flag on received request\n");
  357. return -EIO;
  358. }
  359. if (req.command != command) {
  360. razer_error("synapse: Invalid command on received request\n");
  361. return -EIO;
  362. }
  363. return 0;
  364. }
  365. static int synapse_read_config_from_hw(struct razer_synapse *s)
  366. {
  367. unsigned int i, j;
  368. int err;
  369. struct synapse_request_profname profname;
  370. struct synapse_request_globconfig globconfig;
  371. struct synapse_request_hwconfig hwconfig;
  372. enum razer_mouse_res res_x, res_y;
  373. /* Get global config */
  374. memset(&globconfig, 0, sizeof(globconfig));
  375. err = synapse_request_read(s, 5, 1,
  376. &globconfig, sizeof(globconfig));
  377. if (err)
  378. return err;
  379. if (globconfig.profile < 1 || globconfig.profile > SYNAPSE_NR_PROFILES) {
  380. razer_error("synapse: Got invalid profile number: %u\n",
  381. (unsigned int)globconfig.profile);
  382. globconfig.profile = 1;
  383. }
  384. s->cur_profile = &s->profiles[globconfig.profile - 1];
  385. switch (globconfig.freq) {
  386. case 1:
  387. s->cur_freq = RAZER_MOUSE_FREQ_1000HZ;
  388. break;
  389. case 2:
  390. s->cur_freq = RAZER_MOUSE_FREQ_500HZ;
  391. break;
  392. case 8:
  393. s->cur_freq = RAZER_MOUSE_FREQ_125HZ;
  394. break;
  395. default:
  396. razer_error("synapse: "
  397. "Read invalid frequency value from device (%u)\n",
  398. globconfig.freq);
  399. s->cur_freq = RAZER_MOUSE_FREQ_125HZ;
  400. }
  401. /* Get the profile names */
  402. for (i = 0; i < SYNAPSE_NR_PROFILES; i++) {
  403. memset(&profname, 0, sizeof(profname));
  404. profname.profile = i + 1;
  405. err = synapse_request_read(s, 0x22, 1,
  406. &profname, sizeof(profname));
  407. if (err)
  408. return err;
  409. memset(&s->profile_names[i], 0, sizeof(s->profile_names[i]));
  410. for (j = 0; j < SYNAPSE_PROFNAME_MAX_LEN; j++) {
  411. s->profile_names[i].name[j] = profname.name_raw[j * 2 + 0];
  412. s->profile_names[i].name[j] |= (uint16_t)profname.name_raw[j * 2 + 1] << 8;
  413. }
  414. }
  415. /* Get the profile configs */
  416. for (i = 0; i < SYNAPSE_NR_PROFILES; i++) {
  417. memset(&hwconfig, 0, sizeof(hwconfig));
  418. hwconfig.profile = i + 1;
  419. err = synapse_request_read(s, 6, 1,
  420. &hwconfig, sizeof(hwconfig));
  421. if (err)
  422. return err;
  423. if (hwconfig.profile != i + 1) {
  424. razer_error("synapse: Failed to read hw config (%u vs %u)\n",
  425. hwconfig.profile, i + 1);
  426. hwconfig.profile = i + 1;
  427. }
  428. for (j = 0; j < SYNAPSE_NR_LEDS; j++)
  429. s->led_states[i][j] = !!(hwconfig.leds & (1 << j));
  430. if (hwconfig.nr_dpimappings < 1 ||
  431. hwconfig.nr_dpimappings > SYNAPSE_NR_DPIMAPPINGS) {
  432. razer_error("synapse: Got invalid nr_dpimappings: %u\n",
  433. hwconfig.nr_dpimappings);
  434. hwconfig.nr_dpimappings = SYNAPSE_NR_DPIMAPPINGS;
  435. }
  436. if (hwconfig.dpisel < 1 || hwconfig.dpisel > SYNAPSE_NR_DPIMAPPINGS ||
  437. hwconfig.dpisel > hwconfig.nr_dpimappings) {
  438. razer_error("synapse: Got invalid DPI selection: %u\n",
  439. hwconfig.dpisel);
  440. hwconfig.dpisel = 1;
  441. }
  442. s->cur_dpimapping[i] = &s->dpimappings[i][hwconfig.dpisel - 1];
  443. for (j = 0; j < SYNAPSE_NR_DPIMAPPINGS; j++) {
  444. if (j + 1 > hwconfig.nr_dpimappings) {
  445. res_x = RAZER_MOUSE_RES_5600DPI;
  446. res_y = res_x;
  447. } else {
  448. res_x = ((hwconfig.dpimappings[j].dpival0 / 4) + 1) * 100;
  449. res_y = ((hwconfig.dpimappings[j].dpival1 / 4) + 1) * 100;
  450. }
  451. s->dpimappings[i][j].res[RAZER_DIM_X] = res_x;
  452. s->dpimappings[i][j].res[RAZER_DIM_Y] = res_y;
  453. }
  454. err = razer_parse_buttonmap(hwconfig.buttonmap, sizeof(hwconfig.buttonmap),
  455. s->buttons[i].mapping,
  456. ARRAY_SIZE(s->buttons[i].mapping), 2);
  457. if (err)
  458. return err;
  459. for (j = 0; j < SYNAPSE_NR_LEDS; j++) {
  460. s->led_colors[i][j].r = hwconfig.led_colors[j].r;
  461. s->led_colors[i][j].g = hwconfig.led_colors[j].g;
  462. s->led_colors[i][j].b = hwconfig.led_colors[j].b;
  463. s->led_colors[i][j].valid = !!(s->features & RAZER_SYNFEAT_RGBLEDS);
  464. }
  465. }
  466. return 0;
  467. }
  468. static int synapse_read_devinfo(struct razer_synapse *s)
  469. {
  470. struct synapse_request_devinfo devinfo;
  471. int err;
  472. s->fw_version = 0;
  473. memset(s->serial, 0, sizeof(s->serial));
  474. memset(&devinfo, 0, sizeof(devinfo));
  475. err = synapse_request_read(s, 2, 1,
  476. &devinfo, sizeof(devinfo));
  477. if (err)
  478. return -EIO;
  479. s->fw_version = ((uint16_t)(devinfo.fwver[0]) << 8) |
  480. devinfo.fwver[1];
  481. memcpy(s->serial, devinfo.serial, SYNAPSE_SERIAL_MAX_LEN);
  482. return 0;
  483. }
  484. static int synapse_get_fw_version(struct razer_mouse *m)
  485. {
  486. struct razer_synapse *s = m->drv_data;
  487. return s->fw_version;
  488. }
  489. static int synapse_do_commit(struct razer_synapse *s)
  490. {
  491. struct synapse_request_profname profname;
  492. struct synapse_request_globconfig globconfig;
  493. struct synapse_request_hwconfig hwconfig;
  494. int err;
  495. unsigned int i, j;
  496. /* Commit profile configs */
  497. for (i = 0; i < SYNAPSE_NR_PROFILES; i++) {
  498. memset(&hwconfig, 0, sizeof(hwconfig));
  499. hwconfig.profile = i + 1;
  500. hwconfig.leds = 0x04; /* Bit 2 is always set */
  501. for (j = 0; j < SYNAPSE_NR_LEDS; j++) {
  502. if (s->led_states[i][j])
  503. hwconfig.leds |= (1 << j);
  504. }
  505. hwconfig.dpisel = (s->cur_dpimapping[i]->nr % 10) + 1;
  506. hwconfig.nr_dpimappings = SYNAPSE_NR_DPIMAPPINGS;
  507. for (j = 0; j < SYNAPSE_NR_DPIMAPPINGS; j++) {
  508. hwconfig.dpimappings[j].dpival0 = ((s->dpimappings[i][j].res[RAZER_DIM_X] / 100) - 1) * 4;
  509. hwconfig.dpimappings[j].dpival1 = ((s->dpimappings[i][j].res[RAZER_DIM_Y] / 100) - 1) * 4;
  510. }
  511. err = razer_create_buttonmap(hwconfig.buttonmap, sizeof(hwconfig.buttonmap),
  512. s->buttons[i].mapping,
  513. ARRAY_SIZE(s->buttons[i].mapping), 2);
  514. if (err)
  515. return err;
  516. if (s->features & RAZER_SYNFEAT_RGBLEDS) {
  517. for (j = 0; j < SYNAPSE_NR_LEDS; j++) {
  518. hwconfig.led_colors[j].padding = SYNAPSE_LED_COLOR_PADDING;
  519. hwconfig.led_colors[j].r = s->led_colors[i][j].r;
  520. hwconfig.led_colors[j].g = s->led_colors[i][j].g;
  521. hwconfig.led_colors[j].b = s->led_colors[i][j].b;
  522. }
  523. }
  524. err = synapse_request_write(s, 6, 0x48,
  525. &hwconfig, sizeof(hwconfig));
  526. if (err)
  527. return err;
  528. }
  529. /* Commit profile names */
  530. for (i = 0; i < SYNAPSE_NR_PROFILES; i++) {
  531. memset(&profname, 0, sizeof(profname));
  532. profname.profile = i + 1;
  533. for (j = 0; j < SYNAPSE_PROFNAME_MAX_LEN; j++) {
  534. le16_t c = cpu_to_le16(s->profile_names[i].name[j]);
  535. profname.name_le16[j] = c;
  536. }
  537. err = synapse_request_write(s, 0x22, 0x29,
  538. &profname, sizeof(profname));
  539. if (err)
  540. return err;
  541. }
  542. /* Commit global config */
  543. memset(&globconfig, 0, sizeof(globconfig));
  544. globconfig.profile = s->cur_profile->nr + 1;
  545. switch (s->cur_freq) {
  546. default:
  547. case RAZER_MOUSE_FREQ_1000HZ:
  548. globconfig.freq = 1;
  549. break;
  550. case RAZER_MOUSE_FREQ_500HZ:
  551. globconfig.freq = 2;
  552. break;
  553. case RAZER_MOUSE_FREQ_125HZ:
  554. globconfig.freq = 8;
  555. break;
  556. }
  557. globconfig.dpisel = (s->cur_dpimapping[s->cur_profile->nr]->nr % 10) + 1;
  558. globconfig.dpival0 = ((s->cur_dpimapping[s->cur_profile->nr]->res[RAZER_DIM_X] / 100) - 1) * 4;
  559. globconfig.dpival1 = ((s->cur_dpimapping[s->cur_profile->nr]->res[RAZER_DIM_Y] / 100) - 1) * 4;
  560. err = synapse_request_write(s, 5, 5,
  561. &globconfig, sizeof(globconfig));
  562. if (err)
  563. return err;
  564. return 0;
  565. }
  566. static int synapse_commit(struct razer_mouse *m, int force)
  567. {
  568. struct razer_synapse *s = m->drv_data;
  569. int err = 0;
  570. if (!m->claim_count)
  571. return -EBUSY;
  572. if (s->commit_pending || force) {
  573. err = synapse_do_commit(s);
  574. if (!err)
  575. s->commit_pending = 0;
  576. }
  577. return err;
  578. }
  579. static enum razer_mouse_freq synapse_global_get_freq(struct razer_mouse *m)
  580. {
  581. struct razer_synapse *s = m->drv_data;
  582. return s->cur_freq;
  583. }
  584. static int synapse_global_set_freq(struct razer_mouse *m,
  585. enum razer_mouse_freq freq)
  586. {
  587. struct razer_synapse *s = m->drv_data;
  588. if (!s->m->claim_count)
  589. return -EBUSY;
  590. s->cur_freq = freq;
  591. s->commit_pending = 1;
  592. return 0;
  593. }
  594. static const razer_utf16_t * synapse_profile_get_name(struct razer_mouse_profile *p)
  595. {
  596. struct razer_mouse *m = p->mouse;
  597. struct razer_synapse *s = m->drv_data;
  598. if (p->nr >= SYNAPSE_NR_PROFILES)
  599. return NULL;
  600. return s->profile_names[p->nr].name;
  601. }
  602. static int synapse_profile_set_name(struct razer_mouse_profile *p,
  603. const razer_utf16_t *new_name)
  604. {
  605. struct razer_mouse *m = p->mouse;
  606. struct razer_synapse *s = m->drv_data;
  607. int err;
  608. if (p->nr >= SYNAPSE_NR_PROFILES)
  609. return -EINVAL;
  610. if (!m->claim_count)
  611. return -EBUSY;
  612. err = razer_utf16_cpy(s->profile_names[p->nr].name,
  613. new_name, SYNAPSE_PROFNAME_MAX_LEN);
  614. s->commit_pending = 1;
  615. return err;
  616. }
  617. static int synapse_led_toggle(struct razer_led *led,
  618. enum razer_led_state new_state)
  619. {
  620. struct razer_mouse_profile *p = led->u.mouse_prof;
  621. struct razer_mouse *m = p->mouse;
  622. struct razer_synapse *s = m->drv_data;
  623. if (led->id >= SYNAPSE_NR_LEDS)
  624. return -EINVAL;
  625. if ((new_state != RAZER_LED_OFF) &&
  626. (new_state != RAZER_LED_ON))
  627. return -EINVAL;
  628. if (p->nr >= SYNAPSE_NR_PROFILES)
  629. return -EINVAL;
  630. if (!s->m->claim_count)
  631. return -EBUSY;
  632. s->led_states[p->nr][led->id] = new_state;
  633. s->commit_pending = 1;
  634. return 0;
  635. }
  636. static int synapse_led_change_color(struct razer_led *led,
  637. const struct razer_rgb_color *new_color)
  638. {
  639. struct razer_mouse_profile *p = led->u.mouse_prof;
  640. struct razer_mouse *m = p->mouse;
  641. struct razer_synapse *s = m->drv_data;
  642. if (led->id >= SYNAPSE_NR_LEDS)
  643. return -EINVAL;
  644. if (p->nr >= SYNAPSE_NR_PROFILES)
  645. return -EINVAL;
  646. if (!s->m->claim_count)
  647. return -EBUSY;
  648. s->led_colors[p->nr][led->id] = *new_color;
  649. s->commit_pending = 1;
  650. return 0;
  651. }
  652. static struct razer_mouse_profile * synapse_get_profiles(struct razer_mouse *m)
  653. {
  654. struct razer_synapse *s = m->drv_data;
  655. return &s->profiles[0];
  656. }
  657. static struct razer_mouse_profile * synapse_get_active_profile(struct razer_mouse *m)
  658. {
  659. struct razer_synapse *s = m->drv_data;
  660. return s->cur_profile;
  661. }
  662. static int synapse_set_active_profile(struct razer_mouse *m,
  663. struct razer_mouse_profile *p)
  664. {
  665. struct razer_synapse *s = m->drv_data;
  666. if (!s->m->claim_count)
  667. return -EBUSY;
  668. s->cur_profile = p;
  669. s->commit_pending = 1;
  670. return 0;
  671. }
  672. static int synapse_supported_dpimappings(struct razer_mouse *m,
  673. struct razer_mouse_dpimapping **res_ptr)
  674. {
  675. struct razer_synapse *s = m->drv_data;
  676. *res_ptr = &s->dpimappings[0][0];
  677. return SYNAPSE_NR_PROFILES * SYNAPSE_NR_DPIMAPPINGS;
  678. }
  679. static struct razer_mouse_dpimapping * synapse_get_dpimapping(struct razer_mouse_profile *p,
  680. struct razer_axis *axis)
  681. {
  682. struct razer_synapse *s = p->mouse->drv_data;
  683. if (p->nr >= ARRAY_SIZE(s->cur_dpimapping))
  684. return NULL;
  685. return s->cur_dpimapping[p->nr];
  686. }
  687. static int synapse_set_dpimapping(struct razer_mouse_profile *p,
  688. struct razer_axis *axis,
  689. struct razer_mouse_dpimapping *d)
  690. {
  691. struct razer_synapse *s = p->mouse->drv_data;
  692. razer_id_mask_t idmask;
  693. if (!s->m->claim_count)
  694. return -EBUSY;
  695. if (p->nr >= ARRAY_SIZE(s->cur_dpimapping))
  696. return -EINVAL;
  697. razer_id_mask_zero(&idmask);
  698. razer_id_mask_set(&idmask, p->nr);
  699. if (d->profile_mask != idmask)
  700. return -EINVAL;
  701. s->cur_dpimapping[p->nr] = d;
  702. s->commit_pending = 1;
  703. return 0;
  704. }
  705. static int synapse_dpimapping_modify(struct razer_mouse_dpimapping *d,
  706. enum razer_dimension dim,
  707. enum razer_mouse_res res)
  708. {
  709. struct razer_synapse *s = d->mouse->drv_data;
  710. if ((int)dim < 0 || (unsigned int)dim >= ARRAY_SIZE(d->res))
  711. return -EINVAL;
  712. if (!s->m->claim_count)
  713. return -EBUSY;
  714. d->res[dim] = res;
  715. s->commit_pending = 1;
  716. return 0;
  717. }
  718. static int synapse_profile_get_leds(struct razer_mouse_profile *p,
  719. struct razer_led **leds_list)
  720. {
  721. struct razer_synapse *s = p->mouse->drv_data;
  722. struct razer_led *leds[SYNAPSE_NR_LEDS];
  723. int i;
  724. if (p->nr >= SYNAPSE_NR_PROFILES)
  725. return -EINVAL;
  726. for (i = 0; i < SYNAPSE_NR_LEDS; i++) {
  727. leds[i] = zalloc(sizeof(struct razer_led));
  728. if (!leds[i]) {
  729. for (i--; i >= 0; i--)
  730. razer_free(leds[i], sizeof(struct razer_led));
  731. return -ENOMEM;
  732. }
  733. }
  734. for (i = 0; i < SYNAPSE_NR_LEDS; i++) {
  735. leds[i]->name = s->led_names[i].name;
  736. leds[i]->id = i;
  737. leds[i]->state = s->led_states[p->nr][i];
  738. leds[i]->toggle_state = synapse_led_toggle;
  739. if (s->features & RAZER_SYNFEAT_RGBLEDS) {
  740. leds[i]->color = s->led_colors[p->nr][i];
  741. leds[i]->change_color = synapse_led_change_color;
  742. }
  743. leds[i]->u.mouse_prof = &s->profiles[p->nr];
  744. }
  745. /* Link the list */
  746. *leds_list = leds[0];
  747. for (i = 0; i < SYNAPSE_NR_LEDS; i++)
  748. leds[i]->next = (i < SYNAPSE_NR_LEDS - 1) ? leds[i + 1] : NULL;
  749. return SYNAPSE_NR_LEDS;
  750. }
  751. static int synapse_supported_axes(struct razer_mouse *m,
  752. struct razer_axis **axes_list)
  753. {
  754. struct razer_synapse *s = m->drv_data;
  755. *axes_list = s->axes;
  756. return ARRAY_SIZE(s->axes);
  757. }
  758. static int synapse_supported_freqs(struct razer_mouse *m,
  759. enum razer_mouse_freq **freq_list)
  760. {
  761. enum razer_mouse_freq *list;
  762. const int count = 3;
  763. list = malloc(sizeof(*list) * count);
  764. if (!list)
  765. return -ENOMEM;
  766. list[0] = RAZER_MOUSE_FREQ_1000HZ;
  767. list[1] = RAZER_MOUSE_FREQ_500HZ;
  768. list[2] = RAZER_MOUSE_FREQ_125HZ;
  769. *freq_list = list;
  770. return count;
  771. }
  772. static int synapse_supported_resolutions(struct razer_mouse *m,
  773. enum razer_mouse_res **res_list)
  774. {
  775. enum razer_mouse_res *list;
  776. unsigned int i, count = 0, res, step = 0;
  777. count = 56;
  778. step = RAZER_MOUSE_RES_100DPI;
  779. list = malloc(sizeof(*list) * count);
  780. if (!list)
  781. return -ENOMEM;
  782. res = step;
  783. for (i = 0; i < count; i++) {
  784. list[i] = res;
  785. res += step;
  786. }
  787. *res_list = list;
  788. return count;
  789. }
  790. static int synapse_supported_buttons(struct razer_mouse *m,
  791. struct razer_button **res_ptr)
  792. {
  793. *res_ptr = synapse_physical_buttons;
  794. return ARRAY_SIZE(synapse_physical_buttons);
  795. }
  796. static int synapse_supported_button_functions(struct razer_mouse *m,
  797. struct razer_button_function **res_ptr)
  798. {
  799. *res_ptr = synapse_button_functions;
  800. return ARRAY_SIZE(synapse_button_functions);
  801. }
  802. static struct razer_button_function * synapse_get_button_function(struct razer_mouse_profile *p,
  803. struct razer_button *b)
  804. {
  805. struct razer_synapse *s = p->mouse->drv_data;
  806. struct synapse_buttons *buttons;
  807. if (p->nr > ARRAY_SIZE(s->buttons))
  808. return NULL;
  809. buttons = &s->buttons[p->nr];
  810. return razer_get_buttonfunction_by_button(
  811. buttons->mapping, ARRAY_SIZE(buttons->mapping),
  812. synapse_button_functions, ARRAY_SIZE(synapse_button_functions),
  813. b);
  814. }
  815. static int synapse_set_button_function(struct razer_mouse_profile *p,
  816. struct razer_button *b,
  817. struct razer_button_function *f)
  818. {
  819. struct razer_synapse *s = p->mouse->drv_data;
  820. struct synapse_buttons *buttons;
  821. struct razer_buttonmapping *mapping;
  822. if (!s->m->claim_count)
  823. return -EBUSY;
  824. if (p->nr > ARRAY_SIZE(s->buttons))
  825. return -EINVAL;
  826. buttons = &s->buttons[p->nr];
  827. mapping = razer_get_buttonmapping_by_physid(
  828. buttons->mapping, ARRAY_SIZE(buttons->mapping),
  829. b->id);
  830. if (!mapping)
  831. return -ENODEV;
  832. mapping->logical = f->id;
  833. s->commit_pending = 1;
  834. return 0;
  835. }
  836. int razer_synapse_init(struct razer_mouse *m,
  837. void *drv_data,
  838. unsigned int features)
  839. {
  840. struct razer_synapse *s;
  841. int i, j, k, err;
  842. BUILD_BUG_ON(sizeof(struct synapse_request) != 90);
  843. BUILD_BUG_ON(sizeof(struct synapse_request_devinfo) != 34);
  844. BUILD_BUG_ON(sizeof(struct synapse_request_globconfig) != 5);
  845. BUILD_BUG_ON(sizeof(struct synapse_request_profname) != 41);
  846. BUILD_BUG_ON(sizeof(struct synapse_request_hwconfig) != 72);
  847. s = zalloc(sizeof(*s));
  848. if (!s)
  849. return -ENOMEM;
  850. m->drv_data = s;
  851. s->m = m;
  852. s->drv_data = drv_data;
  853. s->features = features;
  854. err = razer_usb_add_used_interface(m->usb_ctx, 0, 0);
  855. if (err) {
  856. err = -ENODEV;
  857. goto err_free;
  858. }
  859. for (i = 0; i < SYNAPSE_NR_PROFILES; i++) {
  860. s->profiles[i].nr = i;
  861. s->profiles[i].get_leds = synapse_profile_get_leds;
  862. s->profiles[i].get_name = synapse_profile_get_name;
  863. s->profiles[i].set_name = synapse_profile_set_name;
  864. s->profiles[i].get_dpimapping = synapse_get_dpimapping;
  865. s->profiles[i].set_dpimapping = synapse_set_dpimapping;
  866. s->profiles[i].get_button_function = synapse_get_button_function;
  867. s->profiles[i].set_button_function = synapse_set_button_function;
  868. s->profiles[i].mouse = m;
  869. }
  870. razer_init_axes(&s->axes[0],
  871. "X", 0,
  872. "Y", 0,
  873. "Scroll", 0);
  874. for (i = 0; i < SYNAPSE_NR_PROFILES; i++) {
  875. for (j = 0; j < SYNAPSE_NR_DPIMAPPINGS; j++) {
  876. s->dpimappings[i][j].nr = i * 10 + j;
  877. for (k = 0; k < RAZER_NR_DIMS; k++)
  878. s->dpimappings[i][j].res[k] = RAZER_MOUSE_RES_UNKNOWN;
  879. s->dpimappings[i][j].dimension_mask = (1 << RAZER_DIM_X) |
  880. (1 << RAZER_DIM_Y);
  881. razer_id_mask_zero(&s->dpimappings[i][j].profile_mask);
  882. razer_id_mask_set(&s->dpimappings[i][j].profile_mask, i);
  883. s->dpimappings[i][j].change = synapse_dpimapping_modify;
  884. s->dpimappings[i][j].mouse = m;
  885. }
  886. }
  887. /* Default LED names */
  888. razer_synapse_set_led_name(m, 0, "ScrollWheel");
  889. razer_synapse_set_led_name(m, 1, "GlowingLogo");
  890. err = m->claim(m);
  891. if (err) {
  892. razer_error("synapse: "
  893. "Failed to initially claim the device\n");
  894. goto err_free;
  895. }
  896. err = synapse_read_devinfo(s);
  897. if (err) {
  898. razer_error("synapse: Failed to get firmware version\n");
  899. goto err_release;
  900. }
  901. err = synapse_read_config_from_hw(s);
  902. if (err) {
  903. razer_error("synapse: "
  904. "Failed to read the configuration from hardware\n");
  905. goto err_release;
  906. }
  907. m->get_fw_version = synapse_get_fw_version;
  908. m->commit = synapse_commit;
  909. m->global_get_freq = synapse_global_get_freq;
  910. m->global_set_freq = synapse_global_set_freq;
  911. m->nr_profiles = SYNAPSE_NR_PROFILES;
  912. m->get_profiles = synapse_get_profiles;
  913. m->get_active_profile = synapse_get_active_profile;
  914. m->set_active_profile = synapse_set_active_profile;
  915. m->supported_axes = synapse_supported_axes;
  916. m->supported_resolutions = synapse_supported_resolutions;
  917. m->supported_freqs = synapse_supported_freqs;
  918. m->supported_dpimappings = synapse_supported_dpimappings;
  919. m->supported_buttons = synapse_supported_buttons;
  920. m->supported_button_functions = synapse_supported_button_functions;
  921. err = synapse_do_commit(s);
  922. if (err) {
  923. razer_error("synapse: Failed to commit initial settings\n");
  924. goto err_release;
  925. }
  926. m->release(m);
  927. return 0;
  928. err_release:
  929. m->release(m);
  930. err_free:
  931. razer_free(s, sizeof(*s));
  932. return err;
  933. }
  934. void razer_synapse_exit(struct razer_mouse *m)
  935. {
  936. struct razer_synapse *s = m->drv_data;
  937. razer_free(s, sizeof(*s));
  938. m->drv_data = NULL;
  939. }
  940. void * razer_synapse_get_drv_data(struct razer_mouse *m)
  941. {
  942. struct razer_synapse *s = m->drv_data;
  943. return s->drv_data;
  944. }
  945. int razer_synapse_set_led_name(struct razer_mouse *m,
  946. unsigned int index,
  947. const char *name)
  948. {
  949. struct razer_synapse *s = m->drv_data;
  950. if (index >= ARRAY_SIZE(s->led_names))
  951. return -EINVAL;
  952. razer_strlcpy(s->led_names[index].name, name,
  953. sizeof(s->led_names[index].name));
  954. return 0;
  955. }
  956. const char * razer_synapse_get_serial(struct razer_mouse *m)
  957. {
  958. struct razer_synapse *s = m->drv_data;
  959. return s->serial;
  960. }