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