linux/drivers/spi/spi-davinci.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2009 Texas Instruments.
   3 * Copyright (C) 2010 EF Johnson Technologies
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 */
  19
  20#include <linux/interrupt.h>
  21#include <linux/io.h>
  22#include <linux/gpio.h>
  23#include <linux/module.h>
  24#include <linux/delay.h>
  25#include <linux/platform_device.h>
  26#include <linux/err.h>
  27#include <linux/clk.h>
  28#include <linux/dma-mapping.h>
  29#include <linux/spi/spi.h>
  30#include <linux/spi/spi_bitbang.h>
  31#include <linux/slab.h>
  32
  33#include <mach/spi.h>
  34#include <mach/edma.h>
  35
  36#define SPI_NO_RESOURCE         ((resource_size_t)-1)
  37
  38#define SPI_MAX_CHIPSELECT      2
  39
  40#define CS_DEFAULT      0xFF
  41
  42#define SPIFMT_PHASE_MASK       BIT(16)
  43#define SPIFMT_POLARITY_MASK    BIT(17)
  44#define SPIFMT_DISTIMER_MASK    BIT(18)
  45#define SPIFMT_SHIFTDIR_MASK    BIT(20)
  46#define SPIFMT_WAITENA_MASK     BIT(21)
  47#define SPIFMT_PARITYENA_MASK   BIT(22)
  48#define SPIFMT_ODD_PARITY_MASK  BIT(23)
  49#define SPIFMT_WDELAY_MASK      0x3f000000u
  50#define SPIFMT_WDELAY_SHIFT     24
  51#define SPIFMT_PRESCALE_SHIFT   8
  52
  53/* SPIPC0 */
  54#define SPIPC0_DIFUN_MASK       BIT(11)         /* MISO */
  55#define SPIPC0_DOFUN_MASK       BIT(10)         /* MOSI */
  56#define SPIPC0_CLKFUN_MASK      BIT(9)          /* CLK */
  57#define SPIPC0_SPIENA_MASK      BIT(8)          /* nREADY */
  58
  59#define SPIINT_MASKALL          0x0101035F
  60#define SPIINT_MASKINT          0x0000015F
  61#define SPI_INTLVL_1            0x000001FF
  62#define SPI_INTLVL_0            0x00000000
  63
  64/* SPIDAT1 (upper 16 bit defines) */
  65#define SPIDAT1_CSHOLD_MASK     BIT(12)
  66
  67/* SPIGCR1 */
  68#define SPIGCR1_CLKMOD_MASK     BIT(1)
  69#define SPIGCR1_MASTER_MASK     BIT(0)
  70#define SPIGCR1_POWERDOWN_MASK  BIT(8)
  71#define SPIGCR1_LOOPBACK_MASK   BIT(16)
  72#define SPIGCR1_SPIENA_MASK     BIT(24)
  73
  74/* SPIBUF */
  75#define SPIBUF_TXFULL_MASK      BIT(29)
  76#define SPIBUF_RXEMPTY_MASK     BIT(31)
  77
  78/* SPIDELAY */
  79#define SPIDELAY_C2TDELAY_SHIFT 24
  80#define SPIDELAY_C2TDELAY_MASK  (0xFF << SPIDELAY_C2TDELAY_SHIFT)
  81#define SPIDELAY_T2CDELAY_SHIFT 16
  82#define SPIDELAY_T2CDELAY_MASK  (0xFF << SPIDELAY_T2CDELAY_SHIFT)
  83#define SPIDELAY_T2EDELAY_SHIFT 8
  84#define SPIDELAY_T2EDELAY_MASK  (0xFF << SPIDELAY_T2EDELAY_SHIFT)
  85#define SPIDELAY_C2EDELAY_SHIFT 0
  86#define SPIDELAY_C2EDELAY_MASK  0xFF
  87
  88/* Error Masks */
  89#define SPIFLG_DLEN_ERR_MASK            BIT(0)
  90#define SPIFLG_TIMEOUT_MASK             BIT(1)
  91#define SPIFLG_PARERR_MASK              BIT(2)
  92#define SPIFLG_DESYNC_MASK              BIT(3)
  93#define SPIFLG_BITERR_MASK              BIT(4)
  94#define SPIFLG_OVRRUN_MASK              BIT(6)
  95#define SPIFLG_BUF_INIT_ACTIVE_MASK     BIT(24)
  96#define SPIFLG_ERROR_MASK               (SPIFLG_DLEN_ERR_MASK \
  97                                | SPIFLG_TIMEOUT_MASK | SPIFLG_PARERR_MASK \
  98                                | SPIFLG_DESYNC_MASK | SPIFLG_BITERR_MASK \
  99                                | SPIFLG_OVRRUN_MASK)
 100
 101#define SPIINT_DMA_REQ_EN       BIT(16)
 102
 103/* SPI Controller registers */
 104#define SPIGCR0         0x00
 105#define SPIGCR1         0x04
 106#define SPIINT          0x08
 107#define SPILVL          0x0c
 108#define SPIFLG          0x10
 109#define SPIPC0          0x14
 110#define SPIDAT1         0x3c
 111#define SPIBUF          0x40
 112#define SPIDELAY        0x48
 113#define SPIDEF          0x4c
 114#define SPIFMT0         0x50
 115
 116/* We have 2 DMA channels per CS, one for RX and one for TX */
 117struct davinci_spi_dma {
 118        int                     tx_channel;
 119        int                     rx_channel;
 120        int                     dummy_param_slot;
 121        enum dma_event_q        eventq;
 122};
 123
  74/* SPI Controlef="dr' thiivate data.r TX */
  25struct davinci_dma {
  26    struct resource_size_t               32          32                       33    struct };
  34a>};
  35    const void /a>          *uct };
