summaryrefslogtreecommitdiff
path: root/chip/stm32/usb_spi.h
blob: 7ca5a57a7a82774d1f4bd5620f73c14b77afdf13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
/* Copyright 2014 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef __CROS_EC_USB_SPI_H
#define __CROS_EC_USB_SPI_H

/* STM32 USB SPI driver for Chrome EC */

#include "compile_time_macros.h"
#include "hooks.h"
#include "usb_descriptor.h"
#include "usb_hw.h"

/*
 * This SPI flash programming interface is designed to talk to a Chromium OS
 * device over a Raiden USB connection.
 *
 * USB SPI Version 2:
 *
 *     USB SPI version 2 adds support for larger SPI transfers and reduces the
 *     number of USB packets transferred. This improves performance when
 *     writing or reading large chunks of memory from a device. A packet ID
 *     field is used to distinguish the different packet types. Additional
 *     packets have been included to query the device for its configuration
 *     allowing the interface to be used on platforms with different SPI
 *     limitations. It includes validation and a packet to recover from the
 *     situations where USB packets are lost.
 *
 *     The USB SPI hosts which support packet version 2 are backwards compatible
 *     and use the bInterfaceProtocol field to identify which type of target
 *     they are connected to.
 *
 *
 * Example: USB SPI request with 128 byte write and 0 byte read.
 *
 *      Packet #1 Host to Device:
 *           packet id   = USB_SPI_PKT_ID_CMD_TRANSFER_START
 *           write count = 128
 *           read count  = 0
 *           payload     = First 58 bytes from the write buffer,
 *                            starting at byte 0 in the buffer
 *           packet size = 64 bytes
 *
 *      Packet #2 Host to Device:
 *           packet id   = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE
 *           data index  = 58
 *           payload     = Next 60 bytes from the write buffer,
 *                           starting at byte 58 in the buffer
 *           packet size = 64 bytes
 *
 *      Packet #3 Host to Device:
 *           packet id   = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE
 *           data index  = 118
 *           payload     = Next 10 bytes from the write buffer,
 *                           starting at byte 118 in the buffer
 *           packet size = 14 bytes
 *
 *      Packet #4 Device to Host:
 *           packet id   = USB_SPI_PKT_ID_RSP_TRANSFER_START
 *           status code = status code from device
 *           payload     = 0 bytes
 *           packet size = 4 bytes
 *
 * Example: USB SPI request with 2 byte write and 100 byte read.
 *
 *      Packet #1 Host to Device:
 *           packet id   = USB_SPI_PKT_ID_CMD_TRANSFER_START
 *           write count = 2
 *           read count  = 100
 *           payload     = The 2 byte write buffer
 *           packet size = 8 bytes
 *
 *      Packet #2 Device to Host:
 *           packet id   = USB_SPI_PKT_ID_RSP_TRANSFER_START
 *           status code = status code from device
 *           payload     = First 60 bytes from the read buffer,
 *                            starting at byte 0 in the buffer
 *           packet size = 64 bytes
 *
 *      Packet #3 Device to Host:
 *           packet id   = USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE
 *           data index  = 60
 *           payload     = Next 40 bytes from the read buffer,
 *                           starting at byte 60 in the buffer
 *           packet size = 44 bytes
 *
 *
 * Message Packets:
 *
 * Command Start Packet (Host to Device):
 *
 *      Start of the USB SPI command, contains the number of bytes to write
 *      and read on SPI and up to the first 58 bytes of write payload.
 *      Longer writes will use the continue packets with packet id
 *      USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE to transmit the remaining data.
 *
 *     +----------------+------------------+-----------------+---------------+
 *     | packet id : 2B | write count : 2B | read count : 2B | w.p. : <= 58B |
 *     +----------------+------------------+-----------------+---------------+
 *
 *     packet id:     2 byte enum defined by packet_id_type
 *                    Valid values packet id = USB_SPI_PKT_ID_CMD_TRANSFER_START
 *
 *     write count:   2 byte, zero based count of bytes to write
 *
 *     read count:    2 byte, zero based count of bytes to read
 *                    UINT16_MAX indicates full duplex mode with a read count
 *                    equal to the write count.
 *
 *     write payload: Up to 58 bytes of data to write to SPI, the total
 *                    length of all TX packets must match write count.
 *                    Due to data alignment constraints, this must be an
 *                    even number of bytes unless this is the final packet.
 *
 *
 * Response Start Packet (Device to Host):
 *
 *      Start of the USB SPI response, contains the status code and up to
 *      the first 60 bytes of read payload. Longer reads will use the
 *      continue packets with packet id USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE
 *      to transmit the remaining data.
 *
 *     +----------------+------------------+-----------------------+
 *     | packet id : 2B | status code : 2B | read payload : <= 60B |
 *     +----------------+------------------+-----------------------+
 *
 *     packet id:     2 byte enum defined by packet_id_type
 *                    Valid values packet id = USB_SPI_PKT_ID_RSP_TRANSFER_START
 *
 *     status code: 2 byte status code
 *         0x0000: Success
 *         0x0001: SPI timeout
 *         0x0002: Busy, try again
 *             This can happen if someone else has acquired the shared memory
 *             buffer that the SPI driver uses as /dev/null
 *         0x0003: Write count invalid. The byte limit is platform specific
 *             and is set during the configure USB SPI response.
 *         0x0004: Read count invalid. The byte limit is platform specific
 *             and is set during the configure USB SPI response.
 *         0x0005: The SPI bridge is disabled.
 *         0x0006: The RX continue packet's data index is invalid. This
 *             can indicate a USB transfer failure to the device.
 *         0x0007: The RX endpoint has received more data than write count.
 *             This can indicate a USB transfer failure to the device.
 *         0x0008: An unexpected packet arrived that the device could not
 *             process.
 *         0x0009: The device does not support full duplex mode.
 *         0x000A: Requested serial flash mode not supported
 *         0x8000: Unknown error mask
 *             The bottom 15 bits will contain the bottom 15 bits from the EC
 *             error code.
 *
 *     read payload: Up to 60 bytes of data read from SPI, the total
 *                   length of all RX packets must match read count
 *                   unless an error status was returned. Due to data
 *                   alignment constraints, this must be a even number
 *                   of bytes unless this is the final packet.
 *
 *
 * Continue Packet (Bidirectional):
 *
 *      Continuation packet for the writes and read buffers. Both packets
 *      follow the same format, a data index counts the number of bytes
 *      previously transferred in the USB SPI transfer and a payload of bytes.
 *
 *     +----------------+-----------------+-------------------------------+
 *     | packet id : 2B | data index : 2B | write / read payload : <= 60B |
 *     +----------------+-----------------+-------------------------------+
 *
 *     packet id:     2 byte enum defined by packet_id_type
 *                    The packet id has 2 values depending on direction:
 *                    packet id = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE
 *                    indicates the packet is being transmitted from the host
 *                    to the device and contains SPI write payload.
 *                    packet id = USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE
 *                    indicates the packet is being transmitted from the device
 *                    to the host and contains SPI read payload.
 *
 *     data index:    The data index indicates the number of bytes in the
 *                    read or write buffers that have already been transmitted.
 *                    It is used to validate that no packets have been dropped
 *                    and that the prior packets have been correctly decoded.
 *                    This value corresponds to the offset bytes in the buffer
 *                    to start copying the payload into.
 *
 *     read and write payload:
 *                    Contains up to 60 bytes of payload data to transfer to
 *                    the SPI write buffer or from the SPI read buffer.
 *
 *
 * Command Get Configuration Packet (Host to Device):
 *
 *      Query the device to request it's USB SPI configuration indicating
 *      the number of bytes it can write and read.
 *
 *     +----------------+
 *     | packet id : 2B |
 *     +----------------+
 *
 *     packet id:     2 byte enum USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG
 *
 * Response Configuration Packet (Device to Host):
 *
 *      Response packet form the device to report the maximum write and
 *      read size supported by the device.
 *
 *     +----------------+----------------+---------------+----------------+
 *     | packet id : 2B | max write : 2B | max read : 2B | feature bitmap |
 *     +----------------+----------------+---------------+----------------+
 *
 *     packet id:         2 byte enum USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG
 *
 *     max write count:   2 byte count of the maximum number of bytes
 *                        the device can write to SPI in one transaction.
 *
 *     max read count:    2 byte count of the maximum number of bytes
 *                        the device can read from SPI in one transaction.
 *
 *     feature bitmap:    Bitmap of supported features.
 *                        BIT(0): Full duplex SPI mode is supported
 *                        BIT(1): Serial flash extensions are supported
 *                        BIT(2): Dual mode flash supported
 *                        BIT(3): Quad mode flash supported
 *                        BIT(4): Octo mode flash supported
 *                        BIT(5): Double transfer rate supported
 *                        BIT(6:15): Reserved for future use
 *
 * Command Restart Response Packet (Host to Device):
 *
 *      Command to restart the response transfer from the device. This enables
 *      the host to recover from a lost packet when reading the response
 *      without restarting the SPI transfer.
 *
 *     +----------------+
 *     | packet id : 2B |
 *     +----------------+
 *
 *     packet id:         2 byte enum USB_SPI_PKT_ID_CMD_RESTART_RESPONSE
 *
 * Command chip select Packet (Host to Device):
 *
 *     +----------------+-------------+
 *     | packet id : 2B | action : 2B |
 *     +----------------+-------------+
 *
 *     packet id:         2 byte enum USB_SPI_PKT_ID_CMD_CHIP_SELECT
 *
 *     action:            2 byte, current options:
 *                            0: Deassert chip select
 *                            1: Assert chip select
 *
 * Response chip select Packet (Device to Host):
 *
 *     +----------------+------------------+
 *     | packet id : 2B | status code : 2B |
 *     +----------------+------------------+
 *
 *     packet id:     2 byte enum USB_SPI_PKT_ID_RSP_CHIP_SELECT
 *
 *     status code: 2 byte status code
 *         0x0000: Success
 *         others: Error
 *
 * Flash Command Start Packet (Host to Device):
 *
 *      Start of the USB serial flash SPI command, contains the number of
 *      bytes to write or read on SPI and up to the first 58 bytes of write
 *      payload.  Longer writes will use the continue packets with packet id
 *      USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE to transmit the remaining data.
 *
 *      The reading or writing of the "main" data will be preceded by an
 *      short sequence of opcode, optional address, optional "alternate data",
 *      and optional 'dummy cycles" on the SPI bus.  Flags indicate how many
 *      bytes of each stage to send, and whether to use advanced features such
 *      as dual or quad signal lanes for each stage of the transfer".
 *
 *      The indicated number of opcode, address and alternate bytes will be
 *      the first in the "write payload".  The "count" field will contain the
 *      number of data bytes to be written/read after the opcode, address and
 *      alternate bytes.
 *
 *      This request is only supported if bit 1 of the "feature bitmap"
 *      indicates that serial flash extensions are supported.  Implementations
 *      will further advertise whether they support dual, quad or octo modes, if
 *      none of these are supported, then support for "dummy cycles" is not
 *      guaranteed either, and callers should use one or two bytes of "extra
 *      address data" for dummy cycles, address length can be up to 7 bytes for
 *      this reason.
 *
 *     +----------------+------------+------------+---------------+
 *     | packet id : 2B | count : 2B | flags : 4B | w.p. : <= 56B |
 *     +----------------+------------+------------+---------------+
 *
 *     packet id:     2 byte enum defined by packet_id_type
 *                    Valid values packet id =
 *                    USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START
 *
 *     count:         2 byte, zero based count of bytes to read or write
 *
 *     flags:         4 byte, flags
 *          bits 0:1  opcode length in bytes (0-3)
 *          bits 2:4  address length in bytes (0-7)
 *          bits 5:6  mode (0: 1-1-1, 1: 1-1-N, 2: 1-N-N, 3: N-N-N)
 *          bits 7:8  width (0: N=1, 1: N=2, 2: N=4, 3: N=8)
 *             bit 9  double transfer rate (in phases marked as N)
 *        bits 10:14  number of dummy cycles (0-31)
 *        bits 15:27  reserved, must be zero
 *            bit 28  write to be preceded by "write enable"
 *            bit 29  write to be followed by polling of JEDEC "busy bit"
 *            bit 30  reserved, must be zero
 *            bit 31  read (0) / write (1)
 *
 *     write payload: Up to 56 bytes of data to write to SPI, the total length
 *                    of all TX packets must match: write enable length (zero or
 *                    one, depending on bit 27) + opcode length + address length
 *                    + count, (the last one only if bit 31 indicates a write
 *                    operation). Due to data alignment constraints, this must
 *                    be an even number of bytes unless this is the final
 *                    packet.
 *
 *
 * USB Error Codes:
 *
 * send_command return codes have the following format:
 *
 *     0x00000:         Status code success.
 *     0x00001-0x0FFFF: Error code returned by the USB SPI device.
 *     0x10001-0x1FFFF: USB SPI Host error codes
 *     0x20001-0x20063  Lower bits store the positive value representation
 *                      of the libusb_error enum. See the libusb documentation:
 *                      http://libusb.sourceforge.net/api-1.0/group__misc.html
 */

