/****************************************************************************
* hacking a friend's Linux buzzer driver in OK335xS
* 说明:
* 解读朋友的Linux buzzer驱动,作为后续相关编码的参考。
*
* 2015-8-25 晴 深圳 南山平山村 曾剑锋
***************************************************************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/semaphore.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/mux.h>
#include <linux/gpio.h> #define IO_VAULE_H 5
#define IO_VAULE_L 6 /**
* 1. 参考文档:AM335x ARM Cortex-A8 Microprocessors (MPUs) Technical Reference Manual (Rev. H).pdf
* 2. ARM Cortex-A8 Memory Map:
* Table 2-1. L3 Memory Map (page 155)
* +------------+---------------------+-------------------+------------------+
* | Block Name | Start_address (hex) | End_address (hex) | Size Description |
* +------------+---------------------+-------------------=------------------+
* | L4_WKUP | 0x44C0_0000 | 0x44FF_FFFF | 4MB L4_WKUP |
* +------------+---------------------+-------------------+------------------+
* Table 2-2. L4_WKUP Peripheral Memory Map (page 158)
* +----------------+---------------------+-------------------+-------+--------------------------+
* | Region Name | Start Address (hex) | End Address (hex) | Size | Description |
* +----------------+---------------------+-------------------+-------+--------------------------+
* | Control Module | 0x44E1_0000 | 0x44E1_1FFF | 128KB | Control Module Registers |
* +----------------+---------------------+-------------------+-------+--------------------------+
*/
#define Control_Module_address 0x44E10000 /**
* 1. 参考文档:AM335x ARM Cortex-A8 Microprocessors (MPUs) Technical Reference Manual (Rev. H).pdf
* 2. CONTROL_MODULE Registers:
* Table 9-10. CONTROL_MODULE REGISTERS
* +--------+---------------+----------------------+----------------+
* | Offset | Acronym | Register Description | Section |
* +--------+---------------+----------------------+----------------+
* | 960h | conf_spi0_cs1 | | Section 9.3.51 |
* +--------+---------------+----------------------+----------------+
*/
#define CONFIG_SPI0_CS1_offset 0x960 /**
* can't find any reference for this define, but it can use
*/
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio) ) /**
* just like container_of in kernel
*/
#define GET_STRUCT_ADDR (ptr,type,member)\
((unsigned long )ptr - (unsigned long)((type*)->member)) /**
* 1. 参考文档:Sitara AM335x ARM Cortex-A8 Microprocessors (MPUs) (Rev. F).pdf
* Table 2-7. Ball Characteristics (ZCE and ZCZ Packages) (continued) (page 43)
* +-----------+-----------+-------------+--------------------+---------+---------+
* | ZCE BALL | ZCZ BALL | PIN NAME[2] | SIGNAL NAME[3] | MODE[4] | TYPE[5] |
* | NUMBER[1] | NUMBER[1] | | | | |
* +-----------+-----------+-------------+--------------------+---------+---------+
* | B16 | C15 | SPI0_CS1 | spi0_cs1 | 0 | I/O |
* | | | |--------------------|---------+---------+
* | | | | uart3_rxd | 1 | I |
* | | | |--------------------|---------+---------+
* | | | | eCAP1_in_PWM1_out | 2 | I/O |
* | | | |--------------------|---------+---------+
* | | | | mmc0_pow | 3 | O |
* | | | |--------------------|---------+---------+
* | | | | xdma_event_intr2 | 4 | I |
* | | | |--------------------|---------+---------+
* | | | | mmc0_sdcd | 5 | I |
* | | | |--------------------|---------+---------+
* | | | | EMU4 | 6 | I/O |
* | | | |--------------------|---------+---------+
* | | | | gpio0_6 | 7 | I/O |
* +-----------+-----------+-------------+--------------------+---------+---------+
*/
#define BUZZER_PIN GPIO_TO_PIN(0, 6) struct cdev * buzz; static int buzz_init(void)
{
int result; /**
* void *ioremap(unsigned long phys_addr, unsigned long size)
* 入口:phys_addr:要映射的起始的IO地址;
* size:要映射的空间的大小;
*/
void __iomem * base = ioremap(Control_Module_address, 0x1FFF);
/**
* 1 参考文章:AM335x ARM Cortex-A8 Microprocessors (MPUs) Technical Reference Manual (Rev. H).pdf
* Table 9-61. conf_<module>_<pin> Register Field Descriptions(page 815)
* +-------+-------------------------+--------------+-------------------------------------------+
* | Bit | Field | Type | Reset | Description |
* +-------+-------------------------+--------------+-------------------------------------------+
* | 31-20 | Reserved | R | 0h | |
* +-------+-------------------------+--------------+-------------------------------------------+
* | 19-7 | Reserved | R | 0h | |
* +-------+-------------------------+--------------+-------------------------------------------+
* | 6 | conf_<module>_<pin>_sle | R/W | X | Select between faster or slower slew rate |
* | | wctrl | | | 0: Fast |
* | | | | | 1: Slow |
* | | | | | Reset value is pad-dependent. |
* +-------+-------------------------+--------------+----------------------------------------- +
* | 5 | conf_<module>_<pin>_rx | R/W | 1h | Input enable value for the PAD |
* | | active | | | 0: Receiver disabled |
* | | | | | 1: Receiver enabled |
* +-------+-------------------------+--------------+----------------------------------------- +
* | 4 | conf_<module>_<pin>_pu | R/W | X | Pad pullup/pulldown type selection |
* | | typesel | | | 0: Pulldown selected |
* | | | | | 1: Pullup selected |
* | | | | | Reset value is pad-dependent. |
* +-------+-------------------------+--------------+-------------------------------------------+
* | 3 | conf_<module>_<pin>_pu | R/W | X | Pad pullup/pulldown enable |
* | | den | | | 0: Pullup/pulldown enabled |
* | | | | | 1: Pullup/pulldown disabled |
* | | | | | Reset value is pad-dependent. |
* +-------+-------------------------+--------------+-------------------------------------------+
* | 2-0 | conf_<module>_<pin>_m | R/W | X | Pad functional signal mux select. |
* | | mode | | | Reset value is pad-dependent. |
* +-------+-------------------------+--------------+-------------------------------------------+
* 2. 0x37 = B0011 0111
* 1. bit 6 --> 0 --> Fast;
* 2. bit 5 --> 1 --> Receiver enabled;
* 3. bit 4 --> 1 --> Pullup selected;
* 4. bit 3 --> 0 --> Pullup/pulldown enabled;
* 5. bit 2-0 --> 7 --> gpio0_6; 参考前面说明 #define BUZZER_PIN GPIO_TO_PIN(0,6)
*/
__raw_writel(0x37, (base + CONFIG_SPI0_CS1_offset )); /* Allocating GPIOs and setting direction */
result = gpio_request(BUZZER_PIN, "buzzer"); //usr1
if (result != )
printk("gpio_request(0_6) failed!\n"); return result; result = gpio_direction_output(BUZZER_PIN, );
if (result != )
printk("gpio_direction(0_6) failed!\n"); return result; gpio_set_value(BUZZER_PIN, ); return result;
} static int buzz_open(struct inode *inode, struct file *file)
{
return ;
} static ssize_t buzz_read (struct file *file, char __user *buf, size_t size, loff_t * off)
{
return ;
} static int buzz_ioctl(struct file *filp,unsigned int cmd, unsigned long arg)
{
if(cmd == IO_VAULE_H ) {
printk(" buzz iotcl IO_VALUE_H.\n"); // for debug
gpio_set_value(BUZZER_PIN,);
}
if(cmd == IO_VAULE_L ) {
printk(" buzz iotcl IO_VALUE_L.\n");
gpio_set_value(BUZZER_PIN,);
} return ;
} static ssize_t buzz_write (struct file *file, char __user *buf, size_t size, loff_t * off)
{
return ;
} static int buzz_release (struct inode *inode, struct file *file)
{
return ;
} struct file_operations buzz_fops = {
.owner = THIS_MODULE,
.open = buzz_open,
.read = buzz_read,
.write = buzz_write,
.release = buzz_release,
.unlocked_ioctl= buzz_ioctl
}; static int __init buzzm_init()
{
/**
* 表示静态的申请和注册设备号:
* register_chrdev_region(dev_t first,unsigned int count,char *name)
* first :要分配的设备编号范围的初始值(次设备号常设为0);
* count:连续编号范围.
* name:编号相关联的设备名称. (/proc/devices);
*/
if(register_chrdev_region(MKDEV(,),,"aple_buzz") < )
return -ENOMEM ; /**
* 前面只是注册了设备号,后面要向内核添加设备了;
*/
buzz = cdev_alloc();
if(buzz == NULL)
return -ENOMEM; cdev_init(buzz , &buzz_fops);
cdev_add(buzz ,MKDEV(,),);
buzz_init();
return ;
} static void __exit buzzm_exit()
{
cdev_del(buzz);
unregister_chrdev_region(MKDEV(,),);
} module_init(buzzm_init);
module_exit(buzzm_exit);
MODULE_AUTHOR("Danny Zhao");
MODULE_LICENSE("GPL");

