Linux 驱动之 PWM

PWM 概述

  • Ton:信号高电平持续时间
  • Toff:信号底电平持续时间
  • Period: 完整 pwm 周期
  • Duty cycle:pwm 信号周期内保持为 ON 的时间百分比

Linux 下 PWM 驱动

数据结构

pwm 的数据结构如下图所示:原图

  • pwm_chip 结构体用于抽象 soc 的 pwm 控制器
  • pwm_device 用来抽象设备
  • pwm_state 表示 pwm 设备的周期、占空比、极性等信息
  • pwm ops 结构体提供一系列回调函数。这些回调函数的操作对象是具体的 pwm device

实现

pwm 驱动分为 consumer 和 provider。其中 consumer 提供接口如下:

1
2
3
static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) //配置 pwm device 的频率、占空比。
static inline int pwm_enable(struct pwm_device *pwm) //使能/禁止 pwm 信号输出
static inline void pwm_disable(struct pwm_device *pwm)

这些接口实现对 pwm 设备的配置,使能等(这些接口最终会调用到 pwm_ops 结构体提供的函数),操作 struct pwm_device 结构体,代表了具体的 pwm 设备。这些 struct pwm_device 结构体指针由以下函数获得:

1
2
3
struct pwm_device *pwm_get(struct device *dev, const char *con_id)
void pwm_put(struct pwm_device *pwm)
struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)

其中 pwm_get 接口流程如下:原图

pwm_get/devm_pwm_get,从指定设备(dev)的 DTS 节点中,获得对应的 PWM 句柄。可以通过 con_id 指定一个名称,或者会获取和该设备绑定的第一个 PWM 句柄。

provider 提供以下接口:

1
2
int pwmchip_add(struct pwm_chip *chip)
int pwmchip_remove(struct pwm_chip *chip)

将一个 pwm_chip 注册到内核添加到 pwm_chips 链表中去。

参考文献

http://www.wowotech.net/comm/pwm_overview.html
《Linux 设备驱动开发》