]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
ebcab48a SG |
2 | /* |
3 | * Copyright (C) 2013 Google, Inc | |
ebcab48a SG |
4 | */ |
5 | ||
6 | #include <common.h> | |
7 | #include <dm.h> | |
8 | #include <fdtdec.h> | |
9 | #include <spi.h> | |
10 | #include <spi_flash.h> | |
e721b882 | 11 | #include <asm/state.h> |
ebcab48a SG |
12 | #include <dm/device-internal.h> |
13 | #include <dm/test.h> | |
14 | #include <dm/uclass-internal.h> | |
ebcab48a | 15 | #include <dm/util.h> |
e721b882 | 16 | #include <test/ut.h> |
ebcab48a SG |
17 | |
18 | /* Test that we can find buses and chip-selects */ | |
e721b882 | 19 | static int dm_test_spi_find(struct unit_test_state *uts) |
ebcab48a SG |
20 | { |
21 | struct sandbox_state *state = state_get_current(); | |
22 | struct spi_slave *slave; | |
23 | struct udevice *bus, *dev; | |
24 | const int busnum = 0, cs = 0, mode = 0, speed = 1000000, cs_b = 1; | |
25 | struct spi_cs_info info; | |
26 | int of_offset; | |
27 | ||
28 | ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_SPI, busnum, | |
29 | false, &bus)); | |
30 | ||
31 | /* | |
91195485 SG |
32 | * The post_bind() method will bind devices to chip selects. Check |
33 | * this then remove the emulation and the slave device. | |
ebcab48a SG |
34 | */ |
35 | ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus)); | |
36 | ut_assertok(spi_cs_info(bus, cs, &info)); | |
e160f7d4 | 37 | of_offset = dev_of_offset(info.dev); |
706865af | 38 | device_remove(info.dev, DM_REMOVE_NORMAL); |
ebcab48a SG |
39 | device_unbind(info.dev); |
40 | ||
41 | /* | |
42 | * Even though the device is gone, the sandbox SPI drivers always | |
43 | * reports that CS 0 is present | |
44 | */ | |
45 | ut_assertok(spi_cs_info(bus, cs, &info)); | |
d0cff03e | 46 | ut_asserteq_ptr(NULL, info.dev); |
ebcab48a SG |
47 | |
48 | /* This finds nothing because we removed the device */ | |
49 | ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); | |
50 | ut_asserteq(-ENODEV, spi_get_bus_and_cs(busnum, cs, speed, mode, | |
51 | NULL, 0, &bus, &slave)); | |
52 | ||
53 | /* | |
54 | * This forces the device to be re-added, but there is no emulation | |
55 | * connected so the probe will fail. We require that bus is left | |
56 | * alone on failure, and that the spi_get_bus_and_cs() does not add | |
57 | * a 'partially-inited' device. | |
58 | */ | |
59 | ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); | |
60 | ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode, | |
61 | "spi_flash_std", "name", &bus, | |
62 | &slave)); | |
d0cff03e | 63 | sandbox_sf_unbind_emul(state_get_current(), busnum, cs); |
ebcab48a | 64 | ut_assertok(spi_cs_info(bus, cs, &info)); |
d0cff03e | 65 | ut_asserteq_ptr(NULL, info.dev); |
ebcab48a SG |
66 | |
67 | /* Add the emulation and try again */ | |
68 | ut_assertok(sandbox_sf_bind_emul(state, busnum, cs, bus, of_offset, | |
69 | "name")); | |
70 | ut_assertok(spi_find_bus_and_cs(busnum, cs, &bus, &dev)); | |
71 | ut_assertok(spi_get_bus_and_cs(busnum, cs, speed, mode, | |
72 | "spi_flash_std", "name", &bus, &slave)); | |
73 | ||
74 | ut_assertok(spi_cs_info(bus, cs, &info)); | |
75 | ut_asserteq_ptr(info.dev, slave->dev); | |
76 | ||
77 | /* We should be able to add something to another chip select */ | |
78 | ut_assertok(sandbox_sf_bind_emul(state, busnum, cs_b, bus, of_offset, | |
79 | "name")); | |
80 | ut_assertok(spi_get_bus_and_cs(busnum, cs_b, speed, mode, | |
81 | "spi_flash_std", "name", &bus, &slave)); | |
82 | ut_assertok(spi_cs_info(bus, cs_b, &info)); | |
83 | ut_asserteq_ptr(info.dev, slave->dev); | |
84 | ||
85 | /* | |
86 | * Since we are about to destroy all devices, we must tell sandbox | |
87 | * to forget the emulation device | |
88 | */ | |
89 | sandbox_sf_unbind_emul(state_get_current(), busnum, cs); | |
90 | sandbox_sf_unbind_emul(state_get_current(), busnum, cs_b); | |
91 | ||
92 | return 0; | |
93 | } | |
94 | DM_TEST(dm_test_spi_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); | |
95 | ||
96 | /* Test that sandbox SPI works correctly */ | |
e721b882 | 97 | static int dm_test_spi_xfer(struct unit_test_state *uts) |
ebcab48a SG |
98 | { |
99 | struct spi_slave *slave; | |
100 | struct udevice *bus; | |
101 | const int busnum = 0, cs = 0, mode = 0; | |
102 | const char dout[5] = {0x9f}; | |
103 | unsigned char din[5]; | |
104 | ||
105 | ut_assertok(spi_get_bus_and_cs(busnum, cs, 1000000, mode, NULL, 0, | |
106 | &bus, &slave)); | |
107 | ut_assertok(spi_claim_bus(slave)); | |
108 | ut_assertok(spi_xfer(slave, 40, dout, din, | |
109 | SPI_XFER_BEGIN | SPI_XFER_END)); | |
110 | ut_asserteq(0xff, din[0]); | |
111 | ut_asserteq(0x20, din[1]); | |
112 | ut_asserteq(0x20, din[2]); | |
113 | ut_asserteq(0x15, din[3]); | |
114 | spi_release_bus(slave); | |
115 | ||
116 | /* | |
117 | * Since we are about to destroy all devices, we must tell sandbox | |
118 | * to forget the emulation device | |
119 | */ | |
120 | #ifdef CONFIG_DM_SPI_FLASH | |
121 | sandbox_sf_unbind_emul(state_get_current(), busnum, cs); | |
122 | #endif | |
123 | ||
124 | return 0; | |
125 | } | |
126 | DM_TEST(dm_test_spi_xfer, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |