root/drivers/hwmon/ina209.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ina209_update_device
  2. ina209_from_reg
  3. ina209_to_reg
  4. ina209_interval_from_reg
  5. ina209_reg_from_interval
  6. ina209_interval_store
  7. ina209_interval_show
  8. ina209_history_store
  9. ina209_value_store
  10. ina209_value_show
  11. ina209_alarm_show
  12. ina209_restore_conf
  13. ina209_init_client
  14. ina209_probe
  15. ina209_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Driver for the Texas Instruments / Burr Brown INA209
   4  * Bidirectional Current/Power Monitor
   5  *
   6  * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
   7  *
   8  * Derived from Ira W. Snyder's original driver submission
   9  *      Copyright (C) 2008 Paul Hays <Paul.Hays@cattail.ca>
  10  *      Copyright (C) 2008-2009 Ira W. Snyder <iws@ovro.caltech.edu>
  11  *
  12  * Aligned with ina2xx driver
  13  *      Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
  14  *      Thanks to Jan Volkering
  15  *
  16  * Datasheet:
  17  * http://www.ti.com/lit/gpn/ina209
  18  */
  19 
  20 #include <linux/kernel.h>
  21 #include <linux/module.h>
  22 #include <linux/init.h>
  23 #include <linux/err.h>
  24 #include <linux/slab.h>
  25 #include <linux/bug.h>
  26 #include <linux/i2c.h>
  27 #include <linux/hwmon.h>
  28 #include <linux/hwmon-sysfs.h>
  29 
  30 #include <linux/platform_data/ina2xx.h>
  31 
  32 /* register definitions */
  33 #define INA209_CONFIGURATION            0x00
  34 #define INA209_STATUS                   0x01
  35 #define INA209_STATUS_MASK              0x02
  36 #define INA209_SHUNT_VOLTAGE            0x03
  37 #define INA209_BUS_VOLTAGE              0x04
  38 #define INA209_POWER                    0x05
  39 #define INA209_CURRENT                  0x06
  40 #define INA209_SHUNT_VOLTAGE_POS_PEAK   0x07
  41 #define INA209_SHUNT_VOLTAGE_NEG_PEAK   0x08
  42 #define INA209_BUS_VOLTAGE_MAX_PEAK     0x09
  43 #define INA209_BUS_VOLTAGE_MIN_PEAK     0x0a
  44 #define INA209_POWER_PEAK               0x0b
  45 #define INA209_SHUNT_VOLTAGE_POS_WARN   0x0c
  46 #define INA209_SHUNT_VOLTAGE_NEG_WARN   0x0d
  47 #define INA209_POWER_WARN               0x0e
  48 #define INA209_BUS_VOLTAGE_OVER_WARN    0x0f
  49 #define INA209_BUS_VOLTAGE_UNDER_WARN   0x10
  50 #define INA209_POWER_OVER_LIMIT         0x11
  51 #define INA209_BUS_VOLTAGE_OVER_LIMIT   0x12
  52 #define INA209_BUS_VOLTAGE_UNDER_LIMIT  0x13
  53 #define INA209_CRITICAL_DAC_POS         0x14
  54 #define INA209_CRITICAL_DAC_NEG         0x15
  55 #define INA209_CALIBRATION              0x16
  56 
  57 #define INA209_REGISTERS                0x17
  58 
  59 #define INA209_CONFIG_DEFAULT           0x3c47  /* PGA=8, full range */
  60 #define INA209_SHUNT_DEFAULT            10000   /* uOhm */
  61 
  62 struct ina209_data {
  63         struct i2c_client *client;
  64 
  65         struct mutex update_lock;
  66         bool valid;
  67         unsigned long last_updated;     /* in jiffies */
  68 
  69         u16 regs[INA209_REGISTERS];     /* All chip registers */
  70 
  71         u16 config_orig;                /* Original configuration */
  72         u16 calibration_orig;           /* Original calibration */
  73         u16 update_interval;
  74 };
  75 
  76 static struct ina209_data *ina209_update_device(struct device *dev)
  77 {
  78         struct ina209_data *data = dev_get_drvdata(dev);
  79         struct i2c_client *client = data->client;
  80         struct ina209_data *ret = data;
  81         s32 val;
  82         int i;
  83 
  84         mutex_lock(&data->update_lock);
  85 
  86         if (!data->valid ||
  87             time_after(jiffies, data->last_updated + data->update_interval)) {
  88                 for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
  89                         val = i2c_smbus_read_word_swapped(client, i);
  90                         if (val < 0) {
  91                                 ret = ERR_PTR(val);
  92                                 goto abort;
  93                         }
  94                         data->regs[i] = val;
  95                 }
  96                 data->last_updated = jiffies;
  97                 data->valid = true;
  98         }
  99 abort:
 100         mutex_unlock(&data->update_lock);
 101         return ret;
 102 }
 103 
 104 /*
 105  * Read a value from a device register and convert it to the
 106  * appropriate sysfs units
 107  */
 108 static long ina209_from_reg(const u8 reg, const u16 val)
 109 {
 110         switch (reg) {
 111         case INA209_SHUNT_VOLTAGE:
 112         case INA209_SHUNT_VOLTAGE_POS_PEAK:
 113         case INA209_SHUNT_VOLTAGE_NEG_PEAK:
 114         case INA209_SHUNT_VOLTAGE_POS_WARN:
 115         case INA209_SHUNT_VOLTAGE_NEG_WARN:
 116                 /* LSB=10 uV. Convert to mV. */
 117                 return DIV_ROUND_CLOSEST((s16)val, 100);
 118 
 119         case INA209_BUS_VOLTAGE:
 120         case INA209_BUS_VOLTAGE_MAX_PEAK:
 121         case INA209_BUS_VOLTAGE_MIN_PEAK:
 122         case INA209_BUS_VOLTAGE_OVER_WARN:
 123         case INA209_BUS_VOLTAGE_UNDER_WARN:
 124         case INA209_BUS_VOLTAGE_OVER_LIMIT:
 125         case INA209_BUS_VOLTAGE_UNDER_LIMIT:
 126                 /* LSB=4 mV, last 3 bits unused */
 127                 return (val >> 3) * 4;
 128 
 129         case INA209_CRITICAL_DAC_POS:
 130                 /* LSB=1 mV, in the upper 8 bits */
 131                 return val >> 8;
 132 
 133         case INA209_CRITICAL_DAC_NEG:
 134                 /* LSB=1 mV, in the upper 8 bits */
 135                 return -1 * (val >> 8);
 136 
 137         case INA209_POWER:
 138         case INA209_POWER_PEAK:
 139         case INA209_POWER_WARN:
 140         case INA209_POWER_OVER_LIMIT:
 141                 /* LSB=20 mW. Convert to uW */
 142                 return val * 20 * 1000L;
 143 
 144         case INA209_CURRENT:
 145                 /* LSB=1 mA (selected). Is in mA */
 146                 return (s16)val;
 147         }
 148 
 149         /* programmer goofed */
 150         WARN_ON_ONCE(1);
 151         return 0;
 152 }
 153 
 154 /*
 155  * Take a value and convert it to register format, clamping the value
 156  * to the appropriate range.
 157  */
 158 static int ina209_to_reg(u8 reg, u16 old, long val)
 159 {
 160         switch (reg) {
 161         case INA209_SHUNT_VOLTAGE_POS_WARN:
 162         case INA209_SHUNT_VOLTAGE_NEG_WARN:
 163                 /* Limit to +- 320 mV, 10 uV LSB */
 164                 return clamp_val(val, -320, 320) * 100;
 165 
 166         case INA209_BUS_VOLTAGE_OVER_WARN:
 167         case INA209_BUS_VOLTAGE_UNDER_WARN:
 168         case INA209_BUS_VOLTAGE_OVER_LIMIT:
 169         case INA209_BUS_VOLTAGE_UNDER_LIMIT:
 170                 /*
 171                  * Limit to 0-32000 mV, 4 mV LSB
 172                  *
 173                  * The last three bits aren't part of the value, but we'll
 174                  * preserve them in their original state.
 175                  */
 176                 return (DIV_ROUND_CLOSEST(clamp_val(val, 0, 32000), 4) << 3)
 177                   | (old & 0x7);
 178 
 179         case INA209_CRITICAL_DAC_NEG:
 180                 /*
 181                  * Limit to -255-0 mV, 1 mV LSB
 182                  * Convert the value to a positive value for the register
 183                  *
 184                  * The value lives in the top 8 bits only, be careful
 185                  * and keep original value of other bits.
 186                  */
 187                 return (clamp_val(-val, 0, 255) << 8) | (old & 0xff);
 188 
 189         case INA209_CRITICAL_DAC_POS:
 190                 /*
 191                  * Limit to 0-255 mV, 1 mV LSB
 192                  *
 193                  * The value lives in the top 8 bits only, be careful
 194                  * and keep original value of other bits.
 195                  */
 196                 return (clamp_val(val, 0, 255) << 8) | (old & 0xff);
 197 
 198         case INA209_POWER_WARN:
 199         case INA209_POWER_OVER_LIMIT:
 200                 /* 20 mW LSB */
 201                 return DIV_ROUND_CLOSEST(val, 20 * 1000);
 202         }
 203 
 204         /* Other registers are read-only, return access error */
 205         return -EACCES;
 206 }
 207 
 208 static int ina209_interval_from_reg(u16 reg)
 209 {
 210         return 68 >> (15 - ((reg >> 3) & 0x0f));
 211 }
 212 
 213 static u16 ina209_reg_from_interval(u16 config, long interval)
 214 {
 215         int i, adc;
 216 
 217         if (interval <= 0) {
 218                 adc = 8;
 219         } else {
 220                 adc = 15;
 221                 for (i = 34 + 34 / 2; i; i >>= 1) {
 222                         if (i < interval)
 223                                 break;
 224                         adc--;
 225                 }
 226         }
 227         return (config & 0xf807) | (adc << 3) | (adc << 7);
 228 }
 229 
 230 static ssize_t ina209_interval_store(struct device *dev,
 231                                      struct device_attribute *da,
 232                                      const char *buf, size_t count)
 233 {
 234         struct ina209_data *data = ina209_update_device(dev);
 235         long val;
 236         u16 regval;
 237         int ret;
 238 
 239         if (IS_ERR(data))
 240                 return PTR_ERR(data);
 241 
 242         ret = kstrtol(buf, 10, &val);
 243         if (ret < 0)
 244                 return ret;
 245 
 246         mutex_lock(&data->update_lock);
 247         regval = ina209_reg_from_interval(data->regs[INA209_CONFIGURATION],
 248                                           val);
 249         i2c_smbus_write_word_swapped(data->client, INA209_CONFIGURATION,
 250                                      regval);
 251         data->regs[INA209_CONFIGURATION] = regval;
 252         data->update_interval = ina209_interval_from_reg(regval);
 253         mutex_unlock(&data->update_lock);
 254         return count;
 255 }
 256 
 257 static ssize_t ina209_interval_show(struct device *dev,
 258                                     struct device_attribute *da, char *buf)
 259 {
 260         struct ina209_data *data = dev_get_drvdata(dev);
 261 
 262         return snprintf(buf, PAGE_SIZE, "%d\n", data->update_interval);
 263 }
 264 
 265 /*
 266  * History is reset by writing 1 into bit 0 of the respective peak register.
 267  * Since more than one peak register may be affected by the scope of a
 268  * reset_history attribute write, use a bit mask in attr->index to identify
 269  * which registers are affected.
 270  */
 271 static u16 ina209_reset_history_regs[] = {
 272         INA209_SHUNT_VOLTAGE_POS_PEAK,
 273         INA209_SHUNT_VOLTAGE_NEG_PEAK,
 274         INA209_BUS_VOLTAGE_MAX_PEAK,
 275         INA209_BUS_VOLTAGE_MIN_PEAK,
 276         INA209_POWER_PEAK
 277 };
 278 
 279 static ssize_t ina209_history_store(struct device *dev,
 280                                     struct device_attribute *da,
 281                                     const char *buf, size_t count)
 282 {
 283         struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 284         struct ina209_data *data = dev_get_drvdata(dev);
 285         struct i2c_client *client = data->client;
 286         u32 mask = attr->index;
 287         long val;
 288         int i, ret;
 289 
 290         ret = kstrtol(buf, 10, &val);
 291         if (ret < 0)
 292                 return ret;
 293 
 294         mutex_lock(&data->update_lock);
 295         for (i = 0; i < ARRAY_SIZE(ina209_reset_history_regs); i++) {
 296                 if (mask & (1 << i))
 297                         i2c_smbus_write_word_swapped(client,
 298                                         ina209_reset_history_regs[i], 1);
 299         }
 300         data->valid = false;
 301         mutex_unlock(&data->update_lock);
 302         return count;
 303 }
 304 
 305 static ssize_t ina209_value_store(struct device *dev,
 306                                   struct device_attribute *da,
 307                                   const char *buf, size_t count)
 308 {
 309         struct ina209_data *data = ina209_update_device(dev);
 310         struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 311         int reg = attr->index;
 312         long val;
 313         int ret;
 314 
 315         if (IS_ERR(data))
 316                 return PTR_ERR(data);
 317 
 318         ret = kstrtol(buf, 10, &val);
 319         if (ret < 0)
 320                 return ret;
 321 
 322         mutex_lock(&data->update_lock);
 323         ret = ina209_to_reg(reg, data->regs[reg], val);
 324         if (ret < 0) {
 325                 count = ret;
 326                 goto abort;
 327         }
 328         i2c_smbus_write_word_swapped(data->client, reg, ret);
 329         data->regs[reg] = ret;
 330 abort:
 331         mutex_unlock(&data->update_lock);
 332         return count;
 333 }
 334 
 335 static ssize_t ina209_value_show(struct device *dev,
 336                                  struct device_attribute *da, char *buf)
 337 {
 338         struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 339         struct ina209_data *data = ina209_update_device(dev);
 340         long val;
 341 
 342         if (IS_ERR(data))
 343                 return PTR_ERR(data);
 344 
 345         val = ina209_from_reg(attr->index, data->regs[attr->index]);
 346         return snprintf(buf, PAGE_SIZE, "%ld\n", val);
 347 }
 348 
 349 static ssize_t ina209_alarm_show(struct device *dev,
 350                                  struct device_attribute *da, char *buf)
 351 {
 352         struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 353         struct ina209_data *data = ina209_update_device(dev);
 354         const unsigned int mask = attr->index;
 355         u16 status;
 356 
 357         if (IS_ERR(data))
 358                 return PTR_ERR(data);
 359 
 360         status = data->regs[INA209_STATUS];
 361 
 362         /*
 363          * All alarms are in the INA209_STATUS register. To avoid a long
 364          * switch statement, the mask is passed in attr->index
 365          */
 366         return snprintf(buf, PAGE_SIZE, "%u\n", !!(status & mask));
 367 }
 368 
 369 /* Shunt voltage, history, limits, alarms */
 370 static SENSOR_DEVICE_ATTR_RO(in0_input, ina209_value, INA209_SHUNT_VOLTAGE);
 371 static SENSOR_DEVICE_ATTR_RO(in0_input_highest, ina209_value,
 372                              INA209_SHUNT_VOLTAGE_POS_PEAK);
 373 static SENSOR_DEVICE_ATTR_RO(in0_input_lowest, ina209_value,
 374                              INA209_SHUNT_VOLTAGE_NEG_PEAK);
 375 static SENSOR_DEVICE_ATTR_WO(in0_reset_history, ina209_history,
 376                              (1 << 0) | (1 << 1));
 377 static SENSOR_DEVICE_ATTR_RW(in0_max, ina209_value,
 378                              INA209_SHUNT_VOLTAGE_POS_WARN);
 379 static SENSOR_DEVICE_ATTR_RW(in0_min, ina209_value,
 380                              INA209_SHUNT_VOLTAGE_NEG_WARN);
 381 static SENSOR_DEVICE_ATTR_RW(in0_crit_max, ina209_value,
 382                              INA209_CRITICAL_DAC_POS);
 383 static SENSOR_DEVICE_ATTR_RW(in0_crit_min, ina209_value,
 384                              INA209_CRITICAL_DAC_NEG);
 385 
 386 static SENSOR_DEVICE_ATTR_RO(in0_min_alarm, ina209_alarm, 1 << 11);
 387 static SENSOR_DEVICE_ATTR_RO(in0_max_alarm, ina209_alarm, 1 << 12);
 388 static SENSOR_DEVICE_ATTR_RO(in0_crit_min_alarm, ina209_alarm, 1 << 6);
 389 static SENSOR_DEVICE_ATTR_RO(in0_crit_max_alarm, ina209_alarm, 1 << 7);
 390 
 391 /* Bus voltage, history, limits, alarms */
 392 static SENSOR_DEVICE_ATTR_RO(in1_input, ina209_value, INA209_BUS_VOLTAGE);
 393 static SENSOR_DEVICE_ATTR_RO(in1_input_highest, ina209_value,
 394                              INA209_BUS_VOLTAGE_MAX_PEAK);
 395 static SENSOR_DEVICE_ATTR_RO(in1_input_lowest, ina209_value,
 396                              INA209_BUS_VOLTAGE_MIN_PEAK);
 397 static SENSOR_DEVICE_ATTR_WO(in1_reset_history, ina209_history,
 398                              (1 << 2) | (1 << 3));
 399 static SENSOR_DEVICE_ATTR_RW(in1_max, ina209_value,
 400                              INA209_BUS_VOLTAGE_OVER_WARN);
 401 static SENSOR_DEVICE_ATTR_RW(in1_min, ina209_value,
 402                              INA209_BUS_VOLTAGE_UNDER_WARN);
 403 static SENSOR_DEVICE_ATTR_RW(in1_crit_max, ina209_value,
 404                              INA209_BUS_VOLTAGE_OVER_LIMIT);
 405 static SENSOR_DEVICE_ATTR_RW(in1_crit_min, ina209_value,
 406                              INA209_BUS_VOLTAGE_UNDER_LIMIT);
 407 
 408 static SENSOR_DEVICE_ATTR_RO(in1_min_alarm, ina209_alarm, 1 << 14);
 409 static SENSOR_DEVICE_ATTR_RO(in1_max_alarm, ina209_alarm, 1 << 15);
 410 static SENSOR_DEVICE_ATTR_RO(in1_crit_min_alarm, ina209_alarm, 1 << 9);
 411 static SENSOR_DEVICE_ATTR_RO(in1_crit_max_alarm, ina209_alarm, 1 << 10);
 412 
 413 /* Power */
 414 static SENSOR_DEVICE_ATTR_RO(power1_input, ina209_value, INA209_POWER);
 415 static SENSOR_DEVICE_ATTR_RO(power1_input_highest, ina209_value,
 416                              INA209_POWER_PEAK);
 417 static SENSOR_DEVICE_ATTR_WO(power1_reset_history, ina209_history, 1 << 4);
 418 static SENSOR_DEVICE_ATTR_RW(power1_max, ina209_value, INA209_POWER_WARN);
 419 static SENSOR_DEVICE_ATTR_RW(power1_crit, ina209_value,
 420                              INA209_POWER_OVER_LIMIT);
 421 
 422 static SENSOR_DEVICE_ATTR_RO(power1_max_alarm, ina209_alarm, 1 << 13);
 423 static SENSOR_DEVICE_ATTR_RO(power1_crit_alarm, ina209_alarm, 1 << 8);
 424 
 425 /* Current */
 426 static SENSOR_DEVICE_ATTR_RO(curr1_input, ina209_value, INA209_CURRENT);
 427 
 428 static SENSOR_DEVICE_ATTR_RW(update_interval, ina209_interval, 0);
 429 
 430 /*
 431  * Finally, construct an array of pointers to members of the above objects,
 432  * as required for sysfs_create_group()
 433  */
 434 static struct attribute *ina209_attrs[] = {
 435         &sensor_dev_attr_in0_input.dev_attr.attr,
 436         &sensor_dev_attr_in0_input_highest.dev_attr.attr,
 437         &sensor_dev_attr_in0_input_lowest.dev_attr.attr,
 438         &sensor_dev_attr_in0_reset_history.dev_attr.attr,
 439         &sensor_dev_attr_in0_max.dev_attr.attr,
 440         &sensor_dev_attr_in0_min.dev_attr.attr,
 441         &sensor_dev_attr_in0_crit_max.dev_attr.attr,
 442         &sensor_dev_attr_in0_crit_min.dev_attr.attr,
 443         &sensor_dev_attr_in0_max_alarm.dev_attr.attr,
 444         &sensor_dev_attr_in0_min_alarm.dev_attr.attr,
 445         &sensor_dev_attr_in0_crit_max_alarm.dev_attr.attr,
 446         &sensor_dev_attr_in0_crit_min_alarm.dev_attr.attr,
 447 
 448         &sensor_dev_attr_in1_input.dev_attr.attr,
 449         &sensor_dev_attr_in1_input_highest.dev_attr.attr,
 450         &sensor_dev_attr_in1_input_lowest.dev_attr.attr,
 451         &sensor_dev_attr_in1_reset_history.dev_attr.attr,
 452         &sensor_dev_attr_in1_max.dev_attr.attr,
 453         &sensor_dev_attr_in1_min.dev_attr.attr,
 454         &sensor_dev_attr_in1_crit_max.dev_attr.attr,
 455         &sensor_dev_attr_in1_crit_min.dev_attr.attr,
 456         &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
 457         &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
 458         &sensor_dev_attr_in1_crit_max_alarm.dev_attr.attr,
 459         &sensor_dev_attr_in1_crit_min_alarm.dev_attr.attr,
 460 
 461         &sensor_dev_attr_power1_input.dev_attr.attr,
 462         &sensor_dev_attr_power1_input_highest.dev_attr.attr,
 463         &sensor_dev_attr_power1_reset_history.dev_attr.attr,
 464         &sensor_dev_attr_power1_max.dev_attr.attr,
 465         &sensor_dev_attr_power1_crit.dev_attr.attr,
 466         &sensor_dev_attr_power1_max_alarm.dev_attr.attr,
 467         &sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
 468 
 469         &sensor_dev_attr_curr1_input.dev_attr.attr,
 470 
 471         &sensor_dev_attr_update_interval.dev_attr.attr,
 472 
 473         NULL,
 474 };
 475 ATTRIBUTE_GROUPS(ina209);
 476 
 477 static void ina209_restore_conf(struct i2c_client *client,
 478                                 struct ina209_data *data)
 479 {
 480         /* Restore initial configuration */
 481         i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
 482                                      data->config_orig);
 483         i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
 484                                      data->calibration_orig);
 485 }
 486 
 487 static int ina209_init_client(struct i2c_client *client,
 488                               struct ina209_data *data)
 489 {
 490         struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev);
 491         u32 shunt;
 492         int reg;
 493 
 494         reg = i2c_smbus_read_word_swapped(client, INA209_CALIBRATION);
 495         if (reg < 0)
 496                 return reg;
 497         data->calibration_orig = reg;
 498 
 499         reg = i2c_smbus_read_word_swapped(client, INA209_CONFIGURATION);
 500         if (reg < 0)
 501                 return reg;
 502         data->config_orig = reg;
 503 
 504         if (pdata) {
 505                 if (pdata->shunt_uohms <= 0)
 506                         return -EINVAL;
 507                 shunt = pdata->shunt_uohms;
 508         } else if (!of_property_read_u32(client->dev.of_node, "shunt-resistor",
 509                                          &shunt)) {
 510                 if (shunt == 0)
 511                         return -EINVAL;
 512         } else {
 513                 shunt = data->calibration_orig ?
 514                   40960000 / data->calibration_orig : INA209_SHUNT_DEFAULT;
 515         }
 516 
 517         i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
 518                                      INA209_CONFIG_DEFAULT);
 519         data->update_interval = ina209_interval_from_reg(INA209_CONFIG_DEFAULT);
 520 
 521         /*
 522          * Calibrate current LSB to 1mA. Shunt is in uOhms.
 523          * See equation 13 in datasheet.
 524          */
 525         i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
 526                                      clamp_val(40960000 / shunt, 1, 65535));
 527 
 528         /* Clear status register */
 529         i2c_smbus_read_word_swapped(client, INA209_STATUS);
 530 
 531         return 0;
 532 }
 533 
 534 static int ina209_probe(struct i2c_client *client,
 535                         const struct i2c_device_id *id)
 536 {
 537         struct i2c_adapter *adapter = client->adapter;
 538         struct ina209_data *data;
 539         struct device *hwmon_dev;
 540         int ret;
 541 
 542         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
 543                 return -ENODEV;
 544 
 545         data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
 546         if (!data)
 547                 return -ENOMEM;
 548 
 549         i2c_set_clientdata(client, data);
 550         data->client = client;
 551         mutex_init(&data->update_lock);
 552 
 553         ret = ina209_init_client(client, data);
 554         if (ret)
 555                 return ret;
 556 
 557         hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
 558                                                            client->name,
 559                                                            data, ina209_groups);
 560         if (IS_ERR(hwmon_dev)) {
 561                 ret = PTR_ERR(hwmon_dev);
 562                 goto out_restore_conf;
 563         }
 564 
 565         return 0;
 566 
 567 out_restore_conf:
 568         ina209_restore_conf(client, data);
 569         return ret;
 570 }
 571 
 572 static int ina209_remove(struct i2c_client *client)
 573 {
 574         struct ina209_data *data = i2c_get_clientdata(client);
 575 
 576         ina209_restore_conf(client, data);
 577 
 578         return 0;
 579 }
 580 
 581 static const struct i2c_device_id ina209_id[] = {
 582         { "ina209", 0 },
 583         { }
 584 };
 585 MODULE_DEVICE_TABLE(i2c, ina209_id);
 586 
 587 static const struct of_device_id __maybe_unused ina209_of_match[] = {
 588         { .compatible = "ti,ina209" },
 589         { },
 590 };
 591 MODULE_DEVICE_TABLE(of, ina209_of_match);
 592 
 593 /* This is the driver that will be inserted */
 594 static struct i2c_driver ina209_driver = {
 595         .class          = I2C_CLASS_HWMON,
 596         .driver = {
 597                 .name   = "ina209",
 598                 .of_match_table = of_match_ptr(ina209_of_match),
 599         },
 600         .probe          = ina209_probe,
 601         .remove         = ina209_remove,
 602         .id_table       = ina209_id,
 603 };
 604 
 605 module_i2c_driver(ina209_driver);
 606 
 607 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>, Paul Hays <Paul.Hays@cattail.ca>, Guenter Roeck <linux@roeck-us.net>");
 608 MODULE_DESCRIPTION("INA209 driver");
 609 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */