#include <linux/module.h>
|
#include <linux/clk-provider.h>
|
#include <linux/i2c.h>
|
#include <linux/delay.h>
|
|
static struct i2c_client s_m_client;
|
static struct i2c_client* m_client;
|
|
//写16位寄存器
|
static inline int nkmcu_reg_write(struct i2c_client *client,int index,unsigned short reg, unsigned char val)
|
{
|
unsigned char u8_buf[3] = { 0 };
|
unsigned int buf_len = 3;
|
int retry, timeout = 5;
|
int ret;
|
|
ret = 0;
|
u8_buf[0] = (reg >> 8) & 0xFF;//寄存器地址高位
|
u8_buf[1] = reg & 0xFF; //寄存器地址低位
|
u8_buf[2] = val; //要发送的数据
|
|
//pdata->client->addr = ADDR + index;
|
for (retry = 0; retry < timeout; retry++)
|
{
|
if (i2c_master_send(client, u8_buf, buf_len) < 0)
|
{
|
pr_err("%s:write reg error: reg=0x%x, val=0x%x, retry = %d.\n", __func__, reg, val, retry);
|
ret = -1;
|
msleep(5);
|
continue;
|
}
|
else
|
{
|
pr_err("%s:write reg ok: reg=0x%x, val=0x%x, retry = %d.\n", __func__, reg, val, retry);
|
ret = 0;
|
break;
|
}
|
}
|
return ret;
|
}
|
|
//16位读
|
static inline int nkmcu_reg_read(struct i2c_client *client, int index, unsigned short reg)
|
{
|
unsigned char u8_buf[2] = { 0 };
|
unsigned int buf_len = 2;
|
int retry, timeout = 5;
|
unsigned char u8_val = 0;
|
|
u8_buf[0] = (reg >> 8) & 0xFF;//寄存器地址高位
|
u8_buf[1] = reg & 0xFF;//寄存器地址低位
|
|
//pdata->client->addr = ADDR + index;
|
for (retry = 0; retry < timeout; retry++)
|
{
|
if (i2c_master_send(client, u8_buf, buf_len) < 0)
|
{
|
pr_err("%s:read reg error on send: reg=0x%x, retry = %d.\n", __func__, reg, retry);
|
msleep(5);
|
continue;
|
}
|
if (i2c_master_recv(client, &u8_val, 1) != 1) {
|
pr_err("%s:read reg error on recv: reg=0x%x, retry = %d.\n", __func__, reg, retry);
|
msleep(5);
|
continue;
|
}
|
break;
|
}
|
|
if (retry >= timeout) {
|
pr_err("%s:read reg error: reg=0x%x.\n", __func__, reg);
|
return -1;
|
}
|
|
return u8_val;
|
}
|
|
void nkmcu_device_shutdown(void)
|
{
|
int ret;
|
|
pr_err("nkmcu_device_shutdown.. \n");
|
|
//powenoff
|
if (m_client != NULL)
|
{
|
ret = nkmcu_reg_write(m_client, 0x00, 0x06, 0x01);
|
if (ret < 0)
|
pr_err("nkmcu_device_shutdown..failed \n");
|
else
|
pr_err("nkmcu_device_shutdown.. ok \n");
|
}
|
|
}
|
EXPORT_SYMBOL(nkmcu_device_shutdown);
|
|
static int nk_mcu_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
{
|
//struct device_node *np = client->dev.of_node;
|
int ret;
|
|
printk("%s: probe\n", __FUNCTION__);
|
|
/* check state of calendar information */
|
//device id
|
//i2c_smbus_read_word_data
|
msleep(100);
|
//ret = i2c_smbus_read_byte_data(client, 0x00);
|
ret = nkmcu_reg_read(client, 0x00, 0x00);
|
printk("device id:%x \n", ret);
|
if (ret != 0xaa)
|
goto error;
|
|
//powenon
|
msleep(100);
|
//ret = i2c_smbus_write_word_data(client, 0x07, 0x01);
|
ret = nkmcu_reg_write(client, 0x00, 0x07, 0x01);
|
printk("poweron command:%x \n", ret);
|
if (ret < 0)
|
goto error;
|
|
//m_client = client;
|
memcpy(&s_m_client, client, sizeof(struct i2c_client));
|
m_client = &s_m_client;
|
return 0;
|
|
error:
|
return -1;
|
}
|
|
static const struct i2c_device_id nk_mcu_id[] = {
|
{ "nk_mcu", 0 },
|
{ }
|
};
|
|
static struct i2c_driver nk_mcu_driver = {
|
.driver = {
|
.name = "nk_mcu",
|
.owner = THIS_MODULE,
|
},
|
.probe = nk_mcu_probe,
|
.id_table = nk_mcu_id,
|
};
|
|
static int __init nk_mcu_init(void)
|
{
|
return i2c_add_driver(&nk_mcu_driver);
|
}
|
|
static void __exit nk_mcu_exit(void)
|
{
|
i2c_del_driver(&nk_mcu_driver);
|
}
|
|
|
MODULE_AUTHOR("ben@hotmail.com");
|
MODULE_DESCRIPTION("nodka mcu driver");
|
MODULE_LICENSE("GPL");
|
|
late_initcall(nk_mcu_init);
|
module_exit(nk_mcu_exit);
|