]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/phy/dp83848.c
net: phy: dp83848: Add macro for dp83848 compatible devices
[karo-tx-linux.git] / drivers / net / phy / dp83848.c
1 /*
2  * Driver for the Texas Instruments DP83848 PHY
3  *
4  * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 #include <linux/module.h>
17 #include <linux/phy.h>
18
19 #define DP83848_PHY_ID                  0x20005c90
20
21 /* Registers */
22 #define DP83848_MICR                    0x11
23 #define DP83848_MISR                    0x12
24
25 /* MICR Register Fields */
26 #define DP83848_MICR_INT_OE             BIT(0) /* Interrupt Output Enable */
27 #define DP83848_MICR_INTEN              BIT(1) /* Interrupt Enable */
28
29 /* MISR Register Fields */
30 #define DP83848_MISR_RHF_INT_EN         BIT(0) /* Receive Error Counter */
31 #define DP83848_MISR_FHF_INT_EN         BIT(1) /* False Carrier Counter */
32 #define DP83848_MISR_ANC_INT_EN         BIT(2) /* Auto-negotiation complete */
33 #define DP83848_MISR_DUP_INT_EN         BIT(3) /* Duplex Status */
34 #define DP83848_MISR_SPD_INT_EN         BIT(4) /* Speed status */
35 #define DP83848_MISR_LINK_INT_EN        BIT(5) /* Link status */
36 #define DP83848_MISR_ED_INT_EN          BIT(6) /* Energy detect */
37 #define DP83848_MISR_LQM_INT_EN         BIT(7) /* Link Quality Monitor */
38
39 static int dp83848_ack_interrupt(struct phy_device *phydev)
40 {
41         int err = phy_read(phydev, DP83848_MISR);
42
43         return err < 0 ? err : 0;
44 }
45
46 static int dp83848_config_intr(struct phy_device *phydev)
47 {
48         int err;
49
50         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
51                 err = phy_write(phydev, DP83848_MICR,
52                                 DP83848_MICR_INT_OE |
53                                 DP83848_MICR_INTEN);
54                 if (err < 0)
55                         return err;
56
57                 return phy_write(phydev, DP83848_MISR,
58                                  DP83848_MISR_ANC_INT_EN |
59                                  DP83848_MISR_DUP_INT_EN |
60                                  DP83848_MISR_SPD_INT_EN |
61                                  DP83848_MISR_LINK_INT_EN);
62         }
63
64         return phy_write(phydev, DP83848_MICR, 0x0);
65 }
66
67 static struct mdio_device_id __maybe_unused dp83848_tbl[] = {
68         { DP83848_PHY_ID, 0xfffffff0 },
69         { }
70 };
71 MODULE_DEVICE_TABLE(mdio, dp83848_tbl);
72
73 #define DP83848_PHY_DRIVER(_id, _name)                          \
74         {                                                       \
75                 .phy_id         = _id,                          \
76                 .phy_id_mask    = 0xfffffff0,                   \
77                 .name           = _name,                        \
78                 .features       = PHY_BASIC_FEATURES,           \
79                 .flags          = PHY_HAS_INTERRUPT,            \
80                                                                 \
81                 .soft_reset     = genphy_soft_reset,            \
82                 .config_init    = genphy_config_init,           \
83                 .suspend        = genphy_suspend,               \
84                 .resume         = genphy_resume,                \
85                 .config_aneg    = genphy_config_aneg,           \
86                 .read_status    = genphy_read_status,           \
87                                                                 \
88                 /* IRQ related */                               \
89                 .ack_interrupt  = dp83848_ack_interrupt,        \
90                 .config_intr    = dp83848_config_intr,          \
91         }
92
93 static struct phy_driver dp83848_driver[] = {
94         DP83848_PHY_DRIVER(DP83848_PHY_ID, "TI DP83848 10/100 Mbps PHY"),
95 };
96 module_phy_driver(dp83848_driver);
97
98 MODULE_DESCRIPTION("Texas Instruments DP83848 PHY driver");
99 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com");
100 MODULE_LICENSE("GPL");