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