📄 i2c_mem_adpt.c
字号:
/* i2c_mem_adapt.c * * author marco corvi * date june 2003 * * i2c memory adapter (and algorithm) * * credits: i2c_XXX in the kernel 2.4.X * http://secure/netroedge.com/~lm78/docs.html *//* #include <linux/version.h> */#include <linux/module.h>/* #include <linux/modversions.h> */#include <linux/kernel.h>#include <linux/i2c.h>#include <linux/init.h>#include "i2c_mem.h"/* ================================================= *//* data structures *//* ------------------------------------------------- */int i2c_mem_adpt_xfer( struct i2c_adapter * adapter, struct i2c_msg msgs[], int num );int i2c_mem_adpt_smbus_xfer( struct i2c_adapter * adapter, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data);u32 i2c_mem_adpt_func( struct i2c_adapter * adapter );void i2c_mem_adpt_inc_use( struct i2c_adapter * adapter );void i2c_mem_adpt_dec_use( struct i2c_adapter * adapter );int i2c_mem_adapt_client_register( struct i2c_client * client );int i2c_mem_adapt_client_unregister( struct i2c_client * client );int i2c_mem_adpt_init(void);int i2c_mem_adpt_cleanup(void);static struct i2c_algorithm i2c_mem_algo = { .name = "mem bus algorithm", .id = I2C_ALGO_MEM, .master_xfer = & i2c_mem_adpt_xfer, .smbus_xfer = & i2c_mem_adpt_smbus_xfer, /* NULL, */ /* pure i2c, no smbus */ .slave_send = NULL, .slave_recv = NULL, .algo_control = NULL, /* no custom ioctl */ .functionality = & i2c_mem_adpt_func};static struct i2c_adapter i2c_mem_adapter = { .name = "mem adapter", .id = I2C_ALGO_MEM | I2C_HW_MEM, .algo = & i2c_mem_algo, .algo_data = NULL, .inc_use = & i2c_mem_adpt_inc_use, .dec_use = & i2c_mem_adpt_dec_use, .data = NULL, .client_register = & i2c_mem_adapt_client_register, .client_unregister = & i2c_mem_adapt_client_unregister, /* nothing else initialized */};/* ---------------------------------------------------------------- *//* algorithm *//* ---------------------------------------------------------------- *//* algorithm master transfer * This is called by i2c_transfer() under the adapter's lock * */inti2c_mem_adpt_xfer( struct i2c_adapter * adapter, struct i2c_msg msgs[], int num ){ int i, j, k, len; int cnt = 0; unsigned char addr; unsigned char * data; unsigned char * cdata; struct i2c_client ** client = &(adapter->clients[0]); for (i=0; i<num; i++) { if ( (len = msgs[i].len) < 1 ) continue; /* 7-bit addresses */ addr = (unsigned char)( msgs[i].addr & 0x7f ) ; data = (unsigned char *)( msgs[i].buf ); for (j=0; j<I2C_CLIENT_MAX; j++) { if ( client[j] && (client[j]->addr == addr) ) { /* struct copy byte by byte */ cdata = (unsigned char *)(client[j]->data); if ( msgs[i].flags & I2C_M_RD ) { for (k=0; k<len && k<I2C_MEM_CDATA_SIZE; k++) data[k] = cdata[k]; } else { for (k=0; k<len && k<I2C_MEM_CDATA_SIZE; k++) cdata[k] = data[k]; } cnt ++; break; /* check no further client */ } } } return cnt; /* return the number oftransferred msgs */}int i2c_mem_adpt_smbus_xfer( struct i2c_adapter * adapter, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data){ int j; printk(KERN_ALERT "i2c_mem_adpt_smbus_xfer() addr %x rw %d cmd %d size %d\n", addr, read_write, command, size ); /* EBUSY if the address is already taken */ for (j=0; j<I2C_CLIENT_MAX; j++) if ( adapter->clients[j] && ( adapter->clients[j]->addr == addr ) ) return -EBUSY; /* since this is called by probe 'before' the client allocation * there really is no client yet for any address * so just return o.k. */ if ( size == I2C_SMBUS_QUICK ) return 0; return -1; /* fail */} u32i2c_mem_adpt_func( struct i2c_adapter * adapter ){ printk(KERN_ALERT "i2c_mem_adpt_func() adapter %s\n", adapter->name); return I2C_FUNC_MEM | I2C_FUNC_SMBUS_QUICK ;}/* ---------------------------------------------------------------- *//* adapter *//* ---------------------------------------------------------------- *//* inc/dec_use are called by i2c_inc/dec_use_client * */voidi2c_mem_adpt_inc_use( struct i2c_adapter * adapter ){ printk(KERN_ALERT "i2c_mem_adpt_inc_use() adapter %s\n", adapter->name); #ifdef MODULE MOD_INC_USE_COUNT; #endif}voidi2c_mem_adpt_dec_use( struct i2c_adapter * adapter ){ printk(KERN_ALERT "i2c_mem_adpt_dec_use() adapter %s\n", adapter->name); #ifdef MODULE MOD_DEC_USE_COUNT; #endif}/* i2c_attach_client first checks that the client's adapter has available * the client's address; if it is o.k. it inserts the client in the * adapter's clients[] and calls the custom adapter' client_register() method. * Similarly client_unregister() is called by i2c_detach_client. * * Put here anything special to your adapter. */inti2c_mem_adapt_client_register( struct i2c_client * client ){ printk(KERN_ALERT "i2c_mem_adapt_client_register() client %s\n", client->name ); return 0; /* O.K. */}inti2c_mem_adapt_client_unregister( struct i2c_client * client ){ printk(KERN_ALERT "i2c_mem_adapt_client_unregister() client %s\n", client->name ); /* already done by I2C core for (i=0; i<I2C_CLIENT_MAX; i++) { if ( i2c_mem_adapter->clients[i] == client ) { i2c_mem_adapter->client[i] = NULL; break; } } */ return 0; /* O.K. */}/* ------------------------------------------------- */static int __initdata i2c_mem_adpt_initialized = 0;int __init i2c_mem_adpt_init(void){ int res; printk(KERN_ALERT "i2c_mem version %04x\n", I2C_MEM_VERSION); i2c_mem_adpt_initialized++; if ( i2c_mem_adpt_initialized == 1 ) { if ( (res = i2c_add_adapter( & i2c_mem_adapter ) ) ) { printk(KERN_ALERT "i2c_mem: Adapter registration failed, " "module i2c_mem is not inserted\n."); i2c_mem_adpt_cleanup(); return res; } } printk(KERN_ALERT "i2c_mem_adpt: initialized %d \n", i2c_mem_adpt_initialized); return 0;}int __init i2c_mem_adpt_cleanup(void){ int res; i2c_mem_adpt_initialized--; if (i2c_mem_adpt_initialized == 0) { if ( (res = i2c_del_adapter( &i2c_mem_adapter ) ) ) { printk (KERN_ALERT "i2c_mem: Fail adapter deregist., module not removed\n"); return res; } } printk(KERN_ALERT "i2c_mem_adpt: deinitialized %d \n", i2c_mem_adpt_initialized); return 0;}EXPORT_NO_SYMBOLS;/* ================================================= *//* module *//* ------------------------------------------------- */#ifdef MODULEMODULE_AUTHOR("marco corvi <marco_corvi@geocities.com>");MODULE_DESCRIPTION("memory access through i2c");#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 10) MODULE_LICENSE("GPL");#endifint init_module(void){ return i2c_mem_adpt_init();}int cleanup_module(void){ return i2c_mem_adpt_cleanup();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -