···11+Kernel driver ltc426022+=====================33+44+Supported chips:55+ * Linear Technology LTC426066+ Prefix: 'ltc4260'77+ Addresses scanned: -88+ Datasheet:99+ http://cds.linear.com/docs/en/datasheet/4260fc.pdf1010+1111+Author: Guenter Roeck <linux@roeck-us.net>1212+1313+1414+Description1515+-----------1616+1717+The LTC4260 Hot Swap controller allows a board to be safely inserted1818+and removed from a live backplane.1919+2020+2121+Usage Notes2222+-----------2323+2424+This driver does not probe for LTC4260 devices, since there is no register2525+which can be safely used to identify the chip. You will have to instantiate2626+the devices explicitly.2727+2828+Example: the following will load the driver for an LTC4260 at address 0x102929+on I2C bus #1:3030+$ modprobe ltc42603131+$ echo ltc4260 0x10 > /sys/bus/i2c/devices/i2c-1/new_device3232+3333+3434+Sysfs entries3535+-------------3636+3737+Voltage readings provided by this driver are reported as obtained from the ADC3838+registers. If a set of voltage divider resistors is installed, calculate the3939+real voltage by multiplying the reported value with (R1+R2)/R2, where R1 is the4040+value of the divider resistor against the measured voltage and R2 is the value4141+of the divider resistor against Ground.4242+4343+Current reading provided by this driver is reported as obtained from the ADC4444+Current Sense register. The reported value assumes that a 1 mOhm sense resistor4545+is installed. If a different sense resistor is installed, calculate the real4646+current by dividing the reported value by the sense resistor value in mOhm.4747+4848+in1_input SOURCE voltage (mV)4949+in1_min_alarm Undervoltage alarm5050+in1_max_alarm Overvoltage alarm5151+5252+in2_input ADIN voltage (mV)5353+in2_alarm Power bad alarm5454+5555+curr1_input SENSE current (mA)5656+curr1_alarm SENSE overcurrent alarm
+12
drivers/hwmon/Kconfig
···821821 This driver can also be built as a module. If so, the module will822822 be called ltc4245.823823824824+config SENSORS_LTC4260825825+ tristate "Linear Technology LTC4260"826826+ depends on I2C827827+ select REGMAP_I2C828828+ default n829829+ help830830+ If you say yes here you get support for Linear Technology LTC4261831831+ Positive Voltage Hot Swap Controller I2C interface.832832+833833+ This driver can also be built as a module. If so, the module will834834+ be called ltc4260.835835+824836config SENSORS_LTC4261825837 tristate "Linear Technology LTC4261"826838 depends on I2C
···11+/*22+ * Driver for Linear Technology LTC4260 I2C Positive Voltage Hot Swap Controller33+ *44+ * Copyright (c) 2014 Guenter Roeck55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License as published by88+ * the Free Software Foundation; either version 2 of the License, or99+ * (at your option) any later version.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ */1616+1717+#include <linux/kernel.h>1818+#include <linux/module.h>1919+#include <linux/err.h>2020+#include <linux/slab.h>2121+#include <linux/i2c.h>2222+#include <linux/hwmon.h>2323+#include <linux/hwmon-sysfs.h>2424+#include <linux/jiffies.h>2525+#include <linux/regmap.h>2626+2727+/* chip registers */2828+#define LTC4260_CONTROL 0x002929+#define LTC4260_ALERT 0x013030+#define LTC4260_STATUS 0x023131+#define LTC4260_FAULT 0x033232+#define LTC4260_SENSE 0x043333+#define LTC4260_SOURCE 0x053434+#define LTC4260_ADIN 0x063535+3636+/*3737+ * Fault register bits3838+ */3939+#define FAULT_OV (1 << 0)4040+#define FAULT_UV (1 << 1)4141+#define FAULT_OC (1 << 2)4242+#define FAULT_POWER_BAD (1 << 3)4343+#define FAULT_FET_SHORT (1 << 5)4444+4545+/* Return the voltage from the given register in mV or mA */4646+static int ltc4260_get_value(struct device *dev, u8 reg)4747+{4848+ struct regmap *regmap = dev_get_drvdata(dev);4949+ unsigned int val;5050+ int ret;5151+5252+ ret = regmap_read(regmap, reg, &val);5353+ if (ret < 0)5454+ return ret;5555+5656+ switch (reg) {5757+ case LTC4260_ADIN:5858+ /* 10 mV resolution. Convert to mV. */5959+ val = val * 10;6060+ break;6161+ case LTC4260_SOURCE:6262+ /* 400 mV resolution. Convert to mV. */6363+ val = val * 400;6464+ break;6565+ case LTC4260_SENSE:6666+ /*6767+ * 300 uV resolution. Convert to current as measured with6868+ * an 1 mOhm sense resistor, in mA. If a different sense6969+ * resistor is installed, calculate the actual current by7070+ * dividing the reported current by the sense resistor value7171+ * in mOhm.7272+ */7373+ val = val * 300;7474+ break;7575+ default:7676+ return -EINVAL;7777+ }7878+7979+ return val;8080+}8181+8282+static ssize_t ltc4260_show_value(struct device *dev,8383+ struct device_attribute *da, char *buf)8484+{8585+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);8686+ int value;8787+8888+ value = ltc4260_get_value(dev, attr->index);8989+ if (value < 0)9090+ return value;9191+ return snprintf(buf, PAGE_SIZE, "%d\n", value);9292+}9393+9494+static ssize_t ltc4260_show_bool(struct device *dev,9595+ struct device_attribute *da, char *buf)9696+{9797+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);9898+ struct regmap *regmap = dev_get_drvdata(dev);9999+ unsigned int fault;100100+ int ret;101101+102102+ ret = regmap_read(regmap, LTC4260_FAULT, &fault);103103+ if (ret < 0)104104+ return ret;105105+106106+ fault &= attr->index;107107+ if (fault) /* Clear reported faults in chip register */108108+ regmap_update_bits(regmap, LTC4260_FAULT, attr->index, 0);109109+110110+ return snprintf(buf, PAGE_SIZE, "%d\n", !!fault);111111+}112112+113113+/* Voltages */114114+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4260_show_value, NULL,115115+ LTC4260_SOURCE);116116+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4260_show_value, NULL,117117+ LTC4260_ADIN);118118+119119+/*120120+ * Voltage alarms121121+ * UV/OV faults are associated with the input voltage, and the POWER BAD and122122+ * FET SHORT faults are associated with the output voltage.123123+ */124124+static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ltc4260_show_bool, NULL,125125+ FAULT_UV);126126+static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ltc4260_show_bool, NULL,127127+ FAULT_OV);128128+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, ltc4260_show_bool, NULL,129129+ FAULT_POWER_BAD | FAULT_FET_SHORT);130130+131131+/* Current (via sense resistor) */132132+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4260_show_value, NULL,133133+ LTC4260_SENSE);134134+135135+/* Overcurrent alarm */136136+static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc4260_show_bool, NULL,137137+ FAULT_OC);138138+139139+static struct attribute *ltc4260_attrs[] = {140140+ &sensor_dev_attr_in1_input.dev_attr.attr,141141+ &sensor_dev_attr_in1_min_alarm.dev_attr.attr,142142+ &sensor_dev_attr_in1_max_alarm.dev_attr.attr,143143+ &sensor_dev_attr_in2_input.dev_attr.attr,144144+ &sensor_dev_attr_in2_alarm.dev_attr.attr,145145+146146+ &sensor_dev_attr_curr1_input.dev_attr.attr,147147+ &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,148148+149149+ NULL,150150+};151151+ATTRIBUTE_GROUPS(ltc4260);152152+153153+static struct regmap_config ltc4260_regmap_config = {154154+ .reg_bits = 8,155155+ .val_bits = 8,156156+ .max_register = LTC4260_ADIN,157157+};158158+159159+static int ltc4260_probe(struct i2c_client *client,160160+ const struct i2c_device_id *id)161161+{162162+ struct device *dev = &client->dev;163163+ struct device *hwmon_dev;164164+ struct regmap *regmap;165165+166166+ regmap = devm_regmap_init_i2c(client, <c4260_regmap_config);167167+ if (IS_ERR(regmap)) {168168+ dev_err(dev, "failed to allocate register map\n");169169+ return PTR_ERR(regmap);170170+ }171171+172172+ /* Clear faults */173173+ regmap_write(regmap, LTC4260_FAULT, 0x00);174174+175175+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,176176+ regmap,177177+ ltc4260_groups);178178+ return PTR_ERR_OR_ZERO(hwmon_dev);179179+}180180+181181+static const struct i2c_device_id ltc4260_id[] = {182182+ {"ltc4260", 0},183183+ { }184184+};185185+186186+MODULE_DEVICE_TABLE(i2c, ltc4260_id);187187+188188+static struct i2c_driver ltc4260_driver = {189189+ .driver = {190190+ .name = "ltc4260",191191+ },192192+ .probe = ltc4260_probe,193193+ .id_table = ltc4260_id,194194+};195195+196196+module_i2c_driver(ltc4260_driver);197197+198198+MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");199199+MODULE_DESCRIPTION("LTC4260 driver");200200+MODULE_LICENSE("GPL");