Commit 920fa1ffce48d36d7e7bc54eb38c58313bc0a667

Authored by Guenter Roeck
Committed by Linus Torvalds
1 parent cfa3b24c38

hwmon: driver for SMM665 Six-Channel Active DC Output Controller/Monitor

This driver adds support for the monitoring features of the Summit
Microelectronics SMM665 Six-Channel Active DC Output Controller/Monitor.

Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 5 changed files with 923 additions and 0 deletions Side-by-side Diff

Documentation/hwmon/smm665
  1 +Kernel driver smm665
  2 +====================
  3 +
  4 +Supported chips:
  5 + * Summit Microelectronics SMM465
  6 + Prefix: 'smm465'
  7 + Addresses scanned: -
  8 + Datasheet:
  9 + http://www.summitmicro.com/prod_select/summary/SMM465/SMM465DS.pdf
  10 + * Summit Microelectronics SMM665, SMM665B
  11 + Prefix: 'smm665'
  12 + Addresses scanned: -
  13 + Datasheet:
  14 + http://www.summitmicro.com/prod_select/summary/SMM665/SMM665B_2089_20.pdf
  15 + * Summit Microelectronics SMM665C
  16 + Prefix: 'smm665c'
  17 + Addresses scanned: -
  18 + Datasheet:
  19 + http://www.summitmicro.com/prod_select/summary/SMM665C/SMM665C_2125.pdf
  20 + * Summit Microelectronics SMM764
  21 + Prefix: 'smm764'
  22 + Addresses scanned: -
  23 + Datasheet:
  24 + http://www.summitmicro.com/prod_select/summary/SMM764/SMM764_2098.pdf
  25 + * Summit Microelectronics SMM766, SMM766B
  26 + Prefix: 'smm766'
  27 + Addresses scanned: -
  28 + Datasheets:
  29 + http://www.summitmicro.com/prod_select/summary/SMM766/SMM766_2086.pdf
  30 + http://www.summitmicro.com/prod_select/summary/SMM766B/SMM766B_2122.pdf
  31 +
  32 +Author: Guenter Roeck <guenter.roeck@ericsson.com>
  33 +
  34 +
  35 +Module Parameters
  36 +-----------------
  37 +
  38 +* vref: int
  39 + Default: 1250 (mV)
  40 + Reference voltage on VREF_ADC pin in mV. It should not be necessary to set
  41 + this parameter unless a non-default reference voltage is used.
  42 +
  43 +
  44 +Description
  45 +-----------
  46 +
  47 +[From datasheet] The SMM665 is an Active DC Output power supply Controller
  48 +that monitors, margins and cascade sequences power. The part monitors six
  49 +power supply channels as well as VDD, 12V input, two general-purpose analog
  50 +inputs and an internal temperature sensor using a 10-bit ADC.
  51 +
  52 +Each monitored channel has its own high and low limits, plus a critical
  53 +limit.
  54 +
  55 +Support for SMM465, SMM764, and SMM766 has been implemented but is untested.
  56 +
  57 +
  58 +Usage Notes
  59 +-----------
  60 +
  61 +This driver does not probe for devices, since there is no register which
  62 +can be safely used to identify the chip. You will have to instantiate
  63 +the devices explicitly. When instantiating the device, you have to specify
  64 +its configuration register address.
  65 +
  66 +Example: the following will load the driver for an SMM665 at address 0x57
  67 +on I2C bus #1:
  68 +$ modprobe smm665
  69 +$ echo smm665 0x57 > /sys/bus/i2c/devices/i2c-1/new_device
  70 +
  71 +
  72 +Sysfs entries
  73 +-------------
  74 +
  75 +This driver uses the values in the datasheet to convert ADC register values
  76 +into the values specified in the sysfs-interface document. All attributes are
  77 +read only.
  78 +
  79 +Min, max, lcrit, and crit values are used by the chip to trigger external signals
  80 +and/or other activity. Triggered signals can include HEALTHY, RST, Power Off,
  81 +or Fault depending on the chip configuration. The driver reports values as lcrit
  82 +or crit if exceeding the limits triggers RST, Power Off, or Fault, and as min or
  83 +max otherwise. For details please see the SMM665 datasheet.
  84 +
  85 +For SMM465 and SMM764, values for Channel E and F are reported but undefined.
  86 +
  87 +in1_input 12V input voltage (mV)
  88 +in2_input 3.3V (VDD) input voltage (mV)
  89 +in3_input Channel A voltage (mV)
  90 +in4_input Channel B voltage (mV)
  91 +in5_input Channel C voltage (mV)
  92 +in6_input Channel D voltage (mV)
  93 +in7_input Channel E voltage (mV)
  94 +in8_input Channel F voltage (mV)
  95 +in9_input AIN1 voltage (mV)
  96 +in10_input AIN2 voltage (mV)
  97 +
  98 +in1_min 12v input minimum voltage (mV)
  99 +in2_min 3.3V (VDD) input minimum voltage (mV)
  100 +in3_min Channel A minimum voltage (mV)
  101 +in4_min Channel B minimum voltage (mV)
  102 +in5_min Channel C minimum voltage (mV)
  103 +in6_min Channel D minimum voltage (mV)
  104 +in7_min Channel E minimum voltage (mV)
  105 +in8_min Channel F minimum voltage (mV)
  106 +in9_min AIN1 minimum voltage (mV)
  107 +in10_min AIN2 minimum voltage (mV)
  108 +
  109 +in1_max 12v input maximum voltage (mV)
  110 +in2_max 3.3V (VDD) input maximum voltage (mV)
  111 +in3_max Channel A maximum voltage (mV)
  112 +in4_max Channel B maximum voltage (mV)
  113 +in5_max Channel C maximum voltage (mV)
  114 +in6_max Channel D maximum voltage (mV)
  115 +in7_max Channel E maximum voltage (mV)
  116 +in8_max Channel F maximum voltage (mV)
  117 +in9_max AIN1 maximum voltage (mV)
  118 +in10_max AIN2 maximum voltage (mV)
  119 +
  120 +in1_lcrit 12v input critical minimum voltage (mV)
  121 +in2_lcrit 3.3V (VDD) input critical minimum voltage (mV)
  122 +in3_lcrit Channel A critical minimum voltage (mV)
  123 +in4_lcrit Channel B critical minimum voltage (mV)
  124 +in5_lcrit Channel C critical minimum voltage (mV)
  125 +in6_lcrit Channel D critical minimum voltage (mV)
  126 +in7_lcrit Channel E critical minimum voltage (mV)
  127 +in8_lcrit Channel F critical minimum voltage (mV)
  128 +in9_lcrit AIN1 critical minimum voltage (mV)
  129 +in10_lcrit AIN2 critical minimum voltage (mV)
  130 +
  131 +in1_crit 12v input critical maximum voltage (mV)
  132 +in2_crit 3.3V (VDD) input critical maximum voltage (mV)
  133 +in3_crit Channel A critical maximum voltage (mV)
  134 +in4_crit Channel B critical maximum voltage (mV)
  135 +in5_crit Channel C critical maximum voltage (mV)
  136 +in6_crit Channel D critical maximum voltage (mV)
  137 +in7_crit Channel E critical maximum voltage (mV)
  138 +in8_crit Channel F critical maximum voltage (mV)
  139 +in9_crit AIN1 critical maximum voltage (mV)
  140 +in10_crit AIN2 critical maximum voltage (mV)
  141 +
  142 +in1_crit_alarm 12v input critical alarm
  143 +in2_crit_alarm 3.3V (VDD) input critical alarm
  144 +in3_crit_alarm Channel A critical alarm
  145 +in4_crit_alarm Channel B critical alarm
  146 +in5_crit_alarm Channel C critical alarm
  147 +in6_crit_alarm Channel D critical alarm
  148 +in7_crit_alarm Channel E critical alarm
  149 +in8_crit_alarm Channel F critical alarm
  150 +in9_crit_alarm AIN1 critical alarm
  151 +in10_crit_alarm AIN2 critical alarm
  152 +
  153 +temp1_input Chip tempererature
  154 +temp1_min Mimimum chip tempererature
  155 +temp1_max Maximum chip tempererature
  156 +temp1_crit Critical chip tempererature
  157 +temp1_crit_alarm Temperature critical alarm
