GPIO的驅動模型

  1. 一、概述
  2. GPIO是嵌入式系統最簡單、最常用的資源了,比如點亮LED,控制蜂鳴器,輸出高低電平,檢測按鍵,等等。GPIO分輸入和輸出,在davinci linux中,有關GPIO的最底層的寄存器驅動,\arch\arm\mach-davinci目錄下的gpio.c,這個是寄存器級的驅動,搞過單片機MCU的朋友應該比較熟悉寄存器級的驅動。

  3. GPIO的驅動主要就是讀取GPIO口的狀態,或者設置GPIO口的狀態。就是這麼簡單,但是爲了能夠寫好的這個驅動,在LINUX上作了一些軟件上的分層。爲了讓其它驅動可以方便的操作到GPIO,在LINUX裏實現了對GPIO操作的統一接口,這個接口實則上就是GPIO驅動的框架,具體的實現文件爲gpiolib.c在配置內核的時候,我們必須使用CONFIG_GENERIC_GPIO這個宏來支持GPIO驅動。

  4. GPIO是與硬件體系密切相關的,linux提供一個模型來讓驅動統一處理GPIO,即各個板卡都有實現自己的gpio_chip控制模塊:request, free, input,output, get,set,irq...然後把控制模塊註冊到內核中,這時會改變全局gpio數組:gpio_desc[]. 當用戶請求gpio時,就會到這個數組中找到,並調用這個GPIO對應的gpio_chip的處理函數。gpio實現爲一組可用的 gpio_chip, 由驅動傳入對應 gpio的全局序號去 request, dataout ,datain, free. 這時會調用gpio_chip中具體的實現。
  5. gpio是一組可控件的腳,由多個寄存器同時控制。通過設置對應的寄存器可以達到設置GPIO口對應狀態與功能。數據狀態,輸入輸出方向,清零,中斷(那個邊沿觸發), 一般是一組(bank)一組的。
  6. 寄存器讀寫函數: __raw_writel() __raw_writeb() __raw_readl() __raw_readb()

  7. 二、linux 中GPIO模型的結構
  8. //表示一個gpio口,含對應的gpio_chip.
  9. //對於每一個gpio,都有一個gpio描述符,這個描述符包含了這個gpio所屬的控制器即chip和一些標誌,label等
  10. struct gpio_desc {
  11.     struct gpio_chip    *chip;
  12.     unsigned long    flags;
  13.     /* flag symbols are bit numbers */
  14.     #define FLAG_REQUESTED 0
  15.     #define FLAG_IS_OUT 1
  16.     #define FLAG_RESERVED 2
  17.     #define FLAG_EXPORT 3 /* protected by sysfs_lock */
  18.     #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */
  19.     #define FLAG_TRIG_FALL 5 /* trigger on falling edge */
  20.     #define FLAG_TRIG_RISE 6 /* trigger on rising edge */
  21.     #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */
  22.     #define FLAG_OPEN_DRAIN 8 /* Gpio is open drain type */
  23.     #define FLAG_OPEN_SOURCE 9 /* Gpio is open source type */
  24.     
  25.     #define ID_SHIFT 16 /* add new flags before this one */ 
  26.     #define GPIO_FLAGS_MASK ((1 << ID_SHIFT) - 1)
  27.     #define GPIO_TRIGGER_MASK (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE))
  28.  
  29. #ifdef CONFIG_DEBUG_FS
  30.     const char    *label;
  31. #endif
  32. };
  33. //採用了一個具有ARCH_NR_GPIOS大小的gpio描述符數組。這個描述符數組便代表了系統所有的gpio。
  34. static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];//ARCH_NR_GPIOS=144,即系統現在有144個GPIO口

  35. //static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];//將144個GPIO分成每32個一組
  36. //一組GPIO控制器結構,例如GPIO0和GPIO1是一組(共32個GPIO口),共用一組寄存器,所以GPIO0和GPIO1荷載一起用chips[0]來控制
  37. ///共有144個GPIO,分爲4組(GPIO0~GPIO8),每組有2個banks(即GPIO0和GPIO1爲1組),每組最多可以有32個GPIO,每組的控制寄存器空間有10個。
  38. struct davinci_gpio_controller {
  39.     struct gpio_chip    chip;//每組對應的gpio_chip
  40.     int            irq_base;//每組對應的中斷
  41.     spinlock_t        lock;//自旋鎖
  42.     void __iomem        *regs;//每組的寄存器地址
  43.     void __iomem        *set_data;//設置數據寄存器地址
  44.     void __iomem        *clr_data;//清除數據寄存器地址
  45.     void __iomem        *in_data;//輸入數據寄存器地址
  46. }; 

  47. //每一個davinci_gpio_controller結構都對應於一個gpio_chip結構,gpio_chip既可看成是davinci_gpio_controller結構的補充
  48. //表示一個gpio controller.通過這個結構抽象化所有的GPIO源,而讓板上其它的模塊可以用相同的接口調用使用這些GPIO。
  49. struct gpio_chip {
  50.     const char    *label;
  51.     struct device    *dev;
  52.     struct module    *owner; 
  53.     int    (*request)(struct gpio_chip *chip,unsigned offset);//請求gpio
  54.     void    *free)(struct gpio_chip *chip,unsigned offset);//釋放gpio
  55.     int    (*get_direction)(struct gpio_chip *chip,unsigned offset);
  56.     int    (*direction_input)(struct gpio_chip *chip,unsigned offset);//配置gpio爲輸入,返回當前gpio狀態
  57.     int    (*get)(struct gpio_chip *chip,unsigned offset);//獲取gpio的狀態
  58.     int    (*direction_output)(struct gpio_chip *chip,unsigned offset, int value);//配置gpio爲輸出,並設置爲value
  59.     int    (*set_debounce)(struct gpio_chip *chip,unsigned offset, unsigned debounce);//設置消抖動時間,尤其是gpio按鍵時有用
  60.     void    (*set)(struct gpio_chip *chip,unsigned offset, int value);//設置gpio爲value值
  61.     int    (*to_irq)(struct gpio_chip *chip,unsigned offset);//把gpio號轉換爲中斷號
  62.     void    (*dbg_show)(struct seq_file *s,struct gpio_chip *chip);
  63.     int    base;// 這個gpio控制器的gpio開始編號
  64.     u16    ngpio;//這個gpio控制器說控制的gpio數
  65.     const char    *const *names;
  66.     unsigned    can_sleep:1;
  67.     unsigned    exported:1;
  68.  
  69. #if defined(CONFIG_OF_GPIO)
  70.     struct device_node *of_node;
  71.     int of_gpio_n_cells;
  72.     int (*of_xlate)(struct gpio_chip *gc,const struct of_phandle_args *gpiospec, u32 *flags);
  73. #endif
  74. #ifdef CONFIG_PINCTRL
  75.     struct list_head pin_ranges;
  76. #endif
  77. };

  78. //GPIO寄存器結構
  79. struct davinci_gpio_regs {
  80.     u32 dir; // gpio方向設置寄存器 
  81.     u32 out_data; // gpio設置爲輸出時,表示輸出狀態(0或1) 
  82.     u32 set_data; // gpio設置爲輸出時,用於輸出高電平 
  83.     u32 clr_data; // gpio設置爲輸出時,用於輸出低電平 
  84.     u32 in_data; // gpio設置爲輸入時,用於讀取輸入值 
  85.     u32 set_rising; // gpio中斷上升沿觸發設置 
  86.     u32 clr_rising; // gpio中斷上升沿觸發清除 
  87.     u32 set_falling; // gpio中斷下降沿觸發設置 
  88.     u32 clr_falling; // gpio中斷下降沿觸發清除 
  89.     u32 intstat; // gpio中斷狀態位,由硬件設置,可讀取,寫1時清除。 
  90. };

  91. struct gpio {
  92.     unsigned gpio;//gpio號
  93.     unsigned long flags;//gpio標誌
  94.     const char *label;//gpio名
  95. };

  96. 三、GPIO的初始化
  97. 1.首先設置GPIO的管腳複用寄存器
  98. static __init void da850_evm_init(void)
  99. {
  100.     //.......
  101.     ret = davinci_cfg_reg_list(da850_gpio_test_pins);
  102.     if (ret) 
  103.         pr_warning("da850_evm_init: gpio test ping mux setup failed: %d\n", ret);
  104.     //.......
  105. }

  106. 2.根據板級結構的資源初始化chips數組,此函數在系統初始化時自動調用
  107. static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];//將144個GPIO分成每32個一組
  108. static int __init davinci_gpio_setup(void)
  109. {
  110.     int i, base;
  111.     unsigned ngpio;
  112.     struct davinci_soc_info *soc_info = &davinci_soc_info;//板級資源結構
  113.     struct davinci_gpio_regs *regs;

  114.     if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)//判斷GPIO類型
  115.         return 0;

  116.     ngpio = soc_info->gpio_num;//GPIO數量144
  117.     if (ngpio == 0) {
  118.         pr_err("GPIO setup: how many GPIOs?\n");
  119.         return -EINVAL;
  120.     }

  121.     if (WARN_ON(DAVINCI_N_GPIO < ngpio))//DAVINCI_N_GPIO=144
  122.         ngpio = DAVINCI_N_GPIO;

  123.     gpio_base = ioremap(soc_info->gpio_base, SZ_4K);//將GPIO的寄存器物理基地址(#define DA8XX_GPIO_BASE        0x01e26000)映射到內存中
  124.     if (WARN_ON(!gpio_base))
  125.         return -ENOMEM;
  126.     
  127.     //共有144個GPIO,分爲4組(GPIO0~GPIO8),每組有2個banks(即GPIO0和GPIO1爲1組),每組最多可以有32個GPIO,每組的控制寄存器空間有10個。
  128.     //chips[0]--chips[4],base值爲0,32,64,96,128,ngpio分別爲:32,32,32,32,16
  129.     for (i = 0, base = 0; base < ngpio; i++, base += 32) {
  130.         chips[i].chip.label = "DaVinci";
  131.         //設置操作函數
  132.         chips[i].chip.direction_input = davinci_direction_in;
  133.         chips[i].chip.get = davinci_gpio_get;
  134.         chips[i].chip.direction_output = davinci_direction_out;
  135.         chips[i].chip.set = davinci_gpio_set;

  136.         chips[i].chip.base = base;//每一組開始的GPIO號
  137.         //每組控制的GPIO個數,一般爲32個
  138.         chips[i].chip.ngpio = ngpio - base;
  139.         if (chips[i].chip.ngpio > 32)
  140.             chips[i].chip.ngpio = 32;

  141.         spin_lock_init(&chips[i].lock);
  142.         //找到這組GPIO的寄存器地址,初始化chips結構
  143.         regs = gpio2regs(base);
  144.         chips[i].regs = regs;//設置每組的寄存器
  145.         chips[i].set_data = ?s->set_data;
  146.         chips[i].clr_data = ?s->clr_data;
  147.         chips[i].in_data = ?s->in_data;
  148.         
  149.         gpiochip_add(&chips[i].chip);//註冊gpio_chip
  150.     }
  151.     //chips數組添加到板級資源中
  152.     soc_info->gpio_ctlrs = chips;
  153.     soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);

  154.     davinci_gpio_irq_setup();//設置GPIO中斷
  155.     return 0;
  156. }
  157. pure_initcall(davinci_gpio_setup);//linux初始化時會自動調用

  158. static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
  159. {
  160.     void __iomem *ptr;
  161.     
  162.     //根據GPIO的基地址累加,其中基地址(gpio_base+0)是REVID(Revision ID Register)寄存器
  163.     //(gpio_base+8)是BINTEN (GPIO Interrupt Per-Bank Enable Register)寄存器
  164.     //所以第一組寄存器從基地址+0x10開始
  165.     if (gpio < 32 * 1)
  166.         ptr = gpio_base + 0x10;
  167.     else if (gpio < 32 * 2)
  168.         ptr = gpio_base + 0x38;
  169.     else if (gpio < 32 * 3)
  170.         ptr = gpio_base + 0x60;
  171.     else if (gpio < 32 * 4)
  172.         ptr = gpio_base + 0x88;
  173.     else if (gpio < 32 * 5)
  174.         ptr = gpio_base + 0xb0;
  175.     else
  176.         ptr = NULL;
  177.     return ptr;
  178. }

  179. int gpiochip_add(struct gpio_chip *chip)
  180. {
  181.     unsigned long    flags;
  182.     int        status = 0;
  183.     unsigned    id;
  184.     int        base = chip->base;
  185.     
  186.     //檢測gpio的有效性,判斷這組GPIO的起始號是否在有效範圍內
  187.     if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1))&& base >= 0) {
  188.         status = -EINVAL;
  189.         goto fail;
  190.     }

  191.     spin_lock_irqsave(&gpio_lock, flags);
  192.     
  193.     //如果這組GPIO的起始號小於0,則動態的分配gpio的開始索引。
  194.     if (base < 0) {
  195.         base = gpiochip_find_base(chip->ngpio);//這個函數在gpiolib.c中,在gpio_desc[]中分配chip->ngpio個空間(從最後往前分配),返回第一個index
  196.         if (base < 0) {
  197.             status = base;
  198.             goto unlock;
  199.         }
  200.         chip->base = base;
  201.     }

  202.     //確保這些分配的gpio號沒有被其他chip佔用
  203.     for (id = base; id < base + chip->ngpio; id++) {
  204.         if (gpio_desc[id].chip != NULL) {
  205.             status = -EBUSY;
  206.             break;
  207.         }
  208.     }
  209.     //填充gpio_desc,將該組內的每個GPIO口的gpio_desc結構和該組的控制結構chip聯繫起來
  210.     if (status == 0) {
  211.         for (id = base; id < base + chip->ngpio; id++) {
  212.             gpio_desc[id].chip = chip;
  213.             gpio_desc[id].flags = !chip->direction_input? (1 << FLAG_IS_OUT): 0;//設置GPIO口標誌
  214.         }
  215.     }
  216.     of_gpiochip_add(chip);

  217. unlock:
  218.     spin_unlock_irqrestore(&gpio_lock, flags);

  219.     if (status)
  220.         goto fail;

  221.     status = gpiochip_export(chip);//與sysfs文件系統有關,這裏不關心
  222.     if (status)
  223.         goto fail;

  224.     return 0;
  225. fail:
  226.     /* failures here can mean systems won't boot... */
  227.     pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",chip->base, chip->base + chip->ngpio - 1,chip->label ? : "generic");
  228.     return status;
  229. }

  230. .gpio的申請
  231. //所謂申請就是檢測GPIO描述符desc->flags的FLAG_REQUESTED標誌,已申請的話該標誌是1,否則是0
  232. //往往多個gpio作爲一個數組來進行申請
  233. int gpio_request_array(struct gpio *array, size_t num)
  234. {
  235.     int i, err;

  236.     for (i = 0; i < num; i++, array++) {//遍歷數組中的每一個GPIO,gpio是GPIO號,flags是輸入輸出標誌等,label是其取一個名字
  237.         err = gpio_request_one(array->gpio, array->flags, array->label);
  238.         if (err)
  239.             goto err_free;
  240.     }
  241.     return 0;

  242. err_free:
  243.     while (i--)
  244.         gpio_free((--array)->gpio);
  245.     return err;
  246. }

  247. int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
  248. {
  249.     int err;
  250.     
  251.     //gpio則爲你要申請的哪一個管腳,label則是爲其取一個名字。
  252.     err = gpio_request(gpio, label);
  253.     if (err)
  254.         return err;

  255.     if (flags & GPIOF_DIR_IN)//GPIO標誌是輸入
  256.         err = gpio_direction_input(gpio);//設置管腳爲輸入
  257.     else//GPIO標誌是輸出
  258.         err = gpio_direction_output(gpio,(flags & GPIOF_INIT_HIGH) ? 1 : 0);//根據標誌確定輸出1還是0

  259.     if (err)
  260.         gpio_free(gpio);

  261.     return err;
  262. }

  263. int gpio_request(unsigned gpio, const char *label)
  264. {
  265.     struct gpio_desc    *desc;
  266.     struct gpio_chip    *chip;
  267.     int            status = -EINVAL;
  268.     unsigned long        flags;
  269.     //屏蔽中斷
  270.     spin_lock_irqsave(&gpio_lock, flags);

  271.     if (!gpio_is_valid(gpio))//判斷是否有效,也就是參數的取值範圍判斷
  272.         goto done;
  273.         
  274.     //根據GPIO號找到對應的GPIO描述符結構
  275.     desc = &gpio_desc[gpio];
  276.     chip = desc->chip;//找到該GPIO所在的組控制器
  277.     if (chip == NULL)
  278.         goto done;
  279.         
  280.     //計數加1
  281.     if (!try_module_get(chip->owner))
  282.         goto done;

  283.     //這裏測試並設置flags的第FLAG_REQUESTED位,如果沒有被申請就返回該位的原值0
  284.     if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
  285.         desc_set_label(desc, label ? : "?");//設置GPIO描述符結構desc的label字段
  286.         status = 0;
  287.     } else {
  288.         status = -EBUSY;
  289.         module_put(chip->owner);
  290.         goto done;
  291.     }

  292.     if (chip->request) {/* chip->request may sleep */
  293.         spin_unlock_irqrestore(&gpio_lock, flags);
  294.         status = chip->request(chip, gpio - chip->base);
  295.         spin_lock_irqsave(&gpio_lock, flags);

  296.         if (status < 0) {
  297.             desc_set_label(desc, NULL);
  298.             module_put(chip->owner);
  299.             clear_bit(FLAG_REQUESTED, &desc->flags);
  300.         }
  301.     }

  302. done:
  303.     if (status)
  304.         pr_debug("gpio_request: gpio-%d (%s) status %d\n",gpio, label ? : "?", status);
  305.     spin_unlock_irqrestore(&gpio_lock, flags);
  306.     return status;
  307. }

  308. .GPIO的操作
  309. 1.設置GPIO爲輸出或輸入
  310. int gpio_direction_input(unsigned gpio)
  311. {
  312.     unsigned long        flags;
  313.     struct gpio_chip    *chip;
  314.     struct gpio_desc    *desc = &gpio_desc[gpio];
  315.     int            status = -EINVAL;

  316.     spin_lock_irqsave(&gpio_lock, flags);
  317.     
  318.     //判斷GPIO號是否有效
  319.     if (!gpio_is_valid(gpio))
  320.         goto fail;
  321.     //找到GPIO對應的gpio_chip結構
  322.     chip = desc->chip;
  323.     if (!chip || !chip->get || !chip->direction_input)
  324.         goto fail;
  325.     
  326.     //確保此GPIO是在此組內,chip->base是此組GPIO的起始號,chip->ngpio是此組GPIO的個數
  327.     gpio -= chip->base;
  328.     if (gpio >= chip->ngpio)
  329.         goto fail;
  330.         
  331.     //確保GPIO已申請
  332.     status = gpio_ensure_requested(desc, gpio);
  333.     if (status < 0)
  334.         goto fail;

  335.     //到這裏可以確保GPIO是有效的
  336.     spin_unlock_irqrestore(&gpio_lock, flags);

  337.     might_sleep_if(chip->can_sleep);
  338.     //status=0
  339.     if (status) {
  340.         status = chip->request(chip, gpio);
  341.         if (status < 0) {
  342.             pr_debug("GPIO-%d: chip request fail, %d\n",chip->base + gpio, status);
  343.             goto lose;
  344.         }
  345.     }
  346.     //調用底層的已經設置過的操作,這裏即davinci_direction_in
  347.     status = chip->direction_input(chip, gpio);
  348.     if (status == 0)//返回成功
  349.         clear_bit(FLAG_IS_OUT, &desc->flags);//清除輸出標誌
  350. lose:
  351.     return status;
  352. fail:
  353.     spin_unlock_irqrestore(&gpio_lock, flags);
  354.     if (status)
  355.         pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);
  356.     return status;
  357. }

  358. int gpio_direction_output(unsigned gpio, int value)
  359. {
  360.     //.........GPIO的檢查,同上函數
  361.     
  362.     //調用底層的已經設置過的操作,這裏即davinci_direction_out
  363.     status = chip->direction_output(chip, gpio, value);
  364.     if (status == 0)//返回成功
  365.         set_bit(FLAG_IS_OUT, &desc->flags);//設置輸出標誌
  366. lose:
  367.     return status;
  368. fail:
  369.     spin_unlock_irqrestore(&gpio_lock, flags);
  370.     if (status)
  371.         pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);
  372.     return status;
  373. }

  374. //根據前邊對gpio_chip結構的初始化,會調用\arch\arm\mach-davinci\gpio.c裏的函數
  375. static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
  376. {
  377.     return __davinci_direction(chip, offset, false, 0);
  378. }

  379. static int davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
  380. {
  381.     return __davinci_direction(chip, offset, true, value);
  382. }

  383. static inline int __davinci_direction(struct gpio_chip *chip,unsigned offset, bool out, int value)
  384. {
  385.     struct davinci_gpio_controller *d = chip2controller(chip);
  386.     struct davinci_gpio_regs __iomem *g = d->regs;//找到此組GPIO的控制寄存器地址
  387.     unsigned long flags;
  388.     u32 temp;
  389.     u32 mask = 1 << offset;

  390.     spin_lock_irqsave(&d->lock, flags);
  391.     temp = __raw_readl(&g->dir);//讀出當前寄存器的輸入輸出方向
  392.     
  393.     if (out) {//爲1設置輸出
  394.         temp &= ~mask;
  395.         __raw_writel(mask, value ? &g->set_data : &g->clr_data);//確定是用於輸出高電平還是輸出低電平
  396.     } 
  397.     else {//爲0設置爲輸入
  398.         temp |= mask;
  399.     }
  400.     __raw_writel(temp, &g->dir);//寫入方向寄存器
  401.     spin_unlock_irqrestore(&d->lock, flags);

  402.     return 0;
  403. }

  404. 2.獲取gpio的狀態
  405. int __gpio_get_value(unsigned gpio)
  406. {
  407.     struct gpio_chip    *chip;

  408.     chip = gpio_to_chip(gpio);
  409.     WARN_ON(chip->can_sleep);
  410.     return chip->get ? chip->get(chip, gpio - chip->base) : 0;//調用davinci_gpio_get
  411. }

  412. static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
  413. {
  414.     struct davinci_gpio_controller *d = chip2controller(chip);
  415.     struct davinci_gpio_regs __iomem *g = d->regs;

  416.     return (1 << offset) & __raw_readl(&g->in_data);
  417. }

  418. 3.設置GPIO的值
  419. void __gpio_set_value(unsigned gpio, int value)
  420. {
  421.     struct gpio_chip    *chip;

  422.     chip = gpio_to_chip(gpio);
  423.     WARN_ON(chip->can_sleep);
  424.     chip->set(chip, gpio - chip->base, value);//調用davinci_gpio_set
  425. }

  426. static void davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  427. {
  428.     struct davinci_gpio_controller *d = chip2controller(chip);
  429.     struct davinci_gpio_regs __iomem *g = d->regs;

  430.     __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
  431. }

  432. 六、GPIO驅動編寫
  433. 1.首先要申請GPIO口
  434. 2.註冊設備
  435. 3.創建GPIO的sysfs相關文件
  436. #define GPIO_MAJOR 199         // major device NO.
  437. #define GPIO_MINOR 0         // minor device NO.
  438. #define DEVICE_NAME "omapl138_gpios" /*定義設備驅動的名字,或設備節點名稱*/

  439. #define SET_OUTPUT_LOW 0
  440. #define SET_OUTPUT_HIGH 1
  441. #define GET_VALUE 2
  442. #define SET_INPUT 3

  443. static struct class *gpio_class;
  444. static struct gpio gpio_array[] =
  445. {
  446.     /*{ GPIO_TO_PIN(0, 0), GPIOF_OUT_INIT_LOW,     "RTU_WDI_SIGNAL" },will request fail*/
  447.     { GPIO_TO_PIN(0, 1), GPIOF_OUT_INIT_HIGH, "RTU_PLC_BAK_IO1"}, 
  448.     { GPIO_TO_PIN(0, 2), GPIOF_OUT_INIT_LOW,     "RTU_CHG_EN" }, 
  449.     { GPIO_TO_PIN(0, 3), GPIOF_IN,         "RTU_CHG_PG" }, 
  450.     { GPIO_TO_PIN(0, 5), GPIOF_IN,         "RTU_USB_OC_OUT" }, 
  451.     { GPIO_TO_PIN(0, 6), GPIOF_OUT_INIT_LOW,     "RTU_RUN_IND_LED" },
  452.     { GPIO_TO_PIN(1, 10), GPIOF_IN,         "RTU_TSC_BUSY"},
  453.     { GPIO_TO_PIN(1, 11), GPIOF_IN,        "RTU_PENIRQn" },
  454.     { GPIO_TO_PIN(1, 12), GPIOF_OUT_INIT_LOW, "RTU_uP_Q26x_RESET" }, 
  455.     { GPIO_TO_PIN(1, 13), GPIOF_OUT_INIT_HIGH, "RTU_uP_GPRS_PWR_EN" },
  456.     { GPIO_TO_PIN(1, 14), GPIOF_OUT_INIT_HIGH, "RTU_uP_Q26x_ON/OFF" }, 
  457.     { GPIO_TO_PIN(2, 1), GPIOF_OUT_INIT_LOW, "RTU_PLC_Reset" },
  458.     { GPIO_TO_PIN(2, 2), GPIOF_OUT_INIT_LOW, "RTU_PLC_T_Reg" }, 
  459.     { GPIO_TO_PIN(2, 4), GPIOF_OUT_INIT_LOW, "RTU_PLC_BAK_IO2" },
  460.     { GPIO_TO_PIN(2, 5), GPIOF_OUT_INIT_LOW, "RTU_RS485_RE" }, 
  461.     { GPIO_TO_PIN(2, 15), GPIOF_OUT_INIT_HIGH, "RTU_CHPWR_CS" },
  462.     { GPIO_TO_PIN(3, 9), GPIOF_OUT_INIT_HIGH, "RTU_RS485_DE" }, 
  463.     { GPIO_TO_PIN(6, 1), GPIOF_OUT_INIT_HIGH, "RTU_uP_VPIF_CLKO3" },
  464.     { GPIO_TO_PIN(6, 9), GPIOF_IN,         "RTU_KEY_IN2" },
  465.     { GPIO_TO_PIN(6, 11), GPIOF_IN,        "RTU_ALARM_IN5" },
  466.     { GPIO_TO_PIN(6, 15), GPIOF_OUT_INIT_HIGH,"RTU_uP_RESETOUTn" },
  467. };

  468. static int gpio_open(struct inode *inode,struct file *file)
  469. {
  470.     printk(KERN_WARNING"gpio open success!\n");
  471.     return 0;
  472. }

  473. static int gpio_release(struct inode *inode, struct file *filp)
  474. {
  475.   printk (KERN_ALERT "Device gpio released\n");
  476.   return 0;
  477. }

  478. static int gpio_read(struct file*f,char *dst,size_t size,loff_t*offset)
  479. {
  480.     unsigned char num;
  481.     __copy_to_user(&num,dst,1);
  482. #ifdef DEBUG
  483.      printk("__copy_to_user:%d\n",num);
  484. #endif

  485.     return 0;
  486. }

  487. static int gpio_write(struct file*f,const char *src,size_t size,loff_t *offset)
  488. {
  489.      unsigned char num;
  490.      __copy_from_user(&num,src,1);
  491. #ifdef DEBUG
  492.      printk("__copy_from_user:%d\n",num);
  493. #endif
  494.      return 0;

  495. }

  496. static long gpio_ioctl(struct file *file,unsigned int cmd,unsigned long gpio)
  497. {
  498.     int i;
  499.     unsigned long gpio_num = (gpio/100)*16+gpio%100;
  500.     for (i = 0; i < ARRAY_SIZE(gpio_array); i++) {
  501.         if(gpio_array[i].gpio == gpio_num)
  502.             goto valid_gpio;
  503.     }
  504.     return -1;
  505.         
  506. valid_gpio:
  507.     switch(cmd)//cmd表示應用程序傳入的 GPIO 動作
  508.     {
  509.         case SET_OUTPUT_LOW://0
  510.         {
  511.             gpio_direction_output(gpio_num, 0);
  512.             break;
  513.         }
  514.         case SET_OUTPUT_HIGH://1
  515.         {
  516.             gpio_direction_output(gpio_num, 1);
  517.             break;
  518.         }
  519.         case GET_VALUE://2
  520.         {
  521.             return gpio_get_value(gpio_num);    
  522.         } 
  523.         case SET_INPUT://3
  524.         {
  525.             gpio_direction_input(gpio_num);
  526.             break;
  527.         }
  528.         default:
  529.         {
  530.             printk(KERN_EMERG "GPIO command mistake!!!\n");
  531.             break;
  532.         }
  533.     }
  534.     return 0;
  535. }
  536.         
  537. static const struct file_operations gpio_fops =
  538. {
  539.   .owner = THIS_MODULE,
  540.   .open = gpio_open,
  541.   .release = gpio_release,
  542.   .read = gpio_read,
  543.   .write = gpio_write,
  544.   .unlocked_ioctl = gpio_ioctl,
  545. };

  546. static int __init gpio_init(void) /*內核初始化會調用該函數*/
  547. {
  548.     int ret;
  549.     
  550.     ret = gpio_request_array(gpio_array, ARRAY_SIZE(gpio_array));
  551.     if (ret < 0) 
  552.     {
  553.         printk(KERN_EMERG "GPIO request failed\n");
  554.         goto request_failed; 
  555.     }
  556.     
  557.     dev_t my_dev_no;
  558.     struct cdev *gpio_cdev;
  559.     gpio_cdev = cdev_alloc();
  560.     if(gpio_cdev == NULL)
  561.     {
  562.         printk(KERN_EMERG "Cannot alloc cdev\n");
  563.         goto request_failed;
  564.     }
  565.     cdev_init(gpio_cdev,&gpio_fops);
  566.     gpio_cdev->owner=THIS_MODULE;
  567.     int result=alloc_chrdev_region(&my_dev_no,0,1,DEVICE_NAME); 
  568.     if(result < 0)
  569.     {
  570.         printk(KERN_EMERG "alloc_chrdev_region failed\n");
  571.         goto request_failed;
  572.     }
  573.     ret=cdev_add(gpio_cdev,my_dev_no,1); 
  574.     
  575.     
  576.   ret = register_chrdev(GPIO_MAJOR, DEVICE_NAME, &gpio_fops);//驅動字符設備
  577.      if(ret < 0)
  578.      {
  579.     printk(KERN_EMERG "GPIO register failed\n");
  580.     goto request_failed;
  581.      }
  582.     
  583.     //在sysfs文件系統下創建一個類
  584.   gpio_class = class_create(THIS_MODULE, DEVICE_NAME);
  585.   //device_create-->device_create_vargs-->device_register創建相應的sysfs文件(如dev文件),用於udev根據sysfs文件系統下的dev文件創建設備節點
  586.     device_create(gpio_class, NULL, MKDEV(GPIO_MAJOR, GPIO_MINOR), NULL, DEVICE_NAME);
  587.     return ret;
  588.     
  589. request_failed:
  590.     gpio_free_array(gpio_array, ARRAY_SIZE(gpio_array)); 
  591.     return ret;
  592. }

  593. static void __exit gpio_exit(void)
  594. {
  595.     device_destroy(gpio_class, MKDEV(GPIO_MAJOR, GPIO_MINOR));
  596.   class_unregister(gpio_class);
  597.   class_destroy(gpio_class);
  598.   unregister_chrdev(GPIO_MAJOR, DEVICE_NAME);
  599. }

  600. module_init(gpio_init);
  601. module_exit(gpio_exit);
  602. MODULE_LICENSE("GPL");
  603. MODULE_VERSION ("v2.0");
  604. MODULE_AUTHOR("wbl <>");
  605. MODULE_DESCRIPTION("OMAPL138 GPIO driver");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章