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