i2c-velleman.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

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. MOD_INC_USE_COUNT;
  98. }
  99. static void bit_velle_dec_use(struct i2c_adapter *adap)
  100. {
  101. MOD_DEC_USE_COUNT;
  102. }
  103. /* ------------------------------------------------------------------------
  104.  * Encapsulate the above functions in the correct operations structure.
  105.  * This is only done when more than one hardware adapter is supported.
  106.  */
  107. static struct i2c_algo_bit_data bit_velle_data = {
  108. NULL,
  109. bit_velle_setsda,
  110. bit_velle_setscl,
  111. bit_velle_getsda,
  112. bit_velle_getscl,
  113. 10, 10, 100, /* waits, timeout */
  114. };
  115. static struct i2c_adapter bit_velle_ops = {
  116. "Velleman K8000",
  117. I2C_HW_B_VELLE,
  118. NULL,
  119. &bit_velle_data,
  120. bit_velle_inc_use,
  121. bit_velle_dec_use,
  122. bit_velle_reg,
  123. bit_velle_unreg,
  124. };
  125. static int __init i2c_bitvelle_init(void)
  126. {
  127. printk("i2c-velleman.o: i2c Velleman K8000 adapter modulen");
  128. if (base==0) {
  129. /* probe some values */
  130. base=DEFAULT_BASE;
  131. bit_velle_data.data=(void*)DEFAULT_BASE;
  132. if (bit_velle_init()==0) {
  133. if(i2c_bit_add_bus(&bit_velle_ops) < 0)
  134. return -ENODEV;
  135. } else {
  136. return -ENODEV;
  137. }
  138. } else {
  139. bit_velle_data.data=(void*)base;
  140. if (bit_velle_init()==0) {
  141. if(i2c_bit_add_bus(&bit_velle_ops) < 0)
  142. return -ENODEV;
  143. } else {
  144. return -ENODEV;
  145. }
  146. }
  147. printk("i2c-velleman.o: found device at %#x.n",base);
  148. return 0;
  149. }
  150. static void __exit i2c_bitvelle_exit(void)
  151. {
  152. i2c_bit_del_bus(&bit_velle_ops);
  153. bit_velle_exit();
  154. }
  155. EXPORT_NO_SYMBOLS;
  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. module_init(i2c_bitvelle_init);
  161. module_exit(i2c_bitvelle_exit);