Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /* Realtek MDIO interface driver
0003  *
0004  * ASICs we intend to support with this driver:
0005  *
0006  * RTL8366   - The original version, apparently
0007  * RTL8369   - Similar enough to have the same datsheet as RTL8366
0008  * RTL8366RB - Probably reads out "RTL8366 revision B", has a quite
0009  *             different register layout from the other two
0010  * RTL8366S  - Is this "RTL8366 super"?
0011  * RTL8367   - Has an OpenWRT driver as well
0012  * RTL8368S  - Seems to be an alternative name for RTL8366RB
0013  * RTL8370   - Also uses SMI
0014  *
0015  * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
0016  * Copyright (C) 2010 Antti Seppälä <a.seppala@gmail.com>
0017  * Copyright (C) 2010 Roman Yeryomin <roman@advem.lv>
0018  * Copyright (C) 2011 Colin Leitner <colin.leitner@googlemail.com>
0019  * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
0020  */
0021 
0022 #include <linux/module.h>
0023 #include <linux/of_device.h>
0024 #include <linux/regmap.h>
0025 
0026 #include "realtek.h"
0027 
0028 /* Read/write via mdiobus */
0029 #define REALTEK_MDIO_CTRL0_REG      31
0030 #define REALTEK_MDIO_START_REG      29
0031 #define REALTEK_MDIO_CTRL1_REG      21
0032 #define REALTEK_MDIO_ADDRESS_REG    23
0033 #define REALTEK_MDIO_DATA_WRITE_REG 24
0034 #define REALTEK_MDIO_DATA_READ_REG  25
0035 
0036 #define REALTEK_MDIO_START_OP       0xFFFF
0037 #define REALTEK_MDIO_ADDR_OP        0x000E
0038 #define REALTEK_MDIO_READ_OP        0x0001
0039 #define REALTEK_MDIO_WRITE_OP       0x0003
0040 
0041 static int realtek_mdio_write(void *ctx, u32 reg, u32 val)
0042 {
0043     struct realtek_priv *priv = ctx;
0044     struct mii_bus *bus = priv->bus;
0045     int ret;
0046 
0047     mutex_lock(&bus->mdio_lock);
0048 
0049     ret = bus->write(bus, priv->mdio_addr, REALTEK_MDIO_CTRL0_REG, REALTEK_MDIO_ADDR_OP);
0050     if (ret)
0051         goto out_unlock;
0052 
0053     ret = bus->write(bus, priv->mdio_addr, REALTEK_MDIO_ADDRESS_REG, reg);
0054     if (ret)
0055         goto out_unlock;
0056 
0057     ret = bus->write(bus, priv->mdio_addr, REALTEK_MDIO_DATA_WRITE_REG, val);
0058     if (ret)
0059         goto out_unlock;
0060 
0061     ret = bus->write(bus, priv->mdio_addr, REALTEK_MDIO_CTRL1_REG, REALTEK_MDIO_WRITE_OP);
0062 
0063 out_unlock:
0064     mutex_unlock(&bus->mdio_lock);
0065 
0066     return ret;
0067 }
0068 
0069 static int realtek_mdio_read(void *ctx, u32 reg, u32 *val)
0070 {
0071     struct realtek_priv *priv = ctx;
0072     struct mii_bus *bus = priv->bus;
0073     int ret;
0074 
0075     mutex_lock(&bus->mdio_lock);
0076 
0077     ret = bus->write(bus, priv->mdio_addr, REALTEK_MDIO_CTRL0_REG, REALTEK_MDIO_ADDR_OP);
0078     if (ret)
0079         goto out_unlock;
0080 
0081     ret = bus->write(bus, priv->mdio_addr, REALTEK_MDIO_ADDRESS_REG, reg);
0082     if (ret)
0083         goto out_unlock;
0084 
0085     ret = bus->write(bus, priv->mdio_addr, REALTEK_MDIO_CTRL1_REG, REALTEK_MDIO_READ_OP);
0086     if (ret)
0087         goto out_unlock;
0088 
0089     ret = bus->read(bus, priv->mdio_addr, REALTEK_MDIO_DATA_READ_REG);
0090     if (ret >= 0) {
0091         *val = ret;
0092         ret = 0;
0093     }
0094 
0095 out_unlock:
0096     mutex_unlock(&bus->mdio_lock);
0097 
0098     return ret;
0099 }
0100 
0101 static void realtek_mdio_lock(void *ctx)
0102 {
0103     struct realtek_priv *priv = ctx;
0104 
0105     mutex_lock(&priv->map_lock);
0106 }
0107 
0108 static void realtek_mdio_unlock(void *ctx)
0109 {
0110     struct realtek_priv *priv = ctx;
0111 
0112     mutex_unlock(&priv->map_lock);
0113 }
0114 
0115 static const struct regmap_config realtek_mdio_regmap_config = {
0116     .reg_bits = 10, /* A4..A0 R4..R0 */
0117     .val_bits = 16,
0118     .reg_stride = 1,
0119     /* PHY regs are at 0x8000 */
0120     .max_register = 0xffff,
0121     .reg_format_endian = REGMAP_ENDIAN_BIG,
0122     .reg_read = realtek_mdio_read,
0123     .reg_write = realtek_mdio_write,
0124     .cache_type = REGCACHE_NONE,
0125     .lock = realtek_mdio_lock,
0126     .unlock = realtek_mdio_unlock,
0127 };
0128 
0129 static const struct regmap_config realtek_mdio_nolock_regmap_config = {
0130     .reg_bits = 10, /* A4..A0 R4..R0 */
0131     .val_bits = 16,
0132     .reg_stride = 1,
0133     /* PHY regs are at 0x8000 */
0134     .max_register = 0xffff,
0135     .reg_format_endian = REGMAP_ENDIAN_BIG,
0136     .reg_read = realtek_mdio_read,
0137     .reg_write = realtek_mdio_write,
0138     .cache_type = REGCACHE_NONE,
0139     .disable_locking = true,
0140 };
0141 
0142 static int realtek_mdio_probe(struct mdio_device *mdiodev)
0143 {
0144     struct realtek_priv *priv;
0145     struct device *dev = &mdiodev->dev;
0146     const struct realtek_variant *var;
0147     struct regmap_config rc;
0148     struct device_node *np;
0149     int ret;
0150 
0151     var = of_device_get_match_data(dev);
0152     if (!var)
0153         return -EINVAL;
0154 
0155     priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
0156     if (!priv)
0157         return -ENOMEM;
0158 
0159     mutex_init(&priv->map_lock);
0160 
0161     rc = realtek_mdio_regmap_config;
0162     rc.lock_arg = priv;
0163     priv->map = devm_regmap_init(dev, NULL, priv, &rc);
0164     if (IS_ERR(priv->map)) {
0165         ret = PTR_ERR(priv->map);
0166         dev_err(dev, "regmap init failed: %d\n", ret);
0167         return ret;
0168     }
0169 
0170     rc = realtek_mdio_nolock_regmap_config;
0171     priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
0172     if (IS_ERR(priv->map_nolock)) {
0173         ret = PTR_ERR(priv->map_nolock);
0174         dev_err(dev, "regmap init failed: %d\n", ret);
0175         return ret;
0176     }
0177 
0178     priv->mdio_addr = mdiodev->addr;
0179     priv->bus = mdiodev->bus;
0180     priv->dev = &mdiodev->dev;
0181     priv->chip_data = (void *)priv + sizeof(*priv);
0182 
0183     priv->clk_delay = var->clk_delay;
0184     priv->cmd_read = var->cmd_read;
0185     priv->cmd_write = var->cmd_write;
0186     priv->ops = var->ops;
0187 
0188     priv->write_reg_noack = realtek_mdio_write;
0189 
0190     np = dev->of_node;
0191 
0192     dev_set_drvdata(dev, priv);
0193 
0194     /* TODO: if power is software controlled, set up any regulators here */
0195     priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
0196 
0197     priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
0198     if (IS_ERR(priv->reset)) {
0199         dev_err(dev, "failed to get RESET GPIO\n");
0200         return PTR_ERR(priv->reset);
0201     }
0202 
0203     if (priv->reset) {
0204         gpiod_set_value(priv->reset, 1);
0205         dev_dbg(dev, "asserted RESET\n");
0206         msleep(REALTEK_HW_STOP_DELAY);
0207         gpiod_set_value(priv->reset, 0);
0208         msleep(REALTEK_HW_START_DELAY);
0209         dev_dbg(dev, "deasserted RESET\n");
0210     }
0211 
0212     ret = priv->ops->detect(priv);
0213     if (ret) {
0214         dev_err(dev, "unable to detect switch\n");
0215         return ret;
0216     }
0217 
0218     priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
0219     if (!priv->ds)
0220         return -ENOMEM;
0221 
0222     priv->ds->dev = dev;
0223     priv->ds->num_ports = priv->num_ports;
0224     priv->ds->priv = priv;
0225     priv->ds->ops = var->ds_ops_mdio;
0226 
0227     ret = dsa_register_switch(priv->ds);
0228     if (ret) {
0229         dev_err(priv->dev, "unable to register switch ret = %d\n", ret);
0230         return ret;
0231     }
0232 
0233     return 0;
0234 }
0235 
0236 static void realtek_mdio_remove(struct mdio_device *mdiodev)
0237 {
0238     struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
0239 
0240     if (!priv)
0241         return;
0242 
0243     dsa_unregister_switch(priv->ds);
0244 
0245     /* leave the device reset asserted */
0246     if (priv->reset)
0247         gpiod_set_value(priv->reset, 1);
0248 
0249     dev_set_drvdata(&mdiodev->dev, NULL);
0250 }
0251 
0252 static void realtek_mdio_shutdown(struct mdio_device *mdiodev)
0253 {
0254     struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
0255 
0256     if (!priv)
0257         return;
0258 
0259     dsa_switch_shutdown(priv->ds);
0260 
0261     dev_set_drvdata(&mdiodev->dev, NULL);
0262 }
0263 
0264 static const struct of_device_id realtek_mdio_of_match[] = {
0265 #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB)
0266     { .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, },
0267 #endif
0268 #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
0269     { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
0270 #endif
0271     { /* sentinel */ },
0272 };
0273 MODULE_DEVICE_TABLE(of, realtek_mdio_of_match);
0274 
0275 static struct mdio_driver realtek_mdio_driver = {
0276     .mdiodrv.driver = {
0277         .name = "realtek-mdio",
0278         .of_match_table = of_match_ptr(realtek_mdio_of_match),
0279     },
0280     .probe  = realtek_mdio_probe,
0281     .remove = realtek_mdio_remove,
0282     .shutdown = realtek_mdio_shutdown,
0283 };
0284 
0285 mdio_module_driver(realtek_mdio_driver);
0286 
0287 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
0288 MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface");
0289 MODULE_LICENSE("GPL");