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

📄 i2c-proc.c

📁 IXP425 平台下嵌入式LINUX的I2Cz总线的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* nrels contains initially the maximum number of elements which can be   put in results, and finally the number of elements actually put there.   A magnitude of 1 will multiply everything with 10; etc.   buffer, bufsize is the character buffer we read from and its length.   results will finally contain the parsed integers.    Buffer should contain several reals, separated by whitespace. A real   has the following syntax:     [ Minus ] Digit* [ Dot Digit* ]    (everything between [] is optional; * means zero or more).   When the next character is unparsable, everything is skipped until the   next whitespace.   WARNING! This is tricky code. I have tested it, but there may still be            hidden bugs in it, even leading to crashes and things!*/int i2c_parse_reals(int *nrels, void *buffer, int bufsize,			 long *results, int magnitude){	int maxels, min, mag;	long res,ret=0;	char nextchar = 0;	maxels = *nrels;	*nrels = 0;	while (bufsize && (*nrels < maxels)) {		/* Skip spaces at the start */		while (bufsize && 		       !((ret=get_user(nextchar, (char *) buffer))) &&		       isspace((int) nextchar)) {			bufsize--;			((char *) buffer)++;		}		if (ret)			return -EFAULT;			/* Well, we may be done now */		if (!bufsize)			return 0;		/* New defaults for our result */		min = 0;		res = 0;		mag = magnitude;		/* Check for a minus */		if (!((ret=get_user(nextchar, (char *) buffer)))		    && (nextchar == '-')) {			min = 1;			bufsize--;			((char *) buffer)++;		}		if (ret)			return -EFAULT;		/* Digits before a decimal dot */		while (bufsize && 		       !((ret=get_user(nextchar, (char *) buffer))) &&		       isdigit((int) nextchar)) {			res = res * 10 + nextchar - '0';			bufsize--;			((char *) buffer)++;		}		if (ret)			return -EFAULT;		/* If mag < 0, we must actually divide here! */		while (mag < 0) {			res = res / 10;			mag++;		}		if (bufsize && (nextchar == '.')) {			/* Skip the dot */			bufsize--;			((char *) buffer)++;			/* Read digits while they are significant */			while (bufsize && (mag > 0) &&			       !((ret=get_user(nextchar, (char *) buffer))) &&			       isdigit((int) nextchar)) {				res = res * 10 + nextchar - '0';				mag--;				bufsize--;				((char *) buffer)++;			}			if (ret)				return -EFAULT;		}		/* If we are out of data, but mag > 0, we need to scale here */		while (mag > 0) {			res = res * 10;			mag--;		}		/* Skip everything until we hit whitespace */		while (bufsize && 		       !((ret=get_user(nextchar, (char *) buffer))) &&		       isspace((int) nextchar)) {			bufsize--;			((char *) buffer)++;		}		if (ret)			return -EFAULT;		/* Put res in results */		results[*nrels] = (min ? -1 : 1) * res;		(*nrels)++;	}	/* Well, there may be more in the buffer, but we need no more data. 	   Ignore anything that is left. */	return 0;}int i2c_write_reals(int nrels, void *buffer, int *bufsize,			 long *results, int magnitude){#define BUFLEN 20	char BUF[BUFLEN + 1];	/* An individual representation should fit! */	char printfstr[10];	int nr = 0;	int buflen, mag, times;	int curbufsize = 0;	while ((nr < nrels) && (curbufsize < *bufsize)) {		mag = magnitude;		if (nr != 0) {			if(put_user(' ', (char *) buffer))				return -EFAULT;			curbufsize++;			((char *) buffer)++;		}		/* Fill BUF with the representation of the next string */		if (mag <= 0) {			buflen = sprintf(BUF, "%ld", results[nr]);			if (buflen < 0) {	/* Oops, a sprintf error! */				*bufsize = 0;				return -EINVAL;			}			while ((mag < 0) && (buflen < BUFLEN)) {				BUF[buflen++] = '0';				mag++;			}			BUF[buflen] = 0;		} else {			times = 1;			for (times = 1; mag-- > 0; times *= 10);			if (results[nr] < 0) {				BUF[0] = '-';				buflen = 1;			} else				buflen = 0;			strcpy(printfstr, "%ld.%0Xld");			printfstr[6] = magnitude + '0';			buflen +=			    sprintf(BUF + buflen, printfstr,				    abs(results[nr]) / times,				    abs(results[nr]) % times);			if (buflen < 0) {	/* Oops, a sprintf error! */				*bufsize = 0;				return -EINVAL;			}		}		/* Now copy it to the user-space buffer */		if (buflen + curbufsize > *bufsize)			buflen = *bufsize - curbufsize;		if(copy_to_user(buffer, BUF, buflen))			return -EFAULT;		curbufsize += buflen;		(char *) buffer += buflen;		nr++;	}	if (curbufsize < *bufsize) {		if(put_user('\n', (char *) buffer))			return -EFAULT;		curbufsize++;	}	*bufsize = curbufsize;	return 0;}/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */int i2c_detect(struct i2c_adapter *adapter,		   struct i2c_address_data *address_data,		   i2c_found_addr_proc * found_proc){	int addr, i, found, j, err;	struct i2c_force_data *this_force;	int is_isa = i2c_is_isa_adapter(adapter);	int adapter_id =	    is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter);	/* Forget it if we can't probe using SMBUS_QUICK */	if ((!is_isa)	    && !i2c_check_functionality(adapter,					I2C_FUNC_SMBUS_QUICK)) return -1;	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {		if ((is_isa && check_region(addr, 1)) ||		    (!is_isa && i2c_check_addr(adapter, addr)))			continue;		/* If it is in one of the force entries, we don't do any		   detection at all */		found = 0;		for (i = 0;		     !found		     && (this_force =			 address_data->forces + i, this_force->force); i++) {			for (j = 0;			     !found			     && (this_force->force[j] != SENSORS_I2C_END);			     j += 2) {				if (				    ((adapter_id == this_force->force[j])				     ||				     ((this_force->				       force[j] == SENSORS_ANY_I2C_BUS)				      && !is_isa))				    && (addr == this_force->force[j + 1])) {#ifdef DEBUG					printk					    ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n",					     adapter_id, addr);#endif					if (					    (err =					     found_proc(adapter, addr, 0,							this_force->							kind))) return err;					found = 1;				}			}		}		if (found)			continue;		/* If this address is in one of the ignores, we can forget about it		   right now */		for (i = 0;		     !found		     && (address_data->ignore[i] != SENSORS_I2C_END);		     i += 2) {			if (			    ((adapter_id == address_data->ignore[i])			     ||			     ((address_data->			       ignore[i] == SENSORS_ANY_I2C_BUS)			      && !is_isa))			    && (addr == address_data->ignore[i + 1])) {#ifdef DEBUG				printk				    ("i2c-proc.o: found ignore parameter for adapter %d, "				     "addr %04x\n", adapter_id, addr);#endif				found = 1;			}		}		for (i = 0;		     !found		     && (address_data->ignore_range[i] != SENSORS_I2C_END);		     i += 3) {			if (			    ((adapter_id == address_data->ignore_range[i])			     ||			     ((address_data->			       ignore_range[i] ==			       SENSORS_ANY_I2C_BUS) & !is_isa))			    && (addr >= address_data->ignore_range[i + 1])			    && (addr <= address_data->ignore_range[i + 2])) {#ifdef DEBUG				printk				    ("i2c-proc.o: found ignore_range parameter for adapter %d, "				     "addr %04x\n", adapter_id, addr);#endif				found = 1;			}		}		if (found)			continue;		/* Now, we will do a detection, but only if it is in the normal or 		   probe entries */		if (is_isa) {			for (i = 0;			     !found			     && (address_data->normal_isa[i] !=				 SENSORS_ISA_END); i += 1) {				if (addr == address_data->normal_isa[i]) {#ifdef DEBUG					printk					    ("i2c-proc.o: found normal isa entry for adapter %d, "					     "addr %04x\n", adapter_id,					     addr);#endif					found = 1;				}			}			for (i = 0;			     !found			     && (address_data->normal_isa_range[i] !=				 SENSORS_ISA_END); i += 3) {				if ((addr >=				     address_data->normal_isa_range[i])				    && (addr <=					address_data->normal_isa_range[i + 1])				    &&				    ((addr -				      address_data->normal_isa_range[i]) %				     address_data->normal_isa_range[i + 2] ==				     0)) {#ifdef DEBUG					printk					    ("i2c-proc.o: found normal isa_range entry for adapter %d, "					     "addr %04x", adapter_id, addr);#endif					found = 1;				}			}		} else {			for (i = 0;			     !found && (address_data->normal_i2c[i] !=				 SENSORS_I2C_END); i += 1) {				if (addr == address_data->normal_i2c[i]) {					found = 1;#ifdef DEBUG					printk					    ("i2c-proc.o: found normal i2c entry for adapter %d, "					     "addr %02x", adapter_id, addr);#endif				}			}			for (i = 0;			     !found			     && (address_data->normal_i2c_range[i] !=				 SENSORS_I2C_END); i += 2) {				if ((addr >=				     address_data->normal_i2c_range[i])				    && (addr <=					address_data->normal_i2c_range[i + 1]))				{#ifdef DEBUG					printk					    ("i2c-proc.o: found normal i2c_range entry for adapter %d, "					     "addr %04x\n", adapter_id, addr);#endif					found = 1;				}			}		}		for (i = 0;		     !found && (address_data->probe[i] != SENSORS_I2C_END);		     i += 2) {			if (((adapter_id == address_data->probe[i]) ||			     ((address_data->			       probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa))			    && (addr == address_data->probe[i + 1])) {#ifdef DEBUG				printk				    ("i2c-proc.o: found probe parameter for adapter %d, "				     "addr %04x\n", adapter_id, addr);#endif				found = 1;			}		}		for (i = 0; !found &&		           (address_data->probe_range[i] != SENSORS_I2C_END);		     i += 3) {			if (			    ((adapter_id == address_data->probe_range[i])			     ||			     ((address_data->probe_range[i] ==			       SENSORS_ANY_I2C_BUS) & !is_isa))			    && (addr >= address_data->probe_range[i + 1])			    && (addr <= address_data->probe_range[i + 2])) {				found = 1;#ifdef DEBUG				printk				    ("i2c-proc.o: found probe_range parameter for adapter %d, "				     "addr %04x\n", adapter_id, addr);#endif			}		}		if (!found)			continue;		/* OK, so we really should examine this address. First check		   whether there is some client here at all! */		if (is_isa ||		    (i2c_smbus_xfer		     (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0))			if ((err = found_proc(adapter, addr, 0, -1)))				return err;	}	return 0;}int __init sensors_init(void){	printk("i2c-proc.o version %s (%s)\n", LM_VERSION, LM_DATE);	i2c_initialized = 0;	if (!	    (i2c_proc_header =	     register_sysctl_table(i2c_proc, 0))) return -ENOMEM;#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1))	i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE;#else	i2c_proc_header->ctl_table->child->de->fill_inode =	    &i2c_fill_inode;#endif			/* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) */	i2c_initialized++;	return 0;}EXPORT_SYMBOL(i2c_deregister_entry);EXPORT_SYMBOL(i2c_detect);EXPORT_SYMBOL(i2c_proc_real);EXPORT_SYMBOL(i2c_register_entry);EXPORT_SYMBOL(i2c_sysctl_real);#ifdef MODULEMODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");MODULE_DESCRIPTION("i2c-proc driver");MODULE_LICENSE("GPL");int i2c_cleanup(void){	if (i2c_initialized >= 1) {		unregister_sysctl_table(i2c_proc_header);		i2c_initialized--;	}	return 0;}int init_module(void){	return sensors_init();}int cleanup_module(void){	return i2c_cleanup();}#endif				/* MODULE */

⌨️ 快捷键说明

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