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. 49
      bspStubs.c
  3. 68
      hwconf.c
  4. 299
      vxbSm2130SpiDev.c
  5. 37
      vxbSm2130SpiDev.h

37
bspApi.h

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

49
bspStubs.c

@ -8,6 +8,7 @@
#include <ioLib.h> #include <ioLib.h>
#include <sysSymTbl.h> #include <sysSymTbl.h>
#include <fcntl.h> #include <fcntl.h>
#include <logLib.h>
#include <hwif/vxbus/vxBus.h> #include <hwif/vxbus/vxBus.h>
#include <hwif/util/vxbParamSys.h> #include <hwif/util/vxbParamSys.h>
#include "config.h" #include "config.h"
@ -30,6 +31,7 @@ IMPORT int uenvInit();
IMPORT void lfsDevRegister(void); IMPORT void lfsDevRegister(void);
IMPORT void vxbSpiRawDevRegister(void); IMPORT void vxbSpiRawDevRegister(void);
IMPORT void sysMsDelay(UINT delay); IMPORT void sysMsDelay(UINT delay);
IMPORT void sysUsDelay(int us);
/* bsp glue functions */ /* bsp glue functions */
void bspPinMuxInitialize(void) void bspPinMuxInitialize(void)
@ -109,27 +111,39 @@ void bspDriverRegiser(void)
} }
/* {{{ 1553B IO */ /* {{{ 1553B IO */
/* GPIO1_A4 */
int bspSm1553bIrqConnect(void *data, void (*isr)(void *data)) /* MR: GPIO1_B7 (reset) */
void bspSm1553bReset(BOOL value)
{ {
VXB_DEVICE_ID pDev; VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl; FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", 1); pDev = vxbInstByNameFind("ftGpio", 1);
if (pDev == NULL) { if (pDev == NULL) {
printf("Can't find ftGpio1\r\n"); logMsg("Can't find ftGpio1\r\n", 1, 2, 3, 4, 5, 6);
return ERROR; return;
} }
pCtrl = pDev->pDrvCtrl; pCtrl = pDev->pDrvCtrl;
/* MR: GPIO1_B7 (reset) */ /* MR: GPIO1_B7 (reset) */
pCtrl->gpioOutput(pDev, 1, 7, 0); pCtrl->gpioOutput(pDev, 1, 7, value);
sysMsDelay(10); }
pCtrl->gpioOutput(pDev, 1, 7, 1);
/* 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) */ /* GPIO1_A4 (irq) */
pCtrl->gpioISRSet(pDev, 4, isr, data); pCtrl->gpioISRSet(pDev, 4, isr, data);
return OK;
} }
/* GPIO0_B7: SM2130_READY */ /* GPIO0_B7: SM2130_READY */
@ -140,7 +154,7 @@ int bspSm1553bChipReady(void)
pDev = vxbInstByNameFind("ftGpio", 0); pDev = vxbInstByNameFind("ftGpio", 0);
if (pDev == NULL) { 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; return 0;
} }
pCtrl = pDev->pDrvCtrl; pCtrl = pDev->pDrvCtrl;
@ -148,9 +162,20 @@ int bspSm1553bChipReady(void)
return pCtrl->gpioInput(pDev, 1, 7); 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 */ /* pin, sensitivity */
{ INT_VEC_GPIO0INTR, VXB_INTR_TRIG_RISING_EDGE }, { 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 */ 0, 0, 0, 0, 0, 0, 2, 1 /* GPIO0_B6: SM2130_ACKIRQ; GPIO0_B7: SM2130_READY */
}; };
struct hcfResource gpioDev0Resources[] = { struct hcfResource gpioDev0Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_0_BASE_ADR } }, { "regBase", HCF_RES_INT, { (void *)GPIO_0_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio0PortAModeTable[0] } }, { "portAModeTable", HCF_RES_ADDR, { (void *)&gpio0PortAModeTable[0] } },
{ "portAModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio0PortAModeTable)} }, { "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)} }, { "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) #define gpioDev0Num NELEMENTS(gpioDev0Resources)
@ -401,21 +401,21 @@ LOCAL UINT8 gpio1PortBModeTable[] = {
0, 0, 0, 0, 0, 0, 0, 2 /* GPIO1_B7: SM2130_MR */ 0, 0, 0, 0, 0, 0, 0, 2 /* GPIO1_B7: SM2130_MR */
}; };
struct hcfResource gpioDev1Resources[] = { struct hcfResource gpioDev1Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_1_BASE_ADR } }, { "regBase", HCF_RES_INT, { (void *)GPIO_1_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio1PortAModeTable[0] } }, { "portAModeTable", HCF_RES_ADDR, { (void *)&gpio1PortAModeTable[0] } },
{ "portAModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio1PortAModeTable)} }, { "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)} }, { "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) #define gpioDev1Num NELEMENTS(gpioDev1Resources)
#endif #endif
#ifdef DRV_ARM_GEN_SYS_TIMER #ifdef DRV_ARM_GEN_SYS_TIMER
struct hcfResource armGenSysTimerResources[] = { struct hcfResource armGenSysTimerResources[] = {
{ "regBase", HCF_RES_INT, {(void *)0xeeee0000} }, { "regBase", HCF_RES_INT, {(void *)0xeeee0000 } },
{ "irq", HCF_RES_INT, {(void *)GEN_TIMER_IRQ} }, { "irq", HCF_RES_INT, {(void *)GEN_TIMER_IRQ } },
{ "clkFreq", HCF_RES_INT, {(void *)SYS_CLK_FREQ} }, { "clkFreq", HCF_RES_INT, {(void *)SYS_CLK_FREQ } },
{ "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} }, { "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} },
{ "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} }, { "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} },
}; };
@ -424,9 +424,9 @@ struct hcfResource armGenSysTimerResources[] = {
#ifdef DRV_ARM_GEN_AUX_TIMER #ifdef DRV_ARM_GEN_AUX_TIMER
struct hcfResource armAuxGenTimerResources[] = { struct hcfResource armAuxGenTimerResources[] = {
{ "regBase", HCF_RES_INT, {(void *)AUX_CLK_REG_BASE} }, { "regBase", HCF_RES_INT, {(void *)AUX_CLK_REG_BASE } },
{ "irq", HCF_RES_INT, {(void *)AUX_GEN_TIMER_IRQ} }, { "irq", HCF_RES_INT, {(void *)AUX_GEN_TIMER_IRQ } },
{ "clkFreq", HCF_RES_INT, {(void *)AUX_CLK_FREQ} }, { "clkFreq", HCF_RES_INT, {(void *)AUX_CLK_FREQ } },
{ "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} }, { "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} },
{ "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} }, { "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} },
}; };
@ -444,31 +444,31 @@ const struct hcfResource ftPci0Resources[] = {
{ "io32Addr", HCF_RES_ADDR, { (void *)0x50000000 } }, { "io32Addr", HCF_RES_ADDR, { (void *)0x50000000 } },
{ "io32Size", HCF_RES_INT, { (void *)0x08000000 } }, { "io32Size", HCF_RES_INT, { (void *)0x08000000 } },
{ "io16Addr", HCF_RES_ADDR, { (void *)0x1000 } }, { "io16Addr", HCF_RES_ADDR, { (void *)0x1000 } },
{ "io16Size", HCF_RES_INT, { (void *)0x0ffff000 } }, { "io16Size", HCF_RES_INT, { (void *)0x0ffff000 } },
{ "ioStart", HCF_RES_ADDR, { (void *)0x50000000 } }, { "ioStart", HCF_RES_ADDR, { (void *)0x50000000} },
{ "fbbEnable", HCF_RES_INT, { (void *)TRUE } }, { "fbbEnable", HCF_RES_INT, { (void *)TRUE } },
{ "cacheSize", HCF_RES_INT, { (void *)(8) } }, { "cacheSize", HCF_RES_INT, { (void *)(8) } },
{ "maxLatAllSet", HCF_RES_INT, { (void *)0x40 } }, { "maxLatAllSet", HCF_RES_INT, { (void *)0x40 } },
{ "autoIntRouteSet", HCF_RES_INT, { (void *)FALSE } }, { "autoIntRouteSet", HCF_RES_INT, { (void *)FALSE } },
{ "includeFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigInclude } }, { "includeFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigInclude } },
{ "intAssignFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigIntrAssign } }, { "intAssignFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigIntrAssign } },
{ "funcPirqEnable", HCF_RES_ADDR, { (void *)sysPciPirqEnable}}, { "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 */ /* 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 #ifdef INCLUDE_INTCTLR_DYNAMIC_LIB
{ "msiEnable", HCF_RES_INT, { (void *)(TRUE)} }, { "msiEnable", HCF_RES_INT, { (void *)(TRUE) } },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(TRUE)} } { "dynamicInterrupts", HCF_RES_INT, { (void *)(TRUE) } }
#else #else
{ "msiEnable", HCF_RES_INT, { (void *)(FALSE)} }, { "msiEnable", HCF_RES_INT, { (void *)(FALSE) } },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(FALSE)} } { "dynamicInterrupts", HCF_RES_INT, { (void *)(FALSE) } }
#endif /* INCLUDE_INTCTLR_DYNAMIC_LIB */ #endif /* INCLUDE_INTCTLR_DYNAMIC_LIB */
}; };
#define ftPci0Num NELEMENTS(ftPci0Resources) #define ftPci0Num NELEMENTS(ftPci0Resources)
@ -530,15 +530,17 @@ struct hcfResource lfsResources[] = {
#define lfsResNum NELEMENTS(lfsResources) #define lfsResNum NELEMENTS(lfsResources)
#endif #endif
IMPORT int bspSm1553bIrqConnect(void *data, void (*isr)(void *data)); IMPORT void bspSm1553bIrqConnect(void *data, void (*isr)(void *data));
IMPORT int bspSm1553bChipReady(void); IMPORT int bspSm1553bChipReady(void);
IMPORT void bspSm1553bAckIrq(void); IMPORT void bspSm1553bAckIrq(BOOL);
IMPORT void bspSm1553bReset(BOOL);
struct hcfResource sm2130Resources[] = { struct hcfResource sm2130Resources[] = {
{ "devName" , HCF_RES_STRING, {(void *)"/sm1553b"}}, { "devName" , HCF_RES_STRING, {(void *)"/sm1553b" } },
{ "reqIsr" , HCF_RES_ADDR, {(void *)bspSm1553bIrqConnect}}, { "funcReqIsr" , HCF_RES_ADDR, {(void *)bspSm1553bIrqConnect } },
{ "isReady" , HCF_RES_ADDR, {(void *)bspSm1553bChipReady}}, { "funcIsReady" , HCF_RES_ADDR, {(void *)bspSm1553bChipReady } },
{ "ackIrq" , HCF_RES_ADDR, {(void *)bspSm1553bAckIrq}}, { "funcAckIrq" , HCF_RES_ADDR, {(void *)bspSm1553bAckIrq } },
{ "funcReset" , HCF_RES_ADDR, {(void *)bspSm1553bReset } },
}; };
#define sm2130ResNum NELEMENTS(sm2130Resources) #define sm2130ResNum NELEMENTS(sm2130Resources)

299
vxbSm2130SpiDev.c

@ -28,11 +28,16 @@ typedef struct _Sm2310_DEV_HANDLE {
SEL_WAKEUP_LIST selList; SEL_WAKEUP_LIST selList;
void (*usrIsr)();
SM2130_SPI_DEV *pDevCtrl; SM2130_SPI_DEV *pDevCtrl;
} SM2310_DEV_HANDLE; } SM2310_DEV_HANDLE;
LOCAL int sm2130_driver_node = -1; LOCAL int sm2130_driver_node = -1;
/* Declare */
IMPORT void sysUsDelay(UINT32 us);
/* locals */ /* locals */
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose); LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose);
LOCAL INT32 sm2130BusDevRead(VXB_DEVICE_ID pDev, UINT8 cmd); LOCAL INT32 sm2130BusDevRead(VXB_DEVICE_ID pDev, UINT8 cmd);
@ -118,21 +123,25 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev)
pDrvCtrl->devHandle = NULL; 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; pDrvCtrl->devName = pDrvCtrl->name;
pHcf = (struct hcfDevice *)hcfDeviceGet(pDev); pHcf = (struct hcfDevice *)hcfDeviceGet(pDev);
if (pHcf) { if (pHcf) {
if (devResourceGet(pHcf, "devName", HCF_RES_STRING, (void *)&pDrvCtrl->devName) != OK) { if (devResourceGet(pHcf, "devName", HCF_RES_STRING, (void *)&pDrvCtrl->devName) != OK) {
pDrvCtrl->devName = pDrvCtrl->name; pDrvCtrl->devName = pDrvCtrl->name;
} }
if (devResourceGet(pHcf, "reqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->reqIsr) != OK) { if (devResourceGet(pHcf, "funcReqIsr", HCF_RES_ADDR, (void *)&pDrvCtrl->funcReqIsr) != OK) {
pDrvCtrl->reqIsr = NULL; pDrvCtrl->funcReqIsr = NULL;
}
if (devResourceGet(pHcf, "funcIsReady", HCF_RES_ADDR, (void *)&pDrvCtrl->funcIsReady) != OK) {
pDrvCtrl->funcIsReady = NULL;
} }
if (devResourceGet(pHcf, "isReady", HCF_RES_ADDR, (void *)&pDrvCtrl->isReady) != OK) { if (devResourceGet(pHcf, "funcAckIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->funcAckIrq) != OK) {
pDrvCtrl->isReady = NULL; pDrvCtrl->funcAckIrq = NULL;
} }
if (devResourceGet(pHcf, "ackIrq", HCF_RES_ADDR, (void *)&pDrvCtrl->ackIrq) != OK) {
pDrvCtrl->ackIrq = NULL; if (devResourceGet(pHcf, "funcReset", HCF_RES_ADDR, (void *)&pDrvCtrl->funcReset) != OK) {
pDrvCtrl->funcReset = NULL;
} }
} }
@ -146,10 +155,15 @@ 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); if (pDrvCtrl->refcount > 0) {
errnoSet(EBUSY);
return (void *)ERROR;
}
semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
++pDrvCtrl->refcount; ++pDrvCtrl->refcount;
(void)semGive(pDrvCtrl->muteSem); semGive(pDrvCtrl->muteSem);
return dev; return dev;
} }
@ -157,39 +171,39 @@ LOCAL int drv1553bClose(SM2310_DEV_HANDLE *dev)
{ {
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
(void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
--pDrvCtrl->refcount; --pDrvCtrl->refcount;
(void)semGive(pDrvCtrl->muteSem); semGive(pDrvCtrl->muteSem);
return (OK); return (OK);
} }
LOCAL int readReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer) LOCAL int readReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
{ {
UINT8 cmd; UINT8 cmd;
if (xfer->reg <= 15) { if (xfer->reg <= 15) {
cmd = (xfer->reg << 2); cmd = (xfer->reg << 2);
} else { } else {
cmd = xfer->reg & 0xff; cmd = xfer->reg & 0xff;
} }
xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, cmd); xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, cmd);
return 0; return 0;
} }
LOCAL int writeReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer) LOCAL int writeReg(SM2130_SPI_DEV *pDrvCtrl, SM2130_XFER *xfer)
{ {
UINT8 cmd; UINT8 cmd;
if (xfer->reg <= 63) { if (xfer->reg <= 63) {
cmd = 0x80 | (xfer->reg & 0x3f); cmd = 0x80 | (xfer->reg & 0x3f);
} else { } else {
cmd = xfer->reg & 0xff; 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) 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; transInfo.txLen = 1;
if (xfer->reg >= 0xb && xfer->reg <= 0xE) { if (xfer->reg >= 0xb && xfer->reg <= 0xE) {
cmd =(xfer->reg - 0xB) + 0xD8; cmd = (xfer->reg - 0xB) + 0xD8;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
return pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | xfer->reg, xfer->val); return pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | xfer->reg, xfer->val);
} }
@ -214,22 +228,22 @@ LOCAL int readMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 }; SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 };
UINT8 *ptr; UINT8 *ptr;
UINT8 cmd; 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); errnoSet(EINVAL);
return ERROR; return ERROR;
} }
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) { if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) {
cmd =(mxfr->reg - 0xB) + 0xD8; cmd = (mxfr->reg - 0xB) + 0xD8;
transInfo.txBuf = &cmd; transInfo.txBuf = &cmd;
transInfo.txLen = 1; transInfo.txLen = 1;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address); pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address);
} }
cmd = 0x40; cmd = 0x40;
ptr = (UINT8 *)pDrvCtrl->regmem; ptr = (UINT8 *)pDrvCtrl->regmem;
transInfo.txBuf = &cmd; transInfo.txBuf = &cmd;
@ -238,8 +252,8 @@ LOCAL int readMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
transInfo.rxLen = 1 + mxfr->count * 2; transInfo.rxLen = 1 + mxfr->count * 2;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
memcpy(mxfr->membuf, ptr + 1, mxfr->count * 2); memcpy(mxfr->membuf, ptr + 1, mxfr->count * 2);
return OK; return OK;
} }
@ -248,33 +262,85 @@ LOCAL int writeMemory(SM2130_SPI_DEV *pDrvCtrl, SM2130_MEM_XFER *mxfr)
SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 }; SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 };
UINT8 *ptr; UINT8 *ptr;
UINT8 cmd; 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); errnoSet(EINVAL);
return ERROR; return ERROR;
} }
if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) { if (mxfr->reg >= 0xb && mxfr->reg <= 0xE) {
cmd =(mxfr->reg - 0xB) + 0xD8; cmd = (mxfr->reg - 0xB) + 0xD8;
transInfo.txBuf = &cmd; transInfo.txBuf = &cmd;
transInfo.txLen = 1; transInfo.txLen = 1;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address); pDrvCtrl->write(pDrvCtrl->pDev, 0x80 | mxfr->reg, mxfr->address);
} }
ptr = (UINT8 *)pDrvCtrl->regmem; ptr = (UINT8 *)pDrvCtrl->regmem;
ptr[0] = 0xC0; 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.txBuf = ptr;
transInfo.txLen = 1 + mxfr->count * 2; transInfo.txLen = 1 + mxfr->count * 2;
vxbSpiTransfer(pDrvCtrl->pDev, &transInfo); vxbSpiTransfer(pDrvCtrl->pDev, &transInfo);
return OK; 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) LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg)
{ {
SM2130_XFER *xfer; 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); ret = selNodeDelete(&dev->selList, (SEL_WAKEUP_NODE *)arg);
break; break;
case FIOC_SM2130_WR: case FIOC_SM2130_WR:
xfer = (SM2130_XFER *)(arg); xfer = (SM2130_XFER *)(arg);
pDrvCtrl->write(pDrvCtrl->pDev, xfer->reg, xfer->val); pDrvCtrl->write(pDrvCtrl->pDev, xfer->reg, xfer->val);
break; break;
case FIOC_SM2130_RD: case FIOC_SM2130_RD:
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_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: case FIOC_SM2130_READY:
if (pDrvCtrl->isReady) { if (pDrvCtrl->funcIsReady) {
*(int *)(arg) = pDrvCtrl->isReady(); *(int *)(arg) = pDrvCtrl->funcIsReady();
} else { } else {
errnoSet(EIO); errnoSet(EIO);
ret = ERROR; ret = ERROR;
} }
break; break;
case FIOC_SM2130_REGRD: case FIOC_SM2130_REGRD:
ret = readReg(pDrvCtrl, (SM2130_XFER *)(arg)); ret = readReg(pDrvCtrl, (SM2130_XFER *)(arg));
break; break;
case FIOC_SM2130_REGWR: case FIOC_SM2130_REGWR:
ret = writeReg(pDrvCtrl, (SM2130_XFER *)(arg)); ret = writeReg(pDrvCtrl, (SM2130_XFER *)(arg));
break; break;
case FIOC_SM2130_SMADDR: case FIOC_SM2130_SMADDR:
ret = setMemAddress(pDrvCtrl, (SM2130_XFER *)(arg)); ret = setMemAddress(pDrvCtrl, (SM2130_XFER *)(arg));
break; break;
@ -358,7 +461,6 @@ 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)
@ -366,11 +468,13 @@ LOCAL void sm1553isr(void *data)
SM2310_DEV_HANDLE *dev = data; SM2310_DEV_HANDLE *dev = data;
SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl;
if (pDrvCtrl->ackIrq) { ++pDrvCtrl->irqCount;
pDrvCtrl->ackIrq();
//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); selWakeupAll(&dev->selList, SELREAD);
} }
@ -400,23 +504,34 @@ LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev)
(DRV_REMOVE_PTR)NULL , (DRV_REMOVE_PTR)NULL ,
(DRV_OPEN_PTR)drv1553bOpen , (DRV_OPEN_PTR)drv1553bOpen ,
(DRV_CLOSE_PTR)drv1553bClose , (DRV_CLOSE_PTR)drv1553bClose ,
(DRV_READ_PTR)NULL , (DRV_READ_PTR)drv1553bRead ,
(DRV_WRITE_PTR)NULL , (DRV_WRITE_PTR)drv1553bWrite ,
(DRV_IOCTL_PTR)drv1553bIoctl); (DRV_IOCTL_PTR)drv1553bIoctl);
/* clang-format on */ /* 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); semTake(pDrvCtrl->muteSem, WAIT_FOREVER);
if (sm2130_driver_node > 0) { if (sm2130_driver_node > 0) {
dev = (SM2310_DEV_HANDLE *)hwMemAlloc(sizeof(SM2310_DEV_HANDLE)); dev = (SM2310_DEV_HANDLE *)hwMemAlloc(sizeof(SM2310_DEV_HANDLE));
if (dev) { if (dev) {
pDrvCtrl->refcount = 0; pDrvCtrl->refcount = 0;
dev->usrIsr = NULL;
selWakeupListInit(&dev->selList); selWakeupListInit(&dev->selList);
if (iosDevAdd(&dev->devHdr, pDrvCtrl->devName, sm2130_driver_node) == OK) { if (iosDevAdd(&dev->devHdr, pDrvCtrl->devName, sm2130_driver_node) == OK) {
pDrvCtrl->devHandle = dev; pDrvCtrl->devHandle = dev;
dev->pDevCtrl = pDrvCtrl; dev->pDevCtrl = pDrvCtrl;
if (pDrvCtrl->reqIsr) { if (pDrvCtrl->funcReqIsr) {
pDrvCtrl->irqStage = pDrvCtrl->reqIsr(dev, sm1553isr); pDrvCtrl->funcReqIsr(dev, sm1553isr);
} }
} else { } else {
#ifndef _VXBUS_BASIC_HWMEMLIB #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) LOCAL const char *checkReady(SM2130_SPI_DEV *pDrvCtrl)
{ {
if (!pDrvCtrl->isReady()) { if (!pDrvCtrl->funcIsReady) {
return "Unknown"; return "Unknown";
} }
if (pDrvCtrl->isReady()) { if (pDrvCtrl->funcIsReady()) {
return "Ready"; return "Ready";
} }
return "Not Ready"; return "Not Ready";
} }
LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose) 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(" devName: %s\n", pDrvCtrl->devName);
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(" funcReqIsr: %p\n", pDrvCtrl->funcReqIsr);
printf(" irqStatus: %d\n", pDrvCtrl->irqStage); printf(" irqCount: %u\n", pDrvCtrl->irqCount);
printf(" isReady: %s\n", checkReady(pDrvCtrl)); printf(" isReady: %s\n", checkReady(pDrvCtrl));
} }

37
vxbSm2130SpiDev.h

@ -10,10 +10,13 @@
#define XFER_TYPE_WR (1) #define XFER_TYPE_WR (1)
#define XFER_TYPE_RD (2) #define XFER_TYPE_RD (2)
#define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR) #define FIOC_SM2130_WR (__SM2130__IOC_MAGIC | XFER_TYPE_WR)
#define FIOC_SM2130_RD (__SM2130__IOC_MAGIC | XFER_TYPE_RD) #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_REGRD (__SM2130__IOC_MAGIC | 0x21)
#define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22) #define FIOC_SM2130_REGWR (__SM2130__IOC_MAGIC | 0x22)
@ -22,14 +25,15 @@
#define FIOC_SM2130_WRMEM (__SM2130__IOC_MAGIC | 0x25) #define FIOC_SM2130_WRMEM (__SM2130__IOC_MAGIC | 0x25)
struct sm2130_xfer { struct sm2130_xfer {
UINT8 reg; UINT8 reg;
UINT16 val; UINT16 val;
}; };
typedef struct sm2130_xfer SM2130_XFER; typedef struct sm2130_xfer SM2130_XFER;
#define SMX_MAX_WORDS (64)
struct sm2130_xfer_mem { struct sm2130_xfer_mem {
int count; int count;
UINT8 reg; UINT8 reg;
UINT16 address; UINT16 address;
UINT16 *membuf; UINT16 *membuf;
}; };
@ -42,21 +46,22 @@ typedef struct _spi_1553b_drv_ctrl {
const char *devName; const char *devName;
int refcount; volatile int refcount;
int irqStage; volatile UINT32 irqCount;
void *devHandle; 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); INT32 (*read)(VXB_DEVICE_ID pDev, UINT8 cmd);
STATUS (*write)(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var); 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 */ SEM_ID muteSem; /* operation semaphore */
VXB_SPI_MAST_SPEC *specialInfo; VXB_SPI_MAST_SPEC *specialInfo;
} SM2130_SPI_DEV; } SM2130_SPI_DEV;

Loading…
Cancel
Save