Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * SuperH HSPI bus driver
0004  *
0005  * Copyright (C) 2011  Kuninori Morimoto
0006  *
0007  * Based on spi-sh.c:
0008  * Based on pxa2xx_spi.c:
0009  * Copyright (C) 2011 Renesas Solutions Corp.
0010  * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
0011  */
0012 
0013 #include <linux/clk.h>
0014 #include <linux/module.h>
0015 #include <linux/kernel.h>
0016 #include <linux/timer.h>
0017 #include <linux/delay.h>
0018 #include <linux/list.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/pm_runtime.h>
0022 #include <linux/io.h>
0023 #include <linux/spi/spi.h>
0024 #include <linux/spi/sh_hspi.h>
0025 
0026 #define SPCR    0x00
0027 #define SPSR    0x04
0028 #define SPSCR   0x08
0029 #define SPTBR   0x0C
0030 #define SPRBR   0x10
0031 #define SPCR2   0x14
0032 
0033 /* SPSR */
0034 #define RXFL    (1 << 2)
0035 
0036 struct hspi_priv {
0037     void __iomem *addr;
0038     struct spi_controller *ctlr;
0039     struct device *dev;
0040     struct clk *clk;
0041 };
0042 
0043 /*
0044  *      basic function
0045  */
0046 static void hspi_write(struct hspi_priv *hspi, int reg, u32 val)
0047 {
0048     iowrite32(val, hspi->addr + reg);
0049 }
0050 
0051 static u32 hspi_read(struct hspi_priv *hspi, int reg)
0052 {
0053     return ioread32(hspi->addr + reg);
0054 }
0055 
0056 static void hspi_bit_set(struct hspi_priv *hspi, int reg, u32 mask, u32 set)
0057 {
0058     u32 val = hspi_read(hspi, reg);
0059 
0060     val &= ~mask;
0061     val |= set & mask;
0062 
0063     hspi_write(hspi, reg, val);
0064 }
0065 
0066 /*
0067  *      transfer function
0068  */
0069 static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val)
0070 {
0071     int t = 256;
0072 
0073     while (t--) {
0074         if ((mask & hspi_read(hspi, SPSR)) == val)
0075             return 0;
0076 
0077         udelay(10);
0078     }
0079 
0080     dev_err(hspi->dev, "timeout\n");
0081     return -ETIMEDOUT;
0082 }
0083 
0084 /*
0085  *      spi master function
0086  */
0087 
0088 #define hspi_hw_cs_enable(hspi)     hspi_hw_cs_ctrl(hspi, 0)
0089 #define hspi_hw_cs_disable(hspi)    hspi_hw_cs_ctrl(hspi, 1)
0090 static void hspi_hw_cs_ctrl(struct hspi_priv *hspi, int hi)
0091 {
0092     hspi_bit_set(hspi, SPSCR, (1 << 6), (hi) << 6);
0093 }
0094 
0095 static void hspi_hw_setup(struct hspi_priv *hspi,
0096               struct spi_message *msg,
0097               struct spi_transfer *t)
0098 {
0099     struct spi_device *spi = msg->spi;
0100     struct device *dev = hspi->dev;
0101     u32 spcr, idiv_clk;
0102     u32 rate, best_rate, min, tmp;
0103 
0104     /*
0105      * find best IDIV/CLKCx settings
0106      */
0107     min = ~0;
0108     best_rate = 0;
0109     spcr = 0;
0110     for (idiv_clk = 0x00; idiv_clk <= 0x3F; idiv_clk++) {
0111         rate = clk_get_rate(hspi->clk);
0112 
0113         /* IDIV calculation */
0114         if (idiv_clk & (1 << 5))
0115             rate /= 128;
0116         else
0117             rate /= 16;
0118 
0119         /* CLKCx calculation */
0120         rate /= (((idiv_clk & 0x1F) + 1) * 2);
0121 
0122         /* save best settings */
0123         tmp = abs(t->speed_hz - rate);
0124         if (tmp < min) {
0125             min = tmp;
0126             spcr = idiv_clk;
0127             best_rate = rate;
0128         }
0129     }
0130 
0131     if (spi->mode & SPI_CPHA)
0132         spcr |= 1 << 7;
0133     if (spi->mode & SPI_CPOL)
0134         spcr |= 1 << 6;
0135 
0136     dev_dbg(dev, "speed %d/%d\n", t->speed_hz, best_rate);
0137 
0138     hspi_write(hspi, SPCR, spcr);
0139     hspi_write(hspi, SPSR, 0x0);
0140     hspi_write(hspi, SPSCR, 0x21);  /* master mode / CS control */
0141 }
0142 
0143 static int hspi_transfer_one_message(struct spi_controller *ctlr,
0144                      struct spi_message *msg)
0145 {
0146     struct hspi_priv *hspi = spi_controller_get_devdata(ctlr);
0147     struct spi_transfer *t;
0148     u32 tx;
0149     u32 rx;
0150     int ret, i;
0151     unsigned int cs_change;
0152     const int nsecs = 50;
0153 
0154     dev_dbg(hspi->dev, "%s\n", __func__);
0155 
0156     cs_change = 1;
0157     ret = 0;
0158     list_for_each_entry(t, &msg->transfers, transfer_list) {
0159 
0160         if (cs_change) {
0161             hspi_hw_setup(hspi, msg, t);
0162             hspi_hw_cs_enable(hspi);
0163             ndelay(nsecs);
0164         }
0165         cs_change = t->cs_change;
0166 
0167         for (i = 0; i < t->len; i++) {
0168 
0169             /* wait remains */
0170             ret = hspi_status_check_timeout(hspi, 0x1, 0);
0171             if (ret < 0)
0172                 break;
0173 
0174             tx = 0;
0175             if (t->tx_buf)
0176                 tx = (u32)((u8 *)t->tx_buf)[i];
0177 
0178             hspi_write(hspi, SPTBR, tx);
0179 
0180             /* wait receive */
0181             ret = hspi_status_check_timeout(hspi, 0x4, 0x4);
0182             if (ret < 0)
0183                 break;
0184 
0185             rx = hspi_read(hspi, SPRBR);
0186             if (t->rx_buf)
0187                 ((u8 *)t->rx_buf)[i] = (u8)rx;
0188 
0189         }
0190 
0191         msg->actual_length += t->len;
0192 
0193         spi_transfer_delay_exec(t);
0194 
0195         if (cs_change) {
0196             ndelay(nsecs);
0197             hspi_hw_cs_disable(hspi);
0198             ndelay(nsecs);
0199         }
0200     }
0201 
0202     msg->status = ret;
0203     if (!cs_change) {
0204         ndelay(nsecs);
0205         hspi_hw_cs_disable(hspi);
0206     }
0207     spi_finalize_current_message(ctlr);
0208 
0209     return ret;
0210 }
0211 
0212 static int hspi_probe(struct platform_device *pdev)
0213 {
0214     struct resource *res;
0215     struct spi_controller *ctlr;
0216     struct hspi_priv *hspi;
0217     struct clk *clk;
0218     int ret;
0219 
0220     /* get base addr */
0221     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0222     if (!res) {
0223         dev_err(&pdev->dev, "invalid resource\n");
0224         return -EINVAL;
0225     }
0226 
0227     ctlr = spi_alloc_master(&pdev->dev, sizeof(*hspi));
0228     if (!ctlr)
0229         return -ENOMEM;
0230 
0231     clk = clk_get(&pdev->dev, NULL);
0232     if (IS_ERR(clk)) {
0233         dev_err(&pdev->dev, "couldn't get clock\n");
0234         ret = -EINVAL;
0235         goto error0;
0236     }
0237 
0238     hspi = spi_controller_get_devdata(ctlr);
0239     platform_set_drvdata(pdev, hspi);
0240 
0241     /* init hspi */
0242     hspi->ctlr  = ctlr;
0243     hspi->dev   = &pdev->dev;
0244     hspi->clk   = clk;
0245     hspi->addr  = devm_ioremap(hspi->dev,
0246                        res->start, resource_size(res));
0247     if (!hspi->addr) {
0248         ret = -ENOMEM;
0249         goto error1;
0250     }
0251 
0252     pm_runtime_enable(&pdev->dev);
0253 
0254     ctlr->bus_num = pdev->id;
0255     ctlr->mode_bits = SPI_CPOL | SPI_CPHA;
0256     ctlr->dev.of_node = pdev->dev.of_node;
0257     ctlr->auto_runtime_pm = true;
0258     ctlr->transfer_one_message = hspi_transfer_one_message;
0259     ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
0260 
0261     ret = devm_spi_register_controller(&pdev->dev, ctlr);
0262     if (ret < 0) {
0263         dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
0264         goto error2;
0265     }
0266 
0267     return 0;
0268 
0269  error2:
0270     pm_runtime_disable(&pdev->dev);
0271  error1:
0272     clk_put(clk);
0273  error0:
0274     spi_controller_put(ctlr);
0275 
0276     return ret;
0277 }
0278 
0279 static int hspi_remove(struct platform_device *pdev)
0280 {
0281     struct hspi_priv *hspi = platform_get_drvdata(pdev);
0282 
0283     pm_runtime_disable(&pdev->dev);
0284 
0285     clk_put(hspi->clk);
0286 
0287     return 0;
0288 }
0289 
0290 static const struct of_device_id hspi_of_match[] = {
0291     { .compatible = "renesas,hspi", },
0292     { /* sentinel */ }
0293 };
0294 MODULE_DEVICE_TABLE(of, hspi_of_match);
0295 
0296 static struct platform_driver hspi_driver = {
0297     .probe = hspi_probe,
0298     .remove = hspi_remove,
0299     .driver = {
0300         .name = "sh-hspi",
0301         .of_match_table = hspi_of_match,
0302     },
0303 };
0304 module_platform_driver(hspi_driver);
0305 
0306 MODULE_DESCRIPTION("SuperH HSPI bus driver");
0307 MODULE_LICENSE("GPL v2");
0308 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
0309 MODULE_ALIAS("platform:sh-hspi");