pwm: rockchip: support more features

1.support counter, frequency meter, global control and
  wave generator.
2.add struct rockchip_pwm_funcs and modify struct
  rockchip_pwm_data for compatibility and extensibility.
3.rename current .enable/.config/.irq_handler to v1.
4.not to return ERRNO if failed to get irq in probing for
  pwm_v3.

Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
Change-Id: I28c6a2946ccb9072f464397d6b25f4b6803fa8c5
This commit is contained in:
Damon Ding
2023-11-27 14:26:22 +08:00
committed by Tao Huang
parent 210fc91d1c
commit a8165608c7
3 changed files with 521 additions and 31 deletions

View File

@@ -7,6 +7,7 @@
#define _PWM_ROCKCHIP_IRQ_CALLBACKS_H_
#include <linux/pwm.h>
#include <linux/pwm-rockchip.h>
static void rockchip_pwm_oneshot_callback(struct pwm_device *pwm, struct pwm_state *state)
{

View File

@@ -18,6 +18,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/pwm-rockchip.h>
#include <linux/time.h>
#include "pwm-rockchip-irq-callbacks.h"
@@ -52,7 +53,6 @@
#define PWM_ONESHOT_COUNT_SHIFT 24
#define PWM_ONESHOT_COUNT_MASK (0xff << PWM_ONESHOT_COUNT_SHIFT)
#define PWM_ONESHOT_COUNT_MAX 256
#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10)
#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14)
@@ -73,8 +73,12 @@ struct rockchip_pwm_chip {
bool vop_pwm_en; /* indicate voppwm mirror register state */
bool center_aligned;
bool oneshot_en;
bool freq_meter_support;
bool counter_support;
bool wave_support;
int channel_id;
int irq;
u8 capture_cnt;
};
struct rockchip_pwm_regs {
@@ -82,16 +86,45 @@ struct rockchip_pwm_regs {
unsigned long period;
unsigned long cntr;
unsigned long ctrl;
unsigned long version;
};
struct rockchip_pwm_funcs {
int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm, bool enable);
void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state);
void (*set_capture)(struct pwm_chip *chip, struct pwm_device *pwm, bool enable);
int (*get_capture_result)(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_capture *catpure_res);
int (*set_counter)(struct pwm_chip *chip, struct pwm_device *pwm, bool enable);
int (*get_counter_result)(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long *counter_res, bool is_clear);
int (*set_freq_meter)(struct pwm_chip *chip, struct pwm_device *pwm,
bool enable, unsigned long delay_ms);
int (*get_freq_meter_result)(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long delay_ms, unsigned long *freq_hz);
int (*global_ctrl)(struct pwm_chip *chip, struct pwm_device *pwm,
enum rockchip_pwm_global_ctrl_cmd cmd);
int (*set_wave_table)(struct pwm_chip *chip, struct pwm_device *pwm,
struct rockchip_pwm_wave_table *table_config,
enum rockchip_pwm_wave_table_width_mode width_mode);
int (*set_wave)(struct pwm_chip *chip, struct pwm_device *pwm,
struct rockchip_pwm_wave_config *config);
irqreturn_t (*irq_handler)(int irq, void *data);
};
struct rockchip_pwm_data {
struct rockchip_pwm_regs regs;
struct rockchip_pwm_funcs funcs;
unsigned int prescaler;
bool supports_polarity;
bool supports_lock;
bool vop_pwm;
u32 enable_conf;
u32 enable_conf_mask;
u32 oneshot_cnt_max;
u32 oneshot_rpt_max;
u32 wave_table_max;
};
static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
@@ -107,7 +140,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
u32 enable_conf = pc->data->enable_conf;
u64 tmp;
u32 val;
u32 dclk_div;
u32 dclk_div = 1;
int ret;
if (!pc->oneshot_en) {
@@ -140,7 +173,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
clk_disable(pc->pclk);
}
static irqreturn_t rockchip_pwm_oneshot_irq(int irq, void *data)
static irqreturn_t rockchip_pwm_irq_v1(int irq, void *data)
{
struct rockchip_pwm_chip *pc = data;
struct pwm_state state;
@@ -168,8 +201,8 @@ static irqreturn_t rockchip_pwm_oneshot_irq(int irq, void *data)
return IRQ_HANDLED;
}
static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
static void rockchip_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
unsigned long period, duty, delay_ns;
@@ -179,7 +212,7 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u8 dclk_div = 1;
#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
if (state->oneshot_count > 0 && state->oneshot_count <= PWM_ONESHOT_COUNT_MAX)
if (state->oneshot_count > 0 && state->oneshot_count <= pc->data->oneshot_cnt_max)
dclk_div = 2;
#endif
@@ -210,7 +243,7 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
}
#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
if (state->oneshot_count > 0 && state->oneshot_count <= PWM_ONESHOT_COUNT_MAX) {
if (state->oneshot_count > 0 && state->oneshot_count <= pc->data->oneshot_cnt_max) {
u32 int_ctrl;
/*
@@ -233,9 +266,11 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
ctrl &= ~PWM_ONESHOT_COUNT_MASK;
ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
int_ctrl = readl_relaxed(pc->base + PWM_REG_INT_EN(pc->channel_id));
int_ctrl |= PWM_CH_INT(pc->channel_id);
writel_relaxed(int_ctrl, pc->base + PWM_REG_INT_EN(pc->channel_id));
if (pc->irq >= 0) {
int_ctrl = readl_relaxed(pc->base + PWM_REG_INT_EN(pc->channel_id));
int_ctrl |= PWM_CH_INT(pc->channel_id);
writel_relaxed(int_ctrl, pc->base + PWM_REG_INT_EN(pc->channel_id));
}
} else {
u32 int_ctrl;
@@ -244,7 +279,8 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
ctrl |= PWM_SEL_NO_SCALED_CLOCK;
if (state->oneshot_count)
dev_err(chip->dev, "Oneshot_count must be between 1 and 256.\n");
dev_err(chip->dev, "Oneshot_count must be between 1 and %d.\n",
pc->data->oneshot_cnt_max);
pc->oneshot_en = false;
ctrl &= ~PWM_MODE_MASK;
@@ -292,9 +328,7 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
local_irq_restore(flags);
}
static int rockchip_pwm_enable(struct pwm_chip *chip,
struct pwm_device *pwm,
bool enable)
static int rockchip_pwm_enable_v1(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = pc->data->enable_conf;
@@ -333,6 +367,21 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
return 0;
}
static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
pc->data->funcs.config(chip, pwm, state);
}
static int rockchip_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
return pc->data->funcs.enable(chip, pwm, enable);
}
static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
@@ -374,6 +423,235 @@ out:
return ret;
}
int rockchip_pwm_set_counter(struct pwm_device *pwm, bool enable)
{
struct pwm_chip *chip;
struct rockchip_pwm_chip *pc;
struct pwm_state curstate;
int ret = 0;
if (!pwm)
return -EINVAL;
chip = pwm->chip;
pc = to_rockchip_pwm_chip(chip);
if (!pc->counter_support ||
!pc->data->funcs.set_counter || !pc->data->funcs.get_counter_result) {
dev_err(chip->dev, "Unsupported counter mode\n");
return -EINVAL;
}
pwm_get_state(pwm, &curstate);
if (curstate.enabled) {
dev_err(chip->dev, "Failed to enable counter mode because PWM%d is busy\n",
pc->channel_id);
return -EBUSY;
}
ret = clk_enable(pc->pclk);
if (ret)
return ret;
ret = pc->data->funcs.set_counter(chip, pwm, enable);
if (ret) {
dev_err(chip->dev, "Failed to abtain counter arbitration for PWM%d\n",
pc->channel_id);
goto err_disable_pclk;
}
err_disable_pclk:
clk_disable(pc->pclk);
return ret;
}
EXPORT_SYMBOL_GPL(rockchip_pwm_set_counter);
int rockchip_pwm_get_counter_result(struct pwm_device *pwm,
unsigned long *counter_res, bool is_clear)
{
struct pwm_chip *chip;
struct rockchip_pwm_chip *pc;
int ret = 0;
if (!pwm || !counter_res)
return -EINVAL;
chip = pwm->chip;
pc = to_rockchip_pwm_chip(chip);
if (!pc->counter_support ||
!pc->data->funcs.set_counter || !pc->data->funcs.get_counter_result) {
dev_err(chip->dev, "Unsupported counter mode\n");
return -EINVAL;
}
ret = clk_enable(pc->pclk);
if (ret)
return ret;
ret = pc->data->funcs.get_counter_result(chip, pwm, counter_res, is_clear);
if (ret) {
dev_err(chip->dev, "Failed to get counter result for PWM%d\n",
pc->channel_id);
goto err_disable_pclk;
}
err_disable_pclk:
clk_disable(pc->pclk);
return ret;
}
EXPORT_SYMBOL_GPL(rockchip_pwm_get_counter_result);
int rockchip_pwm_set_freq_meter(struct pwm_device *pwm, unsigned long delay_ms,
unsigned long *freq_hz)
{
struct pwm_chip *chip;
struct rockchip_pwm_chip *pc;
struct pwm_state curstate;
int ret = 0;
if (!pwm || !freq_hz)
return -EINVAL;
chip = pwm->chip;
pc = to_rockchip_pwm_chip(chip);
if (!pc->freq_meter_support ||
!pc->data->funcs.set_freq_meter || !pc->data->funcs.get_freq_meter_result) {
dev_err(chip->dev, "Unsupported frequency meter mode\n");
return -EINVAL;
}
pwm_get_state(pwm, &curstate);
if (curstate.enabled) {
dev_err(chip->dev, "Failed to enable frequency meter mode because PWM%d is busy\n",
pc->channel_id);
return -EBUSY;
}
ret = clk_enable(pc->pclk);
if (ret)
return ret;
ret = pc->data->funcs.set_freq_meter(chip, pwm, true, delay_ms);
if (ret) {
dev_err(chip->dev, "Failed to abtain frequency meter arbitration for PWM%d\n",
pc->channel_id);
} else {
ret = pc->data->funcs.get_freq_meter_result(chip, pwm, delay_ms, freq_hz);
if (ret) {
dev_err(chip->dev, "Failed to get frequency meter result for PWM%d\n",
pc->channel_id);
}
}
pc->data->funcs.set_freq_meter(chip, pwm, false, 0);
clk_disable(pc->pclk);
return ret;
}
EXPORT_SYMBOL_GPL(rockchip_pwm_set_freq_meter);
int rockchip_pwm_global_ctrl(struct pwm_device *pwm, enum rockchip_pwm_global_ctrl_cmd cmd)
{
struct pwm_chip *chip;
struct rockchip_pwm_chip *pc;
struct pwm_state curstate;
int ret = 0;
if (!pwm)
return -EINVAL;
chip = pwm->chip;
pc = to_rockchip_pwm_chip(chip);
if (!pc->data->funcs.global_ctrl) {
dev_err(chip->dev, "Unsupported global control\n");
return -EINVAL;
}
pwm_get_state(pwm, &curstate);
if (curstate.enabled) {
dev_err(chip->dev, "Failed to execute global ctrl cmd %d because PWM%d is busy\n",
cmd, pc->channel_id);
return -EBUSY;
}
ret = clk_enable(pc->pclk);
if (ret)
return ret;
ret = pc->data->funcs.global_ctrl(chip, pwm, cmd);
if (ret) {
dev_err(chip->dev, "Failed to execute global ctrl cmd %d for PWM%d\n",
cmd, pc->channel_id);
goto err_disable_pclk;
}
err_disable_pclk:
clk_disable(pc->pclk);
return ret;
}
EXPORT_SYMBOL_GPL(rockchip_pwm_global_ctrl);
int rockchip_pwm_set_wave(struct pwm_device *pwm, struct rockchip_pwm_wave_config *config)
{
struct pwm_chip *chip;
struct rockchip_pwm_chip *pc;
int ret = 0;
if (!pwm || !config)
return -EINVAL;
chip = pwm->chip;
pc = to_rockchip_pwm_chip(chip);
if (!pc->wave_support ||
!pc->data->funcs.set_wave_table || !pc->data->funcs.set_wave) {
dev_err(chip->dev, "Unsupported wave generator mode\n");
return -EINVAL;
}
ret = clk_enable(pc->pclk);
if (ret)
return ret;
if (config->duty_table) {
ret = pc->data->funcs.set_wave_table(chip, pwm, config->duty_table,
config->width_mode);
if (ret) {
dev_err(chip->dev, "Failed to set wave duty table for PWM%d\n",
pc->channel_id);
goto err_disable_pclk;
}
}
if (config->period_table) {
ret = pc->data->funcs.set_wave_table(chip, pwm, config->period_table,
config->width_mode);
if (ret) {
dev_err(chip->dev, "Failed to set wave period table for PWM%d\n",
pc->channel_id);
goto err_disable_pclk;
}
}
ret = pc->data->funcs.set_wave(chip, pwm, config);
if (ret) {
dev_err(chip->dev, "Failed to set wave generator for PWM%d\n", pc->channel_id);
goto err_disable_pclk;
}
err_disable_pclk:
clk_disable(pc->pclk);
return ret;
}
EXPORT_SYMBOL_GPL(rockchip_pwm_set_wave);
#ifdef CONFIG_DEBUG_FS
static int rockchip_pwm_debugfs_show(struct seq_file *s, void *data)
{
@@ -433,6 +711,7 @@ static const struct pwm_ops rockchip_pwm_ops = {
static const struct rockchip_pwm_data pwm_data_v1 = {
.regs = {
.version = 0x5c,
.duty = 0x04,
.period = 0x08,
.cntr = 0x00,
@@ -444,10 +723,16 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
.vop_pwm = false,
.enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN,
.enable_conf_mask = BIT(1) | BIT(3),
.oneshot_cnt_max = 0x100,
.funcs = {
.enable = rockchip_pwm_enable_v1,
.config = rockchip_pwm_config_v1,
},
};
static const struct rockchip_pwm_data pwm_data_v2 = {
.regs = {
.version = 0x5c,
.duty = 0x08,
.period = 0x04,
.cntr = 0x00,
@@ -460,10 +745,16 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
.oneshot_cnt_max = 0x100,
.funcs = {
.enable = rockchip_pwm_enable_v1,
.config = rockchip_pwm_config_v1,
},
};
static const struct rockchip_pwm_data pwm_data_vop = {
.regs = {
.version = 0x5c,
.duty = 0x08,
.period = 0x04,
.cntr = 0x0c,
@@ -476,10 +767,16 @@ static const struct rockchip_pwm_data pwm_data_vop = {
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
.oneshot_cnt_max = 0x100,
.funcs = {
.enable = rockchip_pwm_enable_v1,
.config = rockchip_pwm_config_v1,
},
};
static const struct rockchip_pwm_data pwm_data_v3 = {
.regs = {
.version = 0x5c,
.duty = 0x08,
.period = 0x04,
.cntr = 0x00,
@@ -492,6 +789,12 @@ static const struct rockchip_pwm_data pwm_data_v3 = {
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
.oneshot_cnt_max = 0x100,
.funcs = {
.enable = rockchip_pwm_enable_v1,
.config = rockchip_pwm_config_v1,
.irq_handler = rockchip_pwm_irq_v1,
},
};
static const struct of_device_id rockchip_pwm_dt_ids[] = {
@@ -580,23 +883,6 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
goto err_pclk;
}
if (IS_ENABLED(CONFIG_PWM_ROCKCHIP_ONESHOT)) {
pc->irq = platform_get_irq(pdev, 0);
if (pc->irq < 0) {
dev_err(&pdev->dev, "Get oneshot mode irq failed\n");
ret = pc->irq;
goto err_pclk;
}
ret = devm_request_irq(&pdev->dev, pc->irq, rockchip_pwm_oneshot_irq,
IRQF_NO_SUSPEND | IRQF_SHARED,
"rk_pwm_oneshot_irq", pc);
if (ret) {
dev_err(&pdev->dev, "Claim oneshot IRQ failed\n");
goto err_pclk;
}
}
pc->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(pc->pinctrl)) {
dev_err(&pdev->dev, "Get pinctrl failed!\n");
@@ -620,6 +906,22 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
pc->chip.npwm = 1;
pc->clk_rate = clk_get_rate(pc->clk);
if (IS_ENABLED(CONFIG_PWM_ROCKCHIP_ONESHOT) && pc->data->funcs.irq_handler) {
pc->irq = platform_get_irq_optional(pdev, 0);
if (pc->irq < 0) {
dev_warn(&pdev->dev,
"Can't get oneshot mode irq and oneshot interrupt is unsupported\n");
} else {
ret = devm_request_irq(&pdev->dev, pc->irq, pc->data->funcs.irq_handler,
IRQF_NO_SUSPEND | IRQF_SHARED,
"rk_pwm_oneshot_irq", pc);
if (ret) {
dev_err(&pdev->dev, "Claim oneshot IRQ failed\n");
goto err_pclk;
}
}
}
if (pc->data->supports_polarity) {
pc->chip.of_xlate = of_pwm_xlate_with_flags;
pc->chip.of_pwm_n_cells = 3;

View File

@@ -0,0 +1,187 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
#ifndef _PWM_ROCKCHIP_H_
#define _PWM_ROCKCHIP_H_
#include <linux/pwm.h>
/**
* enum rockchip_pwm_global_ctrl_cmd - commands for pwm global ctrl
* @PWM_GLOBAL_CTRL_JOIN: join the global control group
* @PWM_GLOBAL_CTRL_EXIT: exit the global control group
* @PWM_GLOBAL_CTRL_GRANT: obtian the permission of global control
* @PWM_GLOBAL_CTRL_RECLAIM: reclaim the permission of global control
* @PWM_GLOBAL_CTRL_UPDATE: update the configs for all channels in group
* @PWM_GLOBAL_CTRL_ENABLE: enable all channels in group
* @PWM_GLOBAL_CTRL_DISABLE: disable all channels in group
*/
enum rockchip_pwm_global_ctrl_cmd {
PWM_GLOBAL_CTRL_JOIN,
PWM_GLOBAL_CTRL_EXIT,
PWM_GLOBAL_CTRL_GRANT,
PWM_GLOBAL_CTRL_RECLAIM,
PWM_GLOBAL_CTRL_UPDATE,
PWM_GLOBAL_CTRL_ENABLE,
PWM_GLOBAL_CTRL_DISABLE,
};
/**
* struct rockchip_pwm_wave_table - wave table config object
* @offset: the offset of wave table to set
* @len: the length of wave table to set
* @table: the values of wave table to set (in nanoseconds)
* @
*/
struct rockchip_pwm_wave_table {
u16 offset;
u16 len;
u64 *table;
};
/**
* enum rockchip_pwm_wave_table_width_mode - element width of pwm wave table
* @PWM_WAVE_TABLE_8BITS_WIDTH: each element in table is 8bits
* @PWM_WAVE_TABLE_16BITS_WIDTH: each element in table is 16bits
*/
enum rockchip_pwm_wave_table_width_mode {
PWM_WAVE_TABLE_8BITS_WIDTH,
PWM_WAVE_TABLE_16BITS_WIDTH,
};
/**
* enum rockchip_pwm_wave_update_mode - update mode of wave generator
* @PWM_WAVE_INCREASING:
* The wave table address will wrap back to minimum address when increase to
* maximum and then increase again.
* @PWM_WAVE_INCREASING_THEN_DECREASING:
* The wave table address will change to decreasing when increasing to the maximum
* address. it will return to increasing when decrease to the minimum value.
*/
enum rockchip_pwm_wave_update_mode {
PWM_WAVE_INCREASING,
PWM_WAVE_INCREASING_THEN_DECREASING,
};
/**
* struct rockchip_pwm_wave_config - wave generator config object
* @duty_table: the wave table config of duty
* @period_table: the wave table config of period
* @enable: enable or disable wave generator
* @duty_en: to update duty by duty table or not
* @period_en: to update period by period table or not
* @width_mode: the width mode of wave table
* @update_mode: the update mode of wave generator
* @duty_max: the maximum address of duty table
* @duty_min: the minimum address of duty table
* @period_max: the maximum address of period table
* @period_min: the minimum address of period table
* @offset: the initial offset address of duty and period
* @middle: the middle address of duty and period
* @max_hold: the time to stop at maximum address
* @min_hold: the time to stop at minimum address
* @middle_hold: the time to stop at middle address
*/
struct rockchip_pwm_wave_config {
struct rockchip_pwm_wave_table *duty_table;
struct rockchip_pwm_wave_table *period_table;
bool enable;
bool duty_en;
bool period_en;
u16 rpt;
u32 width_mode;
u32 update_mode;
u32 duty_max;
u32 duty_min;
u32 period_max;
u32 period_min;
u32 offset;
u32 middle;
u32 max_hold;
u32 min_hold;
u32 middle_hold;
};
#if IS_REACHABLE(CONFIG_PWM_ROCKCHIP)
/**
* rockchip_pwm_set_counter() - setup pwm counter mode
* @pwm: PWM device
* @enable: enable/disable counter mode
*
* Returns: 0 on success or a negative error code on failure.
*/
int rockchip_pwm_set_counter(struct pwm_device *pwm, bool enable);
/**
* rockchip_pwm_get_counter_result() - get counter result
* @pwm: PWM device
* @counter_res: number of input waveforms
* @is_clear: clear counter result or not
*
* Returns: 0 on success or a negative error code on failure.
*/
int rockchip_pwm_get_counter_result(struct pwm_device *pwm,
unsigned long *counter_res, bool is_clear);
/**
* rockchip_pwm_set_freq_meter() - setup pwm frequency meter mode
* @pwm: PWM device
* @delay_ms: time to wait, in milliseconds, before getting frequency meter result
* @freq_hz: parameter in Hz to fill with frequency meter result
*
* Returns: 0 on success or a negative error code on failure.
*/
int rockchip_pwm_set_freq_meter(struct pwm_device *pwm, unsigned long delay_ms,
unsigned long *freq_hz);
/**
* rockchip_pwm_global_ctrl() - execute global control commands
* @pwm: PWM device
* @cmd: command type to execute
*
* Returns: 0 on success or a negative error code on failure.
*/
int rockchip_pwm_global_ctrl(struct pwm_device *pwm, enum rockchip_pwm_global_ctrl_cmd cmd);
/**
* rockchip_pwm_set_wave() - setup pwm wave generator mode
* @pwm: PWM device
* @config: configs of wave generator mode
*
* Returns: 0 on success or a negative error code on failure.
*/
int rockchip_pwm_set_wave(struct pwm_device *pwm, struct rockchip_pwm_wave_config *config);
#else
static inline int rockchip_pwm_set_counter(struct pwm_device *pwm, bool enable)
{
return 0;
}
static inline int rockchip_pwm_get_counter_result(struct pwm_device *pwm,
unsigned long *counter_res, bool is_clear)
{
return 0;
}
static inline int rockchip_pwm_set_freq_meter(struct pwm_device *pwm, unsigned long delay_ms,
unsigned long *freq_hz)
{
return 0;
}
static inline int rockchip_pwm_global_ctrl(struct pwm_device *pwm,
enum rockchip_pwm_global_ctrl_cmd cmd)
{
return 0;
}
static inline int rockchip_pwm_set_wave(struct pwm_device *pwm,
struct rockchip_pwm_wave_config *config)
{
return 0;
}
#endif
#endif /* _PWM_ROCKCHIP_H_ */