mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-25 09:17:08 +00:00
support the AG8032 platfrom
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
@@ -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
|
||||
|
||||
2
packages/platforms/delta/x86-64/x86-64-delta-ag8032/.gitignore
vendored
Normal file
2
packages/platforms/delta/x86-64/x86-64-delta-ag8032/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*x86*64*delta*ag8032*.mk
|
||||
onlpdump.mk
|
||||
@@ -0,0 +1 @@
|
||||
include $(ONL)/make/pkg.mk
|
||||
@@ -0,0 +1 @@
|
||||
include $(ONL)/make/pkg.mk
|
||||
@@ -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"
|
||||
1
packages/platforms/delta/x86-64/x86-64-delta-ag8032/modules/builds/.gitignore
vendored
Normal file
1
packages/platforms/delta/x86-64/x86-64-delta-ag8032/modules/builds/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
lib
|
||||
@@ -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
|
||||
@@ -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");
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
include $(ONL)/make/pkg.mk
|
||||
@@ -0,0 +1 @@
|
||||
!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-delta-ag8032 ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu
|
||||
@@ -0,0 +1,2 @@
|
||||
FILTER=src
|
||||
include $(ONL)/make/subdirs.mk
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
name: x86_64_delta_ag8032
|
||||
@@ -0,0 +1,9 @@
|
||||
###############################################################################
|
||||
#
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
include ../../init.mk
|
||||
MODULE := x86_64_delta_ag8032
|
||||
AUTOMODULE := x86_64_delta_ag8032
|
||||
include $(BUILDER)/definemodule.mk
|
||||
@@ -0,0 +1,6 @@
|
||||
###############################################################################
|
||||
#
|
||||
# x86_64_delta_ag8032 README
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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> */
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
/* @} */
|
||||
@@ -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__ */
|
||||
@@ -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__ */
|
||||
/* @} */
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Local source generation targets.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ucli:
|
||||
@../../../../tools/uclihandlers.py x86_64_delta_ag8032_ucli.c
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
###############################################################################
|
||||
#
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
LIBRARY := x86_64_delta_ag8032
|
||||
$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
include $(BUILDER)/lib.mk
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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> */
|
||||
|
||||
@@ -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> */
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
include $(ONL)/make/pkg.mk
|
||||
@@ -0,0 +1 @@
|
||||
include $(ONL)/make/pkg.mk
|
||||
@@ -0,0 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=delta BASENAME=x86-64-delta-ag8032 REVISION=r0
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user