... ... @@ -5251,6 +5251,13 @@
5251 5251 S: Odd Fixes
5252 5252 F: drivers/net/smc91x.*
5253 5253  
  5254 +SMM665 HARDWARE MONITOR DRIVER
  5255 +M: Guenter Roeck <linux@roeck-us.net>
  5256 +L: lm-sensors@lm-sensors.org
  5257 +S: Maintained
  5258 +F: Documentation/hwmon/smm665
  5259 +F: drivers/hwmon/smm665.c
  5260 +
5254 5261 SMSC47B397 HARDWARE MONITOR DRIVER
5255 5262 M: "Mark M. Hoffman" <mhoffman@lightlink.com>
5256 5263 L: lm-sensors@lm-sensors.org
drivers/hwmon/Kconfig
... ... @@ -756,6 +756,21 @@
756 756 This driver can also be built as a module. If so, the module
757 757 will be called sis5595.
758 758  
  759 +config SENSORS_SMM665
  760 + tristate "Summit Microelectronics SMM665"
  761 + depends on I2C && EXPERIMENTAL
  762 + default n
  763 + help
  764 + If you say yes here you get support for the hardware monitoring
  765 + features of the Summit Microelectronics SMM665/SMM665B Six-Channel
  766 + Active DC Output Controller / Monitor.
  767 +
  768 + Other supported chips are SMM465, SMM665C, SMM764, and SMM766.
  769 + Support for those chips is untested.
  770 +
  771 + This driver can also be built as a module. If so, the module will
  772 + be called smm665.
  773 +
759 774 config SENSORS_DME1737
760 775 tristate "SMSC DME1737, SCH311x and compatibles"
761 776 depends on I2C && EXPERIMENTAL
drivers/hwmon/Makefile
... ... @@ -88,6 +88,7 @@
88 88 obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o
89 89 obj-$(CONFIG_SENSORS_SHT15) += sht15.o
90 90 obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
  91 +obj-$(CONFIG_SENSORS_SMM665) += smm665.o
