diff options
| author | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-07-08 13:43:57 -0400 |
|---|---|---|
| committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-07-28 23:16:17 -0400 |
| commit | 03e9bd8dbcee60c2e22fd54f9f28f0d32da218c3 (patch) | |
| tree | 0e55d78c814798f6467ad0c293fe9d365f78b7be | |
| parent | 98591dbe633eace43a20ffa2907861fbef97237b (diff) | |
hwmon: (pmbus) Add client driver for LM25066, LM5064, and LM5066
PMBus client driver supporting National Semiconductor LM25066, LM5064, and LM5066.
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Reviewed-by: Robert Coulson <robert.coulson@ericsson.com>
| -rw-r--r-- | Documentation/hwmon/lm25066 | 90 | ||||
| -rw-r--r-- | drivers/hwmon/pmbus/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/hwmon/pmbus/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hwmon/pmbus/lm25066.c | 340 | ||||
| -rw-r--r-- | drivers/hwmon/pmbus/pmbus.h | 1 | ||||
| -rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 3 |
6 files changed, 444 insertions, 1 deletions
diff --git a/Documentation/hwmon/lm25066 b/Documentation/hwmon/lm25066 new file mode 100644 index 000000000000..a21db81c4591 --- /dev/null +++ b/Documentation/hwmon/lm25066 | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | Kernel driver max8688 | ||
| 2 | ===================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * National Semiconductor LM25066 | ||
| 6 | Prefix: 'lm25066' | ||
| 7 | Addresses scanned: - | ||
| 8 | Datasheets: | ||
| 9 | http://www.national.com/pf/LM/LM25066.html | ||
| 10 | http://www.national.com/pf/LM/LM25066A.html | ||
| 11 | * National Semiconductor LM5064 | ||
| 12 | Prefix: 'lm5064' | ||
| 13 | Addresses scanned: - | ||
| 14 | Datasheet: | ||
| 15 | http://www.national.com/pf/LM/LM5064.html | ||
| 16 | * National Semiconductor LM5066 | ||
| 17 | Prefix: 'lm5066' | ||
| 18 | Addresses scanned: - | ||
| 19 | Datasheet: | ||
| 20 | http://www.national.com/pf/LM/LM5066.html | ||
| 21 | |||
| 22 | Author: Guenter Roeck <guenter.roeck@ericsson.com> | ||
| 23 | |||
| 24 | |||
| 25 | Description | ||
| 26 | ----------- | ||
| 27 | |||
| 28 | This driver supports hardware montoring for National Semiconductor LM25066, | ||
| 29 | LM5064, and LM5064 Power Management, Monitoring, Control, and Protection ICs. | ||
| 30 | |||
| 31 | The driver is a client driver to the core PMBus driver. Please see | ||
| 32 | Documentation/hwmon/pmbus for details on PMBus client drivers. | ||
| 33 | |||
| 34 | |||
| 35 | Usage Notes | ||
| 36 | ----------- | ||
| 37 | |||
| 38 | This driver does not auto-detect devices. You will have to instantiate the | ||
| 39 | devices explicitly. Please see Documentation/i2c/instantiating-devices for | ||
| 40 | details. | ||
| 41 | |||
| 42 | |||
| 43 | Platform data support | ||
| 44 | --------------------- | ||
| 45 | |||
| 46 | The driver supports standard PMBus driver platform data. | ||
| 47 | |||
| 48 | |||
| 49 | Sysfs entries | ||
| 50 | ------------- | ||
| 51 | |||
| 52 | The following attributes are supported. Limits are read-write; all other | ||
| 53 | attributes are read-only. | ||
| 54 | |||
| 55 | in1_label "vin" | ||
| 56 | in1_input Measured input voltage. | ||
| 57 | in1_average Average measured input voltage. | ||
| 58 | in1_min Minimum input voltage. | ||
| 59 | in1_max Maximum input voltage. | ||
| 60 | in1_min_alarm Input voltage low alarm. | ||
| 61 | in1_max_alarm Input voltage high alarm. | ||
| 62 | |||
| 63 | in2_label "vout1" | ||
| 64 | in2_input Measured output voltage. | ||
| 65 | in2_average Average measured output voltage. | ||
| 66 | in2_min Minimum output voltage. | ||
| 67 | in2_min_alarm Output voltage low alarm. | ||
| 68 | |||
| 69 | in3_label "vout2" | ||
| 70 | in3_input Measured voltage on vaux pin | ||
| 71 | |||
| 72 | curr1_label "iin" | ||
| 73 | curr1_input Measured input current. | ||
| 74 | curr1_average Average measured input current. | ||
| 75 | curr1_max Maximum input current. | ||
| 76 | curr1_max_alarm Input current high alarm. | ||
| 77 | |||
| 78 | power1_label "pin" | ||
| 79 | power1_input Measured input power. | ||
| 80 | power1_average Average measured input power. | ||
| 81 | power1_max Maximum input power limit. | ||
| 82 | power1_alarm Input power alarm | ||
| 83 | power1_input_highest Historical maximum power. | ||
| 84 | power1_reset_history Write any value to reset maximum power history. | ||
| 85 | |||
| 86 | temp1_input Measured temperature. | ||
| 87 | temp1_max Maximum temperature. | ||
| 88 | temp1_crit Critical high temperature. | ||
| 89 | temp1_max_alarm Chip temperature high alarm. | ||
| 90 | temp1_crit_alarm Chip temperature critical high alarm. | ||
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 0a822a45085d..c9237b9dcff2 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
| @@ -35,6 +35,16 @@ config SENSORS_ADM1275 | |||
| 35 | This driver can also be built as a module. If so, the module will | 35 | This driver can also be built as a module. If so, the module will |
| 36 | be called adm1275. | 36 | be called adm1275. |
| 37 | 37 | ||
| 38 | config SENSORS_LM25066 | ||
| 39 | tristate "National Semiconductor LM25066 and compatibles" | ||
| 40 | default n | ||
| 41 | help | ||
| 42 | If you say yes here you get hardware monitoring support for National | ||
| 43 | Semiconductor LM25066, LM5064, and LM5066. | ||
| 44 | |||
| 45 | This driver can also be built as a module. If so, the module will | ||
| 46 | be called lm25066. | ||
| 47 | |||
| 38 | config SENSORS_MAX16064 | 48 | config SENSORS_MAX16064 |
| 39 | tristate "Maxim MAX16064" | 49 | tristate "Maxim MAX16064" |
| 40 | default n | 50 | default n |
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile index 0178f81829d0..623eedb1ed9a 100644 --- a/drivers/hwmon/pmbus/Makefile +++ b/drivers/hwmon/pmbus/Makefile | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | obj-$(CONFIG_PMBUS) += pmbus_core.o | 5 | obj-$(CONFIG_PMBUS) += pmbus_core.o |
| 6 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o | 6 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o |
| 7 | obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o | 7 | obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o |
| 8 | obj-$(CONFIG_SENSORS_LM25066) += lm25066.o | ||
| 8 | obj-$(CONFIG_SENSORS_MAX16064) += max16064.o | 9 | obj-$(CONFIG_SENSORS_MAX16064) += max16064.o |
| 9 | obj-$(CONFIG_SENSORS_MAX34440) += max34440.o | 10 | obj-$(CONFIG_SENSORS_MAX34440) += max34440.o |
| 10 | obj-$(CONFIG_SENSORS_MAX8688) += max8688.o | 11 | obj-$(CONFIG_SENSORS_MAX8688) += max8688.o |
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c new file mode 100644 index 000000000000..d4bc114572de --- /dev/null +++ b/drivers/hwmon/pmbus/lm25066.c | |||
| @@ -0,0 +1,340 @@ | |||
| 1 | /* | ||
| 2 | * Hardware monitoring driver for LM25066 / LM5064 / LM5066 | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011 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; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/err.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <linux/i2c.h> | ||
| 27 | #include "pmbus.h" | ||
| 28 | |||
| 29 | enum chips { lm25066, lm5064, lm5066 }; | ||
| 30 | |||
| 31 | #define LM25066_READ_VAUX 0xd0 | ||
| 32 | #define LM25066_MFR_READ_IIN 0xd1 | ||
| 33 | #define LM25066_MFR_READ_PIN 0xd2 | ||
| 34 | #define LM25066_MFR_IIN_OC_WARN_LIMIT 0xd3 | ||
| 35 | #define LM25066_MFR_PIN_OP_WARN_LIMIT 0xd4 | ||
| 36 | #define LM25066_READ_PIN_PEAK 0xd5 | ||
| 37 | #define LM25066_CLEAR_PIN_PEAK 0xd6 | ||
| 38 | #define LM25066_DEVICE_SETUP 0xd9 | ||
| 39 | #define LM25066_READ_AVG_VIN 0xdc | ||
| 40 | #define LM25066_READ_AVG_VOUT 0xdd | ||
| 41 | #define LM25066_READ_AVG_IIN 0xde | ||
| 42 | #define LM25066_READ_AVG_PIN 0xdf | ||
| 43 | |||
| 44 | #define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */ | ||
| 45 | |||
| 46 | struct lm25066_data { | ||
| 47 | int id; | ||
| 48 | struct pmbus_driver_info info; | ||
| 49 | }; | ||
| 50 | |||
| 51 | #define to_lm25066_data(x) container_of(x, struct lm25066_data, info) | ||
| 52 | |||
| 53 | static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | ||
| 54 | { | ||
| 55 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
| 56 | const struct lm25066_data *data = to_lm25066_data(info); | ||
| 57 | int ret; | ||
| 58 | |||
| 59 | if (page > 1) | ||
| 60 | return -EINVAL; | ||
| 61 | |||
| 62 | /* Map READ_VAUX into READ_VOUT register on page 1 */ | ||
| 63 | if (page == 1) { | ||
| 64 | switch (reg) { | ||
| 65 | case PMBUS_READ_VOUT: | ||
| 66 | ret = pmbus_read_word_data(client, 0, | ||
| 67 | LM25066_READ_VAUX); | ||
| 68 | if (ret < 0) | ||
| 69 | break; | ||
| 70 | /* Adjust returned value to match VOUT coefficients */ | ||
| 71 | switch (data->id) { | ||
| 72 | case lm25066: | ||
| 73 | /* VOUT: 4.54 mV VAUX: 283.2 uV LSB */ | ||
| 74 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); | ||
| 75 | break; | ||
| 76 | case lm5064: | ||
| 77 | /* VOUT: 4.53 mV VAUX: 700 uV LSB */ | ||
| 78 | ret = DIV_ROUND_CLOSEST(ret * 70, 453); | ||
| 79 | break; | ||
| 80 | case lm5066: | ||
| 81 | /* VOUT: 2.18 mV VAUX: 725 uV LSB */ | ||
| 82 | ret = DIV_ROUND_CLOSEST(ret * 725, 2180); | ||
| 83 | break; | ||
| 84 | } | ||
| 85 | break; | ||
| 86 | default: | ||
| 87 | /* No other valid registers on page 1 */ | ||
| 88 | ret = -EINVAL; | ||
| 89 | break; | ||
| 90 | } | ||
| 91 | goto done; | ||
| 92 | } | ||
| 93 | |||
| 94 | switch (reg) { | ||
| 95 | case PMBUS_READ_IIN: | ||
| 96 | ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN); | ||
| 97 | break; | ||
| 98 | case PMBUS_READ_PIN: | ||
| 99 | ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN); | ||
| 100 | break; | ||
| 101 | case PMBUS_IIN_OC_WARN_LIMIT: | ||
| 102 | ret = pmbus_read_word_data(client, 0, | ||
| 103 | LM25066_MFR_IIN_OC_WARN_LIMIT); | ||
| 104 | break; | ||
| 105 | case PMBUS_PIN_OP_WARN_LIMIT: | ||
| 106 | ret = pmbus_read_word_data(client, 0, | ||
| 107 | LM25066_MFR_PIN_OP_WARN_LIMIT); | ||
| 108 | break; | ||
| 109 | case PMBUS_VIRT_READ_VIN_AVG: | ||
| 110 | ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN); | ||
| 111 | break; | ||
| 112 | case PMBUS_VIRT_READ_VOUT_AVG: | ||
| 113 | ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT); | ||
| 114 | break; | ||
| 115 | case PMBUS_VIRT_READ_IIN_AVG: | ||
| 116 | ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN); | ||
| 117 | break; | ||
| 118 | case PMBUS_VIRT_READ_PIN_AVG: | ||
| 119 | ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN); | ||
| 120 | break; | ||
| 121 | case PMBUS_VIRT_READ_PIN_MAX: | ||
| 122 | ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK); | ||
| 123 | break; | ||
| 124 | case PMBUS_VIRT_RESET_PIN_HISTORY: | ||
| 125 | ret = 0; | ||
| 126 | break; | ||
| 127 | default: | ||
| 128 | ret = -ENODATA; | ||
| 129 | break; | ||
| 130 | } | ||
| 131 | done: | ||
| 132 | return ret; | ||
| 133 | } | ||
| 134 | |||
| 135 | static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | ||
| 136 | u16 word) | ||
| 137 | { | ||
| 138 | int ret; | ||
| 139 | |||
| 140 | if (page > 1) | ||
| 141 | return -EINVAL; | ||
| 142 | |||
| 143 | switch (reg) { | ||
| 144 | case PMBUS_IIN_OC_WARN_LIMIT: | ||
| 145 | ret = pmbus_write_word_data(client, 0, | ||
| 146 | LM25066_MFR_IIN_OC_WARN_LIMIT, | ||
| 147 | word); | ||
| 148 | break; | ||
| 149 | case PMBUS_PIN_OP_WARN_LIMIT: | ||
| 150 | ret = pmbus_write_word_data(client, 0, | ||
| 151 | LM25066_MFR_PIN_OP_WARN_LIMIT, | ||
| 152 | word); | ||
| 153 | break; | ||
| 154 | case PMBUS_VIRT_RESET_PIN_HISTORY: | ||
| 155 | ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK); | ||
| 156 | break; | ||
| 157 | default: | ||
| 158 | ret = -ENODATA; | ||
| 159 | break; | ||
| 160 | } | ||
| 161 | return ret; | ||
| 162 | } | ||
| 163 | |||
| 164 | static int lm25066_probe(struct i2c_client *client, | ||
| 165 | const struct i2c_device_id *id) | ||
| 166 | { | ||
| 167 | int config; | ||
| 168 | int ret; | ||
| 169 | struct lm25066_data *data; | ||
| 170 | struct pmbus_driver_info *info; | ||
| 171 | |||
| 172 | if (!i2c_check_functionality(client->adapter, | ||
| 173 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) | ||
| 174 | return -ENODEV; | ||
| 175 | |||
| 176 | data = kzalloc(sizeof(struct lm25066_data), GFP_KERNEL); | ||
| 177 | if (!data) | ||
| 178 | return -ENOMEM; | ||
| 179 | |||
| 180 | config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP); | ||
| 181 | if (config < 0) { | ||
| 182 | ret = config; | ||
| 183 | goto err_mem; | ||
| 184 | } | ||
| 185 | |||
| 186 | data->id = id->driver_data; | ||
| 187 | info = &data->info; | ||
| 188 | |||
| 189 | info->pages = 2; | ||
| 190 | info->format[PSC_VOLTAGE_IN] = direct; | ||
| 191 | info->format[PSC_VOLTAGE_OUT] = direct; | ||
| 192 | info->format[PSC_CURRENT_IN] = direct; | ||
| 193 | info->format[PSC_TEMPERATURE] = direct; | ||
| 194 | info->format[PSC_POWER] = direct; | ||
| 195 | |||
| 196 | info->m[PSC_TEMPERATURE] = 16; | ||
| 197 | info->b[PSC_TEMPERATURE] = 0; | ||
| 198 | info->R[PSC_TEMPERATURE] = 0; | ||
| 199 | |||
| 200 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | ||
| 201 | | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | ||
| 202 | | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | ||
| 203 | info->func[1] = PMBUS_HAVE_VOUT; | ||
| 204 | |||
| 205 | info->read_word_data = lm25066_read_word_data; | ||
| 206 | info->write_word_data = lm25066_write_word_data; | ||
| 207 | |||
| 208 | switch (id->driver_data) { | ||
| 209 | case lm25066: | ||
| 210 | info->m[PSC_VOLTAGE_IN] = 22070; | ||
| 211 | info->b[PSC_VOLTAGE_IN] = 0; | ||
| 212 | info->R[PSC_VOLTAGE_IN] = -2; | ||
| 213 | info->m[PSC_VOLTAGE_OUT] = 22070; | ||
| 214 | info->b[PSC_VOLTAGE_OUT] = 0; | ||
| 215 | info->R[PSC_VOLTAGE_OUT] = -2; | ||
| 216 | |||
| 217 | if (config & LM25066_DEV_SETUP_CL) { | ||
| 218 | info->m[PSC_CURRENT_IN] = 6852; | ||
| 219 | info->b[PSC_CURRENT_IN] = 0; | ||
| 220 | info->R[PSC_CURRENT_IN] = -2; | ||
| 221 | info->m[PSC_POWER] = 369; | ||
| 222 | info->b[PSC_POWER] = 0; | ||
| 223 | info->R[PSC_POWER] = -2; | ||
| 224 | } else { | ||
| 225 | info->m[PSC_CURRENT_IN] = 13661; | ||
| 226 | info->b[PSC_CURRENT_IN] = 0; | ||
| 227 | info->R[PSC_CURRENT_IN] = -2; | ||
| 228 | info->m[PSC_POWER] = 736; | ||
| 229 | info->b[PSC_POWER] = 0; | ||
| 230 | info->R[PSC_POWER] = -2; | ||
| 231 | } | ||
| 232 | break; | ||
| 233 | case lm5064: | ||
| 234 | info->m[PSC_VOLTAGE_IN] = 22075; | ||
| 235 | info->b[PSC_VOLTAGE_IN] = 0; | ||
| 236 | info->R[PSC_VOLTAGE_IN] = -2; | ||
| 237 | info->m[PSC_VOLTAGE_OUT] = 22075; | ||
| 238 | info->b[PSC_VOLTAGE_OUT] = 0; | ||
| 239 | info->R[PSC_VOLTAGE_OUT] = -2; | ||
| 240 | |||
| 241 | if (config & LM25066_DEV_SETUP_CL) { | ||
| 242 | info->m[PSC_CURRENT_IN] = 6713; | ||
| 243 | info->b[PSC_CURRENT_IN] = 0; | ||
| 244 | info->R[PSC_CURRENT_IN] = -2; | ||
| 245 | info->m[PSC_POWER] = 3619; | ||
| 246 | info->b[PSC_POWER] = 0; | ||
| 247 | info->R[PSC_POWER] = -3; | ||
| 248 | } else { | ||
| 249 | info->m[PSC_CURRENT_IN] = 13426; | ||
| 250 | info->b[PSC_CURRENT_IN] = 0; | ||
| 251 | info->R[PSC_CURRENT_IN] = -2; | ||
| 252 | info->m[PSC_POWER] = 7238; | ||
| 253 | info->b[PSC_POWER] = 0; | ||
| 254 | info->R[PSC_POWER] = -3; | ||
| 255 | } | ||
| 256 | break; | ||
| 257 | case lm5066: | ||
| 258 | info->m[PSC_VOLTAGE_IN] = 4587; | ||
| 259 | info->b[PSC_VOLTAGE_IN] = 0; | ||
| 260 | info->R[PSC_VOLTAGE_IN] = -2; | ||
| 261 | info->m[PSC_VOLTAGE_OUT] = 4587; | ||
| 262 | info->b[PSC_VOLTAGE_OUT] = 0; | ||
| 263 | info->R[PSC_VOLTAGE_OUT] = -2; | ||
| 264 | |||
| 265 | if (config & LM25066_DEV_SETUP_CL) { | ||
| 266 | info->m[PSC_CURRENT_IN] = 10753; | ||
| 267 | info->b[PSC_CURRENT_IN] = 0; | ||
| 268 | info->R[PSC_CURRENT_IN] = -2; | ||
| 269 | info->m[PSC_POWER] = 1204; | ||
| 270 | info->b[PSC_POWER] = 0; | ||
| 271 | info->R[PSC_POWER] = -3; | ||
| 272 | } else { | ||
| 273 | info->m[PSC_CURRENT_IN] = 5405; | ||
| 274 | info->b[PSC_CURRENT_IN] = 0; | ||
| 275 | info->R[PSC_CURRENT_IN] = -2; | ||
| 276 | info->m[PSC_POWER] = 605; | ||
| 277 | info->b[PSC_POWER] = 0; | ||
| 278 | info->R[PSC_POWER] = -3; | ||
| 279 | } | ||
| 280 | break; | ||
| 281 | default: | ||
| 282 | ret = -ENODEV; | ||
| 283 | goto err_mem; | ||
| 284 | } | ||
| 285 | |||
| 286 | ret = pmbus_do_probe(client, id, info); | ||
| 287 | if (ret) | ||
| 288 | goto err_mem; | ||
| 289 | return 0; | ||
| 290 | |||
| 291 | err_mem: | ||
| 292 | kfree(data); | ||
| 293 | return ret; | ||
| 294 | } | ||
| 295 | |||
| 296 | static int lm25066_remove(struct i2c_client *client) | ||
| 297 | { | ||
| 298 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
| 299 | const struct lm25066_data *data = to_lm25066_data(info); | ||
| 300 | int ret; | ||
| 301 | |||
| 302 | ret = pmbus_do_remove(client); | ||
| 303 | kfree(data); | ||
| 304 | return ret; | ||
| 305 | } | ||
| 306 | |||
| 307 | static const struct i2c_device_id lm25066_id[] = { | ||
| 308 | {"lm25066", lm25066}, | ||
| 309 | {"lm5064", lm5064}, | ||
| 310 | {"lm5066", lm5066}, | ||
| 311 | { } | ||
| 312 | }; | ||
| 313 | |||
| 314 | MODULE_DEVICE_TABLE(i2c, lm25066_id); | ||
| 315 | |||
| 316 | /* This is the driver that will be inserted */ | ||
| 317 | static struct i2c_driver lm25066_driver = { | ||
| 318 | .driver = { | ||
| 319 | .name = "lm25066", | ||
| 320 | }, | ||
| 321 | .probe = lm25066_probe, | ||
| 322 | .remove = lm25066_remove, | ||
| 323 | .id_table = lm25066_id, | ||
| 324 | }; | ||
| 325 | |||
| 326 | static int __init lm25066_init(void) | ||
| 327 | { | ||
| 328 | return i2c_add_driver(&lm25066_driver); | ||
| 329 | } | ||
| 330 | |||
| 331 | static void __exit lm25066_exit(void) | ||
| 332 | { | ||
| 333 | i2c_del_driver(&lm25066_driver); | ||
| 334 | } | ||
| 335 | |||
| 336 | MODULE_AUTHOR("Guenter Roeck"); | ||
| 337 | MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066"); | ||
| 338 | MODULE_LICENSE("GPL"); | ||
| 339 | module_init(lm25066_init); | ||
| 340 | module_exit(lm25066_exit); | ||
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index 9973d265b28f..0808d986d75b 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h | |||
| @@ -340,6 +340,7 @@ int pmbus_set_page(struct i2c_client *client, u8 page); | |||
| 340 | int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); | 340 | int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); |
| 341 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); | 341 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); |
| 342 | int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); | 342 | int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); |
| 343 | int pmbus_write_byte(struct i2c_client *client, int page, u8 value); | ||
| 343 | void pmbus_clear_faults(struct i2c_client *client); | 344 | void pmbus_clear_faults(struct i2c_client *client); |
| 344 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); | 345 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); |
| 345 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); | 346 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); |
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 9baf119b64db..5c1b6cf31701 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
| @@ -168,7 +168,7 @@ int pmbus_set_page(struct i2c_client *client, u8 page) | |||
| 168 | } | 168 | } |
| 169 | EXPORT_SYMBOL_GPL(pmbus_set_page); | 169 | EXPORT_SYMBOL_GPL(pmbus_set_page); |
| 170 | 170 | ||
| 171 | static int pmbus_write_byte(struct i2c_client *client, int page, u8 value) | 171 | int pmbus_write_byte(struct i2c_client *client, int page, u8 value) |
| 172 | { | 172 | { |
| 173 | int rv; | 173 | int rv; |
| 174 | 174 | ||
| @@ -180,6 +180,7 @@ static int pmbus_write_byte(struct i2c_client *client, int page, u8 value) | |||
| 180 | 180 | ||
| 181 | return i2c_smbus_write_byte(client, value); | 181 | return i2c_smbus_write_byte(client, value); |
| 182 | } | 182 | } |
| 183 | EXPORT_SYMBOL_GPL(pmbus_write_byte); | ||
| 183 | 184 | ||
| 184 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word) | 185 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word) |
| 185 | { | 186 | { |
