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