#define USB_SPI_FULL_DUPLEX_ENABLED (UINT16_MAX)

#define USB_SPI_PAYLOAD_SIZE_V2_START (58)

#define USB_SPI_PAYLOAD_SIZE_V2_RESPONSE (60)

#define USB_SPI_PAYLOAD_SIZE_V2_CONTINUE (60)

#define USB_SPI_PAYLOAD_SIZE_V2_ERROR (60)

#define USB_SPI_PAYLOAD_SIZE_FLASH_START (56)

#define USB_SPI_MIN_PACKET_SIZE (2)

/*
 * Values used in spi_device_t.usb_flags
 */

/* Is the USB host allowed to operate on SPI device. */
#define USB_SPI_ENABLED BIT(0)
/* Use board specific SPI driver when forwarding to this device. */
#define USB_SPI_CUSTOM_SPI_DEVICE BIT(1)
/* This SPI device supports dual lane mode. */
#define USB_SPI_FLASH_DUAL_SUPPORT BIT(2)
/* This SPI device supports four lane mode. */
#define USB_SPI_FLASH_QUAD_SUPPORT BIT(3)
/* This SPI device supports eight lane mode. */
#define USB_SPI_FLASH_OCTO_SUPPORT BIT(4)
/* This SPI device supports double transfer rate (data on both clock edges). */
#define USB_SPI_FLASH_DTR_SUPPORT BIT(5)

