hacking a friend's Linux buzzer driver in OK335xS
/****************************************************************************
* 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的更多相关文章
- I.MX6 PWM buzzer driver hacking with Demo test
/***************************************************************************** * I.MX6 PWM buzzer dr ...
- linux device driver —— 环形缓冲区的实现
还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...
- Linux Device Driver 学习(1)
Linux Device Driver 学习(1) 一.搭建虚拟机开发环境 1.选择虚拟机VirtualBox,官网下载.deb包安装: VirtualBox Linux 5.1.6 下载fedora ...
- Program for Linux USB-devices driver step by step (ONE)
Program for Linux USB-devices driver 開始啃硬骨头~ 这里我打算一步步给出USB device driver 的demo.希望有心能可以共同交流学习. 希望认识很多 ...
- 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 ...
- Linux Device Driver && Device File
catalog . 设备驱动程序简介 . I/O体系结构 . 访问设备 . 与文件系统关联 . 字符设备操作 . 块设备操作 . 资源分配 . 总线系统 1. 设备驱动程序简介 设备驱动程序是内核的关 ...
- How to learn linux device driver
To learn device driver development, like any other new knowledge, the bestapproach for me is to lear ...
- 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 ...
- <<linux device driver,third edition>> Chapter 4:Debugging Techniques
Debugging by Printing printk lets you classify messages accoring to their severity by associating di ...
随机推荐
- c++ 在指定长度的数组或者容器中,统计元素出现的次数(count)
#include <iostream> // cout #include <algorithm> // count #include <vector> // vec ...
- C#怎样用文件读写在文件的原有基础上追加一行数据
首先添加命名空间using System.IO;这里有两种方法,希望对你有帮助,操作文件时,一定要记得及时关闭流. 第一种方法: string path="D\1.txt";//文 ...
- SpringMVC是如何逐步简化Servlet的编程的
转自:https://www.cnblogs.com/winterfells/p/8476759.html Servlet和JSP是开发java Web应用程序的两种基本技术,Spring MVC是S ...
- 记一次无法正常本地登陆Linux服务器(确定密码正确)
首先,ssh可以正常登陆使用.但是,本地可以确定密码是正确的情况还是不能登陆. 然后查看/var/log/secure文件如下提示: 然后,尝试去看了下/etc/pam.d/login 下面(有问题的 ...
- mate桌面xrdp无法登陆问题
vi /usr/libexec/xrdp/startwm.sh 或者/etc/xrdp/startwm.sh: 找到相应的发行版本,增加mate-session如下所示: # el if [ -r ...
- Java 主要特性
Java 有下面的一些主要特性. 面向对象 在 Java 中,所有的都是对象.正式因为 Java 基于对象模型,所以 Java 更加容易进行扩展. Java语言提供类.接口和继承等面向对象的特性,为了 ...
- Sasha and Interesting Fact from Graph Theory CodeForces - 1109D (图论,计数,Caylay定理)
大意: 求a->b最短路长度为m的n节点树的个数, 边权全部不超过m 枚举$a$与$b$之间的边数, 再由拓展$Caylay$定理分配其余结点 拓展$Caylay$定理 $n$个有标号节点生成k ...
- 51nod1344
有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i] > 0,机器 ...
- POJ-3259 Wormholes(判断负环、模板)
Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...
- PL/SQL Developer 使用中文条件查询时无数据的解决方法(转)
原文地址: PL/SQL Developer 使用中文条件查询时无数据的解决方法 PL/SQL Developer 使用中文条件查询时无数据,这是由于字符集的不一致导致的. 执行以下sql命令:sel ...