support the AG8032 platfrom

This commit is contained in:
shaohua.xiong
2018-06-11 19:01:14 +08:00
parent afae91cf04
commit 62f5cd82c2
55 changed files with 5049 additions and 0 deletions

View File

@@ -2428,6 +2428,7 @@ CONFIG_SENSORS_CORETEMP=y
# CONFIG_SENSORS_MAX1668 is not set
# CONFIG_SENSORS_MAX197 is not set
# CONFIG_SENSORS_MAX31722 is not set
CONFIG_SENSORS_MAX6620=y
# CONFIG_SENSORS_MAX6639 is not set
# CONFIG_SENSORS_MAX6642 is not set
# CONFIG_SENSORS_MAX6650 is not set

View File

@@ -0,0 +1,740 @@
From 63fff0670cf4fea6815aba404ba9ae7c19f2f3ff Mon Sep 17 00:00:00 2001
From: "shaohua.xiong" <shaohua.xiong@deltaww.com>
Date: Thu, 19 Apr 2018 16:50:29 +0800
Subject: [PATCH] add the support max6620 driver
---
drivers/hwmon/Kconfig | 10 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/max6620.c | 686 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 697 insertions(+)
create mode 100644 drivers/hwmon/max6620.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 45cef3d..5c33957 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -844,6 +844,16 @@ tristate "MAX31722 temperature sensor"
This driver can also be built as a module. If so, the module
will be called max31722.
+config SENSORS_MAX6620
+ tristate "Maxim MAX6620 sensor chip"
+ depends on I2C
+ help
+ If you say yes here you get support for the MAX6620
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called max6620
+
config SENSORS_MAX6639
tristate "Maxim MAX6639 sensor chip"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index aecf4ba..724a1f7 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_MAX1668) += max1668.o
obj-$(CONFIG_SENSORS_MAX197) += max197.o
obj-$(CONFIG_SENSORS_MAX31722) += max31722.o
+obj-$(CONFIG_SENSORS_MAX6620) += max6620.o
obj-$(CONFIG_SENSORS_MAX6639) += max6639.o
obj-$(CONFIG_SENSORS_MAX6642) += max6642.o
obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
diff --git a/drivers/hwmon/max6620.c b/drivers/hwmon/max6620.c
new file mode 100644
index 0000000..fb49195
--- /dev/null
+++ b/drivers/hwmon/max6620.c
@@ -0,0 +1,686 @@
+/*
+ * max6620.c - Linux Kernel module for hardware monitoring.
+ *
+ * (C) 2012 by L. Grunenberg <contact@lgrunenberg.de>
+ *
+ * based on code written by :
+ * 2007 by Hans J. Koch <hjk@hansjkoch.de>
+ * John Morris <john.morris@spirentcom.com>
+ * Copyright (c) 2003 Spirent Communications
+ * and Claus Gindhart <claus.gindhart@kontron.com>
+ *
+ * This module has only been tested with the MAX6620 chip.
+ *
+ * The datasheet was last seen at:
+ *
+ * http://pdfserv.maxim-ic.com/en/ds/MAX6620.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+
+/*
+ * Insmod parameters
+ */
+
+
+/* clock: The clock frequency of the chip the driver should assume */
+static int clock = 8192;
+static u32 sr = 2;
+static u32 np = 2;
+
+module_param(clock, int, S_IRUGO);
+
+static const unsigned short normal_i2c[] = {0x0a, 0x1a, 0x2a, I2C_CLIENT_END};
+
+/*
+ * MAX 6620 registers
+ */
+
+#define MAX6620_REG_CONFIG 0x00
+#define MAX6620_REG_FAULT 0x01
+#define MAX6620_REG_CONF_FAN0 0x02
+#define MAX6620_REG_CONF_FAN1 0x03
+#define MAX6620_REG_CONF_FAN2 0x04
+#define MAX6620_REG_CONF_FAN3 0x05
+#define MAX6620_REG_DYN_FAN0 0x06
+#define MAX6620_REG_DYN_FAN1 0x07
+#define MAX6620_REG_DYN_FAN2 0x08
+#define MAX6620_REG_DYN_FAN3 0x09
+#define MAX6620_REG_TACH0 0x10
+#define MAX6620_REG_TACH1 0x12
+#define MAX6620_REG_TACH2 0x14
+#define MAX6620_REG_TACH3 0x16
+#define MAX6620_REG_VOLT0 0x18
+#define MAX6620_REG_VOLT1 0x1A
+#define MAX6620_REG_VOLT2 0x1C
+#define MAX6620_REG_VOLT3 0x1E
+#define MAX6620_REG_TAR0 0x20
+#define MAX6620_REG_TAR1 0x22
+#define MAX6620_REG_TAR2 0x24
+#define MAX6620_REG_TAR3 0x26
+#define MAX6620_REG_DAC0 0x28
+#define MAX6620_REG_DAC1 0x2A
+#define MAX6620_REG_DAC2 0x2C
+#define MAX6620_REG_DAC3 0x2E
+
+/*
+ * Config register bits
+ */
+
+#define MAX6620_CFG_RUN 0x80
+#define MAX6620_CFG_POR 0x40
+#define MAX6620_CFG_TIMEOUT 0x20
+#define MAX6620_CFG_FULLFAN 0x10
+#define MAX6620_CFG_OSC 0x08
+#define MAX6620_CFG_WD_MASK 0x06
+#define MAX6620_CFG_WD_2 0x02
+#define MAX6620_CFG_WD_6 0x04
+#define MAX6620_CFG_WD10 0x06
+#define MAX6620_CFG_WD 0x01
+
+
+/*
+ * Failure status register bits
+ */
+
+#define MAX6620_FAIL_TACH0 0x10
+#define MAX6620_FAIL_TACH1 0x20
+#define MAX6620_FAIL_TACH2 0x40
+#define MAX6620_FAIL_TACH3 0x80
+#define MAX6620_FAIL_MASK0 0x01
+#define MAX6620_FAIL_MASK1 0x02
+#define MAX6620_FAIL_MASK2 0x04
+#define MAX6620_FAIL_MASK3 0x08
+
+
+/* Minimum and maximum values of the FAN-RPM */
+#define FAN_RPM_MIN 240
+#define FAN_RPM_MAX 30000
+
+#define DIV_FROM_REG(reg) (1 << ((reg & 0xE0) >> 5))
+
+static int max6620_probe(struct i2c_client *client, const struct i2c_device_id *id);
+static int max6620_init_client(struct i2c_client *client);
+static int max6620_remove(struct i2c_client *client);
+static struct max6620_data *max6620_update_device(struct device *dev);
+
+static const u8 config_reg[] = {
+ MAX6620_REG_CONF_FAN0,
+ MAX6620_REG_CONF_FAN1,
+ MAX6620_REG_CONF_FAN2,
+ MAX6620_REG_CONF_FAN3,
+};
+
+static const u8 dyn_reg[] = {
+ MAX6620_REG_DYN_FAN0,
+ MAX6620_REG_DYN_FAN1,
+ MAX6620_REG_DYN_FAN2,
+ MAX6620_REG_DYN_FAN3,
+};
+
+static const u8 tach_reg[] = {
+ MAX6620_REG_TACH0,
+ MAX6620_REG_TACH1,
+ MAX6620_REG_TACH2,
+ MAX6620_REG_TACH3,
+};
+
+static const u8 volt_reg[] = {
+ MAX6620_REG_VOLT0,
+ MAX6620_REG_VOLT1,
+ MAX6620_REG_VOLT2,
+ MAX6620_REG_VOLT3,
+};
+
+static const u8 target_reg[] = {
+ MAX6620_REG_TAR0,
+ MAX6620_REG_TAR1,
+ MAX6620_REG_TAR2,
+ MAX6620_REG_TAR3,
+};
+
+static const u8 dac_reg[] = {
+ MAX6620_REG_DAC0,
+ MAX6620_REG_DAC1,
+ MAX6620_REG_DAC2,
+ MAX6620_REG_DAC3,
+};
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static const struct i2c_device_id max6620_id[] = {
+ { "max6620", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max6620_id);
+
+static struct i2c_driver max6620_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "max6620",
+ },
+ .probe = max6620_probe,
+ .remove = max6620_remove,
+ .id_table = max6620_id,
+ .address_list = normal_i2c,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct max6620_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ int nr_fans;
+ char valid; /* zero until following fields are valid */
+ unsigned long last_updated; /* in jiffies */
+
+ /* register values */
+ u8 speed[4];
+ u8 config;
+ u8 fancfg[4];
+ u8 fandyn[4];
+ u8 tach[4];
+ u8 volt[4];
+ u8 target[4];
+ u8 dac[4];
+ u8 fault;
+};
+
+static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, char *buf) {
+
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct max6620_data *data = max6620_update_device(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ u32 rpm = 0;
+ u32 tach = 0;
+ u32 tach1 = 0;
+ u32 tach2 = 0;
+
+ tach1 = i2c_smbus_read_byte_data(client, tach_reg[attr->index]);
+ tach1 = (tach1 << 3) & 0x7f8;
+ tach2 = i2c_smbus_read_byte_data(client, tach_reg[attr->index] + 1);
+ tach2 = (tach2 >> 5) & 0x7;
+ tach = tach1 | tach2;
+ if (tach == 0) {
+ rpm = 0;
+ } else {
+ rpm = (60 * sr * clock)/(tach * np);
+ }
+
+ return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t get_target(struct device *dev, struct device_attribute *devattr, char *buf) {
+
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct max6620_data *data = max6620_update_device(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ u32 rpm;
+ u32 target;
+ u32 target1;
+ u32 target2;
+
+ target1 = i2c_smbus_read_byte_data(client, target_reg[attr->index]);
+ target1 = (target1 << 3) & 0x7f8;
+ target2 = i2c_smbus_read_byte_data(client, target_reg[attr->index] + 1);
+ target2 = (target2 >> 5) & 0x7;
+ target = target1 | target2;
+ if (target == 0) {
+ rpm = 0;
+ } else {
+ rpm = (60 * sr * clock)/(target * np);
+ }
+ return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t set_target(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) {
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct max6620_data *data = i2c_get_clientdata(client);
+ unsigned long rpm;
+ int err;
+ unsigned long target;
+ unsigned long target1;
+ unsigned long target2;
+
+ err = kstrtoul(buf, 10, &rpm);
+ if (err)
+ return err;
+
+ rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
+
+ mutex_lock(&data->update_lock);
+
+ target = (60 * sr * 8192)/(rpm * np);
+ target1 = (target >> 3) & 0xff;
+ target2 = (target << 5) & 0xe0;
+ i2c_smbus_write_byte_data(client, target_reg[attr->index], target1);
+ i2c_smbus_write_byte_data(client, target_reg[attr->index] + 1, target2);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Get/set the fan speed in open loop mode using pwm1 sysfs file.
+ * Speed is given as a relative value from 0 to 255, where 255 is maximum
+ * speed. Note that this is done by writing directly to the chip's DAC,
+ * it won't change the closed loop speed set by fan1_target.
+ * Also note that due to rounding errors it is possible that you don't read
+ * back exactly the value you have set.
+ */
+
+static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, char *buf) {
+
+ int pwm;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct max6620_data *data = max6620_update_device(dev);
+
+ /*
+ * Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans.
+ * Lower DAC values mean higher speeds.
+ */
+ pwm = ((int)data->volt[attr->index]);
+
+ if (pwm < 0)
+ pwm = 0;
+
+ return sprintf(buf, "%d\n", pwm);
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) {
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct max6620_data *data = i2c_get_clientdata(client);
+ unsigned long pwm;
+ int err;
+
+ err = kstrtoul(buf, 10, &pwm);
+ if (err)
+ return err;
+
+ pwm = clamp_val(pwm, 0, 255);
+
+ mutex_lock(&data->update_lock);
+
+ data->dac[attr->index] = pwm;
+
+
+ i2c_smbus_write_byte_data(client, dac_reg[attr->index], data->dac[attr->index]);
+ i2c_smbus_write_byte_data(client, dac_reg[attr->index]+1, 0x00);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Get/Set controller mode:
+ * Possible values:
+ * 0 = Fan always on
+ * 1 = Open loop, Voltage is set according to speed, not regulated.
+ * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer
+ */
+
+static ssize_t get_enable(struct device *dev, struct device_attribute *devattr, char *buf) {
+
+ struct max6620_data *data = max6620_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int mode = (data->fancfg[attr->index] & 0x80 ) >> 7;
+ int sysfs_modes[2] = {1, 2};
+
+ return sprintf(buf, "%d\n", sysfs_modes[mode]);
+}
+
+static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) {
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6620_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int max6620_modes[3] = {0, 1, 0};
+ unsigned long mode;
+ int err;
+
+ err = kstrtoul(buf, 10, &mode);
+ if (err)
+ return err;
+
+ if (mode > 2)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+
+ data->fancfg[attr->index] = i2c_smbus_read_byte_data(client, config_reg[attr->index]);
+ data->fancfg[attr->index] = (data->fancfg[attr->index] & ~0x80)
+ | (max6620_modes[mode] << 7);
+
+ i2c_smbus_write_byte_data(client, config_reg[attr->index], data->fancfg[attr->index]);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Read/write functions for fan1_div sysfs file. The MAX6620 has no such
+ * divider. We handle this by converting between divider and counttime:
+ *
+ * (counttime == k) <==> (divider == 2^k), k = 0, 1, 2, 3, 4 or 5
+ *
+ * Lower values of k allow to connect a faster fan without the risk of
+ * counter overflow. The price is lower resolution. You can also set counttime
+ * using the module parameter. Note that the module parameter "prescaler" also
+ * influences the behaviour. Unfortunately, there's no sysfs attribute
+ * defined for that. See the data sheet for details.
+ */
+
+static ssize_t get_div(struct device *dev, struct device_attribute *devattr, char *buf) {
+
+ struct max6620_data *data = max6620_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+ return sprintf(buf, "%d\n", DIV_FROM_REG(data->fandyn[attr->index]));
+}
+
+static ssize_t set_div(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) {
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6620_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ unsigned long div;
+ int err;
+ u8 div_bin;
+
+ err = kstrtoul(buf, 10, &div);
+ if (err)
+ return err;
+
+ mutex_lock(&data->update_lock);
+ switch (div) {
+ case 1:
+ div_bin = 0;
+ break;
+ case 2:
+ div_bin = 1;
+ break;
+ case 4:
+ div_bin = 2;
+ break;
+ case 8:
+ div_bin = 3;
+ break;
+ case 16:
+ div_bin = 4;
+ break;
+ case 32:
+ div_bin = 5;
+ break;
+ default:
+ mutex_unlock(&data->update_lock);
+ return -EINVAL;
+ }
+ data->fandyn[attr->index] &= 0x1F;
+ data->fandyn[attr->index] |= div_bin << 5;
+ i2c_smbus_write_byte_data(client, dyn_reg[attr->index], data->fandyn[attr->index]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Get alarm stati:
+ * Possible values:
+ * 0 = no alarm
+ * 1 = alarm
+ */
+
+static ssize_t get_alarm(struct device *dev, struct device_attribute *devattr, char *buf) {
+
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct max6620_data *data = max6620_update_device(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ int alarm = 0;
+
+ if (data->fault & (1 << attr->index)) {
+ mutex_lock(&data->update_lock);
+ alarm = 1;
+ data->fault &= ~(1 << attr->index);
+ data->fault |= i2c_smbus_read_byte_data(client,
+ MAX6620_REG_FAULT);
+ mutex_unlock(&data->update_lock);
+ }
+
+ return sprintf(buf, "%d\n", alarm);
+}
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target, 0);
+static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div, 0);
+// static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 0);
+static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, get_target, set_target, 1);
+static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, get_div, set_div, 1);
+// static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 1);
+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 1);
+static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, get_target, set_target, 2);
+static SENSOR_DEVICE_ATTR(fan3_div, S_IWUSR | S_IRUGO, get_div, set_div, 2);
+// static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 2);
+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 2);
+static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, get_target, set_target, 3);
+static SENSOR_DEVICE_ATTR(fan4_div, S_IWUSR | S_IRUGO, get_div, set_div, 3);
+// static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, 3);
+static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 3);
+
+static struct attribute *max6620_attrs[] = {
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan4_input.dev_attr.attr,
+ &sensor_dev_attr_fan1_target.dev_attr.attr,
+ &sensor_dev_attr_fan1_div.dev_attr.attr,
+// &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_fan2_target.dev_attr.attr,
+ &sensor_dev_attr_fan2_div.dev_attr.attr,
+// &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm2.dev_attr.attr,
+ &sensor_dev_attr_fan3_target.dev_attr.attr,
+ &sensor_dev_attr_fan3_div.dev_attr.attr,
+// &sensor_dev_attr_pwm3_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm3.dev_attr.attr,
+ &sensor_dev_attr_fan4_target.dev_attr.attr,
+ &sensor_dev_attr_fan4_div.dev_attr.attr,
+// &sensor_dev_attr_pwm4_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm4.dev_attr.attr,
+ NULL
+};
+
+static struct attribute_group max6620_attr_grp = {
+ .attrs = max6620_attrs,
+};
+
+
+/*
+ * Real code
+ */
+
+static int max6620_probe(struct i2c_client *client, const struct i2c_device_id *id) {
+
+ struct max6620_data *data;
+ int err;
+
+ data = devm_kzalloc(&client->dev, sizeof(struct max6620_data), GFP_KERNEL);
+ if (!data) {
+ dev_err(&client->dev, "out of memory.\n");
+ return -ENOMEM;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+ data->nr_fans = id->driver_data;
+
+ /*
+ * Initialize the max6620 chip
+ */
+ dev_info(&client->dev, "About to initialize module\n");
+
+ err = max6620_init_client(client);
+ if (err)
+ return err;
+ dev_info(&client->dev, "Module initialized\n");
+
+ err = sysfs_create_group(&client->dev.kobj, &max6620_attr_grp);
+ if (err)
+ return err;
+dev_info(&client->dev, "Sysfs entries created\n");
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (!IS_ERR(data->hwmon_dev))
+ return 0;
+
+ err = PTR_ERR(data->hwmon_dev);
+ dev_err(&client->dev, "error registering hwmon device.\n");
+
+ sysfs_remove_group(&client->dev.kobj, &max6620_attr_grp);
+ return err;
+}
+
+static int max6620_remove(struct i2c_client *client) {
+
+ struct max6620_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+
+ sysfs_remove_group(&client->dev.kobj, &max6620_attr_grp);
+ return 0;
+}
+
+static int max6620_init_client(struct i2c_client *client) {
+
+ struct max6620_data *data = i2c_get_clientdata(client);
+ int config;
+ int err = -EIO;
+ int i;
+
+ config = i2c_smbus_read_byte_data(client, MAX6620_REG_CONFIG);
+
+ if (config < 0) {
+ dev_err(&client->dev, "Error reading config, aborting.\n");
+ return err;
+ }
+
+ /*
+ * Set bit 4, disable other fans from going full speed on a fail
+ * failure.
+ */
+ if (i2c_smbus_write_byte_data(client, MAX6620_REG_CONFIG, config | 0x10)) {
+ dev_err(&client->dev, "Config write error, aborting.\n");
+ return err;
+ }
+
+ data->config = config;
+ for (i = 0; i < 4; i++) {
+ data->fancfg[i] = i2c_smbus_read_byte_data(client, config_reg[i]);
+ data->fancfg[i] |= 0xa8; // enable TACH monitoring
+ i2c_smbus_write_byte_data(client, config_reg[i], data->fancfg[i]);
+ data->fandyn[i] = i2c_smbus_read_byte_data(client, dyn_reg[i]);
+ /* 2 counts (001) and Rate change 100 (0.125 secs) */
+ data-> fandyn[i] = 0x30;
+ i2c_smbus_write_byte_data(client, dyn_reg[i], data->fandyn[i]);
+ data->tach[i] = i2c_smbus_read_byte_data(client, tach_reg[i]);
+ data->volt[i] = i2c_smbus_read_byte_data(client, volt_reg[i]);
+ data->target[i] = i2c_smbus_read_byte_data(client, target_reg[i]);
+ data->dac[i] = i2c_smbus_read_byte_data(client, dac_reg[i]);
+ }
+ return 0;
+}
+
+static struct max6620_data *max6620_update_device(struct device *dev)
+{
+ int i;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6620_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+
+ for (i = 0; i < 4; i++) {
+ data->fancfg[i] = i2c_smbus_read_byte_data(client, config_reg[i]);
+ data->fandyn[i] = i2c_smbus_read_byte_data(client, dyn_reg[i]);
+ data->tach[i] = i2c_smbus_read_byte_data(client, tach_reg[i]);
+ data->volt[i] = i2c_smbus_read_byte_data(client, volt_reg[i]);
+ data->target[i] = i2c_smbus_read_byte_data(client, target_reg[i]);
+ data->dac[i] = i2c_smbus_read_byte_data(client, dac_reg[i]);
+ }
+
+
+ /*
+ * Alarms are cleared on read in case the condition that
+ * caused the alarm is removed. Keep the value latched here
+ * for providing the register through different alarm files.
+ */
+ u8 fault_reg;
+ fault_reg = i2c_smbus_read_byte_data(client, MAX6620_REG_FAULT);
+ data->fault |= (fault_reg >> 4) & (fault_reg & 0x0F);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init max6620_init(void)
+{
+ return i2c_add_driver(&max6620_driver);
+}
+module_init(max6620_init);
+
+/**
+ * sht21_init() - clean up driver
+ *
+ * Called when module is removed.
+ */
+static void __exit max6620_exit(void)
+{
+ i2c_del_driver(&max6620_driver);
+}
+module_exit(max6620_exit);
+
+MODULE_AUTHOR("Lucas Grunenberg");
+MODULE_DESCRIPTION("MAX6620 sensor driver");
+MODULE_LICENSE("GPL");
--
2.7.4

View File

@@ -0,0 +1,39 @@
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 35c0bc6..25878eb 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -62,6 +62,8 @@
static DEFINE_MUTEX(core_lock);
static DEFINE_IDR(i2c_adapter_idr);
+static char i2c_dev_auto_detect = 1;
+
static struct device_type i2c_client_type;
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
@@ -2011,6 +2013,9 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
if (!driver->detect || !address_list)
return 0;
+ if (i2c_dev_auto_detect == 0)
+ return 0;
+
/* Stop here if the classes do not match */
if (!(adapter->class & driver->class))
return 0;
@@ -2617,6 +2622,15 @@ trace:
}
EXPORT_SYMBOL(i2c_smbus_xfer);
+static int __init __i2c_dev_auto_detect(char *str)
+{
+ if (str[0] == '0')
+ i2c_dev_auto_detect = 0;
+
+ return 1;
+}
+__setup("i2c_dev_auto_detect=", __i2c_dev_auto_detect);
+
MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
MODULE_DESCRIPTION("I2C-Bus main module");
MODULE_LICENSE("GPL");

View File

@@ -11,3 +11,5 @@ driver-support-intel-igb-bcm5461-phy.patch
0010-platform-mellanox-mlxreg-hotplug-driver-add-check-fo.patch
0011-platform-x86-mlx-platform-new-features.patch
0012-i2c-busses-Add-capabilities-to-i2c-mlxcpld.patch
driver-i2c-i2c-core.patch
driver-add-the-support-max6620.patch

View File

@@ -0,0 +1,2 @@
*x86*64*delta*ag8032*.mk
onlpdump.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=delta BASENAME=x86-64-delta-ag8032 ARCH=amd64 KERNELS="onl-kernel-4.9-lts-x86-64-all:amd64"

View File

@@ -0,0 +1 @@
lib

View File

@@ -0,0 +1,6 @@
KERNELS := onl-kernel-4.9-lts-x86-64-all:amd64
KMODULES := $(wildcard *.c)
VENDOR := delta
BASENAME := x86-64-delta-ag8032
ARCH := x86_64
include $(ONL)/make/kmodule.mk

View File

@@ -0,0 +1,207 @@
/*
*
* Copyright (C) 2017 Delta Networks, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/version.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#if 0
#include "x86-64-delta-ag8032-i2c-mux-cpld.h"
#else
struct i2c_mux_cpld_platform_data
{
u8 cpld_bus;
u8 cpld_addr;
u8 cpld_reg;
u8 parent_bus;
u8 base_nr;
const u8 *values;
int n_values;
bool idle_in_use;
u8 idle;
void *ctrl_adap;
};
#endif
//static DEFINE_MUTEX(locker);
struct cpldmux {
struct i2c_mux_cpld_platform_data data;
};
static int i2c_mux_cpld_set(const struct cpldmux *mux, unsigned int chan_id)
{
unsigned long orig_jiffies;
unsigned short flags;
union i2c_smbus_data data;
struct i2c_adapter *ctrl_adap;
int try;
s32 res = -EIO;
data.byte = chan_id;
flags = 0;
ctrl_adap = mux->data.ctrl_adap;
if (!ctrl_adap)
return res;
// try to lock it
if (ctrl_adap->algo->smbus_xfer) {
/* Retry automatically on arbitration loss */
orig_jiffies = jiffies;
for (res = 0, try = 0; try <= ctrl_adap->retries; try++) {
// modify the register
res = ctrl_adap->algo->smbus_xfer(ctrl_adap,
mux->data.cpld_addr, flags,
I2C_SMBUS_WRITE, mux->data.cpld_reg,
I2C_SMBUS_BYTE_DATA, &data);
if (res && res != -EAGAIN)
break;
if (time_after(jiffies,
orig_jiffies + ctrl_adap->timeout))
break;
}
}
return 0;
}
static int i2c_mux_cpld_select (struct i2c_mux_core *muxc, u32 chan)
{
struct cpldmux *mux = i2c_mux_priv(muxc);
return i2c_mux_cpld_set(mux, chan);
}
static int i2c_mux_cpld_deselect (struct i2c_mux_core *muxc, u32 chan)
{
struct cpldmux *mux = i2c_mux_priv(muxc);
if (mux->data.idle_in_use)
return i2c_mux_cpld_set(mux, mux->data.idle);
return 0;
}
static int i2c_mux_cpld_probe(struct platform_device *pdev)
{
struct i2c_mux_core *muxc;
struct cpldmux *mux;
struct i2c_adapter *parent;
struct i2c_adapter *ctrl;
int i, ret, nr;
mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
if (!mux)
return -ENOMEM;
ctrl = NULL;
parent = NULL;
if (dev_get_platdata(&pdev->dev)) {
memcpy(&mux->data, dev_get_platdata(&pdev->dev),
sizeof(mux->data));
parent = i2c_get_adapter(mux->data.parent_bus);
if (!parent)
return -EPROBE_DEFER;
ctrl = i2c_get_adapter(mux->data.cpld_bus);
if (!ctrl) {
i2c_put_adapter(parent);
return -EPROBE_DEFER;
}
}
muxc = i2c_mux_alloc (parent, &pdev->dev,
mux->data.n_values,
0, 0,
i2c_mux_cpld_select,
i2c_mux_cpld_deselect);
if (!muxc)
return -ENOMEM;
muxc->priv = mux;
mux->data.ctrl_adap = ctrl;
platform_set_drvdata(pdev, muxc);
for (i = 0; i < mux->data.n_values; i++) {
nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
ret = i2c_mux_add_adapter (muxc, nr, mux->data.values[i], 0);
if (ret) {
dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
goto add_adapter_failed;
}
}
dev_dbg(&pdev->dev, "%d port mux on %s adapter\n",
mux->data.n_values, parent->name);
return 0;
add_adapter_failed:
i2c_put_adapter(ctrl);
i2c_put_adapter(parent);
i2c_mux_del_adapters(muxc);
return ret;
}
static int i2c_mux_cpld_remove(struct platform_device *pdev)
{
struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
struct cpldmux *mux = i2c_mux_priv(muxc);
i2c_mux_del_adapters(muxc);
i2c_put_adapter(mux->data.ctrl_adap);
i2c_put_adapter(muxc->parent);
return 0;
}
static struct platform_driver i2c_mux_cpld_driver = {
.probe = i2c_mux_cpld_probe,
.remove = i2c_mux_cpld_remove,
.driver = {
.name = "i2c-mux-cpld",
},
};
module_platform_driver(i2c_mux_cpld_driver);
MODULE_AUTHOR("Dave Hu <dave.hu@deltaww.com>");
MODULE_DESCRIPTION("I2C CPLD mux driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:i2c-mux-cpld");

