Blame view

drivers/hwmon/lm90.c 50 KB
74ba9207e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
  /*
   * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
   *          monitoring
7c81c60f3   Jean Delvare   Update Jean Delva...
5
   * Copyright (C) 2003-2010  Jean Delvare <jdelvare@suse.de>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
   *
   * Based on the lm83 driver. The LM90 is a sensor chip made by National
   * Semiconductor. It reports up to two temperatures (its own plus up to
   * one external one) with a 0.125 deg resolution (1 deg for local
a874a10cf   Jean Delvare   hwmon: (lm90) Upd...
10
   * temperature) and a 3-4 deg accuracy.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
   *
   * This driver also supports the LM89 and LM99, two other sensor chips
   * made by National Semiconductor. Both have an increased remote
   * temperature measurement accuracy (1 degree), and the LM99
   * additionally shifts remote temperatures (measured and limits) by 16
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
16
   * degrees, which allows for higher temperatures measurement.
44bbe87e9   Steven Cole   [PATCH] Spelling ...
17
   * Note that there is no way to differentiate between both chips.
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
18
   * When device is auto-detected, the driver will assume an LM99.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
   *
   * This driver also supports the LM86, another sensor chip made by
   * National Semiconductor. It is exactly similar to the LM90 except it
   * has a higher accuracy.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
   *
   * This driver also supports the ADM1032, a sensor chip made by Analog
   * Devices. That chip is similar to the LM90, with a few differences
a874a10cf   Jean Delvare   hwmon: (lm90) Upd...
26
27
   * that are not handled by this driver. Among others, it has a higher
   * accuracy than the LM90, much like the LM86 does.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
   *
   * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor
a874a10cf   Jean Delvare   hwmon: (lm90) Upd...
30
   * chips made by Maxim. These chips are similar to the LM86.
44bbe87e9   Steven Cole   [PATCH] Spelling ...
31
   * Note that there is no easy way to differentiate between the three
6948708dd   Guenter Roeck   hwmon: (lm90) Add...
32
33
34
35
36
   * variants. We use the device address to detect MAX6659, which will result
   * in a detection as max6657 if it is on address 0x4c. The extra address
   * and features of the MAX6659 are only supported if the chip is configured
   * explicitly as max6659, or if its address is not 0x4c.
   * These chips lack the remote temperature offset feature.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
   *
1a51e068c   Darrick J. Wong   hwmon: (lm90) Doc...
38
39
40
41
   * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
   * MAX6692 chips made by Maxim.  These are again similar to the LM86,
   * but they use unsigned temperature values and can report temperatures
   * from 0 to 145 degrees.
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
42
   *
32c82a934   Rainer Birkenmaier   hwmon/lm90: Add s...
43
44
   * This driver also supports the MAX6680 and MAX6681, two other sensor
   * chips made by Maxim. These are quite similar to the other Maxim
a874a10cf   Jean Delvare   hwmon: (lm90) Upd...
45
46
   * chips. The MAX6680 and MAX6681 only differ in the pinout so they can
   * be treated identically.
32c82a934   Rainer Birkenmaier   hwmon/lm90: Add s...
47
   *
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
48
49
50
51
52
   * This driver also supports the MAX6695 and MAX6696, two other sensor
   * chips made by Maxim. These are also quite similar to other Maxim
   * chips, but support three temperature sensors instead of two. MAX6695
   * and MAX6696 only differ in the pinout so they can be treated identically.
   *
5a4e5e6a7   Guenter Roeck   hwmon: (lm90) Add...
53
54
55
56
   * This driver also supports ADT7461 and ADT7461A from Analog Devices as well as
   * NCT1008 from ON Semiconductor. The chips are supported in both compatibility
   * and extended mode. They are mostly compatible with LM90 except for a data
   * format difference for the temperature value registers.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
   *
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
58
59
60
   * This driver also supports the SA56004 from Philips. This device is
   * pin-compatible with the LM86, the ED/EDP parts are also address-compatible.
   *
ae544f64c   Guenter Roeck   hwmon: (lm90) Add...
61
62
63
   * This driver also supports the G781 from GMT. This device is compatible
   * with the ADM1032.
   *
1daaceb26   Wei Ni   hwmon: (lm90) Add...
64
65
66
67
68
   * This driver also supports TMP451 from Texas Instruments. This device is
   * supported in both compatibility and extended mode. It's mostly compatible
   * with ADT7461 except for local temperature low byte register and max
   * conversion rate.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
71
   * Since the LM90 was the first chipset supported by this driver, most
   * comments will refer to this chipset, but are actually general and
   * concern all supported chipsets, unless mentioned otherwise.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
75
76
77
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/jiffies.h>
  #include <linux/i2c.h>
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
78
79
  #include <linux/hwmon.h>
  #include <linux/err.h>
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
80
  #include <linux/mutex.h>
df8d57bf8   Javier Martinez Canillas   hwmon: (lm90) Add...
81
  #include <linux/of_device.h>
0e39e01c9   Jean Delvare   hwmon: Fix unchec...
82
  #include <linux/sysfs.h>
109b1283f   Wei Ni   hwmon: (lm90) Add...
83
  #include <linux/interrupt.h>
3e0f964f2   Wei Ni   hwmon: (lm90) Add...
84
  #include <linux/regulator/consumer.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
87
88
  
  /*
   * Addresses to scan
   * Address is fully defined internally and cannot be changed except for
32c82a934   Rainer Birkenmaier   hwmon/lm90: Add s...
89
   * MAX6659, MAX6680 and MAX6681.
5a4e5e6a7   Guenter Roeck   hwmon: (lm90) Add...
90
91
92
93
   * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, ADT7461A, MAX6649,
   * MAX6657, MAX6658, NCT1008 and W83L771 have address 0x4c.
   * ADM1032-2, ADT7461-2, ADT7461A-2, LM89-1, LM99-1, MAX6646, and NCT1008D
   * have address 0x4d.
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
94
   * MAX6647 has address 0x4e.
13c84951a   Guenter Roeck   hwmon: (lm90) Add...
95
   * MAX6659 can have address 0x4c, 0x4d or 0x4e.
32c82a934   Rainer Birkenmaier   hwmon/lm90: Add s...
96
97
   * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
   * 0x4c, 0x4d or 0x4e.
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
98
   * SA56004 can have address 0x48 through 0x4F.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
   */
25e9c86d5   Mark M. Hoffman   hwmon: normal_i2c...
100
  static const unsigned short normal_i2c[] = {
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
101
102
  	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
  	0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103

13c84951a   Guenter Roeck   hwmon: (lm90) Add...
104
  enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
1daaceb26   Wei Ni   hwmon: (lm90) Add...
105
  	max6646, w83l771, max6696, sa56004, g781, tmp451 };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
  
  /*
   * The LM90 registers
   */
  
  #define LM90_REG_R_MAN_ID		0xFE
  #define LM90_REG_R_CHIP_ID		0xFF
  #define LM90_REG_R_CONFIG1		0x03
  #define LM90_REG_W_CONFIG1		0x09
  #define LM90_REG_R_CONFIG2		0xBF
  #define LM90_REG_W_CONFIG2		0xBF
  #define LM90_REG_R_CONVRATE		0x04
  #define LM90_REG_W_CONVRATE		0x0A
  #define LM90_REG_R_STATUS		0x02
  #define LM90_REG_R_LOCAL_TEMP		0x00
  #define LM90_REG_R_LOCAL_HIGH		0x05
  #define LM90_REG_W_LOCAL_HIGH		0x0B
  #define LM90_REG_R_LOCAL_LOW		0x06
  #define LM90_REG_W_LOCAL_LOW		0x0C
  #define LM90_REG_R_LOCAL_CRIT		0x20
  #define LM90_REG_W_LOCAL_CRIT		0x20
  #define LM90_REG_R_REMOTE_TEMPH		0x01
  #define LM90_REG_R_REMOTE_TEMPL		0x10
  #define LM90_REG_R_REMOTE_OFFSH		0x11
  #define LM90_REG_W_REMOTE_OFFSH		0x11
  #define LM90_REG_R_REMOTE_OFFSL		0x12
  #define LM90_REG_W_REMOTE_OFFSL		0x12
  #define LM90_REG_R_REMOTE_HIGHH		0x07
  #define LM90_REG_W_REMOTE_HIGHH		0x0D
  #define LM90_REG_R_REMOTE_HIGHL		0x13
  #define LM90_REG_W_REMOTE_HIGHL		0x13
  #define LM90_REG_R_REMOTE_LOWH		0x08
  #define LM90_REG_W_REMOTE_LOWH		0x0E
  #define LM90_REG_R_REMOTE_LOWL		0x14
  #define LM90_REG_W_REMOTE_LOWL		0x14
  #define LM90_REG_R_REMOTE_CRIT		0x19
  #define LM90_REG_W_REMOTE_CRIT		0x19
  #define LM90_REG_R_TCRIT_HYST		0x21
  #define LM90_REG_W_TCRIT_HYST		0x21
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
145
  /* MAX6646/6647/6649/6657/6658/6659/6695/6696 registers */
f65e17086   Jean Delvare   hwmon: (lm90) Sup...
146
147
  
  #define MAX6657_REG_R_LOCAL_TEMPL	0x11
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
148
  #define MAX6696_REG_R_STATUS2		0x12
6948708dd   Guenter Roeck   hwmon: (lm90) Add...
149
150
151
152
  #define MAX6659_REG_R_REMOTE_EMERG	0x16
  #define MAX6659_REG_W_REMOTE_EMERG	0x16
  #define MAX6659_REG_R_LOCAL_EMERG	0x17
  #define MAX6659_REG_W_LOCAL_EMERG	0x17
f65e17086   Jean Delvare   hwmon: (lm90) Sup...
153

2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
154
155
156
  /*  SA56004 registers */
  
  #define SA56004_REG_R_LOCAL_TEMPL 0x22
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
157
  #define LM90_MAX_CONVRATE_MS	16000	/* Maximum conversion rate in ms */
1daaceb26   Wei Ni   hwmon: (lm90) Add...
158
159
  /* TMP451 registers */
  #define TMP451_REG_R_LOCAL_TEMPL	0x15
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  /*
23b2d4778   Nate Case   hwmon: (lm90) Sup...
161
162
   * Device flags
   */
88073bb1b   Guenter Roeck   hwmon: (lm90) Int...
163
164
165
  #define LM90_FLAG_ADT7461_EXT	(1 << 0) /* ADT7461 extended mode	*/
  /* Device features */
  #define LM90_HAVE_OFFSET	(1 << 1) /* temperature offset register	*/
88073bb1b   Guenter Roeck   hwmon: (lm90) Int...
166
  #define LM90_HAVE_REM_LIMIT_EXT	(1 << 3) /* extended remote limit	*/
6948708dd   Guenter Roeck   hwmon: (lm90) Add...
167
  #define LM90_HAVE_EMERGENCY	(1 << 4) /* 3rd upper (emergency) limit	*/
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
168
169
  #define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm		*/
  #define LM90_HAVE_TEMP3		(1 << 6) /* 3rd temperature sensor	*/
1179324c4   Guenter Roeck   hwmon: (lm90) Int...
170
  #define LM90_HAVE_BROKEN_ALERT	(1 << 7) /* Broken alert		*/
