xref: /aosp_15_r20/external/flashrom/ch347_spi.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1 /*
2  * This file is part of the flashrom project.
3  *
4  * Copyright (C) 2022 Nicholas Chin <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 
17 #include <string.h>
18 #include <stdlib.h>
19 #include <libusb.h>
20 #include "platform.h"
21 #include "programmer.h"
22 #include "flash.h"
23 
24 #define CH347_CMD_SPI_SET_CFG	0xC0
25 #define CH347_CMD_SPI_CS_CTRL	0xC1
26 #define CH347_CMD_SPI_OUT_IN	0xC2
27 #define CH347_CMD_SPI_IN	0xC3
28 #define CH347_CMD_SPI_OUT	0xC4
29 #define CH347_CMD_SPI_GET_CFG	0xCA
30 
31 #define CH347_CS_ASSERT		0x00
32 #define CH347_CS_DEASSERT	0x40
33 #define CH347_CS_CHANGE		0x80
34 #define CH347_CS_IGNORE		0x00
35 
36 #define WRITE_EP	0x06
37 #define READ_EP 	0x86
38 
39 #define CH347T_IFACE 2
40 #define CH347F_IFACE 4
41 
42 /* The USB descriptor says the max transfer size is 512 bytes, but the
43  * vendor driver only seems to transfer a maximum of 510 bytes at once,
44  * leaving 507 bytes for data as the command + length take up 3 bytes
45  */
46 #define CH347_PACKET_SIZE 510
47 #define CH347_MAX_DATA_LEN (CH347_PACKET_SIZE - 3)
48 
49 struct ch347_spi_data {
50 	struct libusb_device_handle *handle;
51 	int interface;
52 };
53 
54 struct device_speeds {
55 	const char *name;
56 	const int divisor;
57 };
58 
59 /* TODO: Add support for HID mode */
60 static const struct dev_entry devs_ch347_spi[] = {
61 	{0x1A86, 0x55DB, OK, "QinHeng Electronics", "USB To UART+SPI+I2C"},   /* CH347T */
62 	{0x1A86, 0x55DE, OK, "QinHeng Electronics", "USB To UART+SPI+I2C"},   /* CH347F */
63 	{0}
64 };
65 
66 static int ch347_interface[] = {
67 	CH347T_IFACE,
68 	CH347F_IFACE,
69 };
70 
71 static const struct device_speeds spispeeds[] = {
72 	{"60M",     0},
73 	{"30M",     1},
74 	{"15M",     2},
75 	{"7.5M",    3},
76 	{"3.75M",   4},
77 	{"1.875M",  5},
78 	{"937.5K",  6},
79 	{"468.75K", 7},
80 	{NULL,      0}
81 };
82 
ch347_spi_shutdown(void * data)83 static int ch347_spi_shutdown(void *data)
84 {
85 	struct ch347_spi_data *ch347_data = data;
86 	int spi_interface = ch347_data->interface;
87 	libusb_release_interface(ch347_data->handle, spi_interface);
88 	libusb_attach_kernel_driver(ch347_data->handle, spi_interface);
89 	libusb_close(ch347_data->handle);
90 	libusb_exit(NULL);
91 	free(data);
92 	return 0;
93 }
94 
ch347_cs_control(struct ch347_spi_data * ch347_data,uint8_t cs1,uint8_t cs2)95 static int ch347_cs_control(struct ch347_spi_data *ch347_data, uint8_t cs1, uint8_t cs2)
96 {
97 	uint8_t cmd[13] = {
98 		[0] = CH347_CMD_SPI_CS_CTRL,
99 		/* payload length, uint16 LSB: 10 */
100 		[1] = 10,
101 		[3] = cs1,
102 		[8] = cs2
103 	};
104 
105 	int32_t ret = libusb_bulk_transfer(ch347_data->handle, WRITE_EP, cmd, sizeof(cmd), NULL, 1000);
106 	if (ret < 0) {
107 		msg_perr("Could not change CS!\n");
108 		return -1;
109 	}
110 	return 0;
111 }
112 
113 
ch347_write(struct ch347_spi_data * ch347_data,unsigned int writecnt,const uint8_t * writearr)114 static int ch347_write(struct ch347_spi_data *ch347_data, unsigned int writecnt, const uint8_t *writearr)
115 {
116 	unsigned int data_len;
117 	int packet_len;
118 	int transferred;
119 	int ret;
120 	uint8_t resp_buf[4] = {0};
121 	uint8_t buffer[CH347_PACKET_SIZE] = {0};
122 	unsigned int bytes_written = 0;
123 
124 	while (bytes_written < writecnt) {
125 		data_len = min(CH347_MAX_DATA_LEN, writecnt - bytes_written );
126 		packet_len = data_len + 3;
127 
128 		buffer[0] = CH347_CMD_SPI_OUT;
129 		buffer[1] = (data_len) & 0xFF;
130 		buffer[2] = ((data_len) & 0xFF00) >> 8;
131 		memcpy(buffer + 3, writearr + bytes_written, data_len);
132 
133 		ret = libusb_bulk_transfer(ch347_data->handle, WRITE_EP, buffer, packet_len, &transferred, 1000);
134 		if (ret < 0 || transferred != packet_len) {
135 			msg_perr("Could not send write command\n");
136 			return -1;
137 		}
138 
139 		ret = libusb_bulk_transfer(ch347_data->handle, READ_EP, resp_buf, sizeof(resp_buf), NULL, 1000);
140 		if (ret < 0) {
141 			msg_perr("Could not receive write command response\n");
142 			return -1;
143 		}
144 		bytes_written += data_len;
145 	}
146 	return 0;
147 }
148 
ch347_read(struct ch347_spi_data * ch347_data,unsigned int readcnt,uint8_t * readarr)149 static int ch347_read(struct ch347_spi_data *ch347_data, unsigned int readcnt, uint8_t *readarr)
150 {
151 	uint8_t *read_ptr = readarr;
152 	int ret;
153 	int transferred;
154 	unsigned int bytes_read = 0;
155 	uint8_t buffer[CH347_PACKET_SIZE] = {0};
156 	uint8_t command_buf[7] = {
157 		[0] = CH347_CMD_SPI_IN,
158 		[1] = 4,
159 		[2] = 0,
160 		[3] = readcnt & 0xFF,
161 		[4] = (readcnt & 0xFF00) >> 8,
162 		[5] = (readcnt & 0xFF0000) >> 16,
163 		[6] = (readcnt & 0xFF000000) >> 24
164 	};
165 
166 	ret = libusb_bulk_transfer(ch347_data->handle, WRITE_EP, command_buf, sizeof(command_buf), &transferred, 1000);
167 	if (ret < 0 || transferred != sizeof(command_buf)) {
168 		msg_perr("Could not send read command\n");
169 		return -1;
170 	}
171 
172 	while (bytes_read < readcnt) {
173 		ret = libusb_bulk_transfer(ch347_data->handle, READ_EP, buffer, CH347_PACKET_SIZE, &transferred, 1000);
174 		if (ret < 0) {
175 			msg_perr("Could not read data\n");
176 			return -1;
177 		}
178 		if (transferred > CH347_PACKET_SIZE) {
179 			msg_perr("libusb bug: bytes received overflowed buffer\n");
180 			return -1;
181 		}
182 		/* Response: u8 command, u16 data length, then the data that was read */
183 		if (transferred < 3) {
184 			msg_perr("CH347 returned an invalid response to read command\n");
185 			return -1;
186 		}
187 		int ch347_data_length = read_le16(buffer, 1);
188 		if (transferred - 3 < ch347_data_length) {
189 			msg_perr("CH347 returned less data than data length header indicates\n");
190 			return -1;
191 		}
192 		bytes_read += ch347_data_length;
193 		if (bytes_read > readcnt) {
194 			msg_perr("CH347 returned more bytes than requested\n");
195 			return -1;
196 		}
197 		memcpy(read_ptr, buffer + 3, ch347_data_length);
198 		read_ptr += ch347_data_length;
199 	}
200 	return 0;
201 }
202 
ch347_spi_send_command(const struct flashctx * flash,unsigned int writecnt,unsigned int readcnt,const unsigned char * writearr,unsigned char * readarr)203 static int ch347_spi_send_command(const struct flashctx *flash, unsigned int writecnt,
204 		unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr)
205 {
206 	struct ch347_spi_data *ch347_data = flash->mst->spi.data;
207 	int ret = 0;
208 
209 	ch347_cs_control(ch347_data, CH347_CS_ASSERT | CH347_CS_CHANGE, CH347_CS_IGNORE);
210 	if (writecnt) {
211 		ret = ch347_write(ch347_data, writecnt, writearr);
212 		if (ret < 0) {
213 			msg_perr("CH347 write error\n");
214 			return -1;
215 		}
216 	}
217 	if (readcnt) {
218 		ret = ch347_read(ch347_data, readcnt, readarr);
219 		if (ret < 0) {
220 			msg_perr("CH347 read error\n");
221 			return -1;
222 		}
223 	}
224 	ch347_cs_control(ch347_data, CH347_CS_DEASSERT | CH347_CS_CHANGE, CH347_CS_IGNORE);
225 
226 	return 0;
227 }
228 
ch347_spi_config(struct ch347_spi_data * ch347_data,uint8_t divisor)229 static int32_t ch347_spi_config(struct ch347_spi_data *ch347_data, uint8_t divisor)
230 {
231 	int32_t ret;
232 	uint8_t buff[29] = {
233 		[0] = CH347_CMD_SPI_SET_CFG,
234 		[1] = (sizeof(buff) - 3) & 0xFF,
235 		[2] = ((sizeof(buff) - 3) & 0xFF00) >> 8,
236 		/* Not sure what these two bytes do, but the vendor
237 		 * drivers seem to unconditionally set these values
238 		 */
239 		[5] = 4,
240 		[6] = 1,
241 		/* Clock polarity: bit 1 */
242 		[9] = 0,
243 		/* Clock phase: bit 0 */
244 		[11] = 0,
245 		/* Another mystery byte */
246 		[14] = 2,
247 		/* Clock divisor: bits 5:3 */
248 		[15] = (divisor & 0x7) << 3,
249 		/* Bit order: bit 7, 0=MSB */
250 		[17] = 0,
251 		/* Yet another mystery byte */
252 		[19] = 7,
253 		/* CS polarity: bit 7 CS2, bit 6 CS1. 0 = active low */
254 		[24] = 0
255 	};
256 
257 	ret = libusb_bulk_transfer(ch347_data->handle, WRITE_EP, buff, sizeof(buff), NULL, 1000);
258 	if (ret < 0) {
259 		msg_perr("Could not configure SPI interface\n");
260 	}
261 
262 	/* FIXME: Not sure if the CH347 sends error responses for
263 	 * invalid config data, if so the code should check
264 	 */
265 	ret = libusb_bulk_transfer(ch347_data->handle, READ_EP, buff, sizeof(buff), NULL, 1000);
266 	if (ret < 0) {
267 		msg_perr("Could not receive configure SPI command response\n");
268 	}
269 	return ret;
270 }
271 
272 static const struct spi_master spi_master_ch347_spi = {
273 	.features	= SPI_MASTER_4BA,
274 	.max_data_read	= MAX_DATA_READ_UNLIMITED,
275 	.max_data_write	= MAX_DATA_WRITE_UNLIMITED,
276 	.command	= ch347_spi_send_command,
277 	.read		= default_spi_read,
278 	.write_256	= default_spi_write_256,
279 	.write_aai	= default_spi_write_aai,
280 	.shutdown	= ch347_spi_shutdown,
281 };
282 
283 /* Largely copied from ch341a_spi.c */
ch347_spi_init(const struct programmer_cfg * cfg)284 static int ch347_spi_init(const struct programmer_cfg *cfg)
285 {
286 	char *arg;
287 	uint16_t vid = devs_ch347_spi[0].vendor_id;
288 	uint16_t pid = 0;
289 	int index = 0;
290 	int speed_index = 2;
291 	struct ch347_spi_data *ch347_data = calloc(1, sizeof(*ch347_data));
292 	if (!ch347_data) {
293 		msg_perr("Could not allocate space for SPI data\n");
294 		return 1;
295 	}
296 
297 	int32_t ret = libusb_init(NULL);
298 	if (ret < 0) {
299 		msg_perr("Could not initialize libusb!\n");
300 		free(ch347_data);
301 		return 1;
302 	}
303 	/* Enable information, warning, and error messages (only). */
304 #if LIBUSB_API_VERSION < 0x01000106
305 	libusb_set_debug(NULL, 3);
306 #else
307 	libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
308 #endif
309 	while (devs_ch347_spi[index].vendor_id != 0) {
310 		vid = devs_ch347_spi[index].vendor_id;
311 		pid = devs_ch347_spi[index].device_id;
312 		ch347_data->handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
313 		if (ch347_data->handle) {
314 			ch347_data->interface = ch347_interface[index];
315 			break;
316 		}
317 		index++;
318 	}
319 	if (!ch347_data->handle) {
320 		msg_perr("Couldn't find CH347.\n");
321 		free(ch347_data);
322 		return 1;
323 	}
324 
325 	ret = libusb_detach_kernel_driver(ch347_data->handle, ch347_data->interface);
326 	if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND)
327 		msg_pwarn("Cannot detach the existing USB driver. Claiming the interface may fail. %s\n",
328 			libusb_error_name(ret));
329 
330 	ret = libusb_claim_interface(ch347_data->handle, ch347_data->interface);
331 	if (ret != 0) {
332 		msg_perr("Failed to claim interface %d: '%s'\n", ch347_data->interface, libusb_error_name(ret));
333 		goto error_exit;
334 	}
335 
336 	struct libusb_device *dev;
337 	if (!(dev = libusb_get_device(ch347_data->handle))) {
338 		msg_perr("Failed to get device from device handle.\n");
339 		goto error_exit;
340 	}
341 
342 	struct libusb_device_descriptor desc;
343 	ret = libusb_get_device_descriptor(dev, &desc);
344 	if (ret < 0) {
345 		msg_perr("Failed to get device descriptor: '%s'\n", libusb_error_name(ret));
346 		goto error_exit;
347 	}
348 
349 	msg_pdbg("Device revision is %d.%01d.%01d\n",
350 		(desc.bcdDevice >> 8) & 0x00FF,
351 		(desc.bcdDevice >> 4) & 0x000F,
352 		(desc.bcdDevice >> 0) & 0x000F);
353 
354 	/* set CH347 clock division */
355 	arg = extract_programmer_param_str(cfg, "spispeed");
356 	if (arg) {
357 		for (speed_index = 0; spispeeds[speed_index].name; speed_index++) {
358 			if (!strncasecmp(spispeeds[speed_index].name, arg, strlen(spispeeds[speed_index].name))) {
359 				break;
360 			}
361 		}
362 	}
363 	if (!spispeeds[speed_index].name || !arg) {
364 		msg_perr("Unknown value of spispeed parameter, using default 15MHz clock spi.\n");
365 		speed_index = 2;
366 	}
367 	free(arg);
368 	if (ch347_spi_config(ch347_data, spispeeds[speed_index].divisor) < 0) {
369 		goto error_exit;
370 	} else {
371 		msg_pinfo("CH347 SPI clock set to %sHz.\n", spispeeds[speed_index].name);
372 	}
373 
374 	return register_spi_master(&spi_master_ch347_spi, ch347_data);
375 
376 error_exit:
377 	ch347_spi_shutdown(ch347_data);
378 	return 1;
379 }
380 
381 const struct programmer_entry programmer_ch347_spi = {
382 	.name		= "ch347_spi",
383 	.type		= USB,
384 	.devs.dev	= devs_ch347_spi,
385 	.init		= ch347_spi_init,
386 };