home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / drivers / char / atari_SCC.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  14.5 KB  |  541 lines

  1.  
  2.  
  3. /*
  4.  * atari_SCC.h: Definitions for the Am8530 Serial Communcications Controller
  5.  *
  6.  * Copyright 1994 Roman Hodek
  7.  *   EMail: rnhodek@cip.informatik.uni-erlangen.de (Internet)
  8.  *      or: Roman_Hodek@n.maus.de (MausNet, NO mail > 16 KB!)
  9.  *
  10.  * This file is subject to the terms and conditions of the GNU General Public
  11.  * License.  See the file README.legal in the main directory of this archive
  12.  * for more details.
  13.  *
  14.  */
  15.  
  16.  
  17. #ifndef _ATARI_SCC_H
  18. #define _ATARI_SCC_H
  19.  
  20. #include <linux/atarihw.h>
  21. #include "atari_serial.h"
  22.  
  23. /***********************************************************************/
  24. /*                                                                     */
  25. /*                             Register Names                          */
  26. /*                                                                     */
  27. /***********************************************************************/
  28.  
  29. /* The SCC documentation gives no explicit names to the registers,
  30.  * they're just called WR0..15 and RR0..15. To make the source code
  31.  * better readable and make the transparent write reg read access (see
  32.  * below) possible, I christen them here with self-invented names.
  33.  * Note that (real) read registers are assigned numbers 16..31. WR7'
  34.  * has number 33.
  35.  */
  36.  
  37. #define    COMMAND_REG            0    /* wo */
  38. #define    INT_AND_DMA_REG        1    /* wo */
  39. #define    INT_VECTOR_REG        2    /* rw, common to both channels */
  40. #define    RX_CTRL_REG            3    /* rw */
  41. #define    AUX1_CTRL_REG        4    /* rw */
  42. #define    TX_CTRL_REG            5    /* rw */
  43. #define    SYNC_ADR_REG        6    /* wo */
  44. #define    SYNC_CHAR_REG        7    /* wo */
  45. #define    SDLC_OPTION_REG        33    /* wo */
  46. #define    TX_DATA_REG            8    /* wo */
  47. #define    MASTER_INT_CTRL        9    /* wo, common to both channels */
  48. #define    AUX2_CTRL_REG        10    /* rw */
  49. #define    CLK_CTRL_REG        11    /* wo */
  50. #define    TIMER_LOW_REG        12    /* rw */
  51. #define    TIMER_HIGH_REG        13    /* rw */
  52. #define    DPLL_CTRL_REG        14    /* wo */
  53. #define    INT_CTRL_REG        15    /* rw */
  54.  
  55. #define    STATUS_REG            16    /* ro */
  56. #define    SPCOND_STATUS_REG    17    /* wo */
  57. /* RR2 is WR2 for Channel A, Channel B gives vector + current status: */
  58. #define    CURR_VECTOR_REG        18    /* Ch. B only, Ch. A for rw */
  59. #define    INT_PENDING_REG        19    /* Channel A only! */
  60. /* RR4 is WR4, if b6(MR7') == 1 */
  61. /* RR5 is WR5, if b6(MR7') == 1 */
  62. #define    FS_FIFO_LOW_REG        22    /* ro */
  63. #define    FS_FIFO_HIGH_REG    23    /* ro */
  64. #define    RX_DATA_REG            24    /* ro */
  65. /* RR9 is WR3, if b6(MR7') == 1 */
  66. #define    DPLL_STATUS_REG        26    /* ro */
  67. /* RR11 is WR10, if b6(MR7') == 1 */
  68. /* RR12 is WR12 */
  69. /* RR13 is WR13 */
  70. /* RR14 not present */
  71. /* RR15 is WR15 */
  72.  
  73.  
  74. /***********************************************************************/
  75. /*                                                                     */
  76. /*                             Register Values                         */
  77. /*                                                                     */
  78. /***********************************************************************/
  79.  
  80.  
  81. /* WR0: COMMAND_REG "CR" */
  82.  
  83. #define    CR_RX_CRC_RESET            0x40
  84. #define    CR_TX_CRC_RESET            0x80
  85. #define    CR_TX_UNDERRUN_RESET    0xc0
  86.  
  87. #define    CR_EXTSTAT_RESET        0x10
  88. #define    CR_SEND_ABORT            0x18
  89. #define    CR_ENAB_INT_NEXT_RX        0x20
  90. #define    CR_TX_PENDING_RESET        0x28
  91. #define    CR_ERROR_RESET            0x30
  92. #define    CR_HIGHEST_IUS_RESET    0x38
  93.  
  94.  
  95. /* WR1: INT_AND_DMA_REG "IDR" */
  96.  
  97. #define    IDR_EXTSTAT_INT_ENAB    0x01
  98. #define    IDR_TX_INT_ENAB            0x02
  99. #define    IDR_PARERR_AS_SPCOND    0x04
  100.  
  101. #define    IDR_RX_INT_DISAB        0x00
  102. #define    IDR_RX_INT_FIRST        0x08
  103. #define    IDR_RX_INT_ALL            0x10
  104. #define    IDR_RX_INT_SPCOND        0x18
  105.  
  106. #define    IDR_WAITREQ_RX            0x20
  107. #define    IDR_WAITREQ_IS_REQ        0x40
  108. #define    IDR_WAITREQ_ENAB        0x80
  109.  
  110.  
  111. /* WR3: RX_CTRL_REG "RCR" */
  112.  
  113. #define    RCR_RX_ENAB                0x01
  114. #define    RCR_DISCARD_SYNC_CHARS    0x02
  115. #define    RCR_ADDR_SEARCH            0x04
  116. #define    RCR_CRC_ENAB            0x08
  117. #define    RCR_SEARCH_MODE            0x10
  118. #define    RCR_AUTO_ENAB_MODE        0x20
  119.  
  120. #define    RCR_CHSIZE_MASK            0xc0
  121. #define    RCR_CHSIZE_5            0x00
  122. #define    RCR_CHSIZE_6            0x40
  123. #define    RCR_CHSIZE_7            0x80
  124. #define    RCR_CHSIZE_8            0xc0
  125.  
  126.  
  127. /* WR4: AUX1_CTRL_REG "A1CR" */
  128.  
  129. #define    A1CR_PARITY_NONE        0x00
  130. #define    A1CR_PARITY_ODD            0x01
  131. #define    A1CR_PARITY_EVEN        0x03
  132.  
  133. #define    A1CR_MODE_MASK            0x0c
  134. #define    A1CR_MODE_SYNCR            0x00
  135. #define    A1CR_MODE_ASNYC_1        0x04
  136. #define    A1CR_MODE_ASNYC_15        0x08
  137. #define    A1CR_MODE_ASNYC_2        0x0c
  138.  
  139. #define    A1CR_SYNCR_MODE_MASK    0x30
  140. #define    A1CR_SYNCR_MONOSYNC        0x00
  141. #define    A1CR_SYNCR_BISYNC        0x10
  142. #define    A1CR_SYNCR_SDLC            0x20
  143. #define    A1CR_SYNCR_EXTCSYNC        0x30
  144.  
  145. #define    A1CR_CLKMODE_MASK        0xc0
  146. #define    A1CR_CLKMODE_x1            0x00
  147. #define    A1CR_CLKMODE_x16        0x40
  148. #define    A1CR_CLKMODE_x32        0x80
  149. #define    A1CR_CLKMODE_x64        0xc0
  150.  
  151.  
  152. /* WR5: TX_CTRL_REG "TCR" */
  153.  
  154. #define    TCR_TX_CRC_ENAB            0x01
  155. #define    TCR_RTS                    0x02
  156. #define    TCR_USE_CRC_CCITT        0x00
  157. #define    TCR_USE_CRC_16            0x04
  158. #define    TCR_TX_ENAB                0x08
  159. #define    TCR_SEND_BREAK            0x10
  160.  
  161. #define    TCR_CHSIZE_MASK            0x60
  162. #define    TCR_CHSIZE_5            0x00
  163. #define    TCR_CHSIZE_6            0x20
  164. #define    TCR_CHSIZE_7            0x40
  165. #define    TCR_CHSIZE_8            0x60
  166.  
  167. #define    TCR_DTR                    0x80
  168.  
  169.  
  170. /* WR7': SLDC_OPTION_REG "SOR" */
  171.  
  172. #define    SOR_AUTO_TX_ENAB        0x01
  173. #define    SOR_AUTO_EOM_RESET        0x02
  174. #define    SOR_AUTO_RTS_MODE        0x04
  175. #define    SOR_NRZI_DISAB_HIGH        0x08
  176. #define    SOR_ALT_DTRREQ_TIMING    0x10
  177. #define    SOR_READ_CRC_CHARS        0x20
  178. #define    SOR_EXTENDED_REG_ACCESS    0x40
  179.  
  180.  
  181. /* WR9: MASTER_INT_CTRL "MIC" */
  182.  
  183. #define    MIC_VEC_INCL_STAT        0x01
  184. #define    MIC_NO_VECTOR            0x02
  185. #define    MIC_DISAB_LOWER_CHAIN    0x04
  186. #define    MIC_MASTER_INT_ENAB        0x08
  187. #define    MIC_STATUS_HIGH            0x10
  188. #define    MIC_IGN_INTACK            0x20
  189.  
  190. #define    MIC_NO_RESET            0x00
  191. #define    MIC_CH_A_RESET            0x40
  192. #define    MIC_CH_B_RESET            0x80
  193. #define    MIC_HARD_RESET            0xc0
  194.  
  195.  
  196. /* WR10: AUX2_CTRL_REG "A2CR" */
  197.  
  198. #define    A2CR_SYNC_6                0x01
  199. #define    A2CR_LOOP_MODE            0x02
  200. #define    A2CR_ABORT_ON_UNDERRUN    0x04
  201. #define    A2CR_MARK_IDLE            0x08
  202. #define    A2CR_GO_ACTIVE_ON_POLL    0x10
  203.  
  204. #define    A2CR_CODING_MASK        0x60
  205. #define    A2CR_CODING_NRZ            0x00
  206. #define    A2CR_CODING_NRZI        0x20
  207. #define    A2CR_CODING_FM1            0x40
  208. #define    A2CR_CODING_FM0            0x60
  209.  
  210. #define    A2CR_PRESET_CRC_1        0x80
  211.  
  212.  
  213. /* WR11: CLK_CTRL_REG "CCR" */
  214.  
  215. #define    CCR_TRxCOUT_MASK        0x03
  216. #define    CCR_TRxCOUT_XTAL        0x00
  217. #define    CCR_TRxCOUT_TXCLK        0x01
  218. #define    CCR_TRxCOUT_BRG            0x02
  219. #define    CCR_TRxCOUT_DPLL        0x03
  220.  
  221. #define    CCR_TRxC_OUTPUT            0x04
  222.  
  223. #define    CCR_TXCLK_MASK            0x18
  224. #define    CCR_TXCLK_RTxC            0x00
  225. #define    CCR_TXCLK_TRxC            0x08
  226. #define    CCR_TXCLK_BRG            0x10
  227. #define    CCR_TXCLK_DPLL            0x18
  228.  
  229. #define    CCR_RXCLK_MASK            0x60
  230. #define    CCR_RXCLK_RTxC            0x00
  231. #define    CCR_RXCLK_TRxC            0x20
  232. #define    CCR_RXCLK_BRG            0x40
  233. #define    CCR_RXCLK_DPLL            0x60
  234.  
  235. #define    CCR_RTxC_XTAL            0x80
  236.  
  237.  
  238. /* WR14: DPLL_CTRL_REG "DCR" */
  239.  
  240. #define    DCR_BRG_ENAB            0x01
  241. #define    DCR_BRG_USE_PCLK        0x02
  242. #define    DCR_DTRREQ_IS_REQ        0x04
  243. #define    DCR_AUTO_ECHO            0x08
  244. #define    DCR_LOCAL_LOOPBACK        0x10
  245.  
  246. #define    DCR_DPLL_EDGE_SEARCH    0x20
  247. #define    DCR_DPLL_ERR_RESET        0x40
  248. #define    DCR_DPLL_DISAB            0x60
  249. #define    DCR_DPLL_CLK_BRG        0x80
  250. #define    DCR_DPLL_CLK_RTxC        0xa0
  251. #define    DCR_DPLL_FM                0xc0
  252. #define    DCR_DPLL_NRZI            0xe0
  253.  
  254.  
  255. /* WR15: INT_CTRL_REG "ICR" */
  256.  
  257. #define    ICR_OPTIONREG_SELECT    0x01
  258. #define    ICR_ENAB_BRG_ZERO_INT    0x02
  259. #define    ICR_USE_FS_FIFO            0x04
  260. #define    ICR_ENAB_DCD_INT        0x08
  261. #define    ICR_ENAB_SYNC_INT        0x10
  262. #define    ICR_ENAB_CTS_INT        0x20
  263. #define    ICR_ENAB_UNDERRUN_INT    0x40
  264. #define    ICR_ENAB_BREAK_INT        0x80
  265.  
  266.  
  267. /* RR0: STATUS_REG "SR" */
  268.  
  269. #define    SR_CHAR_AVAIL            0x01
  270. #define    SR_BRG_ZERO                0x02
  271. #define    SR_TX_BUF_EMPTY            0x04
  272. #define    SR_DCD                    0x08
  273. #define    SR_SYNC_ABORT            0x10
  274. #define    SR_CTS                    0x20
  275. #define    SR_TX_UNDERRUN            0x40
  276. #define    SR_BREAK                0x80
  277.  
  278.  
  279. /* RR1: SPCOND_STATUS_REG "SCSR" */
  280.  
  281. #define    SCSR_ALL_SENT            0x01
  282. #define    SCSR_RESIDUAL_MASK        0x0e
  283. #define    SCSR_PARITY_ERR            0x10
  284. #define    SCSR_RX_OVERRUN            0x20
  285. #define    SCSR_CRC_FRAME_ERR        0x40
  286. #define    SCSR_END_OF_FRAME        0x80
  287.  
  288.  
  289. /* RR3: INT_PENDING_REG "IPR" */
  290.  
  291. #define    IPR_B_EXTSTAT            0x01
  292. #define    IPR_B_TX                0x02
  293. #define    IPR_B_RX                0x04
  294. #define    IPR_A_EXTSTAT            0x08
  295. #define    IPR_A_TX                0x10
  296. #define    IPR_A_RX                0x20
  297.  
  298.  
  299. /* RR7: FS_FIFO_HIGH_REG "FFHR" */
  300.  
  301. #define    FFHR_CNT_MASK            0x3f
  302. #define    FFHR_IS_FROM_FIFO        0x40
  303. #define    FFHR_FIFO_OVERRUN        0x80
  304.  
  305.  
  306. /* RR10: DPLL_STATUS_REG "DSR" */
  307.  
  308. #define    DSR_ON_LOOP                0x02
  309. #define    DSR_ON_LOOP_SENDING        0x10
  310. #define    DSR_TWO_CLK_MISSING        0x40
  311. #define    DSR_ONE_CLK_MISSING        0x80
  312.  
  313.  
  314.  
  315. /***************************** Prototypes *****************************/
  316.  
  317. void atari_init_SCC( struct async_struct *info, SERTYPE type, int tt_flag,
  318.                      void *ri_addr, unsigned char ri_bitno, unsigned char
  319.                      ri_active );
  320.  
  321. /************************* End of Prototypes **************************/
  322.  
  323.  
  324.  
  325.  
  326. /***********************************************************************/
  327. /*                                                                     */
  328. /*                             Register Access                         */
  329. /*                                                                     */
  330. /***********************************************************************/
  331.  
  332.  
  333. /* The SCC needs 3.5 PCLK cycles recovery time between to register
  334.  * accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 *
  335.  * 125 ns = 437.5 ns. Since this is too short for udelay(), it is
  336.  * implemented by some nop's. I think that a nop needs 4 cycles (but
  337.  * I'm not sure, correct me please!), that gives 4 nops for a TT (32
  338.  * MHz) (2 would be sufficient for the Falcon (16 MHz), but looking at
  339.  * boot_info.bi_atari.model at runtime takes longer than 2 nop's...)
  340.  */
  341.  
  342. static __inline__ void scc_reg_delay( void )
  343.  
  344. {
  345.     __asm__ __volatile__ ( "nop; nop; nop; nop" );
  346. }
  347.  
  348. /* Another version with only 3 nop's for cases when some other
  349.  * statement intervenes between the two SCC accesses
  350.  */
  351.  
  352. static __inline__ void scc_reg3_delay( void )
  353.  
  354. {
  355.     __asm__ __volatile__ ( "nop; nop; nop" );
  356. }
  357.  
  358.  
  359. struct PARTIAL_SCC {        /* just one channel */
  360.     unsigned char    ctrl;
  361.     unsigned char    dummy;
  362.     unsigned char    data;
  363. };
  364.  
  365.  
  366. extern unsigned char    SCC_shadow[16];
  367.  
  368.  
  369. /* The following functions should relax the somehow complicated
  370.  * register access of the SCC. _SCCwrite() stores all written values
  371.  * (except for WR0 and WR8) in shadow registers for later recall. This
  372.  * removes the burden of remembering written values as needed. The
  373.  * extra work of storing the value doesn't count, since a delay is
  374.  * needed after a SCC access anyway. Additionally, _SCCwrite() manages
  375.  * writes to WR0 and WR8 differently, because these can be accessed
  376.  * directly with less overhead. Another special case are WR7 and WR7'.
  377.  * _SCCwrite automatically checks what of this registers is selected
  378.  * and changes b0 of WR15 if needed.
  379.  * 
  380.  * _SCCread() for standard read registers is straightforward, except
  381.  * for RR2 (split into two "virtual" registers: one for the value
  382.  * written to WR2 (from the shadow) and one for the vector including
  383.  * status from RR2, Ch. B) and RR3. The latter must be read from
  384.  * Channel A, because it reads as all zeros on Ch. B. RR0 and RR8 can
  385.  * be accessed directly as before.
  386.  * 
  387.  * The two inline function contain complicated switch statements. But
  388.  * I rely on regno and final_delay being constants, so gcc can reduce
  389.  * the whole stuff to just some assembler statements.
  390.  * 
  391.  * _SCCwrite and _SCCread aren't intended to be used directly under
  392.  * normal circumstances. The macros SCCread[_ND] and SCCwrite[_ND] are
  393.  * for that purpose. They assume that a local variable 'info' is
  394.  * declared and pointing to the port's async_struct entry. The
  395.  * variants with "_NB" appended should be used if no other SCC
  396.  * accesses follow immediatly (within 0.5 usecs). They just skip the
  397.  * final delay nops.
  398.  * 
  399.  * Please note that accesses to SCC registers should only take place
  400.  * when interrupts are turned off (at least if SCC interrupts are
  401.  * enabled). Otherwise, an interrupt could interfere with the
  402.  * two-stage accessing process.
  403.  *
  404.  */
  405.  
  406. static __inline__ void _SCCwrite( struct async_struct *info, int regno,
  407.                                   unsigned char val, int final_delay )
  408.  
  409. {
  410.     volatile struct PARTIAL_SCC *sc =
  411.         (volatile struct PARTIAL_SCC *)(info->base);
  412.  
  413.     switch( regno ) {
  414.  
  415.       case COMMAND_REG:
  416.         /* WR0 can be written directly without pointing */
  417.         sc->ctrl = val;
  418.         break;
  419.  
  420.       case SYNC_CHAR_REG:
  421.         /* For WR7, first set b0 of WR15 to 0, if needed */
  422.         if (SCC_shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT) {
  423.             sc->ctrl = 15;
  424.             SCC_shadow[INT_CTRL_REG] &= ~ICR_OPTIONREG_SELECT;
  425.             scc_reg3_delay();
  426.             sc->ctrl = SCC_shadow[INT_CTRL_REG];
  427.             scc_reg_delay();
  428.         }
  429.         goto normal_case;
  430.         
  431.       case SDLC_OPTION_REG:
  432.         /* For WR7', first set b0 of WR15 to 1, if needed */
  433.         if (!(SCC_shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT)) {
  434.             sc->ctrl = 15;
  435.             SCC_shadow[INT_CTRL_REG] |= ICR_OPTIONREG_SELECT;
  436.             scc_reg3_delay();
  437.             sc->ctrl = SCC_shadow[INT_CTRL_REG];
  438.             scc_reg_delay();
  439.         }
  440.         sc->ctrl = 7;
  441.         SCC_shadow[8] = val;    /* WR7' shadowed at WR8 */
  442.         scc_reg3_delay();
  443.         sc->ctrl = val;
  444.         break;
  445.  
  446.       case TX_DATA_REG:        /* WR8 */
  447.         /* TX_DATA_REG can be accessed directly */
  448.         sc->data = val;
  449.         break;
  450.  
  451.       case 1 ... 6:    
  452.       case 9 ... 15:
  453.       normal_case:
  454.         sc->ctrl = regno;
  455.         SCC_shadow[regno] = val;
  456.         scc_reg3_delay();
  457.         sc->ctrl = val;
  458.         break;
  459.         
  460.       default:
  461.         printk( "Bad SCC write access to WR%d\n", regno );
  462.         break;
  463.         
  464.     }
  465.  
  466.     if (final_delay)
  467.         scc_reg_delay();
  468. }
  469.  
  470.  
  471. static __inline__ unsigned char _SCCread( struct async_struct *info,
  472.                                           int regno, int final_delay )
  473.  
  474. {    volatile struct PARTIAL_SCC *sc =
  475.         (volatile struct PARTIAL_SCC *)info->base;
  476.     unsigned char rv;
  477.     
  478.     switch( regno ) {
  479.  
  480.         /* --- real read registers --- */
  481.       case STATUS_REG:
  482.         rv = sc->ctrl;
  483.         break;
  484.  
  485.       case SPCOND_STATUS_REG:
  486.       case FS_FIFO_LOW_REG:
  487.       case FS_FIFO_HIGH_REG:
  488.       case DPLL_STATUS_REG:
  489.         sc->ctrl = regno & 0x0f;
  490.         scc_reg_delay();
  491.         rv = sc->ctrl;
  492.         break;
  493.         
  494.       case INT_PENDING_REG:
  495.         /* RR3: read only from Channel A! */
  496.         sc->ctrl = regno & 0x0f;
  497.         scc_reg_delay();
  498.         rv = ((volatile struct SCC *)((long)(info->base) & ~4))->cha_a_ctrl;
  499.         break;
  500.  
  501.       case RX_DATA_REG:
  502.         /* RR8 can be accessed directly */
  503.         rv = sc->data;
  504.         break;
  505.  
  506.       case CURR_VECTOR_REG:
  507.         /* RR2 (vector including status) from Ch. B */
  508.         sc->ctrl = regno & 0x0f;
  509.         scc_reg_delay();
  510.         rv = ((volatile struct SCC *)((long)info->base & ~4))->cha_b_ctrl;
  511.         break;
  512.         
  513.         /* --- reading write registers: access the shadow --- */
  514.       case 1 ... 7:
  515.       case 9 ... 15:
  516.         return( SCC_shadow[regno] ); /* no final delay! */
  517.  
  518.         /* WR7' is special, because it is shadowed at the place of WR8 */
  519.       case SDLC_OPTION_REG:
  520.         return( SCC_shadow[8] ); /* no final delay! */
  521.  
  522.       default:
  523.         printk( "Bad SCC read access to %cR%d\n", (regno & 16) ? 'R' : 'W',
  524.                 regno & ~16 );
  525.         break;
  526.         
  527.     }
  528.  
  529.     if (final_delay)
  530.         scc_reg_delay();
  531. }
  532.  
  533.  
  534. #define    SCCwrite(reg,val)        _SCCwrite( info, (reg), (val), 1 )
  535. #define    SCCwrite_NB(reg,val)    _SCCwrite( info, (reg), (val), 0 )
  536. #define    SCCread(reg)            _SCCread( info, (reg), 1 )
  537. #define    SCCread_NB(reg)            _SCCread( info, (reg), 0 )
  538.  
  539.  
  540. #endif /* _ATARI_SCC_H */
  541.