62456189f   Boyang Yu   hwmon: (lm90) Fix...
171
  #define LM90_PAUSE_FOR_CONFIG	(1 << 8) /* Pause conversion for config	*/
23b2d4778   Nate Case   hwmon: (lm90) Sup...
172

072de4969   Wei Ni   hwmon: (lm90) Def...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  /* LM90 status */
  #define LM90_STATUS_LTHRM	(1 << 0) /* local THERM limit tripped */
  #define LM90_STATUS_RTHRM	(1 << 1) /* remote THERM limit tripped */
  #define LM90_STATUS_ROPEN	(1 << 2) /* remote is an open circuit */
  #define LM90_STATUS_RLOW	(1 << 3) /* remote low temp limit tripped */
  #define LM90_STATUS_RHIGH	(1 << 4) /* remote high temp limit tripped */
  #define LM90_STATUS_LLOW	(1 << 5) /* local low temp limit tripped */
  #define LM90_STATUS_LHIGH	(1 << 6) /* local high temp limit tripped */
  
  #define MAX6696_STATUS2_R2THRM	(1 << 1) /* remote2 THERM limit tripped */
  #define MAX6696_STATUS2_R2OPEN	(1 << 2) /* remote2 is an open circuit */
  #define MAX6696_STATUS2_R2LOW	(1 << 3) /* remote2 low temp limit tripped */
  #define MAX6696_STATUS2_R2HIGH	(1 << 4) /* remote2 high temp limit tripped */
  #define MAX6696_STATUS2_ROT2	(1 << 5) /* remote emergency limit tripped */
  #define MAX6696_STATUS2_R2OT2	(1 << 6) /* remote2 emergency limit tripped */
  #define MAX6696_STATUS2_LOT2	(1 << 7) /* local emergency limit tripped */
23b2d4778   Nate Case   hwmon: (lm90) Sup...
189
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
191
   * Driver data (common to all clients)
   */
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
192
193
194
  static const struct i2c_device_id lm90_id[] = {
  	{ "adm1032", adm1032 },
  	{ "adt7461", adt7461 },
5a4e5e6a7   Guenter Roeck   hwmon: (lm90) Add...
195
  	{ "adt7461a", adt7461 },
ae544f64c   Guenter Roeck   hwmon: (lm90) Add...
196
  	{ "g781", g781 },
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
197
198
  	{ "lm90", lm90 },
  	{ "lm86", lm86 },
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
199
200
  	{ "lm89", lm86 },
  	{ "lm99", lm99 },
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
201
202
203
  	{ "max6646", max6646 },
  	{ "max6647", max6646 },
  	{ "max6649", max6646 },
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
204
205
  	{ "max6657", max6657 },
  	{ "max6658", max6657 },
13c84951a   Guenter Roeck   hwmon: (lm90) Add...
206
  	{ "max6659", max6659 },
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
207
208
  	{ "max6680", max6680 },
  	{ "max6681", max6680 },
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
209
210
  	{ "max6695", max6696 },
  	{ "max6696", max6696 },
5a4e5e6a7   Guenter Roeck   hwmon: (lm90) Add...
211
  	{ "nct1008", adt7461 },
6771ea1ff   Jean Delvare   hwmon: (lm90) Add...
212
  	{ "w83l771", w83l771 },
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
213
  	{ "sa56004", sa56004 },
1daaceb26   Wei Ni   hwmon: (lm90) Add...
214
  	{ "tmp451", tmp451 },
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
215
216
217
  	{ }
  };
  MODULE_DEVICE_TABLE(i2c, lm90_id);
