1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * ADT7410/ADT7420 digital temperature sensor driver |
4 | * |
5 | * Copyright 2012-2013 Analog Devices Inc. |
6 | * Author: Lars-Peter Clausen <lars@metafoo.de> |
7 | */ |
8 | |
9 | #include <linux/module.h> |
10 | #include <linux/init.h> |
11 | #include <linux/i2c.h> |
12 | #include <linux/regmap.h> |
13 | |
14 | #include "adt7x10.h" |
15 | |
16 | static bool adt7410_regmap_is_volatile(struct device *dev, unsigned int reg) |
17 | { |
18 | switch (reg) { |
19 | case ADT7X10_TEMPERATURE: |
20 | case ADT7X10_STATUS: |
21 | return true; |
22 | default: |
23 | return false; |
24 | } |
25 | } |
26 | |
27 | static int adt7410_reg_read(void *context, unsigned int reg, unsigned int *val) |
28 | { |
29 | struct i2c_client *client = context; |
30 | int regval; |
31 | |
32 | switch (reg) { |
33 | case ADT7X10_TEMPERATURE: |
34 | case ADT7X10_T_ALARM_HIGH: |
35 | case ADT7X10_T_ALARM_LOW: |
36 | case ADT7X10_T_CRIT: |
37 | regval = i2c_smbus_read_word_swapped(client, command: reg); |
38 | break; |
39 | default: |
40 | regval = i2c_smbus_read_byte_data(client, command: reg); |
41 | break; |
42 | } |
43 | if (regval < 0) |
44 | return regval; |
45 | *val = regval; |
46 | return 0; |
47 | } |
48 | |
49 | static int adt7410_reg_write(void *context, unsigned int reg, unsigned int val) |
50 | { |
51 | struct i2c_client *client = context; |
52 | int ret; |
53 | |
54 | switch (reg) { |
55 | case ADT7X10_TEMPERATURE: |
56 | case ADT7X10_T_ALARM_HIGH: |
57 | case ADT7X10_T_ALARM_LOW: |
58 | case ADT7X10_T_CRIT: |
59 | ret = i2c_smbus_write_word_swapped(client, command: reg, value: val); |
60 | break; |
61 | default: |
62 | ret = i2c_smbus_write_byte_data(client, command: reg, value: val); |
63 | break; |
64 | } |
65 | return ret; |
66 | } |
67 | |
68 | static const struct regmap_config adt7410_regmap_config = { |
69 | .reg_bits = 8, |
70 | .val_bits = 16, |
71 | .max_register = ADT7X10_ID, |
72 | .cache_type = REGCACHE_RBTREE, |
73 | .volatile_reg = adt7410_regmap_is_volatile, |
74 | .reg_read = adt7410_reg_read, |
75 | .reg_write = adt7410_reg_write, |
76 | }; |
77 | |
78 | static int adt7410_i2c_probe(struct i2c_client *client) |
79 | { |
80 | struct regmap *regmap; |
81 | |
82 | regmap = devm_regmap_init(&client->dev, NULL, client, |
83 | &adt7410_regmap_config); |
84 | if (IS_ERR(ptr: regmap)) |
85 | return PTR_ERR(ptr: regmap); |
86 | |
87 | return adt7x10_probe(dev: &client->dev, name: client->name, irq: client->irq, regmap); |
88 | } |
89 | |
90 | static const struct i2c_device_id adt7410_ids[] = { |
91 | { "adt7410" , 0 }, |
92 | { "adt7420" , 0 }, |
93 | {} |
94 | }; |
95 | MODULE_DEVICE_TABLE(i2c, adt7410_ids); |
96 | |
97 | static struct i2c_driver adt7410_driver = { |
98 | .class = I2C_CLASS_HWMON, |
99 | .driver = { |
100 | .name = "adt7410" , |
101 | .pm = pm_sleep_ptr(&adt7x10_dev_pm_ops), |
102 | }, |
103 | .probe = adt7410_i2c_probe, |
104 | .id_table = adt7410_ids, |
105 | .address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b), |
106 | }; |
107 | module_i2c_driver(adt7410_driver); |
108 | |
109 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>" ); |
110 | MODULE_DESCRIPTION("ADT7410/AD7420 driver" ); |
111 | MODULE_LICENSE("GPL" ); |
112 | |