PWM

来自Firefly wiki
跳转至: 导航搜索

Introduction

Firefly-RK3288 development board has 4 PWMs, namely PWM0 ~ PWM3. This article describes how to configure and use PWM.

The PWM driver file of RK3288 is:

kernel/drivers/pwm/pwm-rockchip.c

Data Structure

struct pwm_device

The pwm_device mainly use to pwm device .it’s the most important structure in pwm. };

struct pwm_device {
    const char      *label;
    unsigned long       flags;
    unsigned int        hwpwm;
    unsigned int        pwm;//lane of pwm
    struct pwm_chip     *chip;
    void            *chip_data;
    unsigned int        period; /* in nanoseconds */

struct pwm_chip

pwm_chip abstracts for a PWM controller.

struct pwm_chip {
    struct device       *dev;//device providing the PWMs
    struct list_head    list;//list node for internal use
    const struct pwm_ops    *ops;//callbacks for this PWM controller
    int         base;//number of first PWM controlled by this chip
    unsigned int        npwm;//number of PWMs controlled by this chip
    struct pwm_device   *pwms;//array of PWM devices allocated by the framework
    struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
                        const struct of_phandle_args *args);
    unsigned int        of_pwm_n_cells;
    bool            can_sleep;// must be true if the .config(),enable() or.disable(),operations may sleep
};

Configuration steps

You can follow these steps to finish the PWM configuration.

Create PWM DTS Node

You can create the pwm device node in file kernel/arch/arm/boot/dts/rk3288.dtsi, as shown below:

 pwm1: pwm@ff680010 {
        compatible = "rockchip,rk-pwm";
        reg = <0xff680010 0x10>;
        #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pwm1_pin>;
        clocks = <&clk_gates11 11>; 
        clock-names = "pclk_pwm";
        status = "okay";
    };

Note: ff680010 is the address of pwm1 register.

Configure PWM driver

The PWM driver of RK3288 is in file kernel/drivers/pwm/pwm-rockchip.c

Modify the code as shown below:

static const struct of_device_id rk_pwm_of_match[] = {
    { .compatible = "rockchip,pwm",          .data = &rk_pwm_data_v1,},
    { .compatible =  "rockchip,rk-pwm",    .data = &rk_pwm_data_v2,},
    { .compatible =  "rockchip,vop-pwm",  .data = &rk_pwm_data_v3,},
    { }
};

Make sure the compatible field matches the device tree’s compatible property that you create above.

Control PWM Device

Now you can use the PWM node created above to control devices, as shown in the following steps:

(1). Include the pwm.h file

#include <linux/pwm.h>

This file includes the API functions of PWM.

(2). Request PWM.

You can use the pwm_request function to request the PWM device. For example:

struct pwm_device * pwm0=NULL;
pwm0= pwm_request(0, “backlight-pwm”);

See The API of PWM device for more detail of this function.

(3). Set PWM configuration

You can use the function pwm_config to set the PWM configuration. For example:

pwm_config(pwm0, 500000, 1000000)

See The API of PWM device for more detail of this function.

(4). Enable PWM

Then you start the pwm device using the pwm_enable function. For example:

int pwm_enable(struct pwm_device *pwm);

See The API of PWM device for more detail of this function.

The API of PWM device

/**
 * pwm_request() - request a PWM device
 * @pwm_id: global PWM device index
 * @label: PWM device label
 *
 * This function is deprecated, use pwm_get() instead.
 */
	struct pwm_device *pwm_request(int pwm_id, const char *label);


/**
 * pwm_free() - free a PWM device
 * @pwm: PWM device
 *
 * This function is deprecated, use pwm_put() instead.
 */
	void pwm_free(struct pwm_device *pwm);


/**
 * pwm_config() - change a PWM device configuration
 * @pwm: PWM device
 * @duty_ns: "on" time (in nanoseconds)
 * @period_ns: duration (in nanoseconds) of one cycle
 */
	int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);


/**
 * pwm_enable() - start a PWM output toggling
 * @pwm: PWM device
 */
	int pwm_enable(struct pwm_device *pwm);


/**
 * pwm_disable() - stop a PWM output toggling
 * @pwm: PWM device
 */
	void pwm_disable(struct pwm_device *pwm);