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(®s->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, ®s->ch_cfg); 389*4882a593Smuzhiyun writel(SPI_FB_DELAY_180, ®s->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(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST); 482*4882a593Smuzhiyun clrbits_le32(®s->ch_cfg, SPI_CH_RST); 483*4882a593Smuzhiyun setbits_le32(®s->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