787afaa30   Guenter Roeck   hwmon: (lm90) Fix...
218
  static const struct of_device_id __maybe_unused lm90_of_match[] = {
df8d57bf8   Javier Martinez Canillas   hwmon: (lm90) Add...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  	{
  		.compatible = "adi,adm1032",
  		.data = (void *)adm1032
  	},
  	{
  		.compatible = "adi,adt7461",
  		.data = (void *)adt7461
  	},
  	{
  		.compatible = "adi,adt7461a",
  		.data = (void *)adt7461
  	},
  	{
  		.compatible = "gmt,g781",
  		.data = (void *)g781
  	},
  	{
  		.compatible = "national,lm90",
  		.data = (void *)lm90
  	},
  	{
  		.compatible = "national,lm86",
  		.data = (void *)lm86
  	},
  	{
  		.compatible = "national,lm89",
  		.data = (void *)lm86
  	},
  	{
  		.compatible = "national,lm99",
  		.data = (void *)lm99
  	},
  	{
  		.compatible = "dallas,max6646",
  		.data = (void *)max6646
  	},
  	{
  		.compatible = "dallas,max6647",
  		.data = (void *)max6646
  	},
  	{
  		.compatible = "dallas,max6649",
  		.data = (void *)max6646
  	},
  	{
  		.compatible = "dallas,max6657",
  		.data = (void *)max6657
  	},
  	{
  		.compatible = "dallas,max6658",
  		.data = (void *)max6657
  	},
  	{
  		.compatible = "dallas,max6659",
  		.data = (void *)max6659
  	},
  	{
  		.compatible = "dallas,max6680",
  		.data = (void *)max6680
  	},
  	{
  		.compatible = "dallas,max6681",
  		.data = (void *)max6680
  	},
  	{
  		.compatible = "dallas,max6695",
  		.data = (void *)max6696
  	},
  	{
  		.compatible = "dallas,max6696",
  		.data = (void *)max6696
  	},
  	{
  		.compatible = "onnn,nct1008",
  		.data = (void *)adt7461
  	},
  	{
  		.compatible = "winbond,w83l771",
  		.data = (void *)w83l771
  	},
  	{
  		.compatible = "nxp,sa56004",
  		.data = (void *)sa56004
  	},
  	{
  		.compatible = "ti,tmp451",
  		.data = (void *)tmp451
  	},
  	{ },
  };
  MODULE_DEVICE_TABLE(of, lm90_of_match);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  /*
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
311
312
313
314
315
316
   * chip type specific parameters
   */
  struct lm90_params {
  	u32 flags;		/* Capabilities */
  	u16 alert_alarms;	/* Which alarm bits trigger ALERT# */
  				/* Upper 8 bits for max6695/96 */
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
317
  	u8 max_convrate;	/* Maximum conversion rate register value */
a095f687f   Jean Delvare   hwmon: (lm90) Sim...
318
  	u8 reg_local_ext;	/* Extended local temp register (optional) */
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
319
320
321
322
  };
  
  static const struct lm90_params lm90_params[] = {
  	[adm1032] = {
1179324c4   Guenter Roeck   hwmon: (lm90) Int...
323
324
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
  		  | LM90_HAVE_BROKEN_ALERT,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
325
  		.alert_alarms = 0x7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
326
  		.max_convrate = 10,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
327
328
  	},
  	[adt7461] = {
1179324c4   Guenter Roeck   hwmon: (lm90) Int...
329
330
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
  		  | LM90_HAVE_BROKEN_ALERT,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
331
  		.alert_alarms = 0x7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
332
  		.max_convrate = 10,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
333
  	},
ae544f64c   Guenter Roeck   hwmon: (lm90) Add...
334
335
336
337
338
339
  	[g781] = {
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
  		  | LM90_HAVE_BROKEN_ALERT,
  		.alert_alarms = 0x7c,
  		.max_convrate = 8,
  	},
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
340
341
342
  	[lm86] = {
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
  		.alert_alarms = 0x7b,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
343
  		.max_convrate = 9,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
344
345
346
347
  	},
  	[lm90] = {
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
  		.alert_alarms = 0x7b,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
348
  		.max_convrate = 9,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
349
350
351
352
  	},
  	[lm99] = {
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
  		.alert_alarms = 0x7b,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
353
  		.max_convrate = 9,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
354
355
  	},
  	[max6646] = {
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
356
  		.alert_alarms = 0x7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
357
  		.max_convrate = 6,
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
358
  		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
359
360
  	},
  	[max6657] = {
62456189f   Boyang Yu   hwmon: (lm90) Fix...
361
  		.flags = LM90_PAUSE_FOR_CONFIG,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
362
  		.alert_alarms = 0x7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
363
  		.max_convrate = 8,
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
364
  		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
365
366
  	},
  	[max6659] = {
a095f687f   Jean Delvare   hwmon: (lm90) Sim...
367
  		.flags = LM90_HAVE_EMERGENCY,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
368
  		.alert_alarms = 0x7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
369
  		.max_convrate = 8,
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
370
  		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
371
372
373
374
  	},
  	[max6680] = {
  		.flags = LM90_HAVE_OFFSET,
  		.alert_alarms = 0x7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
375
  		.max_convrate = 7,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
376
377
  	},
  	[max6696] = {
a095f687f   Jean Delvare   hwmon: (lm90) Sim...
378
  		.flags = LM90_HAVE_EMERGENCY
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
379
  		  | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3,
e41fae2b1   Guenter Roeck   hwmon: (lm90) Fix...
380
  		.alert_alarms = 0x1c7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
381
  		.max_convrate = 6,
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
382
  		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
383
384
385
386
  	},
  	[w83l771] = {
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
  		.alert_alarms = 0x7c,
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
387
  		.max_convrate = 8,
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
388
  	},
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
389
  	[sa56004] = {
a095f687f   Jean Delvare   hwmon: (lm90) Sim...
390
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
391
392
393
394
  		.alert_alarms = 0x7b,
  		.max_convrate = 9,
  		.reg_local_ext = SA56004_REG_R_LOCAL_TEMPL,
  	},
1daaceb26   Wei Ni   hwmon: (lm90) Add...
395
396
397
398
399
400
  	[tmp451] = {
  		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
  		  | LM90_HAVE_BROKEN_ALERT,
  		.alert_alarms = 0x7c,
  		.max_convrate = 9,
  		.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
401
  	},
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
402
403
404
  };
  
  /*
40465d942   Wei Ni   hwmon: (lm90) Use...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
   * TEMP8 register index
   */
  enum lm90_temp8_reg_index {
  	LOCAL_LOW = 0,
  	LOCAL_HIGH,
  	LOCAL_CRIT,
  	REMOTE_CRIT,
  	LOCAL_EMERG,	/* max6659 and max6695/96 */
  	REMOTE_EMERG,	/* max6659 and max6695/96 */
  	REMOTE2_CRIT,	/* max6695/96 only */
  	REMOTE2_EMERG,	/* max6695/96 only */
  	TEMP8_REG_NUM
  };
  
  /*
   * TEMP11 register index
   */
  enum lm90_temp11_reg_index {
  	REMOTE_TEMP = 0,
  	REMOTE_LOW,
  	REMOTE_HIGH,
  	REMOTE_OFFSET,	/* except max6646, max6657/58/59, and max6695/96 */
  	LOCAL_TEMP,
  	REMOTE2_TEMP,	/* max6695/96 only */
  	REMOTE2_LOW,	/* max6695/96 only */
  	REMOTE2_HIGH,	/* max6695/96 only */
  	TEMP11_REG_NUM
  };
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
436
437
438
   * Client data (each client gets its own)
   */
  
  struct lm90_data {
1de8b250f   Guenter Roeck   hwmon: (lm90) Con...
439
  	struct i2c_client *client;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
440
441
442
443
  	u32 channel_config[4];
  	struct hwmon_channel_info temp_info;
  	const struct hwmon_channel_info *info[3];
  	struct hwmon_chip_info chip;
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
444
  	struct mutex update_lock;
2f83ab77b   Guenter Roeck   hwmon: (lm90) Use...
445
  	bool valid;		/* true if register values are valid */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
447
  	unsigned long last_updated; /* in jiffies */
  	int kind;
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
448
  	u32 flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449

38bab98a8   Wolfram Sang   hwmon: (lm90) use...
450
  	unsigned int update_interval; /* in milliseconds */
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
451

b849e5d18   Guenter Roeck   hwmon: (lm90) Cac...
452
  	u8 config;		/* Current configuration register value */
952383641   Jean Delvare   hwmon: (lm90) Res...
453
  	u8 config_orig;		/* Original configuration register value */
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
454
  	u8 convrate_orig;	/* Original conversion rate register value */
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
455
456
  	u16 alert_alarms;	/* Which alarm bits trigger ALERT# */
  				/* Upper 8 bits for max6695/96 */
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
457
  	u8 max_convrate;	/* Maximum conversion rate */
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
458
  	u8 reg_local_ext;	/* local extension register offset */
952383641   Jean Delvare   hwmon: (lm90) Res...
459

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  	/* registers values */
40465d942   Wei Ni   hwmon: (lm90) Use...
461
462
  	s8 temp8[TEMP8_REG_NUM];
  	s16 temp11[TEMP11_REG_NUM];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  	u8 temp_hyst;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
464
  	u16 alarms; /* bitvector (upper 8 bits for max6695/96) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
  };
  
  /*
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
   * Support functions
   */
  
  /*
   * The ADM1032 supports PEC but not on write byte transactions, so we need
   * to explicitly ask for a transaction without PEC.
   */
  static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
  {
  	return i2c_smbus_xfer(client->adapter, client->addr,
  			      client->flags & ~I2C_CLIENT_PEC,
  			      I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
  }
  
  /*
   * It is assumed that client->update_lock is held (unless we are in
   * detection or initialization steps). This matters when PEC is enabled,
   * because we don't want the address pointer to change between the write
   * byte and the read byte transactions.
   */
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
488
  static int lm90_read_reg(struct i2c_client *client, u8 reg)
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
489
490
491
492
493
494
495
496
497
  {
  	int err;
  
  	if (client->flags & I2C_CLIENT_PEC) {
  		err = adm1032_write_byte(client, reg);
  		if (err >= 0)
  			err = i2c_smbus_read_byte(client);
  	} else
  		err = i2c_smbus_read_byte_data(client, reg);
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
498
  	return err;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
499
  }
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
500
  static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl)
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
501
  {
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
502
  	int oldh, newh, l;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
503
504
505
506
  
  	/*
  	 * There is a trick here. We have to read two registers to have the
  	 * sensor temperature, but we have to beware a conversion could occur
25985edce   Lucas De Marchi   Fix common misspe...
507
  	 * between the readings. The datasheet says we should either use
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
508
509
510
511
512
513
514
515
516
  	 * the one-shot conversion register, which we don't want to do
  	 * (disables hardware monitoring) or monitor the busy bit, which is
  	 * impossible (we can't read the values and monitor that bit at the
  	 * exact same time). So the solution used here is to read the high
  	 * byte once, then the low byte, then the high byte again. If the new
  	 * high byte matches the old one, then we have a valid reading. Else
  	 * we have to read the low byte again, and now we believe we have a
  	 * correct reading.
  	 */
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
517
518
519
520
521
522
523
524
525
  	oldh = lm90_read_reg(client, regh);
  	if (oldh < 0)
  		return oldh;
  	l = lm90_read_reg(client, regl);
  	if (l < 0)
  		return l;
  	newh = lm90_read_reg(client, regh);
  	if (newh < 0)
  		return newh;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
526
  	if (oldh != newh) {
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
527
528
529
  		l = lm90_read_reg(client, regl);
  		if (l < 0)
  			return l;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
530
  	}
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
531
  	return (newh << 8) | l;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
532
  }
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
  static int lm90_update_confreg(struct lm90_data *data, u8 config)
  {
  	if (data->config != config) {
  		int err;
  
  		err = i2c_smbus_write_byte_data(data->client,
  						LM90_REG_W_CONFIG1,
  						config);
  		if (err)
  			return err;
  		data->config = config;
  	}
  	return 0;
  }
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
547
548
549
550
551
552
553
554
  /*
   * client->update_lock must be held when calling this function (unless we are
   * in detection or initialization steps), and while a remote channel other
   * than channel 0 is selected. Also, calling code must make sure to re-select
   * external channel 0 before releasing the lock. This is necessary because
   * various registers have different meanings as a result of selecting a
   * non-default remote channel.
   */
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
555
  static int lm90_select_remote_channel(struct lm90_data *data, int channel)
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
556
  {
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
557
  	int err = 0;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
558
  	if (data->kind == max6696) {
b849e5d18   Guenter Roeck   hwmon: (lm90) Cac...
559
  		u8 config = data->config & ~0x08;
b849e5d18   Guenter Roeck   hwmon: (lm90) Cac...
560

15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
561
562
  		if (channel)
  			config |= 0x08;
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
563
  		err = lm90_update_confreg(data, config);
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
564
  	}
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
565
  	return err;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
566
  }
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
567
  static int lm90_write_convrate(struct lm90_data *data, int val)
62456189f   Boyang Yu   hwmon: (lm90) Fix...
568
  {
b849e5d18   Guenter Roeck   hwmon: (lm90) Cac...
569
  	u8 config = data->config;
62456189f   Boyang Yu   hwmon: (lm90) Fix...
570
  	int err;
62456189f   Boyang Yu   hwmon: (lm90) Fix...
571
572
573
  
  	/* Save config and pause conversion */
  	if (data->flags & LM90_PAUSE_FOR_CONFIG) {
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
574
575
576
  		err = lm90_update_confreg(data, config | 0x40);
  		if (err < 0)
  			return err;
62456189f   Boyang Yu   hwmon: (lm90) Fix...
577
578
579
  	}
  
  	/* Set conv rate */
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
580
  	err = i2c_smbus_write_byte_data(data->client, LM90_REG_W_CONVRATE, val);
62456189f   Boyang Yu   hwmon: (lm90) Fix...
581
582
  
  	/* Revert change to config */
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
583
  	lm90_update_confreg(data, config);
62456189f   Boyang Yu   hwmon: (lm90) Fix...
584
585
586
  
  	return err;
  }
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
587
588
589
590
591
  /*
   * Set conversion rate.
   * client->update_lock must be held when calling this function (unless we are
   * in detection or initialization steps).
   */
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
592
593
  static int lm90_set_convrate(struct i2c_client *client, struct lm90_data *data,
  			     unsigned int interval)
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
594
  {
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
595
  	unsigned int update_interval;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
596
  	int i, err;
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
597
598
599
600
601
602
603
604
605
  
  	/* Shift calculations to avoid rounding errors */
  	interval <<= 6;
  
  	/* find the nearest update rate */
  	for (i = 0, update_interval = LM90_MAX_CONVRATE_MS << 6;
  	     i < data->max_convrate; i++, update_interval >>= 1)
  		if (interval >= update_interval * 3 / 4)
  			break;
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
606
  	err = lm90_write_convrate(data, i);
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
607
  	data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
608
  	return err;
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
609
  }
10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  static int lm90_update_limits(struct device *dev)
  {
  	struct lm90_data *data = dev_get_drvdata(dev);
  	struct i2c_client *client = data->client;
  	int val;
  
  	val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT);
  	if (val < 0)
  		return val;
  	data->temp8[LOCAL_CRIT] = val;
  
  	val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
  	if (val < 0)
  		return val;
  	data->temp8[REMOTE_CRIT] = val;
  
  	val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST);
  	if (val < 0)
  		return val;
  	data->temp_hyst = val;
be9d6374a   Guenter Roeck   hwmon: (lm90) Add...
630
  	val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH);
10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  	if (val < 0)
  		return val;
  	data->temp11[REMOTE_LOW] = val << 8;
  
  	if (data->flags & LM90_HAVE_REM_LIMIT_EXT) {
  		val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL);
  		if (val < 0)
  			return val;
  		data->temp11[REMOTE_LOW] |= val;
  	}
  
  	val = lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH);
  	if (val < 0)
  		return val;
  	data->temp11[REMOTE_HIGH] = val << 8;
  
  	if (data->flags & LM90_HAVE_REM_LIMIT_EXT) {
  		val = lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL);
  		if (val < 0)
  			return val;
  		data->temp11[REMOTE_HIGH] |= val;
  	}
  
  	if (data->flags & LM90_HAVE_OFFSET) {
  		val = lm90_read16(client, LM90_REG_R_REMOTE_OFFSH,
  				  LM90_REG_R_REMOTE_OFFSL);
  		if (val < 0)
  			return val;
  		data->temp11[REMOTE_OFFSET] = val;
  	}
  
  	if (data->flags & LM90_HAVE_EMERGENCY) {
  		val = lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG);
  		if (val < 0)
  			return val;
  		data->temp8[LOCAL_EMERG] = val;
  
  		val = lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG);
  		if (val < 0)
  			return val;
  		data->temp8[REMOTE_EMERG] = val;
  	}
  
  	if (data->kind == max6696) {
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
675
  		val = lm90_select_remote_channel(data, 1);
10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
  		if (val < 0)
  			return val;
  
  		val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
  		if (val < 0)
  			return val;
  		data->temp8[REMOTE2_CRIT] = val;
  
  		val = lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG);
  		if (val < 0)
  			return val;
  		data->temp8[REMOTE2_EMERG] = val;
  
  		val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH);
  		if (val < 0)
  			return val;
  		data->temp11[REMOTE2_LOW] = val << 8;
  
  		val = lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH);
  		if (val < 0)
  			return val;
  		data->temp11[REMOTE2_HIGH] = val << 8;
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
698
  		lm90_select_remote_channel(data, 0);
10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
699
700
701
702
  	}
  
  	return 0;
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
703
  static int lm90_update_device(struct device *dev)
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
704
  {
1de8b250f   Guenter Roeck   hwmon: (lm90) Con...
705
706
  	struct lm90_data *data = dev_get_drvdata(dev);
  	struct i2c_client *client = data->client;
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
707
  	unsigned long next_update;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
708
  	int val;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
709

10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
710
711
712
  	if (!data->valid) {
  		val = lm90_update_limits(dev);
  		if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
713
  			return val;
10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
714
  	}
78c2c2fe5   Jean Delvare   hwmon: (lm90) Dro...
715
716
  	next_update = data->last_updated +
  		      msecs_to_jiffies(data->update_interval);
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
717
  	if (time_after(jiffies, next_update) || !data->valid) {
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
718
719
  		dev_dbg(&client->dev, "Updating lm90 data.
  ");
10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
720

2f83ab77b   Guenter Roeck   hwmon: (lm90) Use...
721
  		data->valid = false;
10bfef47b   Guenter Roeck   hwmon: (lm90) Rea...
722

37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
723
724
  		val = lm90_read_reg(client, LM90_REG_R_LOCAL_LOW);
  		if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
725
  			return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
726
727
728
729
  		data->temp8[LOCAL_LOW] = val;
  
  		val = lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH);
  		if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
730
  			return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
731
  		data->temp8[LOCAL_HIGH] = val;
a095f687f   Jean Delvare   hwmon: (lm90) Sim...
732
  		if (data->reg_local_ext) {
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
733
734
735
  			val = lm90_read16(client, LM90_REG_R_LOCAL_TEMP,
  					  data->reg_local_ext);
  			if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
736
  				return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
737
  			data->temp11[LOCAL_TEMP] = val;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
738
  		} else {
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
739
740
  			val = lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP);
  			if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
741
  				return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
742
  			data->temp11[LOCAL_TEMP] = val << 8;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
743
  		}
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
744
745
746
  		val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
  				  LM90_REG_R_REMOTE_TEMPL);
  		if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
