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_MODE_CPOL             (1 << 11)
  36#define ORION_SPI_MODE_CPHA             (1 << 12)
  37#define ORION_SPI_IF_8_16_BIT_MODE      (1 << 5)
  38#define ORION_SPI_CLK_PRESCALE_MASK     0x1F
  39#define ORION_SPI_MODE_MASK             (ORION_SPI_MODE_CPOL | \
  40                                         ORION_SPI_MODE_CPHA)
  41
  42struct orion_spi {
  43        struct spi_master       *master;
  44        void __iomem            *base;
  45        unsigned int            max_speed;
  46        unsigned int            min_speed;
  47        struct clk              *clk;
  48};
  49
  50static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
  51{
  52        return orion_spi->base + reg;
  53}
  54
  55static inline void
  56orion_spi_setbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
  57{
  58        void __iomem *reg_addr = spi_reg(orion_spi, reg);
  59        u32 val;
  60
  61        val = readl(reg_addr);
  62        val |= mask;
  63        writel(val, reg_addr);
  64}
  65
  66static inline void
  67orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
  68{
  69        void __iomem *reg_addr = spi_reg(orion_spi, reg);
  70        u32 val;
  71
  72        val = readl(reg_addr);
  73        val &= ~mask;
  74        writel(val, reg_addr);
  75}
  76
  77static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size)
  78{
  79        if (size == 16) {
  80                orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
  81                                  ORION_SPI_IF_8_16_BIT_MODE);
  82        } else if (size == 8) {
  83                orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
  84                                  ORION_SPI_IF_8_16_BIT_MODE);
  85        } else {
  86                pr_debug("Bad bits per word value %d (only 8 or 16 are "
  87                         "allowed).\n", size);
  88                return -EINVAL;
  89        }
  90
  91        return 0;
  92}
  93
  94static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
  95{
  96        u32 tclk_hz;
  97        u32 rate;
  98        u32 prescale;
  99        u32 reg;
 100        struct orion_spi *orion_spi;
 101
 102        orion_spi = spi_master_get_devdata(spi->master);
 103
 104        tclk_hz = clk_get_rate(orion_spi->clk);
 105
 106        /*
 107         * the supported rates are: 4,6,8...30
 108         * round up as we look for equal or less speed
 109         */
 110        rate = DIV_ROUND_UP(tclk_hz, speed);
 111        rate = roundup(rate, 2);
 112
 113        /* check if requested speed is too small */
 114        if (rate > 30)
 115                return -EINVAL;
 116
 117        if (rate < 4)
 118                rate = 4;
 119
 120        /* Convert the rate to SPI clock divisor value. */
 121        prescale = 0x10 + rate/2;
 122
 123        reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 124        reg = ((reg & ~ORION_SPI_CLK_PRESCALE_MASK) | prescale);
 125        writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 126
 127        return 0;
 128}
 129
 130static void
 131orion_spi_mode_set(struct spi_device *spi)
 132{
 133        u32 reg;
 134        struct orion_spi *orion_spi;
 135
 136        orion_spi = spi_master_get_devdata(spi->master);
 137
 138        reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 139        reg &= ~ORION_SPI_MODE_MASK;
 140        if (spi->mode & SPI_CPOL)
 141                reg |= ORION_SPI_MODE_CPOL;
 142        if (spi->mode & SPI_CPHA)
 143                reg |= ORION_SPI_MODE_CPHA;
 144        writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 145}
 146
 147/*
 148 * called only when no transfer is active on the bus
 149 */
 150static int
 151orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 152{
 153        struct orion_spi *orion_spi;
 154        unsigned int speed = spi->max_speed_hz;
 155        unsigned int bits_per_word = spi->bits_per_word;
 156        int     rc;
 157
 158        orion_spi = spi_master_get_devdata(spi->master);
 159
 160        if ((t != NULL) && t->speed_hz)
 161                speed = t->speed_hz;
 162
 163        if ((t != NULL) && t->bits_per_word)
 164                bits_per_word = t->bits_per_word;
 165
 166        orion_spi_mode_set(spi);
 167
 168        rc = orion_spi_baudrate_set(spi, speed);
 169        if (rc)
 170                return rc;
 171
 172        return orion_spi_set_transfer_size(orion_spi, bits_per_word);
 173}
 174
 175static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
 176{
 177        if (enable)
 178                orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
 179        else
 180                orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
 181}
 182
 183static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi)
 184{
 185        int i;
 186
 187        for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) {
 188                if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG)))
 189                        return 1;
 190                else
 191                        udelay(1);
 192        }
 193
 194        return -1;
 195}
 196
 197static inline int
 198orion_spi_write_read_8bit(struct spi_device *spi,
 199                          const u8 **tx_buf, u8 **rx_buf)
 200{
 201        void __iomem *tx_reg, *rx_reg, *int_reg;
 202        struct orion_spi *orion_spi;
 203
 204        orion_spi = spi_master_get_devdata(spi->master);
 205        tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
 206        rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
 207        int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
 208
 209        /* clear the interrupt cause register */
 210        writel(0x0, int_reg);
 211
 212        if (tx_buf && *tx_buf)
 213                writel(*(*tx_buf)++, tx_reg);
 214        else
 215                writel(0, tx_reg);
 216
 217        if (orion_spi_wait_till_ready(orion_spi) < 0) {
 218                dev_err(&spi->dev, "TXS timed out\n");
 219                return -1;
 220        }
 221
 222        if (rx_buf && *rx_buf)
 223                *(*rx_buf)++ = readl(rx_reg);
 224
 225        return 1;
 226}
 227
 228static inline int
 229orion_spi_write_read_16bit(struct spi_device *spi,
 230                           const u16 **tx_buf, u16 **rx_buf)
 231{
 232        void __iomem *tx_reg, *rx_reg, *int_reg;
 233        struct orion_spi *orion_spi;
 234
 235        orion_spi = spi_master_get_devdata(spi->master);
 236        tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
 237        rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
 238        int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
 239
 240        /* clear the interrupt cause register */
 241        writel(0x0, int_reg);
 242
 243        if (tx_buf && *tx_buf)
 244                writel(__cpu_to_le16(get_unaligned((*tx_buf)++)), tx_reg);
 245        else
 246                writel(0, tx_reg);
 247
 248        if (orion_spi_wait_till_ready(orion_spi) < 0) {
 249                dev_err(&spi->dev, "TXS timed out\n");
 250                return -1;
 251        }
 252
 253        if (rx_buf && *rx_buf)
 254                put_unaligned(__le16_to_cpu(readl(rx_reg)), (*rx_buf)++);
 255
 256        return 1;
 257}
 258
 259static unsigned int
 260orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
 261{
 262        struct orion_spi *orion_spi;
 263        unsigned int count;
 264        int word_len;
 265
 266        orion_spi = spi_master_get_devdata(spi->master);
 267        word_len = spi->bits_per_word;
 268        count = xfer->len;
 269
 270        if (word_len == 8) {
 271                const u8 *tx = xfer->tx_buf;
 272                u8 *rx = xfer->rx_buf;
 273
 274                do {
 275                        if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0)
 276                                goto out;
 277                        count--;
 278                } while (count);
 279        } else if (word_len == 16) {
 280                const u16 *tx = xfer->tx_buf;
 281                u16 *rx = xfer->rx_buf;
 282
 283                do {
 284                        if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0)
 285                                goto out;
 286                        count -= 2;
 287                } while (count);
 288        }
 289
 290out:
 291        return xfer->len - count;
 292}
 293
 294
 295static int orion_spi_transfer_one_message(struct spi_master *master,
 296                                           struct spi_message *m)
 297{
 298        struct orion_spi *orion_spi = spi_master_get_devdata(master);
 299        struct spi_device *spi = m->spi;
 300        struct spi_transfer *t = NULL;
 301        int par_override = 0;
 302        int status = 0;
 303        int cs_active = 0;
 304
 305        /* Load defaults */
 306        status = orion_spi_setup_transfer(spi, NULL);
 307
 308        if (status < 0)
 309                goto msg_done;
 310
 311        list_for_each_entry(t, &m->transfers, transfer_list) {
 312                /* make sure buffer length is even when working in 16
 313                 * bit mode*/
 314                if ((t->bits_per_word == 16) && (t->len & 1)) {
 315                        dev_err(&spi->dev,
 316                                "message rejected : "
 317                                "odd data length %d while in 16 bit mode\n",
 318                                t->len);
 319                        status = -EIO;
 320                        goto msg_done;
 321                }
 322
 323                if (t->speed_hz && t->speed_hz < orion_spi->min_speed) {
 324                        dev_err(&spi->dev,
 325                                "message rejected : "
 326                                "device min speed (%d Hz) exceeds "
 327                                "required transfer speed (%d Hz)\n",
 328                                orion_spi->min_speed, t->speed_hz);
 329                        status = -EIO;
 330                        goto msg_done;
 331                }
 332
 333                if (par_override || t->speed_hz || t->bits_per_word) {
 334                        par_override = 1;
 335                        status = orion_spi_setup_transfer(spi, t);
 336                        if (status < 0)
 337                                break;
 338                        if (!t->speed_hz && !t->bits_per_word)
 339                                par_override = 0;
 340                }
 341
 342                if (!cs_active) {
 343                        orion_spi_set_cs(orion_spi, 1);
 344                        cs_active = 1;
 345                }
 346
 347                if (t->len)
 348                        m->actual_length += orion_spi_write_read(spi, t);
 349
 350                if (t->delay_usecs)
 351                        udelay(t->delay_usecs);
 352
 353                if (t->cs_change) {
 354                        orion_spi_set_cs(orion_spi, 0);
 355                        cs_active = 0;
 356                }
 357        }
 358
 359msg_done:
 360        if (cs_active)
 361                orion_spi_set_cs(orion_spi, 0);
 362
 363        m->status = status;
 364        spi_finalize_current_message(master);
 365
 366        return 0;
 367}
 368
 369static int orion_spi_reset(struct orion_spi *orion_spi)
 370{
 371        /* Verify that the CS is deasserted */
 372        orion_spi_set_cs(orion_spi, 0);
 373
 374        return 0;
 375}
 376
 377static int orion_spi_setup(struct spi_device *spi)
 378{
 379        struct orion_spi *orion_spi;
 380
 381        orion_spi = spi_master_get_devdata(spi->master);
 382
 383        if ((spi->max_speed_hz == 0)
 384                        || (spi->max_speed_hz > orion_spi->max_speed))
 385                spi->max_speed_hz = orion_spi->max_speed;
 386
 387        if (spi->max_speed_hz < orion_spi->min_speed) {
 388                dev_err(&spi->dev, "setup: requested speed too low %d Hz\n",
 389                        spi->max_speed_hz);
 390                return -EINVAL;
 391        }
 392
 393        /*
 394         * baudrate & width will be set orion_spi_setup_transfer
 395         */
 396        return 0;
 397}
 398
 399static int orion_spi_probe(struct platform_device *pdev)
 400{
 401        struct spi_master *master;
 402        struct orion_spi *spi;
 403        struct resource *r;
 404        unsigned long tclk_hz;
 405        int status = 0;
 406        const u32 *iprop;
 407        int size;
 408
 409        master = spi_alloc_master(&pdev->dev, sizeof *spi);
 410        if (master == NULL) {
 411                dev_dbg(&pdev->dev, "master allocation failed\n");
 412                return -ENOMEM;
 413        }
 414
 415        if (pdev->id != -1)
 416                master->bus_num = pdev->id;
 417        if (pdev->dev.of_node) {
 418                iprop = of_get_property(pdev->dev.of_node, "cell-index",
 419                                        &size);
 420                if (iprop && size == sizeof(*iprop))
 421                        master->bus_num = *iprop;
 422        }
 423
 424        /* we support only mode 0, and no options */
 425        master->mode_bits = SPI_CPHA | SPI_CPOL;
 426
 427        master->setup = orion_spi_setup;
 428        master->transfer_one_message = orion_spi_transfer_one_message;
 429        master->num_chipselect = ORION_NUM_CHIPSELECTS;
 430
 431        dev_set_drvdata(&pdev->dev, master);
 432
 433        spi = spi_master_get_devdata(master);
 434        spi->master = master;
 435
 436        spi->clk = clk_get(&pdev->dev, NULL);
 437        if (IS_ERR(spi->clk)) {
 438                status = PTR_ERR(spi->clk);
 439                goto out;
 440        }
 441
 442        clk_prepare(spi->clk);
 443        clk_enable(spi->clk);
 444        tclk_hz = clk_get_rate(spi->clk);
 445        spi->max_speed = DIV_ROUND_UP(tclk_hz, 4);
 446        spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
 447
 448        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 449        if (r == NULL) {
 450                status = -ENODEV;
 451                goto out_rel_clk;
 452        }
 453
 454        if (!request_mem_region(r->start, resource_size(r),
 455                                dev_name(&pdev->dev))) {
 456                status = -EBUSY;
 457                goto out_rel_clk;
 458        }
 459        spi->base = ioremap(r->start, SZ_1K);
 460
 461        if (orion_spi_reset(spi) < 0)
 462                goto out_rel_mem;
 463
 464        master->dev.of_node = pdev->dev.of_node;
 465        status = spi_register_master(master);
 466        if (status < 0)
 467                goto out_rel_mem;
 468
 469        return status;
 470
 471out_rel_mem:
 472        release_mem_region(r->start, resource_size(r));
 473out_rel_clk:
 474        clk_disable_unprepare(spi->clk);
 475        clk_put(spi->clk);
 476out:
 477        spi_master_put(master);
 478        return status;
 479}
 480
 481
 482static int orion_spi_remove(struct platform_device *pdev)
 483{
 484        struct spi_master *master;
 485        struct resource *r;
 486        struct orion_spi *spi;
 487
 488        master = dev_get_drvdata(&pdev->dev);
 489        spi = spi_master_get_devdata(master);
 490
 491        clk_disable_unprepare(spi->clk);
 492        clk_put(spi->clk);
 493
 494        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 495        release_mem_region(r->start, resource_size(r));
 496
 497        spi_unregister_master(master);
 498
 499        return 0;
 500}
 501
 502MODULE_ALIAS("platform:" DRIVER_NAME);
 503
 504static const struct of_device_id orion_spi_of_match_table[] = {
 505        { .compatible = "marvell,orion-spi", },
 506        {}
 507};
 508MODULE_DEVICE_TABLE(of, orion_spi_of_match_table);
 509
 510static struct platform_driver orion_spi_driver = {
 511        .driver = {
 512                .name   = DRIVER_NAME,
 513                .owner  = THIS_MODULE,
 514                .of_match_table = of_match_ptr(orion_spi_of_match_table),
 515        },
 516        .probe          = orion_spi_probe,
 517        .remove         = orion_spi_remove,
 518};
 519
 520module_platform_driver(orion_spi_driver);
 521
 522MODULE_DESCRIPTION("Orion SPI driver");
 523MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>");
 524MODULE_LICENSE("GPL");
 525
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.