xref: /OK3568_Linux_fs/u-boot/doc/driver-model/spi-howto.txt (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunHow to port a SPI driver to driver model
2*4882a593Smuzhiyun========================================
3*4882a593Smuzhiyun
4*4882a593SmuzhiyunHere is a rough step-by-step guide. It is based around converting the
5*4882a593Smuzhiyunexynos SPI driver to driver model (DM) and the example code is based
6*4882a593Smuzhiyunaround U-Boot v2014.10-rc2 (commit be9f643). This has been updated for
7*4882a593Smuzhiyunv2015.04.
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunIt is quite long since it includes actual code examples.
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunBefore driver model, SPI drivers have their own private structure which
12*4882a593Smuzhiyuncontains 'struct spi_slave'. With driver model, 'struct spi_slave' still
13*4882a593Smuzhiyunexists, but now it is 'per-child data' for the SPI bus. Each child of the
14*4882a593SmuzhiyunSPI bus is a SPI slave. The information that was stored in the
15*4882a593Smuzhiyundriver-specific slave structure can now be port in private data for the
16*4882a593SmuzhiyunSPI bus.
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunFor example, struct tegra_spi_slave looks like this:
19*4882a593Smuzhiyun
20*4882a593Smuzhiyunstruct tegra_spi_slave {
21*4882a593Smuzhiyun	struct spi_slave slave;
22*4882a593Smuzhiyun	struct tegra_spi_ctrl *ctrl;
23*4882a593Smuzhiyun};
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunIn this case 'slave' will be in per-child data, and 'ctrl' will be in the
26*4882a593SmuzhiyunSPI's buses private data.
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun0. How long does this take?
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunYou should be able to complete this within 2 hours, including testing but
32*4882a593Smuzhiyunexcluding preparing the patches. The API is basically the same as before
33*4882a593Smuzhiyunwith only minor changes:
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun- methods to set speed and mode are separated out
36*4882a593Smuzhiyun- cs_info is used to get information on a chip select
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun1. Enable driver mode for SPI and SPI flash
40*4882a593Smuzhiyun
41*4882a593SmuzhiyunAdd these to your board config:
42*4882a593Smuzhiyun
43*4882a593SmuzhiyunCONFIG_DM_SPI
44*4882a593SmuzhiyunCONFIG_DM_SPI_FLASH
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun2. Add the skeleton
48*4882a593Smuzhiyun
49*4882a593SmuzhiyunPut this code at the bottom of your existing driver file:
50*4882a593Smuzhiyun
51*4882a593Smuzhiyunstruct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
52*4882a593Smuzhiyun			unsigned int max_hz, unsigned int mode)
53*4882a593Smuzhiyun{
54*4882a593Smuzhiyun	return NULL;
55*4882a593Smuzhiyun}
56*4882a593Smuzhiyun
57*4882a593Smuzhiyunstruct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
58*4882a593Smuzhiyun				      int spi_node)
59*4882a593Smuzhiyun{
60*4882a593Smuzhiyun	return NULL;
61*4882a593Smuzhiyun}
62*4882a593Smuzhiyun
63*4882a593Smuzhiyunstatic int exynos_spi_ofdata_to_platdata(struct udevice *dev)
64*4882a593Smuzhiyun{
65*4882a593Smuzhiyun	return -ENODEV;
66*4882a593Smuzhiyun}
67*4882a593Smuzhiyun
68*4882a593Smuzhiyunstatic int exynos_spi_probe(struct udevice *dev)
69*4882a593Smuzhiyun{
70*4882a593Smuzhiyun	return -ENODEV;
71*4882a593Smuzhiyun}
72*4882a593Smuzhiyun
73*4882a593Smuzhiyunstatic int exynos_spi_remove(struct udevice *dev)
74*4882a593Smuzhiyun{
75*4882a593Smuzhiyun	return -ENODEV;
76*4882a593Smuzhiyun}
77*4882a593Smuzhiyun
78*4882a593Smuzhiyunstatic int exynos_spi_claim_bus(struct udevice *dev)
79*4882a593Smuzhiyun{
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun	return -ENODEV;
82*4882a593Smuzhiyun}
83*4882a593Smuzhiyun
84*4882a593Smuzhiyunstatic int exynos_spi_release_bus(struct udevice *dev)
85*4882a593Smuzhiyun{
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun	return -ENODEV;
88*4882a593Smuzhiyun}
89*4882a593Smuzhiyun
90*4882a593Smuzhiyunstatic int exynos_spi_xfer(struct udevice *dev, unsigned int bitlen,
91*4882a593Smuzhiyun			    const void *dout, void *din, unsigned long flags)
92*4882a593Smuzhiyun{
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun	return -ENODEV;
95*4882a593Smuzhiyun}
96*4882a593Smuzhiyun
97*4882a593Smuzhiyunstatic int exynos_spi_set_speed(struct udevice *dev, uint speed)
98*4882a593Smuzhiyun{
99*4882a593Smuzhiyun	return -ENODEV;
100*4882a593Smuzhiyun}
101*4882a593Smuzhiyun
102*4882a593Smuzhiyunstatic int exynos_spi_set_mode(struct udevice *dev, uint mode)
103*4882a593Smuzhiyun{
104*4882a593Smuzhiyun	return -ENODEV;
105*4882a593Smuzhiyun}
106*4882a593Smuzhiyun
107*4882a593Smuzhiyunstatic int exynos_cs_info(struct udevice *bus, uint cs,
108*4882a593Smuzhiyun			  struct spi_cs_info *info)
109*4882a593Smuzhiyun{
110*4882a593Smuzhiyun	return -ENODEV;
111*4882a593Smuzhiyun}
112*4882a593Smuzhiyun
113*4882a593Smuzhiyunstatic const struct dm_spi_ops exynos_spi_ops = {
114*4882a593Smuzhiyun	.claim_bus	= exynos_spi_claim_bus,
115*4882a593Smuzhiyun	.release_bus	= exynos_spi_release_bus,
116*4882a593Smuzhiyun	.xfer		= exynos_spi_xfer,
117*4882a593Smuzhiyun	.set_speed	= exynos_spi_set_speed,
118*4882a593Smuzhiyun	.set_mode	= exynos_spi_set_mode,
119*4882a593Smuzhiyun	.cs_info	= exynos_cs_info,
120*4882a593Smuzhiyun};
121*4882a593Smuzhiyun
122*4882a593Smuzhiyunstatic const struct udevice_id exynos_spi_ids[] = {
123*4882a593Smuzhiyun	{ .compatible = "samsung,exynos-spi" },
124*4882a593Smuzhiyun	{ }
125*4882a593Smuzhiyun};
126*4882a593Smuzhiyun
127*4882a593SmuzhiyunU_BOOT_DRIVER(exynos_spi) = {
128*4882a593Smuzhiyun	.name	= "exynos_spi",
129*4882a593Smuzhiyun	.id	= UCLASS_SPI,
130*4882a593Smuzhiyun	.of_match = exynos_spi_ids,
131*4882a593Smuzhiyun	.ops	= &exynos_spi_ops,
132*4882a593Smuzhiyun	.ofdata_to_platdata = exynos_spi_ofdata_to_platdata,
133*4882a593Smuzhiyun	.probe	= exynos_spi_probe,
134*4882a593Smuzhiyun	.remove	= exynos_spi_remove,
135*4882a593Smuzhiyun};
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun3. Replace 'exynos' in the above code with your driver name
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun4. #ifdef out all of the code in your driver except for the above
142*4882a593Smuzhiyun
143*4882a593SmuzhiyunThis will allow you to get it building, which means you can work
144*4882a593Smuzhiyunincrementally. Since all the methods return an error initially, there is
145*4882a593Smuzhiyunless chance that you will accidentally leave something in.
146*4882a593Smuzhiyun
147*4882a593SmuzhiyunAlso, even though your conversion is basically a rewrite, it might help
148*4882a593Smuzhiyunreviewers if you leave functions in the same place in the file,
149*4882a593Smuzhiyunparticularly for large drivers.
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun5. Add some includes
153*4882a593Smuzhiyun
154*4882a593SmuzhiyunAdd these includes to your driver:
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun#include <dm.h>
157*4882a593Smuzhiyun#include <errno.h>
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun6. Build
161*4882a593Smuzhiyun
162*4882a593SmuzhiyunAt this point you should be able to build U-Boot for your board with the
163*4882a593Smuzhiyunempty SPI driver. You still have empty methods in your driver, but we will
164*4882a593Smuzhiyunwrite these one by one.
165*4882a593Smuzhiyun
166*4882a593SmuzhiyunIf you have spi_init() functions or the like that are called from your
167*4882a593Smuzhiyunboard then the build will fail. Remove these calls and make a note of the
168*4882a593Smuzhiyuninit that needs to be done.
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun7. Set up your platform data structure
172*4882a593Smuzhiyun
173*4882a593SmuzhiyunThis will hold the information your driver to operate, like its hardware
174*4882a593Smuzhiyunaddress or maximum frequency.
175*4882a593Smuzhiyun
176*4882a593SmuzhiyunYou may already have a struct like this, or you may need to create one
177*4882a593Smuzhiyunfrom some of the #defines or global variables in the driver.
178*4882a593Smuzhiyun
179*4882a593SmuzhiyunNote that this information is not the run-time information. It should not
180*4882a593Smuzhiyuninclude state that changes. It should be fixed throughout the live of
181*4882a593SmuzhiyunU-Boot. Run-time information comes later.
182*4882a593Smuzhiyun
183*4882a593SmuzhiyunHere is what was in the exynos spi driver:
184*4882a593Smuzhiyun
185*4882a593Smuzhiyunstruct spi_bus {
186*4882a593Smuzhiyun	enum periph_id periph_id;
187*4882a593Smuzhiyun	s32 frequency;		/* Default clock frequency, -1 for none */
188*4882a593Smuzhiyun	struct exynos_spi *regs;
189*4882a593Smuzhiyun	int inited;		/* 1 if this bus is ready for use */
190*4882a593Smuzhiyun	int node;
191*4882a593Smuzhiyun	uint deactivate_delay_us;	/* Delay to wait after deactivate */
192*4882a593Smuzhiyun};
193*4882a593Smuzhiyun
194*4882a593SmuzhiyunOf these, inited is handled by DM and node is the device tree node, which
195*4882a593SmuzhiyunDM tells you. The name is not quite right. So in this case we would use:
196*4882a593Smuzhiyun
197*4882a593Smuzhiyunstruct exynos_spi_platdata {
198*4882a593Smuzhiyun	enum periph_id periph_id;
199*4882a593Smuzhiyun	s32 frequency;		/* Default clock frequency, -1 for none */
200*4882a593Smuzhiyun	struct exynos_spi *regs;
201*4882a593Smuzhiyun	uint deactivate_delay_us;	/* Delay to wait after deactivate */
202*4882a593Smuzhiyun};
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun8a. Write ofdata_to_platdata()   [for device tree only]
206*4882a593Smuzhiyun
207*4882a593SmuzhiyunThis method will convert information in the device tree node into a C
208*4882a593Smuzhiyunstructure in your driver (called platform data). If you are not using
209*4882a593Smuzhiyundevice tree, go to 8b.
210*4882a593Smuzhiyun
211*4882a593SmuzhiyunDM will automatically allocate the struct for us when we are using device
212*4882a593Smuzhiyuntree, but we need to tell it the size:
213*4882a593Smuzhiyun
214*4882a593SmuzhiyunU_BOOT_DRIVER(spi_exynos) = {
215*4882a593Smuzhiyun...
216*4882a593Smuzhiyun	.platdata_auto_alloc_size = sizeof(struct exynos_spi_platdata),
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun
219*4882a593SmuzhiyunHere is a sample function. It gets a pointer to the platform data and
220*4882a593Smuzhiyunfills in the fields from device tree.
221*4882a593Smuzhiyun
222*4882a593Smuzhiyunstatic int exynos_spi_ofdata_to_platdata(struct udevice *bus)
223*4882a593Smuzhiyun{
224*4882a593Smuzhiyun	struct exynos_spi_platdata *plat = bus->platdata;
225*4882a593Smuzhiyun	const void *blob = gd->fdt_blob;
226*4882a593Smuzhiyun	int node = dev_of_offset(bus);
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun	plat->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
229*4882a593Smuzhiyun	plat->periph_id = pinmux_decode_periph_id(blob, node);
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun	if (plat->periph_id == PERIPH_ID_NONE) {
232*4882a593Smuzhiyun		debug("%s: Invalid peripheral ID %d\n", __func__,
233*4882a593Smuzhiyun			plat->periph_id);
234*4882a593Smuzhiyun		return -FDT_ERR_NOTFOUND;
235*4882a593Smuzhiyun	}
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun	/* Use 500KHz as a suitable default */
238*4882a593Smuzhiyun	plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
239*4882a593Smuzhiyun					500000);
240*4882a593Smuzhiyun	plat->deactivate_delay_us = fdtdec_get_int(blob, node,
241*4882a593Smuzhiyun					"spi-deactivate-delay", 0);
242*4882a593Smuzhiyun	debug("%s: regs=%p, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
243*4882a593Smuzhiyun	      __func__, plat->regs, plat->periph_id, plat->frequency,
244*4882a593Smuzhiyun              plat->deactivate_delay_us);
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun	return 0;
247*4882a593Smuzhiyun}
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun8b. Add the platform data  [non-device-tree only]
251*4882a593Smuzhiyun
252*4882a593SmuzhiyunSpecify this data in a U_BOOT_DEVICE() declaration in your board file:
253*4882a593Smuzhiyun
254*4882a593Smuzhiyunstruct exynos_spi_platdata platdata_spi0 = {
255*4882a593Smuzhiyun	.periph_id = ...
256*4882a593Smuzhiyun	.frequency = ...
257*4882a593Smuzhiyun	.regs = ...
258*4882a593Smuzhiyun	.deactivate_delay_us = ...
259*4882a593Smuzhiyun};
260*4882a593Smuzhiyun
261*4882a593SmuzhiyunU_BOOT_DEVICE(board_spi0) = {
262*4882a593Smuzhiyun	.name = "exynos_spi",
263*4882a593Smuzhiyun	.platdata = &platdata_spi0,
264*4882a593Smuzhiyun};
265*4882a593Smuzhiyun
266*4882a593SmuzhiyunYou will unfortunately need to put the struct definition into a header file
267*4882a593Smuzhiyunin this case so that your board file can use it.
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun9. Add the device private data
271*4882a593Smuzhiyun
272*4882a593SmuzhiyunMost devices have some private data which they use to keep track of things
273*4882a593Smuzhiyunwhile active. This is the run-time information and needs to be stored in
274*4882a593Smuzhiyuna structure. There is probably a structure in the driver that includes a
275*4882a593Smuzhiyun'struct spi_slave', so you can use that.
276*4882a593Smuzhiyun
277*4882a593Smuzhiyunstruct exynos_spi_slave {
278*4882a593Smuzhiyun	struct spi_slave slave;
279*4882a593Smuzhiyun	struct exynos_spi *regs;
280*4882a593Smuzhiyun	unsigned int freq;		/* Default frequency */
281*4882a593Smuzhiyun	unsigned int mode;
282*4882a593Smuzhiyun	enum periph_id periph_id;	/* Peripheral ID for this device */
283*4882a593Smuzhiyun	unsigned int fifo_size;
284*4882a593Smuzhiyun	int skip_preamble;
285*4882a593Smuzhiyun	struct spi_bus *bus;		/* Pointer to our SPI bus info */
286*4882a593Smuzhiyun	ulong last_transaction_us;	/* Time of last transaction end */
287*4882a593Smuzhiyun};
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun
290*4882a593SmuzhiyunWe should rename this to make its purpose more obvious, and get rid of
291*4882a593Smuzhiyunthe slave structure, so we have:
292*4882a593Smuzhiyun
293*4882a593Smuzhiyunstruct exynos_spi_priv {
294*4882a593Smuzhiyun	struct exynos_spi *regs;
295*4882a593Smuzhiyun	unsigned int freq;		/* Default frequency */
296*4882a593Smuzhiyun	unsigned int mode;
297*4882a593Smuzhiyun	enum periph_id periph_id;	/* Peripheral ID for this device */
298*4882a593Smuzhiyun	unsigned int fifo_size;
299*4882a593Smuzhiyun	int skip_preamble;
300*4882a593Smuzhiyun	ulong last_transaction_us;	/* Time of last transaction end */
301*4882a593Smuzhiyun};
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun
304*4882a593SmuzhiyunDM can auto-allocate this also:
305*4882a593Smuzhiyun
306*4882a593SmuzhiyunU_BOOT_DRIVER(spi_exynos) = {
307*4882a593Smuzhiyun...
308*4882a593Smuzhiyun	.priv_auto_alloc_size = sizeof(struct exynos_spi_priv),
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun
311*4882a593SmuzhiyunNote that this is created before the probe method is called, and destroyed
312*4882a593Smuzhiyunafter the remove method is called. It will be zeroed when the probe
313*4882a593Smuzhiyunmethod is called.
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun10. Add the probe() and remove() methods
317*4882a593Smuzhiyun
318*4882a593SmuzhiyunNote: It's a good idea to build repeatedly as you are working, to avoid a
319*4882a593Smuzhiyunhuge amount of work getting things compiling at the end.
320*4882a593Smuzhiyun
321*4882a593SmuzhiyunThe probe method is supposed to set up the hardware. U-Boot used to use
322*4882a593Smuzhiyunspi_setup_slave() to do this. So take a look at this function and see
323*4882a593Smuzhiyunwhat you can copy out to set things up.
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun
326*4882a593Smuzhiyunstatic int exynos_spi_probe(struct udevice *bus)
327*4882a593Smuzhiyun{
328*4882a593Smuzhiyun	struct exynos_spi_platdata *plat = dev_get_platdata(bus);
329*4882a593Smuzhiyun	struct exynos_spi_priv *priv = dev_get_priv(bus);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun	priv->regs = plat->regs;
332*4882a593Smuzhiyun	if (plat->periph_id == PERIPH_ID_SPI1 ||
333*4882a593Smuzhiyun	    plat->periph_id == PERIPH_ID_SPI2)
334*4882a593Smuzhiyun		priv->fifo_size = 64;
335*4882a593Smuzhiyun	else
336*4882a593Smuzhiyun		priv->fifo_size = 256;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun	priv->skip_preamble = 0;
339*4882a593Smuzhiyun	priv->last_transaction_us = timer_get_us();
340*4882a593Smuzhiyun	priv->freq = plat->frequency;
341*4882a593Smuzhiyun	priv->periph_id = plat->periph_id;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun	return 0;
344*4882a593Smuzhiyun}
345*4882a593Smuzhiyun
346*4882a593SmuzhiyunThis implementation doesn't actually touch the hardware, which is somewhat
347*4882a593Smuzhiyununusual for a driver. In this case we will do that when the device is
348*4882a593Smuzhiyunclaimed by something that wants to use the SPI bus.
349*4882a593Smuzhiyun
350*4882a593SmuzhiyunFor remove we could shut down the clocks, but in this case there is
351*4882a593Smuzhiyunnothing to do. DM frees any memory that it allocated, so we can just
352*4882a593Smuzhiyunremove exynos_spi_remove() and its reference in U_BOOT_DRIVER.
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun11. Implement set_speed()
356*4882a593Smuzhiyun
357*4882a593SmuzhiyunThis should set up clocks so that the SPI bus is running at the right
358*4882a593Smuzhiyunspeed. With the old API spi_claim_bus() would normally do this and several
359*4882a593Smuzhiyunof the following functions, so let's look at that function:
360*4882a593Smuzhiyun
361*4882a593Smuzhiyunint spi_claim_bus(struct spi_slave *slave)
362*4882a593Smuzhiyun{
363*4882a593Smuzhiyun	struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
364*4882a593Smuzhiyun	struct exynos_spi *regs = spi_slave->regs;
365*4882a593Smuzhiyun	u32 reg = 0;
366*4882a593Smuzhiyun	int ret;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun	ret = set_spi_clk(spi_slave->periph_id,
369*4882a593Smuzhiyun					spi_slave->freq);
370*4882a593Smuzhiyun	if (ret < 0) {
371*4882a593Smuzhiyun		debug("%s: Failed to setup spi clock\n", __func__);
372*4882a593Smuzhiyun		return ret;
373*4882a593Smuzhiyun	}
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun	exynos_pinmux_config(spi_slave->periph_id, PINMUX_FLAG_NONE);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun	spi_flush_fifo(slave);
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun	reg = readl(&regs->ch_cfg);
380*4882a593Smuzhiyun	reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun	if (spi_slave->mode & SPI_CPHA)
383*4882a593Smuzhiyun		reg |= SPI_CH_CPHA_B;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun	if (spi_slave->mode & SPI_CPOL)
386*4882a593Smuzhiyun		reg |= SPI_CH_CPOL_L;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun	writel(reg, &regs->ch_cfg);
389*4882a593Smuzhiyun	writel(SPI_FB_DELAY_180, &regs->fb_clk);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun	return 0;
392*4882a593Smuzhiyun}
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun
395*4882a593SmuzhiyunIt sets up the speed, mode, pinmux, feedback delay and clears the FIFOs.
396*4882a593SmuzhiyunWith DM these will happen in separate methods.
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun
399*4882a593SmuzhiyunHere is an example for the speed part:
400*4882a593Smuzhiyun
401*4882a593Smuzhiyunstatic int exynos_spi_set_speed(struct udevice *bus, uint speed)
402*4882a593Smuzhiyun{
403*4882a593Smuzhiyun	struct exynos_spi_platdata *plat = bus->platdata;
404*4882a593Smuzhiyun	struct exynos_spi_priv *priv = dev_get_priv(bus);
405*4882a593Smuzhiyun	int ret;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun	if (speed > plat->frequency)
408*4882a593Smuzhiyun		speed = plat->frequency;
409*4882a593Smuzhiyun	ret = set_spi_clk(priv->periph_id, speed);
410*4882a593Smuzhiyun	if (ret)
411*4882a593Smuzhiyun		return ret;
412*4882a593Smuzhiyun	priv->freq = speed;
413*4882a593Smuzhiyun	debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun	return 0;
416*4882a593Smuzhiyun}
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun12. Implement set_mode()
420*4882a593Smuzhiyun
421*4882a593SmuzhiyunThis should adjust the SPI mode (polarity, etc.). Again this code probably
422*4882a593Smuzhiyuncomes from the old spi_claim_bus(). Here is an example:
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun
425*4882a593Smuzhiyunstatic int exynos_spi_set_mode(struct udevice *bus, uint mode)
426*4882a593Smuzhiyun{
427*4882a593Smuzhiyun	struct exynos_spi_priv *priv = dev_get_priv(bus);
428*4882a593Smuzhiyun	uint32_t reg;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun	reg = readl(&priv->regs->ch_cfg);
431*4882a593Smuzhiyun	reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun	if (mode & SPI_CPHA)
434*4882a593Smuzhiyun		reg |= SPI_CH_CPHA_B;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun	if (mode & SPI_CPOL)
437*4882a593Smuzhiyun		reg |= SPI_CH_CPOL_L;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun	writel(reg, &priv->regs->ch_cfg);
440*4882a593Smuzhiyun	priv->mode = mode;
441*4882a593Smuzhiyun	debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun	return 0;
444*4882a593Smuzhiyun}
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun13. Implement claim_bus()
448*4882a593Smuzhiyun
449*4882a593SmuzhiyunThis is where a client wants to make use of the bus, so claims it first.
450*4882a593SmuzhiyunAt this point we need to make sure everything is set up ready for data
451*4882a593Smuzhiyuntransfer. Note that this function is wholly internal to the driver - at
452*4882a593Smuzhiyunpresent the SPI uclass never calls it.
453*4882a593Smuzhiyun
454*4882a593SmuzhiyunHere again we look at the old claim function and see some code that is
455*4882a593Smuzhiyunneeded. It is anything unrelated to speed and mode:
456*4882a593Smuzhiyun
457*4882a593Smuzhiyunstatic int exynos_spi_claim_bus(struct udevice *bus)
458*4882a593Smuzhiyun{
459*4882a593Smuzhiyun	struct exynos_spi_priv *priv = dev_get_priv(bus);
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun	exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE);
462*4882a593Smuzhiyun	spi_flush_fifo(priv->regs);
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun	writel(SPI_FB_DELAY_180, &priv->regs->fb_clk);
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun	return 0;
467*4882a593Smuzhiyun}
468*4882a593Smuzhiyun
469*4882a593SmuzhiyunThe spi_flush_fifo() function is in the removed part of the code, so we
470*4882a593Smuzhiyunneed to expose it again (perhaps with an #endif before it and '#if 0'
471*4882a593Smuzhiyunafter it). It only needs access to priv->regs which is why we have
472*4882a593Smuzhiyunpassed that in:
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun/**
475*4882a593Smuzhiyun * Flush spi tx, rx fifos and reset the SPI controller
476*4882a593Smuzhiyun *
477*4882a593Smuzhiyun * @param regs	Pointer to SPI registers
478*4882a593Smuzhiyun */
479*4882a593Smuzhiyunstatic void spi_flush_fifo(struct exynos_spi *regs)
480*4882a593Smuzhiyun{
481*4882a593Smuzhiyun	clrsetbits_le32(&regs->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
482*4882a593Smuzhiyun	clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
483*4882a593Smuzhiyun	setbits_le32(&regs->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
484*4882a593Smuzhiyun}
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun14. Implement release_bus()
488*4882a593Smuzhiyun
489*4882a593SmuzhiyunThis releases the bus - in our example the old code in spi_release_bus()
490*4882a593Smuzhiyunis a call to spi_flush_fifo, so we add:
491*4882a593Smuzhiyun
492*4882a593Smuzhiyunstatic int exynos_spi_release_bus(struct udevice *bus)
493*4882a593Smuzhiyun{
494*4882a593Smuzhiyun	struct exynos_spi_priv *priv = dev_get_priv(bus);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun	spi_flush_fifo(priv->regs);
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun	return 0;
499*4882a593Smuzhiyun}
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun15. Implement xfer()
503*4882a593Smuzhiyun
504*4882a593SmuzhiyunThis is the final method that we need to create, and it is where all the
505*4882a593Smuzhiyunwork happens. The method parameters are the same as the old spi_xfer() with
506*4882a593Smuzhiyunthe addition of a 'struct udevice' so conversion is pretty easy. Start
507*4882a593Smuzhiyunby copying the contents of spi_xfer() to your new xfer() method and proceed
508*4882a593Smuzhiyunfrom there.
509*4882a593Smuzhiyun
510*4882a593SmuzhiyunIf (flags & SPI_XFER_BEGIN) is non-zero then xfer() normally calls an
511*4882a593Smuzhiyunactivate function, something like this:
512*4882a593Smuzhiyun
513*4882a593Smuzhiyunvoid spi_cs_activate(struct spi_slave *slave)
514*4882a593Smuzhiyun{
515*4882a593Smuzhiyun	struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun	/* If it's too soon to do another transaction, wait */
518*4882a593Smuzhiyun	if (spi_slave->bus->deactivate_delay_us &&
519*4882a593Smuzhiyun	    spi_slave->last_transaction_us) {
520*4882a593Smuzhiyun		ulong delay_us;		/* The delay completed so far */
521*4882a593Smuzhiyun		delay_us = timer_get_us() - spi_slave->last_transaction_us;
522*4882a593Smuzhiyun		if (delay_us < spi_slave->bus->deactivate_delay_us)
523*4882a593Smuzhiyun			udelay(spi_slave->bus->deactivate_delay_us - delay_us);
524*4882a593Smuzhiyun	}
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun	clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
527*4882a593Smuzhiyun	debug("Activate CS, bus %d\n", spi_slave->slave.bus);
528*4882a593Smuzhiyun	spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
529*4882a593Smuzhiyun}
530*4882a593Smuzhiyun
531*4882a593SmuzhiyunThe new version looks like this:
532*4882a593Smuzhiyun
533*4882a593Smuzhiyunstatic void spi_cs_activate(struct udevice *dev)
534*4882a593Smuzhiyun{
535*4882a593Smuzhiyun	struct udevice *bus = dev->parent;
536*4882a593Smuzhiyun	struct exynos_spi_platdata *pdata = dev_get_platdata(bus);
537*4882a593Smuzhiyun	struct exynos_spi_priv *priv = dev_get_priv(bus);
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun	/* If it's too soon to do another transaction, wait */
540*4882a593Smuzhiyun	if (pdata->deactivate_delay_us &&
541*4882a593Smuzhiyun	    priv->last_transaction_us) {
542*4882a593Smuzhiyun		ulong delay_us;		/* The delay completed so far */
543*4882a593Smuzhiyun		delay_us = timer_get_us() - priv->last_transaction_us;
544*4882a593Smuzhiyun		if (delay_us < pdata->deactivate_delay_us)
545*4882a593Smuzhiyun			udelay(pdata->deactivate_delay_us - delay_us);
546*4882a593Smuzhiyun	}
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun	clrbits_le32(&priv->regs->cs_reg, SPI_SLAVE_SIG_INACT);
549*4882a593Smuzhiyun	debug("Activate CS, bus '%s'\n", bus->name);
550*4882a593Smuzhiyun	priv->skip_preamble = priv->mode & SPI_PREAMBLE;
551*4882a593Smuzhiyun}
552*4882a593Smuzhiyun
553*4882a593SmuzhiyunAll we have really done here is change the pointers and print the device name
554*4882a593Smuzhiyuninstead of the bus number. Other local static functions can be treated in
555*4882a593Smuzhiyunthe same way.
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun16. Set up the per-child data and child pre-probe function
559*4882a593Smuzhiyun
560*4882a593SmuzhiyunTo minimise the pain and complexity of the SPI subsystem while the driver
561*4882a593Smuzhiyunmodel change-over is in place, struct spi_slave is used to reference a
562*4882a593SmuzhiyunSPI bus slave, even though that slave is actually a struct udevice. In fact
563*4882a593Smuzhiyunstruct spi_slave is the device's child data. We need to make sure this space
564*4882a593Smuzhiyunis available. It is possible to allocate more space that struct spi_slave
565*4882a593Smuzhiyunneeds, but this is the minimum.
566*4882a593Smuzhiyun
567*4882a593SmuzhiyunU_BOOT_DRIVER(exynos_spi) = {
568*4882a593Smuzhiyun...
569*4882a593Smuzhiyun	.per_child_auto_alloc_size	= sizeof(struct spi_slave),
570*4882a593Smuzhiyun}
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun17. Optional: Set up cs_info() if you want it
574*4882a593Smuzhiyun
575*4882a593SmuzhiyunSometimes it is useful to know whether a SPI chip select is valid, but this
576*4882a593Smuzhiyunis not obvious from outside the driver. In this case you can provide a
577*4882a593Smuzhiyunmethod for cs_info() to deal with this. If you don't provide it, then the
578*4882a593Smuzhiyundevice tree will be used to determine what chip selects are valid.
579*4882a593Smuzhiyun
580*4882a593SmuzhiyunReturn -ENODEV if the supplied chip select is invalid, or 0 if it is valid.
581*4882a593SmuzhiyunIf you don't provide the cs_info() method, -ENODEV is assumed for all
582*4882a593Smuzhiyunchip selects that do not appear in the device tree.
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun18. Test it
586*4882a593Smuzhiyun
587*4882a593SmuzhiyunNow that you have the code written and it compiles, try testing it using
588*4882a593Smuzhiyunthe 'sf test' command. You may need to enable CONFIG_CMD_SF_TEST for your
589*4882a593Smuzhiyunboard.
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun19. Prepare patches and send them to the mailing lists
593*4882a593Smuzhiyun
594*4882a593SmuzhiyunYou can use 'tools/patman/patman' to prepare, check and send patches for
595*4882a593Smuzhiyunyour work. See the README for details.
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun20. A little note about SPI uclass features:
598*4882a593Smuzhiyun
599*4882a593SmuzhiyunThe SPI uclass keeps some information about each device 'dev' on the bus:
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun   struct dm_spi_slave_platdata - this is device_get_parent_platdata(dev)
602*4882a593Smuzhiyun		This is where the chip select number is stored, along with
603*4882a593Smuzhiyun		the default bus speed and mode. It is automatically read
604*4882a593Smuzhiyun		from the device tree in spi_child_post_bind(). It must not
605*4882a593Smuzhiyun		be changed at run-time after being set up because platform
606*4882a593Smuzhiyun		data is supposed to be immutable at run-time.
607*4882a593Smuzhiyun   struct spi_slave - this is device_get_parentdata(dev)
608*4882a593Smuzhiyun		Already mentioned above. It holds run-time information about
609*4882a593Smuzhiyun		the device.
610*4882a593Smuzhiyun
611*4882a593SmuzhiyunThere are also some SPI uclass methods that get called behind the scenes:
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun   spi_post_bind() - called when a new bus is bound
614*4882a593Smuzhiyun		This scans the device tree for devices on the bus, and binds
615*4882a593Smuzhiyun		each one. This in turn causes spi_child_post_bind() to be
616*4882a593Smuzhiyun		called for each, which reads the device tree information
617*4882a593Smuzhiyun		into the parent (per-child) platform data.
618*4882a593Smuzhiyun   spi_child_post_bind() - called when a new child is bound
619*4882a593Smuzhiyun		As mentioned above this reads the device tree information
620*4882a593Smuzhiyun		into the per-child platform data
621*4882a593Smuzhiyun   spi_child_pre_probe() - called before a new child is probed
622*4882a593Smuzhiyun		This sets up the mode and speed in struct spi_slave by
623*4882a593Smuzhiyun		copying it from the parent's platform data for this child.
624*4882a593Smuzhiyun		It also sets the 'dev' pointer, needed to permit passing
625*4882a593Smuzhiyun		'struct spi_slave' around the place without needing a
626*4882a593Smuzhiyun		separate 'struct udevice' pointer.
627*4882a593Smuzhiyun
628*4882a593SmuzhiyunThe above housekeeping makes it easier to write your SPI driver.
629