View File

@@ -0,0 +1,43 @@
/*
*
* Copyright (C) 2017 Delta Networks, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __DNI_I2C_MUX_CPLD_H__
#define __DNI_I2C_MUX_CPLD_H__
struct i2c_mux_cpld_platform_data
{
u8 cpld_bus;
u8 cpld_addr;
u8 cpld_reg;
u8 parent_bus;
u8 base_nr;
const u8 *values;
int n_values;
bool idle_in_use;
u8 idle;
void *ctrl_adap;
};
#endif // __DNI_I2C_MUX_CPLD_H__

View File

@@ -0,0 +1,177 @@
/*
*
* Copyright (C) 2017 Delta Networks, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#if 0
#include "x86-64-delta-ag8032-i2c-mux-cpld.h"
#else
struct i2c_mux_cpld_platform_data
{
u8 cpld_bus;
u8 cpld_addr;
u8 cpld_reg;
u8 parent_bus;
u8 base_nr;
const u8 *values;
int n_values;
bool idle_in_use;
u8 idle;
void *ctrl_adap;
};
#endif
static const u8 subbus_mux_values[] = {
0xe0, 0xe1, 0xe2, 0xe3
};
static struct i2c_mux_cpld_platform_data subbus_mux = {
.cpld_bus = 0,
.cpld_addr= 0x2e,
.cpld_reg = 0x15,
.parent_bus = 1,
.values = subbus_mux_values,
.n_values = 4,
};
static const u8 qsfp_mux_values_1_8[] = {
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
};
static struct i2c_mux_cpld_platform_data qsfp_mux_1_8 = {
.cpld_bus = 3,
.cpld_addr= 0x30,
.cpld_reg = 0x05,
.parent_bus = 3,
.values = qsfp_mux_values_1_8,
.n_values = 8,
.idle_in_use = 1,
.idle = 0xff,
};
static const u8 qsfp_mux_values_9_16[] = {
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
};
static struct i2c_mux_cpld_platform_data qsfp_mux_9_16 = {
.cpld_bus = 3,
.cpld_addr= 0x30,
.cpld_reg = 0x04,
.parent_bus = 3,
.values = qsfp_mux_values_9_16,
.n_values = 8,
.idle_in_use = 1,
.idle = 0xff,
};
static const u8 qsfp_mux_values_17_24[] = {
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
};
static struct i2c_mux_cpld_platform_data qsfp_mux_17_24 = {
.cpld_bus = 3,
.cpld_addr= 0x30,
.cpld_reg = 0x03,
.parent_bus = 3,
.values = qsfp_mux_values_17_24,
.n_values = 8,
.idle_in_use = 1,
.idle = 0xff,
};
static const u8 qsfp_mux_values_25_32[] = {
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
};
static struct i2c_mux_cpld_platform_data qsfp_mux_25_32 = {
.cpld_bus = 3,
.cpld_addr= 0x30,
.cpld_reg = 0x02,
.parent_bus = 3,
.values = qsfp_mux_values_25_32,
.n_values = 8,
.idle_in_use = 1,
.idle = 0xff,
};
static int add_ag8032_platform_cpld_mux_devices(void)
{
struct platform_device *pdev;
pdev = platform_device_register_simple("i2c-mux-cpld", 1, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
platform_device_add_data (pdev, &subbus_mux, sizeof(subbus_mux));
pdev = platform_device_register_simple("i2c-mux-cpld", 2, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
platform_device_add_data (pdev, &qsfp_mux_1_8, sizeof(qsfp_mux_1_8));
pdev = platform_device_register_simple("i2c-mux-cpld", 3, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
platform_device_add_data (pdev, &qsfp_mux_9_16, sizeof(qsfp_mux_9_16));
pdev = platform_device_register_simple("i2c-mux-cpld", 4, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
platform_device_add_data (pdev, &qsfp_mux_17_24, sizeof(qsfp_mux_17_24));
pdev = platform_device_register_simple("i2c-mux-cpld", 5, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
platform_device_add_data (pdev, &qsfp_mux_25_32, sizeof(qsfp_mux_25_32));
return 0;
}
static int __init ag8032_platform_init(void)
{
add_ag8032_platform_cpld_mux_devices ();
return 0;
}
static void __exit ag8032_platform_exit(void)
{
}
MODULE_AUTHOR("Dave Hu <dave.hu@deltaww.com>");
MODULE_DESCRIPTION("Delta AG8032");
MODULE_LICENSE("GPL");
module_init(ag8032_platform_init);
module_exit(ag8032_platform_exit);

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-delta-ag8032 ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu

View File

@@ -0,0 +1,2 @@
FILTER=src
include $(ONL)/make/subdirs.mk

View File

@@ -0,0 +1,45 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific
# language governing permissions and limitations under the
# License.
#
# </bsn.cl>
############################################################
#
#
############################################################
include $(ONL)/make/config.amd64.mk
MODULE := libonlp-x86-64-delta-ag8032
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF x86_64_delta_ag8032 onlplib
DEPENDMODULE_HEADERS := sff
include $(BUILDER)/dependmodules.mk
SHAREDLIB := libonlp-x86-64-delta-ag8032.so
$(SHAREDLIB)_TARGETS := $(ALL_TARGETS)
include $(BUILDER)/so.mk
.DEFAULT_GOAL := $(SHAREDLIB)
GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -fPIC
GLOBAL_LINK_LIBS += -lpthread
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1,46 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific
# language governing permissions and limitations under the
# License.
#
# </bsn.cl>
############################################################
#
#
#
############################################################
include $(ONL)/make/config.amd64.mk
.DEFAULT_GOAL := onlpdump
MODULE := onlpdump
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF onlp x86_64_delta_ag8032 onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS
include $(BUILDER)/dependmodules.mk
BINARY := onlpdump
$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS)
include $(BUILDER)/bin.mk
GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1
GLOBAL_LINK_LIBS += -lpthread -lm
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1 @@
name: x86_64_delta_ag8032

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
include ../../init.mk
MODULE := x86_64_delta_ag8032
AUTOMODULE := x86_64_delta_ag8032
include $(BUILDER)/definemodule.mk

View File

@@ -0,0 +1,6 @@
###############################################################################
#
# x86_64_delta_ag8032 README
#
###############################################################################

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# x86_64_delta_ag8032 Autogeneration
#
###############################################################################
x86_64_delta_ag8032_AUTO_DEFS := module/auto/x86_64_delta_ag8032.yml
x86_64_delta_ag8032_AUTO_DIRS := module/inc/x86_64_delta_ag8032 module/src
include $(BUILDER)/auto.mk

View File

@@ -0,0 +1,50 @@
###############################################################################
#
# x86_64_delta_ag8032 Autogeneration Definitions.
#
###############################################################################
cdefs: &cdefs
- X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING:
doc: "Include or exclude logging."
default: 1
- X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT:
doc: "Default enabled log options."
default: AIM_LOG_OPTIONS_DEFAULT
- X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT:
doc: "Default enabled log bits."
default: AIM_LOG_BITS_DEFAULT
- X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT:
doc: "Default enabled custom log bits."
default: 0
- X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB:
doc: "Default all porting macros to use the C standard libraries."
default: 1
- X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS:
doc: "Include standard library headers for stdlib porting macros."
default: X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB
- X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI:
doc: "Include generic uCli support."
default: 0
- X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION:
doc: "Assume chassis fan direction is the same as the PSU fan direction."
default: 0
definitions:
cdefs:
X86_64_DELTA_AG8032_CONFIG_HEADER:
defs: *cdefs
basename: x86_64_delta_ag8032_config
portingmacro:
x86_64_delta_ag8032:
macros:
- malloc
- free
- memset
- memcpy
- strncpy
- vsnprintf
- snprintf
- strlen

View File

@@ -0,0 +1,14 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag8032/x86_64_delta_ag8032_config.h>
/* <--auto.start.xmacro(ALL).define> */
/* <auto.end.xmacro(ALL).define> */
/* <--auto.start.xenum(ALL).define> */
/* <auto.end.xenum(ALL).define> */

