0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
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
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,
0117 .val_bits = 16,
0118 .reg_stride = 1,
0119
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,
0131 .val_bits = 16,
0132 .reg_stride = 1,
0133
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
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
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 { },
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");