powr1220.c (7322B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 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. 6 * 7 * Copyright (c) 2014 Echo360 https://www.echo360.com 8 * Scott Kanowitz <skanowitz@echo360.com> <scott.kanowitz@gmail.com> 9 */ 10 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> 21 22#define ADC_STEP_MV 2 23#define ADC_MAX_LOW_MEASUREMENT_MV 2000 24 25enum powr1xxx_chips { powr1014, powr1220 }; 26 27enum powr1220_regs { 28 VMON_STATUS0, 29 VMON_STATUS1, 30 VMON_STATUS2, 31 OUTPUT_STATUS0, 32 OUTPUT_STATUS1, 33 OUTPUT_STATUS2, 34 INPUT_STATUS, 35 ADC_VALUE_LOW, 36 ADC_VALUE_HIGH, 37 ADC_MUX, 38 UES_BYTE0, 39 UES_BYTE1, 40 UES_BYTE2, 41 UES_BYTE3, 42 GP_OUTPUT1, 43 GP_OUTPUT2, 44 GP_OUTPUT3, 45 INPUT_VALUE, 46 RESET, 47 TRIM1_TRIM, 48 TRIM2_TRIM, 49 TRIM3_TRIM, 50 TRIM4_TRIM, 51 TRIM5_TRIM, 52 TRIM6_TRIM, 53 TRIM7_TRIM, 54 TRIM8_TRIM, 55 MAX_POWR1220_REGS 56}; 57 58enum powr1220_adc_values { 59 VMON1, 60 VMON2, 61 VMON3, 62 VMON4, 63 VMON5, 64 VMON6, 65 VMON7, 66 VMON8, 67 VMON9, 68 VMON10, 69 VMON11, 70 VMON12, 71 VCCA, 72 VCCINP, 73 MAX_POWR1220_ADC_VALUES 74}; 75 76struct powr1220_data { 77 struct i2c_client *client; 78 struct mutex update_lock; 79 u8 max_channels; 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]; 83 84 /* values */ 85 int adc_maxes[MAX_POWR1220_ADC_VALUES]; 86 int adc_values[MAX_POWR1220_ADC_VALUES]; 87}; 88 89static const char * const input_names[] = { 90 [VMON1] = "vmon1", 91 [VMON2] = "vmon2", 92 [VMON3] = "vmon3", 93 [VMON4] = "vmon4", 94 [VMON5] = "vmon5", 95 [VMON6] = "vmon6", 96 [VMON7] = "vmon7", 97 [VMON8] = "vmon8", 98 [VMON9] = "vmon9", 99 [VMON10] = "vmon10", 100 [VMON11] = "vmon11", 101 [VMON12] = "vmon12", 102 [VCCA] = "vcca", 103 [VCCINP] = "vccinp", 104}; 105 106/* Reads the specified ADC channel */ 107static int powr1220_read_adc(struct device *dev, int ch_num) 108{ 109 struct powr1220_data *data = dev_get_drvdata(dev); 110 int reading; 111 int result; 112 int adc_range = 0; 113 114 mutex_lock(&data->update_lock); 115 116 if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) || 117 !data->adc_valid[ch_num]) { 118 /* 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 122 * max reading. 123 */ 124 if (data->adc_maxes[ch_num] > ADC_MAX_LOW_MEASUREMENT_MV || 125 data->adc_maxes[ch_num] == 0) 126 adc_range = 1 << 4; 127 128 /* set the attenuator and mux */ 129 result = i2c_smbus_write_byte_data(data->client, ADC_MUX, 130 adc_range | ch_num); 131 if (result) 132 goto exit; 133 134 /* 135 * wait at least Tconvert time (200 us) for the 136 * conversion to complete 137 */ 138 udelay(200); 139 140 /* get the ADC reading */ 141 result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_LOW); 142 if (result < 0) 143 goto exit; 144 145 reading = result >> 4; 146 147 /* get the upper half of the reading */ 148 result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_HIGH); 149 if (result < 0) 150 goto exit; 151 152 reading |= result << 4; 153 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; 159 result = reading; 160 161 if (reading > data->adc_maxes[ch_num]) 162 data->adc_maxes[ch_num] = reading; 163 } else { 164 result = data->adc_values[ch_num]; 165 } 166 167exit: 168 mutex_unlock(&data->update_lock); 169 170 return result; 171} 172 173static umode_t 174powr1220_is_visible(const void *data, enum hwmon_sensor_types type, u32 175 attr, int channel) 176{ 177 struct powr1220_data *chip_data = (struct powr1220_data *)data; 178 179 if (channel >= chip_data->max_channels) 180 return 0; 181 182 switch (type) { 183 case hwmon_in: 184 switch (attr) { 185 case hwmon_in_input: 186 case hwmon_in_highest: 187 case hwmon_in_label: 188 return 0444; 189 default: 190 break; 191 } 192 break; 193 default: 194 break; 195 } 196 197 return 0; 198} 199 200static int 201powr1220_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr, 202 int channel, const char **str) 203{ 204 switch (type) { 205 case hwmon_in: 206 switch (attr) { 207 case hwmon_in_label: 208 *str = input_names[channel]; 209 return 0; 210 default: 211 return -EOPNOTSUPP; 212 } 213 break; 214 default: 215 return -EOPNOTSUPP; 216 } 217 218 return -EOPNOTSUPP; 219} 220 221static int 222powr1220_read(struct device *dev, enum hwmon_sensor_types type, u32 223 attr, int channel, long *val) 224{ 225 struct powr1220_data *data = dev_get_drvdata(dev); 226 int ret; 227 228 switch (type) { 229 case hwmon_in: 230 switch (attr) { 231 case hwmon_in_input: 232 ret = powr1220_read_adc(dev, channel); 233 if (ret < 0) 234 return ret; 235 *val = ret; 236 break; 237 case hwmon_in_highest: 238 *val = data->adc_maxes[channel]; 239 break; 240 default: 241 return -EOPNOTSUPP; 242 } 243 break; 244 default: 245 return -EOPNOTSUPP; 246} 247 248 return 0; 249} 250 251static const struct hwmon_channel_info *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), 267 268 NULL 269}; 270 271static const struct hwmon_ops powr1220_hwmon_ops = { 272 .read = powr1220_read, 273 .read_string = powr1220_read_string, 274 .is_visible = powr1220_is_visible, 275}; 276 277static const struct hwmon_chip_info powr1220_chip_info = { 278 .ops = &powr1220_hwmon_ops, 279 .info = powr1220_info, 280}; 281 282static const struct i2c_device_id powr1220_ids[]; 283 284static int powr1220_probe(struct i2c_client *client) 285{ 286 struct powr1220_data *data; 287 struct device *hwmon_dev; 288 289 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 290 return -ENODEV; 291 292 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 293 if (!data) 294 return -ENOMEM; 295 296 switch (i2c_match_id(powr1220_ids, client)->driver_data) { 297 case powr1014: 298 data->max_channels = 10; 299 break; 300 default: 301 data->max_channels = 12; 302 break; 303 } 304 305 mutex_init(&data->update_lock); 306 data->client = client; 307 308 hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, 309 client->name, 310 data, 311 &powr1220_chip_info, 312 NULL); 313 314 return PTR_ERR_OR_ZERO(hwmon_dev); 315} 316 317static const struct i2c_device_id powr1220_ids[] = { 318 { "powr1014", powr1014, }, 319 { "powr1220", powr1220, }, 320 { } 321}; 322 323MODULE_DEVICE_TABLE(i2c, powr1220_ids); 324 325static struct i2c_driver powr1220_driver = { 326 .class = I2C_CLASS_HWMON, 327 .driver = { 328 .name = "powr1220", 329 }, 330 .probe_new = powr1220_probe, 331 .id_table = powr1220_ids, 332}; 333 334module_i2c_driver(powr1220_driver); 335 336MODULE_AUTHOR("Scott Kanowitz"); 337MODULE_DESCRIPTION("POWR1220 driver"); 338MODULE_LICENSE("GPL");