mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	All patches automatically rebased. Build system: x86_64 Build-tested: bcm2711/RPi4B Run-tested: bcm2711/RPi4B Signed-off-by: John Audia <therealgraysky@proton.me>
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 3cb0bde365d913c484d20224367a54a0eac780a7 Mon Sep 17 00:00:00 2001
 | |
| From: Antoine Tenart <antoine.tenart@bootlin.com>
 | |
| Date: Fri, 21 Feb 2020 11:55:29 +0100
 | |
| Subject: [PATCH 3/3] net: phy: sfp: add support for SMBus
 | |
| 
 | |
| Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
 | |
| ---
 | |
|  drivers/net/phy/sfp.c | 68 ++++++++++++++++++++++++++++++++++---------
 | |
|  1 file changed, 54 insertions(+), 14 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/phy/sfp.c
 | |
| +++ b/drivers/net/phy/sfp.c
 | |
| @@ -413,32 +413,72 @@ static int sfp_i2c_write(struct sfp *sfp
 | |
|  	return ret == ARRAY_SIZE(msgs) ? len : 0;
 | |
|  }
 | |
|  
 | |
| +static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
 | |
| +			  size_t len)
 | |
| +{
 | |
| +	u8 bus_addr = a2 ? 0x51 : 0x50, *val = buf;
 | |
| +
 | |
| +	bus_addr -= 0x40;
 | |
| +
 | |
| +	while (len > 0) {
 | |
| +		*val = sfp->i2c_mii->read(sfp->i2c_mii, bus_addr, dev_addr);
 | |
| +
 | |
| +		val++;
 | |
| +		dev_addr++;
 | |
| +		len--;
 | |
| +	}
 | |
| +
 | |
| +	return val - (u8 *)buf;
 | |
| +}
 | |
| +
 | |
| +static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
 | |
| +			   size_t len)
 | |
| +{
 | |
| +	u8 bus_addr = a2 ? 0x51 : 0x50;
 | |
| +	u16 val;
 | |
| +
 | |
| +	memcpy(&val, buf, len);
 | |
| +
 | |
| +	return sfp->i2c_mii->write(sfp->i2c_mii, bus_addr, dev_addr, val);
 | |
| +}
 | |
| +
 | |
|  static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
 | |
|  {
 | |
| -	struct mii_bus *i2c_mii;
 | |
| +	struct mii_bus *mii;
 | |
|  	int ret;
 | |
|  
 | |
| -	if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
 | |
| -		return -EINVAL;
 | |
| -
 | |
|  	sfp->i2c = i2c;
 | |
| -	sfp->read = sfp_i2c_read;
 | |
| -	sfp->write = sfp_i2c_write;
 | |
|  
 | |
| -	i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
 | |
| -	if (IS_ERR(i2c_mii))
 | |
| -		return PTR_ERR(i2c_mii);
 | |
| +	if (i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
 | |
| +		sfp->read = sfp_i2c_read;
 | |
| +		sfp->write = sfp_i2c_write;
 | |
| +
 | |
| +		mii = mdio_i2c_alloc(sfp->dev, i2c);
 | |
| +		if (IS_ERR(mii))
 | |
| +			return PTR_ERR(mii);
 | |
| +
 | |
| +		mii->name = "SFP I2C Bus";
 | |
| +	} else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) {
 | |
| +		sfp->read = sfp_smbus_read;
 | |
| +		sfp->write = sfp_smbus_write;
 | |
| +
 | |
| +		mii = mdio_smbus_alloc(sfp->dev, i2c);
 | |
| +		if (IS_ERR(mii))
 | |
| +			return PTR_ERR(mii);
 | |
|  
 | |
| -	i2c_mii->name = "SFP I2C Bus";
 | |
| -	i2c_mii->phy_mask = ~0;
 | |
| +		mii->name = "SFP SMBus";
 | |
| +	} else {
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
|  
 | |
| -	ret = mdiobus_register(i2c_mii);
 | |
| +	mii->phy_mask = ~0;
 | |
| +	ret = mdiobus_register(mii);
 | |
|  	if (ret < 0) {
 | |
| -		mdiobus_free(i2c_mii);
 | |
| +		mdiobus_free(mii);
 | |
|  		return ret;
 | |
|  	}
 | |
|  
 | |
| -	sfp->i2c_mii = i2c_mii;
 | |
| +	sfp->i2c_mii = mii;
 | |
|  
 | |
|  	return 0;
 | |
|  }
 |