0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/mfd/rave-sp.h>
0011 #include <linux/module.h>
0012 #include <linux/nvmem-provider.h>
0013 #include <linux/of_device.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/sizes.h>
0016
0017
0018
0019
0020
0021
0022
0023 enum rave_sp_eeprom_access_type {
0024 RAVE_SP_EEPROM_WRITE = 0,
0025 RAVE_SP_EEPROM_READ = 1,
0026 };
0027
0028
0029
0030
0031
0032
0033
0034 enum rave_sp_eeprom_header_size {
0035 RAVE_SP_EEPROM_HEADER_SMALL = 4U,
0036 RAVE_SP_EEPROM_HEADER_BIG = 5U,
0037 };
0038 #define RAVE_SP_EEPROM_HEADER_MAX RAVE_SP_EEPROM_HEADER_BIG
0039
0040 #define RAVE_SP_EEPROM_PAGE_SIZE 32U
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 struct rave_sp_eeprom_page {
0053 u8 type;
0054 u8 success;
0055 u8 data[RAVE_SP_EEPROM_PAGE_SIZE];
0056 } __packed;
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 struct rave_sp_eeprom {
0068 struct rave_sp *sp;
0069 struct mutex mutex;
0070 u8 address;
0071 unsigned int header_size;
0072 struct device *dev;
0073 };
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 static int rave_sp_eeprom_io(struct rave_sp_eeprom *eeprom,
0091 enum rave_sp_eeprom_access_type type,
0092 u16 idx,
0093 struct rave_sp_eeprom_page *page)
0094 {
0095 const bool is_write = type == RAVE_SP_EEPROM_WRITE;
0096 const unsigned int data_size = is_write ? sizeof(page->data) : 0;
0097 const unsigned int cmd_size = eeprom->header_size + data_size;
0098 const unsigned int rsp_size =
0099 is_write ? sizeof(*page) - sizeof(page->data) : sizeof(*page);
0100 unsigned int offset = 0;
0101 u8 cmd[RAVE_SP_EEPROM_HEADER_MAX + sizeof(page->data)];
0102 int ret;
0103
0104 if (WARN_ON(cmd_size > sizeof(cmd)))
0105 return -EINVAL;
0106
0107 cmd[offset++] = eeprom->address;
0108 cmd[offset++] = 0;
0109 cmd[offset++] = type;
0110 cmd[offset++] = idx;
0111
0112
0113
0114
0115
0116
0117 if (offset < eeprom->header_size)
0118 cmd[offset++] = idx >> 8;
0119
0120
0121
0122
0123
0124 memcpy(&cmd[offset], page->data, data_size);
0125
0126 ret = rave_sp_exec(eeprom->sp, cmd, cmd_size, page, rsp_size);
0127 if (ret)
0128 return ret;
0129
0130 if (page->type != type)
0131 return -EPROTO;
0132
0133 if (!page->success)
0134 return -EIO;
0135
0136 return 0;
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 static int
0156 rave_sp_eeprom_page_access(struct rave_sp_eeprom *eeprom,
0157 enum rave_sp_eeprom_access_type type,
0158 unsigned int offset, u8 *data,
0159 size_t data_len)
0160 {
0161 const unsigned int page_offset = offset % RAVE_SP_EEPROM_PAGE_SIZE;
0162 const unsigned int page_nr = offset / RAVE_SP_EEPROM_PAGE_SIZE;
0163 struct rave_sp_eeprom_page page;
0164 int ret;
0165
0166
0167
0168
0169
0170
0171
0172 if (WARN_ON(data_len > sizeof(page.data) - page_offset))
0173 return -EINVAL;
0174
0175 if (type == RAVE_SP_EEPROM_WRITE) {
0176
0177
0178
0179
0180 if (data_len < RAVE_SP_EEPROM_PAGE_SIZE) {
0181 ret = rave_sp_eeprom_io(eeprom, RAVE_SP_EEPROM_READ,
0182 page_nr, &page);
0183 if (ret)
0184 return ret;
0185 }
0186
0187 memcpy(&page.data[page_offset], data, data_len);
0188 }
0189
0190 ret = rave_sp_eeprom_io(eeprom, type, page_nr, &page);
0191 if (ret)
0192 return ret;
0193
0194
0195
0196
0197
0198 if (type == RAVE_SP_EEPROM_READ)
0199 memcpy(data, &page.data[page_offset], data_len);
0200
0201 return 0;
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 static int rave_sp_eeprom_access(struct rave_sp_eeprom *eeprom,
0221 enum rave_sp_eeprom_access_type type,
0222 unsigned int offset, u8 *data,
0223 unsigned int data_len)
0224 {
0225 unsigned int residue;
0226 unsigned int chunk;
0227 unsigned int head;
0228 int ret;
0229
0230 mutex_lock(&eeprom->mutex);
0231
0232 head = offset % RAVE_SP_EEPROM_PAGE_SIZE;
0233 residue = data_len;
0234
0235 do {
0236
0237
0238
0239
0240
0241
0242 if (unlikely(head)) {
0243 chunk = RAVE_SP_EEPROM_PAGE_SIZE - head;
0244
0245
0246
0247
0248
0249
0250 head = 0;
0251 } else {
0252 chunk = RAVE_SP_EEPROM_PAGE_SIZE;
0253 }
0254
0255
0256
0257
0258 chunk = min(chunk, residue);
0259 ret = rave_sp_eeprom_page_access(eeprom, type, offset,
0260 data, chunk);
0261 if (ret)
0262 goto out;
0263
0264 residue -= chunk;
0265 offset += chunk;
0266 data += chunk;
0267 } while (residue);
0268 out:
0269 mutex_unlock(&eeprom->mutex);
0270 return ret;
0271 }
0272
0273 static int rave_sp_eeprom_reg_read(void *eeprom, unsigned int offset,
0274 void *val, size_t bytes)
0275 {
0276 return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_READ,
0277 offset, val, bytes);
0278 }
0279
0280 static int rave_sp_eeprom_reg_write(void *eeprom, unsigned int offset,
0281 void *val, size_t bytes)
0282 {
0283 return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_WRITE,
0284 offset, val, bytes);
0285 }
0286
0287 static int rave_sp_eeprom_probe(struct platform_device *pdev)
0288 {
0289 struct device *dev = &pdev->dev;
0290 struct rave_sp *sp = dev_get_drvdata(dev->parent);
0291 struct device_node *np = dev->of_node;
0292 struct nvmem_config config = { 0 };
0293 struct rave_sp_eeprom *eeprom;
0294 struct nvmem_device *nvmem;
0295 u32 reg[2], size;
0296
0297 if (of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg))) {
0298 dev_err(dev, "Failed to parse \"reg\" property\n");
0299 return -EINVAL;
0300 }
0301
0302 size = reg[1];
0303
0304
0305
0306
0307 if (size > U16_MAX * RAVE_SP_EEPROM_PAGE_SIZE) {
0308 dev_err(dev, "Specified size is too big\n");
0309 return -EINVAL;
0310 }
0311
0312 eeprom = devm_kzalloc(dev, sizeof(*eeprom), GFP_KERNEL);
0313 if (!eeprom)
0314 return -ENOMEM;
0315
0316 eeprom->address = reg[0];
0317 eeprom->sp = sp;
0318 eeprom->dev = dev;
0319
0320 if (size > SZ_8K)
0321 eeprom->header_size = RAVE_SP_EEPROM_HEADER_BIG;
0322 else
0323 eeprom->header_size = RAVE_SP_EEPROM_HEADER_SMALL;
0324
0325 mutex_init(&eeprom->mutex);
0326
0327 config.id = -1;
0328 of_property_read_string(np, "zii,eeprom-name", &config.name);
0329 config.priv = eeprom;
0330 config.dev = dev;
0331 config.size = size;
0332 config.reg_read = rave_sp_eeprom_reg_read;
0333 config.reg_write = rave_sp_eeprom_reg_write;
0334 config.word_size = 1;
0335 config.stride = 1;
0336
0337 nvmem = devm_nvmem_register(dev, &config);
0338
0339 return PTR_ERR_OR_ZERO(nvmem);
0340 }
0341
0342 static const struct of_device_id rave_sp_eeprom_of_match[] = {
0343 { .compatible = "zii,rave-sp-eeprom" },
0344 {}
0345 };
0346 MODULE_DEVICE_TABLE(of, rave_sp_eeprom_of_match);
0347
0348 static struct platform_driver rave_sp_eeprom_driver = {
0349 .probe = rave_sp_eeprom_probe,
0350 .driver = {
0351 .name = KBUILD_MODNAME,
0352 .of_match_table = rave_sp_eeprom_of_match,
0353 },
0354 };
0355 module_platform_driver(rave_sp_eeprom_driver);
0356
0357 MODULE_LICENSE("GPL");
0358 MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
0359 MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
0360 MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
0361 MODULE_DESCRIPTION("RAVE SP EEPROM driver");