openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

phyi2c.c (3430B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:    phyi2c.c
      8  * Purpose: I2C bus read/write routines for SFP copper PHY devices 
      9  */
     10 
     11 #if defined(BCM_ESW_SUPPORT) && defined(INCLUDE_I2C)
     12 #include <sal/types.h>
     13 #include <soc/drv.h>
     14 #include <soc/phy.h>
     15 #include <soc/i2c.h>
     16 #include <soc/debug.h>
     17 
     18 #ifndef BCMSWAP16
     19 #define BCMSWAP16(val) \
     20         ((uint16)( \
     21                 (((uint16)(val) & (uint16)0x00ffU) << 8) | \
     22                 (((uint16)(val) & (uint16)0xff00U) >> 8) ))
     23 #endif
     24 
     25 /* customer specific phy bus read/write hook pointers */
     26 typedef struct {
     27     soc_phy_bus_rd_t rd;
     28     soc_phy_bus_wr_t wr;
     29 } soc_phy_bus_hook_t;
     30 
     31 STATIC soc_phy_bus_hook_t _soc_phy_bus_hook[SOC_MAX_NUM_DEVICES];
     32  
     33 
     34 /*
     35  * Function:
     36  *  phy_i2c_miireg_read
     37  * Purpose:
     38  *  Read a MII register of the given PHY device on the I2C bus. Typically it is
     39  *  a copper SFP PHY device.
     40  * Parameters:
     41  *  unit         - StrataSwitch unit #.
     42  *  phy_id       - the address on the I2C bus.
     43  *  phy_reg_addr - MII register address.
     44  *  phy_rd_data  - pointer to a 16bit storage to hold read data.
     45  * Returns:
     46  *  SOC_E_XXX
     47  */
     48 
     49 int
     50 phy_i2c_miireg_read (int unit,uint32 phy_id,uint32 phy_reg_addr,
     51                                              uint16 *phy_rd_data)
     52 {
     53     int rv = SOC_E_NONE;
     54 
     55     if (_soc_phy_bus_hook[unit].rd) {
     56         return (*_soc_phy_bus_hook[unit].rd)(unit,phy_id,phy_reg_addr,phy_rd_data);
     57     }
     58 
     59     /* Make sure that we're already attached, or go get attached */
     60     if (!soc_i2c_is_attached(unit)) {
     61         if ((rv = soc_i2c_attach(unit, 0, 0)) <= 0) {
     62             return rv;
     63         }
     64     }
     65     rv = soc_i2c_read_word_data(unit,phy_id,phy_reg_addr,phy_rd_data);
     66 
     67     if (rv == SOC_E_NONE) {
     68         *phy_rd_data = BCMSWAP16(*phy_rd_data);
     69     }
     70     return rv;
     71 }
     72 
     73 /*
     74  * Function:
     75  *  phy_i2c_miireg_write
     76  * Purpose:
     77  *  Write to a MII register of the given PHY device on the I2C bus. Typically it is
     78  *  a copper SFP PHY device.
     79  * Parameters:
     80  *  unit         - StrataSwitch unit #.
     81  *  phy_id       - the address on the I2C bus.
     82  *  phy_reg_addr - MII register address.
     83  *  phy_wr_data  - 16bit value to write to the MII register.
     84  * Returns:
     85  *  SOC_E_XXX
     86  */
     87 
     88 int 
     89 phy_i2c_miireg_write (int unit,uint32 phy_id,uint32 phy_reg_addr, 
     90                                                 uint16 phy_wr_data)
     91 {
     92     int rv = SOC_E_NONE;
     93 
     94     if (_soc_phy_bus_hook[unit].wr) {
     95         return (*_soc_phy_bus_hook[unit].wr)(unit,phy_id,phy_reg_addr,phy_wr_data);
     96     }
     97 
     98     /* Make sure that we're already attached, or go get attached */
     99     if (!soc_i2c_is_attached(unit)) {
    100         if ((rv = soc_i2c_attach(unit, 0, 0)) <= 0) {
    101             return rv;
    102         }
    103     }
    104 
    105     rv = soc_i2c_write_word_data(unit,phy_id,phy_reg_addr,BCMSWAP16(phy_wr_data));
    106     return rv;
    107 }
    108 
    109 /*
    110  * Function:
    111  *  phy_i2c_bus_func_hook_set
    112  * Purpose:
    113  *  Install customer specific I2C bus read/write routines 
    114  *  
    115  * Parameters:
    116  *  unit - StrataSwitch unit #.
    117  *  rd   - I2C bus read routine.
    118  *  wr   - I2C bus write routine.
    119  * Returns:
    120  *  SOC_E_XXX
    121  */
    122 
    123 int phy_i2c_bus_func_hook_set (int unit, soc_phy_bus_rd_t rd, soc_phy_bus_wr_t wr)
    124 {
    125     _soc_phy_bus_hook[unit].rd = rd;
    126     _soc_phy_bus_hook[unit].wr = wr;
    127     return SOC_E_NONE;
    128 }
    129 #else
    130 int _soc_phy_phyi2c_not_empty;
    131 #endif