FILE
lt3074.c
File preview with syntax highlighting.
linux-6.19.14/drivers/hwmon/pmbus/lt3074.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, <3074_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.