i2c.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.  * Driver for the Auravision VxP524 video processor
  39.  * vxp524 i2c operations
  40.  *
  41.  */
  42. #include <linux/errno.h>
  43. #include <vxp524.h>
  44. /**
  45.  *
  46.  * Send an ACK on the i2c bus
  47.  *
  48.  * @param instance VXP524 instance to use
  49.  *
  50.  */
  51. static int vxp524_i2s_send_ack(vxp524_t* instance) 
  52. {
  53.   int status = 0;
  54.   
  55.   // set clock line
  56.   vxp524_i2s_set_scl(instance);
  57.   // wait till it is reflected on the input
  58.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) <0) {
  59.     
  60.     status--;
  61.   }
  62.   // clear clock line
  63.   vxp524_i2s_clear_scl(instance);
  64.   
  65.   // return status
  66.   if (status < 0) {
  67.     
  68.     return(-ETIMEDOUT);
  69.   }
  70.   
  71.   // OK
  72.   return(0);
  73. }
  74. /**
  75.  *
  76.  * Wait for acknowledgement from slave i2c device
  77.  *
  78.  * @param instance VXP524 instance to use
  79.  *
  80.  */
  81. static int vxp524_i2s_wait_for_ack(vxp524_t* instance) 
  82. {
  83.   int status=0;
  84.   
  85.   // tristate the data line
  86.   vxp524_i2s_tri_sda(instance);
  87.   
  88.   // wait till sda set
  89.   if (vxp524_i2s_wait_till_sda_set(instance, 5000) <0) {
  90.     
  91.     status--;
  92.   }
  93.   // un-tristate the data line
  94.   vxp524_i2s_untri_sda(instance);
  95.   
  96.   // set clock line
  97.   vxp524_i2s_set_scl(instance);
  98.   // wait till it is reflected on the input
  99.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  100.     
  101.     status--;
  102.   }
  103.   // clear clock line
  104.   vxp524_i2s_clear_scl(instance);
  105.   
  106.   // check for error 
  107.   if (status < 0) {
  108.     
  109.     return(-ETIMEDOUT);
  110.   }
  111.   // OK
  112.   return(0);
  113. }
  114. /**
  115.  *
  116.  * Send a stop bit
  117.  *
  118.  * @param instance VXP524 instance to use
  119.  *
  120.  */
  121. static int vxp524_i2s_send_stop_bit(vxp524_t* instance) 
  122. {
  123.   int status = 0;
  124.   // clear data line
  125.   vxp524_i2s_clear_sda(instance);
  126.   // set clock line
  127.   vxp524_i2s_set_scl(instance);
  128.   // wait till it is reflected on the input
  129.   status = vxp524_i2s_wait_till_scl_set(instance, 1000);
  130.   // set data line
  131.   vxp524_i2s_set_sda(instance);
  132.   
  133.   // return status
  134.   return(status);
  135. }
  136. /**
  137.  *
  138.  * Send a start bit
  139.  *
  140.  * @param instance VXP524 instance to use
  141.  *
  142.  */
  143. static int vxp524_i2s_send_start_bit(vxp524_t* instance) 
  144. {
  145.   int status=0;
  146.   // set data line
  147.   vxp524_i2s_set_sda(instance);
  148.   // wait till it is reflected on the input
  149.   if (vxp524_i2s_wait_till_sda_set(instance, 1000) <0) {
  150.     
  151.     status--;
  152.   }
  153.   // set clock line
  154.   vxp524_i2s_set_scl(instance);
  155.   // wait till it is reflected on the input
  156.   if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  157.     
  158.     status--;
  159.   }
  160.   // clear data line
  161.   vxp524_i2s_clear_sda(instance);
  162.   // clear clock line
  163.   vxp524_i2s_clear_scl(instance);
  164.   
  165.   // return status
  166.   if (status < 0) {
  167.     
  168.     return(-ETIMEDOUT);
  169.   }
  170.   
  171.   // OK
  172.   return(0);
  173. }
  174. /**
  175.  *
  176.  * Read a (8bit) byte from the i2c interface
  177.  *
  178.  * @param instance VXP524 instance to use
  179.  *
  180.  * @return The value (>=0), or <0 on error
  181.  *
  182.  */
  183. static int vxp524_i2s_read_byte(vxp524_t* instance) 
  184. {
  185.   int value=0;
  186.   int status=0;
  187.   int i;
  188.   // tri state the SDA read line
  189.   vxp524_i2s_tri_sda(instance);
  190.   // read in each bit MSB first
  191.   for(i=0; i<8; i++) {
  192.     
  193.     // set clock
  194.     vxp524_i2s_set_scl(instance);
  195.     // wait for it to be reflected on input lines
  196.     if (vxp524_i2s_wait_till_scl_set(instance, 1000) < 0) {
  197.       status--;
  198.     }
  199.     
  200.     // get the next bit
  201.     value <<=1; // shift acc left a bit
  202.     value |= vxp524_i2s_get_sda(instance); // OR on the next value
  203.     
  204.     // clear clock
  205.     vxp524_i2s_clear_scl(instance);
  206.   }
  207.   // tri state the SDA read line
  208.   vxp524_i2s_untri_sda(instance);
  209.   // return the status if there was an error
  210.   if (status < 0) {
  211.     
  212.     return(-ETIMEDOUT);
  213.   }
  214.   // return the value if everything was OK
  215.   return(value);
  216. }
  217. /**
  218.  *
  219.  * Write an (8bit) byte to the i2c interface
  220.  *
  221.  * @param instance VXP524 instance to use
  222.  * @param val Value to write
  223.  *
  224.  * @return 0 on success, or <0 on error
  225.  *
  226.  */
  227. static int vxp524_i2s_write_byte(vxp524_t* instance, int val) 
  228. {
  229.   int curBit = 0x80;
  230.   int status=0;
  231.   int i;
  232.   // write out each bit MSB first
  233.   for(i=0; i<8; i++) {
  234.     
  235.     // set the SDA line appropriately
  236.     if (val & curBit) {
  237.       
  238.       vxp524_i2s_set_sda(instance);
  239.     }
  240.     else {
  241.       vxp524_i2s_clear_sda(instance);
  242.     }
  243.     // set clock
  244.     vxp524_i2s_set_scl(instance);
  245.     // wait for it to be reflected on input lines
  246.     if (vxp524_i2s_wait_till_scl_set(instance, 1000) <0) {
  247.       status --;
  248.     }
  249.     // clear clock
  250.     vxp524_i2s_clear_scl(instance);
  251.     // move curBit right one
  252.     curBit >>= 1;
  253.   }
  254.   // tri state the SDA read line
  255.   if (vxp524_i2s_wait_for_ack(instance) < 0) {
  256.     
  257.     return(-ETIMEDOUT);
  258.   }
  259.   // return the status if there was an error
  260.   if (status < 0) {
  261.     
  262.     return(-ETIMEDOUT);
  263.   }
  264.   // return the value if everything was OK
  265.   return(0);
  266. }
  267. /**
  268.  *
  269.  * Read a value from a register on a device connected to the i2c bus
  270.  *
  271.  * @param instance VXP524 instance to use
  272.  * @param devId Device id to read from
  273.  * @param reg Register on the device to read from
  274.  *
  275.  * @return Value on success (>=0), or <0 on error
  276.  *
  277.  */
  278. extern int vxp524_i2c_read_reg(vxp524_t* instance, int devId, int reg)
  279. {
  280.   int value;
  281.   int status = 0;
  282.   
  283.   // initialise I2S bus
  284.   vxp524_i2s_init(instance);
  285.   
  286.   // send start bit
  287.   if (vxp524_i2s_send_start_bit(instance) < 0) {
  288.     status = -ETIMEDOUT;
  289.     goto error;
  290.   }
  291.   // write device ID
  292.   if (vxp524_i2s_write_byte(instance, devId) < 0) {
  293.     
  294.     status = -ETIMEDOUT;
  295.     goto error;
  296.   }
  297.   // write register
  298.   if (vxp524_i2s_write_byte(instance, reg) < 0) {
  299.     status = -ETIMEDOUT;
  300.     goto error;
  301.   }
  302.   
  303.   // send start bit
  304.   if (vxp524_i2s_send_start_bit(instance) < 0) {
  305.     status = -ETIMEDOUT;
  306.     goto error;
  307.   }
  308.   // write device ID (set bit1... ie. READ from device)
  309.   if (vxp524_i2s_write_byte(instance, devId | 1) < 0) {
  310.     status = -ETIMEDOUT;
  311.     goto error;
  312.   }
  313.   // read register
  314.   if ((value = vxp524_i2s_read_byte(instance)) < 0) {
  315.     status = -ETIMEDOUT;
  316.     goto error;
  317.   }
  318.   // send ACK
  319.   if (vxp524_i2s_send_ack(instance) < 0) {
  320.     status = -ETIMEDOUT;
  321.     goto error;
  322.   }
  323.   
  324.   // send stop bit
  325.   if (vxp524_i2s_send_stop_bit(instance) < 0) {
  326.     status = -ETIMEDOUT;
  327.   }
  328.  error:
  329.   // shutdown i2c bus
  330.   vxp524_i2s_close(instance);
  331.   
  332.   // if it's an error, return it
  333.   if (status <0) {
  334.     
  335.     return(status);
  336.   }
  337.   
  338.   // return the read value
  339.   return(value);
  340. }
  341.   
  342. /**
  343.  *
  344.  * Write a value to a register on a device connected to the i2c bus
  345.  *
  346.  * @param instance VXP524 instance to use
  347.  * @param devId Device id to write to
  348.  * @param reg Register on the device to write to
  349.  * @param val Value to write
  350.  *
  351.  * @return 0 on success, or <0 on error
  352.  *
  353.  */
  354. extern int vxp524_i2c_write_reg(vxp524_t* instance, int devId, int reg, int val)
  355. {
  356.   int status=0;
  357.   // initialise I2S bus
  358.   vxp524_i2s_init(instance);
  359.   
  360.   // send start bit
  361.   if (vxp524_i2s_send_start_bit(instance) < 0) {
  362.     status = -ETIMEDOUT;
  363.     goto error;
  364.   }
  365.   // write device ID
  366.   if (vxp524_i2s_write_byte(instance, devId) <0) {
  367.     status = -ETIMEDOUT;
  368.     goto error;
  369.   }
  370.   // write register
  371.   if (vxp524_i2s_write_byte(instance, reg) <0) {
  372.     status = -ETIMEDOUT;
  373.     goto error;
  374.   }
  375.   // write value
  376.   if (vxp524_i2s_write_byte(instance, val) <0) {
  377.     status = -ETIMEDOUT;
  378.     goto error;
  379.   }
  380.  
  381.   // send stop bit
  382.   if (vxp524_i2s_send_stop_bit(instance) <0) {
  383.  
  384.     status = -ETIMEDOUT;
  385.     goto error;
  386.   }
  387.  error:
  388.   // shutdown i2c bus
  389.   vxp524_i2s_close(instance);
  390.   // OK
  391.   return(status);
  392. }