2 * Register map access API - W1 (1-Wire) support
4 * Copyright (c) 2017 Radioavionica Corporation
5 * Author: Alex A. Mihaylov <minimumlaw@rambler.ru>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation
12 #include <linux/regmap.h>
13 #include <linux/module.h>
18 #define W1_CMD_READ_DATA 0x69
19 #define W1_CMD_WRITE_DATA 0x6C
22 * 1-Wire slaves registers with addess 8 bit and data 8 bit
25 static int w1_reg_a8_v8_read(void *context
, unsigned int reg
, unsigned int *val
)
27 struct device
*dev
= context
;
28 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
34 mutex_lock(&sl
->master
->bus_mutex
);
35 if (!w1_reset_select_slave(sl
)) {
36 w1_write_8(sl
->master
, W1_CMD_READ_DATA
);
37 w1_write_8(sl
->master
, reg
);
38 *val
= w1_read_8(sl
->master
);
42 mutex_unlock(&sl
->master
->bus_mutex
);
47 static int w1_reg_a8_v8_write(void *context
, unsigned int reg
, unsigned int val
)
49 struct device
*dev
= context
;
50 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
56 mutex_lock(&sl
->master
->bus_mutex
);
57 if (!w1_reset_select_slave(sl
)) {
58 w1_write_8(sl
->master
, W1_CMD_WRITE_DATA
);
59 w1_write_8(sl
->master
, reg
);
60 w1_write_8(sl
->master
, val
);
64 mutex_unlock(&sl
->master
->bus_mutex
);
70 * 1-Wire slaves registers with addess 8 bit and data 16 bit
73 static int w1_reg_a8_v16_read(void *context
, unsigned int reg
,
76 struct device
*dev
= context
;
77 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
83 mutex_lock(&sl
->master
->bus_mutex
);
84 if (!w1_reset_select_slave(sl
)) {
85 w1_write_8(sl
->master
, W1_CMD_READ_DATA
);
86 w1_write_8(sl
->master
, reg
);
87 *val
= w1_read_8(sl
->master
);
88 *val
|= w1_read_8(sl
->master
)<<8;
92 mutex_unlock(&sl
->master
->bus_mutex
);
97 static int w1_reg_a8_v16_write(void *context
, unsigned int reg
,
100 struct device
*dev
= context
;
101 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
107 mutex_lock(&sl
->master
->bus_mutex
);
108 if (!w1_reset_select_slave(sl
)) {
109 w1_write_8(sl
->master
, W1_CMD_WRITE_DATA
);
110 w1_write_8(sl
->master
, reg
);
111 w1_write_8(sl
->master
, val
& 0x00FF);
112 w1_write_8(sl
->master
, val
>>8 & 0x00FF);
116 mutex_unlock(&sl
->master
->bus_mutex
);
122 * 1-Wire slaves registers with addess 16 bit and data 16 bit
125 static int w1_reg_a16_v16_read(void *context
, unsigned int reg
,
128 struct device
*dev
= context
;
129 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
135 mutex_lock(&sl
->master
->bus_mutex
);
136 if (!w1_reset_select_slave(sl
)) {
137 w1_write_8(sl
->master
, W1_CMD_READ_DATA
);
138 w1_write_8(sl
->master
, reg
& 0x00FF);
139 w1_write_8(sl
->master
, reg
>>8 & 0x00FF);
140 *val
= w1_read_8(sl
->master
);
141 *val
|= w1_read_8(sl
->master
)<<8;
145 mutex_unlock(&sl
->master
->bus_mutex
);
150 static int w1_reg_a16_v16_write(void *context
, unsigned int reg
,
153 struct device
*dev
= context
;
154 struct w1_slave
*sl
= container_of(dev
, struct w1_slave
, dev
);
160 mutex_lock(&sl
->master
->bus_mutex
);
161 if (!w1_reset_select_slave(sl
)) {
162 w1_write_8(sl
->master
, W1_CMD_WRITE_DATA
);
163 w1_write_8(sl
->master
, reg
& 0x00FF);
164 w1_write_8(sl
->master
, reg
>>8 & 0x00FF);
165 w1_write_8(sl
->master
, val
& 0x00FF);
166 w1_write_8(sl
->master
, val
>>8 & 0x00FF);
170 mutex_unlock(&sl
->master
->bus_mutex
);
176 * Various types of supported bus addressing
179 static struct regmap_bus regmap_w1_bus_a8_v8
= {
180 .reg_read
= w1_reg_a8_v8_read
,
181 .reg_write
= w1_reg_a8_v8_write
,
184 static struct regmap_bus regmap_w1_bus_a8_v16
= {
185 .reg_read
= w1_reg_a8_v16_read
,
186 .reg_write
= w1_reg_a8_v16_write
,
189 static struct regmap_bus regmap_w1_bus_a16_v16
= {
190 .reg_read
= w1_reg_a16_v16_read
,
191 .reg_write
= w1_reg_a16_v16_write
,
194 static const struct regmap_bus
*regmap_get_w1_bus(struct device
*w1_dev
,
195 const struct regmap_config
*config
)
197 if (config
->reg_bits
== 8 && config
->val_bits
== 8)
198 return ®map_w1_bus_a8_v8
;
200 if (config
->reg_bits
== 8 && config
->val_bits
== 16)
201 return ®map_w1_bus_a8_v16
;
203 if (config
->reg_bits
== 16 && config
->val_bits
== 16)
204 return ®map_w1_bus_a16_v16
;
206 return ERR_PTR(-ENOTSUPP
);
209 struct regmap
*__regmap_init_w1(struct device
*w1_dev
,
210 const struct regmap_config
*config
,
211 struct lock_class_key
*lock_key
,
212 const char *lock_name
)
215 const struct regmap_bus
*bus
= regmap_get_w1_bus(w1_dev
, config
);
218 return ERR_CAST(bus
);
220 return __regmap_init(w1_dev
, bus
, w1_dev
, config
,
221 lock_key
, lock_name
);
225 EXPORT_SYMBOL_GPL(__regmap_init_w1
);
227 struct regmap
*__devm_regmap_init_w1(struct device
*w1_dev
,
228 const struct regmap_config
*config
,
229 struct lock_class_key
*lock_key
,
230 const char *lock_name
)
233 const struct regmap_bus
*bus
= regmap_get_w1_bus(w1_dev
, config
);
236 return ERR_CAST(bus
);
238 return __devm_regmap_init(w1_dev
, bus
, w1_dev
, config
,
239 lock_key
, lock_name
);
243 EXPORT_SYMBOL_GPL(__devm_regmap_init_w1
);
245 MODULE_LICENSE("GPL");