mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 14:41:27 +00:00
lan78xx: Add to handle mux control per chip id
Depends on chip, some EEPROM pins are muxed with LED function. Disable & restore LED function to access EEPROM. Signed-off-by: Woojung Huh <woojung.huh@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e4953910ae
commit
a0db7d10b7
1 changed files with 71 additions and 27 deletions
|
@ -462,32 +462,53 @@ static int lan78xx_read_raw_eeprom(struct lan78xx_net *dev, u32 offset,
|
||||||
u32 length, u8 *data)
|
u32 length, u8 *data)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
|
u32 saved;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
int retval;
|
||||||
|
|
||||||
ret = lan78xx_eeprom_confirm_not_busy(dev);
|
/* depends on chip, some EEPROM pins are muxed with LED function.
|
||||||
if (ret)
|
* disable & restore LED function to access EEPROM.
|
||||||
return ret;
|
*/
|
||||||
|
ret = lan78xx_read_reg(dev, HW_CFG, &val);
|
||||||
|
saved = val;
|
||||||
|
if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000) {
|
||||||
|
val &= ~(HW_CFG_LED1_EN_ | HW_CFG_LED0_EN_);
|
||||||
|
ret = lan78xx_write_reg(dev, HW_CFG, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = lan78xx_eeprom_confirm_not_busy(dev);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_READ_;
|
val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_READ_;
|
||||||
val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
|
val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
|
||||||
ret = lan78xx_write_reg(dev, E2P_CMD, val);
|
ret = lan78xx_write_reg(dev, E2P_CMD, val);
|
||||||
if (unlikely(ret < 0))
|
if (unlikely(ret < 0)) {
|
||||||
return -EIO;
|
retval = -EIO;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
ret = lan78xx_wait_eeprom(dev);
|
retval = lan78xx_wait_eeprom(dev);
|
||||||
if (ret < 0)
|
if (retval < 0)
|
||||||
return ret;
|
goto exit;
|
||||||
|
|
||||||
ret = lan78xx_read_reg(dev, E2P_DATA, &val);
|
ret = lan78xx_read_reg(dev, E2P_DATA, &val);
|
||||||
if (unlikely(ret < 0))
|
if (unlikely(ret < 0)) {
|
||||||
return -EIO;
|
retval = -EIO;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
data[i] = val & 0xFF;
|
data[i] = val & 0xFF;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
retval = 0;
|
||||||
|
exit:
|
||||||
|
if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000)
|
||||||
|
ret = lan78xx_write_reg(dev, HW_CFG, saved);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lan78xx_read_eeprom(struct lan78xx_net *dev, u32 offset,
|
static int lan78xx_read_eeprom(struct lan78xx_net *dev, u32 offset,
|
||||||
|
@ -509,44 +530,67 @@ static int lan78xx_write_raw_eeprom(struct lan78xx_net *dev, u32 offset,
|
||||||
u32 length, u8 *data)
|
u32 length, u8 *data)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
|
u32 saved;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
int retval;
|
||||||
|
|
||||||
ret = lan78xx_eeprom_confirm_not_busy(dev);
|
/* depends on chip, some EEPROM pins are muxed with LED function.
|
||||||
if (ret)
|
* disable & restore LED function to access EEPROM.
|
||||||
return ret;
|
*/
|
||||||
|
ret = lan78xx_read_reg(dev, HW_CFG, &val);
|
||||||
|
saved = val;
|
||||||
|
if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000) {
|
||||||
|
val &= ~(HW_CFG_LED1_EN_ | HW_CFG_LED0_EN_);
|
||||||
|
ret = lan78xx_write_reg(dev, HW_CFG, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = lan78xx_eeprom_confirm_not_busy(dev);
|
||||||
|
if (retval)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
/* Issue write/erase enable command */
|
/* Issue write/erase enable command */
|
||||||
val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWEN_;
|
val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWEN_;
|
||||||
ret = lan78xx_write_reg(dev, E2P_CMD, val);
|
ret = lan78xx_write_reg(dev, E2P_CMD, val);
|
||||||
if (unlikely(ret < 0))
|
if (unlikely(ret < 0)) {
|
||||||
return -EIO;
|
retval = -EIO;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
ret = lan78xx_wait_eeprom(dev);
|
retval = lan78xx_wait_eeprom(dev);
|
||||||
if (ret < 0)
|
if (retval < 0)
|
||||||
return ret;
|
goto exit;
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
/* Fill data register */
|
/* Fill data register */
|
||||||
val = data[i];
|
val = data[i];
|
||||||
ret = lan78xx_write_reg(dev, E2P_DATA, val);
|
ret = lan78xx_write_reg(dev, E2P_DATA, val);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
return ret;
|
retval = -EIO;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* Send "write" command */
|
/* Send "write" command */
|
||||||
val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_WRITE_;
|
val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_WRITE_;
|
||||||
val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
|
val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
|
||||||
ret = lan78xx_write_reg(dev, E2P_CMD, val);
|
ret = lan78xx_write_reg(dev, E2P_CMD, val);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
return ret;
|
retval = -EIO;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
ret = lan78xx_wait_eeprom(dev);
|
retval = lan78xx_wait_eeprom(dev);
|
||||||
if (ret < 0)
|
if (retval < 0)
|
||||||
return ret;
|
goto exit;
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
retval = 0;
|
||||||
|
exit:
|
||||||
|
if ((dev->devid & ID_REV_CHIP_ID_MASK_) == 0x78000000)
|
||||||
|
ret = lan78xx_write_reg(dev, HW_CFG, saved);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset,
|
static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue