linux/drivers/spi/spi-sh-hspi.c
<<
>>
Prefs
   1/*
   2 * SuperH HSPI bus driver
   3 *
   4 * Copyright (C) 2011  Kuninori Morimoto
   5 *
   6 * Based on spi-sh.c:
   7 * Based on pxa2xx_spi.c:
   8 * Copyright (C) 2011 Renesas Solutions Corp.
   9 * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; version 2 of the License.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  23 *
  24 */
  25
  26#include <linux/clk.h>
  27#include <linux/module.h>
  28#include <linux/kernel.h>
  29#include <linux/timer.h>
  30#include <linux/delay.h>
  31#include <linux/list.h>
  32#include <linux/interrupt.h>
  33#include <linux/platform_device.h>
  34#include <linux/pm_runtime.h>
  35#include <linux/io.h>
  36#include <linux/spi/spi.h>
  37#include <linux/spi/sh_hspi.h>
  38
  39#define SPCR    0x00
  40#define SPSR    0x04
  41#define SPSCR   0x08
  42#define SPTBR   0x0C
  43#define SPRBR   0x10
  44#define SPCR2   0x14
  45
  46/* SPSR */
  47#define RXFL    (1 << 2)
  48
  49#define hspi2info(h)    (h->dev->platform_data)
  50
  51struct hspi_priv {
  52        void __iomem *addr;
  53        struct spi_master *master;
  54        struct device *dev;
  55        struct clk *clk;
  56};
  57
  58/*
  59 *              basic function
  60 */
  61static void hspi_write(struct hspi_priv *hspi, int reg, u32 val)
  62{
  63        iowrite32(val, hspi->addr + reg);
  64}
  65
  66static u32 hspi_read(struct hspi_priv *hspi, int reg)
  67{
  68        return ioread32(hspi->addr + reg);
  69}
  70
  71static void hspi_bit_set(struct hspi_priv *hspi, int reg, u32 mask, u32 set)
  72{
  73        u32 val = hspi_read(hspi, reg);
  74
  75        val &= ~mask;
  76        val |= set & mask;
  77
  78        hspi_write(hspi, reg, val);
  79}
  80
  81/*
  82 *              transfer function
  83 */
  84static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val)
  85{
  86        int t = 256;
  87
  88        while (t--) {
  89                if ((mask & hspi_read(hspi, SPSR)) == val)
  90                        return 0;
  91
  92                udelay(10);
  93        }
  94
  95        dev_err(hspi->dev, "timeout\n");
  96        return -ETIMEDOUT;
  97}
  98
  99/*
 100 *              spi master function
 101 */
 102
 103#define hspi_hw_cs_enable(hspi)         hspi_hw_cs_ctrl(hspi, 0)
 104#define hspi_hw_cs_disable(hspi)        hspi_hw_cs_ctrl(hspi, 1)
 105static void hspi_hw_cs_ctrl(struct hspi_priv *hspi, int hi)
 106{
 107        hspi_bit_set(hspi, SPSCR, (1 << 6), (hi) << 6);
 108}
 109
 110static void hspi_hw_setup(struct hspi_priv *hspi,
 111                          struct spi_message *msg,
 112                          struct spi_transfer *t)
 113{
 114        struct spi_device *spi = msg->spi;
 115        struct device *dev = hspi->dev;
 116        u32 target_rate;
 117        u32 spcr, idiv_clk;
 118        u32 rate, best_rate, min, tmp;
 119
 120        target_rate = t ? t->speed_hz : 0;
 121        if (!target_rate)
 122                target_rate = spi->max_speed_hz;
 123
 124        /*
 125         * find best IDIV/CLKCx settings
 126         */
 127        min = ~0;
 128        best_rate = 0;
 129        spcr = 0;
 130        for (idiv_clk = 0x00; idiv_clk <= 0x3F; idiv_clk++) {
 131                rate = clk_get_rate(hspi->clk);
 132
 133                /* IDIV calculation */
 134                if (idiv_clk & (1 << 5))
 135                        rate /= 128;
 136                else
 137                        rate /= 16;
 138
 139                /* CLKCx calculation */
 140                rate /= (((idiv_clk & 0x1F) + 1) * 2) ;
 141
 142                /* save best settings */
 143                tmp = abs(target_rate - rate);
 144                if (tmp < min) {
 145                        min = tmp;
 146                        spcr = idiv_clk;
 147                        best_rate = rate;
 148                }
 149        }
 150
 151        if (spi->mode & SPI_CPHA)
 152                spcr |= 1 << 7;
 153        if (spi->mode & SPI_CPOL)
 154                spcr |= 1 << 6;
 155
 156        dev_dbg(dev, "speed %d/%d\n", target_rate, best_rate);
 157
 158        hspi_write(hspi, SPCR, spcr);
 159        hspi_write(hspi, SPSR, 0x0);
 160        hspi_write(hspi, SPSCR, 0x21);  /* master mode / CS control */
 161}
 162
 163static int hspi_transfer_one_message(struct spi_master *master,
 164                                     struct spi_message *msg)
 165{
 166        struct hspi_priv *hspi = spi_master_get_devdata(master);
 167        struct spi_transfer *t;
 168        u32 tx;
 169        u32 rx;
 170        int ret, i;
 171        unsigned int cs_change;
 172        const int nsecs = 50;
 173
 174        dev_dbg(hspi->dev, "%s\n", __func__);
 175
 176        cs_change = 1;
 177        ret = 0;
 178        list_for_each_entry(t, &msg->transfers, transfer_list) {
 179
 180                if (cs_change) {
 181                        hspi_hw_setup(hspi, msg, t);
 182                        hspi_hw_cs_enable(hspi);
 183                        ndelay(nsecs);
 184                }
 185                cs_change = t->cs_change;
 186
 187                for (i = 0; i < t->len; i++) {
 188
 189                        /* wait remains */
 190                        ret = hspi_status_check_timeout(hspi, 0x1, 0);
 191                        if (ret < 0)
 192                                break;
 193
 194                        tx = 0;
 195                        if (t->tx_buf)
 196                                tx = (u32)((u8 *)t->tx_buf)[i];
 197
 198                        hspi_write(hspi, SPTBR, tx);
 199
 200                        /* wait recive */
 201                        ret = hspi_status_check_timeout(hspi, 0x4, 0x4);
 202                        if (ret < 0)
 203                                break;
 204
 205                        rx = hspi_read(hspi, SPRBR);
 206                        if (t->rx_buf)
 207                                ((u8 *)t->rx_buf)[i] = (u8)rx;
 208
 209                }
 210
 211                msg->actual_length += t->len;
 212
 213                if (t->delay_usecs)
 214                        udelay(t->delay_usecs);
 215
 216                if (cs_change) {
 217                        ndelay(nsecs);
 218                        hspi_hw_cs_disable(hspi);
 219                        ndelay(nsecs);
 220                }
 221        }
 222
 223        msg->status = ret;
 224        if (!cs_change) {
 225                ndelay(nsecs);
 226                hspi_hw_cs_disable(hspi);
 227        }
 228        spi_finalize_current_message(master);
 229
 230        return ret;
 231}
 232
 233static int hspi_setup(struct spi_device *spi)
 234{
 235        struct hspi_priv *hspi = spi_master_get_devdata(spi->master);
 236        struct device *dev = hspi->dev;
 237
 238        if (8 != spi->bits_per_word) {
 239                dev_err(dev, "bits_per_word should be 8\n");
 240                return -EIO;
 241        }
 242
 243        dev_dbg(dev, "%s setup\n", spi->modalias);
 244
 245        return 0;
 246}
 247
 248static void hspi_cleanup(struct spi_device *spi)
 249{
 250        struct hspi_priv *hspi = spi_master_get_devdata(spi->master);
 251        struct device *dev = hspi->dev;
 252
 253        dev_dbg(dev, "%s cleanup\n", spi->modalias);
 254}
 255
 256static int hspi_probe(struct platform_device *pdev)
 257{
 258        struct resource *res;
 259        struct spi_master *master;
 260        struct hspi_priv *hspi;
 261        struct clk *clk;
 262        int ret;
 263
 264        /* get base addr */
 265        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 266        if (!res) {
 267                dev_err(&pdev->dev, "invalid resource\n");
 268                return -EINVAL;
 269        }
 270
 271        master = spi_alloc_master(&pdev->dev, sizeof(*hspi));
 272        if (!master) {
 273                dev_err(&pdev->dev, "spi_alloc_master error.\n");
 274                return -ENOMEM;
 275        }
 276
 277        clk = clk_get(NULL, "shyway_clk");
 278        if (IS_ERR(clk)) {
 279                dev_err(&pdev->dev, "shyway_clk is required\n");
 280                ret = -EINVAL;
 281                goto error0;
 282        }
 283
 284        hspi = spi_master_get_devdata(master);
 285        platform_set_drvdata(pdev, hspi);
 286
 287        /* init hspi */
 288        hspi->master    = master;
 289        hspi->dev       = &pdev->dev;
 290        hspi->clk       = clk;
 291        hspi->addr      = devm_ioremap(hspi->dev,
 292                                       res->start, resource_size(res));
 293        if (!hspi->addr) {
 294                dev_err(&pdev->dev, "ioremap error.\n");
 295                ret = -ENOMEM;
 296                goto error1;
 297        }
 298
 299        pm_runtime_enable(&pdev->dev);
 300
 301        master->num_chipselect  = 1;
 302        master->bus_num         = pdev->id;
 303        master->setup           = hspi_setup;
 304        master->cleanup         = hspi_cleanup;
 305        master->mode_bits       = SPI_CPOL | SPI_CPHA;
 306        master->auto_runtime_pm = true;
 307        master->transfer_one_message            = hspi_transfer_one_message;
 308        ret = spi_register_master(master);
 309        if (ret < 0) {
 310                dev_err(&pdev->dev, "spi_register_master error.\n");
 311                goto error1;
 312        }
 313
 314        return 0;
 315
 316 error1:
 317        clk_put(clk);
 318 error0:
 319        spi_master_put(master);
 320
 321        return ret;
 322}
 323
 324static int hspi_remove(struct platform_device *pdev)
 325{
 326        struct hspi_priv *hspi = platform_get_drvdata(pdev);
 327
 328        pm_runtime_disable(&pdev->dev);
 329
 330        clk_put(hspi->clk);
 331        spi_unregister_master(hspi->master);
 332
 333        return 0;
 334}
 335
 336static struct platform_driver hspi_driver = {
 337        .probe = hspi_probe,
 338        .remove = hspi_remove,
 339        .driver = {
 340                .name = "sh-hspi",
 341                .owner = THIS_MODULE,
 342        },
 343};
 344module_platform_driver(hspi_driver);
 345
 346MODULE_DESCRIPTION("SuperH HSPI bus driver");
 347MODULE_LICENSE("GPL");
 348MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
 349MODULE_ALIAS("platform:sh_spi");
 350
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.