蜂鸣器电路和LED控制电路一样,只需GPIO的高低电平控制就可以了。对应电路图如下:
当XpwmTOUT1为高电平时,三极管Q1导通,蜂鸣器鸣叫。反之,三极管Q1将截止,蜂鸣器停止蜂鸣。 可以完全模仿前面的LED驱动程序,将控制XpwmTOUT1口的功能封装到sysfs设备文件系统。 默认已经将蜂鸣器驱动放在kernel/drivers/char/beep目录,为了源码更加统一,将它全部移到kernel/drivers/char/x4412目录。 删掉kernel/drivers/char/beep目录,同时删掉kernel/drivers/char/Kconfig中的如下语句: - source "drivers/char/beep/Kconfig"
复制代码 删掉kernel/drivers/char/Makefile中的如下语句: 在kernel/drivers/char/x4412目录下新建x4412-beep.c文件,编辑内容如下: - #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/platform_device.h>
- #include <linux/gpio.h>
- #include <plat/gpio-cfg.h>
-
- /*
- * BEEP -> PWM1 -> GPD0(1)
- */
- static int __x4412_beep_status = 0;
- static void __x4412_beep_probe(void)
- {
- int ret;
-
- ret = gpio_request(EXYNOS4_GPD0(1), "GPD0(1)");
- if(ret)
- printk("x4412-beep: request gpio GPD0(1) fail\n");
- s3c_gpio_setpull(EXYNOS4_GPD0(1), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(EXYNOS4_GPD0(1), S3C_GPIO_SFN(1));
- gpio_set_value(EXYNOS4_GPD0(1), 0);
- __x4412_beep_status = 0;
- }
-
- static void __x4412_beep_remove(void)
- {
- gpio_free(EXYNOS4_GPD0(1));
- }
- static ssize_t x4412_beep_read(struct device *dev, struct device_attribute *attr, char *buf)
- {
- if(!strcmp(attr->attr.name, "state"))
- {
- if(__x4412_beep_status != 0)
- return strlcpy(buf, "1\n", 3);
- else
- return strlcpy(buf, "0\n", 3);
- }
- return strlcpy(buf, "\n", 3);
- }
-
- static ssize_t x4412_beep_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
- {
- unsigned long on = simple_strtoul(buf, NULL, 10);
-
- if(!strcmp(attr->attr.name, "state"))
- {
- if(on)
- {
- gpio_set_value(EXYNOS4_GPD0(1), 1);
- __x4412_beep_status = 1;
- }
- else
- {
- gpio_set_value(EXYNOS4_GPD0(1), 0);
- __x4412_beep_status = 0;
- }
- }
-
- return count;
- }
-
- static DEVICE_ATTR(state, 0666, x4412_beep_read, x4412_beep_write);
-
- static struct attribute * x4412_beep_sysfs_entries[] = {
- &dev_attr_state.attr,
- NULL,
- };
-
- static struct attribute_group x4412_beep_attr_group = {
- .name = NULL,
- .attrs = x4412_beep_sysfs_entries,
- };
-
- static int x4412_beep_probe(struct platform_device *pdev)
- {
- __x4412_beep_probe();
-
- return sysfs_create_group(&pdev->dev.kobj, &x4412_beep_attr_group);
- }
-
- static int x4412_beep_remove(struct platform_device *pdev)
- {
- __x4412_beep_remove();
-
- sysfs_remove_group(&pdev->dev.kobj, &x4412_beep_attr_group);
- return 0;
- }
-
- #define x4412_beep_suspend NULL
- #define x4412_beep_resume NULL
-
- static struct platform_driver x4412_beep_driver = {
- .probe = x4412_beep_probe,
- .remove = x4412_beep_remove,
- .suspend = x4412_beep_suspend,
- .resume = x4412_beep_resume,
- .driver = {
- .name = "x4412-beep",
- },
- };
-
- static struct platform_device x4412_beep_device = {
- .name = "x4412-beep",
- .id = -1,
- };
-
- static int __devinit x4412_beep_init(void)
- {
- int ret;
-
- printk("x4412 beep driver\r\n");
-
- ret = platform_device_register(&x4412_beep_device);
- if(ret)
- printk("failed to register x4412 beep device\n");
-
- ret = platform_driver_register(&x4412_beep_driver);
- if(ret)
- printk("failed to register x4412 beep driver\n");
-
- return ret;
- }
-
- static void x4412_beep_exit(void)
- {
- platform_driver_unregister(&x4412_beep_driver);
- }
-
- module_init(x4412_beep_init);
- module_exit(x4412_beep_exit);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("www.9tripod.com");
- MODULE_DESCRIPTION("x4412 beep driver");
复制代码 编辑kernel/drivers/char/x4412/Kconfig文件,添加如下内容: - config X4412_BEEP_DRIVER
- tristate "x4412 beep driver"
- default y
- help
- compile for x4412 beep driver,y for kernel,m for module.
复制代码 编辑kernel/drivers/char/x4412/Makefile文件,添加如下内容: - obj-$(CONFIG_X4412_LED_SYSFS_DRIVER) += x4412-beep.o
复制代码 编译源码后更新内核映像,使用如下指令即可打开和关闭蜂鸣器了: - echo 1 > state
- echo 0 > state
复制代码 |