747
  			return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
748
  		data->temp11[REMOTE_TEMP] = val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
749
750
  		val = lm90_read_reg(client, LM90_REG_R_STATUS);
  		if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
751
  			return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
752
  		data->alarms = val;	/* lower 8 bit of alarms */
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
753
754
  
  		if (data->kind == max6696) {
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
755
  			val = lm90_select_remote_channel(data, 1);
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
756
  			if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
757
  				return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
758

37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
759
760
  			val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
  					  LM90_REG_R_REMOTE_TEMPL);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
761
  			if (val < 0) {
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
762
  				lm90_select_remote_channel(data, 0);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
763
764
  				return val;
  			}
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
765
  			data->temp11[REMOTE2_TEMP] = val;
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
766
  			lm90_select_remote_channel(data, 0);
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
767

37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
768
769
  			val = lm90_read_reg(client, MAX6696_REG_R_STATUS2);
  			if (val < 0)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
770
  				return val;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
771
  			data->alarms |= val << 8;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
772
  		}
f36ffeab0   Guenter Roeck   hwmon: (lm90) Fix...
773
774
775
776
  		/*
  		 * Re-enable ALERT# output if it was originally enabled and
  		 * relevant alarms are all clear
  		 */
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
777
778
  		if (!(data->config_orig & 0x80) &&
  		    !(data->alarms & data->alert_alarms)) {
b849e5d18   Guenter Roeck   hwmon: (lm90) Cac...
779
  			if (data->config & 0x80) {
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
780
781
  				dev_dbg(&client->dev, "Re-enabling ALERT#
  ");
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
782
  				lm90_update_confreg(data, data->config & ~0x80);
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
783
784
785
786
  			}
  		}
  
  		data->last_updated = jiffies;
2f83ab77b   Guenter Roeck   hwmon: (lm90) Use...
787
  		data->valid = true;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
788
  	}
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
789
  	return 0;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
790
791
792
  }
  
  /*
cea50fe2f   Nate Case   hwmon: (lm90) Con...
793
794
795
796
   * Conversions
   * For local temperatures and limits, critical limits and the hysteresis
   * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius.
   * For remote temperatures and limits, it uses signed 11-bit values with
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
797
798
   * LSB = 0.125 degree Celsius, left-justified in 16-bit registers.  Some
   * Maxim chips use unsigned values.
cea50fe2f   Nate Case   hwmon: (lm90) Con...
799
   */
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
800
  static inline int temp_from_s8(s8 val)
cea50fe2f   Nate Case   hwmon: (lm90) Con...
801
802
803
  {
  	return val * 1000;
  }
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
804
805
806
807
  static inline int temp_from_u8(u8 val)
  {
  	return val * 1000;
  }
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
808
  static inline int temp_from_s16(s16 val)
cea50fe2f   Nate Case   hwmon: (lm90) Con...
809
810
811
  {
  	return val / 32 * 125;
  }
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
812
813
814
815
  static inline int temp_from_u16(u16 val)
  {
  	return val / 32 * 125;
  }
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
816
  static s8 temp_to_s8(long val)
cea50fe2f   Nate Case   hwmon: (lm90) Con...
817
818
819
820
821
822
823
824
825
  {
  	if (val <= -128000)
  		return -128;
  	if (val >= 127000)
  		return 127;
  	if (val < 0)
  		return (val - 500) / 1000;
  	return (val + 500) / 1000;
  }
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
826
827
828
829
830
831
832
833
  static u8 temp_to_u8(long val)
  {
  	if (val <= 0)
  		return 0;
  	if (val >= 255000)
  		return 255;
  	return (val + 500) / 1000;
  }
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
834
  static s16 temp_to_s16(long val)
cea50fe2f   Nate Case   hwmon: (lm90) Con...
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
  {
  	if (val <= -128000)
  		return 0x8000;
  	if (val >= 127875)
  		return 0x7FE0;
  	if (val < 0)
  		return (val - 62) / 125 * 32;
  	return (val + 62) / 125 * 32;
  }
  
  static u8 hyst_to_reg(long val)
  {
  	if (val <= 0)
  		return 0;
  	if (val >= 30500)
  		return 31;
  	return (val + 500) / 1000;
  }
  
  /*
23b2d4778   Nate Case   hwmon: (lm90) Sup...
855
856
857
858
859
860
   * ADT7461 in compatibility mode is almost identical to LM90 except that
   * attempts to write values that are outside the range 0 < temp < 127 are
   * treated as the boundary value.
   *
   * ADT7461 in "extended mode" operation uses unsigned integers offset by
   * 64 (e.g., 0 -> -64 degC).  The range is restricted to -64..191 degC.
cea50fe2f   Nate Case   hwmon: (lm90) Con...
861
   */
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
862
  static inline int temp_from_u8_adt7461(struct lm90_data *data, u8 val)
cea50fe2f   Nate Case   hwmon: (lm90) Con...
863
  {
23b2d4778   Nate Case   hwmon: (lm90) Sup...
864
865
  	if (data->flags & LM90_FLAG_ADT7461_EXT)
  		return (val - 64) * 1000;
589f707c7   Guenter Roeck   hwmon: (lm90) Dro...
866
  	return temp_from_s8(val);
cea50fe2f   Nate Case   hwmon: (lm90) Con...
867
  }
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
868
  static inline int temp_from_u16_adt7461(struct lm90_data *data, u16 val)
cea50fe2f   Nate Case   hwmon: (lm90) Con...
869
  {
23b2d4778   Nate Case   hwmon: (lm90) Sup...
870
871
  	if (data->flags & LM90_FLAG_ADT7461_EXT)
  		return (val - 0x4000) / 64 * 250;
589f707c7   Guenter Roeck   hwmon: (lm90) Dro...
872
  	return temp_from_s16(val);
23b2d4778   Nate Case   hwmon: (lm90) Sup...
873
  }
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
874
  static u8 temp_to_u8_adt7461(struct lm90_data *data, long val)
23b2d4778   Nate Case   hwmon: (lm90) Sup...
875
876
877
878
879
880
881
  {
  	if (data->flags & LM90_FLAG_ADT7461_EXT) {
  		if (val <= -64000)
  			return 0;
  		if (val >= 191000)
  			return 0xFF;
  		return (val + 500 + 64000) / 1000;
23b2d4778   Nate Case   hwmon: (lm90) Sup...
882
  	}
589f707c7   Guenter Roeck   hwmon: (lm90) Dro...
883
884
885
886
887
  	if (val <= 0)
  		return 0;
  	if (val >= 127000)
  		return 127;
  	return (val + 500) / 1000;
23b2d4778   Nate Case   hwmon: (lm90) Sup...
888
  }
9d4d38342   Ben Hutchings   hwmon: (lm90) Ren...
889
  static u16 temp_to_u16_adt7461(struct lm90_data *data, long val)
23b2d4778   Nate Case   hwmon: (lm90) Sup...
890
891
892
893
894
895
896
  {
  	if (data->flags & LM90_FLAG_ADT7461_EXT) {
  		if (val <= -64000)
  			return 0;
  		if (val >= 191750)
  			return 0xFFC0;
  		return (val + 64000 + 125) / 250 * 64;
23b2d4778   Nate Case   hwmon: (lm90) Sup...
897
  	}
589f707c7   Guenter Roeck   hwmon: (lm90) Dro...
898
899
900
901
902
  	if (val <= 0)
  		return 0;
  	if (val >= 127750)
  		return 0x7FC0;
  	return (val + 125) / 250 * 64;
cea50fe2f   Nate Case   hwmon: (lm90) Con...
903
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
904
  /* pec used for ADM1032 only */
e57959a6d   Julia Lawall   hwmon: (lm90) use...
905
  static ssize_t pec_show(struct device *dev, struct device_attribute *dummy,
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
906
  			char *buf)
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
907
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
908
  	struct i2c_client *client = to_i2c_client(dev);
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
909

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
910
911
  	return sprintf(buf, "%d
  ", !!(client->flags & I2C_CLIENT_PEC));
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
912
  }
e57959a6d   Julia Lawall   hwmon: (lm90) use...
913
914
  static ssize_t pec_store(struct device *dev, struct device_attribute *dummy,
  			 const char *buf, size_t count)
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
915
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
916
  	struct i2c_client *client = to_i2c_client(dev);
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
917
918
  	long val;
  	int err;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
919
  	err = kstrtol(buf, 10, &val);
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
920
921
  	if (err < 0)
  		return err;
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
922

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
923
924
925
926
927
928
929
930
931
932
  	switch (val) {
  	case 0:
  		client->flags &= ~I2C_CLIENT_PEC;
  		break;
  	case 1:
  		client->flags |= I2C_CLIENT_PEC;
  		break;
  	default:
  		return -EINVAL;
  	}
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
933

30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
934
  	return count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
935
  }
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
936

e57959a6d   Julia Lawall   hwmon: (lm90) use...
937
  static DEVICE_ATTR_RW(pec);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
938
939
  
  static int lm90_get_temp11(struct lm90_data *data, int index)
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
940
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
941
  	s16 temp11 = data->temp11[index];
23b2d4778   Nate Case   hwmon: (lm90) Sup...
942
  	int temp;
1daaceb26   Wei Ni   hwmon: (lm90) Add...
943
  	if (data->kind == adt7461 || data->kind == tmp451)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
944
  		temp = temp_from_u16_adt7461(data, temp11);
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
945
  	else if (data->kind == max6646)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
946
  		temp = temp_from_u16(temp11);
23b2d4778   Nate Case   hwmon: (lm90) Sup...
947
  	else
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
948
  		temp = temp_from_s16(temp11);
23b2d4778   Nate Case   hwmon: (lm90) Sup...
949

97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
950
  	/* +16 degrees offset for temp2 for the LM99 */
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
951
  	if (data->kind == lm99 && index <= 2)
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
952
  		temp += 16000;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
953
  	return temp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954
  }
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
955

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
956
  static int lm90_set_temp11(struct lm90_data *data, int index, long val)
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
957
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
958
  	static struct reg {
96512861c   Guenter Roeck   hwmon: (lm90) Sim...
959
960
  		u8 high;
  		u8 low;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
961
962
963
964
965
966
  	} reg[] = {
  	[REMOTE_LOW] = { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL },
  	[REMOTE_HIGH] = { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL },
  	[REMOTE_OFFSET] = { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL },
  	[REMOTE2_LOW] = { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL },
  	[REMOTE2_HIGH] = { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL }
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
967
  	};
