1 // SPDX-License-Identifier: GPL-2.0 2 // SPI to CAN driver for the Texas Instruments TCAN4x5x 3 // Copyright (C) 2018-19 Texas Instruments Incorporated - http://www.ti.com/ 4 5 #include "tcan4x5x.h" 6 7 #define TCAN4X5X_EXT_CLK_DEF 40000000 8 9 #define TCAN4X5X_DEV_ID1 0x00 10 #define TCAN4X5X_DEV_ID1_TCAN 0x4e414354 /* ASCII TCAN */ 11 #define TCAN4X5X_DEV_ID2 0x04 12 #define TCAN4X5X_REV 0x08 13 #define TCAN4X5X_STATUS 0x0C 14 #define TCAN4X5X_ERROR_STATUS_MASK 0x10 15 #define TCAN4X5X_CONTROL 0x14 16 17 #define TCAN4X5X_CONFIG 0x800 18 #define TCAN4X5X_TS_PRESCALE 0x804 19 #define TCAN4X5X_TEST_REG 0x808 20 #define TCAN4X5X_INT_FLAGS 0x820 21 #define TCAN4X5X_MCAN_INT_REG 0x824 22 #define TCAN4X5X_INT_EN 0x830 23 24 /* Interrupt bits */ 25 #define TCAN4X5X_CANBUSTERMOPEN_INT_EN BIT(30) 26 #define TCAN4X5X_CANHCANL_INT_EN BIT(29) 27 #define TCAN4X5X_CANHBAT_INT_EN BIT(28) 28 #define TCAN4X5X_CANLGND_INT_EN BIT(27) 29 #define TCAN4X5X_CANBUSOPEN_INT_EN BIT(26) 30 #define TCAN4X5X_CANBUSGND_INT_EN BIT(25) 31 #define TCAN4X5X_CANBUSBAT_INT_EN BIT(24) 32 #define TCAN4X5X_UVSUP_INT_EN BIT(22) 33 #define TCAN4X5X_UVIO_INT_EN BIT(21) 34 #define TCAN4X5X_TSD_INT_EN BIT(19) 35 #define TCAN4X5X_ECCERR_INT_EN BIT(16) 36 #define TCAN4X5X_CANINT_INT_EN BIT(15) 37 #define TCAN4X5X_LWU_INT_EN BIT(14) 38 #define TCAN4X5X_CANSLNT_INT_EN BIT(10) 39 #define TCAN4X5X_CANDOM_INT_EN BIT(8) 40 #define TCAN4X5X_CANBUS_ERR_INT_EN BIT(5) 41 #define TCAN4X5X_BUS_FAULT BIT(4) 42 #define TCAN4X5X_MCAN_INT BIT(1) 43 #define TCAN4X5X_ENABLE_TCAN_INT \ 44 (TCAN4X5X_MCAN_INT | TCAN4X5X_BUS_FAULT | \ 45 TCAN4X5X_CANBUS_ERR_INT_EN | TCAN4X5X_CANINT_INT_EN) 46 47 /* MCAN Interrupt bits */ 48 #define TCAN4X5X_MCAN_IR_ARA BIT(29) 49 #define TCAN4X5X_MCAN_IR_PED BIT(28) 50 #define TCAN4X5X_MCAN_IR_PEA BIT(27) 51 #define TCAN4X5X_MCAN_IR_WD BIT(26) 52 #define TCAN4X5X_MCAN_IR_BO BIT(25) 53 #define TCAN4X5X_MCAN_IR_EW BIT(24) 54 #define TCAN4X5X_MCAN_IR_EP BIT(23) 55 #define TCAN4X5X_MCAN_IR_ELO BIT(22) 56 #define TCAN4X5X_MCAN_IR_BEU BIT(21) 57 #define TCAN4X5X_MCAN_IR_BEC BIT(20) 58 #define TCAN4X5X_MCAN_IR_DRX BIT(19) 59 #define TCAN4X5X_MCAN_IR_TOO BIT(18) 60 #define TCAN4X5X_MCAN_IR_MRAF BIT(17) 61 #define TCAN4X5X_MCAN_IR_TSW BIT(16) 62 #define TCAN4X5X_MCAN_IR_TEFL BIT(15) 63 #define TCAN4X5X_MCAN_IR_TEFF BIT(14) 64 #define TCAN4X5X_MCAN_IR_TEFW BIT(13) 65 #define TCAN4X5X_MCAN_IR_TEFN BIT(12) 66 #define TCAN4X5X_MCAN_IR_TFE BIT(11) 67 #define TCAN4X5X_MCAN_IR_TCF BIT(10) 68 #define TCAN4X5X_MCAN_IR_TC BIT(9) 69 #define TCAN4X5X_MCAN_IR_HPM BIT(8) 70 #define TCAN4X5X_MCAN_IR_RF1L BIT(7) 71 #define TCAN4X5X_MCAN_IR_RF1F BIT(6) 72 #define TCAN4X5X_MCAN_IR_RF1W BIT(5) 73 #define TCAN4X5X_MCAN_IR_RF1N BIT(4) 74 #define TCAN4X5X_MCAN_IR_RF0L BIT(3) 75 #define TCAN4X5X_MCAN_IR_RF0F BIT(2) 76 #define TCAN4X5X_MCAN_IR_RF0W BIT(1) 77 #define TCAN4X5X_MCAN_IR_RF0N BIT(0) 78 #define TCAN4X5X_ENABLE_MCAN_INT \ 79 (TCAN4X5X_MCAN_IR_TC | TCAN4X5X_MCAN_IR_RF0N | \ 80 TCAN4X5X_MCAN_IR_RF1N | TCAN4X5X_MCAN_IR_RF0F | \ 81 TCAN4X5X_MCAN_IR_RF1F) 82 83 #define TCAN4X5X_MRAM_START 0x8000 84 #define TCAN4X5X_MRAM_SIZE 0x800 85 #define TCAN4X5X_MCAN_OFFSET 0x1000 86 87 #define TCAN4X5X_CLEAR_ALL_INT 0xffffffff 88 #define TCAN4X5X_SET_ALL_INT 0xffffffff 89 90 #define TCAN4X5X_MODE_SEL_MASK (BIT(7) | BIT(6)) 91 #define TCAN4X5X_MODE_SLEEP 0x00 92 #define TCAN4X5X_MODE_STANDBY BIT(6) 93 #define TCAN4X5X_MODE_NORMAL BIT(7) 94 95 #define TCAN4X5X_DISABLE_WAKE_MSK (BIT(31) | BIT(30)) 96 #define TCAN4X5X_DISABLE_INH_MSK BIT(9) 97 98 #define TCAN4X5X_SW_RESET BIT(2) 99 100 #define TCAN4X5X_MCAN_CONFIGURED BIT(5) 101 #define TCAN4X5X_WATCHDOG_EN BIT(3) 102 #define TCAN4X5X_WD_60_MS_TIMER 0 103 #define TCAN4X5X_WD_600_MS_TIMER BIT(28) 104 #define TCAN4X5X_WD_3_S_TIMER BIT(29) 105 #define TCAN4X5X_WD_6_S_TIMER (BIT(28) | BIT(29)) 106 107 struct tcan4x5x_version_info { 108 const char *name; 109 u32 id2_register; 110 111 bool has_wake_pin; 112 bool has_state_pin; 113 }; 114 115 enum { 116 TCAN4552 = 0, 117 TCAN4553, 118 TCAN4X5X, 119 }; 120 121 static const struct tcan4x5x_version_info tcan4x5x_versions[] = { 122 [TCAN4552] = { 123 .name = "4552", 124 .id2_register = 0x32353534, 125 }, 126 [TCAN4553] = { 127 .name = "4553", 128 .id2_register = 0x33353534, 129 }, 130 /* generic version with no id2_register at the end */ 131 [TCAN4X5X] = { 132 .name = "generic", 133 .has_wake_pin = true, 134 .has_state_pin = true, 135 }, 136 }; 137 138 static inline struct tcan4x5x_priv *cdev_to_priv(struct m_can_classdev *cdev) 139 { 140 return container_of(cdev, struct tcan4x5x_priv, cdev); 141 } 142 143 static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv) 144 { 145 int wake_state = 0; 146 147 if (priv->device_state_gpio) 148 wake_state = gpiod_get_value(priv->device_state_gpio); 149 150 if (priv->device_wake_gpio && wake_state) { 151 gpiod_set_value(priv->device_wake_gpio, 0); 152 usleep_range(5, 50); 153 gpiod_set_value(priv->device_wake_gpio, 1); 154 } 155 } 156 157 static int tcan4x5x_reset(struct tcan4x5x_priv *priv) 158 { 159 int ret = 0; 160 161 if (priv->reset_gpio) { 162 gpiod_set_value(priv->reset_gpio, 1); 163 164 /* tpulse_width minimum 30us */ 165 usleep_range(30, 100); 166 gpiod_set_value(priv->reset_gpio, 0); 167 } else { 168 ret = regmap_write(priv->regmap, TCAN4X5X_CONFIG, 169 TCAN4X5X_SW_RESET); 170 if (ret) 171 return ret; 172 } 173 174 usleep_range(700, 1000); 175 176 return ret; 177 } 178 179 static u32 tcan4x5x_read_reg(struct m_can_classdev *cdev, int reg) 180 { 181 struct tcan4x5x_priv *priv = cdev_to_priv(cdev); 182 u32 val; 183 184 regmap_read(priv->regmap, TCAN4X5X_MCAN_OFFSET + reg, &val); 185 186 return val; 187 } 188 189 static int tcan4x5x_read_fifo(struct m_can_classdev *cdev, int addr_offset, 190 void *val, size_t val_count) 191 { 192 struct tcan4x5x_priv *priv = cdev_to_priv(cdev); 193 194 return regmap_bulk_read(priv->regmap, TCAN4X5X_MRAM_START + addr_offset, val, val_count); 195 } 196 197 static int tcan4x5x_write_reg(struct m_can_classdev *cdev, int reg, int val) 198 { 199 struct tcan4x5x_priv *priv = cdev_to_priv(cdev); 200 201 return regmap_write(priv->regmap, TCAN4X5X_MCAN_OFFSET + reg, val); 202 } 203 204 static int tcan4x5x_write_fifo(struct m_can_classdev *cdev, 205 int addr_offset, const void *val, size_t val_count) 206 { 207 struct tcan4x5x_priv *priv = cdev_to_priv(cdev); 208 209 return regmap_bulk_write(priv->regmap, TCAN4X5X_MRAM_START + addr_offset, val, val_count); 210 } 211 212 static int tcan4x5x_power_enable(struct regulator *reg, int enable) 213 { 214 if (IS_ERR_OR_NULL(reg)) 215 return 0; 216 217 if (enable) 218 return regulator_enable(reg); 219 else 220 return regulator_disable(reg); 221 } 222 223 static int tcan4x5x_write_tcan_reg(struct m_can_classdev *cdev, 224 int reg, int val) 225 { 226 struct tcan4x5x_priv *priv = cdev_to_priv(cdev); 227 228 return regmap_write(priv->regmap, reg, val); 229 } 230 231 static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev) 232 { 233 int ret; 234 235 ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_STATUS, 236 TCAN4X5X_CLEAR_ALL_INT); 237 if (ret) 238 return ret; 239 240 return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS, 241 TCAN4X5X_CLEAR_ALL_INT); 242 } 243 244 static int tcan4x5x_init(struct m_can_classdev *cdev) 245 { 246 struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); 247 int ret; 248 249 tcan4x5x_check_wake(tcan4x5x); 250 251 ret = tcan4x5x_clear_interrupts(cdev); 252 if (ret) 253 return ret; 254 255 ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_EN, 256 TCAN4X5X_ENABLE_TCAN_INT); 257 if (ret) 258 return ret; 259 260 ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS_MASK, 261 TCAN4X5X_CLEAR_ALL_INT); 262 if (ret) 263 return ret; 264 265 ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, 266 TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL); 267 if (ret) 268 return ret; 269 270 return ret; 271 } 272 273 static int tcan4x5x_disable_wake(struct m_can_classdev *cdev) 274 { 275 struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); 276 277 return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, 278 TCAN4X5X_DISABLE_WAKE_MSK, 0x00); 279 } 280 281 static int tcan4x5x_disable_state(struct m_can_classdev *cdev) 282 { 283 struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); 284 285 return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, 286 TCAN4X5X_DISABLE_INH_MSK, 0x01); 287 } 288 289 static const struct tcan4x5x_version_info 290 *tcan4x5x_find_version(struct tcan4x5x_priv *priv) 291 { 292 u32 val; 293 int ret; 294 295 ret = regmap_read(priv->regmap, TCAN4X5X_DEV_ID1, &val); 296 if (ret) 297 return ERR_PTR(ret); 298 299 if (val != TCAN4X5X_DEV_ID1_TCAN) { 300 dev_err(&priv->spi->dev, "Not a tcan device %x\n", val); 301 return ERR_PTR(-ENODEV); 302 } 303 304 ret = regmap_read(priv->regmap, TCAN4X5X_DEV_ID2, &val); 305 if (ret) 306 return ERR_PTR(ret); 307 308 for (int i = 0; i != ARRAY_SIZE(tcan4x5x_versions); ++i) { 309 const struct tcan4x5x_version_info *vinfo = &tcan4x5x_versions[i]; 310 311 if (!vinfo->id2_register || val == vinfo->id2_register) { 312 dev_info(&priv->spi->dev, "Detected TCAN device version %s\n", 313 vinfo->name); 314 return vinfo; 315 } 316 } 317 318 return &tcan4x5x_versions[TCAN4X5X]; 319 } 320 321 static int tcan4x5x_get_gpios(struct m_can_classdev *cdev, 322 const struct tcan4x5x_version_info *version_info) 323 { 324 struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); 325 int ret; 326 327 if (version_info->has_wake_pin) { 328 tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake", 329 GPIOD_OUT_HIGH); 330 if (IS_ERR(tcan4x5x->device_wake_gpio)) { 331 if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER) 332 return -EPROBE_DEFER; 333 334 tcan4x5x_disable_wake(cdev); 335 } 336 } 337 338 tcan4x5x->reset_gpio = devm_gpiod_get_optional(cdev->dev, "reset", 339 GPIOD_OUT_LOW); 340 if (IS_ERR(tcan4x5x->reset_gpio)) 341 tcan4x5x->reset_gpio = NULL; 342 343 ret = tcan4x5x_reset(tcan4x5x); 344 if (ret) 345 return ret; 346 347 if (version_info->has_state_pin) { 348 tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev, 349 "device-state", 350 GPIOD_IN); 351 if (IS_ERR(tcan4x5x->device_state_gpio)) { 352 tcan4x5x->device_state_gpio = NULL; 353 tcan4x5x_disable_state(cdev); 354 } 355 } 356 357 return 0; 358 } 359 360 static struct m_can_ops tcan4x5x_ops = { 361 .init = tcan4x5x_init, 362 .read_reg = tcan4x5x_read_reg, 363 .write_reg = tcan4x5x_write_reg, 364 .write_fifo = tcan4x5x_write_fifo, 365 .read_fifo = tcan4x5x_read_fifo, 366 .clear_interrupts = tcan4x5x_clear_interrupts, 367 }; 368 369 static int tcan4x5x_can_probe(struct spi_device *spi) 370 { 371 const struct tcan4x5x_version_info *version_info; 372 struct tcan4x5x_priv *priv; 373 struct m_can_classdev *mcan_class; 374 int freq, ret; 375 376 mcan_class = m_can_class_allocate_dev(&spi->dev, 377 sizeof(struct tcan4x5x_priv)); 378 if (!mcan_class) 379 return -ENOMEM; 380 381 ret = m_can_check_mram_cfg(mcan_class, TCAN4X5X_MRAM_SIZE); 382 if (ret) 383 goto out_m_can_class_free_dev; 384 385 priv = cdev_to_priv(mcan_class); 386 387 priv->power = devm_regulator_get_optional(&spi->dev, "vsup"); 388 if (PTR_ERR(priv->power) == -EPROBE_DEFER) { 389 ret = -EPROBE_DEFER; 390 goto out_m_can_class_free_dev; 391 } else { 392 priv->power = NULL; 393 } 394 395 m_can_class_get_clocks(mcan_class); 396 if (IS_ERR(mcan_class->cclk)) { 397 dev_err(&spi->dev, "no CAN clock source defined\n"); 398 freq = TCAN4X5X_EXT_CLK_DEF; 399 } else { 400 freq = clk_get_rate(mcan_class->cclk); 401 } 402 403 /* Sanity check */ 404 if (freq < 20000000 || freq > TCAN4X5X_EXT_CLK_DEF) { 405 dev_err(&spi->dev, "Clock frequency is out of supported range %d\n", 406 freq); 407 ret = -ERANGE; 408 goto out_m_can_class_free_dev; 409 } 410 411 priv->spi = spi; 412 413 mcan_class->pm_clock_support = 0; 414 mcan_class->can.clock.freq = freq; 415 mcan_class->dev = &spi->dev; 416 mcan_class->ops = &tcan4x5x_ops; 417 mcan_class->is_peripheral = true; 418 mcan_class->net->irq = spi->irq; 419 420 spi_set_drvdata(spi, priv); 421 422 /* Configure the SPI bus */ 423 spi->bits_per_word = 8; 424 ret = spi_setup(spi); 425 if (ret) { 426 dev_err(&spi->dev, "SPI setup failed %pe\n", ERR_PTR(ret)); 427 goto out_m_can_class_free_dev; 428 } 429 430 ret = tcan4x5x_regmap_init(priv); 431 if (ret) { 432 dev_err(&spi->dev, "regmap init failed %pe\n", ERR_PTR(ret)); 433 goto out_m_can_class_free_dev; 434 } 435 436 ret = tcan4x5x_power_enable(priv->power, 1); 437 if (ret) { 438 dev_err(&spi->dev, "Enabling regulator failed %pe\n", 439 ERR_PTR(ret)); 440 goto out_m_can_class_free_dev; 441 } 442 443 version_info = tcan4x5x_find_version(priv); 444 if (IS_ERR(version_info)) { 445 ret = PTR_ERR(version_info); 446 goto out_power; 447 } 448 449 ret = tcan4x5x_get_gpios(mcan_class, version_info); 450 if (ret) { 451 dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret)); 452 goto out_power; 453 } 454 455 ret = tcan4x5x_init(mcan_class); 456 if (ret) { 457 dev_err(&spi->dev, "tcan initialization failed %pe\n", 458 ERR_PTR(ret)); 459 goto out_power; 460 } 461 462 ret = m_can_class_register(mcan_class); 463 if (ret) { 464 dev_err(&spi->dev, "Failed registering m_can device %pe\n", 465 ERR_PTR(ret)); 466 goto out_power; 467 } 468 469 netdev_info(mcan_class->net, "TCAN4X5X successfully initialized.\n"); 470 return 0; 471 472 out_power: 473 tcan4x5x_power_enable(priv->power, 0); 474 out_m_can_class_free_dev: 475 m_can_class_free_dev(mcan_class->net); 476 return ret; 477 } 478 479 static void tcan4x5x_can_remove(struct spi_device *spi) 480 { 481 struct tcan4x5x_priv *priv = spi_get_drvdata(spi); 482 483 m_can_class_unregister(&priv->cdev); 484 485 tcan4x5x_power_enable(priv->power, 0); 486 487 m_can_class_free_dev(priv->cdev.net); 488 } 489 490 static const struct of_device_id tcan4x5x_of_match[] = { 491 { 492 .compatible = "ti,tcan4x5x", 493 }, { 494 /* sentinel */ 495 }, 496 }; 497 MODULE_DEVICE_TABLE(of, tcan4x5x_of_match); 498 499 static const struct spi_device_id tcan4x5x_id_table[] = { 500 { 501 .name = "tcan4x5x", 502 }, { 503 /* sentinel */ 504 }, 505 }; 506 MODULE_DEVICE_TABLE(spi, tcan4x5x_id_table); 507 508 static struct spi_driver tcan4x5x_can_driver = { 509 .driver = { 510 .name = KBUILD_MODNAME, 511 .of_match_table = tcan4x5x_of_match, 512 .pm = NULL, 513 }, 514 .id_table = tcan4x5x_id_table, 515 .probe = tcan4x5x_can_probe, 516 .remove = tcan4x5x_can_remove, 517 }; 518 module_spi_driver(tcan4x5x_can_driver); 519 520 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 521 MODULE_DESCRIPTION("Texas Instruments TCAN4x5x CAN driver"); 522 MODULE_LICENSE("GPL v2"); 523