root/drivers/net/dsa/realtek-smi-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. realtek_smi_clk_delay
  2. realtek_smi_start
  3. realtek_smi_stop
  4. realtek_smi_write_bits
  5. realtek_smi_read_bits
  6. realtek_smi_wait_for_ack
  7. realtek_smi_write_byte
  8. realtek_smi_write_byte_noack
  9. realtek_smi_read_byte0
  10. realtek_smi_read_byte1
  11. realtek_smi_read_reg
  12. realtek_smi_write_reg
  13. realtek_smi_write_reg_noack
  14. realtek_smi_write
  15. realtek_smi_read
  16. realtek_smi_mdio_read
  17. realtek_smi_mdio_write
  18. realtek_smi_setup_mdio
  19. realtek_smi_probe
  20. realtek_smi_remove

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /* Realtek Simple Management Interface (SMI) driver
   3  * It can be discussed how "simple" this interface is.
   4  *
   5  * The SMI protocol piggy-backs the MDIO MDC and MDIO signals levels
   6  * but the protocol is not MDIO at all. Instead it is a Realtek
   7  * pecularity that need to bit-bang the lines in a special way to
   8  * communicate with the switch.
   9  *
  10  * ASICs we intend to support with this driver:
  11  *
  12  * RTL8366   - The original version, apparently
  13  * RTL8369   - Similar enough to have the same datsheet as RTL8366
  14  * RTL8366RB - Probably reads out "RTL8366 revision B", has a quite
  15  *             different register layout from the other two
  16  * RTL8366S  - Is this "RTL8366 super"?
  17  * RTL8367   - Has an OpenWRT driver as well
  18  * RTL8368S  - Seems to be an alternative name for RTL8366RB
  19  * RTL8370   - Also uses SMI
  20  *
  21  * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
  22  * Copyright (C) 2010 Antti Seppälä <a.seppala@gmail.com>
  23  * Copyright (C) 2010 Roman Yeryomin <roman@advem.lv>
  24  * Copyright (C) 2011 Colin Leitner <colin.leitner@googlemail.com>
  25  * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  26  */
  27 
  28 #include <linux/kernel.h>
  29 #include <linux/module.h>
  30 #include <linux/device.h>
  31 #include <linux/spinlock.h>
  32 #include <linux/skbuff.h>
  33 #include <linux/of.h>
  34 #include <linux/of_device.h>
  35 #include <linux/of_mdio.h>
  36 #include <linux/delay.h>
  37 #include <linux/gpio/consumer.h>
  38 #include <linux/platform_device.h>
  39 #include <linux/regmap.h>
  40 #include <linux/bitops.h>
  41 #include <linux/if_bridge.h>
  42 
  43 #include "realtek-smi-core.h"
  44 
  45 #define REALTEK_SMI_ACK_RETRY_COUNT             5
  46 #define REALTEK_SMI_HW_STOP_DELAY               25      /* msecs */
  47 #define REALTEK_SMI_HW_START_DELAY              100     /* msecs */
  48 
  49 static inline void realtek_smi_clk_delay(struct realtek_smi *smi)
  50 {
  51         ndelay(smi->clk_delay);
  52 }
  53 
  54 static void realtek_smi_start(struct realtek_smi *smi)
  55 {
  56         /* Set GPIO pins to output mode, with initial state:
  57          * SCK = 0, SDA = 1
  58          */
  59         gpiod_direction_output(smi->mdc, 0);
  60         gpiod_direction_output(smi->mdio, 1);
  61         realtek_smi_clk_delay(smi);
  62 
  63         /* CLK 1: 0 -> 1, 1 -> 0 */
  64         gpiod_set_value(smi->mdc, 1);
  65         realtek_smi_clk_delay(smi);
  66         gpiod_set_value(smi->mdc, 0);
  67         realtek_smi_clk_delay(smi);
  68 
  69         /* CLK 2: */
  70         gpiod_set_value(smi->mdc, 1);
  71         realtek_smi_clk_delay(smi);
  72         gpiod_set_value(smi->mdio, 0);
  73         realtek_smi_clk_delay(smi);
  74         gpiod_set_value(smi->mdc, 0);
  75         realtek_smi_clk_delay(smi);
  76         gpiod_set_value(smi->mdio, 1);
  77 }
  78 
  79 static void realtek_smi_stop(struct realtek_smi *smi)
  80 {
  81         realtek_smi_clk_delay(smi);
  82         gpiod_set_value(smi->mdio, 0);
  83         gpiod_set_value(smi->mdc, 1);
  84         realtek_smi_clk_delay(smi);
  85         gpiod_set_value(smi->mdio, 1);
  86         realtek_smi_clk_delay(smi);
  87         gpiod_set_value(smi->mdc, 1);
  88         realtek_smi_clk_delay(smi);
  89         gpiod_set_value(smi->mdc, 0);
  90         realtek_smi_clk_delay(smi);
  91         gpiod_set_value(smi->mdc, 1);
  92 
  93         /* Add a click */
  94         realtek_smi_clk_delay(smi);
  95         gpiod_set_value(smi->mdc, 0);
  96         realtek_smi_clk_delay(smi);
  97         gpiod_set_value(smi->mdc, 1);
  98 
  99         /* Set GPIO pins to input mode */
 100         gpiod_direction_input(smi->mdio);
 101         gpiod_direction_input(smi->mdc);
 102 }
 103 
 104 static void realtek_smi_write_bits(struct realtek_smi *smi, u32 data, u32 len)
 105 {
 106         for (; len > 0; len--) {
 107                 realtek_smi_clk_delay(smi);
 108 
 109                 /* Prepare data */
 110                 gpiod_set_value(smi->mdio, !!(data & (1 << (len - 1))));
 111                 realtek_smi_clk_delay(smi);
 112 
 113                 /* Clocking */
 114                 gpiod_set_value(smi->mdc, 1);
 115                 realtek_smi_clk_delay(smi);
 116                 gpiod_set_value(smi->mdc, 0);
 117         }
 118 }
 119 
 120 static void realtek_smi_read_bits(struct realtek_smi *smi, u32 len, u32 *data)
 121 {
 122         gpiod_direction_input(smi->mdio);
 123 
 124         for (*data = 0; len > 0; len--) {
 125                 u32 u;
 126 
 127                 realtek_smi_clk_delay(smi);
 128 
 129                 /* Clocking */
 130                 gpiod_set_value(smi->mdc, 1);
 131                 realtek_smi_clk_delay(smi);
 132                 u = !!gpiod_get_value(smi->mdio);
 133                 gpiod_set_value(smi->mdc, 0);
 134 
 135                 *data |= (u << (len - 1));
 136         }
 137 
 138         gpiod_direction_output(smi->mdio, 0);
 139 }
 140 
 141 static int realtek_smi_wait_for_ack(struct realtek_smi *smi)
 142 {
 143         int retry_cnt;
 144 
 145         retry_cnt = 0;
 146         do {
 147                 u32 ack;
 148 
 149                 realtek_smi_read_bits(smi, 1, &ack);
 150                 if (ack == 0)
 151                         break;
 152 
 153                 if (++retry_cnt > REALTEK_SMI_ACK_RETRY_COUNT) {
 154                         dev_err(smi->dev, "ACK timeout\n");
 155                         return -ETIMEDOUT;
 156                 }
 157         } while (1);
 158 
 159         return 0;
 160 }
 161 
 162 static int realtek_smi_write_byte(struct realtek_smi *smi, u8 data)
 163 {
 164         realtek_smi_write_bits(smi, data, 8);
 165         return realtek_smi_wait_for_ack(smi);
 166 }
 167 
 168 static int realtek_smi_write_byte_noack(struct realtek_smi *smi, u8 data)
 169 {
 170         realtek_smi_write_bits(smi, data, 8);
 171         return 0;
 172 }
 173 
 174 static int realtek_smi_read_byte0(struct realtek_smi *smi, u8 *data)
 175 {
 176         u32 t;
 177 
 178         /* Read data */
 179         realtek_smi_read_bits(smi, 8, &t);
 180         *data = (t & 0xff);
 181 
 182         /* Send an ACK */
 183         realtek_smi_write_bits(smi, 0x00, 1);
 184 
 185         return 0;
 186 }
 187 
 188 static int realtek_smi_read_byte1(struct realtek_smi *smi, u8 *data)
 189 {
 190         u32 t;
 191 
 192         /* Read data */
 193         realtek_smi_read_bits(smi, 8, &t);
 194         *data = (t & 0xff);
 195 
 196         /* Send an ACK */
 197         realtek_smi_write_bits(smi, 0x01, 1);
 198 
 199         return 0;
 200 }
 201 
 202 static int realtek_smi_read_reg(struct realtek_smi *smi, u32 addr, u32 *data)
 203 {
 204         unsigned long flags;
 205         u8 lo = 0;
 206         u8 hi = 0;
 207         int ret;
 208 
 209         spin_lock_irqsave(&smi->lock, flags);
 210 
 211         realtek_smi_start(smi);
 212 
 213         /* Send READ command */
 214         ret = realtek_smi_write_byte(smi, smi->cmd_read);
 215         if (ret)
 216                 goto out;
 217 
 218         /* Set ADDR[7:0] */
 219         ret = realtek_smi_write_byte(smi, addr & 0xff);
 220         if (ret)
 221                 goto out;
 222 
 223         /* Set ADDR[15:8] */
 224         ret = realtek_smi_write_byte(smi, addr >> 8);
 225         if (ret)
 226                 goto out;
 227 
 228         /* Read DATA[7:0] */
 229         realtek_smi_read_byte0(smi, &lo);
 230         /* Read DATA[15:8] */
 231         realtek_smi_read_byte1(smi, &hi);
 232 
 233         *data = ((u32)lo) | (((u32)hi) << 8);
 234 
 235         ret = 0;
 236 
 237  out:
 238         realtek_smi_stop(smi);
 239         spin_unlock_irqrestore(&smi->lock, flags);
 240 
 241         return ret;
 242 }
 243 
 244 static int realtek_smi_write_reg(struct realtek_smi *smi,
 245                                  u32 addr, u32 data, bool ack)
 246 {
 247         unsigned long flags;
 248         int ret;
 249 
 250         spin_lock_irqsave(&smi->lock, flags);
 251 
 252         realtek_smi_start(smi);
 253 
 254         /* Send WRITE command */
 255         ret = realtek_smi_write_byte(smi, smi->cmd_write);
 256         if (ret)
 257                 goto out;
 258 
 259         /* Set ADDR[7:0] */
 260         ret = realtek_smi_write_byte(smi, addr & 0xff);
 261         if (ret)
 262                 goto out;
 263 
 264         /* Set ADDR[15:8] */
 265         ret = realtek_smi_write_byte(smi, addr >> 8);
 266         if (ret)
 267                 goto out;
 268 
 269         /* Write DATA[7:0] */
 270         ret = realtek_smi_write_byte(smi, data & 0xff);
 271         if (ret)
 272                 goto out;
 273 
 274         /* Write DATA[15:8] */
 275         if (ack)
 276                 ret = realtek_smi_write_byte(smi, data >> 8);
 277         else
 278                 ret = realtek_smi_write_byte_noack(smi, data >> 8);
 279         if (ret)
 280                 goto out;
 281 
 282         ret = 0;
 283 
 284  out:
 285         realtek_smi_stop(smi);
 286         spin_unlock_irqrestore(&smi->lock, flags);
 287 
 288         return ret;
 289 }
 290 
 291 /* There is one single case when we need to use this accessor and that
 292  * is when issueing soft reset. Since the device reset as soon as we write
 293  * that bit, no ACK will come back for natural reasons.
 294  */
 295 int realtek_smi_write_reg_noack(struct realtek_smi *smi, u32 addr,
 296                                 u32 data)
 297 {
 298         return realtek_smi_write_reg(smi, addr, data, false);
 299 }
 300 EXPORT_SYMBOL_GPL(realtek_smi_write_reg_noack);
 301 
 302 /* Regmap accessors */
 303 
 304 static int realtek_smi_write(void *ctx, u32 reg, u32 val)
 305 {
 306         struct realtek_smi *smi = ctx;
 307 
 308         return realtek_smi_write_reg(smi, reg, val, true);
 309 }
 310 
 311 static int realtek_smi_read(void *ctx, u32 reg, u32 *val)
 312 {
 313         struct realtek_smi *smi = ctx;
 314 
 315         return realtek_smi_read_reg(smi, reg, val);
 316 }
 317 
 318 static const struct regmap_config realtek_smi_mdio_regmap_config = {
 319         .reg_bits = 10, /* A4..A0 R4..R0 */
 320         .val_bits = 16,
 321         .reg_stride = 1,
 322         /* PHY regs are at 0x8000 */
 323         .max_register = 0xffff,
 324         .reg_format_endian = REGMAP_ENDIAN_BIG,
 325         .reg_read = realtek_smi_read,
 326         .reg_write = realtek_smi_write,
 327         .cache_type = REGCACHE_NONE,
 328 };
 329 
 330 static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
 331 {
 332         struct realtek_smi *smi = bus->priv;
 333 
 334         return smi->ops->phy_read(smi, addr, regnum);
 335 }
 336 
 337 static int realtek_smi_mdio_write(struct mii_bus *bus, int addr, int regnum,
 338                                   u16 val)
 339 {
 340         struct realtek_smi *smi = bus->priv;
 341 
 342         return smi->ops->phy_write(smi, addr, regnum, val);
 343 }
 344 
 345 int realtek_smi_setup_mdio(struct realtek_smi *smi)
 346 {
 347         struct device_node *mdio_np;
 348         int ret;
 349 
 350         mdio_np = of_get_compatible_child(smi->dev->of_node, "realtek,smi-mdio");
 351         if (!mdio_np) {
 352                 dev_err(smi->dev, "no MDIO bus node\n");
 353                 return -ENODEV;
 354         }
 355 
 356         smi->slave_mii_bus = devm_mdiobus_alloc(smi->dev);
 357         if (!smi->slave_mii_bus) {
 358                 ret = -ENOMEM;
 359                 goto err_put_node;
 360         }
 361         smi->slave_mii_bus->priv = smi;
 362         smi->slave_mii_bus->name = "SMI slave MII";
 363         smi->slave_mii_bus->read = realtek_smi_mdio_read;
 364         smi->slave_mii_bus->write = realtek_smi_mdio_write;
 365         snprintf(smi->slave_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d",
 366                  smi->ds->index);
 367         smi->slave_mii_bus->dev.of_node = mdio_np;
 368         smi->slave_mii_bus->parent = smi->dev;
 369         smi->ds->slave_mii_bus = smi->slave_mii_bus;
 370 
 371         ret = of_mdiobus_register(smi->slave_mii_bus, mdio_np);
 372         if (ret) {
 373                 dev_err(smi->dev, "unable to register MDIO bus %s\n",
 374                         smi->slave_mii_bus->id);
 375                 goto err_put_node;
 376         }
 377 
 378         return 0;
 379 
 380 err_put_node:
 381         of_node_put(mdio_np);
 382 
 383         return ret;
 384 }
 385 
 386 static int realtek_smi_probe(struct platform_device *pdev)
 387 {
 388         const struct realtek_smi_variant *var;
 389         struct device *dev = &pdev->dev;
 390         struct realtek_smi *smi;
 391         struct device_node *np;
 392         int ret;
 393 
 394         var = of_device_get_match_data(dev);
 395         np = dev->of_node;
 396 
 397         smi = devm_kzalloc(dev, sizeof(*smi), GFP_KERNEL);
 398         if (!smi)
 399                 return -ENOMEM;
 400         smi->map = devm_regmap_init(dev, NULL, smi,
 401                                     &realtek_smi_mdio_regmap_config);
 402         if (IS_ERR(smi->map)) {
 403                 ret = PTR_ERR(smi->map);
 404                 dev_err(dev, "regmap init failed: %d\n", ret);
 405                 return ret;
 406         }
 407 
 408         /* Link forward and backward */
 409         smi->dev = dev;
 410         smi->clk_delay = var->clk_delay;
 411         smi->cmd_read = var->cmd_read;
 412         smi->cmd_write = var->cmd_write;
 413         smi->ops = var->ops;
 414 
 415         dev_set_drvdata(dev, smi);
 416         spin_lock_init(&smi->lock);
 417 
 418         /* TODO: if power is software controlled, set up any regulators here */
 419 
 420         /* Assert then deassert RESET */
 421         smi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 422         if (IS_ERR(smi->reset)) {
 423                 dev_err(dev, "failed to get RESET GPIO\n");
 424                 return PTR_ERR(smi->reset);
 425         }
 426         msleep(REALTEK_SMI_HW_STOP_DELAY);
 427         gpiod_set_value(smi->reset, 0);
 428         msleep(REALTEK_SMI_HW_START_DELAY);
 429         dev_info(dev, "deasserted RESET\n");
 430 
 431         /* Fetch MDIO pins */
 432         smi->mdc = devm_gpiod_get_optional(dev, "mdc", GPIOD_OUT_LOW);
 433         if (IS_ERR(smi->mdc))
 434                 return PTR_ERR(smi->mdc);
 435         smi->mdio = devm_gpiod_get_optional(dev, "mdio", GPIOD_OUT_LOW);
 436         if (IS_ERR(smi->mdio))
 437                 return PTR_ERR(smi->mdio);
 438 
 439         smi->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
 440 
 441         ret = smi->ops->detect(smi);
 442         if (ret) {
 443                 dev_err(dev, "unable to detect switch\n");
 444                 return ret;
 445         }
 446 
 447         smi->ds = dsa_switch_alloc(dev, smi->num_ports);
 448         if (!smi->ds)
 449                 return -ENOMEM;
 450         smi->ds->priv = smi;
 451 
 452         smi->ds->ops = var->ds_ops;
 453         ret = dsa_register_switch(smi->ds);
 454         if (ret) {
 455                 dev_err(dev, "unable to register switch ret = %d\n", ret);
 456                 return ret;
 457         }
 458         return 0;
 459 }
 460 
 461 static int realtek_smi_remove(struct platform_device *pdev)
 462 {
 463         struct realtek_smi *smi = dev_get_drvdata(&pdev->dev);
 464 
 465         dsa_unregister_switch(smi->ds);
 466         if (smi->slave_mii_bus)
 467                 of_node_put(smi->slave_mii_bus->dev.of_node);
 468         gpiod_set_value(smi->reset, 1);
 469 
 470         return 0;
 471 }
 472 
 473 static const struct of_device_id realtek_smi_of_match[] = {
 474         {
 475                 .compatible = "realtek,rtl8366rb",
 476                 .data = &rtl8366rb_variant,
 477         },
 478         {
 479                 /* FIXME: add support for RTL8366S and more */
 480                 .compatible = "realtek,rtl8366s",
 481                 .data = NULL,
 482         },
 483         { /* sentinel */ },
 484 };
 485 MODULE_DEVICE_TABLE(of, realtek_smi_of_match);
 486 
 487 static struct platform_driver realtek_smi_driver = {
 488         .driver = {
 489                 .name = "realtek-smi",
 490                 .of_match_table = of_match_ptr(realtek_smi_of_match),
 491         },
 492         .probe  = realtek_smi_probe,
 493         .remove = realtek_smi_remove,
 494 };
 495 module_platform_driver(realtek_smi_driver);
 496 
 497 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */