xref: /OK3568_Linux_fs/kernel/include/linux/can/dev/peak_canfd.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * CAN driver for PEAK System micro-CAN based adapters
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2003-2011 PEAK System-Technik GmbH
6*4882a593Smuzhiyun  * Copyright (C) 2011-2013 Stephane Grosjean <s.grosjean@peak-system.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun #ifndef PUCAN_H
9*4882a593Smuzhiyun #define PUCAN_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /* uCAN commands opcodes list (low-order 10 bits) */
12*4882a593Smuzhiyun #define PUCAN_CMD_NOP			0x000
13*4882a593Smuzhiyun #define PUCAN_CMD_RESET_MODE		0x001
14*4882a593Smuzhiyun #define PUCAN_CMD_NORMAL_MODE		0x002
15*4882a593Smuzhiyun #define PUCAN_CMD_LISTEN_ONLY_MODE	0x003
16*4882a593Smuzhiyun #define PUCAN_CMD_TIMING_SLOW		0x004
17*4882a593Smuzhiyun #define PUCAN_CMD_TIMING_FAST		0x005
18*4882a593Smuzhiyun #define PUCAN_CMD_SET_STD_FILTER	0x006
19*4882a593Smuzhiyun #define PUCAN_CMD_RESERVED2		0x007
20*4882a593Smuzhiyun #define PUCAN_CMD_FILTER_STD		0x008
21*4882a593Smuzhiyun #define PUCAN_CMD_TX_ABORT		0x009
22*4882a593Smuzhiyun #define PUCAN_CMD_WR_ERR_CNT		0x00a
23*4882a593Smuzhiyun #define PUCAN_CMD_SET_EN_OPTION		0x00b
24*4882a593Smuzhiyun #define PUCAN_CMD_CLR_DIS_OPTION	0x00c
25*4882a593Smuzhiyun #define PUCAN_CMD_RX_BARRIER		0x010
26*4882a593Smuzhiyun #define PUCAN_CMD_END_OF_COLLECTION	0x3ff
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /* uCAN received messages list */
29*4882a593Smuzhiyun #define PUCAN_MSG_CAN_RX		0x0001
30*4882a593Smuzhiyun #define PUCAN_MSG_ERROR			0x0002
31*4882a593Smuzhiyun #define PUCAN_MSG_STATUS		0x0003
32*4882a593Smuzhiyun #define PUCAN_MSG_BUSLOAD		0x0004
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define PUCAN_MSG_CACHE_CRITICAL	0x0102
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /* uCAN transmitted messages */
37*4882a593Smuzhiyun #define PUCAN_MSG_CAN_TX		0x1000
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /* uCAN command common header */
40*4882a593Smuzhiyun struct __packed pucan_command {
41*4882a593Smuzhiyun 	__le16	opcode_channel;
42*4882a593Smuzhiyun 	u16	args[3];
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /* return the opcode from the opcode_channel field of a command */
pucan_cmd_get_opcode(struct pucan_command * c)46*4882a593Smuzhiyun static inline u16 pucan_cmd_get_opcode(struct pucan_command *c)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	return le16_to_cpu(c->opcode_channel) & 0x3ff;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define PUCAN_TSLOW_BRP_BITS		10
52*4882a593Smuzhiyun #define PUCAN_TSLOW_TSGEG1_BITS		8
53*4882a593Smuzhiyun #define PUCAN_TSLOW_TSGEG2_BITS		7
54*4882a593Smuzhiyun #define PUCAN_TSLOW_SJW_BITS		7
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #define PUCAN_TSLOW_BRP_MASK		((1 << PUCAN_TSLOW_BRP_BITS) - 1)
57*4882a593Smuzhiyun #define PUCAN_TSLOW_TSEG1_MASK		((1 << PUCAN_TSLOW_TSGEG1_BITS) - 1)
58*4882a593Smuzhiyun #define PUCAN_TSLOW_TSEG2_MASK		((1 << PUCAN_TSLOW_TSGEG2_BITS) - 1)
59*4882a593Smuzhiyun #define PUCAN_TSLOW_SJW_MASK		((1 << PUCAN_TSLOW_SJW_BITS) - 1)
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* uCAN TIMING_SLOW command fields */
62*4882a593Smuzhiyun #define PUCAN_TSLOW_SJW_T(s, t)		(((s) & PUCAN_TSLOW_SJW_MASK) | \
63*4882a593Smuzhiyun 								((!!(t)) << 7))
64*4882a593Smuzhiyun #define PUCAN_TSLOW_TSEG2(t)		((t) & PUCAN_TSLOW_TSEG2_MASK)
65*4882a593Smuzhiyun #define PUCAN_TSLOW_TSEG1(t)		((t) & PUCAN_TSLOW_TSEG1_MASK)
66*4882a593Smuzhiyun #define PUCAN_TSLOW_BRP(b)		((b) & PUCAN_TSLOW_BRP_MASK)
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun struct __packed pucan_timing_slow {
69*4882a593Smuzhiyun 	__le16	opcode_channel;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	u8	ewl;		/* Error Warning limit */
72*4882a593Smuzhiyun 	u8	sjw_t;		/* Sync Jump Width + Triple sampling */
73*4882a593Smuzhiyun 	u8	tseg2;		/* Timing SEGment 2 */
74*4882a593Smuzhiyun 	u8	tseg1;		/* Timing SEGment 1 */
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	__le16	brp;		/* BaudRate Prescaler */
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun #define PUCAN_TFAST_BRP_BITS		10
80*4882a593Smuzhiyun #define PUCAN_TFAST_TSGEG1_BITS		5
81*4882a593Smuzhiyun #define PUCAN_TFAST_TSGEG2_BITS		4
82*4882a593Smuzhiyun #define PUCAN_TFAST_SJW_BITS		4
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun #define PUCAN_TFAST_BRP_MASK		((1 << PUCAN_TFAST_BRP_BITS) - 1)
85*4882a593Smuzhiyun #define PUCAN_TFAST_TSEG1_MASK		((1 << PUCAN_TFAST_TSGEG1_BITS) - 1)
86*4882a593Smuzhiyun #define PUCAN_TFAST_TSEG2_MASK		((1 << PUCAN_TFAST_TSGEG2_BITS) - 1)
87*4882a593Smuzhiyun #define PUCAN_TFAST_SJW_MASK		((1 << PUCAN_TFAST_SJW_BITS) - 1)
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun /* uCAN TIMING_FAST command fields */
90*4882a593Smuzhiyun #define PUCAN_TFAST_SJW(s)		((s) & PUCAN_TFAST_SJW_MASK)
91*4882a593Smuzhiyun #define PUCAN_TFAST_TSEG2(t)		((t) & PUCAN_TFAST_TSEG2_MASK)
92*4882a593Smuzhiyun #define PUCAN_TFAST_TSEG1(t)		((t) & PUCAN_TFAST_TSEG1_MASK)
93*4882a593Smuzhiyun #define PUCAN_TFAST_BRP(b)		((b) & PUCAN_TFAST_BRP_MASK)
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun struct __packed pucan_timing_fast {
96*4882a593Smuzhiyun 	__le16	opcode_channel;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	u8	unused;
99*4882a593Smuzhiyun 	u8	sjw;		/* Sync Jump Width */
100*4882a593Smuzhiyun 	u8	tseg2;		/* Timing SEGment 2 */
101*4882a593Smuzhiyun 	u8	tseg1;		/* Timing SEGment 1 */
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	__le16	brp;		/* BaudRate Prescaler */
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun /* uCAN FILTER_STD command fields */
107*4882a593Smuzhiyun #define PUCAN_FLTSTD_ROW_IDX_BITS	6
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun struct __packed pucan_filter_std {
110*4882a593Smuzhiyun 	__le16	opcode_channel;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	__le16	idx;
113*4882a593Smuzhiyun 	__le32	mask;		/* CAN-ID bitmask in idx range */
114*4882a593Smuzhiyun };
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun #define PUCAN_FLTSTD_ROW_IDX_MAX	((1 << PUCAN_FLTSTD_ROW_IDX_BITS) - 1)
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun /* uCAN SET_STD_FILTER command fields */
119*4882a593Smuzhiyun struct __packed pucan_std_filter {
120*4882a593Smuzhiyun 	__le16	opcode_channel;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	u8	unused;
123*4882a593Smuzhiyun 	u8	idx;
124*4882a593Smuzhiyun 	__le32	mask;		/* CAN-ID bitmask in idx range */
125*4882a593Smuzhiyun };
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /* uCAN TX_ABORT commands fields */
128*4882a593Smuzhiyun #define PUCAN_TX_ABORT_FLUSH		0x0001
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun struct __packed pucan_tx_abort {
131*4882a593Smuzhiyun 	__le16	opcode_channel;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	__le16	flags;
134*4882a593Smuzhiyun 	u32	unused;
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /* uCAN WR_ERR_CNT command fields */
138*4882a593Smuzhiyun #define PUCAN_WRERRCNT_TE		0x4000	/* Tx error cntr write Enable */
139*4882a593Smuzhiyun #define PUCAN_WRERRCNT_RE		0x8000	/* Rx error cntr write Enable */
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun struct __packed pucan_wr_err_cnt {
142*4882a593Smuzhiyun 	__le16	opcode_channel;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	__le16	sel_mask;
145*4882a593Smuzhiyun 	u8	tx_counter;	/* Tx error counter new value */
146*4882a593Smuzhiyun 	u8	rx_counter;	/* Rx error counter new value */
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	u16	unused;
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun /* uCAN SET_EN/CLR_DIS _OPTION command fields */
152*4882a593Smuzhiyun #define PUCAN_OPTION_ERROR		0x0001
153*4882a593Smuzhiyun #define PUCAN_OPTION_BUSLOAD		0x0002
154*4882a593Smuzhiyun #define PUCAN_OPTION_CANDFDISO		0x0004
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun struct __packed pucan_options {
157*4882a593Smuzhiyun 	__le16	opcode_channel;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	__le16	options;
160*4882a593Smuzhiyun 	u32	unused;
161*4882a593Smuzhiyun };
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun /* uCAN received messages global format */
164*4882a593Smuzhiyun struct __packed pucan_msg {
165*4882a593Smuzhiyun 	__le16	size;
166*4882a593Smuzhiyun 	__le16	type;
167*4882a593Smuzhiyun 	__le32	ts_low;
168*4882a593Smuzhiyun 	__le32	ts_high;
169*4882a593Smuzhiyun };
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun /* uCAN flags for CAN/CANFD messages */
172*4882a593Smuzhiyun #define PUCAN_MSG_SELF_RECEIVE		0x80
173*4882a593Smuzhiyun #define PUCAN_MSG_ERROR_STATE_IND	0x40	/* error state indicator */
174*4882a593Smuzhiyun #define PUCAN_MSG_BITRATE_SWITCH	0x20	/* bitrate switch */
175*4882a593Smuzhiyun #define PUCAN_MSG_EXT_DATA_LEN		0x10	/* extended data length */
176*4882a593Smuzhiyun #define PUCAN_MSG_SINGLE_SHOT		0x08
177*4882a593Smuzhiyun #define PUCAN_MSG_LOOPED_BACK		0x04
178*4882a593Smuzhiyun #define PUCAN_MSG_EXT_ID		0x02
179*4882a593Smuzhiyun #define PUCAN_MSG_RTR			0x01
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun struct __packed pucan_rx_msg {
182*4882a593Smuzhiyun 	__le16	size;
183*4882a593Smuzhiyun 	__le16	type;
184*4882a593Smuzhiyun 	__le32	ts_low;
185*4882a593Smuzhiyun 	__le32	ts_high;
186*4882a593Smuzhiyun 	__le32	tag_low;
187*4882a593Smuzhiyun 	__le32	tag_high;
188*4882a593Smuzhiyun 	u8	channel_dlc;
189*4882a593Smuzhiyun 	u8	client;
190*4882a593Smuzhiyun 	__le16	flags;
191*4882a593Smuzhiyun 	__le32	can_id;
192*4882a593Smuzhiyun 	u8	d[];
193*4882a593Smuzhiyun };
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /* uCAN error types */
196*4882a593Smuzhiyun #define PUCAN_ERMSG_BIT_ERROR		0
197*4882a593Smuzhiyun #define PUCAN_ERMSG_FORM_ERROR		1
198*4882a593Smuzhiyun #define PUCAN_ERMSG_STUFF_ERROR		2
199*4882a593Smuzhiyun #define PUCAN_ERMSG_OTHER_ERROR		3
200*4882a593Smuzhiyun #define PUCAN_ERMSG_ERR_CNT_DEC		4
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun struct __packed pucan_error_msg {
203*4882a593Smuzhiyun 	__le16	size;
204*4882a593Smuzhiyun 	__le16	type;
205*4882a593Smuzhiyun 	__le32	ts_low;
206*4882a593Smuzhiyun 	__le32	ts_high;
207*4882a593Smuzhiyun 	u8	channel_type_d;
208*4882a593Smuzhiyun 	u8	code_g;
209*4882a593Smuzhiyun 	u8	tx_err_cnt;
210*4882a593Smuzhiyun 	u8	rx_err_cnt;
211*4882a593Smuzhiyun };
212*4882a593Smuzhiyun 
pucan_error_get_channel(const struct pucan_error_msg * msg)213*4882a593Smuzhiyun static inline int pucan_error_get_channel(const struct pucan_error_msg *msg)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun 	return msg->channel_type_d & 0x0f;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun #define PUCAN_RX_BARRIER		0x10
219*4882a593Smuzhiyun #define PUCAN_BUS_PASSIVE		0x20
220*4882a593Smuzhiyun #define PUCAN_BUS_WARNING		0x40
221*4882a593Smuzhiyun #define PUCAN_BUS_BUSOFF		0x80
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun struct __packed pucan_status_msg {
224*4882a593Smuzhiyun 	__le16	size;
225*4882a593Smuzhiyun 	__le16	type;
226*4882a593Smuzhiyun 	__le32	ts_low;
227*4882a593Smuzhiyun 	__le32	ts_high;
228*4882a593Smuzhiyun 	u8	channel_p_w_b;
229*4882a593Smuzhiyun 	u8	unused[3];
230*4882a593Smuzhiyun };
231*4882a593Smuzhiyun 
pucan_status_get_channel(const struct pucan_status_msg * msg)232*4882a593Smuzhiyun static inline int pucan_status_get_channel(const struct pucan_status_msg *msg)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun 	return msg->channel_p_w_b & 0x0f;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun 
pucan_status_is_rx_barrier(const struct pucan_status_msg * msg)237*4882a593Smuzhiyun static inline int pucan_status_is_rx_barrier(const struct pucan_status_msg *msg)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun 	return msg->channel_p_w_b & PUCAN_RX_BARRIER;
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun 
pucan_status_is_passive(const struct pucan_status_msg * msg)242*4882a593Smuzhiyun static inline int pucan_status_is_passive(const struct pucan_status_msg *msg)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	return msg->channel_p_w_b & PUCAN_BUS_PASSIVE;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun 
pucan_status_is_warning(const struct pucan_status_msg * msg)247*4882a593Smuzhiyun static inline int pucan_status_is_warning(const struct pucan_status_msg *msg)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun 	return msg->channel_p_w_b & PUCAN_BUS_WARNING;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun 
pucan_status_is_busoff(const struct pucan_status_msg * msg)252*4882a593Smuzhiyun static inline int pucan_status_is_busoff(const struct pucan_status_msg *msg)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 	return msg->channel_p_w_b & PUCAN_BUS_BUSOFF;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun /* uCAN transmitted message format */
258*4882a593Smuzhiyun #define PUCAN_MSG_CHANNEL_DLC(c, d)	(((c) & 0xf) | ((d) << 4))
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun struct __packed pucan_tx_msg {
261*4882a593Smuzhiyun 	__le16	size;
262*4882a593Smuzhiyun 	__le16	type;
263*4882a593Smuzhiyun 	__le32	tag_low;
264*4882a593Smuzhiyun 	__le32	tag_high;
265*4882a593Smuzhiyun 	u8	channel_dlc;
266*4882a593Smuzhiyun 	u8	client;
267*4882a593Smuzhiyun 	__le16	flags;
268*4882a593Smuzhiyun 	__le32	can_id;
269*4882a593Smuzhiyun 	u8	d[];
270*4882a593Smuzhiyun };
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun /* build the cmd opcode_channel field with respect to the correct endianness */
pucan_cmd_opcode_channel(int index,int opcode)273*4882a593Smuzhiyun static inline __le16 pucan_cmd_opcode_channel(int index, int opcode)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	return cpu_to_le16(((index) << 12) | ((opcode) & 0x3ff));
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun /* return the channel number part from any received message channel_dlc field */
pucan_msg_get_channel(const struct pucan_rx_msg * msg)279*4882a593Smuzhiyun static inline int pucan_msg_get_channel(const struct pucan_rx_msg *msg)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun 	return msg->channel_dlc & 0xf;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun /* return the dlc value from any received message channel_dlc field */
pucan_msg_get_dlc(const struct pucan_rx_msg * msg)285*4882a593Smuzhiyun static inline int pucan_msg_get_dlc(const struct pucan_rx_msg *msg)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	return msg->channel_dlc >> 4;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun 
pucan_ermsg_get_channel(const struct pucan_error_msg * msg)290*4882a593Smuzhiyun static inline int pucan_ermsg_get_channel(const struct pucan_error_msg *msg)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	return msg->channel_type_d & 0x0f;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
pucan_stmsg_get_channel(const struct pucan_status_msg * msg)295*4882a593Smuzhiyun static inline int pucan_stmsg_get_channel(const struct pucan_status_msg *msg)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	return msg->channel_p_w_b & 0x0f;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun #endif
301