1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * powr1220.c - Driver for the Lattice POWR1220 programmable power supply
4 * and monitor. Users can read all ADC inputs along with their labels
5 * using the sysfs nodes.
7 * Copyright (c) 2014 Echo360 https://www.echo360.com
8 * Scott Kanowitz <skanowitz@echo360.com> <scott.kanowitz@gmail.com>
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/jiffies.h>
15 #include <linux/i2c.h>
16 #include <linux/hwmon.h>
17 #include <linux/hwmon-sysfs.h>
18 #include <linux/err.h>
19 #include <linux/mutex.h>
20 #include <linux/delay.h>
23 #define ADC_MAX_LOW_MEASUREMENT_MV 2000
25 enum powr1xxx_chips { powr1014, powr1220 };
58 enum powr1220_adc_values {
73 MAX_POWR1220_ADC_VALUES
76 struct powr1220_data {
77 struct i2c_client *client;
78 struct mutex update_lock;
80 bool adc_valid[MAX_POWR1220_ADC_VALUES];
81 /* the next value is in jiffies */
82 unsigned long adc_last_updated[MAX_POWR1220_ADC_VALUES];
85 int adc_maxes[MAX_POWR1220_ADC_VALUES];
86 int adc_values[MAX_POWR1220_ADC_VALUES];
89 static const char * const input_names[] = {
106 /* Reads the specified ADC channel */
107 static int powr1220_read_adc(struct device *dev, int ch_num)
109 struct powr1220_data *data = dev_get_drvdata(dev);
114 mutex_lock(&data->update_lock);
116 if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) ||
117 !data->adc_valid[ch_num]) {
119 * figure out if we need to use the attenuator for
120 * high inputs or inputs that we don't yet have a measurement
121 * for. We dynamically set the attenuator depending on the
124 if (data->adc_maxes[ch_num] > ADC_MAX_LOW_MEASUREMENT_MV ||
125 data->adc_maxes[ch_num] == 0)
128 /* set the attenuator and mux */
129 result = i2c_smbus_write_byte_data(data->client, ADC_MUX,
135 * wait at least Tconvert time (200 us) for the
136 * conversion to complete
140 /* get the ADC reading */
141 result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_LOW);
145 reading = result >> 4;
147 /* get the upper half of the reading */
148 result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_HIGH);
152 reading |= result << 4;
154 /* now convert the reading to a voltage */
155 reading *= ADC_STEP_MV;
156 data->adc_values[ch_num] = reading;
157 data->adc_valid[ch_num] = true;
158 data->adc_last_updated[ch_num] = jiffies;
161 if (reading > data->adc_maxes[ch_num])
162 data->adc_maxes[ch_num] = reading;
164 result = data->adc_values[ch_num];
168 mutex_unlock(&data->update_lock);
174 powr1220_is_visible(const void *data, enum hwmon_sensor_types type, u32
177 struct powr1220_data *chip_data = (struct powr1220_data *)data;
179 if (channel >= chip_data->max_channels)
186 case hwmon_in_highest:
201 powr1220_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
202 int channel, const char **str)
208 *str = input_names[channel];
222 powr1220_read(struct device *dev, enum hwmon_sensor_types type, u32
223 attr, int channel, long *val)
225 struct powr1220_data *data = dev_get_drvdata(dev);
232 ret = powr1220_read_adc(dev, channel);
237 case hwmon_in_highest:
238 *val = data->adc_maxes[channel];
251 static const struct hwmon_channel_info * const powr1220_info[] = {
252 HWMON_CHANNEL_INFO(in,
253 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
254 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
255 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
256 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
257 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
258 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
259 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
260 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
261 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
262 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
263 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
264 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
265 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
266 HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL),
271 static const struct hwmon_ops powr1220_hwmon_ops = {
272 .read = powr1220_read,
273 .read_string = powr1220_read_string,
274 .is_visible = powr1220_is_visible,
277 static const struct hwmon_chip_info powr1220_chip_info = {
278 .ops = &powr1220_hwmon_ops,
279 .info = powr1220_info,
282 static const struct i2c_device_id powr1220_ids[];
284 static int powr1220_probe(struct i2c_client *client)
286 struct powr1220_data *data;
287 struct device *hwmon_dev;
289 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
292 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
296 switch (i2c_match_id(powr1220_ids, client)->driver_data) {
298 data->max_channels = 10;
301 data->max_channels = 12;
305 mutex_init(&data->update_lock);
306 data->client = client;
308 hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
314 return PTR_ERR_OR_ZERO(hwmon_dev);
317 static const struct i2c_device_id powr1220_ids[] = {
318 { "powr1014", powr1014, },
319 { "powr1220", powr1220, },
323 MODULE_DEVICE_TABLE(i2c, powr1220_ids);
325 static struct i2c_driver powr1220_driver = {
326 .class = I2C_CLASS_HWMON,
330 .probe = powr1220_probe,
331 .id_table = powr1220_ids,
334 module_i2c_driver(powr1220_driver);
336 MODULE_AUTHOR("Scott Kanowitz");
337 MODULE_DESCRIPTION("POWR1220 driver");
338 MODULE_LICENSE("GPL");