.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* tmp421.c |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de> |
---|
4 | 5 | * Preliminary support by: |
---|
5 | 6 | * Melvin Rook, Raymond Ng |
---|
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 | 7 | */ |
---|
17 | 8 | |
---|
18 | 9 | /* |
---|
.. | .. |
---|
70 | 61 | }; |
---|
71 | 62 | MODULE_DEVICE_TABLE(i2c, tmp421_id); |
---|
72 | 63 | |
---|
73 | | -static const struct of_device_id tmp421_of_match[] = { |
---|
| 64 | +static const struct of_device_id __maybe_unused tmp421_of_match[] = { |
---|
74 | 65 | { |
---|
75 | 66 | .compatible = "ti,tmp421", |
---|
76 | 67 | .data = (void *)2 |
---|
.. | .. |
---|
122 | 113 | return DIV_ROUND_CLOSEST(temp * 1000, 256); |
---|
123 | 114 | } |
---|
124 | 115 | |
---|
125 | | -static struct tmp421_data *tmp421_update_device(struct device *dev) |
---|
| 116 | +static int tmp421_update_device(struct tmp421_data *data) |
---|
126 | 117 | { |
---|
127 | | - struct tmp421_data *data = dev_get_drvdata(dev); |
---|
128 | 118 | struct i2c_client *client = data->client; |
---|
| 119 | + int ret = 0; |
---|
129 | 120 | int i; |
---|
130 | 121 | |
---|
131 | 122 | mutex_lock(&data->update_lock); |
---|
132 | 123 | |
---|
133 | | - if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { |
---|
134 | | - data->config = i2c_smbus_read_byte_data(client, |
---|
135 | | - TMP421_CONFIG_REG_1); |
---|
| 124 | + if (time_after(jiffies, data->last_updated + (HZ / 2)) || |
---|
| 125 | + !data->valid) { |
---|
| 126 | + ret = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); |
---|
| 127 | + if (ret < 0) |
---|
| 128 | + goto exit; |
---|
| 129 | + data->config = ret; |
---|
136 | 130 | |
---|
137 | 131 | for (i = 0; i < data->channels; i++) { |
---|
138 | | - data->temp[i] = i2c_smbus_read_byte_data(client, |
---|
139 | | - TMP421_TEMP_MSB[i]) << 8; |
---|
140 | | - data->temp[i] |= i2c_smbus_read_byte_data(client, |
---|
141 | | - TMP421_TEMP_LSB[i]); |
---|
| 132 | + ret = i2c_smbus_read_byte_data(client, TMP421_TEMP_MSB[i]); |
---|
| 133 | + if (ret < 0) |
---|
| 134 | + goto exit; |
---|
| 135 | + data->temp[i] = ret << 8; |
---|
| 136 | + |
---|
| 137 | + ret = i2c_smbus_read_byte_data(client, TMP421_TEMP_LSB[i]); |
---|
| 138 | + if (ret < 0) |
---|
| 139 | + goto exit; |
---|
| 140 | + data->temp[i] |= ret; |
---|
142 | 141 | } |
---|
143 | 142 | data->last_updated = jiffies; |
---|
144 | 143 | data->valid = 1; |
---|
145 | 144 | } |
---|
146 | 145 | |
---|
| 146 | +exit: |
---|
147 | 147 | mutex_unlock(&data->update_lock); |
---|
148 | 148 | |
---|
149 | | - return data; |
---|
| 149 | + if (ret < 0) { |
---|
| 150 | + data->valid = 0; |
---|
| 151 | + return ret; |
---|
| 152 | + } |
---|
| 153 | + |
---|
| 154 | + return 0; |
---|
150 | 155 | } |
---|
151 | 156 | |
---|
152 | 157 | static int tmp421_read(struct device *dev, enum hwmon_sensor_types type, |
---|
153 | 158 | u32 attr, int channel, long *val) |
---|
154 | 159 | { |
---|
155 | | - struct tmp421_data *tmp421 = tmp421_update_device(dev); |
---|
| 160 | + struct tmp421_data *tmp421 = dev_get_drvdata(dev); |
---|
| 161 | + int ret = 0; |
---|
| 162 | + |
---|
| 163 | + ret = tmp421_update_device(tmp421); |
---|
| 164 | + if (ret) |
---|
| 165 | + return ret; |
---|
156 | 166 | |
---|
157 | 167 | switch (attr) { |
---|
158 | 168 | case hwmon_temp_input: |
---|
.. | .. |
---|
215 | 225 | { |
---|
216 | 226 | enum chips kind; |
---|
217 | 227 | struct i2c_adapter *adapter = client->adapter; |
---|
218 | | - const char * const names[] = { "TMP421", "TMP422", "TMP423", |
---|
219 | | - "TMP441", "TMP442" }; |
---|
| 228 | + static const char * const names[] = { |
---|
| 229 | + "TMP421", "TMP422", "TMP423", |
---|
| 230 | + "TMP441", "TMP442" |
---|
| 231 | + }; |
---|
220 | 232 | int addr = client->addr; |
---|
221 | 233 | u8 reg; |
---|
222 | 234 | |
---|
.. | .. |
---|
274 | 286 | .read = tmp421_read, |
---|
275 | 287 | }; |
---|
276 | 288 | |
---|
277 | | -static int tmp421_probe(struct i2c_client *client, |
---|
278 | | - const struct i2c_device_id *id) |
---|
| 289 | +static int tmp421_probe(struct i2c_client *client) |
---|
279 | 290 | { |
---|
280 | 291 | struct device *dev = &client->dev; |
---|
281 | 292 | struct device *hwmon_dev; |
---|
.. | .. |
---|
291 | 302 | data->channels = (unsigned long) |
---|
292 | 303 | of_device_get_match_data(&client->dev); |
---|
293 | 304 | else |
---|
294 | | - data->channels = id->driver_data; |
---|
| 305 | + data->channels = i2c_match_id(tmp421_id, client)->driver_data; |
---|
295 | 306 | data->client = client; |
---|
296 | 307 | |
---|
297 | 308 | err = tmp421_init_client(client); |
---|
.. | .. |
---|
322 | 333 | .name = "tmp421", |
---|
323 | 334 | .of_match_table = of_match_ptr(tmp421_of_match), |
---|
324 | 335 | }, |
---|
325 | | - .probe = tmp421_probe, |
---|
| 336 | + .probe_new = tmp421_probe, |
---|
326 | 337 | .id_table = tmp421_id, |
---|
327 | 338 | .detect = tmp421_detect, |
---|
328 | 339 | .address_list = normal_i2c, |
---|