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

bcm59101.c (5534B)


      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  * BCM56xx I2C Device Driver for BCM59101 8-bit PoE Microcontroller Unit.
      8  * The MCU communicates with message types of 12-byte long packet.
      9  */
     10 
     11 #include <sal/types.h>
     12 #include <soc/debug.h>
     13 #include <soc/drv.h>
     14 #include <soc/error.h>
     15 #include <soc/i2c.h>
     16 #include <shared/bsl.h>
     17 #define BCM59101_CTN     12
     18 
     19 STATIC int
     20 bcm59101_read(int unit, int devno,
     21              uint16 addr, uint8* data, uint32* len)
     22 {
     23     int rv = SOC_E_NONE;
     24     uint8 saddr_r;
     25     uint32 nbytes = 0;
     26 
     27 
     28     /* Valid address, memory and size must be provided */
     29     if ( ! len || ! data )
     30         return SOC_E_PARAM;
     31 
     32     LOG_INFO(BSL_LS_SOC_I2C,
     33              (BSL_META_U(unit,
     34                          "bcm59101_read: unit: %d devno: %d addr: %d data: %p len: %u\n"),
     35               unit, devno, addr, (void *)data, *len));
     36 
     37     I2C_LOCK(unit);
     38 
     39     saddr_r = SOC_I2C_RX_ADDR(soc_i2c_addr(unit, devno));
     40 
     41     LOG_INFO(BSL_LS_SOC_I2C,
     42              (BSL_META_U(unit,
     43                          "bcm59101_read: devno=0x%x (data=%p) len=%d\n"),
     44               devno, (void *)data, (int)*len));
     45 
     46     /* Now, we have sent the first and second word addresses,
     47      * we then issue a repeated start condition, followed by
     48      * the device's read address (note: saddr_r)
     49      */
     50     /* Generate Start, for Write address */
     51     if( (rv = soc_i2c_start(unit, saddr_r)) < 0){
     52       LOG_INFO(BSL_LS_SOC_I2C,
     53                (BSL_META_U(unit,
     54                            "bcm59101_write(%d,%d,0x%x,%p,%d): "
     55                            "failed to gen start\n"),
     56                 unit, devno, addr, (void *)data, *len));
     57       goto error;
     58     }
     59 
     60     nbytes = *len;
     61     if ( (rv = soc_i2c_read_bytes(unit, data, (int *)&nbytes, 0) ) < 0 ) {
     62         goto error;
     63     }
     64     *len = nbytes;
     65 
     66  error:
     67 
     68     soc_i2c_stop(unit);
     69 
     70     I2C_UNLOCK(unit);
     71     return rv ;
     72 
     73 }
     74 
     75 STATIC int
     76 bcm59101_write(int unit, int devno,
     77               uint16 addr, uint8* data, uint32 len)
     78 {
     79     int rv = SOC_E_NONE;
     80     uint8 saddr = soc_i2c_addr(unit, devno);
     81     uint8 *ptr;
     82     uint32 i;
     83 
     84     LOG_INFO(BSL_LS_SOC_I2C,
     85              (BSL_META_U(unit,
     86                          "bcm59101_write: unit: %d devno: %d addr: %d data: %p len: %d\n"),
     87               unit, devno, addr, (void *)data, len));
     88 
     89     if (!data) {
     90         return SOC_E_PARAM;
     91     }
     92 
     93     I2C_LOCK(unit);
     94 
     95     if ((rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr))) < 0) {
     96         LOG_INFO(BSL_LS_SOC_I2C,
     97                  (BSL_META_U(unit,
     98                              "i2c%d: soc_i2c_bcm59101_write: "
     99                              "failed to generate start.\n"),
    100                   unit));
    101         I2C_UNLOCK(unit);
    102         return rv;
    103     }
    104 
    105     ptr = data;
    106     for (i = 0; i < len; i++, ptr++) {
    107         if ((rv = soc_i2c_write_one_byte(unit, *ptr) ) < 0 ) {
    108             LOG_INFO(BSL_LS_SOC_I2C,
    109                      (BSL_META_U(unit,
    110                                  "i2c%d: soc_i2c_bcm59101_write: "
    111                                  "failed to send byte %d.\n"),
    112                       unit, i ));
    113             break;
    114         }
    115         soc_i2c_device(unit, devno)->tbyte++;
    116     }
    117 
    118     soc_i2c_stop(unit);
    119     I2C_UNLOCK(unit);
    120 
    121     return rv;
    122 }
    123 
    124 
    125 
    126 STATIC int
    127 bcm59101_ioctl(int unit, int devno,
    128               int opcode, void* data, int len)
    129 {
    130     return SOC_E_NONE;
    131 }
    132 
    133 STATIC int
    134 bcm59101_init(int unit, int devno,
    135              void* data, int len)
    136 {
    137     uint8 pkt[BCM59101_CTN];
    138     uint32 l = 2;
    139     soc_timeout_t to;
    140     int rv = SOC_E_NONE;
    141 
    142     LOG_INFO(BSL_LS_SOC_I2C,
    143              (BSL_META_U(unit,
    144                          "bcm59101_init: unit: %d devno: %d data: %p len: %d\n"),
    145               unit, devno, data, len)); 
    146     /*
    147     Request :
    148     0x20 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x18
    149 
    150     Response:
    151     0x20 0x01   Rest dont care ..
    152     0xAF   Rest dont care ..
    153      */
    154 
    155     soc_i2c_devdesc_set(unit, devno, "BCM59101 POE controller");
    156 
    157     if ((rv = bcm59101_write(unit, devno, 0, data, len)) < 0) {
    158                             
    159         LOG_INFO(BSL_LS_SOC_I2C,
    160                  (BSL_META_U(unit,
    161                              "i2c%d: soc_i2c_bcm59101_init: "
    162                              "failed to send power init packet.\n"), unit));
    163         return rv;
    164     }
    165 
    166     soc_timeout_init(&to, 100000, 0);
    167     for (;;) {
    168          if (soc_timeout_check(&to)) {
    169              break;
    170          }
    171     }
    172 
    173     l = BCM59101_CTN;
    174     if ((rv = bcm59101_read(unit, devno, 0, pkt, &l)) < 0) {
    175         LOG_INFO(BSL_LS_SOC_I2C,
    176                  (BSL_META_U(unit,
    177                              "i2c%d: soc_i2c_bcm59101_init: "
    178                              "failed to read power init packet.\n"), unit));
    179         return rv;
    180     }
    181 
    182     LOG_INFO(BSL_LS_SOC_I2C,
    183              (BSL_META_U(unit,
    184                          "bcm59101_init: Signature read %x %x\n"), *pkt, *(pkt+1)));
    185 
    186     if ((*pkt != 0x20 || *(pkt+1) != 0x01) && *pkt != 0xaf) {
    187 
    188         LOG_INFO(BSL_LS_SOC_I2C,
    189                  (BSL_META_U(unit,
    190                              "i2c%d: soc_i2c_bcm59101_init: "
    191                              "bcm5910 not found.\n"), unit));
    192 
    193         return SOC_E_UNAVAIL;
    194     }
    195 
    196     return rv;
    197 }
    198 
    199 
    200 /* BCM59101 Chip Driver callout */
    201 i2c_driver_t _soc_i2c_bcm59101_driver = {
    202     0x0, 0x0, /* System assigned bytes */
    203     BCM59101_DEVICE_TYPE,
    204     bcm59101_read,
    205     bcm59101_write,
    206     bcm59101_ioctl,
    207     bcm59101_init,
    208     NULL,
    209 };