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