[device] accton update driver and sync as5712-54x from 201807. (#2110)
* [platform_accton] Remove dependency on particular version of linux. Signed-off-by: Polly Hsu <polly_hsu@edge-core.com> * [platfrom] as5712-54x: update i2c_client for linux kernel 4.x. Signed-off-by: Polly Hsu <polly_hsu@edge-core.com> * [platform] Update lastest optoe.c from https://github.com/opencomputeproject/oom/blob/master/optoe/optoe.c. Signed-off-by: roy_lee <roy_lee@accton.com> * [platform] rm optoe driver here. For it's inside the kernel. Signed-off-by: roy_lee <roy_lee@accton.com> * [platform] as5712-54x, merge the change of Azure/sonic-buildimage#2002 which is on branch 201807. Signed-off-by: roy_lee <roy_lee@accton.com>
This commit is contained in:
parent
c8e6b15504
commit
593bcb1c1b
@ -2,9 +2,9 @@
|
|||||||
#
|
#
|
||||||
# Platform-specific SFP transceiver interface for SONiC
|
# Platform-specific SFP transceiver interface for SONiC
|
||||||
#
|
#
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import time
|
import time
|
||||||
|
import os
|
||||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError("%s - required module not found" % str(e))
|
raise ImportError("%s - required module not found" % str(e))
|
||||||
@ -21,8 +21,14 @@ class SfpUtil(SfpUtilBase):
|
|||||||
|
|
||||||
BASE_VAL_PATH = "/sys/class/i2c-adapter/i2c-{0}/{1}-0050/"
|
BASE_VAL_PATH = "/sys/class/i2c-adapter/i2c-{0}/{1}-0050/"
|
||||||
BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/"
|
BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/"
|
||||||
BASE_CPLD2_PATH = "/sys/bus/i2c/devices/0-0061/"
|
BASE_CPLD2_PATH = "/sys/bus/i2c/devices/{0}-0061/"
|
||||||
BASE_CPLD3_PATH = "/sys/bus/i2c/devices/0-0062/"
|
BASE_CPLD3_PATH = "/sys/bus/i2c/devices/{0}-0062/"
|
||||||
|
I2C_BUS_ORDER = -1
|
||||||
|
|
||||||
|
#The sidebands of QSFP is different.
|
||||||
|
#present is in-order.
|
||||||
|
#But lp_mode and reset are not.
|
||||||
|
qsfp_sb_map = [1, 3, 5, 2, 4, 6]
|
||||||
|
|
||||||
_port_to_is_present = {}
|
_port_to_is_present = {}
|
||||||
_port_to_lp_mode = {}
|
_port_to_lp_mode = {}
|
||||||
@ -137,19 +143,31 @@ class SfpUtil(SfpUtilBase):
|
|||||||
|
|
||||||
SfpUtilBase.__init__(self)
|
SfpUtilBase.__init__(self)
|
||||||
|
|
||||||
|
#Two i2c buses might get flipped order, check them both.
|
||||||
|
def update_i2c_order(self):
|
||||||
|
if self.I2C_BUS_ORDER < 0:
|
||||||
|
eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom"
|
||||||
|
if os.path.exists(eeprom_path):
|
||||||
|
self.I2C_BUS_ORDER = 0
|
||||||
|
eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom"
|
||||||
|
if os.path.exists(eeprom_path):
|
||||||
|
self.I2C_BUS_ORDER = 1
|
||||||
|
return self.I2C_BUS_ORDER
|
||||||
|
|
||||||
def get_presence(self, port_num):
|
def get_presence(self, port_num):
|
||||||
# Check for invalid port_num
|
# Check for invalid port_num
|
||||||
if port_num < self.port_start or port_num > self.port_end:
|
if port_num < self.port_start or port_num > self.port_end:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
order = self.update_i2c_order()
|
||||||
if port_num < 24:
|
if port_num < 24:
|
||||||
present_path = self.BASE_CPLD2_PATH + "module_present_" + str(self._port_to_i2c_mapping[port_num][0])
|
present_path = self.BASE_CPLD2_PATH.format(order)
|
||||||
else:
|
else:
|
||||||
present_path = self.BASE_CPLD3_PATH + "module_present_" + str(self._port_to_i2c_mapping[port_num][0])
|
present_path = self.BASE_CPLD3_PATH.format(order)
|
||||||
|
|
||||||
|
present_path = present_path + "module_present_" + str(self._port_to_i2c_mapping[port_num][0])
|
||||||
self.__port_to_is_present = present_path
|
self.__port_to_is_present = present_path
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
val_file = open(self.__port_to_is_present)
|
val_file = open(self.__port_to_is_present)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
@ -165,11 +183,21 @@ class SfpUtil(SfpUtilBase):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def qsfp_sb_remap(self, port_num):
|
||||||
|
qsfp_start = self.qsfp_port_start
|
||||||
|
qsfp_index = self._port_to_i2c_mapping[port_num][0] - qsfp_start
|
||||||
|
qsfp_index = self.qsfp_sb_map[qsfp_index-1]
|
||||||
|
return qsfp_start+qsfp_index
|
||||||
|
|
||||||
def get_low_power_mode(self, port_num):
|
def get_low_power_mode(self, port_num):
|
||||||
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
lp_mode_path = self.BASE_CPLD3_PATH + "module_lp_mode_" + str(self._port_to_i2c_mapping[port_num][0])
|
order = self.update_i2c_order()
|
||||||
|
lp_mode_path = self.BASE_CPLD3_PATH.format(order)
|
||||||
|
lp_mode_path = lp_mode_path + "module_lp_mode_"
|
||||||
|
q = self.qsfp_sb_remap(port_num)
|
||||||
|
lp_mode_path = lp_mode_path + str(q)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
val_file = open(lp_mode_path)
|
val_file = open(lp_mode_path)
|
||||||
@ -190,7 +218,11 @@ class SfpUtil(SfpUtilBase):
|
|||||||
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
lp_mode_path = self.BASE_CPLD3_PATH + "module_lp_mode_" + str(self._port_to_i2c_mapping[port_num][0])
|
order = self.update_i2c_order()
|
||||||
|
lp_mode_path = self.BASE_CPLD3_PATH.format(order)
|
||||||
|
lp_mode_path = lp_mode_path + "module_lp_mode_"
|
||||||
|
q = self.qsfp_sb_remap(port_num)
|
||||||
|
lp_mode_path = lp_mode_path + str(q)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
reg_file = open(lp_mode_path, 'r+')
|
reg_file = open(lp_mode_path, 'r+')
|
||||||
@ -212,7 +244,11 @@ class SfpUtil(SfpUtilBase):
|
|||||||
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
mod_rst_path = lp_mode_path = self.BASE_CPLD3_PATH + "module_reset_" + str(self._port_to_i2c_mapping[port_num][0])
|
order = self.update_i2c_order()
|
||||||
|
lp_mode_path = self.BASE_CPLD3_PATH.format(order)
|
||||||
|
mod_rst_path = lp_mode_path + "module_reset_"
|
||||||
|
q = self.qsfp_sb_remap(port_num)
|
||||||
|
mod_rst_path = mod_rst_path + str(q)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
reg_file = open(mod_rst_path, 'r+')
|
reg_file = open(mod_rst_path, 'r+')
|
||||||
@ -220,11 +256,13 @@ class SfpUtil(SfpUtilBase):
|
|||||||
print "Error: unable to open file: %s" % str(e)
|
print "Error: unable to open file: %s" % str(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
reg_value = '1'
|
#toggle reset
|
||||||
|
reg_file.seek(0)
|
||||||
reg_file.write(reg_value)
|
reg_file.write('0')
|
||||||
|
time.sleep(1)
|
||||||
|
reg_file.seek(0)
|
||||||
|
reg_file.write('1')
|
||||||
reg_file.close()
|
reg_file.close()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_transceiver_change_event(self):
|
def get_transceiver_change_event(self):
|
||||||
@ -234,3 +272,4 @@ class SfpUtil(SfpUtilBase):
|
|||||||
on this platform.
|
on this platform.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* I2C multiplexer
|
* An I2C multiplexer dirver for accton as5712 CPLD
|
||||||
*
|
*
|
||||||
* Copyright (C) Brandon Chuang <brandon_chuang@accton.com.tw>
|
* Copyright (C) 2015 Accton Technology Corporation.
|
||||||
|
* Brandon Chuang <brandon_chuang@accton.com.tw>
|
||||||
*
|
*
|
||||||
* This module supports the accton cpld that hold the channel select
|
* This module supports the accton cpld that hold the channel select
|
||||||
* mechanism for other i2c slave devices, such as SFP.
|
* mechanism for other i2c slave devices, such as SFP.
|
||||||
@ -25,9 +26,6 @@
|
|||||||
* License version 2. This program is licensed "as is" without any
|
* License version 2. This program is licensed "as is" without any
|
||||||
* warranty of any kind, whether express or implied.
|
* warranty of any kind, whether express or implied.
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
#define DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
@ -49,12 +47,6 @@
|
|||||||
#define CPLD_CHANNEL_SELECT_REG 0x2
|
#define CPLD_CHANNEL_SELECT_REG 0x2
|
||||||
#define CPLD_DESELECT_CHANNEL 0xFF
|
#define CPLD_DESELECT_CHANNEL 0xFF
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define NUM_OF_ALL_CPLD_CHANS (NUM_OF_CPLD2_CHANS + NUM_OF_CPLD3_CHANS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS
|
|
||||||
|
|
||||||
static LIST_HEAD(cpld_client_list);
|
static LIST_HEAD(cpld_client_list);
|
||||||
static struct mutex list_lock;
|
static struct mutex list_lock;
|
||||||
|
|
||||||
@ -71,24 +63,13 @@ enum cpld_mux_type {
|
|||||||
|
|
||||||
struct as5712_54x_cpld_data {
|
struct as5712_54x_cpld_data {
|
||||||
enum cpld_mux_type type;
|
enum cpld_mux_type type;
|
||||||
struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS];
|
|
||||||
u8 last_chan; /* last register value */
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct i2c_mux_core *muxc;
|
u8 last_chan; /* last register value */
|
||||||
#endif
|
|
||||||
struct device *hwmon_dev;
|
struct device *hwmon_dev;
|
||||||
struct mutex update_lock;
|
struct mutex update_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* The mapping table between mux index and adapter index
|
|
||||||
array index : the mux index
|
|
||||||
the content : adapter index
|
|
||||||
*/
|
|
||||||
static int mux_adap_map[NUM_OF_ALL_CPLD_CHANS];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct chip_desc {
|
struct chip_desc {
|
||||||
u8 nchans;
|
u8 nchans;
|
||||||
u8 deselectChan;
|
u8 deselectChan;
|
||||||
@ -122,8 +103,6 @@ MODULE_DEVICE_TABLE(i2c, as5712_54x_cpld_mux_id);
|
|||||||
#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index
|
#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index
|
||||||
#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index
|
#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index
|
||||||
#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index
|
#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index
|
||||||
#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index
|
|
||||||
#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index
|
|
||||||
|
|
||||||
enum as5712_54x_cpld1_sysfs_attributes {
|
enum as5712_54x_cpld1_sysfs_attributes {
|
||||||
CPLD_VERSION,
|
CPLD_VERSION,
|
||||||
@ -329,18 +308,6 @@ enum as5712_54x_cpld1_sysfs_attributes {
|
|||||||
TRANSCEIVER_TXFAULT_ATTR_ID(46),
|
TRANSCEIVER_TXFAULT_ATTR_ID(46),
|
||||||
TRANSCEIVER_TXFAULT_ATTR_ID(47),
|
TRANSCEIVER_TXFAULT_ATTR_ID(47),
|
||||||
TRANSCEIVER_TXFAULT_ATTR_ID(48),
|
TRANSCEIVER_TXFAULT_ATTR_ID(48),
|
||||||
TRANSCEIVER_LPMODE_ATTR_ID(49),
|
|
||||||
TRANSCEIVER_LPMODE_ATTR_ID(50),
|
|
||||||
TRANSCEIVER_LPMODE_ATTR_ID(51),
|
|
||||||
TRANSCEIVER_LPMODE_ATTR_ID(52),
|
|
||||||
TRANSCEIVER_LPMODE_ATTR_ID(53),
|
|
||||||
TRANSCEIVER_LPMODE_ATTR_ID(54),
|
|
||||||
TRANSCEIVER_RESET_ATTR_ID(49),
|
|
||||||
TRANSCEIVER_RESET_ATTR_ID(50),
|
|
||||||
TRANSCEIVER_RESET_ATTR_ID(51),
|
|
||||||
TRANSCEIVER_RESET_ATTR_ID(52),
|
|
||||||
TRANSCEIVER_RESET_ATTR_ID(53),
|
|
||||||
TRANSCEIVER_RESET_ATTR_ID(54),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* sysfs attributes for hwmon
|
/* sysfs attributes for hwmon
|
||||||
@ -353,10 +320,6 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
|
|||||||
char *buf);
|
char *buf);
|
||||||
static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
|
static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
|
||||||
const char *buf, size_t count);
|
const char *buf, size_t count);
|
||||||
static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da,
|
|
||||||
const char *buf, size_t count);
|
|
||||||
static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
|
|
||||||
const char *buf, size_t count);
|
|
||||||
static ssize_t access(struct device *dev, struct device_attribute *da,
|
static ssize_t access(struct device *dev, struct device_attribute *da,
|
||||||
const char *buf, size_t count);
|
const char *buf, size_t count);
|
||||||
static ssize_t show_version(struct device *dev, struct device_attribute *da,
|
static ssize_t show_version(struct device *dev, struct device_attribute *da,
|
||||||
@ -373,21 +336,11 @@ static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8
|
|||||||
static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \
|
static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \
|
||||||
static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \
|
static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \
|
||||||
static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index)
|
static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index)
|
||||||
|
|
||||||
#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \
|
#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \
|
||||||
&sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \
|
&sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \
|
||||||
&sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \
|
&sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \
|
||||||
&sensor_dev_attr_module_tx_fault_##index.dev_attr.attr
|
&sensor_dev_attr_module_tx_fault_##index.dev_attr.attr
|
||||||
|
|
||||||
#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \
|
|
||||||
static SENSOR_DEVICE_ATTR(module_lp_mode_##index, S_IRUGO | S_IWUSR, show_status, set_lp_mode, MODULE_LPMODE_##index); \
|
|
||||||
static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, show_status, set_mode_reset, MODULE_RESET_##index)
|
|
||||||
|
|
||||||
#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \
|
|
||||||
&sensor_dev_attr_module_lp_mode_##index.dev_attr.attr, \
|
|
||||||
&sensor_dev_attr_module_reset_##index.dev_attr.attr
|
|
||||||
|
|
||||||
|
|
||||||
static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
|
static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
|
||||||
static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS);
|
static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS);
|
||||||
/* transceiver attributes */
|
/* transceiver attributes */
|
||||||
@ -496,12 +449,6 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45);
|
|||||||
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46);
|
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46);
|
||||||
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47);
|
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47);
|
||||||
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48);
|
DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48);
|
||||||
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49);
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50);
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51);
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52);
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53);
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54);
|
|
||||||
|
|
||||||
static struct attribute *as5712_54x_cpld1_attributes[] = {
|
static struct attribute *as5712_54x_cpld1_attributes[] = {
|
||||||
&sensor_dev_attr_version.dev_attr.attr,
|
&sensor_dev_attr_version.dev_attr.attr,
|
||||||
@ -634,12 +581,6 @@ static struct attribute *as5712_54x_cpld3_attributes[] = {
|
|||||||
DECLARE_SFP_TRANSCEIVER_ATTR(46),
|
DECLARE_SFP_TRANSCEIVER_ATTR(46),
|
||||||
DECLARE_SFP_TRANSCEIVER_ATTR(47),
|
DECLARE_SFP_TRANSCEIVER_ATTR(47),
|
||||||
DECLARE_SFP_TRANSCEIVER_ATTR(48),
|
DECLARE_SFP_TRANSCEIVER_ATTR(48),
|
||||||
DECLARE_QSFP_TRANSCEIVER_ATTR(49),
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_ATTR(50),
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_ATTR(51),
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_ATTR(52),
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_ATTR(53),
|
|
||||||
DECLARE_QSFP_TRANSCEIVER_ATTR(54),
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -654,7 +595,8 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
|
|||||||
u8 values[4] = {0};
|
u8 values[4] = {0};
|
||||||
u8 regs[] = {0x6, 0x7, 0x8, 0x14};
|
u8 regs[] = {0x6, 0x7, 0x8, 0x14};
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||||
|
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||||
|
|
||||||
mutex_lock(&data->update_lock);
|
mutex_lock(&data->update_lock);
|
||||||
|
|
||||||
@ -697,7 +639,8 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
|
|||||||
u8 values[3] = {0};
|
u8 values[3] = {0};
|
||||||
u8 regs[] = {0xF, 0x10, 0x11};
|
u8 regs[] = {0xF, 0x10, 0x11};
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||||
|
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||||
|
|
||||||
mutex_lock(&data->update_lock);
|
mutex_lock(&data->update_lock);
|
||||||
|
|
||||||
@ -726,7 +669,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
|
|||||||
{
|
{
|
||||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||||
|
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||||
int status = 0;
|
int status = 0;
|
||||||
u8 reg = 0, mask = 0, revert = 0;
|
u8 reg = 0, mask = 0, revert = 0;
|
||||||
|
|
||||||
@ -851,14 +795,6 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
|
|||||||
reg = 0x11;
|
reg = 0x11;
|
||||||
mask = 0x1 << (attr->index - MODULE_RXLOS_41);
|
mask = 0x1 << (attr->index - MODULE_RXLOS_41);
|
||||||
break;
|
break;
|
||||||
case MODULE_LPMODE_49 ... MODULE_LPMODE_54:
|
|
||||||
reg = 0x16;
|
|
||||||
mask = 0x1 << (attr->index - MODULE_LPMODE_49);
|
|
||||||
break;
|
|
||||||
case MODULE_RESET_49 ... MODULE_RESET_54:
|
|
||||||
reg = 0x15;
|
|
||||||
mask = 0x1 << (attr->index - MODULE_RESET_49);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -886,7 +822,8 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
|
|||||||
{
|
{
|
||||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||||
|
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||||
long disable;
|
long disable;
|
||||||
int status;
|
int status;
|
||||||
u8 reg = 0, mask = 0;
|
u8 reg = 0, mask = 0;
|
||||||
@ -953,111 +890,14 @@ exit:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da,
|
|
||||||
const char *buf, size_t count)
|
|
||||||
{
|
|
||||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
|
||||||
long on;
|
|
||||||
int status= -ENOENT;
|
|
||||||
u8 reg = 0x16, mask = 0;
|
|
||||||
|
|
||||||
if(attr->index < MODULE_LPMODE_49 || attr->index > MODULE_LPMODE_54)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = kstrtol(buf, 10, &on);
|
|
||||||
if (status) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read current status */
|
|
||||||
mutex_lock(&data->update_lock);
|
|
||||||
status = as5712_54x_cpld_read_internal(client, reg);
|
|
||||||
if (unlikely(status < 0)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask = 0x1 << (attr->index - MODULE_LPMODE_49);
|
|
||||||
|
|
||||||
/* Update lp_mode status */
|
|
||||||
if (on) {
|
|
||||||
status |= mask;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
status &= ~mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = as5712_54x_cpld_write_internal(client, reg, status);
|
|
||||||
if (unlikely(status < 0)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&data->update_lock);
|
|
||||||
return count;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
mutex_unlock(&data->update_lock);
|
|
||||||
return status;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da,
|
|
||||||
const char *buf, size_t count)
|
|
||||||
{
|
|
||||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
|
||||||
long on;
|
|
||||||
int status= -ENOENT;
|
|
||||||
u8 reg = 0x15, mask = 0;
|
|
||||||
|
|
||||||
if(attr->index < MODULE_RESET_49 || attr->index > MODULE_RESET_54)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = kstrtol(buf, 10, &on);
|
|
||||||
if (status) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read current status */
|
|
||||||
mutex_lock(&data->update_lock);
|
|
||||||
status = as5712_54x_cpld_read_internal(client, reg);
|
|
||||||
if (unlikely(status < 0)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask = 0x1 << (attr->index - MODULE_RESET_49);
|
|
||||||
|
|
||||||
/* Update tx_disable status */
|
|
||||||
if (on) {
|
|
||||||
status |= mask;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
status &= ~mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = as5712_54x_cpld_write_internal(client, reg, status);
|
|
||||||
if (unlikely(status < 0)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&data->update_lock);
|
|
||||||
return count;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
mutex_unlock(&data->update_lock);
|
|
||||||
return status;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t access(struct device *dev, struct device_attribute *da,
|
static ssize_t access(struct device *dev, struct device_attribute *da,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||||
|
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||||
int status;
|
int status;
|
||||||
u32 addr, val;
|
u32 addr, val;
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
|
||||||
|
|
||||||
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
|
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1111,10 +951,8 @@ static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
|
||||||
static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
|
static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
|
||||||
u32 chan)
|
u32 chan)
|
||||||
{
|
{
|
||||||
@ -1122,8 +960,8 @@ static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
|
|||||||
struct i2c_client *client = data->client;
|
struct i2c_client *client = data->client;
|
||||||
u8 regval;
|
u8 regval;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
regval = chan;
|
|
||||||
|
|
||||||
|
regval = chan;
|
||||||
/* Only select the channel if its different from the last channel */
|
/* Only select the channel if its different from the last channel */
|
||||||
if (data->last_chan != regval) {
|
if (data->last_chan != regval) {
|
||||||
ret = as5712_54x_cpld_mux_reg_write(muxc->parent, client, regval);
|
ret = as5712_54x_cpld_mux_reg_write(muxc->parent, client, regval);
|
||||||
@ -1144,37 +982,6 @@ static int as5712_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc,
|
|||||||
|
|
||||||
return as5712_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
|
return as5712_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
|
||||||
static int as5712_54x_cpld_mux_select_chan(struct i2c_adapter *adap,
|
|
||||||
void *client, u32 chan)
|
|
||||||
{
|
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
|
||||||
u8 regval;
|
|
||||||
int ret = 0;
|
|
||||||
regval = chan;
|
|
||||||
|
|
||||||
/* Only select the channel if its different from the last channel */
|
|
||||||
if (data->last_chan != regval) {
|
|
||||||
ret = as5712_54x_cpld_mux_reg_write(adap, client, regval);
|
|
||||||
data->last_chan = regval;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int as5712_54x_cpld_mux_deselect_mux(struct i2c_adapter *adap,
|
|
||||||
void *client, u32 chan)
|
|
||||||
{
|
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
|
||||||
|
|
||||||
/* Deselect active channel */
|
|
||||||
data->last_chan = chips[data->type].deselectChan;
|
|
||||||
|
|
||||||
return as5712_54x_cpld_mux_reg_write(adap, client, data->last_chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)*/
|
|
||||||
|
|
||||||
static void as5712_54x_cpld_add_client(struct i2c_client *client)
|
static void as5712_54x_cpld_add_client(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
@ -1200,8 +1007,7 @@ static void as5712_54x_cpld_remove_client(struct i2c_client *client)
|
|||||||
|
|
||||||
mutex_lock(&list_lock);
|
mutex_lock(&list_lock);
|
||||||
|
|
||||||
list_for_each(list_node, &cpld_client_list)
|
list_for_each(list_node, &cpld_client_list) {
|
||||||
{
|
|
||||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||||
|
|
||||||
if (cpld_node->client == client) {
|
if (cpld_node->client == client) {
|
||||||
@ -1239,72 +1045,45 @@ static int as5712_54x_cpld_mux_probe(struct i2c_client *client,
|
|||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
int num, force, class;
|
||||||
int force, class;
|
|
||||||
struct i2c_mux_core *muxc;
|
struct i2c_mux_core *muxc;
|
||||||
#endif
|
|
||||||
|
|
||||||
int chan=0;
|
|
||||||
struct as5712_54x_cpld_data *data;
|
struct as5712_54x_cpld_data *data;
|
||||||
int ret = -ENODEV;
|
int ret = 0;
|
||||||
const struct attribute_group *group = NULL;
|
const struct attribute_group *group = NULL;
|
||||||
|
|
||||||
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
|
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
|
||||||
goto exit;
|
return -ENODEV;
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
|
||||||
muxc = i2c_mux_alloc(adap, &client->dev,
|
muxc = i2c_mux_alloc(adap, &client->dev,
|
||||||
chips[id->driver_data].nchans,
|
chips[id->driver_data].nchans, sizeof(*data), 0,
|
||||||
sizeof(*data), 0,
|
as5712_54x_cpld_mux_select_chan, as5712_54x_cpld_mux_deselect_mux);
|
||||||
accton_i2c_cpld_mux_select_chan,
|
|
||||||
accton_i2c_cpld_mux_deselect_mux);
|
|
||||||
if (!muxc)
|
if (!muxc)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
i2c_set_clientdata(client, muxc);
|
||||||
data = i2c_mux_priv(muxc);
|
data = i2c_mux_priv(muxc);
|
||||||
i2c_set_clientdata(client, data);
|
|
||||||
data->muxc = muxc;
|
|
||||||
data->client = client;
|
data->client = client;
|
||||||
#else
|
|
||||||
|
|
||||||
data = kzalloc(sizeof(struct as5712_54x_cpld_data), GFP_KERNEL);
|
|
||||||
if (!data) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
i2c_set_clientdata(client, data);
|
|
||||||
mutex_init(&data->update_lock);
|
|
||||||
#endif
|
|
||||||
data->type = id->driver_data;
|
data->type = id->driver_data;
|
||||||
if (data->type == as5712_54x_cpld2 || data->type == as5712_54x_cpld3) {
|
|
||||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||||
|
mutex_init(&data->update_lock);
|
||||||
|
|
||||||
/* Now create an adapter for each channel */
|
/* Now create an adapter for each channel */
|
||||||
for (chan = 0; chan < chips[data->type].nchans; chan++) {
|
for (num = 0; num < chips[data->type].nchans; num++) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
|
||||||
force = 0; /* dynamic adap number */
|
force = 0; /* dynamic adap number */
|
||||||
class = 0; /* no class by default */
|
class = 0; /* no class by default */
|
||||||
ret = i2c_mux_add_adapter(muxc, force, chan, class);
|
|
||||||
if (ret)
|
ret = i2c_mux_add_adapter(muxc, force, num, class);
|
||||||
#else
|
|
||||||
data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan,
|
if (ret) {
|
||||||
0,
|
dev_err(&client->dev,
|
||||||
as5712_54x_cpld_mux_select_chan,
|
"failed to register multiplexed adapter"
|
||||||
as5712_54x_cpld_mux_deselect_mux);
|
" %d as bus %d\n", num, force);
|
||||||
if (data->virt_adaps[chan] == NULL)
|
goto add_mux_failed;
|
||||||
#endif
|
|
||||||
{
|
|
||||||
ret = -ENODEV;
|
|
||||||
dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
|
|
||||||
goto exit_mux_register;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
|
|
||||||
chan, client->name);
|
|
||||||
}
|
|
||||||
/* Register sysfs hooks */
|
/* Register sysfs hooks */
|
||||||
switch (data->type)
|
switch (data->type) {
|
||||||
{
|
|
||||||
case as5712_54x_cpld1:
|
case as5712_54x_cpld1:
|
||||||
group = &as5712_54x_cpld1_group;
|
group = &as5712_54x_cpld1_group;
|
||||||
break;
|
break;
|
||||||
@ -1313,45 +1092,44 @@ static int as5712_54x_cpld_mux_probe(struct i2c_client *client,
|
|||||||
break;
|
break;
|
||||||
case as5712_54x_cpld3:
|
case as5712_54x_cpld3:
|
||||||
group = &as5712_54x_cpld3_group;
|
group = &as5712_54x_cpld3_group;
|
||||||
|
|
||||||
|
/* Bring QSFPs out of reset */
|
||||||
|
as5712_54x_cpld_write_internal(client, 0x15, 0x3F);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (group) {
|
if (group) {
|
||||||
ret = sysfs_create_group(&client->dev.kobj, group);
|
ret = sysfs_create_group(&client->dev.kobj, group);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
goto exit_mux_register;
|
goto add_mux_failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chips[data->type].nchans) {
|
||||||
|
dev_info(&client->dev,
|
||||||
|
"registered %d multiplexed busses for I2C %s\n",
|
||||||
|
num, client->name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dev_info(&client->dev,
|
||||||
|
"device %s registered\n", client->name);
|
||||||
|
}
|
||||||
|
|
||||||
as5712_54x_cpld_add_client(client);
|
as5712_54x_cpld_add_client(client);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit_mux_register:
|
add_mux_failed:
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
|
||||||
i2c_mux_del_adapters(muxc);
|
i2c_mux_del_adapters(muxc);
|
||||||
#else
|
|
||||||
for (chan--; chan >= 0; chan--) {
|
|
||||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
kfree(data);
|
|
||||||
exit:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int as5712_54x_cpld_mux_remove(struct i2c_client *client)
|
static int as5712_54x_cpld_mux_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||||
struct i2c_mux_core *muxc = data->muxc;
|
|
||||||
|
|
||||||
i2c_mux_del_adapters(muxc);
|
|
||||||
#else
|
|
||||||
const struct chip_desc *chip = &chips[data->type];
|
|
||||||
int chan;
|
|
||||||
const struct attribute_group *group = NULL;
|
const struct attribute_group *group = NULL;
|
||||||
|
|
||||||
as5712_54x_cpld_remove_client(client);
|
as5712_54x_cpld_remove_client(client);
|
||||||
@ -1375,14 +1153,7 @@ static int as5712_54x_cpld_mux_remove(struct i2c_client *client)
|
|||||||
sysfs_remove_group(&client->dev.kobj, group);
|
sysfs_remove_group(&client->dev.kobj, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (chan = 0; chan < chip->nchans; ++chan) {
|
i2c_mux_del_adapters(muxc);
|
||||||
if (data->virt_adaps[chan]) {
|
|
||||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
|
||||||
data->virt_adaps[chan] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
kfree(data);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1431,8 +1202,7 @@ int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg)
|
|||||||
|
|
||||||
mutex_lock(&list_lock);
|
mutex_lock(&list_lock);
|
||||||
|
|
||||||
list_for_each(list_node, &cpld_client_list)
|
list_for_each(list_node, &cpld_client_list) {
|
||||||
{
|
|
||||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||||
|
|
||||||
if (cpld_node->client->addr == cpld_addr) {
|
if (cpld_node->client->addr == cpld_addr) {
|
||||||
@ -1455,8 +1225,7 @@ int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
|
|||||||
|
|
||||||
mutex_lock(&list_lock);
|
mutex_lock(&list_lock);
|
||||||
|
|
||||||
list_for_each(list_node, &cpld_client_list)
|
list_for_each(list_node, &cpld_client_list) {
|
||||||
{
|
|
||||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||||
|
|
||||||
if (cpld_node->client->addr == cpld_addr) {
|
if (cpld_node->client->addr == cpld_addr) {
|
||||||
@ -1471,22 +1240,6 @@ int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(as5712_54x_cpld_write);
|
EXPORT_SYMBOL(as5712_54x_cpld_write);
|
||||||
|
|
||||||
#if 0
|
|
||||||
int accton_i2c_cpld_mux_get_index(int adap_index)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_OF_ALL_CPLD_CHANS; i++) {
|
|
||||||
if (mux_adap_map[i] == adap_index) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(accton_i2c_cpld_mux_get_index);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct i2c_driver as5712_54x_cpld_mux_driver = {
|
static struct i2c_driver as5712_54x_cpld_mux_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "as5712_54x_cpld",
|
.name = "as5712_54x_cpld",
|
||||||
@ -1509,7 +1262,7 @@ static void __exit as5712_54x_cpld_mux_exit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
|
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
|
||||||
MODULE_DESCRIPTION("Accton I2C CPLD mux driver");
|
MODULE_DESCRIPTION("Accton as5712-54x CPLD driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
module_init(as5712_54x_cpld_mux_init);
|
module_init(as5712_54x_cpld_mux_init);
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Usage: %(scriptName)s [options] command object
|
Usage: %(scriptName)s [options] command object
|
||||||
|
|
||||||
@ -36,6 +35,7 @@ import sys, getopt
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
import pickle
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
PROJECT_NAME = 'as5712_54x'
|
PROJECT_NAME = 'as5712_54x'
|
||||||
@ -80,12 +80,19 @@ i2c_nodes = {
|
|||||||
'psu': ['psu_present ', 'psu_power_good'] ,
|
'psu': ['psu_present ', 'psu_power_good'] ,
|
||||||
'sfp': ['sfp_is_present ', 'sfp_tx_disable']}
|
'sfp': ['sfp_is_present ', 'sfp_tx_disable']}
|
||||||
|
|
||||||
|
QSFP_START = 48
|
||||||
|
I2C_BUS_ORDER = -1
|
||||||
|
|
||||||
sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10,
|
sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||||
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||||
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
||||||
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||||
41, 42, 43, 44, 45, 46, 47, 48, 49,
|
41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||||
50, 52, 54, 51, 53, 55]
|
50, 52, 54, 51, 53, 55]
|
||||||
|
|
||||||
|
port_cpld_path = [ "/sys/bus/i2c/devices/0-0061/"
|
||||||
|
,'/sys/bus/i2c/devices/0-0062/']
|
||||||
|
|
||||||
mknod =[
|
mknod =[
|
||||||
'echo as5712_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device',
|
'echo as5712_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device',
|
||||||
'echo as5712_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-0/new_device',
|
'echo as5712_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-0/new_device',
|
||||||
@ -131,7 +138,7 @@ mknod2 =[
|
|||||||
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device',
|
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device',
|
||||||
|
|
||||||
#EERPOM
|
#EERPOM
|
||||||
'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device',
|
'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device',
|
||||||
]
|
]
|
||||||
|
|
||||||
FORCE = 0
|
FORCE = 0
|
||||||
@ -207,7 +214,7 @@ def show_set_help():
|
|||||||
print cmd +" [led|sfp|fan]"
|
print cmd +" [led|sfp|fan]"
|
||||||
print " use \""+ cmd + " led 0-4 \" to set led color"
|
print " use \""+ cmd + " led 0-4 \" to set led color"
|
||||||
print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
|
print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
|
||||||
print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable"
|
print " use \""+ cmd + " sfp 1-48 {0|1}\" to set sfp# tx_disable"
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def show_eeprom_help():
|
def show_eeprom_help():
|
||||||
@ -289,10 +296,28 @@ def i2c_order_check():
|
|||||||
status, output = log_os_system(tmp, 0)
|
status, output = log_os_system(tmp, 0)
|
||||||
return order
|
return order
|
||||||
|
|
||||||
def device_install():
|
def update_i2c_order():
|
||||||
global FORCE
|
global I2C_BUS_ORDER
|
||||||
|
|
||||||
order = i2c_order_check()
|
order = i2c_order_check()
|
||||||
|
pickle.dump(order, open("/tmp/accton_util.p", "wb")) # save it
|
||||||
|
I2C_BUS_ORDER = order
|
||||||
|
print "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), I2C_BUS_ORDER)
|
||||||
|
|
||||||
|
def get_i2c_order():
|
||||||
|
global I2C_BUS_ORDER
|
||||||
|
if I2C_BUS_ORDER < 0:
|
||||||
|
if os.path.exists("/tmp/accton_util.p"):
|
||||||
|
I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb"))
|
||||||
|
else:
|
||||||
|
update_i2c_order()
|
||||||
|
|
||||||
|
def device_install():
|
||||||
|
global FORCE
|
||||||
|
global I2C_BUS_ORDER
|
||||||
|
|
||||||
|
update_i2c_order()
|
||||||
|
order = I2C_BUS_ORDER
|
||||||
# if 0x76 is not exist @i2c-0, use reversed bus order
|
# if 0x76 is not exist @i2c-0, use reversed bus order
|
||||||
if order:
|
if order:
|
||||||
for i in range(0,len(mknod2)):
|
for i in range(0,len(mknod2)):
|
||||||
@ -318,6 +343,9 @@ def device_install():
|
|||||||
return status
|
return status
|
||||||
|
|
||||||
for i in range(0,len(sfp_map)):
|
for i in range(0,len(sfp_map)):
|
||||||
|
if i < QSFP_START:
|
||||||
|
status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
|
||||||
|
else:
|
||||||
status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
|
status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
|
||||||
if status:
|
if status:
|
||||||
print output
|
print output
|
||||||
@ -333,13 +361,10 @@ def device_install():
|
|||||||
|
|
||||||
def device_uninstall():
|
def device_uninstall():
|
||||||
global FORCE
|
global FORCE
|
||||||
|
global I2C_BUS_ORDER
|
||||||
|
|
||||||
status, output =log_os_system("ls /sys/bus/i2c/devices/0-0070", 0)
|
get_i2c_order()
|
||||||
if status==0:
|
order = I2C_BUS_ORDER
|
||||||
I2C_ORDER=1
|
|
||||||
else:
|
|
||||||
I2C_ORDER=0
|
|
||||||
|
|
||||||
for i in range(0,len(sfp_map)):
|
for i in range(0,len(sfp_map)):
|
||||||
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
|
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
|
||||||
status, output =log_os_system("echo 0x50 > "+ target, 1)
|
status, output =log_os_system("echo 0x50 > "+ target, 1)
|
||||||
@ -348,7 +373,7 @@ def device_uninstall():
|
|||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
return status
|
||||||
|
|
||||||
if I2C_ORDER==0:
|
if order == 0:
|
||||||
nodelist = mknod
|
nodelist = mknod
|
||||||
else:
|
else:
|
||||||
nodelist = mknod2
|
nodelist = mknod2
|
||||||
@ -476,7 +501,7 @@ def show_eeprom(index):
|
|||||||
if len(ALL_DEVICE)==0:
|
if len(ALL_DEVICE)==0:
|
||||||
devices_info()
|
devices_info()
|
||||||
node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
|
node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
|
||||||
node = node.replace(node.split("/")[-1], 'sfp_eeprom')
|
node = node.replace(node.split("/")[-1], 'eeprom')
|
||||||
# check if got hexdump command in current environment
|
# check if got hexdump command in current environment
|
||||||
ret, log = log_os_system("which hexdump", 0)
|
ret, log = log_os_system("which hexdump", 0)
|
||||||
ret, log2 = log_os_system("which busybox hexdump", 0)
|
ret, log2 = log_os_system("which busybox hexdump", 0)
|
||||||
@ -498,6 +523,43 @@ def show_eeprom(index):
|
|||||||
print "**********device no found**********"
|
print "**********device no found**********"
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_cpld_path(index):
|
||||||
|
global I2C_BUS_ORDER
|
||||||
|
|
||||||
|
if I2C_BUS_ORDER < 0:
|
||||||
|
get_i2c_order()
|
||||||
|
|
||||||
|
if I2C_BUS_ORDER !=0 :
|
||||||
|
return port_cpld_path[index].replace("0-", "1-")
|
||||||
|
else:
|
||||||
|
return port_cpld_path[index]
|
||||||
|
|
||||||
|
def cpld_path_of_port(port_index):
|
||||||
|
if port_index < 1 and port_index > DEVICE_NO['sfp']:
|
||||||
|
return None
|
||||||
|
if port_index < 25:
|
||||||
|
return get_cpld_path(0)
|
||||||
|
else:
|
||||||
|
return get_cpld_path(1)
|
||||||
|
|
||||||
|
def get_path_sfp_tx_dis(port_index):
|
||||||
|
cpld_p = cpld_path_of_port(port_index)
|
||||||
|
if cpld_p == None:
|
||||||
|
return False, ''
|
||||||
|
else:
|
||||||
|
dev = cpld_p+"module_tx_disable_"+str(port_index)
|
||||||
|
return True, dev
|
||||||
|
|
||||||
|
def get_path_sfp_presence(port_index):
|
||||||
|
cpld_p = cpld_path_of_port(port_index)
|
||||||
|
if cpld_p == None:
|
||||||
|
return False, ''
|
||||||
|
else:
|
||||||
|
dev = cpld_p+"module_present_"+str(port_index)
|
||||||
|
return True, dev
|
||||||
|
|
||||||
|
|
||||||
def set_device(args):
|
def set_device(args):
|
||||||
global DEVICE_NO
|
global DEVICE_NO
|
||||||
global ALL_DEVICE
|
global ALL_DEVICE
|
||||||
@ -535,7 +597,9 @@ def set_device(args):
|
|||||||
print ("Current fan duty: " + args[1] +"%")
|
print ("Current fan duty: " + args[1] +"%")
|
||||||
return ret
|
return ret
|
||||||
elif args[0]=='sfp':
|
elif args[0]=='sfp':
|
||||||
if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
|
#if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
|
||||||
|
#There no tx_disable for QSFP port
|
||||||
|
if int(args[1]) > QSFP_START or int(args[1])==0:
|
||||||
show_set_help()
|
show_set_help()
|
||||||
return
|
return
|
||||||
if len(args)<2:
|
if len(args)<2:
|
||||||
@ -546,14 +610,13 @@ def set_device(args):
|
|||||||
show_set_help()
|
show_set_help()
|
||||||
return
|
return
|
||||||
|
|
||||||
#print ALL_DEVICE[args[0]]
|
port_index = int(args[1])
|
||||||
for i in range(0,len(ALL_DEVICE[args[0]])):
|
ret, dev = get_path_sfp_tx_dis(port_index)
|
||||||
for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
|
if ret == False:
|
||||||
if j.find('tx_disable')!= -1:
|
return False
|
||||||
ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
|
else:
|
||||||
if ret:
|
ret, log = log_os_system("echo "+args[2]+" >"+ dev, 1)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
#get digits inside a string.
|
#get digits inside a string.
|
||||||
@ -562,6 +625,16 @@ def get_value(input):
|
|||||||
digit = re.findall('\d+', input)
|
digit = re.findall('\d+', input)
|
||||||
return int(digit[0])
|
return int(digit[0])
|
||||||
|
|
||||||
|
def print_1_device_traversal(i, j, k):
|
||||||
|
ret, log = log_os_system("cat "+k, 0)
|
||||||
|
func = k.split("/")[-1].strip()
|
||||||
|
func = re.sub(j+'_','',func,1)
|
||||||
|
func = re.sub(i.lower()+'_','',func,1)
|
||||||
|
if ret==0:
|
||||||
|
return func+"="+log+" "
|
||||||
|
else:
|
||||||
|
return func+"="+"X"+" "
|
||||||
|
|
||||||
def device_traversal():
|
def device_traversal():
|
||||||
if system_ready()==False:
|
if system_ready()==False:
|
||||||
print("System's not ready.")
|
print("System's not ready.")
|
||||||
@ -577,15 +650,26 @@ def device_traversal():
|
|||||||
|
|
||||||
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
|
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
|
||||||
print " "+j+":",
|
print " "+j+":",
|
||||||
|
if i == 'sfp':
|
||||||
|
port_index = int(filter(str.isdigit, j))
|
||||||
for k in (ALL_DEVICE[i][j]):
|
for k in (ALL_DEVICE[i][j]):
|
||||||
ret, log = log_os_system("cat "+k, 0)
|
if k.find('tx_disable')!= -1:
|
||||||
func = k.split("/")[-1].strip()
|
ret, k = get_path_sfp_tx_dis(port_index)
|
||||||
func = re.sub(j+'_','',func,1)
|
if ret == False:
|
||||||
func = re.sub(i.lower()+'_','',func,1)
|
continue
|
||||||
if ret==0:
|
log = print_1_device_traversal(i, j, k)
|
||||||
print func+"="+log+" ",
|
print log,
|
||||||
|
if k.find('present')!= -1:
|
||||||
|
ret, k = get_path_sfp_presence(port_index)
|
||||||
|
if ret == False:
|
||||||
|
continue
|
||||||
|
log = print_1_device_traversal(i, j, k)
|
||||||
|
print log,
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print func+"="+"X"+" ",
|
for k in (ALL_DEVICE[i][j]):
|
||||||
|
log = print_1_device_traversal(i, j, k)
|
||||||
|
print log,
|
||||||
print
|
print
|
||||||
print("----------------------------------------------------------------")
|
print("----------------------------------------------------------------")
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,40 +2,33 @@ Source: sonic-accton-platform-modules
|
|||||||
Section: main
|
Section: main
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: Accton network <roy_lee@accton.com>, Accton Network <polly_hsu@accton.com>
|
Maintainer: Accton network <roy_lee@accton.com>, Accton Network <polly_hsu@accton.com>
|
||||||
Build-Depends: debhelper (>= 8.0.0), bzip2
|
Build-Depends: debhelper (>= 9), bzip2
|
||||||
Standards-Version: 3.9.3
|
Standards-Version: 3.9.3
|
||||||
|
|
||||||
Package: sonic-platform-accton-as7712-32x
|
Package: sonic-platform-accton-as7712-32x
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: linux-image-3.16.0-5-amd64
|
|
||||||
Description: kernel modules for platform devices such as fan, led, sfp
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
|
||||||
Package: sonic-platform-accton-as5712-54x
|
Package: sonic-platform-accton-as5712-54x
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: linux-image-3.16.0-5-amd64
|
|
||||||
Description: kernel modules for platform devices such as fan, led, sfp
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
|
||||||
Package: sonic-platform-accton-as7816-64x
|
Package: sonic-platform-accton-as7816-64x
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: linux-image-3.16.0-5-amd64
|
|
||||||
Description: kernel modules for platform devices such as fan, led, sfp
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
|
||||||
Package: sonic-platform-accton-as7716-32x
|
Package: sonic-platform-accton-as7716-32x
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: linux-image-3.16.0-5-amd64
|
|
||||||
Description: kernel modules for platform devices such as fan, led, sfp
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
|
||||||
Package: sonic-platform-accton-as7716-32xb
|
Package: sonic-platform-accton-as7716-32xb
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: linux-image-3.16.0-5-amd64
|
|
||||||
Description: kernel modules for platform devices such as fan, led, sfp
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
|
||||||
Package: sonic-platform-accton-as7312-54x
|
Package: sonic-platform-accton-as7312-54x
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: linux-image-3.16.0-5-amd64
|
|
||||||
Description: kernel modules for platform devices such as fan, led, sfp
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
|
||||||
Package: sonic-platform-accton-as7326-56x
|
Package: sonic-platform-accton-as7326-56x
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: linux-image-3.16.0-5-amd64
|
|
||||||
Description: kernel modules for platform devices such as fan, led, sfp
|
Description: kernel modules for platform devices such as fan, led, sfp
|
||||||
|
Reference in New Issue
Block a user