From 170c1c0fa90ad9f762d1877f8a57efce706fc95a Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 07:26:34 +0000 Subject: [PATCH] add nkmcu --- kernel/drivers/misc/nkmcu/nk_mcu.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/drivers/misc/nkmcu/Makefile | 1 2 files changed, 162 insertions(+), 0 deletions(-) diff --git a/kernel/drivers/misc/nkmcu/Makefile b/kernel/drivers/misc/nkmcu/Makefile new file mode 100644 index 0000000..aca06fb --- /dev/null +++ b/kernel/drivers/misc/nkmcu/Makefile @@ -0,0 +1 @@ +obj-y += nk_mcu.o diff --git a/kernel/drivers/misc/nkmcu/nk_mcu.c b/kernel/drivers/misc/nkmcu/nk_mcu.c new file mode 100755 index 0000000..b0702be --- /dev/null +++ b/kernel/drivers/misc/nkmcu/nk_mcu.c @@ -0,0 +1,161 @@ +#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); -- Gitblit v1.6.2