#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/math64.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/pmbus.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/of.h>
#include <linux/thermal.h>
#include "pmbus.h"
#define PMBUS_ATTR_ALLOC_SIZE …
#define PMBUS_NAME_SIZE …
struct pmbus_sensor { … };
#define to_pmbus_sensor(_attr) …
struct pmbus_boolean { … };
#define to_pmbus_boolean(_attr) …
struct pmbus_label { … };
#define to_pmbus_label(_attr) …
#define PB_STATUS_MASK …
#define PB_REG_SHIFT …
#define PB_REG_MASK …
#define PB_PAGE_SHIFT …
#define PB_PAGE_MASK …
#define pb_reg_to_index(page, reg, mask) …
#define pb_index_to_page(index) …
#define pb_index_to_reg(index) …
#define pb_index_to_mask(index) …
struct pmbus_data { … };
struct pmbus_debugfs_entry { … };
static const int pmbus_fan_rpm_mask[] = …;
static const int pmbus_fan_config_registers[] = …;
static const int pmbus_fan_command_registers[] = …;
void pmbus_clear_cache(struct i2c_client *client)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
void pmbus_set_update(struct i2c_client *client, u8 reg, bool update)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
int pmbus_set_page(struct i2c_client *client, int page, int phase)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
int pmbus_write_byte(struct i2c_client *client, int page, u8 value)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value)
{ … }
int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg,
u16 word)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int pmbus_write_virt_reg(struct i2c_client *client, int page, int reg,
u16 word)
{ … }
static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg,
u16 word)
{ … }
static int _pmbus_write_byte_data(struct i2c_client *client, int page, int reg, u8 value)
{ … }
static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg)
{ … }
int pmbus_update_fan(struct i2c_client *client, int page, int id,
u8 config, u8 mask, u16 command)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
int pmbus_read_word_data(struct i2c_client *client, int page, int phase, u8 reg)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int pmbus_read_virt_reg(struct i2c_client *client, int page, int reg)
{ … }
static int _pmbus_read_word_data(struct i2c_client *client, int page,
int phase, int reg)
{ … }
static int __pmbus_read_word_data(struct i2c_client *client, int page, int reg)
{ … }
int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg,
u8 mask, u8 value)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int pmbus_read_block_data(struct i2c_client *client, int page, u8 reg,
char *data_buf)
{ … }
static struct pmbus_sensor *pmbus_find_sensor(struct pmbus_data *data, int page,
int reg)
{ … }
static int pmbus_get_fan_rate(struct i2c_client *client, int page, int id,
enum pmbus_fan_mode mode,
bool from_cache)
{ … }
int pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id,
enum pmbus_fan_mode mode)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
int pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id,
enum pmbus_fan_mode mode)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static void pmbus_clear_fault_page(struct i2c_client *client, int page)
{ … }
void pmbus_clear_faults(struct i2c_client *client)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int pmbus_check_status_cml(struct i2c_client *client)
{ … }
static bool pmbus_check_register(struct i2c_client *client,
int (*func)(struct i2c_client *client,
int page, int reg),
int page, int reg)
{ … }
static bool pmbus_check_status_register(struct i2c_client *client, int page)
{ … }
bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
bool pmbus_check_word_register(struct i2c_client *client, int page, int reg)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static bool __maybe_unused pmbus_check_block_register(struct i2c_client *client,
int page, int reg)
{ … }
const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int pmbus_get_status(struct i2c_client *client, int page, int reg)
{ … }
static void pmbus_update_sensor_data(struct i2c_client *client, struct pmbus_sensor *sensor)
{ … }
static long pmbus_reg2data_ieee754(struct pmbus_data *data,
struct pmbus_sensor *sensor)
{ … }
static s64 pmbus_reg2data_linear(struct pmbus_data *data,
struct pmbus_sensor *sensor)
{ … }
static s64 pmbus_reg2data_direct(struct pmbus_data *data,
struct pmbus_sensor *sensor)
{ … }
static s64 pmbus_reg2data_vid(struct pmbus_data *data,
struct pmbus_sensor *sensor)
{ … }
static s64 pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
{ … }
#define MAX_IEEE_MANTISSA …
#define MIN_IEEE_MANTISSA …
static u16 pmbus_data2reg_ieee754(struct pmbus_data *data,
struct pmbus_sensor *sensor, long val)
{ … }
#define MAX_LIN_MANTISSA …
#define MIN_LIN_MANTISSA …
static u16 pmbus_data2reg_linear(struct pmbus_data *data,
struct pmbus_sensor *sensor, s64 val)
{ … }
static u16 pmbus_data2reg_direct(struct pmbus_data *data,
struct pmbus_sensor *sensor, s64 val)
{ … }
static u16 pmbus_data2reg_vid(struct pmbus_data *data,
struct pmbus_sensor *sensor, s64 val)
{ … }
static u16 pmbus_data2reg(struct pmbus_data *data,
struct pmbus_sensor *sensor, s64 val)
{ … }
static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b,
int index)
{ … }
static ssize_t pmbus_show_boolean(struct device *dev,
struct device_attribute *da, char *buf)
{ … }
static ssize_t pmbus_show_sensor(struct device *dev,
struct device_attribute *devattr, char *buf)
{ … }
static ssize_t pmbus_set_sensor(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{ … }
static ssize_t pmbus_show_label(struct device *dev,
struct device_attribute *da, char *buf)
{ … }
static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr)
{ … }
static void pmbus_dev_attr_init(struct device_attribute *dev_attr,
const char *name,
umode_t mode,
ssize_t (*show)(struct device *dev,
struct device_attribute *attr,
char *buf),
ssize_t (*store)(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count))
{ … }
static void pmbus_attr_init(struct sensor_device_attribute *a,
const char *name,
umode_t mode,
ssize_t (*show)(struct device *dev,
struct device_attribute *attr,
char *buf),
ssize_t (*store)(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count),
int idx)
{ … }
static int pmbus_add_boolean(struct pmbus_data *data,
const char *name, const char *type, int seq,
struct pmbus_sensor *s1,
struct pmbus_sensor *s2,
u8 page, u16 reg, u16 mask)
{ … }
struct pmbus_thermal_data { … };
static int pmbus_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
{ … }
static const struct thermal_zone_device_ops pmbus_thermal_ops = …;
static int pmbus_thermal_add_sensor(struct pmbus_data *pmbus_data,
struct pmbus_sensor *sensor, int index)
{ … }
static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
const char *name, const char *type,
int seq, int page, int phase,
int reg,
enum pmbus_sensor_classes class,
bool update, bool readonly,
bool convert)
{ … }
static int pmbus_add_label(struct pmbus_data *data,
const char *name, int seq,
const char *lstring, int index, int phase)
{ … }
struct pmbus_limit_attr { … };
struct pmbus_sensor_attr { … };
static int pmbus_add_limit_attrs(struct i2c_client *client,
struct pmbus_data *data,
const struct pmbus_driver_info *info,
const char *name, int index, int page,
struct pmbus_sensor *base,
const struct pmbus_sensor_attr *attr)
{ … }
static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
struct pmbus_data *data,
const struct pmbus_driver_info *info,
const char *name,
int index, int page, int phase,
const struct pmbus_sensor_attr *attr,
bool paged)
{ … }
static bool pmbus_sensor_is_paged(const struct pmbus_driver_info *info,
const struct pmbus_sensor_attr *attr)
{ … }
static int pmbus_add_sensor_attrs(struct i2c_client *client,
struct pmbus_data *data,
const char *name,
const struct pmbus_sensor_attr *attrs,
int nattrs)
{ … }
static const struct pmbus_limit_attr vin_limit_attrs[] = …;
static const struct pmbus_limit_attr vmon_limit_attrs[] = …;
static const struct pmbus_limit_attr vout_limit_attrs[] = …;
static const struct pmbus_sensor_attr voltage_attributes[] = …;
static const struct pmbus_limit_attr iin_limit_attrs[] = …;
static const struct pmbus_limit_attr iout_limit_attrs[] = …;
static const struct pmbus_sensor_attr current_attributes[] = …;
static const struct pmbus_limit_attr pin_limit_attrs[] = …;
static const struct pmbus_limit_attr pout_limit_attrs[] = …;
static const struct pmbus_sensor_attr power_attributes[] = …;
static const struct pmbus_limit_attr temp_limit_attrs[] = …;
static const struct pmbus_limit_attr temp_limit_attrs2[] = …;
static const struct pmbus_limit_attr temp_limit_attrs3[] = …;
static const struct pmbus_sensor_attr temp_attributes[] = …;
static const int pmbus_fan_registers[] = …;
static const int pmbus_fan_status_registers[] = …;
static const u32 pmbus_fan_flags[] = …;
static const u32 pmbus_fan_status_flags[] = …;
static int pmbus_add_fan_ctrl(struct i2c_client *client,
struct pmbus_data *data, int index, int page, int id,
u8 config)
{ … }
static int pmbus_add_fan_attributes(struct i2c_client *client,
struct pmbus_data *data)
{ … }
struct pmbus_samples_attr { … };
struct pmbus_samples_reg { … };
static struct pmbus_samples_attr pmbus_samples_registers[] = …;
#define to_samples_reg(x) …
static ssize_t pmbus_show_samples(struct device *dev,
struct device_attribute *devattr, char *buf)
{ … }
static ssize_t pmbus_set_samples(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{ … }
static int pmbus_add_samples_attr(struct pmbus_data *data, int page,
struct pmbus_samples_attr *attr)
{ … }
static int pmbus_add_samples_attributes(struct i2c_client *client,
struct pmbus_data *data)
{ … }
static int pmbus_find_attributes(struct i2c_client *client,
struct pmbus_data *data)
{ … }
struct pmbus_class_attr_map { … };
static const struct pmbus_class_attr_map class_attr_map[] = …;
static int pmbus_read_coefficients(struct i2c_client *client,
struct pmbus_driver_info *info,
const struct pmbus_sensor_attr *attr)
{ … }
static int pmbus_init_coefficients(struct i2c_client *client,
struct pmbus_driver_info *info)
{ … }
static int pmbus_identify_common(struct i2c_client *client,
struct pmbus_data *data, int page)
{ … }
static int pmbus_read_status_byte(struct i2c_client *client, int page)
{ … }
static int pmbus_read_status_word(struct i2c_client *client, int page)
{ … }
static ssize_t pec_show(struct device *dev, struct device_attribute *dummy,
char *buf)
{ … }
static ssize_t pec_store(struct device *dev, struct device_attribute *dummy,
const char *buf, size_t count)
{ … }
static DEVICE_ATTR_RW(pec);
static void pmbus_remove_pec(void *dev)
{ … }
static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
struct pmbus_driver_info *info)
{ … }
struct pmbus_status_assoc { … };
struct pmbus_status_category { … };
static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[] = …;
static int _pmbus_is_enabled(struct i2c_client *client, u8 page)
{ … }
static int __maybe_unused pmbus_is_enabled(struct i2c_client *client, u8 page)
{ … }
#define to_dev_attr(_dev_attr) …
static void pmbus_notify(struct pmbus_data *data, int page, int reg, int flags)
{ … }
static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flags,
unsigned int *event, bool notify)
{ … }
static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flags,
unsigned int *event, bool notify)
{ … }
#if IS_ENABLED(CONFIG_REGULATOR)
static int pmbus_regulator_is_enabled(struct regulator_dev *rdev)
{ … }
static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable)
{ … }
static int pmbus_regulator_enable(struct regulator_dev *rdev)
{ … }
static int pmbus_regulator_disable(struct regulator_dev *rdev)
{ … }
static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
{ … }
static int pmbus_regulator_get_status(struct regulator_dev *rdev)
{ … }
static int pmbus_regulator_get_low_margin(struct i2c_client *client, int page)
{ … }
static int pmbus_regulator_get_high_margin(struct i2c_client *client, int page)
{ … }
static int pmbus_regulator_get_voltage(struct regulator_dev *rdev)
{ … }
static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
int max_uv, unsigned int *selector)
{ … }
static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
unsigned int selector)
{ … }
const struct regulator_ops pmbus_regulator_ops = …;
EXPORT_SYMBOL_NS_GPL(…);
static int pmbus_regulator_register(struct pmbus_data *data)
{ … }
static int pmbus_regulator_notify(struct pmbus_data *data, int page, int event)
{ … }
#else
static int pmbus_regulator_register(struct pmbus_data *data)
{
return 0;
}
static int pmbus_regulator_notify(struct pmbus_data *data, int page, int event)
{
return 0;
}
#endif
static int pmbus_write_smbalert_mask(struct i2c_client *client, u8 page, u8 reg, u8 val)
{ … }
static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
{ … }
static int pmbus_irq_setup(struct i2c_client *client, struct pmbus_data *data)
{ … }
static struct dentry *pmbus_debugfs_dir;
#if IS_ENABLED(CONFIG_DEBUG_FS)
static int pmbus_debugfs_get(void *data, u64 *val)
{ … }
DEFINE_DEBUGFS_ATTRIBUTE(…);
static int pmbus_debugfs_get_status(void *data, u64 *val)
{ … }
DEFINE_DEBUGFS_ATTRIBUTE(…);
static ssize_t pmbus_debugfs_mfr_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations pmbus_debugfs_ops_mfr = …;
static void pmbus_remove_debugfs(void *data)
{ … }
static int pmbus_init_debugfs(struct i2c_client *client,
struct pmbus_data *data)
{ … }
#else
static int pmbus_init_debugfs(struct i2c_client *client,
struct pmbus_data *data)
{
return 0;
}
#endif
int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
int pmbus_lock_interruptible(struct i2c_client *client)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
void pmbus_unlock(struct i2c_client *client)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int __init pmbus_core_init(void)
{ … }
static void __exit pmbus_core_exit(void)
{ … }
module_init(…) …;
module_exit(pmbus_core_exit);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;