linux/drivers/spi/spi-sh-hspi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * SuperH HSPI bus driver
   4 *
   5 * Copyright (C) 2011  Kuninori Morimoto
   6 *
   7 * Based on spi-sh.c:
   8 * Based on pxa2xx_spi.c:
   9 * Copyright (C) 2011 Renesas Solutions Corp.
  10 * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
  11 */
  12
  13#include <linux/clk.h>
  14#include <linux/module.h>
  15#include <linux/kernel.h>
  16#include <linux/timer.h>
  17#include <linux/delay.h>
  18#include <linux/list.h>
  19#include <linux/interrupt.h>
  20#include <linux/platform_device.h>
  21#include <linux/pm_runtime.h>
  22#include <linux/io.h>
  23#include <linux/spi/spi.h>
  24#include <linux/spi/sh_hspi.h>
  25
  26#define SPCR    0x00
  27#define SPSR    0x04
  28#define SPSCR   0x08
  29#define SPTBR   0x0C
  30#define SPRBR   0x10
  31#define SPCR2   0x14
  32
  33/* SPSR */
  34#define RXFL    (1 << 2)
  35
  36struct hspi_priv {
  37        void __iomem *addr;
  38        struct spi_controller *ctlr;
  39        struct device *dev;
  40        struct clk *clk;
  41};
  42
  43/*
  44 *              basic function
  45 */
  46static void hspi_write(struct hspi_priv *hspi, int reg, u32 val)
  47{
  48        iowrite32(val, hspi->addr + reg);
  49}
  50
  51static u32 hspi_read(struct hspi_priv *hspi, int reg)
  52{
  53        return ioread32(hspi->addr + reg);
  54}
  55
  56static void hspi_bit_set(struct hspi_priv *hspi, int reg, u32 mask, u32 set)
  57{
  58        u32 val = hspi_read(hspi, reg);
  59
  60        val &= ~mask;
  61        val |= set & mask;
  62
  63        hspi_write(hspi, reg, val);
  64}
  65
  66/*
  67 *              transfer function
  68 */
  69static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val)
  70{
  71        int t = 256;
  72
  73        while (t--) {
  74                if ((mask & hspi_read(hspi, SPSR)) == val)
  75                        return 0;
  76
  77                udelay(10);
  78        }
  79
  80        dev_err(hspi->dev, "timeout\n");
  81        return -ETIMEDOUT;
  82}
  83
  84/*
  85 *              spi master function
  86 */
  87
  88#define hspi_hw_cs_enable(hspi)         hspi_hw_cs_ctrl(hspi, 0)
  89#define hspi_hw_cs_disable(hspi)        hspi_hw_cs_ctrl(hspi, 1)
  90static void hspi_hw_cs_ctrl(struct hspi_priv *hspi, int hi)
  91{
  92        hspi_bit_set(hspi, SPSCR, (1 << 6), (hi) << 6);
  93}
  94
  95static void hspi_hw_setup(struct hspi_priv *hspi,
  96                          struct spi_message *msg,
  97                          struct spi_transfer *t)
  98{
  99        struct spi_device *spi = msg->spi;
 100        struct device *dev = hspi->dev;
 101        u32 spcr, idiv_clk;
 102        u32 rate, best_rate, min, tmp;
 103
 104        /*
 105         * find best IDIV/CLKCx settings
 106         */
 107        min = ~0;
 108        best_rate = 0;
 109        spcr = 0;
 110        for (idiv_clk = 0x00; idiv_clk <= 0x3F; idiv_clk++) {
 111                rate = clk_get_rate(hspi->clk);
 112
 113                /* IDIV calculation */
 114                if (idiv_clk & (1 << 5))
 115                        rate /= 128;
 116                else
 117                        rate /= 16;
 118
 119                /* CLKCx calculation */
 120                rate /= (((idiv_clk & 0x1F) + 1) * 2);
 121
 122                /* save best settings */
 123                tmp = abs(t->speed_hz - rate);
 124                if (tmp < min) {
 125                        min = tmp;
 126                        spcr = idiv_clk;
 127                        best_rate = rate;
 128                }
 129        }
 130
 131        if (spi->mode & SPI_CPHA)
 132                spcr |= 1 << 7;
 133        if (spi->mode & SPI_CPOL)
 134                spcr |= 1 << 6;
 135
 136        dev_dbg(dev, "speed %d/%d\n", t->speed_hz, best_rate);
 137
 138        hspi_write(hspi, SPCR, spcr);
 139        hspi_write(hspi, SPSR, 0x0);
 140        hspi_write(hspi, SPSCR, 0x21);  /* master mode / CS control */
 141}
 142
 143static int hspi_transfer_one_message(struct spi_controller *ctlr,
 144                                     struct spi_message *msg)
 145{
 146        struct hspi_priv *hspi = spi_controller_get_devdata(ctlr);
 147        struct spi_transfer *t;
 148        u32 tx;
 149        u32 rx;
 150        int ret, i;
 151        unsigned int cs_change;
 152        const int nsecs = 50;
 153
 154        dev_dbg(hspi->dev, "%s\n", __func__);
 155
 156        cs_change = 1;
 157        ret = 0;
 158        list_for_each_entry(t, &msg->transfers, transfer_list) {
 159
 160                if (cs_change) {
 161                        hspi_hw_setup(hspi, msg, t);
 162                        hspi_hw_cs_enable(hspi);
 163                        ndelay(nsecs);
 164                }
 165                cs_change = t->cs_change;
 166
 167                for (i = 0; i < t->len; i++) {
 168
 169                        /* wait remains */
 170                        ret = hspi_status_check_timeout(hspi, 0x1, 0);
 171                        if (ret < 0)
 172                                break;
 173
 174                        tx = 0;
 175                        if (t->tx_buf)
 176                                tx = (u32)((u8 *)t->tx_buf)[i];
 177
 178                        hspi_write(hspi, SPTBR, tx);
 179
 180                        /* wait receive */
 181                        ret = hspi_status_check_timeout(hspi, 0x4, 0x4);
 182                        if (ret < 0)
 183                                break;
 184
 185                        rx = hspi_read(hspi, SPRBR);
 186                        if (t->rx_buf)
 187                                ((u8 *)t->rx_buf)[i] = (u8)rx;
 188
 189                }
 190
 191                msg->actual_length += t->len;
 192
 193                if (t->delay_usecs)
 194                        udelay(t->delay_usecs);
 195
 196                if (cs_change) {
 197                        ndelay(nsecs);
 198                        hspi_hw_cs_disable(hspi);
 199                        ndelay(nsecs);
 200                }
 201        }
 202
 203        msg->status = ret;
 204        if (!cs_change) {
 205                ndelay(nsecs);
 206                hspi_hw_cs_disable(hspi);
 207        }
 208        spi_finalize_current_message(ctlr);
 209
 210        return ret;
 211}
 212
 213static int hspi_probe(struct platform_device *pdev)
 214{
 215        struct resource *res;
 216        struct spi_controller *ctlr;
 217        struct hspi_priv *hspi;
 218        struct clk *clk;
 219        int ret;
 220
 221        /* get base addr */
 222        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 223        if (!res) {
 224                dev_err(&pdev->dev, "invalid resource\n");
 225                return -EINVAL;
 226        }
 227
 228        ctlr = spi_alloc_master(&pdev->dev, sizeof(*hspi));
 229        if (!ctlr)
 230                return -ENOMEM;
 231
 232        clk = clk_get(&pdev->dev, NULL);
 233        if (IS_ERR(clk)) {
 234                dev_err(&pdev->dev, "couldn't get clock\n");
 235                ret = -EINVAL;
 236                goto error0;
 237        }
 238
 239        hspi = spi_controller_get_devdata(ctlr);
 240        platform_set_drvdata(pdev, hspi);
 241
 242        /* init hspi */
 243        hspi->ctlr      = ctlr;
 244        hspi->dev       = &pdev->dev;
 245        hspi->clk       = clk;
 246        hspi->addr      = devm_ioremap(hspi->dev,
 247                                       res->start, resource_size(res));
 248        if (!hspi->addr) {
 249                ret = -ENOMEM;
 250                goto error1;
 251        }
 252
 253        pm_runtime_enable(&pdev->dev);
 254
 255        ctlr->bus_num = pdev->id;
 256        ctlr->mode_bits = SPI_CPOL | SPI_CPHA;
 257        ctlr->dev.of_node = pdev->dev.of_node;
 258        ctlr->auto_runtime_pm = true;
 259        ctlr->transfer_one_message = hspi_transfer_one_message;
 260        ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
 261
 262        ret = devm_spi_register_controller(&pdev->dev, ctlr);
 263        if (ret < 0) {
 264                dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
 265                goto error2;
 266        }
 267
 268        return 0;
 269
 270 error2:
 271        pm_runtime_disable(&pdev->dev);
 272 error1:
 273        clk_put(clk);
 274 error0:
 275        spi_controller_put(ctlr);
 276
 277        return ret;
 278}
 279
 280static int hspi_remove(struct platform_device *pdev)
 281{
 282        struct hspi_priv *hspi = platform_get_drvdata(pdev);
 283
 284        pm_runtime_disable(&pdev->dev);
 285
 286        clk_put(hspi->clk);
 287
 288        return 0;
 289}
 290
 291static const struct of_device_id hspi_of_match[] = {
 292        { .compatible = "renesas,hspi", },
 293        { /* sentinel */ }
 294};
 295MODULE_DEVICE_TABLE(of, hspi_of_match);
 296
 297static struct platform_driver hspi_driver = {
 298        .probe = hspi_probe,
 299        .remove = hspi_remove,
 300        .driver = {
 301                .name = "sh-hspi",
 302                .of_match_table = hspi_of_match,
 303        },
 304};
 305module_platform_driver(hspi_driver);
 306
 307MODULE_DESCRIPTION("SuperH HSPI bus driver");
 308MODULE_LICENSE("GPL v2");
 309MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
 310MODULE_ALIAS("platform:sh-hspi");
 311