enum packet_id_type {
	/* Request USB SPI configuration data from device. */
	USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG = 0,
	/* USB SPI configuration data from device. */
	USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG = 1,
	/*
	 * Start a USB SPI transfer specifying number of bytes to write,
	 * read and deliver first packet of data to write.
	 */
	USB_SPI_PKT_ID_CMD_TRANSFER_START = 2,
	/* Additional packets containing write payload. */
	USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE = 3,
	/*
	 * Request the device restart the response enabling us to recover
	 * from packet loss without another SPI transfer.
	 */
	USB_SPI_PKT_ID_CMD_RESTART_RESPONSE = 4,
	/*
	 * First packet of USB SPI response with the status code
	 * and read payload if it was successful.
	 */
	USB_SPI_PKT_ID_RSP_TRANSFER_START = 5,
	/* Additional packets containing read payload. */
	USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE = 6,
	/*
	 * Request assertion or deassertion of chip select
	 */
	USB_SPI_PKT_ID_CMD_CHIP_SELECT = 7,
	/* Response to above request. */
	USB_SPI_PKT_ID_RSP_CHIP_SELECT = 8,
	/*
	 * Start a USB serial flash SPI transfer.
	 */
	USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START = 9,
};

enum feature_bitmap {
	/* Indicates the platform supports full duplex mode. */
	USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED = BIT(0),
	/* Indicates support for USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START. */
	USB_SPI_FEATURE_FLASH_EXTENSIONS = BIT(1),
	/*
	 * Indicates that chip and any MUXes support bidirectional data on the
	 * two SPI data lines.
	 */
	USB_SPI_FEATURE_DUAL_MODE_SUPPORTED = BIT(2),
	/*
	 * Indicates that chip and any MUXes support bidirectional data on the
	 * "hold" and "write protect" lines.
	 */
	USB_SPI_FEATURE_QUAD_MODE_SUPPORTED = BIT(3),
	/* Indicates support for eight-line bidirectional data. */
	USB_SPI_FEATURE_OCTO_MODE_SUPPORTED = BIT(4),
	/*
	 * Indicates support for double transfer rate, i.e. data bit shift on
	 * both rising and falling clock edges.
	 */
	USB_SPI_FEATURE_DTR_SUPPORTED = BIT(5),
};