hacking a friend's Linux buzzer driver in OK335xS的更多相关文章

  1. I.MX6 PWM buzzer driver hacking with Demo test

    /***************************************************************************** * I.MX6 PWM buzzer dr ...

  2. linux device driver —— 环形缓冲区的实现

    还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...

  3. Linux Device Driver 学习(1)

    Linux Device Driver 学习(1) 一.搭建虚拟机开发环境 1.选择虚拟机VirtualBox,官网下载.deb包安装: VirtualBox Linux 5.1.6 下载fedora ...

  4. Program for Linux USB-devices driver step by step (ONE)

    Program for Linux USB-devices driver 開始啃硬骨头~ 这里我打算一步步给出USB device driver 的demo.希望有心能可以共同交流学习. 希望认识很多 ...

  5. how to write your first linux device driver

    how to write your first linux device driver 0. environment-ubuntu 1804 64bit 1. apt-get install linu ...

  6. Linux Device Driver && Device File

    catalog . 设备驱动程序简介 . I/O体系结构 . 访问设备 . 与文件系统关联 . 字符设备操作 . 块设备操作 . 资源分配 . 总线系统 1. 设备驱动程序简介 设备驱动程序是内核的关 ...

  7. How to learn linux device driver

    To learn device driver development, like any other new knowledge, the bestapproach for me is to lear ...

  8. linux nVidia driver 304 319 . installation by hand

    It's so painful to install nVidia driver by hand on linux. If you remove it or you want to upgrade b ...

  9. <<linux device driver,third edition>> Chapter 4:Debugging Techniques

    Debugging by Printing printk lets you classify messages accoring to their severity by associating di ...

随机推荐

  1. Springboot 学习笔记 之 Day 1

    SpringBoot快速入门 https://spring.io/ 1. SpringBoot简介Spring Boot来简化Spring应用开发,约定大于配置,去繁从简,just run就能创建一个 ...

  2. WM_COPYDATA

    1. WM_COPYDATA : https://msdn.microsoft.com/en-us/library/windows/desktop/ms649011(v=vs.85).aspx COP ...

  3. 创意时钟 人形时钟 可惜不是 https

    ; (function () { $('#header').css({ 'position':'relative' }).prepend('<div id="clockWrap&quo ...

  4. react新的生命周期

    一. react16当前生命周期 componentWillMountrender前,所以setState不会重新渲染,服务端渲染唯一调用,推荐用constructor代替之 render compo ...

  5. js匿名函数和闭包总结

    js匿名函数和闭包总结 一.总结 一句话总结:匿名函数的最主要作用是创建闭包,闭包就是将函数内部和函数外部连接起来的一座桥梁.内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕.闭包可以用 ...

  6. Assert.IsNotNull 方法(判断对象不为NULL)

    Assert.IsNotNull 方法 Visual Studio 2012   其他版本 Visual Studio 2010 Visual Studio 2008 Visual Studio 20 ...

  7. TCP三次握手(待细研究)

    xu言: 看到一张不错清晰的Tcp三次握手图,收藏 Initiator  发起人 Receiver  接收者 LISTENING 状态xx服务启动后首先处于侦听(LISTENING)状态. ESTAB ...

  8. mycat分布式mysql中间件(自增主键)

    一.全局序列号 全局序列号是MyCAT提供的一个新功能,为了实现分库分表情况下,表的主键是全局唯一,而默认的MySQL的自增长主键无法满足这个要求.全局序列号的语法符合标准SQL规范,其格式为:nex ...

  9. python-day49--前端 css-层叠样式表

    1.css功能: 对html标签的渲染和布局 2.CSS 要掌握的两方面: 1.查找标签 选择器 2.操作标签  (对属性进行操作) 3.CSS 语法 CSS 规则由两个主要的部分构成:选择器,以及一 ...

  10. MFC中format函数用法

    本文转载于:http://blog.csdn.net/sunxc123/article/details/7742982 在MFC程序中,使用CString来处理字符串是一个很不错的选择.CString ...