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#define DRV_VER         "0.1.2"
  40
  41struct bcm63xx_spi {
  42        struct completion       done;
  43
  44        void __iomem            *regs;
  45        int                     irq;
  46
  47        /* Platform data */
  48        u32                     speed_hz;
  49        unsigned                fifo_size;
  50        unsigned int            msg_type_shift;
  51        unsigned int            msg_ctl_width;
  52
  53        /* Data buffers */
  54        const unsigned char     *tx_ptr;
  55        unsigned char           *rx_ptr;
  56
  57        /* data iomem */
  58        u8 __iomem              *tx_io;
  59        const u8 __iomem        *rx_io;
  60
  61        int                     remaining_bytes;
  62
  63        struct clk              *clk;
  64        struct platform_device  *pdev;
  65};
  66
  67static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
  68                                unsigned int offset)
  69{
  70        return bcm_readb(bs->regs + bcm63xx_spireg(offset));
  71}
  72
  73static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
  74                                unsigned int offset)
  75{
  76        return bcm_readw(bs->regs + bcm63xx_spireg(offset));
  77}
  78
  79static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
  80                                  u8 value, unsigned int offset)
  81{
  82        bcm_writeb(value, bs->regs + bcm63xx_spireg(offset));
  83}
  84
  85static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
  86                                  u16 value, unsigned int offset)
  87{
  88        bcm_writew(value, bs->regs + bcm63xx_spireg(offset));
  89}
  90
  91static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
  92        { 20000000, SPI_CLK_20MHZ },
  93        { 12500000, SPI_CLK_12_50MHZ },
  94        {  6250000, SPI_CLK_6_250MHZ },
  95        {  3125000, SPI_CLK_3_125MHZ },
  96        {  1563000, SPI_CLK_1_563MHZ },
  97        {   781000, SPI_CLK_0_781MHZ },
  98        {   391000, SPI_CLK_0_391MHZ }
  99};
 100
 101static int bcm63xx_spi_check_transfer(struct spi_device *spi,
 102                                        struct spi_transfer *t)
 103{
 104        u8 bits_per_word;
 105
 106        bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
 107        if (bits_per_word != 8) {
 108                dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
 109                        __func__, bits_per_word);
 110                return -EINVAL;
 111        }
 112
 113        if (spi->chip_select > spi->master->num_chipselect) {
 114                dev_err(&spi->dev, "%s, unsupported slave %d\n",
 115                        __func__, spi->chip_select);
 116                return -EINVAL;
 117        }
 118
 119        return 0;
 120}
 121
 122static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
 123                                      struct spi_transfer *t)
 124{
 125        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 126        u32 hz;
 127        u8 clk_cfg, reg;
 128        int i;
 129
 130        hz = (t) ? t->speed_hz : spi->max_speed_hz;
 131
 132        /* Find the closest clock configuration */
 133        for (i = 0; i < SPI_CLK_MASK; i++) {
 134                if (hz >= bcm63xx_spi_freq_table[i][0]) {
 135                        clk_cfg = bcm63xx_spi_freq_table[i][1];
 136                        break;
 137                }
 138        }
 139
 140        /* No matching configuration found, default to lowest */
 141        if (i == SPI_CLK_MASK)
 142                clk_cfg = SPI_CLK_0_391MHZ;
 143
 144        /* clear existing clock configuration bits of the register */
 145        reg = bcm_spi_readb(bs, SPI_CLK_CFG);
 146        reg &= ~SPI_CLK_MASK;
 147        reg |= clk_cfg;
 148
 149        bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
 150        dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
 151                clk_cfg, hz);
 152}
 153
 154/* the spi->mode bits understood by this driver: */
 155#define MODEBITS (SPI_CPOL | SPI_CPHA)
 156
 157static int bcm63xx_spi_setup(struct spi_device *spi)
 158{
 159        struct bcm63xx_spi *bs;
 160        int ret;
 161
 162        bs = spi_master_get_devdata(spi->master);
 163
 164        if (!spi->bits_per_word)
 165                spi->bits_per_word = 8;
 166
 167        if (spi->mode & ~MODEBITS) {
 168                dev_err(&spi->dev, "%s, unsupported mode bits %x\n",
 169                        __func__, spi->mode & ~MODEBITS);
 170                return -EINVAL;
 171        }
 172
 173        ret = bcm63xx_spi_check_transfer(spi, NULL);
 174        if (ret < 0) {
 175                dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
 176                        spi->mode & ~MODEBITS);
 177                return ret;
 178        }
 179
 180        dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
 181                __func__, spi->mode & MODEBITS, spi->bits_per_word, 0);
 182
 183        return 0;
 184}
 185
 186/* Fill the TX FIFO with as many bytes as possible */
 187static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
 188{
 189        u8 size;
 190
 191        /* Fill the Tx FIFO with as many bytes as possible */
 192        size = bs->remaining_bytes < bs->fifo_size ? bs->remaining_bytes :
 193                bs->fifo_size;
 194        memcpy_toio(bs->tx_io, bs->tx_ptr, size);
 195        bs->remaining_bytes -= size;
 196}
 197
 198static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
 199                                        struct spi_transfer *t)
 200{
 201        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 202        u16 msg_ctl;
 203        u16 cmd;
 204
 205        /* Disable the CMD_DONE interrupt */
 206        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 207
 208        dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
 209                t->tx_buf, t->rx_buf, t->len);
 210
 211        /* Transmitter is inhibited */
 212        bs->tx_ptr = t->tx_buf;
 213        bs->rx_ptr = t->rx_buf;
 214
 215        if (t->tx_buf) {
 216                bs->remaining_bytes = t->len;
 217                bcm63xx_spi_fill_tx_fifo(bs);
 218        }
 219
 220        init_completion(&bs->done);
 221
 222        /* Fill in the Message control register */
 223        msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
 224
 225        if (t->rx_buf && t->tx_buf)
 226                msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
 227        else if (t->rx_buf)
 228                msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
 229        else if (t->tx_buf)
 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 |= (0 << 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        return t->len - bs->remaining_bytes;
 251}
 252
 253static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
 254{
 255        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 256
 257        pm_runtime_get_sync(&bs->pdev->dev);
 258
 259        return 0;
 260}
 261
 262static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
 263{
 264        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 265
 266        pm_runtime_put(&bs->pdev->dev);
 267
 268        return 0;
 269}
 270
 271static int bcm63xx_spi_transfer_one(struct spi_master *master,
 272                                        struct spi_message *m)
 273{
 274        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 275        struct spi_transfer *t;
 276        struct spi_device *spi = m->spi;
 277        int status = 0;
 278        unsigned int timeout = 0;
 279
 280        list_for_each_entry(t, &m->transfers, transfer_list) {
 281                unsigned int len = t->len;
 282                u8 rx_tail;
 283
 284                status = bcm63xx_spi_check_transfer(spi, t);
 285                if (status < 0)
 286                        goto exit;
 287
 288                /* configure adapter for a new transfer */
 289                bcm63xx_spi_setup_transfer(spi, t);
 290
 291                while (len) {
 292                        /* send the data */
 293                        len -= bcm63xx_txrx_bufs(spi, t);
 294
 295                        timeout = wait_for_completion_timeout(&bs->done, HZ);
 296                        if (!timeout) {
 297                                status = -ETIMEDOUT;
 298                                goto exit;
 299                        }
 300
 301                        /* read out all data */
 302                        rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
 303
 304                        /* Read out all the data */
 305                        if (rx_tail)
 306                                memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
 307                }
 308
 309                m->actual_length += t->len;
 310        }
 311exit:
 312        m->status = status;
 313        spi_finalize_current_message(master);
 314
 315        return 0;
 316}
 317
 318/* This driver supports single master mode only. Hence
 319 * CMD_DONE is the only interrupt we care about
 320 */
 321static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
 322{
 323        struct spi_master *master = (struct spi_master *)dev_id;
 324        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 325        u8 intr;
 326
 327        /* Read interupts and clear them immediately */
 328        intr = bcm_spi_readb(bs, SPI_INT_STATUS);
 329        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 330        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 331
 332        /* A transfer completed */
 333        if (intr & SPI_INTR_CMD_DONE)
 334                complete(&bs->done);
 335
 336        return IRQ_HANDLED;
 337}
 338
 339
 340static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
 341{
 342        struct resource *r;
 343        struct device *dev = &pdev->dev;
 344        struct bcm63xx_spi_pdata *pdata = pdev->dev.platform_data;
 345        int irq;
 346        struct spi_master *master;
 347        struct clk *clk;
 348        struct bcm63xx_spi *bs;
 349        int ret;
 350
 351        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 352        if (!r) {
 353                dev_err(dev, "no iomem\n");
 354                ret = -ENXIO;
 355                goto out;
 356        }
 357
 358        irq = platform_get_irq(pdev, 0);
 359        if (irq < 0) {
 360                dev_err(dev, "no irq\n");
 361                ret = -ENXIO;
 362                goto out;
 363        }
 364
 365        clk = clk_get(dev, "spi");
 366        if (IS_ERR(clk)) {
 367                dev_err(dev, "no clock for device\n");
 368                ret = PTR_ERR(clk);
 369                goto out;
 370        }
 371
 372        master = spi_alloc_master(dev, sizeof(*bs));
 373        if (!master) {
 374                dev_err(dev, "out of memory\n");
 375                ret = -ENOMEM;
 376                goto out_clk;
 377        }
 378
 379        bs = spi_master_get_devdata(master);
 380
 381        platform_set_drvdata(pdev, master);
 382        bs->pdev = pdev;
 383
 384        if (!devm_request_mem_region(&pdev->dev, r->start,
 385                                        resource_size(r), PFX)) {
 386                dev_err(dev, "iomem request failed\n");
 387                ret = -ENXIO;
 388                goto out_err;
 389        }
 390
 391        bs->regs = devm_ioremap_nocache(&pdev->dev, r->start,
 392                                                        resource_size(r));
 393        if (!bs->regs) {
 394                dev_err(dev, "unable to ioremap regs\n");
 395                ret = -ENOMEM;
 396                goto out_err;
 397        }
 398
 399        bs->irq = irq;
 400        bs->clk = clk;
 401        bs->fifo_size = pdata->fifo_size;
 402
 403        ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
 404                                                        pdev->name, master);
 405        if (ret) {
 406                dev_err(dev, "unable to request irq\n");
 407                goto out_err;
 408        }
 409
 410        master->bus_num = pdata->bus_num;
 411        master->num_chipselect = pdata->num_chipselect;
 412        master->setup = bcm63xx_spi_setup;
 413        master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
 414        master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
 415        master->transfer_one_message = bcm63xx_spi_transfer_one;
 416        master->mode_bits = MODEBITS;
 417        bs->speed_hz = pdata->speed_hz;
 418        bs->msg_type_shift = pdata->msg_type_shift;
 419        bs->msg_ctl_width = pdata->msg_ctl_width;
 420        bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
 421        bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
 422
 423        switch (bs->msg_ctl_width) {
 424        case 8:
 425        case 16:
 426                break;
 427        default:
 428                dev_err(dev, "unsupported MSG_CTL width: %d\n",
 429                         bs->msg_ctl_width);
 430                goto out_clk_disable;
 431        }
 432
 433        /* Initialize hardware */
 434        clk_enable(bs->clk);
 435        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 436
 437        /* register and we are done */
 438        ret = spi_register_master(master);
 439        if (ret) {
 440                dev_err(dev, "spi register failed\n");
 441                goto out_clk_disable;
 442        }
 443
 444        dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d) v%s\n",
 445                 r->start, irq, bs->fifo_size, DRV_VER);
 446
 447        return 0;
 448
 449out_clk_disable:
 450        clk_disable(clk);
 451out_err:
 452        platform_set_drvdata(pdev, NULL);
 453        spi_master_put(master);
 454out_clk:
 455        clk_put(clk);
 456out:
 457        return ret;
 458}
 459
 460static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)
 461{
 462        struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
 463        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 464
 465        spi_unregister_master(master);
 466
 467        /* reset spi block */
 468        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 469
 470        /* HW shutdown */
 471        clk_disable(bs->clk);
 472        clk_put(bs->clk);
 473
 474        platform_set_drvdata(pdev, 0);
 475
 476        spi_master_put(master);
 477
 478        return 0;
 479}
 480
 481#ifdef CONFIG_PM
 482static int bcm63xx_spi_suspend(struct device *dev)
 483{
 484        struct spi_master *master =
 485                        platform_get_drvdata(to_platform_device(dev));
 486        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 487
 488        clk_disable(bs->clk);
 489
 490        return 0;
 491}
 492
 493static int bcm63xx_spi_resume(struct device *dev)
 494{
 495        struct spi_master *master =
 496                        platform_get_drvdata(to_platform_device(dev));
 497        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 498
 499        clk_enable(bs->clk);
 500
 501        return 0;
 502}
 503
 504static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
 505        .suspend        = bcm63xx_spi_suspend,
 506        .resume         = bcm63xx_spi_resume,
 507};
 508
 509#define BCM63XX_SPI_PM_OPS      (&bcm63xx_spi_pm_ops)
 510#else
 511#define BCM63XX_SPI_PM_OPS      NULL
 512#endif
 513
 514static struct platform_driver bcm63xx_spi_driver = {
 515        .driver = {
 516                .name   = "bcm63xx-spi",
 517                .owner  = THIS_MODULE,
 518                .pm     = BCM63XX_SPI_PM_OPS,
 519        },
 520        .probe          = bcm63xx_spi_probe,
 521        .remove         = __devexit_p(bcm63xx_spi_remove),
 522};
 523
 524module_platform_driver(bcm63xx_spi_driver);
 525
 526MODULE_ALIAS("platform:bcm63xx_spi");
 527MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
 528MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>");
 529MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
 530MODULE_LICENSE("GPL");
 531
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.