LED Operation of Quanzhi A33 Driver Development
I. Overall description
_The development board used in this time is vstar2 of RERVISION. The development board is shown in the following figure. This example uses the probe function of the platform device to register a misc device. Form Jay_leds device files from the front under / dev / directory. Operate through ioctl function. Turn on and turn off the LED lights.
II. Notes
1. The configuration description of GPIO in fex file:
Use of GPIO configuration scripts:
_Port: Port + Group Sequence Number < Function Allocation > < Internal Resistance Status > < Driving Capability > < Output Level Status >
2. Configuration in sys_config.fex:
;----------------------------------------------------------------------------------
;leds config parameters
;leds_used 0:uboot charging, 1:android charging
;----------------------------------------------------------------------------------
[leds_para]
leds_used = 0
red_led = port:PB02<1><0>
3. Get the configuration in sys_config.fex: (see the driver file in detail)
type = script_get_item("leds_para", "red_led", &led_val);
4. Kernel configuration:
_Because the development kit provided by a33 is compiled by script, build root has its own generation compilation tool. There are no specific compiler tools and architectures in linux kernel.
_Here are two configurations to be set up as follows: (Remove the original configuration)
#ARCH ?= $(SUBARCH)
#CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
ARCH ?= arm
CROSS_COMPILE ?= /home/mydocuments/linux_kernel/a33/dragonboard/out/sun8iw5p1/dragonboard/common/buildroot/external-toolchain/bin/arm-linux-gnueabi-
5. Compile and test program:
/home/mydocument/arm-gcc/arm-2009q3/bin/arm-none-linux-gnueabi-gcc led.c -o leds_test
3. Implementing led driver
1. Source files
/**************************************************START OF FILE*****************************************************/ /* ------------------------------------------------------------------------------------------------------------------ Contains header files */ #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <mach/gpio.h> #include <linux/miscdevice.h> #include <linux/platform_device.h> #include <asm/io.h> #include <linux/regulator/consumer.h> #include <linux/delay.h> #include <mach/hardware.h> #include <mach/platform.h> #include <mach/sys_config.h> #include <linux/gpio.h> /* ------------------------------------------------------------------------------------------------------------------ Macro Definition */ //Configure whether to turn on print information #define DEBUG 1 #ifdef DEBUG #define dprintk( argc, argv... ) printk( argc, ##argv ) #else #define dprintk( argc, argv... ) #endif //platform device correlation function static int leds_probe(struct platform_device *pdev); static int leds_remove (struct platform_device *pdev); static int leds_suspend (struct platform_device *pdev, pm_message_t state); static int leds_resume (struct platform_device *pdev); //misc driver correlation function int leds_release(struct inode *inode,struct file *filp); int leds_open(struct inode *inode,struct file *filp); long leds_ioctl(struct file *filp,unsigned int cmd,unsigned long arg); /* ------------------------------------------------------------------------------------------------------------------ Definition of data structure */ //Used to mark GPIO port information static script_item_u led_val; struct platform_device led_device = { .name = "mooer_a33_leds", }; //platform driver static struct platform_driver leds_driver = { .probe = leds_probe, //Platform driver is called when it matches device. .remove = leds_remove, //Platform Driver Call When Unloading .suspend = leds_suspend, //Called when suspended .resume = leds_resume, //Called upon recovery .driver = { .name = "mooer_a33_leds", //Platform driver name for matching platform device, leds here .owner = THIS_MODULE, }, }; //Stray file_ops static struct file_operations leds_ops = { .owner = THIS_MODULE, .open = leds_open, .release= leds_release, .unlocked_ioctl = leds_ioctl, //The main function is to control the switch of LED. }; //Spurious device static struct miscdevice leds_dev = { .minor = MISC_DYNAMIC_MINOR, .fops = &leds_ops, //Implementation of Document Operating Interface for Stray Devices .name = "Jay_leds", //Used to generate dev/Jay_leds device files }; /* ********************************************************************************************************************* @ Name : int leds_open(struct inode *inode,struct file *filp) @ Brief : Opening File Operations for Stray Devices @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ int leds_open(struct inode *inode,struct file *filp) { dprintk("Device Opened Success!\n"); //Location is not allowed return nonseekable_open(inode,filp); } /* ********************************************************************************************************************* @ Name : int leds_release(struct inode *inode,struct file *filp) @ Brief : Closing File Operations for Stray Devices @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ int leds_release(struct inode *inode,struct file *filp) { dprintk("Device Closed Success!\n"); return 0; } /* ********************************************************************************************************************* @ Name : long leds_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) @ Brief : ioctl operation in file_ops of stray devices @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ long leds_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) { printk("debug: leds_ioctl cmd is %d\n" , cmd); switch(cmd) { case 0: case 1: //Turn on and off LED gpio_set_value(led_val.gpio.gpio, cmd); break; default: return -EINVAL; } return 0; } /* ********************************************************************************************************************* @ Name : static int leds_probe(struct platform_device *pdev) @ Brief : Mainly register a stray device, initialize IO port @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ static int leds_probe(struct platform_device *pdev) { int ret; //char leds_para[16] = {0}; script_item_value_type_e type; dprintk("+%s()\n", __FUNCTION__); type = script_get_item("leds_para", "red_led", &led_val); if (type != SCIRPT_ITEM_VALUE_TYPE_PIO) { dprintk("get gpio message error"); return -1; } //Apply for GPIO ret = gpio_request(led_val.gpio.gpio, NULL); if (ret) { printk("request gpio error\n"); return ret; } //Set to Output gpio_direction_output(led_val.gpio.gpio, 0); //Set GPIO to High Level gpio_set_value(led_val.gpio.gpio, 1); //Registered Stray Equipment ret = misc_register(&leds_dev); if(ret<0) { printk("leds:register device failed!\n"); goto exit; } dprintk("-%s()\n", __FUNCTION__); return 0; exit: misc_deregister(&leds_dev); return ret; } /* ********************************************************************************************************************* @ Name : static int leds_remove (struct platform_device *pdev) @ Brief : leds platform driver Removal of equipment @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ static int leds_remove (struct platform_device *pdev) { dprintk("leds remove\n"); //Remove stray equipment misc_deregister(&leds_dev); return 0; } /* ********************************************************************************************************************* @ Name : static int leds_suspend (struct platform_device *pdev, pm_message_t state) @ Brief : leds platform driver Hang up @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ static int leds_suspend (struct platform_device *pdev, pm_message_t state) { dprintk("leds suspend:power off!\n"); return 0; } /* ********************************************************************************************************************* @ Name : static int leds_resume (struct platform_device *pdev) @ Brief : leds platform driver restart @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ static int leds_resume (struct platform_device *pdev) { dprintk("leds resume:power on!\n"); return 0; } /* ********************************************************************************************************************* @ Name : static int __init leds_init(void) @ Brief : Module entry function, register a platform driver @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ static int __init leds_init(void) { dprintk("+%s()\n", __FUNCTION__); if (platform_device_register(&led_device)) { printk("%s: register gpio device failed\n", __func__); } dprintk("-%s()\n", __FUNCTION__); //Platform-driven registration return platform_driver_register(&leds_driver); } /* ********************************************************************************************************************* @ Name : static void __exit leds_exit(void) @ Brief : Module exit function, anti-registration of a platform driver @ Param : NONE @ Return : NONE @ Author : YWJ ********************************************************************************************************************* */ static void __exit leds_exit(void) { dprintk("+%s()\n", __FUNCTION__); //Platform-driven unloading dprintk("-%s()\n", __FUNCTION__); platform_driver_unregister(&leds_driver); } //Define load and unload functions for modules module_init(leds_init); module_exit(leds_exit); //Define compliance agreements MODULE_LICENSE("Dual BSD/GPL"); /**************************************************END OF FILE**********************************************************/
2. Makefile file file
obj-m := mooer_a33_leds.o KERNEL_DIR :=/home/mydocuments/linux_kernel/a33/dragonboard/linux-3.4/ PWD := $(shell pwd) all: make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules clean: rm *.o *.ko *.mod.c .PHONY:clean
IV. Application Programs for Implementing Testing
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define MAXC 10 main() { int fd; char gpio[MAXC],cmd[MAXC]; char *leds = "/dev/Jay_leds"; if((fd = open(leds, O_RDWR|O_NOCTTY|O_NDELAY))<0) { printf("open %s failed\n",leds); } else { while(1) { //Open LED 2-3 ioctl(fd,1,0); ioctl(fd,1,1); sleep(1); //Open LED 2-3 ioctl(fd,0,0); ioctl(fd,0,1); sleep(1); } } }
Fifth, schematic diagram
Sweeping into the group, you can download related files in the group file (QQ2413298768)