linux/drivers/hwmon/lineage-pem.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for Lineage Compact Power Line series of power entry modules.
 *
 * Copyright (C) 2010, 2011 Ericsson AB.
 *
 * Documentation:
 *  http://www.lineagepower.com/oem/pdf/CPLI2C.pdf
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>

/*
 * This driver supports various Lineage Compact Power Line DC/DC and AC/DC
 * converters such as CP1800, CP2000AC, CP2000DC, CP2100DC, and others.
 *
 * The devices are nominally PMBus compliant. However, most standard PMBus
 * commands are not supported. Specifically, all hardware monitoring and
 * status reporting commands are non-standard. For this reason, a standard
 * PMBus driver can not be used.
 *
 * All Lineage CPL devices have a built-in I2C bus master selector (PCA9541).
 * To ensure device access, this driver should only be used as client driver
 * to the pca9541 I2C master selector driver.
 */

/* Command codes */
#define PEM_OPERATION
#define PEM_CLEAR_INFO_FLAGS
#define PEM_VOUT_COMMAND
#define PEM_VOUT_OV_FAULT_LIMIT
#define PEM_READ_DATA_STRING
#define PEM_READ_INPUT_STRING
#define PEM_READ_FIRMWARE_REV
#define PEM_READ_RUN_TIMER
#define PEM_FAN_HI_SPEED
#define PEM_FAN_NORMAL_SPEED
#define PEM_READ_FAN_SPEED

/* offsets in data string */
#define PEM_DATA_STATUS_2
#define PEM_DATA_STATUS_1
#define PEM_DATA_ALARM_2
#define PEM_DATA_ALARM_1
#define PEM_DATA_VOUT_LSB
#define PEM_DATA_VOUT_MSB
#define PEM_DATA_CURRENT
#define PEM_DATA_TEMP

/* Virtual entries, to report constants */
#define PEM_DATA_TEMP_MAX
#define PEM_DATA_TEMP_CRIT

/* offsets in input string */
#define PEM_INPUT_VOLTAGE
#define PEM_INPUT_POWER_LSB
#define PEM_INPUT_POWER_MSB

/* offsets in fan data */
#define PEM_FAN_ADJUSTMENT
#define PEM_FAN_FAN1
#define PEM_FAN_FAN2
#define PEM_FAN_FAN3

/* Status register bits */
#define STS1_OUTPUT_ON
#define STS1_LEDS_FLASHING
#define STS1_EXT_FAULT
#define STS1_SERVICE_LED_ON
#define STS1_SHUTDOWN_OCCURRED
#define STS1_INT_FAULT
#define STS1_ISOLATION_TEST_OK

#define STS2_ENABLE_PIN_HI
#define STS2_DATA_OUT_RANGE
#define STS2_RESTARTED_OK
#define STS2_ISOLATION_TEST_FAIL
#define STS2_HIGH_POWER_CAP
#define STS2_INVALID_INSTR
#define STS2_WILL_RESTART
#define STS2_PEC_ERR

/* Alarm register bits */
#define ALRM1_VIN_OUT_LIMIT
#define ALRM1_VOUT_OUT_LIMIT
#define ALRM1_OV_VOLT_SHUTDOWN
#define ALRM1_VIN_OVERCURRENT
#define ALRM1_TEMP_WARNING
#define ALRM1_TEMP_SHUTDOWN
#define ALRM1_PRIMARY_FAULT
#define ALRM1_POWER_LIMIT

#define ALRM2_5V_OUT_LIMIT
#define ALRM2_TEMP_FAULT
#define ALRM2_OV_LOW
#define ALRM2_DCDC_TEMP_HIGH
#define ALRM2_PRI_TEMP_HIGH
#define ALRM2_NO_PRIMARY
#define ALRM2_FAN_FAULT

#define FIRMWARE_REV_LEN
#define DATA_STRING_LEN
#define INPUT_STRING_LEN
#define FAN_SPEED_LEN

struct pem_data {};

static int pem_read_block(struct i2c_client *client, u8 command, u8 *data,
			  int data_len)
{}

static struct pem_data *pem_update_device(struct device *dev)
{}

static long pem_get_data(u8 *data, int len, int index)
{}

