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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * I2C driver for parallel port
  3.  *
  4.  * Author: Phil Blundell <philb@gnu.org>
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License
  8.  * as published by the Free Software Foundation; either version
  9.  * 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This driver implements a simple I2C protocol by bit-twiddling some
  12.  * signals on the parallel port.  Since the outputs on the parallel port
  13.  * aren't open collector, three lines rather than two are used:
  14.  *
  15.  * D0 clock out
  16.  * D1 data out
  17.  * BUSY data in
  18.  */
  19. #include <linux/parport.h>
  20. #include <linux/module.h>
  21. #include <linux/delay.h>
  22. #include <linux/i2c-old.h>
  23. #include <linux/init.h>
  24. #include <linux/spinlock.h>
  25. #define I2C_DELAY   10
  26. static int debug = 0;
  27. struct parport_i2c_bus
  28. {
  29.   struct i2c_bus i2c;
  30.   struct parport_i2c_bus *next;
  31. };
  32. static struct parport_i2c_bus *bus_list;
  33. static spinlock_t bus_list_lock = SPIN_LOCK_UNLOCKED;
  34. /* software I2C functions */
  35. static void i2c_setlines(struct i2c_bus *bus, int clk, int data)
  36. {
  37.   struct parport *p = bus->data;
  38.   parport_write_data(p, (clk?1:0) | (data?2:0)); 
  39.   udelay(I2C_DELAY);
  40. }
  41. static int i2c_getdataline(struct i2c_bus *bus)
  42. {
  43.   struct parport *p = bus->data;
  44.   return (parport_read_status(p) & PARPORT_STATUS_BUSY) ? 0 : 1;
  45. }
  46. static struct i2c_bus parport_i2c_bus_template = 
  47. {
  48.   "...",
  49.   I2C_BUSID_PARPORT,
  50.   NULL,
  51.   
  52.   SPIN_LOCK_UNLOCKED,
  53.   
  54.   NULL,
  55.   NULL,
  56.   i2c_setlines,
  57.   i2c_getdataline,
  58.   NULL,
  59.   NULL,
  60. };
  61. static void i2c_parport_attach(struct parport *port)
  62. {
  63.   struct parport_i2c_bus *b = kmalloc(sizeof(struct parport_i2c_bus), 
  64.       GFP_KERNEL);
  65.   if (!b) {
  66.   printk(KERN_ERR "i2c_parport: Memory allocation failed. Not attaching.n");
  67.   return;
  68.   }
  69.   b->i2c = parport_i2c_bus_template;
  70.   b->i2c.data = parport_get_port (port);
  71.   strncpy(b->i2c.name, port->name, 32);
  72.   spin_lock(&bus_list_lock);
  73.   b->next = bus_list;
  74.   bus_list = b;
  75.   spin_unlock(&bus_list_lock);
  76.   i2c_register_bus(&b->i2c);
  77.   if (debug)
  78.     printk(KERN_DEBUG "i2c: attached to %sn", port->name);
  79. }
  80. static void i2c_parport_detach(struct parport *port)
  81. {
  82.   struct parport_i2c_bus *b, *old_b = NULL;
  83.   spin_lock(&bus_list_lock);
  84.   b = bus_list;
  85.   while (b)
  86.   {
  87.     if (b->i2c.data == port)
  88.     {
  89.       if (old_b)
  90. old_b->next = b->next;
  91.       else
  92. bus_list = b->next;
  93.       i2c_unregister_bus(&b->i2c);
  94.       kfree(b);
  95.       break;
  96.     }
  97.     old_b = b;
  98.     b = b->next;
  99.   }
  100.   spin_unlock(&bus_list_lock);
  101.   if (debug)
  102.     printk(KERN_DEBUG "i2c: detached from %sn", port->name);
  103. }
  104. static struct parport_driver parport_i2c_driver = 
  105. {
  106.   "i2c",
  107.   i2c_parport_attach,
  108.   i2c_parport_detach
  109. };
  110. #ifdef MODULE
  111. int init_module(void)
  112. #else
  113. int __init i2c_parport_init(void)
  114. #endif
  115. {
  116.   printk("I2C: driver for parallel port v0.1 philb@gnu.orgn");
  117.   parport_register_driver(&parport_i2c_driver);
  118.   return 0;
  119. }
  120. #ifdef MODULE
  121. MODULE_PARM(debug, "i");
  122. void cleanup_module(void)
  123. {
  124.   struct parport_i2c_bus *b = bus_list;
  125.   while (b)
  126.   {
  127.     struct parport_i2c_bus *next = b->next;
  128.     i2c_unregister_bus(&b->i2c);
  129.     kfree(b);
  130.     b = next;
  131.   }
  132.   parport_unregister_driver(&parport_i2c_driver);
  133. }
  134. #endif
  135. MODULE_LICENSE("GPL");