Documentation-filesystems/sysfs

sysfs是一个基于RAM的文件系统,用于将内核数据结构及其属性导出到用户空间。它与kobject基础设施紧密相关,允许在用户空间中访问内核对象。sysfs提供了一种通过属性进行读写内核属性的方法,并支持子系统自定义属性结构和回调函数。

Chinese translated version of Documentation/CodingStyle

If you have any comment or update to the content, please post to LKML directly.
However, if you have problem communicating in English you can also ask the
Chinese maintainer for help. Contact the Chinese maintainer, if this
translation is outdated or there is problem with translation.

Chinese maintainer: ytian
---------------------------------------------------------------------
Documentation/CodingStyle的中文翻译

如果想评论或更新本文的内容,请直接发信到LKML。如果你使用英文交流有困难的话,也可
以向中文版维护者求助。如果本翻译更新不及时或者翻译存在问题,请联系中文版维护者。

中文版维护者:田雨
中文版翻译者:田雨
中文版校译者:田雨
 
 
 
以下为正文


sysfs - _The_ filesystem for exporting kernel objects.
             文件系统内核对象的出口。

Patrick Mochel <mochel@osdl.org>
Mike Murphy <mamurph@cs.clemson.edu>

Revised:    16 August 2011修订:2011年8月16日
Original:   10 January 2003初版:2003年1月10日


What it is:它是什么
~~~~~~~~~~~

sysfs is a ram-based filesystem initially based on ramfs. It provides
a means to export kernel data structures, their attributes, and the
linkages between them to userspace.
sysfs是一个基于ram的文件系统最初基于ramfs。它提供了

一个意味着出口内核数据结构,它们的属性,和

它们之间联系到用户空间。

 


sysfs is tied inherently to the kobject infrastructure. Please read
Documentation/kobject.txt for more information concerning the kobject
interface.
sysfs是天生的kobject挂钩基础设施。请阅读

文档/ kobject。为更多的信息关于三kobject

接口。

 

Using sysfs
~~使用sysfs~~~~~~~~~

sysfs is always compiled in if CONFIG_SYSFS is defined. You can access
it by doing:
sysfsis总是在编译如果CONFIG_SYSFS被定义。你可以访问

它,通过做:

    mount -t sysfs sysfs /sys


Directory Creation创建目录

~~~~~~~~~~~~~~~~~~

For every kobject that is registered with the system, a directory is
created for it in sysfs. That directory is created as a subdirectory
of the kobject's parent, expressing internal object hierarchies to
userspace. Top-level directories in sysfs represent the common
ancestors of object hierarchies; i.e. the subsystems the objects
belong to.
对于每个kobject来说,是在系统中注册,一个目录

为它在系统文件中被创建。该目录是创建一个子目录

的kobject母公司内部对象层次来表达

用户空间。顶级目录sysfs代表共同

祖先的对象层次结构,即属于的子系统对象。

 

Sysfs internally stores a pointer to the kobject that implements a
directory in the sysfs_dirent object associated with the directory. In
the past this kobject pointer has been used by sysfs to do reference
counting directly on the kobject whenever the file is opened or closed.
With the current sysfs implementation the kobject reference count is
only modified directly by the function sysfs_schedule_callback().
Sysfs内部存储的指针,它实现了一个kobject

目录在sysfs_dirent与对象关联的目录。在
过去这个kobject的指针只要文件被打开或关闭已被用于sysfs中做参考
直接计数的kobject。
随着当前的sysfs实现kobject的引用计数
只有直接由的功能sysfs_schedule_callback()修改

. .

 


Attributes
~~属性~~~~~~~~

Attributes can be exported for kobjects in the form of regular files in
the filesystem. Sysfs forwards file I/O operations to methods defined
for the attributes, providing a means to read and write kernel
attributes.

文件系统中属性可以被导出为kobjects常规文件的形式。Sysfs转发文件I / O操作的方法定义

的属性,提供一个意味着读和写内核

属性。


Attributes should be ASCII text files, preferably with only one value
per file. It is noted that it may not be efficient to contain only one
value per file, so it is socially acceptable to express an array of
values of the same type.
ttributes应该ASCII文本文件,最好是只有一个值

每个文件。t是指出,它可能不是有效的,只包含一个

值在每个文件,所以它是社会可接受的表达一组

相同类型的值。


Mixing types, expressing multiple lines of data, and doing fancy
formatting of data is heavily frowned upon. Doing these things may get
you publicly humiliated and your code rewritten without notice.
混合类型,表达多行数据,和做花式

格式化的数据严重不满。做这些事情可以得到

你公开羞辱和代码重写,恕不另行通知。

 

An attribute definition is simply:

struct attribute {
        char                    * name;
        struct module  *owner;
        umode_t                 mode;
};


int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);


A bare attribute contains no means to read or write the value of the
attribute. Subsystems are encouraged to define their own attribute
structure and wrapper functions for adding and removing attributes for
a specific object type.
一个裸属性包含不读或写的价值

属性.子系统是鼓励去定义自己的属性

结构和包装器函数来添加和删除属性

一个特定的对象类型。
 .

For example, the driver model defines struct device_attribute like:
例如,驾驶员模型定义结构体设备属性像

struct device_attribute {
 struct attribute attr;
 ssize_t (*show)(struct device *dev, struct device_attribute *attr,
   char *buf);
 ssize_t (*store)(struct device *dev, struct device_attribute *attr,
    const char *buf, size_t count);
};

int device_create_file(struct device *, const struct device_attribute *);
void device_remove_file(struct device *, const struct device_attribute *);

It also defines this helper for defining device attributes:

#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

For example, declaring

