Blame view

cmd/spi.c 3.64 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
e3093091a   wdenk   Initial revision
2
3
4
  /*
   * (C) Copyright 2002
   * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
e3093091a   wdenk   Initial revision
5
6
7
8
9
10
11
12
   */
  
  /*
   * SPI Read/Write Utilities
   */
  
  #include <common.h>
  #include <command.h>
1157a161b   Simon Glass   dm: spi: Adjust c...
13
  #include <dm.h>
df3b23ae3   Simon Glass   dm: spi: Move cmd...
14
  #include <errno.h>
e3093091a   wdenk   Initial revision
15
  #include <spi.h>
e3093091a   wdenk   Initial revision
16

eb9401e3e   wdenk   * Patch by Andrea...
17
18
19
20
21
22
23
  /*-----------------------------------------------------------------------
   * Definitions
   */
  
  #ifndef MAX_SPI_BYTES
  #   define MAX_SPI_BYTES 32	/* Maximum number of bytes we can handle */
  #endif
e3093091a   wdenk   Initial revision
24

e3093091a   wdenk   Initial revision
25
26
27
  /*
   * Values from last command.
   */
21032b35a   Reinhard Meyer   sspi: add options...
28
29
30
  static unsigned int	bus;
  static unsigned int	cs;
  static unsigned int	mode;
6954756a1   Marek Vasut   cmd: spi: Permit ...
31
  static unsigned int	freq;
d255bb0e7   Haavard Skinnemoen   SPI API improvements
32
33
34
  static int   		bitlen;
  static uchar 		dout[MAX_SPI_BYTES];
  static uchar 		din[MAX_SPI_BYTES];
e3093091a   wdenk   Initial revision
35

