1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2020 Microchip 4 * 5 * Author: Kamel Bouhara <kamel.bouhara@bootlin.com> 6 */ 7 #include <linux/clk.h> 8 #include <linux/counter.h> 9 #include <linux/interrupt.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/module.h> 12 #include <linux/mutex.h> 13 #include <linux/of.h> 14 #include <linux/of_irq.h> 15 #include <linux/platform_device.h> 16 #include <linux/regmap.h> 17 #include <uapi/linux/counter/microchip-tcb-capture.h> 18 #include <soc/at91/atmel_tcb.h> 19 20 #define ATMEL_TC_CMR_MASK (ATMEL_TC_LDRA_RISING | ATMEL_TC_LDRB_FALLING | \ 21 ATMEL_TC_ETRGEDG_RISING | ATMEL_TC_LDBDIS | \ 22 ATMEL_TC_LDBSTOP) 23 24 #define ATMEL_TC_DEF_IRQS (ATMEL_TC_ETRGS | ATMEL_TC_COVFS | \ 25 ATMEL_TC_LDRAS | ATMEL_TC_LDRBS | ATMEL_TC_CPCS) 26 27 #define ATMEL_TC_QDEN BIT(8) 28 #define ATMEL_TC_POSEN BIT(9) 29 30 struct mchp_tc_data { 31 const struct atmel_tcb_config *tc_cfg; 32 struct regmap *regmap; 33 int qdec_mode; 34 int num_channels; 35 int channel[2]; 36 }; 37 38 static const enum counter_function mchp_tc_count_functions[] = { 39 COUNTER_FUNCTION_INCREASE, 40 COUNTER_FUNCTION_QUADRATURE_X4, 41 }; 42 43 static const enum counter_synapse_action mchp_tc_synapse_actions[] = { 44 COUNTER_SYNAPSE_ACTION_NONE, 45 COUNTER_SYNAPSE_ACTION_RISING_EDGE, 46 COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 47 COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 48 }; 49 50 static struct counter_signal mchp_tc_count_signals[] = { 51 { 52 .id = 0, 53 .name = "Channel A", 54 }, 55 { 56 .id = 1, 57 .name = "Channel B", 58 } 59 }; 60 61 static struct counter_synapse mchp_tc_count_synapses[] = { 62 { 63 .actions_list = mchp_tc_synapse_actions, 64 .num_actions = ARRAY_SIZE(mchp_tc_synapse_actions), 65 .signal = &mchp_tc_count_signals[0] 66 }, 67 { 68 .actions_list = mchp_tc_synapse_actions, 69 .num_actions = ARRAY_SIZE(mchp_tc_synapse_actions), 70 .signal = &mchp_tc_count_signals[1] 71 } 72 }; 73 74 static int mchp_tc_count_function_read(struct counter_device *counter, 75 struct counter_count *count, 76 enum counter_function *function) 77 { 78 struct mchp_tc_data *const priv = counter_priv(counter); 79 80 if (priv->qdec_mode) 81 *function = COUNTER_FUNCTION_QUADRATURE_X4; 82 else 83 *function = COUNTER_FUNCTION_INCREASE; 84 85 return 0; 86 } 87 88 static int mchp_tc_count_function_write(struct counter_device *counter, 89 struct counter_count *count, 90 enum counter_function function) 91 { 92 struct mchp_tc_data *const priv = counter_priv(counter); 93 u32 bmr, cmr; 94 95 regmap_read(priv->regmap, ATMEL_TC_BMR, &bmr); 96 regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr); 97 98 /* Set capture mode */ 99 cmr &= ~ATMEL_TC_WAVE; 100 101 switch (function) { 102 case COUNTER_FUNCTION_INCREASE: 103 priv->qdec_mode = 0; 104 /* Set highest rate based on whether soc has gclk or not */ 105 bmr &= ~(ATMEL_TC_QDEN | ATMEL_TC_POSEN); 106 if (!priv->tc_cfg->has_gclk) 107 cmr |= ATMEL_TC_TIMER_CLOCK2; 108 else 109 cmr |= ATMEL_TC_TIMER_CLOCK1; 110 /* Setup the period capture mode */ 111 cmr |= ATMEL_TC_CMR_MASK; 112 cmr &= ~(ATMEL_TC_ABETRG | ATMEL_TC_XC0); 113 break; 114 case COUNTER_FUNCTION_QUADRATURE_X4: 115 if (!priv->tc_cfg->has_qdec) 116 return -EINVAL; 117 /* In QDEC mode settings both channels 0 and 1 are required */ 118 if (priv->num_channels < 2 || priv->channel[0] != 0 || 119 priv->channel[1] != 1) { 120 pr_err("Invalid channels number or id for quadrature mode\n"); 121 return -EINVAL; 122 } 123 priv->qdec_mode = 1; 124 bmr |= ATMEL_TC_QDEN | ATMEL_TC_POSEN; 125 cmr |= ATMEL_TC_ETRGEDG_RISING | ATMEL_TC_ABETRG | ATMEL_TC_XC0; 126 break; 127 default: 128 /* should never reach this path */ 129 return -EINVAL; 130 } 131 132 regmap_write(priv->regmap, ATMEL_TC_BMR, bmr); 133 regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), cmr); 134 135 /* Enable clock and trigger counter */ 136 regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], CCR), 137 ATMEL_TC_CLKEN | ATMEL_TC_SWTRG); 138 139 if (priv->qdec_mode) { 140 regmap_write(priv->regmap, 141 ATMEL_TC_REG(priv->channel[1], CMR), cmr); 142 regmap_write(priv->regmap, 143 ATMEL_TC_REG(priv->channel[1], CCR), 144 ATMEL_TC_CLKEN | ATMEL_TC_SWTRG); 145 } 146 147 return 0; 148 } 149 150 static int mchp_tc_count_signal_read(struct counter_device *counter, 151 struct counter_signal *signal, 152 enum counter_signal_level *lvl) 153 { 154 struct mchp_tc_data *const priv = counter_priv(counter); 155 bool sigstatus; 156 u32 sr; 157 158 regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], SR), &sr); 159 160 if (signal->id == 1) 161 sigstatus = (sr & ATMEL_TC_MTIOB); 162 else 163 sigstatus = (sr & ATMEL_TC_MTIOA); 164 165 *lvl = sigstatus ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW; 166 167 return 0; 168 } 169 170 static int mchp_tc_count_action_read(struct counter_device *counter, 171 struct counter_count *count, 172 struct counter_synapse *synapse, 173 enum counter_synapse_action *action) 174 { 175 struct mchp_tc_data *const priv = counter_priv(counter); 176 u32 cmr; 177 178 if (priv->qdec_mode) { 179 *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 180 return 0; 181 } 182 183 /* Only TIOA signal is evaluated in non-QDEC mode */ 184 if (synapse->signal->id != 0) { 185 *action = COUNTER_SYNAPSE_ACTION_NONE; 186 return 0; 187 } 188 189 regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr); 190 191 switch (cmr & ATMEL_TC_ETRGEDG) { 192 default: 193 *action = COUNTER_SYNAPSE_ACTION_NONE; 194 break; 195 case ATMEL_TC_ETRGEDG_RISING: 196 *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 197 break; 198 case ATMEL_TC_ETRGEDG_FALLING: 199 *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE; 200 break; 201 case ATMEL_TC_ETRGEDG_BOTH: 202 *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 203 break; 204 } 205 206 return 0; 207 } 208 209 static int mchp_tc_count_action_write(struct counter_device *counter, 210 struct counter_count *count, 211 struct counter_synapse *synapse, 212 enum counter_synapse_action action) 213 { 214 struct mchp_tc_data *const priv = counter_priv(counter); 215 u32 edge = ATMEL_TC_ETRGEDG_NONE; 216 217 /* QDEC mode is rising edge only; only TIOA handled in non-QDEC mode */ 218 if (priv->qdec_mode || synapse->signal->id != 0) 219 return -EINVAL; 220 221 switch (action) { 222 case COUNTER_SYNAPSE_ACTION_NONE: 223 edge = ATMEL_TC_ETRGEDG_NONE; 224 break; 225 case COUNTER_SYNAPSE_ACTION_RISING_EDGE: 226 edge = ATMEL_TC_ETRGEDG_RISING; 227 break; 228 case COUNTER_SYNAPSE_ACTION_FALLING_EDGE: 229 edge = ATMEL_TC_ETRGEDG_FALLING; 230 break; 231 case COUNTER_SYNAPSE_ACTION_BOTH_EDGES: 232 edge = ATMEL_TC_ETRGEDG_BOTH; 233 break; 234 default: 235 /* should never reach this path */ 236 return -EINVAL; 237 } 238 239 return regmap_write_bits(priv->regmap, 240 ATMEL_TC_REG(priv->channel[0], CMR), 241 ATMEL_TC_ETRGEDG, edge); 242 } 243 244 static int mchp_tc_count_read(struct counter_device *counter, 245 struct counter_count *count, u64 *val) 246 { 247 struct mchp_tc_data *const priv = counter_priv(counter); 248 u32 cnt; 249 250 regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CV), &cnt); 251 *val = cnt; 252 253 return 0; 254 } 255 256 static int mchp_tc_count_cap_read(struct counter_device *counter, 257 struct counter_count *count, size_t idx, u64 *val) 258 { 259 struct mchp_tc_data *const priv = counter_priv(counter); 260 u32 cnt; 261 int ret; 262 263 switch (idx) { 264 case COUNTER_MCHP_EXCAP_RA: 265 ret = regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], RA), &cnt); 266 break; 267 case COUNTER_MCHP_EXCAP_RB: 268 ret = regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], RB), &cnt); 269 break; 270 default: 271 return -EINVAL; 272 } 273 274 if (ret < 0) 275 return ret; 276 277 *val = cnt; 278 279 return 0; 280 } 281 282 static int mchp_tc_count_cap_write(struct counter_device *counter, 283 struct counter_count *count, size_t idx, u64 val) 284 { 285 struct mchp_tc_data *const priv = counter_priv(counter); 286 int ret; 287 288 if (val > U32_MAX) 289 return -ERANGE; 290 291 switch (idx) { 292 case COUNTER_MCHP_EXCAP_RA: 293 ret = regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], RA), val); 294 break; 295 case COUNTER_MCHP_EXCAP_RB: 296 ret = regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], RB), val); 297 break; 298 default: 299 return -EINVAL; 300 } 301 302 return ret; 303 } 304 305 static int mchp_tc_count_compare_read(struct counter_device *counter, struct counter_count *count, 306 u64 *val) 307 { 308 struct mchp_tc_data *const priv = counter_priv(counter); 309 u32 cnt; 310 int ret; 311 312 ret = regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], RC), &cnt); 313 if (ret < 0) 314 return ret; 315 316 *val = cnt; 317 318 return 0; 319 } 320 321 static int mchp_tc_count_compare_write(struct counter_device *counter, struct counter_count *count, 322 u64 val) 323 { 324 struct mchp_tc_data *const priv = counter_priv(counter); 325 326 if (val > U32_MAX) 327 return -ERANGE; 328 329 return regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], RC), val); 330 } 331 332 static DEFINE_COUNTER_ARRAY_CAPTURE(mchp_tc_cnt_cap_array, 2); 333 334 static struct counter_comp mchp_tc_count_ext[] = { 335 COUNTER_COMP_ARRAY_CAPTURE(mchp_tc_count_cap_read, mchp_tc_count_cap_write, 336 mchp_tc_cnt_cap_array), 337 COUNTER_COMP_COMPARE(mchp_tc_count_compare_read, mchp_tc_count_compare_write), 338 }; 339 340 static int mchp_tc_watch_validate(struct counter_device *counter, 341 const struct counter_watch *watch) 342 { 343 if (watch->channel == COUNTER_MCHP_EVCHN_CV || watch->channel == COUNTER_MCHP_EVCHN_RA) 344 switch (watch->event) { 345 case COUNTER_EVENT_CHANGE_OF_STATE: 346 case COUNTER_EVENT_OVERFLOW: 347 case COUNTER_EVENT_CAPTURE: 348 return 0; 349 default: 350 return -EINVAL; 351 } 352 353 if (watch->channel == COUNTER_MCHP_EVCHN_RB && watch->event == COUNTER_EVENT_CAPTURE) 354 return 0; 355 356 if (watch->channel == COUNTER_MCHP_EVCHN_RC && watch->event == COUNTER_EVENT_THRESHOLD) 357 return 0; 358 359 return -EINVAL; 360 } 361 362 static struct counter_count mchp_tc_counts[] = { 363 { 364 .id = 0, 365 .name = "Timer Counter", 366 .functions_list = mchp_tc_count_functions, 367 .num_functions = ARRAY_SIZE(mchp_tc_count_functions), 368 .synapses = mchp_tc_count_synapses, 369 .num_synapses = ARRAY_SIZE(mchp_tc_count_synapses), 370 .ext = mchp_tc_count_ext, 371 .num_ext = ARRAY_SIZE(mchp_tc_count_ext), 372 }, 373 }; 374 375 static const struct counter_ops mchp_tc_ops = { 376 .signal_read = mchp_tc_count_signal_read, 377 .count_read = mchp_tc_count_read, 378 .function_read = mchp_tc_count_function_read, 379 .function_write = mchp_tc_count_function_write, 380 .action_read = mchp_tc_count_action_read, 381 .action_write = mchp_tc_count_action_write, 382 .watch_validate = mchp_tc_watch_validate, 383 }; 384 385 static const struct atmel_tcb_config tcb_rm9200_config = { 386 .counter_width = 16, 387 }; 388 389 static const struct atmel_tcb_config tcb_sam9x5_config = { 390 .counter_width = 32, 391 }; 392 393 static const struct atmel_tcb_config tcb_sama5d2_config = { 394 .counter_width = 32, 395 .has_gclk = true, 396 .has_qdec = true, 397 }; 398 399 static const struct atmel_tcb_config tcb_sama5d3_config = { 400 .counter_width = 32, 401 .has_qdec = true, 402 }; 403 404 static const struct of_device_id atmel_tc_of_match[] = { 405 { .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, }, 406 { .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, }, 407 { .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config, }, 408 { .compatible = "atmel,sama5d3-tcb", .data = &tcb_sama5d3_config, }, 409 { /* sentinel */ } 410 }; 411 412 static irqreturn_t mchp_tc_isr(int irq, void *dev_id) 413 { 414 struct counter_device *const counter = dev_id; 415 struct mchp_tc_data *const priv = counter_priv(counter); 416 u32 sr, mask; 417 418 regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], SR), &sr); 419 regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], IMR), &mask); 420 421 sr &= mask; 422 if (!(sr & ATMEL_TC_ALL_IRQ)) 423 return IRQ_NONE; 424 425 if (sr & ATMEL_TC_ETRGS) 426 counter_push_event(counter, COUNTER_EVENT_CHANGE_OF_STATE, 427 COUNTER_MCHP_EVCHN_CV); 428 if (sr & ATMEL_TC_LDRAS) 429 counter_push_event(counter, COUNTER_EVENT_CAPTURE, 430 COUNTER_MCHP_EVCHN_RA); 431 if (sr & ATMEL_TC_LDRBS) 432 counter_push_event(counter, COUNTER_EVENT_CAPTURE, 433 COUNTER_MCHP_EVCHN_RB); 434 if (sr & ATMEL_TC_CPCS) 435 counter_push_event(counter, COUNTER_EVENT_THRESHOLD, 436 COUNTER_MCHP_EVCHN_RC); 437 if (sr & ATMEL_TC_COVFS) 438 counter_push_event(counter, COUNTER_EVENT_OVERFLOW, 439 COUNTER_MCHP_EVCHN_CV); 440 441 return IRQ_HANDLED; 442 } 443 444 static void mchp_tc_irq_remove(void *ptr) 445 { 446 struct mchp_tc_data *priv = ptr; 447 448 regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], IDR), ATMEL_TC_DEF_IRQS); 449 } 450 451 static int mchp_tc_irq_enable(struct counter_device *const counter, int irq) 452 { 453 struct mchp_tc_data *const priv = counter_priv(counter); 454 int ret = devm_request_irq(counter->parent, irq, mchp_tc_isr, 0, 455 dev_name(counter->parent), counter); 456 457 if (ret < 0) 458 return ret; 459 460 ret = regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], IER), ATMEL_TC_DEF_IRQS); 461 if (ret < 0) 462 return ret; 463 464 ret = devm_add_action_or_reset(counter->parent, mchp_tc_irq_remove, priv); 465 if (ret < 0) 466 return ret; 467 468 return 0; 469 } 470 471 static void mchp_tc_clk_remove(void *ptr) 472 { 473 clk_disable_unprepare((struct clk *)ptr); 474 } 475 476 static int mchp_tc_probe(struct platform_device *pdev) 477 { 478 struct device_node *np = pdev->dev.of_node; 479 const struct atmel_tcb_config *tcb_config; 480 const struct of_device_id *match; 481 struct counter_device *counter; 482 struct mchp_tc_data *priv; 483 char clk_name[7]; 484 struct regmap *regmap; 485 struct clk *clk[3]; 486 int channel; 487 int ret, i; 488 489 counter = devm_counter_alloc(&pdev->dev, sizeof(*priv)); 490 if (!counter) 491 return -ENOMEM; 492 priv = counter_priv(counter); 493 494 match = of_match_node(atmel_tc_of_match, np->parent); 495 tcb_config = match->data; 496 if (!tcb_config) { 497 dev_err(&pdev->dev, "No matching parent node found\n"); 498 return -ENODEV; 499 } 500 501 regmap = syscon_node_to_regmap(np->parent); 502 if (IS_ERR(regmap)) 503 return PTR_ERR(regmap); 504 505 /* max. channels number is 2 when in QDEC mode */ 506 priv->num_channels = of_property_count_u32_elems(np, "reg"); 507 if (priv->num_channels < 0) { 508 dev_err(&pdev->dev, "Invalid or missing channel\n"); 509 return -EINVAL; 510 } 511 512 /* Register channels and initialize clocks */ 513 for (i = 0; i < priv->num_channels; i++) { 514 ret = of_property_read_u32_index(np, "reg", i, &channel); 515 if (ret < 0 || channel > 2) 516 return -ENODEV; 517 518 priv->channel[i] = channel; 519 520 snprintf(clk_name, sizeof(clk_name), "t%d_clk", channel); 521 522 clk[i] = of_clk_get_by_name(np->parent, clk_name); 523 if (IS_ERR(clk[i])) { 524 /* Fallback to t0_clk */ 525 clk[i] = of_clk_get_by_name(np->parent, "t0_clk"); 526 if (IS_ERR(clk[i])) 527 return PTR_ERR(clk[i]); 528 } 529 530 ret = clk_prepare_enable(clk[i]); 531 if (ret) 532 return ret; 533 534 ret = devm_add_action_or_reset(&pdev->dev, 535 mchp_tc_clk_remove, 536 clk[i]); 537 if (ret) 538 return ret; 539 540 dev_dbg(&pdev->dev, 541 "Initialized capture mode on channel %d\n", 542 channel); 543 } 544 545 /* Disable Quadrature Decoder and position measure */ 546 ret = regmap_update_bits(regmap, ATMEL_TC_BMR, ATMEL_TC_QDEN | ATMEL_TC_POSEN, 0); 547 if (ret) 548 return ret; 549 550 /* Setup the period capture mode */ 551 ret = regmap_update_bits(regmap, ATMEL_TC_REG(priv->channel[0], CMR), 552 ATMEL_TC_WAVE | ATMEL_TC_ABETRG | ATMEL_TC_CMR_MASK | 553 ATMEL_TC_TCCLKS, 554 ATMEL_TC_CMR_MASK); 555 if (ret) 556 return ret; 557 558 /* Enable clock and trigger counter */ 559 ret = regmap_write(regmap, ATMEL_TC_REG(priv->channel[0], CCR), 560 ATMEL_TC_CLKEN | ATMEL_TC_SWTRG); 561 if (ret) 562 return ret; 563 564 priv->tc_cfg = tcb_config; 565 priv->regmap = regmap; 566 counter->name = dev_name(&pdev->dev); 567 counter->parent = &pdev->dev; 568 counter->ops = &mchp_tc_ops; 569 counter->num_counts = ARRAY_SIZE(mchp_tc_counts); 570 counter->counts = mchp_tc_counts; 571 counter->num_signals = ARRAY_SIZE(mchp_tc_count_signals); 572 counter->signals = mchp_tc_count_signals; 573 574 i = of_irq_get(np->parent, 0); 575 if (i == -EPROBE_DEFER) 576 return -EPROBE_DEFER; 577 if (i > 0) { 578 ret = mchp_tc_irq_enable(counter, i); 579 if (ret < 0) 580 return dev_err_probe(&pdev->dev, ret, "Failed to set up IRQ"); 581 } 582 583 ret = devm_counter_add(&pdev->dev, counter); 584 if (ret < 0) 585 return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n"); 586 587 return 0; 588 } 589 590 static const struct of_device_id mchp_tc_dt_ids[] = { 591 { .compatible = "microchip,tcb-capture", }, 592 { /* sentinel */ }, 593 }; 594 MODULE_DEVICE_TABLE(of, mchp_tc_dt_ids); 595 596 static struct platform_driver mchp_tc_driver = { 597 .probe = mchp_tc_probe, 598 .driver = { 599 .name = "microchip-tcb-capture", 600 .of_match_table = mchp_tc_dt_ids, 601 }, 602 }; 603 module_platform_driver(mchp_tc_driver); 604 605 MODULE_AUTHOR("Kamel Bouhara <kamel.bouhara@bootlin.com>"); 606 MODULE_DESCRIPTION("Microchip TCB Capture driver"); 607 MODULE_LICENSE("GPL v2"); 608 MODULE_IMPORT_NS("COUNTER"); 609