static long pem_get_input(u8 *data, int len, int index)
{}

static long pem_get_fan(u8 *data, int len, int index)
{}

/*
 * Show boolean, either a fault or an alarm.
 * .nr points to the register, .index is the bit mask to check
 */
static ssize_t pem_bool_show(struct device *dev, struct device_attribute *da,
			     char *buf)
{}

static ssize_t pem_data_show(struct device *dev, struct device_attribute *da,
			     char *buf)
{}

static ssize_t pem_input_show(struct device *dev, struct device_attribute *da,
			      char *buf)
{}

static ssize_t pem_fan_show(struct device *dev, struct device_attribute *da,
			    char *buf)
{}

/* Voltages */
static SENSOR_DEVICE_ATTR_RO(in1_input, pem_data, PEM_DATA_VOUT_LSB);
static SENSOR_DEVICE_ATTR_2_RO(in1_alarm, pem_bool, PEM_DATA_ALARM_1,
			       ALRM1_VOUT_OUT_LIMIT);
static SENSOR_DEVICE_ATTR_2_RO(in1_crit_alarm, pem_bool, PEM_DATA_ALARM_1,
			       ALRM1_OV_VOLT_SHUTDOWN);
static SENSOR_DEVICE_ATTR_RO(in2_input, pem_input, PEM_INPUT_VOLTAGE);
static SENSOR_DEVICE_ATTR_2_RO(in2_alarm, pem_bool, PEM_DATA_ALARM_1,
			       ALRM1_VIN_OUT_LIMIT | ALRM1_PRIMARY_FAULT);

/* Currents */
static SENSOR_DEVICE_ATTR_RO(curr1_input, pem_data, PEM_DATA_CURRENT);
static SENSOR_DEVICE_ATTR_2_RO(curr1_alarm, pem_bool, PEM_DATA_ALARM_1,
			       ALRM1_VIN_OVERCURRENT);

/* Power */
static SENSOR_DEVICE_ATTR_RO(power1_input, pem_input, PEM_INPUT_POWER_LSB);
static SENSOR_DEVICE_ATTR_2_RO(power1_alarm, pem_bool, PEM_DATA_ALARM_1,
			       ALRM1_POWER_LIMIT);

/* Fans */
static SENSOR_DEVICE_ATTR_RO(fan1_input, pem_fan, PEM_FAN_FAN1);
static SENSOR_DEVICE_ATTR_RO(fan2_input, pem_fan, PEM_FAN_FAN2);
static SENSOR_DEVICE_ATTR_RO(fan3_input, pem_fan, PEM_FAN_FAN3);
static SENSOR_DEVICE_ATTR_2_RO(fan1_alarm, pem_bool, PEM_DATA_ALARM_2,
			       ALRM2_FAN_FAULT);

/* Temperatures */
static SENSOR_DEVICE_ATTR_RO(temp1_input, pem_data, PEM_DATA_TEMP);
static SENSOR_DEVICE_ATTR_RO(temp1_max, pem_data, PEM_DATA_TEMP_MAX);
static SENSOR_DEVICE_ATTR_RO(temp1_crit, pem_data, PEM_DATA_TEMP_CRIT);
static SENSOR_DEVICE_ATTR_2_RO(temp1_alarm, pem_bool, PEM_DATA_ALARM_1,
			       ALRM1_TEMP_WARNING);
static SENSOR_DEVICE_ATTR_2_RO(temp1_crit_alarm, pem_bool, PEM_DATA_ALARM_1,
			       ALRM1_TEMP_SHUTDOWN);
static SENSOR_DEVICE_ATTR_2_RO(temp1_fault, pem_bool, PEM_DATA_ALARM_2,
			       ALRM2_TEMP_FAULT);

static struct attribute *pem_attributes[] =;

static const struct attribute_group pem_group =;

static struct attribute *pem_input_attributes[] =;

static const struct attribute_group pem_input_group =;

static struct attribute *pem_fan_attributes[] =;

static const struct attribute_group pem_fan_group =;

static int pem_probe(struct i2c_client *client)
{}

static const struct i2c_device_id pem_id[] =;
MODULE_DEVICE_TABLE(i2c, pem_id);

static struct i2c_driver pem_driver =;

module_i2c_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();