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