brintos

brintos / linux-shallow public Read only

0
0
Text · 3.7 KiB · 503be59 Raw
149 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Hardware monitoring driver for IR352214 *5 * Copyright (C) IBM Corporation 2017.6 */7 8#include <linux/err.h>9#include <linux/i2c.h>10#include <linux/init.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include "pmbus.h"14 15#define IR35221_MFR_VIN_PEAK		0xc516#define IR35221_MFR_VOUT_PEAK		0xc617#define IR35221_MFR_IOUT_PEAK		0xc718#define IR35221_MFR_TEMP_PEAK		0xc819#define IR35221_MFR_VIN_VALLEY		0xc920#define IR35221_MFR_VOUT_VALLEY		0xca21#define IR35221_MFR_IOUT_VALLEY		0xcb22#define IR35221_MFR_TEMP_VALLEY		0xcc23 24static int ir35221_read_word_data(struct i2c_client *client, int page,25				  int phase, int reg)26{27	int ret;28 29	switch (reg) {30	case PMBUS_VIRT_READ_VIN_MAX:31		ret = pmbus_read_word_data(client, page, phase,32					   IR35221_MFR_VIN_PEAK);33		break;34	case PMBUS_VIRT_READ_VOUT_MAX:35		ret = pmbus_read_word_data(client, page, phase,36					   IR35221_MFR_VOUT_PEAK);37		break;38	case PMBUS_VIRT_READ_IOUT_MAX:39		ret = pmbus_read_word_data(client, page, phase,40					   IR35221_MFR_IOUT_PEAK);41		break;42	case PMBUS_VIRT_READ_TEMP_MAX:43		ret = pmbus_read_word_data(client, page, phase,44					   IR35221_MFR_TEMP_PEAK);45		break;46	case PMBUS_VIRT_READ_VIN_MIN:47		ret = pmbus_read_word_data(client, page, phase,48					   IR35221_MFR_VIN_VALLEY);49		break;50	case PMBUS_VIRT_READ_VOUT_MIN:51		ret = pmbus_read_word_data(client, page, phase,52					   IR35221_MFR_VOUT_VALLEY);53		break;54	case PMBUS_VIRT_READ_IOUT_MIN:55		ret = pmbus_read_word_data(client, page, phase,56					   IR35221_MFR_IOUT_VALLEY);57		break;58	case PMBUS_VIRT_READ_TEMP_MIN:59		ret = pmbus_read_word_data(client, page, phase,60					   IR35221_MFR_TEMP_VALLEY);61		break;62	default:63		ret = -ENODATA;64		break;65	}66 67	return ret;68}69 70static int ir35221_probe(struct i2c_client *client)71{72	struct pmbus_driver_info *info;73	u8 buf[I2C_SMBUS_BLOCK_MAX];74	int ret;75 76	if (!i2c_check_functionality(client->adapter,77				     I2C_FUNC_SMBUS_READ_BYTE_DATA78				| I2C_FUNC_SMBUS_READ_WORD_DATA79				| I2C_FUNC_SMBUS_READ_BLOCK_DATA))80		return -ENODEV;81 82	ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);83	if (ret < 0) {84		dev_err(&client->dev, "Failed to read PMBUS_MFR_ID\n");85		return ret;86	}87	if (ret != 2 || strncmp(buf, "RI", strlen("RI"))) {88		dev_err(&client->dev, "MFR_ID unrecognised\n");89		return -ENODEV;90	}91 92	ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);93	if (ret < 0) {94		dev_err(&client->dev, "Failed to read PMBUS_MFR_MODEL\n");95		return ret;96	}97	if (ret != 2 || !(buf[0] == 0x6c && buf[1] == 0x00)) {98		dev_err(&client->dev, "MFR_MODEL unrecognised\n");99		return -ENODEV;100	}101 102	info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info),103			    GFP_KERNEL);104	if (!info)105		return -ENOMEM;106 107	info->read_word_data = ir35221_read_word_data;108 109	info->pages = 2;110	info->format[PSC_VOLTAGE_IN] = linear;111	info->format[PSC_VOLTAGE_OUT] = linear;112	info->format[PSC_CURRENT_IN] = linear;113	info->format[PSC_CURRENT_OUT] = linear;114	info->format[PSC_POWER] = linear;115	info->format[PSC_TEMPERATURE] = linear;116 117	info->func[0] = PMBUS_HAVE_VIN118		| PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN119		| PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN120		| PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP121		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT122		| PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP;123	info->func[1] = info->func[0];124 125	return pmbus_do_probe(client, info);126}127 128static const struct i2c_device_id ir35221_id[] = {129	{"ir35221"},130	{}131};132 133MODULE_DEVICE_TABLE(i2c, ir35221_id);134 135static struct i2c_driver ir35221_driver = {136	.driver = {137		.name	= "ir35221",138	},139	.probe		= ir35221_probe,140	.id_table	= ir35221_id,141};142 143module_i2c_driver(ir35221_driver);144 145MODULE_AUTHOR("Samuel Mendoza-Jonas <sam@mendozajonas.com");146MODULE_DESCRIPTION("PMBus driver for IR35221");147MODULE_LICENSE("GPL");148MODULE_IMPORT_NS(PMBUS);149