Browse Source

improv sm2130 chip driver

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 2 weeks ago
parent
commit
caa486d56b
  1. 37
      bspApi.h
  2. 47
      bspStubs.c
  3. 68
      hwconf.c
  4. 251
      vxbSm2130SpiDev.c
  5. 29
      vxbSm2130SpiDev.h

37
bspApi.h

@ -15,13 +15,16 @@ extern "C" {
#define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR)
#define FIOC_SM2130_RD (__SM2130__IOC_MAGIC | XFER_TYPE_RD)
#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10)
#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10)
#define FIOC_SM2130_ACKIRQ (__SM2130__IOC_MAGIC | 0x11)
#define FIOC_SM2130_RST (__SM2130__IOC_MAGIC | 0x12)
#define FIOC_SM2130_REQISR (__SM2130__IOC_MAGIC | 0x13)
#define FIOC_SM2130_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
#define FIOC_SM2130_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
#define FIOC_SM2130_SMADDR (__SM2130__IOC_MAGIC | 0x23)
#define FIOC_SM2130_RDMEM (__SM2130__IOC_MAGIC | 0x24)
#define FIOC_SM2130_WRMEM (__SM2130__IOC_MAGIC | 0x25)
#define FIOC_SM2130_RDMEM (__SM2130__IOC_MAGIC | 0x24)
#define FIOC_SM2130_WRMEM (__SM2130__IOC_MAGIC | 0x25)
struct sm2130_xfer {
UINT8 reg;
@ -29,9 +32,11 @@ struct sm2130_xfer {
};
typedef struct sm2130_xfer SM2130_XFER;
#define SMX_MAX_WORDS (64)
struct sm2130_xfer_mem {
int count;
UINT8 reg;
int count;
UINT8 reg;
UINT16 address;
UINT16 *membuf;
};
@ -39,23 +44,23 @@ typedef struct sm2130_xfer_mem SM2130_MEM_XFER;
/* }}} */
/* {{{ spidev FIO_SPIXFER msgs */
#define FIO_XFER_TX (1 << 0)
#define FIO_XFER_RX (1 << 1)
#define FIO_XFER_TX (1 << 0)
#define FIO_XFER_RX (1 << 1)
#define FIO_XFER_DUPLEX ((FIO_XFER_TX) | (FIO_XFER_RX))
/* ioctl */
#define FIO_SPIXFER (('P' << 16) | 0x1001)
#define FIO_SPIXFER (('P' << 16) | 0x1001)
struct spi_xfer {
int len;
int xferDir;
UINT8 *txbuf;
UINT8 *rxbuf;
int len;
int xferDir;
UINT8 *txbuf;
UINT8 *rxbuf;
};
struct spi_xfer_msg {
int count;
struct spi_xfer *xfer;
int count;
struct spi_xfer *xfer;
};
/* }}} */

47
bspStubs.c

@ -8,6 +8,7 @@
#include <ioLib.h>
#include <sysSymTbl.h>
#include <fcntl.h>
#include <logLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/util/vxbParamSys.h>
#include "config.h"
@ -30,6 +31,7 @@ IMPORT int uenvInit();
IMPORT void lfsDevRegister(void);
IMPORT void vxbSpiRawDevRegister(void);
IMPORT void sysMsDelay(UINT delay);
IMPORT void sysUsDelay(int us);
/* bsp glue functions */
void bspPinMuxInitialize(void)
@ -109,27 +111,39 @@ void bspDriverRegiser(void)
}
/* {{{ 1553B IO */
/* GPIO1_A4 */
int bspSm1553bIrqConnect(void *data, void (*isr)(void *data))
/* MR: GPIO1_B7 (reset) */
void bspSm1553bReset(BOOL value)
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 1);
if (pDev == NULL) {
printf("Can't find ftGpio1\r\n");
return ERROR;
logMsg("Can't find ftGpio1\r\n", 1, 2, 3, 4, 5, 6);
return;
}
pCtrl = pDev->pDrvCtrl;
/* MR: GPIO1_B7 (reset) */
pCtrl->gpioOutput(pDev, 1, 7, 0);
sysMsDelay(10);
pCtrl->gpioOutput(pDev, 1, 7, 1);
pCtrl->gpioOutput(pDev, 1, 7, value);
}
/* GPIO1_A4 */
void bspSm1553bIrqConnect(void *data, void (*isr)(void *data))
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 1);
if (pDev == NULL) {
logMsg("Can't find ftGpio1\r\n", 1, 2, 3, 4, 5, 6);
return;
}
pCtrl = pDev->pDrvCtrl;
/* GPIO1_A4 (irq) */
pCtrl->gpioISRSet(pDev, 4, isr, data);
return OK;
}
/* GPIO0_B7: SM2130_READY */
@ -140,7 +154,7 @@ int bspSm1553bChipReady(void)
pDev = vxbInstByNameFind("ftGpio", 0);
if (pDev == NULL) {
printf("Can't find ftGpio0\r\n");
logMsg("Can't find ftGpio0\r\n", 1, 2, 3, 4, 5, 6);
return 0;
}
pCtrl = pDev->pDrvCtrl;
@ -148,9 +162,20 @@ int bspSm1553bChipReady(void)
return pCtrl->gpioInput(pDev, 1, 7);
}
void bspSm1553bAckIrq(void)
/* GPIO0_B6: M2130_ACKIRQ */
void bspSm1553bAckIrq(BOOL value)
{
logMsg("Sm1553b Irq\r\n", 1, 2, 3, 4, 5, 6);
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 0);
if (pDev == NULL) {
return;
}
pCtrl = pDev->pDrvCtrl;
pCtrl->gpioOutput(pDev, 1, 6, value);
logMsg("ackirq Sm1553b Irq\r\n", 1, 2, 3, 4, 5, 6);
}
/* }}} */

