1 /* 2 * (C) Copyright 2002 3 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * SPI Read/Write Utilities 10 */ 11 12 #include <common.h> 13 #include <command.h> 14 #include <dm.h> 15 #include <errno.h> 16 #include <spi.h> 17 18 /*----------------------------------------------------------------------- 19 * Definitions 20 */ 21 22 #ifndef MAX_SPI_BYTES 23 # define MAX_SPI_BYTES 32 /* Maximum number of bytes we can handle */ 24 #endif 25 26 #ifndef CONFIG_DEFAULT_SPI_BUS 27 # define CONFIG_DEFAULT_SPI_BUS 0 28 #endif 29 #ifndef CONFIG_DEFAULT_SPI_MODE 30 # define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0 31 #endif 32 33 /* 34 * Values from last command. 35 */ 36 static unsigned int bus; 37 static unsigned int cs; 38 static unsigned int mode; 39 static int bitlen; 40 static uchar dout[MAX_SPI_BYTES]; 41 static uchar din[MAX_SPI_BYTES]; 42 43 static int do_spi_xfer(int bus, int cs) 44 { 45 struct spi_slave *slave; 46 int ret = 0; 47 48 #ifdef CONFIG_DM_SPI 49 char name[30], *str; 50 struct udevice *dev; 51 52 snprintf(name, sizeof(name), "generic_%d:%d", bus, cs); 53 str = strdup(name); 54 ret = spi_get_bus_and_cs(bus, cs, 1000000, mode, "spi_generic_drv", 55 str, &dev, &slave); 56 if (ret) 57 return ret; 58 #else 59 slave = spi_setup_slave(bus, cs, 1000000, mode); 60 if (!slave) { 61 printf("Invalid device %d:%d\n", bus, cs); 62 return -EINVAL; 63 } 64 #endif 65 66 ret = spi_claim_bus(slave); 67 if (ret) 68 goto done; 69 ret = spi_xfer(slave, bitlen, dout, din, 70 SPI_XFER_BEGIN | SPI_XFER_END); 71 #ifndef CONFIG_DM_SPI 72 /* We don't get an error code in this case */ 73 if (ret) 74 ret = -EIO; 75 #endif 76 if (ret) { 77 printf("Error %d during SPI transaction\n", ret); 78 } else { 79 int j; 80 81 for (j = 0; j < ((bitlen + 7) / 8); j++) 82 printf("%02X", din[j]); 83 printf("\n"); 84 } 85 done: 86 spi_release_bus(slave); 87 #ifndef CONFIG_DM_SPI 88 spi_free_slave(slave); 89 #endif 90 91 return ret; 92 } 93 94 /* 95 * SPI read/write 96 * 97 * Syntax: 98 * spi {dev} {num_bits} {dout} 99 * {dev} is the device number for controlling chip select (see TBD) 100 * {num_bits} is the number of bits to send & receive (base 10) 101 * {dout} is a hexadecimal string of data to send 102 * The command prints out the hexadecimal string received via SPI. 103 */ 104 105 int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 106 { 107 char *cp = 0; 108 uchar tmp; 109 int j; 110 111 /* 112 * We use the last specified parameters, unless new ones are 113 * entered. 114 */ 115 116 if ((flag & CMD_FLAG_REPEAT) == 0) 117 { 118 if (argc >= 2) { 119 mode = CONFIG_DEFAULT_SPI_MODE; 120 bus = simple_strtoul(argv[1], &cp, 10); 121 if (*cp == ':') { 122 cs = simple_strtoul(cp+1, &cp, 10); 123 } else { 124 cs = bus; 125 bus = CONFIG_DEFAULT_SPI_BUS; 126 } 127 if (*cp == '.') 128 mode = simple_strtoul(cp+1, NULL, 10); 129 } 130 if (argc >= 3) 131 bitlen = simple_strtoul(argv[2], NULL, 10); 132 if (argc >= 4) { 133 cp = argv[3]; 134 for(j = 0; *cp; j++, cp++) { 135 tmp = *cp - '0'; 136 if(tmp > 9) 137 tmp -= ('A' - '0') - 10; 138 if(tmp > 15) 139 tmp -= ('a' - 'A'); 140 if(tmp > 15) { 141 printf("Hex conversion error on %c\n", *cp); 142 return 1; 143 } 144 if((j % 2) == 0) 145 dout[j / 2] = (tmp << 4); 146 else 147 dout[j / 2] |= tmp; 148 } 149 } 150 } 151 152 if ((bitlen < 0) || (bitlen > (MAX_SPI_BYTES * 8))) { 153 printf("Invalid bitlen %d\n", bitlen); 154 return 1; 155 } 156 157 if (do_spi_xfer(bus, cs)) 158 return 1; 159 160 return 0; 161 } 162 163 /***************************************************/ 164 165 U_BOOT_CMD( 166 sspi, 5, 1, do_spi, 167 "SPI utility command", 168 "[<bus>:]<cs>[.<mode>] <bit_len> <dout> - Send and receive bits\n" 169 "<bus> - Identifies the SPI bus\n" 170 "<cs> - Identifies the chip select\n" 171 "<mode> - Identifies the SPI mode to use\n" 172 "<bit_len> - Number of bits to send (base 10)\n" 173 "<dout> - Hexadecimal string that gets sent" 174 ); 175