现把一个蜂鸣器模块的控制引脚接到板上的PL11, 当输出低电平时蜂鸣器响,高电平时就不响.
H5芯片上有两个gpio控制器, PL组gpio口单独在一个gpio控制器上.
PL组的gpio控制器在设备树里的描述:
r_pio: pinctrl@01f02c00 { /* 可通过此基础区分gpio控制器 */
compatible = "allwinner,sun8i-h3-r-pinctrl";
...
gpio-controller;
#gpio-cells = <3>; //每个gpio口由3个数字组成一个gpio标识符
...
};
加入的蜂鸣器描述:
mybuzzer {
compatible = "mybuzzer";
gpios = <&r_pio 0 11 GPIO_ACTIVE_LOW>; //设备节点的gpios属性
};
设备驱动代码:
/* mydrv.c */
#include
#include
#include
#include
#include
int myprobe(struct platform_device *pdev)
{
struct gpio_desc *gpiod = NULL;
gpiod = gpiod_get(&pdev->dev, NULL, GPIOD_OUT_HIGH);
if (NULL == gpiod)
return -ENODEV;
gpiod_direction_output(gpiod, 1); //输出低电平,因在设备树里是用GPIO_ACTIVE_LOW
platform_set_drvdata(pdev, gpiod);
printk("in myprobe\n");
return 0;
}
int myremove(struct platform_device *pdev)
{
struct gpio_desc *gpiod = platform_get_drvdata(pdev);
printk("in myremove ...\n");
gpiod_set_value(gpiod, 0); //输出高电平
gpiod_put(gpiod); //回收gpio口的gpio_desc资源
return 0;
}
struct of_device_id ids[] = {
{.compatible = "mybuzzer"},
{},
};
struct platform_driver mydrv = {
.probe = myprobe,
.remove = myremove,
.driver = {
.owner = THIS_MODULE,
.name = "mydrv" ,
.of_match_table = ids,
},
};
module_platform_driver(mydrv);
MODULE_LICENSE("GPL");
板上有两个led灯,分别接在PA17, PL10上,自定义的设备节点:
myleds {
compatible = "myleds";
leds-gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>,<&pio 0 17 GPIO_ACTIVE_HIGH>;
};
//注意gpio口在设备驱动里只能独占使用的,所以需要确认gpio口不会发生重用的情况.
// 在h5里, 需要把设备节点leds失效才可以.
驱动代码:
/*mydrv.c */
#include
#include
#include
#include
#include
int myprobe(struct platform_device *pdev)
{
struct gpio_descs *gpiods = NULL;
int i;
gpiods = devm_gpiod_get_array(&pdev->dev, "leds", GPIOD_OUT_LOW);
if (IS_ERR(gpiods))
{
printk("gpiod get array failed\n");
return -ENODEV;
}
printk("ndescs = %d\n", gpiods->ndescs);
for (i = 0; i < gpiods->ndescs; i++)
gpiod_set_value(gpiods->desc[i], 1); //输出有效电平
platform_set_drvdata(pdev, gpiods);
printk("in myprobe\n");
return 0;
}
int myremove(struct platform_device *pdev)
{
struct gpio_descs *gpiods = platform_get_drvdata(pdev);
int i;
printk("in myremove ...\n");
for (i = 0; i < gpiods->ndescs; i++)
gpiod_set_value(gpiods->desc[i], 0); //输出失效电平
devm_gpiod_put_array(&pdev->dev, gpiods); //回收gpio口的gpio_desc资源
return 0;
}
struct of_device_id ids[] = {
{.compatible = "myleds"},
{},
};
struct platform_driver mydrv = {
.probe = myprobe,
.remove = myremove,
.driver = {
.owner = THIS_MODULE,
.name = "mydrv" ,
.of_match_table = ids,
},
};
module_platform_driver(mydrv);
MODULE_LICENSE("GPL");
gpio中断的应用. 一个按键模块接在PA12接口上。 默认处于高电平状态, 当按下时变为低电平.
设备树里的描述:
mykeys {
compatible = "mykeys";
btn1 {
btn-gpios = <&pio 0 12 GPIO_ACTIVE_LOW>;
};
};
驱动代码:
#include
#include
#include
#include
#include
#include
typedef struct {
struct gpio_desc *desc;
int keycode;
}mygpio_t;
typedef struct {
mygpio_t *mygpio;
int n;
}mygpio_pdata;
irqreturn_t irq_func(int irqno, void *arg) // arg参值就是在request_irq时的最后一个参数值
{
printk("irq irq irq ...\n");
return IRQ_HANDLED;
}
int myprobe(struct platform_device *pdev)
{
int n = device_get_child_node_count(&pdev->dev);
int i = 0, ret;
struct fwnode_handle *fwnode;
mygpio_pdata *pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata)+n*sizeof(mygpio_t), GFP_KERNEL);
pdata->mygpio = (mygpio_t *)(pdata+1);
pdata->n = n;
device_for_each_child_node(&pdev->dev, fwnode) {
pdata->mygpio[i].desc = fwnode_get_named_gpiod(fwnode, "btn-gpios",0,GPIOD_IN, NULL);
if (IS_ERR(pdata->mygpio[i].desc))
{
printk("get gpiod failed\n");
return -ENODEV;
}
ret = devm_request_any_context_irq(&pdev->dev, gpiod_to_irq(pdata->mygpio[i].desc), irq_func, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, pdev->name, NULL);
if (ret < 0)
printk("request irq failed\n");
i++;
}
platform_set_drvdata(pdev, pdata);
printk("in myprobe n = %d\n", n);
return 0;
}
int myremove(struct platform_device *pdev)
{
mygpio_pdata *pdata = platform_get_drvdata(pdev);
int i;
for (i = 0; i < pdata->n; i++)
gpiod_put(pdata->mygpio[i].desc);
printk("in myremove\n");
return 0;
}
struct of_device_id ids[] = {
{.compatible = "mykeys"},
{},
};
struct platform_driver mydrv = {
.probe = myprobe,
.remove = myremove,
.driver = {
.owner = THIS_MODULE,
.name = "mydrv" ,
.of_match_table = ids,
},
};
module_platform_driver(mydrv);
MODULE_LICENSE("GPL");