1 // SPDX-License-Identifier: GPL-2.0
3 // Register map access API - W1 (1-Wire) support
5 // Copyright (c) 2017 Radioavionica Corporation
6 // Author: Alex A. Mihaylov <minimumlaw@rambler.ru>
8 #include <linux/regmap.h>
9 #include <linux/module.h>
14 #define W1_CMD_READ_DATA 0x69
15 #define W1_CMD_WRITE_DATA 0x6C
18 * 1-Wire slaves registers with addess 8 bit and data 8 bit
21 static int w1_reg_a8_v8_read(void *context
, unsigned int reg
, unsigned int *val
)
23 struct device
*dev
= context
;
24 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
30 mutex_lock(&sl
->master
->bus_mutex
);
31 if (!w1_reset_select_slave(sl
)) {
32 w1_write_8(sl
->master
, W1_CMD_READ_DATA
);
33 w1_write_8(sl
->master
, reg
);
34 *val
= w1_read_8(sl
->master
);
38 mutex_unlock(&sl
->master
->bus_mutex
);
43 static int w1_reg_a8_v8_write(void *context
, unsigned int reg
, unsigned int val
)
45 struct device
*dev
= context
;
46 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
52 mutex_lock(&sl
->master
->bus_mutex
);
53 if (!w1_reset_select_slave(sl
)) {
54 w1_write_8(sl
->master
, W1_CMD_WRITE_DATA
);
55 w1_write_8(sl
->master
, reg
);
56 w1_write_8(sl
->master
, val
);
60 mutex_unlock(&sl
->master
->bus_mutex
);
66 * 1-Wire slaves registers with addess 8 bit and data 16 bit
69 static int w1_reg_a8_v16_read(void *context
, unsigned int reg
,
72 struct device
*dev
= context
;
73 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
79 mutex_lock(&sl
->master
->bus_mutex
);
80 if (!w1_reset_select_slave(sl
)) {
81 w1_write_8(sl
->master
, W1_CMD_READ_DATA
);
82 w1_write_8(sl
->master
, reg
);
83 *val
= w1_read_8(sl
->master
);
84 *val
|= w1_read_8(sl
->master
)<<8;
88 mutex_unlock(&sl
->master
->bus_mutex
);
93 static int w1_reg_a8_v16_write(void *context
, unsigned int reg
,
96 struct device
*dev
= context
;
97 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
103 mutex_lock(&sl
->master
->bus_mutex
);
104 if (!w1_reset_select_slave(sl
)) {
105 w1_write_8(sl
->master
, W1_CMD_WRITE_DATA
);
106 w1_write_8(sl
->master
, reg
);
107 w1_write_8(sl
->master
, val
& 0x00FF);
108 w1_write_8(sl
->master
, val
>>8 & 0x00FF);
112 mutex_unlock(&sl
->master
->bus_mutex
);
118 * 1-Wire slaves registers with addess 16 bit and data 16 bit
121 static int w1_reg_a16_v16_read(void *context
, unsigned int reg
,
124 struct device
*dev
= context
;
125 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
131 mutex_lock(&sl
->master
->bus_mutex
);
132 if (!w1_reset_select_slave(sl
)) {
133 w1_write_8(sl
->master
, W1_CMD_READ_DATA
);
134 w1_write_8(sl
->master
, reg
& 0x00FF);
135 w1_write_8(sl
->master
, reg
>>8 & 0x00FF);
136 *val
= w1_read_8(sl
->master
);
137 *val
|= w1_read_8(sl
->master
)<<8;
141 mutex_unlock(&sl
->master
->bus_mutex
);
146 static int w1_reg_a16_v16_write(void *context
, unsigned int reg
,
149 struct device
*dev
= context
;
150 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
156 mutex_lock(&sl
->master
->bus_mutex
);
157 if (!w1_reset_select_slave(sl
)) {
158 w1_write_8(sl
->master
, W1_CMD_WRITE_DATA
);
159 w1_write_8(sl
->master
, reg
& 0x00FF);
160 w1_write_8(sl
->master
, reg
>>8 & 0x00FF);
161 w1_write_8(sl
->master
, val
& 0x00FF);
162 w1_write_8(sl
->master
, val
>>8 & 0x00FF);
166 mutex_unlock(&sl
->master
->bus_mutex
);
172 * Various types of supported bus addressing
175 static struct regmap_bus regmap_w1_bus_a8_v8
= {
176 .reg_read
= w1_reg_a8_v8_read
,
177 .reg_write
= w1_reg_a8_v8_write
,
180 static struct regmap_bus regmap_w1_bus_a8_v16
= {
181 .reg_read
= w1_reg_a8_v16_read
,
182 .reg_write
= w1_reg_a8_v16_write
,
185 static struct regmap_bus regmap_w1_bus_a16_v16
= {
186 .reg_read
= w1_reg_a16_v16_read
,
187 .reg_write
= w1_reg_a16_v16_write
,
190 static const struct regmap_bus
*regmap_get_w1_bus(struct device
*w1_dev
,
191 const struct regmap_config
*config
)
193 if (config
->reg_bits
== 8 && config
->val_bits
== 8)
194 return ®map_w1_bus_a8_v8
;
196 if (config
->reg_bits
== 8 && config
->val_bits
== 16)
197 return ®map_w1_bus_a8_v16
;
199 if (config
->reg_bits
== 16 && config
->val_bits
== 16)
200 return ®map_w1_bus_a16_v16
;
202 return ERR_PTR(-ENOTSUPP
);
205 struct regmap
*__regmap_init_w1(struct device
*w1_dev
,
206 const struct regmap_config
*config
,
207 struct lock_class_key
*lock_key
,
208 const char *lock_name
)
211 const struct regmap_bus
*bus
= regmap_get_w1_bus(w1_dev
, config
);
214 return ERR_CAST(bus
);
216 return __regmap_init(w1_dev
, bus
, w1_dev
, config
,
217 lock_key
, lock_name
);
219 EXPORT_SYMBOL_GPL(__regmap_init_w1
);
221 struct regmap
*__devm_regmap_init_w1(struct device
*w1_dev
,
222 const struct regmap_config
*config
,
223 struct lock_class_key
*lock_key
,
224 const char *lock_name
)
227 const struct regmap_bus
*bus
= regmap_get_w1_bus(w1_dev
, config
);
230 return ERR_CAST(bus
);
232 return __devm_regmap_init(w1_dev
, bus
, w1_dev
, config
,
233 lock_key
, lock_name
);
235 EXPORT_SYMBOL_GPL(__devm_regmap_init_w1
);
237 MODULE_LICENSE("GPL");