struct usb_spi_response_configuration_v2 {
	uint16_t packet_id;
	uint16_t max_write_count;
	uint16_t max_read_count;
	uint16_t feature_bitmap;
} __packed;

struct usb_spi_command_v2 {
	uint16_t packet_id;
	uint16_t write_count;
	/* UINT16_MAX Indicates readback all on halfduplex compliant devices. */
	uint16_t read_count;
	uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_START];
} __packed;

struct usb_spi_response_v2 {
	uint16_t packet_id;
	uint16_t status_code;
	uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_RESPONSE];
} __packed;

struct usb_spi_continue_v2 {
	uint16_t packet_id;
	uint16_t data_index;
	uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_CONTINUE];
} __packed;

enum chip_select_flags {
	/* Indicates chip select should be asserted. */
	USB_SPI_CHIP_SELECT = BIT(0)
};

struct usb_spi_chip_select_command {
	uint16_t packet_id;
	uint16_t flags;
} __packed;

struct usb_spi_chip_select_response {
	uint16_t packet_id;
	uint16_t status_code;
} __packed;

struct usb_spi_flash_command {
	uint16_t packet_id;
	uint16_t count;
	uint32_t flags;
	uint8_t data[USB_SPI_PAYLOAD_SIZE_FLASH_START];
} __packed;

