|
@ -128,6 +128,12 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev) |
|
|
if (devResourceGet(pHcf, "reqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->reqIsr) != OK) { |
|
|
if (devResourceGet(pHcf, "reqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->reqIsr) != OK) { |
|
|
pDrvCtrl->reqIsr = NULL; |
|
|
pDrvCtrl->reqIsr = NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
if (devResourceGet(pHcf, "isReady", HCF_RES_ADDR, (void *)&pDrvCtrl->isReady) != OK) { |
|
|
|
|
|
pDrvCtrl->isReady = NULL; |
|
|
|
|
|
} |
|
|
|
|
|
if (devResourceGet(pHcf, "ackIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->ackIrq) != OK) { |
|
|
|
|
|
pDrvCtrl->ackIrq = NULL; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
pDrvCtrl->read = sm2130BusDevRead; |
|
|
pDrvCtrl->read = sm2130BusDevRead; |
|
@ -140,7 +146,7 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev) |
|
|
LOCAL SM2310_DEV_HANDLE *drv1553bOpen(SM2310_DEV_HANDLE *dev, const char *name, int flags, int mode) |
|
|
LOCAL SM2310_DEV_HANDLE *drv1553bOpen(SM2310_DEV_HANDLE *dev, const char *name, int flags, int mode) |
|
|
{ |
|
|
{ |
|
|
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; |
|
|
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; |
|
|
|
|
|
|
|
|
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); |
|
|
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); |
|
|
++pDrvCtrl->refcount; |
|
|
++pDrvCtrl->refcount; |
|
|
(void)semGive(pDrvCtrl->muteSem); |
|
|
(void)semGive(pDrvCtrl->muteSem); |
|
@ -157,34 +163,125 @@ LOCAL int drv1553bClose(SM2310_DEV_HANDLE *dev) |
|
|
return (OK); |
|
|
return (OK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
LOCAL int doXferMem(SM2130_SPI_DEV * pDrvCtrl, SM2130_MEM_XFER *mxfr) |
|
|
LOCAL int readReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer) |
|
|
{ |
|
|
{ |
|
|
STATUS ret = OK; |
|
|
UINT8 cmd; |
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
if (mxfr->type == XFER_TYPE_WR) { |
|
|
if (xfer->reg <= 15) { |
|
|
for (i = 0; i < mxfr->count; ++i) { |
|
|
cmd = (xfer->reg << 2); |
|
|
pDrvCtrl->write(pDrvCtrl->pDev, mxfr->regbuf[i], mxfr->membuf[i]); |
|
|
|
|
|
} |
|
|
|
|
|
} else if (mxfr->type == XFER_TYPE_RD) { |
|
|
|
|
|
for (i = 0; i < mxfr->count; ++i) { |
|
|
|
|
|
mxfr->membuf[i] = pDrvCtrl->read(pDrvCtrl->pDev, mxfr->regbuf[i]); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
ret = ERROR; |
|
|
cmd = xfer->reg & 0xff; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return (OK); |
|
|
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, cmd); |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LOCAL int writeReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer) |
|
|
|
|
|
{ |
|
|
|
|
|
UINT8 cmd; |
|
|
|
|
|
|
|
|
|
|
|
if (xfer->reg <= 63) { |
|
|
|
|
|
cmd = 0x80 | (xfer->reg & 0x3f); |
|
|
|
|
|
} else { |
|
|
|
|
|
cmd = xfer->reg & 0xff; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pDrvCtrl->write(pDrvCtrl->pDev, cmd, xfer->val); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LOCAL int setMemAddress(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer) |
|
|
|
|
|
{ |
|
|
|
|
|
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 }; |
|
|
|
|
|
UINT8 cmd; |
|
|
|
|
|
transInfo.txBuf = &cmd; |
|
|
|
|
|
transInfo.txLen = 1; |
|
|
|
|
|
|
|
|
|
|
|
if (xfer->reg >= 0xb && xfer->reg <= 0xE) { |
|
|
|
|
|
cmd =(xfer->reg - 0xB) + 0xD8; |
|
|
|
|
|
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); |
|
|
|
|
|
return pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | xfer->reg, xfer->val); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
errnoSet(EINVAL); |
|
|
|
|
|
return ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LOCAL int readMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr) |
|
|
|
|
|
{ |
|
|
|
|
|
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 }; |
|
|
|
|
|
UINT8 *ptr; |
|
|
|
|
|
UINT8 cmd; |
|
|
|
|
|
|
|
|
|
|
|
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) { |
|
|
|
|
|
errnoSet(EINVAL); |
|
|
|
|
|
return ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) { |
|
|
|
|
|
cmd =(mxfr->reg - 0xB) + 0xD8; |
|
|
|
|
|
transInfo.txBuf = &cmd; |
|
|
|
|
|
transInfo.txLen = 1; |
|
|
|
|
|
|
|
|
|
|
|
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); |
|
|
|
|
|
|
|
|
|
|
|
pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cmd = 0x40; |
|
|
|
|
|
ptr = (UINT8 *)pDrvCtrl->regmem; |
|
|
|
|
|
transInfo.txBuf = &cmd; |
|
|
|
|
|
transInfo.txLen = 1; |
|
|
|
|
|
transInfo.rxBuf = ptr; |
|
|
|
|
|
transInfo.rxLen = 1 + mxfr->count * 2; |
|
|
|
|
|
|
|
|
|
|
|
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); |
|
|
|
|
|
|
|
|
|
|
|
memcpy(mxfr->membuf, ptr + 1, mxfr->count * 2); |
|
|
|
|
|
return OK; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr) |
|
|
|
|
|
{ |
|
|
|
|
|
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 }; |
|
|
|
|
|
UINT8 *ptr; |
|
|
|
|
|
UINT8 cmd; |
|
|
|
|
|
|
|
|
|
|
|
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) { |
|
|
|
|
|
errnoSet(EINVAL); |
|
|
|
|
|
return ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) { |
|
|
|
|
|
cmd =(mxfr->reg - 0xB) + 0xD8; |
|
|
|
|
|
transInfo.txBuf = &cmd; |
|
|
|
|
|
transInfo.txLen = 1; |
|
|
|
|
|
|
|
|
|
|
|
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); |
|
|
|
|
|
|
|
|
|
|
|
pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ptr = (UINT8 *)pDrvCtrl->regmem; |
|
|
|
|
|
ptr[0] = 0xC0; |
|
|
|
|
|
memcpy(ptr + 1, (UINT8*)mxfr->membuf, mxfr->count * 2); |
|
|
|
|
|
transInfo.txBuf = ptr; |
|
|
|
|
|
transInfo.txLen = 1 + mxfr->count * 2; |
|
|
|
|
|
|
|
|
|
|
|
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); |
|
|
|
|
|
|
|
|
|
|
|
return OK; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) |
|
|
LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) |
|
|
{ |
|
|
{ |
|
|
SM2130_XFER *xfer; |
|
|
SM2130_XFER *xfer; |
|
|
SM2130_MEM_XFER *mxfr; |
|
|
|
|
|
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; |
|
|
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; |
|
|
STATUS ret = OK; |
|
|
STATUS ret = OK; |
|
|
|
|
|
|
|
|
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); |
|
|
semTake(pDrvCtrl->muteSem, WAIT_FOREVER); |
|
|
switch (cmd) { |
|
|
switch (cmd) { |
|
|
case FIOSELECT: |
|
|
case FIOSELECT: |
|
|
ret = selNodeAdd(&dev->selList, (SEL_WAKEUP_NODE *)arg); |
|
|
ret = selNodeAdd(&dev->selList, (SEL_WAKEUP_NODE *)arg); |
|
@ -200,11 +297,28 @@ LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) |
|
|
xfer = (SM2130_XFER *)(arg); |
|
|
xfer = (SM2130_XFER *)(arg); |
|
|
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, xfer->reg); |
|
|
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, xfer->reg); |
|
|
break; |
|
|
break; |
|
|
case FIOC_SM2130_MEM: |
|
|
case FIOC_SM2130_READY: |
|
|
mxfr = (SM2130_MEM_XFER *)(arg); |
|
|
if (pDrvCtrl->isReady) { |
|
|
if (mxfr) { |
|
|
*(int *)(arg) = pDrvCtrl->isReady(); |
|
|
doXferMem(pDrvCtrl, mxfr); |
|
|
} else { |
|
|
|
|
|
errnoSet(EIO); |
|
|
|
|
|
ret = ERROR; |
|
|
} |
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case FIOC_SM2130_REGRD: |
|
|
|
|
|
ret = readReg(pDrvCtrl, (SM2130_XFER *)(arg)); |
|
|
|
|
|
break; |
|
|
|
|
|
case FIOC_SM2130_REGWR: |
|
|
|
|
|
ret = writeReg(pDrvCtrl, (SM2130_XFER *)(arg)); |
|
|
|
|
|
break; |
|
|
|
|
|
case FIOC_SM2130_SMADDR: |
|
|
|
|
|
ret = setMemAddress(pDrvCtrl, (SM2130_XFER *)(arg)); |
|
|
|
|
|
break; |
|
|
|
|
|
case FIOC_SM2130_RDMEM: |
|
|
|
|
|
ret = readMemory(pDrvCtrl, (SM2130_MEM_XFER *)(arg)); |
|
|
|
|
|
break; |
|
|
|
|
|
case FIOC_SM2130_WRMEM: |
|
|
|
|
|
ret = writeMemory(pDrvCtrl, (SM2130_MEM_XFER *)(arg)); |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
|
printf("sm2130 unsupported ioctl: %d\r\n", cmd); |
|
|
printf("sm2130 unsupported ioctl: %d\r\n", cmd); |
|
@ -244,12 +358,18 @@ LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev) |
|
|
/* Retrieve the SPI master special information */ |
|
|
/* Retrieve the SPI master special information */ |
|
|
if (pFunc != NULL) |
|
|
if (pFunc != NULL) |
|
|
(*pFunc)(vxbDevParent(pDev), &pDrvCtrl->specialInfo); |
|
|
(*pFunc)(vxbDevParent(pDev), &pDrvCtrl->specialInfo); |
|
|
|
|
|
pDrvCtrl->irqStage = -128; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
LOCAL void sm1553isr(void *data) |
|
|
LOCAL void sm1553isr(void *data) |
|
|
{ |
|
|
{ |
|
|
SM2310_DEV_HANDLE *dev = data; |
|
|
SM2310_DEV_HANDLE *dev = data; |
|
|
|
|
|
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; |
|
|
|
|
|
|
|
|
|
|
|
if (pDrvCtrl->ackIrq) { |
|
|
|
|
|
pDrvCtrl->ackIrq(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6); |
|
|
logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6); |
|
|
selWakeupAll(&dev->selList, SELREAD); |
|
|
selWakeupAll(&dev->selList, SELREAD); |
|
|
} |
|
|
} |
|
@ -296,7 +416,7 @@ LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev) |
|
|
pDrvCtrl->devHandle = dev; |
|
|
pDrvCtrl->devHandle = dev; |
|
|
dev->pDevCtrl = pDrvCtrl; |
|
|
dev->pDevCtrl = pDrvCtrl; |
|
|
if (pDrvCtrl->reqIsr) { |
|
|
if (pDrvCtrl->reqIsr) { |
|
|
pDrvCtrl->reqIsr(dev, sm1553isr); |
|
|
pDrvCtrl->irqStage = pDrvCtrl->reqIsr(dev, sm1553isr); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
#ifndef _VXBUS_BASIC_HWMEMLIB |
|
|
#ifndef _VXBUS_BASIC_HWMEMLIB |
|
@ -351,6 +471,19 @@ LOCAL STATUS sm2130SpiDevInstUnlink(VXB_DEVICE_ID pDev, void *unused) |
|
|
* |
|
|
* |
|
|
* ERRNO: N/A |
|
|
* ERRNO: N/A |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
LOCAL const char *checkReady(SM2130_SPI_DEV *pDrvCtrl) |
|
|
|
|
|
{ |
|
|
|
|
|
if (!pDrvCtrl->isReady()) { |
|
|
|
|
|
return "Unknown"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (pDrvCtrl->isReady()) { |
|
|
|
|
|
return "Ready"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return "Not Ready"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose) |
|
|
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose) |
|
|
{ |
|
|
{ |
|
|
SM2130_SPI_DEV *pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl; |
|
|
SM2130_SPI_DEV *pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl; |
|
@ -363,6 +496,8 @@ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose) |
|
|
printf(" devHandle: %p\n", pDrvCtrl->devHandle); |
|
|
printf(" devHandle: %p\n", pDrvCtrl->devHandle); |
|
|
printf(" refCount: %d\n", pDrvCtrl->refcount); |
|
|
printf(" refCount: %d\n", pDrvCtrl->refcount); |
|
|
printf(" reqIsr: %p\n", pDrvCtrl->reqIsr); |
|
|
printf(" reqIsr: %p\n", pDrvCtrl->reqIsr); |
|
|
|
|
|
printf(" irqStatus: %d\n", pDrvCtrl->irqStage); |
|
|
|
|
|
printf(" isReady: %s\n", checkReady(pDrvCtrl)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
@ -388,7 +523,7 @@ LOCAL STATUS sm2130BusDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var) |
|
|
VXB_ASSERT(pDev != NULL, ERROR) |
|
|
VXB_ASSERT(pDev != NULL, ERROR) |
|
|
buf[0] = cmd; |
|
|
buf[0] = cmd; |
|
|
buf[1] = var & 0xff; |
|
|
buf[1] = var & 0xff; |
|
|
buf[1] = (var >> 8) & 0xff; |
|
|
buf[2] = (var >> 8) & 0xff; |
|
|
|
|
|
|
|
|
transInfo.txBuf = buf; |
|
|
transInfo.txBuf = buf; |
|
|
transInfo.txLen = 3; |
|
|
transInfo.txLen = 3; |
|
|