0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/platform_device.h>
0010 #include <linux/spi/spi.h>
0011 #include <linux/module.h>
0012 #include <linux/io.h>
0013 #include <linux/of.h>
0014
0015 #include <asm/octeon/octeon.h>
0016
0017 #include "spi-cavium.h"
0018
0019 static int octeon_spi_probe(struct platform_device *pdev)
0020 {
0021 void __iomem *reg_base;
0022 struct spi_master *master;
0023 struct octeon_spi *p;
0024 int err = -ENOENT;
0025
0026 master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
0027 if (!master)
0028 return -ENOMEM;
0029 p = spi_master_get_devdata(master);
0030 platform_set_drvdata(pdev, master);
0031
0032 reg_base = devm_platform_ioremap_resource(pdev, 0);
0033 if (IS_ERR(reg_base)) {
0034 err = PTR_ERR(reg_base);
0035 goto fail;
0036 }
0037
0038 p->register_base = reg_base;
0039 p->sys_freq = octeon_get_io_clock_rate();
0040
0041 p->regs.config = 0;
0042 p->regs.status = 0x08;
0043 p->regs.tx = 0x10;
0044 p->regs.data = 0x80;
0045
0046 master->num_chipselect = 4;
0047 master->mode_bits = SPI_CPHA |
0048 SPI_CPOL |
0049 SPI_CS_HIGH |
0050 SPI_LSB_FIRST |
0051 SPI_3WIRE;
0052
0053 master->transfer_one_message = octeon_spi_transfer_one_message;
0054 master->bits_per_word_mask = SPI_BPW_MASK(8);
0055 master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
0056
0057 master->dev.of_node = pdev->dev.of_node;
0058 err = devm_spi_register_master(&pdev->dev, master);
0059 if (err) {
0060 dev_err(&pdev->dev, "register master failed: %d\n", err);
0061 goto fail;
0062 }
0063
0064 dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
0065
0066 return 0;
0067 fail:
0068 spi_master_put(master);
0069 return err;
0070 }
0071
0072 static int octeon_spi_remove(struct platform_device *pdev)
0073 {
0074 struct spi_master *master = platform_get_drvdata(pdev);
0075 struct octeon_spi *p = spi_master_get_devdata(master);
0076
0077
0078 writeq(0, p->register_base + OCTEON_SPI_CFG(p));
0079
0080 return 0;
0081 }
0082
0083 static const struct of_device_id octeon_spi_match[] = {
0084 { .compatible = "cavium,octeon-3010-spi", },
0085 {},
0086 };
0087 MODULE_DEVICE_TABLE(of, octeon_spi_match);
0088
0089 static struct platform_driver octeon_spi_driver = {
0090 .driver = {
0091 .name = "spi-octeon",
0092 .of_match_table = octeon_spi_match,
0093 },
0094 .probe = octeon_spi_probe,
0095 .remove = octeon_spi_remove,
0096 };
0097
0098 module_platform_driver(octeon_spi_driver);
0099
0100 MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
0101 MODULE_AUTHOR("David Daney");
0102 MODULE_LICENSE("GPL");