1 /* 2 * Copyright (C) 2016 Jagan Teki <jteki@openedev.com> 3 * Christophe Ricard <christophe.ricard@gmail.com> 4 * 5 * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com> 6 * 7 * Driver for McSPI controller on OMAP3. Based on davinci_spi.c 8 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 9 * 10 * Copyright (C) 2007 Atmel Corporation 11 * 12 * Parts taken from linux/drivers/spi/omap2_mcspi.c 13 * Copyright (C) 2005, 2006 Nokia Corporation 14 * 15 * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com> 16 * 17 * SPDX-License-Identifier: GPL-2.0+ 18 */ 19 20 #include <common.h> 21 #include <dm.h> 22 #include <spi.h> 23 #include <malloc.h> 24 #include <asm/io.h> 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 #if defined(CONFIG_AM33XX) || defined(CONFIG_AM43XX) 29 #define OMAP3_MCSPI1_BASE 0x48030100 30 #define OMAP3_MCSPI2_BASE 0x481A0100 31 #else 32 #define OMAP3_MCSPI1_BASE 0x48098000 33 #define OMAP3_MCSPI2_BASE 0x4809A000 34 #define OMAP3_MCSPI3_BASE 0x480B8000 35 #define OMAP3_MCSPI4_BASE 0x480BA000 36 #endif 37 38 #define OMAP4_MCSPI_REG_OFFSET 0x100 39 40 struct omap2_mcspi_platform_config { 41 unsigned int regs_offset; 42 }; 43 44 /* per-register bitmasks */ 45 #define OMAP3_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3) 46 #define OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2) 47 #define OMAP3_MCSPI_SYSCONFIG_AUTOIDLE BIT(0) 48 #define OMAP3_MCSPI_SYSCONFIG_SOFTRESET BIT(1) 49 50 #define OMAP3_MCSPI_SYSSTATUS_RESETDONE BIT(0) 51 52 #define OMAP3_MCSPI_MODULCTRL_SINGLE BIT(0) 53 #define OMAP3_MCSPI_MODULCTRL_MS BIT(2) 54 #define OMAP3_MCSPI_MODULCTRL_STEST BIT(3) 55 56 #define OMAP3_MCSPI_CHCONF_PHA BIT(0) 57 #define OMAP3_MCSPI_CHCONF_POL BIT(1) 58 #define OMAP3_MCSPI_CHCONF_CLKD_MASK GENMASK(5, 2) 59 #define OMAP3_MCSPI_CHCONF_EPOL BIT(6) 60 #define OMAP3_MCSPI_CHCONF_WL_MASK GENMASK(11, 7) 61 #define OMAP3_MCSPI_CHCONF_TRM_RX_ONLY BIT(12) 62 #define OMAP3_MCSPI_CHCONF_TRM_TX_ONLY BIT(13) 63 #define OMAP3_MCSPI_CHCONF_TRM_MASK GENMASK(13, 12) 64 #define OMAP3_MCSPI_CHCONF_DMAW BIT(14) 65 #define OMAP3_MCSPI_CHCONF_DMAR BIT(15) 66 #define OMAP3_MCSPI_CHCONF_DPE0 BIT(16) 67 #define OMAP3_MCSPI_CHCONF_DPE1 BIT(17) 68 #define OMAP3_MCSPI_CHCONF_IS BIT(18) 69 #define OMAP3_MCSPI_CHCONF_TURBO BIT(19) 70 #define OMAP3_MCSPI_CHCONF_FORCE BIT(20) 71 72 #define OMAP3_MCSPI_CHSTAT_RXS BIT(0) 73 #define OMAP3_MCSPI_CHSTAT_TXS BIT(1) 74 #define OMAP3_MCSPI_CHSTAT_EOT BIT(2) 75 76 #define OMAP3_MCSPI_CHCTRL_EN BIT(0) 77 #define OMAP3_MCSPI_CHCTRL_DIS (0 << 0) 78 79 #define OMAP3_MCSPI_WAKEUPENABLE_WKEN BIT(0) 80 #define MCSPI_PINDIR_D0_IN_D1_OUT 0 81 #define MCSPI_PINDIR_D0_OUT_D1_IN 1 82 83 #define OMAP3_MCSPI_MAX_FREQ 48000000 84 #define SPI_WAIT_TIMEOUT 10 85 86 /* OMAP3 McSPI registers */ 87 struct mcspi_channel { 88 unsigned int chconf; /* 0x2C, 0x40, 0x54, 0x68 */ 89 unsigned int chstat; /* 0x30, 0x44, 0x58, 0x6C */ 90 unsigned int chctrl; /* 0x34, 0x48, 0x5C, 0x70 */ 91 unsigned int tx; /* 0x38, 0x4C, 0x60, 0x74 */ 92 unsigned int rx; /* 0x3C, 0x50, 0x64, 0x78 */ 93 }; 94 95 struct mcspi { 96 unsigned char res1[0x10]; 97 unsigned int sysconfig; /* 0x10 */ 98 unsigned int sysstatus; /* 0x14 */ 99 unsigned int irqstatus; /* 0x18 */ 100 unsigned int irqenable; /* 0x1C */ 101 unsigned int wakeupenable; /* 0x20 */ 102 unsigned int syst; /* 0x24 */ 103 unsigned int modulctrl; /* 0x28 */ 104 struct mcspi_channel channel[4]; 105 /* channel0: 0x2C - 0x3C, bus 0 & 1 & 2 & 3 */ 106 /* channel1: 0x40 - 0x50, bus 0 & 1 */ 107 /* channel2: 0x54 - 0x64, bus 0 & 1 */ 108 /* channel3: 0x68 - 0x78, bus 0 */ 109 }; 110 111 struct omap3_spi_priv { 112 #ifndef CONFIG_DM_SPI 113 struct spi_slave slave; 114 #endif 115 struct mcspi *regs; 116 unsigned int cs; 117 unsigned int freq; 118 unsigned int mode; 119 unsigned int wordlen; 120 unsigned int pin_dir:1; 121 }; 122 123 static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val) 124 { 125 writel(val, &priv->regs->channel[priv->cs].chconf); 126 /* Flash post writes to make immediate effect */ 127 readl(&priv->regs->channel[priv->cs].chconf); 128 } 129 130 static void omap3_spi_set_enable(struct omap3_spi_priv *priv, int enable) 131 { 132 writel(enable, &priv->regs->channel[priv->cs].chctrl); 133 /* Flash post writes to make immediate effect */ 134 readl(&priv->regs->channel[priv->cs].chctrl); 135 } 136 137 static int omap3_spi_write(struct omap3_spi_priv *priv, unsigned int len, 138 const void *txp, unsigned long flags) 139 { 140 ulong start; 141 int i, chconf; 142 143 chconf = readl(&priv->regs->channel[priv->cs].chconf); 144 145 /* Enable the channel */ 146 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 147 148 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 149 chconf |= (priv->wordlen - 1) << 7; 150 chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY; 151 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 152 omap3_spi_write_chconf(priv, chconf); 153 154 for (i = 0; i < len; i++) { 155 /* wait till TX register is empty (TXS == 1) */ 156 start = get_timer(0); 157 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 158 OMAP3_MCSPI_CHSTAT_TXS)) { 159 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 160 printf("SPI TXS timed out, status=0x%08x\n", 161 readl(&priv->regs->channel[priv->cs].chstat)); 162 return -1; 163 } 164 } 165 /* Write the data */ 166 unsigned int *tx = &priv->regs->channel[priv->cs].tx; 167 if (priv->wordlen > 16) 168 writel(((u32 *)txp)[i], tx); 169 else if (priv->wordlen > 8) 170 writel(((u16 *)txp)[i], tx); 171 else 172 writel(((u8 *)txp)[i], tx); 173 } 174 175 /* wait to finish of transfer */ 176 while ((readl(&priv->regs->channel[priv->cs].chstat) & 177 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) != 178 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) 179 ; 180 181 /* Disable the channel otherwise the next immediate RX will get affected */ 182 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 183 184 if (flags & SPI_XFER_END) { 185 186 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 187 omap3_spi_write_chconf(priv, chconf); 188 } 189 return 0; 190 } 191 192 static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len, 193 void *rxp, unsigned long flags) 194 { 195 int i, chconf; 196 ulong start; 197 198 chconf = readl(&priv->regs->channel[priv->cs].chconf); 199 200 /* Enable the channel */ 201 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 202 203 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 204 chconf |= (priv->wordlen - 1) << 7; 205 chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY; 206 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 207 omap3_spi_write_chconf(priv, chconf); 208 209 writel(0, &priv->regs->channel[priv->cs].tx); 210 211 for (i = 0; i < len; i++) { 212 start = get_timer(0); 213 /* Wait till RX register contains data (RXS == 1) */ 214 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 215 OMAP3_MCSPI_CHSTAT_RXS)) { 216 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 217 printf("SPI RXS timed out, status=0x%08x\n", 218 readl(&priv->regs->channel[priv->cs].chstat)); 219 return -1; 220 } 221 } 222 223 /* Disable the channel to prevent furher receiving */ 224 if (i == (len - 1)) 225 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 226 227 /* Read the data */ 228 unsigned int *rx = &priv->regs->channel[priv->cs].rx; 229 if (priv->wordlen > 16) 230 ((u32 *)rxp)[i] = readl(rx); 231 else if (priv->wordlen > 8) 232 ((u16 *)rxp)[i] = (u16)readl(rx); 233 else 234 ((u8 *)rxp)[i] = (u8)readl(rx); 235 } 236 237 if (flags & SPI_XFER_END) { 238 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 239 omap3_spi_write_chconf(priv, chconf); 240 } 241 242 return 0; 243 } 244 245 /*McSPI Transmit Receive Mode*/ 246 static int omap3_spi_txrx(struct omap3_spi_priv *priv, unsigned int len, 247 const void *txp, void *rxp, unsigned long flags) 248 { 249 ulong start; 250 int chconf, i = 0; 251 252 chconf = readl(&priv->regs->channel[priv->cs].chconf); 253 254 /*Enable SPI channel*/ 255 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 256 257 /*set TRANSMIT-RECEIVE Mode*/ 258 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 259 chconf |= (priv->wordlen - 1) << 7; 260 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 261 omap3_spi_write_chconf(priv, chconf); 262 263 /*Shift in and out 1 byte at time*/ 264 for (i=0; i < len; i++){ 265 /* Write: wait for TX empty (TXS == 1)*/ 266 start = get_timer(0); 267 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 268 OMAP3_MCSPI_CHSTAT_TXS)) { 269 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 270 printf("SPI TXS timed out, status=0x%08x\n", 271 readl(&priv->regs->channel[priv->cs].chstat)); 272 return -1; 273 } 274 } 275 /* Write the data */ 276 unsigned int *tx = &priv->regs->channel[priv->cs].tx; 277 if (priv->wordlen > 16) 278 writel(((u32 *)txp)[i], tx); 279 else if (priv->wordlen > 8) 280 writel(((u16 *)txp)[i], tx); 281 else 282 writel(((u8 *)txp)[i], tx); 283 284 /*Read: wait for RX containing data (RXS == 1)*/ 285 start = get_timer(0); 286 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 287 OMAP3_MCSPI_CHSTAT_RXS)) { 288 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 289 printf("SPI RXS timed out, status=0x%08x\n", 290 readl(&priv->regs->channel[priv->cs].chstat)); 291 return -1; 292 } 293 } 294 /* Read the data */ 295 unsigned int *rx = &priv->regs->channel[priv->cs].rx; 296 if (priv->wordlen > 16) 297 ((u32 *)rxp)[i] = readl(rx); 298 else if (priv->wordlen > 8) 299 ((u16 *)rxp)[i] = (u16)readl(rx); 300 else 301 ((u8 *)rxp)[i] = (u8)readl(rx); 302 } 303 /* Disable the channel */ 304 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 305 306 /*if transfer must be terminated disable the channel*/ 307 if (flags & SPI_XFER_END) { 308 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 309 omap3_spi_write_chconf(priv, chconf); 310 } 311 312 return 0; 313 } 314 315 static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen, 316 const void *dout, void *din, unsigned long flags) 317 { 318 unsigned int len; 319 int ret = -1; 320 321 if (priv->wordlen < 4 || priv->wordlen > 32) { 322 printf("omap3_spi: invalid wordlen %d\n", priv->wordlen); 323 return -1; 324 } 325 326 if (bitlen % priv->wordlen) 327 return -1; 328 329 len = bitlen / priv->wordlen; 330 331 if (bitlen == 0) { /* only change CS */ 332 int chconf = readl(&priv->regs->channel[priv->cs].chconf); 333 334 if (flags & SPI_XFER_BEGIN) { 335 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 336 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 337 omap3_spi_write_chconf(priv, chconf); 338 } 339 if (flags & SPI_XFER_END) { 340 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 341 omap3_spi_write_chconf(priv, chconf); 342 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 343 } 344 ret = 0; 345 } else { 346 if (dout != NULL && din != NULL) 347 ret = omap3_spi_txrx(priv, len, dout, din, flags); 348 else if (dout != NULL) 349 ret = omap3_spi_write(priv, len, dout, flags); 350 else if (din != NULL) 351 ret = omap3_spi_read(priv, len, din, flags); 352 } 353 return ret; 354 } 355 356 static void _omap3_spi_set_speed(struct omap3_spi_priv *priv) 357 { 358 uint32_t confr, div = 0; 359 360 confr = readl(&priv->regs->channel[priv->cs].chconf); 361 362 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */ 363 if (priv->freq) { 364 while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div)) 365 > priv->freq) 366 div++; 367 } else { 368 div = 0xC; 369 } 370 371 /* set clock divisor */ 372 confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK; 373 confr |= div << 2; 374 375 omap3_spi_write_chconf(priv, confr); 376 } 377 378 static void _omap3_spi_set_mode(struct omap3_spi_priv *priv) 379 { 380 uint32_t confr; 381 382 confr = readl(&priv->regs->channel[priv->cs].chconf); 383 384 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS 385 * REVISIT: this controller could support SPI_3WIRE mode. 386 */ 387 if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) { 388 confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1); 389 confr |= OMAP3_MCSPI_CHCONF_DPE0; 390 } else { 391 confr &= ~OMAP3_MCSPI_CHCONF_DPE0; 392 confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1; 393 } 394 395 /* set SPI mode 0..3 */ 396 confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA); 397 if (priv->mode & SPI_CPHA) 398 confr |= OMAP3_MCSPI_CHCONF_PHA; 399 if (priv->mode & SPI_CPOL) 400 confr |= OMAP3_MCSPI_CHCONF_POL; 401 402 /* set chipselect polarity; manage with FORCE */ 403 if (!(priv->mode & SPI_CS_HIGH)) 404 confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */ 405 else 406 confr &= ~OMAP3_MCSPI_CHCONF_EPOL; 407 408 /* Transmit & receive mode */ 409 confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 410 411 omap3_spi_write_chconf(priv, confr); 412 } 413 414 static void _omap3_spi_set_wordlen(struct omap3_spi_priv *priv) 415 { 416 unsigned int confr; 417 418 /* McSPI individual channel configuration */ 419 confr = readl(&priv->regs->channel[priv->wordlen].chconf); 420 421 /* wordlength */ 422 confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK; 423 confr |= (priv->wordlen - 1) << 7; 424 425 omap3_spi_write_chconf(priv, confr); 426 } 427 428 static void spi_reset(struct mcspi *regs) 429 { 430 unsigned int tmp; 431 432 writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, ®s->sysconfig); 433 do { 434 tmp = readl(®s->sysstatus); 435 } while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE)); 436 437 writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE | 438 OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP | 439 OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, ®s->sysconfig); 440 441 writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, ®s->wakeupenable); 442 } 443 444 static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv) 445 { 446 unsigned int conf; 447 448 spi_reset(priv->regs); 449 450 /* 451 * setup when switching from (reset default) slave mode 452 * to single-channel master mode 453 */ 454 conf = readl(&priv->regs->modulctrl); 455 conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS); 456 conf |= OMAP3_MCSPI_MODULCTRL_SINGLE; 457 458 writel(conf, &priv->regs->modulctrl); 459 } 460 461 #ifndef CONFIG_DM_SPI 462 463 static inline struct omap3_spi_priv *to_omap3_spi(struct spi_slave *slave) 464 { 465 return container_of(slave, struct omap3_spi_priv, slave); 466 } 467 468 void spi_init(void) 469 { 470 /* do nothing */ 471 } 472 473 void spi_free_slave(struct spi_slave *slave) 474 { 475 struct omap3_spi_priv *priv = to_omap3_spi(slave); 476 477 free(priv); 478 } 479 480 int spi_claim_bus(struct spi_slave *slave) 481 { 482 struct omap3_spi_priv *priv = to_omap3_spi(slave); 483 484 _omap3_spi_claim_bus(priv); 485 _omap3_spi_set_wordlen(priv); 486 _omap3_spi_set_mode(priv); 487 _omap3_spi_set_speed(priv); 488 489 return 0; 490 } 491 492 void spi_release_bus(struct spi_slave *slave) 493 { 494 struct omap3_spi_priv *priv = to_omap3_spi(slave); 495 496 /* Reset the SPI hardware */ 497 spi_reset(priv->regs); 498 } 499 500 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, 501 unsigned int max_hz, unsigned int mode) 502 { 503 struct omap3_spi_priv *priv; 504 struct mcspi *regs; 505 506 /* 507 * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules) 508 * with different number of chip selects (CS, channels): 509 * McSPI1 has 4 CS (bus 0, cs 0 - 3) 510 * McSPI2 has 2 CS (bus 1, cs 0 - 1) 511 * McSPI3 has 2 CS (bus 2, cs 0 - 1) 512 * McSPI4 has 1 CS (bus 3, cs 0) 513 */ 514 515 switch (bus) { 516 case 0: 517 regs = (struct mcspi *)OMAP3_MCSPI1_BASE; 518 break; 519 #ifdef OMAP3_MCSPI2_BASE 520 case 1: 521 regs = (struct mcspi *)OMAP3_MCSPI2_BASE; 522 break; 523 #endif 524 #ifdef OMAP3_MCSPI3_BASE 525 case 2: 526 regs = (struct mcspi *)OMAP3_MCSPI3_BASE; 527 break; 528 #endif 529 #ifdef OMAP3_MCSPI4_BASE 530 case 3: 531 regs = (struct mcspi *)OMAP3_MCSPI4_BASE; 532 break; 533 #endif 534 default: 535 printf("SPI error: unsupported bus %i. Supported busses 0 - 3\n", bus); 536 return NULL; 537 } 538 539 if (((bus == 0) && (cs > 3)) || 540 ((bus == 1) && (cs > 1)) || 541 ((bus == 2) && (cs > 1)) || 542 ((bus == 3) && (cs > 0))) { 543 printf("SPI error: unsupported chip select %i on bus %i\n", cs, bus); 544 return NULL; 545 } 546 547 if (max_hz > OMAP3_MCSPI_MAX_FREQ) { 548 printf("SPI error: unsupported frequency %i Hz. Max frequency is 48 MHz\n", 549 max_hz); 550 return NULL; 551 } 552 553 if (mode > SPI_MODE_3) { 554 printf("SPI error: unsupported SPI mode %i\n", mode); 555 return NULL; 556 } 557 558 priv = spi_alloc_slave(struct omap3_spi_priv, bus, cs); 559 if (!priv) { 560 printf("SPI error: malloc of SPI structure failed\n"); 561 return NULL; 562 } 563 564 priv->regs = regs; 565 priv->cs = cs; 566 priv->freq = max_hz; 567 priv->mode = mode; 568 priv->wordlen = priv->slave.wordlen; 569 #if 0 570 /* Please migrate to DM_SPI support for this feature. */ 571 priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; 572 #endif 573 574 return &priv->slave; 575 } 576 577 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, 578 const void *dout, void *din, unsigned long flags) 579 { 580 struct omap3_spi_priv *priv = to_omap3_spi(slave); 581 582 return _spi_xfer(priv, bitlen, dout, din, flags); 583 } 584 585 #else 586 587 static int omap3_spi_claim_bus(struct udevice *dev) 588 { 589 struct udevice *bus = dev->parent; 590 struct omap3_spi_priv *priv = dev_get_priv(bus); 591 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); 592 593 priv->cs = slave_plat->cs; 594 _omap3_spi_claim_bus(priv); 595 596 return 0; 597 } 598 599 static int omap3_spi_release_bus(struct udevice *dev) 600 { 601 struct udevice *bus = dev->parent; 602 struct omap3_spi_priv *priv = dev_get_priv(bus); 603 604 /* Reset the SPI hardware */ 605 spi_reset(priv->regs); 606 607 return 0; 608 } 609 610 static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen) 611 { 612 struct udevice *bus = dev->parent; 613 struct omap3_spi_priv *priv = dev_get_priv(bus); 614 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); 615 616 priv->cs = slave_plat->cs; 617 priv->wordlen = wordlen; 618 _omap3_spi_set_wordlen(priv); 619 620 return 0; 621 } 622 623 static int omap3_spi_probe(struct udevice *dev) 624 { 625 struct omap3_spi_priv *priv = dev_get_priv(dev); 626 const void *blob = gd->fdt_blob; 627 int node = dev_of_offset(dev); 628 629 struct omap2_mcspi_platform_config* data = 630 (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev); 631 632 priv->regs = (struct mcspi *)(devfdt_get_addr(dev) + data->regs_offset); 633 priv->pin_dir = fdtdec_get_uint(blob, node, "ti,pindir-d0-out-d1-in", 634 MCSPI_PINDIR_D0_IN_D1_OUT); 635 priv->wordlen = SPI_DEFAULT_WORDLEN; 636 return 0; 637 } 638 639 static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen, 640 const void *dout, void *din, unsigned long flags) 641 { 642 struct udevice *bus = dev->parent; 643 struct omap3_spi_priv *priv = dev_get_priv(bus); 644 645 return _spi_xfer(priv, bitlen, dout, din, flags); 646 } 647 648 static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed) 649 { 650 struct udevice *bus = dev->parent; 651 struct omap3_spi_priv *priv = dev_get_priv(bus); 652 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); 653 654 priv->cs = slave_plat->cs; 655 priv->freq = slave_plat->max_hz; 656 _omap3_spi_set_speed(priv); 657 658 return 0; 659 } 660 661 static int omap3_spi_set_mode(struct udevice *dev, uint mode) 662 { 663 struct udevice *bus = dev->parent; 664 struct omap3_spi_priv *priv = dev_get_priv(bus); 665 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); 666 667 priv->cs = slave_plat->cs; 668 priv->mode = slave_plat->mode; 669 _omap3_spi_set_mode(priv); 670 671 return 0; 672 } 673 674 static const struct dm_spi_ops omap3_spi_ops = { 675 .claim_bus = omap3_spi_claim_bus, 676 .release_bus = omap3_spi_release_bus, 677 .set_wordlen = omap3_spi_set_wordlen, 678 .xfer = omap3_spi_xfer, 679 .set_speed = omap3_spi_set_speed, 680 .set_mode = omap3_spi_set_mode, 681 /* 682 * cs_info is not needed, since we require all chip selects to be 683 * in the device tree explicitly 684 */ 685 }; 686 687 static struct omap2_mcspi_platform_config omap2_pdata = { 688 .regs_offset = 0, 689 }; 690 691 static struct omap2_mcspi_platform_config omap4_pdata = { 692 .regs_offset = OMAP4_MCSPI_REG_OFFSET, 693 }; 694 695 static const struct udevice_id omap3_spi_ids[] = { 696 { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata }, 697 { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata }, 698 { } 699 }; 700 701 U_BOOT_DRIVER(omap3_spi) = { 702 .name = "omap3_spi", 703 .id = UCLASS_SPI, 704 .of_match = omap3_spi_ids, 705 .probe = omap3_spi_probe, 706 .ops = &omap3_spi_ops, 707 .priv_auto_alloc_size = sizeof(struct omap3_spi_priv), 708 }; 709 #endif 710