zoukankan      html  css  js  c++  java
  • hacking a friend's Linux buzzer driver in OK335xS

      1 /****************************************************************************
      2  *          hacking a friend's Linux buzzer driver in OK335xS
      3  * 说明:
      4  *   解读朋友的Linux buzzer驱动,作为后续相关编码的参考。
      5  *
      6  *                                   2015-8-25 晴 深圳 南山平山村 曾剑锋
      7  ***************************************************************************/
      8 #include <linux/init.h>
      9 #include <linux/module.h>
     10 #include <linux/leds.h>
     11 #include <linux/io.h>
     12 #include <linux/semaphore.h>
     13 #include <linux/kernel.h>
     14 #include <linux/cdev.h>
     15 #include <linux/types.h>
     16 #include <linux/fs.h>
     17 #include <mach/gpio.h>
     18 #include <plat/mux.h>
     19 #include <linux/gpio.h>
     20 
     21 #define IO_VAULE_H          5  
     22 #define IO_VAULE_L          6
     23 
     24 /**
     25  * 1. 参考文档:AM335x ARM Cortex-A8 Microprocessors (MPUs) Technical Reference Manual (Rev. H).pdf
     26  * 2. ARM Cortex-A8 Memory Map:
     27  *                         Table 2-1. L3 Memory Map (page 155)
     28  *  +------------+---------------------+-------------------+------------------+
     29  *  | Block Name | Start_address (hex) | End_address (hex) | Size Description |
     30  *  +------------+---------------------+-------------------=------------------+
     31  *  | L4_WKUP    | 0x44C0_0000         | 0x44FF_FFFF       | 4MB L4_WKUP      |
     32  *  +------------+---------------------+-------------------+------------------+
     33  *                        Table 2-2. L4_WKUP Peripheral Memory Map (page 158)
     34  *  +----------------+---------------------+-------------------+-------+--------------------------+
     35  *  | Region Name    | Start Address (hex) | End Address (hex) | Size  | Description              |
     36  *  +----------------+---------------------+-------------------+-------+--------------------------+
     37  *  | Control Module | 0x44E1_0000         | 0x44E1_1FFF       | 128KB | Control Module Registers |
     38  *  +----------------+---------------------+-------------------+-------+--------------------------+
     39  */
     40 #define Control_Module_address                0x44E10000
     41 
     42 /**
     43  * 1. 参考文档:AM335x ARM Cortex-A8 Microprocessors (MPUs) Technical Reference Manual (Rev. H).pdf
     44  * 2. CONTROL_MODULE Registers:
     45  *                     Table 9-10. CONTROL_MODULE REGISTERS
     46  *  +--------+---------------+----------------------+----------------+
     47  *  | Offset | Acronym       | Register Description | Section        |
     48  *  +--------+---------------+----------------------+----------------+
     49  *  | 960h   | conf_spi0_cs1 |                      | Section 9.3.51 |
     50  *  +--------+---------------+----------------------+----------------+
     51  */
     52 #define CONFIG_SPI0_CS1_offset                0x960
     53 
     54 /**
     55  * can't find any reference for this define, but it can use
     56  */
     57 #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio) )
     58 
     59 /**
     60  * just like container_of in kernel 
     61  */
     62 #define GET_STRUCT_ADDR (ptr,type,member)
     63      ((unsigned long )ptr - (unsigned long)((type*)0->member)) 
     64 
     65 /**
     66  * 1. 参考文档:Sitara AM335x ARM Cortex-A8 Microprocessors (MPUs) (Rev. F).pdf
     67  *    Table 2-7. Ball Characteristics (ZCE and ZCZ Packages) (continued) (page 43)
     68  *  +-----------+-----------+-------------+--------------------+---------+---------+
     69  *  | ZCE BALL  | ZCZ BALL  | PIN NAME[2] |  SIGNAL NAME[3]    | MODE[4] | TYPE[5] |
     70  *  | NUMBER[1] | NUMBER[1] |             |                    |         |         |
     71  *  +-----------+-----------+-------------+--------------------+---------+---------+
     72  *  | B16       | C15       | SPI0_CS1    |  spi0_cs1          | 0       | I/O     |
     73  *  |           |           |             |--------------------|---------+---------+
     74  *  |           |           |             |  uart3_rxd         | 1       | I       |
     75  *  |           |           |             |--------------------|---------+---------+
     76  *  |           |           |             |  eCAP1_in_PWM1_out | 2       | I/O     |
     77  *  |           |           |             |--------------------|---------+---------+
     78  *  |           |           |             |  mmc0_pow          | 3       | O       |
     79  *  |           |           |             |--------------------|---------+---------+
     80  *  |           |           |             |  xdma_event_intr2  | 4       | I       |
     81  *  |           |           |             |--------------------|---------+---------+
     82  *  |           |           |             |  mmc0_sdcd         | 5       | I       |
     83  *  |           |           |             |--------------------|---------+---------+
     84  *  |           |           |             |  EMU4              | 6       | I/O     |
     85  *  |           |           |             |--------------------|---------+---------+
     86  *  |           |           |             |  gpio0_6           | 7       | I/O     |
     87  *  +-----------+-----------+-------------+--------------------+---------+---------+
     88  */ 
     89 #define BUZZER_PIN     GPIO_TO_PIN(0, 6)
     90 
     91 struct cdev * buzz;
     92 
     93 static int buzz_init(void)
     94 {
     95     int result;
     96 
     97     /**
     98      * void *ioremap(unsigned long phys_addr, unsigned long size)
     99      *  入口:phys_addr:要映射的起始的IO地址;
    100      *  size:要映射的空间的大小;
    101      */
    102     void __iomem * base = ioremap(Control_Module_address, 0x1FFF);
    103     /**
    104      * 1 参考文章:AM335x ARM Cortex-A8 Microprocessors (MPUs) Technical Reference Manual (Rev. H).pdf
    105      *          Table 9-61. conf_<module>_<pin> Register Field Descriptions(page 815)
    106      *  +-------+-------------------------+--------------+-------------------------------------------+
    107      *  | Bit   | Field                   | Type | Reset | Description                               |
    108      *  +-------+-------------------------+--------------+-------------------------------------------+
    109      *  | 31-20 | Reserved                | R    | 0h    |                                           |
    110      *  +-------+-------------------------+--------------+-------------------------------------------+
    111      *  | 19-7  | Reserved                | R    | 0h    |                                           |
    112      *  +-------+-------------------------+--------------+-------------------------------------------+
    113      *  | 6     | conf_<module>_<pin>_sle | R/W  | X     | Select between faster or slower slew rate |
    114      *  |       | wctrl                   |      |       | 0: Fast                                   |
    115      *  |       |                         |      |       | 1: Slow                                   |
    116      *  |       |                         |      |       | Reset value is pad-dependent.             |
    117      *  +-------+-------------------------+--------------+-----------------------------------------  +
    118      *  | 5     | conf_<module>_<pin>_rx  | R/W  | 1h    | Input enable value for the PAD            |
    119      *  |       | active                  |      |       | 0: Receiver disabled                      |
    120      *  |       |                         |      |       | 1: Receiver enabled                       |
    121      *  +-------+-------------------------+--------------+-----------------------------------------  +
    122      *  | 4     | conf_<module>_<pin>_pu  | R/W  | X     | Pad pullup/pulldown type selection        |
    123      *  |       | typesel                 |      |       | 0: Pulldown selected                      |
    124      *  |       |                         |      |       | 1: Pullup selected                        |
    125      *  |       |                         |      |       | Reset value is pad-dependent.             |
    126      *  +-------+-------------------------+--------------+-------------------------------------------+
    127      *  | 3     | conf_<module>_<pin>_pu  | R/W  | X     | Pad pullup/pulldown enable                |
    128      *  |       | den                     |      |       | 0: Pullup/pulldown enabled                |
    129      *  |       |                         |      |       | 1: Pullup/pulldown disabled               |
    130      *  |       |                         |      |       | Reset value is pad-dependent.             |
    131      *  +-------+-------------------------+--------------+-------------------------------------------+
    132      *  | 2-0   | conf_<module>_<pin>_m   | R/W  | X     | Pad functional signal mux select.         |
    133      *  |       | mode                    |      |       | Reset value is pad-dependent.             |
    134      *  +-------+-------------------------+--------------+-------------------------------------------+
    135      * 2. 0x37 = B0011 0111
    136      *      1. bit 6 --> 0 --> Fast;
    137      *      2. bit 5 --> 1 --> Receiver enabled;
    138      *      3. bit 4 --> 1 --> Pullup selected;
    139      *      4. bit 3 --> 0 --> Pullup/pulldown enabled;
    140      *      5. bit 2-0 --> 7 --> gpio0_6;  参考前面说明 #define BUZZER_PIN     GPIO_TO_PIN(0,6)
    141      */
    142     __raw_writel(0x37, (base + CONFIG_SPI0_CS1_offset ));
    143 
    144     /* Allocating GPIOs and setting direction */
    145     result = gpio_request(BUZZER_PIN, "buzzer");            //usr1
    146     if (result != 0) 
    147         printk("gpio_request(0_6) failed!
    "); return result; 
    148 
    149     result = gpio_direction_output(BUZZER_PIN, 1);
    150     if (result != 0) 
    151         printk("gpio_direction(0_6) failed!
    "); return result; 
    152 
    153     gpio_set_value(BUZZER_PIN, 0);
    154 
    155     return result;
    156 }
    157 
    158 static int buzz_open(struct inode *inode, struct file *file)
    159 {
    160     return 0;
    161 }
    162 
    163 static ssize_t buzz_read (struct file *file, char __user *buf, size_t size, loff_t * off)
    164 {
    165     return 0;
    166 }
    167 
    168 static int buzz_ioctl(struct file *filp,unsigned int cmd,    unsigned long arg)
    169 { 
    170     if(cmd == IO_VAULE_H ) {
    171         printk(" buzz iotcl IO_VALUE_H.
    ");       // for debug
    172             gpio_set_value(BUZZER_PIN,1);
    173     }
    174     if(cmd == IO_VAULE_L ) {
    175         printk(" buzz iotcl IO_VALUE_L.
    ");
    176             gpio_set_value(BUZZER_PIN,0);
    177     }
    178 
    179     return 0;      
    180 }
    181 
    182 static ssize_t buzz_write (struct file *file, char __user *buf, size_t size, loff_t * off)
    183 {
    184     return 0;
    185 }
    186 
    187 static int buzz_release (struct inode *inode, struct file *file)
    188 {
    189     return 0;
    190 }
    191 
    192 struct file_operations buzz_fops = {
    193     .owner = THIS_MODULE,
    194     .open =    buzz_open,
    195     .read =    buzz_read,
    196     .write =   buzz_write,
    197     .release = buzz_release,
    198     .unlocked_ioctl= buzz_ioctl
    199 };
    200 
    201 static int __init  buzzm_init()
    202 {
    203     /**
    204      * 表示静态的申请和注册设备号:
    205      * register_chrdev_region(dev_t first,unsigned int count,char *name) 
    206      *    first :要分配的设备编号范围的初始值(次设备号常设为0); 
    207      *    count:连续编号范围. 
    208      *    name:编号相关联的设备名称. (/proc/devices); 
    209      */
    210     if(register_chrdev_region(MKDEV(301,0),1,"aple_buzz") < 0)
    211         return     -ENOMEM    ;
    212 
    213     /**
    214      * 前面只是注册了设备号,后面要向内核添加设备了;
    215      */
    216     buzz = cdev_alloc();
    217     if(buzz == NULL)
    218         return -ENOMEM;
    219 
    220     cdev_init(buzz , &buzz_fops);
    221     cdev_add(buzz ,MKDEV(301,0),1);
    222     buzz_init();
    223     return 0;
    224 }
    225 
    226 static void  __exit  buzzm_exit()
    227 {
    228     cdev_del(buzz);
    229     unregister_chrdev_region(MKDEV(301,0),1);
    230 }
    231 
    232 
    233 module_init(buzzm_init);
    234 module_exit(buzzm_exit);
    235 MODULE_AUTHOR("Danny Zhao");
    236 MODULE_LICENSE("GPL");
  • 相关阅读:
    收集起来先
    asp .net 页面回车触发button 按钮事件
    关于SQL 数据库表中的聚集索引和非聚集索引等
    WinForm换肤操作(用IrisSkin2.dll)
    生成Word文档的相关操作
    API自动化测试测试数据集
    API文档实践
    使用eolinker对API测试的响应结果进行断言
    API自动化定时测试
    接口测试之对数据进行RSA加解密
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/4757185.html
Copyright © 2011-2022 走看看