df3b23ae3   Simon Glass   dm: spi: Move cmd...
36
37
38
  static int do_spi_xfer(int bus, int cs)
  {
  	struct spi_slave *slave;
1157a161b   Simon Glass   dm: spi: Adjust c...
39
  	int ret = 0;
df3b23ae3   Simon Glass   dm: spi: Move cmd...
40

1157a161b   Simon Glass   dm: spi: Adjust c...
41
42
43
44
45
46
  #ifdef CONFIG_DM_SPI
  	char name[30], *str;
  	struct udevice *dev;
  
  	snprintf(name, sizeof(name), "generic_%d:%d", bus, cs);
  	str = strdup(name);
9caeb26c5   Peng Fan   cmd: spi: check r...
47
48
  	if (!str)
  		return -ENOMEM;
6954756a1   Marek Vasut   cmd: spi: Permit ...
49
  	ret = spi_get_bus_and_cs(bus, cs, freq, mode, "spi_generic_drv",
1157a161b   Simon Glass   dm: spi: Adjust c...
50
51
52
53
  				 str, &dev, &slave);
  	if (ret)
  		return ret;
  #else
6954756a1   Marek Vasut   cmd: spi: Permit ...
54
  	slave = spi_setup_slave(bus, cs, freq, mode);
df3b23ae3   Simon Glass   dm: spi: Move cmd...
55
56
57
58
59
  	if (!slave) {
  		printf("Invalid device %d:%d
  ", bus, cs);
  		return -EINVAL;
  	}
1157a161b   Simon Glass   dm: spi: Adjust c...
60
  #endif
df3b23ae3   Simon Glass   dm: spi: Move cmd...
61

1157a161b   Simon Glass   dm: spi: Adjust c...
62
63
64
65
66
67
68
69
70
71
72
73
74
  	ret = spi_claim_bus(slave);
  	if (ret)
  		goto done;
  	ret = spi_xfer(slave, bitlen, dout, din,
  		       SPI_XFER_BEGIN | SPI_XFER_END);
  #ifndef CONFIG_DM_SPI
  	/* We don't get an error code in this case */
  	if (ret)
  		ret = -EIO;
  #endif
  	if (ret) {
  		printf("Error %d during SPI transaction
  ", ret);
df3b23ae3   Simon Glass   dm: spi: Move cmd...
75
76
77
78
79
80
81
82
  	} else {
  		int j;
  
  		for (j = 0; j < ((bitlen + 7) / 8); j++)
  			printf("%02X", din[j]);
  		printf("
  ");
  	}
1157a161b   Simon Glass   dm: spi: Adjust c...
83
  done:
df3b23ae3   Simon Glass   dm: spi: Move cmd...
84
  	spi_release_bus(slave);
1157a161b   Simon Glass   dm: spi: Adjust c...
85
  #ifndef CONFIG_DM_SPI
df3b23ae3   Simon Glass   dm: spi: Move cmd...
86
  	spi_free_slave(slave);
1157a161b   Simon Glass   dm: spi: Adjust c...
87
  #endif
df3b23ae3   Simon Glass   dm: spi: Move cmd...
88

1157a161b   Simon Glass   dm: spi: Adjust c...
89
  	return ret;
df3b23ae3   Simon Glass   dm: spi: Move cmd...
90
  }
e3093091a   wdenk   Initial revision
91
92
93
94
95
96
97
98
99
100
  /*
   * SPI read/write
   *
   * Syntax:
   *   spi {dev} {num_bits} {dout}
   *     {dev} is the device number for controlling chip select (see TBD)
   *     {num_bits} is the number of bits to send & receive (base 10)
   *     {dout} is a hexadecimal string of data to send
   * The command prints out the hexadecimal string received via SPI.
   */
54841ab50   Wolfgang Denk   Make sure that ar...
101
  int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
e3093091a   wdenk   Initial revision
102
103
104
105
  {
  	char  *cp = 0;
  	uchar tmp;
  	int   j;
e3093091a   wdenk   Initial revision
106
107
108
109
110
  
  	/*
  	 * We use the last specified parameters, unless new ones are
  	 * entered.
  	 */
6954756a1   Marek Vasut   cmd: spi: Permit ...
111
112
  	if (freq == 0)
  		freq = 1000000;
e3093091a   wdenk   Initial revision
113
114
115
  
  	if ((flag & CMD_FLAG_REPEAT) == 0)
  	{
21032b35a   Reinhard Meyer   sspi: add options...
116
117
118
119
120
121
122
123
124
  		if (argc >= 2) {
  			mode = CONFIG_DEFAULT_SPI_MODE;
  			bus = simple_strtoul(argv[1], &cp, 10);
  			if (*cp == ':') {
  				cs = simple_strtoul(cp+1, &cp, 10);
  			} else {
  				cs = bus;
  				bus = CONFIG_DEFAULT_SPI_BUS;
  			}
2d5e7c7a4   Marek Vasut   cmd_spi: remove s...
125
  			if (*cp == '.')
6954756a1   Marek Vasut   cmd: spi: Permit ...
126
127
128
  				mode = simple_strtoul(cp+1, &cp, 10);
  			if (*cp == '@')
  				freq = simple_strtoul(cp+1, &cp, 10);
21032b35a   Reinhard Meyer   sspi: add options...
129
  		}
e3093091a   wdenk   Initial revision
130
131
  		if (argc >= 3)
  			bitlen = simple_strtoul(argv[2], NULL, 10);
eb9401e3e   wdenk   * Patch by Andrea...
132
133
134
135
136
137
138
139
140
  		if (argc >= 4) {
  			cp = argv[3];
  			for(j = 0; *cp; j++, cp++) {
  				tmp = *cp - '0';
  				if(tmp > 9)
  					tmp -= ('A' - '0') - 10;
  				if(tmp > 15)
  					tmp -= ('a' - 'A');
  				if(tmp > 15) {
21032b35a   Reinhard Meyer   sspi: add options...
141
142
  					printf("Hex conversion error on %c
  ", *cp);
eb9401e3e   wdenk   * Patch by Andrea...
143
144
145
146
147
148
  					return 1;
  				}
  				if((j % 2) == 0)
  					dout[j / 2] = (tmp << 4);
  				else
  					dout[j / 2] |= tmp;
e3093091a   wdenk   Initial revision
149
  			}
e3093091a   wdenk   Initial revision
150
151
  		}
  	}
eb9401e3e   wdenk   * Patch by Andrea...
152
  	if ((bitlen < 0) || (bitlen >  (MAX_SPI_BYTES * 8))) {
21032b35a   Reinhard Meyer   sspi: add options...
153
154
  		printf("Invalid bitlen %d
  ", bitlen);
eb9401e3e   wdenk   * Patch by Andrea...
155
  		return 1;
8bde7f776   wdenk   * Code cleanup:
156
  	}
eb9401e3e   wdenk   * Patch by Andrea...
157

df3b23ae3   Simon Glass   dm: spi: Move cmd...
158
  	if (do_spi_xfer(bus, cs))
d255bb0e7   Haavard Skinnemoen   SPI API improvements
159
  		return 1;
e3093091a   wdenk   Initial revision
160

df3b23ae3   Simon Glass   dm: spi: Move cmd...
161
  	return 0;
e3093091a   wdenk   Initial revision
162
  }
8bde7f776   wdenk   * Code cleanup:
163
  /***************************************************/
0d4983930   wdenk   Patch by Kenneth ...
164
165
  U_BOOT_CMD(
  	sspi,	5,	1,	do_spi,
21032b35a   Reinhard Meyer   sspi: add options...
166
  	"SPI utility command",
6954756a1   Marek Vasut   cmd: spi: Permit ...
167
168
  	"[<bus>:]<cs>[.<mode>][@<freq>] <bit_len> <dout> - Send and receive bits
  "
21032b35a   Reinhard Meyer   sspi: add options...
169
170
171
172
173
174
  	"<bus>     - Identifies the SPI bus
  "
  	"<cs>      - Identifies the chip select
  "
  	"<mode>    - Identifies the SPI mode to use
  "
6954756a1   Marek Vasut   cmd: spi: Permit ...
175
176
  	"<freq>    - Identifies the SPI bus frequency in Hz
  "
8bde7f776   wdenk   * Code cleanup:
177
178
  	"<bit_len> - Number of bits to send (base 10)
  "
a89c33db9   Wolfgang Denk   General help mess...
179
  	"<dout>    - Hexadecimal string that gets sent"
8bde7f776   wdenk   * Code cleanup:
180
  );