davinci_spi_dma};
davinci_nux/platfoata  33<*uct   44    void                    (*uct   32<    struct davinci_dma<*)/a>};
  32                 (*uct davinci_dma<*)/a>};
SPI_MAX_CHIPSELECT]/a>};
  48};
  50../.st struct davinci_sefault_cft_dma" class="srode=davinci_sefault_cft  33/a>};
  52../.st void     BIT<   (  32<    davinci_dma<*uct   53/a> {
  59}a>};
  61../.st void      116<   (  32<    davinci_dma<*uct   62/a> {
 116<*uct  116)      68}a>};
  32<    BIT<struct davinci_dma<*uct   71/a> {
  32<        }a>};
  66
  32<     116<struct davinci_dma<*uct   62/a> {
  32<     116<*uct   9 }a>};
  32<      53/a> {
  32<     115
  68}a>};
  19
  32<      71/a> {
  32<     108}a>};
  87
  88 108 118  61../.st void       62/a> {
  33    struct davinci_dma<*uct davinci_nux/platfoata  33<*uct  116ruct CS_DEFAUL3/a>};
 119   *uct   33                               (SPERN_CESFMT0" class="sref">SPERN_CE> 11aa>(1)
                 115
  26   8  67  88 108  32                          33           elas/a>};
  35   } elas) {
  97                   ruct SPIDAT1_CSHOLD_MAS)/a>};
SPe  9 +=2*)/a>};
  34a>};

 116davincirgetprescale - Calculates the correct prescale valud>  */
  67/*clock ca>  */
  88 108 118
  58/*ller regiTX */
 103not be urpoaed.TX */

davincirgetprescalea_dma" class="sref">davincirgetprescale> 116<struct davinci_dma<*uct   32<      19
  33            it="re-   |   34a>};
 108}a>};
  87
  88 108davincisit=p_transfer - This funcetves will deregmss=dtransfer methodTX */
 118

  58 103/*Clock  SPI Co*ller reg according toTX */
/*sl We _srm_d freq.TX */
 116  50../.st    <   (davincisit=p_transfera_dma" class="sref">davincisit=p_transfer> 116<struct davinci_dma<*uct   32<     115
  32                  33           <     115
  26   8  19


  58 103BI3/a>};
BI3/a>};
 113/a>};
 113/a>};
  33            it="re-   |   34a>};
  87
/FMTn*ller reg, unique to this chipselect. * TX */
  19
davincirgetprescale> 116       32            it="ret      32        /FMT_PRESCALE_SHIFSELECT" class="srefFMT_PRESCALE_SHIFS> 11a)|fa*uct  115
  26    ifa*uct /_LSB_FIRSSELECT" class="sref"LSB_FIRSS> 11aa>(1)
