/** * Return non-zero if the SPI interface has a SPI4000 attached * * @param interface SPI interface the SPI4000 is connected to * * @return */ int cvmx_spi4000_is_present(int interface) { if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))) return 0; // Check for the presence of a SPI4000. If it isn't there, // these writes will timeout. if (cvmx_twsi_write8(SPI4000_TWSI_ID(interface), SPI4000_WRITE_ADDRESS_HIGH, 0)) return 0; if (cvmx_twsi_write8(SPI4000_TWSI_ID(interface), SPI4000_WRITE_ADDRESS_LOW, 0)) return 0; interface_is_spi4000[interface] = 1; return 1; }
/* * Board-specific RTC write * Time returned is in seconds from epoch (Jan 1 1970 at 00:00:00 UTC) */ int cvmx_rtc_ds1337_write(uint32_t time) { struct clocktime ct; struct timespec ts; int i, rc, retry; uint8_t reg[8]; uint8_t sec; ts.tv_sec = time; ts.tv_nsec = 0; clock_ts_to_ct(&ts, &ct); if (validate_ct_struct(&ct)) { cvmx_dprintf("Error: RTC was passed wrong calendar values, write failed\n"); goto ct_invalid; } reg[0] = bin2bcd(ct.sec); reg[1] = bin2bcd(ct.min); reg[2] = bin2bcd(ct.hour); /* Force 0..23 format even if using AM/PM */ reg[3] = bin2bcd(ct.dow); reg[4] = bin2bcd(ct.day); reg[5] = bin2bcd(ct.mon); if (ct.year >= 2000) /* Set century bit*/ { reg[5] |= 0x80; } reg[6] = bin2bcd(ct.year % 100); /* Lockless write: detects the infrequent roll-over and retries */ for(retry=0; retry<2; retry++) { rc = 0; for(i=0; i<7; i++) { rc |= cvmx_twsi_write8(CVMX_RTC_DS1337_ADDR, i, reg[i]); } sec = cvmx_twsi_read8(CVMX_RTC_DS1337_ADDR, 0x0); if ((sec & 0xf) == (reg[0] & 0xf)) break; /* Time did not roll-over, value is correct */ } return (rc ? -1 : 0); ct_invalid: return -1; }
/* * Board-specific RTC write * Time returned is in seconds from epoch (Jan 1 1970 at 00:00:00 UTC) */ int cvmx_rtc_ds1337_write(uint32_t time) { int i, rc, retry; struct tm tms; uint8_t reg[8]; uint8_t sec; time_t time_from_epoch = time; localtime_r(&time_from_epoch, &tms); if (validate_tm_struct(&tms)) { cvmx_dprintf("Error: RTC was passed wrong calendar values, write failed\n"); goto tm_invalid; } reg[0] = bin2bcd(tms.tm_sec); reg[1] = bin2bcd(tms.tm_min); reg[2] = bin2bcd(tms.tm_hour); /* Force 0..23 format even if using AM/PM */ reg[3] = bin2bcd(tms.tm_wday + 1); reg[4] = bin2bcd(tms.tm_mday); reg[5] = bin2bcd(tms.tm_mon + 1); if (tms.tm_year >= 100) /* Set century bit*/ { reg[5] |= 0x80; } reg[6] = bin2bcd(tms.tm_year % 100); /* Lockless write: detects the infrequent roll-over and retries */ for(retry=0; retry<2; retry++) { rc = 0; for(i=0; i<7; i++) { rc |= cvmx_twsi_write8(CVMX_RTC_DS1337_ADDR, i, reg[i]); } sec = cvmx_twsi_read8(CVMX_RTC_DS1337_ADDR, 0x0); if ((sec & 0xf) == (reg[0] & 0xf)) break; /* Time did not roll-over, value is correct */ } return (rc ? -1 : 0); tm_invalid: return -1; }