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

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

    • 分享

      Linux下regulator驅(qū)動程序分析

       老匹夫 2015-07-08

      原文地址::http://blog.csdn.net/lishuiwang/article/details/6130299

       

       

      //
      /*regulator 是驅(qū)動中電源管理的基礎(chǔ)設(shè)施。要先注冊到內(nèi)核中,然后使用這些電壓輸出的模塊get其regulator,在驅(qū)動中的init里,在適當時間中進行電壓電流的設(shè)置.
      與 gpio 差不多? 一樣是基礎(chǔ)設(shè)施?
      */

      //
      Linux 內(nèi)核的動態(tài)電壓和電流控制接口
      功耗已經(jīng)成為電子產(chǎn)品設(shè)計的首要考慮。
      //
      "LDO是 low dropout regulator,意為低壓差線性穩(wěn)壓器",是相對于傳統(tǒng)的線性穩(wěn)壓器來說的。傳統(tǒng)的線性穩(wěn)壓器,如78xx系列的芯片都要求輸入電壓要比輸出電壓高出 2v~3V以上,否則就不能正常工作。但是在一些情況下,這樣的條件顯然是太苛刻了,如5v轉(zhuǎn)3.3v,輸入與輸出的壓差只有1.7v,顯然是不滿足條件的。針對這種情況,才有了LDO類的電源轉(zhuǎn)換芯片。生產(chǎn)LDO芯片的公司很多,常見的有ALPHA, Linear(LT), Micrel, National semiconductor,TI等

      in:twl4030-poweroff.c
      pm_power_off: what it for???


      一種稱為校準器(regulator)的動態(tài)電壓和電流控制的方法,很有參考意義和實際使用價值。

      //***********************************************************************//
      1: 校準器的基本概念
      所謂校準器實際是在軟件控制下把輸入的電源調(diào)節(jié)精心輸出。

      2:Consumer 的API
      regulator = regulator_get(dev, “Vcc”);
      其中,dev 是設(shè)備“Vcc”一個字符串代表,校準器(regulator)然后返回一個指針,也是regulator_put(regulator)使用的。
      打開和關(guān)閉校準器(regulator)API如下。
      int regulator_enable(regulator);
      int regulator_disable(regulator);

      3: 電壓的API
      消費者可以申請?zhí)峁┙o它們的電壓,如下所示。
      int regulator_set_voltage(regulator, int min_uV, int max_uV);
      在改變電壓前要檢查約束,如下所示。
      regulator_set_voltage(regulator,100000,150000)
      電壓值下面的設(shè)置改變?nèi)缦滤尽?/div>
      int regulator_get_voltage)struct regulator *regulator);

      4:校準器的驅(qū)動和系統(tǒng)配置
      在實際使用校準器之前,需要按照下面的結(jié)構(gòu)寫校準器的驅(qū)動程序,然后注冊后通知給消費者使用。



      //************************* linux regulator 模型******************************************//

      static LIST_HEAD(regulator_list);     //整個regulator模型的所有regulator.
      static LIST_HEAD(regulator_map_list); //整個regulator模型的map

      struct regulator_consumer_supply : 用戶支持的接口映射。  supply -> device
      struct regulator_state: 用于表示 在整個系統(tǒng)的低功耗狀態(tài)下的設(shè)備狀態(tài)。
      struct regulation_constraints : 操作約束。
      struct regulator_init_data   校準器平臺初始化數(shù)據(jù)。
      struct regulator_dev
      向內(nèi)核注冊后 得到regulator設(shè)備結(jié)構(gòu)

      注冊:
      struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,struct device *dev, void *driver_data)
      反注冊:
      要使用注冊得到 regulator_dev:
      void regulator_unregister(struct regulator_dev *rdev)






      /* Regulator operating modes.**/
      #define REGULATOR_MODE_FAST 0x1 //電壓可以快速調(diào)
      #define REGULATOR_MODE_NORMAL 0x2 //一般模式
      #define REGULATOR_MODE_IDLE 0x4 //低load
      #define REGULATOR_MODE_STANDBY 0x8 //sleep/ standby 狀態(tài)下 低功耗

      例子:
      /* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
      static struct regulator_init_data zoom2_vsim = { //這個data被置于 對應的 platform_device 的data字段中。

      .constraints = {
      .min_uV = 1800000,
      .max_uV = 3000000,
      .valid_modes_mask= REGULATOR_MODE_NORMAL  /*這里設(shè)置*/
      | REGULATOR_MODE_STANDBY,
      .valid_ops_mask= REGULATOR_CHANGE_VOLTAGE /*這里設(shè)置這個regulator上可進行的操作。調(diào)電壓,模式可變,可以打開關(guān)閉*/
      | REGULATOR_CHANGE_MODE
      | REGULATOR_CHANGE_STATUS,
      },
      .num_consumer_supplies  = 1,
      .consumer_supplies      = &zoom2_vsim_supply,
      };
      // regulator 的初始化數(shù)據(jù)要放到  device 's  platform_data
      struct regulator_init_data *init_data = dev->platform_data;





      " 重點"
      //*************************** twl4030 regulator 的實現(xiàn)  ****************************//
      struct twlreg_info : 關(guān)聯(lián)到驅(qū)動與設(shè)備的數(shù)據(jù)。驅(qū)動的私有數(shù)據(jù),driver_data.
      struct twlreg_info {
      /* start of regulator's PM_RECEIVER control register bank */
      u8 base;

      /* twl4030 resource ID, for resource control state machine */
      u8 id;

      /* FIXED_LDO voltage */
      u8 deciV;

      /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
      u8 table_len;
      const u16*table;

      /* used by regulator core */
      struct regulator_descdesc;
      };
      //一個驅(qū)動 (platform_driver)對應所有的regulator, 每個regulator在內(nèi)核中表示為一個platform_device. 所以調(diào)用了許多次的probe
      //在probe中,從全局數(shù)組中取出自定義的數(shù)據(jù)結(jié)構(gòu): twlreg_info, 然后從platform_device中取出初始化數(shù)據(jù)(device's platform_data),然后就可以向內(nèi)核注冊一個 regulator(會返回一個regulator_dev:類)。
      "struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,struct device *dev, void *driver_data)"

      1: 


      1: 每個regulator 的  "twlreg_info" 被 存于 regulator_dev 的 device 's driver_data, twlreg_info中的 table 存支持的電壓值。
      2:兩種操作結(jié)構(gòu)"regulator_ops":twl4030fixed_ops(電壓固定),  twl4030ldo_ops(電壓可調(diào))
      3:傳入每個 ops中的操作函數(shù) 的參數(shù)是:  regulator_dev.
      4: 在  twl4030-core.c中,在添加 twl4030的 i2c_client時,添加了所有的 regulator 的 platform_device.

      5: 在驅(qū)動初始化注冊中,內(nèi)核會自動去匹配 bus上的所有符合的 platform_device(代表regulator,init_data 放于device's platform_data), 所以一個驅(qū)動就可以匹配到 bus上所有對應的 regulator.
      6: 每匹配一個 regulator的 platform_device時,就會從中,platform_device的 device 中的 platform_data 中得到 regulator的初始化數(shù)據(jù): regulator_init_data
      7: 取出初始化數(shù)據(jù)后, 設(shè)置一下. "設(shè)置,即是當設(shè)備支持一定的功能后,由驅(qū)動來控制時,要匹配驅(qū)動能做到的功能。that is 兩者 與(&) 一下"
        然后,從regulator模塊的全局數(shù)組"twl4030_regs[]" 中取出 twlreg_info 
      if (twl4030_regs[i].desc.id != pdev->id)
      continue;
      info = twl4030_regs + i;

      就可以向內(nèi)核注冊這個 regulator了:
      "rdev = regulator_register(&info->desc, &pdev->dev, info);"
      "注冊后返回一個 regulator_dev": 然后把這個rdev輸入到 platform_device 's device 's driver_data... 主要用于 remove中???
      regulator_dev:是一個類,其父是 本regulator的platform_device 's device.
      8: // regulator_ops 存入了 regulator_desc, 然后注冊時,desc 關(guān)聯(lián)到了 regulator_dev-> desc = desc.
      生成 regualator_dev, 設(shè)置數(shù)據(jù),注冊sysfs,然后: constraints, attribute, supply ,comsumer device.
      struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,struct device *dev, void *driver_data)


      9:
      另:
      大部分的regulator的platform_device生成如下:
      每個regulator設(shè)備注冊到內(nèi)核的時機是在 twl4030-core.c 中。
      把regulator的初始化數(shù)據(jù),放到新生成的platform_device  's device 's platform_data...
      然后注冊 platform_device 到內(nèi)核中。

      usb部分的 regulator生成如下:(這里明顯是由于OMAP不一定是有USB??,然后在其board-zoom2.c中,"沒有設(shè)置每個初始化數(shù)據(jù)"(包括:supply,constraints(min,max,mask)))
      而對于usb模塊的 regulator, 先生成對應的platform_device, 返回了platform_device->device, 然后利用這個device去形成多個: regulator_consumer_supply.dev = device.
      然后用這些 regulator_consumer_supply, 來做comsumer并生成 platform_device.注冊
      //************************** 使用regulator ***************************//
      regulator已經(jīng)向內(nèi)核模型注冊了,但如何使用呢,怎樣調(diào)節(jié)電壓??
      //注冊后,內(nèi)核中就已經(jīng)有對應的regulator對應的 supply consumer. 然后在驅(qū)動中任何地方調(diào)用接口即可:
      //regulator_get, regulator_enable, regulator_disable, regulator_set_voltage, regulator_get_voltage......

      1: 在twl4030-usb模塊中,會用到 usb對應的 reuglator,,   fixed_ops
      twl->usb3v1 = regulator_get(twl->dev, "usb3v1");
      regulator_enable(twl->usb3v1);
      regulator_disable(twl->usb1v5);
      2:
      regulator = regulator_get(dev, “Vcc”);
      其中,dev 是設(shè)備“Vcc”一個字符串代表,校準器(regulator)然后返回一個指針,也是regulator_put(regulator)使用的。
      打開和關(guān)閉校準器(regulator)API如下。
      int regulator_enable(regulator);
      int regulator_disable(regulator);

       電壓的API
      消費者可以申請?zhí)峁┙o它們的電壓,如下所示。
      int regulator_set_voltage(regulator, int min_uV, int max_uV);
      在改變電壓前要檢查約束,如下所示。
      regulator_set_voltage(regulator,100000,150000)


      //************************************************//






      /**
       * struct regulator_desc - Regulator descriptor
       *
       * Each regulator registered with the core is described with a structure of
       * this type.
       *
       * @name: Identifying name for the regulator.
       * @id: Numerical identifier for the regulator.
       * @n_voltages: Number of selectors available for ops.list_voltage().
       * @ops: Regulator operations table.
       * @irq: Interrupt number for the regulator.
       * @type: Indicates if the regulator is a voltage or current regulator.
       * @owner: Module providing the regulator, used for refcounting.
       */
      struct regulator_desc {
      const char *name;
      int id;
      unsigned n_voltages;
      struct regulator_ops *ops;
      int irq;
      enum regulator_type type;
      struct module *owner;
      };
      enum regulator_status {
      REGULATOR_STATUS_OFF,
      REGULATOR_STATUS_ON,
      REGULATOR_STATUS_ERROR,
      /* fast/normal/idle/standby are flavors of "on" */
      REGULATOR_STATUS_FAST,
      REGULATOR_STATUS_NORMAL,
      REGULATOR_STATUS_IDLE,
      REGULATOR_STATUS_STANDBY,
      };
      /*
       * struct regulator_dev
       *
       * Voltage / Current regulator class device. One for each regulator.
       */
      struct regulator_dev {
      struct regulator_desc *desc;
      int use_count;

      /* lists we belong to */
      struct list_head list; /* list of all regulators */
      struct list_head slist; /* list of supplied regulators */

      /* lists we own */
      struct list_head consumer_list; /* consumers we supply */
      struct list_head supply_list; /* regulators we supply */

      struct blocking_notifier_head notifier;
      struct mutex mutex; /* consumer lock */
      struct module *owner;
      struct device dev;
      struct regulation_constraints *constraints;
      struct regulator_dev *supply;/* for tree */

      void *reg_data;/* regulator_dev data */
      };
      /*
       * struct regulator
       *
       * One for each consumer device.
       */
      struct regulator {
      struct device *dev;
      struct list_head list;
      int uA_load;
      int min_uV;
      int max_uV;
      int enabled; /* count of client enables */
      char *supply_name;
      struct device_attribute dev_attr;
      struct regulator_dev *rdev;
      };
      /*
       * struct regulator_map
       *
       * Used to provide symbolic supply names to devices.
       */
      struct regulator_map {
      struct list_head list;
      struct device *dev;
      const char *supply;
      struct regulator_dev *regulator;
      };
      /**
       * struct regulator_state - regulator state during low power syatem states
       *
       * This describes a regulators state during a system wide low power state.
       *
       * @uV: Operating voltage during suspend.
       * @mode: Operating mode during suspend.
       * @enabled: Enabled during suspend.
       */
      struct regulator_state {
      int uV; /* suspend voltage */
      unsigned int mode; /* suspend regulator operating mode */
      int enabled; /* is regulator enabled in this suspend state */
      };

      /**
       * struct regulation_constraints - regulator operating constraints.
       *
       * This struct describes regulator and board/machine specific constraints.
       *
       * @name: Descriptive name for the constraints, used for display purposes.
       *
       * @min_uV: Smallest voltage consumers may set.
       * @max_uV: Largest voltage consumers may set.
       *
       * @min_uA: Smallest consumers consumers may set.
       * @max_uA: Largest current consumers may set.
       *
       * @valid_modes_mask: Mask of modes which may be configured by consumers.
       * @valid_ops_mask: Operations which may be performed by consumers.
       *
       * @always_on: Set if the regulator should never be disabled.
       * @boot_on: Set if the regulator is enabled when the system is initially
       *           started.
       * @apply_uV: Apply the voltage constraint when initialising.
       *
       * @input_uV: Input voltage for regulator when supplied by another regulator.
       *
       * @state_disk: State for regulator when system is suspended in disk mode.
       * @state_mem: State for regulator when system is suspended in mem mode.
       * @state_standby: State for regulator when system is suspended in standby
       *                 mode.
       * @initial_state: Suspend state to set by default.
       */
      struct regulation_constraints {

      char *name;

      /* voltage output range (inclusive) - for voltage control */
      int min_uV;
      int max_uV;

      /* current output range (inclusive) - for current control */
      int min_uA;
      int max_uA;

      /* valid regulator operating modes for this machine */
      unsigned int valid_modes_mask;

      /* valid operations for regulator on this machine */
      unsigned int valid_ops_mask;

      /* regulator input voltage - only if supply is another regulator */
      int input_uV;

      /* regulator suspend states for global PMIC STANDBY/HIBERNATE */
      struct regulator_state state_disk;
      struct regulator_state state_mem;
      struct regulator_state state_standby;
      suspend_state_t initial_state; /* suspend state to set at init */

      /* constriant flags */
      unsigned always_on:1;/* regulator never off when system is on */
      unsigned boot_on:1;/* bootloader/firmware enabled regulator */
      unsigned apply_uV:1;/* apply uV constraint iff min == max */
      };

      /**
       * struct regulator_consumer_supply - supply -> device mapping
       *
       * This maps a supply name to a device.
       *
       * @dev: Device structure for the consumer.
       * @supply: Name for the supply.
       */
      struct regulator_consumer_supply {
      struct device *dev;/* consumer */
      const char *supply;/* consumer supply - e.g. "vcc" */
      };
      /**
       * struct regulator_desc - Regulator descriptor
       *
       * Each regulator registered with the core is described with a structure of
       * this type.
       *
       * @name: Identifying name for the regulator.
       * @id: Numerical identifier for the regulator.
       * @n_voltages: Number of selectors available for ops.list_voltage().
       * @ops: Regulator operations table.
       * @irq: Interrupt number for the regulator.
       * @type: Indicates if the regulator is a voltage or current regulator.
       * @owner: Module providing the regulator, used for refcounting.
       */
      struct regulator_desc {
      const char *name;
      int id;
      unsigned n_voltages;
      struct regulator_ops *ops;
      int irq;
      enum regulator_type type;
      struct module *owner;
      };

      /**
       * struct regulator_init_data - regulator platform initialisation data.
       *
       * Initialisation constraints, our supply and consumers supplies.
       *
       * @supply_regulator_dev: Parent regulator (if any).
       *
       * @constraints: Constraints.  These must be specified for the regulator to
       *               be usable.
       * @num_consumer_supplies: Number of consumer device supplies.
       * @consumer_supplies: Consumer device supply configuration.
       *
       * @regulator_init: Callback invoked when the regulator has been registered.
       * @driver_data: Data passed to regulator_init.
       */
      struct regulator_init_data {
      struct device *supply_regulator_dev; /* or NULL for LINE */

      struct regulation_constraints constraints;

      int num_consumer_supplies;
      struct regulator_consumer_supply *consumer_supplies;

      /* optional regulator machine specific init */
      int (*regulator_init)(void *driver_data);
      void *driver_data;/* core does not touch this */
      };

      /*
       * Regulator operation constraint flags. These flags are used to enable
       * certain regulator operations and can be OR'ed together.
       *
       * VOLTAGE:  Regulator output voltage can be changed by software on this
       *           board/machine.
       * CURRENT:  Regulator output current can be changed by software on this
       *           board/machine.
       * MODE:     Regulator operating mode can be changed by software on this
       *           board/machine.
       * STATUS:   Regulator can be enabled and disabled.
       * DRMS:     Dynamic Regulator Mode Switching is enabled for this regulator.
       */

      #define REGULATOR_CHANGE_VOLTAGE 0x1
      #define REGULATOR_CHANGE_CURRENT 0x2
      #define REGULATOR_CHANGE_MODE 0x4
      #define REGULATOR_CHANGE_STATUS 0x8
      #define REGULATOR_CHANGE_DRMS 0x10

      /*
       * Regulator operating modes.
       *
       * Regulators can run in a variety of different operating modes depending on
       * output load. This allows further system power savings by selecting the
       * best (and most efficient) regulator mode for a desired load.
       *
       * Most drivers will only care about NORMAL. The modes below are generic and
       * will probably not match the naming convention of your regulator data sheet
       * but should match the use cases in the datasheet.
       *
       * In order of power efficiency (least efficient at top).
       *
       *  Mode       Description
       *  FAST       Regulator can handle fast changes in it's load.
       *             e.g. useful in CPU voltage & frequency scaling where
       *             load can quickly increase with CPU frequency increases.
       *
       *  NORMAL     Normal regulator power supply mode. Most drivers will
       *             use this mode.
       *
       *  IDLE       Regulator runs in a more efficient mode for light
       *             loads. Can be used for devices that have a low power
       *             requirement during periods of inactivity. This mode
       *             may be more noisy than NORMAL and may not be able
       *             to handle fast load switching.
       *
       *  STANDBY    Regulator runs in the most efficient mode for very
       *             light loads. Can be used by devices when they are
       *             in a sleep/standby state. This mode is likely to be
       *             the most noisy and may not be able to handle fast load
       *             switching.
       *
       * NOTE: Most regulators will only support a subset of these modes. Some
       * will only just support NORMAL.
       *
       * These modes can be OR'ed together to make up a mask of valid register modes.
       */

      #define REGULATOR_MODE_FAST 0x1
      #define REGULATOR_MODE_NORMAL 0x2
      #define REGULATOR_MODE_IDLE 0x4
      #define REGULATOR_MODE_STANDBY 0x8

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多