lowlevel.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:11k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.   **********************************************************************
  3.   *
  4.   *     Copyright 1999, 2000 Creative Labs, Inc.
  5.   *
  6.   **********************************************************************
  7.   *
  8.   *     Date                 Author               Summary of changes
  9.   *     ----                 ------               ------------------
  10.   *     October 20, 1999     Andrew de Quincey    Rewrote and extended
  11.   *                          Lucien Murray-Pitts  original incomplete 
  12.   *                                               driver.
  13.   *
  14.   *     April 18, 1999       Andrew Veliath       Original Driver
  15.   *                                               implementation
  16.   *
  17.   **********************************************************************
  18.   *
  19.   *     This program is free software; you can redistribute it and/or
  20.   *     modify it under the terms of the GNU General Public License as
  21.   *     published by the Free Software Foundation; either version 2 of
  22.   *     the License, or (at your option) any later version.
  23.   *
  24.   *     This program is distributed in the hope that it will be useful,
  25.   *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.   *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.   *     GNU General Public License for more details.
  28.   *
  29.   *     You should have received a copy of the GNU General Public
  30.   *     License along with this program; if not, write to the Free
  31.   *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  32.   *     USA.
  33.   *
  34.   **********************************************************************
  35.   */
  36. /**
  37.  *
  38.  * Driver for the C-Cube Ziva-DS MPEG decoder chip
  39.  * Register get/set functions.
  40.  *
  41.  */
  42. #include <linux/errno.h>
  43. #include <linux/types.h>
  44. #include <linux/sched.h>
  45. #include <zivaDS.h>
  46. /**
  47.  *
  48.  * Get register from the ZivaDS
  49.  *
  50.  * @param instance Instance of the ZivaDS to use
  51.  * @param reg Register to retrieve
  52.  *
  53.  * @return The register's value, or <0 on failure
  54.  *
  55.  */
  56. extern int zivaDS_get_reg(zivaDS_t* instance, int reg)
  57. {
  58.   return (*instance->ops->get_reg) (instance, reg);
  59. }
  60. /**
  61.  *
  62.  * Set register on the ZivaDS
  63.  *
  64.  * @param instance Instance of the ZivaDS to use
  65.  * @param reg Register to retrieve
  66.  * @param val Value to set
  67.  *
  68.  */
  69. extern void zivaDS_set_reg(zivaDS_t* instance, int reg, int val)
  70. {
  71.   (*instance->ops->set_reg) (instance, reg, val);
  72. }
  73. /**
  74.  *
  75.  * Get specified bitmask of a register from ZivaDS
  76.  *
  77.  * @param instance Instance of the ZivaDS to use
  78.  * @param reg Register to retrieve
  79.  * @param bitmask Bitmask of bits to retrive from that register
  80.  *
  81.  * @return The register bitvalues, or <0 on failure
  82.  *
  83.  */
  84. extern int zivaDS_get_bits(zivaDS_t* instance, int reg, int bitmask)
  85. {
  86.   return (zivaDS_get_reg(instance, reg) & bitmask);
  87. }
  88. /**
  89.  *
  90.  * Set specified bits of a register on ZivaDS
  91.  *
  92.  * @param instance Instance of the ZivaDS to use
  93.  * @param reg Register to retrieve
  94.  * @param bitmask Bitmask of bits to set from that register
  95.  * @param valuemask Values of the bits in the bitmask
  96.  *
  97.  */
  98. extern void zivaDS_set_bits(zivaDS_t* instance, int reg, int bitmask, int valuemask)
  99. {
  100.   // get the current register value
  101.   int value = zivaDS_get_reg(instance, reg);
  102.   
  103.   // set it on the hardware
  104.   zivaDS_set_reg(instance, reg, (value & (~bitmask)) | valuemask);
  105. }
  106. /**
  107.  *
  108.  * Read from a ZivaDS memory location
  109.  *
  110.  * @param instance Instance of Ziva DS to read from
  111.  * @param addr Address to read from in that memory area
  112.  *
  113.  * @return Memory value
  114.  *
  115.  */
  116. extern int zivaDS_get_mem (zivaDS_t* instance, int addr)
  117. {
  118.   // return the value
  119.   return (*instance->ops->get_mem) (instance, addr);
  120. }
  121. /**
  122.  *
  123.  * Write to a ZivaDS memory location
  124.  *
  125.  * @param instance Instance of Ziva DS to read from
  126.  * @param addr Address to write to in that memory area
  127.  * @param val Value to write
  128.  *
  129.  */
  130. extern void zivaDS_set_mem (zivaDS_t* instance, int addr, int val)
  131. {
  132.   // set the value
  133.   (*instance->ops->set_mem) (instance, addr, val);
  134. }
  135. /**
  136.  *
  137.  * Issues a command to the Ziva chip
  138.  *
  139.  * @param instance Instance of the ZivaDS to use
  140.  * @param command Ziva command to send
  141.  * @param arg0 Argument 0 for command
  142.  * @param arg1 Argument 1 for command
  143.  * @param arg2 Argument 2 for command
  144.  * @param arg3 Argument 3 for command
  145.  * @param arg4 Argument 4 for command
  146.  * @param arg5 Argument 5 for command
  147.  * @param intMask Ziva Int Mask to set (0 for don't bother)
  148.  * @param statusToWaitFor Ziva Status to wait for (0 for don't bother)
  149.  *
  150.  * @return 0 on success, <0 on failure
  151.  *
  152.  */
  153. extern int zivaDS_command(zivaDS_t* instance,
  154.   int command,
  155.   int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
  156.   int intMask, int statusToWaitFor)
  157. {
  158.   int oldIntFlag;
  159.   int oldIntMask;
  160.   int oldIntStatus;
  161.   int endTime;
  162.   int status = 0;
  163.   int statusAddress;
  164.   zivaDS_int_src_t intStatus;
  165.   int loopFlag;
  166.   // if the int mask isn't zero, set supplied int status on ziva
  167.   if (intMask != 0) {
  168.     
  169.     // get old interrupt enabled flag
  170.     oldIntFlag = zivaDS_is_int_enabled(instance);
  171.     
  172.     // disable ziva interrupts
  173.     zivaDS_enable_int(instance, 0);
  174.     // get old int mask & status
  175.     oldIntMask = zivaDS_get_mem(instance, ZIVADS_INT_MASK);
  176.     // clear any pending interrupts
  177.     zivaDS_get_int_status(instance, &intStatus);
  178.     
  179.     // write supplied int mask
  180.     zivaDS_set_mem(instance, ZIVADS_INT_MASK, intMask);
  181.   }
  182.   // loop until ziva status address is set
  183.   loopFlag=0;
  184.   endTime = jiffies + ((40*HZ)/100);
  185.   while(jiffies < endTime) {
  186.     
  187.     // let other things in
  188.     schedule();
  189.     
  190.     // get status addres
  191.     if (zivaDS_get_mem(instance, ZIVADS_STATUS_ADDRESS)) {
  192.       
  193.       loopFlag=1;
  194.       break;
  195.     }
  196.   }
  197.   
  198.   // has loop elapsed? if so => error
  199.   if (!loopFlag) {
  200.     
  201.     return(-ETIMEDOUT);
  202.   }
  203.   
  204.   // OK, issue command to the ziva
  205.   zivaDS_set_mem(instance, ZIVADS_COMMAND, command);
  206.   zivaDS_set_mem(instance, ZIVADS_PARAMETER_1, arg0);
  207.   zivaDS_set_mem(instance, ZIVADS_PARAMETER_2, arg1);
  208.   zivaDS_set_mem(instance, ZIVADS_PARAMETER_3, arg2);
  209.   zivaDS_set_mem(instance, ZIVADS_PARAMETER_4, arg3);
  210.   zivaDS_set_mem(instance, ZIVADS_PARAMETER_5, arg4);
  211.   zivaDS_set_mem(instance, ZIVADS_PARAMETER_6, arg5);
  212.   // OK, ziva status address = 0.... does this start the command going?
  213.   zivaDS_set_mem(instance, ZIVADS_STATUS_ADDRESS, 0);
  214.   
  215.   // OK, if the intMask != 0 => wait until interrupt occurs
  216.   if (intMask != 0) {
  217.     
  218.     // loop until ziva status address is set
  219.     loopFlag =0;
  220.     endTime = jiffies + ((30*HZ)/100);
  221.     while(jiffies < endTime) {
  222.       
  223.       // let other things in
  224.       schedule();
  225.       
  226.       // is the interrupt set?
  227.       if (zivaDS_get_int_status(instance, &intStatus) & intMask) {
  228. loopFlag=1;
  229. break;
  230.       }
  231.     }
  232.     
  233.     // restore old int mask
  234.     zivaDS_set_mem(instance, ZIVADS_INT_MASK, oldIntMask);
  235.     // turn interrupts back on if oldIntFlag says so.
  236.     if (oldIntFlag != 0) {
  237.       zivaDS_enable_int(instance, 1);
  238.     }
  239.     // did timer elapse?
  240.     if (!loopFlag) {
  241.       
  242.       status = -ETIMEDOUT;
  243.     }
  244.   }
  245.   
  246.   // right, if statusToWaitFor != 0 => wait for it...
  247.   if (statusToWaitFor != 0) {
  248.     
  249.     // loop until ziva status is what we're looking for, or timeout
  250.     loopFlag=0;
  251.     endTime = jiffies + ((80*HZ)/100);
  252.     while(jiffies < endTime) {
  253.       
  254.       // let other things in
  255.       schedule();
  256.       
  257.       // get the status address
  258.       if (statusAddress = zivaDS_get_mem(instance, ZIVADS_STATUS_ADDRESS)) {
  259. if (zivaDS_get_mem(instance, statusAddress) == statusToWaitFor) {
  260.   
  261.   loopFlag=1;
  262.   break;
  263. }
  264.       }
  265.     }
  266.     
  267.     // did timer elapse?
  268.     if (!loopFlag) {
  269.       
  270.       status = -ETIMEDOUT;
  271.     }
  272.   }
  273.   // return status
  274.   return(status);
  275. }
  276. /**
  277.  *
  278.  * Determines whether the ziva Int is currently enabled
  279.  *
  280.  * @param instance zivaDS instance
  281.  *
  282.  * @return 0 => int NOT enabled, 1 => int enabled
  283.  *
  284.  */
  285. extern int zivaDS_is_int_enabled(zivaDS_t* instance)
  286. {
  287.   
  288.   return(instance->intEnabledFlag);
  289. }
  290. /**
  291.  *
  292.  * Enable/disable ziva interrupt
  293.  *
  294.  * @param instance zivaDS instance
  295.  * @param flag 0=> disable, 1=> enable
  296.  *
  297.  * @return 0 on success, <0 on failure
  298. *
  299.  */
  300. extern int zivaDS_enable_int(zivaDS_t* instance, int flag) 
  301. {
  302.   
  303.   // OK, do the hardware specifics
  304.   (*instance->ops->enable_int) (instance, flag);
  305.   // remember status
  306.   instance->intEnabledFlag = flag;
  307.   // OK
  308.   return(0);
  309. }
  310. /**
  311.  *
  312.  * Get ziva int status
  313.  *
  314.  * @param instance zivaDS instance
  315.  * @param itnSrcBuf buffer to hold intsrcs
  316.  * 
  317.  * @return int status bitmap from ziva
  318.  *
  319.  */
  320. extern int zivaDS_get_int_status(zivaDS_t* instance, zivaDS_int_src_t* intSrcBuf)
  321. {
  322.   int intStatus;
  323.   // read the int status.. if it's 0, exit now
  324.   intStatus = zivaDS_get_mem(instance, ZIVADS_INT_STATUS);
  325.   // OK, do stuff if some ints ARE marked as set
  326.   if (intStatus != 0) {
  327.     // ??
  328.     zivaDS_set_mem(instance, 0x800000, 0x1002);
  329.     // OK, read int srcs
  330.     if (intStatus & 0x80000) {
  331.       
  332.       intSrcBuf->HLI_int_src = zivaDS_get_mem(instance, ZIVADS_HLI_INT_SRC);
  333.       zivaDS_set_mem(instance, ZIVADS_HLI_INT_SRC, 0);
  334.     }
  335.     if (intStatus & 0x10000) {
  336.       
  337.       intSrcBuf->BUF_int_src = zivaDS_get_mem(instance, ZIVADS_BUFF_INT_SRC);
  338.       zivaDS_set_mem(instance, ZIVADS_BUFF_INT_SRC, 0);    
  339.     }
  340.     if (intStatus & 0x100) {
  341.       
  342.       intSrcBuf->UND_int_src = zivaDS_get_mem(instance, ZIVADS_UND_INT_SRC);
  343.       zivaDS_set_mem(instance, ZIVADS_UND_INT_SRC, 0);
  344.     }
  345.     if (intStatus & 0x80) {
  346.       
  347.       intSrcBuf->AOR_int_src = zivaDS_get_mem(instance, ZIVADS_AOR_INT_SRC);
  348.       zivaDS_set_mem(instance, ZIVADS_AOR_INT_SRC, 0);
  349.     }
  350.     if (intStatus & 0x8000) {
  351.       
  352.       intSrcBuf->AEE_int_src = zivaDS_get_mem(instance, ZIVADS_AEE_INT_SRC);
  353.       zivaDS_set_mem(instance, ZIVADS_AEE_INT_SRC, 0);
  354.     }
  355.     if (intStatus & 1) {
  356.       
  357.       intSrcBuf->ERR_int_src = zivaDS_get_mem(instance, ZIVADS_ERR_INT_SRC);
  358.       zivaDS_set_mem(instance, ZIVADS_ERR_INT_SRC, 0);
  359.     }
  360.   
  361.     // set int status to 0 (i.e. the interrupt has been dealt with)
  362.     zivaDS_set_mem(instance, ZIVADS_INT_STATUS, 0);
  363.   }
  364.   
  365.   // return status
  366.   return(intStatus);
  367. }
  368. /**
  369.  *
  370.  * Checks if the ziva is ZIVADS_TYPE_1 or not (i.e. doesn't have onboard CSS)
  371.  *
  372.  * @param instance zivaDS instance
  373.  *
  374.  * @return 0 => NOT ZIVADS_TYPE_1, 1=> it IS ZIVADS_TYPE_1
  375.  *
  376.  */
  377. extern int zivaDS_check_type_1(zivaDS_t* instance)
  378. {
  379.   // if this bit is set => it is!!
  380.   if (zivaDS_get_mem(instance, 0x800000) & 0x40000) {
  381.     
  382.     return(1);
  383.   }
  384.   // failed
  385.   return(0);
  386. }
  387. /**
  388.  *
  389.  * Check the ziva is there
  390.  *
  391.  * @param instance zivaDS instance
  392.  *
  393.  * @return 0 if it is, <0 on failure
  394.  *
  395.  */
  396. extern int zivaDS_validate(zivaDS_t* instance)
  397. {
  398.   // write to ziva reg
  399.   zivaDS_set_reg(instance, ZIVADS_REGADDRESS, 0x65);
  400.   
  401.   // check it is still that value
  402.   if (zivaDS_get_reg(instance, ZIVADS_REGADDRESS) != 0x65) {
  403.     
  404.     return(-ENODEV);
  405.   }
  406.   
  407.   // OK!
  408.   return(0);
  409. }