91 92 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
92 93 obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
93 94 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
drivers/hwmon/smm665.c
  1 +/*
  2 + * Driver for SMM665 Power Controller / Monitor
  3 + *
  4 + * Copyright (C) 2010 Ericsson AB.
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; version 2 of the License.
  9 + *
  10 + * This driver should also work for SMM465, SMM764, and SMM766, but is untested
  11 + * for those chips. Only monitoring functionality is implemented.
  12 + *
  13 + * Datasheets:
  14 + * http://www.summitmicro.com/prod_select/summary/SMM665/SMM665B_2089_20.pdf
  15 + * http://www.summitmicro.com/prod_select/summary/SMM766B/SMM766B_2122.pdf
  16 + */
  17 +
  18 +#include <linux/kernel.h>
  19 +#include <linux/module.h>
  20 +#include <linux/init.h>
  21 +#include <linux/err.h>
  22 +#include <linux/slab.h>
  23 +#include <linux/i2c.h>
  24 +#include <linux/hwmon.h>
  25 +#include <linux/hwmon-sysfs.h>
  26 +#include <linux/delay.h>
  27 +
  28 +/* Internal reference voltage (VREF, x 1000 */
  29 +#define SMM665_VREF_ADC_X1000 1250
  30 +
  31 +/* module parameters */
  32 +static int vref = SMM665_VREF_ADC_X1000;
  33 +module_param(vref, int, 0);
  34 +MODULE_PARM_DESC(vref, "Reference voltage in mV");
  35 +
  36 +enum chips { smm465, smm665, smm665c, smm764, smm766 };
  37 +
  38 +/*
  39 + * ADC channel addresses
  40 + */
  41 +#define SMM665_MISC16_ADC_DATA_A 0x00
  42 +#define SMM665_MISC16_ADC_DATA_B 0x01
  43 +#define SMM665_MISC16_ADC_DATA_C 0x02
  44 +#define SMM665_MISC16_ADC_DATA_D 0x03
  45 +#define SMM665_MISC16_ADC_DATA_E 0x04
  46 +#define SMM665_MISC16_ADC_DATA_F 0x05
  47 +#define SMM665_MISC16_ADC_DATA_VDD 0x06
  48 +#define SMM665_MISC16_ADC_DATA_12V 0x07
  49 +#define SMM665_MISC16_ADC_DATA_INT_TEMP 0x08
  50 +#define SMM665_MISC16_ADC_DATA_AIN1 0x09
  51 +#define SMM665_MISC16_ADC_DATA_AIN2 0x0a
  52 +
  53 +/*
  54 + * Command registers
  55 + */
  56 +#define SMM665_MISC8_CMD_STS 0x80
  57 +#define SMM665_MISC8_STATUS1 0x81
  58 +#define SMM665_MISC8_STATUSS2 0x82
  59 +#define SMM665_MISC8_IO_POLARITY 0x83
  60 +#define SMM665_MISC8_PUP_POLARITY 0x84
  61 +#define SMM665_MISC8_ADOC_STATUS1 0x85
  62 +#define SMM665_MISC8_ADOC_STATUS2 0x86
  63 +#define SMM665_MISC8_WRITE_PROT 0x87
  64 +#define SMM665_MISC8_STS_TRACK 0x88
  65 +
  66 +/*
  67 + * Configuration registers and register groups
  68 + */
  69 +#define SMM665_ADOC_ENABLE 0x0d
  70 +#define SMM665_LIMIT_BASE 0x80 /* First limit register */
  71 +
  72 +/*
  73 + * Limit register bit masks
  74 + */
  75 +#define SMM665_TRIGGER_RST 0x8000
  76 +#define SMM665_TRIGGER_HEALTHY 0x4000
  77 +#define SMM665_TRIGGER_POWEROFF 0x2000
  78 +#define SMM665_TRIGGER_SHUTDOWN 0x1000
  79 +#define SMM665_ADC_MASK 0x03ff
  80 +
  81 +#define smm665_is_critical(lim) ((lim) & (SMM665_TRIGGER_RST \
  82 + | SMM665_TRIGGER_POWEROFF \
  83 + | SMM665_TRIGGER_SHUTDOWN))
  84 +/*
  85 + * Fault register bit definitions
  86 + * Values are merged from status registers 1/2,
  87 + * with status register 1 providing the upper 8 bits.
  88 + */
  89 +#define SMM665_FAULT_A 0x0001
  90 +#define SMM665_FAULT_B 0x0002
  91 +#define SMM665_FAULT_C 0x0004
  92 +#define SMM665_FAULT_D 0x0008
  93 +#define SMM665_FAULT_E 0x0010
  94 +#define SMM665_FAULT_F 0x0020
  95 +#define SMM665_FAULT_VDD 0x0040
  96 +#define SMM665_FAULT_12V 0x0080
  97 +#define SMM665_FAULT_TEMP 0x0100
  98 +#define SMM665_FAULT_AIN1 0x0200
  99 +#define SMM665_FAULT_AIN2 0x0400
  100 +
  101 +/*
  102 + * I2C Register addresses
  103 + *
  104 + * The configuration register needs to be the configured base register.
  105 + * The command/status register address is derived from it.
  106 + */
  107 +#define SMM665_REGMASK 0x78
  108 +#define SMM665_CMDREG_BASE 0x48
  109 +#define SMM665_CONFREG_BASE 0x50
  110 +
  111 +/*
  112 + * Equations given by chip manufacturer to calculate voltage/temperature values
  113 + * vref = Reference voltage on VREF_ADC pin (module parameter)
  114 + * adc = 10bit ADC value read back from registers
  115 + */
  116 +
  117 +/* Voltage A-F and VDD */
  118 +#define SMM665_VMON_ADC_TO_VOLTS(adc) ((adc) * vref / 256)
  119 +
  120 +/* Voltage 12VIN */
  121 +#define SMM665_12VIN_ADC_TO_VOLTS(adc) ((adc) * vref * 3 / 256)
  122 +
  123 +/* Voltage AIN1, AIN2 */
  124 +#define SMM665_AIN_ADC_TO_VOLTS(adc) ((adc) * vref / 512)
  125 +
  126 +/* Temp Sensor */
  127 +#define SMM665_TEMP_ADC_TO_CELSIUS(adc) ((adc) <= 511) ? \
  128 + ((int)(adc) * 1000 / 4) : \
  129 + (((int)(adc) - 0x400) * 1000 / 4)
  130 +
  131 +#define SMM665_NUM_ADC 11
  132 +
  133 +/*
  134 + * Chip dependent ADC conversion time, in uS
  135 + */
  136 +#define SMM665_ADC_WAIT_SMM665 70
  137 +#define SMM665_ADC_WAIT_SMM766 185
  138 +
  139 +struct smm665_data {
  140 + enum chips type;
  141 + int conversion_time; /* ADC conversion time */
  142 + struct device *hwmon_dev;
  143 + struct mutex update_lock;
  144 + bool valid;
  145 + unsigned long last_updated; /* in jiffies */
  146 + u16 adc[SMM665_NUM_ADC]; /* adc values (raw) */
  147 + u16 faults; /* fault status */
  148 + /* The following values are in mV */
  149 + int critical_min_limit[SMM665_NUM_ADC];
  150 + int alarm_min_limit[SMM665_NUM_ADC];
  151 + int critical_max_limit[SMM665_NUM_ADC];
  152 + int alarm_max_limit[SMM665_NUM_ADC];
  153 + struct i2c_client *cmdreg;
  154 +};
  155 +
  156 +/*
  157 + * smm665_read16()
  158 + *
  159 + * Read 16 bit value from <reg>, <reg+1>. Upper 8 bits are in <reg>.
  160 + */
  161 +static int smm665_read16(struct i2c_client *client, int reg)
  162 +{
  163 + int rv, val;
  164 +
  165 + rv = i2c_smbus_read_byte_data(client, reg);
  166 + if (rv < 0)
  167 + return rv;
  168 + val = rv << 8;
  169 + rv = i2c_smbus_read_byte_data(client, reg + 1);
  170 + if (rv < 0)
  171 + return rv;
  172 + val |= rv;
  173 + return val;
  174 +}
  175 +
  176 +/*
  177 + * Read adc value.
  178 + */
  179 +static int smm665_read_adc(struct smm665_data *data, int adc)
  180 +{
  181 + struct i2c_client *client = data->cmdreg;
  182 + int rv;
  183 + int radc;
  184 +
  185 + /*
  186 + * Algorithm for reading ADC, per SMM665 datasheet
  187 + *
  188 + * {[S][addr][W][Ack]} {[offset][Ack]} {[S][addr][R][Nack]}
  189 + * [wait conversion time]
  190 + * {[S][addr][R][Ack]} {[datahi][Ack]} {[datalo][Ack][P]}
  191 + *
  192 + * To implement the first part of this exchange,
  193 + * do a full read transaction and expect a failure/Nack.
  194 + * This sets up the address pointer on the SMM665
  195 + * and starts the ADC conversion.
  196 + * Then do a two-byte read transaction.
  197 + */
  198 + rv = i2c_smbus_read_byte_data(client, adc << 3);
  199 + if (rv != -ENXIO) {
  200 + /*
  201 + * We expect ENXIO to reflect NACK
  202 + * (per Documentation/i2c/fault-codes).
  203 + * Everything else is an error.
  204 + */
  205 + dev_dbg(&client->dev,
  206 + "Unexpected return code %d when setting ADC index", rv);
  207 + return (rv < 0) ? rv : -EIO;
  208 + }
  209 +
  210 + udelay(data->conversion_time);
  211 +
  212 + /*
  213 + * Now read two bytes.
  214 + *
  215 + * Neither i2c_smbus_read_byte() nor
  216 + * i2c_smbus_read_block_data() worked here,
  217 + * so use i2c_smbus_read_word_data() instead.
  218 + * We could also try to use i2c_master_recv(),
  219 + * but that is not always supported.
  220 + */
  221 + rv = i2c_smbus_read_word_data(client, 0);
  222 + if (rv < 0) {
  223 + dev_dbg(&client->dev, "Failed to read ADC value: error %d", rv);
  224 + return -1;
  225 + }
  226 + /*
  227 + * Validate/verify readback adc channel (in bit 11..14).
  228 + * High byte is in lower 8 bit of rv, so only shift by 3.
  229 + */
  230 + radc = (rv >> 3) & 0x0f;
  231 + if (radc != adc) {
  232 + dev_dbg(&client->dev, "Unexpected RADC: Expected %d got %d",
  233 + adc, radc);
  234 + return -EIO;
  235 + }
  236 + /*
  237 + * Chip replies with H/L, while SMBus expects L/H.
  238 + * Thus, byte order is reversed, and we have to swap
  239 + * the result.
  240 + */
  241 + rv = swab16(rv) & SMM665_ADC_MASK;
  242 +
  243 + return rv;
  244 +}
  245 +
  246 +static struct smm665_data *smm665_update_device(struct device *dev)
  247 +{
  248 + struct i2c_client *client = to_i2c_client(dev);
  249 + struct smm665_data *data = i2c_get_clientdata(client);
  250 + struct smm665_data *ret = data;
  251 +
  252 + mutex_lock(&data->update_lock);
  253 +
  254 + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
  255 + int i, val;
  256 +
  257 + /*
  258 + * read status registers
  259 + */
  260 + val = smm665_read16(client, SMM665_MISC8_STATUS1);
  261 + if (unlikely(val < 0)) {
  262 + ret = ERR_PTR(val);
  263 + goto abort;
  264 + }
  265 + data->faults = val;
  266 +
  267 + /* Read adc registers */
  268 + for (i = 0; i < SMM665_NUM_ADC; i++) {
  269 + val = smm665_read_adc(data, i);
  270 + if (unlikely(val < 0)) {
  271 + ret = ERR_PTR(val);
  272 + goto abort;
  273 + }
  274 + data->adc[i] = val;
  275 + }
  276 + data->last_updated = jiffies;
  277 + data->valid = 1;
  278 + }
  279 +abort:
  280 + mutex_unlock(&data->update_lock);
  281 + return ret;
  282 +}
  283 +
  284 +/* Return converted value from given adc */
  285 +static int smm665_convert(u16 adcval, int index)
  286 +{
  287 + int val = 0;
  288 +
  289 + switch (index) {
  290 + case SMM665_MISC16_ADC_DATA_12V:
  291 + val = SMM665_12VIN_ADC_TO_VOLTS(adcval & SMM665_ADC_MASK);
  292 + break;
  293 +
  294 + case SMM665_MISC16_ADC_DATA_VDD:
  295 + case SMM665_MISC16_ADC_DATA_A:
  296 + case SMM665_MISC16_ADC_DATA_B:
  297 + case SMM665_MISC16_ADC_DATA_C:
  298 + case SMM665_MISC16_ADC_DATA_D:
  299 + case SMM665_MISC16_ADC_DATA_E:
  300 + case SMM665_MISC16_ADC_DATA_F:
  301 + val = SMM665_VMON_ADC_TO_VOLTS(adcval & SMM665_ADC_MASK);
  302 + break;
  303 +
  304 + case SMM665_MISC16_ADC_DATA_AIN1:
  305 + case SMM665_MISC16_ADC_DATA_AIN2:
  306 + val = SMM665_AIN_ADC_TO_VOLTS(adcval & SMM665_ADC_MASK);
  307 + break;
  308 +
  309 + case SMM665_MISC16_ADC_DATA_INT_TEMP:
  310 + val = SMM665_TEMP_ADC_TO_CELSIUS(adcval & SMM665_ADC_MASK);
  311 + break;
  312 +
  313 + default:
  314 + /* If we get here, the developer messed up */
  315 + WARN_ON_ONCE(1);
  316 + break;
  317 + }
  318 +
  319 + return val;
  320 +}
  321 +
  322 +static int smm665_get_min(struct device *dev, int index)
  323 +{
  324 + struct i2c_client *client = to_i2c_client(dev);
  325 + struct smm665_data *data = i2c_get_clientdata(client);
  326 +
  327 + return data->alarm_min_limit[index];
  328 +}
  329 +
  330 +static int smm665_get_max(struct device *dev, int index)
  331 +{
  332 + struct i2c_client *client = to_i2c_client(dev);
  333 + struct smm665_data *data = i2c_get_clientdata(client);
  334 +
  335 + return data->alarm_max_limit[index];
  336 +}
  337 +
  338 +static int smm665_get_lcrit(struct device *dev, int index)
  339 +{
  340 + struct i2c_client *client = to_i2c_client(dev);
  341 + struct smm665_data *data = i2c_get_clientdata(client);
  342 +
  343 + return data->critical_min_limit[index];
  344 +}
  345 +
  346 +static int smm665_get_crit(struct device *dev, int index)
  347 +{
  348 + struct i2c_client *client = to_i2c_client(dev);
  349 + struct smm665_data *data = i2c_get_clientdata(client);
  350 +
  351 + return data->critical_max_limit[index];
  352 +}
  353 +
  354 +static ssize_t smm665_show_crit_alarm(struct device *dev,
  355 + struct device_attribute *da, char *buf)
  356 +{
  357 + struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
  358 + struct smm665_data *data = smm665_update_device(dev);
  359 + int val = 0;
  360 +
  361 + if (IS_ERR(data))
  362 + return PTR_ERR(data);
  363 +
  364 + if (data->faults & (1 << attr->index))
  365 + val = 1;
  366 +
  367 + return snprintf(buf, PAGE_SIZE, "%d\n", val);
  368 +}
  369 +
  370 +static ssize_t smm665_show_input(struct device *dev,
  371 + struct device_attribute *da, char *buf)
  372 +{
  373 + struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
  374 + struct smm665_data *data = smm665_update_device(dev);
  375 + int adc = attr->index;
  376 + int val;
  377 +
  378 + if (IS_ERR(data))
  379 + return PTR_ERR(data);
  380 +
  381 + val = smm665_convert(data->adc[adc], adc);
  382 + return snprintf(buf, PAGE_SIZE, "%d\n", val);
  383 +}
  384 +
  385 +#define SMM665_SHOW(what) \
  386 + static ssize_t smm665_show_##what(struct device *dev, \
  387 + struct device_attribute *da, char *buf) \
  388 +{ \
  389 + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
  390 + const int val = smm665_get_##what(dev, attr->index); \
  391 + return snprintf(buf, PAGE_SIZE, "%d\n", val); \
  392 +}
  393 +
  394 +SMM665_SHOW(min);
  395 +SMM665_SHOW(max);
  396 +SMM665_SHOW(lcrit);
  397 +SMM665_SHOW(crit);
  398 +
  399 +/* These macros are used below in constructing device attribute objects
  400 + * for use with sysfs_create_group() to make a sysfs device file
  401 + * for each register.
  402 + */
  403 +
  404 +#define SMM665_ATTR(name, type, cmd_idx) \
  405 + static SENSOR_DEVICE_ATTR(name##_##type, S_IRUGO, \
  406 + smm665_show_##type, NULL, cmd_idx)
  407 +
  408 +/* Construct a sensor_device_attribute structure for each register */
  409 +
  410 +/* Input voltages */
  411 +SMM665_ATTR(in1, input, SMM665_MISC16_ADC_DATA_12V);
  412 +SMM665_ATTR(in2, input, SMM665_MISC16_ADC_DATA_VDD);
  413 +SMM665_ATTR(in3, input, SMM665_MISC16_ADC_DATA_A);
  414 +SMM665_ATTR(in4, input, SMM665_MISC16_ADC_DATA_B);
  415 +SMM665_ATTR(in5, input, SMM665_MISC16_ADC_DATA_C);
  416 +SMM665_ATTR(in6, input, SMM665_MISC16_ADC_DATA_D);
  417 +SMM665_ATTR(in7, input, SMM665_MISC16_ADC_DATA_E);
  418 +SMM665_ATTR(in8, input, SMM665_MISC16_ADC_DATA_F);
  419 +SMM665_ATTR(in9, input, SMM665_MISC16_ADC_DATA_AIN1);
  420 +SMM665_ATTR(in10, input, SMM665_MISC16_ADC_DATA_AIN2);
  421 +
  422 +/* Input voltages min */
  423 +SMM665_ATTR(in1, min, SMM665_MISC16_ADC_DATA_12V);
  424 +SMM665_ATTR(in2, min, SMM665_MISC16_ADC_DATA_VDD);
  425 +SMM665_ATTR(in3, min, SMM665_MISC16_ADC_DATA_A);
  426 +SMM665_ATTR(in4, min, SMM665_MISC16_ADC_DATA_B);
  427 +SMM665_ATTR(in5, min, SMM665_MISC16_ADC_DATA_C);
  428 +SMM665_ATTR(in6, min, SMM665_MISC16_ADC_DATA_D);
  429 +SMM665_ATTR(in7, min, SMM665_MISC16_ADC_DATA_E);
  430 +SMM665_ATTR(in8, min, SMM665_MISC16_ADC_DATA_F);
  431 +SMM665_ATTR(in9, min, SMM665_MISC16_ADC_DATA_AIN1);
  432 +SMM665_ATTR(in10, min, SMM665_MISC16_ADC_DATA_AIN2);
  433 +
  434 +/* Input voltages max */
  435 +SMM665_ATTR(in1, max, SMM665_MISC16_ADC_DATA_12V);
  436 +SMM665_ATTR(in2, max, SMM665_MISC16_ADC_DATA_VDD);
  437 +SMM665_ATTR(in3, max, SMM665_MISC16_ADC_DATA_A);
  438 +SMM665_ATTR(in4, max, SMM665_MISC16_ADC_DATA_B);
  439 +SMM665_ATTR(in5, max, SMM665_MISC16_ADC_DATA_C);
  440 +SMM665_ATTR(in6, max, SMM665_MISC16_ADC_DATA_D);
  441 +SMM665_ATTR(in7, max, SMM665_MISC16_ADC_DATA_E);
  442 +SMM665_ATTR(in8, max, SMM665_MISC16_ADC_DATA_F);
  443 +SMM665_ATTR(in9, max, SMM665_MISC16_ADC_DATA_AIN1);
  444 +SMM665_ATTR(in10, max, SMM665_MISC16_ADC_DATA_AIN2);
  445 +
  446 +/* Input voltages lcrit */
  447 +SMM665_ATTR(in1, lcrit, SMM665_MISC16_ADC_DATA_12V);
  448 +SMM665_ATTR(in2, lcrit, SMM665_MISC16_ADC_DATA_VDD);
  449 +SMM665_ATTR(in3, lcrit, SMM665_MISC16_ADC_DATA_A);
  450 +SMM665_ATTR(in4, lcrit, SMM665_MISC16_ADC_DATA_B);
  451 +SMM665_ATTR(in5, lcrit, SMM665_MISC16_ADC_DATA_C);
  452 +SMM665_ATTR(in6, lcrit, SMM665_MISC16_ADC_DATA_D);
  453 +SMM665_ATTR(in7, lcrit, SMM665_MISC16_ADC_DATA_E);
  454 +SMM665_ATTR(in8, lcrit, SMM665_MISC16_ADC_DATA_F);
  455 +SMM665_ATTR(in9, lcrit, SMM665_MISC16_ADC_DATA_AIN1);
  456 +SMM665_ATTR(in10, lcrit, SMM665_MISC16_ADC_DATA_AIN2);
  457 +
  458 +/* Input voltages crit */
  459 +SMM665_ATTR(in1, crit, SMM665_MISC16_ADC_DATA_12V);
  460 +SMM665_ATTR(in2, crit, SMM665_MISC16_ADC_DATA_VDD);
  461 +SMM665_ATTR(in3, crit, SMM665_MISC16_ADC_DATA_A);
  462 +SMM665_ATTR(in4, crit, SMM665_MISC16_ADC_DATA_B);
  463 +SMM665_ATTR(in5, crit, SMM665_MISC16_ADC_DATA_C);
  464 +SMM665_ATTR(in6, crit, SMM665_MISC16_ADC_DATA_D);
  465 +SMM665_ATTR(in7, crit, SMM665_MISC16_ADC_DATA_E);
  466 +SMM665_ATTR(in8, crit, SMM665_MISC16_ADC_DATA_F);
  467 +SMM665_ATTR(in9, crit, SMM665_MISC16_ADC_DATA_AIN1);
  468 +SMM665_ATTR(in10, crit, SMM665_MISC16_ADC_DATA_AIN2);
  469 +
  470 +/* critical alarms */
  471 +SMM665_ATTR(in1, crit_alarm, SMM665_FAULT_12V);
  472 +SMM665_ATTR(in2, crit_alarm, SMM665_FAULT_VDD);
  473 +SMM665_ATTR(in3, crit_alarm, SMM665_FAULT_A);
  474 +SMM665_ATTR(in4, crit_alarm, SMM665_FAULT_B);
  475 +SMM665_ATTR(in5, crit_alarm, SMM665_FAULT_C);
  476 +SMM665_ATTR(in6, crit_alarm, SMM665_FAULT_D);
  477 +SMM665_ATTR(in7, crit_alarm, SMM665_FAULT_E);
  478 +SMM665_ATTR(in8, crit_alarm, SMM665_FAULT_F);
  479 +SMM665_ATTR(in9, crit_alarm, SMM665_FAULT_AIN1);
  480 +SMM665_ATTR(in10, crit_alarm, SMM665_FAULT_AIN2);
  481 +
  482 +/* Temperature */
  483 +SMM665_ATTR(temp1, input, SMM665_MISC16_ADC_DATA_INT_TEMP);
  484 +SMM665_ATTR(temp1, min, SMM665_MISC16_ADC_DATA_INT_TEMP);
  485 +SMM665_ATTR(temp1, max, SMM665_MISC16_ADC_DATA_INT_TEMP);
  486 +SMM665_ATTR(temp1, lcrit, SMM665_MISC16_ADC_DATA_INT_TEMP);
  487 +SMM665_ATTR(temp1, crit, SMM665_MISC16_ADC_DATA_INT_TEMP);
  488 +SMM665_ATTR(temp1, crit_alarm, SMM665_FAULT_TEMP);
  489 +
  490 +/*
  491 + * Finally, construct an array of pointers to members of the above objects,
  492 + * as required for sysfs_create_group()
  493 + */
  494 +static struct attribute *smm665_attributes[] = {
  495 + &sensor_dev_attr_in1_input.dev_attr.attr,
  496 + &sensor_dev_attr_in1_min.dev_attr.attr,
  497 + &sensor_dev_attr_in1_max.dev_attr.attr,
  498 + &sensor_dev_attr_in1_lcrit.dev_attr.attr,
  499 + &sensor_dev_attr_in1_crit.dev_attr.attr,
  500 + &sensor_dev_attr_in1_crit_alarm.dev_attr.attr,
  501 +
  502 + &sensor_dev_attr_in2_input.dev_attr.attr,
  503 + &sensor_dev_attr_in2_min.dev_attr.attr,
  504 + &sensor_dev_attr_in2_max.dev_attr.attr,
  505 + &sensor_dev_attr_in2_lcrit.dev_attr.attr,
  506 + &sensor_dev_attr_in2_crit.dev_attr.attr,
  507 + &sensor_dev_attr_in2_crit_alarm.dev_attr.attr,
  508 +
  509 + &sensor_dev_attr_in3_input.dev_attr.attr,
  510 + &sensor_dev_attr_in3_min.dev_attr.attr,
  511 + &sensor_dev_attr_in3_max.dev_attr.attr,
  512 + &sensor_dev_attr_in3_lcrit.dev_attr.attr,
  513 + &sensor_dev_attr_in3_crit.dev_attr.attr,
  514 + &sensor_dev_attr_in3_crit_alarm.dev_attr.attr,
  515 +
  516 + &sensor_dev_attr_in4_input.dev_attr.attr,
  517 + &sensor_dev_attr_in4_min.dev_attr.attr,
  518 + &sensor_dev_attr_in4_max.dev_attr.attr,
  519 + &sensor_dev_attr_in4_lcrit.dev_attr.attr,
  520 + &sensor_dev_attr_in4_crit.dev_attr.attr,
  521 + &sensor_dev_attr_in4_crit_alarm.dev_attr.attr,
  522 +
  523 + &sensor_dev_attr_in5_input.dev_attr.attr,
  524 + &sensor_dev_attr_in5_min.dev_attr.attr,
  525 + &sensor_dev_attr_in5_max.dev_attr.attr,
  526 + &sensor_dev_attr_in5_lcrit.dev_attr.attr,
  527 + &sensor_dev_attr_in5_crit.dev_attr.attr,
  528 + &sensor_dev_attr_in5_crit_alarm.dev_attr.attr,
  529 +
  530 + &sensor_dev_attr_in6_input.dev_attr.attr,
  531 + &sensor_dev_attr_in6_min.dev_attr.attr,
  532 + &sensor_dev_attr_in6_max.dev_attr.attr,
  533 + &sensor_dev_attr_in6_lcrit.dev_attr.attr,
  534 + &sensor_dev_attr_in6_crit.dev_attr.attr,
  535 + &sensor_dev_attr_in6_crit_alarm.dev_attr.attr,
  536 +
  537 + &sensor_dev_attr_in7_input.dev_attr.attr,
  538 + &sensor_dev_attr_in7_min.dev_attr.attr,
  539 + &sensor_dev_attr_in7_max.dev_attr.attr,
  540 + &sensor_dev_attr_in7_lcrit.dev_attr.attr,
  541 + &sensor_dev_attr_in7_crit.dev_attr.attr,
  542 + &sensor_dev_attr_in7_crit_alarm.dev_attr.attr,
  543 +
  544 + &sensor_dev_attr_in8_input.dev_attr.attr,
  545 + &sensor_dev_attr_in8_min.dev_attr.attr,
  546 + &sensor_dev_attr_in8_max.dev_attr.attr,
  547 + &sensor_dev_attr_in8_lcrit.dev_attr.attr,
  548 + &sensor_dev_attr_in8_crit.dev_attr.attr,
  549 + &sensor_dev_attr_in8_crit_alarm.dev_attr.attr,
  550 +
  551 + &sensor_dev_attr_in9_input.dev_attr.attr,
  552 + &sensor_dev_attr_in9_min.dev_attr.attr,
  553 + &sensor_dev_attr_in9_max.dev_attr.attr,
  554 + &sensor_dev_attr_in9_lcrit.dev_attr.attr,
  555 + &sensor_dev_attr_in9_crit.dev_attr.attr,
  556 + &sensor_dev_attr_in9_crit_alarm.dev_attr.attr,
  557 +
  558 + &sensor_dev_attr_in10_input.dev_attr.attr,
  559 + &sensor_dev_attr_in10_min.dev_attr.attr,
  560 + &sensor_dev_attr_in10_max.dev_attr.attr,
  561 + &sensor_dev_attr_in10_lcrit.dev_attr.attr,
  562 + &sensor_dev_attr_in10_crit.dev_attr.attr,
  563 + &sensor_dev_attr_in10_crit_alarm.dev_attr.attr,
  564 +
  565 + &sensor_dev_attr_temp1_input.dev_attr.attr,
  566 + &sensor_dev_attr_temp1_min.dev_attr.attr,
  567 + &sensor_dev_attr_temp1_max.dev_attr.attr,
  568 + &sensor_dev_attr_temp1_lcrit.dev_attr.attr,
  569 + &sensor_dev_attr_temp1_crit.dev_attr.attr,
  570 + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
  571 +
  572 + NULL,
  573 +};
  574 +
  575 +static const struct attribute_group smm665_group = {
  576 + .attrs = smm665_attributes,
  577 +};
  578 +
  579 +static int smm665_probe(struct i2c_client *client,
  580 + const struct i2c_device_id *id)
  581 +{
  582 + struct i2c_adapter *adapter = client->adapter;
  583 + struct smm665_data *data;
  584 + int i, ret;
  585 +
  586 + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
  587 + | I2C_FUNC_SMBUS_WORD_DATA))
  588 + return -ENODEV;
  589 +
  590 + if (i2c_smbus_read_byte_data(client, SMM665_ADOC_ENABLE) < 0)
  591 + return -ENODEV;
  592 +
  593 + ret = -ENOMEM;
  594 + data = kzalloc(sizeof(*data), GFP_KERNEL);
  595 + if (!data)
  596 + goto out_return;
  597 +
  598 + i2c_set_clientdata(client, data);
  599 + mutex_init(&data->update_lock);
  600 +
  601 + data->type = id->driver_data;
  602 + data->cmdreg = i2c_new_dummy(adapter, (client->addr & ~SMM665_REGMASK)
  603 + | SMM665_CMDREG_BASE);
  604 + if (!data->cmdreg)
  605 + goto out_kfree;
  606 +
  607 + switch (data->type) {
  608 + case smm465:
  609 + case smm665:
  610 + data->conversion_time = SMM665_ADC_WAIT_SMM665;
  611 + break;
  612 + case smm665c:
  613 + case smm764:
  614 + case smm766:
  615 + data->conversion_time = SMM665_ADC_WAIT_SMM766;
  616 + break;
  617 + }
  618 +
  619 + ret = -ENODEV;
  620 + if (i2c_smbus_read_byte_data(data->cmdreg, SMM665_MISC8_CMD_STS) < 0)
  621 + goto out_unregister;
  622 +
  623 + /*
  624 + * Read limits.
  625 + *
  626 + * Limit registers start with register SMM665_LIMIT_BASE.
  627 + * Each channel uses 8 registers, providing four limit values
  628 + * per channel. Each limit value requires two registers, with the
  629 + * high byte in the first register and the low byte in the second
  630 + * register. The first two limits are under limit values, followed
  631 + * by two over limit values.
  632 + *
  633 + * Limit register order matches the ADC register order, so we use
  634 + * ADC register defines throughout the code to index limit registers.
  635 + *
  636 + * We save the first retrieved value both as "critical" and "alarm"
  637 + * value. The second value overwrites either the critical or the
  638 + * alarm value, depending on its configuration. This ensures that both
  639 + * critical and alarm values are initialized, even if both registers are
  640 + * configured as critical or non-critical.
  641 + */
  642 + for (i = 0; i < SMM665_NUM_ADC; i++) {
  643 + int val;
  644 +
  645 + val = smm665_read16(client, SMM665_LIMIT_BASE + i * 8);
  646 + if (unlikely(val < 0))
  647 + goto out_unregister;
  648 + data->critical_min_limit[i] = data->alarm_min_limit[i]
  649 + = smm665_convert(val, i);
  650 + val = smm665_read16(client, SMM665_LIMIT_BASE + i * 8 + 2);
  651 + if (unlikely(val < 0))
  652 + goto out_unregister;
  653 + if (smm665_is_critical(val))
  654 + data->critical_min_limit[i] = smm665_convert(val, i);
  655 + else
  656 + data->alarm_min_limit[i] = smm665_convert(val, i);
  657 + val = smm665_read16(client, SMM665_LIMIT_BASE + i * 8 + 4);
  658 + if (unlikely(val < 0))
  659 + goto out_unregister;
  660 + data->critical_max_limit[i] = data->alarm_max_limit[i]
  661 + = smm665_convert(val, i);
  662 + val = smm665_read16(client, SMM665_LIMIT_BASE + i * 8 + 6);
  663 + if (unlikely(val < 0))
  664 + goto out_unregister;
  665 + if (smm665_is_critical(val))
  666 + data->critical_max_limit[i] = smm665_convert(val, i);
  667 + else
  668 + data->alarm_max_limit[i] = smm665_convert(val, i);
  669 + }
  670 +
  671 + /* Register sysfs hooks */
  672 + ret = sysfs_create_group(&client->dev.kobj, &smm665_group);
  673 + if (ret)
  674 + goto out_unregister;
  675 +
  676 + data->hwmon_dev = hwmon_device_register(&client->dev);
  677 + if (IS_ERR(data->hwmon_dev)) {
  678 + ret = PTR_ERR(data->hwmon_dev);
  679 + goto out_remove_group;
  680 + }
  681 +
  682 + return 0;
  683 +
  684 +out_remove_group:
  685 + sysfs_remove_group(&client->dev.kobj, &smm665_group);
  686 +out_unregister:
  687 + i2c_unregister_device(data->cmdreg);
  688 +out_kfree:
  689 + kfree(data);
  690 +out_return:
  691 + return ret;
  692 +}
  693 +
  694 +static int smm665_remove(struct i2c_client *client)
  695 +{
  696 + struct smm665_data *data = i2c_get_clientdata(client);
  697 +
  698 + i2c_unregister_device(data->cmdreg);
  699 + hwmon_device_unregister(data->hwmon_dev);
  700 + sysfs_remove_group(&client->dev.kobj, &smm665_group);
  701 +
  702 + kfree(data);
  703 +
  704 + return 0;
  705 +}
  706 +
  707 +static const struct i2c_device_id smm665_id[] = {
  708 + {"smm465", smm465},
  709 + {"smm665", smm665},
  710 + {"smm665c", smm665c},
  711 + {"smm764", smm764},
  712 + {"smm766", smm766},
  713 + {}
  714 +};
  715 +
  716 +MODULE_DEVICE_TABLE(i2c, smm665_id);
  717 +
  718 +/* This is the driver that will be inserted */
  719 +static struct i2c_driver smm665_driver = {
  720 + .driver = {
  721 + .name = "smm665",
  722 + },
  723 + .probe = smm665_probe,
  724 + .remove = smm665_remove,
  725 + .id_table = smm665_id,
  726 +};
  727 +
  728 +static int __init smm665_init(void)
  729 +{
  730 + return i2c_add_driver(&smm665_driver);
  731 +}
  732 +
  733 +static void __exit smm665_exit(void)
  734 +{
  735 + i2c_del_driver(&smm665_driver);
  736 +}
  737 +
  738 +MODULE_AUTHOR("Guenter Roeck");
  739 +MODULE_DESCRIPTION("SMM665 driver");
  740 +MODULE_LICENSE("GPL");
  741 +
  742 +module_init(smm665_init);
  743 +module_exit(smm665_exit);