if_robo.c
资源名称:bcm4702.rar [点击查看]
上传用户:yuanda199
上传日期:2022-06-26
资源大小:412k
文件大小:12k
源码类别:
VxWorks
开发平台:
C/C++
- /*
- * BCM53xx RoboSwitch utility functions
- *
- * Copyright (C) 2002 Broadcom Corporation
- *
- * $Id: if_robo.c,v 1.1 Broadcom SDK $
- */
- #if 0
- #include <typedefs.h>
- #include <osl.h>
- #include <sbutils.h>
- #include <nvutils.h>
- #include <proto/ethernet.h>
- #include <etc53xx.h>
- #include "if_robo.h"
- #endif
- /* Missing Defines */
- #define OSL_IN_INTERRUPT() 1
- #define OSL_SLEEP(a) udelay((a))
- void
- udelay(uint usec)
- {
- volatile int i;
- for(i = 0; i < 5*usec; i++);
- }
- /* Missing Defines */
- int clkLen = 20;
- void *robo = 0;
- void *hSb = 0;
- #define robo_debug 0
- #if 1
- #undef OSL_DELAY
- #define OSL_DELAY(a) udelay(a)
- #endif
- robo_driver_t *robo_driver;
- robo_driver_t drv_table[] = {
- { NULL, robosw_rreg, robosw_wreg },
- { NULL, NULL, NULL }
- };
- #define ROBO_POLL_DELAY_US 200000
- /* Get access to the RoboSwitch */
- robo_info_t *
- robosw_attach(void *sbh, uint32 reset, uint32 ssl, uint32 clk, uint32 mosi, uint32 miso)
- {
- robo_info_t *robo;
- #if 0
- unsigned int flags = atoi(nvram_safe_get("boardflags"));
- #endif
- /* set up type of register access based on board type */
- #if 0
- if (flags & ENET_SPI) {
- robo_driver = &drv_table[0];
- } else if (flags & ENET_PMII) {
- robo_driver = &drv_table[1];
- } else {
- #endif
- /* default to SPI*/
- robo_driver = &drv_table[0];
- #if 0
- }
- #endif
- /* Allocate private state */
- if (!(robo = MALLOC(sizeof(robo_info_t)))) {
- printf("robo_attach: out of memory");
- return NULL;
- }
- bzero((char *) robo, sizeof(robo_info_t));
- robo->reset = reset;
- robo->sbh = sbh;
- robo->ssl = ssl;
- robo->clk = clk;
- robo->mosi = mosi;
- robo->miso = miso;
- robo->cid = robo->page = -1;
- /* Initialize GPIO outputs */
- sb_gpioout(robo->sbh, robo->reset|robo->ssl | robo->clk | robo->mosi,
- robo->ssl|robo->reset);
- sb_gpioouten(robo->sbh, robo->reset|robo->ssl | robo->clk | robo->mosi
- | robo->miso, robo->reset|robo->ssl | robo->clk | robo->mosi);
- #ifdef _KERNEL_
- /* Initialize lock */
- spin_lock_init(&robo->lock);
- #endif
- return robo;
- }
- /* Release access to the RoboSwitch */
- void
- robosw_detach(robo_info_t *robo)
- {
- /* Disable GPIO outputs */
- sb_gpioouten(robo->sbh, robo->reset|robo->ssl | robo->clk | robo->mosi, 0);
- /* Free private state */
- MFREE(robo, sizeof(robo_info_t));
- }
- /* Enable serial access to the chip */
- static void
- robo_enable(robo_info_t *robo)
- {
- void *regs;
- /* Save current core index */
- robo->coreidx = sb_coreidx(robo->sbh);
- /* Switch to GPIO core for faster access */
- regs = sb_gpiosetcore(robo->sbh);
- ASSERT(regs);
- }
- /* Disable serial access to the chip */
- static void
- robo_disable(robo_info_t *robo)
- {
- /* Switch back to original core */
- sb_setcoreidx(robo->sbh, robo->coreidx);
- }
- /* Write a byte stream to the chip */
- static void
- robo_write(robo_info_t *robo, uint8 *buf, uint len)
- {
- uint i;
- uint8 mask;
- if (robo_debug) {
- printf("%s: ", __FUNCTION__);
- for (i=0; i<len ; i++) printf("0x%02X ", buf[i]);
- printf("n");
- }
- for (i = 0; i < len; i++) {
- /* Bit bang from MSB to LSB */
- for (mask = 0x80; mask; mask >>= 1) {
- /* Clock low */
- sb_gpioout(robo->sbh, robo->clk, 0);
- OSL_DELAY(clkLen);
- /* Output on rising edge */
- if (mask & buf[i])
- sb_gpioout(robo->sbh, robo->mosi, robo->mosi);
- else
- sb_gpioout(robo->sbh, robo->mosi, 0);
- /* Clock high */
- sb_gpioout(robo->sbh, robo->clk, robo->clk);
- OSL_DELAY(clkLen);
- }
- }
- }
- /* Handy macros for writing fixed length values */
- #define robo_write8(robo, b) { uint8 val = (uint8) (b); robo_write((robo), &val, sizeof(val)); }
- #define robo_write16(robo, w) { uint16 val = (uint16) (w); robo_write((robo), &val, sizeof(val)); }
- #define robo_write32(robo, l) { uint32 val = (uint32) (l); robo_write((robo), &val, sizeof(val)); }
- /* Read a byte stream from the chip */
- static void
- robo_read(robo_info_t *robo, uint8 *buf, uint len)
- {
- uint i;
- uint8 rack, mask, byte;
- for (i = 0, rack = 0; i < len;) {
- /* Bit bang from MSB to LSB */
- for (mask = 0x80, byte = 0; mask; mask >>= 1) {
- /* Clock low */
- sb_gpioout(robo->sbh, robo->clk, 0);
- OSL_DELAY(clkLen);
- sb_gpioout(robo->sbh, robo->mosi, 0);
- /* Sample */
- if (sb_gpioin(robo->sbh) & robo->miso)
- byte |= mask;
- /* Clock high */
- sb_gpioout(robo->sbh, robo->clk, robo->clk);
- OSL_DELAY(clkLen);
- }
- buf[i] = byte;
- i++;
- }
- if (robo_debug) {
- for (; i>0; i--) printf("0x%02x ", buf[i-1]);
- printf("n");
- }
- }
- /* poll for RACK */
- static int
- robo_poll_for_RACK(robo_info_t *robo)
- {
- uint i, timeout;
- uint8 byte;
- /* Timeout after 100 tries without RACK */
- for (i = 0, timeout = 100; timeout;) {
- robo_read(robo, &byte, sizeof(byte));
- /* RACK when bit 0 is high */
- if (byte & 0x01)
- break;
- else
- {
- timeout--;
- /* sleep, unless in interrupt mode */
- if (OSL_IN_INTERRUPT())
- {
- #ifndef _CFE_
- udelay(ROBO_POLL_DELAY_US);
- #else
- et_delay(ROBO_POLL_DELAY_US);
- #endif
- /* OSL_DELAY(ROBO_POLL_DELAY_US); */
- }
- else
- {
- OSL_SLEEP(ROBO_POLL_DELAY_US);
- }
- }
- }
- if (timeout == 0) {
- printf("robo_read: timeout");
- return -1;
- }
- return 0;
- }
- /* poll for MDIO_START low */
- static int
- robo_poll_for_MDIO_START(robo_info_t *robo, uint8 cid)
- {
- uint i, timeout;
- uint8 byte;
- uint data;
- /* Timeout after 100 tries without MDIO_START low */
- for (i = 0, timeout = 100; timeout;) {
- sb_gpioout(robo->sbh, robo->ssl, 0);
- robo_write8(robo, 0x60 | ((cid & 0x7) << 1));
- robo_write8(robo, 0xfe);
- robo_read((robo), &byte, sizeof(char));
- sb_gpioout(robo->sbh, robo->ssl, robo->ssl);
- /* MDIO_START is bit 2 of SPI_STS */
- if (!(byte & 0x4))
- break;
- else
- {
- timeout--;
- data = (uint)byte;
- /* sleep, unless in interrupt mode */
- if (OSL_IN_INTERRUPT())
- {
- #ifndef _CFE_
- udelay(ROBO_POLL_DELAY_US);
- #else
- et_delay(ROBO_POLL_DELAY_US);
- #endif
- /* OSL_DELAY(ROBO_POLL_DELAY_US); */
- }
- else
- {
- OSL_SLEEP(ROBO_POLL_DELAY_US);
- }
- }
- }
- if (timeout == 0) {
- printf("robo_read: timeout");
- return -1;
- }
- return 0;
- }
- /* Handy macros for reading fixed length values */
- #define robo_read8(robo) { uint8 val; robo_read((robo), &val, sizeof(val)); val; }
- #define robo_read16(robo) { uint16 val; robo_read((robo), &val, sizeof(val)); val; }
- #define robo_read32(robo) { uint32 val; robo_read((robo), &val, sizeof(val)); val; }
- /* Select new chip and page */
- static void
- robo_select(robo_info_t *robo, uint8 cid, uint8 page)
- {
- /* Chip and page already selected */
- if (robo->cid == (int) cid && robo->page == (int) page)
- return;
- robo->cid = (int) cid;
- robo->page = (int) page;
- /* Enable CS */
- sb_gpioout(robo->sbh, robo->ssl, 0);
- OSL_DELAY(clkLen);
- /* Select new chip */
- robo_write8(robo, 0x61 | ((cid & 0x7) << 1));
- /* Select new page */
- robo_write8(robo, 0xff);
- robo_write8(robo, page);
- /* Disable CS */
- sb_gpioout(robo->sbh, robo->ssl, robo->ssl);
- OSL_DELAY(clkLen);
- }
- /* Write chip register */
- void
- robosw_wreg(robo_info_t *robo, uint8 cid, uint8 page, uint8 addr, uint8 *buf, uint len)
- {
- #ifdef _KERNEL_
- unsigned long flags;
- spin_lock_irqsave(&robo->lock, flags);
- #endif
- robo_enable(robo);
- if (robo_poll_for_MDIO_START(robo, cid))
- {
- /* timeout */
- robo_select(robo, cid, page);
- return;
- }
- /* Select chip and page */
- robo_select(robo, cid, page);
- /* Enable CS */
- sb_gpioout(robo->sbh, robo->ssl, 0);
- OSL_DELAY(clkLen);
- /* Write */
- robo_write8(robo, 0x61 | ((cid & 0x7) << 1));
- robo_write8(robo, addr);
- robo_write(robo, buf, len);
- /* Disable CS */
- sb_gpioout(robo->sbh, robo->ssl, robo->ssl);
- OSL_DELAY(clkLen);
- robo_disable(robo);
- #ifdef _KERNEL_
- spin_unlock_irqrestore(&robo->lock, flags);
- #endif
- }
- /* Read chip register */
- void
- robosw_rreg(robo_info_t *robo, uint8 cid, uint8 page, uint8 addr, uint8 *buf, uint len)
- {
- #ifdef _KERNEL_
- unsigned long flags;
- spin_lock_irqsave(&robo->lock, flags);
- #endif
- robo_enable(robo);
- if (robo_poll_for_MDIO_START(robo,cid))
- /* timeout */
- return;
- /* Select chip and page */
- robo_select(robo, cid, page);
- /* Enable CS */
- sb_gpioout(robo->sbh, robo->ssl, 0);
- /*delay so uP have sufficient time to prepare data */
- OSL_DELAY(clkLen);
- /* Fast read */
- robo_write8(robo, 0x10 | ((cid & 0x7) << 1));
- OSL_DELAY(clkLen);
- robo_write8(robo, addr);
- OSL_DELAY(clkLen);
- if (robo_poll_for_RACK(robo))
- /* timeout */
- return;
- robo_read(robo, buf, len);
- /* Disable CS */
- sb_gpioout(robo->sbh, robo->ssl, robo->ssl);
- OSL_DELAY(clkLen);
- robo_disable(robo);
- #ifdef _KERNEL_
- spin_unlock_irqrestore(&robo->lock, flags);
- #endif
- }
- #define sb_doattach(a, b, c, d, e, f) sb_attach((a), (b), (c), (e), (f))
- /* generic kernel variant of sb_attach() */
- void*
- sb_robo_kattach()
- {
- #if 0
- char *unused;
- int varsz;
- return (sb_doattach(BCM4710_DEVICE_ID, NULL, (void*)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE),
- SB_BUS, &unused, &varsz));
- #else
- return (sb_kattach (BCM4710_DEVICE_ID, 0));
- #endif
- }
- /*
- * Init API
- */
- void *
- bcm_robo_api_init()
- {
- if (!(hSb = sb_robo_kattach()))
- return 0;
- if (!(robo = robosw_attach(hSb, 1, (1 << 2), (1 << 3), (1 << 4), (1 << 5))))
- return 0;
- /* sema_init (&robo_sema, 1);*/
- return robo;
- }
- uint8 tr_buf[256];
- int
- tr_wreg(uint8 cid, uint8 page, uint8 addr, uint len)
- {
- int i;
- uint8 *buf;
- if (robo == NULL) { bcm_robo_api_init(); }
- buf = tr_buf;
- robosw_wreg(robo, cid, page, addr, buf, len);
- printf("robo = %p cid = %d page = %d addr = %02x len = %dn",
- robo, cid, page, addr, len);
- for(i = 0; i < len; i++) {
- if (!(i % 16)) printf("n");
- printf(" %02X", (unsigned int)buf[i] & 0xFF);
- }
- return(0);
- }
- int
- tr_rreg(uint8 cid, uint8 page, uint8 addr, uint len)
- {
- uint8 buf[256];
- int i;
- if (robo == NULL) { bcm_robo_api_init(); }
- robosw_rreg(robo, cid, page, addr, buf, len);
- printf("robo = %p cid = %d page = %d addr = %02x len = %dn",
- robo, cid, page, addr, len);
- for(i = 0; i < len; i++) {
- if (!(i % 16)) printf("n");
- printf(" %02X", (unsigned int)buf[i] & 0xFF);
- }
- return(0);
- }
- int
- robo_tcl_wreg(uint8 cid, uint8 page, uint8 addr, uint8 *buf, uint len)
- {
- int i;
- if (robo == NULL) { bcm_robo_api_init(); }
- if (gSPIEnable)
- robosw_wreg(robo, cid, page, addr, buf, len);
- else
- robo_mdio_wreg(cid, page, addr, buf, len);
- if (robo_debug) {
- printf("Write Reg: robo = %p cid = %d page = %d addr = %02x len = %dn",
- robo, cid, page, addr, len);
- for(i = 0; i < len; i++) {
- if (!(i % 16)) printf("n");
- printf(" %02X", (unsigned int)buf[i] & 0xFF);
- }
- }
- return(0);
- }
- int
- robo_tcl_rreg(uint8 cid, uint8 page, uint8 addr, uint8* buf, uint len)
- {
- int i;
- if (robo == NULL) { bcm_robo_api_init(); }
- if (gSPIEnable)
- robosw_rreg(robo, cid, page, addr, buf, len);
- else
- robo_mdio_rreg(cid, page, addr, buf, len);
- if (robo_debug) {
- printf("Read Reg: robo = %p cid = %d page = %d addr = %02x len = %dn",
- robo, cid, page, addr, len);
- for(i = 0; i < len; i++) {
- if (!(i % 16)) printf("n");
- printf(" %02X", (unsigned int)buf[i] & 0xFF);
- }
- }
- return(0);
- }
- /* reset robo chips*/
- int robo_reset(void)
- { robo_info_t *p ;
- if (robo == NULL) {
- if (!bcm_robo_api_init()) {
- printf("Err: unable to attach to robo devicen");
- return (1);
- }
- }
- p = (robo_info_t *) robo;
- sb_gpioout(p->sbh, p->reset, p->reset);
- OSL_DELAY(10);
- sb_gpioout(p->sbh, p->reset, 0);
- OSL_DELAY(10);
- sb_gpioout(p->sbh, p->reset, p->reset);
- robosw_detach(robo);
- robo = 0;
- robo_mdio_reset();
- return(0);
- }