From 5e6b53bfd99248f3c13ca5e2b06ffc8dcf70a8e9 Mon Sep 17 00:00:00 2001 From: sushe_Ubuntu Date: Sat, 22 Jun 2024 22:15:42 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=A5=BDiic=E5=AE=9E?= =?UTF-8?q?=E9=AA=8C=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: sushe_Ubuntu --- 21_iic/.vscode/c_cpp_properties.json | 50 +++++++++ 21_iic/.vscode/settings.json | 21 ++++ 21_iic/Makefile | 13 +++ 21_iic/ap3216c.c | 60 ++++++++++ 21_iic/ap3216creg.h | 157 +++++++++++++++++++++++++++ 21_iic/iic.code-workspace | 14 +++ 6 files changed, 315 insertions(+) create mode 100644 21_iic/.vscode/c_cpp_properties.json create mode 100644 21_iic/.vscode/settings.json create mode 100644 21_iic/Makefile create mode 100644 21_iic/ap3216c.c create mode 100644 21_iic/ap3216creg.h create mode 100644 21_iic/iic.code-workspace diff --git a/21_iic/.vscode/c_cpp_properties.json b/21_iic/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..79c6d19 --- /dev/null +++ b/21_iic/.vscode/c_cpp_properties.json @@ -0,0 +1,50 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "linux-gcc-x64", + "browse": { + "path": [ + "${workspaceFolder}", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ] + } + }, + { + "name": "Win32", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "C:/Qt/Qt5.12.9/Tools/mingw730_64/bin/gcc.exe", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "windows-gcc-x64" + } + ], + "version": 4 +} diff --git a/21_iic/.vscode/settings.json b/21_iic/.vscode/settings.json new file mode 100644 index 0000000..1a2a04a --- /dev/null +++ b/21_iic/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + } +} \ No newline at end of file diff --git a/21_iic/Makefile b/21_iic/Makefile new file mode 100644 index 0000000..6cac2dd --- /dev/null +++ b/21_iic/Makefile @@ -0,0 +1,13 @@ +KERNELDIR := ../../../linux-imx-rel_imx_4.1.15_2.1.0_ga +CURRENT_PATH := $(shell pwd) +obj-m := keyinput.o + +build: kernel_modules + +kernel_modules: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules + +clean: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean + + diff --git a/21_iic/ap3216c.c b/21_iic/ap3216c.c new file mode 100644 index 0000000..d49d43c --- /dev/null +++ b/21_iic/ap3216c.c @@ -0,0 +1,60 @@ +#include "stdio.h" +#include "unistd.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "fcntl.h" +#include "stdlib.h" +#include "string.h" +#include +#include +#include +#include +#include +#include + +static struct input_event inputevent; + + +int main(int argc, char *argv[]){ + int fd; + int err = 0; + char *filename; + + filename = argv[1]; + + if (argc !=2 ) + { + printf("Error Usage!\r\n"); + return -1; + } + + fd = open(filename, O_RDWR); + if (fd <0) + { + printf("Can't open file %s \r\n", filename); + return -1; + } + + while(1){ + err = read(fd, &inputevent, sizeof(inputevent)); + if (err >0) + { + switch (inputevent.type) + { + case EV_KEY: + if (inputevent.code < BTN_MISC) + { + printf("key %d %s \r\n",inputevent.code, + inputevent.value ? "press" : "release"); + } + break; + + default: + break; + } + }else { + printf("读取数据失败\r\n"); + } + } + return 0; +} diff --git a/21_iic/ap3216creg.h b/21_iic/ap3216creg.h new file mode 100644 index 0000000..1ede368 --- /dev/null +++ b/21_iic/ap3216creg.h @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KEYINPUT_CNT 1 +#define KEYINPUT_NAME "keyinput" +#define KEY0VALUE 0X01 +#define INVAKEY 0XFF +#define KEY_NUM 1 + +struct irq_keydesc { + int gpio; /* gpio */ + int irqnum; /* 中断号 */ + unsigned char value; /* 按键对应的值 */ + char name[10]; /* 名字*/ + irqreturn_t (*handler)(int, void *); /* 中断服务函数*/ +}; + + +struct keyinput_dev +{ + dev_t devid; /* 中断号 */ + struct cdev cdev; /* cdev */ + struct class* class; /* 类 */ + struct device* device; + struct device_node* nd; + struct timer_list timer; + struct irq_keydesc irqkeydesc; /* 案件描述组 */ + unsigned char curkeynum; /* 当前的按键号 */ + struct input_dev* inputdev; /* input结构体 */ +}; + +struct keyinput_dev keyinputdev; + + +void timer_function(unsigned long arg) +{ + unsigned char value; + unsigned char num; + struct irq_keydesc* keydesc; + struct keyinput_dev* dev = (struct keyinput_dev*)arg; + + num = dev->curkeynum; + keydesc = &dev->irqkeydesc; + value = gpio_get_value(keydesc->gpio); + + if (value == 0) + { + input_report_key(dev->inputdev, keydesc->value, 1); + input_sync(dev->inputdev); + } + else { /* 按键松开 */ + input_report_key(dev->inputdev, keydesc->value, 0); + input_sync(dev->inputdev); + } + +} + +irqreturn_t key0_handler(int irq, void* dev_id) +{ + struct keyinput_dev *dev = (struct keyinput_dev *)dev_id; + + dev->curkeynum = 0; + dev->timer.data = (volatile long)dev_id; + mod_timer(&dev->timer, jiffies + msecs_to_jiffies(10)); + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void keyio_init(void) +{ + int ret = 0; + keyinputdev.nd = of_find_node_by_path("/key"); + if (keyinputdev.nd == NULL) + { + printk("key node not find!\r\n"); + return -EINVAL; + } + + keyinputdev.irqkeydesc.gpio = of_get_named_gpio(keyinputdev.nd, "key-gpio", 0); + if (keyinputdev.irqkeydesc.gpio < 0) + { + printk("can't get key0"); + } + + /* 初始化key所使用的IO,并且设置成中断模式 */ + memset(keyinputdev.irqkeydesc.name, 0, sizeof(keyinputdev.irqkeydesc.name)); + sprintf(keyinputdev.irqkeydesc.name, "key0"); + gpio_request(keyinputdev.irqkeydesc.gpio, keyinputdev.irqkeydesc.name); + gpio_direction_input(keyinputdev.irqkeydesc.gpio); + keyinputdev.irqkeydesc.irqnum = irq_of_parse_and_map(keyinputdev.nd, 0); + + /* 申请中断 */ + keyinputdev.irqkeydesc.handler = key0_handler; + keyinputdev.irqkeydesc.value = KEY_0; + + ret = request_irq(keyinputdev.irqkeydesc.irqnum, + keyinputdev.irqkeydesc.handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + keyinputdev.irqkeydesc.name, &keyinputdev); + if (ret <0) + { + printk("irq %d request failed !\r\n", keyinputdev.irqkeydesc.irqnum); + return -EFAULT; + } + + /* 创建定时器 */ + init_timer(&keyinputdev.timer); + keyinputdev.timer.function = timer_function; + /* 申请input_dev */ + keyinputdev.inputdev = input_allocate_device(); + keyinputdev.inputdev->name = KEYINPUT_NAME; + keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_set_capability(keyinputdev.inputdev, EV_KEY, KEY_0); + + /* 注册输入设备 */ + ret = input_register_device(keyinputdev.inputdev); + if (ret) + { + printk("register input device failed!\r\n"); + return ret; + } + return 0; +} + +static __init keyinput_init(void) +{ + keyio_init(); + return 0; +} + +static __exit keyinput_exit(void) +{ + +} + + + +module_init(keyinput_init); +module_exit(keyinput_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("zhangchaoliang"); diff --git a/21_iic/iic.code-workspace b/21_iic/iic.code-workspace new file mode 100644 index 0000000..213b97e --- /dev/null +++ b/21_iic/iic.code-workspace @@ -0,0 +1,14 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.associations": { + "ide.h": "c", + "init.h": "c" + } + + } +} \ No newline at end of file -- Gitee From 357123d8cbe91d06fec253f8a07f246805f2b3a2 Mon Sep 17 00:00:00 2001 From: sushe_Ubuntu Date: Sun, 23 Jun 2024 22:14:10 +0800 Subject: [PATCH 2/4] =?UTF-8?q?i2c=E5=AE=9E=E9=AA=8C=E5=86=99=E5=88=B0read?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: sushe_Ubuntu --- 21_iic/ap3216c.c | 185 +++++++++++++++++++++++++++----------- 21_iic/ap3216creg.h | 171 +++-------------------------------- 21_iic/iic.code-workspace | 10 ++- 3 files changed, 156 insertions(+), 210 deletions(-) diff --git a/21_iic/ap3216c.c b/21_iic/ap3216c.c index d49d43c..c8c91eb 100644 --- a/21_iic/ap3216c.c +++ b/21_iic/ap3216c.c @@ -1,60 +1,141 @@ -#include "stdio.h" -#include "unistd.h" -#include "sys/types.h" -#include "sys/stat.h" -#include "fcntl.h" -#include "stdlib.h" -#include "string.h" -#include -#include -#include -#include -#include -#include - -static struct input_event inputevent; - - -int main(int argc, char *argv[]){ - int fd; - int err = 0; - char *filename; - - filename = argv[1]; - - if (argc !=2 ) - { - printf("Error Usage!\r\n"); - return -1; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ap3216creg.h" + +#define AP3216C_CNT +#define AP3216C_NAME "ap3216c" + +struct ap3216c_dev +{ + dev_t devid; /* 设备号 */ + struct cdev cdev; + struct device *device; + struct class *class; + struct device_node *nd; + int major; + void *private_data; + unsigned short ir, als, ps; /* 三个光传感器数据 */ +}; + +static struct ap3216c_dev ap3216cdev; + +static int ap3216c_open(struct inode *nd, struct file *filp) +{ + +} + +static ssize_t ap3216c_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) +{ + filp->private_data = &ap3216cdev; + + +} + +static int ap3216c_release(struct inode *inode, struct file *file) +{ + +} + +static struct file_operations ap3216c_ops = { + .owner = THIS_MODULE, + .open = ap3216c_open, + .read = ap3216c_read, + .release = ap3216c_release, + +}; + +static int ap3216c_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + /* 1、构建设备号 */ + if(ap3216cdev.major){ + ap3216cdev.devid = MKDEV(ap3216cdev.major, 0); + register_chrdev_region(ap3216cdev.devid, AP3216C_CNT,AP3216C_NAME); + }else { + alloc_chrdev_region(&ap3216cdev.devid, 0, AP3216C_CNT, AP3216C_NAME); + ap3216cdev.major = MAJOR(ap3216cdev.devid); } - fd = open(filename, O_RDWR); - if (fd <0) + /* 2、 注册设备 */ + cdev_init(&ap3216cdev.cdev, &ap3216c_ops); + cdev_add(&ap3216cdev.cdev, ap3216cdev.devid, AP3216C_CNT); + + /* 3、创建类 */ + ap3216cdev.class = class_create(THIS_MODULE, AP3216C_NAME); + if (IS_ERR(ap3216cdev.class)) { - printf("Can't open file %s \r\n", filename); - return -1; + return PTR_ERR(ap3216cdev.class); } - while(1){ - err = read(fd, &inputevent, sizeof(inputevent)); - if (err >0) - { - switch (inputevent.type) - { - case EV_KEY: - if (inputevent.code < BTN_MISC) - { - printf("key %d %s \r\n",inputevent.code, - inputevent.value ? "press" : "release"); - } - break; - - default: - break; - } - }else { - printf("读取数据失败\r\n"); - } + /* 4、创建设备 */ + ap3216cdev.device = device_create(ap3216cdev.class, NULL, ap3216cdev.devid, NULL, AP3216C_NAME); + if(IS_ERR(ap3216cdev.device)){ + return PTR_ERR(ap3216cdev.device); } + + ap3216cdev.private_data = client; + return 0; +} + +static int ap3216c_remove(struct i2c_client *client) +{ + cdev_del(&ap3216cdev.cdev); + unregister_chrdev_region(ap3216cdev.devid, AP3216C_CNT); + + device_destroy(ap3216cdev.class, ap3216cdev.devid); + class_destroy(ap3216cdev.class); return 0; } + +static struct of_device_id ap3216c_of_match[] = { + {.compatible = "alientek,ap3216c" }, + {/* */} +}; + +static struct i2c_device_id ap3216c_id[] = { + {"alienek,ap3216c", 0}, + {/* */} +}; + +struct i2c_driver ap3216c_driver = { + .probe = ap3216c_probe, + .remove = ap3216c_remove, + .driver = { + .owner = THIS_MODULE, + .name = "ap3216c", + .of_match_table = ap3216c_of_match, + }, + .id_table = ap3216c_id, +}; + +static int __init ap3216c_init(void) +{ + int ret = 0; + + ret = i2c_add_driver(&ap3216c_driver); + return ret; +} + +static void __exit ap3216c_exit(void) +{ + i2c_del_driver(&ap3216c_driver); +} + +module_init(ap3216c_init); +module_exit(ap3216c_exitc); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR(“zhangchaoliang”); diff --git a/21_iic/ap3216creg.h b/21_iic/ap3216creg.h index 1ede368..39f1614 100644 --- a/21_iic/ap3216creg.h +++ b/21_iic/ap3216creg.h @@ -1,157 +1,14 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define KEYINPUT_CNT 1 -#define KEYINPUT_NAME "keyinput" -#define KEY0VALUE 0X01 -#define INVAKEY 0XFF -#define KEY_NUM 1 - -struct irq_keydesc { - int gpio; /* gpio */ - int irqnum; /* 中断号 */ - unsigned char value; /* 按键对应的值 */ - char name[10]; /* 名字*/ - irqreturn_t (*handler)(int, void *); /* 中断服务函数*/ -}; - - -struct keyinput_dev -{ - dev_t devid; /* 中断号 */ - struct cdev cdev; /* cdev */ - struct class* class; /* 类 */ - struct device* device; - struct device_node* nd; - struct timer_list timer; - struct irq_keydesc irqkeydesc; /* 案件描述组 */ - unsigned char curkeynum; /* 当前的按键号 */ - struct input_dev* inputdev; /* input结构体 */ -}; - -struct keyinput_dev keyinputdev; - - -void timer_function(unsigned long arg) -{ - unsigned char value; - unsigned char num; - struct irq_keydesc* keydesc; - struct keyinput_dev* dev = (struct keyinput_dev*)arg; - - num = dev->curkeynum; - keydesc = &dev->irqkeydesc; - value = gpio_get_value(keydesc->gpio); - - if (value == 0) - { - input_report_key(dev->inputdev, keydesc->value, 1); - input_sync(dev->inputdev); - } - else { /* 按键松开 */ - input_report_key(dev->inputdev, keydesc->value, 0); - input_sync(dev->inputdev); - } - -} - -irqreturn_t key0_handler(int irq, void* dev_id) -{ - struct keyinput_dev *dev = (struct keyinput_dev *)dev_id; - - dev->curkeynum = 0; - dev->timer.data = (volatile long)dev_id; - mod_timer(&dev->timer, jiffies + msecs_to_jiffies(10)); - return IRQ_RETVAL(IRQ_HANDLED); -} - -static void keyio_init(void) -{ - int ret = 0; - keyinputdev.nd = of_find_node_by_path("/key"); - if (keyinputdev.nd == NULL) - { - printk("key node not find!\r\n"); - return -EINVAL; - } - - keyinputdev.irqkeydesc.gpio = of_get_named_gpio(keyinputdev.nd, "key-gpio", 0); - if (keyinputdev.irqkeydesc.gpio < 0) - { - printk("can't get key0"); - } - - /* 初始化key所使用的IO,并且设置成中断模式 */ - memset(keyinputdev.irqkeydesc.name, 0, sizeof(keyinputdev.irqkeydesc.name)); - sprintf(keyinputdev.irqkeydesc.name, "key0"); - gpio_request(keyinputdev.irqkeydesc.gpio, keyinputdev.irqkeydesc.name); - gpio_direction_input(keyinputdev.irqkeydesc.gpio); - keyinputdev.irqkeydesc.irqnum = irq_of_parse_and_map(keyinputdev.nd, 0); - - /* 申请中断 */ - keyinputdev.irqkeydesc.handler = key0_handler; - keyinputdev.irqkeydesc.value = KEY_0; - - ret = request_irq(keyinputdev.irqkeydesc.irqnum, - keyinputdev.irqkeydesc.handler, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - keyinputdev.irqkeydesc.name, &keyinputdev); - if (ret <0) - { - printk("irq %d request failed !\r\n", keyinputdev.irqkeydesc.irqnum); - return -EFAULT; - } - - /* 创建定时器 */ - init_timer(&keyinputdev.timer); - keyinputdev.timer.function = timer_function; - /* 申请input_dev */ - keyinputdev.inputdev = input_allocate_device(); - keyinputdev.inputdev->name = KEYINPUT_NAME; - keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); - input_set_capability(keyinputdev.inputdev, EV_KEY, KEY_0); - - /* 注册输入设备 */ - ret = input_register_device(keyinputdev.inputdev); - if (ret) - { - printk("register input device failed!\r\n"); - return ret; - } - return 0; -} - -static __init keyinput_init(void) -{ - keyio_init(); - return 0; -} - -static __exit keyinput_exit(void) -{ - -} - - - -module_init(keyinput_init); -module_exit(keyinput_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("zhangchaoliang"); +#ifndef AP3216C_H +#define AP3216C_H + +#define AP3216C_SYSTEMCONG 0x00 /* 配置寄存器 */ +#define AP3216C_INTSTATUS 0X01 /* 中断状态寄存器 */ +#define AP3216C_INTCLEAR 0X02 /* 中断清除寄存器 */ +#define AP3216C_IRDATALOW 0x0A /* IR 数据低字节 */ +#define AP3216C_IRDATAHIGH 0x0B /* IR 数据高字节 */ +#define AP3216C_ALSDATALOW 0x0C /* ALS 数据低字节 */ +#define AP3216C_ALSDATAHIGH 0X0D /* ALS 数据高字节 */ +#define AP3216C_PSDATALOW 0X0E /* PS 数据低字节 */ +#define AP3216C_PSDATAHIGH 0X0F /* PS 数据高字节 */ + +#endif // \ No newline at end of file diff --git a/21_iic/iic.code-workspace b/21_iic/iic.code-workspace index 213b97e..4575012 100644 --- a/21_iic/iic.code-workspace +++ b/21_iic/iic.code-workspace @@ -7,7 +7,15 @@ "settings": { "files.associations": { "ide.h": "c", - "init.h": "c" + "init.h": "c", + "time.h": "c", + "stdlib.h": "c", + "i2c.h": "c", + "interrupt.h": "c", + "hardirq.h": "c", + "irq.h": "c", + "types.h": "c", + "proc_fs.h": "c" } } -- Gitee From c4b4f6cecb33c2d586dc2e4f37a274b48713159f Mon Sep 17 00:00:00 2001 From: sushe_Ubuntu Date: Mon, 24 Jun 2024 22:34:16 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E9=83=BD=E5=86=99=E5=A5=BD=E4=BA=86?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E6=98=AF=E6=9C=89bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: sushe_Ubuntu --- 21_iic/Makefile | 2 +- 21_iic/ap3216c.c | 104 ++++++++++++++++++++++++++++++++++++++++---- 21_iic/ap3216cApp.c | 48 ++++++++++++++++++++ 3 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 21_iic/ap3216cApp.c diff --git a/21_iic/Makefile b/21_iic/Makefile index 6cac2dd..750cd50 100644 --- a/21_iic/Makefile +++ b/21_iic/Makefile @@ -1,6 +1,6 @@ KERNELDIR := ../../../linux-imx-rel_imx_4.1.15_2.1.0_ga CURRENT_PATH := $(shell pwd) -obj-m := keyinput.o +obj-m := ap3216c.o build: kernel_modules diff --git a/21_iic/ap3216c.c b/21_iic/ap3216c.c index c8c91eb..00fe916 100644 --- a/21_iic/ap3216c.c +++ b/21_iic/ap3216c.c @@ -17,8 +17,8 @@ #include #include "ap3216creg.h" -#define AP3216C_CNT -#define AP3216C_NAME "ap3216c" +#define AP3216C_CNT 1 +#define AP3216C_NAME "ap3216c" struct ap3216c_dev { @@ -34,24 +34,110 @@ struct ap3216c_dev static struct ap3216c_dev ap3216cdev; -static int ap3216c_open(struct inode *nd, struct file *filp) +static s32 ap3216c_write_regs(struct ap3216c_dev *dev,u8 reg,u8 *buf,u8 len) { + u8 b[256]; + struct i2c_msg msg; + struct i2c_client *client = (struct i2c_client *)dev->private_data; + b[0] = reg; + memcpy(&b[1], buf, len); + msg.addr = client->addr; + msg.flags = 0; + msg.buf = b; + msg.len = len + 1; + return i2c_transfer(client->adapter, &msg, 1); +} +static void ap3216c_write_reg(struct ap3216c_dev *dev,u8 reg,u8 data) +{ + u8 buf = 0; + buf = data; + ap3216c_write_regs(dev, reg, &buf, 1); } -static ssize_t ap3216c_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) +static int ap3216c_open(struct inode *nd, struct file *filp) { filp->private_data = &ap3216cdev; + ap3216c_write_reg(&ap3216cdev, AP3216C_SYSTEMCONG, 0x04); + mdelay(50); + ap3216c_write_reg(&ap3216cdev, AP3216C_SYSTEMCONG, 0x03); + return 0; +} - +static int ap3216c_read_regs(struct ap3216c_dev *dev,u8 reg,void *val,int len) +{ + int ret; + struct i2c_msg msg[2]; + struct i2c_client *client = (struct i2c_client *)dev->private_data; + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].buf = ® + msg[0].len = 1; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = val; + msg[1].len = len; + + ret = i2c_transfer(client->adapter, msg, 2); + if (ret == 2) + { + ret = 0; + }else { + printk("i2c read failed=%d,reg=%06x,len=%d\r\n", ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +static unsigned char ap3216c_read_reg(struct ap3216c_dev *dev,u8 reg) +{ + u8 data = 0; + ap3216c_read_regs(dev, reg, &data, 1); + return data; +} + +void ap3216c_readdata(struct ap3216c_dev *dev) +{ + unsigned char i = 0; + unsigned char buf[6]; + + for (i = 0; i < 6;i++){ + buf[i] = ap3216c_read_reg(dev, AP3216C_IRDATAHIGH + i); + } + if(buf[0] & 0x80) + dev->ir; + else + dev->ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0x03); + dev->als = ((unsigned short)buf[3] << 8) | buf[2]; + if(buf[4] & 0x40) + dev->ps = 0; + else + dev->ps = ((unsigned short)(buf[5] & 0x3F) << 4) | (buf[4] & 0x0F); +} + +static ssize_t ap3216c_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) +{ + short data[3]; + long err = 0; + struct ap3216c_dev *dev = (struct ap3216c_dev *)filp->private_data; + ap3216c_readdata(dev); + data[0] = dev->ir; + data[1] = dev->als; + data[2] = dev->ps; + err = copy_to_user(buf, data, sizeof(data)); + return 0; } static int ap3216c_release(struct inode *inode, struct file *file) { + return 0; } -static struct file_operations ap3216c_ops = { +static const struct file_operations ap3216c_ops = { .owner = THIS_MODULE, .open = ap3216c_open, .read = ap3216c_read, @@ -66,7 +152,7 @@ static int ap3216c_probe(struct i2c_client *client, const struct i2c_device_id * ap3216cdev.devid = MKDEV(ap3216cdev.major, 0); register_chrdev_region(ap3216cdev.devid, AP3216C_CNT,AP3216C_NAME); }else { - alloc_chrdev_region(&ap3216cdev.devid, 0, AP3216C_CNT, AP3216C_NAME); + alloc_chrdev_region(&ap3216cdev.devid, 0, AP3216C_CNT,AP3216C_NAME); ap3216cdev.major = MAJOR(ap3216cdev.devid); } @@ -136,6 +222,6 @@ static void __exit ap3216c_exit(void) } module_init(ap3216c_init); -module_exit(ap3216c_exitc); +module_exit(ap3216c_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR(“zhangchaoliang”); +MODULE_AUTHOR("zhangchaoliang"); diff --git a/21_iic/ap3216cApp.c b/21_iic/ap3216cApp.c new file mode 100644 index 0000000..610d3b6 --- /dev/null +++ b/21_iic/ap3216cApp.c @@ -0,0 +1,48 @@ +#include "stdio.h" +#include "unistd.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "sys/ioctl.h" +#include "fcntl.h" +#include "stdlib.h" +#include "string.h" +#include +#include +#include +#include +#include + +int main(int argc,char *argv[]) +{ + int fd; + char *filename; + unsigned short databuf[3]; + + unsigned short ir, als, ps; + int ret = 0; + if(argc !=2){ + printf("Error Usage!\r\n"); + return -1; + } + + filename = argv[1]; + fd = open(filename, O_RDWR); + if(fd <0 ){ + printf("can't open file %s\r\n", filename); + return -1; + } + + while (1) + { + ret = read(fd, databuf, sizeof(databuf)); + if(ret == 0){ + ir = databuf[0]; + als = databuf[1]; + ps = databuf[2]; + printf("ir = %d, als = %d, ps = %d\r\n", ir, als, ps); + } + usleep(200000); + } + close(fd); + return 0; +} \ No newline at end of file -- Gitee From 8b9cdcfda9f962db8185f73afc307b4cf740bdce Mon Sep 17 00:00:00 2001 From: sushe_Ubuntu Date: Tue, 25 Jun 2024 21:56:16 +0800 Subject: [PATCH 4/4] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D=EF=BC=8C=E6=98=AF?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=95=B0=E8=8A=82=E7=82=B9=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82i2c=E5=AE=9E=E9=AA=8C=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: sushe_Ubuntu --- 21_iic/ap3216c.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/21_iic/ap3216c.c b/21_iic/ap3216c.c index 00fe916..a30d8be 100644 --- a/21_iic/ap3216c.c +++ b/21_iic/ap3216c.c @@ -105,10 +105,10 @@ void ap3216c_readdata(struct ap3216c_dev *dev) unsigned char buf[6]; for (i = 0; i < 6;i++){ - buf[i] = ap3216c_read_reg(dev, AP3216C_IRDATAHIGH + i); + buf[i] = ap3216c_read_reg(dev, AP3216C_IRDATALOW + i); } if(buf[0] & 0x80) - dev->ir; + dev->ir = 0; else dev->ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0x03); dev->als = ((unsigned short)buf[3] << 8) | buf[2]; @@ -187,16 +187,19 @@ static int ap3216c_remove(struct i2c_client *client) return 0; } -static struct of_device_id ap3216c_of_match[] = { - {.compatible = "alientek,ap3216c" }, +static struct i2c_device_id ap3216c_id[] = { + {"alienek,ap3216c", 0}, {/* */} }; -static struct i2c_device_id ap3216c_id[] = { - {"alienek,ap3216c", 0}, + +static struct of_device_id ap3216c_of_match[] = { + {.compatible = "alientek,ap3216c" }, {/* */} }; + + struct i2c_driver ap3216c_driver = { .probe = ap3216c_probe, .remove = ap3216c_remove, -- Gitee