亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? iic.c

?? 嵌入式linux的IIC驅動
?? C
?? 第 1 頁 / 共 3 頁
字號:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/config.h>

#include <linux/i2c.h>

/* ----- compatibility stuff ----------------------------------------------- */

#include <linux/version.h>
#include <linux/init.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
#define init_MUTEX(s) do { *(s) = MUTEX; } while(0)
#endif

#include <asm/uaccess.h>

/* ----- global defines ---------------------------------------------------- */

/* exclusive access to the bus */
#define I2C_LOCK(adap) down(&adap->lock)
#define I2C_UNLOCK(adap) up(&adap->lock) 

#define ADAP_LOCK()	down(&adap_lock)
#define ADAP_UNLOCK()	up(&adap_lock)

#define DRV_LOCK()	down(&driver_lock)
#define DRV_UNLOCK()	up(&driver_lock)

#define DEB(x) if (i2c_debug>=1) x;
#define DEB2(x) if (i2c_debug>=2) x;

/* ----- global variables -------------------------------------------------- */

/**** lock for writing to global variables: the adapter & driver list */
struct semaphore adap_lock;
struct semaphore driver_lock;

/**** adapter list */
static struct i2c_adapter *adapters[I2C_ADAP_MAX];
static int adap_count;

/**** drivers list */
static struct i2c_driver *drivers[I2C_DRIVER_MAX];
static int driver_count;

/**** debug level */
static int i2c_debug = 0;

/* ---------------------------------------------------
 * /proc entry declarations
 *----------------------------------------------------
 */

#ifdef CONFIG_PROC_FS

static int i2cproc_init(void);
static void i2cproc_cleanup(void);

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27))
static void monitor_bus_i2c(struct inode *inode, int fill);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */

static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, 
                                loff_t *ppos);
static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
                           int *eof , void *private);

/* To implement the dynamic /proc/bus/i2c-? files, we need our own 
   implementation of the read hook */
static struct file_operations i2cproc_operations = {
	read:		i2cproc_bus_read,
};

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48))
static struct inode_operations i2cproc_inode_operations = {
	&i2cproc_operations
};
#endif

static int i2cproc_initialized = 0;

#else /* undef CONFIG_PROC_FS */

#define i2cproc_init() 0
#define i2cproc_cleanup() 0

#endif /* CONFIG_PROC_FS */


/* ---------------------------------------------------
 * registering functions 
 * --------------------------------------------------- 
 */

/* -----
 * i2c_add_adapter is called from within the algorithm layer,
 * when a new hw adapter registers. A new device is register to be
 * available for clients.
 */
int i2c_add_adapter(struct i2c_adapter *adap)
{
	int i,j,res;

	ADAP_LOCK();
	for (i = 0; i < I2C_ADAP_MAX; i++)
		if (NULL == adapters[i])
			break;
	if (I2C_ADAP_MAX == i) {
		printk(KERN_WARNING 
		       " i2c-core.o: register_adapter(%s) - enlarge I2C_ADAP_MAX.\n",
			adap->name);
		res = -ENOMEM;
		goto ERROR0;
	}

	adapters[i] = adap;
	adap_count++;
	ADAP_UNLOCK();
	
	/* init data types */
	init_MUTEX(&adap->lock);

#ifdef CONFIG_PROC_FS

	if (i2cproc_initialized) {
		char name[8];
		struct proc_dir_entry *proc_entry;

		sprintf(name,"i2c-%d", i);

		proc_entry = create_proc_entry(name,0,proc_bus);
		if (! proc_entry) {
			printk("i2c-core.o: Could not create /proc/bus/%s\n",
			       name);
			res = -ENOENT;
			goto ERROR1;
		}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,48))
		proc_entry->proc_fops = &i2cproc_operations;
#else
		proc_entry->ops = &i2cproc_inode_operations;
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
		proc_entry->owner = THIS_MODULE;
#else
		proc_entry->fill_inode = &monitor_bus_i2c;
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
		adap->inode = proc_entry->low_ino;
	}

#endif /* def CONFIG_PROC_FS */

	/* inform drivers of new adapters */
	DRV_LOCK();	
	for (j=0;j<I2C_DRIVER_MAX;j++)
		if (drivers[j]!=NULL && 
		    (drivers[j]->flags&(I2C_DF_NOTIFY|I2C_DF_DUMMY)))
			/* We ignore the return code; if it fails, too bad */
			drivers[j]->attach_adapter(adap);
	DRV_UNLOCK();
	
	DEB(printk("i2c-core.o: adapter %s registered as adapter %d.\n",
	           adap->name,i));

	return 0;	


ERROR1:
	ADAP_LOCK();
	adapters[i] = NULL;
	adap_count--;
ERROR0:
	ADAP_UNLOCK();
	return res;
}