/*
 * Mask of the flags that are handled by logic in sub_spi.c, and not passed to
 * SPI drivers through usb_spi_board_transaction().
 */
#define FLASH_FLAGS_NONBOARD 0xF0000000UL

#define FLASH_FLAG_WRITE_ENABLE_POS 28U
#define FLASH_FLAG_WRITE_ENABLE (0x1UL << FLASH_FLAG_WRITE_ENABLE_POS)

#define FLASH_FLAG_POLL_POS 29U
#define FLASH_FLAG_POLL (0x1UL << FLASH_FLAG_POLL_POS)

#define FLASH_FLAG_READ_WRITE_POS 31U
#define FLASH_FLAG_READ_WRITE_MSK (0x1UL << FLASH_FLAG_READ_WRITE_POS)
#define FLASH_FLAG_READ_WRITE_READ 0
#define FLASH_FLAG_READ_WRITE_WRITE (0x1UL << FLASH_FLAG_READ_WRITE_POS)

struct usb_spi_packet_ctx {
	union {
		uint8_t bytes[USB_MAX_PACKET_SIZE];
		uint16_t packet_id;
		struct usb_spi_command_v2 cmd_start;
		struct usb_spi_flash_command cmd_flash_start;
		struct usb_spi_continue_v2 cmd_continue;
		struct usb_spi_response_configuration_v2 rsp_config;
		struct usb_spi_response_v2 rsp_start;
		struct usb_spi_continue_v2 rsp_continue;
		struct usb_spi_chip_select_command cmd_cs;
		struct usb_spi_chip_select_response rsp_cs;
	} __packed;
	/*
	 * By storing the number of bytes in the header and knowing that the
	 * USB data packets are all 64B long, we are able to use the header
	 * size to store the offset of the buffer and it's size without
	 * duplicating variables that can go out of sync.
	 */
	size_t header_size;
	/* Number of bytes in the packet. */
	size_t packet_size;
};

enum usb_spi_error {
	USB_SPI_SUCCESS = 0x0000,
	USB_SPI_TIMEOUT = 0x0001,
	USB_SPI_BUSY = 0x0002,
	USB_SPI_WRITE_COUNT_INVALID = 0x0003,
	USB_SPI_READ_COUNT_INVALID = 0x0004,
	USB_SPI_DISABLED = 0x0005,
	/* The RX continue packet's data index is invalid. */
	USB_SPI_RX_BAD_DATA_INDEX = 0x0006,
	/* The RX endpoint has received more data than write count. */
	USB_SPI_RX_DATA_OVERFLOW = 0x0007,
	/* An unexpected packet arrived on the device. */
	USB_SPI_RX_UNEXPECTED_PACKET = 0x0008,
	/* The device does not support full duplex mode. */
	USB_SPI_UNSUPPORTED_FULL_DUPLEX = 0x0009,
	/* The device does not support dual/quad wire mode. */
	USB_SPI_UNSUPPORTED_FLASH_MODE = 0x000A,
	USB_SPI_UNKNOWN_ERROR = 0x8000,
};

enum usb_spi_request {
	USB_SPI_REQ_ENABLE = 0x0000,
	USB_SPI_REQ_DISABLE = 0x0001,
};

/*
 * To optimize for speed, we want to fill whole packets for each transfer
 * This is done by setting the read and write counts to the payload sizes
 * of the smaller start packet + N * continue packets.
 *
 * If a platform has a small maximum SPI transfer size, it can be optimized
 * by setting these limits to the maximum transfer size.
 */
#ifdef CONFIG_USB_SPI_BUFFER_SIZE
#define USB_SPI_BUFFER_SIZE CONFIG_USB_SPI_BUFFER_SIZE
#else
#define USB_SPI_BUFFER_SIZE \
	(USB_SPI_PAYLOAD_SIZE_V2_START + (4 * USB_SPI_PAYLOAD_SIZE_V2_CONTINUE))
