|
|
|
@ -199,7 +199,7 @@ static int rtl8366_smi_read_byte1(struct rtl8366_smi *smi, u8 *data) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) |
|
|
|
|
static int __rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) |
|
|
|
|
{ |
|
|
|
|
unsigned long flags; |
|
|
|
|
u8 lo = 0; |
|
|
|
@ -240,6 +240,101 @@ int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
/* Read/write via mdiobus */ |
|
|
|
|
#define MDC_MDIO_CTRL0_REG 31 |
|
|
|
|
#define MDC_MDIO_START_REG 29 |
|
|
|
|
#define MDC_MDIO_CTRL1_REG 21 |
|
|
|
|
#define MDC_MDIO_ADDRESS_REG 23 |
|
|
|
|
#define MDC_MDIO_DATA_WRITE_REG 24 |
|
|
|
|
#define MDC_MDIO_DATA_READ_REG 25 |
|
|
|
|
|
|
|
|
|
#define MDC_MDIO_START_OP 0xFFFF |
|
|
|
|
#define MDC_MDIO_ADDR_OP 0x000E |
|
|
|
|
#define MDC_MDIO_READ_OP 0x0001 |
|
|
|
|
#define MDC_MDIO_WRITE_OP 0x0003 |
|
|
|
|
#define MDC_REALTEK_PHY_ADDR 0x0 |
|
|
|
|
|
|
|
|
|
int __rtl8366_mdio_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) |
|
|
|
|
{ |
|
|
|
|
u32 phy_id = MDC_REALTEK_PHY_ADDR; |
|
|
|
|
struct mii_bus *mbus = smi->ext_mbus; |
|
|
|
|
|
|
|
|
|
BUG_ON(in_interrupt()); |
|
|
|
|
|
|
|
|
|
mutex_lock(&mbus->mdio_lock); |
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Write address control code to register 31 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); |
|
|
|
|
|
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Write address to register 23 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_ADDRESS_REG, addr); |
|
|
|
|
|
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Write read control code to register 21 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP); |
|
|
|
|
|
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(smi->ext_mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Read data from register 25 */ |
|
|
|
|
*data = mbus->read(mbus, phy_id, MDC_MDIO_DATA_READ_REG); |
|
|
|
|
|
|
|
|
|
mutex_unlock(&mbus->mdio_lock); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int __rtl8366_mdio_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data) |
|
|
|
|
{ |
|
|
|
|
u32 phy_id = MDC_REALTEK_PHY_ADDR; |
|
|
|
|
struct mii_bus *mbus = smi->ext_mbus; |
|
|
|
|
|
|
|
|
|
BUG_ON(in_interrupt()); |
|
|
|
|
|
|
|
|
|
mutex_lock(&mbus->mdio_lock); |
|
|
|
|
|
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Write address control code to register 31 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); |
|
|
|
|
|
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Write address to register 23 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_ADDRESS_REG, addr); |
|
|
|
|
|
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Write data to register 24 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_DATA_WRITE_REG, data); |
|
|
|
|
|
|
|
|
|
/* Write Start command to register 29 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); |
|
|
|
|
|
|
|
|
|
/* Write data control code to register 21 */ |
|
|
|
|
mbus->write(mbus, phy_id, MDC_MDIO_CTRL1_REG, MDC_MDIO_WRITE_OP); |
|
|
|
|
|
|
|
|
|
mutex_unlock(&mbus->mdio_lock); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) |
|
|
|
|
{ |
|
|
|
|
if (smi->ext_mbus) |
|
|
|
|
return __rtl8366_mdio_read_reg(smi, addr, data); |
|
|
|
|
else |
|
|
|
|
return __rtl8366_smi_read_reg(smi, addr, data); |
|
|
|
|
} |
|
|
|
|
EXPORT_SYMBOL_GPL(rtl8366_smi_read_reg); |
|
|
|
|
|
|
|
|
|
static int __rtl8366_smi_write_reg(struct rtl8366_smi *smi, |
|
|
|
@ -291,7 +386,10 @@ static int __rtl8366_smi_write_reg(struct rtl8366_smi *smi, |
|
|
|
|
|
|
|
|
|
int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data) |
|
|
|
|
{ |
|
|
|
|
return __rtl8366_smi_write_reg(smi, addr, data, true); |
|
|
|
|
if (smi->ext_mbus) |
|
|
|
|
return __rtl8366_mdio_write_reg(smi, addr, data); |
|
|
|
|
else |
|
|
|
|
return __rtl8366_smi_write_reg(smi, addr, data, true); |
|
|
|
|
} |
|
|
|
|
EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg); |
|
|
|
|
|
|
|
|
@ -1282,18 +1380,20 @@ static int __rtl8366_smi_init(struct rtl8366_smi *smi, const char *name) |
|
|
|
|
{ |
|
|
|
|
int err; |
|
|
|
|
|
|
|
|
|
err = gpio_request(smi->gpio_sda, name); |
|
|
|
|
if (err) { |
|
|
|
|
printk(KERN_ERR "rtl8366_smi: gpio_request failed for %u, err=%d\n", |
|
|
|
|
smi->gpio_sda, err); |
|
|
|
|
goto err_out; |
|
|
|
|
} |
|
|
|
|
if (!smi->ext_mbus) { |
|
|
|
|
err = gpio_request(smi->gpio_sda, name); |
|
|
|
|
if (err) { |
|
|
|
|
printk(KERN_ERR "rtl8366_smi: gpio_request failed for %u, err=%d\n", |
|
|
|
|
smi->gpio_sda, err); |
|
|
|
|
goto err_out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = gpio_request(smi->gpio_sck, name); |
|
|
|
|
if (err) { |
|
|
|
|
printk(KERN_ERR "rtl8366_smi: gpio_request failed for %u, err=%d\n", |
|
|
|
|
smi->gpio_sck, err); |
|
|
|
|
goto err_free_sda; |
|
|
|
|
err = gpio_request(smi->gpio_sck, name); |
|
|
|
|
if (err) { |
|
|
|
|
printk(KERN_ERR "rtl8366_smi: gpio_request failed for %u, err=%d\n", |
|
|
|
|
smi->gpio_sck, err); |
|
|
|
|
goto err_free_sda; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
spin_lock_init(&smi->lock); |
|
|
|
@ -1317,8 +1417,10 @@ static void __rtl8366_smi_cleanup(struct rtl8366_smi *smi) |
|
|
|
|
if (smi->hw_reset) |
|
|
|
|
smi->hw_reset(smi, true); |
|
|
|
|
|
|
|
|
|
gpio_free(smi->gpio_sck); |
|
|
|
|
gpio_free(smi->gpio_sda); |
|
|
|
|
if (!smi->ext_mbus) { |
|
|
|
|
gpio_free(smi->gpio_sck); |
|
|
|
|
gpio_free(smi->gpio_sda); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum rtl8366_type rtl8366_smi_detect(struct rtl8366_platform_data *pdata) |
|
|
|
@ -1371,8 +1473,11 @@ int rtl8366_smi_init(struct rtl8366_smi *smi) |
|
|
|
|
if (err) |
|
|
|
|
goto err_out; |
|
|
|
|
|
|
|
|
|
dev_info(smi->parent, "using GPIO pins %u (SDA) and %u (SCK)\n", |
|
|
|
|
smi->gpio_sda, smi->gpio_sck); |
|
|
|
|
if (!smi->ext_mbus) |
|
|
|
|
dev_info(smi->parent, "using GPIO pins %u (SDA) and %u (SCK)\n", |
|
|
|
|
smi->gpio_sda, smi->gpio_sck); |
|
|
|
|
else |
|
|
|
|
dev_info(smi->parent, "using MDIO bus '%s'\n", smi->ext_mbus->name); |
|
|
|
|
|
|
|
|
|
err = smi->ops->detect(smi); |
|
|
|
|
if (err) { |
|
|
|
@ -1437,7 +1542,25 @@ int rtl8366_smi_probe_of(struct platform_device *pdev, struct rtl8366_smi *smi) |
|
|
|
|
{ |
|
|
|
|
int sck = of_get_named_gpio(pdev->dev.of_node, "gpio-sck", 0); |
|
|
|
|
int sda = of_get_named_gpio(pdev->dev.of_node, "gpio-sda", 0); |
|
|
|
|
struct device_node *np = pdev->dev.of_node; |
|
|
|
|
struct device_node *mdio_node; |
|
|
|
|
|
|
|
|
|
mdio_node = of_parse_phandle(np, "mii-bus", 0); |
|
|
|
|
if (!mdio_node) { |
|
|
|
|
dev_err(&pdev->dev, "cannot find mdio node phandle"); |
|
|
|
|
goto try_gpio; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
smi->ext_mbus = of_mdio_find_bus(mdio_node); |
|
|
|
|
if (!smi->ext_mbus) { |
|
|
|
|
dev_err(&pdev->dev, |
|
|
|
|
"cannot find mdio bus from bus handle"); |
|
|
|
|
goto try_gpio; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
try_gpio: |
|
|
|
|
if (!gpio_is_valid(sck) || !gpio_is_valid(sda)) { |
|
|
|
|
dev_err(&pdev->dev, "gpios missing in devictree\n"); |
|
|
|
|
return -EINVAL; |
|
|
|
|