View File

@@ -0,0 +1,137 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_ag8032 Configuration Header
*
* @addtogroup x86_64_delta_ag8032-config
* @{
*
*****************************************************************************/
#ifndef __X86_64_DELTA_AG8032_CONFIG_H__
#define __X86_64_DELTA_AG8032_CONFIG_H__
#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG
#include <global_custom_config.h>
#endif
#ifdef X86_64_DELTA_AG8032_INCLUDE_CUSTOM_CONFIG
#include <x86_64_delta_ag8032_custom_config.h>
#endif
/* <auto.start.cdefs(X86_64_DELTA_AG8032_CONFIG_HEADER).header> */
#include <AIM/aim.h>
/**
* X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING
*
* Include or exclude logging. */
#ifndef X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING
#define X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING 1
#endif
/**
* X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT
*
* Default enabled log options. */
#ifndef X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT
#define X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT
#endif
/**
* X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT
*
* Default enabled log bits. */
#ifndef X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT
#define X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT
#endif
/**
* X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT
*
* Default enabled custom log bits. */
#ifndef X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT
#define X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT 0
#endif
/**
* X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB
*
* Default all porting macros to use the C standard libraries. */
#ifndef X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB
#define X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB 1
#endif
/**
* X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
*
* Include standard library headers for stdlib porting macros. */
#ifndef X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
#define X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB
#endif
/**
* X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI
*
* Include generic uCli support. */
#ifndef X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI
#define X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI 0
#endif
/**
* X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
*
* Assume chassis fan direction is the same as the PSU fan direction. */
#ifndef X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
#define X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION 0
#endif
/**
* All compile time options can be queried or displayed
*/
/** Configuration settings structure. */
typedef struct x86_64_delta_ag8032_config_settings_s {
/** name */
const char* name;
/** value */
const char* value;
} x86_64_delta_ag8032_config_settings_t;
/** Configuration settings table. */
/** x86_64_delta_ag8032_config_settings table. */
extern x86_64_delta_ag8032_config_settings_t x86_64_delta_ag8032_config_settings[];
/**
* @brief Lookup a configuration setting.
* @param setting The name of the configuration option to lookup.
*/
const char* x86_64_delta_ag8032_config_lookup(const char* setting);
/**
* @brief Show the compile-time configuration.
* @param pvs The output stream.
*/
int x86_64_delta_ag8032_config_show(struct aim_pvs_s* pvs);
/* <auto.end.cdefs(X86_64_DELTA_AG8032_CONFIG_HEADER).header> */
#include "x86_64_delta_ag8032_porting.h"
#endif /* __X86_64_DELTA_AG8032_CONFIG_H__ */
/* @} */

View File

@@ -0,0 +1,26 @@
/**************************************************************************//**
*
* x86_64_delta_ag8032 Doxygen Header
*
*****************************************************************************/
#ifndef __X86_64_DELTA_AG8032_DOX_H__
#define __X86_64_DELTA_AG8032_DOX_H__
/**
* @defgroup x86_64_delta_ag8032 x86_64_delta_ag8032 - x86_64_delta_ag8032 Description
*
The documentation overview for this module should go here.
*
* @{
*
* @defgroup x86_64_delta_ag8032-x86_64_delta_ag8032 Public Interface
* @defgroup x86_64_delta_ag8032-config Compile Time Configuration
* @defgroup x86_64_delta_ag8032-porting Porting Macros
*
* @}
*
*/
#endif /* __X86_64_DELTA_AG8032_DOX_H__ */

View File

@@ -0,0 +1,107 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_ag8032 Porting Macros.
*
* @addtogroup x86_64_delta_ag8032-porting
* @{
*
*****************************************************************************/
#ifndef __X86_64_DELTA_AG8032_PORTING_H__
#define __X86_64_DELTA_AG8032_PORTING_H__
/* <auto.start.portingmacro(ALL).define> */
#if X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <memory.h>
#endif
#ifndef x86_64_delta_ag8032_MALLOC
#if defined(GLOBAL_MALLOC)
#define x86_64_delta_ag8032_MALLOC GLOBAL_MALLOC
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_MALLOC malloc
#else
#error The macro x86_64_delta_ag8032_MALLOC is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag8032_FREE
#if defined(GLOBAL_FREE)
#define x86_64_delta_ag8032_FREE GLOBAL_FREE
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_FREE free
#else
#error The macro x86_64_delta_ag8032_FREE is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag8032_MEMSET
#if defined(GLOBAL_MEMSET)
#define x86_64_delta_ag8032_MEMSET GLOBAL_MEMSET
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_MEMSET memset
#else
#error The macro x86_64_delta_ag8032_MEMSET is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag8032_MEMCPY
#if defined(GLOBAL_MEMCPY)
#define x86_64_delta_ag8032_MEMCPY GLOBAL_MEMCPY
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_MEMCPY memcpy
#else
#error The macro x86_64_delta_ag8032_MEMCPY is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag8032_STRNCPY
#if defined(GLOBAL_STRNCPY)
#define x86_64_delta_ag8032_STRNCPY GLOBAL_STRNCPY
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_STRNCPY strncpy
#else
#error The macro x86_64_delta_ag8032_STRNCPY is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag8032_VSNPRINTF
#if defined(GLOBAL_VSNPRINTF)
#define x86_64_delta_ag8032_VSNPRINTF GLOBAL_VSNPRINTF
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_VSNPRINTF vsnprintf
#else
#error The macro x86_64_delta_ag8032_VSNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag8032_SNPRINTF
#if defined(GLOBAL_SNPRINTF)
#define x86_64_delta_ag8032_SNPRINTF GLOBAL_SNPRINTF
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_SNPRINTF snprintf
#else
#error The macro x86_64_delta_ag8032_SNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag8032_STRLEN
#if defined(GLOBAL_STRLEN)
#define x86_64_delta_ag8032_STRLEN GLOBAL_STRLEN
#elif X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag8032_STRLEN strlen
#else
#error The macro x86_64_delta_ag8032_STRLEN is required but cannot be defined.
#endif
#endif
/* <auto.end.portingmacro(ALL).define> */
#endif /* __X86_64_DELTA_AG8032_PORTING_H__ */
/* @} */

View File

@@ -0,0 +1,10 @@
###############################################################################
#
#
#
###############################################################################
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
x86_64_delta_ag8032_INCLUDES := -I $(THIS_DIR)inc
x86_64_delta_ag8032_INTERNAL_INCLUDES := -I $(THIS_DIR)src
x86_64_delta_ag8032_DEPENDMODULE_ENTRIES := init:x86_64_delta_ag8032 ucli:x86_64_delta_ag8032

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# Local source generation targets.
#
###############################################################################
ucli:
@../../../../tools/uclihandlers.py x86_64_delta_ag8032_ucli.c

View File

@@ -0,0 +1,44 @@
#if X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEBUG == 1
#include <unistd.h>
static char help__[] =
"Usage: debug [options]\n"
" -c CPLD Versions\n"
" -h Help\n"
;
int
x86_64_delta_ag8032_debug_main(int argc, char* argv[])
{
int c = 0;
int help = 0;
int rv = 0;
while( (c = getopt(argc, argv, "ch")) != -1) {
switch(c)
{
case 'c': c = 1; break;
case 'h': help = 1; rv = 0; break;
default: help = 1; rv = 1; break;
}
}
if(help || argc == 1) {
printf("%s", help__);
return rv;
}
if(c) {
printf("Not implemented.\n");
}
return 0;
}
#endif

View File

@@ -0,0 +1,43 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2017 (C) Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include "platform_lib.h"
#include "eeprom_drv.h"
int eeprom_read (int bus, uint8_t addr, uint8_t offset, uint8_t *buff, int len)
{
int i,r;
for (i = 0 ; i < len ; i ++) {
r = onlp_i2c_readb(bus,addr,offset+i,0);
if (r < 0) {
return -1;
}
buff[i] = (uint8_t)r;
}
return 0;
}

View File

@@ -0,0 +1,33 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2017 (C) Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#ifndef __EEPROM_DRV_H__
#define __EEPROM_DRV_H__
int eeprom_read (int bus, uint8_t addr, uint8_t offset, uint8_t *buff, int len);
#endif // __EEPROM_DRV_H__

View File

@@ -0,0 +1,118 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2017 (C) Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include "eeprom_info.h"
#include <string.h>
#define PSU_MODEL_LEN 11
#define PSU_SERIES_LEN 14
/*
function:
search the eeprom with the key
variables:
eeprom: the eeprom data;
key : the searching key string
mode : 1 means model search, 0 means series search
return:
success, return index which points to the finding string
failed, return -1
*/
int eeprom_info_find(char *eeprom, int len, const char *key,int mode)
{
int index=0;
int found=0;
int key_len=0;
if(!eeprom || !key)
return -1;
key_len=strlen(key);
while(index < len-key_len){
if (!strncmp(&eeprom[index], key, key_len)){
found=1;
break;
}
index++;
}
if(found){
/*mode is 1 means the model search and mode is 0 means the series search*/
if((mode == 1) && (index < len-PSU_MODEL_LEN))
return index;
else if ((mode == 0) && (index < len-PSU_SERIES_LEN))
return index;
else
return -1;
}
return -1;
}
int eeprom_info_get(uint8_t *eeprom, int len, char *type, char *v)
{
const char psu_model_key[]="DPS";
const char psu_460_series_key[]="DZRD";
const char psu_550_series_key[]="GVVD";
int index=0;
char model[PSU_MODEL_LEN+1]={'\0'};
char * eep=NULL;
if(!eeprom || !type ||!v)
return -1;
eep=(char *)eeprom;
/*fan eeprom is not now*/
if((strcmp(type, "fan_model")==0) ||(strcmp(type,"fan_series"))==0)
return 0;
/*first get the psu tpye*/
index = eeprom_info_find(eep,len,psu_model_key,1);
if(index <0)
return -1;
strncpy(model,&eep[index],PSU_MODEL_LEN);
if((strcmp(type,"psu_model"))==0){
strncpy(v,model,PSU_MODEL_LEN);
}
else if ((strcmp(type,"psu_series"))==0){
if(strstr(model,"460")){
index = eeprom_info_find(eep,len,psu_460_series_key,0);
if(index <0)
return -1;
strncpy(v,&eep[index],PSU_SERIES_LEN);
}
else if(strstr(model,"550")){
index = eeprom_info_find(eep,len,psu_550_series_key,0);
if(index <0)
return -1;
strncpy(v,&eep[index],PSU_SERIES_LEN);
}
}
else
return -1;
return 0;
}

View File

@@ -0,0 +1,36 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2017 (C) Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#ifndef __EEPROM_INFO__
#define __EEPROM_INFO__
#include "onlp/onlp_config.h"
extern int eeprom_info_get(uint8_t *eeprom, int len, char *type, char *v);
#endif // __EEPROM_INFO__

View File

@@ -0,0 +1,448 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2017 (C) Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/fani.h>
#include <onlplib/file.h>
#include "platform_lib.h"
#include "eeprom_info.h"
#define AG8032_FAN_TRAY_DEF_CAP \
(ONLP_FAN_CAPS_F2B)
static int _fan_tray_present (void *e);
static int _psu_fan_present (void *e);
static int _fan_event_cb (void *e, int ev);
static cpld_reg_t _fan_tray_present_reg[] = {
[PLAT_LED_ID_5] = CPLD_REG(CPLD_CPUPLD, 0x11, 0, 1),
[PLAT_LED_ID_6] = CPLD_REG(CPLD_CPUPLD, 0x11, 1, 1),
[PLAT_LED_ID_7] = CPLD_REG(CPLD_CPUPLD, 0x11, 2, 1),
};
static plat_fan_t plat_fans[] = {
[PLAT_FAN_ID_1] = {
.name = "FanTray1-1",
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_5],
.rpm_get_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan1_input",
.rpm_set_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan1_target",
.def_rpm = 7000,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
.eeprom_path = "/sys/devices/platform/*/*/2-0051/eeprom",
.event_callback = _fan_event_cb,
PLAT_FAN_INTERNAL_DEF,
},
[PLAT_FAN_ID_2] = {
.name = "FanTray1-2",
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_5],
.rpm_get_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan2_input",
.rpm_set_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan2_target",
.def_rpm = 7000,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
.eeprom_path = "/sys/devices/platform/*/*/2-0051/eeprom",
.event_callback = _fan_event_cb,
PLAT_FAN_INTERNAL_DEF,
},
[PLAT_FAN_ID_3] = {
.name = "FanTray2-1",
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_6],
.rpm_get_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan3_input",
.rpm_set_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan3_target",
.def_rpm = 7000,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
.eeprom_path = "/sys/devices/platform/*/*/2-0052/eeprom",
.event_callback = _fan_event_cb,
PLAT_FAN_INTERNAL_DEF,
},
[PLAT_FAN_ID_4] = {
.name = "FanTray2-2",
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_6],
.rpm_get_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan4_input",
.rpm_set_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0029/fan4_target",
.def_rpm = 7000,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
.eeprom_path = "/sys/devices/platform/*/*/2-0052/eeprom",
.event_callback = _fan_event_cb,
PLAT_FAN_INTERNAL_DEF,
},
[PLAT_FAN_ID_5] = {
.name = "FanTray3-1",
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_7],
.rpm_get_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-002a/fan1_input",
.rpm_set_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-002a/fan1_target",
.def_rpm = 7000,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
.eeprom_path = "/sys/devices/platform/*/*/2-0053/eeprom",
.event_callback = _fan_event_cb,
PLAT_FAN_INTERNAL_DEF,
},
[PLAT_FAN_ID_6] = {
.name = "FanTray3-2",
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_7],
.rpm_get_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-002a/fan2_input",
.rpm_set_path = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-002a/fan2_target",
.def_rpm = 7000,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
.eeprom_path = "/sys/devices/platform/*/*/2-0053/eeprom",
.event_callback = _fan_event_cb,
PLAT_FAN_INTERNAL_DEF,
},
[PLAT_FAN_ID_7] = {
.name = "PSU1 Fan",
.present = _psu_fan_present,
.rpm_get_path = "/sys/bus/i2c/devices/i2c-4/4-0058/hwmon/*/fan1_input",
.rpm_set_path = NULL,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
PLAT_FAN_INTERNAL_DEF,
},
[PLAT_FAN_ID_8] = {
.name = "PSU2 Fan",
.present = _psu_fan_present,
.rpm_get_path = "/sys/bus/i2c/devices/i2c-4/4-0059/hwmon/*/fan1_input",
.rpm_set_path = NULL,
.per_get_path = NULL,
.per_set_path = NULL,
.caps = AG8032_FAN_TRAY_DEF_CAP,
PLAT_FAN_INTERNAL_DEF,
},
};
static int _psu_fan_present (void *e)
{
plat_fan_t *fan = e;
return plat_os_file_is_existed (fan->rpm_get_path) ? 1 : 0;
}
static int _fan_event_cb (void *e, int ev)
{
int len;
plat_fan_t *fan = e;
switch (ev) {
case PLAT_FAN_EVENT_PLUGIN:
// reflush fan setting
if (fan->rpm_set_value > 0 && fan->rpm_set_path)
plat_os_file_write_int (fan->rpm_set_value, fan->rpm_set_path, NULL);
if (fan->per_set_value > 0 && fan->per_set_path)
plat_os_file_write_int (fan->per_set_value, fan->per_set_path, NULL);
// read eeprom info
if (fan->eeprom_path && (plat_os_file_read (fan->eeprom, sizeof(fan->eeprom), &len,
fan->eeprom_path, NULL) == ONLP_STATUS_OK)) {
break;
}
memset (fan->eeprom, 0xff, sizeof(fan->eeprom));
break;
case PLAT_FAN_EVENT_UNPLUG:
// clear eeprom info
memset (fan->eeprom, 0xff, sizeof(fan->eeprom));
break;
default:
break;
}
return 0;
}
static int _fan_tray_present (void *e)
{
plat_fan_t *fan = e;
return cpld_reg_get (fan->present_data) == 0 ? 1 : 0;
}
static int plat_fan_is_valid (int id)
{
if (id > PLAT_FAN_ID_INVALID && id < PLAT_FAN_ID_MAX) {
if (plat_fans[id].name)
return 1;
}
return 0;
}
int onlp_fani_init(void)
{
#if 0
plat_fan_t *fan;
int i;
for (i = PLAT_FAN_ID_1 ; i < PLAT_FAN_ID_MAX ; i ++) {
if (!plat_fan_is_valid(i))
continue;
fan = &plat_fans[i];
if (fan->def_rpm && fan->rpm_set_path)
onlp_fani_rpm_set (ONLP_FAN_ID_CREATE(i), fan->def_rpm);
if (fan->def_per && fan->per_set_path)
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(i), fan->def_per);
}
#endif
return ONLP_STATUS_OK;
}
int onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
{
int error;
plat_fan_t *fan;
int fid;
int present = 1;
if (!ONLP_OID_IS_FAN(id))
return ONLP_STATUS_E_INVALID;
fid = ONLP_OID_ID_GET(id);
if (!plat_fan_is_valid(fid))
return ONLP_STATUS_E_INVALID;
fan = &plat_fans[fid];
plat_fan_state_update (fan);
present = fan->state == PLAT_FAN_STATE_PRESENT ? 1 : 0;
memset (info, 0, sizeof(*info));
info->hdr.id = id;
if (fan->name)
snprintf (info->hdr.description, sizeof(info->hdr.description), "%s", fan->name);
info->caps = fan->caps;
if (fan->rpm_get_path) info->caps |= ONLP_FAN_CAPS_GET_RPM;
if (fan->rpm_set_path) info->caps |= ONLP_FAN_CAPS_SET_RPM;
if (fan->per_get_path) info->caps |= ONLP_FAN_CAPS_GET_PERCENTAGE;
if (fan->per_set_path) info->caps |= ONLP_FAN_CAPS_SET_PERCENTAGE;
error = 0;
if (present) {
info->status |= ONLP_FAN_STATUS_PRESENT;
if (info->caps & ONLP_FAN_CAPS_GET_RPM) {
if (plat_os_file_read_int(&info->rpm, fan->rpm_get_path, NULL) < 0) {
error ++;
} else {
if (fan->rpm_set_value > 0) {
if (info->rpm < ((fan->rpm_set_value * 80) / 100)) {
info->status |= ONLP_FAN_STATUS_FAILED;
}
}
}
}
if (info->caps & ONLP_FAN_CAPS_GET_PERCENTAGE) {
if (plat_os_file_read_int(&info->percentage, fan->per_get_path, NULL) < 0) {
error ++;
} else {
if (fan->per_set_value > 0) {
if (info->percentage < ((fan->per_set_value * 80) / 100)) {
info->status |= ONLP_FAN_STATUS_FAILED;
}
}
}
}
// get fan info
eeprom_info_get (fan->eeprom, sizeof(fan->eeprom), "fan_model", info->model);
eeprom_info_get (fan->eeprom, sizeof(fan->eeprom), "fan_series", info->serial);
}
if ((info->caps & (ONLP_FAN_CAPS_B2F | ONLP_FAN_CAPS_B2F)) == (ONLP_FAN_CAPS_B2F | ONLP_FAN_CAPS_B2F)) {
// should do check it auto
// TODO
} else if (info->caps & ONLP_FAN_CAPS_B2F) {
info->status |= ONLP_FAN_STATUS_B2F;
} else if (info->caps & ONLP_FAN_CAPS_F2B) {
info->status |= ONLP_FAN_STATUS_F2B;
}
return error ? ONLP_STATUS_E_INTERNAL : ONLP_STATUS_OK;
}
/*
* This function sets the speed of the given fan in RPM.
*
* This function will only be called if the fan supprots the RPM_SET
* capability.
*
* It is optional if you have no fans at all with this feature.
*/
int
onlp_fani_rpm_set(onlp_oid_t id, int rpm)
{
int error;
plat_fan_t *fan;
int fid;
if (!ONLP_OID_IS_FAN(id))
return ONLP_STATUS_E_INVALID;
fid = ONLP_OID_ID_GET(id);
if (!plat_fan_is_valid(fid))
return ONLP_STATUS_E_INVALID;
fan = &plat_fans[fid];
if (fan->rpm_set_path) {
if (fan->rpm_set_value != rpm) {
error = plat_os_file_write_int (rpm, fan->rpm_set_path, NULL);
}
} else
return ONLP_STATUS_E_UNSUPPORTED;
if (error < 0) {
return ONLP_STATUS_E_PARAM;
}
fan->rpm_set_value = rpm;
return ONLP_STATUS_OK;
}
int onlp_fani_percentage_set(onlp_oid_t id, int p)
{
int error;
plat_fan_t *fan;
int fid;
if (!ONLP_OID_IS_FAN(id))
return ONLP_STATUS_E_INVALID;
fid = ONLP_OID_ID_GET(id);
if (!plat_fan_is_valid(fid))
return ONLP_STATUS_E_INVALID;
fan = &plat_fans[fid];
if (fan->per_set_path) {
if (fan->per_set_value != p) {
error = plat_os_file_write_int (p, fan->per_set_path, NULL);
}
} else
return ONLP_STATUS_E_UNSUPPORTED;
if (error < 0) {
return ONLP_STATUS_E_PARAM;
}
fan->per_set_value = p;
return ONLP_STATUS_OK;
}
/*
* This function sets the fan speed of the given OID as per
* the predefined ONLP fan speed modes: off, slow, normal, fast, max.
*
* Interpretation of these modes is up to the platform.
*
*/
int
onlp_fani_mode_set(onlp_oid_t id, onlp_fan_mode_t mode)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* This function sets the fan direction of the given OID.
*
* This function is only relevant if the fan OID supports both direction
* capabilities.
*
* This function is optional unless the functionality is available.
*/
int
onlp_fani_dir_set(onlp_oid_t id, onlp_fan_dir_t dir)
{
plat_fan_t *fan;
int fid;
if (!ONLP_OID_IS_FAN(id))
return ONLP_STATUS_E_INVALID;
fid = ONLP_OID_ID_GET(id);
if (!plat_fan_is_valid(fid))
return ONLP_STATUS_E_INVALID;
fan = &plat_fans[fid];
if ((fan->caps & (ONLP_FAN_CAPS_B2F | ONLP_FAN_CAPS_B2F)) == (ONLP_FAN_CAPS_B2F | ONLP_FAN_CAPS_B2F)) {
// TODO
}
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* Generic fan ioctl. Optional.
*/
int
onlp_fani_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,347 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/ledi.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "platform_lib.h"
static int _fan_tray_present (void *e);
static cpld_reg_t _fan_tray_present_reg[] = {
[PLAT_LED_ID_5] = CPLD_REG (CPLD_CPUPLD, 0x11, 0, 1),
[PLAT_LED_ID_6] = CPLD_REG (CPLD_CPUPLD, 0x11, 1, 1),
[PLAT_LED_ID_7] = CPLD_REG (CPLD_CPUPLD, 0x11, 2, 1),
};
static plat_led_t plat_leds[] = {
/////////////////////////////////////////////////////////////
[PLAT_LED_ID_1] = {
.name = "sys",
.hw = CPLD_REG (CPLD_CPUPLD, 0x0e, 2, 2),
.mode = {
PLAT_LED_MODE(ONLP_LED_MODE_RED, 0),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN, 1),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN_BLINKING, 2),
PLAT_LED_MODE(ONLP_LED_MODE_RED_BLINKING, 3),
PLAT_LED_MODE_END,
},
PLAT_LED_INTERNAL_DEF,
},
/////////////////////////////////////////////////////////////
[PLAT_LED_ID_2] = {
.name = "fans",
.hw = CPLD_REG (CPLD_CPUPLD, 0x0c, 0, 2),
.mode = {
PLAT_LED_MODE(ONLP_LED_MODE_OFF, 0),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN, 1),
PLAT_LED_MODE(ONLP_LED_MODE_ORANGE, 3),
PLAT_LED_MODE_END,
},
PLAT_LED_INTERNAL_DEF,
},
/////////////////////////////////////////////////////////////
[PLAT_LED_ID_4] = {
.name = "pwr2",
.hw = CPLD_REG (CPLD_CPUPLD, 0x0c, 4, 2),
.mode = {
PLAT_LED_MODE(ONLP_LED_MODE_OFF, 0),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN, 1),
PLAT_LED_MODE(ONLP_LED_MODE_ORANGE, 2),
PLAT_LED_MODE_END,
},
PLAT_LED_INTERNAL_DEF,
},
/////////////////////////////////////////////////////////////
[PLAT_LED_ID_3] = {
.name = "pwr1",
.hw = CPLD_REG (CPLD_CPUPLD, 0x0c, 6, 2),
.mode = {
PLAT_LED_MODE(ONLP_LED_MODE_OFF, 0),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN, 1),
PLAT_LED_MODE(ONLP_LED_MODE_ORANGE, 2),
PLAT_LED_MODE_END,
},
PLAT_LED_INTERNAL_DEF,
},
/////////////////////////////////////////////////////////////
[PLAT_LED_ID_5] = {
.name = "fan1",
.hw = CPLD_REG (CPLD_CPUPLD, 0x0d, 0, 2),
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_5],
.mode = {
PLAT_LED_MODE(ONLP_LED_MODE_OFF, 0),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN, 1),
PLAT_LED_MODE(ONLP_LED_MODE_ORANGE, 2),
PLAT_LED_MODE_END,
},
PLAT_LED_INTERNAL_DEF,
},
/////////////////////////////////////////////////////////////
[PLAT_LED_ID_6] = {
.name = "fan2",
.hw = CPLD_REG (CPLD_CPUPLD, 0x0d, 2, 2),
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_6],
.mode = {
PLAT_LED_MODE(ONLP_LED_MODE_OFF, 0),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN, 1),
PLAT_LED_MODE(ONLP_LED_MODE_ORANGE, 2),
PLAT_LED_MODE_END,
},
PLAT_LED_INTERNAL_DEF,
},
/////////////////////////////////////////////////////////////
[PLAT_LED_ID_7] = {
.name = "fan3",
.hw = CPLD_REG (CPLD_CPUPLD, 0x0d, 4, 2),
.present = _fan_tray_present,
.present_data = &_fan_tray_present_reg[PLAT_LED_ID_7],
.mode = {
PLAT_LED_MODE(ONLP_LED_MODE_OFF, 0),
PLAT_LED_MODE(ONLP_LED_MODE_GREEN, 1),
PLAT_LED_MODE(ONLP_LED_MODE_ORANGE, 2),
PLAT_LED_MODE_END,
},
PLAT_LED_INTERNAL_DEF,
},
};
#define plat_leds_size (sizeof(plat_leds)/sizeof(plat_leds[0]))
static int plat_led_is_valid (int id)
{
if (id > 0 && id < plat_leds_size) {
if (plat_leds[id].name)
return 1;
}
return 0;
}
static int __hw_to_onlp_val (int id, int hv)
{
plat_led_t *led = &plat_leds[id];
led_mode_t *mod = &led->mode[0];
while (mod->hw_val >= 0) {
if (mod->hw_val == hv)
return mod->onlp_val;
mod ++;
}
return -1;
}
static int __onlp_to_hw_val (int id, int ov)
{
plat_led_t *led = &plat_leds[id];
led_mode_t *mod = &led->mode[0];
while (mod->onlp_val >= 0) {
if (mod->onlp_val == ov)
return mod->hw_val;
mod ++;
}
return -1;
}
static uint32_t _onlp_cap_create (led_mode_t *mod)
{
uint32_t cap = 0;
while (mod->onlp_val >= 0) {
switch (mod->onlp_val) {
case ONLP_LED_MODE_OFF: cap |= ONLP_LED_CAPS_ON_OFF; break;
case ONLP_LED_MODE_ON: cap |= ONLP_LED_CAPS_ON_OFF; break;
case ONLP_LED_MODE_RED: cap |= ONLP_LED_CAPS_RED; break;
case ONLP_LED_MODE_RED_BLINKING: cap |= ONLP_LED_CAPS_RED_BLINKING; break;
case ONLP_LED_MODE_ORANGE: cap |= ONLP_LED_CAPS_ORANGE; break;
case ONLP_LED_MODE_ORANGE_BLINKING: cap |= ONLP_LED_CAPS_ORANGE_BLINKING; break;
case ONLP_LED_MODE_YELLOW: cap |= ONLP_LED_CAPS_YELLOW; break;
case ONLP_LED_MODE_YELLOW_BLINKING: cap |= ONLP_LED_CAPS_YELLOW_BLINKING; break;
case ONLP_LED_MODE_GREEN: cap |= ONLP_LED_CAPS_GREEN; break;
case ONLP_LED_MODE_GREEN_BLINKING: cap |= ONLP_LED_CAPS_GREEN_BLINKING; break;
case ONLP_LED_MODE_BLUE: cap |= ONLP_LED_CAPS_BLUE; break;
case ONLP_LED_MODE_BLUE_BLINKING: cap |= ONLP_LED_CAPS_BLUE_BLINKING; break;
case ONLP_LED_MODE_PURPLE: cap |= ONLP_LED_CAPS_PURPLE; break;
case ONLP_LED_MODE_PURPLE_BLINKING: cap |= ONLP_LED_CAPS_PURPLE_BLINKING; break;
case ONLP_LED_MODE_AUTO: cap |= ONLP_LED_CAPS_AUTO; break;
case ONLP_LED_MODE_AUTO_BLINKING: cap |= ONLP_LED_CAPS_AUTO_BLINKING; break;
}
mod ++;
}
return cap;
}
static int _fan_tray_present (void *e)
{
plat_led_t *led = e;
return cpld_reg_get (led->present_data) == 0 ? 1 : 0;
}
/*
* This function will be called prior to any other onlp_ledi_* functions.
*/
int
onlp_ledi_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
{
int lid;
plat_led_t *led = &plat_leds[id];
led_mode_t *mod = &led->mode[0];
int present = 1;
if (!ONLP_OID_IS_LED(id))
return ONLP_STATUS_E_INVALID;
lid = ONLP_OID_ID_GET(id);
if (!plat_led_is_valid (lid))
return ONLP_STATUS_E_INVALID;
/* Set the onlp_oid_hdr_t and capabilities */
led = &plat_leds[lid];
mod = &led->mode[0];
memset (info, 0, sizeof(*info));
info->hdr.id = id;
if (led->name)
snprintf (info->hdr.description, sizeof(info->hdr.description), "%s", led->name);
info->caps = _onlp_cap_create (mod);
if (led->present) {
present = led->present(led) ? 1 : 0;
}
if (present) {
int mode;
if (led->hw_val_run < 0)
led->hw_val_run = cpld_reg_get (&led->hw);
mode = __hw_to_onlp_val (lid, led->hw_val_run);
info->status |= ONLP_LED_STATUS_PRESENT;
if (mode < 0) {
info->mode = ONLP_LED_MODE_OFF;
info->status |= ONLP_LED_STATUS_FAILED;
} else {
info->mode = mode;
info->status |= ONLP_LED_STATUS_ON;
}
switch (info->mode) {
case ONLP_LED_MODE_OFF:
info->status &= ~ONLP_LED_STATUS_ON;
break;
default:
break;
}
} else {
info->mode = ONLP_LED_MODE_OFF;
info->status &= ~ONLP_LED_STATUS_ON;
}
return ONLP_STATUS_OK;
}
/*
* This function puts the LED into the given mode. It is a more functional
* interface for multimode LEDs.
*
* Only modes reported in the LED's capabilities will be attempted.
*/
int
onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode)
{
int lid;
plat_led_t *led = &plat_leds[id];
int hw_val;
if (!ONLP_OID_IS_LED(id))
return ONLP_STATUS_E_INVALID;
lid = ONLP_OID_ID_GET(id);
if (!plat_led_is_valid (lid))
return ONLP_STATUS_E_INVALID;
led = &plat_leds[lid];
hw_val = __onlp_to_hw_val (lid, mode);
if (hw_val < 0)
return ONLP_STATUS_E_UNSUPPORTED;
if (led->hw_val_run == hw_val)
return ONLP_STATUS_OK;
if (cpld_reg_set (&led->hw, (uint8_t)hw_val)){
return ONLP_STATUS_E_INTERNAL;
}
led->hw_val_run = hw_val;
return ONLP_STATUS_OK;
}
/*
* Turn an LED on or off.
*
* This function will only be called if the LED OID supports the ONOFF
* capability.
*
* What 'on' means in terms of colors or modes for multimode LEDs is
* up to the platform to decide. This is intended as baseline toggle mechanism.
*/
int
onlp_ledi_set(onlp_oid_t id, int on_or_off)
{
if (!on_or_off) {
return onlp_ledi_mode_set(id, ONLP_LED_MODE_OFF);
}
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* Generic LED ioctl interface.
*/
int
onlp_ledi_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
LIBRARY := x86_64_delta_ag8032
$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(BUILDER)/lib.mk

View File

@@ -0,0 +1,386 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2017 (C) Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <stdio.h>
#include <unistd.h>
#include <onlplib/file.h>
#include "platform_lib.h"
////////////////////////////////////////////////////////////////
// PLAT DEV CONFIG
////////////////////////////////////////////////////////////////
static plat_dev_desc_t plat_devs[] = {
[PLAT_DEV_ID_INVALID] = {
.name = NULL,
},
// valid dev desc start
[PLAT_DEV_ID_1] = {
.name = "CPUPLD",
// i2c dev
.bus = 0,
.addr = 0x2e,
},
[PLAT_DEV_ID_2] = {
.name = "SWPLD",
// i2c dev
.bus = 3,
.addr = 0x30,
},
// valid dev desc end
// END
[PLAT_DEV_ID_MAX] = {
.name = NULL,
},
};
////////////////////////////////////////////////////////////////
// CPLD CONFIG
////////////////////////////////////////////////////////////////
static plat_cpld_t plat_cplds[] = {
[PLAT_CPLD_ID_INVALID] = {
.id = PLAT_DEV_ID_INVALID,
},
[PLAT_CPLD_ID_1] = {
.id = PLAT_DEV_ID_1,
.cached = {
[0x11] = 1,
[0x1a] = 1,
},
},
[PLAT_CPLD_ID_2] = {
.id = PLAT_DEV_ID_2,
.cached = {
[0x0a] = 1,
[0x0b] = 1,
[0x0c] = 1,
[0x0d] = 1,
},
},
// END
[PLAT_CPLD_ID_MAX] = {
.id = PLAT_DEV_ID_INVALID,
},
};
////////////////////////////////////////////////////////////////
// PLAT DEV ROUTINE
int plat_dev_id_is_valid (plat_dev_id_t id)
{
if (id > PLAT_DEV_ID_INVALID && id < PLAT_DEV_ID_MAX) {
if (plat_devs[id].name) {
return 1;
}
}
return 0;
}
int plat_dev_get_byte (plat_dev_id_t id, uint8_t reg)
{
if (!plat_dev_id_is_valid(id)) {
return -1;
}
return onlp_i2c_readb (plat_devs[id].bus, plat_devs[id].addr, reg, 0);
}
int plat_dev_set_byte (plat_dev_id_t id, uint8_t reg, uint8_t val)
{
if (!plat_dev_id_is_valid(id))
return -1;
return onlp_i2c_writeb(plat_devs[id].bus, plat_devs[id].addr, reg, val, 0);
}
////////////////////////////////////////////////////////////////
// CPLD PLAT ROUTINE
int cpld_id_is_valid (plat_cpld_id_t id)
{
if (id > PLAT_CPLD_ID_INVALID && id < PLAT_CPLD_ID_MAX) {
if (plat_dev_id_is_valid(plat_cplds[id].id))
return 1;
}
return 0;
}
int cpld_get (plat_cpld_id_t id, uint8_t reg)
{
if (!cpld_id_is_valid (id))
return -1;
return plat_dev_get_byte (plat_cplds[id].id, reg);
}
int cpld_set (plat_cpld_id_t id, uint8_t reg, uint8_t val)
{
if (!cpld_id_is_valid (id))
return -1;
return plat_dev_set_byte (plat_cplds[id].id, reg, val);
}
int cpld_field_get (plat_cpld_id_t id, uint8_t reg, uint8_t field, uint8_t len)
{
int val;
int i;
uint8_t mask = 0;
val = cpld_get (id, reg);
if (val < 0) {
return val;
}
// make mask;
for (i = 0 ; i < len ; i ++) {
mask |= (1 << (i));
}
val = ((val >> field) & mask);
return val;
}
int cpld_field_set (plat_cpld_id_t id, uint8_t reg, uint8_t field, uint8_t len, uint8_t val)
{
int _val;
int i;
uint8_t mask = 0;
_val = cpld_get (id, reg);
if (_val < 0)
return val;
// make mask;
for (i = 0 ; i < len ; i ++) {
mask |= (1 << (field + i));
}
val = ((val << field) & mask);
_val = (_val & ~mask);
return cpld_set (id, reg, val | (uint8_t)_val);
}
////////////////////////////////////////////////////////////////
// CPLD REG PLAT ROUTINE
int cpld_reg_is_valid (cpld_reg_t *r)
{
if (!r)
return 0;
if (r->valid)
return 1;
return 0;
}
int cpld_reg_get (cpld_reg_t *r)
{
if (!r)
return -1;
return cpld_field_get (r->id, r->reg, r->field, r->len);
}
int cpld_reg_set (cpld_reg_t *r, uint8_t val)
{
if (!r)
return -1;
return cpld_field_set (r->id, r->reg, r->field, r->len, val);
}
int present_on_board_always (void *e)
{
return 1;
}
////////////////////////////////////////////////////////////////
// PSU PLAT ROUTINE
int plat_fan_state_update (plat_fan_t *fan)
{
int present ;
plat_fan_state_t old_state;
do {
old_state = fan->state;
present = 1;
if (fan->present) {
present = fan->present(fan) ? 1 : 0;
}
switch (fan->state) {
case PLAT_FAN_STATE_UNPRESENT:
if (present) {
fan->state = PLAT_FAN_STATE_PRESENT;
if (fan->event_callback)
fan->event_callback(fan, PLAT_FAN_EVENT_PLUGIN);
break;
}
break;
case PLAT_FAN_STATE_PRESENT:
if (!present) {
fan->state = PLAT_FAN_STATE_UNPRESENT;
if (fan->event_callback)
fan->event_callback(fan, PLAT_FAN_EVENT_UNPLUG);
break;
}
break;
default:
break;
}
} while (old_state != fan->state);
return 0;
}
////////////////////////////////////////////////////////////////
// PSU PLAT ROUTINE
int plat_psu_state_update (plat_psu_t *psu)
{
int present ;
plat_psu_state_t old_state;
do {
old_state = psu->state;
present = 1;
if (psu->present) {
present = psu->present(psu) ? 1 : 0;
}
switch (psu->state) {
case PLAT_PSU_STATE_UNPRESENT:
if (present) {
psu->state = PLAT_PSU_STATE_PRESENT;
if (psu->event_callback)
psu->event_callback(psu, PLAT_PSU_EVENT_PLUGIN);
}
break;
case PLAT_PSU_STATE_PRESENT:
if (!present) {
psu->state = PLAT_PSU_STATE_UNPRESENT;
if (psu->event_callback)
psu->event_callback(psu, PLAT_PSU_EVENT_UNPLUG);
break;
}
if (onlp_i2c_readb (psu->pmbus_bus, psu->pmbus_addr, 0x00,
ONLP_I2C_F_FORCE | ONLP_I2C_F_DISABLE_READ_RETRIES) >= 0) {
psu->state = PLAT_PSU_STATE_PMBUS_READY;
if (!plat_os_file_is_existed(psu->pmbus_ready_path) && psu->pmbus_insert_cmd) {
system (psu->pmbus_insert_cmd);
}
if (psu->event_callback)
psu->event_callback(psu, PLAT_PSU_PMBUS_CONNECT);
}
break;
case PLAT_PSU_STATE_PMBUS_READY:
// If unplug, remove kernel module
if (!present) {
psu->state = PLAT_PSU_STATE_UNPRESENT;
if (psu->pmbus_remove_cmd) {
system (psu->pmbus_remove_cmd);
}
if (psu->event_callback)
psu->event_callback(psu, PLAT_PSU_EVENT_UNPLUG);
break;
}
// If pmbus interface is not ok, remove kernel module
if (onlp_i2c_readb (psu->pmbus_bus, psu->pmbus_addr, 0x00,
ONLP_I2C_F_FORCE | ONLP_I2C_F_DISABLE_READ_RETRIES) < 0) {
psu->state = PLAT_PSU_STATE_PRESENT;
if (psu->pmbus_remove_cmd) {
system (psu->pmbus_remove_cmd);
}
if (psu->event_callback)
psu->event_callback(psu, PLAT_PSU_PMBUS_DISCONNECT);
break;
}
break;
default:
break;
}
} while (old_state != psu->state);
return 0;
}
////////////////////////////////////////////////////////////////
// OS HELP ROUTINE
static char *plat_os_path_complete (char *path_pattern, char *buff, int len)
{
FILE *fp;
snprintf (buff, len, "realpath -z %s 2>/dev/null", path_pattern);
fp = popen (buff, "r");
if (fp) {
fgets (buff, len, fp);
pclose (fp);
} else {
snprintf (buff, len, "%s", path_pattern);
}
return buff;
}
int plat_os_file_is_existed (char *path)
{
char buff[1024];
if (path)
return access (plat_os_path_complete(path, buff, sizeof(buff)), F_OK) == 0 ? 1 : 0;
return 0;
}
int plat_os_file_read (uint8_t *data, int max, int *len, char *path, ...)
{
char buff[1024];
return onlp_file_read (data, max, len, plat_os_path_complete(path, buff, sizeof(buff)), NULL);
}
int plat_os_file_read_int (int *val, char *path, ...)
{
char buff[1024];
return onlp_file_read_int (val, plat_os_path_complete(path, buff, sizeof(buff)), NULL);
}
int plat_os_file_write_int(int val, char *path, ...)
{
char buff[1024];
return onlp_file_write_int (val, plat_os_path_complete(path, buff, sizeof(buff)), NULL);
}

View File

@@ -0,0 +1,334 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2017 (C) Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#ifndef __PLAT_LIB_H__
#define __PLAT_LIB_H__
#include <onlplib/i2c.h>
#define ONIE_EEPROM_LOCATION "/sys/bus/i2c/devices/i2c-5/5-0054/eeprom"
typedef int (*hook_present)(void *e);
typedef int (*hook_event )(void *e, int ev);
extern int present_on_board_always (void *e);
////////////////////////////////////////////////////////////////
// PLAT DEV ROUTINE
typedef enum plat_dev_id {
PLAT_DEV_ID_INVALID = 0,
PLAT_DEV_ID_1,
PLAT_DEV_ID_2,
PLAT_DEV_ID_3,
PLAT_DEV_ID_4,
PLAT_DEV_ID_5,
// ....
PLAT_DEV_ID_MAX = 128,
} plat_dev_id_t;
typedef struct plat_dev_desc {
char *name;
// i2c dev
int bus;
uint8_t addr;
} plat_dev_desc_t;
extern int plat_dev_id_is_valid (plat_dev_id_t id);
extern int plat_dev_get_byte (plat_dev_id_t id, uint8_t reg);
extern int plat_dev_set_byte (plat_dev_id_t id, uint8_t reg, uint8_t val);
////////////////////////////////////////////////////////////////
// CPLD PLAT ROUTINE
typedef enum plat_cpld_id {
PLAT_CPLD_ID_INVALID = 0,
PLAT_CPLD_ID_1,
PLAT_CPLD_ID_2,
PLAT_CPLD_ID_3,
PLAT_CPLD_ID_4,
PLAT_CPLD_ID_MAX,
} plat_cpld_id_t ;
typedef struct plat_cpld {
plat_dev_id_t id;
uint8_t cached[256];
uint8_t cache[256];
} plat_cpld_t;
extern int cpld_id_is_valid (plat_cpld_id_t id);
extern int cpld_get (plat_cpld_id_t id, uint8_t reg);
extern int cpld_set (plat_cpld_id_t id, uint8_t reg, uint8_t val);
extern int cpld_field_get (plat_cpld_id_t id, uint8_t reg, uint8_t field, uint8_t len);
extern int cpld_field_set (plat_cpld_id_t id, uint8_t reg, uint8_t field, uint8_t len, uint8_t val);
#define CPLD_CPUPLD PLAT_CPLD_ID_1
#define CPLD_SWPLD PLAT_CPLD_ID_2
////////////////////////////////////////////////////////////////
// CPLD REG PLAT ROUTINE
typedef struct cpld_reg {
plat_cpld_id_t id;
uint8_t reg;
uint8_t field;
uint8_t len;
char valid;
} cpld_reg_t;
#define CPLD_REG(i,r,f,l) {.valid=1, .id=i,.reg=r,.field=f,.len=l,}
extern int cpld_reg_is_valid (cpld_reg_t *r);
extern int cpld_reg_get (cpld_reg_t *r);
extern int cpld_reg_set (cpld_reg_t *r, uint8_t val);
////////////////////////////////////////////////////////////////
// THERMAL PLAT ROUTINE
typedef enum plat_thermal_id {
PLAT_THERMAL_ID_INVALID,
PLAT_THERMAL_ID_1 = 1,
PLAT_THERMAL_ID_2,
PLAT_THERMAL_ID_3,
PLAT_THERMAL_ID_4,
PLAT_THERMAL_ID_5,
PLAT_THERMAL_ID_6,
PLAT_THERMAL_ID_7,
PLAT_THERMAL_ID_MAX
} plat_thermal_id_t;
typedef struct plat_thermal {
char *desc;
hook_present present;
void *present_data;
char *temp_get_path;
char *warnning_set_path;
int def_warnning;
char *critical_set_path;
int def_critical;
char *shutdown_set_path;
int def_shutdown;
} plat_thermal_t ;
////////////////////////////////////////////////////////////////
// LED PLAT ROUTINE
typedef enum plat_led_id {
PLAT_LED_ID_INVALID = 0,
PLAT_LED_ID_1,
PLAT_LED_ID_2,
PLAT_LED_ID_3,
PLAT_LED_ID_4,
PLAT_LED_ID_5,
PLAT_LED_ID_6,
PLAT_LED_ID_7,
PLAT_LED_ID_MAX
} plat_led_id_t ;
typedef struct led_mode {
int onlp_val;
int hw_val;
} led_mode_t;
#define PLAT_LED_MODE_MAX 16
#define PLAT_LED_MODE(o,h) { .onlp_val = o, .hw_val = h, }
#define PLAT_LED_MODE_END { .onlp_val = -1, .hw_val = -1, }
#define PLAT_LED_INTERNAL_DEF \
.hw_val_run = -1
typedef struct plat_led {
char *name;
hook_present present;
void *present_data;
cpld_reg_t hw;
int hw_val_run;
led_mode_t mode[PLAT_LED_MODE_MAX];
} plat_led_t;
////////////////////////////////////////////////////////////////
// FAN PLAT ROUTINE
typedef enum plat_fan_id {
PLAT_FAN_ID_INVALID = 0,
PLAT_FAN_ID_1,
PLAT_FAN_ID_2,
PLAT_FAN_ID_3,
PLAT_FAN_ID_4,
PLAT_FAN_ID_5,
PLAT_FAN_ID_6,
PLAT_FAN_ID_7,
PLAT_FAN_ID_8,
PLAT_FAN_ID_MAX,
} plat_fan_id_t ;
typedef enum plat_fan_state {
PLAT_FAN_STATE_UNPRESENT = 0,
PLAT_FAN_STATE_PRESENT,
} plat_fan_state_t;
typedef enum plat_fan_event {
PLAT_FAN_EVENT_UNPLUG = 0,
PLAT_FAN_EVENT_PLUGIN,
} plat_fan_event_t ;
typedef struct plat_fan {
char *name;
hook_present present;
void *present_data;
char *rpm_get_path;
char *rpm_set_path;
int def_rpm;
char *per_get_path;
char *per_set_path;
int def_per;
char *eeprom_path;
uint32_t caps;
// internal use
int rpm_set_value;
int per_set_value;
plat_fan_state_t state;
hook_event event_callback;
uint8_t eeprom[256];
} plat_fan_t;
#define PLAT_FAN_INTERNAL_DEF \
.rpm_set_value = -1,\
.per_set_value = -1,\
.state = PLAT_FAN_STATE_UNPRESENT
extern int plat_fan_state_update (plat_fan_t *fan);
////////////////////////////////////////////////////////////////
// SFP PLAT ROUTINE
typedef enum plat_sff_id {
PLAT_SFF_ID_MIN = 1,
PLAT_SFF_ID_MAX = 32,
} plat_sff_id_t;
typedef int (*hook_sff_control)(void *e, int sval, int *gval, int *sup);
typedef struct plat_sff {
char valid;
hook_present present;
cpld_reg_t present_cpld_reg;
hook_sff_control reset;
cpld_reg_t reset_cpld_reg;
hook_sff_control lpmode;
cpld_reg_t lpmode_cpld_reg;
hook_sff_control rxlos;
cpld_reg_t rxlos_cpld_reg;
hook_sff_control txfault;
cpld_reg_t txfault_cpld_reg;
hook_sff_control txdisable;
cpld_reg_t txdisable_cpld_reg;
int bus;
} plat_sff_t;
////////////////////////////////////////////////////////////////
// PSU PLAT ROUTINE
typedef enum plat_psu_id {
PLAT_PSU_ID_INVALID = 0,
PLAT_PSU_ID_1,
PLAT_PSU_ID_2,
PLAT_PSU_ID_MAX
} plat_psu_id_t;
typedef enum plat_psu_state {
PLAT_PSU_STATE_UNPRESENT = 0,
PLAT_PSU_STATE_PRESENT,
PLAT_PSU_STATE_PMBUS_READY,
PLAT_PSU_STATE_MAX
} plat_psu_state_t;
typedef enum plat_psu_event {
PLAT_PSU_EVENT_UNPLUG = 0,
PLAT_PSU_EVENT_PLUGIN,
PLAT_PSU_PMBUS_CONNECT,
PLAT_PSU_PMBUS_DISCONNECT,
LAT_PSU_EVENT_
} plat_psu_event_t;
typedef struct plat_psu {
char *name;
hook_present present;
cpld_reg_t present_cpld_reg;
char *vin_path;
char *vout_path;
char *iin_path;
char *iout_path;
char *pin_path;
char *pout_path;
char *vin_max_path;
char *vin_min_path;
hook_event event_callback;
char eeprom_bus;
char eeprom_addr;
// use for probe and insmod
plat_psu_state_t state;
char *pmbus_insert_cmd;
char *pmbus_remove_cmd;
char *pmbus_ready_path;
uint8_t pmbus_bus;
uint8_t pmbus_addr;
uint8_t eeprom[256];
} plat_psu_t;
extern int plat_psu_state_update (plat_psu_t *psu);
////////////////////////////////////////////////////////////////
// OS HELP ROUTINE
extern int plat_os_file_is_existed (char *path);
extern int plat_os_file_read (uint8_t *data, int max, int *len, char *path, ...);
extern int plat_os_file_read_int (int *val, char *path, ...);
extern int plat_os_file_write_int(int val, char *path, ...);
#endif // __PLAT_LIB_H__

View File

@@ -0,0 +1,283 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlplib/file.h>
#include <onlp/platformi/psui.h>
#include "eeprom_drv.h"
#include "eeprom_info.h"
#include "platform_lib.h"
static int _psu_present (void *e);
static int _psu_event (void *e, int ev);
static plat_psu_t plat_psus[] = {
[PLAT_PSU_ID_1] = {
.name = "PSU1",
.present = _psu_present,
.present_cpld_reg = CPLD_REG (CPLD_CPUPLD, 0x1a, 6, 1),
.vin_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/in1_input",
.iin_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/curr1_input",
.pin_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/power1_input",
.vout_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/in2_input",
.iout_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/curr2_input",
.pout_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/power2_input",
.vin_max_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/in1_max",
.vin_min_path = "/sys/bus/i2c/devices/4-0058/hwmon/*/in1_min",
.eeprom_bus = 4,
.eeprom_addr= 0x50,
.event_callback = _psu_event,
.state = PLAT_PSU_STATE_UNPRESENT,
.pmbus_insert_cmd = "echo pmbus 0x58 > /sys/bus/i2c/devices/i2c-4/new_device",
.pmbus_remove_cmd = "echo 0x58 > /sys/bus/i2c/devices/i2c-4/delete_device",
.pmbus_ready_path = "/sys/bus/i2c/devices/4-0058/hwmon",
.pmbus_bus = 4,
.pmbus_addr = 0x58,
},
[PLAT_PSU_ID_2] = {
.name = "PSU2",
.present = _psu_present,
.present_cpld_reg = CPLD_REG (CPLD_CPUPLD, 0x1a, 7, 1),
.vin_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/in1_input",
.iin_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/curr1_input",
.pin_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/power1_input",
.vout_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/in2_input",
.iout_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/curr2_input",
.pout_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/power2_input",
.vin_max_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/in1_max",
.vin_min_path = "/sys/bus/i2c/devices/4-0059/hwmon/*/in1_min",
.eeprom_bus = 4,
.eeprom_addr= 0x51,
.event_callback = _psu_event,
.state = PLAT_PSU_STATE_UNPRESENT,
.pmbus_insert_cmd = "echo pmbus 0x59 > /sys/bus/i2c/devices/i2c-4/new_device",
.pmbus_remove_cmd = "echo 0x59 > /sys/bus/i2c/devices/i2c-4/delete_device",
.pmbus_ready_path = "/sys/bus/i2c/devices/4-0059/hwmon",
.pmbus_bus = 4,
.pmbus_addr = 0x59,
},
};
#define plat_psus_size (sizeof(plat_psus)/sizeof(plat_psus[0]))
static int plat_psu_is_valid (int id)
{
plat_psu_t *psu;
if (id < 0 && id >= plat_psus_size)
return 0;
psu = &plat_psus[id];
if (psu->name)
return 1;
return 0;
}
static int _psu_present (void *e)
{
plat_psu_t *psu = e;
return cpld_reg_get (&psu->present_cpld_reg) == 0 ? 1 : 0;
}
static int _psu_event (void *e, int ev)
{
plat_psu_t *psu = e;
switch (ev) {
case PLAT_PSU_PMBUS_CONNECT:
if (eeprom_read (psu->eeprom_bus, psu->eeprom_addr, 0, psu->eeprom, sizeof(psu->eeprom)))
memset (psu->eeprom, 0xff, sizeof(psu->eeprom));
break;
case PLAT_PSU_PMBUS_DISCONNECT:
memset (psu->eeprom, 0xff, sizeof(psu->eeprom));
break;
case PLAT_PSU_EVENT_UNPLUG:
case PLAT_PSU_EVENT_PLUGIN:
default:
break;
}
return 0;
}
static uint32_t _psu_vin_type_guess (plat_psu_t *psu)
{
uint32_t ret;
int vmax = -1;
int vmin = -1;
if ((psu->vin_max_path) &&
(plat_os_file_read_int (&vmax, psu->vin_max_path, NULL) < 0))
vmax = -1;
if ((psu->vin_min_path) &&
(plat_os_file_read_int (&vmin, psu->vin_min_path, NULL) < 0))
vmin = -1;
ret = 0;
if (12000 > vmin && 12000 < vmax)
ret |= ONLP_PSU_CAPS_DC12;
if (48000 > vmin && 48000 < vmax)
ret |= ONLP_PSU_CAPS_DC48;
if (110000 > vmin && 110000 < vmax)
ret |= ONLP_PSU_CAPS_AC;
if (!ret)
ret |= ONLP_PSU_CAPS_AC;
return ret;
}
int
onlp_psui_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
{
int error ;
plat_psu_t *psu;
int present;
int pid= ONLP_OID_ID_GET(id);
if (!ONLP_OID_IS_PSU(id))
return ONLP_STATUS_E_INVALID;
if (!plat_psu_is_valid(pid))
return ONLP_STATUS_E_INVALID;
psu = &plat_psus[pid];
memset(info, 0, sizeof(onlp_psu_info_t));
info->hdr.id = id;
if (psu->name)
snprintf (info->hdr.description, sizeof(info->hdr.description), "%s", psu->name);
plat_psu_state_update (psu);
// check present;
present = psu->state != PLAT_PSU_STATE_UNPRESENT ? 1 : 0;
if (present) {
info->status |= ONLP_PSU_STATUS_PRESENT;
info->status &= ~ONLP_PSU_STATUS_UNPLUGGED;
} else {
info->status |= ONLP_PSU_STATUS_UNPLUGGED;
info->status &= ~ONLP_PSU_STATUS_PRESENT;
}
// unpresent will return directly
if (info->status & ONLP_PSU_STATUS_UNPLUGGED) {
return ONLP_STATUS_OK;
}
///////////////////////////////////////////////////////////////
// get caps
if (psu->vin_path && plat_os_file_is_existed(psu->vin_path)) info->caps |= ONLP_PSU_CAPS_VIN;
if (psu->iin_path && plat_os_file_is_existed(psu->iin_path)) info->caps |= ONLP_PSU_CAPS_IIN;
if (psu->pin_path && plat_os_file_is_existed(psu->pin_path)) info->caps |= ONLP_PSU_CAPS_PIN;
if (psu->vout_path && plat_os_file_is_existed(psu->vout_path)) info->caps |= ONLP_PSU_CAPS_VOUT;
if (psu->iout_path && plat_os_file_is_existed(psu->iout_path)) info->caps |= ONLP_PSU_CAPS_IOUT;
if (psu->pout_path && plat_os_file_is_existed(psu->pout_path)) info->caps |= ONLP_PSU_CAPS_POUT;
//// TODO : auto detect AC / DC type
// we do a guess
info->caps |= _psu_vin_type_guess (psu);
// get psu info
eeprom_info_get (psu->eeprom, sizeof(psu->eeprom), "psu_model", info->model);
eeprom_info_get (psu->eeprom, sizeof(psu->eeprom), "psu_series", info->serial);
///////////////////////////////////////////////////////////////
// get and check value
error = 0;
if (info->caps & ONLP_PSU_CAPS_VIN) {
if (psu->state != PLAT_PSU_STATE_PMBUS_READY) {
info->status |= ONLP_PSU_STATUS_FAILED;
} else {
if (plat_os_file_read_int(&info->mvin, psu->vin_path, NULL) < 0) {
error ++;
} else {
if (info->mvin < 2)
info->status |= ONLP_PSU_STATUS_FAILED;
}
}
}
//// If VIN is not ok, skip other
if ((info->status & ONLP_PSU_STATUS_FAILED) == 0) {
if (info->caps & ONLP_PSU_CAPS_IIN) {
if (plat_os_file_read_int(&info->miin, psu->iin_path, NULL) < 0)
error ++;
}
if (info->caps & ONLP_PSU_CAPS_PIN) {
if (plat_os_file_read_int(&info->mpin, psu->pin_path, NULL) < 0)
error ++;
else
info->mpin = info->mpin / 1000;
}
if (info->caps & ONLP_PSU_CAPS_VOUT) {
if (plat_os_file_read_int(&info->mvout, psu->vout_path, NULL) < 0) {
error ++;
} else {
if (info->mvout < 2)
info->status |= ONLP_PSU_STATUS_FAILED;
}
}
if (info->caps & ONLP_PSU_CAPS_IOUT) {
if (plat_os_file_read_int(&info->miout, psu->iout_path, NULL) < 0)
error ++;
}
if (info->caps & ONLP_PSU_CAPS_POUT) {
if (plat_os_file_read_int(&info->mpout, psu->pout_path, NULL) < 0)
error ++;
else
info->mpout = info->mpout / 1000;
}
} // if ((info->status & ONLP_PSU_STATUS_FAILED) == 0)
return error ? ONLP_STATUS_E_INTERNAL : ONLP_STATUS_OK;
}
int
onlp_psui_ioctl(onlp_oid_t pid, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,501 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/sfpi.h>
#include "platform_lib.h"
static int _sff_present (void *e);
static int _sff_lpmode (void *e, int sval, int *gval, int *sup);
static int _sff_reset (void *e, int sval, int *gval, int *sup);
static int _sff8636_txdisable (void *e, int sval, int *gval, int *sup);
static plat_sff_t plat_sffs[] = {
[PLAT_SFF_ID_MIN] = {
.valid = 1,
.present = _sff_present,
.present_cpld_reg = CPLD_REG(CPLD_SWPLD, 0x0d, 0, 1),
.lpmode = _sff_lpmode,
.lpmode_cpld_reg = CPLD_REG(CPLD_SWPLD, 0x09, 0, 1),
.reset = _sff_reset,
.reset_cpld_reg = CPLD_REG(CPLD_SWPLD, 0x11, 0, 1),
.txdisable = _sff8636_txdisable,
.bus = 6,
},
// total 32 port .... init in onlp_sfpi_init
[PLAT_SFF_ID_MAX] = {
.valid = 1,
},
};
static int _sff_present (void *e)
{
int val;
plat_sff_t *sff = e;
val = cpld_reg_get (&sff->present_cpld_reg);
/*
* Return 1 if present.
* Return 0 if not present.
* Return < 0 if error.
*/
if (val < 0)
return val;
return val ? 0 : 1;
}
static int _sff_lpmode (void *e, int sval, int *gval, int *sup)
{
plat_sff_t *sff = e;
if (sup) {
if (cpld_reg_is_valid(&sff->lpmode_cpld_reg))
*sup = 1;
}
if (gval)
*gval = cpld_reg_get (&sff->lpmode_cpld_reg);
if (sval >= 0)
cpld_reg_set (&sff->lpmode_cpld_reg, sval ? 1 : 0);
return ONLP_STATUS_OK;
}
static int _sff_reset (void *e, int sval, int *gval, int *sup)
{
plat_sff_t *sff = e;
if (sup) {
if (cpld_reg_is_valid(&sff->reset_cpld_reg))
*sup = 1;
}
if (gval) {
*gval = cpld_reg_get (&sff->reset_cpld_reg);
*gval = *gval ? 0 : 1;
}
if (sval >= 0) {
cpld_reg_set (&sff->reset_cpld_reg, sval ? 0 : 1);
}
return ONLP_STATUS_OK;
}
static int _sff8636_txdisable (void *e, int sval, int *gval, int *sup)
{
int ret = ONLP_STATUS_OK;
plat_sff_t *sff = e;
if (sup) {
*sup = 1;
}
if (gval) {
if (cpld_reg_is_valid(&sff->txdisable_cpld_reg)) {
*gval = cpld_reg_get (&sff->reset_cpld_reg);
} else {
// following sff8636 spec
ret = onlp_i2c_readb (sff->bus, 0x50, 86, ONLP_I2C_F_DISABLE_READ_RETRIES);
if (ret >= 0)
*gval = ret;
}
}
if (sval >= 0) {
if (cpld_reg_is_valid(&sff->txdisable_cpld_reg)) {
cpld_reg_set (&sff->reset_cpld_reg, sval ? 1 : 0);
} else {
// following sff8636 spec
ret = onlp_i2c_writeb (sff->bus, 0x50, 86, sval, 0);
}
}
return ret;
}
static int _sff_is_valid (int p)
{
plat_sff_t *sff;
if (p >= PLAT_SFF_ID_MIN && p <= PLAT_SFF_ID_MAX) {
sff = &plat_sffs[p];
if (sff->valid)
return 1;
}
return 0;
}
/************************************************************
*
* SFPI Entry Points
*
***********************************************************/
int
onlp_sfpi_init(void)
{
int p;
plat_sff_t *base = &plat_sffs[PLAT_SFF_ID_MIN];
plat_sff_t *sff;
for (p = PLAT_SFF_ID_MIN + 1; p <= PLAT_SFF_ID_MAX ; p ++) {
sff = &plat_sffs[p];
sff->valid = 1;
// .present_cpld_reg
sff->present = base->present;
sff->present_cpld_reg.id = base->present_cpld_reg.id;
sff->present_cpld_reg.reg = base->present_cpld_reg.reg - (p - 1) / 8;
sff->present_cpld_reg.field = base->present_cpld_reg.field + (p - 1) % 8;
sff->present_cpld_reg.len = base->present_cpld_reg.len;
sff->present_cpld_reg.valid = 1,
// .lpmode
sff->lpmode = base->lpmode;
sff->lpmode_cpld_reg.id = base->lpmode_cpld_reg.id;
sff->lpmode_cpld_reg.reg = base->lpmode_cpld_reg.reg - (p - 1) / 8;
sff->lpmode_cpld_reg.field = base->lpmode_cpld_reg.field + (p - 1) % 8;
sff->lpmode_cpld_reg.len = base->lpmode_cpld_reg.len;
sff->lpmode_cpld_reg.valid = 1,
// .reset
sff->reset = base->reset;
sff->reset_cpld_reg.id = base->reset_cpld_reg.id;
sff->reset_cpld_reg.reg = base->reset_cpld_reg.reg - (p - 1) / 8;
sff->reset_cpld_reg.field = base->reset_cpld_reg.field + (p - 1) % 8;
sff->reset_cpld_reg.len = base->reset_cpld_reg.len;
sff->reset_cpld_reg.valid = 1,
//.txdisable
sff->txdisable = base->txdisable;
// bus
sff->bus = base->bus + p - 1;
}
/* Called at initialization time */
return ONLP_STATUS_OK;
}
int
onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap)
{
int p;
for (p = PLAT_SFF_ID_MIN ; p <= PLAT_SFF_ID_MAX ; p++) {
if (_sff_is_valid (p))
AIM_BITMAP_SET(bmap, p);
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_is_present(int port)
{
plat_sff_t *sff;
/*
* Return 1 if present.
* Return 0 if not present.
* Return < 0 if error.
*/
if (!_sff_is_valid (port))
return -1;
sff = &plat_sffs[port];
if (sff->present == NULL) {
// If not present, it means it is present always.
return 1;
}
return sff->present (sff);
}
static int _sff_read_eeprom (int port, uint8_t devaddr, uint8_t *data)
{
/*
* Read the SFP eeprom into data[]
*
* Return MISSING if SFP is missing.
* Return OK if eeprom is read
*/
plat_sff_t *sff;
int i;
memset(data, 0, 256);
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
if (onlp_sfpi_is_present(port) <= 0)
{
return ONLP_STATUS_E_MISSING;
}
sff = &plat_sffs[port];
for (i = 0 ; i < (256/ONLPLIB_CONFIG_I2C_BLOCK_SIZE); i++) {
if (onlp_i2c_block_read (sff->bus, devaddr,
ONLPLIB_CONFIG_I2C_BLOCK_SIZE * i,
ONLPLIB_CONFIG_I2C_BLOCK_SIZE,
&data [ONLPLIB_CONFIG_I2C_BLOCK_SIZE * i],
0) < 0)
{
return ONLP_STATUS_E_INTERNAL;
}
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
{
return _sff_read_eeprom (port, 0x50, data);
}
int
onlp_sfpi_dom_read(int port, uint8_t data[256])
{
return _sff_read_eeprom (port, 0x51, data);
}
int onlp_sfpi_dev_readb(int port, uint8_t devaddr, uint8_t addr)
{
plat_sff_t *sff;
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
if (onlp_sfpi_is_present(port) <= 0)
{
return ONLP_STATUS_E_MISSING;
}
sff = &plat_sffs[port];
return onlp_i2c_readb (sff->bus, devaddr, addr, 0);
}
int onlp_sfpi_dev_writeb(int port, uint8_t devaddr, uint8_t addr, uint8_t value)
{
plat_sff_t *sff;
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
if (onlp_sfpi_is_present(port) <= 0)
{
return ONLP_STATUS_E_MISSING;
}
sff = &plat_sffs[port];
return onlp_i2c_writeb (sff->bus, devaddr, addr, value, 0);
}
int onlp_sfpi_dev_readw(int port, uint8_t devaddr, uint8_t addr)
{
plat_sff_t *sff;
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
if (onlp_sfpi_is_present(port) <= 0)
{
return ONLP_STATUS_E_MISSING;
}
sff = &plat_sffs[port];
return onlp_i2c_readw (sff->bus, devaddr, addr, 0);
}
int onlp_sfpi_dev_writew(int port, uint8_t devaddr, uint8_t addr, uint16_t value)
{
plat_sff_t *sff;
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
if (onlp_sfpi_is_present(port) <= 0)
{
return ONLP_STATUS_E_MISSING;
}
sff = &plat_sffs[port];
return onlp_i2c_readw (sff->bus, devaddr, addr, 0);
}
int onlp_sfpi_presence_bitmap_get (onlp_sfp_bitmap_t* dst)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
int onlp_sfpi_control_supported(int port, onlp_sfp_control_t control, int* rv)
{
plat_sff_t *sff;
*rv = 0;
if (control > ONLP_SFP_CONTROL_LAST)
return ONLP_STATUS_OK;
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
sff = &plat_sffs[port];
switch (control) {
case ONLP_SFP_CONTROL_RESET_STATE:
case ONLP_SFP_CONTROL_RESET:
if (sff->reset) sff->reset (sff, -1, NULL, rv);
break;
case ONLP_SFP_CONTROL_RX_LOS:
if (sff->rxlos) sff->rxlos (sff, -1, NULL, rv);
break;
case ONLP_SFP_CONTROL_TX_FAULT:
if (sff->txfault) sff->txfault (sff, -1, NULL, rv);
break;
case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL:
case ONLP_SFP_CONTROL_TX_DISABLE:
if (sff->txdisable) sff->txdisable (sff, -1, NULL, rv);
break;
case ONLP_SFP_CONTROL_LP_MODE:
if (sff->lpmode) sff->lpmode (sff, -1, NULL, rv);
break;
case ONLP_SFP_CONTROL_POWER_OVERRIDE:
default:
break;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
{
plat_sff_t *sff;
if (control > ONLP_SFP_CONTROL_LAST)
return ONLP_STATUS_E_UNSUPPORTED;
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
sff = &plat_sffs[port];
switch (control) {
case ONLP_SFP_CONTROL_RESET:
if (sff->reset) return sff->reset (sff, value, NULL, NULL);
break;
case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL:
case ONLP_SFP_CONTROL_TX_DISABLE:
if (sff->txdisable) return sff->txdisable (sff, value, NULL, NULL);
break;
case ONLP_SFP_CONTROL_LP_MODE:
if (sff->lpmode) return sff->lpmode (sff, value, NULL, NULL);
break;
default:
break;
}
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
{
plat_sff_t *sff;
if (control > ONLP_SFP_CONTROL_LAST)
return ONLP_STATUS_E_UNSUPPORTED;
if (!_sff_is_valid(port)) {
return ONLP_STATUS_E_INVALID;
}
sff = &plat_sffs[port];
switch (control) {
case ONLP_SFP_CONTROL_RESET_STATE:
case ONLP_SFP_CONTROL_RESET:
if (sff->reset) return sff->reset (sff, -1, value, NULL);
break;
case ONLP_SFP_CONTROL_TX_DISABLE_CHANNEL:
case ONLP_SFP_CONTROL_TX_DISABLE:
if (sff->txdisable) return sff->txdisable (sff, -1, value, NULL);
break;
case ONLP_SFP_CONTROL_LP_MODE:
if (sff->lpmode) return sff->lpmode (sff, -1, value, NULL);
break;
case ONLP_SFP_CONTROL_RX_LOS:
if (sff->rxlos) return sff->rxlos (sff, -1, value, NULL);
break;
case ONLP_SFP_CONTROL_TX_FAULT:
if (sff->txfault) return sff->txfault (sff, -1, value, NULL);
break;
default:
break;
}
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_sfpi_denit(void)
{
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,230 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <onlplib/file.h>
#include <onlp/platformi/sysi.h>
#include <onlp/platformi/ledi.h>
#include <onlp/platformi/thermali.h>
#include <onlp/platformi/fani.h>
#include <onlp/platformi/psui.h>
#include "platform_lib.h"
//platform_id_t platform_id = PLATFORM_ID_UNKNOWN;
//#define ONIE_PLATFORM_NAME "x86-64-delta-ag8032-r0"
const char*
onlp_sysi_platform_get(void)
{
return "x86-64-delta-ag8032-r0";
}
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
char buff[128];
cpld_reg_t CpuBoardHwVer = CPLD_REG(CPLD_CPUPLD, 0x02, 4, 4);
cpld_reg_t CpuBoardPldVer = CPLD_REG(CPLD_CPUPLD, 0x01, 0, 4);
cpld_reg_t MainBoardHwVer = CPLD_REG(CPLD_SWPLD, 0x00, 0, 4);
cpld_reg_t MainBoardPldVer = CPLD_REG(CPLD_SWPLD, 0x01, 0, 4);
snprintf (buff, sizeof(buff), "CpuBoardPldVer=%d,MainBoardPldVer=%d",
cpld_reg_get(&CpuBoardPldVer),
cpld_reg_get(&MainBoardPldVer));
pi->cpld_versions = aim_fstrdup("%s", buff);
snprintf (buff, sizeof(buff), "CpuBoardHwVer=%d,MainBoardHwVer=%d",
cpld_reg_get(&CpuBoardHwVer),
cpld_reg_get(&MainBoardHwVer));
pi->other_versions = aim_fstrdup("%s", buff);
return 0;
}
int
onlp_sysi_onie_data_get(uint8_t** data, int* size)
{
uint8_t* rdata = aim_zmalloc(256);
if(!rdata){
return ONLP_STATUS_E_INTERNAL;
}
*data = rdata;
if(onlp_file_read(rdata, 256, size, ONIE_EEPROM_LOCATION) == ONLP_STATUS_OK) {
if(*size == 256) {
*data = rdata;
return ONLP_STATUS_OK;
}
}
aim_free(rdata);
*size = 0;
return ONLP_STATUS_E_UNSUPPORTED;
}
void
onlp_sysi_onie_data_free(uint8_t* data)
{
aim_free(data);
}
int
onlp_sysi_oids_get(onlp_oid_t* table, int max)
{
int i;
onlp_oid_t* e = table;
memset(table, 0, max*sizeof(onlp_oid_t));
/* Thermal sensors on the platform */
for (i = PLAT_THERMAL_ID_1; i < PLAT_THERMAL_ID_MAX; i++) {
*e++ = ONLP_THERMAL_ID_CREATE(i);
}
/* LEDs on the platform */
for (i = PLAT_LED_ID_1; i < PLAT_LED_ID_MAX; i++) {
*e++ = ONLP_LED_ID_CREATE(i);
}
/* Fans on the platform */
for (i = PLAT_FAN_ID_1; i < PLAT_FAN_ID_MAX; i++) {
*e++ = ONLP_FAN_ID_CREATE(i);
}
/* PSUs on the platform */
for (i = PLAT_PSU_ID_1; i < PLAT_PSU_ID_MAX; i++) {
*e++ = ONLP_PSU_ID_CREATE(i);
}
return 0;
}
int
onlp_sysi_onie_info_get(onlp_onie_info_t* onie)
{
onie->platform_name = aim_strdup("x86-64-delta_ag8032-r0");
return ONLP_STATUS_OK;
}
int
onlp_sysi_platform_manage_fans(void)
{
onlp_thermal_info_t thermal;
int i;
int temp_max;
int rpm;
temp_max = 0;
for (i = PLAT_THERMAL_ID_1 ; i <= PLAT_THERMAL_ID_5; i ++) {
if (onlp_thermali_info_get (ONLP_THERMAL_ID_CREATE(i), &thermal) == ONLP_STATUS_OK)
if (thermal.mcelsius > temp_max)
temp_max = thermal.mcelsius;
}
rpm = 7500;
if((temp_max >= 30000) && (temp_max < 40000)) rpm =10000;
if((temp_max >= 45000) && (temp_max < 55000)) rpm =13000;
if((temp_max >= 60000) && (temp_max < 75000)) rpm =16000;
if( temp_max >= 80000) rpm =19000;
for (i = PLAT_FAN_ID_1 ; i <= PLAT_FAN_ID_6 ; i ++) {
onlp_fani_rpm_set (ONLP_FAN_ID_CREATE(i), rpm);
}
return ONLP_STATUS_OK;
}
int
onlp_sysi_platform_manage_leds(void)
{
onlp_fan_info_t fan;
onlp_psu_info_t psu;
int i;
uint32_t status;
int led_setting;
int global_fail;
// fan tray led
global_fail = 0;
for (i = 0 ; i < 3 ; i ++) {
status = 0;
if (onlp_fani_info_get (ONLP_FAN_ID_CREATE(PLAT_FAN_ID_1 + i * 2 + 0),
&fan) == ONLP_STATUS_OK) {
status |= fan.status;
}
if (onlp_fani_info_get (ONLP_FAN_ID_CREATE(PLAT_FAN_ID_1 + i * 2 + 1),
&fan) == ONLP_STATUS_OK) {
status |= fan.status;
}
led_setting = ONLP_LED_MODE_GREEN;
if (status & ONLP_FAN_STATUS_FAILED) {
led_setting = ONLP_LED_MODE_ORANGE;
global_fail ++;
} else if ((status & ONLP_FAN_STATUS_PRESENT) == 0) {
led_setting = ONLP_LED_MODE_OFF;
global_fail ++;
}
printf ("fuck 111111111111 %d led_setting=%d \n", i, led_setting);
onlp_ledi_mode_set (ONLP_LED_ID_CREATE (PLAT_LED_ID_5 + i), led_setting);
}
// fans led (front fan led)
onlp_ledi_mode_set (ONLP_LED_ID_CREATE (PLAT_LED_ID_2),
global_fail ? ONLP_LED_MODE_ORANGE : ONLP_LED_MODE_GREEN);
// pwr1 led (front)
led_setting = ONLP_LED_MODE_ORANGE;
if (onlp_psui_info_get (ONLP_PSU_ID_CREATE(PLAT_PSU_ID_1), &psu) == ONLP_STATUS_OK) {
if (psu.status & ONLP_PSU_STATUS_FAILED)
led_setting = ONLP_LED_MODE_ORANGE;
else if ((psu.status & ONLP_PSU_STATUS_PRESENT) == 0)
led_setting = ONLP_LED_MODE_OFF;
else
led_setting = ONLP_LED_MODE_GREEN;
}
onlp_ledi_mode_set (ONLP_LED_ID_CREATE (PLAT_LED_ID_3), led_setting);
// pwr2 led (front)
led_setting = ONLP_LED_MODE_ORANGE;
if (onlp_psui_info_get (ONLP_PSU_ID_CREATE(PLAT_PSU_ID_2), &psu) == ONLP_STATUS_OK) {
if (psu.status & ONLP_PSU_STATUS_FAILED)
led_setting = ONLP_LED_MODE_ORANGE;
else if ((psu.status & ONLP_PSU_STATUS_PRESENT) == 0)
led_setting = ONLP_LED_MODE_OFF;
else
led_setting = ONLP_LED_MODE_GREEN;
}
onlp_ledi_mode_set (ONLP_LED_ID_CREATE (PLAT_LED_ID_4), led_setting);
// sys
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,265 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Thermal Sensor Platform Implementation.
*
***********************************************************/
#include <onlplib/file.h>
#include <onlp/platformi/thermali.h>
#include "platform_lib.h"
static int _psu_thermal_present (void *e);
////////////////////////////////////////////////////////////////
// THERMALS PLAT CONFIG
static plat_thermal_t plat_thermals[] = {
[PLAT_THERMAL_ID_1] = {
.desc = "Thermal Sensor %d - close to cpu",
.temp_get_path = "/sys/bus/i2c/devices/0-0048/hwmon/*/temp1_input",
.warnning_set_path = "/sys/bus/i2c/devices/0-0048/hwmon/*/temp1_max_hyst",
.critical_set_path = NULL,
.shutdown_set_path = "/sys/bus/i2c/devices/0-0048/hwmon/*/temp1_max",
.def_warnning = ONLP_THERMAL_THRESHOLD_WARNING_DEFAULT,
.def_critical = ONLP_THERMAL_THRESHOLD_ERROR_DEFAULT,
.def_shutdown = ONLP_THERMAL_THRESHOLD_SHUTDOWN_DEFAULT,
},
[PLAT_THERMAL_ID_2] = {
.desc = "Thermal Sensor %d - Main Board (U54)",
.temp_get_path = "/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_input",
.warnning_set_path = "/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_max_hyst",
.critical_set_path = NULL,
.shutdown_set_path = "/sys/bus/i2c/devices/2-004a/hwmon/*/temp1_max",
.def_warnning = ONLP_THERMAL_THRESHOLD_WARNING_DEFAULT,
.def_critical = ONLP_THERMAL_THRESHOLD_ERROR_DEFAULT,
.def_shutdown = ONLP_THERMAL_THRESHOLD_SHUTDOWN_DEFAULT,
},
[PLAT_THERMAL_ID_3] = {
.desc = "Thermal Sensor %d - BCM chip Bottom (U70)",
.temp_get_path = "/sys/bus/i2c/devices/2-004c/hwmon/*/temp1_input",
.warnning_set_path = "/sys/bus/i2c/devices/2-004c/hwmon/*/temp1_max_hyst",
.critical_set_path = NULL,
.shutdown_set_path = "/sys/bus/i2c/devices/2-004c/hwmon/*/temp1_max",
.def_warnning = ONLP_THERMAL_THRESHOLD_WARNING_DEFAULT,
.def_critical = ONLP_THERMAL_THRESHOLD_ERROR_DEFAULT,
.def_shutdown = ONLP_THERMAL_THRESHOLD_SHUTDOWN_DEFAULT,
},
[PLAT_THERMAL_ID_4] = {
.desc = "Thermal Sensor %d - BCM chip Top (U71)",
.temp_get_path = "/sys/bus/i2c/devices/2-004d/hwmon/*/temp1_input",
.warnning_set_path = "/sys/bus/i2c/devices/2-004d/hwmon/*/temp1_max_hyst",
.critical_set_path = NULL,
.shutdown_set_path = "/sys/bus/i2c/devices/2-004d/hwmon/*/temp1_max",
.def_warnning = ONLP_THERMAL_THRESHOLD_WARNING_DEFAULT,
.def_critical = ONLP_THERMAL_THRESHOLD_ERROR_DEFAULT,
.def_shutdown = ONLP_THERMAL_THRESHOLD_SHUTDOWN_DEFAULT,
},
[PLAT_THERMAL_ID_5] = {
.desc = "Thermal Sensor %d - Cpu Core",
.temp_get_path = "/sys/devices/platform/coretemp.0/hwmon/*/temp2_input",
.warnning_set_path = "/sys/devices/platform/coretemp.0/hwmon/*/temp2_crit",
.critical_set_path = NULL,
.shutdown_set_path = "/sys/devices/platform/coretemp.0/hwmon/*/temp2_max",
.def_warnning = 0,
.def_critical = 0,
.def_shutdown = 0,
},
[PLAT_THERMAL_ID_6] = {
.desc = "Thermal Sensor %d - PSU1",
.present = _psu_thermal_present,
.temp_get_path = "/sys/bus/i2c/devices/i2c-4/4-0058/hwmon/*/temp1_input",
.shutdown_set_path = "/sys/bus/i2c/devices/i2c-4/4-0058/hwmon/*/temp1_max",
.def_warnning = 0,
.def_critical = 0,
.def_shutdown = 0,
},
[PLAT_THERMAL_ID_7] = {
.desc = "Thermal Sensor %d - PSU2",
.present = _psu_thermal_present,
.temp_get_path = "/sys/bus/i2c/devices/i2c-4/4-0059/hwmon/*/temp1_input",
.shutdown_set_path = "/sys/bus/i2c/devices/i2c-4/4-0059/hwmon/*/temp1_max",
.def_warnning = 0,
.def_critical = 0,
.def_shutdown = 0,
},
};
#define plat_thermals_size (sizeof(plat_thermals)/sizeof(plat_thermals[0]))
static int _psu_thermal_present (void *e)
{
plat_thermal_t *thermal = e;
return plat_os_file_is_existed (thermal->temp_get_path) ? 1 : 0;
}
static int plat_thermal_is_valid (int id)
{
plat_thermal_t *thermal;
if (id < 0 && id >= plat_thermals_size)
return 0;
thermal = &plat_thermals[id];
if (thermal->temp_get_path || thermal->desc)
return 1;
return 0;
}
int onlp_thermali_init(void)
{
int i;
plat_thermal_t *thermal;
for (i = 0 ; i < plat_thermals_size ; i ++) {
if (!plat_thermal_is_valid (i))
continue;
thermal = &plat_thermals[i];
if (thermal->warnning_set_path && thermal->def_warnning)
plat_os_file_write_int (thermal->def_warnning, thermal->warnning_set_path, NULL);
if (thermal->critical_set_path && thermal->def_critical)
plat_os_file_write_int (thermal->def_critical, thermal->critical_set_path, NULL);
if (thermal->shutdown_set_path && thermal->def_shutdown)
plat_os_file_write_int (thermal->def_shutdown, thermal->shutdown_set_path, NULL);
}
return ONLP_STATUS_OK;
}
/*
* Retrieve the information structure for the given thermal OID.
*
* If the OID is invalid, return ONLP_E_STATUS_INVALID.
* If an unexpected error occurs, return ONLP_E_STATUS_INTERNAL.
* Otherwise, return ONLP_STATUS_OK with the OID's information.
*
* Note -- it is expected that you fill out the information
* structure even if the sensor described by the OID is not present.
*/
int
onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
{
int tid;
int present = 1;
plat_thermal_t *thermal;
int value;
int error;
if (!ONLP_OID_IS_THERMAL(id))
return ONLP_STATUS_E_INVALID;
tid = ONLP_OID_ID_GET(id);
if (!plat_thermal_is_valid(tid))
return ONLP_STATUS_E_INVALID;
thermal = &plat_thermals[tid];
if (thermal->present) {
present = thermal->present(thermal) ? 1 : 0;
}
memset (info, 0, sizeof(*info));
// fix onlp_thermal_info_t
info->hdr.id = id;
if (thermal->desc)
snprintf (info->hdr.description, sizeof(info->hdr.description), thermal->desc, tid);
if (thermal->temp_get_path)
info->caps |= ONLP_THERMAL_CAPS_GET_TEMPERATURE;
if (thermal->warnning_set_path || thermal->def_warnning)
info->caps |= ONLP_THERMAL_CAPS_GET_WARNING_THRESHOLD;
if (thermal->critical_set_path || thermal->def_critical)
info->caps |= ONLP_THERMAL_CAPS_GET_ERROR_THRESHOLD;
if (thermal->shutdown_set_path || thermal->def_shutdown)
info->caps |= ONLP_THERMAL_CAPS_GET_SHUTDOWN_THRESHOLD;
// Get value
error = 0;
if (info->caps & ONLP_THERMAL_CAPS_GET_TEMPERATURE) {
if (plat_os_file_read_int(&value, thermal->temp_get_path, NULL) < 0)
error ++;
else
info->mcelsius = value;
}
if (info->caps & ONLP_THERMAL_CAPS_GET_WARNING_THRESHOLD) {
if (thermal->warnning_set_path) {
if (plat_os_file_read_int(&value, thermal->warnning_set_path, NULL) < 0)
error ++;
else
info->thresholds.warning = value;
} else {
info->thresholds.warning = thermal->def_warnning;
}
}
if (info->caps & ONLP_THERMAL_CAPS_GET_ERROR_THRESHOLD) {
if (thermal->critical_set_path) {
if (plat_os_file_read_int(&value, thermal->critical_set_path, NULL) < 0)
error ++;
else
info->thresholds.error = value;
} else {
info->thresholds.error = thermal->def_critical;
}
}
if (info->caps & ONLP_THERMAL_CAPS_GET_SHUTDOWN_THRESHOLD) {
if (thermal->shutdown_set_path) {
if (plat_os_file_read_int(&value, thermal->shutdown_set_path, NULL) < 0)
error ++;
else
info->thresholds.shutdown = value;
} else {
info->thresholds.shutdown = thermal->def_shutdown;
}
}
if (present)
info->status |= ONLP_THERMAL_STATUS_PRESENT;
// check threshold
if (info->caps & ONLP_THERMAL_CAPS_GET_TEMPERATURE) {
if (info->caps & ONLP_THERMAL_CAPS_GET_ERROR_THRESHOLD) {
if (info->mcelsius >= info->thresholds.error) {
info->status |= ONLP_THERMAL_STATUS_FAILED;
}
}
if (info->caps & ONLP_THERMAL_CAPS_GET_SHUTDOWN_THRESHOLD) {
if (info->mcelsius >= info->thresholds.shutdown) {
info->status |= ONLP_THERMAL_STATUS_FAILED;
}
}
}
return error ? ONLP_STATUS_E_INTERNAL : ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,81 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag8032/x86_64_delta_ag8032_config.h>
/* <auto.start.cdefs(X86_64_DELTA_AG8032_CONFIG_HEADER).source> */
#define __x86_64_delta_ag8032_config_STRINGIFY_NAME(_x) #_x
#define __x86_64_delta_ag8032_config_STRINGIFY_VALUE(_x) __x86_64_delta_ag8032_config_STRINGIFY_NAME(_x)
x86_64_delta_ag8032_config_settings_t x86_64_delta_ag8032_config_settings[] =
{
#ifdef X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING) },
#else
{ X86_64_DELTA_AG8032_CONFIG_INCLUDE_LOGGING(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT) },
#else
{ X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT) },
#else
{ X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT) },
#else
{ X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB) },
#else
{ X86_64_DELTA_AG8032_CONFIG_PORTING_STDLIB(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS) },
#else
{ X86_64_DELTA_AG8032_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI) },
#else
{ X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
{ __x86_64_delta_ag8032_config_STRINGIFY_NAME(X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION), __x86_64_delta_ag8032_config_STRINGIFY_VALUE(X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION) },
#else
{ X86_64_DELTA_AG8032_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION(__x86_64_delta_ag8032_config_STRINGIFY_NAME), "__undefined__" },
#endif
{ NULL, NULL }
};
#undef __x86_64_delta_ag8032_config_STRINGIFY_VALUE
#undef __x86_64_delta_ag8032_config_STRINGIFY_NAME
const char*
x86_64_delta_ag8032_config_lookup(const char* setting)
{
int i;
for(i = 0; x86_64_delta_ag8032_config_settings[i].name; i++) {
if(strcmp(x86_64_delta_ag8032_config_settings[i].name, setting)) {
return x86_64_delta_ag8032_config_settings[i].value;
}
}
return NULL;
}
int
x86_64_delta_ag8032_config_show(struct aim_pvs_s* pvs)
{
int i;
for(i = 0; x86_64_delta_ag8032_config_settings[i].name; i++) {
aim_printf(pvs, "%s = %s\n", x86_64_delta_ag8032_config_settings[i].name, x86_64_delta_ag8032_config_settings[i].value);
}
return i;
}
/* <auto.end.cdefs(X86_64_DELTA_AG8032_CONFIG_HEADER).source> */

View File

@@ -0,0 +1,10 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag8032/x86_64_delta_ag8032_config.h>
/* <--auto.start.enum(ALL).source> */
/* <auto.end.enum(ALL).source> */

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
* x86_64_delta_ag8032 Internal Header
*
*****************************************************************************/
#ifndef __x86_64_delta_ag8032_INT_H__
#define __x86_64_delta_ag8032_INT_H__
#include <x86_64_delta_ag8032/x86_64_delta_ag8032_config.h>
#endif /* __x86_64_delta_ag8032_INT_H__ */

View File

@@ -0,0 +1,18 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag8032/x86_64_delta_ag8032_config.h>
#include "x86_64_delta_ag8032_log.h"
/*
* x86_64_delta_ag8032 log struct.
*/
AIM_LOG_STRUCT_DEFINE(
X86_64_DELTA_AG8032_CONFIG_LOG_OPTIONS_DEFAULT,
X86_64_DELTA_AG8032_CONFIG_LOG_BITS_DEFAULT,
NULL, /* Custom log map */
X86_64_DELTA_AG8032_CONFIG_LOG_CUSTOM_BITS_DEFAULT
);

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#ifndef __x86_64_delta_ag8032_LOG_H__
#define __x86_64_delta_ag8032_LOG_H__
#define AIM_LOG_MODULE_NAME x86_64_delta_ag8032
#include <AIM/aim_log.h>
#endif /* __x86_64_delta_ag8032_LOG_H__ */

View File

@@ -0,0 +1,24 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag8032/x86_64_delta_ag8032_config.h>
#include "x86_64_delta_ag8032_log.h"
static int
datatypes_init__(void)
{
#define x86_64_delta_ag8032_ENUMERATION_ENTRY(_enum_name, _desc) AIM_DATATYPE_MAP_REGISTER(_enum_name, _enum_name##_map, _desc, AIM_LOG_INTERNAL);
#include <x86_64_delta_ag8032/x86_64_delta_ag8032.x>
return 0;
}
void __x86_64_delta_ag8032_module_init__(void)
{
AIM_LOG_STRUCT_REGISTER();
datatypes_init__();
}
int __onlp_platform_version__ = 1;

View File

@@ -0,0 +1,50 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag8032/x86_64_delta_ag8032_config.h>
#if X86_64_DELTA_AG8032_CONFIG_INCLUDE_UCLI == 1
#include <uCli/ucli.h>
#include <uCli/ucli_argparse.h>
#include <uCli/ucli_handler_macros.h>
static ucli_status_t
x86_64_delta_ag8032_ucli_ucli__config__(ucli_context_t* uc)
{
UCLI_HANDLER_MACRO_MODULE_CONFIG(x86_64_delta_ag8032)
}
/* <auto.ucli.handlers.start> */
/* <auto.ucli.handlers.end> */
static ucli_module_t
x86_64_delta_ag8032_ucli_module__ =
{
"x86_64_delta_ag8032_ucli",
NULL,
x86_64_delta_ag8032_ucli_ucli_handlers__,
NULL,
NULL,
};
ucli_node_t*
x86_64_delta_ag8032_ucli_node_create(void)
{
ucli_node_t* n;
ucli_module_init(&x86_64_delta_ag8032_ucli_module__);
n = ucli_node_create("x86_64_delta_ag8032", NULL, &x86_64_delta_ag8032_ucli_module__);
ucli_node_subnode_add(n, ucli_module_log_node_create("x86_64_delta_ag8032"));
return n;
}
#else
void*
x86_64_delta_ag8032_ucli_node_create(void)
{
return NULL;
}
#endif

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=delta BASENAME=x86-64-delta-ag8032 REVISION=r0

View File

@@ -0,0 +1,34 @@
---
######################################################################
#
# platform-config for AG8032
#
######################################################################
x86-64-delta-ag8032-r0:
grub:
serial: >-
--port=0x2f8
--speed=115200
--word=8
--parity=no
--stop=1
kernel:
<<: *kernel-4-9
args: >-
nopat
acpi=off
console=ttyS1,115200n8
i2c_dev_auto_detect=0
tsc=reliable
##network
## interfaces:
## ma1:
## name: ~
## syspath: pci0000:00/0000:00:14.0

View File

@@ -0,0 +1,34 @@
from onl.platform.base import *
from onl.platform.delta import *
class OnlPlatform_x86_64_delta_ag8032_r0(OnlPlatformDelta,OnlPlatformPortConfig_32x40):
PLATFORM='x86-64-delta-ag8032-r0'
MODEL="AG8032"
SYS_OBJECT_ID=".8032.1"
def baseconfig(self):
self.insmod('/lib/modules/4.9.75-OpenNetworkLinux/kernel/drivers/i2c/busses/i2c-ismt.ko')
self.insmod('/lib/modules/4.9.75-OpenNetworkLinux/kernel/drivers/misc/eeprom/at24.ko')
self.insmod('x86-64-delta-ag8032-i2c-mux-setting.ko')
self.insmod('x86-64-delta-ag8032-i2c-mux-cpld.ko')
self.new_i2c_devices(
[
('tmp75', 0x48, 0),
('tmp75', 0x4a, 2),
('tmp75', 0x4c, 2),
('tmp75', 0x4d, 2),
('24c02', 0x51, 2),
('24c02', 0x52, 2),
('24c02', 0x53, 2),
('24c08', 0x54, 5),
('max6620', 0x29, 2),
('max6620', 0x2a, 2),
('at24c02', 0x50, 4),
]
)
return True