File Index
Files and directories
Sign in
FILE

lt3074.c

File preview with syntax highlighting.

linux-6.19.14/drivers/hwmon/pmbus/lt3074.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Hardware monitoring driver for Analog Devices LT3074
  4 *
  5 * Copyright (C) 2025 Analog Devices, Inc.
  6 */
  7#include <linux/err.h>
  8#include <linux/i2c.h>
  9#include <linux/mod_devicetable.h>
 10#include <linux/module.h>
 11
 12#include "pmbus.h"
 13
 14#define LT3074_MFR_READ_VBIAS			0xc6
 15#define LT3074_MFR_BIAS_OV_WARN_LIMIT		0xc7
 16#define LT3074_MFR_BIAS_UV_WARN_LIMIT		0xc8
 17#define LT3074_MFR_SPECIAL_ID			0xe7
 18
 19#define LT3074_SPECIAL_ID_VALUE			0x1c1d
 20
 21static const struct regulator_desc __maybe_unused lt3074_reg_desc[] = {
 22	PMBUS_REGULATOR_ONE("regulator"),
 23};
 24
 25static int lt3074_read_word_data(struct i2c_client *client, int page,
 26				 int phase, int reg)
 27{
 28	switch (reg) {
 29	case PMBUS_VIRT_READ_VMON:
 30		return pmbus_read_word_data(client, page, phase,
 31					   LT3074_MFR_READ_VBIAS);
 32	case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
 33		return pmbus_read_word_data(client, page, phase,
 34					   LT3074_MFR_BIAS_UV_WARN_LIMIT);
 35	case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
 36		return pmbus_read_word_data(client, page, phase,
 37					   LT3074_MFR_BIAS_OV_WARN_LIMIT);
 38	default:
 39		return -ENODATA;
 40	}
 41}
 42
 43static int lt3074_write_word_data(struct i2c_client *client, int page,
 44				  int reg, u16 word)
 45{
 46	switch (reg) {
 47	case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
 48		return pmbus_write_word_data(client, 0,
 49					    LT3074_MFR_BIAS_UV_WARN_LIMIT,
 50					    word);
 51	case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
 52		return pmbus_write_word_data(client, 0,
 53					    LT3074_MFR_BIAS_OV_WARN_LIMIT,
 54					    word);
 55	default:
 56		return -ENODATA;
 57	}
 58}
 59
 60static struct pmbus_driver_info lt3074_info = {
 61	.pages = 1,
 62	.format[PSC_VOLTAGE_IN] = linear,
 63	.format[PSC_VOLTAGE_OUT] = linear,
 64	.format[PSC_CURRENT_OUT] = linear,
 65	.format[PSC_TEMPERATURE] = linear,
 66	.func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
 67		   PMBUS_HAVE_TEMP | PMBUS_HAVE_VMON |
 68		   PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
 69		   PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP,
 70	.read_word_data = lt3074_read_word_data,
 71	.write_word_data = lt3074_write_word_data,
 72#if IS_ENABLED(CONFIG_SENSORS_LT3074_REGULATOR)
 73	.num_regulators = 1,
 74	.reg_desc = lt3074_reg_desc,
 75#endif
 76};
 77
 78static int lt3074_probe(struct i2c_client *client)
 79{
 80	int ret;
 81	struct device *dev = &client->dev;
 82
 83	if (!i2c_check_functionality(client->adapter,
 84				     I2C_FUNC_SMBUS_READ_WORD_DATA))
 85		return -ENODEV;
 86
 87	ret = i2c_smbus_read_word_data(client, LT3074_MFR_SPECIAL_ID);
 88	if (ret < 0)
 89		return dev_err_probe(dev, ret, "Failed to read ID\n");
 90
 91	if (ret != LT3074_SPECIAL_ID_VALUE)
 92		return dev_err_probe(dev, -ENODEV, "ID mismatch\n");
 93
 94	return pmbus_do_probe(client, &lt3074_info);
 95}
 96
 97static const struct i2c_device_id lt3074_id[] = {
 98	{ "lt3074", 0 },
 99	{}
100};
101MODULE_DEVICE_TABLE(i2c, lt3074_id);
102
103static const struct of_device_id __maybe_unused lt3074_of_match[] = {
104	{ .compatible = "adi,lt3074" },
105	{}
106};
107MODULE_DEVICE_TABLE(of, lt3074_of_match);
108
109static struct i2c_driver lt3074_driver = {
110	.driver = {
111		.name = "lt3074",
112		.of_match_table = of_match_ptr(lt3074_of_match),
113	},
114	.probe = lt3074_probe,
115	.id_table = lt3074_id,
116};
117module_i2c_driver(lt3074_driver);
118
119MODULE_AUTHOR("Cedric Encarnacion <cedricjustine.encarnacion@analog.com>");
120MODULE_DESCRIPTION("PMBus driver for Analog Devices LT3074");
121MODULE_LICENSE("GPL");
122MODULE_IMPORT_NS("PMBUS");
~/ Read-only file preview.