1 /*
2  * This file is part of OpenCorsairLink.
3  * Copyright (C) 2017-2019  Sean Nelson <audiohacked@gmail.com>
4 
5  * OpenCorsairLink is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * any later version.
9 
10  * OpenCorsairLink is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14 
15  * You should have received a copy of the GNU General Public License
16  * along with OpenCorsairLink.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "device.h"
20 #include "driver.h"
21 #include "lowlevel/asetek.h"
22 #include "print.h"
23 #include "protocol/asetekpro.h"
24 
25 #include <errno.h>
26 #include <libusb.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 
32 int
corsairlink_asetekpro_pump_mode_read(struct corsair_device_info * dev,struct libusb_device_handle * handle,struct pump_control * ctrl)33 corsairlink_asetekpro_pump_mode_read(
34     struct corsair_device_info* dev,
35     struct libusb_device_handle* handle,
36     struct pump_control* ctrl )
37 {
38     int rr;
39     uint8_t response[64];
40     uint8_t commands[64];
41 
42     memset( response, 0, sizeof( response ) );
43     memset( commands, 0, sizeof( commands ) );
44 
45     msg_debug("function:corsairlink_asetekpro_pump_mode_read file: protocol/asetekpro/pump.c\n");
46 
47 
48     commands[0] = AsetekProPumpModeRead;
49 
50     rr = dev->driver->write( handle, dev->write_endpoint, commands, 1 );
51     rr = dev->driver->read( handle, dev->read_endpoint, response, 4 );
52 
53     msg_debug("pump mode response = %02X %02X %02X %02X\n", response[0], response[1],
54 		response[2], response[3]
55     );
56 
57     if ( response[0] != AsetekProPumpModeRead || response[1] != 0x12 || response[2] != 0x34 )
58     {
59         msg_debug2( "Bad Response for astekpro pump mode\n" );
60     }
61 
62     ctrl->mode = response[3];
63 
64     return rr;
65 }
66 
67 int
corsairlink_asetekpro_pump_mode_quiet(struct corsair_device_info * dev,struct libusb_device_handle * handle,struct pump_control * ctrl)68 corsairlink_asetekpro_pump_mode_quiet(
69     struct corsair_device_info* dev,
70     struct libusb_device_handle* handle,
71     struct pump_control* ctrl )
72 {
73     int rr;
74     uint8_t response[64];
75     uint8_t commands[64];
76     memset( response, 0, sizeof( response ) );
77     memset( commands, 0, sizeof( commands ) );
78 
79     commands[0] = AsetekProPumpModeWrite;
80     commands[1] = AsetekProPumpQuiet;
81 
82     rr = dev->driver->write( handle, dev->write_endpoint, commands, 2 );
83     rr = dev->driver->read( handle, dev->read_endpoint, response, 5 );
84 
85     msg_debug(
86         "pump write quiet response = %02X %02X %02X %02X %02X\n",
87 	response[0], response[1], response[2], response[3], response[4] );
88 
89     rr = corsairlink_asetekpro_pump_mode_read(dev, handle, ctrl);
90     return rr;
91 }
92 
93 int
corsairlink_asetekpro_pump_mode_balanced(struct corsair_device_info * dev,struct libusb_device_handle * handle,struct pump_control * ctrl)94 corsairlink_asetekpro_pump_mode_balanced(
95     struct corsair_device_info* dev,
96     struct libusb_device_handle* handle,
97     struct pump_control* ctrl )
98 {
99     int rr;
100     uint8_t response[64];
101     uint8_t commands[64];
102     memset( response, 0, sizeof( response ) );
103     memset( commands, 0, sizeof( commands ) );
104 
105     commands[0] = AsetekProPumpModeWrite;
106     commands[1] = AsetekProPumpBalanced;
107 
108     rr = dev->driver->write( handle, dev->write_endpoint, commands, 2 );
109     rr = dev->driver->read( handle, dev->read_endpoint, response, 5 );
110 
111     msg_debug(
112         "pump write balanced response = %02X %02X %02X %02X %02X\n",
113 	response[0], response[1], response[2], response[3], response[4] );
114 
115     rr = corsairlink_asetekpro_pump_mode_read(dev, handle, ctrl);
116     return rr;
117 }
118 
119 int
corsairlink_asetekpro_pump_mode_performance(struct corsair_device_info * dev,struct libusb_device_handle * handle,struct pump_control * ctrl)120 corsairlink_asetekpro_pump_mode_performance(
121     struct corsair_device_info* dev,
122     struct libusb_device_handle* handle,
123     struct pump_control* ctrl )
124 {
125     int rr;
126     uint8_t response[64];
127     uint8_t commands[64];
128     memset( response, 0, sizeof( response ) );
129     memset( commands, 0, sizeof( commands ) );
130 
131     commands[0] = AsetekProPumpModeWrite;
132     commands[1] = AsetekProPumpPerformance;
133 
134     rr = dev->driver->write( handle, dev->write_endpoint, commands, 2 );
135     rr = dev->driver->read( handle, dev->read_endpoint, response, 5 );
136 
137     msg_debug(
138         "pump write performance response = %02X %02X %02X %02X %02X\n",
139 	response[0], response[1], response[2], response[3], response[4] );
140 
141     rr = corsairlink_asetekpro_pump_mode_read(dev, handle, ctrl);
142     return rr;
143 }
144 
145 int
corsairlink_asetekpro_pump_speed(struct corsair_device_info * dev,struct libusb_device_handle * handle,struct pump_control * ctrl)146 corsairlink_asetekpro_pump_speed(
147     struct corsair_device_info* dev,
148     struct libusb_device_handle* handle,
149     struct pump_control* ctrl )
150 {
151     int rr;
152     uint8_t response[64];
153     uint8_t commands[64];
154     memset( response, 0, sizeof( response ) );
155     memset( commands, 0, sizeof( commands ) );
156 
157     commands[0] = AsetekProPumpSpeedRead;
158 
159     rr = dev->driver->write( handle, dev->write_endpoint, commands, 1 );
160     rr = dev->driver->read( handle, dev->read_endpoint, response, 5 );
161 
162     msg_debug(
163         "pump speed response = %02X %02X %02X %02X %02X\n", response[0], response[1], response[2], response[3],
164         response[4] );
165 
166     if ( response[0] != AsetekProPumpSpeedRead || response[1] != 0x12 || response[2] != 0x34 )
167     {
168         msg_debug2( "Bad Response for astekpro pump speed\n" );
169     }
170 
171     ctrl->speed = ( response[3] << 8 ) + response[4];
172     ctrl->max_speed = 0;
173 
174     return rr;
175 }
176