1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Driver for Linear Technology LTC4261 I2C Negative Voltage Hot Swap Controller |
4 | * |
5 | * Copyright (C) 2010 Ericsson AB. |
6 | * |
7 | * Derived from: |
8 | * |
9 | * Driver for Linear Technology LTC4245 I2C Multiple Supply Hot Swap Controller |
10 | * Copyright (C) 2008 Ira W. Snyder <iws@ovro.caltech.edu> |
11 | * |
12 | * Datasheet: http://cds.linear.com/docs/Datasheet/42612fb.pdf |
13 | */ |
14 | |
15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> |
17 | #include <linux/init.h> |
18 | #include <linux/err.h> |
19 | #include <linux/slab.h> |
20 | #include <linux/i2c.h> |
21 | #include <linux/hwmon.h> |
22 | #include <linux/hwmon-sysfs.h> |
23 | #include <linux/jiffies.h> |
24 | |
25 | /* chip registers */ |
26 | #define LTC4261_STATUS 0x00 /* readonly */ |
27 | #define LTC4261_FAULT 0x01 |
28 | #define LTC4261_ALERT 0x02 |
29 | #define LTC4261_CONTROL 0x03 |
30 | #define LTC4261_SENSE_H 0x04 |
31 | #define LTC4261_SENSE_L 0x05 |
32 | #define LTC4261_ADIN2_H 0x06 |
33 | #define LTC4261_ADIN2_L 0x07 |
34 | #define LTC4261_ADIN_H 0x08 |
35 | #define LTC4261_ADIN_L 0x09 |
36 | |
37 | /* |
38 | * Fault register bits |
39 | */ |
40 | #define FAULT_OV (1<<0) |
41 | #define FAULT_UV (1<<1) |
42 | #define FAULT_OC (1<<2) |
43 | |
44 | struct ltc4261_data { |
45 | struct i2c_client *client; |
46 | |
47 | struct mutex update_lock; |
48 | bool valid; |
49 | unsigned long last_updated; /* in jiffies */ |
50 | |
51 | /* Registers */ |
52 | u8 regs[10]; |
53 | }; |
54 | |
55 | static struct ltc4261_data *ltc4261_update_device(struct device *dev) |
56 | { |
57 | struct ltc4261_data *data = dev_get_drvdata(dev); |
58 | struct i2c_client *client = data->client; |
59 | struct ltc4261_data *ret = data; |
60 | |
61 | mutex_lock(&data->update_lock); |
62 | |
63 | if (time_after(jiffies, data->last_updated + HZ / 4) || !data->valid) { |
64 | int i; |
65 | |
66 | /* Read registers -- 0x00 to 0x09 */ |
67 | for (i = 0; i < ARRAY_SIZE(data->regs); i++) { |
68 | int val; |
69 | |
70 | val = i2c_smbus_read_byte_data(client, command: i); |
71 | if (unlikely(val < 0)) { |
72 | dev_dbg(dev, |
73 | "Failed to read ADC value: error %d\n" , |
74 | val); |
75 | ret = ERR_PTR(error: val); |
76 | data->valid = false; |
77 | goto abort; |
78 | } |
79 | data->regs[i] = val; |
80 | } |
81 | data->last_updated = jiffies; |
82 | data->valid = true; |
83 | } |
84 | abort: |
85 | mutex_unlock(lock: &data->update_lock); |
86 | return ret; |
87 | } |
88 | |
89 | /* Return the voltage from the given register in mV or mA */ |
90 | static int ltc4261_get_value(struct ltc4261_data *data, u8 reg) |
91 | { |
92 | u32 val; |
93 | |
94 | val = (data->regs[reg] << 2) + (data->regs[reg + 1] >> 6); |
95 | |
96 | switch (reg) { |
97 | case LTC4261_ADIN_H: |
98 | case LTC4261_ADIN2_H: |
99 | /* 2.5mV resolution. Convert to mV. */ |
100 | val = val * 25 / 10; |
101 | break; |
102 | case LTC4261_SENSE_H: |
103 | /* |
104 | * 62.5uV resolution. Convert to current as measured with |
105 | * an 1 mOhm sense resistor, in mA. If a different sense |
106 | * resistor is installed, calculate the actual current by |
107 | * dividing the reported current by the sense resistor value |
108 | * in mOhm. |
109 | */ |
110 | val = val * 625 / 10; |
111 | break; |
112 | default: |
113 | /* If we get here, the developer messed up */ |
114 | WARN_ON_ONCE(1); |
115 | val = 0; |
116 | break; |
117 | } |
118 | |
119 | return val; |
120 | } |
121 | |
122 | static ssize_t ltc4261_value_show(struct device *dev, |
123 | struct device_attribute *da, char *buf) |
124 | { |
125 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
126 | struct ltc4261_data *data = ltc4261_update_device(dev); |
127 | int value; |
128 | |
129 | if (IS_ERR(ptr: data)) |
130 | return PTR_ERR(ptr: data); |
131 | |
132 | value = ltc4261_get_value(data, reg: attr->index); |
133 | return sysfs_emit(buf, fmt: "%d\n" , value); |
134 | } |
135 | |
136 | static ssize_t ltc4261_bool_show(struct device *dev, |
137 | struct device_attribute *da, char *buf) |
138 | { |
139 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
140 | struct ltc4261_data *data = ltc4261_update_device(dev); |
141 | u8 fault; |
142 | |
143 | if (IS_ERR(ptr: data)) |
144 | return PTR_ERR(ptr: data); |
145 | |
146 | fault = data->regs[LTC4261_FAULT] & attr->index; |
147 | if (fault) /* Clear reported faults in chip register */ |
148 | i2c_smbus_write_byte_data(client: data->client, LTC4261_FAULT, value: ~fault); |
149 | |
150 | return sysfs_emit(buf, fmt: "%d\n" , fault ? 1 : 0); |
151 | } |
152 | |
153 | /* |
154 | * Input voltages. |
155 | */ |
156 | static SENSOR_DEVICE_ATTR_RO(in1_input, ltc4261_value, LTC4261_ADIN_H); |
157 | static SENSOR_DEVICE_ATTR_RO(in2_input, ltc4261_value, LTC4261_ADIN2_H); |
158 | |
159 | /* |
160 | * Voltage alarms. The chip has only one set of voltage alarm status bits, |
161 | * triggered by input voltage alarms. In many designs, those alarms are |
162 | * associated with the ADIN2 sensor, due to the proximity of the ADIN2 pin |
163 | * to the OV pin. ADIN2 is, however, not available on all chip variants. |
164 | * To ensure that the alarm condition is reported to the user, report it |
165 | * with both voltage sensors. |
166 | */ |
167 | static SENSOR_DEVICE_ATTR_RO(in1_min_alarm, ltc4261_bool, FAULT_UV); |
168 | static SENSOR_DEVICE_ATTR_RO(in1_max_alarm, ltc4261_bool, FAULT_OV); |
169 | static SENSOR_DEVICE_ATTR_RO(in2_min_alarm, ltc4261_bool, FAULT_UV); |
170 | static SENSOR_DEVICE_ATTR_RO(in2_max_alarm, ltc4261_bool, FAULT_OV); |
171 | |
172 | /* Currents (via sense resistor) */ |
173 | static SENSOR_DEVICE_ATTR_RO(curr1_input, ltc4261_value, LTC4261_SENSE_H); |
174 | |
175 | /* Overcurrent alarm */ |
176 | static SENSOR_DEVICE_ATTR_RO(curr1_max_alarm, ltc4261_bool, FAULT_OC); |
177 | |
178 | static struct attribute *ltc4261_attrs[] = { |
179 | &sensor_dev_attr_in1_input.dev_attr.attr, |
180 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, |
181 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, |
182 | &sensor_dev_attr_in2_input.dev_attr.attr, |
183 | &sensor_dev_attr_in2_min_alarm.dev_attr.attr, |
184 | &sensor_dev_attr_in2_max_alarm.dev_attr.attr, |
185 | |
186 | &sensor_dev_attr_curr1_input.dev_attr.attr, |
187 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, |
188 | |
189 | NULL, |
190 | }; |
191 | ATTRIBUTE_GROUPS(ltc4261); |
192 | |
193 | static int ltc4261_probe(struct i2c_client *client) |
194 | { |
195 | struct i2c_adapter *adapter = client->adapter; |
196 | struct device *dev = &client->dev; |
197 | struct ltc4261_data *data; |
198 | struct device *hwmon_dev; |
199 | |
200 | if (!i2c_check_functionality(adap: adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
201 | return -ENODEV; |
202 | |
203 | if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { |
204 | dev_err(dev, "Failed to read status register\n" ); |
205 | return -ENODEV; |
206 | } |
207 | |
208 | data = devm_kzalloc(dev, size: sizeof(*data), GFP_KERNEL); |
209 | if (!data) |
210 | return -ENOMEM; |
211 | |
212 | data->client = client; |
213 | mutex_init(&data->update_lock); |
214 | |
215 | /* Clear faults */ |
216 | i2c_smbus_write_byte_data(client, LTC4261_FAULT, value: 0x00); |
217 | |
218 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, name: client->name, |
219 | drvdata: data, |
220 | groups: ltc4261_groups); |
221 | return PTR_ERR_OR_ZERO(ptr: hwmon_dev); |
222 | } |
223 | |
224 | static const struct i2c_device_id ltc4261_id[] = { |
225 | {"ltc4261" , 0}, |
226 | {} |
227 | }; |
228 | |
229 | MODULE_DEVICE_TABLE(i2c, ltc4261_id); |
230 | |
231 | /* This is the driver that will be inserted */ |
232 | static struct i2c_driver ltc4261_driver = { |
233 | .driver = { |
234 | .name = "ltc4261" , |
235 | }, |
236 | .probe = ltc4261_probe, |
237 | .id_table = ltc4261_id, |
238 | }; |
239 | |
240 | module_i2c_driver(ltc4261_driver); |
241 | |
242 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>" ); |
243 | MODULE_DESCRIPTION("LTC4261 driver" ); |
244 | MODULE_LICENSE("GPL" ); |
245 | |