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

smbus.c (70497B)


      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  * SMB driver interface for I2C controller operating in master mode
      8  * onboard the CMIC.
      9  * Some devices use the SMBus (System Management Bus) protocol, which
     10  * is a subset of commands from the I2C protocol. Fortunately, many
     11  * devices use the same subset, which makes it possible to derive
     12  * the following SMBus operations/commands.
     13  *
     14  * This module provides for SMB r/w byte and word commands based on
     15  * top of the bus driver module. Note that locking is performed in
     16  * this module, such that all drivers which use SMB commands are
     17  * automatically MT-safe.
     18  *
     19  * When possible, try to use the SMB commands for developing your I2C
     20  * device driver, as this will simplify debugging and development.
     21  *
     22  * Below is a list of SMBus commands, all of the commands are based
     23  * on I2C protocol concepts.
     24  *
     25  * Key to symbols
     26  * ==============
     27  *
     28  * S     (1 bit) : Start bit
     29  * P     (1 bit) : Stop bit
     30  * Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
     31  * A, NA (1 bit) : ACK and Not ACK (NACK)  bit.
     32  * Addr  (7 bits): I2C 7 bit address. Note that this can be expanded
     33  *                 as usual to get a 10 bit I2C address.
     34  * Comm  (8 bits): Command byte, a data byte which often selects
     35  *                 a register or function on  the device.
     36  * Data  (8 bits): A plain data byte. Sometimes, I write DataLow,
     37  *                 DataHigh for 16 bit data.
     38  * Count (8 bits): A data byte containing the length of a block
     39  *                 operation.
     40  *
     41  * [..]: Data sent by I2C device, as opposed to data sent by the
     42  *       host adapter.
     43  *
     44  * See also: bus.c
     45  */
     46 #include <shared/bsl.h>
     47 
     48 #include <sal/types.h>
     49 #include <soc/error.h>
     50 #include <soc/debug.h>
     51 #include <soc/drv.h>
     52 #include <soc/i2c.h>
     53 #include <shared/bsl.h>
     54 #include <soc/iproc.h>
     55 #ifdef BCM_CMICM_SUPPORT
     56 #include <soc/cmicm.h>
     57 #endif
     58 
     59 #define I2C_MORE_TO_READ TRUE
     60 #define I2C_FINAL_READ   FALSE
     61 
     62 #ifdef BCM_CMICM_SUPPORT
     63 
     64 
     65 #define READ_IPROCPERIPH_SMBUS_REG(regName, unit, val)       \
     66     if (soc_feature(unit, soc_feature_use_smbus2_for_i2c)) { \
     67         READ_IPROCPERIPH_SMBUS2_SMBUS_##regName(unit, val);  \
     68     }                                                        \
     69     else {                                                   \
     70         READ_IPROCPERIPH_SMBUS1_SMBUS_##regName(unit, val);  \
     71     }                                                        \
     72 
     73 #define WRITE_IPROCPERIPH_SMBUS_REG(regName, unit, val)      \
     74     if (soc_feature(unit, soc_feature_use_smbus2_for_i2c)) { \
     75         WRITE_IPROCPERIPH_SMBUS2_SMBUS_##regName(unit, val); \
     76     }                                                        \
     77     else {                                                   \
     78         WRITE_IPROCPERIPH_SMBUS1_SMBUS_##regName(unit, val); \
     79     }                                                        \
     80 
     81 int
     82 smbus_timeout_recovery(int unit)
     83 {
     84     uint32 rval;
     85     int clk;
     86     int i, rv = 0;
     87 
     88     READ_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
     89     if (soc_reg_field_get(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, rval, SMBDAT_INf) == 0) {
     90         READ_CMIC_I2CM_SMBUS_CONFIGr(unit, &rval);
     91         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_CONFIGr, &rval, BIT_BANG_ENf, 1);
     92         WRITE_CMIC_I2CM_SMBUS_CONFIGr(unit, rval);
     93 
     94         sal_usleep(60);
     95 
     96         READ_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
     97         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
     98         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 1);
     99         WRITE_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    100         clk = 1;
    101 
    102         for (i = 0; i < 18; i++) {
    103             if (clk == 0) {
    104                 soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    105                 clk = 1;
    106             } else {
    107                 soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 0);
    108                 clk = 0;
    109             }
    110 
    111             WRITE_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    112             sal_usleep(5);
    113         }
    114 
    115         READ_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
    116         if (soc_reg_field_get(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, rval, SMBDAT_INf) == 0) {
    117             LOG_INFO(BSL_LS_SOC_I2C,
    118                      (BSL_META_U(unit,
    119                                  "i2c%d: smbus_timeout_recovery: SDA is still low.\n"), unit));
    120             rv = SOC_E_TIMEOUT;
    121         }
    122 
    123         READ_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
    124         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 0);
    125         WRITE_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    126         sal_usleep(2);
    127         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 0);
    128         WRITE_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    129         sal_usleep(2);
    130         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    131         WRITE_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    132         sal_usleep(2);
    133         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 1);
    134         WRITE_CMIC_I2CM_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    135         sal_usleep(2);
    136 
    137         READ_CMIC_I2CM_SMBUS_CONFIGr(unit, &rval);
    138         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_CONFIGr, &rval, BIT_BANG_ENf, 0);
    139         WRITE_CMIC_I2CM_SMBUS_CONFIGr(unit, rval);
    140 
    141         sal_usleep(60);
    142     }
    143 
    144     READ_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit, &rval);
    145     if (soc_reg_field_get(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, rval, MASTER_START_BUSY_COMMANDf) != 0 ||
    146         soc_reg_field_get(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, rval, MASTER_STATUSf) != 0) {
    147         READ_CMIC_I2CM_SMBUS_CONFIGr(unit, &rval);
    148         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_CONFIGr, &rval, RESETf, 1);
    149         WRITE_CMIC_I2CM_SMBUS_CONFIGr(unit, rval);
    150 
    151         sal_usleep(60);
    152 
    153         READ_CMIC_I2CM_SMBUS_MASTER_FIFO_CONTROLr(unit, &rval);
    154         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_FIFO_CONTROLr, &rval, MASTER_TX_FIFO_FLUSHf, 1);
    155         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_FIFO_CONTROLr, &rval, MASTER_RX_FIFO_FLUSHf, 1);
    156         WRITE_CMIC_I2CM_SMBUS_MASTER_FIFO_CONTROLr(unit, rval);
    157 
    158         READ_CMIC_I2CM_SMBUS_CONFIGr(unit, &rval);
    159         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_CONFIGr, &rval, SMB_ENf, 1);
    160         WRITE_CMIC_I2CM_SMBUS_CONFIGr(unit, rval);
    161 
    162         sal_usleep(60);
    163     }
    164 
    165     return rv;
    166 }
    167 
    168 /* Returns OK or TIMEOUT. Calling routine has to check for ACK/NAK?Error */
    169 int
    170 smbus_start_wait(int unit)
    171 {
    172     int rv = SOC_E_TIMEOUT;
    173     soc_timeout_t to;
    174     uint32 rval, status;
    175 
    176     /* Start Transaction */
    177     READ_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit, &rval);
    178     soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, MASTER_START_BUSY_COMMANDf, 1);
    179     WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
    180 
    181     soc_timeout_init(&to, 10000, 1000);
    182 
    183     do {
    184         READ_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit, &rval);
    185         if (soc_reg_field_get(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr,rval, MASTER_START_BUSY_COMMANDf) == 0) {
    186             rv = SOC_E_NONE;
    187             break;
    188         }
    189     } while(!(soc_timeout_check(&to)));
    190 
    191     READ_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit, &rval);
    192     status = soc_reg_field_get(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr,rval, MASTER_STATUSf);
    193 
    194     if ((rv == 0) && (status == 0)) {
    195         rv = SOC_E_NONE;
    196     } else {
    197         smbus_timeout_recovery(unit);
    198         rv = SOC_E_TIMEOUT;
    199     }
    200     return rv;
    201 }
    202 
    203 int
    204 smbus_quick_command(int unit, uint8 saddr)
    205 {
    206     int rv = SOC_E_NONE;
    207     uint32 rval;
    208     int rt = 5;
    209 
    210     LOG_INFO(BSL_LS_SOC_I2C,
    211              (BSL_META_U(unit,
    212                          "i2c%d: smbus_quick_command @ %02x\n"),
    213               unit, saddr));
    214 
    215     I2C_LOCK(unit);
    216 
    217 retry:
    218     rval = SOC_I2C_TX_ADDR(saddr);
    219     soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    220     WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    221 
    222     rval = 0;
    223     soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_QUICK_CMD);
    224     WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
    225 
    226     rv = smbus_start_wait(unit);
    227     if (rv != SOC_E_NONE && rt-- > 0) {
    228         goto retry;
    229     } else if (rt < 0) {
    230         rv = SOC_E_TIMEOUT;
    231     }
    232 
    233     I2C_UNLOCK(unit);
    234     return rv;
    235 }
    236 
    237 #endif
    238 
    239 #ifdef BCM_CMICX_SUPPORT
    240 
    241 int
    242 cmicx_smbus_timeout_recovery(int unit)
    243 {
    244     uint32 rval;
    245     int clk;
    246     int i, rv = 0;
    247 
    248     READ_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, &rval);
    249     if (soc_reg_field_get(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, rval, SMBDAT_INf) == 0) {
    250         READ_IPROCPERIPH_SMBUS_REG(CONFIGr, unit,  &rval);
    251         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_CONFIGr, &rval, BIT_BANG_ENf, 1);
    252         WRITE_IPROCPERIPH_SMBUS_REG(CONFIGr, unit, rval);
    253 
    254         sal_usleep(60);
    255 
    256         READ_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, &rval);
    257         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    258         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 1);
    259         WRITE_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, rval);
    260         clk = 1;
    261 
    262         for (i = 0; i < 18; i++) {
    263             if (clk == 0) {
    264                 soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    265                 clk = 1;
    266             } else {
    267                 soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 0);
    268                 clk = 0;
    269             }
    270 
    271             WRITE_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, rval);
    272             sal_usleep(5);
    273         }
    274 
    275         READ_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, &rval);
    276         if (soc_reg_field_get(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, rval, SMBDAT_INf) == 0) {
    277             LOG_INFO(BSL_LS_SOC_I2C,
    278                      (BSL_META_U(unit,
    279                                  "i2c%d: smbus_timeout_recovery: SDA is still low.\n"), unit));
    280             rv = SOC_E_TIMEOUT;
    281         }
    282 
    283         READ_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, &rval);
    284         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 0);
    285         WRITE_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, rval);
    286         sal_usleep(2);
    287         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 0);
    288         WRITE_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, rval);
    289         sal_usleep(2);
    290         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    291         WRITE_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, rval);
    292         sal_usleep(2);
    293         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 1);
    294         WRITE_IPROCPERIPH_SMBUS_REG(BIT_BANG_CONTROLr, unit, rval);
    295         sal_usleep(2);
    296 
    297         READ_IPROCPERIPH_SMBUS_REG(CONFIGr, unit,  &rval);
    298         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_CONFIGr, &rval, BIT_BANG_ENf, 0);
    299         WRITE_IPROCPERIPH_SMBUS_REG(CONFIGr, unit, rval);
    300 
    301         sal_usleep(60);
    302     }
    303 
    304     READ_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit, &rval);
    305     if (soc_reg_field_get(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, rval, MASTER_START_BUSY_COMMANDf) != 0 ||
    306         soc_reg_field_get(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, rval, MASTER_STATUSf) != 0) {
    307         READ_IPROCPERIPH_SMBUS_REG(CONFIGr, unit,  &rval);
    308         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_CONFIGr, &rval, RESETf, 1);
    309         WRITE_IPROCPERIPH_SMBUS_REG(CONFIGr, unit, rval);
    310 
    311         sal_usleep(60);
    312 
    313         READ_IPROCPERIPH_SMBUS_REG(MASTER_FIFO_CONTROLr, unit, &rval);
    314         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_FIFO_CONTROLr, &rval, MASTER_TX_FIFO_FLUSHf, 1);
    315         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_FIFO_CONTROLr, &rval, MASTER_RX_FIFO_FLUSHf, 1);
    316         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_FIFO_CONTROLr, unit, rval);
    317 
    318         READ_IPROCPERIPH_SMBUS_REG(CONFIGr, unit,  &rval);
    319         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_CONFIGr, &rval, SMB_ENf, 1);
    320         WRITE_IPROCPERIPH_SMBUS_REG(CONFIGr, unit, rval);
    321 
    322         sal_usleep(60);
    323     }
    324 
    325     return rv;
    326 }
    327 
    328 /* Returns OK or TIMEOUT. Calling routine has to check for ACK/NAK?Error */
    329 int
    330 cmicx_smbus_start_wait(int unit)
    331 {
    332     int rv = SOC_E_TIMEOUT;
    333     soc_timeout_t to;
    334     uint32 rval, status;
    335 
    336     /* Start Transaction */
    337     READ_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit, &rval);
    338     soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, MASTER_START_BUSY_COMMANDf, 1);
    339     WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
    340 
    341     soc_timeout_init(&to, 10000, 1000);
    342 
    343     do {
    344         READ_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit, &rval);
    345         if (soc_reg_field_get(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr,rval, MASTER_START_BUSY_COMMANDf) == 0) {
    346             rv = SOC_E_NONE;
    347             break;
    348         }
    349     } while(!(soc_timeout_check(&to)));
    350 
    351     READ_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit, &rval);
    352     status = soc_reg_field_get(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr,rval, MASTER_STATUSf);
    353 
    354     if ((rv == 0) && (status == 0)) {
    355         rv = SOC_E_NONE;
    356     } else {
    357         cmicx_smbus_timeout_recovery(unit);
    358         rv = SOC_E_TIMEOUT;
    359     }
    360     return rv;
    361 }
    362 
    363 int
    364 cmicx_smbus_quick_command(int unit, uint8 saddr)
    365 {
    366     int rv = SOC_E_NONE;
    367     uint32 rval;
    368     int rt = 5;
    369 
    370     LOG_INFO(BSL_LS_SOC_I2C,
    371              (BSL_META_U(unit,
    372                          "i2c%d: smbus_quick_command @ %02x\n"),
    373               unit, saddr));
    374 
    375     I2C_LOCK(unit);
    376 
    377 retry:
    378     rval = SOC_I2C_TX_ADDR(saddr);
    379     soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    380     WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    381 
    382     rval = 0;
    383     soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_QUICK_CMD);
    384     WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
    385 
    386     rv = cmicx_smbus_start_wait(unit);
    387     if (rv != SOC_E_NONE && rt-- > 0) {
    388         goto retry;
    389     } else if (rt < 0) {
    390         rv = SOC_E_TIMEOUT;
    391     }
    392 
    393     I2C_UNLOCK(unit);
    394     return rv;
    395 }
    396 
    397 #endif
    398 
    399 #ifdef BCM_IPROC_SUPPORT
    400 
    401 int
    402 iproc_smbus_timeout_recovery(int unit)
    403 {
    404     uint32 rval;
    405     int clk;
    406     int i, rv = 0;
    407 
    408     READ_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
    409     if (soc_reg_field_get(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, rval, SMBDAT_INf) == 0) {
    410         READ_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, &rval);
    411         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr, &rval, BIT_BANG_ENf, 1);
    412         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, rval);
    413 
    414         sal_usleep(60);
    415 
    416         READ_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
    417         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    418         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 1);
    419         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    420         clk = 1;
    421 
    422         for (i = 0; i < 18; i++) {
    423             if (clk == 0) {
    424                 soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    425                 clk = 1;
    426             } else {
    427                 soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 0);
    428                 clk = 0;
    429             }
    430 
    431             WRITE_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    432             sal_usleep(5);
    433         }
    434 
    435         READ_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
    436         if (soc_reg_field_get(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, rval, SMBDAT_INf) == 0) {
    437             LOG_INFO(BSL_LS_SOC_I2C,
    438                      (BSL_META_U(unit,
    439                                  "i2c%d: smbus_timeout_recovery: SDA is still low.\n"), unit));
    440             rv = SOC_E_TIMEOUT;
    441         }
    442 
    443         READ_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, &rval);
    444         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 0);
    445         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    446         sal_usleep(2);
    447         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 0);
    448         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    449         sal_usleep(2);
    450         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBCLK_OUT_ENf, 1);
    451         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    452         sal_usleep(2);
    453         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr, &rval, SMBDAT_OUT_ENf, 1);
    454         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_BIT_BANG_CONTROLr(unit, rval);
    455         sal_usleep(2);
    456 
    457         READ_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, &rval);
    458         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr, &rval, BIT_BANG_ENf, 0);
    459         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, rval);
    460 
    461         sal_usleep(60);
    462     }
    463 
    464     READ_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr(unit, &rval);
    465     if (soc_reg_field_get(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr, rval, MASTER_START_BUSY_COMMANDf) != 0 ||
    466         soc_reg_field_get(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr, rval, MASTER_STATUSf) != 0) {
    467         READ_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, &rval);
    468         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr, &rval, RESETf, 1);
    469         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, rval);
    470 
    471         sal_usleep(60);
    472 
    473         READ_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_FIFO_CONTROLr(unit, &rval);
    474         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_FIFO_CONTROLr, &rval, MASTER_TX_FIFO_FLUSHf, 1);
    475         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_FIFO_CONTROLr, &rval, MASTER_RX_FIFO_FLUSHf, 1);
    476         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_FIFO_CONTROLr(unit, rval);
    477 
    478         READ_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, &rval);
    479         soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr, &rval, SMB_ENf, 1);
    480         WRITE_CHIPCOMMONG_SMBUS0_SMBUS_CONFIGr(unit, rval);
    481 
    482         sal_usleep(60);
    483     }
    484 
    485     return rv;
    486 }
    487 
    488 /* Returns OK or TIMEOUT. Calling routine has to check for ACK/NAK?Error */
    489 int
    490 iproc_smbus_start_wait(int unit)
    491 {
    492     int rv = SOC_E_TIMEOUT;
    493     soc_timeout_t to;
    494     uint32 rval, status;
    495 
    496     /* Start Transaction */
    497     READ_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr(unit, &rval);
    498     soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr, &rval, MASTER_START_BUSY_COMMANDf, 1);
    499     WRITE_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr(unit,rval);
    500 
    501     soc_timeout_init(&to, 10000, 1000);
    502 
    503     do {
    504         READ_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr(unit, &rval);
    505         if (soc_reg_field_get(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr,rval, MASTER_START_BUSY_COMMANDf) == 0) {
    506             rv = SOC_E_NONE;
    507             break;
    508         }
    509     } while(!(soc_timeout_check(&to)));
    510 
    511     READ_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr(unit, &rval);
    512     status = soc_reg_field_get(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr,rval, MASTER_STATUSf);
    513 
    514     if ((rv == 0) && (status == 0)) {
    515         rv = SOC_E_NONE;
    516     } else {
    517         iproc_smbus_timeout_recovery(unit);
    518         rv = SOC_E_TIMEOUT;
    519     }
    520     return rv;
    521 }
    522 
    523 int
    524 iproc_smbus_quick_command(int unit, uint8 saddr)
    525 {
    526     int rv = SOC_E_NONE;
    527     uint32 rval;
    528     int rt = 5;
    529 
    530     LOG_INFO(BSL_LS_SOC_I2C,
    531              (BSL_META_U(unit,
    532                          "i2c%d: smbus_quick_command @ %02x\n"),
    533               unit, saddr));
    534 
    535     I2C_LOCK(unit);
    536 
    537 retry:
    538     rval = SOC_I2C_TX_ADDR(saddr);
    539     soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    540     WRITE_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    541 
    542     rval = 0;
    543     soc_reg_field_set(unit, CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_QUICK_CMD);
    544     WRITE_CHIPCOMMONG_SMBUS0_SMBUS_MASTER_COMMANDr(unit,rval);
    545 
    546     rv = iproc_smbus_start_wait(unit);
    547     if (rv != SOC_E_NONE && rt-- > 0) {
    548         goto retry;
    549     } else if (rt < 0) {
    550         rv = SOC_E_TIMEOUT;
    551     }
    552 
    553     I2C_UNLOCK(unit);
    554     return rv;
    555 }
    556 
    557 #endif /* BCM_IPROC_SUPPORT */
    558 
    559 /*
    560  * Function: soc_i2c_write_byte
    561  *
    562  * Purpose: SMBus Write Quick/Byte
    563  *
    564  * This sends a single byte to the device.
    565  *
    566  *
    567  * Algorithm: S Addr Wr [A] Data P
    568  *
    569  * Parameters:
    570  *    unit - StrataSwitch device number or I2C bus number
    571  *    saddr - device base I2C address (datasheet).
    572  *    data - 8 bit device-specific data value
    573  *
    574  * Returns:
    575  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
    576  *    SOC_E_BUSY - the device timed out or is busy.
    577  *    SOC_E_NONE - no error, operation succeeded.
    578  *
    579  * Notes:
    580  *    none
    581  */
    582 int
    583 soc_i2c_write_byte(int unit, i2c_saddr_t saddr, uint8 data)
    584 {
    585     int rv = SOC_E_NONE;
    586 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    587     uint32 rval;
    588     int rt = 5;
    589 #endif
    590 
    591     LOG_INFO(BSL_LS_SOC_I2C,
    592              (BSL_META_U(unit,
    593                          "i2c%d: soc_i2c_write_byte @ %02x\n"),
    594               unit, saddr));
    595 
    596     /* Lock all access to I2C */
    597     I2C_LOCK(unit);
    598 
    599 #ifdef BCM_CMICM_SUPPORT
    600     if(soc_feature(unit, soc_feature_cmicm)) {
    601         LOG_INFO(BSL_LS_SOC_I2C,
    602                  (BSL_META_U(unit,
    603                              "i2c%d: soc_i2c_write_byte: saddr 0x%02x, data 0x%02x\n"),
    604                   unit, (int) saddr, (int) data));
    605 
    606 retry:
    607         rval = SOC_I2C_TX_ADDR(saddr);
    608         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    609 
    610         rval = data;
    611         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    612         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    613 
    614         rval = 0;
    615         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_SEND_BYTE);
    616         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
    617 
    618         rv = smbus_start_wait(unit);
    619         if (rv != SOC_E_NONE && rt-- > 0) {
    620             goto retry;
    621         } else if (rt < 0) {
    622             rv = SOC_E_TIMEOUT;
    623         }
    624     } else
    625 #endif
    626 #ifdef BCM_CMICX_SUPPORT
    627     if(soc_feature(unit, soc_feature_cmicx)) {
    628         LOG_INFO(BSL_LS_SOC_I2C,
    629                  (BSL_META_U(unit,
    630                              "i2c%d: soc_i2c_write_byte: saddr 0x%02x, data 0x%02x\n"),
    631                   unit, (int) saddr, (int) data));
    632 
    633 retry_cmicx:
    634         rval = SOC_I2C_TX_ADDR(saddr);
    635         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    636 
    637         rval = data;
    638         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    639         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    640 
    641         rval = 0;
    642         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_SEND_BYTE);
    643         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
    644 
    645         rv = cmicx_smbus_start_wait(unit);
    646         if (rv != SOC_E_NONE && rt-- > 0) {
    647             goto retry_cmicx;
    648         } else if (rt < 0) {
    649             rv = SOC_E_TIMEOUT;
    650         }
    651     } else
    652 #endif
    653     {
    654         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
    655             LOG_INFO(BSL_LS_SOC_I2C,
    656                      (BSL_META_U(unit,
    657                                  "i2c%d: soc_i2c_write_byte:"
    658                                  " failed to generate start.\n"),
    659                       unit));
    660             I2C_UNLOCK(unit);
    661             return rv;
    662         }
    663 
    664         if ( (rv = soc_i2c_write_one_byte(unit, data) ) < 0 ) {
    665             LOG_INFO(BSL_LS_SOC_I2C,
    666                      (BSL_META_U(unit,
    667                                  "i2c%d: soc_i2c_write_byte:"
    668                                  " failed to write data byte.\n"),
    669                       unit));
    670         }
    671 
    672         soc_i2c_stop(unit);
    673     }
    674     I2C_UNLOCK(unit);
    675     return rv;
    676 }
    677 
    678 /*
    679  * Function: soc_i2c_read_byte
    680  *
    681  * Purpose: SMBus Read Quick/Byte
    682  *
    683  * This Reads a single byte from the device
    684  *
    685  * Algorithm: S Addr Rd [A] [Data] NA P
    686  *
    687  * Parameters:
    688  *    unit - StrataSwitch device number or I2C bus number
    689  *    saddr - device base I2C address (datasheet).
    690  *    data - 8 bit device-specific data value to read into.
    691  *
    692  * Returns:
    693  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
    694  *    SOC_E_INTERNAL - Unexpected or internal error
    695  *    SOC_E_NONE - no error, operation succeeded.
    696  *
    697  * Notes:
    698  *    none
    699  */
    700 int
    701 soc_i2c_read_byte(int unit, i2c_saddr_t saddr, uint8* data)
    702 {
    703     int rv;
    704 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    705     uint32 rval;
    706     int rt = 5;
    707 #endif
    708 
    709     LOG_INFO(BSL_LS_SOC_I2C,
    710              (BSL_META_U(unit,
    711                          "i2c%d: soc_i2c_read_byte @ %02x\n"),
    712               unit, saddr));
    713 
    714     I2C_LOCK(unit);
    715 #ifdef BCM_CMICM_SUPPORT
    716     if(soc_feature(unit, soc_feature_cmicm)) {
    717 retry:
    718         rval = SOC_I2C_RX_ADDR(saddr);
    719         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    720         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    721 
    722         rval = 0;
    723         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_RECEIVE_BYTE);
    724         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
    725 
    726         rv = smbus_start_wait(unit);
    727         if (rv == SOC_E_NONE) {
    728             READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
    729             *data = (uint8) (rval & 0xff);
    730         } else if (rt-- > 0) {
    731             goto retry;
    732         } else {
    733             rv = SOC_E_TIMEOUT;
    734         }
    735 
    736         LOG_INFO(BSL_LS_SOC_I2C,
    737                  (BSL_META_U(unit,
    738                              "i2c%d: soc_i2c_read_byte: saddr 0x%02x, data 0x%02x\n"),
    739                   unit, (int) saddr, (int) *data));
    740 
    741     } else
    742 #endif
    743 #ifdef BCM_CMICX_SUPPORT
    744     if(soc_feature(unit, soc_feature_cmicx)) {
    745 retry_cmicx:
    746         rval = SOC_I2C_RX_ADDR(saddr);
    747         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    748         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    749 
    750         rval = 0;
    751         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_RECEIVE_BYTE);
    752         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
    753 
    754         rv = cmicx_smbus_start_wait(unit);
    755         if (rv == SOC_E_NONE) {
    756             READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
    757             *data = (uint8) (rval & 0xff);
    758         } else if (rt-- > 0) {
    759             goto retry_cmicx;
    760         } else {
    761             rv = SOC_E_TIMEOUT;
    762         }
    763 
    764         LOG_INFO(BSL_LS_SOC_I2C,
    765                  (BSL_META_U(unit,
    766                              "i2c%d: soc_i2c_read_byte: saddr 0x%02x, data 0x%02x\n"),
    767                   unit, (int) saddr, (int) *data));
    768 
    769     } else
    770 #endif
    771     {
    772         if ((rv = soc_i2c_start(unit, SOC_I2C_RX_ADDR(saddr))) < 0) {
    773             LOG_INFO(BSL_LS_SOC_I2C,
    774                      (BSL_META_U(unit,
    775                                  "i2c%d: soc_i2c_read_byte:"
    776                                  " failed to generate start.\n"),
    777                       unit));
    778             I2C_UNLOCK(unit);
    779             return rv;
    780         }
    781 
    782         if ((rv = soc_i2c_read_one_byte(unit, data,
    783                                         I2C_FINAL_READ)) < 0) {
    784             LOG_INFO(BSL_LS_SOC_I2C,
    785                      (BSL_META_U(unit,
    786                                  "i2c%d: soc_i2c_read_byte:"
    787                                  " failed to read data byte.\n"),
    788                       unit));
    789         }
    790 
    791         soc_i2c_stop(unit);
    792     }
    793     I2C_UNLOCK(unit);
    794     return rv;
    795 }
    796 
    797 
    798 
    799 /*
    800  * Function: soc_i2c_write_word
    801  *
    802  * Purpose: SMBus Write Word
    803  *
    804  * This command writes a single word to an I2C device.
    805  *
    806  * Algorithm: S Addr Wr [A] DataHigh [A] DataLow [A] P
    807  *
    808  * Parameters:
    809  *
    810  *    unit - StrataSwitch device number or I2C bus number
    811  *    saddr - device base I2C address (datasheet).
    812  *    value - 16 bit data value to write
    813  *
    814  * Returns:
    815  *
    816  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
    817  *    SOC_E_BUSY - the device timed out or is busy.
    818  *    SOC_E_INTERNAL - Unexpected or internal error
    819  *    SOC_E_NONE - no error, operation succeeded.
    820  *
    821  * Notes:
    822  *    None
    823  */
    824 int
    825 soc_i2c_write_word(int unit, i2c_saddr_t saddr, uint16 value)
    826 {
    827     int rv = SOC_E_NONE;
    828     uint8 b0 = (uint8) (value & 0x00ff);
    829     uint8 b1 = (uint8) ((value & 0xff00) >> 8);
    830 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    831     uint32 rval;
    832     int rt = 5;
    833 #endif
    834 
    835     LOG_INFO(BSL_LS_SOC_I2C,
    836              (BSL_META_U(unit,
    837                          "i2c%d: soc_i2c_write_word @ %02x\n"),
    838               unit, saddr));
    839 
    840     I2C_LOCK(unit);
    841 #ifdef BCM_CMICM_SUPPORT
    842     if(soc_feature(unit, soc_feature_cmicm)) {
    843         /* Write Word is achieved with SMBUS_WRITE_BYTE, with LSB of data instead of teh command */
    844 retry:
    845         rval = SOC_I2C_TX_ADDR(saddr);
    846         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    847 
    848         rval = b1;
    849         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    850         rval = b0;
    851         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    852         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    853 
    854         rval = 0;
    855         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_WRITE_BYTE);
    856         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
    857 
    858         rv = smbus_start_wait(unit);
    859         if (rv != SOC_E_NONE && rt-- > 0) {
    860             goto retry;
    861         } else if (rt < 0) {
    862             rv = SOC_E_TIMEOUT;
    863         }
    864     } else
    865 #endif
    866 #ifdef BCM_CMICX_SUPPORT
    867     if(soc_feature(unit, soc_feature_cmicx)) {
    868         /* Write Word is achieved with SMBUS_WRITE_BYTE, with LSB of data instead of teh command */
    869 retry_cmicx:
    870         rval = SOC_I2C_TX_ADDR(saddr);
    871         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    872 
    873         rval = b1;
    874         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    875         rval = b0;
    876         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    877         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    878 
    879         rval = 0;
    880         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_WRITE_BYTE);
    881         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
    882 
    883         rv = cmicx_smbus_start_wait(unit);
    884         if (rv != SOC_E_NONE && rt-- > 0) {
    885             goto retry_cmicx;
    886         } else if (rt < 0) {
    887             rv = SOC_E_TIMEOUT;
    888         }
    889     } else
    890 #endif
    891     {
    892         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
    893             LOG_INFO(BSL_LS_SOC_I2C,
    894                      (BSL_META_U(unit,
    895                                  "i2c%d: soc_i2c_write_word_data: "
    896                                  "failed to generate start.\n"),
    897                       unit));
    898     	I2C_UNLOCK(unit);
    899     	return rv;
    900         }
    901 
    902         do {
    903             if ( (rv = soc_i2c_write_one_byte(unit, b1) ) < 0 ) {
    904                 LOG_INFO(BSL_LS_SOC_I2C,
    905                          (BSL_META_U(unit,
    906                                      "i2c%d: soc_i2c_write_word_data: "
    907                                      "failed to send data MSB.\n"),
    908                           unit));
    909     	    break;
    910     	}
    911 
    912     	if ( (rv = soc_i2c_write_one_byte(unit, b0) ) < 0 ) {
    913     	    LOG_INFO(BSL_LS_SOC_I2C,
    914                      (BSL_META_U(unit,
    915                                  "i2c%d: soc_i2c_write_word_data: "
    916                                  "failed to send data LSB.\n"),
    917                       unit));
    918     	}
    919         } while (0);
    920 
    921         soc_i2c_stop(unit);
    922     }
    923     I2C_UNLOCK(unit);
    924     return rv;
    925 }
    926 
    927 /*
    928  *
    929  * Function: soc_i2c_read_word
    930  *
    931  * Purpose: SMBus Read Word
    932  *          Reads a single word from the device.
    933  *
    934  * Algorithm: S Addr Rd [A] [Data] [A] [Data] NA P
    935  *
    936  * Parameters:
    937  *    unit - StrataSwitch device number or I2C bus number
    938  *    saddr - device base I2C address (datasheet).
    939  *    value - 16 bit device-specific data value to read.
    940  *
    941  * Returns:
    942  *
    943  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
    944  *    SOC_E_INTERNAL - Unexpected or internal error
    945  *    SOC_E_NONE - no error, operation succeeded.
    946  *
    947  * Notes:
    948  *    none
    949  */
    950 int
    951 soc_i2c_read_word(int unit, i2c_saddr_t saddr, uint16* value)
    952 {
    953     int rv = SOC_E_NONE;
    954 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    955     uint8 b0, b1;
    956     uint32 rval;
    957     int rt = 5;
    958 #endif
    959 
    960     LOG_INFO(BSL_LS_SOC_I2C,
    961              (BSL_META_U(unit,
    962                          "i2c%d: soc_i2c_read_word @ %02x\n"),
    963               unit, saddr));
    964 
    965     I2C_LOCK(unit);
    966 #ifdef BCM_CMICM_SUPPORT
    967     if(soc_feature(unit, soc_feature_cmicm)) {
    968 retry:
    969         rval = SOC_I2C_RX_ADDR(saddr);
    970         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    971         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
    972 
    973         rval = 0;
    974         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_READ_WORD);
    975         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
    976 
    977         rv = smbus_start_wait(unit);
    978         if (rv == SOC_E_NONE) {
    979             READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
    980             b0 = (uint8) (rval & 0xff);
    981             READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
    982             b1 = (uint8) (rval & 0xff);
    983             rval = (b1 << 8) + b0;
    984             *value = (uint16) rval;
    985         } else if (rt-- > 0) {
    986             goto retry;
    987         } else {
    988             rv = SOC_E_TIMEOUT;
    989         }
    990     } else
    991 #endif
    992 #ifdef BCM_CMICX_SUPPORT
    993     if(soc_feature(unit, soc_feature_cmicx)) {
    994 retry_cmicx:
    995         rval = SOC_I2C_RX_ADDR(saddr);
    996         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
    997         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
    998 
    999         rval = 0;
   1000         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_READ_WORD);
   1001         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
   1002 
   1003         rv = cmicx_smbus_start_wait(unit);
   1004         if (rv == SOC_E_NONE) {
   1005             READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
   1006             b0 = (uint8) (rval & 0xff);
   1007             READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
   1008             b1 = (uint8) (rval & 0xff);
   1009             rval = (b1 << 8) + b0;
   1010             *value = (uint16) rval;
   1011         } else if (rt-- > 0) {
   1012             goto retry_cmicx;
   1013         } else {
   1014             rv = SOC_E_TIMEOUT;
   1015         }
   1016     } else
   1017 #endif
   1018     {
   1019         if ((rv = soc_i2c_start(unit, SOC_I2C_RX_ADDR(saddr))) < 0) {
   1020             LOG_INFO(BSL_LS_SOC_I2C,
   1021                      (BSL_META_U(unit,
   1022                                  "i2c%d: soc_i2c_read_word: "
   1023                                  "failed to generate start.\n"),
   1024                       unit));
   1025     	I2C_UNLOCK(unit);
   1026     	return rv;
   1027         }
   1028 
   1029         if ( (rv = soc_i2c_read_short(unit, value,
   1030     				  I2C_FINAL_READ)) < 0 ) {
   1031             LOG_INFO(BSL_LS_SOC_I2C,
   1032                      (BSL_META_U(unit,
   1033                                  "i2c%d: soc_i2c_read_word: "
   1034                                  "failed to read data word.\n"),
   1035                       unit));
   1036         }
   1037 
   1038         soc_i2c_stop(unit);
   1039     }
   1040     I2C_UNLOCK(unit);
   1041     return rv;
   1042 }
   1043 
   1044 /*
   1045  * Function: soc_i2c_read_byte_data
   1046  *
   1047  * Purpose: SMBus read byte
   1048  *
   1049  * This reads a single byte from a device, from a designated register.
   1050  * The register is specified through the Comm byte.
   1051  *
   1052  * Algorithm: S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
   1053  *
   1054  * Parameters:
   1055  *
   1056  *    unit - StrataSwitch device number or I2C bus number
   1057  *    saddr - device base I2C address (datasheet).
   1058  *    com - 8 bit device address or com port
   1059  *    value - address of where data byte should be stored
   1060  *
   1061  * Returns: data byte in value parameter and one of the following:
   1062  *
   1063  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
   1064  *    SOC_E_INTERNAL - Unexpected or internal error
   1065  *    SOC_E_NONE - no error, operation succeeded.
   1066  *
   1067  * Notes:
   1068  *    none
   1069  */
   1070 int
   1071 soc_i2c_read_byte_data(int unit, i2c_saddr_t saddr, uint8 com, uint8* value)
   1072 {
   1073     int rv = SOC_E_NONE;
   1074 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   1075     uint32 rval;
   1076     int rt = 5;
   1077 #endif
   1078 
   1079     LOG_INFO(BSL_LS_SOC_I2C,
   1080              (BSL_META_U(unit,
   1081                          "i2c%d: soc_i2c_read_byte_data @ %02x\n"),
   1082               unit, saddr));
   1083 
   1084     /* Lock all access to I2C */
   1085     I2C_LOCK(unit);
   1086 
   1087 #ifdef BCM_CMICM_SUPPORT
   1088     if(soc_feature(unit, soc_feature_cmicm)) {
   1089 retry:
   1090         rval = SOC_I2C_TX_ADDR(saddr);
   1091         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1092         rval = com;
   1093         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1094         rval = SOC_I2C_RX_ADDR(saddr);
   1095         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1096         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1097 
   1098         rval = 0;
   1099         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_READ_BYTE);
   1100         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
   1101 
   1102         rv = smbus_start_wait(unit);
   1103         if (rv == SOC_E_NONE) {
   1104             READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
   1105             *value = (uint8) (rval & 0xff);
   1106         } else if (rt-- > 0) {
   1107             goto retry;
   1108         } else {
   1109             rv = SOC_E_TIMEOUT;
   1110         }
   1111     } else
   1112 #endif
   1113 #ifdef BCM_CMICX_SUPPORT
   1114     if(soc_feature(unit, soc_feature_cmicx)) {
   1115 retry_cmicx:
   1116         rval = SOC_I2C_TX_ADDR(saddr);
   1117         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1118         rval = com;
   1119         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1120         rval = SOC_I2C_RX_ADDR(saddr);
   1121         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1122         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1123 
   1124         rval = 0;
   1125         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_READ_BYTE);
   1126         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
   1127 
   1128         rv = cmicx_smbus_start_wait(unit);
   1129         if (rv == SOC_E_NONE) {
   1130             READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
   1131             *value = (uint8) (rval & 0xff);
   1132         } else if (rt-- > 0) {
   1133             goto retry_cmicx;
   1134         } else {
   1135             rv = SOC_E_TIMEOUT;
   1136         }
   1137     } else
   1138 #endif
   1139     {
   1140         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
   1141             LOG_INFO(BSL_LS_SOC_I2C,
   1142                      (BSL_META_U(unit,
   1143                                  "i2c%d: soc_i2c_read_byte_data: "
   1144                                  "failed to generate start.\n"),
   1145                       unit));
   1146     	I2C_UNLOCK(unit);
   1147     	return rv;
   1148         }
   1149 
   1150         do {
   1151             if ( (rv = soc_i2c_write_one_byte(unit, com) ) < 0 ) {
   1152                 LOG_INFO(BSL_LS_SOC_I2C,
   1153                          (BSL_META_U(unit,
   1154                                      "i2c%d: soc_i2c_read_byte_data: "
   1155                                      "failed to send com byte.\n"),
   1156                           unit));
   1157     	    break;
   1158     	}
   1159     	if( (rv = soc_i2c_rep_start(unit, SOC_I2C_RX_ADDR(saddr) ) ) < 0 ){
   1160     	    LOG_INFO(BSL_LS_SOC_I2C,
   1161                      (BSL_META_U(unit,
   1162                                  "i2c%d: soc_i2c_read_byte_data: "
   1163                                  "failed to gen rep start.\n"),
   1164                       unit));
   1165     	    break;
   1166     	}
   1167     	if ( (rv = soc_i2c_read_one_byte(unit, value,
   1168     					 I2C_FINAL_READ)) < 0 ) {
   1169     	    LOG_INFO(BSL_LS_SOC_I2C,
   1170                      (BSL_META_U(unit,
   1171                                  "i2c%d: soc_i2c_read_byte_data: "
   1172                                  "failed to read data byte.\n"),
   1173                       unit));
   1174     	}
   1175         } while (0);
   1176 
   1177         soc_i2c_stop(unit);
   1178     }
   1179     I2C_UNLOCK(unit);
   1180     return rv;
   1181 }
   1182 
   1183 /*
   1184  * Function: soc_i2c_write_byte_data
   1185  *
   1186  * Purpose: SMBus write byte
   1187  *
   1188  * This writes a single byte to a device, to a designated register. The
   1189  * register is specified through the Comm byte. This is the opposite of
   1190  * the Read Byte Data command.
   1191  *
   1192  * Algorithm: S Addr Wr [A] Comm [A] Data [A] P
   1193  *
   1194  * Parameters:
   1195  *
   1196  *    unit - StrataSwitch device number or I2C bus number
   1197  *    saddr - device base I2C address (datasheet).
   1198  *    com - 8 bit device address or com port
   1199  *    value - data value to write
   1200  *
   1201  * Returns:
   1202  *
   1203  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
   1204  *    SOC_E_INTERNAL - Unexpected or internal error
   1205  *    SOC_E_NONE - no error, operation succeeded.
   1206  *
   1207  * Notes:
   1208  *    none
   1209  */
   1210 int
   1211 soc_i2c_write_byte_data(int unit, i2c_saddr_t saddr, uint8 com, uint8 value)
   1212 {
   1213     int rv = SOC_E_NONE;
   1214 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   1215     uint32 rval;
   1216     int rt = 5;
   1217 #endif
   1218 
   1219     LOG_INFO(BSL_LS_SOC_I2C,
   1220              (BSL_META_U(unit,
   1221                          "i2c%d: soc_i2c_write_byte_data @ %02x\n"),
   1222               unit, saddr));
   1223 
   1224     I2C_LOCK(unit);
   1225 
   1226 #ifdef BCM_CMICM_SUPPORT
   1227     if(soc_feature(unit, soc_feature_cmicm)) {
   1228 retry:
   1229         rval = SOC_I2C_TX_ADDR(saddr);
   1230         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1231         rval = com;
   1232         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1233         rval = value;
   1234         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1235         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1236 
   1237         rval = 0;
   1238         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_WRITE_BYTE);
   1239         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
   1240 
   1241         rv = smbus_start_wait(unit);
   1242         if (rv != SOC_E_NONE && rt-- > 0) {
   1243             goto retry;
   1244         } else if (rt < 0) {
   1245             rv = SOC_E_TIMEOUT;
   1246         }
   1247     } else
   1248 #endif
   1249 #ifdef BCM_CMICX_SUPPORT
   1250     if(soc_feature(unit, soc_feature_cmicx)) {
   1251 retry_cmicx:
   1252         rval = SOC_I2C_TX_ADDR(saddr);
   1253         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1254         rval = com;
   1255         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1256         rval = value;
   1257         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1258         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1259 
   1260         rval = 0;
   1261         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_WRITE_BYTE);
   1262         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
   1263 
   1264         rv = cmicx_smbus_start_wait(unit);
   1265         if (rv != SOC_E_NONE && rt-- > 0) {
   1266             goto retry_cmicx;
   1267         } else if (rt < 0) {
   1268             rv = SOC_E_TIMEOUT;
   1269         }
   1270     } else
   1271 #endif
   1272     {
   1273         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
   1274             LOG_INFO(BSL_LS_SOC_I2C,
   1275                      (BSL_META_U(unit,
   1276                                  "i2c%d: soc_i2c_write_byte_data: "
   1277                                  "failed to generate start.\n"),
   1278                       unit));
   1279     	I2C_UNLOCK(unit);
   1280     	return rv;
   1281         }
   1282 
   1283         do {
   1284             if ( (rv = soc_i2c_write_one_byte(unit, com) ) < 0 ) {
   1285                 LOG_INFO(BSL_LS_SOC_I2C,
   1286                          (BSL_META_U(unit,
   1287                                      "i2c%d: soc_i2c_write_byte_data: "
   1288                                      "failed to send com byte.\n"),
   1289                           unit));
   1290     	    break;
   1291     	}
   1292     	if ( (rv = soc_i2c_write_one_byte(unit, value) ) < 0 ) {
   1293     	    LOG_INFO(BSL_LS_SOC_I2C,
   1294                      (BSL_META_U(unit,
   1295                                  "i2c%d: soc_i2c_write_byte_data: "
   1296                                  "failed to send data byte.\n"),
   1297                       unit));
   1298     	}
   1299         } while (0);
   1300 
   1301         soc_i2c_stop(unit);
   1302     }
   1303     I2C_UNLOCK(unit);
   1304     return rv;
   1305 }
   1306 
   1307 /*
   1308  * Function: soc_i2c_read_word_data
   1309  *
   1310  * Purpose: SMBus Read Word Data
   1311  *
   1312  * This command is very like Read Byte Data; again, data is read from a
   1313  * device, from a designated register that is specified through the Comm
   1314  * byte. But this time, the data is a complete word (16 bits).
   1315  *
   1316  * Algorithm:
   1317  *     S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
   1318  *
   1319  * Parameters:
   1320  *
   1321  *    unit - StrataSwitch device number or I2C bus number
   1322  *    saddr - device base I2C address (datasheet).
   1323  *    com - 8 bit device address or com port
   1324  *    value - address where 16bit data value should be stored.
   1325  *
   1326  * Returns: 16bit data value on success, and one of the following :
   1327  *
   1328  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
   1329  *    SOC_E_INTERNAL - Unexpected or internal error
   1330  *    SOC_E_NONE - no error, operation succeeded.
   1331  *
   1332  * Notes:
   1333  *   None
   1334  */
   1335 int
   1336 soc_i2c_read_word_data(int unit, i2c_saddr_t saddr, uint8 com, uint16* value)
   1337 {
   1338     int rv = SOC_E_NONE;
   1339 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   1340     uint32 rval;
   1341     int rt = 5;
   1342 #endif
   1343 
   1344     I2C_LOCK(unit);
   1345 
   1346 #ifdef BCM_CMICM_SUPPORT
   1347     if(soc_feature(unit, soc_feature_cmicm)) {
   1348 retry:
   1349         rval = SOC_I2C_TX_ADDR(saddr);
   1350         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1351         rval = com;
   1352         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1353         rval = SOC_I2C_RX_ADDR(saddr);
   1354         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval,
   1355                             MASTER_WR_STATUSf, 1); /* Last Byte */
   1356         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1357 
   1358         rval = 0;
   1359         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval,
   1360                             SMBUS_PROTOCOLf, SMBUS_READ_WORD);
   1361         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
   1362         rv = smbus_start_wait(unit);
   1363         if (rv == SOC_E_NONE) {
   1364             READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
   1365             *value = (uint16) (rval & 0xff);
   1366             READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
   1367             *value |= (uint16) ((rval & 0xff) <<8);
   1368         } else if (rt-- > 0) {
   1369             goto retry;
   1370         } else {
   1371             rv = SOC_E_TIMEOUT;
   1372         }
   1373     } else
   1374 #endif
   1375 #ifdef BCM_CMICX_SUPPORT
   1376     if(soc_feature(unit, soc_feature_cmicx)) {
   1377 retry_cmicx:
   1378         rval = SOC_I2C_TX_ADDR(saddr);
   1379         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1380         rval = com;
   1381         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1382         rval = SOC_I2C_RX_ADDR(saddr);
   1383         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval,
   1384                             MASTER_WR_STATUSf, 1); /* Last Byte */
   1385         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1386 
   1387         rval = 0;
   1388         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval,
   1389                             SMBUS_PROTOCOLf, SMBUS_READ_WORD);
   1390         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
   1391         rv = cmicx_smbus_start_wait(unit);
   1392         if (rv == SOC_E_NONE) {
   1393             READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
   1394             *value = (uint16) (rval & 0xff);
   1395             READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
   1396             *value |= (uint16) ((rval & 0xff) <<8);
   1397         } else if (rt-- > 0) {
   1398             goto retry_cmicx;
   1399         } else {
   1400             rv = SOC_E_TIMEOUT;
   1401         }
   1402     } else
   1403 #endif
   1404     {
   1405         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
   1406             LOG_INFO(BSL_LS_SOC_I2C,
   1407                      (BSL_META_U(unit,
   1408                                  "i2c%d: soc_i2c_read_word_data: "
   1409                                  "failed to generate start.\n"),
   1410                       unit));
   1411     	I2C_UNLOCK(unit);
   1412     	return rv;
   1413         }
   1414 
   1415         do {
   1416             if ( (rv = soc_i2c_write_one_byte(unit, com) ) < 0 ) {
   1417                 LOG_INFO(BSL_LS_SOC_I2C,
   1418                          (BSL_META_U(unit,
   1419                                      "i2c%d: soc_i2c_read_word_data: "
   1420                                      "failed to send com byte.\n"),
   1421                           unit));
   1422     	    break;
   1423     	}
   1424     	if( (rv = soc_i2c_rep_start(unit, SOC_I2C_RX_ADDR(saddr) ) ) < 0 ){
   1425     	    LOG_INFO(BSL_LS_SOC_I2C,
   1426                      (BSL_META_U(unit,
   1427                                  "i2c%d: soc_i2c_read_word_data: "
   1428                                  "failed to gen rep start.\n"),
   1429                       unit));
   1430     	    break;
   1431     	}
   1432     	if( (rv = soc_i2c_read_short(unit, value,
   1433     				     I2C_FINAL_READ)) < 0){
   1434     	    LOG_INFO(BSL_LS_SOC_I2C,
   1435                      (BSL_META_U(unit,
   1436                                  "i2c%d: soc_i2c_read_word_data: "
   1437                                  "failed to read data word.\n"),
   1438                       unit));
   1439     	}
   1440         } while (0);
   1441 
   1442         soc_i2c_stop(unit);
   1443     }
   1444     I2C_UNLOCK(unit);
   1445     return rv;
   1446 }
   1447 
   1448 /*
   1449  * Function: soc_i2c_write_word_data
   1450  *
   1451  * Purpose: SMBus Write Word Data
   1452  *
   1453  * This is the opposite operation of the Read Word Data command. 16 bits
   1454  * of data is read from a device, from a designated register that is
   1455  * specified through the Comm byte.
   1456  *
   1457  * Algorithm: S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
   1458  *
   1459  * Parameters:
   1460  *
   1461  *    unit - StrataSwitch device number or I2C bus number
   1462  *    saddr - device base I2C address (datasheet).
   1463  *    com - 8 bit device address or com port
   1464  *    value - 16 bit data value to write
   1465  *
   1466  * Returns:
   1467  *
   1468  *    SOC_E_TIMEOUT - the device can not be contacted or is offline.
   1469  *    SOC_E_INTERNAL - Unexpected or internal error
   1470  *    SOC_E_NONE - no error, operation succeeded.
   1471  *
   1472  * Notes:
   1473  *    None
   1474  */
   1475 int
   1476 soc_i2c_write_word_data(int unit, i2c_saddr_t saddr, uint8 com, uint16 value)
   1477 {
   1478     int rv = SOC_E_NONE;
   1479 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   1480     uint32 rval;
   1481     int rt = 5;
   1482 #endif
   1483     uint8 b0 = (uint8) (value & 0x00ff);
   1484     uint8 b1 = (uint8) ((value & 0xff00) >> 8);
   1485 
   1486     I2C_LOCK(unit);
   1487 
   1488 #ifdef BCM_CMICM_SUPPORT
   1489     if(soc_feature(unit, soc_feature_cmicm)) {
   1490 retry:
   1491         rval = SOC_I2C_TX_ADDR(saddr);
   1492         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1493         rval = com;
   1494         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1495         rval = value & 0xff;
   1496         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1497         rval = (value & 0xff00) >> 8;
   1498         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval,
   1499                             MASTER_WR_STATUSf, 1); /* Last Byte */
   1500         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1501 
   1502         rval = 0;
   1503         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval,
   1504                             SMBUS_PROTOCOLf, SMBUS_WRITE_WORD);
   1505         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
   1506         rv = smbus_start_wait(unit);
   1507         if (rv != SOC_E_NONE && rt-- > 0) {
   1508             goto retry;
   1509         } else if (rt < 0) {
   1510             rv = SOC_E_TIMEOUT;
   1511         }
   1512     } else
   1513 #endif
   1514 #ifdef BCM_CMICX_SUPPORT
   1515     if(soc_feature(unit, soc_feature_cmicx)) {
   1516 retry_cmicx:
   1517         rval = SOC_I2C_TX_ADDR(saddr);
   1518         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1519         rval = com;
   1520         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1521         rval = value & 0xff;
   1522         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1523         rval = (value & 0xff00) >> 8;
   1524         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval,
   1525                             MASTER_WR_STATUSf, 1); /* Last Byte */
   1526         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1527 
   1528         rval = 0;
   1529         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval,
   1530                             SMBUS_PROTOCOLf, SMBUS_WRITE_WORD);
   1531         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
   1532         rv = cmicx_smbus_start_wait(unit);
   1533         if (rv != SOC_E_NONE && rt-- > 0) {
   1534             goto retry_cmicx;
   1535         } else if (rt < 0) {
   1536             rv = SOC_E_TIMEOUT;
   1537         }
   1538     } else
   1539 #endif
   1540     {
   1541         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
   1542             LOG_INFO(BSL_LS_SOC_I2C,
   1543                      (BSL_META_U(unit,
   1544                                  "i2c%d: soc_i2c_write_word_data: "
   1545                                  "failed to generate start.\n"),
   1546                       unit));
   1547     	I2C_UNLOCK(unit);
   1548     	return rv;
   1549         }
   1550 
   1551         do {
   1552             if ( (rv = soc_i2c_write_one_byte(unit, com) ) < 0 ) {
   1553                 LOG_INFO(BSL_LS_SOC_I2C,
   1554                          (BSL_META_U(unit,
   1555                                      "i2c%d: soc_i2c_write_word_data: "
   1556                                      "failed to send com byte.\n"),
   1557                           unit));
   1558     	    break;
   1559     	}
   1560     	if ( (rv = soc_i2c_write_one_byte(unit, b0) ) < 0 ) {
   1561     	    LOG_INFO(BSL_LS_SOC_I2C,
   1562                      (BSL_META_U(unit,
   1563                                  "i2c%d: soc_i2c_write_word_data: "
   1564                                  "failed to send data LSB.\n"),
   1565                       unit));
   1566     	    break;
   1567     	}
   1568 
   1569     	if ( (rv = soc_i2c_write_one_byte(unit, b1) ) < 0 ) {
   1570     	    LOG_INFO(BSL_LS_SOC_I2C,
   1571                      (BSL_META_U(unit,
   1572                                  "i2c%d: soc_i2c_write_word_data: "
   1573                                  "failed to send data MSB.\n"),
   1574                       unit));
   1575     	}
   1576         } while (0);
   1577 
   1578         soc_i2c_stop(unit);
   1579     }
   1580     I2C_UNLOCK(unit);
   1581     return rv;
   1582 }
   1583 
   1584 /*
   1585  * Function: soc_i2c_block_read
   1586  *
   1587  * Purpose: SMBus Block Read
   1588  *
   1589  * This command reads a block of up to 32 bytes from a device, from a
   1590  * designated register that is specified through the Comm byte.
   1591  * The amount of data is specified by the device in the Count byte.
   1592  *
   1593  * Algorithm:
   1594  *         S Addr Wr [A] Comm [A]
   1595  *         S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
   1596  *
   1597  * Parameters:
   1598  *
   1599  *    unit - StrataSwitch device number or I2C bus number
   1600  *    saddr - device base I2C address (datasheet).
   1601  *    com - 8 bit device address or com port
   1602  *    count - address where number of bytes read is stored.
   1603  *    data - address where data buffer should be stored.
   1604  *
   1605  * Returns:
   1606  *    count - updated with the number of bytes successfullly read.
   1607  *
   1608  *    SOC_E_TIMEOUT - the device can not be contacted or is
   1609  *                        offline, or the number of bytes specified
   1610  *                        could not be read from the device.
   1611  *
   1612  *    SOC_E_INTERNAL - Unexpected or internal error
   1613  *    SOC_E_NONE - no error, operation succeeded.
   1614  *
   1615  * Notes:
   1616  *    None
   1617  */
   1618 int
   1619 soc_i2c_block_read(int unit, i2c_saddr_t saddr,
   1620 		   uint8 com, uint8* count, uint8* data)
   1621 {
   1622     int i, ack, rv = SOC_E_NONE;
   1623     uint8* ptr = NULL;
   1624 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   1625     uint32 rval;
   1626     int rt = 5;
   1627 #endif
   1628 
   1629     LOG_INFO(BSL_LS_SOC_I2C,
   1630              (BSL_META_U(unit,
   1631                          "i2c%d: soc_i2c_block_read %02x bytes @ %02x - %02x\n"),
   1632               unit, (int)*count, saddr, com));
   1633 
   1634     I2C_LOCK(unit);
   1635 
   1636 #ifdef BCM_CMICM_SUPPORT
   1637     if(soc_feature(unit, soc_feature_cmicm)) {
   1638 retry:
   1639         rval = SOC_I2C_TX_ADDR(saddr);
   1640         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1641         rval = com;
   1642         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1643         rval = SOC_I2C_RX_ADDR(saddr);
   1644         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1645         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1646 
   1647         rval = 0;
   1648         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_BLOCK_READ);
   1649         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
   1650 
   1651         rv = smbus_start_wait(unit);
   1652         if (rv == SOC_E_NONE) {
   1653             READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
   1654             *count = (uint8) (rval & 0xff);
   1655             ptr = data;
   1656             for( i = 0; i < *count; i++, ptr++) {
   1657                 READ_CMIC_I2CM_SMBUS_MASTER_DATA_READr(unit, &rval);
   1658                 *ptr = (uint8) (rval & 0xff);
   1659             }
   1660         } else if (rt-- > 0) {
   1661             goto retry;
   1662         } else {
   1663             rv = SOC_E_TIMEOUT;
   1664         }
   1665     } else
   1666 #endif
   1667 #ifdef BCM_CMICX_SUPPORT
   1668     if(soc_feature(unit, soc_feature_cmicx)) {
   1669 retry_cmicx:
   1670         rval = SOC_I2C_TX_ADDR(saddr);
   1671         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1672         rval = com;
   1673         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1674         rval = SOC_I2C_RX_ADDR(saddr);
   1675         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1676         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1677 
   1678         rval = 0;
   1679         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_BLOCK_READ);
   1680         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
   1681 
   1682         rv = cmicx_smbus_start_wait(unit);
   1683         if (rv == SOC_E_NONE) {
   1684             READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
   1685             *count = (uint8) (rval & 0xff);
   1686             ptr = data;
   1687             for( i = 0; i < *count; i++, ptr++) {
   1688                 READ_IPROCPERIPH_SMBUS_REG(MASTER_DATA_READr, unit, &rval);
   1689                 *ptr = (uint8) (rval & 0xff);
   1690             }
   1691         } else if (rt-- > 0) {
   1692             goto retry_cmicx;
   1693         } else {
   1694             rv = SOC_E_TIMEOUT;
   1695         }
   1696     } else
   1697 #endif
   1698     {
   1699         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
   1700             LOG_INFO(BSL_LS_SOC_I2C,
   1701                      (BSL_META_U(unit,
   1702                                  "i2c%d: soc_i2c_block_read: "
   1703                                  "failed to generate start.\n"),
   1704                       unit));
   1705     	I2C_UNLOCK(unit);
   1706     	return rv;
   1707         }
   1708 
   1709         do {
   1710             if ( (rv = soc_i2c_write_one_byte(unit, com) ) < 0 ) {
   1711                 LOG_INFO(BSL_LS_SOC_I2C,
   1712                          (BSL_META_U(unit,
   1713                                      "i2c%d: soc_i2c_block_read: "
   1714                                      "failed to send com byte.\n"),
   1715                           unit));
   1716     	    break;
   1717     	}
   1718 
   1719     	if( (rv = soc_i2c_rep_start(unit, SOC_I2C_RX_ADDR(saddr)))
   1720     	    < 0 ){
   1721     	    LOG_INFO(BSL_LS_SOC_I2C,
   1722                      (BSL_META_U(unit,
   1723                                  "i2c%d: soc_i2c_block_read: "
   1724                                  "failed to gen rep start.\n"),
   1725                       unit));
   1726     	    break;
   1727     	}
   1728     	/* Read expected byte count from chip */
   1729     	if ( (rv = soc_i2c_read_one_byte(unit, count,
   1730     					 I2C_MORE_TO_READ)) < 0 ) {
   1731     	    LOG_INFO(BSL_LS_SOC_I2C,
   1732                      (BSL_META_U(unit,
   1733                                  "i2c%d: soc_i2c_block_read: "
   1734                                  "failed to read data count byte.\n"),
   1735                       unit));
   1736     	    break;
   1737     	}
   1738     	ptr = data;
   1739     	for( i = 0; i < *count; i++, ptr++) {
   1740     	    if (i == (*count - 1)) {
   1741     	        ack = I2C_FINAL_READ;
   1742     	    }
   1743     	    else {
   1744     	        ack = I2C_MORE_TO_READ;
   1745     	    }
   1746     	    if ( (rv = soc_i2c_read_one_byte(unit, ptr, ack) ) < 0 ) {
   1747     	        LOG_INFO(BSL_LS_SOC_I2C,
   1748                          (BSL_META_U(unit,
   1749                                      "i2c%d: soc_i2c_block_read: "
   1750                                      "failed to read data byte %d.\n"),
   1751                           unit, i));
   1752     		*count = i; /* actual number read */
   1753     		break; /* out of for-loop, fall out of while */
   1754     	    }
   1755     	}
   1756         } while (0);
   1757 
   1758         soc_i2c_stop(unit);
   1759     }
   1760     I2C_UNLOCK(unit);
   1761     return rv;
   1762 }
   1763 
   1764 /*
   1765  * Function: soc_i2c_block_write
   1766  *
   1767  * Purpose: SMBus Block Write
   1768  *
   1769  * The opposite of the Block Read command, this writes upto 32 bytes to
   1770  * a device, to a designated register that is specified through the
   1771  * Comm byte. The amount of data is specified in the Count byte.
   1772  *
   1773  * Algorithm: S Addr Wr [A] Comm [A]
   1774  *            Count [A] Data [A] Data [A] ... [A] Data [A] P
   1775  *
   1776  *
   1777  * Parameters:
   1778  *
   1779  *    unit - StrataSwitch device number or I2C bus number
   1780  *    saddr - device base I2C address (datasheet).
   1781  *    com - 8 bit device address or com port
   1782  *    count - number of bytes to write from data buff.
   1783  *    data - address of data to write (data buffer).
   1784  *
   1785  * Returns:
   1786  *
   1787  *    SOC_E_TIMEOUT - the device can not be contacted or is
   1788  *                        offline, or the specified number of bytes
   1789  *                        could not be written to the device.
   1790  *
   1791  *    SOC_E_NONE - no error, operation succeeded.
   1792  *
   1793  * Notes:
   1794  *    None
   1795  */
   1796 int
   1797 soc_i2c_block_write(int unit, i2c_saddr_t saddr,
   1798 		    uint8 com, uint8 count, uint8* data)
   1799 {
   1800     int i,rv = SOC_E_NONE;
   1801     uint8* ptr = NULL;
   1802 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   1803     uint32 rval;
   1804     int rt = 5;
   1805 #endif
   1806 
   1807     LOG_INFO(BSL_LS_SOC_I2C,
   1808              (BSL_META_U(unit,
   1809                          "i2c%d: soc_i2c_block_write %02x bytes @ %02x - %02x\n"),
   1810               unit, count, saddr, com));
   1811 
   1812     I2C_LOCK(unit);
   1813 
   1814 #ifdef BCM_CMICM_SUPPORT
   1815     if(soc_feature(unit, soc_feature_cmicm)) {
   1816 retry:
   1817         rval = SOC_I2C_TX_ADDR(saddr);
   1818         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1819         rval = com;
   1820         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1821         rval = count;
   1822         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1823 
   1824         ptr = data;
   1825         for( i = 0; i < (int) (count - 1); i++, ptr++) {
   1826             rval = (uint32) *ptr;
   1827             WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1828         }
   1829         rval = (uint32) *ptr;
   1830         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1831         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1832 
   1833         rval = 0;
   1834         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_BLOCK_WRITE);
   1835         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
   1836 
   1837         rv = smbus_start_wait(unit);
   1838         if (rv != SOC_E_NONE && rt-- > 0) {
   1839             goto retry;
   1840         } else if (rt < 0) {
   1841             rv = SOC_E_TIMEOUT;
   1842         }
   1843     } else
   1844 #endif
   1845 #ifdef BCM_CMICX_SUPPORT
   1846     if(soc_feature(unit, soc_feature_cmicx)) {
   1847 retry_cmicx:
   1848         rval = SOC_I2C_TX_ADDR(saddr);
   1849         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1850         rval = com;
   1851         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1852         rval = count;
   1853         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1854 
   1855         ptr = data;
   1856         for( i = 0; i < (int) (count - 1); i++, ptr++) {
   1857             rval = (uint32) *ptr;
   1858             WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1859         }
   1860         rval = (uint32) *ptr;
   1861         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1862         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_DATA_WRITEr, unit, rval);
   1863 
   1864         rval = 0;
   1865         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_BLOCK_WRITE);
   1866         WRITE_IPROCPERIPH_SMBUS_REG(MASTER_COMMANDr, unit,rval);
   1867 
   1868         rv = cmicx_smbus_start_wait(unit);
   1869         if (rv != SOC_E_NONE && rt-- > 0) {
   1870             goto retry_cmicx;
   1871         } else if (rt < 0) {
   1872             rv = SOC_E_TIMEOUT;
   1873         }
   1874     } else
   1875 #endif
   1876     {
   1877         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
   1878             LOG_INFO(BSL_LS_SOC_I2C,
   1879                      (BSL_META_U(unit,
   1880                                  "i2c%d: soc_i2c_block_write: "
   1881                                  "failed to generate start.\n"),
   1882                       unit));
   1883     	I2C_UNLOCK(unit);
   1884     	return rv;
   1885         }
   1886 
   1887         do {
   1888             if ( (rv = soc_i2c_write_one_byte(unit, com) ) < 0 ) {
   1889                 LOG_INFO(BSL_LS_SOC_I2C,
   1890                          (BSL_META_U(unit,
   1891                                      "i2c%d: soc_i2c_block_write: "
   1892                                      "failed to send com byte.\n"),
   1893                           unit));
   1894     	    break;
   1895     	}
   1896 
   1897     	if ( (rv = soc_i2c_write_one_byte(unit, count) ) < 0 ) {
   1898     	    LOG_INFO(BSL_LS_SOC_I2C,
   1899                      (BSL_META_U(unit,
   1900                                  "i2c%d: soc_i2c_block_write: "
   1901                                  "failed to send count byte.\n"),
   1902                       unit));
   1903     	    break;
   1904     	}
   1905     	ptr = data;
   1906     	for( i = 0; i < (int) count; i++, ptr++) {
   1907     	    if ( (rv = soc_i2c_write_one_byte(unit, *ptr) ) < 0 ) {
   1908     	        LOG_INFO(BSL_LS_SOC_I2C,
   1909                          (BSL_META_U(unit,
   1910                                      "i2c%d: soc_i2c_block_write: "
   1911                                      "failed to send byte %d.\n"),
   1912                           unit, i ));
   1913     		break;
   1914     	    }
   1915     	}
   1916         } while (0);
   1917 
   1918         soc_i2c_stop(unit);
   1919     }
   1920     I2C_UNLOCK(unit);
   1921     return rv;
   1922 }
   1923 
   1924 /*
   1925  * Function: soc_i2c_multi_write
   1926  *
   1927  * Purpose: SMBus Multi Write
   1928  *
   1929  * The opposite of the Block Read command, this writes upto 32 bytes to
   1930  * a device, to a designated register that is specified through the
   1931  * Comm byte. The amount of data is specified in the Count byte.
   1932  *
   1933  * Algorithm: S Addr Wr [A] Comm [A]
   1934  *            Data [A] Data [A] ... [A] Data [A] P
   1935  *
   1936  *
   1937  * Parameters:
   1938  *
   1939  *    unit - StrataSwitch device number or I2C bus number
   1940  *    saddr - device base I2C address (datasheet).
   1941  *    com - 8 bit device address or com port
   1942  *    count - number of bytes to write from data buff.
   1943  *    data - address of data to write (data buffer).
   1944  *
   1945  * Returns:
   1946  *
   1947  *    SOC_E_TIMEOUT - the device can not be contacted or is
   1948  *                        offline, or the specified number of bytes
   1949  *                        could not be written to the device.
   1950  *
   1951  *    SOC_E_NONE - no error, operation succeeded.
   1952  *
   1953  * Notes:
   1954  *    None
   1955  */
   1956 int
   1957 soc_i2c_multi_write(int unit, i2c_saddr_t saddr,
   1958 		    uint8 com, uint8 count, uint8* data)
   1959 {
   1960     int i,rv = SOC_E_NONE;
   1961     uint8* ptr = NULL;
   1962 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   1963     uint32 rval;
   1964     int rt = 5;
   1965 #endif
   1966 
   1967     LOG_INFO(BSL_LS_SOC_I2C,
   1968              (BSL_META_U(unit,
   1969                          "i2c%d: soc_i2c_multi_write %02x bytes @ %02x - %02x\n"),
   1970               unit, count, saddr, com));
   1971 
   1972     I2C_LOCK(unit);
   1973 
   1974 #ifdef BCM_CMICM_SUPPORT
   1975     if(soc_feature(unit, soc_feature_cmicm)) {
   1976 retry:
   1977         rval = SOC_I2C_TX_ADDR(saddr);
   1978         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1979         rval = com;
   1980         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1981 
   1982         ptr = data;
   1983         for( i = 0; i < (int) (count - 1); i++, ptr++) {
   1984             rval = (uint32) *ptr;
   1985             WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1986         }
   1987         rval = (uint32) *ptr;
   1988         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   1989         WRITE_CMIC_I2CM_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   1990         rval = 0;
   1991         soc_reg_field_set(unit, CMIC_I2CM_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_BLOCK_WRITE);
   1992         WRITE_CMIC_I2CM_SMBUS_MASTER_COMMANDr(unit,rval);
   1993 
   1994         rv = smbus_start_wait(unit);
   1995         if (rv != SOC_E_NONE && rt-- > 0) {
   1996             goto retry;
   1997         } else if (rt < 0) {
   1998             rv = SOC_E_TIMEOUT;
   1999         }
   2000     } else
   2001 #endif
   2002 #ifdef BCM_CMICX_SUPPORT
   2003     if(soc_feature(unit, soc_feature_cmicx)) {
   2004 retry_cmicx:
   2005         rval = SOC_I2C_TX_ADDR(saddr);
   2006         WRITE_IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   2007         rval = com;
   2008         WRITE_IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   2009 
   2010         ptr = data;
   2011         for( i = 0; i < (int) (count - 1); i++, ptr++) {
   2012             rval = (uint32) *ptr;
   2013             WRITE_IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   2014         }
   2015         rval = (uint32) *ptr;
   2016         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr, &rval, MASTER_WR_STATUSf, 1); /* Last Byte */
   2017         WRITE_IPROCPERIPH_SMBUS1_SMBUS_MASTER_DATA_WRITEr(unit, rval);
   2018 
   2019         rval = 0;
   2020         soc_reg_field_set(unit, IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr, &rval, SMBUS_PROTOCOLf, SMBUS_BLOCK_WRITE);
   2021         WRITE_IPROCPERIPH_SMBUS1_SMBUS_MASTER_COMMANDr(unit,rval);
   2022 
   2023         rv = cmicx_smbus_start_wait(unit);
   2024         if (rv != SOC_E_NONE && rt-- > 0) {
   2025             goto retry_cmicx;
   2026         } else if (rt < 0) {
   2027             rv = SOC_E_TIMEOUT;
   2028         }
   2029     } else
   2030 #endif
   2031     {
   2032         if ( (rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr) ) ) < 0 ) {
   2033             LOG_INFO(BSL_LS_SOC_I2C,
   2034                      (BSL_META_U(unit,
   2035                                  "i2c%d: soc_i2c_multi_write: "
   2036                                  "failed to generate start.\n"),
   2037                       unit));
   2038     	I2C_UNLOCK(unit);
   2039     	return rv;
   2040         }
   2041 
   2042         do {
   2043             if ( (rv = soc_i2c_write_one_byte(unit, com) ) < 0 ) {
   2044                 LOG_INFO(BSL_LS_SOC_I2C,
   2045                      (BSL_META_U(unit,
   2046                                  "i2c%d: soc_i2c_multi_write: "
   2047                                  "failed to send com byte.\n"),
   2048                       unit));
   2049                  break;
   2050             }
   2051 
   2052             ptr = data;
   2053             for( i = 0; i < (int) count; i++, ptr++) {
   2054                 if ( (rv = soc_i2c_write_one_byte(unit, *ptr) ) < 0 ) {
   2055     	            LOG_INFO(BSL_LS_SOC_I2C,
   2056                          (BSL_META_U(unit,
   2057                                      "i2c%d: soc_i2c_multi_write: "
   2058                                      "failed to send byte %d.\n"),
   2059                           unit, i ));
   2060                     break;
   2061                 }
   2062             }
   2063         } while (0);
   2064 
   2065         soc_i2c_stop(unit);
   2066     }
   2067     I2C_UNLOCK(unit);
   2068     return rv;
   2069 }
   2070