i2c-velleman.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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