1. 程式人生 > >編寫MTK6737平臺的GPIO驅動例程(一)

編寫MTK6737平臺的GPIO驅動例程(一)

1、在dts檔案中建立節點,在/kernel-3.18/arch/arm64/boot/dts/mt6735.dtsi

建立一個名mygpio的裝置節點,匹配名稱為“mykgpio”。

2、別寫驅動框架

#include <linux/slab.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <generated/autoconf.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/atomic.h>

#include "mt-plat/mtgpio.h"
#include <linux/types.h>
#include <mt-plat/mt_gpio.h>
#include <mt-plat/mt_gpio_core.h>
#include <mach/gpio_const.h>

/* 生命函式定義 */
static int mygpio_probe(struct platform_device *pdev);
static int mygpio_remove(struct platform_device *pdev);


static const struct of_device_id mygpio_of_match[] = {
	{ .compatible = "mykgpio", },
	{},
};

static struct platform_driver mygpio_driver = {
	.remove = mygpio_remove,
	.probe = mygpio_probe,
	.driver = {
			.name = "myGPIO",
			.owner = THIS_MODULE,
			.of_match_table = mygpio_of_match,
	},
};

static int mygpio_misc_open(struct inode *inode, struct file *file)
{
	printk("MyGPIO OPen. \r\n");
	
	return 0;
}


static int mygpio_misc_release(struct inode *inode, struct file *file)
{
	printk("MyGPIO Release. \r\n");
	
	return 0;
}

static long mygpio_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	printk("MyGPIO Ioctl. \r\n");
	
	printk("MyGPIO cmd=%d \r\n", cmd);
	
	return 0;
}

static const struct file_operations mygpio_fops = {
 /* .owner = THIS_MODULE, */
	.open = mygpio_misc_open,
	.release = mygpio_misc_release,
	.unlocked_ioctl = mygpio_unlocked_ioctl,
};


static struct miscdevice mygpio_misc_device = {
	.minor = MISC_DYNAMIC_MINOR,		//動態裝置號
	.name = "myGPIO",
	.fops = &mygpio_fops,
};



/* My GPIO probe */
static int mygpio_probe(struct platform_device *pdev)
{
	int ret = 0;
	
	printk("MyGPIO Probe. \r\n");
	
	ret = misc_register(&mygpio_misc_device);
	if (ret != 0 )
		printk("myGPIO: mygpio_device register failed\n");
	
	return ret;
}


static int mygpio_remove(struct platform_device *pdev)
{
	int err;
	
	printk("MyGPIO remove. \r\n");

	err = misc_deregister(&mygpio_misc_device);
	if (err)
		printk("deregister gpio\n");
	
	return err;
}

static int __init my_gpio_init(void)
{
	int ret = 0;

	printk("Register MyGPIO platform_driver. \r\n");

	ret = platform_driver_register(&mygpio_driver);
	if(ret != 0 )
		printk("unable to register MyGPIO driver.\n");
	
	return ret;
}

/*---------------------------------------------------------------------------*/
static void __exit my_gpio_exit(void)
{
	platform_driver_unregister(&mygpio_driver);
}

subsys_initcall(my_gpio_init);
/*module_init(my_gpio_init);*/
module_exit(my_gpio_exit);

MODULE_AUTHOR("zue");
MODULE_DESCRIPTION("MY General Purpose Driver (GPIO)");
MODULE_LICENSE("GPL v2");

這個過程很簡單,首先註冊一個裝置驅動,當DTS中匹配到名為"mykgpio"的裝置時,呼叫Probe函式,在probe函式中,註冊一個名為"myGPIO"的雜項裝置驅動。

將驅動檔案放入kernel,進行編譯並少寫編譯出的映象。

待開發板啟動後,即可在/dev目錄下看到註冊的裝置。這樣一個驅動框架就OK了,下面就可以編寫實質的GPIO驅動程式了。