您的位置:首页 > 其它

智能电池管理芯片msp430驱动

2016-07-21 16:27 585 查看
#include <linux/interrupt.h>

#include <linux/i2c.h>

#include <linux/irq.h>

#include <linux/delay.h>

#include <linux/input.h>

#include <linux/workqueue.h>

#include <linux/kthread.h>

#include <linux/platform_device.h>

#include <asm/atomic.h>

#include <linux/of.h>

#include <linux/of_address.h>

#include <linux/of_device.h>

#include <linux/of_gpio.h>

#include <linux/of_irq.h>

#include <linux/uaccess.h>      /* needed by copy_to_user */

#include <linux/miscdevice.h>   /* needed by miscdevice* */

#include <linux/input.h>

#include <linux/slab.h>

#include "scp_helper.h"

#include <scp_ipi.h>

#include "scp_excep.h"

#define MSP430_BUF_LEN 27

#define SEND_IPI_FRE_MS  500 

#define SLAVA_READ_DATA_CMD 0x10

#define MSP430_DATA_SIZE 25

//#define SLAVE_READ_ADDR 0x5B

//#define SLAVA_WRITE_ADDR 0x5A

//#define DEVICE_ADDR   0X2D

static struct i2c_client *new_client;

static struct input_dev *huba_wakeup_speech_dev;

static int msp430_read_data(u8 cmd,u8 *buf)

{
int ret;

struct i2c_msg msg[2];

if (!new_client) {
pr_err("error: access msp430 before driver ready\n");
return 0;
}

msg[0].addr = new_client->addr;
msg[0].buf = &cmd;
msg[0].flags = 0;
msg[0].len = 1;

msg[1].addr = new_client->addr;
msg[1].buf = buf;
msg[1].flags = I2C_M_RD;
msg[1].len = MSP430_DATA_SIZE;

ret = i2c_transfer(new_client->adapter, msg, 2);

if (ret != 2)
pr_err("%s: err=%d\n", __func__, ret);

return ret == 2 ? 1 : 0;

}

static ssize_t huba_cm4_msp430_ipi_driver_read(
struct file *file, char *buf, size_t count, loff_t *ppos)

{
int32_t ret_len = 0,len=0;
u8 ret_buf[25]="abc";
ret_len = msp430_read_data(SLAVA_READ_DATA_CMD,ret_buf);
if(!ret_len)
{
printk("read_data_from_msp430 error!\n");
}
len = strlen(ret_buf);
if(copy_to_user(buf,ret_buf,len))
{
return -EFAULT;
}
if(count==len)
return len;
else
return -EFAULT;

}

static ssize_t huba_cm4_msp430_ipi_driver_write(
struct file *file, const char *buf, size_t count, loff_t *ppos)

{
return 0;

}

static const struct file_operations huba_cm4_msp430_ipi_device_ops = {
.owner          = THIS_MODULE,
.read           = huba_cm4_msp430_ipi_driver_read,
.write = huba_cm4_msp430_ipi_driver_write,

};

static struct miscdevice huba_cm4_msp430_ipi_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "huba_cm4_msp430",
.fops = &huba_cm4_msp430_ipi_device_ops

};

static void huba_cm4_ipi_msp430_msg_dispatcher(int id, void *data, unsigned int len)

{
return;

}

void huba_cm4_msp430_ipi_init(void)

{

ipi_status retval = ERROR; 
retval = scp_ipi_registration(IPI_HUBA_MSP430, huba_cm4_ipi_msp430_msg_dispatcher, "huba_cm4_msp430");
if (retval != DONE)
printk("%s(), scp_ipi_registration fail!!\n", __func__);

misc_register(&huba_cm4_msp430_ipi_device);

}

void huba_cm4_msp430_ipi_exit(void)

{
misc_deregister(&huba_cm4_msp430_ipi_device);

}

static int32_t read_data_from_msp430(void *data)