1de8b250f   Guenter Roeck   hwmon: (lm90) Con...
968
  	struct i2c_client *client = data->client;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
969
  	struct reg *regp = &reg[index];
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
970
  	int err;
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
971
  	/* +16 degrees offset for temp2 for the LM99 */
96512861c   Guenter Roeck   hwmon: (lm90) Sim...
972
  	if (data->kind == lm99 && index <= 2)
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
973
  		val -= 16000;
1daaceb26   Wei Ni   hwmon: (lm90) Add...
974
  	if (data->kind == adt7461 || data->kind == tmp451)
96512861c   Guenter Roeck   hwmon: (lm90) Sim...
975
  		data->temp11[index] = temp_to_u16_adt7461(data, val);
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
976
  	else if (data->kind == max6646)
96512861c   Guenter Roeck   hwmon: (lm90) Sim...
977
  		data->temp11[index] = temp_to_u8(val) << 8;
88073bb1b   Guenter Roeck   hwmon: (lm90) Int...
978
  	else if (data->flags & LM90_HAVE_REM_LIMIT_EXT)
96512861c   Guenter Roeck   hwmon: (lm90) Sim...
979
  		data->temp11[index] = temp_to_s16(val);
88073bb1b   Guenter Roeck   hwmon: (lm90) Int...
980
  	else
96512861c   Guenter Roeck   hwmon: (lm90) Sim...
981
  		data->temp11[index] = temp_to_s8(val) << 8;
5f502a834   Jean Delvare   hwmon: (lm90) Don...
982

7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
983
  	lm90_select_remote_channel(data, index >= 3);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
984
  	err = i2c_smbus_write_byte_data(client, regp->high,
96512861c   Guenter Roeck   hwmon: (lm90) Sim...
985
  				  data->temp11[index] >> 8);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
986
987
  	if (err < 0)
  		return err;
88073bb1b   Guenter Roeck   hwmon: (lm90) Int...
988
  	if (data->flags & LM90_HAVE_REM_LIMIT_EXT)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
989
990
  		err = i2c_smbus_write_byte_data(client, regp->low,
  						data->temp11[index] & 0xff);
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
991

7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
992
  	lm90_select_remote_channel(data, 0);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
993
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
994
  }
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
995

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
996
  static int lm90_get_temp8(struct lm90_data *data, int index)
30d7394b1   Jean Delvare   [PATCH] I2C: lm90...
997
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
998
  	s8 temp8 = data->temp8[index];
23b2d4778   Nate Case   hwmon: (lm90) Sup...
999
  	int temp;
1daaceb26   Wei Ni   hwmon: (lm90) Add...
1000
  	if (data->kind == adt7461 || data->kind == tmp451)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1001
  		temp = temp_from_u8_adt7461(data, temp8);
ec38fa2b3   Jean Delvare   hwmon: (lm90) Fix...
1002
  	else if (data->kind == max6646)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1003
  		temp = temp_from_u8(temp8);
23b2d4778   Nate Case   hwmon: (lm90) Sup...
1004
  	else
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1005
  		temp = temp_from_s8(temp8);
23b2d4778   Nate Case   hwmon: (lm90) Sup...
1006

97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
1007
  	/* +16 degrees offset for temp2 for the LM99 */
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1008
  	if (data->kind == lm99 && index == 3)
97ae60bb3   Jean Delvare   hwmon: (lm90) Add...
1009
  		temp += 16000;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1010
  	return temp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1013
  static int lm90_set_temp8(struct lm90_data *data, int index, long val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1014
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
  	static const u8 reg[TEMP8_REG_NUM] = {
  		LM90_REG_W_LOCAL_LOW,
  		LM90_REG_W_LOCAL_HIGH,
  		LM90_REG_W_LOCAL_CRIT,
  		LM90_REG_W_REMOTE_CRIT,
  		MAX6659_REG_W_LOCAL_EMERG,
  		MAX6659_REG_W_REMOTE_EMERG,
  		LM90_REG_W_REMOTE_CRIT,
  		MAX6659_REG_W_REMOTE_EMERG,
  	};
1de8b250f   Guenter Roeck   hwmon: (lm90) Con...
1025
  	struct i2c_client *client = data->client;
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
1026
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1027

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1028
1029
1030
  	/* +16 degrees offset for temp2 for the LM99 */
  	if (data->kind == lm99 && index == 3)
  		val -= 16000;
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
1031

1daaceb26   Wei Ni   hwmon: (lm90) Add...
1032
  	if (data->kind == adt7461 || data->kind == tmp451)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1033
  		data->temp8[index] = temp_to_u8_adt7461(data, val);
ec38fa2b3   Jean Delvare   hwmon: (lm90) Fix...
1034
  	else if (data->kind == max6646)
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1035
  		data->temp8[index] = temp_to_u8(val);
ec38fa2b3   Jean Delvare   hwmon: (lm90) Fix...
1036
  	else
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1037
  		data->temp8[index] = temp_to_s8(val);
ec38fa2b3   Jean Delvare   hwmon: (lm90) Fix...
1038

7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
1039
  	lm90_select_remote_channel(data, index >= 6);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1040
  	err = i2c_smbus_write_byte_data(client, reg[index], data->temp8[index]);
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
1041
  	lm90_select_remote_channel(data, 0);
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1042

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1043
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1045
  static int lm90_get_temphyst(struct lm90_data *data, int index)
2d45771e6   Jean Delvare   hwmon: Add indivi...
1046
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1047
  	int temp;
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1048

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1049
1050
1051
1052
1053
1054
  	if (data->kind == adt7461 || data->kind == tmp451)
  		temp = temp_from_u8_adt7461(data, data->temp8[index]);
  	else if (data->kind == max6646)
  		temp = temp_from_u8(data->temp8[index]);
  	else
  		temp = temp_from_s8(data->temp8[index]);
2d45771e6   Jean Delvare   hwmon: Add indivi...
1055

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1056
1057
1058
  	/* +16 degrees offset for temp2 for the LM99 */
  	if (data->kind == lm99 && index == 3)
  		temp += 16000;
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1059

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1060
  	return temp - temp_from_s8(data->temp_hyst);
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1061
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1062
  static int lm90_set_temphyst(struct lm90_data *data, long val)
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1063
  {
1de8b250f   Guenter Roeck   hwmon: (lm90) Con...
1064
  	struct i2c_client *client = data->client;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1065
  	int temp;
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1066
  	int err;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1067
1068
1069
1070
1071
1072
  	if (data->kind == adt7461 || data->kind == tmp451)
  		temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]);
  	else if (data->kind == max6646)
  		temp = temp_from_u8(data->temp8[LOCAL_CRIT]);
  	else
  		temp = temp_from_s8(data->temp8[LOCAL_CRIT]);
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1073

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1074
1075
1076
1077
  	data->temp_hyst = hyst_to_reg(temp - val);
  	err = i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
  					data->temp_hyst);
  	return err;
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1078
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1079
1080
  static const u8 lm90_temp_index[3] = {
  	LOCAL_TEMP, REMOTE_TEMP, REMOTE2_TEMP
0e39e01c9   Jean Delvare   hwmon: Fix unchec...
1081
  };
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1082
1083
  static const u8 lm90_temp_min_index[3] = {
  	LOCAL_LOW, REMOTE_LOW, REMOTE2_LOW
0e39e01c9   Jean Delvare   hwmon: Fix unchec...
1084
  };
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1085
1086
  static const u8 lm90_temp_max_index[3] = {
  	LOCAL_HIGH, REMOTE_HIGH, REMOTE2_HIGH
742192f54   Guenter Roeck   hwmon: (lm90) Cre...
1087
  };
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1088
1089
  static const u8 lm90_temp_crit_index[3] = {
  	LOCAL_CRIT, REMOTE_CRIT, REMOTE2_CRIT
742192f54   Guenter Roeck   hwmon: (lm90) Cre...
1090
  };
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1091
1092
  static const u8 lm90_temp_emerg_index[3] = {
  	LOCAL_EMERG, REMOTE_EMERG, REMOTE2_EMERG
6948708dd   Guenter Roeck   hwmon: (lm90) Add...
1093
  };
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1094
  static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 };
e9572fdd1   Michael Walle   hwmon: (lm90) fix...
1095
  static const u8 lm90_max_alarm_bits[3] = { 6, 4, 12 };
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1096
1097
1098
  static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 };
  static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 };
  static const u8 lm90_fault_bits[3] = { 0, 2, 10 };
