sonic-buildimage/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.c

584 lines
19 KiB
C
Raw Normal View History

/* An hwmon driver for Cameo esc602-32Q Innovium i2c Module */
#pragma GCC diagnostic ignored "-Wformat-zero-length"
#include "x86-64-cameo-esc602-32q.h"
#include "x86-64-cameo-esc602-32q-common.h"
#include "x86-64-cameo-esc602-32q-qsfp.h"
/* i2c_client Declaration */
extern struct i2c_client *Cameo_CPLD_31_client; //0x31 for Port 01-16
extern struct i2c_client *Cameo_CPLD_32_client; //0x32 for Port 17-32
/* end of i2c_client Declaration */
/* extern i2c_function */
/* end of extern i2c_function */
/* implement i2c_function */
ssize_t qsfp_low_power_all_get(struct device *dev, struct device_attribute *da, char *buf)
{
u8 status = -EPERM;
u32 result = -EPERM;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
if (attr->index == QSFP_LOW_POWER_ALL)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_REAR_LOW_POWER_REG); //25-32
result = status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_LOW_POWER_REG); //17-24
result = (result << 8) | status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_REAR_LOW_POWER_REG); //9-16
result = (result << 8) | status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_LOW_POWER_REG); //1-8
result = (result << 8) | status;
sprintf(buf, "%s0x%x\n", buf, result);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
{
int value = 0x0;
int result = 0;
int input = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client);
struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client);
mutex_lock(&Cameo_CPLD_31_data->update_lock);
mutex_lock(&Cameo_CPLD_32_data->update_lock);
if (attr->index == QSFP_LOW_POWER_ALL)
{
input = simple_strtol(buf, NULL, 10);
if (input == ENABLE)
{
value = 0xff;
}
else if(input == DISABLE)
{
value = 0x00;
}
else
{
printk(KERN_ALERT "qsfp_low_power_all_set wrong value\n");
return count;
}
result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_LOW_POWER_REG, value);
result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_REAR_LOW_POWER_REG, value);
result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_LOW_POWER_REG, value);
result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_REAR_LOW_POWER_REG, value);
if(result != 0)
{
printk(KERN_ALERT "qsfp_low_power_all_set FAILED\n");
return count;
}
}
mutex_unlock(&Cameo_CPLD_31_data->update_lock);
mutex_unlock(&Cameo_CPLD_32_data->update_lock);
return count;
}
ssize_t qsfp_low_power_get(struct device *dev, struct device_attribute *da, char *buf)
{
int status = -EPERM;
int port_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
port_index = attr->index;
sprintf(buf, "");
if (port_index >= 1 && port_index <= 16)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_low_power_regs[port_index][0]);
}
else if (port_index >= 17 && port_index <= 32)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_low_power_regs[port_index][0]);
}
if (status & qsfp_low_power_regs[port_index][1])
{
sprintf(buf, "%s%d\n", buf, ENABLE);
}
else
{
sprintf(buf, "%s%d\n", buf, DISABLE);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
{
int status = -EPERM;
int result = 0;
int input = 0;
int port_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client);
struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client);
struct i2c_client *target_client = NULL;
port_index = attr->index;
input = simple_strtol(buf, NULL, 10);
mutex_lock(&Cameo_CPLD_31_data->update_lock);
mutex_lock(&Cameo_CPLD_32_data->update_lock);
if (port_index >= 1 && port_index <= 16)
{
target_client = Cameo_CPLD_31_client;
}
else if (port_index >= 17 && port_index <= 32)
{
target_client = Cameo_CPLD_32_client;
}
status = i2c_smbus_read_byte_data(target_client, qsfp_low_power_regs[port_index][0]);
if( input == ENABLE)
{
status |= qsfp_low_power_regs[port_index][1];
result = i2c_smbus_write_byte_data(target_client, qsfp_low_power_regs[port_index][0], status);
if (result < 0)
{
printk(KERN_ALERT "ERROR: qsfp_low_power_set ON FAILED!\n");
}
}
else if( input == DISABLE)
{
status &= ~(qsfp_low_power_regs[port_index][1]);
result = i2c_smbus_write_byte_data(target_client, qsfp_low_power_regs[port_index][0], status);
if (result < 0)
{
printk(KERN_ALERT "ERROR: qsfp_low_power_set OFF FAILED!\n");
}
}
else
{
printk(KERN_ALERT "ERROR: qsfp_low_power_set WRONG VALUE\n");
}
mutex_unlock(&Cameo_CPLD_31_data->update_lock);
mutex_unlock(&Cameo_CPLD_32_data->update_lock);
return count;
}
ssize_t qsfp_reset_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
{
int value = 0x0;
int result = 0;
int input = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client);
struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client);
mutex_lock(&Cameo_CPLD_31_data->update_lock);
mutex_lock(&Cameo_CPLD_32_data->update_lock);
if (attr->index == QSFP_RESET_ALL)
{
input = simple_strtol(buf, NULL, 10);
if (input == QSFP_RESET)
{
value = 0x00;
}
else
{
printk(KERN_ALERT "qsfp_reset_all_set wrong value\n");
return count;
}
result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_RESET_REG, value);
result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_REAR_RESET_REG, value);
result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_RESET_REG, value);
result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_REAR_RESET_REG, value);
if(result != 0)
{
printk(KERN_ALERT "qsfp_reset_all_set FAILED\n");
return count;
}
}
mutex_unlock(&Cameo_CPLD_31_data->update_lock);
mutex_unlock(&Cameo_CPLD_32_data->update_lock);
return count;
}
ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
{
int status = -EPERM;
int result = 0;
int input = 0;
int port_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client);
struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client);
struct i2c_client *target_client = NULL;
port_index = attr->index;
input = simple_strtol(buf, NULL, 10);
mutex_lock(&Cameo_CPLD_31_data->update_lock);
mutex_lock(&Cameo_CPLD_32_data->update_lock);
if (port_index >= 1 && port_index <= 16)
{
target_client = Cameo_CPLD_31_client;
}
else if (port_index >= 17 && port_index <= 32)
{
target_client = Cameo_CPLD_32_client;
}
status = i2c_smbus_read_byte_data(target_client, qsfp_reset_regs[port_index][0]);
if( input == QSFP_RESET)
{
status |= qsfp_reset_regs[port_index][1];
result = i2c_smbus_write_byte_data(target_client, qsfp_reset_regs[port_index][0], status);
if (result < 0)
{
printk(KERN_ALERT "ERROR: qsfp_reset_set FAILED!\n");
}
}
else
{
printk(KERN_ALERT "ERROR: qsfp_reset_set WRONG VALUE\n");
}
mutex_unlock(&Cameo_CPLD_31_data->update_lock);
mutex_unlock(&Cameo_CPLD_32_data->update_lock);
return count;
}
ssize_t qsfp_present_all_get(struct device *dev, struct device_attribute *da, char *buf)
{
u8 status = -EPERM;
u32 result = -EPERM;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
if (attr->index == QSFP_PRESENT_ALL)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_REAR_PRESENT_REG); //25-32
result = status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_PRESENT_REG); //17-24
result = (result << 8) | status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_REAR_PRESENT_REG); //9-16
result = (result << 8) | status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_PRESENT_REG); //1-8
result = (result << 8) | status;
result = ~(result);
sprintf(buf, "%s0x%x\n", buf, result);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_present_get(struct device *dev, struct device_attribute *da, char *buf)
{
int status = -EPERM;
int port_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
port_index = attr->index;
sprintf(buf, "");
if (port_index >= 1 && port_index <= 16)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_present_regs[port_index][0]);
}
else if (port_index >= 17 && port_index <= 32)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_present_regs[port_index][0]);
}
if (status & qsfp_present_regs[port_index][1])
{
sprintf(buf, "%s%d\n", buf, DISABLE);
}
else
{
sprintf(buf, "%s%d\n", buf, ENABLE);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_int_all_get(struct device *dev, struct device_attribute *da, char *buf)
{
u8 status = -EPERM;
u32 result = -EPERM;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
if (attr->index == QSFP_INT_ALL)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_REAR_INT_REG); //25-32
result = status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_INT_REG); //17-24
result = (result << 8) | status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_REAR_INT_REG); //9-16
result = (result << 8) | status;
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_INT_REG); //1-8
result = (result << 8) | status;
sprintf(buf, "%s0x%x\n", buf, result);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_int_get(struct device *dev, struct device_attribute *da, char *buf)
{
int status = -EPERM;
int port_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
port_index = attr->index;
sprintf(buf, "");
if (port_index >= 1 && port_index <= 16)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_int_regs[port_index][0]);
}
else if (port_index >= 17 && port_index <= 32)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_int_regs[port_index][0]);
}
if (status & qsfp_int_regs[port_index][1])
{
sprintf(buf, "%s%d\n", buf, ENABLE);
}
else
{
sprintf(buf, "%s%d\n", buf, DISABLE);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_quter_int_get(struct device *dev, struct device_attribute *da, char *buf)
{
int status = -EPERM;
int quter_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
quter_index = attr->index;
sprintf(buf, "");
if (quter_index >= 1 && quter_index <= 2)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_quter_int_regs[quter_index][0]);
}
else if (quter_index >= 3 && quter_index <= 4)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_quter_int_regs[quter_index][0]);
}
if (status & qsfp_quter_int_regs[quter_index][1])
{
sprintf(buf, "%s%d\n", buf, NORMAL);
}
else
{
sprintf(buf, "%s%d\n", buf, ABNORMAL);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_quter_int_mask_get(struct device *dev, struct device_attribute *da, char *buf)
{
int status = -EPERM;
int quter_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
quter_index = attr->index;
sprintf(buf, "");
if (quter_index >= 1 && quter_index <= 2)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_quter_int_mask_regs[quter_index][0]);
}
else if (quter_index >= 3 && quter_index <= 4)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_quter_int_mask_regs[quter_index][0]);
}
if (status & qsfp_quter_int_mask_regs[quter_index][1])
{
sprintf(buf, "%s%d\n", buf, DISABLE);
}
else
{
sprintf(buf, "%s%d\n", buf, ENABLE);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_quter_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
{
int status = -EPERM;
int result = 0;
int input = 0;
int quter_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client);
struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client);
struct i2c_client *target_client = NULL;
quter_index = attr->index;
input = simple_strtol(buf, NULL, 10);
mutex_lock(&Cameo_CPLD_31_data->update_lock);
mutex_lock(&Cameo_CPLD_32_data->update_lock);
if (quter_index >= 1 && quter_index <= 2)
{
target_client = Cameo_CPLD_31_client;
}
else if (quter_index >= 3 && quter_index <= 4)
{
target_client = Cameo_CPLD_32_client;
}
status = i2c_smbus_read_byte_data(target_client, qsfp_quter_int_mask_regs[quter_index][0]);
if( input == DISABLE)
{
status |= qsfp_quter_int_mask_regs[quter_index][1];
result = i2c_smbus_write_byte_data(target_client, qsfp_quter_int_mask_regs[quter_index][0], status);
if (result < 0)
{
printk(KERN_ALERT "ERROR: qsfp_quter_int_mask_set ON FAILED!\n");
}
}
else if( input == ENABLE)
{
status &= ~(qsfp_quter_int_mask_regs[quter_index][1]);
result = i2c_smbus_write_byte_data(target_client, qsfp_quter_int_mask_regs[quter_index][0], status);
if (result < 0)
{
printk(KERN_ALERT "ERROR: qsfp_quter_int_mask_set OFF FAILED!\n");
}
}
else
{
printk(KERN_ALERT "ERROR: qsfp_quter_int_mask_set WRONG VALUE\n");
}
mutex_unlock(&Cameo_CPLD_31_data->update_lock);
mutex_unlock(&Cameo_CPLD_32_data->update_lock);
return count;
}
ssize_t qsfp_modprs_int_get(struct device *dev, struct device_attribute *da, char *buf)
{
int status = -EPERM;
int quter_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
quter_index = attr->index;
sprintf(buf, "");
if (quter_index >= 1 && quter_index <= 2)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_modprs_int_regs[quter_index][0]);
}
else if (quter_index >= 3 && quter_index <= 4)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_modprs_int_regs[quter_index][0]);
}
if (status & qsfp_modprs_int_regs[quter_index][1])
{
sprintf(buf, "%s%d\n", buf, NORMAL);
}
else
{
sprintf(buf, "%s%d\n", buf, ABNORMAL);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_modprs_int_mask_get(struct device *dev, struct device_attribute *da, char *buf)
{
int status = -EPERM;
int quter_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
quter_index = attr->index;
sprintf(buf, "");
if (quter_index >= 1 && quter_index <= 2)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_modprs_int_mask_regs[quter_index][0]);
}
else if (quter_index >= 3 && quter_index <= 4)
{
status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_modprs_int_mask_regs[quter_index][0]);
}
if (status & qsfp_modprs_int_mask_regs[quter_index][1])
{
sprintf(buf, "%s%d\n", buf, DISABLE);
}
else
{
sprintf(buf, "%s%d\n", buf, ENABLE);
}
return sprintf(buf, "%s\n", buf);
}
ssize_t qsfp_modprs_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
{
int status = -EPERM;
int result = 0;
int input = 0;
int quter_index = 0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client);
struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client);
struct i2c_client *target_client = NULL;
quter_index = attr->index;
input = simple_strtol(buf, NULL, 10);
mutex_lock(&Cameo_CPLD_31_data->update_lock);
mutex_lock(&Cameo_CPLD_32_data->update_lock);
if (quter_index >= 1 && quter_index <= 2)
{
target_client = Cameo_CPLD_31_client;
}
else if (quter_index >= 3 && quter_index <= 4)
{
target_client = Cameo_CPLD_32_client;
}
status = i2c_smbus_read_byte_data(target_client, qsfp_modprs_int_mask_regs[quter_index][0]);
if( input == DISABLE)
{
status |= qsfp_modprs_int_mask_regs[quter_index][1];
result = i2c_smbus_write_byte_data(target_client, qsfp_modprs_int_mask_regs[quter_index][0], status);
if (result < 0)
{
printk(KERN_ALERT "ERROR: qsfp_modprs_int_mask_set ON FAILED!\n");
}
}
else if( input == ENABLE)
{
status &= ~(qsfp_modprs_int_mask_regs[quter_index][1]);
result = i2c_smbus_write_byte_data(target_client, qsfp_modprs_int_mask_regs[quter_index][0], status);
if (result < 0)
{
printk(KERN_ALERT "ERROR: qsfp_modprs_int_mask_set OFF FAILED!\n");
}
}
else
{
printk(KERN_ALERT "ERROR: qsfp_modprs_int_mask_set WRONG VALUE\n");
}
mutex_unlock(&Cameo_CPLD_31_data->update_lock);
mutex_unlock(&Cameo_CPLD_32_data->update_lock);
return count;
}
/* end of implement i2c_function */