/_CPOSPILVL" class="s">/_CPOS> 11aa>(1)
/_CPHAPILVL" class="s">/_CPHA> 11aaa>(1)
  33            uct   34a>};
  35   8 116/*mf="s:TX */
  67/*mf=" uses 4 pins, with chipselectf  */
  88/*is a*4 pin variant without CS (">/_NO_CS)f  */
 108/_3WIRE, with just onee datdwire;f  */
 118
  58
 103
/*variant is standard ">/*plus ">/_READYTX */
/_READY)|f">/_NO_CS)f  */
 116  87
 119  =ruct  11a) {
  19
  32<      32                /FMT_WDELAY_SHIFSELECT" class="srefFMT_WDELAY_SHIFS> 11aa>(1)
  33                                                    amp;8< /FMT_WDELAY_HOLD_MASK" class="srefFMT_WDELAY_HOLD> 11a3/a>};
  34a>};
  87
  32                          33           } elas) {
/DELAY_C2TDELAY_SHIFSELECT" class="srefDELAY_C2TDELAY_SHIFS> 11aa>(1)
/DELAY_C2TDELAY_HOLD_MASK" class="sref"ELAY_C2TDELAY_HOLD> 113/a>};
/DELAY_T2CDELAY_SHIFSELECT" class="srefDELAY_T2CDELAY_SHIFS> 11aa>(1)
  97                                            amp;8< /DELAY_T2CDELAY_HOLD_MASK" class="sref"ELAY_T2CDELAY_HOLD> 113/a>};
  19
/_READY="L32" class="sref"READYTX11a) {
  32                        /DELAY_T2EDELAY_SHIFSELECT" class="srefDELAY_T2EDELAY_SHIFS> 11aa>(1)
  33                                            amp;8< /DELAY_T2EDELAY_HOLD_MASK" class="sref"ELAY_T2EDELAY_HOLD> 113/a>};
/DELAY_C2EDELAY_SHIFSELECT" class="srefDELAY_C2EDELAY_SHIFS> 11aa>(1)
/DELAY_C2EDELAY_HOLD_MASK" class="sref"ELAY_C2EDELAY_HOLD> 113/a>};
  87
 11a3/a>};
 119   8}a>};
};
 115
 116  67davincisit=p - This funcetves will site_sefaul transfer methodTX */
  88
 108
 118
  30../.st    <   (davincisit=pi_dma" class="sref">davincisit=p> 116<struct   3 {
davinci_dma<*uct   26    struct   87
 119   *uct 
  33            uct   34a>};
/_NO_CS="L32" class="sref"NO_CSa  3aa) {
 {
  19
/_READY="L32" class="sref"READYTX11a1
  33           ruct   34a>};
/_LOOPize_t" class="s">/_LOOPTX11a1
  19
davincicheck_er/* a_dma" class="scode=davincicheck_er/* > 116<struct davinci_dma<*uct   3 {
 11)/a>};
  2/a>};
/FLG_TIMEOUTSHOLD_MASK" class="srefFLG_TIMEOUTSHOLDTX11a) {
/*Time-out Er/* \n"TX */};
/FLG_DESYNCSHOLD_MASK" class="srefFLG_DESYNCSHOLDTX11a) {
  32                /*Desynchronizaetve Er/* \n"TX */};
  33            it="re-   | /FLG_BITERRSHOLD_MASK" class="srefFLG_BITERRSHOLDTX11a) {
/*Bit er/* \n"TX */};
  19
 119  =ruct  11a) {
/FLG_DLEN_ERRSHOLD_MASK" class="srefFLG_DLEN_ERRSHOLD> 11a) {
  32                        /*DdatdLength Er/* \n"TX */};
  33                    it="re-   | /FLG_PARERRSHOLD_MASK" class="srefFLG_PARERRSHOLD> 11a) {
/*Parity Er/* \n"TX */};
  97                    it="re-   | /FLG_OVRRUNSHOLD_MASK" class="srefFLG_OVRRUNSHOLD> 11a) {
/*DdatdO="drun er/* \n"TX */};
  32           8}a>};
  33            ifa    (/FLG_BUF_INIT_ACTIVESHOLD_MASK" class="srefFLG_BUF_INIT_ACTIVESHOLD> 11a) {
/*Buffer Init Actf="\n"TX */};
  97   8}a>};
};
  58 103davinciprocess_events - check for and handle any ">/*cSPI Contr eventsTX */


 116
  67
  88  10../.st    <   (davinciprocess_eventsa_dma" class="scode=davinciprocess_events> 116<struct davinci_dma<*uct   32<      33   <      34a>};
