1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f4ff4155SScott Kanowitz /*
3f4ff4155SScott Kanowitz * powr1220.c - Driver for the Lattice POWR1220 programmable power supply
4f4ff4155SScott Kanowitz * and monitor. Users can read all ADC inputs along with their labels
5f4ff4155SScott Kanowitz * using the sysfs nodes.
6f4ff4155SScott Kanowitz *
7ad736c1aSAlexander A. Klimov * Copyright (c) 2014 Echo360 https://www.echo360.com
8f4ff4155SScott Kanowitz * Scott Kanowitz <skanowitz@echo360.com> <scott.kanowitz@gmail.com>
9f4ff4155SScott Kanowitz */
10f4ff4155SScott Kanowitz
11f4ff4155SScott Kanowitz #include <linux/module.h>
12f4ff4155SScott Kanowitz #include <linux/init.h>
13f4ff4155SScott Kanowitz #include <linux/slab.h>
14f4ff4155SScott Kanowitz #include <linux/jiffies.h>
15f4ff4155SScott Kanowitz #include <linux/i2c.h>
16f4ff4155SScott Kanowitz #include <linux/hwmon.h>
17f4ff4155SScott Kanowitz #include <linux/hwmon-sysfs.h>
18f4ff4155SScott Kanowitz #include <linux/err.h>
19f4ff4155SScott Kanowitz #include <linux/mutex.h>
20f4ff4155SScott Kanowitz #include <linux/delay.h>
21f4ff4155SScott Kanowitz
22f4ff4155SScott Kanowitz #define ADC_STEP_MV 2
23f4ff4155SScott Kanowitz #define ADC_MAX_LOW_MEASUREMENT_MV 2000
24f4ff4155SScott Kanowitz
259f93aa10SMichael Shych enum powr1xxx_chips { powr1014, powr1220 };
269f93aa10SMichael Shych
27f4ff4155SScott Kanowitz enum powr1220_regs {
28f4ff4155SScott Kanowitz VMON_STATUS0,
29f4ff4155SScott Kanowitz VMON_STATUS1,
30f4ff4155SScott Kanowitz VMON_STATUS2,
31f4ff4155SScott Kanowitz OUTPUT_STATUS0,
32f4ff4155SScott Kanowitz OUTPUT_STATUS1,
33f4ff4155SScott Kanowitz OUTPUT_STATUS2,
34f4ff4155SScott Kanowitz INPUT_STATUS,
35f4ff4155SScott Kanowitz ADC_VALUE_LOW,
36f4ff4155SScott Kanowitz ADC_VALUE_HIGH,
37f4ff4155SScott Kanowitz ADC_MUX,
38f4ff4155SScott Kanowitz UES_BYTE0,
39f4ff4155SScott Kanowitz UES_BYTE1,
40f4ff4155SScott Kanowitz UES_BYTE2,
41f4ff4155SScott Kanowitz UES_BYTE3,
42f4ff4155SScott Kanowitz GP_OUTPUT1,
43f4ff4155SScott Kanowitz GP_OUTPUT2,
44f4ff4155SScott Kanowitz GP_OUTPUT3,
45f4ff4155SScott Kanowitz INPUT_VALUE,
46f4ff4155SScott Kanowitz RESET,
47f4ff4155SScott Kanowitz TRIM1_TRIM,
48f4ff4155SScott Kanowitz TRIM2_TRIM,
49f4ff4155SScott Kanowitz TRIM3_TRIM,
50f4ff4155SScott Kanowitz TRIM4_TRIM,
51f4ff4155SScott Kanowitz TRIM5_TRIM,
52f4ff4155SScott Kanowitz TRIM6_TRIM,
53f4ff4155SScott Kanowitz TRIM7_TRIM,
54f4ff4155SScott Kanowitz TRIM8_TRIM,
55f4ff4155SScott Kanowitz MAX_POWR1220_REGS
56f4ff4155SScott Kanowitz };
57f4ff4155SScott Kanowitz
58f4ff4155SScott Kanowitz enum powr1220_adc_values {
59f4ff4155SScott Kanowitz VMON1,
60f4ff4155SScott Kanowitz VMON2,
61f4ff4155SScott Kanowitz VMON3,
62f4ff4155SScott Kanowitz VMON4,
63f4ff4155SScott Kanowitz VMON5,
64f4ff4155SScott Kanowitz VMON6,
65f4ff4155SScott Kanowitz VMON7,
66f4ff4155SScott Kanowitz VMON8,
67f4ff4155SScott Kanowitz VMON9,
68f4ff4155SScott Kanowitz VMON10,
69f4ff4155SScott Kanowitz VMON11,
70f4ff4155SScott Kanowitz VMON12,
71f4ff4155SScott Kanowitz VCCA,
72f4ff4155SScott Kanowitz VCCINP,
73f4ff4155SScott Kanowitz MAX_POWR1220_ADC_VALUES
74f4ff4155SScott Kanowitz };
75f4ff4155SScott Kanowitz
76f4ff4155SScott Kanowitz struct powr1220_data {
77f4ff4155SScott Kanowitz struct i2c_client *client;
78f4ff4155SScott Kanowitz struct mutex update_lock;
799f93aa10SMichael Shych u8 max_channels;
80f4ff4155SScott Kanowitz bool adc_valid[MAX_POWR1220_ADC_VALUES];
81f4ff4155SScott Kanowitz /* the next value is in jiffies */
82f4ff4155SScott Kanowitz unsigned long adc_last_updated[MAX_POWR1220_ADC_VALUES];
83f4ff4155SScott Kanowitz
84f4ff4155SScott Kanowitz /* values */
85f4ff4155SScott Kanowitz int adc_maxes[MAX_POWR1220_ADC_VALUES];
86f4ff4155SScott Kanowitz int adc_values[MAX_POWR1220_ADC_VALUES];
87f4ff4155SScott Kanowitz };
88f4ff4155SScott Kanowitz
89f4ff4155SScott Kanowitz static const char * const input_names[] = {
90f4ff4155SScott Kanowitz [VMON1] = "vmon1",
91f4ff4155SScott Kanowitz [VMON2] = "vmon2",
92f4ff4155SScott Kanowitz [VMON3] = "vmon3",
93f4ff4155SScott Kanowitz [VMON4] = "vmon4",
94f4ff4155SScott Kanowitz [VMON5] = "vmon5",
95f4ff4155SScott Kanowitz [VMON6] = "vmon6",
96f4ff4155SScott Kanowitz [VMON7] = "vmon7",
97f4ff4155SScott Kanowitz [VMON8] = "vmon8",
98f4ff4155SScott Kanowitz [VMON9] = "vmon9",
99f4ff4155SScott Kanowitz [VMON10] = "vmon10",
100f4ff4155SScott Kanowitz [VMON11] = "vmon11",
101f4ff4155SScott Kanowitz [VMON12] = "vmon12",
102f4ff4155SScott Kanowitz [VCCA] = "vcca",
103f4ff4155SScott Kanowitz [VCCINP] = "vccinp",
104f4ff4155SScott Kanowitz };
105f4ff4155SScott Kanowitz
106f4ff4155SScott Kanowitz /* Reads the specified ADC channel */
powr1220_read_adc(struct device * dev,int ch_num)107f4ff4155SScott Kanowitz static int powr1220_read_adc(struct device *dev, int ch_num)
108f4ff4155SScott Kanowitz {
109f4ff4155SScott Kanowitz struct powr1220_data *data = dev_get_drvdata(dev);
110f4ff4155SScott Kanowitz int reading;
111f4ff4155SScott Kanowitz int result;
112f4ff4155SScott Kanowitz int adc_range = 0;
113f4ff4155SScott Kanowitz
114f4ff4155SScott Kanowitz mutex_lock(&data->update_lock);
115f4ff4155SScott Kanowitz
116f4ff4155SScott Kanowitz if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) ||
117f4ff4155SScott Kanowitz !data->adc_valid[ch_num]) {
118f4ff4155SScott Kanowitz /*
119f4ff4155SScott Kanowitz * figure out if we need to use the attenuator for
120f4ff4155SScott Kanowitz * high inputs or inputs that we don't yet have a measurement
121f4ff4155SScott Kanowitz * for. We dynamically set the attenuator depending on the
122f4ff4155SScott Kanowitz * max reading.
123f4ff4155SScott Kanowitz */
124f4ff4155SScott Kanowitz if (data->adc_maxes[ch_num] > ADC_MAX_LOW_MEASUREMENT_MV ||
125f4ff4155SScott Kanowitz data->adc_maxes[ch_num] == 0)
126f4ff4155SScott Kanowitz adc_range = 1 << 4;
127f4ff4155SScott Kanowitz
128f4ff4155SScott Kanowitz /* set the attenuator and mux */
129f4ff4155SScott Kanowitz result = i2c_smbus_write_byte_data(data->client, ADC_MUX,
130f4ff4155SScott Kanowitz adc_range | ch_num);
131f4ff4155SScott Kanowitz if (result)
132f4ff4155SScott Kanowitz goto exit;
133f4ff4155SScott Kanowitz
134f4ff4155SScott Kanowitz /*
135f4ff4155SScott Kanowitz * wait at least Tconvert time (200 us) for the
136f4ff4155SScott Kanowitz * conversion to complete
137f4ff4155SScott Kanowitz */
138f4ff4155SScott Kanowitz udelay(200);
139f4ff4155SScott Kanowitz
140f4ff4155SScott Kanowitz /* get the ADC reading */
141f4ff4155SScott Kanowitz result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_LOW);
142f4ff4155SScott Kanowitz if (result < 0)
143f4ff4155SScott Kanowitz goto exit;
144f4ff4155SScott Kanowitz
145f4ff4155SScott Kanowitz reading = result >> 4;
146f4ff4155SScott Kanowitz
147f4ff4155SScott Kanowitz /* get the upper half of the reading */
148f4ff4155SScott Kanowitz result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_HIGH);
149f4ff4155SScott Kanowitz if (result < 0)
150f4ff4155SScott Kanowitz goto exit;
151f4ff4155SScott Kanowitz
152f4ff4155SScott Kanowitz reading |= result << 4;
153f4ff4155SScott Kanowitz
154f4ff4155SScott Kanowitz /* now convert the reading to a voltage */
155f4ff4155SScott Kanowitz reading *= ADC_STEP_MV;
156f4ff4155SScott Kanowitz data->adc_values[ch_num] = reading;
157f4ff4155SScott Kanowitz data->adc_valid[ch_num] = true;
158f4ff4155SScott Kanowitz data->adc_last_updated[ch_num] = jiffies;
159f4ff4155SScott Kanowitz result = reading;
160f4ff4155SScott Kanowitz
161f4ff4155SScott Kanowitz if (reading > data->adc_maxes[ch_num])
162f4ff4155SScott Kanowitz data->adc_maxes[ch_num] = reading;
163f4ff4155SScott Kanowitz } else {
164f4ff4155SScott Kanowitz result = data->adc_values[ch_num];
165f4ff4155SScott Kanowitz }
166f4ff4155SScott Kanowitz
167f4ff4155SScott Kanowitz exit:
168f4ff4155SScott Kanowitz mutex_unlock(&data->update_lock);
169f4ff4155SScott Kanowitz
170f4ff4155SScott Kanowitz return result;
171f4ff4155SScott Kanowitz }
172f4ff4155SScott Kanowitz
173915d4664SMichael Shych static umode_t
powr1220_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)174915d4664SMichael Shych powr1220_is_visible(const void *data, enum hwmon_sensor_types type, u32
175915d4664SMichael Shych attr, int channel)
176f4ff4155SScott Kanowitz {
1779f93aa10SMichael Shych struct powr1220_data *chip_data = (struct powr1220_data *)data;
1789f93aa10SMichael Shych
1799f93aa10SMichael Shych if (channel >= chip_data->max_channels)
1809f93aa10SMichael Shych return 0;
1819f93aa10SMichael Shych
182915d4664SMichael Shych switch (type) {
183915d4664SMichael Shych case hwmon_in:
184915d4664SMichael Shych switch (attr) {
185915d4664SMichael Shych case hwmon_in_input:
186915d4664SMichael Shych case hwmon_in_highest:
187915d4664SMichael Shych case hwmon_in_label:
188915d4664SMichael Shych return 0444;
189915d4664SMichael Shych default:
190915d4664SMichael Shych break;
191915d4664SMichael Shych }
192915d4664SMichael Shych break;
193915d4664SMichael Shych default:
194915d4664SMichael Shych break;
195f4ff4155SScott Kanowitz }
196f4ff4155SScott Kanowitz
197915d4664SMichael Shych return 0;
198915d4664SMichael Shych }
199915d4664SMichael Shych
200915d4664SMichael Shych static int
powr1220_read_string(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,const char ** str)201915d4664SMichael Shych powr1220_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
202915d4664SMichael Shych int channel, const char **str)
203f4ff4155SScott Kanowitz {
204915d4664SMichael Shych switch (type) {
205915d4664SMichael Shych case hwmon_in:
206915d4664SMichael Shych switch (attr) {
207915d4664SMichael Shych case hwmon_in_label:
208915d4664SMichael Shych *str = input_names[channel];
209915d4664SMichael Shych return 0;
210915d4664SMichael Shych default:
211915d4664SMichael Shych return -EOPNOTSUPP;
212915d4664SMichael Shych }
213915d4664SMichael Shych break;
214915d4664SMichael Shych default:
215915d4664SMichael Shych return -EOPNOTSUPP;
216915d4664SMichael Shych }
217915d4664SMichael Shych
218915d4664SMichael Shych return -EOPNOTSUPP;
219915d4664SMichael Shych }
220915d4664SMichael Shych
221915d4664SMichael Shych static int
powr1220_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)222915d4664SMichael Shych powr1220_read(struct device *dev, enum hwmon_sensor_types type, u32
223915d4664SMichael Shych attr, int channel, long *val)
224915d4664SMichael Shych {
225f4ff4155SScott Kanowitz struct powr1220_data *data = dev_get_drvdata(dev);
226915d4664SMichael Shych int ret;
227f4ff4155SScott Kanowitz
228915d4664SMichael Shych switch (type) {
229915d4664SMichael Shych case hwmon_in:
230915d4664SMichael Shych switch (attr) {
231915d4664SMichael Shych case hwmon_in_input:
232915d4664SMichael Shych ret = powr1220_read_adc(dev, channel);
233915d4664SMichael Shych if (ret < 0)
234915d4664SMichael Shych return ret;
235915d4664SMichael Shych *val = ret;
236915d4664SMichael Shych break;
237915d4664SMichael Shych case hwmon_in_highest:
238915d4664SMichael Shych *val = data->adc_maxes[channel];
239915d4664SMichael Shych break;
240915d4664SMichael Shych default:
241915d4664SMichael Shych return -EOPNOTSUPP;
242915d4664SMichael Shych }
243915d4664SMichael Shych break;
244915d4664SMichael Shych default:
245915d4664SMichael Shych return -EOPNOTSUPP;
246f4ff4155SScott Kanowitz }
247f4ff4155SScott Kanowitz
248915d4664SMichael Shych return 0;
249f4ff4155SScott Kanowitz }
250f4ff4155SScott Kanowitz
251*42d273bcSKrzysztof Kozlowski static const struct hwmon_channel_info * const powr1220_info[] = {
252915d4664SMichael Shych HWMON_CHANNEL_INFO(in,
253915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
254915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
255915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
256915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
257915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
258915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
259915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
260915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
261915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
262915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
263915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
264915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
265915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL,
266915d4664SMichael Shych HWMON_I_INPUT | HWMON_I_HIGHEST | HWMON_I_LABEL),
267f4ff4155SScott Kanowitz
268f4ff4155SScott Kanowitz NULL
269f4ff4155SScott Kanowitz };
270f4ff4155SScott Kanowitz
271915d4664SMichael Shych static const struct hwmon_ops powr1220_hwmon_ops = {
272915d4664SMichael Shych .read = powr1220_read,
273915d4664SMichael Shych .read_string = powr1220_read_string,
274915d4664SMichael Shych .is_visible = powr1220_is_visible,
275915d4664SMichael Shych };
276915d4664SMichael Shych
277915d4664SMichael Shych static const struct hwmon_chip_info powr1220_chip_info = {
278915d4664SMichael Shych .ops = &powr1220_hwmon_ops,
279915d4664SMichael Shych .info = powr1220_info,
280915d4664SMichael Shych };
281f4ff4155SScott Kanowitz
2829f93aa10SMichael Shych static const struct i2c_device_id powr1220_ids[];
2839f93aa10SMichael Shych
powr1220_probe(struct i2c_client * client)28467487038SStephen Kitt static int powr1220_probe(struct i2c_client *client)
285f4ff4155SScott Kanowitz {
286f4ff4155SScott Kanowitz struct powr1220_data *data;
287f4ff4155SScott Kanowitz struct device *hwmon_dev;
288f4ff4155SScott Kanowitz
289f4ff4155SScott Kanowitz if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
290f4ff4155SScott Kanowitz return -ENODEV;
291f4ff4155SScott Kanowitz
292f4ff4155SScott Kanowitz data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
293f4ff4155SScott Kanowitz if (!data)
294f4ff4155SScott Kanowitz return -ENOMEM;
295f4ff4155SScott Kanowitz
2969f93aa10SMichael Shych switch (i2c_match_id(powr1220_ids, client)->driver_data) {
2979f93aa10SMichael Shych case powr1014:
2989f93aa10SMichael Shych data->max_channels = 10;
2999f93aa10SMichael Shych break;
3009f93aa10SMichael Shych default:
3019f93aa10SMichael Shych data->max_channels = 12;
3029f93aa10SMichael Shych break;
3039f93aa10SMichael Shych }
3049f93aa10SMichael Shych
305f4ff4155SScott Kanowitz mutex_init(&data->update_lock);
306f4ff4155SScott Kanowitz data->client = client;
307f4ff4155SScott Kanowitz
308915d4664SMichael Shych hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
309915d4664SMichael Shych client->name,
310915d4664SMichael Shych data,
311915d4664SMichael Shych &powr1220_chip_info,
312915d4664SMichael Shych NULL);
313f4ff4155SScott Kanowitz
314f4ff4155SScott Kanowitz return PTR_ERR_OR_ZERO(hwmon_dev);
315f4ff4155SScott Kanowitz }
316f4ff4155SScott Kanowitz
317f4ff4155SScott Kanowitz static const struct i2c_device_id powr1220_ids[] = {
3189f93aa10SMichael Shych { "powr1014", powr1014, },
3199f93aa10SMichael Shych { "powr1220", powr1220, },
320f4ff4155SScott Kanowitz { }
321f4ff4155SScott Kanowitz };
322f4ff4155SScott Kanowitz
323f4ff4155SScott Kanowitz MODULE_DEVICE_TABLE(i2c, powr1220_ids);
324f4ff4155SScott Kanowitz
325f4ff4155SScott Kanowitz static struct i2c_driver powr1220_driver = {
326f4ff4155SScott Kanowitz .class = I2C_CLASS_HWMON,
327f4ff4155SScott Kanowitz .driver = {
328f4ff4155SScott Kanowitz .name = "powr1220",
329f4ff4155SScott Kanowitz },
33067487038SStephen Kitt .probe = powr1220_probe,
331f4ff4155SScott Kanowitz .id_table = powr1220_ids,
332f4ff4155SScott Kanowitz };
333f4ff4155SScott Kanowitz
334f4ff4155SScott Kanowitz module_i2c_driver(powr1220_driver);
335f4ff4155SScott Kanowitz
336f4ff4155SScott Kanowitz MODULE_AUTHOR("Scott Kanowitz");
337f4ff4155SScott Kanowitz MODULE_DESCRIPTION("POWR1220 driver");
338f4ff4155SScott Kanowitz MODULE_LICENSE("GPL");
339