aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2014-05-12 13:44:48 -0400
committerGuenter Roeck <linux@roeck-us.net>2014-05-21 19:02:23 -0400
commit4cab259f866ed33571c5f9e3f4bc2799ab64ba45 (patch)
tree0c17eba6c39de840a50070ac09b063d1d702b0ac /drivers/hwmon
parent57d60b1b7e0d0d32602587fd032d56d7ed9e1556 (diff)
hwmon: (emc1403) Convert to use regmap
Convert to regmap to be able to use its register caching mechanism. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/emc1403.c117
1 files changed, 63 insertions, 54 deletions
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 0bb0bab60163..3c9a8a94753f 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -18,9 +18,6 @@
18 * with this program; if not, write to the Free Software Foundation, Inc., 18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 *
22 * TODO
23 * - cache alarm and critical limit registers
24 */ 21 */
25 22
26#include <linux/module.h> 23#include <linux/module.h>
@@ -32,7 +29,7 @@
32#include <linux/err.h> 29#include <linux/err.h>
33#include <linux/sysfs.h> 30#include <linux/sysfs.h>
34#include <linux/mutex.h> 31#include <linux/mutex.h>
35#include <linux/jiffies.h> 32#include <linux/regmap.h>
36 33
37#define THERMAL_PID_REG 0xfd 34#define THERMAL_PID_REG 0xfd
38#define THERMAL_SMSC_ID_REG 0xfe 35#define THERMAL_SMSC_ID_REG 0xfe
@@ -41,15 +38,9 @@
41enum emc1403_chip { emc1402, emc1403, emc1404 }; 38enum emc1403_chip { emc1402, emc1403, emc1404 };
42 39
43struct thermal_data { 40struct thermal_data {
44 struct i2c_client *client; 41 struct regmap *regmap;
45 const struct attribute_group *groups[4];
46 struct mutex mutex; 42 struct mutex mutex;
47 /* 43 const struct attribute_group *groups[4];
48 * Cache the hyst value so we don't keep re-reading it. In theory
49 * we could cache it forever as nobody else should be writing it.
50 */
51 u8 cached_hyst;
52 unsigned long hyst_valid;
53}; 44};
54 45
55static ssize_t show_temp(struct device *dev, 46static ssize_t show_temp(struct device *dev,
@@ -57,12 +48,13 @@ static ssize_t show_temp(struct device *dev,
57{ 48{
58 struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); 49 struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
59 struct thermal_data *data = dev_get_drvdata(dev); 50 struct thermal_data *data = dev_get_drvdata(dev);
51 unsigned int val;
60 int retval; 52 int retval;
61 53
62 retval = i2c_smbus_read_byte_data(data->client, sda->index); 54 retval = regmap_read(data->regmap, sda->index, &val);
63 if (retval < 0) 55 if (retval < 0)
64 return retval; 56 return retval;
65 return sprintf(buf, "%d000\n", retval); 57 return sprintf(buf, "%d000\n", val);
66} 58}
67 59
68static ssize_t show_bit(struct device *dev, 60static ssize_t show_bit(struct device *dev,
@@ -70,12 +62,13 @@ static ssize_t show_bit(struct device *dev,
70{ 62{
71 struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); 63 struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr);
72 struct thermal_data *data = dev_get_drvdata(dev); 64 struct thermal_data *data = dev_get_drvdata(dev);
65 unsigned int val;
73 int retval; 66 int retval;
74 67
75 retval = i2c_smbus_read_byte_data(data->client, sda->nr); 68 retval = regmap_read(data->regmap, sda->nr, &val);
76 if (retval < 0) 69 if (retval < 0)
77 return retval; 70 return retval;
78 return sprintf(buf, "%d\n", !!(retval & sda->index)); 71 return sprintf(buf, "%d\n", !!(val & sda->index));
79} 72}
80 73
81static ssize_t store_temp(struct device *dev, 74static ssize_t store_temp(struct device *dev,
@@ -88,8 +81,8 @@ static ssize_t store_temp(struct device *dev,
88 81
89 if (kstrtoul(buf, 10, &val)) 82 if (kstrtoul(buf, 10, &val))
90 return -EINVAL; 83 return -EINVAL;
91 retval = i2c_smbus_write_byte_data(data->client, sda->index, 84 retval = regmap_write(data->regmap, sda->index,
92 DIV_ROUND_CLOSEST(val, 1000)); 85 DIV_ROUND_CLOSEST(val, 1000));
93 if (retval < 0) 86 if (retval < 0)
94 return retval; 87 return retval;
95 return count; 88 return count;
@@ -100,28 +93,17 @@ static ssize_t store_bit(struct device *dev,
100{ 93{
101 struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); 94 struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr);
102 struct thermal_data *data = dev_get_drvdata(dev); 95 struct thermal_data *data = dev_get_drvdata(dev);
103 struct i2c_client *client = data->client;
104 unsigned long val; 96 unsigned long val;
105 int retval; 97 int retval;
106 98
107 if (kstrtoul(buf, 10, &val)) 99 if (kstrtoul(buf, 10, &val))
108 return -EINVAL; 100 return -EINVAL;
109 101
110 mutex_lock(&data->mutex); 102 retval = regmap_update_bits(data->regmap, sda->nr, sda->index,
111 retval = i2c_smbus_read_byte_data(client, sda->nr); 103 val ? sda->index : 0);
112 if (retval < 0) 104 if (retval < 0)
113 goto fail; 105 return retval;
114 106 return count;
115 retval &= ~sda->index;
116 if (val)
117 retval |= sda->index;
118
119 retval = i2c_smbus_write_byte_data(client, sda->index, retval);
120 if (retval == 0)
121 retval = count;
122fail:
123 mutex_unlock(&data->mutex);
124 return retval;
125} 107}
126 108
127static ssize_t show_hyst(struct device *dev, 109static ssize_t show_hyst(struct device *dev,
@@ -129,22 +111,20 @@ static ssize_t show_hyst(struct device *dev,
129{ 111{
130 struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); 112 struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
131 struct thermal_data *data = dev_get_drvdata(dev); 113 struct thermal_data *data = dev_get_drvdata(dev);
132 struct i2c_client *client = data->client; 114 struct regmap *regmap = data->regmap;
115 unsigned int limit;
116 unsigned int hyst;
133 int retval; 117 int retval;
134 int hyst;
135 118
136 retval = i2c_smbus_read_byte_data(client, sda->index); 119 retval = regmap_read(regmap, sda->index, &limit);
137 if (retval < 0) 120 if (retval < 0)
138 return retval; 121 return retval;
139 122
140 if (time_after(jiffies, data->hyst_valid)) { 123 retval = regmap_read(regmap, 0x21, &hyst);
141 hyst = i2c_smbus_read_byte_data(client, 0x21); 124 if (retval < 0)
142 if (hyst < 0) 125 return retval;
143 return retval; 126
144 data->cached_hyst = hyst; 127 return sprintf(buf, "%d000\n", limit - hyst);
145 data->hyst_valid = jiffies + HZ;
146 }
147 return sprintf(buf, "%d000\n", retval - data->cached_hyst);
148} 128}
149 129
150static ssize_t store_hyst(struct device *dev, 130static ssize_t store_hyst(struct device *dev,
@@ -152,7 +132,8 @@ static ssize_t store_hyst(struct device *dev,
152{ 132{
153 struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); 133 struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
154 struct thermal_data *data = dev_get_drvdata(dev); 134 struct thermal_data *data = dev_get_drvdata(dev);
155 struct i2c_client *client = data->client; 135 struct regmap *regmap = data->regmap;
136 unsigned int limit;
156 int retval; 137 int retval;
157 int hyst; 138 int hyst;
158 unsigned long val; 139 unsigned long val;
@@ -161,23 +142,20 @@ static ssize_t store_hyst(struct device *dev,
161 return -EINVAL; 142 return -EINVAL;
162 143
163 mutex_lock(&data->mutex); 144 mutex_lock(&data->mutex);
164 retval = i2c_smbus_read_byte_data(client, sda->index); 145 retval = regmap_read(regmap, sda->index, &limit);
165 if (retval < 0) 146 if (retval < 0)
166 goto fail; 147 goto fail;
167 148
168 hyst = retval * 1000 - val; 149 hyst = limit * 1000 - val;
169 hyst = DIV_ROUND_CLOSEST(hyst, 1000); 150 hyst = DIV_ROUND_CLOSEST(hyst, 1000);
170 if (hyst < 0 || hyst > 255) { 151 if (hyst < 0 || hyst > 255) {
171 retval = -ERANGE; 152 retval = -ERANGE;
172 goto fail; 153 goto fail;
173 } 154 }
174 155
175 retval = i2c_smbus_write_byte_data(client, 0x21, hyst); 156 retval = regmap_write(regmap, 0x21, hyst);
176 if (retval == 0) { 157 if (retval == 0)
177 retval = count; 158 retval = count;
178 data->cached_hyst = hyst;
179 data->hyst_valid = jiffies + HZ;
180 }
181fail: 159fail:
182 mutex_unlock(&data->mutex); 160 mutex_unlock(&data->mutex);
183 return retval; 161 return retval;
@@ -356,6 +334,35 @@ static int emc1403_detect(struct i2c_client *client,
356 return 0; 334 return 0;
357} 335}
358 336
337static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg)
338{
339 switch (reg) {
340 case 0x00: /* internal diode high byte */
341 case 0x01: /* external diode 1 high byte */
342 case 0x02: /* status */
343 case 0x10: /* external diode 1 low byte */
344 case 0x1b: /* external diode fault */
345 case 0x23: /* external diode 2 high byte */
346 case 0x24: /* external diode 2 low byte */
347 case 0x29: /* internal diode low byte */
348 case 0x2a: /* externl diode 3 high byte */
349 case 0x2b: /* external diode 3 low byte */
350 case 0x35: /* high limit status */
351 case 0x36: /* low limit status */
352 case 0x37: /* therm limit status */
353 return true;
354 default:
355 return false;
356 }
357}
358
359static struct regmap_config emc1403_regmap_config = {
360 .reg_bits = 8,
361 .val_bits = 8,
362 .cache_type = REGCACHE_RBTREE,
363 .volatile_reg = emc1403_regmap_is_volatile,
364};
365
359static int emc1403_probe(struct i2c_client *client, 366static int emc1403_probe(struct i2c_client *client,
360 const struct i2c_device_id *id) 367 const struct i2c_device_id *id)
361{ 368{
@@ -367,9 +374,11 @@ static int emc1403_probe(struct i2c_client *client,
367 if (data == NULL) 374 if (data == NULL)
368 return -ENOMEM; 375 return -ENOMEM;
369 376
370 data->client = client; 377 data->regmap = devm_regmap_init_i2c(client, &emc1403_regmap_config);
378 if (IS_ERR(data->regmap))
379 return PTR_ERR(data->regmap);
380
371 mutex_init(&data->mutex); 381 mutex_init(&data->mutex);
372 data->hyst_valid = jiffies - 1; /* Expired */
373 382
374 switch (id->driver_data) { 383 switch (id->driver_data) {
375 case emc1404: 384 case emc1404: