From de95588158736ff3908daa2bae837d9530cf01b4 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 8 Dec 2009 10:29:35 +0000 Subject: [PATCH] ar71xx: add mdio bus driver for the rtl8366 switch SVN-Revision: 18694 --- target/linux/ar71xx/config-2.6.28 | 1 + target/linux/ar71xx/config-2.6.30 | 1 + target/linux/ar71xx/config-2.6.31 | 1 + target/linux/ar71xx/config-2.6.32 | 1 + .../files/drivers/net/phy/rtl8366_smi.c | 661 ++++++++++++++++++ .../ar71xx/files/include/linux/rtl8366_smi.h | 19 + .../204-rtl8366-smi-driver.patch | 21 + .../204-rtl8366-smi-driver.patch | 21 + .../204-rtl8366-smi-driver.patch | 21 + .../204-rtl8366-smi-driver.patch | 21 + 10 files changed, 768 insertions(+) create mode 100644 target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c create mode 100644 target/linux/ar71xx/files/include/linux/rtl8366_smi.h create mode 100644 target/linux/ar71xx/patches-2.6.28/204-rtl8366-smi-driver.patch create mode 100644 target/linux/ar71xx/patches-2.6.30/204-rtl8366-smi-driver.patch create mode 100644 target/linux/ar71xx/patches-2.6.31/204-rtl8366-smi-driver.patch create mode 100644 target/linux/ar71xx/patches-2.6.32/204-rtl8366-smi-driver.patch diff --git a/target/linux/ar71xx/config-2.6.28 b/target/linux/ar71xx/config-2.6.28 index b155259153..83587906ee 100644 --- a/target/linux/ar71xx/config-2.6.28 +++ b/target/linux/ar71xx/config-2.6.28 @@ -162,6 +162,7 @@ CONFIG_PHYLIB=y # CONFIG_PROBE_INITRD_HEADER is not set # CONFIG_R6040 is not set CONFIG_RTL8306_PHY=y +CONFIG_RTL8366_SMI=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_SCSI_DMA is not set # CONFIG_SERIAL_8250_EXTENDED is not set diff --git a/target/linux/ar71xx/config-2.6.30 b/target/linux/ar71xx/config-2.6.30 index 0db13af3c7..3cedfdc460 100644 --- a/target/linux/ar71xx/config-2.6.30 +++ b/target/linux/ar71xx/config-2.6.30 @@ -166,6 +166,7 @@ CONFIG_PHYLIB=y # CONFIG_PNX8550_STB810 is not set # CONFIG_PROBE_INITRD_HEADER is not set CONFIG_RTL8306_PHY=y +CONFIG_RTL8366_SMI=y CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_SCSI_DMA is not set # CONFIG_SERIAL_8250_EXTENDED is not set diff --git a/target/linux/ar71xx/config-2.6.31 b/target/linux/ar71xx/config-2.6.31 index 2e4a56be48..0615a50f43 100644 --- a/target/linux/ar71xx/config-2.6.31 +++ b/target/linux/ar71xx/config-2.6.31 @@ -169,6 +169,7 @@ CONFIG_PHYLIB=y # CONFIG_PNX8550_STB810 is not set # CONFIG_PROBE_INITRD_HEADER is not set CONFIG_RTL8306_PHY=y +CONFIG_RTL8366_SMI=y CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_SCSI_DMA is not set # CONFIG_SERIAL_8250_EXTENDED is not set diff --git a/target/linux/ar71xx/config-2.6.32 b/target/linux/ar71xx/config-2.6.32 index dcca7d22b7..f1a69bc0bc 100644 --- a/target/linux/ar71xx/config-2.6.32 +++ b/target/linux/ar71xx/config-2.6.32 @@ -173,6 +173,7 @@ CONFIG_PHYLIB=y # CONFIG_PNX8550_STB810 is not set # CONFIG_PROBE_INITRD_HEADER is not set CONFIG_RTL8306_PHY=y +CONFIG_RTL8366_SMI=y CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_SCSI_DMA is not set # CONFIG_SERIAL_8250_EXTENDED is not set diff --git a/target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c b/target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c new file mode 100644 index 0000000000..e43f8a2d03 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/phy/rtl8366_smi.c @@ -0,0 +1,661 @@ +/* + * Platform driver for the Realtek RTL8366 ethernet switch + * + * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DEBUG 1 + +#define RTL8366_SMI_DRIVER_NAME "rtl8366-smi" +#define RTL8366_SMI_DRIVER_DESC "Realtek RTL8366 switch driver" +#define RTL8366_SMI_DRIVER_VER "0.1.0" + +#define RTL8366S_PHY_NO_MAX 4 +#define RTL8366S_PHY_PAGE_MAX 7 +#define RTL8366S_PHY_ADDR_MAX 31 + +#define RTL8366S_CHIP_VERSION_CTRL_REG 0x0104 +#define RTL8366S_CHIP_VERSION_MASK 0xf +#define RTL8366S_CHIP_ID_REG 0x0105 +#define RTL8366S_CHIP_ID_8366 0x8366 + +/* PHY registers control */ +#define RTL8366S_PHY_ACCESS_CTRL_REG 0x8028 +#define RTL8366S_PHY_ACCESS_DATA_REG 0x8029 + +#define RTL8366S_PHY_CTRL_READ 1 +#define RTL8366S_PHY_CTRL_WRITE 0 + +#define RTL8366S_PHY_REG_MASK 0x1f +#define RTL8366S_PHY_PAGE_OFFSET 5 +#define RTL8366S_PHY_PAGE_MASK (0x7 << 5) +#define RTL8366S_PHY_NO_OFFSET 9 +#define RTL8366S_PHY_NO_MASK (0x1f << 9) + +#define RTL8366_SMI_ACK_RETRY_COUNT 5 +#define RTL8366_SMI_CLK_DELAY 10 /* nsec */ + +struct rtl8366_smi { + struct platform_device *pdev; + struct rtl8366_smi_platform_data *pdata; + spinlock_t lock; + struct mii_bus *mii_bus; + int mii_irq[PHY_MAX_ADDR]; +}; + +static inline void rtl8366_smi_clk_delay(struct rtl8366_smi *smi) +{ + ndelay(RTL8366_SMI_CLK_DELAY); +} + +static void rtl8366_smi_start(struct rtl8366_smi *smi) +{ + unsigned int sda = smi->pdata->gpio_sda; + unsigned int sck = smi->pdata->gpio_sck; + + /* + * Set GPIO pins to output mode, with initial state: + * SCK = 0, SDA = 1 + */ + gpio_direction_output(sck, 0); + gpio_direction_output(sda, 1); + rtl8366_smi_clk_delay(smi); + + /* CLK 1: 0 -> 1, 1 -> 0 */ + gpio_set_value(sck, 1); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 0); + rtl8366_smi_clk_delay(smi); + + /* CLK 2: */ + gpio_set_value(sck, 1); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sda, 0); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 0); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sda, 1); +} + +static void rtl8366_smi_stop(struct rtl8366_smi *smi) +{ + unsigned int sda = smi->pdata->gpio_sda; + unsigned int sck = smi->pdata->gpio_sck; + + rtl8366_smi_clk_delay(smi); + gpio_set_value(sda, 0); + gpio_set_value(sck, 1); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sda, 1); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 1); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 0); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 1); + + /* add a click */ + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 0); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 1); + + /* set GPIO pins to input mode */ + gpio_direction_input(sda); + gpio_direction_input(sck); +} + +static void rtl8366_smi_write_bits(struct rtl8366_smi *smi, u32 data, u32 len) +{ + unsigned int sda = smi->pdata->gpio_sda; + unsigned int sck = smi->pdata->gpio_sck; + + for (; len > 0; len--) { + rtl8366_smi_clk_delay(smi); + + /* prepare data */ + if ( data & ( 1 << (len - 1)) ) + gpio_set_value(sda, 1); + else + gpio_set_value(sda, 0); + rtl8366_smi_clk_delay(smi); + + /* clocking */ + gpio_set_value(sck, 1); + rtl8366_smi_clk_delay(smi); + gpio_set_value(sck, 0); + } +} + +static void rtl8366_smi_read_bits(struct rtl8366_smi *smi, u32 len, u32 *data) +{ + unsigned int sda = smi->pdata->gpio_sda; + unsigned int sck = smi->pdata->gpio_sck; + + gpio_direction_input(sda); + + for (*data = 0; len > 0; len--) { + u32 u; + + rtl8366_smi_clk_delay(smi); + + /* clocking */ + gpio_set_value(sck, 1); + rtl8366_smi_clk_delay(smi); + u = gpio_get_value(sda); + gpio_set_value(sck, 0); + + *data |= (u << (len - 1)); + } + + gpio_direction_output(sda, 0); +} + +static int rtl8366_smi_wait_for_ack(struct rtl8366_smi *smi) +{ + int retry_cnt; + + retry_cnt = 0; + do { + u32 ack; + + rtl8366_smi_read_bits(smi, 1, &ack); + if (ack == 0) + break; + + if (++retry_cnt > RTL8366_SMI_ACK_RETRY_COUNT) + return -EIO; + } while (1); + + return 0; +} + +static int rtl8366_smi_write_byte(struct rtl8366_smi *smi, u8 data) +{ + rtl8366_smi_write_bits(smi, data, 8); + return rtl8366_smi_wait_for_ack(smi); +} + +static int rtl8366_smi_read_byte0(struct rtl8366_smi *smi, u8 *data) +{ + u32 t; + + /* read data */ + rtl8366_smi_read_bits(smi, 8, &t); + *data = (t & 0xff); + + /* send an ACK */ + rtl8366_smi_write_bits(smi, 0x00, 1); + + return 0; +} + +static int rtl8366_smi_read_byte1(struct rtl8366_smi *smi, u8 *data) +{ + u32 t; + + /* read data */ + rtl8366_smi_read_bits(smi, 8, &t); + *data = (t & 0xff); + + /* send an ACK */ + rtl8366_smi_write_bits(smi, 0x01, 1); + + return 0; +} + +static int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) +{ + unsigned long flags; + u8 lo = 0; + u8 hi = 0; + int ret; + + spin_lock_irqsave(&smi->lock, flags); + + rtl8366_smi_start(smi); + + /* send READ command */ + ret = rtl8366_smi_write_byte(smi, 0x0a << 4 | 0x04 << 1 | 0x01); + if (ret) + goto out; + + /* set ADDR[7:0] */ + ret = rtl8366_smi_write_byte(smi, addr & 0xff); + if (ret) + goto out; + + /* set ADDR[15:8] */ + ret = rtl8366_smi_write_byte(smi, addr >> 8); + if (ret) + goto out; + + /* read DATA[7:0] */ + rtl8366_smi_read_byte0(smi, &lo); + /* read DATA[15:8] */ + rtl8366_smi_read_byte1(smi, &hi); + + *data = ((u32) lo) | (((u32) hi) << 8); + + ret = 0; + + out: + rtl8366_smi_stop(smi); + spin_unlock_irqrestore(&smi->lock, flags); + + return ret; +} + +static int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&smi->lock, flags); + + rtl8366_smi_start(smi); + + /* send WRITE command */ + ret = rtl8366_smi_write_byte(smi, 0x0a << 4 | 0x04 << 1 | 0x00); + if (ret) + goto out; + + /* set ADDR[7:0] */ + ret = rtl8366_smi_write_byte(smi, addr & 0xff); + if (ret) + goto out; + + /* set ADDR[15:8] */ + ret = rtl8366_smi_write_byte(smi, addr >> 8); + if (ret) + goto out; + + /* write DATA[7:0] */ + ret = rtl8366_smi_write_byte(smi, data & 0xff); + if (ret) + goto out; + + /* write DATA[15:8] */ + ret = rtl8366_smi_write_byte(smi, data >> 8); + if (ret) + goto out; + + ret = 0; + + out: + rtl8366_smi_stop(smi); + spin_unlock_irqrestore(&smi->lock, flags); + + return ret; +} + +static int rtl8366_smi_read_phy_reg(struct rtl8366_smi *smi, + u32 phy_no, u32 page, u32 addr, u32 *data) +{ + u32 reg; + int ret; + + if (phy_no > RTL8366S_PHY_NO_MAX) + return -EINVAL; + + if (page > RTL8366S_PHY_PAGE_MAX) + return -EINVAL; + + if (addr > RTL8366S_PHY_ADDR_MAX) + return -EINVAL; + + ret = rtl8366_smi_write_reg(smi, RTL8366S_PHY_ACCESS_CTRL_REG, + RTL8366S_PHY_CTRL_READ); + if (ret) + return ret; + + reg = 0x8000 | (1 << (phy_no + RTL8366S_PHY_NO_OFFSET)) | + ((page << RTL8366S_PHY_PAGE_OFFSET) & RTL8366S_PHY_PAGE_MASK) | + (addr & RTL8366S_PHY_REG_MASK); + + ret = rtl8366_smi_write_reg(smi, reg, 0); + if (ret) + return ret; + + ret = rtl8366_smi_read_reg(smi, RTL8366S_PHY_ACCESS_DATA_REG, data); + if (ret) + return ret; + + return 0; +} + +static int rtl8366_smi_write_phy_reg(struct rtl8366_smi *smi, + u32 phy_no, u32 page, u32 addr, u32 data) +{ + u32 reg; + int ret; + + if (phy_no > RTL8366S_PHY_NO_MAX) + return -EINVAL; + + if (page > RTL8366S_PHY_PAGE_MAX) + return -EINVAL; + + if (addr > RTL8366S_PHY_ADDR_MAX) + return -EINVAL; + + ret = rtl8366_smi_write_reg(smi, RTL8366S_PHY_ACCESS_CTRL_REG, + RTL8366S_PHY_CTRL_WRITE); + if (ret) + return ret; + + reg = 0x8000 | (1 << (phy_no + RTL8366S_PHY_NO_OFFSET)) | + ((page << RTL8366S_PHY_PAGE_OFFSET) & RTL8366S_PHY_PAGE_MASK) | + (addr & RTL8366S_PHY_REG_MASK); + + ret = rtl8366_smi_write_reg(smi, reg, data); + if (ret) + return ret; + + return 0; +} + +#ifdef DEBUG +static void rtl8366_smi_dump_regs(struct rtl8366_smi *smi) +{ + u32 t; + int err; + int i; + + for (i = 0; i < 0x200; i++) { + err = rtl8366_smi_read_reg(smi, i, &t); + if (err) { + dev_err(&smi->pdev->dev, + "unable to read register %04x\n", i); + return; + } + dev_info(&smi->pdev->dev, "reg %04x: %04x\n", i, t); + } + + for (i = 0; i <= RTL8366S_PHY_NO_MAX; i++) { + int j; + + for (j = 0; j <= RTL8366S_PHY_ADDR_MAX; j++) { + err = rtl8366_smi_read_phy_reg(smi, i, 0, j, &t); + if (err) { + dev_err(&smi->pdev->dev, + "unable to read PHY%u:%02x register\n", + i, j); + return; + } + dev_info(&smi->pdev->dev, + "PHY%u:%02x: %04x\n", i, j, t); + } + } +} +#else +static inline void rtl8366_smi_dump_regs(struct rtl8366_smi *smi) {} +#endif + +static int rtl8366_smi_mii_read(struct mii_bus *bus, int addr, int reg) +{ + struct rtl8366_smi *smi = bus->priv; + u32 val = 0; + int err; + + err = rtl8366_smi_read_phy_reg(smi, addr, 0, reg, &val); + if (err) + return 0xffff; + + return val; +} + +static int rtl8366_smi_mii_write(struct mii_bus *bus, int addr, int reg, + u16 val) +{ + struct rtl8366_smi *smi = bus->priv; + u32 t; + int err; + + err = rtl8366_smi_write_phy_reg(smi, addr, 0, reg, val); + /* flush write */ + (void) rtl8366_smi_read_phy_reg(smi, addr, 0, reg, &t); + + return err; +} + +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; + } + + spin_lock_init(&smi->lock); + smi->mii_bus->priv = (void *) smi; + smi->mii_bus->name = "rtl8366-smi"; + smi->mii_bus->read = rtl8366_smi_mii_read; + smi->mii_bus->write = rtl8366_smi_mii_write; + snprintf(smi->mii_bus->id, MII_BUS_ID_SIZE, "%s", + dev_name(&smi->pdev->dev)); + smi->mii_bus->parent = &smi->pdev->dev; + 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; + + rtl8366_smi_dump_regs(smi); + + ret = mdiobus_register(smi->mii_bus); + if (ret) + goto err_free; + + rtl8366_smi_dump_regs(smi); + + 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); +} + +static int rtl8366_smi_setup(struct rtl8366_smi *smi) +{ + u32 chip_id = 0; + u32 chip_ver = 0; + int ret; + + ret = rtl8366_smi_read_reg(smi, RTL8366S_CHIP_ID_REG, &chip_id); + if (ret) { + dev_err(&smi->pdev->dev, "unable to read chip id\n"); + return ret; + } + + switch (chip_id) { + case RTL8366S_CHIP_ID_8366: + break; + default: + dev_err(&smi->pdev->dev, "unknown chip id (%04x)\n", chip_id); + return -ENODEV; + } + + ret = rtl8366_smi_read_reg(smi, RTL8366S_CHIP_VERSION_CTRL_REG, + &chip_ver); + if (ret) { + dev_err(&smi->pdev->dev, "unable to read chip version\n"); + return ret; + } + + dev_info(&smi->pdev->dev, "RTL%04x ver. %u chip found\n", + chip_id, chip_ver & RTL8366S_CHIP_VERSION_MASK); + + return 0; +} + +static int __init rtl8366_smi_probe(struct platform_device *pdev) +{ + static int rtl8366_smi_version_printed; + struct rtl8366_smi_platform_data *pdata; + struct rtl8366_smi *smi; + int err; + + if (!rtl8366_smi_version_printed++) + printk(KERN_NOTICE RTL8366_SMI_DRIVER_DESC + " version " RTL8366_SMI_DRIVER_VER"\n"); + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data specified\n"); + err = -EINVAL; + goto err_out; + } + + smi = kzalloc(sizeof(struct rtl8366_smi), GFP_KERNEL); + if (!smi) { + dev_err(&pdev->dev, "no memory for private data\n"); + err = -ENOMEM; + goto err_out; + } + + err = gpio_request(pdata->gpio_sda, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "gpio_request failed for %u, err=%d\n", + pdata->gpio_sda, err); + goto err_free_smi; + } + + err = gpio_request(pdata->gpio_sck, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "gpio_request failed for %u, err=%d\n", + pdata->gpio_sck, err); + goto err_free_sda; + } + + smi->pdev = pdev; + smi->pdata = pdata; + spin_lock_init(&smi->lock); + + platform_set_drvdata(pdev, smi); + + dev_info(&pdev->dev, "using GPIO pins %u (SDA) and %u (SCK)\n", + pdata->gpio_sda, pdata->gpio_sck); + + err = rtl8366_smi_setup(smi); + if (err) + goto err_clear_drvdata; + + err = rtl8366_smi_mii_init(smi); + if (err) + goto err_clear_drvdata; + + return 0; + + err_clear_drvdata: + platform_set_drvdata(pdev, NULL); + gpio_free(pdata->gpio_sck); + err_free_sda: + gpio_free(pdata->gpio_sda); + err_free_smi: + kfree(smi); + err_out: + return err; +} + +static int __devexit rtl8366_smi_remove(struct platform_device *pdev) +{ + struct rtl8366_smi *smi = platform_get_drvdata(pdev); + + if (smi) { + struct rtl8366_smi_platform_data *pdata; + + pdata = pdev->dev.platform_data; + + rtl8366_smi_mii_cleanup(smi); + platform_set_drvdata(pdev, NULL); + gpio_free(pdata->gpio_sck); + gpio_free(pdata->gpio_sda); + kfree(smi); + } + + return 0; +} + +int rtl8366_phy_config_aneg(struct phy_device *phydev) +{ + return 0; +} + +static struct platform_driver rtl8366_smi_driver = { + .driver = { + .name = RTL8366_SMI_DRIVER_NAME, + .owner = THIS_MODULE, + }, + .probe = rtl8366_smi_probe, + .remove = __devexit_p(rtl8366_smi_remove), +}; + +static struct phy_driver rtl8366_smi_phy_driver = { + .phy_id = 0x001cc960, + .name = "Realtek RTL8366", + .phy_id_mask = 0x1ffffff0, + .features = PHY_GBIT_FEATURES, + .config_aneg = rtl8366_phy_config_aneg, + .read_status = genphy_read_status, + .driver = { + .owner = THIS_MODULE, + }, +}; + +static int __init rtl8366_smi_init(void) +{ + int ret; + + ret = phy_driver_register(&rtl8366_smi_phy_driver); + if (ret) + return ret; + + ret = platform_driver_register(&rtl8366_smi_driver); + if (ret) + goto err_phy_unregister; + + return 0; + + err_phy_unregister: + phy_driver_unregister(&rtl8366_smi_phy_driver); + return ret; +} +module_init(rtl8366_smi_init); + +static void __exit rtl8366_smi_exit(void) +{ + platform_driver_unregister(&rtl8366_smi_driver); + phy_driver_unregister(&rtl8366_smi_phy_driver); +} +module_exit(rtl8366_smi_exit); + +MODULE_DESCRIPTION(RTL8366_SMI_DRIVER_DESC); +MODULE_VERSION(RTL8366_SMI_DRIVER_VER); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" RTL8366_SMI_DRIVER_NAME); diff --git a/target/linux/ar71xx/files/include/linux/rtl8366_smi.h b/target/linux/ar71xx/files/include/linux/rtl8366_smi.h new file mode 100644 index 0000000000..cd0fcbc452 --- /dev/null +++ b/target/linux/ar71xx/files/include/linux/rtl8366_smi.h @@ -0,0 +1,19 @@ +/* + * Platform data definition for the Realtek RTL8366 ethernet switch driver + * + * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef _RTL8366_SMI_H +#define _RTL8366_SMI_H + +struct rtl8366_smi_platform_data { + unsigned gpio_sda; + unsigned gpio_sck; +}; + +#endif /* _RTL8366_SMI_H */ diff --git a/target/linux/ar71xx/patches-2.6.28/204-rtl8366-smi-driver.patch b/target/linux/ar71xx/patches-2.6.28/204-rtl8366-smi-driver.patch new file mode 100644 index 0000000000..afb3cbdb7b --- /dev/null +++ b/target/linux/ar71xx/patches-2.6.28/204-rtl8366-smi-driver.patch @@ -0,0 +1,21 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -114,4 +114,8 @@ config MDIO_OF_GPIO + ---help--- + Supports GPIO lib-based MDIO busses. + ++config RTL8366_SMI ++ tristate "Support for RTL8366 switch via SMI interface" ++ depends on GENERIC_GPIO ++ + endif # PHYLIB +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -17,6 +17,7 @@ obj-$(CONFIG_ADM6996_PHY) += adm6996.o + obj-$(CONFIG_IP175C_PHY) += ip175c.o + obj-$(CONFIG_RTL8306_PHY) += rtl8306.o + obj-$(CONFIG_REALTEK_PHY) += realtek.o ++obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o + obj-$(CONFIG_MICREL_PHY) += micrel.o + obj-$(CONFIG_FIXED_PHY) += fixed.o + obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o diff --git a/target/linux/ar71xx/patches-2.6.30/204-rtl8366-smi-driver.patch b/target/linux/ar71xx/patches-2.6.30/204-rtl8366-smi-driver.patch new file mode 100644 index 0000000000..77874b49f6 --- /dev/null +++ b/target/linux/ar71xx/patches-2.6.30/204-rtl8366-smi-driver.patch @@ -0,0 +1,21 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -140,4 +140,8 @@ config MDIO_GPIO + To compile this driver as a module, choose M here: the module + will be called mdio-gpio. + ++config RTL8366_SMI ++ tristate "Support for RTL8366 switch via SMI interface" ++ depends on GENERIC_GPIO ++ + endif # PHYLIB +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -19,6 +19,7 @@ obj-$(CONFIG_IP175C_PHY) += ip175c.o + obj-$(CONFIG_REALTEK_PHY) += realtek.o + obj-$(CONFIG_AR8216_PHY) += ar8216.o + obj-$(CONFIG_RTL8306_PHY) += rtl8306.o ++obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o + obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o + obj-$(CONFIG_MICREL) += micrel.o + obj-$(CONFIG_FIXED_PHY) += fixed.o diff --git a/target/linux/ar71xx/patches-2.6.31/204-rtl8366-smi-driver.patch b/target/linux/ar71xx/patches-2.6.31/204-rtl8366-smi-driver.patch new file mode 100644 index 0000000000..77874b49f6 --- /dev/null +++ b/target/linux/ar71xx/patches-2.6.31/204-rtl8366-smi-driver.patch @@ -0,0 +1,21 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -140,4 +140,8 @@ config MDIO_GPIO + To compile this driver as a module, choose M here: the module + will be called mdio-gpio. + ++config RTL8366_SMI ++ tristate "Support for RTL8366 switch via SMI interface" ++ depends on GENERIC_GPIO ++ + endif # PHYLIB +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -19,6 +19,7 @@ obj-$(CONFIG_IP175C_PHY) += ip175c.o + obj-$(CONFIG_REALTEK_PHY) += realtek.o + obj-$(CONFIG_AR8216_PHY) += ar8216.o + obj-$(CONFIG_RTL8306_PHY) += rtl8306.o ++obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o + obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o + obj-$(CONFIG_MICREL) += micrel.o + obj-$(CONFIG_FIXED_PHY) += fixed.o diff --git a/target/linux/ar71xx/patches-2.6.32/204-rtl8366-smi-driver.patch b/target/linux/ar71xx/patches-2.6.32/204-rtl8366-smi-driver.patch new file mode 100644 index 0000000000..78ec2e44c0 --- /dev/null +++ b/target/linux/ar71xx/patches-2.6.32/204-rtl8366-smi-driver.patch @@ -0,0 +1,21 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -146,4 +146,8 @@ config MDIO_GPIO + To compile this driver as a module, choose M here: the module + will be called mdio-gpio. + ++config RTL8366_SMI ++ tristate "Support for RTL8366 switch via SMI interface" ++ depends on GENERIC_GPIO ++ + endif # PHYLIB +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -20,6 +20,7 @@ obj-$(CONFIG_IP175C_PHY) += ip175c.o + obj-$(CONFIG_REALTEK_PHY) += realtek.o + obj-$(CONFIG_AR8216_PHY) += ar8216.o + obj-$(CONFIG_RTL8306_PHY) += rtl8306.o ++obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o + obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o + obj-$(CONFIG_MICREL) += micrel.o + obj-$(CONFIG_FIXED_PHY) += fixed.o -- 2.30.2