SI4703_I2C.c
上传用户:ledjyj
上传日期:2014-08-27
资源大小:2639k
文件大小:8k
源码类别:

驱动编程

开发平台:

Unix_Linux

  1. /*
  2.     si4703.c - Part of lm_sensors, Linux kernel modules for hardware
  3.              monitoring
  4.     Copyright (c) 2000  Frodo Looijaard <frodol@dds.nl>, 
  5.                         Philip Edelbrock <phil@netroedge.com>,
  6.                         Dan Eaton <dan.eaton@rocketlogix.com>
  7.     Ported to Linux 2.6 by Aurelien Jarno <aurel32@debian.org> with 
  8.     the help of Jean Delvare <khali@linux-fr.org>
  9.     This program is free software; you can redistribute it and/or modify
  10.     it under the terms of the GNU General Public License as published by
  11.     the Free Software Foundation; either version 2 of the License, or
  12.     (at your option) any later version.
  13.     
  14.     This program is distributed in the hope that it will be useful,
  15.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.     GNU General Public License for more details.
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program; if not, write to the Free Software
  20.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. /* A few notes about the SI4703:
  23. * The SI4703 is an 8-bit I/O expander for the I2C bus produced by
  24.   Philips Semiconductors.  It is designed to provide a byte I2C
  25.   interface to up to 8 separate devices.
  26.   
  27. * The SI4703 appears as a very simple SMBus device which can be
  28.   read from or written to with SMBUS byte read/write accesses.
  29.   --Dan
  30. */
  31. #include <linux/module.h>
  32. #include <linux/init.h>
  33. #include <linux/slab.h>
  34. #include <linux/i2c.h>
  35. /* Addresses to scan */
  36. static unsigned short normal_i2c[] = { 0x2a, 
  37. I2C_CLIENT_END };
  38. /* Insmod parameters */
  39. I2C_CLIENT_INSMOD_2(si4703, si4703a);
  40. /* Initial values */
  41. #define SI4703_INIT 255 /* All outputs on (input mode) */
  42. /* Each client has this additional data */
  43. struct si4703_data {
  44. struct i2c_client client;
  45. u8 write; /* Remember last written value */
  46. };
  47. static int si4703_attach_adapter(struct i2c_adapter *adapter);
  48. static int si4703_detect(struct i2c_adapter *adapter, int address, int kind);
  49. static int si4703_detach_client(struct i2c_client *client);
  50. static void si4703_init_client(struct i2c_client *client);
  51. /* This is the driver that will be inserted */
  52. static struct i2c_driver si4703_driver = {
  53. .driver = {
  54. .name = "si4703",
  55. },
  56. .id = I2C_DRIVERID_SI4703,
  57. .attach_adapter = si4703_attach_adapter,
  58. .detach_client = si4703_detach_client,
  59. };
  60. static struct i2c_client *g_client = NULL;
  61. /* following are the sysfs callback functions */
  62. static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf)
  63. {
  64. struct i2c_client *client = to_i2c_client(dev);
  65. return sprintf(buf, "%un", i2c_smbus_read_byte(client));
  66. }
  67. static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
  68. static ssize_t show_write(struct device *dev, struct device_attribute *attr, char *buf)
  69. {
  70. struct si4703_data *data = i2c_get_clientdata(to_i2c_client(dev));
  71. return sprintf(buf, "%un", data->write);
  72. }
  73. static ssize_t set_write(struct device *dev, struct device_attribute *attr, const char *buf,
  74.  size_t count)
  75. {
  76. struct i2c_client *client = to_i2c_client(dev);
  77. struct si4703_data *data = i2c_get_clientdata(client);
  78. unsigned long val = simple_strtoul(buf, NULL, 10);
  79. if (val > 0xff)
  80. return -EINVAL;
  81. data->write = val;
  82. i2c_smbus_write_byte(client, data->write);
  83. return count;
  84. }
  85. static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
  86. /*
  87.  * Real code
  88.  */
  89. //beck add it for si4703 int SI4703_I2C_Write( u8 *value, u8 size)
  90. {
  91. int res=0;
  92. // printk("%sn",__FUNCTION__);
  93. if( g_client == NULL )
  94. return -1;
  95. struct i2c_msg msgs[1] = 
  96.        {  g_client->addr, 0, size, value };
  97.    res=i2c_transfer(g_client->adapter,msgs,1);
  98.     if (res<=0) 
  99.        goto out;
  100. //res = i2c_master_send(g_client, buf, 2);
  101. //if (res >0) 
  102. // res =0;
  103. //else 
  104. // res =-1;
  105. printk(KERN_INFO "In funtion %s addr:%x value:%xreturn %d n", __FUNCTION__, g_client->addr,value,res);
  106. return res;
  107. out:
  108.     printk(KERN_INFO "In funtion %s addr:%x,value=%xn", __FUNCTION__, g_client->addr,value);
  109.     if (res<=0) printk("res = %d n",res);
  110.     return res;
  111. }
  112. //beck add int SI4703_I2C_Read( u8 *pvalue, u8 size)
  113. {   
  114.     //printk("%sn",__FUNCTION__);
  115.     int res=0;
  116.    // char   buf=0;
  117.    // char buffer=0x0;
  118.     struct i2c_msg msgs[1] ={
  119.      // { addr, 0, 1, &buffer },
  120.        { g_client->addr, 1, size, pvalue}};
  121.  printk("%sn",__FUNCTION__);
  122.     if( g_client == NULL )   
  123.        return -1;
  124. //  i2c_ov9640_inc_use(g_client);
  125.    // msgs[0].addr=msgs[1].addr=g_client->addr;
  126. //msgs[0].addr=g_client->addr;
  127.     //res=i2c_transfer(g_client->adapter,&msgs[0],1);
  128.     //if (res<=0) 
  129.       // goto out;
  130.     res=i2c_transfer(g_client->adapter,msgs,1);
  131.     if (res<=0) 
  132.        goto out;
  133.   //  printk("%s--buf value=%xn",__FUNCTION__, buf);
  134.    // *pvalue=buf;
  135.  
  136.     printk("%s-- pvalue=%xn",__FUNCTION__,*pvalue);
  137.     return 0;
  138. //  i2c_ov9640_dec_use(g_client);
  139. out:
  140.     printk(KERN_INFO "In funtion %s addr:%x,value=%xn", __FUNCTION__, g_client->addr,*pvalue);
  141.     if (res<=0) printk("res = %d n",res);
  142.     return res;
  143. }
  144. static int si4703_attach_adapter(struct i2c_adapter *adapter)
  145. {
  146. return i2c_probe(adapter, &addr_data, si4703_detect);
  147. }
  148. /* This function is called by i2c_probe */
  149. static int si4703_detect(struct i2c_adapter *adapter, int address, int kind)
  150. {
  151. struct i2c_client *new_client;
  152. struct si4703_data *data;
  153. int err = 0;
  154. const char *client_name = "";
  155. if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
  156. goto exit;
  157. /* OK. For now, we presume we have a valid client. We now create the
  158.    client structure, even though we cannot fill it completely yet. */
  159. if (!(data = kzalloc(sizeof(struct si4703_data), GFP_KERNEL))) {
  160. err = -ENOMEM;
  161. goto exit;
  162. }
  163. new_client = &data->client;
  164. i2c_set_clientdata(new_client, data);
  165. new_client->addr = address;
  166. new_client->adapter = adapter;
  167. new_client->driver = &si4703_driver;
  168. new_client->flags = 0;   g_client = new_client;
  169. /* Now, we would do the remaining detection. But the SI4703 is plainly
  170.    impossible to detect! Stupid chip. */
  171. /* Determine the chip type */
  172. //if (kind <= 0) {
  173. //if (address >= 0x38 && address <= 0x3f)
  174. // kind = si4703a;
  175. // else
  176. // kind = si4703;
  177. //}
  178. //if (kind == si4703a)
  179. // client_name = "si4703a";
  180. //else
  181. client_name = "si4703";
  182. /* Fill in the remaining client fields and put it into the global list */
  183. strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
  184. /* Tell the I2C layer a new client has arrived */
  185. if ((err = i2c_attach_client(new_client)))
  186. {printk("si4703  has been registered failed!n");goto exit_free;}
  187. else{printk("si4703  has been registered success!n");}
  188. /* Initialize the SI4703 chip */
  189. //si4703_init_client(new_client);
  190. /* Register sysfs hooks */
  191. device_create_file(&new_client->dev, &dev_attr_read);
  192. device_create_file(&new_client->dev, &dev_attr_write);
  193. return 0;
  194. /* OK, this is not exactly good programming practice, usually. But it is
  195.    very code-efficient in this case. */
  196.       exit_free:
  197. kfree(data);
  198.       exit:
  199. return err;
  200. }
  201. static int si4703_detach_client(struct i2c_client *client)
  202. {
  203. int err;
  204. if ((err = i2c_detach_client(client)))
  205. return err;
  206. kfree(i2c_get_clientdata(client));
  207. return 0;
  208. }
  209. /* Called when we have found a new SI4703. */
  210. static void si4703_init_client(struct i2c_client *client)
  211. {
  212. struct si4703_data *data = i2c_get_clientdata(client);
  213. data->write = SI4703_INIT;
  214. i2c_smbus_write_byte(client, data->write);
  215. }
  216. static int __init si4703_init(void)
  217. {          int res=0;
  218. if ( (res = i2c_add_driver(&si4703_driver)) ) {
  219. printk("pcf8574: Driver registration failed, module not inserted.n");
  220. i2c_del_driver(&si4703_driver);
  221. return res;
  222. }
  223.      if(g_client != NULL)
  224.        printk("I2C: driver for device %s registed!.n", g_client->name);
  225.         else 
  226.            printk("I2C: driver for device si4703 unregisted!.n");
  227. //return i2c_add_driver(&si4703_driver);
  228. }
  229. static void __exit si4703_exit(void)
  230. {
  231. i2c_del_driver(&si4703_driver);
  232. }
  233. MODULE_AUTHOR
  234.     ("Beck He<beck.he@quantacn.com>");
  235. MODULE_DESCRIPTION("SI4703 driver");
  236. MODULE_LICENSE("GPL"); EXPORT_SYMBOL(SI4703_I2C_Write);
  237. EXPORT_SYMBOL(SI4703_I2C_Read);
  238. module_init(si4703_init);
  239. module_exit(si4703_exit);