| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Hardware monitoring driver for Maxim MAX34440/MAX34441 |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2011 Ericsson AB. |
|---|
| 5 | 6 | * Copyright (c) 2012 Guenter Roeck |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | | - * (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License |
|---|
| 18 | | - * along with this program; if not, write to the Free Software |
|---|
| 19 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 20 | 7 | */ |
|---|
| 21 | 8 | |
|---|
| 22 | 9 | #include <linux/bitops.h> |
|---|
| .. | .. |
|---|
| 44 | 31 | #define MAX34440_STATUS_OT_FAULT BIT(5) |
|---|
| 45 | 32 | #define MAX34440_STATUS_OT_WARN BIT(6) |
|---|
| 46 | 33 | |
|---|
| 34 | +/* |
|---|
| 35 | + * The whole max344* family have IOUT_OC_WARN_LIMIT and IOUT_OC_FAULT_LIMIT |
|---|
| 36 | + * swapped from the standard pmbus spec addresses. |
|---|
| 37 | + */ |
|---|
| 38 | +#define MAX34440_IOUT_OC_WARN_LIMIT 0x46 |
|---|
| 39 | +#define MAX34440_IOUT_OC_FAULT_LIMIT 0x4A |
|---|
| 40 | + |
|---|
| 47 | 41 | #define MAX34451_MFR_CHANNEL_CONFIG 0xe4 |
|---|
| 48 | 42 | #define MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK 0x3f |
|---|
| 49 | 43 | |
|---|
| .. | .. |
|---|
| 54 | 48 | |
|---|
| 55 | 49 | #define to_max34440_data(x) container_of(x, struct max34440_data, info) |
|---|
| 56 | 50 | |
|---|
| 57 | | -static int max34440_read_word_data(struct i2c_client *client, int page, int reg) |
|---|
| 51 | +static const struct i2c_device_id max34440_id[]; |
|---|
| 52 | + |
|---|
| 53 | +static int max34440_read_word_data(struct i2c_client *client, int page, |
|---|
| 54 | + int phase, int reg) |
|---|
| 58 | 55 | { |
|---|
| 59 | 56 | int ret; |
|---|
| 60 | 57 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
|---|
| 61 | 58 | const struct max34440_data *data = to_max34440_data(info); |
|---|
| 62 | 59 | |
|---|
| 63 | 60 | switch (reg) { |
|---|
| 61 | + case PMBUS_IOUT_OC_FAULT_LIMIT: |
|---|
| 62 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 63 | + MAX34440_IOUT_OC_FAULT_LIMIT); |
|---|
| 64 | + break; |
|---|
| 65 | + case PMBUS_IOUT_OC_WARN_LIMIT: |
|---|
| 66 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 67 | + MAX34440_IOUT_OC_WARN_LIMIT); |
|---|
| 68 | + break; |
|---|
| 64 | 69 | case PMBUS_VIRT_READ_VOUT_MIN: |
|---|
| 65 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 70 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 66 | 71 | MAX34440_MFR_VOUT_MIN); |
|---|
| 67 | 72 | break; |
|---|
| 68 | 73 | case PMBUS_VIRT_READ_VOUT_MAX: |
|---|
| 69 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 74 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 70 | 75 | MAX34440_MFR_VOUT_PEAK); |
|---|
| 71 | 76 | break; |
|---|
| 72 | 77 | case PMBUS_VIRT_READ_IOUT_AVG: |
|---|
| 73 | 78 | if (data->id != max34446 && data->id != max34451) |
|---|
| 74 | 79 | return -ENXIO; |
|---|
| 75 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 80 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 76 | 81 | MAX34446_MFR_IOUT_AVG); |
|---|
| 77 | 82 | break; |
|---|
| 78 | 83 | case PMBUS_VIRT_READ_IOUT_MAX: |
|---|
| 79 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 84 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 80 | 85 | MAX34440_MFR_IOUT_PEAK); |
|---|
| 81 | 86 | break; |
|---|
| 82 | 87 | case PMBUS_VIRT_READ_POUT_AVG: |
|---|
| 83 | 88 | if (data->id != max34446) |
|---|
| 84 | 89 | return -ENXIO; |
|---|
| 85 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 90 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 86 | 91 | MAX34446_MFR_POUT_AVG); |
|---|
| 87 | 92 | break; |
|---|
| 88 | 93 | case PMBUS_VIRT_READ_POUT_MAX: |
|---|
| 89 | 94 | if (data->id != max34446) |
|---|
| 90 | 95 | return -ENXIO; |
|---|
| 91 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 96 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 92 | 97 | MAX34446_MFR_POUT_PEAK); |
|---|
| 93 | 98 | break; |
|---|
| 94 | 99 | case PMBUS_VIRT_READ_TEMP_AVG: |
|---|
| 95 | 100 | if (data->id != max34446 && data->id != max34460 && |
|---|
| 96 | 101 | data->id != max34461) |
|---|
| 97 | 102 | return -ENXIO; |
|---|
| 98 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 103 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 99 | 104 | MAX34446_MFR_TEMPERATURE_AVG); |
|---|
| 100 | 105 | break; |
|---|
| 101 | 106 | case PMBUS_VIRT_READ_TEMP_MAX: |
|---|
| 102 | | - ret = pmbus_read_word_data(client, page, |
|---|
| 107 | + ret = pmbus_read_word_data(client, page, phase, |
|---|
| 103 | 108 | MAX34440_MFR_TEMPERATURE_PEAK); |
|---|
| 104 | 109 | break; |
|---|
| 105 | 110 | case PMBUS_VIRT_RESET_POUT_HISTORY: |
|---|
| .. | .. |
|---|
| 127 | 132 | int ret; |
|---|
| 128 | 133 | |
|---|
| 129 | 134 | switch (reg) { |
|---|
| 135 | + case PMBUS_IOUT_OC_FAULT_LIMIT: |
|---|
| 136 | + ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_FAULT_LIMIT, |
|---|
| 137 | + word); |
|---|
| 138 | + break; |
|---|
| 139 | + case PMBUS_IOUT_OC_WARN_LIMIT: |
|---|
| 140 | + ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_WARN_LIMIT, |
|---|
| 141 | + word); |
|---|
| 142 | + break; |
|---|
| 130 | 143 | case PMBUS_VIRT_RESET_POUT_HISTORY: |
|---|
| 131 | 144 | ret = pmbus_write_word_data(client, page, |
|---|
| 132 | 145 | MAX34446_MFR_POUT_PEAK, 0); |
|---|
| .. | .. |
|---|
| 172 | 185 | int mfg_status; |
|---|
| 173 | 186 | |
|---|
| 174 | 187 | if (page >= 0) { |
|---|
| 175 | | - ret = pmbus_set_page(client, page); |
|---|
| 188 | + ret = pmbus_set_page(client, page, 0xff); |
|---|
| 176 | 189 | if (ret < 0) |
|---|
| 177 | 190 | return ret; |
|---|
| 178 | 191 | } |
|---|
| 179 | 192 | |
|---|
| 180 | 193 | switch (reg) { |
|---|
| 181 | 194 | case PMBUS_STATUS_IOUT: |
|---|
| 182 | | - mfg_status = pmbus_read_word_data(client, 0, |
|---|
| 195 | + mfg_status = pmbus_read_word_data(client, 0, 0xff, |
|---|
| 183 | 196 | PMBUS_STATUS_MFR_SPECIFIC); |
|---|
| 184 | 197 | if (mfg_status < 0) |
|---|
| 185 | 198 | return mfg_status; |
|---|
| .. | .. |
|---|
| 189 | 202 | ret |= PB_IOUT_OC_FAULT; |
|---|
| 190 | 203 | break; |
|---|
| 191 | 204 | case PMBUS_STATUS_TEMPERATURE: |
|---|
| 192 | | - mfg_status = pmbus_read_word_data(client, 0, |
|---|
| 205 | + mfg_status = pmbus_read_word_data(client, 0, 0xff, |
|---|
| 193 | 206 | PMBUS_STATUS_MFR_SPECIFIC); |
|---|
| 194 | 207 | if (mfg_status < 0) |
|---|
| 195 | 208 | return mfg_status; |
|---|
| .. | .. |
|---|
| 470 | 483 | }, |
|---|
| 471 | 484 | }; |
|---|
| 472 | 485 | |
|---|
| 473 | | -static int max34440_probe(struct i2c_client *client, |
|---|
| 474 | | - const struct i2c_device_id *id) |
|---|
| 486 | +static int max34440_probe(struct i2c_client *client) |
|---|
| 475 | 487 | { |
|---|
| 476 | 488 | struct max34440_data *data; |
|---|
| 477 | 489 | int rv; |
|---|
| .. | .. |
|---|
| 480 | 492 | GFP_KERNEL); |
|---|
| 481 | 493 | if (!data) |
|---|
| 482 | 494 | return -ENOMEM; |
|---|
| 483 | | - data->id = id->driver_data; |
|---|
| 484 | | - data->info = max34440_info[id->driver_data]; |
|---|
| 495 | + data->id = i2c_match_id(max34440_id, client)->driver_data; |
|---|
| 496 | + data->info = max34440_info[data->id]; |
|---|
| 485 | 497 | |
|---|
| 486 | 498 | if (data->id == max34451) { |
|---|
| 487 | 499 | rv = max34451_set_supported_funcs(client, data); |
|---|
| .. | .. |
|---|
| 489 | 501 | return rv; |
|---|
| 490 | 502 | } |
|---|
| 491 | 503 | |
|---|
| 492 | | - return pmbus_do_probe(client, id, &data->info); |
|---|
| 504 | + return pmbus_do_probe(client, &data->info); |
|---|
| 493 | 505 | } |
|---|
| 494 | 506 | |
|---|
| 495 | 507 | static const struct i2c_device_id max34440_id[] = { |
|---|
| .. | .. |
|---|
| 508 | 520 | .driver = { |
|---|
| 509 | 521 | .name = "max34440", |
|---|
| 510 | 522 | }, |
|---|
| 511 | | - .probe = max34440_probe, |
|---|
| 523 | + .probe_new = max34440_probe, |
|---|
| 512 | 524 | .remove = pmbus_do_remove, |
|---|
| 513 | 525 | .id_table = max34440_id, |
|---|
| 514 | 526 | }; |
|---|