xref: /openbmc/linux/drivers/w1/slaves/w1_ds2408.c (revision ad9c36be)
140b0b3f8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
289610274SJean-François Dagenais /*
389610274SJean-François Dagenais  *	w1_ds2408.c - w1 family 29 (DS2408) driver
489610274SJean-François Dagenais  *
589610274SJean-François Dagenais  * Copyright (c) 2010 Jean-Francois Dagenais <dagenaisj@sonatest.com>
689610274SJean-François Dagenais  */
789610274SJean-François Dagenais 
889610274SJean-François Dagenais #include <linux/kernel.h>
989610274SJean-François Dagenais #include <linux/module.h>
1089610274SJean-François Dagenais #include <linux/moduleparam.h>
1189610274SJean-François Dagenais #include <linux/device.h>
1289610274SJean-François Dagenais #include <linux/types.h>
1389610274SJean-François Dagenais #include <linux/delay.h>
1489610274SJean-François Dagenais #include <linux/slab.h>
1589610274SJean-François Dagenais 
16de0d6dbdSAndrew F. Davis #include <linux/w1.h>
17de0d6dbdSAndrew F. Davis 
18de0d6dbdSAndrew F. Davis #define W1_FAMILY_DS2408	0x29
1989610274SJean-François Dagenais 
2089610274SJean-François Dagenais #define W1_F29_RETRIES		3
2189610274SJean-François Dagenais 
2289610274SJean-François Dagenais #define W1_F29_REG_LOGIG_STATE             0x88 /* R */
2389610274SJean-François Dagenais #define W1_F29_REG_OUTPUT_LATCH_STATE      0x89 /* R */
2489610274SJean-François Dagenais #define W1_F29_REG_ACTIVITY_LATCH_STATE    0x8A /* R */
2589610274SJean-François Dagenais #define W1_F29_REG_COND_SEARCH_SELECT_MASK 0x8B /* RW */
2689610274SJean-François Dagenais #define W1_F29_REG_COND_SEARCH_POL_SELECT  0x8C /* RW */
2789610274SJean-François Dagenais #define W1_F29_REG_CONTROL_AND_STATUS      0x8D /* RW */
2889610274SJean-François Dagenais 
2989610274SJean-François Dagenais #define W1_F29_FUNC_READ_PIO_REGS          0xF0
3089610274SJean-François Dagenais #define W1_F29_FUNC_CHANN_ACCESS_READ      0xF5
3189610274SJean-François Dagenais #define W1_F29_FUNC_CHANN_ACCESS_WRITE     0x5A
3289610274SJean-François Dagenais /* also used to write the control/status reg (0x8D): */
3389610274SJean-François Dagenais #define W1_F29_FUNC_WRITE_COND_SEARCH_REG  0xCC
3489610274SJean-François Dagenais #define W1_F29_FUNC_RESET_ACTIVITY_LATCHES 0xC3
3589610274SJean-François Dagenais 
3689610274SJean-François Dagenais #define W1_F29_SUCCESS_CONFIRM_BYTE        0xAA
3789610274SJean-François Dagenais 
_read_reg(struct w1_slave * sl,u8 address,unsigned char * buf)3889610274SJean-François Dagenais static int _read_reg(struct w1_slave *sl, u8 address, unsigned char *buf)
3989610274SJean-François Dagenais {
4089610274SJean-François Dagenais 	u8 wrbuf[3];
41*ad9c36beSKrzysztof Kozlowski 
42*ad9c36beSKrzysztof Kozlowski 	dev_dbg(&sl->dev, "Reading with slave: %p, reg addr: %0#4x, buff addr: %p",
4389610274SJean-François Dagenais 		sl, (unsigned int)address, buf);
4489610274SJean-François Dagenais 
4589610274SJean-François Dagenais 	if (!buf)
4689610274SJean-François Dagenais 		return -EINVAL;
4789610274SJean-François Dagenais 
48b02f8bedSNeilBrown 	mutex_lock(&sl->master->bus_mutex);
4989610274SJean-François Dagenais 	dev_dbg(&sl->dev, "mutex locked");
5089610274SJean-François Dagenais 
5189610274SJean-François Dagenais 	if (w1_reset_select_slave(sl)) {
52b02f8bedSNeilBrown 		mutex_unlock(&sl->master->bus_mutex);
5389610274SJean-François Dagenais 		return -EIO;
5489610274SJean-François Dagenais 	}
5589610274SJean-François Dagenais 
5689610274SJean-François Dagenais 	wrbuf[0] = W1_F29_FUNC_READ_PIO_REGS;
5789610274SJean-François Dagenais 	wrbuf[1] = address;
5889610274SJean-François Dagenais 	wrbuf[2] = 0;
5989610274SJean-François Dagenais 	w1_write_block(sl->master, wrbuf, 3);
6089610274SJean-François Dagenais 	*buf = w1_read_8(sl->master);
6189610274SJean-François Dagenais 
62b02f8bedSNeilBrown 	mutex_unlock(&sl->master->bus_mutex);
6389610274SJean-François Dagenais 	dev_dbg(&sl->dev, "mutex unlocked");
6489610274SJean-François Dagenais 	return 1;
6589610274SJean-François Dagenais }
6689610274SJean-François Dagenais 
state_read(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)6732ea4175SGreg Kroah-Hartman static ssize_t state_read(struct file *filp, struct kobject *kobj,
6832ea4175SGreg Kroah-Hartman 			  struct bin_attribute *bin_attr, char *buf, loff_t off,
6932ea4175SGreg Kroah-Hartman 			  size_t count)
7089610274SJean-François Dagenais {
7189610274SJean-François Dagenais 	dev_dbg(&kobj_to_w1_slave(kobj)->dev,
7289610274SJean-François Dagenais 		"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
7389610274SJean-François Dagenais 		bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
7489610274SJean-François Dagenais 	if (count != 1 || off != 0)
7589610274SJean-François Dagenais 		return -EFAULT;
7689610274SJean-François Dagenais 	return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf);
7789610274SJean-François Dagenais }
7889610274SJean-François Dagenais 
output_read(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)7932ea4175SGreg Kroah-Hartman static ssize_t output_read(struct file *filp, struct kobject *kobj,
8032ea4175SGreg Kroah-Hartman 			   struct bin_attribute *bin_attr, char *buf,
8132ea4175SGreg Kroah-Hartman 			   loff_t off, size_t count)
8289610274SJean-François Dagenais {
8389610274SJean-François Dagenais 	dev_dbg(&kobj_to_w1_slave(kobj)->dev,
8489610274SJean-François Dagenais 		"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
8589610274SJean-François Dagenais 		bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
8689610274SJean-François Dagenais 	if (count != 1 || off != 0)
8789610274SJean-François Dagenais 		return -EFAULT;
8889610274SJean-François Dagenais 	return _read_reg(kobj_to_w1_slave(kobj),
8989610274SJean-François Dagenais 					 W1_F29_REG_OUTPUT_LATCH_STATE, buf);
9089610274SJean-François Dagenais }
9189610274SJean-François Dagenais 
activity_read(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)9232ea4175SGreg Kroah-Hartman static ssize_t activity_read(struct file *filp, struct kobject *kobj,
9332ea4175SGreg Kroah-Hartman 			     struct bin_attribute *bin_attr, char *buf,
9432ea4175SGreg Kroah-Hartman 			     loff_t off, size_t count)
9589610274SJean-François Dagenais {
9689610274SJean-François Dagenais 	dev_dbg(&kobj_to_w1_slave(kobj)->dev,
9789610274SJean-François Dagenais 		"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
9889610274SJean-François Dagenais 		bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
9989610274SJean-François Dagenais 	if (count != 1 || off != 0)
10089610274SJean-François Dagenais 		return -EFAULT;
10189610274SJean-François Dagenais 	return _read_reg(kobj_to_w1_slave(kobj),
10289610274SJean-François Dagenais 					 W1_F29_REG_ACTIVITY_LATCH_STATE, buf);
10389610274SJean-François Dagenais }
10489610274SJean-François Dagenais 
cond_search_mask_read(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)10532ea4175SGreg Kroah-Hartman static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj,
10632ea4175SGreg Kroah-Hartman 				     struct bin_attribute *bin_attr, char *buf,
10732ea4175SGreg Kroah-Hartman 				     loff_t off, size_t count)
10889610274SJean-François Dagenais {
10989610274SJean-François Dagenais 	dev_dbg(&kobj_to_w1_slave(kobj)->dev,
11089610274SJean-François Dagenais 		"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
11189610274SJean-François Dagenais 		bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
11289610274SJean-François Dagenais 	if (count != 1 || off != 0)
11389610274SJean-François Dagenais 		return -EFAULT;
11489610274SJean-François Dagenais 	return _read_reg(kobj_to_w1_slave(kobj),
11589610274SJean-François Dagenais 		W1_F29_REG_COND_SEARCH_SELECT_MASK, buf);
11689610274SJean-François Dagenais }
11789610274SJean-François Dagenais 
cond_search_polarity_read(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)11832ea4175SGreg Kroah-Hartman static ssize_t cond_search_polarity_read(struct file *filp,
11932ea4175SGreg Kroah-Hartman 					 struct kobject *kobj,
12089610274SJean-François Dagenais 					 struct bin_attribute *bin_attr,
12189610274SJean-François Dagenais 					 char *buf, loff_t off, size_t count)
12289610274SJean-François Dagenais {
12389610274SJean-François Dagenais 	if (count != 1 || off != 0)
12489610274SJean-François Dagenais 		return -EFAULT;
12589610274SJean-François Dagenais 	return _read_reg(kobj_to_w1_slave(kobj),
12689610274SJean-François Dagenais 		W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
12789610274SJean-François Dagenais }
12889610274SJean-François Dagenais 
status_control_read(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)12932ea4175SGreg Kroah-Hartman static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
13032ea4175SGreg Kroah-Hartman 				   struct bin_attribute *bin_attr, char *buf,
13132ea4175SGreg Kroah-Hartman 				   loff_t off, size_t count)
13289610274SJean-François Dagenais {
13389610274SJean-François Dagenais 	if (count != 1 || off != 0)
13489610274SJean-François Dagenais 		return -EFAULT;
13589610274SJean-François Dagenais 	return _read_reg(kobj_to_w1_slave(kobj),
13689610274SJean-François Dagenais 		W1_F29_REG_CONTROL_AND_STATUS, buf);
13789610274SJean-François Dagenais }
13889610274SJean-François Dagenais 
1396660a04fSMariusz Bialonczyk #ifdef CONFIG_W1_SLAVE_DS2408_READBACK
optional_read_back_valid(struct w1_slave * sl,u8 expected)14049695ac4SJean-Francois Dagenais static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
14149695ac4SJean-Francois Dagenais {
14249695ac4SJean-Francois Dagenais 	u8 w1_buf[3];
14349695ac4SJean-Francois Dagenais 
14449695ac4SJean-Francois Dagenais 	if (w1_reset_resume_command(sl->master))
14549695ac4SJean-Francois Dagenais 		return false;
14649695ac4SJean-Francois Dagenais 
14749695ac4SJean-Francois Dagenais 	w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
14849695ac4SJean-Francois Dagenais 	w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE;
14949695ac4SJean-Francois Dagenais 	w1_buf[2] = 0;
15049695ac4SJean-Francois Dagenais 
15149695ac4SJean-Francois Dagenais 	w1_write_block(sl->master, w1_buf, 3);
15249695ac4SJean-Francois Dagenais 
15349695ac4SJean-Francois Dagenais 	return (w1_read_8(sl->master) == expected);
15449695ac4SJean-Francois Dagenais }
15549695ac4SJean-Francois Dagenais #else
optional_read_back_valid(struct w1_slave * sl,u8 expected)15649695ac4SJean-Francois Dagenais static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
15749695ac4SJean-Francois Dagenais {
15849695ac4SJean-Francois Dagenais 	return true;
15949695ac4SJean-Francois Dagenais }
16049695ac4SJean-Francois Dagenais #endif
16149695ac4SJean-Francois Dagenais 
output_write(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)16232ea4175SGreg Kroah-Hartman static ssize_t output_write(struct file *filp, struct kobject *kobj,
16332ea4175SGreg Kroah-Hartman 			    struct bin_attribute *bin_attr, char *buf,
16432ea4175SGreg Kroah-Hartman 			    loff_t off, size_t count)
16589610274SJean-François Dagenais {
16689610274SJean-François Dagenais 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
16789610274SJean-François Dagenais 	u8 w1_buf[3];
16889610274SJean-François Dagenais 	unsigned int retries = W1_F29_RETRIES;
16949695ac4SJean-Francois Dagenais 	ssize_t bytes_written = -EIO;
17089610274SJean-François Dagenais 
17189610274SJean-François Dagenais 	if (count != 1 || off != 0)
17289610274SJean-François Dagenais 		return -EFAULT;
17389610274SJean-François Dagenais 
17489610274SJean-François Dagenais 	dev_dbg(&sl->dev, "locking mutex for write_output");
175b02f8bedSNeilBrown 	mutex_lock(&sl->master->bus_mutex);
17689610274SJean-François Dagenais 	dev_dbg(&sl->dev, "mutex locked");
17789610274SJean-François Dagenais 
17889610274SJean-François Dagenais 	if (w1_reset_select_slave(sl))
17949695ac4SJean-Francois Dagenais 		goto out;
18089610274SJean-François Dagenais 
18149695ac4SJean-Francois Dagenais 	do {
18289610274SJean-François Dagenais 		w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
18389610274SJean-François Dagenais 		w1_buf[1] = *buf;
18489610274SJean-François Dagenais 		w1_buf[2] = ~(*buf);
18549695ac4SJean-Francois Dagenais 
18689610274SJean-François Dagenais 		w1_write_block(sl->master, w1_buf, 3);
18789610274SJean-François Dagenais 
18849695ac4SJean-Francois Dagenais 		if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE &&
18949695ac4SJean-Francois Dagenais 		    optional_read_back_valid(sl, *buf)) {
19049695ac4SJean-Francois Dagenais 			bytes_written = 1;
19149695ac4SJean-Francois Dagenais 			goto out;
19249695ac4SJean-Francois Dagenais 		}
193aceca285SJean-Francois Dagenais 
194aceca285SJean-Francois Dagenais 		if (w1_reset_resume_command(sl->master))
19549695ac4SJean-Francois Dagenais 			goto out; /* unrecoverable error */
196aceca285SJean-Francois Dagenais 		/* try again, the slave is ready for a command */
19749695ac4SJean-Francois Dagenais 	} while (--retries);
198aceca285SJean-Francois Dagenais 
19949695ac4SJean-Francois Dagenais out:
200b02f8bedSNeilBrown 	mutex_unlock(&sl->master->bus_mutex);
20189610274SJean-François Dagenais 
20249695ac4SJean-Francois Dagenais 	dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n",
20349695ac4SJean-Francois Dagenais 		(bytes_written > 0) ? "succeeded" : "error", retries);
20449695ac4SJean-Francois Dagenais 
20549695ac4SJean-Francois Dagenais 	return bytes_written;
20689610274SJean-François Dagenais }
20789610274SJean-François Dagenais 
20889610274SJean-François Dagenais 
20945c85d97SKrzysztof Kozlowski /*
21089610274SJean-François Dagenais  * Writing to the activity file resets the activity latches.
21189610274SJean-François Dagenais  */
activity_write(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)21232ea4175SGreg Kroah-Hartman static ssize_t activity_write(struct file *filp, struct kobject *kobj,
21332ea4175SGreg Kroah-Hartman 			      struct bin_attribute *bin_attr, char *buf,
21432ea4175SGreg Kroah-Hartman 			      loff_t off, size_t count)
21589610274SJean-François Dagenais {
21689610274SJean-François Dagenais 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
21789610274SJean-François Dagenais 	unsigned int retries = W1_F29_RETRIES;
21889610274SJean-François Dagenais 
21989610274SJean-François Dagenais 	if (count != 1 || off != 0)
22089610274SJean-François Dagenais 		return -EFAULT;
22189610274SJean-François Dagenais 
222b02f8bedSNeilBrown 	mutex_lock(&sl->master->bus_mutex);
22389610274SJean-François Dagenais 
22489610274SJean-François Dagenais 	if (w1_reset_select_slave(sl))
22589610274SJean-François Dagenais 		goto error;
22689610274SJean-François Dagenais 
22789610274SJean-François Dagenais 	while (retries--) {
22889610274SJean-François Dagenais 		w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES);
22989610274SJean-François Dagenais 		if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) {
230b02f8bedSNeilBrown 			mutex_unlock(&sl->master->bus_mutex);
23189610274SJean-François Dagenais 			return 1;
23289610274SJean-François Dagenais 		}
23389610274SJean-François Dagenais 		if (w1_reset_resume_command(sl->master))
23489610274SJean-François Dagenais 			goto error;
23589610274SJean-François Dagenais 	}
23689610274SJean-François Dagenais 
23789610274SJean-François Dagenais error:
238b02f8bedSNeilBrown 	mutex_unlock(&sl->master->bus_mutex);
23989610274SJean-François Dagenais 	return -EIO;
24089610274SJean-François Dagenais }
24189610274SJean-François Dagenais 
status_control_write(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t off,size_t count)24232ea4175SGreg Kroah-Hartman static ssize_t status_control_write(struct file *filp, struct kobject *kobj,
24332ea4175SGreg Kroah-Hartman 				    struct bin_attribute *bin_attr, char *buf,
24432ea4175SGreg Kroah-Hartman 				    loff_t off, size_t count)
24589610274SJean-François Dagenais {
24689610274SJean-François Dagenais 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
24789610274SJean-François Dagenais 	u8 w1_buf[4];
24889610274SJean-François Dagenais 	unsigned int retries = W1_F29_RETRIES;
24989610274SJean-François Dagenais 
25089610274SJean-François Dagenais 	if (count != 1 || off != 0)
25189610274SJean-François Dagenais 		return -EFAULT;
25289610274SJean-François Dagenais 
253b02f8bedSNeilBrown 	mutex_lock(&sl->master->bus_mutex);
25489610274SJean-François Dagenais 
25589610274SJean-François Dagenais 	if (w1_reset_select_slave(sl))
25689610274SJean-François Dagenais 		goto error;
25789610274SJean-François Dagenais 
25889610274SJean-François Dagenais 	while (retries--) {
25989610274SJean-François Dagenais 		w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
26089610274SJean-François Dagenais 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
26189610274SJean-François Dagenais 		w1_buf[2] = 0;
26289610274SJean-François Dagenais 		w1_buf[3] = *buf;
26389610274SJean-François Dagenais 
26489610274SJean-François Dagenais 		w1_write_block(sl->master, w1_buf, 4);
26589610274SJean-François Dagenais 		if (w1_reset_resume_command(sl->master))
26689610274SJean-François Dagenais 			goto error;
26789610274SJean-François Dagenais 
26889610274SJean-François Dagenais 		w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
26989610274SJean-François Dagenais 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
27089610274SJean-François Dagenais 		w1_buf[2] = 0;
27189610274SJean-François Dagenais 
27289610274SJean-François Dagenais 		w1_write_block(sl->master, w1_buf, 3);
27389610274SJean-François Dagenais 		if (w1_read_8(sl->master) == *buf) {
27489610274SJean-François Dagenais 			/* success! */
275b02f8bedSNeilBrown 			mutex_unlock(&sl->master->bus_mutex);
27689610274SJean-François Dagenais 			return 1;
27789610274SJean-François Dagenais 		}
27889610274SJean-François Dagenais 	}
27989610274SJean-François Dagenais error:
280b02f8bedSNeilBrown 	mutex_unlock(&sl->master->bus_mutex);
28189610274SJean-François Dagenais 
28289610274SJean-François Dagenais 	return -EIO;
28389610274SJean-François Dagenais }
28489610274SJean-François Dagenais 
285d5528773SJean-Francois Dagenais /*
286d5528773SJean-Francois Dagenais  * This is a special sequence we must do to ensure the P0 output is not stuck
287d5528773SJean-Francois Dagenais  * in test mode. This is described in rev 2 of the ds2408's datasheet
288d5528773SJean-Francois Dagenais  * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
289d5528773SJean-Francois Dagenais  * "APPLICATION INFORMATION/Power-up timing".
290d5528773SJean-Francois Dagenais  */
w1_f29_disable_test_mode(struct w1_slave * sl)291d5528773SJean-Francois Dagenais static int w1_f29_disable_test_mode(struct w1_slave *sl)
292d5528773SJean-Francois Dagenais {
293d5528773SJean-Francois Dagenais 	int res;
294d5528773SJean-Francois Dagenais 	u8 magic[10] = {0x96, };
295d5528773SJean-Francois Dagenais 	u64 rn = le64_to_cpu(*((u64 *)&sl->reg_num));
29689610274SJean-François Dagenais 
297d5528773SJean-Francois Dagenais 	memcpy(&magic[1], &rn, 8);
298d5528773SJean-Francois Dagenais 	magic[9] = 0x3C;
299d5528773SJean-Francois Dagenais 
300d5528773SJean-Francois Dagenais 	mutex_lock(&sl->master->bus_mutex);
301d5528773SJean-Francois Dagenais 
302d5528773SJean-Francois Dagenais 	res = w1_reset_bus(sl->master);
303d5528773SJean-Francois Dagenais 	if (res)
304d5528773SJean-Francois Dagenais 		goto out;
305d5528773SJean-Francois Dagenais 	w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
306d5528773SJean-Francois Dagenais 
307d5528773SJean-Francois Dagenais 	res = w1_reset_bus(sl->master);
308d5528773SJean-Francois Dagenais out:
309d5528773SJean-Francois Dagenais 	mutex_unlock(&sl->master->bus_mutex);
310d5528773SJean-Francois Dagenais 	return res;
311d5528773SJean-Francois Dagenais }
31289610274SJean-François Dagenais 
31332ea4175SGreg Kroah-Hartman static BIN_ATTR_RO(state, 1);
31432ea4175SGreg Kroah-Hartman static BIN_ATTR_RW(output, 1);
31532ea4175SGreg Kroah-Hartman static BIN_ATTR_RW(activity, 1);
31632ea4175SGreg Kroah-Hartman static BIN_ATTR_RO(cond_search_mask, 1);
31732ea4175SGreg Kroah-Hartman static BIN_ATTR_RO(cond_search_polarity, 1);
31832ea4175SGreg Kroah-Hartman static BIN_ATTR_RW(status_control, 1);
31932ea4175SGreg Kroah-Hartman 
32032ea4175SGreg Kroah-Hartman static struct bin_attribute *w1_f29_bin_attrs[] = {
32132ea4175SGreg Kroah-Hartman 	&bin_attr_state,
32232ea4175SGreg Kroah-Hartman 	&bin_attr_output,
32332ea4175SGreg Kroah-Hartman 	&bin_attr_activity,
32432ea4175SGreg Kroah-Hartman 	&bin_attr_cond_search_mask,
32532ea4175SGreg Kroah-Hartman 	&bin_attr_cond_search_polarity,
32632ea4175SGreg Kroah-Hartman 	&bin_attr_status_control,
32732ea4175SGreg Kroah-Hartman 	NULL,
32889610274SJean-François Dagenais };
32989610274SJean-François Dagenais 
33032ea4175SGreg Kroah-Hartman static const struct attribute_group w1_f29_group = {
33132ea4175SGreg Kroah-Hartman 	.bin_attrs = w1_f29_bin_attrs,
33232ea4175SGreg Kroah-Hartman };
33389610274SJean-François Dagenais 
33432ea4175SGreg Kroah-Hartman static const struct attribute_group *w1_f29_groups[] = {
33532ea4175SGreg Kroah-Hartman 	&w1_f29_group,
33632ea4175SGreg Kroah-Hartman 	NULL,
33732ea4175SGreg Kroah-Hartman };
33889610274SJean-François Dagenais 
33957de2dfcSRikard Falkeborn static const struct w1_family_ops w1_f29_fops = {
34032ea4175SGreg Kroah-Hartman 	.add_slave      = w1_f29_disable_test_mode,
34132ea4175SGreg Kroah-Hartman 	.groups		= w1_f29_groups,
34289610274SJean-François Dagenais };
34389610274SJean-François Dagenais 
34489610274SJean-François Dagenais static struct w1_family w1_family_29 = {
34589610274SJean-François Dagenais 	.fid = W1_FAMILY_DS2408,
34689610274SJean-François Dagenais 	.fops = &w1_f29_fops,
34789610274SJean-François Dagenais };
348939fc832SAndrew F. Davis module_w1_family(w1_family_29);
34950fa2951SAndrew F. Davis 
35050fa2951SAndrew F. Davis MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>");
35150fa2951SAndrew F. Davis MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO");
35250fa2951SAndrew F. Davis MODULE_LICENSE("GPL");
35350fa2951SAndrew F. Davis MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408));
354