linux/drivers/spi/spi-cavium-octeon.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2011, 2012 Cavium, Inc.
   7 */
   8
   9#include <linux/platform_device.h>
  10#include <linux/spi/spi.h>
  11#include <linux/module.h>
  12#include <linux/io.h>
  13#include <linux/of.h>
  14
  15#include <asm/octeon/octeon.h>
  16
  17#include "spi-cavium.h"
  18
  19static int octeon_spi_probe(struct platform_device *pdev)
  20{
  21        void __iomem *reg_base;
  22        struct spi_master *master;
  23        struct octeon_spi *p;
  24        int err = -ENOENT;
  25
  26        master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
  27        if (!master)
  28                return -ENOMEM;
  29        p = spi_master_get_devdata(master);
  30        platform_set_drvdata(pdev, master);
  31
  32        reg_base = devm_platform_ioremap_resource(pdev, 0);
  33        if (IS_ERR(reg_base)) {
  34                err = PTR_ERR(reg_base);
  35                goto fail;
  36        }
  37
  38        p->register_base = reg_base;
  39        p->sys_freq = octeon_get_io_clock_rate();
  40
  41        p->regs.config = 0;
  42        p->regs.status = 0x08;
  43        p->regs.tx = 0x10;
  44        p->regs.data = 0x80;
  45
  46        master->num_chipselect = 4;
  47        master->mode_bits = SPI_CPHA |
  48                            SPI_CPOL |
  49                            SPI_CS_HIGH |
  50                            SPI_LSB_FIRST |
  51                            SPI_3WIRE;
  52
  53        master->transfer_one_message = octeon_spi_transfer_one_message;
  54        master->bits_per_word_mask = SPI_BPW_MASK(8);
  55        master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
  56
  57        master->dev.of_node = pdev->dev.of_node;
  58        err = devm_spi_register_master(&pdev->dev, master);
  59        if (err) {
  60                dev_err(&pdev->dev, "register master failed: %d\n", err);
  61                goto fail;
  62        }
  63
  64        dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
  65
  66        return 0;
  67fail:
  68        spi_master_put(master);
  69        return err;
  70}
  71
  72static int octeon_spi_remove(struct platform_device *pdev)
  73{
  74        struct spi_master *master = platform_get_drvdata(pdev);
  75        struct octeon_spi *p = spi_master_get_devdata(master);
  76
  77        /* Clear the CSENA* and put everything in a known state. */
  78        writeq(0, p->register_base + OCTEON_SPI_CFG(p));
  79
  80        return 0;
  81}
  82
  83static const struct of_device_id octeon_spi_match[] = {
  84        { .compatible = "cavium,octeon-3010-spi", },
  85        {},
  86};
  87MODULE_DEVICE_TABLE(of, octeon_spi_match);
  88
  89static struct platform_driver octeon_spi_driver = {
  90        .driver = {
  91                .name           = "spi-octeon",
  92                .of_match_table = octeon_spi_match,
  93        },
  94        .probe          = octeon_spi_probe,
  95        .remove         = octeon_spi_remove,
  96};
  97
  98module_platform_driver(octeon_spi_driver);
  99
 100MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
 101MODULE_AUTHOR("David Daney");
 102MODULE_LICENSE("GPL");
 103