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/clk.h>
  24#include <linux/io.h>
  25#include <linux/module.h>
  26#include <linux/platform_device.h>
  27#include <linux/delay.h>
  28#include <linux/interrupt.h>
  29#include <linux/spi/spi.h>
  30#include <linux/completion.h>
  31#include <linux/err.h>
  32#include <linux/pm_runtime.h>
  33
  34#include <bcm63xx_dev_spi.h>
  35
  36#define BCM63XX_SPI_MAX_PREPEND         15
  37
  38struct bcm63xx_spi {
  39        struct completion       done;
  40
  41        void __iomem            *regs;
  42        int                     irq;
  43
  44        /* Platform data */
  45        unsigned                fifo_size;
  46        unsigned int            msg_type_shift;
  47        unsigned int            msg_ctl_width;
  48
  49        /* data iomem */
  50        u8 __iomem              *tx_io;
  51        const u8 __iomem        *rx_io;
  52
  53        struct clk              *clk;
  54        struct platform_device  *pdev;
  55};
  56
  57static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
  58                                unsigned int offset)
  59{
  60        return bcm_readb(bs->regs + bcm63xx_spireg(offset));
  61}
  62
  63static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
  64                                unsigned int offset)
  65{
  66        return bcm_readw(bs->regs + bcm63xx_spireg(offset));
  67}
  68
  69static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
  70                                  u8 value, unsigned int offset)
  71{
  72        bcm_writeb(value, bs->regs + bcm63xx_spireg(offset));
  73}
  74
  75static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
  76                                  u16 value, unsigned int offset)
  77{
  78        bcm_writew(value, bs->regs + bcm63xx_spireg(offset));
  79}
  80
  81static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
  82        { 20000000, SPI_CLK_20MHZ },
  83        { 12500000, SPI_CLK_12_50MHZ },
  84        {  6250000, SPI_CLK_6_250MHZ },
  85        {  3125000, SPI_CLK_3_125MHZ },
  86        {  1563000, SPI_CLK_1_563MHZ },
  87        {   781000, SPI_CLK_0_781MHZ },
  88        {   391000, SPI_CLK_0_391MHZ }
  89};
  90
  91static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
  92                                      struct spi_transfer *t)
  93{
  94        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
  95        u8 clk_cfg, reg;
  96        int i;
  97
  98        /* Find the closest clock configuration */
  99        for (i = 0; i < SPI_CLK_MASK; i++) {
 100                if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) {
 101                        clk_cfg = bcm63xx_spi_freq_table[i][1];
 102                        break;
 103                }
 104        }
 105
 106        /* No matching configuration found, default to lowest */
 107        if (i == SPI_CLK_MASK)
 108                clk_cfg = SPI_CLK_0_391MHZ;
 109
 110        /* clear existing clock configuration bits of the register */
 111        reg = bcm_spi_readb(bs, SPI_CLK_CFG);
 112        reg &= ~SPI_CLK_MASK;
 113        reg |= clk_cfg;
 114
 115        bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
 116        dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
 117                clk_cfg, t->speed_hz);
 118}
 119
 120/* the spi->mode bits understood by this driver: */
 121#define MODEBITS (SPI_CPOL | SPI_CPHA)
 122
 123static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
 124                                unsigned int num_transfers)
 125{
 126        struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
 127        u16 msg_ctl;
 128        u16 cmd;
 129        u8 rx_tail;
 130        unsigned int i, timeout = 0, prepend_len = 0, len = 0;
 131        struct spi_transfer *t = first;
 132        bool do_rx = false;
 133        bool do_tx = false;
 134
 135        /* Disable the CMD_DONE interrupt */
 136        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 137
 138        dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
 139                t->tx_buf, t->rx_buf, t->len);
 140
 141        if (num_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
 142                prepend_len = t->len;
 143
 144        /* prepare the buffer */
 145        for (i = 0; i < num_transfers; i++) {
 146                if (t->tx_buf) {
 147                        do_tx = true;
 148                        memcpy_toio(bs->tx_io + len, t->tx_buf, t->len);
 149
 150                        /* don't prepend more than one tx */
 151                        if (t != first)
 152                                prepend_len = 0;
 153                }
 154
 155                if (t->rx_buf) {
 156                        do_rx = true;
 157                        /* prepend is half-duplex write only */
 158                        if (t == first)
 159                                prepend_len = 0;
 160                }
 161
 162                len += t->len;
 163
 164                t = list_entry(t->transfer_list.next, struct spi_transfer,
 165                               transfer_list);
 166        }
 167
 168        reinit_completion(&bs->done);
 169
 170        /* Fill in the Message control register */
 171        msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
 172
 173        if (do_rx && do_tx && prepend_len == 0)
 174                msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
 175        else if (do_rx)
 176                msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
 177        else if (do_tx)
 178                msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
 179
 180        switch (bs->msg_ctl_width) {
 181        case 8:
 182                bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
 183                break;
 184        case 16:
 185                bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
 186                break;
 187        }
 188
 189        /* Issue the transfer */
 190        cmd = SPI_CMD_START_IMMEDIATE;
 191        cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
 192        cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
 193        bcm_spi_writew(bs, cmd, SPI_CMD);
 194
 195        /* Enable the CMD_DONE interrupt */
 196        bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
 197
 198        timeout = wait_for_completion_timeout(&bs->done, HZ);
 199        if (!timeout)
 200                return -ETIMEDOUT;
 201
 202        if (!do_rx)
 203                return 0;
 204
 205        len = 0;
 206        t = first;
 207        /* Read out all the data */
 208        for (i = 0; i < num_transfers; i++) {
 209                if (t->rx_buf)
 210                        memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);
 211
 212                if (t != first || prepend_len == 0)
 213                        len += t->len;
 214
 215                t = list_entry(t->transfer_list.next, struct spi_transfer,
 216                               transfer_list);
 217        }
 218
 219        return 0;
 220}
 221
 222static int bcm63xx_spi_transfer_one(struct spi_master *master,
 223                                        struct spi_message *m)
 224{
 225        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 226        struct spi_transfer *t, *first = NULL;
 227        struct spi_device *spi = m->spi;
 228        int status = 0;
 229        unsigned int n_transfers = 0, total_len = 0;
 230        bool can_use_prepend = false;
 231
 232        /*
 233         * This SPI controller does not support keeping CS active after a
 234         * transfer.
 235         * Work around this by merging as many transfers we can into one big
 236         * full-duplex transfers.
 237         */
 238        list_for_each_entry(t, &m->transfers, transfer_list) {
 239                if (!first)
 240                        first = t;
 241
 242                n_transfers++;
 243                total_len += t->len;
 244
 245                if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
 246                    first->len <= BCM63XX_SPI_MAX_PREPEND)
 247                        can_use_prepend = true;
 248                else if (can_use_prepend && t->tx_buf)
 249                        can_use_prepend = false;
 250
 251                /* we can only transfer one fifo worth of data */
 252                if ((can_use_prepend &&
 253                     total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
 254                    (!can_use_prepend && total_len > bs->fifo_size)) {
 255                        dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
 256                                total_len, bs->fifo_size);
 257                        status = -EINVAL;
 258                        goto exit;
 259                }
 260
 261                /* all combined transfers have to have the same speed */
 262                if (t->speed_hz != first->speed_hz) {
 263                        dev_err(&spi->dev, "unable to change speed between transfers\n");
 264                        status = -EINVAL;
 265                        goto exit;
 266                }
 267
 268                /* CS will be deasserted directly after transfer */
 269                if (t->delay_usecs) {
 270                        dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
 271                        status = -EINVAL;
 272                        goto exit;
 273                }
 274
 275                if (t->cs_change ||
 276                    list_is_last(&t->transfer_list, &m->transfers)) {
 277                        /* configure adapter for a new transfer */
 278                        bcm63xx_spi_setup_transfer(spi, first);
 279
 280                        /* send the data */
 281                        status = bcm63xx_txrx_bufs(spi, first, n_transfers);
 282                        if (status)
 283                                goto exit;
 284
 285                        m->actual_length += total_len;
 286
 287                        first = NULL;
 288                        n_transfers = 0;
 289                        total_len = 0;
 290                        can_use_prepend = false;
 291                }
 292        }
 293exit:
 294        m->status = status;
 295        spi_finalize_current_message(master);
 296
 297        return 0;
 298}
 299
 300/* This driver supports single master mode only. Hence
 301 * CMD_DONE is the only interrupt we care about
 302 */
 303static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
 304{
 305        struct spi_master *master = (struct spi_master *)dev_id;
 306        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 307        u8 intr;
 308
 309        /* Read interupts and clear them immediately */
 310        intr = bcm_spi_readb(bs, SPI_INT_STATUS);
 311        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 312        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 313
 314        /* A transfer completed */
 315        if (intr & SPI_INTR_CMD_DONE)
 316                complete(&bs->done);
 317
 318        return IRQ_HANDLED;
 319}
 320
 321
 322static int bcm63xx_spi_probe(struct platform_device *pdev)
 323{
 324        struct resource *r;
 325        struct device *dev = &pdev->dev;
 326        struct bcm63xx_spi_pdata *pdata = dev_get_platdata(&pdev->dev);
 327        int irq;
 328        struct spi_master *master;
 329        struct clk *clk;
 330        struct bcm63xx_spi *bs;
 331        int ret;
 332
 333        irq = platform_get_irq(pdev, 0);
 334        if (irq < 0) {
 335                dev_err(dev, "no irq\n");
 336                return -ENXIO;
 337        }
 338
 339        clk = devm_clk_get(dev, "spi");
 340        if (IS_ERR(clk)) {
 341                dev_err(dev, "no clock for device\n");
 342                return PTR_ERR(clk);
 343        }
 344
 345        master = spi_alloc_master(dev, sizeof(*bs));
 346        if (!master) {
 347                dev_err(dev, "out of memory\n");
 348                return -ENOMEM;
 349        }
 350
 351        bs = spi_master_get_devdata(master);
 352        init_completion(&bs->done);
 353
 354        platform_set_drvdata(pdev, master);
 355        bs->pdev = pdev;
 356
 357        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 358        bs->regs = devm_ioremap_resource(&pdev->dev, r);
 359        if (IS_ERR(bs->regs)) {
 360                ret = PTR_ERR(bs->regs);
 361                goto out_err;
 362        }
 363
 364        bs->irq = irq;
 365        bs->clk = clk;
 366        bs->fifo_size = pdata->fifo_size;
 367
 368        ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
 369                                                        pdev->name, master);
 370        if (ret) {
 371                dev_err(dev, "unable to request irq\n");
 372                goto out_err;
 373        }
 374
 375        master->bus_num = pdata->bus_num;
 376        master->num_chipselect = pdata->num_chipselect;
 377        master->transfer_one_message = bcm63xx_spi_transfer_one;
 378        master->mode_bits = MODEBITS;
 379        master->bits_per_word_mask = SPI_BPW_MASK(8);
 380        master->auto_runtime_pm = true;
 381        bs->msg_type_shift = pdata->msg_type_shift;
 382        bs->msg_ctl_width = pdata->msg_ctl_width;
 383        bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
 384        bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
 385
 386        switch (bs->msg_ctl_width) {
 387        case 8:
 388        case 16:
 389                break;
 390        default:
 391                dev_err(dev, "unsupported MSG_CTL width: %d\n",
 392                         bs->msg_ctl_width);
 393                goto out_err;
 394        }
 395
 396        /* Initialize hardware */
 397        ret = clk_prepare_enable(bs->clk);
 398        if (ret)
 399                goto out_err;
 400
 401        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 402
 403        /* register and we are done */
 404        ret = devm_spi_register_master(dev, master);
 405        if (ret) {
 406                dev_err(dev, "spi register failed\n");
 407                goto out_clk_disable;
 408        }
 409
 410        dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d)\n",
 411                 r->start, irq, bs->fifo_size);
 412
 413        return 0;
 414
 415out_clk_disable:
 416        clk_disable_unprepare(clk);
 417out_err:
 418        spi_master_put(master);
 419        return ret;
 420}
 421
 422static int bcm63xx_spi_remove(struct platform_device *pdev)
 423{
 424        struct spi_master *master = platform_get_drvdata(pdev);
 425        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 426
 427        /* reset spi block */
 428        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 429
 430        /* HW shutdown */
 431        clk_disable_unprepare(bs->clk);
 432
 433        return 0;
 434}
 435
 436#ifdef CONFIG_PM_SLEEP
 437static int bcm63xx_spi_suspend(struct device *dev)
 438{
 439        struct spi_master *master = dev_get_drvdata(dev);
 440        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 441
 442        spi_master_suspend(master);
 443
 444        clk_disable_unprepare(bs->clk);
 445
 446        return 0;
 447}
 448
 449static int bcm63xx_spi_resume(struct device *dev)
 450{
 451        struct spi_master *master = dev_get_drvdata(dev);
 452        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 453        int ret;
 454
 455        ret = clk_prepare_enable(bs->clk);
 456        if (ret)
 457                return ret;
 458
 459        spi_master_resume(master);
 460
 461        return 0;
 462}
 463#endif
 464
 465static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
 466        SET_SYSTEM_SLEEP_PM_OPS(bcm63xx_spi_suspend, bcm63xx_spi_resume)
 467};
 468
 469static struct platform_driver bcm63xx_spi_driver = {
 470        .driver = {
 471                .name   = "bcm63xx-spi",
 472                .owner  = THIS_MODULE,
 473                .pm     = &bcm63xx_spi_pm_ops,
 474        },
 475        .probe          = bcm63xx_spi_probe,
 476        .remove         = bcm63xx_spi_remove,
 477};
 478
 479module_platform_driver(bcm63xx_spi_driver);
 480
 481MODULE_ALIAS("platform:bcm63xx_spi");
 482MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
 483MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>");
 484MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
 485MODULE_LICENSE("GPL");
 486