1 /* 2 * DWMAC glue for NXP LPC18xx/LPC43xx Ethernet 3 * 4 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> 5 * 6 * This file is licensed under the terms of the GNU General Public 7 * License version 2. This program is licensed "as is" without any 8 * warranty of any kind, whether express or implied. 9 */ 10 11 #include <linux/mfd/syscon.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/of_net.h> 15 #include <linux/phy.h> 16 #include <linux/platform_device.h> 17 #include <linux/regmap.h> 18 #include <linux/stmmac.h> 19 20 #include "stmmac_platform.h" 21 22 /* Register defines for CREG syscon */ 23 #define LPC18XX_CREG_CREG6 0x12c 24 # define LPC18XX_CREG_CREG6_ETHMODE_MASK 0x7 25 # define LPC18XX_CREG_CREG6_ETHMODE_MII 0x0 26 # define LPC18XX_CREG_CREG6_ETHMODE_RMII 0x4 27 28 struct lpc18xx_dwmac_priv_data { 29 struct regmap *reg; 30 int interface; 31 }; 32 33 static void *lpc18xx_dwmac_setup(struct platform_device *pdev) 34 { 35 struct lpc18xx_dwmac_priv_data *dwmac; 36 37 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); 38 if (!dwmac) 39 return ERR_PTR(-ENOMEM); 40 41 dwmac->interface = of_get_phy_mode(pdev->dev.of_node); 42 if (dwmac->interface < 0) 43 return ERR_PTR(dwmac->interface); 44 45 dwmac->reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg"); 46 if (IS_ERR(dwmac->reg)) { 47 dev_err(&pdev->dev, "Syscon lookup failed\n"); 48 return dwmac->reg; 49 } 50 51 return dwmac; 52 } 53 54 static int lpc18xx_dwmac_init(struct platform_device *pdev, void *priv) 55 { 56 struct lpc18xx_dwmac_priv_data *dwmac = priv; 57 u8 ethmode; 58 59 if (dwmac->interface == PHY_INTERFACE_MODE_MII) { 60 ethmode = LPC18XX_CREG_CREG6_ETHMODE_MII; 61 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) { 62 ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII; 63 } else { 64 dev_err(&pdev->dev, "Only MII and RMII mode supported\n"); 65 return -EINVAL; 66 } 67 68 regmap_update_bits(dwmac->reg, LPC18XX_CREG_CREG6, 69 LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode); 70 71 return 0; 72 } 73 74 static const struct stmmac_of_data lpc18xx_dwmac_data = { 75 .has_gmac = 1, 76 .setup = lpc18xx_dwmac_setup, 77 .init = lpc18xx_dwmac_init, 78 }; 79 80 static const struct of_device_id lpc18xx_dwmac_match[] = { 81 { .compatible = "nxp,lpc1850-dwmac", .data = &lpc18xx_dwmac_data }, 82 { } 83 }; 84 MODULE_DEVICE_TABLE(of, lpc18xx_dwmac_match); 85 86 static struct platform_driver lpc18xx_dwmac_driver = { 87 .probe = stmmac_pltfr_probe, 88 .remove = stmmac_pltfr_remove, 89 .driver = { 90 .name = "lpc18xx-dwmac", 91 .pm = &stmmac_pltfr_pm_ops, 92 .of_match_table = lpc18xx_dwmac_match, 93 }, 94 }; 95 module_platform_driver(lpc18xx_dwmac_driver); 96 97 MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>"); 98 MODULE_DESCRIPTION("DWMAC glue for LPC18xx/43xx Ethernet"); 99 MODULE_LICENSE("GPL v2"); 100