6948708dd   Guenter Roeck   hwmon: (lm90) Add...
1099

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1100
1101
1102
1103
  static int lm90_temp_read(struct device *dev, u32 attr, int channel, long *val)
  {
  	struct lm90_data *data = dev_get_drvdata(dev);
  	int err;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1104

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1105
1106
1107
1108
1109
  	mutex_lock(&data->update_lock);
  	err = lm90_update_device(dev);
  	mutex_unlock(&data->update_lock);
  	if (err)
  		return err;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1110

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  	switch (attr) {
  	case hwmon_temp_input:
  		*val = lm90_get_temp11(data, lm90_temp_index[channel]);
  		break;
  	case hwmon_temp_min_alarm:
  		*val = (data->alarms >> lm90_min_alarm_bits[channel]) & 1;
  		break;
  	case hwmon_temp_max_alarm:
  		*val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1;
  		break;
  	case hwmon_temp_crit_alarm:
  		*val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1;
  		break;
  	case hwmon_temp_emergency_alarm:
  		*val = (data->alarms >> lm90_emergency_alarm_bits[channel]) & 1;
  		break;
  	case hwmon_temp_fault:
  		*val = (data->alarms >> lm90_fault_bits[channel]) & 1;
  		break;
  	case hwmon_temp_min:
  		if (channel == 0)
  			*val = lm90_get_temp8(data,
  					      lm90_temp_min_index[channel]);
  		else
  			*val = lm90_get_temp11(data,
  					       lm90_temp_min_index[channel]);
  		break;
  	case hwmon_temp_max:
  		if (channel == 0)
  			*val = lm90_get_temp8(data,
  					      lm90_temp_max_index[channel]);
  		else
  			*val = lm90_get_temp11(data,
  					       lm90_temp_max_index[channel]);
  		break;
  	case hwmon_temp_crit:
  		*val = lm90_get_temp8(data, lm90_temp_crit_index[channel]);
  		break;
  	case hwmon_temp_crit_hyst:
  		*val = lm90_get_temphyst(data, lm90_temp_crit_index[channel]);
  		break;
  	case hwmon_temp_emergency:
  		*val = lm90_get_temp8(data, lm90_temp_emerg_index[channel]);
  		break;
  	case hwmon_temp_emergency_hyst:
  		*val = lm90_get_temphyst(data, lm90_temp_emerg_index[channel]);
  		break;
  	case hwmon_temp_offset:
  		*val = lm90_get_temp11(data, REMOTE_OFFSET);
  		break;
  	default:
  		return -EOPNOTSUPP;
  	}
  	return 0;
  }
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1166

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1167
1168
1169
1170
  static int lm90_temp_write(struct device *dev, u32 attr, int channel, long val)
  {
  	struct lm90_data *data = dev_get_drvdata(dev);
  	int err;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1171

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1172
  	mutex_lock(&data->update_lock);
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1173

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
  	err = lm90_update_device(dev);
  	if (err)
  		goto error;
  
  	switch (attr) {
  	case hwmon_temp_min:
  		if (channel == 0)
  			err = lm90_set_temp8(data,
  					      lm90_temp_min_index[channel],
  					      val);
  		else
  			err = lm90_set_temp11(data,
  					      lm90_temp_min_index[channel],
  					      val);
  		break;
  	case hwmon_temp_max:
  		if (channel == 0)
  			err = lm90_set_temp8(data,
  					     lm90_temp_max_index[channel],
  					     val);
  		else
  			err = lm90_set_temp11(data,
  					      lm90_temp_max_index[channel],
  					      val);
  		break;
  	case hwmon_temp_crit:
  		err = lm90_set_temp8(data, lm90_temp_crit_index[channel], val);
  		break;
  	case hwmon_temp_crit_hyst:
  		err = lm90_set_temphyst(data, val);
  		break;
  	case hwmon_temp_emergency:
  		err = lm90_set_temp8(data, lm90_temp_emerg_index[channel], val);
  		break;
  	case hwmon_temp_offset:
  		err = lm90_set_temp11(data, REMOTE_OFFSET, val);
  		break;
  	default:
  		err = -EOPNOTSUPP;
  		break;
  	}
  error:
  	mutex_unlock(&data->update_lock);
  
  	return err;
  }
  
  static umode_t lm90_temp_is_visible(const void *data, u32 attr, int channel)
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1222
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1223
1224
1225
1226
1227
1228
1229
1230
  	switch (attr) {
  	case hwmon_temp_input:
  	case hwmon_temp_min_alarm:
  	case hwmon_temp_max_alarm:
  	case hwmon_temp_crit_alarm:
  	case hwmon_temp_emergency_alarm:
  	case hwmon_temp_emergency_hyst:
  	case hwmon_temp_fault:
3334851dc   Guenter Roeck   hwmon: (lm90) Rep...
1231
  		return 0444;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1232
1233
1234
1235
1236
  	case hwmon_temp_min:
  	case hwmon_temp_max:
  	case hwmon_temp_crit:
  	case hwmon_temp_emergency:
  	case hwmon_temp_offset:
3334851dc   Guenter Roeck   hwmon: (lm90) Rep...
1237
  		return 0644;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1238
1239
  	case hwmon_temp_crit_hyst:
  		if (channel == 0)
3334851dc   Guenter Roeck   hwmon: (lm90) Rep...
1240
1241
  			return 0644;
  		return 0444;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1242
1243
1244
  	default:
  		return 0;
  	}
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1245
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1246
  static int lm90_chip_read(struct device *dev, u32 attr, int channel, long *val)
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1247
  {
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1248
  	struct lm90_data *data = dev_get_drvdata(dev);
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
1249
  	int err;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1250
1251
1252
1253
  	mutex_lock(&data->update_lock);
  	err = lm90_update_device(dev);
  	mutex_unlock(&data->update_lock);
  	if (err)
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
1254
  		return err;
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1255

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1256
1257
1258
  	switch (attr) {
  	case hwmon_chip_update_interval:
  		*val = data->update_interval;
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1259
  		break;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1260
1261
  	case hwmon_chip_alarms:
  		*val = data->alarms;
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1262
1263
  		break;
  	default:
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1264
  		return -EOPNOTSUPP;
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1265
  	}
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1266
  	return 0;
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1267
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1268
1269
1270
1271
1272
  static int lm90_chip_write(struct device *dev, u32 attr, int channel, long val)
  {
  	struct lm90_data *data = dev_get_drvdata(dev);
  	struct i2c_client *client = data->client;
  	int err;
c3df5806c   Jean Delvare   [PATCH] hwmon: Ad...
1273

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
  	mutex_lock(&data->update_lock);
  
  	err = lm90_update_device(dev);
  	if (err)
  		goto error;
  
  	switch (attr) {
  	case hwmon_chip_update_interval:
  		err = lm90_set_convrate(client, data,
  					clamp_val(val, 0, 100000));
  		break;
  	default:
  		err = -EOPNOTSUPP;
  		break;
  	}
  error:
  	mutex_unlock(&data->update_lock);
  
  	return err;
  }
  
  static umode_t lm90_chip_is_visible(const void *data, u32 attr, int channel)
  {
  	switch (attr) {
  	case hwmon_chip_update_interval:
3334851dc   Guenter Roeck   hwmon: (lm90) Rep...
1299
  		return 0644;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1300
  	case hwmon_chip_alarms:
3334851dc   Guenter Roeck   hwmon: (lm90) Rep...
1301
  		return 0444;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  	default:
  		return 0;
  	}
  }
  
  static int lm90_read(struct device *dev, enum hwmon_sensor_types type,
  		     u32 attr, int channel, long *val)
  {
  	switch (type) {
  	case hwmon_chip:
  		return lm90_chip_read(dev, attr, channel, val);
  	case hwmon_temp:
  		return lm90_temp_read(dev, attr, channel, val);
  	default:
  		return -EOPNOTSUPP;
  	}
  }
  
  static int lm90_write(struct device *dev, enum hwmon_sensor_types type,
  		      u32 attr, int channel, long val)
  {
  	switch (type) {
  	case hwmon_chip:
  		return lm90_chip_write(dev, attr, channel, val);
  	case hwmon_temp:
  		return lm90_temp_write(dev, attr, channel, val);
  	default:
  		return -EOPNOTSUPP;
  	}
  }
  
  static umode_t lm90_is_visible(const void *data, enum hwmon_sensor_types type,
  			       u32 attr, int channel)
  {
  	switch (type) {
  	case hwmon_chip:
  		return lm90_chip_is_visible(data, attr, channel);
  	case hwmon_temp:
  		return lm90_temp_is_visible(data, attr, channel);
  	default:
  		return 0;
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1345

15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1346
  /* Return 0 if detection is successful, -ENODEV otherwise */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1347
  static int lm90_detect(struct i2c_client *client,
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1348
  		       struct i2c_board_info *info)
8256fe0f4   Jean Delvare   [PATCH] hwmon: Se...
1349
  {
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1350
1351
  	struct i2c_adapter *adapter = client->adapter;
  	int address = client->addr;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1352
  	const char *name = NULL;
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1353
  	int man_id, chip_id, config1, config2, convrate;
8256fe0f4   Jean Delvare   [PATCH] hwmon: Se...
1354

15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1355
1356
  	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1357

8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1358
  	/* detection and identification */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1359
1360
1361
1362
1363
  	man_id = i2c_smbus_read_byte_data(client, LM90_REG_R_MAN_ID);
  	chip_id = i2c_smbus_read_byte_data(client, LM90_REG_R_CHIP_ID);
  	config1 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
  	convrate = i2c_smbus_read_byte_data(client, LM90_REG_R_CONVRATE);
  	if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1364
  		return -ENODEV;
f90be42fb   Jean Delvare   hwmon: (lm90) Ref...
1365
  	if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) {
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1366
1367
  		config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
  		if (config2 < 0)
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
1368
  			return -ENODEV;
f90be42fb   Jean Delvare   hwmon: (lm90) Ref...
1369
  	} else
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1370
  		config2 = 0;		/* Make compiler happy */
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1371

f90be42fb   Jean Delvare   hwmon: (lm90) Ref...
1372
1373
  	if ((address == 0x4C || address == 0x4D)
  	 && man_id == 0x01) { /* National Semiconductor */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1374
1375
1376
  		if ((config1 & 0x2A) == 0x00
  		 && (config2 & 0xF8) == 0x00
  		 && convrate <= 0x09) {
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1377
1378
1379
  			if (address == 0x4C
  			 && (chip_id & 0xF0) == 0x20) { /* LM90 */
  				name = "lm90";
32c82a934   Rainer Birkenmaier   hwmon/lm90: Add s...
1380
  			} else
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
  			if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
  				name = "lm99";
  				dev_info(&adapter->dev,
  					 "Assuming LM99 chip at 0x%02x
  ",
  					 address);
  				dev_info(&adapter->dev,
  					 "If it is an LM89, instantiate it "
  					 "with the new_device sysfs "
  					 "interface
  ");
271dabf5b   Ben Hutchings   hwmon: (lm90) Sup...
1392
  			} else
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1393
1394
1395
  			if (address == 0x4C
  			 && (chip_id & 0xF0) == 0x10) { /* LM86 */
  				name = "lm86";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1396
1397
  			}
  		}
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1398
1399
1400
1401
  	} else
  	if ((address == 0x4C || address == 0x4D)
  	 && man_id == 0x41) { /* Analog Devices */
  		if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1402
1403
  		 && (config1 & 0x3F) == 0x00
  		 && convrate <= 0x0A) {
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1404
  			name = "adm1032";
f36ffeab0   Guenter Roeck   hwmon: (lm90) Fix...
1405
1406
1407
1408
  			/*
  			 * The ADM1032 supports PEC, but only if combined
  			 * transactions are not used.
  			 */
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1409
1410
1411
1412
1413
  			if (i2c_check_functionality(adapter,
  						    I2C_FUNC_SMBUS_BYTE))
  				info->flags |= I2C_CLIENT_PEC;
  		} else
  		if (chip_id == 0x51 /* ADT7461 */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1414
1415
  		 && (config1 & 0x1B) == 0x00
  		 && convrate <= 0x0A) {
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1416
  			name = "adt7461";
5a4e5e6a7   Guenter Roeck   hwmon: (lm90) Add...
1417
1418
  		} else
  		if (chip_id == 0x57 /* ADT7461A, NCT1008 */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1419
1420
  		 && (config1 & 0x1B) == 0x00
  		 && convrate <= 0x0A) {
5a4e5e6a7   Guenter Roeck   hwmon: (lm90) Add...
1421
  			name = "adt7461a";
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1422
1423
1424
  		}
  	} else
  	if (man_id == 0x4D) { /* Maxim */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1425
  		int emerg, emerg2, status2;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1426
1427
1428
1429
1430
1431
1432
  
  		/*
  		 * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read
  		 * LM90_REG_R_MAN_ID in between. If MAX6659_REG_R_REMOTE_EMERG
  		 * exists, both readings will reflect the same value. Otherwise,
  		 * the readings will be different.
  		 */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1433
1434
1435
  		emerg = i2c_smbus_read_byte_data(client,
  						 MAX6659_REG_R_REMOTE_EMERG);
  		man_id = i2c_smbus_read_byte_data(client,
8dc089d68   Jean Delvare   hwmon: (lm90) Fix...
1436
  						  LM90_REG_R_MAN_ID);
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1437
  		emerg2 = i2c_smbus_read_byte_data(client,
8dc089d68   Jean Delvare   hwmon: (lm90) Fix...
1438
  						  MAX6659_REG_R_REMOTE_EMERG);
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1439
1440
1441
  		status2 = i2c_smbus_read_byte_data(client,
  						   MAX6696_REG_R_STATUS2);
  		if (emerg < 0 || man_id < 0 || emerg2 < 0 || status2 < 0)
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1442
  			return -ENODEV;
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1443
1444
1445
1446
1447
1448
1449
  		/*
  		 * The MAX6657, MAX6658 and MAX6659 do NOT have a chip_id
  		 * register. Reading from that address will return the last
  		 * read value, which in our case is those of the man_id
  		 * register. Likewise, the config1 register seems to lack a
  		 * low nibble, so the value will be those of the previous
  		 * read, so in our case those of the man_id register.
13c84951a   Guenter Roeck   hwmon: (lm90) Add...
1450
1451
1452
1453
1454
  		 * MAX6659 has a third set of upper temperature limit registers.
  		 * Those registers also return values on MAX6657 and MAX6658,
  		 * thus the only way to detect MAX6659 is by its address.
  		 * For this reason it will be mis-detected as MAX6657 if its
  		 * address is 0x4C.
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1455
1456
  		 */
  		if (chip_id == man_id
13c84951a   Guenter Roeck   hwmon: (lm90) Add...
1457
  		 && (address == 0x4C || address == 0x4D || address == 0x4E)
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1458
1459
  		 && (config1 & 0x1F) == (man_id & 0x0F)
  		 && convrate <= 0x09) {
13c84951a   Guenter Roeck   hwmon: (lm90) Add...
1460
1461
1462
1463
  			if (address == 0x4C)
  				name = "max6657";
  			else
  				name = "max6659";
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1464
1465
  		} else
  		/*
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
  		 * Even though MAX6695 and MAX6696 do not have a chip ID
  		 * register, reading it returns 0x01. Bit 4 of the config1
  		 * register is unused and should return zero when read. Bit 0 of
  		 * the status2 register is unused and should return zero when
  		 * read.
  		 *
  		 * MAX6695 and MAX6696 have an additional set of temperature
  		 * limit registers. We can detect those chips by checking if
  		 * one of those registers exists.
  		 */
  		if (chip_id == 0x01
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1477
1478
1479
1480
  		 && (config1 & 0x10) == 0x00
  		 && (status2 & 0x01) == 0x00
  		 && emerg == emerg2
  		 && convrate <= 0x07) {
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1481
1482
1483
  			name = "max6696";
  		} else
  		/*
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1484
1485
1486
1487
1488
1489
  		 * The chip_id register of the MAX6680 and MAX6681 holds the
  		 * revision of the chip. The lowest bit of the config1 register
  		 * is unused and should return zero when read, so should the
  		 * second to last bit of config1 (software reset).
  		 */
  		if (chip_id == 0x01
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1490
1491
  		 && (config1 & 0x03) == 0x00
  		 && convrate <= 0x07) {
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1492
1493
1494
1495
1496
1497
1498
1499
  			name = "max6680";
  		} else
  		/*
  		 * The chip_id register of the MAX6646/6647/6649 holds the
  		 * revision of the chip. The lowest 6 bits of the config1
  		 * register are unused and should return zero when read.
  		 */
  		if (chip_id == 0x59
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1500
1501
  		 && (config1 & 0x3f) == 0x00
  		 && convrate <= 0x07) {
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1502
  			name = "max6646";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503
  		}
6771ea1ff   Jean Delvare   hwmon: (lm90) Add...
1504
1505
1506
  	} else
  	if (address == 0x4C
  	 && man_id == 0x5C) { /* Winbond/Nuvoton */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1507
1508
  		if ((config1 & 0x2A) == 0x00
  		 && (config2 & 0xF8) == 0x00) {
c4f99a2b8   Jean Delvare   hwmon: (lm90) Add...
1509
  			if (chip_id == 0x01 /* W83L771W/G */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1510
  			 && convrate <= 0x09) {
c4f99a2b8   Jean Delvare   hwmon: (lm90) Add...
1511
1512
1513
  				name = "w83l771";
  			} else
  			if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1514
  			 && convrate <= 0x08) {
c4f99a2b8   Jean Delvare   hwmon: (lm90) Add...
1515
1516
  				name = "w83l771";
  			}
6771ea1ff   Jean Delvare   hwmon: (lm90) Add...
1517
  		}
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
1518
  	} else
6d101c588   Jean Delvare   hwmon: (lm90) Mak...
1519
1520
  	if (address >= 0x48 && address <= 0x4F
  	 && man_id == 0xA1) { /*  NXP Semiconductor/Philips */
6d101c588   Jean Delvare   hwmon: (lm90) Mak...
1521
  		if (chip_id == 0x00
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1522
1523
1524
  		 && (config1 & 0x2A) == 0x00
  		 && (config2 & 0xFE) == 0x00
  		 && convrate <= 0x09) {
2ef017935   Stijn Devriendt   hwmon: (lm90) Add...
1525
1526
  			name = "sa56004";
  		}
ae544f64c   Guenter Roeck   hwmon: (lm90) Add...
1527
1528
1529
1530
1531
1532
1533
  	} else
  	if ((address == 0x4C || address == 0x4D)
  	 && man_id == 0x47) { /* GMT */
  		if (chip_id == 0x01 /* G781 */
  		 && (config1 & 0x3F) == 0x00
  		 && convrate <= 0x08)
  			name = "g781";
1daaceb26   Wei Ni   hwmon: (lm90) Add...
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
  	} else
  	if (address == 0x4C
  	 && man_id == 0x55) { /* Texas Instruments */
  		int local_ext;
  
  		local_ext = i2c_smbus_read_byte_data(client,
  						     TMP451_REG_R_LOCAL_TEMPL);
  
  		if (chip_id == 0x00 /* TMP451 */
  		 && (config1 & 0x1B) == 0x00
  		 && convrate <= 0x09
  		 && (local_ext & 0x0F) == 0x00)
  			name = "tmp451";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1547
  	}
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1548
1549
1550
1551
1552
1553
  	if (!name) { /* identification failed */
  		dev_dbg(&adapter->dev,
  			"Unsupported chip at 0x%02x (man_id=0x%02X, "
  			"chip_id=0x%02X)
  ", address, man_id, chip_id);
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
  	}
8f2fa77c5   Jean Delvare   hwmon: (lm90) Cle...
1555

9b0e85269   Jean Delvare   hwmon: (lm90) Con...
1556
1557
1558
1559
  	strlcpy(info->type, name, I2C_NAME_SIZE);
  
  	return 0;
  }
1f17a444b   Guenter Roeck   hwmon: (lm90) Use...
1560
  static void lm90_restore_conf(void *_data)
f7001bb06   Guenter Roeck   hwmon: (lm90) Res...
1561
  {
1f17a444b   Guenter Roeck   hwmon: (lm90) Use...
1562
1563
  	struct lm90_data *data = _data;
  	struct i2c_client *client = data->client;
f7001bb06   Guenter Roeck   hwmon: (lm90) Res...
1564
  	/* Restore initial configuration */
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
1565
  	lm90_write_convrate(data, data->convrate_orig);
f7001bb06   Guenter Roeck   hwmon: (lm90) Res...
1566
1567
1568
  	i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
  				  data->config_orig);
  }
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1569
  static int lm90_init_client(struct i2c_client *client, struct lm90_data *data)
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1570
  {
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1571
  	int config, convrate;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1572

37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1573
1574
1575
  	convrate = lm90_read_reg(client, LM90_REG_R_CONVRATE);
  	if (convrate < 0)
  		return convrate;
0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1576
  	data->convrate_orig = convrate;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1577
1578
1579
  	/*
  	 * Start the conversions.
  	 */
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1580
1581
1582
  	config = lm90_read_reg(client, LM90_REG_R_CONFIG1);
  	if (config < 0)
  		return config;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1583
  	data->config_orig = config;
b849e5d18   Guenter Roeck   hwmon: (lm90) Cac...
1584
  	data->config = config;
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1585

62456189f   Boyang Yu   hwmon: (lm90) Fix...
1586
  	lm90_set_convrate(client, data, 500); /* 500ms; 2Hz conversion rate */
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1587
  	/* Check Temperature Range Select */
1daaceb26   Wei Ni   hwmon: (lm90) Add...
1588
  	if (data->kind == adt7461 || data->kind == tmp451) {
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
  		if (config & 0x04)
  			data->flags |= LM90_FLAG_ADT7461_EXT;
  	}
  
  	/*
  	 * Put MAX6680/MAX8881 into extended resolution (bit 0x10,
  	 * 0.125 degree resolution) and range (0x08, extend range
  	 * to -64 degree) mode for the remote temperature sensor.
  	 */
  	if (data->kind == max6680)
  		config |= 0x18;
  
  	/*
  	 * Select external channel 0 for max6695/96
  	 */
  	if (data->kind == max6696)
  		config &= ~0x08;
  
  	config &= 0xBF;	/* run */
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
1608
  	lm90_update_confreg(data, config);
1f17a444b   Guenter Roeck   hwmon: (lm90) Use...
1609

c5fcf01bc   Guenter Roeck   hwmon: (lm90) Imp...
1610
  	return devm_add_action_or_reset(&client->dev, lm90_restore_conf, data);
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1611
  }
