diff options
Diffstat (limited to 'drivers/misc/eeprom/eeprom_93xx46.c')
| -rw-r--r-- | drivers/misc/eeprom/eeprom_93xx46.c | 92 |
1 files changed, 19 insertions, 73 deletions
diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 426fe2fd5238..94cc035aa841 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| 22 | #include <linux/nvmem-provider.h> | 22 | #include <linux/nvmem-provider.h> |
| 23 | #include <linux/regmap.h> | ||
| 24 | #include <linux/eeprom_93xx46.h> | 23 | #include <linux/eeprom_93xx46.h> |
| 25 | 24 | ||
| 26 | #define OP_START 0x4 | 25 | #define OP_START 0x4 |
| @@ -43,7 +42,6 @@ struct eeprom_93xx46_dev { | |||
| 43 | struct spi_device *spi; | 42 | struct spi_device *spi; |
| 44 | struct eeprom_93xx46_platform_data *pdata; | 43 | struct eeprom_93xx46_platform_data *pdata; |
| 45 | struct mutex lock; | 44 | struct mutex lock; |
| 46 | struct regmap_config regmap_config; | ||
| 47 | struct nvmem_config nvmem_config; | 45 | struct nvmem_config nvmem_config; |
| 48 | struct nvmem_device *nvmem; | 46 | struct nvmem_device *nvmem; |
| 49 | int addrlen; | 47 | int addrlen; |
| @@ -60,11 +58,12 @@ static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) | |||
| 60 | return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; | 58 | return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; |
| 61 | } | 59 | } |
| 62 | 60 | ||
| 63 | static ssize_t | 61 | static int eeprom_93xx46_read(void *priv, unsigned int off, |
| 64 | eeprom_93xx46_read(struct eeprom_93xx46_dev *edev, char *buf, | 62 | void *val, size_t count) |
| 65 | unsigned off, size_t count) | ||
| 66 | { | 63 | { |
| 67 | ssize_t ret = 0; | 64 | struct eeprom_93xx46_dev *edev = priv; |
| 65 | char *buf = val; | ||
| 66 | int err = 0; | ||
| 68 | 67 | ||
| 69 | if (unlikely(off >= edev->size)) | 68 | if (unlikely(off >= edev->size)) |
| 70 | return 0; | 69 | return 0; |
| @@ -84,7 +83,6 @@ eeprom_93xx46_read(struct eeprom_93xx46_dev *edev, char *buf, | |||
| 84 | u16 cmd_addr = OP_READ << edev->addrlen; | 83 | u16 cmd_addr = OP_READ << edev->addrlen; |
| 85 | size_t nbytes = count; | 84 | size_t nbytes = count; |
| 86 | int bits; | 85 | int bits; |
| 87 | int err; | ||
| 88 | 86 | ||
| 89 | if (edev->addrlen == 7) { | 87 | if (edev->addrlen == 7) { |
| 90 | cmd_addr |= off & 0x7f; | 88 | cmd_addr |= off & 0x7f; |
| @@ -120,21 +118,20 @@ eeprom_93xx46_read(struct eeprom_93xx46_dev *edev, char *buf, | |||
| 120 | if (err) { | 118 | if (err) { |
| 121 | dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n", | 119 | dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n", |
| 122 | nbytes, (int)off, err); | 120 | nbytes, (int)off, err); |
| 123 | ret = err; | ||
| 124 | break; | 121 | break; |
| 125 | } | 122 | } |
| 126 | 123 | ||
| 127 | buf += nbytes; | 124 | buf += nbytes; |
| 128 | off += nbytes; | 125 | off += nbytes; |
| 129 | count -= nbytes; | 126 | count -= nbytes; |
| 130 | ret += nbytes; | ||
| 131 | } | 127 | } |
| 132 | 128 | ||
| 133 | if (edev->pdata->finish) | 129 | if (edev->pdata->finish) |
| 134 | edev->pdata->finish(edev); | 130 | edev->pdata->finish(edev); |
| 135 | 131 | ||
| 136 | mutex_unlock(&edev->lock); | 132 | mutex_unlock(&edev->lock); |
| 137 | return ret; | 133 | |
| 134 | return err; | ||
| 138 | } | 135 | } |
| 139 | 136 | ||
| 140 | static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on) | 137 | static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on) |
| @@ -230,10 +227,11 @@ eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev, | |||
| 230 | return ret; | 227 | return ret; |
| 231 | } | 228 | } |
| 232 | 229 | ||
| 233 | static ssize_t | 230 | static int eeprom_93xx46_write(void *priv, unsigned int off, |
| 234 | eeprom_93xx46_write(struct eeprom_93xx46_dev *edev, const char *buf, | 231 | void *val, size_t count) |
| 235 | loff_t off, size_t count) | ||
| 236 | { | 232 | { |
| 233 | struct eeprom_93xx46_dev *edev = priv; | ||
| 234 | char *buf = val; | ||
| 237 | int i, ret, step = 1; | 235 | int i, ret, step = 1; |
| 238 | 236 | ||
| 239 | if (unlikely(off >= edev->size)) | 237 | if (unlikely(off >= edev->size)) |
| @@ -275,52 +273,9 @@ eeprom_93xx46_write(struct eeprom_93xx46_dev *edev, const char *buf, | |||
| 275 | 273 | ||
| 276 | /* erase/write disable */ | 274 | /* erase/write disable */ |
| 277 | eeprom_93xx46_ew(edev, 0); | 275 | eeprom_93xx46_ew(edev, 0); |
| 278 | return ret ? : count; | 276 | return ret; |
| 279 | } | ||
| 280 | |||
| 281 | /* | ||
| 282 | * Provide a regmap interface, which is registered with the NVMEM | ||
| 283 | * framework | ||
| 284 | */ | ||
| 285 | static int eeprom_93xx46_regmap_read(void *context, const void *reg, | ||
| 286 | size_t reg_size, void *val, | ||
| 287 | size_t val_size) | ||
| 288 | { | ||
| 289 | struct eeprom_93xx46_dev *eeprom_93xx46 = context; | ||
| 290 | off_t offset = *(u32 *)reg; | ||
| 291 | int err; | ||
| 292 | |||
| 293 | err = eeprom_93xx46_read(eeprom_93xx46, val, offset, val_size); | ||
| 294 | if (err) | ||
| 295 | return err; | ||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 299 | static int eeprom_93xx46_regmap_write(void *context, const void *data, | ||
| 300 | size_t count) | ||
| 301 | { | ||
| 302 | struct eeprom_93xx46_dev *eeprom_93xx46 = context; | ||
| 303 | const char *buf; | ||
| 304 | u32 offset; | ||
| 305 | size_t len; | ||
| 306 | int err; | ||
| 307 | |||
| 308 | memcpy(&offset, data, sizeof(offset)); | ||
| 309 | buf = (const char *)data + sizeof(offset); | ||
| 310 | len = count - sizeof(offset); | ||
| 311 | |||
| 312 | err = eeprom_93xx46_write(eeprom_93xx46, buf, offset, len); | ||
| 313 | if (err) | ||
| 314 | return err; | ||
| 315 | return 0; | ||
| 316 | } | 277 | } |
| 317 | 278 | ||
| 318 | static const struct regmap_bus eeprom_93xx46_regmap_bus = { | ||
| 319 | .read = eeprom_93xx46_regmap_read, | ||
| 320 | .write = eeprom_93xx46_regmap_write, | ||
| 321 | .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, | ||
| 322 | }; | ||
| 323 | |||
| 324 | static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev) | 279 | static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev) |
| 325 | { | 280 | { |
| 326 | struct eeprom_93xx46_platform_data *pd = edev->pdata; | 281 | struct eeprom_93xx46_platform_data *pd = edev->pdata; |
| @@ -480,7 +435,6 @@ static int eeprom_93xx46_probe(struct spi_device *spi) | |||
| 480 | { | 435 | { |
| 481 | struct eeprom_93xx46_platform_data *pd; | 436 | struct eeprom_93xx46_platform_data *pd; |
| 482 | struct eeprom_93xx46_dev *edev; | 437 | struct eeprom_93xx46_dev *edev; |
| 483 | struct regmap *regmap; | ||
| 484 | int err; | 438 | int err; |
| 485 | 439 | ||
| 486 | if (spi->dev.of_node) { | 440 | if (spi->dev.of_node) { |
| @@ -511,24 +465,10 @@ static int eeprom_93xx46_probe(struct spi_device *spi) | |||
| 511 | 465 | ||
| 512 | mutex_init(&edev->lock); | 466 | mutex_init(&edev->lock); |
| 513 | 467 | ||
| 514 | edev->spi = spi_dev_get(spi); | 468 | edev->spi = spi; |
| 515 | edev->pdata = pd; | 469 | edev->pdata = pd; |
| 516 | 470 | ||
| 517 | edev->size = 128; | 471 | edev->size = 128; |
| 518 | |||
| 519 | edev->regmap_config.reg_bits = 32; | ||
| 520 | edev->regmap_config.val_bits = 8; | ||
| 521 | edev->regmap_config.reg_stride = 1; | ||
| 522 | edev->regmap_config.max_register = edev->size - 1; | ||
| 523 | |||
| 524 | regmap = devm_regmap_init(&spi->dev, &eeprom_93xx46_regmap_bus, edev, | ||
| 525 | &edev->regmap_config); | ||
| 526 | if (IS_ERR(regmap)) { | ||
| 527 | dev_err(&spi->dev, "regmap init failed\n"); | ||
| 528 | err = PTR_ERR(regmap); | ||
| 529 | goto fail; | ||
| 530 | } | ||
| 531 | |||
| 532 | edev->nvmem_config.name = dev_name(&spi->dev); | 472 | edev->nvmem_config.name = dev_name(&spi->dev); |
| 533 | edev->nvmem_config.dev = &spi->dev; | 473 | edev->nvmem_config.dev = &spi->dev; |
| 534 | edev->nvmem_config.read_only = pd->flags & EE_READONLY; | 474 | edev->nvmem_config.read_only = pd->flags & EE_READONLY; |
| @@ -536,6 +476,12 @@ static int eeprom_93xx46_probe(struct spi_device *spi) | |||
| 536 | edev->nvmem_config.owner = THIS_MODULE; | 476 | edev->nvmem_config.owner = THIS_MODULE; |
| 537 | edev->nvmem_config.compat = true; | 477 | edev->nvmem_config.compat = true; |
| 538 | edev->nvmem_config.base_dev = &spi->dev; | 478 | edev->nvmem_config.base_dev = &spi->dev; |
| 479 | edev->nvmem_config.reg_read = eeprom_93xx46_read; | ||
| 480 | edev->nvmem_config.reg_write = eeprom_93xx46_write; | ||
| 481 | edev->nvmem_config.priv = edev; | ||
| 482 | edev->nvmem_config.stride = 4; | ||
| 483 | edev->nvmem_config.word_size = 1; | ||
| 484 | edev->nvmem_config.size = edev->size; | ||
| 539 | 485 | ||
| 540 | edev->nvmem = nvmem_register(&edev->nvmem_config); | 486 | edev->nvmem = nvmem_register(&edev->nvmem_config); |
| 541 | if (IS_ERR(edev->nvmem)) { | 487 | if (IS_ERR(edev->nvmem)) { |
