MC3302_SDK_V1.1.9_202507281.../bsp/test/gpio/gpio_test.c
2025-11-11 12:08:31 +08:00

364 lines
11 KiB
C
Executable File

#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
static int gpio_in_num = -1;
static int gpio_out_num = -1;
static int int_type = -1;
static int gpio_test_case = 0;
module_param(gpio_in_num, int, S_IRUSR);
module_param(gpio_out_num, int, S_IRUSR);
module_param(int_type, int, S_IRUSR);
module_param(gpio_test_case, int, S_IRUSR);
DECLARE_COMPLETION(work);
static irqreturn_t gpio_input_output_interrupt_test_interrupt_call(int irq, void *dev_id)
{
disable_irq_nosync(gpio_to_irq(gpio_in_num));
printk("%s:Interrupt triggered success for gpio:%d irq:%d int_type:%d\n",__FUNCTION__,gpio_in_num,irq,int_type);
complete_all(&work);
return IRQ_HANDLED;
}
static int gpio_input_output_interrupt_test_entry(void)
{
int ret = -1;
printk("%s:current args:gpio_in_num=%d gpio_out_num=%d int_type=%d gpio_test_case=%d\n",__FUNCTION__,gpio_in_num,gpio_out_num,int_type,gpio_test_case);
if(gpio_in_num == -1 || gpio_out_num == -1 || int_type < 1 || int_type > 5)
{
printk("you input args is error!!!\n");
printk("int_type=1 //IRQ_TYPE_EDGE_RISING\n");
printk("int_type=2 //IRQ_TYPE_EDGE_FALLING\n");
printk("int_type=3 //IRQ_TYPE_EDGE_BOTH\n");
printk("int_type=4 //IRQ_TYPE_LEVEL_HIGH\n");
printk("int_type=5 //IRQ_TYPE_LEVEL_LOW\n");
return ret;
}
init_completion(&work);
gpio_free(gpio_in_num);
gpio_free(gpio_out_num);
ret = gpio_request(gpio_in_num, "gpio_in\n");
if (ret != 0) {
printk("error %d: gpio%d request is failed\n",ret,gpio_in_num);
return ret;
}
ret = gpio_request(gpio_out_num, "gpio_out\n");
if (ret != 0) {
printk("error %d: gpio%d request is failed\n",ret,gpio_out_num);
gpio_free(gpio_in_num);
return ret;
}
ret = gpio_direction_input(gpio_in_num);
if (ret != 0) {
printk("error %d: gpio%d direction input is failed\n",ret,gpio_in_num);
goto err;
}
ret = gpio_direction_output(gpio_out_num, 0);
if (ret != 0) {
printk("error %d: gpio%d direction output is failed\n",ret,gpio_out_num);
goto err;
}
if (int_type == 1) {
ret = request_irq(gpio_to_irq(gpio_in_num), gpio_input_output_interrupt_test_interrupt_call, IRQ_TYPE_EDGE_RISING, "gpio_interrupt_edge_rising", NULL);
} else if (int_type == 2) {
ret = request_irq(gpio_to_irq(gpio_in_num), gpio_input_output_interrupt_test_interrupt_call, IRQ_TYPE_EDGE_FALLING, "gpio_interrupt_edge_falling", NULL);
} else if (int_type == 3) {
ret = request_irq(gpio_to_irq(gpio_in_num), gpio_input_output_interrupt_test_interrupt_call, IRQ_TYPE_EDGE_BOTH, "gpio_interrupt_edge_both", NULL);
} else if (int_type == 4) {
ret = request_irq(gpio_to_irq(gpio_in_num), gpio_input_output_interrupt_test_interrupt_call, IRQ_TYPE_LEVEL_HIGH, "gpio_interrupt_level_high", NULL);
} else if (int_type == 5) {
ret = request_irq(gpio_to_irq(gpio_in_num), gpio_input_output_interrupt_test_interrupt_call, IRQ_TYPE_LEVEL_LOW, "gpio_interrupt_level_low", NULL);
}
if(ret != 0) {
printk(KERN_ERR "error %d: request irq is failed gpio:%d irq:%d int_type:%d\n",ret,gpio_in_num,gpio_to_irq(gpio_in_num),int_type);
goto err;
}
gpio_set_value(gpio_out_num ,0);
mdelay(1000);
gpio_set_value(gpio_out_num ,1);
mdelay(1000);
gpio_set_value(gpio_out_num ,0);
mdelay(1000);
gpio_set_value(gpio_out_num ,1);
mdelay(1000);
wait_for_completion_interruptible(&work);
printk("gpio test done\n");
return ret;
err:
gpio_free(gpio_in_num);
gpio_free(gpio_out_num);
return ret;
}
static void gpio_input_output_interrupt_test_exit(void)
{
free_irq(gpio_to_irq(gpio_in_num), NULL);
gpio_free(gpio_in_num);
gpio_free(gpio_out_num);
gpio_in_num = -1;
gpio_out_num = -1;
int_type = -1;
gpio_test_case = 0;
printk("%s:gpio_in_num=%d gpio_out_num=%d int_type=%d gpio_test_case=%d\n",__FUNCTION__,gpio_in_num,gpio_out_num,int_type,gpio_test_case);
}
static void addr_ioremap(unsigned long int phy_addr, unsigned int val)
{
void __iomem *vir = NULL;
vir = ioremap(phy_addr,0x4);
writel(val, vir);
iounmap(vir);
vir = NULL;
}
static void gpio_pin_func(void)
{
addr_ioremap(0x102000ec, 0x1); //pin5
addr_ioremap(0x102000f0, 0x1); //pin6
addr_ioremap(0x10200020, 0x1); //pin9
addr_ioremap(0x10200024, 0x1); //pin10
addr_ioremap(0x10200028, 0x1); //pin11
addr_ioremap(0x1020002c, 0x1); //pin12
addr_ioremap(0x10200030, 0x1); //pin13
addr_ioremap(0x10200034, 0x1); //pin14
addr_ioremap(0x10200038, 0x1); //pin15
addr_ioremap(0x10200048, 0x1); //pin16
addr_ioremap(0x10200054, 0x1); //pin17
addr_ioremap(0x1020004c, 0x1); //pin18
addr_ioremap(0x10200044, 0x1); //pin19
addr_ioremap(0x10200040, 0x1); //pin20
addr_ioremap(0x1020003c, 0x1); //pin21
addr_ioremap(0x10200050, 0x1); //pin22
addr_ioremap(0x102000b4, 0x1); //pin23
addr_ioremap(0x102000b8, 0x1); //pin24
addr_ioremap(0x1020005c, 0x1); //pin25
addr_ioremap(0x10200060, 0x1); //pin26
addr_ioremap(0x10200064, 0x1); //pin27
addr_ioremap(0x10200068, 0x1); //pin28
addr_ioremap(0x1020006c, 0x1); //pin29
addr_ioremap(0x10200070, 0x1); //pin30
addr_ioremap(0x10200074, 0x1); //pin31
addr_ioremap(0x10200078, 0x1); //pin32
addr_ioremap(0x1020007c, 0x1); //pin33
addr_ioremap(0x10200084, 0x1); //pin34
addr_ioremap(0x10200080, 0x1); //pin35
addr_ioremap(0x10200088, 0x1); //pin36
addr_ioremap(0x10200090, 0x1); //pin37
addr_ioremap(0x1020008c, 0x1); //pin38
addr_ioremap(0x10200098, 0x1); //pin39
addr_ioremap(0x10200094, 0x1); //pin40
addr_ioremap(0x1020009c, 0x1); //pin41
addr_ioremap(0x102000a0, 0x1); //pin42
addr_ioremap(0x102000a4, 0x1); //pin43
addr_ioremap(0x102000a8, 0x1); //pin44
addr_ioremap(0x102000ac, 0x1); //pin45
addr_ioremap(0x102000b0, 0x1); //pin46
addr_ioremap(0x102000d0, 0x1); //pin47
addr_ioremap(0x102000cc, 0x1); //pin48
addr_ioremap(0x102000c0, 0x1); //pin49
addr_ioremap(0x102000bc, 0x1); //pin50
addr_ioremap(0x102000c8, 0x1); //pin51
addr_ioremap(0x102000c4, 0x1); //pin52
addr_ioremap(0x102000d4, 0x1); //pin53
addr_ioremap(0x102000d8, 0x1); //pin54
addr_ioremap(0x102000dc, 0x1); //pin55
addr_ioremap(0x102000e0, 0x1); //pin56
addr_ioremap(0x102000e4, 0x1); //pin57
addr_ioremap(0x102000e8, 0x1); //pin58
}
static void gpio_pin_pulldown_en(void)
{
addr_ioremap(0x0b100080, 0x64); //pin5
addr_ioremap(0x0b100084, 0x64); //pin6
addr_ioremap(0x25b00018, 0x64); //pin9
addr_ioremap(0x25b0001C, 0x64); //pin10
addr_ioremap(0x25b00020, 0x64); //pin11
addr_ioremap(0x25b00024, 0x64); //pin12
addr_ioremap(0x25b00028, 0x64); //pin13
addr_ioremap(0x25b0002C, 0x64); //pin14
addr_ioremap(0x25b00030, 0x64); //pin15
addr_ioremap(0x25b00040, 0x64); //pin16
addr_ioremap(0x25b0004C, 0x64); //pin17
addr_ioremap(0x25b00044, 0x64); //pin18
addr_ioremap(0x25b0003C, 0x64); //pin19
addr_ioremap(0x25b00038, 0x64); //pin20
addr_ioremap(0x25b00034, 0x64); //pin21
addr_ioremap(0x25b00048, 0x64); //pin22
addr_ioremap(0x0b100078, 0x64); //pin23
addr_ioremap(0x0b10007C, 0x64); //pin24
addr_ioremap(0x25b00054, 0x64); //pin25
addr_ioremap(0x25b00058, 0x64); //pin26
addr_ioremap(0x0b100028, 0x64); //pin27
addr_ioremap(0x0b10002C, 0x64); //pin28
addr_ioremap(0x0b100030, 0x64); //pin29
addr_ioremap(0x0b100034, 0x64); //pin30
addr_ioremap(0x0b100038, 0x64); //pin31
addr_ioremap(0x0b10003C, 0x64); //pin32
addr_ioremap(0x0b100040, 0x64); //pin33
addr_ioremap(0x0b100048, 0x64); //pin34
addr_ioremap(0x0b100044, 0x64); //pin35
addr_ioremap(0x0b10004C, 0x64); //pin36
addr_ioremap(0x0b100054, 0x64); //pin37
addr_ioremap(0x0b100050, 0x64); //pin38
addr_ioremap(0x0b10005C, 0x64); //pin39
addr_ioremap(0x0b100058, 0x64); //pin40
addr_ioremap(0x0b100060, 0x64); //pin41
addr_ioremap(0x0b100064, 0x64); //pin42
addr_ioremap(0x0b100068, 0x64); //pin43
addr_ioremap(0x0b10006C, 0x64); //pin44
addr_ioremap(0x0b100070, 0x64); //pin45
addr_ioremap(0x0b100074, 0x64); //pin46
addr_ioremap(0x25b00070, 0x64); //pin47
addr_ioremap(0x25b0006C, 0x64); //pin48
addr_ioremap(0x25b00060, 0x64); //pin49
addr_ioremap(0x25b0005c, 0x64); //pin50
addr_ioremap(0x25b00068, 0x64); //pin51
addr_ioremap(0x25b00064, 0x64); //pin52
addr_ioremap(0x25b00074, 0x64); //pin53
addr_ioremap(0x25b00078, 0x64); //pin54
addr_ioremap(0x25b0007C, 0x64); //pin55
addr_ioremap(0x25b00080, 0x64); //pin56
addr_ioremap(0x25b00084, 0x64); //pin57
addr_ioremap(0x25b00088, 0x64); //pin58
}
static irqreturn_t gpio_wakeup_test_interrupt_call(int irq, void *dev_id)
{
disable_irq_nosync(gpio_to_irq(gpio_in_num));
printk("%s:high level Interrupt triggered success for gpio:%d irq:%d\n",__FUNCTION__,gpio_in_num,irq);
return IRQ_HANDLED;
}
static int gpio_wakeup_test_entry(void)
{
int ret = -1;
printk("%s:current args:gpio_in_num=%d gpio_test_case=%d\n",__FUNCTION__,gpio_in_num,gpio_test_case);
if(gpio_in_num == -1)
{
printk("you input args is error\n");
return ret;
}
gpio_free(gpio_in_num);
ret = gpio_request(gpio_in_num, "gpio_in\n");
if (ret != 0) {
printk("error %d: gpio%d request is failed\n",ret,gpio_in_num);
return ret;
}
ret = gpio_direction_input(gpio_in_num);
if (ret != 0) {
printk("error %d: gpio%d direction input is failed\n",ret,gpio_in_num);
goto err;
}
ret = request_irq(gpio_to_irq(gpio_in_num), gpio_wakeup_test_interrupt_call, IRQ_TYPE_LEVEL_HIGH, "gpio_interrupt_level_high", NULL);
if(ret != 0) {
printk(KERN_ERR "error %d: request irq is failed gpio:%d irq:%d int_type:level_high\n",ret,gpio_in_num,gpio_to_irq(gpio_in_num));
goto err;
}
//disable_irq(gpio_to_irq(gpio_in_num));
//enable_irq(gpio_to_irq(gpio_in_num));
printk("gpio waite trigger interrupu .....\n");
return ret;
err:
gpio_free(gpio_in_num);
return ret;
}
static void gpio_wakeup_test_exit(void)
{
free_irq(gpio_to_irq(gpio_in_num), NULL);
gpio_free(gpio_in_num);
gpio_in_num = -1;
gpio_test_case = 0;
printk("%s:gpio_in_num=%d int_type=level_high gpio_test_case=%d\n",__FUNCTION__,gpio_in_num,gpio_test_case);
}
static void gpio_test_case_message(void)
{
printk("\ndescription:\n");
printk("you input:\n");
printk("insmod gpio_test.ko gpio_in_num= gpio_out_num= int_type= gpio_test_case=0\n");
printk("test gpio input/output/interrupt\n");
printk("you input:\n");
printk("insmod gpio_test.ko gpio_in_num= gpio_test_case=1\n");
printk("test gpio wakeup\n\n");
}
static int __init gpio_test_init(void)
{
printk("%s.....\n",__FUNCTION__);
gpio_test_case_message();
gpio_pin_func();
gpio_pin_pulldown_en();
switch (gpio_test_case) {
case 0 :
gpio_input_output_interrupt_test_entry();
break;
case 1 :
gpio_wakeup_test_entry();
break;
default :
printk("%s err, no this gpio_test_case(%d).....\n",__FUNCTION__,gpio_test_case);
}
return 0;
}
static void __exit gpio_test_exit(void)
{
printk("%s.....\n",__FUNCTION__);
switch (gpio_test_case) {
case 0 :
gpio_input_output_interrupt_test_exit();
break;
case 1 :
gpio_wakeup_test_exit();
break;
default :
printk("%s err, no this gpio_test_case(%d).....\n",__FUNCTION__,gpio_test_case);
}
}
module_init(gpio_test_init);
module_exit(gpio_test_exit);
MODULE_LICENSE("GPL v2");