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