120 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| #include <linux/i2c.h>
 | |
| #include <linux/slab.h>
 | |
| #include "sf_mcu_dev.h"
 | |
| 
 | |
| #define MALLOC(x) kzalloc((x), GFP_KERNEL)
 | |
| #define FREE(x) kfree((x))
 | |
| 
 | |
| 
 | |
| #define __MODULE__          sf_i2c
 | |
| #define __DBGLVL__          2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER
 | |
| #define __DBGFLT__          "*" // *=All, [mark]=CustomClass
 | |
| #include "kwrap/debug.h"
 | |
| //#include <kwrap/debug.h>
 | |
| 
 | |
| 
 | |
| static struct i2c_board_info sf_i2c_device = {
 | |
| 	.type = SF_I2C_NAME,
 | |
| 	.addr = MCU_I2C_SLAVE_ADDR,
 | |
| };
 | |
| 
 | |
| typedef struct {
 | |
| 	struct i2c_client  *iic_client;
 | |
| 	struct i2c_adapter *iic_adapter;
 | |
| } SF_I2C_INFO;
 | |
| 
 | |
| static SF_I2C_INFO *sf_i2c_info;
 | |
| 
 | |
| static const struct i2c_device_id sf_i2c_id[] = {
 | |
| 	{ SF_I2C_NAME, 0 },
 | |
| 	{ }
 | |
| };
 | |
| 
 | |
| static int sf_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
 | |
| {
 | |
| 	sf_i2c_info = NULL;
 | |
| 	sf_i2c_info = MALLOC(sizeof(SF_I2C_INFO));
 | |
| 	if (sf_i2c_info == NULL) {
 | |
| 		DBG_ERR("%s fail: MALLOC not OK.\n", __FUNCTION__);
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	sf_i2c_info->iic_client  = client;
 | |
| 	sf_i2c_info->iic_adapter = client->adapter;
 | |
| 
 | |
| 	i2c_set_clientdata(client, sf_i2c_info);
 | |
| 	//printk(KERN_ERR "sf_i2c_probe!\r\n");
 | |
| 	DBG_DUMP("sf_i2c_probe!\r\n");
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int sf_i2c_remove(struct i2c_client *client)
 | |
| {
 | |
| 	FREE(sf_i2c_info);
 | |
| 	sf_i2c_info = NULL;
 | |
| 	//printk(KERN_ERR "sf_i2c_remove!\r\n");
 | |
| 	DBG_DUMP("sf_i2c_remove!\r\n");
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static struct i2c_driver sf_i2c_driver = {
 | |
| 	.driver = {
 | |
| 		.name  = SF_I2C_NAME,
 | |
| 		.owner = THIS_MODULE,
 | |
| 	},
 | |
| 	.probe    = sf_i2c_probe,
 | |
| 	.remove   = sf_i2c_remove,
 | |
| 	.id_table = sf_i2c_id
 | |
| };
 | |
| 
 | |
| ER sf_i2c_init_driver(UINT32 i2c_id)
 | |
| {
 | |
| 	ER ret = E_OK;
 | |
| 
 | |
| 	if (i2c_new_device(i2c_get_adapter(i2c_id), &sf_i2c_device) == NULL) {
 | |
| 		DBG_ERR("%s fail: i2c_new_device not OK.\n", __FUNCTION__);
 | |
| 		//printk(KERN_ERR "%s fail: i2c_new_device not OK.\n", __FUNCTION__);
 | |
| 	}
 | |
| 	if (i2c_add_driver(&sf_i2c_driver) != 0) {
 | |
| 		DBG_ERR("%s fail: i2c_add_driver not OK.\n", __FUNCTION__);
 | |
| 		//printk(KERN_ERR "%s fail: i2c_add_driver not OK.\n", __FUNCTION__);
 | |
| 	}
 | |
| 
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| void sf_i2c_remove_driver(UINT32 id)
 | |
| {
 | |
| 	i2c_unregister_device(sf_i2c_info->iic_client);
 | |
| 	i2c_del_driver(&sf_i2c_driver);
 | |
| }
 | |
| 
 | |
| INT32 sf_i2c_transfer(struct i2c_msg *msgs, INT32 num)
 | |
| {
 | |
| 	int ret;
 | |
| 
 | |
| 	if (unlikely(sf_i2c_info->iic_adapter == NULL)) {
 | |
| 		DBG_ERR("%s fail: sf_i2c_info->ii2c_adapter not OK\n", __FUNCTION__);
 | |
| 		//printk(KERN_ERR "%s fail: sf_i2c_info->ii2c_adapter not OK\n", __FUNCTION__);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| #if 0
 | |
| 	if (unlikely(i2c_transfer(sf_i2c_info->iic_adapter, msgs, num) != num)) {
 | |
| 		DBG_ERR("%s fail: i2c_transfer not OK \n", __FUNCTION__);
 | |
| 		//printk(KERN_ERR "%s fail: i2c_transfer not OK \n", __FUNCTION__);
 | |
| 		return -1;
 | |
| 	}
 | |
| #else
 | |
| 	ret = i2c_transfer(sf_i2c_info->iic_adapter, msgs, num);
 | |
| 	if (ret != num) {
 | |
| 		DBG_ERR("%s fail: i2c_transfer not OK, ret %d\n", __FUNCTION__, ret);
 | |
| 		//printk(KERN_ERR "%s fail: i2c_transfer not OK, ret %d\n", __FUNCTION__, ret);
 | |
| 		return -1;
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| 	return 0;
 | |
| }
 | 