int i2c_del_adapter(struct i2c_adapter *adap)
{
	int i,j,res;

	ADAP_LOCK();

	for (i = 0; i < I2C_ADAP_MAX; i++)
		if (adap == adapters[i])
			break;
	if (I2C_ADAP_MAX == i) {
		printk( "i2c-core.o: unregister_adapter adap [%s] not found.\n",
			adap->name);
		res = -ENODEV;
		goto ERROR0;
	}

	/* DUMMY drivers do not register their clients, so we have to
	 * use a trick here: we call driver->attach_adapter to
	 * *detach* it! Of course, each dummy driver should know about
	 * this or hell will break loose...
	 */
	DRV_LOCK();
	for (j = 0; j < I2C_DRIVER_MAX; j++) 
		if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY))
			if ((res = drivers[j]->attach_adapter(adap))) {
				printk("i2c-core.o: can't detach adapter %s "
				       "while detaching driver %s: driver not "
				       "detached!",adap->name,drivers[j]->name);
				goto ERROR1;	
			}
	DRV_UNLOCK();


	/* detach any active clients. This must be done first, because
	 * it can fail; in which case we give upp. */
	for (j=0;j<I2C_CLIENT_MAX;j++) {
		struct i2c_client *client = adap->clients[j];
		if (client!=NULL)
		    /* detaching devices is unconditional of the set notify
		     * flag, as _all_ clients that reside on the adapter
		     * must be deleted, as this would cause invalid states.
		     */
			if ((res=client->driver->detach_client(client))) {
				printk("i2c-core.o: adapter %s not "
					"unregistered, because client at "
					"address %02x can't be detached. ",
					adap->name, client->addr);
				goto ERROR0;
			}
	}
#ifdef CONFIG_PROC_FS
	if (i2cproc_initialized) {
		char name[8];
		sprintf(name,"i2c-%d", i);
		remove_proc_entry(name,proc_bus);
	}
#endif /* def CONFIG_PROC_FS */

	adapters[i] = NULL;
	adap_count--;
	
	ADAP_UNLOCK();	
	DEB(printk("i2c-core.o: adapter unregistered: %s\n",adap->name));
	return 0;

ERROR0:
	ADAP_UNLOCK();
	return res;
ERROR1:
	DRV_UNLOCK();
	return res;
}


/* -----
 * What follows is the "upwards" interface: commands for talking to clients,
 * which implement the functions to access the physical information of the
 * chips.
 */

int i2c_add_driver(struct i2c_driver *driver)
{
	int i;
	DRV_LOCK();
	for (i = 0; i < I2C_DRIVER_MAX; i++)
		if (NULL == drivers[i])
			break;
	if (I2C_DRIVER_MAX == i) {
		printk(KERN_WARNING 
		       " i2c-core.o: register_driver(%s) "
		       "- enlarge I2C_DRIVER_MAX.\n",
			driver->name);
		DRV_UNLOCK();
		return -ENOMEM;
	}

	drivers[i] = driver;
	driver_count++;
	
	DRV_UNLOCK();	/* driver was successfully added */
	
	DEB(printk("i2c-core.o: driver %s registered.\n",driver->name));
	
	ADAP_LOCK();

	/* now look for instances of driver on our adapters
	 */
	if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
		for (i=0;i<I2C_ADAP_MAX;i++)
			if (adapters[i]!=NULL)
				/* Ignore errors */
				driver->attach_adapter(adapters[i]);
	}
	ADAP_UNLOCK();
	return 0;
}

