home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lxapi32.zip / Linux / I2C / i2c-velleman.c < prev   
C/C++ Source or Header  |  2002-04-26  |  5KB  |  208 lines

  1. /* ------------------------------------------------------------------------- */
  2. /* i2c-velleman.c i2c-hw access for Velleman K9000 adapters             */
  3. /* ------------------------------------------------------------------------- */
  4. /*   Copyright (C) 1995-96, 2000 Simon G. Vogl
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             */
  19. /* ------------------------------------------------------------------------- */
  20.  
  21. /* $Id: i2c-velleman.c,v 1.2 2002/04/26 23:09:29 smilcke Exp $ */
  22.  
  23. #include <linux/kernel.h>
  24. #include <linux/ioport.h>
  25. #include <linux/module.h>
  26. #include <linux/init.h>
  27. #include <linux/string.h>  /* for 2.0 kernels to get NULL   */
  28. #include <asm/errno.h>     /* for 2.0 kernels to get ENODEV */
  29. #include <asm/io.h>
  30.  
  31. #include <linux/i2c.h>
  32. #include <linux/i2c-algo-bit.h>
  33.  
  34. /* ----- global defines -----------------------------------------------    */
  35. #define DEB(x)        /* should be reasonable open, close &c.     */
  36. #define DEB2(x)     /* low level debugging - very slow         */
  37. #define DEBE(x)    x    /* error messages                 */
  38.  
  39.                     /* Pin Port  Inverted    name    */
  40. #define I2C_SDA        0x02        /*  ctrl bit 1     (inv)    */
  41. #define I2C_SCL        0x08        /*  ctrl bit 3     (inv)    */
  42.  
  43. #define I2C_SDAIN    0x10        /* stat bit 4        */
  44. #define I2C_SCLIN    0x08        /* ctrl bit 3 (inv)(reads own output)*/
  45.  
  46. #define I2C_DMASK    0xfd
  47. #define I2C_CMASK    0xf7
  48.  
  49.  
  50. /* --- Convenience defines for the parallel port:            */
  51. #define BASE    (unsigned int)(data)
  52. #define DATA    BASE            /* Centronics data port        */
  53. #define STAT    (BASE+1)        /* Centronics status port    */
  54. #define CTRL    (BASE+2)        /* Centronics control port    */
  55.  
  56. #define DEFAULT_BASE 0x378
  57. static int base=0;
  58.  
  59. /* ----- local functions --------------------------------------------------- */
  60.  
  61. static void bit_velle_setscl(void *data, int state)
  62. {
  63.     if (state) {
  64.         outb(inb(CTRL) & I2C_CMASK,   CTRL);
  65.     } else {
  66.         outb(inb(CTRL) | I2C_SCL, CTRL);
  67.     }
  68.     
  69. }
  70.  
  71. static void bit_velle_setsda(void *data, int state)
  72. {
  73.     if (state) {
  74.         outb(inb(CTRL) & I2C_DMASK , CTRL);
  75.     } else {
  76.         outb(inb(CTRL) | I2C_SDA, CTRL);
  77.     }
  78.     
  79.  
  80. static int bit_velle_getscl(void *data)
  81. {
  82.     return ( 0 == ( (inb(CTRL)) & I2C_SCLIN ) );
  83. }
  84.  
  85. static int bit_velle_getsda(void *data)
  86. {
  87.     return ( 0 != ( (inb(STAT)) & I2C_SDAIN ) );
  88. }
  89.  
  90. static int bit_velle_init(void)
  91. {
  92.     if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) {
  93.         DEBE(printk("i2c-velleman.o: Port %#x already in use.\n",
  94.              base));
  95.         return -ENODEV;
  96.     } else {
  97.         request_region(base, (base == 0x3bc)? 3 : 8, 
  98.             "i2c (Vellemann adapter)");
  99.         bit_velle_setsda((void*)base,1);
  100.         bit_velle_setscl((void*)base,1);
  101.     }
  102.     return 0;
  103. }
  104.  
  105. static void __exit bit_velle_exit(void)
  106. {    
  107.     release_region( base , (base == 0x3bc)? 3 : 8 );
  108. }
  109.  
  110.  
  111. static int bit_velle_reg(struct i2c_client *client)
  112. {
  113.     return 0;
  114. }
  115.  
  116. static int bit_velle_unreg(struct i2c_client *client)
  117. {
  118.     return 0;
  119. }
  120.  
  121. static void bit_velle_inc_use(struct i2c_adapter *adap)
  122. {
  123. #ifdef MODULE
  124.     MOD_INC_USE_COUNT;
  125. #endif
  126. }
  127.  
  128. static void bit_velle_dec_use(struct i2c_adapter *adap)
  129. {
  130. #ifdef MODULE
  131.     MOD_DEC_USE_COUNT;
  132. #endif
  133. }
  134.  
  135. /* ------------------------------------------------------------------------
  136.  * Encapsulate the above functions in the correct operations structure.
  137.  * This is only done when more than one hardware adapter is supported.
  138.  */
  139.  
  140. static struct i2c_algo_bit_data bit_velle_data = {
  141.     NULL,
  142.     bit_velle_setsda,
  143.     bit_velle_setscl,
  144.     bit_velle_getsda,
  145.     bit_velle_getscl,
  146.     10, 10, 100,        /*    waits, timeout */
  147. };
  148.  
  149. static struct i2c_adapter bit_velle_ops = {
  150.     "Velleman K8000",
  151.     I2C_HW_B_VELLE,
  152.     NULL,
  153.     &bit_velle_data,
  154.     bit_velle_inc_use,
  155.     bit_velle_dec_use,
  156.     bit_velle_reg,
  157.     bit_velle_unreg,
  158. };
  159.  
  160. int __init  i2c_bitvelle_init(void)
  161. {
  162.     printk("i2c-velleman.o: i2c Velleman K8000 adapter module\n");
  163.     if (base==0) {
  164.         /* probe some values */
  165.         base=DEFAULT_BASE;
  166.         bit_velle_data.data=(void*)DEFAULT_BASE;
  167.         if (bit_velle_init()==0) {
  168.             if(i2c_bit_add_bus(&bit_velle_ops) < 0)
  169.                 return -ENODEV;
  170.         } else {
  171.             return -ENODEV;
  172.         }
  173.     } else {
  174.         bit_velle_data.data=(void*)base;
  175.         if (bit_velle_init()==0) {
  176.             if(i2c_bit_add_bus(&bit_velle_ops) < 0)
  177.                 return -ENODEV;
  178.         } else {
  179.             return -ENODEV;
  180.         }
  181.     }
  182.     printk("i2c-velleman.o: found device at %#x.\n",base);
  183.     return 0;
  184. }
  185.  
  186. EXPORT_NO_SYMBOLS;
  187.  
  188. #ifdef MODULE
  189. MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
  190. MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
  191. MODULE_LICENSE("GPL");
  192.  
  193. MODULE_PARM(base, "i");
  194.  
  195. int init_module(void) 
  196. {
  197.     return i2c_bitvelle_init();
  198. }
  199.  
  200. void cleanup_module(void) 
  201. {
  202.     i2c_bit_del_bus(&bit_velle_ops);
  203.     bit_velle_exit();
  204. }
  205.  
  206. #endif
  207.