+static void __init ar71xx_mii_ctrl_set_if(unsigned int reg,
+ unsigned int mii_if)
+{
+ void __iomem *base;
+ u32 t;
+
+ base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE);
+
+ t = __raw_readl(base + reg);
+ t &= ~(MII_CTRL_IF_MASK);
+ t |= (mii_if & MII_CTRL_IF_MASK);
+ __raw_writel(t, base + reg);
+
+ iounmap(base);
+}
+
+static void ar71xx_mii_ctrl_set_speed(unsigned int reg, unsigned int speed)
+{
+ void __iomem *base;
+ unsigned int mii_speed;
+ u32 t;
+
+ switch (speed) {
+ case SPEED_10:
+ mii_speed = MII_CTRL_SPEED_10;
+ break;
+ case SPEED_100:
+ mii_speed = MII_CTRL_SPEED_100;
+ break;
+ case SPEED_1000:
+ mii_speed = MII_CTRL_SPEED_1000;
+ break;
+ default:
+ BUG();
+ }
+
+ base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE);
+
+ t = __raw_readl(base + reg);
+ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
+ t |= mii_speed << MII_CTRL_SPEED_SHIFT;
+ __raw_writel(t, base + reg);
+
+ iounmap(base);
+}
+
+void __init ar71xx_add_device_mdio(unsigned int id, u32 phy_mask)
+{
+ struct platform_device *mdio_dev;
+ struct ag71xx_mdio_platform_data *mdio_data;
+ unsigned int max_id;
+
+ if (ar71xx_soc == AR71XX_SOC_AR9341 ||
+ ar71xx_soc == AR71XX_SOC_AR9342 ||
+ ar71xx_soc == AR71XX_SOC_AR9344)
+ max_id = 1;
+ else
+ max_id = 0;
+
+ if (id > max_id) {
+ printk(KERN_ERR "ar71xx: invalid MDIO id %u\n", id);
+ return;
+ }
+
+ switch (ar71xx_soc) {
+ case AR71XX_SOC_AR7241:
+ case AR71XX_SOC_AR9330:
+ case AR71XX_SOC_AR9331:
+ mdio_dev = &ar71xx_mdio1_device;
+ mdio_data = &ar71xx_mdio1_data;
+ break;
+
+ case AR71XX_SOC_AR9341:
+ case AR71XX_SOC_AR9342:
+ case AR71XX_SOC_AR9344:
+ if (id == 0) {
+ mdio_dev = &ar71xx_mdio0_device;
+ mdio_data = &ar71xx_mdio0_data;
+ } else {
+ mdio_dev = &ar71xx_mdio1_device;
+ mdio_data = &ar71xx_mdio1_data;
+ }
+ break;
+
+ case AR71XX_SOC_AR7242:
+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG,
+ AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000,
+ AR71XX_ETH0_PLL_SHIFT);
+ /* fall through */
+ default:
+ mdio_dev = &ar71xx_mdio0_device;
+ mdio_data = &ar71xx_mdio0_data;
+ break;
+ }
+
+ mdio_data->phy_mask = phy_mask;
+
+ switch (ar71xx_soc) {
+ case AR71XX_SOC_AR7240:
+ case AR71XX_SOC_AR7241:
+ case AR71XX_SOC_AR9330:
+ case AR71XX_SOC_AR9331:
+ mdio_data->is_ar7240 = 1;
+ break;
+
+ case AR71XX_SOC_AR9341:
+ case AR71XX_SOC_AR9342:
+ case AR71XX_SOC_AR9344:
+ if (id == 1)
+ mdio_data->is_ar7240 = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ platform_device_register(mdio_dev);
+}
+