linux/drivers/video/fbdev/mmp/hw/mmp_spi.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/video/mmp/hw/mmp_spi.c
   3 * using the spi in LCD controler for commands send
   4 *
   5 * Copyright (C) 2012 Marvell Technology Group Ltd.
   6 * Authors:  Guoqing Li <ligq@marvell.com>
   7 *          Lisa Du <cldu@marvell.com>
   8 *          Zhou Zhu <zzhu3@marvell.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify it
  11 * under the terms of the GNU General Public License as published by the
  12 * Free Software Foundation; either version 2 of the License, or (at your
  13 * option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful, but WITHOUT
  16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  18 * more details.
  19 *
  20 * You should have received a copy of the GNU General Public License along with
  21 * this program.  If not, see <http://www.gnu.org/licenses/>.
  22 *
  23 */
  24#include <linux/errno.h>
  25#include <linux/delay.h>
  26#include <linux/err.h>
  27#include <linux/io.h>
  28#include <linux/spi/spi.h>
  29#include "mmp_ctrl.h"
  30
  31/**
  32 * spi_write - write command to the SPI port
  33 * @data: can be 8/16/32-bit, MSB justified data to write.
  34 * @len:  data length.
  35 *
  36 * Wait bus transfer complete IRQ.
  37 * The caller is expected to perform the necessary locking.
  38 *
  39 * Returns:
  40 *   %-ETIMEDOUT        timeout occurred
  41 *   0                  success
  42 */
  43static inline int lcd_spi_write(struct spi_device *spi, u32 data)
  44{
  45        int timeout = 100000, isr, ret = 0;
  46        u32 tmp;
  47        void *reg_base =
  48                *(void **)spi_master_get_devdata(spi->master);
  49
  50        /* clear ISR */
  51        writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
  52
  53        switch (spi->bits_per_word) {
  54        case 8:
  55                writel_relaxed((u8)data, reg_base + LCD_SPU_SPI_TXDATA);
  56                break;
  57        case 16:
  58                writel_relaxed((u16)data, reg_base + LCD_SPU_SPI_TXDATA);
  59                break;
  60        case 32:
  61                writel_relaxed((u32)data, reg_base + LCD_SPU_SPI_TXDATA);
  62                break;
  63        default:
  64                dev_err(&spi->dev, "Wrong spi bit length\n");
  65        }
  66
  67        /* SPI start to send command */
  68        tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
  69        tmp &= ~CFG_SPI_START_MASK;
  70        tmp |= CFG_SPI_START(1);
  71        writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
  72
  73        isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
  74        while (!(isr & SPI_IRQ_ENA_MASK)) {
  75                udelay(100);
  76                isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
  77                if (!--timeout) {
  78                        ret = -ETIMEDOUT;
  79                        dev_err(&spi->dev, "spi cmd send time out\n");
  80                        break;
  81                }
  82        }
  83
  84        tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
  85        tmp &= ~CFG_SPI_START_MASK;
  86        tmp |= CFG_SPI_START(0);
  87        writel_relaxed(tmp, reg_base + LCD_SPU_SPI_CTRL);
  88
  89        writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
  90
  91        return ret;
  92}
  93
  94static int lcd_spi_setup(struct spi_device *spi)
  95{
  96        void *reg_base =
  97                *(void **)spi_master_get_devdata(spi->master);
  98        u32 tmp;
  99
 100        tmp = CFG_SCLKCNT(16) |
 101                CFG_TXBITS(spi->bits_per_word) |
 102                CFG_SPI_SEL(1) | CFG_SPI_ENA(1) |
 103                CFG_SPI_3W4WB(1);
 104        writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
 105
 106        /*
 107         * After set mode it need a time to pull up the spi singals,
 108         * or it would cause the wrong waveform when send spi command,
 109         * especially on pxa910h
 110         */
 111        tmp = readl_relaxed(reg_base + SPU_IOPAD_CONTROL);
 112        if ((tmp & CFG_IOPADMODE_MASK) != IOPAD_DUMB18SPI)
 113                writel_relaxed(IOPAD_DUMB18SPI |
 114                        (tmp & ~CFG_IOPADMODE_MASK),
 115                        reg_base + SPU_IOPAD_CONTROL);
 116        udelay(20);
 117        return 0;
 118}
 119
 120static int lcd_spi_one_transfer(struct spi_device *spi, struct spi_message *m)
 121{
 122        struct spi_transfer *t;
 123        int i;
 124
 125        list_for_each_entry(t, &m->transfers, transfer_list) {
 126                switch (spi->bits_per_word) {
 127                case 8:
 128                        for (i = 0; i < t->len; i++)
 129                                lcd_spi_write(spi, ((u8 *)t->tx_buf)[i]);
 130                        break;
 131                case 16:
 132                        for (i = 0; i < t->len/2; i++)
 133                                lcd_spi_write(spi, ((u16 *)t->tx_buf)[i]);
 134                        break;
 135                case 32:
 136                        for (i = 0; i < t->len/4; i++)
 137                                lcd_spi_write(spi, ((u32 *)t->tx_buf)[i]);
 138                        break;
 139                default:
 140                        dev_err(&spi->dev, "Wrong spi bit length\n");
 141                }
 142        }
 143
 144        m->status = 0;
 145        if (m->complete)
 146                m->complete(m->context);
 147        return 0;
 148}
 149
 150int lcd_spi_register(struct mmphw_ctrl *ctrl)
 151{
 152        struct spi_master *master;
 153        void **p_regbase;
 154        int err;
 155
 156        master = spi_alloc_master(ctrl->dev, sizeof(void *));
 157        if (!master) {
 158                dev_err(ctrl->dev, "unable to allocate SPI master\n");
 159                return -ENOMEM;
 160        }
 161        p_regbase = spi_master_get_devdata(master);
 162        *p_regbase = ctrl->reg_base;
 163
 164        /* set bus num to 5 to avoid conflict with other spi hosts */
 165        master->bus_num = 5;
 166        master->num_chipselect = 1;
 167        master->setup = lcd_spi_setup;
 168        master->transfer = lcd_spi_one_transfer;
 169
 170        err = spi_register_master(master);
 171        if (err < 0) {
 172                dev_err(ctrl->dev, "unable to register SPI master\n");
 173                spi_master_put(master);
 174                return err;
 175        }
 176
 177        dev_info(&master->dev, "registered\n");
 178
 179        return 0;
 180}
 181