/* * Battery s_stCharger driver for X-Powers AXP * * Copyright (C) 2013 X-Powers, Ltd. * Zhang Donglu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include //#include //#include "kwrap/type.h" //#include "kwrap/semaphore.h" //#include "kwrap/flag.h" #include "sf_mcu_dev.h" //#define __MODULE__ sf_i2c_mcu //#define __DBGLVL__ 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER //#define __DBGFLT__ "*" // *=All, [mark]=CustomClass //#include "kwrap/debug.h" #include #include #include #include //#define printf(fmt, args...) printk(fmt , ## args) static SF_I2C sf_i2c = { SF_I2C_ID_3, MCU_I2C_SLAVE_ADDR }; static INT32 sf_i2c_write_ioc(UINT32 addr, UINT32 data) { struct i2c_msg msgs; UINT8 buf[2]; INT32 ret; //printk("%s:%d addr[%d]=0x%02x\n",__FUNCTION__,__LINE__,addr, data); //DBG_DUMP("%s:%d addr[%d]=0x%02x\r\n",__FUNCTION__,__LINE__,addr, data); buf[0] = addr & 0xFF; buf[1] = data & 0xFF; msgs.addr = sf_i2c.addr; msgs.flags = 0;//w msgs.len = 2; msgs.buf = buf; ret = sf_i2c_transfer(&msgs, 1); return ret; } static INT32 sf_i2c_read_ioc(UINT32 addr, UINT8 *data) { struct i2c_msg msgs[2]; UINT8 buf[1], buf2[1]; INT32 ret; //printk("%s:%d addr:%d\n",__FUNCTION__,__LINE__,addr); //DBG_DUMP("%s:%d addr:%d\r\n",__FUNCTION__,__LINE__,addr); buf[0] = addr & 0xFF; msgs[0].addr = sf_i2c.addr; msgs[0].flags = 0;//w msgs[0].len = 1; msgs[0].buf = buf; buf2[0] = 0; msgs[1].addr = sf_i2c.addr; msgs[1].flags = 1;//r msgs[1].len = 1; msgs[1].buf = buf2; ret = sf_i2c_transfer(msgs, 2); if (ret == 0) { //OK *data = buf2[0]; } return ret; } int sf_init_mcu(void) { INT32 ret; ret = sf_i2c_init_driver(sf_i2c.id); return ret; } int sf_off_mcu(void) { return 0; } static long sf_mcu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { INT32 ret = 0; UINT8 buf[2]; if (copy_from_user(buf, (void *)arg, sizeof(buf))) return -EFAULT; switch(cmd) { case IOC_MCU_SET:{ ret = sf_i2c_write_ioc(buf[0],buf[1]); copy_to_user((void *)arg, (void *)&ret, sizeof(INT32)); } break; case IOC_MCU_GET:{ ret = sf_i2c_read_ioc(buf[0],&buf[1]); copy_to_user((void *)arg, (void *)buf, sizeof(buf)); } break; default: return -EINVAL; } return 0; } static const struct file_operations sf_mcu_fops = { .owner = THIS_MODULE, .unlocked_ioctl = sf_mcu_ioctl, }; static struct miscdevice sf_mcu_miscdev = { .minor = MISC_DYNAMIC_MINOR, .name = "sf_mcu", .fops = &sf_mcu_fops, }; static int __init sf_init(void) { int rt; printk("%s:%d s\n",__FUNCTION__,__LINE__); DBG_DUMP("%s:%d s\r\n",__FUNCTION__,__LINE__); rt = sf_init_mcu(); rt = misc_register(&sf_mcu_miscdev); if (rt) { DBG_ERR("misc_register fail, ret = %d\n", rt); return rt; } return rt; } static void __exit sf_exit(void) { sf_i2c_remove_driver(sf_i2c.id); } module_init(sf_init); module_exit(sf_exit); MODULE_DESCRIPTION("SIFAR MCU"); MODULE_AUTHOR("SiFar."); MODULE_LICENSE("GPL");