rk3399 led

发布时间 2023-04-02 13:48:06作者: yang_dh

rk3399 led

开发板:firefly rk3399

关键代码欣赏,由底层驱动来提供led的操作函数:struct led_oprs

struct led_oprs
{
	int(*init)(int i);
	int (*ctrl)(int i, char val);
	void (*release)(void);
	int num;
};
static int __init led_init(void)
{
	int err,i;
	printk("%s %s %d\r\n",__FILE__,__FUNCTION__,__LINE__);
	p_led_ops = get_led_opr();		/* 获取底层提供的led操作函数 */
	led_major = register_chrdev((unsigned int) 0, DRVC_NAME,
				  &led_ops);

	if (!led_major)
		{
			printk("register led failed\r\n");
		}

	led_class = class_create(THIS_MODULE, "led");
	err = PTR_ERR(led_class);
	if (IS_ERR(led_class))
		printk("led class create failed\r\n");
	for(i = 0; i < p_led_ops->num; i++)  {
		device_create(led_class, NULL, MKDEV(led_major,i), NULL, "led%d",i);	/* /dev/led */
	}
	return 0;
}
static void __exit led_exit(void)
{
	int i;
	p_led_ops->release();
	for(i = 0; i < p_led_ops->num; i++)  {
		device_destroy(led_class, MKDEV(led_major,i));
	}
	class_destroy(led_class);
	unregister_chrdev(led_major, DRVC_NAME);
}

#include "rockchip_led.h"
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>

#include "led.h"
static volatile unsigned int *CRU_CLKGATE_CON31;
static volatile unsigned int *GRF_GPIO2D_IOMUX ;
static volatile unsigned int *GPIO2_SWPORTA_DDR;
static volatile unsigned int *GPIO2_SWPORTA_DR ;

static int rockchip_led_init(int i)
{
	if (i == 0)
		{
			if (!CRU_CLKGATE_CON31)  {
				CRU_CLKGATE_CON31 = ioremap(0xFF760000 + 0x037c, 4);
				GRF_GPIO2D_IOMUX = ioremap(0xFF770000 + 0x0e00c, 4);
				GPIO2_SWPORTA_DDR = ioremap(0xFF780000 + 0x0004, 4);
				GPIO2_SWPORTA_DR = ioremap(0xFF780000 + 0x0000, 4);
			}

		*CRU_CLKGATE_CON31 = (1<<(3+16)) | (0<<3);
		*GRF_GPIO2D_IOMUX = (3<<(6+16)) | (0<<4);
		*GPIO2_SWPORTA_DDR |= (1<<26);
	}
	return 0;
}
static int rockchip_led_ctrl(int i, char val)
{
	if (i == 0)
		{
			if (val)
				{
					*GPIO2_SWPORTA_DR &= ~(1<<26);		/* 拉低 gpio2 d2 */
				}
			else
				{
					*GPIO2_SWPORTA_DR |= (1<<26);		/* gpio2 d2 high level */
				}
		}
	return 0;
}



struct led_oprs rockchip_led_opr = {
	.init 	= rockchip_led_init,
	.ctrl 	= rockchip_led_ctrl,
	.release = rockchip_led_exit,
	.num  = 1,

};

struct led_oprs* get_led_opr(void)
{
	return &rockchip_led_opr;
}

void rockchip_led_exit(void)
{
	//printk ("rockchip_led_exit io unmap\r\n");
	iounmap(CRU_CLKGATE_CON31);
	iounmap(GRF_GPIO2D_IOMUX);
	iounmap(GPIO2_SWPORTA_DDR);
	iounmap(GPIO2_SWPORTA_DR);
}