teb6416_edma_pcm3002.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:11k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /* "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)" */
  9. /* 
  10.  *  ======== teb6416_edma_pcm3002.c ========
  11.  * 
  12.  *  Driver for the pcm3002 codec on the TMS320C6416 teb. Requires the
  13.  *  generic TMS320C6x1x McBSP driver.
  14.  */
  15. #include <std.h>
  16. #include <iom.h>
  17. #include <csl.h>
  18. #include <csl_edma.h>
  19. #include <csl_mcbsp.h>
  20. #include <teb6416_edma_pcm3002.h>
  21. #include <c6x1x_edma_mcbsp.h>
  22. #define GENERICDEVPARAMS {                                                  
  23.     C6X1X_EDMA_MCBSP_VERSION_1,/* Version number of mcbsp driver  */        
  24.     FALSE, /* True if buffers are in cacheable memory (set in mdBindDev) */ 
  25.     FALSE, /* Driver should not enable the McBSP sample rate generator */   
  26.     FALSE, /* Driver should not enable the McBSP frame sync generator */    
  27.     0,     /* IRQ id to use for the EDMA (set in mdBindDev) */              
  28.     NULL,  /* McBSP configuration for the codec (set in mdBindDev) */       
  29.     TEB6416_EDMA_PCM3002_INTR_MASK_DEFAULT /* Interrupt mask */             
  30. }
  31. /* TEB6416 specific pcm3002 #defines */
  32. #define CPLDBASEADDR   0x60000000
  33. #define REGCODECMTRDY  0x80
  34. #define REGACODECL     2                // Codec low byte 
  35. #define REGACODECH     3                // Codec high byte
  36. #define REGAMISC       5                // Misc
  37. /* Structure containing port specific variables */
  38. typedef struct {
  39.         Ptr c6x1xPortObj;
  40.         Int edmaPriority;
  41. } PortObj, *PortHandle;
  42. /* Declare the port structures */
  43. /* Only Mcbsp 0 is used */
  44. static PortObj port;
  45. TEB6416_EDMA_PCM3002_DevParams TEB6416_EDMA_PCM3002_DEVPARAMS =
  46.                                    TEB6416_EDMA_PCM3002_DEFAULT_DEVPARAMS;
  47. /* Local function prototypes */
  48. static Int writeMode(Int modeReg, Int modeVal);
  49. static Int writeCodecMode(Int modeVal);
  50. static Int isCodecReady(Void);
  51. /*
  52.  * Forward declaration of the IOM interface functions. They are only
  53.  * exposed via the IOM function table to avoid namespace pollution.
  54.  */
  55. static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams);
  56. static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
  57.                         Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg);
  58. /*
  59.  * The codec driver function table. Notice how we copy most functions
  60.  * from the generic c6x1x edma mcbsp driver.
  61.  */
  62. IOM_Fxns TEB6416_EDMA_PCM3002_FXNS = {
  63.     &mdBindDev,
  64.     NULL,
  65.     NULL,
  66.     &mdCreateChan,
  67.     NULL,
  68.     NULL
  69. };
  70. /*
  71.  * ======== mdBindDev ========
  72.  * This function allocates and configures the pcm3002 codec.
  73.  */
  74. static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams)
  75. {
  76.     Int result;
  77.     TEB6416_EDMA_PCM3002_DevParams *params =
  78.         (TEB6416_EDMA_PCM3002_DevParams *) devParams;
  79.     C6X1X_EDMA_MCBSP_DevParams genericParams = GENERICDEVPARAMS;
  80.     MCBSP_Config mcbspCfg = {
  81.         MCBSP_FMKS(SPCR, FREE, YES)             |
  82.         MCBSP_FMKS(SPCR, SOFT, NO)              |
  83.         MCBSP_FMKS(SPCR, FRST, YES)             |
  84.         MCBSP_FMKS(SPCR, GRST, YES)             |
  85.         MCBSP_FMKS(SPCR, XINTM, XRDY)           |
  86.         MCBSP_FMKS(SPCR, XSYNCERR, NO)          |
  87.         MCBSP_FMKS(SPCR, XRST, YES)             |
  88.         MCBSP_FMKS(SPCR, DLB, OFF)              |
  89.         MCBSP_FMKS(SPCR, RJUST, RZF)            |
  90.         MCBSP_FMKS(SPCR, CLKSTP, DISABLE)       |
  91.         MCBSP_FMKS(SPCR, DXENA, OFF)            |
  92.         MCBSP_FMKS(SPCR, RINTM, RRDY)           |
  93.         MCBSP_FMKS(SPCR, RSYNCERR, NO)          |
  94.         MCBSP_FMKS(SPCR, RRST, YES),
  95.         MCBSP_FMKS(RCR, RPHASE, SINGLE)         |
  96.         MCBSP_FMKS(RCR, RFRLEN2, OF(0))         |
  97.         MCBSP_FMKS(RCR, RWDLEN2, 8BIT)          |
  98.         MCBSP_FMKS(RCR, RCOMPAND, MSB)          |
  99.         MCBSP_FMKS(RCR, RFIG, NO)               |
  100.         MCBSP_FMKS(RCR, RDATDLY, 0BIT)          |
  101.         MCBSP_FMKS(RCR, RFRLEN1, OF(3))         |
  102.         MCBSP_FMKS(RCR, RWDLEN1, 16BIT)         |
  103.         MCBSP_FMKS(RCR, RWDREVRS, DISABLE),
  104.         MCBSP_FMKS(XCR, XPHASE, SINGLE)         |
  105.         MCBSP_FMKS(XCR, XFRLEN2, OF(0))         |
  106.         MCBSP_FMKS(XCR, XWDLEN2, 8BIT)          |
  107.         MCBSP_FMKS(XCR, XCOMPAND, MSB)          |
  108.         MCBSP_FMKS(XCR, XFIG, NO)               |
  109.         MCBSP_FMKS(XCR, XDATDLY, 0BIT)          |
  110.         MCBSP_FMKS(XCR, XFRLEN1, OF(3))         |
  111.         MCBSP_FMKS(XCR, XWDLEN1, 16BIT)         |
  112.         MCBSP_FMKS(XCR, XWDREVRS, DISABLE),
  113.         MCBSP_SRGR_DEFAULT,
  114.         MCBSP_FMKS(MCR, XMCME, DEFAULT)         |
  115.         MCBSP_FMKS(MCR, XPBBLK, DEFAULT)        |
  116.         MCBSP_FMKS(MCR, XPABLK, DEFAULT)        |
  117.         MCBSP_FMKS(MCR, XCBLK, DEFAULT)         |
  118.         MCBSP_FMKS(MCR, XMCM, DISXP)            |
  119.         MCBSP_FMKS(MCR, RMCME, DEFAULT)         |
  120.         MCBSP_FMKS(MCR, RPBBLK, DEFAULT)        |
  121.         MCBSP_FMKS(MCR, RPABLK, DEFAULT)        |
  122.         MCBSP_FMKS(MCR, RCBLK, DEFAULT)         |
  123.         MCBSP_FMKS(MCR, RMCM, ELDISABLE),
  124.         MCBSP_RCERE0_RCE_OF(0x5),
  125.         MCBSP_RCERE1_DEFAULT,
  126.         MCBSP_RCERE2_DEFAULT,
  127.         MCBSP_RCERE3_DEFAULT,
  128.         MCBSP_XCERE0_XCE_OF(0xa),
  129.         MCBSP_XCERE1_DEFAULT,
  130.         MCBSP_XCERE2_DEFAULT,
  131.         MCBSP_XCERE3_DEFAULT,
  132.         MCBSP_FMKS(PCR, XIOEN, DEFAULT)        |
  133.         MCBSP_FMKS(PCR, RIOEN, DEFAULT)        |
  134.         MCBSP_FMKS(PCR, FSXM, DEFAULT)         |
  135.         MCBSP_FMKS(PCR, FSRM, DEFAULT)         |
  136.         MCBSP_FMKS(PCR, CLKXM, DEFAULT)        |
  137.         MCBSP_FMKS(PCR, CLKRM, DEFAULT)        |
  138.         MCBSP_FMKS(PCR, CLKSSTAT, DEFAULT)     |
  139.         MCBSP_FMKS(PCR, DXSTAT, DEFAULT)       |
  140.         MCBSP_FMKS(PCR, FSXP, ACTIVELOW)       |
  141.         MCBSP_FMKS(PCR, FSRP, ACTIVELOW)       |
  142.         MCBSP_FMKS(PCR, CLKXP, FALLING)        |
  143.         MCBSP_FMKS(PCR, CLKRP, RISING)
  144.     };
  145.     /* If no device parameters are passed, use the defaults. */
  146.     if (params == NULL) {
  147.         params = &TEB6416_EDMA_PCM3002_DEVPARAMS;
  148.     }
  149.     /* Check if the version is supported by the driver */
  150.     if (params->versionId != TEB6416_EDMA_PCM3002_VERSION_1) {
  151.         /* Unsupported version */
  152.         return(IOM_EBADIO);
  153.     }
  154.     /* Set up the actual codec */
  155.     result = writeMode(TEB6416_EDMA_PCM3002_MODE_REG0, params->reg[0]);
  156.     if (result) {
  157.         result = writeMode(TEB6416_EDMA_PCM3002_MODE_REG1, params->reg[1]);
  158.     }
  159.     if (result) {
  160.         result = writeMode(TEB6416_EDMA_PCM3002_MODE_REG2, params->reg[2]);
  161.     }
  162.     if (result) {
  163.         result = writeMode(TEB6416_EDMA_PCM3002_MODE_REG3, params->reg[3]);
  164.     }
  165.     if (!result) {
  166.         return (IOM_EBADIO);
  167.     }
  168.     /* Set the IRQ id to use for EDMA (default is 8) */
  169.     genericParams.irqId = params->irqId;
  170.     
  171.     /* Set the interrupt mask */
  172.     genericParams.intrMask = params->intrMask;
  173.     genericParams.cacheCalls = params->cacheCalls;
  174.     genericParams.mcbspCfgPtr = &mcbspCfg;
  175.     /* Call the generic mdBindDev to claim mcbsp port 0 */
  176.     result = (C6X1X_EDMA_MCBSP_FXNS.mdBindDev)(&port.c6x1xPortObj, 0, 
  177.                                                &genericParams);
  178.     /* Store the edma priority in PortObj */
  179.     port.edmaPriority = params->edmaPriority;
  180.     *devp = &port;
  181.     return (result);
  182. }
  183. /*
  184.  * ======== mdCreateChan ========
  185.  * This function creates and configures a device channel.
  186.  */
  187. static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
  188.                         Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg)
  189. {
  190.     Int result;
  191.     C6X1X_EDMA_MCBSP_ChanParams genericParams;
  192.     PortHandle localPort = (PortHandle) devp;
  193.     EDMA_Config edmaCfg = {
  194.         EDMA_FMKS(OPT, ESIZE, 16BIT)          |
  195.         EDMA_FMKS(OPT, 2DS, NO)               |
  196.         EDMA_FMKS(OPT, SUM, NONE)             |
  197.         EDMA_FMKS(OPT, 2DD, NO)               |
  198.         EDMA_FMKS(OPT, DUM, NONE)             |
  199.         EDMA_FMKS(OPT, TCINT, YES)            |
  200.         EDMA_FMK (OPT, TCC, NULL)             |
  201.         EDMA_FMKS(OPT, TCCM, DEFAULT)         |
  202.         EDMA_FMKS(OPT, ATCINT, NO)            |
  203.         EDMA_FMKS(OPT, ATCC, DEFAULT)         |
  204.         EDMA_FMKS(OPT, PDTS, DEFAULT)         |
  205.         EDMA_FMKS(OPT, PDTD, DEFAULT)         |
  206.         EDMA_FMKS(OPT, LINK, YES)             |
  207.         EDMA_FMKS(OPT, FS, NO),
  208.         EDMA_FMK (SRC, SRC, NULL),
  209.         EDMA_FMK (CNT, FRMCNT, NULL)          |
  210.         EDMA_FMK (CNT, ELECNT, NULL),
  211.         EDMA_FMK (DST, DST, NULL),
  212.         EDMA_FMKS(IDX, FRMIDX, DEFAULT)       |
  213.         EDMA_FMKS(IDX, ELEIDX, DEFAULT),
  214.         EDMA_FMK (RLD, ELERLD, NULL)          |
  215.         EDMA_FMK (RLD, LINK, NULL)
  216.     };
  217.     if (mode == IOM_INPUT) {
  218.         edmaCfg.opt |= EDMA_FMK(OPT, DUM, EDMA_OPT_DUM_INC);
  219.     }
  220.     else {
  221.         edmaCfg.opt |= EDMA_FMK(OPT, SUM, EDMA_OPT_SUM_INC);
  222.     }
  223.     /* set the edma transfer priority */
  224.     edmaCfg.opt |= EDMA_FMK(OPT, PRI, localPort->edmaPriority);
  225.     /*
  226.      * This codec uses 4 McBSP TDM channels (although it's a stereo codec).
  227.      * This value will set up the Loop job in the generic driver to keep
  228.      * the external framesync.
  229.      */
  230.     genericParams.tdmChans = 4;
  231.     genericParams.edmaCfgPtr = &edmaCfg;
  232.     result = (C6X1X_EDMA_MCBSP_FXNS.mdCreateChan)(chanp, localPort->c6x1xPortObj, 
  233.                                   name, mode, &genericParams, cbFxn, cbArg);
  234.     return (result);
  235. }
  236. /*
  237.  * ======== writeMode() ========
  238.  * This function writes the value modeVal to the codec mode register.
  239.  */
  240. static Int writeMode(int modeReg, Int modeVal)
  241. {
  242.     Int modeMask;
  243.     volatile Int timeout;
  244.     switch(modeReg) {
  245.     case 0:
  246.     case 1:
  247.     case 2:
  248.         modeMask = 0x01ff;
  249.         break;
  250.     case 3:
  251.         modeMask = 0x002e;
  252.         break;
  253.     default:
  254.         return (0);
  255.     }
  256.     modeVal &= modeMask;
  257.     modeVal |= (modeReg << 9);
  258.     for (timeout = 1000; timeout > 0; timeout--) {
  259.         if (isCodecReady()) {
  260.             writeCodecMode(modeVal);
  261.             return(modeVal);
  262.         }
  263.     }
  264.     return (0);
  265. }
  266. /*
  267.  * ======== WriteCodecMode() ========
  268.  * This function writes the codec mode register.
  269.  */
  270. static Int writeCodecMode(Int modeVal)
  271. {
  272.     volatile Char *ptr = (volatile Char *) CPLDBASEADDR;
  273.     ptr[REGACODECL] = modeVal;
  274.     ptr[REGACODECH] = modeVal >> 8;
  275.     return (modeVal & 0x0ffff);
  276. }
  277. /*
  278.  * ======== isCodecReady() ========
  279.  * This function determines whether the codec is ready or not.
  280.  */
  281. static Int isCodecReady(Void)
  282. {
  283.     volatile Char *ptr = (volatile Char *) CPLDBASEADDR;
  284.     return ((ptr[REGAMISC] & REGCODECMTRDY) == 0);
  285. }
  286. /*
  287.  * ======== TEB6416_EDMA_PCM3002_init ========
  288.  * This function initializes the driver's structures.
  289.  */
  290. Void TEB6416_EDMA_PCM3002_init()
  291. {
  292.     /* Pass some IOM fxns straight to the generic driver */
  293.     TEB6416_EDMA_PCM3002_FXNS.mdControlChan =
  294.         C6X1X_EDMA_MCBSP_FXNS.mdControlChan;
  295.     TEB6416_EDMA_PCM3002_FXNS.mdDeleteChan =
  296.         C6X1X_EDMA_MCBSP_FXNS.mdDeleteChan;
  297.     TEB6416_EDMA_PCM3002_FXNS.mdSubmitChan =
  298.         C6X1X_EDMA_MCBSP_FXNS.mdSubmitChan;
  299.     TEB6416_EDMA_PCM3002_FXNS.mdUnBindDev =
  300.         C6X1X_EDMA_MCBSP_FXNS.mdUnBindDev;
  301.     C6X1X_EDMA_MCBSP_init();
  302. }