/* * Initialize the SMBus (RTC uses channel 1) */ static int bcm1250_smbus_init(int smb_chan) { /* * Assume 100KHz for all devices. We don't need to go fast * ever. Also turn off direct mode and disable interrupts. */ SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_FREQ), K_SMB_FREQ_100KHZ); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_CONTROL), 0); return 0; }
static void temp_smbus_init(int chan) { uintptr_t reg; reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_FREQ)); SBWRITECSR(reg,K_SMB_FREQ_100KHZ); /* 400Khz clock */ reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CONTROL)); SBWRITECSR(reg,0); /* not in direct mode, no interrupts, will poll */ }
static int temp_smbus_write(int chan,int slaveaddr,int devaddr,int data) { uintptr_t reg; int err; /* * Make sure the bus is idle (probably should * ignore error here) */ if (temp_smbus_waitready(chan) < 0) return -1; /* * Write the device address to the controller. There are two * parts, the high part goes in the "CMD" field, and the * low part is the data field. */ reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD)); SBWRITECSR(reg,devaddr); /* * Write the data byte */ reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA)); SBWRITECSR(reg,data); /* * Do the write command. */ reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START)); SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_WR2BYTE) | slaveaddr); err = temp_smbus_waitready(chan); return err; }
/* * Write to SMBus */ static int bcm1250_smbus_write(int smb_chan, UINT8 slave, UINT8 *buf, int len) { int err; /* * Make sure the bus is idle (ignore error here) */ bcm1250_smbus_waitready(smb_chan); /* * Depending on how many bytes we're writing, fill in the various * SMB registers and execute the command. */ switch (len) { case 1: /* "command" byte alone */ SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_CMD), buf[0]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_WR1BYTE) | ((UINT64)slave)); break; case 2: /* "command" byte plus a data byte */ SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_CMD), buf[0]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_DATA), buf[1]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_WR2BYTE) | ((UINT64)slave)); break; case 3: /* "command" byte plus 2 data bytes */ SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_CMD), buf[0]); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_DATA), ((UINT64)(buf[1])) | (((UINT64)buf[2]) << 8)); SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_WR3BYTE) | ((UINT64)slave)); break; default: return -1; break; } /* * Wait for command to complete. */ err = bcm1250_smbus_waitready(smb_chan); if (err < 0) return err; return 0; }
static int ui_cmd_mreset(ui_cmdline_t *cmd,int argc,char *argv[]) { char *x; int val; if ((x = cmd_getarg(cmd,0))) { val = atoi(x); if (val) { SBWRITECSR(A_GPIO_PIN_SET,M_GPIO_MONTEREY_RESET); } else { SBWRITECSR(A_GPIO_PIN_CLR,M_GPIO_MONTEREY_RESET); } printf("Monterey reset pin set to %d\n",val ? 1 : 0); } else { SBWRITECSR(A_GPIO_PIN_CLR,M_GPIO_MONTEREY_RESET); cfe_sleep(2); SBWRITECSR(A_GPIO_PIN_SET,M_GPIO_MONTEREY_RESET); printf("Monterey has been reset.\n"); } return 0; }
/* ********************************************************************* * temp_smbus_waitready(chan) * * Wait until the SMBus channel is ready. We simply poll * the busy bit until it clears. * * Input parameters: * chan - channel (0 or 1) * * Return value: * nothing ********************************************************************* */ static int temp_smbus_waitready(int chan) { uintptr_t reg; uint64_t status; reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_STATUS)); for (;;) { status = SBREADCSR(reg); if (status & M_SMB_BUSY) continue; break; } if (status & M_SMB_ERROR) { SBWRITECSR(reg,(status & M_SMB_ERROR)); return -1; } return 0; }
/* * read from SMBus */ static int bcm1250_smbus_read(int smb_chan, UINT8 slave, UINT8 *buf, int len) { int err; while (len > 0) { err = bcm1250_smbus_waitready(smb_chan); if (err < 0) return err; SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_START), V_SMB_TT(K_SMB_TT_RD1BYTE) | ((UINT64)slave)); err = bcm1250_smbus_waitready(smb_chan); if (err < 0) return err; *buf++ = (UINT8) SBREADCSR(A_SMB_REGISTER(smb_chan, R_SMB_DATA)); len--; } return 0; }
/* * Wait for SMBus */ static int bcm1250_smbus_waitready(int smb_chan) { UINT64 status = 0; int cnt = 10000000; /* about 1 second at 1Ghz */ while (cnt > 0) { status = SBREADCSR(A_SMB_REGISTER(smb_chan, R_SMB_STATUS)); if (status & M_SMB_BUSY) { cnt--; continue; } break; } if (cnt == 0) return -1; if (status & M_SMB_ERROR) { SBWRITECSR(A_SMB_REGISTER(smb_chan, R_SMB_STATUS), (status & M_SMB_ERROR)); return -1; } return 0; }
static int ui_cmd_reset(ui_cmdline_t *cmd,int argc,char *argv[]) { uint64_t data; uint64_t olddata; int confirm = 1; char str[50]; data = SBREADCSR(A_SCD_SYSTEM_CFG) & ~M_SYS_SB_SOFTRES; olddata = data; if (cmd_sw_isset(cmd,"-yes")) confirm = 0; if (cmd_sw_isset(cmd,"-softreset")) data |= M_SYS_SB_SOFTRES; if (cmd_sw_isset(cmd,"-unicpu0")) data |= M_SYS_UNICPU0; else if (cmd_sw_isset(cmd,"-unicpu1")) data |= M_SYS_UNICPU1; if (cmd_sw_isset(cmd,"-sysreset")) data |= M_SYS_SYSTEM_RESET; if (cmd_sw_isset(cmd,"-cpu")) data |= (M_SYS_CPU_RESET_0 | M_SYS_CPU_RESET_1); if (data == olddata) { /* no changes to reset pins were specified */ return ui_showusage(cmd); } if (confirm) { console_readline("Are you sure you want to reset? ",str,sizeof(str)); if ((str[0] != 'Y') && (str[0] != 'y')) return -1; } SBWRITECSR(A_SCD_SYSTEM_CFG,data); /* should not return */ return -1; }