601 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (c) 2018 Google LLC4 * Copyright (c) 2021 Aspeed Technology Inc.5 */6#include <linux/device.h>7#include <linux/module.h>8#include <linux/of.h>9#include <linux/mfd/syscon.h>10#include <linux/regmap.h>11#include <linux/platform_device.h>12 13/* register offsets */14#define HICR9 0x9815#define HICRA 0x9c16 17/* attributes options */18#define UART_ROUTING_IO1 "io1"19#define UART_ROUTING_IO2 "io2"20#define UART_ROUTING_IO3 "io3"21#define UART_ROUTING_IO4 "io4"22#define UART_ROUTING_IO5 "io5"23#define UART_ROUTING_IO6 "io6"24#define UART_ROUTING_IO10 "io10"25#define UART_ROUTING_UART1 "uart1"26#define UART_ROUTING_UART2 "uart2"27#define UART_ROUTING_UART3 "uart3"28#define UART_ROUTING_UART4 "uart4"29#define UART_ROUTING_UART5 "uart5"30#define UART_ROUTING_UART6 "uart6"31#define UART_ROUTING_UART10 "uart10"32#define UART_ROUTING_RES "reserved"33 34struct aspeed_uart_routing {35 struct regmap *map;36 struct attribute_group const *attr_grp;37};38 39struct aspeed_uart_routing_selector {40 struct device_attribute dev_attr;41 uint8_t reg;42 uint8_t mask;43 uint8_t shift;44 const char *const options[];45};46 47#define to_routing_selector(_dev_attr) \48 container_of(_dev_attr, struct aspeed_uart_routing_selector, dev_attr)49 50static ssize_t aspeed_uart_routing_show(struct device *dev,51 struct device_attribute *attr,52 char *buf);53 54static ssize_t aspeed_uart_routing_store(struct device *dev,55 struct device_attribute *attr,56 const char *buf, size_t count);57 58#define ROUTING_ATTR(_name) { \59 .attr = {.name = _name, \60 .mode = VERIFY_OCTAL_PERMISSIONS(0644) }, \61 .show = aspeed_uart_routing_show, \62 .store = aspeed_uart_routing_store, \63}64 65/* routing selector for AST25xx */66static struct aspeed_uart_routing_selector ast2500_io6_sel = {67 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO6),68 .reg = HICR9,69 .shift = 8,70 .mask = 0xf,71 .options = {72 UART_ROUTING_UART1,73 UART_ROUTING_UART2,74 UART_ROUTING_UART3,75 UART_ROUTING_UART4,76 UART_ROUTING_UART5,77 UART_ROUTING_IO1,78 UART_ROUTING_IO2,79 UART_ROUTING_IO3,80 UART_ROUTING_IO4,81 UART_ROUTING_IO5,82 NULL,83 },84};85 86static struct aspeed_uart_routing_selector ast2500_uart5_sel = {87 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART5),88 .reg = HICRA,89 .shift = 28,90 .mask = 0xf,91 .options = {92 UART_ROUTING_IO5,93 UART_ROUTING_IO1,94 UART_ROUTING_IO2,95 UART_ROUTING_IO3,96 UART_ROUTING_IO4,97 UART_ROUTING_UART1,98 UART_ROUTING_UART2,99 UART_ROUTING_UART3,100 UART_ROUTING_UART4,101 UART_ROUTING_IO6,102 NULL,103 },104};105 106static struct aspeed_uart_routing_selector ast2500_uart4_sel = {107 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),108 .reg = HICRA,109 .shift = 25,110 .mask = 0x7,111 .options = {112 UART_ROUTING_IO4,113 UART_ROUTING_IO1,114 UART_ROUTING_IO2,115 UART_ROUTING_IO3,116 UART_ROUTING_UART1,117 UART_ROUTING_UART2,118 UART_ROUTING_UART3,119 UART_ROUTING_IO6,120 NULL,121 },122};123 124static struct aspeed_uart_routing_selector ast2500_uart3_sel = {125 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),126 .reg = HICRA,127 .shift = 22,128 .mask = 0x7,129 .options = {130 UART_ROUTING_IO3,131 UART_ROUTING_IO4,132 UART_ROUTING_IO1,133 UART_ROUTING_IO2,134 UART_ROUTING_UART4,135 UART_ROUTING_UART1,136 UART_ROUTING_UART2,137 UART_ROUTING_IO6,138 NULL,139 },140};141 142static struct aspeed_uart_routing_selector ast2500_uart2_sel = {143 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),144 .reg = HICRA,145 .shift = 19,146 .mask = 0x7,147 .options = {148 UART_ROUTING_IO2,149 UART_ROUTING_IO3,150 UART_ROUTING_IO4,151 UART_ROUTING_IO1,152 UART_ROUTING_UART3,153 UART_ROUTING_UART4,154 UART_ROUTING_UART1,155 UART_ROUTING_IO6,156 NULL,157 },158};159 160static struct aspeed_uart_routing_selector ast2500_uart1_sel = {161 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),162 .reg = HICRA,163 .shift = 16,164 .mask = 0x7,165 .options = {166 UART_ROUTING_IO1,167 UART_ROUTING_IO2,168 UART_ROUTING_IO3,169 UART_ROUTING_IO4,170 UART_ROUTING_UART2,171 UART_ROUTING_UART3,172 UART_ROUTING_UART4,173 UART_ROUTING_IO6,174 NULL,175 },176};177 178static struct aspeed_uart_routing_selector ast2500_io5_sel = {179 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO5),180 .reg = HICRA,181 .shift = 12,182 .mask = 0x7,183 .options = {184 UART_ROUTING_UART5,185 UART_ROUTING_UART1,186 UART_ROUTING_UART2,187 UART_ROUTING_UART3,188 UART_ROUTING_UART4,189 UART_ROUTING_IO1,190 UART_ROUTING_IO3,191 UART_ROUTING_IO6,192 NULL,193 },194};195 196static struct aspeed_uart_routing_selector ast2500_io4_sel = {197 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),198 .reg = HICRA,199 .shift = 9,200 .mask = 0x7,201 .options = {202 UART_ROUTING_UART4,203 UART_ROUTING_UART5,204 UART_ROUTING_UART1,205 UART_ROUTING_UART2,206 UART_ROUTING_UART3,207 UART_ROUTING_IO1,208 UART_ROUTING_IO2,209 UART_ROUTING_IO6,210 NULL,211 },212};213 214static struct aspeed_uart_routing_selector ast2500_io3_sel = {215 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),216 .reg = HICRA,217 .shift = 6,218 .mask = 0x7,219 .options = {220 UART_ROUTING_UART3,221 UART_ROUTING_UART4,222 UART_ROUTING_UART5,223 UART_ROUTING_UART1,224 UART_ROUTING_UART2,225 UART_ROUTING_IO1,226 UART_ROUTING_IO2,227 UART_ROUTING_IO6,228 NULL,229 },230};231 232static struct aspeed_uart_routing_selector ast2500_io2_sel = {233 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),234 .reg = HICRA,235 .shift = 3,236 .mask = 0x7,237 .options = {238 UART_ROUTING_UART2,239 UART_ROUTING_UART3,240 UART_ROUTING_UART4,241 UART_ROUTING_UART5,242 UART_ROUTING_UART1,243 UART_ROUTING_IO3,244 UART_ROUTING_IO4,245 UART_ROUTING_IO6,246 NULL,247 },248};249 250static struct aspeed_uart_routing_selector ast2500_io1_sel = {251 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),252 .reg = HICRA,253 .shift = 0,254 .mask = 0x7,255 .options = {256 UART_ROUTING_UART1,257 UART_ROUTING_UART2,258 UART_ROUTING_UART3,259 UART_ROUTING_UART4,260 UART_ROUTING_UART5,261 UART_ROUTING_IO3,262 UART_ROUTING_IO4,263 UART_ROUTING_IO6,264 NULL,265 },266};267 268static struct attribute *ast2500_uart_routing_attrs[] = {269 &ast2500_io6_sel.dev_attr.attr,270 &ast2500_uart5_sel.dev_attr.attr,271 &ast2500_uart4_sel.dev_attr.attr,272 &ast2500_uart3_sel.dev_attr.attr,273 &ast2500_uart2_sel.dev_attr.attr,274 &ast2500_uart1_sel.dev_attr.attr,275 &ast2500_io5_sel.dev_attr.attr,276 &ast2500_io4_sel.dev_attr.attr,277 &ast2500_io3_sel.dev_attr.attr,278 &ast2500_io2_sel.dev_attr.attr,279 &ast2500_io1_sel.dev_attr.attr,280 NULL,281};282 283static const struct attribute_group ast2500_uart_routing_attr_group = {284 .attrs = ast2500_uart_routing_attrs,285};286 287/* routing selector for AST26xx */288static struct aspeed_uart_routing_selector ast2600_uart10_sel = {289 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART10),290 .reg = HICR9,291 .shift = 12,292 .mask = 0xf,293 .options = {294 UART_ROUTING_IO10,295 UART_ROUTING_IO1,296 UART_ROUTING_IO2,297 UART_ROUTING_IO3,298 UART_ROUTING_IO4,299 UART_ROUTING_RES,300 UART_ROUTING_UART1,301 UART_ROUTING_UART2,302 UART_ROUTING_UART3,303 UART_ROUTING_UART4,304 NULL,305 },306};307 308static struct aspeed_uart_routing_selector ast2600_io10_sel = {309 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO10),310 .reg = HICR9,311 .shift = 8,312 .mask = 0xf,313 .options = {314 UART_ROUTING_UART1,315 UART_ROUTING_UART2,316 UART_ROUTING_UART3,317 UART_ROUTING_UART4,318 UART_ROUTING_RES,319 UART_ROUTING_IO1,320 UART_ROUTING_IO2,321 UART_ROUTING_IO3,322 UART_ROUTING_IO4,323 UART_ROUTING_RES,324 UART_ROUTING_UART10,325 NULL,326 },327};328 329static struct aspeed_uart_routing_selector ast2600_uart4_sel = {330 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),331 .reg = HICRA,332 .shift = 25,333 .mask = 0x7,334 .options = {335 UART_ROUTING_IO4,336 UART_ROUTING_IO1,337 UART_ROUTING_IO2,338 UART_ROUTING_IO3,339 UART_ROUTING_UART1,340 UART_ROUTING_UART2,341 UART_ROUTING_UART3,342 UART_ROUTING_IO10,343 NULL,344 },345};346 347static struct aspeed_uart_routing_selector ast2600_uart3_sel = {348 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),349 .reg = HICRA,350 .shift = 22,351 .mask = 0x7,352 .options = {353 UART_ROUTING_IO3,354 UART_ROUTING_IO4,355 UART_ROUTING_IO1,356 UART_ROUTING_IO2,357 UART_ROUTING_UART4,358 UART_ROUTING_UART1,359 UART_ROUTING_UART2,360 UART_ROUTING_IO10,361 NULL,362 },363};364 365static struct aspeed_uart_routing_selector ast2600_uart2_sel = {366 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),367 .reg = HICRA,368 .shift = 19,369 .mask = 0x7,370 .options = {371 UART_ROUTING_IO2,372 UART_ROUTING_IO3,373 UART_ROUTING_IO4,374 UART_ROUTING_IO1,375 UART_ROUTING_UART3,376 UART_ROUTING_UART4,377 UART_ROUTING_UART1,378 UART_ROUTING_IO10,379 NULL,380 },381};382 383static struct aspeed_uart_routing_selector ast2600_uart1_sel = {384 .dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),385 .reg = HICRA,386 .shift = 16,387 .mask = 0x7,388 .options = {389 UART_ROUTING_IO1,390 UART_ROUTING_IO2,391 UART_ROUTING_IO3,392 UART_ROUTING_IO4,393 UART_ROUTING_UART2,394 UART_ROUTING_UART3,395 UART_ROUTING_UART4,396 UART_ROUTING_IO10,397 NULL,398 },399};400 401static struct aspeed_uart_routing_selector ast2600_io4_sel = {402 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),403 .reg = HICRA,404 .shift = 9,405 .mask = 0x7,406 .options = {407 UART_ROUTING_UART4,408 UART_ROUTING_UART10,409 UART_ROUTING_UART1,410 UART_ROUTING_UART2,411 UART_ROUTING_UART3,412 UART_ROUTING_IO1,413 UART_ROUTING_IO2,414 UART_ROUTING_IO10,415 NULL,416 },417};418 419static struct aspeed_uart_routing_selector ast2600_io3_sel = {420 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),421 .reg = HICRA,422 .shift = 6,423 .mask = 0x7,424 .options = {425 UART_ROUTING_UART3,426 UART_ROUTING_UART4,427 UART_ROUTING_UART10,428 UART_ROUTING_UART1,429 UART_ROUTING_UART2,430 UART_ROUTING_IO1,431 UART_ROUTING_IO2,432 UART_ROUTING_IO10,433 NULL,434 },435};436 437static struct aspeed_uart_routing_selector ast2600_io2_sel = {438 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),439 .reg = HICRA,440 .shift = 3,441 .mask = 0x7,442 .options = {443 UART_ROUTING_UART2,444 UART_ROUTING_UART3,445 UART_ROUTING_UART4,446 UART_ROUTING_UART10,447 UART_ROUTING_UART1,448 UART_ROUTING_IO3,449 UART_ROUTING_IO4,450 UART_ROUTING_IO10,451 NULL,452 },453};454 455static struct aspeed_uart_routing_selector ast2600_io1_sel = {456 .dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),457 .reg = HICRA,458 .shift = 0,459 .mask = 0x7,460 .options = {461 UART_ROUTING_UART1,462 UART_ROUTING_UART2,463 UART_ROUTING_UART3,464 UART_ROUTING_UART4,465 UART_ROUTING_UART10,466 UART_ROUTING_IO3,467 UART_ROUTING_IO4,468 UART_ROUTING_IO10,469 NULL,470 },471};472 473static struct attribute *ast2600_uart_routing_attrs[] = {474 &ast2600_uart10_sel.dev_attr.attr,475 &ast2600_io10_sel.dev_attr.attr,476 &ast2600_uart4_sel.dev_attr.attr,477 &ast2600_uart3_sel.dev_attr.attr,478 &ast2600_uart2_sel.dev_attr.attr,479 &ast2600_uart1_sel.dev_attr.attr,480 &ast2600_io4_sel.dev_attr.attr,481 &ast2600_io3_sel.dev_attr.attr,482 &ast2600_io2_sel.dev_attr.attr,483 &ast2600_io1_sel.dev_attr.attr,484 NULL,485};486 487static const struct attribute_group ast2600_uart_routing_attr_group = {488 .attrs = ast2600_uart_routing_attrs,489};490 491static ssize_t aspeed_uart_routing_show(struct device *dev,492 struct device_attribute *attr,493 char *buf)494{495 struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);496 struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);497 int val, pos, len;498 499 regmap_read(uart_routing->map, sel->reg, &val);500 val = (val >> sel->shift) & sel->mask;501 502 len = 0;503 for (pos = 0; sel->options[pos] != NULL; ++pos) {504 if (pos == val)505 len += sysfs_emit_at(buf, len, "[%s] ", sel->options[pos]);506 else507 len += sysfs_emit_at(buf, len, "%s ", sel->options[pos]);508 }509 510 if (val >= pos)511 len += sysfs_emit_at(buf, len, "[unknown(%d)]", val);512 513 len += sysfs_emit_at(buf, len, "\n");514 515 return len;516}517 518static ssize_t aspeed_uart_routing_store(struct device *dev,519 struct device_attribute *attr,520 const char *buf, size_t count)521{522 struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);523 struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);524 int val;525 526 val = __sysfs_match_string(sel->options, -1, buf);527 if (val < 0) {528 dev_err(dev, "invalid value \"%s\"\n", buf);529 return -EINVAL;530 }531 532 regmap_update_bits(uart_routing->map, sel->reg,533 (sel->mask << sel->shift),534 (val & sel->mask) << sel->shift);535 536 return count;537}538 539static int aspeed_uart_routing_probe(struct platform_device *pdev)540{541 int rc;542 struct device *dev = &pdev->dev;543 struct aspeed_uart_routing *uart_routing;544 545 uart_routing = devm_kzalloc(&pdev->dev, sizeof(*uart_routing), GFP_KERNEL);546 if (!uart_routing)547 return -ENOMEM;548 549 uart_routing->map = syscon_node_to_regmap(dev->parent->of_node);550 if (IS_ERR(uart_routing->map)) {551 dev_err(dev, "cannot get regmap\n");552 return PTR_ERR(uart_routing->map);553 }554 555 uart_routing->attr_grp = of_device_get_match_data(dev);556 557 rc = sysfs_create_group(&dev->kobj, uart_routing->attr_grp);558 if (rc < 0)559 return rc;560 561 dev_set_drvdata(dev, uart_routing);562 563 dev_info(dev, "module loaded\n");564 565 return 0;566}567 568static void aspeed_uart_routing_remove(struct platform_device *pdev)569{570 struct device *dev = &pdev->dev;571 struct aspeed_uart_routing *uart_routing = platform_get_drvdata(pdev);572 573 sysfs_remove_group(&dev->kobj, uart_routing->attr_grp);574}575 576static const struct of_device_id aspeed_uart_routing_table[] = {577 { .compatible = "aspeed,ast2400-uart-routing",578 .data = &ast2500_uart_routing_attr_group },579 { .compatible = "aspeed,ast2500-uart-routing",580 .data = &ast2500_uart_routing_attr_group },581 { .compatible = "aspeed,ast2600-uart-routing",582 .data = &ast2600_uart_routing_attr_group },583 { },584};585 586static struct platform_driver aspeed_uart_routing_driver = {587 .driver = {588 .name = "aspeed-uart-routing",589 .of_match_table = aspeed_uart_routing_table,590 },591 .probe = aspeed_uart_routing_probe,592 .remove_new = aspeed_uart_routing_remove,593};594 595module_platform_driver(aspeed_uart_routing_driver);596 597MODULE_AUTHOR("Oskar Senft <osk@google.com>");598MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang@aspeedtech.com>");599MODULE_LICENSE("GPL v2");600MODULE_DESCRIPTION("Driver to configure Aspeed UART routing");601