乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Linux Regulator Framework(1)

       老匹夫 2015-07-08

      1. 前言

      Regulator,中文名翻譯為“穩(wěn)定器”,在電子工程中,是voltage regulator(穩(wěn)壓器)或者current regulator(穩(wěn)流器)的簡稱,指可以自動維持恒定電壓(或電流)的裝置。

      voltage regulator最早應(yīng)用于功放電路中,主要用于濾除電源紋波(100或者120Hz)和噪聲,以及避免“輸出電壓隨負(fù)載的變化而變化”的情況。后來,隨著IC級別的regulator的出現(xiàn)(便宜了),voltage regulator幾乎存在于任何的電子設(shè)備中。例如我們常見的嵌入式設(shè)備中,基本上每一種電壓,都是經(jīng)過regulator輸出的。

      相比較voltage regulator的廣泛使用,很少見到current regulator的應(yīng)用場景(相信大多數(shù)的嵌入式工程師都沒有接觸過)。它一般存在于電流源中,除此之外,它廣泛存在于近年來新興的LED照明設(shè)備中。current regulator在LED設(shè)備中的作用主要有兩個:避免驅(qū)動電流超出最大額定值,影響其可靠性;獲得預(yù)期的亮度要求,并保證各個LED亮度、色度的一致性。

      雖然原理比較復(fù)雜,但從設(shè)備驅(qū)動的角度看,regulator的控制應(yīng)該很簡單,就是輸出的enable/disable、輸出電壓或電流的大小的控制。那么,linux kernel的regulator framework到底要做什么呢?這就是本文的目的:弄清楚regulator framework背后思考,并總結(jié)出其軟件架構(gòu)(和common clock framework類似,consumer/provider/core)。

      注1:有關(guān)regulator的描述,參考自“http://sound./articles/vi-regulators.html”。

      注2:kernel中有關(guān)regulator framework的介紹寫的相當(dāng)好(Documentation\power\regulator\*),因此本文大部分內(nèi)容會參考這些文件。

      2. 背后的思考

      Linux regulator framework的目的很直接:提供標(biāo)準(zhǔn)的內(nèi)核接口,控制系統(tǒng)的voltage/current regulators,并提供相應(yīng)的機(jī)制,在系統(tǒng)運(yùn)行的過程中,動態(tài)改變regulators的輸出,以達(dá)到省電的目的。

      看似簡單的背后,有些因素不得不考慮。

      1)最重要的,就是安全性:

      在一個系統(tǒng)中,錯誤的regulator配置是非常危險的,嚴(yán)重時可以損毀硬件。而無論是regulator的使用者(consumer),還是regulator提供者(provider,即regulator driver),都不一定有足夠的知識和能力,避免危險發(fā)生。因此必須從machine的角度,小心的設(shè)計(jì)regulator的輸出限值(這一般由產(chǎn)品設(shè)計(jì)、硬件設(shè)計(jì)決定的)。

      同時,一旦設(shè)計(jì)確定下來之后,這些限制必須保存在一些相對固定的地方,不能輕易地被軟件修改。

      最后,所有的regulator操作,必須是小心的、在可允許范圍內(nèi)的。

      2)系統(tǒng)中大部分的設(shè)備,都沒有動態(tài)更改regulator配置的需求,甚至連enable/disable都懶得關(guān)心的,framework需要考慮這種情況,盡量簡化接口。

      3)會存在同一個regulator向多個設(shè)備提供power的情況,如果這些設(shè)備的需求不同怎么辦?

      4)regulator之間是否可以級聯(lián)?如果可以,怎么處理?

      這些思考最終都會反映到軟件設(shè)計(jì)上,具體可參考如下的軟件架構(gòu)。

      3. 軟件架構(gòu)

      基于上面的思考,regulator framework的軟件架構(gòu)如下:

      regulator framework

      除了machine之外,基本上和common clock framework的consumer/provider框架類似。

      3.1 machine

      machine的主要功能,是使用軟件語言(struct regulator_init_data),靜態(tài)的描述regulator在板級的物理現(xiàn)狀,包括:

      1)前級regulator(即該regulator的輸入是另一個regulator的輸出,簡稱supply regulator)和后級regulator(即該regulator的輸出是其它regulator的輸入,簡稱consumer regulator)。

      這主要用于描述regulator在板級的級聯(lián)關(guān)系,需要留意的是,它和clock不同,這種級聯(lián)關(guān)系是非常確定的,以至于需要使用靜態(tài)的方式描述,而不是像clock那樣,在注冊的時候動態(tài)指定并形成。

      2)該regulator的物理限制(struct regulation_constraints),包括:

      輸出電壓的最大值和最小值(voltage regulator);
      輸出電流的最大值和最小值(current regulator);
      允許的操作(修改電壓值、修改電流限制、enable、disable等等);
      輸入電壓是多少(當(dāng)輸入是另一個regulator時);
      是否不允許關(guān)閉(always_on);
      是否啟動時就要打開(always_on);
      等等。

      這些限制關(guān)系到系統(tǒng)安全,因此必須小心配置。配置完成后,在系統(tǒng)運(yùn)行的整個過程中,它們都不會再改變了。

      3.2 driver

      driver模塊的功能,是從regulator driver的角度,抽象regulator設(shè)備。

      1)使用struct regulator_desc描述regulator的靜態(tài)信息,包括:名字、supply regulator的名字、中斷號、操作函數(shù)集(struct regulator_ops)、使用regmap時相應(yīng)的寄存器即bitmap等等。

      2)使用struct regulator_config,描述regulator的動態(tài)信息(所謂的動態(tài)信息,體現(xiàn)在struct regulator_config變量都是局部變量,因此不會永久保存),包括struct regulator_init_data指針、設(shè)備指針、enable gpio等等。

      3)提供regulator的注冊接口(regulator_register/devm_regulator_register),該接口接受描述該regulator的兩個變量的指針:struct regulator_desc和struct regulator_config,并分配一個新的數(shù)據(jù)結(jié)構(gòu)(struct regulator_dev,從設(shè)備的角度描述regulator),并把靜態(tài)指針(struct regulator_desc)和動態(tài)指針(struct regulator_config)提供的信息保存在其中。

      4)最后,regulator driver將以為struct regulator_dev指針為對象,對regulator進(jìn)行后續(xù)的操作。

      3.3 consumer

      consumer的功能,是從regulator consumer的角度,抽象regulator設(shè)備(struct regulator),并提供regulator操作相關(guān)的接口。包括:

      3.4 core

      core負(fù)責(zé)上述邏輯的具體實(shí)現(xiàn),并以sysfs的形式,向用戶空間提供接口。

      4. 接口匯整

      本節(jié)對regulator framework向各個層次提供的API做一個匯整,具體細(xì)節(jié)會在后續(xù)的文章中詳細(xì)描述。

      4.1 consumer模塊向內(nèi)核空間consumer提供的接口

      regulator framework向內(nèi)核空間consumer提供的接口位于“include/linux/regulator/consumer.h”中,包括regulator的獲取、使能、修改等接口,如下。

      1)struct regulator

      struct regulator結(jié)構(gòu)用于從consumer的角度抽象一個regulator,consumer不需要關(guān)心該結(jié)構(gòu)的細(xì)節(jié),當(dāng)作一個句柄使用即可(類似struct clk)。

      2)regulator的get/put接口

         1: struct regulator *__must_check regulator_get(struct device *dev,
         2:                                              const char *id);
         3: struct regulator *__must_check devm_regulator_get(struct device *dev,
         4:                                              const char *id);
         5: struct regulator *__must_check regulator_get_exclusive(struct device *dev,
         6:                                                        const char *id);
         7: struct regulator *__must_check devm_regulator_get_exclusive(struct device *dev,
         8:                                                         const char *id);
         9: struct regulator *__must_check regulator_get_optional(struct device *dev,
        10:                                                       const char *id);
        11: struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
        12:                                                            const char *id);
        13: void regulator_put(struct regulator *regulator);
        14: void devm_regulator_put(struct regulator *regulator);

      根據(jù)是否獨(dú)占regulator、是否可以多次get,regulator get接口分為三類:

      正常的get,非獨(dú)占、可以重復(fù)get,regulator_get/devm_regulator_get;

      獨(dú)占性質(zhì)的get,獨(dú)占、不可重復(fù)get,regulator_get_exclusive/devm_regulator_get_exclusive;

      optional的get,非獨(dú)占、不可重復(fù)get,regulator_get_optional/devm_regulator_get_optional。

      get接口的參數(shù)為id,會在下一篇文章中詳細(xì)介紹。

      3)supply alias相關(guān)的接口

         1: int regulator_register_supply_alias(struct device *dev, const char *id,
         2:                                     struct device *alias_dev,
         3:                                     const char *alias_id);
         4: void regulator_unregister_supply_alias(struct device *dev, const char *id);
         5:  
         6: int devm_regulator_register_supply_alias(struct device *dev, const char *id,
         7:                                          struct device *alias_dev,
         8:                                          const char *alias_id);
         9: void devm_regulator_unregister_supply_alias(struct device *dev,
        10:                                             const char *id);
        11:  
        12: int devm_regulator_bulk_register_supply_alias(struct device *dev,
        13:                                               const char *const *id,
        14:                                               struct device *alias_dev,
        15:                                               const char *const *alias_id,
        16:                                               int num_id);
        17: void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
        18:                                                  const char *const *id,
        19:                                                  int num_id);

      具體意義請參考下一篇文章。

      4)regulator的控制、狀態(tài)獲取接口

         1: int __must_check regulator_enable(struct regulator *regulator);
         2: int regulator_disable(struct regulator *regulator);
         3: int regulator_force_disable(struct regulator *regulator);
         4: int regulator_is_enabled(struct regulator *regulator);
         5: int regulator_disable_deferred(struct regulator *regulator, int ms);
         6:  
         7: int regulator_can_change_voltage(struct regulator *regulator);
         8: int regulator_count_voltages(struct regulator *regulator);
         9: int regulator_list_voltage(struct regulator *regulator, unsigned selector);
        10: int regulator_is_supported_voltage(struct regulator *regulator,
        11:                                    int min_uV, int max_uV);
        12: unsigned int regulator_get_linear_step(struct regulator *regulator);
        13: int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
        14: int regulator_set_voltage_time(struct regulator *regulator,
        15:                                int old_uV, int new_uV);
        16: int regulator_get_voltage(struct regulator *regulator);
        17: int regulator_sync_voltage(struct regulator *regulator);
        18: int regulator_set_current_limit(struct regulator *regulator,
        19:                                int min_uA, int max_uA);
        20: int regulator_get_current_limit(struct regulator *regulator);
        21:  
        22: int regulator_set_mode(struct regulator *regulator, unsigned int mode);
        23: unsigned int regulator_get_mode(struct regulator *regulator);
        24: int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
        25:  
        26: int regulator_allow_bypass(struct regulator *regulator, bool allow);
        27:  
        28: struct regmap *regulator_get_regmap(struct regulator *regulator);
        29: int regulator_get_hardware_vsel_register(struct regulator *regulator,
        30:                                          unsigned *vsel_reg,
        31:                                          unsigned *vsel_mask);
        32: int regulator_list_hardware_vsel(struct regulator *regulator,
        33:                                  unsigned selector);
        34:  

      控制有關(guān)的包括enable、disable、電壓設(shè)置、電流設(shè)置、mode設(shè)置等,其中disable又包括normal、強(qiáng)制、退出等類型。

      狀態(tài)獲取包括:是否enable;是否可以改變電壓;支持的電壓列表;是否支持指定范圍的電壓;當(dāng)前輸出電壓;當(dāng)前電流限制;當(dāng)前mode;等等。

      更為詳細(xì)的描述,請參考下一篇文章。

      5)bulk型的操作(一次操作多個regulator)

         1: int regulator_bulk_register_supply_alias(struct device *dev,
         2:                                          const char *const *id,
         3:                                          struct device *alias_dev,
         4:                                          const char *const *alias_id,
         5:                                          int num_id);
         6: void regulator_bulk_unregister_supply_alias(struct device *dev,
         7:                                             const char * const *id, int num_id);
         8: int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
         9:                                     struct regulator_bulk_data *consumers);
        10: int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
        11:                                          struct regulator_bulk_data *consumers);
        12: int __must_check regulator_bulk_enable(int num_consumers,
        13:                                        struct regulator_bulk_data *consumers);
        14: int regulator_bulk_disable(int num_consumers,
        15:                            struct regulator_bulk_data *consumers);
        16: int regulator_bulk_force_disable(int num_consumers,
        17:                            struct regulator_bulk_data *consumers);
        18: void regulator_bulk_free(int num_consumers,
        19:                          struct regulator_bulk_data *consumers);

      6)notifier相關(guān)的接口

         1: int regulator_register_notifier(struct regulator *regulator,
         2:                               struct notifier_block *nb);
         3: int regulator_unregister_notifier(struct regulator *regulator,
         4:                                 struct notifier_block *nb);

      如果consumer關(guān)心某個regulator的狀態(tài)變化,可以通過上面接口注冊一個notifier。

      7)其它接口

         1: /* driver data - core doesn't touch */
         2: void *regulator_get_drvdata(struct regulator *regulator);
         3: void regulator_set_drvdata(struct regulator *regulator, void *data);

      用于設(shè)置和獲取driver的私有數(shù)據(jù)。

      4.2 consumer模塊向用戶空間consumer提供的接口

      用戶空間程序可以通過sysfs接口,使用regulator,就像內(nèi)核空間consumer一樣。這些接口由“drivers/regulator/userspace-consumer.c”實(shí)現(xiàn),主要包括:

      sysfs目錄位置:/sys/devices/platform/reg-userspace-consumer。

      name,讀取可以獲取該regulator的名字。

      state,讀取,可以獲取該regulator的狀態(tài)(enabled/disabled);寫入可以改變regulator的狀態(tài)(enabled或者1使能,disabled或者0禁止)。

      4.3 machine模塊向regulator driver提供的接口

      machine模塊主要提供struct regulator_init_data、struct regulation_constraints constraints等數(shù)據(jù)結(jié)構(gòu),用于描述板級的regulator配置,具體可參考3.1中介紹。

      4.4 driver模塊向regulator driver提供的接口

      regulator framework向regulator driver提供的接口位于“include/linux/regulator/driver.h”中,包括數(shù)據(jù)結(jié)構(gòu)抽象、regulator注冊等。

      1)struct regulator_desc、struct regulator_config和struct regulator_dev

      見3.2中的介紹。

      2)regulator設(shè)備的注冊接口

         1: struct regulator_dev *
         2: regulator_register(const struct regulator_desc *regulator_desc,
         3:                    const struct regulator_config *config);
         4: struct regulator_dev *
         5: devm_regulator_register(struct device *dev,
         6:                         const struct regulator_desc *regulator_desc,
         7:                         const struct regulator_config *config);
         8: void regulator_unregister(struct regulator_dev *rdev);
         9: void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev);

      見3.2中的介紹。

      3)其它接口,請參考后續(xù)的文章。

      4.5 core模塊向用戶空間提供的sysfs接口

      regulator設(shè)備在內(nèi)核中是以regulator class的形式存在的,regulator core通過class->dev_groups的方式,提供了一些默認(rèn)的attribute,包括:

      name,讀取可以獲取該regulator的名字;

      num_users,讀取可獲取regulator的使用者數(shù)目;

      type,讀取可以獲取該regulator的類型(voltage或者current)。

      另外,如果regulator driver需要提供更多的attribute(如狀態(tài)、最大/最小電壓等等),可以調(diào)用add_regulator_attributes接口,主動添加。

      原創(chuàng)文章,轉(zhuǎn)發(fā)請注明出處。蝸窩科技www.。

      標(biāo)簽: Linux framework regulator 軟件架構(gòu)

      評論:

      wzzazc
      2015-05-03 16:19
      mark ^_^
      haichunzhao
      2015-04-01 16:11
      mark
      tigger
      2015-03-24 11:26
      hi wowo
      我有個問題想請教,我的理解,arm的電,都是靠PMIC給供的。那PMIC的電,跟regulator是怎么對應(yīng)上的呢??物理上肯定是有連線的。
      或者說,比如一個regulator是vdd1v8,那這個肯定是PMIC那邊的1V8供過來的?還是隨便一個regulator,只是軟件寫成1v8,然后PMIC就會出這個電?
      wowo
      2015-03-24 14:38
      @tigger:tigger,我不是很明白您的意思。PMIC是一個硬件設(shè)備,regulator也是硬件設(shè)備。只不過,大多數(shù)時候,regulator集成在PMIC的內(nèi)部了,因此會出現(xiàn);類似下面的設(shè)備拓?fù)浣Y(jié)構(gòu)(以DTS的形式):
      PMICx {
              avdd0 {
              };

              vcc1_8 {
              };

              ...
      };
      driver的編寫形式為:
      pmic_probe {
              ...
              regulator_register(1...);
              regulator_register(2...);
              ...
      };
      因此regulator的控制(包括enable、disable、modify value等),還是需要依賴parent driver(PMIC)的實(shí)現(xiàn)的。
      tigger
      2015-03-24 15:18
      @wowo:ok 我明白了,我以為regulator是ARM CPU這邊的器件了。

      發(fā)表評論:

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多