韦东山老师的Linux驱动设计基础课程的p128 5_101 驱动设计的思想_面向对象_分层_分离这课在开发板上实作练习,可控制imx6ull_pro板子的LED开关。
基于韦老师代码的基础上,更改如下代码:
led_resource.h
#ifndef _LED_RESOURCE_H
#define _LED_RESOURCE_H
#define GROUP(x) (x>>16)
#define PIN(x) (x&0xFFFF)
#define GROUP_PIN(g,p) ((g<<16) | (p))
#define GPIO5_IO3 1
struct led_resource {
int pin;
};
struct led_resource *get_led_resource(void);
#endif
board_A_led.c
#include "led_resource.h"
static struct led_resource board_A_led = {
.pin = GROUP_PIN(5,3),
};
struct led_resource *get_led_resource(void)
{
return &board_A_led;
}
chip_demo_gpio.c
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <asm/io.h>
#include "led_opr.h"
#include "led_resource.h"
static struct led_resource *led_rsc;
#ifdef GPIO5_IO3
static volatile unsigned int *CCM_CCGR1 = NULL;
static volatile unsigned int *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = NULL;
static volatile unsigned int *GPIO5_GDIR = NULL;
static volatile unsigned int *GPIO5_DR = NULL;
#endif
static int _board_demo_led_init (int which)
{
unsigned int value;
printk("%s %s line %d, led %d\n", __FILE__, __FUNCTION__, __LINE__, which);
if(which == 0)
{
if(!CCM_CCGR1)
{
CCM_CCGR1 = ioremap(0x20C406C, 4);
IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = ioremap(0x2290014, 4);
GPIO5_GDIR = ioremap(0x020AC000 + 0x4 , 4);
GPIO5_DR = ioremap(0x020AC000, 4);
}
*CCM_CCGR1 |= (0x3 << 30);
value = *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;
value &= ~0xF;
value |= 0x5;
*IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = value;
*GPIO5_GDIR |= (1 << 3);
}
return 0;
}
static int _board_demo_led_ctl (int which, char status)
{
printk("%s %s line %d, led %d, %s\n", __FILE__, __FUNCTION__, __LINE__, which, status ? "on" : "off");
if(which == 0)
{
if(status)
{
*GPIO5_DR &= ~(1 << 3);
}
else
{
*GPIO5_DR |= (1 << 3);
}
}
return 0;
}
static int board_demo_led_init (int which)
{
unsigned int value;
if (!led_rsc)
{
led_rsc = get_led_resource();
}
printk("init gpio: group %d, pin %d\n", GROUP(led_rsc->pin), PIN(led_rsc->pin));
switch(GROUP(led_rsc->pin))
{
case 0:
{
printk("init pin of group 0 ...\n");
break;
}
case 1:
{
printk("init pin of group 1 ...\n");
break;
}
case 2:
{
printk("init pin of group 2 ...\n");
break;
}
case 3:
{
printk("init pin of group 3 ...\n");
break;
}
case 4:
{
printk("init pin of group 4 ...\n");
break;
}
case 5:
{
printk("init pin of group 5 ...\n");
_board_demo_led_init(which);
break;
}
return 0;
}
}
static int board_demo_led_ctl (int which, char status)
{
printk("set led %s: group %d, pin %d\n", status ? "on" : "off", GROUP(led_rsc->pin), PIN(led_rsc->pin));
switch(GROUP(led_rsc->pin))
{
case 0:
{
printk("set pin of group 0 ...\n");
_board_demo_led_ctl(PIN(led_rsc->pin), status);
break;
}
case 1:
{
printk("set pin of group 1 ...\n");
break;
}
case 2:
{
printk("set pin of group 2 ...\n");
break;
}
case 3:
{
printk("set pin of group 3 ...\n");
break;
}
case 4:
{
printk("init pin of group 4 ...\n");
break;
}
case 5:
{
printk("init pin of group 5 ...\n");
_board_demo_led_ctl(which, status);
break;
}
}
return 0;
}
static struct led_operations board_demo_led_opr = {
.num = 1,
.init = board_demo_led_init,
.ctl = board_demo_led_ctl,
};
struct led_operations *get_board_led_opr(void)
{
return &board_demo_led_opr;
}
|