brintos

brintos / linux-shallow public Read only

0
0
Text · 4.8 KiB · 5d5b6ae Raw
195 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Hardware monitoring driver for Maxim MAX86884 *5 * Copyright (c) 2011 Ericsson AB.6 */7 8#include <linux/bitops.h>9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/init.h>12#include <linux/err.h>13#include <linux/i2c.h>14#include "pmbus.h"15 16#define MAX8688_MFR_VOUT_PEAK		0xd417#define MAX8688_MFR_IOUT_PEAK		0xd518#define MAX8688_MFR_TEMPERATURE_PEAK	0xd619#define MAX8688_MFG_STATUS		0xd820 21#define MAX8688_STATUS_OC_FAULT		BIT(4)22#define MAX8688_STATUS_OV_FAULT		BIT(5)23#define MAX8688_STATUS_OV_WARNING	BIT(8)24#define MAX8688_STATUS_UV_FAULT		BIT(9)25#define MAX8688_STATUS_UV_WARNING	BIT(10)26#define MAX8688_STATUS_UC_FAULT		BIT(11)27#define MAX8688_STATUS_OC_WARNING	BIT(12)28#define MAX8688_STATUS_OT_FAULT		BIT(13)29#define MAX8688_STATUS_OT_WARNING	BIT(14)30 31static int max8688_read_word_data(struct i2c_client *client, int page,32				  int phase, int reg)33{34	int ret;35 36	if (page > 0)37		return -ENXIO;38 39	switch (reg) {40	case PMBUS_VIRT_READ_VOUT_MAX:41		ret = pmbus_read_word_data(client, 0, 0xff,42					   MAX8688_MFR_VOUT_PEAK);43		break;44	case PMBUS_VIRT_READ_IOUT_MAX:45		ret = pmbus_read_word_data(client, 0, 0xff,46					   MAX8688_MFR_IOUT_PEAK);47		break;48	case PMBUS_VIRT_READ_TEMP_MAX:49		ret = pmbus_read_word_data(client, 0, 0xff,50					   MAX8688_MFR_TEMPERATURE_PEAK);51		break;52	case PMBUS_VIRT_RESET_VOUT_HISTORY:53	case PMBUS_VIRT_RESET_IOUT_HISTORY:54	case PMBUS_VIRT_RESET_TEMP_HISTORY:55		ret = 0;56		break;57	default:58		ret = -ENODATA;59		break;60	}61	return ret;62}63 64static int max8688_write_word_data(struct i2c_client *client, int page, int reg,65				   u16 word)66{67	int ret;68 69	switch (reg) {70	case PMBUS_VIRT_RESET_VOUT_HISTORY:71		ret = pmbus_write_word_data(client, 0, MAX8688_MFR_VOUT_PEAK,72					    0);73		break;74	case PMBUS_VIRT_RESET_IOUT_HISTORY:75		ret = pmbus_write_word_data(client, 0, MAX8688_MFR_IOUT_PEAK,76					    0);77		break;78	case PMBUS_VIRT_RESET_TEMP_HISTORY:79		ret = pmbus_write_word_data(client, 0,80					    MAX8688_MFR_TEMPERATURE_PEAK,81					    0xffff);82		break;83	default:84		ret = -ENODATA;85		break;86	}87	return ret;88}89 90static int max8688_read_byte_data(struct i2c_client *client, int page, int reg)91{92	int ret = 0;93	int mfg_status;94 95	if (page > 0)96		return -ENXIO;97 98	switch (reg) {99	case PMBUS_STATUS_VOUT:100		mfg_status = pmbus_read_word_data(client, 0, 0xff,101						  MAX8688_MFG_STATUS);102		if (mfg_status < 0)103			return mfg_status;104		if (mfg_status & MAX8688_STATUS_UV_WARNING)105			ret |= PB_VOLTAGE_UV_WARNING;106		if (mfg_status & MAX8688_STATUS_UV_FAULT)107			ret |= PB_VOLTAGE_UV_FAULT;108		if (mfg_status & MAX8688_STATUS_OV_WARNING)109			ret |= PB_VOLTAGE_OV_WARNING;110		if (mfg_status & MAX8688_STATUS_OV_FAULT)111			ret |= PB_VOLTAGE_OV_FAULT;112		break;113	case PMBUS_STATUS_IOUT:114		mfg_status = pmbus_read_word_data(client, 0, 0xff,115						  MAX8688_MFG_STATUS);116		if (mfg_status < 0)117			return mfg_status;118		if (mfg_status & MAX8688_STATUS_UC_FAULT)119			ret |= PB_IOUT_UC_FAULT;120		if (mfg_status & MAX8688_STATUS_OC_WARNING)121			ret |= PB_IOUT_OC_WARNING;122		if (mfg_status & MAX8688_STATUS_OC_FAULT)123			ret |= PB_IOUT_OC_FAULT;124		break;125	case PMBUS_STATUS_TEMPERATURE:126		mfg_status = pmbus_read_word_data(client, 0, 0xff,127						  MAX8688_MFG_STATUS);128		if (mfg_status < 0)129			return mfg_status;130		if (mfg_status & MAX8688_STATUS_OT_WARNING)131			ret |= PB_TEMP_OT_WARNING;132		if (mfg_status & MAX8688_STATUS_OT_FAULT)133			ret |= PB_TEMP_OT_FAULT;134		break;135	default:136		ret = -ENODATA;137		break;138	}139	return ret;140}141 142static struct pmbus_driver_info max8688_info = {143	.pages = 1,144	.format[PSC_VOLTAGE_IN] = direct,145	.format[PSC_VOLTAGE_OUT] = direct,146	.format[PSC_TEMPERATURE] = direct,147	.format[PSC_CURRENT_OUT] = direct,148	.m[PSC_VOLTAGE_IN] = 19995,149	.b[PSC_VOLTAGE_IN] = 0,150	.R[PSC_VOLTAGE_IN] = -1,151	.m[PSC_VOLTAGE_OUT] = 19995,152	.b[PSC_VOLTAGE_OUT] = 0,153	.R[PSC_VOLTAGE_OUT] = -1,154	.m[PSC_CURRENT_OUT] = 23109,155	.b[PSC_CURRENT_OUT] = 0,156	.R[PSC_CURRENT_OUT] = -2,157	.m[PSC_TEMPERATURE] = -7612,158	.b[PSC_TEMPERATURE] = 335,159	.R[PSC_TEMPERATURE] = -3,160	.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP161		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT162		| PMBUS_HAVE_STATUS_TEMP,163	.read_byte_data = max8688_read_byte_data,164	.read_word_data = max8688_read_word_data,165	.write_word_data = max8688_write_word_data,166};167 168static int max8688_probe(struct i2c_client *client)169{170	return pmbus_do_probe(client, &max8688_info);171}172 173static const struct i2c_device_id max8688_id[] = {174	{"max8688"},175	{ }176};177 178MODULE_DEVICE_TABLE(i2c, max8688_id);179 180/* This is the driver that will be inserted */181static struct i2c_driver max8688_driver = {182	.driver = {183		   .name = "max8688",184		   },185	.probe = max8688_probe,186	.id_table = max8688_id,187};188 189module_i2c_driver(max8688_driver);190 191MODULE_AUTHOR("Guenter Roeck");192MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688");193MODULE_LICENSE("GPL");194MODULE_IMPORT_NS(PMBUS);195