完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1. DTS路径为rv1126linux-4.19archarmbootdts
在rv1126.dtsi上添加以下部分: gpio_para: gpio_para { compatible = "rk,gpio-para"; status = "disabled"; sata-en-gpio = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; lphout-cs-gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; sd0-en-gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_LOW>; reset-hub-gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>; led2-gpio = <&gpio1 RK_PC0 GPIO_ACTIVE_HIGH>; wifi-crl-gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; ads-dms-voice-en-gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>; rt4812-en-gpio = <&gpio1 RK_PC5 GPIO_ACTIVE_HIGH>; vcc-12v-en-gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; led1-gpio = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; sd1-en-gpio = <&gpio1 RK_PD1 GPIO_ACTIVE_LOW>; mc-dj-gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; spk-dj-int-gpio = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>; }; 2. 在rv1126kerneldrivers 下添加gpio_para源码: #include #include #include #include #include #include #include #include #include #include #include struct device *g_dev = NULL; //struct mutex node_mutex; static DEFINE_MUTEX(gpio_para_mutex); /* gpio_para: gpio_para { compatible = "rk,gpio-para"; status = "disabled"; sata-en-gpio = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; lphout-cs-gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; sd0-en-gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_LOW>; reset-hub-gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>; led2-gpio = <&gpio1 RK_PC0 GPIO_ACTIVE_HIGH>; wifi-crl-gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; ads-dms-voice-en-gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>; rt4812-en-gpio = <&gpio1 RK_PC5 GPIO_ACTIVE_HIGH>; vcc-12v-en-gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; led1-gpio = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; sd1-en-gpio = <&gpio1 RK_PD1 GPIO_ACTIVE_LOW>; mc-dj-gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>; spk-dj-int-gpio = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>; }; */ #define SATA_EN_GPIO "sata-en-gpio" #define LPHOUT_CS_GPIO "lphout-cs-gpio" #define SD0_EN_GPIO "sd0-en-gpio" #define RESET_HUB_GPIO "reset-hub-gpio" #define LED2_GPIO "led2-gpio" #define WIFI_CRL_GPIO "wifi-crl-gpio" #define ADS_DMS_VOICE_EN_GPIO "ads-dms-voice-en-gpio" #define RT4812_EN_GPIO "rt4812-en-gpio" #define VCC_12V_EN_GPIO "vcc-12v-en-gpio" #define LED1_GPIO "led1-gpio" #define SD1_EN_GPIO "sd1-en-gpio" #define MC_DJ_GPIO "mc-dj-gpio" #define SPK_DJ_INT_GPIO "spk-dj-int-gpio" enum gpio_para_item { GPIO_PARA_SATA_EN = 0, //GPIO0-A4 : 硬盘功能使能 GPIO_PARA_LPHOUT_CS, //GPIO0-A5 : 对讲功放使能 GPIO_PARA_SD0_EN, //GPIO0-C1 : SD卡0电源使能 GPIO_PARA_RESET_HUB, //GPIO0-C2 : HUB芯片复位 GPIO_PARA_LED2, //GPIO1-C0 : 前面板硬盘指示灯 GPIO_PARA_WIFI_CRL, //GPIO1-C1 : WIFI电源控制 GPIO_PARA_ADS_DMS_VOICE_EN, //GPIO1-C4 : 主动安全报警功放使能 GPIO_PARA_RT4812_EN, //GPIO1-C5 : ADAS/DSM摄像头电源控制 GPIO_PARA_VCC_12V_EN, //GPIO1-C6 : 3-8路摄像头电源使能 GPIO_PARA_LED1, //GPIO1-C7 : RV1126工作指示灯 GPIO_PARA_SD1_EN, //GPIO1-D1 : SD卡1电源使能 GPIO_PARA_MC_DJ, //GPIO1-D2 : 手唛检测 GPIO_PARA_SPK_DJ_INT, //GPIO1-D3 : 喇叭检测 GPIO_PARA_ITEM_BUTT, }; struct bsj_gpio_para { char label[32]; int gpio_num; int io_dir_init; enum of_gpio_flags flags; }; struct bsj_gpio_para gpio_para[] = { //sata_en {SATA_EN_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //lphout_cs {LPHOUT_CS_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //sd0_en {SD0_EN_GPIO, -1, GPIOF_OUT_INIT_LOW, OF_GPIO_ACTIVE_LOW}, //reset_hub {RESET_HUB_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //led2 {LED2_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //wifi_crl {WIFI_CRL_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //ads_dms_voice_en {ADS_DMS_VOICE_EN_GPIO, -1, GPIOF_OUT_INIT_LOW, OF_GPIO_ACTIVE_LOW}, //rt4812_en {RT4812_EN_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //vcc_12v_en {VCC_12V_EN_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //led1 {LED1_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //sd1_en {SD1_EN_GPIO, -1, GPIOF_OUT_INIT_LOW, OF_GPIO_ACTIVE_LOW}, //mc_dj {MC_DJ_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, //spk_dj_int {SPK_DJ_INT_GPIO, -1, GPIOF_OUT_INIT_HIGH, OF_GPIO_ACTIVE_LOW}, }; #define CMD_GET_GPIO_V (0xA0) #define CMD_SET_GPIO_V (0xA1) #define CMD_FREE_GPIO (0xA2) struct user_data { enum gpio_para_item gpio_item; // int gpio_num; //maybe unused int value; }; static int gpio_para_open(struct inode *inode, struct file *filp) { return 0; } /* 如果在使用该 GPIO 时,不会动态的切换输入输出,建议在开始时就设置好 GPIO 输出方向,后面拉高拉低时使用 gpio_set_value()接口, 而不建议使用 gpio_direction_output(), 因为 gpio_direction_output 接口里面有 mutex 锁,对中断上下文调用会有错误异常, 且相比 gpio_set_value,gpio_direction_output 所做事情更多,浪费. */ static long gpio_para_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { long ret = 0; struct user_data userdata; int current_gpio_num = -1; mutex_lock(&gpio_para_mutex); memset(&userdata, 0, sizeof(struct user_data)); if (copy_from_user((void*)&userdata,(void __user *)arg, sizeof(struct user_data))) { ret = -EFAULT; goto out; } if (userdata.gpio_item >= GPIO_PARA_ITEM_BUTT) { ret = -EFAULT; goto out; } current_gpio_num = gpio_para[userdata.gpio_item].gpio_num; if (!gpio_is_valid(current_gpio_num)) { ret = -EFAULT; goto out; } switch (cmd) { case CMD_GET_GPIO_V: { userdata.value = gpio_get_value(current_gpio_num); if (copy_to_user((struct msg __user *)arg, &userdata, sizeof(struct user_data))) { ret = -EFAULT; } break; } case CMD_SET_GPIO_V: { gpio_set_value(current_gpio_num, !!userdata.value); break; } case CMD_FREE_GPIO: { devm_gpio_free(g_dev, current_gpio_num); break; } default: { break; } } out: mutex_unlock(&gpio_para_mutex); return ret; } static int gpio_para_release(struct inode *inode, struct file *filp) { return 0; } static struct file_operations gpio_para_fops = { .owner = THIS_MODULE, .open = gpio_para_open, .unlocked_ioctl = gpio_para_ioctl, .release = gpio_para_release, }; static struct miscdevice gpio_para_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "gpio_para", .fops = &gpio_para_fops, }; static int gpio_para_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = pdev->dev.of_node; int ret = 0; int index = 0; int gpio_cnt = 0; g_dev = dev; gpio_cnt = sizeof(gpio_para)/sizeof(gpio_para[0]); for (index = 0; index < gpio_cnt; index++) { gpio_para[index].gpio_num = of_get_named_gpio_flags(node, gpio_para[index].label, 0, &gpio_para[index].flags); ret = devm_gpio_request_one(dev, gpio_para[index].gpio_num, gpio_para[index].io_dir_init, gpio_para[index].label); if (ret) { dev_err(dev, "line : %d, failed to request gpio [%d] [%d]: %dn", __LINE__, index, gpio_para[index].gpio_num, ret); gpio_para[index].gpio_num = -1; } } ret = misc_register(&gpio_para_dev); if (ret < 0) { printk(KERN_INFO "[%s][%d] misc_register gpio para error!n", __FUNCTION__, __LINE__); return ret; } printk("debug here : %s - %dn", __FUNCTION__, __LINE__); return 0; } static int gpio_para_remove(struct platform_device *pdev) { int index = 0; int gpio_cnt = 0; gpio_cnt = sizeof(gpio_para)/sizeof(gpio_para[0]); for (index = 0; index < gpio_cnt; index++) { if (gpio_para[index].gpio_num != -1) { devm_gpio_free(&pdev->dev, gpio_para[index].gpio_num); } } misc_deregister(&gpio_para_dev); return 0; } static const struct of_device_id gpio_para_of_id[] = { {.compatible = "rk,gpio-para",}, {} }; static struct platform_driver gpio_para_platform_driver = { .probe = gpio_para_probe, .remove = gpio_para_remove, .driver = { .name = "rockchip,gpio-para", .owner = THIS_MODULE, .of_match_table = gpio_para_of_id, }, }; static int __init gpio_para_init(void) { platform_driver_register(&gpio_para_platform_driver); return 0; } static void __exit gpio_para_exit(void) { platform_driver_unregister(&gpio_para_platform_driver); } device_initcall(gpio_para_init); //module_init(gpio_para_init); module_exit(gpio_para_exit); MODULE_AUTHOR("chz"); MODULE_DESCRIPTION("set bsj board gpio para"); MODULE_LICENSE("GPL"); 3. 添加应用测试程序: #include #include #include #include #include #include #include #include #include #include #define CMD_GET_GPIO_V (0xA0) #define CMD_SET_GPIO_V (0xA1) #define CMD_FREE_GPIO (0xA2) enum gpio_para_item { GPIO_PARA_SATA_EN = 0, //GPIO0-A4 : 硬盘功能使能 GPIO_PARA_LPHOUT_CS, //GPIO0-A5 : 对讲功放使能 GPIO_PARA_SD0_EN, //GPIO0-C1 : SD卡0电源使能 GPIO_PARA_RESET_HUB, //GPIO0-C2 : HUB芯片复位 GPIO_PARA_LED2, //GPIO1-C0 : 前面板硬盘指示灯 GPIO_PARA_WIFI_CRL, //GPIO1-C1 : WIFI电源控制 GPIO_PARA_ADS_DMS_VOICE_EN, //GPIO1-C4 : 主动安全报警功放使能 GPIO_PARA_RT4812_EN, //GPIO1-C5 : ADAS/DSM摄像头电源控制 GPIO_PARA_VCC_12V_EN, //GPIO1-C6 : 3-8路摄像头电源使能 GPIO_PARA_LED1, //GPIO1-C7 : RV1126工作指示灯 GPIO_PARA_SD1_EN, //GPIO1-D1 : SD卡1电源使能 GPIO_PARA_MC_DJ, //GPIO1-D2 : 手唛检测 GPIO_PARA_SPK_DJ_INT, //GPIO1-D3 : 喇叭检测 GPIO_PARA_ITEM_BUTT, }; struct user_data { enum gpio_para_item gpio_item; // int gpio_num; //maybe unused int value; }; int get_gpio_value(int fd, enum gpio_para_item user_gpio_item) { struct user_data userdata; memset(&userdata, 0, sizeof(struct user_data)); userdata.gpio_item = user_gpio_item; ioctl(fd, CMD_GET_GPIO_V, &userdata); printf("[%d] -> [%d]n", userdata.gpio_item, userdata.value); return userdata.value; } int set_gpio_value(int fd, enum gpio_para_item user_gpio_item, int value) { int ret = -1; struct user_data userdata; memset(&userdata, 0, sizeof(struct user_data)); userdata.gpio_item = user_gpio_item; userdata.value = value; ret = ioctl(fd, CMD_SET_GPIO_V, &userdata); printf("[%d] -> [%d]n", userdata.gpio_item, userdata.value); return ret; } int release_gpio(int fd, enum gpio_para_item user_gpio_item) { int ret = -1; struct user_data userdata; memset(&userdata, 0, sizeof(struct user_data)); userdata.gpio_item = user_gpio_item; ret = ioctl(fd, CMD_FREE_GPIO, &userdata); return ret; } int main(int argc, char *argv[]) { int fd_gpio_dev = -1; enum gpio_para_item user_gpio_item = GPIO_PARA_ITEM_BUTT; int value = 0; fd_gpio_dev = open("/dev/gpio_para", O_RDWR); if (fd_gpio_dev < 0) { printf("line : %d, open /dev/gpio_para failn", __LINE__); return -1; } if (argc == 2) { user_gpio_item = atoi(argv[1]); value = get_gpio_value(fd_gpio_dev, user_gpio_item); } else if (argc == 3) { user_gpio_item = atoi(argv[1]); value = atoi(argv[2]); set_gpio_value(fd_gpio_dev, user_gpio_item, value); } else if (argc == 4) { user_gpio_item = atoi(argv[1]); if (0 == atoi(argv[2]) && 0 == strncmp("free", argv[3], 4)) { release_gpio(fd_gpio_dev, user_gpio_item); } } else { printf("usage:n"); printf("get gpio value: ./iotest gpio_para_itemn"); printf("set gpio value: ./iotest gpio_para_item valuen"); printf("free gpio: ./iotest gpio_para_item 0 freen"); } close(fd_gpio_dev); return 0; } |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
533 浏览 0 评论
803 浏览 1 评论
700 浏览 1 评论
1926 浏览 1 评论
3171 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 18:34 , Processed in 0.649938 second(s), Total 71, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号