static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);

is equivalent to doing:

static struct device_attribute dev_attr_foo = {
       .attr = {
  .name = "foo",
  .mode = S_IWUSR | S_IRUGO,
  .show = show_foo,
  .store = store_foo,
 },
};


子系统具体的回调
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When a subsystem defines a new attribute type, it must implement a
set of sysfs operations for forwarding read and write calls to the
show and store methods of the attribute owners.
当一个子系统定义了一个新的属性类型,必须执行

组sysfs操作转发读和写调用

显示和存储方法的属性所有者。

struct sysfs_ops {
        ssize_t (*show)(struct kobject *, struct attribute *, char *);
        ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
};

[ Subsystems should have already defined a struct kobj_type as a
descriptor for this type, which is where the sysfs_ops pointer is
stored. See the kobject documentation for more information. ]
子系统应该已经定义了一个struct kobj_type作为

对于这种类型的描述符,这是sysfs行动指针

存储。看到kobject文档了解更多信息。


When a file is read or written, sysfs calls the appropriate method
for the type. The method then translates the generic struct kobject
and struct attribute pointers to the appropriate pointer types, and
calls the associated methods.
当一个文件被读取或写入,sysfs调用适当的方法

的类型。该方法然后翻译kobject通用结构

和结构属性指向相应的指针类型,和

调用相关方法。

 

To illustrate:说明:


#define to_dev(obj) container_of(obj, struct device, kobj)
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)

static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
                             char *buf)
{
        struct device_attribute *dev_attr = to_dev_attr(attr);
        struct device *dev = to_dev(kobj);
        ssize_t ret = -EIO;

        if (dev_attr->show)
                ret = dev_attr->show(dev, dev_attr, buf);
        if (ret >= (ssize_t)PAGE_SIZE) {
                print_symbol("dev_attr_show: %s returned bad count\n",
                                (unsigned long)dev_attr->show);
        }
        return ret;
}

 

读/写属性数据

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To read or write attributes, show() or store() methods must be
specified when declaring the attribute. The method types should be as
simple as those defined for device attributes:
o读写属性,显示()或存储()方法必须

当声明指定的属性。该方法类型应该是

这些定义的简单设备属性:

ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
                 const char *buf, size_t count);

IOW, they should take only an object, an attribute, and a buffer as parameters.

也就是说,他们应该只以一个对象,一个属性和一个缓冲作为参数。


sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the
method. Sysfs will call the method exactly once for each read or
write. This forces the following behavior on the method
implementations:

分配一个缓冲区大小的sysfs(页大小),并将其传递给

法。Sysfs将调用该方法为每个读或执行一次

写。这迫使以下行为的方法

实现:

- On read(2), the show() method should fill the entire buffer.
  Recall that an attribute should only be exporting one value, or an
  array of similar values, so this shouldn't be that expensive.

在阅读(2),显示()方法应该填满整个缓冲区。

回想一下,一个属性只能出口一个值或一个

一系列类似的值,所以这并不贵。

  This allows userspace to do partial reads and forward seeks
  arbitrarily over the entire file at will. If userspace seeks back to
  zero or does a pread(2) with an offset of '0' the show() method will
  be called again, rearmed, to fill the buffer.
他允许用户空间做部分读取和转发寻求

任意在整个文件将。如果用户空间寻求回

零还是一个帖子(2)使用一个偏移的' 0 '这个节目()方法将

又被称为,rearmed,填满缓冲区. .

- On write(2), sysfs expects the entire buffer to be passed during the
  first write. Sysfs then passes the entire buffer to the store()
  method.
  在写(2),sysfs预计整个缓冲区中通过

第一次写。然后通过Sysfs整个缓冲区到商店()

法。

  When writing sysfs files, userspace processes should first read the
  entire file, modify the values it wishes to change, then write the
  entire buffer back.
当编写sysfs文件,用户空间进程应该首先阅读

整个文件,修改值它希望改变,然后编写

整个缓冲区回来。

  Attribute method implementations should operate on an identical
  buffer when reading and writing values.
属性方法实现应该操作相同

缓冲当阅读和写作值。

Other notes:其他的注释:


- Writing causes the show() method to be rearmed regardless of current
  file position.
写作使show()方法rearmed不管电流

文件位置。

- show() methods should return the number of bytes printed into the
  buffer. This is the return value of scnprintf().
show()方法应该返回的字节数的印刷

缓冲。这是scnprintf()的返回值。

- show() should always use scnprintf().
show()应该总是使用scnprintf()

- store() should return the number of bytes used from the buffer. If the
  entire buffer has been used, just return the count argument.
商店()应该返回的字节数从缓冲区使用。如果

整个缓冲区已经被使用,仅返回计数参数。

- show() or store() can always return errors. If a bad value comes
  through, be sure to return an error.
show()或()可以存储总是返回错误。如果一个坏值来

通过,一定要返回一个错误. .

- The object passed to the methods will be pinned in memory via sysfs
  referencing counting its embedded object. However, the physical
  entity (e.g. device) the object represents may not be present. Be
  sure to have a way to check this, if necessary.
对象传递给这个方法将通过sysfs内存中驻留

引用计数其嵌入的对象。然而,物理

实体(如设备)对象表示可能不存在。是

肯定有一种方式来检查这个,如果必要的


A very simple (and naive) implementation of a device attribute is:
一个非常简单的(和天真)实现设备的属性是:

static ssize_t show_name(struct device *dev, struct device_attribute *attr,
                         char *buf)
{
 return scnprintf(buf, PAGE_SIZE, "%s\n", dev->name);
}

