/****************************************************************************
* 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. Use a layout_width of 0dip instead of fill_parent for better performance

    安装了最新的ATD 18之后,新加的Lint Warnings插件会给我们检测出许多xml布局中不当的地方,例如: Use a layout_width of 0dip instead of fill ...

  2. 缓存地图 ArcGIS ——Local compact and exploded tile cache layer for WPF API

      ArcGISArcGIS 主页 特色 合约 图库 地图 组 帮助 我的内容 我的组织 登录 我的个人资料 帮助 管理员指南 登出 0 搜索全部内容 搜索地图 搜索图层 搜索应用程序 搜索工具 搜索 ...

  3. java生产条形码

      一.通过JBarcode(此种方式可以隐藏掉条形码下面的字符串)   1.下载jar包  jbarcode-0.2.8.jar  目前maven中央仓库并没有jbarcode的坐标  如果是mav ...

  4. 5-11敏捷开发rails的章节: Rspec(使用方法) ,Slim(使用操作简介)

    Rspec: test Slim :可以取代ERB的模版语言.(简单了解了以下,方便写代码,但我觉得不方便读.还是用原生的html) Webpack管理css: 不再使用app/assets/styl ...

  5. 2018焦作网络赛Mathematical Curse

    题意:开始有个数k,有个数组和几个运算符.遍历数组的过程中花费一个运算符和数组当前元素运算.运算符必须按顺序花费,并且最后要花费完.问得到最大结果. 用maxv[x][y]记录到第x个元素,用完了第y ...

  6. Confluence 6 使用 LDAP 授权连接一个内部目录概述

    你可以为你的 Confluence 连接 LDAP 服务器使用使用委托认证.这个意思是 Confluence 将会设置一个内部目录,这个目录仅被用来处理 LDAP 的授权. 这个设置将会为尝试登录系统 ...

  7. Confluence 6 LDAP 用户组结构设置

    用户组对象类(Group Object Class) 这是在 LDAP 用户组对象中使用的类的名字.例如: groupOfUniqueNames group 用户组对象过滤器(Group Object ...

  8. 百度安卓SDK秘钥Key错误

    下载官方安卓地图demo,输入报名和sha1申请AK,发现key错误 构建的时候要指定生成的key 安卓定位BaiduLocDemo出现aapt.exe finished with non-zero ...

  9. python-day8-字典的内置方法

    # info=['egon','male',18,180,75]### info_dic={'name':'egon','age':18,'sex':'male'} # 有对应关系 # 常用操作:优先 ...

  10. gleez安装报错

    1gleez安装时候常见的问题就是别人在代码版本服务器上安装好了,一般开发者都会去对文件做一些忽略,所以导致有几个文件是没有的.比如: bootstrap.php      .htaccess 2.如 ...