linux/drivers/spi/spi-bcm63xx.c
<<
>>
Prefs
   1/*
   2 * Broadcom BCM63xx SPI controller support
   3 *
   4 * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
   5 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License
   9 * as published by the Free Software Foundation; either version 2
  10 * of the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the
  19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  20 */
  21
  22#include <linux/kernel.h>
  23#include <linux/init.h>
  24#include <linux/clk.h>
  25#include <linux/io.h>
  26#include <linux/module.h>
  27#include <linux/platform_device.h>
  28#include <linux/delay.h>
  29#include <linux/interrupt.h>
  30#include <linux/spi/spi.h>
  31#include <linux/completion.h>
  32#include <linux/err.h>
  33#include <linux/workqueue.h>
  34#include <linux/pm_runtime.h>
  35
  36#include <bcm63xx_dev_spi.h>
  37
  38#define PFX             KBUILD_MODNAME
  39
  40#define BCM63XX_SPI_MAX_PREPEND         15
  41
  42struct bcm63xx_spi {
  43        struct completion       done;
  44
  45        void __iomem            *regs;
  46        int                     irq;
  47
  48        /* Platform data */
  49        u32                     speed_hz;
  50        unsigned                fifo_size;
  51        unsigned int            msg_type_shift;
  52        unsigned int            msg_ctl_width;
  53
  54        /* data iomem */
  55        u8 __iomem              *tx_io;
  56        const u8 __iomem        *rx_io;
  57
  58        struct clk              *clk;
  59        struct platform_device  *pdev;
  60};
  61
  62static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
  63                                unsigned int offset)
  64{
  65        return bcm_readb(bs->regs + bcm63xx_spireg(offset));
  66}
  67
  68static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
  69                                unsigned int offset)
  70{
  71        return bcm_readw(bs->regs + bcm63xx_spireg(offset));
  72}
  73
  74static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
  75                                  u8 value, unsigned int offset)
  76{
  77        bcm_writeb(value, bs->regs + bcm63xx_spireg(offset));
  78}
  79
  80static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
  81                                  u16 value, unsigned int offset)
  82{
  83        bcm_writew(value, bs->regs + bcm63xx_spireg(offset));
  84}
  85
  86static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
  87        { 20000000, SPI_CLK_20MHZ },
  88        { 12500000, SPI_CLK_12_50MHZ },
  89        {  6250000, SPI_CLK_6_250MHZ },
  90        {  3125000, SPI_CLK_3_125MHZ },
  91        {  1563000, SPI_CLK_1_563MHZ },
  92        {   781000, SPI_CLK_0_781MHZ },
  93        {   391000, SPI_CLK_0_391MHZ }
  94};
  95
  96static int bcm63xx_spi_check_transfer(struct spi_device *spi,
  97                                        struct spi_transfer *t)
  98{
  99        u8 bits_per_word;
 100
 101        bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
 102        if (bits_per_word != 8) {
 103                dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
 104                        __func__, bits_per_word);
 105                return -EINVAL;
 106        }
 107
 108        if (spi->chip_select > spi->master->num_chipselect) {
 109                dev_err(&spi->dev, "%s, unsupported slave %d\n",
 110                        __func__, spi->chip_select);
 111                return -EINVAL;
 112        }
 113
 114        return 0;
 115}
 116
 117static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
 118                                      struct spi_transfer *t)
 119{
 120        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 121        u32 hz;
 122        u8 clk_cfg, reg;
 123        int i;
 124
 125        hz = (t) ? t->speed_hz : spi->max_speed_hz;
 126
 127        /* Find the closest clock configuration */
 128        for (i = 0; i < SPI_CLK_MASK; i++) {
 129                if (hz >= bcm63xx_spi_freq_table[i][0]) {
 130                        clk_cfg = bcm63xx_spi_freq_table[i][1];
 131                        break;
 132                }
 133        }
 134
 135        /* No matching configuration found, default to lowest */
 136        if (i == SPI_CLK_MASK)
 137                clk_cfg = SPI_CLK_0_391MHZ;
 138
 139        /* clear existing clock configuration bits of the register */
 140        reg = bcm_spi_readb(bs, SPI_CLK_CFG);
 141        reg &= ~SPI_CLK_MASK;
 142        reg |= clk_cfg;
 143
 144        bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
 145        dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
 146                clk_cfg, hz);
 147}
 148
 149/* the spi->mode bits understood by this driver: */
 150#define MODEBITS (SPI_CPOL | SPI_CPHA)
 151
 152static int bcm63xx_spi_setup(struct spi_device *spi)
 153{
 154        struct bcm63xx_spi *bs;
 155
 156        bs = spi_master_get_devdata(spi->master);
 157
 158        if (!spi->bits_per_word)
 159                spi->bits_per_word = 8;
 160
 161        if (spi->mode & ~MODEBITS) {
 162                dev_err(&spi->dev, "%s, unsupported mode bits %x\n",
 163                        __func__, spi->mode & ~MODEBITS);
 164                return -EINVAL;
 165        }
 166
 167        dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
 168                __func__, spi->mode & MODEBITS, spi->bits_per_word, 0);
 169
 170        return 0;
 171}
 172
 173static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
 174                                unsigned int num_transfers)
 175{
 176        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 177        u16 msg_ctl;
 178        u16 cmd;
 179        u8 rx_tail;
 180        unsigned int i, timeout = 0, prepend_len = 0, len = 0;
 181        struct spi_transfer *t = first;
 182        bool do_rx = false;
 183        bool do_tx = false;
 184
 185        /* Disable the CMD_DONE interrupt */
 186        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 187
 188        dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
 189                t->tx_buf, t->rx_buf, t->len);
 190
 191        if (num_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
 192                prepend_len = t->len;
 193
 194        /* prepare the buffer */
 195        for (i = 0; i < num_transfers; i++) {
 196                if (t->tx_buf) {
 197                        do_tx = true;
 198                        memcpy_toio(bs->tx_io + len, t->tx_buf, t->len);
 199
 200                        /* don't prepend more than one tx */
 201                        if (t != first)
 202                                prepend_len = 0;
 203                }
 204
 205                if (t->rx_buf) {
 206                        do_rx = true;
 207                        /* prepend is half-duplex write only */
 208                        if (t == first)
 209                                prepend_len = 0;
 210                }
 211
 212                len += t->len;
 213
 214                t = list_entry(t->transfer_list.next, struct spi_transfer,
 215                               transfer_list);
 216        }
 217
 218        len -= prepend_len;
 219
 220        init_completion(&bs->done);
 221
 222        /* Fill in the Message control register */
 223        msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
 224
 225        if (do_rx && do_tx && prepend_len == 0)
 226                msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
 227        else if (do_rx)
 228                msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
 229        else if (do_tx)
 230                msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
 231
 232        switch (bs->msg_ctl_width) {
 233        case 8:
 234                bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
 235                break;
 236        case 16:
 237                bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
 238                break;
 239        }
 240
 241        /* Issue the transfer */
 242        cmd = SPI_CMD_START_IMMEDIATE;
 243        cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
 244        cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
 245        bcm_spi_writew(bs, cmd, SPI_CMD);
 246
 247        /* Enable the CMD_DONE interrupt */
 248        bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
 249
 250        timeout = wait_for_completion_timeout(&bs->done, HZ);
 251        if (!timeout)
 252                return -ETIMEDOUT;
 253
 254        /* read out all data */
 255        rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
 256
 257        if (do_rx && rx_tail != len)
 258                return -EIO;
 259
 260        if (!rx_tail)
 261                return 0;
 262
 263        len = 0;
 264        t = first;
 265        /* Read out all the data */
 266        for (i = 0; i < num_transfers; i++) {
 267                if (t->rx_buf)
 268                        memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);
 269
 270                if (t != first || prepend_len == 0)
 271                        len += t->len;
 272
 273                t = list_entry(t->transfer_list.next, struct spi_transfer,
 274                               transfer_list);
 275        }
 276
 277        return 0;
 278}
 279
 280static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
 281{
 282        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 283
 284        pm_runtime_get_sync(&bs->pdev->dev);
 285
 286        return 0;
 287}
 288
 289static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
 290{
 291        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 292
 293        pm_runtime_put(&bs->pdev->dev);
 294
 295        return 0;
 296}
 297
 298static int bcm63xx_spi_transfer_one(struct spi_master *master,
 299                                        struct spi_message *m)
 300{
 301        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 302        struct spi_transfer *t, *first = NULL;
 303        struct spi_device *spi = m->spi;
 304        int status = 0;
 305        unsigned int n_transfers = 0, total_len = 0;
 306        bool can_use_prepend = false;
 307
 308        /*
 309         * This SPI controller does not support keeping CS active after a
 310         * transfer.
 311         * Work around this by merging as many transfers we can into one big
 312         * full-duplex transfers.
 313         */
 314        list_for_each_entry(t, &m->transfers, transfer_list) {
 315                status = bcm63xx_spi_check_transfer(spi, t);
 316                if (status < 0)
 317                        goto exit;
 318
 319                if (!first)
 320                        first = t;
 321
 322                n_transfers++;
 323                total_len += t->len;
 324
 325                if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
 326                    first->len <= BCM63XX_SPI_MAX_PREPEND)
 327                        can_use_prepend = true;
 328                else if (can_use_prepend && t->tx_buf)
 329                        can_use_prepend = false;
 330
 331                /* we can only transfer one fifo worth of data */
 332                if ((can_use_prepend &&
 333                     total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
 334                    (!can_use_prepend && total_len > bs->fifo_size)) {
 335                        dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
 336                                total_len, bs->fifo_size);
 337                        status = -EINVAL;
 338                        goto exit;
 339                }
 340
 341                /* all combined transfers have to have the same speed */
 342                if (t->speed_hz != first->speed_hz) {
 343                        dev_err(&spi->dev, "unable to change speed between transfers\n");
 344                        status = -EINVAL;
 345                        goto exit;
 346                }
 347
 348                /* CS will be deasserted directly after transfer */
 349                if (t->delay_usecs) {
 350                        dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
 351                        status = -EINVAL;
 352                        goto exit;
 353                }
 354
 355                if (t->cs_change ||
 356                    list_is_last(&t->transfer_list, &m->transfers)) {
 357                        /* configure adapter for a new transfer */
 358                        bcm63xx_spi_setup_transfer(spi, first);
 359
 360                        /* send the data */
 361                        status = bcm63xx_txrx_bufs(spi, first, n_transfers);
 362                        if (status)
 363                                goto exit;
 364
 365                        m->actual_length += total_len;
 366
 367                        first = NULL;
 368                        n_transfers = 0;
 369                        total_len = 0;
 370                        can_use_prepend = false;
 371                }
 372        }
 373exit:
 374        m->status = status;
 375        spi_finalize_current_message(master);
 376
 377        return 0;
 378}
 379
 380/* This driver supports single master mode only. Hence
 381 * CMD_DONE is the only interrupt we care about
 382 */
 383static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
 384{
 385        struct spi_master *master = (struct spi_master *)dev_id;
 386        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 387        u8 intr;
 388
 389        /* Read interupts and clear them immediately */
 390        intr = bcm_spi_readb(bs, SPI_INT_STATUS);
 391        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 392        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 393
 394        /* A transfer completed */
 395        if (intr & SPI_INTR_CMD_DONE)
 396                complete(&bs->done);
 397
 398        return IRQ_HANDLED;
 399}
 400
 401
 402static int bcm63xx_spi_probe(struct platform_device *pdev)
 403{
 404        struct resource *r;
 405        struct device *dev = &pdev->dev;
 406        struct bcm63xx_spi_pdata *pdata = pdev->dev.platform_data;
 407        int irq;
 408        struct spi_master *master;
 409        struct clk *clk;
 410        struct bcm63xx_spi *bs;
 411        int ret;
 412
 413        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 414        if (!r) {
 415                dev_err(dev, "no iomem\n");
 416                ret = -ENXIO;
 417                goto out;
 418        }
 419
 420        irq = platform_get_irq(pdev, 0);
 421        if (irq < 0) {
 422                dev_err(dev, "no irq\n");
 423                ret = -ENXIO;
 424                goto out;
 425        }
 426
 427        clk = clk_get(dev, "spi");
 428        if (IS_ERR(clk)) {
 429                dev_err(dev, "no clock for device\n");
 430                ret = PTR_ERR(clk);
 431                goto out;
 432        }
 433
 434        master = spi_alloc_master(dev, sizeof(*bs));
 435        if (!master) {
 436                dev_err(dev, "out of memory\n");
 437                ret = -ENOMEM;
 438                goto out_clk;
 439        }
 440
 441        bs = spi_master_get_devdata(master);
 442
 443        platform_set_drvdata(pdev, master);
 444        bs->pdev = pdev;
 445
 446        if (!devm_request_mem_region(&pdev->dev, r->start,
 447                                        resource_size(r), PFX)) {
 448                dev_err(dev, "iomem request failed\n");
 449                ret = -ENXIO;
 450                goto out_err;
 451        }
 452
 453        bs->regs = devm_ioremap_nocache(&pdev->dev, r->start,
 454                                                        resource_size(r));
 455        if (!bs->regs) {
 456                dev_err(dev, "unable to ioremap regs\n");
 457                ret = -ENOMEM;
 458                goto out_err;
 459        }
 460
 461        bs->irq = irq;
 462        bs->clk = clk;
 463        bs->fifo_size = pdata->fifo_size;
 464
 465        ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
 466                                                        pdev->name, master);
 467        if (ret) {
 468                dev_err(dev, "unable to request irq\n");
 469                goto out_err;
 470        }
 471
 472        master->bus_num = pdata->bus_num;
 473        master->num_chipselect = pdata->num_chipselect;
 474        master->setup = bcm63xx_spi_setup;
 475        master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
 476        master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
 477        master->transfer_one_message = bcm63xx_spi_transfer_one;
 478        master->mode_bits = MODEBITS;
 479        bs->speed_hz = pdata->speed_hz;
 480        bs->msg_type_shift = pdata->msg_type_shift;
 481        bs->msg_ctl_width = pdata->msg_ctl_width;
 482        bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
 483        bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
 484
 485        switch (bs->msg_ctl_width) {
 486        case 8:
 487        case 16:
 488                break;
 489        default:
 490                dev_err(dev, "unsupported MSG_CTL width: %d\n",
 491                         bs->msg_ctl_width);
 492                goto out_err;
 493        }
 494
 495        /* Initialize hardware */
 496        clk_enable(bs->clk);
 497        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 498
 499        /* register and we are done */
 500        ret = spi_register_master(master);
 501        if (ret) {
 502                dev_err(dev, "spi register failed\n");
 503                goto out_clk_disable;
 504        }
 505
 506        dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d)\n",
 507                 r->start, irq, bs->fifo_size);
 508
 509        return 0;
 510
 511out_clk_disable:
 512        clk_disable(clk);
 513out_err:
 514        platform_set_drvdata(pdev, NULL);
 515        spi_master_put(master);
 516out_clk:
 517        clk_put(clk);
 518out:
 519        return ret;
 520}
 521
 522static int bcm63xx_spi_remove(struct platform_device *pdev)
 523{
 524        struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
 525        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 526
 527        spi_unregister_master(master);
 528
 529        /* reset spi block */
 530        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 531
 532        /* HW shutdown */
 533        clk_disable(bs->clk);
 534        clk_put(bs->clk);
 535
 536        platform_set_drvdata(pdev, 0);
 537
 538        spi_master_put(master);
 539
 540        return 0;
 541}
 542
 543#ifdef CONFIG_PM
 544static int bcm63xx_spi_suspend(struct device *dev)
 545{
 546        struct spi_master *master =
 547                        platform_get_drvdata(to_platform_device(dev));
 548        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 549
 550        spi_master_suspend(master);
 551
 552        clk_disable(bs->clk);
 553
 554        return 0;
 555}
 556
 557static int bcm63xx_spi_resume(struct device *dev)
 558{
 559        struct spi_master *master =
 560                        platform_get_drvdata(to_platform_device(dev));
 561        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 562
 563        clk_enable(bs->clk);
 564
 565        spi_master_resume(master);
 566
 567        return 0;
 568}
 569
 570static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
 571        .suspend        = bcm63xx_spi_suspend,
 572        .resume         = bcm63xx_spi_resume,
 573};
 574
 575#define BCM63XX_SPI_PM_OPS      (&bcm63xx_spi_pm_ops)
 576#else
 577#define BCM63XX_SPI_PM_OPS      NULL
 578#endif
 579
 580static struct platform_driver bcm63xx_spi_driver = {
 581        .driver = {
 582                .name   = "bcm63xx-spi",
 583                .owner  = THIS_MODULE,
 584                .pm     = BCM63XX_SPI_PM_OPS,
 585        },
 586        .probe          = bcm63xx_spi_probe,
 587        .remove         = bcm63xx_spi_remove,
 588};
 589
 590module_platform_driver(bcm63xx_spi_driver);
 591
 592MODULE_ALIAS("platform:bcm63xx_spi");
 593MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
 594MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>");
 595MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
 596MODULE_LICENSE("GPL");
 597
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.