blob: 479c5f96bd80550cc94c8ab52ff864fe4cbb2b2b [file] [log] [blame]
/*
<:copyright-BRCM:2016:DUAL/GPL:standard
Broadcom Proprietary and Confidential.(c) 2016 Broadcom
All Rights Reserved
Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:
As a special exception, the copyright holders of this software give
you permission to link this software with independent modules, and
to copy and distribute the resulting executable under terms of your
choice, provided that you also meet, for each linked independent
module, the terms and conditions of the license of that module.
An independent module is a module which is not derived from this
software. The special exception does not apply to any modifications
of the software.
Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.
:>
*/
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <bcmcli.h>
#include <bcmolt_i2c_devs_ioctl.h>
#include <bcmolt_dev_ctrl_ioctl.h>
#include <bcmolt_api.h>
#include <bcmolt_model_types.h>
#include <bcmolt_fld.h>
#include "bcmolt_board.h"
#include "bcmolt_dpll_table.h"
#define BCM_I2C_DEV_ADDR_START typedef enum {
#define BCM_I2C_DEV_ADDR(name, desc, val) name = val,
#define BCM_I2C_DEV_ADDR_END } bcm_i2c_dev_addr;
#define BCM_FPGA_REG_FPGA_VERSION 0x0
#define BCM_FPGA_REG_BOARD_CONF 0x1
#define BCM_FPGA_REG_RESETS 0x2
/* Enable/disable transceiver */
#define BCM_FPGA_REG_TRX_ENABLE 0x3
#define BCM_FPGA_REG_TRX_FAIL 0x4
/* Is transceiver present ? */
#define BCM_FPGA_REG_TRX_IS_PRESENT 0x5
#define BCM_FPGA_REG_CXP_CONTROLS 0x6
#define BCM_FPGA_REG_SHIFT_REGISTER_DATA 0x7
#define BCM_FPGA_REG_SHIFT_REGISTER_CONTROL 0x8
#define BCM_FPGA_REG_LEDS 0x9
#define BCM_FPGA_REG_DEBUG_LEDS 0xA
#define BCM_FPGA_REG_GPIO_DIR 0xB
#define BCM_FPGA_REG_GPIO_INPUT 0xC
#define BCM_FPGA_REG_GPIO_OUTPUT 0xD
#define BCM_FPGA_REG_GPIO_IRQ 0xE
#define BCM_FPGA_REG_LOW BCM_FPGA_REG_FPGA_VERSION
#define BCM_FPGA_REG_HIGH BCM_FPGA_REG_GPIO_IRQ
#define BCM_RST_BIT_DEVICE 0x0
#define BCM_RST_BIT_PON_DPLL 0x1
#define BCM_RST_BIT_PM_DPLL 0x2
#define BCM_RST_BIT_KT2 0x4
#define SVK4_IDENT_FILE "/etc/svk4"
#include <bcmolt_i2c_devs_addr.h>
#define MAX_CMD_STR_LEN 1024
/* Since the board driver configuration is specific for Linux, there is no point using OS abstraction layer to perform operations like ioctl(). */
static int maple_i2c_fd;
static int maple_dev_ctrl_fd;
static bcmos_bool bcm_board_is_svk4(void)
{
bcmos_bool is_svk4 = BCMOS_FALSE;
FILE *f = fopen(SVK4_IDENT_FILE, "r");
if (f)
{
is_svk4 = BCMOS_TRUE;
fclose(f);
}
return is_svk4;
}
static bcmos_errno bcm_access_fpga(void)
{
bcmos_errno rc;
if (bcm_board_is_svk4())
{
rc = bcm_board_dev_change(I2C_SW1_I2C_ADDR);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW1_I2C_ADDR) failed\n");
rc = bcm_board_switch_write(0x4);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(1) failed\n");
}
else
{
rc = bcm_board_dev_change(I2C_SW0_I2C_ADDR);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW0_I2C_ADDR) failed\n");
rc = bcm_board_switch_write(1);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(1) failed\n");
}
rc = bcm_board_dev_change(FPGA_I2C_ADDR);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(FPGA_I2C_ADDR) failed \n");
return BCM_ERR_OK;
}
bcmos_errno bcm_board_dev_change(uint32_t addr)
{
int rc;
maple_i2c_ioctl_param params =
{
.addr = addr,
};
rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_CHANGE, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
return BCM_ERR_OK;
}
bcmos_errno bcm_board_dev_write(uint32_t count, uint32_t addr, uint32_t val)
{
int rc;
maple_i2c_ioctl_param params =
{
.count = count,
.addr = addr,
.val = val,
};
rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
return BCM_ERR_OK;
}
bcmos_errno bcm_board_dev_read(uint32_t count, uint32_t addr, uint32_t *val)
{
int rc;
maple_i2c_ioctl_param params =
{
.count = count,
.addr = addr,
};
rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_READ, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
*val = params.val;
return BCM_ERR_OK;
}
bcmos_errno bcm_board_switch_write(uint32_t val)
{
int rc;
maple_i2c_ioctl_param params =
{
.val = val,
};
rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_SWITCH_WRITE, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
return BCM_ERR_OK;
}
bcmos_errno bcm_board_switch_read(uint32_t *val)
{
int rc;
maple_i2c_ioctl_param params = {};
rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_SWITCH_READ, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
*val = params.val;
return BCM_ERR_OK;
}
bcmos_errno bcm_board_fpga_write(uint32_t addr, uint32_t val)
{
int rc;
maple_i2c_ioctl_param params =
{
.addr = addr,
.val = val,
};
rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_FPGA_WRITE, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for fpga_write\n");
return BCM_ERR_OK;
}
bcmos_errno bcm_board_host_event_write(uint32_t val)
{
int rc;
dev_ctrl_ioctl_param params =
{
.event = val,
};
rc = ioctl(maple_dev_ctrl_fd, MAPLE_DEV_CTRL_IOCTL_OP_HOST_EVENT_WRITE, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for host_event_write\n");
#ifdef CONFIG_ONU_SIM
/* Raise an interrupt on ext_irq1 for the embedded side. */
rc = bcm_board_fpga_gen_gpio_irq(BCMOLT_EXT_IRQ_EXT_IRQ1);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for bcm_board_fpga_gen_gpio_irq\n");
#endif
return BCM_ERR_OK;
}
bcmos_errno bcm_board_pci_debug(uint32_t device, uint32_t command, int32_t start, int32_t howmany, uint32_t *dumpptr)
{
int rc;
dev_ctrl_ioctl_param params =
{
.device = device,
.dumpptr = dumpptr,
.start_index = start,
.howmany = howmany
};
rc = ioctl(maple_dev_ctrl_fd, command, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for dev_ctrl\n");
return BCM_ERR_OK;
}
bcmos_errno bcm_board_fpga_read(uint32_t addr, uint32_t *val)
{
int rc;
maple_i2c_ioctl_param params =
{
.addr = addr,
};
rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_FPGA_READ, &params);
BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for fpga_read\n");
*val = params.val;
return BCM_ERR_OK;
}
bcmos_errno bcm_board_fpga_reg_read(uint32_t reg, uint32_t *val)
{
bcmos_errno rc;
if (reg > BCM_FPGA_REG_HIGH)
return BCM_ERR_RANGE;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
return bcm_board_fpga_read(reg, val);
}
bcmos_errno bcm_board_fpga_reg_write(uint32_t reg, uint32_t val)
{
bcmos_errno rc;
if (reg > BCM_FPGA_REG_HIGH)
return BCM_ERR_RANGE;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
return bcm_board_fpga_write(reg, val);
}
bcmos_errno bcm_board_fpga_version_get(uint32_t *version)
{
bcmos_errno rc;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
return bcm_board_fpga_read(BCM_FPGA_REG_FPGA_VERSION, version);
}
bcmos_errno bcm_board_fpga_set_gpio_dir(bcmolt_gpio_pin gpio_pin, bcm_fpga_gpio_dir dir)
{
bcmos_errno rc;
uint32_t gpio_dir_mask;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
/* Read-modify-write direction register (we don't want to affect other GPIO's). */
rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_DIR, &gpio_dir_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
if (dir == BCM_FPGA_GPIO_DIR_INPUT)
gpio_dir_mask &= ~(1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
else
gpio_dir_mask |= (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
return bcm_board_fpga_write(BCM_FPGA_REG_GPIO_DIR, gpio_dir_mask);
}
bcmos_errno bcm_board_fpga_get_gpio_dir(bcmolt_gpio_pin gpio_pin, bcm_fpga_gpio_dir *dir)
{
bcmos_errno rc;
uint32_t gpio_dir_mask;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_DIR, &gpio_dir_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
*dir = (gpio_dir_mask & (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4))) ? BCM_FPGA_GPIO_DIR_OUTPUT : BCM_FPGA_GPIO_DIR_INPUT;
return rc;
}
bcmos_errno bcm_board_fpga_write_gpio(bcmolt_gpio_pin gpio_pin, uint32_t val)
{
bcmos_errno rc;
uint32_t gpio_write_mask;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
/* Read-modify-write direction register (we don't want to affect other GPIO's). */
rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_OUTPUT, &gpio_write_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
if (!val)
gpio_write_mask &= ~(1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
else
gpio_write_mask |= (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
return bcm_board_fpga_write(BCM_FPGA_REG_GPIO_OUTPUT, gpio_write_mask);
}
bcmos_errno bcm_board_fpga_read_gpio(bcmolt_gpio_pin gpio_pin, uint32_t *val)
{
bcmos_errno rc;
uint32_t gpio_read_mask;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_INPUT, &gpio_read_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
*val = (gpio_read_mask & (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4)));
return rc;
}
bcmos_errno bcm_board_fpga_gen_gpio_irq(bcmolt_ext_irq ext_irq)
{
bcmos_errno rc;
uint32_t gpio_irq_mask;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
/* Read-modify-write direction register (we don't want to affect other GPIO's). */
rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_IRQ, &gpio_irq_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
gpio_irq_mask |= (1 << ext_irq);
rc = bcm_board_fpga_write(BCM_FPGA_REG_GPIO_IRQ, gpio_irq_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
bcmos_usleep(1000);
gpio_irq_mask &= ~(1 << ext_irq);
rc = bcm_board_fpga_write(BCM_FPGA_REG_GPIO_IRQ, gpio_irq_mask);
return rc;
}
bcmos_errno bcm_board_trx_present(uint8_t pon)
{
bcmos_errno rc;
uint32_t trx_absence_mask;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
/* Check that the transceiver is present (plugged in). For ONU simulator, we allow working without transceivers. */
rc = bcm_board_fpga_read(BCM_FPGA_REG_TRX_IS_PRESENT, &trx_absence_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
if (trx_absence_mask & (1 << pon))
{
/* The transceiver is absent. */
return BCM_ERR_NODEV;
}
return BCM_ERR_OK;
}
bcmos_errno bcm_board_trx_enable(uint8_t pon, bcmos_bool is_enabled)
{
#ifdef CONFIG_ONU_SIM
static uint32_t trx_disable_mask = 0xFFFFFFFF;
/* Keep track of which TRXs are logically enabled. */
if (is_enabled)
trx_disable_mask &= ~(1 << pon);
else
trx_disable_mask |= (1 << pon);
return bcm_board_host_event_write(trx_disable_mask);
#else
uint32_t trx_disable_mask;
uint32_t trx_absence_mask;
bcmos_errno rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
/* Check that the transceiver is present (plugged in). */
rc = bcm_board_fpga_read(BCM_FPGA_REG_TRX_IS_PRESENT, &trx_absence_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
if (trx_absence_mask & (1 << pon))
{
/* The transceiver is absent. */
return BCM_ERR_NODEV;
}
/* Read-modify-write transceiver disable mask (we don't want to affect other PON's). */
rc = bcm_board_fpga_read(BCM_FPGA_REG_TRX_ENABLE, &trx_disable_mask);
BCMOS_CHECK_RETURN(rc, rc, rc);
if (is_enabled == BCMOS_TRUE)
trx_disable_mask &= ~(1 << pon);
else
trx_disable_mask |= (1 << pon);
rc = bcm_board_fpga_write(BCM_FPGA_REG_TRX_ENABLE, trx_disable_mask);
if (rc != BCM_ERR_OK)
return BCM_ERR_INTERNAL;
return bcm_board_host_event_write(trx_disable_mask);
#endif
}
static bcmos_errno bcm_board_config_reset_value(uint32_t rst_bit, bcmos_bool is_on)
{
bcmos_errno rc;
uint32_t reset_values;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
/* Read-modify-write so we can set only the relevant bit to 0 */
rc = bcm_board_fpga_read(BCM_FPGA_REG_RESETS, &reset_values);
BCMOS_CHECK_RETURN(rc, rc, rc);
if (is_on == BCMOS_TRUE)
reset_values |= 1 << rst_bit;
else
reset_values &= ~(1 << rst_bit);
return bcm_board_fpga_write(BCM_FPGA_REG_RESETS, reset_values);
}
static bcmos_errno device_disconnect(void)
{
bcmolt_device_key key = {};
bcmolt_device_cfg dev_cfg;
bcmolt_device_disconnect dev_disconnect;
bcmos_errno rc;
BCMOLT_CFG_INIT(&dev_cfg, device, key);
BCMOLT_CFG_PROP_GET(&dev_cfg, device, state);
rc = bcmolt_cfg_get(0, &dev_cfg.hdr);
BCMOS_CHECK_RETURN(rc, rc, rc);
if (dev_cfg.data.state != BCMOLT_DEVICE_STATE_DISCONNECTED)
{
BCMOLT_OPER_INIT(&dev_disconnect, device, disconnect, key);
return bcmolt_oper_submit(0, &dev_disconnect.hdr);
}
else
return BCM_ERR_OK;
}
bcmos_errno bcm_board_device_reset(void)
{
bcmos_errno rc;
rc = device_disconnect();
BCMOS_CHECK_RETURN(rc, rc, rc);
rc = bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_FALSE);
BCMOS_CHECK_RETURN(rc, rc, rc);
return bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_TRUE);
}
/* Device on keeps the reset bit on active high */
bcmos_errno bcm_board_device_on(void)
{
return bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_TRUE);
}
/* Device off keeps the reset bit on active low */
bcmos_errno bcm_board_device_off(void)
{
bcmos_errno rc;
rc = device_disconnect();
BCMOS_CHECK_RETURN(rc, rc, rc);
return bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_FALSE);
}
/* Katana2 Device on keeps the reset bit on active high */
bcmos_errno bcm_board_kt2_device_on(void)
{
/* take the KT2 out of reset */
return bcm_board_config_reset_value(BCM_RST_BIT_KT2, BCMOS_TRUE);
}
/* Device off keeps the reset bit on active low */
bcmos_errno bcm_board_kt2_device_off(void)
{
return bcm_board_config_reset_value(BCM_RST_BIT_KT2, BCMOS_FALSE);
}
static bcmos_errno bcm_access_dpll(void)
{
bcmos_errno rc;
if (bcm_board_is_svk4())
{
rc = bcm_board_dev_change(I2C_SW1_I2C_ADDR);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW1_I2C_ADDR) failed\n");
rc = bcm_board_switch_write(0x20);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(0x20) failed\n");
}
else
{
rc = bcm_board_dev_change(I2C_SW0_I2C_ADDR);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW0_I2C_ADDR) failed\n");
rc = bcm_board_switch_write(2);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(2) failed\n");
}
rc = bcm_board_dev_change(PON_DPLL_I2C_ADDR);
BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(PON_DPLL_I2C_ADDR) failed \n");
return rc;
}
static int bcm_board_set_page_dpll(uint32_t page)
{
int rcioctl;
maple_i2c_ioctl_param params =
{
.count = 8,
.addr = 1,
.val = page,
};
rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl write change page failed\n");
return BCM_ERR_OK;
}
bcmos_errno bcm_board_read_dpll(uint32_t page, uint32_t reg, uint32_t *val)
{
bcmos_errno rc;
int rcioctl;
maple_i2c_ioctl_param params =
{
.count = 8,
.addr = reg,
.val = 0,
};
rc = bcm_access_dpll();
bcm_board_set_page_dpll(page);
rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_READ, &params);
BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl read failed for maple_i2c_fd\n");
*val = params.val;
return rc;
}
bcmos_errno bcm_board_write_dpll(uint32_t page, uint32_t reg, uint32_t val)
{
bcmos_errno rc;
int rcioctl;
maple_i2c_ioctl_param params =
{
.count = 8,
.addr = reg,
.val = val,
};
rc = bcm_access_dpll();
bcm_board_set_page_dpll(page);
rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl write failed for maple_i2c_fd\n");
return rc;
}
static bcmos_errno bcm_board_load_dpll(dpll_command *commands, int cmdlen)
{
int rcioctl,i;
bcmos_errno rc;
uint8_t previous_page = 0;
maple_i2c_ioctl_param params =
{
.count = 8,
.addr = 0,
.val = 0,
};
rc = bcm_access_dpll();
for (i=0; i < cmdlen; i++)
{
if (commands[i].page != previous_page)
{
bcm_board_set_page_dpll(commands[i].page);
previous_page = commands[i].page;
}
params.addr = commands[i].reg;
params.val = commands[i].data;
rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl write data page failed\n");
}
return rc;
}
bcmos_errno bcm_board_burn_pon_dpll(bcm_dpll_users dpll_dev)
{
switch(dpll_dev)
{
case GPON_DPLL:
return bcm_board_load_dpll(gpon_dpll_table,sizeof(gpon_dpll_table)/sizeof(dpll_command));
break;
case EPON_DPLL:
return bcm_board_load_dpll(epon_dpll_table,sizeof(epon_dpll_table)/sizeof(dpll_command));
break;
case GPON_SYNCE:
return bcm_board_load_dpll(gpon_synce_dpll_table,sizeof(gpon_synce_dpll_table)/sizeof(dpll_command));
break;
default:
break;
}
return BCM_ERR_PARM;
}
bcmos_errno bcm_board_init(void)
{
maple_dev_ctrl_fd = open("/dev/maple_dev_ctrl", O_RDWR);
BCMOS_TRACE_CHECK_RETURN(maple_dev_ctrl_fd < 0, errno, "maple_dev_ctrl_fd open failed\n");
maple_i2c_fd = open("/dev/maple_i2c", O_RDWR);
BCMOS_TRACE_CHECK_RETURN(maple_i2c_fd < 0, errno, "maple_i2c_fd open failed\n");
#ifdef CONFIG_ONU_SIM
/* If the ONU sim is running, always leave all transceivers physically disabled. */
bcmos_errno rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
rc = bcm_board_fpga_write(BCM_FPGA_REG_TRX_ENABLE, 0xFFFFFFFF);
if (rc != BCM_ERR_OK)
return BCM_ERR_INTERNAL;
#endif
return BCM_ERR_OK;
}
bcmos_errno bcm_board_get_board_id(bcm_board_svk_board_id * board_id)
{
bcmos_errno rc;
uint32_t val;
rc = bcm_access_fpga();
BCMOS_CHECK_RETURN(rc, rc, rc);
rc = bcm_board_fpga_read(0x1, &val);
BCMOS_CHECK_RETURN(rc, rc, rc);
*board_id = val & 0x7;
return BCM_ERR_OK;
}
void bcm_board_uninit(void)
{
close(maple_i2c_fd);
maple_i2c_fd = 0;
close(maple_dev_ctrl_fd);
maple_dev_ctrl_fd = -1;
}