0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/init.h>
0016 #include <linux/bitops.h>
0017 #include <linux/err.h>
0018 #include <linux/slab.h>
0019 #include <linux/i2c.h>
0020 #include <linux/hwmon.h>
0021 #include <linux/hwmon-sysfs.h>
0022 #include <linux/jiffies.h>
0023 #include <linux/platform_data/ltc4245.h>
0024
0025
0026 enum ltc4245_cmd {
0027 LTC4245_STATUS = 0x00,
0028 LTC4245_ALERT = 0x01,
0029 LTC4245_CONTROL = 0x02,
0030 LTC4245_ON = 0x03,
0031 LTC4245_FAULT1 = 0x04,
0032 LTC4245_FAULT2 = 0x05,
0033 LTC4245_GPIO = 0x06,
0034 LTC4245_ADCADR = 0x07,
0035
0036 LTC4245_12VIN = 0x10,
0037 LTC4245_12VSENSE = 0x11,
0038 LTC4245_12VOUT = 0x12,
0039 LTC4245_5VIN = 0x13,
0040 LTC4245_5VSENSE = 0x14,
0041 LTC4245_5VOUT = 0x15,
0042 LTC4245_3VIN = 0x16,
0043 LTC4245_3VSENSE = 0x17,
0044 LTC4245_3VOUT = 0x18,
0045 LTC4245_VEEIN = 0x19,
0046 LTC4245_VEESENSE = 0x1a,
0047 LTC4245_VEEOUT = 0x1b,
0048 LTC4245_GPIOADC = 0x1c,
0049 };
0050
0051 struct ltc4245_data {
0052 struct i2c_client *client;
0053
0054 struct mutex update_lock;
0055 bool valid;
0056 unsigned long last_updated;
0057
0058
0059 u8 cregs[0x08];
0060
0061
0062 u8 vregs[0x0d];
0063
0064
0065 bool use_extra_gpios;
0066 int gpios[3];
0067 };
0068
0069
0070
0071
0072
0073
0074
0075
0076 static void ltc4245_update_gpios(struct device *dev)
0077 {
0078 struct ltc4245_data *data = dev_get_drvdata(dev);
0079 struct i2c_client *client = data->client;
0080 u8 gpio_curr, gpio_next, gpio_reg;
0081 int i;
0082
0083
0084 if (!data->use_extra_gpios) {
0085 data->gpios[0] = data->vregs[LTC4245_GPIOADC - 0x10];
0086 return;
0087 }
0088
0089
0090
0091
0092
0093 if (time_after(jiffies, data->last_updated + 5 * HZ)) {
0094 for (i = 0; i < ARRAY_SIZE(data->gpios); i++)
0095 data->gpios[i] = -EAGAIN;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105 gpio_curr = (data->cregs[LTC4245_GPIO] & 0xc0) >> 6;
0106 if (gpio_curr > 0)
0107 gpio_curr -= 1;
0108
0109
0110 data->gpios[gpio_curr] = data->vregs[LTC4245_GPIOADC - 0x10];
0111
0112
0113 gpio_next = (gpio_curr + 1) % ARRAY_SIZE(data->gpios);
0114
0115
0116
0117
0118
0119 gpio_reg = (data->cregs[LTC4245_GPIO] & 0x3f) | ((gpio_next + 1) << 6);
0120
0121
0122 i2c_smbus_write_byte_data(client, LTC4245_GPIO, gpio_reg);
0123
0124
0125 data->cregs[LTC4245_GPIO] = gpio_reg;
0126 }
0127
0128 static struct ltc4245_data *ltc4245_update_device(struct device *dev)
0129 {
0130 struct ltc4245_data *data = dev_get_drvdata(dev);
0131 struct i2c_client *client = data->client;
0132 s32 val;
0133 int i;
0134
0135 mutex_lock(&data->update_lock);
0136
0137 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
0138
0139
0140 for (i = 0; i < ARRAY_SIZE(data->cregs); i++) {
0141 val = i2c_smbus_read_byte_data(client, i);
0142 if (unlikely(val < 0))
0143 data->cregs[i] = 0;
0144 else
0145 data->cregs[i] = val;
0146 }
0147
0148
0149 for (i = 0; i < ARRAY_SIZE(data->vregs); i++) {
0150 val = i2c_smbus_read_byte_data(client, i+0x10);
0151 if (unlikely(val < 0))
0152 data->vregs[i] = 0;
0153 else
0154 data->vregs[i] = val;
0155 }
0156
0157
0158 ltc4245_update_gpios(dev);
0159
0160 data->last_updated = jiffies;
0161 data->valid = true;
0162 }
0163
0164 mutex_unlock(&data->update_lock);
0165
0166 return data;
0167 }
0168
0169
0170 static int ltc4245_get_voltage(struct device *dev, u8 reg)
0171 {
0172 struct ltc4245_data *data = ltc4245_update_device(dev);
0173 const u8 regval = data->vregs[reg - 0x10];
0174 u32 voltage = 0;
0175
0176 switch (reg) {
0177 case LTC4245_12VIN:
0178 case LTC4245_12VOUT:
0179 voltage = regval * 55;
0180 break;
0181 case LTC4245_5VIN:
0182 case LTC4245_5VOUT:
0183 voltage = regval * 22;
0184 break;
0185 case LTC4245_3VIN:
0186 case LTC4245_3VOUT:
0187 voltage = regval * 15;
0188 break;
0189 case LTC4245_VEEIN:
0190 case LTC4245_VEEOUT:
0191 voltage = regval * -55;
0192 break;
0193 case LTC4245_GPIOADC:
0194 voltage = regval * 10;
0195 break;
0196 default:
0197
0198 WARN_ON_ONCE(1);
0199 break;
0200 }
0201
0202 return voltage;
0203 }
0204
0205
0206 static unsigned int ltc4245_get_current(struct device *dev, u8 reg)
0207 {
0208 struct ltc4245_data *data = ltc4245_update_device(dev);
0209 const u8 regval = data->vregs[reg - 0x10];
0210 unsigned int voltage;
0211 unsigned int curr;
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 switch (reg) {
0229 case LTC4245_12VSENSE:
0230 voltage = regval * 250;
0231 curr = voltage / 50;
0232 break;
0233 case LTC4245_5VSENSE:
0234 voltage = regval * 125;
0235 curr = (voltage * 10) / 35;
0236 break;
0237 case LTC4245_3VSENSE:
0238 voltage = regval * 125;
0239 curr = (voltage * 10) / 25;
0240 break;
0241 case LTC4245_VEESENSE:
0242 voltage = regval * 250;
0243 curr = voltage / 100;
0244 break;
0245 default:
0246
0247 WARN_ON_ONCE(1);
0248 curr = 0;
0249 break;
0250 }
0251
0252 return curr;
0253 }
0254
0255
0256
0257 static const s8 ltc4245_in_regs[] = {
0258 LTC4245_12VIN, LTC4245_5VIN, LTC4245_3VIN, LTC4245_VEEIN,
0259 LTC4245_12VOUT, LTC4245_5VOUT, LTC4245_3VOUT, LTC4245_VEEOUT,
0260 };
0261
0262
0263
0264 static const s8 ltc4245_curr_regs[] = {
0265 LTC4245_12VSENSE, LTC4245_5VSENSE, LTC4245_3VSENSE, LTC4245_VEESENSE,
0266 };
0267
0268 static int ltc4245_read_curr(struct device *dev, u32 attr, int channel,
0269 long *val)
0270 {
0271 struct ltc4245_data *data = ltc4245_update_device(dev);
0272
0273 switch (attr) {
0274 case hwmon_curr_input:
0275 *val = ltc4245_get_current(dev, ltc4245_curr_regs[channel]);
0276 return 0;
0277 case hwmon_curr_max_alarm:
0278 *val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel + 4));
0279 return 0;
0280 default:
0281 return -EOPNOTSUPP;
0282 }
0283 }
0284
0285 static int ltc4245_read_in(struct device *dev, u32 attr, int channel, long *val)
0286 {
0287 struct ltc4245_data *data = ltc4245_update_device(dev);
0288
0289 switch (attr) {
0290 case hwmon_in_input:
0291 if (channel < 8) {
0292 *val = ltc4245_get_voltage(dev,
0293 ltc4245_in_regs[channel]);
0294 } else {
0295 int regval = data->gpios[channel - 8];
0296
0297 if (regval < 0)
0298 return regval;
0299 *val = regval * 10;
0300 }
0301 return 0;
0302 case hwmon_in_min_alarm:
0303 if (channel < 4)
0304 *val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel));
0305 else
0306 *val = !!(data->cregs[LTC4245_FAULT2] &
0307 BIT(channel - 4));
0308 return 0;
0309 default:
0310 return -EOPNOTSUPP;
0311 }
0312 }
0313
0314 static int ltc4245_read_power(struct device *dev, u32 attr, int channel,
0315 long *val)
0316 {
0317 unsigned long curr;
0318 long voltage;
0319
0320 switch (attr) {
0321 case hwmon_power_input:
0322 (void)ltc4245_update_device(dev);
0323 curr = ltc4245_get_current(dev, ltc4245_curr_regs[channel]);
0324 voltage = ltc4245_get_voltage(dev, ltc4245_in_regs[channel]);
0325 *val = abs(curr * voltage);
0326 return 0;
0327 default:
0328 return -EOPNOTSUPP;
0329 }
0330 }
0331
0332 static int ltc4245_read(struct device *dev, enum hwmon_sensor_types type,
0333 u32 attr, int channel, long *val)
0334 {
0335
0336 switch (type) {
0337 case hwmon_curr:
0338 return ltc4245_read_curr(dev, attr, channel, val);
0339 case hwmon_power:
0340 return ltc4245_read_power(dev, attr, channel, val);
0341 case hwmon_in:
0342 return ltc4245_read_in(dev, attr, channel - 1, val);
0343 default:
0344 return -EOPNOTSUPP;
0345 }
0346 }
0347
0348 static umode_t ltc4245_is_visible(const void *_data,
0349 enum hwmon_sensor_types type,
0350 u32 attr, int channel)
0351 {
0352 const struct ltc4245_data *data = _data;
0353
0354 switch (type) {
0355 case hwmon_in:
0356 if (channel == 0)
0357 return 0;
0358 switch (attr) {
0359 case hwmon_in_input:
0360 if (channel > 9 && !data->use_extra_gpios)
0361 return 0;
0362 return 0444;
0363 case hwmon_in_min_alarm:
0364 if (channel > 8)
0365 return 0;
0366 return 0444;
0367 default:
0368 return 0;
0369 }
0370 case hwmon_curr:
0371 switch (attr) {
0372 case hwmon_curr_input:
0373 case hwmon_curr_max_alarm:
0374 return 0444;
0375 default:
0376 return 0;
0377 }
0378 case hwmon_power:
0379 switch (attr) {
0380 case hwmon_power_input:
0381 return 0444;
0382 default:
0383 return 0;
0384 }
0385 default:
0386 return 0;
0387 }
0388 }
0389
0390 static const struct hwmon_channel_info *ltc4245_info[] = {
0391 HWMON_CHANNEL_INFO(in,
0392 HWMON_I_INPUT,
0393 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0394 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0395 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0396 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0397 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0398 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0399 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0400 HWMON_I_INPUT | HWMON_I_MIN_ALARM,
0401 HWMON_I_INPUT,
0402 HWMON_I_INPUT,
0403 HWMON_I_INPUT),
0404 HWMON_CHANNEL_INFO(curr,
0405 HWMON_C_INPUT | HWMON_C_MAX_ALARM,
0406 HWMON_C_INPUT | HWMON_C_MAX_ALARM,
0407 HWMON_C_INPUT | HWMON_C_MAX_ALARM,
0408 HWMON_C_INPUT | HWMON_C_MAX_ALARM),
0409 HWMON_CHANNEL_INFO(power,
0410 HWMON_P_INPUT,
0411 HWMON_P_INPUT,
0412 HWMON_P_INPUT,
0413 HWMON_P_INPUT),
0414 NULL
0415 };
0416
0417 static const struct hwmon_ops ltc4245_hwmon_ops = {
0418 .is_visible = ltc4245_is_visible,
0419 .read = ltc4245_read,
0420 };
0421
0422 static const struct hwmon_chip_info ltc4245_chip_info = {
0423 .ops = <c4245_hwmon_ops,
0424 .info = ltc4245_info,
0425 };
0426
0427 static bool ltc4245_use_extra_gpios(struct i2c_client *client)
0428 {
0429 struct ltc4245_platform_data *pdata = dev_get_platdata(&client->dev);
0430 struct device_node *np = client->dev.of_node;
0431
0432
0433 if (pdata)
0434 return pdata->use_extra_gpios;
0435
0436
0437 if (of_find_property(np, "ltc4245,use-extra-gpios", NULL))
0438 return true;
0439
0440 return false;
0441 }
0442
0443 static int ltc4245_probe(struct i2c_client *client)
0444 {
0445 struct i2c_adapter *adapter = client->adapter;
0446 struct ltc4245_data *data;
0447 struct device *hwmon_dev;
0448
0449 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
0450 return -ENODEV;
0451
0452 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
0453 if (!data)
0454 return -ENOMEM;
0455
0456 data->client = client;
0457 mutex_init(&data->update_lock);
0458 data->use_extra_gpios = ltc4245_use_extra_gpios(client);
0459
0460
0461 i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00);
0462 i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00);
0463
0464 hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
0465 client->name, data,
0466 <c4245_chip_info,
0467 NULL);
0468 return PTR_ERR_OR_ZERO(hwmon_dev);
0469 }
0470
0471 static const struct i2c_device_id ltc4245_id[] = {
0472 { "ltc4245", 0 },
0473 { }
0474 };
0475 MODULE_DEVICE_TABLE(i2c, ltc4245_id);
0476
0477
0478 static struct i2c_driver ltc4245_driver = {
0479 .driver = {
0480 .name = "ltc4245",
0481 },
0482 .probe_new = ltc4245_probe,
0483 .id_table = ltc4245_id,
0484 };
0485
0486 module_i2c_driver(ltc4245_driver);
0487
0488 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
0489 MODULE_DESCRIPTION("LTC4245 driver");
0490 MODULE_LICENSE("GPL");