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

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.  * Overall driver for the Creative DXR2 card
  39.  * Low level AnP82 functions
  40.  *
  41.  */
  42. #include <linux/errno.h>
  43. #include <dxr2.h>
  44. #include <anp82.h>
  45. #include <vxp524.h>
  46. static int dxr2_anp82_get_reg(anp82_t* instance, int reg);
  47. static int dxr2_anp82_set_reg(anp82_t* instance, int reg, int val);
  48. static int dxr2_anp82_send_byte(vxp524_t* instance, int data);
  49. static int dxr2_anp82_read_byte(vxp524_t* instance);
  50. anp82_ops_t anp82_ops_table = {
  51.   DXR2_LOGNAME,
  52.   dxr2_anp82_get_reg,
  53.   dxr2_anp82_set_reg,
  54. };
  55. /**
  56.  *
  57.  * Get register from the anp82
  58.  *
  59.  * @param instance anp82 instance to use
  60.  * @param reg Register to read
  61.  *
  62.  * @return value (-1 => error)
  63.  *
  64.  */
  65. static int dxr2_anp82_get_reg(anp82_t* instance, int reg)
  66. {
  67.   int data;
  68.   int status = 0;
  69.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  70.   vxp524_t* vxp524Inst = dxr2Inst->vxp524Instance;
  71.   // open i2c bus
  72.   vxp524_i2s_init(vxp524Inst);
  73.   vxp524_set_bits(vxp524Inst, VXP524_I2C, 0x80, 0x80);
  74.   // Send control byte
  75.   if ((status = dxr2_anp82_send_byte(vxp524Inst, ANP82_CHIPID | 0x80)) < 0) {
  76.     
  77.     vxp524_i2s_close(vxp524Inst);
  78.     return(status);
  79.   }
  80.   // Send index
  81.   if ((status = dxr2_anp82_send_byte (vxp524Inst, reg)) < 0) {
  82.     
  83.     vxp524_i2s_close(vxp524Inst);
  84.     return(status);
  85.   }
  86.   
  87.   // Send data
  88.   if ((data = dxr2_anp82_read_byte (vxp524Inst)) < 0) {
  89.     vxp524_i2s_close(vxp524Inst);    
  90.     return(data);
  91.   }
  92.   
  93.   // turn i2c off again
  94.   vxp524_set_bits(vxp524Inst, VXP524_I2C, 0x80, 0x0);
  95.   vxp524_i2s_close(vxp524Inst);
  96.   // return
  97.   return data;
  98. }
  99. /**
  100.  *
  101.  * Set register on the anp82
  102.  *
  103.  * @param instance anp82 instance to use
  104.  * @param reg Register to write
  105.  * @param reg Value to write
  106.  *
  107.  * @return status (-1 => error)
  108.  *
  109.  */
  110. static int dxr2_anp82_set_reg(anp82_t* instance, int reg, int val)
  111. {
  112.   int status = 0;
  113.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  114.   vxp524_t* vxp524Inst = dxr2Inst->vxp524Instance;
  115.   // open i2c bus
  116.   vxp524_i2s_init(vxp524Inst);
  117.   vxp524_set_bits(vxp524Inst, VXP524_I2C, 0x80, 0x80);
  118.   // Send control byte
  119.   if (dxr2_anp82_send_byte(vxp524Inst, ANP82_CHIPID) < 0) {
  120.   
  121.     vxp524_i2s_close(vxp524Inst);
  122.     return(-ETIMEDOUT);
  123.   }
  124.   // Send register
  125.   if ((status = dxr2_anp82_send_byte(vxp524Inst, reg)) < 0) {
  126.  
  127.     vxp524_i2s_close(vxp524Inst);
  128.     return(status);
  129.   }
  130.   // Send data
  131.   if ((status = dxr2_anp82_send_byte(vxp524Inst, val)) < 0) {
  132.   
  133.     vxp524_i2s_close(vxp524Inst);
  134.     return(status);
  135.   }
  136.   // turn i2c off again
  137.   vxp524_set_bits(vxp524Inst, VXP524_I2C, 0x80, 0x0);
  138.   vxp524_i2s_close(vxp524Inst);
  139.   // OK
  140.   return(0);
  141. }
  142. /**
  143.  *
  144.  * Send a byte to the AnP82
  145.  *
  146.  * @param instance VxP524 instance
  147.  * @param data Data to send
  148.  *
  149.  * @return status (0=>success, -1=>error)
  150.  *
  151.  */
  152. static int dxr2_anp82_send_byte (vxp524_t* instance, int data)
  153. {
  154.   int i, j;
  155.   int status = 0;
  156.   // start bit
  157.   vxp524_i2s_set_sda(instance);
  158.   if (vxp524_i2s_wait_till_sda_set(instance, 1000) < 0) {
  159.     
  160.     status--;
  161.   }
  162.   vxp524_i2s_set_scl(instance);
  163.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  164.     
  165.     status--;
  166.   }
  167.   vxp524_i2s_clear_scl(instance);
  168.   vxp524_i2s_set_scl(instance);
  169.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  170.     
  171.     status--;
  172.   }
  173.   vxp524_i2s_clear_scl(instance);
  174.   vxp524_i2s_clear_sda(instance);
  175.   vxp524_i2s_set_scl(instance);
  176.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  177.     
  178.     status--;
  179.   }
  180.   vxp524_i2s_clear_scl(instance);
  181.   vxp524_i2s_clear_scl(instance);
  182.   // Clock the bits out, MSB to LSB 
  183.   for (i = 7; i >= 0; --i) {
  184.     // set data bit appropriately
  185.     if (data & (1<<i)) {
  186.       vxp524_i2s_set_sda(instance);
  187.       if (vxp524_i2s_wait_till_sda_set(instance, 1000) < 0) {
  188. status--;
  189.       }
  190.     }
  191.     else {
  192.       vxp524_i2s_clear_sda(instance);
  193.     }
  194.     
  195.     // Clock pulse
  196.     vxp524_i2s_set_scl(instance);
  197.     if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  198.       
  199.       status--;
  200.     }
  201.     vxp524_i2s_clear_scl(instance);
  202.   }
  203.   
  204.   // Send stop bit
  205.   vxp524_i2s_set_sda(instance);
  206.   if (vxp524_i2s_wait_till_sda_set(instance, 1000) < 0) {
  207.     
  208.     status--;
  209.   }
  210.   vxp524_i2s_set_scl(instance);
  211.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  212.     
  213.     status--;
  214.   }
  215.   vxp524_i2s_clear_scl(instance);
  216.   
  217.   // get ACK
  218.   vxp524_i2s_tri_sda(instance);
  219.   vxp524_i2s_set_scl(instance);
  220.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  221.     
  222.     status--;
  223.   }
  224.   i = vxp524_i2s_get_sda(instance);
  225.   vxp524_i2s_clear_scl(instance);
  226.   vxp524_i2s_set_scl(instance);
  227.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  228.     
  229.     status--;
  230.   }
  231.   j = vxp524_i2s_get_sda(instance);
  232.   vxp524_i2s_clear_scl(instance);
  233.   vxp524_i2s_set_scl(instance);
  234.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  235.     
  236.     status--;
  237.   }
  238.   vxp524_i2s_untri_sda(instance);
  239.   // check status
  240.   if (status < 0) {
  241.     
  242.     return(-ETIMEDOUT);
  243.   }
  244.   // Check ack
  245.   if (!i && j)
  246.     return(0);
  247.   
  248.   // erk! not got an ACK... just say we've timed out
  249.   return(-ETIMEDOUT);
  250. }
  251. /**
  252.  *
  253.  * Read a byte from the AnP82
  254.  *
  255.  * @param instance VxP524 instance
  256.  *
  257.  * @return data (-1=>error)
  258.  *
  259.  */
  260. static int dxr2_anp82_read_byte (vxp524_t* instance)
  261. {
  262.   int i, data = 0;
  263.   int status=0;
  264.   // Clock start bit, with data tri-stated
  265.   vxp524_i2s_tri_sda(instance);
  266.   vxp524_i2s_clear_scl(instance);
  267.   vxp524_i2s_set_scl(instance);
  268.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  269.     
  270.     status--;
  271.   }
  272.   vxp524_i2s_clear_scl(instance);
  273.   if (vxp524_i2s_wait_till_sda_set(instance, 1000) < 0) {
  274.     
  275.     status--;
  276.   }
  277.   vxp524_i2s_set_scl(instance);  
  278.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  279.     
  280.     status--;
  281.   }
  282.   vxp524_i2s_clear_scl(instance);
  283.   
  284.   // Read the bits in, MSB to LSB 
  285.   for (i = 0; i < 8; i++) {
  286.     // shift old value left 1
  287.     data <<= 1;
  288.     // Read the bit
  289.     if (vxp524_i2s_get_sda(instance)) {
  290.       
  291.       data |= 1;
  292.     }
  293.     // clock up
  294.     vxp524_i2s_set_scl(instance);
  295.     if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  296.       
  297.       status--;
  298.     }
  299.     // Clock down
  300.     vxp524_i2s_clear_scl(instance);
  301.   }
  302.   
  303.   // Clock stop bit
  304.   vxp524_i2s_set_scl(instance);
  305.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  306.     
  307.     status--;
  308.   }
  309.   vxp524_i2s_clear_scl(instance);
  310.   
  311.   // Send ack
  312.   vxp524_i2s_clear_sda(instance);
  313.   vxp524_i2s_untri_sda(instance);
  314.   vxp524_i2s_set_scl(instance);
  315.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  316.     
  317.     status--;
  318.   }
  319.   vxp524_i2s_clear_scl(instance);
  320.   vxp524_i2s_set_sda(instance);
  321.   if (vxp524_i2s_wait_till_sda_set(instance, 1000) < 0) {
  322.     
  323.     status--;
  324.   }
  325.   vxp524_i2s_set_scl(instance);
  326.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  327.     
  328.     status--;
  329.   }
  330.   vxp524_i2s_clear_scl(instance);
  331.   vxp524_i2s_set_scl(instance);
  332.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  333.     
  334.     status--;
  335.   }
  336.   vxp524_i2s_clear_scl(instance);
  337.   // check status
  338.   if (status < 0) {
  339.     
  340.     return(-ETIMEDOUT);
  341.   }
  342.   // OK, return the data
  343.   return(data);
  344. }