| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * w83792d.c - Part of lm_sensors, Linux kernel modules for hardware |
|---|
| 3 | 4 | * monitoring |
|---|
| 4 | 5 | * Copyright (C) 2004, 2005 Winbond Electronics Corp. |
|---|
| 5 | 6 | * Shane Huang, |
|---|
| 6 | 7 | * Rudolf Marek <r.marek@assembler.cz> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to the Free Software |
|---|
| 20 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 21 | 8 | * |
|---|
| 22 | 9 | * Note: |
|---|
| 23 | 10 | * 1. This driver is only for 2.6 kernel, 2.4 kernel need a different driver. |
|---|
| .. | .. |
|---|
| 277 | 264 | char valid; /* !=0 if following fields are valid */ |
|---|
| 278 | 265 | unsigned long last_updated; /* In jiffies */ |
|---|
| 279 | 266 | |
|---|
| 280 | | - /* array of 2 pointers to subclients */ |
|---|
| 281 | | - struct i2c_client *lm75[2]; |
|---|
| 282 | | - |
|---|
| 283 | 267 | u8 in[9]; /* Register value */ |
|---|
| 284 | 268 | u8 in_max[9]; /* Register value */ |
|---|
| 285 | 269 | u8 in_min[9]; /* Register value */ |
|---|
| .. | .. |
|---|
| 299 | 283 | u8 sf2_levels[3][4]; /* Smart FanII: Fan1,2,3 duty cycle levels */ |
|---|
| 300 | 284 | }; |
|---|
| 301 | 285 | |
|---|
| 302 | | -static int w83792d_probe(struct i2c_client *client, |
|---|
| 303 | | - const struct i2c_device_id *id); |
|---|
| 286 | +static int w83792d_probe(struct i2c_client *client); |
|---|
| 304 | 287 | static int w83792d_detect(struct i2c_client *client, |
|---|
| 305 | 288 | struct i2c_board_info *info); |
|---|
| 306 | 289 | static int w83792d_remove(struct i2c_client *client); |
|---|
| .. | .. |
|---|
| 323 | 306 | .driver = { |
|---|
| 324 | 307 | .name = "w83792d", |
|---|
| 325 | 308 | }, |
|---|
| 326 | | - .probe = w83792d_probe, |
|---|
| 309 | + .probe_new = w83792d_probe, |
|---|
| 327 | 310 | .remove = w83792d_remove, |
|---|
| 328 | 311 | .id_table = w83792d_id, |
|---|
| 329 | 312 | .detect = w83792d_detect, |
|---|
| .. | .. |
|---|
| 937 | 920 | static int |
|---|
| 938 | 921 | w83792d_detect_subclients(struct i2c_client *new_client) |
|---|
| 939 | 922 | { |
|---|
| 940 | | - int i, id, err; |
|---|
| 923 | + int i, id; |
|---|
| 941 | 924 | int address = new_client->addr; |
|---|
| 942 | 925 | u8 val; |
|---|
| 943 | 926 | struct i2c_adapter *adapter = new_client->adapter; |
|---|
| 944 | | - struct w83792d_data *data = i2c_get_clientdata(new_client); |
|---|
| 945 | 927 | |
|---|
| 946 | 928 | id = i2c_adapter_id(adapter); |
|---|
| 947 | 929 | if (force_subclients[0] == id && force_subclients[1] == address) { |
|---|
| .. | .. |
|---|
| 951 | 933 | dev_err(&new_client->dev, |
|---|
| 952 | 934 | "invalid subclient address %d; must be 0x48-0x4f\n", |
|---|
| 953 | 935 | force_subclients[i]); |
|---|
| 954 | | - err = -ENODEV; |
|---|
| 955 | | - goto ERROR_SC_0; |
|---|
| 936 | + return -ENODEV; |
|---|
| 956 | 937 | } |
|---|
| 957 | 938 | } |
|---|
| 958 | 939 | w83792d_write_value(new_client, W83792D_REG_I2C_SUBADDR, |
|---|
| .. | .. |
|---|
| 961 | 942 | } |
|---|
| 962 | 943 | |
|---|
| 963 | 944 | val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR); |
|---|
| 964 | | - if (!(val & 0x08)) |
|---|
| 965 | | - data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7)); |
|---|
| 966 | | - if (!(val & 0x80)) { |
|---|
| 967 | | - if ((data->lm75[0] != NULL) && |
|---|
| 968 | | - ((val & 0x7) == ((val >> 4) & 0x7))) { |
|---|
| 969 | | - dev_err(&new_client->dev, |
|---|
| 970 | | - "duplicate addresses 0x%x, use force_subclient\n", |
|---|
| 971 | | - data->lm75[0]->addr); |
|---|
| 972 | | - err = -ENODEV; |
|---|
| 973 | | - goto ERROR_SC_1; |
|---|
| 974 | | - } |
|---|
| 975 | | - data->lm75[1] = i2c_new_dummy(adapter, |
|---|
| 976 | | - 0x48 + ((val >> 4) & 0x7)); |
|---|
| 945 | + |
|---|
| 946 | + if (!(val & 0x88) && (val & 0x7) == ((val >> 4) & 0x7)) { |
|---|
| 947 | + dev_err(&new_client->dev, |
|---|
| 948 | + "duplicate addresses 0x%x, use force_subclient\n", 0x48 + (val & 0x7)); |
|---|
| 949 | + return -ENODEV; |
|---|
| 977 | 950 | } |
|---|
| 978 | 951 | |
|---|
| 952 | + if (!(val & 0x08)) |
|---|
| 953 | + devm_i2c_new_dummy_device(&new_client->dev, adapter, 0x48 + (val & 0x7)); |
|---|
| 954 | + |
|---|
| 955 | + if (!(val & 0x80)) |
|---|
| 956 | + devm_i2c_new_dummy_device(&new_client->dev, adapter, 0x48 + ((val >> 4) & 0x7)); |
|---|
| 957 | + |
|---|
| 979 | 958 | return 0; |
|---|
| 980 | | - |
|---|
| 981 | | -/* Undo inits in case of errors */ |
|---|
| 982 | | - |
|---|
| 983 | | -ERROR_SC_1: |
|---|
| 984 | | - i2c_unregister_device(data->lm75[0]); |
|---|
| 985 | | -ERROR_SC_0: |
|---|
| 986 | | - return err; |
|---|
| 987 | 959 | } |
|---|
| 988 | 960 | |
|---|
| 989 | 961 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0); |
|---|
| .. | .. |
|---|
| 1380 | 1352 | } |
|---|
| 1381 | 1353 | |
|---|
| 1382 | 1354 | static int |
|---|
| 1383 | | -w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id) |
|---|
| 1355 | +w83792d_probe(struct i2c_client *client) |
|---|
| 1384 | 1356 | { |
|---|
| 1385 | 1357 | struct w83792d_data *data; |
|---|
| 1386 | 1358 | struct device *dev = &client->dev; |
|---|
| .. | .. |
|---|
| 1409 | 1381 | /* Register sysfs hooks */ |
|---|
| 1410 | 1382 | err = sysfs_create_group(&dev->kobj, &w83792d_group); |
|---|
| 1411 | 1383 | if (err) |
|---|
| 1412 | | - goto exit_i2c_unregister; |
|---|
| 1384 | + return err; |
|---|
| 1413 | 1385 | |
|---|
| 1414 | 1386 | /* |
|---|
| 1415 | 1387 | * Read GPIO enable register to check if pins for fan 4,5 are used as |
|---|
| .. | .. |
|---|
| 1454 | 1426 | sysfs_remove_group(&dev->kobj, &w83792d_group); |
|---|
| 1455 | 1427 | for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) |
|---|
| 1456 | 1428 | sysfs_remove_group(&dev->kobj, &w83792d_group_fan[i]); |
|---|
| 1457 | | -exit_i2c_unregister: |
|---|
| 1458 | | - i2c_unregister_device(data->lm75[0]); |
|---|
| 1459 | | - i2c_unregister_device(data->lm75[1]); |
|---|
| 1460 | 1429 | return err; |
|---|
| 1461 | 1430 | } |
|---|
| 1462 | 1431 | |
|---|
| .. | .. |
|---|
| 1471 | 1440 | for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) |
|---|
| 1472 | 1441 | sysfs_remove_group(&client->dev.kobj, |
|---|
| 1473 | 1442 | &w83792d_group_fan[i]); |
|---|
| 1474 | | - |
|---|
| 1475 | | - i2c_unregister_device(data->lm75[0]); |
|---|
| 1476 | | - i2c_unregister_device(data->lm75[1]); |
|---|
| 1477 | 1443 | |
|---|
| 1478 | 1444 | return 0; |
|---|
| 1479 | 1445 | } |
|---|