linux/drivers/spi/spi-orion.c
<<
>>
Prefs
   1/*
   2 * Marvell Orion SPI controller driver
   3 *
   4 * Author: Shadi Ammouri <shadi@marvell.com>
   5 * Copyright (C) 2007-2008 Marvell Ltd.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/interrupt.h>
  14#include <linux/delay.h>
  15#include <linux/platform_device.h>
  16#include <linux/err.h>
  17#include <linux/io.h>
  18#include <linux/spi/spi.h>
  19#include <linux/module.h>
  20#include <linux/of.h>
  21#include <linux/clk.h>
  22#include <asm/unaligned.h>
  23
  24#define DRIVER_NAME                     "orion_spi"
  25
  26#define ORION_NUM_CHIPSELECTS           1 /* only one slave is supported*/
  27#define ORION_SPI_WAIT_RDY_MAX_LOOP     2000 /* in usec */
  28
  29#define ORION_SPI_IF_CTRL_REG           0x00
  30#define ORION_SPI_IF_CONFIG_REG         0x04
  31#define ORION_SPI_DATA_OUT_REG          0x08
  32#define ORION_SPI_DATA_IN_REG           0x0c
  33#define ORION_SPI_INT_CAUSE_REG         0x10
  34
  35#define ORION_SPI_IF_8_16_BIT_MODE      (1 << 5)
  36#define ORION_SPI_CLK_PRESCALE_MASK     0x1F
  37
  38struct orion_spi {
  39        struct work_struct      work;
  40
  41        /* Lock access to transfer list.        */
  42        spinlock_t              lock;
  43
  44        struct list_head        msg_queue;
  45        struct spi_master       *master;
  46        void __iomem            *base;
  47        unsigned int            max_speed;
  48        unsigned int            min_speed;
  49        struct clk              *clk;
  50};
  51
  52static struct workqueue_struct *orion_spi_wq;
  53
  54static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
  55{
  56        return orion_spi->base + reg;
  57}
  58
  59static inline void
  60orion_spi_setbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
  61{
  62        void __iomem *reg_addr = spi_reg(orion_spi, reg);
  63        u32 val;
  64
  65        val = readl(reg_addr);
  66        val |= mask;
  67        writel(val, reg_addr);
  68}
  69
  70static inline void
  71orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
  72{
  73        void __iomem *reg_addr = spi_reg(orion_spi, reg);
  74        u32 val;
  75
  76        val = readl(reg_addr);
  77        val &= ~mask;
  78        writel(val, reg_addr);
  79}
  80
  81static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size)
  82{
  83        if (size == 16) {
  84                orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
  85                                  ORION_SPI_IF_8_16_BIT_MODE);
  86        } else if (size == 8) {
  87                orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
  88                                  ORION_SPI_IF_8_16_BIT_MODE);
  89        } else {
  90                pr_debug("Bad bits per word value %d (only 8 or 16 are "
  91                         "allowed).\n", size);
  92                return -EINVAL;
  93        }
  94
  95        return 0;
  96}
  97
  98static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
  99{
 100        u32 tclk_hz;
 101        u32 rate;
 102        u32 prescale;
 103        u32 reg;
 104        struct orion_spi *orion_spi;
 105
 106        orion_spi = spi_master_get_devdata(spi->master);
 107
 108        tclk_hz = clk_get_rate(orion_spi->clk);
 109
 110        /*
 111         * the supported rates are: 4,6,8...30
 112         * round up as we look for equal or less speed
 113         */
 114        rate = DIV_ROUND_UP(tclk_hz, speed);
 115        rate = roundup(rate, 2);
 116
 117        /* check if requested speed is too small */
 118        if (rate > 30)
 119                return -EINVAL;
 120
 121        if (rate < 4)
 122                rate = 4;
 123
 124        /* Convert the rate to SPI clock divisor value. */
 125        prescale = 0x10 + rate/2;
 126
 127        reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 128        reg = ((reg & ~ORION_SPI_CLK_PRESCALE_MASK) | prescale);
 129        writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 130
 131        return 0;
 132}
 133
 134/*
 135 * called only when no transfer is active on the bus
 136 */
 137static int
 138orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 139{
 140        struct orion_spi *orion_spi;
 141        unsigned int speed = spi->max_speed_hz;
 142        unsigned int bits_per_word = spi->bits_per_word;
 143        int     rc;
 144
 145        orion_spi = spi_master_get_devdata(spi->master);
 146
 147        if ((t != NULL) && t->speed_hz)
 148                speed = t->speed_hz;
 149
 150        if ((t != NULL) && t->bits_per_word)
 151                bits_per_word = t->bits_per_word;
 152
 153        rc = orion_spi_baudrate_set(spi, speed);
 154        if (rc)
 155                return rc;
 156
 157        return orion_spi_set_transfer_size(orion_spi, bits_per_word);
 158}
 159
 160static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
 161{
 162        if (enable)
 163                orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
 164        else
 165                orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
 166}
 167
 168static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi)
 169{
 170        int i;
 171
 172        for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) {
 173                if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG)))
 174                        return 1;
 175                else
 176                        udelay(1);
 177        }
 178
 179        return -1;
 180}
 181
 182static inline int
 183orion_spi_write_read_8bit(struct spi_device *spi,
 184                          const u8 **tx_buf, u8 **rx_buf)
 185{
 186        void __iomem *tx_reg, *rx_reg, *int_reg;
 187        struct orion_spi *orion_spi;
 188
 189        orion_spi = spi_master_get_devdata(spi->master);
 190        tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
 191        rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
 192        int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
 193
 194        /* clear the interrupt cause register */
 195        writel(0x0, int_reg);
 196
 197        if (tx_buf && *tx_buf)
 198                writel(*(*tx_buf)++, tx_reg);
 199        else
 200                writel(0, tx_reg);
 201
 202        if (orion_spi_wait_till_ready(orion_spi) < 0) {
 203                dev_err(&spi->dev, "TXS timed out\n");
 204                return -1;
 205        }
 206
 207        if (rx_buf && *rx_buf)
 208                *(*rx_buf)++ = readl(rx_reg);
 209
 210        return 1;
 211}
 212
 213static inline int
 214orion_spi_write_read_16bit(struct spi_device *spi,
 215                           const u16 **tx_buf, u16 **rx_buf)
 216{
 217        void __iomem *tx_reg, *rx_reg, *int_reg;
 218        struct orion_spi *orion_spi;
 219
 220        orion_spi = spi_master_get_devdata(spi->master);
 221        tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
 222        rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
 223        int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
 224
 225        /* clear the interrupt cause register */
 226        writel(0x0, int_reg);
 227
 228        if (tx_buf && *tx_buf)
 229                writel(__cpu_to_le16(get_unaligned((*tx_buf)++)), tx_reg);
 230        else
 231                writel(0, tx_reg);
 232
 233        if (orion_spi_wait_till_ready(orion_spi) < 0) {
 234                dev_err(&spi->dev, "TXS timed out\n");
 235                return -1;
 236        }
 237
 238        if (rx_buf && *rx_buf)
 239                put_unaligned(__le16_to_cpu(readl(rx_reg)), (*rx_buf)++);
 240
 241        return 1;
 242}
 243
 244static unsigned int
 245orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
 246{
 247        struct orion_spi *orion_spi;
 248        unsigned int count;
 249        int word_len;
 250
 251        orion_spi = spi_master_get_devdata(spi->master);
 252        word_len = spi->bits_per_word;
 253        count = xfer->len;
 254
 255        if (word_len == 8) {
 256                const u8 *tx = xfer->tx_buf;
 257                u8 *rx = xfer->rx_buf;
 258
 259                do {
 260                        if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0)
 261                                goto out;
 262                        count--;
 263                } while (count);
 264        } else if (word_len == 16) {
 265                const u16 *tx = xfer->tx_buf;
 266                u16 *rx = xfer->rx_buf;
 267
 268                do {
 269                        if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0)
 270                                goto out;
 271                        count -= 2;
 272                } while (count);
 273        }
 274
 275out:
 276        return xfer->len - count;
 277}
 278
 279
 280static void orion_spi_work(struct work_struct *work)
 281{
 282        struct orion_spi *orion_spi =
 283                container_of(work, struct orion_spi, work);
 284
 285        spin_lock_irq(&orion_spi->lock);
 286        while (!list_empty(&orion_spi->msg_queue)) {
 287                struct spi_message *m;
 288                struct spi_device *spi;
 289                struct spi_transfer *t = NULL;
 290                int par_override = 0;
 291                int status = 0;
 292                int cs_active = 0;
 293
 294                m = container_of(orion_spi->msg_queue.next, struct spi_message,
 295                                 queue);
 296
 297                list_del_init(&m->queue);
 298                spin_unlock_irq(&orion_spi->lock);
 299
 300                spi = m->spi;
 301
 302                /* Load defaults */
 303                status = orion_spi_setup_transfer(spi, NULL);
 304
 305                if (status < 0)
 306                        goto msg_done;
 307
 308                list_for_each_entry(t, &m->transfers, transfer_list) {
 309                        if (par_override || t->speed_hz || t->bits_per_word) {
 310                                par_override = 1;
 311                                status = orion_spi_setup_transfer(spi, t);
 312                                if (status < 0)
 313                                        break;
 314                                if (!t->speed_hz && !t->bits_per_word)
 315                                        par_override = 0;
 316                        }
 317
 318                        if (!cs_active) {
 319                                orion_spi_set_cs(orion_spi, 1);
 320                                cs_active = 1;
 321                        }
 322
 323                        if (t->len)
 324                                m->actual_length +=
 325                                        orion_spi_write_read(spi, t);
 326
 327                        if (t->delay_usecs)
 328                                udelay(t->delay_usecs);
 329
 330                        if (t->cs_change) {
 331                                orion_spi_set_cs(orion_spi, 0);
 332                                cs_active = 0;
 333                        }
 334                }
 335
 336msg_done:
 337                if (cs_active)
 338                        orion_spi_set_cs(orion_spi, 0);
 339
 340                m->status = status;
 341                m->complete(m->context);
 342
 343                spin_lock_irq(&orion_spi->lock);
 344        }
 345
 346        spin_unlock_irq(&orion_spi->lock);
 347}
 348
 349static int __init orion_spi_reset(struct orion_spi *orion_spi)
 350{
 351        /* Verify that the CS is deasserted */
 352        orion_spi_set_cs(orion_spi, 0);
 353
 354        return 0;
 355}
 356
 357static int orion_spi_setup(struct spi_device *spi)
 358{
 359        struct orion_spi *orion_spi;
 360
 361        orion_spi = spi_master_get_devdata(spi->master);
 362
 363        if ((spi->max_speed_hz == 0)
 364                        || (spi->max_speed_hz > orion_spi->max_speed))
 365                spi->max_speed_hz = orion_spi->max_speed;
 366
 367        if (spi->max_speed_hz < orion_spi->min_speed) {
 368                dev_err(&spi->dev, "setup: requested speed too low %d Hz\n",
 369                        spi->max_speed_hz);
 370                return -EINVAL;
 371        }
 372
 373        /*
 374         * baudrate & width will be set orion_spi_setup_transfer
 375         */
 376        return 0;
 377}
 378
 379static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m)
 380{
 381        struct orion_spi *orion_spi;
 382        struct spi_transfer *t = NULL;
 383        unsigned long flags;
 384
 385        m->actual_length = 0;
 386        m->status = 0;
 387
 388        /* reject invalid messages and transfers */
 389        if (list_empty(&m->transfers) || !m->complete)
 390                return -EINVAL;
 391
 392        orion_spi = spi_master_get_devdata(spi->master);
 393
 394        list_for_each_entry(t, &m->transfers, transfer_list) {
 395                unsigned int bits_per_word = spi->bits_per_word;
 396
 397                if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
 398                        dev_err(&spi->dev,
 399                                "message rejected : "
 400                                "invalid transfer data buffers\n");
 401                        goto msg_rejected;
 402                }
 403
 404                if (t->bits_per_word)
 405                        bits_per_word = t->bits_per_word;
 406
 407                if ((bits_per_word != 8) && (bits_per_word != 16)) {
 408                        dev_err(&spi->dev,
 409                                "message rejected : "
 410                                "invalid transfer bits_per_word (%d bits)\n",
 411                                bits_per_word);
 412                        goto msg_rejected;
 413                }
 414                /*make sure buffer length is even when working in 16 bit mode*/
 415                if ((t->bits_per_word == 16) && (t->len & 1)) {
 416                        dev_err(&spi->dev,
 417                                "message rejected : "
 418                                "odd data length (%d) while in 16 bit mode\n",
 419                                t->len);
 420                        goto msg_rejected;
 421                }
 422
 423                if (t->speed_hz && t->speed_hz < orion_spi->min_speed) {
 424                        dev_err(&spi->dev,
 425                                "message rejected : "
 426                                "device min speed (%d Hz) exceeds "
 427                                "required transfer speed (%d Hz)\n",
 428                                orion_spi->min_speed, t->speed_hz);
 429                        goto msg_rejected;
 430                }
 431        }
 432
 433
 434        spin_lock_irqsave(&orion_spi->lock, flags);
 435        list_add_tail(&m->queue, &orion_spi->msg_queue);
 436        queue_work(orion_spi_wq, &orion_spi->work);
 437        spin_unlock_irqrestore(&orion_spi->lock, flags);
 438
 439        return 0;
 440msg_rejected:
 441        /* Message rejected and not queued */
 442        m->status = -EINVAL;
 443        if (m->complete)
 444                m->complete(m->context);
 445        return -EINVAL;
 446}
 447
 448static int __init orion_spi_probe(struct platform_device *pdev)
 449{
 450        struct spi_master *master;
 451        struct orion_spi *spi;
 452        struct resource *r;
 453        unsigned long tclk_hz;
 454        int status = 0;
 455        const u32 *iprop;
 456        int size;
 457
 458        master = spi_alloc_master(&pdev->dev, sizeof *spi);
 459        if (master == NULL) {
 460                dev_dbg(&pdev->dev, "master allocation failed\n");
 461                return -ENOMEM;
 462        }
 463
 464        if (pdev->id != -1)
 465                master->bus_num = pdev->id;
 466        if (pdev->dev.of_node) {
 467                iprop = of_get_property(pdev->dev.of_node, "cell-index",
 468                                        &size);
 469                if (iprop && size == sizeof(*iprop))
 470                        master->bus_num = *iprop;
 471        }
 472
 473        /* we support only mode 0, and no options */
 474        master->mode_bits = 0;
 475
 476        master->setup = orion_spi_setup;
 477        master->transfer = orion_spi_transfer;
 478        master->num_chipselect = ORION_NUM_CHIPSELECTS;
 479
 480        dev_set_drvdata(&pdev->dev, master);
 481
 482        spi = spi_master_get_devdata(master);
 483        spi->master = master;
 484
 485        spi->clk = clk_get(&pdev->dev, NULL);
 486        if (IS_ERR(spi->clk)) {
 487                status = PTR_ERR(spi->clk);
 488                goto out;
 489        }
 490
 491        clk_prepare(spi->clk);
 492        clk_enable(spi->clk);
 493        tclk_hz = clk_get_rate(spi->clk);
 494        spi->max_speed = DIV_ROUND_UP(tclk_hz, 4);
 495        spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
 496
 497        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 498        if (r == NULL) {
 499                status = -ENODEV;
 500                goto out_rel_clk;
 501        }
 502
 503        if (!request_mem_region(r->start, resource_size(r),
 504                                dev_name(&pdev->dev))) {
 505                status = -EBUSY;
 506                goto out_rel_clk;
 507        }
 508        spi->base = ioremap(r->start, SZ_1K);
 509
 510        INIT_WORK(&spi->work, orion_spi_work);
 511
 512        spin_lock_init(&spi->lock);
 513        INIT_LIST_HEAD(&spi->msg_queue);
 514
 515        if (orion_spi_reset(spi) < 0)
 516                goto out_rel_mem;
 517
 518        master->dev.of_node = pdev->dev.of_node;
 519        status = spi_register_master(master);
 520        if (status < 0)
 521                goto out_rel_mem;
 522
 523        return status;
 524
 525out_rel_mem:
 526        release_mem_region(r->start, resource_size(r));
 527out_rel_clk:
 528        clk_disable_unprepare(spi->clk);
 529        clk_put(spi->clk);
 530out:
 531        spi_master_put(master);
 532        return status;
 533}
 534
 535
 536static int __exit orion_spi_remove(struct platform_device *pdev)
 537{
 538        struct spi_master *master;
 539        struct orion_spi *spi;
 540        struct resource *r;
 541
 542        master = dev_get_drvdata(&pdev->dev);
 543        spi = spi_master_get_devdata(master);
 544
 545        cancel_work_sync(&spi->work);
 546
 547        clk_disable_unprepare(spi->clk);
 548        clk_put(spi->clk);
 549
 550        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 551        release_mem_region(r->start, resource_size(r));
 552
 553        spi_unregister_master(master);
 554
 555        return 0;
 556}
 557
 558MODULE_ALIAS("platform:" DRIVER_NAME);
 559
 560static const struct of_device_id orion_spi_of_match_table[] __devinitdata = {
 561        { .compatible = "marvell,orion-spi", },
 562        {}
 563};
 564MODULE_DEVICE_TABLE(of, orion_spi_of_match_table);
 565
 566static struct platform_driver orion_spi_driver = {
 567        .driver = {
 568                .name   = DRIVER_NAME,
 569                .owner  = THIS_MODULE,
 570                .of_match_table = of_match_ptr(orion_spi_of_match_table),
 571        },
 572        .remove         = __exit_p(orion_spi_remove),
 573};
 574
 575static int __init orion_spi_init(void)
 576{
 577        orion_spi_wq = create_singlethread_workqueue(
 578                                orion_spi_driver.driver.name);
 579        if (orion_spi_wq == NULL)
 580                return -ENOMEM;
 581
 582        return platform_driver_probe(&orion_spi_driver, orion_spi_probe);
 583}
 584module_init(orion_spi_init);
 585
 586static void __exit orion_spi_exit(void)
 587{
 588        flush_workqueue(orion_spi_wq);
 589        platform_driver_unregister(&orion_spi_driver);
 590
 591        destroy_workqueue(orion_spi_wq);
 592}
 593module_exit(orion_spi_exit);
 594
 595MODULE_DESCRIPTION("Orion SPI driver");
 596MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>");
 597MODULE_LICENSE("GPL");
 598
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.