{
int32_t ret_len = 0,i;
u8 ret_buf[27]="abc";
ipi_status send_status = ERROR;
while(1)
{
ret_len = msp430_read_data(SLAVA_READ_DATA_CMD,ret_buf);
if(!ret_len)
{
printk("read_data_from_msp430 error!\n");
}
if(ret_buf[23]==1)
{
//printk("********simon********%s:%d\n",__FUNCTION__,__LINE__);
input_report_key(huba_wakeup_speech_dev, KEY_WAKEUP_HUBA_SPEECH, 1);
input_report_key(huba_wakeup_speech_dev, KEY_WAKEUP_HUBA_SPEECH, 0);
input_sync(huba_wakeup_speech_dev);
}else if(ret_buf[23]==0)
{
//printk("********simon********%s:%d\n",__FUNCTION__,__LINE__);
input_report_key(huba_wakeup_speech_dev, KEY_STOP_HUBA_SPEECH, 1);
input_report_key(huba_wakeup_speech_dev, KEY_STOP_HUBA_SPEECH, 0);
input_sync(huba_wakeup_speech_dev);
}
send_status = scp_ipi_send(IPI_HUBA_MSP430,
(void *)ret_buf,
26,
1); 
if (send_status != DONE) {
printk("%s(), listening_cm4_gps_sta error\n", __func__);
}
//printk("**simon**ret_buf=%s\n",ret_buf);
for(i=0;i<25;i++)
{
printk("%0x ",ret_buf[i]);
}
printk("\n");

msleep(SEND_IPI_FRE_MS);
}
return 0;

}

static int msp430_driver_probe(struct i2c_client *client, const struct i2c_device_id *id)

{
struct task_struct *pThread = NULL;
u8 ret_buf[27]="abc";
int32_t ret_len = 0;

new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!new_client) {
return -ENOMEM;
}

new_client = client;
//printk("**simon**%s:%d\n",__FUNCTION__,__LINE__);

ret_len = msp430_read_data(SLAVA_READ_DATA_CMD,ret_buf);//增加设备检测,如果没有读到数据,说明设备不存在,probe就此返回,不跑kthread_run,防止死机

if(!ret_len)

{
printk("read_data_from_msp430 error,no msp430 found !\n");
return -ENOMEM;
}

msleep(100);

if(ret_buf[0]=='a')
{
printk("read_data_from_msp430 error,no msp430 found !\n");
return -ENOMEM;
}
huba_wakeup_speech_dev = input_allocate_device();
if (!huba_wakeup_speech_dev) {
printk("[Accdet]kpd_accdet_dev : fail!\n");
return -ENOMEM;
}
__set_bit(EV_KEY, huba_wakeup_speech_dev->evbit);
__set_bit(KEY_WAKEUP_HUBA_SPEECH, huba_wakeup_speech_dev->keybit);
__set_bit(KEY_STOP_HUBA_SPEECH, huba_wakeup_speech_dev->keybit);

huba_wakeup_speech_dev->id.bustype = BUS_HOST;
huba_wakeup_speech_dev->name = "huba_speech";
//huba_wakeup_speech_dev->dev.parent = &pdev->dev;
if (input_register_device(huba_wakeup_speech_dev))
printk("[msp430]msp430_driver_probe input_register_device : fail!\n");

pThread = kthread_run(read_data_from_msp430, NULL, "readmsp430data");
if (IS_ERR(pThread))
printk("create pThread failed\n");
else
printk("create pThread success,read_data_from_msp430 \n");

return 0;

}

static const struct i2c_device_id msp430_i2c_id[] = { 
{"msp430", 0}, 
{}
};

static const struct of_device_id msp430_of_match[] = {
{.compatible = "mediatek,msp430",},
{},

};

MODULE_DEVICE_TABLE(of, msp430_of_match);

static struct i2c_driver msp430_init_driver = {
.driver = {
  .name = "msp430",
  .of_match_table = of_match_ptr(msp430_of_match),
  },
.probe = msp430_driver_probe,
.id_table = msp430_i2c_id,

};

static int __init msp430_init(void)

{
if (i2c_add_driver(&msp430_init_driver) != 0) {
printk("[msp430_init_init] failed to register msp430_init i2c driver.\n");
} else {
printk("[msp430_init_init] Success to register msp430_init i2c driver.\n");
}
huba_cm4_msp430_ipi_init();

return 0;

}

static void __exit msp430_exit(void)

{
i2c_del_driver(&msp430_init_driver);
huba_cm4_msp430_ipi_exit();
input_unregister_device(huba_wakeup_speech_dev);

}

module_init(msp430_init);

module_exit(msp430_exit);

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("I2C msp430 Driver");

MODULE_AUTHOR("feima_huba_g");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: