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                spi_transfer_delay_exec(t);
 194
 195                if (cs_change) {
 196                        ndelay(nsecs);
 197                        hspi_hw_cs_disable(hspi);
 198                        ndelay(nsecs);
 199                }
 200        }
 201
 202        msg->status = ret;
 203        if (!cs_change) {
 204                ndelay(nsecs);
 205                hspi_hw_cs_disable(hspi);
 206        }
 207        spi_finalize_current_message(ctlr);
 208
 209        return ret;
 210}
 211
 212static int hspi_probe(struct platform_device *pdev)
 213{
 214        struct resource *res;
 215        struct spi_controller *ctlr;
 216        struct hspi_priv *hspi;
 217        struct clk *clk;
 218        int ret;
 219
 220        /* get base addr */
 221        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 222        if (!res) {
 223                dev_err(&pdev->dev, "invalid resource\n");
 224                return -EINVAL;
 225        }
 226
 227        ctlr = spi_alloc_master(&pdev->dev, sizeof(*hspi));
 228        if (!ctlr)
 229                return -ENOMEM;
 230
 231        clk = clk_get(&pdev->dev, NULL);
 232        if (IS_ERR(clk)) {
 233                dev_err(&pdev->dev, "couldn't get clock\n");
 234                ret = -EINVAL;
 235                goto error0;
 236        }
 237
 238        hspi = spi_controller_get_devdata(ctlr);
 239        platform_set_drvdata(pdev, hspi);
 240
 241        /* init hspi */
 242        hspi->ctlr      = ctlr;
 243        hspi->dev       = &pdev->dev;
 244        hspi->clk       = clk;
 245        hspi->addr      = devm_ioremap(hspi->dev,
 246                                       res->start, resource_size(res));
 247        if (!hspi->addr) {
 248                ret = -ENOMEM;
 249                goto error1;
 250        }
 251
 252        pm_runtime_enable(&pdev->dev);
 253
 254        ctlr->bus_num = pdev->id;
 255        ctlr->mode_bits = SPI_CPOL | SPI_CPHA;
 256        ctlr->dev.of_node = pdev->dev.of_node;
 257        ctlr->auto_runtime_pm = true;
 258        ctlr->transfer_one_message = hspi_transfer_one_message;
 259        ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
 260
 261        ret = devm_spi_register_controller(&pdev->dev, ctlr);
 262        if (ret < 0) {
 263                dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
 264                goto error2;
 265        }
 266
 267        return 0;
 268
 269 error2:
 270        pm_runtime_disable(&pdev->dev);
 271 error1:
 272        clk_put(clk);
 273 error0:
 274        spi_controller_put(ctlr);
 275
 276        return ret;
 277}
 278
 279static int hspi_remove(struct platform_device *pdev)
 280{
 281        struct hspi_priv *hspi = platform_get_drvdata(pdev);
 282
 283        pm_runtime_disable(&pdev->dev);
 284
 285        clk_put(hspi->clk);
 286
 287        return 0;
 288}
 289
 290static const struct of_device_id hspi_of_match[] = {
 291        { .compatible = "renesas,hspi", },
 292        { /* sentinel */ }
 293};
 294MODULE_DEVICE_TABLE(of, hspi_of_match);
 295
 296static struct platform_driver hspi_driver = {
 297        .probe = hspi_probe,
 298        .remove = hspi_remove,
 299        .driver = {
 300                .name = "sh-hspi",
 301                .of_match_table = hspi_of_match,
 302        },
 303};
 304module_platform_driver(hspi_driver);
 305
 306MODULE_DESCRIPTION("SuperH HSPI bus driver");
 307MODULE_LICENSE("GPL v2");
 308MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
 309MODULE_ALIAS("platform:sh-hspi");
 310