enum gs_usb_breq {
GS_USB_BREQ_HOST_FORMAT = 0,
GS_USB_BREQ_BITTIMING,
GS_USB_BREQ_MODE,
GS_USB_BREQ_BERR,
GS_USB_BREQ_BT_CONST,
GS_USB_BREQ_DEVICE_CONFIG,
GS_USB_BREQ_TIMESTAMP,
GS_USB_BREQ_IDENTIFY,
GS_USB_BREQ_GET_USER_ID,
GS_USB_BREQ_QUIRK_CANTACT_PRO_DATA_BITTIMING = GS_USB_BREQ_GET_USER_ID,
GS_USB_BREQ_SET_USER_ID,
GS_USB_BREQ_DATA_BITTIMING,
GS_USB_BREQ_BT_CONST_EXT,
GS_USB_BREQ_SET_TERMINATION,
GS_USB_BREQ_GET_TERMINATION,
GS_USB_BREQ_GET_STATE,
};
enum gs_can_mode {
/* reset a channel. turns it off */
GS_CAN_MODE_RESET = 0,
/* starts a channel */
GS_CAN_MODE_START
};
enum gs_can_state {
GS_CAN_STATE_ERROR_ACTIVE = 0,
GS_CAN_STATE_ERROR_WARNING,
GS_CAN_STATE_ERROR_PASSIVE,
GS_CAN_STATE_BUS_OFF,
GS_CAN_STATE_STOPPED,
GS_CAN_STATE_SLEEPING
};
enum gs_can_identify_mode {
GS_CAN_IDENTIFY_OFF = 0,
GS_CAN_IDENTIFY_ON
};
enum gs_can_termination_state {
GS_CAN_TERMINATION_STATE_OFF = 0,
GS_CAN_TERMINATION_STATE_ON
};
/* data types passed between host and device */
/* The firmware on the original USB2CAN by Geschwister Schneider
* Technologie Entwicklungs- und Vertriebs UG exchanges all data
* between the host and the device in host byte order. This is done
* with the struct gs_host_config::byte_order member, which is sent
* first to indicate the desired byte order.
*
* The widely used open source firmware candleLight doesn't support
* this feature and exchanges the data in little endian byte order.
*/
struct gs_host_config {
__le32 byte_order;
} __packed;
/**
* struct gs_device_config - Configuration describing the gs_usb compatible device
* @icount: number of CAN interfaces - 1
* @sw_version: software version - usually 2
* @hw_version: hardware version - usually 1
*
*/
struct gs_device_config {
u8 reserved1;
u8 reserved2;
u8 reserved3;
u8 icount;
__le32 sw_version;
__le32 hw_version;
} __packed;
#define GS_CAN_MODE_NORMAL 0
#define GS_CAN_MODE_LISTEN_ONLY BIT(0)
#define GS_CAN_MODE_LOOP_BACK BIT(1)
#define GS_CAN_MODE_TRIPLE_SAMPLE BIT(2)
#define GS_CAN_MODE_ONE_SHOT BIT(3)
#define GS_CAN_MODE_HW_TIMESTAMP BIT(4)
/* GS_CAN_FEATURE_IDENTIFY BIT(5) */
/* GS_CAN_FEATURE_USER_ID BIT(6) */
#define GS_CAN_MODE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7)
#define GS_CAN_MODE_FD BIT(8)
/* GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) */
/* GS_CAN_FEATURE_BT_CONST_EXT BIT(10) */
/* GS_CAN_FEATURE_TERMINATION BIT(11) */
#define GS_CAN_MODE_BERR_REPORTING BIT(12)
/* GS_CAN_FEATURE_GET_STATE BIT(13) */
struct gs_device_mode {
__le32 mode;
__le32 flags;
} __packed;
struct gs_device_state {
__le32 state;
__le32 rxerr;
__le32 txerr;
} __packed;
struct gs_device_bittiming {
__le32 prop_seg;
__le32 phase_seg1;
__le32 phase_seg2;
__le32 sjw;
__le32 brp;
} __packed;
struct gs_identify_mode {
__le32 mode;
} __packed;
struct gs_device_termination_state {
__le32 state;
} __packed;
#define GS_CAN_FEATURE_LISTEN_ONLY BIT(0)
#define GS_CAN_FEATURE_LOOP_BACK BIT(1)
#define GS_CAN_FEATURE_TRIPLE_SAMPLE BIT(2)
#define GS_CAN_FEATURE_ONE_SHOT BIT(3)
#define GS_CAN_FEATURE_HW_TIMESTAMP BIT(4)
#define GS_CAN_FEATURE_IDENTIFY BIT(5)
#define GS_CAN_FEATURE_USER_ID BIT(6)
#define GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7)
#define GS_CAN_FEATURE_FD BIT(8)
#define GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9)
#define GS_CAN_FEATURE_BT_CONST_EXT BIT(10)
#define GS_CAN_FEATURE_TERMINATION BIT(11)
#define GS_CAN_FEATURE_BERR_REPORTING BIT(12)
#define GS_CAN_FEATURE_GET_STATE BIT(13)
#define GS_CAN_FEATURE_MASK GENMASK(13, 0)
struct gs_device_bt_const {
__le32 feature;
__le32 fclk_can;
__le32 tseg1_min;
__le32 tseg1_max;
__le32 tseg2_min;
__le32 tseg2_max;
__le32 sjw_max;
__le32 brp_min;
__le32 brp_max;
__le32 brp_inc;
} __packed;
struct gs_device_bt_const_extended {
__le32 feature;
__le32 fclk_can;
__le32 tseg1_min;
__le32 tseg1_max;
__le32 tseg2_min;
__le32 tseg2_max;
__le32 sjw_max;
__le32 brp_min;
__le32 brp_max;
__le32 brp_inc;
__le32 dtseg1_min;
__le32 dtseg1_max;
__le32 dtseg2_min;
__le32 dtseg2_max;
__le32 dsjw_max;
__le32 dbrp_min;
__le32 dbrp_max;
__le32 dbrp_inc;
} __packed;
#define GS_CAN_FLAG_OVERFLOW BIT(0)
#define GS_CAN_FLAG_FD BIT(1)
#define GS_CAN_FLAG_BRS BIT(2)
#define GS_CAN_FLAG_ESI BIT(3)
struct classic_can {
u8 data[8];
} __packed;
struct classic_can_ts {
u8 data[8];
__le32 timestamp_us;
} __packed;
struct classic_can_quirk {
u8 data[8];
u8 quirk;
} __packed;
struct canfd {
u8 data[64];
} __packed;
struct canfd_ts {
u8 data[64];
__le32 timestamp_us;
} __packed;
struct canfd_quirk {
u8 data[64];
u8 quirk;
} __packed;
/**
* struct gs_host_frame - bulk data exchanged between host <-> device
* @echo_id: cookie to identify frame, -1 means rx'ed frame, tx-complete otherwise
* @can_id: the CAN-ID to send
* @can_dlc: dlc value
* @channel: the CAN channel to send to/received from
*/
struct gs_host_frame {
u32 echo_id;
__le32 can_id;
u8 can_dlc;
u8 channel;
u8 flags;
u8 reserved;
union {
DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
DECLARE_FLEX_ARRAY(struct classic_can_ts, classic_can_ts);
DECLARE_FLEX_ARRAY(struct classic_can_quirk, classic_can_quirk);
DECLARE_FLEX_ARRAY(struct canfd, canfd);
DECLARE_FLEX_ARRAY(struct canfd_ts, canfd_ts);
DECLARE_FLEX_ARRAY(struct canfd_quirk, canfd_quirk);
};
} __packed;
value
is the CAN channel number, unless otherwise specified.
Send a USB control message request = GS_USB_BREQ_HOST_FORMAT
with
struct struct gs_host_config
with
.byte_order = cpu_to_le32(0x0000beef)
, value
is always 0
.
Receive USB control message request = GS_USB_BREQ_DEVICE_CONFIG
with
struct gs_device_config
, value
is always 0
.
Receive USB control message request = GS_USB_BREQ_BT_CONST
with
struct gs_device_bt_const
, value
is always 0
.
Evaluate struct gs_device_bt_const::feature
flags supported by
device.
If struct gs_device_bt_const::feature
contains
GS_CAN_FEATURE_FD
, receive USB control message
request = GS_USB_BREQ_BT_CONST_EXT
, value
is always 0
.
Setup struct gs_device_bittiming
and send it with USB control
message request = GS_USB_BREQ_BITTIMING
to configure bit timing.
Setup struct gs_device_mode
with
mode = cpu_to_le32(GS_CAN_MODE_START)
, set features flags
struct gs_device_mode::flags
supported by driver. Send USB control
message request = GS_USB_BREQ_MODE
to open device.
Setup struct gs_device_mode
with
mode = cpu_to_le32(GS_CAN_MODE_RESET)
. Send USB control message
request = GS_USB_BREQ_MODE
to put device into reset mode.
Setup struct gs_host_frame
and send USB bulk transfer.
Receive struct gs_host_frame
USB bulk transfer, evaluate
struct gs_host_frame::echo_id
.
TX-completed CAN frames are echoed back to the host with
struct gs_host_frame::echo_id
equals the
struct gs_host_frame::echo_id
of the TX frame.
A struct gs_host_frame::echo_id
equals -1
identifies a RXed frame.