1 /*
2 * Copyright (c) 2023 Vestas Wind Systems A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/can.h>
9 #include <zephyr/drivers/can/can_mcan.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/spi.h>
12 #include <zephyr/logging/log.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/sys/util.h>
15
16 LOG_MODULE_REGISTER(can_tcan4x5x, CONFIG_CAN_LOG_LEVEL);
17
18 #define DT_DRV_COMPAT ti_tcan4x5x
19
20 /*
21 * The register definitions correspond to those found in the TI TCAN4550-Q1 datasheet, revision D
22 * June 2022 (SLLSEZ5D).
23 */
24
25 /* Device ID1 register */
26 #define CAN_TCAN4X5X_DEVICE_ID1 0x0000
27
28 /* Device ID2 register */
29 #define CAN_TCAN4X5X_DEVICE_ID2 0x0004
30
31 /* Revision register */
32 #define CAN_TCAN4X5X_REVISION 0x0008
33 #define CAN_TCAN4X5X_REVISION_SPI_2_REVISION GENMASK(31, 24)
34 #define CAN_TCAN4X5X_REVISION_REV_ID_MAJOR GENMASK(15, 8)
35 #define CAN_TCAN4X5X_REVISION_REV_ID_MINOR GENMASK(7, 0)
36
37 /* Status register */
38 #define CAN_TCAN4X5X_STATUS 0x000c
39 #define CAN_TCAN4X5X_STATUS_INTERNAL_READ_ERROR BIT(29)
40 #define CAN_TCAN4X5X_STATUS_INTERNAL_WRITE_ERROR BIT(28)
41 #define CAN_TCAN4X5X_STATUS_INTERNAL_ERROR_LOG_WRITE BIT(27)
42 #define CAN_TCAN4X5X_STATUS_READ_FIFO_UNDERFLOW BIT(26)
43 #define CAN_TCAN4X5X_STATUS_READ_FIFO_EMPTY BIT(25)
44 #define CAN_TCAN4X5X_STATUS_WRITE_FIFO_OVERFLOW BIT(24)
45 #define CAN_TCAN4X5X_STATUS_SPI_END_ERROR BIT(21)
46 #define CAN_TCAN4X5X_STATUS_INVALID_COMMAND BIT(20)
47 #define CAN_TCAN4X5X_STATUS_WRITE_OVERFLOW BIT(19)
48 #define CAN_TCAN4X5X_STATUS_WRITE_UNDERFLOW BIT(18)
49 #define CAN_TCAN4X5X_STATUS_READ_OVERFLOW BIT(17)
50 #define CAN_TCAN4X5X_STATUS_READ_UNDERFLOW BIT(16)
51 #define CAN_TCAN4X5X_STATUS_WRITE_FIFO_AVAILABLE BIT(5)
52 #define CAN_TCAN4X5X_STATUS_READ_FIFO_AVAILABLE BIT(4)
53 #define CAN_TCAN4X5X_STATUS_INTERNAL_ACCESS_ACTIVE BIT(3)
54 #define CAN_TCAN4X5X_STATUS_INTERNAL_ERROR_INTERRUPT BIT(2)
55 #define CAN_TCAN4X5X_STATUS_SPI_ERROR_INTERRUPT BIT(1)
56 #define CAN_TCAN4X5X_STATUS_INTERRUPT BIT(0)
57
58 /* Mask of clearable status register bits */
59 #define CAN_TCAN4X5X_STATUS_CLEAR_ALL \
60 (CAN_TCAN4X5X_STATUS_INTERNAL_READ_ERROR | CAN_TCAN4X5X_STATUS_INTERNAL_WRITE_ERROR | \
61 CAN_TCAN4X5X_STATUS_INTERNAL_ERROR_LOG_WRITE | CAN_TCAN4X5X_STATUS_READ_FIFO_UNDERFLOW | \
62 CAN_TCAN4X5X_STATUS_READ_FIFO_EMPTY | CAN_TCAN4X5X_STATUS_WRITE_FIFO_OVERFLOW | \
63 CAN_TCAN4X5X_STATUS_SPI_END_ERROR | CAN_TCAN4X5X_STATUS_INVALID_COMMAND | \
64 CAN_TCAN4X5X_STATUS_WRITE_OVERFLOW | CAN_TCAN4X5X_STATUS_WRITE_UNDERFLOW | \
65 CAN_TCAN4X5X_STATUS_READ_OVERFLOW | CAN_TCAN4X5X_STATUS_READ_UNDERFLOW)
66
67 /* SPI Error Status Mask register */
68 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK 0x0010
69 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INTERNAL_READ_ERROR BIT(29)
70 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INTERNAL_WRITE_ERROR BIT(28)
71 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INTERNAL_ERROR_LOG_WRITE BIT(27)
72 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_FIFO_UNDERFLOW BIT(26)
73 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_FIFO_EMPTY BIT(25)
74 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_WRITE_FIFO_OVERFLOW BIT(24)
75 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_SPI_END_ERROR BIT(21)
76 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_INVALID_COMMAND BIT(20)
77 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_WRITE_OVERFLOW BIT(19)
78 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_WRITE_UNDERFLOW BIT(18)
79 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_OVERFLOW BIT(17)
80 #define CAN_TCAN4X5X_SPI_ERROR_STATUS_MASK_READ_UNDERFLOW BIT(16)
81
82 /* Modes of Operation and Pin Configurations register */
83 #define CAN_TCAN4X5X_MODE_CONFIG 0x0800
84 #define CAN_TCAN4X5X_MODE_CONFIG_WAKE_CONFIG GENMASK(31, 30)
85 #define CAN_TCAN4X5X_MODE_CONFIG_WD_TIMER GENMASK(29, 28)
86 #define CAN_TCAN4X5X_MODE_CONFIG_CLK_REF BIT(27)
87 #define CAN_TCAN4X5X_MODE_CONFIG_GPO2_CONFIG GENMASK(23, 22)
88 #define CAN_TCAN4X5X_MODE_CONFIG_TEST_MODE_EN BIT(21)
89 #define CAN_TCAN4X5X_MODE_CONFIG_NWKRQ_VOLTAGE BIT(19)
90 #define CAN_TCAN4X5X_MODE_CONFIG_WD_BIT_SET BIT(18)
91 #define CAN_TCAN4X5X_MODE_CONFIG_WD_ACTION GENMASK(17, 16)
92 #define CAN_TCAN4X5X_MODE_CONFIG_GPIO1_CONFIG GENMASK(15, 14)
93 #define CAN_TCAN4X5X_MODE_CONFIG_FAIL_SAFE_EN BIT(13)
94 #define CAN_TCAN4X5X_MODE_CONFIG_GPIO1_GPO_CONFIG GENMASK(11, 10)
95 #define CAN_TCAN4X5X_MODE_CONFIG_INH_DIS BIT(9)
96 #define CAN_TCAN4X5X_MODE_CONFIG_NWKRQ_CONFIG BIT(8)
97 #define CAN_TCAN4X5X_MODE_CONFIG_MODE_SEL GENMASK(7, 6)
98 #define CAN_TCAN4X5X_MODE_CONFIG_WD_EN BIT(3)
99 #define CAN_TCAN4X5X_MODE_CONFIG_DEVICE_RESET BIT(2)
100 #define CAN_TCAN4X5X_MODE_CONFIG_SWE_DIS BIT(1)
101 #define CAN_TCAN4X5X_MODE_CONFIG_TEST_MODE_CONFIG BIT(0)
102
103 /* Timestamp Prescaler register */
104 #define CAN_TCAN4X5X_TIMESTAMP_PRESCALER 0x0804
105 #define CAN_TCAN4X5X_TIMESTAMP_PRESCALER_MASK GENMASK(7, 0)
106
107 /* Test Register and Scratch Pad */
108 #define CAN_TCAN4X5X_TEST_SCRATCH_PAD 0x0808
109 #define CAN_TCAN4X5X_TEST_SCRATCH_PAD_READ_WRITE GENMASK(31, 16)
110 #define CAN_TCAN4X5X_TEST_SCRATCH_PAD_SCRATCH_PAD GENMASK(15, 0)
111
112 /* Test register */
113 #define CAN_TCAN4X5X_TEST 0x0808
114 #define CAN_TCAN4X5X_TEST_ECC_ERR_FORCE_BIT_SEL GENMASK(21, 16)
115 #define CAN_TCAN4X5X_TEST_ECC_ERR_FORCE BIT(12)
116 #define CAN_TCAN4X5X_TEST_ECC_ERR_CHECK BIT(11)
117
118 /* Interrupts register */
119 #define CAN_TCAN4X5X_IR 0x0820
120 #define CAN_TCAN4X5X_IR_CANBUSNOM BIT(31)
121 #define CAN_TCAN4X5X_IR_SMS BIT(23)
122 #define CAN_TCAN4X5X_IR_UVSUP BIT(22)
123 #define CAN_TCAN4X5X_IR_UVIO BIT(21)
124 #define CAN_TCAN4X5X_IR_PWRON BIT(20)
125 #define CAN_TCAN4X5X_IR_TSD BIT(19)
126 #define CAN_TCAN4X5X_IR_WDTO BIT(18)
127 #define CAN_TCAN4X5X_IR_ECCERR BIT(16)
128 #define CAN_TCAN4X5X_IR_CANINT BIT(15)
129 #define CAN_TCAN4X5X_IR_LWU BIT(14)
130 #define CAN_TCAN4X5X_IR_WKERR BIT(13)
131 #define CAN_TCAN4X5X_IR_CANSLNT BIT(10)
132 #define CAN_TCAN4X5X_IR_CANDOM BIT(8)
133 #define CAN_TCAN4X5X_IR_GLOBALERR BIT(7)
134 #define CAN_TCAN4X5X_IR_WKRQ BIT(6)
135 #define CAN_TCAN4X5X_IR_CANERR BIT(5)
136 #define CAN_TCAN4X5X_IR_SPIERR BIT(3)
137 #define CAN_TCAN4X5X_IR_M_CAN_INT BIT(1)
138 #define CAN_TCAN4X5X_IR_VTWD BIT(0)
139
140 /* Mask of clearable interrupts register bits */
141 #define CAN_TCAN4X5X_IR_CLEAR_ALL \
142 (CAN_TCAN4X5X_IR_SMS | CAN_TCAN4X5X_IR_UVSUP | CAN_TCAN4X5X_IR_UVIO | \
143 CAN_TCAN4X5X_IR_PWRON | CAN_TCAN4X5X_IR_TSD | CAN_TCAN4X5X_IR_WDTO | \
144 CAN_TCAN4X5X_IR_ECCERR | CAN_TCAN4X5X_IR_CANINT | CAN_TCAN4X5X_IR_LWU | \
145 CAN_TCAN4X5X_IR_WKERR | CAN_TCAN4X5X_IR_CANSLNT | CAN_TCAN4X5X_IR_CANDOM)
146
147 /* MCAN Interrupts register */
148 #define CAN_TCAN4X5X_MCAN_IR 0x0824
149 #define CAN_TCAN4X5X_MCAN_IR_ARA BIT(29)
150 #define CAN_TCAN4X5X_MCAN_IR_PED BIT(28)
151 #define CAN_TCAN4X5X_MCAN_IR_PEA BIT(27)
152 #define CAN_TCAN4X5X_MCAN_IR_WDI BIT(26)
153 #define CAN_TCAN4X5X_MCAN_IR_BO BIT(25)
154 #define CAN_TCAN4X5X_MCAN_IR_EW BIT(24)
155 #define CAN_TCAN4X5X_MCAN_IR_EP BIT(23)
156 #define CAN_TCAN4X5X_MCAN_IR_ELO BIT(22)
157 #define CAN_TCAN4X5X_MCAN_IR_BEU BIT(21)
158 #define CAN_TCAN4X5X_MCAN_IR_BEC BIT(20)
159 #define CAN_TCAN4X5X_MCAN_IR_DRX BIT(19)
160 #define CAN_TCAN4X5X_MCAN_IR_TOO BIT(18)
161 #define CAN_TCAN4X5X_MCAN_IR_MRAF BIT(17)
162 #define CAN_TCAN4X5X_MCAN_IR_TSW BIT(16)
163 #define CAN_TCAN4X5X_MCAN_IR_TEFL BIT(15)
164 #define CAN_TCAN4X5X_MCAN_IR_TEFF BIT(14)
165 #define CAN_TCAN4X5X_MCAN_IR_TEFW BIT(13)
166 #define CAN_TCAN4X5X_MCAN_IR_TEFN BIT(12)
167 #define CAN_TCAN4X5X_MCAN_IR_TFE BIT(11)
168 #define CAN_TCAN4X5X_MCAN_IR_TCF BIT(10)
169 #define CAN_TCAN4X5X_MCAN_IR_TC BIT(9)
170 #define CAN_TCAN4X5X_MCAN_IR_HPM BIT(8)
171 #define CAN_TCAN4X5X_MCAN_IR_RF1L BIT(7)
172 #define CAN_TCAN4X5X_MCAN_IR_RF1F BIT(6)
173 #define CAN_TCAN4X5X_MCAN_IR_RF1W BIT(5)
174 #define CAN_TCAN4X5X_MCAN_IR_RF1N BIT(4)
175 #define CAN_TCAN4X5X_MCAN_IR_RF0L BIT(3)
176 #define CAN_TCAN4X5X_MCAN_IR_RF0F BIT(2)
177 #define CAN_TCAN4X5X_MCAN_IR_RF0W BIT(1)
178 #define CAN_TCAN4X5X_MCAN_IR_RF0N BIT(0)
179
180 /* Interrupt Enables register */
181 #define CAN_TCAN4X5X_IE 0x0830
182 #define CAN_TCAN4X5X_IE_UVSUP BIT(22)
183 #define CAN_TCAN4X5X_IE_UVIO BIT(21)
184 #define CAN_TCAN4X5X_IE_TSD BIT(19)
185 #define CAN_TCAN4X5X_IE_ECCERR BIT(16)
186 #define CAN_TCAN4X5X_IE_CANINT BIT(15)
187 #define CAN_TCAN4X5X_IE_LWU BIT(14)
188 #define CAN_TCAN4X5X_IE_CANSLNT BIT(10)
189 #define CAN_TCAN4X5X_IE_CANDOM BIT(8)
190
191 /* Bosch M_CAN registers base address */
192 #define CAN_TCAN4X5X_MCAN_BASE 0x1000
193
194 /* Bosch M_CAN Message RAM base address and size */
195 #define CAN_TCAN4X5X_MRAM_BASE 0x8000
196 #define CAN_TCAN4X5X_MRAM_SIZE 2048
197
198 /* TCAN4x5x SPI OP codes */
199 #define CAN_TCAN4X5X_WRITE_B_FL 0x61
200 #define CAN_TCAN4X5X_READ_B_FL 0x41
201
202 /* TCAN4x5x timing requirements */
203 #define CAN_TCAN4X5X_T_MODE_STBY_NOM_US 70
204 #define CAN_TCAN4X5X_T_WAKE_US 50
205 #define CAN_TCAN4X5X_T_PULSE_WIDTH_US 30
206 #define CAN_TCAN4X5X_T_RESET_US 1000
207
208 /*
209 * Only compile in support for the optional GPIOs if at least one enabled tcan4x5x device tree node
210 * has them. Only the INT GPIO is required.
211 */
212 #define TCAN4X5X_RST_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
213 #define TCAN4X5X_NWKRQ_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(device_state_gpios)
214 #define TCAN4X5X_WAKE_GPIO_SUPPORT DT_ANY_INST_HAS_PROP_STATUS_OKAY(device_wake_gpios)
215
216 struct tcan4x5x_config {
217 struct spi_dt_spec spi;
218 #if TCAN4X5X_RST_GPIO_SUPPORT
219 struct gpio_dt_spec rst_gpio;
220 #endif /* TCAN4X5X_RST_GPIO_SUPPORT */
221 #if TCAN4X5X_NWKRQ_GPIO_SUPPORT
222 struct gpio_dt_spec nwkrq_gpio;
223 #endif /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */
224 #if TCAN4X5X_WAKE_GPIO_SUPPORT
225 struct gpio_dt_spec wake_gpio;
226 #endif /* TCAN4X5X_WAKE_GPIO_SUPPORT */
227 struct gpio_dt_spec int_gpio;
228 uint32_t clk_freq;
229 };
230
231 struct tcan4x5x_data {
232 struct gpio_callback int_gpio_cb;
233 struct k_thread int_thread;
234 struct k_sem int_sem;
235
236 K_KERNEL_STACK_MEMBER(int_stack, CONFIG_CAN_TCAN4X5X_THREAD_STACK_SIZE);
237 };
238
tcan4x5x_read(const struct device * dev,uint16_t addr,void * dst,size_t len)239 static int tcan4x5x_read(const struct device *dev, uint16_t addr, void *dst, size_t len)
240 {
241 const struct can_mcan_config *mcan_config = dev->config;
242 const struct tcan4x5x_config *tcan_config = mcan_config->custom;
243 size_t len32 = len / sizeof(uint32_t);
244 uint32_t *dst32 = (uint32_t *)dst;
245 uint8_t cmd[4] = {CAN_TCAN4X5X_READ_B_FL, addr >> 8U & 0xFF, addr & 0xFF,
246 len32 == 256 ? 0U : len32};
247 uint8_t global_status;
248 const struct spi_buf tx_bufs[] = {
249 {.buf = &cmd, .len = sizeof(cmd)},
250 };
251 const struct spi_buf rx_bufs[] = {
252 {.buf = &global_status, .len = sizeof(global_status)},
253 {.buf = NULL, .len = 3},
254 {.buf = dst, .len = len},
255 };
256 const struct spi_buf_set tx = {
257 .buffers = tx_bufs,
258 .count = ARRAY_SIZE(tx_bufs),
259 };
260 const struct spi_buf_set rx = {
261 .buffers = rx_bufs,
262 .count = ARRAY_SIZE(rx_bufs),
263 };
264 int err;
265 int i;
266
267 if (len == 0) {
268 return 0;
269 }
270
271 /* Maximum transfer size is 256 32-bit words */
272 __ASSERT_NO_MSG(len % 4 == 0);
273 __ASSERT_NO_MSG(len32 <= 256);
274
275 err = spi_transceive_dt(&tcan_config->spi, &tx, &rx);
276 if (err != 0) {
277 LOG_ERR("failed to read addr %u, len %d (err %d)", addr, len, err);
278 return err;
279 }
280
281 __ASSERT_NO_MSG((global_status & CAN_TCAN4X5X_IR_SPIERR) == 0U);
282
283 for (i = 0; i < len32; i++) {
284 dst32[i] = sys_be32_to_cpu(dst32[i]);
285 }
286
287 return 0;
288 }
289
tcan4x5x_write(const struct device * dev,uint16_t addr,const void * src,size_t len)290 static int tcan4x5x_write(const struct device *dev, uint16_t addr, const void *src, size_t len)
291 {
292 const struct can_mcan_config *mcan_config = dev->config;
293 const struct tcan4x5x_config *tcan_config = mcan_config->custom;
294 size_t len32 = len / sizeof(uint32_t);
295 uint32_t src32[len32];
296 uint8_t cmd[4] = {CAN_TCAN4X5X_WRITE_B_FL, addr >> 8U & 0xFF, addr & 0xFF,
297 len32 == 256 ? 0U : len32};
298 uint8_t global_status;
299 const struct spi_buf tx_bufs[] = {
300 {.buf = &cmd, .len = sizeof(cmd)},
301 {.buf = &src32, .len = len},
302 };
303 const struct spi_buf rx_bufs[] = {
304 {.buf = &global_status, .len = sizeof(global_status)},
305 };
306 const struct spi_buf_set tx = {
307 .buffers = tx_bufs,
308 .count = ARRAY_SIZE(tx_bufs),
309 };
310 const struct spi_buf_set rx = {
311 .buffers = rx_bufs,
312 .count = ARRAY_SIZE(rx_bufs),
313 };
314 int err;
315 int i;
316
317 if (len == 0) {
318 return 0;
319 }
320
321 /* Maximum transfer size is 256 32-bit words */
322 __ASSERT_NO_MSG(len % 4 == 0);
323 __ASSERT_NO_MSG(len32 <= 256);
324
325 for (i = 0; i < len32; i++) {
326 src32[i] = sys_cpu_to_be32(((uint32_t *)src)[i]);
327 }
328
329 err = spi_transceive_dt(&tcan_config->spi, &tx, &rx);
330 if (err != 0) {
331 LOG_ERR("failed to write addr %u, len %d (err %d)", addr, len, err);
332 return err;
333 }
334
335 __ASSERT_NO_MSG((global_status & CAN_TCAN4X5X_IR_SPIERR) == 0U);
336
337 return 0;
338 }
339
tcan4x5x_read_tcan_reg(const struct device * dev,uint16_t reg,uint32_t * val)340 static inline int tcan4x5x_read_tcan_reg(const struct device *dev, uint16_t reg, uint32_t *val)
341 {
342 return tcan4x5x_read(dev, reg, val, sizeof(uint32_t));
343 }
344
tcan4x5x_write_tcan_reg(const struct device * dev,uint16_t reg,uint32_t val)345 static inline int tcan4x5x_write_tcan_reg(const struct device *dev, uint16_t reg, uint32_t val)
346 {
347 return tcan4x5x_write(dev, reg, &val, sizeof(uint32_t));
348 }
349
tcan4x5x_read_mcan_reg(const struct device * dev,uint16_t reg,uint32_t * val)350 static int tcan4x5x_read_mcan_reg(const struct device *dev, uint16_t reg, uint32_t *val)
351 {
352 return tcan4x5x_read(dev, CAN_TCAN4X5X_MCAN_BASE + reg, val, sizeof(uint32_t));
353 }
354
tcan4x5x_write_mcan_reg(const struct device * dev,uint16_t reg,uint32_t val)355 static int tcan4x5x_write_mcan_reg(const struct device *dev, uint16_t reg, uint32_t val)
356 {
357 return tcan4x5x_write(dev, CAN_TCAN4X5X_MCAN_BASE + reg, &val, sizeof(uint32_t));
358 }
359
tcan4x5x_read_mcan_mram(const struct device * dev,uint16_t offset,void * dst,size_t len)360 static int tcan4x5x_read_mcan_mram(const struct device *dev, uint16_t offset, void *dst, size_t len)
361 {
362 return tcan4x5x_read(dev, CAN_TCAN4X5X_MRAM_BASE + offset, dst, len);
363 }
364
tcan4x5x_write_mcan_mram(const struct device * dev,uint16_t offset,const void * src,size_t len)365 static int tcan4x5x_write_mcan_mram(const struct device *dev, uint16_t offset, const void *src,
366 size_t len)
367 {
368 return tcan4x5x_write(dev, CAN_TCAN4X5X_MRAM_BASE + offset, src, len);
369 }
370
tcan4x5x_clear_mcan_mram(const struct device * dev,uint16_t offset,size_t len)371 static int tcan4x5x_clear_mcan_mram(const struct device *dev, uint16_t offset, size_t len)
372 {
373 static const uint8_t buf[256] = {0};
374 size_t pending;
375 size_t upto;
376 int err;
377
378 for (upto = 0; upto < len; upto += pending) {
379 pending = MIN(len - upto, sizeof(buf));
380
381 err = tcan4x5x_write_mcan_mram(dev, offset, &buf, pending);
382 if (err != 0) {
383 LOG_ERR("failed to clear message RAM (err %d)", err);
384 return err;
385 }
386
387 offset += pending;
388 }
389
390 return 0;
391 }
392
tcan4x5x_get_core_clock(const struct device * dev,uint32_t * rate)393 static int tcan4x5x_get_core_clock(const struct device *dev, uint32_t *rate)
394 {
395 const struct can_mcan_config *mcan_config = dev->config;
396 const struct tcan4x5x_config *tcan_config = mcan_config->custom;
397
398 *rate = tcan_config->clk_freq;
399
400 return 0;
401 }
402
tcan4x5x_int_gpio_callback_handler(const struct device * port,struct gpio_callback * cb,gpio_port_pins_t pins)403 static void tcan4x5x_int_gpio_callback_handler(const struct device *port, struct gpio_callback *cb,
404 gpio_port_pins_t pins)
405 {
406 struct tcan4x5x_data *tcan_data = CONTAINER_OF(cb, struct tcan4x5x_data, int_gpio_cb);
407
408 k_sem_give(&tcan_data->int_sem);
409 }
410
tcan4x5x_int_thread(void * p1,void * p2,void * p3)411 static void tcan4x5x_int_thread(void *p1, void *p2, void *p3)
412 {
413 ARG_UNUSED(p2);
414 ARG_UNUSED(p3);
415
416 const struct device *dev = p1;
417 struct can_mcan_data *mcan_data = dev->data;
418 struct tcan4x5x_data *tcan_data = mcan_data->custom;
419 uint32_t status;
420 uint32_t ir;
421 int err;
422
423 while (true) {
424 k_sem_take(&tcan_data->int_sem, K_FOREVER);
425
426 err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_IR, &ir);
427 if (err != 0) {
428 LOG_ERR("failed to read interrupt register (err %d)", err);
429 continue;
430 }
431
432 while (ir != 0U) {
433 err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_IR,
434 ir & CAN_TCAN4X5X_IR_CLEAR_ALL);
435 if (err != 0) {
436 LOG_ERR("failed to write interrupt register (err %d)", err);
437 break;
438 }
439
440 if ((ir & CAN_TCAN4X5X_IR_SPIERR) != 0U) {
441 err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_STATUS, &status);
442 if (err != 0) {
443 LOG_ERR("failed to read status register (err %d)", err);
444 continue;
445 }
446
447 LOG_ERR("SPIERR, status = 0x%08x", status);
448
449 err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_STATUS, status &
450 CAN_TCAN4X5X_STATUS_CLEAR_ALL);
451 if (err != 0) {
452 LOG_ERR("failed to write status register (err %d)", err);
453 continue;
454 }
455 }
456
457 if ((ir & CAN_TCAN4X5X_IR_M_CAN_INT) != 0U) {
458 can_mcan_line_0_isr(dev);
459 can_mcan_line_1_isr(dev);
460 }
461
462 err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_IR, &ir);
463 if (err != 0) {
464 LOG_ERR("failed to read interrupt register (err %d)", err);
465 break;
466 }
467 }
468 }
469 }
470
tcan4x5x_wake(const struct device * dev)471 static int tcan4x5x_wake(const struct device *dev)
472 {
473 #if TCAN4X5X_WAKE_GPIO_SUPPORT
474 const struct can_mcan_config *mcan_config = dev->config;
475 const struct tcan4x5x_config *tcan_config = mcan_config->custom;
476 int wake_needed = 1;
477 int err;
478
479 #if TCAN4X5X_NWKRQ_GPIO_SUPPORT
480 if (tcan_config->wake_gpio.port != NULL && tcan_config->nwkrq_gpio.port != NULL) {
481 wake_needed = gpio_pin_get_dt(&tcan_config->nwkrq_gpio);
482
483 if (wake_needed < 0) {
484 LOG_ERR("failed to get nWKRQ status (err %d)", wake_needed);
485 return wake_needed;
486 };
487 }
488 #endif /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */
489 if (tcan_config->wake_gpio.port != NULL && wake_needed != 0) {
490 err = gpio_pin_set_dt(&tcan_config->wake_gpio, 1);
491 if (err != 0) {
492 LOG_ERR("failed to assert WAKE GPIO (err %d)", err);
493 return err;
494 }
495
496 k_busy_wait(CAN_TCAN4X5X_T_WAKE_US);
497
498 err = gpio_pin_set_dt(&tcan_config->wake_gpio, 0);
499 if (err != 0) {
500 LOG_ERR("failed to deassert WAKE GPIO (err %d)", err);
501 return err;
502 }
503 }
504 #endif /* TCAN4X5X_WAKE_GPIO_SUPPORT*/
505
506 return 0;
507 }
508
tcan4x5x_reset(const struct device * dev)509 static int tcan4x5x_reset(const struct device *dev)
510 {
511 #if TCAN4X5X_RST_GPIO_SUPPORT
512 const struct can_mcan_config *mcan_config = dev->config;
513 const struct tcan4x5x_config *tcan_config = mcan_config->custom;
514 #endif /* TCAN4X5X_RST_GPIO_SUPPORT */
515 int err;
516
517 err = tcan4x5x_wake(dev);
518 if (err != 0) {
519 return err;
520 }
521
522 #if TCAN4X5X_RST_GPIO_SUPPORT
523 if (tcan_config->rst_gpio.port != NULL) {
524 err = gpio_pin_set_dt(&tcan_config->rst_gpio, 1);
525 if (err != 0) {
526 LOG_ERR("failed to assert RST GPIO (err %d)", err);
527 return err;
528 }
529
530 k_busy_wait(CAN_TCAN4X5X_T_PULSE_WIDTH_US);
531
532 err = gpio_pin_set_dt(&tcan_config->rst_gpio, 0);
533 if (err != 0) {
534 LOG_ERR("failed to deassert RST GPIO (err %d)", err);
535 return err;
536 }
537 } else {
538 #endif /* TCAN4X5X_RST_GPIO_SUPPORT */
539 err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_MODE_CONFIG,
540 CAN_TCAN4X5X_MODE_CONFIG_DEVICE_RESET);
541 if (err != 0) {
542 LOG_ERR("failed to initiate SW reset (err %d)", err);
543 return err;
544 }
545 #if TCAN4X5X_RST_GPIO_SUPPORT
546 }
547 #endif /* TCAN4X5X_RST_GPIO_SUPPORT */
548
549 k_busy_wait(CAN_TCAN4X5X_T_RESET_US);
550
551 return 0;
552 }
553
tcan4x5x_init(const struct device * dev)554 static int tcan4x5x_init(const struct device *dev)
555 {
556 const struct can_mcan_config *mcan_config = dev->config;
557 const struct tcan4x5x_config *tcan_config = mcan_config->custom;
558 struct can_mcan_data *mcan_data = dev->data;
559 struct tcan4x5x_data *tcan_data = mcan_data->custom;
560 k_tid_t tid;
561 uint32_t reg;
562 int err;
563
564 /* Initialize int_sem to 1 to ensure any pending IRQ is serviced */
565 k_sem_init(&tcan_data->int_sem, 1, 1);
566
567 if (!spi_is_ready_dt(&tcan_config->spi)) {
568 LOG_ERR("SPI bus not ready");
569 return -ENODEV;
570 }
571
572 #if TCAN4X5X_RST_GPIO_SUPPORT
573 if (tcan_config->rst_gpio.port != NULL) {
574 if (!gpio_is_ready_dt(&tcan_config->rst_gpio)) {
575 LOG_ERR("RST GPIO not ready");
576 return -ENODEV;
577 }
578
579 err = gpio_pin_configure_dt(&tcan_config->rst_gpio, GPIO_OUTPUT_INACTIVE);
580 if (err != 0) {
581 LOG_ERR("failed to configure RST GPIO (err %d)", err);
582 return -ENODEV;
583 }
584 }
585 #endif /* TCAN4X5X_RST_GPIO_SUPPORT */
586
587 #if TCAN4X5X_NWKRQ_GPIO_SUPPORT
588 if (tcan_config->nwkrq_gpio.port != NULL) {
589 if (!gpio_is_ready_dt(&tcan_config->nwkrq_gpio)) {
590 LOG_ERR("nWKRQ GPIO not ready");
591 return -ENODEV;
592 }
593
594 err = gpio_pin_configure_dt(&tcan_config->nwkrq_gpio, GPIO_INPUT);
595 if (err != 0) {
596 LOG_ERR("failed to configure nWKRQ GPIO (err %d)", err);
597 return -ENODEV;
598 }
599 }
600 #endif /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */
601
602 #if TCAN4X5X_WAKE_GPIO_SUPPORT
603 if (tcan_config->wake_gpio.port != NULL) {
604 if (!gpio_is_ready_dt(&tcan_config->wake_gpio)) {
605 LOG_ERR("WAKE GPIO not ready");
606 return -ENODEV;
607 }
608
609 err = gpio_pin_configure_dt(&tcan_config->wake_gpio, GPIO_OUTPUT_INACTIVE);
610 if (err != 0) {
611 LOG_ERR("failed to configure WAKE GPIO (err %d)", err);
612 return -ENODEV;
613 }
614 }
615 #endif /* TCAN4X5X_WAKE_GPIO_SUPPORT */
616
617 if (!gpio_is_ready_dt(&tcan_config->int_gpio)) {
618 LOG_ERR("nINT GPIO not ready");
619 return -ENODEV;
620 }
621
622 err = gpio_pin_configure_dt(&tcan_config->int_gpio, GPIO_INPUT);
623 if (err != 0) {
624 LOG_ERR("failed to configure nINT GPIO (err %d)", err);
625 return -ENODEV;
626 }
627
628 gpio_init_callback(&tcan_data->int_gpio_cb, tcan4x5x_int_gpio_callback_handler,
629 BIT(tcan_config->int_gpio.pin));
630
631 err = gpio_add_callback_dt(&tcan_config->int_gpio, &tcan_data->int_gpio_cb);
632 if (err != 0) {
633 LOG_ERR("failed to add nINT GPIO callback (err %d)", err);
634 return -ENODEV;
635 }
636
637 /* Initialize nINT GPIO callback and interrupt handler thread to ACK any early SPIERR */
638 err = gpio_pin_interrupt_configure_dt(&tcan_config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);
639 if (err != 0) {
640 LOG_ERR("failed to configure nINT GPIO interrupt (err %d)", err);
641 return -ENODEV;
642 }
643
644 tid = k_thread_create(&tcan_data->int_thread, tcan_data->int_stack,
645 K_KERNEL_STACK_SIZEOF(tcan_data->int_stack),
646 tcan4x5x_int_thread, (void *)dev, NULL, NULL,
647 CONFIG_CAN_TCAN4X5X_THREAD_PRIO, 0, K_NO_WAIT);
648 k_thread_name_set(tid, "tcan4x5x");
649
650 /* Reset TCAN */
651 err = tcan4x5x_reset(dev);
652 if (err != 0) {
653 return -ENODEV;
654 }
655
656 #if CONFIG_CAN_LOG_LEVEL >= LOG_LEVEL_DBG
657 uint32_t info[3];
658
659 /* Read DEVICE_ID1, DEVICE_ID2, and REVISION registers */
660 err = tcan4x5x_read(dev, CAN_TCAN4X5X_DEVICE_ID1, &info, sizeof(info));
661 if (err != 0) {
662 return -EIO;
663 }
664
665 LOG_DBG("%c%c%c%c%c%c%c%c, SPI 2 rev. %lu, device rev. ID %lu.%lu",
666 (char)FIELD_GET(GENMASK(7, 0), info[0]), (char)FIELD_GET(GENMASK(15, 8), info[0]),
667 (char)FIELD_GET(GENMASK(23, 16), info[0]),
668 (char)FIELD_GET(GENMASK(31, 24), info[0]), (char)FIELD_GET(GENMASK(7, 0), info[1]),
669 (char)FIELD_GET(GENMASK(15, 8), info[1]), (char)FIELD_GET(GENMASK(23, 16), info[1]),
670 (char)FIELD_GET(GENMASK(31, 24), info[1]), FIELD_GET(GENMASK(31, 24), info[2]),
671 FIELD_GET(GENMASK(15, 8), info[2]), FIELD_GET(GENMASK(7, 0), info[2]));
672 #endif /* CONFIG_CAN_LOG_LEVEL >= LOG_LEVEL_DBG */
673
674 /* Set TCAN4x5x mode normal */
675 err = tcan4x5x_read_tcan_reg(dev, CAN_TCAN4X5X_MODE_CONFIG, ®);
676 if (err != 0) {
677 LOG_ERR("failed to read configuration register (err %d)", err);
678 return -ENODEV;
679 }
680
681 reg &= ~(CAN_TCAN4X5X_MODE_CONFIG_MODE_SEL);
682 reg |= FIELD_PREP(CAN_TCAN4X5X_MODE_CONFIG_MODE_SEL, 0x02);
683 reg |= CAN_TCAN4X5X_MODE_CONFIG_WAKE_CONFIG;
684
685 if (tcan_config->clk_freq == MHZ(20)) {
686 /* 20 MHz frequency reference */
687 reg &= ~(CAN_TCAN4X5X_MODE_CONFIG_CLK_REF);
688 } else {
689 /* 40 MHz frequency reference */
690 reg |= CAN_TCAN4X5X_MODE_CONFIG_CLK_REF;
691 }
692
693 err = tcan4x5x_write_tcan_reg(dev, CAN_TCAN4X5X_MODE_CONFIG, reg);
694 if (err != 0) {
695 LOG_ERR("failed to write configuration register (err %d)", err);
696 return -ENODEV;
697 }
698
699 /* Wait for standby to normal mode switch */
700 k_busy_wait(CAN_TCAN4X5X_T_MODE_STBY_NOM_US);
701
702 /* Configure Message RAM */
703 err = can_mcan_configure_mram(dev, CAN_TCAN4X5X_MRAM_BASE, CAN_TCAN4X5X_MRAM_BASE);
704 if (err != 0) {
705 return -EIO;
706 }
707
708 /* Initialize M_CAN */
709 err = can_mcan_init(dev);
710 if (err != 0) {
711 LOG_ERR("failed to initialize mcan (err %d)", err);
712 return err;
713 }
714
715 return 0;
716 }
717
718 static DEVICE_API(can, tcan4x5x_driver_api) = {
719 .get_capabilities = can_mcan_get_capabilities,
720 .start = can_mcan_start,
721 .stop = can_mcan_stop,
722 .set_mode = can_mcan_set_mode,
723 .set_timing = can_mcan_set_timing,
724 .send = can_mcan_send,
725 .add_rx_filter = can_mcan_add_rx_filter,
726 .remove_rx_filter = can_mcan_remove_rx_filter,
727 #ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE
728 .recover = can_mcan_recover,
729 #endif /* CONFIG_CAN_MANUAL_RECOVERY_MODE */
730 .get_state = can_mcan_get_state,
731 .set_state_change_callback = can_mcan_set_state_change_callback,
732 .get_core_clock = tcan4x5x_get_core_clock,
733 .get_max_filters = can_mcan_get_max_filters,
734 .timing_min = CAN_MCAN_TIMING_MIN_INITIALIZER,
735 .timing_max = CAN_MCAN_TIMING_MAX_INITIALIZER,
736 #ifdef CONFIG_CAN_FD_MODE
737 .set_timing_data = can_mcan_set_timing_data,
738 .timing_data_min = CAN_MCAN_TIMING_DATA_MIN_INITIALIZER,
739 .timing_data_max = CAN_MCAN_TIMING_DATA_MAX_INITIALIZER,
740 #endif /* CONFIG_CAN_FD_MODE */
741 };
742
743 static const struct can_mcan_ops tcan4x5x_ops = {
744 .read_reg = tcan4x5x_read_mcan_reg,
745 .write_reg = tcan4x5x_write_mcan_reg,
746 .read_mram = tcan4x5x_read_mcan_mram,
747 .write_mram = tcan4x5x_write_mcan_mram,
748 .clear_mram = tcan4x5x_clear_mcan_mram,
749 };
750
751 #if TCAN4X5X_RST_GPIO_SUPPORT
752 #define TCAN4X5X_RST_GPIO_INIT(inst) \
753 .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}),
754 #else /* TCAN4X5X_RST_GPIO_SUPPORT */
755 #define TCAN4X5X_RST_GPIO_INIT(inst)
756 #endif /* !TCAN4X5X_RST_GPIO_SUPPORT */
757
758 #if TCAN4X5X_NWKRQ_GPIO_SUPPORT
759 #define TCAN4X5X_NWKRQ_GPIO_INIT(inst) \
760 .nwkrq_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, device_state_gpios, {0}),
761 #else /* TCAN4X5X_NWKRQ_GPIO_SUPPORT */
762 #define TCAN4X5X_NWKRQ_GPIO_INIT(inst)
763 #endif /* !TCAN4X5X_NWKRQ_GPIO_SUPPORT */
764
765 #if TCAN4X5X_WAKE_GPIO_SUPPORT
766 #define TCAN4X5X_WAKE_GPIO_INIT(inst) \
767 .wake_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, device_wake_gpios, {0}),
768 #else /* TCAN4X5X_WAKE_GPIO_SUPPORT */
769 #define TCAN4X5X_WAKE_GPIO_INIT(inst)
770 #endif /* !TCAN4X5X_WAKE_GPIO_SUPPORT */
771
772 #define TCAN4X5X_INIT(inst) \
773 BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_OFFSET(inst) == 0, "MRAM offset must be 0"); \
774 BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(inst) <= CAN_TCAN4X5X_MRAM_SIZE, \
775 "Insufficient Message RAM size to hold elements"); \
776 \
777 CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst); \
778 CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, tcan4x5x_cbs_##inst); \
779 \
780 static const struct tcan4x5x_config tcan4x5x_config_##inst = { \
781 .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \
782 .int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \
783 .clk_freq = DT_INST_PROP(inst, clock_frequency), \
784 TCAN4X5X_RST_GPIO_INIT(inst) \
785 TCAN4X5X_NWKRQ_GPIO_INIT(inst) \
786 TCAN4X5X_WAKE_GPIO_INIT(inst) \
787 }; \
788 \
789 static const struct can_mcan_config can_mcan_config_##inst = CAN_MCAN_DT_CONFIG_INST_GET( \
790 inst, &tcan4x5x_config_##inst, &tcan4x5x_ops, &tcan4x5x_cbs_##inst); \
791 \
792 static struct tcan4x5x_data tcan4x5x_data_##inst; \
793 \
794 static struct can_mcan_data can_mcan_data_##inst = \
795 CAN_MCAN_DATA_INITIALIZER(&tcan4x5x_data_##inst); \
796 \
797 CAN_DEVICE_DT_INST_DEFINE(inst, tcan4x5x_init, NULL, &can_mcan_data_##inst, \
798 &can_mcan_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \
799 &tcan4x5x_driver_api);
800
801 DT_INST_FOREACH_STATUS_OKAY(TCAN4X5X_INIT)
802