⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 VGA 转换 Tv Out源代码,在型号为 Matrox G400Dh的显示卡的基础上编程
💻 C
字号:
/* *	Generic i2c interface for linux * *	(c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de> * */#ifdef __KERNEL__#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/string.h>#include <linux/delay.h>#include <linux/locks.h>#include <linux/sched.h>#include <linux/malloc.h>#include <linux/i2c.h>#else#include "kspace.h"#include "kernel/i2c.h"#endif#define REGPRINT(x)   if (verbose)   (x)#define I2C_DEBUG(x)  if (i2c_debug) (x)static int scan      = 0;static int verbose   = 0;static int i2c_debug = 0;#if LINUX_VERSION_CODE >= 0x020117MODULE_PARM(scan,"i");MODULE_PARM(verbose,"i");MODULE_PARM(i2c_debug,"i");#endif/* ----------------------------------------------------------------------- */static struct i2c_bus    *busses[I2C_BUS_MAX];static struct i2c_driver *drivers[I2C_DRIVER_MAX];static int bus_count = 0, driver_count = 0;#ifdef CONFIG_VIDEO_BT848extern int i2c_tuner_init(void);extern int msp3400c_init(void);#endif#ifdef CONFIG_VIDEO_BUZextern int saa7111_init(void);extern int saa7185_init(void);#endif#ifdef CONFIG_VIDEO_LML33extern int bt819_init(void);extern int bt856_init(void);#endifint i2c_init(void){	printk(KERN_INFO "i2c: initialized%s\n",		scan ? " (i2c bus scan enabled)" : "");	/* anything to do here ? */#ifdef CONFIG_VIDEO_BT848	i2c_tuner_init();	msp3400c_init();#endif	#ifdef CONFIG_VIDEO_BUZ	saa7111_init();	saa7185_init();#endif#ifdef CONFIG_VIDEO_LML33	bt819_init();	bt856_init();#endif	return 0;}/* ----------------------------------------------------------------------- */static void i2c_attach_device(struct i2c_bus *bus, struct i2c_driver *driver){	struct i2c_device *device;	int i,j,ack=1;	unsigned char addr;	LOCK_FLAGS;    	/* probe for device */	LOCK_I2C_BUS(bus);	for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2) 	{		i2c_start(bus);		ack = i2c_sendbyte(bus,addr,0);		i2c_stop(bus);		if (!ack)			break;	}	UNLOCK_I2C_BUS(bus);	if (ack)		return;	/* got answer */	for (i = 0; i < I2C_DEVICE_MAX; i++)		if (NULL == driver->devices[i])			break;	if (I2C_DEVICE_MAX == i)		return;	for (j = 0; j < I2C_DEVICE_MAX; j++)		if (NULL == bus->devices[j])			break;	if (I2C_DEVICE_MAX == j)		return;	if (NULL == (device = kmalloc(sizeof(struct i2c_device),GFP_KERNEL)))		return;	device->bus = bus;	device->driver = driver;	device->addr = addr;	/* Attach */		if (driver->attach(device)!=0) 	{		kfree(device);		return;	}	driver->devices[i] = device;	driver->devcount++;	bus->devices[j] = device;	bus->devcount++;	if (bus->attach_inform)		bus->attach_inform(bus,driver->id);	REGPRINT(printk("i2c: device attached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,addr,bus->name,driver->name));}static void i2c_detach_device(struct i2c_device *device){	int i;	if (device->bus->detach_inform)		device->bus->detach_inform(device->bus,device->driver->id);	device->driver->detach(device);	for (i = 0; i < I2C_DEVICE_MAX; i++)		if (device == device->driver->devices[i])			break;	if (I2C_DEVICE_MAX == i) 	{		printk(KERN_WARNING "i2c: detach_device #1: device not found: %s\n",			device->name);		return;	}	device->driver->devices[i] = NULL;	device->driver->devcount--;	for (i = 0; i < I2C_DEVICE_MAX; i++)		if (device == device->bus->devices[i])			break;	if (I2C_DEVICE_MAX == i) 	{		printk(KERN_WARNING "i2c: detach_device #2: device not found: %s\n",		       device->name);		return;	}	device->bus->devices[i] = NULL;	device->bus->devcount--;	REGPRINT(printk("i2c: device detached: %s (addr=0x%02x, bus=%s, driver=%s)\n",device->name,device->addr,device->bus->name,device->driver->name));	kfree(device);}/* ----------------------------------------------------------------------- */int i2c_register_bus(struct i2c_bus *bus){	int i,ack;	LOCK_FLAGS;	memset(bus->devices,0,sizeof(bus->devices));	bus->devcount = 0;	for (i = 0; i < I2C_BUS_MAX; i++)		if (NULL == busses[i])			break;	if (I2C_BUS_MAX == i)		return -ENOMEM;	busses[i] = bus;	bus_count++;	REGPRINT(printk("i2c: bus registered: %s\n",bus->name));		MOD_INC_USE_COUNT;	if (scan) 	{		/* scan whole i2c bus */		LOCK_I2C_BUS(bus);		for (i = 0; i < 256; i+=2) 		{			i2c_start(bus);			ack = i2c_sendbyte(bus,i,0);			i2c_stop(bus);			if (!ack) 			{				printk(KERN_INFO "i2c: scanning bus %s: found device at addr=0x%02x\n",					bus->name,i);			}		}		UNLOCK_I2C_BUS(bus);	}	/* probe available drivers */	for (i = 0; i < I2C_DRIVER_MAX; i++)		if (drivers[i])			i2c_attach_device(bus,drivers[i]);	return 0;}int i2c_unregister_bus(struct i2c_bus *bus){	int i;	/* detach devices */	for (i = 0; i < I2C_DEVICE_MAX; i++)		if (bus->devices[i])			i2c_detach_device(bus->devices[i]);	for (i = 0; i < I2C_BUS_MAX; i++)		if (bus == busses[i])			break;	if (I2C_BUS_MAX == i) 	{		printk(KERN_WARNING "i2c: unregister_bus #1: bus not found: %s\n",			bus->name);		return -ENODEV;	}		MOD_DEC_USE_COUNT;		busses[i] = NULL;	bus_count--;	REGPRINT(printk("i2c: bus unregistered: %s\n",bus->name));	return 0;    }/* ----------------------------------------------------------------------- */int i2c_register_driver(struct i2c_driver *driver){	int i;	memset(driver->devices,0,sizeof(driver->devices));	driver->devcount = 0;	for (i = 0; i < I2C_DRIVER_MAX; i++)		if (NULL == drivers[i])			break;	if (I2C_DRIVER_MAX == i)		return -ENOMEM;	drivers[i] = driver;	driver_count++;		MOD_INC_USE_COUNT;		REGPRINT(printk("i2c: driver registered: %s\n",driver->name));	/* Probe available busses */	for (i = 0; i < I2C_BUS_MAX; i++)		if (busses[i])			i2c_attach_device(busses[i],driver);	return 0;}int i2c_unregister_driver(struct i2c_driver *driver){	int i;	/* detach devices */	for (i = 0; i < I2C_DEVICE_MAX; i++)		if (driver->devices[i])			i2c_detach_device(driver->devices[i]);	for (i = 0; i < I2C_DRIVER_MAX; i++)		if (driver == drivers[i])			break;	if (I2C_DRIVER_MAX == i) 	{		printk(KERN_WARNING "i2c: unregister_driver: driver not found: %s\n",			driver->name);		return -ENODEV;	}	MOD_DEC_USE_COUNT;		drivers[i] = NULL;	driver_count--;	REGPRINT(printk("i2c: driver unregistered: %s\n",driver->name));	return 0;}/* ----------------------------------------------------------------------- */int i2c_control_device(struct i2c_bus *bus, int id,		       unsigned int cmd, void *arg){	int i;	for (i = 0; i < I2C_DEVICE_MAX; i++)		if (bus->devices[i] && bus->devices[i]->driver->id == id)			break;	if (i == I2C_DEVICE_MAX)		return -ENODEV;	if (NULL == bus->devices[i]->driver->command)		return -ENODEV;	return bus->devices[i]->driver->command(bus->devices[i],cmd,arg);}/* ----------------------------------------------------------------------- */#define I2C_SET(bus,ctrl,data)  (bus->i2c_setlines(bus,ctrl,data))#define I2C_GET(bus)            (bus->i2c_getdataline(bus))void i2c_start(struct i2c_bus *bus){	I2C_SET(bus,0,1);	I2C_SET(bus,1,1);	I2C_SET(bus,1,0);	I2C_SET(bus,0,0);	I2C_DEBUG(printk("%s: < ",bus->name));}void i2c_stop(struct i2c_bus *bus){	I2C_SET(bus,0,0);	I2C_SET(bus,1,0);	I2C_SET(bus,1,1);	I2C_DEBUG(printk(">\n"));}void i2c_one(struct i2c_bus *bus){	I2C_SET(bus,0,1);	I2C_SET(bus,1,1);	I2C_SET(bus,0,1);}void i2c_zero(struct i2c_bus *bus){	I2C_SET(bus,0,0);	I2C_SET(bus,1,0);	I2C_SET(bus,0,0);}int i2c_ack(struct i2c_bus *bus){	int ack;    	I2C_SET(bus,0,1);	I2C_SET(bus,1,1);	ack = I2C_GET(bus);	I2C_SET(bus,0,1);	return ack;}int i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack){	int i, ack;    	I2C_SET(bus,0,0);	for (i=7; i>=0; i--)		(data&(1<<i)) ? i2c_one(bus) : i2c_zero(bus);	if (wait_for_ack)		udelay(wait_for_ack);	ack=i2c_ack(bus);	I2C_DEBUG(printk("%02x%c ",(int)data,ack?'-':'+'));	return ack;}unsigned char i2c_readbyte(struct i2c_bus *bus,int last){	int i;	unsigned char data=0;    	I2C_SET(bus,0,1);	for (i=7; i>=0; i--) 	{		I2C_SET(bus,1,1);		if (I2C_GET(bus))			data |= (1<<i);		I2C_SET(bus,0,1);	}	last ? i2c_one(bus) : i2c_zero(bus);	I2C_DEBUG(printk("=%02x%c ",(int)data,last?'-':'+'));	return data;}/* ----------------------------------------------------------------------- */int i2c_read(struct i2c_bus *bus, unsigned char addr){	int ret;    	if (bus->i2c_read)		return bus->i2c_read(bus, addr);	i2c_start(bus);	i2c_sendbyte(bus,addr,0);	ret = i2c_readbyte(bus,1);	i2c_stop(bus);	return ret;}int i2c_write(struct i2c_bus *bus, unsigned char addr,	      unsigned char data1, unsigned char data2, int both){	int ack;	if (bus->i2c_write)		return bus->i2c_write(bus, addr, data1, data2, both);	i2c_start(bus);	i2c_sendbyte(bus,addr,0);	ack = i2c_sendbyte(bus,data1,0);	if (both)		ack = i2c_sendbyte(bus,data2,0);	i2c_stop(bus);	return ack ? -1 : 0 ;}/* ----------------------------------------------------------------------- */#ifdef MODULE#if LINUX_VERSION_CODE >= 0x020100EXPORT_SYMBOL(i2c_register_bus);EXPORT_SYMBOL(i2c_unregister_bus);EXPORT_SYMBOL(i2c_register_driver);EXPORT_SYMBOL(i2c_unregister_driver);EXPORT_SYMBOL(i2c_control_device);EXPORT_SYMBOL(i2c_start);EXPORT_SYMBOL(i2c_stop);EXPORT_SYMBOL(i2c_one);EXPORT_SYMBOL(i2c_zero);EXPORT_SYMBOL(i2c_ack);EXPORT_SYMBOL(i2c_sendbyte);EXPORT_SYMBOL(i2c_readbyte);EXPORT_SYMBOL(i2c_read);EXPORT_SYMBOL(i2c_write);#endifint init_module(void){	return i2c_init();}void cleanup_module(void){}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -