linux/drivers/spi/spi-npcm-pspi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2018 Nuvoton Technology corporation.
   3
   4#include <linux/kernel.h>
   5#include <linux/bitfield.h>
   6#include <linux/bitops.h>
   7#include <linux/clk.h>
   8#include <linux/interrupt.h>
   9#include <linux/io.h>
  10#include <linux/module.h>
  11#include <linux/platform_device.h>
  12#include <linux/spi/spi.h>
  13#include <linux/reset.h>
  14
  15#include <asm/unaligned.h>
  16
  17#include <linux/regmap.h>
  18#include <linux/mfd/syscon.h>
  19
  20struct npcm_pspi {
  21        struct completion xfer_done;
  22        struct reset_control *reset;
  23        struct spi_master *master;
  24        unsigned int tx_bytes;
  25        unsigned int rx_bytes;
  26        void __iomem *base;
  27        bool is_save_param;
  28        u8 bits_per_word;
  29        const u8 *tx_buf;
  30        struct clk *clk;
  31        u32 speed_hz;
  32        u8 *rx_buf;
  33        u16 mode;
  34        u32 id;
  35};
  36
  37#define DRIVER_NAME "npcm-pspi"
  38
  39#define NPCM_PSPI_DATA          0x00
  40#define NPCM_PSPI_CTL1          0x02
  41#define NPCM_PSPI_STAT          0x04
  42
  43/* definitions for control and status register */
  44#define NPCM_PSPI_CTL1_SPIEN    BIT(0)
  45#define NPCM_PSPI_CTL1_MOD      BIT(2)
  46#define NPCM_PSPI_CTL1_EIR      BIT(5)
  47#define NPCM_PSPI_CTL1_EIW      BIT(6)
  48#define NPCM_PSPI_CTL1_SCM      BIT(7)
  49#define NPCM_PSPI_CTL1_SCIDL    BIT(8)
  50#define NPCM_PSPI_CTL1_SCDV6_0  GENMASK(15, 9)
  51
  52#define NPCM_PSPI_STAT_BSY      BIT(0)
  53#define NPCM_PSPI_STAT_RBF      BIT(1)
  54
  55/* general definitions */
  56#define NPCM_PSPI_TIMEOUT_MS            2000
  57#define NPCM_PSPI_MAX_CLK_DIVIDER       256
  58#define NPCM_PSPI_MIN_CLK_DIVIDER       4
  59#define NPCM_PSPI_DEFAULT_CLK           25000000
  60
  61static inline unsigned int bytes_per_word(unsigned int bits)
  62{
  63        return bits <= 8 ? 1 : 2;
  64}
  65
  66static inline void npcm_pspi_irq_enable(struct npcm_pspi *priv, u16 mask)
  67{
  68        u16 val;
  69
  70        val = ioread16(priv->base + NPCM_PSPI_CTL1);
  71        val |= mask;
  72        iowrite16(val, priv->base + NPCM_PSPI_CTL1);
  73}
  74
  75static inline void npcm_pspi_irq_disable(struct npcm_pspi *priv, u16 mask)
  76{
  77        u16 val;
  78
  79        val = ioread16(priv->base + NPCM_PSPI_CTL1);
  80        val &= ~mask;
  81        iowrite16(val, priv->base + NPCM_PSPI_CTL1);
  82}
  83
  84static inline void npcm_pspi_enable(struct npcm_pspi *priv)
  85{
  86        u16 val;
  87
  88        val = ioread16(priv->base + NPCM_PSPI_CTL1);
  89        val |= NPCM_PSPI_CTL1_SPIEN;
  90        iowrite16(val, priv->base + NPCM_PSPI_CTL1);
  91}
  92
  93static inline void npcm_pspi_disable(struct npcm_pspi *priv)
  94{
  95        u16 val;
  96
  97        val = ioread16(priv->base + NPCM_PSPI_CTL1);
  98        val &= ~NPCM_PSPI_CTL1_SPIEN;
  99        iowrite16(val, priv->base + NPCM_PSPI_CTL1);
 100}
 101
 102static void npcm_pspi_set_mode(struct spi_device *spi)
 103{
 104        struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
 105        u16 regtemp;
 106        u16 mode_val;
 107
 108        switch (spi->mode & SPI_MODE_X_MASK) {
 109        case SPI_MODE_0:
 110                mode_val = 0;
 111                break;
 112        case SPI_MODE_1:
 113                mode_val = NPCM_PSPI_CTL1_SCIDL;
 114                break;
 115        case SPI_MODE_2:
 116                mode_val = NPCM_PSPI_CTL1_SCM;
 117                break;
 118        case SPI_MODE_3:
 119                mode_val = NPCM_PSPI_CTL1_SCIDL | NPCM_PSPI_CTL1_SCM;
 120                break;
 121        }
 122
 123        regtemp = ioread16(priv->base + NPCM_PSPI_CTL1);
 124        regtemp &= ~(NPCM_PSPI_CTL1_SCM | NPCM_PSPI_CTL1_SCIDL);
 125        iowrite16(regtemp | mode_val, priv->base + NPCM_PSPI_CTL1);
 126}
 127
 128static void npcm_pspi_set_transfer_size(struct npcm_pspi *priv, int size)
 129{
 130        u16 regtemp;
 131
 132        regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
 133
 134        switch (size) {
 135        case 8:
 136                regtemp &= ~NPCM_PSPI_CTL1_MOD;
 137                break;
 138        case 16:
 139                regtemp |= NPCM_PSPI_CTL1_MOD;
 140                break;
 141        }
 142
 143        iowrite16(regtemp, NPCM_PSPI_CTL1 + priv->base);
 144}
 145
 146static void npcm_pspi_set_baudrate(struct npcm_pspi *priv, unsigned int speed)
 147{
 148        u32 ckdiv;
 149        u16 regtemp;
 150
 151        /* the supported rates are numbers from 4 to 256. */
 152        ckdiv = DIV_ROUND_CLOSEST(clk_get_rate(priv->clk), (2 * speed)) - 1;
 153
 154        regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
 155        regtemp &= ~NPCM_PSPI_CTL1_SCDV6_0;
 156        iowrite16(regtemp | (ckdiv << 9), NPCM_PSPI_CTL1 + priv->base);
 157}
 158
 159static void npcm_pspi_setup_transfer(struct spi_device *spi,
 160                                     struct spi_transfer *t)
 161{
 162        struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
 163
 164        priv->tx_buf = t->tx_buf;
 165        priv->rx_buf = t->rx_buf;
 166        priv->tx_bytes = t->len;
 167        priv->rx_bytes = t->len;
 168
 169        if (!priv->is_save_param || priv->mode != spi->mode) {
 170                npcm_pspi_set_mode(spi);
 171                priv->mode = spi->mode;
 172        }
 173
 174        /*
 175         * If transfer is even length, and 8 bits per word transfer,
 176         * then implement 16 bits-per-word transfer.
 177         */
 178        if (priv->bits_per_word == 8 && !(t->len & 0x1))
 179                t->bits_per_word = 16;
 180
 181        if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) {
 182                npcm_pspi_set_transfer_size(priv, t->bits_per_word);
 183                priv->bits_per_word = t->bits_per_word;
 184        }
 185
 186        if (!priv->is_save_param || priv->speed_hz != t->speed_hz) {
 187                npcm_pspi_set_baudrate(priv, t->speed_hz);
 188                priv->speed_hz = t->speed_hz;
 189        }
 190
 191        if (!priv->is_save_param)
 192                priv->is_save_param = true;
 193}
 194
 195static void npcm_pspi_send(struct npcm_pspi *priv)
 196{
 197        int wsize;
 198        u16 val;
 199
 200        wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
 201        priv->tx_bytes -= wsize;
 202
 203        if (!priv->tx_buf)
 204                return;
 205
 206        switch (wsize) {
 207        case 1:
 208                val = *priv->tx_buf++;
 209                iowrite8(val, NPCM_PSPI_DATA + priv->base);
 210                break;
 211        case 2:
 212                val = *priv->tx_buf++;
 213                val = *priv->tx_buf++ | (val << 8);
 214                iowrite16(val, NPCM_PSPI_DATA + priv->base);
 215                break;
 216        default:
 217                WARN_ON_ONCE(1);
 218                return;
 219        }
 220}
 221
 222static void npcm_pspi_recv(struct npcm_pspi *priv)
 223{
 224        int rsize;
 225        u16 val;
 226
 227        rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
 228        priv->rx_bytes -= rsize;
 229
 230        if (!priv->rx_buf)
 231                return;
 232
 233        switch (rsize) {
 234        case 1:
 235                *priv->rx_buf++ = ioread8(priv->base + NPCM_PSPI_DATA);
 236                break;
 237        case 2:
 238                val = ioread16(priv->base + NPCM_PSPI_DATA);
 239                *priv->rx_buf++ = (val >> 8);
 240                *priv->rx_buf++ = val & 0xff;
 241                break;
 242        default:
 243                WARN_ON_ONCE(1);
 244                return;
 245        }
 246}
 247
 248static int npcm_pspi_transfer_one(struct spi_master *master,
 249                                  struct spi_device *spi,
 250                                  struct spi_transfer *t)
 251{
 252        struct npcm_pspi *priv = spi_master_get_devdata(master);
 253        int status;
 254
 255        npcm_pspi_setup_transfer(spi, t);
 256        reinit_completion(&priv->xfer_done);
 257        npcm_pspi_enable(priv);
 258        status = wait_for_completion_timeout(&priv->xfer_done,
 259                                             msecs_to_jiffies
 260                                             (NPCM_PSPI_TIMEOUT_MS));
 261        if (status == 0) {
 262                npcm_pspi_disable(priv);
 263                return -ETIMEDOUT;
 264        }
 265
 266        return 0;
 267}
 268
 269static int npcm_pspi_prepare_transfer_hardware(struct spi_master *master)
 270{
 271        struct npcm_pspi *priv = spi_master_get_devdata(master);
 272
 273        npcm_pspi_irq_enable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
 274
 275        return 0;
 276}
 277
 278static int npcm_pspi_unprepare_transfer_hardware(struct spi_master *master)
 279{
 280        struct npcm_pspi *priv = spi_master_get_devdata(master);
 281
 282        npcm_pspi_irq_disable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
 283
 284        return 0;
 285}
 286
 287static void npcm_pspi_reset_hw(struct npcm_pspi *priv)
 288{
 289        reset_control_assert(priv->reset);
 290        udelay(5);
 291        reset_control_deassert(priv->reset);
 292}
 293
 294static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
 295{
 296        struct npcm_pspi *priv = dev_id;
 297        u8 stat;
 298
 299        stat = ioread8(priv->base + NPCM_PSPI_STAT);
 300
 301        if (!priv->tx_buf && !priv->rx_buf)
 302                return IRQ_NONE;
 303
 304        if (priv->tx_buf) {
 305                if (stat & NPCM_PSPI_STAT_RBF) {
 306                        ioread8(NPCM_PSPI_DATA + priv->base);
 307                        if (priv->tx_bytes == 0) {
 308                                npcm_pspi_disable(priv);
 309                                complete(&priv->xfer_done);
 310                                return IRQ_HANDLED;
 311                        }
 312                }
 313
 314                if ((stat & NPCM_PSPI_STAT_BSY) == 0)
 315                        if (priv->tx_bytes)
 316                                npcm_pspi_send(priv);
 317        }
 318
 319        if (priv->rx_buf) {
 320                if (stat & NPCM_PSPI_STAT_RBF) {
 321                        if (!priv->rx_bytes)
 322                                return IRQ_NONE;
 323
 324                        npcm_pspi_recv(priv);
 325
 326                        if (!priv->rx_bytes) {
 327                                npcm_pspi_disable(priv);
 328                                complete(&priv->xfer_done);
 329                                return IRQ_HANDLED;
 330                        }
 331                }
 332
 333                if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
 334                        iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
 335        }
 336
 337        return IRQ_HANDLED;
 338}
 339
 340static int npcm_pspi_probe(struct platform_device *pdev)
 341{
 342        struct npcm_pspi *priv;
 343        struct spi_master *master;
 344        unsigned long clk_hz;
 345        int irq;
 346        int ret;
 347
 348        master = spi_alloc_master(&pdev->dev, sizeof(*priv));
 349        if (!master)
 350                return -ENOMEM;
 351
 352        platform_set_drvdata(pdev, master);
 353
 354        priv = spi_master_get_devdata(master);
 355        priv->master = master;
 356        priv->is_save_param = false;
 357
 358        priv->base = devm_platform_ioremap_resource(pdev, 0);
 359        if (IS_ERR(priv->base)) {
 360                ret = PTR_ERR(priv->base);
 361                goto out_master_put;
 362        }
 363
 364        priv->clk = devm_clk_get(&pdev->dev, NULL);
 365        if (IS_ERR(priv->clk)) {
 366                dev_err(&pdev->dev, "failed to get clock\n");
 367                ret = PTR_ERR(priv->clk);
 368                goto out_master_put;
 369        }
 370
 371        ret = clk_prepare_enable(priv->clk);
 372        if (ret)
 373                goto out_master_put;
 374
 375        irq = platform_get_irq(pdev, 0);
 376        if (irq < 0) {
 377                ret = irq;
 378                goto out_disable_clk;
 379        }
 380
 381        priv->reset = devm_reset_control_get(&pdev->dev, NULL);
 382        if (IS_ERR(priv->reset)) {
 383                ret = PTR_ERR(priv->reset);
 384                goto out_disable_clk;
 385        }
 386
 387        /* reset SPI-HW block */
 388        npcm_pspi_reset_hw(priv);
 389
 390        ret = devm_request_irq(&pdev->dev, irq, npcm_pspi_handler, 0,
 391                               "npcm-pspi", priv);
 392        if (ret) {
 393                dev_err(&pdev->dev, "failed to request IRQ\n");
 394                goto out_disable_clk;
 395        }
 396
 397        init_completion(&priv->xfer_done);
 398
 399        clk_hz = clk_get_rate(priv->clk);
 400
 401        master->max_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MIN_CLK_DIVIDER);
 402        master->min_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MAX_CLK_DIVIDER);
 403        master->mode_bits = SPI_CPHA | SPI_CPOL;
 404        master->dev.of_node = pdev->dev.of_node;
 405        master->bus_num = -1;
 406        master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 407        master->transfer_one = npcm_pspi_transfer_one;
 408        master->prepare_transfer_hardware =
 409                npcm_pspi_prepare_transfer_hardware;
 410        master->unprepare_transfer_hardware =
 411                npcm_pspi_unprepare_transfer_hardware;
 412        master->use_gpio_descriptors = true;
 413
 414        /* set to default clock rate */
 415        npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK);
 416
 417        ret = devm_spi_register_master(&pdev->dev, master);
 418        if (ret)
 419                goto out_disable_clk;
 420
 421        pr_info("NPCM Peripheral SPI %d probed\n", master->bus_num);
 422
 423        return 0;
 424
 425out_disable_clk:
 426        clk_disable_unprepare(priv->clk);
 427
 428out_master_put:
 429        spi_master_put(master);
 430        return ret;
 431}
 432
 433static int npcm_pspi_remove(struct platform_device *pdev)
 434{
 435        struct spi_master *master = platform_get_drvdata(pdev);
 436        struct npcm_pspi *priv = spi_master_get_devdata(master);
 437
 438        npcm_pspi_reset_hw(priv);
 439        clk_disable_unprepare(priv->clk);
 440
 441        return 0;
 442}
 443
 444static const struct of_device_id npcm_pspi_match[] = {
 445        { .compatible = "nuvoton,npcm750-pspi", .data = NULL },
 446        {}
 447};
 448MODULE_DEVICE_TABLE(of, npcm_pspi_match);
 449
 450static struct platform_driver npcm_pspi_driver = {
 451        .driver         = {
 452                .name           = DRIVER_NAME,
 453                .of_match_table = npcm_pspi_match,
 454        },
 455        .probe          = npcm_pspi_probe,
 456        .remove         = npcm_pspi_remove,
 457};
 458module_platform_driver(npcm_pspi_driver);
 459
 460MODULE_DESCRIPTION("NPCM peripheral SPI Controller driver");
 461MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
 462MODULE_LICENSE("GPL v2");
 463
 464