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

  1. /* ------------------------------------------------------------------------- */
  2. /* i2c-elv.c i2c-hw access for philips style parallel port adapters         */
  3. /* ------------------------------------------------------------------------- */
  4. /*   Copyright (C) 1995-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. /* With some changes from Ky÷sti MΣlkki <kmalkki@cc.hut.fi> and even
  22.    Frodo Looijaard <frodol@dds.nl> */
  23.  
  24. /* $Id: i2c-elv.c,v 1.2 2002/04/26 23:09:28 smilcke Exp $ */
  25.  
  26. #include <linux/kernel.h>
  27. #include <linux/module.h>
  28. #include <linux/delay.h>
  29. #include <linux/slab.h>
  30. #include <linux/version.h>
  31. #include <linux/init.h>
  32.  
  33. #include <asm/uaccess.h>
  34.  
  35. #include <linux/ioport.h>
  36. #include <asm/io.h>
  37. #include <linux/errno.h>
  38. #include <linux/i2c.h>
  39. #include <linux/i2c-algo-bit.h>
  40.  
  41. #define DEFAULT_BASE 0x378
  42. static int base=0;
  43. static unsigned char PortData = 0;
  44.  
  45. /* ----- global defines -----------------------------------------------    */
  46. #define DEB(x)        /* should be reasonable open, close &c.     */
  47. #define DEB2(x)     /* low level debugging - very slow         */
  48. #define DEBE(x)    x    /* error messages                 */
  49. #define DEBINIT(x) x    /* detection status messages            */
  50.  
  51. /* --- Convenience defines for the parallel port:            */
  52. #define BASE    (unsigned int)(data)
  53. #define DATA    BASE            /* Centronics data port        */
  54. #define STAT    (BASE+1)        /* Centronics status port    */
  55. #define CTRL    (BASE+2)        /* Centronics control port    */
  56.  
  57.  
  58. /* ----- local functions ----------------------------------------------    */
  59.  
  60.  
  61. static void bit_elv_setscl(void *data, int state)
  62. {
  63.     if (state) {
  64.         PortData &= 0xfe;
  65.     } else {
  66.         PortData |=1;
  67.     }
  68.     outb(PortData, DATA);
  69. }
  70.  
  71. static void bit_elv_setsda(void *data, int state)
  72. {
  73.     if (state) {
  74.         PortData &=0xfd;
  75.     } else {
  76.         PortData |=2;
  77.     }
  78.     outb(PortData, DATA);
  79.  
  80. static int bit_elv_getscl(void *data)
  81. {
  82.     return ( 0 == ( (inb_p(STAT)) & 0x08 ) );
  83. }
  84.  
  85. static int bit_elv_getsda(void *data)
  86. {
  87.     return ( 0 == ( (inb_p(STAT)) & 0x40 ) );
  88. }
  89.  
  90. static int bit_elv_init(void)
  91. {
  92.     if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) {
  93.         return -ENODEV;    
  94.     } else {
  95.                         /* test for ELV adap.     */
  96.         if (inb(base+1) & 0x80) {    /* BUSY should be high    */
  97.             DEBINIT(printk("i2c-elv.o: Busy was low.\n"));
  98.             return -ENODEV;
  99.         } else {
  100.             outb(0x0c,base+2);    /* SLCT auf low        */
  101.             udelay(400);
  102.             if ( !(inb(base+1) && 0x10) ) {
  103.                 outb(0x04,base+2);
  104.                 DEBINIT(printk("i2c-elv.o: Select was high.\n"));
  105.                 return -ENODEV;
  106.             }
  107.         }
  108.         request_region(base,(base == 0x3bc)? 3 : 8,
  109.             "i2c (ELV adapter)");
  110.         PortData = 0;
  111.         bit_elv_setsda((void*)base,1);
  112.         bit_elv_setscl((void*)base,1);
  113.     }
  114.     return 0;
  115. }
  116.  
  117. static void __exit bit_elv_exit(void)
  118. {
  119.     release_region( base , (base == 0x3bc)? 3 : 8 );
  120. }
  121.  
  122. static int bit_elv_reg(struct i2c_client *client)
  123. {
  124.     return 0;
  125. }
  126.  
  127. static int bit_elv_unreg(struct i2c_client *client)
  128. {
  129.     return 0;
  130. }
  131.  
  132. static void bit_elv_inc_use(struct i2c_adapter *adap)
  133. {
  134. #ifdef MODULE
  135.     MOD_INC_USE_COUNT;
  136. #endif
  137. }
  138.  
  139. static void bit_elv_dec_use(struct i2c_adapter *adap)
  140. {
  141. #ifdef MODULE
  142.     MOD_DEC_USE_COUNT;
  143. #endif
  144. }
  145.  
  146. /* ------------------------------------------------------------------------
  147.  * Encapsulate the above functions in the correct operations structure.
  148.  * This is only done when more than one hardware adapter is supported.
  149.  */
  150. static struct i2c_algo_bit_data bit_elv_data = {
  151.     NULL,
  152.     bit_elv_setsda,
  153.     bit_elv_setscl,
  154.     bit_elv_getsda,
  155.     bit_elv_getscl,
  156.     80, 80, 100,        /*    waits, timeout */
  157. };
  158.  
  159. static struct i2c_adapter bit_elv_ops = {
  160.     "ELV Parallel port adaptor",
  161.     I2C_HW_B_ELV,
  162.     NULL,
  163.     &bit_elv_data,
  164.     bit_elv_inc_use,
  165.     bit_elv_dec_use,
  166.     bit_elv_reg,
  167.     bit_elv_unreg,    
  168. };
  169.  
  170. int __init i2c_bitelv_init(void)
  171. {
  172.     printk("i2c-elv.o: i2c ELV parallel port adapter module\n");
  173.     if (base==0) {
  174.         /* probe some values */
  175.         base=DEFAULT_BASE;
  176.         bit_elv_data.data=(void*)DEFAULT_BASE;
  177.         if (bit_elv_init()==0) {
  178.             if(i2c_bit_add_bus(&bit_elv_ops) < 0)
  179.                 return -ENODEV;
  180.         } else {
  181.             return -ENODEV;
  182.         }
  183.     } else {
  184.         bit_elv_ops.data=(void*)base;
  185.         if (bit_elv_init()==0) {
  186.             if(i2c_bit_add_bus(&bit_elv_ops) < 0)
  187.                 return -ENODEV;
  188.         } else {
  189.             return -ENODEV;
  190.         }
  191.     }
  192.     printk("i2c-elv.o: found device at %#x.\n",base);
  193.     return 0;
  194. }
  195.  
  196.  
  197. EXPORT_NO_SYMBOLS;
  198.  
  199. #ifdef MODULE
  200. MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
  201. MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
  202. MODULE_LICENSE("GPL");
  203.  
  204.  
  205. MODULE_PARM(base, "i");
  206.  
  207. int init_module(void)
  208. {
  209.     return i2c_bitelv_init();
  210. }
  211.  
  212. void cleanup_module(void)
  213. {
  214.     i2c_bit_del_bus(&bit_elv_ops);
  215.     bit_elv_exit();
  216. }
  217.  
  218. #endif
  219.