#endif
#define USB_SPI_MAX_WRITE_COUNT USB_SPI_BUFFER_SIZE
#define USB_SPI_MAX_READ_COUNT USB_SPI_BUFFER_SIZE

/* Protocol uses two-byte length fields.  Larger buffer makes no sense. */
BUILD_ASSERT(USB_SPI_BUFFER_SIZE <= 65536);

/*
 * Set the enable state for the USB-SPI bridge.
 *
 * The bridge must be enabled from both the host and device side
 * before the SPI bus is usable.  This allows the bridge to be
 * available for host tools to use without forcing the device to
 * disconnect or disable whatever else might be using the SPI bus.
 */
void usb_spi_enable(int enabled);

/*
 * These functions should be implemented by the board to provide any board
 * specific operations required to enable or disable access to the SPI device.
 */
void usb_spi_board_enable(void);
void usb_spi_board_disable(void);

/*
 * In order to facilitate special SPI busses not covered by standard EC
 * drivers, setting the USB_SPI_CUSTOM_SPI_DEVICE_MASK bit of spi_device->port
 * will cause the USB to SPI forwarding logic to invoke this method rather
 * than the standard spi_transaction_async().
 */
int usb_spi_board_transaction(const struct spi_device_t *spi_device,
			      uint32_t flash_flags, const uint8_t *txdata,
			      int txlen, uint8_t *rxdata, int rxlen);

/*
 * Flags to use in usb_spi_board_transaction_async() for advanced serial flash
 * communication, when supported.
 */

/* Number of bytes of opcode (0-3). */
#define FLASH_FLAG_OPCODE_LEN_POS 0
#define FLASH_FLAG_OPCODE_LEN_MSK (0x3U << FLASH_FLAG_OPCODE_LEN_POS)

/* Number of bytes of address plus additional data bytes (0-7). */
#define FLASH_FLAG_ADDR_LEN_POS 2
#define FLASH_FLAG_ADDR_LEN_MSK (0x7U << FLASH_FLAG_ADDR_LEN_POS)

/* At what stage to switch to multi-lane mode (if any). */
#define FLASH_FLAG_MODE_POS 5
#define FLASH_FLAG_MODE_MSK (0x3U << FLASH_FLAG_MODE_POS)
#define FLASH_FLAG_MODE_111 (0x0U << FLASH_FLAG_MODE_POS)
#define FLASH_FLAG_MODE_11N (0x1U << FLASH_FLAG_MODE_POS)
#define FLASH_FLAG_MODE_1NN (0x2U << FLASH_FLAG_MODE_POS)
#define FLASH_FLAG_MODE_NNN (0x3U << FLASH_FLAG_MODE_POS)

/* Data width during the later stages (value of N, above). */
#define FLASH_FLAG_WIDTH_POS 7
#define FLASH_FLAG_WIDTH_MSK (0x3U << FLASH_FLAG_WIDTH_POS)
#define FLASH_FLAG_WIDTH_1WIRE (0x0U << FLASH_FLAG_WIDTH_POS)
#define FLASH_FLAG_WIDTH_2WIRE (0x1U << FLASH_FLAG_WIDTH_POS)
#define FLASH_FLAG_WIDTH_4WIRE (0x2U << FLASH_FLAG_WIDTH_POS)
#define FLASH_FLAG_WIDTH_8WIRE (0x3U << FLASH_FLAG_WIDTH_POS)

/* Transmit opcode bits at both clock edges in later stages. */
#define FLASH_FLAG_DTR_POS 9
#define FLASH_FLAG_DTR (0x1U << FLASH_FLAG_DTR_POS)

/* Number of dummy clock cycles (0-31). */
#define FLASH_FLAG_DUMMY_CYCLES_POS 10
#define FLASH_FLAG_DUMMY_CYCLES_MSK (0x1FU << FLASH_FLAG_DUMMY_CYCLES_POS)

/*
 * Mask of the flags that cannot be ignored.  This is basically any flags
 * which call for wires to switch direction, or data being clocked on both
 * rising and falling edges.  As long as none of these are present, then the
 * remaining flags specifying the length of opcode/address can be ignored, as
 * the entire data buffer can be transmitted as a sequence of bytes, without
 * the controller knowing which parts are to be interpreted as
 * opcode/address/data.
 */
#define FLASH_FLAGS_REQUIRING_SUPPORT \
	(FLASH_FLAG_MODE_MSK | FLASH_FLAG_DTR | FLASH_FLAG_DUMMY_CYCLES_MSK)

#endif /* __CROS_EC_USB_SPI_H */