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

驱动编程

开发平台:

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. #include <asm/arch/gpio.h>
  36. #include <asm/arch/mfp.h>
  37. /* Addresses to scan */
  38. static unsigned short normal_i2c[] = { 0x10, 
  39. I2C_CLIENT_END };
  40. /* Insmod parameters */
  41. I2C_CLIENT_INSMOD_2(si4703, si4703a);
  42. /* Initial values */
  43. #define SI4703_INIT 255 /* All outputs on (input mode) */
  44. /* Each client has this additional data */
  45. struct si4703_data {
  46. struct i2c_client client;
  47. u8 write; /* Remember last written value */
  48. };
  49. static int si4703_attach_adapter(struct i2c_adapter *adapter);
  50. static int si4703_detect(struct i2c_adapter *adapter, int address, int kind);
  51. static int si4703_detach_client(struct i2c_client *client);
  52. static void si4703_init_client(struct i2c_client *client);
  53. /* This is the driver that will be inserted */
  54. static struct i2c_driver si4703_driver = {
  55. //.driver = {
  56. // .name = "si4703",
  57. //},
  58.     .owner = THIS_MODULE,
  59.     .flags = I2C_DF_NOTIFY,
  60.      .name = "SI4703",
  61. // .id = I2C_DRIVERID_SI4703,
  62. .attach_adapter = si4703_attach_adapter,
  63. .detach_client = si4703_detach_client,
  64. };
  65. static struct i2c_client *g_client = NULL;
  66. /* following are the sysfs callback functions */
  67. static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf)
  68. {
  69. struct i2c_client *client = to_i2c_client(dev);
  70. return sprintf(buf, "%un", i2c_smbus_read_byte(client));
  71. }
  72. static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
  73. static ssize_t show_write(struct device *dev, struct device_attribute *attr, char *buf)
  74. {
  75. struct si4703_data *data = i2c_get_clientdata(to_i2c_client(dev));
  76. return sprintf(buf, "%un", data->write);
  77. }
  78. static ssize_t set_write(struct device *dev, struct device_attribute *attr, const char *buf,
  79.  size_t count)
  80. {
  81. struct i2c_client *client = to_i2c_client(dev);
  82. struct si4703_data *data = i2c_get_clientdata(client);
  83. unsigned long val = simple_strtoul(buf, NULL, 10);
  84. if (val > 0xff)
  85. return -EINVAL;
  86. data->write = val;
  87. i2c_smbus_write_byte(client, data->write);
  88. return count;
  89. static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
  90. /*
  91.  * Real code
  92.  */
  93. //beck add it for si4703 int SI4703_I2C_Write( u8 *value, u8 size)
  94. {
  95. int res=0;
  96. // printk("%sn",__FUNCTION__);
  97. if( g_client == NULL )
  98. return -1;
  99. struct i2c_msg msgs[1] = 
  100.        {  g_client->addr, 0, size, value };
  101.    res=i2c_transfer(g_client->adapter,msgs,1);
  102.     if (res<=0) 
  103.        goto out;
  104. //res = i2c_master_send(g_client, buf, 2);
  105. //if (res >0) 
  106. // res =0;
  107. //else 
  108. // res =-1;
  109. //printk(KERN_INFO "In funtion %s addr:%x value:%xreturn %d n", __FUNCTION__, g_client->addr,value,res);
  110. return res;
  111. out:
  112.     printk(KERN_INFO "In funtion %s addr:%x,value=%xn", __FUNCTION__, g_client->addr,value);
  113.     if (res<=0) printk("res = %d n",res);
  114.     return res;
  115. }
  116. //beck add int SI4703_I2C_Read( u8 *pvalue, u8 size)
  117. {   
  118.     //printk("%sn",__FUNCTION__);
  119.     int res=0;
  120.    // char   buf=0;
  121.    // char buffer=0x0;
  122.     struct i2c_msg msgs[1] ={
  123.      // { addr, 0, 1, &buffer },
  124.        { g_client->addr, 1, size, pvalue}};
  125.  printk("%sn",__FUNCTION__);
  126.     if( g_client == NULL )   
  127.        return -1;
  128. //  i2c_ov9640_inc_use(g_client);
  129.    // msgs[0].addr=msgs[1].addr=g_client->addr;
  130. //msgs[0].addr=g_client->addr;
  131.     //res=i2c_transfer(g_client->adapter,&msgs[0],1);
  132.     //if (res<=0) 
  133.       // goto out;
  134.     res=i2c_transfer(g_client->adapter,msgs,1);
  135.     if (res<=0) 
  136.        goto out;
  137.   //  printk("%s--buf value=%xn",__FUNCTION__, buf);
  138.    // *pvalue=buf;
  139.  
  140.    // printk("%s-- pvalue=%xn",__FUNCTION__,*pvalue);
  141.     return 0;
  142. //  i2c_ov9640_dec_use(g_client);
  143. out:
  144.     printk(KERN_INFO "In funtion %s addr:%x,value=%xn", __FUNCTION__, g_client->addr,*pvalue);
  145.     if (res<=0) printk("res = %d n",res);
  146.     return res;
  147. }
  148. static int si4703_attach_adapter(struct i2c_adapter *adapter)
  149. {
  150. return i2c_probe(adapter, &addr_data, si4703_detect);
  151. }
  152. /* This function is called by i2c_probe */
  153. static int si4703_detect(struct i2c_adapter *adapter, int address, int kind)
  154. {
  155. struct i2c_client *new_client;
  156. struct si4703_data *data;
  157. int err = 0;
  158. const char *client_name = "";
  159. if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
  160. goto exit;
  161. /* OK. For now, we presume we have a valid client. We now create the
  162.    client structure, even though we cannot fill it completely yet. */
  163. if (!(data = kzalloc(sizeof(struct si4703_data), GFP_KERNEL))) {
  164. err = -ENOMEM;
  165. goto exit;
  166. }
  167. new_client = &data->client;
  168. i2c_set_clientdata(new_client, data);
  169. new_client->addr = address;
  170. new_client->adapter = adapter;
  171. new_client->driver = &si4703_driver;
  172. new_client->flags = 0;   g_client = new_client;
  173. /* Now, we would do the remaining detection. But the SI4703 is plainly
  174.    impossible to detect! Stupid chip. */
  175. /* Determine the chip type */
  176. //if (kind <= 0) {
  177. //if (address >= 0x38 && address <= 0x3f)
  178. // kind = si4703a;
  179. // else
  180. // kind = si4703;
  181. //}
  182. //if (kind == si4703a)
  183. // client_name = "si4703a";
  184. //else
  185. client_name = "si4703";
  186. /* Fill in the remaining client fields and put it into the global list */
  187. strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
  188. /* Tell the I2C layer a new client has arrived */
  189. if ((err = i2c_attach_client(new_client)))
  190. {printk("si4703  has been registered failed!n");goto exit_free;}
  191. else{printk("si4703  has been registered success!n");}
  192. /* Initialize the SI4703 chip */
  193. //si4703_init_client(new_client);
  194. /* Register sysfs hooks */
  195. device_create_file(&new_client->dev, &dev_attr_read);
  196. device_create_file(&new_client->dev, &dev_attr_write);
  197. return 0;
  198. /* OK, this is not exactly good programming practice, usually. But it is
  199.    very code-efficient in this case. */
  200.       exit_free:
  201. kfree(data);
  202.       exit:
  203. return err;
  204. }
  205. static int si4703_detach_client(struct i2c_client *client)
  206. {
  207. int err;
  208. if ((err = i2c_detach_client(client)))
  209. return err;
  210. kfree(i2c_get_clientdata(client));
  211. return 0;
  212. }
  213. /* Called when we have found a new SI4703. */
  214. static void si4703_init_client(struct i2c_client *client)
  215. {
  216. struct si4703_data *data = i2c_get_clientdata(client);
  217. data->write = SI4703_INIT;
  218. i2c_smbus_write_byte(client, data->write);
  219. }
  220. static int __init si4703_init(void)
  221. {          int res=0;     char buf[32];     int i;
  222. if ( (res = i2c_add_driver(&si4703_driver)) ) {
  223. printk("si4703: Driver registration failed, module not inserted.n");
  224. i2c_del_driver(&si4703_driver);
  225. return res;
  226. }
  227.      if(g_client != NULL)
  228.        printk("I2C: driver for device %s registed!.n", g_client->name);
  229.         else 
  230.            printk("I2C: driver for device si4703 unregisted!.n");
  231. //return i2c_add_driver(&si4703_driver);         //beck test
  232.   #if 0
  233.    enable_gpio_fm_pins();
  234.    mhn_gpio_set_level(MFP_PIN_GPIO123,GPIO_LEVEL_LOW);//pull FM_RST high
  235.    msleep(200);
  236.    mhn_gpio_set_level(MFP_PIN_GPIO123,GPIO_LEVEL_HIGH);//pull FM_RST high    msleep(200);    SI4703_I2C_Read( buf,  24);               for(i=0;i<24;i++)    printk("I2C: SI4703 register contents=%xn", buf[i]);
  237.  #endif
  238. }
  239. static void __exit si4703_exit(void)
  240. {
  241. i2c_del_driver(&si4703_driver);
  242. }
  243. MODULE_AUTHOR
  244.     ("Beck He<beck.he@quantacn.com>");
  245. MODULE_DESCRIPTION("SI4703 driver");
  246. MODULE_LICENSE("GPL"); EXPORT_SYMBOL(SI4703_I2C_Write);
  247. EXPORT_SYMBOL(SI4703_I2C_Read);
  248. module_init(si4703_init);
  249. module_exit(si4703_exit);