| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * jc42.c - driver for Jedec JC42.4 compliant temperature sensors |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Derived from lm77.c by Andras BALI <drewie@freemail.hu>. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * JC42.4 compliant temperature sensors are typically used on memory modules. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 12 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 13 | | - * (at your option) any later version. |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 18 | | - * GNU General Public License for more details. |
|---|
| 19 | | - * |
|---|
| 20 | | - * You should have received a copy of the GNU General Public License |
|---|
| 21 | | - * along with this program; if not, write to the Free Software |
|---|
| 22 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 23 | 10 | */ |
|---|
| 24 | 11 | |
|---|
| 25 | 12 | #include <linux/bitops.h> |
|---|
| .. | .. |
|---|
| 32 | 19 | #include <linux/err.h> |
|---|
| 33 | 20 | #include <linux/mutex.h> |
|---|
| 34 | 21 | #include <linux/of.h> |
|---|
| 22 | +#include <linux/regmap.h> |
|---|
| 35 | 23 | |
|---|
| 36 | 24 | /* Addresses to scan */ |
|---|
| 37 | 25 | static const unsigned short normal_i2c[] = { |
|---|
| .. | .. |
|---|
| 202 | 190 | { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, |
|---|
| 203 | 191 | }; |
|---|
| 204 | 192 | |
|---|
| 205 | | -enum temp_index { |
|---|
| 206 | | - t_input = 0, |
|---|
| 207 | | - t_crit, |
|---|
| 208 | | - t_min, |
|---|
| 209 | | - t_max, |
|---|
| 210 | | - t_num_temp |
|---|
| 211 | | -}; |
|---|
| 212 | | - |
|---|
| 213 | | -static const u8 temp_regs[t_num_temp] = { |
|---|
| 214 | | - [t_input] = JC42_REG_TEMP, |
|---|
| 215 | | - [t_crit] = JC42_REG_TEMP_CRITICAL, |
|---|
| 216 | | - [t_min] = JC42_REG_TEMP_LOWER, |
|---|
| 217 | | - [t_max] = JC42_REG_TEMP_UPPER, |
|---|
| 218 | | -}; |
|---|
| 219 | | - |
|---|
| 220 | 193 | /* Each client has this additional data */ |
|---|
| 221 | 194 | struct jc42_data { |
|---|
| 222 | | - struct i2c_client *client; |
|---|
| 223 | 195 | struct mutex update_lock; /* protect register access */ |
|---|
| 196 | + struct regmap *regmap; |
|---|
| 224 | 197 | bool extended; /* true if extended range supported */ |
|---|
| 225 | 198 | bool valid; |
|---|
| 226 | | - unsigned long last_updated; /* In jiffies */ |
|---|
| 227 | 199 | u16 orig_config; /* original configuration */ |
|---|
| 228 | 200 | u16 config; /* current configuration */ |
|---|
| 229 | | - u16 temp[t_num_temp];/* Temperatures */ |
|---|
| 230 | 201 | }; |
|---|
| 231 | 202 | |
|---|
| 232 | 203 | #define JC42_TEMP_MIN_EXTENDED (-40000) |
|---|
| .. | .. |
|---|
| 251 | 222 | return reg * 125 / 2; |
|---|
| 252 | 223 | } |
|---|
| 253 | 224 | |
|---|
| 254 | | -static struct jc42_data *jc42_update_device(struct device *dev) |
|---|
| 255 | | -{ |
|---|
| 256 | | - struct jc42_data *data = dev_get_drvdata(dev); |
|---|
| 257 | | - struct i2c_client *client = data->client; |
|---|
| 258 | | - struct jc42_data *ret = data; |
|---|
| 259 | | - int i, val; |
|---|
| 260 | | - |
|---|
| 261 | | - mutex_lock(&data->update_lock); |
|---|
| 262 | | - |
|---|
| 263 | | - if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
|---|
| 264 | | - for (i = 0; i < t_num_temp; i++) { |
|---|
| 265 | | - val = i2c_smbus_read_word_swapped(client, temp_regs[i]); |
|---|
| 266 | | - if (val < 0) { |
|---|
| 267 | | - ret = ERR_PTR(val); |
|---|
| 268 | | - goto abort; |
|---|
| 269 | | - } |
|---|
| 270 | | - data->temp[i] = val; |
|---|
| 271 | | - } |
|---|
| 272 | | - data->last_updated = jiffies; |
|---|
| 273 | | - data->valid = true; |
|---|
| 274 | | - } |
|---|
| 275 | | -abort: |
|---|
| 276 | | - mutex_unlock(&data->update_lock); |
|---|
| 277 | | - return ret; |
|---|
| 278 | | -} |
|---|
| 279 | | - |
|---|
| 280 | 225 | static int jc42_read(struct device *dev, enum hwmon_sensor_types type, |
|---|
| 281 | 226 | u32 attr, int channel, long *val) |
|---|
| 282 | 227 | { |
|---|
| 283 | | - struct jc42_data *data = jc42_update_device(dev); |
|---|
| 284 | | - int temp, hyst; |
|---|
| 228 | + struct jc42_data *data = dev_get_drvdata(dev); |
|---|
| 229 | + unsigned int regval; |
|---|
| 230 | + int ret, temp, hyst; |
|---|
| 285 | 231 | |
|---|
| 286 | | - if (IS_ERR(data)) |
|---|
| 287 | | - return PTR_ERR(data); |
|---|
| 232 | + mutex_lock(&data->update_lock); |
|---|
| 288 | 233 | |
|---|
| 289 | 234 | switch (attr) { |
|---|
| 290 | 235 | case hwmon_temp_input: |
|---|
| 291 | | - *val = jc42_temp_from_reg(data->temp[t_input]); |
|---|
| 292 | | - return 0; |
|---|
| 236 | + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); |
|---|
| 237 | + if (ret) |
|---|
| 238 | + break; |
|---|
| 239 | + |
|---|
| 240 | + *val = jc42_temp_from_reg(regval); |
|---|
| 241 | + break; |
|---|
| 293 | 242 | case hwmon_temp_min: |
|---|
| 294 | | - *val = jc42_temp_from_reg(data->temp[t_min]); |
|---|
| 295 | | - return 0; |
|---|
| 243 | + ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, ®val); |
|---|
| 244 | + if (ret) |
|---|
| 245 | + break; |
|---|
| 246 | + |
|---|
| 247 | + *val = jc42_temp_from_reg(regval); |
|---|
| 248 | + break; |
|---|
| 296 | 249 | case hwmon_temp_max: |
|---|
| 297 | | - *val = jc42_temp_from_reg(data->temp[t_max]); |
|---|
| 298 | | - return 0; |
|---|
| 250 | + ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); |
|---|
| 251 | + if (ret) |
|---|
| 252 | + break; |
|---|
| 253 | + |
|---|
| 254 | + *val = jc42_temp_from_reg(regval); |
|---|
| 255 | + break; |
|---|
| 299 | 256 | case hwmon_temp_crit: |
|---|
| 300 | | - *val = jc42_temp_from_reg(data->temp[t_crit]); |
|---|
| 301 | | - return 0; |
|---|
| 257 | + ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, |
|---|
| 258 | + ®val); |
|---|
| 259 | + if (ret) |
|---|
| 260 | + break; |
|---|
| 261 | + |
|---|
| 262 | + *val = jc42_temp_from_reg(regval); |
|---|
| 263 | + break; |
|---|
| 302 | 264 | case hwmon_temp_max_hyst: |
|---|
| 303 | | - temp = jc42_temp_from_reg(data->temp[t_max]); |
|---|
| 265 | + ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); |
|---|
| 266 | + if (ret) |
|---|
| 267 | + break; |
|---|
| 268 | + |
|---|
| 269 | + temp = jc42_temp_from_reg(regval); |
|---|
| 304 | 270 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) |
|---|
| 305 | 271 | >> JC42_CFG_HYST_SHIFT]; |
|---|
| 306 | 272 | *val = temp - hyst; |
|---|
| 307 | | - return 0; |
|---|
| 273 | + break; |
|---|
| 308 | 274 | case hwmon_temp_crit_hyst: |
|---|
| 309 | | - temp = jc42_temp_from_reg(data->temp[t_crit]); |
|---|
| 275 | + ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, |
|---|
| 276 | + ®val); |
|---|
| 277 | + if (ret) |
|---|
| 278 | + break; |
|---|
| 279 | + |
|---|
| 280 | + temp = jc42_temp_from_reg(regval); |
|---|
| 310 | 281 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) |
|---|
| 311 | 282 | >> JC42_CFG_HYST_SHIFT]; |
|---|
| 312 | 283 | *val = temp - hyst; |
|---|
| 313 | | - return 0; |
|---|
| 284 | + break; |
|---|
| 314 | 285 | case hwmon_temp_min_alarm: |
|---|
| 315 | | - *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1; |
|---|
| 316 | | - return 0; |
|---|
| 286 | + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); |
|---|
| 287 | + if (ret) |
|---|
| 288 | + break; |
|---|
| 289 | + |
|---|
| 290 | + *val = (regval >> JC42_ALARM_MIN_BIT) & 1; |
|---|
| 291 | + break; |
|---|
| 317 | 292 | case hwmon_temp_max_alarm: |
|---|
| 318 | | - *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1; |
|---|
| 319 | | - return 0; |
|---|
| 293 | + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); |
|---|
| 294 | + if (ret) |
|---|
| 295 | + break; |
|---|
| 296 | + |
|---|
| 297 | + *val = (regval >> JC42_ALARM_MAX_BIT) & 1; |
|---|
| 298 | + break; |
|---|
| 320 | 299 | case hwmon_temp_crit_alarm: |
|---|
| 321 | | - *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1; |
|---|
| 322 | | - return 0; |
|---|
| 300 | + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); |
|---|
| 301 | + if (ret) |
|---|
| 302 | + break; |
|---|
| 303 | + |
|---|
| 304 | + *val = (regval >> JC42_ALARM_CRIT_BIT) & 1; |
|---|
| 305 | + break; |
|---|
| 323 | 306 | default: |
|---|
| 324 | | - return -EOPNOTSUPP; |
|---|
| 307 | + ret = -EOPNOTSUPP; |
|---|
| 308 | + break; |
|---|
| 325 | 309 | } |
|---|
| 310 | + |
|---|
| 311 | + mutex_unlock(&data->update_lock); |
|---|
| 312 | + |
|---|
| 313 | + return ret; |
|---|
| 326 | 314 | } |
|---|
| 327 | 315 | |
|---|
| 328 | 316 | static int jc42_write(struct device *dev, enum hwmon_sensor_types type, |
|---|
| 329 | 317 | u32 attr, int channel, long val) |
|---|
| 330 | 318 | { |
|---|
| 331 | 319 | struct jc42_data *data = dev_get_drvdata(dev); |
|---|
| 332 | | - struct i2c_client *client = data->client; |
|---|
| 320 | + unsigned int regval; |
|---|
| 333 | 321 | int diff, hyst; |
|---|
| 334 | 322 | int ret; |
|---|
| 335 | 323 | |
|---|
| .. | .. |
|---|
| 337 | 325 | |
|---|
| 338 | 326 | switch (attr) { |
|---|
| 339 | 327 | case hwmon_temp_min: |
|---|
| 340 | | - data->temp[t_min] = jc42_temp_to_reg(val, data->extended); |
|---|
| 341 | | - ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min], |
|---|
| 342 | | - data->temp[t_min]); |
|---|
| 328 | + ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER, |
|---|
| 329 | + jc42_temp_to_reg(val, data->extended)); |
|---|
| 343 | 330 | break; |
|---|
| 344 | 331 | case hwmon_temp_max: |
|---|
| 345 | | - data->temp[t_max] = jc42_temp_to_reg(val, data->extended); |
|---|
| 346 | | - ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max], |
|---|
| 347 | | - data->temp[t_max]); |
|---|
| 332 | + ret = regmap_write(data->regmap, JC42_REG_TEMP_UPPER, |
|---|
| 333 | + jc42_temp_to_reg(val, data->extended)); |
|---|
| 348 | 334 | break; |
|---|
| 349 | 335 | case hwmon_temp_crit: |
|---|
| 350 | | - data->temp[t_crit] = jc42_temp_to_reg(val, data->extended); |
|---|
| 351 | | - ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit], |
|---|
| 352 | | - data->temp[t_crit]); |
|---|
| 336 | + ret = regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL, |
|---|
| 337 | + jc42_temp_to_reg(val, data->extended)); |
|---|
| 353 | 338 | break; |
|---|
| 354 | 339 | case hwmon_temp_crit_hyst: |
|---|
| 340 | + ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, |
|---|
| 341 | + ®val); |
|---|
| 342 | + if (ret) |
|---|
| 343 | + break; |
|---|
| 344 | + |
|---|
| 355 | 345 | /* |
|---|
| 356 | 346 | * JC42.4 compliant chips only support four hysteresis values. |
|---|
| 357 | 347 | * Pick best choice and go from there. |
|---|
| .. | .. |
|---|
| 359 | 349 | val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED |
|---|
| 360 | 350 | : JC42_TEMP_MIN) - 6000, |
|---|
| 361 | 351 | JC42_TEMP_MAX); |
|---|
| 362 | | - diff = jc42_temp_from_reg(data->temp[t_crit]) - val; |
|---|
| 352 | + diff = jc42_temp_from_reg(regval) - val; |
|---|
| 363 | 353 | hyst = 0; |
|---|
| 364 | 354 | if (diff > 0) { |
|---|
| 365 | 355 | if (diff < 2250) |
|---|
| .. | .. |
|---|
| 371 | 361 | } |
|---|
| 372 | 362 | data->config = (data->config & ~JC42_CFG_HYST_MASK) | |
|---|
| 373 | 363 | (hyst << JC42_CFG_HYST_SHIFT); |
|---|
| 374 | | - ret = i2c_smbus_write_word_swapped(data->client, |
|---|
| 375 | | - JC42_REG_CONFIG, |
|---|
| 376 | | - data->config); |
|---|
| 364 | + ret = regmap_write(data->regmap, JC42_REG_CONFIG, |
|---|
| 365 | + data->config); |
|---|
| 377 | 366 | break; |
|---|
| 378 | 367 | default: |
|---|
| 379 | 368 | ret = -EOPNOTSUPP; |
|---|
| .. | .. |
|---|
| 390 | 379 | { |
|---|
| 391 | 380 | const struct jc42_data *data = _data; |
|---|
| 392 | 381 | unsigned int config = data->config; |
|---|
| 393 | | - umode_t mode = S_IRUGO; |
|---|
| 382 | + umode_t mode = 0444; |
|---|
| 394 | 383 | |
|---|
| 395 | 384 | switch (attr) { |
|---|
| 396 | 385 | case hwmon_temp_min: |
|---|
| 397 | 386 | case hwmon_temp_max: |
|---|
| 398 | 387 | if (!(config & JC42_CFG_EVENT_LOCK)) |
|---|
| 399 | | - mode |= S_IWUSR; |
|---|
| 388 | + mode |= 0200; |
|---|
| 400 | 389 | break; |
|---|
| 401 | 390 | case hwmon_temp_crit: |
|---|
| 402 | 391 | if (!(config & JC42_CFG_TCRIT_LOCK)) |
|---|
| 403 | | - mode |= S_IWUSR; |
|---|
| 392 | + mode |= 0200; |
|---|
| 404 | 393 | break; |
|---|
| 405 | 394 | case hwmon_temp_crit_hyst: |
|---|
| 406 | 395 | if (!(config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK))) |
|---|
| 407 | | - mode |= S_IWUSR; |
|---|
| 396 | + mode |= 0200; |
|---|
| 408 | 397 | break; |
|---|
| 409 | 398 | case hwmon_temp_input: |
|---|
| 410 | 399 | case hwmon_temp_max_hyst: |
|---|
| .. | .. |
|---|
| 451 | 440 | return -ENODEV; |
|---|
| 452 | 441 | } |
|---|
| 453 | 442 | |
|---|
| 454 | | -static const u32 jc42_temp_config[] = { |
|---|
| 455 | | - HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_CRIT | |
|---|
| 456 | | - HWMON_T_MAX_HYST | HWMON_T_CRIT_HYST | |
|---|
| 457 | | - HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM, |
|---|
| 458 | | - 0 |
|---|
| 459 | | -}; |
|---|
| 460 | | - |
|---|
| 461 | | -static const struct hwmon_channel_info jc42_temp = { |
|---|
| 462 | | - .type = hwmon_temp, |
|---|
| 463 | | - .config = jc42_temp_config, |
|---|
| 464 | | -}; |
|---|
| 465 | | - |
|---|
| 466 | 443 | static const struct hwmon_channel_info *jc42_info[] = { |
|---|
| 467 | | - &jc42_temp, |
|---|
| 444 | + HWMON_CHANNEL_INFO(temp, |
|---|
| 445 | + HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | |
|---|
| 446 | + HWMON_T_CRIT | HWMON_T_MAX_HYST | |
|---|
| 447 | + HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | |
|---|
| 448 | + HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM), |
|---|
| 468 | 449 | NULL |
|---|
| 469 | 450 | }; |
|---|
| 470 | 451 | |
|---|
| .. | .. |
|---|
| 479 | 460 | .info = jc42_info, |
|---|
| 480 | 461 | }; |
|---|
| 481 | 462 | |
|---|
| 482 | | -static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) |
|---|
| 463 | +static bool jc42_readable_reg(struct device *dev, unsigned int reg) |
|---|
| 464 | +{ |
|---|
| 465 | + return (reg >= JC42_REG_CAP && reg <= JC42_REG_DEVICEID) || |
|---|
| 466 | + reg == JC42_REG_SMBUS; |
|---|
| 467 | +} |
|---|
| 468 | + |
|---|
| 469 | +static bool jc42_writable_reg(struct device *dev, unsigned int reg) |
|---|
| 470 | +{ |
|---|
| 471 | + return (reg >= JC42_REG_CONFIG && reg <= JC42_REG_TEMP_CRITICAL) || |
|---|
| 472 | + reg == JC42_REG_SMBUS; |
|---|
| 473 | +} |
|---|
| 474 | + |
|---|
| 475 | +static bool jc42_volatile_reg(struct device *dev, unsigned int reg) |
|---|
| 476 | +{ |
|---|
| 477 | + return reg == JC42_REG_CONFIG || reg == JC42_REG_TEMP; |
|---|
| 478 | +} |
|---|
| 479 | + |
|---|
| 480 | +static const struct regmap_config jc42_regmap_config = { |
|---|
| 481 | + .reg_bits = 8, |
|---|
| 482 | + .val_bits = 16, |
|---|
| 483 | + .val_format_endian = REGMAP_ENDIAN_BIG, |
|---|
| 484 | + .max_register = JC42_REG_SMBUS, |
|---|
| 485 | + .writeable_reg = jc42_writable_reg, |
|---|
| 486 | + .readable_reg = jc42_readable_reg, |
|---|
| 487 | + .volatile_reg = jc42_volatile_reg, |
|---|
| 488 | + .cache_type = REGCACHE_RBTREE, |
|---|
| 489 | +}; |
|---|
| 490 | + |
|---|
| 491 | +static int jc42_probe(struct i2c_client *client) |
|---|
| 483 | 492 | { |
|---|
| 484 | 493 | struct device *dev = &client->dev; |
|---|
| 485 | 494 | struct device *hwmon_dev; |
|---|
| 495 | + unsigned int config, cap; |
|---|
| 486 | 496 | struct jc42_data *data; |
|---|
| 487 | | - int config, cap; |
|---|
| 497 | + int ret; |
|---|
| 488 | 498 | |
|---|
| 489 | 499 | data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL); |
|---|
| 490 | 500 | if (!data) |
|---|
| 491 | 501 | return -ENOMEM; |
|---|
| 492 | 502 | |
|---|
| 493 | | - data->client = client; |
|---|
| 503 | + data->regmap = devm_regmap_init_i2c(client, &jc42_regmap_config); |
|---|
| 504 | + if (IS_ERR(data->regmap)) |
|---|
| 505 | + return PTR_ERR(data->regmap); |
|---|
| 506 | + |
|---|
| 494 | 507 | i2c_set_clientdata(client, data); |
|---|
| 495 | 508 | mutex_init(&data->update_lock); |
|---|
| 496 | 509 | |
|---|
| 497 | | - cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP); |
|---|
| 498 | | - if (cap < 0) |
|---|
| 499 | | - return cap; |
|---|
| 510 | + ret = regmap_read(data->regmap, JC42_REG_CAP, &cap); |
|---|
| 511 | + if (ret) |
|---|
| 512 | + return ret; |
|---|
| 500 | 513 | |
|---|
| 501 | 514 | data->extended = !!(cap & JC42_CAP_RANGE); |
|---|
| 502 | 515 | |
|---|
| 503 | 516 | if (device_property_read_bool(dev, "smbus-timeout-disable")) { |
|---|
| 504 | | - int smbus; |
|---|
| 505 | | - |
|---|
| 506 | 517 | /* |
|---|
| 507 | 518 | * Not all chips support this register, but from a |
|---|
| 508 | 519 | * quick read of various datasheets no chip appears |
|---|
| 509 | 520 | * incompatible with the below attempt to disable |
|---|
| 510 | 521 | * the timeout. And the whole thing is opt-in... |
|---|
| 511 | 522 | */ |
|---|
| 512 | | - smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS); |
|---|
| 513 | | - if (smbus < 0) |
|---|
| 514 | | - return smbus; |
|---|
| 515 | | - i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS, |
|---|
| 516 | | - smbus | SMBUS_STMOUT); |
|---|
| 523 | + ret = regmap_set_bits(data->regmap, JC42_REG_SMBUS, |
|---|
| 524 | + SMBUS_STMOUT); |
|---|
| 525 | + if (ret) |
|---|
| 526 | + return ret; |
|---|
| 517 | 527 | } |
|---|
| 518 | 528 | |
|---|
| 519 | | - config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); |
|---|
| 520 | | - if (config < 0) |
|---|
| 521 | | - return config; |
|---|
| 529 | + ret = regmap_read(data->regmap, JC42_REG_CONFIG, &config); |
|---|
| 530 | + if (ret) |
|---|
| 531 | + return ret; |
|---|
| 522 | 532 | |
|---|
| 523 | 533 | data->orig_config = config; |
|---|
| 524 | 534 | if (config & JC42_CFG_SHUTDOWN) { |
|---|
| 525 | 535 | config &= ~JC42_CFG_SHUTDOWN; |
|---|
| 526 | | - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); |
|---|
| 536 | + regmap_write(data->regmap, JC42_REG_CONFIG, config); |
|---|
| 527 | 537 | } |
|---|
| 528 | 538 | data->config = config; |
|---|
| 529 | 539 | |
|---|
| .. | .. |
|---|
| 544 | 554 | |
|---|
| 545 | 555 | config = (data->orig_config & ~JC42_CFG_HYST_MASK) |
|---|
| 546 | 556 | | (data->config & JC42_CFG_HYST_MASK); |
|---|
| 547 | | - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); |
|---|
| 557 | + regmap_write(data->regmap, JC42_REG_CONFIG, config); |
|---|
| 548 | 558 | } |
|---|
| 549 | 559 | return 0; |
|---|
| 550 | 560 | } |
|---|
| .. | .. |
|---|
| 556 | 566 | struct jc42_data *data = dev_get_drvdata(dev); |
|---|
| 557 | 567 | |
|---|
| 558 | 568 | data->config |= JC42_CFG_SHUTDOWN; |
|---|
| 559 | | - i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, |
|---|
| 560 | | - data->config); |
|---|
| 569 | + regmap_write(data->regmap, JC42_REG_CONFIG, data->config); |
|---|
| 570 | + |
|---|
| 571 | + regcache_cache_only(data->regmap, true); |
|---|
| 572 | + regcache_mark_dirty(data->regmap); |
|---|
| 573 | + |
|---|
| 561 | 574 | return 0; |
|---|
| 562 | 575 | } |
|---|
| 563 | 576 | |
|---|
| .. | .. |
|---|
| 565 | 578 | { |
|---|
| 566 | 579 | struct jc42_data *data = dev_get_drvdata(dev); |
|---|
| 567 | 580 | |
|---|
| 581 | + regcache_cache_only(data->regmap, false); |
|---|
| 582 | + |
|---|
| 568 | 583 | data->config &= ~JC42_CFG_SHUTDOWN; |
|---|
| 569 | | - i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, |
|---|
| 570 | | - data->config); |
|---|
| 571 | | - return 0; |
|---|
| 584 | + regmap_write(data->regmap, JC42_REG_CONFIG, data->config); |
|---|
| 585 | + |
|---|
| 586 | + /* Restore cached register values to hardware */ |
|---|
| 587 | + return regcache_sync(data->regmap); |
|---|
| 572 | 588 | } |
|---|
| 573 | 589 | |
|---|
| 574 | 590 | static const struct dev_pm_ops jc42_dev_pm_ops = { |
|---|
| .. | .. |
|---|
| 602 | 618 | .pm = JC42_DEV_PM_OPS, |
|---|
| 603 | 619 | .of_match_table = of_match_ptr(jc42_of_ids), |
|---|
| 604 | 620 | }, |
|---|
| 605 | | - .probe = jc42_probe, |
|---|
| 621 | + .probe_new = jc42_probe, |
|---|
| 606 | 622 | .remove = jc42_remove, |
|---|
| 607 | 623 | .id_table = jc42_id, |
|---|
| 608 | 624 | .detect = jc42_detect, |
|---|