点击(此处)折叠或打开
- /**
- * AM1808 5*4矩阵键盘驱动
- * 最后得到从1到20编号的键值
- * Lzy 2012-913
- */
- struct status /*位段类型定义*/
- {
- unsigned char bit1: 1; /*定义bit1占2个二进制位,其范围0~8*/
- unsigned char bit2: 1;
- unsigned char bit3: 1;
- unsigned char bit4: 1;
- unsigned char bit5: 1;
- };
- union Data /*定义联合体*/
- {
- unsigned int x;
- struct status Byte;
- };
- void key_row_set_value(unsigned char cx) // 设置行值
- {
- int i;
- union Data data = {cx}; /*初始化*/
-
- for(i=0; i<5; i++)
- gpio_direction_output(key_row_num[i], 0); // 使能GPIO時钟
-
- // 设置GPIO点平
- gpio_set_value(ROW_1, data.Byte.bit1);
- gpio_set_value(ROW_2, data.Byte.bit2);
- gpio_set_value(ROW_3, data.Byte.bit3);
- gpio_set_value(ROW_4, data.Byte.bit4);
- gpio_set_value(ROW_5, data.Byte.bit5);
- }
- unsigned int key_row_get_value(void) // 得到行值
- {
- int i;
- union Data data = {0}; /*初始化*/
-
- for(i=0; i<5; i++)
- gpio_direction_input(key_row_num[i]); // 使能GPIO時钟
-
- // 得到GPIO点平
- data.Byte.bit1 = gpio_get_value(ROW_1) > 0 ? 1:0;
- data.Byte.bit2 = gpio_get_value(ROW_2) > 0 ? 1:0;
- data.Byte.bit3 = gpio_get_value(ROW_3) > 0 ? 1:0;
- data.Byte.bit4 = gpio_get_value(ROW_4) > 0 ? 1:0;
- data.Byte.bit5 = gpio_get_value(ROW_5) > 0 ? 1:0;
-
- return data.x;
- }
- void key_column_set_value(unsigned char cx) // 设置列值
- {
- int i;
- union Data data = {cx}; /*初始化*/
-
- for(i=0; i<4; i++)
- gpio_direction_output(key_column_num[i], 0); // 使能GPIO時钟
-
- // 设置GPIO点平
- gpio_set_value(column_1, data.Byte.bit1);
- gpio_set_value(column_2, data.Byte.bit2);
- gpio_set_value(column_3, data.Byte.bit3);
- gpio_set_value(column_4, data.Byte.bit4);
- }
- unsigned int key_column_get_value(void) // 得到列值
- {
- int i;
- union Data data = {0}; /*初始化*/
-
- for(i=0; i<4; i++)
- gpio_direction_input(key_column_num[i]); // 使能GPIO時钟
-
- // 得到GPIO点平
- data.Byte.bit1 = gpio_get_value(column_1) > 0 ? 1:0;
- data.Byte.bit2 = gpio_get_value(column_2) > 0 ? 1:0;
- data.Byte.bit3 = gpio_get_value(column_3) > 0 ? 1:0;
- data.Byte.bit4 = gpio_get_value(column_4) > 0 ? 1:0;
-
- return data.x;
- }
- int get_column_biye(int col)
- {
- int io_value = 0;
-
- gpio_direction_input(key_column_num[col]); // 使能GPIO時钟
- io_value = gpio_get_value( key_column_num[col]);
- if(io_value)
- return 1;
- else
- return 0;
- }
- int key_scan(int column)
- {
- int key = -1;
- unsigned char i, temp = 1 ;
-
- mdelay(5);
-
- for(i=0; i<5; i++)
- {
- key_row_set_value(~temp);
- udelay(10);
-
- if(get_column_biye(column) == 0)
- break;
- temp <<= 1;
- }
-
- if(i != 5)
- key = i * 4 + column ;
-
- // printk(" key=%d \n",key);
- mdelay(30);
-
- return key+1;
- }
- static void unmaskkey(void) // 使能所有中断
- {
- int i, irq;
-
- for(i=0; i<4; i++)
- {
- irq = gpio_to_irq(key_column_num[i]);
- enable_irq(irq);
- }
- }
- static void maskkey(void) //禁址所有中断
- {
- int i, irq;
-
- for(i=0; i<4; i++)
- {
- irq = gpio_to_irq(key_column_num[i]);
- disable_irq_nosync(irq);
- }
- }
- static irqreturn_t am1808_key_irqhandler(int irq, void *dev_id)
- {
- maskkey();
-
- key_devices->key_value = key_scan(irq-221); // irq是220开始一直住后面加
- wake_up(&(key_devices->ing)); // 换醒等待队列
-
- /** 引郐复位为下次中断做准备 */
- key_row_set_value(0);
- while(key_column_get_value() != 0x0f); // 等待按键松开
-
- // printk("irq key=%d\n", key_devices->key_value );
- unmaskkey();
- return IRQ_HANDLED;
- }
- static int am1808_request_irqs(int i)
- {
- if(request_irq(gpio_to_irq(key_column_num[i]), am1808_key_irqhandler, IRQ_TYPE_EDGE_FALLING, "KEY_irq", NULL))
- {
- printk("request INT0 error\n");
- free_irq(gpio_to_irq(key_column_num[i]), NULL);
- return -1;
- }
- return 0;
- }
- int key_init_pin(void) // 初始化引郐
- {
- int i, status = 0;
-
- for(i=0; i<5; i++)
- {
- status = davinci_cfg_reg( key_row_gpio_pin[i]); // 设置引脚为GPIO功能
- if (status < 0)
- {
- printk("pin could not be muxed for GPIO functionality %d\n",key_row_num[i]);
- return status;
- }
-
- status = gpio_request(key_row_num[i], "gpio_key\n"); // 引脚是否已经配置成GPIO功能
- if (status < 0)
- {
- printk("ERROR can not open GPIO %d\n", key_row_num[i]);
- return status;
- }
-
- gpio_direction_output(key_row_num[i], 0); // 使能GPIO時钟
- gpio_set_value(key_row_num[i],0); // 设置GPIO默认值为低点平
- }
-
- for(i=0; i<4; i++)
- {
- status = davinci_cfg_reg( key_column_gpio_pin[i]); // 设置引脚为GPIO功能
- if (status < 0)
- {
- printk("pin could not be muxed for GPIO functionality %d\n", key_column_num[i]);
- return status;
- }
-
- status = gpio_request(key_column_num[i], "gpio_key\n"); // 引脚是否已经配置成GPIO功能
- if (status < 0)
- {
- printk("ERROR can not open GPIO %d\n", key_column_num[i]);
- return status;
- }
-
- gpio_direction_input(key_column_num[i]); // 使能GPIO時钟
-
- status = am1808_request_irqs(i);
- if(status < 0)
- {
- printk("am1808_request_irqs %d faild\n", i);
- return status;
- }
-
- }
-
- return status;
- }
