.. | .. |
---|
| 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, |
---|