/****************************************************************************
* 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. shell 求模

    $ expr % $ let i=% $ echo $i $ echo % | bc $ ((i=%)) $ echo $i

  2. Python day9函数部分

    函数的学习:函数对于一门编程语言来说挺重要的,尤其是c语言,是完全使用函数来编写的 1.函数的定义:逻辑结构化和过程化的一种编程方法 def squre(x): "求一个数的平方 retur ...

  3. meta 标签

    <meta http-equiv="Refresh" content="5;url=http://www.w3school.com.cn" /> & ...

  4. typescripts学习

    可选与默认参数 可选参数:在参数名后面,冒号前面添加一个问号,则表明该参数是可选的.如下代码: function buildName(firstName: string, lastName?: str ...

  5. Python BeautifulSoup的使用

    2017-07-24 22:39:14 Python3 中的beautifulsoup引入的包是bs4 import requests from bs4 import * r = requests.g ...

  6. Ubuntu安装NVIDA显卡驱动

    0. 综述 电脑型号:R720 Ubuntu版本:16 显卡型号:1050ti 目前,知道3种安装N卡驱动的方法: 1. PPA源:最简便,但未必有最新驱动(亲测),或可能遇到问题(风闻). sudo ...

  7. 雷林鹏分享:Ruby 数据类型

    Ruby 数据类型 本章节我们将为大家介绍 Ruby 的基本数据类型. Ruby支持的数据类型包括基本的Number.String.Ranges.Symbols,以及true.false和nil这几个 ...

  8. illumina phix

    PhiX Control v3 is a reliable, adapter-ligated library used as a control for Illumina sequencing run ...

  9. English trip -- VC(情景课)9 B Outside chores 室外家务

    Vocabulary focus 核心词汇 cutting the grass 修剪草坪 getting the mail  收到邮件 taking out the trash  把垃圾带出去 wal ...

  10. 新概念 Lesson 3 Nice to meet you

    Nice to meet you. 你好 打招呼: hi,hello 重点: 打招呼和互相介绍.主系表结构 Is Chang-woo Chinese? 昌武是中国人吗? No,he isn't . H ...