int i2c_del_driver(struct i2c_driver *driver)
{
	int i,j,k,res;

	DRV_LOCK();
	for (i = 0; i < I2C_DRIVER_MAX; i++)
		if (driver == drivers[i])
			break;
	if (I2C_DRIVER_MAX == i) {
		printk(KERN_WARNING " i2c-core.o: unregister_driver: "
				    "[%s] not found\n",
			driver->name);
		DRV_UNLOCK();
		return -ENODEV;
	}
	/* Have a look at each adapter, if clients of this driver are still
	 * attached. If so, detach them to be able to kill the driver 
	 * afterwards.
	 */
	DEB2(printk("i2c-core.o: unregister_driver - looking for clients.\n"));
	/* removing clients does not depend on the notify flag, else 
	 * invalid operation might (will!) result, when using stale client
	 * pointers.
	 */
	ADAP_LOCK(); /* should be moved inside the if statement... */
	for (k=0;k<I2C_ADAP_MAX;k++) {
		struct i2c_adapter *adap = adapters[k];
		if (adap == NULL) /* skip empty entries. */
			continue;
		DEB2(printk("i2c-core.o: examining adapter %s:\n",
			    adap->name));
		if (driver->flags & I2C_DF_DUMMY) {
		/* DUMMY drivers do not register their clients, so we have to
		 * use a trick here: we call driver->attach_adapter to
		 * *detach* it! Of course, each dummy driver should know about
		 * this or hell will break loose...  
		 */
			if ((res = driver->attach_adapter(adap))) {
				printk("i2c-core.o: while unregistering "
				       "dummy driver %s, adapter %s could "
				       "not be detached properly; driver "
				       "not unloaded!",driver->name,
				       adap->name);
				ADAP_UNLOCK();
				return res;
			}
		} else {
			for (j=0;j<I2C_CLIENT_MAX;j++) { 
				struct i2c_client *client = adap->clients[j];
				if (client != NULL && 
				    client->driver == driver) {
					DEB2(printk("i2c-core.o: "
						    "detaching client %s:\n",
					            client->name));
					if ((res = driver->
							detach_client(client)))
					{
						printk("i2c-core.o: while "
						       "unregistering driver "
						       "`%s', the client at "
						       "address %02x of
						       adapter `%s' could not
						       be detached; driver
						       not unloaded!",
						       driver->name,
						       client->addr,
						       adap->name);
						ADAP_UNLOCK();
						return res;
					}
				}
			}
		}
	}
	ADAP_UNLOCK();
	drivers[i] = NULL;
	driver_count--;
	DRV_UNLOCK();
	
	DEB(printk("i2c-core.o: driver unregistered: %s\n",driver->name));
	return 0;
}

int i2c_check_addr (struct i2c_adapter *adapter, int addr)
{
	int i;
	for (i = 0; i < I2C_CLIENT_MAX ; i++) 
		if (adapter->clients[i] && (adapter->clients[i]->addr == addr))
			return -EBUSY;
	return 0;
}

int i2c_attach_client(struct i2c_client *client)
{
	struct i2c_adapter *adapter = client->adapter;
	int i;

	if (i2c_check_addr(client->adapter,client->addr))
		return -EBUSY;

	for (i = 0; i < I2C_CLIENT_MAX; i++)
		if (NULL == adapter->clients[i])
			break;
	if (I2C_CLIENT_MAX == i) {
		printk(KERN_WARNING 
		       " i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n",
			client->name);
		return -ENOMEM;
	}

	adapter->clients[i] = client;
	adapter->client_count++;
	
	if (adapter->client_register) 
		if (adapter->client_register(client)) 
			printk("i2c-core.o: warning: client_register seems "
			       "to have failed for client %02x at adapter %s\n",
			       client->addr,adapter->name);
	DEB(printk("i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n",
		client->name, adapter->name,i));

	if(client->flags & I2C_CLIENT_ALLOW_USE)
		client->usage_count = 0;
	
	return 0;
}


int i2c_detach_client(struct i2c_client *client)
{
	struct i2c_adapter *adapter = client->adapter;
	int i,res;

	for (i = 0; i < I2C_CLIENT_MAX; i++)

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲一二三四久久| 亚洲综合在线观看视频| 欧美日韩1区2区| 欧美在线观看一二区| 在线亚洲+欧美+日本专区| 欧美亚洲综合在线| 欧美日韩一本到| 7777精品伊人久久久大香线蕉超级流畅| 91官网在线观看| 欧美一区二区成人| 久久这里只有精品首页| 亚洲国产精品激情在线观看| 中文字幕一区二区三| 1000部国产精品成人观看| 亚洲欧美偷拍三级| 亚洲第一主播视频| 久久99蜜桃精品| 成人av电影观看| 欧美日韩国产首页在线观看| 日韩女优毛片在线| 国产精品久久久久久一区二区三区| 国产精品毛片a∨一区二区三区 | 欧美精品久久天天躁| 日韩一级黄色片| 国产女人18毛片水真多成人如厕 | 午夜国产精品影院在线观看| 国产呦萝稀缺另类资源| 国产91精品一区二区麻豆亚洲| 不卡av电影在线播放| 欧美日韩成人在线一区| 国产午夜精品理论片a级大结局 | 欧美日韩在线一区二区| 日韩一区二区免费高清| 国产精品免费av| 日本vs亚洲vs韩国一区三区二区 | 日韩精品一区二区三区视频播放 | 波多野结衣在线一区| 欧美日韩美女一区二区| 国产精品污污网站在线观看| 亚洲线精品一区二区三区| 国产精品亚洲第一区在线暖暖韩国| 91麻豆蜜桃一区二区三区| 3d成人h动漫网站入口| 中文字幕av在线一区二区三区| 亚洲成av人综合在线观看| 成人国产精品免费网站| 欧美高清dvd| 亚洲精品日韩综合观看成人91| 久久99精品久久久久久国产越南| 色吧成人激情小说| 久久久久久久综合日本| 水蜜桃久久夜色精品一区的特点 | 亚洲影院久久精品| 成人亚洲一区二区一| 精品999久久久| 日韩精品免费视频人成| 欧洲一区在线电影| 中文字幕一区三区| 国产大陆a不卡| 精品国产成人在线影院 | 亚洲视频精选在线| 国模一区二区三区白浆| 日韩欧美亚洲另类制服综合在线| 一区二区在线看| 色88888久久久久久影院按摩| 中文字幕不卡在线播放| 国产在线看一区| 精品国产制服丝袜高跟| 久久99国产乱子伦精品免费| 91精品国产综合久久婷婷香蕉| 亚洲h在线观看| 欧美日高清视频| 日韩国产精品久久久| 777午夜精品免费视频| 日韩国产在线一| 在线不卡一区二区| 日韩avvvv在线播放| 91麻豆精品国产综合久久久久久| 五月综合激情网| 欧美一级理论片| 九一九一国产精品| 久久精品一区二区三区不卡牛牛| 国产精品99久久久久久久vr| 国产亚洲一区二区在线观看| 大陆成人av片| 一区二区三区在线观看网站| 欧美性感一区二区三区| 亚洲电影你懂得| 欧美成人a在线| 成人在线综合网| 亚洲欧美乱综合| 欧美精品v日韩精品v韩国精品v| 蜜臀av亚洲一区中文字幕| 精品国产乱码久久久久久1区2区 | 亚洲精品中文字幕在线观看| 欧日韩精品视频| 免费成人小视频| 国产精品区一区二区三区| 日本道免费精品一区二区三区| 午夜影院在线观看欧美| 亚洲精品一区二区精华| 91免费在线视频观看| 日本不卡中文字幕| 欧美国产精品v| 欧美一a一片一级一片| 国产在线国偷精品产拍免费yy| 中文字幕不卡一区| 欧美一区日本一区韩国一区| 国产精品99久久久久久久vr| 亚洲一区在线观看网站| 久久夜色精品国产噜噜av| 色国产精品一区在线观看| 九九**精品视频免费播放| 一区二区三区免费网站| 精品欧美一区二区在线观看| 日本道色综合久久| 国产盗摄精品一区二区三区在线| 亚洲午夜av在线| 国产人伦精品一区二区| 欧美一区二区美女| 色综合天天综合网天天看片| 久久国产生活片100| 亚洲人成网站精品片在线观看| 日韩欧美在线网站| 欧美视频在线一区二区三区 | 国产大陆亚洲精品国产| 亚洲国产精品久久不卡毛片| 国产精品三级久久久久三级| 日韩免费观看2025年上映的电影| 91高清视频免费看| 99久久精品国产网站| 国产老肥熟一区二区三区| 婷婷久久综合九色国产成人| 亚洲色欲色欲www| 亚洲国产成人在线| 久久精品视频网| 日韩欧美一区电影| 91精品福利在线一区二区三区| 日本福利一区二区| av不卡在线播放| 成人av在线网站| av中文一区二区三区| 国产高清成人在线| 国产精品资源在线观看| 国产一区二区三区四区五区美女 | 欧美日韩亚洲综合| 欧美中文字幕一二三区视频| 91在线视频观看| 色悠久久久久综合欧美99| 97se狠狠狠综合亚洲狠狠| 99久久婷婷国产| 99久久夜色精品国产网站| av中文字幕在线不卡| 99精品国产91久久久久久| 99久久综合狠狠综合久久| 波多野结衣亚洲一区| 一本色道a无线码一区v| 色999日韩国产欧美一区二区| 91福利精品第一导航| 欧美日韩一区二区三区不卡| 884aa四虎影成人精品一区| 欧美一区二区女人| 久久亚洲二区三区| 成人欧美一区二区三区在线播放| 亚洲免费资源在线播放| 亚洲国产精品自拍| 日本色综合中文字幕| 国产在线一区观看| 97久久精品人人做人人爽| 在线视频国内自拍亚洲视频| 51久久夜色精品国产麻豆| 精品成人免费观看| 亚洲欧洲成人精品av97| 一区二区欧美视频| 精品一区二区影视| av中文字幕一区| 91精品国产色综合久久| 久久精品亚洲一区二区三区浴池| 最新不卡av在线| 日韩电影在线观看网站| 成人av动漫在线| 制服丝袜激情欧洲亚洲| 国产欧美日韩麻豆91| 亚洲伊人色欲综合网| 国产福利一区在线| 欧美影院一区二区三区| 久久久久国产成人精品亚洲午夜| 日韩理论片在线| 国产一区在线观看视频| 日本久久一区二区| 久久综合九色综合欧美亚洲| 亚洲精品国产品国语在线app| 久久精品国产成人一区二区三区| 国产a级毛片一区| 日韩一区二区三区视频在线| 国产精品久久精品日日| 精品系列免费在线观看| 欧美丝袜第三区| 1区2区3区欧美| 国产成人无遮挡在线视频|