072de4969   Wei Ni   hwmon: (lm90) Def...
1612
1613
1614
  static bool lm90_is_tripped(struct i2c_client *client, u16 *status)
  {
  	struct lm90_data *data = i2c_get_clientdata(client);
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1615
  	int st, st2 = 0;
072de4969   Wei Ni   hwmon: (lm90) Def...
1616

37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1617
1618
1619
  	st = lm90_read_reg(client, LM90_REG_R_STATUS);
  	if (st < 0)
  		return false;
072de4969   Wei Ni   hwmon: (lm90) Def...
1620

37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1621
1622
1623
1624
1625
  	if (data->kind == max6696) {
  		st2 = lm90_read_reg(client, MAX6696_REG_R_STATUS2);
  		if (st2 < 0)
  			return false;
  	}
072de4969   Wei Ni   hwmon: (lm90) Def...
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
  
  	*status = st | (st2 << 8);
  
  	if ((st & 0x7f) == 0 && (st2 & 0xfe) == 0)
  		return false;
  
  	if ((st & (LM90_STATUS_LLOW | LM90_STATUS_LHIGH | LM90_STATUS_LTHRM)) ||
  	    (st2 & MAX6696_STATUS2_LOT2))
  		dev_warn(&client->dev,
  			 "temp%d out of range, please check!
  ", 1);
  	if ((st & (LM90_STATUS_RLOW | LM90_STATUS_RHIGH | LM90_STATUS_RTHRM)) ||
  	    (st2 & MAX6696_STATUS2_ROT2))
  		dev_warn(&client->dev,
  			 "temp%d out of range, please check!
  ", 2);
  	if (st & LM90_STATUS_ROPEN)
  		dev_warn(&client->dev,
  			 "temp%d diode open, please check!
  ", 2);
  	if (st2 & (MAX6696_STATUS2_R2LOW | MAX6696_STATUS2_R2HIGH |
  		   MAX6696_STATUS2_R2THRM | MAX6696_STATUS2_R2OT2))
  		dev_warn(&client->dev,
  			 "temp%d out of range, please check!
  ", 3);
  	if (st2 & MAX6696_STATUS2_R2OPEN)
  		dev_warn(&client->dev,
  			 "temp%d diode open, please check!
  ", 3);
  
  	return true;
  }
109b1283f   Wei Ni   hwmon: (lm90) Add...
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
  static irqreturn_t lm90_irq_thread(int irq, void *dev_id)
  {
  	struct i2c_client *client = dev_id;
  	u16 status;
  
  	if (lm90_is_tripped(client, &status))
  		return IRQ_HANDLED;
  	else
  		return IRQ_NONE;
  }
1f17a444b   Guenter Roeck   hwmon: (lm90) Use...
1668
1669
1670
1671
1672
1673
1674
1675
1676
  static void lm90_remove_pec(void *dev)
  {
  	device_remove_file(dev, &dev_attr_pec);
  }
  
  static void lm90_regulator_disable(void *regulator)
  {
  	regulator_disable(regulator);
  }
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1677
1678
1679
1680
1681
1682
  
  static const struct hwmon_ops lm90_ops = {
  	.is_visible = lm90_is_visible,
  	.read = lm90_read,
  	.write = lm90_write,
  };
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1683
  static int lm90_probe(struct i2c_client *client,
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
1684
1685
  		      const struct i2c_device_id *id)
  {
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1686
  	struct device *dev = &client->dev;
e67776cc3   Wolfram Sang   hwmon: (lm90) sim...
1687
  	struct i2c_adapter *adapter = client->adapter;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1688
  	struct hwmon_channel_info *info;
3e0f964f2   Wei Ni   hwmon: (lm90) Add...
1689
  	struct regulator *regulator;
6e5f62b9e   Guenter Roeck   hwmon: (lm90) Use...
1690
  	struct device *hwmon_dev;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1691
  	struct lm90_data *data;
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
1692
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1693

3e0f964f2   Wei Ni   hwmon: (lm90) Add...
1694
1695
1696
1697
1698
1699
  	regulator = devm_regulator_get(dev, "vcc");
  	if (IS_ERR(regulator))
  		return PTR_ERR(regulator);
  
  	err = regulator_enable(regulator);
  	if (err < 0) {
d89fa6867   Guenter Roeck   hwmon: (lm90) Alw...
1700
1701
  		dev_err(dev, "Failed to enable regulator: %d
  ", err);
3e0f964f2   Wei Ni   hwmon: (lm90) Add...
1702
1703
  		return err;
  	}
c5fcf01bc   Guenter Roeck   hwmon: (lm90) Imp...
1704
1705
1706
  	err = devm_add_action_or_reset(dev, lm90_regulator_disable, regulator);
  	if (err)
  		return err;
1f17a444b   Guenter Roeck   hwmon: (lm90) Use...
1707

d89fa6867   Guenter Roeck   hwmon: (lm90) Alw...
1708
  	data = devm_kzalloc(dev, sizeof(struct lm90_data), GFP_KERNEL);
20f426ff0   Guenter Roeck   hwmon: (lm90) Con...
1709
1710
  	if (!data)
  		return -ENOMEM;
1de8b250f   Guenter Roeck   hwmon: (lm90) Con...
1711
  	data->client = client;
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1712
  	i2c_set_clientdata(client, data);
9a61bf630   Ingo Molnar   [PATCH] hwmon: Se...
1713
  	mutex_init(&data->update_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1714

9b0e85269   Jean Delvare   hwmon: (lm90) Con...
1715
  	/* Set the device type */
df8d57bf8   Javier Martinez Canillas   hwmon: (lm90) Add...
1716
1717
1718
1719
  	if (client->dev.of_node)
  		data->kind = (enum chips)of_device_get_match_data(&client->dev);
  	else
  		data->kind = id->driver_data;
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
1720
1721
  	if (data->kind == adm1032) {
  		if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1722
  			client->flags &= ~I2C_CLIENT_PEC;
9b0e85269   Jean Delvare   hwmon: (lm90) Con...
1723
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1724

f36ffeab0   Guenter Roeck   hwmon: (lm90) Fix...
1725
1726
1727
1728
  	/*
  	 * Different devices have different alarm bits triggering the
  	 * ALERT# output
  	 */
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
1729
  	data->alert_alarms = lm90_params[data->kind].alert_alarms;
53de33427   Jean Delvare   hwmon: (lm90) Add...
1730

88073bb1b   Guenter Roeck   hwmon: (lm90) Int...
1731
  	/* Set chip capabilities */
4667bcb8d   Guenter Roeck   hwmon: (lm90) Int...
1732
  	data->flags = lm90_params[data->kind].flags;
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1733
1734
1735
  
  	data->chip.ops = &lm90_ops;
  	data->chip.info = data->info;
a4d41e673   Guenter Roeck   hwmon: (lm90) Use...
1736
1737
  	data->info[0] = HWMON_CHANNEL_INFO(chip,
  		HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL | HWMON_C_ALARMS);
eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
  	data->info[1] = &data->temp_info;
  
  	info = &data->temp_info;
  	info->type = hwmon_temp;
  	info->config = data->channel_config;
  
  	data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
  		HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
  		HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM;
  	data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
  		HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
  		HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT;
  
  	if (data->flags & LM90_HAVE_OFFSET)
  		data->channel_config[1] |= HWMON_T_OFFSET;
  
  	if (data->flags & LM90_HAVE_EMERGENCY) {
  		data->channel_config[0] |= HWMON_T_EMERGENCY |
  			HWMON_T_EMERGENCY_HYST;
  		data->channel_config[1] |= HWMON_T_EMERGENCY |
  			HWMON_T_EMERGENCY_HYST;
  	}
  
  	if (data->flags & LM90_HAVE_EMERGENCY_ALARM) {
  		data->channel_config[0] |= HWMON_T_EMERGENCY_ALARM;
  		data->channel_config[1] |= HWMON_T_EMERGENCY_ALARM;
  	}
  
  	if (data->flags & LM90_HAVE_TEMP3) {
  		data->channel_config[2] = HWMON_T_INPUT |
  			HWMON_T_MIN | HWMON_T_MAX |
  			HWMON_T_CRIT | HWMON_T_CRIT_HYST |
  			HWMON_T_EMERGENCY | HWMON_T_EMERGENCY_HYST |
  			HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
  			HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY_ALARM |
  			HWMON_T_FAULT;
  	}
a095f687f   Jean Delvare   hwmon: (lm90) Sim...
1775
  	data->reg_local_ext = lm90_params[data->kind].reg_local_ext;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1776

0c01b644f   Guenter Roeck   hwmon: (lm90) Add...
1777
1778
  	/* Set maximum conversion rate */
  	data->max_convrate = lm90_params[data->kind].max_convrate;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1779
  	/* Initialize the LM90 chip */
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1780
1781
1782
1783
1784
1785
  	err = lm90_init_client(client, data);
  	if (err < 0) {
  		dev_err(dev, "Failed to initialize device
  ");
  		return err;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1786

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1787
1788
1789
1790
  	/*
  	 * The 'pec' attribute is attached to the i2c device and thus created
  	 * separately.
  	 */
b2589ab02   Jean Delvare   hwmon: (lm90) Mak...
1791
1792
  	if (client->flags & I2C_CLIENT_PEC) {
  		err = device_create_file(dev, &dev_attr_pec);
11e578129   Guenter Roeck   hwmon: (lm90) Fix...
1793
  		if (err)
1f17a444b   Guenter Roeck   hwmon: (lm90) Use...
1794
  			return err;
c5fcf01bc   Guenter Roeck   hwmon: (lm90) Imp...
1795
1796
1797
  		err = devm_add_action_or_reset(dev, lm90_remove_pec, dev);
  		if (err)
  			return err;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1798
  	}
0e39e01c9   Jean Delvare   hwmon: Fix unchec...
1799

eb1c8f432   Guenter Roeck   hwmon: (lm90) Con...
1800
1801
1802
  	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
  							 data, &data->chip,
  							 NULL);
6e5f62b9e   Guenter Roeck   hwmon: (lm90) Use...
1803
1804
  	if (IS_ERR(hwmon_dev))
  		return PTR_ERR(hwmon_dev);
943b0830c   Mark M. Hoffman   [PATCH] I2C hwmon...
1805

109b1283f   Wei Ni   hwmon: (lm90) Add...
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
  	if (client->irq) {
  		dev_dbg(dev, "IRQ: %d
  ", client->irq);
  		err = devm_request_threaded_irq(dev, client->irq,
  						NULL, lm90_irq_thread,
  						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
  						"lm90", client);
  		if (err < 0) {
  			dev_err(dev, "cannot request IRQ %d
  ", client->irq);
6e5f62b9e   Guenter Roeck   hwmon: (lm90) Use...
1816
  			return err;
109b1283f   Wei Ni   hwmon: (lm90) Add...
1817
1818
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1819
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1820
  }
b4f210541   Benjamin Tissoires   i2c: add a protoc...
1821
1822
  static void lm90_alert(struct i2c_client *client, enum i2c_alert_protocol type,
  		       unsigned int flag)
53de33427   Jean Delvare   hwmon: (lm90) Add...
1823
  {
072de4969   Wei Ni   hwmon: (lm90) Def...
1824
  	u16 alarms;
06e1c0a21   Guenter Roeck   hwmon: (lm90) Add...
1825

b4f210541   Benjamin Tissoires   i2c: add a protoc...
1826
1827
  	if (type != I2C_PROTOCOL_SMBUS_ALERT)
  		return;
072de4969   Wei Ni   hwmon: (lm90) Def...
1828
  	if (lm90_is_tripped(client, &alarms)) {
f36ffeab0   Guenter Roeck   hwmon: (lm90) Fix...
1829
1830
1831
1832
1833
  		/*
  		 * Disable ALERT# output, because these chips don't implement
  		 * SMBus alert correctly; they should only hold the alert line
  		 * low briefly.
  		 */
072de4969   Wei Ni   hwmon: (lm90) Def...
1834
  		struct lm90_data *data = i2c_get_clientdata(client);
37ad04d7a   Guenter Roeck   hwmon: (lm90) Sim...
1835
1836
  		if ((data->flags & LM90_HAVE_BROKEN_ALERT) &&
  		    (alarms & data->alert_alarms)) {
53de33427   Jean Delvare   hwmon: (lm90) Add...
1837
1838
  			dev_dbg(&client->dev, "Disabling ALERT#
  ");
7a1d220cc   Guenter Roeck   hwmon: (lm90) Int...
1839
  			lm90_update_confreg(data, data->config | 0x80);
53de33427   Jean Delvare   hwmon: (lm90) Add...
1840
  		}
072de4969   Wei Ni   hwmon: (lm90) Def...
1841
1842
1843
  	} else {
  		dev_info(&client->dev, "Everything OK
  ");
53de33427   Jean Delvare   hwmon: (lm90) Add...
1844
1845
  	}
  }
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1846
1847
1848
1849
  static struct i2c_driver lm90_driver = {
  	.class		= I2C_CLASS_HWMON,
  	.driver = {
  		.name	= "lm90",
df8d57bf8   Javier Martinez Canillas   hwmon: (lm90) Add...
1850
  		.of_match_table = of_match_ptr(lm90_of_match),
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1851
1852
  	},
  	.probe		= lm90_probe,
15b66ab69   Guenter Roeck   hwmon: (lm90) Rea...
1853
1854
1855
1856
1857
  	.alert		= lm90_alert,
  	.id_table	= lm90_id,
  	.detect		= lm90_detect,
  	.address_list	= normal_i2c,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1858

f0967eea8   Axel Lin   hwmon: convert dr...
1859
  module_i2c_driver(lm90_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1860

7c81c60f3   Jean Delvare   Update Jean Delva...
1861
  MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1862
1863
  MODULE_DESCRIPTION("LM90/ADM1032 driver");
  MODULE_LICENSE("GPL");