root/drivers/net/phy/dp83848.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dp83848_ack_interrupt
  2. dp83848_config_intr
  3. dp83848_config_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Driver for the Texas Instruments DP83848 PHY
   4  *
   5  * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/phy.h>
  10 
  11 #define TI_DP83848C_PHY_ID              0x20005ca0
  12 #define TI_DP83620_PHY_ID               0x20005ce0
  13 #define NS_DP83848C_PHY_ID              0x20005c90
  14 #define TLK10X_PHY_ID                   0x2000a210
  15 
  16 /* Registers */
  17 #define DP83848_MICR                    0x11 /* MII Interrupt Control Register */
  18 #define DP83848_MISR                    0x12 /* MII Interrupt Status Register */
  19 
  20 /* MICR Register Fields */
  21 #define DP83848_MICR_INT_OE             BIT(0) /* Interrupt Output Enable */
  22 #define DP83848_MICR_INTEN              BIT(1) /* Interrupt Enable */
  23 
  24 /* MISR Register Fields */
  25 #define DP83848_MISR_RHF_INT_EN         BIT(0) /* Receive Error Counter */
  26 #define DP83848_MISR_FHF_INT_EN         BIT(1) /* False Carrier Counter */
  27 #define DP83848_MISR_ANC_INT_EN         BIT(2) /* Auto-negotiation complete */
  28 #define DP83848_MISR_DUP_INT_EN         BIT(3) /* Duplex Status */
  29 #define DP83848_MISR_SPD_INT_EN         BIT(4) /* Speed status */
  30 #define DP83848_MISR_LINK_INT_EN        BIT(5) /* Link status */
  31 #define DP83848_MISR_ED_INT_EN          BIT(6) /* Energy detect */
  32 #define DP83848_MISR_LQM_INT_EN         BIT(7) /* Link Quality Monitor */
  33 
  34 #define DP83848_INT_EN_MASK             \
  35         (DP83848_MISR_ANC_INT_EN |      \
  36          DP83848_MISR_DUP_INT_EN |      \
  37          DP83848_MISR_SPD_INT_EN |      \
  38          DP83848_MISR_LINK_INT_EN)
  39 
  40 static int dp83848_ack_interrupt(struct phy_device *phydev)
  41 {
  42         int err = phy_read(phydev, DP83848_MISR);
  43 
  44         return err < 0 ? err : 0;
  45 }
  46 
  47 static int dp83848_config_intr(struct phy_device *phydev)
  48 {
  49         int control, ret;
  50 
  51         control = phy_read(phydev, DP83848_MICR);
  52         if (control < 0)
  53                 return control;
  54 
  55         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
  56                 control |= DP83848_MICR_INT_OE;
  57                 control |= DP83848_MICR_INTEN;
  58 
  59                 ret = phy_write(phydev, DP83848_MISR, DP83848_INT_EN_MASK);
  60                 if (ret < 0)
  61                         return ret;
  62         } else {
  63                 control &= ~DP83848_MICR_INTEN;
  64         }
  65 
  66         return phy_write(phydev, DP83848_MICR, control);
  67 }
  68 
  69 static int dp83848_config_init(struct phy_device *phydev)
  70 {
  71         int val;
  72 
  73         /* DP83620 always reports Auto Negotiation Ability on BMSR. Instead,
  74          * we check initial value of BMCR Auto negotiation enable bit
  75          */
  76         val = phy_read(phydev, MII_BMCR);
  77         if (!(val & BMCR_ANENABLE))
  78                 phydev->autoneg = AUTONEG_DISABLE;
  79 
  80         return 0;
  81 }
  82 
  83 static struct mdio_device_id __maybe_unused dp83848_tbl[] = {
  84         { TI_DP83848C_PHY_ID, 0xfffffff0 },
  85         { NS_DP83848C_PHY_ID, 0xfffffff0 },
  86         { TI_DP83620_PHY_ID, 0xfffffff0 },
  87         { TLK10X_PHY_ID, 0xfffffff0 },
  88         { }
  89 };
  90 MODULE_DEVICE_TABLE(mdio, dp83848_tbl);
  91 
  92 #define DP83848_PHY_DRIVER(_id, _name, _config_init)            \
  93         {                                                       \
  94                 .phy_id         = _id,                          \
  95                 .phy_id_mask    = 0xfffffff0,                   \
  96                 .name           = _name,                        \
  97                 /* PHY_BASIC_FEATURES */                        \
  98                                                                 \
  99                 .soft_reset     = genphy_soft_reset,            \
 100                 .config_init    = _config_init,                 \
 101                 .suspend        = genphy_suspend,               \
 102                 .resume         = genphy_resume,                \
 103                                                                 \
 104                 /* IRQ related */                               \
 105                 .ack_interrupt  = dp83848_ack_interrupt,        \
 106                 .config_intr    = dp83848_config_intr,          \
 107         }
 108 
 109 static struct phy_driver dp83848_driver[] = {
 110         DP83848_PHY_DRIVER(TI_DP83848C_PHY_ID, "TI DP83848C 10/100 Mbps PHY",
 111                            NULL),
 112         DP83848_PHY_DRIVER(NS_DP83848C_PHY_ID, "NS DP83848C 10/100 Mbps PHY",
 113                            NULL),
 114         DP83848_PHY_DRIVER(TI_DP83620_PHY_ID, "TI DP83620 10/100 Mbps PHY",
 115                            dp83848_config_init),
 116         DP83848_PHY_DRIVER(TLK10X_PHY_ID, "TI TLK10X 10/100 Mbps PHY",
 117                            NULL),
 118 };
 119 module_phy_driver(dp83848_driver);
 120 
 121 MODULE_DESCRIPTION("Texas Instruments DP83848 PHY driver");
 122 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
 123 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */