linux/drivers/spi/spi-s3c24xx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2006 Ben Dooks
   4 * Copyright 2006-2009 Simtec Electronics
   5 *      Ben Dooks <ben@simtec.co.uk>
   6*/
   7
   8#include <linux/spinlock.h>
   9#include <linux/interrupt.h>
  10#include <linux/delay.h>
  11#include <linux/errno.h>
  12#include <linux/err.h>
  13#include <linux/clk.h>
  14#include <linux/platform_device.h>
  15#include <linux/gpio.h>
  16#include <linux/io.h>
  17#include <linux/slab.h>
  18
  19#include <linux/spi/spi.h>
  20#include <linux/spi/spi_bitbang.h>
  21#include <linux/spi/s3c24xx.h>
  22#include <linux/spi/s3c24xx-fiq.h>
  23#include <linux/module.h>
  24
  25#include <asm/fiq.h>
  26
  27#include "spi-s3c24xx-regs.h"
  28
  29/**
  30 * struct s3c24xx_spi_devstate - per device data
  31 * @hz: Last frequency calculated for @sppre field.
  32 * @mode: Last mode setting for the @spcon field.
  33 * @spcon: Value to write to the SPCON register.
  34 * @sppre: Value to write to the SPPRE register.
  35 */
  36struct s3c24xx_spi_devstate {
  37        unsigned int    hz;
  38        unsigned int    mode;
  39        u8              spcon;
  40        u8              sppre;
  41};
  42
  43enum spi_fiq_mode {
  44        FIQ_MODE_NONE   = 0,
  45        FIQ_MODE_TX     = 1,
  46        FIQ_MODE_RX     = 2,
  47        FIQ_MODE_TXRX   = 3,
  48};
  49
  50struct s3c24xx_spi {
  51        /* bitbang has to be first */
  52        struct spi_bitbang       bitbang;
  53        struct completion        done;
  54
  55        void __iomem            *regs;
  56        int                      irq;
  57        int                      len;
  58        int                      count;
  59
  60        struct fiq_handler       fiq_handler;
  61        enum spi_fiq_mode        fiq_mode;
  62        unsigned char            fiq_inuse;
  63        unsigned char            fiq_claimed;
  64
  65        void                    (*set_cs)(struct s3c2410_spi_info *spi,
  66                                          int cs, int pol);
  67
  68        /* data buffers */
  69        const unsigned char     *tx;
  70        unsigned char           *rx;
  71
  72        struct clk              *clk;
  73        struct spi_master       *master;
  74        struct spi_device       *curdev;
  75        struct device           *dev;
  76        struct s3c2410_spi_info *pdata;
  77};
  78
  79#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)
  80#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP)
  81
  82static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev)
  83{
  84        return spi_master_get_devdata(sdev->master);
  85}
  86
  87static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol)
  88{
  89        gpio_set_value(spi->pin_cs, pol);
  90}
  91
  92static void s3c24xx_spi_chipsel(struct spi_device *spi, int value)
  93{
  94        struct s3c24xx_spi_devstate *cs = spi->controller_state;
  95        struct s3c24xx_spi *hw = to_hw(spi);
  96        unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
  97
  98        /* change the chipselect state and the state of the spi engine clock */
  99
 100        switch (value) {
 101        case BITBANG_CS_INACTIVE:
 102                hw->set_cs(hw->pdata, spi->chip_select, cspol^1);
 103                writeb(cs->spcon, hw->regs + S3C2410_SPCON);
 104                break;
 105
 106        case BITBANG_CS_ACTIVE:
 107                writeb(cs->spcon | S3C2410_SPCON_ENSCK,
 108                       hw->regs + S3C2410_SPCON);
 109                hw->set_cs(hw->pdata, spi->chip_select, cspol);
 110                break;
 111        }
 112}
 113
 114static int s3c24xx_spi_update_state(struct spi_device *spi,
 115                                    struct spi_transfer *t)
 116{
 117        struct s3c24xx_spi *hw = to_hw(spi);
 118        struct s3c24xx_spi_devstate *cs = spi->controller_state;
 119        unsigned int hz;
 120        unsigned int div;
 121        unsigned long clk;
 122
 123        hz  = t ? t->speed_hz : spi->max_speed_hz;
 124
 125        if (!hz)
 126                hz = spi->max_speed_hz;
 127
 128        if (spi->mode != cs->mode) {
 129                u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK;
 130
 131                if (spi->mode & SPI_CPHA)
 132                        spcon |= S3C2410_SPCON_CPHA_FMTB;
 133
 134                if (spi->mode & SPI_CPOL)
 135                        spcon |= S3C2410_SPCON_CPOL_HIGH;
 136
 137                cs->mode = spi->mode;
 138                cs->spcon = spcon;
 139        }
 140
 141        if (cs->hz != hz) {
 142                clk = clk_get_rate(hw->clk);
 143                div = DIV_ROUND_UP(clk, hz * 2) - 1;
 144
 145                if (div > 255)
 146                        div = 255;
 147
 148                dev_dbg(&spi->dev, "pre-scaler=%d (wanted %d, got %ld)\n",
 149                        div, hz, clk / (2 * (div + 1)));
 150
 151                cs->hz = hz;
 152                cs->sppre = div;
 153        }
 154
 155        return 0;
 156}
 157
 158static int s3c24xx_spi_setupxfer(struct spi_device *spi,
 159                                 struct spi_transfer *t)
 160{
 161        struct s3c24xx_spi_devstate *cs = spi->controller_state;
 162        struct s3c24xx_spi *hw = to_hw(spi);
 163        int ret;
 164
 165        ret = s3c24xx_spi_update_state(spi, t);
 166        if (!ret)
 167                writeb(cs->sppre, hw->regs + S3C2410_SPPRE);
 168
 169        return ret;
 170}
 171
 172static int s3c24xx_spi_setup(struct spi_device *spi)
 173{
 174        struct s3c24xx_spi_devstate *cs = spi->controller_state;
 175        struct s3c24xx_spi *hw = to_hw(spi);
 176        int ret;
 177
 178        /* allocate settings on the first call */
 179        if (!cs) {
 180                cs = devm_kzalloc(&spi->dev,
 181                                  sizeof(struct s3c24xx_spi_devstate),
 182                                  GFP_KERNEL);
 183                if (!cs)
 184                        return -ENOMEM;
 185
 186                cs->spcon = SPCON_DEFAULT;
 187                cs->hz = -1;
 188                spi->controller_state = cs;
 189        }
 190
 191        /* initialise the state from the device */
 192        ret = s3c24xx_spi_update_state(spi, NULL);
 193        if (ret)
 194                return ret;
 195
 196        mutex_lock(&hw->bitbang.lock);
 197        if (!hw->bitbang.busy) {
 198                hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
 199                /* need to ndelay for 0.5 clocktick ? */
 200        }
 201        mutex_unlock(&hw->bitbang.lock);
 202
 203        return 0;
 204}
 205
 206static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count)
 207{
 208        return hw->tx ? hw->tx[count] : 0;
 209}
 210
 211#ifdef CONFIG_SPI_S3C24XX_FIQ
 212/* Support for FIQ based pseudo-DMA to improve the transfer speed.
 213 *
 214 * This code uses the assembly helper in spi_s3c24xx_spi.S which is
 215 * used by the FIQ core to move data between main memory and the peripheral
 216 * block. Since this is code running on the processor, there is no problem
 217 * with cache coherency of the buffers, so we can use any buffer we like.
 218 */
 219
 220/**
 221 * struct spi_fiq_code - FIQ code and header
 222 * @length: The length of the code fragment, excluding this header.
 223 * @ack_offset: The offset from @data to the word to place the IRQ ACK bit at.
 224 * @data: The code itself to install as a FIQ handler.
 225 */
 226struct spi_fiq_code {
 227        u32     length;
 228        u32     ack_offset;
 229        u8      data[];
 230};
 231
 232/**
 233 * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer
 234 * @hw: The hardware state.
 235 *
 236 * Claim the FIQ handler (only one can be active at any one time) and
 237 * then setup the correct transfer code for this transfer.
 238 *
 239 * This call updates all the necessary state information if successful,
 240 * so the caller does not need to do anything more than start the transfer
 241 * as normal, since the IRQ will have been re-routed to the FIQ handler.
 242*/
 243static void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw)
 244{
 245        struct pt_regs regs;
 246        enum spi_fiq_mode mode;
 247        struct spi_fiq_code *code;
 248        u32 *ack_ptr = NULL;
 249        int ret;
 250
 251        if (!hw->fiq_claimed) {
 252                /* try and claim fiq if we haven't got it, and if not
 253                 * then return and simply use another transfer method */
 254
 255                ret = claim_fiq(&hw->fiq_handler);
 256                if (ret)
 257                        return;
 258        }
 259
 260        if (hw->tx && !hw->rx)
 261                mode = FIQ_MODE_TX;
 262        else if (hw->rx && !hw->tx)
 263                mode = FIQ_MODE_RX;
 264        else
 265                mode = FIQ_MODE_TXRX;
 266
 267        regs.uregs[fiq_rspi] = (long)hw->regs;
 268        regs.uregs[fiq_rrx]  = (long)hw->rx;
 269        regs.uregs[fiq_rtx]  = (long)hw->tx + 1;
 270        regs.uregs[fiq_rcount] = hw->len - 1;
 271
 272        set_fiq_regs(&regs);
 273
 274        if (hw->fiq_mode != mode) {
 275                hw->fiq_mode = mode;
 276
 277                switch (mode) {
 278                case FIQ_MODE_TX:
 279                        code = &s3c24xx_spi_fiq_tx;
 280                        break;
 281                case FIQ_MODE_RX:
 282                        code = &s3c24xx_spi_fiq_rx;
 283                        break;
 284                case FIQ_MODE_TXRX:
 285                        code = &s3c24xx_spi_fiq_txrx;
 286                        break;
 287                default:
 288                        code = NULL;
 289                }
 290
 291                BUG_ON(!code);
 292
 293                ack_ptr = (u32 *)&code->data[code->ack_offset];
 294                set_fiq_handler(&code->data, code->length);
 295        }
 296
 297        s3c24xx_set_fiq(hw->irq, ack_ptr, true);
 298
 299        hw->fiq_mode = mode;
 300        hw->fiq_inuse = 1;
 301}
 302
 303/**
 304 * s3c24xx_spi_fiqop - FIQ core code callback
 305 * @pw: Data registered with the handler
 306 * @release: Whether this is a release or a return.
 307 *
 308 * Called by the FIQ code when another module wants to use the FIQ, so
 309 * return whether we are currently using this or not and then update our
 310 * internal state.
 311 */
 312static int s3c24xx_spi_fiqop(void *pw, int release)
 313{
 314        struct s3c24xx_spi *hw = pw;
 315        int ret = 0;
 316
 317        if (release) {
 318                if (hw->fiq_inuse)
 319                        ret = -EBUSY;
 320
 321                /* note, we do not need to unroute the FIQ, as the FIQ
 322                 * vector code de-routes it to signal the end of transfer */
 323
 324                hw->fiq_mode = FIQ_MODE_NONE;
 325                hw->fiq_claimed = 0;
 326        } else {
 327                hw->fiq_claimed = 1;
 328        }
 329
 330        return ret;
 331}
 332
 333/**
 334 * s3c24xx_spi_initfiq - setup the information for the FIQ core
 335 * @hw: The hardware state.
 336 *
 337 * Setup the fiq_handler block to pass to the FIQ core.
 338 */
 339static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *hw)
 340{
 341        hw->fiq_handler.dev_id = hw;
 342        hw->fiq_handler.name = dev_name(hw->dev);
 343        hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop;
 344}
 345
 346/**
 347 * s3c24xx_spi_usefiq - return if we should be using FIQ.
 348 * @hw: The hardware state.
 349 *
 350 * Return true if the platform data specifies whether this channel is
 351 * allowed to use the FIQ.
 352 */
 353static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *hw)
 354{
 355        return hw->pdata->use_fiq;
 356}
 357
 358/**
 359 * s3c24xx_spi_usingfiq - return if channel is using FIQ
 360 * @spi: The hardware state.
 361 *
 362 * Return whether the channel is currently using the FIQ (separate from
 363 * whether the FIQ is claimed).
 364 */
 365static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *spi)
 366{
 367        return spi->fiq_inuse;
 368}
 369#else
 370
 371static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *s) { }
 372static inline void s3c24xx_spi_tryfiq(struct s3c24xx_spi *s) { }
 373static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *s) { return false; }
 374static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *s) { return false; }
 375
 376#endif /* CONFIG_SPI_S3C24XX_FIQ */
 377
 378static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
 379{
 380        struct s3c24xx_spi *hw = to_hw(spi);
 381
 382        hw->tx = t->tx_buf;
 383        hw->rx = t->rx_buf;
 384        hw->len = t->len;
 385        hw->count = 0;
 386
 387        init_completion(&hw->done);
 388
 389        hw->fiq_inuse = 0;
 390        if (s3c24xx_spi_usefiq(hw) && t->len >= 3)
 391                s3c24xx_spi_tryfiq(hw);
 392
 393        /* send the first byte */
 394        writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
 395
 396        wait_for_completion(&hw->done);
 397        return hw->count;
 398}
 399
 400static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
 401{
 402        struct s3c24xx_spi *hw = dev;
 403        unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
 404        unsigned int count = hw->count;
 405
 406        if (spsta & S3C2410_SPSTA_DCOL) {
 407                dev_dbg(hw->dev, "data-collision\n");
 408                complete(&hw->done);
 409                goto irq_done;
 410        }
 411
 412        if (!(spsta & S3C2410_SPSTA_READY)) {
 413                dev_dbg(hw->dev, "spi not ready for tx?\n");
 414                complete(&hw->done);
 415                goto irq_done;
 416        }
 417
 418        if (!s3c24xx_spi_usingfiq(hw)) {
 419                hw->count++;
 420
 421                if (hw->rx)
 422                        hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
 423
 424                count++;
 425
 426                if (count < hw->len)
 427                        writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
 428                else
 429                        complete(&hw->done);
 430        } else {
 431                hw->count = hw->len;
 432                hw->fiq_inuse = 0;
 433
 434                if (hw->rx)
 435                        hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT);
 436
 437                complete(&hw->done);
 438        }
 439
 440 irq_done:
 441        return IRQ_HANDLED;
 442}
 443
 444static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
 445{
 446        /* for the moment, permanently enable the clock */
 447
 448        clk_enable(hw->clk);
 449
 450        /* program defaults into the registers */
 451
 452        writeb(0xff, hw->regs + S3C2410_SPPRE);
 453        writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
 454        writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);
 455
 456        if (hw->pdata) {
 457                if (hw->set_cs == s3c24xx_spi_gpiocs)
 458                        gpio_direction_output(hw->pdata->pin_cs, 1);
 459
 460                if (hw->pdata->gpio_setup)
 461                        hw->pdata->gpio_setup(hw->pdata, 1);
 462        }
 463}
 464
 465static int s3c24xx_spi_probe(struct platform_device *pdev)
 466{
 467        struct s3c2410_spi_info *pdata;
 468        struct s3c24xx_spi *hw;
 469        struct spi_master *master;
 470        int err = 0;
 471
 472        master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
 473        if (master == NULL) {
 474                dev_err(&pdev->dev, "No memory for spi_master\n");
 475                return -ENOMEM;
 476        }
 477
 478        hw = spi_master_get_devdata(master);
 479
 480        hw->master = master;
 481        hw->pdata = pdata = dev_get_platdata(&pdev->dev);
 482        hw->dev = &pdev->dev;
 483
 484        if (pdata == NULL) {
 485                dev_err(&pdev->dev, "No platform data supplied\n");
 486                err = -ENOENT;
 487                goto err_no_pdata;
 488        }
 489
 490        platform_set_drvdata(pdev, hw);
 491        init_completion(&hw->done);
 492
 493        /* initialise fiq handler */
 494
 495        s3c24xx_spi_initfiq(hw);
 496
 497        /* setup the master state. */
 498
 499        /* the spi->mode bits understood by this driver: */
 500        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 501
 502        master->num_chipselect = hw->pdata->num_cs;
 503        master->bus_num = pdata->bus_num;
 504        master->bits_per_word_mask = SPI_BPW_MASK(8);
 505
 506        /* setup the state for the bitbang driver */
 507
 508        hw->bitbang.master         = hw->master;
 509        hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
 510        hw->bitbang.chipselect     = s3c24xx_spi_chipsel;
 511        hw->bitbang.txrx_bufs      = s3c24xx_spi_txrx;
 512
 513        hw->master->setup  = s3c24xx_spi_setup;
 514
 515        dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
 516
 517        /* find and map our resources */
 518        hw->regs = devm_platform_ioremap_resource(pdev, 0);
 519        if (IS_ERR(hw->regs)) {
 520                err = PTR_ERR(hw->regs);
 521                goto err_no_pdata;
 522        }
 523
 524        hw->irq = platform_get_irq(pdev, 0);
 525        if (hw->irq < 0) {
 526                err = -ENOENT;
 527                goto err_no_pdata;
 528        }
 529
 530        err = devm_request_irq(&pdev->dev, hw->irq, s3c24xx_spi_irq, 0,
 531                                pdev->name, hw);
 532        if (err) {
 533                dev_err(&pdev->dev, "Cannot claim IRQ\n");
 534                goto err_no_pdata;
 535        }
 536
 537        hw->clk = devm_clk_get(&pdev->dev, "spi");
 538        if (IS_ERR(hw->clk)) {
 539                dev_err(&pdev->dev, "No clock for device\n");
 540                err = PTR_ERR(hw->clk);
 541                goto err_no_pdata;
 542        }
 543
 544        /* setup any gpio we can */
 545
 546        if (!pdata->set_cs) {
 547                if (pdata->pin_cs < 0) {
 548                        dev_err(&pdev->dev, "No chipselect pin\n");
 549                        err = -EINVAL;
 550                        goto err_register;
 551                }
 552
 553                err = devm_gpio_request(&pdev->dev, pdata->pin_cs,
 554                                        dev_name(&pdev->dev));
 555                if (err) {
 556                        dev_err(&pdev->dev, "Failed to get gpio for cs\n");
 557                        goto err_register;
 558                }
 559
 560                hw->set_cs = s3c24xx_spi_gpiocs;
 561                gpio_direction_output(pdata->pin_cs, 1);
 562        } else
 563                hw->set_cs = pdata->set_cs;
 564
 565        s3c24xx_spi_initialsetup(hw);
 566
 567        /* register our spi controller */
 568
 569        err = spi_bitbang_start(&hw->bitbang);
 570        if (err) {
 571                dev_err(&pdev->dev, "Failed to register SPI master\n");
 572                goto err_register;
 573        }
 574
 575        return 0;
 576
 577 err_register:
 578        clk_disable(hw->clk);
 579
 580 err_no_pdata:
 581        spi_master_put(hw->master);
 582        return err;
 583}
 584
 585static int s3c24xx_spi_remove(struct platform_device *dev)
 586{
 587        struct s3c24xx_spi *hw = platform_get_drvdata(dev);
 588
 589        spi_bitbang_stop(&hw->bitbang);
 590        clk_disable(hw->clk);
 591        spi_master_put(hw->master);
 592        return 0;
 593}
 594
 595
 596#ifdef CONFIG_PM
 597
 598static int s3c24xx_spi_suspend(struct device *dev)
 599{
 600        struct s3c24xx_spi *hw = dev_get_drvdata(dev);
 601        int ret;
 602
 603        ret = spi_master_suspend(hw->master);
 604        if (ret)
 605                return ret;
 606
 607        if (hw->pdata && hw->pdata->gpio_setup)
 608                hw->pdata->gpio_setup(hw->pdata, 0);
 609
 610        clk_disable(hw->clk);
 611        return 0;
 612}
 613
 614static int s3c24xx_spi_resume(struct device *dev)
 615{
 616        struct s3c24xx_spi *hw = dev_get_drvdata(dev);
 617
 618        s3c24xx_spi_initialsetup(hw);
 619        return spi_master_resume(hw->master);
 620}
 621
 622static const struct dev_pm_ops s3c24xx_spi_pmops = {
 623        .suspend        = s3c24xx_spi_suspend,
 624        .resume         = s3c24xx_spi_resume,
 625};
 626
 627#define S3C24XX_SPI_PMOPS &s3c24xx_spi_pmops
 628#else
 629#define S3C24XX_SPI_PMOPS NULL
 630#endif /* CONFIG_PM */
 631
 632MODULE_ALIAS("platform:s3c2410-spi");
 633static struct platform_driver s3c24xx_spi_driver = {
 634        .probe          = s3c24xx_spi_probe,
 635        .remove         = s3c24xx_spi_remove,
 636        .driver         = {
 637                .name   = "s3c2410-spi",
 638                .pm     = S3C24XX_SPI_PMOPS,
 639        },
 640};
 641module_platform_driver(s3c24xx_spi_driver);
 642
 643MODULE_DESCRIPTION("S3C24XX SPI Driver");
 644MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 645MODULE_LICENSE("GPL");
 646