linux下点灯问题
硬件平台:OMAP-L138
软件平台:linux-2.6.32+VMware
问题描述:
板子上有个CPLD,CPLD的逻辑关系开发商不给,只给了文档描述,如下:
我自己写了个字符驱动用来控制灯的状态:
代码如下:
static int __init hello_init(void){ unsigned long led_addr; led_addr = (unsigned long)ioremap(0x64000040,0x08); printk("\nled_addr is 0x%x.\n",led_addr); writel(0x00,led_addr); iounmap(led_addr); printk("\nhelloword:: Hello module is installed!!!!!!\n"); return 0;}这个驱动,请根据你的需要进行修改。#include <linux/config.h>#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fcntl.h>#include <linux/fs.h>#include <linux/types.h>#include <linux/input.h>#include <asm/io.h>void *R_GPBCON;void *R_GPBDAT;static u32 resave_gpbcon;static u32 resave_gpbdat;static struct input_dev my_led_dev;static void iomap_gpb(void){ R_GPBCON = ioremap(0x56000010,0x4); R_GPBDAT = ioremap(0x56000014,0x4);}static void unmap_gpb(void){ iounmap(R_GPBCON); iounmap(R_GPBDAT);}static void init_led_reg(void){ u32 temp; resave_gpbcon = __raw_readl(R_GPBCON); resave_gpbdat = __raw_readl(R_GPBDAT); temp = resave_gpbcon & (~(0xff << 10)); temp |= ((0x1 << 10) | (0x1 << 12)| \ (0x1 << 14) | (0x1 << 16)); __raw_writel(temp,R_GPBCON); temp = resave_gpbdat | ( 0xf << 5); __raw_writel(temp,R_GPBDAT); }static void resave_led_reg(void){ __raw_writel(resave_gpbcon,R_GPBCON); __raw_writel(resave_gpbdat,R_GPBDAT);}static int my_led_event(struct input_dev *dev, \ unsigned int type, unsigned int code, int value) { u32 temp; if (type != EV_LED) return -1; switch (code) { case LED_NUML: break; default: return -1; } temp = __raw_readl(R_GPBDAT); temp &= (~(0xf << 5)); __raw_writel(temp | value,R_GPBDAT); return 0;}static int __init my_led_init(void){ init_input_dev(&my_led_dev); my_led_dev.evbit[0] = BIT(EV_LED); my_led_dev.ledbit[0] = BIT(LED_NUML); my_led_dev.event = my_led_event; my_led_dev.name = "my_led_name"; my_led_dev.phys = "my_led_phys"; my_led_dev.id.bustype = BUS_HOST; my_led_dev.id.vendor = 0x001f; my_led_dev.id.product = 0x0001; my_led_dev.id.version = 0x0100; iomap_gpb(); init_led_reg(); input_register_device(&my_led_dev); return 0;}static void __exit my_led_exit(void){ resave_led_reg(); unmap_gpb(); input_unregister_device(&my_led_dev);}module_init(my_led_init);module_exit(my_led_exit);下面为测试程序#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <linux/ioctl.h>#include <linux/types.h>#include <linux/delay.h>#include <linux/input.h>#include <stdio.h>int main(void){ struct input_event my_led_event; __s32 ret; __s32 fb; __u32 loop; __u32 led_buffer[4] = {0xE,0xD,0xB,0x7}; fb = open("/dev/input/event1",O_RDWR); if (fb < 0){ printf("open error!\n"); exit(1); } my_led_event.type = EV_LED; my_led_event.code = LED_NUML; loop = 0; while (1){ loop &= 0x3; my_led_event.value = *(led_buffer + loop) << 5; ret = write(fb,&my_led_event,sizeof(struct input_event)); if (ret < 0){ printf("write error!\n"); exit(1); } sleep(1); loop ++; } return 0;}