1/*
2    ds1621.c - Part of lm_sensors, Linux kernel modules for hardware
3             monitoring
4    Christian W. Zuckschwerdt  <zany@triq.net>  2000-11-23
5    based on lm75.c by Frodo Looijaard <frodol@dds.nl>
6    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
7    the help of Jean Delvare <khali@linux-fr.org>
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/slab.h>
27#include <linux/jiffies.h>
28#include <linux/i2c.h>
29#include <linux/hwmon.h>
30#include <linux/err.h>
31#include <linux/mutex.h>
32#include <linux/sysfs.h>
33#include "lm75.h"
34
35/* Addresses to scan */
36static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
37					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
38
39/* Insmod parameters */
40I2C_CLIENT_INSMOD_1(ds1621);
41static int polarity = -1;
42module_param(polarity, int, 0);
43MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low");
44
45/* Many DS1621 constants specified below */
46/* Config register used for detection         */
47/*  7    6    5    4    3    2    1    0      */
48/* |Done|THF |TLF |NVB | X  | X  |POL |1SHOT| */
49#define DS1621_REG_CONFIG_NVB		0x10
50#define DS1621_REG_CONFIG_POLARITY	0x02
51#define DS1621_REG_CONFIG_1SHOT		0x01
52#define DS1621_REG_CONFIG_DONE		0x80
53
54/* The DS1621 registers */
55#define DS1621_REG_TEMP			0xAA /* word, RO */
56#define DS1621_REG_TEMP_MIN		0xA2 /* word, RW */
57#define DS1621_REG_TEMP_MAX		0xA1 /* word, RW */
58#define DS1621_REG_CONF			0xAC /* byte, RW */
59#define DS1621_COM_START		0xEE /* no data */
60#define DS1621_COM_STOP			0x22 /* no data */
61
62/* The DS1621 configuration register */
63#define DS1621_ALARM_TEMP_HIGH		0x40
64#define DS1621_ALARM_TEMP_LOW		0x20
65
66/* Conversions. Rounding and limit checking is only done on the TO_REG
67   variants. Note that you should be a bit careful with which arguments
68   these macros are called: arguments may be evaluated more than once.
69   Fixing this is just not worth it. */
70#define ALARMS_FROM_REG(val) ((val) & \
71                              (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW))
72
73/* Each client has this additional data */
74struct ds1621_data {
75	struct i2c_client client;
76	struct class_device *class_dev;
77	struct mutex update_lock;
78	char valid;			/* !=0 if following fields are valid */
79	unsigned long last_updated;	/* In jiffies */
80
81	u16 temp, temp_min, temp_max;	/* Register values, word */
82	u8 conf;			/* Register encoding, combined */
83};
84
85static int ds1621_attach_adapter(struct i2c_adapter *adapter);
86static int ds1621_detect(struct i2c_adapter *adapter, int address,
87			 int kind);
88static void ds1621_init_client(struct i2c_client *client);
89static int ds1621_detach_client(struct i2c_client *client);
90static struct ds1621_data *ds1621_update_client(struct device *dev);
91
92/* This is the driver that will be inserted */
93static struct i2c_driver ds1621_driver = {
94	.driver = {
95		.name	= "ds1621",
96	},
97	.id		= I2C_DRIVERID_DS1621,
98	.attach_adapter	= ds1621_attach_adapter,
99	.detach_client	= ds1621_detach_client,
100};
101
102/* All registers are word-sized, except for the configuration register.
103   DS1621 uses a high-byte first convention, which is exactly opposite to
104   the usual practice. */
105static int ds1621_read_value(struct i2c_client *client, u8 reg)
106{
107	if (reg == DS1621_REG_CONF)
108		return i2c_smbus_read_byte_data(client, reg);
109	else
110		return swab16(i2c_smbus_read_word_data(client, reg));
111}
112
113/* All registers are word-sized, except for the configuration register.
114   DS1621 uses a high-byte first convention, which is exactly opposite to
115   the usual practice. */
116static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
117{
118	if (reg == DS1621_REG_CONF)
119		return i2c_smbus_write_byte_data(client, reg, value);
120	else
121		return i2c_smbus_write_word_data(client, reg, swab16(value));
122}
123
124static void ds1621_init_client(struct i2c_client *client)
125{
126	int reg = ds1621_read_value(client, DS1621_REG_CONF);
127	/* switch to continuous conversion mode */
128	reg &= ~ DS1621_REG_CONFIG_1SHOT;
129
130	/* setup output polarity */
131	if (polarity == 0)
132		reg &= ~DS1621_REG_CONFIG_POLARITY;
133	else if (polarity == 1)
134		reg |= DS1621_REG_CONFIG_POLARITY;
135
136	ds1621_write_value(client, DS1621_REG_CONF, reg);
137
138	/* start conversion */
139	i2c_smbus_write_byte(client, DS1621_COM_START);
140}
141
142#define show(value)							\
143static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
144{									\
145	struct ds1621_data *data = ds1621_update_client(dev);		\
146	return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value));	\
147}
148
149show(temp);
150show(temp_min);
151show(temp_max);
152
153#define set_temp(suffix, value, reg)					\
154static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf,	\
155				 size_t count)				\
156{									\
157	struct i2c_client *client = to_i2c_client(dev);			\
158	struct ds1621_data *data = ds1621_update_client(dev);		\
159	u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10));	\
160									\
161	mutex_lock(&data->update_lock);					\
162	data->value = val;						\
163	ds1621_write_value(client, reg, data->value);			\
164	mutex_unlock(&data->update_lock);				\
165	return count;							\
166}
167
168set_temp(min, temp_min, DS1621_REG_TEMP_MIN);
169set_temp(max, temp_max, DS1621_REG_TEMP_MAX);
170
171static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
172{
173	struct ds1621_data *data = ds1621_update_client(dev);
174	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf));
175}
176
177static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
178static DEVICE_ATTR(temp1_input, S_IRUGO , show_temp, NULL);
179static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO , show_temp_min, set_temp_min);
180static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
181
182static struct attribute *ds1621_attributes[] = {
183	&dev_attr_temp1_input.attr,
184	&dev_attr_temp1_min.attr,
185	&dev_attr_temp1_max.attr,
186	&dev_attr_alarms.attr,
187	NULL
188};
189
190static const struct attribute_group ds1621_group = {
191	.attrs = ds1621_attributes,
192};
193
194
195static int ds1621_attach_adapter(struct i2c_adapter *adapter)
196{
197	if (!(adapter->class & I2C_CLASS_HWMON))
198		return 0;
199	return i2c_probe(adapter, &addr_data, ds1621_detect);
200}
201
202/* This function is called by i2c_probe */
203static int ds1621_detect(struct i2c_adapter *adapter, int address,
204			 int kind)
205{
206	int conf, temp;
207	struct i2c_client *new_client;
208	struct ds1621_data *data;
209	int err = 0;
210
211	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
212				     | I2C_FUNC_SMBUS_WORD_DATA
213				     | I2C_FUNC_SMBUS_WRITE_BYTE))
214		goto exit;
215
216	/* OK. For now, we presume we have a valid client. We now create the
217	   client structure, even though we cannot fill it completely yet.
218	   But it allows us to access ds1621_{read,write}_value. */
219	if (!(data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
220		err = -ENOMEM;
221		goto exit;
222	}
223
224	new_client = &data->client;
225	i2c_set_clientdata(new_client, data);
226	new_client->addr = address;
227	new_client->adapter = adapter;
228	new_client->driver = &ds1621_driver;
229	new_client->flags = 0;
230
231
232	/* Now, we do the remaining detection. It is lousy. */
233	if (kind < 0) {
234		/* The NVB bit should be low if no EEPROM write has been
235		   requested during the latest 10ms, which is highly
236		   improbable in our case. */
237		conf = ds1621_read_value(new_client, DS1621_REG_CONF);
238		if (conf & DS1621_REG_CONFIG_NVB)
239			goto exit_free;
240		/* The 7 lowest bits of a temperature should always be 0. */
241		temp = ds1621_read_value(new_client, DS1621_REG_TEMP);
242		if (temp & 0x007f)
243			goto exit_free;
244		temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MIN);
245		if (temp & 0x007f)
246			goto exit_free;
247		temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MAX);
248		if (temp & 0x007f)
249			goto exit_free;
250	}
251
252	/* Determine the chip type - only one kind supported! */
253	if (kind <= 0)
254		kind = ds1621;
255
256	/* Fill in remaining client fields and put it into the global list */
257	strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE);
258	data->valid = 0;
259	mutex_init(&data->update_lock);
260
261	/* Tell the I2C layer a new client has arrived */
262	if ((err = i2c_attach_client(new_client)))
263		goto exit_free;
264
265	/* Initialize the DS1621 chip */
266	ds1621_init_client(new_client);
267
268	/* Register sysfs hooks */
269	if ((err = sysfs_create_group(&new_client->dev.kobj, &ds1621_group)))
270		goto exit_detach;
271
272	data->class_dev = hwmon_device_register(&new_client->dev);
273	if (IS_ERR(data->class_dev)) {
274		err = PTR_ERR(data->class_dev);
275		goto exit_remove_files;
276	}
277
278	return 0;
279
280      exit_remove_files:
281	sysfs_remove_group(&new_client->dev.kobj, &ds1621_group);
282      exit_detach:
283	i2c_detach_client(new_client);
284      exit_free:
285	kfree(data);
286      exit:
287	return err;
288}
289
290static int ds1621_detach_client(struct i2c_client *client)
291{
292	struct ds1621_data *data = i2c_get_clientdata(client);
293	int err;
294
295	hwmon_device_unregister(data->class_dev);
296	sysfs_remove_group(&client->dev.kobj, &ds1621_group);
297
298	if ((err = i2c_detach_client(client)))
299		return err;
300
301	kfree(data);
302
303	return 0;
304}
305
306
307static struct ds1621_data *ds1621_update_client(struct device *dev)
308{
309	struct i2c_client *client = to_i2c_client(dev);
310	struct ds1621_data *data = i2c_get_clientdata(client);
311	u8 new_conf;
312
313	mutex_lock(&data->update_lock);
314
315	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
316	    || !data->valid) {
317
318		dev_dbg(&client->dev, "Starting ds1621 update\n");
319
320		data->conf = ds1621_read_value(client, DS1621_REG_CONF);
321
322		data->temp = ds1621_read_value(client, DS1621_REG_TEMP);
323
324		data->temp_min = ds1621_read_value(client,
325		                                    DS1621_REG_TEMP_MIN);
326		data->temp_max = ds1621_read_value(client,
327						    DS1621_REG_TEMP_MAX);
328
329		/* reset alarms if necessary */
330		new_conf = data->conf;
331		if (data->temp > data->temp_min)
332			new_conf &= ~DS1621_ALARM_TEMP_LOW;
333		if (data->temp < data->temp_max)
334			new_conf &= ~DS1621_ALARM_TEMP_HIGH;
335		if (data->conf != new_conf)
336			ds1621_write_value(client, DS1621_REG_CONF,
337					   new_conf);
338
339		data->last_updated = jiffies;
340		data->valid = 1;
341	}
342
343	mutex_unlock(&data->update_lock);
344
345	return data;
346}
347
348static int __init ds1621_init(void)
349{
350	return i2c_add_driver(&ds1621_driver);
351}
352
353static void __exit ds1621_exit(void)
354{
355	i2c_del_driver(&ds1621_driver);
356}
357
358
359MODULE_AUTHOR("Christian W. Zuckschwerdt <zany@triq.net>");
360MODULE_DESCRIPTION("DS1621 driver");
361MODULE_LICENSE("GPL");
362
363module_init(ds1621_init);
364module_exit(ds1621_exit);
365