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

devs.c (54944B)


      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  * I2C driver for the CPU Management Interface Controller (CMIC). This
      8  * module provides for discovery and loading of I2C device drivers and
      9  * manipulation of I2C device state.
     10  *
     11  * See also: bus.c
     12  */
     13 
     14 #include <sal/types.h>
     15 #include <sal/core/boot.h>
     16 #include <soc/debug.h>
     17 #include <soc/error.h>
     18 #include <soc/drv.h>
     19 #include <soc/cmic.h>
     20 #include <soc/i2c.h>
     21 #include <shared/bsl.h>
     22 #ifdef BCM_CMICM_SUPPORT
     23 #include <soc/cmicm.h>
     24 #endif
     25 
     26 /*
     27  * SD9560x Baseboard components (from UM)
     28  *
     29  * Device   AddrLines NDevices   Base Address     Board0     Description
     30  * LM75     3      2          1001XXXY        1001000R   I2C TempSensor
     31  * LM75     3      2          1001XXXY        1001100R   I2C TempSensor
     32  * 24LC64   3      2          1010XXXY        1010000R   I2C EEPROM
     33  * 24LC64   3      2          1010XXXY        1010100R   I2C EEPROM
     34  * W229b    n/a    n/a        1101001Y        1101001Y   Clock chip
     35  * MAX127   n/a    n/a        1010000Y        1010000Y   A/D Converter
     36  *
     37  * X=Don't Care, Y= Read/Write
     38  */
     39 
     40 /* LM63 driver - lm63.c */
     41 extern i2c_driver_t _soc_i2c_lm63_driver;
     42 /* LM75 driver - lm75.c */
     43 extern i2c_driver_t _soc_i2c_lm75_driver;
     44 /* MAX664X driver - max664x.c */
     45 extern i2c_driver_t _soc_i2c_max664x_driver;
     46 /* MAX127 Driver - max127.c */
     47 extern i2c_driver_t _soc_i2c_max127_driver;
     48 /* W229B Driver - w229b.c */
     49 extern i2c_driver_t _soc_i2c_w229b_driver;
     50 /* AT24C64 EEPROM driver - 24c64.c */
     51 extern i2c_driver_t _soc_i2c_eep24c64_driver;
     52 /* XFP driver - xfp.c */
     53 extern i2c_driver_t _soc_i2c_xfp_driver;
     54 /* PCIE config space register access driver - pcie.c */
     55 extern i2c_driver_t _soc_i2c_pcie_driver;
     56 /* Phillips PCF8574 Parallel Port - pcf8574.c */
     57 /* Phillips PCF8574 Parallel Port - pcf8574.c */
     58 extern i2c_driver_t _soc_i2c_pcf8574_driver;
     59 /* LTC 1427 DAC */
     60 extern i2c_driver_t _soc_i2c_ltc1427_driver ;
     61 /* Matrix Orbital LCD Display */
     62 extern i2c_driver_t _soc_i2c_lcd_driver;
     63 /* Cypress 22393 clock chip driver */
     64 extern i2c_driver_t _soc_i2c_cy2239x_driver;
     65 /* Cypress 22150 clock chip driver */
     66 extern i2c_driver_t _soc_i2c_cy22150_driver;
     67 /* LTC4258 Powered Ethernet chip driver */
     68 extern i2c_driver_t _soc_i2c_ltc4258_driver;
     69 /* PD63000 Powered Ethernet chip driver */
     70 extern i2c_driver_t _soc_i2c_pd63000_driver;
     71 /* MAX5478 Digital Potentiometer chip driver */
     72 extern i2c_driver_t _soc_i2c_max5478_driver;
     73 /* BCM59101 Power Over Ethernet chip driver */
     74 extern i2c_driver_t _soc_i2c_bcm59101_driver;
     75 /* PCA9548 8-channel i2c mux chip driver */
     76 extern i2c_driver_t _soc_i2c_pca9548_driver;
     77 /* ADP4000 an integrated power control IC */
     78 extern i2c_driver_t _soc_i2c_adp4000_driver;
     79 /* CxP driver */
     80 extern i2c_driver_t _soc_i2c_cxp_driver;
     81 /* LTC3880 an integrated power control IC */
     82 extern i2c_driver_t _soc_i2c_ltc3880_driver;
     83 /* LTC3882 an integrated power control IC */
     84 extern i2c_driver_t _soc_i2c_ltc3882_driver;
     85 /* LTC3884 an integrated power control IC */
     86 extern i2c_driver_t _soc_i2c_ltc3884_driver;
     87 /* LTC2974 an integrated power monitoring  IC */
     88 extern i2c_driver_t _soc_i2c_ltc2974_driver;
     89 /* LTM4676 an integrated power control IC */
     90 extern i2c_driver_t _soc_i2c_ltm4676_driver;
     91 /* PMBUS an integrated power control IC */
     92 extern i2c_driver_t _soc_i2c_pmbus_driver;
     93 
     94 extern i2c_driver_t _soc_i2c_max669x_driver;
     95 
     96 extern i2c_driver_t _soc_i2c_ltm4678_driver;
     97 
     98 extern i2c_driver_t _soc_i2c_isl68127_driver;
     99 
    100 #if defined(SHADOW_SVK)
    101 /* PCA9505 40-bit i2c bus IO port */
    102 extern i2c_driver_t _soc_i2c_pca9505_driver;
    103 #endif
    104 
    105 /*
    106  * AT24C64 init (test) data - one page, and one word, used
    107  * for page boundary write tests
    108  */
    109  unsigned char
    110 eep24c64_test_data[] = {
    111     0x4A,0x46,0x44,0xff,
    112     0x01,0x02,0x03,0x04,
    113     0x05,0x06,0x07,0x08,
    114     0x09,0x0a,0x0b,0x0c,
    115     0x0d,0x0e,0x0f,0x10,
    116     0x11,0x12,0x13,0x14,
    117     0x15,0x16,0x17,0x18,
    118     0x19,0x1a,0x1b,0x1c,
    119     0xba,0xbe,0xba,0xbe
    120 };
    121 #define eep24c64_test_data_len COUNTOF(eep24c64_test_data)
    122 
    123 /*
    124  * PD63000 init (test) data
    125  */
    126 STATIC unsigned char
    127 pd63000_test_data[] = {
    128     0x00,0xfe,0x07,0x0b,0x15, /* init power source 1 to min 37W */
    129     0x00,0x25,0x02,0x49,0x01,
    130     0xb8,0x01,0x4e,0x02,0x9d
    131 };
    132 #define pd63000_test_data_len COUNTOF(pd63000_test_data)
    133 
    134 /*
    135  * BCM59101 init (test) data
    136  */
    137 /* STATIC */ unsigned char
    138 bcm59101_test_data[] = {
    139     0x20,0x01,0xFF,0xFF,0xFF,
    140     0xFF,0xFF,0xFF,0xFF,0xFF,
    141     0xFF,0x18
    142 
    143 };
    144 
    145 #define bcm59101_test_data_len COUNTOF(bcm59101_test_data)
    146 
    147 /* Data: i2c_devices
    148  * Purpose: I2C device descriptor table.
    149  *          Devices are added to this table, along with their slave
    150  *          address, a string description, and their driver (if available).
    151  *
    152  * Note: The entry for the "MUX" (LPT0) must be the first entry in the list
    153  */
    154 #define	I2CDEV(_name, _num, _drv) {	\
    155 	I2C_##_name##_##_num,		\
    156 	I2C_##_name##_SADDR##_num,	\
    157 	&_soc_i2c_##_drv##_driver,	\
    158 	}
    159 #define	I2CDEVTD(_name, _num, _drv) {	\
    160 	I2C_##_name##_##_num,		\
    161 	I2C_##_name##_SADDR##_num,	\
    162 	&_soc_i2c_##_drv##_driver,	\
    163 	_drv##_test_data,		\
    164 	_drv##_test_data_len,		\
    165 	}
    166 
    167 STATIC i2c_device_t i2c_common_devices[] = {
    168     I2CDEV(LPT, 0, pcf8574),		/* MUX register, must be first */
    169     I2CDEVTD(NVRAM, 0, eep24c64),
    170     I2CDEV(XFP, 0, xfp),
    171     I2CDEV(PCIE, 0, pcie),
    172     I2CDEVTD(NVRAM, 1, eep24c64),
    173     I2CDEV(LM75, 4, lm75),
    174     I2CDEV(MAX664X, 0, max664x),
    175     I2CDEV(LM75, 0, lm75),
    176     I2CDEV(LM75, 1, lm75),
    177     I2CDEV(LM75, 2, lm75),
    178     I2CDEV(LM75, 3, lm75),
    179     I2CDEV(LM75, 5, lm75),
    180     I2CDEV(LM75, 6, lm75),
    181     I2CDEV(LM75, 7, lm75),
    182     I2CDEV(ADC, 0, max127),
    183     I2CDEV(ADC, 1, max127),
    184     I2CDEV(ADC, 2, max127),
    185     I2CDEV(ADC, 3, max127),
    186     I2CDEV(DAC, 0, ltc1427),
    187 #if 0
    188     I2CDEV(PLL, 0, w229b),
    189 #endif
    190     I2CDEV(LPT, 1, pcf8574),
    191     I2CDEV(LPT, 2, pcf8574),
    192     I2CDEV(LPT, 3, pcf8574),
    193     I2CDEV(LPT, 4, pcf8574),
    194 #ifdef SHADOW_SVK  /* Shares same IO addr */
    195     I2CDEV(IOP, 0, pca9505),
    196     I2CDEV(IOP, 1, pca9505),
    197 #else
    198     I2CDEV(LPT, 5, pcf8574),
    199     I2CDEV(LPT, 6, pcf8574),
    200 #endif
    201     I2CDEV(LPT, 7, pcf8574),
    202     I2CDEV(LCD, 0, lcd),
    203     I2CDEV(XPLL, 0, cy2239x),
    204     I2CDEV(XPLL, 1, cy2239x),
    205     I2CDEV(XPLL1, 0, cy22150),		/* should this be xpll, 1? */
    206     I2CDEVTD(POE, 0, pd63000),
    207     I2CDEV(POE, 1, ltc4258),
    208     I2CDEV(POE, 2, ltc4258),
    209     I2CDEV(POE, 3, ltc4258),
    210     I2CDEV(POE, 4, ltc4258),
    211     I2CDEV(POE, 5, ltc4258),
    212     I2CDEV(POE, 6, ltc4258),
    213     I2CDEVTD(POE, 7, bcm59101),
    214     I2CDEVTD(POE, 8, bcm59101),
    215     I2CDEVTD(POE, 9, bcm59101),
    216     I2CDEVTD(POE, 10, bcm59101),
    217     I2CDEV(MUX, 0, pca9548),             /* MUX device */
    218     I2CDEV(MUX, 3, pca9548),             /* MUX device */
    219     I2CDEV(MUX, 4, pca9548),             /* MUX device */
    220     I2CDEV(MUX, 5, pca9548),             /* MUX device */
    221     I2CDEV(MUX, 6, pca9548),             /* MUX device */
    222 #ifdef BCM_TOMAHAWK_SUPPORT
    223     I2CDEV(MUX, 70, pca9548),            /* MUX device */
    224 #endif /* BCM_TOMAHAWK_SUPPORT */
    225     I2CDEV(POT, 0, max5478),
    226     I2CDEV(PWCTRL, 0, adp4000),
    227     I2CDEV(PWCTRL, 2, adp4000),
    228     I2CDEV(LTC3880, 45, ltc3880),
    229     I2CDEV(LTC3882, 0, ltc3882),
    230     I2CDEV(LTC3882, 1, ltc3882),
    231     I2CDEV(LTC2974, 0, ltc2974),
    232     I2CDEV(LTC3880, 60, ltc3880),
    233     I2CDEV(LTC3880, 61, ltc3880),
    234     I2CDEV(LTC3880, 62, ltc3880),
    235     I2CDEV(LTC3880, 64, ltc3880),
    236     I2CDEV(LTC3880, 65, ltc3880),
    237     I2CDEV(LTM4676, 43, ltm4676),
    238 #ifdef BCM_TOMAHAWK_SUPPORT
    239     I2CDEV(LTC3880, 41, ltc3880),
    240     I2CDEV(LTC3880, 42, ltc3880),
    241     I2CDEV(LTC3880, 43, ltc3880),
    242     I2CDEV(LTC3880, 47, ltc3880),
    243     I2CDEV(LTC3882, 55, ltc3882),
    244     I2CDEV(LTC3882, 66, ltc3882),
    245     I2CDEV(LTC3882, 77, ltc3882),
    246 #endif /* BCM_TOMAHAWK_SUPPORT */
    247 };
    248 
    249 STATIC i2c_device_t i2c_56565_devices[] = {
    250     I2CDEV(LPT, 1, pcf8574),
    251     I2CDEVTD(NVRAM, 56, eep24c64),
    252     I2CDEV(LM63, 0, lm63),
    253     I2CDEV(MUX, 3, pca9548),
    254     I2CDEV(LTC3884, 42, ltc3884),
    255     I2CDEV(LTC3884, 43, ltc3884),
    256     I2CDEV(LTC3884, 46, ltc3884),
    257     I2CDEV(LTM4676, 47, ltm4676),
    258 };
    259 
    260 STATIC i2c_device_t i2c_56760_devices[] = {
    261     I2CDEV(LPT, 1, pcf8574),
    262     I2CDEV(LPT, 3, pcf8574),
    263     I2CDEVTD(NVRAM, 56, eep24c64),
    264     I2CDEV(LM63, 0, lm63),
    265     I2CDEV(MUX, 3, pca9548),
    266     I2CDEV(LTC3884, 42, ltc3884),
    267     I2CDEV(LTC3884, 43, ltc3884),
    268     I2CDEV(LTC3880, 45, ltc3880),
    269 };
    270 
    271 STATIC i2c_device_t i2c_56270_devices[] = {
    272     I2CDEV(LPT, 1, pcf8574),
    273     I2CDEV(MUX, 3, pca9548),
    274     I2CDEV(MUX, 4, pca9548),
    275     I2CDEVTD(NVRAM, 1, eep24c64),
    276     I2CDEV(LTC2974, 0, ltc2974),
    277 };
    278 
    279 STATIC i2c_device_t i2c_56272_devices[] = {
    280     I2CDEV(LPT, 1, pcf8574),
    281     I2CDEVTD(NVRAM, 1, eep24c64),
    282 };
    283 
    284 STATIC i2c_device_t i2c_56970_32_devices[] = {
    285     I2CDEV(LPT, 1, pcf8574),
    286     I2CDEV(MUX, 0, pca9548),
    287     I2CDEV(MUX, 3, pca9548),
    288     I2CDEV(MUX, 4, pca9548),
    289     I2CDEVTD(NVRAM, 1, eep24c64),
    290     I2CDEV(NCP81233, 0, pmbus),
    291     I2CDEV(LTC2974, 5C, ltc2974),
    292     I2CDEV(LTC3880, 62, ltc3880),
    293 };
    294 
    295 STATIC i2c_device_t i2c_56970_64_devices[] = {
    296     I2CDEV(LPT, 1, pcf8574),
    297     I2CDEV(MUX, 0, pca9548),
    298     I2CDEV(MUX, 3, pca9548),
    299     I2CDEV(MUX, 4, pca9548),
    300     I2CDEVTD(NVRAM, 1, eep24c64),
    301     I2CDEV(NCP81233, 0, pmbus),
    302     I2CDEV(LTC2974, 5C, ltc2974),
    303     I2CDEV(LTC3880, 62, ltc3880),
    304     I2CDEV(LTC3880, 61, ltc3880),
    305 };
    306 
    307 STATIC i2c_device_t i2c_56870_devices[] = {
    308     I2CDEV(LPT, 1, pcf8574), /* I2C address 0x27 */
    309     I2CDEV(MUX, 3, pca9548), /* I2C address 0x73 */
    310     I2CDEV(MUX, 4, pca9548), /* I2C address 0x74 */
    311     I2CDEVTD(NVRAM, 1, eep24c64), /* I2C address 0x54 */
    312     I2CDEV(NCP81233, 0, pmbus), /* I2C address 0x70 */
    313     I2CDEV(LTC2974, 5C, ltc2974),  /* I2C address 0x5C */
    314     I2CDEV(LTC3880, 62, ltc3880),  /* I2C address 0x62 */
    315 };
    316 
    317 STATIC i2c_device_t i2c_56670_devices[] = {
    318     I2CDEV(LPT, 1, pcf8574),/* I2C address 0x27 */
    319     I2CDEV(LPT, 3, pcf8574),/* I2C address 0x26 */
    320     I2CDEVTD(NVRAM, 56, eep24c64), /* I2C address 0x54 */
    321     I2CDEV(LM63, 0, lm63),
    322     I2CDEV(MUX, 3, pca9548),/* I2C address 0x73 */
    323     I2CDEV(LTC3884, 42, ltc3884),/* I2C address 0x42 */
    324     I2CDEV(LTC3884, 43, ltc3884), /* I2C address 0x43 */
    325     I2CDEV(LTC2974, 64, ltc2974),  /* I2C address 0x64 */ 
    326 };
    327 
    328 STATIC i2c_device_t i2c_56980_devices[] = {
    329     I2CDEV(LPT, 1, pcf8574), /* I2C address 0x27 (board ID) */
    330     I2CDEV(MUX, 3, pca9548), /* I2C address 0x73 (mux 3) */
    331     I2CDEV(MUX, 4, pca9548), /* I2C address 0x74 (mux 4) */
    332     I2CDEVTD(NVRAM, 1, eep24c64), /* I2C address 0x54 (EEPROM) */
    333     I2CDEV(MAX669X, 18, max669x),
    334     I2CDEV(MAX669X, 19, max669x),
    335     I2CDEV(NCP81233, 0, pmbus),
    336     I2CDEV(LTM4678, 40, ltm4678),
    337     I2CDEV(LTM4678, 41, ltm4678),
    338     I2CDEV(LTC2974, 5C, ltc2974),
    339     I2CDEV(ISL68127, 60, isl68127),
    340     I2CDEV(ISL68127, 61, isl68127),
    341 };
    342 
    343 STATIC i2c_device_t i2c_56370_devices[] = {
    344     I2CDEV(LPT, 1, pcf8574),
    345     I2CDEVTD(NVRAM, 1, eep24c64),
    346     I2CDEV(MUX, 3, pca9548),
    347     I2CDEV(LTC3884, 42, ltc3884),
    348     I2CDEV(LTC3884, 43, ltc3884),
    349     I2CDEV(LTC2974, 63, ltc2974),   
    350     I2CDEV(LTC2974, 64, ltc2974),      
    351 };
    352 
    353 
    354 STATIC i2c_device_t *i2c_devices = NULL;
    355 
    356 STATIC int num_i2c_devices = 0;
    357 
    358 #undef	I2CDEV
    359 #undef	I2CDEVTD
    360 
    361 static char *soc_i2c_saddr_to_string_table[0x80] = {
    362     /* 0X00 */ "Unknown",
    363     /* 0X01 */ "Unknown",
    364     /* 0X02 */ "Unknown",
    365     /* 0X03 */ "Unknown",
    366     /* 0X04 */ "Unknown",
    367     /* 0X05 */ "Unknown",
    368     /* 0X06 */ "Unknown",
    369     /* 0X07 */ "Unknown",
    370     /* 0X08 */ "Unknown",
    371     /* 0X09 */ "Unknown",
    372     /* 0X0A */ "Unknown",
    373     /* 0X0B */ "Unknown",
    374     /* 0X0C */ "Unknown",
    375     /* 0X0D */ "Unknown",
    376     /* 0X0E */ "Unknown",
    377     /* 0X0F */ "Unknown",
    378     /* 0X10 */ "Unknown",
    379     /* 0X11 */ "Unknown",
    380     /* 0X12 */ "Unknown",
    381     /* 0X13 */ "Unknown",
    382     /* 0X14 */ "Unknown",
    383     /* 0X15 */ "Unknown",
    384     /* 0X16 */ "Unknown",
    385     /* 0X17 */ "Unknown",
    386     /* 0X18 */ "MAX6695/MAX6696",
    387     /* 0X19 */ "MAX6695/MAX6696",
    388     /* 0X1A */ "Unknown",
    389     /* 0X1B */ "Unknown",
    390     /* 0X1C */ "Unknown",
    391     /* 0X1D */ "Unknown",
    392     /* 0X1E */ "Unknown",
    393     /* 0X1F */ "Unknown",
    394     /* 0X20 */ "lpt0: PCF8574 MUX control",
    395     /* 0X21 */ "lpt4: PCF8574/Linear Tech 4258 Powered Ethernet (POE)",
    396 #ifdef SHADOW_SVK
    397     /* 0X22 */ "iop1: PCA9505 I2C to 10Bit IO CNTL",
    398 #else
    399     /* 0X22 */ "lpt5: PCF8574/Linear Tech 4258 Powered Ethernet (POE)",
    400 #endif
    401     /* 0X23 */ "lpt2: PCF8574/Linear Tech 4258 Powered Ethernet (POE)",
    402 #ifdef SHADOW_SVK
    403     /* 0X24 */ "iop0: PCA9505 I2C to 10Bit IO CNTL",
    404 #else
    405     /* 0X24 */ "lpt6: PCF8574/Linear Tech 4258 Powered Ethernet (POE)",
    406 #endif
    407     /* 0X25 */ "lpt7: PCF8574/Linear Tech 4258 Powered Ethernet (POE)",
    408     /* 0X26 */ "lpt3: PCF8574/Linear Tech 4258 Powered Ethernet (POE)",
    409     /* 0X27 */ "lpt1: PCF8574 or PCA9554 Baseboard ID",
    410     /* 0X28 */ "adc0: MAX127 A/D Converter",
    411     /* 0X29 */ "adc1: MAX127 A/D Converter",
    412     /* 0X2A */ "adc2: MAX127 A/D Converter",
    413     /* 0X2B */ "adc3: MAX127 A/D Converter",
    414     /* 0X2C */ "dac0: Linear Technology LTC1427 DAC",
    415     /* 0X2D */ "pot0: Maxim 5478 Potentiometer",
    416     /* 0X2E */ "lcd0: Matrix Orbital LCD/MAX6653",
    417     /* 0X2F */ "ZM7XXX",
    418     /* 0X30 */ "Unknown",
    419     /* 0X31 */ "Unknown",
    420     /* 0X32 */ "Unknown",
    421     /* 0X33 */ "Unknown",
    422     /* 0X34 */ "Unknown",
    423     /* 0X35 */ "Unknown",
    424     /* 0X36 */ "Unknown",
    425     /* 0X37 */ "Unknown",
    426     /* 0X38 */ "poe0: PowerDsine 63000 PoE Microcontroller",
    427     /* 0X39 */ "Unknown",
    428     /* 0X3A */ "Unknown",
    429     /* 0X3B */ "Unknown",
    430     /* 0X3C */ "Unknown",
    431     /* 0X3D */ "Unknown",
    432     /* 0X3E */ "Unknown",
    433     /* 0X3F */ "Unknown",
    434     /* 0X40 */ "Unknown",
    435     /* 0X41 */ I2C_LTC3880_41": LTC 3880 Voltage Controller",
    436     /* 0X42 */ I2C_LTC3880_42" or I2C_LTC3884_42: LTC 3880/3884 Voltage Controller",
    437     /* 0X43 */ "I2C_LTM4676_43 or I2C_LTC3880_43 or I2C_LTC3884_43: LTC 3880/3884 Voltage Controller",
    438     /* 0X44 */ "pcie0:",
    439     /* 0X45 */ "LTC 3880 Voltage Controller",
    440     /* 0X46 */ "LTC 3882-0 Voltage Controller or LTC 3884 Voltage Controller",
    441     /* 0X47 */ "LTC 3882-1 or I2C_LTC3880_47 or I2C_LTM4676_47 Voltage Controller",
    442     /* 0X48 */ "temp0: LM75 Temperature Sensor",
    443     /* 0X49 */ "temp1: LM75 Temperature Sensor",
    444     /* 0X4A */ "temp2: LM75 Temperature Sensor",
    445     /* 0X4B */ "temp3: LM75 Temperature Sensor",
    446     /* 0X4C */ "temp0: LM63 Temperature Sensor or temp4: LM75 or MAX664x Temperature Sensor",
    447     /* 0X4D */ "temp5: LM75 Temperature Sensor",
    448     /* 0X4E */ "temp6: LM75 Temperature Sensor",
    449     /* 0X4F */ "temp7: LM75 Temperature Sensor",
    450     /* 0X50 */ "EEPROM/nvram0/XFP/POE_DB0/CXP/QSFP",
    451     /* 0X51 */ "Unknown",
    452     /* 0X52 */ "Unknown",
    453     /* 0X53 */ "Unknown",
    454     /* 0X54 */ "nvram1:/CXP ",
    455     /* 0X55 */ "I2C_LTC3882_55: LTC 3882 Voltage Controller",
    456     /* 0X56 */ "nvram_56",
    457     /* 0X57 */ "Unknown",
    458     /* 0X58 */ "POE_DB1",
    459     /* 0X59 */ "Unknown",
    460     /* 0X5A */ "Unknown",
    461     /* 0X5B */ "Unknown",
    462     /* 0X5C */ "LTC 2974",
    463     /* 0X5D */ "Unknown",
    464     /* 0X5E */ "Unknown",
    465     /* 0X5F */ "Unknown",
    466     /* 0X60 */ I2C_LTC3880_60": LTC3880 DC/DC Controller",
    467     /* 0X61 */ I2C_LTC3880_61": LTC3880 DC/DC Controller",
    468     /* 0X62 */ "ADP4200-1 or "I2C_LTC3880_62": LTC3880 DC/DC Controller",
    469     /* 0X63 */ "Unknown",
    470     /* 0X64 */ "LTC 2974 or "I2C_LTC3880_64": LTC3880 DC/DC Controller",
    471     /* 0X65 */ "ADP4000-0 or "I2C_LTC3880_65": LTC3880 DC/DC Controller",
    472     /* 0X66 */ "I2C_LTC3882_66: LTC 3882 Voltage Controller",
    473     /* 0X67 */ "Unknown",
    474     /* 0X68 */ "Unknown",
    475     /* 0X69 */ "pll0: Cypress W229B/W311 Clock Chip",
    476     /* 0X6A */ "clk0: Cypress W2239x clock Chip",
    477     /* 0X6B */ "clk0: Cypress W22150 clock Chip",
    478     /* 0X6C */ "Unknown",
    479     /* 0X6D */ "Unknown",
    480     /* 0X6E */ "Unknown",
    481     /* 0X6F */ "Unknown",
    482     /* 0X70 */ "PCA9548 MUX or NCP81233-0",
    483     /* 0X71 */ "PCA9548 MUX",
    484     /* 0X72 */ "PCA9548 MUX",
    485     /* 0X73 */ "PCA9548 MUX",
    486     /* 0X74 */ "PCA9548 MUX",
    487     /* 0X75 */ "PCA9548 MUX",
    488 #ifdef SHADOW_SVK
    489     /* 0X76 */ "mux6: PCA9548 i2c Switch",
    490     /* 0X77 */ "mux7: PCA9548 i2c Switch",
    491 #else
    492     /* 0X76 */ "PCA9548 MUX",
    493     /* 0X77 */ "PCA9548 MUX or I2C_LTC3882_77: LTC 3882 Voltage Controller",
    494 #endif
    495     /* 0X78 */ "Unknown",
    496     /* 0X79 */ "Unknown",
    497     /* 0X7A */ "Unknown",
    498     /* 0X7B */ "Unknown",
    499     /* 0X7C */ "Unknown",
    500     /* 0X7D */ "Unknown",
    501     /* 0X7E */ "Unknown",
    502     /* 0X7F */ "Unknown"
    503 };
    504 
    505 char *soc_i2c_saddr_to_string(int unit, i2c_saddr_t saddr)
    506 {
    507     return ((unit < 0) ? "" : soc_i2c_saddr_to_string_table[saddr]);
    508 }
    509 
    510 /*
    511  * Function: soc_i2c_device_present
    512  * Purpose: Probe the I2C bus using saddr, report if a device responds.
    513  *          The I2C bus is released upon return.
    514  *          No further action is taken.
    515  *
    516  * Parameters:
    517  *    unit  - StrataSwitch device number or I2C bus number
    518  *    saddr - I2C slave address
    519  *
    520  * Return:
    521  *     SOC_E_NONE - An I2C device responds at the indicated saddr.
    522  *     otherwise  - No I2C response at the indicated saddr, or I/O error.
    523  */
    524 int
    525 soc_i2c_device_present(int unit, i2c_saddr_t saddr)
    526 {
    527   int rv;
    528 
    529 #ifdef BCM_IPROC_SUPPORT
    530     if(soc_feature(unit, soc_feature_eeprom_iproc) &&
    531        ((saddr == I2C_NVRAM_SADDR0) || (saddr == I2C_NVRAM_SADDR1))) {
    532         if ((rv = iproc_smbus_quick_command(unit, saddr)) == SOC_E_NONE) {
    533             /* An ACK was received, there's an I2C device at saddr */
    534             LOG_INFO(BSL_LS_SOC_I2C,
    535                      (BSL_META_U(unit,
    536                                  "unit %d i2c 0x%x: detected device\n"),
    537                       unit, saddr));
    538         }
    539         return rv;
    540     }
    541 #endif
    542 #ifdef BCM_CMICM_SUPPORT
    543     if(soc_feature(unit, soc_feature_cmicm)) {
    544         if ((rv = smbus_quick_command(unit, saddr)) == SOC_E_NONE) {
    545             /* An ACK was received, there's an I2C device at saddr */
    546             LOG_INFO(BSL_LS_SOC_I2C,
    547                      (BSL_META_U(unit,
    548                                  "unit %d i2c 0x%x: detected device\n"),
    549                       unit, saddr));
    550         }
    551         return rv;
    552     }
    553 #endif
    554 #ifdef BCM_CMICX_SUPPORT
    555     if(soc_feature(unit, soc_feature_cmicx)) {
    556         if ((rv = cmicx_smbus_quick_command(unit, saddr)) == SOC_E_NONE) {
    557             /* An ACK was received, there's an I2C device at saddr */
    558             LOG_INFO(BSL_LS_SOC_I2C,
    559                      (BSL_META_U(unit,
    560                                  "unit %d i2c 0x%x: detected device\n"),
    561                       unit, saddr));
    562         }
    563         return rv;
    564     }
    565 #endif
    566   if ((rv=soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr))) == SOC_E_NONE) {
    567     /* An ACK was received, there's an I2C device at saddr */
    568       LOG_INFO(BSL_LS_SOC_I2C,
    569                (BSL_META_U(unit,
    570                            "unit %d i2c 0x%x: detected device\n"),
    571                 unit, saddr));
    572       /* Release the I2C bus */
    573       soc_i2c_stop(unit);
    574   }
    575   return rv;
    576 }
    577 
    578 
    579 static i2c_device_t *i2c_custom_devices[SOC_MAX_NUM_DEVICES][MAX_I2C_DEVICES];
    580 static uint8 i2c_custome_dev_tbl_init = 0;
    581 static uint8 switch_to_i2c_custom_dev_tbl[SOC_MAX_NUM_DEVICES];
    582 static int num_custom_i2c_devices[SOC_MAX_NUM_DEVICES];
    583 #define I2C_DEV_DRV(_drv_name)   &_soc_i2c_##_drv_name##_driver
    584 
    585 typedef struct i2c_driver_map_info_s {
    586     char *drv_name;
    587     i2c_driver_t *drv;
    588 } i2c_driver_map_info_t;
    589 
    590 static const i2c_driver_map_info_t driver_mapping_info[] =
    591 {
    592     {"lm63", I2C_DEV_DRV(lm63)},
    593     {"lm75", I2C_DEV_DRV(lm75)},
    594     {"max664x", I2C_DEV_DRV(max664x)},
    595     {"max127", I2C_DEV_DRV(max127)},
    596     {"w229b", I2C_DEV_DRV(w229b)},
    597     {"eep24c64", I2C_DEV_DRV(eep24c64)},
    598     {"xfp", I2C_DEV_DRV(xfp)},
    599     {"pcie", I2C_DEV_DRV(pcie)},
    600     {"pcf8574", I2C_DEV_DRV(pcf8574)},
    601     {"ltc1427", I2C_DEV_DRV(ltc1427)},
    602     {"lcd", I2C_DEV_DRV(lcd)},
    603     {"cy2239x", I2C_DEV_DRV(cy2239x)},
    604     {"cy22150", I2C_DEV_DRV(cy22150)},
    605     {"ltc4258", I2C_DEV_DRV(ltc4258)},
    606     {"pd63000", I2C_DEV_DRV(pd63000)},
    607     {"max5478", I2C_DEV_DRV(max5478)},
    608     {"bcm59101", I2C_DEV_DRV(bcm59101)},
    609     {"pca9548", I2C_DEV_DRV(pca9548)},
    610     {"adp4000", I2C_DEV_DRV(adp4000)},
    611     {"cxp", I2C_DEV_DRV(cxp)},
    612     {"ltc3880", I2C_DEV_DRV(ltc3880)},
    613     {"ltc3884", I2C_DEV_DRV(ltc3884)},
    614     {"ltc2974", I2C_DEV_DRV(ltc2974)},
    615     {"ltm4676", I2C_DEV_DRV(ltm4676)},
    616     {"pmbus", I2C_DEV_DRV(pmbus)},
    617 };
    618 
    619 int
    620 soc_i2c_dev_driver_get(int unit, char *drv_name, i2c_driver_t **drv)
    621 {
    622     int i;
    623 
    624     for (i = 0; COUNTOF(driver_mapping_info); i++) {
    625         if (!sal_strcmp(drv_name, driver_mapping_info[i].drv_name)) {
    626             *drv = driver_mapping_info[i].drv;
    627             return SOC_E_NONE;
    628         }
    629     }
    630     return SOC_E_NOT_FOUND;
    631 }
    632 
    633 /*
    634  * Check if the device is ever added in custom i2c device descriptor -
    635  * i2c_custom_devices.
    636  */
    637 static int
    638 soc_i2c_custom_device_search(int unit, i2c_device_t *device, int *tbl_idx)
    639 {
    640     i2c_device_t *i2c_dev;
    641     int i;
    642 
    643     if ((device == NULL) || (tbl_idx == NULL)) {
    644         return SOC_E_PARAM;
    645     }
    646     for (i = 0; i < MAX_I2C_DEVICES; i++) {
    647         i2c_dev = i2c_custom_devices[unit][i];
    648         if ((i2c_dev != NULL) && (i2c_dev->saddr == device->saddr)){
    649             /*
    650              * Probably have multiple same devices on the system.
    651              * Check saddr since this should be unique.
    652              */
    653             *tbl_idx = i;
    654             return SOC_E_NONE;
    655         }
    656     }
    657     return SOC_E_NOT_FOUND;
    658 }
    659 
    660 /* Add device to custom i2c device descriptor */
    661 int
    662 soc_i2c_custom_device_add(int unit, i2c_device_t *device)
    663 {
    664     int u, i, tbl_idx;
    665     int rv = SOC_E_UNAVAIL;
    666 
    667     if (!i2c_custome_dev_tbl_init) {
    668         for (u = 0; u < SOC_MAX_NUM_DEVICES; u++) {
    669             for (i = 0; i < MAX_I2C_DEVICES; i++) {
    670                 i2c_custom_devices[u][i] = NULL;
    671             }
    672             switch_to_i2c_custom_dev_tbl[u] = 0;
    673             num_custom_i2c_devices[u] = 0;
    674         }
    675         i2c_custome_dev_tbl_init = 1;
    676     }
    677     tbl_idx = 0;
    678     rv = soc_i2c_custom_device_search(unit, device, &tbl_idx);
    679     if (rv != SOC_E_NOT_FOUND) {
    680         return rv;
    681     }
    682 
    683     for (i = 0; i < MAX_I2C_DEVICES; i++) {
    684         if (i2c_custom_devices[unit][i] == NULL) {
    685             i2c_custom_devices[unit][i] =
    686                 sal_alloc(sizeof(i2c_device_t),"custom i2c dev");
    687             if (i2c_custom_devices[unit][i] == NULL) {
    688                 return SOC_E_MEMORY;
    689             }
    690             sal_memcpy(i2c_custom_devices[unit][i], device,
    691                        sizeof(i2c_device_t));
    692             rv = SOC_E_NONE;
    693             num_custom_i2c_devices[unit]++;
    694             break;
    695         }
    696     }
    697     return rv;
    698 }
    699 
    700 /* Remove device from custom i2c device descriptor. */
    701 int
    702 soc_i2c_custom_device_remove(int unit, i2c_device_t *device)
    703 {
    704     int tbl_idx, i;
    705     i2c_device_t *i2c_dev;
    706 
    707     SOC_IF_ERROR_RETURN(soc_i2c_custom_device_search(unit, device, &tbl_idx));
    708 
    709     i2c_dev = i2c_custom_devices[unit][tbl_idx];
    710     if (i2c_dev->devname != NULL) {
    711         sal_free(i2c_dev->devname);
    712         i2c_dev->devname = NULL;
    713     }
    714     sal_free(i2c_dev);
    715     i2c_custom_devices[unit][tbl_idx] = NULL;
    716 
    717     for (i = tbl_idx; i < (MAX_I2C_DEVICES - 1); i++) {
    718         if (i2c_custom_devices[unit][i + 1] != NULL) {
    719             i2c_custom_devices[unit][i] = i2c_custom_devices[unit][i + 1];
    720         }
    721     }
    722     num_custom_i2c_devices[unit]--;
    723     if (num_custom_i2c_devices[unit] == 0) {
    724         if (i2c_devices != NULL) {
    725             sal_free(i2c_devices);
    726             i2c_devices = NULL;
    727         }
    728         switch_to_i2c_custom_dev_tbl[unit] = 0;
    729     }
    730     return SOC_E_NONE;
    731 }
    732 
    733 typedef struct _soc_i2c_probe_info_s {
    734     int			devid;
    735     int			devid_found;
    736     int			devices_found;
    737     soc_i2c_bus_t	*i2cbus;
    738     int                 i2c_nvram_skip;
    739     int                 i2c_hclk_skip;
    740     int                 i2c_poe_power;
    741     int                 i2c_muxed_devid_count[MAX_I2C_DEVICES];
    742     int                 i2c_mux_stack[MAX_I2C_DEVICES];
    743     int                 i2c_mux_stack_depth;
    744 } _soc_i2c_probe_info_t;
    745 
    746 /*
    747  * Function: _soc_i2c_probe_device
    748  * Purpose: Internal probing of a particular I2C device.
    749  *
    750  * Parameters:
    751  *	unit - StrataSwitch device number or I2C bus number
    752  *	muxed - I2C device search beyond one or more MUX's
    753  *      i2c_probe_info - data structure of I2C probe parameters
    754  *
    755  * Return:
    756  *	SOC_E_***
    757  */
    758 int
    759 _soc_i2c_probe_device(int unit, int muxed,
    760                       _soc_i2c_probe_info_t *i2c_probe_info)
    761 {
    762     int	devid = i2c_probe_info->devid;
    763     int rv = SOC_E_NOT_FOUND;
    764     int mux_stack_index;
    765     i2c_dev_init_func_t	load;
    766     char		*devdesc;
    767 
    768     for (mux_stack_index = 0;
    769          mux_stack_index < i2c_probe_info->i2c_mux_stack_depth;
    770          mux_stack_index++) {
    771         if (i2c_probe_info->i2c_mux_stack[mux_stack_index] == devid) {
    772             /* This is a previous MUX in our tree, skip */
    773             return rv;
    774         }
    775     }
    776 
    777 #ifdef BCM_TOMAHAWK_SUPPORT
    778     if (SOC_IS_TOMAHAWK(unit)) {
    779         if (sal_strcmp(i2c_devices[devid].devname, "pwctrl2") == 0) {
    780             i2c_devices[devid].saddr = I2C_PWCTRL_2_SADDR60;
    781         }
    782     }
    783 #endif /* BCM_TOMAHAWK_SUPPORT */
    784 
    785     if (muxed &&
    786         (NULL != i2c_probe_info->i2cbus->devs[devid]) &&
    787         (0 == i2c_probe_info->i2c_muxed_devid_count[devid])) {
    788         /* Top level device, don't probe again during MUX scan. */
    789         return rv;
    790     }
    791     if ((!i2c_probe_info->i2c_poe_power) && /* Not POE */
    792             ((i2c_devices[devid].driver == &_soc_i2c_pd63000_driver) ||
    793              (i2c_devices[devid].driver == &_soc_i2c_bcm59101_driver))) {
    794             return rv;
    795     } else if (((i2c_probe_info->i2c_poe_power) ||
    796              (i2c_probe_info->i2c_nvram_skip)) &&
    797             (i2c_devices[devid].saddr == I2C_NVRAM_SADDR0) &&
    798             (i2c_devices[devid].driver == &_soc_i2c_eep24c64_driver)) {
    799             /* check property and skip NVRAM */
    800             return rv;
    801     } else if (((i2c_probe_info->i2c_poe_power) ||
    802                 (!i2c_probe_info->i2c_nvram_skip)) &&
    803                (i2c_devices[devid].saddr == I2C_XFP_SADDR0) &&
    804                (i2c_devices[devid].driver == &_soc_i2c_xfp_driver)) {
    805         /* check property and skip XFP */
    806         return rv;
    807     } else if ((i2c_probe_info->i2c_hclk_skip) &&
    808                ((i2c_devices[devid].saddr == I2C_LPT_SADDR2) ||
    809                 (i2c_devices[devid].saddr == I2C_LPT_SADDR3)) &&
    810                (i2c_devices[devid].driver == &_soc_i2c_pcf8574_driver)) {
    811         /* check property and skip HCLK */
    812         return rv;
    813     } else if ((!i2c_probe_info->i2c_hclk_skip) &&
    814                ((i2c_devices[devid].saddr == I2C_POE_SADDR2) ||
    815                 (i2c_devices[devid].saddr == I2C_POE_SADDR3) ||
    816                 (i2c_devices[devid].saddr == I2C_POE_SADDR4) ||
    817                 (i2c_devices[devid].saddr == I2C_POE_SADDR6)) &&
    818                (i2c_devices[devid].driver == &_soc_i2c_ltc4258_driver)) {
    819         /* check property and skip POE */
    820         return rv;
    821     } else if ((i2c_probe_info->i2c_poe_power) &&
    822                (i2c_devices[devid].saddr == I2C_POE_SADDR0) &&
    823                (i2c_devices[devid].driver == &_soc_i2c_pd63000_driver)) {
    824         /* check property and set init power level */
    825         pd63000_test_data[6] = 0x64;   /* set power level to 100W */
    826         pd63000_test_data[8] = 0x39;   /* set max volt to 56.9V */
    827         pd63000_test_data[10] = 0xb7;  /* set min volt to 43.9V */
    828         pd63000_test_data[11] = 0x13;  /* set delta, guard band */
    829         pd63000_test_data[14] = 0xdd;  /* update checksum */
    830     }
    831 
    832     if (SOC_E_NONE ==
    833         soc_i2c_device_present(unit, i2c_devices[devid].saddr)) {
    834 #ifdef BCM_GREYHOUND_SUPPORT
    835         if (SOC_IS_GREYHOUND(unit)) {
    836             int check_devs = 0;
    837             char *board_name = soc_property_get_str(unit, spn_BOARD_NAME);
    838 
    839             if (board_name != NULL) {
    840                 if ((sal_strcmp(board_name, "BCM953411K") == 0) ||
    841                         (sal_strcmp(board_name, "BCM953416K") == 0)) {
    842                     check_devs = 5;
    843                 }
    844                 else if (sal_strcmp(board_name, "BCM953406K") == 0) {
    845                     check_devs = 4;
    846                 }
    847 
    848                 /* filter the pre-defined devices which addr are confict to */
    849                 /* the ones on GH SVK board */
    850                 if (check_devs > 0) {
    851                     if (i2c_devices[devid].driver != &_soc_i2c_ltc3880_driver) {
    852                         if ((i2c_devices[devid].saddr == I2C_LTC3880_SADDR60) ||
    853                                 (i2c_devices[devid].saddr == I2C_LTC3880_SADDR61) ||
    854                                 (i2c_devices[devid].saddr == I2C_LTC3880_SADDR62) ||
    855                                 (i2c_devices[devid].saddr == I2C_LTC3880_SADDR64)) {
    856                             return SOC_E_NOT_FOUND;
    857                         }
    858                         if (check_devs > 4) {
    859                             if (i2c_devices[devid].saddr == I2C_LTC3880_SADDR65) {
    860                                 return SOC_E_NOT_FOUND;
    861                             }
    862                         }
    863                     }
    864                 }
    865             }
    866         }
    867 #endif
    868 
    869         /* An ACK was received, there's a device at this SADDR.      */
    870         /* We infer the device type solely by its I2C slave address. */
    871 
    872         LOG_INFO(BSL_LS_SOC_I2C,
    873                  (BSL_META_U(unit,
    874                              "unit %d i2c 0x%x: found %s: %s\n"),
    875                   unit,
    876                   i2c_devices[devid].saddr,
    877                   i2c_devices[devid].devname,
    878                   i2c_devices[devid].desc ?
    879                   i2c_devices[devid].desc : ""));
    880 
    881         /* Load the device driver */
    882         i2c_probe_info->i2cbus->devs[devid] = &i2c_devices[devid];
    883 
    884         /* Else, if the device is beyond one or more MUX's, then we
    885          * need to check it is present and initialize each time
    886          * it is found.
    887          */
    888 
    889         /* set flags, device id, hook up bus, etc  */
    890         if (i2c_devices[devid].driver) {
    891             i2c_devices[devid].driver->flags |= I2C_DEV_OK;
    892             i2c_devices[devid].driver->flags |= I2C_REG_STATIC;
    893             i2c_devices[devid].driver->devno = devid;
    894         }
    895 
    896         /* Load device if init function exists */
    897 
    898         load = i2c_devices[devid].driver->load;
    899         if (load) {
    900             if ((rv = load(unit,
    901                            devid,
    902                            i2c_devices[devid].testdata,
    903                            i2c_devices[devid].testlen)) < 0) {
    904                 LOG_INFO(BSL_LS_SOC_I2C,
    905                          (BSL_META_U(unit,
    906                                      "unit %d i2c 0x%x: init failed %s - %s\n"),
    907                           unit,
    908                           i2c_devices[devid].saddr,
    909                           i2c_devices[devid].devname,
    910                           soc_errmsg(rv)));
    911             } else {
    912                 LOG_INFO(BSL_LS_SOC_I2C,
    913                          (BSL_META_U(unit,
    914                                      "unit %d i2c: Loaded driver for 0x%02x - %s\n"),
    915                           unit, devid, i2c_devices[devid].devname));
    916            }
    917            if ((rv == SOC_E_NOT_FOUND) && 
    918                 ((i2c_devices[devid].driver == &_soc_i2c_ltc3880_driver) ||
    919                 (i2c_devices[devid].driver == &_soc_i2c_ltc3882_driver) ||
    920                 (i2c_devices[devid].driver == &_soc_i2c_ltc3884_driver))) {
    921                 /* Not loading the expected device driver, unset device driver */
    922                 i2c_probe_info->i2cbus->devs[devid] = NULL;
    923                 return rv;
    924            }
    925         }
    926         soc_i2c_devdesc_get(unit, devid, &devdesc);
    927         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    928                     (BSL_META_U(unit,
    929                                 "unit %d i2c 0x%x %s: %s\n"),
    930                      unit,
    931                      i2c_devices[devid].saddr,
    932                      i2c_devices[devid].devname,
    933                      devdesc));
    934 
    935         /* Only count a device type once, but each device instance */
    936         i2c_probe_info->devices_found += 1;
    937         if (!muxed){
    938             i2c_probe_info->devid_found += 1;
    939         } else {
    940             if (0 == i2c_probe_info->i2c_muxed_devid_count[devid]) {
    941                 i2c_probe_info->devid_found += 1;
    942             }
    943             i2c_probe_info->i2c_muxed_devid_count[devid] += 1;
    944         }
    945         rv = SOC_E_EXISTS;
    946     } else if (!muxed) {  /* Don't clear info when scanning beyond MUX's */
    947         /* I2C device not present */
    948         i2c_probe_info->i2cbus->devs[devid] = NULL;
    949     }
    950     return rv;
    951 }
    952 
    953 /*
    954  * Function: _soc_i2c_probe_mux
    955  * Purpose: Internal probing of a given I2C MUX.
    956  *
    957  * Parameters:
    958  *	unit - StrataSwitch device number or I2C bus number
    959  *      mux_devid_range - I2C device ID for MUX to scan, -1 for all
    960  *      i2c_probe_info - data structre of I2C probe parameters
    961  *
    962  * Return:
    963  *	SOC_E_***
    964  */
    965 int
    966 _soc_i2c_probe_mux(int unit, int mux_devid_range,
    967                    _soc_i2c_probe_info_t *i2c_probe_info)
    968 {
    969     int			devid, mux_devid;
    970     int			mux_channel;
    971     int                 rv = SOC_E_NONE;
    972     uint8               mux_data;
    973     int                 mux_devid_min, mux_devid_max;
    974 
    975     if (mux_devid_range < 0) {
    976         mux_devid_min = 0;
    977         mux_devid_max = num_i2c_devices - 1;
    978     } else {
    979         mux_devid_min = mux_devid_range;
    980         mux_devid_max = mux_devid_range;
    981     }
    982 
    983     /* Now scan down the MUX tree */
    984     for (mux_devid = mux_devid_min;
    985          mux_devid <= mux_devid_max;
    986          mux_devid++) {
    987         if (i2c_devices[mux_devid].driver != &_soc_i2c_pca9548_driver) {
    988             /* Only the MUX's are interesting here. */
    989             continue;
    990         }
    991         if (NULL == i2c_probe_info->i2cbus->devs[mux_devid]) {
    992             /* We didn't find a MUX of this type */
    993             continue;
    994         }
    995 
    996         if ((0 == i2c_probe_info->i2c_mux_stack_depth) && /* Top level */
    997             (0 != i2c_probe_info->i2c_muxed_devid_count[mux_devid])) {
    998             /* We found this MUX type at a lower level of the tree */
    999             continue;
   1000         }
   1001         LOG_INFO(BSL_LS_SOC_I2C,
   1002                  (BSL_META_U(unit,
   1003                              "unit %d i2c: Detected MUX 0x%02x - %s\n"),
   1004                   unit, mux_devid,
   1005                   i2c_devices[mux_devid].devname));
   1006         for (mux_channel = 0; mux_channel < PCA9548_CHANNEL_NUM;
   1007              mux_channel++) {
   1008             /* Set the channel so we can probe beyond it */
   1009             mux_data = (1 << mux_channel);
   1010             if ((rv = i2c_devices[mux_devid].driver->write(unit, mux_devid,
   1011                                          0, &mux_data, 1)) < 0) {
   1012                 LOG_INFO(BSL_LS_SOC_I2C,
   1013                          (BSL_META_U(unit,
   1014                                      "unit %d i2c: Could not assign channel %d to %s\n"),
   1015                           unit, mux_channel,
   1016                           i2c_devices[mux_devid].devname));
   1017                 return rv;
   1018             }
   1019             LOG_INFO(BSL_LS_SOC_I2C,
   1020                      (BSL_META_U(unit,
   1021                                  "unit %d i2c: Set channel %d of MUX 0x%02x - %s\n"),
   1022                       unit, mux_channel, mux_devid,
   1023                       i2c_devices[mux_devid].devname));
   1024             for (devid = 0; devid < num_i2c_devices; devid++) {
   1025                 i2c_probe_info->devid = devid;
   1026                 rv = _soc_i2c_probe_device(unit, TRUE, i2c_probe_info);
   1027                 if (SOC_E_EXISTS == rv) {
   1028                     /* Is it a MUX? Recurse! */
   1029                     if (i2c_devices[devid].driver ==
   1030                         &_soc_i2c_pca9548_driver) {
   1031                         /* Record MUX stack to get here */
   1032                         i2c_probe_info->i2c_mux_stack[i2c_probe_info->i2c_mux_stack_depth] = devid;
   1033                         i2c_probe_info->i2c_mux_stack_depth++;
   1034                         rv = _soc_i2c_probe_mux(unit, devid,
   1035                                                 i2c_probe_info);
   1036                         if (SOC_FAILURE(rv)) {
   1037                             /* Access error */
   1038                             return rv;
   1039                         }
   1040                     }
   1041                     rv = SOC_E_NONE;
   1042                 } else if ((SOC_E_NOT_FOUND == rv) || (SOC_E_INIT == rv)) {
   1043                     /* No problem */
   1044                     rv = SOC_E_NONE;
   1045                 } else if (SOC_FAILURE(rv)) {
   1046                     /* Access error */
   1047                     return rv;
   1048                 }
   1049             }
   1050         }
   1051 
   1052         /* Restore default channel 0 on the MUX now that
   1053          * the probe is complete */
   1054         mux_channel = 0;
   1055         mux_data = (1 << mux_channel);
   1056         if ((rv = i2c_devices[mux_devid].driver->write(unit, mux_devid,
   1057                                                        0, &mux_data, 1)) < 0) {
   1058             LOG_INFO(BSL_LS_SOC_I2C,
   1059                      (BSL_META_U(unit,
   1060                                  "unit %d i2c: Could not assign channel %d to %s\n"),
   1061                       unit, mux_channel,
   1062                       i2c_devices[mux_devid].devname));
   1063             return rv;
   1064         }
   1065     }
   1066 
   1067     i2c_probe_info->i2c_mux_stack_depth--;
   1068     i2c_probe_info->i2c_mux_stack[i2c_probe_info->i2c_mux_stack_depth] = -1;
   1069     return rv;
   1070 }
   1071 
   1072 /*
   1073  * Function: soc_i2c_probe
   1074  * Purpose: Probe I2C devices on bus, report devices found.
   1075  *          This routine will walk through our internal I2C device driver
   1076  *          tables, attempt to find the device on the I2C bus, and if
   1077  *          successful, register a device driver for that device.
   1078  *
   1079  *          This allows for the device to be used in an API context as
   1080  *          when the devices are found, the device driver table is filled
   1081  *          with the correct entries for that device (r/w function, etc).
   1082  *
   1083  * Parameters:
   1084  *	unit - StrataSwitch device number or I2C bus number
   1085  *
   1086  * Return:
   1087  *	count of found devices or SOC_E_***
   1088  */
   1089 int
   1090 soc_i2c_probe(int unit)
   1091 {
   1092     _soc_i2c_probe_info_t i2c_probe_info;
   1093     int			devid;
   1094     int         rv;
   1095     int			mux_devid;
   1096     uint8       mux_data, board_id;
   1097     uint8       *data;
   1098 
   1099     /* Make sure that we're already attached, or go get attached */
   1100     if (!soc_i2c_is_attached(unit)) {
   1101 	return soc_i2c_attach(unit, 0, 0);
   1102     }
   1103 
   1104     if (num_custom_i2c_devices[unit]) {
   1105         if ((i2c_devices != NULL) && switch_to_i2c_custom_dev_tbl[unit]) {
   1106             sal_free(i2c_devices);
   1107             i2c_devices = NULL;
   1108         }
   1109         i2c_devices = sal_alloc(sizeof(i2c_device_t) *
   1110                                 num_custom_i2c_devices[unit],
   1111                                 "custome i2c devices descriptor");
   1112         if (i2c_devices == NULL) {
   1113             return SOC_E_MEMORY;
   1114         }
   1115         sal_memset(i2c_devices, 0,
   1116                    sizeof(i2c_device_t) * num_custom_i2c_devices[unit]);
   1117         for (devid = 0; devid < num_custom_i2c_devices[unit]; devid++) {
   1118             sal_memcpy(&i2c_devices[devid], i2c_custom_devices[unit][devid],
   1119                        sizeof(i2c_device_t));
   1120         }
   1121         switch_to_i2c_custom_dev_tbl[unit] = 1;
   1122         num_i2c_devices = num_custom_i2c_devices[unit];
   1123     } else {
   1124         /* For 56560K, 56760K, 56565K read the Board ID directly before probing
   1125          * and load their respective device descriptor tables.
   1126          * This is a new approach to avoid conflicts with other boards
   1127          * which may have different I2C devices at the same slave address.
   1128          */
   1129         data = &board_id;
   1130         (void)soc_i2c_read_byte(unit, I2C_LPT_SADDR1, data);
   1131         LOG_INFO(BSL_LS_SOC_I2C,
   1132                  (BSL_META_U(unit,
   1133                              "I2C board ID 0x%x\n"),
   1134                   board_id ));
   1135         switch (board_id) {
   1136             case 0x94: i2c_devices = i2c_56760_devices;
   1137                        num_i2c_devices = COUNTOF(i2c_56760_devices);
   1138                        break; /*56560K, 56760K */
   1139             case 0x96: i2c_devices = i2c_56565_devices;
   1140                        num_i2c_devices = COUNTOF(i2c_56565_devices);
   1141                        break; /*56565K */
   1142             case 0x98: i2c_devices = i2c_56270_devices;
   1143                        num_i2c_devices = COUNTOF(i2c_56270_devices);
   1144                        break; /* 56270K */
   1145             case 0x99: i2c_devices = i2c_56272_devices;
   1146                        num_i2c_devices = COUNTOF(i2c_56272_devices);
   1147                        break; /* 56272K */
   1148             case 0x9D: /* TH2 Simplified SVK board */
   1149             case 0xA3: /* TH2 DVT board */
   1150             case 0x9F: i2c_devices = i2c_56970_32_devices;
   1151                        num_i2c_devices = COUNTOF(i2c_56970_32_devices);
   1152                        break; /* 56970K */
   1153             case 0x9E: i2c_devices = i2c_56970_64_devices;
   1154                        num_i2c_devices = COUNTOF(i2c_56970_64_devices);
   1155                        break; /* 56970K */
   1156             case 0xA4: /* TD3 SVK */
   1157             case 0xA5: /* TD3 simplified SVK */
   1158             case 0xA6: /* TD3 56873K /MV2 56770K*/
   1159             case 0xB5: /* MV2 DVT board*/
   1160             case 0xA7: i2c_devices = i2c_56870_devices;
   1161                        num_i2c_devices = COUNTOF(i2c_56870_devices);
   1162                        break; /* TD3 DVT board */
   1163             case 0xAA: i2c_devices = i2c_56670_devices;
   1164                        num_i2c_devices = COUNTOF(i2c_56670_devices);
   1165                        break; /* MONTEREY DVT board */
   1166             case 0xB1:
   1167             case 0xAD:
   1168             case 0xAF:
   1169             case 0xDE:
   1170             case 0xAC: i2c_devices = i2c_56980_devices;
   1171                        num_i2c_devices = COUNTOF(i2c_56980_devices);
   1172                        break; /* 56980K */
   1173             case 0xB0:
   1174             case 0xB3:
   1175             case 0xB6: i2c_devices = i2c_56370_devices;
   1176                        num_i2c_devices = COUNTOF(i2c_56370_devices);
   1177                        break; /* 56370K */
   1178             default:   i2c_devices = i2c_common_devices;
   1179                        num_i2c_devices = COUNTOF(i2c_common_devices);
   1180                        break;
   1181         }
   1182     }
   1183     /* Check for supported I2c devices */
   1184     if (num_i2c_devices > MAX_I2C_DEVICES) {
   1185         LOG_INFO(BSL_LS_SOC_I2C,
   1186                  (BSL_META_U(unit,
   1187                              "ERROR: %d exceeds supported I2C devices\n"),
   1188                   num_i2c_devices ));
   1189         return SOC_E_INTERNAL;
   1190     }
   1191 
   1192     i2c_probe_info.i2cbus = I2CBUS(unit);
   1193 
   1194     LOG_INFO(BSL_LS_SOC_I2C,
   1195              (BSL_META_U(unit,
   1196                          "unit %d i2c: probing %d I2C devices.\n"),
   1197               unit, num_i2c_devices));
   1198 
   1199     /* Attempt to contact known slave devices, hookup driver and
   1200      * run device init function if the device exists, otherwise
   1201      * simply acknowledge the device can be found.
   1202      */
   1203 
   1204     i2c_probe_info.i2c_nvram_skip =
   1205         soc_property_get(unit, spn_I2C_NVRAM_SKIP, 0);
   1206     i2c_probe_info.i2c_hclk_skip =
   1207         soc_property_get(unit, spn_I2C_HCLK_SKIP, 0);
   1208     i2c_probe_info.i2c_poe_power =
   1209         soc_property_get(unit, spn_I2C_POE_POWER, 0);
   1210 
   1211     i2c_probe_info.devid_found = 0; /* Installed I2C device types */
   1212     i2c_probe_info.devices_found = 0; /* Number of installed I2C devices */
   1213 
   1214     /* Initialize device table with none found. */
   1215     for (devid = 0; devid < num_i2c_devices; devid++) {
   1216         /* I2C device not present */
   1217         i2c_probe_info.i2cbus->devs[devid] = NULL;
   1218         i2c_probe_info.i2c_muxed_devid_count[devid] = 0;
   1219         i2c_probe_info.i2c_mux_stack[devid] = -1;
   1220     }
   1221     i2c_probe_info.i2c_mux_stack_depth = 0;
   1222 
   1223     /* First, disable all visible MUX's. */
   1224     for (mux_devid = 0; mux_devid < num_i2c_devices; mux_devid++) {
   1225         if (i2c_devices[mux_devid].driver != &_soc_i2c_pca9548_driver) {
   1226             /* Only the MUX's are interesting here. */
   1227             continue;
   1228         }
   1229         i2c_probe_info.devid = mux_devid;
   1230         rv = _soc_i2c_probe_device(unit, FALSE, &i2c_probe_info);
   1231         if (SOC_E_EXISTS == rv) {
   1232             mux_data = 0; /* Shut down ALL channels */
   1233             if ((rv = i2c_devices[mux_devid].driver->write(unit, mux_devid,
   1234                                              0, &mux_data, 1)) < 0) {
   1235                 LOG_INFO(BSL_LS_SOC_I2C,
   1236                          (BSL_META_U(unit,
   1237                                      "unit %d i2c: Could not disable channels on %s\n"),
   1238                           unit, i2c_devices[mux_devid].devname));
   1239                 return rv;
   1240             } else {
   1241                 /* MUX disabled */
   1242                 rv = SOC_E_NONE;
   1243             }
   1244         } else if ((SOC_E_NOT_FOUND == rv) || (SOC_E_INIT == rv)) {
   1245             /* No error */
   1246             rv = SOC_E_NONE;
   1247         } else if (SOC_FAILURE(rv)) {
   1248             /* Access error */
   1249             return rv;
   1250         }
   1251     }
   1252 
   1253     /* Reset after MUX ops */
   1254     i2c_probe_info.devid_found = 0;
   1255     i2c_probe_info.devices_found = 0;
   1256 
   1257     /* Probe the currently configured (i.e. MUX'd) I2C bus. */
   1258     for (devid = 0; devid < num_i2c_devices; devid++) {
   1259         /* Detect device type */
   1260         i2c_probe_info.devid = devid;
   1261         rv = _soc_i2c_probe_device(unit, FALSE, &i2c_probe_info);
   1262         if ((SOC_E_EXISTS == rv) || (SOC_E_NOT_FOUND == rv)
   1263             || (SOC_E_INIT == rv)) {
   1264             /* No problem */
   1265             rv = SOC_E_NONE;
   1266         } else if (SOC_FAILURE(rv)) {
   1267             /* Access error */
   1268             return rv;
   1269         }
   1270     }
   1271 
   1272     /* Now we know all of the devices that aren't behind a MUX.
   1273      * Anything new we find now must be behind a MUX.
   1274      * Recursively scan down the MUX tree.
   1275      */
   1276     if ((rv = _soc_i2c_probe_mux(unit, -1, &i2c_probe_info)) < 0) {
   1277         LOG_INFO(BSL_LS_SOC_I2C,
   1278                  (BSL_META_U(unit,
   1279                              "unit %d i2c: Could not probe MUX's\n"), unit));
   1280         return rv;
   1281     }
   1282 
   1283     return i2c_probe_info.devid_found;
   1284 }
   1285 
   1286 /*
   1287  * Function: soc_i2c_device_count
   1288  *
   1289  * Purpose: Report the number of devices registered
   1290  *          in the system. For now, this is the total number of devices
   1291  *          we have added to the statically defined device descriptor
   1292  *          array above.
   1293  *
   1294  * Parameters:
   1295  *    unit - StrataSwitch device number or I2C bus number
   1296  *
   1297  * Returns:
   1298  *        number of devices registered in the system device table.
   1299  *
   1300  * Notes: Currently, we do not support dynamic device loading.
   1301  *        Later, one will be able add a driver to the device table,
   1302  *        without the STATIC attribute.
   1303  */
   1304 int
   1305 soc_i2c_device_count(int unit)
   1306 {
   1307     COMPILER_REFERENCE(unit);
   1308     return num_i2c_devices;
   1309 }
   1310 
   1311 /*
   1312  * Function: soc_i2c_show
   1313  *
   1314  * Parameters:
   1315  *    unit - StrataSwitch device number or I2C bus number
   1316  *
   1317  * Purpose: Show all valid devices and their attributes and
   1318  *          statistics.
   1319  * Returns:
   1320  *    none
   1321  * Notes:
   1322  *    none
   1323  */
   1324 void
   1325 soc_i2c_show(int unit)
   1326 {
   1327     int dev;
   1328     soc_i2c_bus_t	*i2cbus;
   1329     i2c_device_t	*i2cdev;
   1330 
   1331 #ifdef BCM_APACHE_SUPPORT
   1332     /* Temporary Output for "i2c show" command in BCMSIM
   1333        Shows info of primary mux
   1334      */
   1335     if (SOC_IS_APACHE(unit) && SAL_BOOT_BCMSIM) {
   1336         LOG_CLI((BSL_META_U(unit,
   1337                             "%15s: %s%s saddr=0x%02x \n"),
   1338                  I2C_MUX_3,
   1339                  " (detached) ",
   1340                  "PCA9548 i2c switch",
   1341                  I2C_MUX_SADDR3));
   1342         return;
   1343     }
   1344 #endif
   1345 
   1346     /* Make sure that we're already attached, or go get attached */
   1347     if ( !soc_i2c_is_attached(unit) &&
   1348 	 (soc_i2c_attach(unit, 0, 0) < 0) ) {
   1349         LOG_CLI((BSL_META_U(unit,
   1350                             "unit %d soc_i2c_show: error attaching to I2C bus\n"),
   1351                  unit));
   1352         return;
   1353     }
   1354 
   1355     i2cbus = I2CBUS(unit);
   1356 
   1357     i2cbus->txBytes = i2cbus->rxBytes = 0;
   1358 
   1359     LOG_CLI((BSL_META_U(unit,
   1360                         "unit %d i2c  bus: mode=%s speed=%dkbps "
   1361                         "SOC_address=0x%02X\n"),
   1362              unit,
   1363              i2cbus->flags&SOC_I2C_MODE_PIO?"PIO":"INTR",
   1364              i2cbus->frequency/1000,
   1365              i2cbus->master_addr));
   1366 
   1367     for (dev = 0; dev < num_i2c_devices; dev++) {
   1368 	i2cdev = i2cbus->devs[dev];
   1369 	if (i2cdev == NULL) {
   1370 	    continue;
   1371 	}
   1372 	LOG_CLI((BSL_META_U(unit,
   1373                             "%15s: %s%s saddr=0x%02x \n"),
   1374                  i2cdev->devname,
   1375                  i2cdev->driver ? "" : " (detached)",
   1376                  i2cdev->desc,
   1377                  i2cdev->saddr));
   1378 
   1379 	if (i2cdev->driver && (i2cdev->rbyte != 0 || i2cdev->tbyte != 0)) {
   1380 	    LOG_CLI((BSL_META_U(unit,
   1381                                 "                 received %d bytes, "
   1382                                 "transmitted %d bytes\n"),
   1383                      i2cdev->rbyte, i2cdev->tbyte));
   1384 	    i2cbus->txBytes += i2cdev->tbyte;
   1385 	    i2cbus->rxBytes += i2cdev->rbyte;
   1386 	}
   1387     }
   1388     LOG_CLI((BSL_META_U(unit,
   1389                         "unit %d i2c  bus: received %d bytes, "
   1390                         "transmitted %d bytes\n"),
   1391              unit, i2cbus->rxBytes, i2cbus->txBytes));
   1392 }
   1393 
   1394 /*
   1395  * Function: soc_i2c_addr
   1396  *
   1397  * Purpose: Return slave address of specified device.
   1398  *
   1399  * Parameters:
   1400  *    unit - StrataSwitch device number or I2C bus number
   1401  *    devid - I2C device id returned from soc_i2c_devopen
   1402  *
   1403  * Returns:
   1404  *    7-bit or 10-bit I2C slave address of device, in "datasheet-speak"
   1405  *
   1406  * Notes:
   1407  *    none
   1408  */
   1409 i2c_saddr_t
   1410 soc_i2c_addr(int unit, int devid)
   1411 {
   1412     soc_i2c_bus_t	*i2cbus;
   1413 
   1414     i2cbus = I2CBUS(unit);
   1415     if (i2cbus && i2cbus->devs[devid]) {
   1416 	return i2cbus->devs[devid]->saddr;
   1417     }
   1418     return 0;
   1419 }
   1420 
   1421 /*
   1422  * Function: soc_i2c_devname
   1423  *
   1424  * Purpose: Return device name of specified device.
   1425  *
   1426  * Parameters:
   1427  *    unit - StrataSwitch device number or I2C bus number
   1428  *    devid - I2C device id returned from soc_i2c_devopen
   1429  *
   1430  * Returns:
   1431  *    character string name of device
   1432  *
   1433  * Notes:
   1434  *    none
   1435  */
   1436 const char *
   1437 soc_i2c_devname(int unit, int devid)
   1438 {
   1439     soc_i2c_bus_t	*i2cbus;
   1440 
   1441     i2cbus = I2CBUS(unit);
   1442     if (i2cbus && i2cbus->devs[devid]) {
   1443 	return i2cbus->devs[devid]->devname;
   1444     }
   1445     return NULL;
   1446 }
   1447 
   1448 int
   1449 soc_i2c_devdesc_set(int unit, int devid, char *desc)
   1450 {
   1451     soc_i2c_bus_t	*i2cbus;
   1452 
   1453     i2cbus = I2CBUS(unit);
   1454     if (i2cbus && i2cbus->devs[devid]) {
   1455 	i2cbus->devs[devid]->desc = desc;
   1456     }
   1457     return SOC_E_NONE;
   1458 }
   1459 
   1460 int
   1461 soc_i2c_devdesc_get(int unit, int devid, char **desc)
   1462 {
   1463     soc_i2c_bus_t	*i2cbus;
   1464 
   1465     i2cbus = I2CBUS(unit);
   1466     if (i2cbus && i2cbus->devs[devid]) {
   1467 	*desc = i2cbus->devs[devid]->desc;
   1468     } else {
   1469 	*desc = "";
   1470     }
   1471     return SOC_E_NONE;
   1472 }
   1473 
   1474 /*
   1475  * Function: soc_i2c_device
   1476  *
   1477  * Purpose: Returns the device structure associated with the bus and
   1478  *          device identifier.
   1479  *
   1480  * Parameters:
   1481  *    unit - StrataSwitch device number or I2C bus number
   1482  *    devid - I2C device id returned from soc_i2c_devopen
   1483  *
   1484  * Returns:
   1485  *    I2C device descriptor
   1486  *
   1487  * Notes:
   1488  *    none
   1489  */
   1490 i2c_device_t *
   1491 soc_i2c_device(int unit, int devid)
   1492 {
   1493     soc_i2c_bus_t	*i2cbus;
   1494 
   1495     i2cbus = I2CBUS(unit);
   1496     if (i2cbus && i2cbus->devs[devid]) {
   1497 	return i2cbus->devs[devid];
   1498     }
   1499     return NULL;
   1500 }
   1501 
   1502 /*
   1503  * Function: soc_i2c_devtype
   1504  *
   1505  * Purpose: Return the device driver type, this is an integer value
   1506  *          associated with the driver to determine ownership of the device.
   1507  *
   1508  * Parameters:
   1509  *    unit - StrataSwitch device number or I2C bus number
   1510  *    devid - I2C device id returned from soc_i2c_devopen
   1511  *
   1512  * Returns:
   1513  *    I2C device type code (from driver)
   1514  *
   1515  * Notes:
   1516  *    Every device should have a unique Device type indentifier.
   1517  */
   1518 int
   1519 soc_i2c_devtype(int unit, int devid)
   1520 {
   1521     soc_i2c_bus_t	*i2cbus;
   1522 
   1523     i2cbus = I2CBUS(unit);
   1524     if (i2cbus && i2cbus->devs[devid] && i2cbus->devs[devid]->driver) {
   1525 	return i2cbus->devs[devid]->driver->id;
   1526     }
   1527     return 0;
   1528 }
   1529 
   1530 /*
   1531  *
   1532  * Function: soc_i2c_is_attached
   1533  *
   1534  * Purpose:  Return true if I2C bus driver is attached.
   1535  *
   1536  * Parameters:
   1537  *    unit - StrataSwitch device number or I2C bus number
   1538  *
   1539  * Returns:
   1540  *    True if the bus driver for I2C is attached.
   1541  *
   1542  * Notes:
   1543  *    None
   1544  */
   1545 int
   1546 soc_i2c_is_attached(int unit)
   1547 {
   1548     uint32 dev_idx;
   1549     uint8 found = 0;
   1550     soc_i2c_bus_t	*i2cbus;
   1551 
   1552     for(dev_idx = 0; dev_idx < soc_ndev ; ++dev_idx) {
   1553         if(SOC_NDEV_IDX2DEV(dev_idx) == unit) {
   1554             found = 1;
   1555             break;
   1556         }
   1557     }
   1558     if (!found) {
   1559         return 0;
   1560     }
   1561 
   1562     i2cbus = I2CBUS(unit);
   1563     if (i2cbus == NULL) {
   1564 	    return 0;
   1565     }
   1566     return (i2cbus->flags & SOC_I2C_ATTACHED) != 0;
   1567 }
   1568 
   1569 /*
   1570  * Function: soc_i2c_devopen
   1571  *
   1572  * Purpose:  Open device, return valid file descriptor or -1 on error.
   1573  *
   1574  * Parameters:
   1575  *    unit - StrataSwitch device number or I2C bus number
   1576  *    devname - I2C device name string
   1577  *    flags - arguments to pass to attach, default value should be zero
   1578  *    speed - I2C bus speed, if non-zero, this speed is configured, normally
   1579  *            this argument should be zero unless a speed is desired.
   1580  * Returns:
   1581  *      device identifier for all I2C operations
   1582  *
   1583  * Notes:
   1584  *      This routine should be called before attempting to communicate
   1585  *      with an I2C device which has a registered driver.
   1586  */
   1587 int
   1588 soc_i2c_devopen(int unit, char* devname, uint32 flags, int speed)
   1589 {
   1590     int devid, rv;
   1591     soc_i2c_bus_t	*i2cbus;
   1592 
   1593     /* Make sure that we're already attached, or go get attached */
   1594     if ( !soc_i2c_is_attached(unit) &&
   1595 	 ((rv = soc_i2c_attach(unit, flags, speed)) < 0) ) {
   1596         return rv;
   1597     }
   1598 
   1599     i2cbus = I2CBUS(unit);
   1600     for (devid = 0; devid < num_i2c_devices; devid++) {
   1601     	if (i2cbus->devs[devid]) {
   1602     	    if (sal_strcmp(i2cbus->devs[devid]->devname, devname) == 0) {
   1603     		return devid;
   1604     	    }
   1605     	}
   1606     }
   1607     return SOC_E_NOT_FOUND;
   1608 }
   1609 
   1610 /*
   1611  * Function: soc_i2c_get_devices
   1612  *
   1613  * Purpose: Return an array of I2C devices; fill in the count.
   1614  *
   1615  * Parameters:
   1616  *    unit - StrataSwitch device number or I2C bus number
   1617  *    count - address where the count of devices should be stored.
   1618  *
   1619  * Returns:
   1620  *      device descriptor array
   1621  *
   1622  * Notes:
   1623  *      NYI
   1624  */
   1625 i2c_device_t *
   1626 soc_i2c_get_devices(int unit, int* count)
   1627 {
   1628     return NULL;
   1629 }
   1630 
   1631 /*
   1632  * Function: soc_i2c_register
   1633  * Purpose : Register a driver with the systems internal table.
   1634  *
   1635  * Parameters:
   1636  *    unit - StrataSwitch device number or I2C bus number
   1637  *    devname - device name
   1638  *    device - I2C device descriptor
   1639  *
   1640  * Returns:
   1641  *      SOC_E_NONE - device is registered
   1642  *
   1643  * Notes:
   1644  *      NYI
   1645  */
   1646 int
   1647 soc_i2c_register(int unit, char* devname, i2c_device_t* device)
   1648 {
   1649     return SOC_E_UNAVAIL;
   1650 }
   1651 
   1652 /*
   1653  * Function: soc_i2c_unload_devices
   1654  * Purpose: Unload I2C devices on bus, hook to I2C device driver uload function.
   1655  *
   1656  * Parameters:
   1657  *          unit - StrataSwitch device number or I2C bus number
   1658  *
   1659  * Return:
   1660  *          SOC_E_NONE
   1661  */
   1662 int
   1663 soc_i2c_unload_devices(int unit)
   1664 {
   1665     int dev;
   1666     soc_i2c_bus_t *i2cbus;
   1667     i2c_device_t *i2cdev;
   1668     i2c_dev_deinit_func_t unload;
   1669 
   1670     i2cbus = I2CBUS(unit);
   1671 
   1672     if (i2cbus != NULL) {
   1673         for (dev = 0; dev < num_i2c_devices; dev++) {
   1674             i2cdev = i2cbus->devs[dev];
   1675             if (i2cdev == NULL) {
   1676                 continue;
   1677             }
   1678             unload = i2cdev->driver->unload;
   1679             if (unload) {
   1680                 (void)unload(unit, dev);
   1681             }
   1682         }
   1683 	}
   1684 
   1685     return SOC_E_NONE;
   1686 }