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

bsc_devs.c (13333B)


      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 BSC (Broadcom Serial control). 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 #if defined(INCLUDE_I2C)
     15 
     16 #include <sal/types.h>
     17 #include <sal/core/boot.h>
     18 #include <soc/debug.h>
     19 #include <soc/error.h>
     20 #include <soc/drv.h>
     21 #include <soc/cmic.h>
     22 #include <soc/i2c.h>
     23 #include <soc/bsc.h>
     24 #include <shared/bsl.h>
     25 
     26 #ifdef INCLUDE_I2C_SFP
     27 extern bsc_driver_t _soc_bsc_sfp_driver;
     28 #endif
     29 
     30 #ifdef BCM_FE2000_SUPPORT
     31 /* Temperature Monitors and PWM Fan Controllers */
     32 extern bsc_driver_t _soc_bsc_max6653_driver;
     33 
     34 /* Digital Power Manager */
     35 extern bsc_driver_t _soc_bsc_zm73xx_driver;
     36 
     37 extern bsc_driver_t _soc_bsc_at24c64_driver;
     38 #endif
     39 
     40 /* Data: bsc_devices
     41  * Purpose: BSC device descriptor table.
     42  *          Devices are added to this table, along with their slave
     43  *          address, a string description, and their driver (if available).
     44  */
     45 STATIC bsc_device_t bsc_devices[] = {
     46 #ifdef BCM_FE2000_SUPPORT
     47 	{
     48 		"max6653_0",				/* device name */
     49 		BSC_PCA9548_SADDR,			/* mux i2c address */
     50 		BSC_PCA9548_CHAN_0,			/* mux channel for this device */
     51 		BSC_MAX6653_SADDR,			/* device i2c address */
     52 		&_soc_bsc_max6653_driver,		/* device driver */
     53 		"Temperature and Fan speed sensor"	/* description */
     54 	},
     55 	{
     56 		"max6653_1",				/* device name */
     57 		BSC_PCA9548_SADDR,			/* mux i2c address */
     58 		BSC_PCA9548_CHAN_1,			/* mux channel for this device */
     59 		BSC_MAX6653_SADDR,			/* device i2c address */
     60 		&_soc_bsc_max6653_driver,		/* device driver */
     61 		"Temperature and Fan speed sensor"	/* description */
     62 	},
     63 	{
     64 		"max6653_2",				/* device name */
     65 		BSC_PCA9548_SADDR,			/* mux i2c address */
     66 		BSC_PCA9548_CHAN_2,			/* mux channel for this device */
     67 		BSC_MAX6653_SADDR,			/* device i2c address */
     68 		&_soc_bsc_max6653_driver,		/* device driver */
     69 		"Temperature and Fan speed sensor"	/* description */
     70 	},
     71 	{
     72 		"max6653_3",				/* device name */
     73 		BSC_PCA9548_SADDR,			/* mux i2c address */
     74 		BSC_PCA9548_CHAN_3,			/* mux channel for this device */
     75 		BSC_MAX6653_SADDR,			/* device i2c address */
     76 		&_soc_bsc_max6653_driver,		/* device driver */
     77 		"Temperature and Fan speed sensor"	/* description */
     78 	},
     79 	{
     80 		"max6653_4",				/* device name */
     81 		BSC_PCA9548_SADDR,			/* mux i2c address */
     82 		BSC_PCA9548_CHAN_4,			/* mux channel for this device */
     83 		BSC_MAX6653_SADDR,			/* device i2c address */
     84 		&_soc_bsc_max6653_driver,		/* device driver */
     85 		"Temperature and Fan speed sensor"	/* description */
     86 	},
     87 	{
     88 		"zm73xx_0",				/* device name */
     89 		BSC_PCA9548_SADDR,			/* mux i2c address */
     90 		BSC_PCA9548_CHAN_5,			/* mux channel for this device */
     91 		BSC_ZM73XX_SADDR,			/* device i2c address */
     92 		&_soc_bsc_zm73xx_driver,		/* device driver */
     93 		"Digital Power Manager"			/* description */
     94 	},
     95 	{
     96 		BSC_AT24C32_NAME,			/* device name */
     97 		0,					/* no mux i2c address */
     98 		0,					/* no mux channel */
     99 		BSC_AT24C32_SADDR,			/* device i2c address */
    100 		&_soc_bsc_at24c64_driver,		/* device driver */
    101 		"Atmel 24C64 serial EEPROM"		/* description */
    102 	},
    103 #endif
    104 #ifdef INCLUDE_I2C_SFP
    105         {
    106 		BSC_SFP_00_NAME,	/* device name */
    107 		BSC_PCA9548_SADDR_1,	/* mux i2c address */
    108 		BSC_PCA9548_CHAN_0,	/* mux channel for this device */
    109 		BSC_SFP_SADDR,	/* device i2c address */
    110 		&_soc_bsc_sfp_driver,		/* device driver */
    111 		"SFP"		/* description */
    112 	},
    113         {
    114 		BSC_SFP_01_NAME,	/* device name */
    115 		BSC_PCA9548_SADDR_1,	/* mux i2c address */
    116 		BSC_PCA9548_CHAN_1,	/* mux channel for this device */
    117 		BSC_SFP_SADDR,	/* device i2c address */
    118 		&_soc_bsc_sfp_driver,		/* device driver */
    119 		"SFP"		/* description */
    120 	},
    121         {
    122 		BSC_SFP_02_NAME,	/* device name */
    123 		BSC_PCA9548_SADDR_1,	/* mux i2c address */
    124 		BSC_PCA9548_CHAN_2,	/* mux channel for this device */
    125 		BSC_SFP_SADDR,	/* device i2c address */
    126 		&_soc_bsc_sfp_driver,		/* device driver */
    127 		"SFP"		/* description */
    128 	},
    129         {
    130 		BSC_SFP_03_NAME,	/* device name */
    131 		BSC_PCA9548_SADDR_1,	/* mux i2c address */
    132 		BSC_PCA9548_CHAN_3,	/* mux channel for this device */
    133 		BSC_SFP_SADDR,	/* device i2c address */
    134 		&_soc_bsc_sfp_driver,		/* device driver */
    135 		"SFP"		/* description */
    136 	},
    137         {
    138 		BSC_SFP_04_NAME,	/* device name */
    139 		BSC_PCA9548_SADDR_3,	/* mux i2c address */
    140 		BSC_PCA9548_CHAN_4,	/* mux channel for this device */
    141 		BSC_SFP_SADDR,	/* device i2c address */
    142 		&_soc_bsc_sfp_driver,		/* device driver */
    143 		"SFP"		/* description */
    144 	},
    145         {
    146 		BSC_SFP_05_NAME,	/* device name */
    147 		BSC_PCA9548_SADDR_1,	/* mux i2c address */
    148 		BSC_PCA9548_CHAN_5,	/* mux channel for this device */
    149 		BSC_SFP_SADDR,	/* device i2c address */
    150 		&_soc_bsc_sfp_driver,		/* device driver */
    151 		"SFP"		/* description */
    152 	},
    153         {
    154 		BSC_SFP_06_NAME,	/* device name */
    155 		BSC_PCA9548_SADDR_1,	/* mux i2c address */
    156 		BSC_PCA9548_CHAN_6,	/* mux channel for this device */
    157 		BSC_SFP_SADDR,	/* device i2c address */
    158 		&_soc_bsc_sfp_driver,		/* device driver */
    159 		"SFP"		/* description */
    160 	},
    161         {
    162 		BSC_SFP_07_NAME,	/* device name */
    163 		BSC_PCA9548_SADDR_1,	/* mux i2c address */
    164 		BSC_PCA9548_CHAN_7,	/* mux channel for this device */
    165 		BSC_SFP_SADDR,	/* device i2c address */
    166 		&_soc_bsc_sfp_driver,		/* device driver */
    167 		"SFP"		/* description */
    168 	},
    169         {
    170 		BSC_SFP_08_NAME,	/* device name */
    171 		BSC_PCA9548_SADDR_2,	/* mux i2c address */
    172 		BSC_PCA9548_CHAN_0,	/* mux channel for this device */
    173 		BSC_SFP_SADDR,	/* device i2c address */
    174 		&_soc_bsc_sfp_driver,		/* device driver */
    175 		"SFP"		/* description */
    176 	},
    177         {
    178 		BSC_SFP_09_NAME,	/* device name */
    179 		BSC_PCA9548_SADDR_2,	/* mux i2c address */
    180 		BSC_PCA9548_CHAN_1,	/* mux channel for this device */
    181 		BSC_SFP_SADDR,	/* device i2c address */
    182 		&_soc_bsc_sfp_driver,		/* device driver */
    183 		"SFP"		/* description */
    184 	},
    185         {
    186 		BSC_SFP_10_NAME,	/* device name */
    187 		BSC_PCA9548_SADDR_2,	/* mux i2c address */
    188 		BSC_PCA9548_CHAN_2,	/* mux channel for this device */
    189 		BSC_SFP_SADDR,	/* device i2c address */
    190 		&_soc_bsc_sfp_driver,		/* device driver */
    191 		"SFP"		/* description */
    192 	},
    193         {
    194 		BSC_SFP_11_NAME,	/* device name */
    195 		BSC_PCA9548_SADDR_2,	/* mux i2c address */
    196 		BSC_PCA9548_CHAN_3,	/* mux channel for this device */
    197 		BSC_SFP_SADDR,	/* device i2c address */
    198 		&_soc_bsc_sfp_driver,		/* device driver */
    199 		"SFP"		/* description */
    200 	},
    201 #endif
    202 	{
    203 		NULL,
    204 		0,
    205 		0,
    206 		0,
    207 		NULL,
    208 		NULL            /* Dummy entry to circumvent PEDANTIC */ 
    209 	}
    210 };
    211 
    212 #define num_bsc_devices (COUNTOF(bsc_devices) - 1)
    213 
    214 /*
    215  * Function: soc_bsc_probe
    216  * Purpose: Probe BSC devices on bus, report devices found.
    217  *          This routine will walk through our internal BSC device driver
    218  *          tables, attempt to find the device on the BSC bus, and if
    219  *          successful, register a device driver for that device.
    220  *
    221  *          This allows for the device to be used in an API context as
    222  *          when the devices are found, the device driver table is filled
    223  *          with the correct entries for that device (r/w function, etc).
    224  *
    225  * Parameters:
    226  *	unit - device number
    227  *
    228  * Return:
    229  *	count of found devices or SOC_E_***
    230  */
    231 int
    232 soc_bsc_probe(int unit)
    233 {
    234 	int found;
    235 	soc_bsc_bus_t *bscbus;
    236 #if defined(BCM_FE2000_SUPPORT) || defined(INCLUDE_I2C_SFP)
    237 	int devno, retv;
    238 #endif
    239 
    240 	/* Make sure that we're already attached, or go get attached */
    241 	if (!soc_bsc_is_attached(unit)) {
    242 		return soc_bsc_attach(unit);
    243 	}
    244 
    245 	bscbus = BSCBUS(unit);
    246 	found = 0; /* Number of installed BSC devices */
    247 
    248     COMPILER_REFERENCE(bscbus);
    249 
    250 /* Coverity Fix : We don't need to probe if no devices are supported */
    251 #if defined(BCM_FE2000_SUPPORT) || defined(INCLUDE_I2C_SFP)
    252 	/* Probe the currently configured (i.e. MUX'd) I2C bus. */
    253 	for (devno = 0; devno < num_bsc_devices; devno++) {
    254 
    255 		bscbus->devs[devno] = &bsc_devices[devno];
    256 
    257 		/* Check device existence */
    258 		retv = bsc_devices[devno].driver->ioctl(
    259 				unit, devno, BSC_IOCTL_DEVICE_PRESENT, 0, 0);
    260 		if (!retv) {
    261 			/* I2C device not present */
    262 			bscbus->devs[devno] = NULL;
    263 			continue;
    264 		}
    265 
    266 		/* set flags, device id, hook up bus, etc  */
    267 		bsc_devices[devno].driver->devno = devno;
    268 
    269 		retv =  bsc_devices[devno].driver->init(unit, devno);
    270 		if (retv < 0) {
    271 			LOG_INFO(BSL_LS_SOC_I2C,
    272                                  (BSL_META_U(unit,
    273                                              "unit %d i2c 0x%x: init failed %s on channel: 0x%02x\n"),
    274                                   unit,
    275                                   bsc_devices[devno].saddr,
    276                                   bsc_devices[devno].devname,
    277                                   bsc_devices[devno].chan));
    278 		}
    279 		LOG_INFO(BSL_LS_SOC_I2C,
    280                          (BSL_META_U(unit,
    281                                      "unit %d bsc 0x%x: found %s on channel 0x%02x: %s\n"),
    282                           unit,
    283                           bsc_devices[devno].saddr,
    284                           bsc_devices[devno].devname,
    285                           bsc_devices[devno].chan,
    286                           bsc_devices[devno].desc ?
    287                           bsc_devices[devno].desc : ""));
    288 
    289 		found += 1;
    290 	}
    291 #endif
    292 	return found;
    293 }
    294 
    295 void
    296 soc_bsc_show(int unit)
    297 {
    298 #if defined(BCM_FE2000_SUPPORT) || defined(INCLUDE_I2C_SFP)
    299 	int devno;
    300 #endif
    301 	soc_bsc_bus_t *bscbus;
    302 
    303 	/* Make sure that we're already attached, or go get attached */
    304 	if (!soc_bsc_is_attached(unit)) {
    305 		if (soc_bsc_attach(unit) < 0) {
    306 			return;
    307 		}
    308 	}
    309 
    310 	bscbus = BSCBUS(unit);
    311 
    312     COMPILER_REFERENCE(bscbus);
    313 
    314 /* Coverity Fix : We don't need to show if no devices are supported */
    315 #if defined(BCM_FE2000_SUPPORT) || defined(INCLUDE_I2C_SFP)
    316 	/* Show the currently configured (i.e. MUX'd) I2C bus. */
    317 	for (devno = 0; devno < num_bsc_devices; devno++) {
    318 		if (bscbus->devs[devno]) {
    319 			LOG_CLI((BSL_META_U(unit,
    320                                             "unit: %d devno: %d name: %s saddr: 0x%x "
    321                                             "chan: 0x%02x - %s\n"),
    322                                  unit,
    323                                  devno,
    324                                  bsc_devices[devno].devname,
    325                                  bsc_devices[devno].saddr,
    326                                  bsc_devices[devno].chan,
    327                                  bsc_devices[devno].desc ?
    328                                  bsc_devices[devno].desc : ""));
    329 		}
    330 	}
    331 #endif
    332 }
    333 
    334 int
    335 soc_bsc_addr(int unit, int devno)
    336 {
    337     soc_bsc_bus_t *bscbus;
    338 
    339     bscbus = BSCBUS(unit);
    340     if (bscbus && bscbus->devs[devno]) {
    341         return bscbus->devs[devno]->saddr;
    342     }
    343     return 0;
    344 }
    345 
    346 const char *
    347 soc_bsc_devname(int unit, int devno)
    348 {
    349     soc_bsc_bus_t *bscbus;
    350 
    351     bscbus = BSCBUS(unit);
    352     if (bscbus && bscbus->devs[devno]) {
    353         return bscbus->devs[devno]->devname;
    354     }
    355     return NULL;
    356 }
    357 
    358 int
    359 soc_bsc_device_count(int unit)
    360 {
    361 	COMPILER_REFERENCE(unit);
    362 	return num_bsc_devices;
    363 }
    364 
    365 int
    366 soc_bsc_devdesc_set(int unit, int devno, char *desc)
    367 {
    368 	soc_bsc_bus_t *bscbus;
    369 
    370 	bscbus = BSCBUS(unit);
    371 	if (bscbus && bscbus->devs[devno]) {
    372 		bscbus->devs[devno]->desc = desc;
    373 	}
    374 	return SOC_E_NONE;
    375 }
    376 
    377 int
    378 soc_bsc_devdesc_get(int unit, int devno, char **desc)
    379 {
    380 	soc_bsc_bus_t *bscbus;
    381 
    382 	bscbus = BSCBUS(unit);
    383 	if (bscbus && bscbus->devs[devno]) {
    384 		*desc = bscbus->devs[devno]->desc;
    385 	} else {
    386 		*desc = "";
    387 	}
    388 	return SOC_E_NONE;
    389 }
    390 
    391 bsc_device_t *
    392 soc_bsc_device(int unit, int devno)
    393 {
    394 	soc_bsc_bus_t *bscbus;
    395 
    396 	bscbus = BSCBUS(unit);
    397 	if (bscbus && bscbus->devs[devno]) {
    398 		return bscbus->devs[devno];
    399 	}
    400 	return NULL;
    401 }
    402 
    403 int
    404 soc_bsc_devopen(int unit, char* devname)
    405 {
    406 #if defined(BCM_FE2000_SUPPORT) || defined(INCLUDE_I2C_SFP)
    407 	int devno;
    408 #endif
    409 	soc_bsc_bus_t *bscbus;
    410 
    411 	/* Make sure that we're already attached, or go get attached */
    412 	if (!soc_bsc_is_attached(unit)) {
    413 		if (soc_bsc_attach(unit) < 0) {
    414 			return SOC_E_FAIL;
    415 		}
    416 	}
    417 	bscbus = BSCBUS(unit);
    418 
    419     COMPILER_REFERENCE(bscbus);
    420 
    421 /* Coverity Fix : We don't need to search if no devices are supported */
    422 #if defined(BCM_FE2000_SUPPORT) || defined(INCLUDE_I2C_SFP)
    423 	for (devno = 0; devno < num_bsc_devices; devno++) {
    424 		if (bscbus->devs[devno]) {
    425 			if (sal_strcmp(bscbus->devs[devno]->devname, devname) == 0) {
    426 				return devno;
    427 			}
    428 		}
    429 	}
    430 #endif
    431 	return SOC_E_NOT_FOUND;
    432 }
    433 
    434 int
    435 soc_bsc_devtype(int unit, int devno)
    436 {
    437 	soc_bsc_bus_t *bscbus;
    438 
    439 	bscbus = BSCBUS(unit);
    440 	if (bscbus && bscbus->devs[devno] && bscbus->devs[devno]->driver) {
    441 		return bscbus->devs[devno]->driver->id;
    442 	}
    443 	return 0;
    444 }
    445 
    446 /*
    447  *
    448  * Function: soc_i2c_is_attached
    449  *
    450  * Purpose:  Return true if I2C bus driver is attached.
    451  *
    452  * Parameters:
    453  *    unit - StrataSwitch device number or I2C bus number
    454  *
    455  * Returns:
    456  *    True if the bus driver for I2C is attached.
    457  *
    458  * Notes:
    459  *    None
    460  */
    461 int
    462 soc_bsc_is_attached(int unit)
    463 {
    464     uint32 dev_idx;
    465     uint8 found = 0;
    466 	soc_bsc_bus_t *bscbus;
    467 
    468     for(dev_idx = 0; dev_idx < soc_ndev ; ++dev_idx) {
    469         if(SOC_NDEV_IDX2DEV(dev_idx) == unit) {
    470             found = 1;
    471             break;
    472         }
    473     }
    474     if (!found) {
    475 		return 0;
    476 	}
    477 
    478 	bscbus = BSCBUS(unit);
    479 	if (bscbus == NULL) {
    480 		return 0;
    481 	}
    482 	return (bscbus->flags & SOC_BSC_ATTACHED) != 0;
    483 }
    484 
    485 #else  /* BCM_FE2000_SUPPORT && INCLUDE_I2C */
    486 int _soc_i2c_bsc_devs_not_empty;
    487 #endif /* BCM_FE2000_SUPPORT && INCLUDE_I2C */
    488