linux/drivers/spi/spi-ar934x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// SPI controller driver for Qualcomm Atheros AR934x/QCA95xx SoCs
   4//
   5// Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com>
   6//
   7// Based on spi-mt7621.c:
   8// Copyright (C) 2011 Sergiy <piratfm@gmail.com>
   9// Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
  10// Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
  11
  12#include <linux/clk.h>
  13#include <linux/io.h>
  14#include <linux/iopoll.h>
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/of_device.h>
  18#include <linux/spi/spi.h>
  19
  20#define DRIVER_NAME "spi-ar934x"
  21
  22#define AR934X_SPI_REG_FS               0x00
  23#define AR934X_SPI_ENABLE               BIT(0)
  24
  25#define AR934X_SPI_REG_IOC              0x08
  26#define AR934X_SPI_IOC_INITVAL          0x70000
  27
  28#define AR934X_SPI_REG_CTRL             0x04
  29#define AR934X_SPI_CLK_MASK             GENMASK(5, 0)
  30
  31#define AR934X_SPI_DATAOUT              0x10
  32
  33#define AR934X_SPI_REG_SHIFT_CTRL       0x14
  34#define AR934X_SPI_SHIFT_EN             BIT(31)
  35#define AR934X_SPI_SHIFT_CS(n)          BIT(28 + (n))
  36#define AR934X_SPI_SHIFT_TERM           26
  37#define AR934X_SPI_SHIFT_VAL(cs, term, count)                   \
  38        (AR934X_SPI_SHIFT_EN | AR934X_SPI_SHIFT_CS(cs) |        \
  39        (term) << AR934X_SPI_SHIFT_TERM | (count))
  40
  41#define AR934X_SPI_DATAIN 0x18
  42
  43struct ar934x_spi {
  44        struct spi_controller *ctlr;
  45        void __iomem *base;
  46        struct clk *clk;
  47        unsigned int clk_freq;
  48};
  49
  50static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq)
  51{
  52        int div = DIV_ROUND_UP(sp->clk_freq, freq * 2) - 1;
  53
  54        if (div < 0)
  55                return 0;
  56        else if (div > AR934X_SPI_CLK_MASK)
  57                return -EINVAL;
  58        else
  59                return div;
  60}
  61
  62static int ar934x_spi_setup(struct spi_device *spi)
  63{
  64        struct ar934x_spi *sp = spi_controller_get_devdata(spi->master);
  65
  66        if ((spi->max_speed_hz == 0) ||
  67            (spi->max_speed_hz > (sp->clk_freq / 2))) {
  68                spi->max_speed_hz = sp->clk_freq / 2;
  69        } else if (spi->max_speed_hz < (sp->clk_freq / 128)) {
  70                dev_err(&spi->dev, "spi clock is too low\n");
  71                return -EINVAL;
  72        }
  73
  74        return 0;
  75}
  76
  77static int ar934x_spi_transfer_one_message(struct spi_controller *master,
  78                                           struct spi_message *m)
  79{
  80        struct ar934x_spi *sp = spi_controller_get_devdata(master);
  81        struct spi_transfer *t = NULL;
  82        struct spi_device *spi = m->spi;
  83        unsigned long trx_done, trx_cur;
  84        int stat = 0;
  85        u8 term = 0;
  86        int div, i;
  87        u32 reg;
  88        const u8 *tx_buf;
  89        u8 *buf;
  90
  91        m->actual_length = 0;
  92        list_for_each_entry(t, &m->transfers, transfer_list) {
  93                if (t->speed_hz)
  94                        div = ar934x_spi_clk_div(sp, t->speed_hz);
  95                else
  96                        div = ar934x_spi_clk_div(sp, spi->max_speed_hz);
  97                if (div < 0) {
  98                        stat = -EIO;
  99                        goto msg_done;
 100                }
 101
 102                reg = ioread32(sp->base + AR934X_SPI_REG_CTRL);
 103                reg &= ~AR934X_SPI_CLK_MASK;
 104                reg |= div;
 105                iowrite32(reg, sp->base + AR934X_SPI_REG_CTRL);
 106                iowrite32(0, sp->base + AR934X_SPI_DATAOUT);
 107
 108                for (trx_done = 0; trx_done < t->len; trx_done += 4) {
 109                        trx_cur = t->len - trx_done;
 110                        if (trx_cur > 4)
 111                                trx_cur = 4;
 112                        else if (list_is_last(&t->transfer_list, &m->transfers))
 113                                term = 1;
 114
 115                        if (t->tx_buf) {
 116                                tx_buf = t->tx_buf + trx_done;
 117                                reg = tx_buf[0];
 118                                for (i = 1; i < trx_cur; i++)
 119                                        reg = reg << 8 | tx_buf[i];
 120                                iowrite32(reg, sp->base + AR934X_SPI_DATAOUT);
 121                        }
 122
 123                        reg = AR934X_SPI_SHIFT_VAL(spi->chip_select, term,
 124                                                   trx_cur * 8);
 125                        iowrite32(reg, sp->base + AR934X_SPI_REG_SHIFT_CTRL);
 126                        stat = readl_poll_timeout(
 127                                sp->base + AR934X_SPI_REG_SHIFT_CTRL, reg,
 128                                !(reg & AR934X_SPI_SHIFT_EN), 0, 5);
 129                        if (stat < 0)
 130                                goto msg_done;
 131
 132                        if (t->rx_buf) {
 133                                reg = ioread32(sp->base + AR934X_SPI_DATAIN);
 134                                buf = t->rx_buf + trx_done;
 135                                for (i = 0; i < trx_cur; i++) {
 136                                        buf[trx_cur - i - 1] = reg & 0xff;
 137                                        reg >>= 8;
 138                                }
 139                        }
 140                }
 141                m->actual_length += t->len;
 142        }
 143
 144msg_done:
 145        m->status = stat;
 146        spi_finalize_current_message(master);
 147
 148        return 0;
 149}
 150
 151static const struct of_device_id ar934x_spi_match[] = {
 152        { .compatible = "qca,ar934x-spi" },
 153        {},
 154};
 155MODULE_DEVICE_TABLE(of, ar934x_spi_match);
 156
 157static int ar934x_spi_probe(struct platform_device *pdev)
 158{
 159        struct spi_controller *ctlr;
 160        struct ar934x_spi *sp;
 161        void __iomem *base;
 162        struct clk *clk;
 163        int ret;
 164
 165        base = devm_platform_ioremap_resource(pdev, 0);
 166        if (IS_ERR(base))
 167                return PTR_ERR(base);
 168
 169        clk = devm_clk_get(&pdev->dev, NULL);
 170        if (IS_ERR(clk)) {
 171                dev_err(&pdev->dev, "failed to get clock\n");
 172                return PTR_ERR(clk);
 173        }
 174
 175        ret = clk_prepare_enable(clk);
 176        if (ret)
 177                return ret;
 178
 179        ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp));
 180        if (!ctlr) {
 181                dev_info(&pdev->dev, "failed to allocate spi controller\n");
 182                ret = -ENOMEM;
 183                goto err_clk_disable;
 184        }
 185
 186        /* disable flash mapping and expose spi controller registers */
 187        iowrite32(AR934X_SPI_ENABLE, base + AR934X_SPI_REG_FS);
 188        /* restore pins to default state: CSn=1 DO=CLK=0 */
 189        iowrite32(AR934X_SPI_IOC_INITVAL, base + AR934X_SPI_REG_IOC);
 190
 191        ctlr->mode_bits = SPI_LSB_FIRST;
 192        ctlr->setup = ar934x_spi_setup;
 193        ctlr->transfer_one_message = ar934x_spi_transfer_one_message;
 194        ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
 195        ctlr->dev.of_node = pdev->dev.of_node;
 196        ctlr->num_chipselect = 3;
 197
 198        dev_set_drvdata(&pdev->dev, ctlr);
 199
 200        sp = spi_controller_get_devdata(ctlr);
 201        sp->base = base;
 202        sp->clk = clk;
 203        sp->clk_freq = clk_get_rate(clk);
 204        sp->ctlr = ctlr;
 205
 206        ret = spi_register_controller(ctlr);
 207        if (!ret)
 208                return 0;
 209
 210err_clk_disable:
 211        clk_disable_unprepare(clk);
 212        return ret;
 213}
 214
 215static int ar934x_spi_remove(struct platform_device *pdev)
 216{
 217        struct spi_controller *ctlr;
 218        struct ar934x_spi *sp;
 219
 220        ctlr = dev_get_drvdata(&pdev->dev);
 221        sp = spi_controller_get_devdata(ctlr);
 222
 223        spi_unregister_controller(ctlr);
 224        clk_disable_unprepare(sp->clk);
 225
 226        return 0;
 227}
 228
 229static struct platform_driver ar934x_spi_driver = {
 230        .driver = {
 231                .name = DRIVER_NAME,
 232                .of_match_table = ar934x_spi_match,
 233        },
 234        .probe = ar934x_spi_probe,
 235        .remove = ar934x_spi_remove,
 236};
 237
 238module_platform_driver(ar934x_spi_driver);
 239
 240MODULE_DESCRIPTION("SPI controller driver for Qualcomm Atheros AR934x/QCA95xx");
 241MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>");
 242MODULE_LICENSE("GPL v2");
 243MODULE_ALIAS("platform:" DRIVER_NAME);
 244