/BUF_RXEMPTYSHOLD_MASK" class="srefBUF_RXEMPTYSHOLDa  3*a) {
  97            uct   19
/FLG_ERRORSHOLD_MASK" class="srefFLG_ERRORSHOLDa  3*a) {
  33           ruct /FLG_ERRORSHOLD_MASK" class="srefFLG_ERRORSHOLDa  3)/a>};
  2/a>};
/BUF_TXFULLSHOLD_MASK" class="srefBUF_TXFULLSHOLDa  3*a) {
  32                  34a>};
  26    it="ret      88}a>};
  10../.stvoid <   (davincidma_callbacka_dma" class="scode=davincidma_callback> 116unsigned <   (davinci_dma<*uct   3/a>};
 115
  33    ifa6!<   (};
  2/a>};
  67  88 108
 118
  58 103/*cSPI Contr and then wait ucoil the cSmplettve will be markedTX */
  74
  20../.st    <   (davincibufsa_dma" class="scode=davincibufs> 116<struct davinci_dma<*uct   32<      32<      33    struct };
  2/a>};
 119   *uct   32   *uct  11)/a>};
  3/a>};
  2/a>};
 119   *uct   32   *uct   3/a>};
  2/a>};
};

};
 {
  33           r  32            struct   33           void <*uct  115
  9/a>};
  26   q   <   (
  58 103

 116  67  88 108 118

  33            ifa    (  97                                  33           r<65535, then we needTX */
 116  67  88 108 118  32                
  33           ruct 
  97                   ruct   32                  33           ruct            ruct };
  19
 {
  58 103 116
  67  88 108
 118  32            ifa    (  33                   >uct   97                   ruct   19
 {
  32            ifa    (  33                   >uct };
  97                           8                           >uct   32                  33           ruct };
  32           q   <   (  3/a>};
  97   8}a>};
  26   r {
};
  32   } elas) {
  33           whilefa    (  97                   ruct  {
  3/a>};
 {
  32   }/a>};
  3/a>};
  2/a>};
 {
  88 108 118  32                  33           ruct  116 amp;       33    it="re     };
 115
 116  67  88 108 118  58 103

 116  6static <   (  33*uct   5 <   (  8 {
  32   *uct   33    ifa    ( 115
  97           t    };
  3static  ns3*uct   3 {
  2/a>};
  97   *uct };
  32           goto >uct   33   }/a>};
};
};
  97           goto >uct   26   r   (  32    it="re0)/a>};
  3>uct   9>uct  {
  58 103
 116  67  88 108 118
  3static  ns3*uct   3 {
};
};
  5 <   (  32           goto >uct   33   }/a>};
};
  2/a>};
  97   *uct   32   *uct  11a)/a>};
  33    ifa    (  32   }/a>};
  3/a>};
  97           goto >uct  116 amp;       32    ifa    (  33           goto >uct   97           t      32    ifa    (  33           ruct   9/a>};
  26   r   (  32   *uct };
  2/a>};
  97   *uct };

};
  32    ifa    (  33           ruct };
 {
  32           *uct   33           ruct   97                   goto >uct   32           8            uct   33   }/a>};
  3a)/a>};

  32   *uct };

  97   *uct 
  32           8    ifa<   (
  33                           >uct   2/a>};
uct uct   32   *uct   3/a>};

  97   *uct   2/a>};
  9>uct   32   *uct   97   *uct   3*uct   9/a>};

  2<sure which contains plateform specific poata  */

  3<



  2<  9static int >uct 10..5nt_q   <   (a>};
10.3> 121   >uct 10.">  32   *uct 10.35nt_q   <   (10.64  98   t    10.45nt_/a>};
10.56  98   reourn 0)/a>};
10.76  9}/a>};
10.2>  58
10.9>  9static  s=*uct  {
 {
"inci_spi-da"TX */ {
  32           .>uct   33   },/a> {
  9>uct  116ruct };
};

The original LXR software_by the a>};
LXR ass=unitye  9, this experi="coal ="drion by a>};
lxg@assux.noe  9.
lxg.assux.no kindly hosted by a>}; Redpill Lsspro ASe 9, provideg of Lssux consultinfdand operations serrices si-de 1995.