LED Operation of Quanzhi A33 Driver Development

Keywords: Linux Makefile Android shell

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)

Posted by Space Cowboy on Tue, 08 Oct 2019 09:39:00 -0700