diff options
-rw-r--r-- | drivers/base/regmap/regmap-mdio.c | 41 | ||||
-rw-r--r-- | include/linux/regmap.h | 8 |
2 files changed, 31 insertions, 18 deletions
diff --git a/drivers/base/regmap/regmap-mdio.c b/drivers/base/regmap/regmap-mdio.c index f7293040a2b1..6aa6a2409478 100644 --- a/drivers/base/regmap/regmap-mdio.c +++ b/drivers/base/regmap/regmap-mdio.c @@ -10,31 +10,21 @@ /* Clause-45 mask includes the device type (5 bit) and actual register number (16 bit) */ #define REGNUM_C45_MASK GENMASK(20, 0) -static int regmap_mdio_read(struct mdio_device *mdio_dev, u32 reg, unsigned int *val) +static int regmap_mdio_c22_read(void *context, unsigned int reg, unsigned int *val) { + struct mdio_device *mdio_dev = context; int ret; + if (unlikely(reg & ~REGNUM_C22_MASK)) + return -ENXIO; + ret = mdiodev_read(mdio_dev, reg); if (ret < 0) return ret; *val = ret & REGVAL_MASK; - return 0; -} - -static int regmap_mdio_write(struct mdio_device *mdio_dev, u32 reg, unsigned int val) -{ - return mdiodev_write(mdio_dev, reg, val); -} - -static int regmap_mdio_c22_read(void *context, unsigned int reg, unsigned int *val) -{ - struct mdio_device *mdio_dev = context; - - if (unlikely(reg & ~REGNUM_C22_MASK)) - return -ENXIO; - return regmap_mdio_read(mdio_dev, reg, val); + return 0; } static int regmap_mdio_c22_write(void *context, unsigned int reg, unsigned int val) @@ -55,21 +45,36 @@ static const struct regmap_bus regmap_mdio_c22_bus = { static int regmap_mdio_c45_read(void *context, unsigned int reg, unsigned int *val) { struct mdio_device *mdio_dev = context; + unsigned int devad; + int ret; if (unlikely(reg & ~REGNUM_C45_MASK)) return -ENXIO; - return regmap_mdio_read(mdio_dev, MII_ADDR_C45 | reg, val); + devad = reg >> REGMAP_MDIO_C45_DEVAD_SHIFT; + reg = reg & REGMAP_MDIO_C45_REGNUM_MASK; + + ret = mdiodev_c45_read(mdio_dev, devad, reg); + if (ret < 0) + return ret; + + *val = ret & REGVAL_MASK; + + return 0; } static int regmap_mdio_c45_write(void *context, unsigned int reg, unsigned int val) { struct mdio_device *mdio_dev = context; + unsigned int devad; if (unlikely(reg & ~REGNUM_C45_MASK)) return -ENXIO; - return regmap_mdio_write(mdio_dev, MII_ADDR_C45 | reg, val); + devad = reg >> REGMAP_MDIO_C45_DEVAD_SHIFT; + reg = reg & REGMAP_MDIO_C45_REGNUM_MASK; + + return mdiodev_c45_write(mdio_dev, devad, reg, val); } static const struct regmap_bus regmap_mdio_c45_bus = { diff --git a/include/linux/regmap.h b/include/linux/regmap.h index a3bc695bcca0..029b9e09d3ca 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -38,6 +38,14 @@ struct regmap_field; struct snd_ac97; struct sdw_slave; +/* + * regmap_mdio address encoding. IEEE 802.3ae clause 45 addresses consist of a + * device address and a register address. + */ +#define REGMAP_MDIO_C45_DEVAD_SHIFT 16 +#define REGMAP_MDIO_C45_DEVAD_MASK GENMASK(20, 16) +#define REGMAP_MDIO_C45_REGNUM_MASK GENMASK(15, 0) + /* An enum of all the supported cache types */ enum regcache_type { REGCACHE_NONE, |