]>
Commit | Line | Data |
---|---|---|
4c2dbefd SG |
1 | /* |
2 | * Copyright (c) 2014 Google, Inc | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <dm.h> | |
9 | #include <spi.h> | |
10 | #include <spi_flash.h> | |
11 | #include <dm/device-internal.h> | |
12 | #include "sf_internal.h" | |
13 | ||
2588f2dd MS |
14 | DECLARE_GLOBAL_DATA_PTR; |
15 | ||
8d987abc SG |
16 | int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf) |
17 | { | |
18 | return sf_get_ops(dev)->read(dev, offset, len, buf); | |
19 | } | |
20 | ||
21 | int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len, | |
22 | const void *buf) | |
23 | { | |
24 | return sf_get_ops(dev)->write(dev, offset, len, buf); | |
25 | } | |
26 | ||
27 | int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len) | |
28 | { | |
29 | return sf_get_ops(dev)->erase(dev, offset, len); | |
30 | } | |
31 | ||
4c2dbefd SG |
32 | /* |
33 | * TODO(sjg@chromium.org): This is an old-style function. We should remove | |
34 | * it when all SPI flash drivers use dm | |
35 | */ | |
36 | struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, | |
37 | unsigned int max_hz, unsigned int spi_mode) | |
38 | { | |
39 | struct udevice *dev; | |
40 | ||
41 | if (spi_flash_probe_bus_cs(bus, cs, max_hz, spi_mode, &dev)) | |
42 | return NULL; | |
43 | ||
e564f054 | 44 | return dev_get_uclass_priv(dev); |
4c2dbefd SG |
45 | } |
46 | ||
47 | void spi_flash_free(struct spi_flash *flash) | |
48 | { | |
49 | spi_flash_remove(flash->spi->dev); | |
50 | } | |
51 | ||
52 | int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, | |
53 | unsigned int max_hz, unsigned int spi_mode, | |
54 | struct udevice **devp) | |
55 | { | |
56 | struct spi_slave *slave; | |
57 | struct udevice *bus; | |
a5e1bcde | 58 | char name[30], *str; |
4c2dbefd SG |
59 | int ret; |
60 | ||
a5e1bcde | 61 | snprintf(name, sizeof(name), "spi_flash@%d:%d", busnum, cs); |
4c2dbefd SG |
62 | str = strdup(name); |
63 | ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode, | |
64 | "spi_flash_std", str, &bus, &slave); | |
65 | if (ret) | |
66 | return ret; | |
67 | ||
68 | *devp = slave->dev; | |
69 | return 0; | |
70 | } | |
71 | ||
72 | int spi_flash_remove(struct udevice *dev) | |
73 | { | |
74 | return device_remove(dev); | |
75 | } | |
76 | ||
2588f2dd MS |
77 | static int spi_flash_post_bind(struct udevice *dev) |
78 | { | |
79 | #if defined(CONFIG_NEEDS_MANUAL_RELOC) | |
80 | struct dm_spi_flash_ops *ops = sf_get_ops(dev); | |
81 | static int reloc_done; | |
82 | ||
83 | if (!reloc_done) { | |
84 | if (ops->read) | |
85 | ops->read += gd->reloc_off; | |
86 | if (ops->write) | |
87 | ops->write += gd->reloc_off; | |
88 | if (ops->erase) | |
89 | ops->erase += gd->reloc_off; | |
90 | ||
91 | reloc_done++; | |
92 | } | |
93 | #endif | |
94 | return 0; | |
95 | } | |
96 | ||
4c2dbefd SG |
97 | UCLASS_DRIVER(spi_flash) = { |
98 | .id = UCLASS_SPI_FLASH, | |
99 | .name = "spi_flash", | |
2588f2dd | 100 | .post_bind = spi_flash_post_bind, |
4c2dbefd SG |
101 | .per_device_auto_alloc_size = sizeof(struct spi_flash), |
102 | }; |