root/drivers/video/fbdev/mmp/hw/mmp_spi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lcd_spi_write
  2. lcd_spi_setup
  3. lcd_spi_one_transfer
  4. lcd_spi_register

   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  * @data: can be 8/16/32-bit, MSB justified data to write.
  21  * @len:  data length.
  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  */
  30 static inline int lcd_spi_write(struct spi_device *spi, u32 data)
  31 {
  32         int timeout = 100000, isr, ret = 0;
  33         u32 tmp;
  34         void *reg_base =
  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 
  81 static int lcd_spi_setup(struct spi_device *spi)
  82 {
  83         void *reg_base =
  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 
 107 static 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 
 137 int 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 = 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 }

/* [<][>][^][v][top][bottom][index][help] */