static ssize_t store_name(struct device *dev, struct device_attribute *attr,
                          const char *buf, size_t count)
{
        snprintf(dev->name, sizeof(dev->name), "%.*s",
                 (int)min(count, sizeof(dev->name) - 1), buf);
 return count;
}

static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);


(Note that the real implementation doesn't allow userspace to set the
name for a device.)


Top Level Directory Layout顶级目录布局

~~~~~~~~~~~~~~~~~~~~~~~~~~

系统文件目录安排公开关系的内核

数据结构。

The top level sysfs directory looks like:

block/
bus/
class/
dev/
devices/
firmware/
net/
fs/

devices/ contains a filesystem representation of the device tree. It maps
directly to the internal kernel device tree, which is a hierarchy of
struct device.
设备/包含一个文件系统表示的设备树。这地图

直接向内部内核设备树,这是一个层次的

结构体装置。

bus/ contains flat directory layout of the various bus types in the
kernel. Each bus's directory contains two subdirectories:
公共汽车/包含平面目录布局的各种总线类型

内核。每个总线的目录包含两个子目录:

 devices/
 drivers/

devices/ contains symlinks for each device discovered in the system
that point to the device's directory under root/.
设备/包含符号链接为每个设备系统中发现的

指向设备的目录在根/。

drivers/ contains a directory for each device driver that is loaded
for devices on that particular bus (this assumes that drivers do not
span multiple bus types).
司机/包含一个目录中为每一个设备驱动程序被加载

设备在特定总线(这个假设司机不

跨越多个总线类型)。

fs/ contains a directory for some filesystems.  Currently each
filesystem wanting to export attributes must create its own hierarchy
below fs/ (see ./fuse.txt for an example).
fs /包含一些文件系统目录。目前每个

文件系统要导出属性必须创建自己的层次结构

低于fs /(见。/保险丝。三为例)。

dev/ contains two directories char/ and block/. Inside these two
directories there are symlinks named <major>:<minor>.  These symlinks
point to the sysfs directory for the given device.  /sys/dev provides a
quick way to lookup the sysfs interface for a device from the result of
a stat(2) operation.
dev /包含两个目录char /和块/。里面这两个

有符号链接的目录命名为<主要>:<小>。这些符号链接

点到sysfs目录给定装置。/ sys / dev提供

快速查找接口设备的sysfs的结果

一个stat(2)操作。

More information can driver-model specific features can be found in
Documentation/driver-model/.
更多的信息可以驱动模型中可以找到特定的特性

文档/驱动程序模型/。


TODO: Finish this section.
待办事项:完成本节。


Current Interfaces
~当前接口
~~~~~~~~~~~~~~~~~

The following interface layers currently exist in sysfs:
下面的界面层目前存在于sysfs:

- devices (include/linux/device.h)
----------------------------------
Structure:

struct device_attribute {
 struct attribute attr;
 ssize_t (*show)(struct device *dev, struct device_attribute *attr,
   char *buf);
 ssize_t (*store)(struct device *dev, struct device_attribute *attr,
    const char *buf, size_t count);
};

Declaring:

DEVICE_ATTR(_name, _mode, _show, _store);

Creation/Removal:

int device_create_file(struct device *dev, const struct device_attribute * attr);
void device_remove_file(struct device *dev, const struct device_attribute * attr);


- bus drivers (include/linux/device.h)
--------------------------------------
Structure:

struct bus_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct bus_type *, char * buf);
        ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};

Declaring:

BUS_ATTR(_name, _mode, _show, _store)

Creation/Removal:

int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);


- device drivers (include/linux/device.h)
-----------------------------------------

Structure:

struct driver_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct device_driver *, char * buf);
        ssize_t (*store)(struct device_driver *, const char * buf,
                         size_t count);
};

Declaring:

DRIVER_ATTR(_name, _mode, _show, _store)

Creation/Removal:

int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);


Documentation
~文档

~~~~~~~~~~~~

The sysfs directory structure and the attributes in each directory define an
ABI between the kernel and user space. As for any ABI, it is important that
this ABI is stable and properly documented. All new sysfs attributes must be
documented in Documentation/ABI. See also Documentation/ABI/README for more
information.
系统文件目录结构和属性在每个目录定义一个

ABI在内核和用户空间之间。至于任何ABI,这是非常重要的

这是稳定的和正确记录ABI。所有新sysfs属性必须

记录在文档/ ABI。参见文档/ ABI / README更多

信息。

