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