Blame view

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

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

d255bb0e7   Haavard Skinnemoen   SPI API improvements
26
27
28
29
30
31
  #ifndef CONFIG_DEFAULT_SPI_BUS
  #   define CONFIG_DEFAULT_SPI_BUS	0
  #endif
  #ifndef CONFIG_DEFAULT_SPI_MODE
  #   define CONFIG_DEFAULT_SPI_MODE	SPI_MODE_0
  #endif
e3093091a   wdenk   Initial revision
32
33
34
35
  
  /*
   * Values from last command.
   */
21032b35a   Reinhard Meyer   sspi: add options...
36
37
38
  static unsigned int	bus;
  static unsigned int	cs;
  static unsigned int	mode;
d255bb0e7   Haavard Skinnemoen   SPI API improvements
39
40
41
  static int   		bitlen;
  static uchar 		dout[MAX_SPI_BYTES];
  static uchar 		din[MAX_SPI_BYTES];
e3093091a   wdenk   Initial revision
42

df3b23ae3   Simon Glass   dm: spi: Move cmd...
43
44
45
  static int do_spi_xfer(int bus, int cs)
  {
  	struct spi_slave *slave;
1157a161b   Simon Glass   dm: spi: Adjust c...
46
  	int ret = 0;
df3b23ae3   Simon Glass   dm: spi: Move cmd...
47

1157a161b   Simon Glass   dm: spi: Adjust c...
48
49
50
51
52
53
  #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...
54
55
  	if (!str)
  		return -ENOMEM;
1157a161b   Simon Glass   dm: spi: Adjust c...
56
57
58
59
60
  	ret = spi_get_bus_and_cs(bus, cs, 1000000, mode, "spi_generic_drv",
  				 str, &dev, &slave);
  	if (ret)
  		return ret;
  #else
df3b23ae3   Simon Glass   dm: spi: Move cmd...
61
62
63
64
65
66
  	slave = spi_setup_slave(bus, cs, 1000000, mode);
  	if (!slave) {
  		printf("Invalid device %d:%d
  ", bus, cs);
  		return -EINVAL;
  	}
1157a161b   Simon Glass   dm: spi: Adjust c...
67
  #endif
df3b23ae3   Simon Glass   dm: spi: Move cmd...
68

1157a161b   Simon Glass   dm: spi: Adjust c...
69
70
71
72
73
74
75
76
77
78
79
80
81
  	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...
82
83
84
85
86
87
88
89
  	} else {
  		int j;
  
  		for (j = 0; j < ((bitlen + 7) / 8); j++)
  			printf("%02X", din[j]);
  		printf("
  ");
  	}
1157a161b   Simon Glass   dm: spi: Adjust c...
90
  done:
df3b23ae3   Simon Glass   dm: spi: Move cmd...
91
  	spi_release_bus(slave);
1157a161b   Simon Glass   dm: spi: Adjust c...
92
  #ifndef CONFIG_DM_SPI
df3b23ae3   Simon Glass   dm: spi: Move cmd...
93
  	spi_free_slave(slave);
1157a161b   Simon Glass   dm: spi: Adjust c...
94
  #endif
df3b23ae3   Simon Glass   dm: spi: Move cmd...
95

1157a161b   Simon Glass   dm: spi: Adjust c...
96
  	return ret;
df3b23ae3   Simon Glass   dm: spi: Move cmd...
97
  }
e3093091a   wdenk   Initial revision
98
99
100
101
102
103
104
105
106
107
  /*
   * 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...
108
  int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
e3093091a   wdenk   Initial revision
109
110
111
112
  {
  	char  *cp = 0;
  	uchar tmp;
  	int   j;
e3093091a   wdenk   Initial revision
113
114
115
116
117
118
119
120
  
  	/*
  	 * We use the last specified parameters, unless new ones are
  	 * entered.
  	 */
  
  	if ((flag & CMD_FLAG_REPEAT) == 0)
  	{
21032b35a   Reinhard Meyer   sspi: add options...
121
122
123
124
125
126
127
128
129
  		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...
130
  			if (*cp == '.')
21032b35a   Reinhard Meyer   sspi: add options...
131
132
  				mode = simple_strtoul(cp+1, NULL, 10);
  		}
e3093091a   wdenk   Initial revision
133
134
  		if (argc >= 3)
  			bitlen = simple_strtoul(argv[2], NULL, 10);
eb9401e3e   wdenk   * Patch by Andrea...
135
136
137
138
139
140
141
142
143
  		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...
144
145
  					printf("Hex conversion error on %c
  ", *cp);
eb9401e3e   wdenk   * Patch by Andrea...
146
147
148
149
150
151
  					return 1;
  				}
  				if((j % 2) == 0)
  					dout[j / 2] = (tmp << 4);
  				else
  					dout[j / 2] |= tmp;
e3093091a   wdenk   Initial revision
152
  			}
e3093091a   wdenk   Initial revision
153
154
  		}
  	}
eb9401e3e   wdenk   * Patch by Andrea...
155
  	if ((bitlen < 0) || (bitlen >  (MAX_SPI_BYTES * 8))) {
21032b35a   Reinhard Meyer   sspi: add options...
156
157
  		printf("Invalid bitlen %d
  ", bitlen);
eb9401e3e   wdenk   * Patch by Andrea...
158
  		return 1;
8bde7f776   wdenk   * Code cleanup:
159
  	}
eb9401e3e   wdenk   * Patch by Andrea...
160

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

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