LED Driver Analysis

Source: Internet
Author: User

Hybrid Equipment LED Driver Analysis

/*******************************
*
* Miscellaneous device driver: Miscdevice
*majior=10;
*
* *****************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/moduleparam.h>//#include memory allocation functions such as <linux/slab.h>//kcalloc,kzalloc
---------IOCTL------------
#include <linux/ioctl.h>
---------Misc_register----
#include <linux/miscdevice.h>
----------Cdev--------------
#include <linux/cdev.h>
----------Delay-------------
#include <linux/delay.h>
----------GPIO---------------
#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#define S3c_gpio_special_mark (0XFFFFFFF0)
#define S3C_GPIO_SPECIAL (x) (S3c_gpio_special_mark | (x)) Kernel definition
#define DEVICE_NAME "LEDs"
static int led_gpios[] = {
S5PV210_MP04 (4),
S5PV210_MP04 (5),
S5PV210_MP04 (6),
S5PV210_MP04 (7),
};//4 an LED
#define Led_num array_size (Led_gpios)
Static long fl210_leds_ioctl (struct file *filp, unsigned int cmd,
unsigned long Arg)
{
Switch (CMD) {
Case 0:
Case 1:
if (Arg > Led_num) {
Return-einval;
}
Gpio_set_value (Led_gpios[arg],!cmd);//Set the led to fade according to CMD
PRINTK (device_name ":%ld%d\n", ARG, CMD);
Break
Default
Return-einval;
}
return 0;
}
static struct File_operations Fl210_led_dev_fops = {
. Owner = This_module,
. Unlocked_ioctl = Fl210_leds_ioctl,
};
----------------miscdevice------------------static struct Miscdevice Fl210_led_dev = {
. minor = Misc_dynamic_minor,
. Name = Device_name,
. FoPs = &fl210_led_dev_fops,
};//--------------------------------------------
static int __init fl210_led_dev_init (void) {
int ret;
int i;
for (i = 0; i < Led_num; i++) {
ret = Gpio_request (Led_gpios[i], "led");//Application Gpio Port
if (ret) {
PRINTK ("%s:request GPIO%d for LED failed, ret =%d\n", Device_name,
Led_gpios[i], ret);
return ret;
}
S3c_gpio_cfgpin (Led_gpios[i], s3c_gpio_output);//set Gpio port as output
Gpio_set_value (Led_gpios[i], 1);//Initialize the value of the Gpio port
}
ret = Misc_register (&fl210_led_dev);//Register Miscellaneous devices
PRINTK (device_name "\tinitialized\n");
PRINTK ("Led num is:%d\n", led_num);
return ret;
}
static void __exit fl210_led_dev_exit (void) {
int i;
for (i = 0; i < Led_num; i++) {
Gpio_free (Led_gpios[i]);//release Gpio port
}
Misc_deregister (&fl210_led_dev);//Logout device
}
Module_init (Fl210_led_dev_init);
Module_exit (Fl210_led_dev_exit);
Module_license ("GPL");
Module_author ("");

S5PV210_MP04 macro defined in Linux/arch/arm/mach-s5pv210/include/mach/gpio.h

#define S5PV210_MP04 (_NR) (S5pv210_gpio_mp04_start + (_NR))

S5pv210_gpio_mp04_start = S5pv210_gpio_next (S5PV210_GPIO_MP03),

#define S5PV210_GPIO_NEXT (__gpio) \ ((__gpio# #_START) + (__gpio# #_NR) + config_s3c_gpio_space + 1)

The CONFIG_S3C_GPIO_SPAC here is the kernel configuration option, which can be found in. config and my configuration is: Config_s3c_gpio_space = 0

The code above uses several functions:

Gpio_set_value ();

S3c_gpio_cfgpin ();

Gpio_request ();

Gpio_free ();

Misc_register ();

Misc_deregister ();

The following will be analyzed individually.

The test procedure is as follows:


#include <stdio.h>//#include "sys/types.h"
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>//read,write et cetera//#include "termios.h"//#include "sys/stat.h"
#include <fcntl.h>
#define LED2_ON 0x1#define Led2_off 0x0
Main (int Argc,char *argv[])
{
int FD;
if (Fd=open ("/dev/leds", O_rdwr/*| O_ndelay | o_noctty*/)) < 0)
{
printf ("Open Device failed.\r\n");
Exit (1);
}
Else
{
printf ("Open Device successed.\r\n");
}
if (argc<3)
{
/* Code */
printf ("Usage:%s <on|off num>\n", argv[0]);
Exit (1);
}
if (!strcmp (argv[1], "on"))
{
printf ("Led1 'll on!! \ n ");
if (IOCTL (Fd,led2_on,atoi (argv[2)) <0)
{
}
}
if (!strcmp (argv[1], "off"))
{
printf ("Led1 'll off!! \ n ");
if (IOCTL (Fd,led2_off,atoi (argv[2)) <0)
{
printf ("Ioctl err!! \ n ");
}
}
Close (FD);
}

First look at S3c_gpio_cfgpin ();

int s3c_gpio_cfgpin (unsigned int pin, unsigned int config)
{
struct S3c_gpio_chip *chip = s3c_gpiolib_getchip (PIN),//get the corresponding gpio struct first pointer, which contains the various parameters of the Gpio
unsigned long flags;
int offset;
int ret;
if (!chip)
Return-einval;
offset = pin-chip->chip.base;
S3c_gpio_lock (chip, flags);
RET = S3C_GPIO_DO_SETCFG (chip, offset, config);//Set the value of the Gpio status Register as Config
S3c_gpio_unlock (chip, flags);
return ret;
}
Static inline struct s3c_gpio_chip *s3c_gpiolib_getchip (unsigned int chip)
{
Return (Chip < s3c_gpio_end)? S3c_gpios[chip]: NULL;
}
static inline int s3c_gpio_do_setcfg (struct s3c_gpio_chip *chip,
unsigned int off, unsigned int config)
{
Return (Chip->config->set_config) (chip, off, config);
}
static struct S3c_gpio_cfg gpio_cfg = {
. Set_config = S3c_gpio_setcfg_s3c64xx_4bit,
. Set_pull = S3c_gpio_setpull_updown,
. Get_pull = S3c_gpio_getpull_updown,
};
int s3c_gpio_setcfg_s3c64xx_4bit (struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
{
void __iomem *reg = chip->base;
unsigned int shift = (off & 7) * 4;
U32 con;
if (Off < 8 && Chip->chip.ngpio > 8)
Reg-= 4;
if (s3c_gpio_is_cfg_special (CFG)) {
CFG &= 0xf;
CFG <<= shift;
}
con = __RAW_READL (reg);//Read Gpxcon value
Con &= ~ (0xf << shift);//zeroing
Con |= cfg;//setting config
__raw_writel (Con, reg);//write value
return 0;
}

The structure of the body s3c_gpio_chip as follows:

*/struct S3c_gpio_chip {
struct gpio_chip chip;
struct S3C_GPIO_CFG *config;
struct S3C_GPIO_PM *pm;
void __iomem *base;
int eint_offset;
spinlock_t lock;
#ifdef CONFIG_PM
U32 pm_save[7]; #endif
};

static struct S3c_gpio_chip s5pv210_gpio_4bit[] = {//description of all GPIO ports in the chip
{
. Chip = {
. Base = s5pv210_gpa0 (0),
. Ngpio = S5pv210_gpio_a0_nr,
. Label = "GPA0",
. TO_IRQ = S5p_gpiolib_gpioint_to_irq,
},
},{
。。。。
}
。。。。
};

Next look at Gpio_set_value ();

void __gpio_set_value (unsigned gpio, int value)
{
struct Gpio_chip *chip;
Chip = Gpio_to_chip (GPIO);//Returns the Gpio_desc[pin].chip pointer warn_on (extra_checks && chip->can_sleep) corresponding to the pin;
Chip->set (Chip, gpio-chip->base, value);//Call Chip->set
}

LED Driver Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.