forked from Imagelibrary/rtems
LEON: updated shared drivers to Driver Manger framework
Some bugfixes at the same time. After this patch the drivers may be used on RASTA systems having a big-endian PCI layout. Removed not up to date changelogs, rely on git log instead.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Driver for GRLIB port of OpenCores I2C-master
|
* Driver for GRLIB port of OpenCores I2C-master
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 2007 Gaisler Research
|
* COPYRIGHT (c) 2007 Cobham Gaisler AB
|
||||||
* based on the RTEMS MPC83xx I2C driver (c) 2007 Embedded Brains GmbH.
|
* based on the RTEMS MPC83xx I2C driver (c) 2007 Embedded Brains GmbH.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
@@ -9,27 +9,41 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*
|
*
|
||||||
* This file contains the driver and initialization code
|
* This file contains the driver and initialization code
|
||||||
*
|
|
||||||
* 2007-09-27: First version of driver (jan@gaisler.com)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <i2cmst.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <ambapp.h>
|
#include <ambapp.h>
|
||||||
#include <grlib.h>
|
|
||||||
#include <rtems/libi2c.h>
|
#include <rtems/libi2c.h>
|
||||||
|
#include <drvmgr/drvmgr.h>
|
||||||
|
#include <drvmgr/ambapp_bus.h>
|
||||||
|
|
||||||
|
#include <i2cmst.h>
|
||||||
|
|
||||||
/* Enable debug printks? */
|
/* Enable debug printks? */
|
||||||
/*#define DEBUG*/
|
/*#define DEBUG*/
|
||||||
|
|
||||||
/* Default to 40 MHz system clock? */
|
#ifdef DEBUG
|
||||||
/*
|
#define DBG(args...) printk(args)
|
||||||
#ifndef SYS_FREQ_kHZ
|
#else
|
||||||
#define SYS_FREQ_kHZ 40000
|
#define DBG(args...)
|
||||||
#endif
|
#endif
|
||||||
*/
|
|
||||||
|
|
||||||
|
/* The OC I2C core will perform a write after a start unless the RD bit
|
||||||
|
in the command register has been set. Since the rtems framework has
|
||||||
|
a send_start function we buffer that command and use it when the first
|
||||||
|
data is written. The START is buffered in the sendstart member below */
|
||||||
|
typedef struct gr_i2cmst_prv {
|
||||||
|
rtems_libi2c_bus_t i2clib_desc;
|
||||||
|
struct drvmgr_dev *dev;
|
||||||
|
gr_i2cmst_regs_t *reg_ptr;
|
||||||
|
unsigned int sysfreq; /* System clock frequency in kHz */
|
||||||
|
int minor;
|
||||||
|
unsigned char sendstart; /* START events are buffered here */
|
||||||
|
/* rtems_irq_number irq_number; */
|
||||||
|
/* rtems_id irq_sema_id; */
|
||||||
|
} gr_i2cmst_prv_t;
|
||||||
|
|
||||||
/* Calculates the scaler value for 100 kHz operation */
|
/* Calculates the scaler value for 100 kHz operation */
|
||||||
static int gr_i2cmst_calc_scaler(int sysfreq)
|
static int gr_i2cmst_calc_scaler(int sysfreq)
|
||||||
@@ -42,12 +56,12 @@ static int gr_i2cmst_wait(gr_i2cmst_prv_t *prv_ptr, uint8_t expected_sts)
|
|||||||
{
|
{
|
||||||
uint32_t tout = 0;
|
uint32_t tout = 0;
|
||||||
int current_sts;
|
int current_sts;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("(gr_i2cmst_wait called...");
|
DBG("(gr_i2cmst_wait called...");
|
||||||
#endif
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (tout++ > 1000000) {
|
if (tout++ > 1000000) {
|
||||||
|
DBG("gr_i2cmst_wait: TIMEOUT\n");
|
||||||
return RTEMS_TIMEOUT;
|
return RTEMS_TIMEOUT;
|
||||||
}
|
}
|
||||||
} while (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_TIP);
|
} while (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_TIP);
|
||||||
@@ -57,32 +71,31 @@ static int gr_i2cmst_wait(gr_i2cmst_prv_t *prv_ptr, uint8_t expected_sts)
|
|||||||
if (current_sts != expected_sts) {
|
if (current_sts != expected_sts) {
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
if (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_RXACK) {
|
if (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_RXACK) {
|
||||||
printk("Transfer NAKed..");
|
DBG("Transfer NAKed..");
|
||||||
}
|
}
|
||||||
if (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_AL) {
|
if (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_AL) {
|
||||||
printk("arbitration lost..");
|
DBG("arbitration lost..");
|
||||||
}
|
}
|
||||||
if (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_TIP) {
|
if (prv_ptr->reg_ptr->cmdsts & GRI2C_STS_TIP) {
|
||||||
printk("transfer still in progress, huh?..");
|
DBG("transfer still in progress, huh?..");
|
||||||
}
|
}
|
||||||
printk("exited with IO error..)");
|
DBG("exited with IO error..)");
|
||||||
#endif
|
#endif
|
||||||
|
DBG("gr_i2cmst_wait: IO-ERROR\n");
|
||||||
return RTEMS_IO_ERROR;
|
return RTEMS_IO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
DBG("exited...)");
|
||||||
printk("exited...)");
|
|
||||||
#endif
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize hardware core */
|
/* Initialize hardware core */
|
||||||
static rtems_status_code gr_i2cmst_init(rtems_libi2c_bus_t *bushdl)
|
static rtems_status_code gr_i2cmst_init(rtems_libi2c_bus_t *bushdl)
|
||||||
{
|
{
|
||||||
gr_i2cmst_prv_t *prv_ptr = &(((gr_i2cmst_desc_t *)(bushdl))->prv);
|
gr_i2cmst_prv_t *prv_ptr = (gr_i2cmst_prv_t *)bushdl;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("gr_i2cmst_init called...");
|
DBG("gr_i2cmst_init called...");
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable core before changing prescale register */
|
/* Disable core before changing prescale register */
|
||||||
prv_ptr->reg_ptr->ctrl = 0;
|
prv_ptr->reg_ptr->ctrl = 0;
|
||||||
@@ -96,54 +109,48 @@ static rtems_status_code gr_i2cmst_init(rtems_libi2c_bus_t *bushdl)
|
|||||||
/* Clear possible START condition */
|
/* Clear possible START condition */
|
||||||
prv_ptr->sendstart = 0;
|
prv_ptr->sendstart = 0;
|
||||||
|
|
||||||
#if defined(DEBUG)
|
DBG("exited\n");
|
||||||
printk("exited\n");
|
|
||||||
#endif
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rtems_status_code gr_i2cmst_send_start(rtems_libi2c_bus_t *bushdl)
|
static rtems_status_code gr_i2cmst_send_start(rtems_libi2c_bus_t *bushdl)
|
||||||
{
|
{
|
||||||
gr_i2cmst_prv_t *prv_ptr = &(((gr_i2cmst_desc_t *)(bushdl))->prv);
|
gr_i2cmst_prv_t *prv_ptr = (gr_i2cmst_prv_t *)bushdl;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("gr_i2cmst_send_start called...");
|
DBG("gr_i2cmst_send_start called...");
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The OC I2C core does not work with stand alone START events,
|
/* The OC I2C core does not work with stand alone START events,
|
||||||
instead the event is buffered */
|
instead the event is buffered */
|
||||||
prv_ptr->sendstart = GRI2C_CMD_STA;
|
prv_ptr->sendstart = GRI2C_CMD_STA;
|
||||||
|
|
||||||
#if defined(DEBUG)
|
DBG("exited\n");
|
||||||
printk("exited\n");
|
|
||||||
#endif
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rtems_status_code gr_i2cmst_send_stop(rtems_libi2c_bus_t *bushdl)
|
static rtems_status_code gr_i2cmst_send_stop(rtems_libi2c_bus_t *bushdl)
|
||||||
{
|
{
|
||||||
gr_i2cmst_prv_t *prv_ptr = &(((gr_i2cmst_desc_t *)(bushdl))->prv);
|
gr_i2cmst_prv_t *prv_ptr = (gr_i2cmst_prv_t *)bushdl;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("gr_i2cmst_send_stop called...");
|
DBG("gr_i2cmst_send_stop called...");
|
||||||
#endif
|
|
||||||
|
|
||||||
prv_ptr->reg_ptr->cmdsts = GRI2C_CMD_STO;
|
prv_ptr->reg_ptr->cmdsts = GRI2C_CMD_STO;
|
||||||
|
|
||||||
#if defined(DEBUG)
|
DBG("exited\n");
|
||||||
printk("exited\n");
|
|
||||||
#endif
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rtems_status_code gr_i2cmst_send_addr(rtems_libi2c_bus_t *bushdl,
|
static rtems_status_code gr_i2cmst_send_addr(rtems_libi2c_bus_t *bushdl,
|
||||||
uint32_t addr, int rw)
|
uint32_t addr, int rw)
|
||||||
{
|
{
|
||||||
gr_i2cmst_prv_t *prv_ptr = &(((gr_i2cmst_desc_t *)(bushdl))->prv);
|
gr_i2cmst_prv_t *prv_ptr = (gr_i2cmst_prv_t *)bushdl;
|
||||||
uint8_t addr_byte;
|
uint8_t addr_byte;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("gr_i2cmst_send_addr called, addr = 0x%x, rw = %d...",
|
DBG("gr_i2cmst_send_addr called, addr = 0x%x, rw = %d...",
|
||||||
addr, rw);
|
addr, rw);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if long address is needed */
|
/* Check if long address is needed */
|
||||||
if (addr > 0x7f) {
|
if (addr > 0x7f) {
|
||||||
@@ -156,9 +163,9 @@ static rtems_status_code gr_i2cmst_send_addr(rtems_libi2c_bus_t *bushdl,
|
|||||||
/* Wait for transfer to complete */
|
/* Wait for transfer to complete */
|
||||||
rc = gr_i2cmst_wait(prv_ptr, GRI2C_STATUS_IDLE);
|
rc = gr_i2cmst_wait(prv_ptr, GRI2C_STATUS_IDLE);
|
||||||
if (rc != RTEMS_SUCCESSFUL) {
|
if (rc != RTEMS_SUCCESSFUL) {
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("exited with error\n");
|
DBG("exited with error\n");
|
||||||
#endif
|
|
||||||
return -rc;
|
return -rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,16 +183,12 @@ static rtems_status_code gr_i2cmst_send_addr(rtems_libi2c_bus_t *bushdl,
|
|||||||
/* Wait for transfer to complete */
|
/* Wait for transfer to complete */
|
||||||
rc = gr_i2cmst_wait(prv_ptr, GRI2C_STATUS_IDLE);
|
rc = gr_i2cmst_wait(prv_ptr, GRI2C_STATUS_IDLE);
|
||||||
if (rc != RTEMS_SUCCESSFUL) {
|
if (rc != RTEMS_SUCCESSFUL) {
|
||||||
#if defined(DEBUG)
|
DBG("exited with error\n");
|
||||||
printk("exited with error\n");
|
|
||||||
#endif
|
|
||||||
return -rc;
|
return -rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
DBG("exited\n");
|
||||||
printk("exited\n");
|
|
||||||
#endif
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,13 +196,12 @@ static rtems_status_code gr_i2cmst_send_addr(rtems_libi2c_bus_t *bushdl,
|
|||||||
static int gr_i2cmst_read_bytes(rtems_libi2c_bus_t *bushdl,
|
static int gr_i2cmst_read_bytes(rtems_libi2c_bus_t *bushdl,
|
||||||
unsigned char *bytes, int nbytes)
|
unsigned char *bytes, int nbytes)
|
||||||
{
|
{
|
||||||
gr_i2cmst_prv_t *prv_ptr = &(((gr_i2cmst_desc_t *)(bushdl))->prv);
|
gr_i2cmst_prv_t *prv_ptr = (gr_i2cmst_prv_t *)bushdl;
|
||||||
unsigned char *buf = bytes;
|
unsigned char *buf = bytes;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
unsigned char expected_sts = GRI2C_STATUS_IDLE;
|
unsigned char expected_sts = GRI2C_STATUS_IDLE;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("gr_i2cmst_read_bytes called, nbytes = %d...", nbytes);
|
DBG("gr_i2cmst_read_bytes called, nbytes = %d...", nbytes);
|
||||||
#endif
|
|
||||||
|
|
||||||
while (nbytes-- > 0) {
|
while (nbytes-- > 0) {
|
||||||
if (nbytes == 0) {
|
if (nbytes == 0) {
|
||||||
@@ -214,34 +216,30 @@ static int gr_i2cmst_read_bytes(rtems_libi2c_bus_t *bushdl,
|
|||||||
/* Wait until end of transfer */
|
/* Wait until end of transfer */
|
||||||
rc = gr_i2cmst_wait(prv_ptr, expected_sts);
|
rc = gr_i2cmst_wait(prv_ptr, expected_sts);
|
||||||
if (rc != RTEMS_SUCCESSFUL) {
|
if (rc != RTEMS_SUCCESSFUL) {
|
||||||
|
DBG("exited with error\n");
|
||||||
return -rc;
|
return -rc;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("exited with error\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
*buf++ = prv_ptr->reg_ptr->tdrd;
|
*buf++ = prv_ptr->reg_ptr->tdrd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
DBG("exited\n");
|
||||||
printk("exited\n");
|
|
||||||
#endif
|
|
||||||
return buf - bytes;
|
return buf - bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gr_i2cmst_write_bytes(rtems_libi2c_bus_t *bushdl,
|
static int gr_i2cmst_write_bytes(rtems_libi2c_bus_t *bushdl,
|
||||||
unsigned char *bytes, int nbytes)
|
unsigned char *bytes, int nbytes)
|
||||||
{
|
{
|
||||||
gr_i2cmst_prv_t *prv_ptr = &(((gr_i2cmst_desc_t *)(bushdl))->prv);
|
gr_i2cmst_prv_t *prv_ptr = (gr_i2cmst_prv_t *)bushdl;
|
||||||
unsigned char *buf = bytes;
|
unsigned char *buf = bytes;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("gr_i2cmst_write_bytes called, nbytes = %d...", nbytes);
|
DBG("gr_i2cmst_write_bytes called, nbytes = %d...", nbytes);
|
||||||
#endif
|
|
||||||
|
|
||||||
while (nbytes-- > 0) {
|
while (nbytes-- > 0) {
|
||||||
#if defined(DEBUG)
|
|
||||||
printk("writing byte 0x%02X...", *buf);
|
DBG("writing byte 0x%02X...", *buf);
|
||||||
#endif
|
|
||||||
prv_ptr->reg_ptr->tdrd = *buf++;
|
prv_ptr->reg_ptr->tdrd = *buf++;
|
||||||
prv_ptr->reg_ptr->cmdsts = GRI2C_CMD_WR | prv_ptr->sendstart;
|
prv_ptr->reg_ptr->cmdsts = GRI2C_CMD_WR | prv_ptr->sendstart;
|
||||||
prv_ptr->sendstart = 0;
|
prv_ptr->sendstart = 0;
|
||||||
@@ -250,16 +248,13 @@ static int gr_i2cmst_write_bytes(rtems_libi2c_bus_t *bushdl,
|
|||||||
rc = gr_i2cmst_wait(prv_ptr, GRI2C_STATUS_IDLE);
|
rc = gr_i2cmst_wait(prv_ptr, GRI2C_STATUS_IDLE);
|
||||||
|
|
||||||
if (rc != RTEMS_SUCCESSFUL) {
|
if (rc != RTEMS_SUCCESSFUL) {
|
||||||
#if defined(DEBUG)
|
DBG("exited with error\n");
|
||||||
printk("exited with error\n");
|
|
||||||
#endif
|
|
||||||
return -rc;
|
return -rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
DBG("exited\n");
|
||||||
printk("exited\n");
|
|
||||||
#endif
|
|
||||||
return buf - bytes;
|
return buf - bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,88 +267,148 @@ static rtems_libi2c_bus_ops_t gr_i2cmst_ops = {
|
|||||||
write_bytes: gr_i2cmst_write_bytes,
|
write_bytes: gr_i2cmst_write_bytes,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Get Hardware and disable it */
|
||||||
|
int i2cmst_device_init(gr_i2cmst_prv_t *priv)
|
||||||
|
{
|
||||||
|
struct amba_dev_info *ambadev;
|
||||||
|
struct ambapp_core *pnpinfo;
|
||||||
|
|
||||||
static gr_i2cmst_desc_t gr_i2cmst_desc = {
|
/* Get device information from AMBA PnP information */
|
||||||
{ /* rtems_libi2c_bus_t */
|
ambadev = (struct amba_dev_info *)priv->dev->businfo;
|
||||||
ops : &gr_i2cmst_ops,
|
if ( ambadev == NULL ) {
|
||||||
size : sizeof(gr_i2cmst_ops),
|
return -1;
|
||||||
},
|
}
|
||||||
{ /* gr_i2cmst_prv_t, private data */
|
pnpinfo = &ambadev->info;
|
||||||
reg_ptr : NULL,
|
priv->reg_ptr = (gr_i2cmst_regs_t *)pnpinfo->apb_slv->start;
|
||||||
sysfreq : 40000,
|
|
||||||
|
/* Disable core */
|
||||||
|
priv->reg_ptr->ctrl = 0;
|
||||||
|
|
||||||
|
priv->i2clib_desc.ops = &gr_i2cmst_ops;
|
||||||
|
priv->i2clib_desc.size = sizeof(gr_i2cmst_ops);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************* Driver Manager Part ***********************/
|
||||||
|
|
||||||
|
int i2cmst_init2(struct drvmgr_dev *dev);
|
||||||
|
int i2cmst_init3(struct drvmgr_dev *dev);
|
||||||
|
|
||||||
|
struct drvmgr_drv_ops i2cmst_ops =
|
||||||
|
{
|
||||||
|
.init = {NULL, i2cmst_init2, i2cmst_init3, NULL},
|
||||||
|
.remove = NULL,
|
||||||
|
.info = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Scans for I2CMST core and initalizes i2c library */
|
struct amba_dev_id i2cmst_ids[] =
|
||||||
rtems_status_code leon_register_i2c(struct ambapp_bus *abus)
|
|
||||||
{
|
{
|
||||||
#if defined(DEBUG)
|
{VENDOR_GAISLER, GAISLER_I2CMST},
|
||||||
printk("leon_register_i2c called...");
|
{0, 0} /* Mark end of table */
|
||||||
#endif
|
};
|
||||||
|
|
||||||
|
struct amba_drv_info i2cmst_drv_info =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
DRVMGR_OBJ_DRV, /* Driver */
|
||||||
|
NULL, /* Next driver */
|
||||||
|
NULL, /* Device list */
|
||||||
|
DRIVER_AMBAPP_GAISLER_I2CMST_ID, /* Driver ID */
|
||||||
|
"I2CMST_DRV", /* Driver Name */
|
||||||
|
DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */
|
||||||
|
&i2cmst_ops,
|
||||||
|
NULL, /* Funcs */
|
||||||
|
0, /* No devices yet */
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
&i2cmst_ids[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
void i2cmst_register_drv (void)
|
||||||
|
{
|
||||||
|
DBG("Registering I2CMST driver\n");
|
||||||
|
drvmgr_drv_register(&i2cmst_drv_info.general);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The I2CMST Driver is informed about a new hardware device */
|
||||||
|
int i2cmst_init2(struct drvmgr_dev *dev)
|
||||||
|
{
|
||||||
|
gr_i2cmst_prv_t *priv;
|
||||||
|
|
||||||
|
DBG("I2CMST[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
|
||||||
|
|
||||||
|
priv = dev->priv = malloc(sizeof(gr_i2cmst_prv_t));
|
||||||
|
if ( !priv )
|
||||||
|
return DRVMGR_NOMEM;
|
||||||
|
memset(priv, 0, sizeof(*priv));
|
||||||
|
priv->dev = dev;
|
||||||
|
|
||||||
|
/* This core will not find other cores, so we wait for init2() */
|
||||||
|
|
||||||
|
return DRVMGR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init stage 2 */
|
||||||
|
int i2cmst_init3(struct drvmgr_dev *dev)
|
||||||
|
{
|
||||||
|
gr_i2cmst_prv_t *priv;
|
||||||
|
char prefix[32];
|
||||||
|
char devName[32];
|
||||||
int rc;
|
int rc;
|
||||||
int device_found = 0;
|
|
||||||
struct ambapp_apb_info apbi2cmst;
|
|
||||||
|
|
||||||
/* Scan AMBA bus for I2CMST core */
|
priv = (gr_i2cmst_prv_t *)dev->priv;
|
||||||
device_found = ambapp_find_apbslv(abus, VENDOR_GAISLER, GAISLER_I2CMST,
|
|
||||||
&apbi2cmst);
|
|
||||||
|
|
||||||
if (device_found == 1) {
|
/* Do initialization */
|
||||||
|
|
||||||
/* Initialize i2c library */
|
/* Initialize i2c library */
|
||||||
rc = rtems_libi2c_initialize();
|
rc = rtems_libi2c_initialize();
|
||||||
if (rc < 0) {
|
if (rc != 0) {
|
||||||
#if defined(DEBUG)
|
DBG("I2CMST: rtems_libi2c_initialize failed, exiting...\n");
|
||||||
printk("rtems_libi2x_initialize failed, exiting...\n");
|
free(dev->priv);
|
||||||
#endif
|
dev->priv = NULL;
|
||||||
return rc;
|
return DRVMGR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gr_i2cmst_desc.prv.reg_ptr = (gr_i2cmst_regs_t *)apbi2cmst.start;
|
/* I/O system registered and initialized
|
||||||
|
* Now we take care of device initialization.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Detect system frequency, same as in apbuart_initialize */
|
/* Get frequency */
|
||||||
#ifndef SYS_FREQ_kHZ
|
if ( drvmgr_freq_get(dev, DEV_APB_SLV, &priv->sysfreq) ) {
|
||||||
#if defined(LEON3)
|
return DRVMGR_FAIL;
|
||||||
/* LEON3: find timer address via AMBA Plug&Play info */
|
}
|
||||||
{
|
priv->sysfreq = priv->sysfreq / 1000; /* Convert to kHz */
|
||||||
struct ambapp_apb_info gptimer;
|
|
||||||
struct gptimer_regs *tregs;
|
|
||||||
|
|
||||||
if (ambapp_find_apbslv(abus, VENDOR_GAISLER,
|
if ( i2cmst_device_init(priv) ) {
|
||||||
GAISLER_GPTIMER, &gptimer) == 1 ) {
|
free(dev->priv);
|
||||||
tregs = (struct gptimer_regs *)gptimer.start;
|
dev->priv = NULL;
|
||||||
gr_i2cmst_desc.prv.sysfreq = (tregs->scaler_reload+1)*1000;
|
return DRVMGR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Filesystem name prefix */
|
||||||
|
prefix[0] = '\0';
|
||||||
|
if ( drvmgr_get_dev_prefix(dev, prefix) ) {
|
||||||
|
/* Failed to get prefix, make sure of a unique FS name
|
||||||
|
* by using the driver minor.
|
||||||
|
*/
|
||||||
|
sprintf(devName, "/dev/i2c%d", dev->minor_drv+1);
|
||||||
} else {
|
} else {
|
||||||
gr_i2cmst_desc.prv.sysfreq = 40000; /* Default to 40MHz */
|
/* Got special prefix, this means we have a bus prefix
|
||||||
|
* And we should use our "bus minor"
|
||||||
|
*/
|
||||||
|
sprintf(devName, "/dev/%si2c%d", prefix, dev->minor_bus+1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#elif defined(LEON2)
|
|
||||||
/* LEON2: use hardcoded address to get to timer */
|
|
||||||
{
|
|
||||||
LEON_Register_Map *regs = (LEON_Register_Map *)0x80000000;
|
|
||||||
gr_i2cmst_desc.prv.sysfreq = (regs->Scaler_Reload+1)*1000;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error CPU not supported for I2CMST driver */
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
/* Use hardcoded frequency */
|
|
||||||
gr_i2cmst_desc.prv.sysfreq = SYS_FREQ_kHZ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rc = rtems_libi2c_register_bus("/dev/i2c1", &gr_i2cmst_desc.bus_desc);
|
/* Register Bus for this Device */
|
||||||
|
rc = rtems_libi2c_register_bus(devName, &priv->i2clib_desc);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
#if defined(DEBUG)
|
DBG("I2CMST: rtems_libi2c_register_bus(%s) failed, exiting..\n", devName);
|
||||||
printk("rtems_libi2c_register_bus failed, exiting..\n");
|
free(dev->priv);
|
||||||
#endif
|
dev->priv = NULL;
|
||||||
return -rc;
|
return DRVMGR_FAIL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
priv->minor = rc;
|
||||||
|
|
||||||
#if defined(DEBUG)
|
return DRVMGR_OK;
|
||||||
printk("exited\n");
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,24 +3,21 @@
|
|||||||
* @ingroup sparc_bsp
|
* @ingroup sparc_bsp
|
||||||
* @defgroup 1553 B1553BRM
|
* @defgroup 1553 B1553BRM
|
||||||
* @ingroup 1553
|
* @ingroup 1553
|
||||||
* @brief Macros used for brm controller
|
* @brief B1553BRM device driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2006.
|
* COPYRIGHT (c) 2006.
|
||||||
* Gaisler Research
|
* Cobham Gaisler AB.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __B1553BRM_H__
|
#ifndef __B1553BRM_H__
|
||||||
#define __B1553BRM_H__
|
#define __B1553BRM_H__
|
||||||
|
|
||||||
#include <ambapp.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -102,6 +99,7 @@ struct bc_msg {
|
|||||||
#define BC_RTRT 0x0002
|
#define BC_RTRT 0x0002
|
||||||
#define BC_BUSA 0x0004
|
#define BC_BUSA 0x0004
|
||||||
#define BC_EOL 0x0020
|
#define BC_EOL 0x0020
|
||||||
|
#define BC_SKIP 0x0040
|
||||||
#define BC_BAME 0x8000
|
#define BC_BAME 0x8000
|
||||||
|
|
||||||
#define BRM_MBC_IRQ 1 /* Monitor Block Counter irq */
|
#define BRM_MBC_IRQ 1 /* Monitor Block Counter irq */
|
||||||
@@ -114,7 +112,7 @@ struct bc_msg {
|
|||||||
#define BRM_IXEQ0_IRQ 256 /* Index Equal Zero irq */
|
#define BRM_IXEQ0_IRQ 256 /* Index Equal Zero irq */
|
||||||
#define BRM_BDRCV_IRQ 512 /* Broadcast Command Received irq */
|
#define BRM_BDRCV_IRQ 512 /* Broadcast Command Received irq */
|
||||||
#define BRM_SUBAD_IRQ 1024 /* Subaddress Accessed irq */
|
#define BRM_SUBAD_IRQ 1024 /* Subaddress Accessed irq */
|
||||||
#define BRM_MERR_IRQ 4096 /* Message Error irq */
|
#define BRM_MERR_IRQ 2048 /* Message Error irq */
|
||||||
#define BRM_TAPF_IRQ 8192 /* Terminal Address Parity Fail irq */
|
#define BRM_TAPF_IRQ 8192 /* Terminal Address Parity Fail irq */
|
||||||
#define BRM_WRAPF_IRQ 16384 /* Wrap Fail irq */
|
#define BRM_WRAPF_IRQ 16384 /* Wrap Fail irq */
|
||||||
#define BRM_DMAF_IRQ 32768 /* DMA Fail irq */
|
#define BRM_DMAF_IRQ 32768 /* DMA Fail irq */
|
||||||
@@ -144,13 +142,6 @@ struct bc_msg {
|
|||||||
#define BRM_MODE_BM 0x2
|
#define BRM_MODE_BM 0x2
|
||||||
#define BRM_MODE_BM_RT 0x3 /* both RT and BM */
|
#define BRM_MODE_BM_RT 0x3 /* both RT and BM */
|
||||||
|
|
||||||
|
|
||||||
/* Register RAMON FPGA BRM driver, calls brm_register */
|
|
||||||
int brm_register_leon3_ramon_fpga(void);
|
|
||||||
|
|
||||||
/* Register RAMON ASIC BRM driver, calls brm_register */
|
|
||||||
int brm_register_leon3_ramon_asic(void);
|
|
||||||
|
|
||||||
#define BRM_FREQ_12MHZ 0
|
#define BRM_FREQ_12MHZ 0
|
||||||
#define BRM_FREQ_16MHZ 1
|
#define BRM_FREQ_16MHZ 1
|
||||||
#define BRM_FREQ_20MHZ 2
|
#define BRM_FREQ_20MHZ 2
|
||||||
@@ -161,15 +152,11 @@ int brm_register_leon3_ramon_asic(void);
|
|||||||
|
|
||||||
#define CLKSEL_MASK 0x7
|
#define CLKSEL_MASK 0x7
|
||||||
|
|
||||||
/* Register BRM driver
|
void b1553brm_register_drv(void);
|
||||||
* See (struct brm_reg).w_ctrl for clksel and clkdiv.
|
|
||||||
* See Enhanced register (the least signinficant 2 bits) in BRM Core for brm_freq
|
|
||||||
* bus = &ambapp_plb for LEON3. (LEON2 not yet supported for this driver)
|
|
||||||
*/
|
|
||||||
int b1553brm_register(struct ambapp_bus *bus, unsigned int clksel, unsigned int clkdiv, unsigned int brm_freq);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __BRM_H__ */
|
#endif /* __BRM_H__ */
|
||||||
|
|
||||||
|
|||||||
@@ -8,19 +8,16 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2007.
|
* COPYRIGHT (c) 2007.
|
||||||
* Gaisler Research
|
* Cobham Gaisler AB.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __GRCAN_H__
|
#ifndef __GRCAN_H__
|
||||||
#define __GRCAN_H__
|
#define __GRCAN_H__
|
||||||
|
|
||||||
#include <ambapp.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -187,21 +184,8 @@ typedef struct {
|
|||||||
#define GRCAN_IOC_SET_SFILTER 40 /* Set Sync Messages RX/TX filters, NULL disables the IRQ completely */
|
#define GRCAN_IOC_SET_SFILTER 40 /* Set Sync Messages RX/TX filters, NULL disables the IRQ completely */
|
||||||
#define GRCAN_IOC_GET_STATUS 41 /* Get status register of GRCAN core */
|
#define GRCAN_IOC_GET_STATUS 41 /* Get status register of GRCAN core */
|
||||||
|
|
||||||
struct grcan_device_info {
|
|
||||||
unsigned int base_address;
|
|
||||||
int irq;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Use hard coded addresses and IRQs to find hardware */
|
void grcan_register_drv(void);
|
||||||
int grcan_rasta_register_abs(struct grcan_device_info *devices, int dev_cnt);
|
|
||||||
|
|
||||||
/* Use prescanned AMBA Plug&Play information to find all GRFIFO cores */
|
|
||||||
int grcan_rasta_register(struct ambapp_bus *abus);
|
|
||||||
int grcan_register(struct ambapp_bus *abus);
|
|
||||||
#if 0
|
|
||||||
void grcan_register(unsigned int baseaddr, unsigned int ram_base);
|
|
||||||
void grcan_interrupt_handler(rtems_vector_number v);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
* @ingroup sparc_bsp
|
* @ingroup sparc_bsp
|
||||||
* @defgroup spw SpaceWire
|
* @defgroup spw SpaceWire
|
||||||
* @ingroup spw
|
* @ingroup spw
|
||||||
* @brief Macros used for Spacewire bus
|
* @brief GRSPW Device Driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2007.
|
* COPYRIGHT (c) 2007.
|
||||||
* Gaisler Research
|
* Cobham Gaisler AB.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
@@ -32,12 +32,18 @@ typedef struct {
|
|||||||
unsigned int txhsize;
|
unsigned int txhsize;
|
||||||
} spw_ioctl_packetsize;
|
} spw_ioctl_packetsize;
|
||||||
|
|
||||||
|
#define GRSPW_PKTSEND_OPTION_HDR_CRC 0x1
|
||||||
|
#define GRSPW_PKTSEND_OPTION_DATA_CRC 0x2
|
||||||
|
#define GRSPW_PKTSEND_OPTION_NOCRCLEN(len) ((len & 0xf) << 8)
|
||||||
|
#define GRSPW_PKTSEND_OPTION_NOCRCLEN_MASK 0xf00
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int hlen;
|
unsigned int hlen;
|
||||||
char *hdr;
|
char *hdr;
|
||||||
unsigned int dlen;
|
unsigned int dlen;
|
||||||
char *data;
|
char *data;
|
||||||
unsigned int sent;
|
unsigned int sent;
|
||||||
|
unsigned int options;
|
||||||
} spw_ioctl_pkt_send;
|
} spw_ioctl_pkt_send;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -84,6 +90,11 @@ typedef struct {
|
|||||||
unsigned int is_rmapcrc;
|
unsigned int is_rmapcrc;
|
||||||
|
|
||||||
unsigned int nodemask;
|
unsigned int nodemask;
|
||||||
|
unsigned int keep_source; /* copy source address to user-buffer in read() operations
|
||||||
|
* Note that rm_prot_id has no effect when keep_source is
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
|
unsigned int rtimeout; /* Read timeout if != 0 */
|
||||||
} spw_config;
|
} spw_config;
|
||||||
|
|
||||||
#define SPACEWIRE_IOCTRL_SET_NODEADDR 1
|
#define SPACEWIRE_IOCTRL_SET_NODEADDR 1
|
||||||
@@ -113,30 +124,42 @@ typedef struct {
|
|||||||
#define SPACEWIRE_IOCTRL_SET_COREFREQ 32
|
#define SPACEWIRE_IOCTRL_SET_COREFREQ 32
|
||||||
#define SPACEWIRE_IOCTRL_SET_CLKDIVSTART 33
|
#define SPACEWIRE_IOCTRL_SET_CLKDIVSTART 33
|
||||||
#define SPACEWIRE_IOCTRL_SET_NODEMASK 34
|
#define SPACEWIRE_IOCTRL_SET_NODEMASK 34
|
||||||
|
#define SPACEWIRE_IOCTRL_SET_KEEP_SOURCE 35
|
||||||
|
#define SPACEWIRE_IOCTRL_SET_TCODE_CTRL 36
|
||||||
|
#define SPACEWIRE_IOCTRL_SET_TCODE 37
|
||||||
|
#define SPACEWIRE_IOCTRL_GET_TCODE 38
|
||||||
|
#define SPACEWIRE_IOCTRL_SET_READ_TIMEOUT 39
|
||||||
|
|
||||||
#define SPACEWIRE_IOCTRL_START 64
|
#define SPACEWIRE_IOCTRL_START 64
|
||||||
#define SPACEWIRE_IOCTRL_STOP 65
|
#define SPACEWIRE_IOCTRL_STOP 65
|
||||||
|
|
||||||
int grspw_register(struct ambapp_bus *bus);
|
/* Defines what register bits that will be touched
|
||||||
|
* for SPACEWIRE_IOCTRL_SET_TCODE_CTRL
|
||||||
|
*/
|
||||||
|
#define SPACEWIRE_TCODE_CTRL_IE_MSK 0x001
|
||||||
|
#define SPACEWIRE_TCODE_CTRL_TT_MSK 0x004
|
||||||
|
#define SPACEWIRE_TCODE_CTRL_TR_MSK 0x008
|
||||||
|
|
||||||
|
/* Defines what register bits that should be set
|
||||||
|
* for SPACEWIRE_IOCTRL_SET_TCODE_CTRL
|
||||||
|
*/
|
||||||
|
#define SPACEWIRE_TCODE_CTRL_IE 0x100
|
||||||
|
#define SPACEWIRE_TCODE_CTRL_TT 0x400
|
||||||
|
#define SPACEWIRE_TCODE_CTRL_TR 0x800
|
||||||
|
|
||||||
#if 0
|
/* SPACEWIRE_IOCTRL_SET_TCODE argument mask */
|
||||||
struct grspw_buf;
|
#define SPACEWIRE_TCODE_TCODE 0x0ff
|
||||||
|
#define SPACEWIRE_TCODE_SET 0x100 /* Set Timecode register */
|
||||||
|
#define SPACEWIRE_TCODE_TX 0x400
|
||||||
|
|
||||||
struct grspw_buf {
|
void grspw_register_drv (void);
|
||||||
grspw_buf *next; /* next packet in chain */
|
|
||||||
|
|
||||||
/* Always used */
|
void grspw_print(int options);
|
||||||
unsigned int dlen; /* data length of '*data' */
|
|
||||||
unsigned int max_dlen; /* allocated length of '*data' */
|
/* Global GRSPW Function pointer called upon timecode receive interrupt */
|
||||||
void *data; /* pointer to beginning of cargo data */
|
extern void (*grspw_timecode_callback)
|
||||||
|
(void *pDev, void *regs, int minor, unsigned int tc);
|
||||||
|
|
||||||
/* Only used when transmitting */
|
|
||||||
unsigned int hlen; /* length of header '*header' */
|
|
||||||
unsigned int max_hlen; /* allocated length of '*header' */
|
|
||||||
void *header; /* pointer to beginning of header data */
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2007 Gaisler Research
|
* COPYRIGHT (c) 2007 Cobham Gaisler AB
|
||||||
* with parts from the RTEMS MPC83xx I2C driver (c) 2007 Embedded Brains GmbH.
|
* with parts from the RTEMS MPC83xx I2C driver (c) 2007 Embedded Brains GmbH.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _I2CMST_H
|
#ifndef _I2CMST_H
|
||||||
@@ -56,26 +55,6 @@ typedef struct gr_i2cmst_regs {
|
|||||||
|
|
||||||
#define GRI2C_STATUS_IDLE 0x00000000
|
#define GRI2C_STATUS_IDLE 0x00000000
|
||||||
|
|
||||||
/* The OC I2C core will perform a write after a start unless the RD bit
|
|
||||||
in the command register has been set. Since the rtems framework has
|
|
||||||
a send_start function we buffer that command and use it when the first
|
|
||||||
data is written. The START is buffered in the sendstart member below */
|
|
||||||
typedef struct gr_i2cmst_prv {
|
|
||||||
gr_i2cmst_regs_t *reg_ptr;
|
|
||||||
unsigned int sysfreq; /* System clock frequency in kHz */
|
|
||||||
unsigned char sendstart; /* START events are buffered here */
|
|
||||||
/* rtems_irq_number irq_number; */
|
|
||||||
/* rtems_id irq_sema_id; */
|
|
||||||
} gr_i2cmst_prv_t;
|
|
||||||
|
|
||||||
typedef struct gr_i2cmst_desc {
|
|
||||||
rtems_libi2c_bus_t bus_desc;
|
|
||||||
gr_i2cmst_prv_t prv;
|
|
||||||
} gr_i2cmst_desc_t;
|
|
||||||
|
|
||||||
/* Scans for I2CMST core and initalizes i2c library */
|
|
||||||
rtems_status_code leon_register_i2c(struct ambapp_bus *abus);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,20 +6,15 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 2007.
|
* COPYRIGHT (c) 2007.
|
||||||
* Gaisler Research.
|
* Cobham Gaisler AB.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*
|
|
||||||
* Author: Daniel Hellstr<74>m, Gaisler Research AB, www.gaisler.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __OCCAN_DRIVER_H__
|
||||||
#ifndef __OCCAN_H__
|
#define __OCCAN_DRIVER_H__
|
||||||
#define __OCCAN_H__
|
|
||||||
|
|
||||||
#include <ambapp.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -152,7 +147,7 @@ struct occan_afilter {
|
|||||||
#define OCCAN_BLK_MODE_RX 0x1
|
#define OCCAN_BLK_MODE_RX 0x1
|
||||||
#define OCCAN_BLK_MODE_TX 0x2
|
#define OCCAN_BLK_MODE_TX 0x2
|
||||||
|
|
||||||
int occan_register(struct ambapp_bus *bus);
|
void occan_register_drv (void);
|
||||||
|
|
||||||
|
|
||||||
#define OCCAN_SPEED_500K 500000
|
#define OCCAN_SPEED_500K 500000
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user