第一章 环境
环境:以mtk平台为例,其他平台相似
内核版本:kernel-4.9
第二章 配置dts
2.1 在dts中定义节点(一般在项目的dtsi中)
test_node: test_node_ctrl {
compatible = "test,test_node";
vqmmc-supply = <&mt_pmic_vmc_ldo_reg>;
vmmc-supply = <&mt_pmic_vmch_ldo_reg>;
};
2.2 在dts中配置引脚(一般在项目的dts中)
&test_node {
pinctrl-names = "test_pin_output0","test_pin_output1";
pinctrl-0 = <&step_dir_right_output0>;
pinctrl-1 = <&step_dir_left_output1>;
};
&pio {
pin_output0: test_output0 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO33__FUNC_GPIO33>;
slew-rate = <1>;//转换速率
output-low;//低电平
};
};
pin_output1: test_output1 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO33__FUNC_GPIO33>;
slew-rate = <1>;
output-high;//低电平
};
};
};
第三章 驱动例程
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/proc_fs.h>
#include <linux/input/mt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/regulator/consumer.h>
#include <linux/platform_device.h>
//写一份平台驱动代码---platform_drv
//-----------------------dts----------------------
/*
test_node: test_node_ctrl {
compatible = "test,test_node";
vqmmc-supply = <&mt_pmic_vmc_ldo_reg>;
vmmc-supply = <&mt_pmic_vmch_ldo_reg>;
};
&test_node {
pinctrl-names = "test_pin_output0","test_pin_output1";
pinctrl-0 = <&pin_output0>;
pinctrl-1 = <&pin_output1>;
};
&pio {
pin_output0: test_output0 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO33__FUNC_GPIO33>;
slew-rate = <1>;//转换速率
output-low;//低电平
};
};
pin_output1: test_output1 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO33__FUNC_GPIO33>;
slew-rate = <1>;
output-high;//低电平
};
};
};
*/
//-----------------------drv----------------------
//pintcrl子系统获取引脚状态
struct platform_device * platform_dev;
struct pinctrl* test_pinctr;
struct pinctrl_state *pin_output0,*pin_output1;
int test_pinctrl_init(struct device *dev)
{
int ret = -1;
printk("%s()\n", __func__);
test_pinctr = devm_pinctrl_get(dev);
if (IS_ERR(test_pinctr)) {
printk("err:test_pinctr\n");
return 0;
}
pin_output0 = pinctrl_lookup_state(test_pinctr, "test_pin_output0");
if (IS_ERR(pin_output0)) {
printk("err:pin_output0\n");
return -1;
}
pin_output1 = pinctrl_lookup_state(test_pinctr, "test_pin_output1");
if (IS_ERR(pin_output1)) {
printk("err:pin_output1\n");
return -1;
}
ret = pinctrl_select_state(test_pinctr, pin_output1);
if(ret < 0){
printk("error:pin_output1\n");
}
return 1;
}
//平台探测函数
int test_drv_probe(struct platform_device * pdev)
{
int ret;
struct regulator *test_reg=NULL;
struct regulator *pwr_reg=NULL;
platform_dev = pdev;
//获取电压输出引脚的寄存器
test_reg = regulator_get(&pdev->dev,"vqmmc");
if(!test_reg){
printk("regulator_get failed!\n");
goto err_regular;
}
pwr_reg = regulator_get(&pdev->dev,"vmmc");
if(!pwr_reg){
printk("regulator_get failed!\n");
goto err_regular;
}
//设置电压输出引脚的值
ret = regulator_set_voltage(test_reg,3300000,3300000);//设置电压值
if (ret<0) {
printk("regulator_set_voltage(ret = %d) failed:3000000!\n", ret);
goto err_regular;
}
ret = regulator_set_voltage(pwr_reg,3300000,3300000);//设置电压值
if (ret<0) {
printk("regulator_set_voltage(ret = %d) failed:3000000!\n", ret);
goto err_regular;
}
//电压输出设置完成
//pinctrl子系统设置
ret = test_pinctrl_init(&pdev->dev);
if(ret < 1){
printk("--------^_^ %s------test_pinctrl_init failed:ret=%d----\n",__FUNCTION__,ret);
goto err_regular;
}
return 0;
err_regular:
return ret;
}
int test_drv_remove(struct platform_device * pdev )
{
printk("%s()\n", __func__);
return 0;
}
int test_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
printk("%s()\n", __func__);
return 0;
}
int test_drv_resume(struct platform_device *pdev)
{
printk("%s() \n", __func__);
return 0;
}
const struct of_device_id test_of_match[] = {
{ .compatible = "test,test_node", },
{}
};
// 4,创建用于和pdev匹配的列表--可不用
struct platform_device_id test_id_table[] = {
{"test_one",0x124},
{"test_two",0x234},
{"test_three",0x1},
};
// 1 , 创建pdrv对象
struct platform_driver test_drv = {
.probe = test_drv_probe, //探测:当匹配成功时,会执行该函数
.remove = test_drv_remove, //移除 probe反操作
.suspend = test_drv_suspend,//挂起
.resume = test_drv_resume,//唤醒:唤醒、恢复时调用
.driver = {
.name = "test_DRV",
//.pm = &tpd_pm_ops,
.owner = THIS_MODULE,
.of_match_table = test_of_match,
},
.id_table = test_id_table,
};
static int test_node_init(void)
{
printk("%s() ok!\n", __func__);
// 2,注册pdrv
return platform_driver_register(&test_drv);//注册平台驱动
}
static void test_node_exit(void)
{
printk("%s()!\n", __func__);
}
module_init(test_node_init);
module_exit(test_node_exit);
MODULE_DESCRIPTION("MTK gpio driver");
MODULE_AUTHOR("<huangzb>");
MODULE_LICENSE("GPL");