68
hwconf.c

@ -150,7 +150,7 @@ LOCAL const struct intrCtlrTrigger gicTrigger[] = {
/* pin, sensitivity */
{ INT_VEC_GPIO0INTR, VXB_INTR_TRIG_RISING_EDGE },
{ INT_VEC_GPIO1INTR, VXB_INTR_TRIG_RISING_EDGE },
{ INT_VEC_GPIO1INTR, VXB_INTR_TRIG_FALLING_EDGE },
};
@ -382,12 +382,12 @@ LOCAL UINT8 gpio0PortBModeTable[] = {
0, 0, 0, 0, 0, 0, 2, 1 /* GPIO0_B6: SM2130_ACKIRQ; GPIO0_B7: SM2130_READY */
};
struct hcfResource gpioDev0Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_0_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio0PortAModeTable[0] } },
{ "regBase", HCF_RES_INT, { (void *)GPIO_0_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio0PortAModeTable[0] } },
{ "portAModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio0PortAModeTable)} },
{ "portBModeTable", HCF_RES_ADDR, { (void *)&gpio0PortBModeTable[0] } },
{ "portBModeTable", HCF_RES_ADDR, { (void *)&gpio0PortBModeTable[0] } },
{ "portBModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio0PortBModeTable)} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_RISING_EDGE} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_RISING_EDGE } },
};
#define gpioDev0Num NELEMENTS(gpioDev0Resources)
@ -401,21 +401,21 @@ LOCAL UINT8 gpio1PortBModeTable[] = {
0, 0, 0, 0, 0, 0, 0, 2 /* GPIO1_B7: SM2130_MR */
};
struct hcfResource gpioDev1Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_1_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio1PortAModeTable[0] } },
{ "regBase", HCF_RES_INT, { (void *)GPIO_1_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio1PortAModeTable[0] } },
{ "portAModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio1PortAModeTable)} },
{ "portBModeTable", HCF_RES_ADDR, { (void *)&gpio1PortBModeTable[0] } },
{ "portBModeTable", HCF_RES_ADDR, { (void *)&gpio1PortBModeTable[0] } },
{ "portBModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio1PortBModeTable)} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_RISING_EDGE} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_FALLING_EDGE } },
};
#define gpioDev1Num NELEMENTS(gpioDev1Resources)
#endif
#ifdef DRV_ARM_GEN_SYS_TIMER
struct hcfResource armGenSysTimerResources[] = {
{ "regBase", HCF_RES_INT, {(void *)0xeeee0000} },
{ "irq", HCF_RES_INT, {(void *)GEN_TIMER_IRQ} },
{ "clkFreq", HCF_RES_INT, {(void *)SYS_CLK_FREQ} },
{ "regBase", HCF_RES_INT, {(void *)0xeeee0000 } },
{ "irq", HCF_RES_INT, {(void *)GEN_TIMER_IRQ } },
{ "clkFreq", HCF_RES_INT, {(void *)SYS_CLK_FREQ } },
{ "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} },
{ "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} },
};
@ -424,9 +424,9 @@ struct hcfResource armGenSysTimerResources[] = {
#ifdef DRV_ARM_GEN_AUX_TIMER
struct hcfResource armAuxGenTimerResources[] = {
{ "regBase", HCF_RES_INT, {(void *)AUX_CLK_REG_BASE} },
{ "irq", HCF_RES_INT, {(void *)AUX_GEN_TIMER_IRQ} },
{ "clkFreq", HCF_RES_INT, {(void *)AUX_CLK_FREQ} },
{ "regBase", HCF_RES_INT, {(void *)AUX_CLK_REG_BASE } },
{ "irq", HCF_RES_INT, {(void *)AUX_GEN_TIMER_IRQ } },
{ "clkFreq", HCF_RES_INT, {(void *)AUX_CLK_FREQ } },
{ "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} },
{ "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} },
};
@ -444,31 +444,31 @@ const struct hcfResource ftPci0Resources[] = {
{ "io32Addr", HCF_RES_ADDR, { (void *)0x50000000 } },
{ "io32Size", HCF_RES_INT, { (void *)0x08000000 } },
{ "io16Addr", HCF_RES_ADDR, { (void *)0x1000 } },
{ "io16Addr", HCF_RES_ADDR, { (void *)0x1000 } },
{ "io16Size", HCF_RES_INT, { (void *)0x0ffff000 } },
{ "ioStart", HCF_RES_ADDR, { (void *)0x50000000 } },
{ "ioStart", HCF_RES_ADDR, { (void *)0x50000000} },
{ "fbbEnable", HCF_RES_INT, { (void *)TRUE } },
{ "cacheSize", HCF_RES_INT, { (void *)(8) } },
{ "maxLatAllSet", HCF_RES_INT, { (void *)0x40 } },
{ "autoIntRouteSet", HCF_RES_INT, { (void *)FALSE } },
{ "fbbEnable", HCF_RES_INT, { (void *)TRUE } },
{ "cacheSize", HCF_RES_INT, { (void *)(8) } },
{ "maxLatAllSet", HCF_RES_INT, { (void *)0x40 } },
{ "autoIntRouteSet", HCF_RES_INT, { (void *)FALSE } },
{ "includeFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigInclude } },
{ "intAssignFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigIntrAssign } },
{ "funcPirqEnable", HCF_RES_ADDR, { (void *)sysPciPirqEnable}},
{ "maxBusSet", HCF_RES_INT, { (void *)32 } },
{ "maxBusSet", HCF_RES_INT, { (void *)32 } },
/* Window Attributes - Defaults to 8540 type if none given */
{ "autoConfig", HCF_RES_INT, { (void *)(FALSE)} },
{ "autoConfig", HCF_RES_INT, { (void *)(FALSE) } },
#ifdef INCLUDE_INTCTLR_DYNAMIC_LIB
{ "msiEnable", HCF_RES_INT, { (void *)(TRUE)} },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(TRUE)} }
{ "msiEnable", HCF_RES_INT, { (void *)(TRUE) } },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(TRUE) } }
#else
{ "msiEnable", HCF_RES_INT, { (void *)(FALSE)} },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(FALSE)} }
{ "msiEnable", HCF_RES_INT, { (void *)(FALSE) } },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(FALSE) } }
#endif /* INCLUDE_INTCTLR_DYNAMIC_LIB */
};
#define ftPci0Num NELEMENTS(ftPci0Resources)
@ -530,15 +530,17 @@ struct hcfResource lfsResources[] = {
#define lfsResNum NELEMENTS(lfsResources)
#endif
IMPORT int bspSm1553bIrqConnect(void *data, void (*isr)(void *data));
IMPORT void bspSm1553bIrqConnect(void *data, void (*isr)(void *data));
IMPORT int bspSm1553bChipReady(void);
IMPORT void bspSm1553bAckIrq(void);
IMPORT void bspSm1553bAckIrq(BOOL);
IMPORT void bspSm1553bReset(BOOL);
struct hcfResource sm2130Resources[] = {
{ "devName" , HCF_RES_STRING, {(void *)"/sm1553b"}},
{ "reqIsr" , HCF_RES_ADDR, {(void *)bspSm1553bIrqConnect}},
{ "isReady" , HCF_RES_ADDR, {(void *)bspSm1553bChipReady}},
{ "ackIrq" , HCF_RES_ADDR, {(void *)bspSm1553bAckIrq}},
{ "devName" , HCF_RES_STRING, {(void *)"/sm1553b" } },
{ "funcReqIsr" , HCF_RES_ADDR, {(void *)bspSm1553bIrqConnect } },
{ "funcIsReady" , HCF_RES_ADDR, {(void *)bspSm1553bChipReady } },
{ "funcAckIrq" , HCF_RES_ADDR, {(void *)bspSm1553bAckIrq } },
{ "funcReset" , HCF_RES_ADDR, {(void *)bspSm1553bReset } },
};
#define sm2130ResNum NELEMENTS(sm2130Resources)

251
vxbSm2130SpiDev.c

@ -28,11 +28,16 @@ typedef struct _Sm2310_DEV_HANDLE {
SEL_WAKEUP_LIST selList;
void (*usrIsr)();
SM2130_SPI_DEV *pDevCtrl;
} SM2310_DEV_HANDLE;
LOCAL int sm2130_driver_node = -1;
/* Declare */
IMPORT void sysUsDelay(UINT32 us);
/* locals */
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose);
LOCAL INT32 sm2130BusDevRead(VXB_DEVICE_ID pDev, UINT8 cmd);
@ -118,21 +123,25 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev)
pDrvCtrl->devHandle = NULL;
snprintf(pDrvCtrl->name, sizeof (pDrvCtrl->name), "%s/%d", SM2130_DEV_NAME, pDev->unitNumber);
snprintf(pDrvCtrl->name, sizeof(pDrvCtrl->name), "%s/%d", SM2130_DEV_NAME, pDev->unitNumber);
pDrvCtrl->devName = pDrvCtrl->name;
pHcf = (struct hcfDevice *)hcfDeviceGet(pDev);
if (pHcf) {
if (devResourceGet(pHcf, "devName", HCF_RES_STRING, (void *)&pDrvCtrl->devName) != OK) {
pDrvCtrl->devName = pDrvCtrl->name;
}
if (devResourceGet(pHcf, "reqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->reqIsr) != OK) {
pDrvCtrl->reqIsr = NULL;
if (devResourceGet(pHcf, "funcReqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->funcReqIsr) != OK) {
pDrvCtrl->funcReqIsr = NULL;
}
if (devResourceGet(pHcf, "isReady", HCF_RES_ADDR, (void *)&pDrvCtrl->isReady) != OK) {
pDrvCtrl->isReady = NULL;
if (devResourceGet(pHcf, "funcIsReady", HCF_RES_ADDR, (void *)&pDrvCtrl->funcIsReady) != OK) {
pDrvCtrl->funcIsReady = NULL;
}
if (devResourceGet(pHcf, "ackIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->ackIrq) != OK) {
pDrvCtrl->ackIrq = NULL;
if (devResourceGet(pHcf, "funcAckIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->funcAckIrq) != OK) {
pDrvCtrl->funcAckIrq = NULL;
}
if (devResourceGet(pHcf, "funcReset", HCF_RES_ADDR, (void *)&pDrvCtrl->funcReset) != OK) {
pDrvCtrl->funcReset = NULL;
}
}
@ -147,9 +156,14 @@ LOCAL SM2310_DEV_HANDLE *drv1553bOpen(SM2310_DEV_HANDLE *dev, const char *name,
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
if (pDrvCtrl->refcount > 0) {
errnoSet(EBUSY);
return (void *)ERROR;
}
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
++pDrvCtrl->refcount;
(void)semGive(pDrvCtrl->muteSem);
semGive(pDrvCtrl->muteSem);
return dev;
}
@ -157,39 +171,39 @@ LOCAL int drv1553bClose(SM2310_DEV_HANDLE *dev)
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
--pDrvCtrl->refcount;
(void)semGive(pDrvCtrl->muteSem);
semGive(pDrvCtrl->muteSem);
return (OK);
}
LOCAL int readReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
{
UINT8 cmd;
UINT8 cmd;
if (xfer->reg <= 15) {
cmd = (xfer->reg << 2);
} else {
cmd = xfer->reg & 0xff;
}
if (xfer->reg <= 15) {
cmd = (xfer->reg << 2);
} else {
cmd = xfer->reg & 0xff;
}
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, cmd);
return 0;
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, cmd);
return 0;
}
LOCAL int writeReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
{
UINT8 cmd;
UINT8 cmd;
if (xfer->reg <= 63) {
cmd = 0x80 | (xfer->reg & 0x3f);
} else {
cmd = xfer->reg & 0xff;
}
if (xfer->reg <= 63) {
cmd = 0x80 | (xfer->reg & 0x3f);
} else {
cmd = xfer->reg & 0xff;
}
pDrvCtrl->write(pDrvCtrl->pDev, cmd, xfer->val);
pDrvCtrl->write(pDrvCtrl->pDev, cmd, xfer->val);
return 0;
return 0;
}
LOCAL int setMemAddress(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
@ -200,7 +214,7 @@ LOCAL int setMemAddress(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
transInfo.txLen = 1;
if (xfer->reg >= 0xb && xfer->reg <= 0xE) {
cmd =(xfer->reg - 0xB) + 0xD8;
cmd = (xfer->reg - 0xB) + 0xD8;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
return pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | xfer->reg, xfer->val);
}
@ -215,13 +229,13 @@ LOCAL int readMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
UINT8 *ptr;
UINT8 cmd;
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) {
if ((mxfr->count <= 0) || (mxfr->count > SMX_MAX_WORDS)) {
errnoSet(EINVAL);
return ERROR;
}
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) {
cmd =(mxfr->reg - 0xB) + 0xD8;
cmd = (mxfr->reg - 0xB) + 0xD8;
transInfo.txBuf = &cmd;
transInfo.txLen = 1;
@ -239,7 +253,7 @@ LOCAL int readMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
memcpy(mxfr->membuf, ptr + 1, mxfr->count * 2);
memcpy(mxfr->membuf, ptr + 1, mxfr->count * 2);
return OK;
}
@ -249,13 +263,13 @@ LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
UINT8 *ptr;
UINT8 cmd;
if ((mxfr->count <= 0) || (mxfr->count >= (sizeof (pDrvCtrl->regmem) / sizeof (pDrvCtrl->regmem[0])))) {
if ((mxfr->count <= 0) || (mxfr->count > SMX_MAX_WORDS)) {
errnoSet(EINVAL);
return ERROR;
}
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) {
cmd =(mxfr->reg - 0xB) + 0xD8;
cmd = (mxfr->reg - 0xB) + 0xD8;
transInfo.txBuf = &cmd;
transInfo.txLen = 1;
@ -266,7 +280,7 @@ LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
ptr = (UINT8 *)pDrvCtrl->regmem;
ptr[0] = 0xC0;
memcpy(ptr + 1, (UINT8*)mxfr->membuf, mxfr->count * 2);
memcpy(ptr + 1, (UINT8 *)mxfr->membuf, mxfr->count * 2);
transInfo.txBuf = ptr;
transInfo.txLen = 1 + mxfr->count * 2;
@ -275,6 +289,58 @@ LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
return OK;
}
LOCAL ssize_t drv1553bRead(SM2310_DEV_HANDLE *dev, char *buffer, size_t maxbytes)
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
int max_words = maxbytes / 2;
SM2130_MEM_XFER smx = { 0, 0, 0, NULL };
STATUS error;
if (max_words > SMX_MAX_WORDS) {
max_words = SMX_MAX_WORDS;
}
smx.count = max_words;
smx.membuf = (UINT16 *)buffer;
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
error = readMemory(pDrvCtrl, &smx);
semGive(pDrvCtrl->muteSem);
if (error != OK) {
errnoSet(EIO);
return -1;
}
return max_words * 2;
}
LOCAL ssize_t drv1553bWrite(SM2310_DEV_HANDLE *dev, char *buffer, size_t nbytes)
{
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
int max_words = nbytes / 2;
SM2130_MEM_XFER smx = { 0, 0, 0, NULL };
STATUS error;
if (max_words > SMX_MAX_WORDS) {
max_words = SMX_MAX_WORDS;
}
smx.count = max_words;
smx.membuf = (UINT16 *)buffer;
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
error = writeMemory(pDrvCtrl, &smx);
semGive(pDrvCtrl->muteSem);
if (error != OK) {
errnoSet(EIO);
return -1;
}
return max_words * 2;
}
LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg)
{
SM2130_XFER *xfer;
@ -290,27 +356,64 @@ LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg)
ret = selNodeDelete(&dev->selList, (SEL_WAKEUP_NODE *)arg);
break;
case FIOC_SM2130_WR:
xfer = (SM2130_XFER *)(arg);
pDrvCtrl->write(pDrvCtrl->pDev, xfer->reg, xfer->val);
break;
xfer = (SM2130_XFER *)(arg);
pDrvCtrl->write(pDrvCtrl->pDev, xfer->reg, xfer->val);
break;
case FIOC_SM2130_RD:
xfer = (SM2130_XFER *)(arg);
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, xfer->reg);
break;
xfer = (SM2130_XFER *)(arg);
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, xfer->reg);
break;
case FIOC_SM2130_RST:
if (pDrvCtrl->funcReset) {
UINT32 us = (UINT32)arg;
if (us == 0) {
us = 10000;
}
pDrvCtrl->funcReset(TRUE);
sysUsDelay(us);
pDrvCtrl->funcReset(FALSE);
} else {
errnoSet(ENOTSUP);
ret = ERROR;
}
break;
case FIOC_SM2130_REQISR:
dev->usrIsr = (void *)(arg);
break;
case FIOC_SM2130_ACKIRQ:
if (pDrvCtrl->funcAckIrq) {
if (pDrvCtrl->irqCount > 0) {
UINT32 us = (UINT32)arg;
if (us == 0) {
us = 100;
}
pDrvCtrl->funcAckIrq(TRUE);
sysUsDelay(us);
pDrvCtrl->funcAckIrq(FALSE);
}
} else {
errnoSet(ENOTSUP);
ret = ERROR;
}
pDrvCtrl->irqCount = 0;
break;
case FIOC_SM2130_READY:
if (pDrvCtrl->isReady) {
*(int *)(arg) = pDrvCtrl->isReady();
} else {
errnoSet(EIO);
ret = ERROR;
}
break;
if (pDrvCtrl->funcIsReady) {
*(int *)(arg) = pDrvCtrl->funcIsReady();
} else {
errnoSet(EIO);
ret = ERROR;
}
break;
case FIOC_SM2130_REGRD:
ret = readReg(pDrvCtrl, (SM2130_XFER *)(arg));
break;
ret = readReg(pDrvCtrl, (SM2130_XFER *)(arg));
break;
case FIOC_SM2130_REGWR:
ret = writeReg(pDrvCtrl, (SM2130_XFER *)(arg));
break;
ret = writeReg(pDrvCtrl, (SM2130_XFER *)(arg));
break;
case FIOC_SM2130_SMADDR:
ret = setMemAddress(pDrvCtrl, (SM2130_XFER *)(arg));
break;
@ -358,7 +461,6 @@ LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev)
/* Retrieve the SPI master special information */
if (pFunc != NULL)
(*pFunc)(vxbDevParent(pDev), &pDrvCtrl->specialInfo);
pDrvCtrl->irqStage = -128;
}
LOCAL void sm1553isr(void *data)
@ -366,11 +468,13 @@ LOCAL void sm1553isr(void *data)
SM2310_DEV_HANDLE *dev = data;
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
if (pDrvCtrl->ackIrq) {
pDrvCtrl->ackIrq();
++pDrvCtrl->irqCount;
//logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6);
if (dev->usrIsr) {
dev->usrIsr();
}
logMsg("sm1553isr interrupt", 1, 2, 3, 4, 5, 6);
selWakeupAll(&dev->selList, SELREAD);
}
@ -400,23 +504,34 @@ LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev)
(DRV_REMOVE_PTR)NULL ,
(DRV_OPEN_PTR)drv1553bOpen ,
(DRV_CLOSE_PTR)drv1553bClose ,
(DRV_READ_PTR)NULL ,
(DRV_WRITE_PTR)NULL ,
(DRV_READ_PTR)drv1553bRead ,
(DRV_WRITE_PTR)drv1553bWrite ,
(DRV_IOCTL_PTR)drv1553bIoctl);
/* clang-format on */
}
if (pDrvCtrl->funcAckIrq) {
pDrvCtrl->funcAckIrq(FALSE);
}
if (pDrvCtrl->funcReset) {
pDrvCtrl->funcReset(FALSE);
sysUsDelay(10000);
pDrvCtrl->funcReset(TRUE);
}
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
if (sm2130_driver_node > 0) {
dev = (SM2310_DEV_HANDLE *)hwMemAlloc(sizeof(SM2310_DEV_HANDLE));
if (dev) {
pDrvCtrl->refcount = 0;
dev->usrIsr = NULL;
selWakeupListInit(&dev->selList);
if (iosDevAdd(&dev->devHdr, pDrvCtrl->devName, sm2130_driver_node) == OK) {
pDrvCtrl->devHandle = dev;
dev->pDevCtrl = pDrvCtrl;
if (pDrvCtrl->reqIsr) {
pDrvCtrl->irqStage = pDrvCtrl->reqIsr(dev, sm1553isr);
if (pDrvCtrl->funcReqIsr) {
pDrvCtrl->funcReqIsr(dev, sm1553isr);
}
} else {
#ifndef _VXBUS_BASIC_HWMEMLIB
@ -473,15 +588,15 @@ LOCAL STATUS sm2130SpiDevInstUnlink(VXB_DEVICE_ID pDev, void *unused)
*/
LOCAL const char *checkReady(SM2130_SPI_DEV *pDrvCtrl)
{
if (!pDrvCtrl->isReady()) {
return "Unknown";
}
if (!pDrvCtrl->funcIsReady) {
return "Unknown";
}
if (pDrvCtrl->isReady()) {
return "Ready";
}
if (pDrvCtrl->funcIsReady()) {
return "Ready";
}
return "Not Ready";
return "Not Ready";
}
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose)
@ -495,8 +610,8 @@ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose)
printf(" devName: %s\n", pDrvCtrl->devName);
printf(" devHandle: %p\n", pDrvCtrl->devHandle);
printf(" refCount: %d\n", pDrvCtrl->refcount);
printf(" reqIsr: %p\n", pDrvCtrl->reqIsr);
printf(" irqStatus: %d\n", pDrvCtrl->irqStage);
printf(" funcReqIsr: %p\n", pDrvCtrl->funcReqIsr);
printf(" irqCount: %u\n", pDrvCtrl->irqCount);
printf(" isReady: %s\n", checkReady(pDrvCtrl));
}

29
vxbSm2130SpiDev.h

@ -10,10 +10,13 @@
#define XFER_TYPE_WR (1)
#define XFER_TYPE_RD (2)
#define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR)
#define FIOC_SM2130_RD (__SM2130__IOC_MAGIC | XFER_TYPE_RD)
#define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR)
#define FIOC_SM2130_RD (__SM2130__IOC_MAGIC | XFER_TYPE_RD)
#define FIOC_SM2130_READY (__SM2130__IOC_MAGIC | 0x10)
#define FIOC_SM2130_ACKIRQ (__SM2130__IOC_MAGIC | 0x11)
#define FIOC_SM2130_RST (__SM2130__IOC_MAGIC | 0x12)
#define FIOC_SM2130_REQISR (__SM2130__IOC_MAGIC | 0x13)
#define FIOC_SM2130_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
@ -22,14 +25,15 @@
#define FIOC_SM2130_WRMEM (__SM2130__IOC_MAGIC | 0x25)
struct sm2130_xfer {
UINT8 reg;
UINT16 val;
UINT8 reg;
UINT16 val;
};
typedef struct sm2130_xfer SM2130_XFER;
#define SMX_MAX_WORDS (64)
struct sm2130_xfer_mem {
int count;
UINT8 reg;
int count;
UINT8 reg;
UINT16 address;
UINT16 *membuf;
};
@ -42,20 +46,21 @@ typedef struct _spi_1553b_drv_ctrl {
const char *devName;
int refcount;
volatile int refcount;
int irqStage;
volatile UINT32 irqCount;
void *devHandle;
int (*reqIsr)(void *data, void (*isr)(void *data));
int (*isReady)();
void (*ackIrq)();
int (*funcReqIsr)(void *data, void (*isr)(void *data));
int (*funcIsReady)();
void (*funcAckIrq)(BOOL);
void (*funcReset)(BOOL);
INT32 (*read)(VXB_DEVICE_ID pDev, UINT8 cmd);
STATUS (*write)(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var);
UINT16 regmem[64];
UINT16 regmem[SMX_MAX_WORDS+1]; /* add 1 dummy slot */
SEM_ID muteSem; /* operation semaphore */
VXB_SPI_MAST_SPEC *specialInfo;

Loading…
Cancel
Save