diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2015-02-23 13:02:39 +0100 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2015-04-17 01:10:17 +0200 |
commit | 3bb41226e0941b86d58ecb97f7d292677de573c8 (patch) | |
tree | 907aa270343f7c6d1bc08bf73288fb9b10da6197 /c/src/lib/libbsp/sparc/shared/time | |
parent | LEON: added network device configuration helper function (diff) | |
download | rtems-3bb41226e0941b86d58ecb97f7d292677de573c8.tar.bz2 |
LEON: added new drivers to the LEON2/LEON3 BSPs
Most drivers use the Driver Manager for device probing, they
work on AMBA-over-PCI systems if PCI is big-endian.
New APIs:
* GPIO Library, interfaced to GRGPIO
* GENIRQ, Generic interrupt service implementation helper
New GRLIB Drivers:
* ACTEL 1553 RT, user interface is similar to 1553 BRM driver
* GR1553 (1553 BC, RT and BM core)
* AHBSTAT (AHB error status core)
* GRADCDAC (Core interfacing to ADC/DAC hardware)
* GRGPIO (GPIO port accessed from GPIO Library)
* MCTRL (Memory controller settings configuration)
* GRETH (10/100/1000 Ethernet driver using Driver manager)
* GRPWM (Pulse Width Modulation core)
* SPICTRL (SPI master interface)
* GRSPW_ROUTER (SpaceWire Router AMBA configuration interface)
* GRCTM (SpaceCraft on-board Time Management core)
* SPWCUC (Time distribution over SpaceWire)
* GRTC (SpaceCraft up-link Tele core)
* GRTM (SpaceCraft down-link Tele Metry core)
GR712RC ASIC specific interfaces:
* GRASCS
* CANMUX (select between OCCAN and SATCAN)
* SATCAN
* SLINK
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/time')
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/time/grctm.c | 409 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/time/spwcuc.c | 369 |
2 files changed, 778 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/time/grctm.c b/c/src/lib/libbsp/sparc/shared/time/grctm.c new file mode 100644 index 0000000000..3185e13264 --- /dev/null +++ b/c/src/lib/libbsp/sparc/shared/time/grctm.c @@ -0,0 +1,409 @@ +/* GRCTM - CCSDS Time Manager - register driver interface. + * + * COPYRIGHT (c) 2009. + * Cobham Gaisler AB. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <drvmgr/drvmgr.h> +#include <drvmgr/ambapp_bus.h> +#include <stdlib.h> + +#include <grctm.h> + +/* Private structure of GRCTM driver */ +struct grctm_priv { + struct drvmgr_dev *dev; + struct grctm_regs *regs; + int open; + + grctm_isr_t user_isr; + void *user_isr_arg; + + struct grctm_stats stats; +}; + +void grctm_isr(void *data); + +struct amba_drv_info grctm_drv_info; + +void *grctm_open(int minor) +{ + struct grctm_priv *priv; + struct drvmgr_dev *dev; + + /* Get Device from Minor */ + if ( drvmgr_get_dev(&grctm_drv_info.general, minor, &dev) ) { + return NULL; + } + + priv = dev->priv; + if ( (priv == NULL) || priv->open ) + return NULL; + + /* Set initial state of software */ + priv->open = 1; + + /* Clear Statistics */ + grctm_clr_stats(priv); + priv->user_isr = NULL; + priv->user_isr_arg = NULL; + + return priv; +} + +void grctm_close(void *grctm) +{ + struct grctm_priv *priv = (struct grctm_priv *)grctm; + + if ( priv->open == 0 ) + return; + + /* Reset Hardware */ + grctm_reset(priv); + + priv->open = 0; +} + +/* Hardware Reset of GRCTM */ +int grctm_reset(void *grctm) +{ + struct grctm_priv *priv = grctm; + struct grctm_regs *r = priv->regs; + + r->grr = 0x55000001; + + int i = 1000; + while ((r->grr & 1) && i > 0) { + i--; + } + + return i ? 0 : -1; +} + +void grctm_int_enable(void *grctm) +{ + struct grctm_priv *priv = (struct grctm_priv *)grctm; + + /* Register and Enable Interrupt at Interrupt controller */ + drvmgr_interrupt_register(priv->dev, 0, "grctm", grctm_isr, priv); +} + +void grctm_int_disable(void *grctm) +{ + struct grctm_priv *priv = (struct grctm_priv *)grctm; + + /* Enable Interrupt at Interrupt controller */ + drvmgr_interrupt_unregister(priv->dev, 0, grctm_isr, priv); +} + +void grctm_clr_stats(void *grctm) +{ + struct grctm_priv *priv = (struct grctm_priv *)grctm; + + memset(&priv->stats, 0, sizeof(priv->stats)); +} + +void grctm_get_stats(void *grctm, struct grctm_stats *stats) +{ + struct grctm_priv *priv = (struct grctm_priv *)grctm; + + memcpy(stats, &priv->stats, sizeof(priv->stats)); +} + +/* Enable external synchronisation (from grctm) */ +void grctm_enable_ext_sync(void *grctm) +{ + struct grctm_priv *priv = grctm; + + priv->regs->gcr |= 0x55<<24 | 1<<9; +} + +/* Disable external synchronisation (from grctm) */ +void grctm_disable_ext_sync(void *grctm) +{ + struct grctm_priv *priv = grctm; + + priv->regs->gcr &= ~((0xAA<<24) | 1<<9); +} + +/* Enable TimeWire synchronisation */ +void grctm_enable_tw_sync(void *grctm) +{ + struct grctm_priv *priv = grctm; + + priv->regs->gcr |= 0x55<<24 | 1<<8; +} + +/* Disable TimeWire synchronisation */ +void grctm_disable_tw_sync(void *grctm) +{ + struct grctm_priv *priv = grctm; + + priv->regs->gcr &= ~((0xAA<<24) | 1<<8); +} + +/* Disable frequency synthesizer from driving ET */ +void grctm_disable_fs(void *grctm) +{ + struct grctm_priv *priv = grctm; + + priv->regs->gcr |= 0x55<<24 | 1<<7; +} + +/* Enable frequency synthesizer to drive ET */ +void grctm_enable_fs(void *grctm) +{ + struct grctm_priv *priv = grctm; + + priv->regs->gcr &= ~((0xAA<<24) | 1<<7); +} + +/* Return elapsed coarse time */ +unsigned int grctm_get_et_coarse(void *grctm) +{ + struct grctm_priv *priv = grctm; + + return priv->regs->etcr; +} + +/* Return elapsed fine time */ +unsigned int grctm_get_et_fine(void *grctm) +{ + struct grctm_priv *priv = grctm; + + return (priv->regs->etfr & 0xffffff00) >> 8; +} + +/* Return elapsed time (coarse and fine) */ +unsigned long long grctm_get_et(void *grctm) +{ + return (((unsigned long)grctm_get_et_coarse(grctm)) << 24) | grctm_get_et_fine(grctm); +} + + +/* Return 1 if specified datation has been latched */ +int grctm_is_dat_latched(void *grctm, int dat) +{ + struct grctm_priv *priv = grctm; + + return (priv->regs->gsr >> dat) & 1; +} + +/* Set triggering edge of datation input */ +void grctm_set_dat_edge(void *grctm, int dat, int edge) +{ + struct grctm_priv *priv = grctm; + + priv->regs->gcr &= ~((0xAA<<24) | 1 << (10+dat)); + priv->regs->gcr |= 0x55<<24 | (edge&1) << (10+dat); +} + +/* Return latched datation coarse time */ +unsigned int grctm_get_dat_coarse(void *grctm, int dat) +{ + struct grctm_priv *priv = grctm; + + switch (dat) { + case 0 : return priv->regs->dcr0; + case 1 : return priv->regs->dcr1; + case 2 : return priv->regs->dcr2; + default: return -1; + } +} + +/* Return latched datation fine time */ +unsigned int grctm_get_dat_fine(void *grctm, int dat) +{ + struct grctm_priv *priv = grctm; + + switch (dat) { + case 0 : return (priv->regs->dfr0 & 0xffffff00) >> 8; + case 1 : return (priv->regs->dfr1 & 0xffffff00) >> 8; + case 2 : return (priv->regs->dfr2 & 0xffffff00) >> 8; + default: return -1; + } +} + + +/* Return latched datation ET */ +unsigned long long grctm_get_dat_et(void *grctm, int dat) +{ + return (((unsigned long)grctm_get_dat_coarse(grctm, dat)) << 24) | + grctm_get_dat_fine(grctm, dat); +} + + +/* Return current pulse configuration */ +unsigned int grctm_get_pulse_reg(void *grctm, int pulse) +{ + struct grctm_priv *priv = grctm; + + return priv->regs->pdr[pulse]; +} + +/* Set pulse register */ +void grctm_set_pulse_reg(void *grctm, int pulse, unsigned int val) +{ + struct grctm_priv *priv = grctm; + + priv->regs->pdr[pulse] = val; +} + +/* Configure pulse: pp = period, pw = width, pl = level, en = enable */ +void grctm_cfg_pulse(void *grctm, int pulse, int pp, int pw, int pl, int en) +{ + grctm_set_pulse_reg(grctm, pulse, (pp&0xf)<<20 | (pw&0xf)<<16 | (pl&1)<<10 | (en&1)<<1); +} + +/* Enable pulse output */ +void grctm_enable_pulse(void *grctm, int pulse) +{ + struct grctm_priv *priv = grctm; + + priv->regs->pdr[pulse] |= 0x2; +} + +/* Disable pulse output */ +void grctm_disable_pulse(void *grctm, int pulse) +{ + struct grctm_priv *priv = grctm; + + priv->regs->pdr[pulse] &= ~0x2; +} + +/* Clear interrupts */ +void grctm_clear_irqs(void *grctm, int irqs) +{ + struct grctm_priv *priv = grctm; + + priv->regs->picr = irqs; +} + +/* Enable interrupts */ +void grctm_enable_irqs(void *grctm, int irqs) +{ + struct grctm_priv *priv = grctm; + + priv->regs->imr = irqs; +} + +/* Set Frequency synthesizer increment */ +void grctm_set_fs_incr(void *grctm, int incr) +{ + struct grctm_priv *priv = grctm; + + priv->regs->fsir = incr; +} + +/* Set ET increment */ +void grctm_set_et_incr(void *grctm, int incr) +{ + struct grctm_priv *priv = grctm; + + priv->regs->etir = incr; +} + + +void grctm_isr(void *data) +{ + struct grctm_priv *priv = data; + struct grctm_stats *stats = &priv->stats; + unsigned int pimr = priv->regs->pimr; + + if ( pimr == 0 ) + return; + + stats->nirqs++; + if (pimr & PULSE0_IRQ ) + stats->pulse++; + + /* Let user Handle Interrupt */ + if ( priv->user_isr ) + priv->user_isr(pimr, priv->user_isr_arg); +} + +struct grctm_regs *grctm_get_regs(void *grctm) +{ + struct grctm_priv *priv = (struct grctm_priv *)grctm; + + return priv->regs; +} + +void grctm_int_register(void *grctm, grctm_isr_t func, void *data) +{ + struct grctm_priv *priv = (struct grctm_priv *)grctm; + + priv->user_isr = func; + priv->user_isr_arg = data; +} + +/*** INTERFACE TO DRIVER MANAGER ***/ + +int grctm_init2(struct drvmgr_dev *dev) +{ + struct amba_dev_info *ambadev; + struct ambapp_core *pnpinfo; + struct grctm_priv *priv; + struct grctm_regs *regs; + + priv = (struct grctm_priv *)malloc(sizeof(*priv)); + if ( priv == NULL ) + return -1; + memset(priv, 0, sizeof(*priv)); + priv->dev = dev; + dev->priv = priv; + + /* Get device information from AMBA PnP information */ + ambadev = (struct amba_dev_info *)dev->businfo; + if ( ambadev == NULL ) { + return -1; + } + pnpinfo = &ambadev->info; + regs = (struct grctm_regs *)pnpinfo->ahb_slv->start[0]; + + priv->regs = regs; + + grctm_reset(priv); + + return 0; +} + +struct drvmgr_drv_ops grctm_ops = +{ + {NULL, grctm_init2, NULL, NULL}, + NULL, + NULL +}; + +struct amba_dev_id grctm_ids[] = +{ + {VENDOR_GAISLER, GAISLER_GRCTM}, + {0, 0} /* Mark end of table */ +}; + +struct amba_drv_info grctm_drv_info = +{ + { + DRVMGR_OBJ_DRV, /* Driver */ + NULL, /* Next driver */ + NULL, /* Device list */ + DRIVER_AMBAPP_GAISLER_GRCTM_ID, /* Driver ID */ + "GRCTM_DRV", /* Driver Name */ + DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */ + &grctm_ops, + NULL, /* Funcs */ + 0, /* No devices yet */ + 0, + }, + &grctm_ids[0] +}; + +/* Register the grctm Driver */ +void grctm_register(void) +{ + drvmgr_drv_register(&grctm_drv_info.general); +} diff --git a/c/src/lib/libbsp/sparc/shared/time/spwcuc.c b/c/src/lib/libbsp/sparc/shared/time/spwcuc.c new file mode 100644 index 0000000000..738ec1a277 --- /dev/null +++ b/c/src/lib/libbsp/sparc/shared/time/spwcuc.c @@ -0,0 +1,369 @@ +/* SPWCUC - SpaceWire - CCSDS unsegmented Code Transfer Protocol GRLIB core + * register driver interface. + * + * COPYRIGHT (c) 2009. + * Cobham Gaisler AB. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <drvmgr/drvmgr.h> +#include <drvmgr/ambapp_bus.h> +#include <stdlib.h> + +#include <spwcuc.h> + +/* Private structure of SPWCUC driver. */ +struct spwcuc_priv { + struct drvmgr_dev *dev; + struct spwcuc_regs *regs; + int open; + + spwcuc_isr_t user_isr; + void *user_isr_arg; + + struct spwcuc_stats stats; +}; + +void spwcuc_isr(void *data); + +struct amba_drv_info spwcuc_drv_info; + +/* Hardware Reset of SPWCUC */ +int spwcuc_hw_reset(struct spwcuc_priv *priv) +{ + struct spwcuc_regs *r = priv->regs; + int i = 1000; + + r->control = 1; + + while ((r->control & 1) && i > 0) { + i--; + } + + spwcuc_clear_irqs(priv, -1); + + return i ? 0 : -1; +} + +int spwcuc_reset(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return spwcuc_hw_reset(priv); +} + +void *spwcuc_open(int minor) +{ + struct spwcuc_priv *priv; + struct drvmgr_dev *dev; + + /* Get Device from Minor */ + if ( drvmgr_get_dev(&spwcuc_drv_info.general, minor, &dev) ) { + return NULL; + } + + priv = dev->priv; + if ( (priv == NULL) || priv->open ) + return NULL; + + /* Set initial state of software */ + priv->open = 1; + + /* Clear Statistics */ + spwcuc_clr_stats(priv); + priv->user_isr = NULL; + priv->user_isr_arg = NULL; + + return priv; +} + +void spwcuc_close(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + if ( priv->open == 0 ) + return; + + /* Reset Hardware */ + spwcuc_hw_reset(priv); + + priv->open = 0; +} + +void spwcuc_int_enable(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + /* Register and Enable Interrupt at Interrupt controller */ + drvmgr_interrupt_register(priv->dev, 0, "spwcuc", spwcuc_isr, priv); +} + +void spwcuc_int_disable(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + /* Enable Interrupt at Interrupt controller */ + drvmgr_interrupt_unregister(priv->dev, 0, spwcuc_isr, priv); +} + +void spwcuc_clr_stats(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + memset(&priv->stats, 0, sizeof(priv->stats)); +} + +void spwcuc_get_stats(void *spwcuc, struct spwcuc_stats *stats) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + memcpy(stats, &priv->stats, sizeof(priv->stats)); +} + +/* Configure the spwcuc core */ +void spwcuc_config(void *spwcuc, struct spwcuc_cfg *cfg) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + struct spwcuc_regs *r = priv->regs; + + r->config = (cfg->sel_out & 0x1f) << 28 | + (cfg->sel_in & 0x1f) << 24 | + (cfg->mapping & 0x1f) << 16 | + (cfg->tolerance & 0x1f) << 8 | + (cfg->tid & 0x7) << 4 | + (cfg->ctf & 1) << 1 | + (cfg->cp & 1); + + r->control = (cfg->txen & 1) << 1 | + (cfg->rxen & 1) << 2 | + (cfg->pktsyncen & 1) << 3 | + (cfg->pktiniten & 1) << 4 | + (cfg->pktrxen & 1) << 5; + + r->dla = (cfg->dla_mask & 0xff)<<8 | (cfg->dla & 0xff); + + r->pid = cfg->pid; + + r->offset = cfg->offset; +} + +/* Return elapsed coarse time */ +unsigned int spwcuc_get_et_coarse(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return priv->regs->etct; +} + +/* Return elapsed fine time */ +unsigned int spwcuc_get_et_fine(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return (priv->regs->etft & 0xffffff) >> 8; +} + +/* Return elapsed time (coarse and fine) */ +unsigned long long spwcuc_get_et(void *spwcuc) +{ + return (((unsigned long long)spwcuc_get_et_coarse(spwcuc)) << 24) | spwcuc_get_et_fine(spwcuc); +} + +/* Return next elapsed coarse time (for use when sending SpW time packet) */ +unsigned int spwcuc_get_next_et_coarse(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return priv->regs->etct_next; +} + +/* Return next elapsed fine time (for use when sending SpW time packet) */ +unsigned int spwcuc_get_next_et_fine(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return (priv->regs->etft_next & 0xffffff) >> 8; +} + +/* Return next elapsed time (for use when sending SpW time packet) */ +unsigned long long spwcuc_get_next_et(void *spwcuc) +{ + return (((unsigned long long)spwcuc_get_next_et_coarse(spwcuc)) << 24) | spwcuc_get_next_et_fine(spwcuc); +} + +/* Force/Set the elapsed time (coarse 32-bit and fine 24-bit) by writing the + * T-Field Time Packet Registers then the FORCE, NEW and INIT bits. + * The latter three are needed for the ET to be set with the new value. + */ +void spwcuc_force_et(void *spwcuc, unsigned long long time) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + struct spwcuc_regs *regs = priv->regs; + + regs->etft_next = (time & 0xffffff) << 8; + regs->etct_next = (time >> 24) & 0xffffffff; + regs->pkt_pf_crc = (1 << 29) | (1 << 30) | (1 << 31); +} + +/* Return received (from time packet) elapsed coarse time */ +unsigned int spwcuc_get_tp_et_coarse(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return priv->regs->pkt_ct; +} + +/* Return received (from time packet) elapsed fine time */ +unsigned int spwcuc_get_tp_et_fine(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return (priv->regs->pkt_ft & 0xffffff) >> 8; +} + +/* Return received (from time packet) elapsed time (coarse and fine) */ +unsigned long long spwcuc_get_tp_et(void *spwcuc) +{ + return (((unsigned long long)spwcuc_get_tp_et_coarse(spwcuc)) << 24) | spwcuc_get_tp_et_fine(spwcuc); +} + +/* Clear interrupts */ +void spwcuc_clear_irqs(void *spwcuc, int irqs) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + priv->regs->picr = irqs; +} + +/* Enable interrupts */ +void spwcuc_enable_irqs(void *spwcuc, int irqs) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + priv->regs->imr = irqs; +} + +struct spwcuc_regs *spwcuc_get_regs(void *spwcuc) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + return priv->regs; +} + +void spwcuc_int_register(void *spwcuc, spwcuc_isr_t func, void *data) +{ + struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; + + priv->user_isr = func; + priv->user_isr_arg = data; +} + +void spwcuc_isr(void *data) +{ + struct spwcuc_priv *priv = data; + struct spwcuc_stats *stats = &priv->stats; + unsigned int pimr = priv->regs->pimr; + + stats->nirqs++; + + if (pimr & PKT_INIT_IRQ) + stats->pkt_init++; + if (pimr & PKT_ERR_IRQ) + stats->pkt_err++; + if (pimr & PKT_RX_IRQ) + stats->pkt_rx++; + if (pimr & WRAP_ERR_IRQ) + stats->wraperr++; + if (pimr & WRAP_IRQ) + stats->wrap++; + if (pimr & SYNC_ERR_IRQ) + stats->syncerr++; + if (pimr & SYNC_IRQ) + stats->sync++; + if (pimr & TOL_ERR_IRQ) + stats->tolerr++; + if (pimr & TICK_RX_ERR_IRQ) + stats->tick_rx_error++; + if (pimr & TICK_RX_WRAP_IRQ) + stats->tick_rx_wrap++; + if (pimr & TICK_RX_IRQ) + stats->tick_rx++; + if (pimr & TICK_TX_WRAP_IRQ) + stats->tick_tx_wrap++; + if (pimr & TICK_TX_IRQ) + stats->tick_tx++; + + /* Let user Handle Interrupt */ + if ( priv->user_isr ) + priv->user_isr(pimr, priv->user_isr_arg); +} + +/*** INTERFACE TO DRIVER MANAGER ***/ + +int spwcuc_init2(struct drvmgr_dev *dev) +{ + struct amba_dev_info *ambadev; + struct ambapp_core *pnpinfo; + struct spwcuc_priv *priv; + struct spwcuc_regs *regs; + + priv = (struct spwcuc_priv *)malloc(sizeof(*priv)); + if ( priv == NULL ) + return -1; + memset(priv, 0, sizeof(*priv)); + priv->dev = dev; + dev->priv = priv; + + /* Get device information from AMBA PnP information */ + ambadev = (struct amba_dev_info *)dev->businfo; + if ( ambadev == NULL ) { + return -1; + } + pnpinfo = &ambadev->info; + regs = (struct spwcuc_regs *)pnpinfo->apb_slv->start; + + priv->regs = regs; + + spwcuc_hw_reset(priv); + + return 0; +} + +struct drvmgr_drv_ops spwcuc_ops = +{ + {NULL, spwcuc_init2, NULL, NULL}, + NULL, + NULL +}; + +struct amba_dev_id spwcuc_ids[] = +{ + {VENDOR_GAISLER, GAISLER_SPWCUC}, + {0, 0} /* Mark end of table */ +}; + +struct amba_drv_info spwcuc_drv_info = +{ + { + DRVMGR_OBJ_DRV, /* Driver */ + NULL, /* Next driver */ + NULL, /* Device list */ + DRIVER_AMBAPP_GAISLER_SPWCUC_ID,/* Driver ID */ + "SPWCUC_DRV", /* Driver Name */ + DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */ + &spwcuc_ops, + NULL, /* Funcs */ + 0, /* No devices yet */ + 0, + }, + &spwcuc_ids[0] +}; + +/* Register the SPWCUC Driver */ +void spwcuc_register(void) +{ + drvmgr_drv_register(&spwcuc_drv_info.general); +} |