X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/d7d76ebff9e1fd64a232c60d7fd5b2f04a0c552d..5e66606678426ebb01fbd81d6212fb6fff2f896c:/target/linux/generic-2.6/files/drivers/net/phy/rtl8366_smi.c diff --git a/target/linux/generic-2.6/files/drivers/net/phy/rtl8366_smi.c b/target/linux/generic-2.6/files/drivers/net/phy/rtl8366_smi.c index 70218fc6c..625a01749 100644 --- a/target/linux/generic-2.6/files/drivers/net/phy/rtl8366_smi.c +++ b/target/linux/generic-2.6/files/drivers/net/phy/rtl8366_smi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "rtl8366_smi.h" @@ -91,10 +92,7 @@ static void rtl8366_smi_write_bits(struct rtl8366_smi *smi, u32 data, u32 len) rtl8366_smi_clk_delay(smi); /* prepare data */ - if ( data & ( 1 << (len - 1)) ) - gpio_set_value(sda, 1); - else - gpio_set_value(sda, 0); + gpio_set_value(sda, !!(data & ( 1 << (len - 1)))); rtl8366_smi_clk_delay(smi); /* clocking */ @@ -119,7 +117,7 @@ static void rtl8366_smi_read_bits(struct rtl8366_smi *smi, u32 len, u32 *data) /* clocking */ gpio_set_value(sck, 1); rtl8366_smi_clk_delay(smi); - u = gpio_get_value(sda); + u = !!gpio_get_value(sda); gpio_set_value(sck, 0); *data |= (u << (len - 1)); @@ -268,6 +266,47 @@ int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data) } EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg); +static int rtl8366_smi_mii_init(struct rtl8366_smi *smi) +{ + int ret; + int i; + + smi->mii_bus = mdiobus_alloc(); + if (smi->mii_bus == NULL) { + ret = -ENOMEM; + goto err; + } + + smi->mii_bus->priv = (void *) smi; + smi->mii_bus->name = dev_name(smi->parent); + smi->mii_bus->read = smi->ops->mii_read; + smi->mii_bus->write = smi->ops->mii_write; + snprintf(smi->mii_bus->id, MII_BUS_ID_SIZE, "%s", + dev_name(smi->parent)); + smi->mii_bus->parent = smi->parent; + smi->mii_bus->phy_mask = ~(0x1f); + smi->mii_bus->irq = smi->mii_irq; + for (i = 0; i < PHY_MAX_ADDR; i++) + smi->mii_irq[i] = PHY_POLL; + + ret = mdiobus_register(smi->mii_bus); + if (ret) + goto err_free; + + return 0; + + err_free: + mdiobus_free(smi->mii_bus); + err: + return ret; +} + +static void rtl8366_smi_mii_cleanup(struct rtl8366_smi *smi) +{ + mdiobus_unregister(smi->mii_bus); + mdiobus_free(smi->mii_bus); +} + int rtl8366_smi_init(struct rtl8366_smi *smi) { int err; @@ -275,6 +314,9 @@ int rtl8366_smi_init(struct rtl8366_smi *smi) if (!smi->parent) return -EINVAL; + if (!smi->ops) + return -EINVAL; + err = gpio_request(smi->gpio_sda, dev_name(smi->parent)); if (err) { dev_err(smi->parent, "gpio_request failed for %u, err=%d\n", @@ -294,8 +336,20 @@ int rtl8366_smi_init(struct rtl8366_smi *smi) dev_info(smi->parent, "using GPIO pins %u (SDA) and %u (SCK)\n", smi->gpio_sda, smi->gpio_sck); + err = smi->ops->detect(smi); + if (err) { + dev_err(smi->parent, "chip detection failed, err=%d\n", err); + goto err_free_sck; + } + + err = rtl8366_smi_mii_init(smi); + if (err) + goto err_free_sck; + return 0; + err_free_sck: + gpio_free(smi->gpio_sck); err_free_sda: gpio_free(smi->gpio_sda); err_out: @@ -305,6 +359,7 @@ EXPORT_SYMBOL_GPL(rtl8366_smi_init); void rtl8366_smi_cleanup(struct rtl8366_smi *smi) { + rtl8366_smi_mii_cleanup(smi); gpio_free(smi->gpio_sck); gpio_free(smi->gpio_sda); }