driver/2-led/led.c

171 lines
4.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
/***************************************************************
Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
文件名 : chrdevbase.c
作者 : 正点原子
版本 : V1.0
描述 : chrdevbase驱动文件。
其他 : 无
论坛 : www.openedv.com
日志 : 初版V1.0 2020/12/26 正点原子创建
***************************************************************/
#define major_dev_id 80
#define dev_name "led"
#define PERIPH_BASE (0x40000000)
#define MPU_AHB4_PERIPH_BASE (PERIPH_BASE + 0x10000000)
#define RCC_BASE (MPU_AHB4_PERIPH_BASE + 0x0000)
#define RCC_MP_AHB4ENSETR (RCC_BASE + 0XA28)
#define GPIOI_BASE (MPU_AHB4_PERIPH_BASE + 0xA000)
#define GPIOI_MODER (GPIOI_BASE + 0x0000)
#define GPIOI_OTYPER (GPIOI_BASE + 0x0004)
#define GPIOI_OSPEEDR (GPIOI_BASE + 0x0008)
#define GPIOI_PUPDR (GPIOI_BASE + 0x000C)
#define GPIOI_BSRR (GPIOI_BASE + 0x0018)
/* 映射后的寄存器虚拟地址指针 */
static void __iomem *MPU_AHB4_PERIPH_RCC_PI;
static void __iomem *GPIOI_MODER_PI;
static void __iomem *GPIOI_OTYPER_PI;
static void __iomem *GPIOI_OSPEEDR_PI;
static void __iomem *GPIOI_PUPDR_PI;
static void __iomem *GPIOI_BSRR_PI;
char led_sta = '0';
static ssize_t tis_module_read(struct file *file, char __user *out, size_t size, loff_t *offt)
{
int ret = 0;
ret = copy_to_user(out,&led_sta,1);
return 0;
}
static ssize_t tis_module_write(struct file *file, const char __user *in, size_t size, loff_t *offt)
{
int ret = 0;
char sta;
unsigned int val;
ret = copy_from_user(&sta, in, 1);
if (ret < 0)
{
return ret;
}
if (sta!='0'&&sta!='1')
{
printk("led module should input 0/1, your input is %c\n");
return 0;
}
led_sta = sta;
switch (sta)
{
case '1':
val = readl(GPIOI_BSRR_PI);
val |= (1 << 16);
writel(val, GPIOI_BSRR_PI);
break;
case '0':
val = readl(GPIOI_BSRR_PI);
val |= (1 << 0);
writel(val, GPIOI_BSRR_PI);
break;
default:
break;
}
return 0;
}
static int tis_module_open(struct inode *inode, struct file *file)
{
printk("%s: module open\n", dev_name);
return 0;
}
static int tis_module_release(struct inode *inode, struct file *file)
{
printk("%s: module release\n", dev_name);
return 0;
}
static struct file_operations tis_module_f = {
.owner = THIS_MODULE,
.write = tis_module_write,
.read = tis_module_read,
.open = tis_module_open,
.release = tis_module_release,
};
static void led_init(void)
{
MPU_AHB4_PERIPH_RCC_PI = ioremap(RCC_MP_AHB4ENSETR, 4);
GPIOI_MODER_PI = ioremap(GPIOI_MODER, 4);
GPIOI_OTYPER_PI = ioremap(GPIOI_OTYPER, 4);
GPIOI_OSPEEDR_PI = ioremap(GPIOI_OSPEEDR, 4);
GPIOI_PUPDR_PI = ioremap(GPIOI_PUPDR, 4);
GPIOI_BSRR_PI = ioremap(GPIOI_BSRR, 4);
unsigned int val;
/* 2、使能PI时钟 */
val = readl(MPU_AHB4_PERIPH_RCC_PI);
val &= ~(0X1 << 8); /* 清除以前的设置 */
val |= (0X1 << 8); /* 设置新值 */
writel(val, MPU_AHB4_PERIPH_RCC_PI);
/* 3、设置PI0通用的输出模式。*/
val = readl(GPIOI_MODER_PI);
val &= ~(0X3 << 0); /* bit0:1清零 */
val |= (0X1 << 0); /* bit0:1设置01 */
writel(val, GPIOI_MODER_PI);
/* 3、设置PI0为推挽模式。*/
val = readl(GPIOI_OTYPER_PI);
val &= ~(0X1 << 0); /* bit0清零设置为上拉*/
writel(val, GPIOI_OTYPER_PI);
/* 4、设置PI0为高速。*/
val = readl(GPIOI_OSPEEDR_PI);
val &= ~(0X3 << 0); /* bit0:1 清零 */
val |= (0x2 << 0); /* bit0:1 设置为10*/
writel(val, GPIOI_OSPEEDR_PI);
/* 5、设置PI0为上拉。*/
val = readl(GPIOI_PUPDR_PI);
val &= ~(0X3 << 0); /* bit0:1 清零*/
val |= (0x1 << 0); /*bit0:1 设置为01*/
writel(val, GPIOI_PUPDR_PI);
/* 6、默认关闭LED */
val = readl(GPIOI_BSRR_PI);
val |= (0x1 << 0);
writel(val, GPIOI_BSRR_PI);
led_sta = '0';
}
static void led_io_unmap(void)
{
iounmap(MPU_AHB4_PERIPH_RCC_PI);
iounmap(GPIOI_MODER_PI);
iounmap(GPIOI_OTYPER_PI);
iounmap(GPIOI_OSPEEDR_PI);
iounmap(GPIOI_PUPDR_PI);
iounmap(GPIOI_BSRR_PI);
}
static int __init tis_module_init(void)
{
register_chrdev(major_dev_id, dev_name, &tis_module_f);
printk("%s init\n", dev_name);
led_init();
return 0;
}
static void __exit tis_module_exit(void)
{
unregister_chrdev(major_dev_id, dev_name);
led_io_unmap();
printk("%s exit\n", dev_name);
}
module_init(tis_module_init);
module_exit(tis_module_exit);
MODULE_LICENSE("GPL v3.0");
MODULE_AUTHOR("Chenyf");