1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * w1_ds250x.c - w1 family 09/0b/89/91 (DS250x) driver 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/moduleparam.h> 9 #include <linux/device.h> 10 #include <linux/types.h> 11 #include <linux/delay.h> 12 #include <linux/slab.h> 13 #include <linux/crc16.h> 14 15 #include <linux/w1.h> 16 #include <linux/nvmem-provider.h> 17 18 #define W1_DS2501_UNW_FAMILY 0x91 19 #define W1_DS2501_SIZE 64 20 21 #define W1_DS2502_FAMILY 0x09 22 #define W1_DS2502_UNW_FAMILY 0x89 23 #define W1_DS2502_SIZE 128 24 25 #define W1_DS2505_FAMILY 0x0b 26 #define W1_DS2505_SIZE 2048 27 28 #define W1_PAGE_SIZE 32 29 30 #define W1_EXT_READ_MEMORY 0xA5 31 #define W1_READ_DATA_CRC 0xC3 32 33 #define OFF2PG(off) ((off) / W1_PAGE_SIZE) 34 35 #define CRC16_INIT 0 36 #define CRC16_VALID 0xb001 37 38 struct w1_eprom_data { 39 size_t size; 40 int (*read)(struct w1_slave *sl, int pageno); 41 u8 eprom[W1_DS2505_SIZE]; 42 DECLARE_BITMAP(page_present, W1_DS2505_SIZE / W1_PAGE_SIZE); 43 char nvmem_name[64]; 44 }; 45 46 static int w1_ds2502_read_page(struct w1_slave *sl, int pageno) 47 { 48 struct w1_eprom_data *data = sl->family_data; 49 int pgoff = pageno * W1_PAGE_SIZE; 50 int ret = -EIO; 51 u8 buf[3]; 52 u8 crc8; 53 54 if (test_bit(pageno, data->page_present)) 55 return 0; /* page already present */ 56 57 mutex_lock(&sl->master->bus_mutex); 58 59 if (w1_reset_select_slave(sl)) 60 goto err; 61 62 buf[0] = W1_READ_DATA_CRC; 63 buf[1] = pgoff & 0xff; 64 buf[2] = pgoff >> 8; 65 w1_write_block(sl->master, buf, 3); 66 67 crc8 = w1_read_8(sl->master); 68 if (w1_calc_crc8(buf, 3) != crc8) 69 goto err; 70 71 w1_read_block(sl->master, &data->eprom[pgoff], W1_PAGE_SIZE); 72 73 crc8 = w1_read_8(sl->master); 74 if (w1_calc_crc8(&data->eprom[pgoff], W1_PAGE_SIZE) != crc8) 75 goto err; 76 77 set_bit(pageno, data->page_present); /* mark page present */ 78 ret = 0; 79 err: 80 mutex_unlock(&sl->master->bus_mutex); 81 return ret; 82 } 83 84 static int w1_ds2505_read_page(struct w1_slave *sl, int pageno) 85 { 86 struct w1_eprom_data *data = sl->family_data; 87 int redir_retries = 16; 88 int pgoff, epoff; 89 int ret = -EIO; 90 u8 buf[6]; 91 u8 redir; 92 u16 crc; 93 94 if (test_bit(pageno, data->page_present)) 95 return 0; /* page already present */ 96 97 epoff = pgoff = pageno * W1_PAGE_SIZE; 98 mutex_lock(&sl->master->bus_mutex); 99 100 retry: 101 if (w1_reset_select_slave(sl)) 102 goto err; 103 104 buf[0] = W1_EXT_READ_MEMORY; 105 buf[1] = pgoff & 0xff; 106 buf[2] = pgoff >> 8; 107 w1_write_block(sl->master, buf, 3); 108 w1_read_block(sl->master, buf + 3, 3); /* redir, crc16 */ 109 redir = buf[3]; 110 crc = crc16(CRC16_INIT, buf, 6); 111 112 if (crc != CRC16_VALID) 113 goto err; 114 115 116 if (redir != 0xff) { 117 redir_retries--; 118 if (redir_retries < 0) 119 goto err; 120 121 pgoff = (redir ^ 0xff) * W1_PAGE_SIZE; 122 goto retry; 123 } 124 125 w1_read_block(sl->master, &data->eprom[epoff], W1_PAGE_SIZE); 126 w1_read_block(sl->master, buf, 2); /* crc16 */ 127 crc = crc16(CRC16_INIT, &data->eprom[epoff], W1_PAGE_SIZE); 128 crc = crc16(crc, buf, 2); 129 130 if (crc != CRC16_VALID) 131 goto err; 132 133 set_bit(pageno, data->page_present); 134 ret = 0; 135 err: 136 mutex_unlock(&sl->master->bus_mutex); 137 return ret; 138 } 139 140 static int w1_nvmem_read(void *priv, unsigned int off, void *buf, size_t count) 141 { 142 struct w1_slave *sl = priv; 143 struct w1_eprom_data *data = sl->family_data; 144 size_t eprom_size = data->size; 145 int ret; 146 int i; 147 148 if (off > eprom_size) 149 return -EINVAL; 150 151 if ((off + count) > eprom_size) 152 count = eprom_size - off; 153 154 i = OFF2PG(off); 155 do { 156 ret = data->read(sl, i++); 157 if (ret < 0) 158 return ret; 159 } while (i < OFF2PG(off + count)); 160 161 memcpy(buf, &data->eprom[off], count); 162 return 0; 163 } 164 165 static int w1_eprom_add_slave(struct w1_slave *sl) 166 { 167 struct w1_eprom_data *data; 168 struct nvmem_device *nvmem; 169 struct nvmem_config nvmem_cfg = { 170 .dev = &sl->dev, 171 .add_legacy_fixed_of_cells = true, 172 .reg_read = w1_nvmem_read, 173 .type = NVMEM_TYPE_OTP, 174 .read_only = true, 175 .word_size = 1, 176 .priv = sl, 177 .id = -1 178 }; 179 180 data = devm_kzalloc(&sl->dev, sizeof(struct w1_eprom_data), GFP_KERNEL); 181 if (!data) 182 return -ENOMEM; 183 184 sl->family_data = data; 185 switch (sl->family->fid) { 186 case W1_DS2501_UNW_FAMILY: 187 data->size = W1_DS2501_SIZE; 188 data->read = w1_ds2502_read_page; 189 break; 190 case W1_DS2502_FAMILY: 191 case W1_DS2502_UNW_FAMILY: 192 data->size = W1_DS2502_SIZE; 193 data->read = w1_ds2502_read_page; 194 break; 195 case W1_DS2505_FAMILY: 196 data->size = W1_DS2505_SIZE; 197 data->read = w1_ds2505_read_page; 198 break; 199 } 200 201 if (sl->master->bus_master->dev_id) 202 snprintf(data->nvmem_name, sizeof(data->nvmem_name), 203 "%s-%02x-%012llx", 204 sl->master->bus_master->dev_id, sl->reg_num.family, 205 (unsigned long long)sl->reg_num.id); 206 else 207 snprintf(data->nvmem_name, sizeof(data->nvmem_name), 208 "%02x-%012llx", 209 sl->reg_num.family, 210 (unsigned long long)sl->reg_num.id); 211 212 nvmem_cfg.name = data->nvmem_name; 213 nvmem_cfg.size = data->size; 214 215 nvmem = devm_nvmem_register(&sl->dev, &nvmem_cfg); 216 return PTR_ERR_OR_ZERO(nvmem); 217 } 218 219 static const struct w1_family_ops w1_eprom_fops = { 220 .add_slave = w1_eprom_add_slave, 221 }; 222 223 static struct w1_family w1_family_09 = { 224 .fid = W1_DS2502_FAMILY, 225 .fops = &w1_eprom_fops, 226 }; 227 228 static struct w1_family w1_family_0b = { 229 .fid = W1_DS2505_FAMILY, 230 .fops = &w1_eprom_fops, 231 }; 232 233 static struct w1_family w1_family_89 = { 234 .fid = W1_DS2502_UNW_FAMILY, 235 .fops = &w1_eprom_fops, 236 }; 237 238 static struct w1_family w1_family_91 = { 239 .fid = W1_DS2501_UNW_FAMILY, 240 .fops = &w1_eprom_fops, 241 }; 242 243 static int __init w1_ds250x_init(void) 244 { 245 int err; 246 247 err = w1_register_family(&w1_family_09); 248 if (err) 249 return err; 250 251 err = w1_register_family(&w1_family_0b); 252 if (err) 253 goto err_0b; 254 255 err = w1_register_family(&w1_family_89); 256 if (err) 257 goto err_89; 258 259 err = w1_register_family(&w1_family_91); 260 if (err) 261 goto err_91; 262 263 return 0; 264 265 err_91: 266 w1_unregister_family(&w1_family_89); 267 err_89: 268 w1_unregister_family(&w1_family_0b); 269 err_0b: 270 w1_unregister_family(&w1_family_09); 271 return err; 272 } 273 274 static void __exit w1_ds250x_exit(void) 275 { 276 w1_unregister_family(&w1_family_09); 277 w1_unregister_family(&w1_family_0b); 278 w1_unregister_family(&w1_family_89); 279 w1_unregister_family(&w1_family_91); 280 } 281 282 module_init(w1_ds250x_init); 283 module_exit(w1_ds250x_exit); 284 285 MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfe@suse.de>"); 286 MODULE_DESCRIPTION("w1 family driver for DS250x Add Only Memory"); 287 MODULE_LICENSE("GPL"); 288 MODULE_ALIAS("w1-family-" __stringify(W1_DS2502_FAMILY)); 289 MODULE_ALIAS("w1-family-" __stringify(W1_DS2505_FAMILY)); 290 MODULE_ALIAS("w1-family-" __stringify(W1_DS2501_UNW_FAMILY)); 291 MODULE_ALIAS("w1-family-" __stringify(W1_DS2502_UNW_FAMILY)); 292