/****************************************************************************
* 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. disable某种警告

    消除警告: #pragma warning(disable:4786) ZC: 需要消除哪种警告,就在上面填写相应的编号 1. 在 VC6中使用vector<string>时,报类似下面的 ...

  2. Codeforces 916C - Jamie and Interesting Graph

    916C - Jamie and Interesting Graph 思路:构造. 对于1到n最短路且素数,那么1到n之间连2 对于最小生成树,找一个稍微大点的素数(比1e5大)构造一个和为这个素数的 ...

  3. SpringBoot入门篇--整合mybatis+generator自动生成代码+druid连接池+PageHelper分页插件

    原文链接 我们这一篇博客讲的是如何整合Springboot和Mybatis框架,然后使用generator自动生成mapper,pojo等文件.然后再使用阿里巴巴提供的开源连接池druid,这个连接池 ...

  4. Xshell Xftp 免费版 (xshell6 评估期已过 解决办法)

    xshell6 评估期已过,因为下载的版本是evaluation版本,是有期限的. 大家可以修改为Home and school use 的版本,这样就不会出现这个提示了. 具体的操作步骤如下: 1. ...

  5. Linux 虚拟内存和物理内存的理解

    关于Linux 虚拟内存和物理内存的理解. 首先,让我们看下虚拟内存: 第一层理解 1. 每个进程都有自己独立的4G内存空间,各个进程的内存空间具有类似的结构 2. 一个新进程建立的时候,将会建立起自 ...

  6. 20161212xlVBA文本文件多列合并

    Sub NextSeven_CodeFrame() '应用程序设置 Application.ScreenUpdating = False Application.DisplayAlerts = Fal ...

  7. Linux Used内存到底哪里去了?

    原创文章,转载请注明: 转载自系统技术非业余研究 本文链接地址: Linux Used内存到底哪里去了? 前几天 纯上 同学问了一个问题: 我ps aux看到的RSS内存只有不到30M,但是free看 ...

  8. Oracle性能诊断艺术-读书笔记(范围分区)

    1. PARTITION RANGE SINGLE 注意:操作2 中的 TABLE ACCESS FULL 并不是全表扫描,只是对分区1 做 全分区扫描 case2 2. 分区范围迭代(PARTITI ...

  9. Oracle 声明常量 (转)

    原文地址 Oracle 声明常量 常量在声明时赋予初值,并且在运行时不允许重新赋值.使用CONSTANT关键字声明常量. 声明常量 DECLARE pi CONSTANT number :=3.14; ...

  10. EBS管理员为供应商创建新联系人流程

    管理员为供应商创建新联系人流程 /oracle/apps/pos/supplier/webui/ByrAddCntctPG oracle.apps.pos.supplier.webui.ByrAddC ...