i need to know what is pmic_chip Each PMIC device in the systems is enumerated * starting with zero. in sa8295p #ifndef PMGPIO_H #define PMGPIO_H /** @file pm_gpio.h * * PMIC-GPIO MODULE RELATED DECLARATION * This file contains functions and variable declarations to support * the PMIC GPIO module. */ /* * Copyright (c) 2009-2013 Qualcomm Technologies, Inc. * All Rights Reserved. * Confidential and Proprietary - Qualcomm Technologies, Inc. */ /*=========================================================================== EDIT HISTORY FOR MODULE This section contains comments describing changes made to the module. Notice that changes are listed in reverse chronological order. $Header: //components/rel/plt_core.qxa_qa/1.0/pmic/public/amss/core/pm_gpio.h#1 $ when who what, where, why -------- --- ---------------------------------------------------------- 03/01/13 kt Added pm_dev_gpio_get_peripheral_info API. 07/05/12 hs Updated the interface. 03/01/12 hs Updated the interface. 04/26/11 wra Adding more GPIO enumeration needed from PM8921 02/08/11 hw Merging changes from the PMIC Distributed Driver Arch branch Added struct pm_gpio_config_type Added pm_gpio_config() and pm_gpio_set_interrupt_polarity() 08/11/10 wra Removed doxygen quotations. They are causing parsing errors 07/26/10 wra Changed documentation from @example to Examples so Deoxygen can parse the file 07/09/10 jtn Added API to get GPIO status 07/02/10 wra Changed pm_gpio_perph_index to int 06/23/10 vk Added pm_gpio_set_mux_ctrl() 03/15/10 fpe Removed RPC remoting because the application processor can do this directly 10/20/09 jtn Move init function prototype to pm_device_init_i.h 10/19/09 vk Removed init API 08/01/09 vk Modified gpio_digital_input prototype 05/20/09 vk New file ===========================================================================*/ #include "com_dtypes.h" #include "pm_err_flags.h" #include "pm_resources_and_types.h" /** @addtogroup pm_gpio @{ */ /** Following api's can be used to configure GPIO as Input - To configure the mode of GPIO to Input pm_gpio_cfg_mode - To configure Pull Up or Pull Down pm_gpio_set_cur_src_pull - To configure input voltage levels for GPIO pm_gpio_set_voltage_source - To enable GPIO, since gpio's are not enabled by default they should be enabled after configuration pm_gpio_enable - To get the status of input level high or low pm_gpio_level_status Following api's can be used to configure GPIO as Input - To configure mode of GPIO to output pm_gpio_cfg_mode - To configure Output buffer type eg. CMOS, Open Drain High, Open Drain Low pm_gpio_set_out_buf_cfg - To configure drive strength of GPIO pm_gpio_set_out_buf_drv_str - To configure voltage levels for GPIO pm_gpio_set_voltage_source - To drive GPIO level high or low pm_gpio_set_output_level - To enable GPIO, since gpio's are not enabled by default they should be enabled after configuration pm_gpio_enable - To check the configuration of output level pm_gpio_level_status - To check configuration of various parameters pm_gpio_reg_status_get */ /** Type definition for different GPIOs */ typedef enum { PM_GPIO_1, /**< GPIO 1. */ PM_GPIO_2, /**< GPIO 2. */ PM_GPIO_3, /**< GPIO 3. */ PM_GPIO_4, /**< GPIO 4. */ PM_GPIO_5, /**< GPIO 5. */ PM_GPIO_6, /**< GPIO 6. */ PM_GPIO_7, /**< GPIO 7. */ PM_GPIO_8, /**< GPIO 8. */ PM_GPIO_9, /**< GPIO 9. */ PM_GPIO_10, /**< GPIO 10. */ PM_GPIO_11, /**< GPIO 11. */ PM_GPIO_12, /**< GPIO 12. */ PM_GPIO_13, /**< GPIO 13. */ PM_GPIO_14, /**< GPIO 14. */ PM_GPIO_15, /**< GPIO 15. */ PM_GPIO_16, /**< GPIO 16. */ PM_GPIO_17, /**< GPIO 17. */ PM_GPIO_18, /**< GPIO 18. */ PM_GPIO_19, /**< GPIO 19. */ PM_GPIO_20, /**< GPIO 20. */ PM_GPIO_21, /**< GPIO 21. */ PM_GPIO_22, /**< GPIO 22. */ PM_GPIO_23, /**< GPIO 23. */ PM_GPIO_24, /**< GPIO 24. */ PM_GPIO_25, /**< GPIO 25. */ PM_GPIO_26, /**< GPIO 26. */ PM_GPIO_27, /**< GPIO 27. */ PM_GPIO_28, /**< GPIO 28. */ PM_GPIO_29, /**< GPIO 29. */ PM_GPIO_30, /**< GPIO 30. */ PM_GPIO_31, /**< GPIO 31. */ PM_GPIO_32, /**< GPIO 32. */ PM_GPIO_33, /**< GPIO 33. */ PM_GPIO_34, /**< GPIO 34. */ PM_GPIO_35, /**< GPIO 35. */ PM_GPIO_36, /**< GPIO 36. */ PM_GPIO_37, /**< GPIO 37. */ PM_GPIO_38, /**< GPIO 38. */ PM_GPIO_39, /**< GPIO 39. */ PM_GPIO_40, /**< GPIO 40. */ PM_GPIO_41, /**< GPIO 41. */ PM_GPIO_42, /**< GPIO 42. */ PM_GPIO_43, /**< GPIO 43. */ PM_GPIO_44 /**< GPIO 44. */ }pm_gpio_perph_index; /** Select GPIO I/O type */ typedef enum { PM_GPIO_DIG_IN, PM_GPIO_DIG_OUT, PM_GPIO_DIG_IN_DIG_OUT, PM_GPIO_ANA_PASS_THRU, PM_GPIO_TYPE_INVALID } pm_gpio_config_type; /** Select voltage source. */ typedef enum { PM_GPIO_VIN0, /**< Voltage input 0. */ PM_GPIO_VIN1, /**< Voltage input 1. */ PM_GPIO_VIN_INVALID }pm_gpio_volt_src_type; /** Input/Output level Status. */ typedef enum { PM_GPIO_LEVEL_LOW, /**< Level of pin is low. */ PM_GPIO_LEVEL_HIGH, /**< Level of pin is high. */ PM_GPIO_LEVEL_INVALID }pm_gpio_level_type; /** Select output buffer configuration. */ typedef enum { PM_GPIO_OUT_BUFFER_CONFIG_CMOS, /**< CMOS output. */ PM_GPIO_OUT_BUFFER_CONFIG_OPEN_DRAIN_NMOS, /**< Open drain NMOS output. */ PM_GPIO_OUT_BUFFER_CONFIG_OPEN_DRAIN_PMOS, /**< Open drain PMOS output. */ PM_GPIO_OUT_BUFFER_CONFIG_INVALID }pm_gpio_out_buf_cfg_type; typedef enum { PM_GPIO_OUT_BUFFER_RESERVED, /**< Output buffer strength reserved. */ PM_GPIO_OUT_BUFFER_LOW, /**< Output buffer strength low. */ PM_GPIO_OUT_BUFFER_MEDIUM, /**< Output buffer strength medium. */ PM_GPIO_OUT_BUFFER_HIGH, /**< Output buffer strength high. */ PM_GPIO_OUT_BUFFER_INVALID }pm_gpio_out_buf_drv_str_type; /** Select current source pulls type. */ typedef enum { PM_GPIO_I_SRC_PULL_UP_30uA, /**< Pull up 30 uA. */ PM_GPIO_I_SRC_PULL_UP_1_5uA, /**< Pull up 1.5 uA. */ PM_GPIO_I_SRC_PULL_UP_31_5uA, /**< Pull up 31.5 uA. */ PM_GPIO_I_SRC_PULL_UP_1_5uA_PLUS_30uA_BOOST, /**< Pull up 1.5 uA plus 30 uA boost. */ PM_GPIO_I_SRC_PULL_DOWN_10uA, /**< Pull down 10 uA. */ PM_GPIO_I_SRC_PULL_NO_PULL, /**< No pull. */ PM_GPIO_I_SRC_PULL_INVALID }pm_gpio_i_src_pull_type; /** GPIO source select. */ typedef enum { PM_GPIO_SOURCE_GND, /**< Ground. */ PM_GPIO_SOURCE_PAIRED_GPIO, /**< Paired GPIO. */ PM_GPIO_SOURCE_SPECIAL_FUNCTION1, /**< Special function 1. */ PM_GPIO_SOURCE_SPECIAL_FUNCTION2, /**< Special function 2. */ PM_GPIO_SOURCE_SPECIAL_FUNCTION3, /**< Special function 3. */ PM_GPIO_SOURCE_SPECIAL_FUNCTION4, /**< Special function 4. */ PM_GPIO_SOURCE_DTEST1, /**< D-test 1. */ PM_GPIO_SOURCE_DTEST2, /**< D-test 2. */ PM_GPIO_SOURCE_DTEST3, /**< D-test 3. */ PM_GPIO_SOURCE_DTEST4, /**< D-test 4. */ PM_GPIO_SOURCE_INVALID }pm_gpio_src_cfg_type; // /** D-test buffer enable/disable. // */ typedef enum { PM_GPIO_DTEST_DISABLE, /**< GPIO D-test disable. */ PM_GPIO_DTEST_ENABLE, /**< GPIO D-test enable. */ PM_GPIO_DTEST_INVALID }pm_gpio_dtest_buf_en_type; /** External pin configuration. */ typedef enum { PM_GPIO_EXT_PIN_DISABLE, /**< Disable EXT_PIN. */ PM_GPIO_EXT_PIN_ENABLE, /**< Puts EXT_PIN at high Z state and disables // the block. */ PM_GPIO_EXT_PIN_CONFIG_TYPE__INVALID }pm_gpio_ext_pin_config_type; /** * Structure used to return GPIO status. This structure includes all of the * enums that are used when configuring the GPIOs. */ typedef struct { boolean enable; /**GPIO Enable Config*/ pm_gpio_config_type mode_select; /**< GPIO mode selection */ pm_gpio_volt_src_type volt_src; /**< GPIO voltage source. */ pm_gpio_out_buf_cfg_type out_buf_cfg; /**< GPIO output buffer configuration. */ pm_gpio_level_type level; /**< GPIO invert EXT_PIN configuration. */ pm_gpio_out_buf_drv_str_type out_buf_drv_str; /**< GPIO output buffer driver strength. */ pm_gpio_i_src_pull_type i_src_pulls; /**< GPIO current source pulls. */ pm_gpio_src_cfg_type src_cfg; /**< GPIO source configuration. */ pm_gpio_dtest_buf_en_type dtest_buffer_on_off; /**< GPIO D-text buffer on/off. */ } pm_gpio_status_type; /*=========================================================================== */ /* FUNCTION DEFINITIONS */ /*=========================================================================== */ /*=========================================================================== */ /* pm_gpio_enable */ /*=========================================================================== */ /** * Enables GPIO. * * @param[in] pmic_chip Each PMIC device in the system is enumerated * starting with zero. * @param[in] gpio GPIO for which to configure voltage source. See * #pm_gpio_perph_index. * @param[in] enable Set TRUE to enable GPIO, FALSE to disable. * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * Enable GPIO5: * @code * errFlag = pm_gpio_enable(0, PM_GPIO_5, TRUE); @endcode */ pm_err_flag_type pm_gpio_enable(uint8 pmic_chip, pm_gpio_perph_index gpio, boolean enable); /*=========================================================================== */ /* pm_gpio_cfg_mode */ /*=========================================================================== */ /** * Set GPIO Configuration to Input, Output, InOut. * * @param[in] pmic_chip Each PMIC device in the system is enumerated * starting with zero. * @param[in] gpio GPIO for which to configure voltage source. See * #pm_gpio_perph_index. * @param[in] type Configuration type. See pm_gpio_config_type. * * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * Configure GPIO5 to Output: * @code * errFlag = pm_gpio_cfg_in_out(0, PM_GPIO_5, PM_GPIO_DIG_OUT); @endcode */ pm_err_flag_type pm_gpio_cfg_mode(uint8 pmic_chip, uint8 gpio, pm_gpio_config_type type); /*=========================================================================== */ /* pm_gpio_level_status */ /*=========================================================================== */ /** * Get input level or configuration of output level for a given gpio. * * @param[in] pmic_chip Each PMIC device in the system is enumerated * starting with zero. * @param[in] gpio GPIO for which to configure voltage source. See * #pm_gpio_perph_index. * @param[in] type Configuration type. See pm_gpio_config_type. * @param[out] level pointer to level * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * Get GPIO5 to Output level: * @code * errFlag = pm_gpio_level_status(0, PM_GPIO_5, * PM_GPIO_DIG_OUT, &level); @endcode */ pm_err_flag_type pm_gpio_level_status(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_config_type type, pm_gpio_level_type *level_status); /*=========================================================================== */ /* pm_gpio_set_voltage_source */ /*=========================================================================== */ /** * Sets the voltage source. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated * starting with zero. * @param[in] gpio GPIO for which to configure voltage source. See * #pm_gpio_perph_index. * @param[in] voltage_source GPIO voltage source. See * #pm_gpio_voltage_source_type. * * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * Set voltage source to VIN2 for GPIO5: * @code * errFlag = pm_gpio_set_voltage_source(0, PM_GPIO_5, * PM_GPIO_VIN2); @endcode */ pm_err_flag_type pm_gpio_set_voltage_source(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_volt_src_type voltage_source); /*=========================================================================== */ /* pm_gpio_set_out_buf_cfg */ /*=========================================================================== */ /** * Sets the output buffer configuration. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated * starting with zero. * @param[in] gpio GPIO for which to configure the current source pulls. See * #pm_gpio_perph_index. * @param[in] out_buffer_config GPIO output buffer configuration: 0 -- CMOS; * 1 -- open drain. See * #pm_gpio_out_buf_cfg_type. * * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * Set the output buffer configuration to CMOS in bias mode for GPIO5: * @code * errFlag = pm_gpio_set_out_buf_cfg(0, PM_GPIO_5, * PM_GPIO_OUT_BUFFER_CONFIG_CMOS); @endcode */ pm_err_flag_type pm_gpio_set_out_buf_cfg(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_out_buf_cfg_type out_buffer_config); /*=========================================================================== */ /* pm_gpio_set_output_level() */ /*=========================================================================== */ /** * Sets level for output. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated * starting with zero. * @param[in] gpio GPIO for which to set the inversion configuration. * See #pm_gpio_perph_index. * @param[in] level Output level to be set for GPIO * see #pm_gpio_output_level_type * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * For GPIO5, set output high: * @code * errFlag = pm_gpio_set_output_level(0, PM_GPIO_5, PM_GPIO_OUTPUT_LEVEL_HIGH); @endcode */ pm_err_flag_type pm_gpio_set_output_level(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_level_type level); /*=========================================================================== */ /* pm_gpio_set_cur_src_pull */ /*=========================================================================== */ /** * Sets the current source pulls. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated * starting with zero. * @param[in] gpio GPIO for which to configure current source pulls. See * #pm_gpio_perph_index. * @param[in] i_source_pulls Current source pulls. See * #pm_gpio_current_src_pulls_type. * * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * Set the current source pulls to 1.5 uA + 30 uA boost for GPIO5: * @code * errFlag = pm_gpio_set_cur_src_pull(0, PM_GPIO_5, * PM_GPIO_I_SOURCE_PULL_UP_1_5uA_PLUS_30uA_BOOST); @endcode */ pm_err_flag_type pm_gpio_set_cur_src_pull(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_i_src_pull_type i_src_pull); /*=========================================================================== */ /* pm_gpio_set_out_buf_drv_str */ /*=========================================================================== */ /** * Sets the output buffer drive strength. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated * starting with zero. * @param[in] gpio GPIO for which to configure current source pulls. See * #pm_gpio_perph_index. * @param[in] out_buffer_strength GPIO output buffer drive strength. * #See #pm_gpio_out_buf_drv_str_type. * * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * Set the output buffer drive strength for GPIO5 to HIGH: * @code * errFlag = pm_gpio_set_out_buf_drv_str(0, PM_GPIO_5, * PM_GPIO_OUT_BUFFER_HIGH); @endcode */ pm_err_flag_type pm_gpio_set_out_buf_drv_str(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_out_buf_drv_str_type out_buffer_strength); /*======================================================================= */ /* pm_gpio_set_out_src_cfg */ /*======================================================================= */ /** * Sets the source configuration. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated * starting with zero. * @param[in] gpio GPIO for which to set the source configuration. * See #pm_gpio_perph_index</td> * @param[in] source Select the source. See #pm_gpio_src_cfg_type. * * @return * SUCCESS or Error -- See #pm_err_flag_type. * * <b>Example </b> \n * To serve GPIO5 as an output in Level Translator mode, select Pair In as * the source: * @code * errFlag=pm_gpio_set_src_cfg(0, PM_GPIO_5, * PM_GPIO_SOURCE_PAIRED_GPIO); @endcode */ pm_err_flag_type pm_gpio_set_out_src_cfg(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_src_cfg_type source); /*======================================================================= */ /* pm_gpio_irq_enable */ /*======================================================================= */ /** * @brief This function enables or disables gpio irq * * @param[in] pmic_chip. Primary: 0. Secondary: 1 * @param[in] gpio: * GPIO number. Refer enum pm_gpio_perph_index. * * @param[in] enable: * TRUE: Enable interrupt for the gpio * FALSE:Disable interrupt for the gpio * * * @return pm_err_flag_type * PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this * version of the PMIC. * PM_ERR_FLAG__SUCCESS = SUCCESS. * */ pm_err_flag_type pm_gpio_irq_enable(uint8 pmic_chip, pm_gpio_perph_index gpio, boolean enable); /*======================================================================= */ /* pm_gpio_irq_clear */ /*======================================================================= */ /** * Clears the GPIO IRQ. * * @param[in] pmic_chip Primary -- 0; Secondary -- 1. * @param[in] gpio GPIO number. See #pm_gpio_perph_index. * * @return * SUCCESS or Error -- See #pm_err_flag_type. */ pm_err_flag_type pm_gpio_irq_clear(uint8 pmic_chip, pm_gpio_perph_index gpio); /*======================================================================= */ /* pm_gpio_irq_set_trigger */ /*======================================================================= */ /** * Configures the GPIO for an IRQ. * * @param[in] pmic_chip Primary -- 0; Secondary -- 1. * @param[in] gpio GPIO number. See #pm_gpio_perph_index. * @param[in] trigger One of the various IRQ triggers. See * #pm_irq_trigger_type. * * @return * SUCCESS or Error -- See #pm_err_flag_type. */ pm_err_flag_type pm_gpio_irq_set_trigger(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_irq_trigger_type trigger); /*======================================================================= */ /* pm_gpio_irq_status */ /*======================================================================= */ /** * Gets the GPIO IRQ status. * * @param[in] pmic_chip Primary -- 0; Secondary -- 1. * @param[in] gpio GPIO number. See #pm_gpio_perph_index. * @param[in] type Type of IRQ status to read. See #pm_irq_status_type. * @param[out] status IRQ status. * * @return * SUCCESS or Error -- See #pm_err_flag_type. */ pm_err_flag_type pm_gpio_irq_status(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_irq_status_type irq_type, boolean *status); /*======================================================================= */ /* pm_gpio_reg_status_get */ /*======================================================================= */ /** * Returns the status of one of the PMIC GPIOs. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated, * starting with zero. * @param[in] gpio GPIO identifier. * @param[out] gpio_status Pointer to the GPIO status. * * @return * SUCCESS or Error -- See #pm_err_flag_type. */ pm_err_flag_type pm_gpio_reg_status_get(uint8 pmic_chip, pm_gpio_perph_index gpio, pm_gpio_status_type *gpio_status); /*======================================================================= */ /* pm_gpio_get_perph_id */ /*======================================================================= */ /** * Returns peripheral ID for gpio. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated, * starting with zero. * @param[in] gpio GPIO identifier. * @param[out] addr Pointer to the . * * @return * SUCCESS or Error -- See #pm_err_flag_type. */ pm_err_flag_type pm_gpio_get_perph_id(uint8 pmic_chip, pm_gpio_perph_index gpio, uint32 *addr); /*======================================================================= */ /* pm_gpio_create_channel */ /*======================================================================= */ /** * Associate spmi channel with gpio * if *chid = -1 , then a new channel id will be created * if *chid !=-1 , then *chid will be considered a valid existing channel and * no new channel will be created . The existing *chid will be associated with * the gpio. * This way we can use same channel for multiple gpios if needed. However it * is not required that we use same channel for multiple gpios or vice versa * To be used with pmic client only. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated, * starting with zero. * @param[in] gpio GPIO identifier. * @param[out] channel id. * @return * SUCCESS or Error -- See #pm_err_flag_type. */ pm_err_flag_type pm_gpio_create_channel(uint8 pmic_chip , pm_gpio_perph_index gpio , int *chid); /*======================================================================= */ /* pm_gpio_wait_for_irq */ /*======================================================================= */ /** * Waits for interrupt on gpio. To be used with pmic client only. * * @param[in] pmic_chip Each PMIC device in the systems is enumerated, * starting with zero. * @param[in] gpio GPIO identifier. * * @return * SUCCESS or Error -- See #pm_err_flag_type. */ pm_err_flag_type pm_gpio_wait_for_irq(uint8 pmic_chip, pm_gpio_perph_index gpio, int chid); /** @} */ /* end_addtogroup pm_gpio */ #endif /* PMGPIO_H */
08-15
<think>我们正在讨论SA8295P平台上的PMIC芯片和GPIO功能,包括GPIO配置和API使用。 由于SA8295P是高通骁龙Ride平台的一部分,通常用于汽车计算领域,因此PMIC(电源管理集成电路)和GPIO(通用输入输出)的配置对于硬件控制和电源管理至关重要。 首先,PMIC芯片负责管理平台的电源分配、电压调节、电池充电等。在SA8295P中,PMIC可能是一个独立的芯片,与主处理器协同工作。 其次,GPIO是通用的数字信号引脚,可以配置为输入或输出模式,用于控制外部设备或读取传感器状态。 关于配置和API使用,通常需要参考高通提供的文档和软件工具(如QRD)。由于具体细节属于专有信息,以下内容基于一般高通平台的知识进行说明。 ### GPIO配置 在Linux系统中,GPIO通常通过sysfs接口或新的gpiolib(libgpiod)进行控制。对于SA8295P,由于是较新的平台,可能使用libgpiod。 1. **查找GPIO编号**:在设备树(Device Tree)中定义GPIO,每个GPIO有一个唯一的编号。可以通过设备树文件(.dts)或使用命令(如`gpiodetect`)查看。 2. **控制GPIO**:使用libgpiod库中的工具(如`gpioset`,`gpioget`)或编写C程序。 示例:使用`gpiodetect`列出所有GPIO控制器: ```bash gpiodetect ``` 使用`gpioinfo`查看特定控制器的GPIO线: ```bash gpioinfo <controller-name> ``` 然后,设置GPIO输出值: ```bash gpioset <controller-name> <line-offset>=<value> ``` 读取GPIO输入值: ```bash gpioget <controller-name> <line-offset> ``` 在C代码中使用libgpiod: ```c #include <gpiod.h> struct gpiod_chip *chip; struct gpiod_line *line; int value; chip = gpiod_chip_open("/dev/gpiochip0"); line = gpiod_chip_get_line(chip, offset); gpiod_line_request_output(line, "example", 0); gpiod_line_set_value(line, 1); value = gpiod_line_get_value(line); gpiod_line_release(line); gpiod_chip_close(chip); ``` ### PMIC相关功能 PMIC的配置通常由高通的PMIC驱动程序处理,开发者可以通过高通的PMIC框架(如SPMI)进行交互。在用户空间,可以通过sysfs节点或特定的设备文件进行控制。 例如,调整某个电源轨的电压: ```bash echo <voltage_in_microvolts> > /sys/class/regulator/regulator.X/microvolts ``` 但请注意,PMIC的操作通常需要内核权限,并且直接操作可能影响系统稳定性。 ### 在SA8295P上使用API 高通提供了Snapdragon Automotive Development Platform(SADP)和相应的文档。开发者应参考: - Snapdragon Automotive SDK (SA SDK) - 高通Linux BSP(板级支持包)文档 在BSP中,可能有特定的API用于PMIC和GPIO控制。例如,在Android Automotive或Linux Automotive中,可能有HAL(硬件抽象层)接口。 由于具体细节依赖于高通的软件版本和平台定制,建议查阅以下资源: 1. 高通提供的SA8295P硬件参考手册(非公开,需NDA) 2. 高通Linux BSP的文档(在代码中) 3. 设备树绑定文档(Documentation/devicetree/bindings/) 注意:以上信息为一般性指导,具体操作请以官方文档为准。 §§相关问题§§ 1. SA8295P平台上的GPIO控制器名称是什么? 2. 如何通过设备树配置SA8295P的GPIO引脚? 3. SA8295P的PMIC芯片型号是什么?它支持哪些电源管理功能? 4. 是否有高通的API文档或示例代码用于控制PMIC? 5. 在SA8295P上使用GPIO时需要注意哪些电气特性?</think>### SA8295P平台中的PMIC芯片与GPIO功能详解 #### 1. **PMIC芯片核心功能** PMIC(电源管理集成电路)在SA8295P平台中负责多域电源管理: - **多轨电压调节**:为CPU核、DDR内存、外设接口提供20+路可编程电压轨,支持动态调压(DVFS)技术[^1] - **功耗管理**:实现低功耗模式切换(如睡眠/唤醒状态),典型待机功耗<5mW - **安全监控**:实时监测温度/电压/电流,触发过压(OVP)/欠压(UVP)保护 - **电池管理**:支持车载电池的充电控制与电量计量(适用于IVI系统) #### 2. **GPIO架构特性** SA8295P提供高度可配置的GPIO子系统: - **物理资源**:最多支持186个GPIO引脚(依具体SoC型号) - **复用能力**:每个引脚可通过IOMMU配置为: - 通用输入/输出 - 外设功能(如I2C/SPI/UART) - 中断源(边沿/电平触发) - **电气特性**: - 电压域:1.8V/3.3V兼容 - 驱动强度:4级可调(2mA~16mA) - 施密特触发器输入噪声抑制 #### 3. **GPIO配置流程** **步骤1:引脚复用配置** 通过设备树(Device Tree)声明引脚功能: ```dts // 示例:配置GPIO12为I2C1_SDA功能 &tlmm { i2c1_sda_active: i2c1_sda_active { mux { pins = "gpio12"; function = "i2c1"; }; config { pins = "gpio12"; drive-strength = <8>; // 8mA驱动强度 bias-pull-up; // 使能上拉 }; }; }; ``` **步骤2:内核空间API** Linux GPIO子系统操作: ```c #include <linux/gpio/consumer.h> struct gpio_desc *gpio; gpio = gpiod_get(dev, "led_ctrl", GPIOD_OUT_HIGH); // 获取GPIO控制权 gpiod_set_value(gpio, 0); // 输出低电平 gpiod_direction_input(gpio); // 切换为输入模式 int val = gpiod_get_value(gpio); // 读取引脚状态 ``` **步骤3:用户空间控制** 通过sysfs接口(需内核CONFIG_GPIO_SYSFS): ```bash echo 48 > /sys/class/gpio/export # 启用GPIO48 echo out > /sys/class/gpio/gpio48/direction echo 1 > /sys/class/gpio/gpio48/value # 输出高电平 ``` #### 4. **PMIC交互API** 通过SPMI(Serial Peripheral Management Interface)总线访问PMIC: ```c #include <linux/regmap.h> #include <linux/spmi.h> // 读取PMIC寄存器 int pmic_read(struct spmi_device *sdev, u16 addr, u8 *val) { return regmap_bulk_read(sdev->regmap, addr, val, 1); } // 配置LDO电压(示例:LDO5设为1.2V) u8 reg_val = 0x24; // 电压值对应寄存器数据 regmap_write(sdev->regmap, PMIC_LDO5_CTRL, reg_val); ``` #### 5. **关键注意事项** - **电平兼容**:连接1.8V器件时需禁用内部上拉 - **中断处理**:GPIO中断服务程序(ISR)需在<100μs内完成 - **PMIC时序**:电压轨使能/禁用需遵循datasheet规定的时序 - **ESD防护**:所有GPIO必须设计TVS二极管保护电路 > 注:具体寄存器地址及电气参数请参考《SA8295P Hardware Reference Manual》(文档编号80-NL436-1)[^2]和《PM855 Data Sheet》[^3] --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值