diff options
author | Srikant Patnaik | 2015-01-13 15:08:24 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-13 15:08:24 +0530 |
commit | 97327692361306d1e6259021bc425e32832fdb50 (patch) | |
tree | fe9088f3248ec61e24f404f21b9793cb644b7f01 /drivers/i2c/algos/wmt-i2c-algo.c | |
parent | 2d05a8f663478a44e088d122e0d62109bbc801d0 (diff) | |
parent | a3a8b90b61e21be3dde9101c4e86c881e0f06210 (diff) | |
download | FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.tar.gz FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.tar.bz2 FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.zip |
dirty fix to merging
Diffstat (limited to 'drivers/i2c/algos/wmt-i2c-algo.c')
-rwxr-xr-x | drivers/i2c/algos/wmt-i2c-algo.c | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/drivers/i2c/algos/wmt-i2c-algo.c b/drivers/i2c/algos/wmt-i2c-algo.c new file mode 100755 index 00000000..3be850d2 --- /dev/null +++ b/drivers/i2c/algos/wmt-i2c-algo.c @@ -0,0 +1,308 @@ +/*++ + drivers/i2c/algos/wmt_i2c_algo.c + + Copyright (c) 2008 WonderMedia Technologies, Inc. + + This program is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software Foundation, + either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + +#define WMT_I2C_ALGO_C + +#include <linux/kernel.h> +#include <linux/module.h> + +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/i2c.h> +/* +#include <linux/i2c-id.h> +*/ + +#include <mach/hardware.h> +#include <mach/wmt-i2c-bus.h> + +#ifdef __KERNEL__ + +#ifdef DEBUG + #define DPRINTK printk +#else + #define DPRINTK(x...) +#endif + +#else +#define DPRINTK printf + +#endif + +static struct i2c_adapter *wmt_i2c_adap[5]; + +/*!************************************************************************* +* wmt_i2c_valid_messages() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief verify the input message +* +* \retval 1 if success +*/ +static int wmt_i2c_valid_messages( + struct i2c_msg msgs[], /*!<; //[IN] transfer data */ + int num /*!<; //[IN] transfer data length */ +) +{ + int i; + if (num < 1 || num > MAX_MESSAGES) { + DPRINTK(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n", MAX_MESSAGES, num); + return -EINVAL; + } + + /* check consistency of our messages */ + for (i = 0; i < num; i++) { + if (&msgs[i] == NULL) { + DPRINTK(KERN_INFO "Msgs is NULL\n"); + return -EINVAL; + } else { + if (msgs[i].buf == NULL) { + DPRINTK(KERN_INFO "Length is less than zero\n"); + return -EINVAL; + } + } + } + + return 1; +} +/*!************************************************************************* +* wmt_i2c_do_xfer() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief +* +* \retval 0 if success +*/ +static int wmt_i2c_do_xfer( + struct i2c_adapter *i2c_adap, /*!<; //[IN] a pointer point to struct inode */ + struct i2c_msg msgs[], /*!<; //[IN] transfer data */ + int num /*!<; //[IN] transfer data length */ +) +{ + int i; + struct i2c_algo_wmt_data *adap; + int ret = 0 ; + + adap = i2c_adap->algo_data; + + /*ret = adap->wait_bus_not_busy();*/ + for (i = 0 ; i < 10; ++i) + ; + if (ret < 0) + return ret ; + + ret = adap->send_request(msgs, num, 0, 0, 0); + + return ret; + +} + +/*!************************************************************************* +* wmt_i2c_xfer() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief Transfer (read/write) data to i2c bus, wmt_i2c_do_xfer will be called to transfer +* +* \retval 0 if success +*/ +static int wmt_i2c_xfer( + struct i2c_adapter *i2c_adap, /*!<; //[IN] a pointer point to struct inode */ + struct i2c_msg msgs[], /*!<; //[IN] transfer data */ + int num /*!<; //[IN] transfer data length */ +) +{ + int ret ; + int i ; + + ret = wmt_i2c_valid_messages(msgs, num); + if (ret < 0) + return ret ; + + for (i = i2c_adap->retries ; i >= 0; i--) { + + ret = wmt_i2c_do_xfer(i2c_adap, msgs, num); + if (ret > 0) + return ret ; + DPRINTK(KERN_INFO"Retrying transmission \n"); + udelay(100); + } + + DPRINTK(KERN_INFO"Retried %i times\n", i2c_adap->retries); + return ret; + +} +/*!************************************************************************* +* wmt_i2c_functionality() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief +* +* \retval smbus functionality +*/ +static u32 wmt_i2c_functionality( + struct i2c_adapter *adapter /*!<; //[IN] a pointer point to struct inode */ +) +{ + /* Emulate the SMBUS functions*/ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +/* + * send i2c_msg into fifo of i2c bus + * msg: transfer data content + * msg_num:number of transferring msg + * bus_id :used to indicate which bus do device want to access + */ +int wmt_i2c_transfer(struct i2c_msg* msgs, int msg_num, int bus_id, void (*callback)(void *data), void *data) +{ + struct i2c_algo_wmt_data *adap; + int ret = 0 ; + + adap = wmt_i2c_adap[bus_id]->algo_data; + ret = adap->send_request(msgs, msg_num, 1, callback, data); + return ret; +} + +#if 0 +/*!************************************************************************* +* wmt_i2c_control() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief To set i2c transfer mode +* +* \retval 0 if success +*/ +static int wmt_i2c_control( + struct i2c_adapter *i2c_adap, /*!<; //[IN] a pointer point to struct inode */ + unsigned int cmd, /*!<; //[IN] standard or fast mode */ + unsigned long arg /*!<; //Not in used, but can't delete */ +) +{ + int ret ; + struct i2c_algo_wmt_data *adap = i2c_adap->algo_data; + + ret = 0 ; + DPRINTK("wmt_i2c_control: cmd = 0x%8.8x \n", cmd); + + switch (cmd) { + case I2C_SET_STANDARD_MODE: + adap->set_mode(I2C_STANDARD_MODE); + break ; + case I2C_SET_FAST_MODE: + adap->set_mode(I2C_FAST_MODE); + break ; + default: + ret = -EINVAL; + break; + } + + return ret; +} +#endif + + +struct i2c_algorithm wmt_i2c_algorithm = { + .master_xfer = wmt_i2c_xfer, + .functionality = wmt_i2c_functionality, +}; +/*!************************************************************************* +* wmt_i2c_add_bus() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief +* +* \retval NULL +*/ +int wmt_i2c_add_bus(struct i2c_adapter *i2c_adap) +{ + printk(KERN_INFO"i2c: adding %s.\n", i2c_adap->name); + + i2c_adap->algo = &wmt_i2c_algorithm; + wmt_i2c_adap[i2c_adap->nr] = i2c_adap; + + /* register new adapter to i2c module... */ + /* + i2c_add_adapter(i2c_adap); + */ + i2c_add_numbered_adapter(i2c_adap); + + /* adap->reset();*/ + + return 0; +} +/*!************************************************************************* +* wmt_i2c_del_bus() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief +* +* \retval NULL +*/ +int wmt_i2c_del_bus(struct i2c_adapter *i2c_adap) +{ + int res; + res = i2c_del_adapter(i2c_adap); + if (res < 0) + return res; + + printk(KERN_INFO "i2c: removing %s.\n", i2c_adap->name); + + return 0; +} +/*!************************************************************************* +* wmt_i2c_algo_init() +* +* Private Function by Paul Kwong, 2007/1/12 +*/ +/*! +* \brief +* +* \retval NULL +*/ +static int __init wmt_i2c_algo_init(void) +{ + printk(KERN_INFO "i2c: wmt algorithm module loaded.\n"); + return 0; +} + +EXPORT_SYMBOL(wmt_i2c_add_bus); +EXPORT_SYMBOL(wmt_i2c_del_bus); + +MODULE_AUTHOR("WonderMedia Technologies, Inc."); +MODULE_DESCRIPTION("WMT I2C ALGO Driver"); +MODULE_LICENSE("GPL"); + +module_init(wmt_i2c_algo_init); + +#undef WMT_I2C_ALGO_C |